aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mediagoblin/app.py4
-rw-r--r--mediagoblin/config_spec.ini3
-rw-r--r--mediagoblin/db/mixin.py3
-rw-r--r--mediagoblin/db/util.py9
-rw-r--r--mediagoblin/edit/views.py4
-rw-r--r--mediagoblin/meddleware/csrf.py12
-rw-r--r--mediagoblin/templates/mediagoblin/base.html8
-rw-r--r--mediagoblin/templates/mediagoblin/bits/logo.html25
-rw-r--r--mediagoblin/templates/mediagoblin/root.html7
-rw-r--r--mediagoblin/templates/mediagoblin/user_pages/collection.html4
-rw-r--r--mediagoblin/templates/mediagoblin/user_pages/collection_list.html56
-rw-r--r--mediagoblin/tests/tools.py5
-rw-r--r--mediagoblin/themes/airy/templates/mediagoblin/base.html98
-rw-r--r--mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html25
-rw-r--r--mediagoblin/user_pages/routing.py4
-rw-r--r--mediagoblin/user_pages/views.py13
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 %} &mdash; {{ 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