Milimetric has uploaded a new change for review.
https://gerrit.wikimedia.org/r/72991
Change subject: work on csv upload and metric forms
......................................................................
work on csv upload and metric forms
Change-Id: Ide74e9b86e2843119f9fb89b021b872f96fbc89f
---
M wikimetrics/controllers/cohorts.py
M wikimetrics/metrics/bytes_added.py
M wikimetrics/metrics/revert_rate.py
M wikimetrics/static/css/site.css
A wikimetrics/static/js/cohortReview.js
M wikimetrics/static/js/cohortUpload.js
M wikimetrics/templates/csv_upload.html
M wikimetrics/templates/csv_upload_form.html
M wikimetrics/templates/csv_upload_review.html
M wikimetrics/templates/form_for_metrics.html
M wikimetrics/templates/request.html
M wikimetrics/utils.py
12 files changed, 82 insertions(+), 57 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/analytics/wikimetrics
refs/changes/91/72991/1
diff --git a/wikimetrics/controllers/cohorts.py
b/wikimetrics/controllers/cohorts.py
index 8eced4a..d9a417c 100644
--- a/wikimetrics/controllers/cohorts.py
+++ b/wikimetrics/controllers/cohorts.py
@@ -97,8 +97,8 @@
return cohort_dict
[email protected]('/cohorts/upload')
-def upload_csv_cohort():
[email protected]('/cohorts/upload', methods=['GET','POST'])
+def cohort_upload():
""" View for uploading and validating a new cohort via CSV """
if request.method == 'GET':
return render_template('csv_upload.html')
@@ -110,11 +110,11 @@
project = request.form['project']
if not csv or not name or len(name) is 0:
flash('The form was invalid, please select a file and name the
cohort.')
- return redirect(url_for('upload_csv_cohort'))
+ return redirect(url_for('cohort_upload'))
if get_cohort_by_name(name):
flash('That Cohort name is already taken.')
- return redirect(url_for('upload_csv_cohort'))
+ return redirect(url_for('cohort_upload'))
unparsed = csv.reader(normalize_newlines(csv.stream))
unvalidated = parse_records(unparsed, project)
@@ -135,11 +135,11 @@
'The file you uploaded was not in a valid format, could not be
validated,'
'or the project you specified is not configured on this
instance of Wiki Metrics.'
)
- return redirect('/uploads/cohort')
+ return redirect(url_for('cohort_upload'))
@app.route('/cohorts/create', methods=['POST'])
-def upload_csv_cohort_finish():
+def cohort_upload_finish():
try:
name = request.form.get('name')
project = request.form.get('project')
@@ -211,7 +211,8 @@
@app.route('/cohorts/validate/name')
def validate_cohort_name_allowed():
name = request.args.get('name')
- return jsonify(get_cohort_by_name(name) is None)
+ available = get_cohort_by_name(name) is None
+ return json.dumps(available)
def normalize_newlines(stream):
diff --git a/wikimetrics/metrics/bytes_added.py
b/wikimetrics/metrics/bytes_added.py
index 736ac1a..8472ae1 100644
--- a/wikimetrics/metrics/bytes_added.py
+++ b/wikimetrics/metrics/bytes_added.py
@@ -1,3 +1,5 @@
+from datetime import date
+from ..utils import thirty_days_ago
from ..models import Revision, Page
from metric import Metric
from form_fields import BetterBooleanField, CommaSeparatedIntegerListField
@@ -57,8 +59,8 @@
description = 'Compute different aggregations of the bytes contributed or
removed from a\
mediawiki project'
- start_date = DateField()
- end_date = DateField()
+ start_date = DateField(default=thirty_days_ago)
+ end_date = DateField(default=date.today)
namespaces = CommaSeparatedIntegerListField(default=[0],
description='0, 2, 4, etc.')
positive_only_sum = BetterBooleanField(default=True)
negative_only_sum = BetterBooleanField(default=True)
diff --git a/wikimetrics/metrics/revert_rate.py
b/wikimetrics/metrics/revert_rate.py
index e2edc1c..c52a68e 100644
--- a/wikimetrics/metrics/revert_rate.py
+++ b/wikimetrics/metrics/revert_rate.py
@@ -1,5 +1,7 @@
from flask.ext import wtf
from metric import Metric
+from datetime import date
+from ..utils import thirty_days_ago
__all__ = [
'RevertRate',
@@ -36,8 +38,8 @@
label = 'Revert Rate'
description = 'Compute the number of reverted edits in a mediawiki project'
- start_date = wtf.DateField()
- end_date = wtf.DateField()
+ start_date = wtf.DateField(default=thirty_days_ago)
+ end_date = wtf.DateField(default=date.today)
#namespace = wtf.IntegerField(default=0)
def __call__(self, user_ids, session):
diff --git a/wikimetrics/static/css/site.css b/wikimetrics/static/css/site.css
index 8d97730..74bfcf6 100644
--- a/wikimetrics/static/css/site.css
+++ b/wikimetrics/static/css/site.css
@@ -29,3 +29,7 @@
.pick-cohorts .cohorts { margin: 14px 0 0 14px; max-height: 160px; overflow-x:
hide; overflow-y: auto; }
.pick-metrics, .sample-result { background-color: #fff; }
.pick-metrics .tabbable, .sample-result .tabbable { margin: 22px 0 0 0; }
+
+
+/* uploading a cohort */
+form.upload-cohort div.navbar-inner { margin: 0 0 20px 0; }
diff --git a/wikimetrics/static/js/cohortReview.js
b/wikimetrics/static/js/cohortReview.js
new file mode 100644
index 0000000..8885219
--- /dev/null
+++ b/wikimetrics/static/js/cohortReview.js
@@ -0,0 +1,31 @@
+// TODO: get this nasty stuff out of here
+//var invalid = JSON.parse('{{ invalid_json | safe }}');
+//var valid = JSON.parse('{{ valid_json | safe }}');
+//var cohort_name = '{{ cohort_name }}';
+//var cohort_project = '{{ cohort_project }}';
+var invalid = [];
+var valid = [];
+var cohort_name = {};
+var cohort_project = {};
+$(document).ready(function(){
+ ko.applyBindings({
+ invalid: ko.observableArray(invalid),
+ valid: ko.observableArray(valid)
+ });
+
+ $('form.finish-upload').submit(function(event){
+ event.preventDefault();
+ event.stopPropagation();
+
+ form = $(this);
+ $.ajax({
+ url: form.attr('action'),
+ type: 'post',
+ data: {
+ users: JSON.stringify(valid),
+ cohort_name: cohort_name,
+ cohort_project: cohort_project
+ }
+ }).done(redirect);
+ });
+});
diff --git a/wikimetrics/static/js/cohortUpload.js
b/wikimetrics/static/js/cohortUpload.js
index d877a1b..b463e51 100644
--- a/wikimetrics/static/js/cohortUpload.js
+++ b/wikimetrics/static/js/cohortUpload.js
@@ -5,6 +5,7 @@
}, 'Cohort names should only contain letters, numbers, spaces, dashes, and
underscores');
$('form.upload-cohort').validate({
+ onkeyup: false,
messages: {
name: {
remote: 'This cohort name is taken.',
@@ -14,7 +15,7 @@
name: {
required: true,
cohortName: true,
- remote: '/validate/cohort/allowed'
+ remote: '/cohorts/validate/name',
},
csv: {
required: true
diff --git a/wikimetrics/templates/csv_upload.html
b/wikimetrics/templates/csv_upload.html
index 10c4ffe..65015ff 100644
--- a/wikimetrics/templates/csv_upload.html
+++ b/wikimetrics/templates/csv_upload.html
@@ -14,3 +14,9 @@
</ul>
</div>
{% endblock %}
+
+{% block scripts %}
+<script
src="//ajax.aspnetcdn.com/ajax/jquery.validate/1.11.1/jquery.validate.min.js"></script>
+<script src="//ajax.aspnetcdn.com/ajax/knockout/knockout-2.2.1.js"></script>
+<script src="{{ url_for('static', filename='js/cohortUpload.js') }}"></script>
+{% endblock %}
diff --git a/wikimetrics/templates/csv_upload_form.html
b/wikimetrics/templates/csv_upload_form.html
index 3a47773..09b9c5c 100644
--- a/wikimetrics/templates/csv_upload_form.html
+++ b/wikimetrics/templates/csv_upload_form.html
@@ -1,4 +1,7 @@
-<form enctype="multipart/form-data" action="/uploads/cohort" method="POST"
class="upload-cohort form-horizontal">
+<form enctype="multipart/form-data" action="{{url_for('cohort_upload')}}"
method="POST" class="upload-cohort form-horizontal">
+ <div class="navbar-inner">
+ <h3>Create a Cohort by Uploading a CSV</h3>
+ </div>
<div class="control-group">
<label for="name" class="control-label">Cohort Name</label>
<div class="controls">
@@ -6,10 +9,10 @@
<label for="name">(automatically checks availability)</label>
</div>
</div>
- <div class="control-group"> <label for="project"
class="control-label">Wiki Project</label>
- <label for="project" class="control-label">Default Cohort
Project</label>
+ <div class="control-group">
+ <label for="project" class="control-label">Default Project</label>
<div class="controls">
- <input type="text" name="project" id="project" value="{% project
%}{{project}}{% endif %}"/>
+ <input type="text" name="project" id="project" value="{% if
project %}{{project}}{% endif %}"/>
</div>
</div>
<div class="control-group">
@@ -22,5 +25,3 @@
<input type="submit" class="btn btn-primary" value="Upload CSV"/>
</div>
</form>
-
-<script
src="//ajax.aspnetcdn.com/ajax/jquery.validate/1.11.1/jquery.validate.min.js"></script>
diff --git a/wikimetrics/templates/csv_upload_review.html
b/wikimetrics/templates/csv_upload_review.html
index af87828..59c21e7 100644
--- a/wikimetrics/templates/csv_upload_review.html
+++ b/wikimetrics/templates/csv_upload_review.html
@@ -22,11 +22,6 @@
<h5>Try uploading again after fixing the issues</h5>
{% include "csv_upload_form.html" %}
-<!--form action="/uploads/cohort/validate" method="POST"
class="form-horizontal">
- <div class="form-actions">
- <input type="submit" class="btn" value="Re-Check These Users"/>
- </div>
-</form-->
{% endif %}
<hr/>
@@ -48,45 +43,18 @@
</tbody>
</table>
-<form action="/uploads/cohort/finish" method="POST" class="form-horizontal
finish-upload">
+<form action="{{url_for('cohort_upload_finish')}}" method="POST"
class="form-horizontal finish-upload">
<div class="form-actions">
<input type="submit" class="btn btn-primary" value="{% if invalid
%}Upload Only These Valid Users{% else %}Finish Upload{% endif %}"/>
</div>
</form>
{% endif %}
+{% endblock %}
+{% block scripts %}
+<script
src="//ajax.aspnetcdn.com/ajax/jquery.validate/1.11.1/jquery.validate.min.js"></script>
<script src="//ajax.aspnetcdn.com/ajax/knockout/knockout-2.2.1.js"></script>
-<script>
- var invalid = JSON.parse('{{ invalid_json | safe }}');
- var valid = JSON.parse('{{ valid_json | safe }}');
- var cohort_name = '{{ cohort_name }}';
- var cohort_project = '{{ cohort_project }}';
- $(document).ready(function(){
- ko.applyBindings({
- invalid: ko.observableArray(invalid),
- valid: ko.observableArray(valid)
- });
-
- $('form.finish-upload').submit(function(event){
- event.preventDefault();
- event.stopPropagation();
-
- form = $(this);
- $.ajax({
- url: form.attr('action'),
- type: 'post',
- data: {
- users: JSON.stringify(valid),
- cohort_name: cohort_name,
- cohort_project: cohort_project
- }
- }).done(redirect);
- });
- });
-
- function redirect(to){
- location.href = to;
- };
-</script>
+<script src="{{ url_for('static', filename='js/cohortUpload.js') }}"></script>
+<script src="{{ url_for('static', filename='js/cohortReview.js') }}"></script>
{% endblock %}
diff --git a/wikimetrics/templates/form_for_metrics.html
b/wikimetrics/templates/form_for_metrics.html
index 45523be..71cda1f 100644
--- a/wikimetrics/templates/form_for_metrics.html
+++ b/wikimetrics/templates/form_for_metrics.html
@@ -7,6 +7,8 @@
<div class="controls">
{% if f.type == 'BooleanField' or f.type ==
'BetterBooleanField' %}
{{ f(**{'data-bind':'checked: '+f.name}) }}
+ {% elif f.type == 'DateField' %}
+ {{ f(**{'type':'date', 'data-bind':'value: '+f.name}) }}
{% else %}
{{ f(placeholder=f.description, **{'data-bind':'value:
'+f.name}) }}
{% endif %}
diff --git a/wikimetrics/templates/request.html
b/wikimetrics/templates/request.html
index b763647..e71d1bc 100644
--- a/wikimetrics/templates/request.html
+++ b/wikimetrics/templates/request.html
@@ -5,7 +5,7 @@
<div class="navbar-inner">
<h3 class="pull-left">Pick Cohorts</h3>
<form class="navbar-search pull-right">
- <a href="upload">create cohort</a>
+ <a href="{{url_for('cohort_upload')}}">create cohort</a>
<input type="text" class="search-query" placeholder="find"/>
</form>
diff --git a/wikimetrics/utils.py b/wikimetrics/utils.py
index 17b2dbf..c57df5a 100644
--- a/wikimetrics/utils.py
+++ b/wikimetrics/utils.py
@@ -44,3 +44,10 @@
return int(mktime(obj.timetuple()))
return json.JSONEncoder.default(self, obj)
+
+
+def thirty_days_ago():
+ """
+ Callable that gets the date 30 days ago, needed by WTForms DateFields
+ """
+ return datetime.date.today() - datetime.timedelta(days=30)
--
To view, visit https://gerrit.wikimedia.org/r/72991
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ide74e9b86e2843119f9fb89b021b872f96fbc89f
Gerrit-PatchSet: 1
Gerrit-Project: analytics/wikimetrics
Gerrit-Branch: master
Gerrit-Owner: Milimetric <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits