diff options
-rw-r--r-- | mediagoblin/app.py | 4 | ||||
-rw-r--r-- | mediagoblin/config_spec.ini | 3 | ||||
-rw-r--r-- | mediagoblin/db/mixin.py | 3 | ||||
-rw-r--r-- | mediagoblin/db/util.py | 9 | ||||
-rw-r--r-- | mediagoblin/edit/views.py | 4 | ||||
-rw-r--r-- | mediagoblin/meddleware/csrf.py | 12 | ||||
-rw-r--r-- | mediagoblin/templates/mediagoblin/base.html | 8 | ||||
-rw-r--r-- | mediagoblin/templates/mediagoblin/bits/logo.html | 25 | ||||
-rw-r--r-- | mediagoblin/templates/mediagoblin/root.html | 7 | ||||
-rw-r--r-- | mediagoblin/templates/mediagoblin/user_pages/collection.html | 4 | ||||
-rw-r--r-- | mediagoblin/templates/mediagoblin/user_pages/collection_list.html | 56 | ||||
-rw-r--r-- | mediagoblin/tests/tools.py | 5 | ||||
-rw-r--r-- | mediagoblin/themes/airy/templates/mediagoblin/base.html | 98 | ||||
-rw-r--r-- | mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html | 25 | ||||
-rw-r--r-- | mediagoblin/user_pages/routing.py | 4 | ||||
-rw-r--r-- | mediagoblin/user_pages/views.py | 13 |
16 files changed, 154 insertions, 126 deletions
diff --git a/mediagoblin/app.py b/mediagoblin/app.py index c1636693..10fbf4a3 100644 --- a/mediagoblin/app.py +++ b/mediagoblin/app.py @@ -22,6 +22,7 @@ from mediagoblin.tools.routing import endpoint_to_controller from werkzeug.wrappers import Request from werkzeug.exceptions import HTTPException, NotFound +from werkzeug.routing import RequestRedirect from mediagoblin import meddleware, __version__ from mediagoblin.tools import common, translate, template @@ -186,6 +187,9 @@ class MediaGoblinApp(object): try: found_rule, url_values = map_adapter.match(return_rule=True) request.matchdict = url_values + except RequestRedirect as response: + # Deal with 301 responses eg due to missing final slash + return response(environ, start_response) except HTTPException as exc: # Stop and render exception return render_http_exception( diff --git a/mediagoblin/config_spec.ini b/mediagoblin/config_spec.ini index 17df2819..bee67d46 100644 --- a/mediagoblin/config_spec.ini +++ b/mediagoblin/config_spec.ini @@ -9,9 +9,6 @@ source_link = string(default="https://gitorious.org/mediagoblin/mediagoblin") media_types = string_list(default=list("mediagoblin.media_types.image")) # database stuff -db_host = string() -db_name = string(default="mediagoblin") -db_port = integer() sql_engine = string(default="sqlite:///%(here)s/mediagoblin.db") # Where temporary files used in processing and etc are kept diff --git a/mediagoblin/db/mixin.py b/mediagoblin/db/mixin.py index 9829bb6e..001b7826 100644 --- a/mediagoblin/db/mixin.py +++ b/mediagoblin/db/mixin.py @@ -58,8 +58,7 @@ class MediaEntryMixin(object): self.slug = slugify(self.title) - duplicate = check_media_slug_used(mg_globals.database, - self.uploader, self.slug, self.id) + duplicate = check_media_slug_used(self.uploader, self.slug, self.id) if duplicate: if self.id is not None: diff --git a/mediagoblin/db/util.py b/mediagoblin/db/util.py index 90383f81..529ef8b9 100644 --- a/mediagoblin/db/util.py +++ b/mediagoblin/db/util.py @@ -29,12 +29,11 @@ def atomic_update(table, query_dict, update_values): Session.commit() -def check_media_slug_used(dummy_db, uploader_id, slug, ignore_m_id): - filt = (MediaEntry.uploader == uploader_id) \ - & (MediaEntry.slug == slug) +def check_media_slug_used(uploader_id, slug, ignore_m_id): + query = MediaEntry.query.filter_by(uploader=uploader_id, slug=slug) if ignore_m_id is not None: - filt = filt & (MediaEntry.id != ignore_m_id) - does_exist = Session.query(MediaEntry.id).filter(filt).first() is not None + query = query.filter(MediaEntry.id != ignore_m_id) + does_exist = query.first() is not None return does_exist diff --git a/mediagoblin/edit/views.py b/mediagoblin/edit/views.py index 505106a4..9b7cab46 100644 --- a/mediagoblin/edit/views.py +++ b/mediagoblin/edit/views.py @@ -58,8 +58,8 @@ def edit_media(request, media): if request.method == 'POST' and form.validate(): # Make sure there isn't already a MediaEntry with such a slug # and userid. - slug_used = check_media_slug_used(request.db, media.uploader, - request.form['slug'], media.id) + slug_used = check_media_slug_used(media.uploader, request.form['slug'], + media.id) if slug_used: form.slug.errors.append( diff --git a/mediagoblin/meddleware/csrf.py b/mediagoblin/meddleware/csrf.py index 2984ebb9..661f0ba2 100644 --- a/mediagoblin/meddleware/csrf.py +++ b/mediagoblin/meddleware/csrf.py @@ -22,6 +22,7 @@ from wtforms import Form, HiddenField, validators from mediagoblin import mg_globals from mediagoblin.meddleware import BaseMeddleware +from mediagoblin.tools.translate import lazy_pass_to_ugettext as _ _log = logging.getLogger(__name__) @@ -127,10 +128,13 @@ class CsrfMeddleware(BaseMeddleware): None) if cookie_token is None: - # the CSRF cookie must be present in the request - errstr = 'CSRF cookie not present' - _log.error(errstr) - raise Forbidden(errstr) + # the CSRF cookie must be present in the request, if not a + # cookie blocker might be in action (in the best case) + _log.error('CSRF cookie not present') + raise Forbidden(_('CSRF cookie not present. This is most likely ' + 'the result of a cookie blocker or somesuch.<br/>' + 'Make sure to permit the settings of cookies for ' + 'this domain.')) # get the form token and confirm it matches form = CsrfForm(request.form) diff --git a/mediagoblin/templates/mediagoblin/base.html b/mediagoblin/templates/mediagoblin/base.html index 3f5e2c79..0a9a56d3 100644 --- a/mediagoblin/templates/mediagoblin/base.html +++ b/mediagoblin/templates/mediagoblin/base.html @@ -41,13 +41,7 @@ {% block mediagoblin_body %} {% block mediagoblin_header %} <header> - {% block mediagoblin_logo %} - <a class="logo" - href="{{ request.urlgen('index') }}" - ><img src="{{ request.staticdirect('/images/logo.png') }}" - alt="{% trans %}MediaGoblin logo{% endtrans %}" /> - </a> - {% endblock mediagoblin_logo %} + {%- include "mediagoblin/bits/logo.html" -%} {% block mediagoblin_header_title %}{% endblock %} <div class="header_right"> {% if request.user %} diff --git a/mediagoblin/templates/mediagoblin/bits/logo.html b/mediagoblin/templates/mediagoblin/bits/logo.html new file mode 100644 index 00000000..5bd8edd8 --- /dev/null +++ b/mediagoblin/templates/mediagoblin/bits/logo.html @@ -0,0 +1,25 @@ +{# +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +-#} + +{% block mediagoblin_logo %} + <a class="logo" + href="{{ request.urlgen('index') }}" + ><img src="{{ request.staticdirect('/images/logo.png') }}" + alt="{% trans %}MediaGoblin logo{% endtrans %}" /> + </a> +{% endblock mediagoblin_logo -%} diff --git a/mediagoblin/templates/mediagoblin/root.html b/mediagoblin/templates/mediagoblin/root.html index 047dd2bb..11e8f2ac 100644 --- a/mediagoblin/templates/mediagoblin/root.html +++ b/mediagoblin/templates/mediagoblin/root.html @@ -27,9 +27,10 @@ <li><a href="{{ request.urlgen('mediagoblin.submit.start') }}"> {%- trans %}Add media{% endtrans -%} </a></li> - <li><a href="{{ request.urlgen('mediagoblin.submit.collection') }}"> - {%- trans %}Create new collection{% endtrans -%} - </a></li> + <li><a href="{{ request.urlgen('mediagoblin.user_pages.collection_list', + user=request.user.username) }}"> + {%- trans %}Browse collections{% endtrans -%} + </a></li> <li><a href="{{ request.urlgen('mediagoblin.edit.account') }}"> {%- trans %}Change account settings{% endtrans -%} </a></li> diff --git a/mediagoblin/templates/mediagoblin/user_pages/collection.html b/mediagoblin/templates/mediagoblin/user_pages/collection.html index f1ab7a42..5a7baadd 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/collection.html +++ b/mediagoblin/templates/mediagoblin/user_pages/collection.html @@ -57,7 +57,9 @@ {% endif %} <p> - {{ collection.description }} + {% autoescape False %} + {{ collection.description_html }} + {% endautoescape %} </p> {{ collection_gallery(request, collection_items, pagination) }} diff --git a/mediagoblin/templates/mediagoblin/user_pages/collection_list.html b/mediagoblin/templates/mediagoblin/user_pages/collection_list.html new file mode 100644 index 00000000..abf22623 --- /dev/null +++ b/mediagoblin/templates/mediagoblin/user_pages/collection_list.html @@ -0,0 +1,56 @@ +{# +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +#} +{% extends "mediagoblin/base.html" %} + +{% block title %} + {%- trans username=user.username -%} + {{ username }}'s collections + {%- endtrans %} — {{ super() }} +{% endblock %} + +{% block mediagoblin_content -%} + <h1> + {%- trans username=user.username, + user_url=request.urlgen( + 'mediagoblin.user_pages.user_home', + user=user.username) -%} + <a href="{{ user_url }}">{{ username }}</a>'s collections + {%- endtrans %} + </h1> + + {% if request.user %} + {% if request.user.status == 'active' %} + <p> + <a href="{{ request.urlgen('mediagoblin.submit.collection', + user=user.username) }}"> + {%- trans %}Create new collection{% endtrans -%} + </p> + {% endif %} + {% endif %} + + <ul> + {% for coll in collections %} + {% set coll_url = request.urlgen( + 'mediagoblin.user_pages.user_collection', + user=user.username, + collection=coll.slug) %} + <li><a href="{{ coll_url }}">{{ coll.title }}</li> + {% endfor %} + </ul> + +{% endblock %} diff --git a/mediagoblin/tests/tools.py b/mediagoblin/tests/tools.py index 11c0c510..3e78b2e3 100644 --- a/mediagoblin/tests/tools.py +++ b/mediagoblin/tests/tools.py @@ -205,7 +205,10 @@ def assert_db_meets_expected(db, expected): def fixture_add_user(username=u'chris', password=u'toast', active_user=True): - test_user = User.query.filter_by(username=username).first() or User() + # Reuse existing user or create a new one + test_user = User.query.filter_by(username=username).first() + if test_user is None: + test_user = User() test_user.username = username test_user.email = username + u'@example.com' if password is not None: diff --git a/mediagoblin/themes/airy/templates/mediagoblin/base.html b/mediagoblin/themes/airy/templates/mediagoblin/base.html deleted file mode 100644 index 6e177ddb..00000000 --- a/mediagoblin/themes/airy/templates/mediagoblin/base.html +++ /dev/null @@ -1,98 +0,0 @@ -{# -# GNU MediaGoblin -- federated, autonomous media hosting -# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS. -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. --#} -<!doctype html> -<html> - <head> - <meta charset="utf-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>{% block title %}{{ app_config['html_title'] }}{% endblock %}</title> - <link rel="stylesheet" type="text/css" - href="{{ request.staticdirect('/css/extlib/reset.css') }}"/> - <link rel="stylesheet" type="text/css" - href="{{ request.staticdirect('/css/base.css') }}"/> - <link rel="shortcut icon" - href="{{ request.staticdirect('/images/goblin.ico') }}" /> - <script src="{{ request.staticdirect('/js/extlib/jquery.js') }}"></script> - <!--[if lt IE 9]> - <script src="{{ request.staticdirect('/js/extlib/html5shiv.js') }}"></script> - <![endif]--> - - {% include "mediagoblin/extra_head.html" %} - - {% block mediagoblin_head %} - {% endblock mediagoblin_head %} - </head> - <body> - {% block mediagoblin_body %} - {% block mediagoblin_header %} - <header> - {% block mediagoblin_logo %} - <a class="logo" - href="{{ request.urlgen('index') }}"> - <img src="{{ request.staticdirect('/images/logo.png', 'theme') }}" - alt="{% trans %}MediaGoblin logo{% endtrans %}" /> - </a> - {% endblock mediagoblin_logo %} - {% block mediagoblin_header_title %}{% endblock %} - <div class="header_right"> - {% if request.user %} - {% trans - user_url=request.urlgen('mediagoblin.user_pages.user_home', - user= request.user.username), - user_name=request.user.username -%} - <a href="{{ user_url }}">{{ user_name }}</a>'s account - {%- endtrans %} - (<a href="{{ request.urlgen('mediagoblin.auth.logout') }}">{% trans %}log out{% endtrans %}</a>) - {% if request.user and request.user.status == 'active' %} - <a class="button_action" href="{{ request.urlgen('mediagoblin.submit.start') }}">{% trans %}Add media{% endtrans %}</a> - {% elif request.user and request.user.status == "needs_email_verification" %} - {# the following link should only appear when verification is needed #} - <a href="{{ request.urlgen('mediagoblin.user_pages.user_home', - user=request.user.username) }}" - class="button_action_highlight"> - {% trans %}Verify your email!{% endtrans %}</a> - {% endif %} - {% else %} - <a href="{{ request.urlgen('mediagoblin.auth.login') }}?next={{ - request.base_url|urlencode }}"> - {% trans %}Log in{% endtrans %}</a> - {% endif %} - </div> - <div class="clear"></div> - </header> - {% endblock %} - <div class="container"> - <div class="mediagoblin_content"> - {% include "mediagoblin/utils/messages.html" %} - {% block mediagoblin_content %} - {% endblock mediagoblin_content %} - </div> - {% block mediagoblin_footer %} - <footer> - {% trans -%} - Powered by <a href="http://mediagoblin.org">MediaGoblin</a>, a <a href="http://gnu.org/">GNU</a> project. - {%- endtrans %} - {% trans source_link=app_config['source_link'] -%} - Released under the <a href="http://www.fsf.org/licensing/licenses/agpl-3.0.html">AGPL</a>. <a href="{{ source_link }}">Source code</a> available. - {%- endtrans %} - </footer> - {% endblock mediagoblin_footer %} - {% endblock mediagoblin_body %} - </div> - </body> -</html> diff --git a/mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html b/mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html new file mode 100644 index 00000000..c8500159 --- /dev/null +++ b/mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html @@ -0,0 +1,25 @@ +{# +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2012 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +-#} + +{% block mediagoblin_logo %} + <a class="logo" + href="{{ request.urlgen('index') }}"> + <img src="{{ request.staticdirect('/images/logo.png', 'theme') }}" + alt="{% trans %}MediaGoblin logo{% endtrans %}" /> + </a> +{% endblock mediagoblin_logo -%} diff --git a/mediagoblin/user_pages/routing.py b/mediagoblin/user_pages/routing.py index d36e7598..a9431405 100644 --- a/mediagoblin/user_pages/routing.py +++ b/mediagoblin/user_pages/routing.py @@ -48,6 +48,10 @@ add_route('mediagoblin.user_pages.media_collect', '/u/<string:user>/m/<string:media>/collect/', 'mediagoblin.user_pages.views:media_collect') +add_route('mediagoblin.user_pages.collection_list', + '/u/<string:user>/collections/', + 'mediagoblin.user_pages.views:collection_list') + add_route('mediagoblin.user_pages.user_collection', '/u/<string:user>/collection/<string:collection>/', 'mediagoblin.user_pages.views:user_collection') diff --git a/mediagoblin/user_pages/views.py b/mediagoblin/user_pages/views.py index a3327a9e..b9f03e8e 100644 --- a/mediagoblin/user_pages/views.py +++ b/mediagoblin/user_pages/views.py @@ -338,6 +338,19 @@ def user_collection(request, page, url_user=None): 'pagination': pagination}) +@active_user_from_url +def collection_list(request, url_user=None): + """A User-defined Collection""" + collections = Collection.query.filter_by( + get_creator=url_user) + + return render_to_response( + request, + 'mediagoblin/user_pages/collection_list.html', + {'user': url_user, + 'collections': collections}) + + @get_user_collection_item @require_active_login @user_may_alter_collection |