diff --git a/.gitignore b/.gitignore index 70ae503..cc18c58 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ mapsme-state.txt mapsme-changes.db mapsme-process.log venv/ +config_local.py diff --git a/mmwatch/config.py b/mmwatch/config.py index bd00590..07f7045 100644 --- a/mmwatch/config.py +++ b/mmwatch/config.py @@ -1,7 +1,8 @@ -DEBUG = True - import os BASE_DIR = os.path.abspath(os.path.dirname(__file__)) + +DEBUG = True + DATABASE_URI = 'sqlite:///' + os.path.join(BASE_DIR, 'server', 'mapsme-changes.db') # DATABASE_URI = 'postgresql://localhost/mmwatch' @@ -12,3 +13,13 @@ TOP = 10 # Example: 'http://localhost:5000/queryat/' QUERYAT_URL = None GEOCODE_BATCH = 20 + +# Override these (and anything else) in config_local.py +OAUTH_KEY = '' +OAUTH_SECRET = '' +SESSION_KEY = 'sdkjfhsfljhsadf' + +try: + from config_local import * +except ImportError: + pass diff --git a/mmwatch/run.py b/mmwatch/run.py index a30335f..179f33a 100755 --- a/mmwatch/run.py +++ b/mmwatch/run.py @@ -1,3 +1,3 @@ #!/usr/bin/env python -from www import mmwatch -mmwatch.app.run(debug=True) +from www import app +app.run(debug=True) diff --git a/mmwatch/www/__init__.py b/mmwatch/www/__init__.py index e69de29..b6e4af0 100644 --- a/mmwatch/www/__init__.py +++ b/mmwatch/www/__init__.py @@ -0,0 +1,14 @@ +from flask import Flask +import config + +app = Flask(__name__) +app.debug = config.DEBUG + +try: + from flask_compress import Compress + Compress(app) +except ImportError: + pass + +import www.mmwatch +import www.revert diff --git a/mmwatch/www/mmwatch.py b/mmwatch/www/mmwatch.py index 429c95c..8994bdf 100644 --- a/mmwatch/www/mmwatch.py +++ b/mmwatch/www/mmwatch.py @@ -1,19 +1,11 @@ +from www import app import os, json, peewee -from flask import Flask, send_file, request, render_template, url_for, abort, jsonify, Response +from flask import send_file, request, render_template, url_for, abort, jsonify, Response from datetime import datetime, timedelta from StringIO import StringIO import config from db import database, Change, User -app = Flask(__name__) -app.debug = config.DEBUG - -try: - from flask_compress import Compress - Compress(app) -except ImportError: - pass - @app.before_request def before_request(): @@ -49,9 +41,12 @@ def get_user_rating(): def purl(params, **kwargs): p2 = params.copy() + found_page = False for k, v in kwargs.iteritems(): p2[k] = v - if 'page' in p2 and p2['page'] <= 1: + if k == 'page': + found_page = True + if 'page' in p2 and (not found_page or p2['page'] <= 1): del p2['page'] return url_for('the_one_and_only_page', **p2) diff --git a/mmwatch/www/revert.py b/mmwatch/www/revert.py new file mode 100644 index 0000000..408c300 --- /dev/null +++ b/mmwatch/www/revert.py @@ -0,0 +1,54 @@ +from www import app +from flask import render_template, session, url_for, redirect +from flask_oauthlib.client import OAuth, get_etree +import config +from db import database, Change + +API_ENDPOINT = 'https://api.openstreetmap.org/api/0.6/' + +oauth = OAuth() +openstreetmap = oauth.remote_app('OpenStreetMap', + base_url=API_ENDPOINT, + request_token_url='https://www.openstreetmap.org/oauth/request_token', + access_token_url='https://www.openstreetmap.org/oauth/access_token', + authorize_url='https://www.openstreetmap.org/oauth/authorize', + consumer_key=config.OAUTH_KEY, + consumer_secret=config.OAUTH_SECRET + ) + + +@app.route('/revert') +def revert(): + if 'osm_token' not in session: + return openstreetmap.authorize(callback=url_for('oauth')) + return 'TODO' + + +@app.route('/oauth') +@openstreetmap.authorized_handler +def oauth(resp): + if resp is None: + return 'Denied. Try again.' + session['osm_token'] = ( + resp['oauth_token'], + resp['oauth_token_secret'] + ) + user_details = openstreetmap.get('user/details').data + session['osm_username'] = user_details[0].get('display_name') + return redirect(url_for('revert')) + + +@openstreetmap.tokengetter +def get_token(token='user'): + if token == 'user' and 'osm_token' in session: + return session['osm_token'] + return None + + +@app.route('/logout') +def logout(): + if 'osm_token' in session: + del session['osm_token'] + if 'osm_username' in session: + del session['osm_username'] + return redirect(url_for('the_one_and_only_page')) diff --git a/mmwatch/www/static/bulk.js b/mmwatch/www/static/bulk.js new file mode 100644 index 0000000..5d8bc27 --- /dev/null +++ b/mmwatch/www/static/bulk.js @@ -0,0 +1,28 @@ +function getCheckedObjects() { + var result = []; + var checks = document.getElementsByClassName('obj_check'); + for (var i = 0; i < checks.length; i++) { + if (checks[i].checked) + result.push(checks[i].value); + checks[i].checked = false; + } + return result; +} + +function btnClear() { + getCheckedObjects(); + window.scrollTo(0, 0); +} + +function btnLevel0() { + var checks = getCheckedObjects(); + var param = checks.join(','); + var w = window.open('http://level0.osmz.ru/?url=' + param, '_blank'); + w.focus(); +} + +function btnRevert(url) { + var checks = getCheckedObjects(); + var param = checks.join(','); + window.location.assign(url + '?objects=' + param); +} diff --git a/mmwatch/www/static/style.css b/mmwatch/www/static/style.css index 4b1ce6f..f84abf5 100644 --- a/mmwatch/www/static/style.css +++ b/mmwatch/www/static/style.css @@ -8,7 +8,7 @@ body { } .change table { - margin-left: 2em; + margin-left: 3em; font-size: 10pt; } @@ -45,6 +45,11 @@ h2 { font-size: 12pt; } +h1 a { + text-decoration: none; + color: black; +} + .download { margin-top: 2em; } diff --git a/mmwatch/www/templates/index.html b/mmwatch/www/templates/index.html index a8daeb8..f3d3c7d 100644 --- a/mmwatch/www/templates/index.html +++ b/mmwatch/www/templates/index.html @@ -2,7 +2,7 @@ MAPS.ME OSM Changes Browser -

OSM Edits Made With MAPS.ME

+

OSM Edits Made With MAPS.ME

Statistics

@@ -106,6 +106,7 @@

Changes

{% for change in changes %}
+ {{ change.user }} at {{ change.timestamp.strftime('%d.%m.%Y %H:%M') }} in {% if change.action == 'n' %} {{ change.changeset }}: {{ change.explain_action() }} @@ -127,11 +128,19 @@
{% endfor %} +
+ With selected changes: + + + +
+