From 663d909c99b10a7fed160ab42ad31e0474e98664 Mon Sep 17 00:00:00 2001 From: Isman Firmansyah Date: Fri, 4 Jul 2014 20:52:41 +0700 Subject: [PATCH 1/5] use url_for instead of hardcoded PUBLIC_URL to generate links for email --- .../text/registration_confirmation_email.txt | 2 +- users/views.py | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/users/templates/text/registration_confirmation_email.txt b/users/templates/text/registration_confirmation_email.txt index 950b628..09dcb6b 100644 --- a/users/templates/text/registration_confirmation_email.txt +++ b/users/templates/text/registration_confirmation_email.txt @@ -17,7 +17,7 @@ to the centre of your nearest town / state or province or country). Deleting or editing your user record does not require a user name or password, only that you click on this unique (for your user record) link below: - - Link: {{ url }}/edit/{{ user.guid }} + - Link: {{ edit_url }} If you have ever forget your special link above, you can request this message to be resent to you by using the 'I forgot my edit link' menu on {{ url }}. diff --git a/users/views.py b/users/views.py index 9b9068f..dadfe8b 100644 --- a/users/views.py +++ b/users/views.py @@ -5,7 +5,7 @@ """ import json -from flask import render_template, Response, request +from flask import render_template, Response, request, url_for from werkzeug.exceptions import default_exceptions # App declared directly in __init__ as per @@ -153,7 +153,9 @@ def add_user_view(): body = render_template( 'text/registration_confirmation_email.txt', project_name=APP.config['PROJECT_NAME'], - url=APP.config['PUBLIC_URL'], + url=url_for(".map_view", _external=True), + edit_url=url_for(".edit_user_view", guid=added_user["guid"], + _external=True), user=added_user) recipient = added_user['email'] send_async_mail( @@ -307,7 +309,7 @@ def delete_user_view(guid): """ # Delete User delete_user(guid) - return APP.config['PUBLIC_URL'] + return url_for(".map_view") @APP.route('/download') @@ -362,7 +364,8 @@ def reminder_view(): body = render_template( 'text/registration_confirmation_email.txt', project_name=APP.config['PROJECT_NAME'], - url=APP.config['PUBLIC_URL'], + url=url_for(".map_view", _external=True), + edit_url=url_for(".edit_user_view", guid=user["guid"], _external=True), user=user) send_async_mail( sender=MAIL_ADMIN, From 5f0d8f21df2d20d0f7672960e2a771021ff153c1 Mon Sep 17 00:00:00 2001 From: Isman Firmansyah Date: Fri, 4 Jul 2014 21:22:54 +0700 Subject: [PATCH 2/5] use url_for to render static files --- runserver.py | 3 --- users/templates/html/base.html | 43 ++++++++++++++------------------- users/templates/html/index.html | 12 +++++---- 3 files changed, 25 insertions(+), 33 deletions(-) diff --git a/runserver.py b/runserver.py index 0a1eea4..b1de16e 100644 --- a/runserver.py +++ b/runserver.py @@ -6,7 +6,6 @@ import optparse from users import APP, LOGGER -from users.static import static_file if __name__ == '__main__': parser = optparse.OptionParser() @@ -19,8 +18,6 @@ print 'Running in debug mode' LOGGER.info('Running in debug mode') APP.debug = True - # set up flask to serve static content - APP.add_url_rule('/', 'static_file', static_file) else: print 'Running in production mode' LOGGER.info('Running in production mode') diff --git a/users/templates/html/base.html b/users/templates/html/base.html index 50f7730..4996087 100644 --- a/users/templates/html/base.html +++ b/users/templates/html/base.html @@ -6,31 +6,24 @@ {% block title %}{{ project_name | safe }} User Map{% endblock %} {% block head_resources %} - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + {% endblock head_resources %} diff --git a/users/templates/html/index.html b/users/templates/html/index.html index 18450c0..a6d7d0d 100644 --- a/users/templates/html/index.html +++ b/users/templates/html/index.html @@ -1,11 +1,13 @@ {% extends "html/base.html" %} {% block head_resources %} - {{ super() }} - - - - + {{ super() }} + + + + {% endblock head_resources %} {% block body %} From 684f07badfca46271e677370ab4a66b25f34a032 Mon Sep 17 00:00:00 2001 From: Isman Firmansyah Date: Fri, 4 Jul 2014 21:37:17 +0700 Subject: [PATCH 3/5] use flask-script to manage entrypoint --- manage.py | 7 +++++++ requirements.txt | 1 + 2 files changed, 8 insertions(+) create mode 100644 manage.py diff --git a/manage.py b/manage.py new file mode 100644 index 0000000..32ee53c --- /dev/null +++ b/manage.py @@ -0,0 +1,7 @@ +from flask.ext.script import Manager + +from users import APP + +if __name__ == "__main__": + manager = Manager(APP) + manager.run() diff --git a/requirements.txt b/requirements.txt index 480195f..d22d0c9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,6 @@ Flask==0.10.1 Flask-Mail==0.9.0 +Flask-Script==2.0.5 Jinja2==2.7.3 MarkupSafe==0.23 Werkzeug==0.9.6 From 26432a4a75d95fdf1857fbb4882176668f95ed43 Mon Sep 17 00:00:00 2001 From: Isman Firmansyah Date: Sat, 5 Jul 2014 15:30:55 +0700 Subject: [PATCH 4/5] reorganize code related to static file, reverse url, and its config --- README.md | 40 ++++++++-------------------------------- runserver.py | 26 -------------------------- users/__init__.py | 19 ++----------------- users/static.py | 46 ---------------------------------------------- 4 files changed, 10 insertions(+), 121 deletions(-) delete mode 100644 runserver.py delete mode 100644 users/static.py diff --git a/README.md b/README.md index 953e121..d9c1f34 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ -[![Stories in Ready](https://badge.waffle.io/timlinux/user_map.png?label=ready)](https://waffle.io/timlinux/user_map) -[![Build Status](http://jenkins.linfiniti.com/buildStatus/icon?job=UserMap)](http://jenkins.linfiniti.com/job/UserMap/) - User Map ======== A simple flask application for creating user community maps. +Hacking +------- + By default, this app reads configuration from `users/default_config.py`. To override values set in default config, simply copy the contents of `users/default_config.py` and save it elsewhere. @@ -14,20 +14,18 @@ of `users/default_config.py` and save it elsewhere. Then edit the custom config file, setting appropriate values as needed. -To run in debug mode (which will also serve up static content), -use the `-d` flag: +To run the development server: - USERS_CONFIG=/path/to/custom/config.py python runserver.py -d + USERS_CONFIG=/path/to/custom/config.py python manage.py runserver Each config item is overridable through environment variable. -For instance, if you want to suppress email delivery, -simply set appropriate value: +For instance, if you want to suppress email delivery, simply set appropriate value: - USERS_MAIL_SUPPRESS_SEND=True python runserver + USERS_MAIL_SUPPRESS_SEND=True python manage.py runserver To run testcases: - USERS_CONFIG=/path/to/custom/config.py MAIL_SUPPRESS_SEND=True ./runtests.sh + USERS_CONFIG=/path/to/custom/config.py USERS_MAIL_SUPPRESS_SEND=True ./runtests.sh Collaboration ------------- @@ -38,28 +36,6 @@ Collaboration 4. Once it done, submit your pull request (PR) against upstream `develop` branch. 5. Our maintainers will review your PR. If it's good — all tests passed and proposed feature is in our roadmap — your PR will be merged. -Deployment using Docker ------------------------ - -If you are using docker, you can create a Docker image for this app easily as -follows: - -``` -wget -O Dockerfile https://raw.github.com/timlinux/user_map/master/docker/Dockerfile -wget -O sources.list https://raw.github.com/timlinux/user_map/master/docker/sources.list -wget -O post-setup.sh https://raw.github.com/timlinux/user_map/master/docker/post-setup.sh -chmod +x post-setup.sh - -docker build -t linfiniti/user_map:base . -docker run -d -p 8099:80 -t linfiniti/user_map:base -n user_map -D -``` - -If you are on a Hetzner server, consider replacing the second line above with: - -``` -wget -O sources.list https://raw.github.com/timlinux/user_map/master/docker/hetzner-sources.list -``` - Authors ------- diff --git a/runserver.py b/runserver.py deleted file mode 100644 index b1de16e..0000000 --- a/runserver.py +++ /dev/null @@ -1,26 +0,0 @@ -# coding=utf-8 -"""Simple runner for our flask app. - -see http://flask.pocoo.org/docs/patterns/packages/#larger-applications -""" -import optparse - -from users import APP, LOGGER - -if __name__ == '__main__': - parser = optparse.OptionParser() - parser.add_option('-d', '--debug', dest='debug', default=False, - help='turn on Flask debugging', action='store_true') - - options, args = parser.parse_args() - - if options.debug: - print 'Running in debug mode' - LOGGER.info('Running in debug mode') - APP.debug = True - else: - print 'Running in production mode' - LOGGER.info('Running in production mode') - - print 'Starting.....' - APP.run(host='0.0.0.0') diff --git a/users/__init__.py b/users/__init__.py index c8ea437..b56cbdd 100644 --- a/users/__init__.py +++ b/users/__init__.py @@ -68,25 +68,10 @@ def setup_logger(): APP = Flask(__name__) -#: Load configuration from any possible means. -#: To override default configuration defined in ``users.default_config``, -#: simply copy the contents of ``config.py`` file, -#: and save it into a file. -#: -#: .. sourcecode:: sh -#: -#: USERS_CONFIG=/path/to/config.py python runserver.py -#: -#: Another way of doing it is by setting environment variable for each -#: config item. -#: -#: .. sourcecode:: sh -#: -#: USERS_CONFIG=/path/to/config.py USERS_MAIL_SUPPRESS_SEND=True \ -#: python runserver.py -#: +# Load configuration from any possible means. AppConfig(APP, default_settings="users.default_config") +# Mailer mail = Mail(APP) # backward-compat diff --git a/users/static.py b/users/static.py deleted file mode 100644 index 6ca23e7..0000000 --- a/users/static.py +++ /dev/null @@ -1,46 +0,0 @@ -# coding=utf-8 -"""Helper module for serving static files when running in dev mode. -:copyright: (c) 2013 by Tim Sutton -:license: GPLv3, see LICENSE for more details. -""" -import os -from flask import abort, Response - -# -# These are only used to serve static files when testing -# -FILE_SUFFIX_MIMETYPES = { - '.css': 'text/css', - '.jpg': 'image/jpeg', - '.html': 'text/html', - '.ico': 'image/x-icon', - '.png': 'image/png', - '.js': 'application/javascript', - '.eot': 'application/vnd.ms-fontobject', - '.svg': 'image/svg+xml', - '.ttf': 'font/ttf', - '.woff': 'application/font-woff' -} - - -def static_file(path): - """Flask static file hander used for local testing. - - :param path: Path for the static resource to be served. - :type path: str - - :returns: An http Response of the correct mime type for the resource - requested. - :rtype: HttpResponse - """ - try: - path = os.path.join(os.path.dirname(__file__), os.path.pardir, path) - static_resource = open(path) - except IOError: - abort(404) - return - _, ext = os.path.splitext(path) - if ext in FILE_SUFFIX_MIMETYPES: - return Response( - static_resource.read(), mimetype=FILE_SUFFIX_MIMETYPES[ext]) - return static_resource.read() From 25d5a99d93eb0851864802132562844cd5c21ca9 Mon Sep 17 00:00:00 2001 From: Isman Firmansyah Date: Mon, 7 Jul 2014 13:16:03 +0700 Subject: [PATCH 5/5] revert url_for magic for generating links in email template --- .../text/registration_confirmation_email.txt | 2 +- users/views.py | 11 ++++------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/users/templates/text/registration_confirmation_email.txt b/users/templates/text/registration_confirmation_email.txt index 09dcb6b..950b628 100644 --- a/users/templates/text/registration_confirmation_email.txt +++ b/users/templates/text/registration_confirmation_email.txt @@ -17,7 +17,7 @@ to the centre of your nearest town / state or province or country). Deleting or editing your user record does not require a user name or password, only that you click on this unique (for your user record) link below: - - Link: {{ edit_url }} + - Link: {{ url }}/edit/{{ user.guid }} If you have ever forget your special link above, you can request this message to be resent to you by using the 'I forgot my edit link' menu on {{ url }}. diff --git a/users/views.py b/users/views.py index dadfe8b..559cd21 100644 --- a/users/views.py +++ b/users/views.py @@ -5,7 +5,7 @@ """ import json -from flask import render_template, Response, request, url_for +from flask import render_template, Response, request from werkzeug.exceptions import default_exceptions # App declared directly in __init__ as per @@ -153,9 +153,7 @@ def add_user_view(): body = render_template( 'text/registration_confirmation_email.txt', project_name=APP.config['PROJECT_NAME'], - url=url_for(".map_view", _external=True), - edit_url=url_for(".edit_user_view", guid=added_user["guid"], - _external=True), + url=APP.config["PUBLIC_URL"], user=added_user) recipient = added_user['email'] send_async_mail( @@ -309,7 +307,7 @@ def delete_user_view(guid): """ # Delete User delete_user(guid) - return url_for(".map_view") + return APP.config["PUBLIC_URL"] @APP.route('/download') @@ -364,8 +362,7 @@ def reminder_view(): body = render_template( 'text/registration_confirmation_email.txt', project_name=APP.config['PROJECT_NAME'], - url=url_for(".map_view", _external=True), - edit_url=url_for(".edit_user_view", guid=user["guid"], _external=True), + url=APP.config["PUBLIC_URL"], user=user) send_async_mail( sender=MAIL_ADMIN,