diff --git a/flask_website/__init__.py b/flask_website/__init__.py index 649061b0..66bbc208 100644 --- a/flask_website/__init__.py +++ b/flask_website/__init__.py @@ -35,16 +35,16 @@ app.add_url_rule('/docs/flask-docs.pdf', endpoint='docs.pdf', app.add_url_rule('/docs/flask-docs.zip', endpoint='docs.zip', build_only=True) -from flask_website.views.general import general -from flask_website.views.community import community -from flask_website.views.mailinglist import mailinglist -from flask_website.views.snippets import snippets -from flask_website.views.extensions import extensions -app.register_module(general) -app.register_module(community) -app.register_module(mailinglist) -app.register_module(snippets) -app.register_module(extensions) +from flask_website.views import general +from flask_website.views import community +from flask_website.views import mailinglist +from flask_website.views import snippets +from flask_website.views import extensions +app.register_module(general.mod) +app.register_module(community.mod) +app.register_module(mailinglist.mod) +app.register_module(snippets.mod) +app.register_module(extensions.mod) from flask_website.database import User, db_session from flask_website import utils diff --git a/flask_website/listings/__init__.py b/flask_website/listings/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/flask_website/listings/extensions.py b/flask_website/listings/extensions.py new file mode 100644 index 00000000..328db64a --- /dev/null +++ b/flask_website/listings/extensions.py @@ -0,0 +1,151 @@ +from urlparse import urlparse +from werkzeug import url_quote +from flask import Markup + + +class Extension(object): + + def __init__(self, name, author, description, + github=None, bitbucket=None, docs=None, website=None): + self.name = name + self.author = author + self.description = Markup(description) + self.github = github + self.bitbucket = bitbucket + self.docs = docs + self.website = website + + @property + def pypi(self): + return 'http://pypi.python.org/pypi/%s' % url_quote(self.name) + + @property + def docserver(self): + if self.docs: + return urlparse(self.docs)[1] + + +extensions = [ + Extension('Flask-OAuth', 'Armin Ronacher', + description=''' +

Adds OAuth support to Flask. + ''', + github='mitsuhiko/flask-oauth', + docs='http://packages.python.org/Flask-OAuth/' + ), + Extension('Flask-OpenID', 'Armin Ronacher', + description=''' +

Adds OpenID support to Flask. + ''', + github='mitsuhiko/flask-openid', + docs='http://packages.python.org/Flask-OpenID/' + ), + Extension('Flask-Babel', 'Armin Ronacher', + description=''' +

Adds i18n/l10n support to Flask, based on + babel and + pytz. + ''', + github='mitsuhiko/flask-babel', + docs='http://packages.python.org/Flask-Babel/' + ), + Extension('Flask-SQLAlchemy', 'Armin Ronacher', + description=''' +

Adds SQLAlchemy support to Flask. Quick and easy. + ''', + github='mitsuhiko/flask-sqlalchemy', + docs='http://packages.python.org/Flask-SQLAlchemy/' + ), + Extension('Flask-XML-RPC', 'Matthew Frazier', + description=''' +

Adds XML-RPC support to Flask. + ''', + bitbucket='leafstorm/flask-xml-rpc', + docs='http://packages.python.org/Flask-XML-RPC/' + ), + Extension('Flask-CouchDB', 'Matthew Frazier', + description=''' +

Adds CouchDB support to Flask. + ''', + bitbucket='leafstorm/flask-couchdb', + docs='http://packages.python.org/Flask-CouchDB/' + ), + Extension('Flask-Uploads', 'Matthew Frazier', + description=''' +

Flask-Uploads allows your application to flexibly and + efficiently handle file uploading and serving the uploaded files. + You can create different sets of uploads - one for document + attachments, one for photos, etc. + ''', + bitbucket='leafstorm/flask-uploads', + docs='http://packages.python.org/Flask-Uploads/' + ), + Extension('Flask-Genshi', 'Dag Odenhall', + description=''' +

Adds support for the Genshi + templating language to Flask applications. + ''', + bitbucket='dag/flask-genshi', + docs='http://packages.python.org/Flask-Genshi/' + ), + Extension('flask-mail', 'Dan Jacob', + description=''' +

Makes sending mails from Flask applications very easy and + has also support for unittesting. + ''', + bitbucket='danjac/flask-mail', + docs='http://packages.python.org/flask-mail/' + ), + Extension('Flask-WTF', 'Dan Jacob', + description=''' +

Flask-WTF offers simple integration with WTForms. This + integration includes optional CSRF handling for greater security. + ''', + bitbucket='danjac/flask-wtf', + docs='http://packages.python.org/Flask-WTF/' + ), + Extension('Flask-Testing', 'Dan Jacob', + description=''' +

The Flask-Testing extension provides unit testing utilities for Flask. + ''', + bitbucket='danjac/flask-testing', + docs='http://packages.python.org/Flask-Testing/' + ), + Extension('Flask-Script', 'Dan Jacob', + description=''' +

The Flask-Script extension provides support for writing external + scripts in Flask. It uses argparse to parse command line arguments. + ''', + bitbucket='danjac/flask-script', + docs='http://packages.python.org/Flask-Script/' + ), + Extension('flask-csrf', 'Steve Losh', + description=''' +

A small Flask extension for adding + CSRF protection. + ''', + docs='http://sjl.bitbucket.org/flask-csrf/', + bitbucket='sjl/flask-csrf' + ), + Extension('flask-lesscss', 'Steve Losh', + description=''' +

+ A small Flask extension that makes it easy to use + LessCSS with your + Flask application. + ''', + docs='http://sjl.bitbucket.org/flask-lesscss/', + bitbucket='sjl/flask-lesscss' + ), + Extension('flask-urls', 'Steve Losh', + description=''' +

+ A collection of URL-related functions for Flask applications. + ''', + docs='http://sjl.bitbucket.org/flask-urls/', + bitbucket='sjl/flask-urls' + ) +] + + +extensions.sort(key=lambda x: x.name.lower()) diff --git a/flask_website/listings/projects.py b/flask_website/listings/projects.py new file mode 100644 index 00000000..67805af3 --- /dev/null +++ b/flask_website/listings/projects.py @@ -0,0 +1,82 @@ +# -*- coding: utf-8 -*- +from urlparse import urlparse +from flask import Markup + + +class Project(object): + + def __init__(self, name, url, description, source=None): + self.name = name + self.url = url + self.description = Markup(description) + self.source = source + + @property + def host(self): + return urlparse(self.url)[1] + + @property + def sourcehost(self): + if self.source is not None: + return urlparse(self.source)[1] + + +projects = { + 'websites': [ + Project('Flask Website', 'http://flask.pocoo.org/', ''' +

+ The website of the Flask microframework itself including the + mailinglist interface, snippet archive and extension registry. + '''), + Project('Brightonpy', 'http://brightonpy.org/', ''' +

+ The website of the Brighton Python User Group + ''', source='http://github.com/j4mie/brightonpy.org/'), + Project('vlasiku.lojban.org', 'http://vlasisku.lojban.org/', ''' +

+ An intelligent search engine for the Lojban dictionary. + '''), + Project(u's h o r e … software development', 'http://shore.be/', ''' +

Corporate website of Shore Software Development. + '''), + # this one might change URL soon, check on each update + Project('rdrei.net', 'http://new.rdrei.net/', ''' +

Personal website of Pascal Hartig. + '''), + ], + 'apps': [ + Project('960 Layout System', 'http://960ls.atomidata.com/', ''' +

+ The generator of the 960 Layout System is powered by Flask. It + generates downloadable 960 stylesheets. + '''), + Project('hg-review', 'http://review.stevelosh.com/', ''' +

+ hg-review is a code review system for Mercurial. It is available + GPL2 license. + ''', source='http://bitbucket.org/sjl/hg-review/'), + Project('geocron', 'http://geocron.us/', ''' +

+ By combining your present location with the time of day, geocron + automates your life. +

+ When you get to your Metro station during the commute home, + geocron can send a text message reading "Pick me up dear" to your + spouse. + '''), + Project('Cockerel', 'http://dcolish.github.com/Cockerel/', ''' +

An Online Logic Assistent Based on Coq. + ''', source='http://github.com/dcolish/Cockerel'), + Project('Ryshcate', 'http://ryshcate.leafstorm.us/', ''' +

+ Ryshcate is a Flask powered pastebin with sourcecode + available. + ''', source='http://bitbucket.org/leafstorm/ryshcate/') + ] +} + + +# order projects by name +for _category in projects.itervalues(): + _category.sort(key=lambda x: x.name.lower()) +del _category diff --git a/flask_website/views/community.py b/flask_website/views/community.py index 143e6888..5e9c5e0c 100644 --- a/flask_website/views/community.py +++ b/flask_website/views/community.py @@ -1,113 +1,35 @@ -# -*- coding: utf-8 -*- -from urlparse import urlparse -from flask import Markup, Module, render_template +from flask import Module, render_template from flask_website.twitter import flask_tweets +from flask_website.listings.projects import projects -community = Module(__name__, url_prefix='/community') +mod = Module(__name__, url_prefix='/community') -class Project(object): - - def __init__(self, name, url, description, source=None): - self.name = name - self.url = url - self.description = Markup(description) - self.source = source - - @property - def host(self): - return urlparse(self.url)[1] - - @property - def sourcehost(self): - if self.source is not None: - return urlparse(self.source)[1] - -projects = { - 'websites': [ - Project('Flask Website', 'http://flask.pocoo.org/', ''' -

- The website of the Flask microframework itself including the - mailinglist interface, snippet archive and extension registry. - '''), - Project('Brightonpy', 'http://brightonpy.org/', ''' -

- The website of the Brighton Python User Group - ''', source='http://github.com/j4mie/brightonpy.org/'), - Project('vlasiku.lojban.org', 'http://vlasisku.lojban.org/', ''' -

- An intelligent search engine for the Lojban dictionary. - '''), - Project(u's h o r e … software development', 'http://shore.be/', ''' -

Corporate website of Shore Software Development. - '''), - # this one might change URL soon, check on each update - Project('rdrei.net', 'http://new.rdrei.net/', ''' -

Personal website of Pascal Hartig. - '''), - ], - 'apps': [ - Project('960 Layout System', 'http://960ls.atomidata.com/', ''' -

- The generator of the 960 Layout System is powered by Flask. It - generates downloadable 960 stylesheets. - '''), - Project('hg-review', 'http://review.stevelosh.com/', ''' -

- hg-review is a code review system for Mercurial. It is available - GPL2 license. - ''', source='http://bitbucket.org/sjl/hg-review/'), - Project('geocron', 'http://geocron.us/', ''' -

- By combining your present location with the time of day, geocron - automates your life. -

- When you get to your Metro station during the commute home, - geocron can send a text message reading "Pick me up dear" to your - spouse. - '''), - Project('Cockerel', 'http://dcolish.github.com/Cockerel/', ''' -

An Online Logic Assistent Based on Coq. - ''', source='http://github.com/dcolish/Cockerel'), - Project('Ryshcate', 'http://ryshcate.leafstorm.us/', ''' -

- Ryshcate is a Flask powered pastebin with sourcecode - available. - ''', source='http://bitbucket.org/leafstorm/ryshcate/') - ] -} - -# order projects by name -for _category in projects.itervalues(): - _category.sort(key=lambda x: x.name.lower()) -del _category - - -@community.route('/') +@mod.route('/') def index(): return render_template('community/index.html') -@community.route('/irc/') +@mod.route('/irc/') def irc(): return render_template('community/irc.html') -@community.route('/twitter/') +@mod.route('/twitter/') def twitter(): return render_template('community/twitter.html', tweets=flask_tweets) -@community.route('/badges/') +@mod.route('/badges/') def badges(): return render_template('community/badges.html') -@community.route('/poweredby/') +@mod.route('/poweredby/') def poweredby(): return render_template('community/poweredby.html', projects=projects) -@community.route('/logos/') +@mod.route('/logos/') def logos(): return render_template('community/logos.html') diff --git a/flask_website/views/extensions.py b/flask_website/views/extensions.py index 1d4094e5..84776b30 100644 --- a/flask_website/views/extensions.py +++ b/flask_website/views/extensions.py @@ -1,159 +1,14 @@ -from urlparse import urlparse -from flask import Module, render_template, Markup -from werkzeug import url_quote +from flask import Module, render_template +from flask_website.listings.extensions import extensions -extensions = Module(__name__, url_prefix='/extensions') - -class Extension(object): - - def __init__(self, name, author, description, - github=None, bitbucket=None, docs=None, website=None): - self.name = name - self.author = author - self.description = Markup(description) - self.github = github - self.bitbucket = bitbucket - self.docs = docs - self.website = website - - @property - def pypi(self): - return 'http://pypi.python.org/pypi/%s' % url_quote(self.name) - - @property - def docserver(self): - if self.docs: - return urlparse(self.docs)[1] - -database = [ - Extension('Flask-OAuth', 'Armin Ronacher', - description=''' -

Adds OAuth support to Flask. - ''', - github='mitsuhiko/flask-oauth', - docs='http://packages.python.org/Flask-OAuth/' - ), - Extension('Flask-OpenID', 'Armin Ronacher', - description=''' -

Adds OpenID support to Flask. - ''', - github='mitsuhiko/flask-openid', - docs='http://packages.python.org/Flask-OpenID/' - ), - Extension('Flask-Babel', 'Armin Ronacher', - description=''' -

Adds i18n/l10n support to Flask, based on - babel and - pytz. - ''', - github='mitsuhiko/flask-babel', - docs='http://packages.python.org/Flask-Babel/' - ), - Extension('Flask-SQLAlchemy', 'Armin Ronacher', - description=''' -

Adds SQLAlchemy support to Flask. Quick and easy. - ''', - github='mitsuhiko/flask-sqlalchemy', - docs='http://packages.python.org/Flask-SQLAlchemy/' - ), - Extension('Flask-XML-RPC', 'Matthew Frazier', - description=''' -

Adds XML-RPC support to Flask. - ''', - bitbucket='leafstorm/flask-xml-rpc', - docs='http://packages.python.org/Flask-XML-RPC/' - ), - Extension('Flask-CouchDB', 'Matthew Frazier', - description=''' -

Adds CouchDB support to Flask. - ''', - bitbucket='leafstorm/flask-couchdb', - docs='http://packages.python.org/Flask-CouchDB/' - ), - Extension('Flask-Uploads', 'Matthew Frazier', - description=''' -

Flask-Uploads allows your application to flexibly and - efficiently handle file uploading and serving the uploaded files. - You can create different sets of uploads - one for document - attachments, one for photos, etc. - ''', - bitbucket='leafstorm/flask-uploads', - docs='http://packages.python.org/Flask-Uploads/' - ), - Extension('Flask-Genshi', 'Dag Odenhall', - description=''' -

Adds support for the Genshi - templating language to Flask applications. - ''', - bitbucket='dag/flask-genshi', - docs='http://packages.python.org/Flask-Genshi/' - ), - Extension('flask-mail', 'Dan Jacob', - description=''' -

Makes sending mails from Flask applications very easy and - has also support for unittesting. - ''', - bitbucket='danjac/flask-mail', - docs='http://packages.python.org/flask-mail/' - ), - Extension('Flask-WTF', 'Dan Jacob', - description=''' -

Flask-WTF offers simple integration with WTForms. This - integration includes optional CSRF handling for greater security. - ''', - bitbucket='danjac/flask-wtf', - docs='http://packages.python.org/Flask-WTF/' - ), - Extension('Flask-Testing', 'Dan Jacob', - description=''' -

The Flask-Testing extension provides unit testing utilities for Flask. - ''', - bitbucket='danjac/flask-testing', - docs='http://packages.python.org/Flask-Testing/' - ), - Extension('Flask-Script', 'Dan Jacob', - description=''' -

The Flask-Script extension provides support for writing external - scripts in Flask. It uses argparse to parse command line arguments. - ''', - bitbucket='danjac/flask-script', - docs='http://packages.python.org/Flask-Script/' - ), - Extension('flask-csrf', 'Steve Losh', - description=''' -

A small Flask extension for adding - CSRF protection. - ''', - docs='http://sjl.bitbucket.org/flask-csrf/', - bitbucket='sjl/flask-csrf' - ), - Extension('flask-lesscss', 'Steve Losh', - description=''' -

- A small Flask extension that makes it easy to use - LessCSS with your - Flask application. - ''', - docs='http://sjl.bitbucket.org/flask-lesscss/', - bitbucket='sjl/flask-lesscss' - ), - Extension('flask-urls', 'Steve Losh', - description=''' -

- A collection of URL-related functions for Flask applications. - ''', - docs='http://sjl.bitbucket.org/flask-urls/', - bitbucket='sjl/flask-urls' - ) -] -database.sort(key=lambda x: x.name.lower()) +mod = Module(__name__, url_prefix='/extensions') -@extensions.route('/') +@mod.route('/') def index(): - return render_template('extensions/index.html', extensions=database) + return render_template('extensions/index.html', extensions=extensions) -@extensions.route('/creating/') +@mod.route('/creating/') def creating(): return render_template('extensions/creating.html') diff --git a/flask_website/views/general.py b/flask_website/views/general.py index 3daaae6f..4f318e9f 100644 --- a/flask_website/views/general.py +++ b/flask_website/views/general.py @@ -6,15 +6,15 @@ from flask_website.twitter import flask_tweets from flask_website.utils import requires_login from flask_website.database import db_session, User -general = Module(__name__) +mod = Module(__name__) -@general.route('/') +@mod.route('/') def index(): return render_template('general/index.html', tweets=flask_tweets) -@general.route('/logout/') +@mod.route('/logout/') def logout(): if 'openid' in session: flash(u'Logged out') @@ -22,7 +22,7 @@ def logout(): return redirect(request.referrer or url_for('general.index')) -@general.route('/login/', methods=['GET', 'POST']) +@mod.route('/login/', methods=['GET', 'POST']) @oid.loginhandler def login(): if g.user is not None: @@ -41,7 +41,7 @@ def login(): return render_template('general/login.html', next=oid.get_next_url()) -@general.route('/first-login/', methods=['GET', 'POST']) +@mod.route('/first-login/', methods=['GET', 'POST']) def first_login(): if g.user is not None or 'openid' not in session: return redirect(url_for('login')) @@ -59,7 +59,7 @@ def first_login(): openid=session['openid']) -@general.route('/profile/', methods=['GET', 'POST']) +@mod.route('/profile/', methods=['GET', 'POST']) @requires_login def profile(): name = g.user.name @@ -75,7 +75,7 @@ def profile(): return render_template('general/profile.html', name=name) -@general.route('/profile/change-openid/', methods=['GET', 'POST']) +@mod.route('/profile/change-openid/', methods=['GET', 'POST']) @requires_login @oid.loginhandler def change_openid(): diff --git a/flask_website/views/mailinglist.py b/flask_website/views/mailinglist.py index c24b7a87..5fbd5003 100644 --- a/flask_website/views/mailinglist.py +++ b/flask_website/views/mailinglist.py @@ -8,7 +8,7 @@ from flask import Module, render_template, json, url_for, abort, Markup from flask_website.utils import split_lines_wrapping from flask_website import config -mailinglist = Module(__name__, url_prefix='/mailinglist') +mod = Module(__name__, url_prefix='/mailinglist') class Mail(object): @@ -73,13 +73,13 @@ class Thread(object): slug=self.slug) -@mailinglist.route('/') +@mod.route('/') def index(): return render_template('mailinglist/index.html') -@mailinglist.route('/archive/', defaults={'page': 1}) -@mailinglist.route('/archive/page//') +@mod.route('/archive/', defaults={'page': 1}) +@mod.route('/archive/page//') def archive(page): all_threads = Thread.get_list() offset = (page - 1) * config.THREADS_PER_PAGE @@ -91,7 +91,7 @@ def archive(page): page_count=page_count, page=page, threads=threads) -@mailinglist.route('/archive/////') +@mod.route('/archive/////') def show_thread(year, month, day, slug): thread = Thread.get(year, month, day, slug) if thread is None: diff --git a/flask_website/views/snippets.py b/flask_website/views/snippets.py index 63a1e642..4c13849e 100644 --- a/flask_website/views/snippets.py +++ b/flask_website/views/snippets.py @@ -6,17 +6,17 @@ from werkzeug.contrib.atom import AtomFeed from flask_website.utils import requires_login, requires_admin, format_creole from flask_website.database import Category, Snippet, Comment, db_session -snippets = Module(__name__, url_prefix='/snippets') +mod = Module(__name__, url_prefix='/snippets') -@snippets.route('/') +@mod.route('/') def index(): return render_template('snippets/index.html', categories=Category.query.order_by(Category.name).all(), recent=Snippet.query.order_by(Snippet.pub_date.desc()).limit(5).all()) -@snippets.route('/new/', methods=['GET', 'POST']) +@mod.route('/new/', methods=['GET', 'POST']) @requires_login def new(): category_id = None @@ -47,7 +47,7 @@ def new(): active_category=category_id, preview=preview) -@snippets.route('//', methods=['GET', 'POST']) +@mod.route('//', methods=['GET', 'POST']) def show(id): snippet = Snippet.query.get(id) if snippet is None: @@ -63,7 +63,7 @@ def show(id): return render_template('snippets/show.html', snippet=snippet) -@snippets.route('/comments//', methods=['GET', 'POST']) +@mod.route('/comments//', methods=['GET', 'POST']) @requires_admin def edit_comment(id): comment = Comment.query.get(id) @@ -92,7 +92,7 @@ def edit_comment(id): comment=comment) -@snippets.route('/edit//', methods=['GET', 'POST']) +@mod.route('/edit//', methods=['GET', 'POST']) @requires_login def edit(id): snippet = Snippet.query.get(id) @@ -134,7 +134,7 @@ def edit(id): categories=Category.query.order_by(Category.name).all()) -@snippets.route('/category//') +@mod.route('/category//') def category(slug): category = Category.query.filter_by(slug=slug).first() if category is None: @@ -144,7 +144,7 @@ def category(slug): snippets=snippets) -@snippets.route('/manage-categories/', methods=['GET', 'POST']) +@mod.route('/manage-categories/', methods=['GET', 'POST']) @requires_admin def manage_categories(): categories = Category.query.order_by(Category.name).all() @@ -159,7 +159,7 @@ def manage_categories(): categories=categories) -@snippets.route('/new-category/', methods=['POST']) +@mod.route('/new-category/', methods=['POST']) @requires_admin def new_category(): category = Category(name=request.form['name']) @@ -169,7 +169,7 @@ def new_category(): return redirect(url_for('manage_categories')) -@snippets.route('/delete-category//', methods=['GET', 'POST']) +@mod.route('/delete-category//', methods=['GET', 'POST']) @requires_admin def delete_category(id): category = Category.query.get(id) @@ -202,7 +202,7 @@ def delete_category(id): .filter(Category.id != category.id).all()) -@snippets.route('/recent.atom') +@mod.route('/recent.atom') def recent_feed(): feed = AtomFeed(u'Recent Flask Snippets', subtitle=u'Recent additions to the Flask snippet archive', @@ -216,7 +216,7 @@ def recent_feed(): return feed.get_response() -@snippets.route('/snippets//comments.atom') +@mod.route('/snippets//comments.atom') def comments_feed(id): snippet = Snippet.query.get(id) if snippet is None: