aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--AUTHORS1
-rw-r--r--docs/source/siteadmin/commandline-upload.rst8
-rw-r--r--mediagoblin.ini1
-rw-r--r--mediagoblin/auth/__init__.py1
-rw-r--r--mediagoblin/auth/tools.py14
-rw-r--r--mediagoblin/config_spec.ini3
-rw-r--r--mediagoblin/db/mixin.py6
-rw-r--r--mediagoblin/gmg_commands/__init__.py6
-rw-r--r--mediagoblin/gmg_commands/deletemedia.py38
-rw-r--r--mediagoblin/plugins/metadata_display/templates/mediagoblin/plugins/metadata_display/bits/metadata_extra_head.html2
-rw-r--r--mediagoblin/plugins/trim_whitespace/README.rst15
-rw-r--r--mediagoblin/templates/mediagoblin/base.html1
-rw-r--r--mediagoblin/tests/__init__.py41
-rw-r--r--mediagoblin/tests/test_modelmethods.py24
-rw-r--r--mediagoblin/tools/metadata.py2
16 files changed, 146 insertions, 18 deletions
diff --git a/.gitignore b/.gitignore
index b2189f82..2524739f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,6 +7,7 @@
/build/
/eggs/
/lib/
+/lib64
/local/
/include/
/parts/
diff --git a/AUTHORS b/AUTHORS
index 6fbc05a7..8ea903f5 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -19,6 +19,7 @@ Thank you!
* Asheesh Laroia
* Bassam Kurdali
* Bernhard Keller
+* Berker Peksag
* Boris Bobrov
* Brandon Invergo
* Brett Smith
diff --git a/docs/source/siteadmin/commandline-upload.rst b/docs/source/siteadmin/commandline-upload.rst
index d67c19dd..742c0cb2 100644
--- a/docs/source/siteadmin/commandline-upload.rst
+++ b/docs/source/siteadmin/commandline-upload.rst
@@ -63,16 +63,16 @@ The csv file
============
The media:location column
-------------------------
-The media:location column is the one column that is absolutely necessary for
+The media:location column is the one column that is absolutely necessary for
uploading your media. This gives a path to each piece of media you upload. This
-can either a path to a local file or a direct link to remote media (with the
+can either a path to a local file or a direct link to remote media (with the
link in http format). As you can see in the example above the (fake) media was
stored remotely on "www.example.net".
Other columns
-------------
Other columns can be used to provide detailed metadata about each media entry.
-Our metadata system accepts any information provided for in the
+Our metadata system accepts any information provided for in the
`RDFa Core Initial Context`_, and the batchupload script recognizes all of the
resources provided within it.
@@ -89,4 +89,4 @@ information of uploaded media entries.
- **dc:description** sets a description of your media entry. If this is left blank the media entry's description will not be filled in.
- **dc:rights** will set a license for your media entry `if` the data provided is a valid URI. If this is left blank 'All Rights Reserved' will be selected.
-You can of course, change these values later.
+You can of course, change these values later.
diff --git a/mediagoblin.ini b/mediagoblin.ini
index fe9d5cd2..4f94b6e4 100644
--- a/mediagoblin.ini
+++ b/mediagoblin.ini
@@ -35,6 +35,7 @@ allow_reporting = true
## If you want the terms of service displayed, you can uncomment this
# show_tos = true
+user_privilege_scheme = "uploader,commenter,reporter"
[storage:queuestore]
base_dir = %(here)s/user_dev/media/queue
diff --git a/mediagoblin/auth/__init__.py b/mediagoblin/auth/__init__.py
index be5d0eed..f518a09d 100644
--- a/mediagoblin/auth/__init__.py
+++ b/mediagoblin/auth/__init__.py
@@ -25,7 +25,6 @@ def create_user(register_form):
results = hook_runall("auth_create_user", register_form)
return results[0]
-
def extra_validation(register_form):
from mediagoblin.auth.tools import basic_extra_validation
diff --git a/mediagoblin/auth/tools.py b/mediagoblin/auth/tools.py
index 88716e1c..39df85af 100644
--- a/mediagoblin/auth/tools.py
+++ b/mediagoblin/auth/tools.py
@@ -132,11 +132,7 @@ def register_user(request, register_form):
user = auth.create_user(register_form)
# give the user the default privileges
- default_privileges = [
- Privilege.query.filter(Privilege.privilege_name==u'commenter').first(),
- Privilege.query.filter(Privilege.privilege_name==u'uploader').first(),
- Privilege.query.filter(Privilege.privilege_name==u'reporter').first()]
- user.all_privileges += default_privileges
+ user.all_privileges += get_default_privileges(user)
user.save()
# log the user in
@@ -151,6 +147,14 @@ def register_user(request, register_form):
return None
+def get_default_privileges(user):
+ instance_privilege_scheme = mg_globals.app_config['user_privilege_scheme']
+ default_privileges = [Privilege.query.filter(
+ Privilege.privilege_name==privilege_name).first()
+ for privilege_name in instance_privilege_scheme.split(',')]
+ default_privileges = [privilege for privilege in default_privileges if not privilege == None]
+
+ return default_privileges
def check_login_simple(username, password):
user = auth.get_user(username=username)
diff --git a/mediagoblin/config_spec.ini b/mediagoblin/config_spec.ini
index cc1ac637..ba2b4519 100644
--- a/mediagoblin/config_spec.ini
+++ b/mediagoblin/config_spec.ini
@@ -89,6 +89,9 @@ upload_limit = integer(default=None)
# Max file size (in Mb)
max_file_size = integer(default=None)
+# Privilege scheme
+user_privilege_scheme = string(default="uploader,commenter,reporter")
+
[jinja2]
# Jinja2 supports more directives than the minimum required by mediagoblin.
# This setting allows users creating custom templates to specify a list of
diff --git a/mediagoblin/db/mixin.py b/mediagoblin/db/mixin.py
index 25ce6642..048cc07c 100644
--- a/mediagoblin/db/mixin.py
+++ b/mediagoblin/db/mixin.py
@@ -46,6 +46,12 @@ class UserMixin(object):
def bio_html(self):
return cleaned_markdown_conversion(self.bio)
+ def url_for_self(self, urlgen, **kwargs):
+ """Generate a URL for this User's home page."""
+ return urlgen('mediagoblin.user_pages.user_home',
+ user=self.username, **kwargs)
+
+
class GenerateSlugMixin(object):
"""
Mixin to add a generate_slug method to objects.
diff --git a/mediagoblin/gmg_commands/__init__.py b/mediagoblin/gmg_commands/__init__.py
index 55e85116..fd546aac 100644
--- a/mediagoblin/gmg_commands/__init__.py
+++ b/mediagoblin/gmg_commands/__init__.py
@@ -53,10 +53,14 @@ SUBCOMMAND_MAP = {
'setup': 'mediagoblin.gmg_commands.addmedia:parser_setup',
'func': 'mediagoblin.gmg_commands.addmedia:addmedia',
'help': 'Reprocess media entries'},
+ 'deletemedia': {
+ 'setup': 'mediagoblin.gmg_commands.deletemedia:parser_setup',
+ 'func': 'mediagoblin.gmg_commands.deletemedia:deletemedia',
+ 'help': 'Delete media entries'},
'batchaddmedia': {
'setup': 'mediagoblin.gmg_commands.batchaddmedia:parser_setup',
'func': 'mediagoblin.gmg_commands.batchaddmedia:batchaddmedia',
- 'help': 'Add many media entries at once'}
+ 'help': 'Add many media entries at once'},
# 'theme': {
# 'setup': 'mediagoblin.gmg_commands.theme:theme_parser_setup',
# 'func': 'mediagoblin.gmg_commands.theme:theme',
diff --git a/mediagoblin/gmg_commands/deletemedia.py b/mediagoblin/gmg_commands/deletemedia.py
new file mode 100644
index 00000000..d08e76cc
--- /dev/null
+++ b/mediagoblin/gmg_commands/deletemedia.py
@@ -0,0 +1,38 @@
+# 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/>.
+
+from mediagoblin.gmg_commands import util as commands_util
+
+
+def parser_setup(subparser):
+ subparser.add_argument('media_ids',
+ help='Comma separated list of media IDs to will be deleted.')
+
+
+def deletemedia(args):
+ app = commands_util.setup_app(args)
+
+ media_ids = set(map(int, args.media_ids.split(',')))
+ found_medias = set()
+ filter_ids = app.db.MediaEntry.id.in_(media_ids)
+ medias = app.db.MediaEntry.query.filter(filter_ids).all()
+ for media in medias:
+ found_medias.add(media.id)
+ media.delete()
+ print 'Media ID %d has been deleted.' % media.id
+ for media in media_ids - found_medias:
+ print 'Can\'t find a media with ID %d.' % media
+ print 'Done.'
diff --git a/mediagoblin/plugins/metadata_display/templates/mediagoblin/plugins/metadata_display/bits/metadata_extra_head.html b/mediagoblin/plugins/metadata_display/templates/mediagoblin/plugins/metadata_display/bits/metadata_extra_head.html
index 84eedf18..4a380299 100644
--- a/mediagoblin/plugins/metadata_display/templates/mediagoblin/plugins/metadata_display/bits/metadata_extra_head.html
+++ b/mediagoblin/plugins/metadata_display/templates/mediagoblin/plugins/metadata_display/bits/metadata_extra_head.html
@@ -1,3 +1,3 @@
<link rel="stylesheet" type="text/css"
- href="{{ request.staticdirect('css/metadata_display.css',
+ href="{{ request.staticdirect('css/metadata_display.css',
'metadata_display') }}"/>
diff --git a/mediagoblin/plugins/trim_whitespace/README.rst b/mediagoblin/plugins/trim_whitespace/README.rst
index b55ce35e..db9a0c53 100644
--- a/mediagoblin/plugins/trim_whitespace/README.rst
+++ b/mediagoblin/plugins/trim_whitespace/README.rst
@@ -3,17 +3,22 @@
=======================
Mediagoblin templates are written with 80 char limit for better
-readability. However that means that the html output is very verbose
-containing LOTS of whitespace. This plugin inserts a Middleware that
-filters out whitespace from the returned HTML in the Response() objects.
+readability. However that means that the HTML output is very verbose
+containing *lots* of whitespace. This plugin inserts a middleware that
+filters out whitespace from the returned HTML in the ``Response()``
+objects.
-Simply enable this plugin by putting it somewhere where python can reach it and put it's path into the [plugins] section of your mediagoblin.ini or mediagoblin_local.ini like for example this:
+Simply enable this plugin by putting it somewhere where Python can reach
+it and put it's path into the ``[plugins]`` section of your
+``mediagoblin.ini`` or ``mediagoblin_local.ini`` like for example this:
+
+.. code-block:: ini
[plugins]
[[mediagoblin.plugins.trim_whitespace]]
There is no further configuration required. If this plugin is enabled,
-all text/html documents should not have lots of whitespace in between
+all *text/html* documents should not have lots of whitespace in between
elements, although it does a very naive filtering right now (just keep
the first whitespace and delete all subsequent ones).
diff --git a/mediagoblin/templates/mediagoblin/base.html b/mediagoblin/templates/mediagoblin/base.html
index b4c7eb8b..28b9c63c 100644
--- a/mediagoblin/templates/mediagoblin/base.html
+++ b/mediagoblin/templates/mediagoblin/base.html
@@ -165,6 +165,7 @@
<a href="{{ request.urlgen('mediagoblin.moderation.reports') }}">
{%- trans %}Report management panel{% endtrans -%}
</a>
+ {% template_hook("moderation_powers") %}
</p>
{% endif %}
{% include 'mediagoblin/fragments/header_notifications.html' %}
diff --git a/mediagoblin/tests/__init__.py b/mediagoblin/tests/__init__.py
index cf200791..fbf3fc6c 100644
--- a/mediagoblin/tests/__init__.py
+++ b/mediagoblin/tests/__init__.py
@@ -14,9 +14,50 @@
# 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/>.
+import pytest
+
+from mediagoblin.db.models import User
+from mediagoblin.tests.tools import fixture_add_user
+from mediagoblin.tools import template
+
def setup_package():
import warnings
from sqlalchemy.exc import SAWarning
warnings.simplefilter("error", SAWarning)
+
+
+class MGClientTestCase:
+
+ usernames = None
+
+ @pytest.fixture(autouse=True)
+ def setup(self, test_app):
+ self.test_app = test_app
+
+ if self.usernames is None:
+ msg = ('The usernames attribute should be overridden '
+ 'in the subclass')
+ raise pytest.skip(msg)
+ for username, options in self.usernames:
+ fixture_add_user(username, **options)
+
+ def user(self, username):
+ return User.query.filter(User.username == username).first()
+
+ def _do_request(self, url, *context_keys, **kwargs):
+ template.clear_test_template_context()
+ response = self.test_app.request(url, **kwargs)
+ context_data = template.TEMPLATE_TEST_CONTEXT
+ for key in context_keys:
+ context_data = context_data[key]
+ return response, context_data
+
+ def do_get(self, url, *context_keys, **kwargs):
+ kwargs['method'] = 'GET'
+ return self._do_request(url, *context_keys, **kwargs)
+
+ def do_post(self, url, *context_keys, **kwargs):
+ kwargs['method'] = 'POST'
+ return self._do_request(url, *context_keys, **kwargs)
diff --git a/mediagoblin/tests/test_modelmethods.py b/mediagoblin/tests/test_modelmethods.py
index 86513c76..ca436c76 100644
--- a/mediagoblin/tests/test_modelmethods.py
+++ b/mediagoblin/tests/test_modelmethods.py
@@ -20,9 +20,11 @@
from mediagoblin.db.base import Session
from mediagoblin.db.models import MediaEntry, User, Privilege
+from mediagoblin.tests import MGClientTestCase
from mediagoblin.tests.tools import fixture_add_user
import mock
+import pytest
class FakeUUID(object):
@@ -30,6 +32,8 @@ class FakeUUID(object):
UUID_MOCK = mock.Mock(return_value=FakeUUID())
+REQUEST_CONTEXT = ['mediagoblin/root.html', 'request']
+
class TestMediaEntrySlugs(object):
def _setup(self):
@@ -204,3 +208,23 @@ def test_media_data_init(test_app):
print repr(obj)
assert obj_in_session == 0
+
+class TestUserUrlForSelf(MGClientTestCase):
+
+ usernames = [(u'lindsay', dict(privileges=[u'active']))]
+
+ def test_url_for_self(self):
+ _, request = self.do_get('/', *REQUEST_CONTEXT)
+
+ assert self.user(u'lindsay').url_for_self(request.urlgen) == '/u/lindsay/'
+
+ def test_url_for_self_not_callable(self):
+ _, request = self.do_get('/', *REQUEST_CONTEXT)
+
+ def fake_urlgen():
+ pass
+
+ with pytest.raises(TypeError) as excinfo:
+ self.user(u'lindsay').url_for_self(fake_urlgen())
+ assert excinfo.errisinstance(TypeError)
+ assert 'object is not callable' in str(excinfo)
diff --git a/mediagoblin/tools/metadata.py b/mediagoblin/tools/metadata.py
index 3f10e9d1..b0cad9da 100644
--- a/mediagoblin/tools/metadata.py
+++ b/mediagoblin/tools/metadata.py
@@ -131,7 +131,7 @@ def load_context(url):
stores internally, load them from disk.
"""
if url in _CONTEXT_CACHE:
- return _CONTEXT_CACHE[url]
+ return _CONTEXT_CACHE[url]
# See if it's one of our basic ones
document = BUILTIN_CONTEXTS.get(url, None)