From 93bdab9daad3ae431afd41a2efaefae05a555d88 Mon Sep 17 00:00:00 2001 From: Joar Wandborg Date: Fri, 23 Sep 2011 02:35:57 +0200 Subject: [PATCH 001/302] Multimedia support - Commiting from a not yet finished state - Details below * DONE Initially testing with arista ** DONE Video display templates *** TODO Multi-browser support ** TODO Video thumbnails ** TODO Link to original video ** TODO Video cropping Also contains a lot of "debug" print's --- mediagoblin/db/migrations.py | 8 + mediagoblin/init/celery/__init__.py | 5 + mediagoblin/media_types/__init__.py | 70 +++++ mediagoblin/media_types/image/__init__.py | 28 ++ mediagoblin/media_types/image/processing.py | 207 ++++++++++++++ mediagoblin/media_types/video/__init__.py | 26 ++ mediagoblin/media_types/video/processing.py | 260 ++++++++++++++++++ mediagoblin/storage/cloudfiles.py | 10 +- mediagoblin/submit/views.py | 13 +- .../mediagoblin/media_displays/image.html | 1 + .../mediagoblin/media_displays/video.html | 8 + .../mediagoblin/user_pages/media.html | 30 +- mediagoblin/user_pages/views.py | 6 +- 13 files changed, 649 insertions(+), 23 deletions(-) create mode 100644 mediagoblin/media_types/__init__.py create mode 100644 mediagoblin/media_types/image/__init__.py create mode 100644 mediagoblin/media_types/image/processing.py create mode 100644 mediagoblin/media_types/video/__init__.py create mode 100644 mediagoblin/media_types/video/processing.py create mode 100644 mediagoblin/templates/mediagoblin/media_displays/image.html create mode 100644 mediagoblin/templates/mediagoblin/media_displays/video.html diff --git a/mediagoblin/db/migrations.py b/mediagoblin/db/migrations.py index 755f49c5..01df7208 100644 --- a/mediagoblin/db/migrations.py +++ b/mediagoblin/db/migrations.py @@ -107,3 +107,11 @@ def user_add_forgot_password_token_and_expires(database): {'fp_token_expire': {'$exists': False}}, {'$set': {'fp_token_expire': None}}, multi=True) + + +@RegisterMigration(7) +def media_type_image_to_multimedia_type_image(database): + database['media_entries'].update( + {'media_type': 'image'}, + {'$set': {'media_type': 'mediagoblin.media_types.image'}}, + multi=True) diff --git a/mediagoblin/init/celery/__init__.py b/mediagoblin/init/celery/__init__.py index c58b1305..05c54b05 100644 --- a/mediagoblin/init/celery/__init__.py +++ b/mediagoblin/init/celery/__init__.py @@ -17,8 +17,13 @@ import os import sys +from mediagoblin.media_types import get_media_types + MANDATORY_CELERY_IMPORTS = ['mediagoblin.process_media'] +MANDATORY_CELERY_IMPORTS = [i for i in get_media_types()] + +print(MANDATORY_CELERY_IMPORTS) DEFAULT_SETTINGS_MODULE = 'mediagoblin.init.celery.dummy_settings_module' diff --git a/mediagoblin/media_types/__init__.py b/mediagoblin/media_types/__init__.py new file mode 100644 index 00000000..67dab418 --- /dev/null +++ b/mediagoblin/media_types/__init__.py @@ -0,0 +1,70 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +import os +import sys + +class FileTypeNotSupported(Exception): + pass + +class InvalidFileType(Exception): + pass + +MEDIA_TYPES = [ + 'mediagoblin.media_types.image', + 'mediagoblin.media_types.video'] + + +def get_media_types(): + for media_type in MEDIA_TYPES: + yield media_type + + +def get_media_managers(): + for media_type in get_media_types(): + ''' + FIXME + __import__ returns the lowest-level module. If the plugin is located + outside the conventional plugin module tree, it will not be loaded + properly because of the [...]ugin.media_types. + + We need this if we want to support a separate site-specific plugin + folder. + ''' + try: + __import__(media_type) + except ImportError as e: + raise Exception('ERROR: Could not import {0}: {1}'.format(media_type, e)) + + yield media_type, sys.modules[media_type].MEDIA_MANAGER + +def get_media_manager(_media_type = None): + for media_type, manager in get_media_managers(): + if media_type in _media_type: + return manager + + +def get_media_type_and_manager(filename): + for media_type, manager in get_media_managers(): + if filename.find('.') > 0: + ext = os.path.splitext(filename)[1].lower() + else: + raise InvalidFileType( + 'Could not find any file extension in "{0}"'.format( + filename)) + + if ext[1:] in manager['accepted_extensions']: + return media_type, manager diff --git a/mediagoblin/media_types/image/__init__.py b/mediagoblin/media_types/image/__init__.py new file mode 100644 index 00000000..0cd0383f --- /dev/null +++ b/mediagoblin/media_types/image/__init__.py @@ -0,0 +1,28 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +from mediagoblin.media_types.image.processing import process_media + + +MEDIA_MANAGER = { + "human_readable": "Image", + "processor": process_media, # alternately a string, + # 'mediagoblin.media_types.image.processing'? + "display_template": "mediagoblin/media_displays/image.html", + "default_thumb": "images/media_thumbs/image.jpg", + "accepted_extensions": ["jpg", "jpeg", "png", "gif", "tiff"], + "accepted_mimetypes": [ + "image/jpeg", "image/png", "image/gif", "image/tiff"]} diff --git a/mediagoblin/media_types/image/processing.py b/mediagoblin/media_types/image/processing.py new file mode 100644 index 00000000..2c4ad2b1 --- /dev/null +++ b/mediagoblin/media_types/image/processing.py @@ -0,0 +1,207 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +import Image + +from celery.task import Task +from celery import registry + +from mediagoblin.db.util import ObjectId +from mediagoblin import mg_globals as mgg + +from mediagoblin.util import lazy_pass_to_ugettext as _ + +THUMB_SIZE = 180, 180 +MEDIUM_SIZE = 640, 640 + + +def create_pub_filepath(entry, filename): + return mgg.public_store.get_unique_filepath( + ['media_entries', + unicode(entry['_id']), + filename]) + + +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.') + + +################################ +# 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') + + 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": + thumb = thumb.convert("RGB") + + thumb_filepath = create_pub_filepath(entry, 'thumbnail.jpg') + thumb_file = mgg.public_store.get_file(thumb_filepath, 'w') + + with 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. + medium = Image.open(queued_filename) + medium_processed = False + + if medium.size[0] > MEDIUM_SIZE[0] or medium.size[1] > MEDIUM_SIZE[1]: + medium.thumbnail(MEDIUM_SIZE, Image.ANTIALIAS) + + if medium.mode != "RGB": + medium = medium.convert("RGB") + + medium_filepath = create_pub_filepath(entry, 'medium.jpg') + medium_file = mgg.public_store.get_file(medium_filepath, 'w') + + with medium_file: + medium.save(medium_file, "JPEG", quality=90) + medium_processed = True + + # we have to re-read because unlike PIL, not everything reads + # things in string representation :) + queued_file = file(queued_filename, 'rb') + + with queued_file: + original_filepath = create_pub_filepath(entry, queued_filepath[-1]) + + with mgg.public_store.get_file(original_filepath, 'wb') as original_file: + original_file.write(queued_file.read()) + + mgg.queue_store.delete_file(queued_filepath) + entry['queued_media_file'] = [] + media_files_dict = entry.setdefault('media_files', {}) + media_files_dict['thumb'] = thumb_filepath + media_files_dict['original'] = original_filepath + if medium_processed: + media_files_dict['medium'] = medium_filepath + + # clean up workbench + workbench.destroy_self() diff --git a/mediagoblin/media_types/video/__init__.py b/mediagoblin/media_types/video/__init__.py new file mode 100644 index 00000000..2a36623e --- /dev/null +++ b/mediagoblin/media_types/video/__init__.py @@ -0,0 +1,26 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +from mediagoblin.media_types.video.processing import process_media + + +MEDIA_MANAGER = { + "human_readable": "Video", + "processor": process_media, # alternately a string, + # 'mediagoblin.media_types.image.processing'? + "display_template": "mediagoblin/media_displays/video.html", + "default_thumb": "images/media_thumbs/video.jpg", + "accepted_extensions": ["mp4", "mov", "webm", "avi", "3gp", "3gpp"]} diff --git a/mediagoblin/media_types/video/processing.py b/mediagoblin/media_types/video/processing.py new file mode 100644 index 00000000..94784836 --- /dev/null +++ b/mediagoblin/media_types/video/processing.py @@ -0,0 +1,260 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +import Image +import tempfile + +from celery.task import Task +from celery import registry + +from mediagoblin.db.util import ObjectId +from mediagoblin import mg_globals as mgg + +from mediagoblin.util import lazy_pass_to_ugettext as _ + +import gobject + +import gst +import arista + +from arista.transcoder import TranscoderOptions + +THUMB_SIZE = 180, 180 +MEDIUM_SIZE = 640, 640 +ARISTA_DEVICE_KEY = 'web' + + +loop = None + + +def process_video(entry): + """ + Code to process a video + """ + info = {} + workbench = mgg.workbench_manager.create_workbench() + + queued_filepath = entry['queued_media_file'] + queued_filename = workbench.localized_file( + mgg.queue_store, queued_filepath, + 'source') + + arista.init() + + devices = arista.presets.get() + device = devices[ARISTA_DEVICE_KEY] + + queue = arista.queue.TranscodeQueue() + + info['tmp_file'] = tmp_file = tempfile.NamedTemporaryFile() + + info['medium_filepath'] = medium_filepath = create_pub_filepath(entry, 'video.webm') + + output = tmp_file.name + + uri = 'file://' + queued_filename + + preset = device.presets[device.default] + + opts = TranscoderOptions(uri, preset, output) + + queue.append(opts) + + info['entry'] = entry + + queue.connect("entry-start", entry_start, info) +# queue.connect("entry-pass-setup", entry_pass_setup, options) + queue.connect("entry-error", entry_error, info) + queue.connect("entry-complete", entry_complete, info) + + info['loop'] = loop = gobject.MainLoop() + + loop.run() + + # we have to re-read because unlike PIL, not everything reads + # things in string representation :) + queued_file = file(queued_filename, 'rb') + + with queued_file: + original_filepath = create_pub_filepath(entry, queued_filepath[-1]) + + with mgg.public_store.get_file(original_filepath, 'wb') as original_file: + original_file.write(queued_file.read()) + + mgg.queue_store.delete_file(queued_filepath) + entry['queued_media_file'] = [] + media_files_dict = entry.setdefault('media_files', {}) + media_files_dict['original'] = original_filepath + + # clean up workbench + workbench.destroy_self() + + +def create_pub_filepath(entry, filename): + return mgg.public_store.get_unique_filepath( + ['media_entries', + unicode(entry['_id']), + filename]) + + +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.') + + +################################ +# 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_video(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 entry_start(queue, entry, options): + print(queue, entry, options) + +def entry_complete(queue, entry, info): + entry.transcoder.stop() + gobject.idle_add(info['loop'].quit) + + with info['tmp_file'] as tmp_file: + mgg.public_store.get_file(info['medium_filepath'], 'wb').write( + tmp_file.read()) + info['entry']['media_files']['medium'] = info['medium_filepath'] + + print('\n=== DONE! ===\n') + + print(queue, entry, info) + +def entry_error(queue, entry, options): + print(queue, entry, options) + +def signal_handler(signum, frame): + """ + Handle Ctr-C gracefully and shut down the transcoder. + """ + global interrupted + print + print _("Interrupt caught. Cleaning up... (Ctrl-C to force exit)") + interrupted = True + signal.signal(signal.SIGINT, signal.SIG_DFL) + +def check_interrupted(): + """ + Check whether we have been interrupted by Ctrl-C and stop the + transcoder. + """ + if interrupted: + try: + source = transcoder.pipe.get_by_name("source") + source.send_event(gst.event_new_eos()) + except: + # Something pretty bad happened... just exit! + gobject.idle_add(loop.quit) + + return False + return True diff --git a/mediagoblin/storage/cloudfiles.py b/mediagoblin/storage/cloudfiles.py index b1dd9450..85d52242 100644 --- a/mediagoblin/storage/cloudfiles.py +++ b/mediagoblin/storage/cloudfiles.py @@ -97,8 +97,14 @@ class CloudFilesStorage(StorageInterface): def delete_file(self, filepath): # TODO: Also delete unused directories if empty (safely, with # checks to avoid race conditions). - self.container.delete_object( - self._resolve_filepath(filepath)) + try: + self.container.delete_object( + self._resolve_filepath(filepath)) + except cloudfiles.container.ResponseError: + pass + finally: + pass + def file_url(self, filepath): return '/'.join([ diff --git a/mediagoblin/submit/views.py b/mediagoblin/submit/views.py index e24d78f3..78f52160 100644 --- a/mediagoblin/submit/views.py +++ b/mediagoblin/submit/views.py @@ -28,8 +28,9 @@ from mediagoblin.util import ( 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, mark_entry_failed +from mediagoblin.process_media import mark_entry_failed from mediagoblin.messages import add_message, SUCCESS +from mediagoblin.media_types import get_media_type_and_manager @require_active_login @@ -45,15 +46,15 @@ def submit_start(request): and request.POST['file'].file): submit_form.file.errors.append( _(u'You must provide a file.')) - elif not security.check_filetype(request.POST['file']): - submit_form.file.errors.append( - _(u"The file doesn't seem to be an image!")) else: filename = request.POST['file'].filename + media_type, media_manager = get_media_type_and_manager(filename) + # create entry and save in database entry = request.db.MediaEntry() entry['_id'] = ObjectId() + entry['media_type'] = unicode(media_type) entry['title'] = ( unicode(request.POST['title']) or unicode(splitext(filename)[0])) @@ -62,7 +63,6 @@ def submit_start(request): entry['description_html'] = cleaned_markdown_conversion( entry['description']) - entry['media_type'] = u'image' # heh entry['uploader'] = request.user['_id'] # Process the user's folksonomy "tags" @@ -72,6 +72,7 @@ def submit_start(request): # Generate a slug from the title entry.generate_slug() + # Now store generate the queueing related filename queue_filepath = request.app.queue_store.get_unique_filepath( ['media_entries', @@ -103,7 +104,7 @@ def submit_start(request): # (... don't change entry after this point to avoid race # conditions with changes to the document via processing code) try: - process_media.apply_async( + media_manager['processor'].apply_async( [unicode(entry['_id'])], {}, task_id=task_id) except BaseException as exc: diff --git a/mediagoblin/templates/mediagoblin/media_displays/image.html b/mediagoblin/templates/mediagoblin/media_displays/image.html new file mode 100644 index 00000000..ad60fa94 --- /dev/null +++ b/mediagoblin/templates/mediagoblin/media_displays/image.html @@ -0,0 +1 @@ +{% extends 'mediagoblin/user_pages/media.html' %} diff --git a/mediagoblin/templates/mediagoblin/media_displays/video.html b/mediagoblin/templates/mediagoblin/media_displays/video.html new file mode 100644 index 00000000..37586924 --- /dev/null +++ b/mediagoblin/templates/mediagoblin/media_displays/video.html @@ -0,0 +1,8 @@ +{% extends 'mediagoblin/user_pages/media.html' %} +{% block mediagoblin_media %} + +{% endblock %} diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html index 442bef6d..82a48e7c 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media.html @@ -24,24 +24,26 @@ {% if media %}
- {% set display_media = request.app.public_store.file_url( - media.get_display_media(media.media_files)) %} + {% block mediagoblin_media %} + {% set display_media = request.app.public_store.file_url( + media.get_display_media(media.media_files)) %} - {# if there's a medium file size, that means the medium size - # isn't the original... so link to the original! - #} - {% if media['media_files'].has_key('medium') %} - + {# if there's a medium file size, that means the medium size + # isn't the original... so link to the original! + #} + {% if media['media_files'].has_key('medium') %} + + Image for {{ media.title }} + + {% else %} Image for {{ media.title }} - - {% else %} - Image for {{ media.title }} - {% endif %} + {% endif %} + {% endblock %}

diff --git a/mediagoblin/user_pages/views.py b/mediagoblin/user_pages/views.py index 6a82d718..5458c694 100644 --- a/mediagoblin/user_pages/views.py +++ b/mediagoblin/user_pages/views.py @@ -29,6 +29,8 @@ from mediagoblin.decorators import (uses_pagination, get_user_media_entry, from werkzeug.contrib.atom import AtomFeed +from mediagoblin.media_types import get_media_manager + @uses_pagination def user_home(request, page): @@ -113,9 +115,11 @@ def media_home(request, media, page, **kwargs): comment_form = user_forms.MediaCommentForm(request.POST) + media_template_name = get_media_manager(media['media_type'])['display_template'] + return render_to_response( request, - 'mediagoblin/user_pages/media.html', + media_template_name, {'media': media, 'comments': comments, 'pagination': pagination, From 1f255101f54579760f2238d70dd3aa0b3cd4ba92 Mon Sep 17 00:00:00 2001 From: Joar Wandborg Date: Sat, 24 Sep 2011 02:21:46 +0200 Subject: [PATCH 002/302] Multimedia support - Refractored video processing. --- mediagoblin/media_types/__init__.py | 1 + .../video/presets/web-advanced.json | 505 +++++++++ .../media_types/video/presets/web-flv.png | Bin 0 -> 2234 bytes .../media_types/video/presets/web-webm.svg | 259 +++++ mediagoblin/media_types/video/presets/web.svg | 982 ++++++++++++++++++ mediagoblin/media_types/video/processing.py | 186 ++-- .../static/images/media_thumbs/video.jpg | Bin 0 -> 7278 bytes .../mediagoblin/media_displays/video.html | 8 + 8 files changed, 1875 insertions(+), 66 deletions(-) create mode 100644 mediagoblin/media_types/video/presets/web-advanced.json create mode 100644 mediagoblin/media_types/video/presets/web-flv.png create mode 100644 mediagoblin/media_types/video/presets/web-webm.svg create mode 100644 mediagoblin/media_types/video/presets/web.svg create mode 100644 mediagoblin/static/images/media_thumbs/video.jpg diff --git a/mediagoblin/media_types/__init__.py b/mediagoblin/media_types/__init__.py index 67dab418..6a368cda 100644 --- a/mediagoblin/media_types/__init__.py +++ b/mediagoblin/media_types/__init__.py @@ -51,6 +51,7 @@ def get_media_managers(): yield media_type, sys.modules[media_type].MEDIA_MANAGER + def get_media_manager(_media_type = None): for media_type, manager in get_media_managers(): if media_type in _media_type: diff --git a/mediagoblin/media_types/video/presets/web-advanced.json b/mediagoblin/media_types/video/presets/web-advanced.json new file mode 100644 index 00000000..ce1d22ff --- /dev/null +++ b/mediagoblin/media_types/video/presets/web-advanced.json @@ -0,0 +1,505 @@ +{ + "make": "Generic", + "model": "Web Browser (Advanced)", + "description": "Media for World Wide Web", + "version": "0.1", + "author": { + "name": "Dionisio E Alonso", + "email": "dealonso@gmail.com" + }, + "icon": "file://web.svg", + "default": "WebM 480p", + "presets": [ + { + "name": "H.264 720p", + "extension": "mp4", + "container": "qtmux", + "vcodec": { + "name": "x264enc", + "container": "qtmux", + "width": [ + 960, 1280 + ], + "height": [ + 720, 720 + ], + "rate": [ + 1, 30 + ], + "passes": [ + "pass=qual quantizer=23 subme=6 cabac=0 threads=0" + ] + }, + "acodec": { + "name": "faac", + "container": "qtmux", + "width": [ + 8, 24 + ], + "depth": [ + 8, 24 + ], + "rate": [ + 8000, 96000 + ], + "channels": [ + 1, 2 + ], + "passes": [ + "bitrate=131072 profile=LC" + ] + } + }, + { + "name": "WebM 720p", + "extension": "webm", + "container": "webmmux", + "icon": "file://web-webm.svg", + "vcodec": { + "name": "vp8enc", + "container": "webmmux", + "width": [ + 960, 1280 + ], + "height": [ + 720, 720 + ], + "rate": [ + 1, 30 + ], + "passes": [ + "quality=5.75 threads=%(threads)s speed=2" + ] + }, + "acodec": { + "name": "vorbisenc", + "container": "webmmux", + "width": [ + 8, 32 + ], + "depth": [ + 8, 24 + ], + "rate": [ + 8000, 96000 + ], + "channels": [ + 1, 2 + ], + "passes": [ + "quality=0.3" + ] + } + }, + { + "name": "Flash Video 720p", + "extension": "flv", + "icon": "file://web-flv.png", + "container": "flvmux", + "vcodec": { + "name": "x264enc", + "container": "flvmux", + "width": [ + 960, 1280 + ], + "height": [ + 720, 720 + ], + "rate": [ + 1, 30 + ], + "passes": [ + "pass=qual quantizer=23 subme=6 cabac=0 threads=0" + ] + }, + "acodec": { + "name": "faac", + "container": "flvmux", + "width": [ + 8, 24 + ], + "depth": [ + 8, 24 + ], + "rate": [ + 8000, 96000 + ], + "channels": [ + 1, 2 + ], + "passes": [ + "bitrate=131072 profile=LC" + ] + } + }, + + { + "name": "H.264 576p", + "extension": "mp4", + "container": "qtmux", + "vcodec": { + "name": "x264enc", + "container": "qtmux", + "width": [ + 768, 1024 + ], + "height": [ + 576, 576 + ], + "rate": [ + 1, 30 + ], + "passes": [ + "pass=qual quantizer=23 subme=6 cabac=0 threads=0" + ] + }, + "acodec": { + "name": "faac", + "container": "qtmux", + "width": [ + 8, 24 + ], + "depth": [ + 8, 24 + ], + "rate": [ + 8000, 96000 + ], + "channels": [ + 1, 2 + ], + "passes": [ + "bitrate=131072 profile=LC" + ] + } + }, + { + "name": "WebM 576p", + "extension": "webm", + "container": "webmmux", + "icon": "file://web-webm.svg", + "vcodec": { + "name": "vp8enc", + "container": "webmmux", + "width": [ + 768, 1024 + ], + "height": [ + 576, 576 + ], + "rate": [ + 1, 30 + ], + "passes": [ + "quality=5.75 threads=%(threads)s speed=2" + ] + }, + "acodec": { + "name": "vorbisenc", + "container": "webmmux", + "width": [ + 8, 32 + ], + "depth": [ + 8, 24 + ], + "rate": [ + 8000, 96000 + ], + "channels": [ + 1, 2 + ], + "passes": [ + "quality=0.3" + ] + } + }, + { + "name": "Flash Video 576p", + "extension": "flv", + "icon": "file://web-flv.png", + "container": "flvmux", + "vcodec": { + "name": "x264enc", + "container": "flvmux", + "width": [ + 768, 1024 + ], + "height": [ + 576, 576 + ], + "rate": [ + 1, 30 + ], + "passes": [ + "pass=qual quantizer=23 subme=6 cabac=0 threads=0" + ] + }, + "acodec": { + "name": "faac", + "container": "flvmux", + "width": [ + 8, 24 + ], + "depth": [ + 8, 24 + ], + "rate": [ + 8000, 96000 + ], + "channels": [ + 1, 2 + ], + "passes": [ + "bitrate=131072 profile=LC" + ] + } + }, + + { + "name": "H.264 480p", + "extension": "mp4", + "container": "qtmux", + "vcodec": { + "name": "x264enc", + "container": "qtmux", + "width": [ + 640, 854 + ], + "height": [ + 480, 480 + ], + "rate": [ + 1, 30 + ], + "passes": [ + "pass=qual quantizer=23 subme=6 cabac=0 threads=0" + ] + }, + "acodec": { + "name": "faac", + "container": "qtmux", + "width": [ + 8, 24 + ], + "depth": [ + 8, 24 + ], + "rate": [ + 8000, 96000 + ], + "channels": [ + 1, 2 + ], + "passes": [ + "bitrate=131072 profile=LC" + ] + } + }, + { + "name": "WebM 480p", + "extension": "webm", + "container": "webmmux", + "icon": "file://web-webm.svg", + "vcodec": { + "name": "vp8enc", + "container": "webmmux", + "width": [ + 640, 854 + ], + "height": [ + 480, 480 + ], + "rate": [ + 1, 30 + ], + "passes": [ + "quality=5.75 threads=%(threads)s speed=2" + ] + }, + "acodec": { + "name": "vorbisenc", + "container": "webmmux", + "width": [ + 8, 32 + ], + "depth": [ + 8, 24 + ], + "rate": [ + 8000, 96000 + ], + "channels": [ + 1, 2 + ], + "passes": [ + "quality=0.3" + ] + } + }, + { + "name": "Flash Video 480p", + "extension": "flv", + "icon": "file://web-flv.png", + "container": "flvmux", + "vcodec": { + "name": "x264enc", + "container": "flvmux", + "width": [ + 640, 854 + ], + "height": [ + 480, 480 + ], + "rate": [ + 1, 30 + ], + "passes": [ + "pass=qual quantizer=23 subme=6 cabac=0 threads=0" + ] + }, + "acodec": { + "name": "faac", + "container": "flvmux", + "width": [ + 8, 24 + ], + "depth": [ + 8, 24 + ], + "rate": [ + 8000, 96000 + ], + "channels": [ + 1, 2 + ], + "passes": [ + "bitrate=131072 profile=LC" + ] + } + }, + + { + "name": "H.264 360p", + "extension": "mp4", + "container": "qtmux", + "vcodec": { + "name": "x264enc", + "container": "qtmux", + "width": [ + 480, 640 + ], + "height": [ + 360, 360 + ], + "rate": [ + 1, 30 + ], + "passes": [ + "pass=qual quantizer=23 subme=6 cabac=0 threads=0" + ] + }, + "acodec": { + "name": "faac", + "container": "qtmux", + "width": [ + 8, 24 + ], + "depth": [ + 8, 24 + ], + "rate": [ + 8000, 96000 + ], + "channels": [ + 1, 2 + ], + "passes": [ + "bitrate=131072 profile=LC" + ] + } + }, + { + "name": "WebM 360p", + "extension": "webm", + "container": "webmmux", + "icon": "file://web-webm.svg", + "vcodec": { + "name": "vp8enc", + "container": "webmmux", + "width": [ + 480, 640 + ], + "height": [ + 360, 360 + ], + "rate": [ + 1, 30 + ], + "passes": [ + "quality=5.75 threads=%(threads)s speed=2" + ] + }, + "acodec": { + "name": "vorbisenc", + "container": "webmmux", + "width": [ + 8, 32 + ], + "depth": [ + 8, 24 + ], + "rate": [ + 8000, 96000 + ], + "channels": [ + 1, 2 + ], + "passes": [ + "quality=0.3" + ] + } + }, + { + "name": "Flash Video 360p", + "extension": "flv", + "icon": "file://web-flv.png", + "container": "flvmux", + "vcodec": { + "name": "x264enc", + "container": "flvmux", + "width": [ + 480, 640 + ], + "height": [ + 360, 360 + ], + "rate": [ + 1, 30 + ], + "passes": [ + "pass=qual quantizer=23 subme=6 cabac=0 threads=0" + ] + }, + "acodec": { + "name": "faac", + "container": "flvmux", + "width": [ + 8, 24 + ], + "depth": [ + 8, 24 + ], + "rate": [ + 8000, 96000 + ], + "channels": [ + 1, 2 + ], + "passes": [ + "bitrate=131072 profile=LC" + ] + } + } + ] +} diff --git a/mediagoblin/media_types/video/presets/web-flv.png b/mediagoblin/media_types/video/presets/web-flv.png new file mode 100644 index 0000000000000000000000000000000000000000..b75699f494cc5aefbdfb6c80ec099e434fcfd4de GIT binary patch literal 2234 zcmV;r2u1gaP)|?_Tq&~sV3GZOKpw#papARLcoG3`VgTMQIvv; zAc&Q|Sn=92DpLC()wZ@&M4E<}5REbIRL5ZSWMsh1Hs@{|h$cc2Ip8CQfh$lu z0J4u{n>wJh6yxSzfYe!I$I$uu{2Hunq8N#80AI{Sq=rBaWTFir5K7zxgHr zHK3X67h?ehD3`55AviH0zBr>f*Ojup9g?}WEtoJKtPIKKI>0?rK3^{^V|T=Cp3M*& z#>$QtdI*8&0DP6DLTiYXh6mo?Eu8PS*qyEg(j2(5z{_>Q+gvIv;`q6njY_d2f|fkv zpsYo-v532u2q;y;;t@!5p&4{3?BtlBDvjcRoR&rn_+&C+G8#gy2KAU)t3{fmh)#WX z3cy!s-y>i^=p3HMRWcUhi119BYuEG}8Lk^8lL^Ua#08h_F8sbNC3V*(kY;-JWU^js=8NghX-|Dw!*XFJ*zQFS~WZSZLhu)7-X=YYyJa75nd` zbIHZo3@zwnLey-cMH5kWwd|=hh+ECCH9WYxjVI(`68*NTV_+I%J(8*IJyYHt48 zm)Z8#Ye@QiChO~&>?lIggj6&-7vj60w%AOP2wUMolIQz8SjyoNWDUm}ZY+4<`+c@v zdo_E%^DR0%b};UpD}*UU)TpCW1C+{BH>DI@C`ZtFYOf?9x%Sgs`(+0TuLY69H^o{a zO%iJJbG-Ax&(mGp!DM~I%BnRRprCi^FZ52HV%X~;QRD=@o6*Wvok}1%9EbGYoq@RIP?;H1hQ8`@5UL47r&W z(DtsnnXFUJ7RAQNXvCH`FLBj9cQfe^>{z|qVda_Uc>LoBIrqv6al3RULc*uGt<1u?a_7OUlT*Ua?8UVFMgWjprJaO=otgWt6pPR>2a95so ztZI~L4tSzAaiLVQR9Z=ZVzIr7q3*~SkJ++&7fW~DPSPJ_19?h*>i#eA*ONzR&?OxV zh+D0|zl#`h<0-7rQwbzUkw&Kxuo^4J1PG(ykfjgaLHFVXt9_*u!(NYt8?NI$Z`nhw z+2YKxV;ueAV?=Q+$TlwcfSfL;(n<@MHZ2pmfL&|oB%!@<5lbI=W4BqI~{KN z!~swdjc$iOJoXa~fAwsVa$QMGwZkHpEF7u1e9HQ206>Aiv z!%$+ zqtS7mx&##|qFQWIr>l%og22>>88M&{649j7i*O(|Yvc6|=5{Qy?}5(|#WBfn2td8v z;-%+*$De-vH1*aTMCLJx{943Y_*m%%v-^E^5R+LTp&Z2FB0ZjvP9`KWX8RSpx$7HW zW#OtTt?Qr^N-3WG=0o&1)@XDt@Faym&5)~e*PZOMMuh@r)`7~Vh50uwa^cQ5ap}$P z;Q9~m=XGybwBQA3&&_f8(Pds({uyzrQ=G4YB4{ajuIZ14#dBs5ZK7mu*~*+ZnFQBmvwl#)E>&eOP(GNGASNDCyJSU~azo~T|& zoWcZvQncshSUquqNA5kq*_9OLyh5X`PS6E5NPN|gy;8j>47p%3;ij{&$ zMZ|fEJp9w2vwY}&{{F`kG}~R$pkfrR-~)FHnM1Rb^{O(YpM{WM(~v-x%IcjCtu6DY zC}Oy_>i#=jm@h%gBE1=D%tts-DzAejn3Z&Advk9?08 zAAf?gr(fcgqsRE$@#Bn!eHzU+QB)^&j}lc1k!s77)|4zTBL<+FVF`j#Jo(VWq)Y%s z9My^Ib?WU-u7qNCsiKF#E1OuC3Nc8jxAa;?Y#o@@qIQc&S{7lNZ((1@h)bX>&(ouy zC!IN7cw3A!(x_~jg-UQNP${ac2cjs7*_c}-tM@Tg+FbqZHhZX-%}=B5aur;?KIcpm zz8tH5<_^eKWU$$%QOPUu%q--$f`EVgD6CLE*%lD0#=>)vKS%64@G1fnuNG&44#Au6 z_FkrgEPpQ^XbPVfd++aWes=P4{D*1OUtMK^sl;%9G%0|D*7M0YdsbyzhkyXJ>KEA6 z6hi-3!K?zjSeKgWa^~t}BzH{Zq+*~3br+;67x2_*kQ{*04Rm588}ng + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/mediagoblin/media_types/video/presets/web.svg b/mediagoblin/media_types/video/presets/web.svg new file mode 100644 index 00000000..c0c68244 --- /dev/null +++ b/mediagoblin/media_types/video/presets/web.svg @@ -0,0 +1,982 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Globe + + + Jakub Steiner + + + + + Tuomas Kuosmanen + + + + http://jimmac.musichall.cz + + + globe + international + web + www + internet + network + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mediagoblin/media_types/video/processing.py b/mediagoblin/media_types/video/processing.py index 94784836..4cae1fd8 100644 --- a/mediagoblin/media_types/video/processing.py +++ b/mediagoblin/media_types/video/processing.py @@ -16,6 +16,7 @@ import Image import tempfile +import pkg_resources from celery.task import Task from celery import registry @@ -25,10 +26,14 @@ from mediagoblin import mg_globals as mgg from mediagoblin.util import lazy_pass_to_ugettext as _ +import mediagoblin.media_types.video + import gobject +gobject.threads_init() import gst import arista +import logging from arista.transcoder import TranscoderOptions @@ -38,12 +43,17 @@ ARISTA_DEVICE_KEY = 'web' loop = None +logger = logging.getLogger(__name__) +logging.basicConfig() +logger.setLevel(logging.DEBUG) def process_video(entry): """ Code to process a video """ + global loop + loop = None info = {} workbench = mgg.workbench_manager.create_workbench() @@ -54,8 +64,11 @@ def process_video(entry): arista.init() - devices = arista.presets.get() - device = devices[ARISTA_DEVICE_KEY] + + web_advanced_preset = pkg_resources.resource_filename( + __name__, + 'presets/web-advanced.json') + device = arista.presets.load(web_advanced_preset) queue = arista.queue.TranscodeQueue() @@ -69,38 +82,127 @@ def process_video(entry): preset = device.presets[device.default] + logger.debug('preset: {0}'.format(preset)) + opts = TranscoderOptions(uri, preset, output) queue.append(opts) info['entry'] = entry - queue.connect("entry-start", entry_start, info) -# queue.connect("entry-pass-setup", entry_pass_setup, options) - queue.connect("entry-error", entry_error, info) - queue.connect("entry-complete", entry_complete, info) + queue.connect("entry-start", _transcoding_start, info) + queue.connect("entry-pass-setup", _transcoding_pass_setup, info) + queue.connect("entry-error", _transcoding_error, info) + queue.connect("entry-complete", _transcoding_complete, info) info['loop'] = loop = gobject.MainLoop() + info['queued_filename'] = queued_filename + info['queued_filepath'] = queued_filepath + info['workbench'] = workbench + + logger.debug('info: {0}'.format(info)) loop.run() + + ''' + try: + #thumb = Image.open(mediagoblin.media_types.video.MEDIA_MANAGER['default_thumb']) + except IOError: + raise BadMediaFail() - # we have to re-read because unlike PIL, not everything reads - # things in string representation :) - queued_file = file(queued_filename, 'rb') + thumb.thumbnail(THUMB_SIZE, Image.ANTIALIAS) + # ensure color mode is compatible with jpg + if thumb.mode != "RGB": + thumb = thumb.convert("RGB") - with queued_file: - original_filepath = create_pub_filepath(entry, queued_filepath[-1]) + thumb_filepath = create_pub_filepath(entry, 'thumbnail.jpg') + thumb_file = mgg.public_store.get_file(thumb_filepath, 'w') - with mgg.public_store.get_file(original_filepath, 'wb') as original_file: - original_file.write(queued_file.read()) + with thumb_file: + thumb.save(thumb_file, "JPEG", quality=90) + ''' - mgg.queue_store.delete_file(queued_filepath) - entry['queued_media_file'] = [] - media_files_dict = entry.setdefault('media_files', {}) - media_files_dict['original'] = original_filepath +def __close_processing(queue, qentry, info, error=False): + ''' + Update MediaEntry, move files, handle errors + ''' + if not error: + qentry.transcoder.stop() + gobject.idle_add(info['loop'].quit) + info['loop'].quit() + + print('\n-> Saving video...\n') + + with info['tmp_file'] as tmp_file: + mgg.public_store.get_file(info['medium_filepath'], 'wb').write( + tmp_file.read()) + info['entry']['media_files']['medium'] = info['medium_filepath'] + + print('\n=== DONE! ===\n') + + # we have to re-read because unlike PIL, not everything reads + # things in string representation :) + queued_file = file(info['queued_filename'], 'rb') + + with queued_file: + original_filepath = create_pub_filepath(info['entry'], info['queued_filepath'][-1]) + + with mgg.public_store.get_file(original_filepath, 'wb') as original_file: + original_file.write(queued_file.read()) + + mgg.queue_store.delete_file(info['queued_filepath']) + info['entry']['queued_media_file'] = [] + media_files_dict = info['entry'].setdefault('media_files', {}) + media_files_dict['original'] = original_filepath + # media_files_dict['thumb'] = thumb_filepath + + info['entry']['state'] = u'processed' + info['entry'].save() + + else: + qentry.transcoder.stop() + gobject.idle_add(info['loop'].quit) + info['loop'].quit() + info['entry']['state'] = u'failed' + info['entry'].save() # clean up workbench - workbench.destroy_self() + info['workbench'].destroy_self() + + +def _transcoding_start(queue, qentry, info): + logger.info('-> Starting transcoding') + logger.debug(queue, qentry, info) + +def _transcoding_complete(*args): + __close_processing(*args) + print(args) + +def _transcoding_error(*args): + logger.info('-> Error') + __close_processing(*args, error=True) + logger.debug(*args) + +def _transcoding_pass_setup(queue, qentry, options): + logger.info('-> Pass setup') + logger.debug(queue, qentry, options) + + +def check_interrupted(): + """ + Check whether we have been interrupted by Ctrl-C and stop the + transcoder. + """ + if interrupted: + try: + source = transcoder.pipe.get_by_name("source") + source.send_event(gst.event_new_eos()) + except: + # Something pretty bad happened... just exit! + gobject.idle_add(loop.quit) + + return False + return True def create_pub_filepath(entry, filename): @@ -161,9 +263,6 @@ class ProcessMedia(Task): 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. @@ -213,48 +312,3 @@ def mark_entry_failed(entry_id, exc): u'fail_error': None, u'fail_metadata': {}}}) - -def entry_start(queue, entry, options): - print(queue, entry, options) - -def entry_complete(queue, entry, info): - entry.transcoder.stop() - gobject.idle_add(info['loop'].quit) - - with info['tmp_file'] as tmp_file: - mgg.public_store.get_file(info['medium_filepath'], 'wb').write( - tmp_file.read()) - info['entry']['media_files']['medium'] = info['medium_filepath'] - - print('\n=== DONE! ===\n') - - print(queue, entry, info) - -def entry_error(queue, entry, options): - print(queue, entry, options) - -def signal_handler(signum, frame): - """ - Handle Ctr-C gracefully and shut down the transcoder. - """ - global interrupted - print - print _("Interrupt caught. Cleaning up... (Ctrl-C to force exit)") - interrupted = True - signal.signal(signal.SIGINT, signal.SIG_DFL) - -def check_interrupted(): - """ - Check whether we have been interrupted by Ctrl-C and stop the - transcoder. - """ - if interrupted: - try: - source = transcoder.pipe.get_by_name("source") - source.send_event(gst.event_new_eos()) - except: - # Something pretty bad happened... just exit! - gobject.idle_add(loop.quit) - - return False - return True diff --git a/mediagoblin/static/images/media_thumbs/video.jpg b/mediagoblin/static/images/media_thumbs/video.jpg new file mode 100644 index 0000000000000000000000000000000000000000..841dc796fda777f8dcf72ed90ebe52c539c77f0a GIT binary patch literal 7278 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 literal 0 HcmV?d00001 diff --git a/mediagoblin/templates/mediagoblin/media_displays/video.html b/mediagoblin/templates/mediagoblin/media_displays/video.html index 37586924..22b19240 100644 --- a/mediagoblin/templates/mediagoblin/media_displays/video.html +++ b/mediagoblin/templates/mediagoblin/media_displays/video.html @@ -5,4 +5,12 @@ media['media_files']['medium']) }}" type='video/webm; codecs="vp8, vorbis"' /> + {% if 'original' in media.media_files %} + + {%- trans -%} + Original + {%- endtrans -%} + + {% endif %} {% endblock %} From 81291bbb896d04fee66b9482f479b3fc6e6e07f5 Mon Sep 17 00:00:00 2001 From: Joar Wandborg Date: Wed, 28 Sep 2011 21:00:33 +0200 Subject: [PATCH 003/302] Added arista to install requires --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index 06626926..7417fb97 100644 --- a/setup.py +++ b/setup.py @@ -61,6 +61,7 @@ setup( 'ConfigObj', 'Markdown', 'python-cloudfiles', + 'arista', ## For now we're expecting that users will install this from ## their package managers. # 'lxml', From 62be795e9141f951a92d5c44a974db9875df197d Mon Sep 17 00:00:00 2001 From: Joar Wandborg Date: Thu, 29 Sep 2011 00:57:07 +0200 Subject: [PATCH 004/302] Renamed video.presets => video.devices --- .../video/{presets => devices}/web-advanced.json | 0 .../video/{presets => devices}/web-flv.png | Bin .../video/{presets => devices}/web-webm.svg | 0 .../media_types/video/{presets => devices}/web.svg | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename mediagoblin/media_types/video/{presets => devices}/web-advanced.json (100%) rename mediagoblin/media_types/video/{presets => devices}/web-flv.png (100%) rename mediagoblin/media_types/video/{presets => devices}/web-webm.svg (100%) rename mediagoblin/media_types/video/{presets => devices}/web.svg (100%) diff --git a/mediagoblin/media_types/video/presets/web-advanced.json b/mediagoblin/media_types/video/devices/web-advanced.json similarity index 100% rename from mediagoblin/media_types/video/presets/web-advanced.json rename to mediagoblin/media_types/video/devices/web-advanced.json diff --git a/mediagoblin/media_types/video/presets/web-flv.png b/mediagoblin/media_types/video/devices/web-flv.png similarity index 100% rename from mediagoblin/media_types/video/presets/web-flv.png rename to mediagoblin/media_types/video/devices/web-flv.png diff --git a/mediagoblin/media_types/video/presets/web-webm.svg b/mediagoblin/media_types/video/devices/web-webm.svg similarity index 100% rename from mediagoblin/media_types/video/presets/web-webm.svg rename to mediagoblin/media_types/video/devices/web-webm.svg diff --git a/mediagoblin/media_types/video/presets/web.svg b/mediagoblin/media_types/video/devices/web.svg similarity index 100% rename from mediagoblin/media_types/video/presets/web.svg rename to mediagoblin/media_types/video/devices/web.svg From 243c3843bd574129caa7663e25d1a843b2d2dd30 Mon Sep 17 00:00:00 2001 From: Nathan Yergler Date: Sat, 1 Oct 2011 15:10:02 -0700 Subject: [PATCH 005/302] Whitespace and formatting cleanup. * Removed trailing whitespace * Line length < 80 where possible * Honor conventions on number of blank lines * Honor conventions about spaces around :, = --- mediagoblin/app.py | 3 +- mediagoblin/auth/forms.py | 8 ++--- mediagoblin/auth/lib.py | 3 +- mediagoblin/auth/routing.py | 3 +- mediagoblin/auth/views.py | 3 +- mediagoblin/db/__init__.py | 2 +- mediagoblin/db/indexes.py | 5 +-- mediagoblin/db/migrations.py | 2 +- mediagoblin/db/models.py | 35 ++++++++++---------- mediagoblin/db/open.py | 2 +- mediagoblin/db/util.py | 5 +-- mediagoblin/decorators.py | 2 +- mediagoblin/edit/__init__.py | 2 -- mediagoblin/edit/views.py | 2 +- mediagoblin/gmg_commands/__init__.py | 3 +- mediagoblin/gmg_commands/import_export.py | 7 ++-- mediagoblin/gmg_commands/migrate.py | 4 +-- mediagoblin/gmg_commands/users.py | 7 ++-- mediagoblin/init/__init__.py | 18 +++++++---- mediagoblin/init/celery/__init__.py | 2 +- mediagoblin/init/celery/from_celery.py | 2 +- mediagoblin/init/config.py | 2 +- mediagoblin/listings/routing.py | 1 - mediagoblin/listings/views.py | 3 +- mediagoblin/messages.py | 2 ++ mediagoblin/middleware/noop.py | 1 + mediagoblin/process_media/__init__.py | 18 ++++++----- mediagoblin/process_media/errors.py | 9 +++--- mediagoblin/storage/cloudfiles.py | 1 + mediagoblin/submit/__init__.py | 2 -- mediagoblin/submit/security.py | 2 +- mediagoblin/submit/views.py | 16 ++++++---- mediagoblin/user_pages/__init__.py | 2 -- mediagoblin/user_pages/views.py | 13 +++++--- mediagoblin/util.py | 39 +++++++++++++---------- mediagoblin/views.py | 1 + mediagoblin/workbench.py | 4 ++- setup.py | 12 +++---- 38 files changed, 135 insertions(+), 113 deletions(-) diff --git a/mediagoblin/app.py b/mediagoblin/app.py index dd5f0b89..9bbccf24 100644 --- a/mediagoblin/app.py +++ b/mediagoblin/app.py @@ -91,7 +91,7 @@ class MediaGoblinApp(object): # object. ####################################################### - setup_globals(app = self) + setup_globals(app=self) # Workbench *currently* only used by celery, so this only # matters in always eager mode :) @@ -101,7 +101,6 @@ class MediaGoblinApp(object): self.middleware = [util.import_component(m)(self) for m in middleware.ENABLED_MIDDLEWARE] - def __call__(self, environ, start_response): request = Request(environ) diff --git a/mediagoblin/auth/forms.py b/mediagoblin/auth/forms.py index 6339b4a3..aadb5888 100644 --- a/mediagoblin/auth/forms.py +++ b/mediagoblin/auth/forms.py @@ -59,9 +59,10 @@ class ForgotPassForm(wtforms.Form): 'Username or email', [wtforms.validators.Required()]) - def validate_username(form,field): - if not (re.match(r'^\w+$',field.data) or - re.match(r'^.+@[^.].*\.[a-z]{2,10}$',field.data, re.IGNORECASE)): + def validate_username(form, field): + if not (re.match(r'^\w+$', field.data) or + re.match(r'^.+@[^.].*\.[a-z]{2,10}$', field.data, + re.IGNORECASE)): raise wtforms.ValidationError(u'Incorrect input') @@ -82,4 +83,3 @@ class ChangePassForm(wtforms.Form): token = wtforms.HiddenField( '', [wtforms.validators.Required()]) - diff --git a/mediagoblin/auth/lib.py b/mediagoblin/auth/lib.py index d7d351a5..0ecccbb5 100644 --- a/mediagoblin/auth/lib.py +++ b/mediagoblin/auth/lib.py @@ -93,6 +93,7 @@ EMAIL_VERIFICATION_TEMPLATE = ( u"http://{host}{uri}?" u"userid={userid}&token={verification_key}") + def send_verification_email(user, request): """ Send the verification email to users to activate their accounts. @@ -127,6 +128,7 @@ EMAIL_FP_VERIFICATION_TEMPLATE = ( u"http://{host}{uri}?" u"userid={userid}&token={fp_verification_key}") + def send_fp_verification_email(user, request): """ Send the verification email to users to change their password. @@ -150,4 +152,3 @@ def send_fp_verification_email(user, request): [user['email']], 'GNU MediaGoblin - Change forgotten password!', rendered_email) - diff --git a/mediagoblin/auth/routing.py b/mediagoblin/auth/routing.py index 912d89fa..365ccfaa 100644 --- a/mediagoblin/auth/routing.py +++ b/mediagoblin/auth/routing.py @@ -33,7 +33,8 @@ auth_routes = [ controller='mediagoblin.views:simple_template_render'), Route('mediagoblin.auth.forgot_password', '/forgot_password/', controller='mediagoblin.auth.views:forgot_password'), - Route('mediagoblin.auth.verify_forgot_password', '/forgot_password/verify/', + Route('mediagoblin.auth.verify_forgot_password', + '/forgot_password/verify/', controller='mediagoblin.auth.views:verify_forgot_password'), Route('mediagoblin.auth.fp_changed_success', '/forgot_password/changed_success/', diff --git a/mediagoblin/auth/views.py b/mediagoblin/auth/views.py index f67f0588..afcfcf1e 100644 --- a/mediagoblin/auth/views.py +++ b/mediagoblin/auth/views.py @@ -233,8 +233,7 @@ def forgot_password(request): request, 'mediagoblin.user_pages.user_home', user=user['username']) - - # do not reveal whether or not there is a matching user, just move along + # do not reveal whether or not there is a matching user return redirect(request, 'mediagoblin.auth.fp_email_sent') return render_to_response( diff --git a/mediagoblin/db/__init__.py b/mediagoblin/db/__init__.py index c5124b1a..27e8a90f 100644 --- a/mediagoblin/db/__init__.py +++ b/mediagoblin/db/__init__.py @@ -23,7 +23,7 @@ Database Abstraction/Wrapper Layer pymongo. Read beow for why, but note that nobody is actually doing this and there's no proof that we'll ever support more than MongoDB... it would be a huge amount of work to do so. - + If you really want to prove that possible, jump on IRC and talk to us about making such a branch. In the meanwhile, it doesn't hurt to have things as they are... if it ever makes it hard for us to diff --git a/mediagoblin/db/indexes.py b/mediagoblin/db/indexes.py index 75394a31..1dd73f2b 100644 --- a/mediagoblin/db/indexes.py +++ b/mediagoblin/db/indexes.py @@ -93,8 +93,9 @@ MEDIAENTRY_INDEXES = { ('created', DESCENDING)]}, 'state_uploader_tags_created': { - # Indexing on processed?, media uploader, associated tags, and timestamp - # Used for showing media items matching a tag search, most recent first. + # Indexing on processed?, media uploader, associated tags, and + # timestamp Used for showing media items matching a tag + # search, most recent first. 'index': [('state', ASCENDING), ('uploader', ASCENDING), ('tags.slug', DESCENDING), diff --git a/mediagoblin/db/migrations.py b/mediagoblin/db/migrations.py index 755f49c5..28bb62fc 100644 --- a/mediagoblin/db/migrations.py +++ b/mediagoblin/db/migrations.py @@ -87,7 +87,7 @@ def mediaentry_add_fail_error_and_metadata(database): {'fail_error': {'$exists': False}}, {'$set': {'fail_error': None}}, multi=True) - + collection.update( {'fail_metadata': {'$exists': False}}, {'$set': {'fail_metadata': {}}}, diff --git a/mediagoblin/db/models.py b/mediagoblin/db/models.py index bbddada6..42db3f83 100644 --- a/mediagoblin/db/models.py +++ b/mediagoblin/db/models.py @@ -14,7 +14,8 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -import datetime, uuid +import datetime +import uuid from mongokit import Document @@ -69,17 +70,17 @@ class User(Document): 'username': unicode, 'email': unicode, 'created': datetime.datetime, - 'plugin_data': dict, # plugins can dump stuff here. + 'plugin_data': dict, # plugins can dump stuff here. 'pw_hash': unicode, 'email_verified': bool, 'status': unicode, 'verification_key': unicode, 'is_admin': bool, - 'url' : unicode, - 'bio' : unicode, # May contain markdown - 'bio_html': unicode, # May contain plaintext, or HTML - 'fp_verification_key': unicode, # forgotten password verification key - 'fp_token_expire': datetime.datetime + 'url': unicode, + 'bio': unicode, # May contain markdown + 'bio_html': unicode, # May contain plaintext, or HTML + 'fp_verification_key': unicode, # forgotten password verification key + 'fp_token_expire': datetime.datetime, } required_fields = ['username', 'created', 'pw_hash', 'email'] @@ -174,8 +175,8 @@ class MediaEntry(Document): critical to this piece of media but may be usefully relevant to people viewing the work. (currently unused.) - - fail_error: path to the exception raised - - fail_metadata: + - fail_error: path to the exception raised + - fail_metadata: """ __collection__ = 'media_entries' @@ -184,11 +185,11 @@ class MediaEntry(Document): 'title': unicode, 'slug': unicode, 'created': datetime.datetime, - 'description': unicode, # May contain markdown/up - 'description_html': unicode, # May contain plaintext, or HTML + 'description': unicode, # May contain markdown/up + 'description_html': unicode, # May contain plaintext, or HTML 'media_type': unicode, - 'media_data': dict, # extra data relevant to this media_type - 'plugin_data': dict, # plugins can dump stuff here. + 'media_data': dict, # extra data relevant to this media_type + 'plugin_data': dict, # plugins can dump stuff here. 'tags': [dict], 'state': unicode, @@ -220,7 +221,8 @@ class MediaEntry(Document): return self.db.MediaComment.find({ 'media_entry': self['_id']}).sort('created', DESCENDING) - def get_display_media(self, media_map, fetch_order=DISPLAY_IMAGE_FETCHING_ORDER): + def get_display_media(self, media_map, + fetch_order=DISPLAY_IMAGE_FETCHING_ORDER): """ Find the best media for display. @@ -273,7 +275,7 @@ class MediaEntry(Document): """ Provide a url to the previous entry from this user, if there is one """ - cursor = self.db.MediaEntry.find({'_id' : {"$gt": self['_id']}, + cursor = self.db.MediaEntry.find({'_id': {"$gt": self['_id']}, 'uploader': self['uploader'], 'state': 'processed'}).sort( '_id', ASCENDING).limit(1) @@ -286,7 +288,7 @@ class MediaEntry(Document): """ Provide a url to the next entry from this user, if there is one """ - cursor = self.db.MediaEntry.find({'_id' : {"$lt": self['_id']}, + cursor = self.db.MediaEntry.find({'_id': {"$lt": self['_id']}, 'uploader': self['uploader'], 'state': 'processed'}).sort( '_id', DESCENDING).limit(1) @@ -353,4 +355,3 @@ def register_models(connection): Register all models in REGISTER_MODELS with this connection. """ connection.register(REGISTER_MODELS) - diff --git a/mediagoblin/db/open.py b/mediagoblin/db/open.py index e73b6258..e677ba12 100644 --- a/mediagoblin/db/open.py +++ b/mediagoblin/db/open.py @@ -29,7 +29,7 @@ def connect_database_from_config(app_config, use_pymongo=False): port = app_config.get('db_port') if port: port = asint(port) - + if use_pymongo: connection = pymongo.Connection( app_config.get('db_host'), port) diff --git a/mediagoblin/db/util.py b/mediagoblin/db/util.py index 84a6cbce..38f0233f 100644 --- a/mediagoblin/db/util.py +++ b/mediagoblin/db/util.py @@ -118,11 +118,12 @@ def remove_deprecated_indexes(database, deprecated_indexes=DEPRECATED_INDEXES): ################# # The default migration registry... -# +# # Don't set this yourself! RegisterMigration will automatically fill # this with stuff via decorating methods in migrations.py -class MissingCurrentMigration(Exception): pass +class MissingCurrentMigration(Exception): + pass MIGRATIONS = {} diff --git a/mediagoblin/decorators.py b/mediagoblin/decorators.py index 7d5978fc..204ac47a 100644 --- a/mediagoblin/decorators.py +++ b/mediagoblin/decorators.py @@ -119,6 +119,7 @@ def get_user_media_entry(controller): return _make_safe(wrapper, controller) + def get_media_entry_by_id(controller): """ Pass in a MediaEntry based off of a url component @@ -138,4 +139,3 @@ def get_media_entry_by_id(controller): return controller(request, media=media, *args, **kwargs) return _make_safe(wrapper, controller) - diff --git a/mediagoblin/edit/__init__.py b/mediagoblin/edit/__init__.py index 576bd0f5..ba347c69 100644 --- a/mediagoblin/edit/__init__.py +++ b/mediagoblin/edit/__init__.py @@ -13,5 +13,3 @@ # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . - - diff --git a/mediagoblin/edit/views.py b/mediagoblin/edit/views.py index 15edfdd6..d15461c0 100644 --- a/mediagoblin/edit/views.py +++ b/mediagoblin/edit/views.py @@ -119,7 +119,7 @@ def edit_attachments(request, media): name=request.POST['attachment_name'] \ or request.POST['attachment_file'].filename, filepath=attachment_public_filepath, - created=datetime.utcnow() + created=datetime.utcnow(), )) media.save() diff --git a/mediagoblin/gmg_commands/__init__.py b/mediagoblin/gmg_commands/__init__.py index 0071c65b..b3f69ccc 100644 --- a/mediagoblin/gmg_commands/__init__.py +++ b/mediagoblin/gmg_commands/__init__.py @@ -28,7 +28,7 @@ SUBCOMMAND_MAP = { 'setup': 'mediagoblin.gmg_commands.migrate:migrate_parser_setup', 'func': 'mediagoblin.gmg_commands.migrate:migrate', 'help': 'Apply all unapplied bulk migrations to the database'}, - 'adduser':{ + 'adduser': { 'setup': 'mediagoblin.gmg_commands.users:adduser_parser_setup', 'func': 'mediagoblin.gmg_commands.users:adduser', 'help': 'Creates an user'}, @@ -80,4 +80,3 @@ def main_cli(): if __name__ == '__main__': main_cli() - diff --git a/mediagoblin/gmg_commands/import_export.py b/mediagoblin/gmg_commands/import_export.py index 05edbfc8..962e545c 100644 --- a/mediagoblin/gmg_commands/import_export.py +++ b/mediagoblin/gmg_commands/import_export.py @@ -91,7 +91,7 @@ def _import_database(db, args): args.mongorestore_path, '-d', db.name, os.path.join(args._cache_path['database'], db.name)]) - + p.wait() _log.info('...Database imported') @@ -229,7 +229,8 @@ def env_export(args): ''' if args.cache_path: if os.path.exists(args.cache_path): - _log.error('The cache directory must not exist before you run this script') + _log.error('The cache directory must not exist ' + 'before you run this script') _log.error('Cache directory: {0}'.format(args.cache_path)) return False @@ -245,7 +246,7 @@ def env_export(args): globa_config, app_config = setup_global_and_app_config(args.conf_file) setup_storage() - + connection, db = setup_connection_and_db_from_config( app_config, use_pymongo=True) diff --git a/mediagoblin/gmg_commands/migrate.py b/mediagoblin/gmg_commands/migrate.py index 1a597188..e6dd6f78 100644 --- a/mediagoblin/gmg_commands/migrate.py +++ b/mediagoblin/gmg_commands/migrate.py @@ -55,13 +55,13 @@ def migrate(args): for collection, index_name in removed_indexes: print "Removed index '%s' in collection '%s'" % ( index_name, collection) - + # Migrate print "\n== Applying migrations... ==" migration_manager.migrate_new( pre_callback=_print_started_migration, post_callback=_print_finished_migration) - + # Add new indexes print "\n== Adding new indexes... ==" new_indexes = db_util.add_new_indexes(db) diff --git a/mediagoblin/gmg_commands/users.py b/mediagoblin/gmg_commands/users.py index 5421907d..3fda0e32 100644 --- a/mediagoblin/gmg_commands/users.py +++ b/mediagoblin/gmg_commands/users.py @@ -41,7 +41,7 @@ def adduser(args): db = mg_globals.database users_with_username = \ db.User.find({ - 'username': args.username.lower() + 'username': args.username.lower(), }).count() if users_with_username: @@ -74,7 +74,7 @@ def makeadmin(args): db = mg_globals.database - user = db.User.one({'username':unicode(args.username.lower())}) + user = db.User.one({'username': unicode(args.username.lower())}) if user: user['is_admin'] = True user.save() @@ -100,11 +100,10 @@ def changepw(args): db = mg_globals.database - user = db.User.one({'username':unicode(args.username.lower())}) + user = db.User.one({'username': unicode(args.username.lower())}) if user: user['pw_hash'] = auth_lib.bcrypt_gen_password_hash(args.password) user.save() print 'Password successfully changed' else: print 'The user doesn\'t exist' - diff --git a/mediagoblin/init/__init__.py b/mediagoblin/init/__init__.py index b7f52595..f21e2fdd 100644 --- a/mediagoblin/init/__init__.py +++ b/mediagoblin/init/__init__.py @@ -29,8 +29,12 @@ from mediagoblin.workbench import WorkbenchManager from mediagoblin.storage import storage_system_from_config -class Error(Exception): pass -class ImproperlyConfigured(Error): pass +class Error(Exception): + pass + + +class ImproperlyConfigured(Error): + pass def setup_global_and_app_config(config_path): @@ -76,8 +80,8 @@ def setup_database(): "in fact they appear to be from the future?!") setup_globals( - db_connection = connection, - database = db) + db_connection=connection, + database=db) return connection, db @@ -126,8 +130,8 @@ def setup_storage(): queue_store = storage_system_from_config(global_config[key_long]) setup_globals( - public_store = public_store, - queue_store = queue_store) + public_store=public_store, + queue_store=queue_store) return public_store, queue_store @@ -137,7 +141,7 @@ def setup_workbench(): workbench_manager = WorkbenchManager(app_config['workbench_path']) - setup_globals(workbench_manager = workbench_manager) + setup_globals(workbench_manager=workbench_manager) def setup_beaker_cache(): diff --git a/mediagoblin/init/celery/__init__.py b/mediagoblin/init/celery/__init__.py index c58b1305..21ce1d39 100644 --- a/mediagoblin/init/celery/__init__.py +++ b/mediagoblin/init/celery/__init__.py @@ -84,6 +84,6 @@ def setup_celery_from_config(app_config, global_config, for key, value in celery_settings.iteritems(): setattr(this_module, key, value) - + if set_environ: os.environ['CELERY_CONFIG_MODULE'] = settings_module diff --git a/mediagoblin/init/celery/from_celery.py b/mediagoblin/init/celery/from_celery.py index 3e5adb98..05669b67 100644 --- a/mediagoblin/init/celery/from_celery.py +++ b/mediagoblin/init/celery/from_celery.py @@ -44,7 +44,7 @@ def setup_self(check_environ_for_conf=True, module_name=OUR_MODULENAME, if not os.path.exists(mgoblin_conf_file): raise IOError( "MEDIAGOBLIN_CONFIG not set or file does not exist") - + # By setting the environment variable here we should ensure that # this is the module that gets set up. os.environ['CELERY_CONFIG_MODULE'] = module_name diff --git a/mediagoblin/init/config.py b/mediagoblin/init/config.py index 029a0956..ae232e91 100644 --- a/mediagoblin/init/config.py +++ b/mediagoblin/init/config.py @@ -73,7 +73,7 @@ def read_mediagoblin_config(config_path, config_spec=CONFIG_SPEC_PATH): # For now the validator just works with the default functions, # but in the future if we want to add additional validation/configuration # functions we'd add them to validator.functions here. - # + # # See also: # http://www.voidspace.org.uk/python/validate.html#adding-functions validator = Validator() diff --git a/mediagoblin/listings/routing.py b/mediagoblin/listings/routing.py index b72bd015..234f2595 100644 --- a/mediagoblin/listings/routing.py +++ b/mediagoblin/listings/routing.py @@ -25,4 +25,3 @@ tag_routes = [ Route('mediagoblin.listings.tag_atom_feed', "/{tag}/atom/", controller="mediagoblin.listings.views:tag_atom_feed"), ] - diff --git a/mediagoblin/listings/views.py b/mediagoblin/listings/views.py index b3384eb4..2d61ee9b 100644 --- a/mediagoblin/listings/views.py +++ b/mediagoblin/listings/views.py @@ -46,7 +46,7 @@ def tag_listing(request, page): {u'state': u'processed', u'tags.slug': tag_slug}) cursor = cursor.sort('created', DESCENDING) - + pagination = Pagination(page, cursor) media_entries = pagination() @@ -63,6 +63,7 @@ def tag_listing(request, page): ATOM_DEFAULT_NR_OF_UPDATED_ITEMS = 15 + def tag_atom_feed(request): """ generates the atom feed with the tag images diff --git a/mediagoblin/messages.py b/mediagoblin/messages.py index dc82fbf6..054d46c0 100644 --- a/mediagoblin/messages.py +++ b/mediagoblin/messages.py @@ -20,11 +20,13 @@ SUCCESS = 'success' WARNING = 'warning' ERROR = 'error' + def add_message(request, level, text): messages = request.session.setdefault('messages', []) messages.append({'level': level, 'text': text}) request.session.save() + def fetch_messages(request, clear_from_session=True): messages = request.session.get('messages') if messages and clear_from_session: diff --git a/mediagoblin/middleware/noop.py b/mediagoblin/middleware/noop.py index 28380232..820b5d9e 100644 --- a/mediagoblin/middleware/noop.py +++ b/mediagoblin/middleware/noop.py @@ -14,6 +14,7 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . + class NoOpMiddleware(object): def __init__(self, mg_app): diff --git a/mediagoblin/process_media/__init__.py b/mediagoblin/process_media/__init__.py index 2b9eed6e..9a7d5c39 100644 --- a/mediagoblin/process_media/__init__.py +++ b/mediagoblin/process_media/__init__.py @@ -65,9 +65,10 @@ class ProcessMedia(Task): """ 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. + 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) @@ -80,10 +81,10 @@ 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. + 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 @@ -164,7 +165,8 @@ def process_image(entry): with queued_file: original_filepath = create_pub_filepath(entry, queued_filepath[-1]) - with mgg.public_store.get_file(original_filepath, 'wb') as original_file: + with mgg.public_store.get_file(original_filepath, 'wb') \ + as original_file: original_file.write(queued_file.read()) mgg.queue_store.delete_file(queued_filepath) diff --git a/mediagoblin/process_media/errors.py b/mediagoblin/process_media/errors.py index 156f0a01..cb236154 100644 --- a/mediagoblin/process_media/errors.py +++ b/mediagoblin/process_media/errors.py @@ -16,17 +16,18 @@ 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" % ( @@ -34,8 +35,8 @@ class BaseProcessingFail(Exception): def __init__(self, **metadata): self.metadata = metadata or {} - - + + class BadMediaFail(BaseProcessingFail): """ Error that should be raised when an inappropriate file was given diff --git a/mediagoblin/storage/cloudfiles.py b/mediagoblin/storage/cloudfiles.py index b1dd9450..0d3cc3df 100644 --- a/mediagoblin/storage/cloudfiles.py +++ b/mediagoblin/storage/cloudfiles.py @@ -27,6 +27,7 @@ from mediagoblin.storage import StorageInterface, clean_listy_filepath import cloudfiles import mimetypes + class CloudFilesStorage(StorageInterface): ''' OpenStack/Rackspace Cloud's Swift/CloudFiles support diff --git a/mediagoblin/submit/__init__.py b/mediagoblin/submit/__init__.py index 576bd0f5..ba347c69 100644 --- a/mediagoblin/submit/__init__.py +++ b/mediagoblin/submit/__init__.py @@ -13,5 +13,3 @@ # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . - - diff --git a/mediagoblin/submit/security.py b/mediagoblin/submit/security.py index 9d62a36e..6708baf7 100644 --- a/mediagoblin/submit/security.py +++ b/mediagoblin/submit/security.py @@ -16,9 +16,9 @@ from mimetypes import guess_type - ALLOWED = ['image/jpeg', 'image/png', 'image/tiff', 'image/gif'] + def check_filetype(posted_file): if not guess_type(posted_file.filename)[0] in ALLOWED: return False diff --git a/mediagoblin/submit/views.py b/mediagoblin/submit/views.py index e24d78f3..22a13b6d 100644 --- a/mediagoblin/submit/views.py +++ b/mediagoblin/submit/views.py @@ -61,8 +61,8 @@ def submit_start(request): entry['description'] = unicode(request.POST.get('description')) entry['description_html'] = cleaned_markdown_conversion( entry['description']) - - entry['media_type'] = u'image' # heh + + entry['media_type'] = u'image' # heh entry['uploader'] = request.user['_id'] # Process the user's folksonomy "tags" @@ -90,8 +90,10 @@ def submit_start(request): # 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) + + # (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 @@ -113,8 +115,8 @@ def submit_start(request): # 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 :) + # ... not completely the diaper pattern because the + # exception is re-raised :) mark_entry_failed(entry[u'_id'], exc) # re-raise the exception raise @@ -122,7 +124,7 @@ def submit_start(request): add_message(request, SUCCESS, _('Woohoo! Submitted!')) return redirect(request, "mediagoblin.user_pages.user_home", - user = request.user['username']) + user=request.user['username']) return render_to_response( request, diff --git a/mediagoblin/user_pages/__init__.py b/mediagoblin/user_pages/__init__.py index 576bd0f5..ba347c69 100644 --- a/mediagoblin/user_pages/__init__.py +++ b/mediagoblin/user_pages/__init__.py @@ -13,5 +13,3 @@ # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . - - diff --git a/mediagoblin/user_pages/views.py b/mediagoblin/user_pages/views.py index 6a82d718..e6ba6b79 100644 --- a/mediagoblin/user_pages/views.py +++ b/mediagoblin/user_pages/views.py @@ -53,7 +53,7 @@ def user_home(request, page): #if no data is available, return NotFound if media_entries == None: return render_404(request) - + user_gallery_url = request.urlgen( 'mediagoblin.user_pages.user_gallery', user=user['username']) @@ -66,6 +66,7 @@ def user_home(request, page): 'media_entries': media_entries, 'pagination': pagination}) + @uses_pagination def user_gallery(request, page): """'Gallery' of a User()""" @@ -85,7 +86,7 @@ def user_gallery(request, page): #if no data is available, return NotFound if media_entries == None: return render_404(request) - + return render_to_response( request, 'mediagoblin/user_pages/gallery.html', @@ -95,6 +96,7 @@ def user_gallery(request, page): MEDIA_COMMENTS_PER_PAGE = 50 + @get_user_media_entry @uses_pagination def media_home(request, media, page, **kwargs): @@ -142,8 +144,8 @@ def media_post_comment(request): 'Comment posted!') return redirect(request, 'mediagoblin.user_pages.media_home', - media = request.matchdict['media'], - user = request.matchdict['user']) + media=request.matchdict['media'], + user=request.matchdict['user']) @get_user_media_entry @@ -184,6 +186,7 @@ def media_confirm_delete(request, media): ATOM_DEFAULT_NR_OF_UPDATED_ITEMS = 15 + def atom_feed(request): """ generates the atom feed with the newest images @@ -204,7 +207,7 @@ def atom_feed(request): feed = AtomFeed(request.matchdict['user'], feed_url=request.url, url=request.host_url) - + for entry in cursor: feed.add(entry.get('title'), entry.get('description_html'), diff --git a/mediagoblin/util.py b/mediagoblin/util.py index 7ff3ec7f..4132b497 100644 --- a/mediagoblin/util.py +++ b/mediagoblin/util.py @@ -45,6 +45,8 @@ from itertools import izip, count DISPLAY_IMAGE_FETCHING_ORDER = [u'medium', u'original', u'thumb'] TESTS_ENABLED = False + + def _activate_testing(): """ Call this to activate testing in util.py @@ -78,7 +80,7 @@ SETUP_JINJA_ENVS = {} def get_jinja_env(template_loader, locale): """ - Set up the Jinja environment, + Set up the Jinja environment, (In the future we may have another system for providing theming; for now this is good enough.) @@ -147,7 +149,7 @@ def render_to_response(request, template, context, status=200): def redirect(request, *args, **kwargs): """Returns a HTTPFound(), takes a request and then urlgen params""" - + querystring = None if kwargs.get('querystring'): querystring = kwargs.get('querystring') @@ -197,6 +199,7 @@ def import_component(import_string): _punct_re = re.compile(r'[\t !"#$%&\'()*\-/<=>?@\[\\\]^_`{|},.]+') + def slugify(text, delim=u'-'): """ Generates an ASCII-only slug. Taken from http://flask.pocoo.org/snippets/5/ @@ -213,7 +216,7 @@ def slugify(text, delim=u'-'): ### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # We have two "test inboxes" here: -# +# # EMAIL_TEST_INBOX: # ---------------- # If you're writing test views, you'll probably want to check this. @@ -233,7 +236,7 @@ def slugify(text, delim=u'-'): # ***IMPORTANT!*** # ---------------- # Before running tests that call functions which send email, you should -# always call _clear_test_inboxes() to "wipe" the inboxes clean. +# always call _clear_test_inboxes() to "wipe" the inboxes clean. EMAIL_TEST_INBOX = [] EMAIL_TEST_MBOX_INBOX = [] @@ -253,6 +256,7 @@ class FakeMhost(object): 'to': to_addrs, 'message': message}) + def _clear_test_inboxes(): global EMAIL_TEST_INBOX global EMAIL_TEST_MBOX_INBOX @@ -263,6 +267,7 @@ def _clear_test_inboxes(): ### ### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + def send_email(from_addr, to_addrs, subject, message_body): """ Simple email sending wrapper, use this so we can capture messages @@ -418,7 +423,7 @@ def convert_to_tag_list_of_dicts(tag_string): # Split the tag string into a list of tags for tag in stripped_tag_string.split( - mg_globals.app_config['tags_delimiter']): + mg_globals.app_config['tags_delimiter']): # Ignore empty or duplicate tags if tag.strip() and tag.strip() not in [t['name'] for t in taglist]: @@ -437,12 +442,13 @@ def media_tags_as_string(media_entry_tags): media_tag_string = '' if media_entry_tags: media_tag_string = mg_globals.app_config['tags_delimiter'].join( - [tag['name'] for tag in media_entry_tags]) + [tag['name'] for tag in media_entry_tags]) return media_tag_string TOO_LONG_TAG_WARNING = \ u'Tags must be shorter than %s characters. Tags that are too long: %s' + def tag_length_validator(form, field): """ Make sure tags do not exceed the maximum tag length. @@ -460,6 +466,7 @@ def tag_length_validator(form, field): MARKDOWN_INSTANCE = markdown.Markdown(safe_mode='escape') + def cleaned_markdown_conversion(text): """ Take a block of text, run it through MarkDown, and clean its HTML. @@ -474,6 +481,7 @@ def cleaned_markdown_conversion(text): SETUP_GETTEXTS = {} + def setup_gettext(locale): """ Setup the gettext instance based on this locale @@ -558,6 +566,7 @@ def fake_ugettext_passthrough(string): PAGINATION_DEFAULT_PER_PAGE = 30 + class Pagination(object): """ Pagination class for mongodb queries. @@ -574,9 +583,9 @@ class Pagination(object): Args: - page: requested page - per_page: number of objects per page - - cursor: db cursor - - jump_to_id: ObjectId, sets the page to the page containing the object - with _id == jump_to_id. + - cursor: db cursor + - jump_to_id: ObjectId, sets the page to the page containing the + object with _id == jump_to_id. """ self.page = page self.per_page = per_page @@ -594,7 +603,6 @@ class Pagination(object): self.active_id = jump_to_id break - def __call__(self): """ Returns slice of objects for the requested page @@ -628,20 +636,18 @@ class Pagination(object): last = num def get_page_url_explicit(self, base_url, get_params, page_no): - """ - Get a page url by adding a page= parameter to the base url - """ + """Get a page url by adding a page= parameter to the base url + """ new_get_params = copy.copy(get_params or {}) new_get_params['page'] = page_no return "%s?%s" % ( base_url, urllib.urlencode(new_get_params)) def get_page_url(self, request, page_no): - """ - Get a new page url based of the request, and the new page number. + """Get a new page url based of the request, and the new page number. This is a nice wrapper around get_page_url_explicit() - """ + """ return self.get_page_url_explicit( request.path_info, request.GET, page_no) @@ -682,6 +688,7 @@ def render_404(request): return render_to_response( request, 'mediagoblin/404.html', {}, status=400) + def delete_media_files(media): """ Delete all files associated with a MediaEntry diff --git a/mediagoblin/views.py b/mediagoblin/views.py index 96687f96..afa6ac91 100644 --- a/mediagoblin/views.py +++ b/mediagoblin/views.py @@ -19,6 +19,7 @@ from mediagoblin.util import render_to_response, Pagination from mediagoblin.db.util import DESCENDING from mediagoblin.decorators import uses_pagination + @uses_pagination def root_view(request, page): cursor = request.db.MediaEntry.find( diff --git a/mediagoblin/workbench.py b/mediagoblin/workbench.py index 722f8e27..60a79f47 100644 --- a/mediagoblin/workbench.py +++ b/mediagoblin/workbench.py @@ -42,8 +42,10 @@ class Workbench(object): def __unicode__(self): return unicode(self.dir) + def __str__(self): return str(self.dir) + def __repr__(self): return repr(self.dir) @@ -140,7 +142,7 @@ class WorkbenchManager(object): self.base_workbench_dir = os.path.abspath(base_workbench_dir) if not os.path.exists(self.base_workbench_dir): os.makedirs(self.base_workbench_dir) - + def create_workbench(self): """ Create and return the path to a new workbench (directory). diff --git a/setup.py b/setup.py index 06626926..11c8fe6c 100644 --- a/setup.py +++ b/setup.py @@ -29,16 +29,17 @@ def get_version(): if mo: return mo.group(1) else: - raise RuntimeError("Unable to find version string in %s." % VERSIONFILE) + raise RuntimeError("Unable to find version string in %s." % + VERSIONFILE) setup( - name = "mediagoblin", - version = get_version(), + name="mediagoblin", + version=get_version(), packages=find_packages(exclude=['ez_setup', 'examples', 'tests']), zip_safe=False, # scripts and dependencies - install_requires = [ + install_requires=[ 'setuptools', 'PasteScript', 'beaker', @@ -66,7 +67,7 @@ setup( # 'lxml', ], test_suite='nose.collector', - entry_points = """\ + entry_points="""\ [console_scripts] gmg = mediagoblin.gmg_commands:main_cli pybabel = mediagoblin.babel.messages.frontend:main @@ -83,7 +84,6 @@ setup( [babel.extractors] jinja2 = jinja2.ext:babel_extract """, - license='AGPLv3', author='Free Software Foundation and contributors', author_email='cwebber@gnu.org', From 285ffeddf3542201b83072d3be544c85e9c487c2 Mon Sep 17 00:00:00 2001 From: Nathan Yergler Date: Sat, 1 Oct 2011 15:10:41 -0700 Subject: [PATCH 006/302] has_key is deprecated, converting uses to use "in" operator. --- mediagoblin/auth/views.py | 4 ++-- mediagoblin/db/util.py | 2 +- mediagoblin/gmg_commands/__init__.py | 2 +- mediagoblin/init/__init__.py | 4 ++-- mediagoblin/init/celery/__init__.py | 10 +++++----- mediagoblin/staticdirect.py | 6 +++--- mediagoblin/submit/views.py | 2 +- mediagoblin/util.py | 16 ++++++++-------- 8 files changed, 23 insertions(+), 23 deletions(-) diff --git a/mediagoblin/auth/views.py b/mediagoblin/auth/views.py index afcfcf1e..adf2c315 100644 --- a/mediagoblin/auth/views.py +++ b/mediagoblin/auth/views.py @@ -146,7 +146,7 @@ def verify_email(request): you are lucky :) """ # 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'): + if not 'userid' in request.GET or not 'token' in request.GET: return render_404(request) user = request.db.User.find_one( @@ -307,6 +307,6 @@ def _process_for_token(request): formdata = { 'vars': formdata_vars, 'has_userid_and_token': - formdata_vars.has_key('userid') and formdata_vars.has_key('token')} + 'userid' in formdata_vars and 'token' in formdata_vars} return formdata diff --git a/mediagoblin/db/util.py b/mediagoblin/db/util.py index 38f0233f..52e97f6d 100644 --- a/mediagoblin/db/util.py +++ b/mediagoblin/db/util.py @@ -148,7 +148,7 @@ class RegisterMigration(object): """ def __init__(self, migration_number, migration_registry=MIGRATIONS): assert migration_number > 0, "Migration number must be > 0!" - assert not migration_registry.has_key(migration_number), \ + assert migration_number not in migration_registry, \ "Duplicate migration numbers detected! That's not allowed!" self.migration_number = migration_number diff --git a/mediagoblin/gmg_commands/__init__.py b/mediagoblin/gmg_commands/__init__.py index b3f69ccc..3250c246 100644 --- a/mediagoblin/gmg_commands/__init__.py +++ b/mediagoblin/gmg_commands/__init__.py @@ -61,7 +61,7 @@ def main_cli(): subparsers = parser.add_subparsers(help='sub-command help') for command_name, command_struct in SUBCOMMAND_MAP.iteritems(): - if command_struct.has_key('help'): + if 'help' in command_struct: subparser = subparsers.add_parser( command_name, help=command_struct['help']) else: diff --git a/mediagoblin/init/__init__.py b/mediagoblin/init/__init__.py index f21e2fdd..08a0618d 100644 --- a/mediagoblin/init/__init__.py +++ b/mediagoblin/init/__init__.py @@ -103,10 +103,10 @@ def get_jinja_loader(user_template_path=None): def get_staticdirector(app_config): - if app_config.has_key('direct_remote_path'): + if 'direct_remote_path' in app_config: return staticdirect.RemoteStaticDirect( app_config['direct_remote_path'].strip()) - elif app_config.has_key('direct_remote_paths'): + elif 'direct_remote_paths' in app_config: direct_remote_path_lines = app_config[ 'direct_remote_paths'].strip().splitlines() return staticdirect.MultiRemoteStaticDirect( diff --git a/mediagoblin/init/celery/__init__.py b/mediagoblin/init/celery/__init__.py index 21ce1d39..f7ef9f39 100644 --- a/mediagoblin/init/celery/__init__.py +++ b/mediagoblin/init/celery/__init__.py @@ -40,25 +40,25 @@ def setup_celery_from_config(app_config, global_config, - set_environ: if set, this will CELERY_CONFIG_MODULE to the settings_module """ - if global_config.has_key('celery'): + if 'celery' in global_config: celery_conf = global_config['celery'] else: celery_conf = {} - + celery_settings = {} # set up mongodb stuff celery_settings['CELERY_RESULT_BACKEND'] = 'mongodb' - if not celery_settings.has_key('BROKER_BACKEND'): + if 'BROKER_BACKEND' not in celery_settings: celery_settings['BROKER_BACKEND'] = 'mongodb' celery_mongo_settings = {} - if app_config.has_key('db_host'): + if 'db_host' in app_config: celery_mongo_settings['host'] = app_config['db_host'] if celery_settings['BROKER_BACKEND'] == 'mongodb': celery_settings['BROKER_HOST'] = app_config['db_host'] - if app_config.has_key('db_port'): + if 'db_port' in app_config: celery_mongo_settings['port'] = app_config['db_port'] if celery_settings['BROKER_BACKEND'] == 'mongodb': celery_settings['BROKER_PORT'] = app_config['db_port'] diff --git a/mediagoblin/staticdirect.py b/mediagoblin/staticdirect.py index 58175881..c6d2b374 100644 --- a/mediagoblin/staticdirect.py +++ b/mediagoblin/staticdirect.py @@ -21,24 +21,24 @@ import urlparse # Staticdirect infrastructure. # Borrowed largely from cc.engine # by Chris Webber & Creative Commons -# +# # This needs documentation! #################################### import pkg_resources import urlparse + class StaticDirect(object): def __init__(self): self.cache = {} def __call__(self, filepath): - if self.cache.has_key(filepath): + if filepath in self.cache: return self.cache[filepath] static_direction = self.cache[filepath] = self.get(filepath) return static_direction - def get(self, filepath): # should be implemented by the individual staticdirector diff --git a/mediagoblin/submit/views.py b/mediagoblin/submit/views.py index 22a13b6d..d450ca21 100644 --- a/mediagoblin/submit/views.py +++ b/mediagoblin/submit/views.py @@ -40,7 +40,7 @@ def submit_start(request): submit_form = submit_forms.SubmitStartForm(request.POST) if request.method == 'POST' and submit_form.validate(): - if not (request.POST.has_key('file') + if not ('file' in request.POST and isinstance(request.POST['file'], FieldStorage) and request.POST['file'].file): submit_form.file.errors.append( diff --git a/mediagoblin/util.py b/mediagoblin/util.py index 4132b497..d6ce5930 100644 --- a/mediagoblin/util.py +++ b/mediagoblin/util.py @@ -89,7 +89,7 @@ def get_jinja_env(template_loader, locale): # If we have a jinja environment set up with this locale, just # return that one. - if SETUP_JINJA_ENVS.has_key(locale): + if locale in SETUP_JINJA_ENVS: return SETUP_JINJA_ENVS[locale] template_env = jinja2.Environment( @@ -166,7 +166,7 @@ def setup_user_in_request(request): Examine a request and tack on a request.user parameter if that's appropriate. """ - if not request.session.has_key('user_id'): + if not 'user_id' in request.session: request.user = None return @@ -356,7 +356,7 @@ def get_locale_from_request(request): """ request_form = request.GET or request.POST - if request_form.has_key('lang'): + if 'lang' in request_form: return locale_to_lower_upper(request_form['lang']) accept_lang_matches = request.accept_language.best_matches() @@ -364,9 +364,9 @@ def get_locale_from_request(request): # Your routing can explicitly specify a target language matchdict = request.matchdict or {} - if matchdict.has_key('locale'): + if 'locale' in matchdict: target_lang = matchdict['locale'] - elif request.session.has_key('target_lang'): + elif 'target_lang' in request.session: target_lang = request.session['target_lang'] # Pull the first acceptable language elif accept_lang_matches: @@ -393,9 +393,9 @@ HTML_CLEANER = Cleaner( annoying_tags=True, allow_tags=[ 'div', 'b', 'i', 'em', 'strong', 'p', 'ul', 'ol', 'li', 'a', 'br'], - remove_unknown_tags=False, # can't be used with allow_tags + remove_unknown_tags=False, # can't be used with allow_tags safe_attrs_only=True, - add_nofollow=True, # for now + add_nofollow=True, # for now host_whitelist=(), whitelist_tags=set([])) @@ -492,7 +492,7 @@ def setup_gettext(locale): # TODO: fallback nicely on translations from pt_PT to pt if not # available, etc. - if SETUP_GETTEXTS.has_key(locale): + if locale in SETUP_GETTEXTS: this_gettext = SETUP_GETTEXTS[locale] else: this_gettext = gettext.translation( From 84a7e7706c8b1239f8fd52c604afbb10c776ac04 Mon Sep 17 00:00:00 2001 From: Aaron Williamson Date: Sat, 1 Oct 2011 19:49:56 -0400 Subject: [PATCH 007/302] Display and error and redirect to login page if unauthenticated user tries to access resend_verification. --- mediagoblin/auth/views.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/mediagoblin/auth/views.py b/mediagoblin/auth/views.py index b6f38fec..d91a1f25 100644 --- a/mediagoblin/auth/views.py +++ b/mediagoblin/auth/views.py @@ -21,7 +21,7 @@ from webob import exc from mediagoblin import messages from mediagoblin import mg_globals -from mediagoblin.util import render_to_response, redirect, render_404 +from mediagoblin.util import render_to_response, redirect, render_404, setup_user_in_request from mediagoblin.util import pass_to_ugettext as _ from mediagoblin.db.util import ObjectId, InvalidId from mediagoblin.auth import lib as auth_lib @@ -195,9 +195,18 @@ def resend_activation(request): Resend the activation email. """ + + if not request.GET.has_key('userid') or not request.GET.has_key('token'): + messages.add_message( + request, + messages.ERROR, + _('You must be logged in so we know who to send the email to!')) + + return redirect(request, "/auth/login") + request.user[u'verification_key'] = unicode(uuid.uuid4()) request.user.save() - + email_debug_message(request) send_verification_email(request.user, request) From f1360855319612a9af3c03ae4ca04fef6660f6b0 Mon Sep 17 00:00:00 2001 From: Aaron Williamson Date: Sat, 1 Oct 2011 19:52:12 -0400 Subject: [PATCH 008/302] Regenerated English .po file to include new string. --- .../i18n/en/LC_MESSAGES/mediagoblin.po | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/mediagoblin/i18n/en/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/en/LC_MESSAGES/mediagoblin.po index 16a235a2..3c176a14 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-09-25 20:26-0500\n" +"POT-Creation-Date: 2011-10-01 19:51-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -41,33 +41,37 @@ msgstr "" msgid "Email address" msgstr "" -#: mediagoblin/auth/views.py:42 +#: mediagoblin/auth/views.py:55 msgid "Sorry, registration is disabled on this instance." msgstr "" -#: mediagoblin/auth/views.py:60 +#: mediagoblin/auth/views.py:73 msgid "Sorry, a user with that name already exists." msgstr "" -#: mediagoblin/auth/views.py:64 +#: mediagoblin/auth/views.py:77 msgid "Sorry, that email address has already been taken." msgstr "" -#: mediagoblin/auth/views.py:165 +#: mediagoblin/auth/views.py:179 msgid "" "Your email address has been verified. You may now login, edit your " "profile, and submit images!" msgstr "" -#: mediagoblin/auth/views.py:171 +#: mediagoblin/auth/views.py:185 msgid "The verification key or user id is incorrect" msgstr "" -#: mediagoblin/auth/views.py:192 +#: mediagoblin/auth/views.py:203 +msgid "You must be logged in so we know who to send the email to!" +msgstr "" + +#: mediagoblin/auth/views.py:216 msgid "Resent your verification email." msgstr "" -#: mediagoblin/auth/views.py:228 +#: mediagoblin/auth/views.py:257 msgid "" "Could not send password recovery email as your username is inactive or " "your account's email address has not been verified." From 3b74ce94ff90e0bd5b214891becb62a6fc503434 Mon Sep 17 00:00:00 2001 From: Aaron Williamson Date: Mon, 3 Oct 2011 19:59:28 -0400 Subject: [PATCH 009/302] Check request.user to determine if user is logged in. --- mediagoblin/auth/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediagoblin/auth/views.py b/mediagoblin/auth/views.py index d91a1f25..fdc5aec8 100644 --- a/mediagoblin/auth/views.py +++ b/mediagoblin/auth/views.py @@ -196,7 +196,7 @@ def resend_activation(request): Resend the activation email. """ - if not request.GET.has_key('userid') or not request.GET.has_key('token'): + if request.user is None: messages.add_message( request, messages.ERROR, From 7903a14f986b5bf37a45d5ec3b156c21a1cada72 Mon Sep 17 00:00:00 2001 From: Aaron Williamson Date: Mon, 3 Oct 2011 20:25:11 -0400 Subject: [PATCH 010/302] Make sure user isn't already verified before resending verification. --- mediagoblin/auth/views.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mediagoblin/auth/views.py b/mediagoblin/auth/views.py index 798fae25..dc4c540b 100644 --- a/mediagoblin/auth/views.py +++ b/mediagoblin/auth/views.py @@ -196,6 +196,14 @@ def resend_activation(request): Resend the activation email. """ + if request.user["email_verified"]: + messages.add_message( + request, + messages.ERROR, + _("You've already verified your email address!")) + + return redirect(request, "mediagoblin.user_pages.user_home", user=request.user['username']) + if request.user is None: messages.add_message( request, From 2fe6991660cd1a20f9117b0cdc88431085eb7490 Mon Sep 17 00:00:00 2001 From: Aaron Williamson Date: Mon, 3 Oct 2011 20:28:48 -0400 Subject: [PATCH 011/302] Reverse order of sanity checks: check email_verified after making sure there's a user in the request. --- mediagoblin/auth/views.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/mediagoblin/auth/views.py b/mediagoblin/auth/views.py index dc4c540b..d8c441ef 100644 --- a/mediagoblin/auth/views.py +++ b/mediagoblin/auth/views.py @@ -196,14 +196,6 @@ def resend_activation(request): Resend the activation email. """ - if request.user["email_verified"]: - messages.add_message( - request, - messages.ERROR, - _("You've already verified your email address!")) - - return redirect(request, "mediagoblin.user_pages.user_home", user=request.user['username']) - if request.user is None: messages.add_message( request, @@ -212,6 +204,14 @@ def resend_activation(request): return redirect(request, "/auth/login") + if request.user["email_verified"]: + messages.add_message( + request, + messages.ERROR, + _("You've already verified your email address!")) + + return redirect(request, "mediagoblin.user_pages.user_home", user=request.user['username']) + request.user[u'verification_key'] = unicode(uuid.uuid4()) request.user.save() From 2a8c1b058b43cfcdeb06f711bbf44af9432af410 Mon Sep 17 00:00:00 2001 From: Aaron Williamson Date: Mon, 3 Oct 2011 21:07:16 -0400 Subject: [PATCH 012/302] Update english translation file. --- .../i18n/en/LC_MESSAGES/mediagoblin.po | 60 ++++++++++--------- 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/mediagoblin/i18n/en/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/en/LC_MESSAGES/mediagoblin.po index 3c176a14..ce62e582 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-10-01 19:51-0400\n" +"POT-Creation-Date: 2011-10-03 21:06-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -67,53 +67,57 @@ msgstr "" msgid "You must be logged in so we know who to send the email to!" msgstr "" -#: mediagoblin/auth/views.py:216 +#: mediagoblin/auth/views.py:211 +msgid "You've already verified your email address!" +msgstr "" + +#: mediagoblin/auth/views.py:224 msgid "Resent your verification email." msgstr "" -#: mediagoblin/auth/views.py:257 +#: mediagoblin/auth/views.py:265 msgid "" "Could not send password recovery email as your username is inactive or " "your account's email address has not been verified." msgstr "" -#: mediagoblin/edit/forms.py:26 mediagoblin/submit/forms.py:27 +#: mediagoblin/edit/forms.py:24 mediagoblin/submit/forms.py:27 msgid "Title" msgstr "" -#: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:32 msgid "Tags" msgstr "" -#: mediagoblin/edit/forms.py:33 +#: mediagoblin/edit/forms.py:31 msgid "Slug" msgstr "" -#: mediagoblin/edit/forms.py:34 +#: mediagoblin/edit/forms.py:32 msgid "The slug can't be empty" msgstr "" -#: mediagoblin/edit/forms.py:35 +#: mediagoblin/edit/forms.py:33 msgid "The title part of this media's URL. You usually don't need to change this." msgstr "" -#: mediagoblin/edit/forms.py:42 +#: mediagoblin/edit/forms.py:40 msgid "Bio" msgstr "" -#: mediagoblin/edit/forms.py:45 +#: mediagoblin/edit/forms.py:43 msgid "Website" msgstr "" -#: mediagoblin/edit/views.py:63 +#: mediagoblin/edit/views.py:64 msgid "An entry with that slug already exists for this user." msgstr "" -#: mediagoblin/edit/views.py:84 +#: mediagoblin/edit/views.py:85 msgid "You are editing another user's media. Proceed with caution." msgstr "" -#: mediagoblin/edit/views.py:154 +#: mediagoblin/edit/views.py:155 msgid "You are editing a user's profile. Proceed with caution." msgstr "" @@ -129,15 +133,15 @@ msgstr "" msgid "Description of this work" msgstr "" -#: mediagoblin/submit/views.py:47 +#: mediagoblin/submit/views.py:46 msgid "You must provide a file." msgstr "" -#: mediagoblin/submit/views.py:50 +#: mediagoblin/submit/views.py:49 msgid "The file doesn't seem to be an image!" msgstr "" -#: mediagoblin/submit/views.py:122 +#: mediagoblin/submit/views.py:121 msgid "Woohoo! Submitted!" msgstr "" @@ -176,8 +180,8 @@ msgid "verify your email!" msgstr "" #: mediagoblin/templates/mediagoblin/base.html:73 -#: mediagoblin/templates/mediagoblin/auth/login.html:26 -#: mediagoblin/templates/mediagoblin/auth/login.html:34 +#: mediagoblin/templates/mediagoblin/auth/login.html:27 +#: mediagoblin/templates/mediagoblin/auth/login.html:35 msgid "Log in" msgstr "" @@ -249,11 +253,11 @@ msgstr "" msgid "Most recent media" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/change_fp.html:27 +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:29 msgid "Enter your new password" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:29 msgid "Enter your username or email" msgstr "" @@ -279,23 +283,23 @@ msgid "" "a happy goblin!" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/login.html:29 +#: mediagoblin/templates/mediagoblin/auth/login.html:30 msgid "Logging in failed!" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/login.html:42 +#: mediagoblin/templates/mediagoblin/auth/login.html:43 msgid "Don't have an account yet?" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/login.html:45 +#: mediagoblin/templates/mediagoblin/auth/login.html:46 msgid "Create one here!" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/login.html:48 +#: mediagoblin/templates/mediagoblin/auth/login.html:49 msgid "Forgot your password?" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/login.html:51 +#: mediagoblin/templates/mediagoblin/auth/login.html:52 msgid "Change it!" msgstr "" @@ -303,7 +307,7 @@ msgstr "" msgid "Create an account!" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/register.html:30 +#: mediagoblin/templates/mediagoblin/auth/register.html:31 msgid "Create" msgstr "" @@ -346,7 +350,7 @@ msgstr "" msgid "Submit yer media" msgstr "" -#: mediagoblin/templates/mediagoblin/submit/start.html:29 +#: mediagoblin/templates/mediagoblin/submit/start.html:30 msgid "Submit" msgstr "" @@ -484,7 +488,7 @@ msgstr "" msgid "I am sure I want to delete this" msgstr "" -#: mediagoblin/user_pages/views.py:175 +#: mediagoblin/user_pages/views.py:176 msgid "You are about to delete another user's media. Proceed with caution." msgstr "" From 26729e0277f883d489157160ab6f0f3fd9d35b47 Mon Sep 17 00:00:00 2001 From: Joar Wandborg Date: Wed, 5 Oct 2011 22:58:42 +0200 Subject: [PATCH 013/302] Multimedia refractoring, and added video thumbnail support --- mediagoblin/media_types/__init__.py | 3 + mediagoblin/media_types/video/processing.py | 168 ++++++++++--------- mediagoblin/media_types/video/transcoders.py | 113 +++++++++++++ mediagoblin/views.py | 8 +- mediagoblin/workbench.py | 5 +- setup.py | 1 + 6 files changed, 213 insertions(+), 85 deletions(-) create mode 100644 mediagoblin/media_types/video/transcoders.py diff --git a/mediagoblin/media_types/__init__.py b/mediagoblin/media_types/__init__.py index 6a368cda..49d3ab9d 100644 --- a/mediagoblin/media_types/__init__.py +++ b/mediagoblin/media_types/__init__.py @@ -17,6 +17,9 @@ import os import sys +from mediagoblin.util import lazy_pass_to_ugettext as _ + + class FileTypeNotSupported(Exception): pass diff --git a/mediagoblin/media_types/video/processing.py b/mediagoblin/media_types/video/processing.py index 4cae1fd8..a7dbcf67 100644 --- a/mediagoblin/media_types/video/processing.py +++ b/mediagoblin/media_types/video/processing.py @@ -17,16 +17,17 @@ import Image import tempfile import pkg_resources +import os from celery.task import Task from celery import registry from mediagoblin.db.util import ObjectId from mediagoblin import mg_globals as mgg - from mediagoblin.util import lazy_pass_to_ugettext as _ - -import mediagoblin.media_types.video +from mediagoblin.process_media.errors import BaseProcessingFail, BadMediaFail +from mediagoblin.process_media import mark_entry_failed +from . import transcoders import gobject gobject.threads_init() @@ -39,10 +40,12 @@ from arista.transcoder import TranscoderOptions THUMB_SIZE = 180, 180 MEDIUM_SIZE = 640, 640 -ARISTA_DEVICE_KEY = 'web' +ARISTA_DEVICE = 'devices/web-advanced.json' +ARISTA_PRESET = None + +loop = None # Is this even used? -loop = None logger = logging.getLogger(__name__) logging.basicConfig() logger.setLevel(logging.DEBUG) @@ -51,10 +54,20 @@ logger.setLevel(logging.DEBUG) def process_video(entry): """ Code to process a video + + Much of this code is derived from the arista-transcoder script in + the arista PyPI package and changed to match the needs of + MediaGoblin + + This function sets up the arista video encoder in some kind of new thread + and attaches callbacks to that child process, hopefully, the + entry-complete callback will be called when the video is done. """ - global loop - loop = None + + ''' Empty dict, will store data which will be passed to the callback + functions ''' info = {} + workbench = mgg.workbench_manager.create_workbench() queued_filepath = entry['queued_media_file'] @@ -62,29 +75,36 @@ def process_video(entry): mgg.queue_store, queued_filepath, 'source') + ''' Initialize arista ''' arista.init() + ''' Loads a preset file which specifies the format of the output video''' + device = arista.presets.load( + pkg_resources.resource_filename( + __name__, + ARISTA_DEVICE)) - web_advanced_preset = pkg_resources.resource_filename( - __name__, - 'presets/web-advanced.json') - device = arista.presets.load(web_advanced_preset) - + # FIXME: Is this needed since we only transcode one video? queue = arista.queue.TranscodeQueue() - - info['tmp_file'] = tmp_file = tempfile.NamedTemporaryFile() - info['medium_filepath'] = medium_filepath = create_pub_filepath(entry, 'video.webm') + info['tmp_file'] = tempfile.NamedTemporaryFile(delete=False) - output = tmp_file.name + info['medium_filepath'] = create_pub_filepath( + entry, 'video.webm') - uri = 'file://' + queued_filename + info['thumb_filepath'] = create_pub_filepath( + entry, 'thumbnail.jpg') - preset = device.presets[device.default] + # With the web-advanced.json device preset, this will select + # 480p WebM w/ OGG Vorbis + preset = device.presets[ARISTA_PRESET or device.default] logger.debug('preset: {0}'.format(preset)) - opts = TranscoderOptions(uri, preset, output) + opts = TranscoderOptions( + 'file://' + queued_filename, # Arista did it this way, IIRC + preset, + info['tmp_file'].name) queue.append(opts) @@ -95,68 +115,78 @@ def process_video(entry): queue.connect("entry-error", _transcoding_error, info) queue.connect("entry-complete", _transcoding_complete, info) - info['loop'] = loop = gobject.MainLoop() + # Add data to the info dict, making it available to the callbacks + info['loop'] = gobject.MainLoop() info['queued_filename'] = queued_filename info['queued_filepath'] = queued_filepath info['workbench'] = workbench + info['preset'] = preset + + info['loop'].run() logger.debug('info: {0}'.format(info)) - loop.run() - - ''' - try: - #thumb = Image.open(mediagoblin.media_types.video.MEDIA_MANAGER['default_thumb']) - except IOError: - raise BadMediaFail() - thumb.thumbnail(THUMB_SIZE, Image.ANTIALIAS) - # ensure color mode is compatible with jpg - if thumb.mode != "RGB": - thumb = thumb.convert("RGB") +def __create_thumbnail(info): + thumbnail = tempfile.NamedTemporaryFile() - thumb_filepath = create_pub_filepath(entry, 'thumbnail.jpg') - thumb_file = mgg.public_store.get_file(thumb_filepath, 'w') + logger.info('thumbnailing...') + transcoders.VideoThumbnailer(info['tmp_file'].name, thumbnail.name) + logger.debug('Done thumbnailing') - with thumb_file: - thumb.save(thumb_file, "JPEG", quality=90) - ''' + os.remove(info['tmp_file'].name) -def __close_processing(queue, qentry, info, error=False): + mgg.public_store.get_file(info['thumb_filepath'], 'wb').write( + thumbnail.read()) + + info['entry']['media_files']['thumb'] = info['thumb_filepath'] + info['entry'].save() + + +def __close_processing(queue, qentry, info, **kwargs): ''' - Update MediaEntry, move files, handle errors + Updates MediaEntry, moves files, handles errors ''' - if not error: + if not kwargs.get('error'): + logger.info('Transcoding successful') + qentry.transcoder.stop() gobject.idle_add(info['loop'].quit) - info['loop'].quit() + info['loop'].quit() # Do I have to do this again? - print('\n-> Saving video...\n') + logger.info('Saving files...') + # Write the transcoded media to the storage system with info['tmp_file'] as tmp_file: mgg.public_store.get_file(info['medium_filepath'], 'wb').write( tmp_file.read()) info['entry']['media_files']['medium'] = info['medium_filepath'] - print('\n=== DONE! ===\n') - # we have to re-read because unlike PIL, not everything reads # things in string representation :) queued_file = file(info['queued_filename'], 'rb') with queued_file: - original_filepath = create_pub_filepath(info['entry'], info['queued_filepath'][-1]) + original_filepath = create_pub_filepath( + info['entry'], + info['queued_filepath'][-1]) - with mgg.public_store.get_file(original_filepath, 'wb') as original_file: + with mgg.public_store.get_file(original_filepath, 'wb') as \ + original_file: original_file.write(queued_file.read()) mgg.queue_store.delete_file(info['queued_filepath']) + + + logger.debug('...Done') + info['entry']['queued_media_file'] = [] media_files_dict = info['entry'].setdefault('media_files', {}) media_files_dict['original'] = original_filepath - # media_files_dict['thumb'] = thumb_filepath info['entry']['state'] = u'processed' + info['entry']['media_data'][u'preset'] = info['preset'].name + __create_thumbnail(info) info['entry'].save() else: @@ -174,17 +204,20 @@ def _transcoding_start(queue, qentry, info): logger.info('-> Starting transcoding') logger.debug(queue, qentry, info) + def _transcoding_complete(*args): __close_processing(*args) print(args) -def _transcoding_error(*args): - logger.info('-> Error') - __close_processing(*args, error=True) - logger.debug(*args) + +def _transcoding_error(queue, qentry, info): + logger.info('Error') + __close_processing(queue, qentry, info, error=True) + logger.debug(queue, quentry, info) + def _transcoding_pass_setup(queue, qentry, options): - logger.info('-> Pass setup') + logger.info('Pass setup') logger.debug(queue, qentry, options) @@ -200,10 +233,10 @@ def check_interrupted(): except: # Something pretty bad happened... just exit! gobject.idle_add(loop.quit) - + return False return True - + def create_pub_filepath(entry, filename): return mgg.public_store.get_unique_filepath( @@ -212,34 +245,6 @@ def create_pub_filepath(entry, filename): filename]) -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.') - - ################################ # Media processing initial steps ################################ @@ -311,4 +316,3 @@ def mark_entry_failed(entry_id, exc): {'$set': {u'state': u'failed', u'fail_error': None, u'fail_metadata': {}}}) - diff --git a/mediagoblin/media_types/video/transcoders.py b/mediagoblin/media_types/video/transcoders.py new file mode 100644 index 00000000..06bfd3cc --- /dev/null +++ b/mediagoblin/media_types/video/transcoders.py @@ -0,0 +1,113 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +import sys +import logging + +_log = logging.getLogger(__name__) +logging.basicConfig() +_log.setLevel(logging.INFO) + +try: + import gobject +except: + _log.error('Could not import gobject') + +try: + import pygst + pygst.require('0.10') + import gst +except: + _log.error('pygst could not be imported') + +class VideoThumbnailer: + def __init__(self, src, dst): + self._set_up_pass(src, dst) + + self.loop = gobject.MainLoop() + self.loop.run() + + def _set_up_pass(self, src, dst): + self.pipeline = gst.Pipeline('TranscodingPipeline') + + _log.debug('Pipeline: {0}'.format(self.pipeline)) + + self.filesrc = gst.element_factory_make('filesrc', 'filesrc') + self.filesrc.set_property('location', src) + self.pipeline.add(self.filesrc) + + self.decoder = gst.element_factory_make('decodebin2', 'decoder') + + self.decoder.connect('new-decoded-pad', self._on_dynamic_pad) + self.pipeline.add(self.decoder) + + self.ffmpegcolorspace = gst.element_factory_make('ffmpegcolorspace', 'ffmpegcolorspace') + self.pipeline.add(self.ffmpegcolorspace) + + self.videoscale = gst.element_factory_make('videoscale', 'videoscale') + self.pipeline.add(self.videoscale) + + self.capsfilter = gst.element_factory_make('capsfilter', 'capsfilter') + self.capsfilter.set_property('caps', gst.caps_from_string('video/x-raw-rgb, width=180, height=100')) + self.pipeline.add(self.capsfilter) + + self.jpegenc = gst.element_factory_make('jpegenc', 'jpegenc') + self.pipeline.add(self.jpegenc) + + self.filesink = gst.element_factory_make('filesink', 'filesink') + self.filesink.set_property('location', dst) + self.pipeline.add(self.filesink) + + # Link all the elements together + self.filesrc.link(self.decoder) + self.ffmpegcolorspace.link(self.videoscale) + self.videoscale.link(self.capsfilter) + self.capsfilter.link(self.jpegenc) + self.jpegenc.link(self.filesink) + + bus = self.pipeline.get_bus() + bus.add_signal_watch() + bus.connect('message', self._on_message) + + self.pipeline.set_state(gst.STATE_PLAYING) + + + def _on_message(self, bus, message): + _log.info((bus, message)) + + t = message.type + + if t == gst.MESSAGE_EOS: + self.__shutdown() + + def _on_dynamic_pad(self, dbin, pad, islast): + ''' + Callback called when ``decodebin2`` has a pad that we can connect to + ''' + pad.link( + self.ffmpegcolorspace.get_pad('sink')) + + def __shutdown(self): + _log.debug(self.loop) + + self.pipeline.set_state(gst.STATE_NULL) + + gobject.idle_add(self.loop.quit) + + +if __name__ == '__main__': + VideoThumbnailer('/home/joar/Dropbox/Public/blender/fluid-box.mp4', '/tmp/dest.jpg') + VideoThumbnailer('/home/joar/Dropbox/iPhone/Video 2011-10-05 21 58 03.mov', '/tmp/dest2.jpg') diff --git a/mediagoblin/views.py b/mediagoblin/views.py index 96687f96..c2e3e80a 100644 --- a/mediagoblin/views.py +++ b/mediagoblin/views.py @@ -14,10 +14,14 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +import sys + from mediagoblin import mg_globals from mediagoblin.util import render_to_response, Pagination from mediagoblin.db.util import DESCENDING from mediagoblin.decorators import uses_pagination +from mediagoblin import media_types + @uses_pagination def root_view(request, page): @@ -26,12 +30,12 @@ def root_view(request, page): pagination = Pagination(page, cursor) media_entries = pagination() - return render_to_response( request, 'mediagoblin/root.html', {'media_entries': media_entries, 'allow_registration': mg_globals.app_config["allow_registration"], - 'pagination': pagination}) + 'pagination': pagination, + 'sys': sys}) def simple_template_render(request): diff --git a/mediagoblin/workbench.py b/mediagoblin/workbench.py index 722f8e27..b5e8eac5 100644 --- a/mediagoblin/workbench.py +++ b/mediagoblin/workbench.py @@ -45,7 +45,10 @@ class Workbench(object): def __str__(self): return str(self.dir) def __repr__(self): - return repr(self.dir) + try: + return str(self) + except AttributeError: + return 'None' def joinpath(self, *args): return os.path.join(self.dir, *args) diff --git a/setup.py b/setup.py index 7417fb97..4ceb4674 100644 --- a/setup.py +++ b/setup.py @@ -66,6 +66,7 @@ setup( ## their package managers. # 'lxml', ], + requires=['gst'], test_suite='nose.collector', entry_points = """\ [console_scripts] From 3528b47d1e731267e57c376da9ad602949e29b22 Mon Sep 17 00:00:00 2001 From: Joar Wandborg Date: Wed, 5 Oct 2011 23:26:50 +0200 Subject: [PATCH 014/302] Added parameter to transcoding_error --- mediagoblin/media_types/video/processing.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mediagoblin/media_types/video/processing.py b/mediagoblin/media_types/video/processing.py index a7dbcf67..a088468b 100644 --- a/mediagoblin/media_types/video/processing.py +++ b/mediagoblin/media_types/video/processing.py @@ -210,10 +210,10 @@ def _transcoding_complete(*args): print(args) -def _transcoding_error(queue, qentry, info): +def _transcoding_error(queue, qentry, info, *args): logger.info('Error') __close_processing(queue, qentry, info, error=True) - logger.debug(queue, quentry, info) + logger.debug(queue, quentry, info, *args) def _transcoding_pass_setup(queue, qentry, options): From 89d764cd7073939f93d2a7c1ae8d0f2c7c2a1be8 Mon Sep 17 00:00:00 2001 From: Joar Wandborg Date: Thu, 6 Oct 2011 00:00:09 +0200 Subject: [PATCH 015/302] Fixed incorrect logger.[...] calls - Added FIXME about thumb size --- mediagoblin/media_types/video/processing.py | 10 +++++----- mediagoblin/media_types/video/transcoders.py | 2 ++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/mediagoblin/media_types/video/processing.py b/mediagoblin/media_types/video/processing.py index a088468b..d7a48caa 100644 --- a/mediagoblin/media_types/video/processing.py +++ b/mediagoblin/media_types/video/processing.py @@ -202,23 +202,23 @@ def __close_processing(queue, qentry, info, **kwargs): def _transcoding_start(queue, qentry, info): logger.info('-> Starting transcoding') - logger.debug(queue, qentry, info) + logger.debug((queue, qentry, info)) def _transcoding_complete(*args): __close_processing(*args) - print(args) + logger.debug(*args) -def _transcoding_error(queue, qentry, info, *args): +def _transcoding_error(queue, qentry, arg, info): logger.info('Error') __close_processing(queue, qentry, info, error=True) - logger.debug(queue, quentry, info, *args) + logger.debug((queue, quentry, info, arg)) def _transcoding_pass_setup(queue, qentry, options): logger.info('Pass setup') - logger.debug(queue, qentry, options) + logger.debug((queue, qentry, options)) def check_interrupted(): diff --git a/mediagoblin/media_types/video/transcoders.py b/mediagoblin/media_types/video/transcoders.py index 06bfd3cc..1134bc66 100644 --- a/mediagoblin/media_types/video/transcoders.py +++ b/mediagoblin/media_types/video/transcoders.py @@ -33,6 +33,7 @@ try: except: _log.error('pygst could not be imported') + class VideoThumbnailer: def __init__(self, src, dst): self._set_up_pass(src, dst) @@ -61,6 +62,7 @@ class VideoThumbnailer: self.pipeline.add(self.videoscale) self.capsfilter = gst.element_factory_make('capsfilter', 'capsfilter') + # FIXME: videoscale doesn't care about original ratios self.capsfilter.set_property('caps', gst.caps_from_string('video/x-raw-rgb, width=180, height=100')) self.pipeline.add(self.capsfilter) From a249b6d3a2e50a1cabd76a240ee391d9e54b1fbf Mon Sep 17 00:00:00 2001 From: Joar Wandborg Date: Tue, 11 Oct 2011 04:57:17 +0200 Subject: [PATCH 016/302] - Refractored the video thumbnailer - Started work on video transcoder Not done, by far! - Bug fix in video.processing error handling --- mediagoblin/media_types/video/processing.py | 1 - mediagoblin/media_types/video/transcoders.py | 322 +++++++++++++++++-- 2 files changed, 303 insertions(+), 20 deletions(-) diff --git a/mediagoblin/media_types/video/processing.py b/mediagoblin/media_types/video/processing.py index d7a48caa..52047ae4 100644 --- a/mediagoblin/media_types/video/processing.py +++ b/mediagoblin/media_types/video/processing.py @@ -213,7 +213,6 @@ def _transcoding_complete(*args): def _transcoding_error(queue, qentry, arg, info): logger.info('Error') __close_processing(queue, qentry, info, error=True) - logger.debug((queue, quentry, info, arg)) def _transcoding_pass_setup(queue, qentry, options): diff --git a/mediagoblin/media_types/video/transcoders.py b/mediagoblin/media_types/video/transcoders.py index 1134bc66..d305d5fc 100644 --- a/mediagoblin/media_types/video/transcoders.py +++ b/mediagoblin/media_types/video/transcoders.py @@ -14,15 +14,18 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +from __future__ import division import sys import logging + _log = logging.getLogger(__name__) logging.basicConfig() -_log.setLevel(logging.INFO) +_log.setLevel(logging.DEBUG) try: import gobject + gobject.threads_init() except: _log.error('Could not import gobject') @@ -30,24 +33,83 @@ try: import pygst pygst.require('0.10') import gst + from gst.extend import discoverer except: _log.error('pygst could not be imported') class VideoThumbnailer: - def __init__(self, src, dst): - self._set_up_pass(src, dst) + ''' + Creates a video thumbnail + + - Sets up discoverer & transcoding pipeline. + Discoverer finds out information about the media file + - Launches gobject.MainLoop, this triggers the discoverer to start running + - Once the discoverer is done, it calls the __discovered callback function + - The __discovered callback function launches the transcoding process + - The _on_message callback is called from the transcoding process until it gets a + message of type gst.MESSAGE_EOS, then it calls __stop which shuts down the + gobject.MainLoop + ''' + def __init__(self, src, dst, **kwargs): + _log.info('Initializing VideoThumbnailer...') self.loop = gobject.MainLoop() + self.source_path = src + self.destination_path = dst + + self.destination_dimensions = kwargs.get('dimensions') or (180, 180) + + if not type(self.destination_dimensions) == tuple: + raise Exception('dimensions must be tuple: (width, height)') + + self._setup() + self._run() + + def _setup(self): + self._setup_pass() + self._setup_discover() + + def _run(self): + _log.info('Discovering...') + self.discoverer.discover() + _log.info('Done') + + _log.debug('Initializing MainLoop()') self.loop.run() - def _set_up_pass(self, src, dst): - self.pipeline = gst.Pipeline('TranscodingPipeline') + def _setup_discover(self): + self.discoverer = discoverer.Discoverer(self.source_path) - _log.debug('Pipeline: {0}'.format(self.pipeline)) + # Connect self.__discovered to the 'discovered' event + self.discoverer.connect('discovered', self.__discovered) + + def __discovered(self, data, is_media): + ''' + Callback for media discoverer. + ''' + if not is_media: + self.__stop() + raise Exception('Could not discover {0}'.format(self.source_path)) + + _log.debug('__discovered, data: {0}'.format(data)) + + self.data = data + + self._on_discovered() + + # Tell the transcoding pipeline to start running + self.pipeline.set_state(gst.STATE_PLAYING) + _log.info('Transcoding...') + + def _on_discovered(self): + self.__setup_capsfilter() + + def _setup_pass(self): + self.pipeline = gst.Pipeline('VideoThumbnailerPipeline') self.filesrc = gst.element_factory_make('filesrc', 'filesrc') - self.filesrc.set_property('location', src) + self.filesrc.set_property('location', self.source_path) self.pipeline.add(self.filesrc) self.decoder = gst.element_factory_make('decodebin2', 'decoder') @@ -59,18 +121,17 @@ class VideoThumbnailer: self.pipeline.add(self.ffmpegcolorspace) self.videoscale = gst.element_factory_make('videoscale', 'videoscale') + self.videoscale.set_property('method', 'bilinear') self.pipeline.add(self.videoscale) self.capsfilter = gst.element_factory_make('capsfilter', 'capsfilter') - # FIXME: videoscale doesn't care about original ratios - self.capsfilter.set_property('caps', gst.caps_from_string('video/x-raw-rgb, width=180, height=100')) self.pipeline.add(self.capsfilter) self.jpegenc = gst.element_factory_make('jpegenc', 'jpegenc') self.pipeline.add(self.jpegenc) self.filesink = gst.element_factory_make('filesink', 'filesink') - self.filesink.set_property('location', dst) + self.filesink.set_property('location', self.destination_path) self.pipeline.add(self.filesink) # Link all the elements together @@ -80,20 +141,50 @@ class VideoThumbnailer: self.capsfilter.link(self.jpegenc) self.jpegenc.link(self.filesink) - bus = self.pipeline.get_bus() - bus.add_signal_watch() - bus.connect('message', self._on_message) + self._setup_bus() - self.pipeline.set_state(gst.STATE_PLAYING) + def _setup_bus(self): + self.bus = self.pipeline.get_bus() + self.bus.add_signal_watch() + self.bus.connect('message', self._on_message) + def __setup_capsfilter(self): + thumbsizes = self.calculate_resize() # Returns tuple with (width, height) + + self.capsfilter.set_property( + 'caps', + gst.caps_from_string('video/x-raw-rgb, width={width}, height={height}'.format( + width=thumbsizes[0], + height=thumbsizes[1] + ))) + + def calculate_resize(self): + x_ratio = self.destination_dimensions[0] / self.data.videowidth + y_ratio = self.destination_dimensions[1] / self.data.videoheight + + if self.data.videoheight > self.data.videowidth: + # We're dealing with a portrait! + dimensions = ( + int(self.data.videowidth * y_ratio), + 180) + else: + dimensions = ( + 180, + int(self.data.videoheight * x_ratio)) + + return dimensions def _on_message(self, bus, message): - _log.info((bus, message)) + _log.debug((bus, message)) t = message.type if t == gst.MESSAGE_EOS: - self.__shutdown() + self.__stop() + _log.info('Done') + elif t == gst.MESSAGE_ERROR: + _log.error((bus, message)) + self.__stop() def _on_dynamic_pad(self, dbin, pad, islast): ''' @@ -102,7 +193,163 @@ class VideoThumbnailer: pad.link( self.ffmpegcolorspace.get_pad('sink')) - def __shutdown(self): + def __stop(self): + _log.debug(self.loop) + + self.pipeline.set_state(gst.STATE_NULL) + + gobject.idle_add(self.loop.quit) + + +class VideoTranscoder(): + ''' + Video transcoder + + TODO: + - Currently not working + ''' + def __init__(self, src, dst, **kwargs): + _log.info('Initializing VideoTranscoder...') + + self.loop = gobject.MainLoop() + self.source_path = src + self.destination_path = dst + + self.destination_dimensions = kwargs.get('dimensions') or (180, 180) + + if not type(self.destination_dimensions) == tuple: + raise Exception('dimensions must be tuple: (width, height)') + + self._setup() + self._run() + + def _setup(self): + self._setup_pass() + self._setup_discover() + + def _run(self): + _log.info('Discovering...') + self.discoverer.discover() + _log.info('Done') + + _log.debug('Initializing MainLoop()') + self.loop.run() + + def _setup_discover(self): + self.discoverer = discoverer.Discoverer(self.source_path) + + # Connect self.__discovered to the 'discovered' event + self.discoverer.connect('discovered', self.__discovered) + + def __discovered(self, data, is_media): + ''' + Callback for media discoverer. + ''' + if not is_media: + self.__stop() + raise Exception('Could not discover {0}'.format(self.source_path)) + + _log.debug('__discovered, data: {0}'.format(data)) + + self.data = data + + # Tell the transcoding pipeline to start running + self.pipeline.set_state(gst.STATE_PLAYING) + _log.info('Transcoding...') + + def _on_discovered(self): + self.__setup_capsfilter() + + def _setup_pass(self): + self.pipeline = gst.Pipeline('VideoTranscoderPipeline') + + self.filesrc = gst.element_factory_make('filesrc', 'filesrc') + self.filesrc.set_property('location', self.source_path) + self.pipeline.add(self.filesrc) + + self.decoder = gst.element_factory_make('decodebin2', 'decoder') + + self.decoder.connect('new-decoded-pad', self._on_dynamic_pad) + self.pipeline.add(self.decoder) + + self.ffmpegcolorspace = gst.element_factory_make('ffmpegcolorspace', 'ffmpegcolorspace') + self.pipeline.add(self.ffmpegcolorspace) + + self.videoscale = gst.element_factory_make('videoscale', 'videoscale') + self.videoscale.set_property('method', 'bilinear') + self.pipeline.add(self.videoscale) + + self.capsfilter = gst.element_factory_make('capsfilter', 'capsfilter') + self.pipeline.add(self.capsfilter) + + self.vp8enc = gst.element_factory_make('vp8enc', 'vp8enc') + self.vp8enc.set_property('quality', 6) + self.vp8enc.set_property('threads', 2) + self.vp8enc.set_property('speed', 2) + + self.webmmux = gst.element_factory_make('webmmux', 'webmmux') + self.pipeline.add(self.webmmux) + + self.filesink = gst.element_factory_make('filesink', 'filesink') + + self.filesrc.link(self.decoder) + self.ffmpegcolorspace.link(self.videoscale) + self.videoscale.link(self.capsfilter) + self.vp8enc.link(self.filesink) + + self._setup_bus() + + def _on_dynamic_pad(self, dbin, pad, islast): + ''' + Callback called when ``decodebin2`` has a pad that we can connect to + ''' + pad.link( + self.ffmpegcolorspace.get_pad('sink')) + + def _setup_bus(self): + self.bus = self.pipeline.get_bus() + self.bus.add_signal_watch() + self.bus.connect('message', self._on_message) + + def __setup_capsfilter(self): + thumbsizes = self.calculate_resize() # Returns tuple with (width, height) + + self.capsfilter.set_property( + 'caps', + gst.caps_from_string('video/x-raw-rgb, width={width}, height={height}'.format( + width=thumbsizes[0], + height=thumbsizes[1] + ))) + + def calculate_resize(self): + x_ratio = self.destination_dimensions[0] / self.data.videowidth + y_ratio = self.destination_dimensions[1] / self.data.videoheight + + if self.data.videoheight > self.data.videowidth: + # We're dealing with a portrait! + dimensions = ( + int(self.data.videowidth * y_ratio), + 180) + else: + dimensions = ( + 180, + int(self.data.videoheight * x_ratio)) + + return dimensions + + def _on_message(self, bus, message): + _log.debug((bus, message)) + + t = message.type + + if t == gst.MESSAGE_EOS: + self.__stop() + _log.info('Done') + elif t == gst.MESSAGE_ERROR: + _log.error((bus, message)) + self.__stop() + + def __stop(self): _log.debug(self.loop) self.pipeline.set_state(gst.STATE_NULL) @@ -111,5 +358,42 @@ class VideoThumbnailer: if __name__ == '__main__': - VideoThumbnailer('/home/joar/Dropbox/Public/blender/fluid-box.mp4', '/tmp/dest.jpg') - VideoThumbnailer('/home/joar/Dropbox/iPhone/Video 2011-10-05 21 58 03.mov', '/tmp/dest2.jpg') + from optparse import OptionParser + + parser = OptionParser( + usage='%prog [-v] -a [ video | thumbnail ] SRC DEST') + + parser.add_option('-a', '--action', + dest='action', + help='One of "video" or "thumbnail"') + + parser.add_option('-v', + dest='verbose', + action='store_true', + help='Output debug information') + + parser.add_option('-q', + dest='quiet', + action='store_true', + help='Dear program, please be quiet unless *error*') + + (options, args) = parser.parse_args() + + if options.verbose: + _log.setLevel(logging.DEBUG) + else: + _log.setLevel(logging.INFO) + + if options.quiet: + _log.setLevel(logging.ERROR) + + _log.debug(args) + + if not len(args) == 2: + parser.print_help() + sys.exit() + + if options.action == 'thumbnail': + VideoThumbnailer(*args) + elif options.action == 'video': + VideoTranscoder(*args) From a7ca2a72118f0e0e72bdc2a0547b80ae0d0a32ea Mon Sep 17 00:00:00 2001 From: Joar Wandborg Date: Fri, 14 Oct 2011 03:15:50 +0200 Subject: [PATCH 017/302] import_export - Added some error handling We still want to be able to do an export if a file can't be read --- mediagoblin/gmg_commands/import_export.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/mediagoblin/gmg_commands/import_export.py b/mediagoblin/gmg_commands/import_export.py index 05edbfc8..fefbdb4e 100644 --- a/mediagoblin/gmg_commands/import_export.py +++ b/mediagoblin/gmg_commands/import_export.py @@ -215,10 +215,12 @@ def _export_media(db, args): _log.info('Exporting {0} - {1}'.format( entry['title'], name)) - - mc_file = media_cache.get_file(path, mode='wb') - mc_file.write( - mg_globals.public_store.get_file(path, mode='rb').read()) + try: + mc_file = media_cache.get_file(path, mode='wb') + mc_file.write( + mg_globals.public_store.get_file(path, mode='rb').read()) + except e: + _log.error('Failed: {0}'.format(e)) _log.info('...Media exported') From e9c1b9381deb51f5b8b40580cea41a73eec65df7 Mon Sep 17 00:00:00 2001 From: Joar Wandborg Date: Fri, 14 Oct 2011 03:17:06 +0200 Subject: [PATCH 018/302] Video transcoding is now gstreamer directly instead of through arista --- mediagoblin/media_types/video/processing.py | 109 ++++++++--------- mediagoblin/media_types/video/transcoders.py | 115 +++++++++++++----- .../mediagoblin/media_displays/video.html | 7 +- 3 files changed, 139 insertions(+), 92 deletions(-) diff --git a/mediagoblin/media_types/video/processing.py b/mediagoblin/media_types/video/processing.py index 52047ae4..09f8a0d9 100644 --- a/mediagoblin/media_types/video/processing.py +++ b/mediagoblin/media_types/video/processing.py @@ -14,10 +14,10 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -import Image import tempfile import pkg_resources import os +import logging from celery.task import Task from celery import registry @@ -29,21 +29,9 @@ from mediagoblin.process_media.errors import BaseProcessingFail, BadMediaFail from mediagoblin.process_media import mark_entry_failed from . import transcoders -import gobject -gobject.threads_init() - -import gst -import arista -import logging - -from arista.transcoder import TranscoderOptions - THUMB_SIZE = 180, 180 MEDIUM_SIZE = 640, 640 -ARISTA_DEVICE = 'devices/web-advanced.json' -ARISTA_PRESET = None - loop = None # Is this even used? logger = logging.getLogger(__name__) @@ -63,11 +51,6 @@ def process_video(entry): and attaches callbacks to that child process, hopefully, the entry-complete callback will be called when the video is done. """ - - ''' Empty dict, will store data which will be passed to the callback - functions ''' - info = {} - workbench = mgg.workbench_manager.create_workbench() queued_filepath = entry['queued_media_file'] @@ -75,57 +58,65 @@ def process_video(entry): mgg.queue_store, queued_filepath, 'source') - ''' Initialize arista ''' - arista.init() + medium_filepath = create_pub_filepath( + entry, '640p.webm') - ''' Loads a preset file which specifies the format of the output video''' - device = arista.presets.load( - pkg_resources.resource_filename( - __name__, - ARISTA_DEVICE)) - - # FIXME: Is this needed since we only transcode one video? - queue = arista.queue.TranscodeQueue() - - info['tmp_file'] = tempfile.NamedTemporaryFile(delete=False) - - info['medium_filepath'] = create_pub_filepath( - entry, 'video.webm') - - info['thumb_filepath'] = create_pub_filepath( + thumbnail_filepath = create_pub_filepath( entry, 'thumbnail.jpg') - # With the web-advanced.json device preset, this will select - # 480p WebM w/ OGG Vorbis - preset = device.presets[ARISTA_PRESET or device.default] - logger.debug('preset: {0}'.format(preset)) + # Create a temporary file for the video destination + tmp_dst = tempfile.NamedTemporaryFile() - opts = TranscoderOptions( - 'file://' + queued_filename, # Arista did it this way, IIRC - preset, - info['tmp_file'].name) + with tmp_dst: + # Transcode queued file to a VP8/vorbis file that fits in a 640x640 square + transcoder = transcoders.VideoTranscoder(queued_filename, tmp_dst.name) - queue.append(opts) + # Push transcoded video to public storage + mgg.public_store.get_file(medium_filepath, 'wb').write( + tmp_dst.read()) - info['entry'] = entry + entry['media_files']['webm_640'] = medium_filepath - queue.connect("entry-start", _transcoding_start, info) - queue.connect("entry-pass-setup", _transcoding_pass_setup, info) - queue.connect("entry-error", _transcoding_error, info) - queue.connect("entry-complete", _transcoding_complete, info) + # Save the width and height of the transcoded video + entry['media_data']['video'] = { + u'width': transcoder.dst_data.videowidth, + u'height': transcoder.dst_data.videoheight} - # Add data to the info dict, making it available to the callbacks - info['loop'] = gobject.MainLoop() - info['queued_filename'] = queued_filename - info['queued_filepath'] = queued_filepath - info['workbench'] = workbench - info['preset'] = preset + # Create a temporary file for the video thumbnail + tmp_thumb = tempfile.NamedTemporaryFile() - info['loop'].run() + with tmp_thumb: + # Create a thumbnail.jpg that fits in a 180x180 square + transcoders.VideoThumbnailer(queued_filename, tmp_thumb.name) - logger.debug('info: {0}'.format(info)) + # Push the thumbnail to public storage + mgg.public_store.get_file(thumbnail_filepath, 'wb').write( + tmp_thumb.read()) + entry['media_files']['thumb'] = thumbnail_filepath + + + # Push original file to public storage + queued_file = file(queued_filename, 'rb') + + with queued_file: + original_filepath = create_pub_filepath( + entry, + queued_filepath[-1]) + + with mgg.public_store.get_file(original_filepath, 'wb') as \ + original_file: + original_file.write(queued_file.read()) + + entry['media_files']['original'] = original_filepath + + mgg.queue_store.delete_file(queued_filepath) + + + # Save the MediaEntry + entry.save() + def __create_thumbnail(info): thumbnail = tempfile.NamedTemporaryFile() @@ -139,6 +130,7 @@ def __create_thumbnail(info): mgg.public_store.get_file(info['thumb_filepath'], 'wb').write( thumbnail.read()) + info['entry']['media_files']['thumb'] = info['thumb_filepath'] info['entry'].save() @@ -267,6 +259,9 @@ class ProcessMedia(Task): 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. diff --git a/mediagoblin/media_types/video/transcoders.py b/mediagoblin/media_types/video/transcoders.py index d305d5fc..8115bb38 100644 --- a/mediagoblin/media_types/video/transcoders.py +++ b/mediagoblin/media_types/video/transcoders.py @@ -17,7 +17,7 @@ from __future__ import division import sys import logging - +import pdb _log = logging.getLogger(__name__) logging.basicConfig() @@ -28,14 +28,17 @@ try: gobject.threads_init() except: _log.error('Could not import gobject') + raise Exception() try: import pygst pygst.require('0.10') import gst + from gst import pbutils from gst.extend import discoverer except: _log.error('pygst could not be imported') + raise Exception() class VideoThumbnailer: @@ -201,12 +204,14 @@ class VideoThumbnailer: gobject.idle_add(self.loop.quit) -class VideoTranscoder(): +class VideoTranscoder: ''' Video transcoder + Transcodes the SRC video file to a VP8 WebM video file at DST + TODO: - - Currently not working + - Audio pipeline ''' def __init__(self, src, dst, **kwargs): _log.info('Initializing VideoTranscoder...') @@ -215,7 +220,7 @@ class VideoTranscoder(): self.source_path = src self.destination_path = dst - self.destination_dimensions = kwargs.get('dimensions') or (180, 180) + self.destination_dimensions = kwargs.get('dimensions') or (640, 640) if not type(self.destination_dimensions) == tuple: raise Exception('dimensions must be tuple: (width, height)') @@ -253,12 +258,14 @@ class VideoTranscoder(): self.data = data + self._on_discovered() + # Tell the transcoding pipeline to start running self.pipeline.set_state(gst.STATE_PLAYING) _log.info('Transcoding...') def _on_discovered(self): - self.__setup_capsfilter() + self.__setup_videoscale_capsfilter() def _setup_pass(self): self.pipeline = gst.Pipeline('VideoTranscoderPipeline') @@ -276,7 +283,8 @@ class VideoTranscoder(): self.pipeline.add(self.ffmpegcolorspace) self.videoscale = gst.element_factory_make('videoscale', 'videoscale') - self.videoscale.set_property('method', 'bilinear') + self.videoscale.set_property('method', 2) # I'm not sure this works + self.videoscale.set_property('add-borders', 0) self.pipeline.add(self.videoscale) self.capsfilter = gst.element_factory_make('capsfilter', 'capsfilter') @@ -286,16 +294,36 @@ class VideoTranscoder(): self.vp8enc.set_property('quality', 6) self.vp8enc.set_property('threads', 2) self.vp8enc.set_property('speed', 2) + self.pipeline.add(self.vp8enc) + + + # Audio + self.audioconvert = gst.element_factory_make('audioconvert', 'audioconvert') + self.pipeline.add(self.audioconvert) + + self.vorbisenc = gst.element_factory_make('vorbisenc', 'vorbisenc') + self.vorbisenc.set_property('quality', 0.7) + self.pipeline.add(self.vorbisenc) + self.webmmux = gst.element_factory_make('webmmux', 'webmmux') self.pipeline.add(self.webmmux) self.filesink = gst.element_factory_make('filesink', 'filesink') + self.filesink.set_property('location', self.destination_path) + self.pipeline.add(self.filesink) self.filesrc.link(self.decoder) self.ffmpegcolorspace.link(self.videoscale) self.videoscale.link(self.capsfilter) - self.vp8enc.link(self.filesink) + self.capsfilter.link(self.vp8enc) + self.vp8enc.link(self.webmmux) + + # Audio + self.audioconvert.link(self.vorbisenc) + self.vorbisenc.link(self.webmmux) + + self.webmmux.link(self.filesink) self._setup_bus() @@ -303,39 +331,43 @@ class VideoTranscoder(): ''' Callback called when ``decodebin2`` has a pad that we can connect to ''' - pad.link( - self.ffmpegcolorspace.get_pad('sink')) + _log.debug('Linked {0}'.format(pad)) + + #pdb.set_trace() + + if self.ffmpegcolorspace.get_pad_template('sink')\ + .get_caps().intersect(pad.get_caps()).is_empty(): + pad.link( + self.audioconvert.get_pad('sink')) + else: + pad.link( + self.ffmpegcolorspace.get_pad('sink')) def _setup_bus(self): self.bus = self.pipeline.get_bus() self.bus.add_signal_watch() self.bus.connect('message', self._on_message) - def __setup_capsfilter(self): - thumbsizes = self.calculate_resize() # Returns tuple with (width, height) + def __setup_videoscale_capsfilter(self): + caps = ['video/x-raw-yuv', 'pixel-aspect-ratio=1/1'] + + if self.data.videoheight > self.data.videowidth: + # Whoa! We have ourselves a portrait video! + caps.append('height={0}'.format( + self.destination_dimensions[1])) + else: + # It's a landscape, phew, how normal. + caps.append('width={0}'.format( + self.destination_dimensions[0])) self.capsfilter.set_property( 'caps', - gst.caps_from_string('video/x-raw-rgb, width={width}, height={height}'.format( - width=thumbsizes[0], - height=thumbsizes[1] - ))) - - def calculate_resize(self): - x_ratio = self.destination_dimensions[0] / self.data.videowidth - y_ratio = self.destination_dimensions[1] / self.data.videoheight - - if self.data.videoheight > self.data.videowidth: - # We're dealing with a portrait! - dimensions = ( - int(self.data.videowidth * y_ratio), - 180) - else: - dimensions = ( - 180, - int(self.data.videoheight * x_ratio)) - - return dimensions + gst.caps_from_string( + ', '.join(caps))) + gst.DEBUG_BIN_TO_DOT_FILE ( + self.pipeline, + gst.DEBUG_GRAPH_SHOW_ALL, + 'supersimple-debug-graph') def _on_message(self, bus, message): _log.debug((bus, message)) @@ -343,12 +375,25 @@ class VideoTranscoder(): t = message.type if t == gst.MESSAGE_EOS: - self.__stop() + self._discover_dst_and_stop() _log.info('Done') elif t == gst.MESSAGE_ERROR: _log.error((bus, message)) self.__stop() + def _discover_dst_and_stop(self): + self.dst_discoverer = discoverer.Discoverer(self.destination_path) + + self.dst_discoverer.connect('discovered', self.__dst_discovered) + + self.dst_discoverer.discover() + + + def __dst_discovered(self, data, is_media): + self.dst_data = data + + self.__stop() + def __stop(self): _log.debug(self.loop) @@ -358,6 +403,9 @@ class VideoTranscoder(): if __name__ == '__main__': + import os + os.environ["GST_DEBUG_DUMP_DOT_DIR"] = "/tmp" + os.putenv('GST_DEBUG_DUMP_DOT_DIR', '/tmp') from optparse import OptionParser parser = OptionParser( @@ -396,4 +444,5 @@ if __name__ == '__main__': if options.action == 'thumbnail': VideoThumbnailer(*args) elif options.action == 'video': - VideoTranscoder(*args) + transcoder = VideoTranscoder(*args) + pdb.set_trace() diff --git a/mediagoblin/templates/mediagoblin/media_displays/video.html b/mediagoblin/templates/mediagoblin/media_displays/video.html index 22b19240..bff9889a 100644 --- a/mediagoblin/templates/mediagoblin/media_displays/video.html +++ b/mediagoblin/templates/mediagoblin/media_displays/video.html @@ -1,16 +1,19 @@ {% extends 'mediagoblin/user_pages/media.html' %} {% block mediagoblin_media %} -

{% endif %} + {% if allow_registration %} +

+ {% trans %}Don't have an account yet?{% endtrans %} + {%- trans %}Create one here!{% endtrans %} +

+ {% endif %} {{ wtforms_util.render_divs(login_form) }} +

+ + {% trans %}Forgot your password?{% endtrans %} +

@@ -38,20 +48,6 @@ {% endif %} - {% if allow_registration %} -

- {% trans %}Don't have an account yet?{% endtrans %} -
- - {%- trans %}Create one here!{% endtrans %} -

-

- {% trans %}Forgot your password?{% endtrans %} -
- - {%- trans %}Change it!{% endtrans %} -

- {% endif %} {% endblock %} From 1b36a8e80c09307a2c4ddf8cc8bfe786a9d86f7d Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Fri, 4 Nov 2011 02:20:26 +0100 Subject: [PATCH 037/302] On second thought, let's use this title for forgot_password.html --- mediagoblin/templates/mediagoblin/auth/forgot_password.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediagoblin/templates/mediagoblin/auth/forgot_password.html b/mediagoblin/templates/mediagoblin/auth/forgot_password.html index c7f01678..9b821426 100644 --- a/mediagoblin/templates/mediagoblin/auth/forgot_password.html +++ b/mediagoblin/templates/mediagoblin/auth/forgot_password.html @@ -24,7 +24,7 @@ method="POST" enctype="multipart/form-data"> {{ csrf_token }}
-

{% trans %}Forgot your password?{% endtrans %}

+

{% trans %}Recover password{% endtrans %}

{{ wtforms_util.render_divs(fp_form) }}
From 80c9a7ee51590923a3b9f7a07419679af4a368d8 Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Fri, 4 Nov 2011 02:30:07 +0100 Subject: [PATCH 038/302] Small style changes to navigation buttons --- mediagoblin/static/css/base.css | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css index b026a819..23a7e6c5 100644 --- a/mediagoblin/static/css/base.css +++ b/mediagoblin/static/css/base.css @@ -290,11 +290,14 @@ img.media_icon{ /* navigation */ .navigation_button{ - width: 139px; + width: 135px; display: block; float: left; text-align: center; - background-color: #222; + background-color: #1d1d1d; + border: 1px solid; + border-color: #2c2c2c #232323 #1a1a1a; + border-radius: 3px; text-decoration: none; padding: 12px 0pt; font-size: 2em; @@ -306,7 +309,7 @@ p.navigation_button{ } .navigation_left{ - margin-right: 2px; + margin-right: 6px; } /* messages */ From da76a8cbaa06ba63533f60051c66f08cd0e7baf4 Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Fri, 4 Nov 2011 02:34:00 +0100 Subject: [PATCH 039/302] Tiny padding change to vertically center navigation button arrows --- mediagoblin/static/css/base.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css index 23a7e6c5..afd10207 100644 --- a/mediagoblin/static/css/base.css +++ b/mediagoblin/static/css/base.css @@ -299,7 +299,7 @@ img.media_icon{ border-color: #2c2c2c #232323 #1a1a1a; border-radius: 3px; text-decoration: none; - padding: 12px 0pt; + padding: 8px 0px 14px; font-size: 2em; margin: 0 0 20px } From d871f4e0d107268fab9dc33c648b1a6f7a99a652 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Fri, 4 Nov 2011 08:23:28 -0500 Subject: [PATCH 040/302] Updating translations --- .../i18n/de/LC_MESSAGES/mediagoblin.mo | Bin 11089 -> 11119 bytes .../i18n/de/LC_MESSAGES/mediagoblin.po | 14 +- .../i18n/fr/LC_MESSAGES/mediagoblin.mo | Bin 11272 -> 11583 bytes .../i18n/fr/LC_MESSAGES/mediagoblin.po | 92 ++-- .../i18n/ro/LC_MESSAGES/mediagoblin.mo | Bin 11051 -> 11067 bytes .../i18n/ro/LC_MESSAGES/mediagoblin.po | 8 +- .../i18n/ru/LC_MESSAGES/mediagoblin.mo | Bin 13895 -> 13899 bytes .../i18n/ru/LC_MESSAGES/mediagoblin.po | 6 +- .../i18n/te/LC_MESSAGES/mediagoblin.mo | Bin 0 -> 10812 bytes .../i18n/te/LC_MESSAGES/mediagoblin.po | 498 ++++++++++++++++++ 10 files changed, 568 insertions(+), 50 deletions(-) create mode 100644 mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.mo create mode 100644 mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.po diff --git a/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.mo index b65212ebe441861fa088710063c6b1713fc3fc3b..056e3ecaac4d6dbbadcfc480f2279b81df03f85c 100644 GIT binary patch delta 1066 zcmYMyO-NKx6u|Lg<=157XZA6TuQW41O2f!3HIjlzNGWWggl}fv=yRMq^4_z+MbpP3 zT4-1hTBJcqTWK~$MU*=ss9gmT)U;?3F04%u^}mhOFwF1X^WMGZ+{w37{wmEfKB)TPh!y)k!lQKE{>xQC(*+DEAd>v z$Xez_cn-__lK8ve7J*U%_fQw|7;oTf%)`E|BGe)=q*l3#ML3Om-6N!CS-=APjMOGS zunhA9BI~do*-~1u0(%09^ad9RR1uiO?f4RNFol`;4Ryk0?8R($U5{bhiyrENAL3VR zHbiQ$Vw*?_cH$I9Fo-${uSzJvK%d|Ww%{GqiQgl+pifEAkt4 zVU_f&4ZBb$p1@38z(#z7I#K4X^twXKVSWJh4IaT`(k^m_flf5N;v$}6?k9`BkztJE z80v(-P@k-Y2J6C)C#SMX3Jx~xYi?+&spsSCFkP?iv|}oF$n@e)voUNtre~>PQ-w|A zP|#9?X3SQHhpeD$s)(2TQaZRM6tg|UvXvDxI&2j+`Yks!V27e!t)ZWUiHAqPRz|1k zy65ALXUsoPVariQ)Ktp#cFT!)EM_UsbpDTw0b7lZ^jnenXZ>FCu75V8yu-2_%lP-M gWw^Eq8_Et1P=GUJjs(4%eSyAJ^E1g;f$MpH0C4-Q8~^|S delta 1019 zcmXZaPe>GT6u|LkrI{IY!x*FBm5fATWVi$P7;63oOO%?IP47eMqg6#?3g6l{k&mEYGnF-y*fi zC#=C=xB)9eB5W!3sPU7btiM5&z#al)xC0+!G0tNlzC%s8fc?0HT5uP;G-Cv{;5)d4 zK_k+DMYSU3*o@P73ZwWHc~rt#vgsSxcnq(jCVq|NkT<9sd_!%)Z`2bi-AP-p7WK`V zu?Rbm)0S>ri?O_esQbEDhu1KL*+&fSF$fUVqj`vWbgxi*x`0}M)cd`yz{^Yxw&87T z#5vS&Vi}KP{Vu=PanwSG^4>yi=_GPxWrly&$UM>}S;n(ivfJONAH&QaAh+ZTYGK9n z>jbu-CU&t9pJFS{q9*!|y6z_yWA$GD1naO%Iz^5!(28&7ox^j?|Dv8qFWDS)P!oPe z{fcX7uom8sn=UFZYinw4Kh)CD#IK~sa=rb187u83Ezilco7jjQjoKM=G(YHw54+xI zEa?o#b4!(1*MtUaH+Cfv8}v*n;Tb!T=Hc_bJ&k5KW#aafWh$x;$Z02)veTZGkxqYP wh8)+kbUoM*si- diff --git a/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.po index 5baab62e..5c4ef0d0 100644 --- a/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.po @@ -16,8 +16,8 @@ msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://bugs.foocorp.net/projects/mediagoblin/issues\n" "POT-Creation-Date: 2011-11-01 23:14-0500\n" -"PO-Revision-Date: 2011-11-02 04:13+0000\n" -"Last-Translator: cwebber \n" +"PO-Revision-Date: 2011-11-02 15:18+0000\n" +"Last-Translator: piratenpanda \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" @@ -259,7 +259,7 @@ msgstr "" #: mediagoblin/templates/mediagoblin/root.html:38 msgid "Excited to join us?" -msgstr "Neugierig dich uns anzuschliessen?" +msgstr "Neugierig dich uns anzuschließen?" #: mediagoblin/templates/mediagoblin/root.html:39 #, python-format @@ -292,8 +292,8 @@ msgstr "Dein Passwort wurde geändert. Versuche dich jetzt einzuloggen." msgid "" "Check your inbox. We sent an email with a URL for changing your password." msgstr "" -"Prüfe deinen Posteingang. Wir haben dir eine Email geschickt mit einer URL, " -"um dein Passwort zu ändern." +"Prüfe deinen Posteingang. Wir haben dir eine Email mit einem Link geschickt," +" mit dem du dein Passwort ändern kannst." #: mediagoblin/templates/mediagoblin/auth/fp_verification_email.txt:19 #, python-format @@ -539,11 +539,11 @@ msgstr "Ja, wirklich löschen" #: mediagoblin/user_pages/views.py:142 msgid "Empty comments are not allowed." -msgstr "" +msgstr "Leere Kommentare sind nicht erlaubt." #: mediagoblin/user_pages/views.py:148 msgid "Comment posted!" -msgstr "" +msgstr "Kommentar hinzugefügt!" #: mediagoblin/user_pages/views.py:181 msgid "You are about to delete another user's media. Proceed with caution." diff --git a/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.mo index eaa18426582b2bd390213b24a816e85dab128988..90e833039023edeafae9a63dc03855e1fec26bb7 100644 GIT binary patch delta 2652 zcmZXVU2GiH700iWkl>{>!O(oTj(zQftWE4~+M1LaH)((nCD=)DKGZL$#*i zb7!`()pmtcMWt1d&>)a_Aq`L43JSOdq#z+!NFPd7sD%1bRq8`&d5TaUs=z}w-y zy-Ix-o`93^J@^Rh{;X0D!g<&YUxe%7>oA6Iz)f(hPpMDAyWwN-zCP7bx3GAJjUo6x z&Cfp3)gZtqh;ZNc1TB(1-UqRV_ncL*M zzrknWW}^HK{27#chFZIn8fS3`-UFLZQuGT*71SG0BK;7Gp=DQc zei6O^_rX8I3D|>miF_K07JdN5!6#OD8E)YDRmgoUb%ljo_z@h1-NU3A?uQ5AMfeqX z70Lx0MwDWy4#EYv0L76H;7#x*tj@q&plIe%NGvLbH^ZmlHuxO$)B{Sr#^MwkJN7E| zb=ZJX<6lD!cjDDWcmN)Q@4{Q*76hYV|Jd@g8+&d$G_F6tZ(`rwd-w5InetpZb~^Dw z7kFuuOlW_>xXjkQMUy3Z^7^N*E_w@5RGUkdKi<~UHQH&LB|V>bX=YQ?Fkz}qsQsuB zr)KhV-hql<`-`%CV8`jPqoGT^AmFQMQ@7rcXg08+c3jhp(!}UEiDKYP(llBA%#O*2 zjf*|s=(^E<(rJ6CjpT+P@Ma_KwR3txH=>YlmoVY1;*(p)Add} zu}$1{IlcsG{ty6-Fsm25?e{bjB1nWIKrn{%aP76Q$0AM15eL&+G3~l zVNjjqp7WW}b2hYk`D*WMS8Hi3FnUm(HHn?Gg+~(9Y}9!%EkYmy-^3C_O&^akhs*qU z%_wwat{E+M+ByrhX?QkZ+xR>geP(8=JQ$06Y3h+@$;W~h&YRWDHKJ61iQU+9&eYWX zQA6tC*~F-`MQSO_>W=nwr=4*%wQ;E?|Gt!n0!S)#P%R_ln;XuCRZri6<11cKC&?ex%J=LX8$XrBabg>I zL-r-vQZorfJz$)lSn@en)(f4aiPt1~`S*8TZcS0`>!K#xw$2tAbtpzMrM(QnTi0p3 znmSynh>*i5YZ@=RA->hurQ>1LAWKs)W zJAF_cz7PjdViNVB^%pEWTPgw3L>Wy%RZ4R=d*_()p!ZQPOWhF$fY3Iw>Ebo$#u9&D)?i_9w z>h_B^_;!{ABd$`foU&!4u?Zb^&u3K>?5f_pMIu#Eu}Kp0G^*`kb#WBdS45)I#kgqT1|z_FHFc_r zltP3jrJM4!pT9NqlfKhYCJm8<>^j|$38!dt(b9$7?9!VKg+6`Y@*nMLZCtD3_FV6- zERXO0&$<)%Qz#1;=q~xbEJ;zOnl3a#vouK`No+9PilHk?o;41UNlIwo6(!`~tIl*U z%6uV1_52UjL77fRgQ5jYLt0%vT|2>@MSMEwTpBG~DyUi+*|bZoR#W&#gRRbb?(*p; z?;K$Ry4PQbGMOh+!@D;yhQd4^9vUzq`84G*UY^e)%TEy^E~oj+!@a%3<)IO(k1DJ* zsK|VdPX1{4-Y&g7IC62_$+N{EyP+diCs`43r(M&Bo#X$lCCvy$wc*OFEV}T2C95gx MN1@68wD+$60;eqbMgRZ+ delta 1545 zcmXxjUu;uV90%}UH#SBYOtwIwjPsd_Ze)aHXf~0F(`fXz_Y}`^dv7`C z-c3xjA;d+qXfP){h(Up9u#3h&^}&#cXk)^gKKbu~kocev{$Vf1VB-9qt!tWm&N=s< z`}>{mZNGf-m6?y9sx5vHBD%YS2w%Foljs(_4)?)}yNI5F-@z7`juHj%FdTu`;M4GL zcmz)GCfWqwg0=8HSb!zC5k^~y!Y~0RU|%a0X)^}%SZIQ0A!?C^FTf9BJ?!2?v<>d9 zdI&aSejK7#%E9fhSY1C4W0=1W?}azvR`?f;!~d$+SzD1Pf`zd*BGjT8XigeH)A6fS z-+-pToA7b?5i|{NM3o^JftTSV`~lvnuHR&9jjX^6SdXE)N$?s(50ow@i1uSJ3HQRY zuo0G_DR={#M81dSBzIsZjIG;Xr6lxcEO9#gT-$! zSj6DI4x$wN3Ze%64oy@|sAf7HfDLd89)mM*5H7(qyak706S_2s9EIk$a0Z%07puMl zO+#gfdPVvi15@x9*bD2?-cdLRN8w9w1YUvTDhLg}FScY}*H)tCC6Pjek zl52@Q3L7wg9-3Ev23m9&?-YaMSojw{0jJQ`W3U7nT!9Oa^{o9Xu0j*#&(K`|wWoZc zzIofheJs6ycwn$6jZgStOZk1%(sGq!`JNnR*?FGHaLFF14#w<2`KPmv7ufxtJX!uD z(j3yu^;h(#yM~I6-~lUmfn*L>tiYx6To)sov#jShR>qTf6!*X1}?wQj%h>QsOF3hi1LNuWra!O17{Roe;`$eO9@|BzJ9XNADjg&2iTc zxa06V2E7bZAz4OXQu)k}Cs_`A@z~XRae72@bt>R2CtOkfDVhoCuQ#1&v4rF_?&ZxR za3JM#TQ9e^>f!K<`rSQAeLLK%YuYYry;()G&j~K+2*U7ucG?`iU@0~4Nn87|c!=u< z8@p=!Uj0SvAD!Ovqy8j*Ko4wX<)%bUXbbZKrh-C23LHtZ_DF+5DoSyw$J&Qt6YiYl z2&9!0t7VvtKr5y7jP={?ZJ}{}qy06#+_Y2AcEswY92, 2011. # , 2011. # , 2011. # , 2011. @@ -13,8 +14,8 @@ msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://bugs.foocorp.net/projects/mediagoblin/issues\n" "POT-Creation-Date: 2011-11-01 23:14-0500\n" -"PO-Revision-Date: 2011-11-02 04:13+0000\n" -"Last-Translator: cwebber \n" +"PO-Revision-Date: 2011-11-04 10:05+0000\n" +"Last-Translator: chesuidayeur \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -42,7 +43,7 @@ msgstr "Confirmer le mot de passe" #: mediagoblin/auth/forms.py:39 msgid "Type it again here to make sure there are no spelling mistakes." msgstr "" -"Tapez-le à nouveau ici pour vous assurer qu'il n'ya pas de fautes " +"Tapez-le à nouveau ici pour vous assurer qu'il n'y a pas de fautes " "d'orthographe." #: mediagoblin/auth/forms.py:42 @@ -82,6 +83,8 @@ msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." msgstr "" +"Impossible d'envoyer un email de récupération de mot de passe : votre compte" +" est inactif ou bien l'email de votre compte n'a pas été vérifiée." #: mediagoblin/edit/forms.py:24 mediagoblin/submit/forms.py:27 msgid "Title" @@ -103,6 +106,8 @@ msgstr "La légende ne peut pas être laissée vide." msgid "" "The title part of this media's URL. You usually don't need to change this." msgstr "" +"Le nom de ce media dans l'URL. Vous n'avez normalement pas besoin de le " +"changer" #: mediagoblin/edit/forms.py:40 msgid "Bio" @@ -130,7 +135,7 @@ msgstr "" #: mediagoblin/process_media/errors.py:44 msgid "Invalid file given for media type." -msgstr "Invalide fichier donné pour le type de média." +msgstr "Le fichier envoyé ne correspond pas au type de média." #: mediagoblin/submit/forms.py:25 msgid "File" @@ -138,7 +143,7 @@ msgstr "Fichier" #: mediagoblin/submit/forms.py:30 msgid "Description of this work" -msgstr "" +msgstr "Descriptif pour ce travail" #: mediagoblin/submit/views.py:46 msgid "You must provide a file." @@ -158,7 +163,7 @@ msgstr "Zut!" #: mediagoblin/templates/mediagoblin/404.html:24 msgid "There doesn't seem to be a page at this address. Sorry!" -msgstr "Il ne semble pas être une page à cette adresse. Désolé!" +msgstr "Il ne semble pas y avoir de page à cette adresse. Désolé !" #: mediagoblin/templates/mediagoblin/404.html:26 msgid "" @@ -166,11 +171,11 @@ msgid "" " been moved or deleted." msgstr "" "Si vous êtes sûr que l'adresse est correcte, peut-être la page que vous " -"recherchez a été déplacé ou supprimé." +"recherchez a été déplacée ou supprimée." #: mediagoblin/templates/mediagoblin/404.html:32 msgid "Image of 404 goblin stressing out" -msgstr "Image de 404 gobelin stresser" +msgstr "Image de 404 gobelin angoissé" #: mediagoblin/templates/mediagoblin/base.html:22 msgid "GNU MediaGoblin" @@ -199,12 +204,12 @@ msgid "" "Powered by MediaGoblin, a GNU project" msgstr "" -"Propulsé par MediaGoblin , un GNU de projet" +"Propulsé par MediaGoblin , un projet " +"GNU" #: mediagoblin/templates/mediagoblin/root.html:24 msgid "Explore" -msgstr "" +msgstr "Explorer" #: mediagoblin/templates/mediagoblin/root.html:27 msgid "Hi there, media lover! MediaGoblin is..." @@ -219,15 +224,15 @@ msgid "" "A place for people to collaborate and show off original and derived " "creations!" msgstr "" -"Un lieu pour les personnes de collaborer et de montrer des créations " -"originales et dérivées!" +"Un espace de création collaboratif : montrez vos œuvres, originales ou " +"dérivées !" #: mediagoblin/templates/mediagoblin/root.html:31 msgid "" "Free, as in freedom. (We’re a GNU project, " "after all.)" msgstr "" -"Logiciel libre. (Nous sommes une GNU projet, " +"Logiciel libre. (Nous sommes un projet GNU " "après tout.)" #: mediagoblin/templates/mediagoblin/root.html:32 @@ -235,8 +240,8 @@ msgid "" "Aiming to make the world a better place through decentralization and " "(eventually, coming soon!) federation!" msgstr "" -"Visant à rendre le monde meilleur grâce à la décentralisation et " -"(éventuellement, venir bientôt!) fédération!" +"Une tentative de rendre le monde meilleur grâce à la décentralisation et (à " +"terme, et pour bientôt !) la fédération !" #: mediagoblin/templates/mediagoblin/root.html:33 msgid "" @@ -258,7 +263,7 @@ msgstr "" #: mediagoblin/templates/mediagoblin/root.html:38 msgid "Excited to join us?" -msgstr "" +msgstr "Envi de vous joindre à nous ?" #: mediagoblin/templates/mediagoblin/root.html:39 #, python-format @@ -267,27 +272,33 @@ msgid "" " or\n" " Set up MediaGoblin on your own server" msgstr "" +"Créez gratuitement en compte\n" +" ou\n" +" Installez MediaGoblin sur votre propre serveur" #: mediagoblin/templates/mediagoblin/root.html:53 msgid "Most recent media" -msgstr "" +msgstr "Tout derniers media" #: mediagoblin/templates/mediagoblin/auth/change_fp.html:29 msgid "Enter your new password" -msgstr "" +msgstr "Entrez un nouveau mot de passe" #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:29 msgid "Enter your username or email" -msgstr "" +msgstr "Entrez votre nom d'utilisateur ou votre email" #: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 msgid "Your password has been changed. Try to log in now." msgstr "" +"Votre mot de passe a été changé. Essayez maintenant de vous identifier." #: mediagoblin/templates/mediagoblin/auth/fp_email_sent.html:22 msgid "" "Check your inbox. We sent an email with a URL for changing your password." msgstr "" +"Verifiez votre boîte de réception. Nous vous avons envoyé un email avec une " +"URL vous permettant de changer votre mot de passe." #: mediagoblin/templates/mediagoblin/auth/fp_verification_email.txt:19 #, python-format @@ -302,10 +313,19 @@ msgid "" "If you think this is an error, just ignore this email and continue being\n" "a happy goblin!" msgstr "" +"Bonjour %(username)s,\n" +"\n" +"Pour changer votre mot de passe GNU MediaGoblin, ouvrez l'URL suivante dans \n" +"votre navigateur internet :\n" +"\n" +"%(verification_url)s\n" +"\n" +"Si vous pensez qu'il s'agit d'une erreur, ignorez simplement cet email et restez\n" +"un goblin heureux !" #: mediagoblin/templates/mediagoblin/auth/login.html:30 msgid "Logging in failed!" -msgstr "Connexion a échoué!" +msgstr "La connexion a échoué!" #: mediagoblin/templates/mediagoblin/auth/login.html:43 msgid "Don't have an account yet?" @@ -317,11 +337,11 @@ msgstr "Créez-en un ici!" #: mediagoblin/templates/mediagoblin/auth/login.html:49 msgid "Forgot your password?" -msgstr "" +msgstr "Vous avez oublié votre mot de passe ?" #: mediagoblin/templates/mediagoblin/auth/login.html:52 msgid "Change it!" -msgstr "" +msgstr "Changez-le !" #: mediagoblin/templates/mediagoblin/auth/register.html:27 msgid "Create an account!" @@ -396,7 +416,7 @@ msgstr "Voulez-vous vraiment supprimer %(title)s ?" #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:50 msgid "Delete Permanently" -msgstr "" +msgstr "Supprimer définitivement" #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:22 msgid "Media processing panel" @@ -419,7 +439,7 @@ msgstr "Aucun média en transformation" #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:50 msgid "These uploads failed to process:" -msgstr "Ces ajouts n'etaient pas processé:" +msgstr "Le traitement de ces ajouts a échoué :" #: mediagoblin/templates/mediagoblin/user_pages/user.html:39 #: mediagoblin/templates/mediagoblin/user_pages/user.html:59 @@ -428,7 +448,7 @@ msgstr "Vérification d'email nécessaire" #: mediagoblin/templates/mediagoblin/user_pages/user.html:42 msgid "Almost done! Your account still needs to be activated." -msgstr "Presque fini! Votre compte a encore besoin d'être activé." +msgstr "Presque fini ! Votre compte a encore besoin d'être activé." #: mediagoblin/templates/mediagoblin/user_pages/user.html:47 msgid "" @@ -479,7 +499,7 @@ msgstr "Modifier le profil" #: mediagoblin/templates/mediagoblin/user_pages/user.html:96 msgid "This user hasn't filled in their profile (yet)." -msgstr "Cet utilisateur n'a pas rempli leur profil (encore)." +msgstr "Cet utilisateur n'a pas (encore) rempli son profil." #: mediagoblin/templates/mediagoblin/user_pages/user.html:122 #, python-format @@ -491,8 +511,8 @@ msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." msgstr "" -"C'est là où vos médias apparaît, mais vous ne semblez pas avoir quoi que ce " -"soit encore ajouté." +"C'est là où vos médias apparaîssent, mais vous ne semblez pas avoir encore " +"ajouté quoi que ce soit." #: mediagoblin/templates/mediagoblin/user_pages/user.html:141 msgid "Add media" @@ -500,11 +520,11 @@ msgstr "Ajouter des médias" #: mediagoblin/templates/mediagoblin/user_pages/user.html:147 msgid "There doesn't seem to be any media here yet..." -msgstr "Il ne semble pas être un média encore là ..." +msgstr "Il ne semble pas y avoir de média là, pour l'instant ..." #: mediagoblin/templates/mediagoblin/utils/feed_link.html:21 msgid "feed icon" -msgstr "icon de flux" +msgstr "icone de flux" #: mediagoblin/templates/mediagoblin/utils/feed_link.html:23 msgid "Atom feed" @@ -512,11 +532,11 @@ msgstr "flux Atom" #: mediagoblin/templates/mediagoblin/utils/pagination.html:40 msgid "Newer" -msgstr "" +msgstr "Nouveaux" #: mediagoblin/templates/mediagoblin/utils/pagination.html:46 msgid "Older" -msgstr "" +msgstr "Anciens" #: mediagoblin/user_pages/forms.py:24 msgid "Comment" @@ -524,15 +544,15 @@ msgstr "Commentaire" #: mediagoblin/user_pages/forms.py:30 msgid "I am sure I want to delete this" -msgstr "" +msgstr "Je suis sûr de vouloir supprimer cela" #: mediagoblin/user_pages/views.py:142 msgid "Empty comments are not allowed." -msgstr "" +msgstr "Les commentaires vides ne sont pas autorisés." #: mediagoblin/user_pages/views.py:148 msgid "Comment posted!" -msgstr "" +msgstr "Votre commentaire a été posté !" #: mediagoblin/user_pages/views.py:181 msgid "You are about to delete another user's media. Proceed with caution." diff --git a/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.mo index 6e9c88976cfa9eff49a76acdd8c6ca29c937de0c..2ab9cf8b6ab09d244718b9c17c0cfccdc88f9e22 100644 GIT binary patch delta 983 zcmX}qUr19?9Ki9PnA$2cvt{P8oBuLbvYZ4>laWD#3i`(i`p2EEdC~34-5n7K7b|@0 z%?Jr9@TG`CT0~M0VLq&&9->}CdNbUEJr?!U_m`t_IiKG-=brt3=bZaE{wh9mzTEpz zCh}*qNS%ljwumg^0!DGJLF5#cZxyM*Gk5}17{*!b!DWnLbEAk4hfC&goW6%uSQc2B z_u)nQbpi4IC3YC#kqMd&IE@qd99LuSHj!F9ggPHD^;1Z0xrXa;vg9<@(|?BKmiMUZ zzT@Oq09NBU)E!tzE*VEH>;dW#&!QIe7P%$)j9Taq zY{j3b?=`lFRA3wGd=QzEFb<;^C%8#4hi!P6)f6vj?7&;7g}gv5>?2;n1&m-Hi$Zu6 zqxcYYBSqAN9qlV85klSZ5!5TSkiC225a?Y@;!b>nnqUd_Xk!faqJ#VJDeCwlp2Qle z)bRvX;1ufoecXuePzzkZDy(KwH{!>$GQb@YXo4|};!BL-Z=^yw*vSWmm+=68LmvjH zTECt4{8XjCw!1qN>DeC)@mq7$%({C{J7y+3V!E~yF;eEJ(MMyCMu%)SZCWE;gLXP! ztbeqsA(?Sa$I6Wurg6p2x`wOk(pI)Be=l&otaHFl|9``El8Ky^G_vzI4AV-`<}${h QohjV4GC4Qj-?Y5$FW*j&od5s; delta 967 zcmXZaOK1~O6vpvWG}gB9(blxp#yB;;Qzf;Oza4ptKtip@IunLKlMQ|JY=a-?{hBo%7w9c|P!9pmcPe z`?*Twcaun?hA=^%1uSK<^QCPr{QmQWi^p+4H}Ohzz{+weB({3nd! z-^zTHv>wLSP}fJX0iU4;oWyGUgL)7T7aft^yh93YkU|shV=w+d63W(1B1P=So%kMW z&`WClcACmJ7x?NU;jW&J&QO?N?fzKa+1#ItW%8+*W9NE|#IO~QTRCG#r7)9)yi-i1 z>_T#jof|5DZJwC#OhZ6t* diff --git a/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.po index 2598f795..01fe5c48 100644 --- a/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.po @@ -9,8 +9,8 @@ msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://bugs.foocorp.net/projects/mediagoblin/issues\n" "POT-Creation-Date: 2011-11-01 23:14-0500\n" -"PO-Revision-Date: 2011-11-02 04:13+0000\n" -"Last-Translator: cwebber \n" +"PO-Revision-Date: 2011-11-02 20:49+0000\n" +"Last-Translator: gap \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -529,11 +529,11 @@ msgstr "Sunt sigur că doresc să șterg" #: mediagoblin/user_pages/views.py:142 msgid "Empty comments are not allowed." -msgstr "" +msgstr "Comentariul trebuie să aibă un conținut." #: mediagoblin/user_pages/views.py:148 msgid "Comment posted!" -msgstr "" +msgstr "Comentariul a fost transmis." #: mediagoblin/user_pages/views.py:181 msgid "You are about to delete another user's media. Proceed with caution." diff --git a/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.mo index 7cfc0b61d7c27edb0d61524e6f866f2b1baa0317..4b5481e070c77a113503c11ef4972e86a877f8a4 100644 GIT binary patch delta 898 zcmXZbT}YEr9LMpW^frcMCbeZXmup%r=ax2t(q2>|q8r6xqm04x80aY2ODPPV3keFU zn-WP1yzxQ;k&L`5Y6L-ECKwS5ywPr=n^KcrzNd9_KIa^s=lTE6|7>qlv#F_z>zuVR z>F0K-S<(-$RK(B@=`6adrFVE9cj6v~F>FB#i}(iHc1c6%+RZa~2e;xRe!$nb1xI}n zrSt^PV8JKn-$r?jRKZ371K5NSf?dGPtZ(@x-q8qBOV6<$-=hh>hNf_YVLx`_LCoV3 zocO<9zz)_GwGy9Jcda8eGRd*gkKT8V2Q8pIvH2R1?g1u#;*&E5UePS?q P)v^b|>D=@ePmk{}>4<#) delta 894 zcmXZaPe{{Y9LMobq&Cb-)0(c_AFYe*B0g_$Hdh0hTJfjscA0d7RzZ zr?G|o-U@nQdxcFiiXjf};S3hzK2q#KA3CrKO)!h41G~@!p2H@5hb#C8zu@O%*+y@U zOXt{cUyc9LR&B0x7Y${#q6o*L;U&LZLU4=t=D#VB^+UHpV?*vPNm z!Y9~`t7zW3sWuz96V1qnFdrxIGX3?EqLG6%UPTx2pJNCkxP`sg7tAJ4VGH}8XaZV{ z%`|?B=1;bUcQAvdQ75U*MEcNy&yZKvG(OZ7X`W($g9hdt!x+#50Cao2S>uSgRz0+FXwId Ee@AtCm;e9( diff --git a/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.po index aacd5ec8..f4bfbd67 100644 --- a/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.po @@ -9,8 +9,8 @@ msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://bugs.foocorp.net/projects/mediagoblin/issues\n" "POT-Creation-Date: 2011-11-01 23:14-0500\n" -"PO-Revision-Date: 2011-11-02 04:13+0000\n" -"Last-Translator: cwebber \n" +"PO-Revision-Date: 2011-11-04 11:13+0000\n" +"Last-Translator: aleksejrs \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -515,7 +515,7 @@ msgstr "Я уверен, что хочу удалить это" #: mediagoblin/user_pages/views.py:142 msgid "Empty comments are not allowed." -msgstr "" +msgstr "Empty comments are not allowed." #: mediagoblin/user_pages/views.py:148 msgid "Comment posted!" diff --git a/mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.mo new file mode 100644 index 0000000000000000000000000000000000000000..b0d8d3fcc54d8d7855f2b529486183e885f8e84d GIT binary patch literal 10812 zcmeI0eT*Ds8Ngpc6}l<{TCj-ry~ENwyxqGiZK>P#TKYkIrB_OOr6Dnp+1+<{hnt<* z%*@_(n~(qr+C&K&K2)MHC_#dJT#*7Aq=}f2h{VK%koZA1Y9b*u!5I0&_=mseeP^!M z(i)7AkZ_l~{oTyIAJ6yu%)EZ#qWcs-P5v(B@5^V))rp_)epIQ8xcnY`9X<_*;XUUl zwHv+&7sCtBRcZ=e3fI8Ha3?$lSHl8>WZWh`WQ(1!4tGPAR7YU}J`cy?OOU121>F23 zTnf*JgYXb6Lpu*%$o2Et_rJ-md+;;d{|CGTe*9zn!4>dgxC(wA?t-6yQ*bHl!e#It zDC2$t#V#+yPr)~!$n|fy2rgpLC2%p^50^oaw*!aZo$yxp6nqViu-O1S_dK`HDC}~5 zJ*>i)VILf35!vs0*bfa9eGfy?_wMZbA3*WXGui!DpxCJgFMxlCAAx6cQ^qZZa;-C7 z4snqhf}+Q2*o4^RI~VxJvQ>{EfLr0#%Xhr8hccrO&ak3+HhQiL6at1{N1 z=<#hR^S=+-LOlj$ou9+y@E1_*@CFn=6fnk4*bim>7Q6~R088+D zM=0z36+V2HQvZVdst1`Q`STnUxxR%lcf*&U%)1CleG?Ra*P+;93hswL zgCg(wEFyl^@K!hhUxP10$)6u;x6iL(m+RwD@~2MF@T-2shwOJ8O8&@)=zAGl2d{wg zeI1H_4neWQH=)?+AxH?Tqfp}KB`D)w$*%vB@l7c4@D>z%FTTv>&oU@>J`Cmiv%lc% zb16gxwFZh^Z-9&7*Wdy84JdlQ0dc)rLNZAHjAX1pwo>;(@yD}J#G%(RgUO0Sx8tbp z2S%;;bT#mjWJ7<`cr_E>oOCKJKfSr>H<|%|X}@m9roN$n`9N$Mev&ez69rt%RCTa≺)BkLEu%Q*s2@WbkdAwbX2eFDE1qE=mpy2F4ps>O-)zD zE`Agyed_93EnnDgA-^ov@}^j{Y4l7K2Q|!BF)3EfHcp#y)M+$XtZKqE_5%NqUCiz< zV5Yg*@q(Z`givAUC9MZ0Izj4-Z>-aF+HIR;zCA<|v2YUA(-|)|Lx@`qIyLdYv|lp_*=e_-g$cl4|U?B@9RijE+R;KBcxs;fjNS)sEPYZmY*g1!CWka$ zV2YH?TGT4(fdl4Gw|xh(JUv&dvO?GhJ5u}l$F}d@FGWghc8jT|tWg)KQKB@c_;P+B zR6B4LzV~#}Mg&O&L&`^_L(JVu)NyhpCa9Ox4j;qk3JxYig#r`ulHlY&W&J!nhIG^> zjwH+KRL5vWoF)0-hXt$mjH&2K9LZ63RhjKL zprlsGWCB%lTk3t;-OBn6Oc$vMu|AfNv%w0WcAFU!tKFRP zr`hScfHPWM7q#gO_GE{|+&^?65^yaqtu{+)59KLl<4X60^RlvFS3c1i^^aLeomk>Z z%ELS6WTj;I9kpcsMp?fT`1B`uQV!a=z&ZWi!{YU1Sc+h&nYM!du^UM!iMXZ-+SEnu zw=gVmY7d6|IPMcM2i0C9jZ7Z!%LlU3zmYF&9KJK6-8W|p_>$Tu=Z&i%iP}fUq4v?V z*b|I6%o|wjI`2%fXStOxFN8xj!w5RpE=dTJm?t+&`$z$rFweFw^V%F~uuo}o5X%h? zrSGUV-IO}rGD(nq^@)-6_#Gt3LSS&G}0>1(8(vkld%Lnq+T zV7sCtf@j60%m5LK7Rk+$*4*k&0C7ljh!~HPC#&z7_PGmOFIA(fA$q%rOOcd)-J(`) zB30~#2PJfw%c9vjQH~2J8WU_d3els!mOm)Ci68a@|Ac~q%)TdqO*+y7=EnB$0g#EMA z&!bUAB>v{jJy`K;uyXQ7IMj zaEJ+`yG+xh_VUNz*5rCi@}}jw(KLTJeW{VB>n6cS+_ZN?#`X0F6!xCZK`kt z|S#vio=4Cbj@^nz_!jI9@B>K#zi7%KDVXv9Q<36IXE}Y529`=1wCiPDW*&9V`{D zOZ6xsVcVt9q{B!ry>2pW?dguYVLwSaCMoQ>Zn9_}PS~fo6}y-9%8}90BEKV}dgYbn z(N)Ef)gvPeEbcYazQ}XxxGVMOs`AL%FOKk2*ySZ@aWeM8B=FKGF7tRKPuhCD=%n@H+7shM-nxm4 z+bDDLXj|56D}GwoZbEqzU@&sGtT%fV6X=oBmr8323-5rWO6JY){8}XqNnU3b-T{5+ z-U0PyXM3{`_m13UKX32NKF~Yz)!yurz1d^$&x@hn>`}WLJG{`Fz2E)+VSG*0n|-2p zM>)tFzze6r&U*O_?Yn+GN#Z%TJ4|DO}yg=&B9=3ab#ksjR%LXFB1NdCR z;RsRih!x-oK0k18n4H~^_qohs60ex*QHfxQsYh%~p}{c*p#mBa-A=nldq=)z)n*)l zk3|<=P1Sw(;&9>B)WWN&_y5(DB&y^i*~dXZ>OMmnlc+~+_4%<>BT3pP-N9gQQWweW zV;`hb;m$Vd+I(tMsg`y7&Fx@5yXY dCw(8ZiA!rsib_vLB2)LJ(Oh_gw(tf`{RbS{tH%HU literal 0 HcmV?d00001 diff --git a/mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.po new file mode 100644 index 00000000..289bddb5 --- /dev/null +++ b/mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.po @@ -0,0 +1,498 @@ +# Translations template for PROJECT. +# Copyright (C) 2011 ORGANIZATION +# This file is distributed under the same license as the PROJECT project. +# +# Translators: +# వీవెన్ , 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-11-01 23:14-0500\n" +"PO-Revision-Date: 2011-11-03 14:08+0000\n" +"Last-Translator: veeven \n" +"Language-Team: LANGUAGE \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: te\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" + +#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 +msgid "Username" +msgstr "వాడుకరి పేరు" + +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:53 +msgid "Password" +msgstr "సంకేతపదం" + +#: mediagoblin/auth/forms.py:35 +msgid "Passwords must match." +msgstr "" + +#: mediagoblin/auth/forms.py:37 +msgid "Confirm password" +msgstr "" + +#: mediagoblin/auth/forms.py:39 +msgid "Type it again here to make sure there are no spelling mistakes." +msgstr "" + +#: mediagoblin/auth/forms.py:42 +msgid "Email address" +msgstr "ఈమెయిలు చిరునామా" + +#: mediagoblin/auth/views.py:55 +msgid "Sorry, registration is disabled on this instance." +msgstr "" + +#: mediagoblin/auth/views.py:73 +msgid "Sorry, a user with that name already exists." +msgstr "" + +#: mediagoblin/auth/views.py:77 +msgid "Sorry, that email address has already been taken." +msgstr "" + +#: mediagoblin/auth/views.py:179 +msgid "" +"Your email address has been verified. You may now login, edit your profile, " +"and submit images!" +msgstr "" + +#: mediagoblin/auth/views.py:185 +msgid "The verification key or user id is incorrect" +msgstr "" + +#: mediagoblin/auth/views.py:207 +msgid "Resent your verification email." +msgstr "" + +#: mediagoblin/auth/views.py:248 +msgid "" +"Could not send password recovery email as your username is inactive or your " +"account's email address has not been verified." +msgstr "" + +#: mediagoblin/edit/forms.py:24 mediagoblin/submit/forms.py:27 +msgid "Title" +msgstr "శీర్షిక" + +#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:32 +msgid "Tags" +msgstr "" + +#: mediagoblin/edit/forms.py:31 +msgid "Slug" +msgstr "" + +#: mediagoblin/edit/forms.py:32 +msgid "The slug can't be empty" +msgstr "" + +#: mediagoblin/edit/forms.py:33 +msgid "" +"The title part of this media's URL. You usually don't need to change this." +msgstr "" + +#: mediagoblin/edit/forms.py:40 +msgid "Bio" +msgstr "" + +#: mediagoblin/edit/forms.py:43 +msgid "Website" +msgstr "" + +#: mediagoblin/edit/views.py:64 +msgid "An entry with that slug already exists for this user." +msgstr "" + +#: mediagoblin/edit/views.py:85 +msgid "You are editing another user's media. Proceed with caution." +msgstr "" + +#: mediagoblin/edit/views.py:155 +msgid "You are editing a user's profile. Proceed with caution." +msgstr "" + +#: mediagoblin/process_media/errors.py:44 +msgid "Invalid file given for media type." +msgstr "" + +#: mediagoblin/submit/forms.py:25 +msgid "File" +msgstr "" + +#: mediagoblin/submit/forms.py:30 +msgid "Description of this work" +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:121 +msgid "Woohoo! Submitted!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/404.html:21 +msgid "Oops!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/404.html:24 +msgid "There doesn't seem to be a page at this address. Sorry!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/404.html:26 +msgid "" +"If you're sure the address is correct, maybe the page you're looking for has" +" been moved or deleted." +msgstr "" + +#: mediagoblin/templates/mediagoblin/404.html:32 +msgid "Image of 404 goblin stressing out" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:22 +msgid "GNU MediaGoblin" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:47 +msgid "MediaGoblin logo" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:52 +msgid "Submit media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:63 +msgid "verify your email!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:73 +#: mediagoblin/templates/mediagoblin/auth/login.html:27 +#: mediagoblin/templates/mediagoblin/auth/login.html:35 +msgid "Log in" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:89 +msgid "" +"Powered by MediaGoblin, a GNU project" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:24 +msgid "Explore" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:27 +msgid "Hi there, media lover! MediaGoblin is..." +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:29 +msgid "The perfect place for your media!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:30 +msgid "" +"A place for people to collaborate and show off original and derived " +"creations!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:31 +msgid "" +"Free, as in freedom. (We’re a GNU project, " +"after all.)" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:32 +msgid "" +"Aiming to make the world a better place through decentralization and " +"(eventually, coming soon!) federation!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:33 +msgid "" +"Built for extensibility. (Multiple media types coming soon to the software," +" including video support!)" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:34 +msgid "" +"Powered by people like you. (You can help us improve this" +" software!)" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:38 +msgid "Excited to join us?" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:39 +#, python-format +msgid "" +"Create a free account\n" +" or\n" +" Set up MediaGoblin on your own server" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:53 +msgid "Most recent media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:29 +msgid "Enter your new password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:29 +msgid "Enter your username or email" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 +msgid "Your password has been changed. Try to log in now." +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/fp_email_sent.html:22 +msgid "" +"Check your inbox. We sent an email with a URL for changing your password." +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/fp_verification_email.txt:19 +#, python-format +msgid "" +"Hi %(username)s,\n" +"\n" +"to change your GNU MediaGoblin password, open the following URL in \n" +"your web browser:\n" +"\n" +"%(verification_url)s\n" +"\n" +"If you think this is an error, just ignore this email and continue being\n" +"a happy goblin!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/login.html:30 +msgid "Logging in failed!" +msgstr "ప్రవేశం విఫలమయ్యింది!" + +#: mediagoblin/templates/mediagoblin/auth/login.html:43 +msgid "Don't have an account yet?" +msgstr "మీకు ఇంకా ఖాతా లేదా?" + +#: mediagoblin/templates/mediagoblin/auth/login.html:46 +msgid "Create one here!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/login.html:49 +msgid "Forgot your password?" +msgstr "మీ సంకేతపదాన్ని మర్చిపోయారా?" + +#: mediagoblin/templates/mediagoblin/auth/login.html:52 +msgid "Change it!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/register.html:27 +msgid "Create an account!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/register.html:31 +msgid "Create" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/verification_email.txt:19 +#, python-format +msgid "" +"Hi %(username)s,\n" +"\n" +"to activate your GNU MediaGoblin account, open the following URL in\n" +"your web browser:\n" +"\n" +"%(verification_url)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:29 +#, python-format +msgid "Editing %(media_title)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:36 +#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49 +msgid "Cancel" +msgstr "రద్దుచేయి" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:37 +#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:35 +msgid "Save changes" +msgstr "మార్పులను భద్రపరచు" + +#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29 +#, python-format +msgid "Editing %(username)s's profile" +msgstr "" + +#: mediagoblin/templates/mediagoblin/listings/tag.html:31 +msgid "Media tagged with:" +msgstr "" + +#: mediagoblin/templates/mediagoblin/submit/start.html:26 +msgid "Submit yer media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Submit" +msgstr "దాఖలు చెయ్యి" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:32 +#, python-format +msgid "%(username)s's media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:52 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:32 +msgid "Sorry, no such user found." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 +#, python-format +msgid "Really delete %(title)s?" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:50 +msgid "Delete Permanently" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:22 +msgid "Media processing panel" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:25 +msgid "" +"You can track the state of media being processed for your gallery here." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:28 +msgid "Media in-processing" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:46 +msgid "No media in-processing" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:50 +msgid "These uploads failed to process:" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:39 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:59 +msgid "Email verification needed" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:42 +msgid "Almost done! Your account still needs to be activated." +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" +" activated." +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 log in and resend it." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:78 +#, python-format +msgid "%(username)s's profile" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:85 +msgid "Here's a spot to tell others about yourself." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:90 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:108 +msgid "Edit profile" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 +msgid "This user hasn't filled in their profile (yet)." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:122 +#, python-format +msgid "View all of %(username)s's media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:135 +msgid "" +"This is where your media will appear, but you don't seem to have added " +"anything yet." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:141 +msgid "Add media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:147 +msgid "There doesn't seem to be any media here yet..." +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/feed_link.html:21 +msgid "feed icon" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/feed_link.html:23 +msgid "Atom feed" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/pagination.html:40 +msgid "Newer" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/pagination.html:46 +msgid "Older" +msgstr "" + +#: mediagoblin/user_pages/forms.py:24 +msgid "Comment" +msgstr "వ్యాఖ్య" + +#: mediagoblin/user_pages/forms.py:30 +msgid "I am sure I want to delete this" +msgstr "" + +#: mediagoblin/user_pages/views.py:142 +msgid "Empty comments are not allowed." +msgstr "" + +#: mediagoblin/user_pages/views.py:148 +msgid "Comment posted!" +msgstr "" + +#: mediagoblin/user_pages/views.py:181 +msgid "You are about to delete another user's media. Proceed with caution." +msgstr "" + + From 34b0874d9ad305f4c8d5e892a679bad2f33ed277 Mon Sep 17 00:00:00 2001 From: Elrond Date: Sun, 30 Oct 2011 20:51:55 +0100 Subject: [PATCH 041/302] Some docs for the TestingMiddleware To make the TestingMiddleware actually more useful in the future, start to document it. --- mediagoblin/middleware/testing.py | 25 +++++++++++++++++++++++++ mediagoblin/tests/tools.py | 2 ++ 2 files changed, 27 insertions(+) diff --git a/mediagoblin/middleware/testing.py b/mediagoblin/middleware/testing.py index 06714769..99322661 100644 --- a/mediagoblin/middleware/testing.py +++ b/mediagoblin/middleware/testing.py @@ -15,6 +15,23 @@ # along with this program. If not, see . class TestingMiddleware(object): + """ + Middleware for the Unit tests + + It might make sense to perform some tests on all + requests/responses. Or prepare them in a special + manner. For example all html responses could be tested + for being valid html *after* being rendered. + + This module is getting inserted at the front of the + middleware list, which means: requests are handed here + first, responses last. So this wraps up the "normal" + app. + + If you need to add a test, either add it directly to + the appropiate process_request or process_response, or + create a new method and call it from process_*. + """ def __init__(self, mg_app): self.app = mg_app @@ -23,12 +40,20 @@ class TestingMiddleware(object): pass def process_response(self, request, response): + # All following tests should be for html only! if response.content_type != "text/html": # Get out early return + + # If the template contains a reference to + # /mgoblin_static/ instead of using + # /request.staticdirect(), error out here. + # This could probably be implemented as a grep on + # the shipped templates easier... if response.text.find("/mgoblin_static/") >= 0: raise AssertionError( "Response HTML contains reference to /mgoblin_static/ " "instead of staticdirect. Request was for: " + request.full_path) + return diff --git a/mediagoblin/tests/tools.py b/mediagoblin/tests/tools.py index e8558240..7f20f6e7 100644 --- a/mediagoblin/tests/tools.py +++ b/mediagoblin/tests/tools.py @@ -107,6 +107,8 @@ def get_test_app(dump_old_app=True): # Insert the TestingMiddleware, which can do some # sanity checks on every request/response. + # Doing it this way is probably not the cleanest way. + # We'll fix it, when we have plugins! mg_globals.app.middleware.insert(0, TestingMiddleware(mg_globals.app)) app = TestApp(test_app) From 33d11e995d183f339597715472e4f6ecc81ba557 Mon Sep 17 00:00:00 2001 From: Elrond Date: Sat, 12 Nov 2011 13:21:41 +0100 Subject: [PATCH 042/302] Move TestingMiddleware to tests/tools.py This middleware isn't needed outside of the tests, so let's just put it there. --- mediagoblin/middleware/testing.py | 59 ------------------------------- mediagoblin/tests/tools.py | 46 +++++++++++++++++++++++- 2 files changed, 45 insertions(+), 60 deletions(-) delete mode 100644 mediagoblin/middleware/testing.py diff --git a/mediagoblin/middleware/testing.py b/mediagoblin/middleware/testing.py deleted file mode 100644 index 99322661..00000000 --- a/mediagoblin/middleware/testing.py +++ /dev/null @@ -1,59 +0,0 @@ -# GNU MediaGoblin -- federated, autonomous media hosting -# Copyright (C) 2011 MediaGoblin contributors. See AUTHORS. -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -class TestingMiddleware(object): - """ - Middleware for the Unit tests - - It might make sense to perform some tests on all - requests/responses. Or prepare them in a special - manner. For example all html responses could be tested - for being valid html *after* being rendered. - - This module is getting inserted at the front of the - middleware list, which means: requests are handed here - first, responses last. So this wraps up the "normal" - app. - - If you need to add a test, either add it directly to - the appropiate process_request or process_response, or - create a new method and call it from process_*. - """ - - def __init__(self, mg_app): - self.app = mg_app - - def process_request(self, request): - pass - - def process_response(self, request, response): - # All following tests should be for html only! - if response.content_type != "text/html": - # Get out early - return - - # If the template contains a reference to - # /mgoblin_static/ instead of using - # /request.staticdirect(), error out here. - # This could probably be implemented as a grep on - # the shipped templates easier... - if response.text.find("/mgoblin_static/") >= 0: - raise AssertionError( - "Response HTML contains reference to /mgoblin_static/ " - "instead of staticdirect. Request was for: " - + request.full_path) - - return diff --git a/mediagoblin/tests/tools.py b/mediagoblin/tests/tools.py index 7f20f6e7..420d9ba8 100644 --- a/mediagoblin/tests/tools.py +++ b/mediagoblin/tests/tools.py @@ -23,7 +23,6 @@ from webtest import TestApp from mediagoblin import mg_globals from mediagoblin.tools import testing -from mediagoblin.middleware.testing import TestingMiddleware from mediagoblin.init.config import read_mediagoblin_config from mediagoblin.decorators import _make_safe from mediagoblin.db.open import setup_connection_and_db_from_config @@ -51,6 +50,51 @@ $ CELERY_CONFIG_MODULE=mediagoblin.init.celery.from_tests ./bin/nosetests""" class BadCeleryEnviron(Exception): pass +class TestingMiddleware(object): + """ + Middleware for the Unit tests + + It might make sense to perform some tests on all + requests/responses. Or prepare them in a special + manner. For example all html responses could be tested + for being valid html *after* being rendered. + + This module is getting inserted at the front of the + middleware list, which means: requests are handed here + first, responses last. So this wraps up the "normal" + app. + + If you need to add a test, either add it directly to + the appropiate process_request or process_response, or + create a new method and call it from process_*. + """ + + def __init__(self, mg_app): + self.app = mg_app + + def process_request(self, request): + pass + + def process_response(self, request, response): + # All following tests should be for html only! + if response.content_type != "text/html": + # Get out early + return + + # If the template contains a reference to + # /mgoblin_static/ instead of using + # /request.staticdirect(), error out here. + # This could probably be implemented as a grep on + # the shipped templates easier... + if response.text.find("/mgoblin_static/") >= 0: + raise AssertionError( + "Response HTML contains reference to /mgoblin_static/ " + "instead of staticdirect. Request was for: " + + request.full_path) + + return + + def suicide_if_bad_celery_environ(): if not os.environ.get('CELERY_CONFIG_MODULE') == \ 'mediagoblin.init.celery.from_tests': From daed11b81263c3841ae23f45ed1bf33aa2e92992 Mon Sep 17 00:00:00 2001 From: Elrond Date: Sat, 12 Nov 2011 14:26:35 +0100 Subject: [PATCH 043/302] 640: Configuration files should mention their _local versions Thanks go to Aleksej Serdjukov for bringing this up and providing the patch in the bug! --- mediagoblin.ini | 3 +++ paste.ini | 3 +++ 2 files changed, 6 insertions(+) diff --git a/mediagoblin.ini b/mediagoblin.ini index c22d12d7..728ab2f2 100644 --- a/mediagoblin.ini +++ b/mediagoblin.ini @@ -1,3 +1,6 @@ +# If you want to make changes to this file, first copy it to +# mediagoblin_local.ini, then make the changes there. + [mediagoblin] direct_remote_path = /mgoblin_static/ email_sender_address = "notice@mediagoblin.example.org" diff --git a/paste.ini b/paste.ini index 8866789c..c729e41d 100644 --- a/paste.ini +++ b/paste.ini @@ -1,3 +1,6 @@ +# If you want to make changes to this file, first copy it to +# paste_local.ini, then make the changes there. + [DEFAULT] # Set to true to enable web-based debugging messages and etc. debug = false From 8bb3eb185ab14e8e8f4fc7b3df9eac4e1438d030 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Sat, 12 Nov 2011 08:10:46 -0600 Subject: [PATCH 044/302] Probably should have MANIFEST.in checked in, for doing python sdists --- MANIFEST.in | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 MANIFEST.in diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 00000000..b1f93dba --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,5 @@ +recursive-include mediagoblin/templates *.html +recursive-include mediagoblin/static *.js *.css *.png *.svg +recursive-include mediagoblin/tests *.ini +recursive-include docs *.rst *.html + From 0cf5b8ad2499a93fdba5ff1202fdc554208ec85f Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Sat, 12 Nov 2011 13:35:41 -0600 Subject: [PATCH 045/302] Don't force-convert resized images to JPEG. That's just not nice for those of us who like transparency! --- mediagoblin/process_media/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mediagoblin/process_media/__init__.py b/mediagoblin/process_media/__init__.py index 2b9eed6e..85bdcbea 100644 --- a/mediagoblin/process_media/__init__.py +++ b/mediagoblin/process_media/__init__.py @@ -136,7 +136,7 @@ def process_image(entry): thumb_file = mgg.public_store.get_file(thumb_filepath, 'w') with thumb_file: - thumb.save(thumb_file, "JPEG", quality=90) + thumb.save(thumb_file) # 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 @@ -154,7 +154,7 @@ def process_image(entry): medium_file = mgg.public_store.get_file(medium_filepath, 'w') with medium_file: - medium.save(medium_file, "JPEG", quality=90) + medium.save(medium_file) medium_processed = True # we have to re-read because unlike PIL, not everything reads From d0504cfa875b0ac7340fb00a64fc8422faecdc9a Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Sat, 12 Nov 2011 15:12:39 -0600 Subject: [PATCH 046/302] Final step for non-force-conversion to jpeg --- mediagoblin/process_media/__init__.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/mediagoblin/process_media/__init__.py b/mediagoblin/process_media/__init__.py index 85bdcbea..f63fb2b0 100644 --- a/mediagoblin/process_media/__init__.py +++ b/mediagoblin/process_media/__init__.py @@ -14,8 +14,9 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -import Image +import os +import Image from celery.task import Task from celery import registry @@ -122,17 +123,16 @@ def process_image(entry): mgg.queue_store, queued_filepath, 'source') + extension = os.path.splitext(queued_filename)[1] + 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": - thumb = thumb.convert("RGB") - thumb_filepath = create_pub_filepath(entry, 'thumbnail.jpg') + thumb_filepath = create_pub_filepath(entry, 'thumbnail' + extension) thumb_file = mgg.public_store.get_file(thumb_filepath, 'w') with thumb_file: @@ -147,10 +147,7 @@ def process_image(entry): if medium.size[0] > MEDIUM_SIZE[0] or medium.size[1] > MEDIUM_SIZE[1]: medium.thumbnail(MEDIUM_SIZE, Image.ANTIALIAS) - if medium.mode != "RGB": - medium = medium.convert("RGB") - - medium_filepath = create_pub_filepath(entry, 'medium.jpg') + medium_filepath = create_pub_filepath(entry, 'medium' + extension) medium_file = mgg.public_store.get_file(medium_filepath, 'w') with medium_file: From efd0a42ca1b81a2dd17aee1626060584a278020c Mon Sep 17 00:00:00 2001 From: Elrond Date: Sun, 13 Nov 2011 19:51:11 +0100 Subject: [PATCH 047/302] Mark two strings for translation --- mediagoblin/edit/views.py | 2 +- mediagoblin/templates/mediagoblin/base.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mediagoblin/edit/views.py b/mediagoblin/edit/views.py index a6ddb553..17244831 100644 --- a/mediagoblin/edit/views.py +++ b/mediagoblin/edit/views.py @@ -170,7 +170,7 @@ def edit_profile(request): messages.add_message(request, messages.SUCCESS, - 'Profile edited!') + _("Profile edited!")) return redirect(request, 'mediagoblin.user_pages.user_home', user=edit_username) diff --git a/mediagoblin/templates/mediagoblin/base.html b/mediagoblin/templates/mediagoblin/base.html index b4c4dcf3..925386e5 100644 --- a/mediagoblin/templates/mediagoblin/base.html +++ b/mediagoblin/templates/mediagoblin/base.html @@ -67,7 +67,7 @@ user= request.user['username']) }}"> {{ request.user['username'] }} - (log out) + ({% trans %}log out{% endtrans %}) {% else %} {% trans %}Log in{% endtrans %} From b97ae0fd7da45c32897a4cb8437c04ddf04fdc95 Mon Sep 17 00:00:00 2001 From: Nathan Yergler Date: Sun, 13 Nov 2011 11:41:43 -0800 Subject: [PATCH 048/302] Issue 653: Don't throw exception if response has no vary header. --- mediagoblin/middleware/csrf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediagoblin/middleware/csrf.py b/mediagoblin/middleware/csrf.py index 7a5e352e..6c977f21 100644 --- a/mediagoblin/middleware/csrf.py +++ b/mediagoblin/middleware/csrf.py @@ -98,7 +98,7 @@ class CsrfMiddleware(object): httponly=True) # update the Vary header - response.vary = (response.vary or []) + ['Cookie'] + response.vary = getattr(response, 'vary', []) + ['Cookie'] def _make_token(self, request): """Generate a new token to use for CSRF protection.""" From ad3f1233df672688c09ab923d8bb216a351db8cb Mon Sep 17 00:00:00 2001 From: Nathan Yergler Date: Sun, 13 Nov 2011 11:59:24 -0800 Subject: [PATCH 049/302] Issue 653: Handle the case where request.vary is None --- mediagoblin/middleware/csrf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediagoblin/middleware/csrf.py b/mediagoblin/middleware/csrf.py index 6c977f21..d0601af8 100644 --- a/mediagoblin/middleware/csrf.py +++ b/mediagoblin/middleware/csrf.py @@ -98,7 +98,7 @@ class CsrfMiddleware(object): httponly=True) # update the Vary header - response.vary = getattr(response, 'vary', []) + ['Cookie'] + response.vary = (getattr(response, 'vary') or []) + ['Cookie'] def _make_token(self, request): """Generate a new token to use for CSRF protection.""" From d9ed3aeb402fc66de2a79d145b5a443c9e660c18 Mon Sep 17 00:00:00 2001 From: Nathan Yergler Date: Sun, 13 Nov 2011 12:07:09 -0800 Subject: [PATCH 050/302] Issue 653: This time for sure! --- mediagoblin/middleware/csrf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediagoblin/middleware/csrf.py b/mediagoblin/middleware/csrf.py index d0601af8..8275c18e 100644 --- a/mediagoblin/middleware/csrf.py +++ b/mediagoblin/middleware/csrf.py @@ -98,7 +98,7 @@ class CsrfMiddleware(object): httponly=True) # update the Vary header - response.vary = (getattr(response, 'vary') or []) + ['Cookie'] + response.vary = (getattr(response, 'vary', None) or []) + ['Cookie'] def _make_token(self, request): """Generate a new token to use for CSRF protection.""" From 688f56c2dc579218b35263d0189e5d7c9ba9627f Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Sun, 13 Nov 2011 14:34:22 -0600 Subject: [PATCH 051/302] Improved title block on media page --- mediagoblin/templates/mediagoblin/user_pages/media.html | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html index 17beffb2..2441ec1b 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media.html @@ -20,6 +20,8 @@ {% import "/mediagoblin/utils/wtforms.html" as wtforms_util %} {% from "mediagoblin/utils/pagination.html" import render_pagination %} +{% block title %}{{ media.title }} — {{ super() }}{% endblock %} + {% block mediagoblin_content %} {% if media %}
From 017d6ca3501b157277fc01fb37df2dbbd9ed17ef Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Sun, 13 Nov 2011 14:38:40 -0600 Subject: [PATCH 052/302] Enhanced title for user profile page --- .../templates/mediagoblin/user_pages/user.html | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/mediagoblin/templates/mediagoblin/user_pages/user.html b/mediagoblin/templates/mediagoblin/user_pages/user.html index c5beeaaa..d65da055 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/user.html +++ b/mediagoblin/templates/mediagoblin/user_pages/user.html @@ -26,6 +26,17 @@ user=user.username) }}"> {% endblock mediagoblin_head %} +{% block title %} + {%- if user -%} + {%- trans username=user.username -%} + {{ username }}'s profile + {%- endtrans %} — {{ super() }} + {%- else -%} + {{ super() }} + {%- endif -%} +{% endblock %} + + {% block mediagoblin_content -%} {# If no user... #} {% if not user %} From 7fc25d27208ef9926e94eeba953160ffbe676942 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Sun, 13 Nov 2011 14:40:11 -0600 Subject: [PATCH 053/302] If the gallery view makes sure we have a user anyway, do we need this check? Seems like the classic annoying "SHOULD NEVER HAPPEN" else: statement :) --- .../mediagoblin/user_pages/gallery.html | 39 ++++++++----------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/mediagoblin/templates/mediagoblin/user_pages/gallery.html b/mediagoblin/templates/mediagoblin/user_pages/gallery.html index df931d9c..86105493 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/gallery.html +++ b/mediagoblin/templates/mediagoblin/user_pages/gallery.html @@ -27,28 +27,23 @@ {% endblock mediagoblin_head %} {% block mediagoblin_content -%} - {% if user %} -

- {%- trans username=user.username, - user_url=request.urlgen( - 'mediagoblin.user_pages.user_home', - user=user.username) -%} - {{ username }}'s media - {%- endtrans %} -

+

+ {%- trans username=user.username, + user_url=request.urlgen( + 'mediagoblin.user_pages.user_home', + user=user.username) -%} + {{ username }}'s media + {%- endtrans %} +

- + -
- {% set feed_url = request.urlgen( - 'mediagoblin.user_pages.atom_feed', - user=user.username) %} - {% include "mediagoblin/utils/feed_link.html" %} -
- {% else %} - {# This *should* not occur as the view makes sure we pass in a user. #} -

{% trans %}Sorry, no such user found.{% endtrans %}

- {% endif %} +

+ {% set feed_url = request.urlgen( + 'mediagoblin.user_pages.atom_feed', + user=user.username) %} + {% include "mediagoblin/utils/feed_link.html" %} +
{% endblock %} From ab56689017daa985f3938af4710f3c76ad415bda Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Sun, 13 Nov 2011 14:42:03 -0600 Subject: [PATCH 054/302] Enhanced title on the user's main media gallery --- mediagoblin/templates/mediagoblin/user_pages/gallery.html | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mediagoblin/templates/mediagoblin/user_pages/gallery.html b/mediagoblin/templates/mediagoblin/user_pages/gallery.html index 86105493..b066dd71 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/gallery.html +++ b/mediagoblin/templates/mediagoblin/user_pages/gallery.html @@ -26,6 +26,12 @@ user=user.username) }}"> {% endblock mediagoblin_head %} +{% block title %} + {%- trans username=user.username -%} + {{ username }}'s media + {%- endtrans %} — {{ super() }} +{% endblock %} + {% block mediagoblin_content -%}

{%- trans username=user.username, From 4671fda345394dad9ca4278b1cf7b2cdf7d2b4ee Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Sun, 13 Nov 2011 14:48:51 -0600 Subject: [PATCH 055/302] Improving on tag page *and* adjusting translation for RTL reasons Basically moving the variable inside the translation to give translators more flexibility --- mediagoblin/templates/mediagoblin/listings/tag.html | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/mediagoblin/templates/mediagoblin/listings/tag.html b/mediagoblin/templates/mediagoblin/listings/tag.html index 58863015..f797f72f 100644 --- a/mediagoblin/templates/mediagoblin/listings/tag.html +++ b/mediagoblin/templates/mediagoblin/listings/tag.html @@ -26,9 +26,13 @@ tag=tag_slug) }}"> {% endblock mediagoblin_head %} +{% block title %} + {% trans %}Media tagged with: {{ tag_name }}{% endtrans %} — {{ super() }} +{% endblock %} + {% block mediagoblin_content -%} <h1> - {% trans %}Media tagged with:{% endtrans %} {{ tag_name }} + {% trans %}Media tagged with: {{ tag_name }}{% endtrans %} </h1> <div class="container_16 media_gallery"> From 2b7aa99d3c221e713a95b664491f35612f9023cc Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber <cwebber@dustycloud.org> Date: Sun, 13 Nov 2011 20:39:42 -0600 Subject: [PATCH 056/302] Only show "post a comment" link if comments already exist The purpose of the link is to help you jump past comments to the comment box, and so... Even with this new conditional, I'm not entirely sure I like that link ;) --- mediagoblin/templates/mediagoblin/user_pages/media.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html index 2441ec1b..1e495b98 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media.html @@ -62,7 +62,7 @@ {%- endtrans %} </p> <h3></h3> - {% if request.user %} + {% if request.user and comments.count() %} <p><a href="#comment_form">{% trans %}Post a comment{% endtrans %}</a></p> {% endif %} {% if comments %} From b33701b851ef7f848d8d7b47e3654552da32b485 Mon Sep 17 00:00:00 2001 From: Joar Wandborg <git@wandborg.com> Date: Tue, 15 Nov 2011 00:27:21 +0100 Subject: [PATCH 057/302] moved from videoscale => ffvideoscale *and* put queus before video and audio pipes --- mediagoblin/media_types/video/transcoders.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/mediagoblin/media_types/video/transcoders.py b/mediagoblin/media_types/video/transcoders.py index 512c7cb6..3a30aedf 100644 --- a/mediagoblin/media_types/video/transcoders.py +++ b/mediagoblin/media_types/video/transcoders.py @@ -624,13 +624,16 @@ class VideoTranscoder: self.pipeline.add(self.decoder) # Video elements + self.videoqueue = gst.element_factory_make('queue', 'videoqueue') + self.pipeline.add(self.videoqueue) + self.ffmpegcolorspace = gst.element_factory_make( 'ffmpegcolorspace', 'ffmpegcolorspace') self.pipeline.add(self.ffmpegcolorspace) - self.videoscale = gst.element_factory_make('videoscale', 'videoscale') - self.videoscale.set_property('method', 2) # I'm not sure this works - self.videoscale.set_property('add-borders', 0) + self.videoscale = gst.element_factory_make('ffvideoscale', 'videoscale') + #self.videoscale.set_property('method', 2) # I'm not sure this works + #self.videoscale.set_property('add-borders', 0) self.pipeline.add(self.videoscale) self.capsfilter = gst.element_factory_make('capsfilter', 'capsfilter') @@ -642,6 +645,9 @@ class VideoTranscoder: self.pipeline.add(self.vp8enc) # Audio elements + self.audioqueue = gst.element_factory_make('queue', 'audioqueue') + self.pipeline.add(self.audioqueue) + self.audioconvert = gst.element_factory_make('audioconvert', 'audioconvert') self.pipeline.add(self.audioconvert) @@ -679,6 +685,7 @@ class VideoTranscoder: self.filesrc.link(self.decoder) # Link all the video elements in a link to webmux + self.videoqueue.link(self.ffmpegcolorspace) self.ffmpegcolorspace.link(self.videoscale) self.videoscale.link(self.capsfilter) #self.capsfilter.link(self.xvimagesink) @@ -688,6 +695,7 @@ class VideoTranscoder: if self.data.is_audio: # Link all the audio elements in a line to webmux #self.audioconvert.link(self.alsasink) + self.audioqueue.link(self.audioconvert) self.audioconvert.link(self.vorbisenc) self.vorbisenc.link(self.webmmux) @@ -707,10 +715,10 @@ class VideoTranscoder: if self.ffmpegcolorspace.get_pad_template('sink')\ .get_caps().intersect(pad.get_caps()).is_empty(): # It is NOT a video src pad. - pad.link(self.audioconvert.get_pad('sink')) + pad.link(self.audioqueue.get_pad('sink')) else: # It IS a video src pad. - pad.link(self.ffmpegcolorspace.get_pad('sink')) + pad.link(self.videoqueue.get_pad('sink')) def _setup_bus(self): self.bus = self.pipeline.get_bus() From a9c7af90408c3537f42763e63862a2ae44bcc368 Mon Sep 17 00:00:00 2001 From: Elrond <elrond+mediagoblin.org@samba-tng.org> Date: Tue, 15 Nov 2011 11:21:15 +0100 Subject: [PATCH 058/302] export: Handle Unicode titles better in logging log("ascii %s" % unicode_string) tries to convert unicode to ascii, which might fail. Better use log(u"unicode format %s" % unicode_string) and let the logging framework handle the conversion. This works much better and the exceptions still happening aren't stopping the main app. Also remove one useless import. --- mediagoblin/gmg_commands/import_export.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mediagoblin/gmg_commands/import_export.py b/mediagoblin/gmg_commands/import_export.py index a46219a0..30112969 100644 --- a/mediagoblin/gmg_commands/import_export.py +++ b/mediagoblin/gmg_commands/import_export.py @@ -16,7 +16,6 @@ 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.filestorage import BasicFileStorage from mediagoblin.init import setup_storage, setup_global_and_app_config @@ -209,7 +208,7 @@ def _export_media(db, args): for entry in db.media_entries.find(): for name, path in entry['media_files'].items(): - _log.info('Exporting {0} - {1}'.format( + _log.info(u'Exporting {0} - {1}'.format( entry['title'], name)) From 7cbddc96a85410c14583b598312e40efe6051a44 Mon Sep 17 00:00:00 2001 From: Elrond <elrond+mediagoblin.org@samba-tng.org> Date: Mon, 14 Nov 2011 14:21:06 +0100 Subject: [PATCH 059/302] Enable mongokit's "Dot notation" mongokit documents can allow to use x.FIELD instead of x["FIELD"]. First it looks a lot more pythonic. Second it might allow us an easier migration path towards an sqlalchemy database backend. Docs: http://namlook.github.com/mongokit/tutorial.html#dot-notation --- mediagoblin/db/models.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mediagoblin/db/models.py b/mediagoblin/db/models.py index c010cb89..65c15917 100644 --- a/mediagoblin/db/models.py +++ b/mediagoblin/db/models.py @@ -63,6 +63,7 @@ class User(Document): - bio_html: biography of the user converted to proper HTML. """ __collection__ = 'users' + use_dot_notation = True structure = { 'username': unicode, @@ -177,6 +178,7 @@ class MediaEntry(Document): - fail_metadata: """ __collection__ = 'media_entries' + use_dot_notation = True structure = { 'uploader': ObjectId, @@ -321,6 +323,7 @@ class MediaComment(Document): """ __collection__ = 'media_comments' + use_dot_notation = True structure = { 'media_entry': ObjectId, From eabe6b678a98fd06d9cd8463935a3b842f41485c Mon Sep 17 00:00:00 2001 From: Elrond <elrond+mediagoblin.org@samba-tng.org> Date: Sun, 13 Nov 2011 19:25:06 +0100 Subject: [PATCH 060/302] Dot-Notation for "_id" Note: Migrations can't use "Dot Notation"! Migrations run on pymongo, not mongokit. So they can't use the "Dot Notation". This isn't really a big issue, as migrations are anyway quite mongo specific. --- mediagoblin/auth/lib.py | 4 ++-- mediagoblin/auth/views.py | 4 ++-- mediagoblin/db/models.py | 10 +++++----- mediagoblin/decorators.py | 6 +++--- mediagoblin/edit/lib.py | 2 +- mediagoblin/edit/views.py | 6 +++--- mediagoblin/process_media/__init__.py | 4 ++-- mediagoblin/submit/views.py | 10 +++++----- .../mediagoblin/user_pages/media.html | 10 +++++----- .../templates/mediagoblin/user_pages/user.html | 6 +++--- mediagoblin/tests/test_auth.py | 12 ++++++------ mediagoblin/tests/test_submission.py | 6 +++--- mediagoblin/tools/pagination.py | 2 +- mediagoblin/user_pages/views.py | 18 +++++++++--------- 14 files changed, 50 insertions(+), 50 deletions(-) diff --git a/mediagoblin/auth/lib.py b/mediagoblin/auth/lib.py index 653424cc..cf4a2b83 100644 --- a/mediagoblin/auth/lib.py +++ b/mediagoblin/auth/lib.py @@ -109,7 +109,7 @@ def send_verification_email(user, request): 'verification_url': EMAIL_VERIFICATION_TEMPLATE.format( host=request.host, uri=request.urlgen('mediagoblin.auth.verify_email'), - userid=unicode(user['_id']), + userid=unicode(user._id), verification_key=user['verification_key'])}) # TODO: There is no error handling in place @@ -144,7 +144,7 @@ def send_fp_verification_email(user, request): 'verification_url': EMAIL_FP_VERIFICATION_TEMPLATE.format( host=request.host, uri=request.urlgen('mediagoblin.auth.verify_forgot_password'), - userid=unicode(user['_id']), + userid=unicode(user._id), fp_verification_key=user['fp_verification_key'])}) # TODO: There is no error handling in place diff --git a/mediagoblin/auth/views.py b/mediagoblin/auth/views.py index 8888d23c..8412b81c 100644 --- a/mediagoblin/auth/views.py +++ b/mediagoblin/auth/views.py @@ -87,7 +87,7 @@ def register(request): user.save(validate=True) # log the user in - request.session['user_id'] = unicode(user['_id']) + request.session['user_id'] = unicode(user._id) request.session.save() # send verification email @@ -122,7 +122,7 @@ def login(request): if user and user.check_login(request.POST['password']): # set up login in session - request.session['user_id'] = unicode(user['_id']) + request.session['user_id'] = unicode(user._id) request.session.save() if request.POST.get('next'): diff --git a/mediagoblin/db/models.py b/mediagoblin/db/models.py index 65c15917..1c1bc2fd 100644 --- a/mediagoblin/db/models.py +++ b/mediagoblin/db/models.py @@ -219,7 +219,7 @@ class MediaEntry(Document): def get_comments(self): return self.db.MediaComment.find({ - 'media_entry': self['_id']}).sort('created', DESCENDING) + 'media_entry': self._id}).sort('created', DESCENDING) def get_display_media(self, media_map, fetch_order=common.DISPLAY_IMAGE_FETCHING_ORDER): @@ -250,7 +250,7 @@ class MediaEntry(Document): {'slug': self['slug']}) if duplicate: - self['slug'] = "%s-%s" % (self['_id'], self['slug']) + self['slug'] = "%s-%s" % (self._id, self['slug']) def url_for_self(self, urlgen): """ @@ -269,13 +269,13 @@ class MediaEntry(Document): return urlgen( 'mediagoblin.user_pages.media_home', user=uploader['username'], - media=unicode(self['_id'])) + media=unicode(self._id)) def url_to_prev(self, urlgen): """ Provide a url to the previous entry from this user, if there is one """ - cursor = self.db.MediaEntry.find({'_id': {"$gt": self['_id']}, + cursor = self.db.MediaEntry.find({'_id': {"$gt": self._id}, 'uploader': self['uploader'], 'state': 'processed'}).sort( '_id', ASCENDING).limit(1) @@ -288,7 +288,7 @@ class MediaEntry(Document): """ Provide a url to the next entry from this user, if there is one """ - cursor = self.db.MediaEntry.find({'_id': {"$lt": self['_id']}, + cursor = self.db.MediaEntry.find({'_id': {"$lt": self._id}, 'uploader': self['uploader'], 'state': 'processed'}).sort( '_id', DESCENDING).limit(1) diff --git a/mediagoblin/decorators.py b/mediagoblin/decorators.py index b247e229..8f7532ec 100644 --- a/mediagoblin/decorators.py +++ b/mediagoblin/decorators.py @@ -60,7 +60,7 @@ def user_may_delete_media(controller): uploader = request.db.MediaEntry.find_one( {'_id': ObjectId(request.matchdict['media'])}).uploader() if not (request.user['is_admin'] or - request.user['_id'] == uploader['_id']): + request.user._id == uploader._id): return exc.HTTPForbidden() return controller(request, *args, **kwargs) @@ -99,7 +99,7 @@ def get_user_media_entry(controller): media = request.db.MediaEntry.find_one( {'slug': request.matchdict['media'], 'state': 'processed', - 'uploader': user['_id']}) + 'uploader': user._id}) # no media via slug? Grab it via ObjectId if not media: @@ -107,7 +107,7 @@ def get_user_media_entry(controller): media = request.db.MediaEntry.find_one( {'_id': ObjectId(request.matchdict['media']), 'state': 'processed', - 'uploader': user['_id']}) + 'uploader': user._id}) except InvalidId: return render_404(request) diff --git a/mediagoblin/edit/lib.py b/mediagoblin/edit/lib.py index b722e9c1..458b704e 100644 --- a/mediagoblin/edit/lib.py +++ b/mediagoblin/edit/lib.py @@ -17,7 +17,7 @@ def may_edit_media(request, media): """Check, if the request's user may edit the media details""" - if media['uploader'] == request.user['_id']: + if media['uploader'] == request.user._id: return True if request.user['is_admin']: return True diff --git a/mediagoblin/edit/views.py b/mediagoblin/edit/views.py index f3ebebe8..5f781552 100644 --- a/mediagoblin/edit/views.py +++ b/mediagoblin/edit/views.py @@ -57,7 +57,7 @@ def edit_media(request, media): existing_user_slug_entries = request.db.MediaEntry.find( {'slug': request.POST['slug'], 'uploader': media['uploader'], - '_id': {'$ne': media['_id']}}).count() + '_id': {'$ne': media._id}}).count() if existing_user_slug_entries: form.slug.errors.append( @@ -78,7 +78,7 @@ def edit_media(request, media): location=media.url_for_self(request.urlgen)) if request.user['is_admin'] \ - and media['uploader'] != request.user['_id'] \ + and media['uploader'] != request.user._id \ and request.method != 'POST': messages.add_message( request, messages.WARNING, @@ -104,7 +104,7 @@ def edit_attachments(request, media): attachment_public_filepath \ = mg_globals.public_store.get_unique_filepath( - ['media_entries', unicode(media['_id']), 'attachment', + ['media_entries', unicode(media._id), 'attachment', secure_filename(request.POST['attachment_file'].filename)]) attachment_public_file = mg_globals.public_store.get_file( diff --git a/mediagoblin/process_media/__init__.py b/mediagoblin/process_media/__init__.py index 3d6b418f..34d83e54 100644 --- a/mediagoblin/process_media/__init__.py +++ b/mediagoblin/process_media/__init__.py @@ -32,7 +32,7 @@ MEDIUM_SIZE = 640, 640 def create_pub_filepath(entry, filename): return mgg.public_store.get_unique_filepath( ['media_entries', - unicode(entry['_id']), + unicode(entry._id), filename]) @@ -56,7 +56,7 @@ class ProcessMedia(Task): try: process_image(entry) except BaseProcessingFail, exc: - mark_entry_failed(entry[u'_id'], exc) + mark_entry_failed(entry._id, exc) return entry['state'] = u'processed' diff --git a/mediagoblin/submit/views.py b/mediagoblin/submit/views.py index 25f7d79d..bd63bd18 100644 --- a/mediagoblin/submit/views.py +++ b/mediagoblin/submit/views.py @@ -52,7 +52,7 @@ def submit_start(request): # create entry and save in database entry = request.db.MediaEntry() - entry['_id'] = ObjectId() + entry._id = ObjectId() entry['title'] = ( unicode(request.POST['title']) or unicode(splitext(filename)[0])) @@ -62,7 +62,7 @@ def submit_start(request): entry['description']) entry['media_type'] = u'image' # heh - entry['uploader'] = request.user['_id'] + entry['uploader'] = request.user._id # Process the user's folksonomy "tags" entry['tags'] = convert_to_tag_list_of_dicts( @@ -74,7 +74,7 @@ def submit_start(request): # Now store generate the queueing related filename queue_filepath = request.app.queue_store.get_unique_filepath( ['media_entries', - unicode(entry['_id']), + unicode(entry._id), secure_filename(filename)]) # queue appropriately @@ -105,7 +105,7 @@ def submit_start(request): # conditions with changes to the document via processing code) try: process_media.apply_async( - [unicode(entry['_id'])], {}, + [unicode(entry._id)], {}, task_id=task_id) except BaseException as exc: # The purpose of this section is because when running in "lazy" @@ -116,7 +116,7 @@ def submit_start(request): # # ... not completely the diaper pattern because the # exception is re-raised :) - mark_entry_failed(entry[u'_id'], exc) + mark_entry_failed(entry._id, exc) # re-raise the exception raise diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html index 1e495b98..4b02b684 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media.html @@ -69,10 +69,10 @@ {% for comment in comments %} {% set comment_author = comment.author() %} {% if pagination.active_id == comment._id %} - <div class="comment_wrapper comment_active" id="comment-{{ comment['_id'] }}"> + <div class="comment_wrapper comment_active" id="comment-{{ comment._id }}"> <a name="comment" id="comment"></a> {% else %} - <div class="comment_wrapper" id="comment-{{ comment['_id'] }}"> + <div class="comment_wrapper" id="comment-{{ comment._id }}"> {% endif %} <div class="comment_content">{% autoescape False %}{{ comment.content_html }} @@ -83,7 +83,7 @@ {{ comment_author['username'] }}</a> {% trans %}at{% endtrans %} <a href="{{ request.urlgen('mediagoblin.user_pages.media_home.view_comment', - comment = comment['_id'], + comment = comment._id, user = media.uploader().username, media = media._id) }}#comment"> {{ comment.created.strftime("%I:%M%p %Y-%m-%d") }} @@ -114,7 +114,7 @@ <div class="grid_5 omega"> {% include "mediagoblin/utils/prev_next.html" %} - {% if media['uploader'] == request.user['_id'] or + {% if media['uploader'] == request.user._id or request.user['is_admin'] %} <h3>{% trans %}Actions{% endtrans %}</h3> <p> @@ -151,7 +151,7 @@ {% endif %} {% if app_config['allow_attachments'] - and (media['uploader'] == request.user['_id'] + and (media['uploader'] == request.user._id or request.user['is_admin']) %} <p> <a href="{{ request.urlgen('mediagoblin.edit.attachments', diff --git a/mediagoblin/templates/mediagoblin/user_pages/user.html b/mediagoblin/templates/mediagoblin/user_pages/user.html index d65da055..1de7f611 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/user.html +++ b/mediagoblin/templates/mediagoblin/user_pages/user.html @@ -90,7 +90,7 @@ </h1> {% if not user['url'] and not user['profile'] %} - {% if request.user['_id'] == user['_id'] %} + {% 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 %} @@ -113,7 +113,7 @@ {% else %} <div class="grid_6 alpha"> {% include "mediagoblin/utils/profile.html" %} - {% if request.user['_id'] == user['_id'] or request.user['is_admin'] %} + {% 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 -%} @@ -140,7 +140,7 @@ {% include "mediagoblin/utils/feed_link.html" %} </div> {% else %} - {% if request.user['_id'] == user['_id'] %} + {% if request.user._id == user._id %} <div class="grid_10 omega empty_space"> <p> {% trans -%} diff --git a/mediagoblin/tests/test_auth.py b/mediagoblin/tests/test_auth.py index 40961eca..153c6e53 100644 --- a/mediagoblin/tests/test_auth.py +++ b/mediagoblin/tests/test_auth.py @@ -168,7 +168,7 @@ def test_register_views(test_app): ## Make sure user is logged in request = template.TEMPLATE_TEST_CONTEXT[ 'mediagoblin/user_pages/user.html']['request'] - assert request.session['user_id'] == unicode(new_user['_id']) + assert request.session['user_id'] == unicode(new_user._id) ## Make sure we get email confirmation, and try verifying assert len(mail.EMAIL_TEST_INBOX) == 1 @@ -185,7 +185,7 @@ def test_register_views(test_app): ### user should have these same parameters assert parsed_get_params['userid'] == [ - unicode(new_user['_id'])] + unicode(new_user._id)] assert parsed_get_params['token'] == [ new_user['verification_key']] @@ -193,7 +193,7 @@ def test_register_views(test_app): template.clear_test_template_context() response = test_app.get( "/auth/verify_email/?userid=%s&token=total_bs" % unicode( - new_user['_id'])) + new_user._id)) response.follow() context = template.TEMPLATE_TEST_CONTEXT[ 'mediagoblin/user_pages/user.html'] @@ -269,7 +269,7 @@ def test_register_views(test_app): # user should have matching parameters new_user = mg_globals.database.User.find_one({'username': 'happygirl'}) - assert parsed_get_params['userid'] == [unicode(new_user['_id'])] + assert parsed_get_params['userid'] == [unicode(new_user._id)] assert parsed_get_params['token'] == [new_user['fp_verification_key']] ### The forgotten password token should be set to expire in ~ 10 days @@ -280,7 +280,7 @@ def test_register_views(test_app): template.clear_test_template_context() response = test_app.get( "/auth/forgot_password/verify/?userid=%s&token=total_bs" % unicode( - new_user['_id']), status=400) + new_user._id), status=400) assert response.status == '400 Bad Request' ## Try using an expired token to change password, shouldn't work @@ -412,7 +412,7 @@ def test_authentication_views(test_app): # Make sure user is in the session context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/root.html'] session = context['request'].session - assert session['user_id'] == unicode(test_user['_id']) + assert session['user_id'] == unicode(test_user._id) # Successful logout # ----------------- diff --git a/mediagoblin/tests/test_submission.py b/mediagoblin/tests/test_submission.py index 1c657e6c..dec7118b 100644 --- a/mediagoblin/tests/test_submission.py +++ b/mediagoblin/tests/test_submission.py @@ -177,7 +177,7 @@ class TestSubmission: request.urlgen('mediagoblin.user_pages.media_confirm_delete', # No work: user=media.uploader().username, user=self.test_user['username'], - media=media['_id']), + media=media._id), # no value means no confirm {}) @@ -197,7 +197,7 @@ class TestSubmission: request.urlgen('mediagoblin.user_pages.media_confirm_delete', # No work: user=media.uploader().username, user=self.test_user['username'], - media=media['_id']), + media=media._id), {'confirm': 'y'}) response.follow() @@ -208,7 +208,7 @@ class TestSubmission: # Does media entry still exist? assert_false( request.db.MediaEntry.find( - {'_id': media['_id']}).count()) + {'_id': media._id}).count()) def test_malicious_uploads(self): # Test non-suppoerted file with non-supported extension diff --git a/mediagoblin/tools/pagination.py b/mediagoblin/tools/pagination.py index bc20ec90..5ebc3c5a 100644 --- a/mediagoblin/tools/pagination.py +++ b/mediagoblin/tools/pagination.py @@ -53,7 +53,7 @@ class Pagination(object): cursor = copy.copy(self.cursor) for (doc, increment) in izip(cursor, count(0)): - if doc['_id'] == jump_to_id: + if doc._id == jump_to_id: self.page = 1 + int(floor(increment / self.per_page)) self.active_id = jump_to_id diff --git a/mediagoblin/user_pages/views.py b/mediagoblin/user_pages/views.py index 2090d6fd..82865bb4 100644 --- a/mediagoblin/user_pages/views.py +++ b/mediagoblin/user_pages/views.py @@ -45,7 +45,7 @@ def user_home(request, page): {'user': user}) cursor = request.db.MediaEntry.find( - {'uploader': user['_id'], + {'uploader': user._id, 'state': 'processed'}).sort('created', DESCENDING) pagination = Pagination(page, cursor) @@ -78,7 +78,7 @@ def user_gallery(request, page): return render_404(request) cursor = request.db.MediaEntry.find( - {'uploader': user['_id'], + {'uploader': user._id, 'state': 'processed'}).sort('created', DESCENDING) pagination = Pagination(page, cursor) @@ -135,8 +135,8 @@ def media_post_comment(request, media): assert request.method == 'POST' comment = request.db.MediaComment() - comment['media_entry'] = media['_id'] - comment['author'] = request.user['_id'] + comment['media_entry'] = media._id + comment['author'] = request.user._id comment['content'] = unicode(request.POST['comment_content']) comment['content_html'] = cleaned_markdown_conversion(comment['content']) @@ -179,7 +179,7 @@ def media_confirm_delete(request, media): location=media.url_for_self(request.urlgen)) if ((request.user[u'is_admin'] and - request.user[u'_id'] != media.uploader()[u'_id'])): + request.user._id != media.uploader()._id)): messages.add_message( request, messages.WARNING, _("You are about to delete another user's media. " @@ -207,7 +207,7 @@ def atom_feed(request): return render_404(request) cursor = request.db.MediaEntry.find({ - 'uploader': user['_id'], + 'uploader': user._id, 'state': 'processed'}) \ .sort('created', DESCENDING) \ .limit(ATOM_DEFAULT_NR_OF_UPDATED_ITEMS) @@ -251,7 +251,7 @@ def processing_panel(request): # # 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'] + if not (user._id == request.user._id or request.user.is_admin): # No? Let's simply redirect to this user's homepage then. return redirect( @@ -260,12 +260,12 @@ def processing_panel(request): # Get media entries which are in-processing processing_entries = request.db.MediaEntry.find( - {'uploader': user['_id'], + {'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'], + {'uploader': user._id, 'state': 'failed'}).sort('created', DESCENDING) # Render to response From 3618a9ac5112c657fd095a0f9cbd346921a4e800 Mon Sep 17 00:00:00 2001 From: Elrond <elrond+mediagoblin.org@samba-tng.org> Date: Mon, 14 Nov 2011 17:11:37 +0100 Subject: [PATCH 061/302] Dot-Notation: x._id = ObjectId() doesn't seem to work properly For whatever reason, this does not work as expected: entry._id = ObjectId() Need to go this way: entry['_id'] = ObjectId() --- mediagoblin/submit/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediagoblin/submit/views.py b/mediagoblin/submit/views.py index bd63bd18..139b1d1d 100644 --- a/mediagoblin/submit/views.py +++ b/mediagoblin/submit/views.py @@ -52,7 +52,7 @@ def submit_start(request): # create entry and save in database entry = request.db.MediaEntry() - entry._id = ObjectId() + entry['_id'] = ObjectId() entry['title'] = ( unicode(request.POST['title']) or unicode(splitext(filename)[0])) From 64fd0462bdd821d5777d9697e67d951838f87de0 Mon Sep 17 00:00:00 2001 From: Joar Wandborg <git@wandborg.com> Date: Tue, 15 Nov 2011 22:43:05 +0100 Subject: [PATCH 062/302] Committing some futile attempts to make GStreamer transcode the audio properly. - Added CPU count detection - Added videorate - Added audiorate --- mediagoblin/media_types/video/transcoders.py | 45 +++++++++++++++++--- 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/mediagoblin/media_types/video/transcoders.py b/mediagoblin/media_types/video/transcoders.py index 3a30aedf..de3701f6 100644 --- a/mediagoblin/media_types/video/transcoders.py +++ b/mediagoblin/media_types/video/transcoders.py @@ -29,6 +29,18 @@ _log = logging.getLogger(__name__) logging.basicConfig() _log.setLevel(logging.DEBUG) +CPU_COUNT = 2 +try: + import multiprocessing + try: + CPU_COUNT = multiprocessing.cpu_count() + except NotImplementedError: + _log.warning('multiprocessing.cpu_count not implemented') + pass +except ImportError: + _log.warning('Could not import multiprocessing, defaulting to 2 CPU cores') + pass + try: import gtk except: @@ -627,10 +639,13 @@ class VideoTranscoder: self.videoqueue = gst.element_factory_make('queue', 'videoqueue') self.pipeline.add(self.videoqueue) + self.videorate = gst.element_factory_make('videorate', 'videorate') + self.pipeline.add(self.videorate) + self.ffmpegcolorspace = gst.element_factory_make( 'ffmpegcolorspace', 'ffmpegcolorspace') self.pipeline.add(self.ffmpegcolorspace) - + self.videoscale = gst.element_factory_make('ffvideoscale', 'videoscale') #self.videoscale.set_property('method', 2) # I'm not sure this works #self.videoscale.set_property('add-borders', 0) @@ -648,11 +663,22 @@ class VideoTranscoder: self.audioqueue = gst.element_factory_make('queue', 'audioqueue') self.pipeline.add(self.audioqueue) + self.audiorate = gst.element_factory_make('audiorate', 'audiorate') + self.pipeline.add(self.audiorate) + self.audioconvert = gst.element_factory_make('audioconvert', 'audioconvert') self.pipeline.add(self.audioconvert) + self.audiocapsfilter = gst.element_factory_make('capsfilter', 'audiocapsfilter') + audiocaps = ['audio/x-raw-float'] + self.audiocapsfilter.set_property( + 'caps', + gst.caps_from_string( + ','.join(audiocaps))) + self.pipeline.add(self.audiocapsfilter) + self.vorbisenc = gst.element_factory_make('vorbisenc', 'vorbisenc') - self.vorbisenc.set_property('quality', 0.7) + self.vorbisenc.set_property('quality', 1) self.pipeline.add(self.vorbisenc) # WebMmux & filesink @@ -685,7 +711,8 @@ class VideoTranscoder: self.filesrc.link(self.decoder) # Link all the video elements in a link to webmux - self.videoqueue.link(self.ffmpegcolorspace) + self.videoqueue.link(self.videorate) + self.videorate.link(self.ffmpegcolorspace) self.ffmpegcolorspace.link(self.videoscale) self.videoscale.link(self.capsfilter) #self.capsfilter.link(self.xvimagesink) @@ -695,8 +722,12 @@ class VideoTranscoder: if self.data.is_audio: # Link all the audio elements in a line to webmux #self.audioconvert.link(self.alsasink) - self.audioqueue.link(self.audioconvert) - self.audioconvert.link(self.vorbisenc) + self.audioqueue.link(self.audiorate) + self.audiorate.link(self.audioconvert) + self.audioconvert.link(self.audiocapsfilter) + self.audiocapsfilter.link(self.vorbisenc) + #self.audiocapsfilter.link(self.level) + #self.level.link(self.vorbisenc) self.vorbisenc.link(self.webmmux) self.webmmux.link(self.progressreport) @@ -729,7 +760,7 @@ class VideoTranscoder: ''' Sets up the output format (width, height) for the video ''' - caps = ['video/x-raw-yuv', 'pixel-aspect-ratio=1/1'] + caps = ['video/x-raw-yuv', 'pixel-aspect-ratio=1/1', 'framerate=30/1'] if self.data.videoheight > self.data.videowidth: # Whoa! We have ourselves a portrait video! @@ -743,7 +774,7 @@ class VideoTranscoder: self.capsfilter.set_property( 'caps', gst.caps_from_string( - ', '.join(caps))) + ','.join(caps))) def _on_message(self, bus, message): _log.debug((bus, message, message.type)) From 359781f075f22c6ea677e28756c8046b2f405e63 Mon Sep 17 00:00:00 2001 From: Joar Wandborg <git@wandborg.com> Date: Wed, 16 Nov 2011 14:20:27 +0100 Subject: [PATCH 063/302] Fixed video transcoding - Added audiorate with tolerance 80 million - Removed deprecated thumbnailer --- mediagoblin/media_types/video/transcoders.py | 213 +------------------ 1 file changed, 1 insertion(+), 212 deletions(-) diff --git a/mediagoblin/media_types/video/transcoders.py b/mediagoblin/media_types/video/transcoders.py index de3701f6..f6a2eb21 100644 --- a/mediagoblin/media_types/video/transcoders.py +++ b/mediagoblin/media_types/video/transcoders.py @@ -340,218 +340,6 @@ class VideoThumbnailer: self.loop.quit() -class DeprecatedVideoThumbnailer: - ''' - Creates a video thumbnail - - - Sets up discoverer & transcoding pipeline. - Discoverer finds out information about the media file - - Launches gobject.MainLoop, this triggers the discoverer to start running - - Once the discoverer is done, it calls the __discovered callback function - - The __discovered callback function launches the transcoding process - - The _on_message callback is called from the transcoding process until it - gets a message of type gst.MESSAGE_EOS, then it calls __stop which shuts - down the gobject.MainLoop - ''' - - WADSWORTH_CONSTANT = 30 # percent - - def __init__(self, src, dst, **kwargs): - _log.info('Initializing VideoThumbnailer...') - - self.loop = gobject.MainLoop() - - self.source_path = src - self.destination_path = dst - - self.destination_dimensions = kwargs.get('dimensions') or (180, 180) - - if not type(self.destination_dimensions) == tuple: - raise Exception('dimensions must be tuple: (width, height)') - - self._setup() - self._run() - - def _setup(self): - self._setup_pipeline() - self._setup_discover() - - def _run(self): - _log.info('Discovering...') - self.discoverer.discover() - _log.info('Done') - - _log.debug('Initializing MainLoop()') - self.loop.run() - - def _setup_discover(self): - self.discoverer = discoverer.Discoverer(self.source_path) - - # Connect self.__discovered to the 'discovered' event - self.discoverer.connect('discovered', self.__discovered) - - def __discovered(self, data, is_media): - ''' - Callback for media discoverer. - ''' - if not is_media: - self.__stop() - raise Exception('Could not discover {0}'.format(self.source_path)) - - _log.debug('__discovered, data: {0}'.format(data)) - - self.data = data - - # Run any tasks that depend on the info from the discovery - self._on_discovered() - - # Tell the transcoding pipeline to start running - _log.info('Transcoding...') - - def _on_discovered(self): - self.__setup_capsfilter() - - def _setup_pipeline(self): - # Create a new pipeline - self.pipeline = gst.Pipeline('VideoThumbnailerPipeline') - - # Create the elements in the pipeline - self.filesrc = gst.element_factory_make('filesrc', 'filesrc') - self.filesrc.set_property('location', self.source_path) - self.pipeline.add(self.filesrc) - - self.decoder = gst.element_factory_make('decodebin2', 'decoder') - self.decoder.connect('new-decoded-pad', self._on_dynamic_pad) - self.pipeline.add(self.decoder) - - self.ffmpegcolorspace = gst.element_factory_make( - 'ffmpegcolorspace', 'ffmpegcolorspace') - self.pipeline.add(self.ffmpegcolorspace) - - self.videoscale = gst.element_factory_make('videoscale', 'videoscale') - self.videoscale.set_property('method', 'bilinear') - self.pipeline.add(self.videoscale) - - self.capsfilter = gst.element_factory_make('capsfilter', 'capsfilter') - self.pipeline.add(self.capsfilter) - - self.jpegenc = gst.element_factory_make('jpegenc', 'jpegenc') - self.pipeline.add(self.jpegenc) - - #self.filesink = gst.element_factory_make('filesink', 'filesink') - #self.filesink.set_property('location', self.destination_path) - #self.pipeline.add(self.filesink) - - self.appsink = gst.element_factory_make('appsink', 'appsink') - self.appsink.set_property('emit-signals', True) - self.appsink.connect('new-preroll', self.__on_sink_preroll) - self.pipeline.add(self.appsink) - - self.progressreport = gst.element_factory_make( - 'progressreport', 'progressreport') - self.progressreport.set_property('update-freq', 1) - self.pipeline.add(self.progressreport) - - self.identity = gst.element_factory_make('identity', 'id') - self.pipeline.add(self.identity) - - # Link all the elements together - self.filesrc.link(self.decoder) - self.ffmpegcolorspace.link(self.videoscale) - self.videoscale.link(self.capsfilter) - self.capsfilter.link(self.jpegenc) - self.jpegenc.link(self.progressreport) - self.progressreport.link(self.identity) - #self.identity.link(self.filesink) - self.identity.link(self.appsink) - - self.pipeline.set_state(gst.STATE_PAUSED) - - self._setup_bus() - - def __on_sink_preroll(self, sink): - _log.debug('SINK PREROLL!!!!') - - def _on_dynamic_pad(self, dbin, pad, islast): - ''' - Callback called when ``decodebin2`` has a pad that we can connect to - ''' - # Intersect the capabilities of the video sink and the pad src - # Then check if they have no common capabilities. - if not self.ffmpegcolorspace.get_pad_template('sink')\ - .get_caps().intersect(pad.get_caps()).is_empty(): - # It IS a video src pad. - pad.link(self.ffmpegcolorspace.get_pad('sink')) - gst.DEBUG_BIN_TO_DOT_FILE( - self.pipeline, - gst.DEBUG_GRAPH_SHOW_ALL, - 'ss') - - def _setup_bus(self): - self.bus = self.pipeline.get_bus() - self.bus.add_signal_watch() - self.bus.connect('message', self._on_message) - - def __setup_capsfilter(self): - caps = ['video/x-raw-rgb', 'pixel-aspect-ratio=1/1'] - - if self.data.videoheight > self.data.videowidth: - # Whoa! We have ourselves a portrait video! - caps.append('height={0}'.format( - self.destination_dimensions[1])) - else: - # It's a landscape, phew, how normal. - caps.append('width={0}'.format( - self.destination_dimensions[0])) - - self.capsfilter.set_property( - 'caps', - gst.caps_from_string( - ', '.join(caps))) - - def __find_wadsworth(self): - if self.decoder.seek_simple( - gst.FORMAT_PERCENT, - gst.SEEK_FLAG_NONE, - 0 * 10000): - _log.info('Found wadsworth') - #pdb.set_trace() - #self.pipeline.set_state(gst.STATE_PLAYING) - self.__get_buffer() - self.__stop() - else: - pdb.set_trace() - - def __get_buffer(self): - buffer = self.appsink.emit('pull-preroll') - open(self.destination_path, 'wb').write(buffer) - - def _on_message(self, bus, message): - t = message.type - - _log.debug(( - t == gst.MESSAGE_ASYNC_DONE, - bus, - message)) - - if t == gst.MESSAGE_EOS: - self.__stop() - _log.info('Got EOS') - elif t == gst.MESSAGE_ASYNC_DONE: - #pdb.set_trace() - self.__find_wadsworth() - elif t == gst.MESSAGE_ERROR: - _log.error((bus, message)) - self.__stop() - - def __stop(self): - _log.debug(self.loop) - - self.pipeline.set_state(gst.STATE_NULL) - - gobject.idle_add(self.loop.quit) - - class VideoTranscoder: ''' Video transcoder @@ -664,6 +452,7 @@ class VideoTranscoder: self.pipeline.add(self.audioqueue) self.audiorate = gst.element_factory_make('audiorate', 'audiorate') + self.audiorate.set_property('tolerance', 80000000) self.pipeline.add(self.audiorate) self.audioconvert = gst.element_factory_make('audioconvert', 'audioconvert') From 76c6c806caec7af20a3fe11c04bb783baacc3934 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber <cwebber@dustycloud.org> Date: Wed, 16 Nov 2011 17:53:46 -0600 Subject: [PATCH 064/302] Accidentally had user['profile'] where it shoulda been user['bio'] --- mediagoblin/templates/mediagoblin/user_pages/user.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediagoblin/templates/mediagoblin/user_pages/user.html b/mediagoblin/templates/mediagoblin/user_pages/user.html index c5beeaaa..6d938262 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/user.html +++ b/mediagoblin/templates/mediagoblin/user_pages/user.html @@ -78,7 +78,7 @@ {%- trans username=user.username %}{{ username }}'s profile{% endtrans -%} </h1> - {% if not user['url'] and not user['profile'] %} + {% if not user['url'] and not user['bio'] %} {% if request.user['_id'] == user['_id'] %} <div class="grid_6 alpha empty_space"> <p> From ccca0fbfc3667900d0a5ad3687c27f4fd72db061 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber <cwebber@dustycloud.org> Date: Thu, 17 Nov 2011 08:28:23 -0600 Subject: [PATCH 065/302] Beginnings of sqlalchemy models --- mediagoblin/db/sql.py | 95 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 mediagoblin/db/sql.py diff --git a/mediagoblin/db/sql.py b/mediagoblin/db/sql.py new file mode 100644 index 00000000..31ebfbf4 --- /dev/null +++ b/mediagoblin/db/sql.py @@ -0,0 +1,95 @@ +import datetime + +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy import ( + Column, Integer, Unicode, UnicodeText, DateTime, Boolean, ForeignKey, + UniqueConstraint) + + +Base = declarative_base() + + +class User(Base): + __tablename__ = "users" + + id = Column(Integer, primary_key=True) + username = Column(Unicode, nullable=False, unique=True) + email = Column(Unicode, nullable=False) + created = Column(DateTime, nullable=False, default=datetime.datetime.now) + pw_hash = Column(Unicode, nullable=False) + email_verified = Column(Boolean) + status = Column(Unicode, default="needs_email_verification", nullable=False) + verification_key = Column(Unicode) + is_admin = Column(Boolean, default=False, nullable=False) + url = Column(Unicode) + bio = Column(UnicodeText) # ?? + bio_html = Column(UnicodeText) # ?? + fp_verification_key = Column(Unicode) + fp_verification_expire = Column(DateTime) + + ## TODO + # plugin data would be in a separate model + + +class MediaEntry(Base): + __tablename__ = "media_entries" + + id = Column(Integer, primary_key=True) + uploader = Column(Integer, ForeignKey('users.id'), nullable=False) + slug = Column(Unicode, nullable=False) + created = Column(DateTime, nullable=False, default=datetime.datetime.now) + description = Column(UnicodeText) # ?? + description_html = Column(UnicodeText) # ?? + media_type = Column(Unicode, nullable=False) + + fail_error = Column(Unicode) + fail_metadata = Column(UnicodeText) + + queued_media_file = Column(Unicode) + + queued_task_id = Column(Unicode) + + __table_args__ = ( + UniqueConstraint('uploader', 'slug'), + {}) + + ## TODO + # media_files + # media_data + # attachment_files + # fail_error + + +class Tag(Base): + __tablename__ = "tags" + + id = Column(Integer, primary_key=True) + slug = Column(Unicode, nullable=False, unique=True) + + +class MediaTag(Base): + __tablename__ = "media_tags" + + id = Column(Integer, primary_key=True) + tag = Column(Integer, ForeignKey('tags.id'), nullable=False) + name = Column(Unicode) + media_entry = Column( + Integer, ForeignKey('media_entries.id'), + nullable=False) + # created = Column(DateTime, nullable=False, default=datetime.datetime.now) + + __table_args__ = ( + UniqueConstraint('tag', 'media_entry'), + {}) + + +class MediaComment(Base): + __tablename__ = "media_comments" + + id = Column(Integer, primary_key=True) + media_entry = Column( + Integer, ForeignKey('media_entries.id'), nullable=False) + author = Column(Integer, ForeignKey('users.id'), nullable=False) + created = Column(DateTime, nullable=False, default=datetime.datetime.now) + content = Column(UnicodeText, nullable=False) + content_html = Column(UnicodeText) From 6950c6c77c2daf4a47810e05a7c3f64f8995059d Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber <cwebber@dustycloud.org> Date: Sat, 19 Nov 2011 08:31:37 -0600 Subject: [PATCH 066/302] Adding app_config and global_config to the template environment --- mediagoblin/tools/template.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mediagoblin/tools/template.py b/mediagoblin/tools/template.py index 905a36df..a0eaabe7 100644 --- a/mediagoblin/tools/template.py +++ b/mediagoblin/tools/template.py @@ -55,6 +55,8 @@ def get_jinja_env(template_loader, locale): template_env.globals['fetch_messages'] = messages.fetch_messages template_env.globals['gridify_list'] = gridify_list template_env.globals['gridify_cursor'] = gridify_cursor + template_env.globals['app_config'] = mg_globals.app_config + template_env.globals['global_config'] = mg_globals.global_config if exists(locale): SETUP_JINJA_ENVS[locale] = template_env From 53bc39755bf22fe8eebf06b051018eba111a64e7 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber <cwebber@dustycloud.org> Date: Sat, 19 Nov 2011 08:33:29 -0600 Subject: [PATCH 067/302] Add app_config and global_config to the template environment --- mediagoblin/tools/template.py | 1 + 1 file changed, 1 insertion(+) diff --git a/mediagoblin/tools/template.py b/mediagoblin/tools/template.py index a0eaabe7..0986761b 100644 --- a/mediagoblin/tools/template.py +++ b/mediagoblin/tools/template.py @@ -52,6 +52,7 @@ def get_jinja_env(template_loader, locale): # All templates will know how to ... # ... fetch all waiting messages and remove them from the queue # ... construct a grid of thumbnails or other media + # ... have access to the global and app config template_env.globals['fetch_messages'] = messages.fetch_messages template_env.globals['gridify_list'] = gridify_list template_env.globals['gridify_cursor'] = gridify_cursor From 3c0411f51f43ade8c7d47df4f3843fd79d4709b5 Mon Sep 17 00:00:00 2001 From: "Pablo J. Urbano Santos" <flamma@member.fsf.org> Date: Sat, 19 Nov 2011 17:07:41 +0100 Subject: [PATCH 068/302] Allow instance owners to customize html titles of page: Added html_title config option. Made base.html template use html_title option as page title. --- mediagoblin/config_spec.ini | 3 +++ mediagoblin/templates/mediagoblin/base.html | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/mediagoblin/config_spec.ini b/mediagoblin/config_spec.ini index 900957ce..b804358c 100644 --- a/mediagoblin/config_spec.ini +++ b/mediagoblin/config_spec.ini @@ -1,4 +1,7 @@ [mediagoblin] +# HTML title of the pages +html_title = string(default="GNU MediaGoblin") + # database stuff db_host = string() db_name = string(default="mediagoblin") diff --git a/mediagoblin/templates/mediagoblin/base.html b/mediagoblin/templates/mediagoblin/base.html index 925386e5..0d6b9e40 100644 --- a/mediagoblin/templates/mediagoblin/base.html +++ b/mediagoblin/templates/mediagoblin/base.html @@ -19,7 +19,7 @@ <html> <head> <meta charset="utf-8"> - <title>{% block title %}{% trans %}GNU MediaGoblin{% endtrans %}{% endblock title %} + {{ app_config['html_title'] }} Date: Sat, 19 Nov 2011 19:11:42 +0100 Subject: [PATCH 069/302] Added parameter ascending to MediaEntry::get_comments, if true, comments will be ordered ascending, otherwise descending --- mediagoblin/db/models.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/mediagoblin/db/models.py b/mediagoblin/db/models.py index 1c1bc2fd..f13a4457 100644 --- a/mediagoblin/db/models.py +++ b/mediagoblin/db/models.py @@ -217,9 +217,14 @@ class MediaEntry(Document): 'created': datetime.datetime.utcnow, 'state': u'unprocessed'} - def get_comments(self): + def get_comments(self, ascending=False): + if ascending: + order = ASCENDING + else: + order = DESCENDING + return self.db.MediaComment.find({ - 'media_entry': self._id}).sort('created', DESCENDING) + 'media_entry': self._id}).sort('created', order) def get_display_media(self, media_map, fetch_order=common.DISPLAY_IMAGE_FETCHING_ORDER): From 1a3138addd43d410b03cdd1816e0a62bd217de30 Mon Sep 17 00:00:00 2001 From: "Pablo J. Urbano Santos" Date: Sat, 19 Nov 2011 19:15:41 +0100 Subject: [PATCH 070/302] media_home: order comments by ascending date. --- mediagoblin/user_pages/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mediagoblin/user_pages/views.py b/mediagoblin/user_pages/views.py index 82865bb4..98a21bb4 100644 --- a/mediagoblin/user_pages/views.py +++ b/mediagoblin/user_pages/views.py @@ -106,11 +106,11 @@ def media_home(request, media, page, **kwargs): """ if ObjectId(request.matchdict.get('comment')): pagination = Pagination( - page, media.get_comments(), MEDIA_COMMENTS_PER_PAGE, + page, media.get_comments(True), MEDIA_COMMENTS_PER_PAGE, ObjectId(request.matchdict.get('comment'))) else: pagination = Pagination( - page, media.get_comments(), MEDIA_COMMENTS_PER_PAGE) + page, media.get_comments(True), MEDIA_COMMENTS_PER_PAGE) comments = pagination() From fc5695c538f2b6d230c0e431087e9c10e6deac6c Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Sat, 19 Nov 2011 10:43:31 -0800 Subject: [PATCH 071/302] incorrect path in nginx config --- docs/source/deploying.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/deploying.rst b/docs/source/deploying.rst index c2ba0c47..b944a3d3 100644 --- a/docs/source/deploying.rst +++ b/docs/source/deploying.rst @@ -207,7 +207,7 @@ this ``nginx.conf`` file should be modeled on the following: :: # Instance specific media: location /mgoblin_media/ { - alias /srv/mediagoblin.example.org/mediagoblin/mediagoblin/user_dev/media/public/; + alias /srv/mediagoblin.example.org/mediagoblin/user_dev/media/public/; } # Mounting MediaGoblin itself via fastcgi. From b4b7b6a57a5ad9a5e52a5d3e05f9ad3d3e8b650a Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Sat, 19 Nov 2011 13:42:30 -0600 Subject: [PATCH 072/302] Added Corey Farwell to the list of contributors --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index c9fc5c8e..b0ef7154 100644 --- a/AUTHORS +++ b/AUTHORS @@ -13,6 +13,7 @@ Thank you! * Alex Camelio * Bernhard Keller * Caleb Forbes Davis V +* Corey Farwell * Chris Moylan * Christopher Allan Webber * Daniel Neel From 7c378f2cd5324a05e709cbada5eb5668ce3a3469 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Sat, 19 Nov 2011 14:01:38 -0600 Subject: [PATCH 073/302] Allow user to set whether comments are ascending or descending --- mediagoblin/config_spec.ini | 3 +++ mediagoblin/user_pages/views.py | 8 ++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/mediagoblin/config_spec.ini b/mediagoblin/config_spec.ini index 900957ce..4d412346 100644 --- a/mediagoblin/config_spec.ini +++ b/mediagoblin/config_spec.ini @@ -27,6 +27,9 @@ allow_registration = boolean(default=True) tags_delimiter = string(default=",") tags_max_length = integer(default=50) +# Whether comments are ascending or descending +comments_ascending = boolean(default=True) + # By default not set, but you might want something like: # "%(here)s/user_dev/templates/" local_templates = string() diff --git a/mediagoblin/user_pages/views.py b/mediagoblin/user_pages/views.py index 98a21bb4..25fd2ebb 100644 --- a/mediagoblin/user_pages/views.py +++ b/mediagoblin/user_pages/views.py @@ -106,11 +106,15 @@ def media_home(request, media, page, **kwargs): """ if ObjectId(request.matchdict.get('comment')): pagination = Pagination( - page, media.get_comments(True), MEDIA_COMMENTS_PER_PAGE, + page, media.get_comments( + mg_globals.app_config['comments_ascending']), + MEDIA_COMMENTS_PER_PAGE, ObjectId(request.matchdict.get('comment'))) else: pagination = Pagination( - page, media.get_comments(True), MEDIA_COMMENTS_PER_PAGE) + page, media.get_comments( + mg_globals.app_config['comments_ascending']), + MEDIA_COMMENTS_PER_PAGE) comments = pagination() From 1bc231c766c41f61aee6d91c631bd972426b277b Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Sat, 19 Nov 2011 14:03:01 -0600 Subject: [PATCH 074/302] Added Pablo Santos to the AUTHORS file --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index b0ef7154..76e16b86 100644 --- a/AUTHORS +++ b/AUTHORS @@ -28,6 +28,7 @@ Thank you! * Nathan Yergler * Odin Hørthe Omdal * Osama Khalid +* Pablo J. Urbano Santos * Rasmus Larsson * Sam Kleinman * Sebastian Spaeth From 7880168526032bc2ddce96257d8f62a01e562832 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Sat, 19 Nov 2011 14:06:48 -0600 Subject: [PATCH 075/302] Added back the title block --- mediagoblin/templates/mediagoblin/base.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediagoblin/templates/mediagoblin/base.html b/mediagoblin/templates/mediagoblin/base.html index 0d6b9e40..64fafb73 100644 --- a/mediagoblin/templates/mediagoblin/base.html +++ b/mediagoblin/templates/mediagoblin/base.html @@ -19,7 +19,7 @@ - {{ app_config['html_title'] }} + {% block title %}{{ app_config['html_title'] }}{% endblock %} Date: Sat, 19 Nov 2011 23:46:42 +0100 Subject: [PATCH 076/302] Change form structure and add relevant CSS rules --- mediagoblin/static/css/base.css | 6 +++++- mediagoblin/templates/mediagoblin/utils/wtforms.html | 12 +++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css index afd10207..a7b659c3 100644 --- a/mediagoblin/static/css/base.css +++ b/mediagoblin/static/css/base.css @@ -212,7 +212,11 @@ text-align: center; width: 100%; } -.form_field_label,.form_field_input { +.form_field_input { + margin-bottom: 10px; +} + +.form_field_label { margin-bottom: 4px; } diff --git a/mediagoblin/templates/mediagoblin/utils/wtforms.html b/mediagoblin/templates/mediagoblin/utils/wtforms.html index 6a86fd24..39dca7cc 100644 --- a/mediagoblin/templates/mediagoblin/utils/wtforms.html +++ b/mediagoblin/templates/mediagoblin/utils/wtforms.html @@ -18,18 +18,16 @@ {# Generically render a field #} {% macro render_field_div(field) %} -
-
{{ _(field.label.text) }}
-
{{ field }}
+

+
+ {{ field }} {%- if field.errors -%} {% for error in field.errors %} -
- {{ error }} -
+

{{ error }}

{% endfor %} {%- endif %} {% if field.description -%} -
{{ _(field.description) }}
+

{{ _(field.description) }}

{%- endif %}
{%- endmacro %} From 2d62e9efd210becd30982e65e06a6ef97029b391 Mon Sep 17 00:00:00 2001 From: lora Date: Sat, 19 Nov 2011 17:00:25 -0600 Subject: [PATCH 077/302] issue 582: use media.slug instead of media.id --- mediagoblin/decorators.py | 3 +-- mediagoblin/templates/mediagoblin/user_pages/media.html | 4 ++-- .../mediagoblin/user_pages/media_confirm_delete.html | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/mediagoblin/decorators.py b/mediagoblin/decorators.py index 19e22bca..38f52ced 100644 --- a/mediagoblin/decorators.py +++ b/mediagoblin/decorators.py @@ -58,7 +58,7 @@ def user_may_delete_media(controller): """ def wrapper(request, *args, **kwargs): uploader = request.db.MediaEntry.find_one( - {'_id': ObjectId(request.matchdict['media'])}).uploader() + {'slug': request.matchdict['media'] }).uploader() if not (request.user['is_admin'] or request.user['_id'] == uploader['_id']): return exc.HTTPForbidden() @@ -95,7 +95,6 @@ def get_user_media_entry(controller): if not user: return render_404(request) - media = request.db.MediaEntry.find_one( {'slug': request.matchdict['media'], 'state': 'processed', diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html index 433f74dc..5e1b73de 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media.html @@ -124,7 +124,7 @@

{% set edit_url = request.urlgen('mediagoblin.edit.edit_media', user= media.uploader().username, - media= media._id) %} + media= media.slug) %} @@ -133,7 +133,7 @@

{% set delete_url = request.urlgen('mediagoblin.user_pages.media_confirm_delete', user= media.uploader().username, - media= media._id) %} + media= media.slug) %} diff --git a/mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html b/mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html index dd6923a9..f62082bd 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html @@ -23,7 +23,7 @@

From 909dda1f85b27866e0d20343169c91953ca7d8f6 Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Sun, 20 Nov 2011 00:28:19 +0100 Subject: [PATCH 078/302] Change button style a bit --- mediagoblin/static/css/base.css | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css index a7b659c3..8d9756b9 100644 --- a/mediagoblin/static/css/base.css +++ b/mediagoblin/static/css/base.css @@ -99,20 +99,14 @@ a.mediagoblin_logo{ } .header_submit, .header_submit_highlight{ - color: #272727; - background-color: #aaa; - background-image: -webkit-gradient(linear, left top, left bottom, from(##D2D2D2), to(#aaa)); - background-image: -webkit-linear-gradient(top, #D2D2D2, #aaa); - background-image: -moz-linear-gradient(top, #D2D2D2, #aaa); - background-image: -ms-linear-gradient(top, #D2D2D2, #aaa); - background-image: -o-linear-gradient(top, #D2D2D2, #aaa); - background-image: linear-gradient(top, #D2D2D2, #aaa); - box-shadow: 0px 0px 4px #000; - border-radius: 3px; + color: #c3c3c3; + background-color: #2d2d2d; + border: 1px solid; + border-color: #323232 #232323 #1F1F1F; + border-radius: 4px; margin: 8px; padding: 3px 8px; text-decoration: none; - border: medium none; font-style: normal; font-weight: bold; font-size: 1em; @@ -301,7 +295,7 @@ img.media_icon{ background-color: #1d1d1d; border: 1px solid; border-color: #2c2c2c #232323 #1a1a1a; - border-radius: 3px; + border-radius: 4px; text-decoration: none; padding: 8px 0px 14px; font-size: 2em; From 4837b2f253e7f525eb4eb97a574c8af68c0ff570 Mon Sep 17 00:00:00 2001 From: Jakob Kramer Date: Sat, 19 Nov 2011 22:17:21 +0100 Subject: [PATCH 079/302] added support for changing the password, issue #643 --- mediagoblin/edit/forms.py | 13 +++++++++++++ mediagoblin/edit/views.py | 34 ++++++++++++++++++++++++---------- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/mediagoblin/edit/forms.py b/mediagoblin/edit/forms.py index 7e71722c..ec4e22b3 100644 --- a/mediagoblin/edit/forms.py +++ b/mediagoblin/edit/forms.py @@ -43,6 +43,19 @@ class EditProfileForm(wtforms.Form): _('Website'), [wtforms.validators.Optional(), wtforms.validators.URL(message='Improperly formed URL')]) + old_password = wtforms.PasswordField( + _('Old password'), + [wtforms.validators.Optional()]) + new_password = wtforms.PasswordField( + _('New Password'), + [wtforms.validators.Optional(), + wtforms.validators.Length(min=6, max=30), + wtforms.validators.EqualTo( + 'confirm_password', + 'Passwords must match.')]) + confirm_password = wtforms.PasswordField( + 'Confirm password', + [wtforms.validators.Optional()]) class EditAttachmentsForm(wtforms.Form): diff --git a/mediagoblin/edit/views.py b/mediagoblin/edit/views.py index 5f781552..75bf51bf 100644 --- a/mediagoblin/edit/views.py +++ b/mediagoblin/edit/views.py @@ -26,6 +26,7 @@ from werkzeug.utils import secure_filename from mediagoblin import messages from mediagoblin import mg_globals +from mediagoblin.auth import lib as auth_lib from mediagoblin.edit import forms from mediagoblin.edit.lib import may_edit_media from mediagoblin.decorators import require_active_login, get_user_media_entry @@ -161,19 +162,32 @@ def edit_profile(request): bio=user.get('bio')) if request.method == 'POST' and form.validate(): - user['url'] = unicode(request.POST['url']) - user['bio'] = unicode(request.POST['bio']) + user['url'] = unicode(request.POST['url']) + user['bio'] = unicode(request.POST['bio']) - user['bio_html'] = cleaned_markdown_conversion(user['bio']) - - user.save() + password_matches = auth_lib.bcrypt_check_password(request.POST['old_password'], + user['pw_hash']) + if (request.POST['old_password'] or request.POST['new_password']) and not \ + password_matches: messages.add_message(request, - messages.SUCCESS, - _("Profile edited!")) - return redirect(request, - 'mediagoblin.user_pages.user_home', - user=edit_username) + messages.ERROR, + _('Wrong password')) + + if password_matches: + user['pw_hash'] = auth_lib.bcrypt_gen_password_hash( + request.POST['new_password']) + + user['bio_html'] = cleaned_markdown_conversion(user['bio']) + + user.save() + + messages.add_message(request, + messages.SUCCESS, + _("Profile edited!")) + return redirect(request, + 'mediagoblin.user_pages.user_home', + user=edit_username) return render_to_response( request, From c8ccd23e8e0d77df3e7382cd6330e0c993bbcc8e Mon Sep 17 00:00:00 2001 From: Jakob Kramer Date: Sun, 20 Nov 2011 00:35:09 +0100 Subject: [PATCH 080/302] added unittests, now using form errors and fixed bug when no GET parameter is given for /edit/profile/ --- mediagoblin/edit/views.py | 23 ++++--- mediagoblin/tests/test_edit.py | 112 +++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+), 9 deletions(-) create mode 100644 mediagoblin/tests/test_edit.py diff --git a/mediagoblin/edit/views.py b/mediagoblin/edit/views.py index 75bf51bf..673409bd 100644 --- a/mediagoblin/edit/views.py +++ b/mediagoblin/edit/views.py @@ -162,17 +162,22 @@ def edit_profile(request): bio=user.get('bio')) if request.method == 'POST' and form.validate(): - user['url'] = unicode(request.POST['url']) - user['bio'] = unicode(request.POST['bio']) - - password_matches = auth_lib.bcrypt_check_password(request.POST['old_password'], - user['pw_hash']) + password_matches = auth_lib.bcrypt_check_password( + request.POST['old_password'], + user['pw_hash']) if (request.POST['old_password'] or request.POST['new_password']) and not \ password_matches: - messages.add_message(request, - messages.ERROR, - _('Wrong password')) + form.old_password.errors.append(_('Wrong password')) + + return render_to_response( + request, + 'mediagoblin/edit/edit_profile.html', + {'user': user, + 'form': form}) + + user['url'] = unicode(request.POST['url']) + user['bio'] = unicode(request.POST['bio']) if password_matches: user['pw_hash'] = auth_lib.bcrypt_gen_password_hash( @@ -187,7 +192,7 @@ def edit_profile(request): _("Profile edited!")) return redirect(request, 'mediagoblin.user_pages.user_home', - user=edit_username) + user=user['username']) return render_to_response( request, diff --git a/mediagoblin/tests/test_edit.py b/mediagoblin/tests/test_edit.py new file mode 100644 index 00000000..3637b046 --- /dev/null +++ b/mediagoblin/tests/test_edit.py @@ -0,0 +1,112 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +from mediagoblin import mg_globals +from mediagoblin.tests.tools import setup_fresh_app +from mediagoblin.tools import template +from mediagoblin.auth.lib import bcrypt_check_password, \ + bcrypt_gen_password_hash + + +@setup_fresh_app +def test_change_password(test_app): + """Test changing password correctly and incorrectly""" + # set up new user + test_user = mg_globals.database.User() + test_user['username'] = u'chris' + test_user['email'] = u'chris@example.com' + test_user['email_verified'] = True + test_user['status'] = u'active' + test_user['pw_hash'] = bcrypt_gen_password_hash('toast') + test_user.save() + + test_app.post( + '/auth/login/', { + 'username': u'chris', + 'password': 'toast'}) + + # test that the password can be changed + # template.clear_test_template_context() + test_app.post( + '/edit/profile/', { + 'bio': u'', + 'url': u'', + 'old_password': 'toast', + 'new_password': '123456', + 'confirm_password': '123456'}) + + # test_user has to be fetched again in order to have the current values + test_user = mg_globals.database.User.one({'username': 'chris'}) + + assert bcrypt_check_password('123456', test_user['pw_hash']) + + # test that the password cannot be changed if the given old_password + # is wrong + # template.clear_test_template_context() + test_app.post( + '/edit/profile/', { + 'bio': u'', + 'url': u'', + 'old_password': 'toast', + 'new_password': '098765', + 'confirm_password': '098765'}) + + test_user = mg_globals.database.User.one({'username': 'chris'}) + + assert not bcrypt_check_password('098765', test_user['pw_hash']) + + +@setup_fresh_app +def change_bio_url(test_app): + """Test changing bio and URL""" + # set up new user + test_user = mg_globals.database.User() + test_user['username'] = u'chris' + test_user['email'] = u'chris@example.com' + test_user['email_verified'] = True + test_user['status'] = u'active' + test_user['pw_hash'] = bcrypt_gen_password_hash('toast') + test_user.save() + + # test changing the bio and the URL properly + test_app.post( + '/edit/profile/', { + 'bio': u'I love toast!', + 'url': u'http://dustycloud.org/'}) + + test_user = mg_globals.database.User.one({'username': 'chris'}) + + assert test_user['bio'] == u'I love toast!' + assert test_user['url'] == u'http://dustycloud.org/' + + # test changing the bio and the URL inproperly + too_long_bio = 150 * 'T' + 150 * 'o' + 150 * 'a' + 150 * 's' + 150* 't' + + test_app.post( + '/edit/profile/', { + # more than 500 characters + 'bio': too_long_bio, + 'url': 'this-is-no-url'}) + + test_user = mg_globals.database.User.one({'username': 'chris'}) + + context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/edit/edit_profile.html'] + form = context['edit_profile_form'] + + assert form.bio.errors == [u'Field must be between 0 and 500 characters long.'] + assert form.url.errors == [u'Improperly formed URL'] + + # test changing the url inproperly From 5bd523eb23e7c30b52e41cdb0f02053d8573ce63 Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Sun, 20 Nov 2011 01:12:10 +0100 Subject: [PATCH 081/302] Change to background of "empty_space", it now uses an image --- mediagoblin/static/css/base.css | 2 +- mediagoblin/static/images/empty_back.png | Bin 0 -> 191 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 mediagoblin/static/images/empty_back.png diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css index 8d9756b9..d61292a2 100644 --- a/mediagoblin/static/css/base.css +++ b/mediagoblin/static/css/base.css @@ -177,7 +177,7 @@ text-align: center; } .empty_space{ - background-color: #222; + background-image: url("../images/empty_back.png"); font-style: italic; text-align: center; height: 160px; diff --git a/mediagoblin/static/images/empty_back.png b/mediagoblin/static/images/empty_back.png new file mode 100644 index 0000000000000000000000000000000000000000..3522ddd3c56c5c9f3ca8c2fdd93a0564f352a58d GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4u@pObhHwBu4M$1`kk47*5m^kR ztU#FYL&_vCprB-lYeY$Kep*R+Vo@qXd3m{BW?pu2a$-TMUVc&f>~}U&Kt(p5E{-7* zQ Date: Sun, 20 Nov 2011 01:43:48 +0100 Subject: [PATCH 082/302] Another change to button style. Renamed header_submit, header_submit_highlight and button classes, correct all references to these --- mediagoblin/static/css/base.css | 39 ++++++++++--------- .../templates/mediagoblin/auth/change_fp.html | 2 +- .../mediagoblin/auth/forgot_password.html | 2 +- .../templates/mediagoblin/auth/login.html | 4 +- .../templates/mediagoblin/auth/register.html | 2 +- mediagoblin/templates/mediagoblin/base.html | 6 +-- .../mediagoblin/edit/attachments.html | 2 +- .../templates/mediagoblin/edit/edit.html | 2 +- .../mediagoblin/edit/edit_profile.html | 2 +- mediagoblin/templates/mediagoblin/root.html | 4 +- .../templates/mediagoblin/submit/start.html | 2 +- .../templates/mediagoblin/test_submit.html | 2 +- .../mediagoblin/user_pages/media.html | 2 +- .../user_pages/media_confirm_delete.html | 2 +- .../mediagoblin/user_pages/user.html | 6 +-- 15 files changed, 40 insertions(+), 39 deletions(-) diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css index d61292a2..cec236f4 100644 --- a/mediagoblin/static/css/base.css +++ b/mediagoblin/static/css/base.css @@ -98,24 +98,6 @@ a.mediagoblin_logo{ font-weight: bold; } -.header_submit, .header_submit_highlight{ - color: #c3c3c3; - background-color: #2d2d2d; - border: 1px solid; - border-color: #323232 #232323 #1F1F1F; - border-radius: 4px; - margin: 8px; - padding: 3px 8px; - text-decoration: none; - font-style: normal; - font-weight: bold; - font-size: 1em; -} - -.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 #333; @@ -135,7 +117,26 @@ background-image: -moz-linear-gradient(center top , rgb(134, 212, 177), rgb(109, /* common website elements */ -.button, .cancel_link { +.button_action, .button_action_highlight{ + color: #c3c3c3; + background-color: #363636; + border: 1px solid; + border-color: #464646 #2B2B2B #252525; + border-radius: 4px; + margin: 8px; + padding: 3px 8px; + text-decoration: none; + font-style: normal; + font-weight: bold; + font-size: 1em; +} + +.button_action_highlight{ +background-image: -moz-linear-gradient(center top , rgb(134, 212, 177), rgb(109, 173, 144)); +} + + +.button_form, .cancel_link { height: 32px; min-width: 99px; background-color: #86d4b1; diff --git a/mediagoblin/templates/mediagoblin/auth/change_fp.html b/mediagoblin/templates/mediagoblin/auth/change_fp.html index 53186cec..fa972085 100644 --- a/mediagoblin/templates/mediagoblin/auth/change_fp.html +++ b/mediagoblin/templates/mediagoblin/auth/change_fp.html @@ -30,7 +30,7 @@ {{ wtforms_util.render_divs(cp_form) }}
- +

diff --git a/mediagoblin/templates/mediagoblin/auth/forgot_password.html b/mediagoblin/templates/mediagoblin/auth/forgot_password.html index 9b821426..41940742 100644 --- a/mediagoblin/templates/mediagoblin/auth/forgot_password.html +++ b/mediagoblin/templates/mediagoblin/auth/forgot_password.html @@ -27,7 +27,7 @@

{% trans %}Recover password{% endtrans %}

{{ wtforms_util.render_divs(fp_form) }}
- +
diff --git a/mediagoblin/templates/mediagoblin/auth/login.html b/mediagoblin/templates/mediagoblin/auth/login.html index 756f67c0..c3807e5f 100644 --- a/mediagoblin/templates/mediagoblin/auth/login.html +++ b/mediagoblin/templates/mediagoblin/auth/login.html @@ -42,10 +42,10 @@ {% trans %}Forgot your password?{% endtrans %}

- +
{% if next %} - {% endif %}

diff --git a/mediagoblin/templates/mediagoblin/auth/register.html b/mediagoblin/templates/mediagoblin/auth/register.html index 25b68058..a0d0a277 100644 --- a/mediagoblin/templates/mediagoblin/auth/register.html +++ b/mediagoblin/templates/mediagoblin/auth/register.html @@ -29,7 +29,7 @@ {{ csrf_token }}
+ class="button_form" />
diff --git a/mediagoblin/templates/mediagoblin/base.html b/mediagoblin/templates/mediagoblin/base.html index 64fafb73..ede5f5c6 100644 --- a/mediagoblin/templates/mediagoblin/base.html +++ b/mediagoblin/templates/mediagoblin/base.html @@ -47,7 +47,7 @@ alt="{% trans %}MediaGoblin logo{% endtrans %}" /> {% endblock %} {% if request.user and request.user['status'] == 'active' %} - {% trans %}Submit media{% endtrans %} @@ -59,8 +59,8 @@ {% if request.user.status == "needs_email_verification" %} - {% trans %}verify your email!{% endtrans %} + class="button_action_highlight"> + {% trans %}Verify your email!{% endtrans %} {% endif %} Cancel - + {{ csrf_token }}
diff --git a/mediagoblin/templates/mediagoblin/edit/edit.html b/mediagoblin/templates/mediagoblin/edit/edit.html index b4b3be85..73c2bada 100644 --- a/mediagoblin/templates/mediagoblin/edit/edit.html +++ b/mediagoblin/templates/mediagoblin/edit/edit.html @@ -34,7 +34,7 @@ {{ wtforms_util.render_divs(form) }}
{% trans %}Cancel{% endtrans %} - + {{ csrf_token }}
diff --git a/mediagoblin/templates/mediagoblin/edit/edit_profile.html b/mediagoblin/templates/mediagoblin/edit/edit_profile.html index 93b2a792..bf8fe5c1 100644 --- a/mediagoblin/templates/mediagoblin/edit/edit_profile.html +++ b/mediagoblin/templates/mediagoblin/edit/edit_profile.html @@ -32,7 +32,7 @@ {{ wtforms_util.render_divs(form) }}
- + {{ csrf_token }}
diff --git a/mediagoblin/templates/mediagoblin/root.html b/mediagoblin/templates/mediagoblin/root.html index 43d973d1..25ce9e96 100644 --- a/mediagoblin/templates/mediagoblin/root.html +++ b/mediagoblin/templates/mediagoblin/root.html @@ -30,9 +30,9 @@ {% if allow_registration %}

{% trans %}Don't have one yet? It's easy!{% endtrans %}

{% trans register_url=request.urlgen('mediagoblin.auth.register') -%} - Create an account at this site + Create an account at this site or - Set up MediaGoblin on your own server + Set up MediaGoblin on your own server {%- endtrans %} {% endif %} diff --git a/mediagoblin/templates/mediagoblin/submit/start.html b/mediagoblin/templates/mediagoblin/submit/start.html index 29b01181..1a0dd4b7 100644 --- a/mediagoblin/templates/mediagoblin/submit/start.html +++ b/mediagoblin/templates/mediagoblin/submit/start.html @@ -27,7 +27,7 @@ {{ wtforms_util.render_divs(submit_form) }}
{{ csrf_token }} - +
diff --git a/mediagoblin/templates/mediagoblin/test_submit.html b/mediagoblin/templates/mediagoblin/test_submit.html index 190b9ac3..38be8efc 100644 --- a/mediagoblin/templates/mediagoblin/test_submit.html +++ b/mediagoblin/templates/mediagoblin/test_submit.html @@ -25,7 +25,7 @@ {{ wtforms_util.render_table(image_form) }} - + {{ csrf_token }} diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html index 4b02b684..c8a9650f 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media.html @@ -98,7 +98,7 @@ media=media._id) }}" method="POST"> {{ wtforms_util.render_divs(comment_form) }}
- + {{ csrf_token }}
diff --git a/mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html b/mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html index 8da90f79..c3a9d622 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html @@ -47,7 +47,7 @@
{# TODO: This isn't a button really... might do unexpected things :) #} {% trans %}Cancel{% endtrans %} - + {{ csrf_token }}
diff --git a/mediagoblin/templates/mediagoblin/user_pages/user.html b/mediagoblin/templates/mediagoblin/user_pages/user.html index d6a9fe1f..91dd2369 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/user.html +++ b/mediagoblin/templates/mediagoblin/user_pages/user.html @@ -62,7 +62,7 @@

{% trans %}In case it doesn't:{% endtrans %}

{% trans %}Resend verification email{% endtrans %} + class="button_form">{% trans %}Resend verification email{% endtrans %} {% else %} {# if the user is not you, but still needs to verify their email #} @@ -97,7 +97,7 @@

+ class="button_action"> {%- trans %}Edit profile{% endtrans -%} @@ -147,7 +147,7 @@ This is where your media will appear, but you don't seem to have added anything yet. {%- endtrans %}

- {%- trans %}Add media{% endtrans -%} From 5ab3855e1f8fd94058ccea76ef2d5a1d795cc93a Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Sun, 20 Nov 2011 01:46:21 +0100 Subject: [PATCH 083/302] Slight change to error wording --- mediagoblin/auth/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediagoblin/auth/views.py b/mediagoblin/auth/views.py index 8412b81c..54cb1ab5 100644 --- a/mediagoblin/auth/views.py +++ b/mediagoblin/auth/views.py @@ -74,7 +74,7 @@ def register(request): extra_validation_passes = False if users_with_email: register_form.email.errors.append( - _(u'Sorry, that email address has already been taken.')) + _(u'Sorry, a user with that email address already exists.')) extra_validation_passes = False if extra_validation_passes: From c6c08a2f296be16dbde4a5041bd6adc0d215d29d Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Sun, 20 Nov 2011 01:57:02 +0100 Subject: [PATCH 084/302] Small correction, this button should be button_action, not button_form --- mediagoblin/templates/mediagoblin/user_pages/user.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediagoblin/templates/mediagoblin/user_pages/user.html b/mediagoblin/templates/mediagoblin/user_pages/user.html index 91dd2369..5a39aaa5 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/user.html +++ b/mediagoblin/templates/mediagoblin/user_pages/user.html @@ -62,7 +62,7 @@

{% trans %}In case it doesn't:{% endtrans %}

{% trans %}Resend verification email{% endtrans %} + class="button_action_highlight">{% trans %}Resend verification email{% endtrans %} {% else %} {# if the user is not you, but still needs to verify their email #} From 88f20b58b29a4edbfbc24378a991d82de8e7b975 Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Sun, 20 Nov 2011 01:57:29 +0100 Subject: [PATCH 085/302] Slight style changes to button_action_highlight --- mediagoblin/static/css/base.css | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css index cec236f4..c26e11af 100644 --- a/mediagoblin/static/css/base.css +++ b/mediagoblin/static/css/base.css @@ -132,7 +132,9 @@ a.mediagoblin_logo{ } .button_action_highlight{ -background-image: -moz-linear-gradient(center top , rgb(134, 212, 177), rgb(109, 173, 144)); + background-color: #86D4B1; + border-color: #A2DEC3 #6CAA8E #5C9179; + color: #283F35; } From cee794a8f7ac82ee7681f749e56411c910e281a6 Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Sun, 20 Nov 2011 15:34:40 +0100 Subject: [PATCH 086/302] Fix for bug #467, "Add explanatory copy to add/edit picture pages saying that tags are comma-separated" --- mediagoblin/edit/forms.py | 4 +++- mediagoblin/submit/forms.py | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/mediagoblin/edit/forms.py b/mediagoblin/edit/forms.py index ec4e22b3..93934be7 100644 --- a/mediagoblin/edit/forms.py +++ b/mediagoblin/edit/forms.py @@ -26,7 +26,9 @@ class EditForm(wtforms.Form): description = wtforms.TextAreaField('Description of this work') tags = wtforms.TextField( _('Tags'), - [tag_length_validator]) + [tag_length_validator], + description=_( + "Seperate tags by commas or spaces.")) slug = wtforms.TextField( _('Slug'), [wtforms.validators.Required(message=_("The slug can't be empty"))], diff --git a/mediagoblin/submit/forms.py b/mediagoblin/submit/forms.py index 25d6e304..48a21f02 100644 --- a/mediagoblin/submit/forms.py +++ b/mediagoblin/submit/forms.py @@ -30,4 +30,6 @@ class SubmitStartForm(wtforms.Form): _('Description of this work')) tags = wtforms.TextField( _('Tags'), - [tag_length_validator]) + [tag_length_validator], + description=_( + "Seperate tags by commas or spaces.")) From 16a444444ab42f88f1654054050b7dcd64bf960e Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Sun, 20 Nov 2011 16:18:27 +0100 Subject: [PATCH 087/302] Change tag list from a list to a paragraph. Wrap text for translation. --- .../templates/mediagoblin/utils/tags.html | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/mediagoblin/templates/mediagoblin/utils/tags.html b/mediagoblin/templates/mediagoblin/utils/tags.html index b3211bd9..19ca8d2a 100644 --- a/mediagoblin/templates/mediagoblin/utils/tags.html +++ b/mediagoblin/templates/mediagoblin/utils/tags.html @@ -17,13 +17,20 @@ #} {% block tags_content -%} -

Tags

- +

{% endblock %} From 7807f5a513f2d5e510916e00dc276d0cd33de66a Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Sun, 20 Nov 2011 16:45:45 +0100 Subject: [PATCH 088/302] Remove Edit/Delete icons, since they are not required yet. --- mediagoblin/static/images/icon_delete.png | Bin 472 -> 0 bytes mediagoblin/static/images/icon_edit.png | Bin 297 -> 0 bytes .../templates/mediagoblin/user_pages/media.html | 11 ++--------- 3 files changed, 2 insertions(+), 9 deletions(-) delete mode 100644 mediagoblin/static/images/icon_delete.png delete mode 100644 mediagoblin/static/images/icon_edit.png diff --git a/mediagoblin/static/images/icon_delete.png b/mediagoblin/static/images/icon_delete.png deleted file mode 100644 index 9d76a5db0080cadb4f8bdf11da279efe1de5b604..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 472 zcmV;}0Vn>6P)Px#24YJ`L;xoMCjciBs;y-J000SaNLh0L01ejw01ejxLMWSf00007bV*G`2ipe$ z4-p<5JEV6200CG@L_t(I%dL|?s=`1J#((CS8(2=iENqe9E2Py57}S?n`34q-`SZ=pH#;MxROC&pwHRYC#sJ{G$9vCiw|fs| z^Z-bbgvDY(S(c<}N(h0bX#mh#BO+X{SE{OFzu$Aa-R=lVsi?J%&bioiU3AVxrPSbi zj?r32rBwWyOeWvU<&yb)&UU+Hy2$hx(6((~x$C;vb=|M( z&vxfrY}+;}rD9^OB~4SxvV5sl*Y%(d^gLN>85?5=A@t5H%ld@F;qa1}Wm&I>5HQA& z7-M?2p94b(hzKG=2;n6eplO;r03XWOdym$7aQ??=B0^o)FI{M@@!peo?-7wf!ty*P z&+|c_h~T~de2rs(s;XG6Ruo0?i>&tz6h*;wI%Tuj{LfeZ_?SkYp7RfY@htYek(Q7E O0000%tiFY)wsWxvhN$S14(QsrzcP-vy6i(`nz>8X=9 z^0q37F!&$l>-i8><(?qowxNv0eN#G1wE6(()78&qol`;+0Jqp}XaE2J diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html index c8a9650f..7ef64c76 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media.html @@ -116,24 +116,17 @@ {% if media['uploader'] == request.user._id or request.user['is_admin'] %} -

{% trans %}Actions{% endtrans %}

{% set edit_url = request.urlgen('mediagoblin.edit.edit_media', user= media.uploader().username, media= media._id) %} - - {% trans %}edit{% endtrans %} + {% trans %}Edit{% endtrans %}

{% set delete_url = request.urlgen('mediagoblin.user_pages.media_confirm_delete', user= media.uploader().username, media= media._id) %} - - {% trans %}delete{% endtrans %} + {% trans %}Delete{% endtrans %}

{% endif %} From 0b3cdd6a25f8aaa74beecb7fed32a20cc13587a8 Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Sun, 20 Nov 2011 17:01:23 +0100 Subject: [PATCH 089/302] Navigation buttons edits. Removed images as they are no longer needed. Related: bug #504 --- mediagoblin/static/css/base.css | 8 ++------ mediagoblin/static/images/navigation_end.png | Bin 718 -> 0 bytes mediagoblin/static/images/navigation_left.png | Bin 406 -> 0 bytes mediagoblin/static/images/navigation_right.png | Bin 383 -> 0 bytes .../templates/mediagoblin/utils/prev_next.html | 8 ++++---- 5 files changed, 6 insertions(+), 10 deletions(-) delete mode 100644 mediagoblin/static/images/navigation_end.png delete mode 100644 mediagoblin/static/images/navigation_left.png delete mode 100644 mediagoblin/static/images/navigation_right.png diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css index c26e11af..12d88ffa 100644 --- a/mediagoblin/static/css/base.css +++ b/mediagoblin/static/css/base.css @@ -300,15 +300,11 @@ img.media_icon{ border-color: #2c2c2c #232323 #1a1a1a; border-radius: 4px; text-decoration: none; - padding: 8px 0px 14px; - font-size: 2em; + padding: 12px 0 16px; + font-size: 1.4em; margin: 0 0 20px } -p.navigation_button{ - color: #272727; -} - .navigation_left{ margin-right: 6px; } diff --git a/mediagoblin/static/images/navigation_end.png b/mediagoblin/static/images/navigation_end.png deleted file mode 100644 index b2f2729698bf8443ce687ab4a6a872726735cc19..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 718 zcmV;<0x|uGP)FN`H1O zGH5A6C_;f`MhjtFI9koZg(x`MCTgMJLI_*A5QG#Xgo(6`(Ss6#CE~PdF}wr1w_3aE>Z@J4ZMz>1RO?6Ly*LxY(PX0WZ2--9y^bLKJC#gCY4Tqkcv#Cs*T zt8uJFe>5{6bTjh_4zvhiCL+d)@if*n=>EV7=nP+8L|nxCE%3eg88U43v>aWmJ{8IU>bk7z?)(=Gk%!_I0y#%6|tZsGPrY;F*r%FH<^ zjR diff --git a/mediagoblin/static/images/navigation_left.png b/mediagoblin/static/images/navigation_left.png deleted file mode 100644 index d1645120322caaa60c8173e8c7dbcc7fc2575397..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 406 zcmeAS@N?(olHy`uVBq!ia0vp^YCtT_!3HD+ZvMRsq*#ibJVQ8upoSx*1IXtr@Q5r1 zs=p4xj7}P}D}aKMC9V-A!TD(=<%vb94CUqJdYO6I#mR{Use1WE>9gP2NHH)l3VXUZ zhD5Z!y|z2+Pyj>wM}N(rBRlyYYIRKCDPAHzUGLVy{0A!**S0+~s$4VM_Y`&$HkIw&br^mF2APpwHij;&h9SRZ=GM>}y@EZ1sAXXyzk=IQUQvn)GM zyrCw&T{x8~n?d;j>x*O8*01eq`g9=bfVRQ0|GCR%1aGvt=B%^ x+IqF2`oUp7^;ba=iGOd)A3dZ6bhz#t@wbP>H(mHWF9R5c44$rjF6*2UngBDsrLq73 diff --git a/mediagoblin/static/images/navigation_right.png b/mediagoblin/static/images/navigation_right.png deleted file mode 100644 index d4caa7b8ba1fa404cefa63a7d216f346a64960f5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 383 zcmeAS@N?(olHy`uVBq!ia0vp^YCtT_!3HD+ZvMRsq*#ibJVQ8upoSx*1IXtr@Q5r1 zs=p4xj7}P}D}aKMC9V-A!TD(=<%vb94CUqJdYO6I#mR{Use1WE>9gP2NC6f7@pN$v ziD-R$Wv|x}2a&di>fIZf%x-a23troHuYK);>kIcLJmT~v-c~ax*lA*l!4%7XMomZC%ulDBJ$kgpSdx_BQgN9+t|GG`o zI6luH_-(tzifb>{^9FU^O@4QHv-q4u{^edjDa!S?S9mU}Ut^eia-)AqQt8Vh auRd|D{C?4*OEDZ2ybPYMelF{r5}E+h>7 - Previous image + ← newer {% else %} {# This is the first entry. display greyed-out 'previous' image #} {% endif %} {# Likewise, this could be the very last media entry #} {% if next_entry_url %} - Next image + older → {% else %} {# This is the last entry. display greyed-out 'next' image #} {% endif %} From 5dbeda8a0f2953aed13521b6e87376327e8302e0 Mon Sep 17 00:00:00 2001 From: Elrond Date: Sun, 20 Nov 2011 20:15:21 +0100 Subject: [PATCH 090/302] Fix redirect to logical path redirects should in nearly all cases go to a logical path like 'mediagoblin.auth.login' and not to an absolute path like "/auth/login". --- mediagoblin/auth/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediagoblin/auth/views.py b/mediagoblin/auth/views.py index b3a70d46..d01861d1 100644 --- a/mediagoblin/auth/views.py +++ b/mediagoblin/auth/views.py @@ -202,7 +202,7 @@ def resend_activation(request): messages.ERROR, _('You must be logged in so we know who to send the email to!')) - return redirect(request, "/auth/login") + return redirect(request, 'mediagoblin.auth.login') if request.user["email_verified"]: messages.add_message( From 9404a9fed23bfe27144da4f8e692df1f692a25b5 Mon Sep 17 00:00:00 2001 From: Jakob Kramer Date: Sun, 20 Nov 2011 21:15:07 +0100 Subject: [PATCH 091/302] don't use 'and' anymore, if there is only one tag --- mediagoblin/templates/mediagoblin/utils/tags.html | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mediagoblin/templates/mediagoblin/utils/tags.html b/mediagoblin/templates/mediagoblin/utils/tags.html index 19ca8d2a..20c50f6e 100644 --- a/mediagoblin/templates/mediagoblin/utils/tags.html +++ b/mediagoblin/templates/mediagoblin/utils/tags.html @@ -20,7 +20,10 @@

{% trans %}Tagged with{% endtrans %} {% for tag in media.tags %} {% if loop.last %} - {% trans %}and{% endtrans %} {{ tag['name'] }}. {% elif loop.revindex==2 %} From a00f1c1e1cecb8f127b6a064e2cd90c8f613660d Mon Sep 17 00:00:00 2001 From: Jakob Kramer Date: Sun, 20 Nov 2011 21:30:46 +0100 Subject: [PATCH 092/302] eyecandy for programmers --- .../templates/mediagoblin/utils/tags.html | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/mediagoblin/templates/mediagoblin/utils/tags.html b/mediagoblin/templates/mediagoblin/utils/tags.html index 20c50f6e..49bc3cee 100644 --- a/mediagoblin/templates/mediagoblin/utils/tags.html +++ b/mediagoblin/templates/mediagoblin/utils/tags.html @@ -20,19 +20,21 @@

{% trans %}Tagged with{% endtrans %} {% for tag in media.tags %} {% if loop.last %} + {# the 'and' should only appear if there is more than one tag #} {% if media.tags|length > 1 %} - {% trans %}and{% endtrans %} + {% trans %}and{% endtrans %} {% endif %} - {{ tag['name'] }}. - {% elif loop.revindex==2 %} - {{ tag['name'] }} - {% else %}{{ tag['name'] }}, + + {{ tag['name'] }}. + {% elif loop.revindex==2 %} + {{ tag['name'] }} + {% else %}{{ tag['name'] }}, {% endif %} {% endfor %}

From fe0a8f53e251aae93bee5f4dee79d462fad751e8 Mon Sep 17 00:00:00 2001 From: Jakob Kramer Date: Sun, 20 Nov 2011 21:40:51 +0100 Subject: [PATCH 093/302] fixed identation --- mediagoblin/templates/mediagoblin/utils/tags.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mediagoblin/templates/mediagoblin/utils/tags.html b/mediagoblin/templates/mediagoblin/utils/tags.html index 49bc3cee..c7dfc8eb 100644 --- a/mediagoblin/templates/mediagoblin/utils/tags.html +++ b/mediagoblin/templates/mediagoblin/utils/tags.html @@ -24,15 +24,15 @@ {% if media.tags|length > 1 %} {% trans %}and{% endtrans %} {% endif %} - {{ tag['name'] }}. - {% elif loop.revindex==2 %} + {% elif loop.revindex == 2 %} {{ tag['name'] }} - {% else %}{{ tag['name'] }}, {% endif %} From a63b640f12896a873ebf96f9fe0ef62d0794bfe7 Mon Sep 17 00:00:00 2001 From: Joar Wandborg Date: Mon, 21 Nov 2011 00:06:59 +0100 Subject: [PATCH 094/302] Stashing changes --- mediagoblin/init/celery/__init__.py | 3 -- mediagoblin/media_types/__init__.py | 26 +++++----- mediagoblin/media_types/video/processing.py | 49 +++---------------- mediagoblin/media_types/video/transcoders.py | 1 - mediagoblin/process_media/__init__.py | 3 ++ mediagoblin/templates/mediagoblin/base.html | 7 +++ .../mediagoblin/media_displays/video.html | 18 ++++--- setup.py | 1 - 8 files changed, 43 insertions(+), 65 deletions(-) diff --git a/mediagoblin/init/celery/__init__.py b/mediagoblin/init/celery/__init__.py index 05c54b05..c5d37420 100644 --- a/mediagoblin/init/celery/__init__.py +++ b/mediagoblin/init/celery/__init__.py @@ -17,11 +17,8 @@ import os import sys -from mediagoblin.media_types import get_media_types - MANDATORY_CELERY_IMPORTS = ['mediagoblin.process_media'] -MANDATORY_CELERY_IMPORTS = [i for i in get_media_types()] print(MANDATORY_CELERY_IMPORTS) diff --git a/mediagoblin/media_types/__init__.py b/mediagoblin/media_types/__init__.py index 49d3ab9d..2d13f5a6 100644 --- a/mediagoblin/media_types/__init__.py +++ b/mediagoblin/media_types/__init__.py @@ -26,31 +26,33 @@ class FileTypeNotSupported(Exception): class InvalidFileType(Exception): pass +# This should be more dynamic in the future. Perhaps put it in the .ini? +# -- Joar MEDIA_TYPES = [ 'mediagoblin.media_types.image', 'mediagoblin.media_types.video'] def get_media_types(): + ''' + Generator that returns the available media types + ''' for media_type in MEDIA_TYPES: yield media_type def get_media_managers(): + ''' + Generator that returns all available media managers + ''' for media_type in get_media_types(): - ''' - FIXME - __import__ returns the lowest-level module. If the plugin is located - outside the conventional plugin module tree, it will not be loaded - properly because of the [...]ugin.media_types. - - We need this if we want to support a separate site-specific plugin - folder. - ''' try: __import__(media_type) except ImportError as e: - raise Exception('ERROR: Could not import {0}: {1}'.format(media_type, e)) + raise Exception( + _('ERROR: Could not import {media_type}: {exception}').format( + media_type=media_type, + exception=e)) yield media_type, sys.modules[media_type].MEDIA_MANAGER @@ -67,8 +69,8 @@ def get_media_type_and_manager(filename): ext = os.path.splitext(filename)[1].lower() else: raise InvalidFileType( - 'Could not find any file extension in "{0}"'.format( - filename)) + _('Could not find any file extension in "{filename}"').format( + filename=filename)) if ext[1:] in manager['accepted_extensions']: return media_type, manager diff --git a/mediagoblin/media_types/video/processing.py b/mediagoblin/media_types/video/processing.py index 027f527b..4e05a71c 100644 --- a/mediagoblin/media_types/video/processing.py +++ b/mediagoblin/media_types/video/processing.py @@ -15,25 +15,21 @@ # along with this program. If not, see . import tempfile -import pkg_resources -import os import logging +import os from celery.task import Task from celery import registry from mediagoblin.db.util import ObjectId from mediagoblin import mg_globals as mgg -from mediagoblin.util import lazy_pass_to_ugettext as _ -from mediagoblin.process_media.errors import BaseProcessingFail, BadMediaFail +from mediagoblin.process_media import BaseProcessingFail from mediagoblin.process_media import mark_entry_failed from . import transcoders THUMB_SIZE = 180, 180 MEDIUM_SIZE = 640, 640 -loop = None # Is this even used? - logger = logging.getLogger(__name__) logging.basicConfig() logger.setLevel(logging.DEBUG) @@ -59,7 +55,11 @@ def process_video(entry): 'source') medium_filepath = create_pub_filepath( - entry, '640p.webm') + entry, + '{original}-640p.webm'.format( + original=os.path.splitext( + queued_filepath[-1])[0] # Select the + )) thumbnail_filepath = create_pub_filepath( entry, 'thumbnail.jpg') @@ -163,38 +163,3 @@ class ProcessMedia(Task): 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': {}}}) diff --git a/mediagoblin/media_types/video/transcoders.py b/mediagoblin/media_types/video/transcoders.py index f6a2eb21..8d80beda 100644 --- a/mediagoblin/media_types/video/transcoders.py +++ b/mediagoblin/media_types/video/transcoders.py @@ -56,7 +56,6 @@ try: import pygst pygst.require('0.10') import gst - from gst import pbutils from gst.extend import discoverer except: raise Exception('gst/pygst 0.10 could not be found') diff --git a/mediagoblin/process_media/__init__.py b/mediagoblin/process_media/__init__.py index 2b9eed6e..96fe49fe 100644 --- a/mediagoblin/process_media/__init__.py +++ b/mediagoblin/process_media/__init__.py @@ -53,10 +53,13 @@ class ProcessMedia(Task): # Try to process, and handle expected errors. try: + __import__(entry['media_type']) process_image(entry) except BaseProcessingFail, exc: mark_entry_failed(entry[u'_id'], exc) return + except ImportError, exc: + mark_entry_failed(entry[u'_id'], exc) entry['state'] = u'processed' entry.save() diff --git a/mediagoblin/templates/mediagoblin/base.html b/mediagoblin/templates/mediagoblin/base.html index b4c4dcf3..bad22e7e 100644 --- a/mediagoblin/templates/mediagoblin/base.html +++ b/mediagoblin/templates/mediagoblin/base.html @@ -28,8 +28,15 @@ href="{{ request.staticdirect('/css/extlib/960_16_col.css') }}"/> + + + + {% block mediagoblin_head %} {% endblock mediagoblin_head %} diff --git a/mediagoblin/templates/mediagoblin/media_displays/video.html b/mediagoblin/templates/mediagoblin/media_displays/video.html index bff9889a..5b8ec789 100644 --- a/mediagoblin/templates/mediagoblin/media_displays/video.html +++ b/mediagoblin/templates/mediagoblin/media_displays/video.html @@ -1,11 +1,17 @@ {% extends 'mediagoblin/user_pages/media.html' %} {% block mediagoblin_media %} - +
+ +
{% if 'original' in media.media_files %}

1: + directory = self._resolve_filepath(filepath[:-1]) + if not os.path.exists(directory): + os.makedirs(directory) + + shutil.copy( + filename, self.get_local_path(filepath)) From 2e8fbc8fab47930f1de7e20e0072eaefafc898a6 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Sun, 20 Nov 2011 22:02:02 -0600 Subject: [PATCH 096/302] Slightly clearer docs on copy_local_to_storage --- mediagoblin/storage/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mediagoblin/storage/__init__.py b/mediagoblin/storage/__init__.py index b76e18af..0840614b 100644 --- a/mediagoblin/storage/__init__.py +++ b/mediagoblin/storage/__init__.py @@ -172,6 +172,10 @@ class StorageInterface(object): def copy_local_to_storage(self, filename, filepath): """ Copy this file from locally to the storage system. + + This is kind of the opposite of copy_locally. It's likely you + could override this method with something more appropriate to + your storage system. """ with self.get_file(filepath, 'wb') as dest_file: with file(filename, 'rb') as source_file: From 61c5306d247a4403032e4e37bbdf32db1e6d8aa8 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Sun, 20 Nov 2011 22:03:38 -0600 Subject: [PATCH 097/302] Made the image processing use intermediary conversion file. This should fix the problem with PIL and the cloudfiles storage system fighting. --- mediagoblin/process_media/__init__.py | 30 ++++++++++++++++++++------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/mediagoblin/process_media/__init__.py b/mediagoblin/process_media/__init__.py index 34d83e54..54c0c493 100644 --- a/mediagoblin/process_media/__init__.py +++ b/mediagoblin/process_media/__init__.py @@ -118,6 +118,10 @@ def process_image(entry): Code to process an image """ workbench = mgg.workbench_manager.create_workbench() + # Conversions subdirectory to avoid collisions + conversions_subdir = os.path.join( + workbench.dir, 'conversions') + os.mkdir(conversions_subdir) queued_filepath = entry['queued_media_file'] queued_filename = workbench.localized_file( @@ -133,11 +137,15 @@ def process_image(entry): thumb.thumbnail(THUMB_SIZE, Image.ANTIALIAS) - thumb_filepath = create_pub_filepath(entry, 'thumbnail' + extension) - thumb_file = mgg.public_store.get_file(thumb_filepath, 'w') - - with thumb_file: + # Copy the thumb to the conversion subdir, then remotely. + thumb_filename = 'thumbnail' + extension + thumb_filepath = create_pub_filepath(entry, thumb_filename) + tmp_thumb_filename = os.path.join( + conversions_subdir, thumb_filename) + with file(tmp_thumb_filename, 'w') as thumb_file: thumb.save(thumb_file) + mgg.public_store.copy_local_to_storage( + tmp_thumb_filename, thumb_filepath) # 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 @@ -148,12 +156,18 @@ def process_image(entry): if medium.size[0] > MEDIUM_SIZE[0] or medium.size[1] > MEDIUM_SIZE[1]: medium.thumbnail(MEDIUM_SIZE, Image.ANTIALIAS) - medium_filepath = create_pub_filepath(entry, 'medium' + extension) - medium_file = mgg.public_store.get_file(medium_filepath, 'w') + medium_filename = 'medium' + extension + medium_filepath = create_pub_filepath(entry, medium_filename) + tmp_medium_filename = os.path.join( + conversions_subdir, medium_filename) - with medium_file: + with file(tmp_medium_filename, 'w') as medium_file: medium.save(medium_file) - medium_processed = True + + mgg.public_store.copy_local_to_storage( + tmp_medium_filename, medium_filepath) + + medium_processed = True # we have to re-read because unlike PIL, not everything reads # things in string representation :) From e56e5f8c5c3dc7909aa68a1543ed04ddb18e27f6 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Sun, 20 Nov 2011 22:25:22 -0600 Subject: [PATCH 098/302] Tests for StorageInterface*.copy_local_to_storage() --- mediagoblin/tests/test_storage.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/mediagoblin/tests/test_storage.py b/mediagoblin/tests/test_storage.py index 46ecb2ec..eab4d032 100644 --- a/mediagoblin/tests/test_storage.py +++ b/mediagoblin/tests/test_storage.py @@ -57,6 +57,10 @@ class FakeRemoteStorage(storage.filestorage.BasicFileStorage): # should force copying to the workbench local_storage = False + def copy_local_to_storage(self, *args, **kwargs): + return storage.StorageInterface.copy_local_to_storage( + self, *args, **kwargs) + def test_storage_system_from_config(): this_storage = storage.storage_system_from_config( @@ -252,3 +256,26 @@ def test_basic_storage_copy_locally(): this_storage.copy_locally(filepath, new_file_dest) assert file(new_file_dest).read() == 'Testing this file' + + +def _test_copy_local_to_storage_works(tmpdir, this_storage): + local_filename = tempfile.mktemp() + with file(local_filename, 'w') as tmpfile: + tmpfile.write('haha') + + this_storage.copy_local_to_storage( + local_filename, ['dir1', 'dir2', 'copiedto.txt']) + + assert file( + os.path.join(tmpdir, 'dir1/dir2/copiedto.txt'), + 'r').read() == 'haha' + + +def test_basic_storage_copy_local_to_storage(): + tmpdir, this_storage = get_tmp_filestorage() + _test_copy_local_to_storage_works(tmpdir, this_storage) + + +def test_general_storage_copy_local_to_storage(): + tmpdir, this_storage = get_tmp_filestorage(fake_remote=True) + _test_copy_local_to_storage_works(tmpdir, this_storage) From c875bb74a8245b39b6985f37cb8ab838c22efa7e Mon Sep 17 00:00:00 2001 From: Joar Wandborg Date: Mon, 21 Nov 2011 21:47:00 +0100 Subject: [PATCH 099/302] Refractored GStreamer element linking --- mediagoblin/media_types/video/transcoders.py | 41 ++++++++++---------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/mediagoblin/media_types/video/transcoders.py b/mediagoblin/media_types/video/transcoders.py index 8d80beda..8b220891 100644 --- a/mediagoblin/media_types/video/transcoders.py +++ b/mediagoblin/media_types/video/transcoders.py @@ -17,7 +17,6 @@ from __future__ import division import os -os.environ["GST_DEBUG_DUMP_DOT_DIR"] = "/tmp" os.putenv('GST_DEBUG_DUMP_DOT_DIR', '/tmp') import sys @@ -498,28 +497,30 @@ class VideoTranscoder: # or audio sink self.filesrc.link(self.decoder) - # Link all the video elements in a link to webmux - self.videoqueue.link(self.videorate) - self.videorate.link(self.ffmpegcolorspace) - self.ffmpegcolorspace.link(self.videoscale) - self.videoscale.link(self.capsfilter) - #self.capsfilter.link(self.xvimagesink) - self.capsfilter.link(self.vp8enc) - self.vp8enc.link(self.webmmux) + # Link all the video elements in a row to webmmux + gst.element_link_many( + self.videoqueue, + self.videorate, + self.ffmpegcolorspace, + self.videoscale, + self.capsfilter, + self.vp8enc, + self.webmmux) if self.data.is_audio: - # Link all the audio elements in a line to webmux - #self.audioconvert.link(self.alsasink) - self.audioqueue.link(self.audiorate) - self.audiorate.link(self.audioconvert) - self.audioconvert.link(self.audiocapsfilter) - self.audiocapsfilter.link(self.vorbisenc) - #self.audiocapsfilter.link(self.level) - #self.level.link(self.vorbisenc) - self.vorbisenc.link(self.webmmux) + # Link all the audio elements in a row to webmux + gst.element_link_many( + self.audioqueue, + self.audiorate, + self.audioconvert, + self.audiocapsfilter, + self.vorbisenc, + self.webmmux) - self.webmmux.link(self.progressreport) - self.progressreport.link(self.filesink) + gst.element_link_many( + self.webmmux, + self.progressreport, + self.filesink) # Setup the message bus and connect _on_message to the pipeline self._setup_bus() From 58dd8d9e6326013528cdfdfeea375c4eade54b92 Mon Sep 17 00:00:00 2001 From: "Pablo J. Urbano Santos" Date: Mon, 21 Nov 2011 22:42:55 +0100 Subject: [PATCH 100/302] Filename extensions are lowercased before uploading the image. --- mediagoblin/process_media/__init__.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/mediagoblin/process_media/__init__.py b/mediagoblin/process_media/__init__.py index 54c0c493..dcf21b81 100644 --- a/mediagoblin/process_media/__init__.py +++ b/mediagoblin/process_media/__init__.py @@ -128,7 +128,9 @@ def process_image(entry): mgg.queue_store, queued_filepath, 'source') - extension = os.path.splitext(queued_filename)[1] + filename_bits = os.path.splitext(queued_filename) + basename = os.path.split(filename_bits[0])[1] + extension = filename_bits[1].lower() try: thumb = Image.open(queued_filename) @@ -174,7 +176,8 @@ def process_image(entry): queued_file = file(queued_filename, 'rb') with queued_file: - original_filepath = create_pub_filepath(entry, queued_filepath[-1]) + #create_pub_filepath(entry, queued_filepath[-1]) + original_filepath = create_pub_filepath(entry, basename + extension) with mgg.public_store.get_file(original_filepath, 'wb') \ as original_file: From 8e5f974684ce4e329a5022459f2e536fa4e15edd Mon Sep 17 00:00:00 2001 From: Joar Wandborg Date: Mon, 21 Nov 2011 23:18:40 +0100 Subject: [PATCH 101/302] Fixes after merging video branch into master - Removed debug output from init/celery - Moved process_media/__init__ to processing.py - Centralized the processing.ProcessMedia task class - Updated media managers to reference the processing function instead of the ProcessMedia instance - Updated new-style image processing to previous, newer old-style image processing - Updated video transcoding - Changed method in progress output, sometimes message.structure['percent'] raises KeyError --- mediagoblin/init/celery/__init__.py | 4 +- mediagoblin/media_types/image/__init__.py | 8 +- mediagoblin/media_types/image/processing.py | 95 +++++---------- mediagoblin/media_types/video/__init__.py | 7 +- mediagoblin/media_types/video/processing.py | 69 ++--------- mediagoblin/media_types/video/transcoders.py | 17 +-- mediagoblin/process_media/errors.py | 45 ------- .../__init__.py => processing.py} | 110 +++++------------- mediagoblin/submit/views.py | 7 +- 9 files changed, 86 insertions(+), 276 deletions(-) delete mode 100644 mediagoblin/process_media/errors.py rename mediagoblin/{process_media/__init__.py => processing.py} (56%) diff --git a/mediagoblin/init/celery/__init__.py b/mediagoblin/init/celery/__init__.py index a62d40e3..1eb21d7a 100644 --- a/mediagoblin/init/celery/__init__.py +++ b/mediagoblin/init/celery/__init__.py @@ -18,9 +18,7 @@ import os import sys -MANDATORY_CELERY_IMPORTS = ['mediagoblin.process_media'] - -print(MANDATORY_CELERY_IMPORTS) +MANDATORY_CELERY_IMPORTS = ['mediagoblin.processing'] DEFAULT_SETTINGS_MODULE = 'mediagoblin.init.celery.dummy_settings_module' diff --git a/mediagoblin/media_types/image/__init__.py b/mediagoblin/media_types/image/__init__.py index 0cd0383f..3b63d8eb 100644 --- a/mediagoblin/media_types/image/__init__.py +++ b/mediagoblin/media_types/image/__init__.py @@ -14,15 +14,13 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -from mediagoblin.media_types.image.processing import process_media +from mediagoblin.media_types.image.processing import process_image MEDIA_MANAGER = { "human_readable": "Image", - "processor": process_media, # alternately a string, + "processor": process_image, # alternately a string, # 'mediagoblin.media_types.image.processing'? "display_template": "mediagoblin/media_displays/image.html", "default_thumb": "images/media_thumbs/image.jpg", - "accepted_extensions": ["jpg", "jpeg", "png", "gif", "tiff"], - "accepted_mimetypes": [ - "image/jpeg", "image/png", "image/gif", "image/tiff"]} + "accepted_extensions": ["jpg", "jpeg", "png", "gif", "tiff"]} diff --git a/mediagoblin/media_types/image/processing.py b/mediagoblin/media_types/image/processing.py index 57eb75db..5e8e4e0a 100644 --- a/mediagoblin/media_types/image/processing.py +++ b/mediagoblin/media_types/image/processing.py @@ -15,6 +15,7 @@ # along with this program. If not, see . import Image +import os from celery.task import Task from celery import registry @@ -22,19 +23,9 @@ from celery import registry from mediagoblin.db.util import ObjectId from mediagoblin import mg_globals as mgg -from mediagoblin.util import lazy_pass_to_ugettext as _ - -from mediagoblin.process_media.errors import * - -THUMB_SIZE = 180, 180 -MEDIUM_SIZE = 640, 640 - - -def create_pub_filepath(entry, filename): - return mgg.public_store.get_unique_filepath( - ['media_entries', - unicode(entry['_id']), - filename]) +from mediagoblin.processing import BaseProcessingFail, \ + mark_entry_failed, BadMediaFail, create_pub_filepath, THUMB_SIZE, \ + MEDIUM_SIZE ################################ # Media processing initial steps @@ -77,67 +68,39 @@ class ProcessMedia(Task): 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() + # Conversions subdirectory to avoid collisions + conversions_subdir = os.path.join( + workbench.dir, 'conversions') + os.mkdir(conversions_subdir) queued_filepath = entry['queued_media_file'] queued_filename = workbench.localized_file( mgg.queue_store, queued_filepath, 'source') + extension = os.path.splitext(queued_filename)[1] + 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": - thumb = thumb.convert("RGB") - thumb_filepath = create_pub_filepath(entry, 'thumbnail.jpg') - thumb_file = mgg.public_store.get_file(thumb_filepath, 'w') - - with thumb_file: - thumb.save(thumb_file, "JPEG", quality=90) + # Copy the thumb to the conversion subdir, then remotely. + thumb_filename = 'thumbnail' + extension + thumb_filepath = create_pub_filepath(entry, thumb_filename) + tmp_thumb_filename = os.path.join( + conversions_subdir, thumb_filename) + with file(tmp_thumb_filename, 'w') as thumb_file: + thumb.save(thumb_file) + mgg.public_store.copy_local_to_storage( + tmp_thumb_filename, thumb_filepath) # 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 @@ -148,15 +111,18 @@ def process_image(entry): if medium.size[0] > MEDIUM_SIZE[0] or medium.size[1] > MEDIUM_SIZE[1]: medium.thumbnail(MEDIUM_SIZE, Image.ANTIALIAS) - if medium.mode != "RGB": - medium = medium.convert("RGB") + medium_filename = 'medium' + extension + medium_filepath = create_pub_filepath(entry, medium_filename) + tmp_medium_filename = os.path.join( + conversions_subdir, medium_filename) - medium_filepath = create_pub_filepath(entry, 'medium.jpg') - medium_file = mgg.public_store.get_file(medium_filepath, 'w') + with file(tmp_medium_filename, 'w') as medium_file: + medium.save(medium_file) - with medium_file: - medium.save(medium_file, "JPEG", quality=90) - medium_processed = True + mgg.public_store.copy_local_to_storage( + tmp_medium_filename, medium_filepath) + + medium_processed = True # we have to re-read because unlike PIL, not everything reads # things in string representation :) @@ -165,7 +131,8 @@ def process_image(entry): with queued_file: original_filepath = create_pub_filepath(entry, queued_filepath[-1]) - with mgg.public_store.get_file(original_filepath, 'wb') as original_file: + with mgg.public_store.get_file(original_filepath, 'wb') \ + as original_file: original_file.write(queued_file.read()) mgg.queue_store.delete_file(queued_filepath) diff --git a/mediagoblin/media_types/video/__init__.py b/mediagoblin/media_types/video/__init__.py index c1910ee2..a970ab01 100644 --- a/mediagoblin/media_types/video/__init__.py +++ b/mediagoblin/media_types/video/__init__.py @@ -14,13 +14,14 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -from mediagoblin.media_types.video.processing import process_media +from mediagoblin.media_types.video.processing import process_video MEDIA_MANAGER = { "human_readable": "Video", - "processor": process_media, # alternately a string, + "processor": process_video, # alternately a string, # 'mediagoblin.media_types.image.processing'? "display_template": "mediagoblin/media_displays/video.html", "default_thumb": "images/media_thumbs/video.jpg", - "accepted_extensions": ["mp4", "mov", "webm", "avi", "3gp", "3gpp", "mkv", "ogv", "ogg"]} + "accepted_extensions": [ + "mp4", "mov", "webm", "avi", "3gp", "3gpp", "mkv", "ogv", "ogg"]} diff --git a/mediagoblin/media_types/video/processing.py b/mediagoblin/media_types/video/processing.py index 4e05a71c..6125e49c 100644 --- a/mediagoblin/media_types/video/processing.py +++ b/mediagoblin/media_types/video/processing.py @@ -18,21 +18,15 @@ import tempfile import logging import os -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 import BaseProcessingFail -from mediagoblin.process_media import mark_entry_failed +from mediagoblin.processing import mark_entry_failed, \ + THUMB_SIZE, MEDIUM_SIZE, create_pub_filepath from . import transcoders -THUMB_SIZE = 180, 180 -MEDIUM_SIZE = 640, 640 - -logger = logging.getLogger(__name__) logging.basicConfig() -logger.setLevel(logging.DEBUG) + +_log = logging.getLogger(__name__) +_log.setLevel(logging.DEBUG) def process_video(entry): @@ -73,8 +67,10 @@ def process_video(entry): transcoder = transcoders.VideoTranscoder(queued_filename, tmp_dst.name) # Push transcoded video to public storage + _log.debug('Saving medium...') mgg.public_store.get_file(medium_filepath, 'wb').write( tmp_dst.read()) + _log.debug('Saved medium') entry['media_files']['webm_640'] = medium_filepath @@ -91,8 +87,10 @@ def process_video(entry): transcoders.VideoThumbnailer(queued_filename, tmp_thumb.name) # Push the thumbnail to public storage + _log.debug('Saving thumbnail...') mgg.public_store.get_file(thumbnail_filepath, 'wb').write( tmp_thumb.read()) + _log.debug('Saved thumbnail') entry['media_files']['thumb'] = thumbnail_filepath @@ -107,7 +105,9 @@ def process_video(entry): with mgg.public_store.get_file(original_filepath, 'wb') as \ original_file: + _log.debug('Saving original...') original_file.write(queued_file.read()) + _log.debug('Saved original') entry['media_files']['original'] = original_filepath @@ -116,50 +116,3 @@ def process_video(entry): # Save the MediaEntry entry.save() - -def create_pub_filepath(entry, filename): - return mgg.public_store.get_unique_filepath( - ['media_entries', - unicode(entry['_id']), - filename]) - - -################################ -# 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_video(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] diff --git a/mediagoblin/media_types/video/transcoders.py b/mediagoblin/media_types/video/transcoders.py index 8b220891..493a837f 100644 --- a/mediagoblin/media_types/video/transcoders.py +++ b/mediagoblin/media_types/video/transcoders.py @@ -195,7 +195,6 @@ class VideoThumbnailer: _log.debug('seek amount: {0}'.format(seek_amount)) - seek_result = self.thumbnail_pipeline.seek( 1.0, gst.FORMAT_TIME, @@ -204,14 +203,6 @@ class VideoThumbnailer: seek_amount, gst.SEEK_TYPE_NONE, 0) - ''' - - seek_result = self.thumbnail_pipeline.seek_simple( - gst.FORMAT_TIME, - gst.SEEK_FLAG_FLUSH | gst.SEEK_FLAG_ACCURATE, - seek_amount) - - ''' if not seek_result: self.errors.append('COULD_NOT_SEEK') @@ -576,17 +567,13 @@ class VideoTranscoder: elif t == gst.MESSAGE_ELEMENT: if message.structure.get_name() == 'progress': - data = { - 'structure': message.structure, - 'percent': message.structure['percent'], - 'total': message.structure['total'], - 'current': message.structure['current']} + data = dict(message.structure) if self._progress_callback: self._progress_callback(data) _log.info('{percent}% done...'.format( - percent=data['percent'])) + percent=data.get('percent'))) _log.debug(data) elif t == gst.MESSAGE_ERROR: diff --git a/mediagoblin/process_media/errors.py b/mediagoblin/process_media/errors.py deleted file mode 100644 index 4224a3e1..00000000 --- a/mediagoblin/process_media/errors.py +++ /dev/null @@ -1,45 +0,0 @@ -# GNU MediaGoblin -- federated, autonomous media hosting -# Copyright (C) 2011 MediaGoblin contributors. See AUTHORS. -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -from mediagoblin.tools.translate 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/process_media/__init__.py b/mediagoblin/processing.py similarity index 56% rename from mediagoblin/process_media/__init__.py rename to mediagoblin/processing.py index 346bb479..8738cbe2 100644 --- a/mediagoblin/process_media/__init__.py +++ b/mediagoblin/processing.py @@ -14,15 +14,14 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -import os - -import Image 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 + +from mediagoblin.util import lazy_pass_to_ugettext as _ + +from mediagoblin.media_types import get_media_manager THUMB_SIZE = 180, 180 @@ -42,6 +41,8 @@ def create_pub_filepath(entry, filename): class ProcessMedia(Task): """ + DEPRECATED -- This now resides in the individual media plugins + Pass this entry off for processing. """ def run(self, media_id): @@ -54,8 +55,9 @@ class ProcessMedia(Task): # Try to process, and handle expected errors. try: - __import__(entry['media_type']) - process_image(entry) + #__import__(entry['media_type']) + manager = get_media_manager(entry['media_type']) + manager['processor'](entry) except BaseProcessingFail, exc: mark_entry_failed(entry._id, exc) return @@ -78,9 +80,6 @@ class ProcessMedia(Task): 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. @@ -116,80 +115,29 @@ def mark_entry_failed(entry_id, exc): u'fail_metadata': {}}}) -def process_image(entry): +class BaseProcessingFail(Exception): """ - Code to process an image + 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. """ - workbench = mgg.workbench_manager.create_workbench() - # Conversions subdirectory to avoid collisions - conversions_subdir = os.path.join( - workbench.dir, 'conversions') - os.mkdir(conversions_subdir) + general_message = u'' - queued_filepath = entry['queued_media_file'] - queued_filename = workbench.localized_file( - mgg.queue_store, queued_filepath, - 'source') + @property + def exception_path(self): + return u"%s:%s" % ( + self.__class__.__module__, self.__class__.__name__) - extension = os.path.splitext(queued_filename)[1] + def __init__(self, **metadata): + self.metadata = metadata or {} - try: - thumb = Image.open(queued_filename) - except IOError: - raise BadMediaFail() - thumb.thumbnail(THUMB_SIZE, Image.ANTIALIAS) - - # Copy the thumb to the conversion subdir, then remotely. - thumb_filename = 'thumbnail' + extension - thumb_filepath = create_pub_filepath(entry, thumb_filename) - tmp_thumb_filename = os.path.join( - conversions_subdir, thumb_filename) - with file(tmp_thumb_filename, 'w') as thumb_file: - thumb.save(thumb_file) - mgg.public_store.copy_local_to_storage( - tmp_thumb_filename, thumb_filepath) - - # 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 - - if medium.size[0] > MEDIUM_SIZE[0] or medium.size[1] > MEDIUM_SIZE[1]: - medium.thumbnail(MEDIUM_SIZE, Image.ANTIALIAS) - - medium_filename = 'medium' + extension - medium_filepath = create_pub_filepath(entry, medium_filename) - tmp_medium_filename = os.path.join( - conversions_subdir, medium_filename) - - with file(tmp_medium_filename, 'w') as medium_file: - medium.save(medium_file) - - mgg.public_store.copy_local_to_storage( - tmp_medium_filename, medium_filepath) - - medium_processed = True - - # we have to re-read because unlike PIL, not everything reads - # things in string representation :) - queued_file = file(queued_filename, 'rb') - - with queued_file: - original_filepath = create_pub_filepath(entry, queued_filepath[-1]) - - with mgg.public_store.get_file(original_filepath, 'wb') \ - as original_file: - original_file.write(queued_file.read()) - - mgg.queue_store.delete_file(queued_filepath) - entry['queued_media_file'] = [] - media_files_dict = entry.setdefault('media_files', {}) - media_files_dict['thumb'] = thumb_filepath - media_files_dict['original'] = original_filepath - if medium_processed: - media_files_dict['medium'] = medium_filepath - - # clean up workbench - workbench.destroy_self() +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/submit/views.py b/mediagoblin/submit/views.py index dd1c3d1b..21381e39 100644 --- a/mediagoblin/submit/views.py +++ b/mediagoblin/submit/views.py @@ -19,6 +19,8 @@ import uuid from os.path import splitext from cgi import FieldStorage +from celery import registry + from werkzeug.utils import secure_filename from mediagoblin.db.util import ObjectId @@ -27,7 +29,7 @@ from mediagoblin.tools.translate import pass_to_ugettext as _ from mediagoblin.tools.response import render_to_response, redirect from mediagoblin.decorators import require_active_login from mediagoblin.submit import forms as submit_forms, security -from mediagoblin.process_media import mark_entry_failed +from mediagoblin.processing import mark_entry_failed, ProcessMedia from mediagoblin.messages import add_message, SUCCESS from mediagoblin.media_types import get_media_type_and_manager @@ -104,8 +106,9 @@ def submit_start(request): # # (... don't change entry after this point to avoid race # conditions with changes to the document via processing code) + process_media = registry.tasks[ProcessMedia.name] try: - media_manager['processor'].apply_async( + process_media.apply_async( [unicode(entry._id)], {}, task_id=task_id) except BaseException as exc: From 0bce749b21595fb0e33e2a109902b71e4611d483 Mon Sep 17 00:00:00 2001 From: Joar Wandborg Date: Mon, 21 Nov 2011 23:38:31 +0100 Subject: [PATCH 102/302] Fixes after merging video into master - part 2 - Added handling of InvalidFileType to submit.views - Updated test_celery_setup and test_submission tests to reflect the changes to the media procesing infrastructure --- mediagoblin/submit/views.py | 157 +++++++++++++------------ mediagoblin/tests/test_celery_setup.py | 4 +- mediagoblin/tests/test_submission.py | 6 +- 3 files changed, 85 insertions(+), 82 deletions(-) diff --git a/mediagoblin/submit/views.py b/mediagoblin/submit/views.py index 21381e39..3def44ce 100644 --- a/mediagoblin/submit/views.py +++ b/mediagoblin/submit/views.py @@ -31,7 +31,7 @@ from mediagoblin.decorators import require_active_login from mediagoblin.submit import forms as submit_forms, security from mediagoblin.processing import mark_entry_failed, ProcessMedia from mediagoblin.messages import add_message, SUCCESS -from mediagoblin.media_types import get_media_type_and_manager +from mediagoblin.media_types import get_media_type_and_manager, InvalidFileType @require_active_login @@ -48,86 +48,89 @@ def submit_start(request): submit_form.file.errors.append( _(u'You must provide a file.')) else: - filename = request.POST['file'].filename - - media_type, media_manager = get_media_type_and_manager(filename) - - # create entry and save in database - entry = request.db.MediaEntry() - entry['_id'] = ObjectId() - entry['media_type'] = unicode(media_type) - entry['title'] = ( - unicode(request.POST['title']) - or unicode(splitext(filename)[0])) - - entry['description'] = unicode(request.POST.get('description')) - entry['description_html'] = cleaned_markdown_conversion( - entry['description']) - - entry['uploader'] = request.user['_id'] - - # Process the user's folksonomy "tags" - entry['tags'] = convert_to_tag_list_of_dicts( - request.POST.get('tags')) - - # Generate a slug from the title - entry.generate_slug() - - - # Now store generate the queueing related filename - queue_filepath = request.app.queue_store.get_unique_filepath( - ['media_entries', - unicode(entry._id), - secure_filename(filename)]) - - # queue appropriately - queue_file = request.app.queue_store.get_file( - queue_filepath, 'wb') - - with queue_file: - queue_file.write(request.POST['file'].file.read()) - - # 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) - - # Pass off to processing - # - # (... don't change entry after this point to avoid race - # conditions with changes to the document via processing code) - process_media = registry.tasks[ProcessMedia.name] 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. + filename = request.POST['file'].filename + media_type, media_manager = get_media_type_and_manager(filename) + + # create entry and save in database + entry = request.db.MediaEntry() + entry['_id'] = ObjectId() + entry['media_type'] = unicode(media_type) + entry['title'] = ( + unicode(request.POST['title']) + or unicode(splitext(filename)[0])) + + entry['description'] = unicode(request.POST.get('description')) + entry['description_html'] = cleaned_markdown_conversion( + entry['description']) + + entry['uploader'] = request.user['_id'] + + # Process the user's folksonomy "tags" + entry['tags'] = convert_to_tag_list_of_dicts( + request.POST.get('tags')) + + # Generate a slug from the title + entry.generate_slug() + + + # Now store generate the queueing related filename + queue_filepath = request.app.queue_store.get_unique_filepath( + ['media_entries', + unicode(entry._id), + secure_filename(filename)]) + + # queue appropriately + queue_file = request.app.queue_store.get_file( + queue_filepath, 'wb') + + with queue_file: + queue_file.write(request.POST['file'].file.read()) + + # 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) + + # Pass off to processing # - # ... not completely the diaper pattern because the - # exception is re-raised :) - mark_entry_failed(entry._id, exc) - # re-raise the exception - raise + # (... don't change entry after this point to avoid race + # conditions with changes to the document via processing code) + process_media = registry.tasks[ProcessMedia.name] + 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._id, exc) + # re-raise the exception + raise - add_message(request, SUCCESS, _('Woohoo! Submitted!')) + add_message(request, SUCCESS, _('Woohoo! Submitted!')) - return redirect(request, "mediagoblin.user_pages.user_home", - user=request.user['username']) + return redirect(request, "mediagoblin.user_pages.user_home", + user=request.user['username']) + except InvalidFileType, exc: + submit_form.file.errors.append( + _(u'Invalid file type.')) return render_to_response( request, diff --git a/mediagoblin/tests/test_celery_setup.py b/mediagoblin/tests/test_celery_setup.py index 348a4357..19a9b899 100644 --- a/mediagoblin/tests/test_celery_setup.py +++ b/mediagoblin/tests/test_celery_setup.py @@ -50,7 +50,7 @@ def test_setup_celery_from_config(): assert isinstance(fake_celery_module.CELERYD_ETA_SCHEDULER_PRECISION, float) assert fake_celery_module.CELERY_RESULT_PERSISTENT is True assert fake_celery_module.CELERY_IMPORTS == [ - 'foo.bar.baz', 'this.is.an.import', 'mediagoblin.process_media'] + 'foo.bar.baz', 'this.is.an.import', 'mediagoblin.processing'] assert fake_celery_module.CELERY_MONGODB_BACKEND_SETTINGS == { 'database': 'mediagoblin'} assert fake_celery_module.CELERY_RESULT_BACKEND == 'mongodb' @@ -74,7 +74,7 @@ def test_setup_celery_from_config(): assert isinstance(fake_celery_module.CELERYD_ETA_SCHEDULER_PRECISION, float) assert fake_celery_module.CELERY_RESULT_PERSISTENT is False assert fake_celery_module.CELERY_IMPORTS == [ - 'baz.bar.foo', 'import.is.a.this', 'mediagoblin.process_media'] + 'baz.bar.foo', 'import.is.a.this', 'mediagoblin.processing'] assert fake_celery_module.CELERY_MONGODB_BACKEND_SETTINGS == { 'database': 'captain_lollerskates', 'host': 'mongodb.example.org', diff --git a/mediagoblin/tests/test_submission.py b/mediagoblin/tests/test_submission.py index dec7118b..eea5747f 100644 --- a/mediagoblin/tests/test_submission.py +++ b/mediagoblin/tests/test_submission.py @@ -222,7 +222,7 @@ class TestSubmission: context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/submit/start.html'] form = context['submit_form'] - assert form.file.errors == ['The file doesn\'t seem to be an image!'] + assert form.file.errors == [u'Invalid file type.'] # NOTE: The following 2 tests will ultimately fail, but they # *will* pass the initial form submission step. Instead, @@ -246,7 +246,7 @@ class TestSubmission: assert_equal(entry['state'], 'failed') assert_equal( entry['fail_error'], - u'mediagoblin.process_media.errors:BadMediaFail') + u'mediagoblin.processing:BadMediaFail') # Test non-supported file with .png extension # ------------------------------------------- @@ -266,4 +266,4 @@ class TestSubmission: assert_equal(entry['state'], 'failed') assert_equal( entry['fail_error'], - u'mediagoblin.process_media.errors:BadMediaFail') + u'mediagoblin.processing:BadMediaFail') From 8aeb6738774f6428312bd0889e2aaf4fc9445da0 Mon Sep 17 00:00:00 2001 From: Joar Wandborg Date: Tue, 22 Nov 2011 00:09:41 +0100 Subject: [PATCH 103/302] Video support is disabled by default, set enable_video to true to enable --- mediagoblin/config_spec.ini | 3 +++ mediagoblin/media_types/__init__.py | 7 +++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/mediagoblin/config_spec.ini b/mediagoblin/config_spec.ini index eef6f6e0..e5e059c9 100644 --- a/mediagoblin/config_spec.ini +++ b/mediagoblin/config_spec.ini @@ -50,6 +50,9 @@ allow_attachments = boolean(default=False) # Cookie stuff csrf_cookie_name = string(default='mediagoblin_csrftoken') +# Media types +enable_video = boolean(default=False) + [storage:publicstore] storage_class = string(default="mediagoblin.storage.filestorage:BasicFileStorage") base_dir = string(default="%(here)s/user_dev/media/public") diff --git a/mediagoblin/media_types/__init__.py b/mediagoblin/media_types/__init__.py index 2d13f5a6..a2ea6bcb 100644 --- a/mediagoblin/media_types/__init__.py +++ b/mediagoblin/media_types/__init__.py @@ -17,6 +17,7 @@ import os import sys +from mediagoblin import mg_globals from mediagoblin.util import lazy_pass_to_ugettext as _ @@ -29,8 +30,10 @@ class InvalidFileType(Exception): # This should be more dynamic in the future. Perhaps put it in the .ini? # -- Joar MEDIA_TYPES = [ - 'mediagoblin.media_types.image', - 'mediagoblin.media_types.video'] + 'mediagoblin.media_types.image'] + +if mg_globals.app_config['enable_video']: + MEDIA_TYPES.append('mediagoblin.media_types.video') def get_media_types(): From d0ba62e2e773dbd3cc89bf6f446da45370652360 Mon Sep 17 00:00:00 2001 From: "Pablo J. Urbano Santos" Date: Tue, 22 Nov 2011 20:29:33 +0100 Subject: [PATCH 104/302] Fixes #597. Add a visible error when user tries to delete an image without cheking the "I'm sure" checkbox. --- mediagoblin/user_pages/views.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mediagoblin/user_pages/views.py b/mediagoblin/user_pages/views.py index 25fd2ebb..2ccb453b 100644 --- a/mediagoblin/user_pages/views.py +++ b/mediagoblin/user_pages/views.py @@ -179,6 +179,9 @@ def media_confirm_delete(request, media): return redirect(request, "mediagoblin.user_pages.user_home", user=username) else: + messages.add_message( + request, messages.ERROR, + _("The file was not deleted because you didn't check that you were sure.")) return exc.HTTPFound( location=media.url_for_self(request.urlgen)) From 6506b1e22c70b55a73ee4cb391aebaf73db79ef9 Mon Sep 17 00:00:00 2001 From: Joar Wandborg Date: Tue, 22 Nov 2011 21:06:08 +0100 Subject: [PATCH 105/302] Fixes for video branch - Removed superfluous code from media_types.image - Updated lazy_pass_to_ugettext imports --- mediagoblin/media_types/__init__.py | 10 ++---- mediagoblin/media_types/image/processing.py | 36 -------------------- mediagoblin/media_types/video/transcoders.py | 4 +-- mediagoblin/processing.py | 2 +- 4 files changed, 5 insertions(+), 47 deletions(-) diff --git a/mediagoblin/media_types/__init__.py b/mediagoblin/media_types/__init__.py index a2ea6bcb..f56fd942 100644 --- a/mediagoblin/media_types/__init__.py +++ b/mediagoblin/media_types/__init__.py @@ -18,7 +18,7 @@ import os import sys from mediagoblin import mg_globals -from mediagoblin.util import lazy_pass_to_ugettext as _ +from mediagoblin.tools.translate import lazy_pass_to_ugettext as _ class FileTypeNotSupported(Exception): @@ -49,13 +49,7 @@ def get_media_managers(): Generator that returns all available media managers ''' for media_type in get_media_types(): - try: - __import__(media_type) - except ImportError as e: - raise Exception( - _('ERROR: Could not import {media_type}: {exception}').format( - media_type=media_type, - exception=e)) + __import__(media_type) yield media_type, sys.modules[media_type].MEDIA_MANAGER diff --git a/mediagoblin/media_types/image/processing.py b/mediagoblin/media_types/image/processing.py index 5e8e4e0a..2932c455 100644 --- a/mediagoblin/media_types/image/processing.py +++ b/mediagoblin/media_types/image/processing.py @@ -31,42 +31,6 @@ from mediagoblin.processing import BaseProcessingFail, \ # 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 process_image(entry): """ diff --git a/mediagoblin/media_types/video/transcoders.py b/mediagoblin/media_types/video/transcoders.py index 493a837f..d7ed14ca 100644 --- a/mediagoblin/media_types/video/transcoders.py +++ b/mediagoblin/media_types/video/transcoders.py @@ -94,8 +94,8 @@ class VideoThumbnailer: self.videosink = gst.element_factory_make('fakesink', 'videosink') self.playbin.set_property('video-sink', self.videosink) - #self.audiosink = gst.element_factory_make('fakesink', 'audiosink') - #self.playbin.set_property('audio-sink', self.audiosink) + self.audiosink = gst.element_factory_make('fakesink', 'audiosink') + self.playbin.set_property('audio-sink', self.audiosink) self.bus = self.playbin.get_bus() self.bus.add_signal_watch() diff --git a/mediagoblin/processing.py b/mediagoblin/processing.py index 8738cbe2..89c4ac89 100644 --- a/mediagoblin/processing.py +++ b/mediagoblin/processing.py @@ -19,7 +19,7 @@ from celery.task import Task from mediagoblin.db.util import ObjectId from mediagoblin import mg_globals as mgg -from mediagoblin.util import lazy_pass_to_ugettext as _ +from mediagoblin.tools.translate import lazy_pass_to_ugettext as _ from mediagoblin.media_types import get_media_manager From 56bfd91ab45c5160bcd65ebe15f44b08f880ed72 Mon Sep 17 00:00:00 2001 From: "Pablo J. Urbano Santos" Date: Tue, 22 Nov 2011 21:07:09 +0100 Subject: [PATCH 106/302] Added a message noticing the user the image has been successfully deleted. --- mediagoblin/user_pages/views.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mediagoblin/user_pages/views.py b/mediagoblin/user_pages/views.py index 2ccb453b..b28b68e1 100644 --- a/mediagoblin/user_pages/views.py +++ b/mediagoblin/user_pages/views.py @@ -175,13 +175,14 @@ def media_confirm_delete(request, media): delete_media_files(media) media.delete() + messages.add_message(request, messages.SUCCESS, _('You deleted the media.')) return redirect(request, "mediagoblin.user_pages.user_home", user=username) else: messages.add_message( request, messages.ERROR, - _("The file was not deleted because you didn't check that you were sure.")) + _("The media was not deleted because you didn't check that you were sure.")) return exc.HTTPFound( location=media.url_for_self(request.urlgen)) From ea33f63635ca0b57f0bc7eca6eb941a9ee99b596 Mon Sep 17 00:00:00 2001 From: Elrond Date: Tue, 22 Nov 2011 21:48:56 +0100 Subject: [PATCH 107/302] Wrap long line. Nothing else. --- mediagoblin/user_pages/views.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mediagoblin/user_pages/views.py b/mediagoblin/user_pages/views.py index b28b68e1..f679be9c 100644 --- a/mediagoblin/user_pages/views.py +++ b/mediagoblin/user_pages/views.py @@ -175,7 +175,8 @@ def media_confirm_delete(request, media): delete_media_files(media) media.delete() - messages.add_message(request, messages.SUCCESS, _('You deleted the media.')) + messages.add_message( + request, messages.SUCCESS, _('You deleted the media.')) return redirect(request, "mediagoblin.user_pages.user_home", user=username) From 4d4e5b435b54fcf0920786a40e190c1748cc2ed1 Mon Sep 17 00:00:00 2001 From: Elrond Date: Fri, 18 Nov 2011 23:37:25 +0100 Subject: [PATCH 108/302] 652: Don't show empty field labels. If the label for a field is empty, don't show it at all. And don't translate it! --- mediagoblin/templates/mediagoblin/utils/wtforms.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mediagoblin/templates/mediagoblin/utils/wtforms.html b/mediagoblin/templates/mediagoblin/utils/wtforms.html index 39dca7cc..cc30388f 100644 --- a/mediagoblin/templates/mediagoblin/utils/wtforms.html +++ b/mediagoblin/templates/mediagoblin/utils/wtforms.html @@ -18,7 +18,9 @@ {# Generically render a field #} {% macro render_field_div(field) %} -

+ {% if field.label.text -%} +

+ {%- endif %}
{{ field }} {%- if field.errors -%} From 30188321531e1b0d3c78166498702bbd8c7dc2bc Mon Sep 17 00:00:00 2001 From: Elrond Date: Mon, 21 Nov 2011 21:40:48 +0100 Subject: [PATCH 109/302] Rename MediaEntry.uploader() to .get_uploader() The .uploader() method conflicts with the uploader database field. As we're moving to .FIELD for db field access, this is a relevant conflict. So renaming .uploader() to .get_uploader() --- mediagoblin/db/models.py | 8 ++++---- mediagoblin/decorators.py | 2 +- mediagoblin/listings/views.py | 2 +- .../templates/mediagoblin/edit/attachments.html | 2 +- mediagoblin/templates/mediagoblin/edit/edit.html | 2 +- .../templates/mediagoblin/user_pages/media.html | 16 ++++++++-------- .../user_pages/media_confirm_delete.html | 2 +- mediagoblin/user_pages/views.py | 4 ++-- 8 files changed, 19 insertions(+), 19 deletions(-) diff --git a/mediagoblin/db/models.py b/mediagoblin/db/models.py index f13a4457..265fe36d 100644 --- a/mediagoblin/db/models.py +++ b/mediagoblin/db/models.py @@ -263,7 +263,7 @@ class MediaEntry(Document): Use a slug if we have one, else use our '_id'. """ - uploader = self.uploader() + uploader = self.get_uploader() if self.get('slug'): return urlgen( @@ -286,7 +286,7 @@ class MediaEntry(Document): '_id', ASCENDING).limit(1) if cursor.count(): return urlgen('mediagoblin.user_pages.media_home', - user=self.uploader()['username'], + user=self.get_uploader()['username'], media=unicode(cursor[0]['slug'])) def url_to_next(self, urlgen): @@ -300,10 +300,10 @@ class MediaEntry(Document): if cursor.count(): return urlgen('mediagoblin.user_pages.media_home', - user=self.uploader()['username'], + user=self.get_uploader()['username'], media=unicode(cursor[0]['slug'])) - def uploader(self): + def get_uploader(self): return self.db.User.find_one({'_id': self['uploader']}) def get_fail_exception(self): diff --git a/mediagoblin/decorators.py b/mediagoblin/decorators.py index 8f7532ec..1cdce23a 100644 --- a/mediagoblin/decorators.py +++ b/mediagoblin/decorators.py @@ -58,7 +58,7 @@ def user_may_delete_media(controller): """ def wrapper(request, *args, **kwargs): uploader = request.db.MediaEntry.find_one( - {'_id': ObjectId(request.matchdict['media'])}).uploader() + {'_id': ObjectId(request.matchdict['media'])}).get_uploader() if not (request.user['is_admin'] or request.user._id == uploader._id): return exc.HTTPForbidden() diff --git a/mediagoblin/listings/views.py b/mediagoblin/listings/views.py index 12e539e7..5a09de43 100644 --- a/mediagoblin/listings/views.py +++ b/mediagoblin/listings/views.py @@ -86,7 +86,7 @@ def tag_atom_feed(request): feed.add(entry.get('title'), entry.get('description_html'), content_type='html', - author=entry.uploader()['username'], + author=entry.get_uploader()['username'], updated=entry.get('created'), url=entry.url_for_self(request.urlgen)) diff --git a/mediagoblin/templates/mediagoblin/edit/attachments.html b/mediagoblin/templates/mediagoblin/edit/attachments.html index 576642cf..6a5ab896 100644 --- a/mediagoblin/templates/mediagoblin/edit/attachments.html +++ b/mediagoblin/templates/mediagoblin/edit/attachments.html @@ -20,7 +20,7 @@ {% import "/mediagoblin/utils/wtforms.html" as wtforms_util %} {% block mediagoblin_content %}
diff --git a/mediagoblin/templates/mediagoblin/edit/edit.html b/mediagoblin/templates/mediagoblin/edit/edit.html index 73c2bada..aa46af3d 100644 --- a/mediagoblin/templates/mediagoblin/edit/edit.html +++ b/mediagoblin/templates/mediagoblin/edit/edit.html @@ -22,7 +22,7 @@ {% block mediagoblin_content %}
diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html index 7ef64c76..adbb66db 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media.html @@ -56,8 +56,8 @@ {% 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 -%} + user=media.get_uploader().username), + username=media.get_uploader().username -%} By {{ username }} on {{ date }} {%- endtrans %}

@@ -84,7 +84,7 @@ {% trans %}at{% endtrans %} {{ comment.created.strftime("%I:%M%p %Y-%m-%d") }} @@ -94,7 +94,7 @@ {% if request.user %} {{ wtforms_util.render_divs(comment_form) }}
@@ -106,7 +106,7 @@ {{ render_pagination(request, pagination, request.urlgen('mediagoblin.user_pages.media_home', - user = media.uploader().username, + user = media.get_uploader().username, media = media._id)) }}
{% endif %} @@ -118,13 +118,13 @@ request.user['is_admin'] %}

{% set edit_url = request.urlgen('mediagoblin.edit.edit_media', - user= media.uploader().username, + user= media.get_uploader().username, media= media._id) %} {% trans %}Edit{% endtrans %}

{% set delete_url = request.urlgen('mediagoblin.user_pages.media_confirm_delete', - user= media.uploader().username, + user= media.get_uploader().username, media= media._id) %} {% trans %}Delete{% endtrans %}

@@ -148,7 +148,7 @@ or request.user['is_admin']) %}

Add attachment

{% endif %} diff --git a/mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html b/mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html index c3a9d622..058351a5 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html @@ -22,7 +22,7 @@ {% block mediagoblin_content %}
diff --git a/mediagoblin/user_pages/views.py b/mediagoblin/user_pages/views.py index f679be9c..61cae775 100644 --- a/mediagoblin/user_pages/views.py +++ b/mediagoblin/user_pages/views.py @@ -169,7 +169,7 @@ def media_confirm_delete(request, media): if request.method == 'POST' and form.validate(): if form.confirm.data is True: - username = media.uploader()['username'] + username = media.get_uploader()['username'] # Delete all files on the public storage delete_media_files(media) @@ -188,7 +188,7 @@ def media_confirm_delete(request, media): location=media.url_for_self(request.urlgen)) if ((request.user[u'is_admin'] and - request.user._id != media.uploader()._id)): + request.user._id != media.get_uploader()._id)): messages.add_message( request, messages.WARNING, _("You are about to delete another user's media. " From cfa96da734e633856282fcefb04e1fb231d85053 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Fri, 25 Nov 2011 11:41:24 -0600 Subject: [PATCH 110/302] Load multiple media types based on the media_types section of the config file --- mediagoblin.ini | 3 +++ mediagoblin/config_spec.ini | 5 +++-- mediagoblin/media_types/__init__.py | 14 +++----------- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/mediagoblin.ini b/mediagoblin.ini index 728ab2f2..dbde6e51 100644 --- a/mediagoblin.ini +++ b/mediagoblin.ini @@ -11,6 +11,9 @@ email_debug_mode = true # Set to false to disable registrations allow_registration = true +## Uncomment this to turn on video or enable other media types +# media_types = mediagoblin.media_types.image, mediagoblin.media_types.video + ## Uncomment this to put some user-overriding templates here #local_templates = %(here)s/user_dev/templates/ diff --git a/mediagoblin/config_spec.ini b/mediagoblin/config_spec.ini index e5e059c9..a17e30f0 100644 --- a/mediagoblin/config_spec.ini +++ b/mediagoblin/config_spec.ini @@ -2,16 +2,17 @@ # HTML title of the pages html_title = string(default="GNU MediaGoblin") +# Enabled media types +media_types = string_list(default=list("mediagoblin.media_types.image")) + # database stuff db_host = string() db_name = string(default="mediagoblin") db_port = integer() - # Where temporary files used in processing and etc are kept workbench_path = string(default="%(here)s/user_dev/media/workbench") - # Where mediagoblin-builtin static assets are kept direct_remote_path = string(default="/mgoblin_static/") diff --git a/mediagoblin/media_types/__init__.py b/mediagoblin/media_types/__init__.py index f56fd942..61786562 100644 --- a/mediagoblin/media_types/__init__.py +++ b/mediagoblin/media_types/__init__.py @@ -27,20 +27,12 @@ class FileTypeNotSupported(Exception): class InvalidFileType(Exception): pass -# This should be more dynamic in the future. Perhaps put it in the .ini? -# -- Joar -MEDIA_TYPES = [ - 'mediagoblin.media_types.image'] - -if mg_globals.app_config['enable_video']: - MEDIA_TYPES.append('mediagoblin.media_types.video') - def get_media_types(): - ''' + """ Generator that returns the available media types - ''' - for media_type in MEDIA_TYPES: + """ + for media_type in mg_globals.app_config['media_types']: yield media_type From f47a7a8c92936dfedd73716a69ba3f0978481aca Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Fri, 25 Nov 2011 11:42:03 -0600 Subject: [PATCH 111/302] Remove old enable_video config option --- mediagoblin/config_spec.ini | 2 -- 1 file changed, 2 deletions(-) diff --git a/mediagoblin/config_spec.ini b/mediagoblin/config_spec.ini index a17e30f0..c057f432 100644 --- a/mediagoblin/config_spec.ini +++ b/mediagoblin/config_spec.ini @@ -51,8 +51,6 @@ allow_attachments = boolean(default=False) # Cookie stuff csrf_cookie_name = string(default='mediagoblin_csrftoken') -# Media types -enable_video = boolean(default=False) [storage:publicstore] storage_class = string(default="mediagoblin.storage.filestorage:BasicFileStorage") From 4da6efb45956321d831339da0fcdbbb6553c6846 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Fri, 25 Nov 2011 11:43:34 -0600 Subject: [PATCH 112/302] Removing these video javascript files, which are currently unused --- mediagoblin/templates/mediagoblin/base.html | 5 ----- 1 file changed, 5 deletions(-) diff --git a/mediagoblin/templates/mediagoblin/base.html b/mediagoblin/templates/mediagoblin/base.html index 3dd9c8ff..29639026 100644 --- a/mediagoblin/templates/mediagoblin/base.html +++ b/mediagoblin/templates/mediagoblin/base.html @@ -32,11 +32,6 @@ href="{{ request.staticdirect('/css/video-js.css') }}"/> - - - {% block mediagoblin_head %} {% endblock mediagoblin_head %} From ce5ae8da19707019cd62d42533e591d71071f4fe Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Fri, 25 Nov 2011 12:13:56 -0600 Subject: [PATCH 113/302] Rename MediaGoblin middleware to meddleware to avoid confusion w/ wsgi middleware hehehehehe, "meddleware" --- mediagoblin/app.py | 16 ++++++++-------- .../{middleware => meddleware}/__init__.py | 6 +++--- mediagoblin/{middleware => meddleware}/csrf.py | 4 ++-- mediagoblin/{middleware => meddleware}/noop.py | 2 +- mediagoblin/tests/tools.py | 10 +++++----- mediagoblin/tools/template.py | 2 +- 6 files changed, 20 insertions(+), 20 deletions(-) rename mediagoblin/{middleware => meddleware}/__init__.py (86%) rename mediagoblin/{middleware => meddleware}/csrf.py (98%) rename mediagoblin/{middleware => meddleware}/noop.py (96%) diff --git a/mediagoblin/app.py b/mediagoblin/app.py index ce4b0bec..aafadd97 100644 --- a/mediagoblin/app.py +++ b/mediagoblin/app.py @@ -20,7 +20,7 @@ import urllib import routes from webob import Request, exc -from mediagoblin import routing, middleware +from mediagoblin import routing, meddleware from mediagoblin.tools import common, translate, template from mediagoblin.tools.response import render_404 from mediagoblin.tools import request as mg_request @@ -100,15 +100,15 @@ class MediaGoblinApp(object): # matters in always eager mode :) setup_workbench() - # instantiate application middleware - self.middleware = [common.import_component(m)(self) - for m in middleware.ENABLED_MIDDLEWARE] + # instantiate application meddleware + self.meddleware = [common.import_component(m)(self) + for m in meddleware.ENABLED_MEDDLEWARE] def __call__(self, environ, start_response): request = Request(environ) - # pass the request through our middleware classes - for m in self.middleware: + # pass the request through our meddleware classes + for m in self.meddleware: response = m.process_request(request) if response is not None: return response(environ, start_response) @@ -169,8 +169,8 @@ class MediaGoblinApp(object): # get the response from the controller response = controller(request) - # pass the response through the middleware - for m in self.middleware[::-1]: + # pass the response through the meddleware + for m in self.meddleware[::-1]: m.process_response(request, response) return response(environ, start_response) diff --git a/mediagoblin/middleware/__init__.py b/mediagoblin/meddleware/__init__.py similarity index 86% rename from mediagoblin/middleware/__init__.py rename to mediagoblin/meddleware/__init__.py index 05325ee5..3addc937 100644 --- a/mediagoblin/middleware/__init__.py +++ b/mediagoblin/meddleware/__init__.py @@ -14,7 +14,7 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -ENABLED_MIDDLEWARE = ( - 'mediagoblin.middleware.noop:NoOpMiddleware', - 'mediagoblin.middleware.csrf:CsrfMiddleware', +ENABLED_MEDDLEWARE = ( + 'mediagoblin.meddleware.noop:NoOpMeddleware', + 'mediagoblin.meddleware.csrf:CsrfMeddleware', ) diff --git a/mediagoblin/middleware/csrf.py b/mediagoblin/meddleware/csrf.py similarity index 98% rename from mediagoblin/middleware/csrf.py rename to mediagoblin/meddleware/csrf.py index 8275c18e..051afe58 100644 --- a/mediagoblin/middleware/csrf.py +++ b/mediagoblin/meddleware/csrf.py @@ -47,8 +47,8 @@ def render_csrf_form_token(request): return form.csrf_token -class CsrfMiddleware(object): - """CSRF Protection Middleware +class CsrfMeddleware(object): + """CSRF Protection Meddleware Adds a CSRF Cookie to responses and verifies that it is present and matches the form token for non-safe requests. diff --git a/mediagoblin/middleware/noop.py b/mediagoblin/meddleware/noop.py similarity index 96% rename from mediagoblin/middleware/noop.py rename to mediagoblin/meddleware/noop.py index 820b5d9e..d11a5b9e 100644 --- a/mediagoblin/middleware/noop.py +++ b/mediagoblin/meddleware/noop.py @@ -15,7 +15,7 @@ # along with this program. If not, see . -class NoOpMiddleware(object): +class NoOpMeddleware(object): def __init__(self, mg_app): self.app = mg_app diff --git a/mediagoblin/tests/tools.py b/mediagoblin/tests/tools.py index 420d9ba8..1a26c6e9 100644 --- a/mediagoblin/tests/tools.py +++ b/mediagoblin/tests/tools.py @@ -50,9 +50,9 @@ $ CELERY_CONFIG_MODULE=mediagoblin.init.celery.from_tests ./bin/nosetests""" class BadCeleryEnviron(Exception): pass -class TestingMiddleware(object): +class TestingMeddleware(object): """ - Middleware for the Unit tests + Meddleware for the Unit tests It might make sense to perform some tests on all requests/responses. Or prepare them in a special @@ -60,7 +60,7 @@ class TestingMiddleware(object): for being valid html *after* being rendered. This module is getting inserted at the front of the - middleware list, which means: requests are handed here + meddleware list, which means: requests are handed here first, responses last. So this wraps up the "normal" app. @@ -149,11 +149,11 @@ def get_test_app(dump_old_app=True): test_app = loadapp( 'config:' + TEST_SERVER_CONFIG) - # Insert the TestingMiddleware, which can do some + # Insert the TestingMeddleware, which can do some # sanity checks on every request/response. # Doing it this way is probably not the cleanest way. # We'll fix it, when we have plugins! - mg_globals.app.middleware.insert(0, TestingMiddleware(mg_globals.app)) + mg_globals.app.meddleware.insert(0, TestingMeddleware(mg_globals.app)) app = TestApp(test_app) MGOBLIN_APP = app diff --git a/mediagoblin/tools/template.py b/mediagoblin/tools/template.py index 0986761b..f48b7c2e 100644 --- a/mediagoblin/tools/template.py +++ b/mediagoblin/tools/template.py @@ -21,7 +21,7 @@ from mediagoblin import mg_globals from mediagoblin import messages from mediagoblin.tools import common from mediagoblin.tools.translate import setup_gettext -from mediagoblin.middleware.csrf import render_csrf_form_token +from mediagoblin.meddleware.csrf import render_csrf_form_token SETUP_JINJA_ENVS = {} From 1b7662012f4f0827d01cc8747ce710b3e4dc6b81 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Fri, 25 Nov 2011 12:33:34 -0600 Subject: [PATCH 114/302] Uncommenting requires=['gst'] till I figure out why Joar added it there :) --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index c3c2f86f..ec672dd2 100644 --- a/setup.py +++ b/setup.py @@ -66,7 +66,7 @@ setup( ## their package managers. # 'lxml', ], - requires=['gst'], + # requires=['gst'], test_suite='nose.collector', entry_points="""\ [console_scripts] From 56dc1c9d3eb73b86bf8e165ffc79ad4929239603 Mon Sep 17 00:00:00 2001 From: Elrond Date: Fri, 25 Nov 2011 22:16:18 +0100 Subject: [PATCH 115/302] Add base class for Meddleware Created a BaseMeddleware which all Meddleware should derive from. This is not strictly needed, but will greatly help. The base class has the common __init__ of all the other Meddlwares and fall backs for all hooks. That way a new Meddlware only needs to override what it actually wants to implement. --- mediagoblin/meddleware/__init__.py | 12 ++++++++++++ mediagoblin/meddleware/csrf.py | 6 ++---- mediagoblin/meddleware/noop.py | 5 ++--- mediagoblin/tests/tools.py | 9 ++------- 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/mediagoblin/meddleware/__init__.py b/mediagoblin/meddleware/__init__.py index 3addc937..729a020d 100644 --- a/mediagoblin/meddleware/__init__.py +++ b/mediagoblin/meddleware/__init__.py @@ -18,3 +18,15 @@ ENABLED_MEDDLEWARE = ( 'mediagoblin.meddleware.noop:NoOpMeddleware', 'mediagoblin.meddleware.csrf:CsrfMeddleware', ) + + +class BaseMeddleware(object): + + def __init__(self, mg_app): + self.app = mg_app + + def process_request(self, request): + pass + + def process_response(self, request, response): + pass diff --git a/mediagoblin/meddleware/csrf.py b/mediagoblin/meddleware/csrf.py index 051afe58..ca2eca5f 100644 --- a/mediagoblin/meddleware/csrf.py +++ b/mediagoblin/meddleware/csrf.py @@ -21,6 +21,7 @@ from webob.exc import HTTPForbidden from wtforms import Form, HiddenField, validators from mediagoblin import mg_globals +from mediagoblin.meddleware import BaseMeddleware # Use the system (hardware-based) random number generator if it exists. # -- this optimization is lifted from Django @@ -47,7 +48,7 @@ def render_csrf_form_token(request): return form.csrf_token -class CsrfMeddleware(object): +class CsrfMeddleware(BaseMeddleware): """CSRF Protection Meddleware Adds a CSRF Cookie to responses and verifies that it is present @@ -57,9 +58,6 @@ class CsrfMeddleware(object): CSRF_KEYLEN = 64 SAFE_HTTP_METHODS = ("GET", "HEAD", "OPTIONS", "TRACE") - def __init__(self, mg_app): - self.app = mg_app - def process_request(self, request): """For non-safe requests, confirm that the tokens are present and match. diff --git a/mediagoblin/meddleware/noop.py b/mediagoblin/meddleware/noop.py index d11a5b9e..b43053de 100644 --- a/mediagoblin/meddleware/noop.py +++ b/mediagoblin/meddleware/noop.py @@ -15,11 +15,10 @@ # along with this program. If not, see . -class NoOpMeddleware(object): +from mediagoblin.meddleware import BaseMeddleware - def __init__(self, mg_app): - self.app = mg_app +class NoOpMeddleware(BaseMeddleware): def process_request(self, request): pass diff --git a/mediagoblin/tests/tools.py b/mediagoblin/tests/tools.py index 1a26c6e9..01813e96 100644 --- a/mediagoblin/tests/tools.py +++ b/mediagoblin/tests/tools.py @@ -26,6 +26,7 @@ from mediagoblin.tools import testing from mediagoblin.init.config import read_mediagoblin_config from mediagoblin.decorators import _make_safe from mediagoblin.db.open import setup_connection_and_db_from_config +from mediagoblin.meddleware import BaseMeddleware MEDIAGOBLIN_TEST_DB_NAME = u'__mediagoblin_tests__' @@ -50,7 +51,7 @@ $ CELERY_CONFIG_MODULE=mediagoblin.init.celery.from_tests ./bin/nosetests""" class BadCeleryEnviron(Exception): pass -class TestingMeddleware(object): +class TestingMeddleware(BaseMeddleware): """ Meddleware for the Unit tests @@ -69,12 +70,6 @@ class TestingMeddleware(object): create a new method and call it from process_*. """ - def __init__(self, mg_app): - self.app = mg_app - - def process_request(self, request): - pass - def process_response(self, request, response): # All following tests should be for html only! if response.content_type != "text/html": From 5568a014195fa9f39021033a6ba2706125bb13ed Mon Sep 17 00:00:00 2001 From: Elrond Date: Sun, 23 Oct 2011 23:29:15 +0200 Subject: [PATCH 116/302] Use setup_global_and_app_config in gmg's migrate. Instead of using read_mediagoblin_config, forgetting to check the validation report and then finding the main app section by hand, just use setup_global_and_app_config. --- mediagoblin/gmg_commands/migrate.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mediagoblin/gmg_commands/migrate.py b/mediagoblin/gmg_commands/migrate.py index beea109d..bd3bcb20 100644 --- a/mediagoblin/gmg_commands/migrate.py +++ b/mediagoblin/gmg_commands/migrate.py @@ -18,7 +18,7 @@ import sys from mediagoblin.db import util as db_util from mediagoblin.db.open import setup_connection_and_db_from_config -from mediagoblin.init.config import read_mediagoblin_config +from mediagoblin.init import setup_global_and_app_config # This MUST be imported so as to set up the appropriate migrations! from mediagoblin.db import migrations @@ -41,9 +41,9 @@ def _print_finished_migration(migration_number, migration_func): def migrate(args): - config, validation_result = read_mediagoblin_config(args.conf_file) + global_config, app_config = setup_global_and_app_config(args.conf_file) connection, db = setup_connection_and_db_from_config( - config['mediagoblin'], use_pymongo=True) + app_config, use_pymongo=True) migration_manager = db_util.MigrationManager(db) # Clear old indexes From 91cf67385a78a59af7874df327b96f7ea0b4259b Mon Sep 17 00:00:00 2001 From: Nathan Yergler Date: Sat, 26 Nov 2011 14:34:36 -0800 Subject: [PATCH 117/302] Issue 680: Dispatch meddleware request processing post-routing --- mediagoblin/app.py | 13 +++++++------ mediagoblin/meddleware/__init__.py | 2 +- mediagoblin/meddleware/csrf.py | 2 +- mediagoblin/meddleware/noop.py | 3 ++- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/mediagoblin/app.py b/mediagoblin/app.py index aafadd97..7f087ed9 100644 --- a/mediagoblin/app.py +++ b/mediagoblin/app.py @@ -107,12 +107,6 @@ class MediaGoblinApp(object): def __call__(self, environ, start_response): request = Request(environ) - # pass the request through our meddleware classes - for m in self.meddleware: - response = m.process_request(request) - if response is not None: - return response(environ, start_response) - ## Routing / controller loading stuff path_info = request.path_info route_match = self.routing.match(path_info) @@ -164,6 +158,13 @@ class MediaGoblinApp(object): return render_404(request)(environ, start_response) controller = common.import_component(route_match['controller']) + + # pass the request through our meddleware classes + for m in self.meddleware: + response = m.process_request(request, controller) + if response is not None: + return response(environ, start_response) + request.start_response = start_response # get the response from the controller diff --git a/mediagoblin/meddleware/__init__.py b/mediagoblin/meddleware/__init__.py index 729a020d..7ba70d87 100644 --- a/mediagoblin/meddleware/__init__.py +++ b/mediagoblin/meddleware/__init__.py @@ -25,7 +25,7 @@ class BaseMeddleware(object): def __init__(self, mg_app): self.app = mg_app - def process_request(self, request): + def process_request(self, request, controller): pass def process_response(self, request, response): diff --git a/mediagoblin/meddleware/csrf.py b/mediagoblin/meddleware/csrf.py index ca2eca5f..961fa7a6 100644 --- a/mediagoblin/meddleware/csrf.py +++ b/mediagoblin/meddleware/csrf.py @@ -58,7 +58,7 @@ class CsrfMeddleware(BaseMeddleware): CSRF_KEYLEN = 64 SAFE_HTTP_METHODS = ("GET", "HEAD", "OPTIONS", "TRACE") - def process_request(self, request): + def process_request(self, request, controller): """For non-safe requests, confirm that the tokens are present and match. """ diff --git a/mediagoblin/meddleware/noop.py b/mediagoblin/meddleware/noop.py index b43053de..f5376494 100644 --- a/mediagoblin/meddleware/noop.py +++ b/mediagoblin/meddleware/noop.py @@ -19,7 +19,8 @@ from mediagoblin.meddleware import BaseMeddleware class NoOpMeddleware(BaseMeddleware): - def process_request(self, request): + + def process_request(self, request, controller): pass def process_response(self, request, response): From ca9ebfe2e05c83248d647b442ff29a9758a6a05c Mon Sep 17 00:00:00 2001 From: Nathan Yergler Date: Sat, 26 Nov 2011 15:32:35 -0800 Subject: [PATCH 118/302] Issue 680 Allow decorating views to prevent CSRF protection. --- mediagoblin/meddleware/csrf.py | 15 ++++++++++++--- mediagoblin/tests/test_csrf_middleware.py | 21 ++++++++++++++++++++- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/mediagoblin/meddleware/csrf.py b/mediagoblin/meddleware/csrf.py index 961fa7a6..16541bee 100644 --- a/mediagoblin/meddleware/csrf.py +++ b/mediagoblin/meddleware/csrf.py @@ -31,6 +31,13 @@ else: getrandbits = random.getrandbits +def csrf_exempt(func): + """Decorate a Controller to exempt it from CSRF protection.""" + + func.csrf_enabled = False + return func + + class CsrfForm(Form): """Simple form to handle rendering a CSRF token and confirming it is included in the POST.""" @@ -75,9 +82,11 @@ class CsrfMeddleware(BaseMeddleware): # if this is a non-"safe" request (ie, one that could have # side effects), confirm that the CSRF tokens are present and # valid - if request.method not in self.SAFE_HTTP_METHODS \ - and ('gmg.verify_csrf' in request.environ or - 'paste.testing' not in request.environ): + if (getattr(controller, 'csrf_enabled', True) and + request.method not in self.SAFE_HTTP_METHODS and + ('gmg.verify_csrf' in request.environ or + 'paste.testing' not in request.environ) + ): return self.verify_tokens(request) diff --git a/mediagoblin/tests/test_csrf_middleware.py b/mediagoblin/tests/test_csrf_middleware.py index 691f10b9..c8fca23a 100644 --- a/mediagoblin/tests/test_csrf_middleware.py +++ b/mediagoblin/tests/test_csrf_middleware.py @@ -27,7 +27,7 @@ from mediagoblin import mg_globals def test_csrf_cookie_set(test_app): cookie_name = mg_globals.app_config['csrf_cookie_name'] - + # get login page response = test_app.get('/auth/login/') @@ -69,3 +69,22 @@ def test_csrf_token_must_match(test_app): mg_globals.app_config['csrf_cookie_name'])}, extra_environ={'gmg.verify_csrf': True}).\ status_int == 200 + +@setup_fresh_app +def test_csrf_exempt(test_app): + + # monkey with the views to decorate a known endpoint + import mediagoblin.auth.views + from mediagoblin.meddleware.csrf import csrf_exempt + + mediagoblin.auth.views.login = csrf_exempt( + mediagoblin.auth.views.login + ) + + # construct a request with no cookie or form token + assert test_app.post('/auth/login/', + extra_environ={'gmg.verify_csrf': True}, + expect_errors=False).status_int == 200 + + # restore the CSRF protection in case other tests expect it + mediagoblin.auth.views.login.csrf_enabled = True From 3038ba87e4fdc5612f57affeedb643a614e0c9a2 Mon Sep 17 00:00:00 2001 From: Manuel Urbano Santos Date: Sun, 27 Nov 2011 13:49:47 +0100 Subject: [PATCH 119/302] * Bug #671: Tags list on Edit page is not seperated by spaces and hard to read : Make 'media_tags_as_string' function put a space after each comma. * Feature #678: Drop custom delimiters in tags : I declare a constant in the begining of text.py file. --- mediagoblin/config_spec.ini | 1 - mediagoblin/tools/text.py | 5 +++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mediagoblin/config_spec.ini b/mediagoblin/config_spec.ini index eef6f6e0..544f0321 100644 --- a/mediagoblin/config_spec.ini +++ b/mediagoblin/config_spec.ini @@ -27,7 +27,6 @@ email_smtp_pass = string(default=None) allow_registration = boolean(default=True) # tag parsing -tags_delimiter = string(default=",") tags_max_length = integer(default=50) # Whether comments are ascending or descending diff --git a/mediagoblin/tools/text.py b/mediagoblin/tools/text.py index be1adb00..d576224d 100644 --- a/mediagoblin/tools/text.py +++ b/mediagoblin/tools/text.py @@ -43,6 +43,7 @@ HTML_CLEANER = Cleaner( host_whitelist=(), whitelist_tags=set([])) +TAGS_DELIMITER=','; def clean_html(html): # clean_html barfs on an empty string @@ -67,7 +68,7 @@ def convert_to_tag_list_of_dicts(tag_string): # Split the tag string into a list of tags for tag in stripped_tag_string.split( - mg_globals.app_config['tags_delimiter']): + TAGS_DELIMITER): # Ignore empty or duplicate tags if tag.strip() and tag.strip() not in [t['name'] for t in taglist]: @@ -85,7 +86,7 @@ def media_tags_as_string(media_entry_tags): """ media_tag_string = '' if media_entry_tags: - media_tag_string = mg_globals.app_config['tags_delimiter'].join( + media_tag_string = (TAGS_DELIMITER+u' ').join( [tag['name'] for tag in media_entry_tags]) return media_tag_string From d5bb51f9d4871d8b758875fb18be5d8a9fbdb260 Mon Sep 17 00:00:00 2001 From: Manuel Urbano Santos Date: Sun, 27 Nov 2011 13:55:07 +0100 Subject: [PATCH 120/302] * Feature #678: Drop custom delimiters in tags * Eliminate the definition of the tag delimiter for tests. * Remove a test that was related to custom tags delimiter. * Bug #671: Tags list on Edit page is not seperated by spaces and hard to read * Modify a test to include this space. --- mediagoblin/tests/test_mgoblin_app.ini | 1 - mediagoblin/tests/test_tags.py | 9 +-------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/mediagoblin/tests/test_mgoblin_app.ini b/mediagoblin/tests/test_mgoblin_app.ini index f979e810..2525a4f9 100644 --- a/mediagoblin/tests/test_mgoblin_app.ini +++ b/mediagoblin/tests/test_mgoblin_app.ini @@ -5,7 +5,6 @@ email_debug_mode = true db_name = __mediagoblin_tests__ # tag parsing -tags_delimiter = "," tags_max_length = 50 # Celery shouldn't be set up by the application as it's setup via diff --git a/mediagoblin/tests/test_tags.py b/mediagoblin/tests/test_tags.py index a05831c9..583c1a55 100644 --- a/mediagoblin/tests/test_tags.py +++ b/mediagoblin/tests/test_tags.py @@ -39,11 +39,4 @@ def test_list_of_dicts_conversion(test_app): # Make sure converting the list of dicts to a string works assert text.media_tags_as_string([{'name': u'yin', 'slug': u'yin'}, {'name': u'yang', 'slug': u'yang'}]) == \ - u'yin,yang' - - # If the tag delimiter is a space then we expect different results - mg_globals.app_config['tags_delimiter'] = u' ' - assert text.convert_to_tag_list_of_dicts('unicorn ceramic nazi') == [ - {'name': u'unicorn', 'slug': u'unicorn'}, - {'name': u'ceramic', 'slug': u'ceramic'}, - {'name': u'nazi', 'slug': u'nazi'}] + u'yin, yang' From 9382221fe2d3e69b7900cfb7461abfdb443b4d10 Mon Sep 17 00:00:00 2001 From: Manuel Urbano Santos Date: Sun, 27 Nov 2011 14:31:20 +0100 Subject: [PATCH 121/302] Fix the text "Seperate tags by commas and spaces" since spaces are not used to seperate anymore. --- mediagoblin/edit/forms.py | 2 +- mediagoblin/submit/forms.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mediagoblin/edit/forms.py b/mediagoblin/edit/forms.py index 93934be7..dd339e08 100644 --- a/mediagoblin/edit/forms.py +++ b/mediagoblin/edit/forms.py @@ -28,7 +28,7 @@ class EditForm(wtforms.Form): _('Tags'), [tag_length_validator], description=_( - "Seperate tags by commas or spaces.")) + "Seperate tags by commas.")) slug = wtforms.TextField( _('Slug'), [wtforms.validators.Required(message=_("The slug can't be empty"))], diff --git a/mediagoblin/submit/forms.py b/mediagoblin/submit/forms.py index 48a21f02..ad420771 100644 --- a/mediagoblin/submit/forms.py +++ b/mediagoblin/submit/forms.py @@ -32,4 +32,4 @@ class SubmitStartForm(wtforms.Form): _('Tags'), [tag_length_validator], description=_( - "Seperate tags by commas or spaces.")) + "Seperate tags by commas.")) From 19e2668b77427a1157984480231023661792fca8 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Sun, 27 Nov 2011 15:31:42 -0600 Subject: [PATCH 122/302] Updating translations --- .../i18n/ar/LC_MESSAGES/mediagoblin.po | 270 ++++++++------- .../i18n/ca/LC_MESSAGES/mediagoblin.po | 296 +++++++++-------- .../i18n/de/LC_MESSAGES/mediagoblin.po | 312 ++++++++++-------- .../i18n/en/LC_MESSAGES/mediagoblin.po | 242 ++++++++------ .../i18n/eo/LC_MESSAGES/mediagoblin.po | 278 +++++++++------- .../i18n/es/LC_MESSAGES/mediagoblin.po | 278 ++++++++-------- .../i18n/fr/LC_MESSAGES/mediagoblin.po | 280 ++++++++-------- .../i18n/ia/LC_MESSAGES/mediagoblin.po | 254 ++++++++------ .../i18n/it/LC_MESSAGES/mediagoblin.po | 278 +++++++++------- .../i18n/ja/LC_MESSAGES/mediagoblin.po | 256 +++++++------- .../i18n/nl/LC_MESSAGES/mediagoblin.po | 264 ++++++++------- .../i18n/nn_NO/LC_MESSAGES/mediagoblin.po | 282 ++++++++-------- .../i18n/pt_BR/LC_MESSAGES/mediagoblin.po | 278 ++++++++-------- .../i18n/ro/LC_MESSAGES/mediagoblin.po | 279 ++++++++-------- .../i18n/ru/LC_MESSAGES/mediagoblin.po | 292 +++++++++------- .../i18n/sk/LC_MESSAGES/mediagoblin.po | 280 ++++++++-------- .../i18n/sl/LC_MESSAGES/mediagoblin.po | 271 ++++++++------- .../i18n/sr/LC_MESSAGES/mediagoblin.po | 254 ++++++++------ .../i18n/sv/LC_MESSAGES/mediagoblin.po | 282 ++++++++-------- .../i18n/te/LC_MESSAGES/mediagoblin.po | 256 +++++++------- .../i18n/zh_TW/LC_MESSAGES/mediagoblin.po | 275 ++++++++------- 21 files changed, 3155 insertions(+), 2602 deletions(-) diff --git a/mediagoblin/i18n/ar/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/ar/LC_MESSAGES/mediagoblin.po index 548e971f..40e8b1cd 100644 --- a/mediagoblin/i18n/ar/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/ar/LC_MESSAGES/mediagoblin.po @@ -10,8 +10,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-11-01 23:14-0500\n" -"PO-Revision-Date: 2011-11-02 04:13+0000\n" +"POT-Creation-Date: 2011-11-27 15:25-0600\n" +"PO-Revision-Date: 2011-11-27 21:28+0000\n" "Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -21,6 +21,10 @@ msgstr "" "Language: ar\n" "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5\n" +#: mediagoblin/processing.py:143 +msgid "Invalid file given for media type." +msgstr "" + #: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 msgid "Username" msgstr "اسم المستخدم" @@ -54,8 +58,8 @@ msgid "Sorry, a user with that name already exists." msgstr "عذرًا، لقد اختار مستخدم آخر هذا الاسم." #: mediagoblin/auth/views.py:77 -msgid "Sorry, that email address has already been taken." -msgstr "عفوًا، هذا العنوان البريدي مستخدم." +msgid "Sorry, a user with that email address already exists." +msgstr "" #: mediagoblin/auth/views.py:179 msgid "" @@ -69,11 +73,19 @@ msgstr "" msgid "The verification key or user id is incorrect" msgstr "مفتاح التحقق أو معرف المستخدم خاطئ" -#: mediagoblin/auth/views.py:207 +#: mediagoblin/auth/views.py:203 +msgid "You must be logged in so we know who to send the email to!" +msgstr "" + +#: mediagoblin/auth/views.py:211 +msgid "You've already verified your email address!" +msgstr "" + +#: mediagoblin/auth/views.py:224 msgid "Resent your verification email." msgstr "أعدنا إرسال رسالة التحقق." -#: mediagoblin/auth/views.py:248 +#: mediagoblin/auth/views.py:265 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." @@ -89,43 +101,63 @@ msgstr "العنوان" msgid "Tags" msgstr "الوسوم" -#: mediagoblin/edit/forms.py:31 +#: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 +msgid "Seperate tags by commas or spaces." +msgstr "" + +#: mediagoblin/edit/forms.py:33 msgid "Slug" msgstr "المسار" -#: mediagoblin/edit/forms.py:32 +#: mediagoblin/edit/forms.py:34 msgid "The slug can't be empty" msgstr "لا يمكن ترك المسار فارغًا" -#: mediagoblin/edit/forms.py:33 +#: mediagoblin/edit/forms.py:35 msgid "" "The title part of this media's URL. You usually don't need to change this." msgstr "" "الجزء الذي يمثل عنوان الملف في المسار. لا حاجة إلى تغيير محتوى هذه الخانة " "عادةً." -#: mediagoblin/edit/forms.py:40 +#: mediagoblin/edit/forms.py:42 msgid "Bio" msgstr "السيرة" -#: mediagoblin/edit/forms.py:43 +#: mediagoblin/edit/forms.py:45 msgid "Website" msgstr "الموقع الإلكتروني" -#: mediagoblin/edit/views.py:64 +#: mediagoblin/edit/forms.py:49 +msgid "Old password" +msgstr "" + +#: mediagoblin/edit/forms.py:52 +msgid "New Password" +msgstr "" + +#: mediagoblin/edit/views.py:65 msgid "An entry with that slug already exists for this user." msgstr "يوجد ملف آخر بهذا المسار لدى هذى المستخدم." -#: mediagoblin/edit/views.py:85 +#: mediagoblin/edit/views.py:86 msgid "You are editing another user's media. Proceed with caution." msgstr "أنت تحرّر وسائط مستخدم آخر. كن حذرًا أثناء العملية." -#: mediagoblin/edit/views.py:155 +#: mediagoblin/edit/views.py:156 msgid "You are editing a user's profile. Proceed with caution." msgstr "أنت تحرّر ملف مستخدم آخر. كن حذرًا أثناء العملية." -#: mediagoblin/process_media/errors.py:44 -msgid "Invalid file given for media type." +#: mediagoblin/edit/views.py:171 +msgid "Wrong password" +msgstr "" + +#: mediagoblin/edit/views.py:192 +msgid "Profile edited!" +msgstr "" + +#: mediagoblin/media_types/__init__.py:61 +msgid "Could not find any file extension in \"{filename}\"" msgstr "" #: mediagoblin/submit/forms.py:25 @@ -136,18 +168,18 @@ msgstr "الملف" msgid "Description of this work" msgstr "وصف هذا العمل." -#: mediagoblin/submit/views.py:46 +#: mediagoblin/submit/views.py:49 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:121 +#: mediagoblin/submit/views.py:127 msgid "Woohoo! Submitted!" msgstr "يا سلام! نُشرَت!" +#: mediagoblin/submit/views.py:133 +msgid "Invalid file type." +msgstr "" + #: mediagoblin/templates/mediagoblin/404.html:21 msgid "Oops!" msgstr "ويحي!" @@ -167,29 +199,29 @@ msgstr "" msgid "Image of 404 goblin stressing out" msgstr "صورة قزم مرتبك" -#: mediagoblin/templates/mediagoblin/base.html:22 -msgid "GNU MediaGoblin" -msgstr "غنو ميدياغوبلن" - -#: mediagoblin/templates/mediagoblin/base.html:47 +#: mediagoblin/templates/mediagoblin/base.html:49 msgid "MediaGoblin logo" msgstr "شعار ميدياغوبلن" -#: mediagoblin/templates/mediagoblin/base.html:52 +#: mediagoblin/templates/mediagoblin/base.html:54 msgid "Submit media" msgstr "أرسل وسائط" -#: mediagoblin/templates/mediagoblin/base.html:63 -msgid "verify your email!" -msgstr "أكّد بريدك" +#: mediagoblin/templates/mediagoblin/base.html:65 +msgid "Verify your email!" +msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:73 +#: mediagoblin/templates/mediagoblin/base.html:72 +msgid "log out" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:75 #: mediagoblin/templates/mediagoblin/auth/login.html:27 -#: mediagoblin/templates/mediagoblin/auth/login.html:35 +#: mediagoblin/templates/mediagoblin/auth/login.html:45 msgid "Log in" msgstr "لِج" -#: mediagoblin/templates/mediagoblin/base.html:89 +#: mediagoblin/templates/mediagoblin/base.html:91 msgid "" "Powered by MediaGoblin, a GNU project" @@ -200,61 +232,32 @@ msgid "Explore" msgstr "" #: mediagoblin/templates/mediagoblin/root.html:27 -msgid "Hi there, media lover! MediaGoblin is..." -msgstr "مرحبًا بكم يا محبي الوسائط! ميدياغوبلن هو..." +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:28 +msgid "Your finest source for all goblin-related media." +msgstr "" #: mediagoblin/templates/mediagoblin/root.html:29 -msgid "The perfect place for your media!" -msgstr "المكان الأنسب لوسائطك!" - -#: mediagoblin/templates/mediagoblin/root.html:30 msgid "" -"A place for people to collaborate and show off original and derived " -"creations!" -msgstr "مكان يجتمع فيه الناس ليتعاونوا ويعرضوا إبداعاتهم الأصلية والمقتبسة!" +"To add your own media, place comments, save your favourites and more, you " +"can log in with your MediaGoblin account." +msgstr "" #: mediagoblin/templates/mediagoblin/root.html:31 -msgid "" -"Free, as in freedom. (We’re a GNU project, " -"after all.)" -msgstr "مشروع حر، فنحن أحد مشاريع غنو." +msgid "Don't have one yet? It's easy!" +msgstr "" #: mediagoblin/templates/mediagoblin/root.html:32 -msgid "" -"Aiming to make the world a better place through decentralization and " -"(eventually, coming soon!) federation!" -msgstr "مشروع يحاول جعل عالمنا أفضل عن طريق اللامركزية (قريبًا!)." - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "" -"Built for extensibility. (Multiple media types coming soon to the software," -" including video support!)" -msgstr "" -"جاهز للتمدد. (سيُضاف دعم أنساق كثيرة من الوسائط قريبًا، كما سندعم الفيديو!)." - -#: mediagoblin/templates/mediagoblin/root.html:34 -msgid "" -"Powered by people like you. (You can help us improve this" -" software!)" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Excited to join us?" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:39 #, python-format msgid "" -"Create a free account\n" +"Create an account at this site\n" " or\n" -" Set up MediaGoblin on your own server" +" Set up MediaGoblin on your own server" msgstr "" -"أنشئ حسابًا مجانيًا\n" -" أو\n" -" ركّب ميدياغوبلن على خادومك الخاص" -#: mediagoblin/templates/mediagoblin/root.html:53 +#: mediagoblin/templates/mediagoblin/root.html:44 msgid "Most recent media" msgstr "أحدث الوسائط" @@ -262,9 +265,13 @@ msgstr "أحدث الوسائط" msgid "Enter your new password" msgstr "أدخل كلمة سرك الجديدة" -#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:29 -msgid "Enter your username or email" -msgstr "أدخل اسم المستخدم أو بريدك الإلكتروني" +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 +msgid "Recover password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:30 +msgid "Send instructions" +msgstr "" #: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 msgid "Your password has been changed. Try to log in now." @@ -300,22 +307,18 @@ msgstr "" msgid "Logging in failed!" msgstr "فشل الولوج!" -#: mediagoblin/templates/mediagoblin/auth/login.html:43 +#: mediagoblin/templates/mediagoblin/auth/login.html:35 msgid "Don't have an account yet?" msgstr "ألا تملك حسابًا بعد؟" -#: mediagoblin/templates/mediagoblin/auth/login.html:46 +#: mediagoblin/templates/mediagoblin/auth/login.html:36 msgid "Create one here!" msgstr "أنشئ حسابًا هنا!" -#: mediagoblin/templates/mediagoblin/auth/login.html:49 +#: mediagoblin/templates/mediagoblin/auth/login.html:42 msgid "Forgot your password?" msgstr "أنسيت كلمة سرك؟" -#: mediagoblin/templates/mediagoblin/auth/login.html:52 -msgid "Change it!" -msgstr "غيّرها!" - #: mediagoblin/templates/mediagoblin/auth/register.html:27 msgid "Create an account!" msgstr "أنشئ حسابًا!" @@ -361,9 +364,15 @@ msgstr "احفظ التغييرات" 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:30 +#: mediagoblin/templates/mediagoblin/listings/tag.html:35 +#, python-format +msgid "Media tagged with: %(tag_name)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:19 +msgid "Original" +msgstr "" #: mediagoblin/templates/mediagoblin/submit/start.html:26 msgid "Submit yer media" @@ -373,16 +382,16 @@ msgstr "انشر وسائطك" msgid "Submit" msgstr "أرسل" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:32 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 +#, python-format +msgid "%(username)s's media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:37 #, python-format msgid "%(username)s's media" msgstr "وسائط %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:52 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:32 -msgid "Sorry, no such user found." -msgstr "عذرًا، تعذر العثور على مستخدم بهذا الاسم." - #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -413,35 +422,45 @@ msgstr "لا توجد وسائط تحت المعالجة" msgid "These uploads failed to process:" msgstr "فشلت معالجة هذه الملفات:" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:39 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:59 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:31 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:89 +#, python-format +msgid "%(username)s's profile" +msgstr "ملف %(username)s الشخصي" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:43 +msgid "Sorry, no such user found." +msgstr "عذرًا، تعذر العثور على مستخدم بهذا الاسم." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:50 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:70 msgid "Email verification needed" msgstr "يجب التحقق من البريد الإلكتروني" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:42 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:53 msgid "Almost done! Your account still needs to be activated." msgstr "أوشكنا على الانتهاء! ما زال حسابك بحاجة إلى التفعيل." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:58 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 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 msgid "In case it doesn't:" msgstr "إن لم تصل." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:54 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:65 msgid "Resend verification email" msgstr "أعد إرسال رسالة التحقق" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:73 msgid "" "Someone has registered an account with this username, but it still has to be" " activated." msgstr "سجّل أحدهم حسابًا بهذا الاسم، ولكننا بانتظار التفعيل حتى الآن." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:79 #, python-format msgid "" "If you are that person but you've lost your verification email, you can الولوج وإعادة إرسالها." -#: 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:85 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 msgid "Here's a spot to tell others about yourself." msgstr "هذه زاوية لتخبر الآخرين فيها عن نفسك." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:90 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:108 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:101 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:119 msgid "Edit profile" msgstr "حرِّر الملف الشخصي" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:107 msgid "This user hasn't filled in their profile (yet)." msgstr "لم يعبئ هذا العضو بيانات ملفه بعد." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:122 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:133 #, python-format msgid "View all of %(username)s's media" msgstr "أظهِر كل وسائط %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:135 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:146 msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." msgstr "هنا ستظهر وسائطك، ولكن يبدو أنك لم تضف شيئًا بعد." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:141 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:152 msgid "Add media" msgstr "أضف وسائط" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:147 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:158 msgid "There doesn't seem to be any media here yet..." msgstr "لا يبدو أنه توجد أي وسائط هنا حتى الآن..." @@ -503,6 +517,14 @@ msgstr "الأحدث" msgid "Older" msgstr "الأقدم" +#: mediagoblin/templates/mediagoblin/utils/tags.html:20 +msgid "Tagged with" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/tags.html:25 +msgid "and" +msgstr "" + #: mediagoblin/user_pages/forms.py:24 msgid "Comment" msgstr "علِّق" @@ -511,15 +533,23 @@ msgstr "علِّق" msgid "I am sure I want to delete this" msgstr "أنا متأكد من رغبتي بحذف هذا العمل" -#: mediagoblin/user_pages/views.py:142 +#: mediagoblin/user_pages/views.py:155 msgid "Empty comments are not allowed." msgstr "" -#: mediagoblin/user_pages/views.py:148 +#: mediagoblin/user_pages/views.py:161 msgid "Comment posted!" msgstr "" -#: mediagoblin/user_pages/views.py:181 +#: mediagoblin/user_pages/views.py:183 +msgid "You deleted the media." +msgstr "" + +#: mediagoblin/user_pages/views.py:190 +msgid "The media was not deleted because you didn't check that you were sure." +msgstr "" + +#: mediagoblin/user_pages/views.py:198 msgid "You are about to delete another user's media. Proceed with caution." msgstr "أنت على وشك حذف وسائط مستخدم آخر. كن حذرًا أثناء العملية." diff --git a/mediagoblin/i18n/ca/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/ca/LC_MESSAGES/mediagoblin.po index e2cd8342..f07ab2d6 100644 --- a/mediagoblin/i18n/ca/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/ca/LC_MESSAGES/mediagoblin.po @@ -3,13 +3,14 @@ # This file is distributed under the same license as the PROJECT project. # # Translators: +# Al fred , 2011. # , 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-11-01 23:14-0500\n" -"PO-Revision-Date: 2011-11-02 04:13+0000\n" +"POT-Creation-Date: 2011-11-27 15:25-0600\n" +"PO-Revision-Date: 2011-11-27 21:28+0000\n" "Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -19,6 +20,10 @@ msgstr "" "Language: ca\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" +#: mediagoblin/processing.py:143 +msgid "Invalid file given for media type." +msgstr "Aquest tipus de fitxer no és vàlid." + #: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 msgid "Username" msgstr "Nom d'usuari" @@ -52,8 +57,8 @@ msgid "Sorry, a user with that name already exists." msgstr "Lamentablement aquest usuari ja existeix." #: mediagoblin/auth/views.py:77 -msgid "Sorry, that email address has already been taken." -msgstr "Disculpeu, aquesta adreça electrònica ja s'està utilitzant." +msgid "Sorry, a user with that email address already exists." +msgstr "" #: mediagoblin/auth/views.py:179 msgid "" @@ -68,11 +73,19 @@ msgid "The verification key or user id is incorrect" msgstr "" "La clau de verificació o la identificació de l'usuari no són correctes." -#: mediagoblin/auth/views.py:207 +#: mediagoblin/auth/views.py:203 +msgid "You must be logged in so we know who to send the email to!" +msgstr "" + +#: mediagoblin/auth/views.py:211 +msgid "You've already verified your email address!" +msgstr "" + +#: mediagoblin/auth/views.py:224 msgid "Resent your verification email." msgstr "Torna'm a enviar el correu de verificació" -#: mediagoblin/auth/views.py:248 +#: mediagoblin/auth/views.py:265 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." @@ -86,42 +99,62 @@ msgstr "Títol" msgid "Tags" msgstr "Etiquetes" -#: mediagoblin/edit/forms.py:31 -msgid "Slug" -msgstr "" - -#: mediagoblin/edit/forms.py:32 -msgid "The slug can't be empty" +#: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 +msgid "Seperate tags by commas or spaces." msgstr "" #: mediagoblin/edit/forms.py:33 +msgid "Slug" +msgstr "" + +#: mediagoblin/edit/forms.py:34 +msgid "The slug can't be empty" +msgstr "" + +#: mediagoblin/edit/forms.py:35 msgid "" "The title part of this media's URL. You usually don't need to change this." msgstr "" -#: mediagoblin/edit/forms.py:40 +#: mediagoblin/edit/forms.py:42 msgid "Bio" msgstr "Biografia" -#: mediagoblin/edit/forms.py:43 +#: mediagoblin/edit/forms.py:45 msgid "Website" msgstr "Lloc web" -#: mediagoblin/edit/views.py:64 +#: mediagoblin/edit/forms.py:49 +msgid "Old password" +msgstr "" + +#: mediagoblin/edit/forms.py:52 +msgid "New Password" +msgstr "" + +#: mediagoblin/edit/views.py:65 msgid "An entry with that slug already exists for this user." msgstr "" -#: mediagoblin/edit/views.py:85 +#: mediagoblin/edit/views.py:86 msgid "You are editing another user's media. Proceed with caution." msgstr "Esteu editant fitxers d'un altre usuari. Aneu amb compte." -#: mediagoblin/edit/views.py:155 +#: mediagoblin/edit/views.py:156 msgid "You are editing a user's profile. Proceed with caution." msgstr "Esteu editant el perfil d'un usuari. Aneu amb compte" -#: mediagoblin/process_media/errors.py:44 -msgid "Invalid file given for media type." -msgstr "Aquest tipus de fitxer no és vàlid." +#: mediagoblin/edit/views.py:171 +msgid "Wrong password" +msgstr "" + +#: mediagoblin/edit/views.py:192 +msgid "Profile edited!" +msgstr "" + +#: mediagoblin/media_types/__init__.py:61 +msgid "Could not find any file extension in \"{filename}\"" +msgstr "" #: mediagoblin/submit/forms.py:25 msgid "File" @@ -131,18 +164,18 @@ msgstr "Fitxer" msgid "Description of this work" msgstr "" -#: mediagoblin/submit/views.py:46 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "Heu d'escollir un fitxer." -#: mediagoblin/submit/views.py:49 -msgid "The file doesn't seem to be an image!" -msgstr "El fitxer no és una imatge" - -#: mediagoblin/submit/views.py:121 +#: mediagoblin/submit/views.py:127 msgid "Woohoo! Submitted!" msgstr "Visca! S'ha enviat!" +#: mediagoblin/submit/views.py:133 +msgid "Invalid file type." +msgstr "" + #: mediagoblin/templates/mediagoblin/404.html:21 msgid "Oops!" msgstr "Ups!" @@ -161,31 +194,31 @@ msgstr "" #: mediagoblin/templates/mediagoblin/404.html:32 msgid "Image of 404 goblin stressing out" -msgstr "" +msgstr "Imatge de la pantalla 404, el goblin no sap què fer..." -#: mediagoblin/templates/mediagoblin/base.html:22 -msgid "GNU MediaGoblin" -msgstr "GNU MediaGoblin" - -#: mediagoblin/templates/mediagoblin/base.html:47 +#: mediagoblin/templates/mediagoblin/base.html:49 msgid "MediaGoblin logo" msgstr "Logo de mediagoblin" -#: mediagoblin/templates/mediagoblin/base.html:52 +#: mediagoblin/templates/mediagoblin/base.html:54 msgid "Submit media" msgstr "Envia fitxers" -#: mediagoblin/templates/mediagoblin/base.html:63 -msgid "verify your email!" -msgstr "verifiqueu el correu electrònic" +#: mediagoblin/templates/mediagoblin/base.html:65 +msgid "Verify your email!" +msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:73 +#: mediagoblin/templates/mediagoblin/base.html:72 +msgid "log out" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:75 #: mediagoblin/templates/mediagoblin/auth/login.html:27 -#: mediagoblin/templates/mediagoblin/auth/login.html:35 +#: mediagoblin/templates/mediagoblin/auth/login.html:45 msgid "Log in" msgstr "Entra" -#: mediagoblin/templates/mediagoblin/base.html:89 +#: mediagoblin/templates/mediagoblin/base.html:91 msgid "" "Powered by MediaGoblin, a GNU project" @@ -196,66 +229,32 @@ msgid "Explore" msgstr "" #: mediagoblin/templates/mediagoblin/root.html:27 -msgid "Hi there, media lover! MediaGoblin is..." -msgstr "Ei, fanàtic multimèdia! MediaGoblin és..." +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:28 +msgid "Your finest source for all goblin-related media." +msgstr "" #: mediagoblin/templates/mediagoblin/root.html:29 -msgid "The perfect place for your media!" -msgstr "El lloc fitxer pels teus fitxers!" - -#: mediagoblin/templates/mediagoblin/root.html:30 msgid "" -"A place for people to collaborate and show off original and derived " -"creations!" +"To add your own media, place comments, save your favourites and more, you " +"can log in with your MediaGoblin account." msgstr "" -"Un lloc en el qual les persones poden col·laborar i mostrar les seves " -"creacions originals o obres derivades." #: mediagoblin/templates/mediagoblin/root.html:31 -msgid "" -"Free, as in freedom. (We’re a GNU project, " -"after all.)" +msgid "Don't have one yet? It's easy!" msgstr "" #: mediagoblin/templates/mediagoblin/root.html:32 -msgid "" -"Aiming to make the world a better place through decentralization and " -"(eventually, coming soon!) federation!" -msgstr "" -"Amb l'objectiu de fer del món un lloc millor a través de la " -"descentralització i (eventualment, aviat disponible!) La federació!" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "" -"Built for extensibility. (Multiple media types coming soon to the software," -" including video support!)" -msgstr "" -"Construït per l'ampliació. (Múltiples tipus de fitxers en breu amb el " -"programari, incloent el suport de vídeo!)" - -#: mediagoblin/templates/mediagoblin/root.html:34 -msgid "" -"Powered by people like you. (You can help us improve this" -" software!)" -msgstr "" -"Desenvolupat per persones com vostè. ( Podeu ajudar a millorar " -"aquest programari! )" - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Excited to join us?" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:39 #, python-format msgid "" -"Create a free account\n" +"Create an account at this site\n" " or\n" -" Set up MediaGoblin on your own server" +" Set up MediaGoblin on your own server" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:53 +#: mediagoblin/templates/mediagoblin/root.html:44 msgid "Most recent media" msgstr "" @@ -263,8 +262,12 @@ msgstr "" msgid "Enter your new password" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:29 -msgid "Enter your username or email" +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 +msgid "Recover password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:30 +msgid "Send instructions" msgstr "" #: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 @@ -294,22 +297,18 @@ msgstr "" msgid "Logging in failed!" msgstr "Inici de sessió ha fallat!" -#: mediagoblin/templates/mediagoblin/auth/login.html:43 +#: mediagoblin/templates/mediagoblin/auth/login.html:35 msgid "Don't have an account yet?" msgstr "Encara no teniu un compte?" -#: mediagoblin/templates/mediagoblin/auth/login.html:46 +#: mediagoblin/templates/mediagoblin/auth/login.html:36 msgid "Create one here!" msgstr "Creeu-ne un aquí!" -#: mediagoblin/templates/mediagoblin/auth/login.html:49 +#: mediagoblin/templates/mediagoblin/auth/login.html:42 msgid "Forgot your password?" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/login.html:52 -msgid "Change it!" -msgstr "" - #: mediagoblin/templates/mediagoblin/auth/register.html:27 msgid "Create an account!" msgstr "Creeu un compte!" @@ -355,9 +354,15 @@ msgstr "Desa els canvis" msgid "Editing %(username)s's profile" msgstr "" -#: mediagoblin/templates/mediagoblin/listings/tag.html:31 -msgid "Media tagged with:" -msgstr "Etiquetat amb:" +#: mediagoblin/templates/mediagoblin/listings/tag.html:30 +#: mediagoblin/templates/mediagoblin/listings/tag.html:35 +#, python-format +msgid "Media tagged with: %(tag_name)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:19 +msgid "Original" +msgstr "" #: mediagoblin/templates/mediagoblin/submit/start.html:26 msgid "Submit yer media" @@ -367,16 +372,16 @@ msgstr "Envieu els vostres fitxers" msgid "Submit" msgstr "Envia" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:32 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 +#, python-format +msgid "%(username)s's media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:37 #, python-format msgid "%(username)s's media" msgstr "%(username)s's media" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:52 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:32 -msgid "Sorry, no such user found." -msgstr "Lamentablement no s'ha trobat l'usuari que cercàveu." - #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -397,7 +402,7 @@ msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:28 msgid "Media in-processing" -msgstr "" +msgstr "S'està processant el fitxer" #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:46 msgid "No media in-processing" @@ -405,37 +410,49 @@ msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:50 msgid "These uploads failed to process:" +msgstr "No s'han pogut penjar els següents fitxers:" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:31 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:89 +#, python-format +msgid "%(username)s's profile" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:39 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:59 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:43 +msgid "Sorry, no such user found." +msgstr "Lamentablement no s'ha trobat l'usuari que cercàveu." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:50 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:70 msgid "Email verification needed" -msgstr "" +msgstr "Cal que verifiqueu l'adreça electrònica" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:42 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:53 msgid "Almost done! Your account still needs to be activated." -msgstr "" +msgstr "Gairebé esteu! Tan sols falta que activeu el vostre compte" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:58 msgid "" "An email should arrive in a few moments with instructions on how to do so." msgstr "Us hauria d'arribar un correu amb les instruccions per a fer-ho." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:51 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 msgid "In case it doesn't:" -msgstr "" +msgstr "Per si no hi fos:" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:54 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:65 msgid "Resend verification email" msgstr "Torna'm a enviar el correu de verificació" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:73 msgid "" "Someone has registered an account with this username, but it still has to be" " activated." msgstr "" +"Algú ja ha registrat un compte amb aquest nom d'usuari, però encara l'ha " +"d'activar." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:79 #, python-format msgid "" "If you are that person but you've lost your verification email, you can entrar i tornar-lo a enviar." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:78 -#, python-format -msgid "%(username)s's profile" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/user.html:85 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 msgid "Here's a spot to tell others about yourself." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:90 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:108 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:101 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:119 msgid "Edit profile" msgstr "Edita el perfil" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:107 msgid "This user hasn't filled in their profile (yet)." -msgstr "" +msgstr "Aquest usuari encara no ha escrit res al seu perfil." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:122 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:133 #, python-format msgid "View all of %(username)s's media" msgstr "View all of %(username)s's media" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:135 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:146 msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:141 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:152 msgid "Add media" -msgstr "" +msgstr "Tots els fitxers" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:147 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:158 msgid "There doesn't seem to be any media here yet..." msgstr "" #: mediagoblin/templates/mediagoblin/utils/feed_link.html:21 msgid "feed icon" -msgstr "" +msgstr "Icona RSS" #: mediagoblin/templates/mediagoblin/utils/feed_link.html:23 msgid "Atom feed" @@ -497,6 +509,14 @@ msgstr "" msgid "Older" msgstr "" +#: mediagoblin/templates/mediagoblin/utils/tags.html:20 +msgid "Tagged with" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/tags.html:25 +msgid "and" +msgstr "" + #: mediagoblin/user_pages/forms.py:24 msgid "Comment" msgstr "Comentari" @@ -505,15 +525,23 @@ msgstr "Comentari" msgid "I am sure I want to delete this" msgstr "" -#: mediagoblin/user_pages/views.py:142 +#: mediagoblin/user_pages/views.py:155 msgid "Empty comments are not allowed." msgstr "" -#: mediagoblin/user_pages/views.py:148 +#: mediagoblin/user_pages/views.py:161 msgid "Comment posted!" msgstr "" -#: mediagoblin/user_pages/views.py:181 +#: mediagoblin/user_pages/views.py:183 +msgid "You deleted the media." +msgstr "" + +#: mediagoblin/user_pages/views.py:190 +msgid "The media was not deleted because you didn't check that you were sure." +msgstr "" + +#: mediagoblin/user_pages/views.py:198 msgid "You are about to delete another user's media. Proceed with caution." msgstr "" diff --git a/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.po index 5c4ef0d0..f5907eda 100644 --- a/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.po @@ -6,6 +6,7 @@ # , 2011. # , 2011. # Elrond , 2011. +# , 2011. # Jan-Christoph Borchardt , 2011. # , 2011. # , 2011. @@ -15,9 +16,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-11-01 23:14-0500\n" -"PO-Revision-Date: 2011-11-02 15:18+0000\n" -"Last-Translator: piratenpanda \n" +"POT-Creation-Date: 2011-11-27 15:25-0600\n" +"PO-Revision-Date: 2011-11-27 21:28+0000\n" +"Last-Translator: cwebber \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" @@ -26,6 +27,10 @@ msgstr "" "Language: de\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" +#: mediagoblin/processing.py:143 +msgid "Invalid file given for media type." +msgstr "Die Datei stimmt nicht mit dem gewählten Medientyp überein." + #: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 msgid "Username" msgstr "Benutzername" @@ -48,43 +53,52 @@ msgstr "Hier nochmal eintragen, um Tippfehler zu verhindern." #: mediagoblin/auth/forms.py:42 msgid "Email address" -msgstr "Email-Adresse" +msgstr "E-Mail-Adresse" #: mediagoblin/auth/views.py:55 msgid "Sorry, registration is disabled on this instance." -msgstr "Registrierung ist auf dieser Instanz leider deaktiviert." +msgstr "Das Registrieren ist auf dieser Instanz leider deaktiviert." #: mediagoblin/auth/views.py:73 msgid "Sorry, a user with that name already exists." msgstr "Leider gibt es bereits einen Benutzer mit diesem Namen." #: mediagoblin/auth/views.py:77 -msgid "Sorry, that email address has already been taken." -msgstr "Tut und Leid, aber diese Email-Adresse wird bereits verwendet." +msgid "Sorry, a user with that email address already exists." +msgstr "" #: mediagoblin/auth/views.py:179 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 " +"Deine E-Mail-Adresse wurde bestätigt. Du kannst dich nun anmelden, Dein " "Profil bearbeiten und Bilder hochladen!" #: mediagoblin/auth/views.py:185 msgid "The verification key or user id is incorrect" -msgstr "Der Bestätigungssschlüssel oder die Nutzernummer ist falsch." +msgstr "Der Bestätigungsschlüssel oder die Nutzernummer ist falsch." -#: mediagoblin/auth/views.py:207 +#: mediagoblin/auth/views.py:203 +msgid "You must be logged in so we know who to send the email to!" +msgstr "" + +#: mediagoblin/auth/views.py:211 +msgid "You've already verified your email address!" +msgstr "" + +#: mediagoblin/auth/views.py:224 msgid "Resent your verification email." -msgstr "Bestätigungs-Email wurde erneut versandt." +msgstr "Bestätigungs-E-Mail wurde erneut versandt." -#: mediagoblin/auth/views.py:248 +#: mediagoblin/auth/views.py:265 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." msgstr "" -"Konnte Email zur Wiederherstellung des Passworts nicht senden, weil dein " -"Benutzername inaktiv oder deine Email-Adresse noch nicht verifiziert ist." +"E-Mail zur Wiederherstellung des Passworts konnte nicht gesendet werden, " +"weil dein Benutzername inaktiv oder deine E-Mail-Adresse noch nicht " +"verifiziert ist." #: mediagoblin/edit/forms.py:24 mediagoblin/submit/forms.py:27 msgid "Title" @@ -94,44 +108,64 @@ msgstr "Titel" msgid "Tags" msgstr "Markierungen" -#: mediagoblin/edit/forms.py:31 +#: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 +msgid "Seperate tags by commas or spaces." +msgstr "" + +#: mediagoblin/edit/forms.py:33 msgid "Slug" msgstr "Kurztitel" -#: mediagoblin/edit/forms.py:32 +#: mediagoblin/edit/forms.py:34 msgid "The slug can't be empty" msgstr "Bitte gib einen Kurztitel ein" -#: mediagoblin/edit/forms.py:33 +#: mediagoblin/edit/forms.py:35 msgid "" "The title part of this media's URL. You usually don't need to change this." msgstr "" "Der Titelteil der Medienadresse. Normalerweise muss hier nichts geändert " "werden." -#: mediagoblin/edit/forms.py:40 +#: mediagoblin/edit/forms.py:42 msgid "Bio" msgstr "Biographie" -#: mediagoblin/edit/forms.py:43 +#: mediagoblin/edit/forms.py:45 msgid "Website" msgstr "Webseite" -#: mediagoblin/edit/views.py:64 +#: mediagoblin/edit/forms.py:49 +msgid "Old password" +msgstr "" + +#: mediagoblin/edit/forms.py:52 +msgid "New Password" +msgstr "" + +#: mediagoblin/edit/views.py:65 msgid "An entry with that slug already exists for this user." msgstr "Diesen Kurztitel hast du bereits vergeben." -#: mediagoblin/edit/views.py:85 +#: mediagoblin/edit/views.py:86 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:155 +#: mediagoblin/edit/views.py:156 msgid "You are editing a user's profile. Proceed with caution." msgstr "Du bearbeitest das Profil eines Anderen. Bitte sei vorsichtig." -#: mediagoblin/process_media/errors.py:44 -msgid "Invalid file given for media type." -msgstr "Die Datei stimmt nicht mit dem gewählten Medientyp überein." +#: mediagoblin/edit/views.py:171 +msgid "Wrong password" +msgstr "" + +#: mediagoblin/edit/views.py:192 +msgid "Profile edited!" +msgstr "" + +#: mediagoblin/media_types/__init__.py:61 +msgid "Could not find any file extension in \"{filename}\"" +msgstr "" #: mediagoblin/submit/forms.py:25 msgid "File" @@ -141,18 +175,18 @@ msgstr "Datei" msgid "Description of this work" msgstr "Beschreibung des Werkes" -#: mediagoblin/submit/views.py:46 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "Du musst eine Datei angeben." -#: mediagoblin/submit/views.py:49 -msgid "The file doesn't seem to be an image!" -msgstr "Diese Datei scheint kein Bild zu sein!" - -#: mediagoblin/submit/views.py:121 +#: mediagoblin/submit/views.py:127 msgid "Woohoo! Submitted!" msgstr "Yeeeaaah! Geschafft!" +#: mediagoblin/submit/views.py:133 +msgid "Invalid file type." +msgstr "" + #: mediagoblin/templates/mediagoblin/404.html:21 msgid "Oops!" msgstr "Hoppla!" @@ -173,29 +207,29 @@ msgstr "" msgid "Image of 404 goblin stressing out" msgstr "Bild eines angespannten Goblins" -#: mediagoblin/templates/mediagoblin/base.html:22 -msgid "GNU MediaGoblin" -msgstr "GNU MediaGoblin" - -#: mediagoblin/templates/mediagoblin/base.html:47 +#: mediagoblin/templates/mediagoblin/base.html:49 msgid "MediaGoblin logo" msgstr "MediaGoblin-Logo" -#: mediagoblin/templates/mediagoblin/base.html:52 +#: mediagoblin/templates/mediagoblin/base.html:54 msgid "Submit media" msgstr "Medien hochladen" -#: mediagoblin/templates/mediagoblin/base.html:63 -msgid "verify your email!" -msgstr "Bitte bestätige deine Email-Adresse!" +#: mediagoblin/templates/mediagoblin/base.html:65 +msgid "Verify your email!" +msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:73 +#: mediagoblin/templates/mediagoblin/base.html:72 +msgid "log out" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:75 #: mediagoblin/templates/mediagoblin/auth/login.html:27 -#: mediagoblin/templates/mediagoblin/auth/login.html:35 +#: mediagoblin/templates/mediagoblin/auth/login.html:45 msgid "Log in" msgstr "Anmelden" -#: mediagoblin/templates/mediagoblin/base.html:89 +#: mediagoblin/templates/mediagoblin/base.html:91 msgid "" "Powered by MediaGoblin, a GNU project" @@ -208,71 +242,32 @@ msgid "Explore" msgstr "Entdecke" #: mediagoblin/templates/mediagoblin/root.html:27 -msgid "Hi there, media lover! MediaGoblin is..." -msgstr "Hallo Medien-Liebhaber! MediaGoblin ist …" +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:28 +msgid "Your finest source for all goblin-related media." +msgstr "" #: mediagoblin/templates/mediagoblin/root.html:29 -msgid "The perfect place for your media!" -msgstr "Der perfekte Platz für deine Medien!" - -#: mediagoblin/templates/mediagoblin/root.html:30 msgid "" -"A place for people to collaborate and show off original and derived " -"creations!" +"To add your own media, place comments, save your favourites and more, you " +"can log in with your MediaGoblin account." msgstr "" -"Ein Platz für Zusammenarbeit und um Originale und abgeleitete Werke zu " -"präsentieren!" #: mediagoblin/templates/mediagoblin/root.html:31 -msgid "" -"Free, as in freedom. (We’re a GNU project, " -"after all.)" +msgid "Don't have one yet? It's easy!" msgstr "" -"Frei, wie in Freiheit. (Wir sind schließlich ein GNU-Projekt.)" #: mediagoblin/templates/mediagoblin/root.html:32 -msgid "" -"Aiming to make the world a better place through decentralization and " -"(eventually, coming soon!) federation!" -msgstr "" -"Weltverbesserer durch Dezentralisierung und (hoffentlich bald!) unabhängige " -"Kommunikation!" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "" -"Built for extensibility. (Multiple media types coming soon to the software," -" including video support!)" -msgstr "" -"Gebaut für Erweiterungen. (Bald mit Unterstützung für verschiedene " -"Medientypen inklusive Videos!)" - -#: mediagoblin/templates/mediagoblin/root.html:34 -msgid "" -"Powered by people like you. (You can help us improve this" -" software!)" -msgstr "" -"Betrieben von Leuten wie dir. (Du kannst uns dabei helfen, " -"die Software zu verbessern!)" - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Excited to join us?" -msgstr "Neugierig dich uns anzuschließen?" - -#: mediagoblin/templates/mediagoblin/root.html:39 #, python-format msgid "" -"Create a free account\n" +"Create an account at this site\n" " or\n" -" Set up MediaGoblin on your own server" +" Set up MediaGoblin on your own server" msgstr "" -"Gratis ein Konto einrichten\n" -" or\n" -" MediaGoblin auf deinem eigenen Server einrichten" -#: mediagoblin/templates/mediagoblin/root.html:53 +#: mediagoblin/templates/mediagoblin/root.html:44 msgid "Most recent media" msgstr "Neuste Medien" @@ -280,9 +275,13 @@ msgstr "Neuste Medien" msgid "Enter your new password" msgstr "Neues Passwort eingeben" -#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:29 -msgid "Enter your username or email" -msgstr "Benutzername oder Email-Adresse eingeben" +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 +msgid "Recover password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:30 +msgid "Send instructions" +msgstr "" #: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 msgid "Your password has been changed. Try to log in now." @@ -292,8 +291,8 @@ msgstr "Dein Passwort wurde geändert. Versuche dich jetzt einzuloggen." msgid "" "Check your inbox. We sent an email with a URL for changing your password." msgstr "" -"Prüfe deinen Posteingang. Wir haben dir eine Email mit einem Link geschickt," -" mit dem du dein Passwort ändern kannst." +"Überprüfe deinen Posteingang. Wir haben dir eine E-Mail mit einem Link " +"geschickt, mit dem du dein Passwort ändern kannst." #: mediagoblin/templates/mediagoblin/auth/fp_verification_email.txt:19 #, python-format @@ -314,28 +313,24 @@ msgstr "" "\n" "%(verification_url)s\n" "\n" -"Wenn du denkst, dass das ein Fehler ist, ignoriere einfach diese Email und bleib ein glücklicher Goblin!" +"Wenn du denkst, dass das ein Fehler ist, ignoriere einfach diese E-Mail und bleib ein glücklicher Goblin!" #: mediagoblin/templates/mediagoblin/auth/login.html:30 msgid "Logging in failed!" msgstr "Anmeldevorgang fehlgeschlagen!" -#: mediagoblin/templates/mediagoblin/auth/login.html:43 +#: mediagoblin/templates/mediagoblin/auth/login.html:35 msgid "Don't have an account yet?" msgstr "Hast du noch kein Konto?" -#: mediagoblin/templates/mediagoblin/auth/login.html:46 +#: mediagoblin/templates/mediagoblin/auth/login.html:36 msgid "Create one here!" msgstr "Registriere dich hier!" -#: mediagoblin/templates/mediagoblin/auth/login.html:49 +#: mediagoblin/templates/mediagoblin/auth/login.html:42 msgid "Forgot your password?" msgstr "Passwort vergessen?" -#: mediagoblin/templates/mediagoblin/auth/login.html:52 -msgid "Change it!" -msgstr "Wechsle es!" - #: mediagoblin/templates/mediagoblin/auth/register.html:27 msgid "Create an account!" msgstr "Neues Konto registrieren!" @@ -356,7 +351,7 @@ msgid "" msgstr "" "Hallo %(username)s,\n" "\n" -"um dein Konto bei GNU MediaGoblin zu aktivieren, musst du folgende Adresse in einem Webbrowser öffnen:\n" +"um dein Konto bei GNU MediaGoblin zu aktivieren, musst du folgende Adresse in deinem Webbrowser öffnen:\n" "\n" "%(verification_url)s" @@ -380,9 +375,15 @@ msgstr "Änderungen speichern" msgid "Editing %(username)s's profile" msgstr "%(username)ss Profil bearbeiten" -#: mediagoblin/templates/mediagoblin/listings/tag.html:31 -msgid "Media tagged with:" -msgstr "Medien markiert mit:" +#: mediagoblin/templates/mediagoblin/listings/tag.html:30 +#: mediagoblin/templates/mediagoblin/listings/tag.html:35 +#, python-format +msgid "Media tagged with: %(tag_name)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:19 +msgid "Original" +msgstr "" #: mediagoblin/templates/mediagoblin/submit/start.html:26 msgid "Submit yer media" @@ -392,16 +393,16 @@ msgstr "Medien hochladen" msgid "Submit" msgstr "Bestätigen" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:32 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 +#, python-format +msgid "%(username)s's media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:37 #, python-format msgid "%(username)s's media" msgstr "%(username)ss Medien" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:52 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:32 -msgid "Sorry, no such user found." -msgstr "Dieser Benutzer wurde leider nicht gefunden." - #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -434,31 +435,41 @@ msgstr "Keine Medien in Bearbeitung" msgid "These uploads failed to process:" msgstr "Die folgenden Uploads sind fehlgeschlagen:" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:39 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:59 -msgid "Email verification needed" -msgstr "Email-Bestätigung benötigt" +#: mediagoblin/templates/mediagoblin/user_pages/user.html:31 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:89 +#, python-format +msgid "%(username)s's profile" +msgstr "%(username)ss Profil" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:42 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:43 +msgid "Sorry, no such user found." +msgstr "Dieser Benutzer konnte leider nicht gefunden werden." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:50 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:70 +msgid "Email verification needed" +msgstr "E-Mail-Bestätigung benötigt" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:53 msgid "Almost done! Your account still needs to be activated." msgstr "Fast fertig! Dein Konto muss noch freigeschaltet werden." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:58 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." +"Gleich solltest du eine E-Mail erhalten, die dir erklärt, was du noch machen" +" musst." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:51 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 msgid "In case it doesn't:" msgstr "Wenn sie nicht ankommt:" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:54 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:65 msgid "Resend verification email" msgstr "Bestätigung erneut senden" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:73 msgid "" "Someone has registered an account with this username, but it still has to be" " activated." @@ -466,7 +477,7 @@ msgstr "" "Jemand hat bereits ein Konto mit diesem Benutzernamen registriert, aber es " "muss noch aktiviert werden." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:79 #, python-format msgid "" "If you are that person but you've lost your verification email, you can anmelden und sie erneut " "senden." -#: 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:85 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 msgid "Here's a spot to tell others about yourself." msgstr "Hier kannst du Anderen etwas über dich erzählen." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:90 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:108 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:101 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:119 msgid "Edit profile" msgstr "Profil bearbeiten" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:107 msgid "This user hasn't filled in their profile (yet)." msgstr "Dieser Benutzer hat (noch) keine Daten in seinem Profil." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:122 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:133 #, python-format msgid "View all of %(username)s's media" msgstr "Alle Medien von %(username)s anschauen" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:135 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:146 msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." msgstr "Hier erscheinen deine Medien. Sobald du etwas hochgeladen hast." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:141 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:152 msgid "Add media" msgstr "Medien hinzufügen" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:147 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:158 msgid "There doesn't seem to be any media here yet..." msgstr "Scheinbar gibt es hier noch nichts …" @@ -529,6 +535,14 @@ msgstr "Neuere" msgid "Older" msgstr "Ältere" +#: mediagoblin/templates/mediagoblin/utils/tags.html:20 +msgid "Tagged with" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/tags.html:25 +msgid "and" +msgstr "" + #: mediagoblin/user_pages/forms.py:24 msgid "Comment" msgstr "Kommentar" @@ -537,15 +551,23 @@ msgstr "Kommentar" msgid "I am sure I want to delete this" msgstr "Ja, wirklich löschen" -#: mediagoblin/user_pages/views.py:142 +#: mediagoblin/user_pages/views.py:155 msgid "Empty comments are not allowed." msgstr "Leere Kommentare sind nicht erlaubt." -#: mediagoblin/user_pages/views.py:148 +#: mediagoblin/user_pages/views.py:161 msgid "Comment posted!" msgstr "Kommentar hinzugefügt!" -#: mediagoblin/user_pages/views.py:181 +#: mediagoblin/user_pages/views.py:183 +msgid "You deleted the media." +msgstr "" + +#: mediagoblin/user_pages/views.py:190 +msgid "The media was not deleted because you didn't check that you were sure." +msgstr "" + +#: mediagoblin/user_pages/views.py:198 msgid "You are about to delete another user's media. Proceed with caution." msgstr "Du versuchst Medien eines anderen Nutzers zu löschen. Sei vorsichtig." diff --git a/mediagoblin/i18n/en/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/en/LC_MESSAGES/mediagoblin.po index f3e0c100..c1f3fd7f 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-11-01 23:14-0500\n" +"POT-Creation-Date: 2011-11-27 15:25-0600\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,6 +17,10 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 0.9.6\n" +#: mediagoblin/processing.py:143 +msgid "Invalid file given for media type." +msgstr "" + #: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 msgid "Username" msgstr "" @@ -50,7 +54,7 @@ msgid "Sorry, a user with that name already exists." msgstr "" #: mediagoblin/auth/views.py:77 -msgid "Sorry, that email address has already been taken." +msgid "Sorry, a user with that email address already exists." msgstr "" #: mediagoblin/auth/views.py:179 @@ -89,40 +93,60 @@ msgstr "" msgid "Tags" msgstr "" -#: mediagoblin/edit/forms.py:31 -msgid "Slug" -msgstr "" - -#: mediagoblin/edit/forms.py:32 -msgid "The slug can't be empty" +#: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 +msgid "Seperate tags by commas or spaces." msgstr "" #: mediagoblin/edit/forms.py:33 +msgid "Slug" +msgstr "" + +#: mediagoblin/edit/forms.py:34 +msgid "The slug can't be empty" +msgstr "" + +#: mediagoblin/edit/forms.py:35 msgid "The title part of this media's URL. You usually don't need to change this." msgstr "" -#: mediagoblin/edit/forms.py:40 +#: mediagoblin/edit/forms.py:42 msgid "Bio" msgstr "" -#: mediagoblin/edit/forms.py:43 +#: mediagoblin/edit/forms.py:45 msgid "Website" msgstr "" -#: mediagoblin/edit/views.py:64 +#: mediagoblin/edit/forms.py:49 +msgid "Old password" +msgstr "" + +#: mediagoblin/edit/forms.py:52 +msgid "New Password" +msgstr "" + +#: mediagoblin/edit/views.py:65 msgid "An entry with that slug already exists for this user." msgstr "" -#: mediagoblin/edit/views.py:85 +#: mediagoblin/edit/views.py:86 msgid "You are editing another user's media. Proceed with caution." msgstr "" -#: mediagoblin/edit/views.py:155 +#: mediagoblin/edit/views.py:156 msgid "You are editing a user's profile. Proceed with caution." msgstr "" -#: mediagoblin/process_media/errors.py:44 -msgid "Invalid file given for media type." +#: mediagoblin/edit/views.py:171 +msgid "Wrong password" +msgstr "" + +#: mediagoblin/edit/views.py:192 +msgid "Profile edited!" +msgstr "" + +#: mediagoblin/media_types/__init__.py:61 +msgid "Could not find any file extension in \"{filename}\"" msgstr "" #: mediagoblin/submit/forms.py:25 @@ -133,16 +157,16 @@ msgstr "" msgid "Description of this work" msgstr "" -#: mediagoblin/submit/views.py:46 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "" -#: mediagoblin/submit/views.py:49 -msgid "The file doesn't seem to be an image!" +#: mediagoblin/submit/views.py:127 +msgid "Woohoo! Submitted!" msgstr "" -#: mediagoblin/submit/views.py:121 -msgid "Woohoo! Submitted!" +#: mediagoblin/submit/views.py:133 +msgid "Invalid file type." msgstr "" #: mediagoblin/templates/mediagoblin/404.html:21 @@ -163,29 +187,29 @@ msgstr "" msgid "Image of 404 goblin stressing out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:22 -msgid "GNU MediaGoblin" -msgstr "" - -#: mediagoblin/templates/mediagoblin/base.html:47 +#: mediagoblin/templates/mediagoblin/base.html:49 msgid "MediaGoblin logo" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:52 +#: mediagoblin/templates/mediagoblin/base.html:54 msgid "Submit media" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:63 -msgid "verify your email!" +#: mediagoblin/templates/mediagoblin/base.html:65 +msgid "Verify your email!" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:73 +#: mediagoblin/templates/mediagoblin/base.html:72 +msgid "log out" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:75 #: mediagoblin/templates/mediagoblin/auth/login.html:27 -#: mediagoblin/templates/mediagoblin/auth/login.html:35 +#: mediagoblin/templates/mediagoblin/auth/login.html:45 msgid "Log in" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:89 +#: mediagoblin/templates/mediagoblin/base.html:91 msgid "" "Powered by MediaGoblin, a GNU project" @@ -196,60 +220,35 @@ msgid "Explore" msgstr "" #: mediagoblin/templates/mediagoblin/root.html:27 -msgid "Hi there, media lover! MediaGoblin is..." +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:28 +msgid "Your finest source for all goblin-related media." msgstr "" #: mediagoblin/templates/mediagoblin/root.html:29 -msgid "The perfect place for your media!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:30 msgid "" -"A place for people to collaborate and show off original and derived " -"creations!" +"To add your own media, place comments, save your favourites and more, you" +" can log in with your MediaGoblin account." msgstr "" #: mediagoblin/templates/mediagoblin/root.html:31 -msgid "" -"Free, as in freedom. (We’re a GNU project," -" after all.)" +msgid "Don't have one yet? It's easy!" msgstr "" #: mediagoblin/templates/mediagoblin/root.html:32 -msgid "" -"Aiming to make the world a better place through decentralization and " -"(eventually, coming soon!) federation!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "" -"Built for extensibility. (Multiple media types coming soon to the " -"software, including video support!)" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:34 -msgid "" -"Powered by people like you. (You can help us improve " -"this software!)" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Excited to join us?" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:39 #, python-format msgid "" -"Create a " -"free account\n" +"Create an " +"account at this site\n" " or\n" -" Set up MediaGoblin on " "your own server" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:53 +#: mediagoblin/templates/mediagoblin/root.html:44 msgid "Most recent media" msgstr "" @@ -257,8 +256,12 @@ msgstr "" msgid "Enter your new password" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:29 -msgid "Enter your username or email" +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 +msgid "Recover password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:30 +msgid "Send instructions" msgstr "" #: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 @@ -287,22 +290,18 @@ msgstr "" msgid "Logging in failed!" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/login.html:43 +#: mediagoblin/templates/mediagoblin/auth/login.html:35 msgid "Don't have an account yet?" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/login.html:46 +#: mediagoblin/templates/mediagoblin/auth/login.html:36 msgid "Create one here!" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/login.html:49 +#: mediagoblin/templates/mediagoblin/auth/login.html:42 msgid "Forgot your password?" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/login.html:52 -msgid "Change it!" -msgstr "" - #: mediagoblin/templates/mediagoblin/auth/register.html:27 msgid "Create an account!" msgstr "" @@ -342,8 +341,14 @@ msgstr "" msgid "Editing %(username)s's profile" msgstr "" -#: mediagoblin/templates/mediagoblin/listings/tag.html:31 -msgid "Media tagged with:" +#: mediagoblin/templates/mediagoblin/listings/tag.html:30 +#: mediagoblin/templates/mediagoblin/listings/tag.html:35 +#, python-format +msgid "Media tagged with: %(tag_name)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:19 +msgid "Original" msgstr "" #: mediagoblin/templates/mediagoblin/submit/start.html:26 @@ -354,14 +359,14 @@ msgstr "" msgid "Submit" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:32 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format -msgid "%(username)s's media" +msgid "%(username)s's media" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:52 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:32 -msgid "Sorry, no such user found." +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:37 +#, python-format +msgid "%(username)s's media" msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 @@ -393,74 +398,79 @@ msgstr "" msgid "These uploads failed to process:" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:39 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:59 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:31 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:89 +#, python-format +msgid "%(username)s's profile" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:43 +msgid "Sorry, no such user found." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:50 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:70 msgid "Email verification needed" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:42 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:53 msgid "Almost done! Your account still needs to be activated." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:58 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 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 msgid "In case it doesn't:" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:54 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:65 msgid "Resend verification email" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:73 msgid "" "Someone has registered an account with this username, but it still has to" " be activated." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:79 #, python-format msgid "" "If you are that person but you've lost your verification email, you can " "log in and resend it." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:78 -#, python-format -msgid "%(username)s's profile" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/user.html:85 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 msgid "Here's a spot to tell others about yourself." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:90 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:108 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:101 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:119 msgid "Edit profile" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:107 msgid "This user hasn't filled in their profile (yet)." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:122 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:133 #, python-format msgid "View all of %(username)s's media" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:135 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:146 msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:141 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:152 msgid "Add media" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:147 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:158 msgid "There doesn't seem to be any media here yet..." msgstr "" @@ -480,6 +490,14 @@ msgstr "" msgid "Older" msgstr "" +#: mediagoblin/templates/mediagoblin/utils/tags.html:20 +msgid "Tagged with" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/tags.html:25 +msgid "and" +msgstr "" + #: mediagoblin/user_pages/forms.py:24 msgid "Comment" msgstr "" @@ -488,15 +506,23 @@ msgstr "" msgid "I am sure I want to delete this" msgstr "" -#: mediagoblin/user_pages/views.py:142 +#: mediagoblin/user_pages/views.py:155 msgid "Empty comments are not allowed." msgstr "" -#: mediagoblin/user_pages/views.py:148 +#: mediagoblin/user_pages/views.py:161 msgid "Comment posted!" msgstr "" -#: mediagoblin/user_pages/views.py:181 +#: mediagoblin/user_pages/views.py:183 +msgid "You deleted the media." +msgstr "" + +#: mediagoblin/user_pages/views.py:190 +msgid "The media was not deleted because you didn't check that you were sure." +msgstr "" + +#: mediagoblin/user_pages/views.py:198 msgid "You are about to delete another user's media. Proceed with caution." msgstr "" diff --git a/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.po index f6bb1cce..2cffe874 100644 --- a/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.po @@ -10,8 +10,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-11-01 23:14-0500\n" -"PO-Revision-Date: 2011-11-02 04:13+0000\n" +"POT-Creation-Date: 2011-11-27 15:25-0600\n" +"PO-Revision-Date: 2011-11-27 21:28+0000\n" "Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -21,6 +21,10 @@ msgstr "" "Language: eo\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" +#: mediagoblin/processing.py:143 +msgid "Invalid file given for media type." +msgstr "La provizita dosiero ne konformas al la informtipo." + #: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 msgid "Username" msgstr "Uzantnomo" @@ -54,8 +58,8 @@ msgid "Sorry, a user with that name already exists." msgstr "Bedaŭrinde, uzanto kun tiu nomo jam ekzistas." #: mediagoblin/auth/views.py:77 -msgid "Sorry, that email address has already been taken." -msgstr "Tiu retpoŝtadreso jam estas uzata." +msgid "Sorry, a user with that email address already exists." +msgstr "" #: mediagoblin/auth/views.py:179 msgid "" @@ -69,11 +73,19 @@ msgstr "" msgid "The verification key or user id is incorrect" msgstr "La kontrol-kodo aŭ la uzantonomo ne estas korekta" -#: mediagoblin/auth/views.py:207 +#: mediagoblin/auth/views.py:203 +msgid "You must be logged in so we know who to send the email to!" +msgstr "" + +#: mediagoblin/auth/views.py:211 +msgid "You've already verified your email address!" +msgstr "" + +#: mediagoblin/auth/views.py:224 msgid "Resent your verification email." msgstr "Resendi vian kontrol-mesaĝon." -#: mediagoblin/auth/views.py:248 +#: mediagoblin/auth/views.py:265 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." @@ -89,44 +101,64 @@ msgstr "Titolo" msgid "Tags" msgstr "Etikedoj" -#: mediagoblin/edit/forms.py:31 +#: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 +msgid "Seperate tags by commas or spaces." +msgstr "" + +#: mediagoblin/edit/forms.py:33 msgid "Slug" msgstr "La distingiga adresparto" -#: mediagoblin/edit/forms.py:32 +#: mediagoblin/edit/forms.py:34 msgid "The slug can't be empty" msgstr "La distingiga adresparto ne povas esti malplena" -#: mediagoblin/edit/forms.py:33 +#: mediagoblin/edit/forms.py:35 msgid "" "The title part of this media's URL. You usually don't need to change this." msgstr "" "La parto de la dosieradreso, bazita sur la dosiertitolo. Ordinare ne necesas" " ĝin ŝanĝi." -#: mediagoblin/edit/forms.py:40 +#: mediagoblin/edit/forms.py:42 msgid "Bio" msgstr "Bio" -#: mediagoblin/edit/forms.py:43 +#: mediagoblin/edit/forms.py:45 msgid "Website" msgstr "Retejo" -#: mediagoblin/edit/views.py:64 +#: mediagoblin/edit/forms.py:49 +msgid "Old password" +msgstr "" + +#: mediagoblin/edit/forms.py:52 +msgid "New Password" +msgstr "" + +#: mediagoblin/edit/views.py:65 msgid "An entry with that slug already exists for this user." msgstr "Ĉi tiu uzanto jam havas dosieron kun tiu distingiga adresparto." -#: mediagoblin/edit/views.py:85 +#: mediagoblin/edit/views.py:86 msgid "You are editing another user's media. Proceed with caution." msgstr "Vi priredaktas dosieron de alia uzanto. Agu singardeme." -#: mediagoblin/edit/views.py:155 +#: mediagoblin/edit/views.py:156 msgid "You are editing a user's profile. Proceed with caution." msgstr "Vi redaktas profilon de alia uzanto. Agu singardeme." -#: mediagoblin/process_media/errors.py:44 -msgid "Invalid file given for media type." -msgstr "La provizita dosiero ne konformas al la informtipo." +#: mediagoblin/edit/views.py:171 +msgid "Wrong password" +msgstr "" + +#: mediagoblin/edit/views.py:192 +msgid "Profile edited!" +msgstr "" + +#: mediagoblin/media_types/__init__.py:61 +msgid "Could not find any file extension in \"{filename}\"" +msgstr "" #: mediagoblin/submit/forms.py:25 msgid "File" @@ -136,18 +168,18 @@ msgstr "Dosiero" msgid "Description of this work" msgstr "Priskribo de ĉi tiu verko" -#: mediagoblin/submit/views.py:46 +#: mediagoblin/submit/views.py:49 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 "La dosiero ŝajnas ne esti bildo!" - -#: mediagoblin/submit/views.py:121 +#: mediagoblin/submit/views.py:127 msgid "Woohoo! Submitted!" msgstr "Hura! Alŝutitas!" +#: mediagoblin/submit/views.py:133 +msgid "Invalid file type." +msgstr "" + #: mediagoblin/templates/mediagoblin/404.html:21 msgid "Oops!" msgstr "Oj!" @@ -168,29 +200,29 @@ msgstr "" msgid "Image of 404 goblin stressing out" msgstr "Bildo de 404-koboldo penŝvitanta." -#: mediagoblin/templates/mediagoblin/base.html:22 -msgid "GNU MediaGoblin" -msgstr "GNU MediaGoblin" - -#: mediagoblin/templates/mediagoblin/base.html:47 +#: mediagoblin/templates/mediagoblin/base.html:49 msgid "MediaGoblin logo" msgstr "Emblemo de MediaGoblin" -#: mediagoblin/templates/mediagoblin/base.html:52 +#: mediagoblin/templates/mediagoblin/base.html:54 msgid "Submit media" msgstr "Alŝuti aŭd-vid-dosieron" -#: mediagoblin/templates/mediagoblin/base.html:63 -msgid "verify your email!" -msgstr "konfirmu vian retpoŝtadreson! " +#: mediagoblin/templates/mediagoblin/base.html:65 +msgid "Verify your email!" +msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:73 +#: mediagoblin/templates/mediagoblin/base.html:72 +msgid "log out" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:75 #: mediagoblin/templates/mediagoblin/auth/login.html:27 -#: mediagoblin/templates/mediagoblin/auth/login.html:35 +#: mediagoblin/templates/mediagoblin/auth/login.html:45 msgid "Log in" msgstr "Ensaluti" -#: mediagoblin/templates/mediagoblin/base.html:89 +#: mediagoblin/templates/mediagoblin/base.html:91 msgid "" "Powered by MediaGoblin, a GNU project" @@ -203,69 +235,32 @@ msgid "Explore" msgstr "" #: mediagoblin/templates/mediagoblin/root.html:27 -msgid "Hi there, media lover! MediaGoblin is..." -msgstr "Saluton, artemulo! MediaGoblin estas…" +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:28 +msgid "Your finest source for all goblin-related media." +msgstr "" #: mediagoblin/templates/mediagoblin/root.html:29 -msgid "The perfect place for your media!" -msgstr "La perfekta loko por viaj aŭd-vid-dosieroj!" - -#: mediagoblin/templates/mediagoblin/root.html:30 msgid "" -"A place for people to collaborate and show off original and derived " -"creations!" +"To add your own media, place comments, save your favourites and more, you " +"can log in with your MediaGoblin account." msgstr "" -"Loko, kie homoj povas kunlabori, kaj elmeti originalajn kreaĵojn kaj " -"derivaĵojn!" #: mediagoblin/templates/mediagoblin/root.html:31 -msgid "" -"Free, as in freedom. (We’re a GNU project, " -"after all.)" +msgid "Don't have one yet? It's easy!" msgstr "" -"Libera verko. (Ni ja estas projekto de GNU.)" #: mediagoblin/templates/mediagoblin/root.html:32 -msgid "" -"Aiming to make the world a better place through decentralization and " -"(eventually, coming soon!) federation!" -msgstr "" -"Celanta plibonigi la mondon per sencentreco kaj (iam, baldaŭ!) federateco!" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "" -"Built for extensibility. (Multiple media types coming soon to the software," -" including video support!)" -msgstr "" -"Kreita por etendado. (Baldaŭ en la programo aperos subteno de pluraj " -"informspecoj, inkluzive de filmoj!)" - -#: mediagoblin/templates/mediagoblin/root.html:34 -msgid "" -"Powered by people like you. (You can help us improve this" -" software!)" -msgstr "" -"Vivanta per homoj kiel vi. (Vi povas helpi al ni " -"plibonigi la programon!)" - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Excited to join us?" -msgstr "Ĉu vi deziregas aliĝi nin?" - -#: mediagoblin/templates/mediagoblin/root.html:39 #, python-format msgid "" -"Create a free account\n" +"Create an account at this site\n" " or\n" -" Set up MediaGoblin on your own server" +" Set up MediaGoblin on your own server" msgstr "" -"Kreu senpagan" -" konton⏎ aŭ⏎ Kreu senpagan konton" -#: mediagoblin/templates/mediagoblin/root.html:53 +#: mediagoblin/templates/mediagoblin/root.html:44 msgid "Most recent media" msgstr "Plej nove aldonitaj dosieroj" @@ -273,9 +268,13 @@ msgstr "Plej nove aldonitaj dosieroj" msgid "Enter your new password" msgstr "Enigu vian novan pasvorton" -#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:29 -msgid "Enter your username or email" -msgstr "Enigu vian salutnomon aŭ retpoŝtadreson" +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 +msgid "Recover password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:30 +msgid "Send instructions" +msgstr "" #: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 msgid "Your password has been changed. Try to log in now." @@ -313,22 +312,18 @@ msgstr "" msgid "Logging in failed!" msgstr "Ensaluto malsukcesis!" -#: mediagoblin/templates/mediagoblin/auth/login.html:43 +#: mediagoblin/templates/mediagoblin/auth/login.html:35 msgid "Don't have an account yet?" msgstr "Ĉu ankoraŭ sen konto?" -#: mediagoblin/templates/mediagoblin/auth/login.html:46 +#: mediagoblin/templates/mediagoblin/auth/login.html:36 msgid "Create one here!" msgstr "Kreu ĝin ĉi tie!" -#: mediagoblin/templates/mediagoblin/auth/login.html:49 +#: mediagoblin/templates/mediagoblin/auth/login.html:42 msgid "Forgot your password?" msgstr "Ĉu vi forgesis vian pasvorton?" -#: mediagoblin/templates/mediagoblin/auth/login.html:52 -msgid "Change it!" -msgstr "Ŝanĝu ĝin!" - #: mediagoblin/templates/mediagoblin/auth/register.html:27 msgid "Create an account!" msgstr "Kreu konton!" @@ -373,9 +368,15 @@ msgstr "Konservi ŝanĝojn" msgid "Editing %(username)s's profile" msgstr "Redaktado de l’profilo de %(username)s'" -#: mediagoblin/templates/mediagoblin/listings/tag.html:31 -msgid "Media tagged with:" -msgstr "Dosieroj markitaj per:" +#: mediagoblin/templates/mediagoblin/listings/tag.html:30 +#: mediagoblin/templates/mediagoblin/listings/tag.html:35 +#, python-format +msgid "Media tagged with: %(tag_name)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:19 +msgid "Original" +msgstr "" #: mediagoblin/templates/mediagoblin/submit/start.html:26 msgid "Submit yer media" @@ -385,16 +386,16 @@ msgstr "Alŝutu vian aŭd-vid-dosieron" msgid "Submit" msgstr "Alŝuti" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:32 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 +#, python-format +msgid "%(username)s's media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:37 #, python-format msgid "%(username)s's media" msgstr "Dosieroj de %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:52 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:32 -msgid "Sorry, no such user found." -msgstr "Uzanto ne trovita." - #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -427,30 +428,40 @@ msgstr "Neniu dosieroj preparatas" msgid "These uploads failed to process:" msgstr "Preparado de ĉi tiuj alŝutaĵoj malsukcesis:" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:39 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:59 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:31 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:89 +#, python-format +msgid "%(username)s's profile" +msgstr "Profilo de %(username)s" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:43 +msgid "Sorry, no such user found." +msgstr "Uzanto ne trovita." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:50 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:70 msgid "Email verification needed" msgstr "Necesas konfirmo de retpoŝtadreso" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:42 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:53 msgid "Almost done! Your account still needs to be activated." msgstr "Preskaŭ finite! Restas nur validigi vian konton." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:58 msgid "" "An email should arrive in a few moments with instructions on how to do so." msgstr "" "Post kelkaj momentoj devas veni retletero kun instrukcio pri kiel tion fari." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:51 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 msgid "In case it doesn't:" msgstr "Se tio ne okazas:" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:54 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:65 msgid "Resend verification email" msgstr "Resendi kontrolmesaĝon" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:73 msgid "" "Someone has registered an account with this username, but it still has to be" " activated." @@ -458,7 +469,7 @@ msgstr "" "Iu registris konton kun tiu ĉi uzantonomo, sed ĝi devas ankoraŭ esti " "aktivigita." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:79 #, python-format msgid "" "If you are that person but you've lost your verification email, you can ensaluti kaj resendi ĝin." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:78 -#, python-format -msgid "%(username)s's profile" -msgstr "Profilo de %(username)s" - -#: mediagoblin/templates/mediagoblin/user_pages/user.html:85 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 msgid "Here's a spot to tell others about yourself." msgstr "Jen estas spaceto por rakonti pri vi al aliaj." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:90 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:108 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:101 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:119 msgid "Edit profile" msgstr "Redakti profilon" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:107 msgid "This user hasn't filled in their profile (yet)." msgstr "Ĉi tiu uzanto ne jam aldonis informojn pri si." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:122 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:133 #, python-format msgid "View all of %(username)s's media" msgstr "Rigardi ĉiujn dosierojn de %(username)s'" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:135 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:146 msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." msgstr "" "Ĝuste ĉi tie aperos viaj dosieroj, sed vi ŝajne ankoraŭ nenion alŝutis." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:141 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:152 msgid "Add media" msgstr "Aldoni dosieron" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:147 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:158 msgid "There doesn't seem to be any media here yet..." msgstr "Ĉi tie ŝajne estas ankoraŭ neniuj dosieroj…" @@ -521,6 +527,14 @@ msgstr "Plinovaj" msgid "Older" msgstr "Malplinovaj" +#: mediagoblin/templates/mediagoblin/utils/tags.html:20 +msgid "Tagged with" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/tags.html:25 +msgid "and" +msgstr "" + #: mediagoblin/user_pages/forms.py:24 msgid "Comment" msgstr "Komento" @@ -529,15 +543,23 @@ msgstr "Komento" msgid "I am sure I want to delete this" msgstr "Mi estas certa, ke mi volas forigi ĉi tion" -#: mediagoblin/user_pages/views.py:142 +#: mediagoblin/user_pages/views.py:155 msgid "Empty comments are not allowed." -msgstr "" +msgstr "Malplenaj komentoj ne estas afiŝeblaj." -#: mediagoblin/user_pages/views.py:148 +#: mediagoblin/user_pages/views.py:161 msgid "Comment posted!" +msgstr "La komento estas afiŝita!" + +#: mediagoblin/user_pages/views.py:183 +msgid "You deleted the media." msgstr "" -#: mediagoblin/user_pages/views.py:181 +#: mediagoblin/user_pages/views.py:190 +msgid "The media was not deleted because you didn't check that you were sure." +msgstr "" + +#: mediagoblin/user_pages/views.py:198 msgid "You are about to delete another user's media. Proceed with caution." msgstr "Vi estas forigonta dosieron de alia uzanto. Estu singardema." diff --git a/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.po index a3c9939b..6ab070af 100644 --- a/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.po @@ -14,8 +14,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-11-01 23:14-0500\n" -"PO-Revision-Date: 2011-11-02 04:13+0000\n" +"POT-Creation-Date: 2011-11-27 15:25-0600\n" +"PO-Revision-Date: 2011-11-27 21:28+0000\n" "Last-Translator: cwebber \n" "Language-Team: Spanish (Castilian) (http://www.transifex.net/projects/p/mediagoblin/team/es/)\n" "MIME-Version: 1.0\n" @@ -25,6 +25,10 @@ msgstr "" "Language: es\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" +#: mediagoblin/processing.py:143 +msgid "Invalid file given for media type." +msgstr "Archivo inválido para el formato seleccionado." + #: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 msgid "Username" msgstr "Nombre de usuario" @@ -59,8 +63,8 @@ msgid "Sorry, a user with that name already exists." msgstr "Lo sentimos, ya existe un usuario con ese nombre." #: mediagoblin/auth/views.py:77 -msgid "Sorry, that email address has already been taken." -msgstr "Lo sentimos, esa dirección de correo electrónico ya ha sido tomada." +msgid "Sorry, a user with that email address already exists." +msgstr "" #: mediagoblin/auth/views.py:179 msgid "" @@ -75,11 +79,19 @@ msgid "The verification key or user id is incorrect" msgstr "" "La clave de verificación o la identificación de usuario son incorrectas" -#: mediagoblin/auth/views.py:207 +#: mediagoblin/auth/views.py:203 +msgid "You must be logged in so we know who to send the email to!" +msgstr "" + +#: mediagoblin/auth/views.py:211 +msgid "You've already verified your email address!" +msgstr "" + +#: mediagoblin/auth/views.py:224 msgid "Resent your verification email." msgstr "Se reenvió tu correo electrónico de verificación." -#: mediagoblin/auth/views.py:248 +#: mediagoblin/auth/views.py:265 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." @@ -96,44 +108,64 @@ msgstr "Título" msgid "Tags" msgstr "Etiquetas" -#: mediagoblin/edit/forms.py:31 +#: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 +msgid "Seperate tags by commas or spaces." +msgstr "" + +#: mediagoblin/edit/forms.py:33 msgid "Slug" msgstr "Ficha" -#: mediagoblin/edit/forms.py:32 +#: mediagoblin/edit/forms.py:34 msgid "The slug can't be empty" msgstr "La ficha no puede estar vacía" -#: mediagoblin/edit/forms.py:33 +#: mediagoblin/edit/forms.py:35 msgid "" "The title part of this media's URL. You usually don't need to change this." msgstr "" "La parte del título de la URL de este contenido. Normalmente no necesitas " "cambiar esto." -#: mediagoblin/edit/forms.py:40 +#: mediagoblin/edit/forms.py:42 msgid "Bio" msgstr "Bio" -#: mediagoblin/edit/forms.py:43 +#: mediagoblin/edit/forms.py:45 msgid "Website" msgstr "Sitio web" -#: mediagoblin/edit/views.py:64 +#: mediagoblin/edit/forms.py:49 +msgid "Old password" +msgstr "" + +#: mediagoblin/edit/forms.py:52 +msgid "New Password" +msgstr "" + +#: mediagoblin/edit/views.py:65 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:85 +#: mediagoblin/edit/views.py:86 msgid "You are editing another user's media. Proceed with caution." msgstr "Estás editando el contenido de otro usuario. Proceder con precaución." -#: mediagoblin/edit/views.py:155 +#: mediagoblin/edit/views.py:156 msgid "You are editing a user's profile. Proceed with caution." msgstr "Estás editando un perfil de usuario. Proceder con precaución." -#: mediagoblin/process_media/errors.py:44 -msgid "Invalid file given for media type." -msgstr "Archivo inválido para el formato seleccionado." +#: mediagoblin/edit/views.py:171 +msgid "Wrong password" +msgstr "" + +#: mediagoblin/edit/views.py:192 +msgid "Profile edited!" +msgstr "" + +#: mediagoblin/media_types/__init__.py:61 +msgid "Could not find any file extension in \"{filename}\"" +msgstr "" #: mediagoblin/submit/forms.py:25 msgid "File" @@ -143,18 +175,18 @@ msgstr "Archivo" msgid "Description of this work" msgstr "Descripción de esta obra" -#: mediagoblin/submit/views.py:46 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "Debes proporcionar un archivo." -#: mediagoblin/submit/views.py:49 -msgid "The file doesn't seem to be an image!" -msgstr "¡El archivo no parece ser una imagen!" - -#: mediagoblin/submit/views.py:121 +#: mediagoblin/submit/views.py:127 msgid "Woohoo! Submitted!" msgstr "¡Woohoo! ¡Enviado!" +#: mediagoblin/submit/views.py:133 +msgid "Invalid file type." +msgstr "" + #: mediagoblin/templates/mediagoblin/404.html:21 msgid "Oops!" msgstr "Ups!" @@ -175,29 +207,29 @@ msgstr "" msgid "Image of 404 goblin stressing out" msgstr "Imagen de 404 goblin estresándose" -#: mediagoblin/templates/mediagoblin/base.html:22 -msgid "GNU MediaGoblin" -msgstr "GNU MediaGoblin" - -#: mediagoblin/templates/mediagoblin/base.html:47 +#: mediagoblin/templates/mediagoblin/base.html:49 msgid "MediaGoblin logo" msgstr "Logo de MediaGoblin" -#: mediagoblin/templates/mediagoblin/base.html:52 +#: mediagoblin/templates/mediagoblin/base.html:54 msgid "Submit media" msgstr "Enviar contenido" -#: mediagoblin/templates/mediagoblin/base.html:63 -msgid "verify your email!" -msgstr "¡Verifica tu correo electrónico!" +#: mediagoblin/templates/mediagoblin/base.html:65 +msgid "Verify your email!" +msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:73 +#: mediagoblin/templates/mediagoblin/base.html:72 +msgid "log out" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:75 #: mediagoblin/templates/mediagoblin/auth/login.html:27 -#: mediagoblin/templates/mediagoblin/auth/login.html:35 +#: mediagoblin/templates/mediagoblin/auth/login.html:45 msgid "Log in" msgstr "Conectarse" -#: mediagoblin/templates/mediagoblin/base.html:89 +#: mediagoblin/templates/mediagoblin/base.html:91 msgid "" "Powered by MediaGoblin, a GNU project" @@ -210,71 +242,32 @@ msgid "Explore" msgstr "Explorar" #: mediagoblin/templates/mediagoblin/root.html:27 -msgid "Hi there, media lover! MediaGoblin is..." -msgstr "¡Hola, amante de los contenidos! MediaGoblin es ..." +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:28 +msgid "Your finest source for all goblin-related media." +msgstr "" #: mediagoblin/templates/mediagoblin/root.html:29 -msgid "The perfect place for your media!" -msgstr "¡El lugar ideal para tus contenidos!" - -#: mediagoblin/templates/mediagoblin/root.html:30 msgid "" -"A place for people to collaborate and show off original and derived " -"creations!" +"To add your own media, place comments, save your favourites and more, you " +"can log in with your MediaGoblin account." msgstr "" -"¡Un lugar para colaborar y exhibir tus creaciones originales y derivadas!" #: mediagoblin/templates/mediagoblin/root.html:31 -msgid "" -"Free, as in freedom. (We’re a GNU project, " -"after all.)" +msgid "Don't have one yet? It's easy!" msgstr "" -"Libre, como en la libertad. (Somos parte del proyecto GNU después de todo.)" #: mediagoblin/templates/mediagoblin/root.html:32 -msgid "" -"Aiming to make the world a better place through decentralization and " -"(eventually, coming soon!) federation!" -msgstr "" -"Queriendo hacer del mundo un mejor lugar a través de la descentralización y " -"(eventualmente, muy pronto!) la federalización!" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "" -"Built for extensibility. (Multiple media types coming soon to the software," -" including video support!)" -msgstr "" -"Pensado para ser extensible. (Prontamente soporte para multiples formatos, " -"incluyendo video!)" - -#: mediagoblin/templates/mediagoblin/root.html:34 -msgid "" -"Powered by people like you. (You can help us improve this" -" software!)" -msgstr "" -"Impulsado por gente como vos. ( Vos podés ayudarnos a " -"mejorar este programa)" - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Excited to join us?" -msgstr "Te gustaría unirte a nosotros?" - -#: mediagoblin/templates/mediagoblin/root.html:39 #, python-format msgid "" -"Create a free account\n" +"Create an account at this site\n" " or\n" -" Set up MediaGoblin on your own server" +" Set up MediaGoblin on your own server" msgstr "" -"Crea una " -"cuenta gratuita o Establece MediaGoblin en " -"tu propio servidor" -#: mediagoblin/templates/mediagoblin/root.html:53 +#: mediagoblin/templates/mediagoblin/root.html:44 msgid "Most recent media" msgstr "El contenido más reciente" @@ -282,9 +275,13 @@ msgstr "El contenido más reciente" msgid "Enter your new password" msgstr "Ingrese su nueva contraseña" -#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:29 -msgid "Enter your username or email" -msgstr "Introduzca su nombre de usuario o correo electrónico" +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 +msgid "Recover password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:30 +msgid "Send instructions" +msgstr "" #: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 msgid "Your password has been changed. Try to log in now." @@ -319,22 +316,18 @@ msgstr "" msgid "Logging in failed!" msgstr "¡Falló el inicio de sesión!" -#: mediagoblin/templates/mediagoblin/auth/login.html:43 +#: mediagoblin/templates/mediagoblin/auth/login.html:35 msgid "Don't have an account yet?" msgstr "¿No tienes una cuenta?" -#: mediagoblin/templates/mediagoblin/auth/login.html:46 +#: mediagoblin/templates/mediagoblin/auth/login.html:36 msgid "Create one here!" msgstr "¡Crea una aquí!" -#: mediagoblin/templates/mediagoblin/auth/login.html:49 +#: mediagoblin/templates/mediagoblin/auth/login.html:42 msgid "Forgot your password?" msgstr "¿Olvidaste tu contraseña?" -#: mediagoblin/templates/mediagoblin/auth/login.html:52 -msgid "Change it!" -msgstr "Cambiarlo!" - #: mediagoblin/templates/mediagoblin/auth/register.html:27 msgid "Create an account!" msgstr "¡Crea una cuenta!" @@ -379,9 +372,15 @@ msgstr "Guardar cambios" msgid "Editing %(username)s's profile" msgstr "Editando el perfil de %(username)s" -#: mediagoblin/templates/mediagoblin/listings/tag.html:31 -msgid "Media tagged with:" -msgstr "Contenido etiquetado con:" +#: mediagoblin/templates/mediagoblin/listings/tag.html:30 +#: mediagoblin/templates/mediagoblin/listings/tag.html:35 +#, python-format +msgid "Media tagged with: %(tag_name)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:19 +msgid "Original" +msgstr "" #: mediagoblin/templates/mediagoblin/submit/start.html:26 msgid "Submit yer media" @@ -391,16 +390,16 @@ msgstr "Envía tu contenido" msgid "Submit" msgstr "Enviar" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:32 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 +#, python-format +msgid "%(username)s's media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:37 #, python-format msgid "%(username)s's media" msgstr "Contenido de %(username)s's" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:52 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:32 -msgid "Sorry, no such user found." -msgstr "Lo sentimos, no se encontró ese usuario." - #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -433,31 +432,41 @@ msgstr "No hay contenido siendo procesado." msgid "These uploads failed to process:" msgstr "Estos archivos no pudieron ser procesados:" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:39 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:59 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:31 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:89 +#, python-format +msgid "%(username)s's profile" +msgstr "Perfil de %(username)s" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:43 +msgid "Sorry, no such user found." +msgstr "Lo sentimos, no se encontró ese usuario." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:50 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:70 msgid "Email verification needed" msgstr "Es necesario un correo electrónico de verificación" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:42 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:53 msgid "Almost done! Your account still needs to be activated." msgstr "Casi terminas! Solo falta activar la cuenta." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:58 msgid "" "An email should arrive in a few moments with instructions on how to do so." msgstr "" "En unos momentos te debería llegar un correo electrónico con las " "instrucciones para hacerlo." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:51 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 msgid "In case it doesn't:" msgstr "En caso de que no:" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:54 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:65 msgid "Resend verification email" msgstr "Reenviar correo electrónico de verificación" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:73 msgid "" "Someone has registered an account with this username, but it still has to be" " activated." @@ -465,7 +474,7 @@ msgstr "" "Alguien ya registró una cuenta con ese nombre de usuario, pero todavía no " "fue activada." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:79 #, python-format msgid "" "If you are that person but you've lost your verification email, you can acceder y reenviarlo." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:78 -#, python-format -msgid "%(username)s's profile" -msgstr "Perfil de %(username)s" - -#: mediagoblin/templates/mediagoblin/user_pages/user.html:85 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 msgid "Here's a spot to tell others about yourself." msgstr "Aquí hay un lugar para que le cuentes a los demás sobre tí." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:90 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:108 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:101 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:119 msgid "Edit profile" msgstr "Editar perfil" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:107 msgid "This user hasn't filled in their profile (yet)." msgstr "Este usuario (todavia) no ha completado su perfil." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:122 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:133 #, python-format msgid "View all of %(username)s's media" msgstr "Ver todo el contenido de %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:135 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:146 msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." msgstr "" "Aquí es donde tú contenido estará, pero parece que aún no has agregado nada." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:141 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:152 msgid "Add media" msgstr "Añadir contenido" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:147 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:158 msgid "There doesn't seem to be any media here yet..." msgstr "Parece que aún no hay ningún contenido aquí..." @@ -528,6 +532,14 @@ msgstr "Recientes" msgid "Older" msgstr "Antiguas" +#: mediagoblin/templates/mediagoblin/utils/tags.html:20 +msgid "Tagged with" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/tags.html:25 +msgid "and" +msgstr "" + #: mediagoblin/user_pages/forms.py:24 msgid "Comment" msgstr "Comentario" @@ -536,15 +548,23 @@ msgstr "Comentario" msgid "I am sure I want to delete this" msgstr "Estoy seguro de que quiero borrar esto" -#: mediagoblin/user_pages/views.py:142 +#: mediagoblin/user_pages/views.py:155 msgid "Empty comments are not allowed." msgstr "" -#: mediagoblin/user_pages/views.py:148 +#: mediagoblin/user_pages/views.py:161 msgid "Comment posted!" msgstr "" -#: mediagoblin/user_pages/views.py:181 +#: mediagoblin/user_pages/views.py:183 +msgid "You deleted the media." +msgstr "" + +#: mediagoblin/user_pages/views.py:190 +msgid "The media was not deleted because you didn't check that you were sure." +msgstr "" + +#: mediagoblin/user_pages/views.py:198 msgid "You are about to delete another user's media. Proceed with caution." msgstr "" "Estás a punto de eliminar un contenido de otro usuario. Proceder con " diff --git a/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.po index 0a6a5a40..b37f5217 100644 --- a/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.po @@ -13,9 +13,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-11-01 23:14-0500\n" -"PO-Revision-Date: 2011-11-04 10:05+0000\n" -"Last-Translator: chesuidayeur \n" +"POT-Creation-Date: 2011-11-27 15:25-0600\n" +"PO-Revision-Date: 2011-11-27 21:28+0000\n" +"Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -24,6 +24,10 @@ msgstr "" "Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1)\n" +#: mediagoblin/processing.py:143 +msgid "Invalid file given for media type." +msgstr "Le fichier envoyé ne correspond pas au type de média." + #: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 msgid "Username" msgstr "Nom d'utilisateur" @@ -59,8 +63,8 @@ msgid "Sorry, a user with that name already exists." msgstr "Un utilisateur existe déjà avec ce nom, désolé." #: mediagoblin/auth/views.py:77 -msgid "Sorry, that email address has already been taken." -msgstr "Désolé, cette adresse courriel a déjà été prise." +msgid "Sorry, a user with that email address already exists." +msgstr "" #: mediagoblin/auth/views.py:179 msgid "" @@ -74,11 +78,19 @@ msgstr "" 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:207 +#: mediagoblin/auth/views.py:203 +msgid "You must be logged in so we know who to send the email to!" +msgstr "" + +#: mediagoblin/auth/views.py:211 +msgid "You've already verified your email address!" +msgstr "" + +#: mediagoblin/auth/views.py:224 msgid "Resent your verification email." msgstr "E-mail de vérification renvoyé." -#: mediagoblin/auth/views.py:248 +#: mediagoblin/auth/views.py:265 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." @@ -94,48 +106,68 @@ msgstr "Titre" msgid "Tags" msgstr "Tags" -#: mediagoblin/edit/forms.py:31 +#: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 +msgid "Seperate tags by commas or spaces." +msgstr "" + +#: mediagoblin/edit/forms.py:33 msgid "Slug" msgstr "Légende" -#: mediagoblin/edit/forms.py:32 +#: mediagoblin/edit/forms.py:34 msgid "The slug can't be empty" msgstr "La légende ne peut pas être laissée vide." -#: mediagoblin/edit/forms.py:33 +#: mediagoblin/edit/forms.py:35 msgid "" "The title part of this media's URL. You usually don't need to change this." msgstr "" "Le nom de ce media dans l'URL. Vous n'avez normalement pas besoin de le " "changer" -#: mediagoblin/edit/forms.py:40 +#: mediagoblin/edit/forms.py:42 msgid "Bio" msgstr "Bio" -#: mediagoblin/edit/forms.py:43 +#: mediagoblin/edit/forms.py:45 msgid "Website" msgstr "Site web" -#: mediagoblin/edit/views.py:64 +#: mediagoblin/edit/forms.py:49 +msgid "Old password" +msgstr "" + +#: mediagoblin/edit/forms.py:52 +msgid "New Password" +msgstr "" + +#: mediagoblin/edit/views.py:65 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:85 +#: mediagoblin/edit/views.py:86 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:155 +#: mediagoblin/edit/views.py:156 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/process_media/errors.py:44 -msgid "Invalid file given for media type." -msgstr "Le fichier envoyé ne correspond pas au type de média." +#: mediagoblin/edit/views.py:171 +msgid "Wrong password" +msgstr "" + +#: mediagoblin/edit/views.py:192 +msgid "Profile edited!" +msgstr "" + +#: mediagoblin/media_types/__init__.py:61 +msgid "Could not find any file extension in \"{filename}\"" +msgstr "" #: mediagoblin/submit/forms.py:25 msgid "File" @@ -145,18 +177,18 @@ msgstr "Fichier" msgid "Description of this work" msgstr "Descriptif pour ce travail" -#: mediagoblin/submit/views.py:46 +#: mediagoblin/submit/views.py:49 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:121 +#: mediagoblin/submit/views.py:127 msgid "Woohoo! Submitted!" msgstr "Youhou, c'est envoyé !" +#: mediagoblin/submit/views.py:133 +msgid "Invalid file type." +msgstr "" + #: mediagoblin/templates/mediagoblin/404.html:21 msgid "Oops!" msgstr "Zut!" @@ -177,29 +209,29 @@ msgstr "" msgid "Image of 404 goblin stressing out" msgstr "Image de 404 gobelin angoissé" -#: mediagoblin/templates/mediagoblin/base.html:22 -msgid "GNU MediaGoblin" -msgstr "GNU MediaGoblin" - -#: mediagoblin/templates/mediagoblin/base.html:47 +#: mediagoblin/templates/mediagoblin/base.html:49 msgid "MediaGoblin logo" msgstr "Logo MediaGoblin" -#: mediagoblin/templates/mediagoblin/base.html:52 +#: mediagoblin/templates/mediagoblin/base.html:54 msgid "Submit media" msgstr "Soumettre un média" -#: mediagoblin/templates/mediagoblin/base.html:63 -msgid "verify your email!" -msgstr "vérifiez votre adresse e-mail !" +#: mediagoblin/templates/mediagoblin/base.html:65 +msgid "Verify your email!" +msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:73 +#: mediagoblin/templates/mediagoblin/base.html:72 +msgid "log out" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:75 #: mediagoblin/templates/mediagoblin/auth/login.html:27 -#: mediagoblin/templates/mediagoblin/auth/login.html:35 +#: mediagoblin/templates/mediagoblin/auth/login.html:45 msgid "Log in" msgstr "S'identifier" -#: mediagoblin/templates/mediagoblin/base.html:89 +#: mediagoblin/templates/mediagoblin/base.html:91 msgid "" "Powered by MediaGoblin, a GNU project" @@ -212,71 +244,32 @@ msgid "Explore" msgstr "Explorer" #: mediagoblin/templates/mediagoblin/root.html:27 -msgid "Hi there, media lover! MediaGoblin is..." -msgstr "Salut à tous, amateur de médias! MediaGoblin est ..." +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:28 +msgid "Your finest source for all goblin-related media." +msgstr "" #: mediagoblin/templates/mediagoblin/root.html:29 -msgid "The perfect place for your media!" -msgstr "L'endroit idéal pour vos médias!" - -#: mediagoblin/templates/mediagoblin/root.html:30 msgid "" -"A place for people to collaborate and show off original and derived " -"creations!" +"To add your own media, place comments, save your favourites and more, you " +"can log in with your MediaGoblin account." msgstr "" -"Un espace de création collaboratif : montrez vos œuvres, originales ou " -"dérivées !" #: mediagoblin/templates/mediagoblin/root.html:31 -msgid "" -"Free, as in freedom. (We’re a GNU project, " -"after all.)" +msgid "Don't have one yet? It's easy!" msgstr "" -"Logiciel libre. (Nous sommes un projet GNU " -"après tout.)" #: mediagoblin/templates/mediagoblin/root.html:32 -msgid "" -"Aiming to make the world a better place through decentralization and " -"(eventually, coming soon!) federation!" -msgstr "" -"Une tentative de rendre le monde meilleur grâce à la décentralisation et (à " -"terme, et pour bientôt !) la fédération !" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "" -"Built for extensibility. (Multiple media types coming soon to the software," -" including video support!)" -msgstr "" -"Construit pour l'extensibilité. (Plusieurs types de médias à venir au " -"logiciel, y compris le support vidéo!)" - -#: mediagoblin/templates/mediagoblin/root.html:34 -msgid "" -"Powered by people like you. (You can help us improve this" -" software!)" -msgstr "" -"Propulsé par des gens comme vous. (Vous pouvez nous aider à " -"améliorer ce logiciel!)" - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Excited to join us?" -msgstr "Envi de vous joindre à nous ?" - -#: mediagoblin/templates/mediagoblin/root.html:39 #, python-format msgid "" -"Create a free account\n" +"Create an account at this site\n" " or\n" -" Set up MediaGoblin on your own server" +" Set up MediaGoblin on your own server" msgstr "" -"Créez gratuitement en compte\n" -" ou\n" -" Installez MediaGoblin sur votre propre serveur" -#: mediagoblin/templates/mediagoblin/root.html:53 +#: mediagoblin/templates/mediagoblin/root.html:44 msgid "Most recent media" msgstr "Tout derniers media" @@ -284,9 +277,13 @@ msgstr "Tout derniers media" msgid "Enter your new password" msgstr "Entrez un nouveau mot de passe" -#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:29 -msgid "Enter your username or email" -msgstr "Entrez votre nom d'utilisateur ou votre email" +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 +msgid "Recover password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:30 +msgid "Send instructions" +msgstr "" #: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 msgid "Your password has been changed. Try to log in now." @@ -327,22 +324,18 @@ msgstr "" msgid "Logging in failed!" msgstr "La connexion a échoué!" -#: mediagoblin/templates/mediagoblin/auth/login.html:43 +#: mediagoblin/templates/mediagoblin/auth/login.html:35 msgid "Don't have an account yet?" msgstr "Pas encore de compte?" -#: mediagoblin/templates/mediagoblin/auth/login.html:46 +#: mediagoblin/templates/mediagoblin/auth/login.html:36 msgid "Create one here!" msgstr "Créez-en un ici!" -#: mediagoblin/templates/mediagoblin/auth/login.html:49 +#: mediagoblin/templates/mediagoblin/auth/login.html:42 msgid "Forgot your password?" msgstr "Vous avez oublié votre mot de passe ?" -#: mediagoblin/templates/mediagoblin/auth/login.html:52 -msgid "Change it!" -msgstr "Changez-le !" - #: mediagoblin/templates/mediagoblin/auth/register.html:27 msgid "Create an account!" msgstr "Créer un compte!" @@ -387,9 +380,15 @@ msgstr "Enregistrer les modifications" 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:30 +#: mediagoblin/templates/mediagoblin/listings/tag.html:35 +#, python-format +msgid "Media tagged with: %(tag_name)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:19 +msgid "Original" +msgstr "" #: mediagoblin/templates/mediagoblin/submit/start.html:26 msgid "Submit yer media" @@ -399,16 +398,16 @@ msgstr "Soumettez ce média" msgid "Submit" msgstr "Soumettre" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:32 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 +#, python-format +msgid "%(username)s's media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:37 #, python-format msgid "%(username)s's media" msgstr "Médias de %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:52 -#: 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/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -441,31 +440,41 @@ msgstr "Aucun média en transformation" msgid "These uploads failed to process:" msgstr "Le traitement de ces ajouts a échoué :" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:39 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:59 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:31 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:89 +#, python-format +msgid "%(username)s's profile" +msgstr "profil de %(username)s" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:43 +msgid "Sorry, no such user found." +msgstr "Impossible de trouver cet utilisateur, désolé." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:50 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:70 msgid "Email verification needed" msgstr "Vérification d'email nécessaire" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:42 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:53 msgid "Almost done! Your account still needs to be activated." msgstr "Presque fini ! Votre compte a encore besoin d'être activé." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:58 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 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 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 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:65 msgid "Resend verification email" msgstr "Renvoyer l'e-mail de vérification" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:73 msgid "" "Someone has registered an account with this username, but it still has to be" " activated." @@ -473,7 +482,7 @@ msgstr "" "Quelqu'un a enregistré un compte avec ce nom, mais il doit encore être " "activé." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:79 #, python-format msgid "" "If you are that person but you've lost your verification email, you can identifier 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:85 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 msgid "Here's a spot to tell others about yourself." msgstr "Voici un endroit pour parler aux autres de vous-même." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:90 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:108 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:101 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:119 msgid "Edit profile" msgstr "Modifier le profil" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:107 msgid "This user hasn't filled in their profile (yet)." msgstr "Cet utilisateur n'a pas (encore) rempli son profil." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:122 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:133 #, python-format msgid "View all of %(username)s's media" msgstr "Voir tous les médias de %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:135 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:146 msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." @@ -514,11 +518,11 @@ msgstr "" "C'est là où vos médias apparaîssent, mais vous ne semblez pas avoir encore " "ajouté quoi que ce soit." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:141 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:152 msgid "Add media" msgstr "Ajouter des médias" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:147 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:158 msgid "There doesn't seem to be any media here yet..." msgstr "Il ne semble pas y avoir de média là, pour l'instant ..." @@ -538,6 +542,14 @@ msgstr "Nouveaux" msgid "Older" msgstr "Anciens" +#: mediagoblin/templates/mediagoblin/utils/tags.html:20 +msgid "Tagged with" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/tags.html:25 +msgid "and" +msgstr "" + #: mediagoblin/user_pages/forms.py:24 msgid "Comment" msgstr "Commentaire" @@ -546,15 +558,23 @@ msgstr "Commentaire" msgid "I am sure I want to delete this" msgstr "Je suis sûr de vouloir supprimer cela" -#: mediagoblin/user_pages/views.py:142 +#: mediagoblin/user_pages/views.py:155 msgid "Empty comments are not allowed." msgstr "Les commentaires vides ne sont pas autorisés." -#: mediagoblin/user_pages/views.py:148 +#: mediagoblin/user_pages/views.py:161 msgid "Comment posted!" msgstr "Votre commentaire a été posté !" -#: mediagoblin/user_pages/views.py:181 +#: mediagoblin/user_pages/views.py:183 +msgid "You deleted the media." +msgstr "" + +#: mediagoblin/user_pages/views.py:190 +msgid "The media was not deleted because you didn't check that you were sure." +msgstr "" + +#: mediagoblin/user_pages/views.py:198 msgid "You are about to delete another user's media. Proceed with caution." msgstr "" "Vous êtes sur le point de supprimer des médias d'un autre utilisateur. " diff --git a/mediagoblin/i18n/ia/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/ia/LC_MESSAGES/mediagoblin.po index d9fdf8d6..a4f1f8d7 100644 --- a/mediagoblin/i18n/ia/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/ia/LC_MESSAGES/mediagoblin.po @@ -8,8 +8,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-11-01 23:14-0500\n" -"PO-Revision-Date: 2011-11-02 04:13+0000\n" +"POT-Creation-Date: 2011-11-27 15:25-0600\n" +"PO-Revision-Date: 2011-11-27 21:28+0000\n" "Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -19,6 +19,10 @@ msgstr "" "Language: ia\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" +#: mediagoblin/processing.py:143 +msgid "Invalid file given for media type." +msgstr "" + #: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 msgid "Username" msgstr "Nomine de usator" @@ -52,7 +56,7 @@ msgid "Sorry, a user with that name already exists." msgstr "" #: mediagoblin/auth/views.py:77 -msgid "Sorry, that email address has already been taken." +msgid "Sorry, a user with that email address already exists." msgstr "" #: mediagoblin/auth/views.py:179 @@ -65,11 +69,19 @@ msgstr "" msgid "The verification key or user id is incorrect" msgstr "" -#: mediagoblin/auth/views.py:207 +#: mediagoblin/auth/views.py:203 +msgid "You must be logged in so we know who to send the email to!" +msgstr "" + +#: mediagoblin/auth/views.py:211 +msgid "You've already verified your email address!" +msgstr "" + +#: mediagoblin/auth/views.py:224 msgid "Resent your verification email." msgstr "" -#: mediagoblin/auth/views.py:248 +#: mediagoblin/auth/views.py:265 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." @@ -83,41 +95,61 @@ msgstr "Titulo" msgid "Tags" msgstr "" -#: mediagoblin/edit/forms.py:31 -msgid "Slug" -msgstr "" - -#: mediagoblin/edit/forms.py:32 -msgid "The slug can't be empty" +#: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 +msgid "Seperate tags by commas or spaces." msgstr "" #: mediagoblin/edit/forms.py:33 +msgid "Slug" +msgstr "" + +#: mediagoblin/edit/forms.py:34 +msgid "The slug can't be empty" +msgstr "" + +#: mediagoblin/edit/forms.py:35 msgid "" "The title part of this media's URL. You usually don't need to change this." msgstr "" -#: mediagoblin/edit/forms.py:40 +#: mediagoblin/edit/forms.py:42 msgid "Bio" msgstr "" -#: mediagoblin/edit/forms.py:43 +#: mediagoblin/edit/forms.py:45 msgid "Website" msgstr "Sito web" -#: mediagoblin/edit/views.py:64 +#: mediagoblin/edit/forms.py:49 +msgid "Old password" +msgstr "" + +#: mediagoblin/edit/forms.py:52 +msgid "New Password" +msgstr "" + +#: mediagoblin/edit/views.py:65 msgid "An entry with that slug already exists for this user." msgstr "" -#: mediagoblin/edit/views.py:85 +#: mediagoblin/edit/views.py:86 msgid "You are editing another user's media. Proceed with caution." msgstr "" -#: mediagoblin/edit/views.py:155 +#: mediagoblin/edit/views.py:156 msgid "You are editing a user's profile. Proceed with caution." msgstr "" -#: mediagoblin/process_media/errors.py:44 -msgid "Invalid file given for media type." +#: mediagoblin/edit/views.py:171 +msgid "Wrong password" +msgstr "" + +#: mediagoblin/edit/views.py:192 +msgid "Profile edited!" +msgstr "" + +#: mediagoblin/media_types/__init__.py:61 +msgid "Could not find any file extension in \"{filename}\"" msgstr "" #: mediagoblin/submit/forms.py:25 @@ -128,16 +160,16 @@ msgstr "" msgid "Description of this work" msgstr "" -#: mediagoblin/submit/views.py:46 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "" -#: mediagoblin/submit/views.py:49 -msgid "The file doesn't seem to be an image!" +#: mediagoblin/submit/views.py:127 +msgid "Woohoo! Submitted!" msgstr "" -#: mediagoblin/submit/views.py:121 -msgid "Woohoo! Submitted!" +#: mediagoblin/submit/views.py:133 +msgid "Invalid file type." msgstr "" #: mediagoblin/templates/mediagoblin/404.html:21 @@ -158,29 +190,29 @@ msgstr "" msgid "Image of 404 goblin stressing out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:22 -msgid "GNU MediaGoblin" -msgstr "" - -#: mediagoblin/templates/mediagoblin/base.html:47 +#: mediagoblin/templates/mediagoblin/base.html:49 msgid "MediaGoblin logo" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:52 +#: mediagoblin/templates/mediagoblin/base.html:54 msgid "Submit media" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:63 -msgid "verify your email!" +#: mediagoblin/templates/mediagoblin/base.html:65 +msgid "Verify your email!" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:73 +#: mediagoblin/templates/mediagoblin/base.html:72 +msgid "log out" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:75 #: mediagoblin/templates/mediagoblin/auth/login.html:27 -#: mediagoblin/templates/mediagoblin/auth/login.html:35 +#: mediagoblin/templates/mediagoblin/auth/login.html:45 msgid "Log in" msgstr "Initiar session" -#: mediagoblin/templates/mediagoblin/base.html:89 +#: mediagoblin/templates/mediagoblin/base.html:91 msgid "" "Powered by MediaGoblin, a GNU project" @@ -191,57 +223,32 @@ msgid "Explore" msgstr "" #: mediagoblin/templates/mediagoblin/root.html:27 -msgid "Hi there, media lover! MediaGoblin is..." +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:28 +msgid "Your finest source for all goblin-related media." msgstr "" #: mediagoblin/templates/mediagoblin/root.html:29 -msgid "The perfect place for your media!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:30 msgid "" -"A place for people to collaborate and show off original and derived " -"creations!" +"To add your own media, place comments, save your favourites and more, you " +"can log in with your MediaGoblin account." msgstr "" #: mediagoblin/templates/mediagoblin/root.html:31 -msgid "" -"Free, as in freedom. (We’re a GNU project, " -"after all.)" +msgid "Don't have one yet? It's easy!" msgstr "" #: mediagoblin/templates/mediagoblin/root.html:32 -msgid "" -"Aiming to make the world a better place through decentralization and " -"(eventually, coming soon!) federation!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "" -"Built for extensibility. (Multiple media types coming soon to the software," -" including video support!)" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:34 -msgid "" -"Powered by people like you. (You can help us improve this" -" software!)" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Excited to join us?" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:39 #, python-format msgid "" -"Create a free account\n" +"Create an account at this site\n" " or\n" -" Set up MediaGoblin on your own server" +" Set up MediaGoblin on your own server" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:53 +#: mediagoblin/templates/mediagoblin/root.html:44 msgid "Most recent media" msgstr "" @@ -249,8 +256,12 @@ msgstr "" msgid "Enter your new password" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:29 -msgid "Enter your username or email" +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 +msgid "Recover password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:30 +msgid "Send instructions" msgstr "" #: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 @@ -280,22 +291,18 @@ msgstr "" msgid "Logging in failed!" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/login.html:43 +#: mediagoblin/templates/mediagoblin/auth/login.html:35 msgid "Don't have an account yet?" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/login.html:46 +#: mediagoblin/templates/mediagoblin/auth/login.html:36 msgid "Create one here!" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/login.html:49 +#: mediagoblin/templates/mediagoblin/auth/login.html:42 msgid "Forgot your password?" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/login.html:52 -msgid "Change it!" -msgstr "" - #: mediagoblin/templates/mediagoblin/auth/register.html:27 msgid "Create an account!" msgstr "Crear un conto!" @@ -335,8 +342,14 @@ msgstr "" msgid "Editing %(username)s's profile" msgstr "" -#: mediagoblin/templates/mediagoblin/listings/tag.html:31 -msgid "Media tagged with:" +#: mediagoblin/templates/mediagoblin/listings/tag.html:30 +#: mediagoblin/templates/mediagoblin/listings/tag.html:35 +#, python-format +msgid "Media tagged with: %(tag_name)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:19 +msgid "Original" msgstr "" #: mediagoblin/templates/mediagoblin/submit/start.html:26 @@ -347,14 +360,14 @@ msgstr "" msgid "Submit" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:32 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format -msgid "%(username)s's media" +msgid "%(username)s's media" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:52 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:32 -msgid "Sorry, no such user found." +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:37 +#, python-format +msgid "%(username)s's media" msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 @@ -387,75 +400,80 @@ msgstr "" msgid "These uploads failed to process:" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:39 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:59 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:31 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:89 +#, python-format +msgid "%(username)s's profile" +msgstr "Profilo de %(username)s" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:43 +msgid "Sorry, no such user found." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:50 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:70 msgid "Email verification needed" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:42 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:53 msgid "Almost done! Your account still needs to be activated." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:58 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 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 msgid "In case it doesn't:" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:54 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:65 msgid "Resend verification email" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:73 msgid "" "Someone has registered an account with this username, but it still has to be" " activated." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:79 #, python-format msgid "" "If you are that person but you've lost your verification email, you can log in and resend it." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:78 -#, python-format -msgid "%(username)s's profile" -msgstr "Profilo de %(username)s" - -#: mediagoblin/templates/mediagoblin/user_pages/user.html:85 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 msgid "Here's a spot to tell others about yourself." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:90 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:108 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:101 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:119 msgid "Edit profile" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:107 msgid "This user hasn't filled in their profile (yet)." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:122 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:133 #, python-format msgid "View all of %(username)s's media" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:135 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:146 msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:141 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:152 msgid "Add media" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:147 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:158 msgid "There doesn't seem to be any media here yet..." msgstr "" @@ -475,6 +493,14 @@ msgstr "" msgid "Older" msgstr "" +#: mediagoblin/templates/mediagoblin/utils/tags.html:20 +msgid "Tagged with" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/tags.html:25 +msgid "and" +msgstr "" + #: mediagoblin/user_pages/forms.py:24 msgid "Comment" msgstr "Commento" @@ -483,15 +509,23 @@ msgstr "Commento" msgid "I am sure I want to delete this" msgstr "" -#: mediagoblin/user_pages/views.py:142 +#: mediagoblin/user_pages/views.py:155 msgid "Empty comments are not allowed." msgstr "" -#: mediagoblin/user_pages/views.py:148 +#: mediagoblin/user_pages/views.py:161 msgid "Comment posted!" msgstr "" -#: mediagoblin/user_pages/views.py:181 +#: mediagoblin/user_pages/views.py:183 +msgid "You deleted the media." +msgstr "" + +#: mediagoblin/user_pages/views.py:190 +msgid "The media was not deleted because you didn't check that you were sure." +msgstr "" + +#: mediagoblin/user_pages/views.py:198 msgid "You are about to delete another user's media. Proceed with caution." msgstr "" diff --git a/mediagoblin/i18n/it/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/it/LC_MESSAGES/mediagoblin.po index 183d09ed..25700f8f 100644 --- a/mediagoblin/i18n/it/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/it/LC_MESSAGES/mediagoblin.po @@ -8,8 +8,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-11-01 23:14-0500\n" -"PO-Revision-Date: 2011-11-02 04:13+0000\n" +"POT-Creation-Date: 2011-11-27 15:25-0600\n" +"PO-Revision-Date: 2011-11-27 21:28+0000\n" "Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -19,6 +19,10 @@ msgstr "" "Language: it\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" +#: mediagoblin/processing.py:143 +msgid "Invalid file given for media type." +msgstr "documento non valido come tipo multimediale." + #: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 msgid "Username" msgstr "Nome utente" @@ -52,8 +56,8 @@ msgid "Sorry, a user with that name already exists." msgstr "Spiacente, esiste già un utente con quel nome" #: mediagoblin/auth/views.py:77 -msgid "Sorry, that email address has already been taken." -msgstr "Spiacente, quell'indirizzo email è già stato preso." +msgid "Sorry, a user with that email address already exists." +msgstr "" #: mediagoblin/auth/views.py:179 msgid "" @@ -67,11 +71,19 @@ msgstr "" msgid "The verification key or user id is incorrect" msgstr "La chiave di verifica o l'id utente è sbagliato" -#: mediagoblin/auth/views.py:207 +#: mediagoblin/auth/views.py:203 +msgid "You must be logged in so we know who to send the email to!" +msgstr "" + +#: mediagoblin/auth/views.py:211 +msgid "You've already verified your email address!" +msgstr "" + +#: mediagoblin/auth/views.py:224 msgid "Resent your verification email." msgstr "Rispedisci email di verifica" -#: mediagoblin/auth/views.py:248 +#: mediagoblin/auth/views.py:265 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." @@ -85,44 +97,64 @@ msgstr "Titolo" msgid "Tags" msgstr "Tags" -#: mediagoblin/edit/forms.py:31 -msgid "Slug" -msgstr "" - -#: mediagoblin/edit/forms.py:32 -msgid "The slug can't be empty" +#: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 +msgid "Seperate tags by commas or spaces." msgstr "" #: mediagoblin/edit/forms.py:33 +msgid "Slug" +msgstr "" + +#: mediagoblin/edit/forms.py:34 +msgid "The slug can't be empty" +msgstr "" + +#: mediagoblin/edit/forms.py:35 msgid "" "The title part of this media's URL. You usually don't need to change this." msgstr "" -#: mediagoblin/edit/forms.py:40 +#: mediagoblin/edit/forms.py:42 msgid "Bio" msgstr "Bio" -#: mediagoblin/edit/forms.py:43 +#: mediagoblin/edit/forms.py:45 msgid "Website" msgstr "Sito web" -#: mediagoblin/edit/views.py:64 +#: mediagoblin/edit/forms.py:49 +msgid "Old password" +msgstr "" + +#: mediagoblin/edit/forms.py:52 +msgid "New Password" +msgstr "" + +#: mediagoblin/edit/views.py:65 msgid "An entry with that slug already exists for this user." msgstr "" -#: mediagoblin/edit/views.py:85 +#: mediagoblin/edit/views.py:86 msgid "You are editing another user's media. Proceed with caution." msgstr "" "Stai modificando documenti multimediale di un altro utente. Procedi con " "attenzione." -#: mediagoblin/edit/views.py:155 +#: mediagoblin/edit/views.py:156 msgid "You are editing a user's profile. Proceed with caution." msgstr "Stai modificando il profilo di un utente. Procedi con attenzione." -#: mediagoblin/process_media/errors.py:44 -msgid "Invalid file given for media type." -msgstr "documento non valido come tipo multimediale." +#: mediagoblin/edit/views.py:171 +msgid "Wrong password" +msgstr "" + +#: mediagoblin/edit/views.py:192 +msgid "Profile edited!" +msgstr "" + +#: mediagoblin/media_types/__init__.py:61 +msgid "Could not find any file extension in \"{filename}\"" +msgstr "" #: mediagoblin/submit/forms.py:25 msgid "File" @@ -132,18 +164,18 @@ msgstr "Documento" msgid "Description of this work" msgstr "Descrizione di questo lavoro" -#: mediagoblin/submit/views.py:46 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "Devi specificare un documento." -#: mediagoblin/submit/views.py:49 -msgid "The file doesn't seem to be an image!" -msgstr "Il documento non sembra essere un'immagine!" - -#: mediagoblin/submit/views.py:121 +#: mediagoblin/submit/views.py:127 msgid "Woohoo! Submitted!" msgstr "Evviva! " +#: mediagoblin/submit/views.py:133 +msgid "Invalid file type." +msgstr "" + #: mediagoblin/templates/mediagoblin/404.html:21 msgid "Oops!" msgstr "Oops!" @@ -164,29 +196,29 @@ msgstr "" msgid "Image of 404 goblin stressing out" msgstr "Immagine di 404 folletti che stressano" -#: mediagoblin/templates/mediagoblin/base.html:22 -msgid "GNU MediaGoblin" -msgstr "GNU MediaGoblin" - -#: mediagoblin/templates/mediagoblin/base.html:47 +#: mediagoblin/templates/mediagoblin/base.html:49 msgid "MediaGoblin logo" msgstr "MediaGoblin logo" -#: mediagoblin/templates/mediagoblin/base.html:52 +#: mediagoblin/templates/mediagoblin/base.html:54 msgid "Submit media" msgstr "Inoltra file multimediale" -#: mediagoblin/templates/mediagoblin/base.html:63 -msgid "verify your email!" -msgstr "verifica il tuo indirizzo email!" +#: mediagoblin/templates/mediagoblin/base.html:65 +msgid "Verify your email!" +msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:73 +#: mediagoblin/templates/mediagoblin/base.html:72 +msgid "log out" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:75 #: mediagoblin/templates/mediagoblin/auth/login.html:27 -#: mediagoblin/templates/mediagoblin/auth/login.html:35 +#: mediagoblin/templates/mediagoblin/auth/login.html:45 msgid "Log in" msgstr "Accedi" -#: mediagoblin/templates/mediagoblin/base.html:89 +#: mediagoblin/templates/mediagoblin/base.html:91 msgid "" "Powered by MediaGoblin, a GNU project" @@ -199,65 +231,32 @@ msgid "Explore" msgstr "Esplora" #: mediagoblin/templates/mediagoblin/root.html:27 -msgid "Hi there, media lover! MediaGoblin is..." -msgstr "Ciao, amante del multimedia! MediaGoblin è..." +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:28 +msgid "Your finest source for all goblin-related media." +msgstr "" #: mediagoblin/templates/mediagoblin/root.html:29 -msgid "The perfect place for your media!" -msgstr "Il posto perfetto per i tuoi documenti multimediali!" - -#: mediagoblin/templates/mediagoblin/root.html:30 msgid "" -"A place for people to collaborate and show off original and derived " -"creations!" +"To add your own media, place comments, save your favourites and more, you " +"can log in with your MediaGoblin account." msgstr "" -"Un posto per collaborare con altri e mostrare le proprie creazioni originali" -" e derivate!" #: mediagoblin/templates/mediagoblin/root.html:31 -msgid "" -"Free, as in freedom. (We’re a GNU project, " -"after all.)" +msgid "Don't have one yet? It's easy!" msgstr "" -"Libero, come in libertà. (Siamo un progetto GNU, dopotutto.)" #: mediagoblin/templates/mediagoblin/root.html:32 -msgid "" -"Aiming to make the world a better place through decentralization and " -"(eventually, coming soon!) federation!" -msgstr "" -"Con l'obbiettivo di rendere il mondo un posto migliore attraverso la " -"decentrelizzazione e (finalmente, presto!) federazione!" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "" -"Built for extensibility. (Multiple media types coming soon to the software," -" including video support!)" -msgstr "" -"Fatto per estensibilità. (Numerosi tipi multimediali saranno presto aggiunti" -" al programma, incluso il supporto video!)" - -#: mediagoblin/templates/mediagoblin/root.html:34 -msgid "" -"Powered by people like you. (You can help us improve this" -" software!)" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Excited to join us?" -msgstr "Eccitato di unirti a noi?" - -#: mediagoblin/templates/mediagoblin/root.html:39 #, python-format msgid "" -"Create a free account\n" +"Create an account at this site\n" " or\n" -" Set up MediaGoblin on your own server" +" Set up MediaGoblin on your own server" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:53 +#: mediagoblin/templates/mediagoblin/root.html:44 msgid "Most recent media" msgstr "Documenti multimediali più recenti" @@ -265,9 +264,13 @@ msgstr "Documenti multimediali più recenti" msgid "Enter your new password" msgstr "Inserisci la tua nuova password" -#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:29 -msgid "Enter your username or email" -msgstr "Inserisci il tuo nome utente o email" +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 +msgid "Recover password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:30 +msgid "Send instructions" +msgstr "" #: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 msgid "Your password has been changed. Try to log in now." @@ -296,22 +299,18 @@ msgstr "" msgid "Logging in failed!" msgstr "Accesso fallito!" -#: mediagoblin/templates/mediagoblin/auth/login.html:43 +#: mediagoblin/templates/mediagoblin/auth/login.html:35 msgid "Don't have an account yet?" msgstr "Non hai ancora un account?" -#: mediagoblin/templates/mediagoblin/auth/login.html:46 +#: mediagoblin/templates/mediagoblin/auth/login.html:36 msgid "Create one here!" msgstr "Creane uno qui!" -#: mediagoblin/templates/mediagoblin/auth/login.html:49 +#: mediagoblin/templates/mediagoblin/auth/login.html:42 msgid "Forgot your password?" msgstr "Hai dimenticato la password?" -#: mediagoblin/templates/mediagoblin/auth/login.html:52 -msgid "Change it!" -msgstr "" - #: mediagoblin/templates/mediagoblin/auth/register.html:27 msgid "Create an account!" msgstr "Crea un account!" @@ -356,9 +355,15 @@ msgstr "Salva i cambiamenti" msgid "Editing %(username)s's profile" msgstr "Stai modificando il profilo di %(username)s" -#: mediagoblin/templates/mediagoblin/listings/tag.html:31 -msgid "Media tagged with:" -msgstr "Media taggata con:" +#: mediagoblin/templates/mediagoblin/listings/tag.html:30 +#: mediagoblin/templates/mediagoblin/listings/tag.html:35 +#, python-format +msgid "Media tagged with: %(tag_name)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:19 +msgid "Original" +msgstr "" #: mediagoblin/templates/mediagoblin/submit/start.html:26 msgid "Submit yer media" @@ -368,16 +373,16 @@ msgstr "Inoltra documento multimediale" msgid "Submit" msgstr "Conferma" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:32 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 +#, python-format +msgid "%(username)s's media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:37 #, python-format msgid "%(username)s's media" msgstr "Documenti multimediali di %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:52 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:32 -msgid "Sorry, no such user found." -msgstr "Mi dispiace, utente non trovato" - #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -408,30 +413,40 @@ msgstr "Nessun documento multimediale in elaborazione" msgid "These uploads failed to process:" msgstr "L'elaborazione di questi upload è fallita:" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:39 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:59 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:31 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:89 +#, python-format +msgid "%(username)s's profile" +msgstr "profilo di %(username)s" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:43 +msgid "Sorry, no such user found." +msgstr "Mi dispiace, utente non trovato" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:50 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:70 msgid "Email verification needed" msgstr "è necessario verificare email" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:42 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:53 msgid "Almost done! Your account still needs to be activated." msgstr "Quasi finito! Il tuo account deve ancora essere attivato." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:58 msgid "" "An email should arrive in a few moments with instructions on how to do so." msgstr "" "In breve dovresti ricevere un email contenente istruzioni su come fare." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:51 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 msgid "In case it doesn't:" msgstr "Nel caso non fosse:" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:54 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:65 msgid "Resend verification email" msgstr "Rispedisci email di verifica" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:73 msgid "" "Someone has registered an account with this username, but it still has to be" " activated." @@ -439,7 +454,7 @@ msgstr "" "Qualcuno ha registrato un account con questo nome utente, ma deve ancora " "essere attivato." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:79 #, python-format msgid "" "If you are that person but you've lost your verification email, you can accedere e rispedirlo." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:78 -#, python-format -msgid "%(username)s's profile" -msgstr "profilo di %(username)s" - -#: mediagoblin/templates/mediagoblin/user_pages/user.html:85 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 msgid "Here's a spot to tell others about yourself." msgstr "Ecco un posto dove raccontare agli altri di te." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:90 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:108 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:101 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:119 msgid "Edit profile" msgstr "Modifica profilo" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:107 msgid "This user hasn't filled in their profile (yet)." msgstr "Questo utente non ha (ancora) compilato il proprio profilo." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:122 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:133 #, python-format msgid "View all of %(username)s's media" msgstr "Visualizza tutti i file multimediali di %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:135 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:146 msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." @@ -479,11 +489,11 @@ msgstr "" "Questo è dove i tuoi documenti multimediali appariranno, ma sembra che tu " "non abbia ancora aggiunto niente." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:141 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:152 msgid "Add media" msgstr "Aggiungi documenti multimediali" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:147 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:158 msgid "There doesn't seem to be any media here yet..." msgstr "Non sembra ci sia ancora nessun documento multimediali qui.." @@ -503,6 +513,14 @@ msgstr "Più nuovo" msgid "Older" msgstr "Più vecchio" +#: mediagoblin/templates/mediagoblin/utils/tags.html:20 +msgid "Tagged with" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/tags.html:25 +msgid "and" +msgstr "" + #: mediagoblin/user_pages/forms.py:24 msgid "Comment" msgstr "Commento" @@ -511,15 +529,23 @@ msgstr "Commento" msgid "I am sure I want to delete this" msgstr "Sono sicuro di volerlo cancellare" -#: mediagoblin/user_pages/views.py:142 +#: mediagoblin/user_pages/views.py:155 msgid "Empty comments are not allowed." msgstr "" -#: mediagoblin/user_pages/views.py:148 +#: mediagoblin/user_pages/views.py:161 msgid "Comment posted!" msgstr "" -#: mediagoblin/user_pages/views.py:181 +#: mediagoblin/user_pages/views.py:183 +msgid "You deleted the media." +msgstr "" + +#: mediagoblin/user_pages/views.py:190 +msgid "The media was not deleted because you didn't check that you were sure." +msgstr "" + +#: mediagoblin/user_pages/views.py:198 msgid "You are about to delete another user's media. Proceed with caution." msgstr "" "Stai cancellando un documento multimediale di un altro utente. Procedi con " diff --git a/mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.po index 59262d82..f2989e0e 100644 --- a/mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.po @@ -8,8 +8,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-11-01 23:14-0500\n" -"PO-Revision-Date: 2011-11-02 04:13+0000\n" +"POT-Creation-Date: 2011-11-27 15:25-0600\n" +"PO-Revision-Date: 2011-11-27 21:28+0000\n" "Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -19,6 +19,10 @@ msgstr "" "Language: ja\n" "Plural-Forms: nplurals=1; plural=0\n" +#: mediagoblin/processing.py:143 +msgid "Invalid file given for media type." +msgstr "" + #: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 msgid "Username" msgstr "ユーザネーム" @@ -52,7 +56,7 @@ msgid "Sorry, a user with that name already exists." msgstr "申し訳ありませんが、その名前を持つユーザーがすでに存在しています。" #: mediagoblin/auth/views.py:77 -msgid "Sorry, that email address has already been taken." +msgid "Sorry, a user with that email address already exists." msgstr "" #: mediagoblin/auth/views.py:179 @@ -65,11 +69,19 @@ msgstr "メアドが確認されています。これで、ログインしてプ msgid "The verification key or user id is incorrect" msgstr "検証キーまたはユーザーIDが間違っています" -#: mediagoblin/auth/views.py:207 +#: mediagoblin/auth/views.py:203 +msgid "You must be logged in so we know who to send the email to!" +msgstr "" + +#: mediagoblin/auth/views.py:211 +msgid "You've already verified your email address!" +msgstr "" + +#: mediagoblin/auth/views.py:224 msgid "Resent your verification email." msgstr "検証メールを再送しました。" -#: mediagoblin/auth/views.py:248 +#: mediagoblin/auth/views.py:265 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." @@ -83,41 +95,61 @@ msgstr "タイトル" msgid "Tags" msgstr "タグ" -#: mediagoblin/edit/forms.py:31 +#: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 +msgid "Seperate tags by commas or spaces." +msgstr "" + +#: mediagoblin/edit/forms.py:33 msgid "Slug" msgstr "スラグ" -#: mediagoblin/edit/forms.py:32 +#: mediagoblin/edit/forms.py:34 msgid "The slug can't be empty" msgstr "スラグは必要です。" -#: mediagoblin/edit/forms.py:33 +#: mediagoblin/edit/forms.py:35 msgid "" "The title part of this media's URL. You usually don't need to change this." msgstr "" -#: mediagoblin/edit/forms.py:40 +#: mediagoblin/edit/forms.py:42 msgid "Bio" msgstr "自己紹介" -#: mediagoblin/edit/forms.py:43 +#: mediagoblin/edit/forms.py:45 msgid "Website" msgstr "URL" -#: mediagoblin/edit/views.py:64 +#: mediagoblin/edit/forms.py:49 +msgid "Old password" +msgstr "" + +#: mediagoblin/edit/forms.py:52 +msgid "New Password" +msgstr "" + +#: mediagoblin/edit/views.py:65 msgid "An entry with that slug already exists for this user." msgstr "そのスラグを持つエントリは、このユーザーは既に存在します。" -#: mediagoblin/edit/views.py:85 +#: mediagoblin/edit/views.py:86 msgid "You are editing another user's media. Proceed with caution." msgstr "あなたは、他のユーザーのメディアを編集しています。ご注意ください。" -#: mediagoblin/edit/views.py:155 +#: mediagoblin/edit/views.py:156 msgid "You are editing a user's profile. Proceed with caution." msgstr "あなたは、他のユーザーのプロファイルを編集しています。ご注意ください。" -#: mediagoblin/process_media/errors.py:44 -msgid "Invalid file given for media type." +#: mediagoblin/edit/views.py:171 +msgid "Wrong password" +msgstr "" + +#: mediagoblin/edit/views.py:192 +msgid "Profile edited!" +msgstr "" + +#: mediagoblin/media_types/__init__.py:61 +msgid "Could not find any file extension in \"{filename}\"" msgstr "" #: mediagoblin/submit/forms.py:25 @@ -128,18 +160,18 @@ msgstr "ファイル" msgid "Description of this work" msgstr "" -#: mediagoblin/submit/views.py:46 +#: mediagoblin/submit/views.py:49 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:121 +#: mediagoblin/submit/views.py:127 msgid "Woohoo! Submitted!" msgstr "投稿終了!" +#: mediagoblin/submit/views.py:133 +msgid "Invalid file type." +msgstr "" + #: mediagoblin/templates/mediagoblin/404.html:21 msgid "Oops!" msgstr "" @@ -158,29 +190,29 @@ msgstr "" msgid "Image of 404 goblin stressing out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:22 -msgid "GNU MediaGoblin" -msgstr "GNU MediaGoblin" - -#: mediagoblin/templates/mediagoblin/base.html:47 +#: mediagoblin/templates/mediagoblin/base.html:49 msgid "MediaGoblin logo" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:52 +#: mediagoblin/templates/mediagoblin/base.html:54 msgid "Submit media" msgstr "コンテンツを投稿" -#: mediagoblin/templates/mediagoblin/base.html:63 -msgid "verify your email!" -msgstr "メアドを確認してください!" +#: mediagoblin/templates/mediagoblin/base.html:65 +msgid "Verify your email!" +msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:73 +#: mediagoblin/templates/mediagoblin/base.html:72 +msgid "log out" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:75 #: mediagoblin/templates/mediagoblin/auth/login.html:27 -#: mediagoblin/templates/mediagoblin/auth/login.html:35 +#: mediagoblin/templates/mediagoblin/auth/login.html:45 msgid "Log in" msgstr "ログイン" -#: mediagoblin/templates/mediagoblin/base.html:89 +#: mediagoblin/templates/mediagoblin/base.html:91 msgid "" "Powered by MediaGoblin, a GNU project" @@ -191,57 +223,32 @@ msgid "Explore" msgstr "" #: mediagoblin/templates/mediagoblin/root.html:27 -msgid "Hi there, media lover! MediaGoblin is..." +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:28 +msgid "Your finest source for all goblin-related media." msgstr "" #: mediagoblin/templates/mediagoblin/root.html:29 -msgid "The perfect place for your media!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:30 msgid "" -"A place for people to collaborate and show off original and derived " -"creations!" +"To add your own media, place comments, save your favourites and more, you " +"can log in with your MediaGoblin account." msgstr "" #: mediagoblin/templates/mediagoblin/root.html:31 -msgid "" -"Free, as in freedom. (We’re a GNU project, " -"after all.)" +msgid "Don't have one yet? It's easy!" msgstr "" #: mediagoblin/templates/mediagoblin/root.html:32 -msgid "" -"Aiming to make the world a better place through decentralization and " -"(eventually, coming soon!) federation!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "" -"Built for extensibility. (Multiple media types coming soon to the software," -" including video support!)" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:34 -msgid "" -"Powered by people like you. (You can help us improve this" -" software!)" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Excited to join us?" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:39 #, python-format msgid "" -"Create a free account\n" +"Create an account at this site\n" " or\n" -" Set up MediaGoblin on your own server" +" Set up MediaGoblin on your own server" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:53 +#: mediagoblin/templates/mediagoblin/root.html:44 msgid "Most recent media" msgstr "" @@ -249,8 +256,12 @@ msgstr "" msgid "Enter your new password" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:29 -msgid "Enter your username or email" +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 +msgid "Recover password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:30 +msgid "Send instructions" msgstr "" #: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 @@ -280,22 +291,18 @@ msgstr "" msgid "Logging in failed!" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/login.html:43 +#: mediagoblin/templates/mediagoblin/auth/login.html:35 msgid "Don't have an account yet?" msgstr "まだアカウントを持っていませんか?" -#: mediagoblin/templates/mediagoblin/auth/login.html:46 +#: mediagoblin/templates/mediagoblin/auth/login.html:36 msgid "Create one here!" msgstr "ここで作成!" -#: mediagoblin/templates/mediagoblin/auth/login.html:49 +#: mediagoblin/templates/mediagoblin/auth/login.html:42 msgid "Forgot your password?" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/login.html:52 -msgid "Change it!" -msgstr "" - #: mediagoblin/templates/mediagoblin/auth/register.html:27 msgid "Create an account!" msgstr "アカウントを作成!" @@ -340,9 +347,15 @@ msgstr "投稿する" 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:30 +#: mediagoblin/templates/mediagoblin/listings/tag.html:35 +#, python-format +msgid "Media tagged with: %(tag_name)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:19 +msgid "Original" +msgstr "" #: mediagoblin/templates/mediagoblin/submit/start.html:26 msgid "Submit yer media" @@ -352,16 +365,16 @@ msgstr "コンテンツを投稿" msgid "Submit" msgstr "送信" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:32 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 +#, python-format +msgid "%(username)s's media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:37 #, python-format msgid "%(username)s's media" msgstr "%(username)sさんのコンテンツ" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:52 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:32 -msgid "Sorry, no such user found." -msgstr "申し訳ありませんが、そのユーザーは見つかりませんでした。" - #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -392,75 +405,80 @@ msgstr "" msgid "These uploads failed to process:" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:39 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:59 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:31 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:89 +#, python-format +msgid "%(username)s's profile" +msgstr "%(username)sさんのプロフィール" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:43 +msgid "Sorry, no such user found." +msgstr "申し訳ありませんが、そのユーザーは見つかりませんでした。" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:50 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:70 msgid "Email verification needed" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:42 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:53 msgid "Almost done! Your account still needs to be activated." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:58 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 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 msgid "In case it doesn't:" msgstr "到着しない場合は、" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:54 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:65 msgid "Resend verification email" msgstr "確認メールを再送信" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:73 msgid "" "Someone has registered an account with this username, but it still has to be" " activated." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:79 #, python-format msgid "" "If you are that person but you've lost your verification email, you can log in and resend it." msgstr "あなたの確認メールを紛失した場合、ログインして再送できます。" -#: 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:85 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 msgid "Here's a spot to tell others about yourself." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:90 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:108 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:101 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:119 msgid "Edit profile" msgstr "プロフィールを編集" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:107 msgid "This user hasn't filled in their profile (yet)." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:122 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:133 #, python-format msgid "View all of %(username)s's media" msgstr "%(username)sさんのコンテンツをすべて見る" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:135 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:146 msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:141 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:152 msgid "Add media" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:147 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:158 msgid "There doesn't seem to be any media here yet..." msgstr "" @@ -480,6 +498,14 @@ msgstr "" msgid "Older" msgstr "" +#: mediagoblin/templates/mediagoblin/utils/tags.html:20 +msgid "Tagged with" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/tags.html:25 +msgid "and" +msgstr "" + #: mediagoblin/user_pages/forms.py:24 msgid "Comment" msgstr "" @@ -488,15 +514,23 @@ msgstr "" msgid "I am sure I want to delete this" msgstr "" -#: mediagoblin/user_pages/views.py:142 +#: mediagoblin/user_pages/views.py:155 msgid "Empty comments are not allowed." msgstr "" -#: mediagoblin/user_pages/views.py:148 +#: mediagoblin/user_pages/views.py:161 msgid "Comment posted!" msgstr "" -#: mediagoblin/user_pages/views.py:181 +#: mediagoblin/user_pages/views.py:183 +msgid "You deleted the media." +msgstr "" + +#: mediagoblin/user_pages/views.py:190 +msgid "The media was not deleted because you didn't check that you were sure." +msgstr "" + +#: mediagoblin/user_pages/views.py:198 msgid "You are about to delete another user's media. Proceed with caution." msgstr "" diff --git a/mediagoblin/i18n/nl/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/nl/LC_MESSAGES/mediagoblin.po index 618daf6f..84957014 100644 --- a/mediagoblin/i18n/nl/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/nl/LC_MESSAGES/mediagoblin.po @@ -8,8 +8,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-11-01 23:14-0500\n" -"PO-Revision-Date: 2011-11-02 04:13+0000\n" +"POT-Creation-Date: 2011-11-27 15:25-0600\n" +"PO-Revision-Date: 2011-11-27 21:28+0000\n" "Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -19,6 +19,10 @@ msgstr "" "Language: nl\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" +#: mediagoblin/processing.py:143 +msgid "Invalid file given for media type." +msgstr "" + #: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 msgid "Username" msgstr "Gebruikersnaam" @@ -52,8 +56,8 @@ msgid "Sorry, a user with that name already exists." msgstr "Sorry, er bestaat al een gebruiker met die naam." #: mediagoblin/auth/views.py:77 -msgid "Sorry, that email address has already been taken." -msgstr "Sorry, dat e-mailadres is al ingenomen." +msgid "Sorry, a user with that email address already exists." +msgstr "" #: mediagoblin/auth/views.py:179 msgid "" @@ -67,11 +71,19 @@ msgstr "" msgid "The verification key or user id is incorrect" msgstr "De verificatie sleutel of gebruikers-ID is onjuist" -#: mediagoblin/auth/views.py:207 +#: mediagoblin/auth/views.py:203 +msgid "You must be logged in so we know who to send the email to!" +msgstr "" + +#: mediagoblin/auth/views.py:211 +msgid "You've already verified your email address!" +msgstr "" + +#: mediagoblin/auth/views.py:224 msgid "Resent your verification email." msgstr "Verificatie e-mail opnieuw opgestuurd." -#: mediagoblin/auth/views.py:248 +#: mediagoblin/auth/views.py:265 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." @@ -85,44 +97,64 @@ msgstr "Titel" msgid "Tags" msgstr "Etiket" -#: mediagoblin/edit/forms.py:31 -msgid "Slug" -msgstr "" - -#: mediagoblin/edit/forms.py:32 -msgid "The slug can't be empty" +#: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 +msgid "Seperate tags by commas or spaces." msgstr "" #: mediagoblin/edit/forms.py:33 +msgid "Slug" +msgstr "" + +#: mediagoblin/edit/forms.py:34 +msgid "The slug can't be empty" +msgstr "" + +#: mediagoblin/edit/forms.py:35 msgid "" "The title part of this media's URL. You usually don't need to change this." msgstr "" -#: mediagoblin/edit/forms.py:40 +#: mediagoblin/edit/forms.py:42 msgid "Bio" msgstr "Bio" -#: mediagoblin/edit/forms.py:43 +#: mediagoblin/edit/forms.py:45 msgid "Website" msgstr "Website" -#: mediagoblin/edit/views.py:64 +#: mediagoblin/edit/forms.py:49 +msgid "Old password" +msgstr "" + +#: mediagoblin/edit/forms.py:52 +msgid "New Password" +msgstr "" + +#: mediagoblin/edit/views.py:65 msgid "An entry with that slug already exists for this user." msgstr "" -#: mediagoblin/edit/views.py:85 +#: mediagoblin/edit/views.py:86 msgid "You are editing another user's media. Proceed with caution." msgstr "" "U bent de media van een andere gebruiker aan het aanpassen. Ga voorzichtig " "te werk." -#: mediagoblin/edit/views.py:155 +#: mediagoblin/edit/views.py:156 msgid "You are editing a user's profile. Proceed with caution." msgstr "" "U bent een gebruikersprofiel aan het aanpassen. Ga voorzichtig te werk." -#: mediagoblin/process_media/errors.py:44 -msgid "Invalid file given for media type." +#: mediagoblin/edit/views.py:171 +msgid "Wrong password" +msgstr "" + +#: mediagoblin/edit/views.py:192 +msgid "Profile edited!" +msgstr "" + +#: mediagoblin/media_types/__init__.py:61 +msgid "Could not find any file extension in \"{filename}\"" msgstr "" #: mediagoblin/submit/forms.py:25 @@ -133,18 +165,18 @@ msgstr "Bestand" msgid "Description of this work" msgstr "" -#: mediagoblin/submit/views.py:46 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "U moet een bestand aangeven." -#: mediagoblin/submit/views.py:49 -msgid "The file doesn't seem to be an image!" -msgstr "Het lijkt erop dat dit bestand geen afbeelding is!" - -#: mediagoblin/submit/views.py:121 +#: mediagoblin/submit/views.py:127 msgid "Woohoo! Submitted!" msgstr "Mooizo! Toegevoegd!" +#: mediagoblin/submit/views.py:133 +msgid "Invalid file type." +msgstr "" + #: mediagoblin/templates/mediagoblin/404.html:21 msgid "Oops!" msgstr "" @@ -163,29 +195,29 @@ msgstr "" msgid "Image of 404 goblin stressing out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:22 -msgid "GNU MediaGoblin" -msgstr "GNU MediaGoblin" - -#: mediagoblin/templates/mediagoblin/base.html:47 +#: mediagoblin/templates/mediagoblin/base.html:49 msgid "MediaGoblin logo" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:52 +#: mediagoblin/templates/mediagoblin/base.html:54 msgid "Submit media" msgstr "Voeg media toe" -#: mediagoblin/templates/mediagoblin/base.html:63 -msgid "verify your email!" -msgstr "Controleer uw e-mail!" +#: mediagoblin/templates/mediagoblin/base.html:65 +msgid "Verify your email!" +msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:73 +#: mediagoblin/templates/mediagoblin/base.html:72 +msgid "log out" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:75 #: mediagoblin/templates/mediagoblin/auth/login.html:27 -#: mediagoblin/templates/mediagoblin/auth/login.html:35 +#: mediagoblin/templates/mediagoblin/auth/login.html:45 msgid "Log in" msgstr "Inloggen" -#: mediagoblin/templates/mediagoblin/base.html:89 +#: mediagoblin/templates/mediagoblin/base.html:91 msgid "" "Powered by MediaGoblin, a GNU project" @@ -196,57 +228,32 @@ msgid "Explore" msgstr "" #: mediagoblin/templates/mediagoblin/root.html:27 -msgid "Hi there, media lover! MediaGoblin is..." +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:28 +msgid "Your finest source for all goblin-related media." msgstr "" #: mediagoblin/templates/mediagoblin/root.html:29 -msgid "The perfect place for your media!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:30 msgid "" -"A place for people to collaborate and show off original and derived " -"creations!" +"To add your own media, place comments, save your favourites and more, you " +"can log in with your MediaGoblin account." msgstr "" #: mediagoblin/templates/mediagoblin/root.html:31 -msgid "" -"Free, as in freedom. (We’re a GNU project, " -"after all.)" +msgid "Don't have one yet? It's easy!" msgstr "" #: mediagoblin/templates/mediagoblin/root.html:32 -msgid "" -"Aiming to make the world a better place through decentralization and " -"(eventually, coming soon!) federation!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "" -"Built for extensibility. (Multiple media types coming soon to the software," -" including video support!)" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:34 -msgid "" -"Powered by people like you. (You can help us improve this" -" software!)" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Excited to join us?" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:39 #, python-format msgid "" -"Create a free account\n" +"Create an account at this site\n" " or\n" -" Set up MediaGoblin on your own server" +" Set up MediaGoblin on your own server" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:53 +#: mediagoblin/templates/mediagoblin/root.html:44 msgid "Most recent media" msgstr "" @@ -254,8 +261,12 @@ msgstr "" msgid "Enter your new password" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:29 -msgid "Enter your username or email" +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 +msgid "Recover password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:30 +msgid "Send instructions" msgstr "" #: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 @@ -285,22 +296,18 @@ msgstr "" msgid "Logging in failed!" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/login.html:43 +#: mediagoblin/templates/mediagoblin/auth/login.html:35 msgid "Don't have an account yet?" msgstr "Heeft u nog geen account?" -#: mediagoblin/templates/mediagoblin/auth/login.html:46 +#: mediagoblin/templates/mediagoblin/auth/login.html:36 msgid "Create one here!" msgstr "Maak er hier een!" -#: mediagoblin/templates/mediagoblin/auth/login.html:49 +#: mediagoblin/templates/mediagoblin/auth/login.html:42 msgid "Forgot your password?" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/login.html:52 -msgid "Change it!" -msgstr "" - #: mediagoblin/templates/mediagoblin/auth/register.html:27 msgid "Create an account!" msgstr "Maak een account aan!" @@ -342,9 +349,15 @@ msgstr "Wijzigingen opslaan" msgid "Editing %(username)s's profile" msgstr "Het profiel aanpassen van %(username)s" -#: mediagoblin/templates/mediagoblin/listings/tag.html:31 -msgid "Media tagged with:" -msgstr "Media met het etiket:" +#: mediagoblin/templates/mediagoblin/listings/tag.html:30 +#: mediagoblin/templates/mediagoblin/listings/tag.html:35 +#, python-format +msgid "Media tagged with: %(tag_name)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:19 +msgid "Original" +msgstr "" #: mediagoblin/templates/mediagoblin/submit/start.html:26 msgid "Submit yer media" @@ -354,16 +367,16 @@ msgstr "Voeg media toe" msgid "Submit" msgstr "Voeg toe" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:32 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 +#, python-format +msgid "%(username)s's media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:37 #, python-format msgid "%(username)s's media" msgstr "Media van %(username)s " -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:52 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:32 -msgid "Sorry, no such user found." -msgstr "Sorry, die gebruiker kon niet worden gevonden." - #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -394,37 +407,47 @@ msgstr "" msgid "These uploads failed to process:" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:39 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:59 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:31 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:89 +#, python-format +msgid "%(username)s's profile" +msgstr "Profiel van %(username)s" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:43 +msgid "Sorry, no such user found." +msgstr "Sorry, die gebruiker kon niet worden gevonden." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:50 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:70 msgid "Email verification needed" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:42 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:53 msgid "Almost done! Your account still needs to be activated." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:58 msgid "" "An email should arrive in a few moments with instructions on how to do so." msgstr "" "Een e-mail zou in een paar ogenblikken aan moeten komen met instructies " "hiertoe." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:51 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 msgid "In case it doesn't:" msgstr "Zoniet:" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:54 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:65 msgid "Resend verification email" msgstr "Stuur de verificatie e-mail opnieuw op." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:73 msgid "" "Someone has registered an account with this username, but it still has to be" " activated." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:79 #, python-format msgid "" "If you are that person but you've lost your verification email, you can inloggen en hem nogmaals verzenden." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:78 -#, python-format -msgid "%(username)s's profile" -msgstr "Profiel van %(username)s" - -#: mediagoblin/templates/mediagoblin/user_pages/user.html:85 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 msgid "Here's a spot to tell others about yourself." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:90 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:108 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:101 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:119 msgid "Edit profile" msgstr "Profiel aanpassen." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:107 msgid "This user hasn't filled in their profile (yet)." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:122 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:133 #, python-format msgid "View all of %(username)s's media" msgstr "Bekijk alle media van %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:135 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:146 msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:141 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:152 msgid "Add media" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:147 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:158 msgid "There doesn't seem to be any media here yet..." msgstr "" @@ -486,6 +504,14 @@ msgstr "" msgid "Older" msgstr "" +#: mediagoblin/templates/mediagoblin/utils/tags.html:20 +msgid "Tagged with" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/tags.html:25 +msgid "and" +msgstr "" + #: mediagoblin/user_pages/forms.py:24 msgid "Comment" msgstr "Commentaar" @@ -494,15 +520,23 @@ msgstr "Commentaar" msgid "I am sure I want to delete this" msgstr "" -#: mediagoblin/user_pages/views.py:142 +#: mediagoblin/user_pages/views.py:155 msgid "Empty comments are not allowed." msgstr "" -#: mediagoblin/user_pages/views.py:148 +#: mediagoblin/user_pages/views.py:161 msgid "Comment posted!" msgstr "" -#: mediagoblin/user_pages/views.py:181 +#: mediagoblin/user_pages/views.py:183 +msgid "You deleted the media." +msgstr "" + +#: mediagoblin/user_pages/views.py:190 +msgid "The media was not deleted because you didn't check that you were sure." +msgstr "" + +#: mediagoblin/user_pages/views.py:198 msgid "You are about to delete another user's media. Proceed with caution." msgstr "" diff --git a/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.po index c74e1dd0..21cfdda5 100644 --- a/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.po @@ -8,8 +8,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-11-01 23:14-0500\n" -"PO-Revision-Date: 2011-11-02 04:13+0000\n" +"POT-Creation-Date: 2011-11-27 15:25-0600\n" +"PO-Revision-Date: 2011-11-27 21:28+0000\n" "Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -19,6 +19,10 @@ msgstr "" "Language: nn_NO\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" +#: mediagoblin/processing.py:143 +msgid "Invalid file given for media type." +msgstr "Ugyldig fil for mediatypen." + #: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 msgid "Username" msgstr "Brukarnamn" @@ -52,8 +56,8 @@ msgid "Sorry, a user with that name already exists." msgstr "Ein konto med dette brukarnamnet finst allereide." #: mediagoblin/auth/views.py:77 -msgid "Sorry, that email address has already been taken." -msgstr "Den epostadressa er allereide teken." +msgid "Sorry, a user with that email address already exists." +msgstr "" #: mediagoblin/auth/views.py:179 msgid "" @@ -67,11 +71,19 @@ msgstr "" msgid "The verification key or user id is incorrect" msgstr "Stadfestingsnykelen eller brukar-ID-en din er feil." -#: mediagoblin/auth/views.py:207 +#: mediagoblin/auth/views.py:203 +msgid "You must be logged in so we know who to send the email to!" +msgstr "" + +#: mediagoblin/auth/views.py:211 +msgid "You've already verified your email address!" +msgstr "" + +#: mediagoblin/auth/views.py:224 msgid "Resent your verification email." msgstr "Send ein ny stadfestingsepost." -#: mediagoblin/auth/views.py:248 +#: mediagoblin/auth/views.py:265 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." @@ -86,42 +98,62 @@ msgstr "Tittel" msgid "Tags" msgstr "Merkelappar" -#: mediagoblin/edit/forms.py:31 +#: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 +msgid "Seperate tags by commas or spaces." +msgstr "" + +#: mediagoblin/edit/forms.py:33 msgid "Slug" msgstr "Nettnamn" -#: mediagoblin/edit/forms.py:32 +#: mediagoblin/edit/forms.py:34 msgid "The slug can't be empty" msgstr "Nettnamnet kan ikkje vera tomt" -#: mediagoblin/edit/forms.py:33 +#: mediagoblin/edit/forms.py:35 msgid "" "The title part of this media's URL. You usually don't need to change this." msgstr "Nettnamnet (adressetittel) for mediefila di. Trengst ikkje endrast." -#: mediagoblin/edit/forms.py:40 +#: mediagoblin/edit/forms.py:42 msgid "Bio" msgstr "Presentasjon" -#: mediagoblin/edit/forms.py:43 +#: mediagoblin/edit/forms.py:45 msgid "Website" msgstr "Heimeside" -#: mediagoblin/edit/views.py:64 +#: mediagoblin/edit/forms.py:49 +msgid "Old password" +msgstr "" + +#: mediagoblin/edit/forms.py:52 +msgid "New Password" +msgstr "" + +#: mediagoblin/edit/views.py:65 msgid "An entry with that slug already exists for this user." msgstr "Eit innlegg med denne adressetittelen finst allereie." -#: mediagoblin/edit/views.py:85 +#: mediagoblin/edit/views.py:86 msgid "You are editing another user's media. Proceed with caution." msgstr "Trå varsamt, du endrar nokon andre sine mediefiler." -#: mediagoblin/edit/views.py:155 +#: mediagoblin/edit/views.py:156 msgid "You are editing a user's profile. Proceed with caution." msgstr "Trå varsamt, du endrar nokon andre sin profil." -#: mediagoblin/process_media/errors.py:44 -msgid "Invalid file given for media type." -msgstr "Ugyldig fil for mediatypen." +#: mediagoblin/edit/views.py:171 +msgid "Wrong password" +msgstr "" + +#: mediagoblin/edit/views.py:192 +msgid "Profile edited!" +msgstr "" + +#: mediagoblin/media_types/__init__.py:61 +msgid "Could not find any file extension in \"{filename}\"" +msgstr "" #: mediagoblin/submit/forms.py:25 msgid "File" @@ -131,18 +163,18 @@ msgstr "Fil" msgid "Description of this work" msgstr "Skildring av mediefila" -#: mediagoblin/submit/views.py:46 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "Du må velja ei fil." -#: mediagoblin/submit/views.py:49 -msgid "The file doesn't seem to be an image!" -msgstr "Fila verkar ikkje å vera ei gyldig biletefil." - -#: mediagoblin/submit/views.py:121 +#: mediagoblin/submit/views.py:127 msgid "Woohoo! Submitted!" msgstr "Johoo! Opplasta!" +#: mediagoblin/submit/views.py:133 +msgid "Invalid file type." +msgstr "" + #: mediagoblin/templates/mediagoblin/404.html:21 msgid "Oops!" msgstr "Oops." @@ -163,29 +195,29 @@ msgstr "" msgid "Image of 404 goblin stressing out" msgstr "Bilete av stressa 404-tusse." -#: mediagoblin/templates/mediagoblin/base.html:22 -msgid "GNU MediaGoblin" -msgstr "GNU MediaGoblin" - -#: mediagoblin/templates/mediagoblin/base.html:47 +#: mediagoblin/templates/mediagoblin/base.html:49 msgid "MediaGoblin logo" msgstr "MediaGoblin" -#: mediagoblin/templates/mediagoblin/base.html:52 +#: mediagoblin/templates/mediagoblin/base.html:54 msgid "Submit media" msgstr "Last opp" -#: mediagoblin/templates/mediagoblin/base.html:63 -msgid "verify your email!" -msgstr "Stadfest epostadressa di" +#: mediagoblin/templates/mediagoblin/base.html:65 +msgid "Verify your email!" +msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:73 +#: mediagoblin/templates/mediagoblin/base.html:72 +msgid "log out" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:75 #: mediagoblin/templates/mediagoblin/auth/login.html:27 -#: mediagoblin/templates/mediagoblin/auth/login.html:35 +#: mediagoblin/templates/mediagoblin/auth/login.html:45 msgid "Log in" msgstr "Logg inn" -#: mediagoblin/templates/mediagoblin/base.html:89 +#: mediagoblin/templates/mediagoblin/base.html:91 msgid "" "Powered by MediaGoblin, a GNU project" @@ -198,69 +230,32 @@ msgid "Explore" msgstr "Utforsk" #: mediagoblin/templates/mediagoblin/root.html:27 -msgid "Hi there, media lover! MediaGoblin is..." -msgstr "Hei der mediaentusiast, MediaGoblin..." +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:28 +msgid "Your finest source for all goblin-related media." +msgstr "" #: mediagoblin/templates/mediagoblin/root.html:29 -msgid "The perfect place for your media!" -msgstr "Er ein perfekt plass for mediet ditt!" - -#: mediagoblin/templates/mediagoblin/root.html:30 msgid "" -"A place for people to collaborate and show off original and derived " -"creations!" +"To add your own media, place comments, save your favourites and more, you " +"can log in with your MediaGoblin account." msgstr "" -"Er ein plass for folk å samarbeida og visa fram sjølvlaga og vidarebygde " -"verk." #: mediagoblin/templates/mediagoblin/root.html:31 -msgid "" -"Free, as in freedom. (We’re a GNU project, " -"after all.)" -msgstr "Fri som i fridom (me er eit GNU-prosjekt)." +msgid "Don't have one yet? It's easy!" +msgstr "" #: mediagoblin/templates/mediagoblin/root.html:32 -msgid "" -"Aiming to make the world a better place through decentralization and " -"(eventually, coming soon!) federation!" -msgstr "" -"Arbeidar for å gjera verda ein betre stad gjennom desentralisering og (til " -"slutt, kjem snart!) federering, enkelt forklart deling og sending av " -"mediefiler og kommentarar over fleire nettstader." - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "" -"Built for extensibility. (Multiple media types coming soon to the software," -" including video support!)" -msgstr "Bygd for utviding (fleire medietypar kjem snart, m.a. video)." - -#: mediagoblin/templates/mediagoblin/root.html:34 -msgid "" -"Powered by people like you. (You can help us improve this" -" software!)" -msgstr "" -"Driven av folk som deg. (Du kan hjelpa med å forbetra" -" MediaGoblin)" - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Excited to join us?" -msgstr "Lyst til å bli med oss?" - -#: mediagoblin/templates/mediagoblin/root.html:39 #, python-format msgid "" -"Create a free account\n" +"Create an account at this site\n" " or\n" -" Set up MediaGoblin on your own server" +" Set up MediaGoblin on your own server" msgstr "" -"Opprett ein " -"gratis konto eller installer MediaGoblin på " -"eigen tenar" -#: mediagoblin/templates/mediagoblin/root.html:53 +#: mediagoblin/templates/mediagoblin/root.html:44 msgid "Most recent media" msgstr "Nyaste mediefiler" @@ -268,9 +263,13 @@ msgstr "Nyaste mediefiler" msgid "Enter your new password" msgstr "Fyll inn passord" -#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:29 -msgid "Enter your username or email" -msgstr "Fyll inn brukarnamn eller epost" +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 +msgid "Recover password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:30 +msgid "Send instructions" +msgstr "" #: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 msgid "Your password has been changed. Try to log in now." @@ -308,22 +307,18 @@ msgstr "" msgid "Logging in failed!" msgstr "Innlogging feila" -#: mediagoblin/templates/mediagoblin/auth/login.html:43 +#: mediagoblin/templates/mediagoblin/auth/login.html:35 msgid "Don't have an account yet?" msgstr "Har du ingen konto?" -#: mediagoblin/templates/mediagoblin/auth/login.html:46 +#: mediagoblin/templates/mediagoblin/auth/login.html:36 msgid "Create one here!" msgstr "Lag ein!" -#: mediagoblin/templates/mediagoblin/auth/login.html:49 +#: mediagoblin/templates/mediagoblin/auth/login.html:42 msgid "Forgot your password?" msgstr "Gløymd passordet?" -#: mediagoblin/templates/mediagoblin/auth/login.html:52 -msgid "Change it!" -msgstr "Endra" - #: mediagoblin/templates/mediagoblin/auth/register.html:27 msgid "Create an account!" msgstr "Lag ein konto." @@ -368,9 +363,15 @@ msgstr "Lagra" msgid "Editing %(username)s's profile" msgstr "Endrar profilen til %(username)s" -#: mediagoblin/templates/mediagoblin/listings/tag.html:31 -msgid "Media tagged with:" -msgstr "Merkelappar:" +#: mediagoblin/templates/mediagoblin/listings/tag.html:30 +#: mediagoblin/templates/mediagoblin/listings/tag.html:35 +#, python-format +msgid "Media tagged with: %(tag_name)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:19 +msgid "Original" +msgstr "" #: mediagoblin/templates/mediagoblin/submit/start.html:26 msgid "Submit yer media" @@ -380,16 +381,16 @@ msgstr "Last opp" msgid "Submit" msgstr "Send" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:32 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 +#, python-format +msgid "%(username)s's media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:37 #, python-format msgid "%(username)s's media" msgstr "%(username)s sine mediefiler" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:52 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:32 -msgid "Sorry, no such user found." -msgstr "Fann ingen slik brukar" - #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -420,35 +421,45 @@ msgstr "Ingen media under handsaming" msgid "These uploads failed to process:" msgstr "Klarte ikkje handsama desse opplasta filene:" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:39 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:59 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:31 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:89 +#, python-format +msgid "%(username)s's profile" +msgstr "%(username)s sin profil" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:43 +msgid "Sorry, no such user found." +msgstr "Fann ingen slik brukar" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:50 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:70 msgid "Email verification needed" msgstr "Epostverifisering trengst." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:42 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:53 msgid "Almost done! Your account still needs to be activated." msgstr "Nesten ferdig. Du treng berre aktivera kontoen." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:58 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:51 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 msgid "In case it doesn't:" msgstr "I tilfelle det ikkje skjer:" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:54 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:65 msgid "Resend verification email" msgstr "Send ein ny epost" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:73 msgid "" "Someone has registered an account with this username, but it still has to be" " activated." msgstr "Dette brukarnamnet finst allereie, men det er ikkje aktivert." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:79 #, python-format msgid "" "If you are that person but you've lost your verification email, you can logga inn for å få " "tilsendt ny epost med stadfestingslenkje." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:78 -#, python-format -msgid "%(username)s's profile" -msgstr "%(username)s sin profil" - -#: mediagoblin/templates/mediagoblin/user_pages/user.html:85 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 msgid "Here's a spot to tell others about yourself." msgstr "Her kan du fortelja om deg sjølv." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:90 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:108 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:101 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:119 msgid "Edit profile" msgstr "Endra profil" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:107 msgid "This user hasn't filled in their profile (yet)." msgstr "Brukaren har ikkje fylt ut profilen sin (enno)." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:122 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:133 #, python-format msgid "View all of %(username)s's media" msgstr "Sjå alle %(username)s sine mediefiler" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:135 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:146 msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." -msgstr "Her kjem mediefilene dine. Ser ikkje ut til at du har lagt til noko." +msgstr "Her kjem mediefilene dine." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:141 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:152 msgid "Add media" msgstr "Legg til mediefiler" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:147 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:158 msgid "There doesn't seem to be any media here yet..." msgstr "Ser ikkje ut til at det finst nokon mediefiler her nett no." @@ -510,6 +516,14 @@ msgstr "Nyare" msgid "Older" msgstr "Eldre" +#: mediagoblin/templates/mediagoblin/utils/tags.html:20 +msgid "Tagged with" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/tags.html:25 +msgid "and" +msgstr "" + #: mediagoblin/user_pages/forms.py:24 msgid "Comment" msgstr "Innspel" @@ -518,15 +532,23 @@ msgstr "Innspel" msgid "I am sure I want to delete this" msgstr "Eg er sikker eg vil sletta dette" -#: mediagoblin/user_pages/views.py:142 +#: mediagoblin/user_pages/views.py:155 msgid "Empty comments are not allowed." -msgstr "" +msgstr "Du må skriva noko i innspelet." -#: mediagoblin/user_pages/views.py:148 +#: mediagoblin/user_pages/views.py:161 msgid "Comment posted!" +msgstr "Innspel lagt til." + +#: mediagoblin/user_pages/views.py:183 +msgid "You deleted the media." msgstr "" -#: mediagoblin/user_pages/views.py:181 +#: mediagoblin/user_pages/views.py:190 +msgid "The media was not deleted because you didn't check that you were sure." +msgstr "" + +#: mediagoblin/user_pages/views.py:198 msgid "You are about to delete another user's media. Proceed with caution." msgstr "" "Du er i ferd med å sletta ein annan brukar sine mediefiler. Trå varsamt." diff --git a/mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.po index 047e598b..c4f77f8a 100644 --- a/mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.po @@ -9,8 +9,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-11-01 23:14-0500\n" -"PO-Revision-Date: 2011-11-02 04:13+0000\n" +"POT-Creation-Date: 2011-11-27 15:25-0600\n" +"PO-Revision-Date: 2011-11-27 21:28+0000\n" "Last-Translator: cwebber \n" "Language-Team: Portuguese (Brazilian) (http://www.transifex.net/projects/p/mediagoblin/team/pt_BR/)\n" "MIME-Version: 1.0\n" @@ -20,6 +20,10 @@ msgstr "" "Language: pt_BR\n" "Plural-Forms: nplurals=2; plural=(n > 1)\n" +#: mediagoblin/processing.py:143 +msgid "Invalid file given for media type." +msgstr "Arquivo inválido para esse tipo de mídia" + #: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 msgid "Username" msgstr "Nome de Usuário" @@ -54,8 +58,8 @@ msgid "Sorry, a user with that name already exists." msgstr "Desculpe, um usuário com este nome já existe." #: mediagoblin/auth/views.py:77 -msgid "Sorry, that email address has already been taken." -msgstr "Desculpe, esse endereço de email já está em uso." +msgid "Sorry, a user with that email address already exists." +msgstr "" #: mediagoblin/auth/views.py:179 msgid "" @@ -69,11 +73,19 @@ msgstr "" 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:207 +#: mediagoblin/auth/views.py:203 +msgid "You must be logged in so we know who to send the email to!" +msgstr "" + +#: mediagoblin/auth/views.py:211 +msgid "You've already verified your email address!" +msgstr "" + +#: mediagoblin/auth/views.py:224 msgid "Resent your verification email." msgstr "O email de verificação foi reenviado." -#: mediagoblin/auth/views.py:248 +#: mediagoblin/auth/views.py:265 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." @@ -89,43 +101,63 @@ msgstr "Título" msgid "Tags" msgstr "Etiquetas" -#: mediagoblin/edit/forms.py:31 +#: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 +msgid "Seperate tags by commas or spaces." +msgstr "" + +#: mediagoblin/edit/forms.py:33 msgid "Slug" msgstr "Arquivo" -#: mediagoblin/edit/forms.py:32 +#: mediagoblin/edit/forms.py:34 msgid "The slug can't be empty" msgstr "O arquivo não pode estar vazio" -#: mediagoblin/edit/forms.py:33 +#: mediagoblin/edit/forms.py:35 msgid "" "The title part of this media's URL. You usually don't need to change this." msgstr "" "A parte título da URL dessa mídia. Geralmente não é necessário alterar isso." -#: mediagoblin/edit/forms.py:40 +#: mediagoblin/edit/forms.py:42 msgid "Bio" msgstr "Biografia" -#: mediagoblin/edit/forms.py:43 +#: mediagoblin/edit/forms.py:45 msgid "Website" msgstr "Website" -#: mediagoblin/edit/views.py:64 +#: mediagoblin/edit/forms.py:49 +msgid "Old password" +msgstr "" + +#: mediagoblin/edit/forms.py:52 +msgid "New Password" +msgstr "" + +#: mediagoblin/edit/views.py:65 msgid "An entry with that slug already exists for this user." msgstr "Uma entrada com esse arquivo já existe para esse usuário" -#: mediagoblin/edit/views.py:85 +#: mediagoblin/edit/views.py:86 msgid "You are editing another user's media. Proceed with caution." msgstr "Você está editando a mídia de outro usuário. Tenha cuidado." -#: mediagoblin/edit/views.py:155 +#: mediagoblin/edit/views.py:156 msgid "You are editing a user's profile. Proceed with caution." msgstr "Você está editando um perfil de usuário. Tenha cuidado." -#: mediagoblin/process_media/errors.py:44 -msgid "Invalid file given for media type." -msgstr "Arquivo inválido para esse tipo de mídia" +#: mediagoblin/edit/views.py:171 +msgid "Wrong password" +msgstr "" + +#: mediagoblin/edit/views.py:192 +msgid "Profile edited!" +msgstr "" + +#: mediagoblin/media_types/__init__.py:61 +msgid "Could not find any file extension in \"{filename}\"" +msgstr "" #: mediagoblin/submit/forms.py:25 msgid "File" @@ -135,18 +167,18 @@ msgstr "Arquivo" msgid "Description of this work" msgstr "Descrição desse trabalho" -#: mediagoblin/submit/views.py:46 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "Você deve fornecer um arquivo." -#: mediagoblin/submit/views.py:49 -msgid "The file doesn't seem to be an image!" -msgstr "O arquivo não parece ser uma imagem!" - -#: mediagoblin/submit/views.py:121 +#: mediagoblin/submit/views.py:127 msgid "Woohoo! Submitted!" msgstr "Eba! Enviado!" +#: mediagoblin/submit/views.py:133 +msgid "Invalid file type." +msgstr "" + #: mediagoblin/templates/mediagoblin/404.html:21 msgid "Oops!" msgstr "Oops" @@ -167,29 +199,29 @@ msgstr "" msgid "Image of 404 goblin stressing out" msgstr "Imagem do goblin 404 aparecendo" -#: mediagoblin/templates/mediagoblin/base.html:22 -msgid "GNU MediaGoblin" -msgstr "GNU MediaGoblin" - -#: mediagoblin/templates/mediagoblin/base.html:47 +#: mediagoblin/templates/mediagoblin/base.html:49 msgid "MediaGoblin logo" msgstr "Logo MediaGoblin" -#: mediagoblin/templates/mediagoblin/base.html:52 +#: mediagoblin/templates/mediagoblin/base.html:54 msgid "Submit media" msgstr "Enviar mídia" -#: mediagoblin/templates/mediagoblin/base.html:63 -msgid "verify your email!" -msgstr "Verifique seu email!" +#: mediagoblin/templates/mediagoblin/base.html:65 +msgid "Verify your email!" +msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:73 +#: mediagoblin/templates/mediagoblin/base.html:72 +msgid "log out" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:75 #: mediagoblin/templates/mediagoblin/auth/login.html:27 -#: mediagoblin/templates/mediagoblin/auth/login.html:35 +#: mediagoblin/templates/mediagoblin/auth/login.html:45 msgid "Log in" msgstr "Entrar" -#: mediagoblin/templates/mediagoblin/base.html:89 +#: mediagoblin/templates/mediagoblin/base.html:91 msgid "" "Powered by MediaGoblin, a GNU project" @@ -202,71 +234,32 @@ msgid "Explore" msgstr "Explorar" #: mediagoblin/templates/mediagoblin/root.html:27 -msgid "Hi there, media lover! MediaGoblin is..." -msgstr "Olá amante de mídias. MediaGoblin é..." +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:28 +msgid "Your finest source for all goblin-related media." +msgstr "" #: mediagoblin/templates/mediagoblin/root.html:29 -msgid "The perfect place for your media!" -msgstr "O lugar perfeito para sua mídia!" - -#: mediagoblin/templates/mediagoblin/root.html:30 msgid "" -"A place for people to collaborate and show off original and derived " -"creations!" +"To add your own media, place comments, save your favourites and more, you " +"can log in with your MediaGoblin account." msgstr "" -"Um lugar para as pessoas colaborarem e mostrarem suas criações originais e " -"derivadas!" #: mediagoblin/templates/mediagoblin/root.html:31 -msgid "" -"Free, as in freedom. (We’re a GNU project, " -"after all.)" +msgid "Don't have one yet? It's easy!" msgstr "" -"Livre como a liberdade. (Afinal, somos um projeto GNU)" #: mediagoblin/templates/mediagoblin/root.html:32 -msgid "" -"Aiming to make the world a better place through decentralization and " -"(eventually, coming soon!) federation!" -msgstr "" -"Com o objetivo de fazer um mundo melhor através da descentralização e " -"(eventualmente, em breve) federação!" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "" -"Built for extensibility. (Multiple media types coming soon to the software," -" including video support!)" -msgstr "" -"Construído para extensibilidade. (Múltiplos tipos de mídia em breve, " -"incluindo suporte a vídeo) " - -#: mediagoblin/templates/mediagoblin/root.html:34 -msgid "" -"Powered by people like you. (You can help us improve this" -" software!)" -msgstr "" -"Desenvolvido por pessoas como você. (Você pode ajudar a melhorar " -"esse software)" - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Excited to join us?" -msgstr "Animado para juntar-se a nós?" - -#: mediagoblin/templates/mediagoblin/root.html:39 #, python-format msgid "" -"Create a free account\n" +"Create an account at this site\n" " or\n" -" Set up MediaGoblin on your own server" +" Set up MediaGoblin on your own server" msgstr "" -" Crie uma conta grátis \n" -" ou Configure seu próprio servidor MediaGoblin\n" -" " -#: mediagoblin/templates/mediagoblin/root.html:53 +#: mediagoblin/templates/mediagoblin/root.html:44 msgid "Most recent media" msgstr "Mídia mais recente" @@ -274,9 +267,13 @@ msgstr "Mídia mais recente" msgid "Enter your new password" msgstr "Digite sua nova senha" -#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:29 -msgid "Enter your username or email" -msgstr "Digite seu nome de usuário ou email" +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 +msgid "Recover password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:30 +msgid "Send instructions" +msgstr "" #: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 msgid "Your password has been changed. Try to log in now." @@ -315,22 +312,18 @@ msgstr "" msgid "Logging in failed!" msgstr "Autenticação falhou" -#: mediagoblin/templates/mediagoblin/auth/login.html:43 +#: mediagoblin/templates/mediagoblin/auth/login.html:35 msgid "Don't have an account yet?" msgstr "Ainda não tem conta?" -#: mediagoblin/templates/mediagoblin/auth/login.html:46 +#: mediagoblin/templates/mediagoblin/auth/login.html:36 msgid "Create one here!" msgstr "Crie uma aqui!" -#: mediagoblin/templates/mediagoblin/auth/login.html:49 +#: mediagoblin/templates/mediagoblin/auth/login.html:42 msgid "Forgot your password?" msgstr "Esqueceu sua senha?" -#: mediagoblin/templates/mediagoblin/auth/login.html:52 -msgid "Change it!" -msgstr "Altere-a" - #: mediagoblin/templates/mediagoblin/auth/register.html:27 msgid "Create an account!" msgstr "Criar uma conta!" @@ -375,9 +368,15 @@ msgstr "Salvar mudanças" msgid "Editing %(username)s's profile" msgstr "Editando perfil de %(username)s" -#: mediagoblin/templates/mediagoblin/listings/tag.html:31 -msgid "Media tagged with:" -msgstr "Mídia marcada como:" +#: mediagoblin/templates/mediagoblin/listings/tag.html:30 +#: mediagoblin/templates/mediagoblin/listings/tag.html:35 +#, python-format +msgid "Media tagged with: %(tag_name)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:19 +msgid "Original" +msgstr "" #: mediagoblin/templates/mediagoblin/submit/start.html:26 msgid "Submit yer media" @@ -387,16 +386,16 @@ msgstr "Envie sua mídia" msgid "Submit" msgstr "Enviar" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:32 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 +#, python-format +msgid "%(username)s's media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:37 #, python-format msgid "%(username)s's media" msgstr "Mídia de %(username)s " -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:52 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:32 -msgid "Sorry, no such user found." -msgstr "Desculpe, esse usuário não foi encontrado." - #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -428,29 +427,39 @@ msgstr "Nenhuma mídia em processo" msgid "These uploads failed to process:" msgstr "Esses envios não foram processados:" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:39 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:59 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:31 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:89 +#, python-format +msgid "%(username)s's profile" +msgstr "Perfil de %(username)s" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:43 +msgid "Sorry, no such user found." +msgstr "Desculpe, esse usuário não foi encontrado." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:50 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:70 msgid "Email verification needed" msgstr "Verificação de email necessária" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:42 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:53 msgid "Almost done! Your account still needs to be activated." msgstr "Quase pronto! Sua conta ainda precisa ser ativada" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:58 msgid "" "An email should arrive in a few moments with instructions on how to do so." msgstr "Um email deve chegar em instantes com instruções de como fazê-lo." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:51 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 msgid "In case it doesn't:" msgstr "Caso contrário:" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:54 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:65 msgid "Resend verification email" msgstr "Reenviar email de verificação" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:73 msgid "" "Someone has registered an account with this username, but it still has to be" " activated." @@ -458,7 +467,7 @@ msgstr "" "Alguém registrou uma conta com esse nome de usuário, mas ainda precisa ser " "ativada." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:79 #, python-format msgid "" "If you are that person but you've lost your verification email, you can efetuar login e reenviá-la." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:78 -#, python-format -msgid "%(username)s's profile" -msgstr "Perfil de %(username)s" - -#: mediagoblin/templates/mediagoblin/user_pages/user.html:85 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 msgid "Here's a spot to tell others about yourself." msgstr "Aqui é o lugar onde você fala de si para os outros." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:90 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:108 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:101 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:119 msgid "Edit profile" msgstr "Editar perfil" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:107 msgid "This user hasn't filled in their profile (yet)." msgstr "Esse usuário não preencheu seu perfil (ainda)." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:122 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:133 #, python-format msgid "View all of %(username)s's media" msgstr "Ver todas as mídias de %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:135 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:146 msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." @@ -498,11 +502,11 @@ msgstr "" "Aqui é onde sua mídia vai aparecer, mas parece que você não adicionou nada " "ainda." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:141 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:152 msgid "Add media" msgstr "Adicionar mídia" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:147 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:158 msgid "There doesn't seem to be any media here yet..." msgstr "Aparentemente não há nenhuma mídia aqui ainda..." @@ -522,6 +526,14 @@ msgstr "Mais novo" msgid "Older" msgstr "Mais velho" +#: mediagoblin/templates/mediagoblin/utils/tags.html:20 +msgid "Tagged with" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/tags.html:25 +msgid "and" +msgstr "" + #: mediagoblin/user_pages/forms.py:24 msgid "Comment" msgstr "Comentário" @@ -530,15 +542,23 @@ msgstr "Comentário" msgid "I am sure I want to delete this" msgstr "Eu tenho certeza de que quero pagar isso" -#: mediagoblin/user_pages/views.py:142 +#: mediagoblin/user_pages/views.py:155 msgid "Empty comments are not allowed." msgstr "" -#: mediagoblin/user_pages/views.py:148 +#: mediagoblin/user_pages/views.py:161 msgid "Comment posted!" msgstr "" -#: mediagoblin/user_pages/views.py:181 +#: mediagoblin/user_pages/views.py:183 +msgid "You deleted the media." +msgstr "" + +#: mediagoblin/user_pages/views.py:190 +msgid "The media was not deleted because you didn't check that you were sure." +msgstr "" + +#: mediagoblin/user_pages/views.py:198 msgid "You are about to delete another user's media. Proceed with caution." msgstr "Você vai apagar uma mídia de outro usuário. Tenha cuidado." diff --git a/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.po index 01fe5c48..96fd46d8 100644 --- a/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.po @@ -8,9 +8,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-11-01 23:14-0500\n" -"PO-Revision-Date: 2011-11-02 20:49+0000\n" -"Last-Translator: gap \n" +"POT-Creation-Date: 2011-11-27 15:25-0600\n" +"PO-Revision-Date: 2011-11-27 21:28+0000\n" +"Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,6 +19,10 @@ msgstr "" "Language: ro\n" "Plural-Forms: nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1))\n" +#: mediagoblin/processing.py:143 +msgid "Invalid file given for media type." +msgstr "Formatul fișierului nu corespunde cu tipul de media selectat." + #: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 msgid "Username" msgstr "Nume de utilizator" @@ -52,8 +56,8 @@ 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:77 -msgid "Sorry, that email address has already been taken." -msgstr "Ne pare rău, această adresă de e-mail este deja rezervată." +msgid "Sorry, a user with that email address already exists." +msgstr "" #: mediagoblin/auth/views.py:179 msgid "" @@ -67,11 +71,19 @@ msgstr "" msgid "The verification key or user id is incorrect" msgstr "Cheie de verificare sau user ID incorect." -#: mediagoblin/auth/views.py:207 +#: mediagoblin/auth/views.py:203 +msgid "You must be logged in so we know who to send the email to!" +msgstr "" + +#: mediagoblin/auth/views.py:211 +msgid "You've already verified your email address!" +msgstr "" + +#: mediagoblin/auth/views.py:224 msgid "Resent your verification email." msgstr "E-mail-ul de verificare a fost retrimis." -#: mediagoblin/auth/views.py:248 +#: mediagoblin/auth/views.py:265 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." @@ -87,45 +99,65 @@ msgstr "Titlu" msgid "Tags" msgstr "Etichete" -#: mediagoblin/edit/forms.py:31 +#: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 +msgid "Seperate tags by commas or spaces." +msgstr "" + +#: mediagoblin/edit/forms.py:33 msgid "Slug" msgstr "Identificator" -#: mediagoblin/edit/forms.py:32 +#: mediagoblin/edit/forms.py:34 msgid "The slug can't be empty" msgstr "Identificatorul nu poate să lipsească" -#: mediagoblin/edit/forms.py:33 +#: mediagoblin/edit/forms.py:35 msgid "" "The title part of this media's URL. You usually don't need to change this." msgstr "" "Partea din adresa acestui fișier corespunzătoare titlului. De regulă nu " "trebuie modificată." -#: mediagoblin/edit/forms.py:40 +#: mediagoblin/edit/forms.py:42 msgid "Bio" msgstr "Biografie" -#: mediagoblin/edit/forms.py:43 +#: mediagoblin/edit/forms.py:45 msgid "Website" msgstr "Sit Web" -#: mediagoblin/edit/views.py:64 +#: mediagoblin/edit/forms.py:49 +msgid "Old password" +msgstr "" + +#: mediagoblin/edit/forms.py:52 +msgid "New Password" +msgstr "" + +#: mediagoblin/edit/views.py:65 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:85 +#: mediagoblin/edit/views.py:86 msgid "You are editing another user's media. Proceed with caution." msgstr "Editezi fișierul unui alt utilizator. Se recomandă prudență." -#: mediagoblin/edit/views.py:155 +#: mediagoblin/edit/views.py:156 msgid "You are editing a user's profile. Proceed with caution." msgstr "Editezi profilul unui utilizator. Se recomandă prudență." -#: mediagoblin/process_media/errors.py:44 -msgid "Invalid file given for media type." -msgstr "Formatul fișierului nu corespunde cu tipul de media selectat." +#: mediagoblin/edit/views.py:171 +msgid "Wrong password" +msgstr "" + +#: mediagoblin/edit/views.py:192 +msgid "Profile edited!" +msgstr "" + +#: mediagoblin/media_types/__init__.py:61 +msgid "Could not find any file extension in \"{filename}\"" +msgstr "" #: mediagoblin/submit/forms.py:25 msgid "File" @@ -135,18 +167,18 @@ msgstr "Fișier" msgid "Description of this work" msgstr "Descrierea acestui fișier" -#: mediagoblin/submit/views.py:46 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "Trebuie să selectezi un fișier." -#: mediagoblin/submit/views.py:49 -msgid "The file doesn't seem to be an image!" -msgstr "Fișierul nu pare a fi o imagine!" - -#: mediagoblin/submit/views.py:121 +#: mediagoblin/submit/views.py:127 msgid "Woohoo! Submitted!" msgstr "Gata, trimis!" +#: mediagoblin/submit/views.py:133 +msgid "Invalid file type." +msgstr "" + #: mediagoblin/templates/mediagoblin/404.html:21 msgid "Oops!" msgstr "Oops!" @@ -167,29 +199,29 @@ msgstr "" msgid "Image of 404 goblin stressing out" msgstr "Imagine cu elful 404 stresat." -#: mediagoblin/templates/mediagoblin/base.html:22 -msgid "GNU MediaGoblin" -msgstr "GNU MediaGoblin" - -#: mediagoblin/templates/mediagoblin/base.html:47 +#: mediagoblin/templates/mediagoblin/base.html:49 msgid "MediaGoblin logo" msgstr "logo MediaGoblin" -#: mediagoblin/templates/mediagoblin/base.html:52 +#: mediagoblin/templates/mediagoblin/base.html:54 msgid "Submit media" msgstr "Transmite un fișier media" -#: mediagoblin/templates/mediagoblin/base.html:63 -msgid "verify your email!" -msgstr "verifică e-mail-ul!" +#: mediagoblin/templates/mediagoblin/base.html:65 +msgid "Verify your email!" +msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:73 +#: mediagoblin/templates/mediagoblin/base.html:72 +msgid "log out" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:75 #: mediagoblin/templates/mediagoblin/auth/login.html:27 -#: mediagoblin/templates/mediagoblin/auth/login.html:35 +#: mediagoblin/templates/mediagoblin/auth/login.html:45 msgid "Log in" msgstr "Autentificare" -#: mediagoblin/templates/mediagoblin/base.html:89 +#: mediagoblin/templates/mediagoblin/base.html:91 msgid "" "Powered by MediaGoblin, a GNU project" @@ -202,70 +234,32 @@ msgid "Explore" msgstr "Explorează" #: mediagoblin/templates/mediagoblin/root.html:27 -msgid "Hi there, media lover! MediaGoblin is..." -msgstr "Bună! MediaGoblin este..." +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:28 +msgid "Your finest source for all goblin-related media." +msgstr "" #: mediagoblin/templates/mediagoblin/root.html:29 -msgid "The perfect place for your media!" -msgstr "Locul perfect pentru fișierele tale media!" - -#: mediagoblin/templates/mediagoblin/root.html:30 msgid "" -"A place for people to collaborate and show off original and derived " -"creations!" +"To add your own media, place comments, save your favourites and more, you " +"can log in with your MediaGoblin account." msgstr "" -"Un loc unde oamenii colaborează și își expun creațiile originale și " -"derivate!" #: mediagoblin/templates/mediagoblin/root.html:31 -msgid "" -"Free, as in freedom. (We’re a GNU project, " -"after all.)" +msgid "Don't have one yet? It's easy!" msgstr "" -"Liber. (Suntem un proiect GNU, până la urmă.)" #: mediagoblin/templates/mediagoblin/root.html:32 -msgid "" -"Aiming to make the world a better place through decentralization and " -"(eventually, coming soon!) federation!" -msgstr "" -"Un pas spre o lume mai bună prin descentralizare și (în curând) " -"federalizare!" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "" -"Built for extensibility. (Multiple media types coming soon to the software," -" including video support!)" -msgstr "" -"Proiectat să fie extensibil. (Software-ul va avea în curând suport pentru " -"mai multe formate de media, inclusiv pentru video!)" - -#: mediagoblin/templates/mediagoblin/root.html:34 -msgid "" -"Powered by people like you. (You can help us improve this" -" software!)" -msgstr "" -"Animat de oameni ca tine. (Ne poți ajuta să îmbunătățim" -" acest software!)" - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Excited to join us?" -msgstr "Vrei să ni te alături?" - -#: mediagoblin/templates/mediagoblin/root.html:39 #, python-format msgid "" -"Create a free account\n" +"Create an account at this site\n" " or\n" -" Set up MediaGoblin on your own server" +" Set up MediaGoblin on your own server" msgstr "" -"Creează gratuit un cont\n" -" sau\n" -" instalează MediaGoblin pe serverul tău" -#: mediagoblin/templates/mediagoblin/root.html:53 +#: mediagoblin/templates/mediagoblin/root.html:44 msgid "Most recent media" msgstr "Cele mai recente fișiere" @@ -273,9 +267,13 @@ msgstr "Cele mai recente fișiere" msgid "Enter your new password" msgstr "Introdu noua parolă" -#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:29 -msgid "Enter your username or email" -msgstr "Introdu numele de utilizator sau adresa de e-mail" +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 +msgid "Recover password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:30 +msgid "Send instructions" +msgstr "" #: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 msgid "Your password has been changed. Try to log in now." @@ -313,22 +311,18 @@ msgstr "" msgid "Logging in failed!" msgstr "Autentificare eșuată!" -#: mediagoblin/templates/mediagoblin/auth/login.html:43 +#: mediagoblin/templates/mediagoblin/auth/login.html:35 msgid "Don't have an account yet?" msgstr "Nu ai un cont?" -#: mediagoblin/templates/mediagoblin/auth/login.html:46 +#: mediagoblin/templates/mediagoblin/auth/login.html:36 msgid "Create one here!" msgstr "Creează-l aici!" -#: mediagoblin/templates/mediagoblin/auth/login.html:49 +#: mediagoblin/templates/mediagoblin/auth/login.html:42 msgid "Forgot your password?" msgstr "Ai uitat parola?" -#: mediagoblin/templates/mediagoblin/auth/login.html:52 -msgid "Change it!" -msgstr "Schimb-o!" - #: mediagoblin/templates/mediagoblin/auth/register.html:27 msgid "Create an account!" msgstr "Creează un cont!" @@ -373,9 +367,15 @@ msgstr "Salvează modificările" msgid "Editing %(username)s's profile" msgstr "Editare profil %(username)s" -#: mediagoblin/templates/mediagoblin/listings/tag.html:31 -msgid "Media tagged with:" -msgstr "Etichete:" +#: mediagoblin/templates/mediagoblin/listings/tag.html:30 +#: mediagoblin/templates/mediagoblin/listings/tag.html:35 +#, python-format +msgid "Media tagged with: %(tag_name)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:19 +msgid "Original" +msgstr "" #: mediagoblin/templates/mediagoblin/submit/start.html:26 msgid "Submit yer media" @@ -385,16 +385,16 @@ msgstr "Trimite fișierele tale media" msgid "Submit" msgstr "Trimite" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:32 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 +#, python-format +msgid "%(username)s's media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:37 #, python-format msgid "%(username)s's media" msgstr "Fișierele media ale lui %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:52 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:32 -msgid "Sorry, no such user found." -msgstr "Ne pare rău, nu am găsit utilizatorul căutat." - #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -425,29 +425,39 @@ msgstr "Niciun fișier în curs de procesare" msgid "These uploads failed to process:" msgstr "Aceste fișiere nu au putut fi procesate:" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:39 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:59 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:31 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:89 +#, python-format +msgid "%(username)s's profile" +msgstr "Profil %(username)s" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:43 +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:50 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:70 msgid "Email verification needed" msgstr "Este necesară confirmarea adresei de e-mail" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:42 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:53 msgid "Almost done! Your account still needs to be activated." msgstr "Aproape gata! Mai trebuie doar să activezi contul." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:58 msgid "" "An email should arrive in a few moments with instructions on how to do so." msgstr "Vei primi în scurt timp un e-mail cu instrucțiuni." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:51 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 msgid "In case it doesn't:" msgstr "Dacă nu-l primești:" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:54 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:65 msgid "Resend verification email" msgstr "Retrimite mesajul de verificare" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:73 msgid "" "Someone has registered an account with this username, but it still has to be" " activated." @@ -455,7 +465,7 @@ msgstr "" "Cineva a înregistrat un cont cu acest nume de utilizator, dar contul nu a " "fost încă activat." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:79 #, python-format msgid "" "If you are that person but you've lost your verification email, you can autentifici pentru a-l retrimite." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:78 -#, python-format -msgid "%(username)s's profile" -msgstr "Profil %(username)s" - -#: mediagoblin/templates/mediagoblin/user_pages/user.html:85 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 msgid "Here's a spot to tell others about yourself." msgstr "Aici poți spune altora ceva despre tine." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:90 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:108 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:101 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:119 msgid "Edit profile" msgstr "Editare profil" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:107 msgid "This user hasn't filled in their profile (yet)." msgstr "Acest utilizator nu și-a completat (încă) profilul." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:122 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:133 #, python-format msgid "View all of %(username)s's media" msgstr "Vezi toate fișierele media ale lui %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:135 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:146 msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." @@ -495,11 +500,11 @@ msgstr "" "Aici vor apărea fișierele tale media, dar se pare că încă nu ai trimis " "nimic." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:141 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:152 msgid "Add media" msgstr "Trimite fișier" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:147 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:158 msgid "There doesn't seem to be any media here yet..." msgstr "Nu pare să existe niciun fișier media deocamdată..." @@ -519,6 +524,14 @@ msgstr "Mai noi" msgid "Older" msgstr "Mai vechi" +#: mediagoblin/templates/mediagoblin/utils/tags.html:20 +msgid "Tagged with" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/tags.html:25 +msgid "and" +msgstr "" + #: mediagoblin/user_pages/forms.py:24 msgid "Comment" msgstr "Scrie un comentariu" @@ -527,15 +540,23 @@ msgstr "Scrie un comentariu" msgid "I am sure I want to delete this" msgstr "Sunt sigur că doresc să șterg" -#: mediagoblin/user_pages/views.py:142 +#: mediagoblin/user_pages/views.py:155 msgid "Empty comments are not allowed." msgstr "Comentariul trebuie să aibă un conținut." -#: mediagoblin/user_pages/views.py:148 +#: mediagoblin/user_pages/views.py:161 msgid "Comment posted!" msgstr "Comentariul a fost transmis." -#: mediagoblin/user_pages/views.py:181 +#: mediagoblin/user_pages/views.py:183 +msgid "You deleted the media." +msgstr "" + +#: mediagoblin/user_pages/views.py:190 +msgid "The media was not deleted because you didn't check that you were sure." +msgstr "" + +#: mediagoblin/user_pages/views.py:198 msgid "You are about to delete another user's media. Proceed with caution." msgstr "" "Urmează să ștergi fișierele media ale unui alt utilizator. Se recomandă " diff --git a/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.po index f4bfbd67..9fb1ce08 100644 --- a/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.po @@ -8,9 +8,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-11-01 23:14-0500\n" -"PO-Revision-Date: 2011-11-04 11:13+0000\n" -"Last-Translator: aleksejrs \n" +"POT-Creation-Date: 2011-11-27 15:25-0600\n" +"PO-Revision-Date: 2011-11-27 21:28+0000\n" +"Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,6 +19,10 @@ msgstr "" "Language: ru\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/processing.py:143 +msgid "Invalid file given for media type." +msgstr "Неправильный формат файла." + #: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 msgid "Username" msgstr "Логин" @@ -52,8 +56,8 @@ msgid "Sorry, a user with that name already exists." msgstr "Извините, пользователь с этим именем уже зарегистрирован." #: mediagoblin/auth/views.py:77 -msgid "Sorry, that email address has already been taken." -msgstr "Извините, этот адрес электронной почты уже занят." +msgid "Sorry, a user with that email address already exists." +msgstr "" #: mediagoblin/auth/views.py:179 msgid "" @@ -67,11 +71,19 @@ msgstr "" msgid "The verification key or user id is incorrect" msgstr "Неверный ключ проверки или идентификатор пользователя" -#: mediagoblin/auth/views.py:207 +#: mediagoblin/auth/views.py:203 +msgid "You must be logged in so we know who to send the email to!" +msgstr "" + +#: mediagoblin/auth/views.py:211 +msgid "You've already verified your email address!" +msgstr "" + +#: mediagoblin/auth/views.py:224 msgid "Resent your verification email." msgstr "Переслать сообщение с подтверждением аккаунта." -#: mediagoblin/auth/views.py:248 +#: mediagoblin/auth/views.py:265 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." @@ -88,45 +100,65 @@ msgstr "Название" msgid "Tags" msgstr "Метки" -#: mediagoblin/edit/forms.py:31 +#: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 +msgid "Seperate tags by commas or spaces." +msgstr "" + +#: mediagoblin/edit/forms.py:33 msgid "Slug" msgstr "Отличительная часть адреса" -#: mediagoblin/edit/forms.py:32 +#: mediagoblin/edit/forms.py:34 msgid "The slug can't be empty" msgstr "Отличительная часть адреса необходима" -#: mediagoblin/edit/forms.py:33 +#: mediagoblin/edit/forms.py:35 msgid "" "The title part of this media's URL. You usually don't need to change this." msgstr "" "Часть адреса этого файла, производная от его названия. Её обычно не нужно " "изменять." -#: mediagoblin/edit/forms.py:40 +#: mediagoblin/edit/forms.py:42 msgid "Bio" msgstr "Биография" -#: mediagoblin/edit/forms.py:43 +#: mediagoblin/edit/forms.py:45 msgid "Website" msgstr "Сайт" -#: mediagoblin/edit/views.py:64 +#: mediagoblin/edit/forms.py:49 +msgid "Old password" +msgstr "" + +#: mediagoblin/edit/forms.py:52 +msgid "New Password" +msgstr "" + +#: mediagoblin/edit/views.py:65 msgid "An entry with that slug already exists for this user." msgstr "" "У этого пользователя уже есть файл с такой отличительной частью адреса." -#: mediagoblin/edit/views.py:85 +#: mediagoblin/edit/views.py:86 msgid "You are editing another user's media. Proceed with caution." msgstr "Вы редактируете файлы другого пользователя. Будьте осторожны." -#: mediagoblin/edit/views.py:155 +#: mediagoblin/edit/views.py:156 msgid "You are editing a user's profile. Proceed with caution." msgstr "Вы редактируете профиль пользователя. Будьте осторожны." -#: mediagoblin/process_media/errors.py:44 -msgid "Invalid file given for media type." -msgstr "Неправильный формат файла." +#: mediagoblin/edit/views.py:171 +msgid "Wrong password" +msgstr "" + +#: mediagoblin/edit/views.py:192 +msgid "Profile edited!" +msgstr "" + +#: mediagoblin/media_types/__init__.py:61 +msgid "Could not find any file extension in \"{filename}\"" +msgstr "" #: mediagoblin/submit/forms.py:25 msgid "File" @@ -136,18 +168,18 @@ msgstr "Файл" msgid "Description of this work" msgstr "Описание этого произведения" -#: mediagoblin/submit/views.py:46 +#: mediagoblin/submit/views.py:49 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:121 +#: mediagoblin/submit/views.py:127 msgid "Woohoo! Submitted!" msgstr "Ура! Файл загружен!" +#: mediagoblin/submit/views.py:133 +msgid "Invalid file type." +msgstr "" + #: mediagoblin/templates/mediagoblin/404.html:21 msgid "Oops!" msgstr "Ой!" @@ -160,35 +192,35 @@ msgstr "Кажется, такой страницы не существует. msgid "" "If you're sure the address is correct, maybe the page you're looking for has" " been moved or deleted." -msgstr "Возможно, страница которую вы ищете была удалена или переехала." +msgstr "Возможно, страница, которую вы ищете, была удалена или переехала." #: mediagoblin/templates/mediagoblin/404.html:32 msgid "Image of 404 goblin stressing out" msgstr "Изображение 404 нервничающего гоблина" -#: mediagoblin/templates/mediagoblin/base.html:22 -msgid "GNU MediaGoblin" -msgstr "GNU MediaGoblin" - -#: mediagoblin/templates/mediagoblin/base.html:47 +#: mediagoblin/templates/mediagoblin/base.html:49 msgid "MediaGoblin logo" msgstr "Символ MediaGoblin" -#: mediagoblin/templates/mediagoblin/base.html:52 +#: mediagoblin/templates/mediagoblin/base.html:54 msgid "Submit media" msgstr "Загрузить файл" -#: mediagoblin/templates/mediagoblin/base.html:63 -msgid "verify your email!" -msgstr "подтвердите ваш адрес электронной почты!" +#: mediagoblin/templates/mediagoblin/base.html:65 +msgid "Verify your email!" +msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:73 +#: mediagoblin/templates/mediagoblin/base.html:72 +msgid "log out" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:75 #: mediagoblin/templates/mediagoblin/auth/login.html:27 -#: mediagoblin/templates/mediagoblin/auth/login.html:35 +#: mediagoblin/templates/mediagoblin/auth/login.html:45 msgid "Log in" msgstr "Войти" -#: mediagoblin/templates/mediagoblin/base.html:89 +#: mediagoblin/templates/mediagoblin/base.html:91 msgid "" "Powered by MediaGoblin, a GNU project" @@ -201,66 +233,32 @@ msgid "Explore" msgstr "" #: mediagoblin/templates/mediagoblin/root.html:27 -msgid "Hi there, media lover! MediaGoblin is..." -msgstr "Привет, любитель мультимедиа! MediaGoblin…" +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:28 +msgid "Your finest source for all goblin-related media." +msgstr "" #: mediagoblin/templates/mediagoblin/root.html:29 -msgid "The perfect place for your media!" -msgstr "Отличное место для ваших файлов!" - -#: mediagoblin/templates/mediagoblin/root.html:30 msgid "" -"A place for people to collaborate and show off original and derived " -"creations!" +"To add your own media, place comments, save your favourites and more, you " +"can log in with your MediaGoblin account." msgstr "" -"Место для того, чтобы совместно работать или просто показать свои " -"оригинальные и/или заимствованные создания!" #: mediagoblin/templates/mediagoblin/root.html:31 -msgid "" -"Free, as in freedom. (We’re a GNU project, " -"after all.)" -msgstr "Свободное ПО. (Мы же проект GNU.)" +msgid "Don't have one yet? It's easy!" +msgstr "" #: mediagoblin/templates/mediagoblin/root.html:32 -msgid "" -"Aiming to make the world a better place through decentralization and " -"(eventually, coming soon!) federation!" -msgstr "" -"Попытка сделать мир лучше с помощью децентрализации и (надеемся, что скоро!)" -" интеграции!" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "" -"Built for extensibility. (Multiple media types coming soon to the software," -" including video support!)" -msgstr "" -"Рассчитан на расширяемость. (В программе скоро должна появиться поддержка " -"других видов мультимедиа, таких как видео!)" - -#: mediagoblin/templates/mediagoblin/root.html:34 -msgid "" -"Powered by people like you. (You can help us improve this" -" software!)" -msgstr "" -"Поддерживается такими же, как и ты. (Ты можешь помочь сделать это" -" ПО лучше!)" - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Excited to join us?" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:39 #, python-format msgid "" -"Create a free account\n" +"Create an account at this site\n" " or\n" -" Set up MediaGoblin on your own server" +" Set up MediaGoblin on your own server" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:53 +#: mediagoblin/templates/mediagoblin/root.html:44 msgid "Most recent media" msgstr "Самые новые файлы" @@ -268,18 +266,24 @@ msgstr "Самые новые файлы" msgid "Enter your new password" msgstr "Введите свой новый пароль" -#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:29 -msgid "Enter your username or email" -msgstr "Введите Ваше имя пользователя или адрес электронной почты" +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 +msgid "Recover password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:30 +msgid "Send instructions" +msgstr "" #: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 msgid "Your password has been changed. Try to log in now." -msgstr "" +msgstr "Ваш пароль изменён. Теперь попробуйте представиться." #: mediagoblin/templates/mediagoblin/auth/fp_email_sent.html:22 msgid "" "Check your inbox. We sent an email with a URL for changing your password." msgstr "" +"Проверьте свой электронный почтовый ящик. Мы отправили сообщение с адресом " +"для изменения Вашего пароля." #: mediagoblin/templates/mediagoblin/auth/fp_verification_email.txt:19 #, python-format @@ -294,27 +298,32 @@ msgid "" "If you think this is an error, just ignore this email and continue being\n" "a happy goblin!" msgstr "" +"Привет, %(username)s,\n" +"\n" +"чтобы сменить свой пароль от GNU MediaGoblin, откройте\n" +"следующий URL вашим веб‐браузером:\n" +"\n" +"%(verification_url)s\n" +"\n" +"Если вы думаете, что это какая‐то ошибка, то игнорируйте\n" +"это сообщение и продолжайте быть счастливым гоблином!" #: mediagoblin/templates/mediagoblin/auth/login.html:30 msgid "Logging in failed!" msgstr "Авторизация неуспешна!" -#: mediagoblin/templates/mediagoblin/auth/login.html:43 +#: mediagoblin/templates/mediagoblin/auth/login.html:35 msgid "Don't have an account yet?" msgstr "Ещё нету аккаунта?" -#: mediagoblin/templates/mediagoblin/auth/login.html:46 +#: mediagoblin/templates/mediagoblin/auth/login.html:36 msgid "Create one here!" msgstr "Создайте здесь!" -#: mediagoblin/templates/mediagoblin/auth/login.html:49 +#: mediagoblin/templates/mediagoblin/auth/login.html:42 msgid "Forgot your password?" msgstr "Забыли свой пароль?" -#: mediagoblin/templates/mediagoblin/auth/login.html:52 -msgid "Change it!" -msgstr "Смените его!" - #: mediagoblin/templates/mediagoblin/auth/register.html:27 msgid "Create an account!" msgstr "Создать аккаунт!" @@ -359,9 +368,15 @@ msgstr "Сохранить изменения" 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:30 +#: mediagoblin/templates/mediagoblin/listings/tag.html:35 +#, python-format +msgid "Media tagged with: %(tag_name)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:19 +msgid "Original" +msgstr "" #: mediagoblin/templates/mediagoblin/submit/start.html:26 msgid "Submit yer media" @@ -371,16 +386,16 @@ msgstr "Загрузить файл(ы)" msgid "Submit" msgstr "Подтвердить" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:32 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 +#, python-format +msgid "%(username)s's media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:37 #, python-format msgid "%(username)s's media" msgstr "Файлы пользователя %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:52 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:32 -msgid "Sorry, no such user found." -msgstr "Извините, но такой пользователь не найден." - #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -412,38 +427,48 @@ msgstr "Нету файлов для обработки" msgid "These uploads failed to process:" msgstr "Обработка этих файлов вызвала ошибку:" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:39 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:59 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:31 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:89 +#, python-format +msgid "%(username)s's profile" +msgstr "Профиль пользователя %(username)s" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:43 +msgid "Sorry, no such user found." +msgstr "Извините, но такой пользователь не найден." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:50 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:70 msgid "Email verification needed" msgstr "Нужно подтверждение почтового адреса" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:42 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:53 msgid "Almost done! Your account still needs to be activated." msgstr "Почти закончили! Теперь надо активировать ваш аккаунт." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:58 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 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 msgid "In case it doesn't:" msgstr "А если нет, то:" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:54 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:65 msgid "Resend verification email" msgstr "" "Повторно отправить сообщение для подверждения адреса электронной почты" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:73 msgid "" "Someone has registered an account with this username, but it still has to be" " activated." msgstr "Кто‐то создал аккаунт с этим именем, но его еще надо активировать." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:79 #, python-format msgid "" "If you are that person but you've lost your verification email, you can войти и отправить его повторно." -#: 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:85 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 msgid "Here's a spot to tell others about yourself." msgstr "Здесь вы можете рассказать о себе." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:90 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:108 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:101 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:119 msgid "Edit profile" msgstr "Редактировать профиль" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:107 msgid "This user hasn't filled in their profile (yet)." msgstr "Это пользователь не заполнил свой профайл (пока)." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:122 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:133 #, python-format msgid "View all of %(username)s's media" msgstr "Смотреть все файлы %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:135 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:146 msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." msgstr "Ваши файлы появятся здесь, когда вы их добавите." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:141 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:152 msgid "Add media" msgstr "Добавить файлы" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:147 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:158 msgid "There doesn't seem to be any media here yet..." msgstr "Пока что тут файлов нет…" @@ -505,6 +525,14 @@ msgstr "Более новые" msgid "Older" msgstr "Более старые" +#: mediagoblin/templates/mediagoblin/utils/tags.html:20 +msgid "Tagged with" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/tags.html:25 +msgid "and" +msgstr "" + #: mediagoblin/user_pages/forms.py:24 msgid "Comment" msgstr "Комментарий" @@ -513,15 +541,23 @@ msgstr "Комментарий" msgid "I am sure I want to delete this" msgstr "Я уверен, что хочу удалить это" -#: mediagoblin/user_pages/views.py:142 +#: mediagoblin/user_pages/views.py:155 msgid "Empty comments are not allowed." msgstr "Empty comments are not allowed." -#: mediagoblin/user_pages/views.py:148 +#: mediagoblin/user_pages/views.py:161 msgid "Comment posted!" +msgstr "Комментарий размещён!" + +#: mediagoblin/user_pages/views.py:183 +msgid "You deleted the media." msgstr "" -#: mediagoblin/user_pages/views.py:181 +#: mediagoblin/user_pages/views.py:190 +msgid "The media was not deleted because you didn't check that you were sure." +msgstr "" + +#: mediagoblin/user_pages/views.py:198 msgid "You are about to delete another user's media. Proceed with caution." msgstr "Вы на пороге удаления файла другого пользователя. Будьте осторожны." diff --git a/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.po index d3196b9c..bee7b3b5 100644 --- a/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.po @@ -8,8 +8,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-11-01 23:14-0500\n" -"PO-Revision-Date: 2011-11-02 04:13+0000\n" +"POT-Creation-Date: 2011-11-27 15:25-0600\n" +"PO-Revision-Date: 2011-11-27 21:28+0000\n" "Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -19,6 +19,10 @@ msgstr "" "Language: sk\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2\n" +#: mediagoblin/processing.py:143 +msgid "Invalid file given for media type." +msgstr "Odovzdaný nesprávny súbor pre daný typ média." + #: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 msgid "Username" msgstr "Prihlasovacie meno" @@ -52,8 +56,8 @@ msgid "Sorry, a user with that name already exists." msgstr "Prepáč, rovnaké prihlasovacie meno už niekto používa." #: mediagoblin/auth/views.py:77 -msgid "Sorry, that email address has already been taken." -msgstr "Prepáč, daná e-mailová adresa už bola pri registrácii využitá." +msgid "Sorry, a user with that email address already exists." +msgstr "" #: mediagoblin/auth/views.py:179 msgid "" @@ -67,11 +71,19 @@ msgstr "" msgid "The verification key or user id is incorrect" msgstr "Nesprávny overovací kľúč alebo používateľské ID" -#: mediagoblin/auth/views.py:207 +#: mediagoblin/auth/views.py:203 +msgid "You must be logged in so we know who to send the email to!" +msgstr "" + +#: mediagoblin/auth/views.py:211 +msgid "You've already verified your email address!" +msgstr "" + +#: mediagoblin/auth/views.py:224 msgid "Resent your verification email." msgstr "Opätovne zaslať overovaciu správu." -#: mediagoblin/auth/views.py:248 +#: mediagoblin/auth/views.py:265 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." @@ -87,42 +99,62 @@ msgstr "Nadpis" msgid "Tags" msgstr "Štítky" -#: mediagoblin/edit/forms.py:31 +#: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 +msgid "Seperate tags by commas or spaces." +msgstr "" + +#: mediagoblin/edit/forms.py:33 msgid "Slug" msgstr "Unikátna časť adresy" -#: mediagoblin/edit/forms.py:32 +#: mediagoblin/edit/forms.py:34 msgid "The slug can't be empty" msgstr "Unikátna časť adresy musí byť vyplnená" -#: mediagoblin/edit/forms.py:33 +#: mediagoblin/edit/forms.py:35 msgid "" "The title part of this media's URL. You usually don't need to change this." msgstr "Titulná časť URL odkazu média. Zvyčajne to meniť nemusíš." -#: mediagoblin/edit/forms.py:40 +#: mediagoblin/edit/forms.py:42 msgid "Bio" msgstr "Bio" -#: mediagoblin/edit/forms.py:43 +#: mediagoblin/edit/forms.py:45 msgid "Website" msgstr "Webstránka" -#: mediagoblin/edit/views.py:64 +#: mediagoblin/edit/forms.py:49 +msgid "Old password" +msgstr "" + +#: mediagoblin/edit/forms.py:52 +msgid "New Password" +msgstr "" + +#: mediagoblin/edit/views.py:65 msgid "An entry with that slug already exists for this user." msgstr "Položku s rovnakou unikátnou časťou adresy už niekde máš." -#: mediagoblin/edit/views.py:85 +#: mediagoblin/edit/views.py:86 msgid "You are editing another user's media. Proceed with caution." msgstr "Upravuješ médiá niekoho iného. Pristupuj opatrne." -#: mediagoblin/edit/views.py:155 +#: mediagoblin/edit/views.py:156 msgid "You are editing a user's profile. Proceed with caution." msgstr "Upravuješ používateľský profil. Pristupuj opatrne." -#: mediagoblin/process_media/errors.py:44 -msgid "Invalid file given for media type." -msgstr "Odovzdaný nesprávny súbor pre daný typ média." +#: mediagoblin/edit/views.py:171 +msgid "Wrong password" +msgstr "" + +#: mediagoblin/edit/views.py:192 +msgid "Profile edited!" +msgstr "" + +#: mediagoblin/media_types/__init__.py:61 +msgid "Could not find any file extension in \"{filename}\"" +msgstr "" #: mediagoblin/submit/forms.py:25 msgid "File" @@ -132,18 +164,18 @@ msgstr "Súbor" msgid "Description of this work" msgstr "Charakteristika diela" -#: mediagoblin/submit/views.py:46 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "Poskytni súbor." -#: mediagoblin/submit/views.py:49 -msgid "The file doesn't seem to be an image!" -msgstr "Súbor najskôr nie je obrázkom!" - -#: mediagoblin/submit/views.py:121 +#: mediagoblin/submit/views.py:127 msgid "Woohoo! Submitted!" msgstr "Juchú! Úspešne vložené!" +#: mediagoblin/submit/views.py:133 +msgid "Invalid file type." +msgstr "" + #: mediagoblin/templates/mediagoblin/404.html:21 msgid "Oops!" msgstr "Ajaj!" @@ -164,29 +196,29 @@ msgstr "" msgid "Image of 404 goblin stressing out" msgstr "Obrázok stresujúceho goblina pri chybovom kóde č. 404" -#: mediagoblin/templates/mediagoblin/base.html:22 -msgid "GNU MediaGoblin" -msgstr "GNU MediaGoblin" - -#: mediagoblin/templates/mediagoblin/base.html:47 +#: mediagoblin/templates/mediagoblin/base.html:49 msgid "MediaGoblin logo" msgstr "MediaGoblin logo" -#: mediagoblin/templates/mediagoblin/base.html:52 +#: mediagoblin/templates/mediagoblin/base.html:54 msgid "Submit media" msgstr "Vložiť výtvor" -#: mediagoblin/templates/mediagoblin/base.html:63 -msgid "verify your email!" -msgstr "over si svoj e-mail!" +#: mediagoblin/templates/mediagoblin/base.html:65 +msgid "Verify your email!" +msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:73 +#: mediagoblin/templates/mediagoblin/base.html:72 +msgid "log out" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:75 #: mediagoblin/templates/mediagoblin/auth/login.html:27 -#: mediagoblin/templates/mediagoblin/auth/login.html:35 +#: mediagoblin/templates/mediagoblin/auth/login.html:45 msgid "Log in" msgstr "Prihlásenie" -#: mediagoblin/templates/mediagoblin/base.html:89 +#: mediagoblin/templates/mediagoblin/base.html:91 msgid "" "Powered by MediaGoblin, a GNU project" @@ -199,71 +231,32 @@ msgid "Explore" msgstr "Preskúmať" #: mediagoblin/templates/mediagoblin/root.html:27 -msgid "Hi there, media lover! MediaGoblin is..." -msgstr "Vitaj medzi nami, kreatívne stvorenie! MediaGoblin je..." +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:28 +msgid "Your finest source for all goblin-related media." +msgstr "" #: mediagoblin/templates/mediagoblin/root.html:29 -msgid "The perfect place for your media!" -msgstr "Parádne miesto pre tvoje výtvory!" - -#: mediagoblin/templates/mediagoblin/root.html:30 msgid "" -"A place for people to collaborate and show off original and derived " -"creations!" +"To add your own media, place comments, save your favourites and more, you " +"can log in with your MediaGoblin account." msgstr "" -"Miesto pre ľudí, vhodné na spoluprácu a vystavovanie tak originálnych, ako " -"aj odvodených kreácií!" #: mediagoblin/templates/mediagoblin/root.html:31 -msgid "" -"Free, as in freedom. (We’re a GNU project, " -"after all.)" +msgid "Don't have one yet? It's easy!" msgstr "" -"Voľné, vo význame slobody. (Koniec-koncov, sme predsa GNU projekt.)" #: mediagoblin/templates/mediagoblin/root.html:32 -msgid "" -"Aiming to make the world a better place through decentralization and " -"(eventually, coming soon!) federation!" -msgstr "" -"Zo snahou spraviť svet lepším miestom vďaka decentralizácii a (eventuálne, " -"už čoskoro!) federácii!" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "" -"Built for extensibility. (Multiple media types coming soon to the software," -" including video support!)" -msgstr "" -"S dôrazom na rozšíriteľnosť. (Podpora pre rozličné typy médií v tomto " -"softvéri už čoskoro, nevynímajúc videá!)" - -#: mediagoblin/templates/mediagoblin/root.html:34 -msgid "" -"Powered by people like you. (You can help us improve this" -" software!)" -msgstr "" -"Existujeme aj vďaka ľudom ako si ty. (Môžeš nám pomôcť softvér " -"vylepšiť!)" - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Excited to join us?" -msgstr "Tak čo, chceš sa pridať?" - -#: mediagoblin/templates/mediagoblin/root.html:39 #, python-format msgid "" -"Create a free account\n" +"Create an account at this site\n" " or\n" -" Set up MediaGoblin on your own server" +" Set up MediaGoblin on your own server" msgstr "" -"Vytvoriť bezplatný účet\n" -" alebo\n" -" Sprevádzkovať MediaGoblin na vlastnom serveri" -#: mediagoblin/templates/mediagoblin/root.html:53 +#: mediagoblin/templates/mediagoblin/root.html:44 msgid "Most recent media" msgstr "Najčerstvejšie výtvory" @@ -271,9 +264,13 @@ msgstr "Najčerstvejšie výtvory" msgid "Enter your new password" msgstr "Vlož svoje nové heslo" -#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:29 -msgid "Enter your username or email" -msgstr "Vlož svoje používateľské meno alebo e-mailovú adresu" +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 +msgid "Recover password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:30 +msgid "Send instructions" +msgstr "" #: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 msgid "Your password has been changed. Try to log in now." @@ -312,22 +309,18 @@ msgstr "" msgid "Logging in failed!" msgstr "Prihlásenie zlyhalo!" -#: mediagoblin/templates/mediagoblin/auth/login.html:43 +#: mediagoblin/templates/mediagoblin/auth/login.html:35 msgid "Don't have an account yet?" msgstr "Ešte nemáš účet?" -#: mediagoblin/templates/mediagoblin/auth/login.html:46 +#: mediagoblin/templates/mediagoblin/auth/login.html:36 msgid "Create one here!" msgstr "Vytvoriť jeden tu!" -#: mediagoblin/templates/mediagoblin/auth/login.html:49 +#: mediagoblin/templates/mediagoblin/auth/login.html:42 msgid "Forgot your password?" msgstr "Zabudnuté heslo?" -#: mediagoblin/templates/mediagoblin/auth/login.html:52 -msgid "Change it!" -msgstr "Zmeniť ho!" - #: mediagoblin/templates/mediagoblin/auth/register.html:27 msgid "Create an account!" msgstr "Vytvoriť účet!" @@ -373,9 +366,15 @@ msgstr "Uložiť zmeny" msgid "Editing %(username)s's profile" msgstr "Úprava profilu, ktorý vlastní %(username)s" -#: mediagoblin/templates/mediagoblin/listings/tag.html:31 -msgid "Media tagged with:" -msgstr "Výtvor značený štítkami:" +#: mediagoblin/templates/mediagoblin/listings/tag.html:30 +#: mediagoblin/templates/mediagoblin/listings/tag.html:35 +#, python-format +msgid "Media tagged with: %(tag_name)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:19 +msgid "Original" +msgstr "" #: mediagoblin/templates/mediagoblin/submit/start.html:26 msgid "Submit yer media" @@ -385,16 +384,16 @@ msgstr "Vlož svoj výtvor" msgid "Submit" msgstr "Vložiť" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:32 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 +#, python-format +msgid "%(username)s's media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:37 #, python-format msgid "%(username)s's media" msgstr "Výtvory, ktoré vlastní %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:52 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:32 -msgid "Sorry, no such user found." -msgstr "Prepáč, používateľské meno nenájdené." - #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -425,29 +424,39 @@ msgstr "Žiadne médiá v procese spracovania" msgid "These uploads failed to process:" msgstr "Nasledovné vloženia neprešli spracovaním:" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:39 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:59 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:31 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:89 +#, python-format +msgid "%(username)s's profile" +msgstr "Profil, ktorý vlastní %(username)s" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:43 +msgid "Sorry, no such user found." +msgstr "Prepáč, používateľské meno nenájdené." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:50 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:70 msgid "Email verification needed" msgstr "Potrebné overenie e-mailovej adresy" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:42 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:53 msgid "Almost done! Your account still needs to be activated." msgstr "Takmer hotovo! Ešte ti musí byť aktivovaný účet." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:58 msgid "" "An email should arrive in a few moments with instructions on how to do so." msgstr "E-mailová správa s popisom ako to spraviť, by mala onedlho doraziť." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:51 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 msgid "In case it doesn't:" msgstr "V prípade, že sa tak nestalo:" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:54 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:65 msgid "Resend verification email" msgstr "Opätovne zaslať overovaciu správu" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:73 msgid "" "Someone has registered an account with this username, but it still has to be" " activated." @@ -455,7 +464,7 @@ msgstr "" "Účet s týmto prihlasovacím menom je už registrovaný, avšak ešte stále " "neaktívny." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:79 #, python-format msgid "" "If you are that person but you've lost your verification email, you can prihlásiť a preposlať si ju." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:78 -#, python-format -msgid "%(username)s's profile" -msgstr "Profil, ktorý vlastní %(username)s" - -#: mediagoblin/templates/mediagoblin/user_pages/user.html:85 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 msgid "Here's a spot to tell others about yourself." msgstr "Povedz tu o sebe ostatným." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:90 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:108 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:101 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:119 msgid "Edit profile" msgstr "Upraviť profil" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:107 msgid "This user hasn't filled in their profile (yet)." msgstr "Dotyčná osoba ešte nevyplnila svoj profil (zatiaľ)." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:122 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:133 #, python-format msgid "View all of %(username)s's media" msgstr "Zhliadnuť všetky výtvory, ktoré vlastní %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:135 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:146 msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." msgstr "" "Všetky tvoje výtvory sa objavia práve tu, ale zatiaľ nemáš nič pridané." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:141 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:152 msgid "Add media" msgstr "Pridať výtvor" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:147 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:158 msgid "There doesn't seem to be any media here yet..." msgstr "Najskôr tu ešte nebudú žiadne výtvory..." @@ -518,6 +522,14 @@ msgstr "Novšie" msgid "Older" msgstr "Staršie" +#: mediagoblin/templates/mediagoblin/utils/tags.html:20 +msgid "Tagged with" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/tags.html:25 +msgid "and" +msgstr "" + #: mediagoblin/user_pages/forms.py:24 msgid "Comment" msgstr "Komentár" @@ -526,15 +538,23 @@ msgstr "Komentár" msgid "I am sure I want to delete this" msgstr "Jednoznačne to chcem odstrániť" -#: mediagoblin/user_pages/views.py:142 +#: mediagoblin/user_pages/views.py:155 msgid "Empty comments are not allowed." -msgstr "" +msgstr "Komentáre bez obsahu nepovolené." -#: mediagoblin/user_pages/views.py:148 +#: mediagoblin/user_pages/views.py:161 msgid "Comment posted!" +msgstr "Komentár odoslaný!" + +#: mediagoblin/user_pages/views.py:183 +msgid "You deleted the media." msgstr "" -#: mediagoblin/user_pages/views.py:181 +#: mediagoblin/user_pages/views.py:190 +msgid "The media was not deleted because you didn't check that you were sure." +msgstr "" + +#: mediagoblin/user_pages/views.py:198 msgid "You are about to delete another user's media. Proceed with caution." msgstr "Chystáš sa odstrániť výtvory niekoho iného. Pristupuj opatrne." diff --git a/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.po index cba4fdd0..77273ebe 100644 --- a/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.po @@ -8,8 +8,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-11-01 23:14-0500\n" -"PO-Revision-Date: 2011-11-02 04:13+0000\n" +"POT-Creation-Date: 2011-11-27 15:25-0600\n" +"PO-Revision-Date: 2011-11-27 21:28+0000\n" "Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -19,6 +19,10 @@ msgstr "" "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/processing.py:143 +msgid "Invalid file given for media type." +msgstr "Za vrsto vsebine je bila podana napačna datoteka." + #: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 msgid "Username" msgstr "Uporabniško ime" @@ -52,8 +56,8 @@ msgid "Sorry, a user with that name already exists." msgstr "Oprostite, uporabnik s tem imenom že obstaja." #: mediagoblin/auth/views.py:77 -msgid "Sorry, that email address has already been taken." -msgstr "Oprostite, ta e-poštni naslov je že v uporabi." +msgid "Sorry, a user with that email address already exists." +msgstr "" #: mediagoblin/auth/views.py:179 msgid "" @@ -67,11 +71,19 @@ msgstr "" msgid "The verification key or user id is incorrect" msgstr "Potrditveni ključ ali uporabniška identifikacija je napačna" -#: mediagoblin/auth/views.py:207 +#: mediagoblin/auth/views.py:203 +msgid "You must be logged in so we know who to send the email to!" +msgstr "" + +#: mediagoblin/auth/views.py:211 +msgid "You've already verified your email address!" +msgstr "" + +#: mediagoblin/auth/views.py:224 msgid "Resent your verification email." msgstr "Ponovno pošiljanje potrditvene e-pošte." -#: mediagoblin/auth/views.py:248 +#: mediagoblin/auth/views.py:265 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." @@ -85,42 +97,62 @@ msgstr "Naslov" msgid "Tags" msgstr "Oznake" -#: mediagoblin/edit/forms.py:31 +#: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 +msgid "Seperate tags by commas or spaces." +msgstr "" + +#: mediagoblin/edit/forms.py:33 msgid "Slug" msgstr "Oznaka" -#: mediagoblin/edit/forms.py:32 +#: mediagoblin/edit/forms.py:34 msgid "The slug can't be empty" msgstr "Oznaka ne sme biti prazna" -#: mediagoblin/edit/forms.py:33 +#: mediagoblin/edit/forms.py:35 msgid "" "The title part of this media's URL. You usually don't need to change this." msgstr "" -#: mediagoblin/edit/forms.py:40 +#: mediagoblin/edit/forms.py:42 msgid "Bio" msgstr "Biografija" -#: mediagoblin/edit/forms.py:43 +#: mediagoblin/edit/forms.py:45 msgid "Website" msgstr "Spletna stran" -#: mediagoblin/edit/views.py:64 +#: mediagoblin/edit/forms.py:49 +msgid "Old password" +msgstr "" + +#: mediagoblin/edit/forms.py:52 +msgid "New Password" +msgstr "" + +#: mediagoblin/edit/views.py:65 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:85 +#: mediagoblin/edit/views.py:86 msgid "You are editing another user's media. Proceed with caution." msgstr "Urejate vsebino drugega uporabnika. Nadaljujte pazljivo." -#: mediagoblin/edit/views.py:155 +#: mediagoblin/edit/views.py:156 msgid "You are editing a user's profile. Proceed with caution." msgstr "Urejate uporabniški profil. Nadaljujte pazljivo." -#: mediagoblin/process_media/errors.py:44 -msgid "Invalid file given for media type." -msgstr "Za vrsto vsebine je bila podana napačna datoteka." +#: mediagoblin/edit/views.py:171 +msgid "Wrong password" +msgstr "" + +#: mediagoblin/edit/views.py:192 +msgid "Profile edited!" +msgstr "" + +#: mediagoblin/media_types/__init__.py:61 +msgid "Could not find any file extension in \"{filename}\"" +msgstr "" #: mediagoblin/submit/forms.py:25 msgid "File" @@ -130,18 +162,18 @@ msgstr "Datoteka" msgid "Description of this work" msgstr "" -#: mediagoblin/submit/views.py:46 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "Podati morate datoteko." -#: mediagoblin/submit/views.py:49 -msgid "The file doesn't seem to be an image!" -msgstr "Kot kaže datoteka ni slika." - -#: mediagoblin/submit/views.py:121 +#: mediagoblin/submit/views.py:127 msgid "Woohoo! Submitted!" msgstr "Juhej! Poslano." +#: mediagoblin/submit/views.py:133 +msgid "Invalid file type." +msgstr "" + #: mediagoblin/templates/mediagoblin/404.html:21 msgid "Oops!" msgstr "Opa!" @@ -162,29 +194,29 @@ msgstr "" msgid "Image of 404 goblin stressing out" msgstr "Slika napake 404 s paničnim škratom" -#: mediagoblin/templates/mediagoblin/base.html:22 -msgid "GNU MediaGoblin" -msgstr "GNU MediaGoblin" - -#: mediagoblin/templates/mediagoblin/base.html:47 +#: mediagoblin/templates/mediagoblin/base.html:49 msgid "MediaGoblin logo" msgstr "Logotip MediaGoblin" -#: mediagoblin/templates/mediagoblin/base.html:52 +#: mediagoblin/templates/mediagoblin/base.html:54 msgid "Submit media" msgstr "Pošlji vsebino" -#: mediagoblin/templates/mediagoblin/base.html:63 -msgid "verify your email!" -msgstr "Preverite svojo e-pošto." +#: mediagoblin/templates/mediagoblin/base.html:65 +msgid "Verify your email!" +msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:73 +#: mediagoblin/templates/mediagoblin/base.html:72 +msgid "log out" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:75 #: mediagoblin/templates/mediagoblin/auth/login.html:27 -#: mediagoblin/templates/mediagoblin/auth/login.html:35 +#: mediagoblin/templates/mediagoblin/auth/login.html:45 msgid "Log in" msgstr "Prijava" -#: mediagoblin/templates/mediagoblin/base.html:89 +#: mediagoblin/templates/mediagoblin/base.html:91 msgid "" "Powered by MediaGoblin, a GNU project" @@ -195,66 +227,32 @@ msgid "Explore" msgstr "" #: mediagoblin/templates/mediagoblin/root.html:27 -msgid "Hi there, media lover! MediaGoblin is..." -msgstr "Pozdravljen, ljubitelj večpredstavnostnih vsebin! MediaGoblin je ..." +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:28 +msgid "Your finest source for all goblin-related media." +msgstr "" #: mediagoblin/templates/mediagoblin/root.html:29 -msgid "The perfect place for your media!" -msgstr "Popolno mesto za vaše večpredstavnostne vsebine." - -#: mediagoblin/templates/mediagoblin/root.html:30 msgid "" -"A place for people to collaborate and show off original and derived " -"creations!" +"To add your own media, place comments, save your favourites and more, you " +"can log in with your MediaGoblin account." msgstr "" -"Mesto, kjer ljudje lahko sodelujejo in razkazujejo originalne in predelane " -"stvaritve." #: mediagoblin/templates/mediagoblin/root.html:31 -msgid "" -"Free, as in freedom. (We’re a GNU project, " -"after all.)" +msgid "Don't have one yet? It's easy!" msgstr "" #: mediagoblin/templates/mediagoblin/root.html:32 -msgid "" -"Aiming to make the world a better place through decentralization and " -"(eventually, coming soon!) federation!" -msgstr "" -"Ustvarjen z namenom izboljšati svet, s pomočjo decentralizacije in (kmalu) " -"federacije." - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "" -"Built for extensibility. (Multiple media types coming soon to the software," -" including video support!)" -msgstr "" -"Zgrajen za razširjanje. (Kmalu bodo na voljo dodatne vrste vsebin, vključno " -"podpora za video)" - -#: mediagoblin/templates/mediagoblin/root.html:34 -msgid "" -"Powered by people like you. (You can help us improve this" -" software!)" -msgstr "" -"Sad dela ljudi, kot ste vi. (Pri izboljševanju nam lahko " -"pomagate tudi vi.)" - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Excited to join us?" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:39 #, python-format msgid "" -"Create a free account\n" +"Create an account at this site\n" " or\n" -" Set up MediaGoblin on your own server" +" Set up MediaGoblin on your own server" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:53 +#: mediagoblin/templates/mediagoblin/root.html:44 msgid "Most recent media" msgstr "" @@ -262,8 +260,12 @@ msgstr "" msgid "Enter your new password" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:29 -msgid "Enter your username or email" +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 +msgid "Recover password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:30 +msgid "Send instructions" msgstr "" #: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 @@ -293,22 +295,18 @@ msgstr "" msgid "Logging in failed!" msgstr "Prijava ni uspela." -#: mediagoblin/templates/mediagoblin/auth/login.html:43 +#: mediagoblin/templates/mediagoblin/auth/login.html:35 msgid "Don't have an account yet?" msgstr "Še nimate računa?" -#: mediagoblin/templates/mediagoblin/auth/login.html:46 +#: mediagoblin/templates/mediagoblin/auth/login.html:36 msgid "Create one here!" msgstr "Ustvarite si ga." -#: mediagoblin/templates/mediagoblin/auth/login.html:49 +#: mediagoblin/templates/mediagoblin/auth/login.html:42 msgid "Forgot your password?" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/login.html:52 -msgid "Change it!" -msgstr "" - #: mediagoblin/templates/mediagoblin/auth/register.html:27 msgid "Create an account!" msgstr "Ustvarite račun." @@ -354,9 +352,15 @@ msgstr "Shrani spremembe" msgid "Editing %(username)s's profile" msgstr "Urejanje profila – %(username)s" -#: mediagoblin/templates/mediagoblin/listings/tag.html:31 -msgid "Media tagged with:" -msgstr "Vsebina označena z:" +#: mediagoblin/templates/mediagoblin/listings/tag.html:30 +#: mediagoblin/templates/mediagoblin/listings/tag.html:35 +#, python-format +msgid "Media tagged with: %(tag_name)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:19 +msgid "Original" +msgstr "" #: mediagoblin/templates/mediagoblin/submit/start.html:26 msgid "Submit yer media" @@ -366,16 +370,16 @@ msgstr "Pošljite svojo vsebino" msgid "Submit" msgstr "Pošlji" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:32 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 +#, python-format +msgid "%(username)s's media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:37 #, python-format msgid "%(username)s's media" msgstr "Vsebina uporabnika %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:52 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:32 -msgid "Sorry, no such user found." -msgstr "Oprostite, tega uporabnika ni bilo moč najti." - #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -406,29 +410,39 @@ msgstr "V obdelavi ni nobene vsebine" msgid "These uploads failed to process:" msgstr "Teh vsebin ni bilo moč obdelati:" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:39 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:59 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:31 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:89 +#, python-format +msgid "%(username)s's profile" +msgstr "Profil – %(username)s" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:43 +msgid "Sorry, no such user found." +msgstr "Oprostite, tega uporabnika ni bilo moč najti." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:50 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:70 msgid "Email verification needed" msgstr "Potrebna je potrditev prek e-pošte" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:42 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:53 msgid "Almost done! Your account still needs to be activated." msgstr "Skoraj ste zaključili. Svoj račun morate le še aktivirati." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:58 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:51 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 msgid "In case it doesn't:" msgstr "Če je ne prejmete:" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:54 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:65 msgid "Resend verification email" msgstr "Ponovno pošlji potrditveno e-pošto" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:73 msgid "" "Someone has registered an account with this username, but it still has to be" " activated." @@ -436,7 +450,7 @@ msgstr "" "Nekdo je s tem uporabniškim imenom že registriral račun, vendar mora biti še" " aktiviran." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:79 #, python-format msgid "" "If you are that person but you've lost your verification email, you can prijavite in jo ponovno pošljete." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:78 -#, python-format -msgid "%(username)s's profile" -msgstr "Profil – %(username)s" - -#: mediagoblin/templates/mediagoblin/user_pages/user.html:85 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 msgid "Here's a spot to tell others about yourself." msgstr "Na tem mestu lahko drugim poveste nekaj o sebi." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:90 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:108 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:101 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:119 msgid "Edit profile" msgstr "Uredi profil" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:107 msgid "This user hasn't filled in their profile (yet)." msgstr "Ta uporabnik še ni izpolnil svojega profila." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:122 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:133 #, python-format msgid "View all of %(username)s's media" msgstr "Prikaži vso vsebino uporabnika %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:135 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:146 msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." msgstr "Tu bo prikazana vaša vsebina, a trenutno še niste dodali nič." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:141 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:152 msgid "Add media" msgstr "Dodaj vsebino" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:147 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:158 msgid "There doesn't seem to be any media here yet..." msgstr "Videti je, da tu še ni nobene vsebine ..." @@ -498,6 +507,14 @@ msgstr "" msgid "Older" msgstr "" +#: mediagoblin/templates/mediagoblin/utils/tags.html:20 +msgid "Tagged with" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/tags.html:25 +msgid "and" +msgstr "" + #: mediagoblin/user_pages/forms.py:24 msgid "Comment" msgstr "Komentar" @@ -506,15 +523,23 @@ msgstr "Komentar" msgid "I am sure I want to delete this" msgstr "" -#: mediagoblin/user_pages/views.py:142 +#: mediagoblin/user_pages/views.py:155 msgid "Empty comments are not allowed." msgstr "" -#: mediagoblin/user_pages/views.py:148 +#: mediagoblin/user_pages/views.py:161 msgid "Comment posted!" msgstr "" -#: mediagoblin/user_pages/views.py:181 +#: mediagoblin/user_pages/views.py:183 +msgid "You deleted the media." +msgstr "" + +#: mediagoblin/user_pages/views.py:190 +msgid "The media was not deleted because you didn't check that you were sure." +msgstr "" + +#: mediagoblin/user_pages/views.py:198 msgid "You are about to delete another user's media. Proceed with caution." msgstr "" diff --git a/mediagoblin/i18n/sr/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/sr/LC_MESSAGES/mediagoblin.po index b4b2fb7b..0bdfc21c 100644 --- a/mediagoblin/i18n/sr/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/sr/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-11-01 23:14-0500\n" -"PO-Revision-Date: 2011-11-02 04:13+0000\n" +"POT-Creation-Date: 2011-11-27 15:25-0600\n" +"PO-Revision-Date: 2011-11-27 21:28+0000\n" "Last-Translator: cwebber \n" "Language-Team: Serbian (http://www.transifex.net/projects/p/mediagoblin/team/sr/)\n" "MIME-Version: 1.0\n" @@ -18,6 +18,10 @@ 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/processing.py:143 +msgid "Invalid file given for media type." +msgstr "" + #: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 msgid "Username" msgstr "" @@ -51,7 +55,7 @@ msgid "Sorry, a user with that name already exists." msgstr "" #: mediagoblin/auth/views.py:77 -msgid "Sorry, that email address has already been taken." +msgid "Sorry, a user with that email address already exists." msgstr "" #: mediagoblin/auth/views.py:179 @@ -64,11 +68,19 @@ msgstr "" msgid "The verification key or user id is incorrect" msgstr "" -#: mediagoblin/auth/views.py:207 +#: mediagoblin/auth/views.py:203 +msgid "You must be logged in so we know who to send the email to!" +msgstr "" + +#: mediagoblin/auth/views.py:211 +msgid "You've already verified your email address!" +msgstr "" + +#: mediagoblin/auth/views.py:224 msgid "Resent your verification email." msgstr "" -#: mediagoblin/auth/views.py:248 +#: mediagoblin/auth/views.py:265 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." @@ -82,41 +94,61 @@ msgstr "" msgid "Tags" msgstr "" -#: mediagoblin/edit/forms.py:31 -msgid "Slug" -msgstr "" - -#: mediagoblin/edit/forms.py:32 -msgid "The slug can't be empty" +#: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 +msgid "Seperate tags by commas or spaces." msgstr "" #: mediagoblin/edit/forms.py:33 +msgid "Slug" +msgstr "" + +#: mediagoblin/edit/forms.py:34 +msgid "The slug can't be empty" +msgstr "" + +#: mediagoblin/edit/forms.py:35 msgid "" "The title part of this media's URL. You usually don't need to change this." msgstr "" -#: mediagoblin/edit/forms.py:40 +#: mediagoblin/edit/forms.py:42 msgid "Bio" msgstr "" -#: mediagoblin/edit/forms.py:43 +#: mediagoblin/edit/forms.py:45 msgid "Website" msgstr "" -#: mediagoblin/edit/views.py:64 +#: mediagoblin/edit/forms.py:49 +msgid "Old password" +msgstr "" + +#: mediagoblin/edit/forms.py:52 +msgid "New Password" +msgstr "" + +#: mediagoblin/edit/views.py:65 msgid "An entry with that slug already exists for this user." msgstr "" -#: mediagoblin/edit/views.py:85 +#: mediagoblin/edit/views.py:86 msgid "You are editing another user's media. Proceed with caution." msgstr "" -#: mediagoblin/edit/views.py:155 +#: mediagoblin/edit/views.py:156 msgid "You are editing a user's profile. Proceed with caution." msgstr "" -#: mediagoblin/process_media/errors.py:44 -msgid "Invalid file given for media type." +#: mediagoblin/edit/views.py:171 +msgid "Wrong password" +msgstr "" + +#: mediagoblin/edit/views.py:192 +msgid "Profile edited!" +msgstr "" + +#: mediagoblin/media_types/__init__.py:61 +msgid "Could not find any file extension in \"{filename}\"" msgstr "" #: mediagoblin/submit/forms.py:25 @@ -127,16 +159,16 @@ msgstr "" msgid "Description of this work" msgstr "" -#: mediagoblin/submit/views.py:46 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "" -#: mediagoblin/submit/views.py:49 -msgid "The file doesn't seem to be an image!" +#: mediagoblin/submit/views.py:127 +msgid "Woohoo! Submitted!" msgstr "" -#: mediagoblin/submit/views.py:121 -msgid "Woohoo! Submitted!" +#: mediagoblin/submit/views.py:133 +msgid "Invalid file type." msgstr "" #: mediagoblin/templates/mediagoblin/404.html:21 @@ -157,29 +189,29 @@ msgstr "" msgid "Image of 404 goblin stressing out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:22 -msgid "GNU MediaGoblin" -msgstr "" - -#: mediagoblin/templates/mediagoblin/base.html:47 +#: mediagoblin/templates/mediagoblin/base.html:49 msgid "MediaGoblin logo" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:52 +#: mediagoblin/templates/mediagoblin/base.html:54 msgid "Submit media" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:63 -msgid "verify your email!" +#: mediagoblin/templates/mediagoblin/base.html:65 +msgid "Verify your email!" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:73 +#: mediagoblin/templates/mediagoblin/base.html:72 +msgid "log out" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:75 #: mediagoblin/templates/mediagoblin/auth/login.html:27 -#: mediagoblin/templates/mediagoblin/auth/login.html:35 +#: mediagoblin/templates/mediagoblin/auth/login.html:45 msgid "Log in" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:89 +#: mediagoblin/templates/mediagoblin/base.html:91 msgid "" "Powered by MediaGoblin, a GNU project" @@ -190,57 +222,32 @@ msgid "Explore" msgstr "" #: mediagoblin/templates/mediagoblin/root.html:27 -msgid "Hi there, media lover! MediaGoblin is..." +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:28 +msgid "Your finest source for all goblin-related media." msgstr "" #: mediagoblin/templates/mediagoblin/root.html:29 -msgid "The perfect place for your media!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:30 msgid "" -"A place for people to collaborate and show off original and derived " -"creations!" +"To add your own media, place comments, save your favourites and more, you " +"can log in with your MediaGoblin account." msgstr "" #: mediagoblin/templates/mediagoblin/root.html:31 -msgid "" -"Free, as in freedom. (We’re a GNU project, " -"after all.)" +msgid "Don't have one yet? It's easy!" msgstr "" #: mediagoblin/templates/mediagoblin/root.html:32 -msgid "" -"Aiming to make the world a better place through decentralization and " -"(eventually, coming soon!) federation!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "" -"Built for extensibility. (Multiple media types coming soon to the software," -" including video support!)" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:34 -msgid "" -"Powered by people like you. (You can help us improve this" -" software!)" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Excited to join us?" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:39 #, python-format msgid "" -"Create a free account\n" +"Create an account at this site\n" " or\n" -" Set up MediaGoblin on your own server" +" Set up MediaGoblin on your own server" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:53 +#: mediagoblin/templates/mediagoblin/root.html:44 msgid "Most recent media" msgstr "" @@ -248,8 +255,12 @@ msgstr "" msgid "Enter your new password" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:29 -msgid "Enter your username or email" +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 +msgid "Recover password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:30 +msgid "Send instructions" msgstr "" #: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 @@ -279,22 +290,18 @@ msgstr "" msgid "Logging in failed!" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/login.html:43 +#: mediagoblin/templates/mediagoblin/auth/login.html:35 msgid "Don't have an account yet?" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/login.html:46 +#: mediagoblin/templates/mediagoblin/auth/login.html:36 msgid "Create one here!" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/login.html:49 +#: mediagoblin/templates/mediagoblin/auth/login.html:42 msgid "Forgot your password?" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/login.html:52 -msgid "Change it!" -msgstr "" - #: mediagoblin/templates/mediagoblin/auth/register.html:27 msgid "Create an account!" msgstr "" @@ -334,8 +341,14 @@ msgstr "" msgid "Editing %(username)s's profile" msgstr "" -#: mediagoblin/templates/mediagoblin/listings/tag.html:31 -msgid "Media tagged with:" +#: mediagoblin/templates/mediagoblin/listings/tag.html:30 +#: mediagoblin/templates/mediagoblin/listings/tag.html:35 +#, python-format +msgid "Media tagged with: %(tag_name)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:19 +msgid "Original" msgstr "" #: mediagoblin/templates/mediagoblin/submit/start.html:26 @@ -346,14 +359,14 @@ msgstr "" msgid "Submit" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:32 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format -msgid "%(username)s's media" +msgid "%(username)s's media" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:52 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:32 -msgid "Sorry, no such user found." +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:37 +#, python-format +msgid "%(username)s's media" msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 @@ -386,75 +399,80 @@ msgstr "" msgid "These uploads failed to process:" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:39 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:59 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:31 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:89 +#, python-format +msgid "%(username)s's profile" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:43 +msgid "Sorry, no such user found." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:50 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:70 msgid "Email verification needed" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:42 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:53 msgid "Almost done! Your account still needs to be activated." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:58 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 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 msgid "In case it doesn't:" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:54 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:65 msgid "Resend verification email" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:73 msgid "" "Someone has registered an account with this username, but it still has to be" " activated." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:79 #, python-format msgid "" "If you are that person but you've lost your verification email, you can log in and resend it." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:78 -#, python-format -msgid "%(username)s's profile" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/user.html:85 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 msgid "Here's a spot to tell others about yourself." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:90 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:108 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:101 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:119 msgid "Edit profile" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:107 msgid "This user hasn't filled in their profile (yet)." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:122 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:133 #, python-format msgid "View all of %(username)s's media" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:135 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:146 msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:141 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:152 msgid "Add media" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:147 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:158 msgid "There doesn't seem to be any media here yet..." msgstr "" @@ -474,6 +492,14 @@ msgstr "" msgid "Older" msgstr "" +#: mediagoblin/templates/mediagoblin/utils/tags.html:20 +msgid "Tagged with" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/tags.html:25 +msgid "and" +msgstr "" + #: mediagoblin/user_pages/forms.py:24 msgid "Comment" msgstr "" @@ -482,15 +508,23 @@ msgstr "" msgid "I am sure I want to delete this" msgstr "" -#: mediagoblin/user_pages/views.py:142 +#: mediagoblin/user_pages/views.py:155 msgid "Empty comments are not allowed." msgstr "" -#: mediagoblin/user_pages/views.py:148 +#: mediagoblin/user_pages/views.py:161 msgid "Comment posted!" msgstr "" -#: mediagoblin/user_pages/views.py:181 +#: mediagoblin/user_pages/views.py:183 +msgid "You deleted the media." +msgstr "" + +#: mediagoblin/user_pages/views.py:190 +msgid "The media was not deleted because you didn't check that you were sure." +msgstr "" + +#: mediagoblin/user_pages/views.py:198 msgid "You are about to delete another user's media. Proceed with caution." msgstr "" diff --git a/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.po index 3ee44b18..37bd36c1 100644 --- a/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.po @@ -9,8 +9,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-11-01 23:14-0500\n" -"PO-Revision-Date: 2011-11-02 04:13+0000\n" +"POT-Creation-Date: 2011-11-27 15:25-0600\n" +"PO-Revision-Date: 2011-11-27 21:28+0000\n" "Last-Translator: cwebber \n" "Language-Team: Swedish (http://www.transifex.net/projects/p/mediagoblin/team/sv/)\n" "MIME-Version: 1.0\n" @@ -20,6 +20,10 @@ msgstr "" "Language: sv\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" +#: mediagoblin/processing.py:143 +msgid "Invalid file given for media type." +msgstr "Ogiltig fil för mediatypen." + #: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 msgid "Username" msgstr "Användarnamn" @@ -53,8 +57,8 @@ msgid "Sorry, a user with that name already exists." msgstr "En användare med det användarnamnet finns redan." #: mediagoblin/auth/views.py:77 -msgid "Sorry, that email address has already been taken." -msgstr "Den e-postadressen är redan tagen." +msgid "Sorry, a user with that email address already exists." +msgstr "" #: mediagoblin/auth/views.py:179 msgid "" @@ -68,11 +72,19 @@ msgstr "" msgid "The verification key or user id is incorrect" msgstr "Verifieringsnyckeln eller användar-IDt är fel." -#: mediagoblin/auth/views.py:207 +#: mediagoblin/auth/views.py:203 +msgid "You must be logged in so we know who to send the email to!" +msgstr "" + +#: mediagoblin/auth/views.py:211 +msgid "You've already verified your email address!" +msgstr "" + +#: mediagoblin/auth/views.py:224 msgid "Resent your verification email." msgstr "Skickade ett nytt verifierings-email." -#: mediagoblin/auth/views.py:248 +#: mediagoblin/auth/views.py:265 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." @@ -88,42 +100,62 @@ msgstr "Titel" msgid "Tags" msgstr "Taggar" -#: mediagoblin/edit/forms.py:31 +#: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 +msgid "Seperate tags by commas or spaces." +msgstr "" + +#: mediagoblin/edit/forms.py:33 msgid "Slug" msgstr "Sökvägsnamn" -#: mediagoblin/edit/forms.py:32 +#: mediagoblin/edit/forms.py:34 msgid "The slug can't be empty" msgstr "Sökvägsnamnet kan inte vara tomt" -#: mediagoblin/edit/forms.py:33 +#: mediagoblin/edit/forms.py:35 msgid "" "The title part of this media's URL. You usually don't need to change this." msgstr "Sökvägstitlen för din media. Du brukar inte behöva ändra denna." -#: mediagoblin/edit/forms.py:40 +#: mediagoblin/edit/forms.py:42 msgid "Bio" msgstr "Presentation" -#: mediagoblin/edit/forms.py:43 +#: mediagoblin/edit/forms.py:45 msgid "Website" msgstr "Hemsida" -#: mediagoblin/edit/views.py:64 +#: mediagoblin/edit/forms.py:49 +msgid "Old password" +msgstr "" + +#: mediagoblin/edit/forms.py:52 +msgid "New Password" +msgstr "" + +#: mediagoblin/edit/views.py:65 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:85 +#: mediagoblin/edit/views.py:86 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:155 +#: mediagoblin/edit/views.py:156 msgid "You are editing a user's profile. Proceed with caution." msgstr "Var försiktig, du redigerar en annan användares profil." -#: mediagoblin/process_media/errors.py:44 -msgid "Invalid file given for media type." -msgstr "Ogiltig fil för mediatypen." +#: mediagoblin/edit/views.py:171 +msgid "Wrong password" +msgstr "" + +#: mediagoblin/edit/views.py:192 +msgid "Profile edited!" +msgstr "" + +#: mediagoblin/media_types/__init__.py:61 +msgid "Could not find any file extension in \"{filename}\"" +msgstr "" #: mediagoblin/submit/forms.py:25 msgid "File" @@ -133,18 +165,18 @@ msgstr "Fil" msgid "Description of this work" msgstr "Beskrivning av verket" -#: mediagoblin/submit/views.py:46 +#: mediagoblin/submit/views.py:49 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:121 +#: mediagoblin/submit/views.py:127 msgid "Woohoo! Submitted!" msgstr "Tjohoo! Upladdat!" +#: mediagoblin/submit/views.py:133 +msgid "Invalid file type." +msgstr "" + #: mediagoblin/templates/mediagoblin/404.html:21 msgid "Oops!" msgstr "Ojoj!" @@ -165,29 +197,29 @@ msgstr "" msgid "Image of 404 goblin stressing out" msgstr "Bild av stressat 404-troll." -#: mediagoblin/templates/mediagoblin/base.html:22 -msgid "GNU MediaGoblin" -msgstr "GNU MediaGoblin" - -#: mediagoblin/templates/mediagoblin/base.html:47 +#: mediagoblin/templates/mediagoblin/base.html:49 msgid "MediaGoblin logo" msgstr "MediaGoblin-logotyp" -#: mediagoblin/templates/mediagoblin/base.html:52 +#: mediagoblin/templates/mediagoblin/base.html:54 msgid "Submit media" msgstr "Ladda upp" -#: mediagoblin/templates/mediagoblin/base.html:63 -msgid "verify your email!" -msgstr "Verifiera din e-postadress!" +#: mediagoblin/templates/mediagoblin/base.html:65 +msgid "Verify your email!" +msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:73 +#: mediagoblin/templates/mediagoblin/base.html:72 +msgid "log out" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:75 #: mediagoblin/templates/mediagoblin/auth/login.html:27 -#: mediagoblin/templates/mediagoblin/auth/login.html:35 +#: mediagoblin/templates/mediagoblin/auth/login.html:45 msgid "Log in" msgstr "Logga in" -#: mediagoblin/templates/mediagoblin/base.html:89 +#: mediagoblin/templates/mediagoblin/base.html:91 msgid "" "Powered by MediaGoblin, a GNU project" @@ -200,75 +232,32 @@ msgid "Explore" msgstr "Utforska" #: mediagoblin/templates/mediagoblin/root.html:27 -msgid "Hi there, media lover! MediaGoblin is..." -msgstr "Hej där mediaentusiast, MediaGoblin..." +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:28 +msgid "Your finest source for all goblin-related media." +msgstr "" #: mediagoblin/templates/mediagoblin/root.html:29 -msgid "The perfect place for your media!" -msgstr "Är ett perfekt ställe för din media!" - -#: mediagoblin/templates/mediagoblin/root.html:30 msgid "" -"A place for people to collaborate and show off original and derived " -"creations!" +"To add your own media, place comments, save your favourites and more, you " +"can log in with your MediaGoblin account." msgstr "" -"Är ett ställe för människor att samarbeta och visa upp originella och " -"härrörande verk." #: mediagoblin/templates/mediagoblin/root.html:31 -msgid "" -"Free, as in freedom. (We’re a GNU project, " -"after all.)" +msgid "Don't have one yet? It's easy!" msgstr "" -"Är fritt som i frihet. (Vi är ju ett GNU-projekt.)" #: mediagoblin/templates/mediagoblin/root.html:32 -msgid "" -"Aiming to make the world a better place through decentralization and " -"(eventually, coming soon!) federation!" -msgstr "" -"Arbetar för att göra världen till ett bättre ställe genom decentralisering " -"och (så småningom, kommer snart!) -- Google Translate säger " -"\"sammanslutning\", en: federation" -" " - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "" -"Built for extensibility. (Multiple media types coming soon to the software," -" including video support!)" -msgstr "" -"Byggd för utbyggbarhet. (Flera mediatyper kommer snart till MediaGoblin, " -"bland annat video!)" - -#: mediagoblin/templates/mediagoblin/root.html:34 -msgid "" -"Powered by people like you. (You can help us improve this" -" software!)" -msgstr "" -"Drivs av människor som du. (Du kan hjälpa os forbättra " -"MediaGoblin!)" - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Excited to join us?" -msgstr "Nyfiken att gå med oss?" - -#: mediagoblin/templates/mediagoblin/root.html:39 #, python-format msgid "" -"Create a free account\n" +"Create an account at this site\n" " or\n" -" Set up MediaGoblin on your own server" +" Set up MediaGoblin on your own server" msgstr "" -"Skapa ett konto gratis\n" -"\n" -" or\n" -" Installera MediaGoblin på din egen server" -#: mediagoblin/templates/mediagoblin/root.html:53 +#: mediagoblin/templates/mediagoblin/root.html:44 msgid "Most recent media" msgstr "Senast medier" @@ -276,9 +265,13 @@ msgstr "Senast medier" msgid "Enter your new password" msgstr "Fyll i ditt lösenord" -#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:29 -msgid "Enter your username or email" -msgstr "Fyll i ditt användarnamn eller lösenord" +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 +msgid "Recover password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:30 +msgid "Send instructions" +msgstr "" #: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 msgid "Your password has been changed. Try to log in now." @@ -317,22 +310,18 @@ msgstr "" msgid "Logging in failed!" msgstr "Inloggning misslyckades!" -#: mediagoblin/templates/mediagoblin/auth/login.html:43 +#: mediagoblin/templates/mediagoblin/auth/login.html:35 msgid "Don't have an account yet?" msgstr "Har du inget konto än?" -#: mediagoblin/templates/mediagoblin/auth/login.html:46 +#: mediagoblin/templates/mediagoblin/auth/login.html:36 msgid "Create one here!" msgstr "Skapa ett här!" -#: mediagoblin/templates/mediagoblin/auth/login.html:49 +#: mediagoblin/templates/mediagoblin/auth/login.html:42 msgid "Forgot your password?" msgstr "Glömt ditt lösenord?" -#: mediagoblin/templates/mediagoblin/auth/login.html:52 -msgid "Change it!" -msgstr "Ändra!" - #: mediagoblin/templates/mediagoblin/auth/register.html:27 msgid "Create an account!" msgstr "Skapa ett konto!" @@ -377,9 +366,15 @@ msgstr "Spara ändringar" msgid "Editing %(username)s's profile" msgstr "Redigerar %(username)ss profil" -#: mediagoblin/templates/mediagoblin/listings/tag.html:31 -msgid "Media tagged with:" -msgstr "Media taggat med:" +#: mediagoblin/templates/mediagoblin/listings/tag.html:30 +#: mediagoblin/templates/mediagoblin/listings/tag.html:35 +#, python-format +msgid "Media tagged with: %(tag_name)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:19 +msgid "Original" +msgstr "" #: mediagoblin/templates/mediagoblin/submit/start.html:26 msgid "Submit yer media" @@ -389,16 +384,16 @@ msgstr "Ladda upp" msgid "Submit" msgstr "Skicka" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:32 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 +#, python-format +msgid "%(username)s's media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:37 #, python-format msgid "%(username)s's media" msgstr "%(username)ss media" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:52 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:32 -msgid "Sorry, no such user found." -msgstr "Ledsen, hittar ingen sådan användare." - #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -429,30 +424,40 @@ msgstr "Ingen media under behandling" msgid "These uploads failed to process:" msgstr "De här behandlingarna misslyckades:" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:39 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:59 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:31 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:89 +#, python-format +msgid "%(username)s's profile" +msgstr "%(username)ss profil" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:43 +msgid "Sorry, no such user found." +msgstr "Ledsen, hittar ingen sådan användare." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:50 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:70 msgid "Email verification needed" msgstr "E-postadressverifiering krävs." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:42 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:53 msgid "Almost done! Your account still needs to be activated." msgstr "Nästan klar! Ditt konto behöver bara aktiveras." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:58 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:51 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 msgid "In case it doesn't:" msgstr "Om det inte skulle göra det:" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:54 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:65 msgid "Resend verification email" msgstr "Skicka ett nytt e-postmeddelande" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:73 msgid "" "Someone has registered an account with this username, but it still has to be" " activated." @@ -460,7 +465,7 @@ msgstr "" "Någon har redan registrerat ett konto med det här användarnamnet men det har" " inte aktiverats." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:79 #, python-format msgid "" "If you are that person but you've lost your verification email, you can logga in och begära ett nytt." -#: 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:85 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 msgid "Here's a spot to tell others about yourself." msgstr "Här kan du berätta för andra om dig själv." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:90 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:108 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:101 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:119 msgid "Edit profile" msgstr "Redigera profil" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:107 msgid "This user hasn't filled in their profile (yet)." msgstr "Den här användaren har inte fyllt i sin profilsida ännu." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:122 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:133 #, python-format msgid "View all of %(username)s's media" msgstr "Se all media från %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:135 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:146 msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." @@ -501,11 +501,11 @@ msgstr "" "Här kommer din media att dyka upp, du verkar inte ha lagt till någonting " "ännu." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:141 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:152 msgid "Add media" msgstr "Lägg till media" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:147 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:158 msgid "There doesn't seem to be any media here yet..." msgstr "Det verkar inte finnas någon media här ännu." @@ -525,6 +525,14 @@ msgstr "Nyare" msgid "Older" msgstr "Äldre" +#: mediagoblin/templates/mediagoblin/utils/tags.html:20 +msgid "Tagged with" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/tags.html:25 +msgid "and" +msgstr "" + #: mediagoblin/user_pages/forms.py:24 msgid "Comment" msgstr "Kommentar" @@ -533,15 +541,23 @@ msgstr "Kommentar" msgid "I am sure I want to delete this" msgstr "Jag är säker på att jag vill radera detta" -#: mediagoblin/user_pages/views.py:142 +#: mediagoblin/user_pages/views.py:155 msgid "Empty comments are not allowed." msgstr "" -#: mediagoblin/user_pages/views.py:148 +#: mediagoblin/user_pages/views.py:161 msgid "Comment posted!" msgstr "" -#: mediagoblin/user_pages/views.py:181 +#: mediagoblin/user_pages/views.py:183 +msgid "You deleted the media." +msgstr "" + +#: mediagoblin/user_pages/views.py:190 +msgid "The media was not deleted because you didn't check that you were sure." +msgstr "" + +#: mediagoblin/user_pages/views.py:198 msgid "You are about to delete another user's media. Proceed with caution." msgstr "Du tänker radera en annan användares media. Var försiktig." diff --git a/mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.po index 289bddb5..064fa7d1 100644 --- a/mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.po @@ -8,9 +8,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-11-01 23:14-0500\n" -"PO-Revision-Date: 2011-11-03 14:08+0000\n" -"Last-Translator: veeven \n" +"POT-Creation-Date: 2011-11-27 15:25-0600\n" +"PO-Revision-Date: 2011-11-27 21:28+0000\n" +"Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,6 +19,10 @@ msgstr "" "Language: te\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" +#: mediagoblin/processing.py:143 +msgid "Invalid file given for media type." +msgstr "" + #: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 msgid "Username" msgstr "వాడుకరి పేరు" @@ -52,7 +56,7 @@ msgid "Sorry, a user with that name already exists." msgstr "" #: mediagoblin/auth/views.py:77 -msgid "Sorry, that email address has already been taken." +msgid "Sorry, a user with that email address already exists." msgstr "" #: mediagoblin/auth/views.py:179 @@ -65,11 +69,19 @@ msgstr "" msgid "The verification key or user id is incorrect" msgstr "" -#: mediagoblin/auth/views.py:207 +#: mediagoblin/auth/views.py:203 +msgid "You must be logged in so we know who to send the email to!" +msgstr "" + +#: mediagoblin/auth/views.py:211 +msgid "You've already verified your email address!" +msgstr "" + +#: mediagoblin/auth/views.py:224 msgid "Resent your verification email." msgstr "" -#: mediagoblin/auth/views.py:248 +#: mediagoblin/auth/views.py:265 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." @@ -83,41 +95,61 @@ msgstr "శీర్షిక" msgid "Tags" msgstr "" -#: mediagoblin/edit/forms.py:31 -msgid "Slug" -msgstr "" - -#: mediagoblin/edit/forms.py:32 -msgid "The slug can't be empty" +#: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 +msgid "Seperate tags by commas or spaces." msgstr "" #: mediagoblin/edit/forms.py:33 +msgid "Slug" +msgstr "" + +#: mediagoblin/edit/forms.py:34 +msgid "The slug can't be empty" +msgstr "" + +#: mediagoblin/edit/forms.py:35 msgid "" "The title part of this media's URL. You usually don't need to change this." msgstr "" -#: mediagoblin/edit/forms.py:40 +#: mediagoblin/edit/forms.py:42 msgid "Bio" msgstr "" -#: mediagoblin/edit/forms.py:43 +#: mediagoblin/edit/forms.py:45 msgid "Website" msgstr "" -#: mediagoblin/edit/views.py:64 +#: mediagoblin/edit/forms.py:49 +msgid "Old password" +msgstr "" + +#: mediagoblin/edit/forms.py:52 +msgid "New Password" +msgstr "" + +#: mediagoblin/edit/views.py:65 msgid "An entry with that slug already exists for this user." msgstr "" -#: mediagoblin/edit/views.py:85 +#: mediagoblin/edit/views.py:86 msgid "You are editing another user's media. Proceed with caution." msgstr "" -#: mediagoblin/edit/views.py:155 +#: mediagoblin/edit/views.py:156 msgid "You are editing a user's profile. Proceed with caution." msgstr "" -#: mediagoblin/process_media/errors.py:44 -msgid "Invalid file given for media type." +#: mediagoblin/edit/views.py:171 +msgid "Wrong password" +msgstr "" + +#: mediagoblin/edit/views.py:192 +msgid "Profile edited!" +msgstr "" + +#: mediagoblin/media_types/__init__.py:61 +msgid "Could not find any file extension in \"{filename}\"" msgstr "" #: mediagoblin/submit/forms.py:25 @@ -128,16 +160,16 @@ msgstr "" msgid "Description of this work" msgstr "" -#: mediagoblin/submit/views.py:46 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "" -#: mediagoblin/submit/views.py:49 -msgid "The file doesn't seem to be an image!" +#: mediagoblin/submit/views.py:127 +msgid "Woohoo! Submitted!" msgstr "" -#: mediagoblin/submit/views.py:121 -msgid "Woohoo! Submitted!" +#: mediagoblin/submit/views.py:133 +msgid "Invalid file type." msgstr "" #: mediagoblin/templates/mediagoblin/404.html:21 @@ -158,29 +190,29 @@ msgstr "" msgid "Image of 404 goblin stressing out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:22 -msgid "GNU MediaGoblin" -msgstr "" - -#: mediagoblin/templates/mediagoblin/base.html:47 +#: mediagoblin/templates/mediagoblin/base.html:49 msgid "MediaGoblin logo" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:52 +#: mediagoblin/templates/mediagoblin/base.html:54 msgid "Submit media" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:63 -msgid "verify your email!" +#: mediagoblin/templates/mediagoblin/base.html:65 +msgid "Verify your email!" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:73 +#: mediagoblin/templates/mediagoblin/base.html:72 +msgid "log out" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:75 #: mediagoblin/templates/mediagoblin/auth/login.html:27 -#: mediagoblin/templates/mediagoblin/auth/login.html:35 +#: mediagoblin/templates/mediagoblin/auth/login.html:45 msgid "Log in" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:89 +#: mediagoblin/templates/mediagoblin/base.html:91 msgid "" "Powered by MediaGoblin, a GNU project" @@ -191,57 +223,32 @@ msgid "Explore" msgstr "" #: mediagoblin/templates/mediagoblin/root.html:27 -msgid "Hi there, media lover! MediaGoblin is..." +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:28 +msgid "Your finest source for all goblin-related media." msgstr "" #: mediagoblin/templates/mediagoblin/root.html:29 -msgid "The perfect place for your media!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:30 msgid "" -"A place for people to collaborate and show off original and derived " -"creations!" +"To add your own media, place comments, save your favourites and more, you " +"can log in with your MediaGoblin account." msgstr "" #: mediagoblin/templates/mediagoblin/root.html:31 -msgid "" -"Free, as in freedom. (We’re a GNU project, " -"after all.)" +msgid "Don't have one yet? It's easy!" msgstr "" #: mediagoblin/templates/mediagoblin/root.html:32 -msgid "" -"Aiming to make the world a better place through decentralization and " -"(eventually, coming soon!) federation!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "" -"Built for extensibility. (Multiple media types coming soon to the software," -" including video support!)" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:34 -msgid "" -"Powered by people like you. (You can help us improve this" -" software!)" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Excited to join us?" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:39 #, python-format msgid "" -"Create a free account\n" +"Create an account at this site\n" " or\n" -" Set up MediaGoblin on your own server" +" Set up MediaGoblin on your own server" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:53 +#: mediagoblin/templates/mediagoblin/root.html:44 msgid "Most recent media" msgstr "" @@ -249,8 +256,12 @@ msgstr "" msgid "Enter your new password" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:29 -msgid "Enter your username or email" +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 +msgid "Recover password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:30 +msgid "Send instructions" msgstr "" #: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 @@ -280,22 +291,18 @@ msgstr "" msgid "Logging in failed!" msgstr "ప్రవేశం విఫలమయ్యింది!" -#: mediagoblin/templates/mediagoblin/auth/login.html:43 +#: mediagoblin/templates/mediagoblin/auth/login.html:35 msgid "Don't have an account yet?" msgstr "మీకు ఇంకా ఖాతా లేదా?" -#: mediagoblin/templates/mediagoblin/auth/login.html:46 +#: mediagoblin/templates/mediagoblin/auth/login.html:36 msgid "Create one here!" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/login.html:49 +#: mediagoblin/templates/mediagoblin/auth/login.html:42 msgid "Forgot your password?" msgstr "మీ సంకేతపదాన్ని మర్చిపోయారా?" -#: mediagoblin/templates/mediagoblin/auth/login.html:52 -msgid "Change it!" -msgstr "" - #: mediagoblin/templates/mediagoblin/auth/register.html:27 msgid "Create an account!" msgstr "" @@ -335,8 +342,14 @@ msgstr "మార్పులను భద్రపరచు" msgid "Editing %(username)s's profile" msgstr "" -#: mediagoblin/templates/mediagoblin/listings/tag.html:31 -msgid "Media tagged with:" +#: mediagoblin/templates/mediagoblin/listings/tag.html:30 +#: mediagoblin/templates/mediagoblin/listings/tag.html:35 +#, python-format +msgid "Media tagged with: %(tag_name)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:19 +msgid "Original" msgstr "" #: mediagoblin/templates/mediagoblin/submit/start.html:26 @@ -347,14 +360,14 @@ msgstr "" msgid "Submit" msgstr "దాఖలు చెయ్యి" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:32 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format -msgid "%(username)s's media" +msgid "%(username)s's media" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:52 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:32 -msgid "Sorry, no such user found." +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:37 +#, python-format +msgid "%(username)s's media" msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 @@ -387,75 +400,80 @@ msgstr "" msgid "These uploads failed to process:" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:39 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:59 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:31 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:89 +#, python-format +msgid "%(username)s's profile" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:43 +msgid "Sorry, no such user found." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:50 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:70 msgid "Email verification needed" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:42 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:53 msgid "Almost done! Your account still needs to be activated." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:58 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 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 msgid "In case it doesn't:" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:54 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:65 msgid "Resend verification email" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:73 msgid "" "Someone has registered an account with this username, but it still has to be" " activated." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:79 #, python-format msgid "" "If you are that person but you've lost your verification email, you can log in and resend it." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:78 -#, python-format -msgid "%(username)s's profile" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/user.html:85 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 msgid "Here's a spot to tell others about yourself." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:90 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:108 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:101 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:119 msgid "Edit profile" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:107 msgid "This user hasn't filled in their profile (yet)." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:122 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:133 #, python-format msgid "View all of %(username)s's media" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:135 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:146 msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:141 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:152 msgid "Add media" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:147 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:158 msgid "There doesn't seem to be any media here yet..." msgstr "" @@ -475,6 +493,14 @@ msgstr "" msgid "Older" msgstr "" +#: mediagoblin/templates/mediagoblin/utils/tags.html:20 +msgid "Tagged with" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/tags.html:25 +msgid "and" +msgstr "" + #: mediagoblin/user_pages/forms.py:24 msgid "Comment" msgstr "వ్యాఖ్య" @@ -483,15 +509,23 @@ msgstr "వ్యాఖ్య" msgid "I am sure I want to delete this" msgstr "" -#: mediagoblin/user_pages/views.py:142 +#: mediagoblin/user_pages/views.py:155 msgid "Empty comments are not allowed." msgstr "" -#: mediagoblin/user_pages/views.py:148 +#: mediagoblin/user_pages/views.py:161 msgid "Comment posted!" msgstr "" -#: mediagoblin/user_pages/views.py:181 +#: mediagoblin/user_pages/views.py:183 +msgid "You deleted the media." +msgstr "" + +#: mediagoblin/user_pages/views.py:190 +msgid "The media was not deleted because you didn't check that you were sure." +msgstr "" + +#: mediagoblin/user_pages/views.py:198 msgid "You are about to delete another user's media. Proceed with caution." msgstr "" diff --git a/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.po index c664adbe..5e406b41 100644 --- a/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.po @@ -9,8 +9,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-11-01 23:14-0500\n" -"PO-Revision-Date: 2011-11-02 04:13+0000\n" +"POT-Creation-Date: 2011-11-27 15:25-0600\n" +"PO-Revision-Date: 2011-11-27 21:28+0000\n" "Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -20,6 +20,10 @@ msgstr "" "Language: zh_TW\n" "Plural-Forms: nplurals=1; plural=0\n" +#: mediagoblin/processing.py:143 +msgid "Invalid file given for media type." +msgstr "指定錯誤的媒體類別!" + #: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 msgid "Username" msgstr "使用者名稱" @@ -53,8 +57,8 @@ msgid "Sorry, a user with that name already exists." msgstr "抱歉, 這個使用者名稱已經存在." #: mediagoblin/auth/views.py:77 -msgid "Sorry, that email address has already been taken." -msgstr "抱歉,這個電子郵件已經被其他人使用了。" +msgid "Sorry, a user with that email address already exists." +msgstr "" #: mediagoblin/auth/views.py:179 msgid "" @@ -66,11 +70,19 @@ msgstr "你的電子郵件位址已被認證. 你現在就可以登入, 編輯 msgid "The verification key or user id is incorrect" msgstr "認證碼或是使用者帳號錯誤" -#: mediagoblin/auth/views.py:207 +#: mediagoblin/auth/views.py:203 +msgid "You must be logged in so we know who to send the email to!" +msgstr "" + +#: mediagoblin/auth/views.py:211 +msgid "You've already verified your email address!" +msgstr "" + +#: mediagoblin/auth/views.py:224 msgid "Resent your verification email." msgstr "重送認證信." -#: mediagoblin/auth/views.py:248 +#: mediagoblin/auth/views.py:265 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." @@ -84,42 +96,62 @@ msgstr "標題" msgid "Tags" msgstr "標籤" -#: mediagoblin/edit/forms.py:31 +#: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 +msgid "Seperate tags by commas or spaces." +msgstr "" + +#: mediagoblin/edit/forms.py:33 msgid "Slug" msgstr "自訂字串" -#: mediagoblin/edit/forms.py:32 +#: mediagoblin/edit/forms.py:34 msgid "The slug can't be empty" msgstr "自訂字串不能空白" -#: mediagoblin/edit/forms.py:33 +#: mediagoblin/edit/forms.py:35 msgid "" "The title part of this media's URL. You usually don't need to change this." msgstr "此媒體網址的名稱。你通常不需要變動這個的。" -#: mediagoblin/edit/forms.py:40 +#: mediagoblin/edit/forms.py:42 msgid "Bio" msgstr "自我介紹" -#: mediagoblin/edit/forms.py:43 +#: mediagoblin/edit/forms.py:45 msgid "Website" msgstr "網站" -#: mediagoblin/edit/views.py:64 +#: mediagoblin/edit/forms.py:49 +msgid "Old password" +msgstr "" + +#: mediagoblin/edit/forms.py:52 +msgid "New Password" +msgstr "" + +#: mediagoblin/edit/views.py:65 msgid "An entry with that slug already exists for this user." msgstr "這個自訂字串已經被其他人用了" -#: mediagoblin/edit/views.py:85 +#: mediagoblin/edit/views.py:86 msgid "You are editing another user's media. Proceed with caution." msgstr "你正在編輯他人的媒體檔案. 請謹慎處理." -#: mediagoblin/edit/views.py:155 +#: mediagoblin/edit/views.py:156 msgid "You are editing a user's profile. Proceed with caution." msgstr "你正在編輯一位用戶的檔案. 請謹慎處理." -#: mediagoblin/process_media/errors.py:44 -msgid "Invalid file given for media type." -msgstr "指定錯誤的媒體類別!" +#: mediagoblin/edit/views.py:171 +msgid "Wrong password" +msgstr "" + +#: mediagoblin/edit/views.py:192 +msgid "Profile edited!" +msgstr "" + +#: mediagoblin/media_types/__init__.py:61 +msgid "Could not find any file extension in \"{filename}\"" +msgstr "" #: mediagoblin/submit/forms.py:25 msgid "File" @@ -129,18 +161,18 @@ msgstr "檔案" msgid "Description of this work" msgstr "這個作品的描述" -#: mediagoblin/submit/views.py:46 +#: mediagoblin/submit/views.py:49 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:121 +#: mediagoblin/submit/views.py:127 msgid "Woohoo! Submitted!" msgstr "呼呼! 送出去嚕!" +#: mediagoblin/submit/views.py:133 +msgid "Invalid file type." +msgstr "" + #: mediagoblin/templates/mediagoblin/404.html:21 msgid "Oops!" msgstr "糟糕!" @@ -159,29 +191,29 @@ msgstr "如果你確定這個位址是正確的,或許你在找的網頁已經 msgid "Image of 404 goblin stressing out" msgstr "Image of 404 goblin stressing out" -#: mediagoblin/templates/mediagoblin/base.html:22 -msgid "GNU MediaGoblin" -msgstr "GNU MediaGoblin" - -#: mediagoblin/templates/mediagoblin/base.html:47 +#: mediagoblin/templates/mediagoblin/base.html:49 msgid "MediaGoblin logo" msgstr "MediaGoblin 標誌" -#: mediagoblin/templates/mediagoblin/base.html:52 +#: mediagoblin/templates/mediagoblin/base.html:54 msgid "Submit media" msgstr "遞交媒體" -#: mediagoblin/templates/mediagoblin/base.html:63 -msgid "verify your email!" -msgstr "確認您的電子郵件!" +#: mediagoblin/templates/mediagoblin/base.html:65 +msgid "Verify your email!" +msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:73 +#: mediagoblin/templates/mediagoblin/base.html:72 +msgid "log out" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:75 #: mediagoblin/templates/mediagoblin/auth/login.html:27 -#: mediagoblin/templates/mediagoblin/auth/login.html:35 +#: mediagoblin/templates/mediagoblin/auth/login.html:45 msgid "Log in" msgstr "登入" -#: mediagoblin/templates/mediagoblin/base.html:89 +#: mediagoblin/templates/mediagoblin/base.html:91 msgid "" "Powered by MediaGoblin, a GNU project" @@ -194,62 +226,32 @@ msgid "Explore" msgstr "探索" #: mediagoblin/templates/mediagoblin/root.html:27 -msgid "Hi there, media lover! MediaGoblin is..." -msgstr "嗨!多媒體檔案愛好者!MediaGoblin是..." +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:28 +msgid "Your finest source for all goblin-related media." +msgstr "" #: mediagoblin/templates/mediagoblin/root.html:29 -msgid "The perfect place for your media!" -msgstr "你的媒體檔案的最佳所在!" - -#: mediagoblin/templates/mediagoblin/root.html:30 msgid "" -"A place for people to collaborate and show off original and derived " -"creations!" -msgstr "這是一個可以讓人們共同展示他們的創作、衍生作品的地方!" +"To add your own media, place comments, save your favourites and more, you " +"can log in with your MediaGoblin account." +msgstr "" #: mediagoblin/templates/mediagoblin/root.html:31 -msgid "" -"Free, as in freedom. (We’re a GNU project, " -"after all.)" -msgstr "免費但是我們更重視自由 (畢竟我們是個 GNU 專案)" +msgid "Don't have one yet? It's easy!" +msgstr "" #: mediagoblin/templates/mediagoblin/root.html:32 -msgid "" -"Aiming to make the world a better place through decentralization and " -"(eventually, coming soon!) federation!" -msgstr "目的是要透過分散式且自由的方式讓這個世界更美好!(總有一天,它很快會到來的!)" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "" -"Built for extensibility. (Multiple media types coming soon to the software," -" including video support!)" -msgstr "天生的擴充性。(軟體將支援多種多媒體格式, 也支援影音檔案!)" - -#: mediagoblin/templates/mediagoblin/root.html:34 -msgid "" -"Powered by people like you. (You can help us improve this" -" software!)" -msgstr "" -"由像你一樣的人們製作 (你可以幫我們改進軟體!)" - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Excited to join us?" -msgstr "迫不亟待想要加入我們?" - -#: mediagoblin/templates/mediagoblin/root.html:39 #, python-format msgid "" -"Create a free account\n" +"Create an account at this site\n" " or\n" -" Set up MediaGoblin on your own server" +" Set up MediaGoblin on your own server" msgstr "" -"建立一個免費帳號\n" -" 或是\n" -" 在你的伺服器上設立 MediaGoblin" -#: mediagoblin/templates/mediagoblin/root.html:53 +#: mediagoblin/templates/mediagoblin/root.html:44 msgid "Most recent media" msgstr "最新的媒體" @@ -257,9 +259,13 @@ msgstr "最新的媒體" msgid "Enter your new password" msgstr "輸入你的新密碼" -#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:29 -msgid "Enter your username or email" -msgstr "輸入你的帳號或是電子郵件" +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 +msgid "Recover password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:30 +msgid "Send instructions" +msgstr "" #: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 msgid "Your password has been changed. Try to log in now." @@ -295,22 +301,18 @@ msgstr "" msgid "Logging in failed!" msgstr "登入失敗!" -#: mediagoblin/templates/mediagoblin/auth/login.html:43 +#: mediagoblin/templates/mediagoblin/auth/login.html:35 msgid "Don't have an account yet?" msgstr "還沒有帳號嗎?" -#: mediagoblin/templates/mediagoblin/auth/login.html:46 +#: mediagoblin/templates/mediagoblin/auth/login.html:36 msgid "Create one here!" msgstr "在這裡建立一個吧!" -#: mediagoblin/templates/mediagoblin/auth/login.html:49 +#: mediagoblin/templates/mediagoblin/auth/login.html:42 msgid "Forgot your password?" msgstr "忘了密碼嗎?" -#: mediagoblin/templates/mediagoblin/auth/login.html:52 -msgid "Change it!" -msgstr "變更!" - #: mediagoblin/templates/mediagoblin/auth/register.html:27 msgid "Create an account!" msgstr "建立一個帳號!" @@ -355,9 +357,15 @@ msgstr "儲存變更" 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:30 +#: mediagoblin/templates/mediagoblin/listings/tag.html:35 +#, python-format +msgid "Media tagged with: %(tag_name)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:19 +msgid "Original" +msgstr "" #: mediagoblin/templates/mediagoblin/submit/start.html:26 msgid "Submit yer media" @@ -367,16 +375,16 @@ msgstr "遞交你的媒體檔案" msgid "Submit" msgstr "送出" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:32 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 +#, python-format +msgid "%(username)s's media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:37 #, python-format msgid "%(username)s's media" msgstr "%(username)s的媒體檔案" -#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:52 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:32 -msgid "Sorry, no such user found." -msgstr "抱歉,找不到這個使用者." - #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -407,75 +415,80 @@ msgstr "沒有正在處理中的媒體" msgid "These uploads failed to process:" msgstr "無法處理這些更新" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:39 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:59 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:31 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:89 +#, python-format +msgid "%(username)s's profile" +msgstr "%(username)s的個人檔案" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:43 +msgid "Sorry, no such user found." +msgstr "抱歉,找不到這個使用者." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:50 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:70 msgid "Email verification needed" msgstr "需要認證電子郵件" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:42 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:53 msgid "Almost done! Your account still needs to be activated." msgstr "幾乎完成了!但你的帳號仍然需要被啟用。" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:58 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 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 msgid "In case it doesn't:" msgstr "假設它無法:" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:54 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:65 msgid "Resend verification email" msgstr "重送認證信" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:73 msgid "" "Someone has registered an account with this username, but it still has to be" " activated." msgstr "有人用了這個帳號登錄了,但是這個帳號仍需要被啟用。" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:79 #, python-format msgid "" "If you are that person but you've lost your verification email, you can log in and resend it." msgstr "如果你就是那個人, 但是遺失了認證信, 你可以登入 然後重送一次." -#: 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:85 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 msgid "Here's a spot to tell others about yourself." msgstr "這是一個地方,能讓你向他人介紹自己。" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:90 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:108 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:101 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:119 msgid "Edit profile" msgstr "編輯個人檔案" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:107 msgid "This user hasn't filled in their profile (yet)." msgstr "這個使用者還沒(來得及)填寫個人檔案。" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:122 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:133 #, python-format msgid "View all of %(username)s's media" msgstr "查看%(username)s的全部媒體檔案" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:135 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:146 msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." msgstr "這個地方是你的媒體檔案會出現的地方,但是你似乎還沒有加入任何東西。" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:141 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:152 msgid "Add media" msgstr "新增媒體檔案" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:147 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:158 msgid "There doesn't seem to be any media here yet..." msgstr "似乎還沒有任何的媒體檔案..." @@ -495,6 +508,14 @@ msgstr "新一點" msgid "Older" msgstr "舊一點" +#: mediagoblin/templates/mediagoblin/utils/tags.html:20 +msgid "Tagged with" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/tags.html:25 +msgid "and" +msgstr "" + #: mediagoblin/user_pages/forms.py:24 msgid "Comment" msgstr "評論" @@ -503,15 +524,23 @@ msgstr "評論" msgid "I am sure I want to delete this" msgstr "我確定我想要刪除" -#: mediagoblin/user_pages/views.py:142 +#: mediagoblin/user_pages/views.py:155 msgid "Empty comments are not allowed." -msgstr "" +msgstr "評論不能空白。" -#: mediagoblin/user_pages/views.py:148 +#: mediagoblin/user_pages/views.py:161 msgid "Comment posted!" +msgstr "評論已經張貼!" + +#: mediagoblin/user_pages/views.py:183 +msgid "You deleted the media." msgstr "" -#: mediagoblin/user_pages/views.py:181 +#: mediagoblin/user_pages/views.py:190 +msgid "The media was not deleted because you didn't check that you were sure." +msgstr "" + +#: mediagoblin/user_pages/views.py:198 msgid "You are about to delete another user's media. Proceed with caution." msgstr "你在刪除其他人的媒體檔案。請小心處理喔。" From a3663b407997cb8e2d45086641b7eb9f4efd476c Mon Sep 17 00:00:00 2001 From: Elrond Date: Mon, 28 Nov 2011 09:45:15 +0100 Subject: [PATCH 123/302] Mark two strings for translation 1. "Go to page:" in pagination 2. "Submit" in the forget password form --- mediagoblin/templates/mediagoblin/auth/change_fp.html | 2 +- mediagoblin/templates/mediagoblin/utils/pagination.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mediagoblin/templates/mediagoblin/auth/change_fp.html b/mediagoblin/templates/mediagoblin/auth/change_fp.html index fa972085..5677949c 100644 --- a/mediagoblin/templates/mediagoblin/auth/change_fp.html +++ b/mediagoblin/templates/mediagoblin/auth/change_fp.html @@ -30,7 +30,7 @@ {{ wtforms_util.render_divs(cp_form) }}
- +
diff --git a/mediagoblin/templates/mediagoblin/utils/pagination.html b/mediagoblin/templates/mediagoblin/utils/pagination.html index 84336103..3c12f93c 100644 --- a/mediagoblin/templates/mediagoblin/utils/pagination.html +++ b/mediagoblin/templates/mediagoblin/utils/pagination.html @@ -47,7 +47,7 @@ Next page {% endif %}
- Go to page: + {% trans %}Go to page:{% endtrans %} {%- for page in pagination.iter_pages() %} {% if page %} {% if page != pagination.page %} From 813be2938ae8036573b04cd6ab7beac06efe8f16 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Thu, 1 Dec 2011 15:21:15 -0600 Subject: [PATCH 124/302] Don't barf on templates that use the autoescaping extension --- babel.ini | 3 +++ 1 file changed, 3 insertions(+) diff --git a/babel.ini b/babel.ini index a4e3267a..1a8231f5 100644 --- a/babel.ini +++ b/babel.ini @@ -4,9 +4,12 @@ [jinja2: mediagoblin/templates/**.html] # Extract jinja templates (html) encoding = utf-8 +extensions = jinja2.ext.autoescape + [jinja2: mediagoblin/templates/**.txt] # Extract jinja templates (text) encoding = utf-8 +extensions = jinja2.ext.autoescape # # Extraction from JavaScript files # [javascript: mediagoblin/static/js/**.js] From 9754802d4bca036b8fb0b50db948dd2eb8f64bd6 Mon Sep 17 00:00:00 2001 From: Elrond Date: Thu, 1 Dec 2011 23:33:47 +0100 Subject: [PATCH 125/302] fixture_add_user: Factoring a unit test tool Some unit tests need a user in the database, especially to act as that user. Some routines did that on their own. So factored this whole thing into a new function and use it around. --- mediagoblin/tests/test_auth.py | 8 ++------ mediagoblin/tests/test_edit.py | 21 ++++----------------- mediagoblin/tests/test_submission.py | 12 +++--------- mediagoblin/tests/tools.py | 17 +++++++++++++++++ 4 files changed, 26 insertions(+), 32 deletions(-) diff --git a/mediagoblin/tests/test_auth.py b/mediagoblin/tests/test_auth.py index 153c6e53..acef3d26 100644 --- a/mediagoblin/tests/test_auth.py +++ b/mediagoblin/tests/test_auth.py @@ -20,7 +20,7 @@ import datetime from nose.tools import assert_equal from mediagoblin.auth import lib as auth_lib -from mediagoblin.tests.tools import setup_fresh_app +from mediagoblin.tests.tools import setup_fresh_app, fixture_add_user from mediagoblin import mg_globals from mediagoblin.tools import template, mail @@ -332,11 +332,7 @@ def test_authentication_views(test_app): Test logging in and logging out """ # Make a new user - test_user = mg_globals.database.User() - test_user['username'] = u'chris' - test_user['email'] = u'chris@example.com' - test_user['pw_hash'] = auth_lib.bcrypt_gen_password_hash('toast') - test_user.save() + test_user = fixture_add_user(active_user=False) # Get login # --------- diff --git a/mediagoblin/tests/test_edit.py b/mediagoblin/tests/test_edit.py index 3637b046..c29ddfe9 100644 --- a/mediagoblin/tests/test_edit.py +++ b/mediagoblin/tests/test_edit.py @@ -15,23 +15,16 @@ # along with this program. If not, see . from mediagoblin import mg_globals -from mediagoblin.tests.tools import setup_fresh_app +from mediagoblin.tests.tools import setup_fresh_app, fixture_add_user from mediagoblin.tools import template -from mediagoblin.auth.lib import bcrypt_check_password, \ - bcrypt_gen_password_hash +from mediagoblin.auth.lib import bcrypt_check_password @setup_fresh_app def test_change_password(test_app): """Test changing password correctly and incorrectly""" # set up new user - test_user = mg_globals.database.User() - test_user['username'] = u'chris' - test_user['email'] = u'chris@example.com' - test_user['email_verified'] = True - test_user['status'] = u'active' - test_user['pw_hash'] = bcrypt_gen_password_hash('toast') - test_user.save() + test_user = fixture_add_user() test_app.post( '/auth/login/', { @@ -73,13 +66,7 @@ def test_change_password(test_app): def change_bio_url(test_app): """Test changing bio and URL""" # set up new user - test_user = mg_globals.database.User() - test_user['username'] = u'chris' - test_user['email'] = u'chris@example.com' - test_user['email_verified'] = True - test_user['status'] = u'active' - test_user['pw_hash'] = bcrypt_gen_password_hash('toast') - test_user.save() + test_user = fixture_add_user() # test changing the bio and the URL properly test_app.post( diff --git a/mediagoblin/tests/test_submission.py b/mediagoblin/tests/test_submission.py index eea5747f..7ea6c4bc 100644 --- a/mediagoblin/tests/test_submission.py +++ b/mediagoblin/tests/test_submission.py @@ -19,8 +19,8 @@ import pkg_resources from nose.tools import assert_equal, assert_true, assert_false -from mediagoblin.auth import lib as auth_lib -from mediagoblin.tests.tools import setup_fresh_app, get_test_app +from mediagoblin.tests.tools import setup_fresh_app, get_test_app, \ + fixture_add_user from mediagoblin import mg_globals from mediagoblin.tools import template, common @@ -45,13 +45,7 @@ class TestSubmission: # TODO: Possibly abstract into a decorator like: # @as_authenticated_user('chris') - test_user = mg_globals.database.User() - test_user['username'] = u'chris' - test_user['email'] = u'chris@example.com' - test_user['email_verified'] = True - test_user['status'] = u'active' - test_user['pw_hash'] = auth_lib.bcrypt_gen_password_hash('toast') - test_user.save() + test_user = fixture_add_user() self.test_user = test_user diff --git a/mediagoblin/tests/tools.py b/mediagoblin/tests/tools.py index 01813e96..49a3d33e 100644 --- a/mediagoblin/tests/tools.py +++ b/mediagoblin/tests/tools.py @@ -27,6 +27,7 @@ from mediagoblin.init.config import read_mediagoblin_config from mediagoblin.decorators import _make_safe from mediagoblin.db.open import setup_connection_and_db_from_config from mediagoblin.meddleware import BaseMeddleware +from mediagoblin.auth.lib import bcrypt_gen_password_hash MEDIAGOBLIN_TEST_DB_NAME = u'__mediagoblin_tests__' @@ -200,3 +201,19 @@ def assert_db_meets_expected(db, expected): document = collection.find_one({'_id': expected_document['_id']}) assert document is not None # make sure it exists assert document == expected_document # make sure it matches + + +def fixture_add_user(username = u'chris', password = 'toast', + active_user = True): + test_user = mg_globals.database.User() + test_user.username = username + test_user.email = username + u'@example.com' + if password is not None: + test_user.pw_hash = bcrypt_gen_password_hash(password) + if active_user: + test_user.email_verified = True + test_user.status = u'active' + + test_user.save() + + return test_user From c7e1fee1b8eab3c01266c9a349812db598ca8f07 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Thu, 1 Dec 2011 16:58:56 -0600 Subject: [PATCH 126/302] Should be 404 for 404s, not 400 :) --- mediagoblin/tools/response.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediagoblin/tools/response.py b/mediagoblin/tools/response.py index b01d31a2..c905097c 100644 --- a/mediagoblin/tools/response.py +++ b/mediagoblin/tools/response.py @@ -30,7 +30,7 @@ def render_404(request): Render a 404. """ return render_to_response( - request, 'mediagoblin/404.html', {}, status=400) + request, 'mediagoblin/404.html', {}, status=404) def redirect(request, *args, **kwargs): From 93e4622491ff6bed339267cea2a0a98a7af3c8d8 Mon Sep 17 00:00:00 2001 From: Elrond Date: Fri, 2 Dec 2011 00:09:13 +0100 Subject: [PATCH 127/302] Expect 404 in unit tests, if we now use 404. Our unit tests for auth were expecting a 400. Well, now we give a 404. So expect that! I'm not completely sure, if the 404 is the right thing here, but that's another topic. --- mediagoblin/tests/test_auth.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mediagoblin/tests/test_auth.py b/mediagoblin/tests/test_auth.py index 153c6e53..ee085761 100644 --- a/mediagoblin/tests/test_auth.py +++ b/mediagoblin/tests/test_auth.py @@ -280,16 +280,16 @@ def test_register_views(test_app): template.clear_test_template_context() response = test_app.get( "/auth/forgot_password/verify/?userid=%s&token=total_bs" % unicode( - new_user._id), status=400) - assert response.status == '400 Bad Request' + new_user._id), status=404) + assert_equal(response.status, '404 Not Found') ## Try using an expired token to change password, shouldn't work template.clear_test_template_context() real_token_expiration = new_user['fp_token_expire'] new_user['fp_token_expire'] = datetime.datetime.now() new_user.save() - response = test_app.get("%s?%s" % (path, get_params), status=400) - assert response.status == '400 Bad Request' + response = test_app.get("%s?%s" % (path, get_params), status=404) + assert_equal(response.status, '404 Not Found') new_user['fp_token_expire'] = real_token_expiration new_user.save() From 92417fc535c32d905957b4f5ef0fd2cfd8d78609 Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Fri, 2 Dec 2011 21:17:55 +0100 Subject: [PATCH 128/302] First push with jQuery library --- extlib/jquery/MIT.txt | 20 ++++++++++++++++++++ extlib/jquery/jquery.js | 4 ++++ mediagoblin/static/js/extlib/jquery.js | 1 + 3 files changed, 25 insertions(+) create mode 100644 extlib/jquery/MIT.txt create mode 100644 extlib/jquery/jquery.js create mode 120000 mediagoblin/static/js/extlib/jquery.js diff --git a/extlib/jquery/MIT.txt b/extlib/jquery/MIT.txt new file mode 100644 index 00000000..5a2aeb47 --- /dev/null +++ b/extlib/jquery/MIT.txt @@ -0,0 +1,20 @@ +Copyright (c) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/extlib/jquery/jquery.js b/extlib/jquery/jquery.js new file mode 100644 index 00000000..198b3ff0 --- /dev/null +++ b/extlib/jquery/jquery.js @@ -0,0 +1,4 @@ +/*! jQuery v1.7.1 jquery.com | jquery.org/license */ +(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!ck[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"":"")+""),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){if(c!=="border")for(;g=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c
a",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="
"+""+"
",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="
t
",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="
",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")}; +f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;le&&i.push({elem:this,matches:d.slice(e)});for(j=0;j0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div
","
"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function() +{for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
").append(c.replace(bN,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bO.test(this.nodeName)||bI.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b_(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b_(a,b);return a},ajaxSettings:{url:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bZ(bT),ajaxTransport:bZ(bU),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cb(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cc(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bH.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bX+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bU,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ce,l),b.url===j&&(e&&(k=k.replace(ce,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cf&&delete ch[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window); \ No newline at end of file diff --git a/mediagoblin/static/js/extlib/jquery.js b/mediagoblin/static/js/extlib/jquery.js new file mode 120000 index 00000000..d78f5cc3 --- /dev/null +++ b/mediagoblin/static/js/extlib/jquery.js @@ -0,0 +1 @@ +../../../../extlib/jquery/jquery.js \ No newline at end of file From 1e9d1acc03aa42ff979c8d15162d51441b81ec5d Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Fri, 2 Dec 2011 16:13:14 -0600 Subject: [PATCH 129/302] We should use the variable local_templates instead of user_template_path --- mediagoblin/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediagoblin/app.py b/mediagoblin/app.py index 7f087ed9..04eb2acc 100644 --- a/mediagoblin/app.py +++ b/mediagoblin/app.py @@ -63,7 +63,7 @@ class MediaGoblinApp(object): # Get the template environment self.template_loader = get_jinja_loader( - app_config.get('user_template_path')) + app_config.get('local_templates')) # Set up storage systems self.public_store, self.queue_store = setup_storage() From 0d6e5dddeb38f6af7972485ae186532449719243 Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Fri, 2 Dec 2011 23:48:40 +0100 Subject: [PATCH 130/302] Add show-password checkbox and make it work --- mediagoblin/auth/forms.py | 10 +--------- .../templates/mediagoblin/auth/register.html | 20 +++++++++++++++++++ mediagoblin/templates/mediagoblin/base.html | 3 ++- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/mediagoblin/auth/forms.py b/mediagoblin/auth/forms.py index dcb6766c..4cd3e9d8 100644 --- a/mediagoblin/auth/forms.py +++ b/mediagoblin/auth/forms.py @@ -29,15 +29,7 @@ class RegistrationForm(wtforms.Form): password = wtforms.PasswordField( _('Password'), [wtforms.validators.Required(), - wtforms.validators.Length(min=6, max=30), - wtforms.validators.EqualTo( - 'confirm_password', - _('Passwords must match.'))]) - confirm_password = wtforms.PasswordField( - _('Confirm password'), - [wtforms.validators.Required()], - description=_( - u"Type it again here to make sure there are no spelling mistakes.")) + wtforms.validators.Length(min=6, max=30)]) email = wtforms.TextField( _('Email address'), [wtforms.validators.Required(), diff --git a/mediagoblin/templates/mediagoblin/auth/register.html b/mediagoblin/templates/mediagoblin/auth/register.html index a0d0a277..bded1d7e 100644 --- a/mediagoblin/templates/mediagoblin/auth/register.html +++ b/mediagoblin/templates/mediagoblin/auth/register.html @@ -19,6 +19,26 @@ {% import "/mediagoblin/utils/wtforms.html" as wtforms_util %} +{% block mediagoblin_head %} + +{% endblock mediagoblin_head %} + {% block mediagoblin_content %} + {% block mediagoblin_head %} {% endblock mediagoblin_head %} - {% block mediagoblin_body %}
From eae7d0585fc0348a47087919c04e2372d15d244c Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Sat, 3 Dec 2011 01:19:15 +0100 Subject: [PATCH 131/302] Changed comment error message wording slightly. Btw, should we translate these things? --- mediagoblin/user_pages/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mediagoblin/user_pages/views.py b/mediagoblin/user_pages/views.py index 3d9735f7..779394c7 100644 --- a/mediagoblin/user_pages/views.py +++ b/mediagoblin/user_pages/views.py @@ -152,13 +152,13 @@ def media_post_comment(request, media): messages.add_message( request, messages.ERROR, - _("Empty comments are not allowed.")) + _("Oops, your comment was empty.")) else: comment.save() messages.add_message( request, messages.SUCCESS, - _('Comment posted!')) + _('Your comment has been posted!')) return exc.HTTPFound( location=media.url_for_self(request.urlgen)) From d463055317e5518adf7c5a99b4724f4e66830b3c Mon Sep 17 00:00:00 2001 From: Manuel Urbano Santos Date: Sat, 3 Dec 2011 14:29:28 +0100 Subject: [PATCH 132/302] Change adduser arguments from positional to --keyword style. --- mediagoblin/gmg_commands/users.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mediagoblin/gmg_commands/users.py b/mediagoblin/gmg_commands/users.py index 4c4b0c1b..a4d85aa4 100644 --- a/mediagoblin/gmg_commands/users.py +++ b/mediagoblin/gmg_commands/users.py @@ -21,14 +21,14 @@ from mediagoblin import mg_globals def adduser_parser_setup(subparser): subparser.add_argument( - 'username', + '--username','-u', help="Username used to login") subparser.add_argument( - 'password', - help="Your supersecret word to login") + '--password','-p', + help="Your supersecret word to login, beware of storing it in bash history") subparser.add_argument( - 'email', - help="Email to recieve notifications") + '--email','-e', + help="Email to receive notifications") def adduser(args): From 7d98005a6b2469134adcf84b7a7417a24968bd8d Mon Sep 17 00:00:00 2001 From: Manuel Urbano Santos Date: Sat, 3 Dec 2011 15:36:02 +0100 Subject: [PATCH 133/302] Prompt for arguments in adduser if not present (I created a function in util.py to check and prompt for arguments). --- mediagoblin/gmg_commands/users.py | 5 ++++- mediagoblin/gmg_commands/util.py | 13 +++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/mediagoblin/gmg_commands/users.py b/mediagoblin/gmg_commands/users.py index a4d85aa4..b437e839 100644 --- a/mediagoblin/gmg_commands/users.py +++ b/mediagoblin/gmg_commands/users.py @@ -18,7 +18,6 @@ from mediagoblin.gmg_commands import util as commands_util from mediagoblin.auth import lib as auth_lib from mediagoblin import mg_globals - def adduser_parser_setup(subparser): subparser.add_argument( '--username','-u', @@ -35,6 +34,10 @@ def adduser(args): #TODO: Lets trust admins this do not validate Emails :) commands_util.setup_app(args) + args.username = commands_util.prompt_if_not_set(args.username, "Username:") + args.password = commands_util.prompt_if_not_set(args.password, "Password:",True) + args.email = commands_util.prompt_if_not_set(args.email, "Email:") + db = mg_globals.database users_with_username = \ db.User.find({ diff --git a/mediagoblin/gmg_commands/util.py b/mediagoblin/gmg_commands/util.py index 168a0760..af172105 100644 --- a/mediagoblin/gmg_commands/util.py +++ b/mediagoblin/gmg_commands/util.py @@ -16,6 +16,7 @@ from mediagoblin import app +import getpass def setup_app(args): @@ -25,3 +26,15 @@ def setup_app(args): mgoblin_app = app.MediaGoblinApp(args.conf_file) return mgoblin_app + +def prompt_if_not_set(variable,text,password=False): + """ + Checks if the variable is None and prompt for a value if it is + """ + if (variable==None): + if not password: + variable=raw_input(text+' ') + else: + variable=getpass.getpass(text) + + return variable From 968dd9e735eeeee9da0d1c10735e9bba2817e7c0 Mon Sep 17 00:00:00 2001 From: Elrond Date: Sat, 3 Dec 2011 16:45:33 +0100 Subject: [PATCH 134/302] Bug #685: Add failing unit test The simplest way to reproduce Bug #685 is to ask for a non existent page. This should return a proper 404. It currently doesn't. So add a unit test exactly for this. This unit test fails currently! It will fail until the bug gets fixed. --- mediagoblin/tests/test_misc.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 mediagoblin/tests/test_misc.py diff --git a/mediagoblin/tests/test_misc.py b/mediagoblin/tests/test_misc.py new file mode 100644 index 00000000..09623355 --- /dev/null +++ b/mediagoblin/tests/test_misc.py @@ -0,0 +1,26 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +from nose.tools import assert_equal + +from mediagoblin.tests.tools import setup_fresh_app + + +@setup_fresh_app +def test_404_for_non_existent(test_app): + assert_equal(test_app.get('/does-not-exist/', + expect_errors=True).status_int, + 404) From 71c6c432a5fe8fe0f96dac284562a8e1b981d669 Mon Sep 17 00:00:00 2001 From: Elrond Date: Sat, 3 Dec 2011 21:20:11 +0100 Subject: [PATCH 135/302] Bug #685: only provide CSRF token if it exists This was suggested by Nathan Yergler in the bug logs. Just implementing it. - Let render_csrf_form_token return None, if the CSRF_TOKEN is not available in the environ, because the process_request part of the meddleware has not yet run. - In render_template: If the returned value from above is None, then do not add the csrf_token to the templates context. --- mediagoblin/meddleware/csrf.py | 3 +++ mediagoblin/tools/template.py | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/mediagoblin/meddleware/csrf.py b/mediagoblin/meddleware/csrf.py index 16541bee..a4e4e5c6 100644 --- a/mediagoblin/meddleware/csrf.py +++ b/mediagoblin/meddleware/csrf.py @@ -50,6 +50,9 @@ def render_csrf_form_token(request): """Render the CSRF token in a format suitable for inclusion in a form.""" + if 'CSRF_TOKEN' not in request.environ: + return None + form = CsrfForm(csrf_token=request.environ['CSRF_TOKEN']) return form.csrf_token diff --git a/mediagoblin/tools/template.py b/mediagoblin/tools/template.py index f48b7c2e..d0400347 100644 --- a/mediagoblin/tools/template.py +++ b/mediagoblin/tools/template.py @@ -79,7 +79,9 @@ def render_template(request, template_path, context): template = request.template_env.get_template( template_path) context['request'] = request - context['csrf_token'] = render_csrf_form_token(request) + rendered_csrf_token = render_csrf_form_token(request) + if rendered_csrf_token is not None: + context['csrf_token'] = render_csrf_form_token(request) rendered = template.render(context) if common.TESTS_ENABLED: From a6f065632a8410dc7e032267fd3ef16ae5d9576c Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Sat, 3 Dec 2011 16:59:20 -0600 Subject: [PATCH 136/302] Updated translations --- .../i18n/ar/LC_MESSAGES/mediagoblin.mo | Bin 12268 -> 12629 bytes .../i18n/ar/LC_MESSAGES/mediagoblin.po | 52 ++++++-- .../i18n/ca/LC_MESSAGES/mediagoblin.mo | Bin 10826 -> 11417 bytes .../i18n/ca/LC_MESSAGES/mediagoblin.po | 52 ++++++-- .../i18n/de/LC_MESSAGES/mediagoblin.mo | Bin 11119 -> 11684 bytes .../i18n/de/LC_MESSAGES/mediagoblin.po | 70 +++++++--- .../i18n/en/LC_MESSAGES/mediagoblin.po | 50 ++++++-- .../i18n/eo/LC_MESSAGES/mediagoblin.mo | Bin 10809 -> 11489 bytes .../i18n/eo/LC_MESSAGES/mediagoblin.po | 70 +++++++--- .../i18n/es/LC_MESSAGES/mediagoblin.mo | Bin 11329 -> 11967 bytes .../i18n/es/LC_MESSAGES/mediagoblin.po | 103 ++++++++++----- .../i18n/fr/LC_MESSAGES/mediagoblin.mo | Bin 11583 -> 12215 bytes .../i18n/fr/LC_MESSAGES/mediagoblin.po | 114 +++++++++++------ .../i18n/ia/LC_MESSAGES/mediagoblin.mo | Bin 10530 -> 11150 bytes .../i18n/ia/LC_MESSAGES/mediagoblin.po | 52 ++++++-- .../i18n/it/LC_MESSAGES/mediagoblin.mo | Bin 11026 -> 11534 bytes .../i18n/it/LC_MESSAGES/mediagoblin.po | 52 ++++++-- .../i18n/ja/LC_MESSAGES/mediagoblin.mo | Bin 11224 -> 11791 bytes .../i18n/ja/LC_MESSAGES/mediagoblin.po | 52 ++++++-- .../i18n/nl/LC_MESSAGES/mediagoblin.mo | Bin 10695 -> 11306 bytes .../i18n/nl/LC_MESSAGES/mediagoblin.po | 52 ++++++-- .../i18n/nn_NO/LC_MESSAGES/mediagoblin.mo | Bin 10287 -> 10845 bytes .../i18n/nn_NO/LC_MESSAGES/mediagoblin.po | 56 ++++++-- .../i18n/pt_BR/LC_MESSAGES/mediagoblin.mo | Bin 10945 -> 11508 bytes .../i18n/pt_BR/LC_MESSAGES/mediagoblin.po | 52 ++++++-- .../i18n/ro/LC_MESSAGES/mediagoblin.mo | Bin 11067 -> 11761 bytes .../i18n/ro/LC_MESSAGES/mediagoblin.po | 121 ++++++++++++------ .../i18n/ru/LC_MESSAGES/mediagoblin.mo | Bin 13899 -> 14235 bytes .../i18n/ru/LC_MESSAGES/mediagoblin.po | 56 ++++++-- .../i18n/sk/LC_MESSAGES/mediagoblin.mo | Bin 11267 -> 11701 bytes .../i18n/sk/LC_MESSAGES/mediagoblin.po | 56 ++++++-- .../i18n/sl/LC_MESSAGES/mediagoblin.mo | Bin 10764 -> 11351 bytes .../i18n/sl/LC_MESSAGES/mediagoblin.po | 52 ++++++-- .../i18n/sr/LC_MESSAGES/mediagoblin.mo | Bin 10627 -> 11247 bytes .../i18n/sr/LC_MESSAGES/mediagoblin.po | 52 ++++++-- .../i18n/sv/LC_MESSAGES/mediagoblin.mo | Bin 11015 -> 11450 bytes .../i18n/sv/LC_MESSAGES/mediagoblin.po | 52 ++++++-- .../i18n/te/LC_MESSAGES/mediagoblin.mo | Bin 10812 -> 11439 bytes .../i18n/te/LC_MESSAGES/mediagoblin.po | 52 ++++++-- .../i18n/zh_TW/LC_MESSAGES/mediagoblin.mo | Bin 10509 -> 11108 bytes .../i18n/zh_TW/LC_MESSAGES/mediagoblin.po | 107 +++++++++++----- 41 files changed, 1056 insertions(+), 319 deletions(-) diff --git a/mediagoblin/i18n/ar/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/ar/LC_MESSAGES/mediagoblin.mo index 4e4e8863d2e81b03e1fec3a2d44ffa6d6ce7016a..aa6eacac22dc24f35dc38b71d9b818a227df36f1 100644 GIT binary patch delta 4318 zcmc)K4Q!Nm9l-JbF0+%i{25-eq%WvIOTKCex{iQNO>tD-L{P zhD1{CbN9dJ{x84Z@Bh2J^Jjg@w@W5}Me*-p{#Ww<@*VQ&AOFrwQ>v7YXR!=_jF<3T zY{mLp%e>eo=7yMR-bN~*jWN^M|Z7BZ*m#UeDY72_zI zdm8zHT9B_)3D%)Jw+dx^V{ZHboXh73R^T42#;@UIJb?vx2FqDry^?$2S2&X|_&c~!q|Wg?!hDYbF5&prT9KB!0JM!5_mU;@gxQ%ZC&teph7ZD)VQVUpBg4&FHr@ByL)Qhq~7iD1|`BP8wBF}#pC1$VUc6=SB zDngvE0e9eh{31%Sj$$kR5GARm54i`&tHSSOHMnZND*@L=(8s9;wiYdfh#%H30P-6!+ zqb%&=$MG0;;w9uyHM84xT#pi|y(rc41WKx2#vPb^hc_*}>ENk0^iVF+QJjRwkh`S5 zg|eZOC|`UZIh6VVan<++Ucx`3%yW^rlMPiu3Cco?a669S{rDy_Z&HQWj-;RsSKw-t zh>YL}CXu_T{(#J_0^ByqVI{tRn^2zr3(Co-P%u2IDp7LWj+{~5ixaL`(NY+3hS~D%ty(22xWpcln`%0*-$Sw;x5eGYs}nhj52;4 zGuN6haVFJ_a=W(SVvL~NmIL*~U+(8w24vziN`1YDveU^SqJqV^9QWZmJdN@@ne9HP z#AO)8JUoKjO!W+Mk<=-al>7)~-ZybQ{(3R-mz^{(QR;ErfvfSi*eT=0RUAdBffw;X zyo`6@ItC>IV<`9f5Pk-y5*`Wp07}Y|$eGk3B>n0%O0B#lU&sVku^;o;jV$2cr|}$a z#agKrd?@G9PccXD;Oz3LvEj=>JzOyf;A zs@l-7YsPJ3&|K`+yL!-!ScZRO>cW|Q!=C5ZJB_esIkx}m)P^!!8{x1sY5O^x{gxfkhMmy;R?O7qL!N27tgS6uFZ`^G$u9RS^jFPz!M`}8t7ffZ*Lyl@jF`-7 z>V)a7)*CzyVH$2CsMbX+&#%k3%WTh#>x45L*S0yThYZ&pb>b2KTK=N^PDgtVLjz{} z_`ZSzf#9ea3p<0RjAl;QE%E4d`eJNCP8%F=DSR+cu)!WNVpb%xQ-ANQ9WyzUXAJDj z#?ikxtG-`v$t|QdnWJW0ZE~`~;5dy#aVKoLu4NCX&9TV!Ey)L--0Tdw!OUwzcH8V| z&?M}m24@=_@)AvIbKDxRY$N6`Em~ONk`bMINNsWWnEMd)Hx}(Gj62zY5)U&H^qYz+ z3&YL`F}WU!&f*P=O@eRPt`{H9WZYHT%po&QqBI9{bzdSgso^&H2Z~23%|XM8X(JMe za}I69;-(QvkTc8mT>m%4cjspcN%vDO5x=}-i+{MJzGuLU=uyjysvc%kJyA0k5jmIb zcsgRnOtz@|%&7R`nUS`(_T?+a z$IH6{rT?-K{dsP~O}*uRXhci=nu=w`si#uM(|dJ#e`-8+H1*BYiShgAR|Y1n$@Hb_ z8~Re}sr0_o>Gb0&^?Z77`g5so`}bB8=c-=+iK_Xn9nLU!R_gUu8`k%#u1sBfT%GTYswliT~b$kUywfZfH^k!SYE2qt9etCI#@rlWZSKG zsmYu=m0ctASV?QLXl gH0ce@dV6}A|3TANTQc45qx7*aG_Rfa@A{bfJGzJu&j0`b delta 4051 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\n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -102,7 +102,7 @@ msgid "Tags" msgstr "الوسوم" #: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 -msgid "Seperate tags by commas or spaces." +msgid "Seperate tags by commas." msgstr "" #: mediagoblin/edit/forms.py:33 @@ -265,6 +265,11 @@ msgstr "أحدث الوسائط" msgid "Enter your new password" msgstr "أدخل كلمة سرك الجديدة" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:33 +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Submit" +msgstr "أرسل" + #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" msgstr "" @@ -378,10 +383,6 @@ msgstr "" msgid "Submit yer media" msgstr "انشر وسائطك" -#: mediagoblin/templates/mediagoblin/submit/start.html:30 -msgid "Submit" -msgstr "أرسل" - #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format msgid "%(username)s's media" @@ -392,6 +393,35 @@ msgstr "" msgid "%(username)s's media" msgstr "وسائط %(username)s" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#, python-format +msgid "By %(username)s on %(date)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +msgid "Post a comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +msgid "at" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +msgid "Post comment!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +msgid "Edit" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +msgid "Delete" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 +msgid "Sorry, no such media found." +msgstr "" + #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -517,6 +547,10 @@ msgstr "الأحدث" msgid "Older" msgstr "الأقدم" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:50 +msgid "Go to page:" +msgstr "" + #: mediagoblin/templates/mediagoblin/utils/tags.html:20 msgid "Tagged with" msgstr "" @@ -534,11 +568,11 @@ msgid "I am sure I want to delete this" msgstr "أنا متأكد من رغبتي بحذف هذا العمل" #: mediagoblin/user_pages/views.py:155 -msgid "Empty comments are not allowed." +msgid "Oops, your comment was empty." msgstr "" #: mediagoblin/user_pages/views.py:161 -msgid "Comment posted!" +msgid "Your comment has been posted!" msgstr "" #: mediagoblin/user_pages/views.py:183 diff --git a/mediagoblin/i18n/ca/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/ca/LC_MESSAGES/mediagoblin.mo index 9b9e7e3b220d3944625628ab743adf6e86e37b8b..203114fc48eade7f6b1a9e9c36a641e4a9c802e3 100644 GIT binary patch literal 11417 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 GUHuEm@Uz(f diff --git a/mediagoblin/i18n/ca/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/ca/LC_MESSAGES/mediagoblin.po index f07ab2d6..a05dc5c0 100644 --- a/mediagoblin/i18n/ca/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/ca/LC_MESSAGES/mediagoblin.po @@ -9,8 +9,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-11-27 15:25-0600\n" -"PO-Revision-Date: 2011-11-27 21:28+0000\n" +"POT-Creation-Date: 2011-12-03 16:57-0600\n" +"PO-Revision-Date: 2011-12-03 22:56+0000\n" "Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -100,7 +100,7 @@ msgid "Tags" msgstr "Etiquetes" #: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 -msgid "Seperate tags by commas or spaces." +msgid "Seperate tags by commas." msgstr "" #: mediagoblin/edit/forms.py:33 @@ -262,6 +262,11 @@ msgstr "" msgid "Enter your new password" msgstr "" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:33 +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Submit" +msgstr "Envia" + #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" msgstr "" @@ -368,10 +373,6 @@ msgstr "" msgid "Submit yer media" msgstr "Envieu els vostres fitxers" -#: mediagoblin/templates/mediagoblin/submit/start.html:30 -msgid "Submit" -msgstr "Envia" - #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format msgid "%(username)s's media" @@ -382,6 +383,35 @@ msgstr "" msgid "%(username)s's media" msgstr "%(username)s's media" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#, python-format +msgid "By %(username)s on %(date)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +msgid "Post a comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +msgid "at" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +msgid "Post comment!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +msgid "Edit" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +msgid "Delete" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 +msgid "Sorry, no such media found." +msgstr "" + #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -509,6 +539,10 @@ msgstr "" msgid "Older" msgstr "" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:50 +msgid "Go to page:" +msgstr "" + #: mediagoblin/templates/mediagoblin/utils/tags.html:20 msgid "Tagged with" msgstr "" @@ -526,11 +560,11 @@ msgid "I am sure I want to delete this" msgstr "" #: mediagoblin/user_pages/views.py:155 -msgid "Empty comments are not allowed." +msgid "Oops, your comment was empty." msgstr "" #: mediagoblin/user_pages/views.py:161 -msgid "Comment posted!" +msgid "Your comment has been posted!" msgstr "" #: mediagoblin/user_pages/views.py:183 diff --git a/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.mo index 056e3ecaac4d6dbbadcfc480f2279b81df03f85c..4747bd76ae93ca162d34495cb36915be3906aa12 100644 GIT binary patch delta 4609 zcmc)M32YqI8Nl(kIUuo#6Fb3<&%CwcBfcF-C@sGz2$2vO8pN&!)XNQG!4)TWJ!DiBvAAti)G}^=j@9^Ed;{Oa zK0Llasf8HhV=b2BcHD?-@OI=^9pyv1ejeq$<9LQr(`rGPQrl=)jP$AY;1YCj00WfC z9Y(&OR+KAMg>5MBosZJKz0|%7mvf)OIy`_)csI_&pW#{fB-Sv#`eo^b*KiRJ5*p`YBg*EqptKK`+P9P(#zxvlko{77OYTQm z%1y{@)FG4*{0K96WC;OcEVY7BC8&MKGqn{ZMte{u7@`bpkzaK`AM*ZBQDSxsuf*S= zWJL$->&9!b9>0OISr6g>K7+EUf2m@Fq~lXG$iNE-lmxvNrQ=o{!cLUU+Kb!qR+Irw z;CUD$hkNmS)R@6hycPTKWt2!(5RMR+;d(qc&4q;QIb;s%IBGnJk`?obyReWYY3-i-7+tsdoqv!@=% zwfKwT19b|&!u@=vD-*a8WuV(o_V59`4}XWUg?l-Lk~3dLiNM_`d;BP}OX>)+R`n}n z?&@`Hk^_2*3)$;BGL8IEE09H~0pwR*#)pJHi;ShNN9pJg%GUh^WpAHA8R%)096Es# z(O1#pQmxcm_#nzwd@IiBnC9XsE)L-dOrXapHnVZkLBNm@B*`z;Vq_wcbVF}0B^%^m(^7%zNw z7pKjPCJb?(a#-8MWR&k!I|4WDdQR4MEorU`*%DoPN$vExE#1WJ_9f#LfnN+L@i3{l z?X7I6Nc#JT$%moXQn_uFA^5HrMnSHy<)IoelO|xJGz$xLB46m#3484wmHQgZgyUwl zlS&1wLp#~PIH^2)=7v#d->O_!UdSXpM!uwMP1R0&sH%N5ZBly5jWTMK9@S{Zlp-SQ z^884rOx7?(oiIs3BNprzPiPrp32Eo&=>c(5puC zlSaElKJB>n@n!2OP2i5@i(e>2CvN|`?4pV*1K&%380ndTv**W#XV)3cMxa;iVNnw~ zb}nILe2J7~oX<-2xaUvlsZ1eNL)j+zUU35=KW+!A8!v5VVY8dS&bnhR9TZmjiH(ZO zIKga0I6CaBF`k|zXGo30Q@ginsZCT5cX1pI6AJkTQ5^FFM#$=P;Vkq7CQE9R4tTG9 zsQTRH1X4MX8Z$EYr0*$-qo0fH2h|4`t?ubRM-QwWTytJe|5|%TP5p(1mes2V*R1X8 z=cnv4CyaVV1IG*L*$)PFa>^tUWa)*ai;GjlC!fsvxzx;?HS=QgWLxZ_rkdsILef9W zal5Gbe=b|QYH)Qzm@8J4U!LB`2aoVrO)!(Twlc=qVw zzz)@4Gk0UL(lvgf(rrj20z(da>gc_!Y0~P3-Z?$Pc1Odm?WH=w@n+NL+o#Z}O@5BT zAcx{KtD@RWcfW7ws2%q`3ZC}dWG2#SBMD>Z+XVK^#(o*|bB*cwg@b1AYaBYQBKmsc zj>^K)do~o#yD1EIaZ|nhTGMiSvZ>|cb<~C{z7tE?GX0(m_IKUU=}N-N0sGIzbw~W` zvC5AZR~>Q8>p0p`iY&`ubFhzj)`T3hWaro0jZ0pDM90tn89_%xxX$969|`droU$->zK# z@5}A?TL%Y5{2<78lQ2}pWTsSC3)Qz*UE-1jf!=7mT(qByLWbCPTWe}1EmFqg6)M4Q zlcstHE@AR)O znVE3xiyh~+ZFD0}PJ*g;^l;>+IopOBs5x02``O%&+sai#l|xQ8b$}keD$1 I&&5;!1Q@MkivR!s delta 4149 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 nO7@EG%LjHc!MhJmm9v4Twz>QtgROM!@mOX\n" "Language-Team: German (http://www.transifex.net/projects/p/mediagoblin/team/de/)\n" "MIME-Version: 1.0\n" @@ -109,7 +109,7 @@ msgid "Tags" msgstr "Markierungen" #: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 -msgid "Seperate tags by commas or spaces." +msgid "Seperate tags by commas." msgstr "" #: mediagoblin/edit/forms.py:33 @@ -137,11 +137,11 @@ msgstr "Webseite" #: mediagoblin/edit/forms.py:49 msgid "Old password" -msgstr "" +msgstr "Altes Passwort" #: mediagoblin/edit/forms.py:52 msgid "New Password" -msgstr "" +msgstr "Neues Passwort" #: mediagoblin/edit/views.py:65 msgid "An entry with that slug already exists for this user." @@ -157,7 +157,7 @@ msgstr "Du bearbeitest das Profil eines Anderen. Bitte sei vorsichtig." #: mediagoblin/edit/views.py:171 msgid "Wrong password" -msgstr "" +msgstr "Falsches Passwort" #: mediagoblin/edit/views.py:192 msgid "Profile edited!" @@ -217,11 +217,11 @@ msgstr "Medien hochladen" #: mediagoblin/templates/mediagoblin/base.html:65 msgid "Verify your email!" -msgstr "" +msgstr "Bitte bestätige deine E-Mail-Adresse!" #: mediagoblin/templates/mediagoblin/base.html:72 msgid "log out" -msgstr "" +msgstr "Abmelden" #: mediagoblin/templates/mediagoblin/base.html:75 #: mediagoblin/templates/mediagoblin/auth/login.html:27 @@ -275,6 +275,11 @@ msgstr "Neuste Medien" msgid "Enter your new password" msgstr "Neues Passwort eingeben" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:33 +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Submit" +msgstr "Bestätigen" + #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" msgstr "" @@ -389,20 +394,45 @@ msgstr "" msgid "Submit yer media" msgstr "Medien hochladen" -#: mediagoblin/templates/mediagoblin/submit/start.html:30 -msgid "Submit" -msgstr "Bestätigen" - #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format msgid "%(username)s's media" -msgstr "" +msgstr "%(username)ss Medien" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:37 #, python-format msgid "%(username)s's media" msgstr "%(username)ss Medien" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#, python-format +msgid "By %(username)s on %(date)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +msgid "Post a comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +msgid "at" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +msgid "Post comment!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +msgid "Edit" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +msgid "Delete" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 +msgid "Sorry, no such media found." +msgstr "" + #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -535,13 +565,17 @@ msgstr "Neuere" msgid "Older" msgstr "Ältere" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:50 +msgid "Go to page:" +msgstr "" + #: mediagoblin/templates/mediagoblin/utils/tags.html:20 msgid "Tagged with" msgstr "" #: mediagoblin/templates/mediagoblin/utils/tags.html:25 msgid "and" -msgstr "" +msgstr "und" #: mediagoblin/user_pages/forms.py:24 msgid "Comment" @@ -552,12 +586,12 @@ msgid "I am sure I want to delete this" msgstr "Ja, wirklich löschen" #: mediagoblin/user_pages/views.py:155 -msgid "Empty comments are not allowed." -msgstr "Leere Kommentare sind nicht erlaubt." +msgid "Oops, your comment was empty." +msgstr "" #: mediagoblin/user_pages/views.py:161 -msgid "Comment posted!" -msgstr "Kommentar hinzugefügt!" +msgid "Your comment has been posted!" +msgstr "" #: mediagoblin/user_pages/views.py:183 msgid "You deleted the media." diff --git a/mediagoblin/i18n/en/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/en/LC_MESSAGES/mediagoblin.po index c1f3fd7f..3732705c 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-11-27 15:25-0600\n" +"POT-Creation-Date: 2011-12-03 16:57-0600\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -94,7 +94,7 @@ msgid "Tags" msgstr "" #: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 -msgid "Seperate tags by commas or spaces." +msgid "Seperate tags by commas." msgstr "" #: mediagoblin/edit/forms.py:33 @@ -256,6 +256,11 @@ msgstr "" msgid "Enter your new password" msgstr "" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:33 +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Submit" +msgstr "" + #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" msgstr "" @@ -355,10 +360,6 @@ msgstr "" msgid "Submit yer media" msgstr "" -#: mediagoblin/templates/mediagoblin/submit/start.html:30 -msgid "Submit" -msgstr "" - #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format msgid "%(username)s's media" @@ -369,6 +370,35 @@ msgstr "" msgid "%(username)s's media" msgstr "" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#, python-format +msgid "By %(username)s on %(date)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +msgid "Post a comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +msgid "at" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +msgid "Post comment!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +msgid "Edit" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +msgid "Delete" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 +msgid "Sorry, no such media found." +msgstr "" + #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -490,6 +520,10 @@ msgstr "" msgid "Older" msgstr "" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:50 +msgid "Go to page:" +msgstr "" + #: mediagoblin/templates/mediagoblin/utils/tags.html:20 msgid "Tagged with" msgstr "" @@ -507,11 +541,11 @@ msgid "I am sure I want to delete this" msgstr "" #: mediagoblin/user_pages/views.py:155 -msgid "Empty comments are not allowed." +msgid "Oops, your comment was empty." msgstr "" #: mediagoblin/user_pages/views.py:161 -msgid "Comment posted!" +msgid "Your comment has been posted!" msgstr "" #: mediagoblin/user_pages/views.py:183 diff --git a/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.mo index c537c65e789f0388ddfed653f85585e3592c9dcf..02d094863da2ae88004e9a0b53efe8247bc186d3 100644 GIT binary patch delta 4345 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\n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -102,7 +102,7 @@ msgid "Tags" msgstr "Etikedoj" #: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 -msgid "Seperate tags by commas or spaces." +msgid "Seperate tags by commas." msgstr "" #: mediagoblin/edit/forms.py:33 @@ -130,11 +130,11 @@ msgstr "Retejo" #: mediagoblin/edit/forms.py:49 msgid "Old password" -msgstr "" +msgstr "La malnova pasvorto" #: mediagoblin/edit/forms.py:52 msgid "New Password" -msgstr "" +msgstr "La nova pasvorto" #: mediagoblin/edit/views.py:65 msgid "An entry with that slug already exists for this user." @@ -150,7 +150,7 @@ msgstr "Vi redaktas profilon de alia uzanto. Agu singardeme." #: mediagoblin/edit/views.py:171 msgid "Wrong password" -msgstr "" +msgstr "Malĝusta pasvorto" #: mediagoblin/edit/views.py:192 msgid "Profile edited!" @@ -214,7 +214,7 @@ msgstr "" #: mediagoblin/templates/mediagoblin/base.html:72 msgid "log out" -msgstr "" +msgstr "elsaluti" #: mediagoblin/templates/mediagoblin/base.html:75 #: mediagoblin/templates/mediagoblin/auth/login.html:27 @@ -236,7 +236,7 @@ msgstr "" #: mediagoblin/templates/mediagoblin/root.html:27 msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "" +msgstr "Saluton, kaj bonvenon al ĉi tiu MediaGoblina retpaĝaro!" #: mediagoblin/templates/mediagoblin/root.html:28 msgid "Your finest source for all goblin-related media." @@ -268,6 +268,11 @@ msgstr "Plej nove aldonitaj dosieroj" msgid "Enter your new password" msgstr "Enigu vian novan pasvorton" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:33 +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Submit" +msgstr "Alŝuti" + #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" msgstr "" @@ -376,16 +381,12 @@ msgstr "" #: mediagoblin/templates/mediagoblin/media_displays/video.html:19 msgid "Original" -msgstr "" +msgstr "Originalo" #: mediagoblin/templates/mediagoblin/submit/start.html:26 msgid "Submit yer media" msgstr "Alŝutu vian aŭd-vid-dosieron" -#: mediagoblin/templates/mediagoblin/submit/start.html:30 -msgid "Submit" -msgstr "Alŝuti" - #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format msgid "%(username)s's media" @@ -396,6 +397,35 @@ msgstr "" msgid "%(username)s's media" msgstr "Dosieroj de %(username)s" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#, python-format +msgid "By %(username)s on %(date)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +msgid "Post a comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +msgid "at" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +msgid "Post comment!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +msgid "Edit" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +msgid "Delete" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 +msgid "Sorry, no such media found." +msgstr "" + #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -527,13 +557,17 @@ msgstr "Plinovaj" msgid "Older" msgstr "Malplinovaj" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:50 +msgid "Go to page:" +msgstr "" + #: mediagoblin/templates/mediagoblin/utils/tags.html:20 msgid "Tagged with" msgstr "" #: mediagoblin/templates/mediagoblin/utils/tags.html:25 msgid "and" -msgstr "" +msgstr "kaj" #: mediagoblin/user_pages/forms.py:24 msgid "Comment" @@ -544,12 +578,12 @@ msgid "I am sure I want to delete this" msgstr "Mi estas certa, ke mi volas forigi ĉi tion" #: mediagoblin/user_pages/views.py:155 -msgid "Empty comments are not allowed." -msgstr "Malplenaj komentoj ne estas afiŝeblaj." +msgid "Oops, your comment was empty." +msgstr "" #: mediagoblin/user_pages/views.py:161 -msgid "Comment posted!" -msgstr "La komento estas afiŝita!" +msgid "Your comment has been posted!" +msgstr "" #: mediagoblin/user_pages/views.py:183 msgid "You deleted the media." diff --git a/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.mo index 2d2b92430cb5f82160be8bc3b3da0290f3206d86..dba37f0a814c9490904ba6c6914b58c5b74c3298 100644 GIT binary patch delta 4405 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 NRksNwS4#@3{{m7eC<_1p delta 3826 zcmai#3yfS<8Gz5o0=wImZkN&r?e3o0w%gryclJRSL!m7N+ENNji!Fulkh62o?A-00 zdx!hjG6<|8HmSj2!jS}w)c`RdS|Ti>CMA__2of~JCI&T;Acjy4#E6M8qS5c4SxT!W zPG;_R?z!jw@Bg3Ucf4}T^xN%Ck19T8ek=LievaII`uWCrN-g2`2z(p92nV4%U#T%T z3tM1&vr-4(N_Z(e46lR7;V5k7kes`ci>SB`mXw-SV=R!VegIqHF}M@H29d26vAGZ~ zhi$MA-U~Ov`g^dQ`(ty@-<-RD2QFj(FYsbGe;z-$7A}PwU?=+3^(+>!aR4rdHP{6m zl!G%+BJ&2k5T1f!*gs$sY(nZqum$deT~G|pU_U$r?}snIx8M-UdSUYgoRtH^ENXBM zEW$Tn9u6W!6z+lD(7MNStER=*pR*&ecn2xXZC>7;czj2}*JvgCgKt z5FP4!Pz1dU*T54{Ts;LP)~)z^9qfi8zXCrCzYYuVs`EK*~TJffCB2@Hl)GN@NaoGz@+SiXq>G;^Ft9GRW6c>Q&4K*V<-_?ze+lsutL(W z_CdaCl8bo!Fr=>3GmtE(V^Bi>78JR^gW^Eb>PFEnfb-C=+F4+O>VyHj55YjzLlQ5L^dehP&Y@I07%jit}Lrcfk}&t^5Rv{F8my z-NNE;Y)D8ygOr=#Qn&?9!X5BgI0iq0V$jz0v?#m_UIu>!=fQSbKtkOK-7n7XUQo8i zv+?JXY`o&9k2Lo$(52W~ZHmPx3sZMhbI;jF+~kT8_jL1Z)4Cd%qSd7+)>Ru-1FO?W z7o#9B<56rR0@5 zLWEV!0fd&VJ{ZM;r;Q%BX=+g?im%~G9Ay(_?b)IY)7S+5y>)4I6}@(f&CCQrtskrE zB9kZz^L@Hx(O*BAcdacyozDCqt-E3GNo|<;<9^_$wSv~YH)KKTi)VGqbXu$0+KC z7E~%&tE*9xS}*VJYF+7`Ykkt~pSRT=n^&2rRMVR1l|zX}kq)C&<6CsldIhyDl&I9A zEY_htsH-MPh?sZgewNrcG!;u8w5=FFP}}Y)`Y00@CL=%8S+d1#nZLSYJK68oCc%|@ zC3sP#pnLb*cfa^}Y~2^uTwLhhykl(N6@zB8uEx=%Ev6hVi3J!`=uN?v=K#O@mc4VUs~|rch2RLHFicqf8e~sLM8};-B^_7(68< zKUs?CO=cX@Y^}}<%@Q@ z_b$48W^hSU&K+91%)P(VxZ1M9%96!*zZivz0Q#j`BiZ#t=H2mShew77hKBXXB^!q~ z3=EA94YlsRao{F9)%Kn;-4*MUWJvE9F^`V=WHzv@(ap>T;~AL=v(FokTu`d*~=WIVN@7mGm#LSDzxNqVh%By-NaVXQ{CUnCclm9U;9_#3F|Ll0%z1z9V?df`Q z$F~17FLs6#lri>YI?U{p@eBNM8>hx2E}vsJkx1~OWQ{P_=!VGMzh+tg zrxS%VRkOLQrI8o?k9l&fek!-q$2R}7wtkw{C95r4W+lCy^lg(XvFS@#1u_x!5+ z+{V>I?!MIn3$})-KarV4?UPaSr`5x5)0zWaJ1f;JXr!2FIZ;n#-KnW4!4nxa*ZlXe z(Km~KktfERTIQLU=n$iNRniQW(Jo%oSe1HL^|>Fe={wJcQ)Jl<^{jFEp6%|@p2P0; zwXN>KwdMBf`TIb*PvH7_of>vWx^%m)8LD3=^aI1YLaVq_YcCy3)QKmy@%I`R%l=eE zY9!b+B{E_%W*Va?%r}lT8kD~%{*mj2TyM!w`Yg%M+}-vC>v ppsQ(b)-b~TdSI`!g^kN+j}r5UMzJ1(Z\n" "Language-Team: Spanish (Castilian) (http://www.transifex.net/projects/p/mediagoblin/team/es/)\n" "MIME-Version: 1.0\n" @@ -64,7 +64,7 @@ msgstr "Lo sentimos, ya existe un usuario con ese nombre." #: mediagoblin/auth/views.py:77 msgid "Sorry, a user with that email address already exists." -msgstr "" +msgstr "Lo sentimos, ya existe un usuario con esa dirección de email." #: mediagoblin/auth/views.py:179 msgid "" @@ -82,10 +82,12 @@ msgstr "" #: mediagoblin/auth/views.py:203 msgid "You must be logged in so we know who to send the email to!" msgstr "" +"Debes iniciar sesión para que podamos saber a quién le enviamos el correo " +"electrónico!" #: mediagoblin/auth/views.py:211 msgid "You've already verified your email address!" -msgstr "" +msgstr "Ya haz verificado tu dirección de email!" #: mediagoblin/auth/views.py:224 msgid "Resent your verification email." @@ -109,7 +111,7 @@ msgid "Tags" msgstr "Etiquetas" #: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 -msgid "Seperate tags by commas or spaces." +msgid "Seperate tags by commas." msgstr "" #: mediagoblin/edit/forms.py:33 @@ -137,11 +139,11 @@ msgstr "Sitio web" #: mediagoblin/edit/forms.py:49 msgid "Old password" -msgstr "" +msgstr "Vieja contraseña" #: mediagoblin/edit/forms.py:52 msgid "New Password" -msgstr "" +msgstr "Nueva contraseña" #: mediagoblin/edit/views.py:65 msgid "An entry with that slug already exists for this user." @@ -157,15 +159,15 @@ msgstr "Estás editando un perfil de usuario. Proceder con precaución." #: mediagoblin/edit/views.py:171 msgid "Wrong password" -msgstr "" +msgstr "Contraseña incorrecta" #: mediagoblin/edit/views.py:192 msgid "Profile edited!" -msgstr "" +msgstr "Perfil editado!" #: mediagoblin/media_types/__init__.py:61 msgid "Could not find any file extension in \"{filename}\"" -msgstr "" +msgstr "No se pudo encontrar la extensión del archivo en \"{filename}\"" #: mediagoblin/submit/forms.py:25 msgid "File" @@ -185,7 +187,7 @@ msgstr "¡Woohoo! ¡Enviado!" #: mediagoblin/submit/views.py:133 msgid "Invalid file type." -msgstr "" +msgstr "Tipo de archivo inválido." #: mediagoblin/templates/mediagoblin/404.html:21 msgid "Oops!" @@ -217,11 +219,11 @@ msgstr "Enviar contenido" #: mediagoblin/templates/mediagoblin/base.html:65 msgid "Verify your email!" -msgstr "" +msgstr "Verifica tu email!" #: mediagoblin/templates/mediagoblin/base.html:72 msgid "log out" -msgstr "" +msgstr "Cerrar sesión" #: mediagoblin/templates/mediagoblin/base.html:75 #: mediagoblin/templates/mediagoblin/auth/login.html:27 @@ -243,21 +245,23 @@ msgstr "Explorar" #: mediagoblin/templates/mediagoblin/root.html:27 msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "" +msgstr "Hola, bienvenido a este sitio de MediaGoblin!" #: mediagoblin/templates/mediagoblin/root.html:28 msgid "Your finest source for all goblin-related media." -msgstr "" +msgstr "Tu mejor fuente de contenidos relacionados con goblins." #: mediagoblin/templates/mediagoblin/root.html:29 msgid "" "To add your own media, place comments, save your favourites and more, you " "can log in with your MediaGoblin account." msgstr "" +"Para añadir tus propios contenidos, dejar comentarios, guardar tus favoritos" +" y más, puedes iniciar sesión con tu cuenta de MediaGoblin." #: mediagoblin/templates/mediagoblin/root.html:31 msgid "Don't have one yet? It's easy!" -msgstr "" +msgstr "Aún no tienes una? Es fácil!" #: mediagoblin/templates/mediagoblin/root.html:32 #, python-format @@ -266,6 +270,9 @@ msgid "" " or\n" " Set up MediaGoblin on your own server" msgstr "" +"Crea una cuenta en este sitio\n" +" o\n" +" Instala MediaGoblin en tu propio servidor" #: mediagoblin/templates/mediagoblin/root.html:44 msgid "Most recent media" @@ -275,13 +282,18 @@ msgstr "El contenido más reciente" msgid "Enter your new password" msgstr "Ingrese su nueva contraseña" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:33 +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Submit" +msgstr "Enviar" + #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" -msgstr "" +msgstr "Recuperar contraseña" #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:30 msgid "Send instructions" -msgstr "" +msgstr "Enviar instrucciones" #: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 msgid "Your password has been changed. Try to log in now." @@ -376,30 +388,55 @@ msgstr "Editando el perfil de %(username)s" #: mediagoblin/templates/mediagoblin/listings/tag.html:35 #, python-format msgid "Media tagged with: %(tag_name)s" -msgstr "" +msgstr "Contenido etiquetado con: %(tag_name)s" #: mediagoblin/templates/mediagoblin/media_displays/video.html:19 msgid "Original" -msgstr "" +msgstr "Original" #: mediagoblin/templates/mediagoblin/submit/start.html:26 msgid "Submit yer media" msgstr "Envía tu contenido" -#: mediagoblin/templates/mediagoblin/submit/start.html:30 -msgid "Submit" -msgstr "Enviar" - #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format msgid "%(username)s's media" -msgstr "" +msgstr "Contenidos de %(username)s" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:37 #, python-format msgid "%(username)s's media" msgstr "Contenido de %(username)s's" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#, python-format +msgid "By %(username)s on %(date)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +msgid "Post a comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +msgid "at" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +msgid "Post comment!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +msgid "Edit" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +msgid "Delete" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 +msgid "Sorry, no such media found." +msgstr "" + #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -532,13 +569,17 @@ msgstr "Recientes" msgid "Older" msgstr "Antiguas" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:50 +msgid "Go to page:" +msgstr "" + #: mediagoblin/templates/mediagoblin/utils/tags.html:20 msgid "Tagged with" -msgstr "" +msgstr "Etiquetado con" #: mediagoblin/templates/mediagoblin/utils/tags.html:25 msgid "and" -msgstr "" +msgstr "y" #: mediagoblin/user_pages/forms.py:24 msgid "Comment" @@ -549,20 +590,20 @@ msgid "I am sure I want to delete this" msgstr "Estoy seguro de que quiero borrar esto" #: mediagoblin/user_pages/views.py:155 -msgid "Empty comments are not allowed." +msgid "Oops, your comment was empty." msgstr "" #: mediagoblin/user_pages/views.py:161 -msgid "Comment posted!" +msgid "Your comment has been posted!" msgstr "" #: mediagoblin/user_pages/views.py:183 msgid "You deleted the media." -msgstr "" +msgstr "Eliminaste el contenido" #: mediagoblin/user_pages/views.py:190 msgid "The media was not deleted because you didn't check that you were sure." -msgstr "" +msgstr "El contenido no se eliminó porque no marcaste que estabas seguro." #: mediagoblin/user_pages/views.py:198 msgid "You are about to delete another user's media. Proceed with caution." diff --git a/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.mo index 90e833039023edeafae9a63dc03855e1fec26bb7..c7f5701f02702fca61eea8d81fe37ce5f6284fe5 100644 GIT binary patch delta 4516 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 GD*qSCoLVmc delta 3934 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 PV{=||qbl3CR_Xr&DRta# diff --git a/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.po index b37f5217..0bff6c37 100644 --- a/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.po @@ -13,8 +13,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-11-27 15:25-0600\n" -"PO-Revision-Date: 2011-11-27 21:28+0000\n" +"POT-Creation-Date: 2011-12-03 16:57-0600\n" +"PO-Revision-Date: 2011-12-03 22:56+0000\n" "Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -64,7 +64,7 @@ msgstr "Un utilisateur existe déjà avec ce nom, désolé." #: mediagoblin/auth/views.py:77 msgid "Sorry, a user with that email address already exists." -msgstr "" +msgstr "Désolé, il existe déjà un utilisateur ayant cette adresse e-mail." #: mediagoblin/auth/views.py:179 msgid "" @@ -81,10 +81,11 @@ msgstr "La clé de vérification ou le nom d'utilisateur est incorrect." #: mediagoblin/auth/views.py:203 msgid "You must be logged in so we know who to send the email to!" msgstr "" +"Vous devez être authentifié afin que nous sachions à qui envoyer l'e-mail !" #: mediagoblin/auth/views.py:211 msgid "You've already verified your email address!" -msgstr "" +msgstr "Votre adresse e-mail a déjà été vérifiée !" #: mediagoblin/auth/views.py:224 msgid "Resent your verification email." @@ -107,7 +108,7 @@ msgid "Tags" msgstr "Tags" #: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 -msgid "Seperate tags by commas or spaces." +msgid "Seperate tags by commas." msgstr "" #: mediagoblin/edit/forms.py:33 @@ -135,11 +136,11 @@ msgstr "Site web" #: mediagoblin/edit/forms.py:49 msgid "Old password" -msgstr "" +msgstr "Ancien mot de passe." #: mediagoblin/edit/forms.py:52 msgid "New Password" -msgstr "" +msgstr "Nouveau mot de passe" #: mediagoblin/edit/views.py:65 msgid "An entry with that slug already exists for this user." @@ -159,15 +160,15 @@ msgstr "" #: mediagoblin/edit/views.py:171 msgid "Wrong password" -msgstr "" +msgstr "Mauvais mot de passe" #: mediagoblin/edit/views.py:192 msgid "Profile edited!" -msgstr "" +msgstr "Profile mis à jour !" #: mediagoblin/media_types/__init__.py:61 msgid "Could not find any file extension in \"{filename}\"" -msgstr "" +msgstr "Impossible d'extraire une extension de fichier de \"{nomfichier}\"" #: mediagoblin/submit/forms.py:25 msgid "File" @@ -187,11 +188,11 @@ msgstr "Youhou, c'est envoyé !" #: mediagoblin/submit/views.py:133 msgid "Invalid file type." -msgstr "" +msgstr "Type de fichier invalide." #: mediagoblin/templates/mediagoblin/404.html:21 msgid "Oops!" -msgstr "Zut!" +msgstr "Zut !" #: mediagoblin/templates/mediagoblin/404.html:24 msgid "There doesn't seem to be a page at this address. Sorry!" @@ -219,11 +220,11 @@ msgstr "Soumettre un média" #: mediagoblin/templates/mediagoblin/base.html:65 msgid "Verify your email!" -msgstr "" +msgstr "Vérifiez votre adresse e-mail !" #: mediagoblin/templates/mediagoblin/base.html:72 msgid "log out" -msgstr "" +msgstr "déconnexion" #: mediagoblin/templates/mediagoblin/base.html:75 #: mediagoblin/templates/mediagoblin/auth/login.html:27 @@ -245,21 +246,23 @@ msgstr "Explorer" #: mediagoblin/templates/mediagoblin/root.html:27 msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "" +msgstr "Bonjour, et bienvenu sur ce site MediaGoblin !" #: mediagoblin/templates/mediagoblin/root.html:28 msgid "Your finest source for all goblin-related media." -msgstr "" +msgstr "Là où ce trouve tout vos \"goblinesque\" media." #: mediagoblin/templates/mediagoblin/root.html:29 msgid "" "To add your own media, place comments, save your favourites and more, you " "can log in with your MediaGoblin account." msgstr "" +"Ajoutez vos propres medias, commentez ceux des autres, sauvegardez vos " +"préférés et plus encore ! Faites tout cela depuis votre compte MediaGoblin." #: mediagoblin/templates/mediagoblin/root.html:31 msgid "Don't have one yet? It's easy!" -msgstr "" +msgstr "Vous n'en avez pas ? C'est facile !" #: mediagoblin/templates/mediagoblin/root.html:32 #, python-format @@ -268,6 +271,9 @@ msgid "" " or\n" " Set up MediaGoblin on your own server" msgstr "" +"Créez un compte sur ce site\n" +" ou\n" +" Déployez MediaGoblin sur votre propre serveur" #: mediagoblin/templates/mediagoblin/root.html:44 msgid "Most recent media" @@ -277,13 +283,18 @@ msgstr "Tout derniers media" msgid "Enter your new password" msgstr "Entrez un nouveau mot de passe" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:33 +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Submit" +msgstr "Soumettre" + #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" -msgstr "" +msgstr "Récupérer le mot de passe" #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:30 msgid "Send instructions" -msgstr "" +msgstr "Envoyer les instructions" #: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 msgid "Your password has been changed. Try to log in now." @@ -326,11 +337,11 @@ msgstr "La connexion a échoué!" #: mediagoblin/templates/mediagoblin/auth/login.html:35 msgid "Don't have an account yet?" -msgstr "Pas encore de compte?" +msgstr "Pas encore de compte ?" #: mediagoblin/templates/mediagoblin/auth/login.html:36 msgid "Create one here!" -msgstr "Créez-en un ici!" +msgstr "Créez-en un ici !" #: mediagoblin/templates/mediagoblin/auth/login.html:42 msgid "Forgot your password?" @@ -338,7 +349,7 @@ msgstr "Vous avez oublié votre mot de passe ?" #: mediagoblin/templates/mediagoblin/auth/register.html:27 msgid "Create an account!" -msgstr "Créer un compte!" +msgstr "Créer un compte !" #: mediagoblin/templates/mediagoblin/auth/register.html:31 msgid "Create" @@ -384,30 +395,55 @@ msgstr "Modification du profil de %(username)s" #: mediagoblin/templates/mediagoblin/listings/tag.html:35 #, python-format msgid "Media tagged with: %(tag_name)s" -msgstr "" +msgstr "Médias taggés avec : %(tag_name)s " #: mediagoblin/templates/mediagoblin/media_displays/video.html:19 msgid "Original" -msgstr "" +msgstr "Original" #: mediagoblin/templates/mediagoblin/submit/start.html:26 msgid "Submit yer media" msgstr "Soumettez ce média" -#: mediagoblin/templates/mediagoblin/submit/start.html:30 -msgid "Submit" -msgstr "Soumettre" - #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format msgid "%(username)s's media" -msgstr "" +msgstr "Medias de %(username)s" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:37 #, python-format msgid "%(username)s's media" msgstr "Médias de %(username)s" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#, python-format +msgid "By %(username)s on %(date)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +msgid "Post a comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +msgid "at" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +msgid "Post comment!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +msgid "Edit" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +msgid "Delete" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 +msgid "Sorry, no such media found." +msgstr "" + #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -542,13 +578,17 @@ msgstr "Nouveaux" msgid "Older" msgstr "Anciens" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:50 +msgid "Go to page:" +msgstr "" + #: mediagoblin/templates/mediagoblin/utils/tags.html:20 msgid "Tagged with" -msgstr "" +msgstr "Taggé avec" #: mediagoblin/templates/mediagoblin/utils/tags.html:25 msgid "and" -msgstr "" +msgstr "et" #: mediagoblin/user_pages/forms.py:24 msgid "Comment" @@ -559,20 +599,22 @@ msgid "I am sure I want to delete this" msgstr "Je suis sûr de vouloir supprimer cela" #: mediagoblin/user_pages/views.py:155 -msgid "Empty comments are not allowed." -msgstr "Les commentaires vides ne sont pas autorisés." +msgid "Oops, your comment was empty." +msgstr "" #: mediagoblin/user_pages/views.py:161 -msgid "Comment posted!" -msgstr "Votre commentaire a été posté !" +msgid "Your comment has been posted!" +msgstr "" #: mediagoblin/user_pages/views.py:183 msgid "You deleted the media." -msgstr "" +msgstr "Vous avez supprimé le media." #: mediagoblin/user_pages/views.py:190 msgid "The media was not deleted because you didn't check that you were sure." msgstr "" +"Ce media n'a pas été supprimé car vous n'avez pas confirmer que vous étiez " +"sur." #: mediagoblin/user_pages/views.py:198 msgid "You are about to delete another user's media. Proceed with caution." diff --git a/mediagoblin/i18n/ia/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/ia/LC_MESSAGES/mediagoblin.mo index feb156ff5f75ce473a53880a7e26328a15d99f8e..55802ee2a5df92612502e4988b9f870a196212d3 100644 GIT binary patch literal 11150 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 GtbYL1;x`8X literal 10530 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 diff --git a/mediagoblin/i18n/ia/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/ia/LC_MESSAGES/mediagoblin.po index a4f1f8d7..7dd3a4f1 100644 --- a/mediagoblin/i18n/ia/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/ia/LC_MESSAGES/mediagoblin.po @@ -8,8 +8,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-11-27 15:25-0600\n" -"PO-Revision-Date: 2011-11-27 21:28+0000\n" +"POT-Creation-Date: 2011-12-03 16:57-0600\n" +"PO-Revision-Date: 2011-12-03 22:56+0000\n" "Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -96,7 +96,7 @@ msgid "Tags" msgstr "" #: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 -msgid "Seperate tags by commas or spaces." +msgid "Seperate tags by commas." msgstr "" #: mediagoblin/edit/forms.py:33 @@ -256,6 +256,11 @@ msgstr "" msgid "Enter your new password" msgstr "" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:33 +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Submit" +msgstr "" + #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" msgstr "" @@ -356,10 +361,6 @@ msgstr "" msgid "Submit yer media" msgstr "" -#: mediagoblin/templates/mediagoblin/submit/start.html:30 -msgid "Submit" -msgstr "" - #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format msgid "%(username)s's media" @@ -370,6 +371,35 @@ msgstr "" msgid "%(username)s's media" msgstr "" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#, python-format +msgid "By %(username)s on %(date)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +msgid "Post a comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +msgid "at" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +msgid "Post comment!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +msgid "Edit" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +msgid "Delete" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 +msgid "Sorry, no such media found." +msgstr "" + #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -493,6 +523,10 @@ msgstr "" msgid "Older" msgstr "" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:50 +msgid "Go to page:" +msgstr "" + #: mediagoblin/templates/mediagoblin/utils/tags.html:20 msgid "Tagged with" msgstr "" @@ -510,11 +544,11 @@ msgid "I am sure I want to delete this" msgstr "" #: mediagoblin/user_pages/views.py:155 -msgid "Empty comments are not allowed." +msgid "Oops, your comment was empty." msgstr "" #: mediagoblin/user_pages/views.py:161 -msgid "Comment posted!" +msgid "Your comment has been posted!" msgstr "" #: mediagoblin/user_pages/views.py:183 diff --git a/mediagoblin/i18n/it/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/it/LC_MESSAGES/mediagoblin.mo index cc0ccbfaef6e730fa8e822b22b9acc626d9c5718..77bfbee9e6ccdac4c0dd271a3cb07c3aaedec425 100644 GIT binary patch delta 4301 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 diff --git a/mediagoblin/i18n/it/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/it/LC_MESSAGES/mediagoblin.po index 25700f8f..dc9ec274 100644 --- a/mediagoblin/i18n/it/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/it/LC_MESSAGES/mediagoblin.po @@ -8,8 +8,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-11-27 15:25-0600\n" -"PO-Revision-Date: 2011-11-27 21:28+0000\n" +"POT-Creation-Date: 2011-12-03 16:57-0600\n" +"PO-Revision-Date: 2011-12-03 22:56+0000\n" "Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -98,7 +98,7 @@ msgid "Tags" msgstr "Tags" #: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 -msgid "Seperate tags by commas or spaces." +msgid "Seperate tags by commas." msgstr "" #: mediagoblin/edit/forms.py:33 @@ -264,6 +264,11 @@ msgstr "Documenti multimediali più recenti" msgid "Enter your new password" msgstr "Inserisci la tua nuova password" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:33 +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Submit" +msgstr "Conferma" + #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" msgstr "" @@ -369,10 +374,6 @@ msgstr "" msgid "Submit yer media" msgstr "Inoltra documento multimediale" -#: mediagoblin/templates/mediagoblin/submit/start.html:30 -msgid "Submit" -msgstr "Conferma" - #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format msgid "%(username)s's media" @@ -383,6 +384,35 @@ msgstr "" msgid "%(username)s's media" msgstr "Documenti multimediali di %(username)s" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#, python-format +msgid "By %(username)s on %(date)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +msgid "Post a comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +msgid "at" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +msgid "Post comment!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +msgid "Edit" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +msgid "Delete" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 +msgid "Sorry, no such media found." +msgstr "" + #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -513,6 +543,10 @@ msgstr "Più nuovo" msgid "Older" msgstr "Più vecchio" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:50 +msgid "Go to page:" +msgstr "" + #: mediagoblin/templates/mediagoblin/utils/tags.html:20 msgid "Tagged with" msgstr "" @@ -530,11 +564,11 @@ msgid "I am sure I want to delete this" msgstr "Sono sicuro di volerlo cancellare" #: mediagoblin/user_pages/views.py:155 -msgid "Empty comments are not allowed." +msgid "Oops, your comment was empty." msgstr "" #: mediagoblin/user_pages/views.py:161 -msgid "Comment posted!" +msgid "Your comment has been posted!" msgstr "" #: mediagoblin/user_pages/views.py:183 diff --git a/mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.mo index 5267eddc326e7a290cbda88ce645b5dcc88c5f81..e2a241a8fb244e61c266aea04de80fc49f2c0a9a 100644 GIT binary patch delta 4229 zcmd7S3v5+)9l-H_w*h_7LJRZ(ef)1rpR|Pn1z`wA28B98fzFCCu+w`_+atHgUnmtXJwotUE3On&|V3-KkqfUn_v zJe#Rh7H06Z1aq(*KZvdPF!E8)^CexML3!>hPF89}Wo9e2o`z{ipK2>kM+;jpfik%# zkrz}&j#33!gYw)ml=k*?`z9>rcMNCaZY;;g@D4nRQ}F~AF~0hF`hh=SE;rBN{r$$j7Z2!rztf&nx%*S_;QPgxACt(@N=2W4yFHg6(rQLvKv~NN7OYKa%3uP%| z$ZXW(C?R+n`|!Kd2@qqc3PzQn&PVR4bto~~iZVeTWnhDR)FHm)`6DPXdjY%fS14Ig z$NCy^8_vPcp={Pu*n&Sn+0?%kutC!CKWLDFGYOOgy#%G>YFvvAD4Vqt+i?%d059WG z%pixGaT#jt!%p0T^YI)?B=ZP|k27%A0dlUy~MQ^KZO_YNtBg6MBL@Q)3^kGjhir+l}3G(z2p_CLc0+v>B`F7xpsCNIOza7i1w4!L+)KQ!cOH_5DuS~2t;m?_ zZj_{sBL_q6MtScMlw>@JBl5x%=^Mw>H%_HJjYLZ=P0Oef&5H-Gm zGGJbPc&?);3ot0>`Vg+dnGNCAbf)b^N$y>EJANA_Lf;wTLeBM1aW%e-4i=LkveHp( z!#|>IRdZu_uGgSs@qNfG^&HApy^03kMLE{{n!;oKJj%d-$J_7{W?|$VE~aoXMV47z zH|X05*XpGV}AdCAE3Fq;`h(TwPrkvjWCct1UNb$IYp% zd(6D-lG+}}jcLnG>K-R~&Rld2Vf> z`>Y|Go^749gH?Kcz-nyEPe#<5m=la~}fbrsFyN2cDJ z5gE4QQLo>YJE^s8kVv$7-El^ibwUwv`iaW8?^vwO!w&k*t!0O!|M$o)6 ztu{+{SiV2(C1U2S%E$`F34f`L@tB=Z8@&NPlKO7cNpCQr8MWUgsKXW$?jHz}&1z%9 z>2+KyZstv|ob40u%MYmzkDuu`BBp)%j=Y2yMv6t+v50BTFU^a3Lw4fIxTY~Ql_>vFw7$LzSx6m_>9wa7VH zypB0B*}7<-9o<3L$t!6cwiCAY2NQPlc-D-sWQ=$+l`vS|up4&Us0ZR!)V>@Gzft?L z|EY-fSVIJscrbU?-R~vrRIGK>a&_G6m1L5chEHF;(dh(lR-MTKTRTL)*K*A9nJe?{ zgwvA@Ur0qKVlK{ne_mI@b9=8udc0-Uq>K%h*BM-nK(pG)qWTBfxo%s=mq_fFI?D8hCvrdmg2dR}_vr!Ql=e>ODBcHl$+tmZ) z45^X2YjzgQFx`b4=5fw!Cgk%5QS9*&j1bqoseErr*l|)LeR`YCGlh$b38bi!NnesVs+z7hP8@ zZnCm`@#?B_DP2)Yuc;^#qhFsG`|`xt_{8Ydxn#@Sq;<-0a zTGYPsIp)Q((NuXkUfytZc^O|<@z@QN7PBBPGF}l`ab0=otlVtQOe^@`mY9;Nj{m;I zMCWd9*mC1F=DE31^Ll=9*){2VCB?%!(`Z%^V$I3_hbpw#{IzaI!H5676dfuqGNtvc*OepF oGHcEF{`$g;jI-kQo}&NUpk*@9H^p9+%t7wdfHMgRZ+ delta 3805 zcmciCZE#f883*vQBLxx?NCG4w=H+Y%8xlABMgSXxm;t2_38sa~Fly_~?%C`mckkWa zdw0X)w9D@L5@u8ek5J;sAgIy7(mGx3IFe3U`=RYvt9ClIU#gB*2d1@UtTVR5wA%l3 zH@F47i?*G9$ywA*i|N7kfyRZ@MAHybCwFG~#6E?tJ*oyhtZFs0g z!#G?8v#%jbwLR}9Na1c^0Uw~ArAO@ond<{|wMj@hR1xTqLsYSs?@bD-aDD)2@6?YY)3d7zx zP_|{qP*5jQ;{T`~=dXH6VS=#oFLj7=biF25y2sfZO4pAXOxSa()vI!U#N@ z!vl6E`y-@*F2HFIW0zqk-cRGd=$!ltQXtQwo<_(g`WEZ$s*kg%tT=co3d}v=l8ZjA0Dc0V(jC z=llkw{&Bbt<{uK^;+I{<2SwbBLqg}| zMtsnOcR6`U2C396M>(Jvq=^ne3g}r#d*DS#Yds62umMM554;E74c~xtn!>*F(nTSS zyC3H0p*Z)&<1mExCm~hhcaSRa38Z6GhuJs5yWmDR1?d>Q2|1+t(!^d!rzis{&}rBY zOOPt~F{I79u#4?;Z|}`r<+U4tTk*v(RN*m58GQz~!)SMTQ#}VI-rs={Xx&h*#56=K z?0G2PT-08j5K2s#-?Gx9N!5O2vA>$fO(D1vjT&j)mj7z<{dX4`y1tm}w0Kg)RD})j zl%_-lj~gaW2_vNmZW}ymXqqx=n2L>o^cc4i#soLwac-FEn5rw9+lpz`jEM25DHK~Z zbj!;IVzJK$R+FkeMuR1laSWOee8Mob7+3hH7_x1F`P`Z9glVM55PdRkPhR!~t9AmO83xs+|pRzIIny zvsKE>O_|%-l(6OxMnO`1mJzon6jS)Qsz08n*N0to8nI*}wWXjIc+|<$H zn2hU&&5@rmAz}e`i%x~f8fla3VuGg>%R<#+^V`#wFm)v*e{|s zy2mL31Qh6E_>%9UZL-}M)l|KtS3T@$Ef-NUGQ#xE|CXy(AP|s8z24H6r5inRa@mOd za9OA1H7$#U$#xql%PX@r?ee9XL<_Pt5%FmD^G&Cz*d)lC)=U1ZrfqXDrHlzHNC^cJ zc2aBKvd>8KsG{?P&{D{et4Rc%p{=D_|5-aPWz!`CwaxO5+FRwXYi*gS>ySUL>kk^H ziA`iD6uVqEuEb)duq>WHi4+Z+IF`lU6gs!DV|Dqry6y^#?ZL)~tD4-rqM-{@A}Fuh zmJ((h1)Fz#+*Na{<1M9@Kkbo+SMHD>tlU%z)-UkL`x+YMg$6}t8w1U8f!x)op)(Xw zjc3aX?k=WR&Nfa)!abodkF4tp_x6O=heDON@9z1!$fy<$S;O7lV3dRS9cwp%+1T<+Fb%y?tpDrl`rEGxKUO&zjBQ(0;h1!DL&~GOHSdu zQ+)2qjo|UhrImZXa23Q`I&c-7!!_WO$6I^lUt3RJv#a2AoBvC{3Zz~YC@tjs|KD{` zI_ka4BR#7JJDtL;Q+WRU^Cz7AQ73=QDLm-pPdSAWRj_!!`+4uBnaBS3%J|3X+pp1; z(IgkH8J2}Lqw z|3UGHlYhp^|Io>wb@KN*g-IuWzuPi(X(oRacguU7vvjxg%RSx8<-zVj8LZz{YP_M| zBM_&?ii26SNk2R6fuC4Q;x? ATmS$7 diff --git a/mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.po index f2989e0e..5dcf7377 100644 --- a/mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.po @@ -8,8 +8,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-11-27 15:25-0600\n" -"PO-Revision-Date: 2011-11-27 21:28+0000\n" +"POT-Creation-Date: 2011-12-03 16:57-0600\n" +"PO-Revision-Date: 2011-12-03 22:56+0000\n" "Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -96,7 +96,7 @@ msgid "Tags" msgstr "タグ" #: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 -msgid "Seperate tags by commas or spaces." +msgid "Seperate tags by commas." msgstr "" #: mediagoblin/edit/forms.py:33 @@ -256,6 +256,11 @@ msgstr "" msgid "Enter your new password" msgstr "" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:33 +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Submit" +msgstr "送信" + #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" msgstr "" @@ -361,10 +366,6 @@ msgstr "" msgid "Submit yer media" msgstr "コンテンツを投稿" -#: mediagoblin/templates/mediagoblin/submit/start.html:30 -msgid "Submit" -msgstr "送信" - #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format msgid "%(username)s's media" @@ -375,6 +376,35 @@ msgstr "" msgid "%(username)s's media" msgstr "%(username)sさんのコンテンツ" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#, python-format +msgid "By %(username)s on %(date)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +msgid "Post a comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +msgid "at" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +msgid "Post comment!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +msgid "Edit" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +msgid "Delete" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 +msgid "Sorry, no such media found." +msgstr "" + #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -498,6 +528,10 @@ msgstr "" msgid "Older" msgstr "" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:50 +msgid "Go to page:" +msgstr "" + #: mediagoblin/templates/mediagoblin/utils/tags.html:20 msgid "Tagged with" msgstr "" @@ -515,11 +549,11 @@ msgid "I am sure I want to delete this" msgstr "" #: mediagoblin/user_pages/views.py:155 -msgid "Empty comments are not allowed." +msgid "Oops, your comment was empty." msgstr "" #: mediagoblin/user_pages/views.py:161 -msgid "Comment posted!" +msgid "Your comment has been posted!" msgstr "" #: mediagoblin/user_pages/views.py:183 diff --git a/mediagoblin/i18n/nl/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/nl/LC_MESSAGES/mediagoblin.mo index e6d1976b50c6e22408bf3a5a008974fba3a54eb6..d7ba8ef6c2d1b6e9ba18a0af4b68244c134c29d5 100644 GIT binary patch literal 11306 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\n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -98,7 +98,7 @@ msgid "Tags" msgstr "Etiket" #: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 -msgid "Seperate tags by commas or spaces." +msgid "Seperate tags by commas." msgstr "" #: mediagoblin/edit/forms.py:33 @@ -261,6 +261,11 @@ msgstr "" msgid "Enter your new password" msgstr "" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:33 +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Submit" +msgstr "Voeg toe" + #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" msgstr "" @@ -363,10 +368,6 @@ msgstr "" msgid "Submit yer media" msgstr "Voeg media toe" -#: mediagoblin/templates/mediagoblin/submit/start.html:30 -msgid "Submit" -msgstr "Voeg toe" - #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format msgid "%(username)s's media" @@ -377,6 +378,35 @@ msgstr "" msgid "%(username)s's media" msgstr "Media van %(username)s " +#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#, python-format +msgid "By %(username)s on %(date)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +msgid "Post a comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +msgid "at" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +msgid "Post comment!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +msgid "Edit" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +msgid "Delete" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 +msgid "Sorry, no such media found." +msgstr "" + #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -504,6 +534,10 @@ msgstr "" msgid "Older" msgstr "" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:50 +msgid "Go to page:" +msgstr "" + #: mediagoblin/templates/mediagoblin/utils/tags.html:20 msgid "Tagged with" msgstr "" @@ -521,11 +555,11 @@ msgid "I am sure I want to delete this" msgstr "" #: mediagoblin/user_pages/views.py:155 -msgid "Empty comments are not allowed." +msgid "Oops, your comment was empty." msgstr "" #: mediagoblin/user_pages/views.py:161 -msgid "Comment posted!" +msgid "Your comment has been posted!" msgstr "" #: mediagoblin/user_pages/views.py:183 diff --git a/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.mo index ba427c291aaebb46cc2323e8daa519590a316c2c..a75d86a72b3bec677f537285bc91700c2029f5c8 100644 GIT binary patch delta 4349 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 X$_-pRv`(w*=!%lXtB(Z0^VNR=;_uE1 diff --git a/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.po index 21cfdda5..10fad192 100644 --- a/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.po @@ -8,8 +8,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-11-27 15:25-0600\n" -"PO-Revision-Date: 2011-11-27 21:28+0000\n" +"POT-Creation-Date: 2011-12-03 16:57-0600\n" +"PO-Revision-Date: 2011-12-03 22:56+0000\n" "Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -99,7 +99,7 @@ msgid "Tags" msgstr "Merkelappar" #: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 -msgid "Seperate tags by commas or spaces." +msgid "Seperate tags by commas." msgstr "" #: mediagoblin/edit/forms.py:33 @@ -263,6 +263,11 @@ msgstr "Nyaste mediefiler" msgid "Enter your new password" msgstr "Fyll inn passord" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:33 +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Submit" +msgstr "Send" + #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" msgstr "" @@ -377,10 +382,6 @@ msgstr "" msgid "Submit yer media" msgstr "Last opp" -#: mediagoblin/templates/mediagoblin/submit/start.html:30 -msgid "Submit" -msgstr "Send" - #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format msgid "%(username)s's media" @@ -391,6 +392,35 @@ msgstr "" msgid "%(username)s's media" msgstr "%(username)s sine mediefiler" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#, python-format +msgid "By %(username)s on %(date)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +msgid "Post a comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +msgid "at" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +msgid "Post comment!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +msgid "Edit" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +msgid "Delete" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 +msgid "Sorry, no such media found." +msgstr "" + #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -516,6 +546,10 @@ msgstr "Nyare" msgid "Older" msgstr "Eldre" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:50 +msgid "Go to page:" +msgstr "" + #: mediagoblin/templates/mediagoblin/utils/tags.html:20 msgid "Tagged with" msgstr "" @@ -533,12 +567,12 @@ msgid "I am sure I want to delete this" msgstr "Eg er sikker eg vil sletta dette" #: mediagoblin/user_pages/views.py:155 -msgid "Empty comments are not allowed." -msgstr "Du må skriva noko i innspelet." +msgid "Oops, your comment was empty." +msgstr "" #: mediagoblin/user_pages/views.py:161 -msgid "Comment posted!" -msgstr "Innspel lagt til." +msgid "Your comment has been posted!" +msgstr "" #: mediagoblin/user_pages/views.py:183 msgid "You deleted the media." diff --git a/mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.mo index 31cb860cd750b944203723b467ba2fb43fbc860b..e78b8e3b001bb9fc065b7729c43ab0da1a0487e9 100644 GIT binary patch delta 4382 zcmc)LeQZ@{9l-JD^3s-;z5<1o0?+L`rEiqcNoC+DZw1SXEtzZ+a(eI6_Ke$e+H=lr zSClm{gTpCCkD6`SA4a#}vS6ZB+zck0xDB%{8OBA48=DD^pg5Imf9RIQ@9*AQ9L-cT zBsQ1(Irll|JkRg>Jl=!{gZ!)D-<6s2>z{w8vz409&!1u`{t_?Y zWo*H7IZDmJ2w&}(hud%iuEsATA9aQ=>H1}q=gwi4QWGjCSE()<3Xwk5UMxZjSE7d! z++)ZKYFVCAC0L8{+!~bjZJGAnxQO3zEXPB*6d%G__+y-lr*R?Ut6yXu_#NhRL++MA z0WQRPl)yfL(!o|-fZfO|Du#{d;vsw#e~smIwgRu>GF)1q)Htrg7(RtjNqI$~QuE{n zR^q2nW|$10h*V9;t1r_cbNv$*;|Itns))wfxCCW!s!-ZHGVNP3cH?{(4I)@rBqU?&<;|tDKBIzZp7PB0y~QIJE5LUU#J(c zog1&BWMnR3?!*NsOJY#=$_Pq_hw-a8iIUn)oI)9JJ4&YRMp@$nC>imP*wis3x#}@o zDhKo@T*z9VN7DCg&6C>`8|sojo}nS;o7P)AS#{w7K$zK!?d zZ}7LcTc?+zDauBjpkXf;U&JGL6!RH{XVuqHX7odBz~@i``3uU-W>%#G$wg_`NEd1q z%KLjz-cOmyj~3&ZA`HB9dKo8D*x~)#+3hp=78OCDkn` znOlc0eiCJ=P9v+SUP1}vGD={7$2u&pA^&n?LrwZz_n>raP*Qpy?!ludseBDvu%tG9 zt~X%noZ~IDKZsfQ3`#&Rp!EML%96Z=GV`mr8Q-rZ{}NFr;q1m3uEif=Ctk%>*j}#` zL92UE0{RNJ;_opVOP8n5^-`4j@HLcyUq@M*w^81Yu#WP4ElPmR6I@6N*Wzus9p!i& z!}a)c+<~(=yt0dXQ10J@68PiDM?J@vEY)8zfrX?+0{k4x{gXHo&*Kby9rG~yCKnRX z6;w6#N#A&mHDs3ib-o@laoY+X&8p1rO9p}K?6+cp?K)vaS#|j5tejFuTd|m%bOLP! zIvBKl?c0F~XJyw;d*N_dTWDwBl@pI=`usx9*%{+H472OzY1h#;^>Hg;Ox0;QF_Q?N zpR*@iky}>RZ#!{qIpezDP8e1+B~P!35=)5-K3`-Gp2_v-yd_mc=%pkb>0?N2QEzm zrepH+bB{-&V+2Zyk2tuYCoop@mbYyOqGioL5cq-EHaN)juCKXr% z`_st`-zco>*Sj(UsU2p_cxs26&IZ$I8ur|n@qODFP&*UxYaz)Gp4{mU`_a^QV>)ai z8ZzX4%wlds!@+p7+UeN?wqqs26-AZhK1-rA52;-)KQlj~;kKd!1)iHuDETn)XxLm_ zQ4n)S$;q`;Y$@(qZb-iE_<@&9ExWIJ%&_rTD9yxt-8Y`<)bg9d3;T0JX~0^D}1=5u6Mx1^_U$Ds$P0jy@Mu`5t*0c z20CsMh7fh1iCJt-nY@nMaarZqpotw|N!WVQN7Qq?6^2Iq7a2 z^>D(9nWMF4`qAt0YO$YQ_iF+xHQq|QQ zpD4X$5s6e*p!$u(9&;Tfd32LO__xvr^4pqPSLv1Q9jk9`YHbgXFI=3PYH4fhSlvE3 zxv(QL|0Ao>l|@z4ip&34jT*wY%i4=>kJ~XSisk8{Gbg3my!#JeMD1&liQfN10nBVq*_vTbeQ)9P>i3=c zwbQHLh59*>-BRjqZUua6d9;gOZ%z>mvl^V%RGIv53ZUQ6v^Y}$&zz+AQ81~4QzcOS E1IE=9BLDyZ delta 3916 zcmajge{7vq8Nl(=Fk~x?t{r0=YqxW|u0KY5Z(BOi!YH*HgN3k@#AMC4@`*8zGz$y0Qop=X6g}=r@ChNte=ku&QFvLX_ z_hBAi!wlvaMJC*booMXCO&e!rtv~0ELLZVh*Kw0Vott4!ci-))&p}&ig+_gkCgd_77Q8wo&$^hR+ z=1@_i#g$4l`Wn8jbNWWzKUO&2J2J$7Oa52LL3IF8{7 zloh{+8vlW^X{%X2bEyqDfx{>hRPZu<5_jM`C>a?hoj2ny9LC3Ixu7!D?@2 z>Ypepc#luLjc1d`E%;}g#4ge#8Tc%Qcppl}{*Bu(w~ms=1ZDj1&-)x2Ue{0-G}}il z%Ed75#mkUNR9`{LKz)7QrxKZ}x?YdRVM>_rMp-HODlLL>%t7qVz|4COdHi;{t# zpwz-CWWlrQKU_#TwytlyF@o~J>#+-GkYDux|0K{SQBwabvW@CRybfPS3Al&RB~zE; z5%lr5_$Tbcmv!U3yo>k9fn7z#+{GJ@AkU~CqLI|@z|D97rTD&x64*T`TlEO?5jBUD zgZdT9=iWgH>|ZFUZ`n9s)JXGCBPc~XhG#Rs+Qx;XW+%#C=J8ATI+AU5BWaMpj$jWS zMVaWwD495k`|&rJ!yHFJs{Ixm!F%x%dOgHleI+7s|vw z?!)`=a(n|Pu$^dR;9HTo)k7$OJconW(%T5|N|a-GHOhPz<@xXRs)O|v{FECK(MjBj zZ=h6f2OBnq2XGG_MG5FF^za<^=VDAyiuMtdt#|_M$#XiFmyA;|(JgU0<-5s)OZ%7W zVq}bV^7$|g68p(@-5-9$dh2eoCzlS*>ayqLjV^|fE}O9I8J&bWA9|iM6-G|N5J5r5 zrSPy0i$xtq?z9^?Ui~f;x)oE<`N%kl8wPPkjTZ{qHwD*G%QBs``*|7zUX>T{O&J ze==j6m%Tchx?WOWhB=a$AaXGTBS~l_G!6ZnDFAj^zVJ9;E z+70qvT9EiFZoz~)PRr#mN-}+F!U^)mQxhd8m^Ru?GF+PcAzif>Ht$~U`$VhDVVsyk z#@^c8Zl7%aj-5Pr+&+J~}7#hQt95GIwqIxvTI*@V*{(Wfs4y-8h@g&UKuBpvm6dGHKs!>9Kl6$5Ioiy`N;)Y|WLOX%pvUh1pW#d!1Jt3{#zV0$nm* znMG^YC*X?InH!(p$c(I{&t_ZO?TxKh*`Kv0w$j#Rf6z9T3!{jNN=i=BNThZOg~-IQ zE|D|GqoNB{3e^NUp?m}Te%t0{vAUirDY~BBdco>GrX;9L{a)EbMUu7XEY-KMo|(*C zdF7)`_RFiTv4323*<9|zB~A9u)obiqs~uZilWi{=*6!xRK#@SVSZ!25eRnhV#Wi;i z4-E_s>ETO8heielw+s$8e|qo0XH3P7IdKEqIH99@cyMTFfZxGkJvcHtbje(G?P!yI z^`eiog|2Zu5xGXEzC$4fiKC~Z+OdR`Nv4|h=^wI7h2%YIkP=zkTWB1^qZ46Jbf;4) zDK;skQkyGBF2}?~oEK_yQH}i1!1k4Om(K3@wU5=EVkSkHre`r5)ZYvCH z!ahCUh@41`dz?=*;HVpCbIrgcJ=WMk8YI|z^9kbj2 zPgmMT!)Io8fNoWB8Y8HMyX<}t(vJu~jnmpOsRC-J(VNBtj>tk1X80O%qJdZz5!B}5 zFr=nDnIsnWIhitc};Ltd|PkQc<2Nsz)(ula1Z>_{L2wyB%t* zA~jO)S+=E1+iSbZJ=+YKtc0GFJN;h1I~OXLMO4Ck?eT@?HU81&b%VUm$H1Ny3J!o(4o*E*8eCm~@6y*aZ;2fCR@p_Th)30a9 zgozXR@3TAhh3>w6+Y|S;)Fe)<_VNXETPmj_kP7D{^8G6(xZWJ>N9OL JjYfl0{{`;&#&`e# diff --git a/mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.po index c4f77f8a..0512f43d 100644 --- a/mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.po @@ -9,8 +9,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-11-27 15:25-0600\n" -"PO-Revision-Date: 2011-11-27 21:28+0000\n" +"POT-Creation-Date: 2011-12-03 16:57-0600\n" +"PO-Revision-Date: 2011-12-03 22:56+0000\n" "Last-Translator: cwebber \n" "Language-Team: Portuguese (Brazilian) (http://www.transifex.net/projects/p/mediagoblin/team/pt_BR/)\n" "MIME-Version: 1.0\n" @@ -102,7 +102,7 @@ msgid "Tags" msgstr "Etiquetas" #: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 -msgid "Seperate tags by commas or spaces." +msgid "Seperate tags by commas." msgstr "" #: mediagoblin/edit/forms.py:33 @@ -267,6 +267,11 @@ msgstr "Mídia mais recente" msgid "Enter your new password" msgstr "Digite sua nova senha" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:33 +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Submit" +msgstr "Enviar" + #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" msgstr "" @@ -382,10 +387,6 @@ msgstr "" msgid "Submit yer media" msgstr "Envie sua mídia" -#: mediagoblin/templates/mediagoblin/submit/start.html:30 -msgid "Submit" -msgstr "Enviar" - #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format msgid "%(username)s's media" @@ -396,6 +397,35 @@ msgstr "" msgid "%(username)s's media" msgstr "Mídia de %(username)s " +#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#, python-format +msgid "By %(username)s on %(date)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +msgid "Post a comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +msgid "at" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +msgid "Post comment!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +msgid "Edit" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +msgid "Delete" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 +msgid "Sorry, no such media found." +msgstr "" + #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -526,6 +556,10 @@ msgstr "Mais novo" msgid "Older" msgstr "Mais velho" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:50 +msgid "Go to page:" +msgstr "" + #: mediagoblin/templates/mediagoblin/utils/tags.html:20 msgid "Tagged with" msgstr "" @@ -543,11 +577,11 @@ msgid "I am sure I want to delete this" msgstr "Eu tenho certeza de que quero pagar isso" #: mediagoblin/user_pages/views.py:155 -msgid "Empty comments are not allowed." +msgid "Oops, your comment was empty." msgstr "" #: mediagoblin/user_pages/views.py:161 -msgid "Comment posted!" +msgid "Your comment has been posted!" msgstr "" #: mediagoblin/user_pages/views.py:183 diff --git a/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.mo index 2ab9cf8b6ab09d244718b9c17c0cfccdc88f9e22..c2044ccbb115fd60d7423191b672c46b414a452f 100644 GIT binary patch delta 4583 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 D\n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -57,14 +57,14 @@ msgstr "Ne pare rău, există deja un utilizator cu același nume." #: mediagoblin/auth/views.py:77 msgid "Sorry, a user with that email address already exists." -msgstr "" +msgstr "Există deja un utilizator înregistrat cu această adresă de e-mail." #: mediagoblin/auth/views.py:179 msgid "" "Your email address has been verified. You may now login, edit your profile, " "and submit images!" msgstr "" -"Adresa ta de e-mail a fost confirmată. Poți să te autentifici, să îți " +"Adresa ta de e-mail a fost verificată. Poți să te autentifici, să îți " "completezi profilul și să trimiți imagini!" #: mediagoblin/auth/views.py:185 @@ -73,11 +73,11 @@ msgstr "Cheie de verificare sau user ID incorect." #: mediagoblin/auth/views.py:203 msgid "You must be logged in so we know who to send the email to!" -msgstr "" +msgstr "Trebuie să fii autentificat ca să știm cui să trimitem mesajul!" #: mediagoblin/auth/views.py:211 msgid "You've already verified your email address!" -msgstr "" +msgstr "Adresa ta de e-mail a fost deja verificată!" #: mediagoblin/auth/views.py:224 msgid "Resent your verification email." @@ -89,7 +89,7 @@ msgid "" "account's email address has not been verified." msgstr "" "E-mailul pentru recuperarea parolei nu a putut fi trimis deoarece contul tău" -" e inactiv sau adresa ta de e-mail nu a fost confirmată." +" e inactiv sau adresa ta de e-mail nu a fost verificată." #: mediagoblin/edit/forms.py:24 mediagoblin/submit/forms.py:27 msgid "Title" @@ -97,10 +97,10 @@ msgstr "Titlu" #: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:32 msgid "Tags" -msgstr "Etichete" +msgstr "Tag-uri" #: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 -msgid "Seperate tags by commas or spaces." +msgid "Seperate tags by commas." msgstr "" #: mediagoblin/edit/forms.py:33 @@ -128,11 +128,11 @@ msgstr "Sit Web" #: mediagoblin/edit/forms.py:49 msgid "Old password" -msgstr "" +msgstr "Vechea parolă" #: mediagoblin/edit/forms.py:52 msgid "New Password" -msgstr "" +msgstr "Noua parolă" #: mediagoblin/edit/views.py:65 msgid "An entry with that slug already exists for this user." @@ -149,15 +149,15 @@ msgstr "Editezi profilul unui utilizator. Se recomandă prudență." #: mediagoblin/edit/views.py:171 msgid "Wrong password" -msgstr "" +msgstr "Parolă incorectă" #: mediagoblin/edit/views.py:192 msgid "Profile edited!" -msgstr "" +msgstr "Profilul a fost modificat!" #: mediagoblin/media_types/__init__.py:61 msgid "Could not find any file extension in \"{filename}\"" -msgstr "" +msgstr "Nu pot extrage extensia din „{filename}”" #: mediagoblin/submit/forms.py:25 msgid "File" @@ -173,19 +173,19 @@ msgstr "Trebuie să selectezi un fișier." #: mediagoblin/submit/views.py:127 msgid "Woohoo! Submitted!" -msgstr "Gata, trimis!" +msgstr "Ura! Trimis!" #: mediagoblin/submit/views.py:133 msgid "Invalid file type." -msgstr "" +msgstr "Tip de fișier incompatibil." #: mediagoblin/templates/mediagoblin/404.html:21 msgid "Oops!" -msgstr "Oops!" +msgstr "Hopa!" #: mediagoblin/templates/mediagoblin/404.html:24 msgid "There doesn't seem to be a page at this address. Sorry!" -msgstr "Ne pare rău, nu există nicio pagină la această adresă." +msgstr "Nu există nicio pagină la această adresă. Ne pare rău!" #: mediagoblin/templates/mediagoblin/404.html:26 msgid "" @@ -209,11 +209,11 @@ msgstr "Transmite un fișier media" #: mediagoblin/templates/mediagoblin/base.html:65 msgid "Verify your email!" -msgstr "" +msgstr "Verifică adresa de e-mail!" #: mediagoblin/templates/mediagoblin/base.html:72 msgid "log out" -msgstr "" +msgstr "ieșire" #: mediagoblin/templates/mediagoblin/base.html:75 #: mediagoblin/templates/mediagoblin/auth/login.html:27 @@ -235,21 +235,23 @@ msgstr "Explorează" #: mediagoblin/templates/mediagoblin/root.html:27 msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "" +msgstr "Salut, bine ai venit pe acest site MediaGoblin!" #: mediagoblin/templates/mediagoblin/root.html:28 msgid "Your finest source for all goblin-related media." -msgstr "" +msgstr "Locul unde elfii își transmit fișierele media." #: mediagoblin/templates/mediagoblin/root.html:29 msgid "" "To add your own media, place comments, save your favourites and more, you " "can log in with your MediaGoblin account." msgstr "" +"Ca să adăugi propriile tale fișiere, să scrii comentarii, să salvezi " +"favoritele tale și multe altele, autentifică-te cu contul tău MediaGoblin." #: mediagoblin/templates/mediagoblin/root.html:31 msgid "Don't have one yet? It's easy!" -msgstr "" +msgstr "Încă nu ai unul? E simplu!" #: mediagoblin/templates/mediagoblin/root.html:32 #, python-format @@ -258,6 +260,9 @@ msgid "" " or\n" " Set up MediaGoblin on your own server" msgstr "" +"Creează un cont pe acest site\n" +" sau\n" +" Instalează MediaGoblin pe propriul tău server" #: mediagoblin/templates/mediagoblin/root.html:44 msgid "Most recent media" @@ -267,13 +272,18 @@ msgstr "Cele mai recente fișiere" msgid "Enter your new password" msgstr "Introdu noua parolă" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:33 +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Submit" +msgstr "Trimite" + #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" -msgstr "" +msgstr "Recuperează parola" #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:30 msgid "Send instructions" -msgstr "" +msgstr "Trimite instrucțiuni" #: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 msgid "Your password has been changed. Try to log in now." @@ -371,30 +381,55 @@ msgstr "Editare profil %(username)s" #: mediagoblin/templates/mediagoblin/listings/tag.html:35 #, python-format msgid "Media tagged with: %(tag_name)s" -msgstr "" +msgstr "Fișier etichetat cu tag-urile: %(tag_name)s" #: mediagoblin/templates/mediagoblin/media_displays/video.html:19 msgid "Original" -msgstr "" +msgstr "Original" #: mediagoblin/templates/mediagoblin/submit/start.html:26 msgid "Submit yer media" msgstr "Trimite fișierele tale media" -#: mediagoblin/templates/mediagoblin/submit/start.html:30 -msgid "Submit" -msgstr "Trimite" - #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format msgid "%(username)s's media" -msgstr "" +msgstr "Fișierele lui %(username)s" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:37 #, python-format msgid "%(username)s's media" msgstr "Fișierele media ale lui %(username)s" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#, python-format +msgid "By %(username)s on %(date)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +msgid "Post a comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +msgid "at" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +msgid "Post comment!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +msgid "Edit" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +msgid "Delete" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 +msgid "Sorry, no such media found." +msgstr "" + #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -438,7 +473,7 @@ msgstr "Ne pare rău, nu am găsit utilizatorul căutat." #: mediagoblin/templates/mediagoblin/user_pages/user.html:50 #: mediagoblin/templates/mediagoblin/user_pages/user.html:70 msgid "Email verification needed" -msgstr "Este necesară confirmarea adresei de e-mail" +msgstr "Este necesară verificarea adresei de e-mail" #: mediagoblin/templates/mediagoblin/user_pages/user.html:53 msgid "Almost done! Your account still needs to be activated." @@ -524,13 +559,17 @@ msgstr "Mai noi" msgid "Older" msgstr "Mai vechi" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:50 +msgid "Go to page:" +msgstr "" + #: mediagoblin/templates/mediagoblin/utils/tags.html:20 msgid "Tagged with" -msgstr "" +msgstr "Tag-uri" #: mediagoblin/templates/mediagoblin/utils/tags.html:25 msgid "and" -msgstr "" +msgstr "și" #: mediagoblin/user_pages/forms.py:24 msgid "Comment" @@ -541,20 +580,20 @@ msgid "I am sure I want to delete this" msgstr "Sunt sigur că doresc să șterg" #: mediagoblin/user_pages/views.py:155 -msgid "Empty comments are not allowed." -msgstr "Comentariul trebuie să aibă un conținut." +msgid "Oops, your comment was empty." +msgstr "" #: mediagoblin/user_pages/views.py:161 -msgid "Comment posted!" -msgstr "Comentariul a fost transmis." +msgid "Your comment has been posted!" +msgstr "" #: mediagoblin/user_pages/views.py:183 msgid "You deleted the media." -msgstr "" +msgstr "Ai șters acest fișier" #: mediagoblin/user_pages/views.py:190 msgid "The media was not deleted because you didn't check that you were sure." -msgstr "" +msgstr "Fișierul nu a fost șters deoarece nu ai confirmat că ești sigur." #: mediagoblin/user_pages/views.py:198 msgid "You are about to delete another user's media. Proceed with caution." diff --git a/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.mo index 4b5481e070c77a113503c11ef4972e86a877f8a4..1976596794ad6bab665cadd747ebad6a558b0dd0 100644 GIT binary patch delta 5006 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 delta 4324 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 diff --git a/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.po index 9fb1ce08..cee135ca 100644 --- a/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.po @@ -8,8 +8,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-11-27 15:25-0600\n" -"PO-Revision-Date: 2011-11-27 21:28+0000\n" +"POT-Creation-Date: 2011-12-03 16:57-0600\n" +"PO-Revision-Date: 2011-12-03 22:56+0000\n" "Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -101,7 +101,7 @@ msgid "Tags" msgstr "Метки" #: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 -msgid "Seperate tags by commas or spaces." +msgid "Seperate tags by commas." msgstr "" #: mediagoblin/edit/forms.py:33 @@ -266,6 +266,11 @@ msgstr "Самые новые файлы" msgid "Enter your new password" msgstr "Введите свой новый пароль" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:33 +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Submit" +msgstr "Подтвердить" + #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" msgstr "" @@ -382,10 +387,6 @@ msgstr "" msgid "Submit yer media" msgstr "Загрузить файл(ы)" -#: mediagoblin/templates/mediagoblin/submit/start.html:30 -msgid "Submit" -msgstr "Подтвердить" - #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format msgid "%(username)s's media" @@ -396,6 +397,35 @@ msgstr "" msgid "%(username)s's media" msgstr "Файлы пользователя %(username)s" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#, python-format +msgid "By %(username)s on %(date)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +msgid "Post a comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +msgid "at" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +msgid "Post comment!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +msgid "Edit" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +msgid "Delete" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 +msgid "Sorry, no such media found." +msgstr "" + #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -525,6 +555,10 @@ msgstr "Более новые" msgid "Older" msgstr "Более старые" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:50 +msgid "Go to page:" +msgstr "" + #: mediagoblin/templates/mediagoblin/utils/tags.html:20 msgid "Tagged with" msgstr "" @@ -542,12 +576,12 @@ msgid "I am sure I want to delete this" msgstr "Я уверен, что хочу удалить это" #: mediagoblin/user_pages/views.py:155 -msgid "Empty comments are not allowed." -msgstr "Empty comments are not allowed." +msgid "Oops, your comment was empty." +msgstr "" #: mediagoblin/user_pages/views.py:161 -msgid "Comment posted!" -msgstr "Комментарий размещён!" +msgid "Your comment has been posted!" +msgstr "" #: mediagoblin/user_pages/views.py:183 msgid "You deleted the media." diff --git a/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.mo index 684c850afbc149abf4f6fc0d198b4729317ae50e..10699d0b39f87d1e1e9288dd7d4a8cd0dc5fcfc5 100644 GIT binary patch delta 4373 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\n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -100,7 +100,7 @@ msgid "Tags" msgstr "Štítky" #: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 -msgid "Seperate tags by commas or spaces." +msgid "Seperate tags by commas." msgstr "" #: mediagoblin/edit/forms.py:33 @@ -264,6 +264,11 @@ msgstr "Najčerstvejšie výtvory" msgid "Enter your new password" msgstr "Vlož svoje nové heslo" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:33 +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Submit" +msgstr "Vložiť" + #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" msgstr "" @@ -380,10 +385,6 @@ msgstr "" msgid "Submit yer media" msgstr "Vlož svoj výtvor" -#: mediagoblin/templates/mediagoblin/submit/start.html:30 -msgid "Submit" -msgstr "Vložiť" - #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format msgid "%(username)s's media" @@ -394,6 +395,35 @@ msgstr "" msgid "%(username)s's media" msgstr "Výtvory, ktoré vlastní %(username)s" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#, python-format +msgid "By %(username)s on %(date)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +msgid "Post a comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +msgid "at" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +msgid "Post comment!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +msgid "Edit" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +msgid "Delete" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 +msgid "Sorry, no such media found." +msgstr "" + #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -522,6 +552,10 @@ msgstr "Novšie" msgid "Older" msgstr "Staršie" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:50 +msgid "Go to page:" +msgstr "" + #: mediagoblin/templates/mediagoblin/utils/tags.html:20 msgid "Tagged with" msgstr "" @@ -539,12 +573,12 @@ msgid "I am sure I want to delete this" msgstr "Jednoznačne to chcem odstrániť" #: mediagoblin/user_pages/views.py:155 -msgid "Empty comments are not allowed." -msgstr "Komentáre bez obsahu nepovolené." +msgid "Oops, your comment was empty." +msgstr "" #: mediagoblin/user_pages/views.py:161 -msgid "Comment posted!" -msgstr "Komentár odoslaný!" +msgid "Your comment has been posted!" +msgstr "" #: mediagoblin/user_pages/views.py:183 msgid "You deleted the media." diff --git a/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.mo index 52e3d632115379f1b744e86a536b022d517b63e9..5d6a0fe2e1955b0ad0a44a5499386808421f793a 100644 GIT binary patch delta 4310 zcmd7UYitzP6~OVkgohv4*v8o4V0_ocPi$k;0L3Yf@HT|tVz-2*fsA*r?ZN9AGc#+~ zZqWu(sX+~V8ATXAyN_f5JjN=&+eK8 zQnjSwLoKtv**i1$an8NRJk@jI;nc;FsZT3@#`!m&e;?i>-#+^}GefCTzP^HG_zqsi zf8b&~m!niJM)+8U`M3qw;!-?}{HoXakgnfGdF~ueS1P4)@|5bNVHVP-+J!}EVLN&# zllwXHf~v|_ss!s$o?C&^z9rlKb)3uhI9A|(T!2S$DxSibcm~TEU;RG&zso8P^ zt8oX)3X|dUk(!je`Zg`H)+<hHREo)7k`M7tmm*DUqeaiwGt8}9e+xL44gxtBy zmt%xI+=?qu;{f*HAzX|XQ6gDLID9O{)%awJ3klg-WDe>aYJ4AMS4<=B(q4cPLXGQi zG0MO`-j6TfCcKRNs>RH<12>{X>Hx}aIfjy|H*hzm-shr?i*-D;1Ot?V^c+sX7m%~0 zUPPJDX?!oD)T_v%)X#`3U8qxd8UKhf@G0UhxxR`kQBMB@unJ|o$B`qKQoqbxs57{X z8*icvcmw6&<}h7}&<>OcJc5$Ly*Q4?Q6^T-DJ1=>3MG~8C^=q>62VSn&g$Dp)>IM~ z$N@dXh2;7K%3e5$^5Cy9ihoAw@MEmO>Fh{ZaTChGYf&b+1<9J~M%hC)O74>w;79uuhbeeG8>t4538o7|H}sq_~g}p2l_fCd%&4XVkCa zN|c$7pq%ShP>$Dml$FimP|LZl=R;D}js3U}+wiX_dnb?4@4=Ng1s}jXjIQTm1{d2= z)ixx3<2lxlY4q!TJ!Imx6&{~nUC^5h0@vAN#RA)P!ndY3mpR&s#oVM5Xe-dcfbDDF z4oo<8M%`@>FQ0KZCmzrC^@E(Vk+Jaa^BQJr*U_~NaVuabwa#*4CK0}o`;Bl>-n{xg z+lgz-8Pk1s!f5lIz&JkRYTMD(-<39*;r{AyMc&EqQr_m8^{!JN=mBfQ(5um7CRnXI z0~TN`e=Mpt#O)xg%Xh--m2<=E`PKQGTphT2*y=YO6W^bCBoZApiI_WNq&2;iZL;u9 zZf}ASWm(aQw!()aGdrCTD`Cge(+UsF+Fig30;_*dCSc*ES@nIo%kuqE*Ndx%%&76y zLvCi}%)MpUb7RK$ZKq#tPsABN`y^j@a=Sb1N7J9pddy9Fni≪yY@wkfGsVtW|CI z?0(y^65*nv>I$FGPd=o&T)t-Ch=yB=1`9nm6FnAh;?eMLH5ElWOw1iI-p!H2O~sv! zhFIH)D8wz4?U`$0h5i1tjuu(9XAQXBz3QeS!_UA zzK+{*Nos7s#0E(Un@m~>snLGYGp!T3v!9KmT$xHHT<)lo>9$!9C#;y6jE3K=ec2i5 znD$vCgqDafch)`RdL|uh9kU#raQkJ8$xJg(e|{TecYCYq85=g*CieZ79llt2(>?Q^C@woR@zn2bWJ+Qq_#lH{+~$Q&eEvhQ40 zs|Ou-RF4j%H>@wIlJ_!62;6AcURJrap2bZjg6!ITHXWo_drPvSGR|kaYJk}H8sq3; zb`BdPeK*`!GCS-o+qQ@kXqb@C8$`0t^%xJXH;cjMMxJ>r{Q+i}A`RGgi%HeG$nZmB+9o*7KozddY+)93fB>2d>4 z&W!Fie!^Aj+$3jJcIlm0rSFB;=C@OsTEeZBrFT@Fc2}m-)oJ5`x?8H#xdlItEZS^K z)@7&u*E$up6-Fn{>#j)g=WCS?*t21E^@COE9W4iY@v?0%{!?hcjK{s6!zgXAq`(FxMxV6#wvh}PYThBTNUB}WRwr5Qi GH1#h4^Z8W( delta 3859 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 A@Bjb+ diff --git a/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.po index 77273ebe..568a5f73 100644 --- a/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.po @@ -8,8 +8,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-11-27 15:25-0600\n" -"PO-Revision-Date: 2011-11-27 21:28+0000\n" +"POT-Creation-Date: 2011-12-03 16:57-0600\n" +"PO-Revision-Date: 2011-12-03 22:56+0000\n" "Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -98,7 +98,7 @@ msgid "Tags" msgstr "Oznake" #: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 -msgid "Seperate tags by commas or spaces." +msgid "Seperate tags by commas." msgstr "" #: mediagoblin/edit/forms.py:33 @@ -260,6 +260,11 @@ msgstr "" msgid "Enter your new password" msgstr "" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:33 +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Submit" +msgstr "Pošlji" + #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" msgstr "" @@ -366,10 +371,6 @@ msgstr "" msgid "Submit yer media" msgstr "Pošljite svojo vsebino" -#: mediagoblin/templates/mediagoblin/submit/start.html:30 -msgid "Submit" -msgstr "Pošlji" - #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format msgid "%(username)s's media" @@ -380,6 +381,35 @@ msgstr "" msgid "%(username)s's media" msgstr "Vsebina uporabnika %(username)s" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#, python-format +msgid "By %(username)s on %(date)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +msgid "Post a comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +msgid "at" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +msgid "Post comment!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +msgid "Edit" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +msgid "Delete" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 +msgid "Sorry, no such media found." +msgstr "" + #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -507,6 +537,10 @@ msgstr "" msgid "Older" msgstr "" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:50 +msgid "Go to page:" +msgstr "" + #: mediagoblin/templates/mediagoblin/utils/tags.html:20 msgid "Tagged with" msgstr "" @@ -524,11 +558,11 @@ msgid "I am sure I want to delete this" msgstr "" #: mediagoblin/user_pages/views.py:155 -msgid "Empty comments are not allowed." +msgid "Oops, your comment was empty." msgstr "" #: mediagoblin/user_pages/views.py:161 -msgid "Comment posted!" +msgid "Your comment has been posted!" msgstr "" #: mediagoblin/user_pages/views.py:183 diff --git a/mediagoblin/i18n/sr/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/sr/LC_MESSAGES/mediagoblin.mo index d2649938b20f6728a9c874a466ecbca909e98150..deb561048f3c58d4f92653ffdc207718568c5bee 100644 GIT binary patch literal 11247 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\n" "Language-Team: Serbian (http://www.transifex.net/projects/p/mediagoblin/team/sr/)\n" "MIME-Version: 1.0\n" @@ -95,7 +95,7 @@ msgid "Tags" msgstr "" #: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 -msgid "Seperate tags by commas or spaces." +msgid "Seperate tags by commas." msgstr "" #: mediagoblin/edit/forms.py:33 @@ -255,6 +255,11 @@ msgstr "" msgid "Enter your new password" msgstr "" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:33 +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Submit" +msgstr "" + #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" msgstr "" @@ -355,10 +360,6 @@ msgstr "" msgid "Submit yer media" msgstr "" -#: mediagoblin/templates/mediagoblin/submit/start.html:30 -msgid "Submit" -msgstr "" - #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format msgid "%(username)s's media" @@ -369,6 +370,35 @@ msgstr "" msgid "%(username)s's media" msgstr "" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#, python-format +msgid "By %(username)s on %(date)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +msgid "Post a comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +msgid "at" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +msgid "Post comment!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +msgid "Edit" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +msgid "Delete" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 +msgid "Sorry, no such media found." +msgstr "" + #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -492,6 +522,10 @@ msgstr "" msgid "Older" msgstr "" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:50 +msgid "Go to page:" +msgstr "" + #: mediagoblin/templates/mediagoblin/utils/tags.html:20 msgid "Tagged with" msgstr "" @@ -509,11 +543,11 @@ msgid "I am sure I want to delete this" msgstr "" #: mediagoblin/user_pages/views.py:155 -msgid "Empty comments are not allowed." +msgid "Oops, your comment was empty." msgstr "" #: mediagoblin/user_pages/views.py:161 -msgid "Comment posted!" +msgid "Your comment has been posted!" msgstr "" #: mediagoblin/user_pages/views.py:183 diff --git a/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.mo index 2ae7c510481b42bcd471dbaefc1d40fa70734b6c..b2194da9540dbef606baddad5d7936a50347f5e1 100644 GIT binary patch delta 4325 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 YWRMQnj5T#o2B|F*E1pnuj8CZl0nO9=8UO$Q diff --git a/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.po index 37bd36c1..0e48dc53 100644 --- a/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.po @@ -9,8 +9,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-11-27 15:25-0600\n" -"PO-Revision-Date: 2011-11-27 21:28+0000\n" +"POT-Creation-Date: 2011-12-03 16:57-0600\n" +"PO-Revision-Date: 2011-12-03 22:56+0000\n" "Last-Translator: cwebber \n" "Language-Team: Swedish (http://www.transifex.net/projects/p/mediagoblin/team/sv/)\n" "MIME-Version: 1.0\n" @@ -101,7 +101,7 @@ msgid "Tags" msgstr "Taggar" #: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 -msgid "Seperate tags by commas or spaces." +msgid "Seperate tags by commas." msgstr "" #: mediagoblin/edit/forms.py:33 @@ -265,6 +265,11 @@ msgstr "Senast medier" msgid "Enter your new password" msgstr "Fyll i ditt lösenord" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:33 +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Submit" +msgstr "Skicka" + #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" msgstr "" @@ -380,10 +385,6 @@ msgstr "" msgid "Submit yer media" msgstr "Ladda upp" -#: mediagoblin/templates/mediagoblin/submit/start.html:30 -msgid "Submit" -msgstr "Skicka" - #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format msgid "%(username)s's media" @@ -394,6 +395,35 @@ msgstr "" msgid "%(username)s's media" msgstr "%(username)ss media" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#, python-format +msgid "By %(username)s on %(date)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +msgid "Post a comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +msgid "at" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +msgid "Post comment!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +msgid "Edit" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +msgid "Delete" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 +msgid "Sorry, no such media found." +msgstr "" + #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -525,6 +555,10 @@ msgstr "Nyare" msgid "Older" msgstr "Äldre" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:50 +msgid "Go to page:" +msgstr "" + #: mediagoblin/templates/mediagoblin/utils/tags.html:20 msgid "Tagged with" msgstr "" @@ -542,11 +576,11 @@ msgid "I am sure I want to delete this" msgstr "Jag är säker på att jag vill radera detta" #: mediagoblin/user_pages/views.py:155 -msgid "Empty comments are not allowed." +msgid "Oops, your comment was empty." msgstr "" #: mediagoblin/user_pages/views.py:161 -msgid "Comment posted!" +msgid "Your comment has been posted!" msgstr "" #: mediagoblin/user_pages/views.py:183 diff --git a/mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.mo index b0d8d3fcc54d8d7855f2b529486183e885f8e84d..2ac4c41c8262e9f9cd51a818626de440fa6bdcca 100644 GIT binary patch literal 11439 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≺)BkLEu%Q*s2@WbkdAwbX2eFDE1qE=mpy2F4ps>O-)zD zE`Agyed_93EnnDgA-^ov@}^j{Y4l7K2Q|!BF)3EfHcp#y)M+$XtZKqE_5%NqUCiz< zV5Yg*@q(Z`givAUC9MZ0Izj4-Z>-aF+HIR;zCA<|v2YUA(-|)|Lx@`qIyLdYv|lp_*=e_-g$cl4|U?B@9RijE+R;KBcxs;fjNS)sEPYZmY*g1!CWka$ zV2YH?TGT4(fdl4Gw|xh(JUv&dvO?GhJ5u}l$F}d@FGWghc8jT|tWg)KQKB@c_;P+B zR6B4LzV~#}Mg&O&L&`^_L(JVu)NyhpCa9Ox4j;qk3JxYig#r`ulHlY&W&J!nhIG^> zjwH+KRL5vWoF)0-hXt$mjH&2K9LZ63RhjKL zprlsGWCB%lTk3t;-OBn6Oc$vMu|AfNv%w0WcAFU!tKFRP zr`hScfHPWM7q#gO_GE{|+&^?65^yaqtu{+)59KLl<4X60^RlvFS3c1i^^aLeomk>Z z%ELS6WTj;I9kpcsMp?fT`1B`uQV!a=z&ZWi!{YU1Sc+h&nYM!du^UM!iMXZ-+SEnu zw=gVmY7d6|IPMcM2i0C9jZ7Z!%LlU3zmYF&9KJK6-8W|p_>$Tu=Z&i%iP}fUq4v?V z*b|I6%o|wjI`2%fXStOxFN8xj!w5RpE=dTJm?t+&`$z$rFweFw^V%F~uuo}o5X%h? zrSGUV-IO}rGD(nq^@)-6_#Gt3LSS&G}0>1(8(vkld%Lnq+T zV7sCtf@j60%m5LK7Rk+$*4*k&0C7ljh!~HPC#&z7_PGmOFIA(fA$q%rOOcd)-J(`) zB30~#2PJfw%c9vjQH~2J8WU_d3els!mOm)Ci68a@|Ac~q%)TdqO*+y7=EnB$0g#EMA z&!bUAB>v{jJy`K;uyXQ7IMj zaEJ+`yG+xh_VUNz*5rCi@}}jw(KLTJeW{VB>n6cS+_ZN?#`X0F6!xCZK`kt z|S#vio=4Cbj@^nz_!jI9@B>K#zi7%KDVXv9Q<36IXE}Y529`=1wCiPDW*&9V`{D zOZ6xsVcVt9q{B!ry>2pW?dguYVLwSaCMoQ>Zn9_}PS~fo6}y-9%8}90BEKV}dgYbn z(N)Ef)gvPeEbcYazQ}XxxGVMOs`AL%FOKk2*ySZ@aWeM8B=FKGF7tRKPuhCD=%n@H+7shM-nxm4 z+bDDLXj|56D}GwoZbEqzU@&sGtT%fV6X=oBmr8323-5rWO6JY){8}XqNnU3b-T{5+ z-U0PyXM3{`_m13UKX32NKF~Yz)!yurz1d^$&x@hn>`}WLJG{`Fz2E)+VSG*0n|-2p zM>)tFzze6r&U*O_?Yn+GN#Z%TJ4|DO}yg=&B9=3ab#ksjR%LXFB1NdCR z;RsRih!x-oK0k18n4H~^_qohs60ex*QHfxQsYh%~p}{c*p#mBa-A=nldq=)z)n*)l zk3|<=P1Sw(;&9>B)WWN&_y5(DB&y^i*~dXZ>OMmnlc+~+_4%<>BT3pP-N9gQQWweW zV;`hb;m$Vd+I(tMsg`y7&Fx@5yXY dCw(8ZiA!rsib_vLB2)LJ(Oh_gw(tf`{RbS{tH%HU diff --git a/mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.po index 064fa7d1..816f2580 100644 --- a/mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.po @@ -8,8 +8,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-11-27 15:25-0600\n" -"PO-Revision-Date: 2011-11-27 21:28+0000\n" +"POT-Creation-Date: 2011-12-03 16:57-0600\n" +"PO-Revision-Date: 2011-12-03 22:56+0000\n" "Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -96,7 +96,7 @@ msgid "Tags" msgstr "" #: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 -msgid "Seperate tags by commas or spaces." +msgid "Seperate tags by commas." msgstr "" #: mediagoblin/edit/forms.py:33 @@ -256,6 +256,11 @@ msgstr "" msgid "Enter your new password" msgstr "" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:33 +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Submit" +msgstr "దాఖలు చెయ్యి" + #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" msgstr "" @@ -356,10 +361,6 @@ msgstr "" msgid "Submit yer media" msgstr "" -#: mediagoblin/templates/mediagoblin/submit/start.html:30 -msgid "Submit" -msgstr "దాఖలు చెయ్యి" - #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format msgid "%(username)s's media" @@ -370,6 +371,35 @@ msgstr "" msgid "%(username)s's media" msgstr "" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#, python-format +msgid "By %(username)s on %(date)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +msgid "Post a comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +msgid "at" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +msgid "Post comment!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +msgid "Edit" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +msgid "Delete" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 +msgid "Sorry, no such media found." +msgstr "" + #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -493,6 +523,10 @@ msgstr "" msgid "Older" msgstr "" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:50 +msgid "Go to page:" +msgstr "" + #: mediagoblin/templates/mediagoblin/utils/tags.html:20 msgid "Tagged with" msgstr "" @@ -510,11 +544,11 @@ msgid "I am sure I want to delete this" msgstr "" #: mediagoblin/user_pages/views.py:155 -msgid "Empty comments are not allowed." +msgid "Oops, your comment was empty." msgstr "" #: mediagoblin/user_pages/views.py:161 -msgid "Comment posted!" +msgid "Your comment has been posted!" msgstr "" #: mediagoblin/user_pages/views.py:183 diff --git a/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.mo index e3751aebe21ab7fb42ffdac898f927f8ba14fb52..33400cefa80281d52de193db3839d3e905b7b06e 100644 GIT binary patch delta 4373 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 MgxZOs-QC6h3-$993IG5A delta 3865 zcmajgeQ*@z9S86y1Jw`&LwGkKc`k1xG+c7wZH&AW0Z|Yv7K_xjy1Cm+R_<=Ew|j}F zqdCC9frKDWh$7Jl1`VVH!bO^w3oo@Zbw-^|J9YS{SVwPnFC86f9XoBuPW%1co+XZd zlu7d0efD{N&-47A-!91?w>{kQQQqWZ4F4MOTY%r6PNKV8|GI8tYz}T;g&)B|SPjMP zjBSPQz$q{}{9>6Yv4}TZq_f z1{&{#^Ivi7aG%IL|6S((V>l1(U&6cK9aHfO7s9!4DJ;bN>_J>iL&GjO zA4Xsi6p%W`A!X)0I1{EIE$nMJ8BRvj*>DPc1QtPBa2Qs>R`@Ku2(QB$OjZH2r=u@* zaN!~Xw?Q|24?18qqR@ofU@?@%@vM>-+Uo~spU#xvEAmO2Pe*Qcw@EYPJW`R@-MFVLNcqfd*RoXONORAFFb~r5U}D z4(DY^0lFdPV84VEXbhIYUqjkz3R13fu-{Fv7*c#cTmfH!PWXqJI53WjtXYh0hsCfO zHbdI+TW}3L2WiKjLk|BA>Con4`AV>xcm@f*>jL4eihOLJsAff zE#NnhGH^X}|3&8cWV~dQ`dN_T6lU&MW!wmF!~AR;E-28Wkj`=!48t3cQud<~d*T43 zg*^u;)$JL(;AY&Pfpq3yK@4Ra>7)B~kZL0UX(PRm#-E2Rl=?*G!H19r{t4oT{Re;O zc`4qlHE~pikzy%H68ZC)KMV zNk@o)hii>$GgrM{u7;EbB_R3It(Z`0l0DoVk|kYH1Db=a^?0~n_9zlttN4{b0|oO- zyAZTd=FMuz=iw5smvvpnbTsjLJPE1chDPp@-Eu$=Nj~N2bhPvo6><|A!;;Szsluw# zAvIMEI4ZeU#{B7?4v{nE-IlQ8)6?6KpVH-krqnAwMUOZ+uhS1OSqjNjTnV^+VGpgpN%6=k*TTV|8qyt=Y@HNv%RaWQQ3^E3T+to4l-;{{ zM9j(AGR^PDYI#uAblKw&PvjJc{+v@{$JDhVG1cGT59$$`mpW-26Y+qmbL>rRmOW0k zAwXG)sNoO~$jv+`X&N%-nb;oIS8v?<$jWMIH4lc=CuO&e0bW`ImgKBt zc*wWVS#DJ8eM%r6xZ`kEp`AjX+9Zb@6Q6QLb2^>z1=AnR60tjXh|lg^D0uFIY&pap zQiGa9L~@J8P;TP_>@|e-)_}#I@X_RnG~(rrOG>sZHYYh13y_^GMoHB0MU zOX89FSy|%9U30$uf*;K;%`-+vtiBhLLs298g3;QRx;QGv@2dHBKYR$5ly~(e$6mKy zc|MsKF}vD~*M`_l?Ohkl&f%Mh z-QrsQtQPA;KiUvD_2%yJX#4o?!$xeMdF%}%(ViUYNbNssbqr94&SA7*LaYLNOb&Hg z#}1h%2Cd77jniWYR$&c|nOz5Hc|B)tCJq_>dyUI6<4T{|wbzJUNM7EDDCk$ojN!}4 z;loD%Av1O)DL%BR^vkY*8sMr*4Xee2Wco{H3HH#Tov*l%{6H`@n|o>#2ie*DcO z<@E#>RK=6S-I?cO1LNIsJ6HBR?VaYO7)$jZ#5!raR|`S~>+FxhH(w5Bof=7wIxTojmxd(-Z&C(9DE(Y%-D-Kxtob@W*!#*E-b3GD=9g)4-xE# z*va_*w$z)Q_QCK9>)0u)50lVH^b-9g`Hov(8{nJzN( z`4c$KRJ0Y3CVY_)nZ7xHN9(fTLV4To{>7yUc6AeQ(T#gIv5{) zjal(-D}IcU?<&ckgi;b$b6w)qlGPm7#@=@14?WG^H*olNDW~2TL#5gusO8`NKw*H9 zu6<*;FSF~8;qmB2yI3+`rhk?ch~iSGXexdDXjz$9TekIX^WcDa?f~l2uHT90Vf^Z% zbxB|wM(ZWKJXl6@?26UVn;hAPG8Bi)oLlV;GP}5vi3I8wCy1%e}av%|sc zf|!^eD(kLjax88hh#Fm#^LT#wp)65Uv05}$Y!L5O{6oxKv`9o3{Y=dI{)#gCa2W{L RGm\n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -58,7 +58,7 @@ msgstr "抱歉, 這個使用者名稱已經存在." #: mediagoblin/auth/views.py:77 msgid "Sorry, a user with that email address already exists." -msgstr "" +msgstr "抱歉,此電子郵件已被註冊了。" #: mediagoblin/auth/views.py:179 msgid "" @@ -72,11 +72,11 @@ msgstr "認證碼或是使用者帳號錯誤" #: mediagoblin/auth/views.py:203 msgid "You must be logged in so we know who to send the email to!" -msgstr "" +msgstr "你必須登入,我們才知道信要送給誰!" #: mediagoblin/auth/views.py:211 msgid "You've already verified your email address!" -msgstr "" +msgstr "你的電子郵件已經確認了!" #: mediagoblin/auth/views.py:224 msgid "Resent your verification email." @@ -97,7 +97,7 @@ msgid "Tags" msgstr "標籤" #: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 -msgid "Seperate tags by commas or spaces." +msgid "Seperate tags by commas." msgstr "" #: mediagoblin/edit/forms.py:33 @@ -123,11 +123,11 @@ msgstr "網站" #: mediagoblin/edit/forms.py:49 msgid "Old password" -msgstr "" +msgstr "舊的密碼" #: mediagoblin/edit/forms.py:52 msgid "New Password" -msgstr "" +msgstr "新的密碼" #: mediagoblin/edit/views.py:65 msgid "An entry with that slug already exists for this user." @@ -143,15 +143,15 @@ msgstr "你正在編輯一位用戶的檔案. 請謹慎處理." #: mediagoblin/edit/views.py:171 msgid "Wrong password" -msgstr "" +msgstr "密碼錯誤" #: mediagoblin/edit/views.py:192 msgid "Profile edited!" -msgstr "" +msgstr "個人資料已被編輯了!" #: mediagoblin/media_types/__init__.py:61 msgid "Could not find any file extension in \"{filename}\"" -msgstr "" +msgstr "找不到任何 \"{filename}\" 的附檔名。" #: mediagoblin/submit/forms.py:25 msgid "File" @@ -171,7 +171,7 @@ msgstr "呼呼! 送出去嚕!" #: mediagoblin/submit/views.py:133 msgid "Invalid file type." -msgstr "" +msgstr "不正確的檔案格式" #: mediagoblin/templates/mediagoblin/404.html:21 msgid "Oops!" @@ -201,11 +201,11 @@ msgstr "遞交媒體" #: mediagoblin/templates/mediagoblin/base.html:65 msgid "Verify your email!" -msgstr "" +msgstr "確認你的電子郵件" #: mediagoblin/templates/mediagoblin/base.html:72 msgid "log out" -msgstr "" +msgstr "登出" #: mediagoblin/templates/mediagoblin/base.html:75 #: mediagoblin/templates/mediagoblin/auth/login.html:27 @@ -227,21 +227,21 @@ msgstr "探索" #: mediagoblin/templates/mediagoblin/root.html:27 msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "" +msgstr "嘿!歡迎來到 媒體怪獸(MediaGoblin) 網站" #: mediagoblin/templates/mediagoblin/root.html:28 msgid "Your finest source for all goblin-related media." -msgstr "" +msgstr "你是媒體怪獸的相關媒體最珍貴的來源。" #: mediagoblin/templates/mediagoblin/root.html:29 msgid "" "To add your own media, place comments, save your favourites and more, you " "can log in with your MediaGoblin account." -msgstr "" +msgstr "你可以用 媒體怪獸 帳號登入,加入你自己的媒體檔案,加入評語,把你的最愛儲存起來。" #: mediagoblin/templates/mediagoblin/root.html:31 msgid "Don't have one yet? It's easy!" -msgstr "" +msgstr "還沒有嗎?其實非常簡單!" #: mediagoblin/templates/mediagoblin/root.html:32 #, python-format @@ -250,6 +250,9 @@ msgid "" " or\n" " Set up MediaGoblin on your own server" msgstr "" +"在這網站建立帳號\n" +" 或是\n" +" 建立一個自己的媒體怪獸(MedaiGoblin)" #: mediagoblin/templates/mediagoblin/root.html:44 msgid "Most recent media" @@ -259,13 +262,18 @@ msgstr "最新的媒體" msgid "Enter your new password" msgstr "輸入你的新密碼" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:33 +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Submit" +msgstr "送出" + #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" -msgstr "" +msgstr "找回密碼" #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:30 msgid "Send instructions" -msgstr "" +msgstr "送出指示" #: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 msgid "Your password has been changed. Try to log in now." @@ -361,30 +369,55 @@ msgstr "編輯 %(username)s'的檔案中" #: mediagoblin/templates/mediagoblin/listings/tag.html:35 #, python-format msgid "Media tagged with: %(tag_name)s" -msgstr "" +msgstr "此媒體被標識為:%(tag_name)s" #: mediagoblin/templates/mediagoblin/media_displays/video.html:19 msgid "Original" -msgstr "" +msgstr "原始的" #: mediagoblin/templates/mediagoblin/submit/start.html:26 msgid "Submit yer media" msgstr "遞交你的媒體檔案" -#: mediagoblin/templates/mediagoblin/submit/start.html:30 -msgid "Submit" -msgstr "送出" - #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format msgid "%(username)s's media" -msgstr "" +msgstr "%(username)s的媒體" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:37 #, python-format msgid "%(username)s's media" msgstr "%(username)s的媒體檔案" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#, python-format +msgid "By %(username)s on %(date)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +msgid "Post a comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +msgid "at" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +msgid "Post comment!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +msgid "Edit" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +msgid "Delete" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 +msgid "Sorry, no such media found." +msgstr "" + #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -508,13 +541,17 @@ msgstr "新一點" msgid "Older" msgstr "舊一點" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:50 +msgid "Go to page:" +msgstr "" + #: mediagoblin/templates/mediagoblin/utils/tags.html:20 msgid "Tagged with" -msgstr "" +msgstr "被標籤為" #: mediagoblin/templates/mediagoblin/utils/tags.html:25 msgid "and" -msgstr "" +msgstr "且" #: mediagoblin/user_pages/forms.py:24 msgid "Comment" @@ -525,20 +562,20 @@ msgid "I am sure I want to delete this" msgstr "我確定我想要刪除" #: mediagoblin/user_pages/views.py:155 -msgid "Empty comments are not allowed." -msgstr "評論不能空白。" +msgid "Oops, your comment was empty." +msgstr "" #: mediagoblin/user_pages/views.py:161 -msgid "Comment posted!" -msgstr "評論已經張貼!" +msgid "Your comment has been posted!" +msgstr "" #: mediagoblin/user_pages/views.py:183 msgid "You deleted the media." -msgstr "" +msgstr "你已刪除此媒體檔案。" #: mediagoblin/user_pages/views.py:190 msgid "The media was not deleted because you didn't check that you were sure." -msgstr "" +msgstr "此媒體檔案尚未被刪除因為你還沒有確認你真的要刪除。" #: mediagoblin/user_pages/views.py:198 msgid "You are about to delete another user's media. Proceed with caution." From cc4f83faabda361301210a6ba66c3ae5c7305a6a Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Sat, 3 Dec 2011 21:38:45 -0600 Subject: [PATCH 137/302] Raise a slightly useful exception when we can't find the media type. --- mediagoblin/media_types/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mediagoblin/media_types/__init__.py b/mediagoblin/media_types/__init__.py index 61786562..25f3d255 100644 --- a/mediagoblin/media_types/__init__.py +++ b/mediagoblin/media_types/__init__.py @@ -51,6 +51,10 @@ def get_media_manager(_media_type = None): if media_type in _media_type: return manager + # Nope? Then raise an error + raise FileTypeNotSupported( + "MediaManager not in enabled types. Check media_types in config?") + def get_media_type_and_manager(filename): for media_type, manager in get_media_managers(): From bbac7663f4b05430592ac5d39f056029dc11db92 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Sat, 3 Dec 2011 21:56:30 -0600 Subject: [PATCH 138/302] PEP-8'ifying prompt_if_not_set --- mediagoblin/gmg_commands/util.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mediagoblin/gmg_commands/util.py b/mediagoblin/gmg_commands/util.py index af172105..004f9e49 100644 --- a/mediagoblin/gmg_commands/util.py +++ b/mediagoblin/gmg_commands/util.py @@ -27,13 +27,13 @@ def setup_app(args): return mgoblin_app -def prompt_if_not_set(variable,text,password=False): +def prompt_if_not_set(variable, text, password=False): """ Checks if the variable is None and prompt for a value if it is """ - if (variable==None): + if variable is None: if not password: - variable=raw_input(text+' ') + variable=raw_input(text + u' ') else: variable=getpass.getpass(text) From bb20c179c43cc9aec2cb7a3160dc734e58961609 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Sat, 3 Dec 2011 21:59:52 -0600 Subject: [PATCH 139/302] Most users won't see this but having space after prompt still nice for passwords. --- mediagoblin/gmg_commands/util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediagoblin/gmg_commands/util.py b/mediagoblin/gmg_commands/util.py index 004f9e49..3e26c53f 100644 --- a/mediagoblin/gmg_commands/util.py +++ b/mediagoblin/gmg_commands/util.py @@ -35,6 +35,6 @@ def prompt_if_not_set(variable, text, password=False): if not password: variable=raw_input(text + u' ') else: - variable=getpass.getpass(text) + variable=getpass.getpass(text + u' ') return variable From 21e84329569a356deab73ed2b98d16b91af16b0f Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Sun, 4 Dec 2011 10:21:58 -0600 Subject: [PATCH 140/302] Change "Your finest source of goblin related media" to something else We don't want to insist everyone hold a goblin-related gallery :) --- mediagoblin/templates/mediagoblin/root.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediagoblin/templates/mediagoblin/root.html b/mediagoblin/templates/mediagoblin/root.html index 25ce9e96..0f769f2f 100644 --- a/mediagoblin/templates/mediagoblin/root.html +++ b/mediagoblin/templates/mediagoblin/root.html @@ -25,7 +25,7 @@ {% else %}

{% trans %}Hi there, welcome to this MediaGoblin site!{% endtrans %}

-

{% trans %}Your finest source for all goblin-related media.{% endtrans %}

+

{% trans %}This site is running MediaGoblin, an extraordinarily great piece of media hosting software.{% endtrans %}

{% trans %}To add your own media, place comments, save your favourites and more, you can log in with your MediaGoblin account.{% endtrans %}

{% if allow_registration %}

{% trans %}Don't have one yet? It's easy!{% endtrans %}

From f80f5b58a818dfcbbf984fc3e580df5fbf04917b Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Sun, 4 Dec 2011 10:24:42 -0600 Subject: [PATCH 141/302] Removing the conditional that checks if there's a media in media.html If there isn't a media, we shouldn't hit that template! The view should ensure that. --- .../mediagoblin/user_pages/media.html | 254 +++++++++--------- 1 file changed, 125 insertions(+), 129 deletions(-) diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html index 7434664c..caa99eb7 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media.html @@ -23,143 +23,139 @@ {% block title %}{{ media.title }} — {{ super() }}{% endblock %} {% block mediagoblin_content %} - {% if media %} -
-
- {% block mediagoblin_media %} - {% set display_media = request.app.public_store.file_url( - media.get_display_media(media.media_files)) %} +
+
+ {% block mediagoblin_media %} + {% set display_media = request.app.public_store.file_url( + media.get_display_media(media.media_files)) %} - {# if there's a medium file size, that means the medium size - # isn't the original... so link to the original! - #} - {% if media['media_files'].has_key('medium') %} - - Image for {{ media.title }} - - {% else %} + {# if there's a medium file size, that means the medium size + # isn't the original... so link to the original! + #} + {% if media['media_files'].has_key('medium') %} + Image for {{ media.title }} - {% endif %} - {% endblock %} -
- -

- {{ media.title }} -

- {% autoescape False %} -

{{ media.description_html }}

- {% endautoescape %} -

- {% trans date=media.created.strftime("%Y-%m-%d"), - user_url=request.urlgen( - 'mediagoblin.user_pages.user_home', - user=media.get_uploader().username), - username=media.get_uploader().username -%} - By {{ username }} on {{ date }} - {%- endtrans %} -

-

- {% if request.user and comments.count() %} -

{% trans %}Post a comment{% endtrans %}

- {% endif %} - {% if comments %} - {% for comment in comments %} - {% set comment_author = comment.author() %} - {% if pagination.active_id == comment._id %} -
- - {% else %} -
- {% endif %} - -
{% autoescape False %}{{ comment.content_html }} - {% endautoescape %} - - - {{ comment_author['username'] }} - {% trans %}at{% endtrans %} - - {{ comment.created.strftime("%I:%M%p %Y-%m-%d") }} - -
-
- {% endfor %} - - {% if request.user %} - - {{ wtforms_util.render_divs(comment_form) }} -
- - {{ csrf_token }} -
- + + {% else %} + Image for {{ media.title }} {% endif %} + {% endblock %} +
- {{ render_pagination(request, pagination, - request.urlgen('mediagoblin.user_pages.media_home', - user = media.get_uploader().username, - media = media._id)) }} -
+

+ {{ media.title }} +

+ {% autoescape False %} +

{{ media.description_html }}

+ {% endautoescape %} +

+ {% trans date=media.created.strftime("%Y-%m-%d"), + user_url=request.urlgen( + 'mediagoblin.user_pages.user_home', + user=media.get_uploader().username), + username=media.get_uploader().username -%} + By {{ username }} on {{ date }} + {%- endtrans %} +

+

+ {% if request.user and comments.count() %} +

{% trans %}Post a comment{% endtrans %}

+ {% endif %} + {% if comments %} + {% for comment in comments %} + {% set comment_author = comment.author() %} + {% if pagination.active_id == comment._id %} +
+ + {% else %} +
+ {% endif %} + +
{% autoescape False %}{{ comment.content_html }} + {% endautoescape %} + + + {{ comment_author['username'] }} + {% trans %}at{% endtrans %} + + {{ comment.created.strftime("%I:%M%p %Y-%m-%d") }} + +
+
+ {% endfor %} + + {% if request.user %} +
+ {{ wtforms_util.render_divs(comment_form) }} +
+ + {{ csrf_token }} +
+ + {% endif %} + + {{ render_pagination(request, pagination, + request.urlgen('mediagoblin.user_pages.media_home', + user = media.get_uploader().username, + media = media._id)) }} +
+ {% endif %} + +
+ {% include "mediagoblin/utils/prev_next.html" %} + + {% if media['uploader'] == request.user._id or + request.user['is_admin'] %} +

+ {% set edit_url = request.urlgen('mediagoblin.edit.edit_media', + user= media.get_uploader().username, + media= media._id) %} + {% trans %}Edit{% endtrans %} +

+

+ {% set delete_url = request.urlgen('mediagoblin.user_pages.media_confirm_delete', + user= media.get_uploader().username, + media= media._id) %} + {% trans %}Delete{% endtrans %} +

{% endif %} -
- {% include "mediagoblin/utils/prev_next.html" %} + {% if media.attachment_files|count %} +

Attachments

+ + {% endif %} - {% if media['uploader'] == request.user._id or - request.user['is_admin'] %} -

- {% set edit_url = request.urlgen('mediagoblin.edit.edit_media', - user= media.get_uploader().username, - media= media._id) %} - {% trans %}Edit{% endtrans %} -

-

- {% set delete_url = request.urlgen('mediagoblin.user_pages.media_confirm_delete', - user= media.get_uploader().username, - media= media._id) %} - {% trans %}Delete{% endtrans %} -

- {% endif %} + {% if app_config['allow_attachments'] + and (media['uploader'] == request.user._id + or request.user['is_admin']) %} +

+ Add attachment +

+ {% endif %} - {% if media.attachment_files|count %} -

Attachments

- - {% endif %} - - {% if app_config['allow_attachments'] - and (media['uploader'] == request.user._id - or request.user['is_admin']) %} -

- Add attachment -

- {% endif %} - - {% if media.tags %} - {% include "mediagoblin/utils/tags.html" %} - {% endif %} -
- {% else %} -

{% trans %}Sorry, no such media found.{% endtrans %}

- {% endif %} + {% if media.tags %} + {% include "mediagoblin/utils/tags.html" %} + {% endif %} +

{% endblock %} From b25b00d26e41158591822f5570c15f1baf2bc30b Mon Sep 17 00:00:00 2001 From: tycho garen Date: Sun, 4 Dec 2011 14:51:00 -0500 Subject: [PATCH 142/302] DOCS: update to deployment documentation and new production deployments doc --- docs/source/deploying.rst | 10 +++--- docs/source/production-deployments.rst | 48 ++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 5 deletions(-) create mode 100644 docs/source/production-deployments.rst diff --git a/docs/source/deploying.rst b/docs/source/deploying.rst index b944a3d3..9c0acf30 100644 --- a/docs/source/deploying.rst +++ b/docs/source/deploying.rst @@ -244,7 +244,7 @@ Production MediaGoblin Deployments with Paste The instance configured with ``lazyserver`` is not ideal for a production MediaGoblin deployment. Ideally, you should be able to use -a a control script (i.e. init script.) to launch and restart the +a control script (i.e. init script.) to launch and restart the MediaGoblin process. Use the following command as the basis for such a script: :: @@ -252,13 +252,13 @@ Use the following command as the basis for such a script: :: CELERY_ALWAYS_EAGER=true \ /srv/mediagoblin.example.org/mediagoblin/bin/paster serve \ /srv/mediagoblin.example.org/mediagoblin/paste.ini \ - --pid-file=/tmp/mediagoblin.pid \ + --pid-file=/var/run/mediagoblin.pid \ --server-name=fcgi fcgi_host=127.0.0.1 fcgi_port=26543 \ .. note:: The above configuration places MediaGoblin in "always eager" mode with Celery. This is fine for development and smaller - deployments. However, if you're getting into the really large - deployment category, consider reading the section of this manual on - Celery. + deployments. However, for larger production deployments with larger + processing requirements, see the ":doc:`production-deployments`" + documentation. diff --git a/docs/source/production-deployments.rst b/docs/source/production-deployments.rst new file mode 100644 index 00000000..37251734 --- /dev/null +++ b/docs/source/production-deployments.rst @@ -0,0 +1,48 @@ +========================================= +Considerations for Production Deployments +========================================= + +This document contains a number of suggestions for deploying +MediaGoblin in actual production environments. Consider +":doc:`deploying`" for a basic overview of how to deploy Media +Goblin. + +Celery +------ + +While the ``./lazyserer.sh`` configuration provides an efficient way to +start using a MediaGoblin instance, it is not suitable for production +deployments for several reasons: + +1. In nearly every scenario, work on the Celery queue will need to + balance with the demands of other processes, and cannot proceed + synchronously. This is a particularly relevant problem if you use + MediaGoblin to host Video content. + +2. Processing with Celery ought to be operationally separate from the + MediaGoblin application itself, this simplifies management and + support better workload distribution. + +3. ... additional reason here. .... + +Build an :ref:`init script ` around the following +command. + + CELERY_CONFIG_MODULE=mediagoblin.init.celery.from_celery ./bin/celeryd + +Modify your existing MediaGoblin and application init scripts, if +necessary, to prevent them from starting their own ``celeryd`` +processes. + +.. _init-script: + +Use an Init Script +------------------- + +TODO insert init script here + +Other Concerns +-------------- + +TODO What are they? + From b3efea3c79097ab5ea080f4c39ea59c2994fca5c Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Sun, 4 Dec 2011 13:56:55 -0600 Subject: [PATCH 143/302] Updated translations --- .../i18n/ar/LC_MESSAGES/mediagoblin.po | 26 +++-- .../i18n/ca/LC_MESSAGES/mediagoblin.po | 26 +++-- .../i18n/de/LC_MESSAGES/mediagoblin.po | 42 ++++---- .../i18n/en/LC_MESSAGES/mediagoblin.po | 24 ++--- .../i18n/eo/LC_MESSAGES/mediagoblin.po | 88 ++++++++------- .../i18n/es/LC_MESSAGES/mediagoblin.po | 54 +++++----- .../i18n/fr/LC_MESSAGES/mediagoblin.po | 28 +++-- .../i18n/ia/LC_MESSAGES/mediagoblin.po | 26 +++-- .../i18n/it/LC_MESSAGES/mediagoblin.po | 26 +++-- .../i18n/ja/LC_MESSAGES/mediagoblin.po | 26 +++-- .../i18n/nl/LC_MESSAGES/mediagoblin.po | 26 +++-- .../i18n/nn_NO/LC_MESSAGES/mediagoblin.po | 26 +++-- .../i18n/pt_BR/LC_MESSAGES/mediagoblin.po | 26 +++-- .../i18n/ro/LC_MESSAGES/mediagoblin.po | 53 ++++----- .../i18n/ru/LC_MESSAGES/mediagoblin.po | 102 ++++++++++-------- .../i18n/sk/LC_MESSAGES/mediagoblin.po | 26 +++-- .../i18n/sl/LC_MESSAGES/mediagoblin.po | 26 +++-- .../i18n/sr/LC_MESSAGES/mediagoblin.po | 26 +++-- .../i18n/sv/LC_MESSAGES/mediagoblin.po | 26 +++-- .../i18n/te/LC_MESSAGES/mediagoblin.po | 26 +++-- .../i18n/zh_TW/LC_MESSAGES/mediagoblin.po | 28 +++-- 21 files changed, 371 insertions(+), 386 deletions(-) diff --git a/mediagoblin/i18n/ar/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/ar/LC_MESSAGES/mediagoblin.po index e1188ac9..61abc63f 100644 --- a/mediagoblin/i18n/ar/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/ar/LC_MESSAGES/mediagoblin.po @@ -10,8 +10,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-12-03 16:57-0600\n" -"PO-Revision-Date: 2011-12-03 22:56+0000\n" +"POT-Creation-Date: 2011-12-04 10:24-0600\n" +"PO-Revision-Date: 2011-12-04 16:23+0000\n" "Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -156,7 +156,7 @@ msgstr "" msgid "Profile edited!" msgstr "" -#: mediagoblin/media_types/__init__.py:61 +#: mediagoblin/media_types/__init__.py:65 msgid "Could not find any file extension in \"{filename}\"" msgstr "" @@ -236,7 +236,9 @@ msgid "Hi there, welcome to this MediaGoblin site!" msgstr "" #: mediagoblin/templates/mediagoblin/root.html:28 -msgid "Your finest source for all goblin-related media." +msgid "" +"This site is running MediaGoblin, an " +"extraordinarily great piece of media hosting software." msgstr "" #: mediagoblin/templates/mediagoblin/root.html:29 @@ -393,35 +395,31 @@ msgstr "" msgid "%(username)s's media" msgstr "وسائط %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:57 #, python-format msgid "By %(username)s on %(date)s" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:67 msgid "Post a comment" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:85 msgid "at" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 msgid "Post comment!" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:124 msgid "Edit" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:130 msgid "Delete" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 -msgid "Sorry, no such media found." -msgstr "" - #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" diff --git a/mediagoblin/i18n/ca/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/ca/LC_MESSAGES/mediagoblin.po index a05dc5c0..9609cb34 100644 --- a/mediagoblin/i18n/ca/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/ca/LC_MESSAGES/mediagoblin.po @@ -9,8 +9,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-12-03 16:57-0600\n" -"PO-Revision-Date: 2011-12-03 22:56+0000\n" +"POT-Creation-Date: 2011-12-04 10:24-0600\n" +"PO-Revision-Date: 2011-12-04 16:23+0000\n" "Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -152,7 +152,7 @@ msgstr "" msgid "Profile edited!" msgstr "" -#: mediagoblin/media_types/__init__.py:61 +#: mediagoblin/media_types/__init__.py:65 msgid "Could not find any file extension in \"{filename}\"" msgstr "" @@ -233,7 +233,9 @@ msgid "Hi there, welcome to this MediaGoblin site!" msgstr "" #: mediagoblin/templates/mediagoblin/root.html:28 -msgid "Your finest source for all goblin-related media." +msgid "" +"This site is running MediaGoblin, an " +"extraordinarily great piece of media hosting software." msgstr "" #: mediagoblin/templates/mediagoblin/root.html:29 @@ -383,35 +385,31 @@ msgstr "" msgid "%(username)s's media" msgstr "%(username)s's media" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:57 #, python-format msgid "By %(username)s on %(date)s" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:67 msgid "Post a comment" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:85 msgid "at" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 msgid "Post comment!" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:124 msgid "Edit" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:130 msgid "Delete" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 -msgid "Sorry, no such media found." -msgstr "" - #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" diff --git a/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.po index fc78ed7c..7d7e0ee9 100644 --- a/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.po @@ -16,9 +16,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-12-03 16:57-0600\n" -"PO-Revision-Date: 2011-12-03 22:56+0000\n" -"Last-Translator: cwebber \n" +"POT-Creation-Date: 2011-12-04 10:24-0600\n" +"PO-Revision-Date: 2011-12-04 16:26+0000\n" +"Last-Translator: elrond \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" @@ -65,7 +65,7 @@ msgstr "Leider gibt es bereits einen Benutzer mit diesem Namen." #: mediagoblin/auth/views.py:77 msgid "Sorry, a user with that email address already exists." -msgstr "" +msgstr "Leider gibt es bereits einen Benutzer mit dieser E-Mail-Adresse." #: mediagoblin/auth/views.py:179 msgid "" @@ -85,7 +85,7 @@ msgstr "" #: mediagoblin/auth/views.py:211 msgid "You've already verified your email address!" -msgstr "" +msgstr "Deine E-Mail-Adresse wurde bereits bestätigt." #: mediagoblin/auth/views.py:224 msgid "Resent your verification email." @@ -161,9 +161,9 @@ msgstr "Falsches Passwort" #: mediagoblin/edit/views.py:192 msgid "Profile edited!" -msgstr "" +msgstr "Das Profil wurde aktualisiert" -#: mediagoblin/media_types/__init__.py:61 +#: mediagoblin/media_types/__init__.py:65 msgid "Could not find any file extension in \"{filename}\"" msgstr "" @@ -246,7 +246,9 @@ msgid "Hi there, welcome to this MediaGoblin site!" msgstr "" #: mediagoblin/templates/mediagoblin/root.html:28 -msgid "Your finest source for all goblin-related media." +msgid "" +"This site is running MediaGoblin, an " +"extraordinarily great piece of media hosting software." msgstr "" #: mediagoblin/templates/mediagoblin/root.html:29 @@ -384,7 +386,7 @@ msgstr "%(username)ss Profil bearbeiten" #: mediagoblin/templates/mediagoblin/listings/tag.html:35 #, python-format msgid "Media tagged with: %(tag_name)s" -msgstr "" +msgstr ": %(tag_name)s" #: mediagoblin/templates/mediagoblin/media_displays/video.html:19 msgid "Original" @@ -404,34 +406,30 @@ msgstr "%(username)ss Medien" msgid "%(username)s's media" msgstr "%(username)ss Medien" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:57 #, python-format msgid "By %(username)s on %(date)s" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:67 msgid "Post a comment" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:85 msgid "at" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 msgid "Post comment!" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:124 msgid "Edit" -msgstr "" +msgstr "Bearbeiten" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:130 msgid "Delete" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 -msgid "Sorry, no such media found." -msgstr "" +msgstr "Löschen" #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format @@ -571,7 +569,7 @@ msgstr "" #: mediagoblin/templates/mediagoblin/utils/tags.html:20 msgid "Tagged with" -msgstr "" +msgstr "Markiert mit" #: mediagoblin/templates/mediagoblin/utils/tags.html:25 msgid "and" diff --git a/mediagoblin/i18n/en/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/en/LC_MESSAGES/mediagoblin.po index 3732705c..17e6873c 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-12-03 16:57-0600\n" +"POT-Creation-Date: 2011-12-04 10:24-0600\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -145,7 +145,7 @@ msgstr "" msgid "Profile edited!" msgstr "" -#: mediagoblin/media_types/__init__.py:61 +#: mediagoblin/media_types/__init__.py:65 msgid "Could not find any file extension in \"{filename}\"" msgstr "" @@ -224,7 +224,9 @@ msgid "Hi there, welcome to this MediaGoblin site!" msgstr "" #: mediagoblin/templates/mediagoblin/root.html:28 -msgid "Your finest source for all goblin-related media." +msgid "" +"This site is running MediaGoblin, " +"an extraordinarily great piece of media hosting software." msgstr "" #: mediagoblin/templates/mediagoblin/root.html:29 @@ -370,35 +372,31 @@ msgstr "" msgid "%(username)s's media" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:57 #, python-format msgid "By %(username)s on %(date)s" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:67 msgid "Post a comment" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:85 msgid "at" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 msgid "Post comment!" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:124 msgid "Edit" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:130 msgid "Delete" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 -msgid "Sorry, no such media found." -msgstr "" - #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" diff --git a/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.po index cfc81d11..e5c6356e 100644 --- a/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.po @@ -10,9 +10,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-12-03 16:57-0600\n" -"PO-Revision-Date: 2011-12-03 22:56+0000\n" -"Last-Translator: cwebber \n" +"POT-Creation-Date: 2011-12-04 10:24-0600\n" +"PO-Revision-Date: 2011-12-04 19:15+0000\n" +"Last-Translator: aleksejrs \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -59,7 +59,7 @@ msgstr "Bedaŭrinde, uzanto kun tiu nomo jam ekzistas." #: mediagoblin/auth/views.py:77 msgid "Sorry, a user with that email address already exists." -msgstr "" +msgstr "Ni bedaŭras, sed konto kun tiu retpoŝtadreso jam ekzistas." #: mediagoblin/auth/views.py:179 msgid "" @@ -75,11 +75,11 @@ msgstr "La kontrol-kodo aŭ la uzantonomo ne estas korekta" #: mediagoblin/auth/views.py:203 msgid "You must be logged in so we know who to send the email to!" -msgstr "" +msgstr "Vi devas esti ensalutita, por ke ni sciu, al kiu sendi la retleteron!" #: mediagoblin/auth/views.py:211 msgid "You've already verified your email address!" -msgstr "" +msgstr "Vi jam konfirmis vian retpoŝtadreson!" #: mediagoblin/auth/views.py:224 msgid "Resent your verification email." @@ -103,7 +103,7 @@ msgstr "Etikedoj" #: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 msgid "Seperate tags by commas." -msgstr "" +msgstr "Dividu la etikedojn per komoj." #: mediagoblin/edit/forms.py:33 msgid "Slug" @@ -154,11 +154,11 @@ msgstr "Malĝusta pasvorto" #: mediagoblin/edit/views.py:192 msgid "Profile edited!" -msgstr "" +msgstr "La profilŝanĝo faritas!" -#: mediagoblin/media_types/__init__.py:61 +#: mediagoblin/media_types/__init__.py:65 msgid "Could not find any file extension in \"{filename}\"" -msgstr "" +msgstr "Ŝajnas, ke en «{filename}» mankas dosiernoma finaĵo" #: mediagoblin/submit/forms.py:25 msgid "File" @@ -178,7 +178,7 @@ msgstr "Hura! Alŝutitas!" #: mediagoblin/submit/views.py:133 msgid "Invalid file type." -msgstr "" +msgstr "Netaŭga dosiertipo." #: mediagoblin/templates/mediagoblin/404.html:21 msgid "Oops!" @@ -210,7 +210,7 @@ msgstr "Alŝuti aŭd-vid-dosieron" #: mediagoblin/templates/mediagoblin/base.html:65 msgid "Verify your email!" -msgstr "" +msgstr "Konfirmu viecon de la retpoŝtadreso!" #: mediagoblin/templates/mediagoblin/base.html:72 msgid "log out" @@ -232,25 +232,32 @@ msgstr "" #: mediagoblin/templates/mediagoblin/root.html:24 msgid "Explore" -msgstr "" +msgstr "Ĉirkaŭrigardi" #: mediagoblin/templates/mediagoblin/root.html:27 msgid "Hi there, welcome to this MediaGoblin site!" msgstr "Saluton, kaj bonvenon al ĉi tiu MediaGoblina retpaĝaro!" #: mediagoblin/templates/mediagoblin/root.html:28 -msgid "Your finest source for all goblin-related media." +msgid "" +"This site is running MediaGoblin, an " +"extraordinarily great piece of media hosting software." msgstr "" +"Ĉi tiu retpaĝaro funkcias per MediaGoblin, eksterordinare bonega " +"programaro por gastigado de aŭd‐vid‐dosieroj." #: mediagoblin/templates/mediagoblin/root.html:29 msgid "" "To add your own media, place comments, save your favourites and more, you " "can log in with your MediaGoblin account." msgstr "" +"Por aldoni viajn proprajn dosierojn, fari liston de plej plaĉantaj por vi, " +"ks, vi povas ensaluti je via MediaGoblina konto." #: mediagoblin/templates/mediagoblin/root.html:31 msgid "Don't have one yet? It's easy!" -msgstr "" +msgstr "Ĉu vi ankoraŭ ne havas tian? Ne malĝoju!" #: mediagoblin/templates/mediagoblin/root.html:32 #, python-format @@ -259,6 +266,9 @@ msgid "" " or\n" " Set up MediaGoblin on your own server" msgstr "" +"Kreu konton en ĉi tiu retejo\n" +" aŭ\n" +" Ekfunkciigu MediaGoblin’on en via propra servilo" #: mediagoblin/templates/mediagoblin/root.html:44 msgid "Most recent media" @@ -275,11 +285,11 @@ msgstr "Alŝuti" #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" -msgstr "" +msgstr "Ekhavo de nova pasvorto" #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:30 msgid "Send instructions" -msgstr "" +msgstr "Sendi instrukcion" #: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 msgid "Your password has been changed. Try to log in now." @@ -377,7 +387,7 @@ msgstr "Redaktado de l’profilo de %(username)s'" #: mediagoblin/templates/mediagoblin/listings/tag.html:35 #, python-format msgid "Media tagged with: %(tag_name)s" -msgstr "" +msgstr "Dosieroj kun etikedo: %(tag_name)s" #: mediagoblin/templates/mediagoblin/media_displays/video.html:19 msgid "Original" @@ -390,41 +400,37 @@ msgstr "Alŝutu vian aŭd-vid-dosieron" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format msgid "%(username)s's media" -msgstr "" +msgstr "Dosieroj de %(username)s" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:37 #, python-format msgid "%(username)s's media" msgstr "Dosieroj de %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:57 #, python-format msgid "By %(username)s on %(date)s" -msgstr "" +msgstr "Afiŝita de %(username)s je %(date)s" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:67 msgid "Post a comment" -msgstr "" +msgstr "Afiŝi komenton" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:85 msgid "at" -msgstr "" +msgstr "je" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 msgid "Post comment!" -msgstr "" +msgstr "Afiŝi la komenton!" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:124 msgid "Edit" -msgstr "" +msgstr "Ŝanĝi" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:130 msgid "Delete" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 -msgid "Sorry, no such media found." -msgstr "" +msgstr "Forigi" #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format @@ -559,11 +565,11 @@ msgstr "Malplinovaj" #: mediagoblin/templates/mediagoblin/utils/pagination.html:50 msgid "Go to page:" -msgstr "" +msgstr "Iri al paĝo:" #: mediagoblin/templates/mediagoblin/utils/tags.html:20 msgid "Tagged with" -msgstr "" +msgstr "Markita per: " #: mediagoblin/templates/mediagoblin/utils/tags.html:25 msgid "and" @@ -579,19 +585,21 @@ msgstr "Mi estas certa, ke mi volas forigi ĉi tion" #: mediagoblin/user_pages/views.py:155 msgid "Oops, your comment was empty." -msgstr "" +msgstr "Oj, via komento estis malplena." #: mediagoblin/user_pages/views.py:161 msgid "Your comment has been posted!" -msgstr "" +msgstr "Via komento estis afiŝita!" #: mediagoblin/user_pages/views.py:183 msgid "You deleted the media." -msgstr "" +msgstr "Vi forigis la dosieron." #: mediagoblin/user_pages/views.py:190 msgid "The media was not deleted because you didn't check that you were sure." msgstr "" +"La dosiero ne estis forigita, ĉar vi ne konfirmis vian certecon per la " +"markilo." #: mediagoblin/user_pages/views.py:198 msgid "You are about to delete another user's media. Proceed with caution." diff --git a/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.po index 88bd4da7..460c074c 100644 --- a/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.po @@ -10,13 +10,14 @@ # , 2011. # , 2011. # Mario Rodriguez , 2011. +# , 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-12-03 16:57-0600\n" -"PO-Revision-Date: 2011-12-03 22:56+0000\n" -"Last-Translator: cwebber \n" +"POT-Creation-Date: 2011-12-04 10:24-0600\n" +"PO-Revision-Date: 2011-12-04 16:49+0000\n" +"Last-Translator: manolinux \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" @@ -112,7 +113,7 @@ msgstr "Etiquetas" #: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 msgid "Seperate tags by commas." -msgstr "" +msgstr "Separar etiquetas por comas." #: mediagoblin/edit/forms.py:33 msgid "Slug" @@ -165,7 +166,7 @@ msgstr "Contraseña incorrecta" msgid "Profile edited!" msgstr "Perfil editado!" -#: mediagoblin/media_types/__init__.py:61 +#: mediagoblin/media_types/__init__.py:65 msgid "Could not find any file extension in \"{filename}\"" msgstr "No se pudo encontrar la extensión del archivo en \"{filename}\"" @@ -248,8 +249,13 @@ msgid "Hi there, welcome to this MediaGoblin site!" msgstr "Hola, bienvenido a este sitio de MediaGoblin!" #: mediagoblin/templates/mediagoblin/root.html:28 -msgid "Your finest source for all goblin-related media." -msgstr "Tu mejor fuente de contenidos relacionados con goblins." +msgid "" +"This site is running MediaGoblin, an " +"extraordinarily great piece of media hosting software." +msgstr "" +"Este sitio está montado con MediaGoblin, un programa libre buenísimo" +" para gestionar contenido multimedia." #: mediagoblin/templates/mediagoblin/root.html:29 msgid "" @@ -408,34 +414,30 @@ msgstr "Contenidos de %(username)s" msgid "%(username)s's media" msgstr "Contenido de %(username)s's" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:57 #, python-format msgid "By %(username)s on %(date)s" -msgstr "" +msgstr "Por %(username)s en %(date)s" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:67 msgid "Post a comment" -msgstr "" +msgstr "Pon un comentario." -#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:85 msgid "at" -msgstr "" +msgstr "en" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 msgid "Post comment!" -msgstr "" +msgstr "¡Pon un comentario!" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:124 msgid "Edit" -msgstr "" +msgstr "Editar" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:130 msgid "Delete" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 -msgid "Sorry, no such media found." -msgstr "" +msgstr "Borrar" #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format @@ -571,7 +573,7 @@ msgstr "Antiguas" #: mediagoblin/templates/mediagoblin/utils/pagination.html:50 msgid "Go to page:" -msgstr "" +msgstr "Ir a la página:" #: mediagoblin/templates/mediagoblin/utils/tags.html:20 msgid "Tagged with" @@ -591,11 +593,11 @@ msgstr "Estoy seguro de que quiero borrar esto" #: mediagoblin/user_pages/views.py:155 msgid "Oops, your comment was empty." -msgstr "" +msgstr "Ups, tu comentario estaba vacío." #: mediagoblin/user_pages/views.py:161 msgid "Your comment has been posted!" -msgstr "" +msgstr "¡Tu comentario ha sido publicado!" #: mediagoblin/user_pages/views.py:183 msgid "You deleted the media." diff --git a/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.po index 0bff6c37..8d1e2711 100644 --- a/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.po @@ -13,8 +13,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-12-03 16:57-0600\n" -"PO-Revision-Date: 2011-12-03 22:56+0000\n" +"POT-Creation-Date: 2011-12-04 10:24-0600\n" +"PO-Revision-Date: 2011-12-04 16:23+0000\n" "Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -166,7 +166,7 @@ msgstr "Mauvais mot de passe" msgid "Profile edited!" msgstr "Profile mis à jour !" -#: mediagoblin/media_types/__init__.py:61 +#: mediagoblin/media_types/__init__.py:65 msgid "Could not find any file extension in \"{filename}\"" msgstr "Impossible d'extraire une extension de fichier de \"{nomfichier}\"" @@ -249,8 +249,10 @@ msgid "Hi there, welcome to this MediaGoblin site!" msgstr "Bonjour, et bienvenu sur ce site MediaGoblin !" #: mediagoblin/templates/mediagoblin/root.html:28 -msgid "Your finest source for all goblin-related media." -msgstr "Là où ce trouve tout vos \"goblinesque\" media." +msgid "" +"This site is running MediaGoblin, an " +"extraordinarily great piece of media hosting software." +msgstr "" #: mediagoblin/templates/mediagoblin/root.html:29 msgid "" @@ -415,35 +417,31 @@ msgstr "Medias de %(username)s" msgid "%(username)s's media" msgstr "Médias de %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:57 #, python-format msgid "By %(username)s on %(date)s" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:67 msgid "Post a comment" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:85 msgid "at" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 msgid "Post comment!" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:124 msgid "Edit" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:130 msgid "Delete" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 -msgid "Sorry, no such media found." -msgstr "" - #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" diff --git a/mediagoblin/i18n/ia/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/ia/LC_MESSAGES/mediagoblin.po index 7dd3a4f1..512635e3 100644 --- a/mediagoblin/i18n/ia/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/ia/LC_MESSAGES/mediagoblin.po @@ -8,8 +8,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-12-03 16:57-0600\n" -"PO-Revision-Date: 2011-12-03 22:56+0000\n" +"POT-Creation-Date: 2011-12-04 10:24-0600\n" +"PO-Revision-Date: 2011-12-04 16:23+0000\n" "Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -148,7 +148,7 @@ msgstr "" msgid "Profile edited!" msgstr "" -#: mediagoblin/media_types/__init__.py:61 +#: mediagoblin/media_types/__init__.py:65 msgid "Could not find any file extension in \"{filename}\"" msgstr "" @@ -227,7 +227,9 @@ msgid "Hi there, welcome to this MediaGoblin site!" msgstr "" #: mediagoblin/templates/mediagoblin/root.html:28 -msgid "Your finest source for all goblin-related media." +msgid "" +"This site is running MediaGoblin, an " +"extraordinarily great piece of media hosting software." msgstr "" #: mediagoblin/templates/mediagoblin/root.html:29 @@ -371,35 +373,31 @@ msgstr "" msgid "%(username)s's media" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:57 #, python-format msgid "By %(username)s on %(date)s" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:67 msgid "Post a comment" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:85 msgid "at" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 msgid "Post comment!" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:124 msgid "Edit" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:130 msgid "Delete" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 -msgid "Sorry, no such media found." -msgstr "" - #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" diff --git a/mediagoblin/i18n/it/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/it/LC_MESSAGES/mediagoblin.po index dc9ec274..96d1f0a2 100644 --- a/mediagoblin/i18n/it/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/it/LC_MESSAGES/mediagoblin.po @@ -8,8 +8,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-12-03 16:57-0600\n" -"PO-Revision-Date: 2011-12-03 22:56+0000\n" +"POT-Creation-Date: 2011-12-04 10:24-0600\n" +"PO-Revision-Date: 2011-12-04 16:23+0000\n" "Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -152,7 +152,7 @@ msgstr "" msgid "Profile edited!" msgstr "" -#: mediagoblin/media_types/__init__.py:61 +#: mediagoblin/media_types/__init__.py:65 msgid "Could not find any file extension in \"{filename}\"" msgstr "" @@ -235,7 +235,9 @@ msgid "Hi there, welcome to this MediaGoblin site!" msgstr "" #: mediagoblin/templates/mediagoblin/root.html:28 -msgid "Your finest source for all goblin-related media." +msgid "" +"This site is running MediaGoblin, an " +"extraordinarily great piece of media hosting software." msgstr "" #: mediagoblin/templates/mediagoblin/root.html:29 @@ -384,35 +386,31 @@ msgstr "" msgid "%(username)s's media" msgstr "Documenti multimediali di %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:57 #, python-format msgid "By %(username)s on %(date)s" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:67 msgid "Post a comment" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:85 msgid "at" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 msgid "Post comment!" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:124 msgid "Edit" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:130 msgid "Delete" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 -msgid "Sorry, no such media found." -msgstr "" - #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" diff --git a/mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.po index 5dcf7377..3198eed9 100644 --- a/mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.po @@ -8,8 +8,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-12-03 16:57-0600\n" -"PO-Revision-Date: 2011-12-03 22:56+0000\n" +"POT-Creation-Date: 2011-12-04 10:24-0600\n" +"PO-Revision-Date: 2011-12-04 16:23+0000\n" "Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -148,7 +148,7 @@ msgstr "" msgid "Profile edited!" msgstr "" -#: mediagoblin/media_types/__init__.py:61 +#: mediagoblin/media_types/__init__.py:65 msgid "Could not find any file extension in \"{filename}\"" msgstr "" @@ -227,7 +227,9 @@ msgid "Hi there, welcome to this MediaGoblin site!" msgstr "" #: mediagoblin/templates/mediagoblin/root.html:28 -msgid "Your finest source for all goblin-related media." +msgid "" +"This site is running MediaGoblin, an " +"extraordinarily great piece of media hosting software." msgstr "" #: mediagoblin/templates/mediagoblin/root.html:29 @@ -376,35 +378,31 @@ msgstr "" msgid "%(username)s's media" msgstr "%(username)sさんのコンテンツ" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:57 #, python-format msgid "By %(username)s on %(date)s" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:67 msgid "Post a comment" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:85 msgid "at" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 msgid "Post comment!" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:124 msgid "Edit" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:130 msgid "Delete" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 -msgid "Sorry, no such media found." -msgstr "" - #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" diff --git a/mediagoblin/i18n/nl/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/nl/LC_MESSAGES/mediagoblin.po index dad00867..c1778676 100644 --- a/mediagoblin/i18n/nl/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/nl/LC_MESSAGES/mediagoblin.po @@ -8,8 +8,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-12-03 16:57-0600\n" -"PO-Revision-Date: 2011-12-03 22:56+0000\n" +"POT-Creation-Date: 2011-12-04 10:24-0600\n" +"PO-Revision-Date: 2011-12-04 16:23+0000\n" "Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -153,7 +153,7 @@ msgstr "" msgid "Profile edited!" msgstr "" -#: mediagoblin/media_types/__init__.py:61 +#: mediagoblin/media_types/__init__.py:65 msgid "Could not find any file extension in \"{filename}\"" msgstr "" @@ -232,7 +232,9 @@ msgid "Hi there, welcome to this MediaGoblin site!" msgstr "" #: mediagoblin/templates/mediagoblin/root.html:28 -msgid "Your finest source for all goblin-related media." +msgid "" +"This site is running MediaGoblin, an " +"extraordinarily great piece of media hosting software." msgstr "" #: mediagoblin/templates/mediagoblin/root.html:29 @@ -378,35 +380,31 @@ msgstr "" msgid "%(username)s's media" msgstr "Media van %(username)s " -#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:57 #, python-format msgid "By %(username)s on %(date)s" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:67 msgid "Post a comment" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:85 msgid "at" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 msgid "Post comment!" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:124 msgid "Edit" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:130 msgid "Delete" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 -msgid "Sorry, no such media found." -msgstr "" - #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" diff --git a/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.po index 10fad192..0b0c2a27 100644 --- a/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.po @@ -8,8 +8,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-12-03 16:57-0600\n" -"PO-Revision-Date: 2011-12-03 22:56+0000\n" +"POT-Creation-Date: 2011-12-04 10:24-0600\n" +"PO-Revision-Date: 2011-12-04 16:23+0000\n" "Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -151,7 +151,7 @@ msgstr "" msgid "Profile edited!" msgstr "" -#: mediagoblin/media_types/__init__.py:61 +#: mediagoblin/media_types/__init__.py:65 msgid "Could not find any file extension in \"{filename}\"" msgstr "" @@ -234,7 +234,9 @@ msgid "Hi there, welcome to this MediaGoblin site!" msgstr "" #: mediagoblin/templates/mediagoblin/root.html:28 -msgid "Your finest source for all goblin-related media." +msgid "" +"This site is running MediaGoblin, an " +"extraordinarily great piece of media hosting software." msgstr "" #: mediagoblin/templates/mediagoblin/root.html:29 @@ -392,35 +394,31 @@ msgstr "" msgid "%(username)s's media" msgstr "%(username)s sine mediefiler" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:57 #, python-format msgid "By %(username)s on %(date)s" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:67 msgid "Post a comment" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:85 msgid "at" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 msgid "Post comment!" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:124 msgid "Edit" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:130 msgid "Delete" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 -msgid "Sorry, no such media found." -msgstr "" - #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" diff --git a/mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.po index 0512f43d..daa65e0f 100644 --- a/mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.po @@ -9,8 +9,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-12-03 16:57-0600\n" -"PO-Revision-Date: 2011-12-03 22:56+0000\n" +"POT-Creation-Date: 2011-12-04 10:24-0600\n" +"PO-Revision-Date: 2011-12-04 16:23+0000\n" "Last-Translator: cwebber \n" "Language-Team: Portuguese (Brazilian) (http://www.transifex.net/projects/p/mediagoblin/team/pt_BR/)\n" "MIME-Version: 1.0\n" @@ -155,7 +155,7 @@ msgstr "" msgid "Profile edited!" msgstr "" -#: mediagoblin/media_types/__init__.py:61 +#: mediagoblin/media_types/__init__.py:65 msgid "Could not find any file extension in \"{filename}\"" msgstr "" @@ -238,7 +238,9 @@ msgid "Hi there, welcome to this MediaGoblin site!" msgstr "" #: mediagoblin/templates/mediagoblin/root.html:28 -msgid "Your finest source for all goblin-related media." +msgid "" +"This site is running MediaGoblin, an " +"extraordinarily great piece of media hosting software." msgstr "" #: mediagoblin/templates/mediagoblin/root.html:29 @@ -397,35 +399,31 @@ msgstr "" msgid "%(username)s's media" msgstr "Mídia de %(username)s " -#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:57 #, python-format msgid "By %(username)s on %(date)s" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:67 msgid "Post a comment" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:85 msgid "at" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 msgid "Post comment!" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:124 msgid "Edit" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:130 msgid "Delete" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 -msgid "Sorry, no such media found." -msgstr "" - #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" diff --git a/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.po index 5401c046..b747fc3a 100644 --- a/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.po @@ -4,13 +4,14 @@ # # Translators: # , 2011. +# George Pop , 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-12-03 16:57-0600\n" -"PO-Revision-Date: 2011-12-03 22:56+0000\n" -"Last-Translator: cwebber \n" +"POT-Creation-Date: 2011-12-04 10:24-0600\n" +"PO-Revision-Date: 2011-12-04 18:41+0000\n" +"Last-Translator: gap \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -101,7 +102,7 @@ msgstr "Tag-uri" #: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 msgid "Seperate tags by commas." -msgstr "" +msgstr "Desparte tag-urile prin virgulă." #: mediagoblin/edit/forms.py:33 msgid "Slug" @@ -155,7 +156,7 @@ msgstr "Parolă incorectă" msgid "Profile edited!" msgstr "Profilul a fost modificat!" -#: mediagoblin/media_types/__init__.py:61 +#: mediagoblin/media_types/__init__.py:65 msgid "Could not find any file extension in \"{filename}\"" msgstr "Nu pot extrage extensia din „{filename}”" @@ -238,8 +239,12 @@ msgid "Hi there, welcome to this MediaGoblin site!" msgstr "Salut, bine ai venit pe acest site MediaGoblin!" #: mediagoblin/templates/mediagoblin/root.html:28 -msgid "Your finest source for all goblin-related media." -msgstr "Locul unde elfii își transmit fișierele media." +msgid "" +"This site is running MediaGoblin, an " +"extraordinarily great piece of media hosting software." +msgstr "" +"Acest site folosește MediaGoblin, un " +"software excepțional pentru găzduirea fișierelor media." #: mediagoblin/templates/mediagoblin/root.html:29 msgid "" @@ -401,34 +406,30 @@ msgstr "Fișierele lui %(username)s" msgid "%(username)s's media" msgstr "Fișierele media ale lui %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:57 #, python-format msgid "By %(username)s on %(date)s" -msgstr "" +msgstr "De %(username)s la %(date)s" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:67 msgid "Post a comment" -msgstr "" +msgstr "Scrie un comentariu" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:85 msgid "at" -msgstr "" +msgstr "la" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 msgid "Post comment!" -msgstr "" +msgstr "Trimite comentariul" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:124 msgid "Edit" -msgstr "" +msgstr "Editare" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:130 msgid "Delete" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 -msgid "Sorry, no such media found." -msgstr "" +msgstr "Șterge" #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format @@ -561,7 +562,7 @@ msgstr "Mai vechi" #: mediagoblin/templates/mediagoblin/utils/pagination.html:50 msgid "Go to page:" -msgstr "" +msgstr "Salt la pagina:" #: mediagoblin/templates/mediagoblin/utils/tags.html:20 msgid "Tagged with" @@ -581,11 +582,11 @@ msgstr "Sunt sigur că doresc să șterg" #: mediagoblin/user_pages/views.py:155 msgid "Oops, your comment was empty." -msgstr "" +msgstr "Hopa, ai uitat să scrii comentariul." #: mediagoblin/user_pages/views.py:161 msgid "Your comment has been posted!" -msgstr "" +msgstr "Comentariul tău a fost trimis!" #: mediagoblin/user_pages/views.py:183 msgid "You deleted the media." diff --git a/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.po index cee135ca..c615cde2 100644 --- a/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.po @@ -8,9 +8,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-12-03 16:57-0600\n" -"PO-Revision-Date: 2011-12-03 22:56+0000\n" -"Last-Translator: cwebber \n" +"POT-Creation-Date: 2011-12-04 10:24-0600\n" +"PO-Revision-Date: 2011-12-04 17:53+0000\n" +"Last-Translator: aleksejrs \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -58,6 +58,8 @@ msgstr "Извините, пользователь с этим именем уж #: mediagoblin/auth/views.py:77 msgid "Sorry, a user with that email address already exists." msgstr "" +"Сожалеем, но на этот адрес электронной почты уже зарегистрирована другая " +"учётная запись." #: mediagoblin/auth/views.py:179 msgid "" @@ -73,11 +75,11 @@ msgstr "Неверный ключ проверки или идентификат #: mediagoblin/auth/views.py:203 msgid "You must be logged in so we know who to send the email to!" -msgstr "" +msgstr "Вам надо представиться, чтобы мы знали, кому отправлять сообщение!" #: mediagoblin/auth/views.py:211 msgid "You've already verified your email address!" -msgstr "" +msgstr "Вы уже потвердили свой адрес электронной почты!" #: mediagoblin/auth/views.py:224 msgid "Resent your verification email." @@ -102,7 +104,7 @@ msgstr "Метки" #: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 msgid "Seperate tags by commas." -msgstr "" +msgstr "Разделяйте метки запятыми." #: mediagoblin/edit/forms.py:33 msgid "Slug" @@ -129,11 +131,11 @@ msgstr "Сайт" #: mediagoblin/edit/forms.py:49 msgid "Old password" -msgstr "" +msgstr "Старый пароль" #: mediagoblin/edit/forms.py:52 msgid "New Password" -msgstr "" +msgstr "Новый пароль" #: mediagoblin/edit/views.py:65 msgid "An entry with that slug already exists for this user." @@ -150,15 +152,15 @@ msgstr "Вы редактируете профиль пользователя. #: mediagoblin/edit/views.py:171 msgid "Wrong password" -msgstr "" +msgstr "Неправильный пароль" #: mediagoblin/edit/views.py:192 msgid "Profile edited!" -msgstr "" +msgstr "Профиль изменён!" -#: mediagoblin/media_types/__init__.py:61 +#: mediagoblin/media_types/__init__.py:65 msgid "Could not find any file extension in \"{filename}\"" -msgstr "" +msgstr "В «{filename}» не обнаружено расширение имени файла" #: mediagoblin/submit/forms.py:25 msgid "File" @@ -178,7 +180,7 @@ msgstr "Ура! Файл загружен!" #: mediagoblin/submit/views.py:133 msgid "Invalid file type." -msgstr "" +msgstr "Неподходящий тип файла." #: mediagoblin/templates/mediagoblin/404.html:21 msgid "Oops!" @@ -208,11 +210,11 @@ msgstr "Загрузить файл" #: mediagoblin/templates/mediagoblin/base.html:65 msgid "Verify your email!" -msgstr "" +msgstr "Подтвердите ваш адрес электронной почты!" #: mediagoblin/templates/mediagoblin/base.html:72 msgid "log out" -msgstr "" +msgstr "завершение сеанса" #: mediagoblin/templates/mediagoblin/base.html:75 #: mediagoblin/templates/mediagoblin/auth/login.html:27 @@ -230,25 +232,32 @@ msgstr "" #: mediagoblin/templates/mediagoblin/root.html:24 msgid "Explore" -msgstr "" +msgstr "Смотреть" #: mediagoblin/templates/mediagoblin/root.html:27 msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "" +msgstr "Привет! Добро пожаловать на наш MediaGoblin’овый сайт!" #: mediagoblin/templates/mediagoblin/root.html:28 -msgid "Your finest source for all goblin-related media." +msgid "" +"This site is running MediaGoblin, an " +"extraordinarily great piece of media hosting software." msgstr "" +"Этот сайт работает на MediaGoblin, " +"необыкновенно замечательном ПО для хостинга мультимедийных файлов." #: mediagoblin/templates/mediagoblin/root.html:29 msgid "" "To add your own media, place comments, save your favourites and more, you " "can log in with your MediaGoblin account." msgstr "" +"Для добавления собственных файлов, комментирования, ведения списка любиых " +"файлов и т. п. вы можете представиться с помощью вашей MediaGoblin’овой " +"учётной записи." #: mediagoblin/templates/mediagoblin/root.html:31 msgid "Don't have one yet? It's easy!" -msgstr "" +msgstr "У вас её ещё нет? Не проблема!" #: mediagoblin/templates/mediagoblin/root.html:32 #, python-format @@ -257,6 +266,9 @@ msgid "" " or\n" " Set up MediaGoblin on your own server" msgstr "" +"Создайте учётную запись на этом сайте\n" +" или\n" +" Установите MediaGoblin на собственный сервер" #: mediagoblin/templates/mediagoblin/root.html:44 msgid "Most recent media" @@ -273,11 +285,11 @@ msgstr "Подтвердить" #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" -msgstr "" +msgstr "Сброс пароля" #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:30 msgid "Send instructions" -msgstr "" +msgstr "Отправить инструкцию" #: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 msgid "Your password has been changed. Try to log in now." @@ -377,11 +389,11 @@ msgstr "Редактирование профиля %(username)s" #: mediagoblin/templates/mediagoblin/listings/tag.html:35 #, python-format msgid "Media tagged with: %(tag_name)s" -msgstr "" +msgstr "Файлы с меткой: %(tag_name)s" #: mediagoblin/templates/mediagoblin/media_displays/video.html:19 msgid "Original" -msgstr "" +msgstr "Оригинал" #: mediagoblin/templates/mediagoblin/submit/start.html:26 msgid "Submit yer media" @@ -390,41 +402,37 @@ msgstr "Загрузить файл(ы)" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format msgid "%(username)s's media" -msgstr "" +msgstr "Файлы %(username)s" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:37 #, python-format msgid "%(username)s's media" msgstr "Файлы пользователя %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:57 #, python-format msgid "By %(username)s on %(date)s" -msgstr "" +msgstr "Загружено %(username)s %(date)s" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:67 msgid "Post a comment" -msgstr "" +msgstr "Оставить комментарий" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:85 msgid "at" -msgstr "" +msgstr "в" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 msgid "Post comment!" -msgstr "" +msgstr "Разместить комментарий!" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:124 msgid "Edit" -msgstr "" +msgstr "Изменить" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:130 msgid "Delete" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 -msgid "Sorry, no such media found." -msgstr "" +msgstr "Удалить" #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format @@ -557,15 +565,15 @@ msgstr "Более старые" #: mediagoblin/templates/mediagoblin/utils/pagination.html:50 msgid "Go to page:" -msgstr "" +msgstr "Перейти к странице:" #: mediagoblin/templates/mediagoblin/utils/tags.html:20 msgid "Tagged with" -msgstr "" +msgstr "Метки:" #: mediagoblin/templates/mediagoblin/utils/tags.html:25 msgid "and" -msgstr "" +msgstr "и" #: mediagoblin/user_pages/forms.py:24 msgid "Comment" @@ -577,19 +585,19 @@ msgstr "Я уверен, что хочу удалить это" #: mediagoblin/user_pages/views.py:155 msgid "Oops, your comment was empty." -msgstr "" +msgstr "Ой, ваш комментарий был пуст." #: mediagoblin/user_pages/views.py:161 msgid "Your comment has been posted!" -msgstr "" +msgstr "Ваш комментарий размещён!" #: mediagoblin/user_pages/views.py:183 msgid "You deleted the media." -msgstr "" +msgstr "Вы удалили файл." #: mediagoblin/user_pages/views.py:190 msgid "The media was not deleted because you didn't check that you were sure." -msgstr "" +msgstr "Файл не удалён, так как вы не подтвердили свою уверенность галочкой." #: mediagoblin/user_pages/views.py:198 msgid "You are about to delete another user's media. Proceed with caution." diff --git a/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.po index 30622dee..a44f7866 100644 --- a/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.po @@ -8,8 +8,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-12-03 16:57-0600\n" -"PO-Revision-Date: 2011-12-03 22:56+0000\n" +"POT-Creation-Date: 2011-12-04 10:24-0600\n" +"PO-Revision-Date: 2011-12-04 16:23+0000\n" "Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -152,7 +152,7 @@ msgstr "" msgid "Profile edited!" msgstr "" -#: mediagoblin/media_types/__init__.py:61 +#: mediagoblin/media_types/__init__.py:65 msgid "Could not find any file extension in \"{filename}\"" msgstr "" @@ -235,7 +235,9 @@ msgid "Hi there, welcome to this MediaGoblin site!" msgstr "" #: mediagoblin/templates/mediagoblin/root.html:28 -msgid "Your finest source for all goblin-related media." +msgid "" +"This site is running MediaGoblin, an " +"extraordinarily great piece of media hosting software." msgstr "" #: mediagoblin/templates/mediagoblin/root.html:29 @@ -395,35 +397,31 @@ msgstr "" msgid "%(username)s's media" msgstr "Výtvory, ktoré vlastní %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:57 #, python-format msgid "By %(username)s on %(date)s" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:67 msgid "Post a comment" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:85 msgid "at" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 msgid "Post comment!" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:124 msgid "Edit" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:130 msgid "Delete" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 -msgid "Sorry, no such media found." -msgstr "" - #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" diff --git a/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.po index 568a5f73..ffd2c04c 100644 --- a/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.po @@ -8,8 +8,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-12-03 16:57-0600\n" -"PO-Revision-Date: 2011-12-03 22:56+0000\n" +"POT-Creation-Date: 2011-12-04 10:24-0600\n" +"PO-Revision-Date: 2011-12-04 16:23+0000\n" "Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -150,7 +150,7 @@ msgstr "" msgid "Profile edited!" msgstr "" -#: mediagoblin/media_types/__init__.py:61 +#: mediagoblin/media_types/__init__.py:65 msgid "Could not find any file extension in \"{filename}\"" msgstr "" @@ -231,7 +231,9 @@ msgid "Hi there, welcome to this MediaGoblin site!" msgstr "" #: mediagoblin/templates/mediagoblin/root.html:28 -msgid "Your finest source for all goblin-related media." +msgid "" +"This site is running MediaGoblin, an " +"extraordinarily great piece of media hosting software." msgstr "" #: mediagoblin/templates/mediagoblin/root.html:29 @@ -381,35 +383,31 @@ msgstr "" msgid "%(username)s's media" msgstr "Vsebina uporabnika %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:57 #, python-format msgid "By %(username)s on %(date)s" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:67 msgid "Post a comment" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:85 msgid "at" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 msgid "Post comment!" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:124 msgid "Edit" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:130 msgid "Delete" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 -msgid "Sorry, no such media found." -msgstr "" - #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" diff --git a/mediagoblin/i18n/sr/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/sr/LC_MESSAGES/mediagoblin.po index 63f92fdc..942f7203 100644 --- a/mediagoblin/i18n/sr/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/sr/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-12-03 16:57-0600\n" -"PO-Revision-Date: 2011-12-03 22:56+0000\n" +"POT-Creation-Date: 2011-12-04 10:24-0600\n" +"PO-Revision-Date: 2011-12-04 16:23+0000\n" "Last-Translator: cwebber \n" "Language-Team: Serbian (http://www.transifex.net/projects/p/mediagoblin/team/sr/)\n" "MIME-Version: 1.0\n" @@ -147,7 +147,7 @@ msgstr "" msgid "Profile edited!" msgstr "" -#: mediagoblin/media_types/__init__.py:61 +#: mediagoblin/media_types/__init__.py:65 msgid "Could not find any file extension in \"{filename}\"" msgstr "" @@ -226,7 +226,9 @@ msgid "Hi there, welcome to this MediaGoblin site!" msgstr "" #: mediagoblin/templates/mediagoblin/root.html:28 -msgid "Your finest source for all goblin-related media." +msgid "" +"This site is running MediaGoblin, an " +"extraordinarily great piece of media hosting software." msgstr "" #: mediagoblin/templates/mediagoblin/root.html:29 @@ -370,35 +372,31 @@ msgstr "" msgid "%(username)s's media" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:57 #, python-format msgid "By %(username)s on %(date)s" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:67 msgid "Post a comment" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:85 msgid "at" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 msgid "Post comment!" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:124 msgid "Edit" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:130 msgid "Delete" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 -msgid "Sorry, no such media found." -msgstr "" - #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" diff --git a/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.po index 0e48dc53..e195ad70 100644 --- a/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.po @@ -9,8 +9,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-12-03 16:57-0600\n" -"PO-Revision-Date: 2011-12-03 22:56+0000\n" +"POT-Creation-Date: 2011-12-04 10:24-0600\n" +"PO-Revision-Date: 2011-12-04 16:23+0000\n" "Last-Translator: cwebber \n" "Language-Team: Swedish (http://www.transifex.net/projects/p/mediagoblin/team/sv/)\n" "MIME-Version: 1.0\n" @@ -153,7 +153,7 @@ msgstr "" msgid "Profile edited!" msgstr "" -#: mediagoblin/media_types/__init__.py:61 +#: mediagoblin/media_types/__init__.py:65 msgid "Could not find any file extension in \"{filename}\"" msgstr "" @@ -236,7 +236,9 @@ msgid "Hi there, welcome to this MediaGoblin site!" msgstr "" #: mediagoblin/templates/mediagoblin/root.html:28 -msgid "Your finest source for all goblin-related media." +msgid "" +"This site is running MediaGoblin, an " +"extraordinarily great piece of media hosting software." msgstr "" #: mediagoblin/templates/mediagoblin/root.html:29 @@ -395,35 +397,31 @@ msgstr "" msgid "%(username)s's media" msgstr "%(username)ss media" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:57 #, python-format msgid "By %(username)s on %(date)s" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:67 msgid "Post a comment" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:85 msgid "at" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 msgid "Post comment!" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:124 msgid "Edit" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:130 msgid "Delete" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 -msgid "Sorry, no such media found." -msgstr "" - #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" diff --git a/mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.po index 816f2580..f7bbd6ac 100644 --- a/mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.po @@ -8,8 +8,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-12-03 16:57-0600\n" -"PO-Revision-Date: 2011-12-03 22:56+0000\n" +"POT-Creation-Date: 2011-12-04 10:24-0600\n" +"PO-Revision-Date: 2011-12-04 16:23+0000\n" "Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -148,7 +148,7 @@ msgstr "" msgid "Profile edited!" msgstr "" -#: mediagoblin/media_types/__init__.py:61 +#: mediagoblin/media_types/__init__.py:65 msgid "Could not find any file extension in \"{filename}\"" msgstr "" @@ -227,7 +227,9 @@ msgid "Hi there, welcome to this MediaGoblin site!" msgstr "" #: mediagoblin/templates/mediagoblin/root.html:28 -msgid "Your finest source for all goblin-related media." +msgid "" +"This site is running MediaGoblin, an " +"extraordinarily great piece of media hosting software." msgstr "" #: mediagoblin/templates/mediagoblin/root.html:29 @@ -371,35 +373,31 @@ msgstr "" msgid "%(username)s's media" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:57 #, python-format msgid "By %(username)s on %(date)s" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:67 msgid "Post a comment" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:85 msgid "at" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 msgid "Post comment!" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:124 msgid "Edit" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:130 msgid "Delete" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 -msgid "Sorry, no such media found." -msgstr "" - #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" diff --git a/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.po index 6bc7a717..70622590 100644 --- a/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.po @@ -9,8 +9,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-12-03 16:57-0600\n" -"PO-Revision-Date: 2011-12-03 22:56+0000\n" +"POT-Creation-Date: 2011-12-04 10:24-0600\n" +"PO-Revision-Date: 2011-12-04 16:23+0000\n" "Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -149,7 +149,7 @@ msgstr "密碼錯誤" msgid "Profile edited!" msgstr "個人資料已被編輯了!" -#: mediagoblin/media_types/__init__.py:61 +#: mediagoblin/media_types/__init__.py:65 msgid "Could not find any file extension in \"{filename}\"" msgstr "找不到任何 \"{filename}\" 的附檔名。" @@ -230,8 +230,10 @@ msgid "Hi there, welcome to this MediaGoblin site!" msgstr "嘿!歡迎來到 媒體怪獸(MediaGoblin) 網站" #: mediagoblin/templates/mediagoblin/root.html:28 -msgid "Your finest source for all goblin-related media." -msgstr "你是媒體怪獸的相關媒體最珍貴的來源。" +msgid "" +"This site is running MediaGoblin, an " +"extraordinarily great piece of media hosting software." +msgstr "" #: mediagoblin/templates/mediagoblin/root.html:29 msgid "" @@ -389,35 +391,31 @@ msgstr "%(username)s的媒體" msgid "%(username)s's media" msgstr "%(username)s的媒體檔案" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:58 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:57 #, python-format msgid "By %(username)s on %(date)s" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:68 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:67 msgid "Post a comment" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:86 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:85 msgid "at" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:103 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 msgid "Post comment!" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:125 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:124 msgid "Edit" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:131 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:130 msgid "Delete" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:163 -msgid "Sorry, no such media found." -msgstr "" - #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" From 5b972a192e923dffde4660ca44e8bfbc74aa0c2f Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Sun, 4 Dec 2011 13:57:35 -0600 Subject: [PATCH 144/302] Compiled the .mo files too --- .../i18n/ar/LC_MESSAGES/mediagoblin.mo | Bin 12629 -> 12717 bytes .../i18n/ca/LC_MESSAGES/mediagoblin.mo | Bin 11417 -> 11505 bytes .../i18n/de/LC_MESSAGES/mediagoblin.mo | Bin 11684 -> 11805 bytes .../i18n/eo/LC_MESSAGES/mediagoblin.mo | Bin 11489 -> 11754 bytes .../i18n/es/LC_MESSAGES/mediagoblin.mo | Bin 11967 -> 12093 bytes .../i18n/fr/LC_MESSAGES/mediagoblin.mo | Bin 12215 -> 12304 bytes .../i18n/ia/LC_MESSAGES/mediagoblin.mo | Bin 11150 -> 11238 bytes .../i18n/it/LC_MESSAGES/mediagoblin.mo | Bin 11534 -> 11622 bytes .../i18n/ja/LC_MESSAGES/mediagoblin.mo | Bin 11791 -> 11879 bytes .../i18n/nl/LC_MESSAGES/mediagoblin.mo | Bin 11306 -> 11394 bytes .../i18n/nn_NO/LC_MESSAGES/mediagoblin.mo | Bin 10845 -> 10933 bytes .../i18n/pt_BR/LC_MESSAGES/mediagoblin.mo | Bin 11508 -> 11596 bytes .../i18n/ro/LC_MESSAGES/mediagoblin.mo | Bin 11761 -> 11882 bytes .../i18n/ru/LC_MESSAGES/mediagoblin.mo | Bin 14235 -> 15455 bytes .../i18n/sk/LC_MESSAGES/mediagoblin.mo | Bin 11701 -> 11789 bytes .../i18n/sl/LC_MESSAGES/mediagoblin.mo | Bin 11351 -> 11439 bytes .../i18n/sr/LC_MESSAGES/mediagoblin.mo | Bin 11247 -> 11335 bytes .../i18n/sv/LC_MESSAGES/mediagoblin.mo | Bin 11450 -> 11538 bytes .../i18n/te/LC_MESSAGES/mediagoblin.mo | Bin 11439 -> 11527 bytes .../i18n/zh_TW/LC_MESSAGES/mediagoblin.mo | Bin 11108 -> 11190 bytes 20 files changed, 0 insertions(+), 0 deletions(-) diff --git a/mediagoblin/i18n/ar/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/ar/LC_MESSAGES/mediagoblin.mo index aa6eacac22dc24f35dc38b71d9b818a227df36f1..02dfa29a8d836b87c0a82d96e257a57d047698c2 100644 GIT binary patch delta 2203 zcmb`{|4-Fb9LMoDUkXIv%9r@6@uASX@mqt*lID|%vI=S+W0A=%`L5^Jzw0r^$&Ch_i@hooX`34 zexGx%bWM1}*E18}H9mvBQHE3h4_unS+oQRD@4EjP==98^Cys=YDR z{y64Q@5BN;gb(8|CgOQa#S56r{Psnx!zE1P!6N44y`>HeMsF>w5;Z^rK7>t37wf<> zd;y2>1YX4y1}nv1un5!BqfxFvFZFROW`0X`nPp)GK7w0NJM^J;HV~_aQT^UQrQ#fF z;7L>@u3-i)AZu7^d;rpTsQy`~_I0TCdJL=3L}3-SBIz?v%$HC*4I+!Rw@?up!yY_` z%w;ZSRmh8wCTl=Nuno09FKXh~kw1HzFZKT@gZL|?U(&D#r%;C`kL{P?Q>YxiidA?T z6_FX#fU~Fx=TNEm4K?0f+=lls7q=3&9k>rQ?l{)tl`P_4K_QJJ?%-zZ#C>=SFXDRK zKo}G$F9y+%&3FwJu~o#ExoizOxDj<`o{P12p(1z$Tk$w*0W)C=nWKZ@hVRbP47lnBWg@w_9 z68I4y3s#4k;0fG==W!R_M-9A-RVW3!u@1ecNW70P4z`19iQQq8o=%x8)*oTIjj$83M?!*!X+kl7N#6OwBSsJ*KHi6tIn?|MLDr)C9aT_k87Er&A9}(=v zX8aSktDXGFFe>-o;4^p|kKvOvHsSZE2&9%1f8FOo;_@P%M1_12m9u1KV{=xB90O}b zofRLZ<7?QBr%)5!!M)hdkH*vZDe7>?kuM#>Jk;UsK-Oe|O%#-?4{#K}!Y$a&T}i-E zjK?uthG#GdKf#fyf}F_Zq?we+=b7d4uAo2UbNoRkaHOx#-*<3iYDGLzhmLvzzQ|m5Z^Fo6-le1( tr>e5Cx@M$3zgXqE#_A1`!TdK}k(F+DLUv~l^ZlRmwwAq-IC8gg@4w%O5k&w1 delta 2187 zcmb8ve@xVM9LMoD0^T7Bf{=ozd{I%9(-YW1UM40Jh@zRe8C$XN?hqDo^A0TB+^x|T zt{F{irPIxt%^I^mx(&(6tlS#WENPW%n&sw3E?rx-nzOZ@uj97-d_SMh_w(cZ z{(SCi@Y~(-8~GV;7=H)&_wauwT~Gi0U2vHd@Hl}F;@3EXx6y~wZnG>*G_bxeuwbCR7C5Pz#KqCLTdPc8V|c|1gjEE2Ljgu?w%D4ox}R_hLIP!B-Us+=vc#;Z8h+KD>d7 zR1V>YVFA|R5GrDm$Qo=K9lV7)GnvF)_482?bg&+MsCi>?3J+5l#YUV#KIUV&0c=2p z>Lt`+I*v-!XV{Lna0AxUsS5j0*X#_=!BOO<*$1cvjiVYqM)qX!Pl&5S;X9nczfc4H zNZiSW<@2MUiB{q+9K_j)K(F75E1}AX`mhmH^!~G%#a2R!XrUCg86f=`Sj!TvZkD*Cb9By^>qp p8i_^+yiRY#iS-A&W?xCowtP)Rdg4p(V8(_vrg8qyl-nzx{TKd90#^V4 diff --git a/mediagoblin/i18n/ca/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/ca/LC_MESSAGES/mediagoblin.mo index 203114fc48eade7f6b1a9e9c36a641e4a9c802e3..34179a53d237515f32598f254aa1c01a628f9b06 100644 GIT binary patch delta 2213 zcmb`{|4-Fb9LMoDUj#uA<%*OuO;#(lhP5>t)uzF3v^MMc;(oUNf!O8qIOlxMJzw7M zbMDCQx!vKPG85l1{s#Fk;Qw}lYXAL>C7WeaJ%=msE1ba}umUeHHcP=dti!)?J66$H zi$kdQQ63ulBC6kIOfn1GJcU*o{z1mH)>N})xC1M3FCM_RkuO-r60=NPf$CR^YWKM9 zk76$MHq6KUcpturiFgLna12*6zg=)Ue1qw{n8iH2x6pyX=&glqKn>7-r*Ury*pq_7*BaC$Jkw zk-02`Srzg%NRu_7BG`&rU|Urr&NBko`mwqZLC<9V#W zYQmsMbzlhnxEXJuBDR|NGM5#jgN>*&^Q_yx7Zt&NY{tW=1x$u1JWN5$Y=I`E$qu6j zKR|`*I_fa}iAvQf8ehOhtilth>va|5aSFLm_AP25(|9h9>y7NmjuTeR6Fx&>hQgPq zosO=Gh4eaVVKev$7V+ayi=C)}-*^2O>!^<-H`IPbUFTW%y@%B@r)@!{upJNJQ6yDi zOXYGZhZ(34I;b31yLAt0fG3ePS{L%M*LWz`AE6H6X;i-nbbxTGX@pNm`r zxQX@)sOvnBN@2;m*mZ8hVd|e?4X$T3Nw}w!`0GA*(XbhRM1?w^?J8#_=%5D|<8!Fg zbfQ8yfX(;@YT&Ebh`OsS;K7Adp@;ei>X-35-2k_?%q%zUvWacU41WmgTCl=c27d&>9X3$ wc<#yM8mDrDr>Z8hBd<{9I!{$~bTF?!Et*>VUVL_2H*@}G$@EyxFLfH2Jr`3EB=U$;1W#Y&U?8TEV`&| zVb0neYlW+(&S{fXgWJqMXtQiCS8U;2{L!LSF4p=<>yKJadw;rT>+jg%yq@!%=R7~Y z-{-k2ol~8WrR?NajK5L-3;6#jNl*X%&83=c;PC^@!Rxq;KcE*EJZ5Q_z^w+;u@xJ! z8c!gXUE!v#=TYqzaFtoaJgdzfpdu6L(>gH=yRj03sL7p0KCr@cvurFuwez9sTiyB& z+{|+?=HVD_#n&(y-^VpLhnpDRuDK1q!L_{5+g!-NO<0PWSOcnqeYg?Zkx#4#D=>g# z_&P3P9-VE+-?0$4W|)m&J@()wEMj~s$TVB87kC#wgj!)3wXzBK`DIkQGpJNtM0Grm zip0;j4sRoKuq-N5a0{yaHdK9`Ti=2aHE5@>1@|NAw1cjrsFfZ?CTmlu2)%{-)_aarc4;8^q)C5DQfhUp6PH|KF*>%KUA^nt!NAYvirYU9l71)LOcpR0>^H_-= zp(67Ks^h;=1A7RMQj&}6w-}qT9F@w0*owzc{ohzm{A(#Bu*G+v4;}2shw&JCaS0Wv z48jq@4Y&sd z4x={HNmQz?Vi(@T`>=^dRXB_~X6G>xr;(Fp@1Q1h3ExgIyNs;KB16Pg10Ka?Jc(NI z5#p|p&Y~uG1sm`VR$~J{7V7wE*Kw@j`92XfJA$bl@01hl_X%m5Liqe0N)smO(!_j;F8|i#W^dXY0gbJb+qA z6t$PmV!l4SK!GUPRpeXy4jIEzw#CnTF{&dUYPYwcI(Q6~x-Pdq?A9MaMPvdAqMbl( z(rMJf-b0OZ86(=2-%`-IUO}DfJE&0h-yIL-GpN)=u^i91&ZFA>iJG8?Wh(S}n2bB| z5!{8^GcTc1@G-KD?3ZE!rx&YB;+v-dQ+Pgvn$Q?3*T+#aKZn|Mv)GJts9Yx96F=Aa zu6uh1 zzC=avS8T%DsE!*6lMfGJ3(lZY^%vG*78^*vkZo-gxXjN@xr*W-zKc571x&jN+c62p zF%h4~G<*S5F^aKh-rj`Rif1Y<{V9L%K)2Hu2oLqfMzZS@W4ku`leYH_4EaODPACu# z_V{@lbh-xzohJiN3=Rz48}tu$5Bqzae?Q$Z`ReAy)SXUcOSmCC`X zDE&%N+JjzuJx-_If-|rS3$Pbc@Hl4RDV#=p^|jaG8fNlf6!URxyaR*LTPC&$Wq=yY z!=*?UwI0iHGw#B7@HITYT`VD2PX43c~F2M>sgmS&EU=m(ME|eNXnaB{{^>MwC zHK{?;D#k`Aj8OO+Wu?P26D!H(pFs`v5^TYjunfXy1Au0b1iK)Is8D|h>{5zN`_x~OR3G@Kv5M^qKl;)#LeGT5h+bCObr6_SL z{=g5ZXL4slcpMo*rO!zOD#NAJ8&J;1Zj`_-$^t&dJmRbKUWaQaGag1c)%Q@YTgu!- zdk)I!FG6-n&G*_@pzQH_&kZOmZbb?By64--Te*BloUbq@0luZsh1XHOxO`sXw?Idk z$ZII6-H(!i&yj<#ZlI+87nH3TL)r6b#Y(kf5!PWZR^w%?L|;kb&{vg^e@VGT!+0Ri z{V4bQQ_s`bMEx6-3Hs*q`+$WgDSjCn@eC3}-A6gBvq}@!bS3Vlz7OS4r|~cq>&wW$ z+~<`v$jr{81Rg~h=%MFamYqiZ8I;r9g0gZGWnw$=DZJ?ED`z{X*P$HhgBZk<$VE{< zVE~hB{fQM-;5Hi8;xg>VWc1N12~%+*rlCwESHA6z=H~q+0k}q zyKWirq1r2qH4h+Ug>Le+wr$pdc+RvPSgr&M%ao* z+O*n)3&scTh=#&uBoMVa>TJC$r2CynNBm@dN^07gOXuv?P9x%;Eilp>4BZMDOg|DY zD10}?y_Gd1eq&CfZ}tk^*4A3lb~CJP@3z_uP2cKt>tWM24aoT4A-jW}DxhN>r=F*2rz7=kLL2iCx diXp>dDYh0eZ0FKZ$Lw$d?!NK^?$iE_{{o@`U^@T+ delta 2306 zcmb8we`u9e9LMqR=H{kLr&HT6-JWI6>73iN`D2z!rqh+-FOr!_+r7`+>bl$R4`iBM zvY-tWqo>H3l7?htCUs$1Xbg+cL~1qg4@I;D%aSNUkb(97cpvERF3+CVdCqh0Ip6a= z=iD9Kc;xBCmAs6%jL$ayCi3_DFg^YEIhAELp2yR8KmLF>@K>zHfo!u8n8s}m=3pZ} zigmaLx$G-$>iPnz-2e_ZOIY?uvlUe2B7IsDj=^TE#Rw|6Bghx5G{-Ct%Tev-qv{*| z`qfy#a}bMg2bSPI%)rm^K0Jl_jBn@s2G?*DFZ8w$Mq@r!paNTr>R>rez?H~XEPyjG zj63iEUc@3gtHi&s6iY^%b>Tt`;7KfFe4ChSHcl__0bGNcVH`EHZvS~Ns@;32rRYO- zd;yh-TR0Z)A~Dz)Dl>5ss{LeCeZ61bfC)8NNnsMMMV8Y#eYc@z`U(=P^`bKL0k&Zu zGM1Gxs#0E!RM~P=2Afa;Mo|NM$YqDPsr{#8$-h#1o{IJOJ!;cbF#Q?035#(TYAugq zEuKMT=5JKTL#TnXNspGK5Y_J#T!zz8OWBEy*n{eSa2)xcOCgOdJ`?AogKfADd$1a> zpfWX@bVPAHF2Zh9#?B%!*Z?|s9kpjN$-C-Dp)%;;60Amz8%M3uCBbb`;a`7;@6=V^lyV@oJh`KQbpv944_e^b31qpf51Fieiv({!A(stt(^?m?)7U;%ip;@kk;|UorqqX! zp=>*esqG>A&+RrGM2V|EjdqL$)~vefDL5_@?b#1`z}4D%Hm zKn?UKK7u1Ar!v}r+A|xlBtaoSf&F4T{RaC`9UMdL>hq{$cNsO4o2bm(K~}}=!BqW3 z)EZa%&PL660cyY|-xlPu=eZ@+;p-GMz`M8wkE70Y@s!m6gi5@3u2HFNLS-O^3j7c% z^?j(NIg48JYuJjvVI8h1Pwo0{RN(#POmFmYU%$8yg(zShu+O)TE5tdC$ZR+M}Le!LJVo#1^ffK%H$w&7>P&!1u8R z^Q%%3FUMhekLkD@b8s&zpm(a0A7))0nX|63AntCIL)DuvpL)nYVW9uxS{5l8+7h{b*A@r!NsiEPVJofy18Dwux$8jXV$Fx zI`2SXL2+QK+tT7joQM6w;$S=)>k5Rz@nG_DVMgZg$J~$`bG=_m+>E8c_E>U#>7ESl zbZ%wx?&PIuxvL`K*7lI=5F+E1C7+#Ak>)*_SK!s;m3ZgM=M}9DMUS$7mGSF A9RL6T diff --git a/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.mo index 02d094863da2ae88004e9a0b53efe8247bc186d3..8f37922f516674ff72c9a1ffbc37fb0ece113507 100644 GIT binary patch delta 3397 zcmZA1eQZ_b9l-GiP+%PhQr;`@l$X*%DNw-L0)wiBAqa?NPMn&jz0WPreL3gmoO26B z@Zw7%CR>Ic=GUdsm&mr5m`vHirp!e5{oQjZ+iu$X zIp?|0d0u|M-*eu(_k;UNf0}gNw-lcN{%_*{FQeq{+UMmlN=@eW6`YF4@qPRwF2%RT zD)j~YJKl_+;vLvZ<0?FW@_U&t8Tt*BesAGurAq1(E;iBdIWnf&RHM{HybG6O5AMSw z$OCG^7nPcXQ&IXgp|p2Y+dFYO_uV)X^Eew1;dS^U9EUICH0D=Fs~yhZcz(EqGw`!Y z2L_|JENmId0Jq>2T#Iy3cVja?hzIcNcphsQY%yNMIe5bjNt9c#m;0Bnp83_d2};#s z3(mz`QFdricDA>AUqb2kG)gL7L>c%Elt{dbH{yrL8Y+#~!+3s_{rFCl%MhI{ZBO3_Sb`^~r&C5I2;a(o6QA}3J>JdHBp1(a0$4Q0G5xB)-IY1l>B z?!fy|#(fFf@DH`bzlDqOl(@z<*p2t&LHq?S#TA4>BGro_I$VeEqC{*K@ntU6fEwFT zYGzlpy$2ctsNp0Y8N-j5}gz&2<17%Ti8z5^_ zkD;vi`zVok4P}ChDE&S_DYj3s3G29#kawY+s&15V_MjB)(>O-X{|j93r+&hhRQD;A zns^6GI7Tb=F+PFqSgKDJa1^B${)!gwWfqy}O}=Eu7f~X587U*xI4`M{wMf~h4Jh@e zzQzS}sRGIXhf!*vj6_wPLfPT_D8=>(%JCX8KY1V2p;Z4;9EGb<##@I{0}rA+=TOEA zP$KY6EY))H11|Pp8D-$b3zAo67fQ%eRrgohkD#QgjIz^TSKHq~DXx$4Zk*UaL1PLf zqR*o|_dC25|J*=;C5H_QlZji9^rQ#ag7_{LQJ$Z;D5nJriND7h zJcncPJyh|fDO1X4$DFJwzcy*f$O)l~tahOeik|1ZzWCV0m2IB3d!xYkLCSe1aJd29 z7g!VNg0sC=`)QrGDQEOgFgZ6W9+-Y+%u2m{Sx4*2_^uiCom{tf zEMK*F8K0UhCXAMJ2gVC?Ch~(0ZE`jn+Ds7YH7T33k-a+D`T^sm?B1537{5B>&FQ!M zp|gRX(J8AJG!{b}cqVU~!uZjd-AgwIwy3kd7x}E*(?d@>9l4?o7%tus%_Bz*B)OX5uHu^m|=UqJbon(-HHdqM!LSQtL^}C#3ezx?=|gFkv$Dzq$6wcZ<7G{#Q0fVFDR>fNTFMs}7V^r-{8_}na)mIi0 zxq=^`pSyGNaCoytLKwNMP5JTKdC$$tG_x8*aPyY%YD>mLSwTUz7GIv%IyVW()gGRz z-sgrN^5V|<`=)QHgp-h*7?ef(I!$FoCX9bOzkXU*mOc6sQqS+FqY3-{AoAmX&)>G# zY3GGeP$XBrr*3!sE>+ZwUR`Cz(*+yI^nNDZws2;AXu-~otxosYlte=k653Q!9a?r* zt&DWu`eWwYsl4b_)(5fp5Nk*}aBy_%HCJ9Hn zlD)_@Q+Xzk?C}%jn07&)Xc0e8_u3$`y_A+LmeuEFcxr0f!k>+pMxjcMOh8mBMM=8p z$5~vlk>e3j_{mYUy2tk{>7z3H0>dD_F8G1&<5-dRR3(ILJ9Y8kVdBJhb+MWFpN;LM z?Q}J{l@jQrmRO3HxBX;C|D{KKY>`J0otNRe0K!4!l;B5*As<&Th5*XL%2V)=RnSEb@v8e6Rl6D8!)O?PJX34US)7TFG~YZeV^um=3|+p*&-u#ck}#?N0A5JjHvj+t delta 2538 zcmb8veN0tl9Ki7hQ9)4NkrxFH@+u-A3Me{tB7#g?;@imOcDeTe$1eB4J@=x}92#!P z8f*F3i>8}eO{deXu2WmMUTkJLGaFM|>9V=GT>fFJtXZz_&wIE2jvdbDInQ~{^YVLs z&%M9tPTSz^l<}`C{s#D;&i^mb^7P-|XpB;6Jf6p?_$}VUpRp3J#VR!kqqx;#JhtF6 zticiFQWv;M*H=*5UBih=4XW5UrB+gri1ex2FbQ2a2mL6Mdl&gY<;5$Ng2gE97NFF( zMC#XICeI$s#_gDkZ{c`6i<5B_GZ(9Y01HIF|6pmSmyyTZAjH3}q{Ou?2@w`X5Ur{&f_hNbw3>fChHq zIvmDIyp0m61j6B98ZN=zC=t7a%t2j41Mi~b%mm^t^;1wHXkY_YqKxYdQdmgg1UBJ4 zBGVMp%s*AW8?_w1;(5M;%D97w5j>8kkNmHj#CUg!@Mk)0PvL-d? zBd+wJhVUM~jdSIhxXa$2MG5&AxC;NmrMQA03wBGrj56Rpti^*UTQi26@OzYj>zK8) zUxL!#8XS=GKSV+H>IuqTMsrvtWJxF;6`<^G88SDu5M{y}kW2Zv$@e2D?e?G~-8(oF zFQA0}0m|w68>OE-8pX)@uYX$L7Yn&m3pYukEhstBhlBVYKEfh{Ji(m&@Rn>u$%!E} z@e#^E&vTO%??8#@9+ZV$M9G=&FkL$Si9#y=iHxBp7lbWG$%R!&6qOrgg*#9>cn#&4 z?MM0kG|I#;VKj~*K~*BVgt(Fe}qI!T}B!BK1%2x zN9t3H!YisqS!pAZS88L#9$d@wFxKELl!&GlhmZBLVgf56*-XVU>_thI(&vXKYV+Z|iled1u<@Fk!cDvW|&GwsKSHScbPd}~DZ)V&#~14RxyND} zxAk~!zo`%B&5UcZjeu?RxH`?y^}N>T-94!nYt<^ zS065}%wB8z{r%;J&o-Q(yDPkca7gvn#rx9MxjH)u*H$agr5Xd)3#P~3qW?*04qYud z6{R!FDz%j!(4UtrO5R}lt&V=9pRgNdx6AT|3TLg4(z`NRvo=_U$Lw=CMvvd_vj%vw v9n19FKK&qLm9ClHRn;b6{hy6HFuN|p6;K`CpksBn+g@9lUdQDP1}yb2e(8cb diff --git a/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.mo index dba37f0a814c9490904ba6c6914b58c5b74c3298..bed6aab8a3cc20c7410f280e4435a62226c9a104 100644 GIT binary patch delta 2502 zcmZA1ZERCj9LMpqtuPo5gRwCtY&)C41h&GUZftB!M*s%|hR!G?U~ap+akag--rLF$ zNDcVH$ADA`i6LerAc-uBH6(@*27N<<32sIZ14a>Ign(##j1m0)X%ioswx4rP&pi*n zdrnVoII%JDRgv#4#cK#OLu%SdIK_TeTxgp8#M8C4>$M5@$6lmt6aCKy5)cqj5!yZMs#2PTrgM0%WxCvXsD(@bIc zwYVDP8E(aT+>4UP8I%ssp$vElF*C*hIg8KI;Nv%O?XQOP&I7+*n zD5q#YR^cE9@Cq_#RjM-+4Pd^U|5getS}jG{Oa?AS7q{V2yoP>ytHWY?pNZ}GDq0xA zUy!$2cYkI<+feq-E|kbmq9pPq$^x!oG2<)WbfqY(GL(*6kqxT4QEu!*NhXOB{Xvw0 z-p|$#qeOodeRvaP$IUER@7oVuB5>Hc|+qhjO03M&9Z+UuMHRL~%Lcs%>=qIAAyc*@W zG@z__DYoMpl<4;0lXw(6uz+4$unXmX;tiaQY3#&XxEtH3l+*Gl%BjekL;kN&7{l3G ziF;9^zJe0b&nQXca}-8n9mbev3I+&JN1ON*sgLI3E3|lDA7rQp5RY3R1_4>T(M`D`slT({9|h zExR{4I3dtzYqKxr8jjm-*@kO{x9DEiG-5hxnITg~OWA z!-kHg`+J#fYPsIw(~n2JS{;k)kP|WO7)x-p>BWqop`SBC=>aEsZTh0=wvOBXYT;L> z`#YWgRi>I|EXye|7*m@u>)E&&Gdvw-Rv{<3d*=Dnj+z6xr9_w+AlgWAVJpONRf-1P$^Df&d9ki5Y5H3#Ok1S~=+V(VrrE8Qm=c`!OwUTE GZ1p!^4}N+8 delta 2316 zcmYM!du&rx0LSsuJ=kC}#$!O)qj$g<4z{uho7>n}m@UF$8Fwi-L$6;}ncDDt}-I5(oh$LB+o?#_!KIap~^o+;eZw<9E*K zxz6*?_g@{Cwa@Ukh5usyf6LU}|9@w5jG4ggIh=^!<1M_6ejLs0?gNiXon`R9bU;t|{iW=Nes^JHyj&q4eOX5YfTaJsc619{)xCD2i+W%oZ`PWnMu*Ivf0WDmQt8gd! z@hU2*eBy}V1YCeSP>FqojKK_}g*Q-pCY#(C3Z^&9J_&_v+`w&N}2WBd%a z5f`DNdJ(mmUPmp}m)MCna1OTdQZ2?&$Lttp;0ffUnUkmi4dPvoF`uFm?LWy?9S-4b zyoPo7HMz4I#>0<-q8g9tuod)LK7@+MLT#@4bLJO}$u#hj1=_ zf{fApiMcxe1y(8=FKV-up*B%7wqOVL;SRis*|b)Lzv2w^(#tMvMV;%5sE+4MOHF7c zY7cdxB7YT?$Z0I4e{+@s`^#KGKIR@5H9TQ@>by6hzW5X>nGLAu`%oQiPuIVTivDBF z!Y`0;%}~1j7HVSmP>KAF{o0kK<*DeZFwA`u>Rca3K4y>$8`@k&&HO$p%BhS}@2y5n zU>$0y`Y;>!;Tk-MO7btP!MPQwq`NA}|6wY&QPGU=;|RQiI?ul&N7ZD^OdX$zsF|1J zLiD5dKop>byVk$kk!&YacN9kF9^ zE9NAkL7S&hD-aG_>zuXW?nqVC4hQ0P$olWA)$abumvbJmYU)w>CA8RgpA#(8z_ z8{SDp!OiyCwRY5+pDwh960vx1Fzh5k$&22GO!vab=44yRN1hRn*wZCP$xL4{jVKF8fvP?AiPFZ8(YjGgEX&lsMv(uqcUXIl}+iY0>U zQ)5a`=SaoTjO34%u}rsUa%tA8gcWix_$+sC^{RSqHrgAQR#(D~#BD2NTS13Hq&wuq dEKM-j?L-2)p*}tFShah-x;Y~dcgy_6{{r-lGT8tC diff --git a/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.mo index c7f5701f02702fca61eea8d81fe37ce5f6284fe5..ed1ea35dfd4e7f0fec92acba788e6751ac127783 100644 GIT binary patch delta 2210 zcmb`{|4-Fb9LMo@fMUoO<%>d!elWlA{d)*ENXxW|L8PPFd+`;5ezrE)up%kVq=1AoRMyt2sbQTz)l@B!9g zDV0y)Vbt>w7j=CZ)$R%|Gz;2&3bj(|Z2FB4@9{z@_F)=ZmUewGEM(%^CcJHH> zVhGjoWmG0^;ZmGN#_+Im0VMEH?Nd<$QY`_2~@x-)Kc6<_4f~M!#P}zTS;3THlg|*#*KJAh5Q#%NMMUQSdER?gh%iK z7GW7_P^LT>Kp$?xTd0g>l3!xkdUUV~wP#+9)VH8AcmTKHQPcp&f)t*lpkY1-)ku{c zMHha6O4TH4Gu=Zi)e0(`u?kD^H0pSbV-!vx2gsk8r$E{huJMGB`|On!-1z zjy_)z-ekA2n)_L7!czVml+u1w$2U*`Z({}ijtaDr(Y=XlQA;v}+6xzOGyZ@lF@ZD5 zQU>iT1*PuOh+l^v*aYguNn~s`gBtN-cGTmz2DR4PQ190xUu)*F9{W%!{{*w}3#1F1 zL@n7Y#_IgfQP2wuo$!bYP&2B+k8wXfz+`&SUP3$;me zkStpfs{IS7)3OUUpa+$i;~3O=K0~1chmj3!X^bWp^N{7YUC89jk4ohrD!@h5Os+?q zMg@!|N&_yzt=NKPIE=+Og)U6UCjZ(@&u52cx+7v6YV#bz7(9kM@i^-I{)#VRd`|cn z?#3GKKSXtW6KP^;%%UBi!XtPdHIQtM(gNI_NB##Xv{11F?<4;~R!w=azK&jJuixwLcJ}+c94>oIqDwcaPie4NawXL=W_) xUyUtyN{U^jA3e*x+W72yB? delta 2187 zcmYM!4NR3)9LMoL2wfCGMM+*%9uNfqy@7#xGhjL2NNtF%(H3=stFT?T<6bTem)?=& zw3fMn`I0Sr*>KX@;%-8lY$jXFiY<)Bvdvk!k+mtG z#Mh9^#<{8M2~@jDe84PXDRa!WQ!x+e(;9I;da)dXsKLFDd|-L0W*N8=)ouf-zAj#0 zk6ApoU=AL@Wq1mca0KV#C0tB=yBcrsJ*M$OZ?hpC7h^GMV6~_YwqYjjL_V=*EW-dE zz_U1wIdoQvzhNFOOE>GmYHY?)%qPArnP;|8FR%c2qh=UJ&Fo10`E^vgcTr1m5!LYo zDigop0=$om!RAw$j7w4Nm!s-E@%pV8QG=ZnmSO|4oYon4KWe6jkipt%REExDD_%rm zSsqc9ayL?C+fW&7L=7;63fzxec8;6c4=*79O6eC=JcVDOHcc_pFT*Cx#aB^lIf&(W z1(liKQ61ky1x_J7T9Ry3zbkMHmY|lh6YKCOs{g5lX;2;A`T%Z%|1j8XcRw4FuRP36KN-}D)ix9d=u5t zE99Ll*%)rbNqh#=`H@gc{iu$ksDNWwg`c1T{fWJ((P~LvLhXrTSc~UzKl z4yjW0a@

`XSVZ!^qg|OVog8a5>&bt#tuAP2U$GmwC9Y#HUfI@5OvPj(lRnn4cgm|IEm~-8$xZm%cwwCI?Uhti z`&FpG6WMnCo;8`yru5_B;tmftFn$=NPcDm#(Yvwmbh*++3dM+N*5 z>+ue5#%iLj#XeMjqebLjyLXBT4<;AKHdQTZ#&vOcnEclr|}6)S`|B% zd+<@72T=W9Lz-9`vuVXD)Ii=YA^*t~zNX>?ev7*?z**zB$gZG+Q%ExG4@|*aqH^-A z5Va&5(Tnw{fkm+qU8~KWL@z2+Be)B{K?e)Bvy+s8&8P<5co+vzKRmhI>hN()#5dxe z#x$PK;#|Doj$UxxoRiw_YiaX3djsK)mS|5#bz*dVrf*j1-nI^3sLKfj!og-AZ-b84 z?|1eEp7*zPtPcA8-Y#E@^Y5o?`cGy}yVg48Ri4Uq{o(9<$`uu!%BtvF*){1o4S`^= zr_AXHIH7QJYwVMFwChC^iP7TH7n9sO#?Lu{@sAxsbp-?AZU}_CobEu#DTu}Ng*wB& Lg8w4E=WhQ8fv*MG diff --git a/mediagoblin/i18n/ia/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/ia/LC_MESSAGES/mediagoblin.mo index 55802ee2a5df92612502e4988b9f870a196212d3..c0a1ecb61f04c10c70234de6b2f19894caf3dbc9 100644 GIT binary patch delta 2207 zcmb`{|4-Fb9LMo@fPp9i5?_`0P$D42mn(4b0x@IBu-3-H*kbA~aMfE1?cQqwj;<|d z)*5qOYo@EQ+Qc>e#run`xv*biHFGkP+LWy?W^1eDhn&`CK3{z9)<4kQy`RT9=bn4M zyx-^CiQZp&qw_0M-ZfsMd{*=MIa#&;UT0Fx9-(>`^Y9D2h2LW>UQ9DviVN6;|KMiy z(AbFMsPE%EH1q{jzl->=S=8=Q=%V3YWK8QyH_O6qtjB&F!(+$~EOVLJO3Xv`t39!iWP2@YjA-2X)I-aTb^l_gEjaVK84z00JXD`L_Lb?cNCS1 zQ>cM2pdxVtv+)mP4U3ISAcHT}KL^#m4%P0(s0wWqim?MppZOEMgxYBsS**Q*c!)leH7E}tK#W8#h zNoCaTQP3gMB~`~PRE|qgA+10bZ7s+etp|DAFc0N=0(BN*s2xorZ#&OJzn?=L#@|ri zr*I+_k=2-@`@e<)X|zhzA!@A56+hr zahG+SYj|iO-KdQYCh8H?`Lj1EDCZ}UIqV!N60^vKu%A#n{0nsmlOA{br=i+QQ0>(T zJxEZk8I^(;P#fEh+UU!u!}vNzb)Sz=(0%?8wZhajZpiad3#mhea3gAgeW;1|qZW7= zm7)`vf^qD{^QbeERpv%?6Doya)LED)BmTv1haGqbwScd%1(Vjf*ZE0QY7e0gKR`w5JJeZPXr-WB6;s=WEvWl^0+aC) zCgBxaidQie=h0%fb93XfsWa*Ev9c$UGQ+`0zzK$((B7e;;Ly(4bXJ3R$O()@LjK{< zU~tGE3ho|tc7_7}i1SJ?Fc5HtcQ|_jgF(NuYd9R?Cr)^HM`WKr6o^fhH^#Gby~(l8 qs?OMS!P}_~PJNxv(-7+}ELFM5=UE>gExftxf1f%&S^nzcv=0F7f(z&X delta 2182 zcmb8ve`wTo9LMqZetGAn)9L29>D+hP+~wwOyV#}^oH}qeIqZjU7&KVBv#qXO+wF=C z#}Nb3LM3j2_KT3fND}hMMkt1r7$vk}NmQd~HH76KB@)P@=d1fdfAm+!ci+e7`}uyp zpC9kf`?Fue$HS?a75T3izfu0y@;9HSr+*lYy1V=qo(HRIdbWo9e&0@vdss1+trD?8#opFp)cjoOL} zsE)6rBJmrR;9tlbY&n$$Scz)C0af4T)^}n`4MG$u@lj+uZP0ZTwbF59vUUm;p?9zk zFCb%C6{9NT0i??IpdxqxHNgaG;52gCTin$CdRgYaX81EI%EO$LSw}0pV9_DY<9sVN# diff --git a/mediagoblin/i18n/it/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/it/LC_MESSAGES/mediagoblin.mo index 77bfbee9e6ccdac4c0dd271a3cb07c3aaedec425..1319a6058478deda7a3c86b62aaeb505fd741f87 100644 GIT binary patch delta 2207 zcmbW%e@xVM9LMpufFj5b<%fV|eyJoeM1Fbv5KCfVSmu~4l_u`MLyjTm?r?}@XM;a1 zTx*^&Hyv(m2{rknZfmo~0_PT48`G9lL;on2^AF87{;0K4&lh)F|MXY4yYJ)k`P}C| zKi==p=iY7pwK;eIIn5E%rRKEgL zdv&zE7PF~0;Tk-GkK<{K!x2ovE11Rnb~W1JCMNU6Bh0~t#SRQcZ!N4CH9#e1;x?p< z?ZHAkh$rz3&R`;gJ%c~vI!sB4M7aptsE=YE^IKA?SvnTs6Zkx8haS|pvLu~|I@CCxQ6Az%q9mNX#KArd%QAp;9J6MBFcmPk~ zr??r*2!kTkh5_{Ab9e_8v9-jPxhx+YtU{fc=4g8>DuTzb4hK*RmM;F=N>wh6Em(!6cpi1VzQGurMlO`yLM>z#$Chxtkv-X2!pcw<9HDTJ z!k1W!Be{{B-N!2G3H&K&VRg6#2T=o0;^KtpqCSn9Xc?>1bxuJ=W*?GObE8riz!Uf( zlB%FNTu$Y1J?b#IP&uwg7HhkZv8^3hqxBE|N1v7&b<|$}}iBCpWSb*x#fV{1lhfe#O$e*AM;wBu5wqK8W6Lm=M zBGI)uR0?9Ains#Ro`E`yr5MzGuBFh4yHO$g99fgyKrQ3}DnbiUbJs_9Sc%H*%cxYf zU>x@1etZLUW^SWySrXwPn6?$G@wI&7uN4l_pg)XDs7PEzrQ!$FfOA-n_fe;|`02=f zei4hQhp+~(M_sZZlB#D>sp-U1ID@)v`wAkdI9EXYb)PTLpf6H4Mkam~#kC^IvBD}E|5{8`$jnACu`$K!Ydj{jJ9x3~LnXkuk~MYrQQ-s5-s z{D-{VZojvy&pGV(xO<$VUQe6H@wGcgJcqn)r^6TM;U`YO*WT0X_Itv!8C|iVuL^gB zCbHj&FLz3ct4qs6jX8NLyQ)je!hJczN#U~mi!m8Z9nAS3bG!cE+~IFG+*q9YABpM^ A*8l(j delta 2194 zcmb8ve@I1I*OTxoVc4XcqptsQf*6YDUHn%tYn2Ue10=D~8*drheJR=52@ zTu;3li|{yZ!dEaAuV6OLU;*RXb@zn@T*U)DErc8_Krd=y&8Q9z;5uwWKCv#W!Vn(E z*YPG6(OD(_jwQG$$7~pPV;4?iDdXG5)n;q;05{`9s1**OR(8s*zkqu04OA+oP#xbu zMdDXnga06Nuv{9`uo(6J7F4_6ZQqYkz0gLX7z0Q;?U?HbYNeydWbGU(LhoQNP9bAi z38O0HwMdg4Kt-?}HNgmK;Bn-#3*7YnBB~G317oK zsuOqR?h|anA5ar4;YXqYdr%!u;GF@{M|~1C(D$fg{WB^;JD4@uwOyzbK7b=S|0gIY zSIejzCUID`sXVA0Z$>6-6-ZyU7n!3yj$AgvP2ZnGeSaPud=C||II6#8sSX-3w;)~uqy{CaM?H9l&fTR%G2neR&o|~u4gd?|HNdx zjVo{&GccWvFn+cuKQ^0jZDrO|!S23J=V)kXpgT6~*_|A_XI(I*@@U^cFf!;wLPO!M zAWy?iXMexb6FSo0H&7i8_IC~jyPZ3q){GZcw~a5Ze=cLYQ|I$HG>#7ymQt>-_c!=r o6NTrqHv~fA@Nktg5ON|zUA>9V5+l~c{N)qLu|pM~{qG_F1(F&7vj6}9 diff --git a/mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.mo index e2a241a8fb244e61c266aea04de80fc49f2c0a9a..39f3595b0100e5d851603afe8bcd22c4bbe6c03a 100644 GIT binary patch delta 2211 zcmb`{|4-Fb9LMo@fFZ~i1wjzW50%&@LAfBv4Q$1P!4?~4)0#wAyy~^QxXZObv)hIn zm1Wko=GNT8Ir0Z{=G|;rZrBfutxabwT2uU?)!6zX*S5Yd>-qBY+4={%yWGb)=bn4c z`Mlrn!|R)8Hpj0QWV~g(hWJ~;-?!=N{r5VRX||B=`&f*h;tYO`EAir7vn;%c4fq#! zqMyOlxF7X>k`FC?0X6R;-f0%M-)VF(@DH-4b!3~($8M~}Ew~qtAV0ADd1eJzjGE^| zjR(B(hp>eH23(B0@Gg7_Gw?mk!Be=1{p}-f!WGQrixigPt=kh=jM+NaD%1jNun1d_ zDfTF?z+T*sui{sj&0_cCH@Fn@^4uubU?2UHSi%05lW$gtHF!5ZjC#Tl>d6MZejGLL zO;jqzPzzr`MPeEk;0@#qw+H7yE?;VXA!@t|HQtDEHCkwtV=IzA3wrKEJ?Q{)SbG^2 zp`*A1$B?}&pIsI5rO1%2K}E0wb-+H<#>2?l4)dY;#}^QPh4fN!jre6D@votgONl$!j2o~A zU&OPx66*+qBGrcj7{&*28Wpi};>%uEi4HcQYUT-Vd&lzomm$Tb|hgX@hvlN}_i%Q5~g zjTst~s3$s8=Ke5+4fOxSZmi{>!$urNEqoP~g6~lCen!=TkJIToH=#BjM)tIWs1%;S zy*P!WGH%^mPWG@(s1U|bIUe!)hfoWQVjZ4G-gbizV z1kX;R4mN=~y8oAGXyR2=5#2-;$=^7FRgQa~&!STBN`+h1=kQtjQ>gp=2zQsJeSkX9 z7s%UY`Ot$E+~Y=U8LIC`)t{}Sp`1UC>}k7ERecz_5H^YmbrMyCNW#h0C!Gb)X39fcsGM zUqjW#7^+sz;A)&(=|*TR>UJH+r|`E*;;&q9VpT2B>p6%@#T%&ak6|00Kpo@<)P2sp z&%HhCv622E)ODUf2Y*3rSnPAJ^V6v7{3GfCmQ)dc-Dh8wTm8pSxtaD%p{hHb#HV8b z6`{4L5O!fJ_Fx!Cu@C1_K<(I%O4WxLz)Ps&%&K;4sim2Qauvn|j-VgQcnodWg=x4R zv+yy@#9p*Ss;DUO{NkMC^~_JQljjPm)A9$xv5*rUaH4x6k#J;tVtjsmW5fv!#-hRg z=+z&$F0e^j>yR<^>hJe2=IaE3)H!)l3B+pl#{$ICF27L_~Y}@`XMbs1l delta 2191 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 delta 2186 zcma*oe@NVQ9LMqZsq>sRb-LxWZGKJXOwF6FJJT^Y5}e5vE|u~h;nG`5>gAmmD2!_a zGU*o~VZ~M<8~Y(eC7Oe6)QZ>^MoKZFH8vQ@VnWm)Vo^O`yD#)_$N7DHzMt>s`}y&H ze?I4I$4~9?YdI-z8lO@AHu85nS$F?^&U($(aeEH$$0c0GTj;~ZG_%#{;S#_MY{AFS zkFO$M`+|$QUO=^5#8k7mrKOuaPDK{dr*&dB2C*6=sL35eUa-Opvm7i%wW~wbx48BD zaRc`~Sbzs{Grol>_$l6pXEBfQ?ULKz2Cm_Op5{X)=3yCXV!KftG~;^QhrD9lSczdg zh)3`W7SLG*{)UCPIn!(e8?YPav54_)W0qO29^ixcBx;2*)XEOK_phVcO`%dThw69% z6^RvGi+>|?uxu(<;U-l3VpM&-TfYb6YOs&OCTv5}X+y4~sFl8iOxE5;Md&2<;v6!T z6*8(q?nA1q85O}!)C8lbfhUl!z0XDMKUqus71FP%cnZHoZJIKcUx{7#0KSaM-(b?9I(w&OVZ@ER&o znS>*X>u?tyMn&u*G6!2k2XCVG%qrrp`ZcHsI@pLl)VR?&g&h>8aStvdU-L2DdTc_4 z>JVx(y@N{CSJ;I&aT_+$s0N2o$Ls_q;WTp6>_gOq=J6ws*=NX_EIveB>BGiw8Q;ZP z-4l1BWam*4Si&+);zz=d6{t`LQ7IU}0FI&t`WQR#jC-HOtQCPgR0>OxV;{GtDd>eM zx4~&tNY9{hd;zt|E}+7v;JbHIXt@J3l(O7nQmJWNj8j?UmQitMmUJ zg?k}GB_A9Z~Z36hPW20Vs} z^arSv&thCTS)ibEeHHug7gWgGi}{7Z9#qK2P!pL%f?=mn6S?Tte}n8RyN(+0Puz(~ zC5b(=8<)#wJlYn?fGhEb2I2MMdOiR0RJ( z{jj8#B|6@Zk8pnobz0_73%!l?nEX)U_%$?B&}M2wPPnf|`Pha;i>;BctNx%X<-#N>u6-tA6xpx$3Q5z8;4TvJo;56m3R_hl5cg(H!X lN@pOrU#`*t4PK=iC_!pM3{-^)| diff --git a/mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.mo index e78b8e3b001bb9fc065b7729c43ab0da1a0487e9..95d6d0ae141c335275f075991429810f61f667ac 100644 GIT binary patch delta 2204 zcmb`{|7+D%9LMo@chlM2+;`nt>StEd>74uitxc&dWk!qPLXtG@=AFAW@0EKuwrh+# zNUBLucAHHC1)(X!5p@3H-9Y{E(K`^R;`Sf1q)9ALn!Kx$pBn z?{m)mEjep^G zET^*y2T`9#c~j^~)VOoF*eq;+(rBUMA0(!=B%7sU8h10FId`AvrJr$8drqs zuaEaXgt)A*Aa)L$k2n2w!z7IkQHS$;9LqW17P zEW@LyicFybPNOEAMQz13RJ@zG74P5*e1x)X$K9y7r?CbvWl{eU8mSy{2OF>*cjFMg zi<_{5GN@9W7(_2_!8ugLR#IQ)vO;vQ4s~XB#rr!@73{+%JcLSMDoo=+8cK5;G$37e z26Mtc0@gRT@`l zB<9CTe-%~IHT)Q;QK5kX)Mmtk(U+mrY&hf-KwWh z-w&e_9l<2s|Kl_`4>pF%_#>>s&v5|%#_zDtiETk!f!R8q2k|hD;R{&CEDW^|Pz(A7 z*W)j!M6&OTEo?0+krK=d(`cqa4BLqc5JCkwhDvN4b=p5cmHs@cBA4R*^T>~*-9}Yp z$^Ef2l8RdC2GrrLL{+FBRp}iVR_Quu`0)U0uf9jN)8N+<(OYi*#xO|XO5gQM{e7Hy2( z=Q4EBUxiDt7L`adT4X*aCwehyDmnUI=0;aq(A(>Ayg?_>=ks}e`yyx4D{Fj?XP`IW z_6PQQeeQs_C*?pQ)(qIlcC&TSI* delta 2188 zcmb8ve@NVQ9LMpuo_6MM-E`A7{o2yprk+3Yw%Kx}<(zAU*@&wcn0HH;d3fhRO6%AH znT;6BYBdUCER04$U9AxY>&I$i4l)``YGPoCU{SKaDn`%O?x4Su^ZWRGKi}_tKJV}A z^ZDM?qt|@V+5D7OjK2~7*YLmO(%FB1lWwz>oPLId_#H0bB6@H-&Fp4O;^4&$?7$Xm z#21l|eaS&XUqanCjW?M^EiK(_2OT-cnC8P=?8Z6_p^7_+e8EaH%<{1Ub>9|Le@CLf z6IXNY$70-%CHNYq;3t@glemic?Ly*)pD~LIx>^L;xC$##h24!BpdAZv7xESB!72>m zetZM3U@?Pj#APhSl5DeKY{niugJsNbYjVt1=mOq~522ngf_kz;iSr|<`%a*i;xuaD zOQ)L^-Ers7)E{p(QuO^N>P7}X8CXspF9WI1gx;RxzUpGS(d*HH<*gS~hf znafIir6>39UcMQxf&9={6r;4OFFnd91}&ZmP#2)N3|@$#@ER)9igzL1%C|$?PohOcsriD`VJsT);VO z)H%5;((9T1_I$X;Y{|7Ey)$g|}mIdAz>`^EmH94IDrv z`W)`YQB;yYp$GFT;;(f}1^M52&*`{>3x`qBoJAG%4Qk@cs3rLo_2kRghX0@nYNeV^ z?7^-0F}C6|HlUYvqGsEND(DE-;xCot@1{|>KK@>ppnf1;LQQ-XwKTt@21sHdb$iRxZ;cxGt!N<;V&|3Y8{g^{6s_Bt#s3*YH zkkj4Y?>rfNqQ7sTIuz*d9t!xK8(*y%KeqacyTPgRHZ^VBuCH%u^v2#Sx{z7i o6%2)jtDJ$L6OQ!s#=nx7&0jH=92;1F%vI}S8t4B^nNr>UFEXeCV*mgE diff --git a/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.mo index c2044ccbb115fd60d7423191b672c46b414a452f..e0a70ea95a5fc3699829d852ad76e992d7380774 100644 GIT binary patch delta 2485 zcmYk-Yiv|S6u|L;MOrGQ(9-g5r_cv|(n5JHtyWqU2+=^R5)jGl_IA0j-MhK>E>Iq> zNqK3M8dv0H_`nCmfMVFhNRR}yiJKTfASfoq7-G;EK;RR`i2hG^4Q#gin>#Z*bLPy< z_TH*LUXA^nJ8ZAw)x+Op{(kkz)1%jk45h~M_z4!^SNI$LgfsAbrcxvD9?rqPaS6_( zayD*5X;1JWL!U+IcOHi;6;lr=ET-aLWK6X_qqhWBhcduC%*Q6A zi)zDaT!Y*2ZTu0l7_16!U=fZQmCAB026#S(#muip<|vhiwKx?QqO8zFS=pxaa}1^5 zdnj9R6lLJED4Dp9WAF|V!(inTkWHiX&qJxNM5&*PF)1`rn1U_H_9-LnI+T^VNU-Wn zlnm|1wRjYnOXV=Dq`U~JQu9zUxELkC0LsL@$XmV3hx9)(hWtxP&rtCSolFWx$Il6Aqwk#ch=F{=(<*A&$dmN!t=!jWX^roQqfU$bT(`Y>v3b zMr_B`_y(TB890kHNTvelqJ>Z6b(D-vA-~L}%24Bclryt3UEhI{!6>%ic9Z~;F$xPP zNSMz2w7sMrMx_bJ@KX1q$P>}df%2D7jX8*n8q!akINucf_#b9lamGSM`mlfbG_CU^^F ziw>it{v__i0VH!V72tBR?J9)Q@pY7e`qK6Lkl576C@Jhm=2BNs`rS>}KR}YBGB|Ov z!XlLM7NAVL6xmJHgK}2(V20fPgA}CW5tNlDumZovt#}(R<2s!>3r)qTJ?_T6)bByL z4JF)N7Ny=nj)gjoPvLo#fYr3r?U{lSXcZR5D6~*uTT};1q+3t|I)-wMPUA?tg0kXY zumpcc$w)R2vL%yI4rv*dVl~R)T#oX+RY)uDY&|f-g{3`aO~abra?HA+wBMLo7hKh8xh2XR!_+U^7;flYfb9U3qF^2M1G# zQhz*c0$X`LgS-c$kO`&}jcnC!lv{KPw!3t<*=ZSit?hbzMZ0#Fx6yFS z#K72)FWxi$QbvQWuk+7rh%cK^+(3DrzoEXWj#t)F!}V&~9V6_949|A_I%q_6BOi98 zd9Cer8&;?`V0R}@PMGTRwVFD9DYM+CLq_7^)sA)m!5SYZm5*3}prEu|yipaN?~bRaWV20+zm*wC6dj=eZv>P!3Tlz#TFI{yv@MZ6gYA{=-@gjh-a0ek^3;#F+5QhTC!d}^)RaX0nrQKuq}Gt8XKI%FG| z9-N17qXNE(Iz@kBVS+-=#MCd8g)EC{LPfd)70^ql*#-gIPaGaD27;wlP?XdSM{=TWJ?jpg_cY7NVIAPHs;PQjI^RKJLt z>3-A%j-mRyfE{=pbqpISQk!}!YH2>KApg@Td`?9(W=&2-*oq3^2^>hJSKs6L3eM;K zUgR=2xoMzGqSBJtI2U)JHsvL+KAo3Kd9Fg$Co0K*CWRAJ?7=?dGRvo?&h1uIq_3g^ zeIK*&7HTQJ!vg#jS6~)rR0DTlGroascmtKGa@Ms4A4Rr{*|v}ZmwAVqW_ktnPvR%k zFI`tPjd4F_;Fp+=H!v5!Mg?@YI{9AqH-qyw*nyzW>U84aK(f1FUV3u&XggzCXE1C> zV^-9ONBlN#BbF}|ver6lLcwr##18plcEB3=YK^;R%=PSk+Te9Ee9_-Tsgh57ao3waJS`6EfU0xedvQC84y;`F6;Txw}g{ z+&@bD2Dds^%(0&Jt+kV9%GM8ZTk{!vbzbh4%H>2Mxj;AMUraqqGjvZ6#E~*~ueo);}x5)9wLl!f(Ej!d13|eQ8p5GU= qVi8|Bx*-^|I)gmgOw;~vjs-O>qkSjn diff --git a/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.mo index 1976596794ad6bab665cadd747ebad6a558b0dd0..0e34144d2509f5c2236c8289db8299e66f3a9788 100644 GIT binary patch delta 4217 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 WFH!OHVUt9a5DRX5m>!hIQU3);V>6Bb delta 2620 zcmb8vd2Ccg9Ki9}Ezpx*lwQ*IwNP4mx7Ze1K>~%A5^kh6MsVAGZ5NilvIn#Xu3C*$ zLL`|GL@+_cfFQ)ULK~opM-XGsEtn851SN8)F;NtcX#Dk4cmqpuC_<@7v~j7zXl%sUSc%(_ zk9wDj41Esey&)WUDK(#tIAl!KjPdBea`d1Cw;%a}%8FJh5htU(Hyx$Faio7K zrgHDZblifO_$-dXevH9Wn8N((gOL}m;8-5W(=>?16wF5nY!=D@4LBYbB41IhScDdC z!M%79(;2J~f5I%xj8&=!XJRW3U^ers32{n|lLwfC%TQM6M_Jj{k^5&*-g^qp##veI58ShX7^LkF<~ zk0W!bEM}FImm*!N0VRXYC;@s=Cf3MD?c*Zvzn(z;C8ZzI(S#wCO_R^^i*Oa*h1*bS zc>v4t9hA)6LK*l^l!+rqkCY@0W!zkxhXp95T#t>|hcf;rGf zuoN$$WGa?)crgj@#jPkAJB!4ihS0#PD0^l!d6)jNC>bkZJTrEwVR@fz|` zrG#69^H5Ut7|LdP4y9CQa1~y~GMvLp73f1bW(UxYhmn(}j-muKfVXW*okrHA0t4jr zZW`zC8rsSC0=$Wm`YL`DoVX0%!+z|=%|wxna<*iJIar02D5Y@YTet;fK{MD06LAGf z3A?e(M*R=bkkou`44>1RC_hAzj4m~vjCoj$66k%%M?KAjvDK@1XAj{N?n5ZG{R5|A z9!E;TO~`MVT7w15ulzKo;y%2yE0Lrq8_S_gDjN-~!5Dl1 z*jo6L%qnzs@l$2jV zscAAh@JY9L5(JAPOd6M33vv|W?YH#i`R#h7{;t?a5~D~+Fwlm7t%OQM>EE9 z24%B!pu7-3$;2L%lAOdSd>`dppT~MkBMrOIfhPWr58`T$21BbsoQvO~1YXV#l==F~ z$-k`Z8#?4%-@?_{LHIJ!S(KVxK*m(xqNFmJda-|07RKUi+>A@H9X~=3R*}A5dr5m9>d{w8|_w$+tpd@G2ITI=``+q zwM6eqy%;{#D6guitk(XtY}yqSHI-HR`LvX*){SOMi|H}$8EMRN`n|rMR=4GMmRO$l z;Kj5^TT*Vm-)nk09qY^~-aPN{u=;lTdYu$;BnptPcL18DrBeQ5C_J#%9}? zI@4|XOno`~QN1;Kk`Co02T$c>*uv*_ceyQ(sc%dyiK@2@pJjA8+RfnfNpINo*JF!< z4SALJg!!Et9B!A>Xmhzu!`IVg>H|}D>%llfy9#Pz7MUB3B@VB5qvdhx69x4#i``B} z8R^K_uFR`n+Vtg?$J0|}bXtbj-`X*};NcSJ7fQ$L?6T|0D;(|Zq{-4sHs%_14bUKy8r$YUq g!O&|%PletLoiIWtL&rjcLyr$_Q*Nu>u>3yt4`{`%Qvd(} diff --git a/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.mo index 10699d0b39f87d1e1e9288dd7d4a8cd0dc5fcfc5..4e71eaa73ef7d50018f120429c17906180963b8d 100644 GIT binary patch delta 2204 zcmb`{|4-Fb9LMo@fM6sb-vm_TLn#CS%GWD5oDoXHA8IbPoTcr8SGY`|-FsP3+QniO zOIMRJm%3R^qNP93t(G;H_(Nl>#&B7yu%%Y~WQo~E%Tdo4e76397TE z?XSmd?wfHrcH%005##V3T!N=Ci}me{J75x%cyJwaaBhA8lQCL>twT+)9y4(RGQ=Ln z5_}x@;Q{;>6PfHDyn=a{oV<|bGHm631oK(nmZX@aV;SCw_oKehkNUD+_dbFecL-IA zVbsKDQJJ`esrVZb!+hr=NaCT!r=$9dQT-l_sIh@YE;bPtgNur`Rw&=G9M zVPq{!VO6C(59zY?s0=ot0&GPs{2cOYuW-@$w^GT!Qu-+!kKj4frpe~>OYlKd4WGtx zJdDc7IBLQP)Phr}Qd~pL_ZK$e9A@EW(zXS6pynMx4_-_s|7A3i*y0Y>VKeT)etaL- zVkK!%rdlzC0o;g}P#Mc5zpP~i=wK~s&un-5TTmJ7!3G>a1u!0=aW4&p`2f@*T{eJT zJc>%yH>l0@JE~MG=-i35Sb;}S$LkA>!3pF**#%S}Q#gJb#~b-3J55?wW8^%IX&Td5 zj}t2vYMRPFgBtGhQGsp4`|t#+=9f_m&Y;HqiONI?(fP0%6~ODL@o%C^IEu&dD)KyH z`#GGH-Cjb<}rbJBlj7$$YYclU(-WAJ~CCoZVXd33=6)-?dO0 zFKTaeqBdVpnqZiL3$G|0Yi+KiuLMCbV;jWAwCrE(jyJJ^m2WDt2|Zy>++85d3P3o3Irk$q+H z1q&s}!|mLAuo@4cHu*TJG;xIlj}?XFe?D?Lv`{Z9RfDJ+9YZ}I!A2ZKo!?ok$2E8J z&j#C2sXu{Q;Ct7_MP?6iUxWSlJbEypcwvuiEGGXt&y936;3ud6=3G-LxF%kW3TP*? z(X9iOffsNS9!5?41L}*@iE=YGp^o#*=*3~whh9d8+KoCIs?{pO-iviuiDxhtuc6NK z4C=+3n1GAQxC~v-%#2=07*C9TlvWy(5(mR5PX9Di>(=<5#d z3Uv8`fjxarThQ+dJ5L1st$wF_x6|q074SLj-JvkAIHB&{;U|4Te{?EiPwY@%_GChp tQ@+kyQ8lzRCtvLvZ$)LaFQ+XjdaK~sn2hFj*84x#-COiQ?2xat`Cs|W6_Ee{ delta 2188 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 delta 2184 zcmb8ve@NVQ9LMpux_R!Lzqg#W&95z;yIlSV-L&bP4yVFc&8Tc`XnIbE^YG4#6y&!0 zXHwQ5$H0k2jMj`{QG!Z18XL7mjM4@Yfguc}$e^+Q8cEMrexbiRzW056zMt>sK0n^? z&*wgCS$sLNl)mAj@fqa1o$v2)diw7(=P}#D<8^!t7jOlC#Uh+fFx!MN+{!T#o3Iwk za0I#R7B_W$7u9Yao!=%Bwpxk79?XP7N90pgX*9Gx8hOcC)SRI7{DPM z$3@Jhv#0O@=HSj`vjMEecAUjr#<%S$W*K^cPvCLX3d5+CU2vb@L$$k%O2ss)6yC>TtfNsW_M?v3RgA@J$VszLQ4^ZQhvhuqMh&=zI@SryRuMXmiogj}3eVu6&i^B#^c9WkCUiBnun-!oxGbUVGCB^ zDEe>#$%_4rHJDSdK3;19@sFqCT`EF&5f9=fmZudrqH^{M>JQ^ADpF&p2~MCQIE!_7 z8@0O=8FfEap(gq|>R4Y#ovwSRg{3rbsCBM)b5pLG@ig{fG5&*?;@8}#?I_4_-Ve}5WnEj$oi*f#EY#wjVUEZY|iXXR2ZEv+mopL##*jm_E3fnac; d(CH00p>TWG`mfvpGxA@Io%*d{=zk7)>>qm_{Y?M> diff --git a/mediagoblin/i18n/sr/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/sr/LC_MESSAGES/mediagoblin.mo index deb561048f3c58d4f92653ffdc207718568c5bee..ece8989faa31253cf521391d10627404560927f2 100644 GIT binary patch delta 2199 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 F{{V`)`oRDI diff --git a/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.mo index b2194da9540dbef606baddad5d7936a50347f5e1..c6cf0df960026e29789893073fcd7f3bcce36f51 100644 GIT binary patch delta 2203 zcmb`{`)`v~9LMpm8&H|Mz&1w9#62508ScKZvBBaHg=~?L#l;KBlrp-lxV74rNj0-1 zBS8}|xQoH?3zIO=;4d^WC@x`;7=k~Ld7H+8foMoH3X-T0Bl`Z(CjJ99?ejX%c}~ye z`#tCR_}SqtvCG+W#*9yt-~If4NY&kcpA#;#Ty8(WJUoln@LR0Fse8@l<8N4pe_<f}_YEEbBhAY|KNoD?!ya zChOOsoBIx2g8ldazK(P77^dS1T+I0PQL@1_X7Jz!dhpKO26RSiO{@~t!D?KDO-K`a z5=-%U9K?M%gK2d3FkZz1%*;$gxg5K=KaPcrZ|PZPIarQG_$X?HKGe!~CGTUXcEhMt zOrScRL`C8fF2rAvIoz$B3mH6A`y5pLN>qJ4##CscuoTxL=`(NA9jKLtk;&Q{s0baz zUYtP2vMfeb$P17vTaAif3u=O0sDX!&uN~l`_U|qv{tD@7DxStOs7>Q$`K8!~%HgY6 zg>R!Gavs&;Mbv<^s8sxd>hCsgz&p4YA17?B*oo@*IM(A=ImEx5LIzvh!L`_dowyrM zVg=R^21Tk1!|2CH@DeIwONlRISur};fZ8)#lJ(nA5!{LEaSv(&=VKJsP|!3t!dj%t z_Fy9(LWSyU)MmPlN>x6U&tU^r<3ZH%`V3R>B66VYbJRp;@yb0MZ)8pODPfhd?S%wmeiVta9Yq#zr;)FH!9}^giTdB4s7>c$$LVI);iw95vIc_y@k^BvQ~@nAk+4I7$5!?!Xvlm*Ck?$l`3? zvcwy8IcjgLLk--4WWhQyFGgX2f@ZcK8Ox5KLUs;y+-6WK`4P1VZz9pQTgm!G%M%eR zLOm}*O`rlb;3iZmoR^&{d?Gq)5XMJxz46mGxQ`~hDt>l>Ujfhz-H76_Tpps zK33v&EJJ5S;<&aUYq8g`9gpB{{2g`L21*ibZP&w;Hr6h_j zdRLK<%wK>NsCOrFt%JA&Qp2hJtdn5j)X`3fVbK#oL&I zf1@I#Woja6I5NJZD1O=XNm~5F?6Q=sus`B+{9z}wGZ63xdPdGHsI3n;zFm=!HyGOP z4|qfVzNpg^@_8f9i+*31&k1%r{l4vfuhSb0NBD~q4t7Ug_J(}%+1$R=k*IsxRqIq$ rHdfb;w0jCwu4}BWiAO!@8S(MrCsJ}ddKvHk9QWrHn^Q+#DBb)oWup%G delta 2188 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 delta 2190 zcmYM!e@xVM9LMnwhx|@XP!tH|i-wSg630Lx=a1NgFqWyyT+`ym8Q{f@JC24MJBrqH zj^U(|h?-@MlvbP9h>V)qa$2#ZbZ)u1xsZb`{i9l2y0xA!?z?q6?(zA2zMt>s^ZvX) zpATburk@VoOkePZ;d6+;9R7ZfRqg-JM1nC(sD6b@@n?+S92VnLqA^Jr!%sP;U@bm| zW!Q&&&A0q$=t)$+DU3HJWD=8&d7K6(GN##!i?AL`(2ol41LOshn_^5lu158%K(*J} z?N4DQ^(M^5Zd`$bxBx%L2XF$HF~7NNcesTMd7!6Rkc!K&5Ea-K)BrV@fpy3$rV)$K zhut`g*D;&HT=)m(;)+ybx^NRV;yC6pzsYeLvse#sCGJG6Fo;^&VY}Xs>i0fsE5=X* zPogq$2h;FhBnGpH#yDJ#>c0xrUTL>iV@Mt9C@jZa$ab1`+e4_8_9DTWw@?}S2%B*X znakudt5RN!G?^My2KS-@44@_+K)&WAKk9!rjr=R6KhUrTub>W1A=J&BI(hVWTD2*$8ER;}I;z zo2X2sl8yi_!OeIWm9a}m3}y-~oJO6QIP$Lcg{TZ#ScS!?c>^H|k5U-LYK$OXQ%ty( zxDA!6mr;jl2(?ugaX(JuBUnWzH+G<|*$6st6uD{U6I4LscsjEftrfF#r*%0aED5Vhye;UxZorTCr|9q=0J`CZh#Zph_*K~fgzpBCn)G%Ka1_yf*SY+DwX$86K4>W0$qt(nH$w!WxE5l!hLqV6Sq_EMV*R0fly!Jxwk3)&XCztts4sq%{o{ From 2ef0679790ca6ee15fea2c8e25449d5c54cf5036 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Sun, 4 Dec 2011 14:39:42 -0600 Subject: [PATCH 145/302] Fix button word-wrapping issue --- mediagoblin/static/css/base.css | 1 + 1 file changed, 1 insertion(+) diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css index 12d88ffa..961a51fc 100644 --- a/mediagoblin/static/css/base.css +++ b/mediagoblin/static/css/base.css @@ -129,6 +129,7 @@ a.mediagoblin_logo{ font-style: normal; font-weight: bold; font-size: 1em; + display: inline-block; } .button_action_highlight{ From 4752fdcf06764965d2f926d99f3831a968d8ea8d Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Sun, 4 Dec 2011 15:27:00 -0600 Subject: [PATCH 146/302] Filled in reason #3 to submit separate out celery. --- docs/source/production-deployments.rst | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/docs/source/production-deployments.rst b/docs/source/production-deployments.rst index 37251734..75acf9cf 100644 --- a/docs/source/production-deployments.rst +++ b/docs/source/production-deployments.rst @@ -23,7 +23,16 @@ deployments for several reasons: MediaGoblin application itself, this simplifies management and support better workload distribution. -3. ... additional reason here. .... +3. If your user submits something complex and it needs to process, + that's extra time your user has to sit around waiting when they + could get back immediately to doing things on the site. + Furthermore, if that processing step takes a long time, as it + certainly will for video, your user won't just be left waiting, + their connection will probably time out. + +Basically, if you're doing anything other than trivial images for a +small set of users (or something similarly trivial, like ascii art), +you want to switch over to doing a separate celery process. Build an :ref:`init script ` around the following command. From a085dda5d29a1353eaf7df3ddfc3a7c500af9186 Mon Sep 17 00:00:00 2001 From: tycho garen Date: Sun, 4 Dec 2011 17:06:54 -0500 Subject: [PATCH 147/302] DOCS:: #675 revision to deployment and production documents --- docs/source/deploying.rst | 25 ++------ docs/source/index.rst | 1 + docs/source/production-deployments.rst | 79 +++++++++++++++++--------- 3 files changed, 57 insertions(+), 48 deletions(-) diff --git a/docs/source/deploying.rst b/docs/source/deploying.rst index 9c0acf30..70b1a6af 100644 --- a/docs/source/deploying.rst +++ b/docs/source/deploying.rst @@ -239,26 +239,9 @@ example: :: Visit the site you've set up in your browser by visiting . You should see MediaGoblin! -Production MediaGoblin Deployments with Paste -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The instance configured with ``lazyserver`` is not ideal for a -production MediaGoblin deployment. Ideally, you should be able to use -a control script (i.e. init script.) to launch and restart the -MediaGoblin process. - -Use the following command as the basis for such a script: :: - - CELERY_ALWAYS_EAGER=true \ - /srv/mediagoblin.example.org/mediagoblin/bin/paster serve \ - /srv/mediagoblin.example.org/mediagoblin/paste.ini \ - --pid-file=/var/run/mediagoblin.pid \ - --server-name=fcgi fcgi_host=127.0.0.1 fcgi_port=26543 \ - .. note:: - The above configuration places MediaGoblin in "always eager" mode - with Celery. This is fine for development and smaller - deployments. However, for larger production deployments with larger - processing requirements, see the ":doc:`production-deployments`" - documentation. + The configuration described above is sufficient for development and + smaller deployments. However, for larger production deployments + with larger processing requirements, see the + ":doc:`production-deployments`" documentation. diff --git a/docs/source/index.rst b/docs/source/index.rst index e9f3993e..6ffe0974 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -14,6 +14,7 @@ Table of Contents: foreword about deploying + production-deployments configuration help theming diff --git a/docs/source/production-deployments.rst b/docs/source/production-deployments.rst index 75acf9cf..7bf26169 100644 --- a/docs/source/production-deployments.rst +++ b/docs/source/production-deployments.rst @@ -7,32 +7,54 @@ MediaGoblin in actual production environments. Consider ":doc:`deploying`" for a basic overview of how to deploy Media Goblin. -Celery ------- +Deploy with Paste +----------------- + +The instance configured with ``./lazyserver.sh`` is not ideal for a +production MediaGoblin deployment. Ideally, you should be able to use +an "init" or "control" script to launch and restart the MediaGoblin +process. + +Use the following command as the basis for such a script: :: + + CELERY_ALWAYS_EAGER=true \ + /srv/mediagoblin.example.org/mediagoblin/bin/paster serve \ + /srv/mediagoblin.example.org/mediagoblin/paste.ini \ + --pid-file=/var/run/mediagoblin.pid \ + --server-name=fcgi fcgi_host=127.0.0.1 fcgi_port=26543 \ + +The above configuration places MediaGoblin in "always eager" mode +with Celery, this means that submissions of content will be processed +synchronously, and the user will advance to the next page only after +processing is complete. If we take Celery out of "always eager mode," +the user will be able to immediately return to the MediaGoblin site +while processing is ongoing. In these cases, use the following command +as the basis for your script: :: + + CELERY_ALWAYS_EAGER=false \ + /srv/mediagoblin.example.org/mediagoblin/bin/paster serve \ + /srv/mediagoblin.example.org/mediagoblin/paste.ini \ + --pid-file=/var/run/mediagoblin.pid \ + --server-name=fcgi fcgi_host=127.0.0.1 fcgi_port=26543 \ + +Separate Celery +--------------- While the ``./lazyserer.sh`` configuration provides an efficient way to start using a MediaGoblin instance, it is not suitable for production deployments for several reasons: -1. In nearly every scenario, work on the Celery queue will need to - balance with the demands of other processes, and cannot proceed - synchronously. This is a particularly relevant problem if you use - MediaGoblin to host Video content. +In nearly every scenario, work on the Celery queue will need to +balance with the demands of other processes, and cannot proceed +synchronously. This is a particularly relevant problem if you use +MediaGoblin to host video content. Processing with Celery ought to be +operationally separate from the MediaGoblin application itself, this +simplifies management and support better workload distribution. -2. Processing with Celery ought to be operationally separate from the - MediaGoblin application itself, this simplifies management and - support better workload distribution. - -3. If your user submits something complex and it needs to process, - that's extra time your user has to sit around waiting when they - could get back immediately to doing things on the site. - Furthermore, if that processing step takes a long time, as it - certainly will for video, your user won't just be left waiting, - their connection will probably time out. - -Basically, if you're doing anything other than trivial images for a -small set of users (or something similarly trivial, like ascii art), -you want to switch over to doing a separate celery process. +Basically, if you're doing anything beyond a trivial workload, such as +image hosting for a small set of users, or have limited media types +such as "ASCII art" or icon sharing, you will need to run ``celeryd`` +as a separate process. Build an :ref:`init script ` around the following command. @@ -46,12 +68,15 @@ processes. .. _init-script: Use an Init Script -------------------- +------------------ -TODO insert init script here - -Other Concerns --------------- - -TODO What are they? +Look in your system's ``/etc/init.d/`` or ``/etc/rc.d/`` directory for +examples of how to build scripts that will start, stop, and restart +MediaGoblin and Celery. These scripts will vary by +distribution/operating system. In the future, MediaGoblin will provide +example scripts as examples. +.. TODO insert init script here +.. TODO are additional concernts ? + .. Other Concerns + .. -------------- From 38f102515a84c1da25a9dab56d2fe7731412f4f5 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Sun, 4 Dec 2011 23:58:58 -0600 Subject: [PATCH 148/302] Cloudfiles not actually a dependency, removing from setup.py If users want cloudfiles, they can always ./bin/easy_install it. --- setup.py | 1 - 1 file changed, 1 deletion(-) diff --git a/setup.py b/setup.py index ec672dd2..293f3f03 100644 --- a/setup.py +++ b/setup.py @@ -61,7 +61,6 @@ setup( 'webtest', 'ConfigObj', 'Markdown', - 'python-cloudfiles', ## For now we're expecting that users will install this from ## their package managers. # 'lxml', From bcc9ee3205dfc6bc2b5e5dacb09de89121eb3782 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Mon, 5 Dec 2011 08:35:42 -0600 Subject: [PATCH 149/302] Update the delete item to use the _id after all... it's the safest way. See http://bugs.foocorp.net/issues/695 --- mediagoblin/decorators.py | 2 +- mediagoblin/templates/mediagoblin/user_pages/media.html | 2 +- .../mediagoblin/user_pages/media_confirm_delete.html | 2 +- mediagoblin/tests/test_submission.py | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/mediagoblin/decorators.py b/mediagoblin/decorators.py index 56dddb44..269b0c2e 100644 --- a/mediagoblin/decorators.py +++ b/mediagoblin/decorators.py @@ -58,7 +58,7 @@ def user_may_delete_media(controller): """ def wrapper(request, *args, **kwargs): uploader = request.db.MediaEntry.find_one( - {'slug': request.matchdict['media']}).get_uploader() + {'_id': ObjectId(request.matchdict['media'])}).get_uploader() if not (request.user['is_admin'] or request.user._id == uploader._id): return exc.HTTPForbidden() diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html index c7818012..5039fb30 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media.html @@ -126,7 +126,7 @@

{% set delete_url = request.urlgen('mediagoblin.user_pages.media_confirm_delete', user= media.get_uploader().username, - media= media.slug) %} + media= media._id) %} {% trans %}Delete{% endtrans %}

{% endif %} diff --git a/mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html b/mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html index e36891d6..058351a5 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html @@ -23,7 +23,7 @@

diff --git a/mediagoblin/tests/test_submission.py b/mediagoblin/tests/test_submission.py index a3453f2f..7ea6c4bc 100644 --- a/mediagoblin/tests/test_submission.py +++ b/mediagoblin/tests/test_submission.py @@ -171,7 +171,7 @@ class TestSubmission: request.urlgen('mediagoblin.user_pages.media_confirm_delete', # No work: user=media.uploader().username, user=self.test_user['username'], - media=media.slug), + media=media._id), # no value means no confirm {}) @@ -191,7 +191,7 @@ class TestSubmission: request.urlgen('mediagoblin.user_pages.media_confirm_delete', # No work: user=media.uploader().username, user=self.test_user['username'], - media=media.slug), + media=media._id), {'confirm': 'y'}) response.follow() From 5b5b67cd5c82e743f7c656616c92841fae31b36f Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Mon, 5 Dec 2011 08:37:20 -0600 Subject: [PATCH 150/302] Update comment URLs to use the media slug. --- mediagoblin/templates/mediagoblin/user_pages/media.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html index 5039fb30..b811d161 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media.html @@ -86,7 +86,7 @@ + media = media.slug) }}#comment"> {{ comment.created.strftime("%I:%M%p %Y-%m-%d") }}

From 5a4e3ff1e2a0f2ed451bc191c1d44bcd694b8e75 Mon Sep 17 00:00:00 2001 From: Elrond Date: Mon, 14 Nov 2011 15:39:57 +0100 Subject: [PATCH 151/302] Dot-Notation for Users.username --- mediagoblin/auth/lib.py | 4 ++-- mediagoblin/auth/views.py | 10 +++++----- mediagoblin/db/models.py | 8 ++++---- mediagoblin/decorators.py | 2 +- mediagoblin/edit/views.py | 2 +- mediagoblin/gmg_commands/users.py | 2 +- mediagoblin/listings/views.py | 2 +- mediagoblin/submit/views.py | 2 +- mediagoblin/templates/mediagoblin/base.html | 6 +++--- .../templates/mediagoblin/edit/edit_profile.html | 4 ++-- .../templates/mediagoblin/user_pages/media.html | 4 ++-- mediagoblin/tests/test_submission.py | 4 ++-- mediagoblin/tests/test_tests.py | 2 +- mediagoblin/user_pages/views.py | 4 ++-- 14 files changed, 28 insertions(+), 28 deletions(-) diff --git a/mediagoblin/auth/lib.py b/mediagoblin/auth/lib.py index cf4a2b83..ee1ce12d 100644 --- a/mediagoblin/auth/lib.py +++ b/mediagoblin/auth/lib.py @@ -105,7 +105,7 @@ def send_verification_email(user, request): """ rendered_email = render_template( request, 'mediagoblin/auth/verification_email.txt', - {'username': user['username'], + {'username': user.username, 'verification_url': EMAIL_VERIFICATION_TEMPLATE.format( host=request.host, uri=request.urlgen('mediagoblin.auth.verify_email'), @@ -140,7 +140,7 @@ def send_fp_verification_email(user, request): """ rendered_email = render_template( request, 'mediagoblin/auth/fp_verification_email.txt', - {'username': user['username'], + {'username': user.username, 'verification_url': EMAIL_FP_VERIFICATION_TEMPLATE.format( host=request.host, uri=request.urlgen('mediagoblin.auth.verify_forgot_password'), diff --git a/mediagoblin/auth/views.py b/mediagoblin/auth/views.py index d01861d1..dab95b17 100644 --- a/mediagoblin/auth/views.py +++ b/mediagoblin/auth/views.py @@ -80,7 +80,7 @@ def register(request): if extra_validation_passes: # Create the user user = request.db.User() - user['username'] = username + user.username = username user['email'] = email user['pw_hash'] = auth_lib.bcrypt_gen_password_hash( request.POST['password']) @@ -98,7 +98,7 @@ def register(request): # message waiting for them to verify their email return redirect( request, 'mediagoblin.user_pages.user_home', - user=user['username']) + user=user.username) return render_to_response( request, @@ -186,7 +186,7 @@ def verify_email(request): return redirect( request, 'mediagoblin.user_pages.user_home', - user=user['username']) + user=user.username) def resend_activation(request): @@ -224,7 +224,7 @@ def resend_activation(request): _('Resent your verification email.')) return redirect( request, 'mediagoblin.user_pages.user_home', - user=request.user['username']) + user=request.user.username) def forgot_password(request): @@ -268,7 +268,7 @@ def forgot_password(request): return redirect( request, 'mediagoblin.user_pages.user_home', - user=user['username']) + user=user.username) # do not reveal whether or not there is a matching user return redirect(request, 'mediagoblin.auth.fp_email_sent') diff --git a/mediagoblin/db/models.py b/mediagoblin/db/models.py index 265fe36d..4af996b8 100644 --- a/mediagoblin/db/models.py +++ b/mediagoblin/db/models.py @@ -268,12 +268,12 @@ class MediaEntry(Document): if self.get('slug'): return urlgen( 'mediagoblin.user_pages.media_home', - user=uploader['username'], + user=uploader.username, media=self['slug']) else: return urlgen( 'mediagoblin.user_pages.media_home', - user=uploader['username'], + user=uploader.username, media=unicode(self._id)) def url_to_prev(self, urlgen): @@ -286,7 +286,7 @@ class MediaEntry(Document): '_id', ASCENDING).limit(1) if cursor.count(): return urlgen('mediagoblin.user_pages.media_home', - user=self.get_uploader()['username'], + user=self.get_uploader().username, media=unicode(cursor[0]['slug'])) def url_to_next(self, urlgen): @@ -300,7 +300,7 @@ class MediaEntry(Document): if cursor.count(): return urlgen('mediagoblin.user_pages.media_home', - user=self.get_uploader()['username'], + user=self.get_uploader().username, media=unicode(cursor[0]['slug'])) def get_uploader(self): diff --git a/mediagoblin/decorators.py b/mediagoblin/decorators.py index 269b0c2e..d6a054f8 100644 --- a/mediagoblin/decorators.py +++ b/mediagoblin/decorators.py @@ -40,7 +40,7 @@ def require_active_login(controller): request.user.get('status') == u'needs_email_verification': return redirect( request, 'mediagoblin.user_pages.user_home', - user=request.user['username']) + user=request.user.username) elif not request.user or request.user.get('status') != u'active': return exc.HTTPFound( location="%s?next=%s" % ( diff --git a/mediagoblin/edit/views.py b/mediagoblin/edit/views.py index 673409bd..61a61d4c 100644 --- a/mediagoblin/edit/views.py +++ b/mediagoblin/edit/views.py @@ -147,7 +147,7 @@ def edit_attachments(request, media): def edit_profile(request): # admins may edit any user profile given a username in the querystring edit_username = request.GET.get('username') - if request.user['is_admin'] and request.user['username'] != edit_username: + if request.user['is_admin'] and request.user.username != edit_username: user = request.db.User.find_one({'username': edit_username}) # No need to warn again if admin just submitted an edited profile if request.method != 'POST': diff --git a/mediagoblin/gmg_commands/users.py b/mediagoblin/gmg_commands/users.py index b437e839..e8426272 100644 --- a/mediagoblin/gmg_commands/users.py +++ b/mediagoblin/gmg_commands/users.py @@ -50,7 +50,7 @@ def adduser(args): else: # Create the user entry = db.User() - entry['username'] = unicode(args.username.lower()) + entry.username = unicode(args.username.lower()) entry['email'] = unicode(args.email) entry['pw_hash'] = auth_lib.bcrypt_gen_password_hash(args.password) entry['status'] = u'active' diff --git a/mediagoblin/listings/views.py b/mediagoblin/listings/views.py index 5a09de43..6b83ffcf 100644 --- a/mediagoblin/listings/views.py +++ b/mediagoblin/listings/views.py @@ -86,7 +86,7 @@ def tag_atom_feed(request): feed.add(entry.get('title'), entry.get('description_html'), content_type='html', - author=entry.get_uploader()['username'], + author=entry.get_uploader().username, updated=entry.get('created'), url=entry.url_for_self(request.urlgen)) diff --git a/mediagoblin/submit/views.py b/mediagoblin/submit/views.py index 3def44ce..6beb6b18 100644 --- a/mediagoblin/submit/views.py +++ b/mediagoblin/submit/views.py @@ -127,7 +127,7 @@ def submit_start(request): add_message(request, SUCCESS, _('Woohoo! Submitted!')) return redirect(request, "mediagoblin.user_pages.user_home", - user=request.user['username']) + user=request.user.username) except InvalidFileType, exc: submit_form.file.errors.append( _(u'Invalid file type.')) diff --git a/mediagoblin/templates/mediagoblin/base.html b/mediagoblin/templates/mediagoblin/base.html index 29639026..c06addd0 100644 --- a/mediagoblin/templates/mediagoblin/base.html +++ b/mediagoblin/templates/mediagoblin/base.html @@ -60,14 +60,14 @@ {# the following link should only appear when verification is needed #} {% if request.user.status == "needs_email_verification" %} {% trans %}Verify your email!{% endtrans %} {% endif %} - {{ request.user['username'] }} + user= request.user.username) }}"> + {{ request.user.username }} ({% trans %}log out{% endtrans %}) {% else %} diff --git a/mediagoblin/templates/mediagoblin/edit/edit_profile.html b/mediagoblin/templates/mediagoblin/edit/edit_profile.html index bf8fe5c1..2d5daa95 100644 --- a/mediagoblin/templates/mediagoblin/edit/edit_profile.html +++ b/mediagoblin/templates/mediagoblin/edit/edit_profile.html @@ -22,11 +22,11 @@ {% block mediagoblin_content %}

- {%- trans username=user['username'] -%} + {%- trans username=user.username -%} Editing {{ username }}'s profile {%- endtrans %}

diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html index b811d161..7fc60c3f 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media.html @@ -80,8 +80,8 @@ {% endautoescape %} - {{ comment_author['username'] }} + user = comment_author.username) }}"> + {{ comment_author.username }} {% trans %}at{% endtrans %} Date: Mon, 14 Nov 2011 18:54:52 +0100 Subject: [PATCH 154/302] Dot-Notation for Users.email_verified --- mediagoblin/auth/views.py | 6 +++--- mediagoblin/gmg_commands/users.py | 2 +- mediagoblin/tests/test_auth.py | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/mediagoblin/auth/views.py b/mediagoblin/auth/views.py index 63bf9a91..2d29d0a5 100644 --- a/mediagoblin/auth/views.py +++ b/mediagoblin/auth/views.py @@ -168,7 +168,7 @@ def verify_email(request): if user and user['verification_key'] == unicode(request.GET['token']): user[u'status'] = u'active' - user[u'email_verified'] = True + user.email_verified = True user[u'verification_key'] = None user.save() @@ -249,7 +249,7 @@ def forgot_password(request): {'email': request.POST['username']}) if user: - if user['email_verified'] and user['status'] == 'active': + if user.email_verified and user['status'] == 'active': user[u'fp_verification_key'] = unicode(uuid.uuid4()) user[u'fp_token_expire'] = datetime.datetime.now() + \ datetime.timedelta(days=10) @@ -304,7 +304,7 @@ def verify_forgot_password(request): if ((user and user['fp_verification_key'] and user['fp_verification_key'] == unicode(formdata_token) and datetime.datetime.now() < user['fp_token_expire'] - and user['email_verified'] and user['status'] == 'active')): + and user.email_verified and user['status'] == 'active')): cp_form = auth_forms.ChangePassForm(formdata_vars) diff --git a/mediagoblin/gmg_commands/users.py b/mediagoblin/gmg_commands/users.py index 6084f9d7..88895661 100644 --- a/mediagoblin/gmg_commands/users.py +++ b/mediagoblin/gmg_commands/users.py @@ -54,7 +54,7 @@ def adduser(args): entry.email = unicode(args.email) entry.pw_hash = auth_lib.bcrypt_gen_password_hash(args.password) entry['status'] = u'active' - entry['email_verified'] = True + entry.email_verified = True entry.save(validate=True) print "User created (and email marked as verified)" diff --git a/mediagoblin/tests/test_auth.py b/mediagoblin/tests/test_auth.py index 2faf0f25..ad9a5bca 100644 --- a/mediagoblin/tests/test_auth.py +++ b/mediagoblin/tests/test_auth.py @@ -163,7 +163,7 @@ def test_register_views(test_app): {'username': 'happygirl'}) assert new_user assert new_user['status'] == u'needs_email_verification' - assert new_user['email_verified'] == False + assert new_user.email_verified == False ## Make sure user is logged in request = template.TEMPLATE_TEST_CONTEXT[ @@ -203,7 +203,7 @@ def test_register_views(test_app): {'username': 'happygirl'}) assert new_user assert new_user['status'] == u'needs_email_verification' - assert new_user['email_verified'] == False + assert new_user.email_verified == False ## Verify the email activation works template.clear_test_template_context() @@ -217,7 +217,7 @@ def test_register_views(test_app): {'username': 'happygirl'}) assert new_user assert new_user['status'] == u'active' - assert new_user['email_verified'] == True + assert new_user.email_verified == True # Uniqueness checks # ----------------- From 7a3d00ec217cc3fd44788b9d8c63ab9f7b1d05a7 Mon Sep 17 00:00:00 2001 From: Elrond Date: Mon, 14 Nov 2011 19:01:26 +0100 Subject: [PATCH 155/302] Dot-Notation for Users.status --- mediagoblin/auth/views.py | 6 +++--- mediagoblin/gmg_commands/users.py | 2 +- mediagoblin/templates/mediagoblin/base.html | 2 +- mediagoblin/tests/test_auth.py | 6 +++--- mediagoblin/user_pages/views.py | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/mediagoblin/auth/views.py b/mediagoblin/auth/views.py index 2d29d0a5..caf9835a 100644 --- a/mediagoblin/auth/views.py +++ b/mediagoblin/auth/views.py @@ -167,7 +167,7 @@ def verify_email(request): {'_id': ObjectId(unicode(request.GET['userid']))}) if user and user['verification_key'] == unicode(request.GET['token']): - user[u'status'] = u'active' + user.status = u'active' user.email_verified = True user[u'verification_key'] = None @@ -249,7 +249,7 @@ def forgot_password(request): {'email': request.POST['username']}) if user: - if user.email_verified and user['status'] == 'active': + if user.email_verified and user.status == 'active': user[u'fp_verification_key'] = unicode(uuid.uuid4()) user[u'fp_token_expire'] = datetime.datetime.now() + \ datetime.timedelta(days=10) @@ -304,7 +304,7 @@ def verify_forgot_password(request): if ((user and user['fp_verification_key'] and user['fp_verification_key'] == unicode(formdata_token) and datetime.datetime.now() < user['fp_token_expire'] - and user.email_verified and user['status'] == 'active')): + and user.email_verified and user.status == 'active')): cp_form = auth_forms.ChangePassForm(formdata_vars) diff --git a/mediagoblin/gmg_commands/users.py b/mediagoblin/gmg_commands/users.py index 88895661..7b23ba34 100644 --- a/mediagoblin/gmg_commands/users.py +++ b/mediagoblin/gmg_commands/users.py @@ -53,7 +53,7 @@ def adduser(args): entry.username = unicode(args.username.lower()) entry.email = unicode(args.email) entry.pw_hash = auth_lib.bcrypt_gen_password_hash(args.password) - entry['status'] = u'active' + entry.status = u'active' entry.email_verified = True entry.save(validate=True) diff --git a/mediagoblin/templates/mediagoblin/base.html b/mediagoblin/templates/mediagoblin/base.html index c06addd0..16569f03 100644 --- a/mediagoblin/templates/mediagoblin/base.html +++ b/mediagoblin/templates/mediagoblin/base.html @@ -48,7 +48,7 @@ >{% trans %}MediaGoblin logo{% endtrans %} {% endblock %} - {% if request.user and request.user['status'] == 'active' %} + {% if request.user and request.user.status == 'active' %} {% trans %}Submit media{% endtrans %} diff --git a/mediagoblin/tests/test_auth.py b/mediagoblin/tests/test_auth.py index ad9a5bca..bd79a407 100644 --- a/mediagoblin/tests/test_auth.py +++ b/mediagoblin/tests/test_auth.py @@ -162,7 +162,7 @@ def test_register_views(test_app): new_user = mg_globals.database.User.find_one( {'username': 'happygirl'}) assert new_user - assert new_user['status'] == u'needs_email_verification' + assert new_user.status == u'needs_email_verification' assert new_user.email_verified == False ## Make sure user is logged in @@ -202,7 +202,7 @@ def test_register_views(test_app): new_user = mg_globals.database.User.find_one( {'username': 'happygirl'}) assert new_user - assert new_user['status'] == u'needs_email_verification' + assert new_user.status == u'needs_email_verification' assert new_user.email_verified == False ## Verify the email activation works @@ -216,7 +216,7 @@ def test_register_views(test_app): new_user = mg_globals.database.User.find_one( {'username': 'happygirl'}) assert new_user - assert new_user['status'] == u'active' + assert new_user.status == u'active' assert new_user.email_verified == True # Uniqueness checks diff --git a/mediagoblin/user_pages/views.py b/mediagoblin/user_pages/views.py index ad33479b..4b311822 100644 --- a/mediagoblin/user_pages/views.py +++ b/mediagoblin/user_pages/views.py @@ -40,7 +40,7 @@ def user_home(request, page): 'username': request.matchdict['user']}) if not user: return render_404(request) - elif user['status'] != u'active': + elif user.status != u'active': return render_to_response( request, 'mediagoblin/user_pages/user.html', @@ -254,7 +254,7 @@ def processing_panel(request): # Make sure the user exists and is active if not user: return render_404(request) - elif user['status'] != u'active': + elif user.status != u'active': return render_to_response( request, 'mediagoblin/user_pages/user.html', From 00bb95502e01f8c8fcaa5652889a5ed423051d7c Mon Sep 17 00:00:00 2001 From: Elrond Date: Mon, 14 Nov 2011 19:04:13 +0100 Subject: [PATCH 156/302] Dot-Notation for Users.verification_key --- mediagoblin/auth/lib.py | 2 +- mediagoblin/auth/views.py | 6 +++--- mediagoblin/tests/test_auth.py | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/mediagoblin/auth/lib.py b/mediagoblin/auth/lib.py index 24992094..d03f7af0 100644 --- a/mediagoblin/auth/lib.py +++ b/mediagoblin/auth/lib.py @@ -110,7 +110,7 @@ def send_verification_email(user, request): host=request.host, uri=request.urlgen('mediagoblin.auth.verify_email'), userid=unicode(user._id), - verification_key=user['verification_key'])}) + verification_key=user.verification_key)}) # TODO: There is no error handling in place send_email( diff --git a/mediagoblin/auth/views.py b/mediagoblin/auth/views.py index caf9835a..d7e8d1bf 100644 --- a/mediagoblin/auth/views.py +++ b/mediagoblin/auth/views.py @@ -166,10 +166,10 @@ def verify_email(request): user = request.db.User.find_one( {'_id': ObjectId(unicode(request.GET['userid']))}) - if user and user['verification_key'] == unicode(request.GET['token']): + if user and user.verification_key == unicode(request.GET['token']): user.status = u'active' user.email_verified = True - user[u'verification_key'] = None + user.verification_key = None user.save() @@ -212,7 +212,7 @@ def resend_activation(request): return redirect(request, "mediagoblin.user_pages.user_home", user=request.user['username']) - request.user[u'verification_key'] = unicode(uuid.uuid4()) + request.user.verification_key = unicode(uuid.uuid4()) request.user.save() email_debug_message(request) diff --git a/mediagoblin/tests/test_auth.py b/mediagoblin/tests/test_auth.py index bd79a407..7cb867d7 100644 --- a/mediagoblin/tests/test_auth.py +++ b/mediagoblin/tests/test_auth.py @@ -187,7 +187,7 @@ def test_register_views(test_app): assert parsed_get_params['userid'] == [ unicode(new_user._id)] assert parsed_get_params['token'] == [ - new_user['verification_key']] + new_user.verification_key] ## Try verifying with bs verification key, shouldn't work template.clear_test_template_context() From bec591d85b1e4695024b54bbd902559ec7727ea6 Mon Sep 17 00:00:00 2001 From: Elrond Date: Mon, 14 Nov 2011 19:08:43 +0100 Subject: [PATCH 157/302] Dot-Notation for Users.is_admin --- mediagoblin/decorators.py | 2 +- mediagoblin/edit/lib.py | 2 +- mediagoblin/edit/views.py | 4 ++-- mediagoblin/gmg_commands/users.py | 2 +- mediagoblin/templates/mediagoblin/user_pages/media.html | 4 ++-- mediagoblin/templates/mediagoblin/user_pages/user.html | 2 +- mediagoblin/user_pages/views.py | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/mediagoblin/decorators.py b/mediagoblin/decorators.py index d6a054f8..229664d7 100644 --- a/mediagoblin/decorators.py +++ b/mediagoblin/decorators.py @@ -59,7 +59,7 @@ def user_may_delete_media(controller): def wrapper(request, *args, **kwargs): uploader = request.db.MediaEntry.find_one( {'_id': ObjectId(request.matchdict['media'])}).get_uploader() - if not (request.user['is_admin'] or + if not (request.user.is_admin or request.user._id == uploader._id): return exc.HTTPForbidden() diff --git a/mediagoblin/edit/lib.py b/mediagoblin/edit/lib.py index 458b704e..4ce2d42f 100644 --- a/mediagoblin/edit/lib.py +++ b/mediagoblin/edit/lib.py @@ -19,6 +19,6 @@ def may_edit_media(request, media): """Check, if the request's user may edit the media details""" if media['uploader'] == request.user._id: return True - if request.user['is_admin']: + if request.user.is_admin: return True return False diff --git a/mediagoblin/edit/views.py b/mediagoblin/edit/views.py index 61a61d4c..e766b6d8 100644 --- a/mediagoblin/edit/views.py +++ b/mediagoblin/edit/views.py @@ -78,7 +78,7 @@ def edit_media(request, media): return exc.HTTPFound( location=media.url_for_self(request.urlgen)) - if request.user['is_admin'] \ + if request.user.is_admin \ and media['uploader'] != request.user._id \ and request.method != 'POST': messages.add_message( @@ -147,7 +147,7 @@ def edit_attachments(request, media): def edit_profile(request): # admins may edit any user profile given a username in the querystring edit_username = request.GET.get('username') - if request.user['is_admin'] and request.user.username != edit_username: + if request.user.is_admin and request.user.username != edit_username: user = request.db.User.find_one({'username': edit_username}) # No need to warn again if admin just submitted an edited profile if request.method != 'POST': diff --git a/mediagoblin/gmg_commands/users.py b/mediagoblin/gmg_commands/users.py index 7b23ba34..4bfe30a5 100644 --- a/mediagoblin/gmg_commands/users.py +++ b/mediagoblin/gmg_commands/users.py @@ -73,7 +73,7 @@ def makeadmin(args): user = db.User.one({'username': unicode(args.username.lower())}) if user: - user['is_admin'] = True + user.is_admin = True user.save() print 'The user is now Admin' else: diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html index 7fc60c3f..89fd104d 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media.html @@ -116,7 +116,7 @@ {% include "mediagoblin/utils/prev_next.html" %} {% if media['uploader'] == request.user._id or - request.user['is_admin'] %} + request.user.is_admin %}

{% set edit_url = request.urlgen('mediagoblin.edit.edit_media', user= media.get_uploader().username, @@ -146,7 +146,7 @@ {% if app_config['allow_attachments'] and (media['uploader'] == request.user._id - or request.user['is_admin']) %} + or request.user.is_admin) %}

{% include "mediagoblin/utils/profile.html" %} - {% if request.user._id == user._id or request.user['is_admin'] %} + {% if request.user._id == user._id or request.user.is_admin %} {%- trans %}Edit profile{% endtrans -%} diff --git a/mediagoblin/user_pages/views.py b/mediagoblin/user_pages/views.py index 4b311822..dc549567 100644 --- a/mediagoblin/user_pages/views.py +++ b/mediagoblin/user_pages/views.py @@ -191,7 +191,7 @@ def media_confirm_delete(request, media): return exc.HTTPFound( location=media.url_for_self(request.urlgen)) - if ((request.user[u'is_admin'] and + if ((request.user.is_admin and request.user._id != media.get_uploader()._id)): messages.add_message( request, messages.WARNING, From a24e5133ed9ee0845e854478da9a88f85e755f70 Mon Sep 17 00:00:00 2001 From: Elrond Date: Mon, 14 Nov 2011 19:16:02 +0100 Subject: [PATCH 158/302] Dot-Notation for Users.url --- mediagoblin/edit/views.py | 2 +- mediagoblin/templates/mediagoblin/user_pages/user.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mediagoblin/edit/views.py b/mediagoblin/edit/views.py index e766b6d8..cbae9cc3 100644 --- a/mediagoblin/edit/views.py +++ b/mediagoblin/edit/views.py @@ -176,7 +176,7 @@ def edit_profile(request): {'user': user, 'form': form}) - user['url'] = unicode(request.POST['url']) + user.url = unicode(request.POST['url']) user['bio'] = unicode(request.POST['bio']) if password_matches: diff --git a/mediagoblin/templates/mediagoblin/user_pages/user.html b/mediagoblin/templates/mediagoblin/user_pages/user.html index d0f3bced..b952e88c 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/user.html +++ b/mediagoblin/templates/mediagoblin/user_pages/user.html @@ -89,7 +89,7 @@ {%- trans username=user.username %}{{ username }}'s profile{% endtrans -%} - {% if not user['url'] and not user['bio'] %} + {% if not user.url and not user.bio %} {% if request.user._id == user._id %}

From 4b77f86ab46c54a41a250ad1d8cec82214b67545 Mon Sep 17 00:00:00 2001 From: Elrond Date: Mon, 14 Nov 2011 19:19:54 +0100 Subject: [PATCH 159/302] Dot-Notation for Users.bio and .bio_html --- mediagoblin/edit/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mediagoblin/edit/views.py b/mediagoblin/edit/views.py index cbae9cc3..4e8c3686 100644 --- a/mediagoblin/edit/views.py +++ b/mediagoblin/edit/views.py @@ -177,13 +177,13 @@ def edit_profile(request): 'form': form}) user.url = unicode(request.POST['url']) - user['bio'] = unicode(request.POST['bio']) + user.bio = unicode(request.POST['bio']) if password_matches: user['pw_hash'] = auth_lib.bcrypt_gen_password_hash( request.POST['new_password']) - user['bio_html'] = cleaned_markdown_conversion(user['bio']) + user.bio_html = cleaned_markdown_conversion(user['bio']) user.save() From dc39e4555c9e104ae9d7b38f231a848fe106d1a0 Mon Sep 17 00:00:00 2001 From: Elrond Date: Mon, 14 Nov 2011 19:21:33 +0100 Subject: [PATCH 160/302] Dot-Notation for Users.fp_verification_key --- mediagoblin/auth/lib.py | 2 +- mediagoblin/auth/views.py | 8 ++++---- mediagoblin/tests/test_auth.py | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/mediagoblin/auth/lib.py b/mediagoblin/auth/lib.py index d03f7af0..c0af3b5b 100644 --- a/mediagoblin/auth/lib.py +++ b/mediagoblin/auth/lib.py @@ -145,7 +145,7 @@ def send_fp_verification_email(user, request): host=request.host, uri=request.urlgen('mediagoblin.auth.verify_forgot_password'), userid=unicode(user._id), - fp_verification_key=user['fp_verification_key'])}) + fp_verification_key=user.fp_verification_key)}) # TODO: There is no error handling in place send_email( diff --git a/mediagoblin/auth/views.py b/mediagoblin/auth/views.py index d7e8d1bf..633ceef4 100644 --- a/mediagoblin/auth/views.py +++ b/mediagoblin/auth/views.py @@ -250,7 +250,7 @@ def forgot_password(request): if user: if user.email_verified and user.status == 'active': - user[u'fp_verification_key'] = unicode(uuid.uuid4()) + user.fp_verification_key = unicode(uuid.uuid4()) user[u'fp_token_expire'] = datetime.datetime.now() + \ datetime.timedelta(days=10) user.save() @@ -301,8 +301,8 @@ def verify_forgot_password(request): return render_404(request) # check if we have a real user and correct token - if ((user and user['fp_verification_key'] and - user['fp_verification_key'] == unicode(formdata_token) and + if ((user and user.fp_verification_key and + user.fp_verification_key == unicode(formdata_token) and datetime.datetime.now() < user['fp_token_expire'] and user.email_verified and user.status == 'active')): @@ -311,7 +311,7 @@ def verify_forgot_password(request): if request.method == 'POST' and cp_form.validate(): user.pw_hash = auth_lib.bcrypt_gen_password_hash( request.POST['password']) - user[u'fp_verification_key'] = None + user.fp_verification_key = None user[u'fp_token_expire'] = None user.save() diff --git a/mediagoblin/tests/test_auth.py b/mediagoblin/tests/test_auth.py index 7cb867d7..2dcb5c14 100644 --- a/mediagoblin/tests/test_auth.py +++ b/mediagoblin/tests/test_auth.py @@ -270,7 +270,7 @@ def test_register_views(test_app): # user should have matching parameters new_user = mg_globals.database.User.find_one({'username': 'happygirl'}) assert parsed_get_params['userid'] == [unicode(new_user._id)] - assert parsed_get_params['token'] == [new_user['fp_verification_key']] + assert parsed_get_params['token'] == [new_user.fp_verification_key] ### The forgotten password token should be set to expire in ~ 10 days # A few ticks have expired so there are only 9 full days left... From 2d540fed8b511c76819a836da3d62875d20b6547 Mon Sep 17 00:00:00 2001 From: Elrond Date: Mon, 14 Nov 2011 19:24:15 +0100 Subject: [PATCH 161/302] Dot-Notation for Users.fp_token_expire --- mediagoblin/auth/views.py | 6 +++--- mediagoblin/tests/test_auth.py | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/mediagoblin/auth/views.py b/mediagoblin/auth/views.py index 633ceef4..919aa3cd 100644 --- a/mediagoblin/auth/views.py +++ b/mediagoblin/auth/views.py @@ -251,7 +251,7 @@ def forgot_password(request): if user: if user.email_verified and user.status == 'active': user.fp_verification_key = unicode(uuid.uuid4()) - user[u'fp_token_expire'] = datetime.datetime.now() + \ + user.fp_token_expire = datetime.datetime.now() + \ datetime.timedelta(days=10) user.save() @@ -303,7 +303,7 @@ def verify_forgot_password(request): # check if we have a real user and correct token if ((user and user.fp_verification_key and user.fp_verification_key == unicode(formdata_token) and - datetime.datetime.now() < user['fp_token_expire'] + datetime.datetime.now() < user.fp_token_expire and user.email_verified and user.status == 'active')): cp_form = auth_forms.ChangePassForm(formdata_vars) @@ -312,7 +312,7 @@ def verify_forgot_password(request): user.pw_hash = auth_lib.bcrypt_gen_password_hash( request.POST['password']) user.fp_verification_key = None - user[u'fp_token_expire'] = None + user.fp_token_expire = None user.save() return redirect(request, 'mediagoblin.auth.fp_changed_success') diff --git a/mediagoblin/tests/test_auth.py b/mediagoblin/tests/test_auth.py index 2dcb5c14..d3b8caf1 100644 --- a/mediagoblin/tests/test_auth.py +++ b/mediagoblin/tests/test_auth.py @@ -274,7 +274,7 @@ def test_register_views(test_app): ### The forgotten password token should be set to expire in ~ 10 days # A few ticks have expired so there are only 9 full days left... - assert (new_user['fp_token_expire'] - datetime.datetime.now()).days == 9 + assert (new_user.fp_token_expire - datetime.datetime.now()).days == 9 ## Try using a bs password-changing verification key, shouldn't work template.clear_test_template_context() @@ -285,12 +285,12 @@ def test_register_views(test_app): ## Try using an expired token to change password, shouldn't work template.clear_test_template_context() - real_token_expiration = new_user['fp_token_expire'] - new_user['fp_token_expire'] = datetime.datetime.now() + real_token_expiration = new_user.fp_token_expire + new_user.fp_token_expire = datetime.datetime.now() new_user.save() response = test_app.get("%s?%s" % (path, get_params), status=404) assert_equal(response.status, '404 Not Found') - new_user['fp_token_expire'] = real_token_expiration + new_user.fp_token_expire = real_token_expiration new_user.save() ## Verify step 1 of password-change works -- can see form to change password From 4ec5717a173803e6ccebf7fced1e5127c8b52caa Mon Sep 17 00:00:00 2001 From: Elrond Date: Mon, 21 Nov 2011 12:56:26 +0100 Subject: [PATCH 162/302] Dot-Notation: tests/test_edit.py convert tests/test_edit.py over to Dot-Notation. It only accesses the User object. --- mediagoblin/tests/test_edit.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mediagoblin/tests/test_edit.py b/mediagoblin/tests/test_edit.py index c29ddfe9..0cf71e9b 100644 --- a/mediagoblin/tests/test_edit.py +++ b/mediagoblin/tests/test_edit.py @@ -44,7 +44,7 @@ def test_change_password(test_app): # test_user has to be fetched again in order to have the current values test_user = mg_globals.database.User.one({'username': 'chris'}) - assert bcrypt_check_password('123456', test_user['pw_hash']) + assert bcrypt_check_password('123456', test_user.pw_hash) # test that the password cannot be changed if the given old_password # is wrong @@ -59,7 +59,7 @@ def test_change_password(test_app): test_user = mg_globals.database.User.one({'username': 'chris'}) - assert not bcrypt_check_password('098765', test_user['pw_hash']) + assert not bcrypt_check_password('098765', test_user.pw_hash) @setup_fresh_app @@ -76,8 +76,8 @@ def change_bio_url(test_app): test_user = mg_globals.database.User.one({'username': 'chris'}) - assert test_user['bio'] == u'I love toast!' - assert test_user['url'] == u'http://dustycloud.org/' + assert test_user.bio == u'I love toast!' + assert test_user.url == u'http://dustycloud.org/' # test changing the bio and the URL inproperly too_long_bio = 150 * 'T' + 150 * 'o' + 150 * 'a' + 150 * 's' + 150* 't' From 0547843020643febbdcbfa33377fd48f92c568c8 Mon Sep 17 00:00:00 2001 From: Elrond Date: Mon, 14 Nov 2011 18:39:18 +0100 Subject: [PATCH 163/302] Dot-Notation for MediaEntry.created --- .../templates/mediagoblin/user_pages/processing_panel.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediagoblin/templates/mediagoblin/user_pages/processing_panel.html b/mediagoblin/templates/mediagoblin/user_pages/processing_panel.html index 9b4adeb5..307a0027 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/processing_panel.html +++ b/mediagoblin/templates/mediagoblin/user_pages/processing_panel.html @@ -37,7 +37,7 @@ {% for media_entry in processing_entries %}

- + {% endfor %} From 1ceb4fc8682dd00c15376b75a3d9222cac6fb5bd Mon Sep 17 00:00:00 2001 From: Elrond Date: Mon, 21 Nov 2011 20:18:38 +0100 Subject: [PATCH 164/302] Dot-Notation for MediaEntry.uploader --- mediagoblin/db/models.py | 6 +++--- mediagoblin/edit/lib.py | 2 +- mediagoblin/edit/views.py | 4 ++-- mediagoblin/submit/views.py | 2 +- mediagoblin/templates/mediagoblin/user_pages/media.html | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/mediagoblin/db/models.py b/mediagoblin/db/models.py index 795cba6a..f1f56dd1 100644 --- a/mediagoblin/db/models.py +++ b/mediagoblin/db/models.py @@ -281,7 +281,7 @@ class MediaEntry(Document): Provide a url to the previous entry from this user, if there is one """ cursor = self.db.MediaEntry.find({'_id': {"$gt": self._id}, - 'uploader': self['uploader'], + 'uploader': self.uploader, 'state': 'processed'}).sort( '_id', ASCENDING).limit(1) if cursor.count(): @@ -294,7 +294,7 @@ class MediaEntry(Document): Provide a url to the next entry from this user, if there is one """ cursor = self.db.MediaEntry.find({'_id': {"$lt": self._id}, - 'uploader': self['uploader'], + 'uploader': self.uploader, 'state': 'processed'}).sort( '_id', DESCENDING).limit(1) @@ -304,7 +304,7 @@ class MediaEntry(Document): media=unicode(cursor[0]['slug'])) def get_uploader(self): - return self.db.User.find_one({'_id': self['uploader']}) + return self.db.User.find_one({'_id': self.uploader}) def get_fail_exception(self): """ diff --git a/mediagoblin/edit/lib.py b/mediagoblin/edit/lib.py index 4ce2d42f..a199cbf7 100644 --- a/mediagoblin/edit/lib.py +++ b/mediagoblin/edit/lib.py @@ -17,7 +17,7 @@ def may_edit_media(request, media): """Check, if the request's user may edit the media details""" - if media['uploader'] == request.user._id: + if media.uploader == request.user._id: return True if request.user.is_admin: return True diff --git a/mediagoblin/edit/views.py b/mediagoblin/edit/views.py index 4e8c3686..0b84f639 100644 --- a/mediagoblin/edit/views.py +++ b/mediagoblin/edit/views.py @@ -57,7 +57,7 @@ def edit_media(request, media): # and userid. existing_user_slug_entries = request.db.MediaEntry.find( {'slug': request.POST['slug'], - 'uploader': media['uploader'], + 'uploader': media.uploader, '_id': {'$ne': media._id}}).count() if existing_user_slug_entries: @@ -79,7 +79,7 @@ def edit_media(request, media): location=media.url_for_self(request.urlgen)) if request.user.is_admin \ - and media['uploader'] != request.user._id \ + and media.uploader != request.user._id \ and request.method != 'POST': messages.add_message( request, messages.WARNING, diff --git a/mediagoblin/submit/views.py b/mediagoblin/submit/views.py index 6beb6b18..64d4b541 100644 --- a/mediagoblin/submit/views.py +++ b/mediagoblin/submit/views.py @@ -64,7 +64,7 @@ def submit_start(request): entry['description_html'] = cleaned_markdown_conversion( entry['description']) - entry['uploader'] = request.user['_id'] + entry.uploader = request.user._id # Process the user's folksonomy "tags" entry['tags'] = convert_to_tag_list_of_dicts( diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html index 89fd104d..d7d510d4 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media.html @@ -115,7 +115,7 @@ - + @@ -57,7 +57,7 @@ {% for media_entry in failed_entries %} - + diff --git a/mediagoblin/templates/mediagoblin/utils/object_gallery.html b/mediagoblin/templates/mediagoblin/utils/object_gallery.html index e1b8cc9b..65ff09a4 100644 --- a/mediagoblin/templates/mediagoblin/utils/object_gallery.html +++ b/mediagoblin/templates/mediagoblin/utils/object_gallery.html @@ -33,9 +33,9 @@ - {% if entry['title'] %} + {% if entry.title %}
- {{ entry['title'] }} + {{ entry.title }} {% endif %} {% endfor %} From 5da0bf901be7551e9708dd248319ff57d7b29a57 Mon Sep 17 00:00:00 2001 From: Elrond Date: Sun, 4 Dec 2011 19:57:42 +0100 Subject: [PATCH 166/302] Dot-Notation for MediaEntry.slug --- mediagoblin/db/models.py | 12 ++++++------ mediagoblin/edit/views.py | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/mediagoblin/db/models.py b/mediagoblin/db/models.py index 7af76b9f..aeee69dd 100644 --- a/mediagoblin/db/models.py +++ b/mediagoblin/db/models.py @@ -249,13 +249,13 @@ class MediaEntry(Document): pass def generate_slug(self): - self['slug'] = url.slugify(self.title) + self.slug = url.slugify(self.title) duplicate = mg_globals.database.media_entries.find_one( - {'slug': self['slug']}) + {'slug': self.slug}) if duplicate: - self['slug'] = "%s-%s" % (self._id, self['slug']) + self.slug = "%s-%s" % (self._id, self.slug) def url_for_self(self, urlgen): """ @@ -269,7 +269,7 @@ class MediaEntry(Document): return urlgen( 'mediagoblin.user_pages.media_home', user=uploader.username, - media=self['slug']) + media=self.slug) else: return urlgen( 'mediagoblin.user_pages.media_home', @@ -287,7 +287,7 @@ class MediaEntry(Document): if cursor.count(): return urlgen('mediagoblin.user_pages.media_home', user=self.get_uploader().username, - media=unicode(cursor[0]['slug'])) + media=unicode(cursor[0].slug)) def url_to_next(self, urlgen): """ @@ -301,7 +301,7 @@ class MediaEntry(Document): if cursor.count(): return urlgen('mediagoblin.user_pages.media_home', user=self.get_uploader().username, - media=unicode(cursor[0]['slug'])) + media=unicode(cursor[0].slug)) def get_uploader(self): return self.db.User.find_one({'_id': self.uploader}) diff --git a/mediagoblin/edit/views.py b/mediagoblin/edit/views.py index feda397d..51661a21 100644 --- a/mediagoblin/edit/views.py +++ b/mediagoblin/edit/views.py @@ -44,7 +44,7 @@ def edit_media(request, media): defaults = dict( title=media.title, - slug=media['slug'], + slug=media.slug, description=media['description'], tags=media_tags_as_string(media['tags'])) @@ -72,7 +72,7 @@ def edit_media(request, media): media['description_html'] = cleaned_markdown_conversion( media['description']) - media['slug'] = unicode(request.POST['slug']) + media.slug = unicode(request.POST['slug']) media.save() return exc.HTTPFound( From 1d9399660416fe5a04d322303986434815bc15f0 Mon Sep 17 00:00:00 2001 From: Elrond Date: Sun, 4 Dec 2011 20:06:42 +0100 Subject: [PATCH 167/302] Dot-Notation for MediaEntry.description(_html) --- mediagoblin/edit/views.py | 8 ++++---- mediagoblin/submit/views.py | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/mediagoblin/edit/views.py b/mediagoblin/edit/views.py index 51661a21..4cb98c15 100644 --- a/mediagoblin/edit/views.py +++ b/mediagoblin/edit/views.py @@ -45,7 +45,7 @@ def edit_media(request, media): defaults = dict( title=media.title, slug=media.slug, - description=media['description'], + description=media.description, tags=media_tags_as_string(media['tags'])) form = forms.EditForm( @@ -65,12 +65,12 @@ def edit_media(request, media): _(u'An entry with that slug already exists for this user.')) else: media.title = unicode(request.POST['title']) - media['description'] = unicode(request.POST.get('description')) + media.description = unicode(request.POST.get('description')) media['tags'] = convert_to_tag_list_of_dicts( request.POST.get('tags')) - media['description_html'] = cleaned_markdown_conversion( - media['description']) + media.description_html = cleaned_markdown_conversion( + media.description) media.slug = unicode(request.POST['slug']) media.save() diff --git a/mediagoblin/submit/views.py b/mediagoblin/submit/views.py index 1805e293..8da71341 100644 --- a/mediagoblin/submit/views.py +++ b/mediagoblin/submit/views.py @@ -60,9 +60,9 @@ def submit_start(request): unicode(request.POST['title']) or unicode(splitext(filename)[0])) - entry['description'] = unicode(request.POST.get('description')) - entry['description_html'] = cleaned_markdown_conversion( - entry['description']) + entry.description = unicode(request.POST.get('description')) + entry.description_html = cleaned_markdown_conversion( + entry.description) entry.uploader = request.user._id From f4ee839939e4215820df3132b62c51f721510f77 Mon Sep 17 00:00:00 2001 From: Elrond Date: Sun, 4 Dec 2011 20:16:01 +0100 Subject: [PATCH 168/302] Dot-Notation for MediaEntry.media_type --- mediagoblin/processing.py | 4 ++-- mediagoblin/submit/views.py | 2 +- mediagoblin/user_pages/views.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mediagoblin/processing.py b/mediagoblin/processing.py index 89c4ac89..7dd5cc7d 100644 --- a/mediagoblin/processing.py +++ b/mediagoblin/processing.py @@ -55,8 +55,8 @@ class ProcessMedia(Task): # Try to process, and handle expected errors. try: - #__import__(entry['media_type']) - manager = get_media_manager(entry['media_type']) + #__import__(entry.media_type) + manager = get_media_manager(entry.media_type) manager['processor'](entry) except BaseProcessingFail, exc: mark_entry_failed(entry._id, exc) diff --git a/mediagoblin/submit/views.py b/mediagoblin/submit/views.py index 8da71341..4e4c7c43 100644 --- a/mediagoblin/submit/views.py +++ b/mediagoblin/submit/views.py @@ -55,7 +55,7 @@ def submit_start(request): # create entry and save in database entry = request.db.MediaEntry() entry['_id'] = ObjectId() - entry['media_type'] = unicode(media_type) + entry.media_type = unicode(media_type) entry.title = ( unicode(request.POST['title']) or unicode(splitext(filename)[0])) diff --git a/mediagoblin/user_pages/views.py b/mediagoblin/user_pages/views.py index dc549567..87b82c74 100644 --- a/mediagoblin/user_pages/views.py +++ b/mediagoblin/user_pages/views.py @@ -122,7 +122,7 @@ def media_home(request, media, page, **kwargs): comment_form = user_forms.MediaCommentForm(request.POST) - media_template_name = get_media_manager(media['media_type'])['display_template'] + media_template_name = get_media_manager(media.media_type)['display_template'] return render_to_response( request, From ddc1cae9ea4c80415557ec0408a56a3a1c60423b Mon Sep 17 00:00:00 2001 From: Elrond Date: Sun, 4 Dec 2011 20:26:36 +0100 Subject: [PATCH 169/302] Dot-Notation for MediaEntry.media_data --- mediagoblin/db/models.py | 4 ++-- mediagoblin/media_types/video/processing.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mediagoblin/db/models.py b/mediagoblin/db/models.py index aeee69dd..569c3600 100644 --- a/mediagoblin/db/models.py +++ b/mediagoblin/db/models.py @@ -131,7 +131,7 @@ class MediaEntry(Document): For example, images might contain some EXIF data that's not appropriate to other formats. You might store it like: - mediaentry['media_data']['exif'] = { + mediaentry.media_data['exif'] = { 'manufacturer': 'CASIO', 'model': 'QV-4000', 'exposure_time': .659} @@ -139,7 +139,7 @@ class MediaEntry(Document): Alternately for video you might store: # play length in seconds - mediaentry['media_data']['play_length'] = 340 + mediaentry.media_data['play_length'] = 340 ... so what's appropriate here really depends on the media type. diff --git a/mediagoblin/media_types/video/processing.py b/mediagoblin/media_types/video/processing.py index 6125e49c..93f16e86 100644 --- a/mediagoblin/media_types/video/processing.py +++ b/mediagoblin/media_types/video/processing.py @@ -75,7 +75,7 @@ def process_video(entry): entry['media_files']['webm_640'] = medium_filepath # Save the width and height of the transcoded video - entry['media_data']['video'] = { + entry.media_data['video'] = { u'width': transcoder.dst_data.videowidth, u'height': transcoder.dst_data.videoheight} From 4535f7597f112443d8997bbd6b8a445612c2440d Mon Sep 17 00:00:00 2001 From: Joar Wandborg Date: Tue, 6 Dec 2011 23:05:47 +0100 Subject: [PATCH 170/302] Bug 681 - Comments from reviewing the new video merge in mediagoblin.media_types and submodules - Moved VideoThumbnailer.errors initialization to VideoThumbnailer.__init__ - Cleaned up the image.processing imports - Removed default ``None`` from get_media_manager(_media_type) in mediagoblin.views - Removed media_types import - Removed sys import, and passing of sys to root.html template --- mediagoblin/media_types/__init__.py | 21 +++++++++++++++++--- mediagoblin/media_types/image/processing.py | 9 ++------- mediagoblin/media_types/video/transcoders.py | 4 ++-- mediagoblin/views.py | 6 +----- 4 files changed, 23 insertions(+), 17 deletions(-) diff --git a/mediagoblin/media_types/__init__.py b/mediagoblin/media_types/__init__.py index 61786562..4fa56bc3 100644 --- a/mediagoblin/media_types/__init__.py +++ b/mediagoblin/media_types/__init__.py @@ -30,7 +30,7 @@ class InvalidFileType(Exception): def get_media_types(): """ - Generator that returns the available media types + Generator, yields the available media types """ for media_type in mg_globals.app_config['media_types']: yield media_type @@ -38,7 +38,7 @@ def get_media_types(): def get_media_managers(): ''' - Generator that returns all available media managers + Generator, yields all enabled media managers ''' for media_type in get_media_types(): __import__(media_type) @@ -46,20 +46,35 @@ def get_media_managers(): yield media_type, sys.modules[media_type].MEDIA_MANAGER -def get_media_manager(_media_type = None): +def get_media_manager(_media_type): + ''' + Get the MEDIA_MANAGER based on a media type string + + Example:: + get_media_type('mediagoblin.media_types.image') + ''' + if not _media_type: + return False + for media_type, manager in get_media_managers(): if media_type in _media_type: return manager def get_media_type_and_manager(filename): + ''' + Get the media type and manager based on a filename + ''' for media_type, manager in get_media_managers(): if filename.find('.') > 0: + # Get the file extension ext = os.path.splitext(filename)[1].lower() else: raise InvalidFileType( _('Could not find any file extension in "{filename}"').format( filename=filename)) + # Omit the dot from the extension and match it against + # the media manager if ext[1:] in manager['accepted_extensions']: return media_type, manager diff --git a/mediagoblin/media_types/image/processing.py b/mediagoblin/media_types/image/processing.py index 5b8259fc..e493eb2b 100644 --- a/mediagoblin/media_types/image/processing.py +++ b/mediagoblin/media_types/image/processing.py @@ -17,15 +17,10 @@ import Image import os -from celery.task import Task -from celery import registry - -from mediagoblin.db.util import ObjectId from mediagoblin import mg_globals as mgg -from mediagoblin.processing import BaseProcessingFail, \ - mark_entry_failed, BadMediaFail, create_pub_filepath, THUMB_SIZE, \ - MEDIUM_SIZE +from mediagoblin.processing import BadMediaFail, \ + create_pub_filepath, THUMB_SIZE, MEDIUM_SIZE ################################ # Media processing initial steps diff --git a/mediagoblin/media_types/video/transcoders.py b/mediagoblin/media_types/video/transcoders.py index d7ed14ca..7071b887 100644 --- a/mediagoblin/media_types/video/transcoders.py +++ b/mediagoblin/media_types/video/transcoders.py @@ -74,14 +74,14 @@ class VideoThumbnailer: buffer_probes = {} - errors = [] - def __init__(self, source_path, dest_path): ''' Set up playbin pipeline in order to get video properties. Initializes and runs the gobject.MainLoop() ''' + self.errors = [] + self.source_path = source_path self.dest_path = dest_path diff --git a/mediagoblin/views.py b/mediagoblin/views.py index cd6aba9b..1e1db6c3 100644 --- a/mediagoblin/views.py +++ b/mediagoblin/views.py @@ -14,14 +14,11 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -import sys - from mediagoblin import mg_globals from mediagoblin.tools.pagination import Pagination from mediagoblin.tools.response import render_to_response from mediagoblin.db.util import DESCENDING from mediagoblin.decorators import uses_pagination -from mediagoblin import media_types @@ -36,8 +33,7 @@ def root_view(request, page): request, 'mediagoblin/root.html', {'media_entries': media_entries, 'allow_registration': mg_globals.app_config["allow_registration"], - 'pagination': pagination, - 'sys': sys}) + 'pagination': pagination}) def simple_template_render(request): From 3f45d9fbe8ed8cad2f3fc9a8e2a68a77ace0a958 Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Wed, 7 Dec 2011 22:15:48 +0100 Subject: [PATCH 171/302] Move author text, "By X", to the sidebar --- .../templates/mediagoblin/user_pages/media.html | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html index 7434664c..95197c15 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media.html @@ -55,12 +55,8 @@

{{ media.description_html }}

{% endautoescape %}

- {% trans date=media.created.strftime("%Y-%m-%d"), - user_url=request.urlgen( - 'mediagoblin.user_pages.user_home', - user=media.get_uploader().username), - username=media.get_uploader().username -%} - By {{ username }} on {{ date }} + {% trans date=media.created.strftime("%Y-%m-%d") -%} + {{ date }} {%- endtrans %}

@@ -114,6 +110,13 @@ {% endif %}
+ {% trans user_url=request.urlgen( + 'mediagoblin.user_pages.user_home', + user=media.get_uploader().username), + username=media.get_uploader().username -%} +

❖ Browsing media by {{ username }}

+ {%- endtrans %} + {% include "mediagoblin/utils/prev_next.html" %} {% if media['uploader'] == request.user._id or From 75a12d632dd281d4d74b93f9014000a3efdc3169 Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Fri, 9 Dec 2011 22:37:20 +0100 Subject: [PATCH 172/302] Lots of changes to media page; rearranged things, added new styles, added jquery bits, gave the comment section a refresh --- mediagoblin/static/css/base.css | 29 +++++-- .../mediagoblin/user_pages/media.html | 79 +++++++++++-------- mediagoblin/user_pages/forms.py | 2 +- 3 files changed, 69 insertions(+), 41 deletions(-) diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css index 12d88ffa..bbc04342 100644 --- a/mediagoblin/static/css/base.css +++ b/mediagoblin/static/css/base.css @@ -117,7 +117,7 @@ a.mediagoblin_logo{ /* common website elements */ -.button_action, .button_action_highlight{ +.button_action, .button_action_highlight { color: #c3c3c3; background-color: #363636; border: 1px solid; @@ -128,16 +128,16 @@ a.mediagoblin_logo{ text-decoration: none; font-style: normal; font-weight: bold; - font-size: 1em; + font-size: 16px; + cursor: pointer; } -.button_action_highlight{ +.button_action_highlight { background-color: #86D4B1; border-color: #A2DEC3 #6CAA8E #5C9179; color: #283F35; } - .button_form, .cancel_link { height: 32px; min-width: 99px; @@ -171,15 +171,15 @@ a.mediagoblin_logo{ background-image: linear-gradient(top, #D2D2D2, #aaa); } -.pagination{ +.pagination { text-align: center; } -.pagination_arrow{ +.pagination_arrow { margin: 5px; } -.empty_space{ +.empty_space { background-image: url("../images/empty_back.png"); font-style: italic; text-align: center; @@ -187,6 +187,21 @@ text-align: center; padding-top: 70px; } +.right_align { + float: right; +} + +textarea { + border: none; + background-color: #f1f1f1; + padding: 3px; +} + +textarea#comment_content { + width: 634px; + height: 90px; +} + /* forms */ .form_box { diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html index 95197c15..12039473 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media.html @@ -22,11 +22,25 @@ {% block title %}{{ media.title }} — {{ super() }}{% endblock %} +{% block mediagoblin_head %} + +{% endblock mediagoblin_head %} + {% block mediagoblin_content %} {% if media %}
- {% block mediagoblin_media %} + {% block mediagoblin_media %} {% set display_media = request.app.public_store.file_url( media.get_display_media(media.media_files)) %} @@ -45,7 +59,7 @@ src="{{ display_media }}" alt="Image for {{ media.title }}" /> {% endif %} - {% endblock %} + {% endblock %}

@@ -59,9 +73,36 @@ {{ date }} {%- endtrans %}

-

- {% if request.user and comments.count() %} -

{% trans %}Post a comment{% endtrans %}

+ + {% if media['uploader'] == request.user._id or + request.user['is_admin'] %} +

+ {% set edit_url = request.urlgen('mediagoblin.edit.edit_media', + user= media.get_uploader().username, + media= media._id) %} + {% trans %}Edit{% endtrans %} +

+

+ {% set delete_url = request.urlgen('mediagoblin.user_pages.media_confirm_delete', + user= media.get_uploader().username, + media= media._id) %} + {% trans %}Delete{% endtrans %} +

+ {% endif %} + +

{% trans %}23 comments{% endtrans %}

+ {# 0 comments. Be the first to add one! #} + {% if request.user %} + +

{% trans %}Type your comment here. You can use Markdown for formatting.{% endtrans %}

+ {{ wtforms_util.render_divs(comment_form) }} +
+ + {{ csrf_token }} +
+ {% endif %} {% if comments %} {% for comment in comments %} @@ -90,18 +131,6 @@
{% endfor %} - {% if request.user %} -
- {{ wtforms_util.render_divs(comment_form) }} -
- - {{ csrf_token }} -
- - {% endif %} - {{ render_pagination(request, pagination, request.urlgen('mediagoblin.user_pages.media_home', user = media.get_uploader().username, @@ -119,22 +148,6 @@ {% include "mediagoblin/utils/prev_next.html" %} - {% if media['uploader'] == request.user._id or - request.user['is_admin'] %} -

- {% set edit_url = request.urlgen('mediagoblin.edit.edit_media', - user= media.get_uploader().username, - media= media._id) %} - {% trans %}Edit{% endtrans %} -

-

- {% set delete_url = request.urlgen('mediagoblin.user_pages.media_confirm_delete', - user= media.get_uploader().username, - media= media._id) %} - {% trans %}Delete{% endtrans %} -

- {% endif %} - {% if media.attachment_files|count %}

Attachments

    diff --git a/mediagoblin/user_pages/forms.py b/mediagoblin/user_pages/forms.py index 301f1f0a..e04fd559 100644 --- a/mediagoblin/user_pages/forms.py +++ b/mediagoblin/user_pages/forms.py @@ -21,7 +21,7 @@ from mediagoblin.tools.translate import fake_ugettext_passthrough as _ class MediaCommentForm(wtforms.Form): comment_content = wtforms.TextAreaField( - _('Comment'), + _(''), [wtforms.validators.Required()]) From 9c6d8d77fba60a355b2b60d4c0a48de8bd58f2fa Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Fri, 9 Dec 2011 22:45:26 +0100 Subject: [PATCH 173/302] Only apply textarea style to comment box --- mediagoblin/static/css/base.css | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css index bbc04342..89988c8b 100644 --- a/mediagoblin/static/css/base.css +++ b/mediagoblin/static/css/base.css @@ -191,15 +191,12 @@ text-align: center; float: right; } -textarea { - border: none; - background-color: #f1f1f1; - padding: 3px; -} - textarea#comment_content { width: 634px; height: 90px; + border: none; + background-color: #f1f1f1; + padding: 3px; } /* forms */ From 8f25d91b1ee8672afa2ebdfb9c938dd1e3439149 Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Fri, 9 Dec 2011 22:48:20 +0100 Subject: [PATCH 174/302] Open Markdown link in new windows; I know _blank is sometimes frowned upon but it may be useful here --- mediagoblin/templates/mediagoblin/user_pages/media.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html index 12039473..000b1b80 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media.html @@ -96,7 +96,7 @@
    -

    {% trans %}Type your comment here. You can use Markdown for formatting.{% endtrans %}

    +

    {% trans %}Type your comment here. You can use Markdown for formatting.{% endtrans %}

    {{ wtforms_util.render_divs(comment_form) }}
    From de73724066d0fb49b77b53332c80d3cbc5f59221 Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Fri, 9 Dec 2011 23:47:11 +0100 Subject: [PATCH 175/302] Change wording in tags.html --- mediagoblin/templates/mediagoblin/utils/tags.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mediagoblin/templates/mediagoblin/utils/tags.html b/mediagoblin/templates/mediagoblin/utils/tags.html index c7dfc8eb..1f587411 100644 --- a/mediagoblin/templates/mediagoblin/utils/tags.html +++ b/mediagoblin/templates/mediagoblin/utils/tags.html @@ -17,12 +17,12 @@ #} {% block tags_content -%} -

    {% trans %}Tagged with{% endtrans %} +

    {% trans %}View more media tagged with{% endtrans %} {% for tag in media.tags %} {% if loop.last %} {# the 'and' should only appear if there is more than one tag #} {% if media.tags|length > 1 %} - {% trans %}and{% endtrans %} + {% trans %}or{% endtrans %} {% endif %} Previous page - {% trans %}Newer{% endtrans %} + {% trans %}← Newer{% endtrans %} {% endif %} {% if pagination.has_next %} {% set next_url = pagination.get_page_url_explicit( base_url, get_params, pagination.page + 1) %} - {% trans %}Older{% endtrans %} - Next page + {% trans %}Older →{% endtrans %} {% endif %}
    {% trans %}Go to page:{% endtrans %} From b27067371d6cb99cf21c7c0970b664e970d9a22d Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Sat, 10 Dec 2011 21:03:18 +0100 Subject: [PATCH 177/302] Style changes for media_uploader (now media_specs); removed margins from button_action buttons --- mediagoblin/static/css/base.css | 16 ++++++++++------ .../templates/mediagoblin/user_pages/media.html | 16 +++++----------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css index 89988c8b..c1239abb 100644 --- a/mediagoblin/static/css/base.css +++ b/mediagoblin/static/css/base.css @@ -96,6 +96,7 @@ input, textarea { a.mediagoblin_logo{ color: #fff; font-weight: bold; + margin-right: 8px; } .mediagoblin_footer { @@ -123,7 +124,6 @@ a.mediagoblin_logo{ border: 1px solid; border-color: #464646 #2B2B2B #252525; border-radius: 4px; - margin: 8px; padding: 3px 8px; text-decoration: none; font-style: normal; @@ -285,24 +285,28 @@ textarea#comment_content { /* media detail */ -h2.media_title{ +h2.media_title { margin-bottom: 0px; } -p.media_uploader{ +p.media_specs { font-size: 0.9em; + border-top: 1px solid #222; + border-bottom: 1px solid #222; + padding: 10px 0px; + color: #888; } /* icons */ -img.media_icon{ +img.media_icon { margin: 0 4px; vertical-align: sub; } /* navigation */ -.navigation_button{ +.navigation_button { width: 135px; display: block; float: left; @@ -317,7 +321,7 @@ img.media_icon{ margin: 0 0 20px } -.navigation_left{ +.navigation_left { margin-right: 6px; } diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html index 000b1b80..1a19443c 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media.html @@ -68,28 +68,22 @@ {% autoescape False %}

    {{ media.description_html }}

    {% endautoescape %} -

    +

    {% trans date=media.created.strftime("%Y-%m-%d") -%} - {{ date }} + Added on {{ date }}. Licensed under an X license. {%- endtrans %} -

    - - {% if media['uploader'] == request.user._id or + {% if media['uploader'] == request.user._id or request.user['is_admin'] %} -

    {% set edit_url = request.urlgen('mediagoblin.edit.edit_media', user= media.get_uploader().username, media= media._id) %} {% trans %}Edit{% endtrans %} -

    -

    {% set delete_url = request.urlgen('mediagoblin.user_pages.media_confirm_delete', user= media.get_uploader().username, media= media._id) %} {% trans %}Delete{% endtrans %} -

    - {% endif %} - + {% endif %} +

    {% trans %}23 comments{% endtrans %}

    {# 0 comments. Be the first to add one! #} {% if request.user %} From ed1840ee64eca680581fd764369f81063dd72831 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Mon, 12 Dec 2011 07:35:47 -0600 Subject: [PATCH 178/302] Mark "newer/older" buttons for translation --- mediagoblin/templates/mediagoblin/utils/prev_next.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mediagoblin/templates/mediagoblin/utils/prev_next.html b/mediagoblin/templates/mediagoblin/utils/prev_next.html index 3363891b..b0c01963 100644 --- a/mediagoblin/templates/mediagoblin/utils/prev_next.html +++ b/mediagoblin/templates/mediagoblin/utils/prev_next.html @@ -25,23 +25,23 @@ {# There are no previous entries for the very first media entry #} {% if prev_entry_url %} - ← newer + ← {% trans %}newer{% endtrans %} {% else %} {# This is the first entry. display greyed-out 'previous' image #} {% endif %} {# Likewise, this could be the very last media entry #} {% if next_entry_url %} - older → + {% trans %}older{% endtrans %} → {% else %} {# This is the last entry. display greyed-out 'next' image #} {% endif %}
    From 23caf305f28d1e8baf5196703ac316cfe4e740dc Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Mon, 12 Dec 2011 08:10:10 -0600 Subject: [PATCH 179/302] Allow administrators to disable keeping the original. That's the new default! --- mediagoblin/config_spec.ini | 5 ++++ mediagoblin/media_types/video/processing.py | 29 +++++++++++---------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/mediagoblin/config_spec.ini b/mediagoblin/config_spec.ini index 13ce925e..eb22bc1b 100644 --- a/mediagoblin/config_spec.ini +++ b/mediagoblin/config_spec.ini @@ -61,6 +61,11 @@ storage_class = string(default="mediagoblin.storage.filestorage:BasicFileStorage base_dir = string(default="%(here)s/user_dev/media/queue") +# Should we keep the original file? +[media_type:mediagoblin.media_types.video] +keep_original = boolean(default=False) + + [beaker.cache] type = string(default="file") data_dir = string(default="%(here)s/user_dev/beaker/cache/data") diff --git a/mediagoblin/media_types/video/processing.py b/mediagoblin/media_types/video/processing.py index 6125e49c..c0a3fb67 100644 --- a/mediagoblin/media_types/video/processing.py +++ b/mediagoblin/media_types/video/processing.py @@ -41,6 +41,8 @@ def process_video(entry): and attaches callbacks to that child process, hopefully, the entry-complete callback will be called when the video is done. """ + video_config = mgg.global_config['media_type:mediagoblin.media_types.video'] + workbench = mgg.workbench_manager.create_workbench() queued_filepath = entry['queued_media_file'] @@ -94,25 +96,24 @@ def process_video(entry): entry['media_files']['thumb'] = thumbnail_filepath + if video_config['keep_original']: + # Push original file to public storage + queued_file = file(queued_filename, 'rb') - # Push original file to public storage - queued_file = file(queued_filename, 'rb') + with queued_file: + original_filepath = create_pub_filepath( + entry, + queued_filepath[-1]) - with queued_file: - original_filepath = create_pub_filepath( - entry, - queued_filepath[-1]) + with mgg.public_store.get_file(original_filepath, 'wb') as \ + original_file: + _log.debug('Saving original...') + original_file.write(queued_file.read()) + _log.debug('Saved original') - with mgg.public_store.get_file(original_filepath, 'wb') as \ - original_file: - _log.debug('Saving original...') - original_file.write(queued_file.read()) - _log.debug('Saved original') - - entry['media_files']['original'] = original_filepath + entry['media_files']['original'] = original_filepath mgg.queue_store.delete_file(queued_filepath) - # Save the MediaEntry entry.save() From 438dd8cd8f79f32609cce15d70ef6a93f1531a3b Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Mon, 12 Dec 2011 08:13:46 -0600 Subject: [PATCH 180/302] Add a note on how to up the upload size limit --- docs/source/deploying.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/source/deploying.rst b/docs/source/deploying.rst index 70b1a6af..14b2c9cf 100644 --- a/docs/source/deploying.rst +++ b/docs/source/deploying.rst @@ -196,6 +196,9 @@ this ``nginx.conf`` file should be modeled on the following: :: # This is the section you should read ##################################### + # Change this to update the upload size limit for your users + client_max_body_size 8m; + server_name mediagoblin.example.org www.mediagoblin.example.org; access_log /var/log/nginx/mediagoblin.example.access.log; error_log /var/log/nginx/mediagoblin.example.error.log; From c36c3782737ef6d27137275ab98dbec49d7cd9ba Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Mon, 12 Dec 2011 08:15:16 -0600 Subject: [PATCH 181/302] Removed extraneous whitespace from video.html --- mediagoblin/templates/mediagoblin/media_displays/video.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediagoblin/templates/mediagoblin/media_displays/video.html b/mediagoblin/templates/mediagoblin/media_displays/video.html index 5b8ec789..5ef1a782 100644 --- a/mediagoblin/templates/mediagoblin/media_displays/video.html +++ b/mediagoblin/templates/mediagoblin/media_displays/video.html @@ -21,5 +21,5 @@ {%- endtrans -%}

    - {% endif %} + {% endif %} {% endblock %} From 528c8b8fabe7036b63c44d93adc9e7b068bbcd91 Mon Sep 17 00:00:00 2001 From: Will Kahn-Greene Date: Mon, 12 Dec 2011 09:46:23 -0500 Subject: [PATCH 182/302] Tweak runtests to be more helpful If nose isn't installed, then runtests.sh says it can't find nosetests and exits, but doesn't tell you what you need to do to fix the situation. This fixes that. --- runtests.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/runtests.sh b/runtests.sh index 1dfbf093..4265326c 100755 --- a/runtests.sh +++ b/runtests.sh @@ -23,7 +23,8 @@ elif which nosetests > /dev/null; then echo "Using nosetests from \$PATH"; export NOSETESTS="nosetests"; else - echo "No nosetests found, exiting! X_X"; + echo "nosetests not found. X_X"; + echo "Please install 'nose'. Exiting."; exit 1 fi From 5b9ef3d58f7b8f8669c5cfb7c4938e01d297ed10 Mon Sep 17 00:00:00 2001 From: Will Kahn-Greene Date: Mon, 12 Dec 2011 09:53:41 -0500 Subject: [PATCH 183/302] Update README * tweaked some language * fixed some statements that aren't correct anymore --- README | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/README b/README index 0aba179b..07f9a094 100644 --- a/README +++ b/README @@ -8,19 +8,18 @@ What is GNU MediaGoblin? * Initially, a place to store all your photos that’s as awesome as, if not more awesome than, existing network services (Flickr, SmugMug, Picasa, etc) -* Later, a place for all sorts of media, such as video, music, etc hosting. -* Federated with OStatus! * Customizable! * A place for people to collaborate and show off original and derived - creations. Free, as in freedom. We’re a GNU project in the making, - afterall. + creations. Free, as in freedom. We’re a GNU project after all. +* Later, a place for all sorts of media, such as video, music, etc hosting. +* Later, federated with OStatus! Is it ready for me to use? ========================== -Not yet! We're working on it and we hope to have a usable system by -September / October 2011. +Yes! But with caveats. The software is usable and there are instances +running, but it's still in its early stages. Can I help/hang out/participate/whisper sweet nothings in your ear? @@ -33,9 +32,9 @@ hang out, see `our Join page `_ Where is the documentation? =========================== -The beginnings of a user manual is located in the ``docs/`` directory -in HTML, Texinfo, and source (Restructured Text) forms. It's also -available online at http://docs.mediagoblin.org/ in HTML form. +The beginnings of a site administration manual is located in the ``docs/`` +directory in HTML, Texinfo, and source (Restructured Text) forms. It's +also available online at http://docs.mediagoblin.org/ in HTML form. Contributor/developer documentation as well as documentation on the project processes and infrastructure is located on From 78dc055e22b55253ed395d616a6ce5635ef91499 Mon Sep 17 00:00:00 2001 From: Will Kahn-Greene Date: Mon, 12 Dec 2011 10:17:03 -0500 Subject: [PATCH 184/302] Add some documentation to lazyserver.sh I had no idea what it did, so I asked and tossed the answer at the top of the script. --- lazyserver.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lazyserver.sh b/lazyserver.sh index 63818a6a..4ca073b5 100755 --- a/lazyserver.sh +++ b/lazyserver.sh @@ -16,6 +16,10 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +# +# This runs Mediagoblin using Paste with Celery set to always eager mode. +# + if [ "$1" = "-h" ] then echo "$0 [-h] [-c paste.ini] [ARGS_to_paster ...]" From 076bf0cf28bae50dcd0f9e79e5c9e6501f1ad04a Mon Sep 17 00:00:00 2001 From: Will Kahn-Greene Date: Mon, 12 Dec 2011 10:20:05 -0500 Subject: [PATCH 185/302] Doc updates * fixed some language * fixed some consistency issues * fixed some 80-line-width issues * fixed some typos and markup problems --- docs/source/configuration.rst | 42 +++--- docs/source/deploying.rst | 181 +++++++++++++------------ docs/source/foreword.rst | 8 +- docs/source/production-deployments.rst | 29 ++-- 4 files changed, 135 insertions(+), 125 deletions(-) diff --git a/docs/source/configuration.rst b/docs/source/configuration.rst index 093f492c..1e22ad2d 100644 --- a/docs/source/configuration.rst +++ b/docs/source/configuration.rst @@ -19,13 +19,13 @@ mediagoblin.ini tweak settings for MediaGoblin, you'll usually tweak them here. paste.ini - This is primarily a server configuration file, on the python side - (specifically, on the wsgi side, via `paste deploy + This is primarily a server configuration file, on the Python side + (specifically, on the WSGI side, via `paste deploy `_ / `paste script `_). It also sets up some middleware that you can mostly ignore, except to configure sessions... more on that later. If you are adding a different - python server other than fastcgi / plain http, you might configure + Python server other than fastcgi / plain HTTP, you might configure it here. You probably won't need to change this file very much. @@ -47,19 +47,23 @@ Let's assume you're doing the virtualenv setup described elsewhere in this manual, and you need to make local tweaks to the config files. How do you do that? Let's see. -To make changes to mediagoblin.ini: +To make changes to mediagoblin.ini :: - cp mediagoblin.ini mediagoblin_local.ini + cp mediagoblin.ini mediagoblin_local.ini -To make changes to paste.ini: - cp paste.ini paste_local.ini +To make changes to paste.ini :: + + cp paste.ini paste_local.ini From here you should be able to make direct adjustments to the files, and most of the commands described elsewhere in this manual will "notice" your local config files and use those instead of the non-local version. -(Note that all commands provide a way to pass in a specific config -file also, usually by a -cf flag.) +.. note:: + + Note that all commands provide a way to pass in a specific config + file also, usually by a ``-cf`` flag. + Common changes ============== @@ -69,9 +73,9 @@ Enabling email notifications You'll almost certainly want to enable sending emails. By default, MediaGoblin doesn't really do this... for the sake of developer -convenience, it runs in "email debug mode". Change this: +convenience, it runs in "email debug mode". Change this:: - email_debug_mode = false + email_debug_mode = false You can (and should) change the "from" email address by setting ``email_sender_address``. @@ -82,21 +86,21 @@ If you have more custom SMTP settings, you also have the following options at your disposal, which are all optional, and do exactly what they sound like. - - email_smtp_host - - email_smtp_port - - email_smtp_user - - email_smtp_pass +- email_smtp_host +- email_smtp_port +- email_smtp_user +- email_smtp_pass All other configuration changes ------------------------------- -To be perfectly honest, there are quite a few options and I'm not -going to be able to get to documanting them all in time for 0.1.0. +To be perfectly honest, there are quite a few options and we haven't had +time to document them all So here's a cop-out section saying that if you get into trouble, hop -onto IRC and we'll help you out: +onto IRC and we'll help you out:: - #mediagoblin on irc.freenode.net + #mediagoblin on irc.freenode.net Celery ====== diff --git a/docs/source/deploying.rst b/docs/source/deploying.rst index 14b2c9cf..4aded2e6 100644 --- a/docs/source/deploying.rst +++ b/docs/source/deploying.rst @@ -11,9 +11,11 @@ it simple with some assumptions and use a setup that combines mediagoblin + virtualenv + fastcgi + nginx on a .deb or .rpm based GNU/Linux distro. -Note: these tools are for administrators wanting to deploy a fresh -install. If instead you want to join in as a contributor, see our -`Hacking HOWTO `_ instead. +.. note:: + + These tools are for site administrators wanting to deploy a fresh + install. If instead you want to join in as a contributor, see our + `Hacking HOWTO `_ instead. Prepare System -------------- @@ -33,12 +35,15 @@ MediaGoblin has the following core dependencies: On a DEB-based system (e.g Debian, gNewSense, Trisquel, Ubuntu, and derivatives) issue the following command: :: - sudo apt-get install mongodb git-core python python-dev python-lxml python-imaging python-virtualenv + sudo apt-get install mongodb git-core python python-dev python-lxml \ + python-imaging python-virtualenv On a RPM-based system (e.g. Fedora, RedHat, and derivatives) issue the following command: :: - yum install mongodb-server python-paste-deploy python-paste-script git-core python python-devel python-lxml python-imaging python-virtualenv + yum install mongodb-server python-paste-deploy python-paste-script \ + git-core python python-devel python-lxml python-imaging \ + python-virtualenv Configure MongoDB ~~~~~~~~~~~~~~~~~ @@ -46,10 +51,11 @@ Configure MongoDB After installing MongoDB some preliminary database configuration may be necessary. -Ensure that MongoDB `journaling `_ -is enabled. Journaling is enabled by default in version 2.0 and later -64-bit MongoDB instances. Check your deployment, and consider enabling -journaling if you're running 32-bit systems or earlier version. +Ensure that MongoDB `journaling +`_ is enabled. Journaling +is enabled by default in version 2.0 and later 64-bit MongoDB instances. +Check your deployment, and consider enabling journaling if you're running +32-bit systems or earlier version. .. warning:: @@ -77,41 +83,42 @@ create "system account" or dedicated service user. Ensure that it is not possible to log in to your system with as this user. You should create a working directory for MediaGoblin. This document -assumes your local git repository will be located at ``/srv/mediagoblin.example.org/mediagoblin/`` -for this documentation. Substitute your prefer ed local deployment path -as needed. +assumes your local git repository will be located at +``/srv/mediagoblin.example.org/mediagoblin/`` for this documentation. +Substitute your prefer ed local deployment path as needed. This document assumes that all operations are performed as this user. To drop privileges to this user, run the following command: :: + su - [mediagoblin] - su - [mediagoblin]`` - -Where, "``[mediagoblin]`` is the username of the system user that will +Where, "``[mediagoblin]``" is the username of the system user that will run MediaGoblin. Install MediaGoblin and Virtualenv ---------------------------------- -As of |version|, MediaGoblin has a rapid development pace. As a result -the following instructions recommend installing from the ``master`` -branch of the git repository. Eventually production deployments will -want to transition to running from more consistent releases. +.. note:: + + As of |version|, MediaGoblin has a rapid development pace. As a result + the following instructions recommend installing from the ``master`` + branch of the git repository. Eventually production deployments will + want to transition to running from more consistent releases. Issue the following commands, to create and change the working -directory. Modify these commands to reflect your own environment: :: +directory. Modify these commands to reflect your own environment:: - mkdir -p /srv/mediagoblin.example.org/ - cd /srv/mediagoblin.example.org/ + mkdir -p /srv/mediagoblin.example.org/ + cd /srv/mediagoblin.example.org/ -Clone the MediaGoblin repository: :: +Clone the MediaGoblin repository:: - git clone git://gitorious.org/mediagoblin/mediagoblin.git + git clone git://gitorious.org/mediagoblin/mediagoblin.git -And setup the in-package virtualenv: :: +And setup the in-package virtualenv:: - cd mediagoblin - virtualenv . && ./bin/python setup.py develop + cd mediagoblin + virtualenv . && ./bin/python setup.py develop .. note:: @@ -127,16 +134,16 @@ more reliable and considerably easier to configure and illustrate. If you're familiar with Python packaging you may consider deploying with your preferred the method. -Assuming you are going to deploy with fastcgi, you should also install -flup: :: +Assuming you are going to deploy with FastCGI, you should also install +flup:: - ./bin/easy_install flup + ./bin/easy_install flup This concludes the initial configuration of the development environment. In the future, if at any point you want update your -codebase, you should also run: :: +codebase, you should also run:: - ./bin/python setup.py develop --upgrade && ./bin/gmg migrate. + ./bin/python setup.py develop --upgrade && ./bin/gmg migrate. Deploy MediaGoblin Services --------------------------- @@ -145,9 +152,9 @@ Test the Server ~~~~~~~~~~~~~~~ At this point MediaGoblin should be properly installed. You can -test the deployment with the following command: :: +test the deployment with the following command:: - ./lazyserver.sh --server-name=broadcast + ./lazyserver.sh --server-name=broadcast You should be able to connect to the machine on port 6543 in your browser to confirm that the service is operable. @@ -156,7 +163,7 @@ Connect the Webserver to MediaGoblin with FastCGI ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This section describes how to configure MediaGoblin to work via -fastcgi. Our configuration example will use nginx, however, you may +FastCGI. Our configuration example will use nginx, however, you may use any webserver of your choice as long as it supports the FastCGI protocol. If you do not already have a web server, consider nginx, as the configuration files may be more clear than the @@ -166,78 +173,78 @@ Create a configuration file at ``/srv/mediagoblin.example.org/nginx.conf`` and create a symbolic link into a directory that will be included in your ``nginx`` configuration (e.g. "``/etc/nginx/sites-enabled`` or ``/etc/nginx/conf.d``) with -one of the following commands (as the root user:) :: +one of the following commands (as the root user):: - ln -s /srv/mediagoblin.example.org/nginx.conf /etc/nginx/conf.d/ - ln -s /srv/mediagoblin.example.org/nginx.conf /etc/nginx/sites-enabled/ + ln -s /srv/mediagoblin.example.org/nginx.conf /etc/nginx/conf.d/ + ln -s /srv/mediagoblin.example.org/nginx.conf /etc/nginx/sites-enabled/ Modify these commands and locations depending on your preferences and the existing configuration of your nginx instance. The contents of -this ``nginx.conf`` file should be modeled on the following: :: +this ``nginx.conf`` file should be modeled on the following:: - server { - ################################################# - # Stock useful config options, but ignore them :) - ################################################# - include /etc/nginx/mime.types; + server { + ################################################# + # Stock useful config options, but ignore them :) + ################################################# + include /etc/nginx/mime.types; - autoindex off; - default_type application/octet-stream; - sendfile on; + autoindex off; + default_type application/octet-stream; + sendfile on; - # Gzip - gzip on; - gzip_min_length 1024; - gzip_buffers 4 32k; - gzip_types text/plain text/html application/x-javascript text/javascript text/xml text/css; + # Gzip + gzip on; + gzip_min_length 1024; + gzip_buffers 4 32k; + gzip_types text/plain text/html application/x-javascript text/javascript text/xml text/css; - ##################################### - # Mounting MediaGoblin stuff - # This is the section you should read - ##################################### + ##################################### + # Mounting MediaGoblin stuff + # This is the section you should read + ##################################### - # Change this to update the upload size limit for your users - client_max_body_size 8m; + # Change this to update the upload size limit for your users + client_max_body_size 8m; - server_name mediagoblin.example.org www.mediagoblin.example.org; - access_log /var/log/nginx/mediagoblin.example.access.log; - error_log /var/log/nginx/mediagoblin.example.error.log; + server_name mediagoblin.example.org www.mediagoblin.example.org; + access_log /var/log/nginx/mediagoblin.example.access.log; + error_log /var/log/nginx/mediagoblin.example.error.log; - # MediaGoblin's stock static files: CSS, JS, etc. - location /mgoblin_static/ { - alias /srv/mediagoblin.example.org/mediagoblin/mediagoblin/static/; - } - - # Instance specific media: - location /mgoblin_media/ { - alias /srv/mediagoblin.example.org/mediagoblin/user_dev/media/public/; - } - - # Mounting MediaGoblin itself via fastcgi. - location / { - fastcgi_pass 127.0.0.1:26543; - include /etc/nginx/fastcgi_params; - - # our understanding vs nginx's handling of script_name vs - # path_info don't match :) - fastcgi_param PATH_INFO $fastcgi_script_name; - fastcgi_param SCRIPT_NAME ""; - } + # MediaGoblin's stock static files: CSS, JS, etc. + location /mgoblin_static/ { + alias /srv/mediagoblin.example.org/mediagoblin/mediagoblin/static/; } + # Instance specific media: + location /mgoblin_media/ { + alias /srv/mediagoblin.example.org/mediagoblin/user_dev/media/public/; + } + + # Mounting MediaGoblin itself via FastCGI. + location / { + fastcgi_pass 127.0.0.1:26543; + include /etc/nginx/fastcgi_params; + + # our understanding vs nginx's handling of script_name vs + # path_info don't match :) + fastcgi_param PATH_INFO $fastcgi_script_name; + fastcgi_param SCRIPT_NAME ""; + } + } + Now, nginx instance is configured to serve the MediaGoblin application. Perform a quick test to ensure that this configuration works. Restart nginx so it picks up your changes, with a command that -resembles one of the following (as the root user:) :: +resembles one of the following (as the root user):: - sudo /etc/init.d/nginx restart - sudo /etc/rc.d/nginx restart + sudo /etc/init.d/nginx restart + sudo /etc/rc.d/nginx restart Now start MediaGoblin. Use the following command sequence as an -example: :: +example:: - cd /srv/mediagoblin.example.org/mediagoblin/ - ./lazyserver.sh --server-name=fcgi fcgi_host=127.0.0.1 fcgi_port=26543 + cd /srv/mediagoblin.example.org/mediagoblin/ + ./lazyserver.sh --server-name=fcgi fcgi_host=127.0.0.1 fcgi_port=26543 Visit the site you've set up in your browser by visiting . You should see MediaGoblin! diff --git a/docs/source/foreword.rst b/docs/source/foreword.rst index 835a7e7a..aa27647f 100644 --- a/docs/source/foreword.rst +++ b/docs/source/foreword.rst @@ -5,14 +5,14 @@ Foreword About the MediaGoblin Manual ============================ -This is the user manual for MediaGoblin. It covers how to set up and -configure MediaGoblin and the kind of information that someone running -MediaGoblin would need to know. +This is the site administrator manual for MediaGoblin. It covers how +to set up and configure MediaGoblin and the kind of information that +someone running MediaGoblin would need to know. We have other documentation at: * http://mediagoblin.org/join/ for general "join us" information -* http://wiki.mediagoblin.org/ for our contributor-focused wiki +* http://wiki.mediagoblin.org/ for our contributor/developer-focused wiki Improving the MediaGobiin Manual diff --git a/docs/source/production-deployments.rst b/docs/source/production-deployments.rst index 7bf26169..ef0bcad6 100644 --- a/docs/source/production-deployments.rst +++ b/docs/source/production-deployments.rst @@ -4,8 +4,7 @@ Considerations for Production Deployments This document contains a number of suggestions for deploying MediaGoblin in actual production environments. Consider -":doc:`deploying`" for a basic overview of how to deploy Media -Goblin. +":doc:`deploying`" for a basic overview of how to deploy MediaGoblin. Deploy with Paste ----------------- @@ -17,11 +16,11 @@ process. Use the following command as the basis for such a script: :: - CELERY_ALWAYS_EAGER=true \ - /srv/mediagoblin.example.org/mediagoblin/bin/paster serve \ - /srv/mediagoblin.example.org/mediagoblin/paste.ini \ - --pid-file=/var/run/mediagoblin.pid \ - --server-name=fcgi fcgi_host=127.0.0.1 fcgi_port=26543 \ + CELERY_ALWAYS_EAGER=true \ + /srv/mediagoblin.example.org/mediagoblin/bin/paster serve \ + /srv/mediagoblin.example.org/mediagoblin/paste.ini \ + --pid-file=/var/run/mediagoblin.pid \ + --server-name=fcgi fcgi_host=127.0.0.1 fcgi_port=26543 The above configuration places MediaGoblin in "always eager" mode with Celery, this means that submissions of content will be processed @@ -31,11 +30,11 @@ the user will be able to immediately return to the MediaGoblin site while processing is ongoing. In these cases, use the following command as the basis for your script: :: - CELERY_ALWAYS_EAGER=false \ - /srv/mediagoblin.example.org/mediagoblin/bin/paster serve \ - /srv/mediagoblin.example.org/mediagoblin/paste.ini \ - --pid-file=/var/run/mediagoblin.pid \ - --server-name=fcgi fcgi_host=127.0.0.1 fcgi_port=26543 \ + CELERY_ALWAYS_EAGER=false \ + /srv/mediagoblin.example.org/mediagoblin/bin/paster serve \ + /srv/mediagoblin.example.org/mediagoblin/paste.ini \ + --pid-file=/var/run/mediagoblin.pid \ + --server-name=fcgi fcgi_host=127.0.0.1 fcgi_port=26543 Separate Celery --------------- @@ -57,9 +56,9 @@ such as "ASCII art" or icon sharing, you will need to run ``celeryd`` as a separate process. Build an :ref:`init script ` around the following -command. +command:: - CELERY_CONFIG_MODULE=mediagoblin.init.celery.from_celery ./bin/celeryd + CELERY_CONFIG_MODULE=mediagoblin.init.celery.from_celery ./bin/celeryd Modify your existing MediaGoblin and application init scripts, if necessary, to prevent them from starting their own ``celeryd`` @@ -77,6 +76,6 @@ distribution/operating system. In the future, MediaGoblin will provide example scripts as examples. .. TODO insert init script here -.. TODO are additional concernts ? +.. TODO are additional concerns ? .. Other Concerns .. -------------- From 9bc2fc6c6a327a79ff5ad9d8f11f5b8f968154a6 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Mon, 12 Dec 2011 09:44:48 -0600 Subject: [PATCH 186/302] Added the "Media types" chapter --- docs/source/index.rst | 1 + docs/source/media-types.rst | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 docs/source/media-types.rst diff --git a/docs/source/index.rst b/docs/source/index.rst index 6ffe0974..f9c9285d 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -16,6 +16,7 @@ Table of Contents: deploying production-deployments configuration + media-types help theming codebase diff --git a/docs/source/media-types.rst b/docs/source/media-types.rst new file mode 100644 index 00000000..809efe07 --- /dev/null +++ b/docs/source/media-types.rst @@ -0,0 +1,34 @@ +.. _media-types-chapter: + +==================== +Enabling Media Types +==================== + +In the future, there will be all sorts of media types you can enable, +but in the meanwhile there's only one additional media type: video. + +First, you should probably read ":doc:`configuration`" to make sure +you know how to modify the mediagoblin config file. + +Video +===== + +To enable video, first install gstreamer and the python-gstreamer +bindings (as well as whatever gstremaer extensions you want, +good/bad/ugly). On Debianoid systems: + + sudo apt-get install python-gst0.10 + +Next, modify (and possibly copy over from mediagoblin.ini) your +mediagoblin_local.ini. Uncomment this line in the [mediagoblin] +section: + + media_types = mediagoblin.media_types.image, mediagoblin.media_types.video + +Now you should be able to submit videos, and mediagoblin should +transcode them. + +Note that you almost certainly want to separate Celery from the normal +paste process or your users will probably find that their connections +time out as the video transcodes. To set that up, check out the +":doc:`production-deployments`" section of this manual. From 57875c83c253e6e6aa08c3dbc92a3eb58664c88b Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Mon, 12 Dec 2011 09:45:45 -0600 Subject: [PATCH 187/302] Updated translations --- .../i18n/de/LC_MESSAGES/mediagoblin.mo | Bin 11805 -> 11802 bytes .../i18n/de/LC_MESSAGES/mediagoblin.po | 10 +-- .../i18n/eo/LC_MESSAGES/mediagoblin.mo | Bin 11754 -> 11749 bytes .../i18n/eo/LC_MESSAGES/mediagoblin.po | 6 +- .../i18n/es/LC_MESSAGES/mediagoblin.mo | Bin 12093 -> 12120 bytes .../i18n/es/LC_MESSAGES/mediagoblin.po | 37 +++++---- .../i18n/pt_BR/LC_MESSAGES/mediagoblin.mo | Bin 11596 -> 11350 bytes .../i18n/pt_BR/LC_MESSAGES/mediagoblin.po | 58 +++++++------- .../i18n/ru/LC_MESSAGES/mediagoblin.mo | Bin 15455 -> 15457 bytes .../i18n/ru/LC_MESSAGES/mediagoblin.po | 4 +- .../i18n/sk/LC_MESSAGES/mediagoblin.mo | Bin 11789 -> 11993 bytes .../i18n/sk/LC_MESSAGES/mediagoblin.po | 75 ++++++++++-------- 12 files changed, 100 insertions(+), 90 deletions(-) diff --git a/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.mo index f7562eaa5e8e1995d2c5ddcbca2050a9641d061e..a01abf9ca7c143db31f1a5d96bc8ac2148711350 100644 GIT binary patch delta 1105 zcmXZaUr19?9Ki9P&dsG2S(+|4otoKSMU50o^TGZ>ky6$}5=^`<(`|OQ(kNOFg)dTx z5EThMBvwcTdnihZl7ilng2D)b3`??yAc%y~_s6|(xu0{+J@@>6zjMw=+l{t|GmiM@ z6p@)ck!%rpxyteb&eH#h75F}1WI3jJMQSk@4`MT}$5C8_Z!rU>u?D}{<369rS^8zD z^KPTYyYG{@RMMDaUgneorzBp~ z`L&piyKMKPR(u#W-bvf|IT}1Nz)OD|M-A{4L-+>u$C^?W$5zy%F;Ta65OoK}P%CAo!>fIQzy@xyLKSE6~ zi7n_|Yi)5DchDb4mX_bBm({aQWIHzDdE(0j8hWdpe05?2Ms)&eVvkV+&!aB%&$fuN z-Sl^(-sTq6$~#dL>&FIsZkxmd^y@cTmwE{6_A+pXhHmXwEJxX7RaAk!boZfV{0tqK z#8gaWawa-a6Uj>4O`p$lZShxC)>RJQ^yGPifpAB_jQF=54|GS`%e&1$$S@m&q5kp? zBk{$P<48Lc3Hyg%xXT>=Kqyh{JL<}A4F@MDdSYEc!}K==Vn$c&bZ=s)WIn~y9Ee8y bB4*6r*JX4V<}t&J#*CgGBb>NYdfELSh;*9K delta 1100 zcmXZaT}YE*6u|NGHb17eP@Cz><(8VJ({RWP`?7B$gFd_n@}kYnv6!1}VnosGLW;WZ zV%-!95kypk!U`hk!fryksX<-uVkAjIAQC}F|I=Q0d4K0Td-k65d^{YS8Jx>oQY(f? zzD~q0BH674mvD*v5AMeNHj!$y*Ng1I797A!*oLpM40BkH%jm;3bKK(;xk2tjotHta z_s%IP=_1H7FoQ+gMKti^Stcd2O*A(T$k22NuYUO?6$myt&% zd2PZcNJ)9skScsA%YYVG#$sGWE%X~J(B=~Hq65>|kIR_DcKqn33H*f*(6&P)fKQQ6 zNO@zSP8;qgKa9Gg6Da~MoJL*2H0p=u%?Y1TJI-SzuA&W#nhN99SVHbbPDxtL@uOHu ze%|yV>WYU@>)kR<-6i0WG%qdm2DQKk9KkQBe>~DG!f}cpwUL{sTRVli1J6+#|BAZx zKTwb6FY1}s?i3kDH}>Hj>=Dj?k)WFaqeWyd`cSt#f&UAcPNCk7N2V|FIQd)D28~vc zv)F*T#aHkc&LSmb4fV3t?-DtPCvbxLa+^SJwUu9s@en3;0%~LPsD*!`erVmaiDg^K zPoduC0o0X8P#e3B2k^bA;o&&Q`%o|SeeCTgctN0B`wctM(otBE7e~p@pmw}~7BrZ& z0gJH$t*DLIGtWv_s!F\n" +"PO-Revision-Date: 2011-12-06 21:16+0000\n" +"Last-Translator: gandaro \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" @@ -185,7 +185,7 @@ msgstr "Yeeeaaah! Geschafft!" #: mediagoblin/submit/views.py:133 msgid "Invalid file type." -msgstr "" +msgstr "Ungültiger Dateityp." #: mediagoblin/templates/mediagoblin/404.html:21 msgid "Oops!" @@ -284,7 +284,7 @@ msgstr "Bestätigen" #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" -msgstr "" +msgstr "Passwort wiederherstellen" #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:30 msgid "Send instructions" @@ -409,7 +409,7 @@ msgstr "%(username)ss Medien" #: mediagoblin/templates/mediagoblin/user_pages/media.html:57 #, python-format msgid "By %(username)s on %(date)s" -msgstr "" +msgstr "Von %(username)s am %(date)s" #: mediagoblin/templates/mediagoblin/user_pages/media.html:67 msgid "Post a comment" diff --git a/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.mo index 8f37922f516674ff72c9a1ffbc37fb0ece113507..3e0a84bf3c263d1fcca55f045823f7aac1023cb0 100644 GIT binary patch delta 610 zcmXZZPbhC{s2zmUQog^o%lmnL&)f4p&+~gfL+_!>qq1bPh}_yl>hKLK@CPmUhYi?d z7pX=U8qkX!IEs}RLRA;WHjH8|?xCtb#Vt&u`mUo(q#eh)Bq>bfWF^j6zz}a?{%$jE$)6&%I5;d0!a=J^)7sVysbyzHQch|uM>qAJ z+$A}fQn*S|ii3kcC%#W}`aI9`_WYjT^Lw8cUl&gg%d*WPa@8i{z!$XPH#)JTU8D}1 zuoAs!!4Yi5F|5EP)V?U{c`2;MeboLuZlZ~LZf}Q33kEwREA<2s3To#6!y(p^n^=Pv z|MdrKApgQybht!DF@hdEM(w-734B5;x;l%4J*b1HunJc?v&EaQQwUMmMlTj{0e^7- z7rI1-aS!|P5_RAYPGeWM$Puoi_B(n+%5fYsIEg+yM}4tRWCxLKuLwQjLTw14Zajy& zNfdR%4Epg52k{+e(A8Ibxh)KmA7CTiBg@MNHlfqawirOYNDlQ^Itv7)1h;6%JG9}W zd18I5vHA_)(6BFH=A3T3EfiZ`HR6d4^SUixZp5N%=|tR!EE`F!Cu8CBop3xICQPJ^ Lji|ZXGjI6=@>^AV diff --git a/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.po index e5c6356e..c3c29b89 100644 --- a/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.po @@ -11,7 +11,7 @@ msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://bugs.foocorp.net/projects/mediagoblin/issues\n" "POT-Creation-Date: 2011-12-04 10:24-0600\n" -"PO-Revision-Date: 2011-12-04 19:15+0000\n" +"PO-Revision-Date: 2011-12-06 20:04+0000\n" "Last-Translator: aleksejrs \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -252,7 +252,7 @@ msgid "" "To add your own media, place comments, save your favourites and more, you " "can log in with your MediaGoblin account." msgstr "" -"Por aldoni viajn proprajn dosierojn, fari liston de plej plaĉantaj por vi, " +"Por aldoni viajn proprajn dosierojn, fari al vi liston de la plej plaĉaj, " "ks, vi povas ensaluti je via MediaGoblina konto." #: mediagoblin/templates/mediagoblin/root.html:31 @@ -272,7 +272,7 @@ msgstr "" #: mediagoblin/templates/mediagoblin/root.html:44 msgid "Most recent media" -msgstr "Plej nove aldonitaj dosieroj" +msgstr "Laste aldonitaj dosieroj" #: mediagoblin/templates/mediagoblin/auth/change_fp.html:29 msgid "Enter your new password" diff --git a/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.mo index bed6aab8a3cc20c7410f280e4435a62226c9a104..0f7f4026aafb3f78d9f6d073c48985f57dc924e7 100644 GIT binary patch delta 1247 zcmXZaOK4PQ6u|K_6DMgV8XFyBeAM|Sk1?7tYJ9}{NQ|xV1sXJq#6sXYxs%*5b4Tai zQKG_tpitcicj2am4yB5^v7JKEwuX*H5bUZOp@kx1yQx?oAao)A4{E?XfI z!9Q>TKE@_|jkQ=Cmy)y)%!`XG!6a&;o!E*as0YvBJUoYb?(+NpZ(xG;Z@3YkBfU$z znQe3c>sar{Wq24rL>K$8WJ)4u3GTA-1hiI8l zDLzD<$Un#> zp^n-8Hf&&>Lfzkj+Tc;t26C9ibEtKmqc&0s@wL{}~AIqo-zD1@h_c4Nh z<0$@%I?BP7BJ1%yuEHO12R_DHjCanCK8bqsUTmbk93apeAH`ibjyk$)ID+?aAI8bL z9Uas{S8+8y!Xd0-aT$lP2cKdcwseVHM1u$LCh7#=*nm5* z5%*QD*F9^h+hlq+Z0%WB`EtpXaC5c%iRC$F($3{Q`keW)oFjSg7_%cQN`F~=$xKNw1M1g}hUxabBA ziPpK%=n=;pCx>Tw!QDh>uVrk{w@prWrff59JZGY4^J|loGR7}h-bCJH?5uOTTlVI& zR*J%vrLDh*!!+=${Z*`596U7F)H0JCJ!u!5jFTpz@r!0W_$9tD80>!Y E4g##w$N&HU delta 1226 zcmXZbOGs2v9LMo9>Nu&SX`^L1ddA17HBMNAQlwI0Sw=+<${^!3bFE9`z0x39agCHNZ)(H9b;8~r#Bd(gyGf)D3*V zAQm+XK`ClcuiJwQF`1*#51v3BjfXn=o2WOsGdDkjI{Nomgr87%{%vkP*djz3;}Gik zcGQs%qCUVdrqIO-e1lvf_l56jiW-ikJCCA{azE-DFQ8uFI_hXA(T~q?2w$L%va^*B zrm-DwU=KdQVk~W&jlL3f=Z#p-{-TRQcifNbaXaehF5^DDi<_~ORoCKf)EiyGWjKvH z@H1Y-J|vtii3g6BF2n_iz*b z!fn_~Z2F}=k2;Z?s2li)oJrKjW`D{7JkIziuEuxh(~*XFg9@+#%dip4F_ym__*5B) z%g(Mf@zwe9+N%ZgHz?PX8N(ShE#>C7)Rh+o*G=EIq-D#DX;_9UvzF?UUb>;lpD?HM zR{mPUq_0v&Wm-8(Ce-L5Q#sQ04uo5L%JYS*SGiefsWIcQO4`mE+0r&\n" "Language-Team: Spanish (Castilian) (http://www.transifex.net/projects/p/mediagoblin/team/es/)\n" "MIME-Version: 1.0\n" @@ -83,12 +83,12 @@ msgstr "" #: mediagoblin/auth/views.py:203 msgid "You must be logged in so we know who to send the email to!" msgstr "" -"Debes iniciar sesión para que podamos saber a quién le enviamos el correo " +"¡Debes iniciar sesión para que podamos saber a quién le enviamos el correo " "electrónico!" #: mediagoblin/auth/views.py:211 msgid "You've already verified your email address!" -msgstr "Ya haz verificado tu dirección de email!" +msgstr "¡Ya has verificado tu dirección de correo!" #: mediagoblin/auth/views.py:224 msgid "Resent your verification email." @@ -113,7 +113,7 @@ msgstr "Etiquetas" #: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 msgid "Seperate tags by commas." -msgstr "Separar etiquetas por comas." +msgstr "Separa las etiquetas con comas." #: mediagoblin/edit/forms.py:33 msgid "Slug" @@ -164,7 +164,7 @@ msgstr "Contraseña incorrecta" #: mediagoblin/edit/views.py:192 msgid "Profile edited!" -msgstr "Perfil editado!" +msgstr "¡Perfil editado!" #: mediagoblin/media_types/__init__.py:65 msgid "Could not find any file extension in \"{filename}\"" @@ -184,7 +184,7 @@ msgstr "Debes proporcionar un archivo." #: mediagoblin/submit/views.py:127 msgid "Woohoo! Submitted!" -msgstr "¡Woohoo! ¡Enviado!" +msgstr "¡Yujú! ¡Enviado!" #: mediagoblin/submit/views.py:133 msgid "Invalid file type." @@ -192,7 +192,7 @@ msgstr "Tipo de archivo inválido." #: mediagoblin/templates/mediagoblin/404.html:21 msgid "Oops!" -msgstr "Ups!" +msgstr "¡Ups!" #: mediagoblin/templates/mediagoblin/404.html:24 msgid "There doesn't seem to be a page at this address. Sorry!" @@ -220,7 +220,7 @@ msgstr "Enviar contenido" #: mediagoblin/templates/mediagoblin/base.html:65 msgid "Verify your email!" -msgstr "Verifica tu email!" +msgstr "¡Verifica tu email!" #: mediagoblin/templates/mediagoblin/base.html:72 msgid "log out" @@ -246,7 +246,7 @@ msgstr "Explorar" #: mediagoblin/templates/mediagoblin/root.html:27 msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "Hola, bienvenido a este sitio de MediaGoblin!" +msgstr "Hola, ¡bienvenido a este sitio de MediaGoblin!" #: mediagoblin/templates/mediagoblin/root.html:28 msgid "" @@ -267,7 +267,7 @@ msgstr "" #: mediagoblin/templates/mediagoblin/root.html:31 msgid "Don't have one yet? It's easy!" -msgstr "Aún no tienes una? Es fácil!" +msgstr "¿Aún no tienes una? ¡Es fácil!" #: mediagoblin/templates/mediagoblin/root.html:32 #, python-format @@ -325,10 +325,13 @@ msgid "" "If you think this is an error, just ignore this email and continue being\n" "a happy goblin!" msgstr "" -"Hola %(username)s , para cambiar su contraseña de GNU MediaGoblin, abra la " -"siguiente URL en su navegador: %(verification_url)s Si usted piensa que " -"esto es un error, simplemente ignore este mensaje y siga siendo un duende " -"feliz!" +"Hola %(username)s,\n" +"\n" +"Para cambiar tu contraseña de GNU MediaGoblin, abre la siguiente URL en un navegador:\n" +"\n" +"%(verification_url)s \n" +"\n" +"Si piensas que esto es un error, simplemente ignora este mensaje y sigue siendo un trasgo feliz." #: mediagoblin/templates/mediagoblin/auth/login.html:30 msgid "Logging in failed!" @@ -373,7 +376,7 @@ msgstr "" #: mediagoblin/templates/mediagoblin/edit/edit.html:29 #, python-format msgid "Editing %(media_title)s" -msgstr "Edición %(media_title)s " +msgstr "Editando %(media_title)s " #: mediagoblin/templates/mediagoblin/edit/edit.html:36 #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49 @@ -442,7 +445,7 @@ msgstr "Borrar" #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" -msgstr "Realmente deseas eliminar %(title)s ?" +msgstr "¿Realmente deseas eliminar %(title)s?" #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:50 msgid "Delete Permanently" @@ -488,7 +491,7 @@ msgstr "Es necesario un correo electrónico de verificación" #: mediagoblin/templates/mediagoblin/user_pages/user.html:53 msgid "Almost done! Your account still needs to be activated." -msgstr "Casi terminas! Solo falta activar la cuenta." +msgstr "¡Casi hemos terminado! Solo falta activar la cuenta." #: mediagoblin/templates/mediagoblin/user_pages/user.html:58 msgid "" diff --git a/mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.mo index 95d6d0ae141c335275f075991429810f61f667ac..87e627644267845f356f4b3163792eb54d3f7bbf 100644 GIT binary patch delta 1566 zcmYk*TWDNG9LMol+ve8Ps;zC)nq<;k+N9f6H@3vkVl}Ojk{Cm(l!}(g?qoBvIkP!u zcM&N>D)ynESk_BXEUra@#Y%Ch5ReL8eUXY{p@NFnii%Ld7oWU*|Jk5I;4^d1?EHW8 zpPWmFt{gmfb=lmnF{Q3eG!%t;ZknC;St4$b6GhH{hmQl)4?`xECMAK|GC( z`1O)M<4)$kV*~cKDm8{lT!}||@OtLMSceC39Uexq zsUqHtCs6j8M_KnKuEKN3+0+GW$ItO5`~x>*Q~O+PgYCSPq(fMbBe(_+plmda(upEI zj&I?Y*sYc7!B~e)Xza||T$7bqwB4i^(5zg110 zwGHAZ8;qa?djy+s7Nzw^P&Pb<%~)P~|28gXzJRjd1(bt+i_+=2Ul>S>enSb+&{ZqY zhMsv6<*r^wu2a3UH2(zUWZ&Qx{2L|UmhRf`2T%fypma2Y52D8b{19)YzWR$noCgW| zcn3a=(vjy-TK^Kt#&4kf^Sq04;){4MUP1}7h7{x2kGt?`9Kws(k9FJ+8Py<4ki+;S z_0@R>xA9tgjXI+Y_A`(Zj36I?%A&OTIA(Dk`BQ6YlLXs?*Wo?568GV99FJGd)L*-CMY4ae zKUsRUW&H*prSz^SNGAgCBD*IuV_Y_o@-vmoEuSrm>C%g?IQIMOD_yNpqz#znel zv(sLU`CO#Nawe`LThPR|LB3jcUfU>d*r8~iaK6;rmFO~|F3kM9B6MCo;8_#?|4}LE zidNZh%4Ica^M)wbx;8f#ayDdPw3w!~`_Q&g6Qp_If+!yrs`J(JHc}HdXJl30WFnpO zp)R^GQ^=N1bx#iLwNa{&&Dpp_C`5&7nfg+gn32_1dafUsJYe-8?wk$F84LYS|0ML>KVG3wRvCQR%WVa>32fu()M`Aowc`8 zp=d)lB>Wt~+fuc~KLKCpVq+O(Q5E>!;jlt(~2 delta 1314 zcmX}rduUU46u|LQ`_gvNwmxdDO|N}uW3=l-%PhW_MX8T=ZVW|4NPBN%SjcUYn`YS< z@edIdipmdP10M(~6ht9{BIq9*iZDSKzSva8P(<*B{xzB6_cYxgYYI*A+jJ^qV-V$u=` z;>I~5P52Y;#WT1ITiJ!L%4O6EKEV0-9JP^Ynflzx=AoXX8TErMq=sxlEs#bna1^z% zQTz-rhGmBX0h&oY6{SE5q`q0He)Vul% zxlVb5+K8_)*O(vY5idv04`4Z_Q0wkNo#-k27DrJhDRV_WXMgEnv4D607oou-youV# zZPdb#P_N<@>WSauYAj%PozObmh~ME-yo#&vJ+|X=?uXtbj@rm!+`<0xl0^%NSRmKw z2}}^5#kE+?g^isI^=eY6h4x}Go=0u;66yr6<1)O1`tPXV2eJY;U=NO<{)iu9XD^F) zEc67;jDe-}px)IF7{w#w`ND-F`NXX_0T*K_eu3IZ7n<9%W@LXUzE@t@+R@q8ZjMz| z*7m2IzCI^zEgfI1w37)h-5+(6cC#A~XKz*go^Sd}+RVwC%SByI)bSj%&EIWymo}M; z{);7RT+4HdF9=);ZQVUTLY1(V|nR8$2_R}xztHnUxgBh zlpD9rkM(nB_eO0V&Lw0+D3Y*-o#=K~dfmZ<`Le9ZJg=`eBV|>ltzpO)cgKo3cEodR zbD^Qm=MK~Qf6tr84O`6q@}LPfZZkaw}hgUAfkr4IZry#cT\n" +"PO-Revision-Date: 2011-12-04 23:32+0000\n" +"Last-Translator: osc \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" @@ -59,7 +59,7 @@ msgstr "Desculpe, um usuário com este nome já existe." #: mediagoblin/auth/views.py:77 msgid "Sorry, a user with that email address already exists." -msgstr "" +msgstr "Desculpe, um usuário com esse email já esta cadastrado" #: mediagoblin/auth/views.py:179 msgid "" @@ -75,11 +75,11 @@ msgstr "A chave de verificação ou nome usuário estão incorretos." #: mediagoblin/auth/views.py:203 msgid "You must be logged in so we know who to send the email to!" -msgstr "" +msgstr " " #: mediagoblin/auth/views.py:211 msgid "You've already verified your email address!" -msgstr "" +msgstr "Você já verifico seu email!" #: mediagoblin/auth/views.py:224 msgid "Resent your verification email." @@ -103,7 +103,7 @@ msgstr "Etiquetas" #: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 msgid "Seperate tags by commas." -msgstr "" +msgstr "Separar tags por virgulas." #: mediagoblin/edit/forms.py:33 msgid "Slug" @@ -129,11 +129,11 @@ msgstr "Website" #: mediagoblin/edit/forms.py:49 msgid "Old password" -msgstr "" +msgstr "Senha antiga" #: mediagoblin/edit/forms.py:52 msgid "New Password" -msgstr "" +msgstr "Nova Senha" #: mediagoblin/edit/views.py:65 msgid "An entry with that slug already exists for this user." @@ -149,15 +149,15 @@ msgstr "Você está editando um perfil de usuário. Tenha cuidado." #: mediagoblin/edit/views.py:171 msgid "Wrong password" -msgstr "" +msgstr "Senha errada" #: mediagoblin/edit/views.py:192 msgid "Profile edited!" -msgstr "" +msgstr "Perfil editado!" #: mediagoblin/media_types/__init__.py:65 msgid "Could not find any file extension in \"{filename}\"" -msgstr "" +msgstr " " #: mediagoblin/submit/forms.py:25 msgid "File" @@ -177,7 +177,7 @@ msgstr "Eba! Enviado!" #: mediagoblin/submit/views.py:133 msgid "Invalid file type." -msgstr "" +msgstr "Tipo de arquivo inválido." #: mediagoblin/templates/mediagoblin/404.html:21 msgid "Oops!" @@ -209,11 +209,11 @@ msgstr "Enviar mídia" #: mediagoblin/templates/mediagoblin/base.html:65 msgid "Verify your email!" -msgstr "" +msgstr "Verifique seu email!" #: mediagoblin/templates/mediagoblin/base.html:72 msgid "log out" -msgstr "" +msgstr "Sair" #: mediagoblin/templates/mediagoblin/base.html:75 #: mediagoblin/templates/mediagoblin/auth/login.html:27 @@ -235,7 +235,7 @@ msgstr "Explorar" #: mediagoblin/templates/mediagoblin/root.html:27 msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "" +msgstr "Olá, bemvindo ao site de MediaGoblin." #: mediagoblin/templates/mediagoblin/root.html:28 msgid "" @@ -247,11 +247,11 @@ msgstr "" msgid "" "To add your own media, place comments, save your favourites and more, you " "can log in with your MediaGoblin account." -msgstr "" +msgstr " " #: mediagoblin/templates/mediagoblin/root.html:31 msgid "Don't have one yet? It's easy!" -msgstr "" +msgstr " " #: mediagoblin/templates/mediagoblin/root.html:32 #, python-format @@ -276,11 +276,11 @@ msgstr "Enviar" #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" -msgstr "" +msgstr "Recuperar senha" #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:30 msgid "Send instructions" -msgstr "" +msgstr "Mandar instruções" #: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 msgid "Your password has been changed. Try to log in now." @@ -383,7 +383,7 @@ msgstr "" #: mediagoblin/templates/mediagoblin/media_displays/video.html:19 msgid "Original" -msgstr "" +msgstr "Original" #: mediagoblin/templates/mediagoblin/submit/start.html:26 msgid "Submit yer media" @@ -406,7 +406,7 @@ msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/media.html:67 msgid "Post a comment" -msgstr "" +msgstr "Postar um comentário" #: mediagoblin/templates/mediagoblin/user_pages/media.html:85 msgid "at" @@ -414,15 +414,15 @@ msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/media.html:102 msgid "Post comment!" -msgstr "" +msgstr "Postar comentário!" #: mediagoblin/templates/mediagoblin/user_pages/media.html:124 msgid "Edit" -msgstr "" +msgstr "Editar" #: mediagoblin/templates/mediagoblin/user_pages/media.html:130 msgid "Delete" -msgstr "" +msgstr "Apagar" #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format @@ -556,7 +556,7 @@ msgstr "Mais velho" #: mediagoblin/templates/mediagoblin/utils/pagination.html:50 msgid "Go to page:" -msgstr "" +msgstr "Ir a página:" #: mediagoblin/templates/mediagoblin/utils/tags.html:20 msgid "Tagged with" @@ -564,7 +564,7 @@ msgstr "" #: mediagoblin/templates/mediagoblin/utils/tags.html:25 msgid "and" -msgstr "" +msgstr "e" #: mediagoblin/user_pages/forms.py:24 msgid "Comment" @@ -576,15 +576,15 @@ msgstr "Eu tenho certeza de que quero pagar isso" #: mediagoblin/user_pages/views.py:155 msgid "Oops, your comment was empty." -msgstr "" +msgstr "Opa, seu comentáio estava vazio." #: mediagoblin/user_pages/views.py:161 msgid "Your comment has been posted!" -msgstr "" +msgstr "Seu comentário foi postado!" #: mediagoblin/user_pages/views.py:183 msgid "You deleted the media." -msgstr "" +msgstr "Você deletou a mídia." #: mediagoblin/user_pages/views.py:190 msgid "The media was not deleted because you didn't check that you were sure." diff --git a/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.mo index 0e34144d2509f5c2236c8289db8299e66f3a9788..7e62de833735c4958ffc9e0b1597f4c2732596b4 100644 GIT binary patch delta 213 zcmXBNzY0MC0L9_sPnT>aDbf{TVY=LVDG#7zlSwRg6QvB2GI;?bC5yVN@(NOHlFexF z0Ddujoim*C7(GXak1;iUQp=LMl7?j|f){My9ZOiKNMY)tN(js_jqvb}ZOPWaD9 I?`kcLFW=cBh5!Hn delta 210 zcmXBNArAoo0LAflX2&$iY;HHV9gSdjID7(vCL*aOoy{iP6u~!;DA#P4eFwoN2&RdG z58yx2Z|{Zop5Y@reay9ONJCE=OPc#q4lmfpJJzwX``5t&*~K#Uk~s6ur<;M-NcP26DY\n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -251,7 +251,7 @@ msgid "" "To add your own media, place comments, save your favourites and more, you " "can log in with your MediaGoblin account." msgstr "" -"Для добавления собственных файлов, комментирования, ведения списка любиых " +"Для добавления собственных файлов, комментирования, ведения списка любимых " "файлов и т. п. вы можете представиться с помощью вашей MediaGoblin’овой " "учётной записи." diff --git a/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.mo index 4e71eaa73ef7d50018f120429c17906180963b8d..5ab7befa15e400d1a9754a72ea90210648fec115 100644 GIT binary patch delta 2451 zcmaLXTWnNC7zglaNograDaxg-rL*)x3)=#%f?UfY1Y(pW+@eG=vwH^i?Cv?UIk&Kl zxFPD3HpCo#Fa~u)e5gqYNxcxXi{x}kNCAx~30^`pXrl1}UyM;7{C~UK0-DGJzcaJv z%zX2G-*out8_%4%H6wSaim_XZ8S7w-oo+6B4bH;+A25RX>IWHXfZO02xDW1tFT*YH zTIKf#S{a*xaR=N0yI~#FpnwLP1wVtd-i=n4W1I2tGbT>L?j_|HF2Y8PKZp0jAK+~G zdu3eR#@GUk7gh|z9*nm_+As}i0~aoWFTq}T64JVpkPiG^Tdw>PuzXCbNH{o2!y2>eRfS6(rL7G1Zsbo6j@ED|%z6B4$ z58U+=_w0^wet1yc3dH4eQk2RoxYcb)&nQ#*3;TMo1byk!EI18z%CLt~S4V(=ZV0T;q z7J?M;X1EPTA+7rwd>CGa+hH}Lp@HtqE$pQExtb%7N zo`dw=Cy)ZUGB#5CYh&H&RlI*-{i=2T$)-iz5SF8xeB+RCEEP}mmB(9-7(!3?#g*Y- zYx=t5Krrrj%F6PLa*Ksv)Dw=JCz zp0(YWp*#NV+V(?TN1P1@vb2<5e3!@MP$n%LGZ^Q=xrt%v(AO&ky;RSq|B1AWsk_Gi zvxTf%y@|fwo3W%936pEKdoCl_ESqk z)r_dd{R?%=>bS=zhJ`KtrL8Ac??NPL#SK*~n864)gM8A)^2LHKG}Gl7D;UivJb2s= z&c&1^{jXZTogLL|#|rW$j_iN5B+|dVn0I9PBZ+vV5#)>cLH?NJj^atFnM!lxiC`qe z_Gc{N(Pu4fla0YJ?S=5mtEJqr+if3Ibw?5^8Rnkuh$Q{!$Rt*|`@ogg$F7Fnu3ETD z+K4jmnOW{+GnFu1|M~Vq3#MzVhD?EK&u9N09)<~Nr=M_5x6 zj0VNLE?FcglA+T7VU8jvc}f}5bb`FakvPgven>O3eJpC}M|7mmKh@FReo)wHs?zk! z>_0R9_Z`RTxl8FlT;u-X&i1*{n5if^m8c4xoqnNn&A`;Rx`{MfZYqwrqMC+w<(LRY zofLJkq2kI#Wp!btvVLoqyLGoEGeLf0IDBu9bDLYrGeruo%U-$^%EP13ENMgB1}=~4 zw&NzHf3fTOf#_YyW5svM8?s7nQEbYCsx$;0C5)n_)I=erIBGr~6KT{CsS`+td04m5 z9C2MB!lto??xR(Uf;`GwDXF*4)+K3C80Ijy37JDi1xDM&C>NaJo`7?M_eI zh+D@uDmGC-|I_g>%HYc2hR77h&C^9Z%x%F9*A7ODdD=3O4)S)03TfkHw1ja_|I(iZ z2Y-joE`O>%itEa49hLBxtkCC8ceAWC!Rssj%uVI`-6(ya>2(jJDPGucauUwx#wy#vM^7sDE-Z}l$7T8~K wOAK*^pz&osRC@1D@=AB2v^ll(`rh|BQ%pzM1sW5Lic6TvGNqLgM0scb0J;&z761SM delta 1416 zcmX}qeP~r>9KiA4ZMr*Md%1IV-RnJb_wL2rY@52-8t7N%DIvQEB}6PWBzhs3e`EzYE&C%O%|N1}@6!&!;e3A2bDo#q z^Lx&>&ra`s|3<<1WuM56H6oQFa;91&jGy97yor7Ib&W_F25LpRumQK@9^8s^sJ~ys z0=$iS+#gtk(K-LHT?h3+kA%jT2Arm&n2veW8-0m-;DXoxGg1V(gRfz! z!AYpx+t^0?L<3d9Z+K1O?>LOvwIUDWkH}Q1ZWQUn9<0F8af15^CQzSf8YzOjgH&JU zQBV9H%keL)!V=Qg^P16*8!>{tUVjXA>1|w&hf%Nlg4aLe^^cz*&>OvrrT7_^;1zW7 zI_kUH!|DbeM4iYK@=1;%k9@*Q&;JQ^J+HLi>;(U4~It;AQN`H&L(q9qJRWBFo2c z2R?vDv1cd2NdkS+Ysgr+gZi%ON&9*1#SQoo7T_(s4{xKMcNhJ*Jb&8%YoMroqtVgT z)44&-Rs}=*$E;Y)a*SRt*c#7f+}!?@osF-zorGGbx>^%y$!07kZH`*4ndXc!YQ>YL z3_A9KWJFVQ?=B8RoHK(EZ0)LP@j6GIIOav z&sT1@4c9gfnF%XDXq@w@#gb^geeH}dup|APnM%eD7PbsGcgRwUjr-KcWgRLTt|_+0 zj6pM#8MB?ZIu?GYdRHpWB1;|eq-#2tjwdbY8#aekUwNylh%~6F@{k&e@YN`N@`}K9#SWP-@*4m0ayAw{3UHGnSJ)kTY_2)-fz~r7c;y+p*J$|1(nq(LdFZ z;1gwoc4j2!rjthI!ugo(s9V9E%D?`DP&zKAE6EW%Z5kJ++0DE-J(81@oiOaIEB^v+ C4-QEH diff --git a/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.po index a44f7866..34cf1679 100644 --- a/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.po @@ -9,8 +9,8 @@ msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://bugs.foocorp.net/projects/mediagoblin/issues\n" "POT-Creation-Date: 2011-12-04 10:24-0600\n" -"PO-Revision-Date: 2011-12-04 16:23+0000\n" -"Last-Translator: cwebber \n" +"PO-Revision-Date: 2011-12-10 23:09+0000\n" +"Last-Translator: martin \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -57,7 +57,7 @@ msgstr "Prepáč, rovnaké prihlasovacie meno už niekto používa." #: mediagoblin/auth/views.py:77 msgid "Sorry, a user with that email address already exists." -msgstr "" +msgstr "Prepáč, používateľ s rovnakou e-mailovou adresou už existuje." #: mediagoblin/auth/views.py:179 msgid "" @@ -73,11 +73,11 @@ msgstr "Nesprávny overovací kľúč alebo používateľské ID" #: mediagoblin/auth/views.py:203 msgid "You must be logged in so we know who to send the email to!" -msgstr "" +msgstr "Aby sme ti mohli zaslať e-mail, je potrebné byť prihláseným!" #: mediagoblin/auth/views.py:211 msgid "You've already verified your email address!" -msgstr "" +msgstr "Tvoja e-mailová adresa už bola raz overená!" #: mediagoblin/auth/views.py:224 msgid "Resent your verification email." @@ -101,7 +101,7 @@ msgstr "Štítky" #: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 msgid "Seperate tags by commas." -msgstr "" +msgstr "Oddeľ štítky pomocou čiarky." #: mediagoblin/edit/forms.py:33 msgid "Slug" @@ -126,11 +126,11 @@ msgstr "Webstránka" #: mediagoblin/edit/forms.py:49 msgid "Old password" -msgstr "" +msgstr "Staré heslo" #: mediagoblin/edit/forms.py:52 msgid "New Password" -msgstr "" +msgstr "Nové heslo" #: mediagoblin/edit/views.py:65 msgid "An entry with that slug already exists for this user." @@ -146,15 +146,15 @@ msgstr "Upravuješ používateľský profil. Pristupuj opatrne." #: mediagoblin/edit/views.py:171 msgid "Wrong password" -msgstr "" +msgstr "Nesprávne heslo" #: mediagoblin/edit/views.py:192 msgid "Profile edited!" -msgstr "" +msgstr "Profil upravený!" #: mediagoblin/media_types/__init__.py:65 msgid "Could not find any file extension in \"{filename}\"" -msgstr "" +msgstr "Nebolo možné nájsť žiadnu príponu v súbore \"{filename}\"" #: mediagoblin/submit/forms.py:25 msgid "File" @@ -174,7 +174,7 @@ msgstr "Juchú! Úspešne vložené!" #: mediagoblin/submit/views.py:133 msgid "Invalid file type." -msgstr "" +msgstr "Nesprávny typ súboru." #: mediagoblin/templates/mediagoblin/404.html:21 msgid "Oops!" @@ -206,11 +206,11 @@ msgstr "Vložiť výtvor" #: mediagoblin/templates/mediagoblin/base.html:65 msgid "Verify your email!" -msgstr "" +msgstr "Over si e-mail!" #: mediagoblin/templates/mediagoblin/base.html:72 msgid "log out" -msgstr "" +msgstr "odhlásenie" #: mediagoblin/templates/mediagoblin/base.html:75 #: mediagoblin/templates/mediagoblin/auth/login.html:27 @@ -232,23 +232,27 @@ msgstr "Preskúmať" #: mediagoblin/templates/mediagoblin/root.html:27 msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "" +msgstr "Ahoj, vitaj na tejto MediaGoblin stránke!" #: mediagoblin/templates/mediagoblin/root.html:28 msgid "" "This site is running MediaGoblin, an " "extraordinarily great piece of media hosting software." msgstr "" +"Táto stránka používa MediaGoblin, " +"výnimočne skvelý kus softvéru na hostovanie médií." #: mediagoblin/templates/mediagoblin/root.html:29 msgid "" "To add your own media, place comments, save your favourites and more, you " "can log in with your MediaGoblin account." msgstr "" +"Pre pridanie vlastných výtvorov, vloženie komentárov, uloženie svojich " +"obľúbených položiek a viac, sa musíš prihlásiť so svojim MediaGoblin účtom." #: mediagoblin/templates/mediagoblin/root.html:31 msgid "Don't have one yet? It's easy!" -msgstr "" +msgstr "Ešte žiaden nemáš? Je to jednoduché!" #: mediagoblin/templates/mediagoblin/root.html:32 #, python-format @@ -257,6 +261,9 @@ msgid "" " or\n" " Set up MediaGoblin on your own server" msgstr "" +"<a class=\"header_submit_highlight\" href=\"%(register_url)s\">Vytvoriť bezplatný účet</a>\n" +" alebo\n" +" <a class=\"header_submit\" href=\"http://wiki.mediagoblin.org/HackingHowto\">Sprevádzkovať MediaGoblin na vlastnom serveri</a>" #: mediagoblin/templates/mediagoblin/root.html:44 msgid "Most recent media" @@ -273,11 +280,11 @@ msgstr "Vložiť" #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" -msgstr "" +msgstr "Obnoviť heslo" #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:30 msgid "Send instructions" -msgstr "" +msgstr "Zaslať inštrukcie" #: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 msgid "Your password has been changed. Try to log in now." @@ -377,11 +384,11 @@ msgstr "Úprava profilu, ktorý vlastní %(username)s" #: mediagoblin/templates/mediagoblin/listings/tag.html:35 #, python-format msgid "Media tagged with: %(tag_name)s" -msgstr "" +msgstr "Výtvory označené s: %(tag_name)s" #: mediagoblin/templates/mediagoblin/media_displays/video.html:19 msgid "Original" -msgstr "" +msgstr "Originál" #: mediagoblin/templates/mediagoblin/submit/start.html:26 msgid "Submit yer media" @@ -390,7 +397,7 @@ msgstr "Vlož svoj výtvor" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format msgid "%(username)s's media" -msgstr "" +msgstr "Výtvory používateľa %(username)s" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:37 #, python-format @@ -400,27 +407,27 @@ msgstr "Výtvory, ktoré vlastní %(username)s" #: mediagoblin/templates/mediagoblin/user_pages/media.html:57 #, python-format msgid "By %(username)s on %(date)s" -msgstr "" +msgstr "Od %(username)s v čase %(date)s" #: mediagoblin/templates/mediagoblin/user_pages/media.html:67 msgid "Post a comment" -msgstr "" +msgstr "Zaslať komentár" #: mediagoblin/templates/mediagoblin/user_pages/media.html:85 msgid "at" -msgstr "" +msgstr "o" #: mediagoblin/templates/mediagoblin/user_pages/media.html:102 msgid "Post comment!" -msgstr "" +msgstr "Zaslať komentár!" #: mediagoblin/templates/mediagoblin/user_pages/media.html:124 msgid "Edit" -msgstr "" +msgstr "Upraviť" #: mediagoblin/templates/mediagoblin/user_pages/media.html:130 msgid "Delete" -msgstr "" +msgstr "Odstrániť" #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format @@ -552,15 +559,15 @@ msgstr "Staršie" #: mediagoblin/templates/mediagoblin/utils/pagination.html:50 msgid "Go to page:" -msgstr "" +msgstr "Ísť na stránku:" #: mediagoblin/templates/mediagoblin/utils/tags.html:20 msgid "Tagged with" -msgstr "" +msgstr "Označené s" #: mediagoblin/templates/mediagoblin/utils/tags.html:25 msgid "and" -msgstr "" +msgstr "a" #: mediagoblin/user_pages/forms.py:24 msgid "Comment" @@ -572,19 +579,19 @@ msgstr "Jednoznačne to chcem odstrániť" #: mediagoblin/user_pages/views.py:155 msgid "Oops, your comment was empty." -msgstr "" +msgstr "Ajaj, tvoj komentár bol prázdny." #: mediagoblin/user_pages/views.py:161 msgid "Your comment has been posted!" -msgstr "" +msgstr "Tvoj komentár bol zaslaný!" #: mediagoblin/user_pages/views.py:183 msgid "You deleted the media." -msgstr "" +msgstr "Výtvor bol odstránený tebou." #: mediagoblin/user_pages/views.py:190 msgid "The media was not deleted because you didn't check that you were sure." -msgstr "" +msgstr "Výtvor nebol odstránený, nakoľko chýbala tvoja konfirmácia." #: mediagoblin/user_pages/views.py:198 msgid "You are about to delete another user's media. Proceed with caution." From e91a4dcb738f28fe75d0387175e97dc16ea977fb Mon Sep 17 00:00:00 2001 From: Will Kahn-Greene Date: Mon, 12 Dec 2011 10:48:24 -0500 Subject: [PATCH 188/302] Tweak rest formatting --- docs/source/media-types.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/source/media-types.rst b/docs/source/media-types.rst index 809efe07..76478143 100644 --- a/docs/source/media-types.rst +++ b/docs/source/media-types.rst @@ -15,13 +15,13 @@ Video To enable video, first install gstreamer and the python-gstreamer bindings (as well as whatever gstremaer extensions you want, -good/bad/ugly). On Debianoid systems: +good/bad/ugly). On Debianoid systems:: sudo apt-get install python-gst0.10 -Next, modify (and possibly copy over from mediagoblin.ini) your -mediagoblin_local.ini. Uncomment this line in the [mediagoblin] -section: +Next, modify (and possibly copy over from ``mediagoblin.ini``) your +``mediagoblin_local.ini``. Uncomment this line in the ``[mediagoblin]`` +section:: media_types = mediagoblin.media_types.image, mediagoblin.media_types.video From a46f645e7fc724547979ced22c8f9b7aa4ae0d51 Mon Sep 17 00:00:00 2001 From: Will Kahn-Greene Date: Mon, 12 Dec 2011 11:12:59 -0500 Subject: [PATCH 189/302] Fix doc footer This has the correct copyright statement. --- docs/source/_templates/mg_theme/layout.html | 39 --- .../_templates/mg_theme/static/default.css_t | 299 ------------------ docs/source/_templates/mg_theme/theme.conf | 31 -- docs/source/conf.py | 7 +- docs/source/themes/mg/layout.html | 29 ++ docs/source/themes/mg/theme.conf | 5 + 6 files changed, 38 insertions(+), 372 deletions(-) delete mode 100644 docs/source/_templates/mg_theme/layout.html delete mode 100644 docs/source/_templates/mg_theme/static/default.css_t delete mode 100644 docs/source/_templates/mg_theme/theme.conf create mode 100644 docs/source/themes/mg/layout.html create mode 100644 docs/source/themes/mg/theme.conf diff --git a/docs/source/_templates/mg_theme/layout.html b/docs/source/_templates/mg_theme/layout.html deleted file mode 100644 index eccda14b..00000000 --- a/docs/source/_templates/mg_theme/layout.html +++ /dev/null @@ -1,39 +0,0 @@ -{# - default/layout.html - ~~~~~~~~~~~~~~~~~~~ - - Sphinx layout template for the default theme. - - :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. - :license: BSD, see LICENSE for details. -#} -{% extends "basic/layout.html" %} - -{% if theme_collapsiblesidebar|tobool %} -{% set script_files = script_files + ['_static/sidebar.js'] %} -{% endif %} - -{%- block footer %} - - - -{%- endblock %} diff --git a/docs/source/_templates/mg_theme/static/default.css_t b/docs/source/_templates/mg_theme/static/default.css_t deleted file mode 100644 index f200a0fe..00000000 --- a/docs/source/_templates/mg_theme/static/default.css_t +++ /dev/null @@ -1,299 +0,0 @@ -/* - * default.css_t - * ~~~~~~~~~~~~~ - * - * Sphinx stylesheet -- default theme. - * - * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ - -@import url("basic.css"); - -/* -- page layout ----------------------------------------------------------- */ - -body { - font-family: {{ theme_bodyfont }}; - font-size: 100%; - background-color: {{ theme_footerbgcolor }}; - color: #000; - margin: 0; - padding: 0; -} - -div.document { - background-color: {{ theme_sidebarbgcolor }}; -} - -div.documentwrapper { - float: left; - width: 100%; -} - -div.bodywrapper { - margin: 0 0 0 230px; -} - -div.body { - background-color: {{ theme_bgcolor }}; - color: {{ theme_textcolor }}; - padding: 0 20px 30px 20px; -} - -{%- if theme_rightsidebar|tobool %} -div.bodywrapper { - margin: 0 230px 0 0; -} -{%- endif %} - -div.footer { - color: {{ theme_footertextcolor }}; - width: 100%; - padding: 9px 0 9px 0; - text-align: center; - font-size: 75%; -} - -div.footer a { - color: {{ theme_footertextcolor }}; - text-decoration: underline; -} - -div.related { - background-color: {{ theme_relbarbgcolor }}; - line-height: 30px; - color: {{ theme_relbartextcolor }}; -} - -div.related a { - color: {{ theme_relbarlinkcolor }}; -} - -div.sphinxsidebar { - {%- if theme_stickysidebar|tobool %} - top: 30px; - bottom: 0; - margin: 0; - position: fixed; - overflow: auto; - height: auto; - {%- endif %} - {%- if theme_rightsidebar|tobool %} - float: right; - {%- if theme_stickysidebar|tobool %} - right: 0; - {%- endif %} - {%- endif %} -} - -{%- if theme_stickysidebar|tobool %} -/* this is nice, but it it leads to hidden headings when jumping - to an anchor */ -/* -div.related { - position: fixed; -} - -div.documentwrapper { - margin-top: 30px; -} -*/ -{%- endif %} - -div.sphinxsidebar h3 { - font-family: {{ theme_headfont }}; - color: {{ theme_sidebartextcolor }}; - font-size: 1.4em; - font-weight: normal; - margin: 0; - padding: 0; -} - -div.sphinxsidebar h3 a { - color: {{ theme_sidebartextcolor }}; -} - -div.sphinxsidebar h4 { - font-family: {{ theme_headfont }}; - color: {{ theme_sidebartextcolor }}; - font-size: 1.3em; - font-weight: normal; - margin: 5px 0 0 0; - padding: 0; -} - -div.sphinxsidebar p { - color: {{ theme_sidebartextcolor }}; -} - -div.sphinxsidebar p.topless { - margin: 5px 10px 10px 10px; -} - -div.sphinxsidebar ul { - margin: 10px; - padding: 0; - color: {{ theme_sidebartextcolor }}; -} - -div.sphinxsidebar a { - color: {{ theme_sidebarlinkcolor }}; -} - -div.sphinxsidebar input { - border: 1px solid {{ theme_sidebarlinkcolor }}; - font-family: sans-serif; - font-size: 1em; -} - - -/* -- hyperlink styles ------------------------------------------------------ */ - -a { - color: {{ theme_linkcolor }}; - text-decoration: none; -} - -a:visited { - color: {{ theme_visitedlinkcolor }}; - text-decoration: none; -} - -a:hover { - text-decoration: underline; -} - -{% if theme_externalrefs|tobool %} -a.external { - text-decoration: none; - border-bottom: 1px dashed {{ theme_linkcolor }}; -} - -a.external:hover { - text-decoration: none; - border-bottom: none; -} -{% endif %} - -/* -- body styles ----------------------------------------------------------- */ - -div.body h1, -div.body h2, -div.body h3, -div.body h4, -div.body h5, -div.body h6 { - font-family: {{ theme_headfont }}; - background-color: {{ theme_headbgcolor }}; - font-weight: normal; - color: {{ theme_headtextcolor }}; - border-bottom: 1px solid #ccc; - margin: 20px -20px 10px -20px; - padding: 3px 0 3px 10px; -} - -div.body h1 { margin-top: 0; font-size: 200%; } -div.body h2 { font-size: 160%; } -div.body h3 { font-size: 140%; } -div.body h4 { font-size: 120%; } -div.body h5 { font-size: 110%; } -div.body h6 { font-size: 100%; } - -a.headerlink { - color: {{ theme_headlinkcolor }}; - font-size: 0.8em; - padding: 0 4px 0 4px; - text-decoration: none; -} - -a.headerlink:hover { - background-color: {{ theme_headlinkcolor }}; - color: white; -} - -div.body p, div.body dd, div.body li { - text-align: justify; - line-height: 130%; -} - -div.admonition p.admonition-title + p { - display: inline; -} - -div.admonition p { - margin-bottom: 5px; -} - -div.admonition pre { - margin-bottom: 5px; -} - -div.admonition ul, div.admonition ol { - margin-bottom: 5px; -} - -div.note { - background-color: #eee; - border: 1px solid #ccc; -} - -div.seealso { - background-color: #ffc; - border: 1px solid #ff6; -} - -div.topic { - background-color: #eee; -} - -div.warning { - background-color: #ffe4e4; - border: 1px solid #f66; -} - -p.admonition-title { - display: inline; -} - -p.admonition-title:after { - content: ":"; -} - -pre { - padding: 5px; - background-color: {{ theme_codebgcolor }}; - color: {{ theme_codetextcolor }}; - line-height: 120%; - border: 1px solid #ac9; - border-left: none; - border-right: none; -} - -tt { - background-color: #ecf0f3; - padding: 0 1px 0 1px; - font-size: 0.95em; -} - -th { - background-color: #ede; -} - -.warning tt { - background: #efc2c2; -} - -.note tt { - background: #d6d6d6; -} - -.viewcode-back { - font-family: {{ theme_bodyfont }}; -} - -div.viewcode-block:target { - background-color: #f4debf; - border-top: 1px solid #ac9; - border-bottom: 1px solid #ac9; -} diff --git a/docs/source/_templates/mg_theme/theme.conf b/docs/source/_templates/mg_theme/theme.conf deleted file mode 100644 index 49442e3b..00000000 --- a/docs/source/_templates/mg_theme/theme.conf +++ /dev/null @@ -1,31 +0,0 @@ -[theme] -inherit = basic -stylesheet = default.css -pygments_style = sphinx - -[options] -rightsidebar = false -stickysidebar = false -collapsiblesidebar = false -externalrefs = false - -footerbgcolor = #b11818 -footertextcolor = #ffffff -sidebarbgcolor = #6a0000 -sidebartextcolor = #ffffff -sidebarlinkcolor = #98dbcc -relbarbgcolor = #b11818 -relbartextcolor = #ffffff -relbarlinkcolor = #ffffff -bgcolor = #ffffff -textcolor = #000000 -headbgcolor = #fdeded -headtextcolor = #20435c -headlinkcolor = #c60f0f -linkcolor = #355f7c -visitedlinkcolor = #355f7c -codebgcolor = #eeffcc -codetextcolor = #333333 - -bodyfont = sans-serif -headfont = 'Trebuchet MS', sans-serif diff --git a/docs/source/conf.py b/docs/source/conf.py index eee9900f..f4d194e6 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -28,7 +28,7 @@ sys.path.insert(0, os.path.abspath('.')) extensions = ["mgext.youcanhelp"] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ['source/_templates'] # The suffix of source filenames. source_suffix = '.rst' @@ -91,7 +91,8 @@ pygments_style = 'sphinx' # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'default' +# html_theme = 'default' +html_theme = 'mg' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the @@ -99,7 +100,7 @@ html_theme = 'default' #html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] +html_theme_path = ['themes'] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". diff --git a/docs/source/themes/mg/layout.html b/docs/source/themes/mg/layout.html new file mode 100644 index 00000000..891ed64c --- /dev/null +++ b/docs/source/themes/mg/layout.html @@ -0,0 +1,29 @@ +{# + default/layout.html + ~~~~~~~~~~~~~~~~~~~ + + Sphinx layout template for the default theme. + + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +#} +{% extends "basic/layout.html" %} + +{% if theme_collapsiblesidebar|tobool %} +{% set script_files = script_files + ['_static/sidebar.js'] %} +{% endif %} + +{%- block footer %} + +{%- endblock %} diff --git a/docs/source/themes/mg/theme.conf b/docs/source/themes/mg/theme.conf new file mode 100644 index 00000000..f4fbd8cc --- /dev/null +++ b/docs/source/themes/mg/theme.conf @@ -0,0 +1,5 @@ +[theme] +inherit = default +stylesheet = default.css +pygments_style = sphinx + From 449f58e446ff50f9c84a99a123bd0225a4907f52 Mon Sep 17 00:00:00 2001 From: Will Kahn-Greene Date: Mon, 12 Dec 2011 11:41:29 -0500 Subject: [PATCH 190/302] Update version numbers --- docs/source/conf.py | 4 ++-- mediagoblin/_version.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index f4d194e6..829679b1 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -48,9 +48,9 @@ copyright = u'2011, Free Software Foundation, Inc and contributors' # built documents. # # The short X.Y version. -version = '0.1.0' +version = '0.2.0' # The full version, including alpha/beta/rc tags. -release = '0.1.0' +release = '0.2.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/mediagoblin/_version.py b/mediagoblin/_version.py index d6c6e20d..7a41cf7c 100644 --- a/mediagoblin/_version.py +++ b/mediagoblin/_version.py @@ -14,4 +14,4 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -__version__ = "0.1.0" +__version__ = "0.2.0" From 6ae878e730e006ab674f12c581af8447a0994a9f Mon Sep 17 00:00:00 2001 From: Will Kahn-Greene Date: Mon, 12 Dec 2011 11:52:24 -0500 Subject: [PATCH 191/302] Changer version to -dev --- docs/source/conf.py | 4 ++-- mediagoblin/_version.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index 829679b1..dce254a1 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -48,9 +48,9 @@ copyright = u'2011, Free Software Foundation, Inc and contributors' # built documents. # # The short X.Y version. -version = '0.2.0' +version = '0.3.0' # The full version, including alpha/beta/rc tags. -release = '0.2.0' +release = '0.3.0-dev' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/mediagoblin/_version.py b/mediagoblin/_version.py index 7a41cf7c..5e3f4e5a 100644 --- a/mediagoblin/_version.py +++ b/mediagoblin/_version.py @@ -14,4 +14,4 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -__version__ = "0.2.0" +__version__ = "0.3.0-dev" From bb298cde80ce60290607012cc742ebb7b53af716 Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Wed, 14 Dec 2011 16:18:26 +0100 Subject: [PATCH 192/302] Change wording for change_fp; improved the button text --- mediagoblin/templates/mediagoblin/auth/change_fp.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mediagoblin/templates/mediagoblin/auth/change_fp.html b/mediagoblin/templates/mediagoblin/auth/change_fp.html index 5677949c..03a6583b 100644 --- a/mediagoblin/templates/mediagoblin/auth/change_fp.html +++ b/mediagoblin/templates/mediagoblin/auth/change_fp.html @@ -26,11 +26,11 @@ {{ csrf_token }}
    -

    {% trans %}Enter your new password{% endtrans %}

    +

    {% trans %}Set your new password{% endtrans %}

    {{ wtforms_util.render_divs(cp_form) }}
    - +
    From cd4b519a78961e2ec33e696e9ee730d916c1e073 Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Wed, 14 Dec 2011 16:36:29 +0100 Subject: [PATCH 193/302] Remove "X license" placeholder from media page --- mediagoblin/templates/mediagoblin/user_pages/media.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html index 5760a68c..2c8c5033 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media.html @@ -67,7 +67,7 @@ {% endautoescape %}

    {% trans date=media.created.strftime("%Y-%m-%d") -%} - Added on {{ date }}. Licensed under an X license. + Added on {{ date }}. {%- endtrans %} {% if media['uploader'] == request.user._id or request.user['is_admin'] %} From 31f5c4567fbe8ec04cf649f00d50611aca67036d Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Wed, 14 Dec 2011 16:42:40 +0100 Subject: [PATCH 194/302] Change "Submit" to "Add" for ticket #466 --- mediagoblin/templates/mediagoblin/base.html | 2 +- mediagoblin/templates/mediagoblin/submit/start.html | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mediagoblin/templates/mediagoblin/base.html b/mediagoblin/templates/mediagoblin/base.html index b8061f24..41efbc0d 100644 --- a/mediagoblin/templates/mediagoblin/base.html +++ b/mediagoblin/templates/mediagoblin/base.html @@ -52,7 +52,7 @@ {% if request.user and request.user.status == 'active' %} - {% trans %}Submit media{% endtrans %} + {% trans %}Add media{% endtrans %} {% endif %} {% block mediagoblin_header_title %}{% endblock %} diff --git a/mediagoblin/templates/mediagoblin/submit/start.html b/mediagoblin/templates/mediagoblin/submit/start.html index 1a0dd4b7..47914550 100644 --- a/mediagoblin/templates/mediagoblin/submit/start.html +++ b/mediagoblin/templates/mediagoblin/submit/start.html @@ -23,11 +23,11 @@

    -

    {% trans %}Submit yer media{% endtrans %}

    +

    {% trans %}Add your media{% endtrans %}

    {{ wtforms_util.render_divs(submit_form) }}
    {{ csrf_token }} - +
    From 9c1c6c2a61ad23d5b68eb3794e81c5bee7c7cd46 Mon Sep 17 00:00:00 2001 From: Joar Wandborg Date: Thu, 15 Dec 2011 00:46:10 +0100 Subject: [PATCH 195/302] Added *very preliminary* support for webfinger --- mediagoblin/routing.py | 4 ++ .../mediagoblin/webfinger/host-meta.xml | 27 +++++++++++ .../templates/mediagoblin/webfinger/xrd.xml | 26 +++++++++++ mediagoblin/webfinger/__init__.py | 15 ++++++ mediagoblin/webfinger/routing.py | 25 ++++++++++ mediagoblin/webfinger/views.py | 46 +++++++++++++++++++ 6 files changed, 143 insertions(+) create mode 100644 mediagoblin/templates/mediagoblin/webfinger/host-meta.xml create mode 100644 mediagoblin/templates/mediagoblin/webfinger/xrd.xml create mode 100644 mediagoblin/webfinger/__init__.py create mode 100644 mediagoblin/webfinger/routing.py create mode 100644 mediagoblin/webfinger/views.py diff --git a/mediagoblin/routing.py b/mediagoblin/routing.py index ae56f8cb..bd727db5 100644 --- a/mediagoblin/routing.py +++ b/mediagoblin/routing.py @@ -21,6 +21,8 @@ from mediagoblin.submit.routing import submit_routes from mediagoblin.user_pages.routing import user_routes from mediagoblin.edit.routing import edit_routes from mediagoblin.listings.routing import tag_routes +from mediagoblin.webfinger.routing import webfinger_well_known_routes, \ + webfinger_routes def get_mapper(): @@ -36,5 +38,7 @@ def get_mapper(): mapping.extend(user_routes, '/u') mapping.extend(edit_routes, '/edit') mapping.extend(tag_routes, '/tag') + mapping.extend(webfinger_well_known_routes, '/.well-known') + mapping.extend(webfinger_routes, '/api/webfinger') return mapping diff --git a/mediagoblin/templates/mediagoblin/webfinger/host-meta.xml b/mediagoblin/templates/mediagoblin/webfinger/host-meta.xml new file mode 100644 index 00000000..dff2c9aa --- /dev/null +++ b/mediagoblin/templates/mediagoblin/webfinger/host-meta.xml @@ -0,0 +1,27 @@ +{# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +-#} + + + + {{ request.host }} + + + {{ llrd_title }} + + diff --git a/mediagoblin/templates/mediagoblin/webfinger/xrd.xml b/mediagoblin/templates/mediagoblin/webfinger/xrd.xml new file mode 100644 index 00000000..2ef9b814 --- /dev/null +++ b/mediagoblin/templates/mediagoblin/webfinger/xrd.xml @@ -0,0 +1,26 @@ +{# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +-#} + + + + {{ uri }} + http://{{ request.host }}/u/{{ username }} + + + diff --git a/mediagoblin/webfinger/__init__.py b/mediagoblin/webfinger/__init__.py new file mode 100644 index 00000000..ba347c69 --- /dev/null +++ b/mediagoblin/webfinger/__init__.py @@ -0,0 +1,15 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . diff --git a/mediagoblin/webfinger/routing.py b/mediagoblin/webfinger/routing.py new file mode 100644 index 00000000..effb2bf2 --- /dev/null +++ b/mediagoblin/webfinger/routing.py @@ -0,0 +1,25 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +from routes.route import Route + +webfinger_well_known_routes = [ + Route('mediagoblin.webfinger.host_meta', '/host-meta', + controller='mediagoblin.webfinger.views:host_meta')] + +webfinger_routes = [ + Route('mediagoblin.webfinger.xrd', '/xrd', + controller='mediagoblin.webfinger.views:xrd')] diff --git a/mediagoblin/webfinger/views.py b/mediagoblin/webfinger/views.py new file mode 100644 index 00000000..f6294da9 --- /dev/null +++ b/mediagoblin/webfinger/views.py @@ -0,0 +1,46 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +import re +import mediagoblin.mg_globals as mg_globals + +from mediagoblin.tools.response import render_to_response + +LRDD_TEMPLATE = '{protocol}://{host}/api/webfinger/xrd?uri={{uri}}' + +def host_meta(request): + ''' + Webfinger host-meta + ''' + return render_to_response( + request, + 'mediagoblin/webfinger/host-meta.xml', + {'request': request, + 'lrdd_template': LRDD_TEMPLATE.format( + protocol='http', + host=request.host)}) + +def xrd(request): + ''' + Find user data based on a webfinger URI + ''' + return render_to_response( + request, + 'mediagoblin/webfinger/xrd.xml', + {'request': request, + 'username': re.search( + r'^acct:([^@]*)', + request.GET.get('uri')).group(1)}) From 830a78cdfbb8fc1ee8af770a299f59f26e918aa0 Mon Sep 17 00:00:00 2001 From: Joar Wandborg Date: Thu, 15 Dec 2011 00:58:14 +0100 Subject: [PATCH 196/302] Changed some thngs to be compatible with webfinger.org, still *very preliminary* --- mediagoblin/templates/mediagoblin/webfinger/xrd.xml | 3 +++ mediagoblin/webfinger/views.py | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/mediagoblin/templates/mediagoblin/webfinger/xrd.xml b/mediagoblin/templates/mediagoblin/webfinger/xrd.xml index 2ef9b814..796de89f 100644 --- a/mediagoblin/templates/mediagoblin/webfinger/xrd.xml +++ b/mediagoblin/templates/mediagoblin/webfinger/xrd.xml @@ -20,6 +20,9 @@ {{ uri }} http://{{ request.host }}/u/{{ username }} + + diff --git a/mediagoblin/webfinger/views.py b/mediagoblin/webfinger/views.py index f6294da9..7cbd0913 100644 --- a/mediagoblin/webfinger/views.py +++ b/mediagoblin/webfinger/views.py @@ -42,5 +42,5 @@ def xrd(request): 'mediagoblin/webfinger/xrd.xml', {'request': request, 'username': re.search( - r'^acct:([^@]*)', - request.GET.get('uri')).group(1)}) + r'^(acct:)?([^@]*)', + request.GET.get('uri')).group(2)}) From 8d45c4463bf7bf9dfebe919bb12d588d45d7e30c Mon Sep 17 00:00:00 2001 From: Will Kahn-Greene Date: Thu, 15 Dec 2011 09:27:56 -0500 Subject: [PATCH 197/302] Fix -dev version and add version number docs Version numbers should adhere to PEP-386. --- mediagoblin/_version.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/mediagoblin/_version.py b/mediagoblin/_version.py index 5e3f4e5a..5e69f21a 100644 --- a/mediagoblin/_version.py +++ b/mediagoblin/_version.py @@ -14,4 +14,13 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -__version__ = "0.3.0-dev" +# valid version formats: +# * x.y - final release +# * x.ya1 - alpha 1 +# * x.yb1 - beta 1 +# * x.yrc1 - release candidate 1 +# * x.y.dev - dev + +# see http://www.python.org/dev/peps/pep-0386/ + +__version__ = "0.3.0.dev" From 9df07e87a8452e47eb594763bb700daf6fb69dbe Mon Sep 17 00:00:00 2001 From: Joar Wandborg Date: Thu, 15 Dec 2011 19:35:53 +0100 Subject: [PATCH 198/302] webfinger fully compliant with webfinger.org! Still *preliminary* solution. --- mediagoblin/templates/mediagoblin/webfinger/xrd.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediagoblin/templates/mediagoblin/webfinger/xrd.xml b/mediagoblin/templates/mediagoblin/webfinger/xrd.xml index 796de89f..9a793637 100644 --- a/mediagoblin/templates/mediagoblin/webfinger/xrd.xml +++ b/mediagoblin/templates/mediagoblin/webfinger/xrd.xml @@ -17,7 +17,7 @@ - {{ uri }} + {{ request.GET.get('uri') }} http://{{ request.host }}/u/{{ username }} Date: Thu, 15 Dec 2011 21:15:21 +0100 Subject: [PATCH 199/302] Move sql models into db/sql/ So we can play with the sql models, let's put them in a proper place. --- mediagoblin/db/sql/__init__.py | 15 +++++++++++++++ mediagoblin/db/{sql.py => sql/models.py} | 0 2 files changed, 15 insertions(+) create mode 100644 mediagoblin/db/sql/__init__.py rename mediagoblin/db/{sql.py => sql/models.py} (100%) diff --git a/mediagoblin/db/sql/__init__.py b/mediagoblin/db/sql/__init__.py new file mode 100644 index 00000000..ba347c69 --- /dev/null +++ b/mediagoblin/db/sql/__init__.py @@ -0,0 +1,15 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . diff --git a/mediagoblin/db/sql.py b/mediagoblin/db/sql/models.py similarity index 100% rename from mediagoblin/db/sql.py rename to mediagoblin/db/sql/models.py From e365f980ac21a403a50f61ae687d7dc04760f8bb Mon Sep 17 00:00:00 2001 From: Elrond Date: Thu, 15 Dec 2011 22:11:49 +0100 Subject: [PATCH 200/302] SQL: Some toys and little fix Run bin/python mediagoblin/db/sql/models.py and watch the create tables on a memory sqlite db. Also unicode strings need unicode defauls. Warning by sqlalchemy. --- mediagoblin/db/sql/models.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/mediagoblin/db/sql/models.py b/mediagoblin/db/sql/models.py index 31ebfbf4..a38be1cc 100644 --- a/mediagoblin/db/sql/models.py +++ b/mediagoblin/db/sql/models.py @@ -18,7 +18,7 @@ class User(Base): created = Column(DateTime, nullable=False, default=datetime.datetime.now) pw_hash = Column(Unicode, nullable=False) email_verified = Column(Boolean) - status = Column(Unicode, default="needs_email_verification", nullable=False) + status = Column(Unicode, default=u"needs_email_verification", nullable=False) verification_key = Column(Unicode) is_admin = Column(Boolean, default=False, nullable=False) url = Column(Unicode) @@ -93,3 +93,14 @@ class MediaComment(Base): created = Column(DateTime, nullable=False, default=datetime.datetime.now) content = Column(UnicodeText, nullable=False) content_html = Column(UnicodeText) + + +def show_table_init(): + from sqlalchemy import create_engine + engine = create_engine('sqlite:///:memory:', echo=True) + + Base.metadata.create_all(engine) + + +if __name__ == '__main__': + show_table_init() From 8eb216388f0999115d68c33e2fe2460bc9986112 Mon Sep 17 00:00:00 2001 From: Joar Wandborg Date: Thu, 15 Dec 2011 23:49:52 +0100 Subject: [PATCH 201/302] Fixed import_export - Mongokit instead of pymongo - db.MediaEntry instead of db.media_entry (pymongo style) --- mediagoblin/gmg_commands/import_export.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mediagoblin/gmg_commands/import_export.py b/mediagoblin/gmg_commands/import_export.py index 1308f09e..eda41f4c 100644 --- a/mediagoblin/gmg_commands/import_export.py +++ b/mediagoblin/gmg_commands/import_export.py @@ -64,7 +64,7 @@ def _import_media(db, args): queue_cache = BasicFileStorage( args._cache_path['queue']) - for entry in db.media_entries.find(): + for entry in db.MediaEntry.find(): for name, path in entry['media_files'].items(): _log.info('Importing: {0} - {1}'.format( entry.title, @@ -107,7 +107,7 @@ def env_import(args): global_config, app_config = setup_global_and_app_config(args.conf_file) connection, db = setup_connection_and_db_from_config( - app_config, use_pymongo=True) + app_config) tf = tarfile.open( args.tar_file, @@ -206,7 +206,7 @@ def _export_media(db, args): queue_cache = BasicFileStorage( args._cache_path['queue']) - for entry in db.media_entries.find(): + for entry in db.MediaEntry.find(): for name, path in entry['media_files'].items(): _log.info(u'Exporting {0} - {1}'.format( entry.title, @@ -215,7 +215,7 @@ def _export_media(db, args): mc_file = media_cache.get_file(path, mode='wb') mc_file.write( mg_globals.public_store.get_file(path, mode='rb').read()) - except e: + except Exception as e: _log.error('Failed: {0}'.format(e)) _log.info('...Media exported') @@ -246,7 +246,7 @@ def env_export(args): setup_storage() connection, db = setup_connection_and_db_from_config( - app_config, use_pymongo=True) + app_config) _export_database(db, args) From 7c2c56a5ff0cb229cd3a64451368bf1e72646bc5 Mon Sep 17 00:00:00 2001 From: Elrond Date: Sat, 17 Dec 2011 17:34:55 +0100 Subject: [PATCH 202/302] Little sql model update - Add title to the MediaEntry - Rename fp_verification_expire to fp_token_expire to follow the mongo model. --- mediagoblin/db/sql/models.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mediagoblin/db/sql/models.py b/mediagoblin/db/sql/models.py index a38be1cc..7723a753 100644 --- a/mediagoblin/db/sql/models.py +++ b/mediagoblin/db/sql/models.py @@ -25,7 +25,7 @@ class User(Base): bio = Column(UnicodeText) # ?? bio_html = Column(UnicodeText) # ?? fp_verification_key = Column(Unicode) - fp_verification_expire = Column(DateTime) + fp_token_expire = Column(DateTime) ## TODO # plugin data would be in a separate model @@ -36,6 +36,7 @@ class MediaEntry(Base): id = Column(Integer, primary_key=True) uploader = Column(Integer, ForeignKey('users.id'), nullable=False) + title = Column(Unicode, nullable=False) slug = Column(Unicode, nullable=False) created = Column(DateTime, nullable=False, default=datetime.datetime.now) description = Column(UnicodeText) # ?? From dbcf5289dcc7bcd03a1a92a204fd7c4c8348d318 Mon Sep 17 00:00:00 2001 From: Elrond Date: Sat, 17 Dec 2011 21:37:02 +0100 Subject: [PATCH 203/302] Simple Mongo -> SQL migration tool This is just a start at a Migration tool from Mongo to SQL. It fills all currently available SQL models with data from MongoDB. A few fields in the SQL tables are left out, because some data format migrations are needed (notably: queue_file_name). This thing lives in mediagoblin/db/sql/convert.py because it has a lot of stuff hardcoded and is not, repeat not for end users! Hard coded: - output database: ./mediagoblin.db (sqlite) - Mediagoblin config: ./mediagoblin.ini --- mediagoblin/db/sql/convert.py | 143 ++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 mediagoblin/db/sql/convert.py diff --git a/mediagoblin/db/sql/convert.py b/mediagoblin/db/sql/convert.py new file mode 100644 index 00000000..2ffa9fd7 --- /dev/null +++ b/mediagoblin/db/sql/convert.py @@ -0,0 +1,143 @@ +from sqlalchemy import create_engine +from sqlalchemy.orm import sessionmaker + +from mediagoblin.init import setup_global_and_app_config, setup_database +from mediagoblin.db.util import ObjectId + +from mediagoblin.db.sql.models import (Base, User, MediaEntry, MediaComment, + Tag, MediaTag) + +Session = sessionmaker() + + +obj_id_table = dict() + +def add_obj_ids(entry, new_entry): + global obj_id_table + print "%r -> %r" % (entry._id, new_entry.id) + obj_id_table[entry._id] = new_entry.id + + +def copy_attrs(entry, new_entry, attr_list): + for a in attr_list: + val = entry[a] + setattr(new_entry, a, val) + +def copy_reference_attr(entry, new_entry, ref_attr): + val = entry[ref_attr] + val = obj_id_table[val] + setattr(new_entry, ref_attr, val) + + +def convert_users(mk_db): + session = Session() + + for entry in mk_db.User.find(): + print entry.username + + new_entry = User() + copy_attrs(entry, new_entry, + ('username', 'email', 'created', 'pw_hash', 'email_verified', + 'status', 'verification_key', 'is_admin', 'url', + 'bio', 'bio_html', + 'fp_verification_key', 'fp_token_expire',)) + # new_entry.fp_verification_expire = entry.fp_token_expire + + session.add(new_entry) + session.flush() + add_obj_ids(entry, new_entry) + + session.commit() + session.close() + + +def convert_media_entries(mk_db): + session = Session() + + for entry in mk_db.MediaEntry.find(): + print repr(entry.title) + + new_entry = MediaEntry() + copy_attrs(entry, new_entry, + ('title', 'slug', 'created', + 'description', 'description_html', + 'media_type', + 'fail_error', + 'queued_task_id',)) + copy_reference_attr(entry, new_entry, "uploader") + + session.add(new_entry) + session.flush() + add_obj_ids(entry, new_entry) + + session.commit() + session.close() + + +def convert_media_tags(mk_db): + session = Session() + session.autoflush = False + + for media in mk_db.MediaEntry.find(): + print repr(media.title) + + for otag in media.tags: + print " ", repr((otag["slug"], otag["name"])) + + nslug = session.query(Tag).filter_by(slug=otag["slug"]).first() + print " ", repr(nslug) + if nslug is None: + nslug = Tag(slug=otag["slug"]) + session.add(nslug) + session.flush() + print " ", repr(nslug), nslug.id + + ntag = MediaTag() + ntag.tag = nslug.id + ntag.name = otag["name"] + ntag.media_entry = obj_id_table[media._id] + session.add(ntag) + + session.commit() + session.close() + + +def convert_media_comments(mk_db): + session = Session() + + for entry in mk_db.MediaComment.find(): + print repr(entry.content) + + new_entry = MediaComment() + copy_attrs(entry, new_entry, + ('created', + 'content', 'content_html',)) + copy_reference_attr(entry, new_entry, "media_entry") + copy_reference_attr(entry, new_entry, "author") + + session.add(new_entry) + session.flush() + add_obj_ids(entry, new_entry) + + session.commit() + session.close() + + +def main(): + engine = create_engine('sqlite:///mediagoblin.db', echo=True) + Session.configure(bind=engine) + + setup_global_and_app_config("mediagoblin.ini") + + mk_conn, mk_db = setup_database() + + Base.metadata.create_all(engine) + + convert_users(mk_db) + convert_media_entries(mk_db) + convert_media_tags(mk_db) + convert_media_comments(mk_db) + + +if __name__ == '__main__': + main() From 18517e888a90bf1c0434dd4da99ef7980d333ed0 Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Sun, 18 Dec 2011 00:31:39 +0100 Subject: [PATCH 204/302] Show actual comment number. Only shows plural for now (ticket #712) --- mediagoblin/templates/mediagoblin/user_pages/media.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html index 2c8c5033..b9e31667 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media.html @@ -81,7 +81,7 @@ {% trans %}Delete{% endtrans %} {% endif %}

    -

    {% trans %}23 comments{% endtrans %} +

    {% trans comment_count=comments.count() -%}{{ comment_count }} comments{%- endtrans %}
    Date: Sun, 18 Dec 2011 01:04:41 +0100 Subject: [PATCH 205/302] First test lines for responsive design --- mediagoblin/static/css/base.css | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css index 2a78006d..805f0e29 100644 --- a/mediagoblin/static/css/base.css +++ b/mediagoblin/static/css/base.css @@ -389,3 +389,20 @@ table.media_panel th { margin-top: 10px; margin-left: 10px; } + +@media screen and (max-width: 480px) { + .navigation_button { + position: fixed; + bottom: 0px; + right: 0px; + width: 50%; + margin: 0; + } + .navigation_left { + left: 0px; + width: 50%; + } + .media_image { + width: 480px; + } +} From 436b13bb3e2253dc4361333d1260550d343ccfe2 Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Sun, 18 Dec 2011 01:31:06 +0100 Subject: [PATCH 206/302] Remove 960.gs stylesheets, add Eric Meyer's reset.css --- extlib/960.gs/960_16_col.css | 447 ------------------- extlib/960.gs/MIT.txt | 20 - extlib/960.gs/README.txt | 54 --- extlib/960.gs/reset.css | 202 --------- extlib/960.gs/text.css | 86 ---- mediagoblin/static/css/extlib/960_16_col.css | 1 - mediagoblin/static/css/extlib/reset.css | 1 - mediagoblin/static/css/extlib/text.css | 1 - mediagoblin/static/css/reset.css | 49 ++ mediagoblin/templates/mediagoblin/base.html | 6 +- 10 files changed, 50 insertions(+), 817 deletions(-) delete mode 100644 extlib/960.gs/960_16_col.css delete mode 100644 extlib/960.gs/MIT.txt delete mode 100755 extlib/960.gs/README.txt delete mode 100644 extlib/960.gs/reset.css delete mode 100644 extlib/960.gs/text.css delete mode 120000 mediagoblin/static/css/extlib/960_16_col.css delete mode 120000 mediagoblin/static/css/extlib/reset.css delete mode 120000 mediagoblin/static/css/extlib/text.css create mode 100644 mediagoblin/static/css/reset.css diff --git a/extlib/960.gs/960_16_col.css b/extlib/960.gs/960_16_col.css deleted file mode 100644 index faa6d8b2..00000000 --- a/extlib/960.gs/960_16_col.css +++ /dev/null @@ -1,447 +0,0 @@ -/* - 960 Grid System ~ Core CSS. - Learn more ~ http://960.gs/ - - Licensed under GPL and MIT. -*/ - -/* - Forces backgrounds to span full width, - even if there is horizontal scrolling. - Increase this if your layout is wider. - - Note: IE6 works fine without this fix. -*/ - -body { - min-width: 960px; -} - -/* Container -----------------------------------------------------------------------------------------------------*/ - -.container_16 { - margin-left: auto; - margin-right: auto; - width: 960px; -} - -/* Grid >> Global -----------------------------------------------------------------------------------------------------*/ - -.grid_1, -.grid_2, -.grid_3, -.grid_4, -.grid_5, -.grid_6, -.grid_7, -.grid_8, -.grid_9, -.grid_10, -.grid_11, -.grid_12, -.grid_13, -.grid_14, -.grid_15, -.grid_16 { - display: inline; - float: left; - position: relative; - margin-left: 10px; - margin-right: 10px; -} - -.push_1, .pull_1, -.push_2, .pull_2, -.push_3, .pull_3, -.push_4, .pull_4, -.push_5, .pull_5, -.push_6, .pull_6, -.push_7, .pull_7, -.push_8, .pull_8, -.push_9, .pull_9, -.push_10, .pull_10, -.push_11, .pull_11, -.push_12, .pull_12, -.push_13, .pull_13, -.push_14, .pull_14, -.push_15, .pull_15, -.push_16, .pull_16 { - position: relative; -} - -/* Grid >> Children (Alpha ~ First, Omega ~ Last) -----------------------------------------------------------------------------------------------------*/ - -.alpha { - margin-left: 0; -} - -.omega { - margin-right: 0; -} - -/* Grid >> 16 Columns -----------------------------------------------------------------------------------------------------*/ - -.container_16 .grid_1 { - width: 40px; -} - -.container_16 .grid_2 { - width: 100px; -} - -.container_16 .grid_3 { - width: 160px; -} - -.container_16 .grid_4 { - width: 220px; -} - -.container_16 .grid_5 { - width: 280px; -} - -.container_16 .grid_6 { - width: 340px; -} - -.container_16 .grid_7 { - width: 400px; -} - -.container_16 .grid_8 { - width: 460px; -} - -.container_16 .grid_9 { - width: 520px; -} - -.container_16 .grid_10 { - width: 580px; -} - -.container_16 .grid_11 { - width: 640px; -} - -.container_16 .grid_12 { - width: 700px; -} - -.container_16 .grid_13 { - width: 760px; -} - -.container_16 .grid_14 { - width: 820px; -} - -.container_16 .grid_15 { - width: 880px; -} - -.container_16 .grid_16 { - width: 940px; -} - -/* Prefix Extra Space >> 16 Columns -----------------------------------------------------------------------------------------------------*/ - -.container_16 .prefix_1 { - padding-left: 60px; -} - -.container_16 .prefix_2 { - padding-left: 120px; -} - -.container_16 .prefix_3 { - padding-left: 180px; -} - -.container_16 .prefix_4 { - padding-left: 240px; -} - -.container_16 .prefix_5 { - padding-left: 300px; -} - -.container_16 .prefix_6 { - padding-left: 360px; -} - -.container_16 .prefix_7 { - padding-left: 420px; -} - -.container_16 .prefix_8 { - padding-left: 480px; -} - -.container_16 .prefix_9 { - padding-left: 540px; -} - -.container_16 .prefix_10 { - padding-left: 600px; -} - -.container_16 .prefix_11 { - padding-left: 660px; -} - -.container_16 .prefix_12 { - padding-left: 720px; -} - -.container_16 .prefix_13 { - padding-left: 780px; -} - -.container_16 .prefix_14 { - padding-left: 840px; -} - -.container_16 .prefix_15 { - padding-left: 900px; -} - -/* Suffix Extra Space >> 16 Columns -----------------------------------------------------------------------------------------------------*/ - -.container_16 .suffix_1 { - padding-right: 60px; -} - -.container_16 .suffix_2 { - padding-right: 120px; -} - -.container_16 .suffix_3 { - padding-right: 180px; -} - -.container_16 .suffix_4 { - padding-right: 240px; -} - -.container_16 .suffix_5 { - padding-right: 300px; -} - -.container_16 .suffix_6 { - padding-right: 360px; -} - -.container_16 .suffix_7 { - padding-right: 420px; -} - -.container_16 .suffix_8 { - padding-right: 480px; -} - -.container_16 .suffix_9 { - padding-right: 540px; -} - -.container_16 .suffix_10 { - padding-right: 600px; -} - -.container_16 .suffix_11 { - padding-right: 660px; -} - -.container_16 .suffix_12 { - padding-right: 720px; -} - -.container_16 .suffix_13 { - padding-right: 780px; -} - -.container_16 .suffix_14 { - padding-right: 840px; -} - -.container_16 .suffix_15 { - padding-right: 900px; -} - -/* Push Space >> 16 Columns -----------------------------------------------------------------------------------------------------*/ - -.container_16 .push_1 { - left: 60px; -} - -.container_16 .push_2 { - left: 120px; -} - -.container_16 .push_3 { - left: 180px; -} - -.container_16 .push_4 { - left: 240px; -} - -.container_16 .push_5 { - left: 300px; -} - -.container_16 .push_6 { - left: 360px; -} - -.container_16 .push_7 { - left: 420px; -} - -.container_16 .push_8 { - left: 480px; -} - -.container_16 .push_9 { - left: 540px; -} - -.container_16 .push_10 { - left: 600px; -} - -.container_16 .push_11 { - left: 660px; -} - -.container_16 .push_12 { - left: 720px; -} - -.container_16 .push_13 { - left: 780px; -} - -.container_16 .push_14 { - left: 840px; -} - -.container_16 .push_15 { - left: 900px; -} - -/* Pull Space >> 16 Columns -----------------------------------------------------------------------------------------------------*/ - -.container_16 .pull_1 { - left: -60px; -} - -.container_16 .pull_2 { - left: -120px; -} - -.container_16 .pull_3 { - left: -180px; -} - -.container_16 .pull_4 { - left: -240px; -} - -.container_16 .pull_5 { - left: -300px; -} - -.container_16 .pull_6 { - left: -360px; -} - -.container_16 .pull_7 { - left: -420px; -} - -.container_16 .pull_8 { - left: -480px; -} - -.container_16 .pull_9 { - left: -540px; -} - -.container_16 .pull_10 { - left: -600px; -} - -.container_16 .pull_11 { - left: -660px; -} - -.container_16 .pull_12 { - left: -720px; -} - -.container_16 .pull_13 { - left: -780px; -} - -.container_16 .pull_14 { - left: -840px; -} - -.container_16 .pull_15 { - left: -900px; -} - -/* `Clear Floated Elements -----------------------------------------------------------------------------------------------------*/ - -/* http://sonspring.com/journal/clearing-floats */ - -.clear { - clear: both; - display: block; - overflow: hidden; - visibility: hidden; - width: 0; - height: 0; -} - -/* http://www.yuiblog.com/blog/2010/09/27/clearfix-reloaded-overflowhidden-demystified */ - -.clearfix:before, -.clearfix:after, -.container_16:before, -.container_16:after { - content: '.'; - display: block; - overflow: hidden; - visibility: hidden; - font-size: 0; - line-height: 0; - width: 0; - height: 0; -} - -.clearfix:after, -.container_16:after { - clear: both; -} - -/* - The following zoom:1 rule is specifically for IE6 + IE7. - Move to separate stylesheet if invalid CSS is a problem. -*/ - -.clearfix, -.container_16 { - zoom: 1; -} \ No newline at end of file diff --git a/extlib/960.gs/MIT.txt b/extlib/960.gs/MIT.txt deleted file mode 100644 index 5a2aeb47..00000000 --- a/extlib/960.gs/MIT.txt +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/extlib/960.gs/README.txt b/extlib/960.gs/README.txt deleted file mode 100755 index da0ea86f..00000000 --- a/extlib/960.gs/README.txt +++ /dev/null @@ -1,54 +0,0 @@ -=============== -960 GRID SYSTEM -=============== - -Created by Nathan Smith. See the official site for more info: http://960.gs/ - -============================================================================ - -To install the Adobe Fireworks extension, simply double-click the *.mxp file -included in the /fireworks_extension directory. If you are running Windows 7 -you will need admin permissions in order to install this extension properly. - -============================================================================ - -Thank you for downloading the 960 Grid System. I hope it helps to streamline -web development workflow. Enclosed in the bundle are printable sketch sheets -and template files for Adobe Fireworks and Photoshop, OmniGraffle and Visio. - -Also included is a lightweight CSS file, which contains the grid dimensions. -To use this file, simply include the 960.css in the of the HTML page. -You may also use the reset.css and text.css files, or opt to leave them out. -Here is an example of the XHTML code necessary to incorporate the CSS files: - - - - - - - -It is worth noting that these styles do not automatically make up a finished -site design. They are simply a starting point, ideally for rapid prototyping -or as a basis for creating your own designs. You should not feel constrained -by the way I have built the initial code. If you disagree with how something -has been done, feel free to revise it for the needs of your particular site. - -The files in the 960 Grid System are free of charge, licensed under MIT/GPL. - -============================================================================ - -Note that if you are building a site in a language which reads from right to -left, use the CSS files that end in "_rtl.css" instead. Denote the language: - - - -Be sure to replace "..." with the appropriate two-letter abbreviation of the -language you are using. Example: lang="he" for Hebrew, lang="ar" for Arabic. - -============================================================================ - -GPL license: -http://www.gnu.org/licenses/gpl.html - -MIT license: -http://www.opensource.org/licenses/mit-license.php \ No newline at end of file diff --git a/extlib/960.gs/reset.css b/extlib/960.gs/reset.css deleted file mode 100644 index 87b7f368..00000000 --- a/extlib/960.gs/reset.css +++ /dev/null @@ -1,202 +0,0 @@ -/* `XHTML, HTML4, HTML5 Reset -----------------------------------------------------------------------------------------------------*/ - -a, -abbr, -acronym, -address, -applet, -article, -aside, -audio, -b, -big, -blockquote, -body, -canvas, -caption, -center, -cite, -code, -dd, -del, -details, -dfn, -dialog, -div, -dl, -dt, -em, -embed, -fieldset, -figcaption, -figure, -font, -footer, -form, -h1, -h2, -h3, -h4, -h5, -h6, -header, -hgroup, -hr, -html, -i, -iframe, -img, -ins, -kbd, -label, -legend, -li, -mark, -menu, -meter, -nav, -object, -ol, -output, -p, -pre, -progress, -q, -rp, -rt, -ruby, -s, -samp, -section, -small, -span, -strike, -strong, -sub, -summary, -sup, -table, -tbody, -td, -tfoot, -th, -thead, -time, -tr, -tt, -u, -ul, -var, -video, -xmp { - border: 0; - margin: 0; - padding: 0; - font-size: 100%; -} - -html, -body { - height: 100%; -} - -article, -aside, -details, -figcaption, -figure, -footer, -header, -hgroup, -menu, -nav, -section { -/* - Override the default (display: inline) for - browsers that do not recognize HTML5 tags. - - IE8 (and lower) requires a shiv: - http://ejohn.org/blog/html5-shiv -*/ - display: block; -} - -b, -strong { -/* - Makes browsers agree. - IE + Opera = font-weight: bold. - Gecko + WebKit = font-weight: bolder. -*/ - font-weight: bold; -} - -img { - color: transparent; - font-size: 0; - vertical-align: middle; -/* - For IE. - http://css-tricks.com/ie-fix-bicubic-scaling-for-images -*/ - -ms-interpolation-mode: bicubic; -} - -li { -/* - For IE6 + IE7. -*/ - display: list-item; -} - -table { - border-collapse: collapse; - border-spacing: 0; -} - -th, -td, -caption { - font-weight: normal; - vertical-align: top; - text-align: left; -} - -q { - quotes: none; -} - -q:before, -q:after { - content: ''; - content: none; -} - -sub, -sup, -small { - font-size: 75%; -} - -sub, -sup { - line-height: 0; - position: relative; - vertical-align: baseline; -} - -sub { - bottom: -0.25em; -} - -sup { - top: -0.5em; -} - -svg { -/* - For IE9. -*/ - overflow: hidden; -} \ No newline at end of file diff --git a/extlib/960.gs/text.css b/extlib/960.gs/text.css deleted file mode 100644 index 1a6b302f..00000000 --- a/extlib/960.gs/text.css +++ /dev/null @@ -1,86 +0,0 @@ -/* - 960 Grid System ~ Text CSS. - Learn more ~ http://960.gs/ - - Licensed under GPL and MIT. -*/ - -/* `Basic HTML -----------------------------------------------------------------------------------------------------*/ - -body { - font: 13px/1.5 'Helvetica Neue', Arial, 'Liberation Sans', FreeSans, sans-serif; -} - -pre, -code { - font-family: 'DejaVu Sans Mono', Monaco, Consolas, monospace; -} - -hr { - border: 0 #ccc solid; - border-top-width: 1px; - clear: both; - height: 0; -} - -/* `Headings -----------------------------------------------------------------------------------------------------*/ - -h1 { - font-size: 25px; -} - -h2 { - font-size: 23px; -} - -h3 { - font-size: 21px; -} - -h4 { - font-size: 19px; -} - -h5 { - font-size: 17px; -} - -h6 { - font-size: 15px; -} - -/* `Spacing -----------------------------------------------------------------------------------------------------*/ - -ol { - list-style: decimal; -} - -ul { - list-style: disc; -} - -li { - margin-left: 30px; -} - -p, -dl, -hr, -h1, -h2, -h3, -h4, -h5, -h6, -ol, -ul, -pre, -table, -address, -fieldset, -figure { - margin-bottom: 20px; -} \ No newline at end of file diff --git a/mediagoblin/static/css/extlib/960_16_col.css b/mediagoblin/static/css/extlib/960_16_col.css deleted file mode 120000 index d4e43898..00000000 --- a/mediagoblin/static/css/extlib/960_16_col.css +++ /dev/null @@ -1 +0,0 @@ -../../../../extlib/960.gs/960_16_col.css \ No newline at end of file diff --git a/mediagoblin/static/css/extlib/reset.css b/mediagoblin/static/css/extlib/reset.css deleted file mode 120000 index 65d06d34..00000000 --- a/mediagoblin/static/css/extlib/reset.css +++ /dev/null @@ -1 +0,0 @@ -../../../../extlib/960.gs/reset.css \ No newline at end of file diff --git a/mediagoblin/static/css/extlib/text.css b/mediagoblin/static/css/extlib/text.css deleted file mode 120000 index 2d864de4..00000000 --- a/mediagoblin/static/css/extlib/text.css +++ /dev/null @@ -1 +0,0 @@ -../../../../extlib/960.gs/text.css \ No newline at end of file diff --git a/mediagoblin/static/css/reset.css b/mediagoblin/static/css/reset.css new file mode 100644 index 00000000..6ce25ce7 --- /dev/null +++ b/mediagoblin/static/css/reset.css @@ -0,0 +1,49 @@ +/* http://meyerweb.com/eric/tools/css/reset/ + v2.0 | 20110126 + License: none (public domain) +*/ + +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td, +article, aside, canvas, details, embed, +figure, figcaption, footer, header, hgroup, +menu, nav, output, ruby, section, summary, +time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} +/* HTML5 display-role reset for older browsers */ +article, aside, details, figcaption, figure, +footer, header, hgroup, menu, nav, section { + display: block; +} +body { + line-height: 1; +} +ol, ul { + list-style: none; +} +blockquote, q { + quotes: none; +} +blockquote:before, blockquote:after, +q:before, q:after { + content: ''; + content: none; +} +table { + border-collapse: collapse; + border-spacing: 0; +} + diff --git a/mediagoblin/templates/mediagoblin/base.html b/mediagoblin/templates/mediagoblin/base.html index 41efbc0d..6972fe2f 100644 --- a/mediagoblin/templates/mediagoblin/base.html +++ b/mediagoblin/templates/mediagoblin/base.html @@ -21,11 +21,7 @@ {% block title %}{{ app_config['html_title'] }}{% endblock %} - - + href="{{ request.staticdirect('/css/reset.css') }}"/> Date: Sun, 18 Dec 2011 01:32:13 +0100 Subject: [PATCH 207/302] Media query for everything(?) below 960px wide --- mediagoblin/static/css/base.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css index 805f0e29..effcec69 100644 --- a/mediagoblin/static/css/base.css +++ b/mediagoblin/static/css/base.css @@ -390,7 +390,7 @@ table.media_panel th { margin-left: 10px; } -@media screen and (max-width: 480px) { +@media handheld and (max-width: 480px), screen and (max-device-width: 480px), screen and (max-width: 960px) { .navigation_button { position: fixed; bottom: 0px; From 1bb8eb89c7566cb473c2a7c317420bceaf8e9111 Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Sun, 18 Dec 2011 01:37:57 +0100 Subject: [PATCH 208/302] Remove first 960.gs classes --- mediagoblin/static/css/base.css | 27 +++++++++++++++------ mediagoblin/templates/mediagoblin/base.html | 12 +++------ 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css index effcec69..d3136788 100644 --- a/mediagoblin/static/css/base.css +++ b/mediagoblin/static/css/base.css @@ -84,23 +84,43 @@ input, textarea { .mediagoblin_body { position: relative; min-height: 100%; + margin-left: auto; + margin-right: auto; + width: 960px; } .mediagoblin_header { + width: 940px; height: 36px; + margin-left: 10px; + margin-right: 10px; padding-top: 14px; margin-bottom: 20px; border-bottom: 1px solid #333; } +.mediagoblin_header_right { + float: right; +} + a.mediagoblin_logo{ color: #fff; font-weight: bold; margin-right: 8px; } +.mediagoblin_content { + width: 940px; + margin-left: 10px; + margin-right: 10px; + padding-bottom: 74px; +} + .mediagoblin_footer { + width: 940px; height: 30px; + margin-left: 10px; + margin-right: 10px; border-top: 1px solid #333; bottom: 0px; padding-top: 8px; @@ -108,13 +128,6 @@ a.mediagoblin_logo{ font-size: 0.875em; } -.mediagoblin_content { - padding-bottom: 74px; -} - -.mediagoblin_header_right { - float: right; -} /* common website elements */ diff --git a/mediagoblin/templates/mediagoblin/base.html b/mediagoblin/templates/mediagoblin/base.html index 6972fe2f..870a4861 100644 --- a/mediagoblin/templates/mediagoblin/base.html +++ b/mediagoblin/templates/mediagoblin/base.html @@ -37,8 +37,7 @@ {% block mediagoblin_body %}
    {% block mediagoblin_header %} -
    -
    {% endblock %} {% endblock mediagoblin_body %}
    From 4fe9c9b99fc14f827d87ef803a9a67508591220f Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Sun, 18 Dec 2011 01:41:01 +0100 Subject: [PATCH 209/302] Move reset.css to extlib and symlink it --- {mediagoblin/static/css => extlib/reset}/reset.css | 0 mediagoblin/static/css/extlib/reset.css | 1 + 2 files changed, 1 insertion(+) rename {mediagoblin/static/css => extlib/reset}/reset.css (100%) create mode 120000 mediagoblin/static/css/extlib/reset.css diff --git a/mediagoblin/static/css/reset.css b/extlib/reset/reset.css similarity index 100% rename from mediagoblin/static/css/reset.css rename to extlib/reset/reset.css diff --git a/mediagoblin/static/css/extlib/reset.css b/mediagoblin/static/css/extlib/reset.css new file mode 120000 index 00000000..6084e137 --- /dev/null +++ b/mediagoblin/static/css/extlib/reset.css @@ -0,0 +1 @@ +../../../../extlib/reset/reset.css \ No newline at end of file From 42a7c010321a01d1abb01d1137cc46cd97d66843 Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Sun, 18 Dec 2011 01:54:58 +0100 Subject: [PATCH 210/302] Add styles to make media.html not fall apart entirely --- mediagoblin/static/css/base.css | 14 ++++++++++++++ .../templates/mediagoblin/user_pages/media.html | 4 ++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css index d3136788..2a05e988 100644 --- a/mediagoblin/static/css/base.css +++ b/mediagoblin/static/css/base.css @@ -126,8 +126,22 @@ a.mediagoblin_logo{ padding-top: 8px; text-align: center; font-size: 0.875em; + clear: both; } +.media_pane { + width: 640px; + margin-left: 0px; + margin-right: 10px; + float: left; +} + +.media_sidebar { + width: 280px; + margin-left: 10px; + margin-right: 0px; + float: left; +} /* common website elements */ diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html index b9e31667..0c3f373e 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media.html @@ -37,7 +37,7 @@ {% endblock mediagoblin_head %} {% block mediagoblin_content %} -
    +
    {% block mediagoblin_media %} {% set display_media = request.app.public_store.file_url( @@ -141,7 +141,7 @@ media = media._id)) }} {% endif %}
    -
    +
    {% trans user_url=request.urlgen( 'mediagoblin.user_pages.user_home', user=media.get_uploader().username), From 00c1d00771e0db68f7775968c0e33f000c5f36af Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Sun, 18 Dec 2011 02:07:49 +0100 Subject: [PATCH 211/302] Change widths to percentages for small devices --- mediagoblin/static/css/base.css | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css index 2a05e988..187d1c7a 100644 --- a/mediagoblin/static/css/base.css +++ b/mediagoblin/static/css/base.css @@ -418,6 +418,9 @@ table.media_panel th { } @media handheld and (max-width: 480px), screen and (max-device-width: 480px), screen and (max-width: 960px) { + html { + padding:10px; + } .navigation_button { position: fixed; bottom: 0px; @@ -427,9 +430,19 @@ table.media_panel th { } .navigation_left { left: 0px; - width: 50%; } .media_image { - width: 480px; + width: 100%; + } + .mediagoblin_body { + width: 100%; + } + .mediagoblin_header, .mediagoblin_content, .mediagoblin_footer, .media_pane { + width: 100%; + margin-left: 0; + margin-right: 0; + } + .mediagoblin_footer { + margin-bottom: 100px; } } From 7b194a79f0ad789309b9c34340f19c5a962b0915 Mon Sep 17 00:00:00 2001 From: Elrond Date: Sun, 18 Dec 2011 17:02:27 +0100 Subject: [PATCH 212/302] SQL: mongokit like interface In trying to ease the migration to SQL, created an interface to sqlalchemy that looks a lot like the interface that is currently in use. *WARNING* Work in progress --- mediagoblin/db/sql/base.py | 16 ++++++++++++++++ mediagoblin/db/sql/convert.py | 7 ++++++- mediagoblin/db/sql/models.py | 4 +++- mediagoblin/db/sql/open.py | 29 +++++++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 mediagoblin/db/sql/base.py create mode 100644 mediagoblin/db/sql/open.py diff --git a/mediagoblin/db/sql/base.py b/mediagoblin/db/sql/base.py new file mode 100644 index 00000000..b8d5cc96 --- /dev/null +++ b/mediagoblin/db/sql/base.py @@ -0,0 +1,16 @@ +from sqlalchemy.orm import scoped_session, sessionmaker + + +Session = scoped_session(sessionmaker()) + + +class GMGTableBase(object): + query = Session.query_property() + + @classmethod + def find(cls, query_dict={}): + return cls.query.filter_by(**query_dict) + + @classmethod + def find_one(cls, query_dict={}): + return cls.query.filter_by(**query_dict).first() diff --git a/mediagoblin/db/sql/convert.py b/mediagoblin/db/sql/convert.py index 2ffa9fd7..6de758ed 100644 --- a/mediagoblin/db/sql/convert.py +++ b/mediagoblin/db/sql/convert.py @@ -7,7 +7,8 @@ from mediagoblin.db.util import ObjectId from mediagoblin.db.sql.models import (Base, User, MediaEntry, MediaComment, Tag, MediaTag) -Session = sessionmaker() +# Session = sessionmaker() +from mediagoblin.db.sql.base import Session obj_id_table = dict() @@ -134,9 +135,13 @@ def main(): Base.metadata.create_all(engine) convert_users(mk_db) + Session.remove() convert_media_entries(mk_db) + Session.remove() convert_media_tags(mk_db) + Session.remove() convert_media_comments(mk_db) + Session.remove() if __name__ == '__main__': diff --git a/mediagoblin/db/sql/models.py b/mediagoblin/db/sql/models.py index 7723a753..b87ff3aa 100644 --- a/mediagoblin/db/sql/models.py +++ b/mediagoblin/db/sql/models.py @@ -5,8 +5,10 @@ from sqlalchemy import ( Column, Integer, Unicode, UnicodeText, DateTime, Boolean, ForeignKey, UniqueConstraint) +from mediagoblin.db.sql.base import GMGTableBase -Base = declarative_base() + +Base = declarative_base(cls=GMGTableBase) class User(Base): diff --git a/mediagoblin/db/sql/open.py b/mediagoblin/db/sql/open.py new file mode 100644 index 00000000..57feaf50 --- /dev/null +++ b/mediagoblin/db/sql/open.py @@ -0,0 +1,29 @@ +from sqlalchemy import create_engine + +from mediagoblin.db.sql.base import Session +from mediagoblin.db.sql.models import Base + + +class DatabaseMaster(object): + def __init__(self, engine): + self.engine = engine + + for k,v in Base._decl_class_registry.iteritems(): + setattr(self, k, v) + + def commit(self): + Session.commit() + + def save(self, obj): + Session.add(obj) + Session.flush() + + def reset_after_request(self): + Session.remove() + + +def setup_connection_and_db_from_config(app_config): + engine = create_engine(app_config['sql_engine'], echo=True) + Session.configure(bind=engine) + + return "dummy conn", DatabaseMaster(engine) From 046f9f8481a8950ce18dfc8b4f14e4d14cf59c7a Mon Sep 17 00:00:00 2001 From: Elrond Date: Tue, 20 Dec 2011 19:06:04 +0100 Subject: [PATCH 213/302] Move db/open.py to db/mongo/open.py Starting to move the mongo specific stuff into db/mongo. And create thin "from db.mongo.Y import z" wrappers in db/Y.py. Why? 1) Will make it lots easier to switch to sql for testing/developing. 2) The mongo stuff needs to stay around after moving to sql, because the converter needs it. --- mediagoblin/db/mongo/__init__.py | 15 +++++++++ mediagoblin/db/mongo/open.py | 55 ++++++++++++++++++++++++++++++++ mediagoblin/db/open.py | 40 +---------------------- 3 files changed, 71 insertions(+), 39 deletions(-) create mode 100644 mediagoblin/db/mongo/__init__.py create mode 100644 mediagoblin/db/mongo/open.py diff --git a/mediagoblin/db/mongo/__init__.py b/mediagoblin/db/mongo/__init__.py new file mode 100644 index 00000000..ba347c69 --- /dev/null +++ b/mediagoblin/db/mongo/__init__.py @@ -0,0 +1,15 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . diff --git a/mediagoblin/db/mongo/open.py b/mediagoblin/db/mongo/open.py new file mode 100644 index 00000000..e677ba12 --- /dev/null +++ b/mediagoblin/db/mongo/open.py @@ -0,0 +1,55 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +import pymongo +import mongokit +from paste.deploy.converters import asint +from mediagoblin.db import models + + +def connect_database_from_config(app_config, use_pymongo=False): + """ + Connect to the main database, take config from app_config + + Optionally use pymongo instead of mongokit for the connection. + """ + port = app_config.get('db_port') + if port: + port = asint(port) + + if use_pymongo: + connection = pymongo.Connection( + app_config.get('db_host'), port) + else: + connection = mongokit.Connection( + app_config.get('db_host'), port) + return connection + + +def setup_connection_and_db_from_config(app_config, use_pymongo=False): + """ + Setup connection and database from config. + + Optionally use pymongo instead of mongokit. + """ + connection = connect_database_from_config(app_config, use_pymongo) + database_path = app_config['db_name'] + db = connection[database_path] + + if not use_pymongo: + models.register_models(connection) + + return (connection, db) diff --git a/mediagoblin/db/open.py b/mediagoblin/db/open.py index e677ba12..a92a6ada 100644 --- a/mediagoblin/db/open.py +++ b/mediagoblin/db/open.py @@ -14,42 +14,4 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -import pymongo -import mongokit -from paste.deploy.converters import asint -from mediagoblin.db import models - - -def connect_database_from_config(app_config, use_pymongo=False): - """ - Connect to the main database, take config from app_config - - Optionally use pymongo instead of mongokit for the connection. - """ - port = app_config.get('db_port') - if port: - port = asint(port) - - if use_pymongo: - connection = pymongo.Connection( - app_config.get('db_host'), port) - else: - connection = mongokit.Connection( - app_config.get('db_host'), port) - return connection - - -def setup_connection_and_db_from_config(app_config, use_pymongo=False): - """ - Setup connection and database from config. - - Optionally use pymongo instead of mongokit. - """ - connection = connect_database_from_config(app_config, use_pymongo) - database_path = app_config['db_name'] - db = connection[database_path] - - if not use_pymongo: - models.register_models(connection) - - return (connection, db) +from mediagoblin.db.mongo.open import setup_connection_and_db_from_config From 4970960f8c8e0a49d44f15853a2929c3e615a015 Mon Sep 17 00:00:00 2001 From: Elrond Date: Tue, 20 Dec 2011 19:20:09 +0100 Subject: [PATCH 214/302] Move db/indexes.py to db/mongo/indexes.py And change references (one!). --- mediagoblin/db/{ => mongo}/indexes.py | 0 mediagoblin/db/util.py | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename mediagoblin/db/{ => mongo}/indexes.py (100%) diff --git a/mediagoblin/db/indexes.py b/mediagoblin/db/mongo/indexes.py similarity index 100% rename from mediagoblin/db/indexes.py rename to mediagoblin/db/mongo/indexes.py diff --git a/mediagoblin/db/util.py b/mediagoblin/db/util.py index 52e97f6d..e2065693 100644 --- a/mediagoblin/db/util.py +++ b/mediagoblin/db/util.py @@ -34,7 +34,7 @@ from pymongo import ASCENDING, DESCENDING from pymongo.errors import InvalidId from mongokit import ObjectId -from mediagoblin.db.indexes import ACTIVE_INDEXES, DEPRECATED_INDEXES +from mediagoblin.db.mongo.indexes import ACTIVE_INDEXES, DEPRECATED_INDEXES ################ From 59bd06aabb0b9a6277d2ad5d1d38c3c8a8da5298 Mon Sep 17 00:00:00 2001 From: Elrond Date: Tue, 20 Dec 2011 19:35:47 +0100 Subject: [PATCH 215/302] Move db/util.py -> db/mongo/util.py - Change some reference - Provide a wrapper db/util.py --- mediagoblin/db/migrations.py | 2 +- mediagoblin/db/models.py | 2 +- mediagoblin/db/mongo/util.py | 292 +++++++++++++++++++++++++++ mediagoblin/db/util.py | 278 +------------------------ mediagoblin/tests/test_migrations.py | 2 +- 5 files changed, 297 insertions(+), 279 deletions(-) create mode 100644 mediagoblin/db/mongo/util.py diff --git a/mediagoblin/db/migrations.py b/mediagoblin/db/migrations.py index cfc01287..cf4e94ae 100644 --- a/mediagoblin/db/migrations.py +++ b/mediagoblin/db/migrations.py @@ -14,7 +14,7 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -from mediagoblin.db.util import RegisterMigration +from mediagoblin.db.mongo.util import RegisterMigration from mediagoblin.tools.text import cleaned_markdown_conversion diff --git a/mediagoblin/db/models.py b/mediagoblin/db/models.py index 569c3600..51c6e98e 100644 --- a/mediagoblin/db/models.py +++ b/mediagoblin/db/models.py @@ -22,7 +22,7 @@ from mongokit import Document from mediagoblin.auth import lib as auth_lib from mediagoblin import mg_globals from mediagoblin.db import migrations -from mediagoblin.db.util import ASCENDING, DESCENDING, ObjectId +from mediagoblin.db.mongo.util import ASCENDING, DESCENDING, ObjectId from mediagoblin.tools.pagination import Pagination from mediagoblin.tools import url, common diff --git a/mediagoblin/db/mongo/util.py b/mediagoblin/db/mongo/util.py new file mode 100644 index 00000000..e2065693 --- /dev/null +++ b/mediagoblin/db/mongo/util.py @@ -0,0 +1,292 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +""" +Utilities for database operations. + +Some note on migration and indexing tools: + +We store information about what the state of the database is in the +'mediagoblin' document of the 'app_metadata' collection. Keys in that +document relevant to here: + + - 'migration_number': The integer representing the current state of + the migrations +""" + +import copy + +# Imports that other modules might use +from pymongo import ASCENDING, DESCENDING +from pymongo.errors import InvalidId +from mongokit import ObjectId + +from mediagoblin.db.mongo.indexes import ACTIVE_INDEXES, DEPRECATED_INDEXES + + +################ +# Indexing tools +################ + + +def add_new_indexes(database, active_indexes=ACTIVE_INDEXES): + """ + Add any new indexes to the database. + + Args: + - database: pymongo or mongokit database instance. + - active_indexes: indexes to possibly add in the pattern of: + {'collection_name': { + 'identifier': { + 'index': [index_foo_goes_here], + 'unique': True}} + where 'index' is the index to add and all other options are + arguments for collection.create_index. + + Returns: + A list of indexes added in form ('collection', 'index_name') + """ + indexes_added = [] + + for collection_name, indexes in active_indexes.iteritems(): + collection = database[collection_name] + collection_indexes = collection.index_information().keys() + + for index_name, index_data in indexes.iteritems(): + if not index_name in collection_indexes: + # Get a copy actually so we don't modify the actual + # structure + index_data = copy.copy(index_data) + index = index_data.pop('index') + collection.create_index( + index, name=index_name, **index_data) + + indexes_added.append((collection_name, index_name)) + + return indexes_added + + +def remove_deprecated_indexes(database, deprecated_indexes=DEPRECATED_INDEXES): + """ + Remove any deprecated indexes from the database. + + Args: + - database: pymongo or mongokit database instance. + - deprecated_indexes: the indexes to deprecate in the pattern of: + {'collection_name': { + 'identifier': { + 'index': [index_foo_goes_here], + 'unique': True}} + + (... although we really only need the 'identifier' here, as the + rest of the information isn't used in this case. But it's kept + around so we can remember what it was) + + Returns: + A list of indexes removed in form ('collection', 'index_name') + """ + indexes_removed = [] + + for collection_name, indexes in deprecated_indexes.iteritems(): + collection = database[collection_name] + collection_indexes = collection.index_information().keys() + + for index_name, index_data in indexes.iteritems(): + if index_name in collection_indexes: + collection.drop_index(index_name) + + indexes_removed.append((collection_name, index_name)) + + return indexes_removed + + +################# +# Migration tools +################# + +# The default migration registry... +# +# Don't set this yourself! RegisterMigration will automatically fill +# this with stuff via decorating methods in migrations.py + +class MissingCurrentMigration(Exception): + pass + + +MIGRATIONS = {} + + +class RegisterMigration(object): + """ + Tool for registering migrations + + Call like: + + @RegisterMigration(33) + def update_dwarves(database): + [...] + + This will register your migration with the default migration + registry. Alternately, to specify a very specific + migration_registry, you can pass in that as the second argument. + + Note, the number of your migration should NEVER be 0 or less than + 0. 0 is the default "no migrations" state! + """ + def __init__(self, migration_number, migration_registry=MIGRATIONS): + assert migration_number > 0, "Migration number must be > 0!" + assert migration_number not in migration_registry, \ + "Duplicate migration numbers detected! That's not allowed!" + + self.migration_number = migration_number + self.migration_registry = migration_registry + + def __call__(self, migration): + self.migration_registry[self.migration_number] = migration + return migration + + +class MigrationManager(object): + """ + Migration handling tool. + + Takes information about a database, lets you update the database + to the latest migrations, etc. + """ + def __init__(self, database, migration_registry=MIGRATIONS): + """ + Args: + - database: database we're going to migrate + - migration_registry: where we should find all migrations to + run + """ + self.database = database + self.migration_registry = migration_registry + self._sorted_migrations = None + + def _ensure_current_migration_record(self): + """ + If there isn't a database[u'app_metadata'] mediagoblin entry + with the 'current_migration', throw an error. + """ + if self.database_current_migration() is None: + raise MissingCurrentMigration( + "Tried to call function which requires " + "'current_migration' set in database") + + @property + def sorted_migrations(self): + """ + Sort migrations if necessary and store in self._sorted_migrations + """ + if not self._sorted_migrations: + self._sorted_migrations = sorted( + self.migration_registry.items(), + # sort on the key... the migration number + key=lambda migration_tuple: migration_tuple[0]) + + return self._sorted_migrations + + def latest_migration(self): + """ + Return a migration number for the latest migration, or 0 if + there are no migrations. + """ + if self.sorted_migrations: + return self.sorted_migrations[-1][0] + else: + # If no migrations have been set, we start at 0. + return 0 + + def set_current_migration(self, migration_number): + """ + Set the migration in the database to migration_number + """ + # Add the mediagoblin migration if necessary + self.database[u'app_metadata'].update( + {u'_id': u'mediagoblin'}, + {u'$set': {u'current_migration': migration_number}}, + upsert=True) + + def install_migration_version_if_missing(self): + """ + Sets the migration to the latest version if no migration + version at all is set. + """ + mgoblin_metadata = self.database[u'app_metadata'].find_one( + {u'_id': u'mediagoblin'}) + if not mgoblin_metadata: + latest_migration = self.latest_migration() + self.set_current_migration(latest_migration) + + def database_current_migration(self): + """ + Return the current migration in the database. + """ + mgoblin_metadata = self.database[u'app_metadata'].find_one( + {u'_id': u'mediagoblin'}) + if not mgoblin_metadata: + return None + else: + return mgoblin_metadata[u'current_migration'] + + def database_at_latest_migration(self): + """ + See if the database is at the latest migration. + Returns a boolean. + """ + current_migration = self.database_current_migration() + return current_migration == self.latest_migration() + + def migrations_to_run(self): + """ + Get a list of migrations to run still, if any. + + Note that calling this will set your migration version to the + latest version if it isn't installed to anything yet! + """ + self._ensure_current_migration_record() + + db_current_migration = self.database_current_migration() + + return [ + (migration_number, migration_func) + for migration_number, migration_func in self.sorted_migrations + if migration_number > db_current_migration] + + def migrate_new(self, pre_callback=None, post_callback=None): + """ + Run all migrations. + + Includes two optional args: + - pre_callback: if called, this is a callback on something to + run pre-migration. Takes (migration_number, migration_func) + as arguments + - pre_callback: if called, this is a callback on something to + run post-migration. Takes (migration_number, migration_func) + as arguments + """ + # If we aren't set to any version number, presume we're at the + # latest (which means we'll do nothing here...) + self.install_migration_version_if_missing() + + for migration_number, migration_func in self.migrations_to_run(): + if pre_callback: + pre_callback(migration_number, migration_func) + migration_func(self.database) + self.set_current_migration(migration_number) + if post_callback: + post_callback(migration_number, migration_func) diff --git a/mediagoblin/db/util.py b/mediagoblin/db/util.py index e2065693..3fd96a1d 100644 --- a/mediagoblin/db/util.py +++ b/mediagoblin/db/util.py @@ -14,279 +14,5 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -""" -Utilities for database operations. - -Some note on migration and indexing tools: - -We store information about what the state of the database is in the -'mediagoblin' document of the 'app_metadata' collection. Keys in that -document relevant to here: - - - 'migration_number': The integer representing the current state of - the migrations -""" - -import copy - -# Imports that other modules might use -from pymongo import ASCENDING, DESCENDING -from pymongo.errors import InvalidId -from mongokit import ObjectId - -from mediagoblin.db.mongo.indexes import ACTIVE_INDEXES, DEPRECATED_INDEXES - - -################ -# Indexing tools -################ - - -def add_new_indexes(database, active_indexes=ACTIVE_INDEXES): - """ - Add any new indexes to the database. - - Args: - - database: pymongo or mongokit database instance. - - active_indexes: indexes to possibly add in the pattern of: - {'collection_name': { - 'identifier': { - 'index': [index_foo_goes_here], - 'unique': True}} - where 'index' is the index to add and all other options are - arguments for collection.create_index. - - Returns: - A list of indexes added in form ('collection', 'index_name') - """ - indexes_added = [] - - for collection_name, indexes in active_indexes.iteritems(): - collection = database[collection_name] - collection_indexes = collection.index_information().keys() - - for index_name, index_data in indexes.iteritems(): - if not index_name in collection_indexes: - # Get a copy actually so we don't modify the actual - # structure - index_data = copy.copy(index_data) - index = index_data.pop('index') - collection.create_index( - index, name=index_name, **index_data) - - indexes_added.append((collection_name, index_name)) - - return indexes_added - - -def remove_deprecated_indexes(database, deprecated_indexes=DEPRECATED_INDEXES): - """ - Remove any deprecated indexes from the database. - - Args: - - database: pymongo or mongokit database instance. - - deprecated_indexes: the indexes to deprecate in the pattern of: - {'collection_name': { - 'identifier': { - 'index': [index_foo_goes_here], - 'unique': True}} - - (... although we really only need the 'identifier' here, as the - rest of the information isn't used in this case. But it's kept - around so we can remember what it was) - - Returns: - A list of indexes removed in form ('collection', 'index_name') - """ - indexes_removed = [] - - for collection_name, indexes in deprecated_indexes.iteritems(): - collection = database[collection_name] - collection_indexes = collection.index_information().keys() - - for index_name, index_data in indexes.iteritems(): - if index_name in collection_indexes: - collection.drop_index(index_name) - - indexes_removed.append((collection_name, index_name)) - - return indexes_removed - - -################# -# Migration tools -################# - -# The default migration registry... -# -# Don't set this yourself! RegisterMigration will automatically fill -# this with stuff via decorating methods in migrations.py - -class MissingCurrentMigration(Exception): - pass - - -MIGRATIONS = {} - - -class RegisterMigration(object): - """ - Tool for registering migrations - - Call like: - - @RegisterMigration(33) - def update_dwarves(database): - [...] - - This will register your migration with the default migration - registry. Alternately, to specify a very specific - migration_registry, you can pass in that as the second argument. - - Note, the number of your migration should NEVER be 0 or less than - 0. 0 is the default "no migrations" state! - """ - def __init__(self, migration_number, migration_registry=MIGRATIONS): - assert migration_number > 0, "Migration number must be > 0!" - assert migration_number not in migration_registry, \ - "Duplicate migration numbers detected! That's not allowed!" - - self.migration_number = migration_number - self.migration_registry = migration_registry - - def __call__(self, migration): - self.migration_registry[self.migration_number] = migration - return migration - - -class MigrationManager(object): - """ - Migration handling tool. - - Takes information about a database, lets you update the database - to the latest migrations, etc. - """ - def __init__(self, database, migration_registry=MIGRATIONS): - """ - Args: - - database: database we're going to migrate - - migration_registry: where we should find all migrations to - run - """ - self.database = database - self.migration_registry = migration_registry - self._sorted_migrations = None - - def _ensure_current_migration_record(self): - """ - If there isn't a database[u'app_metadata'] mediagoblin entry - with the 'current_migration', throw an error. - """ - if self.database_current_migration() is None: - raise MissingCurrentMigration( - "Tried to call function which requires " - "'current_migration' set in database") - - @property - def sorted_migrations(self): - """ - Sort migrations if necessary and store in self._sorted_migrations - """ - if not self._sorted_migrations: - self._sorted_migrations = sorted( - self.migration_registry.items(), - # sort on the key... the migration number - key=lambda migration_tuple: migration_tuple[0]) - - return self._sorted_migrations - - def latest_migration(self): - """ - Return a migration number for the latest migration, or 0 if - there are no migrations. - """ - if self.sorted_migrations: - return self.sorted_migrations[-1][0] - else: - # If no migrations have been set, we start at 0. - return 0 - - def set_current_migration(self, migration_number): - """ - Set the migration in the database to migration_number - """ - # Add the mediagoblin migration if necessary - self.database[u'app_metadata'].update( - {u'_id': u'mediagoblin'}, - {u'$set': {u'current_migration': migration_number}}, - upsert=True) - - def install_migration_version_if_missing(self): - """ - Sets the migration to the latest version if no migration - version at all is set. - """ - mgoblin_metadata = self.database[u'app_metadata'].find_one( - {u'_id': u'mediagoblin'}) - if not mgoblin_metadata: - latest_migration = self.latest_migration() - self.set_current_migration(latest_migration) - - def database_current_migration(self): - """ - Return the current migration in the database. - """ - mgoblin_metadata = self.database[u'app_metadata'].find_one( - {u'_id': u'mediagoblin'}) - if not mgoblin_metadata: - return None - else: - return mgoblin_metadata[u'current_migration'] - - def database_at_latest_migration(self): - """ - See if the database is at the latest migration. - Returns a boolean. - """ - current_migration = self.database_current_migration() - return current_migration == self.latest_migration() - - def migrations_to_run(self): - """ - Get a list of migrations to run still, if any. - - Note that calling this will set your migration version to the - latest version if it isn't installed to anything yet! - """ - self._ensure_current_migration_record() - - db_current_migration = self.database_current_migration() - - return [ - (migration_number, migration_func) - for migration_number, migration_func in self.sorted_migrations - if migration_number > db_current_migration] - - def migrate_new(self, pre_callback=None, post_callback=None): - """ - Run all migrations. - - Includes two optional args: - - pre_callback: if called, this is a callback on something to - run pre-migration. Takes (migration_number, migration_func) - as arguments - - pre_callback: if called, this is a callback on something to - run post-migration. Takes (migration_number, migration_func) - as arguments - """ - # If we aren't set to any version number, presume we're at the - # latest (which means we'll do nothing here...) - self.install_migration_version_if_missing() - - for migration_number, migration_func in self.migrations_to_run(): - if pre_callback: - pre_callback(migration_number, migration_func) - migration_func(self.database) - self.set_current_migration(migration_number) - if post_callback: - post_callback(migration_number, migration_func) +from mediagoblin.db.mongo.util import (MigrationManager, ObjectId, InvalidId, + DESCENDING) diff --git a/mediagoblin/tests/test_migrations.py b/mediagoblin/tests/test_migrations.py index e7cef0a1..3e2e37ee 100644 --- a/mediagoblin/tests/test_migrations.py +++ b/mediagoblin/tests/test_migrations.py @@ -20,7 +20,7 @@ from pymongo import Connection from mediagoblin.tests.tools import ( install_fixtures_simple, assert_db_meets_expected) -from mediagoblin.db.util import ( +from mediagoblin.db.mongo.util import ( RegisterMigration, MigrationManager, ObjectId, MissingCurrentMigration) from mediagoblin.db.migrations import add_table_field From faf74067dae0f6f9d200a30369e9b7a4501b66ab Mon Sep 17 00:00:00 2001 From: Elrond Date: Tue, 20 Dec 2011 20:33:33 +0100 Subject: [PATCH 216/302] Move db/migrations.py -> db/mongo/migrations.py And change references. --- mediagoblin/db/models.py | 2 +- mediagoblin/db/{ => mongo}/migrations.py | 0 mediagoblin/init/__init__.py | 2 +- mediagoblin/tests/test_migrations.py | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename mediagoblin/db/{ => mongo}/migrations.py (100%) diff --git a/mediagoblin/db/models.py b/mediagoblin/db/models.py index 51c6e98e..e2ac1b5a 100644 --- a/mediagoblin/db/models.py +++ b/mediagoblin/db/models.py @@ -21,7 +21,7 @@ from mongokit import Document from mediagoblin.auth import lib as auth_lib from mediagoblin import mg_globals -from mediagoblin.db import migrations +from mediagoblin.db.mongo import migrations from mediagoblin.db.mongo.util import ASCENDING, DESCENDING, ObjectId from mediagoblin.tools.pagination import Pagination from mediagoblin.tools import url, common diff --git a/mediagoblin/db/migrations.py b/mediagoblin/db/mongo/migrations.py similarity index 100% rename from mediagoblin/db/migrations.py rename to mediagoblin/db/mongo/migrations.py diff --git a/mediagoblin/init/__init__.py b/mediagoblin/init/__init__.py index 08a0618d..5f7f83d4 100644 --- a/mediagoblin/init/__init__.py +++ b/mediagoblin/init/__init__.py @@ -57,7 +57,7 @@ def setup_database(): app_config = mg_globals.app_config # This MUST be imported so as to set up the appropriate migrations! - from mediagoblin.db import migrations + from mediagoblin.db.mongo import migrations # Set up the database connection, db = setup_connection_and_db_from_config(app_config) diff --git a/mediagoblin/tests/test_migrations.py b/mediagoblin/tests/test_migrations.py index 3e2e37ee..8e573f5a 100644 --- a/mediagoblin/tests/test_migrations.py +++ b/mediagoblin/tests/test_migrations.py @@ -23,7 +23,7 @@ from mediagoblin.tests.tools import ( from mediagoblin.db.mongo.util import ( RegisterMigration, MigrationManager, ObjectId, MissingCurrentMigration) -from mediagoblin.db.migrations import add_table_field +from mediagoblin.db.mongo.migrations import add_table_field # This one will get filled with local migrations TEST_MIGRATION_REGISTRY = {} From 4ae4012dad3f5638ea7b510d40f0b4d0b641fe2a Mon Sep 17 00:00:00 2001 From: Elrond Date: Tue, 20 Dec 2011 20:41:21 +0100 Subject: [PATCH 217/302] Move db/models.py -> db/mongo/models.py To my surprise, there was only ONE reference to models.py. From open.py. --- mediagoblin/db/{ => mongo}/models.py | 0 mediagoblin/db/mongo/open.py | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename mediagoblin/db/{ => mongo}/models.py (100%) diff --git a/mediagoblin/db/models.py b/mediagoblin/db/mongo/models.py similarity index 100% rename from mediagoblin/db/models.py rename to mediagoblin/db/mongo/models.py diff --git a/mediagoblin/db/mongo/open.py b/mediagoblin/db/mongo/open.py index e677ba12..63889292 100644 --- a/mediagoblin/db/mongo/open.py +++ b/mediagoblin/db/mongo/open.py @@ -17,7 +17,7 @@ import pymongo import mongokit from paste.deploy.converters import asint -from mediagoblin.db import models +from mediagoblin.db.mongo import models def connect_database_from_config(app_config, use_pymongo=False): From c8cb0ee88f8eb667af77c5741cfb04f95afe66b0 Mon Sep 17 00:00:00 2001 From: Joar Wandborg Date: Tue, 20 Dec 2011 22:06:36 +0100 Subject: [PATCH 218/302] Polishing the webfinger implementation - Changed quotes in the templates from " to ' - Changed all link generation to use request.urlgen - Moved xrd links data generation from template to view - Added parsing of the account URI using urlparse --- .../mediagoblin/webfinger/host-meta.xml | 12 +- .../templates/mediagoblin/webfinger/xrd.xml | 20 +- mediagoblin/tools/feed.py | 527 ++++++++++++++++++ mediagoblin/webfinger/views.py | 94 +++- 4 files changed, 623 insertions(+), 30 deletions(-) create mode 100644 mediagoblin/tools/feed.py diff --git a/mediagoblin/templates/mediagoblin/webfinger/host-meta.xml b/mediagoblin/templates/mediagoblin/webfinger/host-meta.xml index dff2c9aa..95a1a176 100644 --- a/mediagoblin/templates/mediagoblin/webfinger/host-meta.xml +++ b/mediagoblin/templates/mediagoblin/webfinger/host-meta.xml @@ -14,14 +14,14 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -#} - - + + {{ request.host }} - - {{ llrd_title }} + + {{ lrdd_title }} diff --git a/mediagoblin/templates/mediagoblin/webfinger/xrd.xml b/mediagoblin/templates/mediagoblin/webfinger/xrd.xml index 9a793637..1fe34577 100644 --- a/mediagoblin/templates/mediagoblin/webfinger/xrd.xml +++ b/mediagoblin/templates/mediagoblin/webfinger/xrd.xml @@ -14,16 +14,14 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -#} - - + + - {{ request.GET.get('uri') }} - http://{{ request.host }}/u/{{ username }} - - - - + {{ subject }} + {{ alias }} + {% for link in links %} + + {%- endfor %} diff --git a/mediagoblin/tools/feed.py b/mediagoblin/tools/feed.py new file mode 100644 index 00000000..7c14a42a --- /dev/null +++ b/mediagoblin/tools/feed.py @@ -0,0 +1,527 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +from lxml import etree +from lxml.builder import ElementMaker +from werkzeug.wrappers import BaseResponse + +import datetime + +""" + Feed engine written for GNU MediaGoblin, + based on werkzeug atom feeds tool (werkzeug.contrib.atom) + + The feed library contains two types of classes: + - Entities that contains the feed data. + - Generators that are injected to the above classes and are able to + generate feeds in a specific format. An atom feed genearator is + provided, but others could be written as well. + + The Werkzeurg library interface have been mimetized, so the replacement can + be done with only switching the import call. + + Example:: + + def atom_feed(request): + feed = AtomFeed("My Blog", feed_url=request.url, + url=request.host_url, + subtitle="My example blog for a feed test.") + for post in Post.query.limit(10).all(): + feed.add(post.title, post.body, content_type='html', + author=post.author, url=post.url, id=post.uid, + updated=post.last_update, published=post.pub_date) + return feed.get_response() +""" + + +## +# Class FeedGenerator +# +class FeedGenerator(object): + def __init__(self): + pass + + def format_iso8601(self, obj): + """Format a datetime object for iso8601""" + return obj.strftime('%Y-%m-%dT%H:%M:%SZ') + + +## +# Class AtomGenerator +# +class AtomGenerator(FeedGenerator): + """ Generator that generate feeds in Atom format """ + NAMESPACE = "http://www.w3.org/2005/Atom" + + def __init__(self): + pass + + def generate(self, data): + """Return an XML tree representation.""" + if isinstance(data, AtomFeed): + return self.generate_feed(data) + elif isinstance(data, FeedEntry): + return self.generate_feedEntry(data) + + def generate_text_block(self, name, content, content_type=None): + """Helper method for the builder that creates an XML text block.""" + root = etree.Element(name) + + if content_type: + root.set('type', content_type) + + if content_type == 'xhtml': + div_ele = etree.Element('div') + div_ele.set('xmlns', XHTML_NAMESPACE) + div_ele.text = content + root.append(div_ele) + else: + root.text = content + + return root + + def generate_feed(self, data): + """Return an XML tree representation of the feed.""" + NSMAP = {None: self.NAMESPACE} + root = etree.Element("feed", nsmap=NSMAP) + + E = ElementMaker() + + # atom demands either an author element in every entry or a global one + if not data.author: + if False in map(lambda e: bool(e.author), data.entries): + data.author = ({'name': 'Unknown author'},) + + if not data.updated: + dates = sorted([entry.updated for entry in data.entries]) + data.updated = dates and dates[-1] or datetime.utcnow() + + title_ele = self.generate_text_block( + 'title', + data.title, + data.title_type) + root.append(title_ele) + + root.append(E.id(data.id)) + root.append(E.updated(self.format_iso8601(data.updated))) + + if data.url: + link_ele = etree.Element("link") + link_ele.set("href", data.url) + root.append(link_ele) + + if data.feed_url: + link_ele = etree.Element("link") + link_ele.set("href", data.feed_url) + link_ele.set("rel", "self") + root.append(link_ele) + + for link in data.links: + link_ele = etree.Element("link") + for name, value in link.items(): + link_ele.set(name, value) + root.append(link_ele) + + for author in data.author: + author_element = etree.Element("author") + author_element.append(E.name(author['name'])) + if 'uri' in author: + author_element.append(E.name(author['uri'])) + if 'email' in author: + author_element.append(E.name(author['email'])) + + root.append(author_element) + + if data.subtitle: + root.append(self.generate_text_block('subtitle', data.subtitle, + data.subtitle_type)) + if data.icon: + root.append(E.icon(data.icon)) + + if data.logo: + root.append(E.logo(data.logo)) + + if data.rights: + root.append(self.generate_text_block('rights', data.rights, + data.rights_type)) + + generator_name, generator_url, generator_version = data.generator + if generator_name or generator_url or generator_version: + generator_ele = etree.Element("generator") + if generator_url: + generator_ele.set("uri", generator_url, True) + if generator_version: + generator_ele.set("version", generator_version) + + generator_ele.text = generator_name + + root.append(generator_ele) + + for entry in data.entries: + root.append(entry.generate()) + + return root + + def generate_feedEntry(self, data): + """Return an XML tree representation of the feed entry.""" + E = ElementMaker() + root = etree.Element("entry") + + if data.xml_base: + root.base = data.xml_base + + title_ele = self.generate_text_block( + 'title', + data.title, + data.title_type) + root.append(title_ele) + + root.append(E.id(data.id)) + root.append(E.updated(self.format_iso8601(data.updated))) + + if data.published: + root.append(E.published(self.format_iso8601(data.published))) + + if data.url: + link_ele = etree.Element("link") + link_ele.set("href", data.url) + root.append(link_ele) + + for author in data.author: + author_element = etree.Element("author") + author_element.append(E.name(author['name'])) + if 'uri' in author: + author_element.append(E.name(author['uri'])) + if 'email' in author: + author_element.append(E.name(author['email'])) + + root.append(author_element) + + for link in data.links: + link_ele = etree.Element("link") + for name, value in link.items(): + link_ele.set(name, value) + root.append(link_ele) + + print data.thumbnail + + if data.thumbnail: + namespace = "http://search.yahoo.com/mrss/" + nsmap = {"media": namespace} + thumbnail_ele = etree.Element( + "{http://search.yahoo.com/mrss/}thumbnail", nsmap=nsmap) + thumbnail_ele.set("url", data.thumbnail) + + root.append(thumbnail_ele) + + if data.summary: + summary_ele = self.generate_text_block('summary', data.summary, + data.summary_type) + root.append(summary_ele) + + if data.content: + content = data.content + + if data.thumbnail: + thumbnail_html = etree.Element("img") + thumbnail_html.set("src", data.thumbnail) + content = etree.tostring(thumbnail_html) + content + + content_ele = self.generate_text_block('content', content, + data.content_type) + root.append(content_ele) + + for name, value in data.custom.items(): + element = etree.Element(name) + element.text = value + root.append(element) + + return root + + +## +# Class AtomFeed +# +class AtomFeed(object): + """ + A helper class that contains feeds. By default, it uses the AtomGenerator + but others could be injected. It has the AtomFeed name to keep the name + it had on werkzeug library + + Following Werkzeurg implementation, the constructor takes a lot of + parameters. As an addition, the class will also store custom parameters for + fields not explicitly supported by the library. + + :param feed_generator: The generator that will be used to generate the feed + defaults to AtomGenerator + :param title: the title of the feed. Required. + :param title_type: the type attribute for the title element. One of + ``'html'``, ``'text'`` or ``'xhtml'``. + :param url: the url for the feed (not the url *of* the feed) + :param id: a globally unique id for the feed. Must be an URI. If + not present the `feed_url` is used, but one of both is + required. + :param updated: the time the feed was modified the last time. Must + be a :class:`datetime.datetime` object. If not + present the latest entry's `updated` is used. + :param feed_url: the URL to the feed. Should be the URL that was + requested. + :param author: the author of the feed. Must be either a string (the + name) or a dict with name (required) and uri or + email (both optional). Can be a list of (may be + mixed, too) strings and dicts, too, if there are + multiple authors. Required if not every entry has an + author element. + :param icon: an icon for the feed. + :param logo: a logo for the feed. + :param rights: copyright information for the feed. + :param rights_type: the type attribute for the rights element. One of + ``'html'``, ``'text'`` or ``'xhtml'``. Default is + ``'text'``. + :param subtitle: a short description of the feed. + :param subtitle_type: the type attribute for the subtitle element. + One of ``'text'``, ``'html'``, ``'text'`` + or ``'xhtml'``. Default is ``'text'``. + :param links: additional links. Must be a list of dictionaries with + href (required) and rel, type, hreflang, title, length + (all optional) + :param generator: the software that generated this feed. This must be + a tuple in the form ``(name, url, version)``. If + you don't want to specify one of them, set the item + to `None`. + :param entries: a list with the entries for the feed. Entries can also + be added later with :meth:`add`. + + For more information on the elements see + http://www.atomenabled.org/developers/syndication/ + + Everywhere where a list is demanded, any iterable can be used. + """ + + default_generator = ('GNU Mediagoblin', None, None) + default_feed_generator = AtomGenerator() + + def __init__(self, title=None, entries=None, feed_generator=None, + **kwargs): + self.feed_generator = feed_generator + self.title = title + self.title_type = kwargs.get('title_type', 'text') + self.url = kwargs.get('url') + self.feed_url = kwargs.get('feed_url', self.url) + self.id = kwargs.get('id', self.feed_url) + self.updated = kwargs.get('updated') + self.author = kwargs.get('author', ()) + self.icon = kwargs.get('icon') + self.logo = kwargs.get('logo') + self.rights = kwargs.get('rights') + self.rights_type = kwargs.get('rights_type') + self.subtitle = kwargs.get('subtitle') + self.subtitle_type = kwargs.get('subtitle_type', 'text') + self.generator = kwargs.get('generator') + if self.generator is None: + self.generator = self.default_generator + self.links = kwargs.get('links', []) + self.entries = entries and list(entries) or [] + + if not hasattr(self.author, '__iter__') \ + or isinstance(self.author, (basestring, dict)): + self.author = [self.author] + for i, author in enumerate(self.author): + if not isinstance(author, dict): + self.author[i] = {'name': author} + + if not self.feed_generator: + self.feed_generator = self.default_feed_generator + if not self.title: + raise ValueError('title is required') + if not self.id: + raise ValueError('id is required') + for author in self.author: + if 'name' not in author: + raise TypeError('author must contain at least a name') + + # Look for arguments that we haven't matched with object members. + # They will be added to the custom dictionary. + # This way we can have custom fields not specified in this class. + self.custom = {} + properties = dir(self) + + for name, value in kwargs.items(): + if (properties.count(name) == 0): + self.custom[name] = value + + def add(self, *args, **kwargs): + """Add a new entry to the feed. This function can either be called + with a :class:`FeedEntry` or some keyword and positional arguments + that are forwarded to the :class:`FeedEntry` constructor. + """ + if len(args) == 1 and not kwargs and isinstance(args[0], FeedEntry): + args[0].generator = self.generator + self.entries.append(args[0]) + else: + kwargs['feed_url'] = self.feed_url + self.entries.append(FeedEntry(feed_generator=self.feed_generator, + *args, **kwargs)) + + def __repr__(self): + return '<%s %r (%d entries)>' % ( + self.__class__.__name__, + self.title, + len(self.entries) + ) + + def generate(self): + """Return an XML tree representation of the feed.""" + return self.feed_generator.generate(self) + + def to_string(self): + """Convert the feed into a string.""" + return etree.tostring(self.generate(), encoding='UTF-8') + + def get_response(self): + """Return a response object for the feed.""" + return BaseResponse(self.to_string(), mimetype='application/atom+xml') + + def __call__(self, environ, start_response): + """Use the class as WSGI response object.""" + return self.get_response()(environ, start_response) + + def __unicode__(self): + return self.to_string() + + def __str__(self): + return self.to_string().encode('utf-8') + + +## +# Class FeedEntry +# +class FeedEntry(object): + """Represents a single entry in a feed. + + Following Werkzeurg implementation, the constructor takes a lot of + parameters. As an addition, the class will also store custom parameters for + fields not explicitly supported by the library. + + :param feed_generator: The generator that will be used to generate the feed. + defaults to AtomGenerator + :param title: the title of the entry. Required. + :param title_type: the type attribute for the title element. One of + ``'html'``, ``'text'`` or ``'xhtml'``. + :param content: the content of the entry. + :param content_type: the type attribute for the content element. One + of ``'html'``, ``'text'`` or ``'xhtml'``. + :param summary: a summary of the entry's content. + :param summary_type: the type attribute for the summary element. One + of ``'html'``, ``'text'`` or ``'xhtml'``. + :param url: the url for the entry. + :param id: a globally unique id for the entry. Must be an URI. If + not present the URL is used, but one of both is required. + :param updated: the time the entry was modified the last time. Must + be a :class:`datetime.datetime` object. Required. + :param author: the author of the feed. Must be either a string (the + name) or a dict with name (required) and uri or + email (both optional). Can be a list of (may be + mixed, too) strings and dicts, too, if there are + multiple authors. Required if not every entry has an + author element. + :param published: the time the entry was initially published. Must + be a :class:`datetime.datetime` object. + :param rights: copyright information for the entry. + :param rights_type: the type attribute for the rights element. One of + ``'html'``, ``'text'`` or ``'xhtml'``. Default is + ``'text'``. + :param links: additional links. Must be a list of dictionaries with + href (required) and rel, type, hreflang, title, length + (all optional) + :param xml_base: The xml base (url) for this feed item. If not provided + it will default to the item url. + + For more information on the elements see + http://www.atomenabled.org/developers/syndication/ + + Everywhere where a list is demanded, any iterable can be used. + """ + + default_feed_generator = AtomGenerator() + + def __init__(self, title=None, content=None, feed_url=None, + feed_generator=None, **kwargs): + self.feed_generator = feed_generator + self.title = title + self.title_type = kwargs.get('title_type', 'text') + self.content = content + self.content_type = kwargs.get('content_type', 'html') + self.url = kwargs.get('url') + self.id = kwargs.get('id', self.url) + self.updated = kwargs.get('updated') + self.summary = kwargs.get('summary') + self.summary_type = kwargs.get('summary_type', 'html') + self.author = kwargs.get('author') + self.published = kwargs.get('published') + self.rights = kwargs.get('rights') + self.links = kwargs.get('links', []) + self.xml_base = kwargs.get('xml_base', feed_url) + self.thumbnail = kwargs.get('thumbnail') + + + if not hasattr(self.author, '__iter__') \ + or isinstance(self.author, (basestring, dict)): + self.author = [self.author] + for i, author in enumerate(self.author): + if not isinstance(author, dict): + self.author[i] = {'name': author} + + if not self.feed_generator: + self.feed_generator = self.default_feed_generator + if not self.title: + raise ValueError('title is required') + if not self.id: + raise ValueError('id is required') + if not self.updated: + raise ValueError('updated is required') + + # Look for arguments that we haven't matched with object members. + # They will be added to the custom dictionary. + # This way we can have custom fields not specified in this class. + self.custom = {} + properties = dir(self) + + for name, value in kwargs.items(): + if ( properties.count(name) == 0 ): + self.custom[name] = value + + + def __repr__(self): + return '<%s %r>' % ( + self.__class__.__name__, + self.title + ) + + def generate(self): + """Returns lxml element tree representation of the feed entry""" + return self.feed_generator.generate(self) + + def to_string(self): + """Convert the feed item into a unicode object.""" + return etree.tostring(self.generate(), encoding='utf-8') + + def __unicode__(self): + return self.to_string() + + def __str__(self): + return self.to_string().encode('utf-8') + + diff --git a/mediagoblin/webfinger/views.py b/mediagoblin/webfinger/views.py index 7cbd0913..e9aa600c 100644 --- a/mediagoblin/webfinger/views.py +++ b/mediagoblin/webfinger/views.py @@ -15,32 +15,100 @@ # along with this program. If not, see . import re -import mediagoblin.mg_globals as mg_globals -from mediagoblin.tools.response import render_to_response +from urlparse import urlparse -LRDD_TEMPLATE = '{protocol}://{host}/api/webfinger/xrd?uri={{uri}}' +from mediagoblin.tools.response import render_to_response, render_404 def host_meta(request): ''' Webfinger host-meta ''' + + placeholder = 'MG_LRDD_PLACEHOLDER' + + lrdd_title = 'GNU MediaGoblin - User lookup' + + lrdd_template = request.urlgen( + 'mediagoblin.webfinger.xrd', + uri=placeholder, + qualified=True) + return render_to_response( request, 'mediagoblin/webfinger/host-meta.xml', {'request': request, - 'lrdd_template': LRDD_TEMPLATE.format( - protocol='http', - host=request.host)}) + 'lrdd_template': lrdd_template, + 'lrdd_title': lrdd_title, + 'placeholder': placeholder}) + +MATCH_SCHEME_PATTERN = re.compile(r'^acct:') def xrd(request): ''' Find user data based on a webfinger URI ''' - return render_to_response( - request, - 'mediagoblin/webfinger/xrd.xml', - {'request': request, - 'username': re.search( - r'^(acct:)?([^@]*)', - request.GET.get('uri')).group(2)}) + param_uri = request.GET.get('uri') + + if not param_uri: + return render_404(request) + + ''' + :py:module:`urlparse` does not recognize usernames in URIs of the + form ``acct:user@example.org`` or ``user@example.org``. + ''' + if not MATCH_SCHEME_PATTERN.search(param_uri): + # Assume the URI is in the form ``user@example.org`` + uri = 'acct://' + param_uri + else: + # Assumes the URI looks like ``acct:user@example.org + uri = MATCH_SCHEME_PATTERN.sub( + 'acct://', param_uri) + + parsed = urlparse(uri) + + xrd_subject = param_uri + + # TODO: Verify that the user exists + # Q: Does webfinger support error handling in this case? + # Returning 404 seems intuitive, need to check. + if parsed.username: + # The user object + # TODO: Fetch from database instead of using the MockUser + user = MockUser() + user.username = parsed.username + + xrd_links = [ + {'attrs': { + 'rel': 'http://microformats.org/profile/hcard', + 'href': request.urlgen( + 'mediagoblin.user_pages.user_home', + user=user.username, + qualified=True)}}, + {'attrs': { + 'rel': 'http://schemas.google.com/g/2010#updates-from', + 'href': request.urlgen( + 'mediagoblin.user_pages.atom_feed', + user=user.username, + qualified=True)}}] + + xrd_alias = request.urlgen( + 'mediagoblin.user_pages.user_home', + user=user.username, + qualified=True) + + return render_to_response( + request, + 'mediagoblin/webfinger/xrd.xml', + {'request': request, + 'subject': xrd_subject, + 'alias': xrd_alias, + 'links': xrd_links }) + else: + return render_404(request) + +class MockUser(object): + ''' + TEMPORARY user object + ''' + username = None From 448a58534f585aac95db9d04f43d73634e96eb4b Mon Sep 17 00:00:00 2001 From: Joar Wandborg Date: Tue, 20 Dec 2011 22:13:43 +0100 Subject: [PATCH 219/302] Removed mediagoblin.tools.feed which was accidentally included --- mediagoblin/tools/feed.py | 527 -------------------------------------- 1 file changed, 527 deletions(-) delete mode 100644 mediagoblin/tools/feed.py diff --git a/mediagoblin/tools/feed.py b/mediagoblin/tools/feed.py deleted file mode 100644 index 7c14a42a..00000000 --- a/mediagoblin/tools/feed.py +++ /dev/null @@ -1,527 +0,0 @@ -# GNU MediaGoblin -- federated, autonomous media hosting -# Copyright (C) 2011 MediaGoblin contributors. See AUTHORS. -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -from lxml import etree -from lxml.builder import ElementMaker -from werkzeug.wrappers import BaseResponse - -import datetime - -""" - Feed engine written for GNU MediaGoblin, - based on werkzeug atom feeds tool (werkzeug.contrib.atom) - - The feed library contains two types of classes: - - Entities that contains the feed data. - - Generators that are injected to the above classes and are able to - generate feeds in a specific format. An atom feed genearator is - provided, but others could be written as well. - - The Werkzeurg library interface have been mimetized, so the replacement can - be done with only switching the import call. - - Example:: - - def atom_feed(request): - feed = AtomFeed("My Blog", feed_url=request.url, - url=request.host_url, - subtitle="My example blog for a feed test.") - for post in Post.query.limit(10).all(): - feed.add(post.title, post.body, content_type='html', - author=post.author, url=post.url, id=post.uid, - updated=post.last_update, published=post.pub_date) - return feed.get_response() -""" - - -## -# Class FeedGenerator -# -class FeedGenerator(object): - def __init__(self): - pass - - def format_iso8601(self, obj): - """Format a datetime object for iso8601""" - return obj.strftime('%Y-%m-%dT%H:%M:%SZ') - - -## -# Class AtomGenerator -# -class AtomGenerator(FeedGenerator): - """ Generator that generate feeds in Atom format """ - NAMESPACE = "http://www.w3.org/2005/Atom" - - def __init__(self): - pass - - def generate(self, data): - """Return an XML tree representation.""" - if isinstance(data, AtomFeed): - return self.generate_feed(data) - elif isinstance(data, FeedEntry): - return self.generate_feedEntry(data) - - def generate_text_block(self, name, content, content_type=None): - """Helper method for the builder that creates an XML text block.""" - root = etree.Element(name) - - if content_type: - root.set('type', content_type) - - if content_type == 'xhtml': - div_ele = etree.Element('div') - div_ele.set('xmlns', XHTML_NAMESPACE) - div_ele.text = content - root.append(div_ele) - else: - root.text = content - - return root - - def generate_feed(self, data): - """Return an XML tree representation of the feed.""" - NSMAP = {None: self.NAMESPACE} - root = etree.Element("feed", nsmap=NSMAP) - - E = ElementMaker() - - # atom demands either an author element in every entry or a global one - if not data.author: - if False in map(lambda e: bool(e.author), data.entries): - data.author = ({'name': 'Unknown author'},) - - if not data.updated: - dates = sorted([entry.updated for entry in data.entries]) - data.updated = dates and dates[-1] or datetime.utcnow() - - title_ele = self.generate_text_block( - 'title', - data.title, - data.title_type) - root.append(title_ele) - - root.append(E.id(data.id)) - root.append(E.updated(self.format_iso8601(data.updated))) - - if data.url: - link_ele = etree.Element("link") - link_ele.set("href", data.url) - root.append(link_ele) - - if data.feed_url: - link_ele = etree.Element("link") - link_ele.set("href", data.feed_url) - link_ele.set("rel", "self") - root.append(link_ele) - - for link in data.links: - link_ele = etree.Element("link") - for name, value in link.items(): - link_ele.set(name, value) - root.append(link_ele) - - for author in data.author: - author_element = etree.Element("author") - author_element.append(E.name(author['name'])) - if 'uri' in author: - author_element.append(E.name(author['uri'])) - if 'email' in author: - author_element.append(E.name(author['email'])) - - root.append(author_element) - - if data.subtitle: - root.append(self.generate_text_block('subtitle', data.subtitle, - data.subtitle_type)) - if data.icon: - root.append(E.icon(data.icon)) - - if data.logo: - root.append(E.logo(data.logo)) - - if data.rights: - root.append(self.generate_text_block('rights', data.rights, - data.rights_type)) - - generator_name, generator_url, generator_version = data.generator - if generator_name or generator_url or generator_version: - generator_ele = etree.Element("generator") - if generator_url: - generator_ele.set("uri", generator_url, True) - if generator_version: - generator_ele.set("version", generator_version) - - generator_ele.text = generator_name - - root.append(generator_ele) - - for entry in data.entries: - root.append(entry.generate()) - - return root - - def generate_feedEntry(self, data): - """Return an XML tree representation of the feed entry.""" - E = ElementMaker() - root = etree.Element("entry") - - if data.xml_base: - root.base = data.xml_base - - title_ele = self.generate_text_block( - 'title', - data.title, - data.title_type) - root.append(title_ele) - - root.append(E.id(data.id)) - root.append(E.updated(self.format_iso8601(data.updated))) - - if data.published: - root.append(E.published(self.format_iso8601(data.published))) - - if data.url: - link_ele = etree.Element("link") - link_ele.set("href", data.url) - root.append(link_ele) - - for author in data.author: - author_element = etree.Element("author") - author_element.append(E.name(author['name'])) - if 'uri' in author: - author_element.append(E.name(author['uri'])) - if 'email' in author: - author_element.append(E.name(author['email'])) - - root.append(author_element) - - for link in data.links: - link_ele = etree.Element("link") - for name, value in link.items(): - link_ele.set(name, value) - root.append(link_ele) - - print data.thumbnail - - if data.thumbnail: - namespace = "http://search.yahoo.com/mrss/" - nsmap = {"media": namespace} - thumbnail_ele = etree.Element( - "{http://search.yahoo.com/mrss/}thumbnail", nsmap=nsmap) - thumbnail_ele.set("url", data.thumbnail) - - root.append(thumbnail_ele) - - if data.summary: - summary_ele = self.generate_text_block('summary', data.summary, - data.summary_type) - root.append(summary_ele) - - if data.content: - content = data.content - - if data.thumbnail: - thumbnail_html = etree.Element("img") - thumbnail_html.set("src", data.thumbnail) - content = etree.tostring(thumbnail_html) + content - - content_ele = self.generate_text_block('content', content, - data.content_type) - root.append(content_ele) - - for name, value in data.custom.items(): - element = etree.Element(name) - element.text = value - root.append(element) - - return root - - -## -# Class AtomFeed -# -class AtomFeed(object): - """ - A helper class that contains feeds. By default, it uses the AtomGenerator - but others could be injected. It has the AtomFeed name to keep the name - it had on werkzeug library - - Following Werkzeurg implementation, the constructor takes a lot of - parameters. As an addition, the class will also store custom parameters for - fields not explicitly supported by the library. - - :param feed_generator: The generator that will be used to generate the feed - defaults to AtomGenerator - :param title: the title of the feed. Required. - :param title_type: the type attribute for the title element. One of - ``'html'``, ``'text'`` or ``'xhtml'``. - :param url: the url for the feed (not the url *of* the feed) - :param id: a globally unique id for the feed. Must be an URI. If - not present the `feed_url` is used, but one of both is - required. - :param updated: the time the feed was modified the last time. Must - be a :class:`datetime.datetime` object. If not - present the latest entry's `updated` is used. - :param feed_url: the URL to the feed. Should be the URL that was - requested. - :param author: the author of the feed. Must be either a string (the - name) or a dict with name (required) and uri or - email (both optional). Can be a list of (may be - mixed, too) strings and dicts, too, if there are - multiple authors. Required if not every entry has an - author element. - :param icon: an icon for the feed. - :param logo: a logo for the feed. - :param rights: copyright information for the feed. - :param rights_type: the type attribute for the rights element. One of - ``'html'``, ``'text'`` or ``'xhtml'``. Default is - ``'text'``. - :param subtitle: a short description of the feed. - :param subtitle_type: the type attribute for the subtitle element. - One of ``'text'``, ``'html'``, ``'text'`` - or ``'xhtml'``. Default is ``'text'``. - :param links: additional links. Must be a list of dictionaries with - href (required) and rel, type, hreflang, title, length - (all optional) - :param generator: the software that generated this feed. This must be - a tuple in the form ``(name, url, version)``. If - you don't want to specify one of them, set the item - to `None`. - :param entries: a list with the entries for the feed. Entries can also - be added later with :meth:`add`. - - For more information on the elements see - http://www.atomenabled.org/developers/syndication/ - - Everywhere where a list is demanded, any iterable can be used. - """ - - default_generator = ('GNU Mediagoblin', None, None) - default_feed_generator = AtomGenerator() - - def __init__(self, title=None, entries=None, feed_generator=None, - **kwargs): - self.feed_generator = feed_generator - self.title = title - self.title_type = kwargs.get('title_type', 'text') - self.url = kwargs.get('url') - self.feed_url = kwargs.get('feed_url', self.url) - self.id = kwargs.get('id', self.feed_url) - self.updated = kwargs.get('updated') - self.author = kwargs.get('author', ()) - self.icon = kwargs.get('icon') - self.logo = kwargs.get('logo') - self.rights = kwargs.get('rights') - self.rights_type = kwargs.get('rights_type') - self.subtitle = kwargs.get('subtitle') - self.subtitle_type = kwargs.get('subtitle_type', 'text') - self.generator = kwargs.get('generator') - if self.generator is None: - self.generator = self.default_generator - self.links = kwargs.get('links', []) - self.entries = entries and list(entries) or [] - - if not hasattr(self.author, '__iter__') \ - or isinstance(self.author, (basestring, dict)): - self.author = [self.author] - for i, author in enumerate(self.author): - if not isinstance(author, dict): - self.author[i] = {'name': author} - - if not self.feed_generator: - self.feed_generator = self.default_feed_generator - if not self.title: - raise ValueError('title is required') - if not self.id: - raise ValueError('id is required') - for author in self.author: - if 'name' not in author: - raise TypeError('author must contain at least a name') - - # Look for arguments that we haven't matched with object members. - # They will be added to the custom dictionary. - # This way we can have custom fields not specified in this class. - self.custom = {} - properties = dir(self) - - for name, value in kwargs.items(): - if (properties.count(name) == 0): - self.custom[name] = value - - def add(self, *args, **kwargs): - """Add a new entry to the feed. This function can either be called - with a :class:`FeedEntry` or some keyword and positional arguments - that are forwarded to the :class:`FeedEntry` constructor. - """ - if len(args) == 1 and not kwargs and isinstance(args[0], FeedEntry): - args[0].generator = self.generator - self.entries.append(args[0]) - else: - kwargs['feed_url'] = self.feed_url - self.entries.append(FeedEntry(feed_generator=self.feed_generator, - *args, **kwargs)) - - def __repr__(self): - return '<%s %r (%d entries)>' % ( - self.__class__.__name__, - self.title, - len(self.entries) - ) - - def generate(self): - """Return an XML tree representation of the feed.""" - return self.feed_generator.generate(self) - - def to_string(self): - """Convert the feed into a string.""" - return etree.tostring(self.generate(), encoding='UTF-8') - - def get_response(self): - """Return a response object for the feed.""" - return BaseResponse(self.to_string(), mimetype='application/atom+xml') - - def __call__(self, environ, start_response): - """Use the class as WSGI response object.""" - return self.get_response()(environ, start_response) - - def __unicode__(self): - return self.to_string() - - def __str__(self): - return self.to_string().encode('utf-8') - - -## -# Class FeedEntry -# -class FeedEntry(object): - """Represents a single entry in a feed. - - Following Werkzeurg implementation, the constructor takes a lot of - parameters. As an addition, the class will also store custom parameters for - fields not explicitly supported by the library. - - :param feed_generator: The generator that will be used to generate the feed. - defaults to AtomGenerator - :param title: the title of the entry. Required. - :param title_type: the type attribute for the title element. One of - ``'html'``, ``'text'`` or ``'xhtml'``. - :param content: the content of the entry. - :param content_type: the type attribute for the content element. One - of ``'html'``, ``'text'`` or ``'xhtml'``. - :param summary: a summary of the entry's content. - :param summary_type: the type attribute for the summary element. One - of ``'html'``, ``'text'`` or ``'xhtml'``. - :param url: the url for the entry. - :param id: a globally unique id for the entry. Must be an URI. If - not present the URL is used, but one of both is required. - :param updated: the time the entry was modified the last time. Must - be a :class:`datetime.datetime` object. Required. - :param author: the author of the feed. Must be either a string (the - name) or a dict with name (required) and uri or - email (both optional). Can be a list of (may be - mixed, too) strings and dicts, too, if there are - multiple authors. Required if not every entry has an - author element. - :param published: the time the entry was initially published. Must - be a :class:`datetime.datetime` object. - :param rights: copyright information for the entry. - :param rights_type: the type attribute for the rights element. One of - ``'html'``, ``'text'`` or ``'xhtml'``. Default is - ``'text'``. - :param links: additional links. Must be a list of dictionaries with - href (required) and rel, type, hreflang, title, length - (all optional) - :param xml_base: The xml base (url) for this feed item. If not provided - it will default to the item url. - - For more information on the elements see - http://www.atomenabled.org/developers/syndication/ - - Everywhere where a list is demanded, any iterable can be used. - """ - - default_feed_generator = AtomGenerator() - - def __init__(self, title=None, content=None, feed_url=None, - feed_generator=None, **kwargs): - self.feed_generator = feed_generator - self.title = title - self.title_type = kwargs.get('title_type', 'text') - self.content = content - self.content_type = kwargs.get('content_type', 'html') - self.url = kwargs.get('url') - self.id = kwargs.get('id', self.url) - self.updated = kwargs.get('updated') - self.summary = kwargs.get('summary') - self.summary_type = kwargs.get('summary_type', 'html') - self.author = kwargs.get('author') - self.published = kwargs.get('published') - self.rights = kwargs.get('rights') - self.links = kwargs.get('links', []) - self.xml_base = kwargs.get('xml_base', feed_url) - self.thumbnail = kwargs.get('thumbnail') - - - if not hasattr(self.author, '__iter__') \ - or isinstance(self.author, (basestring, dict)): - self.author = [self.author] - for i, author in enumerate(self.author): - if not isinstance(author, dict): - self.author[i] = {'name': author} - - if not self.feed_generator: - self.feed_generator = self.default_feed_generator - if not self.title: - raise ValueError('title is required') - if not self.id: - raise ValueError('id is required') - if not self.updated: - raise ValueError('updated is required') - - # Look for arguments that we haven't matched with object members. - # They will be added to the custom dictionary. - # This way we can have custom fields not specified in this class. - self.custom = {} - properties = dir(self) - - for name, value in kwargs.items(): - if ( properties.count(name) == 0 ): - self.custom[name] = value - - - def __repr__(self): - return '<%s %r>' % ( - self.__class__.__name__, - self.title - ) - - def generate(self): - """Returns lxml element tree representation of the feed entry""" - return self.feed_generator.generate(self) - - def to_string(self): - """Convert the feed item into a unicode object.""" - return etree.tostring(self.generate(), encoding='utf-8') - - def __unicode__(self): - return self.to_string() - - def __str__(self): - return self.to_string().encode('utf-8') - - From 85c916919b1e1fe31472feac74f8c216a5df608f Mon Sep 17 00:00:00 2001 From: Joar Wandborg Date: Tue, 20 Dec 2011 22:55:13 +0100 Subject: [PATCH 220/302] Added references to docstring in mediagoblin.webfinger and mediagoblin.webfinger.views [references mediagoblin.webfinger] --- mediagoblin/webfinger/__init__.py | 10 ++++++++++ mediagoblin/webfinger/views.py | 3 +++ 2 files changed, 13 insertions(+) diff --git a/mediagoblin/webfinger/__init__.py b/mediagoblin/webfinger/__init__.py index ba347c69..ec7ec884 100644 --- a/mediagoblin/webfinger/__init__.py +++ b/mediagoblin/webfinger/__init__.py @@ -13,3 +13,13 @@ # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +''' +mediagoblin.webfinger_ provides an LRDD discovery service and +a web host meta information file + +Links: +- `LRDD Discovery Draft + `_. +- `RFC 6415 - Web Host Metadata + `_. +''' diff --git a/mediagoblin/webfinger/views.py b/mediagoblin/webfinger/views.py index e9aa600c..22086396 100644 --- a/mediagoblin/webfinger/views.py +++ b/mediagoblin/webfinger/views.py @@ -13,6 +13,9 @@ # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +''' +For references, see docstring in mediagoblin/webfinger/__init__.py +''' import re From 871fc591dd2492d2bdca0a530fdffac14f3feece Mon Sep 17 00:00:00 2001 From: Elrond Date: Wed, 21 Dec 2011 00:06:38 +0100 Subject: [PATCH 221/302] Workaround for Routes/urlgen bug. This is relevant for fcgi: Some servers (cherokee for example) put "HTTP":"off" in the environ. And the following code in urlgen breaks on this: if environ.get('HTTPS') or environ.get('wsgi.url_scheme') == 'https' \ or environ.get('HTTP_X_FORWARDED_PROTO') == 'https': hostinfo['protocol'] = 'https' workaround is to remove HTTPS:off from the environ. --- mediagoblin/app.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mediagoblin/app.py b/mediagoblin/app.py index 04eb2acc..49dc8d97 100644 --- a/mediagoblin/app.py +++ b/mediagoblin/app.py @@ -122,6 +122,10 @@ class MediaGoblinApp(object): # The other option would be: # request.full_path = environ["SCRIPT_URL"] + # Fix up environ for urlgen + if environ.get('HTTPS', '').lower() == 'off': + environ.pop('HTTPS') + ## Attach utilities to the request object request.matchdict = route_match request.urlgen = routes.URLGenerator(self.routing, environ) From d23d4b23dad2e14e330664f58994dcbbbaa32720 Mon Sep 17 00:00:00 2001 From: Elrond Date: Wed, 21 Dec 2011 00:34:02 +0100 Subject: [PATCH 222/302] Note reported bug in workaround So that the workaround can eventually be removed, note the URL for the relevant bug in a comment. --- mediagoblin/app.py | 1 + 1 file changed, 1 insertion(+) diff --git a/mediagoblin/app.py b/mediagoblin/app.py index 49dc8d97..96b2c8ab 100644 --- a/mediagoblin/app.py +++ b/mediagoblin/app.py @@ -123,6 +123,7 @@ class MediaGoblinApp(object): # request.full_path = environ["SCRIPT_URL"] # Fix up environ for urlgen + # See bug: https://bitbucket.org/bbangert/routes/issue/55/cache_hostinfo-breaks-on-https-off if environ.get('HTTPS', '').lower() == 'off': environ.pop('HTTPS') From 6c191eb3de3bbaf3880ef270461422954554683a Mon Sep 17 00:00:00 2001 From: Karen Rustad Date: Sun, 18 Dec 2011 22:50:36 -0800 Subject: [PATCH 223/302] Added a 'you don't have HTML5 so this video will not work' warning using just the inherent properties of the
    From fb7dd855de987d4e3dded1e55cad09a9fe6120cc Mon Sep 17 00:00:00 2001 From: Elrond Date: Sun, 18 Dec 2011 22:52:49 +0100 Subject: [PATCH 225/302] Turn MediaComment's author() into get_author property 1) MediaComment's author method conflicts with the author field. So rename it to get_author. 2) Turn it from a normal function into a python property. That means you call it by ".get_author" not by ".get_author()". This is exactly what sqlalchemy gives us free of charge. --- mediagoblin/db/mongo/models.py | 3 ++- mediagoblin/templates/mediagoblin/user_pages/media.html | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/mediagoblin/db/mongo/models.py b/mediagoblin/db/mongo/models.py index e2ac1b5a..0e31fc1c 100644 --- a/mediagoblin/db/mongo/models.py +++ b/mediagoblin/db/mongo/models.py @@ -346,7 +346,8 @@ class MediaComment(Document): def media_entry(self): return self.db.MediaEntry.find_one({'_id': self['media_entry']}) - def author(self): + @property + def get_author(self): return self.db.User.find_one({'_id': self['author']}) diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html index b9e31667..c171dd5a 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media.html @@ -109,7 +109,7 @@ {% endif %} {% if comments %} {% for comment in comments %} - {% set comment_author = comment.author() %} + {% set comment_author = comment.get_author %} {% if pagination.active_id == comment._id %}
    From 2608982885477e2f41579240d24a26864f718123 Mon Sep 17 00:00:00 2001 From: Elrond Date: Sat, 24 Dec 2011 19:08:20 +0100 Subject: [PATCH 226/302] Add search level one() method And create a _fix_query_dict which converts '_id' to 'id'. --- mediagoblin/db/sql/base.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/mediagoblin/db/sql/base.py b/mediagoblin/db/sql/base.py index b8d5cc96..38b04334 100644 --- a/mediagoblin/db/sql/base.py +++ b/mediagoblin/db/sql/base.py @@ -4,13 +4,26 @@ from sqlalchemy.orm import scoped_session, sessionmaker Session = scoped_session(sessionmaker()) +def _fix_query_dict(query_dict): + if '_id' in query_dict: + query_dict['id'] = query_dict.pop('_id') + + class GMGTableBase(object): query = Session.query_property() @classmethod def find(cls, query_dict={}): + _fix_query_dict(query_dict) return cls.query.filter_by(**query_dict) @classmethod def find_one(cls, query_dict={}): + _fix_query_dict(query_dict) return cls.query.filter_by(**query_dict).first() + + @classmethod + def one(cls, query_dict): + retval = cls.find_one(query_dict) + assert retval is not None + return retval From 4305580e8538e5523e9f621c3ffbed14a2ddc350 Mon Sep 17 00:00:00 2001 From: Elrond Date: Sat, 24 Dec 2011 18:19:40 +0100 Subject: [PATCH 227/302] Improve .one() by using sqlalchemy's .one() --- mediagoblin/db/sql/base.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/mediagoblin/db/sql/base.py b/mediagoblin/db/sql/base.py index 38b04334..5e420bdc 100644 --- a/mediagoblin/db/sql/base.py +++ b/mediagoblin/db/sql/base.py @@ -24,6 +24,4 @@ class GMGTableBase(object): @classmethod def one(cls, query_dict): - retval = cls.find_one(query_dict) - assert retval is not None - return retval + return cls.find(query_dict).one() From 4deda94a380dc4217247b49df6e8a5bce0082ddc Mon Sep 17 00:00:00 2001 From: Elrond Date: Mon, 19 Dec 2011 22:29:40 +0100 Subject: [PATCH 228/302] Replace media.get_uploader()._id by media.uploader media.get_uploader()._id loads a complete user object without actually needing it, because media.uploader already has the id! --- mediagoblin/decorators.py | 6 +++--- mediagoblin/user_pages/views.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mediagoblin/decorators.py b/mediagoblin/decorators.py index 229664d7..4cf14a70 100644 --- a/mediagoblin/decorators.py +++ b/mediagoblin/decorators.py @@ -57,10 +57,10 @@ def user_may_delete_media(controller): Require user ownership of the MediaEntry to delete. """ def wrapper(request, *args, **kwargs): - uploader = request.db.MediaEntry.find_one( - {'_id': ObjectId(request.matchdict['media'])}).get_uploader() + uploader_id = request.db.MediaEntry.find_one( + {'_id': ObjectId(request.matchdict['media'])}).uploader if not (request.user.is_admin or - request.user._id == uploader._id): + request.user._id == uploader_id): return exc.HTTPForbidden() return controller(request, *args, **kwargs) diff --git a/mediagoblin/user_pages/views.py b/mediagoblin/user_pages/views.py index 87b82c74..449e3b1c 100644 --- a/mediagoblin/user_pages/views.py +++ b/mediagoblin/user_pages/views.py @@ -192,7 +192,7 @@ def media_confirm_delete(request, media): location=media.url_for_self(request.urlgen)) if ((request.user.is_admin and - request.user._id != media.get_uploader()._id)): + request.user._id != media.uploader)): messages.add_message( request, messages.WARNING, _("You are about to delete another user's media. " From 0c0ab3227430b3d55ce9d19b37a01cd2a3c90259 Mon Sep 17 00:00:00 2001 From: Elrond Date: Sun, 25 Dec 2011 19:58:37 +0100 Subject: [PATCH 229/302] Translate one string "There doesn't seem to be any media here yet..." is now translated also here (it's already in the list from another place). --- mediagoblin/templates/mediagoblin/utils/object_gallery.html | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/mediagoblin/templates/mediagoblin/utils/object_gallery.html b/mediagoblin/templates/mediagoblin/utils/object_gallery.html index 65ff09a4..b8155f03 100644 --- a/mediagoblin/templates/mediagoblin/utils/object_gallery.html +++ b/mediagoblin/templates/mediagoblin/utils/object_gallery.html @@ -68,7 +68,11 @@ {% endif %} {% else %}

    - There doesn't seem to be any media here yet... + + {%- trans -%} + There doesn't seem to be any media here yet... + {%- endtrans -%} +

    {% endif %} {% endmacro %} From 479e8a833ba502c976574af77181f60a2a660aec Mon Sep 17 00:00:00 2001 From: Elrond Date: Sun, 25 Dec 2011 20:11:09 +0100 Subject: [PATCH 230/302] Move verification key generation to view Instead of creating the email verication key on the db model as a default for the field, create it in the registration view. Now all verification key generation is only in auth/views.py! --- mediagoblin/auth/views.py | 1 + mediagoblin/db/mongo/models.py | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/mediagoblin/auth/views.py b/mediagoblin/auth/views.py index 919aa3cd..66178371 100644 --- a/mediagoblin/auth/views.py +++ b/mediagoblin/auth/views.py @@ -84,6 +84,7 @@ def register(request): user.email = email user.pw_hash = auth_lib.bcrypt_gen_password_hash( request.POST['password']) + user.verification_key = unicode(uuid.uuid4()) user.save(validate=True) # log the user in diff --git a/mediagoblin/db/mongo/models.py b/mediagoblin/db/mongo/models.py index 0e31fc1c..b068fb06 100644 --- a/mediagoblin/db/mongo/models.py +++ b/mediagoblin/db/mongo/models.py @@ -15,7 +15,6 @@ # along with this program. If not, see . import datetime -import uuid from mongokit import Document @@ -88,7 +87,6 @@ class User(Document): 'created': datetime.datetime.utcnow, 'email_verified': False, 'status': u'needs_email_verification', - 'verification_key': lambda: unicode(uuid.uuid4()), 'is_admin': False} def check_login(self, password): From 0eb649ff7ac3f1eb71eb1d2cb66019a860b2c5c7 Mon Sep 17 00:00:00 2001 From: Elrond Date: Tue, 20 Dec 2011 18:47:33 +0100 Subject: [PATCH 231/302] Use media.url_for_self instead of calling urlgen directly Replace urlgen('ID', user=media.get_uploader().username, media=media.*) by media.url_for_self(urlgen) in a few places. It's just a lot nicer! --- mediagoblin/db/mongo/models.py | 12 ++++-------- .../templates/mediagoblin/user_pages/media.html | 6 ++---- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/mediagoblin/db/mongo/models.py b/mediagoblin/db/mongo/models.py index b068fb06..8cd0da1b 100644 --- a/mediagoblin/db/mongo/models.py +++ b/mediagoblin/db/mongo/models.py @@ -282,10 +282,8 @@ class MediaEntry(Document): 'uploader': self.uploader, 'state': 'processed'}).sort( '_id', ASCENDING).limit(1) - if cursor.count(): - return urlgen('mediagoblin.user_pages.media_home', - user=self.get_uploader().username, - media=unicode(cursor[0].slug)) + for media in cursor: + return media.url_for_self(urlgen) def url_to_next(self, urlgen): """ @@ -296,10 +294,8 @@ class MediaEntry(Document): 'state': 'processed'}).sort( '_id', DESCENDING).limit(1) - if cursor.count(): - return urlgen('mediagoblin.user_pages.media_home', - user=self.get_uploader().username, - media=unicode(cursor[0].slug)) + for media in cursor: + return media.url_for_self(urlgen) def get_uploader(self): return self.db.User.find_one({'_id': self.uploader}) diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html index c171dd5a..77461983 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media.html @@ -135,10 +135,8 @@
    {% endfor %} - {{ render_pagination(request, pagination, - request.urlgen('mediagoblin.user_pages.media_home', - user = media.get_uploader().username, - media = media._id)) }} + {{ render_pagination(request, pagination, + media.url_for_self(request.urlgen)) }} {% endif %}
    From 05751758469a03835975dd2998aa727fa29c9a16 Mon Sep 17 00:00:00 2001 From: Elrond Date: Sat, 24 Dec 2011 00:08:28 +0100 Subject: [PATCH 232/302] Turn media.get_uploader into a property sqlalchemy gives autoloading (hopefully caching) link to other objects as properties. So turn get_uploader on the current mongo based stuff into a property to ease transition. --- mediagoblin/db/mongo/models.py | 3 ++- mediagoblin/listings/views.py | 2 +- .../templates/mediagoblin/edit/attachments.html | 2 +- mediagoblin/templates/mediagoblin/edit/edit.html | 2 +- .../templates/mediagoblin/user_pages/media.html | 14 +++++++------- .../user_pages/media_confirm_delete.html | 2 +- mediagoblin/user_pages/views.py | 2 +- 7 files changed, 14 insertions(+), 13 deletions(-) diff --git a/mediagoblin/db/mongo/models.py b/mediagoblin/db/mongo/models.py index 8cd0da1b..5de59c12 100644 --- a/mediagoblin/db/mongo/models.py +++ b/mediagoblin/db/mongo/models.py @@ -261,7 +261,7 @@ class MediaEntry(Document): Use a slug if we have one, else use our '_id'. """ - uploader = self.get_uploader() + uploader = self.get_uploader if self.get('slug'): return urlgen( @@ -297,6 +297,7 @@ class MediaEntry(Document): for media in cursor: return media.url_for_self(urlgen) + @property def get_uploader(self): return self.db.User.find_one({'_id': self.uploader}) diff --git a/mediagoblin/listings/views.py b/mediagoblin/listings/views.py index 6b83ffcf..3ecf06f4 100644 --- a/mediagoblin/listings/views.py +++ b/mediagoblin/listings/views.py @@ -86,7 +86,7 @@ def tag_atom_feed(request): feed.add(entry.get('title'), entry.get('description_html'), content_type='html', - author=entry.get_uploader().username, + author=entry.get_uploader.username, updated=entry.get('created'), url=entry.url_for_self(request.urlgen)) diff --git a/mediagoblin/templates/mediagoblin/edit/attachments.html b/mediagoblin/templates/mediagoblin/edit/attachments.html index 6a5ab896..124d0313 100644 --- a/mediagoblin/templates/mediagoblin/edit/attachments.html +++ b/mediagoblin/templates/mediagoblin/edit/attachments.html @@ -20,7 +20,7 @@ {% import "/mediagoblin/utils/wtforms.html" as wtforms_util %} {% block mediagoblin_content %}
    diff --git a/mediagoblin/templates/mediagoblin/edit/edit.html b/mediagoblin/templates/mediagoblin/edit/edit.html index aa46af3d..2dfaddc8 100644 --- a/mediagoblin/templates/mediagoblin/edit/edit.html +++ b/mediagoblin/templates/mediagoblin/edit/edit.html @@ -22,7 +22,7 @@ {% block mediagoblin_content %}
    diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html index 77461983..13fa1baa 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media.html @@ -72,11 +72,11 @@ {% if media['uploader'] == request.user._id or request.user['is_admin'] %} {% set edit_url = request.urlgen('mediagoblin.edit.edit_media', - user= media.get_uploader().username, + user= media.get_uploader.username, media= media._id) %} {% trans %}Edit{% endtrans %} {% set delete_url = request.urlgen('mediagoblin.user_pages.media_confirm_delete', - user= media.get_uploader().username, + user= media.get_uploader.username, media= media._id) %} {% trans %}Delete{% endtrans %} {% endif %} @@ -95,7 +95,7 @@ {# 0 comments. Be the first to add one! #} {% if request.user %}

    {% trans %}Type your comment here. You can use Markdown for formatting.{% endtrans %} @@ -128,7 +128,7 @@ {% trans %}at{% endtrans %} {{ comment.created.strftime("%I:%M%p %Y-%m-%d") }} @@ -142,8 +142,8 @@

    {% trans user_url=request.urlgen( 'mediagoblin.user_pages.user_home', - user=media.get_uploader().username), - username=media.get_uploader().username -%} + user=media.get_uploader.username), + username=media.get_uploader.username -%}

    ❖ Browsing media by {{ username }}

    {%- endtrans %} {% include "mediagoblin/utils/prev_next.html" %} @@ -164,7 +164,7 @@ or request.user.is_admin) %}

    Add attachment

    {% endif %} diff --git a/mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html b/mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html index 7c7218ae..6c483769 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html @@ -22,7 +22,7 @@ {% block mediagoblin_content %}
    diff --git a/mediagoblin/user_pages/views.py b/mediagoblin/user_pages/views.py index 449e3b1c..f721f012 100644 --- a/mediagoblin/user_pages/views.py +++ b/mediagoblin/user_pages/views.py @@ -173,7 +173,7 @@ def media_confirm_delete(request, media): if request.method == 'POST' and form.validate(): if form.confirm.data is True: - username = media.get_uploader().username + username = media.get_uploader.username # Delete all files on the public storage delete_media_files(media) From 19ed039ba6d65cecfd6e8ad6e47b5cb008350b04 Mon Sep 17 00:00:00 2001 From: Elrond Date: Sun, 25 Dec 2011 20:03:11 +0100 Subject: [PATCH 233/302] Implement _id proxy on sql objects (on User for now) So that the old code can access the primary key still as "._id". Quite simple Python Descriptor thing. Very generic. --- mediagoblin/db/sql/models.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/mediagoblin/db/sql/models.py b/mediagoblin/db/sql/models.py index b87ff3aa..68b078a5 100644 --- a/mediagoblin/db/sql/models.py +++ b/mediagoblin/db/sql/models.py @@ -11,6 +11,18 @@ from mediagoblin.db.sql.base import GMGTableBase Base = declarative_base(cls=GMGTableBase) +class SimpleFieldAlias(object): + """An alias for any field""" + def __init__(self, fieldname): + self.fieldname = fieldname + + def __get__(self, instance, cls): + return getattr(instance, self.fieldname) + + def __set__(self, instance, val): + setattr(instance, self.fieldname, val) + + class User(Base): __tablename__ = "users" @@ -32,6 +44,8 @@ class User(Base): ## TODO # plugin data would be in a separate model + _id = SimpleFieldAlias("id") + class MediaEntry(Base): __tablename__ = "media_entries" From c6263400cfd334a820122bd1b22eaa4d4d6765cd Mon Sep 17 00:00:00 2001 From: Elrond Date: Sat, 24 Dec 2011 18:12:38 +0100 Subject: [PATCH 234/302] SQL Model: Forgot MediaEntry.state field While creating the new SQL model, the "state" field of MediaEntry was left out. Currently using a plain unicode string for it. Maybe should use sqlalchemy.types.Enum? --- mediagoblin/db/sql/convert.py | 2 +- mediagoblin/db/sql/models.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/mediagoblin/db/sql/convert.py b/mediagoblin/db/sql/convert.py index 6de758ed..c6bed1e9 100644 --- a/mediagoblin/db/sql/convert.py +++ b/mediagoblin/db/sql/convert.py @@ -62,7 +62,7 @@ def convert_media_entries(mk_db): copy_attrs(entry, new_entry, ('title', 'slug', 'created', 'description', 'description_html', - 'media_type', + 'media_type', 'state', 'fail_error', 'queued_task_id',)) copy_reference_attr(entry, new_entry, "uploader") diff --git a/mediagoblin/db/sql/models.py b/mediagoblin/db/sql/models.py index 68b078a5..268f5715 100644 --- a/mediagoblin/db/sql/models.py +++ b/mediagoblin/db/sql/models.py @@ -58,6 +58,7 @@ class MediaEntry(Base): description = Column(UnicodeText) # ?? description_html = Column(UnicodeText) # ?? media_type = Column(Unicode, nullable=False) + state = Column(Unicode, nullable=False) # or use sqlalchemy.types.Enum? fail_error = Column(Unicode) fail_metadata = Column(UnicodeText) From 88e90f41eb86b8aa1fcfef1e0585f314afb5180d Mon Sep 17 00:00:00 2001 From: Elrond Date: Sat, 24 Dec 2011 16:00:05 +0100 Subject: [PATCH 235/302] SQL Model: Add relationship properties MediaEntry now has a get_uploader (property) loading the appropiate User object for the MediaEntry (and caches it). MediaComment has the same for author as get_author. --- mediagoblin/db/sql/models.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mediagoblin/db/sql/models.py b/mediagoblin/db/sql/models.py index 268f5715..31a6ed3b 100644 --- a/mediagoblin/db/sql/models.py +++ b/mediagoblin/db/sql/models.py @@ -4,6 +4,7 @@ from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import ( Column, Integer, Unicode, UnicodeText, DateTime, Boolean, ForeignKey, UniqueConstraint) +from sqlalchemy.orm import relationship from mediagoblin.db.sql.base import GMGTableBase @@ -71,6 +72,8 @@ class MediaEntry(Base): UniqueConstraint('uploader', 'slug'), {}) + get_uploader = relationship(User) + ## TODO # media_files # media_data @@ -112,6 +115,8 @@ class MediaComment(Base): content = Column(UnicodeText, nullable=False) content_html = Column(UnicodeText) + get_author = relationship(User) + def show_table_init(): from sqlalchemy import create_engine From 0724930a6880ea9a088785480cfa7803d43a6370 Mon Sep 17 00:00:00 2001 From: Elrond Date: Wed, 28 Dec 2011 23:27:46 +0100 Subject: [PATCH 236/302] Show --log-file option in lazyserver help. --- lazyserver.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lazyserver.sh b/lazyserver.sh index 4ca073b5..843993e6 100755 --- a/lazyserver.sh +++ b/lazyserver.sh @@ -26,7 +26,7 @@ then echo "" echo " For example:" echo " $0 -c fcgi.ini port_number=23371" - echo " or: $0 --server-name=fcgi" + echo " or: $0 --server-name=fcgi --log-file=paste.log" echo "" echo " The configfile defaults to paste_local.ini," echo " if that is readable, otherwise paste.ini." From 690672580e333bb6a2dc67466390847a79566045 Mon Sep 17 00:00:00 2001 From: Elrond Date: Wed, 28 Dec 2011 23:46:36 +0100 Subject: [PATCH 237/302] Fix "bin/gmg migrate" after mongo move When moving most stuff from db to db/mongo, "gmg migrate" was left out. Fix it now! --- mediagoblin/gmg_commands/migrate.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mediagoblin/gmg_commands/migrate.py b/mediagoblin/gmg_commands/migrate.py index bd3bcb20..0a8ee7dc 100644 --- a/mediagoblin/gmg_commands/migrate.py +++ b/mediagoblin/gmg_commands/migrate.py @@ -16,12 +16,12 @@ import sys -from mediagoblin.db import util as db_util +from mediagoblin.db.mongo import util as db_util from mediagoblin.db.open import setup_connection_and_db_from_config from mediagoblin.init import setup_global_and_app_config # This MUST be imported so as to set up the appropriate migrations! -from mediagoblin.db import migrations +from mediagoblin.db.mongo import migrations def migrate_parser_setup(subparser): From 03c22862322f42a68351e70956e24e512028f0b2 Mon Sep 17 00:00:00 2001 From: Elrond Date: Sun, 25 Dec 2011 16:01:25 +0100 Subject: [PATCH 238/302] Support .get(fieldname) on sql db objects Some parts of the code like to call .get("somefield") on the db objects. It's easy to support this on sqlalchemy based objects, so lets do it. --- mediagoblin/db/sql/base.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mediagoblin/db/sql/base.py b/mediagoblin/db/sql/base.py index 5e420bdc..1249bace 100644 --- a/mediagoblin/db/sql/base.py +++ b/mediagoblin/db/sql/base.py @@ -25,3 +25,6 @@ class GMGTableBase(object): @classmethod def one(cls, query_dict): return cls.find(query_dict).one() + + def get(self, key): + return getattr(self, key) From 9f264942d88c563f9d310c3fea4a554731c1bbbc Mon Sep 17 00:00:00 2001 From: Elrond Date: Sun, 25 Dec 2011 19:09:23 +0100 Subject: [PATCH 239/302] Add a .save method on the sql db objects This is a shortcut to adding the object to a session (if needed) and giving a commit on the session. In reality, calling code should probably utilize the session on its own and call commit in an appropiate place. --- mediagoblin/db/sql/base.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/mediagoblin/db/sql/base.py b/mediagoblin/db/sql/base.py index 1249bace..40140327 100644 --- a/mediagoblin/db/sql/base.py +++ b/mediagoblin/db/sql/base.py @@ -1,4 +1,4 @@ -from sqlalchemy.orm import scoped_session, sessionmaker +from sqlalchemy.orm import scoped_session, sessionmaker, object_session Session = scoped_session(sessionmaker()) @@ -28,3 +28,11 @@ class GMGTableBase(object): def get(self, key): return getattr(self, key) + + def save(self, validate = True): + assert validate + sess = object_session(self) + if sess is None: + sess = Session() + sess.add(self) + sess.commit() From dab1d70280652049078add60c6c44f675fbe267c Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Thu, 29 Dec 2011 22:40:45 +0100 Subject: [PATCH 240/302] Finished #485 and worked out bugs: password fields always update, added margins, fixed Chrome width bug, wrapped checkbox in label element --- mediagoblin/static/css/base.css | 5 +++++ mediagoblin/templates/mediagoblin/auth/register.html | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css index 625269a2..ecdd0474 100644 --- a/mediagoblin/static/css/base.css +++ b/mediagoblin/static/css/base.css @@ -251,6 +251,11 @@ textarea#comment_content { text-align: right; } +#password_boolean { + margin-top: 4px; + width: 20px; +} + /* comments */ .comment_author { diff --git a/mediagoblin/templates/mediagoblin/auth/register.html b/mediagoblin/templates/mediagoblin/auth/register.html index bded1d7e..73eae0d8 100644 --- a/mediagoblin/templates/mediagoblin/auth/register.html +++ b/mediagoblin/templates/mediagoblin/auth/register.html @@ -22,7 +22,7 @@ {% block mediagoblin_head %} {% endblock mediagoblin_head %} From 4e9d467fc0b3dfc55db15e84d5d988cefa400fa1 Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Thu, 29 Dec 2011 22:54:31 +0100 Subject: [PATCH 241/302] Isolate JavaScript; add new show_password.js to forgot-password-page as well --- mediagoblin/auth/forms.py | 8 +------ .../templates/mediagoblin/auth/change_fp.html | 5 ++++ .../templates/mediagoblin/auth/register.html | 23 ++----------------- 3 files changed, 8 insertions(+), 28 deletions(-) diff --git a/mediagoblin/auth/forms.py b/mediagoblin/auth/forms.py index 4cd3e9d8..5a707c7b 100644 --- a/mediagoblin/auth/forms.py +++ b/mediagoblin/auth/forms.py @@ -62,13 +62,7 @@ class ChangePassForm(wtforms.Form): password = wtforms.PasswordField( 'Password', [wtforms.validators.Required(), - wtforms.validators.Length(min=6, max=30), - wtforms.validators.EqualTo( - 'confirm_password', - 'Passwords must match.')]) - confirm_password = wtforms.PasswordField( - 'Confirm password', - [wtforms.validators.Required()]) + wtforms.validators.Length(min=6, max=30)]) userid = wtforms.HiddenField( '', [wtforms.validators.Required()]) diff --git a/mediagoblin/templates/mediagoblin/auth/change_fp.html b/mediagoblin/templates/mediagoblin/auth/change_fp.html index 03a6583b..e8e64023 100644 --- a/mediagoblin/templates/mediagoblin/auth/change_fp.html +++ b/mediagoblin/templates/mediagoblin/auth/change_fp.html @@ -19,6 +19,11 @@ {% import "/mediagoblin/utils/wtforms.html" as wtforms_util %} +{% block mediagoblin_head %} + +{% endblock mediagoblin_head %} + {% block mediagoblin_content %} - $(document).ready(function(){ - $("#password").after(''); - $('#password_clear').hide(); - $('#password_boolean').click(function(){ - if($('#password_boolean').prop("checked")) { - $('#password_clear').val($('#password').val()); - $('#password').hide(); - $('#password_clear').show(); - } else { - $('#password').val($('#password_clear').val()); - $('#password_clear').hide(); - $('#password').show(); - }; - }); - $('#password,#password_clear').keyup(function(){ - $('#password').val($(this).val()); - $('#password_clear').val($(this).val()); - }); - }); - + {% endblock mediagoblin_head %} {% block mediagoblin_content %} From 550d48d04059d94894573d93aed98f4faa63e3fb Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Thu, 29 Dec 2011 22:56:42 +0100 Subject: [PATCH 242/302] Forgot to include the newly created JS file --- mediagoblin/static/js/show_password.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 mediagoblin/static/js/show_password.js diff --git a/mediagoblin/static/js/show_password.js b/mediagoblin/static/js/show_password.js new file mode 100644 index 00000000..519b29c1 --- /dev/null +++ b/mediagoblin/static/js/show_password.js @@ -0,0 +1,19 @@ +$(document).ready(function(){ + $("#password").after(''); + $('#password_clear').hide(); + $('#password_boolean').click(function(){ + if($('#password_boolean').prop("checked")) { + $('#password_clear').val($('#password').val()); + $('#password').hide(); + $('#password_clear').show(); + } else { + $('#password').val($('#password_clear').val()); + $('#password_clear').hide(); + $('#password').show(); + }; + }); + $('#password,#password_clear').keyup(function(){ + $('#password').val($(this).val()); + $('#password_clear').val($(this).val()); + }); +}); From 3ea6a305ce2addc8c2d6322f0d9bdca957bd972c Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Fri, 30 Dec 2011 14:23:12 +0100 Subject: [PATCH 243/302] Lots of little fixes and removal of all 960.gs classes: * Removed

    margin-top * Vertically align logo so Add-media button does not fall off * Remove last 960.gs traces (grid_X/container_X) and add custom classes/sizes to css * Add clear class * Update form_box and add form_box_xl for bigger forms * Switch all pages that use forms to new classes * Remove padding from notification messages so they take full width * Other tiny fixes I forgot about --- mediagoblin/static/css/base.css | 60 +++++++++++++++---- mediagoblin/templates/mediagoblin/404.html | 19 +++--- .../templates/mediagoblin/auth/change_fp.html | 6 +- .../mediagoblin/auth/forgot_password.html | 2 +- .../templates/mediagoblin/auth/login.html | 2 +- .../templates/mediagoblin/auth/register.html | 2 +- .../mediagoblin/edit/attachments.html | 2 +- .../templates/mediagoblin/edit/edit.html | 2 +- .../mediagoblin/edit/edit_profile.html | 2 +- .../templates/mediagoblin/listings/tag.html | 13 ++-- mediagoblin/templates/mediagoblin/root.html | 28 ++++----- .../templates/mediagoblin/submit/start.html | 2 +- .../mediagoblin/user_pages/gallery.html | 16 ++--- .../user_pages/media_confirm_delete.html | 2 +- .../mediagoblin/user_pages/user.html | 16 ++--- .../mediagoblin/utils/prev_next.html | 46 +++++++------- 16 files changed, 115 insertions(+), 105 deletions(-) diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css index 187d1c7a..e8924edf 100644 --- a/mediagoblin/static/css/base.css +++ b/mediagoblin/static/css/base.css @@ -44,24 +44,28 @@ form { /* text styles */ -h1{ +h1 { margin-bottom: 15px; margin-top: 15px; color: #fff; font-size: 1.875em; } -h2{ +h2 { font-size: 1.375em; margin-top: 20px; color: #fff; } -h3{ +h3 { border-bottom: 1px solid #333; font-size: 1.125em; } +p { + margin-top: 0px; +} + a { color: #86D4B1; } @@ -103,12 +107,16 @@ input, textarea { float: right; } -a.mediagoblin_logo{ +a.mediagoblin_logo { color: #fff; font-weight: bold; margin-right: 8px; } +.mediagoblin_logo img { + vertical-align: middle; +} + .mediagoblin_content { width: 940px; margin-left: 10px; @@ -143,6 +151,18 @@ a.mediagoblin_logo{ float: left; } +.profile_sidebar { + width: 340px; + margin-right: 10px; + float: left; +} + +.profile_showcase { + width: 580px; + margin-left: 10px; + float: left; +} + /* common website elements */ .button_action, .button_action_highlight { @@ -219,28 +239,33 @@ text-align: center; float: right; } -textarea#comment_content { - width: 634px; - height: 90px; - border: none; - background-color: #f1f1f1; - padding: 3px; +.clear { + clear: both; + display: block; + overflow: hidden; + visibility: hidden; + width: 0; + height: 0; } /* forms */ -.form_box { +.form_box,.form_box_xl { background-color: #222; background-image: url("../images/background_lines.png"); background-repeat: repeat-x; - padding-bottom: 30px; - padding-top: 30px; + width: 340px; + padding: 30px 60px; margin-left: auto; margin-right: auto; display: block; float: none; } +.form_box_xl { + width: 460px; +} + .edit_box { background-image: url("../images/background_edit.png"); } @@ -294,6 +319,14 @@ textarea#comment_content { margin-bottom: 0px; } +textarea#comment_content { + width: 634px; + height: 90px; + border: none; + background-color: #f1f1f1; + padding: 3px; +} + /* media galleries */ .media_thumbnail { @@ -358,6 +391,7 @@ img.media_icon { ul.mediagoblin_messages { list-style: none inside; color: #f7f7f7; + padding: 0; } .mediagoblin_messages li { diff --git a/mediagoblin/templates/mediagoblin/404.html b/mediagoblin/templates/mediagoblin/404.html index 7db68941..392c14f5 100644 --- a/mediagoblin/templates/mediagoblin/404.html +++ b/mediagoblin/templates/mediagoblin/404.html @@ -18,17 +18,12 @@ {% extends "mediagoblin/base.html" %} {% block mediagoblin_content %} + {% trans %}Image of 404 goblin stressing out{% endtrans %}

    {% trans %}Oops!{% endtrans %}

    - -
    -

    {% trans %}There doesn't seem to be a page at this address. Sorry!{% endtrans %}

    -

    - {%- trans %}If you're sure the address is correct, maybe the page you're looking for has been moved or deleted.{% endtrans -%} -

    -
    - -
    - {% trans %}Image of 404 goblin stressing out{% endtrans %} -
    +

    {% trans %}There doesn't seem to be a page at this address. Sorry!{% endtrans %}

    +

    + {%- trans %}If you're sure the address is correct, maybe the page you're looking for has been moved or deleted.{% endtrans -%} +

    +
    {% endblock %} diff --git a/mediagoblin/templates/mediagoblin/auth/change_fp.html b/mediagoblin/templates/mediagoblin/auth/change_fp.html index 03a6583b..9c8c79bf 100644 --- a/mediagoblin/templates/mediagoblin/auth/change_fp.html +++ b/mediagoblin/templates/mediagoblin/auth/change_fp.html @@ -20,19 +20,15 @@ {% import "/mediagoblin/utils/wtforms.html" as wtforms_util %} {% block mediagoblin_content %} - {{ csrf_token }} - -
    +

    {% trans %}Set your new password{% endtrans %}

    - {{ wtforms_util.render_divs(cp_form) }}
    -
    {% endblock %} diff --git a/mediagoblin/templates/mediagoblin/auth/forgot_password.html b/mediagoblin/templates/mediagoblin/auth/forgot_password.html index 41940742..672e9d9a 100644 --- a/mediagoblin/templates/mediagoblin/auth/forgot_password.html +++ b/mediagoblin/templates/mediagoblin/auth/forgot_password.html @@ -23,7 +23,7 @@
    {{ csrf_token }} -
    +

    {% trans %}Recover password{% endtrans %}

    {{ wtforms_util.render_divs(fp_form) }}
    diff --git a/mediagoblin/templates/mediagoblin/auth/login.html b/mediagoblin/templates/mediagoblin/auth/login.html index c3807e5f..993790eb 100644 --- a/mediagoblin/templates/mediagoblin/auth/login.html +++ b/mediagoblin/templates/mediagoblin/auth/login.html @@ -23,7 +23,7 @@ {{ csrf_token }} -
    +

    {% trans %}Log in{% endtrans %}

    {% if login_failed %}
    diff --git a/mediagoblin/templates/mediagoblin/auth/register.html b/mediagoblin/templates/mediagoblin/auth/register.html index bded1d7e..2520ca9b 100644 --- a/mediagoblin/templates/mediagoblin/auth/register.html +++ b/mediagoblin/templates/mediagoblin/auth/register.html @@ -43,7 +43,7 @@ -
    +

    {% trans %}Create an account!{% endtrans %}

    {{ wtforms_util.render_divs(register_form) }} {{ csrf_token }} diff --git a/mediagoblin/templates/mediagoblin/edit/attachments.html b/mediagoblin/templates/mediagoblin/edit/attachments.html index 6a5ab896..ff357a8c 100644 --- a/mediagoblin/templates/mediagoblin/edit/attachments.html +++ b/mediagoblin/templates/mediagoblin/edit/attachments.html @@ -23,7 +23,7 @@ user= media.get_uploader().username, media= media._id) }}" method="POST" enctype="multipart/form-data"> -
    +

    Editing attachments for {{ media.title }}

    -
    +

    {% trans media_title=media.title %}Editing {{ media_title }}{% endtrans %}

    -
    +

    {%- trans username=user.username -%} Editing {{ username }}'s profile diff --git a/mediagoblin/templates/mediagoblin/listings/tag.html b/mediagoblin/templates/mediagoblin/listings/tag.html index f797f72f..a7cbe241 100644 --- a/mediagoblin/templates/mediagoblin/listings/tag.html +++ b/mediagoblin/templates/mediagoblin/listings/tag.html @@ -35,14 +35,9 @@ {% trans %}Media tagged with: {{ tag_name }}{% endtrans %}

    - + {{ object_gallery(request, media_entries, pagination) }} -
    - {% set feed_url = request.urlgen( - 'mediagoblin.listings.tag_atom_feed', - tag=tag_slug) %} - {% include "mediagoblin/utils/feed_link.html" %} -
    + {% set feed_url = request.urlgen('mediagoblin.listings.tag_atom_feed', + tag=tag_slug) %} + {% include "mediagoblin/utils/feed_link.html" %} {% endblock %} diff --git a/mediagoblin/templates/mediagoblin/root.html b/mediagoblin/templates/mediagoblin/root.html index 0f769f2f..300570ad 100644 --- a/mediagoblin/templates/mediagoblin/root.html +++ b/mediagoblin/templates/mediagoblin/root.html @@ -23,22 +23,18 @@ {% if request.user %}

    {% trans %}Explore{% endtrans %}

    {% else %} -
    -

    {% trans %}Hi there, welcome to this MediaGoblin site!{% endtrans %}

    -

    {% trans %}This site is running MediaGoblin, an extraordinarily great piece of media hosting software.{% endtrans %}

    -

    {% trans %}To add your own media, place comments, save your favourites and more, you can log in with your MediaGoblin account.{% endtrans %}

    - {% if allow_registration %} -

    {% trans %}Don't have one yet? It's easy!{% endtrans %}

    - {% trans register_url=request.urlgen('mediagoblin.auth.register') -%} - Create an account at this site - or - Set up MediaGoblin on your own server - {%- endtrans %} - {% endif %} -
    -
    - -
    + +

    {% trans %}Hi there, welcome to this MediaGoblin site!{% endtrans %}

    +

    {% trans %}This site is running MediaGoblin, an extraordinarily great piece of media hosting software.{% endtrans %}

    +

    {% trans %}To add your own media, place comments, save your favourites and more, you can log in with your MediaGoblin account.{% endtrans %}

    + {% if allow_registration %} +

    {% trans %}Don't have one yet? It's easy!{% endtrans %}

    + {% trans register_url=request.urlgen('mediagoblin.auth.register') -%} + Create an account at this site + or + Set up MediaGoblin on your own server + {%- endtrans %} + {% endif %}
    {% endif %}

    {% trans %}Most recent media{% endtrans %}

    diff --git a/mediagoblin/templates/mediagoblin/submit/start.html b/mediagoblin/templates/mediagoblin/submit/start.html index 47914550..afae2f1f 100644 --- a/mediagoblin/templates/mediagoblin/submit/start.html +++ b/mediagoblin/templates/mediagoblin/submit/start.html @@ -22,7 +22,7 @@ {% block mediagoblin_content %} -
    +

    {% trans %}Add your media{% endtrans %}

    {{ wtforms_util.render_divs(submit_form) }}
    diff --git a/mediagoblin/templates/mediagoblin/user_pages/gallery.html b/mediagoblin/templates/mediagoblin/user_pages/gallery.html index b066dd71..b0bfacf8 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/gallery.html +++ b/mediagoblin/templates/mediagoblin/user_pages/gallery.html @@ -42,14 +42,10 @@ {%- endtrans %}

    - - -
    - {% set feed_url = request.urlgen( - 'mediagoblin.user_pages.atom_feed', - user=user.username) %} - {% include "mediagoblin/utils/feed_link.html" %} -
    + {{ object_gallery(request, media_entries, pagination) }} + + {% set feed_url = request.urlgen('mediagoblin.user_pages.atom_feed', + user=user.username) %} + {% include "mediagoblin/utils/feed_link.html" %} + {% endblock %} diff --git a/mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html b/mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html index 7c7218ae..8e0f2904 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html @@ -25,7 +25,7 @@ user=media.get_uploader().username, media=media._id) }}" method="POST" enctype="multipart/form-data"> -
    +

    {%- trans title=media.title -%} Really delete {{ title }}? diff --git a/mediagoblin/templates/mediagoblin/user_pages/user.html b/mediagoblin/templates/mediagoblin/user_pages/user.html index b952e88c..8a1d3a76 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/user.html +++ b/mediagoblin/templates/mediagoblin/user_pages/user.html @@ -46,7 +46,7 @@ {% elif user.status == "needs_email_verification" %} {% if user == request.user %} {# this should only be visible when you are this user #} -
    +

    {% trans %}Email verification needed{% endtrans %}

    @@ -66,7 +66,7 @@

    {% else %} {# if the user is not you, but still needs to verify their email #} -
    +

    {% trans %}Email verification needed{% endtrans %}

    @@ -91,7 +91,7 @@ {% if not user.url and not user.bio %} {% if request.user._id == user._id %} -

    +

    {% trans %}Here's a spot to tell others about yourself.{% endtrans %}

    @@ -102,7 +102,7 @@
    {% else %} -
    +

    {% trans -%} This user hasn't filled in their profile (yet). @@ -111,7 +111,7 @@

    {% endif %} {% else %} -
    +
    {% include "mediagoblin/utils/profile.html" %} {% if request.user._id == user._id or request.user.is_admin %} +
    {{ object_gallery(request, media_entries, pagination, pagination_base_url=user_gallery_url, col_number=3) }} {% include "mediagoblin/utils/object_gallery.html" %} @@ -141,7 +141,7 @@
    {% else %} {% if request.user._id == user._id %} -
    + {% else %} -
    +

    {% trans -%} There doesn't seem to be any media here yet... diff --git a/mediagoblin/templates/mediagoblin/utils/prev_next.html b/mediagoblin/templates/mediagoblin/utils/prev_next.html index b0c01963..66766555 100644 --- a/mediagoblin/templates/mediagoblin/utils/prev_next.html +++ b/mediagoblin/templates/mediagoblin/utils/prev_next.html @@ -21,28 +21,26 @@ {% set next_entry_url = media.url_to_next(request.urlgen) %} {% if prev_entry_url or next_entry_url %} -

    - {# There are no previous entries for the very first media entry #} - {% if prev_entry_url %} - - ← {% trans %}newer{% endtrans %} - - {% else %} - {# This is the first entry. display greyed-out 'previous' image #} - - {% endif %} - {# Likewise, this could be the very last media entry #} - {% if next_entry_url %} - - {% trans %}older{% endtrans %} → - - {% else %} - {# This is the last entry. display greyed-out 'next' image #} - - {% endif %} -
    + {# There are no previous entries for the very first media entry #} + {% if prev_entry_url %} + + ← {% trans %}newer{% endtrans %} + + {% else %} + {# This is the first entry. display greyed-out 'previous' image #} + + {% endif %} + {# Likewise, this could be the very last media entry #} + {% if next_entry_url %} + + {% trans %}older{% endtrans %} → + + {% else %} + {# This is the last entry. display greyed-out 'next' image #} + + {% endif %} {% endif %} From 426808cc8fe4961e938bc8f6df10ea755980e6c1 Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Fri, 30 Dec 2011 18:01:28 +0100 Subject: [PATCH 244/302] Random changes that break stuff and eat piglets --- mediagoblin/static/css/base.css | 41 +++++++++++++++------------------ 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css index e8924edf..8ed94e36 100644 --- a/mediagoblin/static/css/base.css +++ b/mediagoblin/static/css/base.css @@ -29,7 +29,6 @@ body { background-color: #111; background-image: url("../images/background.png"); color: #C3C3C3; - font-family: sans-serif; padding: none; margin: 0px; height: 100%; @@ -94,7 +93,7 @@ input, textarea { } .mediagoblin_header { - width: 940px; + width: 100%; height: 36px; margin-left: 10px; margin-right: 10px; @@ -118,14 +117,14 @@ a.mediagoblin_logo { } .mediagoblin_content { - width: 940px; + width: 100%; margin-left: 10px; margin-right: 10px; padding-bottom: 74px; } .mediagoblin_footer { - width: 940px; + width: 100%; height: 30px; margin-left: 10px; margin-right: 10px; @@ -451,10 +450,22 @@ table.media_panel th { margin-left: 10px; } -@media handheld and (max-width: 480px), screen and (max-device-width: 480px), screen and (max-width: 960px) { - html { - padding:10px; +@media screen and (max-width: 960px) { + .mediagoblin_body { + width: 100%; } + .mediagoblin_footer { + position: fixed; + left: 0px; + top: 100px; + width: 50px; + height: 20px; + background-color: #f00; + } +} + + + /* old code .navigation_button { position: fixed; bottom: 0px; @@ -465,18 +476,4 @@ table.media_panel th { .navigation_left { left: 0px; } - .media_image { - width: 100%; - } - .mediagoblin_body { - width: 100%; - } - .mediagoblin_header, .mediagoblin_content, .mediagoblin_footer, .media_pane { - width: 100%; - margin-left: 0; - margin-right: 0; - } - .mediagoblin_footer { - margin-bottom: 100px; - } -} + */ From 7c7ba01ee3450ded81f3ec9630cde0818865ed03 Mon Sep 17 00:00:00 2001 From: Joar Wandborg Date: Fri, 30 Dec 2011 19:11:47 +0100 Subject: [PATCH 245/302] Fixed broken confirm_password test --- mediagoblin/tests/test_auth.py | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/mediagoblin/tests/test_auth.py b/mediagoblin/tests/test_auth.py index d3b8caf1..9b0dea66 100644 --- a/mediagoblin/tests/test_auth.py +++ b/mediagoblin/tests/test_auth.py @@ -89,7 +89,6 @@ def test_register_views(test_app): form = context['register_form'] assert form.username.errors == [u'This field is required.'] assert form.password.errors == [u'This field is required.'] - assert form.confirm_password.errors == [u'This field is required.'] assert form.email.errors == [u'This field is required.'] # Try to register with fields that are known to be invalid @@ -101,7 +100,6 @@ def test_register_views(test_app): '/auth/register/', { 'username': 'l', 'password': 'o', - 'confirm_password': 'o', 'email': 'l'}) context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/auth/register.html'] form = context['register_form'] @@ -125,18 +123,6 @@ def test_register_views(test_app): assert form.email.errors == [ u'Invalid email address.'] - ## mismatching passwords - template.clear_test_template_context() - test_app.post( - '/auth/register/', { - 'password': 'herpderp', - 'confirm_password': 'derpherp'}) - context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/auth/register.html'] - form = context['register_form'] - - assert form.password.errors == [ - u'Passwords must match.'] - ## At this point there should be no users in the database ;) assert not mg_globals.database.User.find().count() @@ -147,7 +133,6 @@ def test_register_views(test_app): '/auth/register/', { 'username': 'happygirl', 'password': 'iamsohappy', - 'confirm_password': 'iamsohappy', 'email': 'happygrrl@example.org'}) response.follow() @@ -227,7 +212,6 @@ def test_register_views(test_app): '/auth/register/', { 'username': 'happygirl', 'password': 'iamsohappy2', - 'confirm_password': 'iamsohappy2', 'email': 'happygrrl2@example.org'}) context = template.TEMPLATE_TEST_CONTEXT[ @@ -304,7 +288,6 @@ def test_register_views(test_app): '/auth/forgot_password/verify/', { 'userid': parsed_get_params['userid'], 'password': 'iamveryveryhappy', - 'confirm_password': 'iamveryveryhappy', 'token': parsed_get_params['token']}) response.follow() assert template.TEMPLATE_TEST_CONTEXT.has_key( From 6f559060785270d32a6ca99d2cdb89b5fedfaf9e Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Fri, 30 Dec 2011 19:45:00 +0100 Subject: [PATCH 246/302] Fix #715: On media submit page, "Separate" is misspelled --- mediagoblin/edit/forms.py | 2 +- mediagoblin/submit/forms.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mediagoblin/edit/forms.py b/mediagoblin/edit/forms.py index dd339e08..f9cc92bf 100644 --- a/mediagoblin/edit/forms.py +++ b/mediagoblin/edit/forms.py @@ -28,7 +28,7 @@ class EditForm(wtforms.Form): _('Tags'), [tag_length_validator], description=_( - "Seperate tags by commas.")) + "Separate tags by commas.")) slug = wtforms.TextField( _('Slug'), [wtforms.validators.Required(message=_("The slug can't be empty"))], diff --git a/mediagoblin/submit/forms.py b/mediagoblin/submit/forms.py index ad420771..e21b00ee 100644 --- a/mediagoblin/submit/forms.py +++ b/mediagoblin/submit/forms.py @@ -32,4 +32,4 @@ class SubmitStartForm(wtforms.Form): _('Tags'), [tag_length_validator], description=_( - "Seperate tags by commas.")) + "Separate tags by commas.")) From 694e965f45b8da0af96e3ae99c85b4f1f4819ee6 Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Fri, 30 Dec 2011 20:17:59 +0100 Subject: [PATCH 247/302] Fix #712: Comment counter always uses plural --- .../mediagoblin/user_pages/media.html | 86 ++++++++++--------- 1 file changed, 46 insertions(+), 40 deletions(-) diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html index 13fa1baa..4c255112 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media.html @@ -81,18 +81,25 @@ {% trans %}Delete{% endtrans %} {% endif %}

    -

    {% trans comment_count=comments.count() -%}{{ comment_count }} comments{%- endtrans %} - -

    - {# 0 comments. Be the first to add one! #} + {% if comments %} +

    + {% if comments.count()==1 %} + {% trans comment_count=comments.count() -%}{{ comment_count }} comment{%- endtrans %} + {% elif comments.count()>1 %} + {% trans comment_count=comments.count() -%}{{ comment_count }} comments{%- endtrans %} + {% else %} + {% trans %}No comments yet.{% endtrans %} + {% endif %} + +

    {% if request.user %} - - {% else %} -
    - {% endif %} -
    - {% autoescape False %} - {{ comment.content_html }} - {% endautoescape %} - - - {{ comment_author.username }} - - {% trans %}at{% endtrans %} - - {{ comment.created.strftime("%I:%M%p %Y-%m-%d") }} - -
    -
    - {% endfor %} + {% for comment in comments %} + {% set comment_author = comment.get_author %} + {% if pagination.active_id == comment._id %} +
    + + {% else %} +
    + {% endif %} +
    + {% autoescape False %} + {{ comment.content_html }} + {% endautoescape %} + + + {{ comment_author.username }} + + {% trans %}at{% endtrans %} + + {{ comment.created.strftime("%I:%M%p %Y-%m-%d") }} + +
    +
    + {% endfor %} {{ render_pagination(request, pagination, media.url_for_self(request.urlgen)) }} {% endif %} From 992e4f80324e5e2d0079fd70cce9d4ad962f7047 Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Fri, 30 Dec 2011 21:29:15 +0100 Subject: [PATCH 248/302] Change forgotten password process: different redirect, added/changed messages --- mediagoblin/auth/views.py | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/mediagoblin/auth/views.py b/mediagoblin/auth/views.py index 66178371..f707ecbe 100644 --- a/mediagoblin/auth/views.py +++ b/mediagoblin/auth/views.py @@ -232,16 +232,12 @@ def forgot_password(request): """ Forgot password view - Sends an email whit an url to renew forgoten password + Sends an email with an url to renew forgotten password """ fp_form = auth_forms.ForgotPassForm(request.POST) if request.method == 'POST' and fp_form.validate(): - # Here, so it doesn't depend on the actual mail being sent - # and thus doesn't reveal, wether mail was sent. - email_debug_message(request) - # '$or' not available till mongodb 1.5.3 user = request.db.User.find_one( {'username': request.POST['username']}) @@ -257,6 +253,14 @@ def forgot_password(request): user.save() send_fp_verification_email(user, request) + + messages.add_message( + request, + messages.INFO, + _("An email has been sent with instructions on how to " + "change your password.")) + email_debug_message(request) + else: # special case... we can't send the email because the # username is inactive / hasn't verified their email @@ -270,9 +274,13 @@ def forgot_password(request): return redirect( request, 'mediagoblin.user_pages.user_home', user=user.username) - - # do not reveal whether or not there is a matching user - return redirect(request, 'mediagoblin.auth.fp_email_sent') + return redirect(request, 'mediagoblin.auth.login') + else: + messages.add_message( + request, + messages.WARNING, + _("Couldn't find someone with that username or email.")) + return redirect(request, 'mediagoblin.auth.forgot_password') return render_to_response( request, From a246ccca69e863904718537f45a17d226b33a123 Mon Sep 17 00:00:00 2001 From: Joar Wandborg Date: Wed, 30 Nov 2011 21:21:39 +0100 Subject: [PATCH 249/302] ASCII media type support & fix a bug in file submission error handling * Added ASCII media processing * Added ASCII media display * Added ASCII media type Rebased from Joar Wandborg's ascii art branch (squashed to remove the commits borrowing code of dubious license) Fixed a bug in file submission error handling: - Moved file-extension condition out of loop (what did it do there?) - Updated file submission tests - Changed error handling in file submission, should now report more than absolutely necessary. --- extlib/inconsolata/INFO.txt | 4 + extlib/inconsolata/Inconsolata.otf | Bin 0 -> 58464 bytes extlib/inconsolata/Inconsolata.pfa | 1088 ++++ extlib/inconsolata/Inconsolata.sfd | 5730 +++++++++++++++++ extlib/inconsolata/OFL_1.1.txt | 97 + extlib/inconsolata/textest.pdf | Bin 0 -> 22783 bytes mediagoblin/media_types/__init__.py | 20 +- mediagoblin/media_types/ascii/__init__.py | 27 + mediagoblin/media_types/ascii/asciitoimage.py | 172 + .../media_types/ascii/fonts/Inconsolata.otf | 1 + mediagoblin/media_types/ascii/processing.py | 93 + mediagoblin/static/css/base.css | 12 + mediagoblin/static/fonts/Inconsolata.otf | 1 + mediagoblin/submit/views.py | 8 +- .../mediagoblin/media_displays/ascii.html | 40 + .../mediagoblin/media_displays/image.html | 18 + .../mediagoblin/media_displays/video.html | 18 + mediagoblin/tests/test_submission.py | 5 +- 18 files changed, 7323 insertions(+), 11 deletions(-) create mode 100644 extlib/inconsolata/INFO.txt create mode 100644 extlib/inconsolata/Inconsolata.otf create mode 100644 extlib/inconsolata/Inconsolata.pfa create mode 100644 extlib/inconsolata/Inconsolata.sfd create mode 100644 extlib/inconsolata/OFL_1.1.txt create mode 100644 extlib/inconsolata/textest.pdf create mode 100644 mediagoblin/media_types/ascii/__init__.py create mode 100644 mediagoblin/media_types/ascii/asciitoimage.py create mode 120000 mediagoblin/media_types/ascii/fonts/Inconsolata.otf create mode 100644 mediagoblin/media_types/ascii/processing.py create mode 120000 mediagoblin/static/fonts/Inconsolata.otf create mode 100644 mediagoblin/templates/mediagoblin/media_displays/ascii.html diff --git a/extlib/inconsolata/INFO.txt b/extlib/inconsolata/INFO.txt new file mode 100644 index 00000000..61d3a0f1 --- /dev/null +++ b/extlib/inconsolata/INFO.txt @@ -0,0 +1,4 @@ +Inconsolata +----------- + +This font is found at http://www.levien.com/type/myfonts/inconsolata.html diff --git a/extlib/inconsolata/Inconsolata.otf b/extlib/inconsolata/Inconsolata.otf new file mode 100644 index 0000000000000000000000000000000000000000..348889828d894b9b57fb6435497d5c034448cb1b GIT binary patch literal 58464 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, (), +with Reserved Font Name . +Copyright (c) , (), +with Reserved Font Name . +Copyright (c) , (). + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/extlib/inconsolata/textest.pdf b/extlib/inconsolata/textest.pdf new file mode 100644 index 0000000000000000000000000000000000000000..923aa349f72d4501368af9bb0adbe4696fb8227d GIT binary patch literal 22783 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 literal 0 HcmV?d00001 diff --git a/mediagoblin/media_types/__init__.py b/mediagoblin/media_types/__init__.py index 6f94c714..7b9bf0d7 100644 --- a/mediagoblin/media_types/__init__.py +++ b/mediagoblin/media_types/__init__.py @@ -69,16 +69,20 @@ def get_media_type_and_manager(filename): ''' Get the media type and manager based on a filename ''' - for media_type, manager in get_media_managers(): - if filename.find('.') > 0: - # Get the file extension - ext = os.path.splitext(filename)[1].lower() - else: - raise InvalidFileType( - _('Could not find any file extension in "{filename}"').format( - filename=filename)) + if filename.find('.') > 0: + # Get the file extension + ext = os.path.splitext(filename)[1].lower() + else: + raise Exception( + _(u'Could not extract any file extension from "{filename}"').format( + filename=filename)) + for media_type, manager in get_media_managers(): # Omit the dot from the extension and match it against # the media manager if ext[1:] in manager['accepted_extensions']: return media_type, manager + else: + raise FileTypeNotSupported( + # TODO: Provide information on which file types are supported + _(u'Sorry, I don\'t support that file type :(')) diff --git a/mediagoblin/media_types/ascii/__init__.py b/mediagoblin/media_types/ascii/__init__.py new file mode 100644 index 00000000..21b31d0e --- /dev/null +++ b/mediagoblin/media_types/ascii/__init__.py @@ -0,0 +1,27 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +from mediagoblin.media_types.ascii.processing import process_ascii + + +MEDIA_MANAGER = { + "human_readable": "ASCII", + "processor": process_ascii, # alternately a string, + # 'mediagoblin.media_types.image.processing'? + "display_template": "mediagoblin/media_displays/ascii.html", + "default_thumb": "images/media_thumbs/ascii.jpg", + "accepted_extensions": [ + "txt"]} diff --git a/mediagoblin/media_types/ascii/asciitoimage.py b/mediagoblin/media_types/ascii/asciitoimage.py new file mode 100644 index 00000000..39c75a19 --- /dev/null +++ b/mediagoblin/media_types/ascii/asciitoimage.py @@ -0,0 +1,172 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +import Image +import ImageFont +import ImageDraw +import logging +import pkg_resources +import os + +_log = logging.getLogger(__name__) + +class AsciiToImage(object): + ''' + Converter of ASCII art into image files, preserving whitespace + + kwargs: + - font: Path to font file + default: fonts/Inconsolata.otf + - font_size: Font size, ``int`` + default: 11 + ''' + + # Font file path + _font = None + + _font_size = 11 + + # ImageFont instance + _if = None + + # ImageFont + _if_dims = None + + # Image instance + _im = None + + def __init__(self, **kw): + if kw.get('font'): + self._font = kw.get('font') + else: + self._font = pkg_resources.resource_filename( + 'mediagoblin.media_types.ascii', + os.path.join('fonts', 'Inconsolata.otf')) + + if kw.get('font_size'): + self._font_size = kw.get('font_size') + + _log.info('Setting font to {0}, size {1}'.format( + self._font, + self._font_size)) + + self._if = ImageFont.truetype( + self._font, + self._font_size) + + # ,-,-^-'-^'^-^'^-'^-. + # ( I am a wall socket )Oo, ___ + # `-.,.-.,.-.-.,.-.--' ' ` + # Get the size, in pixels of the '.' character + self._if_dims = self._if.getsize('.') + # `---' + + def convert(self, text, destination): + # TODO: Detect if text is a file-like, if so, act accordingly + im = self._create_image(text) + + # PIL's Image.save will handle both file-likes and paths + if im.save(destination): + _log.info('Saved image in {0}'.format( + destination)) + + def _create_image(self, text): + ''' + Write characters to a PIL image canvas. + + TODO: + - Character set detection and decoding, + http://pypi.python.org/pypi/chardet + ''' + # TODO: Account for alternative line endings + lines = text.split('\n') + + line_lengths = [len(i) for i in lines] + + # Calculate destination size based on text input and character size + im_dims = ( + max(line_lengths) * self._if_dims[0], + len(line_lengths) * self._if_dims[1]) + + _log.info('Destination image dimensions will be {0}'.format( + im_dims)) + + im = Image.new( + 'RGBA', + im_dims, + (255, 255, 255, 0)) + + draw = ImageDraw.Draw(im) + + char_pos = [0, 0] + + for line in lines: + line_length = len(line) + + _log.debug('Writing line at {0}'.format(char_pos)) + + for _pos in range(0, line_length): + char = line[_pos] + + px_pos = self._px_pos(char_pos) + + _log.debug('Writing character "{0}" at {1} (px pos {2}'.format( + char, + char_pos, + px_pos)) + + draw.text( + px_pos, + char, + font=self._if, + fill=(0, 0, 0, 255)) + + char_pos[0] += 1 + + # Reset X position, increment Y position + char_pos[0] = 0 + char_pos[1] += 1 + + return im + + def _px_pos(self, char_pos): + ''' + Helper function to calculate the pixel position based on + character position and character dimensions + ''' + px_pos = [0, 0] + for index, val in zip(range(0, len(char_pos)), char_pos): + px_pos[index] = char_pos[index] * self._if_dims[index] + + return px_pos + + +if __name__ == "__main__": + import urllib + txt = urllib.urlopen('file:///home/joar/Dropbox/ascii/install-all-the-dependencies.txt') + + _log.setLevel(logging.DEBUG) + logging.basicConfig() + + converter = AsciiToImage() + + converter.convert(txt.read(), '/tmp/test.png') + + ''' + im, x, y, duration = renderImage(h, 10) + print "Rendered image in %.5f seconds" % duration + im.save('tldr.png', "PNG") + ''' diff --git a/mediagoblin/media_types/ascii/fonts/Inconsolata.otf b/mediagoblin/media_types/ascii/fonts/Inconsolata.otf new file mode 120000 index 00000000..4e742b5e --- /dev/null +++ b/mediagoblin/media_types/ascii/fonts/Inconsolata.otf @@ -0,0 +1 @@ +../../../../extlib/inconsolata/Inconsolata.otf \ No newline at end of file diff --git a/mediagoblin/media_types/ascii/processing.py b/mediagoblin/media_types/ascii/processing.py new file mode 100644 index 00000000..a74690c1 --- /dev/null +++ b/mediagoblin/media_types/ascii/processing.py @@ -0,0 +1,93 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +import asciitoimage +import chardet +import os +import Image + +from mediagoblin import mg_globals as mgg +from mediagoblin.processing import create_pub_filepath, THUMB_SIZE + + +def process_ascii(entry): + ''' + Code to process a txt file + ''' + workbench = mgg.workbench_manager.create_workbench() + # Conversions subdirectory to avoid collisions + conversions_subdir = os.path.join( + workbench.dir, 'conversions') + os.mkdir(conversions_subdir) + + queued_filepath = entry['queued_media_file'] + queued_filename = workbench.localized_file( + mgg.queue_store, queued_filepath, + 'source') + + queued_file = file(queued_filename, 'rb') + + with queued_file: + queued_file_charset = chardet.detect(queued_file.read()) + + queued_file.seek(0) # Rewind the queued file + + thumb_filepath = create_pub_filepath( + entry, 'thumbnail.png') + + tmp_thumb_filename = os.path.join( + conversions_subdir, thumb_filepath[-1]) + + converter = asciitoimage.AsciiToImage() + + thumb = converter._create_image( + queued_file.read()) + + with file(tmp_thumb_filename, 'w') as thumb_file: + thumb.thumbnail(THUMB_SIZE, Image.ANTIALIAS) + thumb.save(thumb_file) + + mgg.public_store.copy_local_to_storage( + tmp_thumb_filename, thumb_filepath) + + queued_file.seek(0) + + original_filepath = create_pub_filepath(entry, queued_filepath[-1]) + + with mgg.public_store.get_file(original_filepath, 'wb') \ + as original_file: + original_file.write(queued_file.read()) + + + queued_file.seek(0) # Rewind *again* + + unicode_filepath = create_pub_filepath(entry, 'unicode.txt') + + with mgg.public_store.get_file(unicode_filepath, 'wb') \ + as unicode_file: + unicode_file.write( + unicode(queued_file.read().decode( + queued_file_charset['encoding'])).encode( + 'ascii', + 'xmlcharrefreplace')) + + mgg.queue_store.delete_file(queued_filepath) + entry['queued_media_file'] = [] + media_files_dict = entry.setdefault('media_files', {}) + media_files_dict['thumb'] = thumb_filepath + media_files_dict['unicode'] = unicode_filepath + media_files_dict['original'] = original_filepath + + entry.save() diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css index ecdd0474..382ba88a 100644 --- a/mediagoblin/static/css/base.css +++ b/mediagoblin/static/css/base.css @@ -402,3 +402,15 @@ table.media_panel th { margin-top: 10px; margin-left: 10px; } + +/* ASCII art */ + +@font-face { + font-family: Inconsolata; + src: local('Inconsolata'), url('../fonts/Inconsolata.otf') format('opentype') +} + +.ascii-wrapper pre { + font-family: Inconsolata, monospace; + line-height: 1em; +} \ No newline at end of file diff --git a/mediagoblin/static/fonts/Inconsolata.otf b/mediagoblin/static/fonts/Inconsolata.otf new file mode 120000 index 00000000..777be657 --- /dev/null +++ b/mediagoblin/static/fonts/Inconsolata.otf @@ -0,0 +1 @@ +../../../extlib/inconsolata/Inconsolata.otf \ No newline at end of file diff --git a/mediagoblin/submit/views.py b/mediagoblin/submit/views.py index 4e4c7c43..443d0e52 100644 --- a/mediagoblin/submit/views.py +++ b/mediagoblin/submit/views.py @@ -128,9 +128,13 @@ def submit_start(request): return redirect(request, "mediagoblin.user_pages.user_home", user=request.user.username) - except InvalidFileType, exc: + except Exception as e: + ''' + This section is intended to catch exceptions raised in + mediagobling.media_types + ''' submit_form.file.errors.append( - _(u'Invalid file type.')) + e) return render_to_response( request, diff --git a/mediagoblin/templates/mediagoblin/media_displays/ascii.html b/mediagoblin/templates/mediagoblin/media_displays/ascii.html new file mode 100644 index 00000000..9e77066a --- /dev/null +++ b/mediagoblin/templates/mediagoblin/media_displays/ascii.html @@ -0,0 +1,40 @@ +{# +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +#} + +{% extends 'mediagoblin/user_pages/media.html' %} + +{% block mediagoblin_media %} +
    +
    +      {%- autoescape False -%}
    +      {{- request.app.public_store.get_file(
    +             media['media_files']['unicode']).read()|string -}}
    +      {%- endautoescape -%}
    +    
    +
    + {% if 'original' in media.media_files %} +

    + + {%- trans -%} + Original + {%- endtrans -%} + +

    + {% endif %} +{% endblock %} diff --git a/mediagoblin/templates/mediagoblin/media_displays/image.html b/mediagoblin/templates/mediagoblin/media_displays/image.html index ad60fa94..94420e89 100644 --- a/mediagoblin/templates/mediagoblin/media_displays/image.html +++ b/mediagoblin/templates/mediagoblin/media_displays/image.html @@ -1 +1,19 @@ +{# +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +#} + {% extends 'mediagoblin/user_pages/media.html' %} diff --git a/mediagoblin/templates/mediagoblin/media_displays/video.html b/mediagoblin/templates/mediagoblin/media_displays/video.html index ada50e28..fc08f963 100644 --- a/mediagoblin/templates/mediagoblin/media_displays/video.html +++ b/mediagoblin/templates/mediagoblin/media_displays/video.html @@ -1,3 +1,21 @@ +{# +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +#} + {% extends 'mediagoblin/user_pages/media.html' %} {% block mediagoblin_media %} diff --git a/mediagoblin/tests/test_submission.py b/mediagoblin/tests/test_submission.py index 7c372745..4a0543a8 100644 --- a/mediagoblin/tests/test_submission.py +++ b/mediagoblin/tests/test_submission.py @@ -1,3 +1,4 @@ + # GNU MediaGoblin -- federated, autonomous media hosting # Copyright (C) 2011 MediaGoblin contributors. See AUTHORS. # @@ -16,6 +17,7 @@ import urlparse import pkg_resources +import re from nose.tools import assert_equal, assert_true, assert_false @@ -216,7 +218,8 @@ class TestSubmission: context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/submit/start.html'] form = context['submit_form'] - assert form.file.errors == [u'Invalid file type.'] + assert re.match(r'^Could not extract any file extension from ".*?"$', str(form.file.errors[0])) + assert len(form.file.errors) == 1 # NOTE: The following 2 tests will ultimately fail, but they # *will* pass the initial form submission step. Instead, From 4601c30c2e80734cf3a18472c2e29a7f920b9604 Mon Sep 17 00:00:00 2001 From: Joar Wandborg Date: Sat, 31 Dec 2011 22:57:08 +0100 Subject: [PATCH 250/302] Fixed submission error handling and broken tests - Fixed broken test_auth test - Fixed error handling on submission, it now raises the exception if it is not explicitly relevant to file submission. --- mediagoblin/media_types/__init__.py | 2 +- mediagoblin/submit/views.py | 12 +++++++++--- mediagoblin/tests/test_auth.py | 4 ++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/mediagoblin/media_types/__init__.py b/mediagoblin/media_types/__init__.py index 7b9bf0d7..e7eb1dde 100644 --- a/mediagoblin/media_types/__init__.py +++ b/mediagoblin/media_types/__init__.py @@ -73,7 +73,7 @@ def get_media_type_and_manager(filename): # Get the file extension ext = os.path.splitext(filename)[1].lower() else: - raise Exception( + raise InvalidFileType( _(u'Could not extract any file extension from "{filename}"').format( filename=filename)) diff --git a/mediagoblin/submit/views.py b/mediagoblin/submit/views.py index 443d0e52..60693bd6 100644 --- a/mediagoblin/submit/views.py +++ b/mediagoblin/submit/views.py @@ -31,7 +31,8 @@ from mediagoblin.decorators import require_active_login from mediagoblin.submit import forms as submit_forms, security from mediagoblin.processing import mark_entry_failed, ProcessMedia from mediagoblin.messages import add_message, SUCCESS -from mediagoblin.media_types import get_media_type_and_manager, InvalidFileType +from mediagoblin.media_types import get_media_type_and_manager, \ + InvalidFileType, FileTypeNotSupported @require_active_login @@ -133,8 +134,13 @@ def submit_start(request): This section is intended to catch exceptions raised in mediagobling.media_types ''' - submit_form.file.errors.append( - e) + + if isinstance(e, InvalidFileType) or \ + isinstance(e, FileTypeNotSupported): + submit_form.file.errors.append( + e) + else: + raise return render_to_response( request, diff --git a/mediagoblin/tests/test_auth.py b/mediagoblin/tests/test_auth.py index 9b0dea66..e54ffa5a 100644 --- a/mediagoblin/tests/test_auth.py +++ b/mediagoblin/tests/test_auth.py @@ -233,9 +233,9 @@ def test_register_views(test_app): ## Did we redirect to the proper page? Use the right template? assert_equal( urlparse.urlsplit(response.location)[2], - '/auth/forgot_password/email_sent/') + '/auth/login/') assert template.TEMPLATE_TEST_CONTEXT.has_key( - 'mediagoblin/auth/fp_email_sent.html') + 'mediagoblin/auth/login.html') ## Make sure link to change password is sent by email assert len(mail.EMAIL_TEST_INBOX) == 1 From 7fc782bb6d63cef234ff1a4dad29175afb6d8be5 Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Sun, 1 Jan 2012 18:11:39 +0100 Subject: [PATCH 251/302] Disable horizontal resize for text areas. --- mediagoblin/static/css/base.css | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css index 382ba88a..98b77967 100644 --- a/mediagoblin/static/css/base.css +++ b/mediagoblin/static/css/base.css @@ -193,6 +193,7 @@ text-align: center; } textarea#comment_content { + resize: vertical; width: 634px; height: 90px; border: none; @@ -256,6 +257,10 @@ textarea#comment_content { width: 20px; } +textarea#description { + resize: vertical; +} + /* comments */ .comment_author { @@ -413,4 +418,4 @@ table.media_panel th { .ascii-wrapper pre { font-family: Inconsolata, monospace; line-height: 1em; -} \ No newline at end of file +} From ce86b1d5afd21283719146a367b05352d290032f Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Sun, 1 Jan 2012 18:12:18 +0100 Subject: [PATCH 252/302] Remove border-bottom from media_specs --- mediagoblin/static/css/base.css | 1 - 1 file changed, 1 deletion(-) diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css index 98b77967..e58a7368 100644 --- a/mediagoblin/static/css/base.css +++ b/mediagoblin/static/css/base.css @@ -303,7 +303,6 @@ h2.media_title { p.media_specs { font-size: 0.9em; border-top: 1px solid #222; - border-bottom: 1px solid #222; padding: 10px 0px; color: #888; } From f5d837fe4a0ad5f08b48e0cd69fddb37e81d1514 Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Sun, 1 Jan 2012 18:14:39 +0100 Subject: [PATCH 253/302] Forgot this one. Also disable horizontal resize for the bio field --- mediagoblin/static/css/base.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css index e58a7368..76e37c1b 100644 --- a/mediagoblin/static/css/base.css +++ b/mediagoblin/static/css/base.css @@ -257,7 +257,7 @@ textarea#comment_content { width: 20px; } -textarea#description { +textarea#description, textarea#bio { resize: vertical; } From 415077a743400f9d9fa476b37c5b3aff4683f942 Mon Sep 17 00:00:00 2001 From: Elrond Date: Sun, 1 Jan 2012 17:24:02 +0100 Subject: [PATCH 254/302] Factor out check_db_migrations_current When initializing the database connection the current mongo based setup checked for new migrations and warned about them. This was mongo specific so factor'd it out into a more generic check_db_migrations_current function in the mongo backend. Also created a dummy one in the sql backend. --- mediagoblin/db/mongo/open.py | 23 +++++++++++++++++++++++ mediagoblin/db/open.py | 3 ++- mediagoblin/db/sql/open.py | 4 ++++ mediagoblin/init/__init__.py | 24 +++--------------------- 4 files changed, 32 insertions(+), 22 deletions(-) diff --git a/mediagoblin/db/mongo/open.py b/mediagoblin/db/mongo/open.py index 63889292..8016ced9 100644 --- a/mediagoblin/db/mongo/open.py +++ b/mediagoblin/db/mongo/open.py @@ -18,6 +18,7 @@ import pymongo import mongokit from paste.deploy.converters import asint from mediagoblin.db.mongo import models +from mediagoblin.db.util import MigrationManager def connect_database_from_config(app_config, use_pymongo=False): @@ -53,3 +54,25 @@ def setup_connection_and_db_from_config(app_config, use_pymongo=False): models.register_models(connection) return (connection, db) + + +def check_db_migrations_current(db): + # This MUST be imported so as to set up the appropriate migrations! + from mediagoblin.db.mongo import migrations + + # Init the migration number if necessary + migration_manager = MigrationManager(db) + migration_manager.install_migration_version_if_missing() + + # Tiny hack to warn user if our migration is out of date + if not migration_manager.database_at_latest_migration(): + db_migration_num = migration_manager.database_current_migration() + latest_migration_num = migration_manager.latest_migration() + if db_migration_num < latest_migration_num: + print ( + "*WARNING:* Your migrations are out of date, " + "maybe run ./bin/gmg migrate?") + elif db_migration_num > latest_migration_num: + print ( + "*WARNING:* Your migrations are out of date... " + "in fact they appear to be from the future?!") diff --git a/mediagoblin/db/open.py b/mediagoblin/db/open.py index a92a6ada..32827fcb 100644 --- a/mediagoblin/db/open.py +++ b/mediagoblin/db/open.py @@ -14,4 +14,5 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -from mediagoblin.db.mongo.open import setup_connection_and_db_from_config +from mediagoblin.db.mongo.open import \ + setup_connection_and_db_from_config, check_db_migrations_current diff --git a/mediagoblin/db/sql/open.py b/mediagoblin/db/sql/open.py index 57feaf50..c682bd3b 100644 --- a/mediagoblin/db/sql/open.py +++ b/mediagoblin/db/sql/open.py @@ -27,3 +27,7 @@ def setup_connection_and_db_from_config(app_config): Session.configure(bind=engine) return "dummy conn", DatabaseMaster(engine) + + +def check_db_migrations_current(db): + pass diff --git a/mediagoblin/init/__init__.py b/mediagoblin/init/__init__.py index 5f7f83d4..23c1c26d 100644 --- a/mediagoblin/init/__init__.py +++ b/mediagoblin/init/__init__.py @@ -23,8 +23,8 @@ from mediagoblin.init.config import ( read_mediagoblin_config, generate_validation_report) from mediagoblin import mg_globals from mediagoblin.mg_globals import setup_globals -from mediagoblin.db.open import setup_connection_and_db_from_config -from mediagoblin.db.util import MigrationManager +from mediagoblin.db.open import setup_connection_and_db_from_config, \ + check_db_migrations_current from mediagoblin.workbench import WorkbenchManager from mediagoblin.storage import storage_system_from_config @@ -56,28 +56,10 @@ def setup_global_and_app_config(config_path): def setup_database(): app_config = mg_globals.app_config - # This MUST be imported so as to set up the appropriate migrations! - from mediagoblin.db.mongo import migrations - # Set up the database connection, db = setup_connection_and_db_from_config(app_config) - # Init the migration number if necessary - migration_manager = MigrationManager(db) - migration_manager.install_migration_version_if_missing() - - # Tiny hack to warn user if our migration is out of date - if not migration_manager.database_at_latest_migration(): - db_migration_num = migration_manager.database_current_migration() - latest_migration_num = migration_manager.latest_migration() - if db_migration_num < latest_migration_num: - print ( - "*WARNING:* Your migrations are out of date, " - "maybe run ./bin/gmg migrate?") - elif db_migration_num > latest_migration_num: - print ( - "*WARNING:* Your migrations are out of date... " - "in fact they appear to be from the future?!") + check_db_migrations_current(db) setup_globals( db_connection=connection, From d8db95e4b72ae30c368aeba41993004b95bc7412 Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Sun, 1 Jan 2012 19:00:56 +0100 Subject: [PATCH 255/302] Remove fp_email_sent.html and refs to it --- mediagoblin/auth/routing.py | 4 --- .../mediagoblin/auth/fp_email_sent.html | 28 ------------------- 2 files changed, 32 deletions(-) delete mode 100644 mediagoblin/templates/mediagoblin/auth/fp_email_sent.html diff --git a/mediagoblin/auth/routing.py b/mediagoblin/auth/routing.py index 365ccfaa..699ecbe1 100644 --- a/mediagoblin/auth/routing.py +++ b/mediagoblin/auth/routing.py @@ -39,8 +39,4 @@ auth_routes = [ Route('mediagoblin.auth.fp_changed_success', '/forgot_password/changed_success/', template='mediagoblin/auth/fp_changed_success.html', - controller='mediagoblin.views:simple_template_render'), - Route('mediagoblin.auth.fp_email_sent', - '/forgot_password/email_sent/', - template='mediagoblin/auth/fp_email_sent.html', controller='mediagoblin.views:simple_template_render')] diff --git a/mediagoblin/templates/mediagoblin/auth/fp_email_sent.html b/mediagoblin/templates/mediagoblin/auth/fp_email_sent.html deleted file mode 100644 index 69aac6b3..00000000 --- a/mediagoblin/templates/mediagoblin/auth/fp_email_sent.html +++ /dev/null @@ -1,28 +0,0 @@ -{# -# 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 . -#} -{% extends "mediagoblin/base.html" %} - -{% block mediagoblin_content %} -

    - {% trans -%} - Check your inbox. We sent an email with a URL for changing your password. - {%- endtrans %} -

    - -{% endblock %} - From 35149b11247846506b31ef3cd6647b659b18f352 Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Sun, 1 Jan 2012 19:13:23 +0100 Subject: [PATCH 256/302] Remove fp_changed_success.html, use log in page + notification message instead --- mediagoblin/auth/routing.py | 6 +---- mediagoblin/auth/views.py | 6 ++++- .../mediagoblin/auth/fp_changed_success.html | 27 ------------------- 3 files changed, 6 insertions(+), 33 deletions(-) delete mode 100644 mediagoblin/templates/mediagoblin/auth/fp_changed_success.html diff --git a/mediagoblin/auth/routing.py b/mediagoblin/auth/routing.py index 699ecbe1..ea9388c5 100644 --- a/mediagoblin/auth/routing.py +++ b/mediagoblin/auth/routing.py @@ -35,8 +35,4 @@ auth_routes = [ controller='mediagoblin.auth.views:forgot_password'), Route('mediagoblin.auth.verify_forgot_password', '/forgot_password/verify/', - controller='mediagoblin.auth.views:verify_forgot_password'), - Route('mediagoblin.auth.fp_changed_success', - '/forgot_password/changed_success/', - template='mediagoblin/auth/fp_changed_success.html', - controller='mediagoblin.views:simple_template_render')] + controller='mediagoblin.auth.views:verify_forgot_password')] diff --git a/mediagoblin/auth/views.py b/mediagoblin/auth/views.py index f707ecbe..88dc40ad 100644 --- a/mediagoblin/auth/views.py +++ b/mediagoblin/auth/views.py @@ -324,7 +324,11 @@ def verify_forgot_password(request): user.fp_token_expire = None user.save() - return redirect(request, 'mediagoblin.auth.fp_changed_success') + messages.add_message( + request, + messages.INFO, + _("You can now log in using your new password.")) + return redirect(request, 'mediagoblin.auth.login') else: return render_to_response( request, diff --git a/mediagoblin/templates/mediagoblin/auth/fp_changed_success.html b/mediagoblin/templates/mediagoblin/auth/fp_changed_success.html deleted file mode 100644 index 7cea312d..00000000 --- a/mediagoblin/templates/mediagoblin/auth/fp_changed_success.html +++ /dev/null @@ -1,27 +0,0 @@ -{# -# 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 . -#} -{% extends "mediagoblin/base.html" %} - -{% block mediagoblin_content %} -

    - {% trans -%} - Your password has been changed. Try to log in now. - {%- endtrans %} -

    -{% endblock %} - From 445d811043c5cb8b801b91604da6e3967d7ba3b7 Mon Sep 17 00:00:00 2001 From: Elrond Date: Sun, 1 Jan 2012 19:20:38 +0100 Subject: [PATCH 257/302] Fix unit tests for new forget password flow After changing the password, the login page is now shown. It contains a message. (we can't test for that easily currently. There is a bug open on this problem.) At least for the login page being shown now. --- mediagoblin/tests/test_auth.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediagoblin/tests/test_auth.py b/mediagoblin/tests/test_auth.py index e54ffa5a..411b4539 100644 --- a/mediagoblin/tests/test_auth.py +++ b/mediagoblin/tests/test_auth.py @@ -291,7 +291,7 @@ def test_register_views(test_app): 'token': parsed_get_params['token']}) response.follow() assert template.TEMPLATE_TEST_CONTEXT.has_key( - 'mediagoblin/auth/fp_changed_success.html') + 'mediagoblin/auth/login.html') ## Verify step 2.2 of password-change works -- login w/ new password success template.clear_test_template_context() From ada0642e5a619a3dce4050db535eb065e0cdc798 Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Sun, 1 Jan 2012 22:58:32 +0100 Subject: [PATCH 258/302] Seperate jQuery bit that was still in media.html --- mediagoblin/static/js/comment_show.js | 9 +++++++++ .../templates/mediagoblin/user_pages/media.html | 13 ++----------- 2 files changed, 11 insertions(+), 11 deletions(-) create mode 100644 mediagoblin/static/js/comment_show.js diff --git a/mediagoblin/static/js/comment_show.js b/mediagoblin/static/js/comment_show.js new file mode 100644 index 00000000..2212b9ad --- /dev/null +++ b/mediagoblin/static/js/comment_show.js @@ -0,0 +1,9 @@ +$(document).ready(function(){ + $('#form_comment').hide(); + $('#button_addcomment').click(function(){ + $(this).fadeOut('fast'); + $('#form_comment').slideDown(function(){ + $('#comment_content').focus(); + }); + }); +}); diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html index 4c255112..ca650f63 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media.html @@ -23,17 +23,8 @@ {% block title %}{{ media.title }} — {{ super() }}{% endblock %} {% block mediagoblin_head %} - + {% endblock mediagoblin_head %} {% block mediagoblin_content %} From 010fe2d71bf8b1c47c12234466d759561df18355 Mon Sep 17 00:00:00 2001 From: Elrond Date: Sat, 24 Dec 2011 15:55:33 +0100 Subject: [PATCH 259/302] sql convert: Use more library functions 1. Use the new setup_connection_and_db_from_config in the sql backend. 2. Use sql and mongo specific functions wherever appropiate instead of the generic "db.X" one. This makes the converter more indepedent of the current backend choice. --- mediagoblin/db/sql/convert.py | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/mediagoblin/db/sql/convert.py b/mediagoblin/db/sql/convert.py index c6bed1e9..6698b767 100644 --- a/mediagoblin/db/sql/convert.py +++ b/mediagoblin/db/sql/convert.py @@ -1,13 +1,12 @@ -from sqlalchemy import create_engine -from sqlalchemy.orm import sessionmaker - from mediagoblin.init import setup_global_and_app_config, setup_database -from mediagoblin.db.util import ObjectId +from mediagoblin.db.mongo.util import ObjectId from mediagoblin.db.sql.models import (Base, User, MediaEntry, MediaComment, Tag, MediaTag) - -# Session = sessionmaker() +from mediagoblin.db.sql.open import setup_connection_and_db_from_config as \ + sql_connect +from mediagoblin.db.mongo.open import setup_connection_and_db_from_config as \ + mongo_connect from mediagoblin.db.sql.base import Session @@ -125,14 +124,13 @@ def convert_media_comments(mk_db): def main(): - engine = create_engine('sqlite:///mediagoblin.db', echo=True) - Session.configure(bind=engine) + global_config, app_config = setup_global_and_app_config("mediagoblin.ini") - setup_global_and_app_config("mediagoblin.ini") + sql_conn, sql_db = sql_connect({'sql_engine': 'sqlite:///mediagoblin.db'}) - mk_conn, mk_db = setup_database() + mk_conn, mk_db = mongo_connect(app_config) - Base.metadata.create_all(engine) + Base.metadata.create_all(sql_db.engine) convert_users(mk_db) Session.remove() From 228c4470f40d66e8b9383321d44d89e2a1c0ecad Mon Sep 17 00:00:00 2001 From: Elrond Date: Wed, 4 Jan 2012 11:57:08 +0100 Subject: [PATCH 260/302] Dot-Notation for MediaEntry.media_files --- mediagoblin/gmg_commands/import_export.py | 4 ++-- mediagoblin/media_types/video/processing.py | 6 +++--- mediagoblin/templates/mediagoblin/edit/attachments.html | 2 +- mediagoblin/templates/mediagoblin/edit/edit.html | 2 +- mediagoblin/templates/mediagoblin/media_displays/ascii.html | 4 ++-- mediagoblin/templates/mediagoblin/media_displays/video.html | 4 ++-- mediagoblin/templates/mediagoblin/user_pages/media.html | 4 ++-- .../mediagoblin/user_pages/media_confirm_delete.html | 2 +- mediagoblin/templates/mediagoblin/utils/object_gallery.html | 2 +- mediagoblin/tools/files.py | 2 +- 10 files changed, 16 insertions(+), 16 deletions(-) diff --git a/mediagoblin/gmg_commands/import_export.py b/mediagoblin/gmg_commands/import_export.py index eda41f4c..7f699429 100644 --- a/mediagoblin/gmg_commands/import_export.py +++ b/mediagoblin/gmg_commands/import_export.py @@ -65,7 +65,7 @@ def _import_media(db, args): args._cache_path['queue']) for entry in db.MediaEntry.find(): - for name, path in entry['media_files'].items(): + for name, path in entry.media_files.items(): _log.info('Importing: {0} - {1}'.format( entry.title, name)) @@ -207,7 +207,7 @@ def _export_media(db, args): args._cache_path['queue']) for entry in db.MediaEntry.find(): - for name, path in entry['media_files'].items(): + for name, path in entry.media_files.items(): _log.info(u'Exporting {0} - {1}'.format( entry.title, name)) diff --git a/mediagoblin/media_types/video/processing.py b/mediagoblin/media_types/video/processing.py index 7d261226..c260cfd6 100644 --- a/mediagoblin/media_types/video/processing.py +++ b/mediagoblin/media_types/video/processing.py @@ -74,7 +74,7 @@ def process_video(entry): tmp_dst.read()) _log.debug('Saved medium') - entry['media_files']['webm_640'] = medium_filepath + entry.media_files['webm_640'] = medium_filepath # Save the width and height of the transcoded video entry.media_data['video'] = { @@ -94,7 +94,7 @@ def process_video(entry): tmp_thumb.read()) _log.debug('Saved thumbnail') - entry['media_files']['thumb'] = thumbnail_filepath + entry.media_files['thumb'] = thumbnail_filepath if video_config['keep_original']: # Push original file to public storage @@ -111,7 +111,7 @@ def process_video(entry): original_file.write(queued_file.read()) _log.debug('Saved original') - entry['media_files']['original'] = original_filepath + entry.media_files['original'] = original_filepath mgg.queue_store.delete_file(queued_filepath) diff --git a/mediagoblin/templates/mediagoblin/edit/attachments.html b/mediagoblin/templates/mediagoblin/edit/attachments.html index 124d0313..06062cd3 100644 --- a/mediagoblin/templates/mediagoblin/edit/attachments.html +++ b/mediagoblin/templates/mediagoblin/edit/attachments.html @@ -27,7 +27,7 @@

    Editing attachments for {{ media.title }}

    + media.media_files['thumb']) }}" />
    {% if media.attachment_files|count %} diff --git a/mediagoblin/templates/mediagoblin/edit/edit.html b/mediagoblin/templates/mediagoblin/edit/edit.html index 2dfaddc8..024a2b4d 100644 --- a/mediagoblin/templates/mediagoblin/edit/edit.html +++ b/mediagoblin/templates/mediagoblin/edit/edit.html @@ -29,7 +29,7 @@

    {% trans media_title=media.title %}Editing {{ media_title }}{% endtrans %}

    + media.media_files['thumb']) }}" />
    {{ wtforms_util.render_divs(form) }}
    diff --git a/mediagoblin/templates/mediagoblin/media_displays/ascii.html b/mediagoblin/templates/mediagoblin/media_displays/ascii.html index 9e77066a..6b40bf08 100644 --- a/mediagoblin/templates/mediagoblin/media_displays/ascii.html +++ b/mediagoblin/templates/mediagoblin/media_displays/ascii.html @@ -23,14 +23,14 @@
           {%- autoescape False -%}
           {{- request.app.public_store.get_file(
    -             media['media_files']['unicode']).read()|string -}}
    +             media.media_files['unicode']).read()|string -}}
           {%- endautoescape -%}
         
    {% if 'original' in media.media_files %}

    + media.media_files['original']) }}"> {%- trans -%} Original {%- endtrans -%} diff --git a/mediagoblin/templates/mediagoblin/media_displays/video.html b/mediagoblin/templates/mediagoblin/media_displays/video.html index fc08f963..6b5e7a0e 100644 --- a/mediagoblin/templates/mediagoblin/media_displays/video.html +++ b/mediagoblin/templates/mediagoblin/media_displays/video.html @@ -27,7 +27,7 @@ preload="auto" data-setup="">

    {%- trans -%}Sorry, this video will not work because @@ -42,7 +42,7 @@ {% if 'original' in media.media_files %}

    + media.media_files['original']) }}"> {%- trans -%} Original {%- endtrans -%} diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html index ca650f63..d52f544f 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media.html @@ -36,9 +36,9 @@ {# if there's a medium file size, that means the medium size # isn't the original... so link to the original! #} - {% if media['media_files'].has_key('medium') %} + {% if media.media_files.has_key('medium') %} + media.media_files['original']) }}"> Image for {{ media.title }} diff --git a/mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html b/mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html index 6c483769..408bca05 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html @@ -34,7 +34,7 @@


    diff --git a/mediagoblin/templates/mediagoblin/utils/object_gallery.html b/mediagoblin/templates/mediagoblin/utils/object_gallery.html index b8155f03..5f628dc7 100644 --- a/mediagoblin/templates/mediagoblin/utils/object_gallery.html +++ b/mediagoblin/templates/mediagoblin/utils/object_gallery.html @@ -31,7 +31,7 @@ {%- elif loop.last %} thumb_entry_last{% endif %}">
    + entry.media_files['thumb']) }}" /> {% if entry.title %}
    diff --git a/mediagoblin/tools/files.py b/mediagoblin/tools/files.py index e0bf0569..10f1d994 100644 --- a/mediagoblin/tools/files.py +++ b/mediagoblin/tools/files.py @@ -23,7 +23,7 @@ def delete_media_files(media): Arguments: - media: A MediaEntry document """ - for listpath in media['media_files'].itervalues(): + for listpath in media.media_files.itervalues(): mg_globals.public_store.delete_file( listpath) From 049284b1da87c1fcb21a8b5585890364eb8e0735 Mon Sep 17 00:00:00 2001 From: Elrond Date: Tue, 13 Dec 2011 10:49:51 +0100 Subject: [PATCH 261/302] Dot-Notation for MediaEntry.state --- mediagoblin/processing.py | 2 +- mediagoblin/tests/test_submission.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mediagoblin/processing.py b/mediagoblin/processing.py index 7dd5cc7d..cbac8030 100644 --- a/mediagoblin/processing.py +++ b/mediagoblin/processing.py @@ -64,7 +64,7 @@ class ProcessMedia(Task): except ImportError, exc: mark_entry_failed(entry[u'_id'], exc) - entry['state'] = u'processed' + entry.state = u'processed' entry.save() def on_failure(self, exc, task_id, args, kwargs, einfo): diff --git a/mediagoblin/tests/test_submission.py b/mediagoblin/tests/test_submission.py index 4a0543a8..2b17c515 100644 --- a/mediagoblin/tests/test_submission.py +++ b/mediagoblin/tests/test_submission.py @@ -240,7 +240,7 @@ class TestSubmission: entry = mg_globals.database.MediaEntry.find_one( {'title': 'Malicious Upload 2'}) - assert_equal(entry['state'], 'failed') + assert_equal(entry.state, 'failed') assert_equal( entry['fail_error'], u'mediagoblin.processing:BadMediaFail') @@ -260,7 +260,7 @@ class TestSubmission: entry = mg_globals.database.MediaEntry.find_one( {'title': 'Malicious Upload 3'}) - assert_equal(entry['state'], 'failed') + assert_equal(entry.state, 'failed') assert_equal( entry['fail_error'], u'mediagoblin.processing:BadMediaFail') From 8545cfc97d9336b100881bd3ebafd4a5f4882dd3 Mon Sep 17 00:00:00 2001 From: Elrond Date: Tue, 13 Dec 2011 11:18:39 +0100 Subject: [PATCH 262/302] Dot-Notation for MediaEntry.queued_media_file --- mediagoblin/media_types/image/processing.py | 4 ++-- mediagoblin/media_types/video/processing.py | 2 +- mediagoblin/submit/views.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mediagoblin/media_types/image/processing.py b/mediagoblin/media_types/image/processing.py index e493eb2b..cf90388f 100644 --- a/mediagoblin/media_types/image/processing.py +++ b/mediagoblin/media_types/image/processing.py @@ -37,7 +37,7 @@ def process_image(entry): workbench.dir, 'conversions') os.mkdir(conversions_subdir) - queued_filepath = entry['queued_media_file'] + queued_filepath = entry.queued_media_file queued_filename = workbench.localized_file( mgg.queue_store, queued_filepath, 'source') @@ -98,7 +98,7 @@ def process_image(entry): original_file.write(queued_file.read()) mgg.queue_store.delete_file(queued_filepath) - entry['queued_media_file'] = [] + entry.queued_media_file = [] media_files_dict = entry.setdefault('media_files', {}) media_files_dict['thumb'] = thumb_filepath media_files_dict['original'] = original_filepath diff --git a/mediagoblin/media_types/video/processing.py b/mediagoblin/media_types/video/processing.py index c260cfd6..49a50647 100644 --- a/mediagoblin/media_types/video/processing.py +++ b/mediagoblin/media_types/video/processing.py @@ -45,7 +45,7 @@ def process_video(entry): workbench = mgg.workbench_manager.create_workbench() - queued_filepath = entry['queued_media_file'] + queued_filepath = entry.queued_media_file queued_filename = workbench.localized_file( mgg.queue_store, queued_filepath, 'source') diff --git a/mediagoblin/submit/views.py b/mediagoblin/submit/views.py index 60693bd6..dd273c7f 100644 --- a/mediagoblin/submit/views.py +++ b/mediagoblin/submit/views.py @@ -89,7 +89,7 @@ def submit_start(request): queue_file.write(request.POST['file'].file.read()) # Add queued filename to the entry - entry['queued_media_file'] = queue_filepath + entry.queued_media_file = queue_filepath # We generate this ourselves so we know what the taks id is for # retrieval later. From 9c196287ad26f52acb38d6c37560848da23151a6 Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Wed, 4 Jan 2012 17:48:16 +0100 Subject: [PATCH 263/302] Add Markdown for submit page, edit page, profile edit page; thus fixing ticket #690 --- mediagoblin/edit/forms.py | 12 ++++++++++-- mediagoblin/submit/forms.py | 5 ++++- .../templates/mediagoblin/user_pages/media.html | 2 +- mediagoblin/templates/mediagoblin/utils/wtforms.html | 2 +- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/mediagoblin/edit/forms.py b/mediagoblin/edit/forms.py index f9cc92bf..406de3f8 100644 --- a/mediagoblin/edit/forms.py +++ b/mediagoblin/edit/forms.py @@ -23,7 +23,11 @@ class EditForm(wtforms.Form): title = wtforms.TextField( _('Title'), [wtforms.validators.Length(min=0, max=500)]) - description = wtforms.TextAreaField('Description of this work') + description = wtforms.TextAreaField( + _('Description of this work'), + description=_("""You can use + + Markdown for formatting.""")) tags = wtforms.TextField( _('Tags'), [tag_length_validator], @@ -40,7 +44,11 @@ class EditForm(wtforms.Form): class EditProfileForm(wtforms.Form): bio = wtforms.TextAreaField( _('Bio'), - [wtforms.validators.Length(min=0, max=500)]) + [wtforms.validators.Length(min=0, max=500)], + description=_( + """You can use + + Markdown for formatting.""")) url = wtforms.TextField( _('Website'), [wtforms.validators.Optional(), diff --git a/mediagoblin/submit/forms.py b/mediagoblin/submit/forms.py index e21b00ee..7ef3638f 100644 --- a/mediagoblin/submit/forms.py +++ b/mediagoblin/submit/forms.py @@ -27,7 +27,10 @@ class SubmitStartForm(wtforms.Form): _('Title'), [wtforms.validators.Length(min=0, max=500)]) description = wtforms.TextAreaField( - _('Description of this work')) + _('Description of this work'), + description=_("""You can use + + Markdown for formatting.""")) tags = wtforms.TextField( _('Tags'), [tag_length_validator], diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html index d52f544f..9b331789 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media.html @@ -96,7 +96,7 @@ user= media.get_uploader.username, media=media._id) }}" method="POST" id="form_comment">

    - {% trans %}Type your comment here. You can use Markdown for formatting.{% endtrans %} + {% trans %}Type your comment here. You can use Markdown for formatting.{% endtrans %}

    {{ wtforms_util.render_divs(comment_form) }}
    diff --git a/mediagoblin/templates/mediagoblin/utils/wtforms.html b/mediagoblin/templates/mediagoblin/utils/wtforms.html index cc30388f..3517b5c3 100644 --- a/mediagoblin/templates/mediagoblin/utils/wtforms.html +++ b/mediagoblin/templates/mediagoblin/utils/wtforms.html @@ -29,7 +29,7 @@ {% endfor %} {%- endif %} {% if field.description -%} -

    {{ _(field.description) }}

    +

    {{ _(field.description)|safe }}

    {%- endif %}
    {%- endmacro %} From 6a59a8abd49d921c2316fb4bd4cddf55a322b2fb Mon Sep 17 00:00:00 2001 From: Elrond Date: Mon, 2 Jan 2012 16:02:02 +0100 Subject: [PATCH 264/302] Import MigrationManager from mongo in mongo backend. Inside the mongo db backend, use the mongo MigrationManager. This is hopefully the last reference to the generic MigrationManager reference on db.util. --- mediagoblin/db/mongo/open.py | 2 +- mediagoblin/db/util.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mediagoblin/db/mongo/open.py b/mediagoblin/db/mongo/open.py index 8016ced9..48c909d9 100644 --- a/mediagoblin/db/mongo/open.py +++ b/mediagoblin/db/mongo/open.py @@ -18,7 +18,7 @@ import pymongo import mongokit from paste.deploy.converters import asint from mediagoblin.db.mongo import models -from mediagoblin.db.util import MigrationManager +from mediagoblin.db.mongo.util import MigrationManager def connect_database_from_config(app_config, use_pymongo=False): diff --git a/mediagoblin/db/util.py b/mediagoblin/db/util.py index 3fd96a1d..1df9494c 100644 --- a/mediagoblin/db/util.py +++ b/mediagoblin/db/util.py @@ -14,5 +14,5 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -from mediagoblin.db.mongo.util import (MigrationManager, ObjectId, InvalidId, +from mediagoblin.db.mongo.util import (ObjectId, InvalidId, DESCENDING) From f1cdd278e7cf195e485567ed0d0d8a90cad81e48 Mon Sep 17 00:00:00 2001 From: Elrond Date: Wed, 4 Jan 2012 23:48:55 +0100 Subject: [PATCH 265/302] f691: Use StrictUndefined for templates and fix some issues References to undefined variables in templates were silently ignored/converted to None/empty strings. This makes coding lazy stuff easy, but it makes catching typos harder. (It would have catched one of the SQL things earlier!) But on the other hand it might make the current templates error out everywhere. In fact, early testing has shown two instances, that errored out. Those are fixed with this commit too. If this turns out to make things more complex and useless than actually solving any problems, it can easily be dropped again. --- mediagoblin/templates/mediagoblin/user_pages/media.html | 5 +++-- mediagoblin/templates/mediagoblin/user_pages/user.html | 3 ++- mediagoblin/tools/template.py | 3 +++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html index 9b331789..4b5c9337 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media.html @@ -60,8 +60,9 @@ {% trans date=media.created.strftime("%Y-%m-%d") -%} Added on {{ date }}. {%- endtrans %} - {% if media['uploader'] == request.user._id or - request.user['is_admin'] %} + {% if request.user and + (media.uploader == request.user._id or + request.user.is_admin) %} {% set edit_url = request.urlgen('mediagoblin.edit.edit_media', user= media.get_uploader.username, media= media._id) %} diff --git a/mediagoblin/templates/mediagoblin/user_pages/user.html b/mediagoblin/templates/mediagoblin/user_pages/user.html index b952e88c..78bbaf8c 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/user.html +++ b/mediagoblin/templates/mediagoblin/user_pages/user.html @@ -113,7 +113,8 @@ {% else %}
    {% include "mediagoblin/utils/profile.html" %} - {% if request.user._id == user._id or request.user.is_admin %} + {% if request.user and + (request.user._id == user._id or request.user.is_admin) %} {%- trans %}Edit profile{% endtrans -%} diff --git a/mediagoblin/tools/template.py b/mediagoblin/tools/template.py index d0400347..54a40de6 100644 --- a/mediagoblin/tools/template.py +++ b/mediagoblin/tools/template.py @@ -41,8 +41,11 @@ def get_jinja_env(template_loader, locale): if SETUP_JINJA_ENVS.has_key(locale): return SETUP_JINJA_ENVS[locale] + # jinja2.StrictUndefined will give exceptions on references + # to undefined/unknown variables in templates. template_env = jinja2.Environment( loader=template_loader, autoescape=True, + undefined=jinja2.StrictUndefined, extensions=['jinja2.ext.i18n', 'jinja2.ext.autoescape']) template_env.install_gettext_callables( From c8071fa591ad148fbffdabc4d6dd71f5666c2172 Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Thu, 5 Jan 2012 00:17:45 +0100 Subject: [PATCH 266/302] Create edit_account.html --- mediagoblin/edit/forms.py | 23 +++++----- mediagoblin/edit/routing.py | 5 ++- mediagoblin/edit/views.py | 40 +++++++++++++---- .../mediagoblin/edit/edit_account.html | 45 +++++++++++++++++++ 4 files changed, 92 insertions(+), 21 deletions(-) create mode 100644 mediagoblin/templates/mediagoblin/edit/edit_account.html diff --git a/mediagoblin/edit/forms.py b/mediagoblin/edit/forms.py index 406de3f8..df219011 100644 --- a/mediagoblin/edit/forms.py +++ b/mediagoblin/edit/forms.py @@ -37,7 +37,7 @@ class EditForm(wtforms.Form): _('Slug'), [wtforms.validators.Required(message=_("The slug can't be empty"))], description=_( - "The title part of this media's URL. " + "The title part of this media's address. " "You usually don't need to change this.")) @@ -52,20 +52,19 @@ class EditProfileForm(wtforms.Form): url = wtforms.TextField( _('Website'), [wtforms.validators.Optional(), - wtforms.validators.URL(message='Improperly formed URL')]) + wtforms.validators.URL(message="""This address contains errors""")]) + + +class EditAccountForm(wtforms.Form): old_password = wtforms.PasswordField( _('Old password'), - [wtforms.validators.Optional()]) + [wtforms.validators.Required()], + description=_( + "Enter your old password to prove you own this account.")) new_password = wtforms.PasswordField( - _('New Password'), - [wtforms.validators.Optional(), - wtforms.validators.Length(min=6, max=30), - wtforms.validators.EqualTo( - 'confirm_password', - 'Passwords must match.')]) - confirm_password = wtforms.PasswordField( - 'Confirm password', - [wtforms.validators.Optional()]) + _('New password'), + [wtforms.validators.Required(), + wtforms.validators.Length(min=6, max=30)]) class EditAttachmentsForm(wtforms.Form): diff --git a/mediagoblin/edit/routing.py b/mediagoblin/edit/routing.py index 34e9fd80..5216f7ca 100644 --- a/mediagoblin/edit/routing.py +++ b/mediagoblin/edit/routing.py @@ -20,4 +20,7 @@ from routes.route import Route edit_routes = [ # Media editing view handled in user_pages/routing.py Route('mediagoblin.edit.profile', '/profile/', - controller="mediagoblin.edit.views:edit_profile")] + controller="mediagoblin.edit.views:edit_profile"), + Route('mediagoblin.edit.account', '/account/', + controller="mediagoblin.edit.views:edit_account") + ] diff --git a/mediagoblin/edit/views.py b/mediagoblin/edit/views.py index 4cb98c15..bae85c5d 100644 --- a/mediagoblin/edit/views.py +++ b/mediagoblin/edit/views.py @@ -161,6 +161,35 @@ def edit_profile(request): url=user.get('url'), bio=user.get('bio')) + if request.method == 'POST' and form.validate(): + user.url = unicode(request.POST['url']) + user.bio = unicode(request.POST['bio']) + + user.bio_html = cleaned_markdown_conversion(user['bio']) + + user.save() + + messages.add_message(request, + messages.SUCCESS, + _("Profile changes saved")) + return redirect(request, + 'mediagoblin.user_pages.user_home', + user=user['username']) + + return render_to_response( + request, + 'mediagoblin/edit/edit_profile.html', + {'user': user, + 'form': form}) + + +@require_active_login +def edit_account(request): + edit_username = request.GET.get('username') + user = request.user + + form = forms.EditAccountForm(request.POST) + if request.method == 'POST' and form.validate(): password_matches = auth_lib.bcrypt_check_password( request.POST['old_password'], @@ -172,30 +201,25 @@ def edit_profile(request): return render_to_response( request, - 'mediagoblin/edit/edit_profile.html', + 'mediagoblin/edit/edit_account.html', {'user': user, 'form': form}) - user.url = unicode(request.POST['url']) - user.bio = unicode(request.POST['bio']) - if password_matches: user['pw_hash'] = auth_lib.bcrypt_gen_password_hash( request.POST['new_password']) - user.bio_html = cleaned_markdown_conversion(user['bio']) - user.save() messages.add_message(request, messages.SUCCESS, - _("Profile edited!")) + _("Account settings saved")) return redirect(request, 'mediagoblin.user_pages.user_home', user=user['username']) return render_to_response( request, - 'mediagoblin/edit/edit_profile.html', + 'mediagoblin/edit/edit_account.html', {'user': user, 'form': form}) diff --git a/mediagoblin/templates/mediagoblin/edit/edit_account.html b/mediagoblin/templates/mediagoblin/edit/edit_account.html new file mode 100644 index 00000000..0a564161 --- /dev/null +++ b/mediagoblin/templates/mediagoblin/edit/edit_account.html @@ -0,0 +1,45 @@ +{# +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +#} +{% extends "mediagoblin/base.html" %} + +{% import "/mediagoblin/utils/wtforms.html" as wtforms_util %} + +{% block mediagoblin_head %} + +{% endblock mediagoblin_head %} + +{% block mediagoblin_content %} + + +
    +

    + {%- trans username=user.username -%} + Changing {{ username }}'s account settings + {%- endtrans %} +

    + {{ wtforms_util.render_divs(form) }} +
    + + {{ csrf_token }} +
    +
    + +{% endblock %} From 1c53f98c09a5ccd7acd320be8230d8980fc77dea Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Thu, 5 Jan 2012 00:18:29 +0100 Subject: [PATCH 267/302] Add change-account-settings link to user.html --- mediagoblin/templates/mediagoblin/user_pages/user.html | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mediagoblin/templates/mediagoblin/user_pages/user.html b/mediagoblin/templates/mediagoblin/user_pages/user.html index 78bbaf8c..c93db8b0 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/user.html +++ b/mediagoblin/templates/mediagoblin/user_pages/user.html @@ -120,6 +120,11 @@ {%- trans %}Edit profile{% endtrans -%}
    {% endif %} + {% if request.user._id == user._id %} + + {%- trans %}Change account settings{% endtrans -%} + + {% endif %}
    {% endif %} From 4a24500aa43fcf5bca59c12049af34b7935977a0 Mon Sep 17 00:00:00 2001 From: Elrond Date: Thu, 5 Jan 2012 14:46:27 +0100 Subject: [PATCH 268/302] Fix more StrictUndefined issues --- mediagoblin/templates/mediagoblin/user_pages/user.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mediagoblin/templates/mediagoblin/user_pages/user.html b/mediagoblin/templates/mediagoblin/user_pages/user.html index c93db8b0..6b5c2b21 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/user.html +++ b/mediagoblin/templates/mediagoblin/user_pages/user.html @@ -90,7 +90,7 @@

    {% if not user.url and not user.bio %} - {% if request.user._id == user._id %} + {% if request.user and (request.user._id == user._id) %}

    {% trans %}Here's a spot to tell others about yourself.{% endtrans %} @@ -120,7 +120,7 @@ {%- trans %}Edit profile{% endtrans -%} {% endif %} - {% if request.user._id == user._id %} + {% if request.user and (request.user._id == user._id) %} {%- trans %}Change account settings{% endtrans -%} From 49af00e491a7ec6b920a3780254f2203ae47fbe5 Mon Sep 17 00:00:00 2001 From: Elrond Date: Thu, 5 Jan 2012 14:47:15 +0100 Subject: [PATCH 269/302] Make show-password-js work for change password too The show password js depends on the password field to have an id of "password". So give it a proper id. Also fixed the label generation for the case of field.name and field.id being different. --- mediagoblin/edit/forms.py | 3 ++- mediagoblin/templates/mediagoblin/utils/wtforms.html | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/mediagoblin/edit/forms.py b/mediagoblin/edit/forms.py index df219011..09955874 100644 --- a/mediagoblin/edit/forms.py +++ b/mediagoblin/edit/forms.py @@ -64,7 +64,8 @@ class EditAccountForm(wtforms.Form): new_password = wtforms.PasswordField( _('New password'), [wtforms.validators.Required(), - wtforms.validators.Length(min=6, max=30)]) + wtforms.validators.Length(min=6, max=30)], + id="password") class EditAttachmentsForm(wtforms.Form): diff --git a/mediagoblin/templates/mediagoblin/utils/wtforms.html b/mediagoblin/templates/mediagoblin/utils/wtforms.html index 3517b5c3..44b27bb8 100644 --- a/mediagoblin/templates/mediagoblin/utils/wtforms.html +++ b/mediagoblin/templates/mediagoblin/utils/wtforms.html @@ -19,7 +19,7 @@ {# Generically render a field #} {% macro render_field_div(field) %} {% if field.label.text -%} -

    +

    {%- endif %}
    {{ field }} From b48abba3036bb08ad05c469bc37481cc16420ed8 Mon Sep 17 00:00:00 2001 From: Elrond Date: Thu, 5 Jan 2012 14:54:03 +0100 Subject: [PATCH 270/302] Fix Unit Tests for new password changing --- mediagoblin/tests/test_edit.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/mediagoblin/tests/test_edit.py b/mediagoblin/tests/test_edit.py index 0cf71e9b..55f34b42 100644 --- a/mediagoblin/tests/test_edit.py +++ b/mediagoblin/tests/test_edit.py @@ -34,12 +34,10 @@ def test_change_password(test_app): # test that the password can be changed # template.clear_test_template_context() test_app.post( - '/edit/profile/', { - 'bio': u'', - 'url': u'', + '/edit/account/', { 'old_password': 'toast', 'new_password': '123456', - 'confirm_password': '123456'}) + }) # test_user has to be fetched again in order to have the current values test_user = mg_globals.database.User.one({'username': 'chris'}) @@ -50,12 +48,10 @@ def test_change_password(test_app): # is wrong # template.clear_test_template_context() test_app.post( - '/edit/profile/', { - 'bio': u'', - 'url': u'', + '/edit/account/', { 'old_password': 'toast', 'new_password': '098765', - 'confirm_password': '098765'}) + }) test_user = mg_globals.database.User.one({'username': 'chris'}) From 34b4090cbf1f6ea62b9127f0ac96e748ad22b668 Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Thu, 5 Jan 2012 15:58:03 +0100 Subject: [PATCH 271/302] Always show 'Change account settings' link --- .../templates/mediagoblin/user_pages/user.html | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/mediagoblin/templates/mediagoblin/user_pages/user.html b/mediagoblin/templates/mediagoblin/user_pages/user.html index 6b5c2b21..a50849b0 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/user.html +++ b/mediagoblin/templates/mediagoblin/user_pages/user.html @@ -100,7 +100,6 @@ class="button_action"> {%- trans %}Edit profile{% endtrans -%} -
    {% else %}

    @@ -108,7 +107,6 @@ This user hasn't filled in their profile (yet). {%- endtrans %}

    -
    {% endif %} {% else %}
    @@ -120,11 +118,12 @@ {%- trans %}Edit profile{% endtrans -%} {% endif %} - {% if request.user and (request.user._id == user._id) %} - - {%- trans %}Change account settings{% endtrans -%} - - {% endif %} + {% endif %} + + {% if request.user and (request.user._id == user._id) %} + + {%- trans %}Change account settings{% endtrans -%} +
    {% endif %} From 7df9f45c32d7fd2ae5ae6c137ebf96437f764323 Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Thu, 5 Jan 2012 21:36:24 +0100 Subject: [PATCH 272/302] Several changes for mobile layout --- mediagoblin/static/css/base.css | 32 ++++++--------------- mediagoblin/templates/mediagoblin/base.html | 1 + mediagoblin/templates/mediagoblin/root.html | 2 +- 3 files changed, 11 insertions(+), 24 deletions(-) diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css index 8ed94e36..e89ce8a2 100644 --- a/mediagoblin/static/css/base.css +++ b/mediagoblin/static/css/base.css @@ -85,18 +85,14 @@ input, textarea { /* website structure */ .mediagoblin_body { - position: relative; - min-height: 100%; - margin-left: auto; - margin-right: auto; - width: 960px; + margin: auto; + width: 96%; + max-width: 960px; } .mediagoblin_header { width: 100%; height: 36px; - margin-left: 10px; - margin-right: 10px; padding-top: 14px; margin-bottom: 20px; border-bottom: 1px solid #333; @@ -118,16 +114,12 @@ a.mediagoblin_logo { .mediagoblin_content { width: 100%; - margin-left: 10px; - margin-right: 10px; padding-bottom: 74px; } .mediagoblin_footer { width: 100%; height: 30px; - margin-left: 10px; - margin-right: 10px; border-top: 1px solid #333; bottom: 0px; padding-top: 8px; @@ -253,16 +245,17 @@ text-align: center; background-color: #222; background-image: url("../images/background_lines.png"); background-repeat: repeat-x; - width: 340px; - padding: 30px 60px; - margin-left: auto; - margin-right: auto; + padding: 3% 5%; display: block; float: none; + width: 90%; + max-width: 340px; + margin-left: auto; + margin-right: auto; } .form_box_xl { - width: 460px; + max-width: 460px; } .edit_box { @@ -452,15 +445,8 @@ table.media_panel th { @media screen and (max-width: 960px) { .mediagoblin_body { - width: 100%; } .mediagoblin_footer { - position: fixed; - left: 0px; - top: 100px; - width: 50px; - height: 20px; - background-color: #f00; } } diff --git a/mediagoblin/templates/mediagoblin/base.html b/mediagoblin/templates/mediagoblin/base.html index 870a4861..f3912752 100644 --- a/mediagoblin/templates/mediagoblin/base.html +++ b/mediagoblin/templates/mediagoblin/base.html @@ -19,6 +19,7 @@ + {% block title %}{{ app_config['html_title'] }}{% endblock %} diff --git a/mediagoblin/templates/mediagoblin/root.html b/mediagoblin/templates/mediagoblin/root.html index 300570ad..3f834572 100644 --- a/mediagoblin/templates/mediagoblin/root.html +++ b/mediagoblin/templates/mediagoblin/root.html @@ -23,8 +23,8 @@ {% if request.user %}

    {% trans %}Explore{% endtrans %}

    {% else %} -

    {% trans %}Hi there, welcome to this MediaGoblin site!{% endtrans %}

    +

    {% trans %}This site is running MediaGoblin, an extraordinarily great piece of media hosting software.{% endtrans %}

    {% trans %}To add your own media, place comments, save your favourites and more, you can log in with your MediaGoblin account.{% endtrans %}

    {% if allow_registration %} From ee0b9ea282cf5d0ee3f8743477ec61e6b408b9da Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Thu, 5 Jan 2012 21:52:28 +0100 Subject: [PATCH 273/302] Remove last 960.gs leftover; fix classes for edit forms --- mediagoblin/templates/mediagoblin/edit/edit.html | 4 ++-- mediagoblin/templates/mediagoblin/edit/edit_account.html | 2 +- mediagoblin/templates/mediagoblin/edit/edit_profile.html | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mediagoblin/templates/mediagoblin/edit/edit.html b/mediagoblin/templates/mediagoblin/edit/edit.html index 14200466..fc6b1605 100644 --- a/mediagoblin/templates/mediagoblin/edit/edit.html +++ b/mediagoblin/templates/mediagoblin/edit/edit.html @@ -25,7 +25,7 @@ user= media.get_uploader.username, media= media._id) }}" method="POST" enctype="multipart/form-data"> -
    +

    {% trans media_title=media.title %}Editing {{ media_title }}{% endtrans %}

    -
    +

    {%- trans username=user.username -%} Changing {{ username }}'s account settings diff --git a/mediagoblin/templates/mediagoblin/edit/edit_profile.html b/mediagoblin/templates/mediagoblin/edit/edit_profile.html index d6461757..97c03e37 100644 --- a/mediagoblin/templates/mediagoblin/edit/edit_profile.html +++ b/mediagoblin/templates/mediagoblin/edit/edit_profile.html @@ -24,7 +24,7 @@
    -
    +

    {%- trans username=user.username -%} Editing {{ username }}'s profile From a91e4e07e716891b95b5f91b86d123fd9a221525 Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Thu, 5 Jan 2012 22:46:21 +0100 Subject: [PATCH 274/302] Add closing bracket so the whole thing doesn't break down --- mediagoblin/static/css/base.css | 1 + 1 file changed, 1 insertion(+) diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css index f4359791..d8fc86bf 100644 --- a/mediagoblin/static/css/base.css +++ b/mediagoblin/static/css/base.css @@ -237,6 +237,7 @@ textarea#comment_content { border: none; background-color: #f1f1f1; padding: 3px; +} .clear { clear: both; From 7945cd21ba6aa7063fc54bc6f91457a3be65ecb3 Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Thu, 5 Jan 2012 23:36:16 +0100 Subject: [PATCH 275/302] * Rename mediagoblin_header, mediagoblin_body, mediagoblin_footer, mediagoblin_header_right, mediagoblin_logo * Add html5shiv for older browsers * Small size fix (940px instead of 960pgx) --- extlib/html5shiv/MIT.txt | 20 +++++++++++++++++ extlib/html5shiv/html5shiv.js | 3 +++ mediagoblin/static/css/base.css | 14 ++++++------ mediagoblin/static/js/extlib/html5shiv.js | 1 + mediagoblin/templates/mediagoblin/base.html | 24 +++++++++++---------- 5 files changed, 44 insertions(+), 18 deletions(-) create mode 100644 extlib/html5shiv/MIT.txt create mode 100644 extlib/html5shiv/html5shiv.js create mode 120000 mediagoblin/static/js/extlib/html5shiv.js diff --git a/extlib/html5shiv/MIT.txt b/extlib/html5shiv/MIT.txt new file mode 100644 index 00000000..5a2aeb47 --- /dev/null +++ b/extlib/html5shiv/MIT.txt @@ -0,0 +1,20 @@ +Copyright (c) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/extlib/html5shiv/html5shiv.js b/extlib/html5shiv/html5shiv.js new file mode 100644 index 00000000..8de0ff54 --- /dev/null +++ b/extlib/html5shiv/html5shiv.js @@ -0,0 +1,3 @@ +// HTML5 Shiv v3 | @jon_neal @afarkas @rem | MIT/GPL2 Licensed +// Uncompressed source: https://github.com/aFarkas/html5shiv +(function(a,b){var c=function(a){return a.innerHTML="",a.childNodes.length===1}(b.createElement("a")),d=function(a,b,c){return b.appendChild(a),(c=(c?c(a):a.currentStyle).display)&&b.removeChild(a)&&c==="block"}(b.createElement("nav"),b.documentElement,a.getComputedStyle),e={elements:"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video".split(" "),shivDocument:function(a){a=a||b;if(a.documentShived)return;a.documentShived=!0;var f=a.createElement,g=a.createDocumentFragment,h=a.getElementsByTagName("head")[0],i=function(a){f(a)};c||(e.elements.join(" ").replace(/\w+/g,i),a.createElement=function(a){var b=f(a);return b.canHaveChildren&&e.shivDocument(b.document),b},a.createDocumentFragment=function(){return e.shivDocument(g())});if(!d&&h){var j=f("div");j.innerHTML=["x"].join(""),h.insertBefore(j.lastChild,h.firstChild)}return a}};e.shivDocument(b),a.html5=e})(this,document) \ No newline at end of file diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css index d8fc86bf..54de5a5b 100644 --- a/mediagoblin/static/css/base.css +++ b/mediagoblin/static/css/base.css @@ -84,13 +84,13 @@ input, textarea { /* website structure */ -.mediagoblin_body { +.container { margin: auto; width: 96%; - max-width: 960px; + max-width: 940px; } -.mediagoblin_header { +header { width: 100%; height: 36px; padding-top: 14px; @@ -98,17 +98,17 @@ input, textarea { border-bottom: 1px solid #333; } -.mediagoblin_header_right { +.header_right { float: right; } -a.mediagoblin_logo { +a.logo { color: #fff; font-weight: bold; margin-right: 8px; } -.mediagoblin_logo img { +.logo img { vertical-align: middle; } @@ -117,7 +117,7 @@ a.mediagoblin_logo { padding-bottom: 74px; } -.mediagoblin_footer { +footer { width: 100%; height: 30px; border-top: 1px solid #333; diff --git a/mediagoblin/static/js/extlib/html5shiv.js b/mediagoblin/static/js/extlib/html5shiv.js new file mode 120000 index 00000000..ca7358c7 --- /dev/null +++ b/mediagoblin/static/js/extlib/html5shiv.js @@ -0,0 +1 @@ +../../../../extlib/html5shiv/html5shiv.js \ No newline at end of file diff --git a/mediagoblin/templates/mediagoblin/base.html b/mediagoblin/templates/mediagoblin/base.html index f3912752..82ee41b7 100644 --- a/mediagoblin/templates/mediagoblin/base.html +++ b/mediagoblin/templates/mediagoblin/base.html @@ -29,22 +29,24 @@ href="{{ request.staticdirect('/css/video-js.css') }}"/> - + + {% block mediagoblin_head %} {% endblock mediagoblin_head %} {% block mediagoblin_body %} -
    +
    {% block mediagoblin_header %} -
    +
    {% block mediagoblin_logo %} - - {% endblock %} + {% endblock mediagoblin_logo %} {% if request.user and request.user.status == 'active' %} @@ -52,7 +54,7 @@ {% endif %} {% block mediagoblin_header_title %}{% endblock %} -
    +
    {% if request.user %} {# the following link should only appear when verification is needed #} {% if request.user.status == "needs_email_verification" %} @@ -72,7 +74,7 @@ {% trans %}Log in{% endtrans %} {% endif %}
    -
    +
    {% endblock %}
    {% include "mediagoblin/utils/messages.html" %} @@ -80,12 +82,12 @@ {% endblock mediagoblin_content %}
    {% block mediagoblin_footer %} - - {% endblock %} + + {% endblock mediagoblin_footer %} {% endblock mediagoblin_body %}
    From 173999a7e44aac11c8a2d4a7bf61f709b3822f79 Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Fri, 6 Jan 2012 13:34:25 +0100 Subject: [PATCH 276/302] Resize image below 660px width --- mediagoblin/static/css/base.css | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css index 54de5a5b..eac956f1 100644 --- a/mediagoblin/static/css/base.css +++ b/mediagoblin/static/css/base.css @@ -479,3 +479,12 @@ table.media_panel th { font-family: Inconsolata, monospace; line-height: 1em; } + +@media screen and (max-width: 660px) { + .media_pane { + width: 100%; + } + img.media_image { + width: 100%; + } +} From 7646e695bfbfc403deecdf3068abd3b453d6fef0 Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Fri, 6 Jan 2012 13:44:00 +0100 Subject: [PATCH 277/302] Fix div breaking in user.html; add media query bits --- mediagoblin/static/css/base.css | 15 ++++++++++++++- .../templates/mediagoblin/user_pages/user.html | 6 +++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css index eac956f1..c2d45a1b 100644 --- a/mediagoblin/static/css/base.css +++ b/mediagoblin/static/css/base.css @@ -480,11 +480,24 @@ table.media_panel th { line-height: 1em; } -@media screen and (max-width: 660px) { +/* Media queries and other responsivisivity */ +@media screen and (max-width: 680px) { .media_pane { width: 100%; + margin: 0px; } img.media_image { width: 100%; } } + +@media screen and (max-width: 960px) { + .profile_sidebar { + width: 100%; + margin: 0px; + } + .profile_showcase { + width: 100%; + margin: 0px; + } +} diff --git a/mediagoblin/templates/mediagoblin/user_pages/user.html b/mediagoblin/templates/mediagoblin/user_pages/user.html index c8eb9026..0937f97a 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/user.html +++ b/mediagoblin/templates/mediagoblin/user_pages/user.html @@ -120,12 +120,12 @@ {% endif %} {% endif %} - {% if request.user and (request.user._id == user._id) %} + {% if request.user and (request.user._id == user._id) %} {%- trans %}Change account settings{% endtrans -%} -
    - {% endif %} + {% endif %} +
    {% if media_entries.count() %}
    From b957cba0cb9b6de33f9d50001a381ea94d9de57a Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Fri, 6 Jan 2012 19:56:50 +0100 Subject: [PATCH 278/302] First push with new style (includes css file, logo image, fonts) --- docs/source/conf.py | 2 +- .../themes/mg/static/fonts/Lato-Bold.ttf | Bin 0 -> 93224 bytes .../mg/static/fonts/Lato-BoldItalic.ttf | Bin 0 -> 81936 bytes .../themes/mg/static/fonts/Lato-Italic.ttf | Bin 0 -> 83680 bytes .../themes/mg/static/fonts/Lato-Regular.ttf | Bin 0 -> 96044 bytes .../source/themes/mg/static/fonts/OFL_1.1.txt | 97 ++++++++++++ docs/source/themes/mg/static/logo_docs.png | Bin 0 -> 6522 bytes docs/source/themes/mg/static/mg.css | 145 ++++++++++++++++++ docs/source/themes/mg/theme.conf | 4 +- 9 files changed, 245 insertions(+), 3 deletions(-) create mode 100644 docs/source/themes/mg/static/fonts/Lato-Bold.ttf create mode 100644 docs/source/themes/mg/static/fonts/Lato-BoldItalic.ttf create mode 100644 docs/source/themes/mg/static/fonts/Lato-Italic.ttf create mode 100644 docs/source/themes/mg/static/fonts/Lato-Regular.ttf create mode 100644 docs/source/themes/mg/static/fonts/OFL_1.1.txt create mode 100644 docs/source/themes/mg/static/logo_docs.png create mode 100644 docs/source/themes/mg/static/mg.css diff --git a/docs/source/conf.py b/docs/source/conf.py index dce254a1..3014e592 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -111,7 +111,7 @@ html_theme_path = ['themes'] # The name of an image file (relative to this directory) to place at the top # of the sidebar. -#html_logo = None +html_logo = 'logo_docs.png' # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 diff --git a/docs/source/themes/mg/static/fonts/Lato-Bold.ttf b/docs/source/themes/mg/static/fonts/Lato-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..bc3529fce3ce3c38c29440908f8a7bdbae99af10 GIT binary patch literal 93224 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 literal 0 HcmV?d00001 diff --git a/docs/source/themes/mg/static/fonts/Lato-BoldItalic.ttf b/docs/source/themes/mg/static/fonts/Lato-BoldItalic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..2cf5ae0dda701a339c5d77de841e5385413e02be GIT binary patch literal 81936 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 z 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 z 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 V*IjqL3j^*gz8${pJ^r}a{$CA9G{OJ? literal 0 HcmV?d00001 diff --git a/docs/source/themes/mg/static/fonts/Lato-Italic.ttf b/docs/source/themes/mg/static/fonts/Lato-Italic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..11ca3eb6fe4043aab186d52b9c9c1fb15b567e6e GIT binary patch literal 83680 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 KH=cURZ2B)?SC`ZP literal 0 HcmV?d00001 diff --git a/docs/source/themes/mg/static/fonts/Lato-Regular.ttf b/docs/source/themes/mg/static/fonts/Lato-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..26ce10025a9bb380c268aefa8117357c70fb35a1 GIT binary patch literal 96044 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∾l0B9g!c;{5I!t?L{ENL7+FS)KE;-ue~ct7?bWgs+R%Z>apH@GaH6tux;dzAJoB-@cDF!Dh#hzCv)(OF*Z} zvFP0jAycf62d@@_i-<`&r%33X{5ooUc&b9^hkpk)!`D>^{csf6s`@rvXM=D=R~r@j zg_r9(R|t0t_Xzh2_X+n4Z`GB5ApD`O|EjL=n(%c!+Z!ssDSS&c@2UJgu26(`Tnuyy zUBU!BVG-i4o&y%@oDyNVunMzTMc{w_)+6*nGa$v6&iA3+il7_s2R2U*0$WwH27Frt zy+It&UAF5kqbiT7>{oeQS;hV5#`0RQyva z{z1AJP`p(9Q!4%`75|iqe@dZkUc$HJpHlG;<~_kbrQ)Ab@lUDvr_@6JDYcM)O3|J# z0?9w6(7i)_n*_{wcMPe~<}BS0MkC!isnfNd75> zz9o`>N}*#}CjXS-?fk%a^cqNAElg5P_T=|blOrsE-CKsYsxLdeK zxL3GOxL^3Xe*2d2ebiKgC!Youf@u#;KeFI)ww ztVaL-6mYGsJgD+^U4KkCF1%9LJRrPIc)joj;f=zZg@<(IdxiH2?-xEGd{}r`_^9wP z;p4(1!lS}xbhT$yep%1(itugWJHmH?H5Pl|Eud5A62@bmzXq+;2;_Rg8tAm201LtG zHE1znxzH{22)&d2sP{qYYoN!tM{DzBC9qXBY|k3CC-!kwnJrnPmaIV=9zc1mt~03e zh@ND-o?%qwF_rx)kE?v8&Oac$PI$fW2H}mun}xUPN!YeE7(o!(wlx?*5ZSgh7(o!( zwlx?*5ZSgh7(o!(wlx?*5TDUC*|s&%0DQ-n^*pZ#U)2-7CVXA3_lC-E3g1%A+dA_d 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 literal 0 HcmV?d00001 diff --git a/docs/source/themes/mg/static/fonts/OFL_1.1.txt b/docs/source/themes/mg/static/fonts/OFL_1.1.txt new file mode 100644 index 00000000..f1a20ac1 --- /dev/null +++ b/docs/source/themes/mg/static/fonts/OFL_1.1.txt @@ -0,0 +1,97 @@ +Copyright (c) , (), +with Reserved Font Name . +Copyright (c) , (), +with Reserved Font Name . +Copyright (c) , (). + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/docs/source/themes/mg/static/logo_docs.png b/docs/source/themes/mg/static/logo_docs.png new file mode 100644 index 0000000000000000000000000000000000000000..9287996512ef2daff97880d17b29d9501fb32a68 GIT binary patch literal 6522 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 literal 0 HcmV?d00001 diff --git a/docs/source/themes/mg/static/mg.css b/docs/source/themes/mg/static/mg.css new file mode 100644 index 00000000..3a0a1336 --- /dev/null +++ b/docs/source/themes/mg/static/mg.css @@ -0,0 +1,145 @@ +@import url("basic.css"); + +/* text fonts and styles */ + +@font-face { + font-family: 'Lato'; + font-style: normal; + font-weight: 700; + src: local('Lato Bold'), local('Lato-Bold'), url('fonts/Lato-Bold.ttf') format('truetype'); +} +@font-face { + font-family: 'Lato'; + font-style: italic; + font-weight: 400; + src: local('Lato Italic'), local('Lato-Italic'), url('fonts/Lato-Italic.ttf') format('truetype'); +} +@font-face { + font-family: 'Lato'; + font-style: italic; + font-weight: 700; + src: local('Lato Bold Italic'), local('Lato-BoldItalic'), url('fonts/Lato-BoldItalic.ttf') format('truetype'); +} +@font-face { + font-family: 'Lato'; + font-style: normal; + font-weight: 400; + src: local('Lato Regular'), local('Lato-Regular'), url('fonts/Lato-Regular.ttf') format('truetype'); +} + +body { + font: 16px 'Lato',Helvetica,Arial,sans-serif; + background-color: #FCFCFC; + color: #3C3C3C; + margin: 0; + padding: 0; +} + +h1, h2, h3, h4, h5, h6 { + border-bottom: 1px solid #CCCCCC; + background: none; + color: black; + font-weight: bold; + padding-bottom: 0.17em; + padding-top: 0.5em; +} + +h1 { + font-size: 1.875em; +} + +h2 { + font-size: 1.375em; +} + +h3, h4, h5, h6 { + font-size: 1.125em; +} + +p { + font-weight: normal; + margin: 0.4em 0 0.5em; +} + +a { + color: #499776; +} + +a:visited { + color: #2A5744; +} + +a:active { + color: #65D1A3; +} + +h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { + text-decoration: none; +} + +div.topic, pre { + background-color: #F1F1F1; + border: 1px dashed #ccc; + color: black; + line-height: 1.1em; + padding: 1em; +} + +code, tt { + font: 14px monospace,"Courier New"; + background-color: #FFFFDD; + border: thin solid #bbb; + padding-left: 5px; + padding-right: 5px; +} + +pre { + font: 14px monospace,"Courier New"; +} + +div.related a, div.related a:visited, div.related a:active { + color: #86D4B1; +} + +/* layout */ + +div.documentwrapper { + float: left; + width: 100%; +} + +div.bodywrapper { + margin: 60px 0 0 230px; +} + +div.body { + padding: 0 20px 30px 20px; +} + +div.footer { + width: 100%; + padding: 9px 0 9px 0; + text-align: center; + font-size: 75%; +} + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 20px; +} + +div.sphinxsidebar ul { + margin: 10px 10px 10px 0; + padding: 0; +} + +div.related { + line-height: 30px; + font-size: 90%; + width: 100%; + background-color: #161616; + color: #C3C3C3; +} + +p.logo { + margin-bottom: 20px; +} diff --git a/docs/source/themes/mg/theme.conf b/docs/source/themes/mg/theme.conf index f4fbd8cc..dd58038a 100644 --- a/docs/source/themes/mg/theme.conf +++ b/docs/source/themes/mg/theme.conf @@ -1,5 +1,5 @@ [theme] -inherit = default -stylesheet = default.css +inherit = basic +stylesheet = mg.css pygments_style = sphinx From 242509239fddf9ebb904dc9c174da522f3bdc8b7 Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Fri, 6 Jan 2012 23:58:43 +0100 Subject: [PATCH 279/302] New docs logo, small css changes --- docs/source/themes/mg/static/logo_docs.png | Bin 6522 -> 6626 bytes docs/source/themes/mg/static/mg.css | 6 +++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/source/themes/mg/static/logo_docs.png b/docs/source/themes/mg/static/logo_docs.png index 9287996512ef2daff97880d17b29d9501fb32a68..99f04cc7d7794c702e01742749bc64580ff0904f 100644 GIT binary patch delta 6625 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 delta 6520 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 Date: Sat, 7 Jan 2012 00:04:38 +0100 Subject: [PATCH 280/302] Increase docs sidebar width --- docs/source/themes/mg/static/mg.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/source/themes/mg/static/mg.css b/docs/source/themes/mg/static/mg.css index 3fa842cd..b9355a5d 100644 --- a/docs/source/themes/mg/static/mg.css +++ b/docs/source/themes/mg/static/mg.css @@ -123,6 +123,10 @@ div.footer { font-size: 75%; } +div.sphinxsidebar { + width: 240px; +} + div.sphinxsidebarwrapper { padding: 10px 5px 0 30px; } From 3a4d8b9713bb55e4ad831ad9da3f0f23d8aaed1c Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Sat, 7 Jan 2012 13:47:33 -0600 Subject: [PATCH 281/302] Committing present MediaGoblin translations before pushing extracted messages --- .../i18n/fr/LC_MESSAGES/mediagoblin.po | 27 +-- .../i18n/nl/LC_MESSAGES/mediagoblin.po | 170 +++++++++++------- .../i18n/zh_TW/LC_MESSAGES/mediagoblin.po | 28 +-- 3 files changed, 132 insertions(+), 93 deletions(-) diff --git a/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.po index 8d1e2711..ba5c639d 100644 --- a/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.po @@ -3,6 +3,7 @@ # This file is distributed under the same license as the PROJECT project. # # Translators: +# , 2011. # , 2011. # , 2011. # , 2011. @@ -14,8 +15,8 @@ msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://bugs.foocorp.net/projects/mediagoblin/issues\n" "POT-Creation-Date: 2011-12-04 10:24-0600\n" -"PO-Revision-Date: 2011-12-04 16:23+0000\n" -"Last-Translator: cwebber \n" +"PO-Revision-Date: 2011-12-29 17:39+0000\n" +"Last-Translator: ianux \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -109,7 +110,7 @@ msgstr "Tags" #: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 msgid "Seperate tags by commas." -msgstr "" +msgstr "Séparez les tags par des virgules." #: mediagoblin/edit/forms.py:33 msgid "Slug" @@ -253,6 +254,8 @@ msgid "" "This site is running MediaGoblin, an " "extraordinarily great piece of media hosting software." msgstr "" +"Ce site fait tourner MediaGoblin, un " +"logiciel d'hébergement de média extraordinairement génial." #: mediagoblin/templates/mediagoblin/root.html:29 msgid "" @@ -420,27 +423,27 @@ msgstr "Médias de %(username)s" #: mediagoblin/templates/mediagoblin/user_pages/media.html:57 #, python-format msgid "By %(username)s on %(date)s" -msgstr "" +msgstr "Par %(username)s le %(date)s" #: mediagoblin/templates/mediagoblin/user_pages/media.html:67 msgid "Post a comment" -msgstr "" +msgstr "Poster un commentaire" #: mediagoblin/templates/mediagoblin/user_pages/media.html:85 msgid "at" -msgstr "" +msgstr "à" #: mediagoblin/templates/mediagoblin/user_pages/media.html:102 msgid "Post comment!" -msgstr "" +msgstr "Poster le commentaire !" #: mediagoblin/templates/mediagoblin/user_pages/media.html:124 msgid "Edit" -msgstr "" +msgstr "Éditer" #: mediagoblin/templates/mediagoblin/user_pages/media.html:130 msgid "Delete" -msgstr "" +msgstr "Effacer" #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format @@ -578,7 +581,7 @@ msgstr "Anciens" #: mediagoblin/templates/mediagoblin/utils/pagination.html:50 msgid "Go to page:" -msgstr "" +msgstr "Aller à la page :" #: mediagoblin/templates/mediagoblin/utils/tags.html:20 msgid "Tagged with" @@ -598,11 +601,11 @@ msgstr "Je suis sûr de vouloir supprimer cela" #: mediagoblin/user_pages/views.py:155 msgid "Oops, your comment was empty." -msgstr "" +msgstr "Oups, votre commentaire était vide." #: mediagoblin/user_pages/views.py:161 msgid "Your comment has been posted!" -msgstr "" +msgstr "Votre commentaire a été posté !" #: mediagoblin/user_pages/views.py:183 msgid "You deleted the media." diff --git a/mediagoblin/i18n/nl/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/nl/LC_MESSAGES/mediagoblin.po index c1778676..7b63a859 100644 --- a/mediagoblin/i18n/nl/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/nl/LC_MESSAGES/mediagoblin.po @@ -3,14 +3,14 @@ # This file is distributed under the same license as the PROJECT project. # # Translators: -# , 2011. +# , 2011, 2012. msgid "" msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://bugs.foocorp.net/projects/mediagoblin/issues\n" "POT-Creation-Date: 2011-12-04 10:24-0600\n" -"PO-Revision-Date: 2011-12-04 16:23+0000\n" -"Last-Translator: cwebber \n" +"PO-Revision-Date: 2012-01-04 18:42+0000\n" +"Last-Translator: schendje \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -21,7 +21,7 @@ msgstr "" #: mediagoblin/processing.py:143 msgid "Invalid file given for media type." -msgstr "" +msgstr "Verkeerd bestandsformaat voor mediatype opgegeven." #: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 msgid "Username" @@ -41,7 +41,7 @@ msgstr "Bevestig wachtwoord" #: mediagoblin/auth/forms.py:39 msgid "Type it again here to make sure there are no spelling mistakes." -msgstr "" +msgstr "Typ het hier nog een keer om spelfouten te voorkomen." #: mediagoblin/auth/forms.py:42 msgid "Email address" @@ -57,7 +57,7 @@ msgstr "Sorry, er bestaat al een gebruiker met die naam." #: mediagoblin/auth/views.py:77 msgid "Sorry, a user with that email address already exists." -msgstr "" +msgstr "Sorry, een gebruiker met dat e-mailadres bestaat al." #: mediagoblin/auth/views.py:179 msgid "" @@ -74,10 +74,12 @@ msgstr "De verificatie sleutel of gebruikers-ID is onjuist" #: mediagoblin/auth/views.py:203 msgid "You must be logged in so we know who to send the email to!" msgstr "" +"Je moet ingelogd zijn, anders weten we niet waar we de e-mail naartoe moeten" +" sturen!" #: mediagoblin/auth/views.py:211 msgid "You've already verified your email address!" -msgstr "" +msgstr "Je hebt je e-mailadres al geverifieerd!" #: mediagoblin/auth/views.py:224 msgid "Resent your verification email." @@ -88,6 +90,8 @@ msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." msgstr "" +"Email kon niet verstuurd worden omdat je gebruikersnaam inactief is of omdat" +" je e-mailadres nog niet geverifieerd is." #: mediagoblin/edit/forms.py:24 mediagoblin/submit/forms.py:27 msgid "Title" @@ -99,20 +103,22 @@ msgstr "Etiket" #: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 msgid "Seperate tags by commas." -msgstr "" +msgstr "Scheidt labels met komma's." #: mediagoblin/edit/forms.py:33 msgid "Slug" -msgstr "" +msgstr "Slug" #: mediagoblin/edit/forms.py:34 msgid "The slug can't be empty" -msgstr "" +msgstr "De slug kan niet leeg zijn" #: mediagoblin/edit/forms.py:35 msgid "" "The title part of this media's URL. You usually don't need to change this." msgstr "" +"Het titeldeel van het adres van deze media. Meestal hoef je dit niet aan te " +"passen." #: mediagoblin/edit/forms.py:42 msgid "Bio" @@ -124,15 +130,15 @@ msgstr "Website" #: mediagoblin/edit/forms.py:49 msgid "Old password" -msgstr "" +msgstr "Oud wachtwoord" #: mediagoblin/edit/forms.py:52 msgid "New Password" -msgstr "" +msgstr "Nieuw wachtwoord" #: mediagoblin/edit/views.py:65 msgid "An entry with that slug already exists for this user." -msgstr "" +msgstr "Er bestaat al een met die slug voor deze gebruiker." #: mediagoblin/edit/views.py:86 msgid "You are editing another user's media. Proceed with caution." @@ -147,15 +153,15 @@ msgstr "" #: mediagoblin/edit/views.py:171 msgid "Wrong password" -msgstr "" +msgstr "Verkeerd wachtwoord" #: mediagoblin/edit/views.py:192 msgid "Profile edited!" -msgstr "" +msgstr "Profiel aangepast!" #: mediagoblin/media_types/__init__.py:65 msgid "Could not find any file extension in \"{filename}\"" -msgstr "" +msgstr "Kon geen bestandsformaat voor \"{filename}\" vinden" #: mediagoblin/submit/forms.py:25 msgid "File" @@ -163,7 +169,7 @@ msgstr "Bestand" #: mediagoblin/submit/forms.py:30 msgid "Description of this work" -msgstr "" +msgstr "Beschrijving van dit werk" #: mediagoblin/submit/views.py:49 msgid "You must provide a file." @@ -175,29 +181,31 @@ msgstr "Mooizo! Toegevoegd!" #: mediagoblin/submit/views.py:133 msgid "Invalid file type." -msgstr "" +msgstr "Ongeldig bestandstype" #: mediagoblin/templates/mediagoblin/404.html:21 msgid "Oops!" -msgstr "" +msgstr "Oeps!" #: mediagoblin/templates/mediagoblin/404.html:24 msgid "There doesn't seem to be a page at this address. Sorry!" -msgstr "" +msgstr "Het lijkt erop dat er geen pagina bestaat op dit adres. Sorry!" #: mediagoblin/templates/mediagoblin/404.html:26 msgid "" "If you're sure the address is correct, maybe the page you're looking for has" " been moved or deleted." msgstr "" +"Als je zeker weet dat het adres klopt is de pagina misschien verplaatst of " +"verwijderd." #: mediagoblin/templates/mediagoblin/404.html:32 msgid "Image of 404 goblin stressing out" -msgstr "" +msgstr "Afbeelding van de 404 goblin onder stress" #: mediagoblin/templates/mediagoblin/base.html:49 msgid "MediaGoblin logo" -msgstr "" +msgstr "MediaGoblin logo" #: mediagoblin/templates/mediagoblin/base.html:54 msgid "Submit media" @@ -205,11 +213,11 @@ msgstr "Voeg media toe" #: mediagoblin/templates/mediagoblin/base.html:65 msgid "Verify your email!" -msgstr "" +msgstr "Verifieer je e-mailadres!" #: mediagoblin/templates/mediagoblin/base.html:72 msgid "log out" -msgstr "" +msgstr "uitloggen" #: mediagoblin/templates/mediagoblin/base.html:75 #: mediagoblin/templates/mediagoblin/auth/login.html:27 @@ -222,30 +230,37 @@ msgid "" "Powered by MediaGoblin, a GNU project" msgstr "" +"Aangedreven door <a " +"href=\"http://mediagoblin.org\">MediaGoblin</a> , een <a " +"href=\"http://gnu.org/\">GNU-project</a>" #: mediagoblin/templates/mediagoblin/root.html:24 msgid "Explore" -msgstr "" +msgstr "Verkennen" #: mediagoblin/templates/mediagoblin/root.html:27 msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "" +msgstr "Hoi, welkom op deze MediaGoblin website!" #: mediagoblin/templates/mediagoblin/root.html:28 msgid "" "This site is running MediaGoblin, an " "extraordinarily great piece of media hosting software." msgstr "" +"Deze website draait MediaGoblin, een " +"buitengewoon goed stuk software voor mediahosting." #: mediagoblin/templates/mediagoblin/root.html:29 msgid "" "To add your own media, place comments, save your favourites and more, you " "can log in with your MediaGoblin account." msgstr "" +"Om je eigen media toe te voegen, berichten te plaatsen, favorieten op te " +"slaan en meer, kun je inloggen met je MediaGoblin account." #: mediagoblin/templates/mediagoblin/root.html:31 msgid "Don't have one yet? It's easy!" -msgstr "" +msgstr "Heb je er nog geen? Het is heel eenvoudig!" #: mediagoblin/templates/mediagoblin/root.html:32 #, python-format @@ -254,14 +269,17 @@ msgid "" " or\n" " Set up MediaGoblin on your own server" msgstr "" +"Creëer een account op deze website\n" +" of\n" +" Gebruik MediaGoblin op je eigen server" #: mediagoblin/templates/mediagoblin/root.html:44 msgid "Most recent media" -msgstr "" +msgstr "Nieuwste media" #: mediagoblin/templates/mediagoblin/auth/change_fp.html:29 msgid "Enter your new password" -msgstr "" +msgstr "Voer je nieuwe wachtwoord in" #: mediagoblin/templates/mediagoblin/auth/change_fp.html:33 #: mediagoblin/templates/mediagoblin/submit/start.html:30 @@ -270,20 +288,22 @@ msgstr "Voeg toe" #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" -msgstr "" +msgstr "Wachtwoord herstellen" #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:30 msgid "Send instructions" -msgstr "" +msgstr "Stuur instructies" #: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 msgid "Your password has been changed. Try to log in now." -msgstr "" +msgstr "Je wachtwoord is veranderd. Probeer om opnieuw in te loggen." #: mediagoblin/templates/mediagoblin/auth/fp_email_sent.html:22 msgid "" "Check your inbox. We sent an email with a URL for changing your password." msgstr "" +"Check je inbox. Er is een e-mail verstuurd waarmee je je wachtwoord kunt " +"veranderen." #: mediagoblin/templates/mediagoblin/auth/fp_verification_email.txt:19 #, python-format @@ -298,10 +318,17 @@ msgid "" "If you think this is an error, just ignore this email and continue being\n" "a happy goblin!" msgstr "" +"Hoi %(username)s,\n" +"\n" +"Om je wachtwoord voor GNU MediaGoblin te veranderen, moet je dit adres in je webbrowser openen:\n" +"\n" +"%(verification_url)s\n" +"\n" +"Als je denkt dat dit niet klopt, kun je deze e-mail gewoon negeren." #: mediagoblin/templates/mediagoblin/auth/login.html:30 msgid "Logging in failed!" -msgstr "" +msgstr "Inloggen is mislukt!" #: mediagoblin/templates/mediagoblin/auth/login.html:35 msgid "Don't have an account yet?" @@ -313,7 +340,7 @@ msgstr "Maak er hier een!" #: mediagoblin/templates/mediagoblin/auth/login.html:42 msgid "Forgot your password?" -msgstr "" +msgstr "Wachtwoord vergeten?" #: mediagoblin/templates/mediagoblin/auth/register.html:27 msgid "Create an account!" @@ -321,7 +348,7 @@ msgstr "Maak een account aan!" #: mediagoblin/templates/mediagoblin/auth/register.html:31 msgid "Create" -msgstr "" +msgstr "Creëer" #: mediagoblin/templates/mediagoblin/auth/verification_email.txt:19 #, python-format @@ -360,11 +387,11 @@ msgstr "Het profiel aanpassen van %(username)s" #: mediagoblin/templates/mediagoblin/listings/tag.html:35 #, python-format msgid "Media tagged with: %(tag_name)s" -msgstr "" +msgstr "Media met het label: %(tag_name)s" #: mediagoblin/templates/mediagoblin/media_displays/video.html:19 msgid "Original" -msgstr "" +msgstr "Origineel" #: mediagoblin/templates/mediagoblin/submit/start.html:26 msgid "Submit yer media" @@ -373,7 +400,7 @@ msgstr "Voeg media toe" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format msgid "%(username)s's media" -msgstr "" +msgstr "Media van %(username)s" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:37 #, python-format @@ -383,57 +410,57 @@ msgstr "Media van %(username)s " #: mediagoblin/templates/mediagoblin/user_pages/media.html:57 #, python-format msgid "By %(username)s on %(date)s" -msgstr "" +msgstr "Door %(username)s op %(date)s" #: mediagoblin/templates/mediagoblin/user_pages/media.html:67 msgid "Post a comment" -msgstr "" +msgstr "Plaats een bericht" #: mediagoblin/templates/mediagoblin/user_pages/media.html:85 msgid "at" -msgstr "" +msgstr "op" #: mediagoblin/templates/mediagoblin/user_pages/media.html:102 msgid "Post comment!" -msgstr "" +msgstr "Plaats bericht!" #: mediagoblin/templates/mediagoblin/user_pages/media.html:124 msgid "Edit" -msgstr "" +msgstr "Pas aan" #: mediagoblin/templates/mediagoblin/user_pages/media.html:130 msgid "Delete" -msgstr "" +msgstr "Verwijderen" #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" -msgstr "" +msgstr "Zeker weten dat je %(title)s wil verwijderen?" #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:50 msgid "Delete Permanently" -msgstr "" +msgstr "Permanent verwijderen" #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:22 msgid "Media processing panel" -msgstr "" +msgstr "Mediaverwerkingspaneel" #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:25 msgid "" "You can track the state of media being processed for your gallery here." -msgstr "" +msgstr "Hier kun je de status zien van de media die verwerkt worden." #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:28 msgid "Media in-processing" -msgstr "" +msgstr "Media te verwerken" #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:46 msgid "No media in-processing" -msgstr "" +msgstr "Geen media om te verwerken" #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:50 msgid "These uploads failed to process:" -msgstr "" +msgstr "Deze toevoegingen konden niet verwerkt worden:" #: mediagoblin/templates/mediagoblin/user_pages/user.html:31 #: mediagoblin/templates/mediagoblin/user_pages/user.html:89 @@ -448,11 +475,11 @@ msgstr "Sorry, die gebruiker kon niet worden gevonden." #: mediagoblin/templates/mediagoblin/user_pages/user.html:50 #: mediagoblin/templates/mediagoblin/user_pages/user.html:70 msgid "Email verification needed" -msgstr "" +msgstr "Emailverificatie is nodig" #: mediagoblin/templates/mediagoblin/user_pages/user.html:53 msgid "Almost done! Your account still needs to be activated." -msgstr "" +msgstr "Bijna klaar! Je account moet nog geactiveerd worden." #: mediagoblin/templates/mediagoblin/user_pages/user.html:58 msgid "" @@ -474,6 +501,8 @@ msgid "" "Someone has registered an account with this username, but it still has to be" " activated." msgstr "" +"Iemand heeft een account met deze gebruikersnaam gemaakt, maar hij moet nog " +"geactiveerd worden." #: mediagoblin/templates/mediagoblin/user_pages/user.html:79 #, python-format @@ -486,7 +515,7 @@ msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/user.html:96 msgid "Here's a spot to tell others about yourself." -msgstr "" +msgstr "Hier is een plekje om anderen over jezelf te vertellen." #: mediagoblin/templates/mediagoblin/user_pages/user.html:101 #: mediagoblin/templates/mediagoblin/user_pages/user.html:119 @@ -495,7 +524,7 @@ msgstr "Profiel aanpassen." #: mediagoblin/templates/mediagoblin/user_pages/user.html:107 msgid "This user hasn't filled in their profile (yet)." -msgstr "" +msgstr "Deze gebruiker heeft zijn of haar profiel (nog) niet ingevuld." #: mediagoblin/templates/mediagoblin/user_pages/user.html:133 #, python-format @@ -507,42 +536,44 @@ msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." msgstr "" +"Dit is waar je nieuwe media zal verschijnen, maar het lijkt erop dat je nog " +"niets heb toegevoegd." #: mediagoblin/templates/mediagoblin/user_pages/user.html:152 msgid "Add media" -msgstr "" +msgstr "Voeg media toe" #: mediagoblin/templates/mediagoblin/user_pages/user.html:158 msgid "There doesn't seem to be any media here yet..." -msgstr "" +msgstr "Het lijkt erop dat er nog geen media is." #: mediagoblin/templates/mediagoblin/utils/feed_link.html:21 msgid "feed icon" -msgstr "" +msgstr "feed icoon" #: mediagoblin/templates/mediagoblin/utils/feed_link.html:23 msgid "Atom feed" -msgstr "" +msgstr "Atom feed" #: mediagoblin/templates/mediagoblin/utils/pagination.html:40 msgid "Newer" -msgstr "" +msgstr "Nieuwer" #: mediagoblin/templates/mediagoblin/utils/pagination.html:46 msgid "Older" -msgstr "" +msgstr "Ouder" #: mediagoblin/templates/mediagoblin/utils/pagination.html:50 msgid "Go to page:" -msgstr "" +msgstr "Ga naar pagina:" #: mediagoblin/templates/mediagoblin/utils/tags.html:20 msgid "Tagged with" -msgstr "" +msgstr "Gelabeld met" #: mediagoblin/templates/mediagoblin/utils/tags.html:25 msgid "and" -msgstr "" +msgstr "en" #: mediagoblin/user_pages/forms.py:24 msgid "Comment" @@ -550,26 +581,29 @@ msgstr "Commentaar" #: mediagoblin/user_pages/forms.py:30 msgid "I am sure I want to delete this" -msgstr "" +msgstr "Ik weet zeker dat ik dit wil verwijderen." #: mediagoblin/user_pages/views.py:155 msgid "Oops, your comment was empty." -msgstr "" +msgstr "Oeps, je bericht was leeg." #: mediagoblin/user_pages/views.py:161 msgid "Your comment has been posted!" -msgstr "" +msgstr "Je bericht is geplaatst!" #: mediagoblin/user_pages/views.py:183 msgid "You deleted the media." -msgstr "" +msgstr "Je hebt deze media verwijderd." #: mediagoblin/user_pages/views.py:190 msgid "The media was not deleted because you didn't check that you were sure." msgstr "" +"Deze media was niet verwijderd omdat je niet hebt aangegeven dat je het " +"zeker weet." #: mediagoblin/user_pages/views.py:198 msgid "You are about to delete another user's media. Proceed with caution." msgstr "" +"Je staat op het punt de media van iemand anders te verwijderen. Pas op." diff --git a/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.po index 70622590..2864ef8a 100644 --- a/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.po @@ -4,14 +4,14 @@ # # Translators: # , 2011. -# Harry Chen , 2011. +# Harry Chen , 2011, 2012. msgid "" msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://bugs.foocorp.net/projects/mediagoblin/issues\n" "POT-Creation-Date: 2011-12-04 10:24-0600\n" -"PO-Revision-Date: 2011-12-04 16:23+0000\n" -"Last-Translator: cwebber \n" +"PO-Revision-Date: 2012-01-03 16:35+0000\n" +"Last-Translator: Harry Chen \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -98,7 +98,7 @@ msgstr "標籤" #: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 msgid "Seperate tags by commas." -msgstr "" +msgstr "用逗點分開標籤。" #: mediagoblin/edit/forms.py:33 msgid "Slug" @@ -234,6 +234,8 @@ msgid "" "This site is running MediaGoblin, an " "extraordinarily great piece of media hosting software." msgstr "" +"此網站正運行 媒體怪獸(MediaGoblin), " +"他是一個超讚的媒體分享架站軟體." #: mediagoblin/templates/mediagoblin/root.html:29 msgid "" @@ -394,27 +396,27 @@ msgstr "%(username)s的媒體檔案" #: mediagoblin/templates/mediagoblin/user_pages/media.html:57 #, python-format msgid "By %(username)s on %(date)s" -msgstr "" +msgstr "由 %(username)s 於 %(date)s" #: mediagoblin/templates/mediagoblin/user_pages/media.html:67 msgid "Post a comment" -msgstr "" +msgstr "刊登評論" #: mediagoblin/templates/mediagoblin/user_pages/media.html:85 msgid "at" -msgstr "" +msgstr "在" #: mediagoblin/templates/mediagoblin/user_pages/media.html:102 msgid "Post comment!" -msgstr "" +msgstr "刊登評論!" #: mediagoblin/templates/mediagoblin/user_pages/media.html:124 msgid "Edit" -msgstr "" +msgstr "編輯" #: mediagoblin/templates/mediagoblin/user_pages/media.html:130 msgid "Delete" -msgstr "" +msgstr "刪除" #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format @@ -541,7 +543,7 @@ msgstr "舊一點" #: mediagoblin/templates/mediagoblin/utils/pagination.html:50 msgid "Go to page:" -msgstr "" +msgstr "跳到頁數:" #: mediagoblin/templates/mediagoblin/utils/tags.html:20 msgid "Tagged with" @@ -561,11 +563,11 @@ msgstr "我確定我想要刪除" #: mediagoblin/user_pages/views.py:155 msgid "Oops, your comment was empty." -msgstr "" +msgstr "啊,你的留言是空的。" #: mediagoblin/user_pages/views.py:161 msgid "Your comment has been posted!" -msgstr "" +msgstr "你的留言已經刊登!" #: mediagoblin/user_pages/views.py:183 msgid "You deleted the media." From bcd50908d2849dff5a466b15db65112779cb85e2 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Sat, 7 Jan 2012 13:48:12 -0600 Subject: [PATCH 282/302] Committing extracted and compiled translations --- .../i18n/ar/LC_MESSAGES/mediagoblin.mo | Bin 12717 -> 14396 bytes .../i18n/ar/LC_MESSAGES/mediagoblin.po | 327 ++++++++------ .../i18n/ca/LC_MESSAGES/mediagoblin.mo | Bin 11505 -> 13397 bytes .../i18n/ca/LC_MESSAGES/mediagoblin.po | 319 ++++++++----- .../i18n/de/LC_MESSAGES/mediagoblin.mo | Bin 11802 -> 13692 bytes .../i18n/de/LC_MESSAGES/mediagoblin.po | 362 +++++++++------ .../i18n/en/LC_MESSAGES/mediagoblin.po | 312 ++++++++----- .../i18n/eo/LC_MESSAGES/mediagoblin.mo | Bin 11749 -> 13543 bytes .../i18n/eo/LC_MESSAGES/mediagoblin.po | 348 ++++++++------ .../i18n/es/LC_MESSAGES/mediagoblin.mo | Bin 12120 -> 13891 bytes .../i18n/es/LC_MESSAGES/mediagoblin.po | 349 +++++++++------ .../i18n/fr/LC_MESSAGES/mediagoblin.mo | Bin 12304 -> 12357 bytes .../i18n/ia/LC_MESSAGES/mediagoblin.mo | Bin 11238 -> 13161 bytes .../i18n/ia/LC_MESSAGES/mediagoblin.po | 311 ++++++++----- .../i18n/it/LC_MESSAGES/mediagoblin.mo | Bin 11622 -> 13574 bytes .../i18n/it/LC_MESSAGES/mediagoblin.po | 371 +++++++++------ .../i18n/ja/LC_MESSAGES/mediagoblin.mo | Bin 11879 -> 13736 bytes .../i18n/ja/LC_MESSAGES/mediagoblin.po | 317 ++++++++----- .../i18n/nl/LC_MESSAGES/mediagoblin.mo | Bin 11394 -> 11670 bytes .../i18n/nn_NO/LC_MESSAGES/mediagoblin.mo | Bin 10933 -> 12901 bytes .../i18n/nn_NO/LC_MESSAGES/mediagoblin.po | 329 ++++++++------ .../i18n/pt_BR/LC_MESSAGES/mediagoblin.mo | Bin 11350 -> 13279 bytes .../i18n/pt_BR/LC_MESSAGES/mediagoblin.po | 341 ++++++++------ .../i18n/ro/LC_MESSAGES/mediagoblin.mo | Bin 11882 -> 13685 bytes .../i18n/ro/LC_MESSAGES/mediagoblin.po | 348 ++++++++------ .../i18n/ru/LC_MESSAGES/mediagoblin.mo | Bin 15457 -> 16681 bytes .../i18n/ru/LC_MESSAGES/mediagoblin.po | 348 ++++++++------ .../i18n/sk/LC_MESSAGES/mediagoblin.mo | Bin 11993 -> 13900 bytes .../i18n/sk/LC_MESSAGES/mediagoblin.po | 423 ++++++++++-------- .../i18n/sl/LC_MESSAGES/mediagoblin.mo | Bin 11439 -> 13350 bytes .../i18n/sl/LC_MESSAGES/mediagoblin.po | 319 ++++++++----- .../i18n/sr/LC_MESSAGES/mediagoblin.mo | Bin 11335 -> 13259 bytes .../i18n/sr/LC_MESSAGES/mediagoblin.po | 311 ++++++++----- .../i18n/sv/LC_MESSAGES/mediagoblin.mo | Bin 11538 -> 13448 bytes .../i18n/sv/LC_MESSAGES/mediagoblin.po | 329 ++++++++------ .../i18n/te/LC_MESSAGES/mediagoblin.mo | Bin 11527 -> 13409 bytes .../i18n/te/LC_MESSAGES/mediagoblin.po | 313 ++++++++----- .../i18n/zh_TW/LC_MESSAGES/mediagoblin.mo | Bin 11190 -> 11198 bytes 38 files changed, 3686 insertions(+), 2391 deletions(-) diff --git a/mediagoblin/i18n/ar/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/ar/LC_MESSAGES/mediagoblin.mo index 02dfa29a8d836b87c0a82d96e257a57d047698c2..1a7267e52740d231a55fa739a75596c39aed13cc 100644 GIT binary patch delta 5102 zcmeIzZEzJ=8Nl(A7hV$H69}ZCa0tyCklZANgr;ejKtODPwrK<-R@mIT$-Ol9Zrt4v zVuxNB-a@AxF)JOb!v{rW9BDrgOD!T&b?nqZI)1R;z(6a|VVwFh4pxVj8T>!@Zh(N) zQtkAMcXIRFJ-d7MInQ~{xi18dcE!);WbRdbcJQ6fw<%N3u75g5E0xb_6z{@aI2pf# zdH6D($CDVqLs|5J=TNSfWGj_{4M>w(jH7S`PE;zcS~wU_gNZrlVh!%X<#-Gq#8G3E zT7bayiIh>07uoPcH>E|qd1*eQvsv7s8-2V&A;r;5@91w{*<6rno@`6(D z;WXMuk4uew7S7pPG?^-uCMY!%|A4)iM$|!k5@+FCm@Dm*lq$q2C?j2nlG#Nl*PBtM zrXAzb;bsmb1N)Fa^&ibp(#ZyDebf<$b3l|B|A2X^=oh5T3la2ziI9MtPvgZ+{%6qYWr2+=6Rx2g;nEL8+0ERH$UK z9;Ij_ScTiM4G*I{pD+1e#=#7Fl{qwV6>di9-~`swU(on#`QIz6H_&2-OE8@@Ng&JcetZhI;SrSD zXkeJ1!424thwv#}O6SC;eu;H>8tGEyvDW3ecz^?$yS4Zw?8S6Upv>`Ul)&CW8QGtG zFQMFb8Rfn!C=Da&jF{9Y=93uIEF{~i9yLCS=h4P$S^ukPZK7c}N~9+-1K&ZZfj^=I z@BvEEWKimonaL=roQ)EA4KByMxCYPS3TZD)1-K2Rww^_qif`gnS^xVvD5c>iSc4bv z1uU4I+Av;6dEg34fFtfnWo$ai@~T6oSv8`JycLVkLD?^!$4vY&(zW_2N@m{1xx8O} zz=0H72~Wu!wV(v@Rg{tc3fTnJNt7%PqU;y{z$KVo%w~hja9$d#31x1lF{*lO!f)eN z?8Dh*sQ?aQTvGfR2NKyJ%80I@%vr`9zau0@)r3r&ilEfYZj_N9KuPV-P^RbvR^l1I zeLT@*abDnCgz|h~F8LqL!Acq=kkuH*FtXy*Z;`C4izpqBAx*@lrlTy!Wk^A*Zj|T0 zhEm=8aV#E1>F0I-{4KOO{}Yl7wXU4}FW{iBoTY-t@FC2k_j~aXY{Tt17BAv5{5$fe z?q|`j!VS0xUqM-hmwg*a1MgD1@$+~Xx8Q^-r5?aNaSq0Fa1v$1ID?z{9bK7U-_>w#-*bAgZS^>jSci_9 zp@^Z|dNo%|LiK^J2Gtl$_OBh&b-BgSj&cyGxcbf;W#~(?FF*>TbCHI zpxLRGq%Ipb#g=N9ffSW?JEk2oqP(NT(YM}cb$5nz%yPB4$+eB3>vd&M&TO}>sJAow z=}Ng8D{*yuBo@++6*U>0?uocz?S>6k5B04rTbofM(m610OkUbti!S|OL)x`;mu+oK zjzL>JF`gtZejpVCfw46i-lhr9^sy|9c9!Oo zd|8j#rrV^dOq;iuPV(lV7cFmDxnhBTce1|<)xr?Gzm_fcmgd%uGD0ESbew^BZZJKb z?9MM}9X4&VLbqDoI%vdX8g#v(!?xM}Kw;Q*yXpdgkYO|b?Gf8-GdepfVx}8l8a9|g z*9k-o`-u=!5oj}IDCHY9l6798K9?*YZ+2d7!RiRPi(0nnFAx&m zK^;p$c&&Nw#yd#3!3`lwPTx56WVNKyA^~@G8of8Bky5%je!7z2+pSF%47#u(^{_v< z;TI+9S&C$oB(o8-dUU7Np(BzQSp&(;4V(44sjK3C;<9C`ZvEUG&K;%mHhm7ua{T5r z-!PfOp8wxPGVJ~1hri#u8ffv}oceR`jcHS+kt@?ytYZ0Zt8+W|=vC6>ou9U2L3Md$ zRe5EtuDZ8werG*%zq!arShX=Rn!M?;m;y~j2iI@M2%~~b))6b6vw+-%09MFkZ2DcA- zUzol!uQ8U|2K6l)`Q(4Ik%zqRO+U7luC^zR4DR_v_wvw;qg6}pcr%|db8lMB(wNKM zm0Ux2vag@gwVB>MMX%j{U+*tol=ZOGSaNTFsJO{HRs7|f_V(tI;~#%-FDdQ&hANql-f#x*X{_}6Q H{i}ZgQH0rR delta 3531 zcmb8ve@xWp9l-GiumcfMK$MBf!_+Dw$AJZuYEkKrsm%GSI=B8h?!LfH?#|pDA~WQw z9Efy@y07a@n=G}cAO$SmHlx!_&6YJ;SF2C{PUpdW{33o5pTJ_w zmV-G_7Fdb-xCWV`w&QYq9y{^d_%3F$SSkJU)OO68#gzl7^i zZfKy~Y=5#JL7Dd*lvJEWS@8Lz>JG}h3VkM&6U zlq=~sQEnPS4y%r!MCc^8;8|oZHG^Fx2e609N43C=q!JWx<;$8;+x-;!h~+{T-jgPjC)CLD)9pvncBh zVh#Q#kN7)iOsB*(uErhsEWU^rupCzq28om#L+HgiyoD06`NWsK)WfK86-v!~JvrWp z62UgC$0*7H-ipw8l!hGhDOimRsVLUst0YLpGWjJt3E8}L(ui!rHN4{7!mv2u}xELjcYjFgF$oz=XREXTT1bIiTMal7V$Yqs*QcRt=7{7EGsE|P+>g`^30<0*U@dvWEW!~w3OL~tDCVE0gJBZt$=#TKEYpcG5lU#+FV9My_k zLLEnm#288hZlZ+xZqkp?Nk8S`#CT=WI*g|V<^7!~DG8$-s1wWZC`vJ2#fW^*Z_{YO z-=TcZ^~8xwsqHAAS38zqFUr?)0Vx;tKFY%XMyanEOA`lLib48SScQZ51m4C?xQNA8 z;NBAApF!g^1ALNd1o@)Wb(B=Ri*oZ1@JYOna)6p;{1U+?ti!+IQ!-9|#0X06e~w?n zkMKqO3WIC#9h3-Ul@WjWo(qY~3wRVImcedZP8A|$pz2X-#lUPlgiUxHWuuSr z8QjV*jcquJQrs!zONy`nrFgd^XHvmOX-KZVk0D`|KFQ}HBD#aA&M&!BlK z!%WvY5X{ute6Q$$d10z^>N<}{`wWlQW%gvQGiOfgNm*~crb{9^;Ma?ndR$?nB&6zH zez(!8>RSx=9^DaW3u>>wF|gmEcNscl_`}-e*M`sKZPo4GaEo^7r?)lera(};TU`ET zufI9*(q306)E)?W9I8Ix^YI?~o4i4vo_NAQTdPO=1M|YV$?Ny9a0iW6LmT_UhCk%x zR9?TCp4AuoX;xlJmfvW9@NO(MyE-jvgMXi^)$57BWLD&u*;|sEs?A2b5j1b*EHkI& zuB=FohP1CO6xKdh*xlk#TLQFQ+MPUIyqoM4o9l9e=>#flc#6$yxrg(OAi>dLS93@= zcEsOtg&bxi&oJv}<(RLPEihNlI#Ax$=<|lv_Be?^PjotrU~*uGtGU_m#A9a`H<7iTvNe*>;C=`8~=N zR!s&+^tuCnB@Y8_Ve_H+-BlH36_sVqM|6d=w(^lOXSLIrx#g>6+l+l)$yM3ogs4_m zIx8N`tFEnF5&OyfjVb2oj68E|(cwuIIhtejTR*Z7YP;8pSp(Kt>!Mjz{DOJA_)4NG z7ks8Ft$sUdUAB)YYsfxmAF|GyM{5>3qtenWG-k!@sNG`?XlYslOg^WrLHjTxZ1BT) z-;SDvOXfB>ly!;8$L(YGA;r2~_Hh=0sNF4Z$;&Zo>_K_{&+44M@Jj4o3(b@z9OAq+ zYDXt6#3FWAV!dJOyxqrybFrT-u9@=L!u@N>JNXX^H@LaHtwADS_h@T~zZVJRpnYiK6hjh`+E2+=3dKa%J%cq-?Votv`NID@si|7 z?mNs+yevoK`QUD6\n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -25,27 +25,15 @@ msgstr "" msgid "Invalid file given for media type." msgstr "" -#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 +#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41 msgid "Username" msgstr "اسم المستخدم" -#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:53 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 msgid "Password" msgstr "كلمة السر" -#: mediagoblin/auth/forms.py:35 -msgid "Passwords must match." -msgstr "يجب أن تتطابق كلمتا السر." - -#: mediagoblin/auth/forms.py:37 -msgid "Confirm password" -msgstr "أكّد كلمة السر" - -#: mediagoblin/auth/forms.py:39 -msgid "Type it again here to make sure there are no spelling mistakes." -msgstr "اكتبها مرة أخرى هنا للتأكد من عدم وجود أخطاء إملائية." - -#: mediagoblin/auth/forms.py:42 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "عنوان البريد الإلكتروني" @@ -61,7 +49,7 @@ msgstr "عذرًا، لقد اختار مستخدم آخر هذا الاسم." msgid "Sorry, a user with that email address already exists." msgstr "" -#: mediagoblin/auth/views.py:179 +#: mediagoblin/auth/views.py:180 msgid "" "Your email address has been verified. You may now login, edit your profile, " "and submit images!" @@ -69,23 +57,28 @@ msgstr "" "تم التحقق من بريدك الإلكتروني. يمكنك الآن الولوج، وتحرير ملفك الشخصي، ونشر " "الصور!" -#: mediagoblin/auth/views.py:185 +#: mediagoblin/auth/views.py:186 msgid "The verification key or user id is incorrect" msgstr "مفتاح التحقق أو معرف المستخدم خاطئ" -#: mediagoblin/auth/views.py:203 +#: mediagoblin/auth/views.py:204 msgid "You must be logged in so we know who to send the email to!" msgstr "" -#: mediagoblin/auth/views.py:211 +#: mediagoblin/auth/views.py:212 msgid "You've already verified your email address!" msgstr "" -#: mediagoblin/auth/views.py:224 +#: mediagoblin/auth/views.py:225 msgid "Resent your verification email." msgstr "أعدنا إرسال رسالة التحقق." -#: mediagoblin/auth/views.py:265 +#: mediagoblin/auth/views.py:260 +msgid "" +"An email has been sent with instructions on how to change your password." +msgstr "" + +#: mediagoblin/auth/views.py:270 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." @@ -93,47 +86,76 @@ msgstr "" "تعذر إرسال رسالة استعادة كلمة السر لأن اسم المستخدم معطل أو لأننا لم نتحقق " "من بريدك الإلكتروني." +#: mediagoblin/auth/views.py:282 +msgid "Couldn't find someone with that username or email." +msgstr "" + +#: mediagoblin/auth/views.py:330 +msgid "You can now log in using your new password." +msgstr "" + #: mediagoblin/edit/forms.py:24 mediagoblin/submit/forms.py:27 msgid "Title" msgstr "العنوان" -#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:27 mediagoblin/submit/forms.py:30 +msgid "Description of this work" +msgstr "وصف هذا العمل." + +#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:31 +msgid "" +"You can use\n" +" \n" +" Markdown for formatting." +msgstr "" + +#: mediagoblin/edit/forms.py:32 mediagoblin/submit/forms.py:35 msgid "Tags" msgstr "الوسوم" -#: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 -msgid "Seperate tags by commas." +#: mediagoblin/edit/forms.py:34 mediagoblin/submit/forms.py:37 +msgid "Separate tags by commas." msgstr "" -#: mediagoblin/edit/forms.py:33 +#: mediagoblin/edit/forms.py:37 msgid "Slug" msgstr "المسار" -#: mediagoblin/edit/forms.py:34 +#: mediagoblin/edit/forms.py:38 msgid "The slug can't be empty" msgstr "لا يمكن ترك المسار فارغًا" -#: mediagoblin/edit/forms.py:35 +#: mediagoblin/edit/forms.py:39 msgid "" -"The title part of this media's URL. You usually don't need to change this." +"The title part of this media's address. You usually don't need to change " +"this." msgstr "" -"الجزء الذي يمثل عنوان الملف في المسار. لا حاجة إلى تغيير محتوى هذه الخانة " -"عادةً." -#: mediagoblin/edit/forms.py:42 +#: mediagoblin/edit/forms.py:46 msgid "Bio" msgstr "السيرة" -#: mediagoblin/edit/forms.py:45 +#: mediagoblin/edit/forms.py:48 +msgid "" +"You can use\n" +" \n" +" Markdown for formatting." +msgstr "" + +#: mediagoblin/edit/forms.py:53 msgid "Website" msgstr "الموقع الإلكتروني" -#: mediagoblin/edit/forms.py:49 +#: mediagoblin/edit/forms.py:60 msgid "Old password" msgstr "" -#: mediagoblin/edit/forms.py:52 -msgid "New Password" +#: mediagoblin/edit/forms.py:62 +msgid "Enter your old password to prove you own this account." +msgstr "" + +#: mediagoblin/edit/forms.py:65 +msgid "New password" msgstr "" #: mediagoblin/edit/views.py:65 @@ -148,39 +170,43 @@ msgstr "أنت تحرّر وسائط مستخدم آخر. كن حذرًا أثن msgid "You are editing a user's profile. Proceed with caution." msgstr "أنت تحرّر ملف مستخدم آخر. كن حذرًا أثناء العملية." -#: mediagoblin/edit/views.py:171 +#: mediagoblin/edit/views.py:174 +msgid "Profile changes saved" +msgstr "" + +#: mediagoblin/edit/views.py:200 msgid "Wrong password" msgstr "" -#: mediagoblin/edit/views.py:192 -msgid "Profile edited!" +#: mediagoblin/edit/views.py:216 +msgid "Account settings saved" msgstr "" -#: mediagoblin/media_types/__init__.py:65 -msgid "Could not find any file extension in \"{filename}\"" +#: mediagoblin/media_types/__init__.py:77 +msgid "Could not extract any file extension from \"{filename}\"" +msgstr "" + +#: mediagoblin/media_types/__init__.py:88 +msgid "Sorry, I don't support that file type :(" msgstr "" #: mediagoblin/submit/forms.py:25 msgid "File" msgstr "الملف" -#: mediagoblin/submit/forms.py:30 -msgid "Description of this work" -msgstr "وصف هذا العمل." - -#: mediagoblin/submit/views.py:49 +#: mediagoblin/submit/views.py:50 msgid "You must provide a file." msgstr "يجب أن تضع ملفًا." -#: mediagoblin/submit/views.py:127 +#: mediagoblin/submit/views.py:128 msgid "Woohoo! Submitted!" msgstr "يا سلام! نُشرَت!" -#: mediagoblin/submit/views.py:133 -msgid "Invalid file type." -msgstr "" +#: mediagoblin/templates/mediagoblin/404.html:22 +msgid "Image of 404 goblin stressing out" +msgstr "صورة قزم مرتبك" -#: mediagoblin/templates/mediagoblin/404.html:21 +#: mediagoblin/templates/mediagoblin/404.html:23 msgid "Oops!" msgstr "ويحي!" @@ -195,33 +221,30 @@ msgid "" msgstr "" "إن كنت متأكدًا من صحة العنوان فربما تكون الصفحة التي تريدها نُقلت أو حُذفت." -#: mediagoblin/templates/mediagoblin/404.html:32 -msgid "Image of 404 goblin stressing out" -msgstr "صورة قزم مرتبك" - -#: mediagoblin/templates/mediagoblin/base.html:49 +#: mediagoblin/templates/mediagoblin/base.html:48 msgid "MediaGoblin logo" msgstr "شعار ميدياغوبلن" -#: mediagoblin/templates/mediagoblin/base.html:54 -msgid "Submit media" -msgstr "أرسل وسائط" +#: mediagoblin/templates/mediagoblin/base.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:157 +msgid "Add media" +msgstr "أضف وسائط" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:64 msgid "Verify your email!" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:72 +#: mediagoblin/templates/mediagoblin/base.html:71 msgid "log out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:75 +#: mediagoblin/templates/mediagoblin/base.html:74 #: mediagoblin/templates/mediagoblin/auth/login.html:27 #: mediagoblin/templates/mediagoblin/auth/login.html:45 msgid "Log in" msgstr "لِج" -#: mediagoblin/templates/mediagoblin/base.html:91 +#: mediagoblin/templates/mediagoblin/base.html:86 msgid "" "Powered by MediaGoblin, a GNU project" @@ -231,7 +254,7 @@ msgstr "" msgid "Explore" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:27 +#: mediagoblin/templates/mediagoblin/root.html:26 msgid "Hi there, welcome to this MediaGoblin site!" msgstr "" @@ -255,22 +278,21 @@ msgstr "" #, python-format msgid "" "Create an account at this site\n" -" or\n" -" Set up MediaGoblin on your own server" +" or\n" +" Set up MediaGoblin on your own server" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:44 +#: mediagoblin/templates/mediagoblin/root.html:40 msgid "Most recent media" msgstr "أحدث الوسائط" -#: mediagoblin/templates/mediagoblin/auth/change_fp.html:29 -msgid "Enter your new password" -msgstr "أدخل كلمة سرك الجديدة" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:32 +msgid "Set your new password" +msgstr "" -#: mediagoblin/templates/mediagoblin/auth/change_fp.html:33 -#: mediagoblin/templates/mediagoblin/submit/start.html:30 -msgid "Submit" -msgstr "أرسل" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:35 +msgid "Set password" +msgstr "" #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" @@ -280,15 +302,6 @@ msgstr "" msgid "Send instructions" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 -msgid "Your password has been changed. Try to log in now." -msgstr "لقد غُيرت كلمة سرك. جرّب الولوج الآن." - -#: mediagoblin/templates/mediagoblin/auth/fp_email_sent.html:22 -msgid "" -"Check your inbox. We sent an email with a URL for changing your password." -msgstr "تفقد بريدك الإلكتروني. لقد أرسلنا رسالة بها وصلة لتغيير كلمة سرك." - #: mediagoblin/templates/mediagoblin/auth/fp_verification_email.txt:19 #, python-format msgid "" @@ -326,11 +339,11 @@ msgstr "أنشئ حسابًا هنا!" msgid "Forgot your password?" msgstr "أنسيت كلمة سرك؟" -#: mediagoblin/templates/mediagoblin/auth/register.html:27 +#: mediagoblin/templates/mediagoblin/auth/register.html:32 msgid "Create an account!" msgstr "أنشئ حسابًا!" -#: mediagoblin/templates/mediagoblin/auth/register.html:31 +#: mediagoblin/templates/mediagoblin/auth/register.html:36 msgid "Create" msgstr "أنشئ" @@ -362,10 +375,16 @@ msgid "Cancel" msgstr "ألغِ" #: mediagoblin/templates/mediagoblin/edit/edit.html:37 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:40 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:35 msgid "Save changes" msgstr "احفظ التغييرات" +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:34 +#, python-format +msgid "Changing %(username)s's account settings" +msgstr "" + #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29 #, python-format msgid "Editing %(username)s's profile" @@ -377,13 +396,32 @@ msgstr "تحرير ملف %(username)s الشخصي" msgid "Media tagged with: %(tag_name)s" msgstr "" -#: mediagoblin/templates/mediagoblin/media_displays/video.html:19 +#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 +#: mediagoblin/templates/mediagoblin/media_displays/video.html:46 msgid "Original" msgstr "" +#: mediagoblin/templates/mediagoblin/media_displays/video.html:33 +msgid "" +"Sorry, this video will not work because \n" +"\t your web browser does not support HTML5 \n" +"\t video." +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:36 +msgid "" +"You can get a modern web browser that \n" +"\t can play this video at \n" +"\t http://getfirefox.com!" +msgstr "" + #: mediagoblin/templates/mediagoblin/submit/start.html:26 -msgid "Submit yer media" -msgstr "انشر وسائطك" +msgid "Add your media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Add" +msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format @@ -395,31 +433,57 @@ msgstr "" msgid "%(username)s's media" msgstr "وسائط %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:57 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:60 #, python-format -msgid "By %(username)s on %(date)s" +msgid "Added on %(date)s." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:67 -msgid "Post a comment" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:85 -msgid "at" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 -msgid "Post comment!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:124 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:69 msgid "Edit" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:130 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:73 msgid "Delete" msgstr "" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:79 +#, python-format +msgid "%(comment_count)s comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:81 +#, python-format +msgid "%(comment_count)s comments" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:83 +msgid "No comments yet." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:91 +msgid "Add one" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:100 +msgid "" +"Type your comment here. You can use Markdown for" +" formatting." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 +msgid "Add this comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:126 +msgid "at" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:141 +#, python-format +msgid "

❖ Browsing media by %(username)s

" +msgstr "" + #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -502,30 +566,31 @@ msgid "Here's a spot to tell others about yourself." msgstr "هذه زاوية لتخبر الآخرين فيها عن نفسك." #: mediagoblin/templates/mediagoblin/user_pages/user.html:101 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:119 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:118 msgid "Edit profile" msgstr "حرِّر الملف الشخصي" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:107 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:106 msgid "This user hasn't filled in their profile (yet)." msgstr "لم يعبئ هذا العضو بيانات ملفه بعد." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:133 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:125 +msgid "Change account settings" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:138 #, python-format msgid "View all of %(username)s's media" msgstr "أظهِر كل وسائط %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:146 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:151 msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." msgstr "هنا ستظهر وسائطك، ولكن يبدو أنك لم تضف شيئًا بعد." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:152 -msgid "Add media" -msgstr "أضف وسائط" - -#: mediagoblin/templates/mediagoblin/user_pages/user.html:158 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:163 +#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72 msgid "There doesn't seem to be any media here yet..." msgstr "لا يبدو أنه توجد أي وسائط هنا حتى الآن..." @@ -537,30 +602,36 @@ msgstr "" msgid "Atom feed" msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:40 -msgid "Newer" -msgstr "الأحدث" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:39 +msgid "← Newer" +msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:46 -msgid "Older" -msgstr "الأقدم" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:45 +msgid "Older →" +msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:50 +#: mediagoblin/templates/mediagoblin/utils/pagination.html:48 msgid "Go to page:" msgstr "" +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:27 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:32 +msgid "newer" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:38 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:43 +msgid "older" +msgstr "" + #: mediagoblin/templates/mediagoblin/utils/tags.html:20 -msgid "Tagged with" +msgid "View more media tagged with" msgstr "" #: mediagoblin/templates/mediagoblin/utils/tags.html:25 -msgid "and" +msgid "or" msgstr "" -#: mediagoblin/user_pages/forms.py:24 -msgid "Comment" -msgstr "علِّق" - #: mediagoblin/user_pages/forms.py:30 msgid "I am sure I want to delete this" msgstr "أنا متأكد من رغبتي بحذف هذا العمل" diff --git a/mediagoblin/i18n/ca/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/ca/LC_MESSAGES/mediagoblin.mo index 34179a53d237515f32598f254aa1c01a628f9b06..45f2331f5aedcfbe40826e4da079e3ab5c49f29a 100644 GIT binary patch literal 13397 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 F{|}{yC>j6& delta 3228 zcmb`{du$X%9Ki8u3$&I}Xe&@D$kZax(#N$xf#W3>)G8{{5+aIbd$(;@@Ak;<9&N#T zsQ5O~IBIym}n)&_anrRXe1g1G=Pc0pe8-FG?!5p)CA5N+b?p8GeVHAv-t{#_&+)SD=j7p^VSNj5HS0n1XFc`ji!V4a%GP z$YIs(C=q%PdvP1Gmm15i67s3YkeZJY!FH4b#!xoC3Hep`@FDY`C?oz7(pMQ+i*KP6 zO(m~ikC&k2a5FaJ11J&MgRCOD+t?#xE^KQXK)^VQbGJ1 zX^f%7H7>$VT#sAu1#H6Egh3(|LmwSniic1lHih`Imzs_m7ogP4x^TP;C4y;e!>uR> z*ps2LkcJ%dd{~4GsjV2rM^Hkw52cvCM@dx`gID1KY{3UnuGf2*k9&~|r9MJA$U)qh z$Mr_uN!?3WWuMH`G>+1E1LaM(Rpmmu59MG-@f@t-pTk^?qb&Sz=#$t=|2gD_sxMKl z^AF+kD5qslwHzgd>v0p_jif50in*MU!?7qK)F?Tg9rmLr3tWtxQFSA~>IOa}*N>qT z;ZrE{b|Js&13u(Uzr|Y2rxFRCsz-^)avUZ1e_DQco<}Lpy(lks0A-&eD8)Ex8ZRLCc{~ld&owBa zybC3ikD{bz7uMmsp~q0>P3HCFfb}Tzm*5Coi)-*ol$v<~B?VuF{qpI#nz>*)0UXJL z3S2~{~13mzo8?zItt=EoSs|QkPPdjc` zs=raMwY6`%fwo+2CoLzT`<$RxTYAmvmAX6S=~%Dj_Bd`&?n@gi-|tI#@kZ5_N+$Up zy4{YK)Wc60NGIajO-&ATx8ufHcz{O2)^>kjyS~Gz9M`Nn>yDw_B^7xkuHAR?yF>Y< ztpz3R?nW!&#Is*A&1I%^Rk*3T#O|{_bEvG&j4q$w9FF=rnf3#nw1QY~qgs`sZRuEe zx@RGVexULk=B?0B_#tNhkH+eGRnm>Vi$=Eu4wv*`5AP3f+r6R3_Xxu6br25c`J z=(Kuz?07a#rgHq&0wQI$*VhicKR%kjz+v|u%W-wD?b$j=ajt8La9TRqA&Zuq(*6cJ zk&v(^9Y0`-Zw4!ungf;J7;n<@p*>aO@-DhuvNRl4-D~-}%eLKILhN{>?(_y^gG8!_ zfU;&^qq5w%vI5m@b3P}Qa+N$xr2{i^%FT0|8=6}hB6DfOZ53pNUhksj!6Km@KP=@X_ub}MIGStDq2HPB- zvGY%AF<-4QrRB5CiJ2u!R@#1e2sr~CE{~4ej5%)1i96musn1#F#oEnbjXHG}HTrIJ zg}c$QRQ7W?_}L!sFZtL=^?Pg^=0%-as#W#3OQ{ZRuYdTzl<8|tZKf)6G+U-cv!~{* S{P$(rPQEO?x}#&bOx16UQ*jIc diff --git a/mediagoblin/i18n/ca/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/ca/LC_MESSAGES/mediagoblin.po index 9609cb34..a5d6732b 100644 --- a/mediagoblin/i18n/ca/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/ca/LC_MESSAGES/mediagoblin.po @@ -1,5 +1,5 @@ # Translations template for PROJECT. -# Copyright (C) 2011 ORGANIZATION +# Copyright (C) 2012 ORGANIZATION # This file is distributed under the same license as the PROJECT project. # # Translators: @@ -9,8 +9,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-12-04 10:24-0600\n" -"PO-Revision-Date: 2011-12-04 16:23+0000\n" +"POT-Creation-Date: 2012-01-07 13:47-0600\n" +"PO-Revision-Date: 2012-01-07 19:44+0000\n" "Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -24,27 +24,15 @@ msgstr "" msgid "Invalid file given for media type." msgstr "Aquest tipus de fitxer no és vàlid." -#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 +#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41 msgid "Username" msgstr "Nom d'usuari" -#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:53 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 msgid "Password" msgstr "Contrasenya" -#: mediagoblin/auth/forms.py:35 -msgid "Passwords must match." -msgstr "Les contrasenyes han de coincidir" - -#: mediagoblin/auth/forms.py:37 -msgid "Confirm password" -msgstr "Confirmeu la contrasenya" - -#: mediagoblin/auth/forms.py:39 -msgid "Type it again here to make sure there are no spelling mistakes." -msgstr "" - -#: mediagoblin/auth/forms.py:42 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "Adreça electrònica" @@ -60,7 +48,7 @@ msgstr "Lamentablement aquest usuari ja existeix." msgid "Sorry, a user with that email address already exists." msgstr "" -#: mediagoblin/auth/views.py:179 +#: mediagoblin/auth/views.py:180 msgid "" "Your email address has been verified. You may now login, edit your profile, " "and submit images!" @@ -68,68 +56,104 @@ msgstr "" "Ja s'ha verificat la vostra adreça electrònica. Ara podeu entrar, editar el " "vostre perfil i penjar imatge!" -#: mediagoblin/auth/views.py:185 +#: mediagoblin/auth/views.py:186 msgid "The verification key or user id is incorrect" msgstr "" "La clau de verificació o la identificació de l'usuari no són correctes." -#: mediagoblin/auth/views.py:203 +#: mediagoblin/auth/views.py:204 msgid "You must be logged in so we know who to send the email to!" msgstr "" -#: mediagoblin/auth/views.py:211 +#: mediagoblin/auth/views.py:212 msgid "You've already verified your email address!" msgstr "" -#: mediagoblin/auth/views.py:224 +#: mediagoblin/auth/views.py:225 msgid "Resent your verification email." msgstr "Torna'm a enviar el correu de verificació" -#: mediagoblin/auth/views.py:265 +#: mediagoblin/auth/views.py:260 +msgid "" +"An email has been sent with instructions on how to change your password." +msgstr "" + +#: mediagoblin/auth/views.py:270 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." msgstr "" +#: mediagoblin/auth/views.py:282 +msgid "Couldn't find someone with that username or email." +msgstr "" + +#: mediagoblin/auth/views.py:330 +msgid "You can now log in using your new password." +msgstr "" + #: mediagoblin/edit/forms.py:24 mediagoblin/submit/forms.py:27 msgid "Title" msgstr "Títol" -#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:27 mediagoblin/submit/forms.py:30 +msgid "Description of this work" +msgstr "" + +#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:31 +msgid "" +"You can use\n" +" \n" +" Markdown for formatting." +msgstr "" + +#: mediagoblin/edit/forms.py:32 mediagoblin/submit/forms.py:35 msgid "Tags" msgstr "Etiquetes" -#: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 -msgid "Seperate tags by commas." +#: mediagoblin/edit/forms.py:34 mediagoblin/submit/forms.py:37 +msgid "Separate tags by commas." msgstr "" -#: mediagoblin/edit/forms.py:33 +#: mediagoblin/edit/forms.py:37 msgid "Slug" msgstr "" -#: mediagoblin/edit/forms.py:34 +#: mediagoblin/edit/forms.py:38 msgid "The slug can't be empty" msgstr "" -#: mediagoblin/edit/forms.py:35 +#: mediagoblin/edit/forms.py:39 msgid "" -"The title part of this media's URL. You usually don't need to change this." +"The title part of this media's address. You usually don't need to change " +"this." msgstr "" -#: mediagoblin/edit/forms.py:42 +#: mediagoblin/edit/forms.py:46 msgid "Bio" msgstr "Biografia" -#: mediagoblin/edit/forms.py:45 +#: mediagoblin/edit/forms.py:48 +msgid "" +"You can use\n" +" \n" +" Markdown for formatting." +msgstr "" + +#: mediagoblin/edit/forms.py:53 msgid "Website" msgstr "Lloc web" -#: mediagoblin/edit/forms.py:49 +#: mediagoblin/edit/forms.py:60 msgid "Old password" msgstr "" -#: mediagoblin/edit/forms.py:52 -msgid "New Password" +#: mediagoblin/edit/forms.py:62 +msgid "Enter your old password to prove you own this account." +msgstr "" + +#: mediagoblin/edit/forms.py:65 +msgid "New password" msgstr "" #: mediagoblin/edit/views.py:65 @@ -144,39 +168,43 @@ msgstr "Esteu editant fitxers d'un altre usuari. Aneu amb compte." msgid "You are editing a user's profile. Proceed with caution." msgstr "Esteu editant el perfil d'un usuari. Aneu amb compte" -#: mediagoblin/edit/views.py:171 +#: mediagoblin/edit/views.py:174 +msgid "Profile changes saved" +msgstr "" + +#: mediagoblin/edit/views.py:200 msgid "Wrong password" msgstr "" -#: mediagoblin/edit/views.py:192 -msgid "Profile edited!" +#: mediagoblin/edit/views.py:216 +msgid "Account settings saved" msgstr "" -#: mediagoblin/media_types/__init__.py:65 -msgid "Could not find any file extension in \"{filename}\"" +#: mediagoblin/media_types/__init__.py:77 +msgid "Could not extract any file extension from \"{filename}\"" +msgstr "" + +#: mediagoblin/media_types/__init__.py:88 +msgid "Sorry, I don't support that file type :(" msgstr "" #: mediagoblin/submit/forms.py:25 msgid "File" msgstr "Fitxer" -#: mediagoblin/submit/forms.py:30 -msgid "Description of this work" -msgstr "" - -#: mediagoblin/submit/views.py:49 +#: mediagoblin/submit/views.py:50 msgid "You must provide a file." msgstr "Heu d'escollir un fitxer." -#: mediagoblin/submit/views.py:127 +#: mediagoblin/submit/views.py:128 msgid "Woohoo! Submitted!" msgstr "Visca! S'ha enviat!" -#: mediagoblin/submit/views.py:133 -msgid "Invalid file type." -msgstr "" +#: mediagoblin/templates/mediagoblin/404.html:22 +msgid "Image of 404 goblin stressing out" +msgstr "Imatge de la pantalla 404, el goblin no sap què fer..." -#: mediagoblin/templates/mediagoblin/404.html:21 +#: mediagoblin/templates/mediagoblin/404.html:23 msgid "Oops!" msgstr "Ups!" @@ -192,33 +220,30 @@ msgstr "" "Si esteu convençut que l'adreça és correcta, pot ser que la pàgina que " "cerqueu s'hagi canviat d'ubicació o s'hagi eliminat." -#: mediagoblin/templates/mediagoblin/404.html:32 -msgid "Image of 404 goblin stressing out" -msgstr "Imatge de la pantalla 404, el goblin no sap què fer..." - -#: mediagoblin/templates/mediagoblin/base.html:49 +#: mediagoblin/templates/mediagoblin/base.html:48 msgid "MediaGoblin logo" msgstr "Logo de mediagoblin" -#: mediagoblin/templates/mediagoblin/base.html:54 -msgid "Submit media" -msgstr "Envia fitxers" +#: mediagoblin/templates/mediagoblin/base.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:157 +msgid "Add media" +msgstr "Tots els fitxers" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:64 msgid "Verify your email!" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:72 +#: mediagoblin/templates/mediagoblin/base.html:71 msgid "log out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:75 +#: mediagoblin/templates/mediagoblin/base.html:74 #: mediagoblin/templates/mediagoblin/auth/login.html:27 #: mediagoblin/templates/mediagoblin/auth/login.html:45 msgid "Log in" msgstr "Entra" -#: mediagoblin/templates/mediagoblin/base.html:91 +#: mediagoblin/templates/mediagoblin/base.html:86 msgid "" "Powered by MediaGoblin, a GNU project" @@ -228,7 +253,7 @@ msgstr "" msgid "Explore" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:27 +#: mediagoblin/templates/mediagoblin/root.html:26 msgid "Hi there, welcome to this MediaGoblin site!" msgstr "" @@ -252,22 +277,21 @@ msgstr "" #, python-format msgid "" "Create an account at this site\n" -" or\n" -" Set up MediaGoblin on your own server" +" or\n" +" Set up MediaGoblin on your own server" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:44 +#: mediagoblin/templates/mediagoblin/root.html:40 msgid "Most recent media" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/change_fp.html:29 -msgid "Enter your new password" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:32 +msgid "Set your new password" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/change_fp.html:33 -#: mediagoblin/templates/mediagoblin/submit/start.html:30 -msgid "Submit" -msgstr "Envia" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:35 +msgid "Set password" +msgstr "" #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" @@ -277,15 +301,6 @@ msgstr "" msgid "Send instructions" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 -msgid "Your password has been changed. Try to log in now." -msgstr "" - -#: mediagoblin/templates/mediagoblin/auth/fp_email_sent.html:22 -msgid "" -"Check your inbox. We sent an email with a URL for changing your password." -msgstr "" - #: mediagoblin/templates/mediagoblin/auth/fp_verification_email.txt:19 #, python-format msgid "" @@ -316,11 +331,11 @@ msgstr "Creeu-ne un aquí!" msgid "Forgot your password?" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/register.html:27 +#: mediagoblin/templates/mediagoblin/auth/register.html:32 msgid "Create an account!" msgstr "Creeu un compte!" -#: mediagoblin/templates/mediagoblin/auth/register.html:31 +#: mediagoblin/templates/mediagoblin/auth/register.html:36 msgid "Create" msgstr "Crea" @@ -352,10 +367,16 @@ msgid "Cancel" msgstr "Cancel·la" #: mediagoblin/templates/mediagoblin/edit/edit.html:37 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:40 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:35 msgid "Save changes" msgstr "Desa els canvis" +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:34 +#, python-format +msgid "Changing %(username)s's account settings" +msgstr "" + #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29 #, python-format msgid "Editing %(username)s's profile" @@ -367,13 +388,32 @@ msgstr "" msgid "Media tagged with: %(tag_name)s" msgstr "" -#: mediagoblin/templates/mediagoblin/media_displays/video.html:19 +#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 +#: mediagoblin/templates/mediagoblin/media_displays/video.html:46 msgid "Original" msgstr "" +#: mediagoblin/templates/mediagoblin/media_displays/video.html:33 +msgid "" +"Sorry, this video will not work because \n" +"\t your web browser does not support HTML5 \n" +"\t video." +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:36 +msgid "" +"You can get a modern web browser that \n" +"\t can play this video at \n" +"\t http://getfirefox.com!" +msgstr "" + #: mediagoblin/templates/mediagoblin/submit/start.html:26 -msgid "Submit yer media" -msgstr "Envieu els vostres fitxers" +msgid "Add your media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Add" +msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format @@ -385,31 +425,57 @@ msgstr "" msgid "%(username)s's media" msgstr "%(username)s's media" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:57 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:60 #, python-format -msgid "By %(username)s on %(date)s" +msgid "Added on %(date)s." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:67 -msgid "Post a comment" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:85 -msgid "at" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 -msgid "Post comment!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:124 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:69 msgid "Edit" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:130 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:73 msgid "Delete" msgstr "" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:79 +#, python-format +msgid "%(comment_count)s comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:81 +#, python-format +msgid "%(comment_count)s comments" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:83 +msgid "No comments yet." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:91 +msgid "Add one" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:100 +msgid "" +"Type your comment here. You can use Markdown for" +" formatting." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 +msgid "Add this comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:126 +msgid "at" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:141 +#, python-format +msgid "

❖ Browsing media by %(username)s

" +msgstr "" + #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -494,30 +560,31 @@ msgid "Here's a spot to tell others about yourself." msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/user.html:101 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:119 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:118 msgid "Edit profile" msgstr "Edita el perfil" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:107 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:106 msgid "This user hasn't filled in their profile (yet)." msgstr "Aquest usuari encara no ha escrit res al seu perfil." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:133 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:125 +msgid "Change account settings" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:138 #, python-format msgid "View all of %(username)s's media" msgstr "View all of %(username)s's media" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:146 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:151 msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:152 -msgid "Add media" -msgstr "Tots els fitxers" - -#: mediagoblin/templates/mediagoblin/user_pages/user.html:158 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:163 +#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72 msgid "There doesn't seem to be any media here yet..." msgstr "" @@ -529,30 +596,36 @@ msgstr "Icona RSS" msgid "Atom feed" msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:40 -msgid "Newer" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:39 +msgid "← Newer" msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:46 -msgid "Older" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:45 +msgid "Older →" msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:50 +#: mediagoblin/templates/mediagoblin/utils/pagination.html:48 msgid "Go to page:" msgstr "" +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:27 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:32 +msgid "newer" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:38 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:43 +msgid "older" +msgstr "" + #: mediagoblin/templates/mediagoblin/utils/tags.html:20 -msgid "Tagged with" +msgid "View more media tagged with" msgstr "" #: mediagoblin/templates/mediagoblin/utils/tags.html:25 -msgid "and" +msgid "or" msgstr "" -#: mediagoblin/user_pages/forms.py:24 -msgid "Comment" -msgstr "Comentari" - #: mediagoblin/user_pages/forms.py:30 msgid "I am sure I want to delete this" msgstr "" diff --git a/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.mo index a01abf9ca7c143db31f1a5d96bc8ac2148711350..4f4bbfdaa6ca1d9b55b4b0ea53714ff51d5879f1 100644 GIT binary patch literal 13692 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 delta 3622 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�Do)?_5! F{|2Qo6)^w+ diff --git a/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.po index e2765357..1fb472f0 100644 --- a/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.po @@ -1,5 +1,5 @@ # Translations template for PROJECT. -# Copyright (C) 2011 ORGANIZATION +# Copyright (C) 2012 ORGANIZATION # This file is distributed under the same license as the PROJECT project. # # Translators: @@ -8,6 +8,7 @@ # Elrond , 2011. # , 2011. # Jan-Christoph Borchardt , 2011. +# Jan-Christoph Borchardt , 2011. # , 2011. # , 2011. # Rafael Maguiña , 2011. @@ -16,9 +17,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-12-04 10:24-0600\n" -"PO-Revision-Date: 2011-12-06 21:16+0000\n" -"Last-Translator: gandaro \n" +"POT-Creation-Date: 2012-01-07 13:47-0600\n" +"PO-Revision-Date: 2012-01-07 19:44+0000\n" +"Last-Translator: cwebber \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" @@ -31,27 +32,15 @@ msgstr "" msgid "Invalid file given for media type." msgstr "Die Datei stimmt nicht mit dem gewählten Medientyp überein." -#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 +#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41 msgid "Username" msgstr "Benutzername" -#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:53 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 msgid "Password" msgstr "Passwort" -#: mediagoblin/auth/forms.py:35 -msgid "Passwords must match." -msgstr "Passwörter müssen übereinstimmen." - -#: mediagoblin/auth/forms.py:37 -msgid "Confirm password" -msgstr "Passwort wiederholen" - -#: mediagoblin/auth/forms.py:39 -msgid "Type it again here to make sure there are no spelling mistakes." -msgstr "Hier nochmal eintragen, um Tippfehler zu verhindern." - -#: mediagoblin/auth/forms.py:42 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "E-Mail-Adresse" @@ -67,7 +56,7 @@ msgstr "Leider gibt es bereits einen Benutzer mit diesem Namen." msgid "Sorry, a user with that email address already exists." msgstr "Leider gibt es bereits einen Benutzer mit dieser E-Mail-Adresse." -#: mediagoblin/auth/views.py:179 +#: mediagoblin/auth/views.py:180 msgid "" "Your email address has been verified. You may now login, edit your profile, " "and submit images!" @@ -75,23 +64,28 @@ msgstr "" "Deine E-Mail-Adresse wurde bestätigt. Du kannst dich nun anmelden, Dein " "Profil bearbeiten und Bilder hochladen!" -#: mediagoblin/auth/views.py:185 +#: mediagoblin/auth/views.py:186 msgid "The verification key or user id is incorrect" msgstr "Der Bestätigungsschlüssel oder die Nutzernummer ist falsch." -#: mediagoblin/auth/views.py:203 +#: mediagoblin/auth/views.py:204 msgid "You must be logged in so we know who to send the email to!" -msgstr "" +msgstr "Du musst angemeldet sein, damit wir wissen, wer die Email bekommt." -#: mediagoblin/auth/views.py:211 +#: mediagoblin/auth/views.py:212 msgid "You've already verified your email address!" msgstr "Deine E-Mail-Adresse wurde bereits bestätigt." -#: mediagoblin/auth/views.py:224 +#: mediagoblin/auth/views.py:225 msgid "Resent your verification email." msgstr "Bestätigungs-E-Mail wurde erneut versandt." -#: mediagoblin/auth/views.py:265 +#: mediagoblin/auth/views.py:260 +msgid "" +"An email has been sent with instructions on how to change your password." +msgstr "" + +#: mediagoblin/auth/views.py:270 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." @@ -100,48 +94,77 @@ msgstr "" "weil dein Benutzername inaktiv oder deine E-Mail-Adresse noch nicht " "verifiziert ist." +#: mediagoblin/auth/views.py:282 +msgid "Couldn't find someone with that username or email." +msgstr "" + +#: mediagoblin/auth/views.py:330 +msgid "You can now log in using your new password." +msgstr "" + #: mediagoblin/edit/forms.py:24 mediagoblin/submit/forms.py:27 msgid "Title" msgstr "Titel" -#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:27 mediagoblin/submit/forms.py:30 +msgid "Description of this work" +msgstr "Beschreibung des Werkes" + +#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:31 +msgid "" +"You can use\n" +" \n" +" Markdown for formatting." +msgstr "" + +#: mediagoblin/edit/forms.py:32 mediagoblin/submit/forms.py:35 msgid "Tags" msgstr "Markierungen" -#: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 -msgid "Seperate tags by commas." +#: mediagoblin/edit/forms.py:34 mediagoblin/submit/forms.py:37 +msgid "Separate tags by commas." msgstr "" -#: mediagoblin/edit/forms.py:33 +#: mediagoblin/edit/forms.py:37 msgid "Slug" msgstr "Kurztitel" -#: mediagoblin/edit/forms.py:34 +#: mediagoblin/edit/forms.py:38 msgid "The slug can't be empty" msgstr "Bitte gib einen Kurztitel ein" -#: mediagoblin/edit/forms.py:35 +#: mediagoblin/edit/forms.py:39 msgid "" -"The title part of this media's URL. You usually don't need to change this." +"The title part of this media's address. You usually don't need to change " +"this." msgstr "" -"Der Titelteil der Medienadresse. Normalerweise muss hier nichts geändert " -"werden." -#: mediagoblin/edit/forms.py:42 +#: mediagoblin/edit/forms.py:46 msgid "Bio" msgstr "Biographie" -#: mediagoblin/edit/forms.py:45 +#: mediagoblin/edit/forms.py:48 +msgid "" +"You can use\n" +" \n" +" Markdown for formatting." +msgstr "" + +#: mediagoblin/edit/forms.py:53 msgid "Website" msgstr "Webseite" -#: mediagoblin/edit/forms.py:49 +#: mediagoblin/edit/forms.py:60 msgid "Old password" msgstr "Altes Passwort" -#: mediagoblin/edit/forms.py:52 -msgid "New Password" -msgstr "Neues Passwort" +#: mediagoblin/edit/forms.py:62 +msgid "Enter your old password to prove you own this account." +msgstr "" + +#: mediagoblin/edit/forms.py:65 +msgid "New password" +msgstr "" #: mediagoblin/edit/views.py:65 msgid "An entry with that slug already exists for this user." @@ -155,39 +178,43 @@ msgstr "Du bearbeitest die Medien eines Anderen. Bitte sei vorsichtig." msgid "You are editing a user's profile. Proceed with caution." msgstr "Du bearbeitest das Profil eines Anderen. Bitte sei vorsichtig." -#: mediagoblin/edit/views.py:171 +#: mediagoblin/edit/views.py:174 +msgid "Profile changes saved" +msgstr "" + +#: mediagoblin/edit/views.py:200 msgid "Wrong password" msgstr "Falsches Passwort" -#: mediagoblin/edit/views.py:192 -msgid "Profile edited!" -msgstr "Das Profil wurde aktualisiert" +#: mediagoblin/edit/views.py:216 +msgid "Account settings saved" +msgstr "" -#: mediagoblin/media_types/__init__.py:65 -msgid "Could not find any file extension in \"{filename}\"" +#: mediagoblin/media_types/__init__.py:77 +msgid "Could not extract any file extension from \"{filename}\"" +msgstr "" + +#: mediagoblin/media_types/__init__.py:88 +msgid "Sorry, I don't support that file type :(" msgstr "" #: mediagoblin/submit/forms.py:25 msgid "File" msgstr "Datei" -#: mediagoblin/submit/forms.py:30 -msgid "Description of this work" -msgstr "Beschreibung des Werkes" - -#: mediagoblin/submit/views.py:49 +#: mediagoblin/submit/views.py:50 msgid "You must provide a file." msgstr "Du musst eine Datei angeben." -#: mediagoblin/submit/views.py:127 +#: mediagoblin/submit/views.py:128 msgid "Woohoo! Submitted!" msgstr "Yeeeaaah! Geschafft!" -#: mediagoblin/submit/views.py:133 -msgid "Invalid file type." -msgstr "Ungültiger Dateityp." +#: mediagoblin/templates/mediagoblin/404.html:22 +msgid "Image of 404 goblin stressing out" +msgstr "Bild eines angespannten Goblins" -#: mediagoblin/templates/mediagoblin/404.html:21 +#: mediagoblin/templates/mediagoblin/404.html:23 msgid "Oops!" msgstr "Hoppla!" @@ -203,33 +230,30 @@ msgstr "" "Wenn du sicher bist, dass die Adresse stimmt, wurde die Seite eventuell " "verschoben oder gelöscht." -#: mediagoblin/templates/mediagoblin/404.html:32 -msgid "Image of 404 goblin stressing out" -msgstr "Bild eines angespannten Goblins" - -#: mediagoblin/templates/mediagoblin/base.html:49 +#: mediagoblin/templates/mediagoblin/base.html:48 msgid "MediaGoblin logo" msgstr "MediaGoblin-Logo" -#: mediagoblin/templates/mediagoblin/base.html:54 -msgid "Submit media" -msgstr "Medien hochladen" +#: mediagoblin/templates/mediagoblin/base.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:157 +msgid "Add media" +msgstr "Medien hinzufügen" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:64 msgid "Verify your email!" msgstr "Bitte bestätige deine E-Mail-Adresse!" -#: mediagoblin/templates/mediagoblin/base.html:72 +#: mediagoblin/templates/mediagoblin/base.html:71 msgid "log out" msgstr "Abmelden" -#: mediagoblin/templates/mediagoblin/base.html:75 +#: mediagoblin/templates/mediagoblin/base.html:74 #: mediagoblin/templates/mediagoblin/auth/login.html:27 #: mediagoblin/templates/mediagoblin/auth/login.html:45 msgid "Log in" msgstr "Anmelden" -#: mediagoblin/templates/mediagoblin/base.html:91 +#: mediagoblin/templates/mediagoblin/base.html:86 msgid "" "Powered by MediaGoblin, a GNU project" @@ -241,46 +265,49 @@ msgstr "" msgid "Explore" msgstr "Entdecke" -#: mediagoblin/templates/mediagoblin/root.html:27 +#: mediagoblin/templates/mediagoblin/root.html:26 msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "" +msgstr "Hallo du, willkommen auf dieser MediaGoblin-Seite!" #: mediagoblin/templates/mediagoblin/root.html:28 msgid "" "This site is running MediaGoblin, an " "extraordinarily great piece of media hosting software." msgstr "" +"Diese Seite läuft mit MediaGoblin, " +"einer großartigen Software für Medienhosting." #: mediagoblin/templates/mediagoblin/root.html:29 msgid "" "To add your own media, place comments, save your favourites and more, you " "can log in with your MediaGoblin account." msgstr "" +"Melde dich mit deinem MediaGoblin-Konto an, um eigene Medien hinzuzufügen, " +"zu kommentieren, Favoriten zu speichern und mehr." #: mediagoblin/templates/mediagoblin/root.html:31 msgid "Don't have one yet? It's easy!" -msgstr "" +msgstr "Hast du noch keinen? Das geht ganz einfach!" #: mediagoblin/templates/mediagoblin/root.html:32 #, python-format msgid "" "Create an account at this site\n" -" or\n" -" Set up MediaGoblin on your own server" +" or\n" +" Set up MediaGoblin on your own server" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:44 +#: mediagoblin/templates/mediagoblin/root.html:40 msgid "Most recent media" msgstr "Neuste Medien" -#: mediagoblin/templates/mediagoblin/auth/change_fp.html:29 -msgid "Enter your new password" -msgstr "Neues Passwort eingeben" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:32 +msgid "Set your new password" +msgstr "" -#: mediagoblin/templates/mediagoblin/auth/change_fp.html:33 -#: mediagoblin/templates/mediagoblin/submit/start.html:30 -msgid "Submit" -msgstr "Bestätigen" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:35 +msgid "Set password" +msgstr "" #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" @@ -288,18 +315,7 @@ msgstr "Passwort wiederherstellen" #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:30 msgid "Send instructions" -msgstr "" - -#: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 -msgid "Your password has been changed. Try to log in now." -msgstr "Dein Passwort wurde geändert. Versuche dich jetzt einzuloggen." - -#: mediagoblin/templates/mediagoblin/auth/fp_email_sent.html:22 -msgid "" -"Check your inbox. We sent an email with a URL for changing your password." -msgstr "" -"Überprüfe deinen Posteingang. Wir haben dir eine E-Mail mit einem Link " -"geschickt, mit dem du dein Passwort ändern kannst." +msgstr "Anleitung senden" #: mediagoblin/templates/mediagoblin/auth/fp_verification_email.txt:19 #, python-format @@ -338,11 +354,11 @@ msgstr "Registriere dich hier!" msgid "Forgot your password?" msgstr "Passwort vergessen?" -#: mediagoblin/templates/mediagoblin/auth/register.html:27 +#: mediagoblin/templates/mediagoblin/auth/register.html:32 msgid "Create an account!" msgstr "Neues Konto registrieren!" -#: mediagoblin/templates/mediagoblin/auth/register.html:31 +#: mediagoblin/templates/mediagoblin/auth/register.html:36 msgid "Create" msgstr "Registrieren" @@ -373,10 +389,16 @@ msgid "Cancel" msgstr "Abbrechen" #: mediagoblin/templates/mediagoblin/edit/edit.html:37 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:40 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:35 msgid "Save changes" msgstr "Änderungen speichern" +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:34 +#, python-format +msgid "Changing %(username)s's account settings" +msgstr "" + #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29 #, python-format msgid "Editing %(username)s's profile" @@ -386,15 +408,34 @@ msgstr "%(username)ss Profil bearbeiten" #: mediagoblin/templates/mediagoblin/listings/tag.html:35 #, python-format msgid "Media tagged with: %(tag_name)s" -msgstr ": %(tag_name)s" +msgstr "Medien markiert mit: %(tag_name)s" -#: mediagoblin/templates/mediagoblin/media_displays/video.html:19 +#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 +#: mediagoblin/templates/mediagoblin/media_displays/video.html:46 msgid "Original" +msgstr "Original" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:33 +msgid "" +"Sorry, this video will not work because \n" +"\t your web browser does not support HTML5 \n" +"\t video." +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:36 +msgid "" +"You can get a modern web browser that \n" +"\t can play this video at \n" +"\t http://getfirefox.com!" msgstr "" #: mediagoblin/templates/mediagoblin/submit/start.html:26 -msgid "Submit yer media" -msgstr "Medien hochladen" +msgid "Add your media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Add" +msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format @@ -406,31 +447,57 @@ msgstr "%(username)ss Medien" msgid "%(username)s's media" msgstr "%(username)ss Medien" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:57 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:60 #, python-format -msgid "By %(username)s on %(date)s" -msgstr "Von %(username)s am %(date)s" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:67 -msgid "Post a comment" +msgid "Added on %(date)s." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:85 -msgid "at" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 -msgid "Post comment!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:124 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:69 msgid "Edit" msgstr "Bearbeiten" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:130 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:73 msgid "Delete" msgstr "Löschen" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:79 +#, python-format +msgid "%(comment_count)s comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:81 +#, python-format +msgid "%(comment_count)s comments" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:83 +msgid "No comments yet." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:91 +msgid "Add one" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:100 +msgid "" +"Type your comment here. You can use Markdown for" +" formatting." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 +msgid "Add this comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:126 +msgid "at" +msgstr "bei" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:141 +#, python-format +msgid "

❖ Browsing media by %(username)s

" +msgstr "" + #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -520,30 +587,31 @@ msgid "Here's a spot to tell others about yourself." msgstr "Hier kannst du Anderen etwas über dich erzählen." #: mediagoblin/templates/mediagoblin/user_pages/user.html:101 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:119 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:118 msgid "Edit profile" msgstr "Profil bearbeiten" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:107 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:106 msgid "This user hasn't filled in their profile (yet)." msgstr "Dieser Benutzer hat (noch) keine Daten in seinem Profil." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:133 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:125 +msgid "Change account settings" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:138 #, python-format msgid "View all of %(username)s's media" msgstr "Alle Medien von %(username)s anschauen" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:146 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:151 msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." msgstr "Hier erscheinen deine Medien. Sobald du etwas hochgeladen hast." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:152 -msgid "Add media" -msgstr "Medien hinzufügen" - -#: mediagoblin/templates/mediagoblin/user_pages/user.html:158 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:163 +#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72 msgid "There doesn't seem to be any media here yet..." msgstr "Scheinbar gibt es hier noch nichts …" @@ -555,29 +623,35 @@ msgstr "Feed-Symbol" msgid "Atom feed" msgstr "Atom-Feed" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:40 -msgid "Newer" -msgstr "Neuere" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:39 +msgid "← Newer" +msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:46 -msgid "Older" -msgstr "Ältere" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:45 +msgid "Older →" +msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:50 +#: mediagoblin/templates/mediagoblin/utils/pagination.html:48 msgid "Go to page:" +msgstr "Zu Seite:" + +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:27 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:32 +msgid "newer" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:38 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:43 +msgid "older" msgstr "" #: mediagoblin/templates/mediagoblin/utils/tags.html:20 -msgid "Tagged with" -msgstr "Markiert mit" +msgid "View more media tagged with" +msgstr "" #: mediagoblin/templates/mediagoblin/utils/tags.html:25 -msgid "and" -msgstr "und" - -#: mediagoblin/user_pages/forms.py:24 -msgid "Comment" -msgstr "Kommentar" +msgid "or" +msgstr "" #: mediagoblin/user_pages/forms.py:30 msgid "I am sure I want to delete this" @@ -585,19 +659,21 @@ msgstr "Ja, wirklich löschen" #: mediagoblin/user_pages/views.py:155 msgid "Oops, your comment was empty." -msgstr "" +msgstr "Ohh, der Kommentar war leer." #: mediagoblin/user_pages/views.py:161 msgid "Your comment has been posted!" -msgstr "" +msgstr "Dein Kommentar wurde gesendet!" #: mediagoblin/user_pages/views.py:183 msgid "You deleted the media." -msgstr "" +msgstr "Du hast das Medium gelöscht." #: mediagoblin/user_pages/views.py:190 msgid "The media was not deleted because you didn't check that you were sure." msgstr "" +"Das Medium wurde nicht gelöscht. Du musst ankreuzen, dass du es wirklich " +"löschen möchtest." #: mediagoblin/user_pages/views.py:198 msgid "You are about to delete another user's media. Proceed with caution." diff --git a/mediagoblin/i18n/en/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/en/LC_MESSAGES/mediagoblin.po index 17e6873c..3584cd4f 100644 --- a/mediagoblin/i18n/en/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/en/LC_MESSAGES/mediagoblin.po @@ -1,14 +1,14 @@ # Translations template for PROJECT. -# Copyright (C) 2011 ORGANIZATION +# Copyright (C) 2012 ORGANIZATION # This file is distributed under the same license as the PROJECT project. -# FIRST AUTHOR , 2011. +# FIRST AUTHOR , 2012. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2011-12-04 10:24-0600\n" +"POT-Creation-Date: 2012-01-07 13:47-0600\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -21,27 +21,15 @@ msgstr "" msgid "Invalid file given for media type." msgstr "" -#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 +#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41 msgid "Username" msgstr "" -#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:53 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 msgid "Password" msgstr "" -#: mediagoblin/auth/forms.py:35 -msgid "Passwords must match." -msgstr "" - -#: mediagoblin/auth/forms.py:37 -msgid "Confirm password" -msgstr "" - -#: mediagoblin/auth/forms.py:39 -msgid "Type it again here to make sure there are no spelling mistakes." -msgstr "" - -#: mediagoblin/auth/forms.py:42 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "" @@ -57,72 +45,110 @@ msgstr "" msgid "Sorry, a user with that email address already exists." msgstr "" -#: mediagoblin/auth/views.py:179 +#: mediagoblin/auth/views.py:180 msgid "" "Your email address has been verified. You may now login, edit your " "profile, and submit images!" msgstr "" -#: mediagoblin/auth/views.py:185 +#: mediagoblin/auth/views.py:186 msgid "The verification key or user id is incorrect" msgstr "" -#: mediagoblin/auth/views.py:203 +#: mediagoblin/auth/views.py:204 msgid "You must be logged in so we know who to send the email to!" msgstr "" -#: mediagoblin/auth/views.py:211 +#: mediagoblin/auth/views.py:212 msgid "You've already verified your email address!" msgstr "" -#: mediagoblin/auth/views.py:224 +#: mediagoblin/auth/views.py:225 msgid "Resent your verification email." msgstr "" -#: mediagoblin/auth/views.py:265 +#: mediagoblin/auth/views.py:260 +msgid "An email has been sent with instructions on how to change your password." +msgstr "" + +#: mediagoblin/auth/views.py:270 msgid "" "Could not send password recovery email as your username is inactive or " "your account's email address has not been verified." msgstr "" +#: mediagoblin/auth/views.py:282 +msgid "Couldn't find someone with that username or email." +msgstr "" + +#: mediagoblin/auth/views.py:330 +msgid "You can now log in using your new password." +msgstr "" + #: mediagoblin/edit/forms.py:24 mediagoblin/submit/forms.py:27 msgid "Title" msgstr "" -#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:27 mediagoblin/submit/forms.py:30 +msgid "Description of this work" +msgstr "" + +#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:31 +msgid "" +"You can use\n" +" \n" +" Markdown for formatting." +msgstr "" + +#: mediagoblin/edit/forms.py:32 mediagoblin/submit/forms.py:35 msgid "Tags" msgstr "" -#: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 -msgid "Seperate tags by commas." +#: mediagoblin/edit/forms.py:34 mediagoblin/submit/forms.py:37 +msgid "Separate tags by commas." msgstr "" -#: mediagoblin/edit/forms.py:33 +#: mediagoblin/edit/forms.py:37 msgid "Slug" msgstr "" -#: mediagoblin/edit/forms.py:34 +#: mediagoblin/edit/forms.py:38 msgid "The slug can't be empty" msgstr "" -#: mediagoblin/edit/forms.py:35 -msgid "The title part of this media's URL. You usually don't need to change this." +#: mediagoblin/edit/forms.py:39 +msgid "" +"The title part of this media's address. You usually don't need to change " +"this." msgstr "" -#: mediagoblin/edit/forms.py:42 +#: mediagoblin/edit/forms.py:46 msgid "Bio" msgstr "" -#: mediagoblin/edit/forms.py:45 +#: mediagoblin/edit/forms.py:48 +msgid "" +"You can use\n" +" \n" +" Markdown for formatting." +msgstr "" + +#: mediagoblin/edit/forms.py:53 msgid "Website" msgstr "" -#: mediagoblin/edit/forms.py:49 +#: mediagoblin/edit/forms.py:60 msgid "Old password" msgstr "" -#: mediagoblin/edit/forms.py:52 -msgid "New Password" +#: mediagoblin/edit/forms.py:62 +msgid "Enter your old password to prove you own this account." +msgstr "" + +#: mediagoblin/edit/forms.py:65 +msgid "New password" msgstr "" #: mediagoblin/edit/views.py:65 @@ -137,39 +163,43 @@ msgstr "" msgid "You are editing a user's profile. Proceed with caution." msgstr "" -#: mediagoblin/edit/views.py:171 +#: mediagoblin/edit/views.py:174 +msgid "Profile changes saved" +msgstr "" + +#: mediagoblin/edit/views.py:200 msgid "Wrong password" msgstr "" -#: mediagoblin/edit/views.py:192 -msgid "Profile edited!" +#: mediagoblin/edit/views.py:216 +msgid "Account settings saved" msgstr "" -#: mediagoblin/media_types/__init__.py:65 -msgid "Could not find any file extension in \"{filename}\"" +#: mediagoblin/media_types/__init__.py:77 +msgid "Could not extract any file extension from \"{filename}\"" +msgstr "" + +#: mediagoblin/media_types/__init__.py:88 +msgid "Sorry, I don't support that file type :(" msgstr "" #: mediagoblin/submit/forms.py:25 msgid "File" msgstr "" -#: mediagoblin/submit/forms.py:30 -msgid "Description of this work" -msgstr "" - -#: mediagoblin/submit/views.py:49 +#: mediagoblin/submit/views.py:50 msgid "You must provide a file." msgstr "" -#: mediagoblin/submit/views.py:127 +#: mediagoblin/submit/views.py:128 msgid "Woohoo! Submitted!" msgstr "" -#: mediagoblin/submit/views.py:133 -msgid "Invalid file type." +#: mediagoblin/templates/mediagoblin/404.html:22 +msgid "Image of 404 goblin stressing out" msgstr "" -#: mediagoblin/templates/mediagoblin/404.html:21 +#: mediagoblin/templates/mediagoblin/404.html:23 msgid "Oops!" msgstr "" @@ -183,33 +213,30 @@ msgid "" "has been moved or deleted." msgstr "" -#: mediagoblin/templates/mediagoblin/404.html:32 -msgid "Image of 404 goblin stressing out" -msgstr "" - -#: mediagoblin/templates/mediagoblin/base.html:49 +#: mediagoblin/templates/mediagoblin/base.html:48 msgid "MediaGoblin logo" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:54 -msgid "Submit media" +#: mediagoblin/templates/mediagoblin/base.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:157 +msgid "Add media" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:64 msgid "Verify your email!" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:72 +#: mediagoblin/templates/mediagoblin/base.html:71 msgid "log out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:75 +#: mediagoblin/templates/mediagoblin/base.html:74 #: mediagoblin/templates/mediagoblin/auth/login.html:27 #: mediagoblin/templates/mediagoblin/auth/login.html:45 msgid "Log in" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:91 +#: mediagoblin/templates/mediagoblin/base.html:86 msgid "" "Powered by MediaGoblin, a GNU project" @@ -219,7 +246,7 @@ msgstr "" msgid "Explore" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:27 +#: mediagoblin/templates/mediagoblin/root.html:26 msgid "Hi there, welcome to this MediaGoblin site!" msgstr "" @@ -244,23 +271,22 @@ msgstr "" msgid "" "Create an " "account at this site\n" -" or\n" -" Set up MediaGoblin on " "your own server" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:44 +#: mediagoblin/templates/mediagoblin/root.html:40 msgid "Most recent media" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/change_fp.html:29 -msgid "Enter your new password" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:32 +msgid "Set your new password" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/change_fp.html:33 -#: mediagoblin/templates/mediagoblin/submit/start.html:30 -msgid "Submit" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:35 +msgid "Set password" msgstr "" #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 @@ -271,14 +297,6 @@ msgstr "" msgid "Send instructions" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 -msgid "Your password has been changed. Try to log in now." -msgstr "" - -#: mediagoblin/templates/mediagoblin/auth/fp_email_sent.html:22 -msgid "Check your inbox. We sent an email with a URL for changing your password." -msgstr "" - #: mediagoblin/templates/mediagoblin/auth/fp_verification_email.txt:19 #, python-format msgid "" @@ -309,11 +327,11 @@ msgstr "" msgid "Forgot your password?" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/register.html:27 +#: mediagoblin/templates/mediagoblin/auth/register.html:32 msgid "Create an account!" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/register.html:31 +#: mediagoblin/templates/mediagoblin/auth/register.html:36 msgid "Create" msgstr "" @@ -339,10 +357,16 @@ msgid "Cancel" msgstr "" #: mediagoblin/templates/mediagoblin/edit/edit.html:37 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:40 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:35 msgid "Save changes" msgstr "" +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:34 +#, python-format +msgid "Changing %(username)s's account settings" +msgstr "" + #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29 #, python-format msgid "Editing %(username)s's profile" @@ -354,12 +378,31 @@ msgstr "" msgid "Media tagged with: %(tag_name)s" msgstr "" -#: mediagoblin/templates/mediagoblin/media_displays/video.html:19 +#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 +#: mediagoblin/templates/mediagoblin/media_displays/video.html:46 msgid "Original" msgstr "" +#: mediagoblin/templates/mediagoblin/media_displays/video.html:33 +msgid "" +"Sorry, this video will not work because \n" +"\t your web browser does not support HTML5 \n" +"\t video." +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:36 +msgid "" +"You can get a modern web browser that \n" +"\t can play this video at \n" +"\t http://getfirefox.com!" +msgstr "" + #: mediagoblin/templates/mediagoblin/submit/start.html:26 -msgid "Submit yer media" +msgid "Add your media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Add" msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 @@ -372,31 +415,57 @@ msgstr "" msgid "%(username)s's media" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:57 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:60 #, python-format -msgid "By %(username)s on %(date)s" +msgid "Added on %(date)s." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:67 -msgid "Post a comment" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:85 -msgid "at" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 -msgid "Post comment!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:124 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:69 msgid "Edit" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:130 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:73 msgid "Delete" msgstr "" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:79 +#, python-format +msgid "%(comment_count)s comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:81 +#, python-format +msgid "%(comment_count)s comments" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:83 +msgid "No comments yet." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:91 +msgid "Add one" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:100 +msgid "" +"Type your comment here. You can use Markdown " +"for formatting." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 +msgid "Add this comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:126 +msgid "at" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:141 +#, python-format +msgid "

❖ Browsing media by %(username)s

" +msgstr "" + #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -475,30 +544,31 @@ msgid "Here's a spot to tell others about yourself." msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/user.html:101 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:119 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:118 msgid "Edit profile" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:107 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:106 msgid "This user hasn't filled in their profile (yet)." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:133 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:125 +msgid "Change account settings" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:138 #, python-format msgid "View all of %(username)s's media" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:146 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:151 msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:152 -msgid "Add media" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/user.html:158 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:163 +#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72 msgid "There doesn't seem to be any media here yet..." msgstr "" @@ -510,28 +580,34 @@ msgstr "" msgid "Atom feed" msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:40 -msgid "Newer" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:39 +msgid "← Newer" msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:46 -msgid "Older" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:45 +msgid "Older →" msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:50 +#: mediagoblin/templates/mediagoblin/utils/pagination.html:48 msgid "Go to page:" msgstr "" +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:27 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:32 +msgid "newer" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:38 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:43 +msgid "older" +msgstr "" + #: mediagoblin/templates/mediagoblin/utils/tags.html:20 -msgid "Tagged with" +msgid "View more media tagged with" msgstr "" #: mediagoblin/templates/mediagoblin/utils/tags.html:25 -msgid "and" -msgstr "" - -#: mediagoblin/user_pages/forms.py:24 -msgid "Comment" +msgid "or" msgstr "" #: mediagoblin/user_pages/forms.py:30 diff --git a/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.mo index 3e0a84bf3c263d1fcca55f045823f7aac1023cb0..d0c5f2bf0774c5bfeaa2b1782d9179f1eda5bef6 100644 GIT binary patch delta 5109 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 WvQ|cAjOuptp_A)kvC6omd+NX6AP2<& diff --git a/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.po index c3c29b89..6536f4d5 100644 --- a/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.po @@ -1,5 +1,5 @@ # Translations template for PROJECT. -# Copyright (C) 2011 ORGANIZATION +# Copyright (C) 2012 ORGANIZATION # This file is distributed under the same license as the PROJECT project. # # Translators: @@ -10,9 +10,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-12-04 10:24-0600\n" -"PO-Revision-Date: 2011-12-06 20:04+0000\n" -"Last-Translator: aleksejrs \n" +"POT-Creation-Date: 2012-01-07 13:47-0600\n" +"PO-Revision-Date: 2012-01-07 19:44+0000\n" +"Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -25,27 +25,15 @@ msgstr "" msgid "Invalid file given for media type." msgstr "La provizita dosiero ne konformas al la informtipo." -#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 +#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41 msgid "Username" msgstr "Uzantnomo" -#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:53 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 msgid "Password" msgstr "Pasvorto" -#: mediagoblin/auth/forms.py:35 -msgid "Passwords must match." -msgstr "Pasvortoj devas esti egalaj." - -#: mediagoblin/auth/forms.py:37 -msgid "Confirm password" -msgstr "Retajpu pasvorton" - -#: mediagoblin/auth/forms.py:39 -msgid "Type it again here to make sure there are no spelling mistakes." -msgstr "Retajpu ĝin por certigi, ke ne okazis mistajpoj." - -#: mediagoblin/auth/forms.py:42 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "Retpoŝtadreso" @@ -61,7 +49,7 @@ msgstr "Bedaŭrinde, uzanto kun tiu nomo jam ekzistas." msgid "Sorry, a user with that email address already exists." msgstr "Ni bedaŭras, sed konto kun tiu retpoŝtadreso jam ekzistas." -#: mediagoblin/auth/views.py:179 +#: mediagoblin/auth/views.py:180 msgid "" "Your email address has been verified. You may now login, edit your profile, " "and submit images!" @@ -69,23 +57,28 @@ msgstr "" "Via retpoŝtadreso estas konfirmita. Vi povas nun ensaluti, redakti vian " "profilon, kaj alŝuti bildojn!" -#: mediagoblin/auth/views.py:185 +#: mediagoblin/auth/views.py:186 msgid "The verification key or user id is incorrect" msgstr "La kontrol-kodo aŭ la uzantonomo ne estas korekta" -#: mediagoblin/auth/views.py:203 +#: mediagoblin/auth/views.py:204 msgid "You must be logged in so we know who to send the email to!" msgstr "Vi devas esti ensalutita, por ke ni sciu, al kiu sendi la retleteron!" -#: mediagoblin/auth/views.py:211 +#: mediagoblin/auth/views.py:212 msgid "You've already verified your email address!" msgstr "Vi jam konfirmis vian retpoŝtadreson!" -#: mediagoblin/auth/views.py:224 +#: mediagoblin/auth/views.py:225 msgid "Resent your verification email." msgstr "Resendi vian kontrol-mesaĝon." -#: mediagoblin/auth/views.py:265 +#: mediagoblin/auth/views.py:260 +msgid "" +"An email has been sent with instructions on how to change your password." +msgstr "" + +#: mediagoblin/auth/views.py:270 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." @@ -93,48 +86,77 @@ msgstr "" "Ni ne povas sendi pasvortsavan retleteron, ĉar aŭ via konto estas neaktiva, " "aŭ ĝia retpoŝtadreso ne estis konfirmita." +#: mediagoblin/auth/views.py:282 +msgid "Couldn't find someone with that username or email." +msgstr "" + +#: mediagoblin/auth/views.py:330 +msgid "You can now log in using your new password." +msgstr "" + #: mediagoblin/edit/forms.py:24 mediagoblin/submit/forms.py:27 msgid "Title" msgstr "Titolo" -#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:27 mediagoblin/submit/forms.py:30 +msgid "Description of this work" +msgstr "Priskribo de ĉi tiu verko" + +#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:31 +msgid "" +"You can use\n" +" \n" +" Markdown for formatting." +msgstr "" + +#: mediagoblin/edit/forms.py:32 mediagoblin/submit/forms.py:35 msgid "Tags" msgstr "Etikedoj" -#: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 -msgid "Seperate tags by commas." -msgstr "Dividu la etikedojn per komoj." +#: mediagoblin/edit/forms.py:34 mediagoblin/submit/forms.py:37 +msgid "Separate tags by commas." +msgstr "" -#: mediagoblin/edit/forms.py:33 +#: mediagoblin/edit/forms.py:37 msgid "Slug" msgstr "La distingiga adresparto" -#: mediagoblin/edit/forms.py:34 +#: mediagoblin/edit/forms.py:38 msgid "The slug can't be empty" msgstr "La distingiga adresparto ne povas esti malplena" -#: mediagoblin/edit/forms.py:35 +#: mediagoblin/edit/forms.py:39 msgid "" -"The title part of this media's URL. You usually don't need to change this." +"The title part of this media's address. You usually don't need to change " +"this." msgstr "" -"La parto de la dosieradreso, bazita sur la dosiertitolo. Ordinare ne necesas" -" ĝin ŝanĝi." -#: mediagoblin/edit/forms.py:42 +#: mediagoblin/edit/forms.py:46 msgid "Bio" msgstr "Bio" -#: mediagoblin/edit/forms.py:45 +#: mediagoblin/edit/forms.py:48 +msgid "" +"You can use\n" +" \n" +" Markdown for formatting." +msgstr "" + +#: mediagoblin/edit/forms.py:53 msgid "Website" msgstr "Retejo" -#: mediagoblin/edit/forms.py:49 +#: mediagoblin/edit/forms.py:60 msgid "Old password" msgstr "La malnova pasvorto" -#: mediagoblin/edit/forms.py:52 -msgid "New Password" -msgstr "La nova pasvorto" +#: mediagoblin/edit/forms.py:62 +msgid "Enter your old password to prove you own this account." +msgstr "" + +#: mediagoblin/edit/forms.py:65 +msgid "New password" +msgstr "" #: mediagoblin/edit/views.py:65 msgid "An entry with that slug already exists for this user." @@ -148,39 +170,43 @@ msgstr "Vi priredaktas dosieron de alia uzanto. Agu singardeme." msgid "You are editing a user's profile. Proceed with caution." msgstr "Vi redaktas profilon de alia uzanto. Agu singardeme." -#: mediagoblin/edit/views.py:171 +#: mediagoblin/edit/views.py:174 +msgid "Profile changes saved" +msgstr "" + +#: mediagoblin/edit/views.py:200 msgid "Wrong password" msgstr "Malĝusta pasvorto" -#: mediagoblin/edit/views.py:192 -msgid "Profile edited!" -msgstr "La profilŝanĝo faritas!" +#: mediagoblin/edit/views.py:216 +msgid "Account settings saved" +msgstr "" -#: mediagoblin/media_types/__init__.py:65 -msgid "Could not find any file extension in \"{filename}\"" -msgstr "Ŝajnas, ke en «{filename}» mankas dosiernoma finaĵo" +#: mediagoblin/media_types/__init__.py:77 +msgid "Could not extract any file extension from \"{filename}\"" +msgstr "" + +#: mediagoblin/media_types/__init__.py:88 +msgid "Sorry, I don't support that file type :(" +msgstr "" #: mediagoblin/submit/forms.py:25 msgid "File" msgstr "Dosiero" -#: mediagoblin/submit/forms.py:30 -msgid "Description of this work" -msgstr "Priskribo de ĉi tiu verko" - -#: mediagoblin/submit/views.py:49 +#: mediagoblin/submit/views.py:50 msgid "You must provide a file." msgstr "Vi devas provizi dosieron." -#: mediagoblin/submit/views.py:127 +#: mediagoblin/submit/views.py:128 msgid "Woohoo! Submitted!" msgstr "Hura! Alŝutitas!" -#: mediagoblin/submit/views.py:133 -msgid "Invalid file type." -msgstr "Netaŭga dosiertipo." +#: mediagoblin/templates/mediagoblin/404.html:22 +msgid "Image of 404 goblin stressing out" +msgstr "Bildo de 404-koboldo penŝvitanta." -#: mediagoblin/templates/mediagoblin/404.html:21 +#: mediagoblin/templates/mediagoblin/404.html:23 msgid "Oops!" msgstr "Oj!" @@ -196,33 +222,30 @@ msgstr "" "Se vi estas certa, ke la adreso estas ĝusta, eble la serĉata de vi paĝo " "estis movita aŭ forigita." -#: mediagoblin/templates/mediagoblin/404.html:32 -msgid "Image of 404 goblin stressing out" -msgstr "Bildo de 404-koboldo penŝvitanta." - -#: mediagoblin/templates/mediagoblin/base.html:49 +#: mediagoblin/templates/mediagoblin/base.html:48 msgid "MediaGoblin logo" msgstr "Emblemo de MediaGoblin" -#: mediagoblin/templates/mediagoblin/base.html:54 -msgid "Submit media" -msgstr "Alŝuti aŭd-vid-dosieron" +#: mediagoblin/templates/mediagoblin/base.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:157 +msgid "Add media" +msgstr "Aldoni dosieron" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:64 msgid "Verify your email!" msgstr "Konfirmu viecon de la retpoŝtadreso!" -#: mediagoblin/templates/mediagoblin/base.html:72 +#: mediagoblin/templates/mediagoblin/base.html:71 msgid "log out" msgstr "elsaluti" -#: mediagoblin/templates/mediagoblin/base.html:75 +#: mediagoblin/templates/mediagoblin/base.html:74 #: mediagoblin/templates/mediagoblin/auth/login.html:27 #: mediagoblin/templates/mediagoblin/auth/login.html:45 msgid "Log in" msgstr "Ensaluti" -#: mediagoblin/templates/mediagoblin/base.html:91 +#: mediagoblin/templates/mediagoblin/base.html:86 msgid "" "Powered by MediaGoblin, a GNU project" @@ -234,7 +257,7 @@ msgstr "" msgid "Explore" msgstr "Ĉirkaŭrigardi" -#: mediagoblin/templates/mediagoblin/root.html:27 +#: mediagoblin/templates/mediagoblin/root.html:26 msgid "Hi there, welcome to this MediaGoblin site!" msgstr "Saluton, kaj bonvenon al ĉi tiu MediaGoblina retpaĝaro!" @@ -263,25 +286,21 @@ msgstr "Ĉu vi ankoraŭ ne havas tian? Ne malĝoju!" #, python-format msgid "" "Create an account at this site\n" -" or\n" -" Set up MediaGoblin on your own server" +" or\n" +" Set up MediaGoblin on your own server" msgstr "" -"Kreu konton en ĉi tiu retejo\n" -" aŭ\n" -" Ekfunkciigu MediaGoblin’on en via propra servilo" -#: mediagoblin/templates/mediagoblin/root.html:44 +#: mediagoblin/templates/mediagoblin/root.html:40 msgid "Most recent media" msgstr "Laste aldonitaj dosieroj" -#: mediagoblin/templates/mediagoblin/auth/change_fp.html:29 -msgid "Enter your new password" -msgstr "Enigu vian novan pasvorton" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:32 +msgid "Set your new password" +msgstr "" -#: mediagoblin/templates/mediagoblin/auth/change_fp.html:33 -#: mediagoblin/templates/mediagoblin/submit/start.html:30 -msgid "Submit" -msgstr "Alŝuti" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:35 +msgid "Set password" +msgstr "" #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" @@ -291,17 +310,6 @@ msgstr "Ekhavo de nova pasvorto" msgid "Send instructions" msgstr "Sendi instrukcion" -#: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 -msgid "Your password has been changed. Try to log in now." -msgstr "Via pasvorto estis ŝanĝita. Nun provu ensaluti." - -#: mediagoblin/templates/mediagoblin/auth/fp_email_sent.html:22 -msgid "" -"Check your inbox. We sent an email with a URL for changing your password." -msgstr "" -"Kontrolu vian retleterujon. Ni sendis retleteron kun retadreso por ŝanĝo de " -"via pasvorto." - #: mediagoblin/templates/mediagoblin/auth/fp_verification_email.txt:19 #, python-format msgid "" @@ -339,11 +347,11 @@ msgstr "Kreu ĝin ĉi tie!" msgid "Forgot your password?" msgstr "Ĉu vi forgesis vian pasvorton?" -#: mediagoblin/templates/mediagoblin/auth/register.html:27 +#: mediagoblin/templates/mediagoblin/auth/register.html:32 msgid "Create an account!" msgstr "Kreu konton!" -#: mediagoblin/templates/mediagoblin/auth/register.html:31 +#: mediagoblin/templates/mediagoblin/auth/register.html:36 msgid "Create" msgstr "Krei" @@ -374,10 +382,16 @@ msgid "Cancel" msgstr "Nuligi" #: mediagoblin/templates/mediagoblin/edit/edit.html:37 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:40 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:35 msgid "Save changes" msgstr "Konservi ŝanĝojn" +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:34 +#, python-format +msgid "Changing %(username)s's account settings" +msgstr "" + #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29 #, python-format msgid "Editing %(username)s's profile" @@ -389,13 +403,32 @@ msgstr "Redaktado de l’profilo de %(username)s'" msgid "Media tagged with: %(tag_name)s" msgstr "Dosieroj kun etikedo: %(tag_name)s" -#: mediagoblin/templates/mediagoblin/media_displays/video.html:19 +#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 +#: mediagoblin/templates/mediagoblin/media_displays/video.html:46 msgid "Original" msgstr "Originalo" +#: mediagoblin/templates/mediagoblin/media_displays/video.html:33 +msgid "" +"Sorry, this video will not work because \n" +"\t your web browser does not support HTML5 \n" +"\t video." +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:36 +msgid "" +"You can get a modern web browser that \n" +"\t can play this video at \n" +"\t http://getfirefox.com!" +msgstr "" + #: mediagoblin/templates/mediagoblin/submit/start.html:26 -msgid "Submit yer media" -msgstr "Alŝutu vian aŭd-vid-dosieron" +msgid "Add your media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Add" +msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format @@ -407,31 +440,57 @@ msgstr "Dosieroj de %(username)s" msgid "%(username)s's media" msgstr "Dosieroj de %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:57 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:60 #, python-format -msgid "By %(username)s on %(date)s" -msgstr "Afiŝita de %(username)s je %(date)s" +msgid "Added on %(date)s." +msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:67 -msgid "Post a comment" -msgstr "Afiŝi komenton" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:85 -msgid "at" -msgstr "je" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 -msgid "Post comment!" -msgstr "Afiŝi la komenton!" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:124 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:69 msgid "Edit" msgstr "Ŝanĝi" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:130 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:73 msgid "Delete" msgstr "Forigi" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:79 +#, python-format +msgid "%(comment_count)s comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:81 +#, python-format +msgid "%(comment_count)s comments" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:83 +msgid "No comments yet." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:91 +msgid "Add one" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:100 +msgid "" +"Type your comment here. You can use Markdown for" +" formatting." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 +msgid "Add this comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:126 +msgid "at" +msgstr "je" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:141 +#, python-format +msgid "

❖ Browsing media by %(username)s

" +msgstr "" + #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -519,31 +578,32 @@ msgid "Here's a spot to tell others about yourself." msgstr "Jen estas spaceto por rakonti pri vi al aliaj." #: mediagoblin/templates/mediagoblin/user_pages/user.html:101 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:119 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:118 msgid "Edit profile" msgstr "Redakti profilon" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:107 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:106 msgid "This user hasn't filled in their profile (yet)." msgstr "Ĉi tiu uzanto ne jam aldonis informojn pri si." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:133 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:125 +msgid "Change account settings" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:138 #, python-format msgid "View all of %(username)s's media" msgstr "Rigardi ĉiujn dosierojn de %(username)s'" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:146 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:151 msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." msgstr "" "Ĝuste ĉi tie aperos viaj dosieroj, sed vi ŝajne ankoraŭ nenion alŝutis." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:152 -msgid "Add media" -msgstr "Aldoni dosieron" - -#: mediagoblin/templates/mediagoblin/user_pages/user.html:158 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:163 +#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72 msgid "There doesn't seem to be any media here yet..." msgstr "Ĉi tie ŝajne estas ankoraŭ neniuj dosieroj…" @@ -555,29 +615,35 @@ msgstr "flusimbolo" msgid "Atom feed" msgstr "Atom-a informfluo" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:40 -msgid "Newer" -msgstr "Plinovaj" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:39 +msgid "← Newer" +msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:46 -msgid "Older" -msgstr "Malplinovaj" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:45 +msgid "Older →" +msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:50 +#: mediagoblin/templates/mediagoblin/utils/pagination.html:48 msgid "Go to page:" msgstr "Iri al paĝo:" +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:27 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:32 +msgid "newer" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:38 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:43 +msgid "older" +msgstr "" + #: mediagoblin/templates/mediagoblin/utils/tags.html:20 -msgid "Tagged with" -msgstr "Markita per: " +msgid "View more media tagged with" +msgstr "" #: mediagoblin/templates/mediagoblin/utils/tags.html:25 -msgid "and" -msgstr "kaj" - -#: mediagoblin/user_pages/forms.py:24 -msgid "Comment" -msgstr "Komento" +msgid "or" +msgstr "" #: mediagoblin/user_pages/forms.py:30 msgid "I am sure I want to delete this" diff --git a/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.mo index 0f7f4026aafb3f78d9f6d073c48985f57dc924e7..b9f8eeed37508b74ebf0fdc0cb3eb07e6df84ac2 100644 GIT binary patch delta 5082 zcmc)L4{TLe9l-JP+OqzELjOQ%S7;A^N?V|Pucfq5yE6WcIVh|{XGa*j@4eghvG?A6 z-g`^w6yC-Lof{^k*KJWp)VXMk%ZxO02{UdBE=GgQKMArCP$5JUoSMuf!#~mQ@4eST zVK7maz4Y~S|D1cy@BGfWzjyNfqtWD_jf9RhWw#ut=$-+QPw9E|^$?F1F$@uE!tYCoy-j zQcJNLrK87DIv&AW@M)Zhhp-M`Lh0uWK7=!-DAkMyQQ9BH62@0QCBBkr*0_q z9+q=GuP{CHIatMc2TGE*B2Cl-CUsW2<_@C-atvkW+00g+pNumYUlnmc zkZJ)g#%A1&+wnJe8W-V9)0C>l-{TPah&qIy!#Vg{ES2lUO3lR?C^KD#lGzm~_q$P+ zrWcda;cgBj1BZ}5^& z7bT;wqm1{qN1D1rSN<@Gv`lF~n+%zV=P^j@k)x=?K>?e0UV3kFI% zOYSqi`T_?8t6snsJdP4bc1=3cc9aaPMwUeC(8A#a-6gtE3Fl-G6- zN?=c-4Dc*Ure4K-{3S{zPN7WrY(4qU;~-~Yx&jtrl=BMYjZ^zkX7Ft0{3teX{uWB6 za@oQZL)C#2=mwOfFi-+|2&JE4oP>w42fvBTN&RaP`Ii(f;AL+@6A4Z|gSX-97{q_0 z%pl0{0<&m*y_6Sx_Dr1>CrqwKA7Ne*&3C<`d{1XiIG zjPIbNu9jY8X3LS~Rb421z(on@Aj(pF1?BB|5xemXT!H0`atD3}AH}aDlUMVXqytZG z=3s;iU&B4vOkOEk>if7Ae~L2G8s0IIpw^(Q?PqZizl2#hg&jK?r{PqrL`nI=i~*E( zttf#nM^#hT9I|3DGwyB=Sp#vm-qD$JZe8P!;pm`g#u+5;dOi8GOGEueyw6NOnlKz^ z(6T*${z%ViBOWrNYIXXyaYbzD>oSj;x&gc2P(!MP+iv80y=ugbQ`^rqJ=s7?EVq2 zqiC7;?V?0sIw_eI@T!W3ml-x$)ULs@1cy?O8&0FT$8^WzNS&lsAZ`whU-ga@n{)2e zVM`|I3?vek?WU*J8;R24P{P#hb>7C33NKLdWy7-Vp~dM5?2Lp>i&R9TsqC>X53+P2 zgOuoke9b2{*q|BILD^KM%_ydmYCJa3`YjtbEX}k|_1EaVU-DS45f0m?|BdztO3CSwp@tBelI7)u&SX#+z5xR{7}&DT`UQnRzY9 zb06DR_JP+^b|KkEo(&p=*=hRn8K*W$IvWyjB5Dj>o;`NZmGRS+1mA1zYGl%LJJSzm zCO7e>L_J55jM`K-;?|&!T75bqiIJ_J%G`v-ZlBqe%p|TrR_N-_mEqh_I=c{R0Yl*z2G5t*z-wZrC4bEibHk^TuoWTUB@YTGz&1mM`@#-AGx# zT_4Ey{xI*ztjmh+)s_8~`K|ezWXq+>`^EVyyuCFsZ(4EQ#1cQU;Mmgtt-POKVAS1{ zuG$}7<=57}9n3UN{YHI6CBCOF=4~sj9xL-+vb27*y8b{`a*O=hq%!?+)cY>){Y4wD zSL#PsFD~{a$LiI`RrAM+{(oEZyBqEvkC`9L2{rao{l9tD_EMkYbvOAzKd)nXyfUVn a7s>eeC0CC>`i+KdKCj(hRdKDlul@tIjkI$B delta 3534 zcmZY9du$ZP9l-H9JG^XTFpuCsz+)2}+u*}zz{UncjCs^RjRUSoh>~jVZhc;Iw`+Fy zY}^!Gl>%wfG(z2^N=5!CX+@$Y{6X%IDx!H1M-f$tP%E`1EwrMqsPsXpBK0NFet&mo z8c_@UnVp@T`OR;B&ZS$GpW@ZY!-+v!|~M^N79`6W}og);6uPFE_Y{z0Rkj{hKYs{RV4=Hi1G!#I8c zpGQ7Wb1IdZhj*ilYewnsF7@|fEzd)^7&EvGzk+w+D_DiE<095qZSC6onBe(UtY>{yHAkuW z7{vzMg0e#kWoL&=&pDKFUq?BL(ZU1~i_2K!M0OrR|MW#pea!7myA zat-;Hl%AtwKfa4nG_`Dh6%L@B;S(6cZ=hu40?LG!P!_y`auk0?neU&t9dF?x+(z1V z;-e_@zKWgrllkO7N@F%9u5lv{;iLE^d;?eG8qy${N}!K6ZpN!98CyzzSxYsd#x9ha zIZ*14qhv6PeRvclfD1Vq8)!(FJ76QyrH*1ZoMiS20P9^}TVH<6gt`?v|O;5)d4J4r@!>K8O5b=Oc9{siTWr&Bout7fAV zQzObm51`zVhfu~nfl`!DqKrFHdjDOl=lMfii#L$i)qT1cXfMu?`@fS0n^t>KipjxE zn8PpP+xQ#Yz-&?rb*$cqd+@6`h6yZNUJPs)WkXM+jDHCw>0gf$ z-~r50;3`8SjZdO1bOR-j2)`(B)r76M2_=W#^qJ*JT&Vjt}4#OroUj6?_Okz<#V_){SUm3{PVV zUdBNz=ivknq1=|=q1=kvmE`{!8k)Pc3tvOYz~51JHjBR&BttF3S-2G?zyXx&6UV(c zft&Fn?!YS2HGo4XMf+`h1ka&tU=e?G7^*rp(2%oC;5Z(~F1&>iTu%j+VK-J{4_0G8 zhNotRGqiTS3a!J=S+C9NO(u25O4=qoUeO!Qtvnvt5`IlL=d|nS6-`MKSk1obGfu)v ztG*E{@wlFFv!1q{xO+IN_gmVxoIo2#TNz`g^|&33Xrn*3cefsPJ)IaaPRe#t#g9gf z?~l7)GOGIAOos2!8MeKQo_a$^Hl5UtJ3Y|Dwv!A`H7qEzop46gGx_(c=0~a=Yy9@$ zd|7ozc~!qNX3}<&;b|+3)r8f9rB&2`HEwy~)tZ*Da^Ct_sn^$;tRLu%2@)ewHR#ed zI#CLz@K}1N4}0f%GssL}CF{d?=RLL1^2mk`Ov=~siNZI=kA}JVR@k?oCS11Qo2#?& zj2)qwpel8I^DjeyS*)ZXX&EajB#9o%^ubpGua0+RwizF z(P4i$e{*ShBy6rbv`S|k4k1fL7)^|pPo8}{u-%QT%_b^!>c=fs?SoDI4%?RQe1#pixjJ6UT?3jFr!`K}eumMhsU43eDpE={il5lM&VUu*ZVv-bkZ9&$ zauA*>Qi!K;&eAb?=5}gJeWi&=EP;onHM4)Wk>jG~B%{IPnIM}kB!_g%QOc=HMan)4 zb42xk>t#$@c2u~Ij+L;eR|&3k;(Xxdmqec{+qun8cy_!{J8~ATHixp4XNvVfJ*2Xp z@i;0LVSjSBN6dsCHffoSPS*?ElxK$7N4O%kCx0R~Hxdr6*^@uJ_L0bjeMBWIPUi2d eG2Ji0a-VF+PDl;i!Ej*yoG@ diff --git a/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.po index 406e1923..ab8c6b3f 100644 --- a/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.po @@ -1,5 +1,5 @@ # Translations template for PROJECT. -# Copyright (C) 2011 ORGANIZATION +# Copyright (C) 2012 ORGANIZATION # This file is distributed under the same license as the PROJECT project. # # Translators: @@ -15,9 +15,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-12-04 10:24-0600\n" -"PO-Revision-Date: 2011-12-05 23:20+0000\n" -"Last-Translator: manolinux \n" +"POT-Creation-Date: 2012-01-07 13:47-0600\n" +"PO-Revision-Date: 2012-01-07 19:44+0000\n" +"Last-Translator: cwebber \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" @@ -30,28 +30,15 @@ msgstr "" msgid "Invalid file given for media type." msgstr "Archivo inválido para el formato seleccionado." -#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 +#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41 msgid "Username" msgstr "Nombre de usuario" -#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:53 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 msgid "Password" msgstr "Contraseña" -#: mediagoblin/auth/forms.py:35 -msgid "Passwords must match." -msgstr "Las contraseñas deben coincidir." - -#: mediagoblin/auth/forms.py:37 -msgid "Confirm password" -msgstr "Confirma tu contraseña" - -#: mediagoblin/auth/forms.py:39 -msgid "Type it again here to make sure there are no spelling mistakes." -msgstr "" -"Escriba de nuevo aquí para asegurarse de que no hay faltas de ortografía." - -#: mediagoblin/auth/forms.py:42 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "Dirección de correo electrónico" @@ -67,7 +54,7 @@ msgstr "Lo sentimos, ya existe un usuario con ese nombre." msgid "Sorry, a user with that email address already exists." msgstr "Lo sentimos, ya existe un usuario con esa dirección de email." -#: mediagoblin/auth/views.py:179 +#: mediagoblin/auth/views.py:180 msgid "" "Your email address has been verified. You may now login, edit your profile, " "and submit images!" @@ -75,26 +62,31 @@ msgstr "" "Tu dirección de correo electrónico ha sido verificada. ¡Ahora puedes " "ingresar, editar tu perfil, y enviar imágenes!" -#: mediagoblin/auth/views.py:185 +#: mediagoblin/auth/views.py:186 msgid "The verification key or user id is incorrect" msgstr "" "La clave de verificación o la identificación de usuario son incorrectas" -#: mediagoblin/auth/views.py:203 +#: mediagoblin/auth/views.py:204 msgid "You must be logged in so we know who to send the email to!" msgstr "" "¡Debes iniciar sesión para que podamos saber a quién le enviamos el correo " "electrónico!" -#: mediagoblin/auth/views.py:211 +#: mediagoblin/auth/views.py:212 msgid "You've already verified your email address!" msgstr "¡Ya has verificado tu dirección de correo!" -#: mediagoblin/auth/views.py:224 +#: mediagoblin/auth/views.py:225 msgid "Resent your verification email." msgstr "Se reenvió tu correo electrónico de verificación." -#: mediagoblin/auth/views.py:265 +#: mediagoblin/auth/views.py:260 +msgid "" +"An email has been sent with instructions on how to change your password." +msgstr "" + +#: mediagoblin/auth/views.py:270 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." @@ -103,48 +95,77 @@ msgstr "" "porque su nombre de usuario está inactivo o la dirección de su cuenta de " "correo electrónico no ha sido verificada." +#: mediagoblin/auth/views.py:282 +msgid "Couldn't find someone with that username or email." +msgstr "" + +#: mediagoblin/auth/views.py:330 +msgid "You can now log in using your new password." +msgstr "" + #: mediagoblin/edit/forms.py:24 mediagoblin/submit/forms.py:27 msgid "Title" msgstr "Título" -#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:27 mediagoblin/submit/forms.py:30 +msgid "Description of this work" +msgstr "Descripción de esta obra" + +#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:31 +msgid "" +"You can use\n" +" \n" +" Markdown for formatting." +msgstr "" + +#: mediagoblin/edit/forms.py:32 mediagoblin/submit/forms.py:35 msgid "Tags" msgstr "Etiquetas" -#: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 -msgid "Seperate tags by commas." -msgstr "Separa las etiquetas con comas." +#: mediagoblin/edit/forms.py:34 mediagoblin/submit/forms.py:37 +msgid "Separate tags by commas." +msgstr "" -#: mediagoblin/edit/forms.py:33 +#: mediagoblin/edit/forms.py:37 msgid "Slug" msgstr "Ficha" -#: mediagoblin/edit/forms.py:34 +#: mediagoblin/edit/forms.py:38 msgid "The slug can't be empty" msgstr "La ficha no puede estar vacía" -#: mediagoblin/edit/forms.py:35 +#: mediagoblin/edit/forms.py:39 msgid "" -"The title part of this media's URL. You usually don't need to change this." +"The title part of this media's address. You usually don't need to change " +"this." msgstr "" -"La parte del título de la URL de este contenido. Normalmente no necesitas " -"cambiar esto." -#: mediagoblin/edit/forms.py:42 +#: mediagoblin/edit/forms.py:46 msgid "Bio" msgstr "Bio" -#: mediagoblin/edit/forms.py:45 +#: mediagoblin/edit/forms.py:48 +msgid "" +"You can use\n" +" \n" +" Markdown for formatting." +msgstr "" + +#: mediagoblin/edit/forms.py:53 msgid "Website" msgstr "Sitio web" -#: mediagoblin/edit/forms.py:49 +#: mediagoblin/edit/forms.py:60 msgid "Old password" msgstr "Vieja contraseña" -#: mediagoblin/edit/forms.py:52 -msgid "New Password" -msgstr "Nueva contraseña" +#: mediagoblin/edit/forms.py:62 +msgid "Enter your old password to prove you own this account." +msgstr "" + +#: mediagoblin/edit/forms.py:65 +msgid "New password" +msgstr "" #: mediagoblin/edit/views.py:65 msgid "An entry with that slug already exists for this user." @@ -158,39 +179,43 @@ msgstr "Estás editando el contenido de otro usuario. Proceder con precaución." msgid "You are editing a user's profile. Proceed with caution." msgstr "Estás editando un perfil de usuario. Proceder con precaución." -#: mediagoblin/edit/views.py:171 +#: mediagoblin/edit/views.py:174 +msgid "Profile changes saved" +msgstr "" + +#: mediagoblin/edit/views.py:200 msgid "Wrong password" msgstr "Contraseña incorrecta" -#: mediagoblin/edit/views.py:192 -msgid "Profile edited!" -msgstr "¡Perfil editado!" +#: mediagoblin/edit/views.py:216 +msgid "Account settings saved" +msgstr "" -#: mediagoblin/media_types/__init__.py:65 -msgid "Could not find any file extension in \"{filename}\"" -msgstr "No se pudo encontrar la extensión del archivo en \"{filename}\"" +#: mediagoblin/media_types/__init__.py:77 +msgid "Could not extract any file extension from \"{filename}\"" +msgstr "" + +#: mediagoblin/media_types/__init__.py:88 +msgid "Sorry, I don't support that file type :(" +msgstr "" #: mediagoblin/submit/forms.py:25 msgid "File" msgstr "Archivo" -#: mediagoblin/submit/forms.py:30 -msgid "Description of this work" -msgstr "Descripción de esta obra" - -#: mediagoblin/submit/views.py:49 +#: mediagoblin/submit/views.py:50 msgid "You must provide a file." msgstr "Debes proporcionar un archivo." -#: mediagoblin/submit/views.py:127 +#: mediagoblin/submit/views.py:128 msgid "Woohoo! Submitted!" msgstr "¡Yujú! ¡Enviado!" -#: mediagoblin/submit/views.py:133 -msgid "Invalid file type." -msgstr "Tipo de archivo inválido." +#: mediagoblin/templates/mediagoblin/404.html:22 +msgid "Image of 404 goblin stressing out" +msgstr "Imagen de 404 goblin estresándose" -#: mediagoblin/templates/mediagoblin/404.html:21 +#: mediagoblin/templates/mediagoblin/404.html:23 msgid "Oops!" msgstr "¡Ups!" @@ -206,33 +231,30 @@ msgstr "" "Si estás seguro que la dirección es correcta, puede ser que la pagina haya " "sido movida o borrada." -#: mediagoblin/templates/mediagoblin/404.html:32 -msgid "Image of 404 goblin stressing out" -msgstr "Imagen de 404 goblin estresándose" - -#: mediagoblin/templates/mediagoblin/base.html:49 +#: mediagoblin/templates/mediagoblin/base.html:48 msgid "MediaGoblin logo" msgstr "Logo de MediaGoblin" -#: mediagoblin/templates/mediagoblin/base.html:54 -msgid "Submit media" -msgstr "Enviar contenido" +#: mediagoblin/templates/mediagoblin/base.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:157 +msgid "Add media" +msgstr "Añadir contenido" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:64 msgid "Verify your email!" msgstr "¡Verifica tu email!" -#: mediagoblin/templates/mediagoblin/base.html:72 +#: mediagoblin/templates/mediagoblin/base.html:71 msgid "log out" msgstr "Cerrar sesión" -#: mediagoblin/templates/mediagoblin/base.html:75 +#: mediagoblin/templates/mediagoblin/base.html:74 #: mediagoblin/templates/mediagoblin/auth/login.html:27 #: mediagoblin/templates/mediagoblin/auth/login.html:45 msgid "Log in" msgstr "Conectarse" -#: mediagoblin/templates/mediagoblin/base.html:91 +#: mediagoblin/templates/mediagoblin/base.html:86 msgid "" "Powered by MediaGoblin, a GNU project" @@ -244,7 +266,7 @@ msgstr "" msgid "Explore" msgstr "Explorar" -#: mediagoblin/templates/mediagoblin/root.html:27 +#: mediagoblin/templates/mediagoblin/root.html:26 msgid "Hi there, welcome to this MediaGoblin site!" msgstr "Hola, ¡bienvenido a este sitio de MediaGoblin!" @@ -273,25 +295,21 @@ msgstr "¿Aún no tienes una? ¡Es fácil!" #, python-format msgid "" "Create an account at this site\n" -" or\n" -" Set up MediaGoblin on your own server" +" or\n" +" Set up MediaGoblin on your own server" msgstr "" -"Crea una cuenta en este sitio\n" -" o\n" -" Instala MediaGoblin en tu propio servidor" -#: mediagoblin/templates/mediagoblin/root.html:44 +#: mediagoblin/templates/mediagoblin/root.html:40 msgid "Most recent media" msgstr "El contenido más reciente" -#: mediagoblin/templates/mediagoblin/auth/change_fp.html:29 -msgid "Enter your new password" -msgstr "Ingrese su nueva contraseña" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:32 +msgid "Set your new password" +msgstr "" -#: mediagoblin/templates/mediagoblin/auth/change_fp.html:33 -#: mediagoblin/templates/mediagoblin/submit/start.html:30 -msgid "Submit" -msgstr "Enviar" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:35 +msgid "Set password" +msgstr "" #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" @@ -301,17 +319,6 @@ msgstr "Recuperar contraseña" msgid "Send instructions" msgstr "Enviar instrucciones" -#: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 -msgid "Your password has been changed. Try to log in now." -msgstr "Se cambió tu contraseña. Intenta iniciar sesión ahora." - -#: mediagoblin/templates/mediagoblin/auth/fp_email_sent.html:22 -msgid "" -"Check your inbox. We sent an email with a URL for changing your password." -msgstr "" -"Revisa tu bandeja de entrada. Te enviamos un correo electrónico con una URL " -"para cambiar tu contraseña." - #: mediagoblin/templates/mediagoblin/auth/fp_verification_email.txt:19 #, python-format msgid "" @@ -349,11 +356,11 @@ msgstr "¡Crea una aquí!" msgid "Forgot your password?" msgstr "¿Olvidaste tu contraseña?" -#: mediagoblin/templates/mediagoblin/auth/register.html:27 +#: mediagoblin/templates/mediagoblin/auth/register.html:32 msgid "Create an account!" msgstr "¡Crea una cuenta!" -#: mediagoblin/templates/mediagoblin/auth/register.html:31 +#: mediagoblin/templates/mediagoblin/auth/register.html:36 msgid "Create" msgstr "Crear" @@ -384,10 +391,16 @@ msgid "Cancel" msgstr "Cancelar" #: mediagoblin/templates/mediagoblin/edit/edit.html:37 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:40 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:35 msgid "Save changes" msgstr "Guardar cambios" +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:34 +#, python-format +msgid "Changing %(username)s's account settings" +msgstr "" + #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29 #, python-format msgid "Editing %(username)s's profile" @@ -399,13 +412,32 @@ msgstr "Editando el perfil de %(username)s" msgid "Media tagged with: %(tag_name)s" msgstr "Contenido etiquetado con: %(tag_name)s" -#: mediagoblin/templates/mediagoblin/media_displays/video.html:19 +#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 +#: mediagoblin/templates/mediagoblin/media_displays/video.html:46 msgid "Original" msgstr "Original" +#: mediagoblin/templates/mediagoblin/media_displays/video.html:33 +msgid "" +"Sorry, this video will not work because \n" +"\t your web browser does not support HTML5 \n" +"\t video." +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:36 +msgid "" +"You can get a modern web browser that \n" +"\t can play this video at \n" +"\t http://getfirefox.com!" +msgstr "" + #: mediagoblin/templates/mediagoblin/submit/start.html:26 -msgid "Submit yer media" -msgstr "Envía tu contenido" +msgid "Add your media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Add" +msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format @@ -417,31 +449,57 @@ msgstr "Contenidos de %(username)s" msgid "%(username)s's media" msgstr "Contenido de %(username)s's" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:57 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:60 #, python-format -msgid "By %(username)s on %(date)s" -msgstr "Por %(username)s en %(date)s" +msgid "Added on %(date)s." +msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:67 -msgid "Post a comment" -msgstr "Pon un comentario." - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:85 -msgid "at" -msgstr "en" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 -msgid "Post comment!" -msgstr "¡Pon un comentario!" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:124 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:69 msgid "Edit" msgstr "Editar" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:130 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:73 msgid "Delete" msgstr "Borrar" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:79 +#, python-format +msgid "%(comment_count)s comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:81 +#, python-format +msgid "%(comment_count)s comments" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:83 +msgid "No comments yet." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:91 +msgid "Add one" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:100 +msgid "" +"Type your comment here. You can use Markdown for" +" formatting." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 +msgid "Add this comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:126 +msgid "at" +msgstr "en" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:141 +#, python-format +msgid "

❖ Browsing media by %(username)s

" +msgstr "" + #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -530,31 +588,32 @@ msgid "Here's a spot to tell others about yourself." msgstr "Aquí hay un lugar para que le cuentes a los demás sobre tí." #: mediagoblin/templates/mediagoblin/user_pages/user.html:101 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:119 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:118 msgid "Edit profile" msgstr "Editar perfil" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:107 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:106 msgid "This user hasn't filled in their profile (yet)." msgstr "Este usuario (todavia) no ha completado su perfil." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:133 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:125 +msgid "Change account settings" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:138 #, python-format msgid "View all of %(username)s's media" msgstr "Ver todo el contenido de %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:146 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:151 msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." msgstr "" "Aquí es donde tú contenido estará, pero parece que aún no has agregado nada." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:152 -msgid "Add media" -msgstr "Añadir contenido" - -#: mediagoblin/templates/mediagoblin/user_pages/user.html:158 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:163 +#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72 msgid "There doesn't seem to be any media here yet..." msgstr "Parece que aún no hay ningún contenido aquí..." @@ -566,29 +625,35 @@ msgstr "ícono feed" msgid "Atom feed" msgstr "Atom feed" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:40 -msgid "Newer" -msgstr "Recientes" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:39 +msgid "← Newer" +msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:46 -msgid "Older" -msgstr "Antiguas" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:45 +msgid "Older →" +msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:50 +#: mediagoblin/templates/mediagoblin/utils/pagination.html:48 msgid "Go to page:" msgstr "Ir a la página:" +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:27 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:32 +msgid "newer" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:38 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:43 +msgid "older" +msgstr "" + #: mediagoblin/templates/mediagoblin/utils/tags.html:20 -msgid "Tagged with" -msgstr "Etiquetado con" +msgid "View more media tagged with" +msgstr "" #: mediagoblin/templates/mediagoblin/utils/tags.html:25 -msgid "and" -msgstr "y" - -#: mediagoblin/user_pages/forms.py:24 -msgid "Comment" -msgstr "Comentario" +msgid "or" +msgstr "" #: mediagoblin/user_pages/forms.py:30 msgid "I am sure I want to delete this" diff --git a/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.mo index ed1ea35dfd4e7f0fec92acba788e6751ac127783..b805cca5c47437a8b9e7ecc3e200ccb5b3c3c0cc 100644 GIT binary patch delta 1385 zcmZY7U1$_n6u|M5Zqi+CEGDK+qD^v56F1c~iLRR%(MIbBn3mQL6e|c$cPHz#li784 zHwHzPKD45-t#mDvqTmooe)jgB2J7+eBW+R@8BCqs|{j9@))n5gx*q@jNcXa$A8(1k-dx@E_C!|DjH(F_lE!*iU;1 z&)^t7#wN1#U_*Ol{5t%W_D8rMYp6=|AHwB$5?A09>PBW4Iz(y-I*?nCrKlf*?=0Q8)4s*`(BxTo>%aEjWl9Z~|kjFH;14bkuZ- zti*oQpJ^ZJP7lubCF;*}4y*Ay+=ky{H%8tNc^~6AgrDMSyo#DPMD+}nw{S0}@G$Gk z9|Tk)JC{_B>KJ}a`zzdvU1YDrgJ|$`^Ca~y7&R@UvN9l z=ZDdg%HVtN5_~~m@DA!p{EvFHy}crz;Z_{RTlfNYFi4H!99)dGxT0JN->-`-8#GG? zR>lU4rIvi66w+Mjpq7L^=8XA#Ve6$$hda7zU8N? z@P?5QD`ES^>DGPW;7HQR5f8WhS+~}8ZQlf^jcb{Vm9kBF!2Da?p3h{v%~(3;+lHj0 zwwJRU;-G{%Gv*}i;yaz|yO^5yo*f~Z(^*op?6bY5e4%qw6|*yzZy(@e*5s^ImIZy2 zq%r3BsXUcdN6&>C*4ZXYd1gdc%BAzZN2!x@V?(Uurc+MBv0aml?hQ&G+J4H`+DKwX zgHqD5j6I(7t+bzXJT3U?$5c@A9Lp^)T5>DYzT>$)S-PvBWHM9^3yZ(^G!>Wk{@faz Y7AKMRY|TF6=Eo%&lxTbQxRdte3G^-jDF6Tf delta 1130 zcmXZaOGs2v7{KvQXY!GwjHdaVnXCD1QYRHl(Q={oum>4Qfr`!}3xqKnky<#p$c+TX z%@$J7!%8C~yg`eCXdx|nNDCDt2+1~47J*O%+5a#XF8BA{bI(2BcfNDyy2iSmtXjg4 zqC{3RM7D~^)vSn9xW@BKtiZ?FB3p0;>u?=Aup&pK8OJalm(YSMSdCvW7IPdT!$OFb}QRjOzOq&sVgkP8nVbh9Im6P_#dhdVzfxbrKomPgSW8{|6&TOlwnd{WPUwP@a)Gy z+(5PdAk|gjb=-|_P;JB-&KI!}IFVBjH>wwns0!#rF1gIjjt@~C#dA!>c~ph3qDu7L z9JdujHj;~*7%xGZEaj-?A4Zio+(uAD;6v4#QB1@M?8PZe!!)Ydj&9`mr48Af^rLF! zII0BCP;F$vbPZL)Sdtt=J2s&gE6FcY1Re%HVl5^XM}DULsCL?FdK%Twa}ljLg2!vgX&1;up5_A63 z;v`1n57S?$j%pokXfdW^za__csR;W4Bnr8O;SL(gvN*b6(eYhw(I?IrlVtskrPf>Y68?#$eox%ke# zqkHdonM5X32@s{K8d)WOH06&z{-A18Rj8zDg;3k{kE#l3rAm1~aTB7d@BV}GN2gehmUlngbI|ET)I1mA$KjUu8nY9A4yyl`q1O9LsC~R% zw*PzC{$2RvwBPVU{@hdWcAob_iRfWS7xO68y1nxKQ;@&rxA-Nwy#Te3uRxvqS`Mr6 zH^D9N{g5r155rlw6P|}>;Md{n@J{&R`;7T1_-#0Z*Rbg(`~;kWe+Pd=?LTbHG~5Dp z&U>NGc|X+qWhlM0q2@aeb^hldf6edlOXvENvi%jP{uj&k??TCc6O+CNz88KF-U2ZJ zGhgyP*yVXY)H#0#N}hiTwce{x^7$92eY}UwY2B@mCCpB!{s+tUk3r4z7?k{;gs0(C zQ2Kry%08~cI3>ruQ1%+Z9q`kz0lx$_{x&8%3~z_hUkFdY^HAfz0`Gy}gEhDVAz1h* zT!Fs;pM+n7vis9aB6&OmbNEY8dc1~1NG_j*9MyaVTKEO{6YwP{yZA=={#y{0n>XPB zxCtR?ABW){_yqhE{9`D)Sm2OH;A8Ltd;vZI4>37gGk*^2@HNPk=2o0s-~{A|rU7-nr=a%pZ2A6qDEoN{ z%0K@G>ilm)`R8VYr*qv3)&3!<{=3TdpM{eDN1^Pe0WlHNg*U*bq0aNmunWHcbb zdiyh|IPp4c!1vwh$7k>`&#O@Sdl{a9UxOOIm0$P3Wmtosg%22FiA14-|K(OiJi+sp6~__uHq+;f-L?*hD@ z=c7=1UMl$zRKK5xH^MW}Y~9{Wd%Z9z&NS0OQq1JGe7^jfoL7T9%#xrN&g9#2+Y4J! zu)eXMrR^vV&ECK^;~>xXO*aNbktSz?W)XpI)al0j6w|hwh3$RQTeoLnC(4U3J2S}Q znS6TTKo$l?XoJKCO}9H66t?I_xy_>@+&dR6RBZVt&Bp(EnFUA7bc>>2pPO5a&PFx2 z@lM)^qokH*ow=hy^K6uKj;5NghE-u}WH&wbwR&(hVL^}GOWV`#5(qP=td1@k~DlRPX6CP65{xv*s( zXt|$KDLk?1P_15aBkiie9mOk;$51`(*6l51K9kqX1930S3)^D&l>IrKdZdNCh~n5L zVc5!Tk=h0-LZ{~#*J4;=!(I@@wj1QU3MHtdu&YtgwNa86*}&;P*J9mtRTDJ3LDC8R zcKVpgYMM<>ly}oX+_FKIMdw21uz_udtG1WQZ1XG5+)8bp`aLB@HuQaqE@qU+gN_Yi zEUY!O;p5m{Zrf?*g(M|1sz`gRgiQBGsW}iN%`i3x{9ebRD24CarOQdBqww$V=nj*l z1*;Yrg2TRtR<5FkFv)Qa+s;^e`V(rEmz|$B2gbt?XUmSnWV5iDVuqZ-2_2a`t&aTD z;w(|()Dv2c=U$e3Vt3`BRx1nh+-Xc3b6R84s2xe8Zs}xO!6sQbN9>rygeb>rF~6IT zAyXj)? z6I0t^SlmDPN=vBCE*3gzkPoNKp;lD5Uv?Cp)Z*3V9N|n66*1=TI=zKD$HTm|z2M9t z_v9tk4BUq09azqxgm~tqo?^pewPE#4#Q{)=izY6tm5QmELy!04Gz-mPMbN{9CbZ&I zH=5vnb0n4P^n*@VH%F1AY|Z9m(uxLq?xqct`yeSDy?3 z>(?Hg_zH{Lt6jZPS!_FrBkkm@w$As{&Lwe&vvxI%39^hw4a!xM`9pbY$}HNTXY&DTEZWt8;7He&a|1WR zl$#9PCWuvi)QAs|KehR7SWT?R>_k2(V()#k?u1PaHIYr?v=b$xyu<@4Q%2(GEkcM3 zDN#`?SKh|LZhO*nPzDE1(o8eLO)+bG!H}S@x3WLCDTc&ps_f~)=s5WIFme)0RvwUW zve?rY9D3LMu2OuKv_JsTU~JVaCbk*mgnDJ4Fvr>Jw4Dp$sO1A?heSY-WLD?2wix!q znmOiM@fk9zH1S5I&51>tB$wuc*a*d{(V^u zAji}kmnsm8lAPO(IYDw7S*d(=Tq*t zQ)@Pw47*YE?ia(FIhjQqIEc+snLEu=x{4{b)>IT_-Q(82RPszOxC8qG$s%TnB4fKL z$8?f`E03lZa8747i0v^f!7TYAugu`15@b0H;&?bRX~gGa>iuTfC#y@+S@x#){YFez zS2kS6#%t!3qQ8$DxjChjI9XiK(ho8fkEo6^Wa#7;P}QiY8!JZ-ZiQr0Wv3_&%&9WX z$&g2NDH5HiMO{VXJbaV@XPt{;wZ1^oP&|8Wd2|XN8qVVQ)Kw(0e9-TwnW|d++!X<` zWn16Q23*I$YW9h2yEbL7tzbCbWk$(**Ofct&Iv`*pxN~cwfPFbNy~Zs$q}S-FcF{? zJkU&XC zl;ph0wL5#oO3=%w?rvX zWh|^SpSDG1?MJEfFC{LGlJ>%YTv?{0ks+76^;MbsnxL*_yF_9a_uQn)f0{WPB#GXv zk2G$XD@P}Cwd!U*5r}zNM4aiU*tGqK7%Y922PQ0Qg*ytN=Tu$M;wwcp zfs9WX*=Jtw&9r6q_{7KMxcXaB2ym~<1zf4@ZBDbujn+%9g)EXzJIcZaHd#x;Vy+C* z`CKo^&bHY6TqDS%CLh+v%LW(Al}7pL1@1GlW*#KoC|sC_^aU{V8*x!*$~+ViD4Ab! zUiYEn1mipC%%vJ85~(>IHl%-ZI!(K2I%Q7{8oj9CqjAcd&Qf$Wj>~c`RX@IT#Wc(6 zD8SvZNvB1e(JfiCB%!8!&jnYVjqco1XMq)Xy{$qM@-Ckyij)+$6fVZ_f+S1 z&(G7bx*VR1w4b-=cVB(it~=-XQ#lsoMRg?$k~|KIG^^VtaiBr$+FSm|M_SmyuohNR7J`zX%?NU6*g1CB^K%LiZ(sz&fzMXprB6_oLdt#^d z*&Q>LUeYM>c^Uhr(qj&6DA%9JVF*xqVJ@QPh zAU{fdX5$_?`2oF0j)QFDD*5eRB~$ouGej^W9hUz#^n-qn{D8Z8=cA8QUsWCsHZGGl zE|WJdlc|pXe=n046FwV*j9VD)rKwksy=!lkRXt{09PqCq8yCwP7t4H5PhLlFTrBgQ zy>YR;aj`77xay1LL7ct|ZxQgIafx>r&($zhOQVaaYVe%f=P6`$x8oE9R^I O7m0Ur0!l2b*?(GqZDM z=6v5b{l59z#^|*{$*(DXI{6#U-`7df`{(CSic*i!J&ZZ{5njj7u^dmPD%BrvVkQ28 zv(Urf1nffjzMBtO`WVW*llX{IQFWWfOa}f!)>Jdol*+^fSbW&9$^un5 z7^fgp)FLd!<=BOy_o{Hkqy$ozM*h`)sNLk1f01WM85 z^7^GX7bS;lumWF4iO4CG1<#^vcm*XDKccL62dCp*9D+{~wpq9oW!(cf5ie#Fe;17b zl(@#p*nmrM9Uj4Q97h-=QeF(Bg|&DUC1QERm%Y>&)Hn&HW}b_WH=#tZ4eN0O$^lMA zY1Gh=W6prd$dKBA)wmlaRF_bS>1UKw4P$T_PC^gvM7ds{VIrPIE|fZta*!){IDzYp zyp!5aSXoL%_tUse<2cHj?jII=um>yYe}NLZT>d#sKrhO|Z=h`WF3P<9@$qXY*ZDh? z$apxdq^JfZg>!HKARd;Ae5y>T$iJ2%lEeGT3u5HN)aZGjLlC)8P7)&ynu4zZ%`JziE^KBq2zGNm{?IR#!~uwa3Y>Yxz7E@#;)Obl-;22YBypv zzJ(I0%P6&UvxbJ`Dv#bWtUab}?v|(#AU|4?LZbe$Pp%*Wlqnm>v?QJ#e7RzplJ+#sYhuec8pG(yT0|A~xyV(i_ z^u2EwX!HBD9ULCf&6e$B;Z7QUQ=1(T(+*pl%Ceo5^ex>Vr)MXm+h%*;v)%JXRVAgZ zGW?dW_YtQe%NaO7zNMOLwwod6YF4ph6uN5qhVM1PI?xu5=ztONwz|~(AZl}z0Wt!_2Ky2&){SW--%OE-i%Wdnb(g`l!# zyGt3iPZ<%_Y;r!!8?=>t8ElI<{qkO(P*GOlDRYn474B-!_%e5;+nqLlUfDu(l_iNO zn?|uzYmd94Z(e1!XPk39?>FbY)NJSOh_(N=^87~V;TK=<{?(_Y{2o|+86yWjp!(L1 kee?d+S5pzM$^Svk`4ay_z4f?eIMwAp^wry(hgfgwZ&hnu&;S4c diff --git a/mediagoblin/i18n/ia/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/ia/LC_MESSAGES/mediagoblin.po index 512635e3..56f74573 100644 --- a/mediagoblin/i18n/ia/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/ia/LC_MESSAGES/mediagoblin.po @@ -1,5 +1,5 @@ # Translations template for PROJECT. -# Copyright (C) 2011 ORGANIZATION +# Copyright (C) 2012 ORGANIZATION # This file is distributed under the same license as the PROJECT project. # # Translators: @@ -8,8 +8,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-12-04 10:24-0600\n" -"PO-Revision-Date: 2011-12-04 16:23+0000\n" +"POT-Creation-Date: 2012-01-07 13:47-0600\n" +"PO-Revision-Date: 2012-01-07 19:44+0000\n" "Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -23,27 +23,15 @@ msgstr "" msgid "Invalid file given for media type." msgstr "" -#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 +#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41 msgid "Username" msgstr "Nomine de usator" -#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:53 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 msgid "Password" msgstr "Contrasigno" -#: mediagoblin/auth/forms.py:35 -msgid "Passwords must match." -msgstr "" - -#: mediagoblin/auth/forms.py:37 -msgid "Confirm password" -msgstr "" - -#: mediagoblin/auth/forms.py:39 -msgid "Type it again here to make sure there are no spelling mistakes." -msgstr "" - -#: mediagoblin/auth/forms.py:42 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "Adresse de e-posta" @@ -59,73 +47,109 @@ msgstr "" msgid "Sorry, a user with that email address already exists." msgstr "" -#: mediagoblin/auth/views.py:179 +#: mediagoblin/auth/views.py:180 msgid "" "Your email address has been verified. You may now login, edit your profile, " "and submit images!" msgstr "" -#: mediagoblin/auth/views.py:185 +#: mediagoblin/auth/views.py:186 msgid "The verification key or user id is incorrect" msgstr "" -#: mediagoblin/auth/views.py:203 +#: mediagoblin/auth/views.py:204 msgid "You must be logged in so we know who to send the email to!" msgstr "" -#: mediagoblin/auth/views.py:211 +#: mediagoblin/auth/views.py:212 msgid "You've already verified your email address!" msgstr "" -#: mediagoblin/auth/views.py:224 +#: mediagoblin/auth/views.py:225 msgid "Resent your verification email." msgstr "" -#: mediagoblin/auth/views.py:265 +#: mediagoblin/auth/views.py:260 +msgid "" +"An email has been sent with instructions on how to change your password." +msgstr "" + +#: mediagoblin/auth/views.py:270 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." msgstr "" +#: mediagoblin/auth/views.py:282 +msgid "Couldn't find someone with that username or email." +msgstr "" + +#: mediagoblin/auth/views.py:330 +msgid "You can now log in using your new password." +msgstr "" + #: mediagoblin/edit/forms.py:24 mediagoblin/submit/forms.py:27 msgid "Title" msgstr "Titulo" -#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:27 mediagoblin/submit/forms.py:30 +msgid "Description of this work" +msgstr "" + +#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:31 +msgid "" +"You can use\n" +" \n" +" Markdown for formatting." +msgstr "" + +#: mediagoblin/edit/forms.py:32 mediagoblin/submit/forms.py:35 msgid "Tags" msgstr "" -#: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 -msgid "Seperate tags by commas." +#: mediagoblin/edit/forms.py:34 mediagoblin/submit/forms.py:37 +msgid "Separate tags by commas." msgstr "" -#: mediagoblin/edit/forms.py:33 +#: mediagoblin/edit/forms.py:37 msgid "Slug" msgstr "" -#: mediagoblin/edit/forms.py:34 +#: mediagoblin/edit/forms.py:38 msgid "The slug can't be empty" msgstr "" -#: mediagoblin/edit/forms.py:35 +#: mediagoblin/edit/forms.py:39 msgid "" -"The title part of this media's URL. You usually don't need to change this." +"The title part of this media's address. You usually don't need to change " +"this." msgstr "" -#: mediagoblin/edit/forms.py:42 +#: mediagoblin/edit/forms.py:46 msgid "Bio" msgstr "" -#: mediagoblin/edit/forms.py:45 +#: mediagoblin/edit/forms.py:48 +msgid "" +"You can use\n" +" \n" +" Markdown for formatting." +msgstr "" + +#: mediagoblin/edit/forms.py:53 msgid "Website" msgstr "Sito web" -#: mediagoblin/edit/forms.py:49 +#: mediagoblin/edit/forms.py:60 msgid "Old password" msgstr "" -#: mediagoblin/edit/forms.py:52 -msgid "New Password" +#: mediagoblin/edit/forms.py:62 +msgid "Enter your old password to prove you own this account." +msgstr "" + +#: mediagoblin/edit/forms.py:65 +msgid "New password" msgstr "" #: mediagoblin/edit/views.py:65 @@ -140,39 +164,43 @@ msgstr "" msgid "You are editing a user's profile. Proceed with caution." msgstr "" -#: mediagoblin/edit/views.py:171 +#: mediagoblin/edit/views.py:174 +msgid "Profile changes saved" +msgstr "" + +#: mediagoblin/edit/views.py:200 msgid "Wrong password" msgstr "" -#: mediagoblin/edit/views.py:192 -msgid "Profile edited!" +#: mediagoblin/edit/views.py:216 +msgid "Account settings saved" msgstr "" -#: mediagoblin/media_types/__init__.py:65 -msgid "Could not find any file extension in \"{filename}\"" +#: mediagoblin/media_types/__init__.py:77 +msgid "Could not extract any file extension from \"{filename}\"" +msgstr "" + +#: mediagoblin/media_types/__init__.py:88 +msgid "Sorry, I don't support that file type :(" msgstr "" #: mediagoblin/submit/forms.py:25 msgid "File" msgstr "" -#: mediagoblin/submit/forms.py:30 -msgid "Description of this work" -msgstr "" - -#: mediagoblin/submit/views.py:49 +#: mediagoblin/submit/views.py:50 msgid "You must provide a file." msgstr "" -#: mediagoblin/submit/views.py:127 +#: mediagoblin/submit/views.py:128 msgid "Woohoo! Submitted!" msgstr "" -#: mediagoblin/submit/views.py:133 -msgid "Invalid file type." +#: mediagoblin/templates/mediagoblin/404.html:22 +msgid "Image of 404 goblin stressing out" msgstr "" -#: mediagoblin/templates/mediagoblin/404.html:21 +#: mediagoblin/templates/mediagoblin/404.html:23 msgid "Oops!" msgstr "" @@ -186,33 +214,30 @@ msgid "" " been moved or deleted." msgstr "" -#: mediagoblin/templates/mediagoblin/404.html:32 -msgid "Image of 404 goblin stressing out" -msgstr "" - -#: mediagoblin/templates/mediagoblin/base.html:49 +#: mediagoblin/templates/mediagoblin/base.html:48 msgid "MediaGoblin logo" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:54 -msgid "Submit media" +#: mediagoblin/templates/mediagoblin/base.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:157 +msgid "Add media" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:64 msgid "Verify your email!" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:72 +#: mediagoblin/templates/mediagoblin/base.html:71 msgid "log out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:75 +#: mediagoblin/templates/mediagoblin/base.html:74 #: mediagoblin/templates/mediagoblin/auth/login.html:27 #: mediagoblin/templates/mediagoblin/auth/login.html:45 msgid "Log in" msgstr "Initiar session" -#: mediagoblin/templates/mediagoblin/base.html:91 +#: mediagoblin/templates/mediagoblin/base.html:86 msgid "" "Powered by MediaGoblin, a GNU project" @@ -222,7 +247,7 @@ msgstr "" msgid "Explore" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:27 +#: mediagoblin/templates/mediagoblin/root.html:26 msgid "Hi there, welcome to this MediaGoblin site!" msgstr "" @@ -246,21 +271,20 @@ msgstr "" #, python-format msgid "" "Create an account at this site\n" -" or\n" -" Set up MediaGoblin on your own server" +" or\n" +" Set up MediaGoblin on your own server" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:44 +#: mediagoblin/templates/mediagoblin/root.html:40 msgid "Most recent media" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/change_fp.html:29 -msgid "Enter your new password" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:32 +msgid "Set your new password" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/change_fp.html:33 -#: mediagoblin/templates/mediagoblin/submit/start.html:30 -msgid "Submit" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:35 +msgid "Set password" msgstr "" #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 @@ -271,15 +295,6 @@ msgstr "" msgid "Send instructions" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 -msgid "Your password has been changed. Try to log in now." -msgstr "" - -#: mediagoblin/templates/mediagoblin/auth/fp_email_sent.html:22 -msgid "" -"Check your inbox. We sent an email with a URL for changing your password." -msgstr "" - #: mediagoblin/templates/mediagoblin/auth/fp_verification_email.txt:19 #, python-format msgid "" @@ -310,11 +325,11 @@ msgstr "" msgid "Forgot your password?" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/register.html:27 +#: mediagoblin/templates/mediagoblin/auth/register.html:32 msgid "Create an account!" msgstr "Crear un conto!" -#: mediagoblin/templates/mediagoblin/auth/register.html:31 +#: mediagoblin/templates/mediagoblin/auth/register.html:36 msgid "Create" msgstr "" @@ -340,10 +355,16 @@ msgid "Cancel" msgstr "Cancellar" #: mediagoblin/templates/mediagoblin/edit/edit.html:37 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:40 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:35 msgid "Save changes" msgstr "" +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:34 +#, python-format +msgid "Changing %(username)s's account settings" +msgstr "" + #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29 #, python-format msgid "Editing %(username)s's profile" @@ -355,12 +376,31 @@ msgstr "" msgid "Media tagged with: %(tag_name)s" msgstr "" -#: mediagoblin/templates/mediagoblin/media_displays/video.html:19 +#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 +#: mediagoblin/templates/mediagoblin/media_displays/video.html:46 msgid "Original" msgstr "" +#: mediagoblin/templates/mediagoblin/media_displays/video.html:33 +msgid "" +"Sorry, this video will not work because \n" +"\t your web browser does not support HTML5 \n" +"\t video." +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:36 +msgid "" +"You can get a modern web browser that \n" +"\t can play this video at \n" +"\t http://getfirefox.com!" +msgstr "" + #: mediagoblin/templates/mediagoblin/submit/start.html:26 -msgid "Submit yer media" +msgid "Add your media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Add" msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 @@ -373,31 +413,57 @@ msgstr "" msgid "%(username)s's media" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:57 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:60 #, python-format -msgid "By %(username)s on %(date)s" +msgid "Added on %(date)s." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:67 -msgid "Post a comment" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:85 -msgid "at" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 -msgid "Post comment!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:124 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:69 msgid "Edit" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:130 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:73 msgid "Delete" msgstr "" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:79 +#, python-format +msgid "%(comment_count)s comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:81 +#, python-format +msgid "%(comment_count)s comments" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:83 +msgid "No comments yet." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:91 +msgid "Add one" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:100 +msgid "" +"Type your comment here. You can use Markdown for" +" formatting." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 +msgid "Add this comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:126 +msgid "at" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:141 +#, python-format +msgid "

❖ Browsing media by %(username)s

" +msgstr "" + #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -478,30 +544,31 @@ msgid "Here's a spot to tell others about yourself." msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/user.html:101 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:119 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:118 msgid "Edit profile" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:107 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:106 msgid "This user hasn't filled in their profile (yet)." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:133 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:125 +msgid "Change account settings" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:138 #, python-format msgid "View all of %(username)s's media" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:146 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:151 msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:152 -msgid "Add media" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/user.html:158 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:163 +#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72 msgid "There doesn't seem to be any media here yet..." msgstr "" @@ -513,30 +580,36 @@ msgstr "" msgid "Atom feed" msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:40 -msgid "Newer" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:39 +msgid "← Newer" msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:46 -msgid "Older" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:45 +msgid "Older →" msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:50 +#: mediagoblin/templates/mediagoblin/utils/pagination.html:48 msgid "Go to page:" msgstr "" +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:27 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:32 +msgid "newer" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:38 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:43 +msgid "older" +msgstr "" + #: mediagoblin/templates/mediagoblin/utils/tags.html:20 -msgid "Tagged with" +msgid "View more media tagged with" msgstr "" #: mediagoblin/templates/mediagoblin/utils/tags.html:25 -msgid "and" +msgid "or" msgstr "" -#: mediagoblin/user_pages/forms.py:24 -msgid "Comment" -msgstr "Commento" - #: mediagoblin/user_pages/forms.py:30 msgid "I am sure I want to delete this" msgstr "" diff --git a/mediagoblin/i18n/it/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/it/LC_MESSAGES/mediagoblin.mo index 1319a6058478deda7a3c86b62aaeb505fd741f87..d5fb3eacad7f7934101a5761139174c17951e2b3 100644 GIT binary patch literal 13574 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 diff --git a/mediagoblin/i18n/it/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/it/LC_MESSAGES/mediagoblin.po index 96d1f0a2..6a8b8b65 100644 --- a/mediagoblin/i18n/it/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/it/LC_MESSAGES/mediagoblin.po @@ -1,15 +1,16 @@ # Translations template for PROJECT. -# Copyright (C) 2011 ORGANIZATION +# Copyright (C) 2012 ORGANIZATION # This file is distributed under the same license as the PROJECT project. # # Translators: +# , 2011. # , 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-12-04 10:24-0600\n" -"PO-Revision-Date: 2011-12-04 16:23+0000\n" +"POT-Creation-Date: 2012-01-07 13:47-0600\n" +"PO-Revision-Date: 2012-01-07 19:44+0000\n" "Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -23,27 +24,15 @@ msgstr "" msgid "Invalid file given for media type." msgstr "documento non valido come tipo multimediale." -#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 +#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41 msgid "Username" msgstr "Nome utente" -#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:53 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 msgid "Password" msgstr "Password" -#: mediagoblin/auth/forms.py:35 -msgid "Passwords must match." -msgstr "Le password devono coincidere" - -#: mediagoblin/auth/forms.py:37 -msgid "Confirm password" -msgstr "Conferma password" - -#: mediagoblin/auth/forms.py:39 -msgid "Type it again here to make sure there are no spelling mistakes." -msgstr "Scrivilo ancora qui per assicurarti che non ci siano errori" - -#: mediagoblin/auth/forms.py:42 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "Indirizzo email" @@ -57,9 +46,9 @@ msgstr "Spiacente, esiste già un utente con quel nome" #: mediagoblin/auth/views.py:77 msgid "Sorry, a user with that email address already exists." -msgstr "" +msgstr "Siamo spiacenti, un utente con quell'indirizzo email esiste già." -#: mediagoblin/auth/views.py:179 +#: mediagoblin/auth/views.py:180 msgid "" "Your email address has been verified. You may now login, edit your profile, " "and submit images!" @@ -67,67 +56,106 @@ msgstr "" "Il tuo indirizzo email è stato verificato. Puoi ora fare login, modificare " "il tuo profilo, e inserire immagini!" -#: mediagoblin/auth/views.py:185 +#: mediagoblin/auth/views.py:186 msgid "The verification key or user id is incorrect" msgstr "La chiave di verifica o l'id utente è sbagliato" -#: mediagoblin/auth/views.py:203 +#: mediagoblin/auth/views.py:204 msgid "You must be logged in so we know who to send the email to!" msgstr "" +"Devi entrare col tuo profilo così possiamo sapere a chi inviare l'email!" -#: mediagoblin/auth/views.py:211 +#: mediagoblin/auth/views.py:212 msgid "You've already verified your email address!" -msgstr "" +msgstr "Hai già verificato il tuo indirizzo email!" -#: mediagoblin/auth/views.py:224 +#: mediagoblin/auth/views.py:225 msgid "Resent your verification email." msgstr "Rispedisci email di verifica" -#: mediagoblin/auth/views.py:265 +#: mediagoblin/auth/views.py:260 +msgid "" +"An email has been sent with instructions on how to change your password." +msgstr "" + +#: mediagoblin/auth/views.py:270 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." msgstr "" +"Impossibile inviare l'email di recupero password perchè il tuo nome utente è" +" inattivo o il tuo account email non è stato verificato." + +#: mediagoblin/auth/views.py:282 +msgid "Couldn't find someone with that username or email." +msgstr "" + +#: mediagoblin/auth/views.py:330 +msgid "You can now log in using your new password." +msgstr "" #: mediagoblin/edit/forms.py:24 mediagoblin/submit/forms.py:27 msgid "Title" msgstr "Titolo" -#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:27 mediagoblin/submit/forms.py:30 +msgid "Description of this work" +msgstr "Descrizione di questo lavoro" + +#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:31 +msgid "" +"You can use\n" +" \n" +" Markdown for formatting." +msgstr "" + +#: mediagoblin/edit/forms.py:32 mediagoblin/submit/forms.py:35 msgid "Tags" msgstr "Tags" -#: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 -msgid "Seperate tags by commas." +#: mediagoblin/edit/forms.py:34 mediagoblin/submit/forms.py:37 +msgid "Separate tags by commas." msgstr "" -#: mediagoblin/edit/forms.py:33 +#: mediagoblin/edit/forms.py:37 msgid "Slug" msgstr "" -#: mediagoblin/edit/forms.py:34 +#: mediagoblin/edit/forms.py:38 msgid "The slug can't be empty" msgstr "" -#: mediagoblin/edit/forms.py:35 +#: mediagoblin/edit/forms.py:39 msgid "" -"The title part of this media's URL. You usually don't need to change this." +"The title part of this media's address. You usually don't need to change " +"this." msgstr "" -#: mediagoblin/edit/forms.py:42 +#: mediagoblin/edit/forms.py:46 msgid "Bio" msgstr "Bio" -#: mediagoblin/edit/forms.py:45 +#: mediagoblin/edit/forms.py:48 +msgid "" +"You can use\n" +" \n" +" Markdown for formatting." +msgstr "" + +#: mediagoblin/edit/forms.py:53 msgid "Website" msgstr "Sito web" -#: mediagoblin/edit/forms.py:49 +#: mediagoblin/edit/forms.py:60 msgid "Old password" +msgstr "Password vecchia" + +#: mediagoblin/edit/forms.py:62 +msgid "Enter your old password to prove you own this account." msgstr "" -#: mediagoblin/edit/forms.py:52 -msgid "New Password" +#: mediagoblin/edit/forms.py:65 +msgid "New password" msgstr "" #: mediagoblin/edit/views.py:65 @@ -144,39 +172,43 @@ msgstr "" msgid "You are editing a user's profile. Proceed with caution." msgstr "Stai modificando il profilo di un utente. Procedi con attenzione." -#: mediagoblin/edit/views.py:171 +#: mediagoblin/edit/views.py:174 +msgid "Profile changes saved" +msgstr "" + +#: mediagoblin/edit/views.py:200 msgid "Wrong password" +msgstr "Password errata" + +#: mediagoblin/edit/views.py:216 +msgid "Account settings saved" msgstr "" -#: mediagoblin/edit/views.py:192 -msgid "Profile edited!" +#: mediagoblin/media_types/__init__.py:77 +msgid "Could not extract any file extension from \"{filename}\"" msgstr "" -#: mediagoblin/media_types/__init__.py:65 -msgid "Could not find any file extension in \"{filename}\"" +#: mediagoblin/media_types/__init__.py:88 +msgid "Sorry, I don't support that file type :(" msgstr "" #: mediagoblin/submit/forms.py:25 msgid "File" msgstr "Documento" -#: mediagoblin/submit/forms.py:30 -msgid "Description of this work" -msgstr "Descrizione di questo lavoro" - -#: mediagoblin/submit/views.py:49 +#: mediagoblin/submit/views.py:50 msgid "You must provide a file." msgstr "Devi specificare un documento." -#: mediagoblin/submit/views.py:127 +#: mediagoblin/submit/views.py:128 msgid "Woohoo! Submitted!" msgstr "Evviva! " -#: mediagoblin/submit/views.py:133 -msgid "Invalid file type." -msgstr "" +#: mediagoblin/templates/mediagoblin/404.html:22 +msgid "Image of 404 goblin stressing out" +msgstr "Immagine di 404 folletti che stressano" -#: mediagoblin/templates/mediagoblin/404.html:21 +#: mediagoblin/templates/mediagoblin/404.html:23 msgid "Oops!" msgstr "Oops!" @@ -192,33 +224,30 @@ msgstr "" "Se sei sicuro che l'indirizzo è corretto, forse la pagina che stai cercando " "è stata spostata o cancellata." -#: mediagoblin/templates/mediagoblin/404.html:32 -msgid "Image of 404 goblin stressing out" -msgstr "Immagine di 404 folletti che stressano" - -#: mediagoblin/templates/mediagoblin/base.html:49 +#: mediagoblin/templates/mediagoblin/base.html:48 msgid "MediaGoblin logo" msgstr "MediaGoblin logo" -#: mediagoblin/templates/mediagoblin/base.html:54 -msgid "Submit media" -msgstr "Inoltra file multimediale" +#: mediagoblin/templates/mediagoblin/base.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:157 +msgid "Add media" +msgstr "Aggiungi documenti multimediali" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:64 msgid "Verify your email!" -msgstr "" +msgstr "Verifica la tua email!" -#: mediagoblin/templates/mediagoblin/base.html:72 +#: mediagoblin/templates/mediagoblin/base.html:71 msgid "log out" -msgstr "" +msgstr "disconnettiti" -#: mediagoblin/templates/mediagoblin/base.html:75 +#: mediagoblin/templates/mediagoblin/base.html:74 #: mediagoblin/templates/mediagoblin/auth/login.html:27 #: mediagoblin/templates/mediagoblin/auth/login.html:45 msgid "Log in" msgstr "Accedi" -#: mediagoblin/templates/mediagoblin/base.html:91 +#: mediagoblin/templates/mediagoblin/base.html:86 msgid "" "Powered by MediaGoblin, a GNU project" @@ -230,63 +259,58 @@ msgstr "" msgid "Explore" msgstr "Esplora" -#: mediagoblin/templates/mediagoblin/root.html:27 +#: mediagoblin/templates/mediagoblin/root.html:26 msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "" +msgstr "Ciao, benvenuto a questo sito MediaGoblin!" #: mediagoblin/templates/mediagoblin/root.html:28 msgid "" "This site is running MediaGoblin, an " "extraordinarily great piece of media hosting software." msgstr "" +"questo sito sta utilizzando Mediagoblin, un ottimo programma di " +"media hosting." #: mediagoblin/templates/mediagoblin/root.html:29 msgid "" "To add your own media, place comments, save your favourites and more, you " "can log in with your MediaGoblin account." msgstr "" +"Per aggiungere i tuoi file, scrivere commenti, salvare i tuoi preferiti e " +"altro, devi entrare col tuo profilo MediaGoblin." #: mediagoblin/templates/mediagoblin/root.html:31 msgid "Don't have one yet? It's easy!" -msgstr "" +msgstr "Non ne hai già uno? E' semplice!" #: mediagoblin/templates/mediagoblin/root.html:32 #, python-format msgid "" "Create an account at this site\n" -" or\n" -" Set up MediaGoblin on your own server" +" or\n" +" Set up MediaGoblin on your own server" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:44 +#: mediagoblin/templates/mediagoblin/root.html:40 msgid "Most recent media" msgstr "Documenti multimediali più recenti" -#: mediagoblin/templates/mediagoblin/auth/change_fp.html:29 -msgid "Enter your new password" -msgstr "Inserisci la tua nuova password" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:32 +msgid "Set your new password" +msgstr "" -#: mediagoblin/templates/mediagoblin/auth/change_fp.html:33 -#: mediagoblin/templates/mediagoblin/submit/start.html:30 -msgid "Submit" -msgstr "Conferma" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:35 +msgid "Set password" +msgstr "" #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" -msgstr "" +msgstr "Recupera Password" #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:30 msgid "Send instructions" -msgstr "" - -#: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 -msgid "Your password has been changed. Try to log in now." -msgstr "" - -#: mediagoblin/templates/mediagoblin/auth/fp_email_sent.html:22 -msgid "" -"Check your inbox. We sent an email with a URL for changing your password." -msgstr "" +msgstr "Invia istruzioni" #: mediagoblin/templates/mediagoblin/auth/fp_verification_email.txt:19 #, python-format @@ -301,6 +325,14 @@ msgid "" "If you think this is an error, just ignore this email and continue being\n" "a happy goblin!" msgstr "" +"Ciao %(username)s,\n" +"per cambiare la tua password MediaGoblin apri il seguente URL\n" +"nel tuo web browser:\n" +"\n" +"%(verification_url)s\n" +"\n" +"Se pensi che sia un errore, ignora semplicemente questa email e continua ad essere \n" +"un goblin felice!" #: mediagoblin/templates/mediagoblin/auth/login.html:30 msgid "Logging in failed!" @@ -318,11 +350,11 @@ msgstr "Creane uno qui!" msgid "Forgot your password?" msgstr "Hai dimenticato la password?" -#: mediagoblin/templates/mediagoblin/auth/register.html:27 +#: mediagoblin/templates/mediagoblin/auth/register.html:32 msgid "Create an account!" msgstr "Crea un account!" -#: mediagoblin/templates/mediagoblin/auth/register.html:31 +#: mediagoblin/templates/mediagoblin/auth/register.html:36 msgid "Create" msgstr "Crea" @@ -353,10 +385,16 @@ msgid "Cancel" msgstr "Annulla" #: mediagoblin/templates/mediagoblin/edit/edit.html:37 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:40 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:35 msgid "Save changes" msgstr "Salva i cambiamenti" +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:34 +#, python-format +msgid "Changing %(username)s's account settings" +msgstr "" + #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29 #, python-format msgid "Editing %(username)s's profile" @@ -366,49 +404,94 @@ msgstr "Stai modificando il profilo di %(username)s" #: mediagoblin/templates/mediagoblin/listings/tag.html:35 #, python-format msgid "Media tagged with: %(tag_name)s" +msgstr "file taggato con:%(tag_name)s" + +#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 +#: mediagoblin/templates/mediagoblin/media_displays/video.html:46 +msgid "Original" +msgstr "Originale" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:33 +msgid "" +"Sorry, this video will not work because \n" +"\t your web browser does not support HTML5 \n" +"\t video." msgstr "" -#: mediagoblin/templates/mediagoblin/media_displays/video.html:19 -msgid "Original" +#: mediagoblin/templates/mediagoblin/media_displays/video.html:36 +msgid "" +"You can get a modern web browser that \n" +"\t can play this video at \n" +"\t http://getfirefox.com!" msgstr "" #: mediagoblin/templates/mediagoblin/submit/start.html:26 -msgid "Submit yer media" -msgstr "Inoltra documento multimediale" +msgid "Add your media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Add" +msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format msgid "%(username)s's media" -msgstr "" +msgstr "file di %(username)s" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:37 #, python-format msgid "%(username)s's media" msgstr "Documenti multimediali di %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:57 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:60 #, python-format -msgid "By %(username)s on %(date)s" +msgid "Added on %(date)s." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:67 -msgid "Post a comment" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:85 -msgid "at" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 -msgid "Post comment!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:124 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:69 msgid "Edit" +msgstr "Modifica" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:73 +msgid "Delete" +msgstr "Elimina" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:79 +#, python-format +msgid "%(comment_count)s comment" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:130 -msgid "Delete" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:81 +#, python-format +msgid "%(comment_count)s comments" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:83 +msgid "No comments yet." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:91 +msgid "Add one" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:100 +msgid "" +"Type your comment here. You can use Markdown for" +" formatting." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 +msgid "Add this comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:126 +msgid "at" +msgstr "a" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:141 +#, python-format +msgid "

❖ Browsing media by %(username)s

" msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 @@ -496,20 +579,24 @@ msgid "Here's a spot to tell others about yourself." msgstr "Ecco un posto dove raccontare agli altri di te." #: mediagoblin/templates/mediagoblin/user_pages/user.html:101 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:119 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:118 msgid "Edit profile" msgstr "Modifica profilo" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:107 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:106 msgid "This user hasn't filled in their profile (yet)." msgstr "Questo utente non ha (ancora) compilato il proprio profilo." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:133 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:125 +msgid "Change account settings" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:138 #, python-format msgid "View all of %(username)s's media" msgstr "Visualizza tutti i file multimediali di %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:146 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:151 msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." @@ -517,11 +604,8 @@ msgstr "" "Questo è dove i tuoi documenti multimediali appariranno, ma sembra che tu " "non abbia ancora aggiunto niente." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:152 -msgid "Add media" -msgstr "Aggiungi documenti multimediali" - -#: mediagoblin/templates/mediagoblin/user_pages/user.html:158 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:163 +#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72 msgid "There doesn't seem to be any media here yet..." msgstr "Non sembra ci sia ancora nessun documento multimediali qui.." @@ -533,49 +617,56 @@ msgstr "feed icon" msgid "Atom feed" msgstr "Atom feed" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:40 -msgid "Newer" -msgstr "Più nuovo" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:39 +msgid "← Newer" +msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:46 -msgid "Older" -msgstr "Più vecchio" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:45 +msgid "Older →" +msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:50 +#: mediagoblin/templates/mediagoblin/utils/pagination.html:48 msgid "Go to page:" +msgstr "Vai alla pagina:" + +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:27 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:32 +msgid "newer" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:38 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:43 +msgid "older" msgstr "" #: mediagoblin/templates/mediagoblin/utils/tags.html:20 -msgid "Tagged with" +msgid "View more media tagged with" msgstr "" #: mediagoblin/templates/mediagoblin/utils/tags.html:25 -msgid "and" +msgid "or" msgstr "" -#: mediagoblin/user_pages/forms.py:24 -msgid "Comment" -msgstr "Commento" - #: mediagoblin/user_pages/forms.py:30 msgid "I am sure I want to delete this" msgstr "Sono sicuro di volerlo cancellare" #: mediagoblin/user_pages/views.py:155 msgid "Oops, your comment was empty." -msgstr "" +msgstr "Oops, il tuo commento era vuoto." #: mediagoblin/user_pages/views.py:161 msgid "Your comment has been posted!" -msgstr "" +msgstr "Il tuo commento è stato aggiunto!" #: mediagoblin/user_pages/views.py:183 msgid "You deleted the media." -msgstr "" +msgstr "Hai cancellato il file" #: mediagoblin/user_pages/views.py:190 msgid "The media was not deleted because you didn't check that you were sure." msgstr "" +"Il file non è stato eliminato perchè non hai confermato di essere sicuro." #: mediagoblin/user_pages/views.py:198 msgid "You are about to delete another user's media. Proceed with caution." diff --git a/mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.mo index 39f3595b0100e5d851603afe8bcd22c4bbe6c03a..21aeed269a18be785d89a6011b4755121c70ed0f 100644 GIT binary patch literal 13736 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 delta 3284 zcmcK4du&rx9Ki82rjEyWYy+II!I{dVgO;|8F(znmhyis1Vo)QFyY_Co(B6`^V@!i( z>vW2bDA#8Ui9<7qZ>{l#1~7(@Xf$d>4bDF-I^Rwc-|_MNwO1rWV~o0N{hV`p?m6fF ze!sI_8wM{;y;pkNt%{#c{wnx8TqwOiejY4RYCPSCa3a2dgZK{4!F|J(8i8M7E&hbd zG05ON+=B9bh7Vc#d6aqk@C2n&>U$c?82A-gQ!N{*)Hqy;0c^(0@fPF(HFlIzr8p5~ zo(E;T-W^|z<@8tMB#hz|yatcM`>+@v#1q+HJ>yPz4M+3E5T1m;I<34Vc`AvbtDjOI(3UxqSXjWRwTQ_@&OqY@jC^eMx2J<6LV zki)8LQ6h8)wqZZAmm15i67s3Ykg7w8;4+j0hEO(6Bfsh25) z<-GoEY(&Z76&S$VP$F^wWx-cbHhdQ)6`!N5_X94)U+_dci?A)nwJ7WE!uj}S8S(eg z7)^<5T!^c2EpElfaSqNU3=*jjCeXq&Z~!G@mBg35)O6Ii0HtOwamSlcBG`@%*n@I_ z11TD((U4=F4GWPW)r0kT7fPrOq7>7YD5;vv;AOY~gLntZ^?C`1;j74nQm>;N*5R&qJnLtTUt!X!$Ld)@wxC=2xATznS!RbTKSxgJf0 z$@8VIK9qUOk?g1|QHt>vBzWp!l!NWZV!8jX(2$9TP>Sd)lp^^Vd$C&Q@AKm*DcDw( zuj(gp6a9lI_xU{TE=~0q%7NZMe$|(J$cvSpl8@LllztGU{?u7CB!F zP(rSz+rkj#9wlK z5v$4qO|F|!QgJiN_d9SY-ivaOPf_l3(aikqS%vfI--vRZ_oK#dP&SMkVlg;=9*oY0d7A@?<5RRgN&c+x@s-D7n zdsWlG*3LCkcb3jb z=%^XC47E5M&bORFz1SHy>gs|solCSQrDL|9HZyD_O;18K7vt%hamHZ#svG0wSx zh__28H)PPVV>+?Xj6@{NQ7e&TO2XMveundQ`6tec!6nY5nnq`0#S70_K3t^IXm622}CP%bFF#xxP ze|@mV>#z0uN3J;EyUN^TNuIn*2v5BZ`U6Mi)z$~+I(sUIoWoQ4j;hApBaSY@I;X8_ z-=7s>w)>%M`krh$lkMJ}O+WBIRAV-MbGG}LZ2FOG`nhcS+N`&G`{2%JKf3>hBW3xw zRk`kz)?=#j>r>A=rYh@Z-udTM>2sEP##J4AimvMqKfU#%-Y2qMw`aThvt2#T)|!fn ze^9EkoL@aHe^IVGs@J>aIwjLIYf{0IkGFOm-qWYD-5H5=`s&\n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -23,27 +23,15 @@ msgstr "" msgid "Invalid file given for media type." msgstr "" -#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 +#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41 msgid "Username" msgstr "ユーザネーム" -#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:53 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 msgid "Password" msgstr "パスワード" -#: mediagoblin/auth/forms.py:35 -msgid "Passwords must match." -msgstr "パスワードが一致している必要があります。" - -#: mediagoblin/auth/forms.py:37 -msgid "Confirm password" -msgstr "パスワードを確認" - -#: mediagoblin/auth/forms.py:39 -msgid "Type it again here to make sure there are no spelling mistakes." -msgstr "" - -#: mediagoblin/auth/forms.py:42 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "メールアドレス" @@ -59,73 +47,109 @@ msgstr "申し訳ありませんが、その名前を持つユーザーがすで msgid "Sorry, a user with that email address already exists." msgstr "" -#: mediagoblin/auth/views.py:179 +#: mediagoblin/auth/views.py:180 msgid "" "Your email address has been verified. You may now login, edit your profile, " "and submit images!" msgstr "メアドが確認されています。これで、ログインしてプロファイルを編集し、画像を提出することができます!" -#: mediagoblin/auth/views.py:185 +#: mediagoblin/auth/views.py:186 msgid "The verification key or user id is incorrect" msgstr "検証キーまたはユーザーIDが間違っています" -#: mediagoblin/auth/views.py:203 +#: mediagoblin/auth/views.py:204 msgid "You must be logged in so we know who to send the email to!" msgstr "" -#: mediagoblin/auth/views.py:211 +#: mediagoblin/auth/views.py:212 msgid "You've already verified your email address!" msgstr "" -#: mediagoblin/auth/views.py:224 +#: mediagoblin/auth/views.py:225 msgid "Resent your verification email." msgstr "検証メールを再送しました。" -#: mediagoblin/auth/views.py:265 +#: mediagoblin/auth/views.py:260 +msgid "" +"An email has been sent with instructions on how to change your password." +msgstr "" + +#: mediagoblin/auth/views.py:270 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." msgstr "" +#: mediagoblin/auth/views.py:282 +msgid "Couldn't find someone with that username or email." +msgstr "" + +#: mediagoblin/auth/views.py:330 +msgid "You can now log in using your new password." +msgstr "" + #: mediagoblin/edit/forms.py:24 mediagoblin/submit/forms.py:27 msgid "Title" msgstr "タイトル" -#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:27 mediagoblin/submit/forms.py:30 +msgid "Description of this work" +msgstr "" + +#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:31 +msgid "" +"You can use\n" +" \n" +" Markdown for formatting." +msgstr "" + +#: mediagoblin/edit/forms.py:32 mediagoblin/submit/forms.py:35 msgid "Tags" msgstr "タグ" -#: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 -msgid "Seperate tags by commas." +#: mediagoblin/edit/forms.py:34 mediagoblin/submit/forms.py:37 +msgid "Separate tags by commas." msgstr "" -#: mediagoblin/edit/forms.py:33 +#: mediagoblin/edit/forms.py:37 msgid "Slug" msgstr "スラグ" -#: mediagoblin/edit/forms.py:34 +#: mediagoblin/edit/forms.py:38 msgid "The slug can't be empty" msgstr "スラグは必要です。" -#: mediagoblin/edit/forms.py:35 +#: mediagoblin/edit/forms.py:39 msgid "" -"The title part of this media's URL. You usually don't need to change this." +"The title part of this media's address. You usually don't need to change " +"this." msgstr "" -#: mediagoblin/edit/forms.py:42 +#: mediagoblin/edit/forms.py:46 msgid "Bio" msgstr "自己紹介" -#: mediagoblin/edit/forms.py:45 +#: mediagoblin/edit/forms.py:48 +msgid "" +"You can use\n" +" \n" +" Markdown for formatting." +msgstr "" + +#: mediagoblin/edit/forms.py:53 msgid "Website" msgstr "URL" -#: mediagoblin/edit/forms.py:49 +#: mediagoblin/edit/forms.py:60 msgid "Old password" msgstr "" -#: mediagoblin/edit/forms.py:52 -msgid "New Password" +#: mediagoblin/edit/forms.py:62 +msgid "Enter your old password to prove you own this account." +msgstr "" + +#: mediagoblin/edit/forms.py:65 +msgid "New password" msgstr "" #: mediagoblin/edit/views.py:65 @@ -140,39 +164,43 @@ msgstr "あなたは、他のユーザーのメディアを編集しています msgid "You are editing a user's profile. Proceed with caution." msgstr "あなたは、他のユーザーのプロファイルを編集しています。ご注意ください。" -#: mediagoblin/edit/views.py:171 +#: mediagoblin/edit/views.py:174 +msgid "Profile changes saved" +msgstr "" + +#: mediagoblin/edit/views.py:200 msgid "Wrong password" msgstr "" -#: mediagoblin/edit/views.py:192 -msgid "Profile edited!" +#: mediagoblin/edit/views.py:216 +msgid "Account settings saved" msgstr "" -#: mediagoblin/media_types/__init__.py:65 -msgid "Could not find any file extension in \"{filename}\"" +#: mediagoblin/media_types/__init__.py:77 +msgid "Could not extract any file extension from \"{filename}\"" +msgstr "" + +#: mediagoblin/media_types/__init__.py:88 +msgid "Sorry, I don't support that file type :(" msgstr "" #: mediagoblin/submit/forms.py:25 msgid "File" msgstr "ファイル" -#: mediagoblin/submit/forms.py:30 -msgid "Description of this work" -msgstr "" - -#: mediagoblin/submit/views.py:49 +#: mediagoblin/submit/views.py:50 msgid "You must provide a file." msgstr "ファイルを提供する必要があります。" -#: mediagoblin/submit/views.py:127 +#: mediagoblin/submit/views.py:128 msgid "Woohoo! Submitted!" msgstr "投稿終了!" -#: mediagoblin/submit/views.py:133 -msgid "Invalid file type." +#: mediagoblin/templates/mediagoblin/404.html:22 +msgid "Image of 404 goblin stressing out" msgstr "" -#: mediagoblin/templates/mediagoblin/404.html:21 +#: mediagoblin/templates/mediagoblin/404.html:23 msgid "Oops!" msgstr "" @@ -186,33 +214,30 @@ msgid "" " been moved or deleted." msgstr "" -#: mediagoblin/templates/mediagoblin/404.html:32 -msgid "Image of 404 goblin stressing out" -msgstr "" - -#: mediagoblin/templates/mediagoblin/base.html:49 +#: mediagoblin/templates/mediagoblin/base.html:48 msgid "MediaGoblin logo" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:54 -msgid "Submit media" -msgstr "コンテンツを投稿" +#: mediagoblin/templates/mediagoblin/base.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:157 +msgid "Add media" +msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:64 msgid "Verify your email!" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:72 +#: mediagoblin/templates/mediagoblin/base.html:71 msgid "log out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:75 +#: mediagoblin/templates/mediagoblin/base.html:74 #: mediagoblin/templates/mediagoblin/auth/login.html:27 #: mediagoblin/templates/mediagoblin/auth/login.html:45 msgid "Log in" msgstr "ログイン" -#: mediagoblin/templates/mediagoblin/base.html:91 +#: mediagoblin/templates/mediagoblin/base.html:86 msgid "" "Powered by MediaGoblin, a GNU project" @@ -222,7 +247,7 @@ msgstr "" msgid "Explore" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:27 +#: mediagoblin/templates/mediagoblin/root.html:26 msgid "Hi there, welcome to this MediaGoblin site!" msgstr "" @@ -246,22 +271,21 @@ msgstr "" #, python-format msgid "" "Create an account at this site\n" -" or\n" -" Set up MediaGoblin on your own server" +" or\n" +" Set up MediaGoblin on your own server" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:44 +#: mediagoblin/templates/mediagoblin/root.html:40 msgid "Most recent media" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/change_fp.html:29 -msgid "Enter your new password" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:32 +msgid "Set your new password" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/change_fp.html:33 -#: mediagoblin/templates/mediagoblin/submit/start.html:30 -msgid "Submit" -msgstr "送信" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:35 +msgid "Set password" +msgstr "" #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" @@ -271,15 +295,6 @@ msgstr "" msgid "Send instructions" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 -msgid "Your password has been changed. Try to log in now." -msgstr "" - -#: mediagoblin/templates/mediagoblin/auth/fp_email_sent.html:22 -msgid "" -"Check your inbox. We sent an email with a URL for changing your password." -msgstr "" - #: mediagoblin/templates/mediagoblin/auth/fp_verification_email.txt:19 #, python-format msgid "" @@ -310,11 +325,11 @@ msgstr "ここで作成!" msgid "Forgot your password?" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/register.html:27 +#: mediagoblin/templates/mediagoblin/auth/register.html:32 msgid "Create an account!" msgstr "アカウントを作成!" -#: mediagoblin/templates/mediagoblin/auth/register.html:31 +#: mediagoblin/templates/mediagoblin/auth/register.html:36 msgid "Create" msgstr "" @@ -345,10 +360,16 @@ msgid "Cancel" msgstr "キャンセル" #: mediagoblin/templates/mediagoblin/edit/edit.html:37 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:40 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:35 msgid "Save changes" msgstr "投稿する" +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:34 +#, python-format +msgid "Changing %(username)s's account settings" +msgstr "" + #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29 #, python-format msgid "Editing %(username)s's profile" @@ -360,13 +381,32 @@ msgstr "%(username)sさんのプロフィールを編集中" msgid "Media tagged with: %(tag_name)s" msgstr "" -#: mediagoblin/templates/mediagoblin/media_displays/video.html:19 +#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 +#: mediagoblin/templates/mediagoblin/media_displays/video.html:46 msgid "Original" msgstr "" +#: mediagoblin/templates/mediagoblin/media_displays/video.html:33 +msgid "" +"Sorry, this video will not work because \n" +"\t your web browser does not support HTML5 \n" +"\t video." +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:36 +msgid "" +"You can get a modern web browser that \n" +"\t can play this video at \n" +"\t http://getfirefox.com!" +msgstr "" + #: mediagoblin/templates/mediagoblin/submit/start.html:26 -msgid "Submit yer media" -msgstr "コンテンツを投稿" +msgid "Add your media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Add" +msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format @@ -378,31 +418,57 @@ msgstr "" msgid "%(username)s's media" msgstr "%(username)sさんのコンテンツ" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:57 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:60 #, python-format -msgid "By %(username)s on %(date)s" +msgid "Added on %(date)s." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:67 -msgid "Post a comment" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:85 -msgid "at" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 -msgid "Post comment!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:124 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:69 msgid "Edit" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:130 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:73 msgid "Delete" msgstr "" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:79 +#, python-format +msgid "%(comment_count)s comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:81 +#, python-format +msgid "%(comment_count)s comments" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:83 +msgid "No comments yet." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:91 +msgid "Add one" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:100 +msgid "" +"Type your comment here. You can use Markdown for" +" formatting." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 +msgid "Add this comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:126 +msgid "at" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:141 +#, python-format +msgid "

❖ Browsing media by %(username)s

" +msgstr "" + #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -483,30 +549,31 @@ msgid "Here's a spot to tell others about yourself." msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/user.html:101 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:119 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:118 msgid "Edit profile" msgstr "プロフィールを編集" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:107 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:106 msgid "This user hasn't filled in their profile (yet)." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:133 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:125 +msgid "Change account settings" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:138 #, python-format msgid "View all of %(username)s's media" msgstr "%(username)sさんのコンテンツをすべて見る" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:146 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:151 msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:152 -msgid "Add media" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/user.html:158 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:163 +#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72 msgid "There doesn't seem to be any media here yet..." msgstr "" @@ -518,28 +585,34 @@ msgstr "" msgid "Atom feed" msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:40 -msgid "Newer" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:39 +msgid "← Newer" msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:46 -msgid "Older" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:45 +msgid "Older →" msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:50 +#: mediagoblin/templates/mediagoblin/utils/pagination.html:48 msgid "Go to page:" msgstr "" +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:27 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:32 +msgid "newer" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:38 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:43 +msgid "older" +msgstr "" + #: mediagoblin/templates/mediagoblin/utils/tags.html:20 -msgid "Tagged with" +msgid "View more media tagged with" msgstr "" #: mediagoblin/templates/mediagoblin/utils/tags.html:25 -msgid "and" -msgstr "" - -#: mediagoblin/user_pages/forms.py:24 -msgid "Comment" +msgid "or" msgstr "" #: mediagoblin/user_pages/forms.py:30 diff --git a/mediagoblin/i18n/nl/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/nl/LC_MESSAGES/mediagoblin.mo index 842bfb9b4989511d1c900cf5f80d0c147f5ed7d5..4d03c586116666894bf7768a0089ea53dcda2358 100644 GIT binary patch delta 4284 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 diff --git a/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.mo index c07f42beb8bcf379e111623dd567cceb3bb8b78e..11b00041fbae9de695c6fa6b7ba58ab62cfdc86e 100644 GIT binary patch literal 12901 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 CC2r6F delta 3264 zcmajg4{TM{9l-I^7A%yu&=zVZFi!c?Kh(bVwNRiGNvYBlYheO$E@8{7?YIheAw$$byb-^E)A#`X2FsYN1+U;btgI|VIfekv-%)7efUf%J>?T{>>=;+b}1M zT{PBWACf+0MIJ>tX$IM>`U*;f9>r073Rz1nXH^OLI;2Z&M~UD7$_5iC3x65;r@qb~ z8UI8T@t2UkK*t^U5=zn3ar_%`2qlMiV;sMM5|Ili6JA7F@G?p&-b0!1BixH0P$IUL__CI2K#e<4 zYUXoM|1e4fC$JAsplskmj>b+Jvdw$@KKcO z^$Hf_MdU)M*HAWc8J{cSdLw62j}TU-Qn?u#@6b4h+i+%ep~$YFocu#YRqkE1N~Iv&Qk=(&^K%E@=4q;Ma~b-xE0pHn}J2K)*olyfLK{v%3py@wK! zeapPTq2x$Z~V$RNtNJ5l2}O3F?lXH(xqsg>tZHhLaQ@xLvnW!{K%KX1TIpAfKjl7Mutgk+# zK^>_IR%H#f0c9h7$c0e*QBG)~oXAC@tAeQiRMh`?WY6fM&3n(YPgp%_&P*QRg zb8?^61}YjVQ9^zU*^{~-Wv4SJ8+icmQaeEsJH8$Bu{N+AR(-Fg~$p14+Q}U9t7UUgu6UucmC=u~cLU#+d6G*#|lrD^@b~!oh;fD4(jHd_FTQG$+iO1oKbz2n=mQWH);}N zI_pjN+Hr@yV=;Y)(HY|g+H$o?TTV((Il-v5^x@kF^@!)|#Hi&a9XDBcY23R_Hikmnz=#*aD-hmh#x= z7!jY4hkTbs%k^|-+@w+x=CqRu7?KI6>vo5~t@~5x-*9u-6CVm|*POfcPD$K+r1hx9 zzKwAUIWl%kAM&%ZM#@VPW2T*oDa*B$6{r!z7M+CWD*4cx2*Sl{@7)@2jd!%RZ_)Ag z?v5?3?OpBdWe4`R-fkux$y4jigr{3~w8t05b#-@ihCg2W_we+Rbz#Li|C&O4BHXB} zY6eX*sRPPLD$+>a{qQXv50BJm|FbCf_*ud;sSX}BV`J=?iX5XDwe7eueVgHcz7(e& zXxk*U;Yem&^2^*jY1agn?VC)-ufb z_OJhJ_}cn+SM1HEQnItc>%Kkv*A1m5Ro9lN4zlAW{HWn;*VJj2tcKrdY*~CuiVcRB z8oRbg5wkl>r_VpBC#gK0a>mU6DcI|pG7ANJvg!DLDcGBu_fxQs)pK$+Xb~T8eEgHf zwdMJ}&6zzzCJ0{Ig$dsV#0j zIOaQ(^I>5!j~hrx`O4sc6Rw*CN_o\n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -23,27 +23,15 @@ msgstr "" msgid "Invalid file given for media type." msgstr "Ugyldig fil for mediatypen." -#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 +#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41 msgid "Username" msgstr "Brukarnamn" -#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:53 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 msgid "Password" msgstr "Passord" -#: mediagoblin/auth/forms.py:35 -msgid "Passwords must match." -msgstr "Passorda må vera like." - -#: mediagoblin/auth/forms.py:37 -msgid "Confirm password" -msgstr "Gjenta passord" - -#: mediagoblin/auth/forms.py:39 -msgid "Type it again here to make sure there are no spelling mistakes." -msgstr "Skriv passordet omatt for å unngå stavefeil." - -#: mediagoblin/auth/forms.py:42 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "Epost" @@ -59,7 +47,7 @@ msgstr "Ein konto med dette brukarnamnet finst allereide." msgid "Sorry, a user with that email address already exists." msgstr "" -#: mediagoblin/auth/views.py:179 +#: mediagoblin/auth/views.py:180 msgid "" "Your email address has been verified. You may now login, edit your profile, " "and submit images!" @@ -67,68 +55,104 @@ msgstr "" "Kontoen din er stadfesta. Du kan no logga inn, endra profilen din og lasta " "opp filer." -#: mediagoblin/auth/views.py:185 +#: mediagoblin/auth/views.py:186 msgid "The verification key or user id is incorrect" msgstr "Stadfestingsnykelen eller brukar-ID-en din er feil." -#: mediagoblin/auth/views.py:203 +#: mediagoblin/auth/views.py:204 msgid "You must be logged in so we know who to send the email to!" msgstr "" -#: mediagoblin/auth/views.py:211 +#: mediagoblin/auth/views.py:212 msgid "You've already verified your email address!" msgstr "" -#: mediagoblin/auth/views.py:224 +#: mediagoblin/auth/views.py:225 msgid "Resent your verification email." msgstr "Send ein ny stadfestingsepost." -#: mediagoblin/auth/views.py:265 +#: mediagoblin/auth/views.py:260 +msgid "" +"An email has been sent with instructions on how to change your password." +msgstr "" + +#: mediagoblin/auth/views.py:270 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." msgstr "" "Kunne ikkje senda epost. Brukarnamnet ditt er inaktivt eller uverifisert." +#: mediagoblin/auth/views.py:282 +msgid "Couldn't find someone with that username or email." +msgstr "" + +#: mediagoblin/auth/views.py:330 +msgid "You can now log in using your new password." +msgstr "" + #: mediagoblin/edit/forms.py:24 mediagoblin/submit/forms.py:27 msgid "Title" msgstr "Tittel" -#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:27 mediagoblin/submit/forms.py:30 +msgid "Description of this work" +msgstr "Skildring av mediefila" + +#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:31 +msgid "" +"You can use\n" +" \n" +" Markdown for formatting." +msgstr "" + +#: mediagoblin/edit/forms.py:32 mediagoblin/submit/forms.py:35 msgid "Tags" msgstr "Merkelappar" -#: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 -msgid "Seperate tags by commas." +#: mediagoblin/edit/forms.py:34 mediagoblin/submit/forms.py:37 +msgid "Separate tags by commas." msgstr "" -#: mediagoblin/edit/forms.py:33 +#: mediagoblin/edit/forms.py:37 msgid "Slug" msgstr "Nettnamn" -#: mediagoblin/edit/forms.py:34 +#: mediagoblin/edit/forms.py:38 msgid "The slug can't be empty" msgstr "Nettnamnet kan ikkje vera tomt" -#: mediagoblin/edit/forms.py:35 +#: mediagoblin/edit/forms.py:39 msgid "" -"The title part of this media's URL. You usually don't need to change this." -msgstr "Nettnamnet (adressetittel) for mediefila di. Trengst ikkje endrast." +"The title part of this media's address. You usually don't need to change " +"this." +msgstr "" -#: mediagoblin/edit/forms.py:42 +#: mediagoblin/edit/forms.py:46 msgid "Bio" msgstr "Presentasjon" -#: mediagoblin/edit/forms.py:45 +#: mediagoblin/edit/forms.py:48 +msgid "" +"You can use\n" +" \n" +" Markdown for formatting." +msgstr "" + +#: mediagoblin/edit/forms.py:53 msgid "Website" msgstr "Heimeside" -#: mediagoblin/edit/forms.py:49 +#: mediagoblin/edit/forms.py:60 msgid "Old password" msgstr "" -#: mediagoblin/edit/forms.py:52 -msgid "New Password" +#: mediagoblin/edit/forms.py:62 +msgid "Enter your old password to prove you own this account." +msgstr "" + +#: mediagoblin/edit/forms.py:65 +msgid "New password" msgstr "" #: mediagoblin/edit/views.py:65 @@ -143,39 +167,43 @@ msgstr "Trå varsamt, du endrar nokon andre sine mediefiler." msgid "You are editing a user's profile. Proceed with caution." msgstr "Trå varsamt, du endrar nokon andre sin profil." -#: mediagoblin/edit/views.py:171 +#: mediagoblin/edit/views.py:174 +msgid "Profile changes saved" +msgstr "" + +#: mediagoblin/edit/views.py:200 msgid "Wrong password" msgstr "" -#: mediagoblin/edit/views.py:192 -msgid "Profile edited!" +#: mediagoblin/edit/views.py:216 +msgid "Account settings saved" msgstr "" -#: mediagoblin/media_types/__init__.py:65 -msgid "Could not find any file extension in \"{filename}\"" +#: mediagoblin/media_types/__init__.py:77 +msgid "Could not extract any file extension from \"{filename}\"" +msgstr "" + +#: mediagoblin/media_types/__init__.py:88 +msgid "Sorry, I don't support that file type :(" msgstr "" #: mediagoblin/submit/forms.py:25 msgid "File" msgstr "Fil" -#: mediagoblin/submit/forms.py:30 -msgid "Description of this work" -msgstr "Skildring av mediefila" - -#: mediagoblin/submit/views.py:49 +#: mediagoblin/submit/views.py:50 msgid "You must provide a file." msgstr "Du må velja ei fil." -#: mediagoblin/submit/views.py:127 +#: mediagoblin/submit/views.py:128 msgid "Woohoo! Submitted!" msgstr "Johoo! Opplasta!" -#: mediagoblin/submit/views.py:133 -msgid "Invalid file type." -msgstr "" +#: mediagoblin/templates/mediagoblin/404.html:22 +msgid "Image of 404 goblin stressing out" +msgstr "Bilete av stressa 404-tusse." -#: mediagoblin/templates/mediagoblin/404.html:21 +#: mediagoblin/templates/mediagoblin/404.html:23 msgid "Oops!" msgstr "Oops." @@ -191,33 +219,30 @@ msgstr "" "Er du sikker på at adressa er korrekt, so er sida truleg flytta eller " "sletta." -#: mediagoblin/templates/mediagoblin/404.html:32 -msgid "Image of 404 goblin stressing out" -msgstr "Bilete av stressa 404-tusse." - -#: mediagoblin/templates/mediagoblin/base.html:49 +#: mediagoblin/templates/mediagoblin/base.html:48 msgid "MediaGoblin logo" msgstr "MediaGoblin" -#: mediagoblin/templates/mediagoblin/base.html:54 -msgid "Submit media" -msgstr "Last opp" +#: mediagoblin/templates/mediagoblin/base.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:157 +msgid "Add media" +msgstr "Legg til mediefiler" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:64 msgid "Verify your email!" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:72 +#: mediagoblin/templates/mediagoblin/base.html:71 msgid "log out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:75 +#: mediagoblin/templates/mediagoblin/base.html:74 #: mediagoblin/templates/mediagoblin/auth/login.html:27 #: mediagoblin/templates/mediagoblin/auth/login.html:45 msgid "Log in" msgstr "Logg inn" -#: mediagoblin/templates/mediagoblin/base.html:91 +#: mediagoblin/templates/mediagoblin/base.html:86 msgid "" "Powered by MediaGoblin, a GNU project" @@ -229,7 +254,7 @@ msgstr "" msgid "Explore" msgstr "Utforsk" -#: mediagoblin/templates/mediagoblin/root.html:27 +#: mediagoblin/templates/mediagoblin/root.html:26 msgid "Hi there, welcome to this MediaGoblin site!" msgstr "" @@ -253,22 +278,21 @@ msgstr "" #, python-format msgid "" "Create an account at this site\n" -" or\n" -" Set up MediaGoblin on your own server" +" or\n" +" Set up MediaGoblin on your own server" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:44 +#: mediagoblin/templates/mediagoblin/root.html:40 msgid "Most recent media" msgstr "Nyaste mediefiler" -#: mediagoblin/templates/mediagoblin/auth/change_fp.html:29 -msgid "Enter your new password" -msgstr "Fyll inn passord" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:32 +msgid "Set your new password" +msgstr "" -#: mediagoblin/templates/mediagoblin/auth/change_fp.html:33 -#: mediagoblin/templates/mediagoblin/submit/start.html:30 -msgid "Submit" -msgstr "Send" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:35 +msgid "Set password" +msgstr "" #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" @@ -278,17 +302,6 @@ msgstr "" msgid "Send instructions" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 -msgid "Your password has been changed. Try to log in now." -msgstr "Passordet endra. Prøv å logga inn no." - -#: mediagoblin/templates/mediagoblin/auth/fp_email_sent.html:22 -msgid "" -"Check your inbox. We sent an email with a URL for changing your password." -msgstr "" -"Sjekk innboksen din. Me har sendt deg ein epost med ei netadresse for " -"passordendring." - #: mediagoblin/templates/mediagoblin/auth/fp_verification_email.txt:19 #, python-format msgid "" @@ -326,11 +339,11 @@ msgstr "Lag ein!" msgid "Forgot your password?" msgstr "Gløymd passordet?" -#: mediagoblin/templates/mediagoblin/auth/register.html:27 +#: mediagoblin/templates/mediagoblin/auth/register.html:32 msgid "Create an account!" msgstr "Lag ein konto." -#: mediagoblin/templates/mediagoblin/auth/register.html:31 +#: mediagoblin/templates/mediagoblin/auth/register.html:36 msgid "Create" msgstr "Opprett" @@ -361,10 +374,16 @@ msgid "Cancel" msgstr "Bryt av" #: mediagoblin/templates/mediagoblin/edit/edit.html:37 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:40 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:35 msgid "Save changes" msgstr "Lagra" +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:34 +#, python-format +msgid "Changing %(username)s's account settings" +msgstr "" + #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29 #, python-format msgid "Editing %(username)s's profile" @@ -376,13 +395,32 @@ msgstr "Endrar profilen til %(username)s" msgid "Media tagged with: %(tag_name)s" msgstr "" -#: mediagoblin/templates/mediagoblin/media_displays/video.html:19 +#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 +#: mediagoblin/templates/mediagoblin/media_displays/video.html:46 msgid "Original" msgstr "" +#: mediagoblin/templates/mediagoblin/media_displays/video.html:33 +msgid "" +"Sorry, this video will not work because \n" +"\t your web browser does not support HTML5 \n" +"\t video." +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:36 +msgid "" +"You can get a modern web browser that \n" +"\t can play this video at \n" +"\t http://getfirefox.com!" +msgstr "" + #: mediagoblin/templates/mediagoblin/submit/start.html:26 -msgid "Submit yer media" -msgstr "Last opp" +msgid "Add your media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Add" +msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format @@ -394,31 +432,57 @@ msgstr "" msgid "%(username)s's media" msgstr "%(username)s sine mediefiler" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:57 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:60 #, python-format -msgid "By %(username)s on %(date)s" +msgid "Added on %(date)s." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:67 -msgid "Post a comment" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:85 -msgid "at" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 -msgid "Post comment!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:124 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:69 msgid "Edit" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:130 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:73 msgid "Delete" msgstr "" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:79 +#, python-format +msgid "%(comment_count)s comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:81 +#, python-format +msgid "%(comment_count)s comments" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:83 +msgid "No comments yet." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:91 +msgid "Add one" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:100 +msgid "" +"Type your comment here. You can use Markdown for" +" formatting." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 +msgid "Add this comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:126 +msgid "at" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:141 +#, python-format +msgid "

❖ Browsing media by %(username)s

" +msgstr "" + #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -501,30 +565,31 @@ msgid "Here's a spot to tell others about yourself." msgstr "Her kan du fortelja om deg sjølv." #: mediagoblin/templates/mediagoblin/user_pages/user.html:101 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:119 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:118 msgid "Edit profile" msgstr "Endra profil" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:107 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:106 msgid "This user hasn't filled in their profile (yet)." msgstr "Brukaren har ikkje fylt ut profilen sin (enno)." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:133 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:125 +msgid "Change account settings" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:138 #, python-format msgid "View all of %(username)s's media" msgstr "Sjå alle %(username)s sine mediefiler" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:146 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:151 msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." msgstr "Her kjem mediefilene dine." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:152 -msgid "Add media" -msgstr "Legg til mediefiler" - -#: mediagoblin/templates/mediagoblin/user_pages/user.html:158 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:163 +#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72 msgid "There doesn't seem to be any media here yet..." msgstr "Ser ikkje ut til at det finst nokon mediefiler her nett no." @@ -536,30 +601,36 @@ msgstr " " msgid "Atom feed" msgstr "Atom-kjelde" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:40 -msgid "Newer" -msgstr "Nyare" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:39 +msgid "← Newer" +msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:46 -msgid "Older" -msgstr "Eldre" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:45 +msgid "Older →" +msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:50 +#: mediagoblin/templates/mediagoblin/utils/pagination.html:48 msgid "Go to page:" msgstr "" +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:27 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:32 +msgid "newer" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:38 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:43 +msgid "older" +msgstr "" + #: mediagoblin/templates/mediagoblin/utils/tags.html:20 -msgid "Tagged with" +msgid "View more media tagged with" msgstr "" #: mediagoblin/templates/mediagoblin/utils/tags.html:25 -msgid "and" +msgid "or" msgstr "" -#: mediagoblin/user_pages/forms.py:24 -msgid "Comment" -msgstr "Innspel" - #: mediagoblin/user_pages/forms.py:30 msgid "I am sure I want to delete this" msgstr "Eg er sikker eg vil sletta dette" diff --git a/mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.mo index 87e627644267845f356f4b3163792eb54d3f7bbf..5b7445f7555287cc6230740e289bd8973d84c09f 100644 GIT binary patch delta 5131 zcmc)L4{TLe9l-I^mK9q5thBVy@$a-y+5&y=wc~H;ifsXL8AblgNf6oXd$;Xl@4egI zdtXaob&42S40CG2oFgy+HH&OBaV!zt)bH=T+d}!X z$z)m6_H*yK_nz}Rzw__q&%V}?I#W2}NySe;e^dBdHbU+$|HMWqRmyD~@4($S0iVVa z{63z?Ut=MzsJ)!2M^z_)O0+Hy_iMRVcd>o_!<^T`FN$uu^6SNi%>GV6y^C^l%Z+I zlvLQqg=F9W@~ghfKk3=e{PGu3J~-o-zk@Oa+0=R)j=`x|h)e?&@?DIb+&5z}ej6pD zM^V~)Rq`(>xD(JlnPGZLcD|ltR)Q^@5lA{Fz&>cQD*;rR3aJK zjSlWb8OkhrA(=@beN~U4#;;1jWG;S;GC5xHU-%<3?CNc7!EDkbfvmtKxC0--BPesD zk#2qxx8OcJggbCKl@pu#1=iy!q)Ju7T9@xqK`vzMHsa^87qjsdlrcVq64;+ndiJL8 z+bHi{LV539{CgIur!rzvmsl#qpo$n*vaJG0GE@tm$Bj5&*8ftS*)WnQksiSu{4L5P zIf)X$U;O*GP%`r$lvIvm>dV-c;YwVG%kU|b9-l=Ca0*L8oP{zJA)F}de=!#_dDh?p z+=gGmgII?xGcrBzMhWO4lmPakEU%|f0)Gaj$48LqqE2EKUO;*8O_Y7%BFYeC&t%fm zzM9O1^kfOrrfNkAG~$S;2ZB@=(} z%P*p&KC9Z_`B3UBs3!lTxTvE*Cf5?Qun8rAgUGy6$B|7>{Rt(2i%6_$0#QpK4Jd)E zLP@QG63{l3dUoSTJb?G&H<6gszh;yFMO@5eEy()agtG4U;ygTpZTL6L!?iqIfuBPO z%ZLqQW&1~1`Vm`m+4`-W2UD%4p z&4jx-Y$X$JwWIxe9^K%H z<7Omk=(b+X)5=Igu&Yruh0|?l$8=p@akOJ}n-SF%N&jWOkUMQ9%(QN2^m07%pw~*; zm)|qxObl7KJ;FM2DIAw99au9?SNEdHXiB z7>TeMQ!Sat##OOp%B3R}RY}LR6GogiDjj|8i&iog(Fx1d=2q7>!mihqKVd|>ZN3qIo%U=JGI+sxO%W|ZQ0t48`0Rn*wH0fb1bU#gNr8hjj`U4>1QKS?P^ouhyjk`s9kHa7PO_`Z zvfWJA+M_Wl?CmmjeU-PWu+$3`e#NkCyLWD;1KrVxX_1OpES){Z*P2pQrgr zH`Zge={A{FrcEoRlYV)yp_S`b-80{RJ6&JE`$yrUBaKMJHXUamRTR!nrEBr$vhFl( zGoUwENgXy4l6~D^=uX>gzpK2{b-U_=!H8iq?Cnw8Y%^l9K*Dr`WPghpcAa3{upfvp z0>L)JiH4o>##MenL(pi{?TjIRaU(sw1M1%Nyzyp~ES&tAC@G6uw&|}6^4!7nm3iQ8 zD7ld8AkPLbM3`y%${wdDNhTW-a97Oey)t{upsVAjDha;b+8UtK<&Bw-{mu=4C{dRw zl2Mt?M#AdRF{?vIB{4Gf)0rDK*!2@zQ-0#|WrVK%xjLMiO6Lvg9G2zO)oH$BFo%7A z>mnJ}{ z%t}TAmfbOMqBJ+_!)@YE_#61a_usrzAG~=-!*s%6Yd-cJcK!cj4_9lF25XW9mvF5z zy)J3!u(x!|^pd7TW_#4vZ1Ba`+2A7qZ_|_~H)ghY!~Tdi`SG&J>+JvA;<9nfL?=4uKa2ezDg1ec$zj=CJj`wQ$m#18@BVW7y_s^)#TP^c4eFpqs#zL=d z=7SS#E4@PxKMD@c{QCS4cMh~yY_3|D+1@|+IC!sOs&}^Hdu{#)=>zQ}IuDM{vb{}3 z(+AH4FI7}M&|mpRR%*Q*P3eq(9EU@z_mk?o-}hX|oqakrxVL>==fmIu@xPuAXJ@Y& zikZW8*nWKZthjYM^W{2+_UP30j^e>QULDh|i)5(%qU*Hp)y_HZHP4+;dZRN!{TJhH B)u;df delta 3357 zcmZ|Pe{hsX8Nl%kPy!)9$d3|%z^0To2gxP5K!6kmLZF>sN=Zp=)uGJh?&a>ackdhC z_wGW9cpXcrG99ONQQNWOn4+Z}L2ENQ)6xDS>M&y+sx!7#p;c<9R>xMIaq5qe`hD(R zD*u>C^4WK9-`!`QefHi+zj8+s*%Ujcr~8ExA9ll zi7(DkYA*g2d-3166BBfocH=1C zjmMD})WUg6)#KGD<6^*NSE4xlEFcg0Fx*S-;4aJ2l*%C zA6rEJC8a;0<92)jrD&Sjemm|$Im1KPjbBE|$XS#L&!H@M9_1+hj56Op@kYFai*W~O z+lhNo=6wR!<1ZV?f1JjAN?hY69KpSK4?c~Z*h3m5Q%MZb#VvRNC1Wk*m$lS&sBt4o z&3q#2A4SPv0SE91N&sg|G;W|FVcrCrkS=uu`|ztMsd@#anBGGN23zR_4uEV#MR#Li@F9S(=J8s82Q35)F zGV$w?f52Xz|Avx@7}4E=36vxGEJ}@h0a;&t4IjdQ_fc+D4W06S2TGs=SS|N|hz9kbMo=co zpk$(m2k{jC23Kj$7pq#8YQr`>hQoLi&m%)slGS8G_u^_ijDuFIUNqq}$ z#?{z|8Qg*=a2LLba?KLlU0G)*$_9pz3!t($(2!Ig!z`XeepMrRk{7n(4BUqEa0kx9 zVYHKTY_-;YP@}b7KlfX6`%@{Mb5gFcM{D|R-Mph!+w226R?@zwSGA=~-id{3z<5a~ zs|GSo@-98$7Xs~iqyE9TzTMHG+j5hkVTZi<1KhVjH@zSoBuDmp6 z!f@OVQgJol=W@J<-hMa8>C2zcQOKsW=P%3a{jQf{;t3jAM>_}eju*N_<$AWd_Sn>q zY8$F*J!kyGcc*47=$%OtLjC}$<`w84_?Q)idfRekj1a%z{; ztTTq79mlI2kdun*kzhg=$ogp#%$(zKWxSL!d9~jmJ~!!mNhCSHtL!)CG}wU^pShw&57{lcx2`|sCYjifx9QVTuDZ3yKH7Tx|Cg%? z)W@8_-R~YKNX|G`;~q3RMJ;*xz@$uE-^>yE>3AkEXYTBgyR{N9KWMfb%=rQhY(GAjttkm?Q ztM}QxYnIuqYrfOH!z;REwnB6k<)_MiD~F@5tm@(RV0S;I7szdyKAkUQ$w1{RBISgk zi6)8bo48R~iJF?8KH=->C$;A!8B$KTHrYG_*lQU2Q*|BhR_%=PEIF>cW=N{6#KDo2 zq{EVT8!hKwo-pGVikyBBaN?XnN{-1)pJXk2sB_4^*?HcUx@Ox#_n>__aj|0$HB&x! czRKKad8wL_a)|tsXiVA\n" +"POT-Creation-Date: 2012-01-07 13:47-0600\n" +"PO-Revision-Date: 2012-01-07 19:44+0000\n" +"Last-Translator: cwebber \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" @@ -24,28 +24,15 @@ msgstr "" msgid "Invalid file given for media type." msgstr "Arquivo inválido para esse tipo de mídia" -#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 +#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41 msgid "Username" msgstr "Nome de Usuário" -#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:53 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 msgid "Password" msgstr "Senha" -#: mediagoblin/auth/forms.py:35 -msgid "Passwords must match." -msgstr "Senhas devem ser iguais." - -#: mediagoblin/auth/forms.py:37 -msgid "Confirm password" -msgstr "Confirmar senha" - -#: mediagoblin/auth/forms.py:39 -msgid "Type it again here to make sure there are no spelling mistakes." -msgstr "" -"Digite novamente aqui para ter certeza que não houve erros de digitação" - -#: mediagoblin/auth/forms.py:42 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "Endereço de email" @@ -61,7 +48,7 @@ msgstr "Desculpe, um usuário com este nome já existe." msgid "Sorry, a user with that email address already exists." msgstr "Desculpe, um usuário com esse email já esta cadastrado" -#: mediagoblin/auth/views.py:179 +#: mediagoblin/auth/views.py:180 msgid "" "Your email address has been verified. You may now login, edit your profile, " "and submit images!" @@ -69,23 +56,28 @@ 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:185 +#: mediagoblin/auth/views.py:186 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:203 +#: mediagoblin/auth/views.py:204 msgid "You must be logged in so we know who to send the email to!" msgstr " " -#: mediagoblin/auth/views.py:211 +#: mediagoblin/auth/views.py:212 msgid "You've already verified your email address!" msgstr "Você já verifico seu email!" -#: mediagoblin/auth/views.py:224 +#: mediagoblin/auth/views.py:225 msgid "Resent your verification email." msgstr "O email de verificação foi reenviado." -#: mediagoblin/auth/views.py:265 +#: mediagoblin/auth/views.py:260 +msgid "" +"An email has been sent with instructions on how to change your password." +msgstr "" + +#: mediagoblin/auth/views.py:270 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." @@ -93,47 +85,77 @@ msgstr "" "Não foi possível enviar o email de recuperação de senha, pois seu nome de " "usuário está inativo ou o email da sua conta não foi confirmado." +#: mediagoblin/auth/views.py:282 +msgid "Couldn't find someone with that username or email." +msgstr "" + +#: mediagoblin/auth/views.py:330 +msgid "You can now log in using your new password." +msgstr "" + #: mediagoblin/edit/forms.py:24 mediagoblin/submit/forms.py:27 msgid "Title" msgstr "Título" -#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:27 mediagoblin/submit/forms.py:30 +msgid "Description of this work" +msgstr "Descrição desse trabalho" + +#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:31 +msgid "" +"You can use\n" +" \n" +" Markdown for formatting." +msgstr "" + +#: mediagoblin/edit/forms.py:32 mediagoblin/submit/forms.py:35 msgid "Tags" msgstr "Etiquetas" -#: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 -msgid "Seperate tags by commas." -msgstr "Separar tags por virgulas." +#: mediagoblin/edit/forms.py:34 mediagoblin/submit/forms.py:37 +msgid "Separate tags by commas." +msgstr "" -#: mediagoblin/edit/forms.py:33 +#: mediagoblin/edit/forms.py:37 msgid "Slug" msgstr "Arquivo" -#: mediagoblin/edit/forms.py:34 +#: mediagoblin/edit/forms.py:38 msgid "The slug can't be empty" msgstr "O arquivo não pode estar vazio" -#: mediagoblin/edit/forms.py:35 +#: mediagoblin/edit/forms.py:39 msgid "" -"The title part of this media's URL. You usually don't need to change this." +"The title part of this media's address. You usually don't need to change " +"this." msgstr "" -"A parte título da URL dessa mídia. Geralmente não é necessário alterar isso." -#: mediagoblin/edit/forms.py:42 +#: mediagoblin/edit/forms.py:46 msgid "Bio" msgstr "Biografia" -#: mediagoblin/edit/forms.py:45 +#: mediagoblin/edit/forms.py:48 +msgid "" +"You can use\n" +" \n" +" Markdown for formatting." +msgstr "" + +#: mediagoblin/edit/forms.py:53 msgid "Website" msgstr "Website" -#: mediagoblin/edit/forms.py:49 +#: mediagoblin/edit/forms.py:60 msgid "Old password" msgstr "Senha antiga" -#: mediagoblin/edit/forms.py:52 -msgid "New Password" -msgstr "Nova Senha" +#: mediagoblin/edit/forms.py:62 +msgid "Enter your old password to prove you own this account." +msgstr "" + +#: mediagoblin/edit/forms.py:65 +msgid "New password" +msgstr "" #: mediagoblin/edit/views.py:65 msgid "An entry with that slug already exists for this user." @@ -147,39 +169,43 @@ msgstr "Você está editando a mídia de outro usuário. Tenha cuidado." msgid "You are editing a user's profile. Proceed with caution." msgstr "Você está editando um perfil de usuário. Tenha cuidado." -#: mediagoblin/edit/views.py:171 +#: mediagoblin/edit/views.py:174 +msgid "Profile changes saved" +msgstr "" + +#: mediagoblin/edit/views.py:200 msgid "Wrong password" msgstr "Senha errada" -#: mediagoblin/edit/views.py:192 -msgid "Profile edited!" -msgstr "Perfil editado!" +#: mediagoblin/edit/views.py:216 +msgid "Account settings saved" +msgstr "" -#: mediagoblin/media_types/__init__.py:65 -msgid "Could not find any file extension in \"{filename}\"" -msgstr " " +#: mediagoblin/media_types/__init__.py:77 +msgid "Could not extract any file extension from \"{filename}\"" +msgstr "" + +#: mediagoblin/media_types/__init__.py:88 +msgid "Sorry, I don't support that file type :(" +msgstr "" #: mediagoblin/submit/forms.py:25 msgid "File" msgstr "Arquivo" -#: mediagoblin/submit/forms.py:30 -msgid "Description of this work" -msgstr "Descrição desse trabalho" - -#: mediagoblin/submit/views.py:49 +#: mediagoblin/submit/views.py:50 msgid "You must provide a file." msgstr "Você deve fornecer um arquivo." -#: mediagoblin/submit/views.py:127 +#: mediagoblin/submit/views.py:128 msgid "Woohoo! Submitted!" msgstr "Eba! Enviado!" -#: mediagoblin/submit/views.py:133 -msgid "Invalid file type." -msgstr "Tipo de arquivo inválido." +#: mediagoblin/templates/mediagoblin/404.html:22 +msgid "Image of 404 goblin stressing out" +msgstr "Imagem do goblin 404 aparecendo" -#: mediagoblin/templates/mediagoblin/404.html:21 +#: mediagoblin/templates/mediagoblin/404.html:23 msgid "Oops!" msgstr "Oops" @@ -195,33 +221,30 @@ msgstr "" "Se você está certo de que o endereço está correto, talvez a página que " "esteja procurando tenha sido apagada ou mudou de endereço" -#: mediagoblin/templates/mediagoblin/404.html:32 -msgid "Image of 404 goblin stressing out" -msgstr "Imagem do goblin 404 aparecendo" - -#: mediagoblin/templates/mediagoblin/base.html:49 +#: mediagoblin/templates/mediagoblin/base.html:48 msgid "MediaGoblin logo" msgstr "Logo MediaGoblin" -#: mediagoblin/templates/mediagoblin/base.html:54 -msgid "Submit media" -msgstr "Enviar mídia" +#: mediagoblin/templates/mediagoblin/base.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:157 +msgid "Add media" +msgstr "Adicionar mídia" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:64 msgid "Verify your email!" msgstr "Verifique seu email!" -#: mediagoblin/templates/mediagoblin/base.html:72 +#: mediagoblin/templates/mediagoblin/base.html:71 msgid "log out" msgstr "Sair" -#: mediagoblin/templates/mediagoblin/base.html:75 +#: mediagoblin/templates/mediagoblin/base.html:74 #: mediagoblin/templates/mediagoblin/auth/login.html:27 #: mediagoblin/templates/mediagoblin/auth/login.html:45 msgid "Log in" msgstr "Entrar" -#: mediagoblin/templates/mediagoblin/base.html:91 +#: mediagoblin/templates/mediagoblin/base.html:86 msgid "" "Powered by MediaGoblin, a GNU project" @@ -233,7 +256,7 @@ msgstr "" msgid "Explore" msgstr "Explorar" -#: mediagoblin/templates/mediagoblin/root.html:27 +#: mediagoblin/templates/mediagoblin/root.html:26 msgid "Hi there, welcome to this MediaGoblin site!" msgstr "Olá, bemvindo ao site de MediaGoblin." @@ -257,22 +280,21 @@ msgstr " " #, python-format msgid "" "Create an account at this site\n" -" or\n" -" Set up MediaGoblin on your own server" +" or\n" +" Set up MediaGoblin on your own server" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:44 +#: mediagoblin/templates/mediagoblin/root.html:40 msgid "Most recent media" msgstr "Mídia mais recente" -#: mediagoblin/templates/mediagoblin/auth/change_fp.html:29 -msgid "Enter your new password" -msgstr "Digite sua nova senha" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:32 +msgid "Set your new password" +msgstr "" -#: mediagoblin/templates/mediagoblin/auth/change_fp.html:33 -#: mediagoblin/templates/mediagoblin/submit/start.html:30 -msgid "Submit" -msgstr "Enviar" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:35 +msgid "Set password" +msgstr "" #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" @@ -282,17 +304,6 @@ msgstr "Recuperar senha" msgid "Send instructions" msgstr "Mandar instruções" -#: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 -msgid "Your password has been changed. Try to log in now." -msgstr "Sua senha foi alterada. Tente entrar agora." - -#: mediagoblin/templates/mediagoblin/auth/fp_email_sent.html:22 -msgid "" -"Check your inbox. We sent an email with a URL for changing your password." -msgstr "" -"Verifique sua caixa de entrada. Mandamos um email com a URL para troca da " -"senha" - #: mediagoblin/templates/mediagoblin/auth/fp_verification_email.txt:19 #, python-format msgid "" @@ -331,11 +342,11 @@ msgstr "Crie uma aqui!" msgid "Forgot your password?" msgstr "Esqueceu sua senha?" -#: mediagoblin/templates/mediagoblin/auth/register.html:27 +#: mediagoblin/templates/mediagoblin/auth/register.html:32 msgid "Create an account!" msgstr "Criar uma conta!" -#: mediagoblin/templates/mediagoblin/auth/register.html:31 +#: mediagoblin/templates/mediagoblin/auth/register.html:36 msgid "Create" msgstr "Criar" @@ -366,10 +377,16 @@ msgid "Cancel" msgstr "Cancelar" #: mediagoblin/templates/mediagoblin/edit/edit.html:37 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:40 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:35 msgid "Save changes" msgstr "Salvar mudanças" +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:34 +#, python-format +msgid "Changing %(username)s's account settings" +msgstr "" + #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29 #, python-format msgid "Editing %(username)s's profile" @@ -381,13 +398,32 @@ msgstr "Editando perfil de %(username)s" msgid "Media tagged with: %(tag_name)s" msgstr "" -#: mediagoblin/templates/mediagoblin/media_displays/video.html:19 +#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 +#: mediagoblin/templates/mediagoblin/media_displays/video.html:46 msgid "Original" msgstr "Original" +#: mediagoblin/templates/mediagoblin/media_displays/video.html:33 +msgid "" +"Sorry, this video will not work because \n" +"\t your web browser does not support HTML5 \n" +"\t video." +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:36 +msgid "" +"You can get a modern web browser that \n" +"\t can play this video at \n" +"\t http://getfirefox.com!" +msgstr "" + #: mediagoblin/templates/mediagoblin/submit/start.html:26 -msgid "Submit yer media" -msgstr "Envie sua mídia" +msgid "Add your media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Add" +msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format @@ -399,31 +435,57 @@ msgstr "" msgid "%(username)s's media" msgstr "Mídia de %(username)s " -#: mediagoblin/templates/mediagoblin/user_pages/media.html:57 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:60 #, python-format -msgid "By %(username)s on %(date)s" +msgid "Added on %(date)s." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:67 -msgid "Post a comment" -msgstr "Postar um comentário" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:85 -msgid "at" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 -msgid "Post comment!" -msgstr "Postar comentário!" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:124 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:69 msgid "Edit" msgstr "Editar" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:130 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:73 msgid "Delete" msgstr "Apagar" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:79 +#, python-format +msgid "%(comment_count)s comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:81 +#, python-format +msgid "%(comment_count)s comments" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:83 +msgid "No comments yet." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:91 +msgid "Add one" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:100 +msgid "" +"Type your comment here. You can use Markdown for" +" formatting." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 +msgid "Add this comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:126 +msgid "at" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:141 +#, python-format +msgid "

❖ Browsing media by %(username)s

" +msgstr "" + #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -509,20 +571,24 @@ msgid "Here's a spot to tell others about yourself." msgstr "Aqui é o lugar onde você fala de si para os outros." #: mediagoblin/templates/mediagoblin/user_pages/user.html:101 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:119 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:118 msgid "Edit profile" msgstr "Editar perfil" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:107 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:106 msgid "This user hasn't filled in their profile (yet)." msgstr "Esse usuário não preencheu seu perfil (ainda)." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:133 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:125 +msgid "Change account settings" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:138 #, python-format msgid "View all of %(username)s's media" msgstr "Ver todas as mídias de %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:146 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:151 msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." @@ -530,11 +596,8 @@ msgstr "" "Aqui é onde sua mídia vai aparecer, mas parece que você não adicionou nada " "ainda." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:152 -msgid "Add media" -msgstr "Adicionar mídia" - -#: mediagoblin/templates/mediagoblin/user_pages/user.html:158 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:163 +#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72 msgid "There doesn't seem to be any media here yet..." msgstr "Aparentemente não há nenhuma mídia aqui ainda..." @@ -546,29 +609,35 @@ msgstr "ícone feed" msgid "Atom feed" msgstr "Atom feed" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:40 -msgid "Newer" -msgstr "Mais novo" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:39 +msgid "← Newer" +msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:46 -msgid "Older" -msgstr "Mais velho" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:45 +msgid "Older →" +msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:50 +#: mediagoblin/templates/mediagoblin/utils/pagination.html:48 msgid "Go to page:" msgstr "Ir a página:" +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:27 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:32 +msgid "newer" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:38 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:43 +msgid "older" +msgstr "" + #: mediagoblin/templates/mediagoblin/utils/tags.html:20 -msgid "Tagged with" +msgid "View more media tagged with" msgstr "" #: mediagoblin/templates/mediagoblin/utils/tags.html:25 -msgid "and" -msgstr "e" - -#: mediagoblin/user_pages/forms.py:24 -msgid "Comment" -msgstr "Comentário" +msgid "or" +msgstr "" #: mediagoblin/user_pages/forms.py:30 msgid "I am sure I want to delete this" diff --git a/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.mo index e0a70ea95a5fc3699829d852ad76e992d7380774..5a71126669d43f3033c43b8c4b1470cbc4bceb0a 100644 GIT binary patch delta 5188 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 nYG5&\n" +"POT-Creation-Date: 2012-01-07 13:47-0600\n" +"PO-Revision-Date: 2012-01-07 19:44+0000\n" +"Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -24,27 +24,15 @@ msgstr "" msgid "Invalid file given for media type." msgstr "Formatul fișierului nu corespunde cu tipul de media selectat." -#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 +#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41 msgid "Username" msgstr "Nume de utilizator" -#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:53 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 msgid "Password" msgstr "Parolă" -#: mediagoblin/auth/forms.py:35 -msgid "Passwords must match." -msgstr "Parolele trebuie să fie identice." - -#: mediagoblin/auth/forms.py:37 -msgid "Confirm password" -msgstr "Reintrodu parola" - -#: mediagoblin/auth/forms.py:39 -msgid "Type it again here to make sure there are no spelling mistakes." -msgstr "Introdu parola din nou pentru verificare." - -#: mediagoblin/auth/forms.py:42 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "Adresa de e-mail" @@ -60,7 +48,7 @@ msgstr "Ne pare rău, există deja un utilizator cu același nume." msgid "Sorry, a user with that email address already exists." msgstr "Există deja un utilizator înregistrat cu această adresă de e-mail." -#: mediagoblin/auth/views.py:179 +#: mediagoblin/auth/views.py:180 msgid "" "Your email address has been verified. You may now login, edit your profile, " "and submit images!" @@ -68,23 +56,28 @@ msgstr "" "Adresa ta de e-mail a fost verificată. Poți să te autentifici, să îți " "completezi profilul și să trimiți imagini!" -#: mediagoblin/auth/views.py:185 +#: mediagoblin/auth/views.py:186 msgid "The verification key or user id is incorrect" msgstr "Cheie de verificare sau user ID incorect." -#: mediagoblin/auth/views.py:203 +#: mediagoblin/auth/views.py:204 msgid "You must be logged in so we know who to send the email to!" msgstr "Trebuie să fii autentificat ca să știm cui să trimitem mesajul!" -#: mediagoblin/auth/views.py:211 +#: mediagoblin/auth/views.py:212 msgid "You've already verified your email address!" msgstr "Adresa ta de e-mail a fost deja verificată!" -#: mediagoblin/auth/views.py:224 +#: mediagoblin/auth/views.py:225 msgid "Resent your verification email." msgstr "E-mail-ul de verificare a fost retrimis." -#: mediagoblin/auth/views.py:265 +#: mediagoblin/auth/views.py:260 +msgid "" +"An email has been sent with instructions on how to change your password." +msgstr "" + +#: mediagoblin/auth/views.py:270 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." @@ -92,48 +85,77 @@ msgstr "" "E-mailul pentru recuperarea parolei nu a putut fi trimis deoarece contul tău" " e inactiv sau adresa ta de e-mail nu a fost verificată." +#: mediagoblin/auth/views.py:282 +msgid "Couldn't find someone with that username or email." +msgstr "" + +#: mediagoblin/auth/views.py:330 +msgid "You can now log in using your new password." +msgstr "" + #: mediagoblin/edit/forms.py:24 mediagoblin/submit/forms.py:27 msgid "Title" msgstr "Titlu" -#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:27 mediagoblin/submit/forms.py:30 +msgid "Description of this work" +msgstr "Descrierea acestui fișier" + +#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:31 +msgid "" +"You can use\n" +" \n" +" Markdown for formatting." +msgstr "" + +#: mediagoblin/edit/forms.py:32 mediagoblin/submit/forms.py:35 msgid "Tags" msgstr "Tag-uri" -#: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 -msgid "Seperate tags by commas." -msgstr "Desparte tag-urile prin virgulă." +#: mediagoblin/edit/forms.py:34 mediagoblin/submit/forms.py:37 +msgid "Separate tags by commas." +msgstr "" -#: mediagoblin/edit/forms.py:33 +#: mediagoblin/edit/forms.py:37 msgid "Slug" msgstr "Identificator" -#: mediagoblin/edit/forms.py:34 +#: mediagoblin/edit/forms.py:38 msgid "The slug can't be empty" msgstr "Identificatorul nu poate să lipsească" -#: mediagoblin/edit/forms.py:35 +#: mediagoblin/edit/forms.py:39 msgid "" -"The title part of this media's URL. You usually don't need to change this." +"The title part of this media's address. You usually don't need to change " +"this." msgstr "" -"Partea din adresa acestui fișier corespunzătoare titlului. De regulă nu " -"trebuie modificată." -#: mediagoblin/edit/forms.py:42 +#: mediagoblin/edit/forms.py:46 msgid "Bio" msgstr "Biografie" -#: mediagoblin/edit/forms.py:45 +#: mediagoblin/edit/forms.py:48 +msgid "" +"You can use\n" +" \n" +" Markdown for formatting." +msgstr "" + +#: mediagoblin/edit/forms.py:53 msgid "Website" msgstr "Sit Web" -#: mediagoblin/edit/forms.py:49 +#: mediagoblin/edit/forms.py:60 msgid "Old password" msgstr "Vechea parolă" -#: mediagoblin/edit/forms.py:52 -msgid "New Password" -msgstr "Noua parolă" +#: mediagoblin/edit/forms.py:62 +msgid "Enter your old password to prove you own this account." +msgstr "" + +#: mediagoblin/edit/forms.py:65 +msgid "New password" +msgstr "" #: mediagoblin/edit/views.py:65 msgid "An entry with that slug already exists for this user." @@ -148,39 +170,43 @@ msgstr "Editezi fișierul unui alt utilizator. Se recomandă prudență." msgid "You are editing a user's profile. Proceed with caution." msgstr "Editezi profilul unui utilizator. Se recomandă prudență." -#: mediagoblin/edit/views.py:171 +#: mediagoblin/edit/views.py:174 +msgid "Profile changes saved" +msgstr "" + +#: mediagoblin/edit/views.py:200 msgid "Wrong password" msgstr "Parolă incorectă" -#: mediagoblin/edit/views.py:192 -msgid "Profile edited!" -msgstr "Profilul a fost modificat!" +#: mediagoblin/edit/views.py:216 +msgid "Account settings saved" +msgstr "" -#: mediagoblin/media_types/__init__.py:65 -msgid "Could not find any file extension in \"{filename}\"" -msgstr "Nu pot extrage extensia din „{filename}”" +#: mediagoblin/media_types/__init__.py:77 +msgid "Could not extract any file extension from \"{filename}\"" +msgstr "" + +#: mediagoblin/media_types/__init__.py:88 +msgid "Sorry, I don't support that file type :(" +msgstr "" #: mediagoblin/submit/forms.py:25 msgid "File" msgstr "Fișier" -#: mediagoblin/submit/forms.py:30 -msgid "Description of this work" -msgstr "Descrierea acestui fișier" - -#: mediagoblin/submit/views.py:49 +#: mediagoblin/submit/views.py:50 msgid "You must provide a file." msgstr "Trebuie să selectezi un fișier." -#: mediagoblin/submit/views.py:127 +#: mediagoblin/submit/views.py:128 msgid "Woohoo! Submitted!" msgstr "Ura! Trimis!" -#: mediagoblin/submit/views.py:133 -msgid "Invalid file type." -msgstr "Tip de fișier incompatibil." +#: mediagoblin/templates/mediagoblin/404.html:22 +msgid "Image of 404 goblin stressing out" +msgstr "Imagine cu elful 404 stresat." -#: mediagoblin/templates/mediagoblin/404.html:21 +#: mediagoblin/templates/mediagoblin/404.html:23 msgid "Oops!" msgstr "Hopa!" @@ -196,33 +222,30 @@ msgstr "" "Dacă ești sigur că adresa e corectă, poate că pagina pe care o cauți a fost " "mutată sau ștearsă." -#: mediagoblin/templates/mediagoblin/404.html:32 -msgid "Image of 404 goblin stressing out" -msgstr "Imagine cu elful 404 stresat." - -#: mediagoblin/templates/mediagoblin/base.html:49 +#: mediagoblin/templates/mediagoblin/base.html:48 msgid "MediaGoblin logo" msgstr "logo MediaGoblin" -#: mediagoblin/templates/mediagoblin/base.html:54 -msgid "Submit media" -msgstr "Transmite un fișier media" +#: mediagoblin/templates/mediagoblin/base.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:157 +msgid "Add media" +msgstr "Trimite fișier" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:64 msgid "Verify your email!" msgstr "Verifică adresa de e-mail!" -#: mediagoblin/templates/mediagoblin/base.html:72 +#: mediagoblin/templates/mediagoblin/base.html:71 msgid "log out" msgstr "ieșire" -#: mediagoblin/templates/mediagoblin/base.html:75 +#: mediagoblin/templates/mediagoblin/base.html:74 #: mediagoblin/templates/mediagoblin/auth/login.html:27 #: mediagoblin/templates/mediagoblin/auth/login.html:45 msgid "Log in" msgstr "Autentificare" -#: mediagoblin/templates/mediagoblin/base.html:91 +#: mediagoblin/templates/mediagoblin/base.html:86 msgid "" "Powered by MediaGoblin, a GNU project" @@ -234,7 +257,7 @@ msgstr "" msgid "Explore" msgstr "Explorează" -#: mediagoblin/templates/mediagoblin/root.html:27 +#: mediagoblin/templates/mediagoblin/root.html:26 msgid "Hi there, welcome to this MediaGoblin site!" msgstr "Salut, bine ai venit pe acest site MediaGoblin!" @@ -262,25 +285,21 @@ msgstr "Încă nu ai unul? E simplu!" #, python-format msgid "" "Create an account at this site\n" -" or\n" -" Set up MediaGoblin on your own server" +" or\n" +" Set up MediaGoblin on your own server" msgstr "" -"Creează un cont pe acest site\n" -" sau\n" -" Instalează MediaGoblin pe propriul tău server" -#: mediagoblin/templates/mediagoblin/root.html:44 +#: mediagoblin/templates/mediagoblin/root.html:40 msgid "Most recent media" msgstr "Cele mai recente fișiere" -#: mediagoblin/templates/mediagoblin/auth/change_fp.html:29 -msgid "Enter your new password" -msgstr "Introdu noua parolă" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:32 +msgid "Set your new password" +msgstr "" -#: mediagoblin/templates/mediagoblin/auth/change_fp.html:33 -#: mediagoblin/templates/mediagoblin/submit/start.html:30 -msgid "Submit" -msgstr "Trimite" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:35 +msgid "Set password" +msgstr "" #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" @@ -290,17 +309,6 @@ msgstr "Recuperează parola" msgid "Send instructions" msgstr "Trimite instrucțiuni" -#: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 -msgid "Your password has been changed. Try to log in now." -msgstr "Parola a fost schimbată. Încearcă să te autentifici acum." - -#: mediagoblin/templates/mediagoblin/auth/fp_email_sent.html:22 -msgid "" -"Check your inbox. We sent an email with a URL for changing your password." -msgstr "" -"Verifică-ți căsuța de e-mail. Ți-am trimis un mesaj cu link-ul pentru " -"schimbarea parolei." - #: mediagoblin/templates/mediagoblin/auth/fp_verification_email.txt:19 #, python-format msgid "" @@ -338,11 +346,11 @@ msgstr "Creează-l aici!" msgid "Forgot your password?" msgstr "Ai uitat parola?" -#: mediagoblin/templates/mediagoblin/auth/register.html:27 +#: mediagoblin/templates/mediagoblin/auth/register.html:32 msgid "Create an account!" msgstr "Creează un cont!" -#: mediagoblin/templates/mediagoblin/auth/register.html:31 +#: mediagoblin/templates/mediagoblin/auth/register.html:36 msgid "Create" msgstr "Creează" @@ -373,10 +381,16 @@ msgid "Cancel" msgstr "Anulare" #: mediagoblin/templates/mediagoblin/edit/edit.html:37 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:40 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:35 msgid "Save changes" msgstr "Salvează modificările" +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:34 +#, python-format +msgid "Changing %(username)s's account settings" +msgstr "" + #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29 #, python-format msgid "Editing %(username)s's profile" @@ -388,13 +402,32 @@ msgstr "Editare profil %(username)s" msgid "Media tagged with: %(tag_name)s" msgstr "Fișier etichetat cu tag-urile: %(tag_name)s" -#: mediagoblin/templates/mediagoblin/media_displays/video.html:19 +#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 +#: mediagoblin/templates/mediagoblin/media_displays/video.html:46 msgid "Original" msgstr "Original" +#: mediagoblin/templates/mediagoblin/media_displays/video.html:33 +msgid "" +"Sorry, this video will not work because \n" +"\t your web browser does not support HTML5 \n" +"\t video." +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:36 +msgid "" +"You can get a modern web browser that \n" +"\t can play this video at \n" +"\t http://getfirefox.com!" +msgstr "" + #: mediagoblin/templates/mediagoblin/submit/start.html:26 -msgid "Submit yer media" -msgstr "Trimite fișierele tale media" +msgid "Add your media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Add" +msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format @@ -406,31 +439,57 @@ msgstr "Fișierele lui %(username)s" msgid "%(username)s's media" msgstr "Fișierele media ale lui %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:57 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:60 #, python-format -msgid "By %(username)s on %(date)s" -msgstr "De %(username)s la %(date)s" +msgid "Added on %(date)s." +msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:67 -msgid "Post a comment" -msgstr "Scrie un comentariu" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:85 -msgid "at" -msgstr "la" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 -msgid "Post comment!" -msgstr "Trimite comentariul" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:124 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:69 msgid "Edit" msgstr "Editare" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:130 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:73 msgid "Delete" msgstr "Șterge" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:79 +#, python-format +msgid "%(comment_count)s comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:81 +#, python-format +msgid "%(comment_count)s comments" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:83 +msgid "No comments yet." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:91 +msgid "Add one" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:100 +msgid "" +"Type your comment here. You can use Markdown for" +" formatting." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 +msgid "Add this comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:126 +msgid "at" +msgstr "la" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:141 +#, python-format +msgid "

❖ Browsing media by %(username)s

" +msgstr "" + #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -515,20 +574,24 @@ msgid "Here's a spot to tell others about yourself." msgstr "Aici poți spune altora ceva despre tine." #: mediagoblin/templates/mediagoblin/user_pages/user.html:101 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:119 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:118 msgid "Edit profile" msgstr "Editare profil" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:107 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:106 msgid "This user hasn't filled in their profile (yet)." msgstr "Acest utilizator nu și-a completat (încă) profilul." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:133 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:125 +msgid "Change account settings" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:138 #, python-format msgid "View all of %(username)s's media" msgstr "Vezi toate fișierele media ale lui %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:146 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:151 msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." @@ -536,11 +599,8 @@ msgstr "" "Aici vor apărea fișierele tale media, dar se pare că încă nu ai trimis " "nimic." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:152 -msgid "Add media" -msgstr "Trimite fișier" - -#: mediagoblin/templates/mediagoblin/user_pages/user.html:158 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:163 +#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72 msgid "There doesn't seem to be any media here yet..." msgstr "Nu pare să existe niciun fișier media deocamdată..." @@ -552,29 +612,35 @@ msgstr "icon feed" msgid "Atom feed" msgstr "feed Atom" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:40 -msgid "Newer" -msgstr "Mai noi" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:39 +msgid "← Newer" +msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:46 -msgid "Older" -msgstr "Mai vechi" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:45 +msgid "Older →" +msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:50 +#: mediagoblin/templates/mediagoblin/utils/pagination.html:48 msgid "Go to page:" msgstr "Salt la pagina:" +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:27 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:32 +msgid "newer" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:38 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:43 +msgid "older" +msgstr "" + #: mediagoblin/templates/mediagoblin/utils/tags.html:20 -msgid "Tagged with" -msgstr "Tag-uri" +msgid "View more media tagged with" +msgstr "" #: mediagoblin/templates/mediagoblin/utils/tags.html:25 -msgid "and" -msgstr "și" - -#: mediagoblin/user_pages/forms.py:24 -msgid "Comment" -msgstr "Scrie un comentariu" +msgid "or" +msgstr "" #: mediagoblin/user_pages/forms.py:30 msgid "I am sure I want to delete this" diff --git a/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.mo index 7e62de833735c4958ffc9e0b1597f4c2732596b4..3ddb0c8eb3322f603a92ddba3134215115322913 100644 GIT binary patch delta 5116 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 diff --git a/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.po index 098ea38c..38748a97 100644 --- a/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.po @@ -1,5 +1,5 @@ # Translations template for PROJECT. -# Copyright (C) 2011 ORGANIZATION +# Copyright (C) 2012 ORGANIZATION # This file is distributed under the same license as the PROJECT project. # # Translators: @@ -8,9 +8,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-12-04 10:24-0600\n" -"PO-Revision-Date: 2011-12-04 19:58+0000\n" -"Last-Translator: aleksejrs \n" +"POT-Creation-Date: 2012-01-07 13:47-0600\n" +"PO-Revision-Date: 2012-01-07 19:44+0000\n" +"Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -23,27 +23,15 @@ msgstr "" msgid "Invalid file given for media type." msgstr "Неправильный формат файла." -#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 +#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41 msgid "Username" msgstr "Логин" -#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:53 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 msgid "Password" msgstr "Пароль" -#: mediagoblin/auth/forms.py:35 -msgid "Passwords must match." -msgstr "Пароли должны совпадать." - -#: mediagoblin/auth/forms.py:37 -msgid "Confirm password" -msgstr "Подтвердите пароль" - -#: mediagoblin/auth/forms.py:39 -msgid "Type it again here to make sure there are no spelling mistakes." -msgstr "Наберите его ещё раз здесь, чтобы избежать опечаток." - -#: mediagoblin/auth/forms.py:42 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "Адрес электронной почты" @@ -61,7 +49,7 @@ msgstr "" "Сожалеем, но на этот адрес электронной почты уже зарегистрирована другая " "учётная запись." -#: mediagoblin/auth/views.py:179 +#: mediagoblin/auth/views.py:180 msgid "" "Your email address has been verified. You may now login, edit your profile, " "and submit images!" @@ -69,23 +57,28 @@ msgstr "" "Адрес вашей электронной потвержден. Вы теперь можете войти и начать " "редактировать свой профиль и загружать новые изображения!" -#: mediagoblin/auth/views.py:185 +#: mediagoblin/auth/views.py:186 msgid "The verification key or user id is incorrect" msgstr "Неверный ключ проверки или идентификатор пользователя" -#: mediagoblin/auth/views.py:203 +#: mediagoblin/auth/views.py:204 msgid "You must be logged in so we know who to send the email to!" msgstr "Вам надо представиться, чтобы мы знали, кому отправлять сообщение!" -#: mediagoblin/auth/views.py:211 +#: mediagoblin/auth/views.py:212 msgid "You've already verified your email address!" msgstr "Вы уже потвердили свой адрес электронной почты!" -#: mediagoblin/auth/views.py:224 +#: mediagoblin/auth/views.py:225 msgid "Resent your verification email." msgstr "Переслать сообщение с подтверждением аккаунта." -#: mediagoblin/auth/views.py:265 +#: mediagoblin/auth/views.py:260 +msgid "" +"An email has been sent with instructions on how to change your password." +msgstr "" + +#: mediagoblin/auth/views.py:270 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." @@ -94,48 +87,77 @@ msgstr "" "учётная запись неактивна, либо указанный в ней адрес электронной почты не " "был подтверждён." +#: mediagoblin/auth/views.py:282 +msgid "Couldn't find someone with that username or email." +msgstr "" + +#: mediagoblin/auth/views.py:330 +msgid "You can now log in using your new password." +msgstr "" + #: mediagoblin/edit/forms.py:24 mediagoblin/submit/forms.py:27 msgid "Title" msgstr "Название" -#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:27 mediagoblin/submit/forms.py:30 +msgid "Description of this work" +msgstr "Описание этого произведения" + +#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:31 +msgid "" +"You can use\n" +" \n" +" Markdown for formatting." +msgstr "" + +#: mediagoblin/edit/forms.py:32 mediagoblin/submit/forms.py:35 msgid "Tags" msgstr "Метки" -#: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 -msgid "Seperate tags by commas." -msgstr "Разделяйте метки запятыми." +#: mediagoblin/edit/forms.py:34 mediagoblin/submit/forms.py:37 +msgid "Separate tags by commas." +msgstr "" -#: mediagoblin/edit/forms.py:33 +#: mediagoblin/edit/forms.py:37 msgid "Slug" msgstr "Отличительная часть адреса" -#: mediagoblin/edit/forms.py:34 +#: mediagoblin/edit/forms.py:38 msgid "The slug can't be empty" msgstr "Отличительная часть адреса необходима" -#: mediagoblin/edit/forms.py:35 +#: mediagoblin/edit/forms.py:39 msgid "" -"The title part of this media's URL. You usually don't need to change this." +"The title part of this media's address. You usually don't need to change " +"this." msgstr "" -"Часть адреса этого файла, производная от его названия. Её обычно не нужно " -"изменять." -#: mediagoblin/edit/forms.py:42 +#: mediagoblin/edit/forms.py:46 msgid "Bio" msgstr "Биография" -#: mediagoblin/edit/forms.py:45 +#: mediagoblin/edit/forms.py:48 +msgid "" +"You can use\n" +" \n" +" Markdown for formatting." +msgstr "" + +#: mediagoblin/edit/forms.py:53 msgid "Website" msgstr "Сайт" -#: mediagoblin/edit/forms.py:49 +#: mediagoblin/edit/forms.py:60 msgid "Old password" msgstr "Старый пароль" -#: mediagoblin/edit/forms.py:52 -msgid "New Password" -msgstr "Новый пароль" +#: mediagoblin/edit/forms.py:62 +msgid "Enter your old password to prove you own this account." +msgstr "" + +#: mediagoblin/edit/forms.py:65 +msgid "New password" +msgstr "" #: mediagoblin/edit/views.py:65 msgid "An entry with that slug already exists for this user." @@ -150,39 +172,43 @@ msgstr "Вы редактируете файлы другого пользова msgid "You are editing a user's profile. Proceed with caution." msgstr "Вы редактируете профиль пользователя. Будьте осторожны." -#: mediagoblin/edit/views.py:171 +#: mediagoblin/edit/views.py:174 +msgid "Profile changes saved" +msgstr "" + +#: mediagoblin/edit/views.py:200 msgid "Wrong password" msgstr "Неправильный пароль" -#: mediagoblin/edit/views.py:192 -msgid "Profile edited!" -msgstr "Профиль изменён!" +#: mediagoblin/edit/views.py:216 +msgid "Account settings saved" +msgstr "" -#: mediagoblin/media_types/__init__.py:65 -msgid "Could not find any file extension in \"{filename}\"" -msgstr "В «{filename}» не обнаружено расширение имени файла" +#: mediagoblin/media_types/__init__.py:77 +msgid "Could not extract any file extension from \"{filename}\"" +msgstr "" + +#: mediagoblin/media_types/__init__.py:88 +msgid "Sorry, I don't support that file type :(" +msgstr "" #: mediagoblin/submit/forms.py:25 msgid "File" msgstr "Файл" -#: mediagoblin/submit/forms.py:30 -msgid "Description of this work" -msgstr "Описание этого произведения" - -#: mediagoblin/submit/views.py:49 +#: mediagoblin/submit/views.py:50 msgid "You must provide a file." msgstr "Вы должны загрузить файл." -#: mediagoblin/submit/views.py:127 +#: mediagoblin/submit/views.py:128 msgid "Woohoo! Submitted!" msgstr "Ура! Файл загружен!" -#: mediagoblin/submit/views.py:133 -msgid "Invalid file type." -msgstr "Неподходящий тип файла." +#: mediagoblin/templates/mediagoblin/404.html:22 +msgid "Image of 404 goblin stressing out" +msgstr "Изображение 404 нервничающего гоблина" -#: mediagoblin/templates/mediagoblin/404.html:21 +#: mediagoblin/templates/mediagoblin/404.html:23 msgid "Oops!" msgstr "Ой!" @@ -196,33 +222,30 @@ msgid "" " been moved or deleted." msgstr "Возможно, страница, которую вы ищете, была удалена или переехала." -#: mediagoblin/templates/mediagoblin/404.html:32 -msgid "Image of 404 goblin stressing out" -msgstr "Изображение 404 нервничающего гоблина" - -#: mediagoblin/templates/mediagoblin/base.html:49 +#: mediagoblin/templates/mediagoblin/base.html:48 msgid "MediaGoblin logo" msgstr "Символ MediaGoblin" -#: mediagoblin/templates/mediagoblin/base.html:54 -msgid "Submit media" -msgstr "Загрузить файл" +#: mediagoblin/templates/mediagoblin/base.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:157 +msgid "Add media" +msgstr "Добавить файлы" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:64 msgid "Verify your email!" msgstr "Подтвердите ваш адрес электронной почты!" -#: mediagoblin/templates/mediagoblin/base.html:72 +#: mediagoblin/templates/mediagoblin/base.html:71 msgid "log out" msgstr "завершение сеанса" -#: mediagoblin/templates/mediagoblin/base.html:75 +#: mediagoblin/templates/mediagoblin/base.html:74 #: mediagoblin/templates/mediagoblin/auth/login.html:27 #: mediagoblin/templates/mediagoblin/auth/login.html:45 msgid "Log in" msgstr "Войти" -#: mediagoblin/templates/mediagoblin/base.html:91 +#: mediagoblin/templates/mediagoblin/base.html:86 msgid "" "Powered by MediaGoblin, a GNU project" @@ -234,7 +257,7 @@ msgstr "" msgid "Explore" msgstr "Смотреть" -#: mediagoblin/templates/mediagoblin/root.html:27 +#: mediagoblin/templates/mediagoblin/root.html:26 msgid "Hi there, welcome to this MediaGoblin site!" msgstr "Привет! Добро пожаловать на наш MediaGoblin’овый сайт!" @@ -263,25 +286,21 @@ msgstr "У вас её ещё нет? Не проблема!" #, python-format msgid "" "Create an account at this site\n" -" or\n" -" Set up MediaGoblin on your own server" +" or\n" +" Set up MediaGoblin on your own server" msgstr "" -"Создайте учётную запись на этом сайте\n" -" или\n" -" Установите MediaGoblin на собственный сервер" -#: mediagoblin/templates/mediagoblin/root.html:44 +#: mediagoblin/templates/mediagoblin/root.html:40 msgid "Most recent media" msgstr "Самые новые файлы" -#: mediagoblin/templates/mediagoblin/auth/change_fp.html:29 -msgid "Enter your new password" -msgstr "Введите свой новый пароль" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:32 +msgid "Set your new password" +msgstr "" -#: mediagoblin/templates/mediagoblin/auth/change_fp.html:33 -#: mediagoblin/templates/mediagoblin/submit/start.html:30 -msgid "Submit" -msgstr "Подтвердить" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:35 +msgid "Set password" +msgstr "" #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" @@ -291,17 +310,6 @@ msgstr "Сброс пароля" msgid "Send instructions" msgstr "Отправить инструкцию" -#: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 -msgid "Your password has been changed. Try to log in now." -msgstr "Ваш пароль изменён. Теперь попробуйте представиться." - -#: mediagoblin/templates/mediagoblin/auth/fp_email_sent.html:22 -msgid "" -"Check your inbox. We sent an email with a URL for changing your password." -msgstr "" -"Проверьте свой электронный почтовый ящик. Мы отправили сообщение с адресом " -"для изменения Вашего пароля." - #: mediagoblin/templates/mediagoblin/auth/fp_verification_email.txt:19 #, python-format msgid "" @@ -341,11 +349,11 @@ msgstr "Создайте здесь!" msgid "Forgot your password?" msgstr "Забыли свой пароль?" -#: mediagoblin/templates/mediagoblin/auth/register.html:27 +#: mediagoblin/templates/mediagoblin/auth/register.html:32 msgid "Create an account!" msgstr "Создать аккаунт!" -#: mediagoblin/templates/mediagoblin/auth/register.html:31 +#: mediagoblin/templates/mediagoblin/auth/register.html:36 msgid "Create" msgstr "Создать" @@ -376,10 +384,16 @@ msgid "Cancel" msgstr "Отменить" #: mediagoblin/templates/mediagoblin/edit/edit.html:37 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:40 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:35 msgid "Save changes" msgstr "Сохранить изменения" +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:34 +#, python-format +msgid "Changing %(username)s's account settings" +msgstr "" + #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29 #, python-format msgid "Editing %(username)s's profile" @@ -391,13 +405,32 @@ msgstr "Редактирование профиля %(username)s" msgid "Media tagged with: %(tag_name)s" msgstr "Файлы с меткой: %(tag_name)s" -#: mediagoblin/templates/mediagoblin/media_displays/video.html:19 +#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 +#: mediagoblin/templates/mediagoblin/media_displays/video.html:46 msgid "Original" msgstr "Оригинал" +#: mediagoblin/templates/mediagoblin/media_displays/video.html:33 +msgid "" +"Sorry, this video will not work because \n" +"\t your web browser does not support HTML5 \n" +"\t video." +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:36 +msgid "" +"You can get a modern web browser that \n" +"\t can play this video at \n" +"\t http://getfirefox.com!" +msgstr "" + #: mediagoblin/templates/mediagoblin/submit/start.html:26 -msgid "Submit yer media" -msgstr "Загрузить файл(ы)" +msgid "Add your media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Add" +msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format @@ -409,31 +442,57 @@ msgstr "Файлы %(username)s" msgid "%(username)s's media" msgstr "Файлы пользователя %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:57 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:60 #, python-format -msgid "By %(username)s on %(date)s" -msgstr "Загружено %(username)s %(date)s" +msgid "Added on %(date)s." +msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:67 -msgid "Post a comment" -msgstr "Оставить комментарий" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:85 -msgid "at" -msgstr "в" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 -msgid "Post comment!" -msgstr "Разместить комментарий!" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:124 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:69 msgid "Edit" msgstr "Изменить" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:130 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:73 msgid "Delete" msgstr "Удалить" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:79 +#, python-format +msgid "%(comment_count)s comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:81 +#, python-format +msgid "%(comment_count)s comments" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:83 +msgid "No comments yet." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:91 +msgid "Add one" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:100 +msgid "" +"Type your comment here. You can use Markdown for" +" formatting." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 +msgid "Add this comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:126 +msgid "at" +msgstr "в" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:141 +#, python-format +msgid "

❖ Browsing media by %(username)s

" +msgstr "" + #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -520,30 +579,31 @@ msgid "Here's a spot to tell others about yourself." msgstr "Здесь вы можете рассказать о себе." #: mediagoblin/templates/mediagoblin/user_pages/user.html:101 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:119 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:118 msgid "Edit profile" msgstr "Редактировать профиль" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:107 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:106 msgid "This user hasn't filled in their profile (yet)." msgstr "Это пользователь не заполнил свой профайл (пока)." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:133 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:125 +msgid "Change account settings" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:138 #, python-format msgid "View all of %(username)s's media" msgstr "Смотреть все файлы %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:146 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:151 msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." msgstr "Ваши файлы появятся здесь, когда вы их добавите." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:152 -msgid "Add media" -msgstr "Добавить файлы" - -#: mediagoblin/templates/mediagoblin/user_pages/user.html:158 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:163 +#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72 msgid "There doesn't seem to be any media here yet..." msgstr "Пока что тут файлов нет…" @@ -555,29 +615,35 @@ msgstr "значок ленты" msgid "Atom feed" msgstr "лента в формате Atom" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:40 -msgid "Newer" -msgstr "Более новые" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:39 +msgid "← Newer" +msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:46 -msgid "Older" -msgstr "Более старые" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:45 +msgid "Older →" +msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:50 +#: mediagoblin/templates/mediagoblin/utils/pagination.html:48 msgid "Go to page:" msgstr "Перейти к странице:" +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:27 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:32 +msgid "newer" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:38 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:43 +msgid "older" +msgstr "" + #: mediagoblin/templates/mediagoblin/utils/tags.html:20 -msgid "Tagged with" -msgstr "Метки:" +msgid "View more media tagged with" +msgstr "" #: mediagoblin/templates/mediagoblin/utils/tags.html:25 -msgid "and" -msgstr "и" - -#: mediagoblin/user_pages/forms.py:24 -msgid "Comment" -msgstr "Комментарий" +msgid "or" +msgstr "" #: mediagoblin/user_pages/forms.py:30 msgid "I am sure I want to delete this" diff --git a/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.mo index 5ab7befa15e400d1a9754a72ea90210648fec115..2d3f505f38f516dc2fab1b7258ad20919df19b9e 100644 GIT binary patch delta 5788 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 gS delta 4182 zcmaLYeQcH09l-I^0+x3u6sTb3l-kmk_Vxv+P(WTGup?pwy`Ph{ARn{*8>Ow$D^*K7Ii^updY8 zUgQNeZQu|h{roIQ4Vj3^Tui;eu3C_kxa0&CPCrcfEgL8QB0bYoo z6gn^%y=7tTCq)kjhKeGBC%9zq#-93>KGu@e7+tfA024d(Dr`Y%LjZ$@dq6i217 zi9!wbAjhYyl0zsv4UomEJ5VBY9}eO}$Xse3vr5R9BTZ@@N(8r~EHI8T@vX=|^-X?B z{~uNoe+lVRG+c|PP?Dya?YH0#lry{uJMcRw5qTD6z!y;_d<*3$-bWelpZGca1ef6D zgzYN44rSbj@lyQlLgF8zFozV^xDof@b@&y09NTa;VUS40F+c}5<5`r5)ev9iQVpna zJxb2(FSYlhL@>f0JdCn{XGbY)pdib<0yZK|>M(ZWQIt@3J2akO?nA*+3&oBob(08f5`5qKx+jUWR|h2e6Sl$@5Y5D+(OD`ZaPa>K&A`{ClZh zP6iQWwYX#pHc{V(GGPj3f(QwYx(!?L0hDpipzQQ)>3O*>j=vNyko(_2K{~dgoZ)6% zhP&}DbWtMoF*Z}5#vQH2cDx05;}E`r>v3~kG3$p>j^=)pg*}gwwC|#9=tHbwepSKp zh`y>v+SC@5tWKa@qX;D;-#|Ibqgam*q73*PN+e!INz%8GwWvR$9Km!tOZx(pd8$!1 zyc$Pk$CpzG@r$JgFQBIWHcHm2hGGckAx&xxO8b74BXdyWA(WkdANS+Wu?H(x7IS1T z%F*0|8}aFt#9vnaFB)XW(;ACMuoz`$O(@U1a4T-c7QCfYe-zhI{{SWQO(cd)5HEQT z?xg-S-iq@$ze~~J1$d^J_~$6RM1!m}*1oeGbjVUiL-DKvvUDdEy{u~!(QBp zGVr~)7N5tmOsPs=J;1CE^qO2p1rVawrd|e_wMoXxm{CcZ+Ej+%1IPnG98s>?yl0LYKMK$_RZPKW;1KSx{gw7 zpwm$h>a-Qc2V-iNN7>Tx(&`G;Ql-{xUEo&`sL)Q-no|qDy2$nkjt;GXK=%(9-m!w1 z8C__bo~lZ7an=28QGePARbPQ(kS8m{wqI)4V+{=0i9*~=^`gU5h}`i97sbohJFH~D za$G%V`%L4p#w5{>q*7?ID7l^vGIlB@Ax=9%NSDAIs@`l~uYS+?OM8z$yKH{h)nAem zn+&lYv{VVDKoVe#IdFVxFPb=+AImb{>64bJS-yH{Ln_?B0i`&; zO)Ca%D`ERL1cd;bf#r4AHw=Uu_6^J1&cu(|HUa=TDqIVu$i}n-Xel(F|kE$=}xx_LR4e7wqcB@3v%jQq$AU^2lb8a$<>1|$0hmIbxf|TXvbEFJU zvX%}C_tZ-ytq~T>p7aQ}GSb9vXwW0^=pR#8d)wu%=5s#xBh2~<39UTyxKjOIip=yT zPP+MHnz4rh9!{KetOVmQ%~-~xkkvu{M8D_T=CKux=G_&C&C$9QQy9mbs@q`7E_rLo zz7%8VfQcokvkX?4!7QwAxF~-_1|_aRSlm%J3(4Av5gkS*Q$Hwo#=KU4WR84w3cJx+ zPn$o~uQK0l*j?$`>?~mYS!;-!%B1f%+;jYnmDiLl-eDI*!AB+>&Xg7znO7R?Yp%&3 zOE|wZ@!Y)%PCs&?Q$$VGUz1=c^Fgs<%kJZ(wjW8 z|7xi<^P6v;r6YEeWv%12=4kU?bEdhzH>UQ=Dai3k9t@uw&2cAkp&upVEPiJq!DZAm zN7aW>w1^bE;*}mcrpmvQ8Ez^S#(mIQDZ* zJ3kdgHSq(P#@yW6R%I2^(qe0cKNr7z+w7RswELrk zc{5g5k(E%{u9@2QkLsNE0CD7-hKbUWSjT zYn#5#m7mdixU>E\n" +"POT-Creation-Date: 2012-01-07 13:47-0600\n" +"PO-Revision-Date: 2012-01-07 19:44+0000\n" +"Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -23,27 +23,15 @@ msgstr "" msgid "Invalid file given for media type." msgstr "Odovzdaný nesprávny súbor pre daný typ média." -#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 +#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41 msgid "Username" msgstr "Prihlasovacie meno" -#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:53 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 msgid "Password" msgstr "Heslo" -#: mediagoblin/auth/forms.py:35 -msgid "Passwords must match." -msgstr "Heslá sa musia zhodovať." - -#: mediagoblin/auth/forms.py:37 -msgid "Confirm password" -msgstr "Potvrdiť heslo" - -#: mediagoblin/auth/forms.py:39 -msgid "Type it again here to make sure there are no spelling mistakes." -msgstr "Prepíš ho sem opätovne kvôli uisteniu, že nedošlo k preklepu." - -#: mediagoblin/auth/forms.py:42 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "E-mailová adresa" @@ -59,7 +47,7 @@ msgstr "Prepáč, rovnaké prihlasovacie meno už niekto používa." msgid "Sorry, a user with that email address already exists." msgstr "Prepáč, používateľ s rovnakou e-mailovou adresou už existuje." -#: mediagoblin/auth/views.py:179 +#: mediagoblin/auth/views.py:180 msgid "" "Your email address has been verified. You may now login, edit your profile, " "and submit images!" @@ -67,70 +55,108 @@ msgstr "" "Tvoja e-mailová adresa bola úspešne overená. Môžeš sa hneď prihlásiť, " "upraviť svoj profil a vkladať výtvory! " -#: mediagoblin/auth/views.py:185 +#: mediagoblin/auth/views.py:186 msgid "The verification key or user id is incorrect" -msgstr "Nesprávny overovací kľúč alebo používateľské ID" +msgstr "Nesprávny overovací kľúč alebo používateľský identifikátor" -#: mediagoblin/auth/views.py:203 +#: mediagoblin/auth/views.py:204 msgid "You must be logged in so we know who to send the email to!" -msgstr "Aby sme ti mohli zaslať e-mail, je potrebné byť prihláseným!" +msgstr "" +"Aby sme ti mohli zaslať e-mailovú správu, je potrebné byť prihláseným!" -#: mediagoblin/auth/views.py:211 +#: mediagoblin/auth/views.py:212 msgid "You've already verified your email address!" msgstr "Tvoja e-mailová adresa už bola raz overená!" -#: mediagoblin/auth/views.py:224 +#: mediagoblin/auth/views.py:225 msgid "Resent your verification email." -msgstr "Opätovne zaslať overovaciu správu." +msgstr "Opätovne zaslať overovaciu správu na e-mail." -#: mediagoblin/auth/views.py:265 +#: mediagoblin/auth/views.py:260 +msgid "" +"An email has been sent with instructions on how to change your password." +msgstr "" + +#: mediagoblin/auth/views.py:270 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." msgstr "" -"Nebolo ti možné zaslať správu ohľadom obnovy hesla, nakoľko je tvoje " -"používateľské meno buď neaktívne alebo e-mailová adresa účtu neoverená." +"Nebolo ti možné zaslať e-mailovú správu ohľadom obnovy hesla, nakoľko je " +"tvoje používateľské meno buď neaktívne alebo e-mailová adresa účtu " +"neoverená." + +#: mediagoblin/auth/views.py:282 +msgid "Couldn't find someone with that username or email." +msgstr "" + +#: mediagoblin/auth/views.py:330 +msgid "You can now log in using your new password." +msgstr "" #: mediagoblin/edit/forms.py:24 mediagoblin/submit/forms.py:27 msgid "Title" msgstr "Nadpis" -#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:27 mediagoblin/submit/forms.py:30 +msgid "Description of this work" +msgstr "Charakteristika tohto diela" + +#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:31 +msgid "" +"You can use\n" +" \n" +" Markdown for formatting." +msgstr "" + +#: mediagoblin/edit/forms.py:32 mediagoblin/submit/forms.py:35 msgid "Tags" -msgstr "Štítky" +msgstr "Značky" -#: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 -msgid "Seperate tags by commas." -msgstr "Oddeľ štítky pomocou čiarky." +#: mediagoblin/edit/forms.py:34 mediagoblin/submit/forms.py:37 +msgid "Separate tags by commas." +msgstr "" -#: mediagoblin/edit/forms.py:33 +#: mediagoblin/edit/forms.py:37 msgid "Slug" msgstr "Unikátna časť adresy" -#: mediagoblin/edit/forms.py:34 +#: mediagoblin/edit/forms.py:38 msgid "The slug can't be empty" -msgstr "Unikátna časť adresy musí byť vyplnená" +msgstr "Unikátna časť adresy nesmie byť prázdna" -#: mediagoblin/edit/forms.py:35 +#: mediagoblin/edit/forms.py:39 msgid "" -"The title part of this media's URL. You usually don't need to change this." -msgstr "Titulná časť URL odkazu média. Zvyčajne to meniť nemusíš." +"The title part of this media's address. You usually don't need to change " +"this." +msgstr "" -#: mediagoblin/edit/forms.py:42 +#: mediagoblin/edit/forms.py:46 msgid "Bio" msgstr "Bio" -#: mediagoblin/edit/forms.py:45 +#: mediagoblin/edit/forms.py:48 +msgid "" +"You can use\n" +" \n" +" Markdown for formatting." +msgstr "" + +#: mediagoblin/edit/forms.py:53 msgid "Website" msgstr "Webstránka" -#: mediagoblin/edit/forms.py:49 +#: mediagoblin/edit/forms.py:60 msgid "Old password" msgstr "Staré heslo" -#: mediagoblin/edit/forms.py:52 -msgid "New Password" -msgstr "Nové heslo" +#: mediagoblin/edit/forms.py:62 +msgid "Enter your old password to prove you own this account." +msgstr "" + +#: mediagoblin/edit/forms.py:65 +msgid "New password" +msgstr "" #: mediagoblin/edit/views.py:65 msgid "An entry with that slug already exists for this user." @@ -138,45 +164,49 @@ msgstr "Položku s rovnakou unikátnou časťou adresy už niekde máš." #: mediagoblin/edit/views.py:86 msgid "You are editing another user's media. Proceed with caution." -msgstr "Upravuješ médiá niekoho iného. Pristupuj opatrne." +msgstr "Upravuješ médiá niekoho iného. Dbaj na to." #: mediagoblin/edit/views.py:156 msgid "You are editing a user's profile. Proceed with caution." -msgstr "Upravuješ používateľský profil. Pristupuj opatrne." +msgstr "Upravuješ používateľský profil. Dbaj na to." -#: mediagoblin/edit/views.py:171 +#: mediagoblin/edit/views.py:174 +msgid "Profile changes saved" +msgstr "" + +#: mediagoblin/edit/views.py:200 msgid "Wrong password" msgstr "Nesprávne heslo" -#: mediagoblin/edit/views.py:192 -msgid "Profile edited!" -msgstr "Profil upravený!" +#: mediagoblin/edit/views.py:216 +msgid "Account settings saved" +msgstr "" -#: mediagoblin/media_types/__init__.py:65 -msgid "Could not find any file extension in \"{filename}\"" -msgstr "Nebolo možné nájsť žiadnu príponu v súbore \"{filename}\"" +#: mediagoblin/media_types/__init__.py:77 +msgid "Could not extract any file extension from \"{filename}\"" +msgstr "" + +#: mediagoblin/media_types/__init__.py:88 +msgid "Sorry, I don't support that file type :(" +msgstr "" #: mediagoblin/submit/forms.py:25 msgid "File" msgstr "Súbor" -#: mediagoblin/submit/forms.py:30 -msgid "Description of this work" -msgstr "Charakteristika diela" - -#: mediagoblin/submit/views.py:49 +#: mediagoblin/submit/views.py:50 msgid "You must provide a file." -msgstr "Poskytni súbor." +msgstr "Musíš poskytnúť súbor." -#: mediagoblin/submit/views.py:127 +#: mediagoblin/submit/views.py:128 msgid "Woohoo! Submitted!" msgstr "Juchú! Úspešne vložené!" -#: mediagoblin/submit/views.py:133 -msgid "Invalid file type." -msgstr "Nesprávny typ súboru." +#: mediagoblin/templates/mediagoblin/404.html:22 +msgid "Image of 404 goblin stressing out" +msgstr "Obrázok stresujúceho goblina pri chybovom kóde č. 404" -#: mediagoblin/templates/mediagoblin/404.html:21 +#: mediagoblin/templates/mediagoblin/404.html:23 msgid "Oops!" msgstr "Ajaj!" @@ -192,33 +222,30 @@ msgstr "" "Ak vieš s istotou, že adresa je správna, tak najskôr bola hľadaná stánka " "presunutá alebo zmazaná." -#: mediagoblin/templates/mediagoblin/404.html:32 -msgid "Image of 404 goblin stressing out" -msgstr "Obrázok stresujúceho goblina pri chybovom kóde č. 404" - -#: mediagoblin/templates/mediagoblin/base.html:49 +#: mediagoblin/templates/mediagoblin/base.html:48 msgid "MediaGoblin logo" msgstr "MediaGoblin logo" -#: mediagoblin/templates/mediagoblin/base.html:54 -msgid "Submit media" -msgstr "Vložiť výtvor" +#: mediagoblin/templates/mediagoblin/base.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:157 +msgid "Add media" +msgstr "Pridať výtvor" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:64 msgid "Verify your email!" -msgstr "Over si e-mail!" +msgstr "Over si e-mailovú adresu!" -#: mediagoblin/templates/mediagoblin/base.html:72 +#: mediagoblin/templates/mediagoblin/base.html:71 msgid "log out" -msgstr "odhlásenie" +msgstr "odhlásiť sa" -#: mediagoblin/templates/mediagoblin/base.html:75 +#: mediagoblin/templates/mediagoblin/base.html:74 #: mediagoblin/templates/mediagoblin/auth/login.html:27 #: mediagoblin/templates/mediagoblin/auth/login.html:45 msgid "Log in" msgstr "Prihlásenie" -#: mediagoblin/templates/mediagoblin/base.html:91 +#: mediagoblin/templates/mediagoblin/base.html:86 msgid "" "Powered by MediaGoblin, a GNU project" @@ -230,7 +257,7 @@ msgstr "" msgid "Explore" msgstr "Preskúmať" -#: mediagoblin/templates/mediagoblin/root.html:27 +#: mediagoblin/templates/mediagoblin/root.html:26 msgid "Hi there, welcome to this MediaGoblin site!" msgstr "Ahoj, vitaj na tejto MediaGoblin stránke!" @@ -258,25 +285,21 @@ msgstr "Ešte žiaden nemáš? Je to jednoduché!" #, python-format msgid "" "Create an account at this site\n" -" or\n" -" Set up MediaGoblin on your own server" +" or\n" +" Set up MediaGoblin on your own server" msgstr "" -"<a class=\"header_submit_highlight\" href=\"%(register_url)s\">Vytvoriť bezplatný účet</a>\n" -" alebo\n" -" <a class=\"header_submit\" href=\"http://wiki.mediagoblin.org/HackingHowto\">Sprevádzkovať MediaGoblin na vlastnom serveri</a>" -#: mediagoblin/templates/mediagoblin/root.html:44 +#: mediagoblin/templates/mediagoblin/root.html:40 msgid "Most recent media" msgstr "Najčerstvejšie výtvory" -#: mediagoblin/templates/mediagoblin/auth/change_fp.html:29 -msgid "Enter your new password" -msgstr "Vlož svoje nové heslo" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:32 +msgid "Set your new password" +msgstr "" -#: mediagoblin/templates/mediagoblin/auth/change_fp.html:33 -#: mediagoblin/templates/mediagoblin/submit/start.html:30 -msgid "Submit" -msgstr "Vložiť" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:35 +msgid "Set password" +msgstr "" #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" @@ -284,18 +307,7 @@ msgstr "Obnoviť heslo" #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:30 msgid "Send instructions" -msgstr "Zaslať inštrukcie" - -#: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 -msgid "Your password has been changed. Try to log in now." -msgstr "Heslo ti bolo zmenené. Skús sa prihlásiť teraz." - -#: mediagoblin/templates/mediagoblin/auth/fp_email_sent.html:22 -msgid "" -"Check your inbox. We sent an email with a URL for changing your password." -msgstr "" -"Skontroluj si e-mailovú schránku. Bol ti zaslaná správa s URL odkazom pre " -"zmenu tvojho hesla." +msgstr "Zaslať postup" #: mediagoblin/templates/mediagoblin/auth/fp_verification_email.txt:19 #, python-format @@ -312,12 +324,11 @@ msgid "" msgstr "" "Ahoj %(username)s,\n" "\n" -"pre zmenu svojho hesla k GNU MediaGoblin účtu, otvor nasledujúci URL odkaz vo \n" -"svojom prehliadači:\n" +"pre zmenu svojho hesla k GNU MediaGoblin účtu, otvor nasledujúci odkaz vo svojom prehliadači:\n" "\n" "%(verification_url)s\n" "\n" -"Pokiaľ si myslíš, že došlo k omylu, tak jednoducho ignoruj túto správu a neprestávaj byť šťastným goblinom!" +"Pokiaľ si myslíš, že došlo k omylu, tak jednoducho ignoruj túto správu a buď šťastným goblinom!" #: mediagoblin/templates/mediagoblin/auth/login.html:30 msgid "Logging in failed!" @@ -329,17 +340,17 @@ msgstr "Ešte nemáš účet?" #: mediagoblin/templates/mediagoblin/auth/login.html:36 msgid "Create one here!" -msgstr "Vytvoriť jeden tu!" +msgstr "Vytvor si jeden tu!" #: mediagoblin/templates/mediagoblin/auth/login.html:42 msgid "Forgot your password?" msgstr "Zabudnuté heslo?" -#: mediagoblin/templates/mediagoblin/auth/register.html:27 +#: mediagoblin/templates/mediagoblin/auth/register.html:32 msgid "Create an account!" msgstr "Vytvoriť účet!" -#: mediagoblin/templates/mediagoblin/auth/register.html:31 +#: mediagoblin/templates/mediagoblin/auth/register.html:36 msgid "Create" msgstr "Vytvoriť" @@ -355,7 +366,7 @@ msgid "" msgstr "" "Ahoj %(username)s,\n" "\n" -"pre aktiváciu tvojho GNU MediaGoblin účtu, otvor nasledujúci URL odkaz vo\n" +"pre aktiváciu tvojho GNU MediaGoblin účtu, otvor nasledujúci odkaz vo\n" "svojom prehliadači:\n" "\n" "%(verification_url)s" @@ -371,10 +382,16 @@ msgid "Cancel" msgstr "Zrušiť" #: mediagoblin/templates/mediagoblin/edit/edit.html:37 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:40 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:35 msgid "Save changes" msgstr "Uložiť zmeny" +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:34 +#, python-format +msgid "Changing %(username)s's account settings" +msgstr "" + #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29 #, python-format msgid "Editing %(username)s's profile" @@ -384,51 +401,96 @@ msgstr "Úprava profilu, ktorý vlastní %(username)s" #: mediagoblin/templates/mediagoblin/listings/tag.html:35 #, python-format msgid "Media tagged with: %(tag_name)s" -msgstr "Výtvory označené s: %(tag_name)s" +msgstr "Výtvory označené ako: %(tag_name)s" -#: mediagoblin/templates/mediagoblin/media_displays/video.html:19 +#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 +#: mediagoblin/templates/mediagoblin/media_displays/video.html:46 msgid "Original" msgstr "Originál" +#: mediagoblin/templates/mediagoblin/media_displays/video.html:33 +msgid "" +"Sorry, this video will not work because \n" +"\t your web browser does not support HTML5 \n" +"\t video." +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:36 +msgid "" +"You can get a modern web browser that \n" +"\t can play this video at \n" +"\t http://getfirefox.com!" +msgstr "" + #: mediagoblin/templates/mediagoblin/submit/start.html:26 -msgid "Submit yer media" -msgstr "Vlož svoj výtvor" +msgid "Add your media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Add" +msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format msgid "%(username)s's media" -msgstr "Výtvory používateľa %(username)s" +msgstr "Výtvory, ktoré vlastní %(username)s" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:37 #, python-format msgid "%(username)s's media" -msgstr "Výtvory, ktoré vlastní %(username)s" +msgstr "Výtvory, ktoré vlastní %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:57 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:60 #, python-format -msgid "By %(username)s on %(date)s" -msgstr "Od %(username)s v čase %(date)s" +msgid "Added on %(date)s." +msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:67 -msgid "Post a comment" -msgstr "Zaslať komentár" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:85 -msgid "at" -msgstr "o" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 -msgid "Post comment!" -msgstr "Zaslať komentár!" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:124 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:69 msgid "Edit" msgstr "Upraviť" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:130 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:73 msgid "Delete" msgstr "Odstrániť" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:79 +#, python-format +msgid "%(comment_count)s comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:81 +#, python-format +msgid "%(comment_count)s comments" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:83 +msgid "No comments yet." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:91 +msgid "Add one" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:100 +msgid "" +"Type your comment here. You can use Markdown for" +" formatting." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 +msgid "Add this comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:126 +msgid "at" +msgstr "o" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:141 +#, python-format +msgid "

❖ Browsing media by %(username)s

" +msgstr "" + #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -440,24 +502,24 @@ msgstr "Odstrániť navždy" #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:22 msgid "Media processing panel" -msgstr "Sekcia spracovania médií" +msgstr "Sekcia spracovania výtvorov" #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:25 msgid "" "You can track the state of media being processed for your gallery here." -msgstr "Tu môžeš sledovať priebeh spracovania médií pre svoju galériu." +msgstr "Tu môžeš sledovať priebeh spracovania výtvorov pre svoju galériu." #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:28 msgid "Media in-processing" -msgstr "Médiá v procese spracovania" +msgstr "Výtvory sa spracúvajú" #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:46 msgid "No media in-processing" -msgstr "Žiadne médiá v procese spracovania" +msgstr "Žiadne výtvory sa nespracúvajú" #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:50 msgid "These uploads failed to process:" -msgstr "Nasledovné vloženia neprešli spracovaním:" +msgstr "Nasledovné nahratia neprešli spracovaním:" #: mediagoblin/templates/mediagoblin/user_pages/user.html:31 #: mediagoblin/templates/mediagoblin/user_pages/user.html:89 @@ -467,7 +529,7 @@ msgstr "Profil, ktorý vlastní %(username)s" #: mediagoblin/templates/mediagoblin/user_pages/user.html:43 msgid "Sorry, no such user found." -msgstr "Prepáč, používateľské meno nenájdené." +msgstr "Prepáč, zadané používateľské meno nenájdené." #: mediagoblin/templates/mediagoblin/user_pages/user.html:50 #: mediagoblin/templates/mediagoblin/user_pages/user.html:70 @@ -481,7 +543,7 @@ msgstr "Takmer hotovo! Ešte ti musí byť aktivovaný účet." #: mediagoblin/templates/mediagoblin/user_pages/user.html:58 msgid "" "An email should arrive in a few moments with instructions on how to do so." -msgstr "E-mailová správa s popisom ako to spraviť, by mala onedlho doraziť." +msgstr "E-mailová správa s popisom ako to spraviť, by mal zanedlho doraziť." #: mediagoblin/templates/mediagoblin/user_pages/user.html:62 msgid "In case it doesn't:" @@ -489,7 +551,7 @@ msgstr "V prípade, že sa tak nestalo:" #: mediagoblin/templates/mediagoblin/user_pages/user.html:65 msgid "Resend verification email" -msgstr "Opätovne zaslať overovaciu správu" +msgstr "Opätovne zaslať overovaciu správu na e-mail" #: mediagoblin/templates/mediagoblin/user_pages/user.html:73 msgid "" @@ -505,41 +567,42 @@ msgid "" "If you are that person but you've lost your verification email, you can log in and resend it." msgstr "" -"Pokiaľ si to ty, ale už nemáš overovaciu správu, tak sa môžeš prihlásiť a preposlať si ju." #: mediagoblin/templates/mediagoblin/user_pages/user.html:96 msgid "Here's a spot to tell others about yourself." -msgstr "Povedz tu o sebe ostatným." +msgstr "Miesto, kde smieš povedať čo to o sebe ostatným." #: mediagoblin/templates/mediagoblin/user_pages/user.html:101 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:119 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:118 msgid "Edit profile" msgstr "Upraviť profil" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:107 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:106 msgid "This user hasn't filled in their profile (yet)." -msgstr "Dotyčná osoba ešte nevyplnila svoj profil (zatiaľ)." +msgstr "Dotyčný používateľ ešte nevyplnil svoj profil (zatiaľ)." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:133 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:125 +msgid "Change account settings" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:138 #, python-format msgid "View all of %(username)s's media" msgstr "Zhliadnuť všetky výtvory, ktoré vlastní %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:146 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:151 msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." msgstr "" "Všetky tvoje výtvory sa objavia práve tu, ale zatiaľ nemáš nič pridané." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:152 -msgid "Add media" -msgstr "Pridať výtvor" - -#: mediagoblin/templates/mediagoblin/user_pages/user.html:158 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:163 +#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72 msgid "There doesn't seem to be any media here yet..." -msgstr "Najskôr tu ešte nebudú žiadne výtvory..." +msgstr "Najskôr sa tu ešte nenachádzajú žiadne výtvory..." #: mediagoblin/templates/mediagoblin/utils/feed_link.html:21 msgid "feed icon" @@ -549,29 +612,35 @@ msgstr "ikona čítačky" msgid "Atom feed" msgstr "Čítačka Atom" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:40 -msgid "Newer" -msgstr "Novšie" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:39 +msgid "← Newer" +msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:46 -msgid "Older" -msgstr "Staršie" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:45 +msgid "Older →" +msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:50 +#: mediagoblin/templates/mediagoblin/utils/pagination.html:48 msgid "Go to page:" -msgstr "Ísť na stránku:" +msgstr "Prejsť na stránku:" + +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:27 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:32 +msgid "newer" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:38 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:43 +msgid "older" +msgstr "" #: mediagoblin/templates/mediagoblin/utils/tags.html:20 -msgid "Tagged with" -msgstr "Označené s" +msgid "View more media tagged with" +msgstr "" #: mediagoblin/templates/mediagoblin/utils/tags.html:25 -msgid "and" -msgstr "a" - -#: mediagoblin/user_pages/forms.py:24 -msgid "Comment" -msgstr "Komentár" +msgid "or" +msgstr "" #: mediagoblin/user_pages/forms.py:30 msgid "I am sure I want to delete this" @@ -587,14 +656,14 @@ msgstr "Tvoj komentár bol zaslaný!" #: mediagoblin/user_pages/views.py:183 msgid "You deleted the media." -msgstr "Výtvor bol odstránený tebou." +msgstr "Výtvor bol tebou odstránený." #: mediagoblin/user_pages/views.py:190 msgid "The media was not deleted because you didn't check that you were sure." -msgstr "Výtvor nebol odstránený, nakoľko chýbala tvoja konfirmácia." +msgstr "Výtvor nebol odstránený, nakoľko chýbalo tvoje potvrdenie." #: mediagoblin/user_pages/views.py:198 msgid "You are about to delete another user's media. Proceed with caution." -msgstr "Chystáš sa odstrániť výtvory niekoho iného. Pristupuj opatrne." +msgstr "Chystáš sa odstrániť výtvory niekoho iného. Dbaj na to." diff --git a/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.mo index 9ad54a834e25ff6192466cc557cb23a9553b063a..73bb41134a012553df8260edef2902c4c5a0e8e9 100644 GIT binary patch delta 5072 zcmeIzZEO_B8Nl)J3$Zbn7aJQKzzhcCH|#qcFyK0F4GtkG7z#8Ig*NQnt?k2ix5w_< z#vnM-V4zK-B5xWLTBNE%{nCs^|D4BRlE0{{rQKi+=kxlqtxj*D*LAXJQeu3{=o}DRy(d3`_7w zC>ebj<$dQQ|B|A2X^=q15T3la5_yMeM0udyZ~rPvM_W-+xCbA_L6kYafU-vJVTDR2 zTTm8l6c^xL4B-nX&zDL5S8z~HuQG=wcHl0Q4qnH__yIQH0@9#y3vR&2aSy(QvicvT z6UoSabnq#Zsmx*&l9?1TR&@Y1epec%bMRA?#c|fZ;Wx;%tM_p^W|JlfWCeZ>cjFWI z63W_WWtb1*Rvg0PxEmj!b7E7cu^G=JU8+*{x;&Q(a3FKH3BQH|n2l#q=J-5HV825d z+3$VdN4f67dQm$OJcoe`6Io2^0&Dw}yF+iE6~4AqEN@nIyOlxonKf)PcD^f}DI zS5danYbXJnL0L4HP%`relvI9%_hS)TU?r}_HhdO?cpfPsYCKy)oQe`~1x}UyKc9nY z8rrc5NLt?yNa^7-$uFb z8qVhZYQo%1he4!GwV?!JqKy1|n2$%1b*PS^)QeLni|!5d@FP5fUS(!(d*)?!)ggSG z_7`yrF0EpR;bBZkq$fF$k^TzvFpqS|h$i}0AnQggLZ(f93FWzMC>a?<8QCF}%p66Q zgF4~2zloCaOPGuApscy~s>y#o2jgopi>m~?IiHR)(!D6DI*iisFfvGW8u_Ys{PyD7 zOdxYn?r%Z~Xbnm~n^C69#!WbY#Grm%Oa2#e@OK(ye=lTDh+(Y9Aq?S3ln&-l6jop@ z$|~Q69rz@+;yGN3WjsumYCW?4)NcF&ejoSXW#p?uDc&X>A4CTa;VvA<#L9@jfie|` zk-pV2l&Ls}h4?3&h`GVcu9$+$IiG`4@w#vcK8sJ_o5)zyBV3e$q`uC<5C^Z}Zrsd5 zkZpJ#rC|IKW#87{mwE63l)2l6UHEOx#y?{Leu%P$#w^TCX`yd1%6(-x7H6QUtZocj z@wl0A9}8Q(3Ae`4{yCTKaK-U{oag0Oc7eBL`cCiV{9sv2vh~W5XY?}L>UW}vE*&=` zQA39YG*_!4ErDdKY73|P*N*AB+~R1*=rbd#Et39ao{%$bCCs#Lcl1Uqa$&&gwQt;K z%ALBhI%2qHjnm+LnBP{|Z8$n)nh9Q#aJ`LVXBLOMjYOB3c{FJ_PQPV)fw4mymm7(& z8B@zMmyKIu%e2ctDyw@P(@q$1-cjY~+i$dbV-cOOTy1W5Z6oY@$$}}lowgPC_7!|H zC|46zuI`K`BHFRyCWF)cQMX&W-G-}2`qq}M&A1Vb4Hu3p&8oBL(hoMGT}vlzt1mqU zZS^O3lDznVGz(V>@$}qeVJ0d5 z40z>}_b)MQvZ!5yX<^c2+6|{ctvB84aimYuGmtR*ueW+HO*Usgq$8FL(&vs#nRbhUV50iut7?6!C1{F{jz>D zq(ic*Oq;iuPWtAN7p>f|detKT?sR_*-d~FL<{6QQZ92|ysyLjTO84TgW8H1qW`o{n z_3E&ZknHOgLwDO|=lvDkuA6KQ1R{pbw0A~rGi1bK4GGf?ko~P@*mVMN!|sVN1A&m? zM8i%+>uSHDC1AAbPUetb+(<9)2KD9iy7A_eE}s5Kl$6CS+w}JZdG2EQ$~y2imcE;)l?2~uZEs-E6|I?v{lSgCC{fQ=B%>;w zjfB;&V^)`rN@8T`r!zNdvYV%Nr2NDc$PC^7xiy?ml+HW!IV#JkThn~gWR80NKNrcU z_fHu8ey_c5gZI|dSG+f-l}sa7rmfh#^4C^Z_8rt6(&Sy8Hn^y|Y{W`NR>O`$XeLMTFSvLk3T)%H=^TLJ0N6PB5K23do_1>rb`uxJ(Yjf&f z)#i39Vr1s;dp~_eUsc)ju`2qh(E9&=IX^bI K*Hw3_^y(jTRkpAI delta 3265 zcmb`{4{TM{9l-I^7ATbRr>!kjDVzc#E$!=jPbjp7VJX8^X6c~DxP`g<-n)J8()aGg zdv99`VGlMYLUdU?Y9KDlGz3kio2)Ztab`%EahZw1#JMTxHqD6pzbtWoBm4edZy7OL zmi=j7-{;)(&O3j8zu$SMa^JYK_*U(VhZKJk{4eJJ-3od7$KR8cN?pU_Q`mrK@e=+R zJMe|sO3lIFV<-L-L#Ze|$kM+0_8KQP#8{UNn@IHJUtC(yx{tTDm{P|N+j$xYTC$O3IRrLa; z>M(}Oa5KsYZIqMkjh>4r;~qds#VM4DpGS$rMXbT!AbTiv&V+eywp>?Nv>Z;sfF_>iuj4K~m4da*PM5Oq5FWzMU z_VdX4l}feqyk#Zvmyq~$$in+ja&!zO6_4R8{5o#MXHb4v{)Td&8*WtUBWPh4eid8s z4J0dS<|?Ib#vAb<=1>-X4`<<`7UCb!Si-S3;R7fqeibEW@1Xo(ypIy8<;*S{O`wFZ z7yED!rMe%)_4p#nhA*RB=dIjbxm~+Z4tN}Ssi%8*mt0-IEdB+hXi}_Nfe&Fhp1>;n zGFIZ_XdazyDz*0fDy_}BIbWO8o5|>copCI4PgSp3IQO2i&E}wPDQeHvH>}E7q1_Uw zKFdwpdDWM*(<6Gq8}+s0ro6o|eTS_B+YPnlYP(=Lc|GogIc@3NcYItAd%jNREH~@8 z*{Lt>v4UXS^D{Bk=M@Tk58YwMFX-t{=ormswCgPn^|0e+n0SIl-q!Zs&~^idT{*6) ztUfk*uDY(Q+O@~8e0Q>ZerH8>zdL5-olNOVCQ)PN4@Qfs0ejr`&BdBlGq-kqBI*rv zVKfMJ!3xv4m>TqGTRI)>uJjl^G@IU9zmhuxPr);(`_x2FV}aMcRB1P zYdNmY**;5o>~n;OkIF--%cA9aI@n|9^AhHQ6NC&2%z?&D=0}acF#dI0%-hKU)3EsL zwmT(p(~;IWi+$U+JC!3l6VpTfgshSGvc#Ba$79NJGs+6pu+0{owC5`M&>IcS%%(4_ zO|&PH?eR4_5${f}X^(ft<5h#(+jrPwj^wF*3*qV3$#~+*xX$k6O_SekT3u#N&aN}b zrJud368D>!?wPm6%UHYhSYW3d*E2QEo6L#kqyMZT2Yq`a@0`2e`9BurHcx8O@+pJR zmqhEV9pt^JCYQM0zp2TilRK6#`A|(hvLatmb9GJXaAFS?vg+Xv7v{HC#b>DPdn~iC zwx#Em(!%oY=z>R~Svuu}j<#KE#QBfvbhSCxGWsuS_3qXYYW2CzgWmTZ&F^+NcggAa zPd^igV9eX?UFpB7X4Uq6Y{@oF^&c~Lw{=PRPM&VN>whWTBON=<`yCg|=Mvi{-%d7` V-S*$tZU2bpT6)a!t?9y5e+M~}e>?yH diff --git a/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.po index ffd2c04c..c5d3104c 100644 --- a/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.po @@ -1,5 +1,5 @@ # Translations template for PROJECT. -# Copyright (C) 2011 ORGANIZATION +# Copyright (C) 2012 ORGANIZATION # This file is distributed under the same license as the PROJECT project. # # Translators: @@ -8,8 +8,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-12-04 10:24-0600\n" -"PO-Revision-Date: 2011-12-04 16:23+0000\n" +"POT-Creation-Date: 2012-01-07 13:47-0600\n" +"PO-Revision-Date: 2012-01-07 19:44+0000\n" "Last-Translator: cwebber \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -23,27 +23,15 @@ msgstr "" msgid "Invalid file given for media type." msgstr "Za vrsto vsebine je bila podana napačna datoteka." -#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 +#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41 msgid "Username" msgstr "Uporabniško ime" -#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:53 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 msgid "Password" msgstr "Geslo" -#: mediagoblin/auth/forms.py:35 -msgid "Passwords must match." -msgstr "Gesli morata biti enaki." - -#: mediagoblin/auth/forms.py:37 -msgid "Confirm password" -msgstr "Potrdite geslo" - -#: mediagoblin/auth/forms.py:39 -msgid "Type it again here to make sure there are no spelling mistakes." -msgstr "" - -#: mediagoblin/auth/forms.py:42 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "E-poštni naslov" @@ -59,7 +47,7 @@ msgstr "Oprostite, uporabnik s tem imenom že obstaja." msgid "Sorry, a user with that email address already exists." msgstr "" -#: mediagoblin/auth/views.py:179 +#: mediagoblin/auth/views.py:180 msgid "" "Your email address has been verified. You may now login, edit your profile, " "and submit images!" @@ -67,67 +55,103 @@ msgstr "" "Vaš e-poštni naslov je bil potrjen. Sedaj se lahko prijavite, uredite svoj " "profil in pošljete slike." -#: mediagoblin/auth/views.py:185 +#: mediagoblin/auth/views.py:186 msgid "The verification key or user id is incorrect" msgstr "Potrditveni ključ ali uporabniška identifikacija je napačna" -#: mediagoblin/auth/views.py:203 +#: mediagoblin/auth/views.py:204 msgid "You must be logged in so we know who to send the email to!" msgstr "" -#: mediagoblin/auth/views.py:211 +#: mediagoblin/auth/views.py:212 msgid "You've already verified your email address!" msgstr "" -#: mediagoblin/auth/views.py:224 +#: mediagoblin/auth/views.py:225 msgid "Resent your verification email." msgstr "Ponovno pošiljanje potrditvene e-pošte." -#: mediagoblin/auth/views.py:265 +#: mediagoblin/auth/views.py:260 +msgid "" +"An email has been sent with instructions on how to change your password." +msgstr "" + +#: mediagoblin/auth/views.py:270 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." msgstr "" +#: mediagoblin/auth/views.py:282 +msgid "Couldn't find someone with that username or email." +msgstr "" + +#: mediagoblin/auth/views.py:330 +msgid "You can now log in using your new password." +msgstr "" + #: mediagoblin/edit/forms.py:24 mediagoblin/submit/forms.py:27 msgid "Title" msgstr "Naslov" -#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:27 mediagoblin/submit/forms.py:30 +msgid "Description of this work" +msgstr "" + +#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:31 +msgid "" +"You can use\n" +" \n" +" Markdown for formatting." +msgstr "" + +#: mediagoblin/edit/forms.py:32 mediagoblin/submit/forms.py:35 msgid "Tags" msgstr "Oznake" -#: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 -msgid "Seperate tags by commas." +#: mediagoblin/edit/forms.py:34 mediagoblin/submit/forms.py:37 +msgid "Separate tags by commas." msgstr "" -#: mediagoblin/edit/forms.py:33 +#: mediagoblin/edit/forms.py:37 msgid "Slug" msgstr "Oznaka" -#: mediagoblin/edit/forms.py:34 +#: mediagoblin/edit/forms.py:38 msgid "The slug can't be empty" msgstr "Oznaka ne sme biti prazna" -#: mediagoblin/edit/forms.py:35 +#: mediagoblin/edit/forms.py:39 msgid "" -"The title part of this media's URL. You usually don't need to change this." +"The title part of this media's address. You usually don't need to change " +"this." msgstr "" -#: mediagoblin/edit/forms.py:42 +#: mediagoblin/edit/forms.py:46 msgid "Bio" msgstr "Biografija" -#: mediagoblin/edit/forms.py:45 +#: mediagoblin/edit/forms.py:48 +msgid "" +"You can use\n" +" \n" +" Markdown for formatting." +msgstr "" + +#: mediagoblin/edit/forms.py:53 msgid "Website" msgstr "Spletna stran" -#: mediagoblin/edit/forms.py:49 +#: mediagoblin/edit/forms.py:60 msgid "Old password" msgstr "" -#: mediagoblin/edit/forms.py:52 -msgid "New Password" +#: mediagoblin/edit/forms.py:62 +msgid "Enter your old password to prove you own this account." +msgstr "" + +#: mediagoblin/edit/forms.py:65 +msgid "New password" msgstr "" #: mediagoblin/edit/views.py:65 @@ -142,39 +166,43 @@ msgstr "Urejate vsebino drugega uporabnika. Nadaljujte pazljivo." msgid "You are editing a user's profile. Proceed with caution." msgstr "Urejate uporabniški profil. Nadaljujte pazljivo." -#: mediagoblin/edit/views.py:171 +#: mediagoblin/edit/views.py:174 +msgid "Profile changes saved" +msgstr "" + +#: mediagoblin/edit/views.py:200 msgid "Wrong password" msgstr "" -#: mediagoblin/edit/views.py:192 -msgid "Profile edited!" +#: mediagoblin/edit/views.py:216 +msgid "Account settings saved" msgstr "" -#: mediagoblin/media_types/__init__.py:65 -msgid "Could not find any file extension in \"{filename}\"" +#: mediagoblin/media_types/__init__.py:77 +msgid "Could not extract any file extension from \"{filename}\"" +msgstr "" + +#: mediagoblin/media_types/__init__.py:88 +msgid "Sorry, I don't support that file type :(" msgstr "" #: mediagoblin/submit/forms.py:25 msgid "File" msgstr "Datoteka" -#: mediagoblin/submit/forms.py:30 -msgid "Description of this work" -msgstr "" - -#: mediagoblin/submit/views.py:49 +#: mediagoblin/submit/views.py:50 msgid "You must provide a file." msgstr "Podati morate datoteko." -#: mediagoblin/submit/views.py:127 +#: mediagoblin/submit/views.py:128 msgid "Woohoo! Submitted!" msgstr "Juhej! Poslano." -#: mediagoblin/submit/views.py:133 -msgid "Invalid file type." -msgstr "" +#: mediagoblin/templates/mediagoblin/404.html:22 +msgid "Image of 404 goblin stressing out" +msgstr "Slika napake 404 s paničnim škratom" -#: mediagoblin/templates/mediagoblin/404.html:21 +#: mediagoblin/templates/mediagoblin/404.html:23 msgid "Oops!" msgstr "Opa!" @@ -190,33 +218,30 @@ msgstr "" "Če ste v točnost naslova prepričani, je bila iskana stran morda premaknjena " "ali pa izbrisana." -#: mediagoblin/templates/mediagoblin/404.html:32 -msgid "Image of 404 goblin stressing out" -msgstr "Slika napake 404 s paničnim škratom" - -#: mediagoblin/templates/mediagoblin/base.html:49 +#: mediagoblin/templates/mediagoblin/base.html:48 msgid "MediaGoblin logo" msgstr "Logotip MediaGoblin" -#: mediagoblin/templates/mediagoblin/base.html:54 -msgid "Submit media" -msgstr "Pošlji vsebino" +#: mediagoblin/templates/mediagoblin/base.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:157 +msgid "Add media" +msgstr "Dodaj vsebino" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:64 msgid "Verify your email!" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:72 +#: mediagoblin/templates/mediagoblin/base.html:71 msgid "log out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:75 +#: mediagoblin/templates/mediagoblin/base.html:74 #: mediagoblin/templates/mediagoblin/auth/login.html:27 #: mediagoblin/templates/mediagoblin/auth/login.html:45 msgid "Log in" msgstr "Prijava" -#: mediagoblin/templates/mediagoblin/base.html:91 +#: mediagoblin/templates/mediagoblin/base.html:86 msgid "" "Powered by MediaGoblin, a GNU project" @@ -226,7 +251,7 @@ msgstr "" msgid "Explore" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:27 +#: mediagoblin/templates/mediagoblin/root.html:26 msgid "Hi there, welcome to this MediaGoblin site!" msgstr "" @@ -250,22 +275,21 @@ msgstr "" #, python-format msgid "" "Create an account at this site\n" -" or\n" -" Set up MediaGoblin on your own server" +" or\n" +" Set up MediaGoblin on your own server" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:44 +#: mediagoblin/templates/mediagoblin/root.html:40 msgid "Most recent media" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/change_fp.html:29 -msgid "Enter your new password" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:32 +msgid "Set your new password" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/change_fp.html:33 -#: mediagoblin/templates/mediagoblin/submit/start.html:30 -msgid "Submit" -msgstr "Pošlji" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:35 +msgid "Set password" +msgstr "" #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" @@ -275,15 +299,6 @@ msgstr "" msgid "Send instructions" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 -msgid "Your password has been changed. Try to log in now." -msgstr "" - -#: mediagoblin/templates/mediagoblin/auth/fp_email_sent.html:22 -msgid "" -"Check your inbox. We sent an email with a URL for changing your password." -msgstr "" - #: mediagoblin/templates/mediagoblin/auth/fp_verification_email.txt:19 #, python-format msgid "" @@ -314,11 +329,11 @@ msgstr "Ustvarite si ga." msgid "Forgot your password?" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/register.html:27 +#: mediagoblin/templates/mediagoblin/auth/register.html:32 msgid "Create an account!" msgstr "Ustvarite račun." -#: mediagoblin/templates/mediagoblin/auth/register.html:31 +#: mediagoblin/templates/mediagoblin/auth/register.html:36 msgid "Create" msgstr "Ustvari" @@ -350,10 +365,16 @@ msgid "Cancel" msgstr "Prekliči" #: mediagoblin/templates/mediagoblin/edit/edit.html:37 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:40 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:35 msgid "Save changes" msgstr "Shrani spremembe" +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:34 +#, python-format +msgid "Changing %(username)s's account settings" +msgstr "" + #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29 #, python-format msgid "Editing %(username)s's profile" @@ -365,13 +386,32 @@ msgstr "Urejanje profila – %(username)s" msgid "Media tagged with: %(tag_name)s" msgstr "" -#: mediagoblin/templates/mediagoblin/media_displays/video.html:19 +#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 +#: mediagoblin/templates/mediagoblin/media_displays/video.html:46 msgid "Original" msgstr "" +#: mediagoblin/templates/mediagoblin/media_displays/video.html:33 +msgid "" +"Sorry, this video will not work because \n" +"\t your web browser does not support HTML5 \n" +"\t video." +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:36 +msgid "" +"You can get a modern web browser that \n" +"\t can play this video at \n" +"\t http://getfirefox.com!" +msgstr "" + #: mediagoblin/templates/mediagoblin/submit/start.html:26 -msgid "Submit yer media" -msgstr "Pošljite svojo vsebino" +msgid "Add your media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Add" +msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format @@ -383,31 +423,57 @@ msgstr "" msgid "%(username)s's media" msgstr "Vsebina uporabnika %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:57 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:60 #, python-format -msgid "By %(username)s on %(date)s" +msgid "Added on %(date)s." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:67 -msgid "Post a comment" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:85 -msgid "at" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 -msgid "Post comment!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:124 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:69 msgid "Edit" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:130 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:73 msgid "Delete" msgstr "" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:79 +#, python-format +msgid "%(comment_count)s comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:81 +#, python-format +msgid "%(comment_count)s comments" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:83 +msgid "No comments yet." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:91 +msgid "Add one" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:100 +msgid "" +"Type your comment here. You can use Markdown for" +" formatting." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 +msgid "Add this comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:126 +msgid "at" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:141 +#, python-format +msgid "

❖ Browsing media by %(username)s

" +msgstr "" + #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -492,30 +558,31 @@ msgid "Here's a spot to tell others about yourself." msgstr "Na tem mestu lahko drugim poveste nekaj o sebi." #: mediagoblin/templates/mediagoblin/user_pages/user.html:101 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:119 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:118 msgid "Edit profile" msgstr "Uredi profil" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:107 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:106 msgid "This user hasn't filled in their profile (yet)." msgstr "Ta uporabnik še ni izpolnil svojega profila." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:133 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:125 +msgid "Change account settings" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:138 #, python-format msgid "View all of %(username)s's media" msgstr "Prikaži vso vsebino uporabnika %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:146 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:151 msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." msgstr "Tu bo prikazana vaša vsebina, a trenutno še niste dodali nič." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:152 -msgid "Add media" -msgstr "Dodaj vsebino" - -#: mediagoblin/templates/mediagoblin/user_pages/user.html:158 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:163 +#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72 msgid "There doesn't seem to be any media here yet..." msgstr "Videti je, da tu še ni nobene vsebine ..." @@ -527,30 +594,36 @@ msgstr "Ikona vira" msgid "Atom feed" msgstr "Ikona Atom" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:40 -msgid "Newer" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:39 +msgid "← Newer" msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:46 -msgid "Older" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:45 +msgid "Older →" msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:50 +#: mediagoblin/templates/mediagoblin/utils/pagination.html:48 msgid "Go to page:" msgstr "" +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:27 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:32 +msgid "newer" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:38 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:43 +msgid "older" +msgstr "" + #: mediagoblin/templates/mediagoblin/utils/tags.html:20 -msgid "Tagged with" +msgid "View more media tagged with" msgstr "" #: mediagoblin/templates/mediagoblin/utils/tags.html:25 -msgid "and" +msgid "or" msgstr "" -#: mediagoblin/user_pages/forms.py:24 -msgid "Comment" -msgstr "Komentar" - #: mediagoblin/user_pages/forms.py:30 msgid "I am sure I want to delete this" msgstr "" diff --git a/mediagoblin/i18n/sr/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/sr/LC_MESSAGES/mediagoblin.mo index ece8989faa31253cf521391d10627404560927f2..2a99cb531b2fd2b39ce21db011e18e458ec1c819 100644 GIT binary patch literal 13259 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 X3kzFsxTlxc6aN)6y~O^1eu@3R3e(en delta 3192 zcmeIy>u*#=7{KA_P1@2@+HzAUOrgb=(rtI4S0JU7O9})F)Zh)w>F#NJq{yi4)d!~Z1yZzM_WpTE8lN{ylV9*)BkIE3F|86HnnDh+?bO1y(h z(MMwi_M$xR=Szk@hSKjiKA==g{YjybhQE+8Rb#qRqj4pAu?3&QH;@-p)<~sta2!g% zVwCn;x4j-GP;bVEFo=`!RZPZrF$4Q>JoBqh+zwx2CJ%na2l4K32L_|JEUX-5fNC6z z^N=oTHO|DRu@|@D6-;Na61 zXW|N!Gu(t;+>H{EvnT^zK$-9=%2E7`GTv=mjCXN7E+TA8aV^TYN3jYoeIEWIlJmSk-YC3AHLCKjX-1Zif2zFruZb4bV*%*a6 z6l9r8U@p?6wqPypMG4hqlw`Vza#Ry(T!%I2!#yb1>l`NH1>{1huTU0p6-#(<1KE=r zJuyB{tdPPG4RcX;TELHhyx5GDxDF+ByRZVkbDxi66*8el=~sYqG*6;j=N6QS`%sSP zLzE*tg>s#5A^l@2%;l8O^`LazhBDB8xBU>ZX!S8lE?h)D>PNohtkcOb$%QN=IBF8g z^VulLx*8=J4fpvbl!ZB%Ecbse1&&c2L`kBLP?F>X_To*vf<>nQoB{-7Xdo;EE$uttf*eB?r?l_)#(qaeEniW)n(8-$yyZYbd#JyO8)xNJ^&12lSy#Sch^H zO_+>N;bJsU&iE)wQVyUDJo4fAb*e_W&Yh_70Lpb9z|AUms;`%v!l9ZW(G+e<_rreOujLh8_YJJoS+P04f;_2IPoKtKo0fMqz#^6Q;T z`7b9da6Z$;F&(mXVNt+{n#B>-VAy`MLp8LU{`I;i)D_m2-4fd9(Q8Z{G3}@}Y;6V& zt3!8N(ROXNFye?oc@3Q4OJBkoVATwZcJt?+FcE9RY2J zCPj6tWd|6zheC&`&5cphj##Y9vYqo&U+X`ak(-cVo89-{?LSjcnUv9JZ!kKn!0=0s zH`^K2b;DJ+lJC^#ghvpl zs2Rw226A2*YlaDqjv8$d-O@AsjuG)Vv0T$hEy;E!k9o7Kt0ibf)#_p5LB3b%F~e>{ zv(eUO28QG243=z3B69uhGyRD*7At8pEL*pmVWtVO#`Q$IODe-n1|>VBBb{bPhlDt2 zMWS?xIK30i;~iE5SLGy5s-Ui{FC(Lh3F57gJCD4dYU18vp\n" "Language-Team: Serbian (http://www.transifex.net/projects/p/mediagoblin/team/sr/)\n" "MIME-Version: 1.0\n" @@ -22,27 +22,15 @@ msgstr "" msgid "Invalid file given for media type." msgstr "" -#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 +#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41 msgid "Username" msgstr "" -#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:53 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 msgid "Password" msgstr "" -#: mediagoblin/auth/forms.py:35 -msgid "Passwords must match." -msgstr "" - -#: mediagoblin/auth/forms.py:37 -msgid "Confirm password" -msgstr "" - -#: mediagoblin/auth/forms.py:39 -msgid "Type it again here to make sure there are no spelling mistakes." -msgstr "" - -#: mediagoblin/auth/forms.py:42 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "" @@ -58,73 +46,109 @@ msgstr "" msgid "Sorry, a user with that email address already exists." msgstr "" -#: mediagoblin/auth/views.py:179 +#: mediagoblin/auth/views.py:180 msgid "" "Your email address has been verified. You may now login, edit your profile, " "and submit images!" msgstr "" -#: mediagoblin/auth/views.py:185 +#: mediagoblin/auth/views.py:186 msgid "The verification key or user id is incorrect" msgstr "" -#: mediagoblin/auth/views.py:203 +#: mediagoblin/auth/views.py:204 msgid "You must be logged in so we know who to send the email to!" msgstr "" -#: mediagoblin/auth/views.py:211 +#: mediagoblin/auth/views.py:212 msgid "You've already verified your email address!" msgstr "" -#: mediagoblin/auth/views.py:224 +#: mediagoblin/auth/views.py:225 msgid "Resent your verification email." msgstr "" -#: mediagoblin/auth/views.py:265 +#: mediagoblin/auth/views.py:260 +msgid "" +"An email has been sent with instructions on how to change your password." +msgstr "" + +#: mediagoblin/auth/views.py:270 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." msgstr "" +#: mediagoblin/auth/views.py:282 +msgid "Couldn't find someone with that username or email." +msgstr "" + +#: mediagoblin/auth/views.py:330 +msgid "You can now log in using your new password." +msgstr "" + #: mediagoblin/edit/forms.py:24 mediagoblin/submit/forms.py:27 msgid "Title" msgstr "" -#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:27 mediagoblin/submit/forms.py:30 +msgid "Description of this work" +msgstr "" + +#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:31 +msgid "" +"You can use\n" +" \n" +" Markdown for formatting." +msgstr "" + +#: mediagoblin/edit/forms.py:32 mediagoblin/submit/forms.py:35 msgid "Tags" msgstr "" -#: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 -msgid "Seperate tags by commas." +#: mediagoblin/edit/forms.py:34 mediagoblin/submit/forms.py:37 +msgid "Separate tags by commas." msgstr "" -#: mediagoblin/edit/forms.py:33 +#: mediagoblin/edit/forms.py:37 msgid "Slug" msgstr "" -#: mediagoblin/edit/forms.py:34 +#: mediagoblin/edit/forms.py:38 msgid "The slug can't be empty" msgstr "" -#: mediagoblin/edit/forms.py:35 +#: mediagoblin/edit/forms.py:39 msgid "" -"The title part of this media's URL. You usually don't need to change this." +"The title part of this media's address. You usually don't need to change " +"this." msgstr "" -#: mediagoblin/edit/forms.py:42 +#: mediagoblin/edit/forms.py:46 msgid "Bio" msgstr "" -#: mediagoblin/edit/forms.py:45 +#: mediagoblin/edit/forms.py:48 +msgid "" +"You can use\n" +" \n" +" Markdown for formatting." +msgstr "" + +#: mediagoblin/edit/forms.py:53 msgid "Website" msgstr "" -#: mediagoblin/edit/forms.py:49 +#: mediagoblin/edit/forms.py:60 msgid "Old password" msgstr "" -#: mediagoblin/edit/forms.py:52 -msgid "New Password" +#: mediagoblin/edit/forms.py:62 +msgid "Enter your old password to prove you own this account." +msgstr "" + +#: mediagoblin/edit/forms.py:65 +msgid "New password" msgstr "" #: mediagoblin/edit/views.py:65 @@ -139,39 +163,43 @@ msgstr "" msgid "You are editing a user's profile. Proceed with caution." msgstr "" -#: mediagoblin/edit/views.py:171 +#: mediagoblin/edit/views.py:174 +msgid "Profile changes saved" +msgstr "" + +#: mediagoblin/edit/views.py:200 msgid "Wrong password" msgstr "" -#: mediagoblin/edit/views.py:192 -msgid "Profile edited!" +#: mediagoblin/edit/views.py:216 +msgid "Account settings saved" msgstr "" -#: mediagoblin/media_types/__init__.py:65 -msgid "Could not find any file extension in \"{filename}\"" +#: mediagoblin/media_types/__init__.py:77 +msgid "Could not extract any file extension from \"{filename}\"" +msgstr "" + +#: mediagoblin/media_types/__init__.py:88 +msgid "Sorry, I don't support that file type :(" msgstr "" #: mediagoblin/submit/forms.py:25 msgid "File" msgstr "" -#: mediagoblin/submit/forms.py:30 -msgid "Description of this work" -msgstr "" - -#: mediagoblin/submit/views.py:49 +#: mediagoblin/submit/views.py:50 msgid "You must provide a file." msgstr "" -#: mediagoblin/submit/views.py:127 +#: mediagoblin/submit/views.py:128 msgid "Woohoo! Submitted!" msgstr "" -#: mediagoblin/submit/views.py:133 -msgid "Invalid file type." +#: mediagoblin/templates/mediagoblin/404.html:22 +msgid "Image of 404 goblin stressing out" msgstr "" -#: mediagoblin/templates/mediagoblin/404.html:21 +#: mediagoblin/templates/mediagoblin/404.html:23 msgid "Oops!" msgstr "" @@ -185,33 +213,30 @@ msgid "" " been moved or deleted." msgstr "" -#: mediagoblin/templates/mediagoblin/404.html:32 -msgid "Image of 404 goblin stressing out" -msgstr "" - -#: mediagoblin/templates/mediagoblin/base.html:49 +#: mediagoblin/templates/mediagoblin/base.html:48 msgid "MediaGoblin logo" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:54 -msgid "Submit media" +#: mediagoblin/templates/mediagoblin/base.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:157 +msgid "Add media" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:64 msgid "Verify your email!" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:72 +#: mediagoblin/templates/mediagoblin/base.html:71 msgid "log out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:75 +#: mediagoblin/templates/mediagoblin/base.html:74 #: mediagoblin/templates/mediagoblin/auth/login.html:27 #: mediagoblin/templates/mediagoblin/auth/login.html:45 msgid "Log in" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:91 +#: mediagoblin/templates/mediagoblin/base.html:86 msgid "" "Powered by MediaGoblin, a GNU project" @@ -221,7 +246,7 @@ msgstr "" msgid "Explore" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:27 +#: mediagoblin/templates/mediagoblin/root.html:26 msgid "Hi there, welcome to this MediaGoblin site!" msgstr "" @@ -245,21 +270,20 @@ msgstr "" #, python-format msgid "" "Create an account at this site\n" -" or\n" -" Set up MediaGoblin on your own server" +" or\n" +" Set up MediaGoblin on your own server" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:44 +#: mediagoblin/templates/mediagoblin/root.html:40 msgid "Most recent media" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/change_fp.html:29 -msgid "Enter your new password" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:32 +msgid "Set your new password" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/change_fp.html:33 -#: mediagoblin/templates/mediagoblin/submit/start.html:30 -msgid "Submit" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:35 +msgid "Set password" msgstr "" #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 @@ -270,15 +294,6 @@ msgstr "" msgid "Send instructions" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 -msgid "Your password has been changed. Try to log in now." -msgstr "" - -#: mediagoblin/templates/mediagoblin/auth/fp_email_sent.html:22 -msgid "" -"Check your inbox. We sent an email with a URL for changing your password." -msgstr "" - #: mediagoblin/templates/mediagoblin/auth/fp_verification_email.txt:19 #, python-format msgid "" @@ -309,11 +324,11 @@ msgstr "" msgid "Forgot your password?" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/register.html:27 +#: mediagoblin/templates/mediagoblin/auth/register.html:32 msgid "Create an account!" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/register.html:31 +#: mediagoblin/templates/mediagoblin/auth/register.html:36 msgid "Create" msgstr "" @@ -339,10 +354,16 @@ msgid "Cancel" msgstr "" #: mediagoblin/templates/mediagoblin/edit/edit.html:37 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:40 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:35 msgid "Save changes" msgstr "" +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:34 +#, python-format +msgid "Changing %(username)s's account settings" +msgstr "" + #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29 #, python-format msgid "Editing %(username)s's profile" @@ -354,12 +375,31 @@ msgstr "" msgid "Media tagged with: %(tag_name)s" msgstr "" -#: mediagoblin/templates/mediagoblin/media_displays/video.html:19 +#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 +#: mediagoblin/templates/mediagoblin/media_displays/video.html:46 msgid "Original" msgstr "" +#: mediagoblin/templates/mediagoblin/media_displays/video.html:33 +msgid "" +"Sorry, this video will not work because \n" +"\t your web browser does not support HTML5 \n" +"\t video." +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:36 +msgid "" +"You can get a modern web browser that \n" +"\t can play this video at \n" +"\t http://getfirefox.com!" +msgstr "" + #: mediagoblin/templates/mediagoblin/submit/start.html:26 -msgid "Submit yer media" +msgid "Add your media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Add" msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 @@ -372,31 +412,57 @@ msgstr "" msgid "%(username)s's media" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:57 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:60 #, python-format -msgid "By %(username)s on %(date)s" +msgid "Added on %(date)s." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:67 -msgid "Post a comment" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:85 -msgid "at" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 -msgid "Post comment!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:124 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:69 msgid "Edit" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:130 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:73 msgid "Delete" msgstr "" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:79 +#, python-format +msgid "%(comment_count)s comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:81 +#, python-format +msgid "%(comment_count)s comments" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:83 +msgid "No comments yet." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:91 +msgid "Add one" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:100 +msgid "" +"Type your comment here. You can use Markdown for" +" formatting." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 +msgid "Add this comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:126 +msgid "at" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:141 +#, python-format +msgid "

❖ Browsing media by %(username)s

" +msgstr "" + #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -477,30 +543,31 @@ msgid "Here's a spot to tell others about yourself." msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/user.html:101 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:119 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:118 msgid "Edit profile" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:107 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:106 msgid "This user hasn't filled in their profile (yet)." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:133 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:125 +msgid "Change account settings" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:138 #, python-format msgid "View all of %(username)s's media" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:146 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:151 msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:152 -msgid "Add media" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/user.html:158 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:163 +#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72 msgid "There doesn't seem to be any media here yet..." msgstr "" @@ -512,28 +579,34 @@ msgstr "" msgid "Atom feed" msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:40 -msgid "Newer" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:39 +msgid "← Newer" msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:46 -msgid "Older" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:45 +msgid "Older →" msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:50 +#: mediagoblin/templates/mediagoblin/utils/pagination.html:48 msgid "Go to page:" msgstr "" +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:27 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:32 +msgid "newer" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:38 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:43 +msgid "older" +msgstr "" + #: mediagoblin/templates/mediagoblin/utils/tags.html:20 -msgid "Tagged with" +msgid "View more media tagged with" msgstr "" #: mediagoblin/templates/mediagoblin/utils/tags.html:25 -msgid "and" -msgstr "" - -#: mediagoblin/user_pages/forms.py:24 -msgid "Comment" +msgid "or" msgstr "" #: mediagoblin/user_pages/forms.py:30 diff --git a/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.mo index c6cf0df960026e29789893073fcd7f3bcce36f51..d647e3739e51ffb7165388b0c7f4a3d6c65c284f 100644 GIT binary patch delta 5114 zcmeIzeN0v79l-Giuqyb5pa{P4fJH>gy?_cx5k=9u&f?~18*Hr}?mfW8d+)h9=KwON z*S1s4vNjDT)g~M1(wS}9mL`?x68GBKtZD0BlC9RP(XCpyWzD)|rd`@J%f7#R4=Orc zHEa6M2=F=gIp;htzu)ux?(o)wk>t6&2~R72_VYKNzt#!z>B>)ZvQkBSjNx1y!ddtn z7T^!?0{#kvcr=?n@I1=>@*JhIuo-DmYjF~8!d#`2s-27JG?InZNaz{}natdYTS*%vxpMtX)U*&Sa zB-LWP3u|!?ZpSz9ELP&N8A=u7TR4ar%sPa-u>}8s`O-d9sZyMcveE{W$gW1YzXc^V zU6_;(_i!N*7(ss3^Zb*Q{mgIwCCUru{Py=yQjkfnci>c9fO*I^P}ROGv4_uVaW;Mr zC895)jQ4wqzl7)=8e}4OFg+Q#3>ib!qP)=Rw{Jt~s23%K`|v^BkCOAVD0^fgJ5(as zgtBQPSc6~2PCSnCev!m~0~ZVFRdQ%z8}32r;1t&52N=K_!k}>nw&SC?4^N}){s-wq zA~J*yK7o?T3|1kLNg``i2T|kKq+uQxKSJ3YXZ#2Lh@@Rz!gZKQm}DXw@NV3TkK+lH zz0u4v@4;Ri#-q3w*V8$3Q!im7zKL|H3OMWXUNXpq8 zdaT18_#__2T3oy+z48u}32jGCph}>0w9juJLbi!|21&bm9tnc_1>(2DdmLXA5YcMqtludIOv+x@z5juiWFMf!GP`!*Y;rH=<++UW??Uxp(H}QAy z$F#qWz37#v_uRiQDY>7^@=2d+KpF6Uluhyo%76nXD|-@Uf=7^(rd~p+bZ1aP`zMqL zT|((^LPfg01SJIlls(jdGH!DP@t@4a!~O#%_VC$48So4eCG{>!$9YTB$7T_-NY#qc z-iuN%cB4%E36u$a3#Fe?l!?BAJMax;j;f)O_^;r?;4Db44PKU#XV6@p4ypMdD%YSTU2u>4Avb!|DuIkM*rBTbnT>5*?j3r68lyqDz0Wgu&7Y z+v-oPL0bdybX@$21V)2X>$1FEGrn3h_JV4&#?t8MLDLO*dAUm`=<^4Ly{6m-@7uYF zY3ZQ&8Soa)9BMFZqNrViw2(B(z2OAZ7fko^JW?N08Hk$$ms`CPGtH9E=&&V=bovqr z%XZUC>xx9_a4=!&#wFhB#r0lW-tI2Twg>M@FQ7jXHZ4LCji#bUUUrhYkU>avPPXPJ zHQ0dJsXJv?nKq-CPU_*Yfi||^w`qm{bgI9AYG(=F>hg`=`uzGyMmTJnjx(Cf4`n7( z-TAv(_n5XB&>dEv4jFMtgKjc(k8O6XD(!LIL}M@*Hf-|W6|v1uBN`3FO*cpydd-mQ z1Y?H1GfXOiorV($Ii=0_`3+4$qgk^``HLB;eI8Kvr#6tcsGxq{0})~uvux8pAOyUd zeJmTo>nM09*-gL=9tgAL^wmpG?Ur;{WWtH4F?e+t*-F>WpRQ!`UDmDui!NY3-+N$cB zs_J@Ov#fD>eN}Z`b#>0?Hdk#i`y)=oidVIA5F2%Eb(57iMSFt&h7DvD9I@ zl>+}*@lUh7_C-(Mq`?1kQRVc_vfHG}tIfSuuh)`Wk-h2UalQvFJM2Asr+rP)FD(1! z?HB#ulns2WqW?SN6EFB)L%Hp3%P$_Q^JFPxf-RN6D F{TnMe#DV|- delta 3279 zcmajfe{7WX9l-H#TcKD=p)IXN?D{PraHV&>woqw>L1~98U_smIBw_RE-P5~=yL+DU z+;dku!%hQ=F1jcWsLQfs$`74!$>Jr%#Sn#C7Q;*o+Z-;FEgBaS6Q^_8rdj6p{@fj< z?4LE)dwrkp^E}@lpU>xek61_d=Kk1l-Eqa=4F5Or|3Q^pUHyBhTB)U6{uG<>JbsA3 z$1Xg#K&k8Tuh@tG!X4N{=LS58azD?P41E^mxpO#Qshs+p#t0q%LB>=gHA*ePJFpuk z@H==6c|k2+s8j|Fu(eF`GJeLh#Q~c zGW@dm0E6+gEG&#Nz(#Ds&B!Ba3_J1Lcn}}MOIX8T>+pSS!@9asltUQd`UPxfepS0z zsYVRp3fzXWLlb3Z_m!`6D9;^5NyTZDfzP5u;xg9bUywBvJLkb7Zp!nGDE%EM{kLFF z8k=df;t-NPWt82IvePuOSoJ7Mgr31To<`DRPMakj)*o{x2MC1*W0pCKI@LiNte2g;Q7q}h2#2fHy zglz}zLmBr4yanHGB>o{9izso8n{XWW;RE%3USgjlvFLJ^IO=DJ@^dD z@%j~3;#*Q6llq@={2v`7w}?x1fY>2d>BC zC<9+WNx^Ti58p#cO$)1wVH?VGN04Z%CsD>bh2O_ZNJMjLlEW!EOrjLiL6m_WFZUlq zqO49Kn^&(QAN3o)B-fvzy!TI(qN}FjH$$mZ79(Gin?~KFTTgA4g8CI*qcUS5U^gi1*^3 za06~#T`JNnuHpJ8xD_w1CjOG^26|k)+sY;8EP;ZEw%iIYXl7<{!|3oOWz|^V+E4 znSrz#GVF+%R6}tylF&0w#?_WR;oKL}cbhtG+MYISZKez>si!S3t_}T-J9p_x$JLRz zVaF^xR(fg5NT;VAHyTnyPAbKFXir*hN?*A{MPY1w{t?f3G( zsBNsMwaw|-hx3(neO0w1cGgH*Q65j4es{fJx2HUd8a1a)*S}of;V*31*j?^r-uw4iaV8J4Z%rfX`?VOXhV0fyC)c4ue-wo zJ?n$vzHqo^&+g!zX4XnujvXAPI0kf2xO?`wzJZ?J{A;c2D*TfR+WfD!Idf|6#U;B6 zCu1?~S;=I%;^wvY`VY20U8=agYbtIqJK@fFYNwM-8am2qEj!`3v5>yYVq>mOC#*=q z@U-dIu4&oJCa2Ab2_x#7>9n3KoN=|`dAe}Yj=J(X?PTE$m0B#mouzCWuG(fM+``F8 z&$xPfwgRs$z(-g7D1Xn&>WZfAGc4cwpE2`Kt$MAher_ddZ)VE$$JRbQryOTUre76U zx3F+H$x7Ak{my=WNkd>{*Oj%Y*%muW6;7o+Q)dmfU`07CRytw)pOUo$S4;Nez=?9n zUg*eBvTt@4W2SZ)(Ws#_Q&V$VbBa_++i?BXrmy=Sbgmp4E1XGW$z0mAyd=viMprUY z{QU^&;f$VeGYN8H*(`U$j2F&ijoH|nwr%9cgIg*)#uBcTmBNdfp0;9FhLS{O>}b|X z7@FG7PMS%7ad^nL!*Bb4>mJFE_SRPH9=;}p4DM<>Q=Y@4uua}9rkwJP5iY7bb4_sv Kt;E&hR{sTq*NX}O diff --git a/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.po index e195ad70..acace870 100644 --- a/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.po @@ -1,5 +1,5 @@ # Translations template for PROJECT. -# Copyright (C) 2011 ORGANIZATION +# Copyright (C) 2012 ORGANIZATION # This file is distributed under the same license as the PROJECT project. # # Translators: @@ -9,8 +9,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-12-04 10:24-0600\n" -"PO-Revision-Date: 2011-12-04 16:23+0000\n" +"POT-Creation-Date: 2012-01-07 13:47-0600\n" +"PO-Revision-Date: 2012-01-07 19:44+0000\n" "Last-Translator: cwebber \n" "Language-Team: Swedish (http://www.transifex.net/projects/p/mediagoblin/team/sv/)\n" "MIME-Version: 1.0\n" @@ -24,27 +24,15 @@ msgstr "" msgid "Invalid file given for media type." msgstr "Ogiltig fil för mediatypen." -#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 +#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41 msgid "Username" msgstr "Användarnamn" -#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:53 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 msgid "Password" msgstr "Lösenord" -#: mediagoblin/auth/forms.py:35 -msgid "Passwords must match." -msgstr "Lösenorden måste vara identiska." - -#: mediagoblin/auth/forms.py:37 -msgid "Confirm password" -msgstr "Bekräfta lösenord" - -#: mediagoblin/auth/forms.py:39 -msgid "Type it again here to make sure there are no spelling mistakes." -msgstr "Skriv in det igen för att undvika stavfel." - -#: mediagoblin/auth/forms.py:42 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "E-postadress" @@ -60,7 +48,7 @@ msgstr "En användare med det användarnamnet finns redan." msgid "Sorry, a user with that email address already exists." msgstr "" -#: mediagoblin/auth/views.py:179 +#: mediagoblin/auth/views.py:180 msgid "" "Your email address has been verified. You may now login, edit your profile, " "and submit images!" @@ -68,23 +56,28 @@ msgstr "" "Din e-postadress är verifierad. Du kan nu logga in, redigera din profil och " "ladda upp filer!" -#: mediagoblin/auth/views.py:185 +#: mediagoblin/auth/views.py:186 msgid "The verification key or user id is incorrect" msgstr "Verifieringsnyckeln eller användar-IDt är fel." -#: mediagoblin/auth/views.py:203 +#: mediagoblin/auth/views.py:204 msgid "You must be logged in so we know who to send the email to!" msgstr "" -#: mediagoblin/auth/views.py:211 +#: mediagoblin/auth/views.py:212 msgid "You've already verified your email address!" msgstr "" -#: mediagoblin/auth/views.py:224 +#: mediagoblin/auth/views.py:225 msgid "Resent your verification email." msgstr "Skickade ett nytt verifierings-email." -#: mediagoblin/auth/views.py:265 +#: mediagoblin/auth/views.py:260 +msgid "" +"An email has been sent with instructions on how to change your password." +msgstr "" + +#: mediagoblin/auth/views.py:270 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." @@ -92,45 +85,76 @@ msgstr "" "Kunde inte skicka e-poståterställning av lösenord eftersom ditt användarnamn" " är inaktivt eller kontots e-postadress har inte verifierats." +#: mediagoblin/auth/views.py:282 +msgid "Couldn't find someone with that username or email." +msgstr "" + +#: mediagoblin/auth/views.py:330 +msgid "You can now log in using your new password." +msgstr "" + #: mediagoblin/edit/forms.py:24 mediagoblin/submit/forms.py:27 msgid "Title" msgstr "Titel" -#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:27 mediagoblin/submit/forms.py:30 +msgid "Description of this work" +msgstr "Beskrivning av verket" + +#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:31 +msgid "" +"You can use\n" +" \n" +" Markdown for formatting." +msgstr "" + +#: mediagoblin/edit/forms.py:32 mediagoblin/submit/forms.py:35 msgid "Tags" msgstr "Taggar" -#: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 -msgid "Seperate tags by commas." +#: mediagoblin/edit/forms.py:34 mediagoblin/submit/forms.py:37 +msgid "Separate tags by commas." msgstr "" -#: mediagoblin/edit/forms.py:33 +#: mediagoblin/edit/forms.py:37 msgid "Slug" msgstr "Sökvägsnamn" -#: mediagoblin/edit/forms.py:34 +#: mediagoblin/edit/forms.py:38 msgid "The slug can't be empty" msgstr "Sökvägsnamnet kan inte vara tomt" -#: mediagoblin/edit/forms.py:35 +#: mediagoblin/edit/forms.py:39 msgid "" -"The title part of this media's URL. You usually don't need to change this." -msgstr "Sökvägstitlen för din media. Du brukar inte behöva ändra denna." +"The title part of this media's address. You usually don't need to change " +"this." +msgstr "" -#: mediagoblin/edit/forms.py:42 +#: mediagoblin/edit/forms.py:46 msgid "Bio" msgstr "Presentation" -#: mediagoblin/edit/forms.py:45 +#: mediagoblin/edit/forms.py:48 +msgid "" +"You can use\n" +" \n" +" Markdown for formatting." +msgstr "" + +#: mediagoblin/edit/forms.py:53 msgid "Website" msgstr "Hemsida" -#: mediagoblin/edit/forms.py:49 +#: mediagoblin/edit/forms.py:60 msgid "Old password" msgstr "" -#: mediagoblin/edit/forms.py:52 -msgid "New Password" +#: mediagoblin/edit/forms.py:62 +msgid "Enter your old password to prove you own this account." +msgstr "" + +#: mediagoblin/edit/forms.py:65 +msgid "New password" msgstr "" #: mediagoblin/edit/views.py:65 @@ -145,39 +169,43 @@ msgstr "Var försiktig, du redigerar någon annans inlägg." msgid "You are editing a user's profile. Proceed with caution." msgstr "Var försiktig, du redigerar en annan användares profil." -#: mediagoblin/edit/views.py:171 +#: mediagoblin/edit/views.py:174 +msgid "Profile changes saved" +msgstr "" + +#: mediagoblin/edit/views.py:200 msgid "Wrong password" msgstr "" -#: mediagoblin/edit/views.py:192 -msgid "Profile edited!" +#: mediagoblin/edit/views.py:216 +msgid "Account settings saved" msgstr "" -#: mediagoblin/media_types/__init__.py:65 -msgid "Could not find any file extension in \"{filename}\"" +#: mediagoblin/media_types/__init__.py:77 +msgid "Could not extract any file extension from \"{filename}\"" +msgstr "" + +#: mediagoblin/media_types/__init__.py:88 +msgid "Sorry, I don't support that file type :(" msgstr "" #: mediagoblin/submit/forms.py:25 msgid "File" msgstr "Fil" -#: mediagoblin/submit/forms.py:30 -msgid "Description of this work" -msgstr "Beskrivning av verket" - -#: mediagoblin/submit/views.py:49 +#: mediagoblin/submit/views.py:50 msgid "You must provide a file." msgstr "Du måste ange en fil" -#: mediagoblin/submit/views.py:127 +#: mediagoblin/submit/views.py:128 msgid "Woohoo! Submitted!" msgstr "Tjohoo! Upladdat!" -#: mediagoblin/submit/views.py:133 -msgid "Invalid file type." -msgstr "" +#: mediagoblin/templates/mediagoblin/404.html:22 +msgid "Image of 404 goblin stressing out" +msgstr "Bild av stressat 404-troll." -#: mediagoblin/templates/mediagoblin/404.html:21 +#: mediagoblin/templates/mediagoblin/404.html:23 msgid "Oops!" msgstr "Ojoj!" @@ -193,33 +221,30 @@ msgstr "" "Om du är säker på att adressen stämmer så kanske sidan du letar efter har " "flyttats eller tagits bort." -#: mediagoblin/templates/mediagoblin/404.html:32 -msgid "Image of 404 goblin stressing out" -msgstr "Bild av stressat 404-troll." - -#: mediagoblin/templates/mediagoblin/base.html:49 +#: mediagoblin/templates/mediagoblin/base.html:48 msgid "MediaGoblin logo" msgstr "MediaGoblin-logotyp" -#: mediagoblin/templates/mediagoblin/base.html:54 -msgid "Submit media" -msgstr "Ladda upp" +#: mediagoblin/templates/mediagoblin/base.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:157 +msgid "Add media" +msgstr "Lägg till media" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:64 msgid "Verify your email!" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:72 +#: mediagoblin/templates/mediagoblin/base.html:71 msgid "log out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:75 +#: mediagoblin/templates/mediagoblin/base.html:74 #: mediagoblin/templates/mediagoblin/auth/login.html:27 #: mediagoblin/templates/mediagoblin/auth/login.html:45 msgid "Log in" msgstr "Logga in" -#: mediagoblin/templates/mediagoblin/base.html:91 +#: mediagoblin/templates/mediagoblin/base.html:86 msgid "" "Powered by MediaGoblin, a GNU project" @@ -231,7 +256,7 @@ msgstr "" msgid "Explore" msgstr "Utforska" -#: mediagoblin/templates/mediagoblin/root.html:27 +#: mediagoblin/templates/mediagoblin/root.html:26 msgid "Hi there, welcome to this MediaGoblin site!" msgstr "" @@ -255,22 +280,21 @@ msgstr "" #, python-format msgid "" "Create an account at this site\n" -" or\n" -" Set up MediaGoblin on your own server" +" or\n" +" Set up MediaGoblin on your own server" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:44 +#: mediagoblin/templates/mediagoblin/root.html:40 msgid "Most recent media" msgstr "Senast medier" -#: mediagoblin/templates/mediagoblin/auth/change_fp.html:29 -msgid "Enter your new password" -msgstr "Fyll i ditt lösenord" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:32 +msgid "Set your new password" +msgstr "" -#: mediagoblin/templates/mediagoblin/auth/change_fp.html:33 -#: mediagoblin/templates/mediagoblin/submit/start.html:30 -msgid "Submit" -msgstr "Skicka" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:35 +msgid "Set password" +msgstr "" #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" @@ -280,17 +304,6 @@ msgstr "" msgid "Send instructions" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 -msgid "Your password has been changed. Try to log in now." -msgstr "Ditt lösenord är nu ändrat. Testa att logga in nu." - -#: mediagoblin/templates/mediagoblin/auth/fp_email_sent.html:22 -msgid "" -"Check your inbox. We sent an email with a URL for changing your password." -msgstr "" -"Kolla din inkorg. Vi har skickat ett e-postmeddelande med en webbadress för " -"att ändra ditt lösenord." - #: mediagoblin/templates/mediagoblin/auth/fp_verification_email.txt:19 #, python-format msgid "" @@ -329,11 +342,11 @@ msgstr "Skapa ett här!" msgid "Forgot your password?" msgstr "Glömt ditt lösenord?" -#: mediagoblin/templates/mediagoblin/auth/register.html:27 +#: mediagoblin/templates/mediagoblin/auth/register.html:32 msgid "Create an account!" msgstr "Skapa ett konto!" -#: mediagoblin/templates/mediagoblin/auth/register.html:31 +#: mediagoblin/templates/mediagoblin/auth/register.html:36 msgid "Create" msgstr "Skapa" @@ -364,10 +377,16 @@ msgid "Cancel" msgstr "Avbryt" #: mediagoblin/templates/mediagoblin/edit/edit.html:37 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:40 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:35 msgid "Save changes" msgstr "Spara ändringar" +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:34 +#, python-format +msgid "Changing %(username)s's account settings" +msgstr "" + #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29 #, python-format msgid "Editing %(username)s's profile" @@ -379,13 +398,32 @@ msgstr "Redigerar %(username)ss profil" msgid "Media tagged with: %(tag_name)s" msgstr "" -#: mediagoblin/templates/mediagoblin/media_displays/video.html:19 +#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 +#: mediagoblin/templates/mediagoblin/media_displays/video.html:46 msgid "Original" msgstr "" +#: mediagoblin/templates/mediagoblin/media_displays/video.html:33 +msgid "" +"Sorry, this video will not work because \n" +"\t your web browser does not support HTML5 \n" +"\t video." +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:36 +msgid "" +"You can get a modern web browser that \n" +"\t can play this video at \n" +"\t http://getfirefox.com!" +msgstr "" + #: mediagoblin/templates/mediagoblin/submit/start.html:26 -msgid "Submit yer media" -msgstr "Ladda upp" +msgid "Add your media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Add" +msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format @@ -397,31 +435,57 @@ msgstr "" msgid "%(username)s's media" msgstr "%(username)ss media" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:57 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:60 #, python-format -msgid "By %(username)s on %(date)s" +msgid "Added on %(date)s." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:67 -msgid "Post a comment" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:85 -msgid "at" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 -msgid "Post comment!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:124 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:69 msgid "Edit" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:130 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:73 msgid "Delete" msgstr "" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:79 +#, python-format +msgid "%(comment_count)s comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:81 +#, python-format +msgid "%(comment_count)s comments" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:83 +msgid "No comments yet." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:91 +msgid "Add one" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:100 +msgid "" +"Type your comment here. You can use Markdown for" +" formatting." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 +msgid "Add this comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:126 +msgid "at" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:141 +#, python-format +msgid "

❖ Browsing media by %(username)s

" +msgstr "" + #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -508,20 +572,24 @@ msgid "Here's a spot to tell others about yourself." msgstr "Här kan du berätta för andra om dig själv." #: mediagoblin/templates/mediagoblin/user_pages/user.html:101 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:119 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:118 msgid "Edit profile" msgstr "Redigera profil" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:107 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:106 msgid "This user hasn't filled in their profile (yet)." msgstr "Den här användaren har inte fyllt i sin profilsida ännu." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:133 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:125 +msgid "Change account settings" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:138 #, python-format msgid "View all of %(username)s's media" msgstr "Se all media från %(username)s" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:146 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:151 msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." @@ -529,11 +597,8 @@ msgstr "" "Här kommer din media att dyka upp, du verkar inte ha lagt till någonting " "ännu." -#: mediagoblin/templates/mediagoblin/user_pages/user.html:152 -msgid "Add media" -msgstr "Lägg till media" - -#: mediagoblin/templates/mediagoblin/user_pages/user.html:158 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:163 +#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72 msgid "There doesn't seem to be any media here yet..." msgstr "Det verkar inte finnas någon media här ännu." @@ -545,30 +610,36 @@ msgstr "feed-ikon" msgid "Atom feed" msgstr "Atom-feed" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:40 -msgid "Newer" -msgstr "Nyare" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:39 +msgid "← Newer" +msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:46 -msgid "Older" -msgstr "Äldre" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:45 +msgid "Older →" +msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:50 +#: mediagoblin/templates/mediagoblin/utils/pagination.html:48 msgid "Go to page:" msgstr "" +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:27 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:32 +msgid "newer" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:38 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:43 +msgid "older" +msgstr "" + #: mediagoblin/templates/mediagoblin/utils/tags.html:20 -msgid "Tagged with" +msgid "View more media tagged with" msgstr "" #: mediagoblin/templates/mediagoblin/utils/tags.html:25 -msgid "and" +msgid "or" msgstr "" -#: mediagoblin/user_pages/forms.py:24 -msgid "Comment" -msgstr "Kommentar" - #: mediagoblin/user_pages/forms.py:30 msgid "I am sure I want to delete this" msgstr "Jag är säker på att jag vill radera detta" diff --git a/mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.mo index cd9fab9fadb90228642594750d6eb0378046f61d..5480404c58fecf345eaee979ae67a755bf11bb31 100644 GIT binary patch literal 13409 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 A5dZ)H delta 3252 zcmb`{du$X%9Ki7@MOv^>+9It8b}CTY(jL761qyG z@{(vmSS9uK2Si%JBNiGH4N}1H2gWGT0BQtt8Y4!757a0j0l&Yyt*>Y>f#!Oj+1c5d z+28Ls_j%*SMX}Ga`#!JuYvq49|6iuc)t`TR)07&*H?sxMgQy)SZcNF_66;r>_sHNiyGN-B?pwwWzAN^R5tMNJH0hM{9QrS2Z zWn3{zf0fr?jd@(x;V=y0t+)yMVkc(cUd&~E^`YdMy66Z=)>D^2Fe?nC~vmP zyN;oZ+lrEk4wQ)xp+w>=X5n|p9ul25z(8)w_#Bk}5|sXl7?Z{wG)7%EEvWUNg^dKDz@CZuL z%j95H(IlshLGye?3YBo3RGhp={uI zjK&livdw#8D$=FaVHLiF5~|ZE#q>Q&s&1ik8BWFuY)3g>?_wW3fgC9HA<9P1;Jy@& zH}XzuD`Ay&Vx2V3(da>W(~et`51z(KuHz`7%jL&m0@kBU+>Wx~4wP{n$WV0_IFLk&pU`FG+1S6)446jdFi6N<MA^uBO#C9EY%p(hG8L0hHW)$~AH%-bjtlS=l$!YkC8A>rlgIgClv;2Ki9bFrylSMfnW#a8P5#LA2dB39MF`R&PT+hd~xCf=k zON*0{SW-;<Yp@e#1K*28|V;m823-N*Cy z^sf#Eb;t}_hWnnbb{7eg^`L|b-! zc$H5tFtuaaQEk}T3>j9FZn2_`+RzU@Fk7z(M|7akup2D9A^Ffs!*N=|k)Ti2ghL^o zLwki43F+QDbTl^wwH+QF)hjGJ$i%HQnoMo3ikh}#u`A1V(=s-9AIr!|$*|3qKc4OG zGpI5(qt<@RXtIKdhg^S_J7}J_sG4K8m=X7ER*8FK_9Va8>*!Fk6V)Lj8ff&Xd12ay z4tTpuTzVG;ZgqAfjX*`sV1auid*e-Jgy86?(ctL%*2FW0<8!-8OgB0v%bh#sg|W@` zAuFmLOppw6??tN_@jB{^h6Xd3h?`qmx-ON-b)PK#GR57P8=Gvgn+C(Ob)y+!sWAI| zl!!OWMWV}~Wrwx1(rjvyFo!HB$`HqG%bV_gocE0z8Fp9q$Z>;HW-XMg^@dqD8f@A$ z?PP+?pikFDT4jNza03Bm&K93C?4UBDYK6)EtU%aSax>fsBa U)8`t>wP)sYSpcUU@\n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -23,27 +23,15 @@ msgstr "" msgid "Invalid file given for media type." msgstr "" -#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:49 +#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41 msgid "Username" msgstr "వాడుకరి పేరు" -#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:53 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 msgid "Password" msgstr "సంకేతపదం" -#: mediagoblin/auth/forms.py:35 -msgid "Passwords must match." -msgstr "" - -#: mediagoblin/auth/forms.py:37 -msgid "Confirm password" -msgstr "" - -#: mediagoblin/auth/forms.py:39 -msgid "Type it again here to make sure there are no spelling mistakes." -msgstr "" - -#: mediagoblin/auth/forms.py:42 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "ఈమెయిలు చిరునామా" @@ -59,73 +47,109 @@ msgstr "" msgid "Sorry, a user with that email address already exists." msgstr "" -#: mediagoblin/auth/views.py:179 +#: mediagoblin/auth/views.py:180 msgid "" "Your email address has been verified. You may now login, edit your profile, " "and submit images!" msgstr "" -#: mediagoblin/auth/views.py:185 +#: mediagoblin/auth/views.py:186 msgid "The verification key or user id is incorrect" msgstr "" -#: mediagoblin/auth/views.py:203 +#: mediagoblin/auth/views.py:204 msgid "You must be logged in so we know who to send the email to!" msgstr "" -#: mediagoblin/auth/views.py:211 +#: mediagoblin/auth/views.py:212 msgid "You've already verified your email address!" msgstr "" -#: mediagoblin/auth/views.py:224 +#: mediagoblin/auth/views.py:225 msgid "Resent your verification email." msgstr "" -#: mediagoblin/auth/views.py:265 +#: mediagoblin/auth/views.py:260 +msgid "" +"An email has been sent with instructions on how to change your password." +msgstr "" + +#: mediagoblin/auth/views.py:270 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." msgstr "" +#: mediagoblin/auth/views.py:282 +msgid "Couldn't find someone with that username or email." +msgstr "" + +#: mediagoblin/auth/views.py:330 +msgid "You can now log in using your new password." +msgstr "" + #: mediagoblin/edit/forms.py:24 mediagoblin/submit/forms.py:27 msgid "Title" msgstr "శీర్షిక" -#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:27 mediagoblin/submit/forms.py:30 +msgid "Description of this work" +msgstr "" + +#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:31 +msgid "" +"You can use\n" +" \n" +" Markdown for formatting." +msgstr "" + +#: mediagoblin/edit/forms.py:32 mediagoblin/submit/forms.py:35 msgid "Tags" msgstr "" -#: mediagoblin/edit/forms.py:30 mediagoblin/submit/forms.py:34 -msgid "Seperate tags by commas." +#: mediagoblin/edit/forms.py:34 mediagoblin/submit/forms.py:37 +msgid "Separate tags by commas." msgstr "" -#: mediagoblin/edit/forms.py:33 +#: mediagoblin/edit/forms.py:37 msgid "Slug" msgstr "" -#: mediagoblin/edit/forms.py:34 +#: mediagoblin/edit/forms.py:38 msgid "The slug can't be empty" msgstr "" -#: mediagoblin/edit/forms.py:35 +#: mediagoblin/edit/forms.py:39 msgid "" -"The title part of this media's URL. You usually don't need to change this." +"The title part of this media's address. You usually don't need to change " +"this." msgstr "" -#: mediagoblin/edit/forms.py:42 +#: mediagoblin/edit/forms.py:46 msgid "Bio" msgstr "" -#: mediagoblin/edit/forms.py:45 +#: mediagoblin/edit/forms.py:48 +msgid "" +"You can use\n" +" \n" +" Markdown for formatting." +msgstr "" + +#: mediagoblin/edit/forms.py:53 msgid "Website" msgstr "" -#: mediagoblin/edit/forms.py:49 +#: mediagoblin/edit/forms.py:60 msgid "Old password" msgstr "" -#: mediagoblin/edit/forms.py:52 -msgid "New Password" +#: mediagoblin/edit/forms.py:62 +msgid "Enter your old password to prove you own this account." +msgstr "" + +#: mediagoblin/edit/forms.py:65 +msgid "New password" msgstr "" #: mediagoblin/edit/views.py:65 @@ -140,39 +164,43 @@ msgstr "" msgid "You are editing a user's profile. Proceed with caution." msgstr "" -#: mediagoblin/edit/views.py:171 +#: mediagoblin/edit/views.py:174 +msgid "Profile changes saved" +msgstr "" + +#: mediagoblin/edit/views.py:200 msgid "Wrong password" msgstr "" -#: mediagoblin/edit/views.py:192 -msgid "Profile edited!" +#: mediagoblin/edit/views.py:216 +msgid "Account settings saved" msgstr "" -#: mediagoblin/media_types/__init__.py:65 -msgid "Could not find any file extension in \"{filename}\"" +#: mediagoblin/media_types/__init__.py:77 +msgid "Could not extract any file extension from \"{filename}\"" +msgstr "" + +#: mediagoblin/media_types/__init__.py:88 +msgid "Sorry, I don't support that file type :(" msgstr "" #: mediagoblin/submit/forms.py:25 msgid "File" msgstr "" -#: mediagoblin/submit/forms.py:30 -msgid "Description of this work" -msgstr "" - -#: mediagoblin/submit/views.py:49 +#: mediagoblin/submit/views.py:50 msgid "You must provide a file." msgstr "" -#: mediagoblin/submit/views.py:127 +#: mediagoblin/submit/views.py:128 msgid "Woohoo! Submitted!" msgstr "" -#: mediagoblin/submit/views.py:133 -msgid "Invalid file type." +#: mediagoblin/templates/mediagoblin/404.html:22 +msgid "Image of 404 goblin stressing out" msgstr "" -#: mediagoblin/templates/mediagoblin/404.html:21 +#: mediagoblin/templates/mediagoblin/404.html:23 msgid "Oops!" msgstr "" @@ -186,33 +214,30 @@ msgid "" " been moved or deleted." msgstr "" -#: mediagoblin/templates/mediagoblin/404.html:32 -msgid "Image of 404 goblin stressing out" -msgstr "" - -#: mediagoblin/templates/mediagoblin/base.html:49 +#: mediagoblin/templates/mediagoblin/base.html:48 msgid "MediaGoblin logo" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:54 -msgid "Submit media" +#: mediagoblin/templates/mediagoblin/base.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:157 +msgid "Add media" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:64 msgid "Verify your email!" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:72 +#: mediagoblin/templates/mediagoblin/base.html:71 msgid "log out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:75 +#: mediagoblin/templates/mediagoblin/base.html:74 #: mediagoblin/templates/mediagoblin/auth/login.html:27 #: mediagoblin/templates/mediagoblin/auth/login.html:45 msgid "Log in" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:91 +#: mediagoblin/templates/mediagoblin/base.html:86 msgid "" "Powered by MediaGoblin, a GNU project" @@ -222,7 +247,7 @@ msgstr "" msgid "Explore" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:27 +#: mediagoblin/templates/mediagoblin/root.html:26 msgid "Hi there, welcome to this MediaGoblin site!" msgstr "" @@ -246,22 +271,21 @@ msgstr "" #, python-format msgid "" "Create an account at this site\n" -" or\n" -" Set up MediaGoblin on your own server" +" or\n" +" Set up MediaGoblin on your own server" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:44 +#: mediagoblin/templates/mediagoblin/root.html:40 msgid "Most recent media" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/change_fp.html:29 -msgid "Enter your new password" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:32 +msgid "Set your new password" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/change_fp.html:33 -#: mediagoblin/templates/mediagoblin/submit/start.html:30 -msgid "Submit" -msgstr "దాఖలు చెయ్యి" +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:35 +msgid "Set password" +msgstr "" #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27 msgid "Recover password" @@ -271,15 +295,6 @@ msgstr "" msgid "Send instructions" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/fp_changed_success.html:22 -msgid "Your password has been changed. Try to log in now." -msgstr "" - -#: mediagoblin/templates/mediagoblin/auth/fp_email_sent.html:22 -msgid "" -"Check your inbox. We sent an email with a URL for changing your password." -msgstr "" - #: mediagoblin/templates/mediagoblin/auth/fp_verification_email.txt:19 #, python-format msgid "" @@ -310,11 +325,11 @@ msgstr "" msgid "Forgot your password?" msgstr "మీ సంకేతపదాన్ని మర్చిపోయారా?" -#: mediagoblin/templates/mediagoblin/auth/register.html:27 +#: mediagoblin/templates/mediagoblin/auth/register.html:32 msgid "Create an account!" msgstr "" -#: mediagoblin/templates/mediagoblin/auth/register.html:31 +#: mediagoblin/templates/mediagoblin/auth/register.html:36 msgid "Create" msgstr "" @@ -340,10 +355,16 @@ msgid "Cancel" msgstr "రద్దుచేయి" #: mediagoblin/templates/mediagoblin/edit/edit.html:37 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:40 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:35 msgid "Save changes" msgstr "మార్పులను భద్రపరచు" +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:34 +#, python-format +msgid "Changing %(username)s's account settings" +msgstr "" + #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29 #, python-format msgid "Editing %(username)s's profile" @@ -355,12 +376,31 @@ msgstr "" msgid "Media tagged with: %(tag_name)s" msgstr "" -#: mediagoblin/templates/mediagoblin/media_displays/video.html:19 +#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 +#: mediagoblin/templates/mediagoblin/media_displays/video.html:46 msgid "Original" msgstr "" +#: mediagoblin/templates/mediagoblin/media_displays/video.html:33 +msgid "" +"Sorry, this video will not work because \n" +"\t your web browser does not support HTML5 \n" +"\t video." +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:36 +msgid "" +"You can get a modern web browser that \n" +"\t can play this video at \n" +"\t http://getfirefox.com!" +msgstr "" + #: mediagoblin/templates/mediagoblin/submit/start.html:26 -msgid "Submit yer media" +msgid "Add your media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Add" msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 @@ -373,31 +413,57 @@ msgstr "" msgid "%(username)s's media" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:57 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:60 #, python-format -msgid "By %(username)s on %(date)s" +msgid "Added on %(date)s." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:67 -msgid "Post a comment" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:85 -msgid "at" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 -msgid "Post comment!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:124 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:69 msgid "Edit" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:130 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:73 msgid "Delete" msgstr "" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:79 +#, python-format +msgid "%(comment_count)s comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:81 +#, python-format +msgid "%(comment_count)s comments" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:83 +msgid "No comments yet." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:91 +msgid "Add one" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:100 +msgid "" +"Type your comment here. You can use Markdown for" +" formatting." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 +msgid "Add this comment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:126 +msgid "at" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:141 +#, python-format +msgid "

❖ Browsing media by %(username)s

" +msgstr "" + #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 #, python-format msgid "Really delete %(title)s?" @@ -478,30 +544,31 @@ msgid "Here's a spot to tell others about yourself." msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/user.html:101 -#: mediagoblin/templates/mediagoblin/user_pages/user.html:119 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:118 msgid "Edit profile" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:107 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:106 msgid "This user hasn't filled in their profile (yet)." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:133 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:125 +msgid "Change account settings" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:138 #, python-format msgid "View all of %(username)s's media" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:146 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:151 msgid "" "This is where your media will appear, but you don't seem to have added " "anything yet." msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/user.html:152 -msgid "Add media" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/user.html:158 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:163 +#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72 msgid "There doesn't seem to be any media here yet..." msgstr "" @@ -513,30 +580,36 @@ msgstr "" msgid "Atom feed" msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:40 -msgid "Newer" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:39 +msgid "← Newer" msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:46 -msgid "Older" +#: mediagoblin/templates/mediagoblin/utils/pagination.html:45 +msgid "Older →" msgstr "" -#: mediagoblin/templates/mediagoblin/utils/pagination.html:50 +#: mediagoblin/templates/mediagoblin/utils/pagination.html:48 msgid "Go to page:" msgstr "" +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:27 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:32 +msgid "newer" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:38 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:43 +msgid "older" +msgstr "" + #: mediagoblin/templates/mediagoblin/utils/tags.html:20 -msgid "Tagged with" +msgid "View more media tagged with" msgstr "" #: mediagoblin/templates/mediagoblin/utils/tags.html:25 -msgid "and" +msgid "or" msgstr "" -#: mediagoblin/user_pages/forms.py:24 -msgid "Comment" -msgstr "వ్యాఖ్య" - #: mediagoblin/user_pages/forms.py:30 msgid "I am sure I want to delete this" msgstr "" diff --git a/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.mo index 6dda94b7975f56d456852f9232e5429a7087c0ba..a7820c4976fd0473368677bed411cb037dfdf3c8 100644 GIT binary patch delta 1359 zcmYk*TWpj?6u|LAivyX30qSUT!gcw619QWFaz!QRn&tzjfYVi_yqN4aT90F{8iMK_!;%- ze?={P$K)TX@bepuTT$nmP5d(Ix#9f`^q>%G!S_)c8NhcjhPrVHUFcI*p{{!lb=@A+ zo9#FGKI2EIH~hlH-(nl_6zVtgk8fD2Hi^)*>_eS+54E$Cs0W=zEo7PaikZKTTJWZs zudNb!hWL4;whW-wo5X7T3AN6D*okXM_VfM8hYXrY{EH>nxLM=~?!Y>nLA~h>)B+2r z1((+N>+4ZJ#>Y_`-i7|%_e-l62c3A%x>ok$q7r*>vXDqdYXh&9 zxU(rQHx(TXSS!3)%O0FAoa%RCa|^j~t8K%r;(#3+TF8y$FP(D7KXqdXFBNgVo^mJV z32#L{jS-#7j{Hl;1b0U-O=-lSrp{|~e7y8~f&~vb+ z<*|;ZYlHc0oJR6<5j!&MWd^(p<8IPoag3D2#JAnBZ#HHAaT5uoIgAAdC zPfh$I(zASbN8^c-J@E}Z#zNEtUQEGC)Q)Pg6VKxmE?@~xTJeN`P}eio(-dAnKJt~X zbWGhK!rtOSEubRGKs!EyEAgnY4Yh#NsGVIl^G9a=CF)7MM?Lx()WqLRJS{IC&oSmB zhbcZYuSMNATF*c?YQz;7#xz~PQ+NqA@juj~bW@FPT!vck9@Nh2O}xbzLGAFInGfK8 z=A)>0=4affxC=xmTK1tXw4qjZ4RxbisEO{H`3tlD8a3gxS3j?@<;92gUbTHUK;3p2gv)URwUB$U zv1RkC()?ckHt*K$mcO)oTZuE6z19=xwws&n4y(cpDuZ2}k)A+Xs4M6Tb+p9ZWWP;t zo+s~&ea@{}l2m24*%90Ex*L~P2U{afzdM$)H)KUZR=BCfE{`4Zd`WcGg~FX%te#L; zhZP95x7#NpR(DgUWw(bTJwE4fUV+n_?n<1$^1!*D?ss10O*q4=vSY*f(+SSQHRocB kMRN(xx-7TzchjBBridK3?cnUqtMen{GJoUA?8R~U55S Date: Thu, 5 Jan 2012 00:18:17 +0100 Subject: [PATCH 283/302] Add DB Mixin classes and use them A bunch of functions on the db objects are really more like "utility functions": They could live outside the classes and be called "by hand" passing the appropiate reference. They usually only use the public API of the object and rarely use database related stuff. Goals: - First, simple: Share the code with the SQL objects, so that the code doesn't need to be duplicated. - Second, it might unclutter the db models and make them more into "model only" stuff. - Doesn't really hurt. --- mediagoblin/db/mixin.py | 90 ++++++++++++++++++++++++++++++++++ mediagoblin/db/mongo/models.py | 63 ++---------------------- mediagoblin/db/sql/models.py | 5 +- 3 files changed, 97 insertions(+), 61 deletions(-) create mode 100644 mediagoblin/db/mixin.py diff --git a/mediagoblin/db/mixin.py b/mediagoblin/db/mixin.py new file mode 100644 index 00000000..4fb325d2 --- /dev/null +++ b/mediagoblin/db/mixin.py @@ -0,0 +1,90 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011,2012 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +""" +This module contains some Mixin classes for the db objects. + +A bunch of functions on the db objects are really more like +"utility functions": They could live outside the classes +and be called "by hand" passing the appropiate reference. +They usually only use the public API of the object and +rarely use database related stuff. + +These functions now live here and get "mixed in" into the +real objects. +""" + +from mediagoblin.auth import lib as auth_lib +from mediagoblin.tools import common + + +class UserMixin(object): + def check_login(self, password): + """ + See if a user can login with this password + """ + return auth_lib.bcrypt_check_password( + password, self.pw_hash) + + +class MediaEntryMixin(object): + def get_display_media(self, media_map, + fetch_order=common.DISPLAY_IMAGE_FETCHING_ORDER): + """ + Find the best media for display. + + Args: + - media_map: a dict like + {u'image_size': [u'dir1', u'dir2', u'image.jpg']} + - fetch_order: the order we should try fetching images in + + Returns: + (media_size, media_path) + """ + media_sizes = media_map.keys() + + for media_size in common.DISPLAY_IMAGE_FETCHING_ORDER: + if media_size in media_sizes: + return media_map[media_size] + + def main_mediafile(self): + pass + + def url_for_self(self, urlgen): + """ + Generate an appropriate url for ourselves + + Use a slug if we have one, else use our '_id'. + """ + uploader = self.get_uploader + + if self.get('slug'): + return urlgen( + 'mediagoblin.user_pages.media_home', + user=uploader.username, + media=self.slug) + else: + return urlgen( + 'mediagoblin.user_pages.media_home', + user=uploader.username, + media=unicode(self._id)) + + def get_fail_exception(self): + """ + Get the exception that's appropriate for this error + """ + if self['fail_error']: + return common.import_component(self['fail_error']) diff --git a/mediagoblin/db/mongo/models.py b/mediagoblin/db/mongo/models.py index 5de59c12..906d2849 100644 --- a/mediagoblin/db/mongo/models.py +++ b/mediagoblin/db/mongo/models.py @@ -18,12 +18,12 @@ import datetime from mongokit import Document -from mediagoblin.auth import lib as auth_lib from mediagoblin import mg_globals from mediagoblin.db.mongo import migrations from mediagoblin.db.mongo.util import ASCENDING, DESCENDING, ObjectId from mediagoblin.tools.pagination import Pagination -from mediagoblin.tools import url, common +from mediagoblin.tools import url +from mediagoblin.db.mixin import UserMixin, MediaEntryMixin ################### # Custom validators @@ -34,7 +34,7 @@ from mediagoblin.tools import url, common ######## -class User(Document): +class User(Document, UserMixin): """ A user of MediaGoblin. @@ -89,15 +89,8 @@ class User(Document): 'status': u'needs_email_verification', 'is_admin': False} - def check_login(self, password): - """ - See if a user can login with this password - """ - return auth_lib.bcrypt_check_password( - password, self.pw_hash) - -class MediaEntry(Document): +class MediaEntry(Document, MediaEntryMixin): """ Record of a piece of media. @@ -224,28 +217,6 @@ class MediaEntry(Document): return self.db.MediaComment.find({ 'media_entry': self._id}).sort('created', order) - def get_display_media(self, media_map, - fetch_order=common.DISPLAY_IMAGE_FETCHING_ORDER): - """ - Find the best media for display. - - Args: - - media_map: a dict like - {u'image_size': [u'dir1', u'dir2', u'image.jpg']} - - fetch_order: the order we should try fetching images in - - Returns: - (media_size, media_path) - """ - media_sizes = media_map.keys() - - for media_size in common.DISPLAY_IMAGE_FETCHING_ORDER: - if media_size in media_sizes: - return media_map[media_size] - - def main_mediafile(self): - pass - def generate_slug(self): self.slug = url.slugify(self.title) @@ -255,25 +226,6 @@ class MediaEntry(Document): if duplicate: self.slug = "%s-%s" % (self._id, self.slug) - def url_for_self(self, urlgen): - """ - Generate an appropriate url for ourselves - - Use a slug if we have one, else use our '_id'. - """ - uploader = self.get_uploader - - if self.get('slug'): - return urlgen( - 'mediagoblin.user_pages.media_home', - user=uploader.username, - media=self.slug) - else: - return urlgen( - 'mediagoblin.user_pages.media_home', - user=uploader.username, - media=unicode(self._id)) - def url_to_prev(self, urlgen): """ Provide a url to the previous entry from this user, if there is one @@ -301,13 +253,6 @@ class MediaEntry(Document): def get_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 common.import_component(self['fail_error']) - class MediaComment(Document): """ diff --git a/mediagoblin/db/sql/models.py b/mediagoblin/db/sql/models.py index 31a6ed3b..95821b4f 100644 --- a/mediagoblin/db/sql/models.py +++ b/mediagoblin/db/sql/models.py @@ -7,6 +7,7 @@ from sqlalchemy import ( from sqlalchemy.orm import relationship from mediagoblin.db.sql.base import GMGTableBase +from mediagoblin.db.mixin import UserMixin, MediaEntryMixin Base = declarative_base(cls=GMGTableBase) @@ -24,7 +25,7 @@ class SimpleFieldAlias(object): setattr(instance, self.fieldname, val) -class User(Base): +class User(Base, UserMixin): __tablename__ = "users" id = Column(Integer, primary_key=True) @@ -48,7 +49,7 @@ class User(Base): _id = SimpleFieldAlias("id") -class MediaEntry(Base): +class MediaEntry(Base, MediaEntryMixin): __tablename__ = "media_entries" id = Column(Integer, primary_key=True) From 7cbbf3e75b2dc67068ec270e53249d95224a86cc Mon Sep 17 00:00:00 2001 From: Elrond Date: Mon, 9 Jan 2012 14:22:28 +0100 Subject: [PATCH 284/302] Create a default logging config paste uses paste.ini to configure python's logging module. Until now, there was NO config, not even a useful default one. This means: any messages went away unseen. Not good. The new default logs everything to stderr at level INFO and higher. Maybe not the best, but a good starting point. --- paste.ini | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/paste.ini b/paste.ini index c729e41d..13c15209 100644 --- a/paste.ini +++ b/paste.ini @@ -19,6 +19,28 @@ use = egg:mediagoblin#app filter-with = beaker config = %(here)s/mediagoblin_local.ini %(here)s/mediagoblin.ini +[loggers] +keys = root + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = INFO +handlers = console + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(asctime)s %(levelname)-7.7s [%(name)s] %(message)s + [app:publicstore_serve] use = egg:Paste#static document_root = %(here)s/user_dev/media/public/ From 1b876ac2ea58830b187463dd3de75299fa257212 Mon Sep 17 00:00:00 2001 From: Elrond Date: Mon, 9 Jan 2012 14:26:01 +0100 Subject: [PATCH 285/302] Warn about unknown staticdirect paths. Use pkg_resource to check for the existence of any files referenced by staticdirect. If they don't exist, warn about this. This might raise false warnings in the future for more advanced setups. --- mediagoblin/staticdirect.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/mediagoblin/staticdirect.py b/mediagoblin/staticdirect.py index c6d2b374..2bddb160 100644 --- a/mediagoblin/staticdirect.py +++ b/mediagoblin/staticdirect.py @@ -14,9 +14,6 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -import pkg_resources -import urlparse - #################################### # Staticdirect infrastructure. # Borrowed largely from cc.engine @@ -26,7 +23,9 @@ import urlparse #################################### import pkg_resources -import urlparse +import logging + +_log = logging.getLogger(__name__) class StaticDirect(object): @@ -37,6 +36,10 @@ class StaticDirect(object): if filepath in self.cache: return self.cache[filepath] + if not pkg_resources.resource_exists('mediagoblin', + 'static' + filepath): + _log.info("StaticDirect resource %r not found locally", + filepath) static_direction = self.cache[filepath] = self.get(filepath) return static_direction From 1dc7f28d2476135f9548a92ec1147659f1a4e810 Mon Sep 17 00:00:00 2001 From: Elrond Date: Mon, 9 Jan 2012 14:33:57 +0100 Subject: [PATCH 286/302] Fix reset.css reference and drop link to video-js.css 1. reset.css was moved to /css/extlib/ some time ago. So update the staticdirect link to it. 2. We don't have video-js.css (any more?). Drop link to it. --- mediagoblin/templates/mediagoblin/base.html | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/mediagoblin/templates/mediagoblin/base.html b/mediagoblin/templates/mediagoblin/base.html index 82ee41b7..5335ebe3 100644 --- a/mediagoblin/templates/mediagoblin/base.html +++ b/mediagoblin/templates/mediagoblin/base.html @@ -22,11 +22,9 @@ {% block title %}{{ app_config['html_title'] }}{% endblock %} + href="{{ request.staticdirect('/css/extlib/reset.css') }}"/> - From c2d6792ddb8d968e0c93a7cdd1da7bdae3b5fa36 Mon Sep 17 00:00:00 2001 From: Elrond Date: Tue, 10 Jan 2012 12:52:01 +0100 Subject: [PATCH 287/302] Test Suite: Enable attachments, add failing test attachments are an optional part. But it doesn't hurt to enable them in the test suite at all. Also (with enabled attachmemtns) the main media view fails, if one isn't logged in (joar found it!). So add a simple (currently failing) test for this. --- mediagoblin/tests/test_mgoblin_app.ini | 3 +++ mediagoblin/tests/test_submission.py | 14 ++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/mediagoblin/tests/test_mgoblin_app.ini b/mediagoblin/tests/test_mgoblin_app.ini index 2525a4f9..c91ed92b 100644 --- a/mediagoblin/tests/test_mgoblin_app.ini +++ b/mediagoblin/tests/test_mgoblin_app.ini @@ -7,6 +7,9 @@ db_name = __mediagoblin_tests__ # tag parsing tags_max_length = 50 +# So we can start to test attachments: +allow_attachments = True + # Celery shouldn't be set up by the application as it's setup via # mediagoblin.init.celery.from_celery celery_setup_elsewhere = true diff --git a/mediagoblin/tests/test_submission.py b/mediagoblin/tests/test_submission.py index 2b17c515..b3c11249 100644 --- a/mediagoblin/tests/test_submission.py +++ b/mediagoblin/tests/test_submission.py @@ -51,11 +51,17 @@ class TestSubmission: self.test_user = test_user + self.login() + + def login(self): self.test_app.post( '/auth/login/', { 'username': u'chris', 'password': 'toast'}) + def logout(self): + self.test_app.get('/auth/logout/') + def test_missing_fields(self): # Test blank form # --------------- @@ -95,6 +101,14 @@ class TestSubmission: assert template.TEMPLATE_TEST_CONTEXT.has_key( 'mediagoblin/user_pages/user.html') + # Make sure the media view is at least reachable, logged in... + self.test_app.get('/u/chris/m/normal-upload-1/') + # ... and logged out too. + self.logout() + self.test_app.get('/u/chris/m/normal-upload-1/') + # Log back in for the remaining tests. + self.login() + # Test PNG # -------- template.clear_test_template_context() From 914b8bcde3e01c2dd3e5679fb7733fc194b34d68 Mon Sep 17 00:00:00 2001 From: Joar Wandborg Date: Tue, 10 Jan 2012 13:12:14 +0100 Subject: [PATCH 288/302] Added check for request.user to media.html attachment-related conditional --- mediagoblin/templates/mediagoblin/user_pages/media.html | 1 + 1 file changed, 1 insertion(+) diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html index 10525f4c..583e4ebd 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media.html @@ -158,6 +158,7 @@ {% endif %} {% if app_config['allow_attachments'] + and request.user and (media.uploader == request.user._id or request.user.is_admin) %}

From 1df68a3524d92caee5601a8acc011ac8e1fe16d4 Mon Sep 17 00:00:00 2001 From: Michele Azzolari Date: Thu, 5 Jan 2012 18:48:23 +0100 Subject: [PATCH 289/302] Fixed #724 and added extra infos to the atom feed (author uri and links to the html version of each entry) --- mediagoblin/db/mongo/models.py | 8 +++++--- mediagoblin/listings/views.py | 24 ++++++++++++++++++++---- mediagoblin/user_pages/views.py | 28 ++++++++++++++++++++++++---- 3 files changed, 49 insertions(+), 11 deletions(-) diff --git a/mediagoblin/db/mongo/models.py b/mediagoblin/db/mongo/models.py index 5de59c12..f1e8eae6 100644 --- a/mediagoblin/db/mongo/models.py +++ b/mediagoblin/db/mongo/models.py @@ -255,7 +255,7 @@ class MediaEntry(Document): if duplicate: self.slug = "%s-%s" % (self._id, self.slug) - def url_for_self(self, urlgen): + def url_for_self(self, urlgen, **extra_args): """ Generate an appropriate url for ourselves @@ -267,12 +267,14 @@ class MediaEntry(Document): return urlgen( 'mediagoblin.user_pages.media_home', user=uploader.username, - media=self.slug) + media=self.slug, + **extra_args) else: return urlgen( 'mediagoblin.user_pages.media_home', user=uploader.username, - media=unicode(self._id)) + media=unicode(self._id), + **extra_args) def url_to_prev(self, urlgen): """ diff --git a/mediagoblin/listings/views.py b/mediagoblin/listings/views.py index 3ecf06f4..ca8e8229 100644 --- a/mediagoblin/listings/views.py +++ b/mediagoblin/listings/views.py @@ -77,17 +77,33 @@ def tag_atom_feed(request): cursor = cursor.sort('created', DESCENDING) cursor = cursor.limit(ATOM_DEFAULT_NR_OF_UPDATED_ITEMS) + """ + ATOM feed id is a tag URI (see http://en.wikipedia.org/wiki/Tag_URI) + """ feed = AtomFeed( "MediaGoblin: Feed for tag '%s'" % tag_slug, feed_url=request.url, - url=request.host_url) - + id='tag:'+request.host+',2011:gallery.tag-%s' % tag_slug, + links=[{'href': request.urlgen( + 'mediagoblin.listings.tags_listing', + qualified=True, tag=tag_slug ), + 'rel': 'alternate', + 'type': 'text/html'}]) for entry in cursor: feed.add(entry.get('title'), entry.get('description_html'), + id=entry.url_for_self(request.urlgen,qualified=True), content_type='html', - author=entry.get_uploader.username, + author={'name': entry.get_uploader.username, + 'uri': request.urlgen( + 'mediagoblin.user_pages.user_home', + qualified=True, user=entry.get_uploader.username)}, updated=entry.get('created'), - url=entry.url_for_self(request.urlgen)) + links=[{ + 'href':entry.url_for_self( + request.urlgen, + qualified=True), + 'rel': 'alternate', + 'type': 'text/html'}]) return feed.get_response() diff --git a/mediagoblin/user_pages/views.py b/mediagoblin/user_pages/views.py index f721f012..a234722f 100644 --- a/mediagoblin/user_pages/views.py +++ b/mediagoblin/user_pages/views.py @@ -225,17 +225,37 @@ def atom_feed(request): .sort('created', DESCENDING) \ .limit(ATOM_DEFAULT_NR_OF_UPDATED_ITEMS) - feed = AtomFeed(request.matchdict['user'], + """ + ATOM feed id is a tag URI (see http://en.wikipedia.org/wiki/Tag_URI) + """ + feed = AtomFeed( + "MediaGoblin: Feed for user '%s'" % request.matchdict['user'], feed_url=request.url, - url=request.host_url) + id='tag:'+request.host+',2011:gallery.user-'+request.matchdict['user'], + links=[{ + 'href': request.urlgen( + 'mediagoblin.user_pages.user_home', + qualified=True,user=request.matchdict['user']), + 'rel': 'alternate', + 'type': 'text/html'}]) for entry in cursor: feed.add(entry.get('title'), entry.get('description_html'), + id=entry.url_for_self(request.urlgen,qualified=True), content_type='html', - author=request.matchdict['user'], + author={ + 'name': entry.get_uploader.username, + 'uri': request.urlgen( + 'mediagoblin.user_pages.user_home', + qualified=True, user=entry.get_uploader.username)}, updated=entry.get('created'), - url=entry.url_for_self(request.urlgen)) + links=[{ + 'href': entry.url_for_self( + request.urlgen, + qualified=True), + 'rel': 'alternate', + 'type': 'text/html'}]) return feed.get_response() From cb7ae1e4331f3521b2028388c3d4ff2555d61eb3 Mon Sep 17 00:00:00 2001 From: Elrond Date: Wed, 11 Jan 2012 11:16:35 +0100 Subject: [PATCH 290/302] Fix url_for_self mixup Move changes from mongo/models:url_for_self back into mixin:url_for_self. --- mediagoblin/db/mixin.py | 8 +++++--- mediagoblin/db/mongo/models.py | 21 --------------------- 2 files changed, 5 insertions(+), 24 deletions(-) diff --git a/mediagoblin/db/mixin.py b/mediagoblin/db/mixin.py index 4fb325d2..5145289e 100644 --- a/mediagoblin/db/mixin.py +++ b/mediagoblin/db/mixin.py @@ -63,7 +63,7 @@ class MediaEntryMixin(object): def main_mediafile(self): pass - def url_for_self(self, urlgen): + def url_for_self(self, urlgen, **extra_args): """ Generate an appropriate url for ourselves @@ -75,12 +75,14 @@ class MediaEntryMixin(object): return urlgen( 'mediagoblin.user_pages.media_home', user=uploader.username, - media=self.slug) + media=self.slug, + **extra_args) else: return urlgen( 'mediagoblin.user_pages.media_home', user=uploader.username, - media=unicode(self._id)) + media=unicode(self._id), + **extra_args) def get_fail_exception(self): """ diff --git a/mediagoblin/db/mongo/models.py b/mediagoblin/db/mongo/models.py index d9b5a570..906d2849 100644 --- a/mediagoblin/db/mongo/models.py +++ b/mediagoblin/db/mongo/models.py @@ -226,27 +226,6 @@ class MediaEntry(Document, MediaEntryMixin): if duplicate: self.slug = "%s-%s" % (self._id, self.slug) - def url_for_self(self, urlgen, **extra_args): - """ - Generate an appropriate url for ourselves - - Use a slug if we have one, else use our '_id'. - """ - uploader = self.get_uploader - - if self.get('slug'): - return urlgen( - 'mediagoblin.user_pages.media_home', - user=uploader.username, - media=self.slug, - **extra_args) - else: - return urlgen( - 'mediagoblin.user_pages.media_home', - user=uploader.username, - media=unicode(self._id), - **extra_args) - def url_to_prev(self, urlgen): """ Provide a url to the previous entry from this user, if there is one From 0ab21f981a8a170f5bf4e83f7d56d3ed8fdae467 Mon Sep 17 00:00:00 2001 From: Elrond Date: Sun, 25 Dec 2011 20:04:41 +0100 Subject: [PATCH 291/302] Dot-Notation: Some random places --- mediagoblin/auth/views.py | 2 +- mediagoblin/edit/views.py | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/mediagoblin/auth/views.py b/mediagoblin/auth/views.py index 88dc40ad..c04a49a7 100644 --- a/mediagoblin/auth/views.py +++ b/mediagoblin/auth/views.py @@ -205,7 +205,7 @@ def resend_activation(request): return redirect(request, 'mediagoblin.auth.login') - if request.user["email_verified"]: + if request.user.email_verified: messages.add_message( request, messages.ERROR, diff --git a/mediagoblin/edit/views.py b/mediagoblin/edit/views.py index bae85c5d..ec748028 100644 --- a/mediagoblin/edit/views.py +++ b/mediagoblin/edit/views.py @@ -46,7 +46,7 @@ def edit_media(request, media): title=media.title, slug=media.slug, description=media.description, - tags=media_tags_as_string(media['tags'])) + tags=media_tags_as_string(media.tags)) form = forms.EditForm( request.POST, @@ -165,7 +165,7 @@ def edit_profile(request): user.url = unicode(request.POST['url']) user.bio = unicode(request.POST['bio']) - user.bio_html = cleaned_markdown_conversion(user['bio']) + user.bio_html = cleaned_markdown_conversion(user.bio) user.save() @@ -193,7 +193,7 @@ def edit_account(request): if request.method == 'POST' and form.validate(): password_matches = auth_lib.bcrypt_check_password( request.POST['old_password'], - user['pw_hash']) + user.pw_hash) if (request.POST['old_password'] or request.POST['new_password']) and not \ password_matches: @@ -206,7 +206,7 @@ def edit_account(request): 'form': form}) if password_matches: - user['pw_hash'] = auth_lib.bcrypt_gen_password_hash( + user.pw_hash = auth_lib.bcrypt_gen_password_hash( request.POST['new_password']) user.save() @@ -216,7 +216,7 @@ def edit_account(request): _("Account settings saved")) return redirect(request, 'mediagoblin.user_pages.user_home', - user=user['username']) + user=user.username) return render_to_response( request, From 02db7e0a83fc06eaa8e96888f6c9e4fb44e7cbe2 Mon Sep 17 00:00:00 2001 From: Elrond Date: Sat, 31 Dec 2011 23:01:34 +0100 Subject: [PATCH 292/302] Add MediaFile table and related infrastructure. - This adds a new SQL table field type for path tuples. They're stored as '/' separated unicode strings. - Uses it to implement a MediaFile table. - Add relationship and proxy fields on MediaEntry to give a nice media_files "view" there. - Let the converter fill the MediaFile. --- mediagoblin/db/sql/convert.py | 7 ++++++- mediagoblin/db/sql/extratypes.py | 18 ++++++++++++++++++ mediagoblin/db/sql/models.py | 27 +++++++++++++++++++++++++-- 3 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 mediagoblin/db/sql/extratypes.py diff --git a/mediagoblin/db/sql/convert.py b/mediagoblin/db/sql/convert.py index 6698b767..88614fd4 100644 --- a/mediagoblin/db/sql/convert.py +++ b/mediagoblin/db/sql/convert.py @@ -2,7 +2,7 @@ from mediagoblin.init import setup_global_and_app_config, setup_database from mediagoblin.db.mongo.util import ObjectId from mediagoblin.db.sql.models import (Base, User, MediaEntry, MediaComment, - Tag, MediaTag) + Tag, MediaTag, MediaFile) from mediagoblin.db.sql.open import setup_connection_and_db_from_config as \ sql_connect from mediagoblin.db.mongo.open import setup_connection_and_db_from_config as \ @@ -70,6 +70,11 @@ def convert_media_entries(mk_db): session.flush() add_obj_ids(entry, new_entry) + for key, value in entry.media_files.iteritems(): + new_file = MediaFile(name=key, file_path=value) + new_file.media_entry = new_entry.id + Session.add(new_file) + session.commit() session.close() diff --git a/mediagoblin/db/sql/extratypes.py b/mediagoblin/db/sql/extratypes.py new file mode 100644 index 00000000..88f556d9 --- /dev/null +++ b/mediagoblin/db/sql/extratypes.py @@ -0,0 +1,18 @@ +from sqlalchemy.types import TypeDecorator, Unicode + + +class PathTupleWithSlashes(TypeDecorator): + "Represents a Tuple of strings as a slash separated string." + + impl = Unicode + + def process_bind_param(self, value, dialect): + if value is not None: + assert len(value), "Does not support empty lists" + value = '/'.join(value) + return value + + def process_result_value(self, value, dialect): + if value is not None: + value = tuple(value.split('/')) + return value diff --git a/mediagoblin/db/sql/models.py b/mediagoblin/db/sql/models.py index 95821b4f..91092f33 100644 --- a/mediagoblin/db/sql/models.py +++ b/mediagoblin/db/sql/models.py @@ -5,7 +5,10 @@ from sqlalchemy import ( Column, Integer, Unicode, UnicodeText, DateTime, Boolean, ForeignKey, UniqueConstraint) from sqlalchemy.orm import relationship +from sqlalchemy.orm.collections import attribute_mapped_collection +from sqlalchemy.ext.associationproxy import association_proxy +from mediagoblin.db.sql.extratypes import PathTupleWithSlashes from mediagoblin.db.sql.base import GMGTableBase from mediagoblin.db.mixin import UserMixin, MediaEntryMixin @@ -65,7 +68,7 @@ class MediaEntry(Base, MediaEntryMixin): fail_error = Column(Unicode) fail_metadata = Column(UnicodeText) - queued_media_file = Column(Unicode) + queued_media_file = Column(PathTupleWithSlashes) queued_task_id = Column(Unicode) @@ -75,13 +78,33 @@ class MediaEntry(Base, MediaEntryMixin): get_uploader = relationship(User) + media_files_helper = relationship("MediaFile", + collection_class=attribute_mapped_collection("name"), + cascade="all, delete-orphan" + ) + media_files = association_proxy('media_files_helper', 'file_path', + creator=lambda k,v: MediaFile(name=k, file_path=v) + ) + ## TODO - # media_files # media_data # attachment_files # fail_error +class MediaFile(Base): + __tablename__ = "mediafiles" + + media_entry = Column( + Integer, ForeignKey(MediaEntry.id), + nullable=False, primary_key=True) + name = Column(Unicode, primary_key=True) + file_path = Column(PathTupleWithSlashes) + + def __repr__(self): + return "" % (self.name, self.file_path) + + class Tag(Base): __tablename__ = "tags" From 20659de2344ccb8d14f8deaeaf9628d84a966e5a Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Fri, 13 Jan 2012 17:38:20 +0100 Subject: [PATCH 293/302] Add CC0 license header to Sphinx MediaGoblin theme (mg.css) --- docs/source/themes/mg/static/mg.css | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/source/themes/mg/static/mg.css b/docs/source/themes/mg/static/mg.css index b9355a5d..96344df4 100644 --- a/docs/source/themes/mg/static/mg.css +++ b/docs/source/themes/mg/static/mg.css @@ -1,3 +1,15 @@ +/* + +MediaGoblin theme - MediaGoblin-style Sphinx documentation theme + +Written in 2012 by Jef van Schendel + +To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide. This software is distributed without any warranty. + +You should have received a copy of the CC0 Public Domain Dedication along with this software. If not, see . + +*/ + @import url("basic.css"); /* text fonts and styles */ From fafec727402ef3fa4d806b200f1d86cb91cd6362 Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Fri, 13 Jan 2012 23:23:02 +0100 Subject: [PATCH 294/302] Remove unnecessary piece of text in media.html. Fix "Markdown text" indentation so they are the same. --- mediagoblin/edit/forms.py | 7 +++---- mediagoblin/templates/mediagoblin/user_pages/media.html | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/mediagoblin/edit/forms.py b/mediagoblin/edit/forms.py index 09955874..5c191fba 100644 --- a/mediagoblin/edit/forms.py +++ b/mediagoblin/edit/forms.py @@ -45,10 +45,9 @@ class EditProfileForm(wtforms.Form): bio = wtforms.TextAreaField( _('Bio'), [wtforms.validators.Length(min=0, max=500)], - description=_( - """You can use - - Markdown for formatting.""")) + description=_("""You can use + + Markdown for formatting.""")) url = wtforms.TextField( _('Website'), [wtforms.validators.Optional(), diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html index 583e4ebd..865a94ab 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media.html @@ -97,7 +97,7 @@ user= media.get_uploader.username, media=media._id) }}" method="POST" id="form_comment">

- {% trans %}Type your comment here. You can use Markdown for formatting.{% endtrans %} + {% trans %}You can use Markdown for formatting.{% endtrans %}

{{ wtforms_util.render_divs(comment_form) }}
From 762d4a0c48e582dba78a27f1a42e367d3f14a891 Mon Sep 17 00:00:00 2001 From: Elrond Date: Fri, 13 Jan 2012 23:38:21 +0100 Subject: [PATCH 295/302] Fix request.user==None error If one isn't logged in and views the profile of a user without media, one gets a problem, because request.user is None and has no _id attribute. Fix this. --- mediagoblin/templates/mediagoblin/user_pages/user.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediagoblin/templates/mediagoblin/user_pages/user.html b/mediagoblin/templates/mediagoblin/user_pages/user.html index 0937f97a..d3b4021d 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/user.html +++ b/mediagoblin/templates/mediagoblin/user_pages/user.html @@ -145,7 +145,7 @@ {% include "mediagoblin/utils/feed_link.html" %}
{% else %} - {% if request.user._id == user._id %} + {% if request.user and (request.user._id == user._id) %}

{% trans -%} From 4670ff1c56ed58591945bbf665bbd9d7f72b71a9 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Fri, 13 Jan 2012 20:26:36 -0600 Subject: [PATCH 296/302] Simple translation update script --- devtools/update_translations.sh | 48 +++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 devtools/update_translations.sh diff --git a/devtools/update_translations.sh b/devtools/update_translations.sh new file mode 100644 index 00000000..1708e7e0 --- /dev/null +++ b/devtools/update_translations.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +# 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 . + +# exit if anything fails +set -e + +echo "==> checking out master" +git checkout master + +echo "==> pulling git master" +git pull + +echo "==> pulling present translations" +./bin/tx pull -a +git add mediagoblin/i18n/ +git commit -m "Committing present MediaGoblin translations before pushing extracted messages" + +echo "==> Extracting translations" +./bin/pybabel extract -F babel.ini -o mediagoblin/i18n/en/LC_MESSAGES/mediagoblin.po . + +echo "==> Pushing extracted translations to Transifex" +./bin/tx push -s + +# gets the new strings added to all files +echo "==> Re-Pulling translations from Transifex" +./bin/tx pull -a + +echo "==> Compiling .mo files" +./bin/pybabel compile -D mediagoblin -d mediagoblin/i18n/ + +echo "==> Committing to git" +git add mediagoblin/i18n/ +git commit -m "Committing extracted and compiled translations" From 1b5bbc0a8522b384084345cbb4f4917a8db015bf Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Fri, 13 Jan 2012 20:27:53 -0600 Subject: [PATCH 297/302] make this script executable --- devtools/update_translations.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 devtools/update_translations.sh diff --git a/devtools/update_translations.sh b/devtools/update_translations.sh old mode 100644 new mode 100755 From 9c947004139d0d0ae5a879cd4c120891f8a8d51e Mon Sep 17 00:00:00 2001 From: Elrond Date: Sat, 14 Jan 2012 12:54:16 +0100 Subject: [PATCH 298/302] Move maketarball.sh into devtools/ Now that there is a devtools directory, use it! --- maketarball.sh => devtools/maketarball.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename maketarball.sh => devtools/maketarball.sh (100%) diff --git a/maketarball.sh b/devtools/maketarball.sh similarity index 100% rename from maketarball.sh rename to devtools/maketarball.sh From 52fc51f6a9b6379d39d391bd54473eebb6d23cd5 Mon Sep 17 00:00:00 2001 From: Elrond Date: Fri, 13 Jan 2012 22:59:14 +0100 Subject: [PATCH 299/302] Drop sessions with invalid ObjectIds The session can contain invalid objectids when switching a more or less live instance (with logged in users) from mongo to sql or vice versa. So drop the complete session and force the user to login again. --- mediagoblin/tools/request.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/mediagoblin/tools/request.py b/mediagoblin/tools/request.py index b1cbe119..7e193125 100644 --- a/mediagoblin/tools/request.py +++ b/mediagoblin/tools/request.py @@ -14,7 +14,7 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -from mediagoblin.db.util import ObjectId +from mediagoblin.db.util import ObjectId, InvalidId def setup_user_in_request(request): """ @@ -25,13 +25,17 @@ def setup_user_in_request(request): request.user = None return - user = None - user = request.app.db.User.one( - {'_id': ObjectId(request.session['user_id'])}) + try: + oid = ObjectId(request.session['user_id']) + except InvalidId: + user = None + else: + user = request.db.User.one({'_id': oid}) if not user: # Something's wrong... this user doesn't exist? Invalidate # this session. + print "Killing session for %r" % request.session['user_id'] request.session.invalidate() request.user = user From b6997919563ab2553e9dc4af1d4cb06c1544a5ce Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Sun, 15 Jan 2012 17:07:15 +0100 Subject: [PATCH 300/302] Small margin/font-weight fix --- mediagoblin/static/css/base.css | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css index c2d45a1b..5b37a362 100644 --- a/mediagoblin/static/css/base.css +++ b/mediagoblin/static/css/base.css @@ -48,6 +48,7 @@ h1 { margin-top: 15px; color: #fff; font-size: 1.875em; + font-weight: bold; } h2 { @@ -63,6 +64,7 @@ h3 { p { margin-top: 0px; + margin-bottom: 20px; } a { From 62f2557cae03bd4675fc67a7775d3c715a2f2a62 Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Sun, 15 Jan 2012 17:10:35 +0100 Subject: [PATCH 301/302] Another small text style fix --- mediagoblin/static/css/base.css | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css index 5b37a362..44c7cd0c 100644 --- a/mediagoblin/static/css/base.css +++ b/mediagoblin/static/css/base.css @@ -43,12 +43,18 @@ form { /* text styles */ +h1,h2,h3,p { + margin-bottom: 20px; +} + +h1,h2,h3 { + font-weight: bold; +} + h1 { - margin-bottom: 15px; margin-top: 15px; color: #fff; font-size: 1.875em; - font-weight: bold; } h2 { @@ -64,7 +70,6 @@ h3 { p { margin-top: 0px; - margin-bottom: 20px; } a { From 8c7701f9f1653cf4038143cfb7a497ae21edf108 Mon Sep 17 00:00:00 2001 From: Jef van Schendel Date: Sun, 15 Jan 2012 17:23:21 +0100 Subject: [PATCH 302/302] Small fix to simplify font style --- mediagoblin/static/css/base.css | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css index 44c7cd0c..efd7b561 100644 --- a/mediagoblin/static/css/base.css +++ b/mediagoblin/static/css/base.css @@ -32,8 +32,7 @@ body { padding: none; margin: 0px; height: 100%; - font: 16px "HelveticaNeue-Light","Helvetica Neue Light","Helvetica Neue",Helvetica,Arial,sans-serif; - font-family:'Lato', sans-serif; + font: 16px 'Lato', 'Helvetica Neue', Arial, 'Liberation Sans', FreeSans, sans-serif; } form {

{{ media_entry['title'] }}{{ media_entry['created'].strftime("%m-%d-%Y %I:%M %p") }}{{ media_entry.created.strftime("%m-%d-%Y %I:%M %p") }}
{{ media_entry['title'] }}{{ media_entry.title }} {{ media_entry.created.strftime("%m-%d-%Y %I:%M %p") }}
{{ media_entry['title'] }}{{ media_entry.title }} {{ media_entry['created'].strftime("%m-%d-%Y %I:%M %p") }} {{ media_entry.get_fail_exception().general_message }}