Merge branch 'master' of gitorious.org:mediagoblin/mediagoblin into metadata
Conflicts: mediagoblin/gmg_commands/__init__.py
This commit is contained in:
commit
1d09e8b4f1
1
.gitignore
vendored
1
.gitignore
vendored
@ -7,6 +7,7 @@
|
||||
/build/
|
||||
/eggs/
|
||||
/lib/
|
||||
/lib64
|
||||
/local/
|
||||
/include/
|
||||
/parts/
|
||||
|
1
AUTHORS
1
AUTHORS
@ -19,6 +19,7 @@ Thank you!
|
||||
* Asheesh Laroia
|
||||
* Bassam Kurdali
|
||||
* Bernhard Keller
|
||||
* Berker Peksag
|
||||
* Boris Bobrov
|
||||
* Brandon Invergo
|
||||
* Brett Smith
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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',
|
||||
|
38
mediagoblin/gmg_commands/deletemedia.py
Normal file
38
mediagoblin/gmg_commands/deletemedia.py
Normal 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.'
|
@ -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') }}"/>
|
||||
|
@ -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).
|
||||
|
||||
|
@ -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' %}
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user