diff options
author | Christopher Allan Webber <cwebber@dustycloud.org> | 2011-08-10 19:53:37 -0500 |
---|---|---|
committer | Christopher Allan Webber <cwebber@dustycloud.org> | 2011-08-10 19:53:37 -0500 |
commit | 852d5bb2387706c11925fa0c2abe4a1f34708f16 (patch) | |
tree | df5e6a3108d2ba007112b558ff65bbfabd88020c /mediagoblin | |
parent | 6b9ee0ca13b99ee20f9d0c680a950c6a7494a5a0 (diff) | |
parent | 6d794f268bb1f5d3cc56c5f0dc902571d48ebeac (diff) | |
download | mediagoblin-852d5bb2387706c11925fa0c2abe4a1f34708f16.tar.lz mediagoblin-852d5bb2387706c11925fa0c2abe4a1f34708f16.tar.xz mediagoblin-852d5bb2387706c11925fa0c2abe4a1f34708f16.zip |
Merge branch 'master' into processing
Diffstat (limited to 'mediagoblin')
83 files changed, 4350 insertions, 1092 deletions
diff --git a/mediagoblin/app.py b/mediagoblin/app.py index 85c3c0c7..c1ee3d77 100644 --- a/mediagoblin/app.py +++ b/mediagoblin/app.py @@ -20,11 +20,12 @@ import urllib import routes from webob import Request, exc -from mediagoblin import routing, util, storage +from mediagoblin import routing, util from mediagoblin.mg_globals import setup_globals from mediagoblin.init.celery import setup_celery_from_config -from mediagoblin.init import get_jinja_loader, get_staticdirector, \ - setup_global_and_app_config, setup_workbench, setup_database +from mediagoblin.init import (get_jinja_loader, get_staticdirector, + setup_global_and_app_config, setup_workbench, setup_database, + setup_storage) class MediaGoblinApp(object): @@ -62,10 +63,7 @@ class MediaGoblinApp(object): app_config.get('user_template_path')) # Set up storage systems - self.public_store = storage.storage_system_from_config( - app_config, 'publicstore') - self.queue_store = storage.storage_system_from_config( - app_config, 'queuestore') + self.public_store, self.queue_store = setup_storage() # set up routing self.routing = routing.get_mapper() @@ -90,10 +88,7 @@ class MediaGoblinApp(object): # object. ####################################################### - setup_globals( - app=self, - public_store=self.public_store, - queue_store=self.queue_store) + setup_globals(app = self) # Workbench *currently* only used by celery, so this only # matters in always eager mode :) diff --git a/mediagoblin/auth/forms.py b/mediagoblin/auth/forms.py index 7bc0aeb1..917909c5 100644 --- a/mediagoblin/auth/forms.py +++ b/mediagoblin/auth/forms.py @@ -16,34 +16,36 @@ import wtforms +from mediagoblin.util import fake_ugettext_passthrough as _ + class RegistrationForm(wtforms.Form): username = wtforms.TextField( - 'Username', + _('Username'), [wtforms.validators.Required(), wtforms.validators.Length(min=3, max=30), wtforms.validators.Regexp(r'^\w+$')]) password = wtforms.PasswordField( - 'Password', + _('Password'), [wtforms.validators.Required(), wtforms.validators.Length(min=6, max=30), wtforms.validators.EqualTo( 'confirm_password', - 'Passwords must match.')]) + _('Passwords must match.'))]) confirm_password = wtforms.PasswordField( - 'Confirm password', + _('Confirm password'), [wtforms.validators.Required()]) email = wtforms.TextField( - 'Email address', + _('Email address'), [wtforms.validators.Required(), wtforms.validators.Email()]) class LoginForm(wtforms.Form): username = wtforms.TextField( - 'Username', + _('Username'), [wtforms.validators.Required(), wtforms.validators.Regexp(r'^\w+$')]) password = wtforms.PasswordField( - 'Password', + _('Password'), [wtforms.validators.Required()]) diff --git a/mediagoblin/auth/routing.py b/mediagoblin/auth/routing.py index 46c585d2..9547b3ea 100644 --- a/mediagoblin/auth/routing.py +++ b/mediagoblin/auth/routing.py @@ -19,18 +19,12 @@ from routes.route import Route auth_routes = [ Route('mediagoblin.auth.register', '/register/', controller='mediagoblin.auth.views:register'), - Route('mediagoblin.auth.register_success', '/register/success/', - template='mediagoblin/auth/register_success.html', - controller='mediagoblin.views:simple_template_render'), Route('mediagoblin.auth.login', '/login/', controller='mediagoblin.auth.views:login'), Route('mediagoblin.auth.logout', '/logout/', controller='mediagoblin.auth.views:logout'), Route('mediagoblin.auth.verify_email', '/verify_email/', controller='mediagoblin.auth.views:verify_email'), - Route('mediagoblin.auth.verify_email_notice', '/verification_required/', - template='mediagoblin/auth/verification_needed.html', - controller='mediagoblin.views:simple_template_render'), Route('mediagoblin.auth.resend_verification', '/resend_verification/', controller='mediagoblin.auth.views:resend_activation'), Route('mediagoblin.auth.resend_verification_success', diff --git a/mediagoblin/auth/views.py b/mediagoblin/auth/views.py index 7fe507b1..121a8c8e 100644 --- a/mediagoblin/auth/views.py +++ b/mediagoblin/auth/views.py @@ -21,6 +21,7 @@ from webob import exc from mediagoblin import messages from mediagoblin import mg_globals from mediagoblin.util import render_to_response, redirect +from mediagoblin.util import pass_to_ugettext as _ from mediagoblin.db.util import ObjectId from mediagoblin.auth import lib as auth_lib from mediagoblin.auth import forms as auth_forms @@ -36,7 +37,7 @@ def register(request): messages.add_message( request, messages.WARNING, - ('Sorry, registration is disabled on this instance.')) + _('Sorry, registration is disabled on this instance.')) return redirect(request, "index") register_form = auth_forms.RegistrationForm(request.POST) @@ -51,20 +52,29 @@ def register(request): if users_with_username: register_form.username.errors.append( - u'Sorry, a user with that name already exists.') + _(u'Sorry, a user with that name already exists.')) else: # Create the user - entry = request.db.User() - entry['username'] = request.POST['username'].lower() - entry['email'] = request.POST['email'] - entry['pw_hash'] = auth_lib.bcrypt_gen_password_hash( + user = request.db.User() + user['username'] = request.POST['username'].lower() + user['email'] = request.POST['email'] + user['pw_hash'] = auth_lib.bcrypt_gen_password_hash( request.POST['password']) - entry.save(validate=True) + user.save(validate=True) - send_verification_email(entry, request) + # log the user in + request.session['user_id'] = unicode(user['_id']) + request.session.save() - return redirect(request, "mediagoblin.auth.register_success") + # send verification email + send_verification_email(user, request) + + # redirect the user to their homepage... there will be a + # message waiting for them to verify their email + return redirect( + request, 'mediagoblin.user_pages.user_home', + user=user['username']) return render_to_response( request, @@ -136,23 +146,20 @@ def verify_email(request): user['status'] = u'active' user['email_verified'] = True user.save() - verification_successful = True messages.add_message( request, messages.SUCCESS, - ('Your email address has been verified. ' - 'You may now login, edit your profile, and submit images!')) + _("Your email address has been verified. " + "You may now login, edit your profile, and submit images!")) else: - verification_successful = False - messages.add_message(request, - messages.ERROR, - 'The verification key or user id is incorrect') + messages.add_message( + request, + messages.ERROR, + _('The verification key or user id is incorrect')) - return render_to_response( - request, - 'mediagoblin/user_pages/user.html', - {'user': user, - 'verification_successful' : verification_successful}) + return redirect( + request, 'mediagoblin.user_pages.user_home', + user=request.user['username']) def resend_activation(request): @@ -166,4 +173,10 @@ def resend_activation(request): send_verification_email(request.user, request) - return redirect(request, 'mediagoblin.auth.resend_verification_success') + messages.add_message( + request, + messages.INFO, + _('Resent your verification email.')) + return redirect( + request, 'mediagoblin.user_pages.user_home', + user=request.user['username']) diff --git a/mediagoblin/config_spec.ini b/mediagoblin/config_spec.ini index 28be5f34..bbc1f7d6 100644 --- a/mediagoblin/config_spec.ini +++ b/mediagoblin/config_spec.ini @@ -24,6 +24,10 @@ email_sender_address = string(default="notice@mediagoblin.example.org") # Set to false to disable registrations allow_registration = boolean(default=True) +# tag parsing +tags_delimiter = string(default=",") +tags_max_length = integer(default=50) + # By default not set, but you might want something like: # "%(here)s/user_dev/templates/" local_templates = string() diff --git a/mediagoblin/contrib/960_16_col.css b/mediagoblin/contrib/960_16_col.css deleted file mode 100644 index faa6d8b2..00000000 --- a/mediagoblin/contrib/960_16_col.css +++ /dev/null @@ -1,447 +0,0 @@ -/* - 960 Grid System ~ Core CSS. - Learn more ~ http://960.gs/ - - Licensed under GPL and MIT. -*/ - -/* - Forces backgrounds to span full width, - even if there is horizontal scrolling. - Increase this if your layout is wider. - - Note: IE6 works fine without this fix. -*/ - -body { - min-width: 960px; -} - -/* Container -----------------------------------------------------------------------------------------------------*/ - -.container_16 { - margin-left: auto; - margin-right: auto; - width: 960px; -} - -/* Grid >> Global -----------------------------------------------------------------------------------------------------*/ - -.grid_1, -.grid_2, -.grid_3, -.grid_4, -.grid_5, -.grid_6, -.grid_7, -.grid_8, -.grid_9, -.grid_10, -.grid_11, -.grid_12, -.grid_13, -.grid_14, -.grid_15, -.grid_16 { - display: inline; - float: left; - position: relative; - margin-left: 10px; - margin-right: 10px; -} - -.push_1, .pull_1, -.push_2, .pull_2, -.push_3, .pull_3, -.push_4, .pull_4, -.push_5, .pull_5, -.push_6, .pull_6, -.push_7, .pull_7, -.push_8, .pull_8, -.push_9, .pull_9, -.push_10, .pull_10, -.push_11, .pull_11, -.push_12, .pull_12, -.push_13, .pull_13, -.push_14, .pull_14, -.push_15, .pull_15, -.push_16, .pull_16 { - position: relative; -} - -/* Grid >> Children (Alpha ~ First, Omega ~ Last) -----------------------------------------------------------------------------------------------------*/ - -.alpha { - margin-left: 0; -} - -.omega { - margin-right: 0; -} - -/* Grid >> 16 Columns -----------------------------------------------------------------------------------------------------*/ - -.container_16 .grid_1 { - width: 40px; -} - -.container_16 .grid_2 { - width: 100px; -} - -.container_16 .grid_3 { - width: 160px; -} - -.container_16 .grid_4 { - width: 220px; -} - -.container_16 .grid_5 { - width: 280px; -} - -.container_16 .grid_6 { - width: 340px; -} - -.container_16 .grid_7 { - width: 400px; -} - -.container_16 .grid_8 { - width: 460px; -} - -.container_16 .grid_9 { - width: 520px; -} - -.container_16 .grid_10 { - width: 580px; -} - -.container_16 .grid_11 { - width: 640px; -} - -.container_16 .grid_12 { - width: 700px; -} - -.container_16 .grid_13 { - width: 760px; -} - -.container_16 .grid_14 { - width: 820px; -} - -.container_16 .grid_15 { - width: 880px; -} - -.container_16 .grid_16 { - width: 940px; -} - -/* Prefix Extra Space >> 16 Columns -----------------------------------------------------------------------------------------------------*/ - -.container_16 .prefix_1 { - padding-left: 60px; -} - -.container_16 .prefix_2 { - padding-left: 120px; -} - -.container_16 .prefix_3 { - padding-left: 180px; -} - -.container_16 .prefix_4 { - padding-left: 240px; -} - -.container_16 .prefix_5 { - padding-left: 300px; -} - -.container_16 .prefix_6 { - padding-left: 360px; -} - -.container_16 .prefix_7 { - padding-left: 420px; -} - -.container_16 .prefix_8 { - padding-left: 480px; -} - -.container_16 .prefix_9 { - padding-left: 540px; -} - -.container_16 .prefix_10 { - padding-left: 600px; -} - -.container_16 .prefix_11 { - padding-left: 660px; -} - -.container_16 .prefix_12 { - padding-left: 720px; -} - -.container_16 .prefix_13 { - padding-left: 780px; -} - -.container_16 .prefix_14 { - padding-left: 840px; -} - -.container_16 .prefix_15 { - padding-left: 900px; -} - -/* Suffix Extra Space >> 16 Columns -----------------------------------------------------------------------------------------------------*/ - -.container_16 .suffix_1 { - padding-right: 60px; -} - -.container_16 .suffix_2 { - padding-right: 120px; -} - -.container_16 .suffix_3 { - padding-right: 180px; -} - -.container_16 .suffix_4 { - padding-right: 240px; -} - -.container_16 .suffix_5 { - padding-right: 300px; -} - -.container_16 .suffix_6 { - padding-right: 360px; -} - -.container_16 .suffix_7 { - padding-right: 420px; -} - -.container_16 .suffix_8 { - padding-right: 480px; -} - -.container_16 .suffix_9 { - padding-right: 540px; -} - -.container_16 .suffix_10 { - padding-right: 600px; -} - -.container_16 .suffix_11 { - padding-right: 660px; -} - -.container_16 .suffix_12 { - padding-right: 720px; -} - -.container_16 .suffix_13 { - padding-right: 780px; -} - -.container_16 .suffix_14 { - padding-right: 840px; -} - -.container_16 .suffix_15 { - padding-right: 900px; -} - -/* Push Space >> 16 Columns -----------------------------------------------------------------------------------------------------*/ - -.container_16 .push_1 { - left: 60px; -} - -.container_16 .push_2 { - left: 120px; -} - -.container_16 .push_3 { - left: 180px; -} - -.container_16 .push_4 { - left: 240px; -} - -.container_16 .push_5 { - left: 300px; -} - -.container_16 .push_6 { - left: 360px; -} - -.container_16 .push_7 { - left: 420px; -} - -.container_16 .push_8 { - left: 480px; -} - -.container_16 .push_9 { - left: 540px; -} - -.container_16 .push_10 { - left: 600px; -} - -.container_16 .push_11 { - left: 660px; -} - -.container_16 .push_12 { - left: 720px; -} - -.container_16 .push_13 { - left: 780px; -} - -.container_16 .push_14 { - left: 840px; -} - -.container_16 .push_15 { - left: 900px; -} - -/* Pull Space >> 16 Columns -----------------------------------------------------------------------------------------------------*/ - -.container_16 .pull_1 { - left: -60px; -} - -.container_16 .pull_2 { - left: -120px; -} - -.container_16 .pull_3 { - left: -180px; -} - -.container_16 .pull_4 { - left: -240px; -} - -.container_16 .pull_5 { - left: -300px; -} - -.container_16 .pull_6 { - left: -360px; -} - -.container_16 .pull_7 { - left: -420px; -} - -.container_16 .pull_8 { - left: -480px; -} - -.container_16 .pull_9 { - left: -540px; -} - -.container_16 .pull_10 { - left: -600px; -} - -.container_16 .pull_11 { - left: -660px; -} - -.container_16 .pull_12 { - left: -720px; -} - -.container_16 .pull_13 { - left: -780px; -} - -.container_16 .pull_14 { - left: -840px; -} - -.container_16 .pull_15 { - left: -900px; -} - -/* `Clear Floated Elements -----------------------------------------------------------------------------------------------------*/ - -/* http://sonspring.com/journal/clearing-floats */ - -.clear { - clear: both; - display: block; - overflow: hidden; - visibility: hidden; - width: 0; - height: 0; -} - -/* http://www.yuiblog.com/blog/2010/09/27/clearfix-reloaded-overflowhidden-demystified */ - -.clearfix:before, -.clearfix:after, -.container_16:before, -.container_16:after { - content: '.'; - display: block; - overflow: hidden; - visibility: hidden; - font-size: 0; - line-height: 0; - width: 0; - height: 0; -} - -.clearfix:after, -.container_16:after { - clear: both; -} - -/* - The following zoom:1 rule is specifically for IE6 + IE7. - Move to separate stylesheet if invalid CSS is a problem. -*/ - -.clearfix, -.container_16 { - zoom: 1; -}
\ No newline at end of file diff --git a/mediagoblin/contrib/reset.css b/mediagoblin/contrib/reset.css deleted file mode 100644 index 87b7f368..00000000 --- a/mediagoblin/contrib/reset.css +++ /dev/null @@ -1,202 +0,0 @@ -/* `XHTML, HTML4, HTML5 Reset -----------------------------------------------------------------------------------------------------*/ - -a, -abbr, -acronym, -address, -applet, -article, -aside, -audio, -b, -big, -blockquote, -body, -canvas, -caption, -center, -cite, -code, -dd, -del, -details, -dfn, -dialog, -div, -dl, -dt, -em, -embed, -fieldset, -figcaption, -figure, -font, -footer, -form, -h1, -h2, -h3, -h4, -h5, -h6, -header, -hgroup, -hr, -html, -i, -iframe, -img, -ins, -kbd, -label, -legend, -li, -mark, -menu, -meter, -nav, -object, -ol, -output, -p, -pre, -progress, -q, -rp, -rt, -ruby, -s, -samp, -section, -small, -span, -strike, -strong, -sub, -summary, -sup, -table, -tbody, -td, -tfoot, -th, -thead, -time, -tr, -tt, -u, -ul, -var, -video, -xmp { - border: 0; - margin: 0; - padding: 0; - font-size: 100%; -} - -html, -body { - height: 100%; -} - -article, -aside, -details, -figcaption, -figure, -footer, -header, -hgroup, -menu, -nav, -section { -/* - Override the default (display: inline) for - browsers that do not recognize HTML5 tags. - - IE8 (and lower) requires a shiv: - http://ejohn.org/blog/html5-shiv -*/ - display: block; -} - -b, -strong { -/* - Makes browsers agree. - IE + Opera = font-weight: bold. - Gecko + WebKit = font-weight: bolder. -*/ - font-weight: bold; -} - -img { - color: transparent; - font-size: 0; - vertical-align: middle; -/* - For IE. - http://css-tricks.com/ie-fix-bicubic-scaling-for-images -*/ - -ms-interpolation-mode: bicubic; -} - -li { -/* - For IE6 + IE7. -*/ - display: list-item; -} - -table { - border-collapse: collapse; - border-spacing: 0; -} - -th, -td, -caption { - font-weight: normal; - vertical-align: top; - text-align: left; -} - -q { - quotes: none; -} - -q:before, -q:after { - content: ''; - content: none; -} - -sub, -sup, -small { - font-size: 75%; -} - -sub, -sup { - line-height: 0; - position: relative; - vertical-align: baseline; -} - -sub { - bottom: -0.25em; -} - -sup { - top: -0.5em; -} - -svg { -/* - For IE9. -*/ - overflow: hidden; -}
\ No newline at end of file diff --git a/mediagoblin/contrib/text.css b/mediagoblin/contrib/text.css deleted file mode 100644 index 1a6b302f..00000000 --- a/mediagoblin/contrib/text.css +++ /dev/null @@ -1,86 +0,0 @@ -/* - 960 Grid System ~ Text CSS. - Learn more ~ http://960.gs/ - - Licensed under GPL and MIT. -*/ - -/* `Basic HTML -----------------------------------------------------------------------------------------------------*/ - -body { - font: 13px/1.5 'Helvetica Neue', Arial, 'Liberation Sans', FreeSans, sans-serif; -} - -pre, -code { - font-family: 'DejaVu Sans Mono', Monaco, Consolas, monospace; -} - -hr { - border: 0 #ccc solid; - border-top-width: 1px; - clear: both; - height: 0; -} - -/* `Headings -----------------------------------------------------------------------------------------------------*/ - -h1 { - font-size: 25px; -} - -h2 { - font-size: 23px; -} - -h3 { - font-size: 21px; -} - -h4 { - font-size: 19px; -} - -h5 { - font-size: 17px; -} - -h6 { - font-size: 15px; -} - -/* `Spacing -----------------------------------------------------------------------------------------------------*/ - -ol { - list-style: decimal; -} - -ul { - list-style: disc; -} - -li { - margin-left: 30px; -} - -p, -dl, -hr, -h1, -h2, -h3, -h4, -h5, -h6, -ol, -ul, -pre, -table, -address, -fieldset, -figure { - margin-bottom: 20px; -}
\ No newline at end of file diff --git a/mediagoblin/db/indexes.py b/mediagoblin/db/indexes.py index a832e013..30d43c98 100644 --- a/mediagoblin/db/indexes.py +++ b/mediagoblin/db/indexes.py @@ -90,6 +90,21 @@ MEDIAENTRY_INDEXES = { # Indexing on uploaders and when media entries are created. # Used for showing a user gallery, etc. 'index': [('uploader', ASCENDING), + ('created', DESCENDING)]}, + + 'state_uploader_tags_created': { + # Indexing on processed?, media uploader, associated tags, and timestamp + # Used for showing media items matching a tag search, most recent first. + 'index': [('state', ASCENDING), + ('uploader', ASCENDING), + ('tags.slug', DESCENDING), + ('created', DESCENDING)]}, + + 'state_tags_created': { + # Indexing on processed?, media tags, and timestamp (across all users) + # This is used for a front page tag search. + 'index': [('state', ASCENDING), + ('tags.slug', DESCENDING), ('created', DESCENDING)]}} diff --git a/mediagoblin/db/models.py b/mediagoblin/db/models.py index e97dc537..23527e84 100644 --- a/mediagoblin/db/models.py +++ b/mediagoblin/db/models.py @@ -186,7 +186,7 @@ class MediaEntry(Document): 'media_type': unicode, 'media_data': dict, # extra data relevant to this media_type 'plugin_data': dict, # plugins can dump stuff here. - 'tags': [unicode], + 'tags': [dict], 'state': unicode, # For now let's assume there can only be one main file queued diff --git a/mediagoblin/decorators.py b/mediagoblin/decorators.py index 081eda62..2e90274e 100644 --- a/mediagoblin/decorators.py +++ b/mediagoblin/decorators.py @@ -38,8 +38,9 @@ def require_active_login(controller): def new_controller_func(request, *args, **kwargs): if request.user and \ request.user.get('status') == u'needs_email_verification': - return redirect(request, - 'mediagoblin.auth.verify_email_notice') + return redirect( + request, 'mediagoblin.user_pages.user_home', + user=request.user['username']) elif not request.user or request.user.get('status') != u'active': return exc.HTTPFound( location="%s?next=%s" % ( diff --git a/mediagoblin/edit/__init__.py b/mediagoblin/edit/__init__.py index e69de29b..a8eeb5ed 100644 --- a/mediagoblin/edit/__init__.py +++ b/mediagoblin/edit/__init__.py @@ -0,0 +1,17 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 Free Software Foundation, Inc +# +# 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/>. + + diff --git a/mediagoblin/edit/forms.py b/mediagoblin/edit/forms.py index 0ed52af1..2f3ed203 100644 --- a/mediagoblin/edit/forms.py +++ b/mediagoblin/edit/forms.py @@ -17,20 +17,27 @@ import wtforms +from mediagoblin.util import tag_length_validator, TOO_LONG_TAG_WARNING +from mediagoblin.util import fake_ugettext_passthrough as _ + class EditForm(wtforms.Form): title = wtforms.TextField( - 'Title', + _('Title'), [wtforms.validators.Length(min=0, max=500)]) slug = wtforms.TextField( - 'Slug', - [wtforms.validators.Required(message="The slug can't be empty")]) + _('Slug'), + [wtforms.validators.Required(message=_("The slug can't be empty"))]) description = wtforms.TextAreaField('Description of this work') + tags = wtforms.TextField( + _('Tags'), + [tag_length_validator]) class EditProfileForm(wtforms.Form): - bio = wtforms.TextAreaField('Bio', + bio = wtforms.TextAreaField( + _('Bio'), [wtforms.validators.Length(min=0, max=500)]) url = wtforms.TextField( - 'Website', + _('Website'), [wtforms.validators.Optional(), - wtforms.validators.URL(message='Improperly formed URL')]) + wtforms.validators.URL(message=_('Improperly formed URL'))]) diff --git a/mediagoblin/edit/views.py b/mediagoblin/edit/views.py index f372fbb9..0b1a98f1 100644 --- a/mediagoblin/edit/views.py +++ b/mediagoblin/edit/views.py @@ -16,10 +16,14 @@ from webob import exc +from string import split from mediagoblin import messages +from mediagoblin import mg_globals from mediagoblin.util import ( - render_to_response, redirect, cleaned_markdown_conversion) + render_to_response, redirect, clean_html, convert_to_tag_list_of_dicts, + media_tags_as_string, cleaned_markdown_conversion) +from mediagoblin.util import pass_to_ugettext as _ from mediagoblin.edit import forms from mediagoblin.edit.lib import may_edit_media from mediagoblin.decorators import require_active_login, get_user_media_entry @@ -34,7 +38,8 @@ def edit_media(request, media): form = forms.EditForm(request.POST, title = media['title'], slug = media['slug'], - description = media['description']) + description = media['description'], + tags = media_tags_as_string(media['tags'])) if request.method == 'POST' and form.validate(): # Make sure there isn't already a MediaEntry with such a slug @@ -46,11 +51,13 @@ def edit_media(request, media): if existing_user_slug_entries: form.slug.errors.append( - u'An entry with that slug already exists for this user.') + _(u'An entry with that slug already exists for this user.')) else: media['title'] = request.POST['title'] media['description'] = request.POST.get('description') - + media['tags'] = convert_to_tag_list_of_dicts( + request.POST.get('tags')) + media['description_html'] = cleaned_markdown_conversion( media['description']) @@ -65,7 +72,7 @@ def edit_media(request, media): and request.method != 'POST': messages.add_message( request, messages.WARNING, - "You are editing another user's media. Proceed with caution.") + _("You are editing another user's media. Proceed with caution.")) return render_to_response( @@ -86,7 +93,7 @@ def edit_profile(request): if request.method != 'POST': messages.add_message( request, messages.WARNING, - "You are editing a user's profile. Proceed with caution.") + _("You are editing a user's profile. Proceed with caution.")) else: user = request.user diff --git a/mediagoblin/gmg_commands/__init__.py b/mediagoblin/gmg_commands/__init__.py index 0cb4d3a2..921f0430 100644 --- a/mediagoblin/gmg_commands/__init__.py +++ b/mediagoblin/gmg_commands/__init__.py @@ -40,6 +40,10 @@ SUBCOMMAND_MAP = { 'setup': 'mediagoblin.gmg_commands.users:changepw_parser_setup', 'func': 'mediagoblin.gmg_commands.users:changepw', 'help': 'Makes admin an user'}, + 'wipealldata': { + 'setup': 'mediagoblin.gmg_commands.wipealldata:wipe_parser_setup', + 'func': 'mediagoblin.gmg_commands.wipealldata:wipe', + 'help': 'Wipes **all** the data for this MediaGoblin instance'}, } diff --git a/mediagoblin/gmg_commands/users.py b/mediagoblin/gmg_commands/users.py index b4a6bbc1..14b6875d 100644 --- a/mediagoblin/gmg_commands/users.py +++ b/mediagoblin/gmg_commands/users.py @@ -1,3 +1,19 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 Free Software Foundation, Inc +# +# 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 from mediagoblin.auth import lib as auth_lib from mediagoblin import mg_globals diff --git a/mediagoblin/gmg_commands/wipealldata.py b/mediagoblin/gmg_commands/wipealldata.py new file mode 100644 index 00000000..9ad32051 --- /dev/null +++ b/mediagoblin/gmg_commands/wipealldata.py @@ -0,0 +1,51 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 Free Software Foundation, Inc +# +# 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/>. + +import sys +import pymongo +import sys +import os +import shutil + + +def wipe_parser_setup(subparser): + pass + + +def wipe(args): + print "*** WARNING! ***" + print "" + print "Running this will destroy your mediagoblin database," + print "remove all your media files in user_dev/, etc." + + drop_it = raw_input( + 'Are you **SURE** you want to destroy your environment? ' + '(if so, type "yes")> ') + + if not drop_it == 'yes': + return + + print "nixing data in mongodb...." + conn = pymongo.Connection() + conn.drop_database('mediagoblin') + + for directory in [os.path.join(os.getcwd(), "user_dev", "media"), + os.path.join(os.getcwd(), "user_dev", "beaker")]: + if os.path.exists(directory): + print "nixing %s...." % directory + shutil.rmtree(directory) + + print "removed all your stuff! okay, now re-run ./bin/buildout" diff --git a/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.mo Binary files differnew file mode 100644 index 00000000..6bb69ce9 --- /dev/null +++ b/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.po new file mode 100644 index 00000000..30c55e21 --- /dev/null +++ b/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.po @@ -0,0 +1,317 @@ +# Translations template for PROJECT. +# Copyright (C) 2011 ORGANIZATION +# This file is distributed under the same license as the PROJECT project. +# +# Rafael Maguiña <rafael.maguina@gmail.com>, 2011. +# <mediagoblin.org@samba-tng.org>, 2011. +# <cwebber@dustycloud.org>, 2011. +# Jan-Christoph Borchardt <JanCBorchardt@fsfe.org>, 2011. +msgid "" +msgstr "" +"Project-Id-Version: GNU MediaGoblin\n" +"Report-Msgid-Bugs-To: http://bugs.foocorp.net/projects/mediagoblin/issues\n" +"POT-Creation-Date: 2011-08-08 22:53-0500\n" +"PO-Revision-Date: 2011-08-10 23:20+0000\n" +"Last-Translator: JanCBorchardt <JanCBorchardt@fsfe.org>\n" +"Language-Team: German (http://www.transifex.net/projects/p/mediagoblin/team/de/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 0.9.6\n" +"Language: de\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" + +#: mediagoblin/auth/forms.py:24 mediagoblin/auth/forms.py:46 +msgid "Username" +msgstr "Benutzername" + +#: mediagoblin/auth/forms.py:29 mediagoblin/auth/forms.py:50 +msgid "Password" +msgstr "Passwort" + +#: mediagoblin/auth/forms.py:34 +msgid "Passwords must match." +msgstr "Passwörter müssen übereinstimmen." + +#: mediagoblin/auth/forms.py:36 +msgid "Confirm password" +msgstr "Passwort wiederholen" + +#: mediagoblin/auth/forms.py:39 +msgid "Email address" +msgstr "Email-Adresse" + +#: mediagoblin/auth/views.py:40 +msgid "Sorry, registration is disabled on this instance." +msgstr "Registrierung ist auf dieser Instanz leider deaktiviert." + +#: mediagoblin/auth/views.py:55 +msgid "Sorry, a user with that name already exists." +msgstr "Leider gibt es bereits einen Benutzer mit diesem Namen." + +#: mediagoblin/auth/views.py:152 +msgid "" +"Your email address has been verified. You may now login, edit your profile, " +"and submit images!" +msgstr "" +"Deine Email-Adresse wurde bestätigt. Du kannst dich nun anmelden, dein " +"Profil bearbeiten und Bilder hochladen!" + +#: mediagoblin/auth/views.py:158 +msgid "The verification key or user id is incorrect" +msgstr "Der Bestätigungssschlüssel oder die Nutzernummer ist falsch." + +#: mediagoblin/auth/views.py:179 +#: mediagoblin/templates/mediagoblin/auth/resent_verification_email.html:22 +msgid "Resent your verification email." +msgstr "Bestätigungs-Email noch Mal senden." + +#: mediagoblin/edit/forms.py:26 mediagoblin/submit/forms.py:26 +msgid "Title" +msgstr "Titel" + +#: mediagoblin/edit/forms.py:29 +msgid "Slug" +msgstr "Kurztitel" + +#: mediagoblin/edit/forms.py:30 +msgid "The slug can't be empty" +msgstr "Bitte gib einen Kurztitel ein" + +#: mediagoblin/edit/forms.py:33 mediagoblin/submit/forms.py:31 +msgid "Tags" +msgstr "Markierungen" + +#: mediagoblin/edit/forms.py:38 +msgid "Bio" +msgstr "Biographie" + +#: mediagoblin/edit/forms.py:41 +msgid "Website" +msgstr "Webseite" + +#: mediagoblin/edit/forms.py:43 +msgid "Improperly formed URL" +msgstr "Adresse fehlerhaft" + +#: mediagoblin/edit/views.py:54 +msgid "An entry with that slug already exists for this user." +msgstr "Diesen Kurztitel hast du bereits vergeben." + +#: mediagoblin/edit/views.py:75 +msgid "You are editing another user's media. Proceed with caution." +msgstr "Du bearbeitest die Medien eines Anderen. Bitte sei vorsichtig." + +#: mediagoblin/edit/views.py:96 +msgid "You are editing a user's profile. Proceed with caution." +msgstr "Du bearbeitest das Profil eines Anderen. Bitte sei vorsichtig." + +#: mediagoblin/submit/forms.py:29 +msgid "File" +msgstr "Datei" + +#: mediagoblin/submit/views.py:45 +msgid "You must provide a file." +msgstr "Du musst eine Datei angeben." + +#: mediagoblin/submit/views.py:48 +msgid "The file doesn't seem to be an image!" +msgstr "Diese Datei scheint kein Bild zu sein!" + +#: mediagoblin/submit/views.py:96 +msgid "Woohoo! Submitted!" +msgstr "Yeeeaaah! Geschafft!" + +#: mediagoblin/templates/mediagoblin/base.html:22 +msgid "GNU MediaGoblin" +msgstr "GNU MediaGoblin" + +#: mediagoblin/templates/mediagoblin/base.html:45 +msgid "Mediagoblin logo" +msgstr "Mediagoblin-Logo" + +#: mediagoblin/templates/mediagoblin/base.html:51 +msgid "Submit media" +msgstr "Medien hochladen" + +#: mediagoblin/templates/mediagoblin/base.html:62 +msgid "verify your email!" +msgstr "Bitte bestätige deine Email-Adresse!" + +#: mediagoblin/templates/mediagoblin/base.html:72 +msgid "Login" +msgstr "Anmelden" + +#: mediagoblin/templates/mediagoblin/base.html:88 +msgid "" +"Powered by <a href=\"http://mediagoblin.org\">MediaGoblin</a>, a <a " +"href=\"http://gnu.org/\">GNU project</a>" +msgstr "" +"Läüft mit <a href=\"http://mediagoblin.org\">MediaGoblin</a>, einem <a " +"href=\"http://gnu.org/\">GNU-Projekt</a>" + +#: mediagoblin/templates/mediagoblin/root.html:21 +msgid "Welcome to GNU MediaGoblin!" +msgstr "Willkommen bei GNU MediaGoblin!" + +#: mediagoblin/templates/mediagoblin/root.html:26 +msgid "Submit an item" +msgstr "Eintrag hochladen" + +#: mediagoblin/templates/mediagoblin/root.html:31 +#, python-format +msgid "If you have an account, you can <a href=\"%(login_url)s\">Login</a>." +msgstr "" +"Falls du ein Konto hast, kannst du dich <a " +"href=\"%(login_url)s\">anmelden</a>." + +#: mediagoblin/templates/mediagoblin/root.html:37 +#, python-format +msgid "" +"If you don't have an account, please <a " +"href=\"%(register_url)s\">Register</a>." +msgstr "" +"Wenn du noch kein Konto hast, <a href=\"%(register_url)s\">registriere " +"dich</a>." + +#: mediagoblin/templates/mediagoblin/auth/login.html:26 +msgid "Log in" +msgstr "Anmelden" + +#: mediagoblin/templates/mediagoblin/auth/login.html:29 +msgid "Login failed!" +msgstr "Anmeldung fehlgeschlagen!" + +#: mediagoblin/templates/mediagoblin/auth/login.html:34 +#: mediagoblin/templates/mediagoblin/auth/register.html:30 +#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:35 +#: mediagoblin/templates/mediagoblin/submit/start.html:32 +msgid "Submit" +msgstr "Bestätigen" + +#: mediagoblin/templates/mediagoblin/auth/login.html:42 +msgid "Don't have an account yet?" +msgstr "Hast du noch kein Konto?" + +#: mediagoblin/templates/mediagoblin/auth/login.html:45 +msgid "Create one here!" +msgstr "Registriere dich!" + +#: mediagoblin/templates/mediagoblin/auth/register.html:27 +msgid "Create an account!" +msgstr "Neues Konto registrieren!" + +#: mediagoblin/templates/mediagoblin/auth/verification_email.txt:19 +#, python-format +msgid "" +"Hi %(username)s,\n" +"\n" +"to activate your GNU MediaGoblin account, open the following URL in\n" +"your web browser:\n" +"\n" +"%(verification_url)s" +msgstr "" +"Hi %(username)s,\n" +"\n" +"um dein Konto bei GNU MediaGoblin zu aktivieren, musst du folgende Adresse in einem Webbrowser öffnen:\n" +"\n" +"%(verification_url)s" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:29 +#, python-format +msgid "Editing %(media_title)s" +msgstr "%(media_title)s bearbeiten" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:36 +msgid "Cancel" +msgstr "Abbrechen" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:37 +msgid "Save changes" +msgstr "Änderungen speichern" + +#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29 +#, python-format +msgid "Editing %(username)s's profile" +msgstr "%(username)s’s Profil barbeiten" + +#: mediagoblin/templates/mediagoblin/listings/tag.html:29 +msgid "Media tagged with:" +msgstr "Medien markiert mit:" + +#: mediagoblin/templates/mediagoblin/listings/tag.html:40 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:46 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:101 +msgid "atom feed" +msgstr "Atom-Feed" + +#: mediagoblin/templates/mediagoblin/submit/start.html:26 +msgid "Submit yer media" +msgstr "Medien hochladen" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 +#, python-format +msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media" +msgstr "<a href=\"%(user_url)s\">%(username)s</a>’s Medien" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:51 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:30 +msgid "Sorry, no such user found." +msgstr "Dieser Benutzer wurde leider nicht gefunden." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:37 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:57 +msgid "Verification needed" +msgstr "Überprüfung notwendig" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:40 +msgid "Almost done! Your account still needs to be verified." +msgstr "Fast geschafft! Dein Konto muss nur noch bestätigt werden." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:45 +msgid "" +"An email should arrive in a few moments with instructions on how to do so." +msgstr "" +"Gleich solltest du eine Email bekommen, die dir sagt was du noch machen " +"musst." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:49 +msgid "In case it doesn't:" +msgstr "Wenn sie nicht ankommt:" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:52 +msgid "Resend verification email" +msgstr "Bestätigung noch Mal senden" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:60 +msgid "" +"Someone has registered an account with this username, but it still has to be" +" verified." +msgstr "" +"Jemand hat schon ein Konto mit diesem Nutzernamen registriert, aber es muss " +"noch bestätigt werden." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:66 +#, python-format +msgid "" +"If you are that person but you've lost your verification email, you can <a " +"href=\"%(login_url)s\">log in</a> and resend it." +msgstr "" +"Wenn dir dieses Konto gehört und die Bestätigungsmail weg ist, kannst du " +"dich <a href=\"%(login_url)s\">anmelden</a> und sie erneut senden." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:76 +#, python-format +msgid "%(username)s's profile" +msgstr "%(username)s’s Profil" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:84 +msgid "Edit profile" +msgstr "Profil bearbeiten" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:95 +#, python-format +msgid "View all of %(username)s's media" +msgstr "Alle Medien von %(username)s anschauen" + + diff --git a/mediagoblin/i18n/en/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/en/LC_MESSAGES/mediagoblin.po new file mode 100644 index 00000000..0de5ca62 --- /dev/null +++ b/mediagoblin/i18n/en/LC_MESSAGES/mediagoblin.po @@ -0,0 +1,292 @@ +# Translations template for PROJECT. +# Copyright (C) 2011 ORGANIZATION +# This file is distributed under the same license as the PROJECT project. +# FIRST AUTHOR <EMAIL@ADDRESS>, 2011. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2011-08-08 22:53-0500\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 0.9.6\n" + +#: mediagoblin/auth/forms.py:24 mediagoblin/auth/forms.py:46 +msgid "Username" +msgstr "" + +#: mediagoblin/auth/forms.py:29 mediagoblin/auth/forms.py:50 +msgid "Password" +msgstr "" + +#: mediagoblin/auth/forms.py:34 +msgid "Passwords must match." +msgstr "" + +#: mediagoblin/auth/forms.py:36 +msgid "Confirm password" +msgstr "" + +#: mediagoblin/auth/forms.py:39 +msgid "Email address" +msgstr "" + +#: mediagoblin/auth/views.py:40 +msgid "Sorry, registration is disabled on this instance." +msgstr "" + +#: mediagoblin/auth/views.py:55 +msgid "Sorry, a user with that name already exists." +msgstr "" + +#: mediagoblin/auth/views.py:152 +msgid "" +"Your email address has been verified. You may now login, edit your " +"profile, and submit images!" +msgstr "" + +#: mediagoblin/auth/views.py:158 +msgid "The verification key or user id is incorrect" +msgstr "" + +#: mediagoblin/auth/views.py:179 +#: mediagoblin/templates/mediagoblin/auth/resent_verification_email.html:22 +msgid "Resent your verification email." +msgstr "" + +#: mediagoblin/edit/forms.py:26 mediagoblin/submit/forms.py:26 +msgid "Title" +msgstr "" + +#: mediagoblin/edit/forms.py:29 +msgid "Slug" +msgstr "" + +#: mediagoblin/edit/forms.py:30 +msgid "The slug can't be empty" +msgstr "" + +#: mediagoblin/edit/forms.py:33 mediagoblin/submit/forms.py:31 +msgid "Tags" +msgstr "" + +#: mediagoblin/edit/forms.py:38 +msgid "Bio" +msgstr "" + +#: mediagoblin/edit/forms.py:41 +msgid "Website" +msgstr "" + +#: mediagoblin/edit/forms.py:43 +msgid "Improperly formed URL" +msgstr "" + +#: mediagoblin/edit/views.py:54 +msgid "An entry with that slug already exists for this user." +msgstr "" + +#: mediagoblin/edit/views.py:75 +msgid "You are editing another user's media. Proceed with caution." +msgstr "" + +#: mediagoblin/edit/views.py:96 +msgid "You are editing a user's profile. Proceed with caution." +msgstr "" + +#: mediagoblin/submit/forms.py:29 +msgid "File" +msgstr "" + +#: mediagoblin/submit/views.py:45 +msgid "You must provide a file." +msgstr "" + +#: mediagoblin/submit/views.py:48 +msgid "The file doesn't seem to be an image!" +msgstr "" + +#: mediagoblin/submit/views.py:96 +msgid "Woohoo! Submitted!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:22 +msgid "GNU MediaGoblin" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:45 +msgid "Mediagoblin logo" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:51 +msgid "Submit media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:62 +msgid "verify your email!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:72 +msgid "Login" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:88 +msgid "" +"Powered by <a href=\"http://mediagoblin.org\">MediaGoblin</a>, a <a " +"href=\"http://gnu.org/\">GNU project</a>" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:21 +msgid "Welcome to GNU MediaGoblin!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:26 +msgid "Submit an item" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:31 +#, python-format +msgid "If you have an account, you can <a href=\"%(login_url)s\">Login</a>." +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:37 +#, python-format +msgid "" +"If you don't have an account, please <a " +"href=\"%(register_url)s\">Register</a>." +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/login.html:26 +msgid "Log in" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/login.html:29 +msgid "Login failed!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/login.html:34 +#: mediagoblin/templates/mediagoblin/auth/register.html:30 +#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:35 +#: mediagoblin/templates/mediagoblin/submit/start.html:32 +msgid "Submit" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/login.html:42 +msgid "Don't have an account yet?" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/login.html:45 +msgid "Create one here!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/register.html:27 +msgid "Create an account!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/verification_email.txt:19 +#, python-format +msgid "" +"Hi %(username)s,\n" +"\n" +"to activate your GNU MediaGoblin account, open the following URL in\n" +"your web browser:\n" +"\n" +"%(verification_url)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:29 +#, python-format +msgid "Editing %(media_title)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:36 +msgid "Cancel" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:37 +msgid "Save changes" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29 +#, python-format +msgid "Editing %(username)s's profile" +msgstr "" + +#: mediagoblin/templates/mediagoblin/listings/tag.html:29 +msgid "Media tagged with:" +msgstr "" + +#: mediagoblin/templates/mediagoblin/listings/tag.html:40 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:46 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:101 +msgid "atom feed" +msgstr "" + +#: mediagoblin/templates/mediagoblin/submit/start.html:26 +msgid "Submit yer media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 +#, python-format +msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:51 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:30 +msgid "Sorry, no such user found." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:37 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:57 +msgid "Verification needed" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:40 +msgid "Almost done! Your account still needs to be verified." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:45 +msgid "An email should arrive in a few moments with instructions on how to do so." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:49 +msgid "In case it doesn't:" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:52 +msgid "Resend verification email" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:60 +msgid "" +"Someone has registered an account with this username, but it still has to" +" be verified." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:66 +#, python-format +msgid "" +"If you are that person but you've lost your verification email, you can " +"<a href=\"%(login_url)s\">log in</a> and resend it." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:76 +#, python-format +msgid "%(username)s's profile" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:84 +msgid "Edit profile" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:95 +#, python-format +msgid "View all of %(username)s's media" +msgstr "" + diff --git a/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.mo Binary files differnew file mode 100644 index 00000000..dfd3a1bc --- /dev/null +++ b/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.po new file mode 100644 index 00000000..0a12586c --- /dev/null +++ b/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.po @@ -0,0 +1,312 @@ +# Translations template for PROJECT. +# Copyright (C) 2011 ORGANIZATION +# This file is distributed under the same license as the PROJECT project. +# +# <jacobo@gnu.org>, 2011. +msgid "" +msgstr "" +"Project-Id-Version: GNU MediaGoblin\n" +"Report-Msgid-Bugs-To: http://bugs.foocorp.net/projects/mediagoblin/issues\n" +"POT-Creation-Date: 2011-08-08 22:53-0500\n" +"PO-Revision-Date: 2011-08-10 20:30+0000\n" +"Last-Translator: nvjacobo <jacobo@gnu.org>\n" +"Language-Team: Spanish (Castilian) (http://www.transifex.net/projects/p/mediagoblin/team/es/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 0.9.6\n" +"Language: es\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" + +#: mediagoblin/auth/forms.py:24 mediagoblin/auth/forms.py:46 +msgid "Username" +msgstr "Nombre de Usuario" + +#: mediagoblin/auth/forms.py:29 mediagoblin/auth/forms.py:50 +msgid "Password" +msgstr "Contraseña" + +#: mediagoblin/auth/forms.py:34 +msgid "Passwords must match." +msgstr "Las contraseñas deben coincidir." + +#: mediagoblin/auth/forms.py:36 +msgid "Confirm password" +msgstr "Confirme su contraseña" + +#: mediagoblin/auth/forms.py:39 +msgid "Email address" +msgstr "Dirección de correo electrónico" + +#: mediagoblin/auth/views.py:40 +msgid "Sorry, registration is disabled on this instance." +msgstr "Lo sentimos, el registro está deshabilitado en este momento." + +#: mediagoblin/auth/views.py:55 +msgid "Sorry, a user with that name already exists." +msgstr "Lo sentimos, un usuario con ese nombre ya existe." + +#: mediagoblin/auth/views.py:152 +msgid "" +"Your email address has been verified. You may now login, edit your profile, " +"and submit images!" +msgstr "" +"Su dirección de correo electrónico ha sido verificada. Ahora puede ingresar," +" editar su perfil, y enviar las imágenes!" + +#: mediagoblin/auth/views.py:158 +msgid "The verification key or user id is incorrect" +msgstr "" +"La clave de la verificación o la identificación del usuario es incorrecta" + +#: mediagoblin/auth/views.py:179 +#: mediagoblin/templates/mediagoblin/auth/resent_verification_email.html:22 +msgid "Resent your verification email." +msgstr "Reenvíe su correo electrónico de verificación" + +#: mediagoblin/edit/forms.py:26 mediagoblin/submit/forms.py:26 +msgid "Title" +msgstr "Título" + +#: mediagoblin/edit/forms.py:29 +msgid "Slug" +msgstr "Ficha" + +#: mediagoblin/edit/forms.py:30 +msgid "The slug can't be empty" +msgstr "La ficha no puede estar vacia" + +#: mediagoblin/edit/forms.py:33 mediagoblin/submit/forms.py:31 +msgid "Tags" +msgstr "Etiquetas" + +#: mediagoblin/edit/forms.py:38 +msgid "Bio" +msgstr "Bio" + +#: mediagoblin/edit/forms.py:41 +msgid "Website" +msgstr "Sitio web" + +#: mediagoblin/edit/forms.py:43 +msgid "Improperly formed URL" +msgstr "URL de forma incorrecta" + +#: mediagoblin/edit/views.py:54 +msgid "An entry with that slug already exists for this user." +msgstr "Una entrada con esa ficha ya existe para este usuario." + +#: mediagoblin/edit/views.py:75 +msgid "You are editing another user's media. Proceed with caution." +msgstr "" +"Usted está editando el contenido de otro usuario. Proceder con precaución." + +#: mediagoblin/edit/views.py:96 +msgid "You are editing a user's profile. Proceed with caution." +msgstr "Usted está editando un perfil de usuario. Proceder con precaucións." + +#: mediagoblin/submit/forms.py:29 +msgid "File" +msgstr "Archivo" + +#: mediagoblin/submit/views.py:45 +msgid "You must provide a file." +msgstr "Usted debe proporcionar un archivo." + +#: mediagoblin/submit/views.py:48 +msgid "The file doesn't seem to be an image!" +msgstr "El archivo no parece ser una imagen!" + +#: mediagoblin/submit/views.py:96 +msgid "Woohoo! Submitted!" +msgstr "Woohoo! Enviado!" + +#: mediagoblin/templates/mediagoblin/base.html:22 +msgid "GNU MediaGoblin" +msgstr "GNU MediaGoblin" + +#: mediagoblin/templates/mediagoblin/base.html:45 +msgid "Mediagoblin logo" +msgstr "Mediagoblin logo" + +#: mediagoblin/templates/mediagoblin/base.html:51 +msgid "Submit media" +msgstr "Enviar contenido" + +#: mediagoblin/templates/mediagoblin/base.html:62 +msgid "verify your email!" +msgstr "Verifique su correo electrónico" + +#: mediagoblin/templates/mediagoblin/base.html:72 +msgid "Login" +msgstr "Conectarse" + +#: mediagoblin/templates/mediagoblin/base.html:88 +msgid "" +"Powered by <a href=\"http://mediagoblin.org\">MediaGoblin</a>, a <a " +"href=\"http://gnu.org/\">GNU project</a>" +msgstr "" +"Potenciado por <a href=\"http://mediagoblin.org\">MediaGoblin</a>, a <a " +"href=\"http://gnu.org/\">GNU project</a>" + +#: mediagoblin/templates/mediagoblin/root.html:21 +msgid "Welcome to GNU MediaGoblin!" +msgstr "¡Bienvenido a GNU MediaGoblin!" + +#: mediagoblin/templates/mediagoblin/root.html:26 +msgid "Submit an item" +msgstr "Enviar un item" + +#: mediagoblin/templates/mediagoblin/root.html:31 +#, python-format +msgid "If you have an account, you can <a href=\"%(login_url)s\">Login</a>." +msgstr "" +"Si tiene una cuenta, puede iniciar sesión <a " +"href=\"%(login_url)s\">Login</a>." + +#: mediagoblin/templates/mediagoblin/root.html:37 +#, python-format +msgid "" +"If you don't have an account, please <a " +"href=\"%(register_url)s\">Register</a>." +msgstr "" +"Si no tienes una cuenta, por favor, <a " +"href=\"%(register_url)s\">Regístrese</a> ." + +#: mediagoblin/templates/mediagoblin/auth/login.html:26 +msgid "Log in" +msgstr "Conectarse" + +#: mediagoblin/templates/mediagoblin/auth/login.html:29 +msgid "Login failed!" +msgstr "El inicio de sesión fallo" + +#: mediagoblin/templates/mediagoblin/auth/login.html:34 +#: mediagoblin/templates/mediagoblin/auth/register.html:30 +#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:35 +#: mediagoblin/templates/mediagoblin/submit/start.html:32 +msgid "Submit" +msgstr "Enviar" + +#: mediagoblin/templates/mediagoblin/auth/login.html:42 +msgid "Don't have an account yet?" +msgstr "¿No tienes una cuenta?" + +#: mediagoblin/templates/mediagoblin/auth/login.html:45 +msgid "Create one here!" +msgstr "Crea una aquí" + +#: mediagoblin/templates/mediagoblin/auth/register.html:27 +msgid "Create an account!" +msgstr "Crea una cuenta!" + +#: mediagoblin/templates/mediagoblin/auth/verification_email.txt:19 +#, python-format +msgid "" +"Hi %(username)s,\n" +"\n" +"to activate your GNU MediaGoblin account, open the following URL in\n" +"your web browser:\n" +"\n" +"%(verification_url)s" +msgstr "" +"Hola %(username)s , para activar su cuenta MediaGoblin GNU, abra ls " +"siguiente URL en su navegador: %(verification_url)s " + +#: mediagoblin/templates/mediagoblin/edit/edit.html:29 +#, python-format +msgid "Editing %(media_title)s" +msgstr "Edición %(media_title)s " + +#: mediagoblin/templates/mediagoblin/edit/edit.html:36 +msgid "Cancel" +msgstr "Cancelar" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:37 +msgid "Save changes" +msgstr "Salvar cambios" + +#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29 +#, python-format +msgid "Editing %(username)s's profile" +msgstr "Edición %(username)s de perfil" + +#: mediagoblin/templates/mediagoblin/listings/tag.html:29 +msgid "Media tagged with:" +msgstr "El contenido con la etiqueta:" + +#: mediagoblin/templates/mediagoblin/listings/tag.html:40 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:46 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:101 +msgid "atom feed" +msgstr "feed Atom" + +#: mediagoblin/templates/mediagoblin/submit/start.html:26 +msgid "Submit yer media" +msgstr "Envíe su contenido" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 +#, python-format +msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media" +msgstr "Contenido de <a href=\"%(user_url)s\">%(username)s</a>'s" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:51 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:30 +msgid "Sorry, no such user found." +msgstr "Lo sentimos, no se ha encontrado el usuario." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:37 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:57 +msgid "Verification needed" +msgstr "Verificación necesaria" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:40 +msgid "Almost done! Your account still needs to be verified." +msgstr "Ya está casi hecho! Su cuenta tiene que ser verificada." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:45 +msgid "" +"An email should arrive in a few moments with instructions on how to do so." +msgstr "" +"Un e-mail debe llegar en unos momentos con las instrucciones para hacerlo." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:49 +msgid "In case it doesn't:" +msgstr "En caso de que no:" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:52 +msgid "Resend verification email" +msgstr "Reenviar correo electrónico de verificación" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:60 +msgid "" +"Someone has registered an account with this username, but it still has to be" +" verified." +msgstr "" +"Alguien ha registrado una cuenta con este nombre de usuario, pero todavía " +"tiene que ser verificado." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:66 +#, python-format +msgid "" +"If you are that person but you've lost your verification email, you can <a " +"href=\"%(login_url)s\">log in</a> and resend it." +msgstr "" +"Si usted es esa persona, pero usted ha perdido su correo electrónico de " +"verificación, usted puede reenviarlo <a href=\"%(login_url)s\">acceder</a>." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:76 +#, python-format +msgid "%(username)s's profile" +msgstr "Perfil de %(username)s's" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:84 +msgid "Edit profile" +msgstr "Editar perfil" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:95 +#, python-format +msgid "View all of %(username)s's media" +msgstr "Ver todo el contenido de %(username)s's " + + diff --git a/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.mo Binary files differnew file mode 100644 index 00000000..a7daf2c9 --- /dev/null +++ b/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.po new file mode 100644 index 00000000..4606bf47 --- /dev/null +++ b/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.po @@ -0,0 +1,305 @@ +# Translations template for PROJECT. +# Copyright (C) 2011 ORGANIZATION +# This file is distributed under the same license as the PROJECT project. +# +# <marktraceur@gmail.com>, 2011. +msgid "" +msgstr "" +"Project-Id-Version: GNU MediaGoblin\n" +"Report-Msgid-Bugs-To: http://bugs.foocorp.net/projects/mediagoblin/issues\n" +"POT-Creation-Date: 2011-08-08 22:53-0500\n" +"PO-Revision-Date: 2011-08-10 21:24+0000\n" +"Last-Translator: MarkTraceur <marktraceur@gmail.com>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 0.9.6\n" +"Language: fr\n" +"Plural-Forms: nplurals=2; plural=(n > 1)\n" + +#: mediagoblin/auth/forms.py:24 mediagoblin/auth/forms.py:46 +msgid "Username" +msgstr "" + +#: mediagoblin/auth/forms.py:29 mediagoblin/auth/forms.py:50 +msgid "Password" +msgstr "" + +#: mediagoblin/auth/forms.py:34 +msgid "Passwords must match." +msgstr "" + +#: mediagoblin/auth/forms.py:36 +msgid "Confirm password" +msgstr "" + +#: mediagoblin/auth/forms.py:39 +msgid "Email address" +msgstr "" + +#: mediagoblin/auth/views.py:40 +msgid "Sorry, registration is disabled on this instance." +msgstr "" + +#: mediagoblin/auth/views.py:55 +msgid "Sorry, a user with that name already exists." +msgstr "" + +#: mediagoblin/auth/views.py:152 +msgid "" +"Your email address has been verified. You may now login, edit your profile, " +"and submit images!" +msgstr "" + +#: mediagoblin/auth/views.py:158 +msgid "The verification key or user id is incorrect" +msgstr "" + +#: mediagoblin/auth/views.py:179 +#: mediagoblin/templates/mediagoblin/auth/resent_verification_email.html:22 +msgid "Resent your verification email." +msgstr "Nous avons renvoyé votre e-mail de vérification." + +#: mediagoblin/edit/forms.py:26 mediagoblin/submit/forms.py:26 +msgid "Title" +msgstr "" + +#: mediagoblin/edit/forms.py:29 +msgid "Slug" +msgstr "" + +#: mediagoblin/edit/forms.py:30 +msgid "The slug can't be empty" +msgstr "" + +#: mediagoblin/edit/forms.py:33 mediagoblin/submit/forms.py:31 +msgid "Tags" +msgstr "" + +#: mediagoblin/edit/forms.py:38 +msgid "Bio" +msgstr "" + +#: mediagoblin/edit/forms.py:41 +msgid "Website" +msgstr "" + +#: mediagoblin/edit/forms.py:43 +msgid "Improperly formed URL" +msgstr "" + +#: mediagoblin/edit/views.py:54 +msgid "An entry with that slug already exists for this user." +msgstr "" + +#: mediagoblin/edit/views.py:75 +msgid "You are editing another user's media. Proceed with caution." +msgstr "" + +#: mediagoblin/edit/views.py:96 +msgid "You are editing a user's profile. Proceed with caution." +msgstr "" + +#: mediagoblin/submit/forms.py:29 +msgid "File" +msgstr "" + +#: mediagoblin/submit/views.py:45 +msgid "You must provide a file." +msgstr "" + +#: mediagoblin/submit/views.py:48 +msgid "The file doesn't seem to be an image!" +msgstr "" + +#: mediagoblin/submit/views.py:96 +msgid "Woohoo! Submitted!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:22 +msgid "GNU MediaGoblin" +msgstr "GNU MediaGoblin" + +#: mediagoblin/templates/mediagoblin/base.html:45 +msgid "Mediagoblin logo" +msgstr "logo de MediaGoblin" + +#: mediagoblin/templates/mediagoblin/base.html:51 +msgid "Submit media" +msgstr "Soumettez des médias" + +#: mediagoblin/templates/mediagoblin/base.html:62 +msgid "verify your email!" +msgstr "vérifiez votre addresse e-mail" + +#: mediagoblin/templates/mediagoblin/base.html:72 +msgid "Login" +msgstr "Connexion" + +#: mediagoblin/templates/mediagoblin/base.html:88 +msgid "" +"Powered by <a href=\"http://mediagoblin.org\">MediaGoblin</a>, a <a " +"href=\"http://gnu.org/\">GNU project</a>" +msgstr "" +"Alimenté par <a href=\"http://mediagoblin.org\">MediaGoblin</a>, un <a " +"href=\"http://gnu.org/\">projet GNU</a>" + +#: mediagoblin/templates/mediagoblin/root.html:21 +msgid "Welcome to GNU MediaGoblin!" +msgstr "Bienvenue à GNU MediaGoblin!" + +#: mediagoblin/templates/mediagoblin/root.html:26 +msgid "Submit an item" +msgstr "Soumettez un fichier" + +#: mediagoblin/templates/mediagoblin/root.html:31 +#, python-format +msgid "If you have an account, you can <a href=\"%(login_url)s\">Login</a>." +msgstr "" +"Si vous avez un compte, vous pouvez <a href=\"%(login_url)s\">Connecter</a>." + +#: mediagoblin/templates/mediagoblin/root.html:37 +#, python-format +msgid "" +"If you don't have an account, please <a " +"href=\"%(register_url)s\">Register</a>." +msgstr "" +"Si vous n'avez pas un compte, s'il vous plaît, <a " +"href=\"%(register_url)s\">vous inscrivez</a>." + +#: mediagoblin/templates/mediagoblin/auth/login.html:26 +msgid "Log in" +msgstr "Connexion" + +#: mediagoblin/templates/mediagoblin/auth/login.html:29 +msgid "Login failed!" +msgstr "Connexion manqué" + +#: mediagoblin/templates/mediagoblin/auth/login.html:34 +#: mediagoblin/templates/mediagoblin/auth/register.html:30 +#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:35 +#: mediagoblin/templates/mediagoblin/submit/start.html:32 +msgid "Submit" +msgstr "Soumettez" + +#: mediagoblin/templates/mediagoblin/auth/login.html:42 +msgid "Don't have an account yet?" +msgstr "N'avez-vous toujours un compte?" + +#: mediagoblin/templates/mediagoblin/auth/login.html:45 +msgid "Create one here!" +msgstr "En créez un ici!" + +#: mediagoblin/templates/mediagoblin/auth/register.html:27 +msgid "Create an account!" +msgstr "Créez un compte!" + +#: mediagoblin/templates/mediagoblin/auth/verification_email.txt:19 +#, python-format +msgid "" +"Hi %(username)s,\n" +"\n" +"to activate your GNU MediaGoblin account, open the following URL in\n" +"your web browser:\n" +"\n" +"%(verification_url)s" +msgstr "" +"Bonjour, %(username)s,\n" +"\n" +"pour activer votre compte de GNU MediaGoblin, ouvrez l'URL suite avec votre navigateur web:\n" +"\n" +"%(verification_url)s" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:29 +#, python-format +msgid "Editing %(media_title)s" +msgstr "On édit %(media_title)s" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:36 +msgid "Cancel" +msgstr "Annulez" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:37 +msgid "Save changes" +msgstr "Enregistrez les modifications" + +#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29 +#, python-format +msgid "Editing %(username)s's profile" +msgstr "" + +#: mediagoblin/templates/mediagoblin/listings/tag.html:29 +msgid "Media tagged with:" +msgstr "" + +#: mediagoblin/templates/mediagoblin/listings/tag.html:40 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:46 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:101 +msgid "atom feed" +msgstr "" + +#: mediagoblin/templates/mediagoblin/submit/start.html:26 +msgid "Submit yer media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 +#, python-format +msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:51 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:30 +msgid "Sorry, no such user found." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:37 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:57 +msgid "Verification needed" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:40 +msgid "Almost done! Your account still needs to be verified." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:45 +msgid "" +"An email should arrive in a few moments with instructions on how to do so." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:49 +msgid "In case it doesn't:" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:52 +msgid "Resend verification email" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:60 +msgid "" +"Someone has registered an account with this username, but it still has to be" +" verified." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:66 +#, python-format +msgid "" +"If you are that person but you've lost your verification email, you can <a " +"href=\"%(login_url)s\">log in</a> and resend it." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:76 +#, python-format +msgid "%(username)s's profile" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:84 +msgid "Edit profile" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:95 +#, python-format +msgid "View all of %(username)s's media" +msgstr "" + + diff --git a/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.mo Binary files differnew file mode 100644 index 00000000..8911785f --- /dev/null +++ b/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.po new file mode 100644 index 00000000..bd00fd1f --- /dev/null +++ b/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.po @@ -0,0 +1,308 @@ +# Translations template for PROJECT. +# Copyright (C) 2011 ORGANIZATION +# This file is distributed under the same license as the PROJECT project. +# +# <odin.omdal@gmail.com>, 2011. +msgid "" +msgstr "" +"Project-Id-Version: GNU MediaGoblin\n" +"Report-Msgid-Bugs-To: http://bugs.foocorp.net/projects/mediagoblin/issues\n" +"POT-Creation-Date: 2011-08-08 22:53-0500\n" +"PO-Revision-Date: 2011-08-10 21:23+0000\n" +"Last-Translator: velmont <odin.omdal@gmail.com>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 0.9.6\n" +"Language: nn_NO\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" + +#: mediagoblin/auth/forms.py:24 mediagoblin/auth/forms.py:46 +msgid "Username" +msgstr "Brukarnamn" + +#: mediagoblin/auth/forms.py:29 mediagoblin/auth/forms.py:50 +msgid "Password" +msgstr "Passord" + +#: mediagoblin/auth/forms.py:34 +msgid "Passwords must match." +msgstr "Passorda må vera like." + +#: mediagoblin/auth/forms.py:36 +msgid "Confirm password" +msgstr "Gjenta passord" + +#: mediagoblin/auth/forms.py:39 +msgid "Email address" +msgstr "E-postadresse" + +#: mediagoblin/auth/views.py:40 +msgid "Sorry, registration is disabled on this instance." +msgstr "Registrering er slege av. Orsak." + +#: mediagoblin/auth/views.py:55 +msgid "Sorry, a user with that name already exists." +msgstr "Ein konto med dette brukarnamnet finst allereide." + +#: mediagoblin/auth/views.py:152 +msgid "" +"Your email address has been verified. You may now login, edit your profile, " +"and submit images!" +msgstr "" +"E-postadressa di, og dimed kontoen din er stadfesta. Du kan no logga inn, " +"endra profilen din og lasta opp filer." + +#: mediagoblin/auth/views.py:158 +msgid "The verification key or user id is incorrect" +msgstr "Stadfestingsnykelen eller brukar-ID-en din er feil." + +#: mediagoblin/auth/views.py:179 +#: mediagoblin/templates/mediagoblin/auth/resent_verification_email.html:22 +msgid "Resent your verification email." +msgstr "Send ein ny stadfestingsepost." + +#: mediagoblin/edit/forms.py:26 mediagoblin/submit/forms.py:26 +msgid "Title" +msgstr "Tittel" + +#: mediagoblin/edit/forms.py:29 +msgid "Slug" +msgstr "Adressetittel" + +#: mediagoblin/edit/forms.py:30 +msgid "The slug can't be empty" +msgstr "Adressetittelen kan ikkje vera tom" + +#: mediagoblin/edit/forms.py:33 mediagoblin/submit/forms.py:31 +msgid "Tags" +msgstr "Merkelappar" + +#: mediagoblin/edit/forms.py:38 +msgid "Bio" +msgstr "Presentasjon" + +#: mediagoblin/edit/forms.py:41 +msgid "Website" +msgstr "Heimeside" + +#: mediagoblin/edit/forms.py:43 +msgid "Improperly formed URL" +msgstr "Ugyldeg URL" + +#: mediagoblin/edit/views.py:54 +msgid "An entry with that slug already exists for this user." +msgstr "Eit innlegg med denne adressetittelen finst allereie." + +#: mediagoblin/edit/views.py:75 +msgid "You are editing another user's media. Proceed with caution." +msgstr "Ver forsiktig, du redigerer ein annan konto sitt innlegg." + +#: mediagoblin/edit/views.py:96 +msgid "You are editing a user's profile. Proceed with caution." +msgstr "Ver forsiktig, du redigerer ein annan konto sin profil." + +#: mediagoblin/submit/forms.py:29 +msgid "File" +msgstr "Fil" + +#: mediagoblin/submit/views.py:45 +msgid "You must provide a file." +msgstr "Du må velja ei fil." + +#: mediagoblin/submit/views.py:48 +msgid "The file doesn't seem to be an image!" +msgstr "Fila verkar ikkje å vera ei gyldig biletefil." + +#: mediagoblin/submit/views.py:96 +msgid "Woohoo! Submitted!" +msgstr "Johoo! Opplasta!" + +#: mediagoblin/templates/mediagoblin/base.html:22 +msgid "GNU MediaGoblin" +msgstr "GNU MediaGoblin" + +#: mediagoblin/templates/mediagoblin/base.html:45 +msgid "Mediagoblin logo" +msgstr "MediaGoblin-logo" + +#: mediagoblin/templates/mediagoblin/base.html:51 +msgid "Submit media" +msgstr "Last opp" + +#: mediagoblin/templates/mediagoblin/base.html:62 +msgid "verify your email!" +msgstr "Stadfest epostadressa di" + +#: mediagoblin/templates/mediagoblin/base.html:72 +msgid "Login" +msgstr "Logg inn" + +#: mediagoblin/templates/mediagoblin/base.html:88 +msgid "" +"Powered by <a href=\"http://mediagoblin.org\">MediaGoblin</a>, a <a " +"href=\"http://gnu.org/\">GNU project</a>" +msgstr "" +"Driven av <a href=\"http://mediagoblin.org\">MediaGoblin</a>, eit <a " +"href=\"http://gnu.org/\">GNU-prosjekt</a>" + +#: mediagoblin/templates/mediagoblin/root.html:21 +msgid "Welcome to GNU MediaGoblin!" +msgstr "Velkomen til GNU MediaGoblin!" + +#: mediagoblin/templates/mediagoblin/root.html:26 +msgid "Submit an item" +msgstr "Last opp" + +#: mediagoblin/templates/mediagoblin/root.html:31 +#, python-format +msgid "If you have an account, you can <a href=\"%(login_url)s\">Login</a>." +msgstr "Har du ein konto? <a href=\"%(login_url)s\">Logg inn</a>." + +#: mediagoblin/templates/mediagoblin/root.html:37 +#, python-format +msgid "" +"If you don't have an account, please <a " +"href=\"%(register_url)s\">Register</a>." +msgstr "Har du ingen konto? <a href=\"%(register_url)s\">Registrer deg</a>." + +#: mediagoblin/templates/mediagoblin/auth/login.html:26 +msgid "Log in" +msgstr "Logg inn" + +#: mediagoblin/templates/mediagoblin/auth/login.html:29 +msgid "Login failed!" +msgstr "Innlogging feila!" + +#: mediagoblin/templates/mediagoblin/auth/login.html:34 +#: mediagoblin/templates/mediagoblin/auth/register.html:30 +#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:35 +#: mediagoblin/templates/mediagoblin/submit/start.html:32 +msgid "Submit" +msgstr "Send" + +#: mediagoblin/templates/mediagoblin/auth/login.html:42 +msgid "Don't have an account yet?" +msgstr "Har du ingen konto?" + +#: mediagoblin/templates/mediagoblin/auth/login.html:45 +msgid "Create one here!" +msgstr "Lag ein!" + +#: mediagoblin/templates/mediagoblin/auth/register.html:27 +msgid "Create an account!" +msgstr "Lag ein konto." + +#: mediagoblin/templates/mediagoblin/auth/verification_email.txt:19 +#, python-format +msgid "" +"Hi %(username)s,\n" +"\n" +"to activate your GNU MediaGoblin account, open the following URL in\n" +"your web browser:\n" +"\n" +"%(verification_url)s" +msgstr "" +"Hei %(username)s,\n" +"\n" +"opna den følgjande adressa i netlesaren din for å aktivera kontoen din:\n" +"\n" +"%(verification_url)s" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:29 +#, python-format +msgid "Editing %(media_title)s" +msgstr "Redigerer %(media_title)s" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:36 +msgid "Cancel" +msgstr "Avbryt" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:37 +msgid "Save changes" +msgstr "Lagra" + +#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29 +#, python-format +msgid "Editing %(username)s's profile" +msgstr "Redigerar profilen til %(username)s" + +#: mediagoblin/templates/mediagoblin/listings/tag.html:29 +msgid "Media tagged with:" +msgstr "Merkelappar:" + +#: mediagoblin/templates/mediagoblin/listings/tag.html:40 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:46 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:101 +msgid "atom feed" +msgstr "atom-feed" + +#: mediagoblin/templates/mediagoblin/submit/start.html:26 +msgid "Submit yer media" +msgstr "Last opp" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 +#, python-format +msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media" +msgstr "<a href=\"%(user_url)s\">%(username)s</a> sin mediafiler" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:51 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:30 +msgid "Sorry, no such user found." +msgstr "Fann ingen slik brukar" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:37 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:57 +msgid "Verification needed" +msgstr "Treng stadfesting" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:40 +msgid "Almost done! Your account still needs to be verified." +msgstr "Nesten klart. Du treng berre stadfesta kontoen din." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:45 +msgid "" +"An email should arrive in a few moments with instructions on how to do so." +msgstr "Ein epost med instruksjonar kjem straks." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:49 +msgid "In case it doesn't:" +msgstr "I tilfelle det ikkje skjer:" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:52 +msgid "Resend verification email" +msgstr "Send ein ny epost" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:60 +msgid "" +"Someone has registered an account with this username, but it still has to be" +" verified." +msgstr "" +"Det finst allereie ein konto med det brukarnamnet, men den kontoen treng " +"stadfesting." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:66 +#, python-format +msgid "" +"If you are that person but you've lost your verification email, you can <a " +"href=\"%(login_url)s\">log in</a> and resend it." +msgstr "" +"Viss dette er deg, kan du <a href=\"%(login_url)s\">logga inn</a> for å få " +"tilsendt ny epost med stadfestingslenkje." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:76 +#, python-format +msgid "%(username)s's profile" +msgstr "%(username)s sin profil" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:84 +msgid "Edit profile" +msgstr "Endra profil" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:95 +#, python-format +msgid "View all of %(username)s's media" +msgstr "Sjå all media frå %(username)s" + + diff --git a/mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.mo Binary files differnew file mode 100644 index 00000000..4dc4ab5f --- /dev/null +++ b/mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.po new file mode 100644 index 00000000..43f65af6 --- /dev/null +++ b/mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.po @@ -0,0 +1,310 @@ +# Translations template for PROJECT. +# Copyright (C) 2011 ORGANIZATION +# This file is distributed under the same license as the PROJECT project. +# +# <snd.noise@gmail.com>, 2011. +msgid "" +msgstr "" +"Project-Id-Version: GNU MediaGoblin\n" +"Report-Msgid-Bugs-To: http://bugs.foocorp.net/projects/mediagoblin/issues\n" +"POT-Creation-Date: 2011-08-08 22:53-0500\n" +"PO-Revision-Date: 2011-08-10 23:16+0000\n" +"Last-Translator: osc <snd.noise@gmail.com>\n" +"Language-Team: Portuguese (Brazilian) (http://www.transifex.net/projects/p/mediagoblin/team/pt_BR/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 0.9.6\n" +"Language: pt_BR\n" +"Plural-Forms: nplurals=2; plural=(n > 1)\n" + +#: mediagoblin/auth/forms.py:24 mediagoblin/auth/forms.py:46 +msgid "Username" +msgstr "Nome de Usuário" + +#: mediagoblin/auth/forms.py:29 mediagoblin/auth/forms.py:50 +msgid "Password" +msgstr "Senha" + +#: mediagoblin/auth/forms.py:34 +msgid "Passwords must match." +msgstr "Senhas devem ser iguais." + +#: mediagoblin/auth/forms.py:36 +msgid "Confirm password" +msgstr "Confirmar senha" + +#: mediagoblin/auth/forms.py:39 +msgid "Email address" +msgstr "Endereço de email" + +#: mediagoblin/auth/views.py:40 +msgid "Sorry, registration is disabled on this instance." +msgstr "Desculpa, o registro está desativado neste momento." + +#: mediagoblin/auth/views.py:55 +msgid "Sorry, a user with that name already exists." +msgstr "Desculpe, um usuário com este nome já existe." + +#: mediagoblin/auth/views.py:152 +msgid "" +"Your email address has been verified. You may now login, edit your profile, " +"and submit images!" +msgstr "" +"O seu endereço de e-mail foi verificado. Você pode agora fazer login, editar" +" seu perfil, e enviar imagens!" + +#: mediagoblin/auth/views.py:158 +msgid "The verification key or user id is incorrect" +msgstr "A chave de verificação ou nome usuário estão incorretos." + +#: mediagoblin/auth/views.py:179 +#: mediagoblin/templates/mediagoblin/auth/resent_verification_email.html:22 +msgid "Resent your verification email." +msgstr "O email de verificação foi reenviado." + +#: mediagoblin/edit/forms.py:26 mediagoblin/submit/forms.py:26 +msgid "Title" +msgstr "Título" + +#: mediagoblin/edit/forms.py:29 +msgid "Slug" +msgstr "" + +#: mediagoblin/edit/forms.py:30 +msgid "The slug can't be empty" +msgstr "" + +#: mediagoblin/edit/forms.py:33 mediagoblin/submit/forms.py:31 +msgid "Tags" +msgstr "Tags" + +#: mediagoblin/edit/forms.py:38 +msgid "Bio" +msgstr "Biográfia" + +#: mediagoblin/edit/forms.py:41 +msgid "Website" +msgstr "Website" + +#: mediagoblin/edit/forms.py:43 +msgid "Improperly formed URL" +msgstr "" + +#: mediagoblin/edit/views.py:54 +msgid "An entry with that slug already exists for this user." +msgstr "" + +#: mediagoblin/edit/views.py:75 +msgid "You are editing another user's media. Proceed with caution." +msgstr "" + +#: mediagoblin/edit/views.py:96 +msgid "You are editing a user's profile. Proceed with caution." +msgstr "" + +#: mediagoblin/submit/forms.py:29 +msgid "File" +msgstr "Arquivo" + +#: mediagoblin/submit/views.py:45 +msgid "You must provide a file." +msgstr "Você deve fornecer um arquivo." + +#: mediagoblin/submit/views.py:48 +msgid "The file doesn't seem to be an image!" +msgstr "O arquivo não parece ser uma imagem!" + +#: mediagoblin/submit/views.py:96 +msgid "Woohoo! Submitted!" +msgstr "Eba! Enviado!" + +#: mediagoblin/templates/mediagoblin/base.html:22 +msgid "GNU MediaGoblin" +msgstr "GNU MediaGoblin" + +#: mediagoblin/templates/mediagoblin/base.html:45 +msgid "Mediagoblin logo" +msgstr "Logo de Mediagoblin" + +#: mediagoblin/templates/mediagoblin/base.html:51 +msgid "Submit media" +msgstr "Enviar mídia" + +#: mediagoblin/templates/mediagoblin/base.html:62 +msgid "verify your email!" +msgstr "Verifique seu email!" + +#: mediagoblin/templates/mediagoblin/base.html:72 +msgid "Login" +msgstr "Login" + +#: mediagoblin/templates/mediagoblin/base.html:88 +msgid "" +"Powered by <a href=\"http://mediagoblin.org\">MediaGoblin</a>, a <a " +"href=\"http://gnu.org/\">GNU project</a>" +msgstr "" +"Powered by <a href=\"http://mediagoblin.org\">MediaGoblin</a>, a <a " +"href=\"http://gnu.org/\">GNU project</a>" + +#: mediagoblin/templates/mediagoblin/root.html:21 +msgid "Welcome to GNU MediaGoblin!" +msgstr "Bemvindo a GNU Mediagoblin!" + +#: mediagoblin/templates/mediagoblin/root.html:26 +msgid "Submit an item" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:31 +#, python-format +msgid "If you have an account, you can <a href=\"%(login_url)s\">Login</a>." +msgstr "Se você tem conta, você pode <a href=\"%(login_url)s\">Entrar</a> ." + +#: mediagoblin/templates/mediagoblin/root.html:37 +#, python-format +msgid "" +"If you don't have an account, please <a " +"href=\"%(register_url)s\">Register</a>." +msgstr "" +"Se você não tem conta, por favor <a href=\"%(register_url)s\">Registrar</a> " +"." + +#: mediagoblin/templates/mediagoblin/auth/login.html:26 +msgid "Log in" +msgstr "Entrar" + +#: mediagoblin/templates/mediagoblin/auth/login.html:29 +msgid "Login failed!" +msgstr "Login falhou!" + +#: mediagoblin/templates/mediagoblin/auth/login.html:34 +#: mediagoblin/templates/mediagoblin/auth/register.html:30 +#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:35 +#: mediagoblin/templates/mediagoblin/submit/start.html:32 +msgid "Submit" +msgstr "Enviar" + +#: mediagoblin/templates/mediagoblin/auth/login.html:42 +msgid "Don't have an account yet?" +msgstr "Ainda não tem conta?" + +#: mediagoblin/templates/mediagoblin/auth/login.html:45 +msgid "Create one here!" +msgstr "Crie uma aqui!" + +#: mediagoblin/templates/mediagoblin/auth/register.html:27 +msgid "Create an account!" +msgstr "Criar uma conta!" + +#: mediagoblin/templates/mediagoblin/auth/verification_email.txt:19 +#, python-format +msgid "" +"Hi %(username)s,\n" +"\n" +"to activate your GNU MediaGoblin account, open the following URL in\n" +"your web browser:\n" +"\n" +"%(verification_url)s" +msgstr "" +"Olá %(username)s,\n" +"\n" +"Para ativar sua conta GNU MediaGoblin, visite este endereço no seu navegador:\n" +"\n" +"%(verification_url)s" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:29 +#, python-format +msgid "Editing %(media_title)s" +msgstr "Editando %(media_title)s" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:36 +msgid "Cancel" +msgstr "Cancelar" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:37 +msgid "Save changes" +msgstr "Salvar mudanças" + +#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29 +#, python-format +msgid "Editing %(username)s's profile" +msgstr "Editando perfil de %(username)s" + +#: mediagoblin/templates/mediagoblin/listings/tag.html:29 +msgid "Media tagged with:" +msgstr "" + +#: mediagoblin/templates/mediagoblin/listings/tag.html:40 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:46 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:101 +msgid "atom feed" +msgstr "atom feed" + +#: mediagoblin/templates/mediagoblin/submit/start.html:26 +msgid "Submit yer media" +msgstr "Envie sua mídia" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 +#, python-format +msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:51 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:30 +msgid "Sorry, no such user found." +msgstr "Desculpe, tal usuário não encontrado." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:37 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:57 +msgid "Verification needed" +msgstr "Verificação necessária" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:40 +msgid "Almost done! Your account still needs to be verified." +msgstr "Quase pronto! Sua conta precisa de verificação." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:45 +msgid "" +"An email should arrive in a few moments with instructions on how to do so." +msgstr "Receberá um email com instruções de como fazer." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:49 +msgid "In case it doesn't:" +msgstr "Caso contrário:" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:52 +msgid "Resend verification email" +msgstr "Reenviar email de verificação" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:60 +msgid "" +"Someone has registered an account with this username, but it still has to be" +" verified." +msgstr "" +"Alguém já registrou uma conta com este nome, mas ainda tem que ser " +"verificada." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:66 +#, python-format +msgid "" +"If you are that person but you've lost your verification email, you can <a " +"href=\"%(login_url)s\">log in</a> and resend it." +msgstr "" +"Se você é essa pessoa, mas você perdeu seu e-mail de verificação, você pode " +"<a href=\"%(login_url)s\">efetuar login</a> e reenviá-la." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:76 +#, python-format +msgid "%(username)s's profile" +msgstr "Perfil de %(username)s" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:84 +msgid "Edit profile" +msgstr "Editar perfil" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:95 +#, python-format +msgid "View all of %(username)s's media" +msgstr "" + + diff --git a/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.mo Binary files differnew file mode 100644 index 00000000..361846d4 --- /dev/null +++ b/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.po new file mode 100644 index 00000000..feb261c8 --- /dev/null +++ b/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.po @@ -0,0 +1,314 @@ +# Translations template for PROJECT. +# Copyright (C) 2011 ORGANIZATION +# This file is distributed under the same license as the PROJECT project. +# +# <gapop@hotmail.com>, 2011. +msgid "" +msgstr "" +"Project-Id-Version: GNU MediaGoblin\n" +"Report-Msgid-Bugs-To: http://bugs.foocorp.net/projects/mediagoblin/issues\n" +"POT-Creation-Date: 2011-08-08 22:53-0500\n" +"PO-Revision-Date: 2011-08-10 21:52+0000\n" +"Last-Translator: gap <gapop@hotmail.com>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 0.9.6\n" +"Language: ro\n" +"Plural-Forms: nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1))\n" + +#: mediagoblin/auth/forms.py:24 mediagoblin/auth/forms.py:46 +msgid "Username" +msgstr "Nume de utilizator" + +#: mediagoblin/auth/forms.py:29 mediagoblin/auth/forms.py:50 +msgid "Password" +msgstr "Parolă" + +#: mediagoblin/auth/forms.py:34 +msgid "Passwords must match." +msgstr "Parolele trebuie să fie identice." + +#: mediagoblin/auth/forms.py:36 +msgid "Confirm password" +msgstr "Reintroduceți parola" + +#: mediagoblin/auth/forms.py:39 +msgid "Email address" +msgstr "Adresa de e-mail" + +#: mediagoblin/auth/views.py:40 +msgid "Sorry, registration is disabled on this instance." +msgstr "Ne pare rău, dar înscrierile sunt dezactivate pe această instanță." + +#: mediagoblin/auth/views.py:55 +msgid "Sorry, a user with that name already exists." +msgstr "Ne pare rău, există deja un utilizator cu același nume." + +#: mediagoblin/auth/views.py:152 +msgid "" +"Your email address has been verified. You may now login, edit your profile, " +"and submit images!" +msgstr "" +"Adresa dvs. de e-mail a fost confirmată. Puteți să vă autentificați, să vă " +"modificați profilul și să trimiteți imagini!" + +#: mediagoblin/auth/views.py:158 +msgid "The verification key or user id is incorrect" +msgstr "Cheie de verificare sau user ID incorect." + +#: mediagoblin/auth/views.py:179 +#: mediagoblin/templates/mediagoblin/auth/resent_verification_email.html:22 +msgid "Resent your verification email." +msgstr "E-mail-ul de verificare a fost retrimis." + +#: mediagoblin/edit/forms.py:26 mediagoblin/submit/forms.py:26 +msgid "Title" +msgstr "Titlu" + +#: mediagoblin/edit/forms.py:29 +msgid "Slug" +msgstr "Identificator" + +#: mediagoblin/edit/forms.py:30 +msgid "The slug can't be empty" +msgstr "Identificatorul nu poate să lipsească" + +#: mediagoblin/edit/forms.py:33 mediagoblin/submit/forms.py:31 +msgid "Tags" +msgstr "Etichete" + +#: mediagoblin/edit/forms.py:38 +msgid "Bio" +msgstr "Biografie" + +#: mediagoblin/edit/forms.py:41 +msgid "Website" +msgstr "Sit Web" + +#: mediagoblin/edit/forms.py:43 +msgid "Improperly formed URL" +msgstr "Adresă URL incorectă" + +#: mediagoblin/edit/views.py:54 +msgid "An entry with that slug already exists for this user." +msgstr "" +"Există deja un entry cu același identificator pentru acest utilizator." + +#: mediagoblin/edit/views.py:75 +msgid "You are editing another user's media. Proceed with caution." +msgstr "Editați fișierul unui alt utilizator. Se recomandă prudență." + +#: mediagoblin/edit/views.py:96 +msgid "You are editing a user's profile. Proceed with caution." +msgstr "Editați profilul unui utilizator. Se recomandă prudență." + +#: mediagoblin/submit/forms.py:29 +msgid "File" +msgstr "Fișier" + +#: mediagoblin/submit/views.py:45 +msgid "You must provide a file." +msgstr "Trebuie să selectați un fișier." + +#: mediagoblin/submit/views.py:48 +msgid "The file doesn't seem to be an image!" +msgstr "Fișierul nu pare a fi o imagine!" + +#: mediagoblin/submit/views.py:96 +msgid "Woohoo! Submitted!" +msgstr "Gata, trimis!" + +#: mediagoblin/templates/mediagoblin/base.html:22 +msgid "GNU MediaGoblin" +msgstr "GNU MediaGoblin" + +#: mediagoblin/templates/mediagoblin/base.html:45 +msgid "Mediagoblin logo" +msgstr "Logo MediaGoblin" + +#: mediagoblin/templates/mediagoblin/base.html:51 +msgid "Submit media" +msgstr "Transmiteți fișier" + +#: mediagoblin/templates/mediagoblin/base.html:62 +msgid "verify your email!" +msgstr "verificați e-mail-ul!" + +#: mediagoblin/templates/mediagoblin/base.html:72 +msgid "Login" +msgstr "Autentificare" + +#: mediagoblin/templates/mediagoblin/base.html:88 +msgid "" +"Powered by <a href=\"http://mediagoblin.org\">MediaGoblin</a>, a <a " +"href=\"http://gnu.org/\">GNU project</a>" +msgstr "" +"Construit cu <a href=\"http://mediagoblin.org\">MediaGoblin</a>, un <a " +"href=\"http://gnu.org/\">proiect GNU</a>" + +#: mediagoblin/templates/mediagoblin/root.html:21 +msgid "Welcome to GNU MediaGoblin!" +msgstr "Bun venit la GNU MediaGoblin!" + +#: mediagoblin/templates/mediagoblin/root.html:26 +msgid "Submit an item" +msgstr "Trimite un fișier" + +#: mediagoblin/templates/mediagoblin/root.html:31 +#, python-format +msgid "If you have an account, you can <a href=\"%(login_url)s\">Login</a>." +msgstr "" +"Dacă aveți deja un cont, vă puteți <a " +"href=\"%(login_url)s\">autentifica</a>." + +#: mediagoblin/templates/mediagoblin/root.html:37 +#, python-format +msgid "" +"If you don't have an account, please <a " +"href=\"%(register_url)s\">Register</a>." +msgstr "" +"Dacă nu aveți cont, vă rugăm să vă <a " +"href=\"%(register_url)s\">înregistrați</a>." + +#: mediagoblin/templates/mediagoblin/auth/login.html:26 +msgid "Log in" +msgstr "Autentificare" + +#: mediagoblin/templates/mediagoblin/auth/login.html:29 +msgid "Login failed!" +msgstr "Autentificare nereușită!" + +#: mediagoblin/templates/mediagoblin/auth/login.html:34 +#: mediagoblin/templates/mediagoblin/auth/register.html:30 +#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:35 +#: mediagoblin/templates/mediagoblin/submit/start.html:32 +msgid "Submit" +msgstr "Trimite" + +#: mediagoblin/templates/mediagoblin/auth/login.html:42 +msgid "Don't have an account yet?" +msgstr "Nu aveți un cont?" + +#: mediagoblin/templates/mediagoblin/auth/login.html:45 +msgid "Create one here!" +msgstr "Creați-l aici!" + +#: mediagoblin/templates/mediagoblin/auth/register.html:27 +msgid "Create an account!" +msgstr "Creați un cont!" + +#: mediagoblin/templates/mediagoblin/auth/verification_email.txt:19 +#, python-format +msgid "" +"Hi %(username)s,\n" +"\n" +"to activate your GNU MediaGoblin account, open the following URL in\n" +"your web browser:\n" +"\n" +"%(verification_url)s" +msgstr "" +"Bună, %(username)s,\n" +"\n" +"pentru activarea contului tău GNU MediaGoblin, accesează adresa următoare:\n" +"\n" +"%(verification_url)s" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:29 +#, python-format +msgid "Editing %(media_title)s" +msgstr "Editare %(media_title)s" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:36 +msgid "Cancel" +msgstr "Anulare" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:37 +msgid "Save changes" +msgstr "Salvează modificările" + +#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29 +#, python-format +msgid "Editing %(username)s's profile" +msgstr "Editare profil %(username)s" + +#: mediagoblin/templates/mediagoblin/listings/tag.html:29 +msgid "Media tagged with:" +msgstr "Etichete:" + +#: mediagoblin/templates/mediagoblin/listings/tag.html:40 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:46 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:101 +msgid "atom feed" +msgstr "flux atom" + +#: mediagoblin/templates/mediagoblin/submit/start.html:26 +msgid "Submit yer media" +msgstr "Trimite fișierele tale" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 +#, python-format +msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media" +msgstr "Fișierele lui <a href=\"%(user_url)s\">%(username)s</a>" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:51 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:30 +msgid "Sorry, no such user found." +msgstr "Ne pare rău, nu am găsit utilizatorul căutat." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:37 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:57 +msgid "Verification needed" +msgstr "Confirmare necesară" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:40 +msgid "Almost done! Your account still needs to be verified." +msgstr "Aproape gata! Este necesară confirmarea contului dvs." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:45 +msgid "" +"An email should arrive in a few moments with instructions on how to do so." +msgstr "Veți primi în scurt timp un mesaj prin e-mail cu instrucțiuni." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:49 +msgid "In case it doesn't:" +msgstr "Dacă nu primiți mesajul:" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:52 +msgid "Resend verification email" +msgstr "Retrimite mesajul de verificare" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:60 +msgid "" +"Someone has registered an account with this username, but it still has to be" +" verified." +msgstr "" +"Cineva s-a înscris pe site cu acest nume de utilizator, dar nu a fost " +"confirmat încă." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:66 +#, python-format +msgid "" +"If you are that person but you've lost your verification email, you can <a " +"href=\"%(login_url)s\">log in</a> and resend it." +msgstr "" +"Dacă dvs. sunteți persoana respectivă și nu mai aveți e-mail-ul de " +"verificare, puteți să vă <a href=\"%(login_url)s\">autentificați</a> pentru " +"a-l retrimite." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:76 +#, python-format +msgid "%(username)s's profile" +msgstr "Profil %(username)s" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:84 +msgid "Edit profile" +msgstr "Editare profil" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:95 +#, python-format +msgid "View all of %(username)s's media" +msgstr "Toate fișierele lui %(username)s" + + diff --git a/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.mo Binary files differnew file mode 100644 index 00000000..a70b1fef --- /dev/null +++ b/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.po new file mode 100644 index 00000000..bf2dd4fa --- /dev/null +++ b/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.po @@ -0,0 +1,309 @@ +# Translations template for PROJECT. +# Copyright (C) 2011 ORGANIZATION +# This file is distributed under the same license as the PROJECT project. +# +# Jure Repinc <jlp@holodeck1.com>, 2011. +msgid "" +msgstr "" +"Project-Id-Version: GNU MediaGoblin\n" +"Report-Msgid-Bugs-To: http://bugs.foocorp.net/projects/mediagoblin/issues\n" +"POT-Creation-Date: 2011-08-08 22:53-0500\n" +"PO-Revision-Date: 2011-08-10 21:28+0000\n" +"Last-Translator: JLP <jlp@holodeck1.com>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 0.9.6\n" +"Language: sl\n" +"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3)\n" + +#: mediagoblin/auth/forms.py:24 mediagoblin/auth/forms.py:46 +msgid "Username" +msgstr "Uporabniško ime" + +#: mediagoblin/auth/forms.py:29 mediagoblin/auth/forms.py:50 +msgid "Password" +msgstr "Geslo" + +#: mediagoblin/auth/forms.py:34 +msgid "Passwords must match." +msgstr "Gesli morata biti enaki." + +#: mediagoblin/auth/forms.py:36 +msgid "Confirm password" +msgstr "Potrdite geslo" + +#: mediagoblin/auth/forms.py:39 +msgid "Email address" +msgstr "E-poštni naslov" + +#: mediagoblin/auth/views.py:40 +msgid "Sorry, registration is disabled on this instance." +msgstr "Oprostite, prijava za ta izvod ni omogočena." + +#: mediagoblin/auth/views.py:55 +msgid "Sorry, a user with that name already exists." +msgstr "Oprostite, uporabnik s tem imenom že obstaja." + +#: mediagoblin/auth/views.py:152 +msgid "" +"Your email address has been verified. You may now login, edit your profile, " +"and submit images!" +msgstr "" +"Vaš e-poštni naslov je bil potrjen. Sedaj se lahko prijavite, uredite svoj " +"profil in pošljete slike." + +#: mediagoblin/auth/views.py:158 +msgid "The verification key or user id is incorrect" +msgstr "Potrditveni ključ ali uporabniška identifikacija je napačna" + +#: mediagoblin/auth/views.py:179 +#: mediagoblin/templates/mediagoblin/auth/resent_verification_email.html:22 +msgid "Resent your verification email." +msgstr "Ponovno pošiljanje potrditvene e-pošte." + +#: mediagoblin/edit/forms.py:26 mediagoblin/submit/forms.py:26 +msgid "Title" +msgstr "Naslov" + +#: mediagoblin/edit/forms.py:29 +msgid "Slug" +msgstr "Oznaka" + +#: mediagoblin/edit/forms.py:30 +msgid "The slug can't be empty" +msgstr "Oznaka ne sme biti prazna" + +#: mediagoblin/edit/forms.py:33 mediagoblin/submit/forms.py:31 +msgid "Tags" +msgstr "Oznake" + +#: mediagoblin/edit/forms.py:38 +msgid "Bio" +msgstr "Biografija" + +#: mediagoblin/edit/forms.py:41 +msgid "Website" +msgstr "Spletna stran" + +#: mediagoblin/edit/forms.py:43 +msgid "Improperly formed URL" +msgstr "Napačno oblikovan URL" + +#: mediagoblin/edit/views.py:54 +msgid "An entry with that slug already exists for this user." +msgstr "Vnos s to oznako za tega uporabnika že obstaja." + +#: mediagoblin/edit/views.py:75 +msgid "You are editing another user's media. Proceed with caution." +msgstr "Urejate vsebino drugega uporabnika. Nadaljujte pazljivo." + +#: mediagoblin/edit/views.py:96 +msgid "You are editing a user's profile. Proceed with caution." +msgstr "Urejate uporabniški profil. Nadaljujte pazljivo." + +#: mediagoblin/submit/forms.py:29 +msgid "File" +msgstr "Datoteka" + +#: mediagoblin/submit/views.py:45 +msgid "You must provide a file." +msgstr "Podati morate datoteko." + +#: mediagoblin/submit/views.py:48 +msgid "The file doesn't seem to be an image!" +msgstr "Kot kaže datoteka ni slika." + +#: mediagoblin/submit/views.py:96 +msgid "Woohoo! Submitted!" +msgstr "Juhej! Poslano." + +#: mediagoblin/templates/mediagoblin/base.html:22 +msgid "GNU MediaGoblin" +msgstr "GNU MediaGoblin" + +#: mediagoblin/templates/mediagoblin/base.html:45 +msgid "Mediagoblin logo" +msgstr "Logotip MediaGoblin" + +#: mediagoblin/templates/mediagoblin/base.html:51 +msgid "Submit media" +msgstr "Pošlji vsebino" + +#: mediagoblin/templates/mediagoblin/base.html:62 +msgid "verify your email!" +msgstr "Preverite svojo e-pošto." + +#: mediagoblin/templates/mediagoblin/base.html:72 +msgid "Login" +msgstr "Prijava" + +#: mediagoblin/templates/mediagoblin/base.html:88 +msgid "" +"Powered by <a href=\"http://mediagoblin.org\">MediaGoblin</a>, a <a " +"href=\"http://gnu.org/\">GNU project</a>" +msgstr "" +"Stran poganja <a href=\"http://mediagoblin.org\">MediaGoblin</a>, del <a " +"href=\"http://gnu.org/\">projekta GNU</a>" + +#: mediagoblin/templates/mediagoblin/root.html:21 +msgid "Welcome to GNU MediaGoblin!" +msgstr "Dobrodošli v GNU MediaGoblin!" + +#: mediagoblin/templates/mediagoblin/root.html:26 +msgid "Submit an item" +msgstr "Pošljite datoteko" + +#: mediagoblin/templates/mediagoblin/root.html:31 +#, python-format +msgid "If you have an account, you can <a href=\"%(login_url)s\">Login</a>." +msgstr "Če imate račun, se lahko <a href=\"%(login_url)s\">Prijavite</a>." + +#: mediagoblin/templates/mediagoblin/root.html:37 +#, python-format +msgid "" +"If you don't have an account, please <a " +"href=\"%(register_url)s\">Register</a>." +msgstr "Če računa še nimate, se <a href=\"%(register_url)s\">Registrirajte</a>." + +#: mediagoblin/templates/mediagoblin/auth/login.html:26 +msgid "Log in" +msgstr "Prijava" + +#: mediagoblin/templates/mediagoblin/auth/login.html:29 +msgid "Login failed!" +msgstr "Neuspešna prijava." + +#: mediagoblin/templates/mediagoblin/auth/login.html:34 +#: mediagoblin/templates/mediagoblin/auth/register.html:30 +#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:35 +#: mediagoblin/templates/mediagoblin/submit/start.html:32 +msgid "Submit" +msgstr "Pošlji" + +#: mediagoblin/templates/mediagoblin/auth/login.html:42 +msgid "Don't have an account yet?" +msgstr "Še nimate računa?" + +#: mediagoblin/templates/mediagoblin/auth/login.html:45 +msgid "Create one here!" +msgstr "Ustvarite si ga." + +#: mediagoblin/templates/mediagoblin/auth/register.html:27 +msgid "Create an account!" +msgstr "Ustvarite račun." + +#: mediagoblin/templates/mediagoblin/auth/verification_email.txt:19 +#, python-format +msgid "" +"Hi %(username)s,\n" +"\n" +"to activate your GNU MediaGoblin account, open the following URL in\n" +"your web browser:\n" +"\n" +"%(verification_url)s" +msgstr "" +"Pozdravljeni, %(username)s\n" +"\n" +"Za aktivacijo svojega računa GNU MediaGoblin odprite\n" +"naslednji URL v svojem spletnem brskalniku:\n" +"\n" +"%(verification_url)s" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:29 +#, python-format +msgid "Editing %(media_title)s" +msgstr "Urejanje %(media_title)s" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:36 +msgid "Cancel" +msgstr "Prekliči" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:37 +msgid "Save changes" +msgstr "Shrani spremembe" + +#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29 +#, python-format +msgid "Editing %(username)s's profile" +msgstr "Urejanje profila – %(username)s" + +#: mediagoblin/templates/mediagoblin/listings/tag.html:29 +msgid "Media tagged with:" +msgstr "Vsebina označena z:" + +#: mediagoblin/templates/mediagoblin/listings/tag.html:40 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:46 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:101 +msgid "atom feed" +msgstr "Vir Atom" + +#: mediagoblin/templates/mediagoblin/submit/start.html:26 +msgid "Submit yer media" +msgstr "Pošljite svojo vsebino" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 +#, python-format +msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media" +msgstr "Vsebina uporabnika <a href=\"%(user_url)s\">%(username)s</a>" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:51 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:30 +msgid "Sorry, no such user found." +msgstr "Oprostite, tega uporabnika ni bilo moč najti." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:37 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:57 +msgid "Verification needed" +msgstr "Potrebna je potrditev" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:40 +msgid "Almost done! Your account still needs to be verified." +msgstr "Skoraj ste zaključili. Račun je potrebno le še potrditi." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:45 +msgid "" +"An email should arrive in a few moments with instructions on how to do so." +msgstr "V kratkem bi morali prejeti e-pošto z navodili, kako to storiti." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:49 +msgid "In case it doesn't:" +msgstr "Če je ne prejmete:" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:52 +msgid "Resend verification email" +msgstr "Ponovno pošlji potrditveno e-pošto" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:60 +msgid "" +"Someone has registered an account with this username, but it still has to be" +" verified." +msgstr "" +"Nekdo je s tem uporabniškim imenom že registriral račun, vendar mora biti še" +" potrjen." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:66 +#, python-format +msgid "" +"If you are that person but you've lost your verification email, you can <a " +"href=\"%(login_url)s\">log in</a> and resend it." +msgstr "" +"Če ste ta oseba vi, a ste izgubili potrditveno e-pošto, se lahko <a " +"href=\"%(login_url)s\">prijavite</a> in jo ponovno pošljete." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:76 +#, python-format +msgid "%(username)s's profile" +msgstr "Profil – %(username)s" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:84 +msgid "Edit profile" +msgstr "Uredi profil" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:95 +#, python-format +msgid "View all of %(username)s's media" +msgstr "Prikaži vso vsebino uporabnika %(username)s" + + diff --git a/mediagoblin/i18n/sr/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/sr/LC_MESSAGES/mediagoblin.mo Binary files differnew file mode 100644 index 00000000..153584d3 --- /dev/null +++ b/mediagoblin/i18n/sr/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/sr/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/sr/LC_MESSAGES/mediagoblin.po new file mode 100644 index 00000000..ec8611ee --- /dev/null +++ b/mediagoblin/i18n/sr/LC_MESSAGES/mediagoblin.po @@ -0,0 +1,294 @@ +# Translations template for PROJECT. +# Copyright (C) 2011 ORGANIZATION +# This file is distributed under the same license as the PROJECT project. +# +msgid "" +msgstr "" +"Project-Id-Version: GNU MediaGoblin\n" +"Report-Msgid-Bugs-To: http://bugs.foocorp.net/projects/mediagoblin/issues\n" +"POT-Creation-Date: 2011-08-08 22:53-0500\n" +"PO-Revision-Date: 2011-08-09 03:57+0000\n" +"Last-Translator: cwebber <cwebber@dustycloud.org>\n" +"Language-Team: Serbian (http://www.transifex.net/projects/p/mediagoblin/team/sr/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 0.9.6\n" +"Language: sr\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n" + +#: mediagoblin/auth/forms.py:24 mediagoblin/auth/forms.py:46 +msgid "Username" +msgstr "" + +#: mediagoblin/auth/forms.py:29 mediagoblin/auth/forms.py:50 +msgid "Password" +msgstr "" + +#: mediagoblin/auth/forms.py:34 +msgid "Passwords must match." +msgstr "" + +#: mediagoblin/auth/forms.py:36 +msgid "Confirm password" +msgstr "" + +#: mediagoblin/auth/forms.py:39 +msgid "Email address" +msgstr "" + +#: mediagoblin/auth/views.py:40 +msgid "Sorry, registration is disabled on this instance." +msgstr "" + +#: mediagoblin/auth/views.py:55 +msgid "Sorry, a user with that name already exists." +msgstr "" + +#: mediagoblin/auth/views.py:152 +msgid "" +"Your email address has been verified. You may now login, edit your profile, " +"and submit images!" +msgstr "" + +#: mediagoblin/auth/views.py:158 +msgid "The verification key or user id is incorrect" +msgstr "" + +#: mediagoblin/auth/views.py:179 +#: mediagoblin/templates/mediagoblin/auth/resent_verification_email.html:22 +msgid "Resent your verification email." +msgstr "" + +#: mediagoblin/edit/forms.py:26 mediagoblin/submit/forms.py:26 +msgid "Title" +msgstr "" + +#: mediagoblin/edit/forms.py:29 +msgid "Slug" +msgstr "" + +#: mediagoblin/edit/forms.py:30 +msgid "The slug can't be empty" +msgstr "" + +#: mediagoblin/edit/forms.py:33 mediagoblin/submit/forms.py:31 +msgid "Tags" +msgstr "" + +#: mediagoblin/edit/forms.py:38 +msgid "Bio" +msgstr "" + +#: mediagoblin/edit/forms.py:41 +msgid "Website" +msgstr "" + +#: mediagoblin/edit/forms.py:43 +msgid "Improperly formed URL" +msgstr "" + +#: mediagoblin/edit/views.py:54 +msgid "An entry with that slug already exists for this user." +msgstr "" + +#: mediagoblin/edit/views.py:75 +msgid "You are editing another user's media. Proceed with caution." +msgstr "" + +#: mediagoblin/edit/views.py:96 +msgid "You are editing a user's profile. Proceed with caution." +msgstr "" + +#: mediagoblin/submit/forms.py:29 +msgid "File" +msgstr "" + +#: mediagoblin/submit/views.py:45 +msgid "You must provide a file." +msgstr "" + +#: mediagoblin/submit/views.py:48 +msgid "The file doesn't seem to be an image!" +msgstr "" + +#: mediagoblin/submit/views.py:96 +msgid "Woohoo! Submitted!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:22 +msgid "GNU MediaGoblin" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:45 +msgid "Mediagoblin logo" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:51 +msgid "Submit media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:62 +msgid "verify your email!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:72 +msgid "Login" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:88 +msgid "" +"Powered by <a href=\"http://mediagoblin.org\">MediaGoblin</a>, a <a " +"href=\"http://gnu.org/\">GNU project</a>" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:21 +msgid "Welcome to GNU MediaGoblin!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:26 +msgid "Submit an item" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:31 +#, python-format +msgid "If you have an account, you can <a href=\"%(login_url)s\">Login</a>." +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:37 +#, python-format +msgid "" +"If you don't have an account, please <a " +"href=\"%(register_url)s\">Register</a>." +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/login.html:26 +msgid "Log in" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/login.html:29 +msgid "Login failed!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/login.html:34 +#: mediagoblin/templates/mediagoblin/auth/register.html:30 +#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:35 +#: mediagoblin/templates/mediagoblin/submit/start.html:32 +msgid "Submit" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/login.html:42 +msgid "Don't have an account yet?" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/login.html:45 +msgid "Create one here!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/register.html:27 +msgid "Create an account!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/verification_email.txt:19 +#, python-format +msgid "" +"Hi %(username)s,\n" +"\n" +"to activate your GNU MediaGoblin account, open the following URL in\n" +"your web browser:\n" +"\n" +"%(verification_url)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:29 +#, python-format +msgid "Editing %(media_title)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:36 +msgid "Cancel" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:37 +msgid "Save changes" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29 +#, python-format +msgid "Editing %(username)s's profile" +msgstr "" + +#: mediagoblin/templates/mediagoblin/listings/tag.html:29 +msgid "Media tagged with:" +msgstr "" + +#: mediagoblin/templates/mediagoblin/listings/tag.html:40 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:46 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:101 +msgid "atom feed" +msgstr "" + +#: mediagoblin/templates/mediagoblin/submit/start.html:26 +msgid "Submit yer media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 +#, python-format +msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:51 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:30 +msgid "Sorry, no such user found." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:37 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:57 +msgid "Verification needed" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:40 +msgid "Almost done! Your account still needs to be verified." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:45 +msgid "" +"An email should arrive in a few moments with instructions on how to do so." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:49 +msgid "In case it doesn't:" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:52 +msgid "Resend verification email" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:60 +msgid "" +"Someone has registered an account with this username, but it still has to be" +" verified." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:66 +#, python-format +msgid "" +"If you are that person but you've lost your verification email, you can <a " +"href=\"%(login_url)s\">log in</a> and resend it." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:76 +#, python-format +msgid "%(username)s's profile" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:84 +msgid "Edit profile" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:95 +#, python-format +msgid "View all of %(username)s's media" +msgstr "" + + diff --git a/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.mo Binary files differnew file mode 100644 index 00000000..04fe0b6f --- /dev/null +++ b/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.po new file mode 100644 index 00000000..311c5656 --- /dev/null +++ b/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.po @@ -0,0 +1,311 @@ +# Translations template for PROJECT. +# Copyright (C) 2011 ORGANIZATION +# This file is distributed under the same license as the PROJECT project. +# +# <transifex@wandborg.se>, 2011. +msgid "" +msgstr "" +"Project-Id-Version: GNU MediaGoblin\n" +"Report-Msgid-Bugs-To: http://bugs.foocorp.net/projects/mediagoblin/issues\n" +"POT-Creation-Date: 2011-08-08 22:53-0500\n" +"PO-Revision-Date: 2011-08-09 15:00+0000\n" +"Last-Translator: joar <transifex@wandborg.se>\n" +"Language-Team: Swedish (http://www.transifex.net/projects/p/mediagoblin/team/sv/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 0.9.6\n" +"Language: sv\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" + +#: mediagoblin/auth/forms.py:24 mediagoblin/auth/forms.py:46 +msgid "Username" +msgstr "Användarnamn" + +#: mediagoblin/auth/forms.py:29 mediagoblin/auth/forms.py:50 +msgid "Password" +msgstr "Lösenord" + +#: mediagoblin/auth/forms.py:34 +msgid "Passwords must match." +msgstr "Lösenorden måste vara identiska." + +#: mediagoblin/auth/forms.py:36 +msgid "Confirm password" +msgstr "Bekräfta lösenord" + +#: mediagoblin/auth/forms.py:39 +msgid "Email address" +msgstr "E-postadress" + +#: mediagoblin/auth/views.py:40 +msgid "Sorry, registration is disabled on this instance." +msgstr "Vi beklagar, registreringen är avtängd på den här instansen." + +#: mediagoblin/auth/views.py:55 +msgid "Sorry, a user with that name already exists." +msgstr "En användare med det användarnamnet finns redan." + +#: mediagoblin/auth/views.py:152 +msgid "" +"Your email address has been verified. You may now login, edit your profile, " +"and submit images!" +msgstr "" +"Din e-postadress är verifierad. Du kan nu logga in, redigera din profil och " +"ladda upp filer!" + +#: mediagoblin/auth/views.py:158 +msgid "The verification key or user id is incorrect" +msgstr "Verifieringsnyckeln eller användar-IDt är fel." + +#: mediagoblin/auth/views.py:179 +#: mediagoblin/templates/mediagoblin/auth/resent_verification_email.html:22 +msgid "Resent your verification email." +msgstr "Skickade ett nytt verifierings-email." + +#: mediagoblin/edit/forms.py:26 mediagoblin/submit/forms.py:26 +msgid "Title" +msgstr "Titel" + +#: mediagoblin/edit/forms.py:29 +msgid "Slug" +msgstr "Sökvägsnamn" + +#: mediagoblin/edit/forms.py:30 +msgid "The slug can't be empty" +msgstr "Sökvägsnamnet kan inte vara tomt" + +#: mediagoblin/edit/forms.py:33 mediagoblin/submit/forms.py:31 +msgid "Tags" +msgstr "Taggar" + +#: mediagoblin/edit/forms.py:38 +msgid "Bio" +msgstr "Presentation" + +#: mediagoblin/edit/forms.py:41 +msgid "Website" +msgstr "Hemsida" + +#: mediagoblin/edit/forms.py:43 +msgid "Improperly formed URL" +msgstr "Ogiltig URL" + +#: mediagoblin/edit/views.py:54 +msgid "An entry with that slug already exists for this user." +msgstr "Ett inlägg med det sökvägsnamnet existerar redan." + +#: mediagoblin/edit/views.py:75 +msgid "You are editing another user's media. Proceed with caution." +msgstr "Var försiktig, du redigerar någon annans inlägg." + +#: mediagoblin/edit/views.py:96 +msgid "You are editing a user's profile. Proceed with caution." +msgstr "Var försiktig, du redigerar en annan användares profil." + +#: mediagoblin/submit/forms.py:29 +msgid "File" +msgstr "Fil" + +#: mediagoblin/submit/views.py:45 +msgid "You must provide a file." +msgstr "Du måste ange en fil" + +#: mediagoblin/submit/views.py:48 +msgid "The file doesn't seem to be an image!" +msgstr "Filen verkar inte vara en giltig bildfil!" + +#: mediagoblin/submit/views.py:96 +msgid "Woohoo! Submitted!" +msgstr "Tjohoo! Upladdat!" + +#: mediagoblin/templates/mediagoblin/base.html:22 +msgid "GNU MediaGoblin" +msgstr "GNU MediaGoblin" + +#: mediagoblin/templates/mediagoblin/base.html:45 +msgid "Mediagoblin logo" +msgstr "MediaGoblin logo" + +#: mediagoblin/templates/mediagoblin/base.html:51 +msgid "Submit media" +msgstr "Ladda upp" + +#: mediagoblin/templates/mediagoblin/base.html:62 +msgid "verify your email!" +msgstr "Verifiera din e-postadress!" + +#: mediagoblin/templates/mediagoblin/base.html:72 +msgid "Login" +msgstr "Logga in" + +#: mediagoblin/templates/mediagoblin/base.html:88 +msgid "" +"Powered by <a href=\"http://mediagoblin.org\">MediaGoblin</a>, a <a " +"href=\"http://gnu.org/\">GNU project</a>" +msgstr "" +"Drivs av <a href=\"http://mediagoblin.org\">MediaGoblin</a>, ett <a " +"href=\"http://gnu.org/\">GNU</a>-projekt" + +#: mediagoblin/templates/mediagoblin/root.html:21 +msgid "Welcome to GNU MediaGoblin!" +msgstr "Välkommen till GNU MediaGoblin!" + +#: mediagoblin/templates/mediagoblin/root.html:26 +msgid "Submit an item" +msgstr "Ladda upp" + +#: mediagoblin/templates/mediagoblin/root.html:31 +#, python-format +msgid "If you have an account, you can <a href=\"%(login_url)s\">Login</a>." +msgstr "Har du ett konto? <a href=\"%(login_url)s\">Logga in</a>." + +#: mediagoblin/templates/mediagoblin/root.html:37 +#, python-format +msgid "" +"If you don't have an account, please <a " +"href=\"%(register_url)s\">Register</a>." +msgstr "" +"Har du inget konto? <a href=\"%(register_url)s\">Registrera ett konto</a>." + +#: mediagoblin/templates/mediagoblin/auth/login.html:26 +msgid "Log in" +msgstr "Logga in" + +#: mediagoblin/templates/mediagoblin/auth/login.html:29 +msgid "Login failed!" +msgstr "Inloggning misslyckades!" + +#: mediagoblin/templates/mediagoblin/auth/login.html:34 +#: mediagoblin/templates/mediagoblin/auth/register.html:30 +#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:35 +#: mediagoblin/templates/mediagoblin/submit/start.html:32 +msgid "Submit" +msgstr "Skicka" + +#: mediagoblin/templates/mediagoblin/auth/login.html:42 +msgid "Don't have an account yet?" +msgstr "Har du inget konto?" + +#: mediagoblin/templates/mediagoblin/auth/login.html:45 +msgid "Create one here!" +msgstr "Skapa ett!" + +#: mediagoblin/templates/mediagoblin/auth/register.html:27 +msgid "Create an account!" +msgstr "Skapa ett konto!" + +#: mediagoblin/templates/mediagoblin/auth/verification_email.txt:19 +#, python-format +msgid "" +"Hi %(username)s,\n" +"\n" +"to activate your GNU MediaGoblin account, open the following URL in\n" +"your web browser:\n" +"\n" +"%(verification_url)s" +msgstr "" +"Hej %(username)s,\n" +"\n" +"oppna den följande URLen i din webbläsare för att aktivera ditt konto på GNU MediaGoblin:\n" +"\n" +"%(verification_url)s" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:29 +#, python-format +msgid "Editing %(media_title)s" +msgstr "Redigerar %(media_title)s" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:36 +msgid "Cancel" +msgstr "Avbryt" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:37 +msgid "Save changes" +msgstr "Spara" + +#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29 +#, python-format +msgid "Editing %(username)s's profile" +msgstr "Redigerar %(username)ss profil" + +#: mediagoblin/templates/mediagoblin/listings/tag.html:29 +msgid "Media tagged with:" +msgstr "Taggat med:" + +#: mediagoblin/templates/mediagoblin/listings/tag.html:40 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:46 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:101 +msgid "atom feed" +msgstr "atom-feed" + +#: mediagoblin/templates/mediagoblin/submit/start.html:26 +msgid "Submit yer media" +msgstr "Ladda upp" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 +#, python-format +msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media" +msgstr "<a href=\"%(user_url)s\">%(username)s</a>s media" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:51 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:30 +msgid "Sorry, no such user found." +msgstr "Finns ingen sådan användare ännu." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:37 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:57 +msgid "Verification needed" +msgstr "Verifiering krävs" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:40 +msgid "Almost done! Your account still needs to be verified." +msgstr "Nästan klart! Nu behöver du bara verifiera ditt konto." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:45 +msgid "" +"An email should arrive in a few moments with instructions on how to do so." +msgstr "" +"Ett e-postmeddelande med instruktioner kommer att hamna hos dig inom kort." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:49 +msgid "In case it doesn't:" +msgstr "Om det inte skulle göra det:" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:52 +msgid "Resend verification email" +msgstr "Skicka ett nytt e-postmeddelande" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:60 +msgid "" +"Someone has registered an account with this username, but it still has to be" +" verified." +msgstr "" +"Det finns redan ett konto med det här användarnamnet, men det behöver " +"verifieras." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:66 +#, python-format +msgid "" +"If you are that person but you've lost your verification email, you can <a " +"href=\"%(login_url)s\">log in</a> and resend it." +msgstr "" +"Om det är du som är den personen och har förlorat ditt e-postmeddelande med " +"detaljer om hur du verifierar ditt konto så kan du <a " +"href=\"%(login_url)s\">logga in</a> och begära ett nytt." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:76 +#, python-format +msgid "%(username)s's profile" +msgstr "%(username)ss profil" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:84 +msgid "Edit profile" +msgstr "Redigera profil" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:95 +#, python-format +msgid "View all of %(username)s's media" +msgstr "Se all media från %(username)s" + + diff --git a/mediagoblin/init/__init__.py b/mediagoblin/init/__init__.py index 1e519cc9..ff005703 100644 --- a/mediagoblin/init/__init__.py +++ b/mediagoblin/init/__init__.py @@ -23,6 +23,7 @@ from mediagoblin.mg_globals import setup_globals from mediagoblin.db.open import setup_connection_and_db_from_config from mediagoblin.db.util import MigrationManager from mediagoblin.workbench import WorkbenchManager +from mediagoblin.storage import storage_system_from_config class Error(Exception): pass @@ -60,9 +61,16 @@ def setup_database(): # Tiny hack to warn user if our migration is out of date if not migration_manager.database_at_latest_migration(): - print ( - "*WARNING:* Your migrations are out of date, " - "maybe run ./bin/gmg migrate?") + db_migration_num = migration_manager.database_current_migration() + latest_migration_num = migration_manager.latest_migration() + if db_migration_num < latest_migration_num: + print ( + "*WARNING:* Your migrations are out of date, " + "maybe run ./bin/gmg migrate?") + elif db_migration_num > latest_migration_num: + print ( + "*WARNING:* Your migrations are out of date... " + "in fact they appear to be from the future?!") setup_globals( db_connection = connection, @@ -103,6 +111,19 @@ def get_staticdirector(app_config): "direct_remote_paths must be provided") +def setup_storage(): + app_config = mg_globals.app_config + + public_store = storage_system_from_config(app_config, 'publicstore') + queue_store = storage_system_from_config(app_config, 'queuestore') + + setup_globals( + public_store = public_store, + queue_store = queue_store) + + return public_store, queue_store + + def setup_workbench(): app_config = mg_globals.app_config diff --git a/mediagoblin/templates/mediagoblin/auth/register_success.html b/mediagoblin/listings/__init__.py index cd82a0b9..fbccb9b8 100644 --- a/mediagoblin/templates/mediagoblin/auth/register_success.html +++ b/mediagoblin/listings/__init__.py @@ -1,4 +1,3 @@ -{# # GNU MediaGoblin -- federated, autonomous media hosting # Copyright (C) 2011 Free Software Foundation, Inc # @@ -14,12 +13,7 @@ # # 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 mediagoblin_content %} - <p> - Register successful! :D <br /> - You should get a confirmation email soon. - </p> -{% endblock %} +""" +Non-user listing views and routing should go in this submodule. +""" diff --git a/mediagoblin/listings/routing.py b/mediagoblin/listings/routing.py new file mode 100644 index 00000000..61dd5210 --- /dev/null +++ b/mediagoblin/listings/routing.py @@ -0,0 +1,28 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 Free Software Foundation, Inc +# +# 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 routes.route import Route + +tag_routes = [ + # Route('mediagoblin.listings.tags_home', "/", + # controller="mediagoblin.listings.views:tags_home"), + Route('mediagoblin.listings.tags_listing', "/{tag}/", + controller="mediagoblin.listings.views:tag_listing"), + Route('mediagoblin.listings.tag_atom_feed', "/{tag}/atom/", + controller="mediagoblin.listings.views:tag_atom_feed"), + ] + diff --git a/mediagoblin/listings/views.py b/mediagoblin/listings/views.py new file mode 100644 index 00000000..aade7e64 --- /dev/null +++ b/mediagoblin/listings/views.py @@ -0,0 +1,91 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 Free Software Foundation, Inc +# +# 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.db.util import DESCENDING + +from mediagoblin.util import Pagination, render_to_response +from mediagoblin.decorators import uses_pagination + +from werkzeug.contrib.atom import AtomFeed + + +def _get_tag_name_from_entries(media_entries, tag_slug): + """ + Get a tag name from the first entry by looking it up via its slug. + """ + # ... this is slightly hacky looking :\ + tag_name = tag_slug + if media_entries.count(): + for tag in media_entries[0]['tags']: + if tag['slug'] == tag_slug: + tag_name == tag['name'] + break + + return tag_name + + +@uses_pagination +def tag_listing(request, page): + """'Gallery'/listing for this tag slug""" + tag_slug = request.matchdict[u'tag'] + + cursor = request.db.MediaEntry.find( + {u'state': u'processed', + u'tags.slug': tag_slug}) + cursor = cursor.sort('created', DESCENDING) + + pagination = Pagination(page, cursor) + media_entries = pagination() + + tag_name = _get_tag_name_from_entries(media_entries, tag_slug) + + return render_to_response( + request, + 'mediagoblin/listings/tag.html', + {'tag_slug': tag_slug, + 'tag_name': tag_name, + 'media_entries': media_entries, + 'pagination': pagination}) + + +ATOM_DEFAULT_NR_OF_UPDATED_ITEMS = 15 + +def tag_atom_feed(request): + """ + generates the atom feed with the tag images + """ + tag_slug = request.matchdict[u'tag'] + + cursor = request.db.MediaEntry.find( + {u'state': u'processed', + u'tags.slug': tag_slug}) + cursor = cursor.sort('created', DESCENDING) + cursor = cursor.limit(ATOM_DEFAULT_NR_OF_UPDATED_ITEMS) + + feed = AtomFeed( + "MediaGoblin: Feed for tag '%s'" % tag_slug, + feed_url=request.url, + url=request.host_url) + + for entry in cursor: + feed.add(entry.get('title'), + entry.get('description_html'), + content_type='html', + author=entry.uploader()['username'], + updated=entry.get('created'), + url=entry.url_for_self(request.urlgen)) + + return feed.get_response() diff --git a/mediagoblin/mg_globals.py b/mediagoblin/mg_globals.py index 12a0e016..80ff5ead 100644 --- a/mediagoblin/mg_globals.py +++ b/mediagoblin/mg_globals.py @@ -1,3 +1,18 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 Free Software Foundation, Inc +# +# 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/>. """ In some places, we need to access the database, public_store, queue_store """ diff --git a/mediagoblin/process_media/__init__.py b/mediagoblin/process_media/__init__.py index 125b24e0..8e12ca4d 100644 --- a/mediagoblin/process_media/__init__.py +++ b/mediagoblin/process_media/__init__.py @@ -19,6 +19,7 @@ from mediagoblin.db.util import ObjectId from celery.task import task from mediagoblin import mg_globals as mgg +from contextlib import contextmanager THUMB_SIZE = 180, 180 @@ -31,6 +32,12 @@ def create_pub_filepath(entry, filename): unicode(entry['_id']), filename]) +@contextmanager +def closing(callback): + try: + yield callback + finally: + pass @task def process_media_initial(media_id): @@ -53,7 +60,7 @@ def process_media_initial(media_id): thumb_filepath = create_pub_filepath(entry, 'thumbnail.jpg') thumb_file = mgg.public_store.get_file(thumb_filepath, 'w') - with thumb_file: + with closing(thumb_file): thumb.save(thumb_file, "JPEG", quality=90) """ @@ -73,7 +80,7 @@ def process_media_initial(media_id): medium_filepath = create_pub_filepath(entry, 'medium.jpg') medium_file = mgg.public_store.get_file(medium_filepath, 'w') - with medium_file: + with closing(medium_file): medium.save(medium_file, "JPEG", quality=90) medium_processed = True @@ -84,7 +91,7 @@ def process_media_initial(media_id): with queued_file: original_filepath = create_pub_filepath(entry, queued_filepath[-1]) - with mgg.public_store.get_file(original_filepath, 'wb') as original_file: + with closing(mgg.public_store.get_file(original_filepath, 'wb')) as original_file: original_file.write(queued_file.read()) mgg.queue_store.delete_file(queued_filepath) diff --git a/mediagoblin/routing.py b/mediagoblin/routing.py index b854c85a..1340da60 100644 --- a/mediagoblin/routing.py +++ b/mediagoblin/routing.py @@ -20,6 +20,8 @@ from mediagoblin.auth.routing import auth_routes from mediagoblin.submit.routing import submit_routes from mediagoblin.user_pages.routing import user_routes from mediagoblin.edit.routing import edit_routes +from mediagoblin.listings.routing import tag_routes + def get_mapper(): mapping = Mapper() @@ -33,5 +35,6 @@ def get_mapper(): mapping.extend(submit_routes, '/submit') mapping.extend(user_routes, '/u') mapping.extend(edit_routes, '/edit') + mapping.extend(tag_routes, '/tag') return mapping diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css index 31b8ebc2..59c2f49d 100644 --- a/mediagoblin/static/css/base.css +++ b/mediagoblin/static/css/base.css @@ -1,15 +1,17 @@ body { - background-color: #1F1F1F; - color: #aaa; + background-color: #111; + background-image: url("../images/background.png"); + color: #999; font-family: sans-serif; - padding:none; - margin:0px; - height:100%; + padding: none; + margin: 0px; + height: 100%; + font: 16px "HelveticaNeue-Light","Helvetica Neue Light","Helvetica Neue",Helvetica,Arial,sans-serif; } form { - margin:0px; - padding:0px; + margin: 0px; + padding: 0px; } /* Carter One font */ @@ -18,22 +20,34 @@ form { font-family: 'Carter One'; font-style: normal; font-weight: normal; - src: local('CarterOne'), url('http://themes.googleusercontent.com/font?kit=FWNn6ITYqL6or7ZTmBxRhq3fkYX5z1QtDUdIWoaaD_k') format('woff'); + src: local('CarterOne'), url('http://themes.googleusercontent.com/font?kit=VjW2qt1pkqVtO22ObxgEBRsxEYwM7FgeyaSgU71cLG0') format('woff'); } /* text styles */ h1{ - font-family: 'Carter One', arial, serif; + font-family: 'Carter One',arial,serif; margin-bottom: 15px; - margin-top:15px; + margin-top: 15px; + color: #fff; + font-size: 30px; } h2{ - margin-top:20px; + margin-top: 20px; + color: #fff; +} + +h3{ + border-bottom: 1px solid #222; + font-size: 18px; } a { + color: #999; +} + +a.highlight { color: #fff; } @@ -44,202 +58,207 @@ label { /* website structure */ .mediagoblin_body { - position:relative; - min-height:100%; + position: relative; + min-height: 100%; } .mediagoblin_header { - width:100%; - height:36px; - background-color:#2F2F2F; - padding-top:14px; - margin-bottom:40px; + height: 36px; + padding-top: 14px; + margin-bottom: 20px; + border-bottom: 1px solid #222222; } .header_submit{ - color:#272727; - background-color:#aaa; + color: #272727; + background-color: #aaa; background-image: -webkit-gradient(linear, left top, left bottom, from(##D2D2D2), to(#aaa)); background-image: -webkit-linear-gradient(top, #D2D2D2, #aaa); background-image: -moz-linear-gradient(top, #D2D2D2, #aaa); background-image: -ms-linear-gradient(top, #D2D2D2, #aaa); background-image: -o-linear-gradient(top, #D2D2D2, #aaa); background-image: linear-gradient(top, #D2D2D2, #aaa); - box-shadow:0px 0px 4px #000; - border-radius:5px 5px 5px 5px; - margin:8px; - padding:3px 8px; - text-decoration:none; - border:medium none; - font-family:'Carter One',arial,serif; + box-shadow: 0px 0px 4px #000; + border-radius: 5px 5px 5px 5px; + margin: 8px; + padding: 3px 8px; + text-decoration: none; + border: medium none; + font-family: 'Carter One',arial,serif; } .mediagoblin_footer { - width:100%; - height:30px; - background-color:#2F2F2F; - bottom:0px; - padding-top:8px; - position:absolute; - text-align:center; - font-size:14px; - color:#999; + height: 30px; + border-top: 1px solid #222222; + bottom: 0px; + padding-top: 8px; + text-align: center; + font-size: 14px; + color: #999; } .mediagoblin_content { - padding-bottom:74px; + padding-bottom: 74px; } .mediagoblin_header_right { - float:right; + float: right; } /* common website elements */ .button { - font-family:'Carter One', arial, serif; - height:32px; - min-width:99px; - background-color:#86d4b1; + font-family: 'Carter One', arial, serif; + height: 32px; + min-width: 99px; + background-color: #86d4b1; background-image: -webkit-gradient(linear, left top, left bottom, from(#86d4b1), to(#62caa2)); background-image: -webkit-linear-gradient(top, #86d4b1, #62caa2); background-image: -moz-linear-gradient(top, #86d4b1, #62caa2); background-image: -ms-linear-gradient(top, #86d4b1, #62caa2); background-image: -o-linear-gradient(top, #86d4b1, #62caa2); background-image: linear-gradient(top, #86d4b1, #62caa2); - box-shadow:0px 0px 4px #000; - border-radius:5px; - border:none; - color:#272727; - margin:10px 0px 10px 15px; - font-size:1em; - text-align:center; - padding-left:11px; - padding-right:11px; + box-shadow: 0px 0px 4px #000; + border-radius: 5px; + border: none; + color: #272727; + margin: 10px 0px 10px 15px; + font-size: 1em; + text-align: center; + padding-left: 11px; + padding-right: 11px; + text-decoration: none; } .pagination{ -text-align:center; +text-align: center; } .pagination_arrow{ - margin:5px; + margin: 5px; } /* forms */ .form_box { - background-color:#393939; - background-image:url("../images/background_lines.png"); - background-repeat:repeat-x; - font-size:18px; - padding-bottom:30px; - padding-top:30px; - margin-left:auto; - margin-right:auto; - display:block; - float:none; + background-color: #222; + background-image: url("../images/background_lines.png"); + background-repeat: repeat-x; + font-size: 18px; + padding-bottom: 30px; + padding-top: 30px; + margin-left: auto; + margin-right: auto; + display: block; + float: none; } .edit_box { - background-image:url("../images/background_edit.png"); + background-image: url("../images/background_edit.png"); } .form_box h1 { - font-size:28px; + font-size: 28px; } .form_field_input input, .form_field_input textarea { - width:100%; - font-size:18px; + width: 100%; + font-size: 18px; } .form_field_box { - margin-bottom:24px; + margin-bottom: 24px; } .form_field_label,.form_field_input { - margin-bottom:4px; + margin-bottom: 4px; } .form_field_error { - background-color:#87453b; - color:#fff; - border:none; - font-size:16px; - padding:9px; - margin-top:8px; - margin-bottom:8px; + background-color: #87453b; + color: #fff; + border: none; + font-size: 16px; + padding: 9px; + margin-top: 8px; + margin-bottom: 8px; } .form_submit_buttons { - text-align:right; + text-align: right; } /* comments */ .comment_author { - margin-bottom:40px; - padding-top:4px; + margin-bottom: 40px; + padding-top: 4px; + font-size: 14px; } .comment_content p { - margin-bottom:4px; + margin-bottom: 4px; } /* media galleries */ .media_thumbnail { - padding:0px; - width:180px; - height:180px; - overflow:hidden; - float:left; - margin:0px 4px 10px 4px; - text-align:center; + padding: 0px; + width: 180px; + height: 180px; + overflow: hidden; + float: left; + margin: 0px 4px 10px 4px; + text-align: center; +} + +/* media detail */ + +.media_image_container { + text-align: center; } /* icons */ img.media_icon{ - margin:0 4px; - vertical-align:sub; + margin: 0 4px; + vertical-align: sub; } /* navigation */ .navigation_button{ - width:139px; - display:block; - float:left; - text-align:center; - background-color:#393939; - text-decoration:none; - padding:12px 0pt; - font-family:'Carter One', arial, serif; - font-size:2em; - margin:0 0 20px + width: 139px; + display: block; + float: left; + text-align: center; + background-color: #222; + text-decoration: none; + padding: 12px 0pt; + font-family: 'Carter One', arial, serif; + font-size: 2em; + margin: 0 0 20px } p.navigation_button{ - color:#272727; + color: #272727; } .navigation_left{ - margin-right:2px; + margin-right: 2px; } /* messages */ ul.mediagoblin_messages { - list-style:none inside; - color:#f7f7f7; + list-style: none inside; + color: #f7f7f7; } .mediagoblin_messages li { - margin:5px 0; - padding:8px; - text-align:center; + margin: 5px 0; + padding: 8px; + text-align: center; } .message_success { @@ -260,5 +279,15 @@ ul.mediagoblin_messages { .message_debug { background-color: #f7f7f7; - color:#272727; + color: #272727; +} + +ul.mediaentry_tags { + list-style-type: none; +} + +ul.mediaentry_tags li { + display: inline; + margin: 0px 5px 0px 0px; + padding: 0px; } diff --git a/mediagoblin/static/css/contrib/960_16_col.css b/mediagoblin/static/css/contrib/960_16_col.css deleted file mode 120000 index bc1a430c..00000000 --- a/mediagoblin/static/css/contrib/960_16_col.css +++ /dev/null @@ -1 +0,0 @@ -../../../contrib/960_16_col.css
\ No newline at end of file diff --git a/mediagoblin/static/css/contrib/reset.css b/mediagoblin/static/css/contrib/reset.css deleted file mode 120000 index 87ae5592..00000000 --- a/mediagoblin/static/css/contrib/reset.css +++ /dev/null @@ -1 +0,0 @@ -../../../contrib/reset.css
\ No newline at end of file diff --git a/mediagoblin/static/css/contrib/text.css b/mediagoblin/static/css/contrib/text.css deleted file mode 120000 index d75ce48b..00000000 --- a/mediagoblin/static/css/contrib/text.css +++ /dev/null @@ -1 +0,0 @@ -../../../contrib/text.css
\ No newline at end of file diff --git a/mediagoblin/static/css/extlib/960_16_col.css b/mediagoblin/static/css/extlib/960_16_col.css new file mode 120000 index 00000000..d4e43898 --- /dev/null +++ b/mediagoblin/static/css/extlib/960_16_col.css @@ -0,0 +1 @@ +../../../../extlib/960.gs/960_16_col.css
\ No newline at end of file diff --git a/mediagoblin/static/css/extlib/reset.css b/mediagoblin/static/css/extlib/reset.css new file mode 120000 index 00000000..65d06d34 --- /dev/null +++ b/mediagoblin/static/css/extlib/reset.css @@ -0,0 +1 @@ +../../../../extlib/960.gs/reset.css
\ No newline at end of file diff --git a/mediagoblin/static/css/extlib/text.css b/mediagoblin/static/css/extlib/text.css new file mode 120000 index 00000000..2d864de4 --- /dev/null +++ b/mediagoblin/static/css/extlib/text.css @@ -0,0 +1 @@ +../../../../extlib/960.gs/text.css
\ No newline at end of file diff --git a/mediagoblin/static/images/background.png b/mediagoblin/static/images/background.png Binary files differnew file mode 100644 index 00000000..aa101308 --- /dev/null +++ b/mediagoblin/static/images/background.png diff --git a/mediagoblin/storage.py b/mediagoblin/storage.py index 5d6faa4c..88c748ce 100644 --- a/mediagoblin/storage.py +++ b/mediagoblin/storage.py @@ -19,6 +19,7 @@ import re import shutil import urlparse import uuid +import cloudfiles from werkzeug.utils import secure_filename @@ -28,11 +29,21 @@ from mediagoblin import util # Errors ######## -class Error(Exception): pass -class InvalidFilepath(Error): pass -class NoWebServing(Error): pass -class NotImplementedError(Error): pass +class Error(Exception): + pass + + +class InvalidFilepath(Error): + pass + + +class NoWebServing(Error): + pass + + +class NotImplementedError(Error): + pass ############################################### @@ -117,7 +128,7 @@ class StorageInterface(object): Eg, if the filename doesn't exist: >>> storage_handler.get_unique_filename(['dir1', 'dir2', 'fname.jpg']) [u'dir1', u'dir2', u'fname.jpg'] - + But if a file does exist, let's get one back with at uuid tacked on: >>> storage_handler.get_unique_filename(['dir1', 'dir2', 'fname.jpg']) [u'dir1', u'dir2', u'd02c3571-dd62-4479-9d62-9e3012dada29-fname.jpg'] @@ -184,7 +195,7 @@ class BasicFileStorage(StorageInterface): """ return os.path.join( self.base_dir, *clean_listy_filepath(filepath)) - + def file_exists(self, filepath): return os.path.exists(self._resolve_filepath(filepath)) @@ -216,6 +227,191 @@ class BasicFileStorage(StorageInterface): return self._resolve_filepath(filepath) +class CloudFilesStorage(StorageInterface): + def __init__(self, **kwargs): + self.param_container = kwargs.get('cloudfiles_container') + self.param_user = kwargs.get('cloudfiles_user') + self.param_api_key = kwargs.get('cloudfiles_api_key') + self.param_host = kwargs.get('cloudfiles_host') + self.param_use_servicenet = kwargs.get('cloudfiles_use_servicenet') + + if not self.param_host: + print('No CloudFiles host URL specified, ' + 'defaulting to Rackspace US') + + self.connection = cloudfiles.get_connection( + username=self.param_user, + api_key=self.param_api_key, + servicenet=True if self.param_use_servicenet == 'true' or \ + self.param_use_servicenet == True else False) + + if not self.param_container == \ + self.connection.get_container(self.param_container): + self.container = self.connection.create_container( + self.param_container) + self.container.make_public( + ttl=60 * 60 * 2) + else: + self.container = self.connection.get_container( + self.param_container) + + def _resolve_filepath(self, filepath): + return '/'.join( + clean_listy_filepath(filepath)) + + def file_exists(self, filepath): + try: + object = self.container.get_object( + self._resolve_filepath(filepath)) + return True + except cloudfiles.errors.NoSuchObject: + return False + + def get_file(self, filepath, mode='r'): + try: + obj = self.container.get_object( + self._resolve_filepath(filepath)) + except cloudfiles.errors.NoSuchObject: + obj = self.container.create_object( + self._resolve_filepath(filepath)) + + return obj + + def delete_file(self, filepath): + # TODO: Also delete unused directories if empty (safely, with + # checks to avoid race conditions). + self.container.delete_object(filepath) + + def file_url(self, filepath): + return self.get_file(filepath).public_uri() + + +class MountStorage(StorageInterface): + """ + Experimental "Mount" virtual Storage Interface + + This isn't an interface to some real storage, instead + it's a redirecting interface, that redirects requests + to other "StorageInterface"s. + For example, requests for ["store1", "a"] to first + storage with the path ["a"], etc. + + To set this up, you currently need to call the mount() + method with the target path and a backend, that shall + be available under that target path. + You have to mount things in a sensible order, + especially you can't mount ["a", "b"] before ["a"]. + """ + def __init__(self, **kwargs): + self.mounttab = {} + + def mount(self, dirpath, backend): + """ + Mount a new backend under dirpath + """ + new_ent = clean_listy_filepath(dirpath) + + print "Mounting:", repr(new_ent) + already, rem_1, table, rem_2 = self._resolve_to_backend(new_ent, True) + print "===", repr(already), repr(rem_1), repr(rem_2), len(table) + + assert (len(rem_2) > 0) or (None not in table), \ + "That path is already mounted" + assert (len(rem_2) > 0) or (len(table)==0), \ + "A longer path is already mounted here" + + for part in rem_2: + table[part] = {} + table = table[part] + table[None] = backend + + def _resolve_to_backend(self, filepath, extra_info = False): + """ + extra_info = True is for internal use! + + Normally, returns the backend and the filepath inside that backend. + + With extra_info = True it returns the last directory node and the + remaining filepath from there in addition. + """ + table = self.mounttab + filepath = filepath[:] + res_fp = None + while True: + new_be = table.get(None) + if (new_be is not None) or res_fp is None: + res_be = new_be + res_fp = filepath[:] + res_extra = (table, filepath[:]) + # print "... New res: %r, %r, %r" % (res_be, res_fp, res_extra) + if len(filepath) == 0: + break + query = filepath.pop(0) + entry = table.get(query) + if entry is not None: + table = entry + res_extra = (table, filepath[:]) + else: + break + if extra_info: + return (res_be, res_fp) + res_extra + else: + return (res_be, res_fp) + + def resolve_to_backend(self, filepath): + backend, filepath = self._resolve_to_backend(filepath) + if backend is None: + raise Error("Path not mounted") + return backend, filepath + + def __repr__(self, table = None, indent = []): + res = [] + if table is None: + res.append("MountStorage<") + table = self.mounttab + v = table.get(None) + if v: + res.append(" " * len(indent) + repr(indent) + ": " + repr(v)) + for k, v in table.iteritems(): + if k == None: + continue + res.append(" " * len(indent) + repr(k) + ":") + res += self.__repr__(v, indent + [k]) + if table is self.mounttab: + res.append(">") + return "\n".join(res) + else: + return res + + def file_exists(self, filepath): + backend, filepath = self.resolve_to_backend(filepath) + return backend.file_exists(filepath) + + def get_file(self, filepath, mode='r'): + backend, filepath = self.resolve_to_backend(filepath) + return backend.get_file(filepath, mode) + + def delete_file(self, filepath): + backend, filepath = self.resolve_to_backend(filepath) + return backend.delete_file(filepath) + + def file_url(self, filepath): + backend, filepath = self.resolve_to_backend(filepath) + return backend.file_url(filepath) + + def get_local_path(self, filepath): + backend, filepath = self.resolve_to_backend(filepath) + return backend.get_local_path(filepath) + + def copy_locally(self, filepath, dest_path): + """ + Need to override copy_locally, because the local_storage + attribute is not correct. + """ + backend, filepath = self.resolve_to_backend(filepath) + backend.copy_locally(filepath, dest_path) + + ########### # Utilities ########### @@ -283,7 +479,7 @@ def storage_system_from_config(paste_config, storage_prefix): for key, value in paste_config.iteritems() if prefix_re.match(key)]) - if config_params.has_key('storage_class'): + if 'storage_class' in config_params: storage_class = config_params['storage_class'] config_params.pop('storage_class') else: @@ -291,5 +487,3 @@ def storage_system_from_config(paste_config, storage_prefix): storage_class = util.import_component(storage_class) return storage_class(**config_params) - - diff --git a/mediagoblin/submit/__init__.py b/mediagoblin/submit/__init__.py index e69de29b..a8eeb5ed 100644 --- a/mediagoblin/submit/__init__.py +++ b/mediagoblin/submit/__init__.py @@ -0,0 +1,17 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 Free Software Foundation, Inc +# +# 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/>. + + diff --git a/mediagoblin/submit/forms.py b/mediagoblin/submit/forms.py index 3fd9ea49..241d32dc 100644 --- a/mediagoblin/submit/forms.py +++ b/mediagoblin/submit/forms.py @@ -17,10 +17,16 @@ import wtforms +from mediagoblin.util import tag_length_validator +from mediagoblin.util import fake_ugettext_passthrough as _ + class SubmitStartForm(wtforms.Form): title = wtforms.TextField( - 'Title', + _('Title'), [wtforms.validators.Length(min=0, max=500)]) description = wtforms.TextAreaField('Description of this work') - file = wtforms.FileField('File') + file = wtforms.FileField(_('File')) + tags = wtforms.TextField( + _('Tags'), + [tag_length_validator]) diff --git a/mediagoblin/submit/views.py b/mediagoblin/submit/views.py index f19bf22e..59d8fe3f 100644 --- a/mediagoblin/submit/views.py +++ b/mediagoblin/submit/views.py @@ -16,11 +16,14 @@ from os.path import splitext from cgi import FieldStorage +from string import split from werkzeug.utils import secure_filename from mediagoblin.util import ( - render_to_response, redirect, cleaned_markdown_conversion) + render_to_response, redirect, cleaned_markdown_conversion, \ + convert_to_tag_list_of_dicts) +from mediagoblin.util import pass_to_ugettext as _ from mediagoblin.decorators import require_active_login from mediagoblin.submit import forms as submit_forms, security from mediagoblin.process_media import process_media_initial @@ -39,10 +42,10 @@ def submit_start(request): and isinstance(request.POST['file'], FieldStorage) and request.POST['file'].file): submit_form.file.errors.append( - u'You must provide a file.') + _(u'You must provide a file.')) elif not security.check_filetype(request.POST['file']): submit_form.file.errors.append( - u'The file doesn\'t seem to be an image!') + _(u"The file doesn't seem to be an image!")) else: filename = request.POST['file'].filename @@ -59,6 +62,10 @@ def submit_start(request): entry['media_type'] = u'image' # heh entry['uploader'] = request.user['_id'] + # Process the user's folksonomy "tags" + entry['tags'] = convert_to_tag_list_of_dicts( + request.POST.get('tags')) + # Save, just so we can get the entry id for the sake of using # it to generate the file path entry.save(validate=False) @@ -87,7 +94,7 @@ def submit_start(request): result = process_media_initial.delay(unicode(entry['_id'])) entry['queued_task_id'] = result.task_id - add_message(request, SUCCESS, 'Woohoo! Submitted!') + add_message(request, SUCCESS, _('Woohoo! Submitted!')) return redirect(request, "mediagoblin.user_pages.user_home", user = request.user['username']) diff --git a/mediagoblin/templates/mediagoblin/auth/login.html b/mediagoblin/templates/mediagoblin/auth/login.html index e25783ea..5750feb0 100644 --- a/mediagoblin/templates/mediagoblin/auth/login.html +++ b/mediagoblin/templates/mediagoblin/auth/login.html @@ -23,20 +23,27 @@ <form action="{{ request.urlgen('mediagoblin.auth.login') }}" method="POST" enctype="multipart/form-data"> <div class="grid_6 prefix_1 suffix_1 form_box"> - <h1>Log in</h1> + <h1>{% trans %}Log in{% endtrans %}</h1> {% if login_failed %} - <div class="form_field_error">Login failed!</div> + <div class="form_field_error"> + {% trans %}Login failed!{% endtrans %} + </div> {% endif %} {{ wtforms_util.render_divs(login_form) }} <div class="form_submit_buttons"> - <input type="submit" value="submit" class="button"/> + <input type="submit" value="{% trans %}Submit{% endtrans %}" class="button"/> </div> {% if next %} <input type="hidden" name="next" value="{{ next }}" class="button" style="display: none;"/> {% endif %} {% if allow_registration %} - <p>Don't have an account yet?<br /><a href="{{ request.urlgen('mediagoblin.auth.register') }}">Create one here!</a></p> + <p> + {% trans %}Don't have an account yet?{% endtrans %} + <br /> + <a href="{{ request.urlgen('mediagoblin.auth.register') }}"> + {%- trans %}Create one here!{% endtrans %}</a> + </p> {% endif %} </div> </form> diff --git a/mediagoblin/templates/mediagoblin/auth/register.html b/mediagoblin/templates/mediagoblin/auth/register.html index f77b3782..623cbdfd 100644 --- a/mediagoblin/templates/mediagoblin/auth/register.html +++ b/mediagoblin/templates/mediagoblin/auth/register.html @@ -24,10 +24,11 @@ <form action="{{ request.urlgen('mediagoblin.auth.register') }}" method="POST" enctype="multipart/form-data"> <div class="grid_6 prefix_1 suffix_1 form_box"> - <h1>Create an account!</h1> + <h1>{% trans %}Create an account!{% endtrans %}</h1> {{ wtforms_util.render_divs(register_form) }} <div class="form_submit_buttons"> - <input type="submit" value="submit" class="button" /> + <input type="submit" value="{% trans %}Submit{% endtrans %}" + class="button" /> </div> </div> </form> diff --git a/mediagoblin/templates/mediagoblin/auth/resent_verification_email.html b/mediagoblin/templates/mediagoblin/auth/resent_verification_email.html index da3a9e99..8fd80ee9 100644 --- a/mediagoblin/templates/mediagoblin/auth/resent_verification_email.html +++ b/mediagoblin/templates/mediagoblin/auth/resent_verification_email.html @@ -19,6 +19,6 @@ {% block mediagoblin_content %} <p> - Resent your verification email. + {% trans %}Resent your verification email.{% endtrans %} </p> {% endblock %} diff --git a/mediagoblin/templates/mediagoblin/auth/verification_email.txt b/mediagoblin/templates/mediagoblin/auth/verification_email.txt index 7863374d..32053101 100644 --- a/mediagoblin/templates/mediagoblin/auth/verification_email.txt +++ b/mediagoblin/templates/mediagoblin/auth/verification_email.txt @@ -14,9 +14,13 @@ # # 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/>. -#} +-#} + +{% trans username=username, verification_url=verification_url|safe -%} Hi {{ username }}, -to activate your GNU MediaGoblin account, open the following URL in your web browser +to activate your GNU MediaGoblin account, open the following URL in +your web browser: -{{ verification_url|safe }} +{{ verification_url }} +{%- endtrans %} diff --git a/mediagoblin/templates/mediagoblin/base.html b/mediagoblin/templates/mediagoblin/base.html index 12f188de..986e0995 100644 --- a/mediagoblin/templates/mediagoblin/base.html +++ b/mediagoblin/templates/mediagoblin/base.html @@ -19,13 +19,13 @@ <html> <head> <meta charset="utf-8"> - <title>{% block title %}GNU MediaGoblin{% endblock title %}</title> + <title>{% block title %}{% trans %}GNU MediaGoblin{% endtrans %}{% endblock title %}</title> <link rel="stylesheet" type="text/css" - href="{{ request.staticdirect('/css/contrib/reset.css') }}"/> + href="{{ request.staticdirect('/css/extlib/reset.css') }}"/> <link rel="stylesheet" type="text/css" - href="{{ request.staticdirect('/css/contrib/text.css') }}"/> + href="{{ request.staticdirect('/css/extlib/text.css') }}"/> <link rel="stylesheet" type="text/css" - href="{{ request.staticdirect('/css/contrib/960_16_col.css') }}"/> + href="{{ request.staticdirect('/css/extlib/960_16_col.css') }}"/> <link rel="stylesheet" type="text/css" href="{{ request.staticdirect('/css/base.css') }}"/> {% block mediagoblin_head %} @@ -36,27 +36,41 @@ {% block mediagoblin_body %} <div class="mediagoblin_body"> {% block mediagoblin_header %} - <div class="mediagoblin_header"> - <div class="container_16"> - <div class="grid_16"> - {% block mediagoblin_logo %} - <a class="mediagoblin_logo" href="{{ request.urlgen('index') }}"><img src="{{ request.staticdirect('/images/logo.png') }}" alt="Mediagoblin logo" /></a> - {% endblock %} + <div class="container_16"> + <div class="grid_16 mediagoblin_header"> + {% block mediagoblin_logo %} + <a class="mediagoblin_logo" + href="{{ request.urlgen('index') }}"> + <img src="{{ request.staticdirect('/images/logo.png') }}" + alt="{% trans %}Mediagoblin logo{% endtrans %}" /> + </a> + {% endblock %} + {% if request.user and request.user['status'] == 'active' %} + <a class="header_submit" + href="{{ request.urlgen('mediagoblin.submit.start') }}"> + {% trans %}Submit media{% endtrans %} + </a> + {% endif %} + {% block mediagoblin_header_title %}{% endblock %} + <div class="mediagoblin_header_right"> {% if request.user %} - <a class="header_submit" href="{{ request.urlgen('mediagoblin.submit.start') }}">Submit media</a> - {% endif %} - {% block mediagoblin_header_title %}{% endblock %} - <div class="mediagoblin_header_right"> - {% if request.user %} + {# the following link should only appear when verification is needed #} + {% if request.user.status == "needs_email_verification" %} <a href="{{ request.urlgen('mediagoblin.user_pages.user_home', - user= request.user['username']) }}"> - {{ request.user['username'] }}</a>'s account - (<a href="{{ request.urlgen('mediagoblin.auth.logout') }}">logout</a>) - {% else %} - <a href="{{ request.urlgen('mediagoblin.auth.login') }}"> - Login</a> + user=request.user['username']) }}" + class="header_submit"> + {% trans %}verify your email!{% endtrans %}</a> {% endif %} - </div> + + <a href="{{ request.urlgen('mediagoblin.user_pages.user_home', + user= request.user['username']) }}"> + {{ request.user['username'] }}</a> + + (<a href="{{ request.urlgen('mediagoblin.auth.logout') }}">logout</a>) + {% else %} + <a href="{{ request.urlgen('mediagoblin.auth.login') }}"> + {% trans %}Login{% endtrans %}</a> + {% endif %} </div> </div> </div> @@ -69,11 +83,11 @@ </div> </div> {% block mediagoblin_footer %} - <div class="mediagoblin_footer"> - <div class="container_16"> - <div class="grid_16"> + <div class="container_16"> + <div class="grid_16 mediagoblin_footer"> + {% trans -%} Powered by <a href="http://mediagoblin.org">MediaGoblin</a>, a <a href="http://gnu.org/">GNU project</a> - </div> + {%- endtrans %} </div> </div> {% endblock %} diff --git a/mediagoblin/templates/mediagoblin/edit/edit.html b/mediagoblin/templates/mediagoblin/edit/edit.html index d19034cb..3dc170c8 100644 --- a/mediagoblin/templates/mediagoblin/edit/edit.html +++ b/mediagoblin/templates/mediagoblin/edit/edit.html @@ -26,15 +26,15 @@ media= media._id) }}" method="POST" enctype="multipart/form-data"> <div class="grid_8 prefix_1 suffix_1 edit_box form_box"> - <h1>Editing {{ media.title }}</h1> + <h1>{% trans media_title=media.title %}Editing {{ media_title }}{% endtrans %}</h1> <div style="text-align: center;" > <img src="{{ request.app.public_store.file_url( media['media_files']['thumb']) }}" /> </div> {{ wtforms_util.render_divs(form) }} <div class="form_submit_buttons"> - <a href="{{ media.url_for_self(request.urlgen) }}">Cancel</a> - <input type="submit" value="Save changes" class="button" /> + <a href="{{ media.url_for_self(request.urlgen) }}">{% trans %}Cancel{% endtrans %}</a> + <input type="submit" value="{% trans %}Save changes{% endtrans %}" class="button" /> </div> </div> </form> diff --git a/mediagoblin/templates/mediagoblin/edit/edit_profile.html b/mediagoblin/templates/mediagoblin/edit/edit_profile.html index a11b86d7..534e5f20 100644 --- a/mediagoblin/templates/mediagoblin/edit/edit_profile.html +++ b/mediagoblin/templates/mediagoblin/edit/edit_profile.html @@ -25,10 +25,14 @@ user['username'] }}" method="POST" enctype="multipart/form-data"> <div class="grid_8 prefix_1 suffix_1 edit_box form_box"> - <h1>Editing {{ user['username'] }}'s profile</h1> + <h1> + {%- trans username=user['username'] -%} + Editing {{ username }}'s profile + {%- endtrans %} + </h1> {{ wtforms_util.render_divs(form) }} <div class="form_submit_buttons"> - <input type="submit" value="submit" class="button" /> + <input type="submit" value="{% trans %}Submit{% endtrans %}" class="button" /> </div> </div> </form> diff --git a/mediagoblin/templates/mediagoblin/listings/tag.html b/mediagoblin/templates/mediagoblin/listings/tag.html new file mode 100644 index 00000000..a013797f --- /dev/null +++ b/mediagoblin/templates/mediagoblin/listings/tag.html @@ -0,0 +1,43 @@ +{# +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 Free Software Foundation, Inc +# +# 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 mediagoblin_head %} + <link rel="alternate" type="application/atom+xml" + href="{{ request.urlgen( + 'mediagoblin.listings.tag_atom_feed', + tag=tag_slug) }}"> +{% endblock mediagoblin_head %} + +{% block mediagoblin_content -%} + <h1> + {% trans %}Media tagged with:{% endtrans %} {{ tag_name }} + </h1> + + <div class="container_16 media_gallery"> + {% include "mediagoblin/utils/object_gallery.html" %} + </div> + + <div class="grid_16"> + <a href="{{ request.urlgen( + 'mediagoblin.listings.tag_atom_feed', + tag=tag_slug) }}"> + {%- trans %}atom feed{% endtrans -%} + </a> + </div> +{% endblock %} diff --git a/mediagoblin/templates/mediagoblin/root.html b/mediagoblin/templates/mediagoblin/root.html index bae033c4..a4e19984 100644 --- a/mediagoblin/templates/mediagoblin/root.html +++ b/mediagoblin/templates/mediagoblin/root.html @@ -22,22 +22,26 @@ {% if request.user %} <p> - <a href="{{ request.urlgen('mediagoblin.submit.start') }}">Submit an item</a> + <a href="{{ request.urlgen('mediagoblin.submit.start') }}"> + {%- trans %}Submit an item{% endtrans -%} + </a> </p> {% else %} <p> - If you have an account, you can - <a href="{{ request.urlgen('mediagoblin.auth.login') }}">Login</a>. + {% trans login_url=request.urlgen('mediagoblin.auth.login') -%} + If you have an account, you can <a href="{{ login_url }}">Login</a>. + {%- endtrans %} </p> {% if allow_registration %} <p> - If you don't have an account, please - <a href="{{ request.urlgen('mediagoblin.auth.register') }}">Register</a>. + {% trans register_url=request.urlgen('mediagoblin.auth.register') -%} + If you don't have an account, please <a href="{{ register_url }}">Register</a>. + {%- endtrans %} </p> {% endif %} {% endif %} {# temporarily, an "image gallery" that isn't one really ;) #} - {% include "mediagoblin/utils/object_gallery.html" %} + {% include "mediagoblin/utils/object_gallery.html" %} {% endblock %} diff --git a/mediagoblin/templates/mediagoblin/submit/start.html b/mediagoblin/templates/mediagoblin/submit/start.html index 50c86afe..eb34c2e2 100644 --- a/mediagoblin/templates/mediagoblin/submit/start.html +++ b/mediagoblin/templates/mediagoblin/submit/start.html @@ -23,12 +23,13 @@ <form action="{{ request.urlgen('mediagoblin.submit.start') }}" method="POST" enctype="multipart/form-data"> <div class="grid_8 prefix_1 suffix_1 form_box"> - <h1>Submit yer media</h1> + <h1>{% trans %}Submit yer media{% endtrans %}</h1> {{ wtforms_util.render_field_div(submit_form.file) }} {{ wtforms_util.render_field_div(submit_form.title) }} {{ wtforms_util.render_textarea_div(submit_form.description) }} + {{ wtforms_util.render_field_div(submit_form.tags) }} <div class="form_submit_buttons"> - <input type="submit" value="Submit" class="button" /> + <input type="submit" value="{% trans %}Submit{% endtrans %}" class="button" /> </div> </div> </form> diff --git a/mediagoblin/templates/mediagoblin/user_pages/gallery.html b/mediagoblin/templates/mediagoblin/user_pages/gallery.html index a434ff15..a66a547e 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/gallery.html +++ b/mediagoblin/templates/mediagoblin/user_pages/gallery.html @@ -27,21 +27,27 @@ {% block mediagoblin_content -%} {% if user %} <h1> - <a href="{{ request.urlgen( - 'mediagoblin.user_pages.user_home', - user=user.username) }}">{{ user.username }}</a>'s media</h1> + {%- trans username=user.username, + user_url=request.urlgen( + 'mediagoblin.user_pages.user_home', + user=user.username) -%} + <a href="{{ user_url }}">{{ username }}</a>'s media + {%- endtrans %} + </h1> </div> <div class="container_16 media_gallery"> {% include "mediagoblin/utils/object_gallery.html" %} </div> <div class="grid_16"> - - <a href={{ request.urlgen( - 'mediagoblin.user_pages.atom_feed', - user=user.username) }}> atom feed</a> + <a href="{{ request.urlgen( + 'mediagoblin.user_pages.atom_feed', + user=user.username) }}"> + {%- trans %}atom feed{% endtrans -%} + </a> + </div> {% else %} {# This *should* not occur as the view makes sure we pass in a user. #} - <p>Sorry, no such user found.<p/> + <p>{% trans %}Sorry, no such user found.{% endtrans %}<p/> {% endif %} {% endblock %} diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html index dc0b6210..afc0d903 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media.html @@ -23,8 +23,11 @@ {% block mediagoblin_content %} {% if media %} <div class="grid_11 alpha"> - <img class="media_image" src="{{ request.app.public_store.file_url( - media.get_display_media(media.media_files)) }}" /> + <div class="media_image_container"> + <img class="media_image" + src="{{ request.app.public_store.file_url( + media.get_display_media(media.media_files)) }}" /> + </div> <h2> {{media.title}} @@ -35,24 +38,26 @@ {% endautoescape %} <p> - — uploaded on - {{ "%4d-%02d-%02d"|format(media.created.year, - media.created.month, media.created.day) }} - by - <a href="{{ request.urlgen('mediagoblin.user_pages.user_home', - user= media.uploader().username) }}"> - {{- media.uploader().username }}</a> + {% trans date="%4d-%02d-%02d"|format( + media.created.year, + media.created.month, media.created.day), + user_url=request.urlgen( + 'mediagoblin.user_pages.user_home', + user=media.uploader().username), + username=media.uploader().username -%} + — uploaded on {{ date }} by <a href="{{ user_url }}">{{ username }}</a> + {%- endtrans %} </p> <br /> - <h3>Comments</h3> + <h3>{% trans %}Comments{% endtrans %}</h3> {% if request.user %} <form action="{{ request.urlgen('mediagoblin.user_pages.media_post_comment', user= media.uploader().username, media=media._id) }}" method="POST"> {{ wtforms_util.render_field_div(comment_form.comment_content) }} <div class="form_submit_buttons"> - <input type="submit" value="Post comment!" class="button" /> + <input type="submit" value="{% trans %}Post comment!{% endtrans %}" class="button" /> </div> </form> {% endif %} @@ -74,7 +79,7 @@ <div class="comment_author">— <a href="{{ request.urlgen('mediagoblin.user_pages.user_home', user = comment_author['username']) }}"> - {{ comment_author['username'] }}</a> at + {{ comment_author['username'] }}</a> {% trans %}at{% endtrans %} <!--</div> <div class="comment_datetime">--> <a href="{{ request.urlgen('mediagoblin.user_pages.media_home.view_comment', @@ -97,12 +102,12 @@ media = media._id)) }} </div> {% endif %} + <div class="grid_5 omega"> {% include "mediagoblin/utils/prev_next.html" %} - <h3>Sidebar content here!</h3> - <p> {% if media['uploader'] == request.user['_id'] or request.user['is_admin'] %} + <h3>Temporary button holder</h3> <p> <a href="{{ request.urlgen('mediagoblin.edit.edit_media', user= media.uploader().username, @@ -112,12 +117,15 @@ </p> <p> <img src="{{ request.staticdirect('/images/icon_delete.png') }}" - class="media_icon" />delete + class="media_icon" />{% trans %}delete{% endtrans %} </p> {% endif %} - </p> + + {% if media.tags %} + {% include "mediagoblin/utils/tags.html" %} + {% endif %} </div> {% else %} - <p>Sorry, no such media found.<p/> + <p>{% trans %}Sorry, no such media found.{% endtrans %}<p/> {% endif %} {% endblock %} diff --git a/mediagoblin/templates/mediagoblin/user_pages/user.html b/mediagoblin/templates/mediagoblin/user_pages/user.html index 9d99ac53..1115fc56 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/user.html +++ b/mediagoblin/templates/mediagoblin/user_pages/user.html @@ -25,26 +25,83 @@ {% endblock mediagoblin_head %} {% block mediagoblin_content -%} - {% if user %} - <h1>{{ user.username }}'s profile</h1> - <div class="grid_6 alpha"> - {% include "mediagoblin/utils/profile.html" %} - {% if request.user['_id'] == user['_id'] or request.user['is_admin'] %} + {# If no user... #} + {% if not user %} + <p>{% trans %}Sorry, no such user found.{% endtrans %}<p/> + + {# User exists, but needs verification #} + {% elif user.status == "needs_email_verification" %} + {% if user == request.user %} + {# this should only be visible when you are this user #} + <div class="grid_6 prefix_1 suffix_1 form_box"> + <h1>{% trans %}Verification needed{% endtrans %}</h1> + + <p> + {% trans -%} + Almost done! Your account still needs to be verified. + {%- endtrans %} + </p> + <p> + {% trans -%} + An email should arrive in a few moments with instructions on how to do so. + {%- endtrans %} + </p> + <p>{% trans %}In case it doesn't:{% endtrans %}</p> + + <a href="{{ request.urlgen('mediagoblin.auth.resend_verification') }}" + class="button">{% trans %}Resend verification email{% endtrans %}</a> + </div> + {% else %} + {# if the user is not you, but still needs to verify their email #} + <div class="grid_6 prefix_1 suffix_1 form_box"> + <h1>{% trans %}Verification needed{% endtrans %}</h1> + + <p> + {% trans -%} + Someone has registered an account with this username, but it still has to be verified. + {%- endtrans %} + </p> + + <p> + {% trans login_url=request.urlgen('mediagoblin.auth.login') -%} + If you are that person but you've lost your verification email, you can <a href="{{ login_url }}">log in</a> and resend it. + {%- endtrans %} + </p> + </div> + {% endif %} + + {# Active(?) (or at least verified at some point) user, horray! #} + {% else %} + <h1> + {%- trans username=user.username %}{{ username }}'s profile{% endtrans -%} + </h1> + + <div class="grid_6 alpha"> + {% include "mediagoblin/utils/profile.html" %} + {% if request.user['_id'] == user['_id'] or request.user['is_admin'] %} <a href="{{ request.urlgen('mediagoblin.edit.profile') }}?username={{ - user.username }}">Edit profile</a> - {% endif %} - </div> - <div class="grid_10 omega"> - {% set pagination_base_url = user_gallery_url %} - {% include "mediagoblin/utils/object_gallery.html" %} - <div class="clear"></div> - <p><a href="{{ user_gallery_url }}">View all of {{ user.username }}'s media</a></p> - <a href={{ request.urlgen( - 'mediagoblin.user_pages.atom_feed', - user=user.username) }}>atom feed</a> - {% else %} - {# This *should* not occur as the view makes sure we pass in a user. #} - <p>Sorry, no such user found.<p/> + user.username }}"> + {%- trans %}Edit profile{% endtrans -%} + </a> + {% endif %} + </div> + + <div class="grid_10 omega"> + {% set pagination_base_url = user_gallery_url %} + {% include "mediagoblin/utils/object_gallery.html" %} + <div class="clear"></div> + <p> + <a href="{{ user_gallery_url }}"> + {% trans username=user.username -%} + View all of {{ username }}'s media{% endtrans -%} + </a> + </p> + <a href="{{ request.urlgen( 'mediagoblin.user_pages.atom_feed', + user=user.username) }}"> + {%- trans %}atom feed{% endtrans -%} + </a> </div> + + <div class="clear"></div> {% endif %} {% endblock %} diff --git a/mediagoblin/templates/mediagoblin/utils/object_gallery.html b/mediagoblin/templates/mediagoblin/utils/object_gallery.html index 2c7a7129..03b85b17 100644 --- a/mediagoblin/templates/mediagoblin/utils/object_gallery.html +++ b/mediagoblin/templates/mediagoblin/utils/object_gallery.html @@ -19,7 +19,7 @@ {% from "mediagoblin/utils/pagination.html" import render_pagination %} {% block object_gallery_content -%} - {% if media_entries %} + {% if media_entries and media_entries.count() %} {% for entry in media_entries %} <div class="media_thumbnail"> <a href="{{ entry.url_for_self(request.urlgen) }}"> @@ -27,11 +27,16 @@ entry['media_files']['thumb']) }}" /></a> </div> {% endfor %} + <div class="clear"></div> {% if pagination_base_url %} {# different url, so set that and don't keep the get params #} {{ render_pagination(request, pagination, pagination_base_url, False) }} {% else %} {{ render_pagination(request, pagination) }} {% endif %} + {% else %} + <p> + <i>There doesn't seem to be any media here yet...</i> + </p> {% endif %} {% endblock %} diff --git a/mediagoblin/templates/mediagoblin/auth/verification_needed.html b/mediagoblin/templates/mediagoblin/utils/tags.html index 4104da19..32db6e31 100644 --- a/mediagoblin/templates/mediagoblin/auth/verification_needed.html +++ b/mediagoblin/templates/mediagoblin/utils/tags.html @@ -15,15 +15,15 @@ # 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 mediagoblin_content %} - <p> - Verfication needed!<br /> - Please check your email to verify your account. - </p> - - <p> - Still haven't received an email? <a href="{{ request.urlgen('mediagoblin.auth.resend_verification') }}">Click here to resend it.</a> - </p> +{% block tags_content -%} + <h3>Tags</h3> + <ul class="mediaentry_tags"> + {% for tag in media.tags %} + <li class="tag"> + <a href="{{ request.urlgen( + 'mediagoblin.listings.tags_listing', + tag=tag['slug']) }}">{{ tag['name'] }}</li> + {% endfor %} + </ul> {% endblock %} diff --git a/mediagoblin/templates/mediagoblin/utils/wtforms.html b/mediagoblin/templates/mediagoblin/utils/wtforms.html index 1d2f8619..e3d8e137 100644 --- a/mediagoblin/templates/mediagoblin/utils/wtforms.html +++ b/mediagoblin/templates/mediagoblin/utils/wtforms.html @@ -19,9 +19,9 @@ {# Generically render a field #} {% macro render_field_div(field) %} <div class="form_field_box"> - <div class="form_field_label">{{ field.label }}</div> + <div class="form_field_label">{{ _(field.label.text) }}</div> {% if field.description -%} - <div class="form_field_description">{{ field.description }}</div> + <div class="form_field_description">{{ _(field.description) }}</div> {%- endif %} <div class="form_field_input">{{ field }}</div> {%- if field.errors -%} @@ -38,9 +38,9 @@ # ... mostly the same thing except it includes rows and cols #} {% macro render_textarea_div(field, rows=8, cols=20) %} <div class="form_field_box"> - <div class="form_field_label">{{ field.label }}</div> + <div class="form_field_label">{{ _(field.label.text) }}</div> {% if field.description -%} - <div class="form_field_description">{{ field.description }}</div> + <div class="form_field_description">{{ _(field.description) }}</div> {%- endif %} <div class="form_field_input">{{ field(rows=rows, cols=cols) }}</div> {%- if field.errors -%} @@ -64,7 +64,7 @@ {% macro render_table(form) -%} {% for field in form %} <tr> - <th>{{field.label}}</th> + <th>{{ _(field.label.text) }}</th> <td> {{field}} {% if field.errors %} diff --git a/mediagoblin/tests/test_auth.py b/mediagoblin/tests/test_auth.py index ad9dd35b..4781dd9b 100644 --- a/mediagoblin/tests/test_auth.py +++ b/mediagoblin/tests/test_auth.py @@ -153,9 +153,9 @@ def test_register_views(test_app): ## Did we redirect to the proper page? Use the right template? assert_equal( urlparse.urlsplit(response.location)[2], - '/auth/register/success/') + '/u/happygirl/') assert util.TEMPLATE_TEST_CONTEXT.has_key( - 'mediagoblin/auth/register_success.html') + 'mediagoblin/user_pages/user.html') ## Make sure user is in place new_user = mg_globals.database.User.find_one( @@ -164,6 +164,11 @@ def test_register_views(test_app): assert new_user['status'] == u'needs_email_verification' assert new_user['email_verified'] == False + ## Make sure user is logged in + request = util.TEMPLATE_TEST_CONTEXT[ + 'mediagoblin/user_pages/user.html']['request'] + assert request.session['user_id'] == unicode(new_user['_id']) + ## Make sure we get email confirmation, and try verifying assert len(util.EMAIL_TEST_INBOX) == 1 message = util.EMAIL_TEST_INBOX.pop() @@ -185,12 +190,14 @@ def test_register_views(test_app): ## Try verifying with bs verification key, shouldn't work util.clear_test_template_context() - test_app.get( + response = test_app.get( "/auth/verify_email/?userid=%s&token=total_bs" % unicode( new_user['_id'])) + response.follow() context = util.TEMPLATE_TEST_CONTEXT[ 'mediagoblin/user_pages/user.html'] - assert context['verification_successful'] == False + # assert context['verification_successful'] == True + # TODO: Would be good to test messages here when we can do so... new_user = mg_globals.database.User.find_one( {'username': 'happygirl'}) assert new_user @@ -199,10 +206,12 @@ def test_register_views(test_app): ## Verify the email activation works util.clear_test_template_context() - test_app.get("%s?%s" % (path, get_params)) + response = test_app.get("%s?%s" % (path, get_params)) + response.follow() context = util.TEMPLATE_TEST_CONTEXT[ 'mediagoblin/user_pages/user.html'] - assert context['verification_successful'] == True + # assert context['verification_successful'] == True + # TODO: Would be good to test messages here when we can do so... new_user = mg_globals.database.User.find_one( {'username': 'happygirl'}) assert new_user diff --git a/mediagoblin/tests/test_mgoblin_app.ini b/mediagoblin/tests/test_mgoblin_app.ini index fd0f87a4..7716e9ca 100644 --- a/mediagoblin/tests/test_mgoblin_app.ini +++ b/mediagoblin/tests/test_mgoblin_app.ini @@ -7,6 +7,10 @@ email_sender_address = "notice@mediagoblin.example.org" email_debug_mode = true db_name = __mediagoblin_tests__ +# tag parsing +tags_delimiter = "," +tags_max_length = 50 + # Celery shouldn't be set up by the application as it's setup via # mediagoblin.init.celery.from_celery celery_setup_elsewhere = true diff --git a/mediagoblin/tests/test_submission.py b/mediagoblin/tests/test_submission.py index 22b6117c..a7248255 100644 --- a/mediagoblin/tests/test_submission.py +++ b/mediagoblin/tests/test_submission.py @@ -35,6 +35,9 @@ EVIL_JPG = pkg_resources.resource_filename( EVIL_PNG = pkg_resources.resource_filename( 'mediagoblin.tests', 'test_submission/evil.png') +GOOD_TAG_STRING = 'yin,yang' +BAD_TAG_STRING = 'rage,' + 'f' * 26 + 'u' * 26 + class TestSubmission: def setUp(self): @@ -110,6 +113,42 @@ class TestSubmission: assert util.TEMPLATE_TEST_CONTEXT.has_key( 'mediagoblin/user_pages/user.html') + def test_tags(self): + # Good tag string + # -------- + util.clear_test_template_context() + response = self.test_app.post( + '/submit/', { + 'title': 'Balanced Goblin', + 'tags': GOOD_TAG_STRING + }, upload_files=[( + 'file', GOOD_JPG)]) + + # New media entry with correct tags should be created + response.follow() + context = util.TEMPLATE_TEST_CONTEXT['mediagoblin/user_pages/user.html'] + request = context['request'] + media = request.db.MediaEntry.find({'title': 'Balanced Goblin'})[0] + assert_equal(media['tags'], + [{'name': u'yin', 'slug': u'yin'}, + {'name': u'yang', 'slug': u'yang'}]) + + # Test tags that are too long + # --------------- + util.clear_test_template_context() + response = self.test_app.post( + '/submit/', { + 'title': 'Balanced Goblin', + 'tags': BAD_TAG_STRING + }, upload_files=[( + 'file', GOOD_JPG)]) + + # Too long error should be raised + context = util.TEMPLATE_TEST_CONTEXT['mediagoblin/submit/start.html'] + form = context['submit_form'] + assert form.tags.errors == [ + u'Tags must be shorter than 50 characters. Tags that are too long'\ + ': ffffffffffffffffffffffffffuuuuuuuuuuuuuuuuuuuuuuuuuu'] def test_malicious_uploads(self): # Test non-suppoerted file with non-supported extension diff --git a/mediagoblin/tests/test_tags.py b/mediagoblin/tests/test_tags.py new file mode 100644 index 00000000..c2e9fa2b --- /dev/null +++ b/mediagoblin/tests/test_tags.py @@ -0,0 +1,50 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 Free Software Foundation, Inc +# +# 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.tests.tools import setup_fresh_app +from mediagoblin import util +from mediagoblin import mg_globals + + +@setup_fresh_app +def test_list_of_dicts_conversion(test_app): + """ + When the user adds tags to a media entry, the string from the form is + converted into a list of tags, where each tag is stored in the database + as a dict. Each tag dict should contain the tag's name and slug. Another + function performs the reverse operation when populating a form to edit tags. + """ + # Leading, trailing, and internal whitespace should be removed and slugified + assert util.convert_to_tag_list_of_dicts('sleep , 6 AM, chainsaw! ') == [ + {'name': u'sleep', 'slug': u'sleep'}, + {'name': u'6 AM', 'slug': u'6-am'}, + {'name': u'chainsaw!', 'slug': u'chainsaw'}] + + # If the user enters two identical tags, record only one of them + assert util.convert_to_tag_list_of_dicts('echo,echo') == [{'name': u'echo', + 'slug': u'echo'}] + + # Make sure converting the list of dicts to a string works + assert util.media_tags_as_string([{'name': u'yin', 'slug': u'yin'}, + {'name': u'yang', 'slug': u'yang'}]) == \ + u'yin,yang' + + # If the tag delimiter is a space then we expect different results + mg_globals.app_config['tags_delimiter'] = u' ' + assert util.convert_to_tag_list_of_dicts('unicorn ceramic nazi') == [ + {'name': u'unicorn', 'slug': u'unicorn'}, + {'name': u'ceramic', 'slug': u'ceramic'}, + {'name': u'nazi', 'slug': u'nazi'}] diff --git a/mediagoblin/tests/tools.py b/mediagoblin/tests/tools.py index 4b61f259..ab14c21e 100644 --- a/mediagoblin/tests/tools.py +++ b/mediagoblin/tests/tools.py @@ -58,6 +58,9 @@ def suicide_if_bad_celery_environ(): def get_test_app(dump_old_app=True): suicide_if_bad_celery_environ() + # Make sure we've turned on testing + util._activate_testing() + # Leave this imported as it sets up celery. from mediagoblin.init.celery import from_tests diff --git a/mediagoblin/translations/en/LC_MESSAGES/mediagoblin.mo b/mediagoblin/translations/en/LC_MESSAGES/mediagoblin.mo Binary files differdeleted file mode 100644 index fb7046cd..00000000 --- a/mediagoblin/translations/en/LC_MESSAGES/mediagoblin.mo +++ /dev/null diff --git a/mediagoblin/translations/en/LC_MESSAGES/mediagoblin.po b/mediagoblin/translations/en/LC_MESSAGES/mediagoblin.po deleted file mode 100644 index 3bec204e..00000000 --- a/mediagoblin/translations/en/LC_MESSAGES/mediagoblin.po +++ /dev/null @@ -1,23 +0,0 @@ -# Translations template for PROJECT. -# Copyright (C) 2011 ORGANIZATION -# This file is distributed under the same license as the PROJECT project. -# FIRST AUTHOR <EMAIL@ADDRESS>, 2011. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PROJECT VERSION\n" -"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2011-05-12 22:28-0500\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" -"Language-Team: LANGUAGE <LL@li.org>\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.6\n" - -#: mediagoblin/templates/mediagoblin/root.html:22 -msgid "Welcome to GNU MediaGoblin!" -msgstr "" - diff --git a/mediagoblin/user_pages/__init__.py b/mediagoblin/user_pages/__init__.py index e69de29b..a8eeb5ed 100644 --- a/mediagoblin/user_pages/__init__.py +++ b/mediagoblin/user_pages/__init__.py @@ -0,0 +1,17 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 Free Software Foundation, Inc +# +# 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/>. + + diff --git a/mediagoblin/user_pages/forms.py b/mediagoblin/user_pages/forms.py index 8829b674..25001019 100644 --- a/mediagoblin/user_pages/forms.py +++ b/mediagoblin/user_pages/forms.py @@ -16,7 +16,10 @@ import wtforms +from mediagoblin.util import fake_ugettext_passthrough as _ + + class MediaCommentForm(wtforms.Form): - comment_content = wtforms.TextAreaField( - 'Comment', - [wtforms.validators.Required()]) + comment_content = wtforms.TextAreaField( + _('Comment'), + [wtforms.validators.Required()]) diff --git a/mediagoblin/user_pages/views.py b/mediagoblin/user_pages/views.py index a3172ebd..fb72a421 100644 --- a/mediagoblin/user_pages/views.py +++ b/mediagoblin/user_pages/views.py @@ -22,8 +22,8 @@ from mediagoblin.util import ( Pagination, render_to_response, redirect, cleaned_markdown_conversion) from mediagoblin.user_pages import forms as user_forms -from mediagoblin.decorators import uses_pagination, get_user_media_entry, \ - require_active_login +from mediagoblin.decorators import (uses_pagination, get_user_media_entry, + require_active_login) from werkzeug.contrib.atom import AtomFeed @@ -32,10 +32,14 @@ from werkzeug.contrib.atom import AtomFeed def user_home(request, page): """'Homepage' of a User()""" user = request.db.User.find_one({ - 'username': request.matchdict['user'], - 'status': 'active'}) + 'username': request.matchdict['user']}) if not user: return exc.HTTPNotFound() + elif user['status'] != u'active': + return render_to_response( + request, + 'mediagoblin/user_pages/user.html', + {'user': user}) cursor = request.db.MediaEntry.find( {'uploader': user['_id'], @@ -139,7 +143,7 @@ def media_post_comment(request): user = request.matchdict['user']) -ATOM_DEFAULT_NR_OF_UPDATED_ITEMS = 5 +ATOM_DEFAULT_NR_OF_UPDATED_ITEMS = 15 def atom_feed(request): """ @@ -150,7 +154,7 @@ def atom_feed(request): 'username': request.matchdict['user'], 'status': 'active'}) if not user: - return exc.HTTPNotFound() + return exc.HTTPNotFound() cursor = request.db.MediaEntry.find({ 'uploader': user['_id'], diff --git a/mediagoblin/util.py b/mediagoblin/util.py index 1892378c..b46c65d9 100644 --- a/mediagoblin/util.py +++ b/mediagoblin/util.py @@ -25,13 +25,16 @@ import re import urllib from math import ceil, floor import copy +import wtforms from babel.localedata import exists +from babel.support import LazyProxy import jinja2 import translitcodec from webob import Response, exc from lxml.html.clean import Cleaner import markdown +from wtforms.form import Form from mediagoblin import mg_globals from mediagoblin import messages @@ -92,8 +95,8 @@ def get_jinja_env(template_loader, locale): extensions=['jinja2.ext.i18n', 'jinja2.ext.autoescape']) template_env.install_gettext_callables( - mg_globals.translations.gettext, - mg_globals.translations.ngettext) + mg_globals.translations.ugettext, + mg_globals.translations.ungettext) # All templates will know how to ... # ... fetch all waiting messages and remove them from the queue @@ -299,7 +302,7 @@ def send_email(from_addr, to_addrs, subject, message_body): TRANSLATIONS_PATH = pkg_resources.resource_filename( - 'mediagoblin', 'translations') + 'mediagoblin', 'i18n') def locale_to_lower_upper(locale): @@ -384,9 +387,63 @@ def clean_html(html): return HTML_CLEANER.clean_html(html) -MARKDOWN_INSTANCE = markdown.Markdown(safe_mode='escape') +def convert_to_tag_list_of_dicts(tag_string): + """ + Filter input from incoming string containing user tags, + + Strips trailing, leading, and internal whitespace, and also converts + the "tags" text into an array of tags + """ + taglist = [] + if tag_string: + + # Strip out internal, trailing, and leading whitespace + stripped_tag_string = u' '.join(tag_string.strip().split()) + + # Split the tag string into a list of tags + for tag in stripped_tag_string.split( + mg_globals.app_config['tags_delimiter']): + + # Ignore empty or duplicate tags + if tag.strip() and tag.strip() not in [t['name'] for t in taglist]: + + taglist.append({'name': tag.strip(), + 'slug': slugify(tag.strip())}) + return taglist + + +def media_tags_as_string(media_entry_tags): + """ + Generate a string from a media item's tags, stored as a list of dicts + + This is the opposite of convert_to_tag_list_of_dicts + """ + media_tag_string = '' + if media_entry_tags: + media_tag_string = mg_globals.app_config['tags_delimiter'].join( + [tag['name'] for tag in media_entry_tags]) + return media_tag_string + +TOO_LONG_TAG_WARNING = \ + u'Tags must be shorter than %s characters. Tags that are too long: %s' + +def tag_length_validator(form, field): + """ + Make sure tags do not exceed the maximum tag length. + """ + tags = convert_to_tag_list_of_dicts(field.data) + too_long_tags = [ + tag['name'] for tag in tags + if len(tag['name']) > mg_globals.app_config['tags_max_length']] + + if too_long_tags: + raise wtforms.ValidationError( + TOO_LONG_TAG_WARNING % (mg_globals.app_config['tags_max_length'], \ + ', '.join(too_long_tags))) +MARKDOWN_INSTANCE = markdown.Markdown(safe_mode='escape') + def cleaned_markdown_conversion(text): """ Take a block of text, run it through MarkDown, and clean its HTML. @@ -423,6 +480,66 @@ def setup_gettext(locale): translations=this_gettext) +# Force en to be setup before anything else so that +# mg_globals.translations is never None +setup_gettext('en') + + +def pass_to_ugettext(*args, **kwargs): + """ + Pass a translation on to the appropriate ugettext method. + + The reason we can't have a global ugettext method is because + mg_globals gets swapped out by the application per-request. + """ + return mg_globals.translations.ugettext( + *args, **kwargs) + + +def lazy_pass_to_ugettext(*args, **kwargs): + """ + Lazily pass to ugettext. + + This is useful if you have to define a translation on a module + level but you need it to not translate until the time that it's + used as a string. + """ + return LazyProxy(pass_to_ugettext, *args, **kwargs) + + +def pass_to_ngettext(*args, **kwargs): + """ + Pass a translation on to the appropriate ngettext method. + + The reason we can't have a global ngettext method is because + mg_globals gets swapped out by the application per-request. + """ + return mg_globals.translations.ngettext( + *args, **kwargs) + + +def lazy_pass_to_ngettext(*args, **kwargs): + """ + Lazily pass to ngettext. + + This is useful if you have to define a translation on a module + level but you need it to not translate until the time that it's + used as a string. + """ + return LazyProxy(pass_to_ngettext, *args, **kwargs) + + +def fake_ugettext_passthrough(string): + """ + Fake a ugettext call for extraction's sake ;) + + In wtforms there's a separate way to define a method to translate + things... so we just need to mark up the text so that it can be + extracted, not so that it's actually run through gettext. + """ + return string + + PAGINATION_DEFAULT_PER_PAGE = 30 class Pagination(object): diff --git a/mediagoblin/views.py b/mediagoblin/views.py index e7d9dbdd..ccd7a2df 100644 --- a/mediagoblin/views.py +++ b/mediagoblin/views.py @@ -15,17 +15,23 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. from mediagoblin import mg_globals -from mediagoblin.util import render_to_response +from mediagoblin.util import render_to_response, Pagination from mediagoblin.db.util import DESCENDING +from mediagoblin.decorators import uses_pagination -def root_view(request): - media_entries = request.db.MediaEntry.find( +@uses_pagination +def root_view(request, page): + cursor = request.db.MediaEntry.find( {u'state': u'processed'}).sort('created', DESCENDING) - + + pagination = Pagination(page, cursor) + media_entries = pagination() + return render_to_response( request, 'mediagoblin/root.html', {'media_entries': media_entries, - 'allow_registration': mg_globals.app_config["allow_registration"]}) + 'allow_registration': mg_globals.app_config["allow_registration"], + 'pagination': pagination}) def simple_template_render(request): |