Merge branch 'master' of gitorious.org:mediagoblin/mediagoblin into metadata

Conflicts:
	mediagoblin/gmg_commands/__init__.py
This commit is contained in:
tilly-Q 2014-05-13 15:24:59 -04:00
commit 1d09e8b4f1
16 changed files with 146 additions and 18 deletions

1
.gitignore vendored
View File

@ -7,6 +7,7 @@
/build/
/eggs/
/lib/
/lib64
/local/
/include/
/parts/

View File

@ -19,6 +19,7 @@ Thank you!
* Asheesh Laroia
* Bassam Kurdali
* Bernhard Keller
* Berker Peksag
* Boris Bobrov
* Brandon Invergo
* Brett Smith

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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.

View File

@ -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',

View File

@ -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.'

View File

@ -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).

View File

@ -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' %}

View File

@ -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)

View File

@ -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)