diff options
67 files changed, 4473 insertions, 387 deletions
diff --git a/mediagoblin/app.py b/mediagoblin/app.py index c1ee3d77..3030929d 100644 --- a/mediagoblin/app.py +++ b/mediagoblin/app.py @@ -101,6 +101,23 @@ class MediaGoblinApp(object): ## Routing / controller loading stuff route_match = self.routing.match(path_info) + ## Attach utilities to the request object + request.matchdict = route_match + request.urlgen = routes.URLGenerator(self.routing, environ) + # Do we really want to load this via middleware? Maybe? + request.session = request.environ['beaker.session'] + # Attach self as request.app + # Also attach a few utilities from request.app for convenience? + request.app = self + request.locale = util.get_locale_from_request(request) + + request.template_env = util.get_jinja_env( + self.template_loader, request.locale) + request.db = self.db + request.staticdirect = self.staticdirector + + util.setup_user_in_request(request) + # No matching page? if route_match is None: # Try to do see if we have a match with a trailing slash @@ -116,28 +133,12 @@ class MediaGoblinApp(object): return request.get_response(redirect)(environ, start_response) # Okay, no matches. 404 time! - return exc.HTTPNotFound()(environ, start_response) + request.matchdict = {} # in case our template expects it + return util.render_404(request)(environ, start_response) controller = util.import_component(route_match['controller']) request.start_response = start_response - ## Attach utilities to the request object - request.matchdict = route_match - request.urlgen = routes.URLGenerator(self.routing, environ) - # Do we really want to load this via middleware? Maybe? - request.session = request.environ['beaker.session'] - # Attach self as request.app - # Also attach a few utilities from request.app for convenience? - request.app = self - request.locale = util.get_locale_from_request(request) - - request.template_env = util.get_jinja_env( - self.template_loader, request.locale) - request.db = self.db - request.staticdirect = self.staticdirector - - util.setup_user_in_request(request) - return controller(request)(environ, start_response) diff --git a/mediagoblin/auth/forms.py b/mediagoblin/auth/forms.py index 1b6bc7c2..917909c5 100644 --- a/mediagoblin/auth/forms.py +++ b/mediagoblin/auth/forms.py @@ -16,7 +16,7 @@ import wtforms -from mediagoblin.util import pass_to_ugettext as _ +from mediagoblin.util import fake_ugettext_passthrough as _ class RegistrationForm(wtforms.Form): diff --git a/mediagoblin/auth/views.py b/mediagoblin/auth/views.py index 121a8c8e..4c4a34fd 100644 --- a/mediagoblin/auth/views.py +++ b/mediagoblin/auth/views.py @@ -20,7 +20,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 render_to_response, redirect, render_404 from mediagoblin.util import pass_to_ugettext as _ from mediagoblin.db.util import ObjectId from mediagoblin.auth import lib as auth_lib @@ -45,20 +45,27 @@ def register(request): if request.method == 'POST' and register_form.validate(): # TODO: Make sure the user doesn't exist already - users_with_username = \ - request.db.User.find({ - 'username': request.POST['username'].lower() - }).count() + users_with_username = request.db.User.find( + {'username': request.POST['username'].lower()}).count() + users_with_email = request.db.User.find( + {'email': request.POST['email'].lower()}).count() + + extra_validation_passes = True if users_with_username: register_form.username.errors.append( _(u'Sorry, a user with that name already exists.')) + extra_validation_passes = False + if users_with_email: + register_form.email.errors.append( + _(u'Sorry, that email address has already been taken.')) + extra_validation_passes = False - else: + if extra_validation_passes: # Create the user user = request.db.User() user['username'] = request.POST['username'].lower() - user['email'] = request.POST['email'] + user['email'] = request.POST['email'].lower() user['pw_hash'] = auth_lib.bcrypt_gen_password_hash( request.POST['password']) user.save(validate=True) @@ -137,7 +144,7 @@ def verify_email(request): """ # If we don't have userid and token parameters, we can't do anything; 404 if not request.GET.has_key('userid') or not request.GET.has_key('token'): - return exc.HTTPNotFound() + return render_404(request) user = request.db.User.find_one( {'_id': ObjectId(unicode(request.GET['userid']))}) @@ -159,7 +166,7 @@ def verify_email(request): return redirect( request, 'mediagoblin.user_pages.user_home', - user=request.user['username']) + user=user['username']) def resend_activation(request): diff --git a/mediagoblin/db/migrations.py b/mediagoblin/db/migrations.py index 6a8ebcf9..5456b248 100644 --- a/mediagoblin/db/migrations.py +++ b/mediagoblin/db/migrations.py @@ -52,3 +52,43 @@ def mediaentry_mediafiles_main_to_original(database): document['media_files']['original'] = original collection.save(document) + + +@RegisterMigration(3) +def mediaentry_remove_thumbnail_file(database): + """ + Use media_files['thumb'] instead of media_entries['thumbnail_file'] + """ + database['media_entries'].update( + {'thumbnail_file': {'$exists': True}}, + {'$unset': {'thumbnail_file': 1}}, + multi=True) + + +@RegisterMigration(4) +def mediaentry_add_queued_task_id(database): + """ + Add the 'queued_task_id' field for entries that don't have it. + """ + collection = database['media_entries'] + collection.update( + {'queued_task_id': {'$exists': False}}, + {'$set': {'queued_task_id': None}}, + multi=True) + + +@RegisterMigration(5) +def mediaentry_add_fail_error_and_metadata(database): + """ + Add 'fail_error' and 'fail_metadata' fields to media entries + """ + collection = database['media_entries'] + collection.update( + {'fail_error': {'$exists': False}}, + {'$set': {'fail_error': None}}, + multi=True) + + collection.update( + {'fail_metadata': {'$exists': False}}, + {'$set': {'fail_metadata': {}}}, + multi=True) diff --git a/mediagoblin/db/models.py b/mediagoblin/db/models.py index 4ef2d928..b6e52441 100644 --- a/mediagoblin/db/models.py +++ b/mediagoblin/db/models.py @@ -162,6 +162,8 @@ class MediaEntry(Document): queued for processing. This is stored in the mg_globals.queue_store storage system. + - queued_task_id: celery task id. Use this to fetch the task state. + - media_files: Files relevant to this that have actually been processed and are available for various types of display. Stored like: {'thumb': ['dir1', 'dir2', 'pic.png'} @@ -170,7 +172,8 @@ class MediaEntry(Document): critical to this piece of media but may be usefully relevant to people viewing the work. (currently unused.) - - thumbnail_file: Deprecated... we should remove this ;) + - fail_error: path to the exception raised + - fail_metadata: """ __collection__ = 'media_entries' @@ -190,6 +193,7 @@ class MediaEntry(Document): # For now let's assume there can only be one main file queued # at a time 'queued_media_file': [unicode], + 'queued_task_id': unicode, # A dictionary of logical names to filepaths 'media_files': dict, @@ -198,8 +202,10 @@ class MediaEntry(Document): # record form 'attachment_files': list, - # This one should just be a single file record - 'thumbnail_file': [unicode]} + # If things go badly in processing things, we'll store that + # data here + 'fail_error': unicode, + 'fail_metadata': dict} required_fields = [ 'uploader', 'created', 'media_type', 'slug'] @@ -291,6 +297,13 @@ class MediaEntry(Document): def uploader(self): return self.db.User.find_one({'_id': self['uploader']}) + def get_fail_exception(self): + """ + Get the exception that's appropriate for this error + """ + if self['fail_error']: + return util.import_component(self['fail_error']) + class MediaComment(Document): """ diff --git a/mediagoblin/decorators.py b/mediagoblin/decorators.py index 2e90274e..c66049ca 100644 --- a/mediagoblin/decorators.py +++ b/mediagoblin/decorators.py @@ -17,7 +17,7 @@ from webob import exc -from mediagoblin.util import redirect +from mediagoblin.util import redirect, render_404 from mediagoblin.db.util import ObjectId, InvalidId @@ -60,9 +60,9 @@ def uses_pagination(controller): try: page = int(request.GET.get('page', 1)) if page < 0: - return exc.HTTPNotFound() + return render_404(request) except ValueError: - return exc.HTTPNotFound() + return render_404(request) return controller(request, page=page, *args, **kwargs) @@ -78,7 +78,7 @@ def get_user_media_entry(controller): {'username': request.matchdict['user']}) if not user: - return exc.HTTPNotFound() + return render_404(request) media = request.db.MediaEntry.find_one( {'slug': request.matchdict['media'], @@ -93,11 +93,11 @@ def get_user_media_entry(controller): 'state': 'processed', 'uploader': user['_id']}) except InvalidId: - return exc.HTTPNotFound() + return render_404(request) # Still no media? Okay, 404. if not media: - return exc.HTTPNotFound() + return render_404(request) return controller(request, media=media, *args, **kwargs) @@ -113,11 +113,11 @@ def get_media_entry_by_id(controller): {'_id': ObjectId(request.matchdict['media']), 'state': 'processed'}) except InvalidId: - return exc.HTTPNotFound() + return render_404(request) # Still no media? Okay, 404. if not media: - return exc.HTTPNotFound() + return render_404(request) return controller(request, media=media, *args, **kwargs) diff --git a/mediagoblin/edit/forms.py b/mediagoblin/edit/forms.py index 8052f482..2f3ed203 100644 --- a/mediagoblin/edit/forms.py +++ b/mediagoblin/edit/forms.py @@ -18,7 +18,7 @@ import wtforms from mediagoblin.util import tag_length_validator, TOO_LONG_TAG_WARNING -from mediagoblin.util import pass_to_ugettext as _ +from mediagoblin.util import fake_ugettext_passthrough as _ class EditForm(wtforms.Form): diff --git a/mediagoblin/errormiddleware.py b/mediagoblin/errormiddleware.py new file mode 100644 index 00000000..352dc891 --- /dev/null +++ b/mediagoblin/errormiddleware.py @@ -0,0 +1,60 @@ +# 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 paste.exceptions.errormiddleware import make_error_middleware + +MGOBLIN_ERROR_MESSAGE = """\ +<div style="text-align:center;font-family: monospace"> + <h1>YEOWCH... that's an error!</h1> + <pre> +.-------------------------. +| __ _ | +| -, \_,------,_// | +| <\ ,-- --.\ | +| / (x ) ( X ) | +| ' '--, ,--'\ | +| / \ -v-v-u-v / | +| . '.__.--__'.\ | +| / ',___/ / \__/' | +| | | ,'\_'/, || | +| \_| | | | | || | +| W',_ ||| |||_'' | +| | '------'| | +| |__| |_|_ | +| ,,,-' '-,,, | +'-------------------------' + </pre> + <p>Something bad happened, and things broke.</p> + <p>If this is not your website, you may want to alert the owner.</p> + <br><br> + <p> + Powered... er broken... by + <a href="http://www.mediagoblin.org">MediaGoblin</a>, + a <a href="http://www.gnu.org">GNU Project</a>. + </p> +</div>""" + + +def mgoblin_error_middleware(app, global_conf, **kw): + """ + MediaGoblin wrapped error middleware. + + This is really just wrapping the error middleware from Paste. + It should take all of Paste's default options, so see: + http://pythonpaste.org/modules/exceptions.html + """ + kw['error_message'] = MGOBLIN_ERROR_MESSAGE + return make_error_middleware(app, global_conf, **kw) diff --git a/mediagoblin/gmg_commands/__init__.py b/mediagoblin/gmg_commands/__init__.py index 921f0430..8226fd0e 100644 --- a/mediagoblin/gmg_commands/__init__.py +++ b/mediagoblin/gmg_commands/__init__.py @@ -44,6 +44,14 @@ SUBCOMMAND_MAP = { 'setup': 'mediagoblin.gmg_commands.wipealldata:wipe_parser_setup', 'func': 'mediagoblin.gmg_commands.wipealldata:wipe', 'help': 'Wipes **all** the data for this MediaGoblin instance'}, + 'env_export': { + 'setup': 'mediagoblin.gmg_commands.import_export:import_export_parse_setup', + 'func': 'mediagoblin.gmg_commands.import_export:env_export', + 'help': 'Exports the data for this MediaGoblin instance'}, + 'env_import': { + 'setup': 'mediagoblin.gmg_commands.import_export:import_export_parse_setup', + 'func': 'mediagoblin.gmg_commands.import_export:env_import', + 'help': 'Exports the data for this MediaGoblin instance'}, } diff --git a/mediagoblin/gmg_commands/import_export.py b/mediagoblin/gmg_commands/import_export.py new file mode 100644 index 00000000..367924a5 --- /dev/null +++ b/mediagoblin/gmg_commands/import_export.py @@ -0,0 +1,250 @@ +# 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 import mg_globals +from mediagoblin.db.open import setup_connection_and_db_from_config +from mediagoblin.init.config import read_mediagoblin_config +from mediagoblin.storage import BasicFileStorage +from mediagoblin.init import setup_storage, setup_global_and_app_config + +import shutil +import tarfile +import tempfile +import subprocess +import os.path +import os +import sys +from contextlib import closing + + +def import_export_parse_setup(subparser): + # TODO: Add default + subparser.add_argument( + 'tar_file') + subparser.add_argument( + '-cf', '--conf_file', default='mediagoblin.ini', + help='Config file used to set up environment') + subparser.add_argument( + '--mongodump_path', default='mongodump', + help='mongodump binary') + subparser.add_argument( + '--mongorestore_path', default='mongorestore', + help='mongorestore binary') + subparser.add_argument( + '--cache_path', + help='Temporary directory where files will be temporarily dumped') + + +def _import_media(db, args): + """ + Import media files + + Must be called after _import_database() + """ + print "\n== Importing media ==\n" + + media_cache = BasicFileStorage( + args._cache_path['media']) + + # TODO: Add import of queue files + queue_cache = BasicFileStorage( + args._cache_path['queue']) + + for entry in db.media_entries.find(): + for name, path in entry['media_files'].items(): + media_file = mg_globals.public_store.get_file(path, mode='wb') + media_file.write( + media_cache.get_file(path, mode='rb').read()) + + print "\n== Media imported ==\n" + + +def _import_database(db, args): + """ + Restore mongo database from ___.bson files + """ + print "\n== Importing database ==\n" + + p = subprocess.Popen([ + args.mongorestore_path, + '-d', db.name, + os.path.join(args._cache_path['database'], db.name)]) + + p.wait() + + print "\n== Database imported ==\n" + + +def env_import(args): + """ + Restore mongo database and media files from a tar archive + """ + if not args.cache_path: + args.cache_path = tempfile.mkdtemp() + + setup_global_and_app_config(args.conf_file) + + # Creates mg_globals.public_store and mg_globals.queue_store + setup_storage() + + config, validation_result = read_mediagoblin_config(args.conf_file) + connection, db = setup_connection_and_db_from_config( + config['mediagoblin'], use_pymongo=True) + + tf = tarfile.open( + args.tar_file, + mode='r|gz') + + tf.extractall(args.cache_path) + + args.cache_path = os.path.join( + args.cache_path, 'mediagoblin-data') + args = _setup_paths(args) + + # Import database from extracted data + _import_database(db, args) + + _import_media(db, args) + + _clean(args) + + +def _setup_paths(args): + """ + Populate ``args`` variable with cache subpaths + """ + args._cache_path = dict() + PATH_MAP = { + 'media': 'media', + 'queue': 'queue', + 'database': 'database'} + + for key, val in PATH_MAP.items(): + args._cache_path[key] = os.path.join(args.cache_path, val) + + return args + + +def _create_archive(args): + """ + Create the tar archive + """ + print "\n== Compressing to archive ==\n" + + tf = tarfile.open( + args.tar_file, + mode='w|gz') + + with closing(tf): + tf.add(args.cache_path, 'mediagoblin-data/') + + print "\n== Archiving done ==\n" + + +def _clean(args): + """ + Remove cache directory + """ + shutil.rmtree(args.cache_path) + + +def _export_check(args): + """ + Run security checks for export command + """ + if os.path.exists(args.tar_file): + overwrite = raw_input( + 'The output file already exists. ' + 'Are you **SURE** you want to overwrite it? ' + '(yes/no)> ') + if not overwrite == 'yes': + print "Aborting." + + return False + + return True + + +def _export_database(db, args): + print "\n== Exporting database ==\n" + + command = '{mongodump_path} -d {database} -o {mongodump_cache}'.format( + mongodump_path=args.mongodump_path, + database=db.name, + mongodump_cache=args._cache_path['database']) + + p = subprocess.Popen([ + args.mongodump_path, + '-d', db.name, + '-o', args._cache_path['database']]) + + p.wait() + + print "\n== Database exported ==\n" + + +def _export_media(db, args): + print "\n== Exporting media ==\n" + + media_cache = BasicFileStorage( + args._cache_path['media']) + + # TODO: Add export of queue files + queue_cache = BasicFileStorage( + args._cache_path['queue']) + + for entry in db.media_entries.find(): + for name, path in entry['media_files'].items(): + mc_file = media_cache.get_file(path, mode='wb') + mc_file.write( + mg_globals.public_store.get_file(path, mode='rb').read()) + + print "\n== Media exported ==\n" + + +def env_export(args): + """ + Export database and media files to a tar archive + """ + if args.cache_path: + if os.path.exists(args.cache_path): + print 'The cache directory must not exist before you run this script' + print 'Cache directory: ', args.cache_path + + return False + else: + args.cache_path = tempfile.mkdtemp() + + args = _setup_paths(args) + + if not _export_check(args): + print "\n== Checks did not pass, exiting ==\n" + sys.exit(0) + + setup_global_and_app_config(args.conf_file) + setup_storage() + + config, validation_result = read_mediagoblin_config(args.conf_file) + connection, db = setup_connection_and_db_from_config( + config['mediagoblin'], use_pymongo=True) + + _export_database(db, args) + + _export_media(db, args) + + _create_archive(args) + + _clean(args) diff --git a/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.mo Binary files differindex c403e3cc..6bb69ce9 100644 --- a/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.mo +++ 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 index 0303ec12..30c55e21 100644 --- a/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.po @@ -2,14 +2,17 @@ # 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 10:20-0500\n" -"PO-Revision-Date: 2011-08-08 15:22+0000\n" -"Last-Translator: cwebber <cwebber@dustycloud.org>\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" @@ -18,31 +21,134 @@ msgstr "" "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 "" +msgstr "GNU MediaGoblin" #: mediagoblin/templates/mediagoblin/base.html:45 msgid "Mediagoblin logo" -msgstr "" +msgstr "Mediagoblin-Logo" #: mediagoblin/templates/mediagoblin/base.html:51 msgid "Submit media" -msgstr "" +msgstr "Medien hochladen" #: mediagoblin/templates/mediagoblin/base.html:62 msgid "verify your email!" -msgstr "" +msgstr "Bitte bestätige deine Email-Adresse!" #: mediagoblin/templates/mediagoblin/base.html:72 msgid "Login" -msgstr "" +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!" @@ -50,12 +156,14 @@ msgstr "Willkommen bei GNU MediaGoblin!" #: mediagoblin/templates/mediagoblin/root.html:26 msgid "Submit an item" -msgstr "" +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 @@ -63,37 +171,35 @@ 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 "" +msgstr "Anmelden" #: mediagoblin/templates/mediagoblin/auth/login.html:29 msgid "Login failed!" -msgstr "" +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 "" +msgstr "Bestätigen" #: mediagoblin/templates/mediagoblin/auth/login.html:42 msgid "Don't have an account yet?" -msgstr "" +msgstr "Hast du noch kein Konto?" #: mediagoblin/templates/mediagoblin/auth/login.html:45 msgid "Create one here!" -msgstr "" +msgstr "Registriere dich!" #: mediagoblin/templates/mediagoblin/auth/register.html:27 msgid "Create an account!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/auth/resent_verification_email.html:22 -msgid "Resent your verification email." -msgstr "" +msgstr "Neues Konto registrieren!" #: mediagoblin/templates/mediagoblin/auth/verification_email.txt:19 #, python-format @@ -105,76 +211,85 @@ msgid "" "\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 "" +msgstr "%(media_title)s bearbeiten" #: mediagoblin/templates/mediagoblin/edit/edit.html:36 msgid "Cancel" -msgstr "" +msgstr "Abbrechen" #: mediagoblin/templates/mediagoblin/edit/edit.html:37 msgid "Save changes" -msgstr "" +msgstr "Änderungen speichern" #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29 #, python-format msgid "Editing %(username)s's profile" -msgstr "" +msgstr "%(username)s’s Profil barbeiten" #: mediagoblin/templates/mediagoblin/listings/tag.html:29 msgid "Media tagged with:" -msgstr "" +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 "" +msgstr "Atom-Feed" #: mediagoblin/templates/mediagoblin/submit/start.html:26 msgid "Submit yer media" -msgstr "" +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 "" +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 "" +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 "" +msgstr "Überprüfung notwendig" #: mediagoblin/templates/mediagoblin/user_pages/user.html:40 msgid "Almost done! Your account still needs to be verified." -msgstr "" +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 "" +msgstr "Wenn sie nicht ankommt:" #: mediagoblin/templates/mediagoblin/user_pages/user.html:52 msgid "Resend verification email" -msgstr "" +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 @@ -182,19 +297,21 @@ 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 "" +msgstr "%(username)s’s Profil" #: mediagoblin/templates/mediagoblin/user_pages/user.html:84 msgid "Edit profile" -msgstr "" +msgstr "Profil bearbeiten" #: mediagoblin/templates/mediagoblin/user_pages/user.html:95 #, python-format msgid "View all of %(username)s's media" -msgstr "" +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 index 0de5ca62..9c46ebe8 100644 --- a/mediagoblin/i18n/en/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/en/LC_MESSAGES/mediagoblin.po @@ -8,7 +8,7 @@ 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" +"POT-Creation-Date: 2011-08-13 19:47-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" @@ -41,26 +41,30 @@ msgstr "" msgid "Sorry, registration is disabled on this instance." msgstr "" -#: mediagoblin/auth/views.py:55 +#: mediagoblin/auth/views.py:57 msgid "Sorry, a user with that name already exists." msgstr "" -#: mediagoblin/auth/views.py:152 +#: mediagoblin/auth/views.py:61 +msgid "Sorry, that email address has already been taken." +msgstr "" + +#: mediagoblin/auth/views.py:159 msgid "" "Your email address has been verified. You may now login, edit your " "profile, and submit images!" msgstr "" -#: mediagoblin/auth/views.py:158 +#: mediagoblin/auth/views.py:165 msgid "The verification key or user id is incorrect" msgstr "" -#: mediagoblin/auth/views.py:179 +#: mediagoblin/auth/views.py:186 #: 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 +#: mediagoblin/edit/forms.py:26 mediagoblin/submit/forms.py:27 msgid "Title" msgstr "" @@ -100,19 +104,19 @@ msgstr "" msgid "You are editing a user's profile. Proceed with caution." msgstr "" -#: mediagoblin/submit/forms.py:29 +#: mediagoblin/submit/forms.py:25 msgid "File" msgstr "" -#: mediagoblin/submit/views.py:45 +#: mediagoblin/submit/views.py:46 msgid "You must provide a file." msgstr "" -#: mediagoblin/submit/views.py:48 +#: mediagoblin/submit/views.py:49 msgid "The file doesn't seem to be an image!" msgstr "" -#: mediagoblin/submit/views.py:96 +#: mediagoblin/submit/views.py:94 msgid "Woohoo! Submitted!" msgstr "" @@ -142,20 +146,20 @@ msgid "" "href=\"http://gnu.org/\">GNU project</a>" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:21 +#: mediagoblin/templates/mediagoblin/root.html:23 msgid "Welcome to GNU MediaGoblin!" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:26 +#: mediagoblin/templates/mediagoblin/root.html:28 msgid "Submit an item" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:31 +#: mediagoblin/templates/mediagoblin/root.html:33 #, python-format msgid "If you have an account, you can <a href=\"%(login_url)s\">Login</a>." msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:37 +#: mediagoblin/templates/mediagoblin/root.html:39 #, python-format msgid "" "If you don't have an account, please <a " @@ -173,7 +177,7 @@ 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 +#: mediagoblin/templates/mediagoblin/submit/start.html:29 msgid "Submit" msgstr "" @@ -218,13 +222,13 @@ msgstr "" msgid "Editing %(username)s's profile" msgstr "" -#: mediagoblin/templates/mediagoblin/listings/tag.html:29 +#: mediagoblin/templates/mediagoblin/listings/tag.html:31 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 +#: mediagoblin/templates/mediagoblin/listings/tag.html:42 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:48 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:104 msgid "atom feed" msgstr "" @@ -232,61 +236,65 @@ msgstr "" msgid "Submit yer media" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:32 #, 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 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:32 msgid "Sorry, no such user found." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:37 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:57 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:39 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:59 msgid "Verification needed" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:40 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:42 msgid "Almost done! Your account still needs to be verified." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:45 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:47 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 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:51 msgid "In case it doesn't:" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:52 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:54 msgid "Resend verification email" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:60 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 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 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:68 #, 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 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:78 #, python-format msgid "%(username)s's profile" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:84 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:86 msgid "Edit profile" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:95 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:98 #, python-format msgid "View all of %(username)s's media" msgstr "" +#: mediagoblin/user_pages/forms.py:24 +msgid "Comment" +msgstr "" + diff --git a/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.mo Binary files differnew file mode 100644 index 00000000..114ab7c0 --- /dev/null +++ b/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.po new file mode 100644 index 00000000..ea19af01 --- /dev/null +++ b/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.po @@ -0,0 +1,319 @@ +# Translations template for PROJECT. +# Copyright (C) 2011 ORGANIZATION +# This file is distributed under the same license as the PROJECT project. +# +# <john_w1954@fastmail.fm>, 2011. +# Fernando Inocencio <faigos@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-13 19:47-0500\n" +"PO-Revision-Date: 2011-08-15 20:33+0000\n" +"Last-Translator: fajro <faigos@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: eo\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" + +#: mediagoblin/auth/forms.py:24 mediagoblin/auth/forms.py:46 +msgid "Username" +msgstr "Uzantnomo" + +#: mediagoblin/auth/forms.py:29 mediagoblin/auth/forms.py:50 +msgid "Password" +msgstr "Pasvorton" + +#: mediagoblin/auth/forms.py:34 +msgid "Passwords must match." +msgstr "Pasvortoj devas koincidi. " + +#: mediagoblin/auth/forms.py:36 +msgid "Confirm password" +msgstr "Retajpu pasvorton" + +#: mediagoblin/auth/forms.py:39 +msgid "Email address" +msgstr "Retadreso" + +#: mediagoblin/auth/views.py:40 +msgid "Sorry, registration is disabled on this instance." +msgstr "Bedaŭrinde, registrado estas malaktivita en tiu ĉi instanco." + +#: mediagoblin/auth/views.py:57 +msgid "Sorry, a user with that name already exists." +msgstr "Bedaŭrinde, uzanto kun tiu nomo jam ekzistas." + +#: mediagoblin/auth/views.py:61 +msgid "Sorry, that email address has already been taken." +msgstr "" + +#: mediagoblin/auth/views.py:159 +msgid "" +"Your email address has been verified. You may now login, edit your profile, " +"and submit images!" +msgstr "" +"Vian retadreson estas kontrolita. Vi povas nun ensaluti, redakti vian " +"profilon, kaj alŝuti bildojn!" + +#: mediagoblin/auth/views.py:165 +msgid "The verification key or user id is incorrect" +msgstr "La kontrol-kodo aŭ la uzantonomo ne estas korekta" + +#: mediagoblin/auth/views.py:186 +#: mediagoblin/templates/mediagoblin/auth/resent_verification_email.html:22 +msgid "Resent your verification email." +msgstr "Resendi vian kontrol-mesaĝon." + +#: mediagoblin/edit/forms.py:26 mediagoblin/submit/forms.py:27 +msgid "Title" +msgstr "Titolo" + +#: 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 "Etikedoj" + +#: mediagoblin/edit/forms.py:38 +msgid "Bio" +msgstr "Bio" + +#: mediagoblin/edit/forms.py:41 +msgid "Website" +msgstr "Retejo" + +#: 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:25 +msgid "File" +msgstr "Dosiero" + +#: mediagoblin/submit/views.py:46 +msgid "You must provide a file." +msgstr "Vi devas provizi dosieron." + +#: mediagoblin/submit/views.py:49 +msgid "The file doesn't seem to be an image!" +msgstr "" + +#: mediagoblin/submit/views.py:94 +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 " Logogramo de Mediagoblin" + +#: mediagoblin/templates/mediagoblin/base.html:51 +msgid "Submit media" +msgstr "Alŝuti aŭd-vid-dosieron" + +#: mediagoblin/templates/mediagoblin/base.html:62 +msgid "verify your email!" +msgstr "kontrolu vian retpoŝton! " + +#: mediagoblin/templates/mediagoblin/base.html:72 +msgid "Login" +msgstr "Ensaluti" + +#: 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 "" +"Provizita de <a href=\"http://mediagoblin.org\">MediaGoblin</a>, unu el la " +"<a href=\"http://gnu.org/\">GNU projectoj</a>" + +#: mediagoblin/templates/mediagoblin/root.html:23 +msgid "Welcome to GNU MediaGoblin!" +msgstr "Bonvenon al GNU MediaGoblin!" + +#: mediagoblin/templates/mediagoblin/root.html:28 +msgid "Submit an item" +msgstr "Alŝuti dosieron" + +#: mediagoblin/templates/mediagoblin/root.html:33 +#, python-format +msgid "If you have an account, you can <a href=\"%(login_url)s\">Login</a>." +msgstr "Se vi havas konton, vi povas <a href=\"%(login_url)s\">Ensaluti</a>." + +#: mediagoblin/templates/mediagoblin/root.html:39 +#, python-format +msgid "" +"If you don't have an account, please <a " +"href=\"%(register_url)s\">Register</a>." +msgstr "" +"Se vi ne havas konton, bonvolu <a href=\"%(register_url)s\">Registriĝi</a>." + +#: mediagoblin/templates/mediagoblin/auth/login.html:26 +msgid "Log in" +msgstr "Ensaluti" + +#: mediagoblin/templates/mediagoblin/auth/login.html:29 +msgid "Login failed!" +msgstr "Ensalutado malsukcesis!" + +#: 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:29 +msgid "Submit" +msgstr "Alŝuti" + +#: mediagoblin/templates/mediagoblin/auth/login.html:42 +msgid "Don't have an account yet?" +msgstr "Ĉu ankoraŭ sen konto?" + +#: mediagoblin/templates/mediagoblin/auth/login.html:45 +msgid "Create one here!" +msgstr "Kreu unu ĉi tie!" + +#: mediagoblin/templates/mediagoblin/auth/register.html:27 +msgid "Create an account!" +msgstr "Kreu konton!" + +#: 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 "" +"Sal %(username)s,\n" +"\n" +"por aktivigi vian GNU MediaGoblin konton, malfermu la sekvantan URLon en via retumilo:\n" +"\n" +"%(verification_url)s" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:29 +#, python-format +msgid "Editing %(media_title)s" +msgstr "Editing %(media_title)s" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:36 +msgid "Cancel" +msgstr "Nuligi" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:37 +msgid "Save changes" +msgstr "Konservi ŝanĝojn" + +#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29 +#, python-format +msgid "Editing %(username)s's profile" +msgstr "Redaktanta profilon de %(username)s'" + +#: mediagoblin/templates/mediagoblin/listings/tag.html:31 +msgid "Media tagged with:" +msgstr "Dosiero markita kiel:" + +#: mediagoblin/templates/mediagoblin/listings/tag.html:42 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:48 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:104 +msgid "atom feed" +msgstr "Atom-a informfluado" + +#: mediagoblin/templates/mediagoblin/submit/start.html:26 +msgid "Submit yer media" +msgstr "Alŝutu vian aŭd-vid-dosieron" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:32 +#, python-format +msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media" +msgstr "<a href=\"%(user_url)s\">%(username)s</a>-a aŭd-vid-dosiero" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:32 +msgid "Sorry, no such user found." +msgstr "Uzanto ne trovita." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:39 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:59 +msgid "Verification needed" +msgstr "Kontrolon bezonata" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:42 +msgid "Almost done! Your account still needs to be verified." +msgstr "Preskaŭ farite! Via konto ankoraŭ devas esti kontrolita." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:47 +msgid "" +"An email should arrive in a few moments with instructions on how to do so." +msgstr "" +"Retmesaĝo alvenos post kelkaj momentoj kun instrukcioj pri kiel tion fari." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:51 +msgid "In case it doesn't:" +msgstr "Se tio ne okazas:" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:54 +msgid "Resend verification email" +msgstr "Resendu kontrolmesaĝon" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 +msgid "" +"Someone has registered an account with this username, but it still has to be" +" verified." +msgstr "" +"Iu registris konton kun tiu ĉi uzantonomo, sed ĝi devas ankoraŭ esti " +"kontrolita." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:68 +#, 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 vi estas tiu sed vi perdis vian kontrolmesaĝon, vi povas <a " +"href=\"%(login_url)s\">ensaluti</a> kaj resendi ĝin." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:78 +#, python-format +msgid "%(username)s's profile" +msgstr "%(username)s'-a profilo" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:86 +msgid "Edit profile" +msgstr "Redakti profilo" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:98 +#, python-format +msgid "View all of %(username)s's media" +msgstr "Rigardu ĉiuj aŭd-vid-dosierojn de %(username)s'" + +#: mediagoblin/user_pages/forms.py:24 +msgid "Comment" +msgstr "Komento" + + 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..f8854734 --- /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..5afe7091 --- /dev/null +++ b/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.po @@ -0,0 +1,329 @@ +# Translations template for PROJECT. +# Copyright (C) 2011 ORGANIZATION +# This file is distributed under the same license as the PROJECT project. +# +# <marktraceur@gmail.com>, 2011. +# Valentin Villenave <valentin@villenave.net>, 2011. +# <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-13 19:47-0500\n" +"PO-Revision-Date: 2011-08-16 13:22+0000\n" +"Last-Translator: joar <transifex@wandborg.se>\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 "Nom d'utilisateur" + +#: mediagoblin/auth/forms.py:29 mediagoblin/auth/forms.py:50 +msgid "Password" +msgstr "Mot de passe" + +#: mediagoblin/auth/forms.py:34 +msgid "Passwords must match." +msgstr "Les mots de passe doivent correspondre." + +#: mediagoblin/auth/forms.py:36 +msgid "Confirm password" +msgstr "Confirmer le mot de passe" + +#: mediagoblin/auth/forms.py:39 +msgid "Email address" +msgstr "Adresse e-mail" + +#: mediagoblin/auth/views.py:40 +msgid "Sorry, registration is disabled on this instance." +msgstr "L'inscription n'est pas activée sur ce serveur, désolé." + +#: mediagoblin/auth/views.py:57 +msgid "Sorry, a user with that name already exists." +msgstr "Un utilisateur existe déjà avec ce nom, désolé." + +#: mediagoblin/auth/views.py:61 +msgid "Sorry, that email address has already been taken." +msgstr "" + +#: mediagoblin/auth/views.py:159 +msgid "" +"Your email address has been verified. You may now login, edit your profile, " +"and submit images!" +msgstr "" +"Votre adresse e-mail a bien été vérifiée. Vous pouvez maintenant vous " +"identifier, modifier votre profil, et soumettre des images !" + +#: mediagoblin/auth/views.py:165 +msgid "The verification key or user id is incorrect" +msgstr "La clé de vérification ou le nom d'utilisateur est incorrect." + +#: mediagoblin/auth/views.py:186 +#: mediagoblin/templates/mediagoblin/auth/resent_verification_email.html:22 +msgid "Resent your verification email." +msgstr "E-mail de vérification renvoyé." + +#: mediagoblin/edit/forms.py:26 mediagoblin/submit/forms.py:27 +msgid "Title" +msgstr "Titre" + +#: mediagoblin/edit/forms.py:29 +msgid "Slug" +msgstr "Légende" + +#: mediagoblin/edit/forms.py:30 +msgid "The slug can't be empty" +msgstr "La légende ne peut pas être laissée vide." + +#: mediagoblin/edit/forms.py:33 mediagoblin/submit/forms.py:31 +msgid "Tags" +msgstr "Tags" + +#: mediagoblin/edit/forms.py:38 +msgid "Bio" +msgstr "Bio" + +#: mediagoblin/edit/forms.py:41 +msgid "Website" +msgstr "Site web" + +#: mediagoblin/edit/forms.py:43 +msgid "Improperly formed URL" +msgstr "Adresse web mal formée" + +#: mediagoblin/edit/views.py:54 +msgid "An entry with that slug already exists for this user." +msgstr "Une entrée existe déjà pour cet utilisateur avec la même légende." + +#: mediagoblin/edit/views.py:75 +msgid "You are editing another user's media. Proceed with caution." +msgstr "" +"Vous vous apprêtez à modifier le média d'un autre utilisateur. Veuillez " +"prendre garde." + +#: mediagoblin/edit/views.py:96 +msgid "You are editing a user's profile. Proceed with caution." +msgstr "" +"Vous vous apprêtez à modifier le profil d'un utilisateur. Veuillez prendre " +"garde." + +#: mediagoblin/submit/forms.py:25 +msgid "File" +msgstr "Fichier" + +#: mediagoblin/submit/views.py:46 +msgid "You must provide a file." +msgstr "Il vous faut fournir un fichier." + +#: mediagoblin/submit/views.py:49 +msgid "The file doesn't seem to be an image!" +msgstr "Ce fichier ne semble pas être une image !" + +#: mediagoblin/submit/views.py:94 +msgid "Woohoo! Submitted!" +msgstr "Youhou, c'est envoyé !" + +#: 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 "Soumettre un média" + +#: mediagoblin/templates/mediagoblin/base.html:62 +msgid "verify your email!" +msgstr "vérifier son adresse e-mail" + +#: mediagoblin/templates/mediagoblin/base.html:72 +msgid "Login" +msgstr "Identification" + +#: 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 "" +"Propulsé par <a href=\"http://mediagoblin.org\">MediaGoblin</a>, un projet " +"de <a href=\"http://gnu.org/\">GNU</a>" + +#: mediagoblin/templates/mediagoblin/root.html:23 +msgid "Welcome to GNU MediaGoblin!" +msgstr "Bienvenue sur GNU MediaGoblin !" + +#: mediagoblin/templates/mediagoblin/root.html:28 +msgid "Submit an item" +msgstr "Soumettre un fichier" + +#: mediagoblin/templates/mediagoblin/root.html:33 +#, 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 vous <a " +"href=\"%(login_url)s\">identifier</a>." + +#: mediagoblin/templates/mediagoblin/root.html:39 +#, python-format +msgid "" +"If you don't have an account, please <a " +"href=\"%(register_url)s\">Register</a>." +msgstr "" +"Si vous n'avez pas de compte, veuillez vous <a " +"href=\"%(register_url)s\">inscrire</a>." + +#: mediagoblin/templates/mediagoblin/auth/login.html:26 +msgid "Log in" +msgstr "S'identifier" + +#: mediagoblin/templates/mediagoblin/auth/login.html:29 +msgid "Login failed!" +msgstr "L'identification a échoué !" + +#: 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:29 +msgid "Submit" +msgstr "Soumettre" + +#: mediagoblin/templates/mediagoblin/auth/login.html:42 +msgid "Don't have an account yet?" +msgstr "Pas encore de compte ?" + +#: mediagoblin/templates/mediagoblin/auth/login.html:45 +msgid "Create one here!" +msgstr "Créez-en un ici !" + +#: mediagoblin/templates/mediagoblin/auth/register.html:27 +msgid "Create an account!" +msgstr "Créer 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 sur GNU MediaGoblin, veuillez vous rendre à l'adresse suivante avec votre navigateur web:\n" +"\n" +"%(verification_url)s" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:29 +#, python-format +msgid "Editing %(media_title)s" +msgstr "Modification de %(media_title)s" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:36 +msgid "Cancel" +msgstr "Annuler" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:37 +msgid "Save changes" +msgstr "Enregistrer les modifications" + +#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29 +#, python-format +msgid "Editing %(username)s's profile" +msgstr "Modification du profil de %(username)s" + +#: mediagoblin/templates/mediagoblin/listings/tag.html:31 +msgid "Media tagged with:" +msgstr "Média comportant les tags suivants :" + +#: mediagoblin/templates/mediagoblin/listings/tag.html:42 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:48 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:104 +msgid "atom feed" +msgstr "flux Atom" + +#: mediagoblin/templates/mediagoblin/submit/start.html:26 +msgid "Submit yer media" +msgstr "Soumettez ce média" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:32 +#, python-format +msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media" +msgstr "Médias de <a href=\"%(user_url)s\">%(username)s</a>" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:32 +msgid "Sorry, no such user found." +msgstr "Impossible de trouver cet utilisateur, désolé." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:39 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:59 +msgid "Verification needed" +msgstr "Vérification requise" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:42 +msgid "Almost done! Your account still needs to be verified." +msgstr "C'est presque fini ! Il vous faut encore vérifier votre compte." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:47 +msgid "" +"An email should arrive in a few moments with instructions on how to do so." +msgstr "" +"Un e-mail devrait vous parvenir dans quelques instants ; il vous indiquera " +"comment procéder." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:51 +msgid "In case it doesn't:" +msgstr "Si la vérification n'est pas arrivée à bon port :" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:54 +msgid "Resend verification email" +msgstr "Renvoyer l'e-mail de vérification" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 +msgid "" +"Someone has registered an account with this username, but it still has to be" +" verified." +msgstr "" +"Quelqu'un a créé un compte à ce nom, mais le compte n'a pas encore été " +"vérifié." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:68 +#, 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 c'est de vous qu'il s'agit, mais que vous avez perdu l'e-mail de " +"vérification, vous pouvez vous <a href=\"%(login_url)s\">identifier</a> et " +"le renvoyer." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:78 +#, python-format +msgid "%(username)s's profile" +msgstr "profil de %(username)s" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:86 +msgid "Edit profile" +msgstr "Modifier le profil" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:98 +#, python-format +msgid "View all of %(username)s's media" +msgstr "Voir tous les médias de %(username)s" + +#: mediagoblin/user_pages/forms.py:24 +msgid "Comment" +msgstr "" + + diff --git a/mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.mo Binary files differnew file mode 100644 index 00000000..78455ad2 --- /dev/null +++ b/mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.po new file mode 100644 index 00000000..0aba5755 --- /dev/null +++ b/mediagoblin/i18n/ja/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. +# +# <averym@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-13 19:47-0500\n" +"PO-Revision-Date: 2011-08-14 00:47+0000\n" +"Last-Translator: cwebber <cwebber@dustycloud.org>\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: ja\n" +"Plural-Forms: nplurals=1; plural=0\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:57 +msgid "Sorry, a user with that name already exists." +msgstr "申し訳ありませんが、その名前を持つユーザーがすでに存在しています。" + +#: mediagoblin/auth/views.py:61 +msgid "Sorry, that email address has already been taken." +msgstr "" + +#: mediagoblin/auth/views.py:159 +msgid "" +"Your email address has been verified. You may now login, edit your profile, " +"and submit images!" +msgstr "メアドが確認されています。これで、ログインしてプロファイルを編集し、画像を提出することができます!" + +#: mediagoblin/auth/views.py:165 +msgid "The verification key or user id is incorrect" +msgstr "検証キーまたはユーザーIDが間違っています" + +#: mediagoblin/auth/views.py:186 +#: mediagoblin/templates/mediagoblin/auth/resent_verification_email.html:22 +msgid "Resent your verification email." +msgstr "検証メールを再送しました。" + +#: mediagoblin/edit/forms.py:26 mediagoblin/submit/forms.py:27 +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 "URL" + +#: mediagoblin/edit/forms.py:43 +msgid "Improperly formed URL" +msgstr "不適切な形式のURL" + +#: 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:25 +msgid "File" +msgstr "ファイル" + +#: mediagoblin/submit/views.py:46 +msgid "You must provide a file." +msgstr "ファイルを提供する必要があります。" + +#: mediagoblin/submit/views.py:49 +msgid "The file doesn't seem to be an image!" +msgstr "ファイルが画像ではないようです!" + +#: mediagoblin/submit/views.py:94 +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 "MediaGoblinロゴ" + +#: 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 "" +"Powered by <a href=\"http://mediagoblin.org\">MediaGoblin</a>, a <a " +"href=\"http://gnu.org/\">GNU project</a>" + +#: mediagoblin/templates/mediagoblin/root.html:23 +msgid "Welcome to GNU MediaGoblin!" +msgstr "GNU MediaGoblinへようこそ!" + +#: mediagoblin/templates/mediagoblin/root.html:28 +msgid "Submit an item" +msgstr "アイテムを投稿" + +#: mediagoblin/templates/mediagoblin/root.html:33 +#, python-format +msgid "If you have an account, you can <a href=\"%(login_url)s\">Login</a>." +msgstr "もしアカウントが持ったら、<a href=\"%(login_url)s\">ログイン</a>できます。" + +#: mediagoblin/templates/mediagoblin/root.html:39 +#, python-format +msgid "" +"If you don't have an account, please <a " +"href=\"%(register_url)s\">Register</a>." +msgstr "アカウントが持っていなければ、<a href=\"%(register_url)s\">登録</a>してお願いします。" + +#: 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:29 +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 "" +"%(username)s様へ\n" +"\n" +"GNU MediaGoblinアカウントを検証にするには、このURLを開いてください。\n" +"\n" +"%(verification_url)s" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:29 +#, python-format +msgid "Editing %(media_title)s" +msgstr "%(media_title)sを編集中" + +#: 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 "%(username)sさんのプロフィールを編集中" + +#: mediagoblin/templates/mediagoblin/listings/tag.html:31 +msgid "Media tagged with:" +msgstr "タグ付けされたコンテンツ:" + +#: mediagoblin/templates/mediagoblin/listings/tag.html:42 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:48 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:104 +msgid "atom feed" +msgstr "Atomフィード" + +#: mediagoblin/templates/mediagoblin/submit/start.html:26 +msgid "Submit yer media" +msgstr "コンテンツを投稿" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:32 +#, python-format +msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media" +msgstr "<a href=\"%(user_url)s\">%(username)s</a>さんのコンテンツ" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:32 +msgid "Sorry, no such user found." +msgstr "申し訳ありませんが、そのユーザーは見つかりませんでした。" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:39 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:59 +msgid "Verification needed" +msgstr "確認必要" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:42 +msgid "Almost done! Your account still needs to be verified." +msgstr "ほぼ完了!アカウントを検証する必要があります。" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:47 +msgid "" +"An email should arrive in a few moments with instructions on how to do so." +msgstr "メールは、その方法の指示でいくつかの瞬間に到着します。" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:51 +msgid "In case it doesn't:" +msgstr "到着しない場合は、" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:54 +msgid "Resend verification email" +msgstr "確認メールを再送信" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 +msgid "" +"Someone has registered an account with this username, but it still has to be" +" verified." +msgstr "誰かがこのユーザ名でアカウントを登録しているが、まだ検証する必要があります。" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:68 +#, 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 "あなたの確認メールを紛失した場合、<a href=\"%(login_url)s\">ログイン</a>して再送できます。" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:78 +#, python-format +msgid "%(username)s's profile" +msgstr "%(username)sさんのプロフィール" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:86 +msgid "Edit profile" +msgstr "プロフィールを編集" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:98 +#, python-format +msgid "View all of %(username)s's media" +msgstr "%(username)sさんのコンテンツをすべて見る" + +#: mediagoblin/user_pages/forms.py:24 +msgid "Comment" +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 differindex cb07e1d0..153584d3 100644 --- a/mediagoblin/i18n/sr/LC_MESSAGES/mediagoblin.mo +++ 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 index b5a6f2d3..ec8611ee 100644 --- a/mediagoblin/i18n/sr/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/sr/LC_MESSAGES/mediagoblin.po @@ -6,9 +6,9 @@ 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 10:20-0500\n" -"PO-Revision-Date: 2011-08-09 03:25+0000\n" -"Last-Translator: FULL NAME <EMAIL@ADDRESS>\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" @@ -17,6 +17,105 @@ msgstr "" "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 "" @@ -90,10 +189,6 @@ msgstr "" msgid "Create an account!" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/resent_verification_email.html:22 -msgid "Resent your verification email." -msgstr "" - #: mediagoblin/templates/mediagoblin/auth/verification_email.txt:19 #, python-format msgid "" diff --git a/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.mo Binary files differindex e300ae89..0d4b463c 100644 --- a/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.mo +++ 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 index 8899a3ea..23605892 100644 --- a/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.po @@ -7,8 +7,8 @@ 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 10:20-0500\n" -"PO-Revision-Date: 2011-08-09 00:35+0000\n" +"POT-Creation-Date: 2011-08-13 19:47-0500\n" +"PO-Revision-Date: 2011-08-16 13:22+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" @@ -18,6 +18,111 @@ msgstr "" "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:57 +msgid "Sorry, a user with that name already exists." +msgstr "En användare med det användarnamnet finns redan." + +#: mediagoblin/auth/views.py:61 +msgid "Sorry, that email address has already been taken." +msgstr "Den e-postadressen är redan tagen." + +#: mediagoblin/auth/views.py:159 +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:165 +msgid "The verification key or user id is incorrect" +msgstr "Verifieringsnyckeln eller användar-IDt är fel." + +#: mediagoblin/auth/views.py:186 +#: 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:27 +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:25 +msgid "File" +msgstr "Fil" + +#: mediagoblin/submit/views.py:46 +msgid "You must provide a file." +msgstr "Du måste ange en fil" + +#: mediagoblin/submit/views.py:49 +msgid "The file doesn't seem to be an image!" +msgstr "Filen verkar inte vara en giltig bildfil!" + +#: mediagoblin/submit/views.py:94 +msgid "Woohoo! Submitted!" +msgstr "Tjohoo! Upladdat!" + #: mediagoblin/templates/mediagoblin/base.html:22 msgid "GNU MediaGoblin" msgstr "GNU MediaGoblin" @@ -43,23 +148,23 @@ 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 project " -"från <a href=\"http://gnu.org/\">GNU</a>" +"Drivs av <a href=\"http://mediagoblin.org\">MediaGoblin</a>, ett <a " +"href=\"http://gnu.org/\">GNU</a>-projekt" -#: mediagoblin/templates/mediagoblin/root.html:21 +#: mediagoblin/templates/mediagoblin/root.html:23 msgid "Welcome to GNU MediaGoblin!" msgstr "Välkommen till GNU MediaGoblin!" -#: mediagoblin/templates/mediagoblin/root.html:26 +#: mediagoblin/templates/mediagoblin/root.html:28 msgid "Submit an item" msgstr "Ladda upp" -#: mediagoblin/templates/mediagoblin/root.html:31 +#: mediagoblin/templates/mediagoblin/root.html:33 #, 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 +#: mediagoblin/templates/mediagoblin/root.html:39 #, python-format msgid "" "If you don't have an account, please <a " @@ -78,7 +183,7 @@ 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 +#: mediagoblin/templates/mediagoblin/submit/start.html:29 msgid "Submit" msgstr "Skicka" @@ -94,10 +199,6 @@ msgstr "Skapa ett!" msgid "Create an account!" msgstr "Skapa ett konto!" -#: mediagoblin/templates/mediagoblin/auth/resent_verification_email.html:22 -msgid "Resent your verification email." -msgstr "Skickade ett nytt verifierings-email." - #: mediagoblin/templates/mediagoblin/auth/verification_email.txt:19 #, python-format msgid "" @@ -132,13 +233,13 @@ msgstr "Spara" msgid "Editing %(username)s's profile" msgstr "Redigerar %(username)ss profil" -#: mediagoblin/templates/mediagoblin/listings/tag.html:29 +#: mediagoblin/templates/mediagoblin/listings/tag.html:31 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 +#: mediagoblin/templates/mediagoblin/listings/tag.html:42 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:48 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:104 msgid "atom feed" msgstr "atom-feed" @@ -146,40 +247,40 @@ msgstr "atom-feed" msgid "Submit yer media" msgstr "Ladda upp" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:32 #, 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 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:32 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 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:39 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:59 msgid "Verification needed" msgstr "Verifiering krävs" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:40 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:42 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 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:47 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 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:51 msgid "In case it doesn't:" msgstr "Om det inte skulle göra det:" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:52 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:54 msgid "Resend verification email" msgstr "Skicka ett nytt e-postmeddelande" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:60 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 msgid "" "Someone has registered an account with this username, but it still has to be" " verified." @@ -187,7 +288,7 @@ 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 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:68 #, python-format msgid "" "If you are that person but you've lost your verification email, you can <a " @@ -197,18 +298,22 @@ msgstr "" "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 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:78 #, python-format msgid "%(username)s's profile" msgstr "%(username)ss profil" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:84 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:86 msgid "Edit profile" msgstr "Redigera profil" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:95 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:98 #, python-format msgid "View all of %(username)s's media" msgstr "Se all media från %(username)s" +#: mediagoblin/user_pages/forms.py:24 +msgid "Comment" +msgstr "Kommentar" + diff --git a/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.mo Binary files differnew file mode 100644 index 00000000..9615e44c --- /dev/null +++ b/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.po new file mode 100644 index 00000000..d8f8c98d --- /dev/null +++ b/mediagoblin/i18n/zh_TW/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. +# +# <chc@citi.sinica.edu.tw>, 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-13 19:47-0500\n" +"PO-Revision-Date: 2011-08-14 00:47+0000\n" +"Last-Translator: cwebber <cwebber@dustycloud.org>\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: zh_TW\n" +"Plural-Forms: nplurals=1; plural=0\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:57 +msgid "Sorry, a user with that name already exists." +msgstr "抱歉, 這個使用者名稱已經存在." + +#: mediagoblin/auth/views.py:61 +msgid "Sorry, that email address has already been taken." +msgstr "" + +#: mediagoblin/auth/views.py:159 +msgid "" +"Your email address has been verified. You may now login, edit your profile, " +"and submit images!" +msgstr "你的電子郵件位址已被認證. 你現在就可以登入, 編輯你的個人檔案而且送出照片!" + +#: mediagoblin/auth/views.py:165 +msgid "The verification key or user id is incorrect" +msgstr "認證碼或是使用者帳號錯誤" + +#: mediagoblin/auth/views.py:186 +#: mediagoblin/templates/mediagoblin/auth/resent_verification_email.html:22 +msgid "Resent your verification email." +msgstr "重送認證郵件." + +#: mediagoblin/edit/forms.py:26 mediagoblin/submit/forms.py:27 +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:25 +msgid "File" +msgstr "檔案" + +#: mediagoblin/submit/views.py:46 +msgid "You must provide a file." +msgstr "你必須提供一個檔案" + +#: mediagoblin/submit/views.py:49 +msgid "The file doesn't seem to be an image!" +msgstr "檔案看起來不像是一個圖片喔!" + +#: mediagoblin/submit/views.py:94 +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 "Mediagoblin 標誌" + +#: 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 "" +"由 <a href=\"http://mediagoblin.org\">MediaGoblin</a> 製作, 她是一個 <a " +"href=\"http://gnu.org/\">GNU project</a>" + +#: mediagoblin/templates/mediagoblin/root.html:23 +msgid "Welcome to GNU MediaGoblin!" +msgstr "GNU MediaGoblin 歡迎您!" + +#: mediagoblin/templates/mediagoblin/root.html:28 +msgid "Submit an item" +msgstr "送出一個項目" + +#: mediagoblin/templates/mediagoblin/root.html:33 +#, python-format +msgid "If you have an account, you can <a href=\"%(login_url)s\">Login</a>." +msgstr "如果您有帳號了, 你可以直接 <a href=\"%(login_url)s\">登入</a>." + +#: mediagoblin/templates/mediagoblin/root.html:39 +#, python-format +msgid "" +"If you don't have an account, please <a " +"href=\"%(register_url)s\">Register</a>." +msgstr "如果您尚未取得帳號, 請 <a href=\"%(register_url)s\">註冊</a>." + +#: 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:29 +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 "" +"嗨 %(username)s,\n" +"\n" +"啟動 GNU MediaGoblin 帳號, 在你的瀏覽器中打開下面的網址:\n" +"\n" +"%(verification_url)s" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:29 +#, python-format +msgid "Editing %(media_title)s" +msgstr "編輯 %(media_title)s 中" + +#: 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 "編輯 %(username)s'的檔案中" + +#: mediagoblin/templates/mediagoblin/listings/tag.html:31 +msgid "Media tagged with:" +msgstr "媒體被標籤為:" + +#: mediagoblin/templates/mediagoblin/listings/tag.html:42 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:48 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:104 +msgid "atom feed" +msgstr "atom feed" + +#: mediagoblin/templates/mediagoblin/submit/start.html:26 +msgid "Submit yer media" +msgstr "送出你的媒體檔案" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:32 +#, python-format +msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media" +msgstr "<a href=\"%(user_url)s\">%(username)s</a>的媒體" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:32 +msgid "Sorry, no such user found." +msgstr "抱歉, 找不到這個使用者." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:39 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:59 +msgid "Verification needed" +msgstr "需要驗證" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:42 +msgid "Almost done! Your account still needs to be verified." +msgstr "快要完成了! 你的帳號仍需要驗證." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:47 +msgid "" +"An email should arrive in a few moments with instructions on how to do so." +msgstr "很快的會有一封電子郵件告訴你如何做." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:51 +msgid "In case it doesn't:" +msgstr "假設它無法:" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:54 +msgid "Resend verification email" +msgstr "重送認證郵件 " + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 +msgid "" +"Someone has registered an account with this username, but it still has to be" +" verified." +msgstr "有人已經註冊了這個帳號, 但此帳號仍需要驗證." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:68 +#, 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 "如果你就是那個人, 但是遺失了認證信, 你可以<a href=\"%(login_url)s\">登入</a> 然後重送一次." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:78 +#, python-format +msgid "%(username)s's profile" +msgstr "%(username)s的個人檔案" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:86 +msgid "Edit profile" +msgstr "編輯個人檔案" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:98 +#, python-format +msgid "View all of %(username)s's media" +msgstr "查看%(username)s的全部媒體檔案" + +#: mediagoblin/user_pages/forms.py:24 +msgid "Comment" +msgstr "" + + diff --git a/mediagoblin/process_media/__init__.py b/mediagoblin/process_media/__init__.py index 8e12ca4d..e1289a4c 100644 --- a/mediagoblin/process_media/__init__.py +++ b/mediagoblin/process_media/__init__.py @@ -15,11 +15,14 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. import Image -from mediagoblin.db.util import ObjectId -from celery.task import task -from mediagoblin import mg_globals as mgg from contextlib import contextmanager +from celery.task import Task +from celery import registry + +from mediagoblin.db.util import ObjectId +from mediagoblin import mg_globals as mgg +from mediagoblin.process_media.errors import BaseProcessingFail, BadMediaFail THUMB_SIZE = 180, 180 @@ -32,6 +35,7 @@ def create_pub_filepath(entry, filename): unicode(entry['_id']), filename]) + @contextmanager def closing(callback): try: @@ -39,19 +43,99 @@ def closing(callback): finally: pass -@task -def process_media_initial(media_id): - workbench = mgg.workbench_manager.create_workbench() - entry = mgg.database.MediaEntry.one( - {'_id': ObjectId(media_id)}) +################################ +# Media processing initial steps +################################ + +class ProcessMedia(Task): + """ + Pass this entry off for processing. + """ + def run(self, media_id): + """ + Pass the media entry off to the appropriate processing function + (for now just process_image...) + """ + entry = mgg.database.MediaEntry.one( + {'_id': ObjectId(media_id)}) + + # Try to process, and handle expected errors. + try: + process_image(entry) + except BaseProcessingFail, exc: + mark_entry_failed(entry[u'_id'], exc) + return + + entry['state'] = u'processed' + entry.save() + + def on_failure(self, exc, task_id, args, kwargs, einfo): + """ + If the processing failed we should mark that in the database. + + Assuming that the exception raised is a subclass of BaseProcessingFail, + we can use that to get more information about the failure and store that + for conveying information to users about the failure, etc. + """ + entry_id = args[0] + mark_entry_failed(entry_id, exc) + + +process_media = registry.tasks[ProcessMedia.name] + + +def mark_entry_failed(entry_id, exc): + """ + Mark a media entry as having failed in its conversion. + + Uses the exception that was raised to mark more information. If the + exception is a derivative of BaseProcessingFail then we can store extra + information that can be useful for users telling them why their media failed + to process. + + Args: + - entry_id: The id of the media entry + + """ + # Was this a BaseProcessingFail? In other words, was this a + # type of error that we know how to handle? + if isinstance(exc, BaseProcessingFail): + # Looks like yes, so record information about that failure and any + # metadata the user might have supplied. + mgg.database['media_entries'].update( + {'_id': entry_id}, + {'$set': {u'state': u'failed', + u'fail_error': exc.exception_path, + u'fail_metadata': exc.metadata}}) + else: + # Looks like no, so just mark it as failed and don't record a + # failure_error (we'll assume it wasn't handled) and don't record + # metadata (in fact overwrite it if somehow it had previous info + # here) + mgg.database['media_entries'].update( + {'_id': entry_id}, + {'$set': {u'state': u'failed', + u'fail_error': None, + u'fail_metadata': {}}}) + + +def process_image(entry): + """ + Code to process an image + """ + workbench = mgg.workbench_manager.create_workbench() queued_filepath = entry['queued_media_file'] queued_filename = workbench.localized_file( mgg.queue_store, queued_filepath, 'source') - thumb = Image.open(queued_filename) + try: + thumb = Image.open(queued_filename) + except IOError: + raise BadMediaFail() + thumb.thumbnail(THUMB_SIZE, Image.ANTIALIAS) # ensure color mode is compatible with jpg if thumb.mode != "RGB": @@ -63,11 +147,9 @@ def process_media_initial(media_id): with closing(thumb_file): thumb.save(thumb_file, "JPEG", quality=90) - """ - If the size of the original file exceeds the specified size of a `medium` - file, a `medium.jpg` files is created and later associated with the media - entry. - """ + # If the size of the original file exceeds the specified size of a `medium` + # file, a `medium.jpg` files is created and later associated with the media + # entry. medium = Image.open(queued_filename) medium_processed = False @@ -101,8 +183,6 @@ def process_media_initial(media_id): media_files_dict['original'] = original_filepath if medium_processed: media_files_dict['medium'] = medium_filepath - entry['state'] = u'processed' - entry.save() # clean up workbench workbench.destroy_self() diff --git a/mediagoblin/process_media/errors.py b/mediagoblin/process_media/errors.py new file mode 100644 index 00000000..f8ae9ab2 --- /dev/null +++ b/mediagoblin/process_media/errors.py @@ -0,0 +1,44 @@ +# 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.util import lazy_pass_to_ugettext as _ + +class BaseProcessingFail(Exception): + """ + Base exception that all other processing failure messages should + subclass from. + + You shouldn't call this itself; instead you should subclass it + and provid the exception_path and general_message applicable to + this error. + """ + general_message = u'' + + @property + def exception_path(self): + return u"%s:%s" % ( + self.__class__.__module__, self.__class__.__name__) + + def __init__(self, **metadata): + self.metadata = metadata or {} + + +class BadMediaFail(BaseProcessingFail): + """ + Error that should be raised when an inappropriate file was given + for the media type specified. + """ + general_message = _(u'Invalid file given for media type.') diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css index 59c2f49d..51a855be 100644 --- a/mediagoblin/static/css/base.css +++ b/mediagoblin/static/css/base.css @@ -1,12 +1,40 @@ +/* @font-face */ + +@font-face { + font-family: 'Lato'; + font-style: normal; + font-weight: 700; + src: local('Lato Bold'), local('Lato-Bold'), url('http://themes.googleusercontent.com/static/fonts/lato/v1/wkfQbvfT_02e2IWO3yYueQ.woff') format('woff'); +} +@font-face { + font-family: 'Lato'; + font-style: italic; + font-weight: 400; + src: local('Lato Italic'), local('Lato-Italic'), url('http://themes.googleusercontent.com/static/fonts/lato/v1/oUan5VrEkpzIazlUe5ieaA.woff') format('woff'); +} +@font-face { + font-family: 'Lato'; + font-style: italic; + font-weight: 700; + src: local('Lato Bold Italic'), local('Lato-BoldItalic'), url('http://themes.googleusercontent.com/static/fonts/lato/v1/HkF_qI1x_noxlxhrhMQYED8E0i7KZn-EPnyo3HZu7kw.woff') format('woff'); +} +@font-face { + font-family: 'Lato'; + font-style: normal; + font-weight: 400; + src: local('Lato Regular'), local('Lato-Regular'), url('http://themes.googleusercontent.com/static/fonts/lato/v1/9k-RPmcnxYEPm8CNFsH2gg.woff') format('woff'); +} + body { background-color: #111; background-image: url("../images/background.png"); - color: #999; + color: #C3C3C3; font-family: sans-serif; padding: none; margin: 0px; height: 100%; font: 16px "HelveticaNeue-Light","Helvetica Neue Light","Helvetica Neue",Helvetica,Arial,sans-serif; + font-family:'Lato', sans-serif; } form { @@ -14,37 +42,28 @@ form { padding: 0px; } -/* Carter One font */ - -@font-face { - font-family: 'Carter One'; - font-style: normal; - font-weight: normal; - src: local('CarterOne'), url('http://themes.googleusercontent.com/font?kit=VjW2qt1pkqVtO22ObxgEBRsxEYwM7FgeyaSgU71cLG0') format('woff'); -} - /* text styles */ h1{ - font-family: 'Carter One',arial,serif; margin-bottom: 15px; margin-top: 15px; color: #fff; - font-size: 30px; + font-size: 1.875em; } h2{ + font-size: 1.375em; margin-top: 20px; color: #fff; } h3{ - border-bottom: 1px solid #222; - font-size: 18px; + border-bottom: 1px solid #333; + font-size: 1.125em; } a { - color: #999; + color: #86D4B1; } a.highlight { @@ -55,6 +74,11 @@ label { font-weight: normal; } +input, textarea { + font-size:1em; + font-family:'Lato', sans-serif; +} + /* website structure */ .mediagoblin_body { @@ -66,10 +90,15 @@ label { height: 36px; padding-top: 14px; margin-bottom: 20px; - border-bottom: 1px solid #222222; + border-bottom: 1px solid #333; } -.header_submit{ +a.mediagoblin_logo{ + color: #fff; + font-weight: bold; +} + +.header_submit, .header_submit_highlight{ color: #272727; background-color: #aaa; background-image: -webkit-gradient(linear, left top, left bottom, from(##D2D2D2), to(#aaa)); @@ -79,22 +108,25 @@ label { 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; + border-radius: 3px; margin: 8px; padding: 3px 8px; text-decoration: none; border: medium none; - font-family: 'Carter One',arial,serif; + font-style: normal; +} + +.header_submit_highlight{ +background-image: -moz-linear-gradient(center top , rgb(134, 212, 177), rgb(109, 173, 144)); } .mediagoblin_footer { height: 30px; - border-top: 1px solid #222222; + border-top: 1px solid #333; bottom: 0px; padding-top: 8px; text-align: center; - font-size: 14px; - color: #999; + font-size: 0.875em; } .mediagoblin_content { @@ -108,7 +140,6 @@ label { /* common website elements */ .button { - font-family: 'Carter One', arial, serif; height: 32px; min-width: 99px; background-color: #86d4b1; @@ -119,15 +150,16 @@ label { 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-radius: 3px; border: none; color: #272727; margin: 10px 0px 10px 15px; - font-size: 1em; text-align: center; padding-left: 11px; padding-right: 11px; text-decoration: none; + font-family:'Lato', sans-serif; + font-size:1em; } .pagination{ @@ -138,13 +170,20 @@ text-align: center; margin: 5px; } +.empty_space{ + background-color: #222; + font-style: italic; + text-align: center; + height: 160px; + padding-top: 70px; +} + /* forms */ .form_box { 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; @@ -157,13 +196,8 @@ text-align: center; background-image: url("../images/background_edit.png"); } -.form_box h1 { - font-size: 28px; -} - .form_field_input input, .form_field_input textarea { width: 100%; - font-size: 18px; } .form_field_box { @@ -178,7 +212,6 @@ text-align: center; background-color: #87453b; color: #fff; border: none; - font-size: 16px; padding: 9px; margin-top: 8px; margin-bottom: 8px; @@ -193,7 +226,7 @@ text-align: center; .comment_author { margin-bottom: 40px; padding-top: 4px; - font-size: 14px; + font-size: 0.9em; } .comment_content p { @@ -205,7 +238,6 @@ text-align: center; .media_thumbnail { padding: 0px; width: 180px; - height: 180px; overflow: hidden; float: left; margin: 0px 4px 10px 4px; @@ -214,8 +246,12 @@ text-align: center; /* media detail */ -.media_image_container { - text-align: center; +h2.media_title{ + margin-bottom: 0px; +} + +p.media_uploader{ + font-size: 0.9em; } /* icons */ @@ -232,10 +268,9 @@ img.media_icon{ display: block; float: left; text-align: center; - background-color: #222; + background-color: #333; text-decoration: none; padding: 12px 0pt; - font-family: 'Carter One', arial, serif; font-size: 2em; margin: 0 0 20px } @@ -291,3 +326,15 @@ ul.mediaentry_tags li { margin: 0px 5px 0px 0px; padding: 0px; } + + +/* media processing panel */ + +table.media_panel { + width: 100%; +} + +table.media_panel th { + font-weight: bold; + padding-bottom: 4px; +} diff --git a/mediagoblin/static/images/404.png b/mediagoblin/static/images/404.png Binary files differnew file mode 100644 index 00000000..78d746ba --- /dev/null +++ b/mediagoblin/static/images/404.png diff --git a/mediagoblin/static/images/frontpage_image.png b/mediagoblin/static/images/frontpage_image.png Binary files differnew file mode 100644 index 00000000..689eb2c2 --- /dev/null +++ b/mediagoblin/static/images/frontpage_image.png diff --git a/mediagoblin/static/images/icon_feed.png b/mediagoblin/static/images/icon_feed.png Binary files differindex 11e5b1e7..81889473 100644 --- a/mediagoblin/static/images/icon_feed.png +++ b/mediagoblin/static/images/icon_feed.png diff --git a/mediagoblin/static/images/logo.png b/mediagoblin/static/images/logo.png Binary files differdeleted file mode 100644 index cf28a6d4..00000000 --- a/mediagoblin/static/images/logo.png +++ /dev/null diff --git a/mediagoblin/storage.py b/mediagoblin/storage.py index ec3bc1b5..d484be1f 100644 --- a/mediagoblin/storage.py +++ b/mediagoblin/storage.py @@ -289,16 +289,29 @@ 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. + This isn't an interface to some real storage, instead it's a + redirecting interface, that redirects requests to other + "StorageInterface"s. + + For example, say you have the paths: + + 1. ['user_data', 'cwebber', 'avatar.jpg'] + 2. ['user_data', 'elrond', 'avatar.jpg'] + 3. ['media_entries', '34352f304c3f4d0ad8ad0f043522b6f2', 'thumb.jpg'] + + You could mount media_entries under CloudFileStorage and user_data + under BasicFileStorage. Then 1 would be passed to + BasicFileStorage under the path ['cwebber', 'avatar.jpg'] and 3 + would be passed to CloudFileStorage under + ['34352f304c3f4d0ad8ad0f043522b6f2', 'thumb.jpg']. + + In other words, this is kind of like mounting /home/ and /etc/ + under different filesystems on your operating system... but with + mediagoblin filestorages :) - 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, + 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): diff --git a/mediagoblin/submit/forms.py b/mediagoblin/submit/forms.py index ccb62a03..4519b057 100644 --- a/mediagoblin/submit/forms.py +++ b/mediagoblin/submit/forms.py @@ -18,15 +18,15 @@ import wtforms from mediagoblin.util import tag_length_validator -from mediagoblin.util import pass_to_ugettext as _ +from mediagoblin.util import fake_ugettext_passthrough as _ class SubmitStartForm(wtforms.Form): + file = wtforms.FileField(_('File')) title = wtforms.TextField( _('Title'), [wtforms.validators.Length(min=0, max=500)]) description = wtforms.TextAreaField('Description of this work') - file = wtforms.FileField(_('File')) tags = wtforms.TextField( _('Tags'), [tag_length_validator]) diff --git a/mediagoblin/submit/views.py b/mediagoblin/submit/views.py index ba13b755..1ba17954 100644 --- a/mediagoblin/submit/views.py +++ b/mediagoblin/submit/views.py @@ -14,19 +14,21 @@ # 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 uuid + from os.path import splitext from cgi import FieldStorage -from string import split from werkzeug.utils import secure_filename +from mediagoblin.db.util import ObjectId from mediagoblin.util import ( 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 +from mediagoblin.process_media import process_media, mark_entry_failed from mediagoblin.messages import add_message, SUCCESS @@ -51,6 +53,7 @@ def submit_start(request): # create entry and save in database entry = request.db.MediaEntry() + entry['_id'] = ObjectId() entry['title'] = ( request.POST['title'] or unicode(splitext(filename)[0])) @@ -66,10 +69,6 @@ def submit_start(request): 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) - # Generate a slug from the title entry.generate_slug() @@ -88,10 +87,37 @@ def submit_start(request): # Add queued filename to the entry entry['queued_media_file'] = queue_filepath + + # We generate this ourselves so we know what the taks id is for + # retrieval later. + # (If we got it off the task's auto-generation, there'd be a risk of + # a race condition when we'd save after sending off the task) + task_id = unicode(uuid.uuid4()) + entry['queued_task_id'] = task_id + + # Save now so we have this data before kicking off processing entry.save(validate=True) - # queue it for processing - process_media_initial.delay(unicode(entry['_id'])) + # Pass off to processing + # + # (... don't change entry after this point to avoid race + # conditions with changes to the document via processing code) + try: + process_media.apply_async( + [unicode(entry['_id'])], {}, + task_id=task_id) + except BaseException as exc: + # The purpose of this section is because when running in "lazy" + # or always-eager-with-exceptions-propagated celery mode that + # the failure handling won't happen on Celery end. Since we + # expect a lot of users to run things in this way we have to + # capture stuff here. + # + # ... not completely the diaper pattern because the exception is + # re-raised :) + mark_entry_failed(entry[u'_id'], exc) + # re-raise the exception + raise add_message(request, SUCCESS, _('Woohoo! Submitted!')) diff --git a/mediagoblin/templates/mediagoblin/404.html b/mediagoblin/templates/mediagoblin/404.html new file mode 100644 index 00000000..5af46a87 --- /dev/null +++ b/mediagoblin/templates/mediagoblin/404.html @@ -0,0 +1,34 @@ +{# +# 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_content %} + <h1>{% trans %}Oops!{% endtrans %}</h1> + + <div class="grid_8 alpha"> + <p>{% trans %}There doesn't seem to be a page at this address. Sorry!{% endtrans %}</p> + <p> + {%- trans %}If you're sure the address is correct, maybe the page you're looking for has been moved or deleted.{% endtrans -%} + </p> + </div> + + <div class="grid_8 omega"> + <img src="{{ request.staticdirect('/images/404.png') }}" + alt="{% trans %}Image of 404 goblin stressing out{% endtrans %}" /> + </div> +{% endblock %} diff --git a/mediagoblin/templates/mediagoblin/auth/login.html b/mediagoblin/templates/mediagoblin/auth/login.html index 5750feb0..afbecf20 100644 --- a/mediagoblin/templates/mediagoblin/auth/login.html +++ b/mediagoblin/templates/mediagoblin/auth/login.html @@ -26,12 +26,12 @@ <h1>{% trans %}Log in{% endtrans %}</h1> {% if login_failed %} <div class="form_field_error"> - {% trans %}Login failed!{% endtrans %} + {% trans %}Logging in failed!{% endtrans %} </div> {% endif %} {{ wtforms_util.render_divs(login_form) }} <div class="form_submit_buttons"> - <input type="submit" value="{% trans %}Submit{% endtrans %}" class="button"/> + <input type="submit" value="{% trans %}Log in{% endtrans %}" class="button"/> </div> {% if next %} <input type="hidden" name="next" value="{{ next }}" class="button" diff --git a/mediagoblin/templates/mediagoblin/auth/register.html b/mediagoblin/templates/mediagoblin/auth/register.html index 623cbdfd..d9eedc4a 100644 --- a/mediagoblin/templates/mediagoblin/auth/register.html +++ b/mediagoblin/templates/mediagoblin/auth/register.html @@ -27,7 +27,7 @@ <h1>{% trans %}Create an account!{% endtrans %}</h1> {{ wtforms_util.render_divs(register_form) }} <div class="form_submit_buttons"> - <input type="submit" value="{% trans %}Submit{% endtrans %}" + <input type="submit" value="{% trans %}Create{% endtrans %}" class="button" /> </div> </div> diff --git a/mediagoblin/templates/mediagoblin/base.html b/mediagoblin/templates/mediagoblin/base.html index 986e0995..6e54c31d 100644 --- a/mediagoblin/templates/mediagoblin/base.html +++ b/mediagoblin/templates/mediagoblin/base.html @@ -39,11 +39,9 @@ <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> + <a class="mediagoblin_logo" href="{{ request.urlgen('index') }}"> + MediaGoblin<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" @@ -66,10 +64,10 @@ user= request.user['username']) }}"> {{ request.user['username'] }}</a> - (<a href="{{ request.urlgen('mediagoblin.auth.logout') }}">logout</a>) + (<a href="{{ request.urlgen('mediagoblin.auth.logout') }}">log out</a>) {% else %} <a href="{{ request.urlgen('mediagoblin.auth.login') }}"> - {% trans %}Login{% endtrans %}</a> + {% trans %}Log in{% endtrans %}</a> {% endif %} </div> </div> diff --git a/mediagoblin/templates/mediagoblin/edit/edit_profile.html b/mediagoblin/templates/mediagoblin/edit/edit_profile.html index 534e5f20..bed5e0ca 100644 --- a/mediagoblin/templates/mediagoblin/edit/edit_profile.html +++ b/mediagoblin/templates/mediagoblin/edit/edit_profile.html @@ -32,7 +32,7 @@ </h1> {{ wtforms_util.render_divs(form) }} <div class="form_submit_buttons"> - <input type="submit" value="{% trans %}Submit{% endtrans %}" class="button" /> + <input type="submit" value="{% trans %}Save changes{% endtrans %}" class="button" /> </div> </div> </form> diff --git a/mediagoblin/templates/mediagoblin/listings/tag.html b/mediagoblin/templates/mediagoblin/listings/tag.html index a013797f..289f44b8 100644 --- a/mediagoblin/templates/mediagoblin/listings/tag.html +++ b/mediagoblin/templates/mediagoblin/listings/tag.html @@ -17,6 +17,8 @@ #} {% extends "mediagoblin/base.html" %} +{% from "mediagoblin/utils/object_gallery.html" import object_gallery %} + {% block mediagoblin_head %} <link rel="alternate" type="application/atom+xml" href="{{ request.urlgen( @@ -30,14 +32,13 @@ </h1> <div class="container_16 media_gallery"> - {% include "mediagoblin/utils/object_gallery.html" %} + {{ object_gallery(request, media_entries, pagination) }} </div> <div class="grid_16"> - <a href="{{ request.urlgen( - 'mediagoblin.listings.tag_atom_feed', - tag=tag_slug) }}"> - {%- trans %}atom feed{% endtrans -%} - </a> + {% set feed_url = request.urlgen( + 'mediagoblin.listings.tag_atom_feed', + tag=tag_slug) %} + {% include "mediagoblin/utils/feed_link.html" %} </div> {% endblock %} diff --git a/mediagoblin/templates/mediagoblin/root.html b/mediagoblin/templates/mediagoblin/root.html index a4e19984..08155c17 100644 --- a/mediagoblin/templates/mediagoblin/root.html +++ b/mediagoblin/templates/mediagoblin/root.html @@ -17,31 +17,36 @@ #} {% extends "mediagoblin/base.html" %} -{% block mediagoblin_content %} - <h1>{% trans %}Welcome to GNU MediaGoblin!{% endtrans %}</h1> +{% from "mediagoblin/utils/object_gallery.html" import object_gallery %} +{% block mediagoblin_content %} {% if request.user %} - <p> - <a href="{{ request.urlgen('mediagoblin.submit.start') }}"> - {%- trans %}Submit an item{% endtrans -%} - </a> - </p> + <h1>Explore</h1> {% else %} - <p> - {% 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> - {% 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 %} + <div class="grid_11 alpha"> + <h1>{% trans %}Hi there, media lover! MediaGoblin is...{% endtrans %}</h1> + <ul> + <li>{% trans %}The perfect place for your media!{% endtrans %}</li> + <li>{% trans %}A place for people to collaborate and show off original and derived creations!{% endtrans %}</li> + <li>{% trans %}Free, as in freedom. (We’re a <a href="http://gnu.org">GNU project</a> in the making, after all.){% endtrans %}</li> + <li>{% trans %}Aiming to make the world a better place through decentralization and (eventually, coming soon!) federation!{% endtrans %}</li> + <li>{% trans %}Built for extensibility. (Multiple media types coming soon to the software, including video support!){% endtrans %}</li> + <li>{% trans %}Powered by people like you. (<a href="http://mediagoblin.org/pages/join.html">You can help us improve this software!</a>){% endtrans %}</li> + </ul> - {# temporarily, an "image gallery" that isn't one really ;) #} + {% if allow_registration %} + <p>Excited to join us? To add your own media, make collections and save favorites...<p> + <a class="header_submit_highlight" href="{{ request.urlgen('mediagoblin.auth.register') }}">Create a free account</a> or + <a class="header_submit" href="http://wiki.mediagoblin.org/HackingHowto">Set up MediaGoblin on your own server</a> + {% endif %} + </div> - {% include "mediagoblin/utils/object_gallery.html" %} + <div class="grid_5 omega"> + <img src="{{ request.staticdirect('/images/frontpage_image.png') }}" /> + </div> + + <div class="clear"></div> + {% endif %} + <h2>Most recent media</h2> + {{ object_gallery(request, media_entries, pagination) }} {% endblock %} diff --git a/mediagoblin/templates/mediagoblin/submit/start.html b/mediagoblin/templates/mediagoblin/submit/start.html index eb34c2e2..3a40850d 100644 --- a/mediagoblin/templates/mediagoblin/submit/start.html +++ b/mediagoblin/templates/mediagoblin/submit/start.html @@ -24,10 +24,7 @@ method="POST" enctype="multipart/form-data"> <div class="grid_8 prefix_1 suffix_1 form_box"> <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) }} + {{ wtforms_util.render_divs(submit_form) }} <div class="form_submit_buttons"> <input type="submit" value="{% trans %}Submit{% endtrans %}" class="button" /> </div> diff --git a/mediagoblin/templates/mediagoblin/user_pages/gallery.html b/mediagoblin/templates/mediagoblin/user_pages/gallery.html index a66a547e..3a3d2373 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/gallery.html +++ b/mediagoblin/templates/mediagoblin/user_pages/gallery.html @@ -17,6 +17,8 @@ #} {% extends "mediagoblin/base.html" %} +{% from "mediagoblin/utils/object_gallery.html" import object_gallery %} + {% block mediagoblin_head %} <link rel="alternate" type="application/atom+xml" href="{{ request.urlgen( @@ -35,16 +37,15 @@ {%- endtrans %} </h1> - </div> <div class="container_16 media_gallery"> - {% include "mediagoblin/utils/object_gallery.html" %} + {{ object_gallery(request, media_entries, pagination) }} </div> + <div class="grid_16"> - <a href="{{ request.urlgen( - 'mediagoblin.user_pages.atom_feed', - user=user.username) }}"> - {%- trans %}atom feed{% endtrans -%} - </a> + {% set feed_url = request.urlgen( + 'mediagoblin.user_pages.atom_feed', + user=user.username) %} + {% include "mediagoblin/utils/feed_link.html" %} </div> {% else %} {# This *should* not occur as the view makes sure we pass in a user. #} diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html index afc0d903..2086d3d6 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media.html @@ -29,33 +29,32 @@ media.get_display_media(media.media_files)) }}" /> </div> - <h2> - {{media.title}} + <h2 class="media_title"> + {{ media.title }} </h2> - {% autoescape False %} - <p>{{ media.description_html }}</p> - {% endautoescape %} - - <p> - {% trans date="%4d-%02d-%02d"|format( - media.created.year, - media.created.month, media.created.day), + <p class="media_uploader"> + {% trans date=media.created.strftime("%Y-%m-%d"), 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> + Uploaded on {{ date }} by <a href="{{ user_url }}">{{ username }}</a> {%- endtrans %} </p> - <br /> + {% autoescape False %} + <p>{{ media.description_html }}</p> + {% endautoescape %} + + <br /> <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) }} + {{ wtforms_util.render_divs(comment_form) }} <div class="form_submit_buttons"> <input type="submit" value="{% trans %}Post comment!{% endtrans %}" class="button" /> </div> @@ -71,26 +70,23 @@ {% else %} <div class="comment_wrapper" id="comment-{{ comment['_id'] }}"> {% endif %} + <div class="comment_content"> {% autoescape False %} {{ comment.content_html }} {% endautoescape %} </div> + <div class="comment_author">— <a href="{{ request.urlgen('mediagoblin.user_pages.user_home', - user = comment_author['username']) }}"> - {{ comment_author['username'] }}</a> {% trans %}at{% endtrans %} - <!--</div> - <div class="comment_datetime">--> + user = comment_author['username']) }}"> + {{ comment_author['username'] }}</a> + {% trans %}at{% endtrans %} <a href="{{ request.urlgen('mediagoblin.user_pages.media_home.view_comment', comment = comment['_id'], user = media.uploader().username, media = media._id) }}#comment"> - {{ "%4d-%02d-%02d %02d:%02d"|format(comment.created.year, - comment.created.month, - comment.created.day, - comment.created.hour, - comment.created.minute) }} + {{ comment.created.strftime("%Y-%m-%d %I:%M%p") }} </a> </div> </div> diff --git a/mediagoblin/templates/mediagoblin/user_pages/processing_panel.html b/mediagoblin/templates/mediagoblin/user_pages/processing_panel.html new file mode 100644 index 00000000..abc7efd3 --- /dev/null +++ b/mediagoblin/templates/mediagoblin/user_pages/processing_panel.html @@ -0,0 +1,67 @@ +{# +# 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_content %} + +<h1>{% trans %}Media processing panel{% endtrans %}</h1> + +<p> + {% trans %}You can track the state of media being processed for your gallery here.{% endtrans %} +</p> + +<h2>{% trans %}Media in-processing{% endtrans %}</h2> + +{% if processing_entries.count() %} + <table class="media_panel processing"> + <tr> + <th>Title</th> + <th>When submitted</th> + <th>Status</th> + </tr> + {% for media_entry in processing_entries %} + <tr> + <td>{{ media_entry['title'] }}</td> + <td>{{ media_entry['created'].strftime("%m-%d-%Y %I:%M %p") }}</td> + <td></td> + </tr> + {% endfor %} + </table> +{% else %} + <p><i>{% trans %}No media in-processing{% endtrans %}</i></p> +{% endif %} + +{% if failed_entries.count() %} + <h2>{% trans %}These uploads failed to process:{% endtrans %}</h2> + + <table class="media_panel failed"> + <tr> + <th>Title</th> + <th>When submitted</th> + <th>Reason for failure</th> + </tr> + {% for media_entry in failed_entries %} + <tr> + <td>{{ media_entry['title'] }}</td> + <td>{{ media_entry['created'].strftime("%m-%d-%Y %I:%M %p") }}</td> + <td>{{ media_entry.get_fail_exception().general_message }}</td> + </tr> + {% endfor %} + </table> +{% endif %} +{% endblock %} diff --git a/mediagoblin/templates/mediagoblin/user_pages/user.html b/mediagoblin/templates/mediagoblin/user_pages/user.html index 1115fc56..0214082c 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/user.html +++ b/mediagoblin/templates/mediagoblin/user_pages/user.html @@ -17,6 +17,8 @@ #} {% extends "mediagoblin/base.html" %} +{% from "mediagoblin/utils/object_gallery.html" import object_gallery %} + {% block mediagoblin_head %} <link rel="alternate" type="application/atom+xml" href="{{ request.urlgen( @@ -76,32 +78,79 @@ {%- 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 }}"> - {%- trans %}Edit profile{% endtrans -%} - </a> + {% if not user['url'] and not user['profile'] %} + {% if request.user['_id'] == user['_id'] %} + <div class="grid_6 alpha empty_space"> + <p> + {% trans %}Here's a spot to tell others about yourself.{% endtrans %} + </p> + <a href="{{ request.urlgen('mediagoblin.edit.profile') }}?username={{ + user.username }}" + class="header_submit"> + {%- trans %}Edit profile{% endtrans -%} + </a> + </div> + {% else %} + <div class="grid_6 alpha empty_space"> + <p> + {% trans -%} + This user hasn't filled in their profile (yet). + {%- endtrans %} + </p> + </div> {% 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> + {% else %} + <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 }}"> + {%- trans %}Edit profile{% endtrans -%} + </a> + {% endif %} + </div> + {% endif %} + {% if media_entries.count() %} + <div class="grid_10 omega"> + {{ object_gallery(request, media_entries, pagination, + pagination_base_url=user_gallery_url, col_number=3) }} + {% 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> + {% set feed_url = request.urlgen( + 'mediagoblin.user_pages.atom_feed', + user=user.username) %} + {% include "mediagoblin/utils/feed_link.html" %} + </div> + {% else %} + {% if request.user['_id'] == user['_id'] %} + <div class="grid_10 omega empty_space"> + <p> + {% trans -%} + This is where your media will appear, but you don't seem to have added anything yet. + {%- endtrans %} + </p> + <a class="header_submit" + href="{{ request.urlgen('mediagoblin.submit.start') }}"> + {%- trans %}Add media{% endtrans -%} + </a> + </div> + {% else %} + <div class="grid_10 omega empty_space"> + <p> + {% trans -%} + There doesn't seem to be any media here yet... + {%- endtrans %} + </p> + </div> + {% endif %} + {% endif %} <div class="clear"></div> {% endif %} {% endblock %} diff --git a/mediagoblin/templates/mediagoblin/utils/feed_link.html b/mediagoblin/templates/mediagoblin/utils/feed_link.html new file mode 100644 index 00000000..c4036bf3 --- /dev/null +++ b/mediagoblin/templates/mediagoblin/utils/feed_link.html @@ -0,0 +1,23 @@ +{# +# 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/>. +#} + +<a href="{{ feed_url }}"> + <img src="{{ request.staticdirect('/images/icon_feed.png') }}" + class="media_icon" alt="{% trans %}feed icon{% endtrans %}" /> +</a> +<a href="{{ feed_url }}">{%- trans %}Atom feed{% endtrans -%}</a> diff --git a/mediagoblin/templates/mediagoblin/utils/object_gallery.html b/mediagoblin/templates/mediagoblin/utils/object_gallery.html index 03b85b17..b451946d 100644 --- a/mediagoblin/templates/mediagoblin/utils/object_gallery.html +++ b/mediagoblin/templates/mediagoblin/utils/object_gallery.html @@ -18,15 +18,42 @@ {% from "mediagoblin/utils/pagination.html" import render_pagination %} -{% block object_gallery_content -%} - {% if media_entries and media_entries.count() %} - {% for entry in media_entries %} - <div class="media_thumbnail"> - <a href="{{ entry.url_for_self(request.urlgen) }}"> - <img src="{{ request.app.public_store.file_url( - entry['media_files']['thumb']) }}" /></a> - </div> +{% macro media_grid(request, media_entries, col_number=5) %} + <table class="thumb_gallery"> + {% for row in gridify_cursor(media_entries, col_number) %} + <tr class="thumb_row + {%- if loop.first %} thumb_row_first + {%- elif loop.last %} thumb_row_last{% endif %}"> + {% for entry in row %} + <td class="media_thumbnail thumb_entry + {%- if loop.first %} thumb_entry_first + {%- elif loop.last %} thumb_entry_last{% endif %}"> + <a href="{{ entry.url_for_self(request.urlgen) }}"> + <img src="{{ request.app.public_store.file_url( + entry['media_files']['thumb']) }}" /> + </a> + </td> + {% endfor %} + </tr> {% endfor %} + </table> +{%- endmacro %} + +{# + Render a media gallery with pagination. + + Args: + - request: Request + - media_entries: pymongo cursor of media entries + - pagination: Paginator object + - pagination_base_url: If you want the pagination to point to a + different URL, point it here + - col_number: How many columns per row (default 5) +#} +{% macro object_gallery(request, media_entries, pagination, + pagination_base_url=None, col_number=5) %} + {% if media_entries and media_entries.count() %} + {{ media_grid(request, media_entries, col_number=col_number) }} <div class="clear"></div> {% if pagination_base_url %} {# different url, so set that and don't keep the get params #} @@ -39,4 +66,4 @@ <i>There doesn't seem to be any media here yet...</i> </p> {% endif %} -{% endblock %} +{% endmacro %} diff --git a/mediagoblin/templates/mediagoblin/utils/wtforms.html b/mediagoblin/templates/mediagoblin/utils/wtforms.html index 1d2f8619..2639522a 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 -%} @@ -34,25 +34,6 @@ </div> {%- endmacro %} -{# Generically render a textarea - # ... 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> - {% if field.description -%} - <div class="form_field_description">{{ field.description }}</div> - {%- endif %} - <div class="form_field_input">{{ field(rows=rows, cols=cols) }}</div> - {%- if field.errors -%} - {% for error in field.errors %} - <div class="form_field_error"> - {{ error }} - </div> - {% endfor %} - {%- endif %} - </div> -{%- endmacro %} - {# Auto-render a form as a series of divs #} {% macro render_divs(form) -%} {% for field in form %} @@ -64,7 +45,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_submission.py b/mediagoblin/tests/test_submission.py index a7248255..9ae129cd 100644 --- a/mediagoblin/tests/test_submission.py +++ b/mediagoblin/tests/test_submission.py @@ -156,7 +156,7 @@ class TestSubmission: util.clear_test_template_context() response = self.test_app.post( '/submit/', { - 'title': 'Malicious Upload 2' + 'title': 'Malicious Upload 1' }, upload_files=[( 'file', EVIL_FILE)]) @@ -164,33 +164,46 @@ class TestSubmission: form = context['submit_form'] assert form.file.errors == ['The file doesn\'t seem to be an image!'] - # NOTE: The following 2 tests will fail. These can be uncommented - # after http://bugs.foocorp.net/issues/324 is resolved and - # bad files are handled properly. + # NOTE: The following 2 tests will ultimately fail, but they + # *will* pass the initial form submission step. Instead, + # they'll be caught as failures during the processing step. # Test non-supported file with .jpg extension # ------------------------------------------- - #util.clear_test_template_context() - #response = self.test_app.post( - # '/submit/', { - # 'title': 'Malicious Upload 2' - # }, upload_files=[( - # 'file', EVIL_JPG)]) + util.clear_test_template_context() + response = self.test_app.post( + '/submit/', { + 'title': 'Malicious Upload 2' + }, upload_files=[( + 'file', EVIL_JPG)]) + response.follow() + assert_equal( + urlparse.urlsplit(response.location)[2], + '/u/chris/') - #context = util.TEMPLATE_TEST_CONTEXT['mediagoblin/submit/start.html'] - #form = context['submit_form'] - #assert form.file.errors == ['The file doesn\'t seem to be an image!'] + entry = mg_globals.database.MediaEntry.find_one( + {'title': 'Malicious Upload 2'}) + assert_equal(entry['state'], 'failed') + assert_equal( + entry['fail_error'], + u'mediagoblin.process_media.errors:BadMediaFail') # Test non-supported file with .png extension # ------------------------------------------- - #util.clear_test_template_context() - #response = self.test_app.post( - # '/submit/', { - # 'title': 'Malicious Upload 3' - # }, upload_files=[( - # 'file', EVIL_PNG)]) - - #context = util.TEMPLATE_TEST_CONTEXT['mediagoblin/submit/start.html'] - #form = context['submit_form'] - #assert form.file.errors == ['The file doesn\'t seem to be an image!'] + util.clear_test_template_context() + response = self.test_app.post( + '/submit/', { + 'title': 'Malicious Upload 3' + }, upload_files=[( + 'file', EVIL_PNG)]) + response.follow() + assert_equal( + urlparse.urlsplit(response.location)[2], + '/u/chris/') + entry = mg_globals.database.MediaEntry.find_one( + {'title': 'Malicious Upload 3'}) + assert_equal(entry['state'], 'failed') + assert_equal( + entry['fail_error'], + u'mediagoblin.process_media.errors:BadMediaFail') 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/routing.py b/mediagoblin/user_pages/routing.py index 3be0617d..bf9f12ab 100644 --- a/mediagoblin/user_pages/routing.py +++ b/mediagoblin/user_pages/routing.py @@ -33,4 +33,8 @@ user_routes = [ controller="mediagoblin.user_pages.views:atom_feed"), Route('mediagoblin.user_pages.media_post_comment', '/{user}/m/{media}/comment/add/', - controller="mediagoblin.user_pages.views:media_post_comment")] + controller="mediagoblin.user_pages.views:media_post_comment"), + Route('mediagoblin.user_pages.processing_panel', + '/{user}/panel/', + controller="mediagoblin.user_pages.views:processing_panel"), + ] diff --git a/mediagoblin/user_pages/views.py b/mediagoblin/user_pages/views.py index 85a84db6..3677c134 100644 --- a/mediagoblin/user_pages/views.py +++ b/mediagoblin/user_pages/views.py @@ -1,4 +1,4 @@ -# GNU MediaGoblin -- federated, autonomous media hosting +# MediaGoblin -- federated, autonomous media hosting # Copyright (C) 2011 Free Software Foundation, Inc # # This program is free software: you can redistribute it and/or modify @@ -19,7 +19,8 @@ from webob import exc from mediagoblin import messages from mediagoblin.db.util import DESCENDING, ObjectId from mediagoblin.util import ( - Pagination, render_to_response, redirect, cleaned_markdown_conversion) + Pagination, render_to_response, redirect, cleaned_markdown_conversion, + render_404) from mediagoblin.user_pages import forms as user_forms from mediagoblin.decorators import (uses_pagination, get_user_media_entry, @@ -34,7 +35,7 @@ def user_home(request, page): user = request.db.User.find_one({ 'username': request.matchdict['user']}) if not user: - return exc.HTTPNotFound() + return render_404(request) elif user['status'] != u'active': return render_to_response( request, @@ -50,7 +51,7 @@ def user_home(request, page): #if no data is available, return NotFound if media_entries == None: - return exc.HTTPNotFound() + return render_404(request) user_gallery_url = request.urlgen( 'mediagoblin.user_pages.user_gallery', @@ -71,7 +72,7 @@ def user_gallery(request, page): 'username': request.matchdict['user'], 'status': 'active'}) if not user: - return exc.HTTPNotFound() + return render_404(request) cursor = request.db.MediaEntry.find( {'uploader': user['_id'], @@ -82,7 +83,7 @@ def user_gallery(request, page): #if no data is available, return NotFound if media_entries == None: - return exc.HTTPNotFound() + return render_404(request) return render_to_response( request, @@ -154,7 +155,7 @@ def atom_feed(request): 'username': request.matchdict['user'], 'status': 'active'}) if not user: - return exc.HTTPNotFound() + return render_404(request) cursor = request.db.MediaEntry.find({ 'uploader': user['_id'], @@ -175,3 +176,53 @@ def atom_feed(request): url=entry.url_for_self(request.urlgen)) return feed.get_response() + + +@require_active_login +def processing_panel(request): + """ + Show to the user what media is still in conversion/processing... + and what failed, and why! + """ + # Get the user + user = request.db.User.find_one( + {'username': request.matchdict['user'], + 'status': 'active'}) + + # Make sure the user exists and is active + if not user: + return render_404(request) + elif user['status'] != u'active': + return render_to_response( + request, + 'mediagoblin/user_pages/user.html', + {'user': user}) + + # XXX: Should this be a decorator? + # + # Make sure we have permission to access this user's panel. Only + # admins and this user herself should be able to do so. + if not (user[u'_id'] == request.user[u'_id'] + or request.user.is_admin): + # No? Let's simply redirect to this user's homepage then. + return redirect( + request, 'mediagoblin.user_pages.user_home', + user=request.matchdict['user']) + + # Get media entries which are in-processing + processing_entries = request.db.MediaEntry.find( + {'uploader': user['_id'], + 'state': 'processing'}).sort('created', DESCENDING) + + # Get media entries which have failed to process + failed_entries = request.db.MediaEntry.find( + {'uploader': user['_id'], + 'state': 'failed'}).sort('created', DESCENDING) + + # Render to response + return render_to_response( + request, + 'mediagoblin/user_pages/processing_panel.html', + {'user': user, + 'processing_entries': processing_entries, + 'failed_entries': failed_entries}) diff --git a/mediagoblin/util.py b/mediagoblin/util.py index ed7be841..0b6428da 100644 --- a/mediagoblin/util.py +++ b/mediagoblin/util.py @@ -28,11 +28,13 @@ 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 @@ -94,11 +96,14 @@ def get_jinja_env(template_loader, locale): template_env.install_gettext_callables( mg_globals.translations.ugettext, - mg_globals.translations.ngettext) + mg_globals.translations.ungettext) # All templates will know how to ... # ... fetch all waiting messages and remove them from the queue + # ... construct a grid of thumbnails or other media template_env.globals['fetch_messages'] = messages.fetch_messages + template_env.globals['gridify_list'] = gridify_list + template_env.globals['gridify_cursor'] = gridify_cursor if exists(locale): SETUP_JINJA_ENVS[locale] = template_env @@ -133,9 +138,11 @@ def clear_test_template_context(): TEMPLATE_TEST_CONTEXT = {} -def render_to_response(request, template, context): +def render_to_response(request, template, context, status=200): """Much like Django's shortcut.render()""" - return Response(render_template(request, template, context)) + return Response( + render_template(request, template, context), + status=status) def redirect(request, *args, **kwargs): @@ -341,8 +348,10 @@ def get_locale_from_request(request): accept_lang_matches = request.accept_language.best_matches() # Your routing can explicitly specify a target language - if request.matchdict.has_key('locale'): - target_lang = request.matchdict['locale'] + matchdict = request.matchdict or {} + + if matchdict.has_key('locale'): + target_lang = matchdict['locale'] elif request.session.has_key('target_lang'): target_lang = request.session['target_lang'] # Pull the first acceptable language @@ -494,6 +503,50 @@ def pass_to_ugettext(*args, **kwargs): *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): @@ -582,3 +635,40 @@ class Pagination(object): """ return self.get_page_url_explicit( request.path_info, request.GET, page_no) + + +def gridify_list(this_list, num_cols=5): + """ + Generates a list of lists where each sub-list's length depends on + the number of columns in the list + """ + grid = [] + + # Figure out how many rows we should have + num_rows = int(ceil(float(len(this_list)) / num_cols)) + + for row_num in range(num_rows): + slice_min = row_num * num_cols + slice_max = (row_num + 1) * num_cols + + row = this_list[slice_min:slice_max] + + grid.append(row) + + return grid + + +def gridify_cursor(this_cursor, num_cols=5): + """ + Generates a list of lists where each sub-list's length depends on + the number of columns in the list + """ + return gridify_list(list(this_cursor), num_cols) + + +def render_404(request): + """ + Render a 404. + """ + return render_to_response( + request, 'mediagoblin/404.html', {}, status=400) @@ -1,7 +1,11 @@ [DEFAULT] -debug = true +# Set to true to enable web-based debugging messages and etc. +debug = false -[composite:main] +[pipeline:main] +pipeline = errors routing + +[composite:routing] use = egg:Paste#urlmap / = mediagoblin /mgoblin_media/ = publicstore_serve @@ -28,6 +32,10 @@ beaker.session.key = mediagoblin beaker.session.data_dir = %(here)s/user_dev/beaker/sessions/data beaker.session.lock_dir = %(here)s/user_dev/beaker/sessions/lock +[filter:errors] +use = egg:mediagoblin#errors +debug = false + [server:main] use = egg:Paste#http host = 127.0.0.1 @@ -58,6 +58,9 @@ setup( [paste.app_factory] app = mediagoblin.app:paste_app_factory + [paste.filter_app_factory] + errors = mediagoblin.errormiddleware:mgoblin_error_middleware + [zc.buildout] make_user_dev_dirs = mediagoblin.buildout_recipes:MakeUserDevDirs |