diff --git a/AUTHORS b/AUTHORS index b6dd1cf2..304e14a2 100644 --- a/AUTHORS +++ b/AUTHORS @@ -8,10 +8,12 @@ variety of different ways and this software wouldn't exist without them. Thank you! * Aaron Williamson +* Aditi Mittal * Aeva Ntsc * Alejandro Villanueva * Aleksandar Micovic * Aleksej Serdjukov +* Alon Levy * Alex Camelio * András Veres-Szentkirályi * Bassam Kurdali @@ -21,13 +23,17 @@ Thank you! * Corey Farwell * Chris Moylan * Christopher Allan Webber +* David Thompson * Daniel Neel * Deb Nicholson * Derek Moore * Duncan Paterson * Elrond of Samba TNG * Emily O'Leary +* Gabi Thume +* Gabriel Saldana * Greg Grossmeier +* Hans Lo * Jakob Kramer * Jef van Schendel * Jessica Tallon @@ -36,25 +42,34 @@ Thank you! * Jorge Araya Navarro * Karen Rustad * Kuno Woudt +* Laura Arjona * Larisa Hoffenbecker * Luke Slater * Manuel Urbano Santos * Mark Holmquist +* Mats Sjöberg * Matt Lee * Michele Azzolari +* Mike Linksvayer +* Natalie Foust-Pilcher * Nathan Yergler * Odin Hørthe Omdal * Osama Khalid * Pablo J. Urbano Santos +* Praveen Kumar * Rasmus Larsson +* Rodney Ewing * Runar Petursson * Sacha De'Angeli * Sam Kleinman +* Sam Tuke * Sebastian Spaeth * Shawn Khan +* Simon Fondrie-Teitler * Stefano Zacchiroli * Tiberiu C. Turbureanu * Tran Thanh Bao +* Tryggvi Björgvinsson * Shawn Khan * Will Kahn-Greene @@ -64,4 +79,4 @@ If you think your name should be on this list, let us know! We also are currently borrowing an image in mediagoblin/static/images/media_thumbs/image.png from the wonderful people at http://tango.freedesktop.org/ which is in the public -domain... thanks Tango folks! \ No newline at end of file +domain... thanks Tango folks! diff --git a/docs/source/index.rst b/docs/source/index.rst index 7f692d57..d71f39f8 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -73,6 +73,7 @@ This guide covers writing new GNU MediaGoblin plugins. pluginwriter/quickstart pluginwriter/database pluginwriter/api + pluginwriter/tests Part 4: Developer's Zone diff --git a/docs/source/pluginwriter/api.rst b/docs/source/pluginwriter/api.rst index 66def173..29adb691 100644 --- a/docs/source/pluginwriter/api.rst +++ b/docs/source/pluginwriter/api.rst @@ -69,6 +69,32 @@ example might look like:: This means that when people enable your plugin in their config you'll be able to provide defaults as well as type validation. +You can access this via the app_config variables in mg_globals, or you +can use a shortcut to get your plugin's config section:: + + >>> from mediagoblin.tools import pluginapi + # Replace with the path to your plugin. + # (If an external package, it won't be part of mediagoblin.plugins) + >>> floobie_config = pluginapi.get_config('mediagoblin.plugins.floobifier') + >>> floobie_dir = floobie_config['floobie_dir'] + # This is the same as the above + >>> from mediagoblin import mg_globals + >>> config = mg_globals.global_config['plugins']['mediagoblin.plugins.floobifier'] + >>> floobie_dir = floobie_config['floobie_dir'] + +A tip: you have access to the `%(here)s` variable in your config, +which is the directory that the user's mediagoblin config is running +out of. So for example, your plugin may need a "floobie" directory to +store floobs in. You could give them a reasonable default that makes +use of the default `user_dev` location, but allow users to override +it, like so:: + + [plugin_spec] + floobie_dir = string(default="%(here)s/user_dev/floobs/") + +Note, this is relative to the user's mediagoblin config directory, +*not* your plugin directory! + Context Hooks ------------- diff --git a/docs/source/pluginwriter/tests.rst b/docs/source/pluginwriter/tests.rst new file mode 100644 index 00000000..fe99688f --- /dev/null +++ b/docs/source/pluginwriter/tests.rst @@ -0,0 +1,64 @@ +.. MediaGoblin Documentation + + Written in 2013 by MediaGoblin contributors + + 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 + . + +============================== +Writing unit tests for plugins +============================== + +Here's a brief guide to writing unit tests for plugins. However, it +isn't really ideal. It also hasn't been well tested... yes, there's +some irony there :) + +Some notes: we're using py.test and webtest for unit testing stuff. +Keep that in mind. + +My suggestion is to mime the behavior of `mediagoblin/tests/` and put +that in your own plugin, like `myplugin/tests/`. Copy over +`conftest.py` and `pytest.ini` to your tests directory, but possibly +change the `test_app` fixture to match your own tests' config needs. +For example:: + + import pkg_resources + # [...] + + @pytest.fixture() + def test_app(request): + return get_app( + request, + mgoblin_config=pkg_resources.resource_filename( + 'myplugin.tests', 'myplugin_mediagoblin.ini')) + +In any test module in your tests directory you can then do:: + + def test_somethingorother(test_app): + # real code goes here + pass + +And you'll get a mediagoblin application wrapped in webtest passed in +to your environment. + +If your plugin needs to define multiple configuration setups, you can +actually set up multiple fixtures very easily for this. You can just +set up multiple fixtures with different names that point to different +configs and pass them in as that named argument. + +To run the tests, from mediagoblin's directory (make sure that your +plugin has been added to your mediagoblin checkout's virtualenv!) do:: + + ./runtests.sh /path/to/myplugin/tests/ + +replacing `/path/to/myplugin/` with the actual path to your plugin. + +NOTE: again, the above is untested, but it should probably work. If +you run into trouble, `contact us +`_, preferably on IRC! diff --git a/docs/source/siteadmin/media-types.rst b/docs/source/siteadmin/media-types.rst index 210094b9..1527bc70 100644 --- a/docs/source/siteadmin/media-types.rst +++ b/docs/source/siteadmin/media-types.rst @@ -199,8 +199,16 @@ will be able to present them to your wide audience of admirers! PDF and Document ================ -To enable the "PDF and Document" support plugin, you need pdftocairo, pdfinfo, -unoconv with headless support. All executables must be on your execution path. +To enable the "PDF and Document" support plugin, you need: + +1. pdftocairo and pdfinfo for pdf only support. + +2. unoconv with headless support to support converting libreoffice supported + documents as well, such as doc/ppt/xls/odf/odg/odp and more. + For the full list see mediagoblin/media_types/pdf/processing.py, + unoconv_supported. + +All executables must be on your execution path. To install this on Fedora: @@ -208,6 +216,9 @@ To install this on Fedora: sudo yum install -y poppler-utils unoconv libreoffice-headless +Note: You can leave out unoconv and libreoffice-headless if you want only pdf +support. This will result in a much smaller list of dependencies. + pdf.js relies on git submodules, so be sure you have fetched them: .. code-block:: bash diff --git a/docs/source/siteadmin/relnotes.rst b/docs/source/siteadmin/relnotes.rst index 9c9d311c..7b6d8353 100644 --- a/docs/source/siteadmin/relnotes.rst +++ b/docs/source/siteadmin/relnotes.rst @@ -39,6 +39,13 @@ carefully, or at least skim over it. alias /srv/mediagoblin.example.org/mediagoblin/user_dev/plugin_static/; } + Similarly, if you've got a modified paste config, you may want to + borrow the app:plugin_static section from the default paste.ini + file. +5. We now use itsdangerous for sessions; if you had any references to + beaker in your paste config you can remove them. Again, see the + default paste.ini config + **For theme authors** If you have your own theme or you have any "user modified templates", @@ -51,7 +58,23 @@ please note the following: You can easily customize this to give a welcome page appropriate to your site. + **New features** +* PDF media type! +* Improved plugin system. More flexible, better documented, with a + new plugin authoring section of the docs. +* itsdangerous based sessions. No more beaker! +* New, experimental Piwigo-based API. This means you should be able + to use MediaGoblin with something like Shotwell. (Again, a word of + caution: this is *very experimental*!) +* Human readable timestamps, and the option to display the original + date of an image when available (available as the + "original_date_visible" variable) +* Moved unit testing system from nosetests to py.test so we can better + handle issues with sqlalchemy exploding with different database + configurations. Long story :) +* You can now disable the ability to post comments. +* Tags now can be up to length 255 characters by default. 0.3.3 diff --git a/mediagoblin.ini b/mediagoblin.ini index 057084ae..e878a478 100644 --- a/mediagoblin.ini +++ b/mediagoblin.ini @@ -20,7 +20,7 @@ email_debug_mode = true allow_registration = true ## Uncomment this to turn on video or enable other media types -## You may have to install dependencies, and will have to run ./bin/dbupdate +## You may have to install dependencies, and will have to run ./bin/gmg dbupdate ## See http://docs.mediagoblin.org/siteadmin/media-types.html for details. # media_types = mediagoblin.media_types.image, mediagoblin.media_types.video diff --git a/mediagoblin/_version.py b/mediagoblin/_version.py index 8437be8b..2abc105f 100644 --- a/mediagoblin/_version.py +++ b/mediagoblin/_version.py @@ -23,4 +23,4 @@ # see http://www.python.org/dev/peps/pep-0386/ -__version__ = "0.4.0.dev" +__version__ = "0.4.1.dev" diff --git a/mediagoblin/app.py b/mediagoblin/app.py index f44504a7..96461711 100644 --- a/mediagoblin/app.py +++ b/mediagoblin/app.py @@ -38,6 +38,7 @@ from mediagoblin.init import (get_jinja_loader, get_staticdirector, from mediagoblin.tools.pluginapi import PluginManager, hook_transform from mediagoblin.tools.crypto import setup_crypto from mediagoblin.auth.tools import check_auth_enabled, no_auth_logout +from mediagoblin import notifications _log = logging.getLogger(__name__) @@ -195,6 +196,8 @@ class MediaGoblinApp(object): # Log user out if authentication_disabled no_auth_logout(request) + request.notifications = notifications + mg_request.setup_user_in_request(request) request.controller_name = None diff --git a/mediagoblin/auth/forms.py b/mediagoblin/auth/forms.py index dad5dd86..866caa13 100644 --- a/mediagoblin/auth/forms.py +++ b/mediagoblin/auth/forms.py @@ -30,9 +30,6 @@ class ForgotPassForm(wtforms.Form): class ChangePassForm(wtforms.Form): password = wtforms.PasswordField( 'Password') - userid = wtforms.HiddenField( - '', - [wtforms.validators.Required()]) token = wtforms.HiddenField( '', [wtforms.validators.Required()]) diff --git a/mediagoblin/auth/tools.py b/mediagoblin/auth/tools.py index 71f824de..877da14f 100644 --- a/mediagoblin/auth/tools.py +++ b/mediagoblin/auth/tools.py @@ -18,6 +18,7 @@ import logging import wtforms from mediagoblin import mg_globals +from mediagoblin.tools.crypto import get_timed_signer_url from mediagoblin.db.models import User from mediagoblin.tools.mail import (normalize_email, send_email, email_debug_message) @@ -60,11 +61,12 @@ def normalize_user_or_email_field(allow_email=True, allow_user=True): EMAIL_VERIFICATION_TEMPLATE = ( - u"http://{host}{uri}?" - u"userid={userid}&token={verification_key}") + u"{uri}?" + u"token={verification_key}") -def send_verification_email(user, request): +def send_verification_email(user, request, email=None, + rendered_email=None): """ Send the verification email to users to activate their accounts. @@ -72,19 +74,24 @@ def send_verification_email(user, request): - user: a user object - request: the request """ - rendered_email = render_template( - request, 'mediagoblin/auth/verification_email.txt', - {'username': user.username, - 'verification_url': EMAIL_VERIFICATION_TEMPLATE.format( - host=request.host, - uri=request.urlgen('mediagoblin.auth.verify_email'), - userid=unicode(user.id), - verification_key=user.verification_key)}) + if not email: + email = user.email + + if not rendered_email: + verification_key = get_timed_signer_url('mail_verification_token') \ + .dumps(user.id) + rendered_email = render_template( + request, 'mediagoblin/auth/verification_email.txt', + {'username': user.username, + 'verification_url': EMAIL_VERIFICATION_TEMPLATE.format( + uri=request.urlgen('mediagoblin.auth.verify_email', + qualified=True), + verification_key=verification_key)}) # TODO: There is no error handling in place send_email( mg_globals.app_config['email_sender_address'], - [user.email], + [email], # TODO # Due to the distributed nature of GNU MediaGoblin, we should # find a way to send some additional information about the diff --git a/mediagoblin/auth/views.py b/mediagoblin/auth/views.py index d7535ef0..34500f91 100644 --- a/mediagoblin/auth/views.py +++ b/mediagoblin/auth/views.py @@ -15,10 +15,11 @@ # along with this program. If not, see . import uuid -import datetime +from itsdangerous import BadSignature from mediagoblin import messages, mg_globals from mediagoblin.db.models import User +from mediagoblin.tools.crypto import get_timed_signer_url from mediagoblin.tools.response import render_to_response, redirect, render_404 from mediagoblin.tools.translate import pass_to_ugettext as _ from mediagoblin.tools.mail import email_debug_message @@ -136,16 +137,28 @@ def verify_email(request): you are lucky :) """ # If we don't have userid and token parameters, we can't do anything; 404 - if not 'userid' in request.GET or not 'token' in request.GET: + if not 'token' in request.GET: return render_404(request) - user = User.query.filter_by(id=request.args['userid']).first() + # Catch error if token is faked or expired + try: + token = get_timed_signer_url("mail_verification_token") \ + .loads(request.GET['token'], max_age=10*24*3600) + except BadSignature: + messages.add_message( + request, + messages.ERROR, + _('The verification key or user id is incorrect.')) - if user and user.verification_key == unicode(request.GET['token']): + return redirect( + request, + 'index') + + user = User.query.filter_by(id=int(token)).first() + + if user and user.email_verified is False: user.status = u'active' user.email_verified = True - user.verification_key = None - user.save() messages.add_message( @@ -187,9 +200,6 @@ def resend_activation(request): return redirect(request, "mediagoblin.user_pages.user_home", user=request.user['username']) - request.user.verification_key = unicode(uuid.uuid4()) - request.user.save() - email_debug_message(request) send_verification_email(request.user, request) @@ -259,11 +269,6 @@ def forgot_password(request): # SUCCESS. Send reminder and return to login page if user: - user.fp_verification_key = unicode(uuid.uuid4()) - user.fp_token_expire = datetime.datetime.now() + \ - datetime.timedelta(days=10) - user.save() - email_debug_message(request) send_fp_verification_email(user, request) @@ -278,31 +283,44 @@ def verify_forgot_password(request): """ # get form data variables, and specifically check for presence of token formdata = _process_for_token(request) - if not formdata['has_userid_and_token']: + if not formdata['has_token']: return render_404(request) - formdata_token = formdata['vars']['token'] - formdata_userid = formdata['vars']['userid'] formdata_vars = formdata['vars'] - # check if it's a valid user id - user = User.query.filter_by(id=formdata_userid).first() - if not user: - return render_404(request) + # Catch error if token is faked or expired + try: + token = get_timed_signer_url("mail_verification_token") \ + .loads(formdata_vars['token'], max_age=10*24*3600) + except BadSignature: + messages.add_message( + request, + messages.ERROR, + _('The verification key or user id is incorrect.')) - # 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 - and user.email_verified and user.status == 'active')): + return redirect( + request, + 'index') + + # check if it's a valid user id + user = User.query.filter_by(id=int(token)).first() + + # no user in db + if not user: + messages.add_message( + request, messages.ERROR, + _('The user id is incorrect.')) + return redirect( + request, 'index') + + # check if user active and has email verified + if user.email_verified and user.status == 'active': cp_form = auth_forms.ChangePassForm(formdata_vars) if request.method == 'POST' and cp_form.validate(): user.pw_hash = auth.gen_password_hash( cp_form.password.data) - user.fp_verification_key = None - user.fp_token_expire = None user.save() messages.add_message( @@ -316,10 +334,20 @@ def verify_forgot_password(request): 'mediagoblin/auth/change_fp.html', {'cp_form': cp_form,}) - # in case there is a valid id but no user with that id in the db - # or the token expired - else: - return render_404(request) + if not user.email_verified: + messages.add_message( + request, messages.ERROR, + _('You need to verify your email before you can reset your' + ' password.')) + + if not user.status == 'active': + messages.add_message( + request, messages.ERROR, + _('You are no longer an active user. Please contact the system' + ' admin to reactivate your accoutn.')) + + return redirect( + request, 'index') def _process_for_token(request): @@ -337,7 +365,6 @@ def _process_for_token(request): formdata = { 'vars': formdata_vars, - 'has_userid_and_token': - 'userid' in formdata_vars and 'token' in formdata_vars} + 'has_token': 'token' in formdata_vars} return formdata diff --git a/mediagoblin/config_spec.ini b/mediagoblin/config_spec.ini index b213970d..4547ea54 100644 --- a/mediagoblin/config_spec.ini +++ b/mediagoblin/config_spec.ini @@ -22,9 +22,10 @@ direct_remote_path = string(default="/mgoblin_static/") # set to false to enable sending notices email_debug_mode = boolean(default=True) +email_smtp_use_ssl = boolean(default=False) email_sender_address = string(default="notice@mediagoblin.example.org") email_smtp_host = string(default='') -email_smtp_port = integer(default=25) +email_smtp_port = integer(default=0) email_smtp_user = string(default=None) email_smtp_pass = string(default=None) diff --git a/mediagoblin/db/migrations.py b/mediagoblin/db/migrations.py index 129c1998..fef353af 100644 --- a/mediagoblin/db/migrations.py +++ b/mediagoblin/db/migrations.py @@ -26,7 +26,7 @@ from sqlalchemy.sql import and_ from migrate.changeset.constraint import UniqueConstraint from mediagoblin.db.migration_tools import RegisterMigration, inspect_table -from mediagoblin.db.models import MediaEntry, Collection, User +from mediagoblin.db.models import MediaEntry, Collection, User, MediaComment MIGRATIONS = {} @@ -288,8 +288,82 @@ def unique_collections_slug(db): db.commit() - @RegisterMigration(11, MIGRATIONS) +def drop_token_related_User_columns(db): + """ + Drop unneeded columns from the User table after switching to using + itsdangerous tokens for email and forgot password verification. + """ + metadata = MetaData(bind=db.bind) + user_table = inspect_table(metadata, 'core__users') + + verification_key = user_table.columns['verification_key'] + fp_verification_key = user_table.columns['fp_verification_key'] + fp_token_expire = user_table.columns['fp_token_expire'] + + verification_key.drop() + fp_verification_key.drop() + fp_token_expire.drop() + + db.commit() + +class CommentSubscription_v0(declarative_base()): + __tablename__ = 'core__comment_subscriptions' + id = Column(Integer, primary_key=True) + + created = Column(DateTime, nullable=False, default=datetime.datetime.now) + + media_entry_id = Column(Integer, ForeignKey(MediaEntry.id), nullable=False) + + user_id = Column(Integer, ForeignKey(User.id), nullable=False) + + notify = Column(Boolean, nullable=False, default=True) + send_email = Column(Boolean, nullable=False, default=True) + + +class Notification_v0(declarative_base()): + __tablename__ = 'core__notifications' + id = Column(Integer, primary_key=True) + type = Column(Unicode) + + created = Column(DateTime, nullable=False, default=datetime.datetime.now) + + user_id = Column(Integer, ForeignKey(User.id), nullable=False, + index=True) + seen = Column(Boolean, default=lambda: False, index=True) + + +class CommentNotification_v0(Notification_v0): + __tablename__ = 'core__comment_notifications' + id = Column(Integer, ForeignKey(Notification_v0.id), primary_key=True) + + subject_id = Column(Integer, ForeignKey(MediaComment.id)) + + +class ProcessingNotification_v0(Notification_v0): + __tablename__ = 'core__processing_notifications' + + id = Column(Integer, ForeignKey(Notification_v0.id), primary_key=True) + + subject_id = Column(Integer, ForeignKey(MediaEntry.id)) + + +@RegisterMigration(12, MIGRATIONS) +def add_new_notification_tables(db): + metadata = MetaData(bind=db.bind) + + user_table = inspect_table(metadata, 'core__users') + mediaentry_table = inspect_table(metadata, 'core__media_entries') + mediacomment_table = inspect_table(metadata, 'core__media_comments') + + CommentSubscription_v0.__table__.create(db.bind) + + Notification_v0.__table__.create(db.bind) + CommentNotification_v0.__table__.create(db.bind) + ProcessingNotification_v0.__table__.create(db.bind) + + +@RegisterMigration(13, MIGRATIONS) def pw_hash_nullable(db): """Make pw_hash column nullable""" metadata = MetaData(bind=db.bind) @@ -302,3 +376,4 @@ def pw_hash_nullable(db): constraint.create() db.commit() + diff --git a/mediagoblin/db/mixin.py b/mediagoblin/db/mixin.py index 9f566e36..1b32d838 100644 --- a/mediagoblin/db/mixin.py +++ b/mediagoblin/db/mixin.py @@ -31,6 +31,8 @@ import uuid import re import datetime +from datetime import datetime + from werkzeug.utils import cached_property from mediagoblin import mg_globals @@ -288,6 +290,13 @@ class MediaCommentMixin(object): """ return cleaned_markdown_conversion(self.content) + def __repr__(self): + return '<{klass} #{id} {author} "{comment}">'.format( + klass=self.__class__.__name__, + id=self.id, + author=self.get_author, + comment=self.content) + class CollectionMixin(GenerateSlugMixin): def check_slug_used(self, slug): diff --git a/mediagoblin/db/models.py b/mediagoblin/db/models.py index 323ed4d7..826d47ba 100644 --- a/mediagoblin/db/models.py +++ b/mediagoblin/db/models.py @@ -24,15 +24,17 @@ import datetime from sqlalchemy import Column, Integer, Unicode, UnicodeText, DateTime, \ Boolean, ForeignKey, UniqueConstraint, PrimaryKeyConstraint, \ SmallInteger -from sqlalchemy.orm import relationship, backref +from sqlalchemy.orm import relationship, backref, with_polymorphic from sqlalchemy.orm.collections import attribute_mapped_collection from sqlalchemy.sql.expression import desc from sqlalchemy.ext.associationproxy import association_proxy from sqlalchemy.util import memoized_property + from mediagoblin.db.extratypes import PathTupleWithSlashes, JSONEncoded from mediagoblin.db.base import Base, DictReadAttrProxy -from mediagoblin.db.mixin import UserMixin, MediaEntryMixin, MediaCommentMixin, CollectionMixin, CollectionItemMixin +from mediagoblin.db.mixin import UserMixin, MediaEntryMixin, \ + MediaCommentMixin, CollectionMixin, CollectionItemMixin from mediagoblin.tools.files import delete_media_files from mediagoblin.tools.common import import_component @@ -60,20 +62,17 @@ class User(Base, UserMixin): # the RFC) and because it would be a mess to implement at this # point. email = Column(Unicode, nullable=False) - created = Column(DateTime, nullable=False, default=datetime.datetime.now) pw_hash = Column(Unicode) email_verified = Column(Boolean, default=False) + created = Column(DateTime, nullable=False, default=datetime.datetime.now) status = Column(Unicode, default=u"needs_email_verification", nullable=False) # Intented to be nullable=False, but migrations would not work for it # set to nullable=True implicitly. wants_comment_notification = Column(Boolean, default=True) license_preference = Column(Unicode) - verification_key = Column(Unicode) is_admin = Column(Boolean, default=False, nullable=False) url = Column(Unicode) bio = Column(UnicodeText) # ?? - fp_verification_key = Column(Unicode) - fp_token_expire = Column(DateTime) ## TODO # plugin data would be in a separate model @@ -392,6 +391,10 @@ class MediaComment(Base, MediaCommentMixin): backref=backref("posted_comments", lazy="dynamic", cascade="all, delete-orphan")) + get_entry = relationship(MediaEntry, + backref=backref("comments", + lazy="dynamic", + cascade="all, delete-orphan")) # Cascade: Comments are somewhat owned by their MediaEntry. # So do the full thing. @@ -484,9 +487,103 @@ class ProcessingMetaData(Base): return DictReadAttrProxy(self) +class CommentSubscription(Base): + __tablename__ = 'core__comment_subscriptions' + id = Column(Integer, primary_key=True) + + created = Column(DateTime, nullable=False, default=datetime.datetime.now) + + media_entry_id = Column(Integer, ForeignKey(MediaEntry.id), nullable=False) + media_entry = relationship(MediaEntry, + backref=backref('comment_subscriptions', + cascade='all, delete-orphan')) + + user_id = Column(Integer, ForeignKey(User.id), nullable=False) + user = relationship(User, + backref=backref('comment_subscriptions', + cascade='all, delete-orphan')) + + notify = Column(Boolean, nullable=False, default=True) + send_email = Column(Boolean, nullable=False, default=True) + + def __repr__(self): + return ('<{classname} #{id}: {user} {media} notify: ' + '{notify} email: {email}>').format( + id=self.id, + classname=self.__class__.__name__, + user=self.user, + media=self.media_entry, + notify=self.notify, + email=self.send_email) + + +class Notification(Base): + __tablename__ = 'core__notifications' + id = Column(Integer, primary_key=True) + type = Column(Unicode) + + created = Column(DateTime, nullable=False, default=datetime.datetime.now) + + user_id = Column(Integer, ForeignKey('core__users.id'), nullable=False, + index=True) + seen = Column(Boolean, default=lambda: False, index=True) + user = relationship( + User, + backref=backref('notifications', cascade='all, delete-orphan')) + + __mapper_args__ = { + 'polymorphic_identity': 'notification', + 'polymorphic_on': type + } + + def __repr__(self): + return '<{klass} #{id}: {user}: {subject} ({seen})>'.format( + id=self.id, + klass=self.__class__.__name__, + user=self.user, + subject=getattr(self, 'subject', None), + seen='unseen' if not self.seen else 'seen') + + +class CommentNotification(Notification): + __tablename__ = 'core__comment_notifications' + id = Column(Integer, ForeignKey(Notification.id), primary_key=True) + + subject_id = Column(Integer, ForeignKey(MediaComment.id)) + subject = relationship( + MediaComment, + backref=backref('comment_notifications', cascade='all, delete-orphan')) + + __mapper_args__ = { + 'polymorphic_identity': 'comment_notification' + } + + +class ProcessingNotification(Notification): + __tablename__ = 'core__processing_notifications' + + id = Column(Integer, ForeignKey(Notification.id), primary_key=True) + + subject_id = Column(Integer, ForeignKey(MediaEntry.id)) + subject = relationship( + MediaEntry, + backref=backref('processing_notifications', + cascade='all, delete-orphan')) + + __mapper_args__ = { + 'polymorphic_identity': 'processing_notification' + } + + +with_polymorphic( + Notification, + [ProcessingNotification, CommentNotification]) + MODELS = [ - User, MediaEntry, Tag, MediaTag, MediaComment, Collection, CollectionItem, MediaFile, FileKeynames, - MediaAttachmentFile, ProcessingMetaData] + User, MediaEntry, Tag, MediaTag, MediaComment, Collection, CollectionItem, + MediaFile, FileKeynames, MediaAttachmentFile, ProcessingMetaData, + Notification, CommentNotification, ProcessingNotification, + CommentSubscription] ###################################################### diff --git a/mediagoblin/db/models_v0.py b/mediagoblin/db/models_v0.py index ec51a1f5..bdedec2e 100644 --- a/mediagoblin/db/models_v0.py +++ b/mediagoblin/db/models_v0.py @@ -18,6 +18,29 @@ TODO: indexes on foreignkeys, where useful. """ +########################################################################### +# WHAT IS THIS FILE? +# ------------------ +# +# Upon occasion, someone runs into this file and wonders why we have +# both a models.py and a models_v0.py. +# +# The short of it is: you can ignore this file. +# +# The long version is, in two parts: +# +# - We used to use MongoDB, then we switched to SQL and SQLAlchemy. +# We needed to convert peoples' databases; the script we had would +# switch them to the first version right after Mongo, convert over +# all their tables, then run any migrations that were added after. +# +# - That script is now removed, but there is some discussion of +# writing a test that would set us at the first SQL migration and +# run everything after. If we wrote that, this file would still be +# useful. But for now, it's legacy! +# +########################################################################### + import datetime import sys diff --git a/mediagoblin/edit/forms.py b/mediagoblin/edit/forms.py index 3b2486de..24b31a76 100644 --- a/mediagoblin/edit/forms.py +++ b/mediagoblin/edit/forms.py @@ -16,9 +16,11 @@ import wtforms -from mediagoblin.tools.text import tag_length_validator, TOO_LONG_TAG_WARNING +from mediagoblin.tools.text import tag_length_validator from mediagoblin.tools.translate import lazy_pass_to_ugettext as _ from mediagoblin.tools.licenses import licenses_as_choices +from mediagoblin.auth.forms import normalize_user_or_email_field + class EditForm(wtforms.Form): title = wtforms.TextField( @@ -59,6 +61,10 @@ class EditProfileForm(wtforms.Form): class EditAccountForm(wtforms.Form): + new_email = wtforms.TextField( + _('New email address'), + [wtforms.validators.Optional(), + normalize_user_or_email_field(allow_user=False)]) license_preference = wtforms.SelectField( _('License preference'), [ diff --git a/mediagoblin/edit/routing.py b/mediagoblin/edit/routing.py index 622729ac..3592f708 100644 --- a/mediagoblin/edit/routing.py +++ b/mediagoblin/edit/routing.py @@ -26,3 +26,5 @@ add_route('mediagoblin.edit.delete_account', '/edit/account/delete/', 'mediagoblin.edit.views:delete_account') add_route('mediagoblin.edit.pass', '/edit/password/', 'mediagoblin.edit.views:change_pass') +add_route('mediagoblin.edit.verify_email', '/edit/verify_email/', + 'mediagoblin.edit.views:verify_email') diff --git a/mediagoblin/edit/views.py b/mediagoblin/edit/views.py index 161285a2..429eb584 100644 --- a/mediagoblin/edit/views.py +++ b/mediagoblin/edit/views.py @@ -16,6 +16,7 @@ from datetime import datetime +from itsdangerous import BadSignature from werkzeug.exceptions import Forbidden from werkzeug.utils import secure_filename @@ -26,15 +27,19 @@ from mediagoblin import auth from mediagoblin.edit import forms from mediagoblin.edit.lib import may_edit_media from mediagoblin.decorators import (require_active_login, active_user_from_url, - get_media_entry_by_id, - user_may_alter_collection, get_user_collection) -from mediagoblin.tools.response import render_to_response, \ - redirect, redirect_obj + get_media_entry_by_id, user_may_alter_collection, + get_user_collection) +from mediagoblin.tools.crypto import get_timed_signer_url +from mediagoblin.tools.mail import email_debug_message +from mediagoblin.tools.response import (render_to_response, + redirect, redirect_obj, render_404) from mediagoblin.tools.translate import pass_to_ugettext as _ +from mediagoblin.tools.template import render_template from mediagoblin.tools.text import ( convert_to_tag_list_of_dicts, media_tags_as_string) from mediagoblin.tools.url import slugify from mediagoblin.db.util import check_media_slug_used, check_collection_slug_used +from mediagoblin.db.models import User import mimetypes @@ -212,6 +217,10 @@ def edit_profile(request, url_user=None): {'user': user, 'form': form}) +EMAIL_VERIFICATION_TEMPLATE = ( + u'{uri}?' + u'token={verification_key}') + @require_active_login def edit_account(request): @@ -220,27 +229,45 @@ def edit_account(request): wants_comment_notification=user.wants_comment_notification, license_preference=user.license_preference) - if request.method == 'POST': - form_validated = form.validate() + if request.method == 'POST' and form.validate(): + user.wants_comment_notification = form.wants_comment_notification.data - if form_validated and \ - form.wants_comment_notification.validate(form): - user.wants_comment_notification = \ - form.wants_comment_notification.data + user.license_preference = form.license_preference.data - if form_validated and \ - form.license_preference.validate(form): - user.license_preference = \ - form.license_preference.data + if form.new_email.data: + new_email = form.new_email.data + users_with_email = User.query.filter_by( + email=new_email).count() + if users_with_email: + form.new_email.errors.append( + _('Sorry, a user with that email address' + ' already exists.')) + else: + verification_key = get_timed_signer_url( + 'mail_verification_token').dumps({ + 'user': user.id, + 'email': new_email}) - if form_validated and not form.errors: + rendered_email = render_template( + request, 'mediagoblin/edit/verification.txt', + {'username': user.username, + 'verification_url': EMAIL_VERIFICATION_TEMPLATE.format( + uri=request.urlgen('mediagoblin.edit.verify_email', + qualified=True), + verification_key=verification_key)}) + + email_debug_message(request) + auth_tools.send_verification_email(user, request, new_email, + rendered_email) + + if not form.errors: user.save() messages.add_message(request, - messages.SUCCESS, - _("Account settings saved")) + messages.SUCCESS, + _("Account settings saved")) return redirect(request, - 'mediagoblin.user_pages.user_home', - user=user.username) + 'mediagoblin.user_pages.user_home', + user=user.username) return render_to_response( request, @@ -369,3 +396,48 @@ def change_pass(request): 'mediagoblin/edit/change_pass.html', {'form': form, 'user': user}) + + +def verify_email(request): + """ + Email verification view for changing email address + """ + # If no token, we can't do anything + if not 'token' in request.GET: + return render_404(request) + + # Catch error if token is faked or expired + token = None + try: + token = get_timed_signer_url("mail_verification_token") \ + .loads(request.GET['token'], max_age=10*24*3600) + except BadSignature: + messages.add_message( + request, + messages.ERROR, + _('The verification key or user id is incorrect.')) + + return redirect( + request, + 'index') + + user = User.query.filter_by(id=int(token['user'])).first() + + if user: + user.email = token['email'] + user.save() + + messages.add_message( + request, + messages.SUCCESS, + _('Your email address has been verified.')) + + else: + messages.add_message( + request, + messages.ERROR, + _('The verification key or user id is incorrect.')) + + return redirect( + request, 'mediagoblin.user_pages.user_home', + user=user.username) diff --git a/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.mo index a07400ae..e2fcf85d 100644 Binary files a/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.mo and b/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.mo differ diff --git a/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.po index 4bde0095..e2147070 100644 --- a/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.po @@ -15,15 +15,15 @@ # Elrond , 2011 # Art O. Pal , 2011 # spaetz , 2012 -# Vinzenz Vietzke , 2012 -# Vinzenz Vietzke , 2011 +# Vinzenz Vietzke , 2012 +# Vinzenz Vietzke , 2011 msgid "" msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" "POT-Creation-Date: 2013-05-27 13:54-0500\n" -"PO-Revision-Date: 2013-05-27 18:54+0000\n" -"Last-Translator: cwebber \n" +"PO-Revision-Date: 2013-05-28 10:43+0000\n" +"Last-Translator: Elrond \n" "Language-Team: German (http://www.transifex.com/projects/p/mediagoblin/language/de/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -47,7 +47,7 @@ msgstr "E-Mail-Adresse" #: mediagoblin/auth/forms.py:41 msgid "Username or Email" -msgstr "" +msgstr "Benutzername oder E-Mail-Adresse" #: mediagoblin/auth/forms.py:52 msgid "Username or email" @@ -628,7 +628,7 @@ msgid "" "Create an account at this site\n" " or\n" " Set up MediaGoblin on your own server" -msgstr "" +msgstr "Registriere dich auf dieser Seite oder Installiere MediaGoblin auf deinem eigenen Server" #: mediagoblin/templates/mediagoblin/bits/logo.html:23 #: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 @@ -784,7 +784,7 @@ msgstr "Bild für %(media_title)s" #: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 msgid "PDF file" -msgstr "" +msgstr "PDF-Datei" #: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 msgid "Toggle Rotate" @@ -944,11 +944,11 @@ msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/media.html:150 msgid "Added" -msgstr "" +msgstr "Hinzugefügt" #: mediagoblin/templates/mediagoblin/user_pages/media.html:161 msgid "Created" -msgstr "" +msgstr "Originaldatum" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:40 @@ -1136,27 +1136,27 @@ msgstr "Tut uns Leid, aber unter der angegebenen Adresse gibt es keine Seite!

\n" "Language-Team: LANGUAGE \n" @@ -17,94 +17,94 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 0.9.6\n" -#: mediagoblin/auth/forms.py:26 +#: mediagoblin/auth/forms.py:25 msgid "Username" msgstr "" -#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 +#: mediagoblin/auth/forms.py:29 mediagoblin/auth/forms.py:44 #: mediagoblin/tests/test_util.py:110 msgid "Password" msgstr "" -#: mediagoblin/auth/forms.py:34 +#: mediagoblin/auth/forms.py:33 msgid "Email address" msgstr "" -#: mediagoblin/auth/forms.py:41 +#: mediagoblin/auth/forms.py:40 msgid "Username or Email" msgstr "" -#: mediagoblin/auth/forms.py:52 +#: mediagoblin/auth/forms.py:51 msgid "Username or email" msgstr "" -#: mediagoblin/auth/tools.py:31 +#: mediagoblin/auth/tools.py:42 msgid "Invalid User name or email address." msgstr "" -#: mediagoblin/auth/tools.py:32 +#: mediagoblin/auth/tools.py:43 msgid "This field does not take email addresses." msgstr "" -#: mediagoblin/auth/tools.py:33 +#: mediagoblin/auth/tools.py:44 msgid "This field requires an email address." msgstr "" -#: mediagoblin/auth/views.py:54 -msgid "Sorry, registration is disabled on this instance." -msgstr "" - -#: mediagoblin/auth/views.py:68 +#: mediagoblin/auth/tools.py:109 msgid "Sorry, a user with that name already exists." msgstr "" -#: mediagoblin/auth/views.py:72 +#: mediagoblin/auth/tools.py:113 msgid "Sorry, a user with that email address already exists." msgstr "" -#: mediagoblin/auth/views.py:182 +#: mediagoblin/auth/views.py:43 +msgid "Sorry, registration is disabled on this instance." +msgstr "" + +#: mediagoblin/auth/views.py:133 msgid "" "Your email address has been verified. You may now login, edit your " "profile, and submit images!" msgstr "" -#: mediagoblin/auth/views.py:188 +#: mediagoblin/auth/views.py:139 msgid "The verification key or user id is incorrect" msgstr "" -#: mediagoblin/auth/views.py:206 +#: mediagoblin/auth/views.py:157 msgid "You must be logged in so we know who to send the email to!" msgstr "" -#: mediagoblin/auth/views.py:214 +#: mediagoblin/auth/views.py:165 msgid "You've already verified your email address!" msgstr "" -#: mediagoblin/auth/views.py:227 +#: mediagoblin/auth/views.py:178 msgid "Resent your verification email." msgstr "" -#: mediagoblin/auth/views.py:258 +#: mediagoblin/auth/views.py:209 msgid "" "If that email address (case sensitive!) is registered an email has been " "sent with instructions on how to change your password." msgstr "" -#: mediagoblin/auth/views.py:269 +#: mediagoblin/auth/views.py:220 msgid "Couldn't find someone with that username." msgstr "" -#: mediagoblin/auth/views.py:272 +#: mediagoblin/auth/views.py:223 msgid "An email has been sent with instructions on how to change your password." msgstr "" -#: mediagoblin/auth/views.py:279 +#: mediagoblin/auth/views.py:230 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:336 +#: mediagoblin/auth/views.py:287 msgid "You can now log in using your new password." msgstr "" @@ -634,13 +634,13 @@ msgid "Editing attachments for %(media_title)s" msgstr "" #: mediagoblin/templates/mediagoblin/edit/attachments.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:182 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:198 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:171 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:187 msgid "Attachments" msgstr "" #: mediagoblin/templates/mediagoblin/edit/attachments.html:57 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:204 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:193 msgid "Add attachment" msgstr "" @@ -763,6 +763,17 @@ msgstr "" msgid "WebM file (Vorbis codec)" msgstr "" +#: mediagoblin/templates/mediagoblin/media_displays/image.html:36 +msgid "Created" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/image.html:39 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:132 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:152 +#, python-format +msgid "%(formatted_time)s ago" +msgstr "" + #: mediagoblin/templates/mediagoblin/media_displays/pdf.html:59 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:87 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:93 @@ -928,21 +939,10 @@ msgstr "" msgid "Add this comment" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:132 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:152 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:164 -#, python-format -msgid "%(formatted_time)s ago" -msgstr "" - #: mediagoblin/templates/mediagoblin/user_pages/media.html:150 msgid "Added" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:161 -msgid "Created" -msgstr "" - #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:40 #, python-format diff --git a/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.mo index 406b269f..645af16b 100644 Binary files a/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.mo and b/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.mo differ diff --git a/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.po index eb1ec1ec..873869f0 100644 --- a/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.po @@ -12,8 +12,8 @@ msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" "POT-Creation-Date: 2013-05-27 13:54-0500\n" -"PO-Revision-Date: 2013-05-27 18:54+0000\n" -"Last-Translator: cwebber \n" +"PO-Revision-Date: 2013-06-01 21:16+0000\n" +"Last-Translator: aleksejrs \n" "Language-Team: Esperanto (http://www.transifex.com/projects/p/mediagoblin/language/eo/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -37,7 +37,7 @@ msgstr "Retpoŝtadreso" #: mediagoblin/auth/forms.py:41 msgid "Username or Email" -msgstr "" +msgstr "Uzantonomo aŭ retpoŝtadreso" #: mediagoblin/auth/forms.py:52 msgid "Username or email" @@ -178,7 +178,7 @@ msgstr "Permesila prefero" #: mediagoblin/edit/forms.py:69 msgid "This will be your default license on upload forms." -msgstr "" +msgstr "Tiu ĉi permesilo estos antaŭelektita en la alŝutformularoj." #: mediagoblin/edit/forms.py:71 msgid "Email me when others comment on my media" @@ -264,7 +264,7 @@ msgstr "Malĝusta pasvorto" #: mediagoblin/edit/views.py:363 msgid "Your password was changed successfully" -msgstr "" +msgstr "Via pasvorto estas sukcese ŝanĝita" #: mediagoblin/gmg_commands/assetlink.py:60 msgid "Cannot link theme... no theme set\n" @@ -665,11 +665,11 @@ msgstr "Konservi ŝanĝojn" #: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 #, python-format msgid "Changing %(username)s's password" -msgstr "" +msgstr "Ŝanĝado de pasvorto de %(username)s" #: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 msgid "Save" -msgstr "" +msgstr "Konservi" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 #, python-format @@ -700,7 +700,7 @@ msgstr "Ŝanĝado de kontagordoj de %(username)s" #: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 msgid "Change your password." -msgstr "" +msgstr "Ŝanĝi la pasvorton" #: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 msgid "Delete my account" @@ -774,7 +774,7 @@ msgstr "Bildo de «%(media_title)s»" #: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 msgid "PDF file" -msgstr "" +msgstr "PDF-dosiero" #: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 msgid "Toggle Rotate" @@ -930,15 +930,15 @@ msgstr "Aldoni ĉi tiun komenton" #: mediagoblin/templates/mediagoblin/user_pages/media.html:164 #, python-format msgid "%(formatted_time)s ago" -msgstr "" +msgstr "antaŭ %(formatted_time)s" #: mediagoblin/templates/mediagoblin/user_pages/media.html:150 msgid "Added" -msgstr "" +msgstr "Aldonita" #: mediagoblin/templates/mediagoblin/user_pages/media.html:161 msgid "Created" -msgstr "" +msgstr "Kreita" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:40 @@ -1126,27 +1126,27 @@ msgstr "" #: mediagoblin/tools/timesince.py:62 msgid "year" -msgstr "" +msgstr "jaro(j)" #: mediagoblin/tools/timesince.py:63 msgid "month" -msgstr "" +msgstr "monato(j)" #: mediagoblin/tools/timesince.py:64 msgid "week" -msgstr "" +msgstr "semajno(j)" #: mediagoblin/tools/timesince.py:65 msgid "day" -msgstr "" +msgstr "tago(j)" #: mediagoblin/tools/timesince.py:66 msgid "hour" -msgstr "" +msgstr "horo(j)" #: mediagoblin/tools/timesince.py:67 msgid "minute" -msgstr "" +msgstr "minuto(j)" #: mediagoblin/user_pages/forms.py:23 msgid "Comment" @@ -1185,7 +1185,7 @@ msgstr "komentis je via afiŝo" #: mediagoblin/user_pages/views.py:169 msgid "Sorry, comments are disabled." -msgstr "" +msgstr "Ve, komentado estas malebligita." #: mediagoblin/user_pages/views.py:174 msgid "Oops, your comment was empty." diff --git a/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.mo index ececfb2e..c5e50f53 100644 Binary files a/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.mo and b/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.mo differ diff --git a/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.po index 03e755ab..8c2f046f 100644 --- a/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.po @@ -20,8 +20,8 @@ msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" "POT-Creation-Date: 2013-05-27 13:54-0500\n" -"PO-Revision-Date: 2013-05-27 18:54+0000\n" -"Last-Translator: cwebber \n" +"PO-Revision-Date: 2013-06-02 21:23+0000\n" +"Last-Translator: larjona \n" "Language-Team: Spanish (http://www.transifex.com/projects/p/mediagoblin/language/es/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -45,7 +45,7 @@ msgstr "Dirección de correo electrónico" #: mediagoblin/auth/forms.py:41 msgid "Username or Email" -msgstr "" +msgstr "Nombre de usuario o correo electrónico" #: mediagoblin/auth/forms.py:52 msgid "Username or email" @@ -272,7 +272,7 @@ msgstr "Contraseña incorrecta" #: mediagoblin/edit/views.py:363 msgid "Your password was changed successfully" -msgstr "" +msgstr "Se ha cambiado la contraseña correctamente" #: mediagoblin/gmg_commands/assetlink.py:60 msgid "Cannot link theme... no theme set\n" @@ -289,17 +289,17 @@ msgstr "Sin embargo, se encontró un enlace simbólico de un directorio antiguo; #: mediagoblin/gmg_commands/assetlink.py:112 #, python-format msgid "Could not link \"%s\": %s exists and is not a symlink\n" -msgstr "" +msgstr "No se pudo enlazar \"%s\": %s existe y no es un enlace simbólico\n" #: mediagoblin/gmg_commands/assetlink.py:119 #, python-format msgid "Skipping \"%s\"; already set up.\n" -msgstr "" +msgstr "Omitiendo \"%s\"; ya está establecido.\n" #: mediagoblin/gmg_commands/assetlink.py:124 #, python-format msgid "Old link found for \"%s\"; removing.\n" -msgstr "" +msgstr "Se encontró un enlace antiguo para \"%s\"; se eliminará.\n" #: mediagoblin/meddleware/csrf.py:134 msgid "" @@ -315,7 +315,7 @@ msgstr "Lo sentidos, No soportamos ese tipo de archivo :(" #: mediagoblin/media_types/pdf/processing.py:136 msgid "unoconv failing to run, check log file" -msgstr "" +msgstr "ha fallado la ejecución de unoconv, comprueba el fichero de registro (log)" #: mediagoblin/media_types/video/processing.py:37 msgid "Video transcoding failed" @@ -626,7 +626,7 @@ msgid "" "Create an account at this site\n" " or\n" " Set up MediaGoblin on your own server" -msgstr "" +msgstr "Crear una cuenta en este sitio\n o\n Instalar MediaGoblin en tu propio servidor" #: mediagoblin/templates/mediagoblin/bits/logo.html:23 #: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 @@ -673,11 +673,11 @@ msgstr "Guardar cambios" #: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 #, python-format msgid "Changing %(username)s's password" -msgstr "" +msgstr "Cambiando la contraseña de %(username)s" #: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 msgid "Save" -msgstr "" +msgstr "Guardar" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 #, python-format @@ -708,7 +708,7 @@ msgstr "Cambio de %(username)s la configuración de la cuenta " #: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 msgid "Change your password." -msgstr "" +msgstr "Cambiar tu contraseña." #: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 msgid "Delete my account" @@ -782,7 +782,7 @@ msgstr "Imágenes para %(media_title)s" #: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 msgid "PDF file" -msgstr "" +msgstr "Fichero PDF" #: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 msgid "Toggle Rotate" @@ -938,15 +938,15 @@ msgstr "Añade un comentario " #: mediagoblin/templates/mediagoblin/user_pages/media.html:164 #, python-format msgid "%(formatted_time)s ago" -msgstr "" +msgstr "hace %(formatted_time)s" #: mediagoblin/templates/mediagoblin/user_pages/media.html:150 msgid "Added" -msgstr "" +msgstr "Agregado" #: mediagoblin/templates/mediagoblin/user_pages/media.html:161 msgid "Created" -msgstr "" +msgstr "Creado" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:40 @@ -1134,27 +1134,27 @@ msgstr "Parece que no hay ninguna página en esta dirección. ¡Lo siento!

\n" +"PO-Revision-Date: 2013-06-01 07:11+0000\n" +"Last-Translator: GenghisKhan \n" "Language-Team: Hebrew (http://www.transifex.com/projects/p/mediagoblin/language/he/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -36,7 +36,7 @@ msgstr "כתובת דוא״ל" #: mediagoblin/auth/forms.py:41 msgid "Username or Email" -msgstr "" +msgstr "שם משתמש או דוא״ל" #: mediagoblin/auth/forms.py:52 msgid "Username or email" @@ -263,7 +263,7 @@ msgstr "סיסמה שגויה" #: mediagoblin/edit/views.py:363 msgid "Your password was changed successfully" -msgstr "" +msgstr "סיסמתך שונתה בהצלחה" #: mediagoblin/gmg_commands/assetlink.py:60 msgid "Cannot link theme... no theme set\n" @@ -280,17 +280,17 @@ msgstr "בכל אופן, קישור מדור symlink נמצא; הוסר.\n" #: mediagoblin/gmg_commands/assetlink.py:112 #, python-format msgid "Could not link \"%s\": %s exists and is not a symlink\n" -msgstr "" +msgstr "לא היתה אפשרות לקשר את \"%s\": %s קיים ואינו קישור סמלי (symlink)\n" #: mediagoblin/gmg_commands/assetlink.py:119 #, python-format msgid "Skipping \"%s\"; already set up.\n" -msgstr "" +msgstr "מדלג על \"%s\"; כבר מוגדר.\n" #: mediagoblin/gmg_commands/assetlink.py:124 #, python-format msgid "Old link found for \"%s\"; removing.\n" -msgstr "" +msgstr "קישור ישן נמצא עבור \"%s\"; מסיר כעת.\n" #: mediagoblin/meddleware/csrf.py:134 msgid "" @@ -306,7 +306,7 @@ msgstr "צר לי, אינני תומך בטיפוס קובץ זה :(" #: mediagoblin/media_types/pdf/processing.py:136 msgid "unoconv failing to run, check log file" -msgstr "" +msgstr "unoconv נכשל לפעול, בדוק קובץ יומן" #: mediagoblin/media_types/video/processing.py:37 msgid "Video transcoding failed" @@ -617,7 +617,7 @@ msgid "" "Create an account at this site\n" " or\n" " Set up MediaGoblin on your own server" -msgstr "" +msgstr "צור חשבון באתר זה\n או\n התקן את MediaGoblin על שרתך" #: mediagoblin/templates/mediagoblin/bits/logo.html:23 #: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 @@ -664,11 +664,11 @@ msgstr "שמור שינויים" #: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 #, python-format msgid "Changing %(username)s's password" -msgstr "" +msgstr "משנה כעת את הסיסמה של %(username)s'" #: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 msgid "Save" -msgstr "" +msgstr "שמור" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 #, python-format @@ -699,7 +699,7 @@ msgstr "שינוי הגדרות חשבון עבור %(username)s" #: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 msgid "Change your password." -msgstr "" +msgstr "שנה את סיסמתך." #: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 msgid "Delete my account" @@ -773,7 +773,7 @@ msgstr "תמונה עבור %(media_title)s" #: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 msgid "PDF file" -msgstr "" +msgstr "קובץ PDF" #: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 msgid "Toggle Rotate" @@ -929,15 +929,15 @@ msgstr "הוסף את תגובה זו" #: mediagoblin/templates/mediagoblin/user_pages/media.html:164 #, python-format msgid "%(formatted_time)s ago" -msgstr "" +msgstr "מלפני %(formatted_time)s" #: mediagoblin/templates/mediagoblin/user_pages/media.html:150 msgid "Added" -msgstr "" +msgstr "התווסף" #: mediagoblin/templates/mediagoblin/user_pages/media.html:161 msgid "Created" -msgstr "" +msgstr "נוצר" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:40 @@ -1125,27 +1125,27 @@ msgstr "לא נראה שקיים עמוד בכתובת זו. צר לי!

א #: mediagoblin/tools/timesince.py:62 msgid "year" -msgstr "" +msgstr "שנה" #: mediagoblin/tools/timesince.py:63 msgid "month" -msgstr "" +msgstr "חודש" #: mediagoblin/tools/timesince.py:64 msgid "week" -msgstr "" +msgstr "שבוע" #: mediagoblin/tools/timesince.py:65 msgid "day" -msgstr "" +msgstr "יום" #: mediagoblin/tools/timesince.py:66 msgid "hour" -msgstr "" +msgstr "שעה" #: mediagoblin/tools/timesince.py:67 msgid "minute" -msgstr "" +msgstr "דקה" #: mediagoblin/user_pages/forms.py:23 msgid "Comment" @@ -1184,7 +1184,7 @@ msgstr "הגיב/ה על פרסומך" #: mediagoblin/user_pages/views.py:169 msgid "Sorry, comments are disabled." -msgstr "" +msgstr "מצטערים, תגובות מנוטרלות." #: mediagoblin/user_pages/views.py:174 msgid "Oops, your comment was empty." diff --git a/mediagoblin/i18n/is_IS/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/is_IS/LC_MESSAGES/mediagoblin.mo index 2fb3a8ce..596ab843 100644 Binary files a/mediagoblin/i18n/is_IS/LC_MESSAGES/mediagoblin.mo and b/mediagoblin/i18n/is_IS/LC_MESSAGES/mediagoblin.mo differ diff --git a/mediagoblin/i18n/is_IS/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/is_IS/LC_MESSAGES/mediagoblin.po index 81ca3838..77896b87 100644 --- a/mediagoblin/i18n/is_IS/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/is_IS/LC_MESSAGES/mediagoblin.po @@ -10,8 +10,8 @@ msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" "POT-Creation-Date: 2013-05-27 13:54-0500\n" -"PO-Revision-Date: 2013-05-27 18:54+0000\n" -"Last-Translator: cwebber \n" +"PO-Revision-Date: 2013-06-05 22:51+0000\n" +"Last-Translator: tryggvib \n" "Language-Team: Icelandic (Iceland) (http://www.transifex.com/projects/p/mediagoblin/language/is_IS/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -35,7 +35,7 @@ msgstr "Netfang" #: mediagoblin/auth/forms.py:41 msgid "Username or Email" -msgstr "" +msgstr "Notandanafn eða tölvupóstur" #: mediagoblin/auth/forms.py:52 msgid "Username or email" @@ -262,7 +262,7 @@ msgstr "Vitlaust lykilorð" #: mediagoblin/edit/views.py:363 msgid "Your password was changed successfully" -msgstr "" +msgstr "Það tókst að breyta lykilorðinu þínu" #: mediagoblin/gmg_commands/assetlink.py:60 msgid "Cannot link theme... no theme set\n" @@ -279,17 +279,17 @@ msgstr "Fann samt gamlan táknrænan tengil á möppu; fjarlægður.\n" #: mediagoblin/gmg_commands/assetlink.py:112 #, python-format msgid "Could not link \"%s\": %s exists and is not a symlink\n" -msgstr "" +msgstr "Gat ekki tengt \"%s\": %s er til og er ekki sýndartengill\n" #: mediagoblin/gmg_commands/assetlink.py:119 #, python-format msgid "Skipping \"%s\"; already set up.\n" -msgstr "" +msgstr "Hoppa yfir \"%s\"; hefur nú þegar verið sett upp.\n" #: mediagoblin/gmg_commands/assetlink.py:124 #, python-format msgid "Old link found for \"%s\"; removing.\n" -msgstr "" +msgstr "Gamall tengill fannst fyrir \"%s\"; fjarlægi.\n" #: mediagoblin/meddleware/csrf.py:134 msgid "" @@ -305,7 +305,7 @@ msgstr "Ég styð því miður ekki þessa gerð af skrám :(" #: mediagoblin/media_types/pdf/processing.py:136 msgid "unoconv failing to run, check log file" -msgstr "" +msgstr "tekst ekki að keyra unoconv, athugaðu annálsskrá" #: mediagoblin/media_types/video/processing.py:37 msgid "Video transcoding failed" @@ -616,7 +616,7 @@ msgid "" "Create an account at this site\n" " or\n" " Set up MediaGoblin on your own server" -msgstr "" +msgstr "Búa til aðgang á þessari síðu\neða\nSettu upp þinn eigin margmiðlunarþjón" #: mediagoblin/templates/mediagoblin/bits/logo.html:23 #: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 @@ -663,11 +663,11 @@ msgstr "Vista breytingar" #: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 #, python-format msgid "Changing %(username)s's password" -msgstr "" +msgstr "Breyti lykilorði fyrir notandann: %(username)s" #: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 msgid "Save" -msgstr "" +msgstr "Vista" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 #, python-format @@ -698,7 +698,7 @@ msgstr "Breyti notandaaðgangsstillingum fyrir: %(username)s" #: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 msgid "Change your password." -msgstr "" +msgstr "Breyta lykilorðinu þínu." #: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 msgid "Delete my account" @@ -772,7 +772,7 @@ msgstr "Mynd fyrir %(media_title)s" #: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 msgid "PDF file" -msgstr "" +msgstr "PDF skrá" #: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 msgid "Toggle Rotate" @@ -928,15 +928,15 @@ msgstr "Senda inn þessa athugasemd" #: mediagoblin/templates/mediagoblin/user_pages/media.html:164 #, python-format msgid "%(formatted_time)s ago" -msgstr "" +msgstr "Fyrir %(formatted_time)s" #: mediagoblin/templates/mediagoblin/user_pages/media.html:150 msgid "Added" -msgstr "" +msgstr "Bætt við" #: mediagoblin/templates/mediagoblin/user_pages/media.html:161 msgid "Created" -msgstr "" +msgstr "Skapað" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:40 @@ -1124,27 +1124,27 @@ msgstr "Því miður! Það virðist ekki vera nein síða á þessari vefslóð #: mediagoblin/tools/timesince.py:62 msgid "year" -msgstr "" +msgstr "ár" #: mediagoblin/tools/timesince.py:63 msgid "month" -msgstr "" +msgstr "mánuður" #: mediagoblin/tools/timesince.py:64 msgid "week" -msgstr "" +msgstr "vika" #: mediagoblin/tools/timesince.py:65 msgid "day" -msgstr "" +msgstr "dagur" #: mediagoblin/tools/timesince.py:66 msgid "hour" -msgstr "" +msgstr "klukkustund" #: mediagoblin/tools/timesince.py:67 msgid "minute" -msgstr "" +msgstr "mínúta" #: mediagoblin/user_pages/forms.py:23 msgid "Comment" @@ -1183,7 +1183,7 @@ msgstr "skrifaði athugasemd við færsluna þína" #: mediagoblin/user_pages/views.py:169 msgid "Sorry, comments are disabled." -msgstr "" +msgstr "Því miður, athugasemdir eru óvirkar." #: mediagoblin/user_pages/views.py:174 msgid "Oops, your comment was empty." diff --git a/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.mo index f9666be3..9cbd03b2 100644 Binary files a/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.mo and b/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.mo differ diff --git a/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.po index ea0d5d25..6a11d5da 100644 --- a/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.po @@ -10,8 +10,8 @@ msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" "POT-Creation-Date: 2013-05-27 13:54-0500\n" -"PO-Revision-Date: 2013-05-27 18:54+0000\n" -"Last-Translator: cwebber \n" +"PO-Revision-Date: 2013-05-31 15:40+0000\n" +"Last-Translator: velmont \n" "Language-Team: Norwegian Nynorsk (Norway) (http://www.transifex.com/projects/p/mediagoblin/language/nn_NO/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -35,7 +35,7 @@ msgstr "Epost" #: mediagoblin/auth/forms.py:41 msgid "Username or Email" -msgstr "" +msgstr "Brukarnamn eller epost" #: mediagoblin/auth/forms.py:52 msgid "Username or email" @@ -262,7 +262,7 @@ msgstr "Feil passord" #: mediagoblin/edit/views.py:363 msgid "Your password was changed successfully" -msgstr "" +msgstr "Endra passord" #: mediagoblin/gmg_commands/assetlink.py:60 msgid "Cannot link theme... no theme set\n" @@ -279,17 +279,17 @@ msgstr "However, old link directory symlink found; removed.\n" #: mediagoblin/gmg_commands/assetlink.py:112 #, python-format msgid "Could not link \"%s\": %s exists and is not a symlink\n" -msgstr "" +msgstr "Kunne ikkje lenkja «%s»: %s eksisterer og er ikkje ei symlenkje\n" #: mediagoblin/gmg_commands/assetlink.py:119 #, python-format msgid "Skipping \"%s\"; already set up.\n" -msgstr "" +msgstr "Hopper over «%s»: allereie satt opp.\n" #: mediagoblin/gmg_commands/assetlink.py:124 #, python-format msgid "Old link found for \"%s\"; removing.\n" -msgstr "" +msgstr "Gamal lenkje funnen for «%s»; fjernar.\n" #: mediagoblin/meddleware/csrf.py:134 msgid "" @@ -305,7 +305,7 @@ msgstr "Orsak, stør ikkje den filtypen :(" #: mediagoblin/media_types/pdf/processing.py:136 msgid "unoconv failing to run, check log file" -msgstr "" +msgstr "klarte ikkje køyra unoconv, sjekk logg-fil" #: mediagoblin/media_types/video/processing.py:37 msgid "Video transcoding failed" @@ -616,7 +616,7 @@ msgid "" "Create an account at this site\n" " or\n" " Set up MediaGoblin on your own server" -msgstr "" +msgstr "Opprett ein konto på denne sida\n eller\n Set opp din eigen MediaGoblin-server" #: mediagoblin/templates/mediagoblin/bits/logo.html:23 #: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 @@ -663,11 +663,11 @@ msgstr "Lagra" #: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 #, python-format msgid "Changing %(username)s's password" -msgstr "" +msgstr "Endrar passordet til %(username)s" #: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 msgid "Save" -msgstr "" +msgstr "Lagra" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 #, python-format @@ -698,7 +698,7 @@ msgstr "Endrar kontoinnstellingane til %(username)s" #: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 msgid "Change your password." -msgstr "" +msgstr "Endra passordet ditt." #: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 msgid "Delete my account" @@ -772,7 +772,7 @@ msgstr "Bilete for %(media_title)s" #: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 msgid "PDF file" -msgstr "" +msgstr "PDF-fil" #: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 msgid "Toggle Rotate" @@ -928,15 +928,15 @@ msgstr "Legg til dette innspelet" #: mediagoblin/templates/mediagoblin/user_pages/media.html:164 #, python-format msgid "%(formatted_time)s ago" -msgstr "" +msgstr "%(formatted_time)s sidan" #: mediagoblin/templates/mediagoblin/user_pages/media.html:150 msgid "Added" -msgstr "" +msgstr "Lagt til" #: mediagoblin/templates/mediagoblin/user_pages/media.html:161 msgid "Created" -msgstr "" +msgstr "Oppretta" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:40 @@ -1124,27 +1124,27 @@ msgstr "Ser ikkje ut til å finnast noko her. Orsak.

\n

Dersom du er sikker #: mediagoblin/tools/timesince.py:62 msgid "year" -msgstr "" +msgstr "år" #: mediagoblin/tools/timesince.py:63 msgid "month" -msgstr "" +msgstr "månad" #: mediagoblin/tools/timesince.py:64 msgid "week" -msgstr "" +msgstr "veke" #: mediagoblin/tools/timesince.py:65 msgid "day" -msgstr "" +msgstr "dag" #: mediagoblin/tools/timesince.py:66 msgid "hour" -msgstr "" +msgstr "time" #: mediagoblin/tools/timesince.py:67 msgid "minute" -msgstr "" +msgstr "minutt" #: mediagoblin/user_pages/forms.py:23 msgid "Comment" @@ -1183,7 +1183,7 @@ msgstr "kom med innspel på innlegget ditt" #: mediagoblin/user_pages/views.py:169 msgid "Sorry, comments are disabled." -msgstr "" +msgstr "Innspel er avslege" #: mediagoblin/user_pages/views.py:174 msgid "Oops, your comment was empty." diff --git a/mediagoblin/i18n/pl/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/pl/LC_MESSAGES/mediagoblin.mo index 5a234c82..8b318329 100644 Binary files a/mediagoblin/i18n/pl/LC_MESSAGES/mediagoblin.mo and b/mediagoblin/i18n/pl/LC_MESSAGES/mediagoblin.mo differ diff --git a/mediagoblin/i18n/pl/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/pl/LC_MESSAGES/mediagoblin.po index 5a36889a..78ab219a 100644 --- a/mediagoblin/i18n/pl/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/pl/LC_MESSAGES/mediagoblin.po @@ -10,8 +10,8 @@ msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" "POT-Creation-Date: 2013-05-27 13:54-0500\n" -"PO-Revision-Date: 2013-05-27 18:54+0000\n" -"Last-Translator: cwebber \n" +"PO-Revision-Date: 2013-05-28 13:51+0000\n" +"Last-Translator: Sergiusz Pawlowicz \n" "Language-Team: Polish (http://www.transifex.com/projects/p/mediagoblin/language/pl/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -35,7 +35,7 @@ msgstr "Adres e-mail" #: mediagoblin/auth/forms.py:41 msgid "Username or Email" -msgstr "" +msgstr "Nazwa konta lub adres poczty elektronicznej" #: mediagoblin/auth/forms.py:52 msgid "Username or email" @@ -262,7 +262,7 @@ msgstr "Nieprawidłowe hasło" #: mediagoblin/edit/views.py:363 msgid "Your password was changed successfully" -msgstr "" +msgstr "Twoje hasło zostało zmienione" #: mediagoblin/gmg_commands/assetlink.py:60 msgid "Cannot link theme... no theme set\n" @@ -279,17 +279,17 @@ msgstr "Znaleziono stary odnośnik symboliczny do katalogu; usunięto.\n" #: mediagoblin/gmg_commands/assetlink.py:112 #, python-format msgid "Could not link \"%s\": %s exists and is not a symlink\n" -msgstr "" +msgstr "Nie mogę zrobić odnośnika \"%s\": %s istnieje i nie jest odnośnikiem\n" #: mediagoblin/gmg_commands/assetlink.py:119 #, python-format msgid "Skipping \"%s\"; already set up.\n" -msgstr "" +msgstr "Opuszczam \"%s\"; już jest gotowe.\n" #: mediagoblin/gmg_commands/assetlink.py:124 #, python-format msgid "Old link found for \"%s\"; removing.\n" -msgstr "" +msgstr "Znaleziono stary odnośnik dla \"%s\"; usuwam.\n" #: mediagoblin/meddleware/csrf.py:134 msgid "" @@ -305,7 +305,7 @@ msgstr "NIestety, nie obsługujemy tego typu plików :-(" #: mediagoblin/media_types/pdf/processing.py:136 msgid "unoconv failing to run, check log file" -msgstr "" +msgstr "nie dało się uruchomić unoconv, sprawdź log" #: mediagoblin/media_types/video/processing.py:37 msgid "Video transcoding failed" @@ -616,7 +616,7 @@ msgid "" "Create an account at this site\n" " or\n" " Set up MediaGoblin on your own server" -msgstr "" +msgstr "Załóż konto na tym serwerze\n albo\n Uruchom MediaGoblin na swoim własnym serwerze" #: mediagoblin/templates/mediagoblin/bits/logo.html:23 #: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 @@ -663,11 +663,11 @@ msgstr "Zapisz zmiany" #: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 #, python-format msgid "Changing %(username)s's password" -msgstr "" +msgstr "Zmieniam hasło użytkownika %(username)s" #: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 msgid "Save" -msgstr "" +msgstr "Zachowaj" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 #, python-format @@ -698,7 +698,7 @@ msgstr "Zmiana ustawień konta %(username)s" #: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 msgid "Change your password." -msgstr "" +msgstr "Zmień swoje hasło." #: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 msgid "Delete my account" @@ -772,7 +772,7 @@ msgstr "Grafika dla %(media_title)s" #: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 msgid "PDF file" -msgstr "" +msgstr "Plik PDF" #: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 msgid "Toggle Rotate" @@ -928,15 +928,15 @@ msgstr "Dodaj komentarz" #: mediagoblin/templates/mediagoblin/user_pages/media.html:164 #, python-format msgid "%(formatted_time)s ago" -msgstr "" +msgstr "%(formatted_time)s temu" #: mediagoblin/templates/mediagoblin/user_pages/media.html:150 msgid "Added" -msgstr "" +msgstr "Dodano" #: mediagoblin/templates/mediagoblin/user_pages/media.html:161 msgid "Created" -msgstr "" +msgstr "Utworzono" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:40 @@ -1124,27 +1124,27 @@ msgstr "Wygląda na to, że nic tutaj nie ma!

Jeśli jesteś pewny, że ad #: mediagoblin/tools/timesince.py:62 msgid "year" -msgstr "" +msgstr "rok" #: mediagoblin/tools/timesince.py:63 msgid "month" -msgstr "" +msgstr "miesiąc" #: mediagoblin/tools/timesince.py:64 msgid "week" -msgstr "" +msgstr "tydzień" #: mediagoblin/tools/timesince.py:65 msgid "day" -msgstr "" +msgstr "dzień" #: mediagoblin/tools/timesince.py:66 msgid "hour" -msgstr "" +msgstr "godzina" #: mediagoblin/tools/timesince.py:67 msgid "minute" -msgstr "" +msgstr "minuta" #: mediagoblin/user_pages/forms.py:23 msgid "Comment" @@ -1183,7 +1183,7 @@ msgstr "komentarze do twojego wpisu" #: mediagoblin/user_pages/views.py:169 msgid "Sorry, comments are disabled." -msgstr "" +msgstr "Komentowanie jest wyłączone." #: mediagoblin/user_pages/views.py:174 msgid "Oops, your comment was empty." diff --git a/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.mo index 309855f5..8cfdf339 100644 Binary files a/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.mo and b/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.mo differ diff --git a/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.po index 4a33f751..af2d94d6 100644 --- a/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.po @@ -10,8 +10,8 @@ msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" "POT-Creation-Date: 2013-05-27 13:54-0500\n" -"PO-Revision-Date: 2013-05-27 18:54+0000\n" -"Last-Translator: cwebber \n" +"PO-Revision-Date: 2013-05-27 20:40+0000\n" +"Last-Translator: George Pop \n" "Language-Team: Romanian (http://www.transifex.com/projects/p/mediagoblin/language/ro/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -35,7 +35,7 @@ msgstr "Adresa de e-mail" #: mediagoblin/auth/forms.py:41 msgid "Username or Email" -msgstr "" +msgstr "Numele de utilizator sau adresa de e-mail" #: mediagoblin/auth/forms.py:52 msgid "Username or email" @@ -262,7 +262,7 @@ msgstr "Parolă incorectă" #: mediagoblin/edit/views.py:363 msgid "Your password was changed successfully" -msgstr "" +msgstr "Parola a fost schimbată cu succes" #: mediagoblin/gmg_commands/assetlink.py:60 msgid "Cannot link theme... no theme set\n" @@ -279,17 +279,17 @@ msgstr "A fost însă găsit un symlink către vechiul folder; s-a șters.\n" #: mediagoblin/gmg_commands/assetlink.py:112 #, python-format msgid "Could not link \"%s\": %s exists and is not a symlink\n" -msgstr "" +msgstr "Nu s-a putut crea link pentru \"%s\": %s există deja și nu este symlink\n" #: mediagoblin/gmg_commands/assetlink.py:119 #, python-format msgid "Skipping \"%s\"; already set up.\n" -msgstr "" +msgstr "S-a omis \"%s\"; configurat deja.\n" #: mediagoblin/gmg_commands/assetlink.py:124 #, python-format msgid "Old link found for \"%s\"; removing.\n" -msgstr "" +msgstr "Există deja un link pentru \"%s\"; va fi șters.\n" #: mediagoblin/meddleware/csrf.py:134 msgid "" @@ -305,7 +305,7 @@ msgstr "Scuze, nu recunosc acest tip de fișier :(" #: mediagoblin/media_types/pdf/processing.py:136 msgid "unoconv failing to run, check log file" -msgstr "" +msgstr "unoconv nu poate fi executat; verificați log-ul" #: mediagoblin/media_types/video/processing.py:37 msgid "Video transcoding failed" @@ -616,7 +616,7 @@ msgid "" "Create an account at this site\n" " or\n" " Set up MediaGoblin on your own server" -msgstr "" +msgstr "Creați un cont pe acest site\n sau\n Instalați MediaGoblin pe serverul dvs." #: mediagoblin/templates/mediagoblin/bits/logo.html:23 #: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 @@ -663,11 +663,11 @@ msgstr "Salvează modificările" #: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 #, python-format msgid "Changing %(username)s's password" -msgstr "" +msgstr "Se modifică parola pentru %(username)s" #: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 msgid "Save" -msgstr "" +msgstr "Salvează" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 #, python-format @@ -698,7 +698,7 @@ msgstr "Se modifică setările contului pentru userul %(username)s" #: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 msgid "Change your password." -msgstr "" +msgstr "Modifică parolă." #: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 msgid "Delete my account" @@ -772,7 +772,7 @@ msgstr "Imagine pentru %(media_title)s" #: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 msgid "PDF file" -msgstr "" +msgstr "Fișier PDF" #: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 msgid "Toggle Rotate" @@ -928,15 +928,15 @@ msgstr "Trimite acest comentariu" #: mediagoblin/templates/mediagoblin/user_pages/media.html:164 #, python-format msgid "%(formatted_time)s ago" -msgstr "" +msgstr "în urmă cu %(formatted_time)s" #: mediagoblin/templates/mediagoblin/user_pages/media.html:150 msgid "Added" -msgstr "" +msgstr "Adăugat" #: mediagoblin/templates/mediagoblin/user_pages/media.html:161 msgid "Created" -msgstr "" +msgstr "Creat" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:40 @@ -1124,27 +1124,27 @@ msgstr "Nu există nicio pagină la această adresă.

Dacă sunteți sigur #: mediagoblin/tools/timesince.py:62 msgid "year" -msgstr "" +msgstr "anul" #: mediagoblin/tools/timesince.py:63 msgid "month" -msgstr "" +msgstr "luna" #: mediagoblin/tools/timesince.py:64 msgid "week" -msgstr "" +msgstr "săptămâna" #: mediagoblin/tools/timesince.py:65 msgid "day" -msgstr "" +msgstr "ziua" #: mediagoblin/tools/timesince.py:66 msgid "hour" -msgstr "" +msgstr "ora" #: mediagoblin/tools/timesince.py:67 msgid "minute" -msgstr "" +msgstr "minutul" #: mediagoblin/user_pages/forms.py:23 msgid "Comment" @@ -1183,7 +1183,7 @@ msgstr "a făcut un comentariu la postarea ta" #: mediagoblin/user_pages/views.py:169 msgid "Sorry, comments are disabled." -msgstr "" +msgstr "Comentariile sunt dezactivate." #: mediagoblin/user_pages/views.py:174 msgid "Oops, your comment was empty." diff --git a/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.mo index 89836e48..ed28ff43 100644 Binary files a/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.mo and b/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.mo differ diff --git a/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.po index 12c79b17..d0ff7bdd 100644 --- a/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.po @@ -10,8 +10,8 @@ msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" "POT-Creation-Date: 2013-05-27 13:54-0500\n" -"PO-Revision-Date: 2013-05-27 18:54+0000\n" -"Last-Translator: cwebber \n" +"PO-Revision-Date: 2013-06-01 21:08+0000\n" +"Last-Translator: aleksejrs \n" "Language-Team: Russian (http://www.transifex.com/projects/p/mediagoblin/language/ru/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -35,7 +35,7 @@ msgstr "Адрес электронной почты" #: mediagoblin/auth/forms.py:41 msgid "Username or Email" -msgstr "" +msgstr "Имя пользователя или адрес электронной почты" #: mediagoblin/auth/forms.py:52 msgid "Username or email" @@ -262,7 +262,7 @@ msgstr "Неправильный пароль" #: mediagoblin/edit/views.py:363 msgid "Your password was changed successfully" -msgstr "" +msgstr "Ваш пароль сменён успешно" #: mediagoblin/gmg_commands/assetlink.py:60 msgid "Cannot link theme... no theme set\n" @@ -663,11 +663,11 @@ msgstr "Сохранить изменения" #: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 #, python-format msgid "Changing %(username)s's password" -msgstr "" +msgstr "Смена пароля %(username)s" #: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 msgid "Save" -msgstr "" +msgstr "Сохранить" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 #, python-format @@ -698,7 +698,7 @@ msgstr "Настройка учётной записи %(username)s" #: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 msgid "Change your password." -msgstr "" +msgstr "Сменить пароль" #: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 msgid "Delete my account" @@ -772,7 +772,7 @@ msgstr "Изображение «%(media_title)s»" #: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 msgid "PDF file" -msgstr "" +msgstr "PDF-файл" #: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 msgid "Toggle Rotate" @@ -928,15 +928,15 @@ msgstr "Добавить этот комментарий" #: mediagoblin/templates/mediagoblin/user_pages/media.html:164 #, python-format msgid "%(formatted_time)s ago" -msgstr "" +msgstr "%(formatted_time)s назад" #: mediagoblin/templates/mediagoblin/user_pages/media.html:150 msgid "Added" -msgstr "" +msgstr "Добавлен" #: mediagoblin/templates/mediagoblin/user_pages/media.html:161 msgid "Created" -msgstr "" +msgstr "Создан" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:40 @@ -1144,7 +1144,7 @@ msgstr "" #: mediagoblin/tools/timesince.py:67 msgid "minute" -msgstr "" +msgstr "мин" #: mediagoblin/user_pages/forms.py:23 msgid "Comment" @@ -1183,7 +1183,7 @@ msgstr "оставил комментарий к вашему файлу" #: mediagoblin/user_pages/views.py:169 msgid "Sorry, comments are disabled." -msgstr "" +msgstr "Сожалеем: возможность комментирования отключена." #: mediagoblin/user_pages/views.py:174 msgid "Oops, your comment was empty." diff --git a/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.mo index a262aaee..fd48a37f 100644 Binary files a/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.mo and b/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.mo differ diff --git a/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.po index ecb83098..e4d1bacc 100644 --- a/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.po @@ -14,8 +14,8 @@ msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" "POT-Creation-Date: 2013-05-27 13:54-0500\n" -"PO-Revision-Date: 2013-05-27 18:54+0000\n" -"Last-Translator: cwebber \n" +"PO-Revision-Date: 2013-05-28 07:47+0000\n" +"Last-Translator: martin \n" "Language-Team: Slovak (http://www.transifex.com/projects/p/mediagoblin/language/sk/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -39,7 +39,7 @@ msgstr "Email adresse" #: mediagoblin/auth/forms.py:41 msgid "Username or Email" -msgstr "" +msgstr "Použivateľské meno alebo e-mail" #: mediagoblin/auth/forms.py:52 msgid "Username or email" @@ -266,7 +266,7 @@ msgstr "Nesprávne heslo" #: mediagoblin/edit/views.py:363 msgid "Your password was changed successfully" -msgstr "" +msgstr "Tvoje heslo bolo úspešne zmenené" #: mediagoblin/gmg_commands/assetlink.py:60 msgid "Cannot link theme... no theme set\n" @@ -283,17 +283,17 @@ msgstr "Odstránené; hoci bol pôvodný symbolický odkaz adresára nájdený.\ #: mediagoblin/gmg_commands/assetlink.py:112 #, python-format msgid "Could not link \"%s\": %s exists and is not a symlink\n" -msgstr "" +msgstr "Nemožno odkazovať na \"%s\": %s existuje a nie je symbolickým odkazom\n" #: mediagoblin/gmg_commands/assetlink.py:119 #, python-format msgid "Skipping \"%s\"; already set up.\n" -msgstr "" +msgstr "Preskakujem \"%s\"; opakovane nastavené.\n" #: mediagoblin/gmg_commands/assetlink.py:124 #, python-format msgid "Old link found for \"%s\"; removing.\n" -msgstr "" +msgstr "Nájdený starý odkaz pre \"%s\"; odstraňujem.\n" #: mediagoblin/meddleware/csrf.py:134 msgid "" @@ -309,7 +309,7 @@ msgstr "Prepáč, nepodporujem tento typ súborov =(" #: mediagoblin/media_types/pdf/processing.py:136 msgid "unoconv failing to run, check log file" -msgstr "" +msgstr "beh unoconv zlyhal, preskúmajte log záznam" #: mediagoblin/media_types/video/processing.py:37 msgid "Video transcoding failed" @@ -620,7 +620,7 @@ msgid "" "Create an account at this site\n" " or\n" " Set up MediaGoblin on your own server" -msgstr "" +msgstr "Vytvoriť účet na tejto stránke\n alebo\n Nastaviť MediaGoblin na vlastnom serveri" #: mediagoblin/templates/mediagoblin/bits/logo.html:23 #: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 @@ -667,11 +667,11 @@ msgstr "Uložiť zmeny" #: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 #, python-format msgid "Changing %(username)s's password" -msgstr "" +msgstr "Mením heslo používateľa %(username)s" #: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 msgid "Save" -msgstr "" +msgstr "Uložiť" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 #, python-format @@ -702,7 +702,7 @@ msgstr "Mením nastavenia účtu používateľa %(username)s" #: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 msgid "Change your password." -msgstr "" +msgstr "Zmeniť svoje heslo." #: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 msgid "Delete my account" @@ -776,7 +776,7 @@ msgstr "Obrázok pre %(media_title)s" #: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 msgid "PDF file" -msgstr "" +msgstr "PDF súbor" #: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 msgid "Toggle Rotate" @@ -932,15 +932,15 @@ msgstr "Pridať tento komentár" #: mediagoblin/templates/mediagoblin/user_pages/media.html:164 #, python-format msgid "%(formatted_time)s ago" -msgstr "" +msgstr "pred %(formatted_time)s " #: mediagoblin/templates/mediagoblin/user_pages/media.html:150 msgid "Added" -msgstr "" +msgstr "Pridané" #: mediagoblin/templates/mediagoblin/user_pages/media.html:161 msgid "Created" -msgstr "" +msgstr "Vytvorené" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:40 @@ -1128,27 +1128,27 @@ msgstr "Zdá sa, že na tejto adrese sa nič nenachádza. Prepáč!

Pokia #: mediagoblin/tools/timesince.py:62 msgid "year" -msgstr "" +msgstr "rok" #: mediagoblin/tools/timesince.py:63 msgid "month" -msgstr "" +msgstr "mesiac" #: mediagoblin/tools/timesince.py:64 msgid "week" -msgstr "" +msgstr "týždeň" #: mediagoblin/tools/timesince.py:65 msgid "day" -msgstr "" +msgstr "deň" #: mediagoblin/tools/timesince.py:66 msgid "hour" -msgstr "" +msgstr "hodina" #: mediagoblin/tools/timesince.py:67 msgid "minute" -msgstr "" +msgstr "minúta" #: mediagoblin/user_pages/forms.py:23 msgid "Comment" @@ -1187,7 +1187,7 @@ msgstr "okmentoval tvoj príspevok" #: mediagoblin/user_pages/views.py:169 msgid "Sorry, comments are disabled." -msgstr "" +msgstr "Prepáč, komentovanie je vypnuté." #: mediagoblin/user_pages/views.py:174 msgid "Oops, your comment was empty." diff --git a/mediagoblin/i18n/tr_TR/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/tr_TR/LC_MESSAGES/mediagoblin.mo new file mode 100644 index 00000000..4341870b Binary files /dev/null and b/mediagoblin/i18n/tr_TR/LC_MESSAGES/mediagoblin.mo differ diff --git a/mediagoblin/i18n/tr_TR/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/tr_TR/LC_MESSAGES/mediagoblin.po new file mode 100644 index 00000000..4155520f --- /dev/null +++ b/mediagoblin/i18n/tr_TR/LC_MESSAGES/mediagoblin.po @@ -0,0 +1,1252 @@ +# Translations template for PROJECT. +# Copyright (C) 2013 ORGANIZATION +# This file is distributed under the same license as the PROJECT project. +# +# Translators: +# Caner BAŞARAN , 2013 +msgid "" +msgstr "" +"Project-Id-Version: GNU MediaGoblin\n" +"Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" +"POT-Creation-Date: 2013-05-27 13:54-0500\n" +"PO-Revision-Date: 2013-06-06 15:44+0000\n" +"Last-Translator: Caner BAŞARAN \n" +"Language-Team: Turkish (Turkey) (http://www.transifex.com/projects/p/mediagoblin/language/tr_TR/)\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: tr_TR\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: mediagoblin/auth/forms.py:26 +msgid "Username" +msgstr "Kullanıcı adı" + +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 +#: mediagoblin/tests/test_util.py:110 +msgid "Password" +msgstr "Parola" + +#: mediagoblin/auth/forms.py:34 +msgid "Email address" +msgstr "E-posta adresi" + +#: mediagoblin/auth/forms.py:41 +msgid "Username or Email" +msgstr "Kullanıcı adı veya E-posta" + +#: mediagoblin/auth/forms.py:52 +msgid "Username or email" +msgstr "Kullanıcı adı ya da e-posta" + +#: mediagoblin/auth/tools.py:31 +msgid "Invalid User name or email address." +msgstr "" + +#: mediagoblin/auth/tools.py:32 +msgid "This field does not take email addresses." +msgstr "" + +#: mediagoblin/auth/tools.py:33 +msgid "This field requires an email address." +msgstr "" + +#: mediagoblin/auth/views.py:54 +msgid "Sorry, registration is disabled on this instance." +msgstr "Üzgünüz, bu durumda kayıt devre dışıdır." + +#: mediagoblin/auth/views.py:68 +msgid "Sorry, a user with that name already exists." +msgstr "Maalesef, bu isimde bir kullanıcı mevcut." + +#: mediagoblin/auth/views.py:72 +msgid "Sorry, a user with that email address already exists." +msgstr "Üzgünüz, bu e-posta adresine sahip bir kullanıcı zaten var." + +#: mediagoblin/auth/views.py:182 +msgid "" +"Your email address has been verified. You may now login, edit your profile, " +"and submit images!" +msgstr "E-posta adresiniz doğrulandı. Şimdi giriş yapabilir, profilinizi düzenleyip ve yeni görüntüleri gönderebilirsiniz!" + +#: mediagoblin/auth/views.py:188 +msgid "The verification key or user id is incorrect" +msgstr "Doğrulama anahtarı veya kullanıcı kimliği yanlış" + +#: mediagoblin/auth/views.py:206 +msgid "You must be logged in so we know who to send the email to!" +msgstr "" + +#: mediagoblin/auth/views.py:214 +msgid "You've already verified your email address!" +msgstr "Zaten e-posta adresinizi doğruladınız!" + +#: mediagoblin/auth/views.py:227 +msgid "Resent your verification email." +msgstr "Doğrulama e-postasını tekrar yolla." + +#: mediagoblin/auth/views.py:258 +msgid "" +"If that email address (case sensitive!) is registered an email has been sent" +" with instructions on how to change your password." +msgstr "" + +#: mediagoblin/auth/views.py:269 +msgid "Couldn't find someone with that username." +msgstr "" + +#: mediagoblin/auth/views.py:272 +msgid "" +"An email has been sent with instructions on how to change your password." +msgstr "Parolanızı nasıl değiştireceğinizle ilgili adımları anlatan bir e-posta gönderildi." + +#: mediagoblin/auth/views.py:279 +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:336 +msgid "You can now log in using your new password." +msgstr "Şimdi yeni parolanızı giriş için kullanabilirsiniz." + +#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:82 +#: mediagoblin/submit/forms.py:28 mediagoblin/submit/forms.py:47 +#: mediagoblin/user_pages/forms.py:45 +msgid "Title" +msgstr "Başlık" + +#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:31 +msgid "Description of this work" +msgstr "" + +#: mediagoblin/edit/forms.py:29 mediagoblin/edit/forms.py:52 +#: mediagoblin/edit/forms.py:86 mediagoblin/submit/forms.py:32 +#: mediagoblin/submit/forms.py:51 mediagoblin/user_pages/forms.py:49 +msgid "" +"You can use\n" +" \n" +" Markdown for formatting." +msgstr "" + +#: mediagoblin/edit/forms.py:33 mediagoblin/submit/forms.py:36 +msgid "Tags" +msgstr "Etiketler" + +#: mediagoblin/edit/forms.py:35 mediagoblin/submit/forms.py:38 +msgid "Separate tags by commas." +msgstr "Etikerleri virgül ile ayırın." + +#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:90 +msgid "Slug" +msgstr "" + +#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:91 +msgid "The slug can't be empty" +msgstr "" + +#: mediagoblin/edit/forms.py:40 +msgid "" +"The title part of this media's address. You usually don't need to change " +"this." +msgstr "" + +#: mediagoblin/edit/forms.py:44 mediagoblin/submit/forms.py:41 +#: mediagoblin/templates/mediagoblin/utils/license.html:20 +msgid "License" +msgstr "" + +#: mediagoblin/edit/forms.py:50 +msgid "Bio" +msgstr "" + +#: mediagoblin/edit/forms.py:56 +msgid "Website" +msgstr "Web sitesi" + +#: mediagoblin/edit/forms.py:58 +msgid "This address contains errors" +msgstr "" + +#: mediagoblin/edit/forms.py:63 +msgid "License preference" +msgstr "" + +#: mediagoblin/edit/forms.py:69 +msgid "This will be your default license on upload forms." +msgstr "" + +#: mediagoblin/edit/forms.py:71 +msgid "Email me when others comment on my media" +msgstr "Medyama birisi yorum yazdığında bana e-posta at" + +#: mediagoblin/edit/forms.py:83 +msgid "The title can't be empty" +msgstr "" + +#: mediagoblin/edit/forms.py:85 mediagoblin/submit/forms.py:50 +#: mediagoblin/user_pages/forms.py:48 +msgid "Description of this collection" +msgstr "" + +#: mediagoblin/edit/forms.py:92 +msgid "" +"The title part of this collection's address. You usually don't need to " +"change this." +msgstr "" + +#: mediagoblin/edit/forms.py:99 +msgid "Old password" +msgstr "Eski parola" + +#: mediagoblin/edit/forms.py:101 +msgid "Enter your old password to prove you own this account." +msgstr "" + +#: mediagoblin/edit/forms.py:104 +msgid "New password" +msgstr "Yeni parola" + +#: mediagoblin/edit/views.py:67 +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 "Başka bir kullanıcının medyasını düzenlerken dikkatli davranın." + +#: mediagoblin/edit/views.py:155 +#, python-format +msgid "You added the attachment %s!" +msgstr "" + +#: mediagoblin/edit/views.py:182 +msgid "You can only edit your own profile." +msgstr "" + +#: mediagoblin/edit/views.py:188 +msgid "You are editing a user's profile. Proceed with caution." +msgstr "Başka bir kullanıcının profilini düzenlerken dikkatli davranın." + +#: mediagoblin/edit/views.py:204 +msgid "Profile changes saved" +msgstr "Profil değişiklikleri kaydedildi" + +#: mediagoblin/edit/views.py:240 +msgid "Account settings saved" +msgstr "Hesap ayarları kaydedildi" + +#: mediagoblin/edit/views.py:274 +msgid "You need to confirm the deletion of your account." +msgstr "" + +#: mediagoblin/edit/views.py:310 mediagoblin/submit/views.py:138 +#: mediagoblin/user_pages/views.py:222 +#, python-format +msgid "You already have a collection called \"%s\"!" +msgstr "" + +#: mediagoblin/edit/views.py:314 +msgid "A collection with that slug already exists for this user." +msgstr "" + +#: mediagoblin/edit/views.py:329 +msgid "You are editing another user's collection. Proceed with caution." +msgstr "" + +#: mediagoblin/edit/views.py:348 +msgid "Wrong password" +msgstr "Yanlış parola" + +#: mediagoblin/edit/views.py:363 +msgid "Your password was changed successfully" +msgstr "Parolanız başarılı bir şekilde değiştirildi" + +#: mediagoblin/gmg_commands/assetlink.py:60 +msgid "Cannot link theme... no theme set\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:73 +msgid "No asset directory for this theme\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:76 +msgid "However, old link directory symlink found; removed.\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:112 +#, python-format +msgid "Could not link \"%s\": %s exists and is not a symlink\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:119 +#, python-format +msgid "Skipping \"%s\"; already set up.\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:124 +#, python-format +msgid "Old link found for \"%s\"; removing.\n" +msgstr "" + +#: mediagoblin/meddleware/csrf.py:134 +msgid "" +"CSRF cookie not present. This is most likely the result of a cookie blocker " +"or somesuch.
Make sure to permit the settings of cookies for this " +"domain." +msgstr "" + +#: mediagoblin/media_types/__init__.py:111 +#: mediagoblin/media_types/__init__.py:155 +msgid "Sorry, I don't support that file type :(" +msgstr "Üzgünüz, bu tip dosyaları desteklemiyoruz :(" + +#: mediagoblin/media_types/pdf/processing.py:136 +msgid "unoconv failing to run, check log file" +msgstr "" + +#: mediagoblin/media_types/video/processing.py:37 +msgid "Video transcoding failed" +msgstr "" + +#: mediagoblin/plugins/geolocation/templates/mediagoblin/plugins/geolocation/map.html:24 +msgid "Location" +msgstr "" + +#: mediagoblin/plugins/geolocation/templates/mediagoblin/plugins/geolocation/map.html:52 +#, python-format +msgid "View on OpenStreetMap" +msgstr "" + +#: mediagoblin/plugins/oauth/forms.py:29 +msgid "Allow" +msgstr "" + +#: mediagoblin/plugins/oauth/forms.py:30 +msgid "Deny" +msgstr "" + +#: mediagoblin/plugins/oauth/forms.py:34 +msgid "Name" +msgstr "" + +#: mediagoblin/plugins/oauth/forms.py:35 +msgid "The name of the OAuth client" +msgstr "" + +#: mediagoblin/plugins/oauth/forms.py:36 +msgid "Description" +msgstr "" + +#: mediagoblin/plugins/oauth/forms.py:38 +msgid "" +"This will be visible to users allowing your\n" +" application to authenticate as them." +msgstr "" + +#: mediagoblin/plugins/oauth/forms.py:40 +msgid "Type" +msgstr "Tür" + +#: mediagoblin/plugins/oauth/forms.py:45 +msgid "" +"Confidential - The client can\n" +" make requests to the GNU MediaGoblin instance that can not be\n" +" intercepted by the user agent (e.g. server-side client).
\n" +" Public - The client can't make confidential\n" +" requests to the GNU MediaGoblin instance (e.g. client-side\n" +" JavaScript client)." +msgstr "" + +#: mediagoblin/plugins/oauth/forms.py:52 +msgid "Redirect URI" +msgstr "" + +#: mediagoblin/plugins/oauth/forms.py:54 +msgid "" +"The redirect URI for the applications, this field\n" +" is required for public clients." +msgstr "" + +#: mediagoblin/plugins/oauth/forms.py:66 +msgid "This field is required for public clients" +msgstr "" + +#: mediagoblin/plugins/oauth/views.py:56 +msgid "The client {0} has been registered!" +msgstr "" + +#: mediagoblin/plugins/oauth/templates/oauth/client/connections.html:22 +msgid "OAuth client connections" +msgstr "" + +#: mediagoblin/plugins/oauth/templates/oauth/client/list.html:22 +msgid "Your OAuth clients" +msgstr "" + +#: mediagoblin/plugins/oauth/templates/oauth/client/register.html:29 +#: mediagoblin/templates/mediagoblin/submit/collection.html:30 +#: mediagoblin/templates/mediagoblin/submit/start.html:34 +#: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:68 +msgid "Add" +msgstr "Ekle" + +#: mediagoblin/processing/__init__.py:193 +msgid "Invalid file given for media type." +msgstr "Bu medya türü için geçersiz dosya türü." + +#: mediagoblin/submit/forms.py:26 +msgid "File" +msgstr "Dosya" + +#: mediagoblin/submit/views.py:49 +msgid "You must provide a file." +msgstr "Bir dosya sağlamanız gerekir." + +#: mediagoblin/submit/views.py:93 +msgid "Woohoo! Submitted!" +msgstr "Hoooop! Gönderildi!" + +#: mediagoblin/submit/views.py:144 +#, python-format +msgid "Collection \"%s\" added!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:67 +msgid "Verify your email!" +msgstr "E-postanızı doğrulayın!" + +#: mediagoblin/templates/mediagoblin/base.html:68 +msgid "log out" +msgstr "çıkış" + +#: mediagoblin/templates/mediagoblin/base.html:73 +#: mediagoblin/templates/mediagoblin/auth/login.html:28 +#: mediagoblin/templates/mediagoblin/auth/login.html:36 +#: mediagoblin/templates/mediagoblin/auth/login.html:54 +msgid "Log in" +msgstr "Giriş" + +#: mediagoblin/templates/mediagoblin/base.html:82 +#, python-format +msgid "%(user_name)s's account" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:89 +msgid "Change account settings" +msgstr "Hesap ayarlarını değiştir" + +#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:108 +#: mediagoblin/templates/mediagoblin/admin/panel.html:21 +#: mediagoblin/templates/mediagoblin/admin/panel.html:26 +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:21 +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:26 +msgid "Media processing panel" +msgstr "Madya işlem paneli" + +#: mediagoblin/templates/mediagoblin/base.html:96 +msgid "Log out" +msgstr "Çıkış" + +#: mediagoblin/templates/mediagoblin/base.html:99 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:156 +msgid "Add media" +msgstr "Medya ekle" + +#: mediagoblin/templates/mediagoblin/base.html:102 +#: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:41 +msgid "Create new collection" +msgstr "" + +#: mediagoblin/templates/mediagoblin/error.html:24 +msgid "Image of goblin stressing out" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:32 +msgid "Most recent media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/admin/panel.html:29 +msgid "" +"Here you can track the state of media being processed on this instance." +msgstr "" + +#: mediagoblin/templates/mediagoblin/admin/panel.html:32 +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:32 +msgid "Media in-processing" +msgstr "" + +#: mediagoblin/templates/mediagoblin/admin/panel.html:58 +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:56 +msgid "No media in-processing" +msgstr "" + +#: mediagoblin/templates/mediagoblin/admin/panel.html:61 +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:59 +msgid "These uploads failed to process:" +msgstr "" + +#: mediagoblin/templates/mediagoblin/admin/panel.html:90 +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:86 +msgid "No failed entries!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/admin/panel.html:92 +msgid "Last 10 successful uploads" +msgstr "" + +#: mediagoblin/templates/mediagoblin/admin/panel.html:112 +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:107 +msgid "No processed entries, yet!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:28 +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:36 +msgid "Set your new password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:39 +msgid "Set password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:23 +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:31 +msgid "Recover password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:34 +msgid "Send instructions" +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:39 +msgid "Logging in failed!" +msgstr "Giriş başarısız!" + +#: mediagoblin/templates/mediagoblin/auth/login.html:44 +msgid "Don't have an account yet?" +msgstr "Hala hesabınız yok mu?" + +#: mediagoblin/templates/mediagoblin/auth/login.html:45 +msgid "Create one here!" +msgstr "Şimdi oluşturun!" + +#: mediagoblin/templates/mediagoblin/auth/login.html:51 +msgid "Forgot your password?" +msgstr "Parolanı mı unuttun?" + +#: mediagoblin/templates/mediagoblin/auth/register.html:28 +#: mediagoblin/templates/mediagoblin/auth/register.html:36 +msgid "Create an account!" +msgstr "Hesap oluştur!" + +#: mediagoblin/templates/mediagoblin/auth/register.html:40 +msgid "Create" +msgstr "Oluştur" + +#: 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 "Merhaba %(username)s,\n\nGNU MediaGoblin hesabınızı etkinleştirmek için, lütfen aşağıdaki\nURL(bağlantı)'yı Web tarayıcınızda açın:\n\n%(verification_url)s" + +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:21 +#, python-format +msgid "" +"Powered by MediaGoblin, a GNU project." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:24 +#, python-format +msgid "" +"Released under the AGPL. Source code available." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:20 +msgid "Explore" +msgstr "Keşfet" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:22 +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:24 +msgid "" +"This site is running MediaGoblin, an " +"extraordinarily great piece of media hosting software." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:25 +msgid "" +"To add your own media, place comments, and more, you can log in with your " +"MediaGoblin account." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:27 +msgid "Don't have one yet? It's easy!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:28 +#, python-format +msgid "" +"Create an account at this site\n" +" or\n" +" Set up MediaGoblin on your own server" +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/logo.html:23 +#: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 +msgid "MediaGoblin logo" +msgstr "MediaGoblin logo" + +#: mediagoblin/templates/mediagoblin/edit/attachments.html:23 +#: mediagoblin/templates/mediagoblin/edit/attachments.html:35 +#, python-format +msgid "Editing attachments for %(media_title)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/attachments.html:44 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:182 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:198 +msgid "Attachments" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/attachments.html:57 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:204 +msgid "Add attachment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/attachments.html:61 +#: mediagoblin/templates/mediagoblin/edit/delete_account.html:42 +#: mediagoblin/templates/mediagoblin/edit/edit.html:41 +#: mediagoblin/templates/mediagoblin/edit/edit_collection.html:32 +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:46 +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:52 +#: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:67 +#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:48 +msgid "Cancel" +msgstr "İptal" + +#: mediagoblin/templates/mediagoblin/edit/attachments.html:63 +#: mediagoblin/templates/mediagoblin/edit/edit.html:42 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:55 +#: mediagoblin/templates/mediagoblin/edit/edit_collection.html:33 +#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:40 +msgid "Save changes" +msgstr "Değişiklikleri kaydet" + +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:28 +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 +#, python-format +msgid "Changing %(username)s's password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 +msgid "Save" +msgstr "Kaydet" + +#: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 +#, python-format +msgid "Really delete user '%(user_name)s' and all related media/comments?" +msgstr "Gerçekten '%(user_name)s' kullanıcısını ve ilgili tüm medya/yorumları silmek istiyor musun?" + +#: mediagoblin/templates/mediagoblin/edit/delete_account.html:35 +msgid "Yes, really delete my account" +msgstr "Evet, gerçekten hesabımı silmek istiyorum" + +#: mediagoblin/templates/mediagoblin/edit/delete_account.html:44 +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:48 +#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49 +msgid "Delete permanently" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:23 +#: mediagoblin/templates/mediagoblin/edit/edit.html:35 +#, python-format +msgid "Editing %(media_title)s" +msgstr "%(media_title)s düzenleme" + +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:28 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:40 +#, python-format +msgid "Changing %(username)s's account settings" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 +msgid "Change your password." +msgstr "Parolanızı değiştirin." + +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 +msgid "Delete my account" +msgstr "Hesabımı sil" + +#: mediagoblin/templates/mediagoblin/edit/edit_collection.html:29 +#, python-format +msgid "Editing %(collection_title)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:23 +#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:34 +#, python-format +msgid "Editing %(username)s's profile" +msgstr "%(username)s profilini düzenleme" + +#: mediagoblin/templates/mediagoblin/listings/collection.html:30 +#: mediagoblin/templates/mediagoblin/listings/collection.html:35 +#: 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/ascii.html:34 +#: mediagoblin/templates/mediagoblin/media_displays/audio.html:56 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:65 +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:136 +#: mediagoblin/templates/mediagoblin/media_displays/video.html:55 +msgid "Download" +msgstr "İndir" + +#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:38 +msgid "Original" +msgstr "Özgün" + +#: mediagoblin/templates/mediagoblin/media_displays/audio.html:44 +msgid "" +"Sorry, this audio will not work because \n" +"\tyour web browser does not support HTML5 \n" +"\taudio." +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/audio.html:47 +msgid "" +"You can get a modern web browser that \n" +"\tcan play the audio at \n" +"\t http://getfirefox.com!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/audio.html:60 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:71 +#: mediagoblin/templates/mediagoblin/media_displays/video.html:61 +msgid "Original file" +msgstr "Özgün dosya" + +#: mediagoblin/templates/mediagoblin/media_displays/audio.html:63 +msgid "WebM file (Vorbis codec)" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:59 +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:87 +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:93 +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:99 +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:105 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:59 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:65 +#, python-format +msgid "Image for %(media_title)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 +msgid "PDF file" +msgstr "PDF dosya" + +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 +msgid "Toggle Rotate" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:113 +msgid "Perspective" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:116 +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:117 +msgid "Front" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:120 +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:121 +msgid "Top" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:124 +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:125 +msgid "Side" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:130 +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:131 +msgid "WebGL" +msgstr "WebGL" + +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:138 +msgid "Download model" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:146 +msgid "File Format" +msgstr "Dosya Biçimi" + +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:148 +msgid "Object Height" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:44 +msgid "" +"Sorry, this video will not work because\n" +" your web browser does not support HTML5 \n" +" video." +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:47 +msgid "" +"You can get a modern web browser that \n" +" can play this video at \n" +" http://getfirefox.com!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:69 +msgid "WebM file (640p; VP8/Vorbis)" +msgstr "" + +#: mediagoblin/templates/mediagoblin/submit/collection.html:26 +msgid "Add a collection" +msgstr "" + +#: mediagoblin/templates/mediagoblin/submit/start.html:23 +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Add your media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/collection.html:30 +#, python-format +msgid "%(collection_title)s (%(username)s's collection)" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/collection.html:39 +#, python-format +msgid "%(collection_title)s by %(username)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/collection.html:52 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:79 +msgid "Edit" +msgstr "Düzenle" + +#: mediagoblin/templates/mediagoblin/user_pages/collection.html:56 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:83 +msgid "Delete" +msgstr "Si" + +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:30 +#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 +#, python-format +msgid "Really delete %(title)s?" +msgstr "Gerçekten %(title)s silmek istiyor musun?" + +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:31 +#, python-format +msgid "Really remove %(media_title)s from %(collection_title)s?" +msgstr "Gerçekten %(collection_title)s %(media_title)s kaldırmak istiyor musun?" + +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:54 +msgid "Remove" +msgstr "Kaldır" + +#: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:21 +#, python-format +msgid "%(username)s's collections" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:28 +#, python-format +msgid "%(username)s's collections" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/comment_email.txt:19 +#, python-format +msgid "" +"Hi %(username)s,\n" +"%(comment_author)s commented on your post (%(comment_url)s) at %(instance_name)s\n" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 +#, python-format +msgid "%(username)s's media" +msgstr "%(username)s medyası" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:38 +#, python-format +msgid "" +"%(username)s's media with tag %(tag)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:48 +#, python-format +msgid "%(username)s's media" +msgstr "%(username)s medyası" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:38 +#, python-format +msgid "❖ Browsing media by %(username)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:95 +msgid "Add a comment" +msgstr "Bir yorum ekle" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 +msgid "Add this comment" +msgstr "Bu yorumu ekle" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:132 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:152 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:164 +#, python-format +msgid "%(formatted_time)s ago" +msgstr "%(formatted_time)s önce" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:150 +msgid "Added" +msgstr "Eklendi" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:161 +msgid "Created" +msgstr "Oluşturuldu" + +#: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 +#: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:40 +#, python-format +msgid "Add “%(media_title)s” to a collection" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:54 +msgid "+" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:58 +msgid "Add a new collection" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:29 +msgid "" +"You can track the state of media being processed for your gallery here." +msgstr "Burada galerinizdeki işlenmekte olan medyanın durumunu takip edebilirsiniz." + +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:89 +msgid "Your last 10 successful uploads" +msgstr "" + +#: 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 profili" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:43 +msgid "Sorry, no such user found." +msgstr "Üzgünüz, böyle bir kullanıcı bulunamadı." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:50 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:70 +msgid "Email verification needed" +msgstr "E-posta doğrulaması gerekli" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:53 +msgid "Almost done! Your account still needs to be activated." +msgstr "Neredeyse bitti! Hesabınızı etkinleştirmeniz gerekiyor." + +#: 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 "Bunun nasıl yapılacağı ile ilgili talimatlar, birkaç dakika içinde size e-posta ulaşacak." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 +msgid "In case it doesn't:" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:65 +msgid "Resend verification email" +msgstr "Doğrulama e-postası tekrar yolla" + +#: 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:79 +#, python-format +msgid "" +"If you are that person but you've lost your verification email, you can log in and resend it." +msgstr "Doğrulama e-postasını kaybettiyseniz, giriş yapabilir ve yeniden yollayabilirsiniz." + +#: 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:100 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:117 +msgid "Edit profile" +msgstr "Profil düzenle" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:105 +msgid "This user hasn't filled in their profile (yet)." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:124 +msgid "Browse collections" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:137 +#, python-format +msgid "View all of %(username)s's media" +msgstr "%(username)s tüm medyasını göster" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:150 +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:162 +#: mediagoblin/templates/mediagoblin/utils/collection_gallery.html:84 +#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:70 +msgid "There doesn't seem to be any media here yet..." +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/collection_gallery.html:49 +msgid "(remove)" +msgstr "(kaldır)" + +#: mediagoblin/templates/mediagoblin/utils/collections.html:21 +msgid "Collected in" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/collections.html:40 +msgid "Add to a collection" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/feed_link.html:21 +#: mediagoblin/themes/airy/templates/mediagoblin/utils/feed_link.html:21 +msgid "feed icon" +msgstr "besleme simgesi" + +#: mediagoblin/templates/mediagoblin/utils/feed_link.html:23 +#: mediagoblin/themes/airy/templates/mediagoblin/utils/feed_link.html:23 +msgid "Atom feed" +msgstr "Atom besleme" + +#: mediagoblin/templates/mediagoblin/utils/license.html:25 +msgid "All rights reserved" +msgstr "Tüm hakları saklıdır" + +#: mediagoblin/templates/mediagoblin/utils/pagination.html:39 +msgid "← Newer" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/pagination.html:45 +msgid "Older →" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/pagination.html:48 +msgid "Go to page:" +msgstr "Sayfaya git:" + +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:28 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:33 +msgid "newer" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:39 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:44 +msgid "older" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/tags.html:20 +msgid "Tagged with" +msgstr "" + +#: mediagoblin/tools/exif.py:83 +msgid "Could not read the image file." +msgstr "" + +#: mediagoblin/tools/response.py:35 +msgid "Oops!" +msgstr "Amaninnn boo!" + +#: mediagoblin/tools/response.py:36 +msgid "An error occured" +msgstr "" + +#: mediagoblin/tools/response.py:51 +msgid "Operation not allowed" +msgstr "" + +#: mediagoblin/tools/response.py:52 +msgid "" +"Sorry Dave, I can't let you do that!

You have tried to perform a " +"function that you are not allowed to. Have you been trying to delete all " +"user accounts again?" +msgstr "" + +#: mediagoblin/tools/response.py:60 +msgid "" +"There doesn't seem to be a page at this address. Sorry!

If you're sure" +" the address is correct, maybe the page you're looking for has been moved or" +" deleted." +msgstr "" + +#: mediagoblin/tools/timesince.py:62 +msgid "year" +msgstr "yıl" + +#: mediagoblin/tools/timesince.py:63 +msgid "month" +msgstr "ay" + +#: mediagoblin/tools/timesince.py:64 +msgid "week" +msgstr "hafta" + +#: mediagoblin/tools/timesince.py:65 +msgid "day" +msgstr "gün" + +#: mediagoblin/tools/timesince.py:66 +msgid "hour" +msgstr "saat" + +#: mediagoblin/tools/timesince.py:67 +msgid "minute" +msgstr "dakika" + +#: mediagoblin/user_pages/forms.py:23 +msgid "Comment" +msgstr "" + +#: mediagoblin/user_pages/forms.py:25 +msgid "" +"You can use Markdown for" +" formatting." +msgstr "" + +#: mediagoblin/user_pages/forms.py:31 +msgid "I am sure I want to delete this" +msgstr "Bunu silmek için eminim" + +#: mediagoblin/user_pages/forms.py:35 +msgid "I am sure I want to remove this item from the collection" +msgstr "" + +#: mediagoblin/user_pages/forms.py:39 +msgid "Collection" +msgstr "" + +#: mediagoblin/user_pages/forms.py:40 +msgid "-- Select --" +msgstr "" + +#: mediagoblin/user_pages/forms.py:42 +msgid "Include a note" +msgstr "" + +#: mediagoblin/user_pages/lib.py:58 +msgid "commented on your post" +msgstr "" + +#: mediagoblin/user_pages/views.py:169 +msgid "Sorry, comments are disabled." +msgstr "Maalesef, yorum devre dışı." + +#: mediagoblin/user_pages/views.py:174 +msgid "Oops, your comment was empty." +msgstr "Amaninnn boo, yorumunuz boştu." + +#: mediagoblin/user_pages/views.py:180 +msgid "Your comment has been posted!" +msgstr "Yorumunuz gönderildi!" + +#: mediagoblin/user_pages/views.py:205 +msgid "Please check your entries and try again." +msgstr "" + +#: mediagoblin/user_pages/views.py:245 +msgid "You have to select or add a collection" +msgstr "" + +#: mediagoblin/user_pages/views.py:256 +#, python-format +msgid "\"%s\" already in collection \"%s\"" +msgstr "" + +#: mediagoblin/user_pages/views.py:262 +#, python-format +msgid "\"%s\" added to collection \"%s\"" +msgstr "" + +#: mediagoblin/user_pages/views.py:282 +msgid "You deleted the media." +msgstr "Medyayı sildiniz." + +#: mediagoblin/user_pages/views.py:289 +msgid "The media was not deleted because you didn't check that you were sure." +msgstr "Medya silinmedi çünkü emin olduğunuzu onaylamadınız." + +#: mediagoblin/user_pages/views.py:296 +msgid "You are about to delete another user's media. Proceed with caution." +msgstr "Başka bir kullanıcının medyasını silerken dikkatli davranın." + +#: mediagoblin/user_pages/views.py:370 +msgid "You deleted the item from the collection." +msgstr "" + +#: mediagoblin/user_pages/views.py:374 +msgid "The item was not removed because you didn't check that you were sure." +msgstr "" + +#: mediagoblin/user_pages/views.py:382 +msgid "" +"You are about to delete an item from another user's collection. Proceed with" +" caution." +msgstr "" + +#: mediagoblin/user_pages/views.py:415 +#, python-format +msgid "You deleted the collection \"%s\"" +msgstr "" + +#: mediagoblin/user_pages/views.py:422 +msgid "" +"The collection was not deleted because you didn't check that you were sure." +msgstr "" + +#: mediagoblin/user_pages/views.py:430 +msgid "" +"You are about to delete another user's collection. Proceed with caution." +msgstr "" diff --git a/mediagoblin/i18n/zh_CN/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/zh_CN/LC_MESSAGES/mediagoblin.mo new file mode 100644 index 00000000..1ed5a4f1 Binary files /dev/null and b/mediagoblin/i18n/zh_CN/LC_MESSAGES/mediagoblin.mo differ diff --git a/mediagoblin/i18n/zh_CN/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/zh_CN/LC_MESSAGES/mediagoblin.po new file mode 100644 index 00000000..4bb714fe --- /dev/null +++ b/mediagoblin/i18n/zh_CN/LC_MESSAGES/mediagoblin.po @@ -0,0 +1,1256 @@ +# Translations template for PROJECT. +# Copyright (C) 2013 ORGANIZATION +# This file is distributed under the same license as the PROJECT project. +# +# Translators: +# , 2011 +# cwebber , 2013 +# m13253 , 2013 +# medicalwei , 2012 +# m13253 , 2013 +msgid "" +msgstr "" +"Project-Id-Version: GNU MediaGoblin\n" +"Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" +"POT-Creation-Date: 2013-05-27 13:54-0500\n" +"PO-Revision-Date: 2013-06-16 11:06+0000\n" +"Last-Translator: m13253 \n" +"Language-Team: Chinese (China) (http://www.transifex.com/projects/p/mediagoblin/language/zh_CN/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 0.9.6\n" +"Language: zh_CN\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: mediagoblin/auth/forms.py:26 +msgid "Username" +msgstr "用户名" + +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 +#: mediagoblin/tests/test_util.py:110 +msgid "Password" +msgstr "密码" + +#: mediagoblin/auth/forms.py:34 +msgid "Email address" +msgstr "电子邮件地址" + +#: mediagoblin/auth/forms.py:41 +msgid "Username or Email" +msgstr "用户名或电子邮件" + +#: mediagoblin/auth/forms.py:52 +msgid "Username or email" +msgstr "用户名或电子邮件" + +#: mediagoblin/auth/tools.py:31 +msgid "Invalid User name or email address." +msgstr "无效用户名或电子邮件地址。" + +#: mediagoblin/auth/tools.py:32 +msgid "This field does not take email addresses." +msgstr "此字段不能填写电子邮件地址。" + +#: mediagoblin/auth/tools.py:33 +msgid "This field requires an email address." +msgstr "此字段需填写电子邮件地址。" + +#: mediagoblin/auth/views.py:54 +msgid "Sorry, registration is disabled on this instance." +msgstr "抱歉,本站已暂停注册。" + +#: mediagoblin/auth/views.py:68 +msgid "Sorry, a user with that name already exists." +msgstr "抱歉,该用户名已存在。" + +#: mediagoblin/auth/views.py:72 +msgid "Sorry, a user with that email address already exists." +msgstr "抱歉,已有用户用该电子邮件注册。" + +#: mediagoblin/auth/views.py:182 +msgid "" +"Your email address has been verified. You may now login, edit your profile, " +"and submit images!" +msgstr "您的电子邮件地址已认证。您现在可以登录、修改个人资料并上传图片了!" + +#: mediagoblin/auth/views.py:188 +msgid "The verification key or user id is incorrect" +msgstr "验证码错误或用户 ID 错误" + +#: mediagoblin/auth/views.py:206 +msgid "You must be logged in so we know who to send the email to!" +msgstr "您必须登录以便让我们知道将电子邮件发给谁" + +#: mediagoblin/auth/views.py:214 +msgid "You've already verified your email address!" +msgstr "您已经认证过电子邮件地址了!" + +#: mediagoblin/auth/views.py:227 +msgid "Resent your verification email." +msgstr "重发认证邮件。" + +#: mediagoblin/auth/views.py:258 +msgid "" +"If that email address (case sensitive!) is registered an email has been sent" +" with instructions on how to change your password." +msgstr "若该邮件地址(区分大小写)已被注册,则密码修改说明已通过电子邮件送达。" + +#: mediagoblin/auth/views.py:269 +msgid "Couldn't find someone with that username." +msgstr "找不到有该用户名的人。" + +#: mediagoblin/auth/views.py:272 +msgid "" +"An email has been sent with instructions on how to change your password." +msgstr "密码修改说明已通过电子邮件送达。" + +#: mediagoblin/auth/views.py:279 +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:336 +msgid "You can now log in using your new password." +msgstr "您现在可以用新的密码来登录了!" + +#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:82 +#: mediagoblin/submit/forms.py:28 mediagoblin/submit/forms.py:47 +#: mediagoblin/user_pages/forms.py:45 +msgid "Title" +msgstr "标题" + +#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:31 +msgid "Description of this work" +msgstr "该作品的描述" + +#: mediagoblin/edit/forms.py:29 mediagoblin/edit/forms.py:52 +#: mediagoblin/edit/forms.py:86 mediagoblin/submit/forms.py:32 +#: mediagoblin/submit/forms.py:51 mediagoblin/user_pages/forms.py:49 +msgid "" +"You can use\n" +" \n" +" Markdown for formatting." +msgstr "您可以用 Markdown 来排版。" + +#: mediagoblin/edit/forms.py:33 mediagoblin/submit/forms.py:36 +msgid "Tags" +msgstr "标签" + +#: mediagoblin/edit/forms.py:35 mediagoblin/submit/forms.py:38 +msgid "Separate tags by commas." +msgstr "用逗号分隔标签。" + +#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:90 +msgid "Slug" +msgstr "简称" + +#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:91 +msgid "The slug can't be empty" +msgstr "简称不能为空" + +#: mediagoblin/edit/forms.py:40 +msgid "" +"The title part of this media's address. You usually don't need to change " +"this." +msgstr "该媒体网址的标题部份。通常不需要修改。" + +#: mediagoblin/edit/forms.py:44 mediagoblin/submit/forms.py:41 +#: mediagoblin/templates/mediagoblin/utils/license.html:20 +msgid "License" +msgstr "许可证" + +#: mediagoblin/edit/forms.py:50 +msgid "Bio" +msgstr "个性签名" + +#: mediagoblin/edit/forms.py:56 +msgid "Website" +msgstr "网站" + +#: mediagoblin/edit/forms.py:58 +msgid "This address contains errors" +msgstr "本网址出错了" + +#: mediagoblin/edit/forms.py:63 +msgid "License preference" +msgstr "许可证偏好" + +#: mediagoblin/edit/forms.py:69 +msgid "This will be your default license on upload forms." +msgstr "这将是您上传界面的默认许可证。" + +#: mediagoblin/edit/forms.py:71 +msgid "Email me when others comment on my media" +msgstr "当有人对我的媒体评论时给我电子邮件" + +#: mediagoblin/edit/forms.py:83 +msgid "The title can't be empty" +msgstr "标题不能是空的" + +#: mediagoblin/edit/forms.py:85 mediagoblin/submit/forms.py:50 +#: mediagoblin/user_pages/forms.py:48 +msgid "Description of this collection" +msgstr "这个合集的描述" + +#: mediagoblin/edit/forms.py:92 +msgid "" +"The title part of this collection's address. You usually don't need to " +"change this." +msgstr "此合集网址的标题部份,通常不需要修改。" + +#: mediagoblin/edit/forms.py:99 +msgid "Old password" +msgstr "旧的密码" + +#: mediagoblin/edit/forms.py:101 +msgid "Enter your old password to prove you own this account." +msgstr "输入您的旧密码来证明您拥有这个账户。" + +#: mediagoblin/edit/forms.py:104 +msgid "New password" +msgstr "新密码" + +#: mediagoblin/edit/views.py:67 +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 +#, python-format +msgid "You added the attachment %s!" +msgstr "您加上了附件“%s”!" + +#: mediagoblin/edit/views.py:182 +msgid "You can only edit your own profile." +msgstr "您只能修改自己的个人资料" + +#: mediagoblin/edit/views.py:188 +msgid "You are editing a user's profile. Proceed with caution." +msgstr "您正在修改别人的个人资料,请小心操作。" + +#: mediagoblin/edit/views.py:204 +msgid "Profile changes saved" +msgstr "个人资料已修改" + +#: mediagoblin/edit/views.py:240 +msgid "Account settings saved" +msgstr "账户设置已保存" + +#: mediagoblin/edit/views.py:274 +msgid "You need to confirm the deletion of your account." +msgstr "您需要确认删除您的账户。" + +#: mediagoblin/edit/views.py:310 mediagoblin/submit/views.py:138 +#: mediagoblin/user_pages/views.py:222 +#, python-format +msgid "You already have a collection called \"%s\"!" +msgstr "您已经有一个称做“%s”的合集了!" + +#: mediagoblin/edit/views.py:314 +msgid "A collection with that slug already exists for this user." +msgstr "该用户已经有使用该简称的合集了。" + +#: mediagoblin/edit/views.py:329 +msgid "You are editing another user's collection. Proceed with caution." +msgstr "您正在修改别人的合集,请小心操作。" + +#: mediagoblin/edit/views.py:348 +msgid "Wrong password" +msgstr "密码错误" + +#: mediagoblin/edit/views.py:363 +msgid "Your password was changed successfully" +msgstr "您的密码已成功修改" + +#: mediagoblin/gmg_commands/assetlink.py:60 +msgid "Cannot link theme... no theme set\n" +msgstr "无法链接到主题……未设置主题\n" + +#: mediagoblin/gmg_commands/assetlink.py:73 +msgid "No asset directory for this theme\n" +msgstr "此主题没有素材目录\n" + +#: mediagoblin/gmg_commands/assetlink.py:76 +msgid "However, old link directory symlink found; removed.\n" +msgstr "但是旧的目录链接已经找到并移除。\n" + +#: mediagoblin/gmg_commands/assetlink.py:112 +#, python-format +msgid "Could not link \"%s\": %s exists and is not a symlink\n" +msgstr "无法链接到“%s”:“%s”已存在且不是链接\n" + +#: mediagoblin/gmg_commands/assetlink.py:119 +#, python-format +msgid "Skipping \"%s\"; already set up.\n" +msgstr "跳过“%s”;已设置过了。\n" + +#: mediagoblin/gmg_commands/assetlink.py:124 +#, python-format +msgid "Old link found for \"%s\"; removing.\n" +msgstr "“%s”的旧链接已经找到并移除。\n" + +#: mediagoblin/meddleware/csrf.py:134 +msgid "" +"CSRF cookie not present. This is most likely the result of a cookie blocker " +"or somesuch.
Make sure to permit the settings of cookies for this " +"domain." +msgstr "CSRF cookie 不存在。很可能是由类似 cookie 屏蔽器造成的。
请允许本域名的 cookie 设定。" + +#: mediagoblin/media_types/__init__.py:111 +#: mediagoblin/media_types/__init__.py:155 +msgid "Sorry, I don't support that file type :(" +msgstr "抱歉,我不支持这样的文件格式 :(" + +#: mediagoblin/media_types/pdf/processing.py:136 +msgid "unoconv failing to run, check log file" +msgstr "无法运行 unoconv,请检查日志" + +#: mediagoblin/media_types/video/processing.py:37 +msgid "Video transcoding failed" +msgstr "视频转码失败" + +#: mediagoblin/plugins/geolocation/templates/mediagoblin/plugins/geolocation/map.html:24 +msgid "Location" +msgstr "位置" + +#: mediagoblin/plugins/geolocation/templates/mediagoblin/plugins/geolocation/map.html:52 +#, python-format +msgid "View on OpenStreetMap" +msgstr "在 OpenStreetMap 上观看" + +#: mediagoblin/plugins/oauth/forms.py:29 +msgid "Allow" +msgstr "允许" + +#: mediagoblin/plugins/oauth/forms.py:30 +msgid "Deny" +msgstr "拒绝" + +#: mediagoblin/plugins/oauth/forms.py:34 +msgid "Name" +msgstr "名称" + +#: mediagoblin/plugins/oauth/forms.py:35 +msgid "The name of the OAuth client" +msgstr "OAuth client 的名称" + +#: mediagoblin/plugins/oauth/forms.py:36 +msgid "Description" +msgstr "描述" + +#: mediagoblin/plugins/oauth/forms.py:38 +msgid "" +"This will be visible to users allowing your\n" +" application to authenticate as them." +msgstr "本描述将会被进行应用程序认证的用户看到。" + +#: mediagoblin/plugins/oauth/forms.py:40 +msgid "Type" +msgstr "类型" + +#: mediagoblin/plugins/oauth/forms.py:45 +msgid "" +"Confidential - The client can\n" +" make requests to the GNU MediaGoblin instance that can not be\n" +" intercepted by the user agent (e.g. server-side client).
\n" +" Public - The client can't make confidential\n" +" requests to the GNU MediaGoblin instance (e.g. client-side\n" +" JavaScript client)." +msgstr "秘密 — OAuth client 可以对 GNU MediaGoblin 站点发送不被用户代理拦截的请求(例如服务端上的 client)。\n公开 — OAuth client 无法对 GNU MediaGoblin 站点发送秘密的请求(例如客户端的 JavaScript client)。" + +#: mediagoblin/plugins/oauth/forms.py:52 +msgid "Redirect URI" +msgstr "重定向 URI" + +#: mediagoblin/plugins/oauth/forms.py:54 +msgid "" +"The redirect URI for the applications, this field\n" +" is required for public clients." +msgstr "此应用程序的重定向 URI,本字段在公开类型的 OAuth client 为必填。" + +#: mediagoblin/plugins/oauth/forms.py:66 +msgid "This field is required for public clients" +msgstr "本字段在公开类型的 OAuth client 为必填" + +#: mediagoblin/plugins/oauth/views.py:56 +msgid "The client {0} has been registered!" +msgstr "OAuth client {0} 注册完成!" + +#: mediagoblin/plugins/oauth/templates/oauth/client/connections.html:22 +msgid "OAuth client connections" +msgstr "OAuth client 连接" + +#: mediagoblin/plugins/oauth/templates/oauth/client/list.html:22 +msgid "Your OAuth clients" +msgstr "您的 OAuth client" + +#: mediagoblin/plugins/oauth/templates/oauth/client/register.html:29 +#: mediagoblin/templates/mediagoblin/submit/collection.html:30 +#: mediagoblin/templates/mediagoblin/submit/start.html:34 +#: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:68 +msgid "Add" +msgstr "增加" + +#: mediagoblin/processing/__init__.py:193 +msgid "Invalid file given for media type." +msgstr "提供文件的媒体类型错误。" + +#: mediagoblin/submit/forms.py:26 +msgid "File" +msgstr "文件" + +#: mediagoblin/submit/views.py:49 +msgid "You must provide a file." +msgstr "您必须提供一个文件" + +#: mediagoblin/submit/views.py:93 +msgid "Woohoo! Submitted!" +msgstr "啊哈!已提交!" + +#: mediagoblin/submit/views.py:144 +#, python-format +msgid "Collection \"%s\" added!" +msgstr "合集“%s”已新增!" + +#: mediagoblin/templates/mediagoblin/base.html:67 +msgid "Verify your email!" +msgstr "确认您的电子邮件!" + +#: mediagoblin/templates/mediagoblin/base.html:68 +msgid "log out" +msgstr "登出" + +#: mediagoblin/templates/mediagoblin/base.html:73 +#: mediagoblin/templates/mediagoblin/auth/login.html:28 +#: mediagoblin/templates/mediagoblin/auth/login.html:36 +#: mediagoblin/templates/mediagoblin/auth/login.html:54 +msgid "Log in" +msgstr "登录" + +#: mediagoblin/templates/mediagoblin/base.html:82 +#, python-format +msgid "%(user_name)s's account" +msgstr "%(user_name)s 的账户" + +#: mediagoblin/templates/mediagoblin/base.html:89 +msgid "Change account settings" +msgstr "更改账户设置" + +#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:108 +#: mediagoblin/templates/mediagoblin/admin/panel.html:21 +#: mediagoblin/templates/mediagoblin/admin/panel.html:26 +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:21 +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:26 +msgid "Media processing panel" +msgstr "媒体处理面板" + +#: mediagoblin/templates/mediagoblin/base.html:96 +msgid "Log out" +msgstr "登出" + +#: mediagoblin/templates/mediagoblin/base.html:99 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:156 +msgid "Add media" +msgstr "新增媒体" + +#: mediagoblin/templates/mediagoblin/base.html:102 +#: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:41 +msgid "Create new collection" +msgstr "新增合集" + +#: mediagoblin/templates/mediagoblin/error.html:24 +msgid "Image of goblin stressing out" +msgstr "满脸问号的哥布林" + +#: mediagoblin/templates/mediagoblin/root.html:32 +msgid "Most recent media" +msgstr "最新的媒体" + +#: mediagoblin/templates/mediagoblin/admin/panel.html:29 +msgid "" +"Here you can track the state of media being processed on this instance." +msgstr "此处您可以追踪本站点处理媒体的状态。" + +#: mediagoblin/templates/mediagoblin/admin/panel.html:32 +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:32 +msgid "Media in-processing" +msgstr "媒体处理中" + +#: mediagoblin/templates/mediagoblin/admin/panel.html:58 +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:56 +msgid "No media in-processing" +msgstr "没有正在处理中的媒体" + +#: mediagoblin/templates/mediagoblin/admin/panel.html:61 +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:59 +msgid "These uploads failed to process:" +msgstr "无法处理这些上传内容:" + +#: mediagoblin/templates/mediagoblin/admin/panel.html:90 +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:86 +msgid "No failed entries!" +msgstr "没有失败的纪录!" + +#: mediagoblin/templates/mediagoblin/admin/panel.html:92 +msgid "Last 10 successful uploads" +msgstr "最近 10 次成功上传的纪录" + +#: mediagoblin/templates/mediagoblin/admin/panel.html:112 +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:107 +msgid "No processed entries, yet!" +msgstr "现在还没有处理的纪录!" + +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:28 +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:36 +msgid "Set your new password" +msgstr "设置您的新密码" + +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:39 +msgid "Set password" +msgstr "设置新密码" + +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:23 +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:31 +msgid "Recover password" +msgstr "找回密码" + +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:34 +msgid "Send instructions" +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 "%(username)s 您好:\n\n要修改 GNU MediaGoblin 的密码,请在您的浏览器中打开下面的网址:\n\n%(verification_url)s\n\n如果您认为这个是个误会,请忽略此封信件,继续当个快乐的哥布林!" + +#: mediagoblin/templates/mediagoblin/auth/login.html:39 +msgid "Logging in failed!" +msgstr "登录失败!" + +#: mediagoblin/templates/mediagoblin/auth/login.html:44 +msgid "Don't have an account yet?" +msgstr "还没有账户吗?" + +#: mediagoblin/templates/mediagoblin/auth/login.html:45 +msgid "Create one here!" +msgstr "在这里建立一个吧!" + +#: mediagoblin/templates/mediagoblin/auth/login.html:51 +msgid "Forgot your password?" +msgstr "忘了密码吗?" + +#: mediagoblin/templates/mediagoblin/auth/register.html:28 +#: mediagoblin/templates/mediagoblin/auth/register.html:36 +msgid "Create an account!" +msgstr "建立一个账户!" + +#: mediagoblin/templates/mediagoblin/auth/register.html:40 +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 "%(username)s 您好:\n\n要启动 GNU MediaGoblin 账户,请在您的浏览器中打开下面的网址:\n\n%(verification_url)s" + +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:21 +#, python-format +msgid "" +"Powered by MediaGoblin, a GNU project." +msgstr "Powered by MediaGoblin,一个 GNU 项目。" + +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:24 +#, python-format +msgid "" +"Released under the AGPL. Source code available." +msgstr "以 AGPL 授权发布。备有源代码。" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:20 +msgid "Explore" +msgstr "探索" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:22 +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "嘿!欢迎来到 MediaGoblin 站! " + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:24 +msgid "" +"This site is running MediaGoblin, an " +"extraordinarily great piece of media hosting software." +msgstr "本站使用 MediaGoblin——与众不同的媒体分享网站。" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:25 +msgid "" +"To add your own media, place comments, and more, you can log in with your " +"MediaGoblin account." +msgstr "您可以登录您的 MediaGoblin 账户以上传媒体、张贴评论等等。" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:27 +msgid "Don't have one yet? It's easy!" +msgstr "没有账户吗?开账户很简单!" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:28 +#, python-format +msgid "" +"Create an account at this site\n" +" or\n" +" Set up MediaGoblin on your own server" +msgstr "在本站创建帐户\n 或者\n 在您自己的服务器上搭建 MediaGoblin" + +#: mediagoblin/templates/mediagoblin/bits/logo.html:23 +#: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 +msgid "MediaGoblin logo" +msgstr "MediaGoblin 标志" + +#: mediagoblin/templates/mediagoblin/edit/attachments.html:23 +#: mediagoblin/templates/mediagoblin/edit/attachments.html:35 +#, python-format +msgid "Editing attachments for %(media_title)s" +msgstr "编辑 %(media_title)s 的附件" + +#: mediagoblin/templates/mediagoblin/edit/attachments.html:44 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:182 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:198 +msgid "Attachments" +msgstr "附件" + +#: mediagoblin/templates/mediagoblin/edit/attachments.html:57 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:204 +msgid "Add attachment" +msgstr "新增附件" + +#: mediagoblin/templates/mediagoblin/edit/attachments.html:61 +#: mediagoblin/templates/mediagoblin/edit/delete_account.html:42 +#: mediagoblin/templates/mediagoblin/edit/edit.html:41 +#: mediagoblin/templates/mediagoblin/edit/edit_collection.html:32 +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:46 +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:52 +#: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:67 +#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:48 +msgid "Cancel" +msgstr "取消" + +#: mediagoblin/templates/mediagoblin/edit/attachments.html:63 +#: mediagoblin/templates/mediagoblin/edit/edit.html:42 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:55 +#: mediagoblin/templates/mediagoblin/edit/edit_collection.html:33 +#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:40 +msgid "Save changes" +msgstr "保存更改" + +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:28 +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 +#, python-format +msgid "Changing %(username)s's password" +msgstr "修改 %(username)s 的密码" + +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 +msgid "Save" +msgstr "保存" + +#: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 +#, python-format +msgid "Really delete user '%(user_name)s' and all related media/comments?" +msgstr "真的要删除用户 %(user_name)s 及所有相关媒体和评论吗?" + +#: mediagoblin/templates/mediagoblin/edit/delete_account.html:35 +msgid "Yes, really delete my account" +msgstr "是的,真的删除我的账户" + +#: mediagoblin/templates/mediagoblin/edit/delete_account.html:44 +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:48 +#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49 +msgid "Delete permanently" +msgstr "永久删除" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:23 +#: mediagoblin/templates/mediagoblin/edit/edit.html:35 +#, python-format +msgid "Editing %(media_title)s" +msgstr "编辑 %(media_title)s" + +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:28 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:40 +#, python-format +msgid "Changing %(username)s's account settings" +msgstr "正在改变 %(username)s 的账户设置" + +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 +msgid "Change your password." +msgstr "修改您的密码。" + +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 +msgid "Delete my account" +msgstr "删除我的帐户" + +#: mediagoblin/templates/mediagoblin/edit/edit_collection.html:29 +#, python-format +msgid "Editing %(collection_title)s" +msgstr "编辑 %(collection_title)s" + +#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:23 +#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:34 +#, python-format +msgid "Editing %(username)s's profile" +msgstr "编辑 %(username)s 的个人资料" + +#: mediagoblin/templates/mediagoblin/listings/collection.html:30 +#: mediagoblin/templates/mediagoblin/listings/collection.html:35 +#: mediagoblin/templates/mediagoblin/listings/tag.html:30 +#: mediagoblin/templates/mediagoblin/listings/tag.html:35 +#, python-format +msgid "Media tagged with: %(tag_name)s" +msgstr "此媒体被标记为:%(tag_name)s" + +#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 +#: mediagoblin/templates/mediagoblin/media_displays/audio.html:56 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:65 +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:136 +#: mediagoblin/templates/mediagoblin/media_displays/video.html:55 +msgid "Download" +msgstr "下载" + +#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:38 +msgid "Original" +msgstr "源文件" + +#: mediagoblin/templates/mediagoblin/media_displays/audio.html:44 +msgid "" +"Sorry, this audio will not work because \n" +"\tyour web browser does not support HTML5 \n" +"\taudio." +msgstr "抱歉,此声音无法播放,因为您的浏览器不支持 HTML5 音频。" + +#: mediagoblin/templates/mediagoblin/media_displays/audio.html:47 +msgid "" +"You can get a modern web browser that \n" +"\tcan play the audio at \n" +"\t http://getfirefox.com!" +msgstr "您可以在 http://getfirefox.com 取得可以播放此声音的浏览器!" + +#: mediagoblin/templates/mediagoblin/media_displays/audio.html:60 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:71 +#: mediagoblin/templates/mediagoblin/media_displays/video.html:61 +msgid "Original file" +msgstr "源文件" + +#: mediagoblin/templates/mediagoblin/media_displays/audio.html:63 +msgid "WebM file (Vorbis codec)" +msgstr "WebM 文件(Vorbis 编码)" + +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:59 +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:87 +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:93 +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:99 +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:105 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:59 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:65 +#, python-format +msgid "Image for %(media_title)s" +msgstr "%(media_title)s 的照片" + +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 +msgid "PDF file" +msgstr "PDF 文件" + +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 +msgid "Toggle Rotate" +msgstr "切换旋转" + +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:113 +msgid "Perspective" +msgstr "透视" + +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:116 +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:117 +msgid "Front" +msgstr "正面" + +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:120 +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:121 +msgid "Top" +msgstr "顶面" + +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:124 +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:125 +msgid "Side" +msgstr "侧面" + +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:130 +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:131 +msgid "WebGL" +msgstr "WebGL" + +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:138 +msgid "Download model" +msgstr "下载模型" + +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:146 +msgid "File Format" +msgstr "文件格式" + +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:148 +msgid "Object Height" +msgstr "对象高度" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:44 +msgid "" +"Sorry, this video will not work because\n" +" your web browser does not support HTML5 \n" +" video." +msgstr "抱歉,此视频无法播放,因为您的浏览器不支持 HTML5 视频。" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:47 +msgid "" +"You can get a modern web browser that \n" +" can play this video at \n" +" http://getfirefox.com!" +msgstr "您可以在 http://getfirefox.com 取得可以播放此视频的浏览器!" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:69 +msgid "WebM file (640p; VP8/Vorbis)" +msgstr "WebM 文件(640p;VP8/Vorbis)" + +#: mediagoblin/templates/mediagoblin/submit/collection.html:26 +msgid "Add a collection" +msgstr "新增合集" + +#: mediagoblin/templates/mediagoblin/submit/start.html:23 +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Add your media" +msgstr "加入您的媒体" + +#: mediagoblin/templates/mediagoblin/user_pages/collection.html:30 +#, python-format +msgid "%(collection_title)s (%(username)s's collection)" +msgstr "%(collection_title)s (%(username)s 的合集)" + +#: mediagoblin/templates/mediagoblin/user_pages/collection.html:39 +#, python-format +msgid "%(collection_title)s by %(username)s" +msgstr "%(collection_title)s by %(username)s" + +#: mediagoblin/templates/mediagoblin/user_pages/collection.html:52 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:79 +msgid "Edit" +msgstr "编辑" + +#: mediagoblin/templates/mediagoblin/user_pages/collection.html:56 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:83 +msgid "Delete" +msgstr "删除" + +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:30 +#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 +#, python-format +msgid "Really delete %(title)s?" +msgstr "真的要删除 %(title)s 吗?" + +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:31 +#, python-format +msgid "Really remove %(media_title)s from %(collection_title)s?" +msgstr "确定要从 %(collection_title)s 移除 %(media_title)s 吗?" + +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:54 +msgid "Remove" +msgstr "移除" + +#: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:21 +#, python-format +msgid "%(username)s's collections" +msgstr "%(username)s 的合集" + +#: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:28 +#, python-format +msgid "%(username)s's collections" +msgstr "%(username)s 的合集" + +#: mediagoblin/templates/mediagoblin/user_pages/comment_email.txt:19 +#, python-format +msgid "" +"Hi %(username)s,\n" +"%(comment_author)s commented on your post (%(comment_url)s) at %(instance_name)s\n" +msgstr "%(username)s 您好:\n%(comment_author)s 在 %(instance_name)s 对您的内容 (%(comment_url)s) 张贴评论\n" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 +#, python-format +msgid "%(username)s's media" +msgstr "%(username)s的媒体" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:38 +#, python-format +msgid "" +"%(username)s's media with tag %(tag)s" +msgstr "%(username)s 的有 %(tag)s 标签的媒体" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:48 +#, python-format +msgid "%(username)s's media" +msgstr "%(username)s 的媒体" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:38 +#, python-format +msgid "❖ Browsing media by %(username)s" +msgstr "❖ 浏览 %(username)s 的媒体" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:95 +msgid "Add a comment" +msgstr "新增评论" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 +msgid "Add this comment" +msgstr "增加评论" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:132 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:152 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:164 +#, python-format +msgid "%(formatted_time)s ago" +msgstr "%(formatted_time)s前" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:150 +msgid "Added" +msgstr "已增加" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:161 +msgid "Created" +msgstr "已创建" + +#: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 +#: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:40 +#, python-format +msgid "Add “%(media_title)s” to a collection" +msgstr "把“%(media_title)s”加入合集" + +#: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:54 +msgid "+" +msgstr "+" + +#: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:58 +msgid "Add a new collection" +msgstr "新增新的合集" + +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:29 +msgid "" +"You can track the state of media being processed for your gallery here." +msgstr "您可以在这里追踪您的艺廊中媒体处理的状态。" + +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:89 +msgid "Your last 10 successful uploads" +msgstr "您的最近 10 次成功上传的纪录" + +#: 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:53 +msgid "Almost done! Your account still needs to be activated." +msgstr "快完成了!但您需要激活您的账户。" + +#: 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:62 +msgid "In case it doesn't:" +msgstr "如果仍然无法认证,您可以:" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:65 +msgid "Resend verification email" +msgstr "重发认证邮件" + +#: 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: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:96 +msgid "Here's a spot to tell others about yourself." +msgstr "这个地方能让您向他人介绍自己。" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:100 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:117 +msgid "Edit profile" +msgstr "编辑个人资料" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:105 +msgid "This user hasn't filled in their profile (yet)." +msgstr "这个用户(还)没有填写个人资料。" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:124 +msgid "Browse collections" +msgstr "浏览合集" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:137 +#, python-format +msgid "View all of %(username)s's media" +msgstr "查看 %(username)s 的全部媒体" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:150 +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:162 +#: mediagoblin/templates/mediagoblin/utils/collection_gallery.html:84 +#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:70 +msgid "There doesn't seem to be any media here yet..." +msgstr "那里好像还没有任何的媒体……" + +#: mediagoblin/templates/mediagoblin/utils/collection_gallery.html:49 +msgid "(remove)" +msgstr "(移除)" + +#: mediagoblin/templates/mediagoblin/utils/collections.html:21 +msgid "Collected in" +msgstr "合集于" + +#: mediagoblin/templates/mediagoblin/utils/collections.html:40 +msgid "Add to a collection" +msgstr "添加到合集" + +#: mediagoblin/templates/mediagoblin/utils/feed_link.html:21 +#: mediagoblin/themes/airy/templates/mediagoblin/utils/feed_link.html:21 +msgid "feed icon" +msgstr "feed 图标" + +#: mediagoblin/templates/mediagoblin/utils/feed_link.html:23 +#: mediagoblin/themes/airy/templates/mediagoblin/utils/feed_link.html:23 +msgid "Atom feed" +msgstr "Atom feed" + +#: mediagoblin/templates/mediagoblin/utils/license.html:25 +msgid "All rights reserved" +msgstr "版权所有" + +#: mediagoblin/templates/mediagoblin/utils/pagination.html:39 +msgid "← Newer" +msgstr "← 更新的" + +#: mediagoblin/templates/mediagoblin/utils/pagination.html:45 +msgid "Older →" +msgstr "更旧的 →" + +#: mediagoblin/templates/mediagoblin/utils/pagination.html:48 +msgid "Go to page:" +msgstr "跳到页数:" + +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:28 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:33 +msgid "newer" +msgstr "更新的" + +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:39 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:44 +msgid "older" +msgstr "更旧的" + +#: mediagoblin/templates/mediagoblin/utils/tags.html:20 +msgid "Tagged with" +msgstr "标签" + +#: mediagoblin/tools/exif.py:83 +msgid "Could not read the image file." +msgstr "无法读取图片文件。" + +#: mediagoblin/tools/response.py:35 +msgid "Oops!" +msgstr "糟糕!" + +#: mediagoblin/tools/response.py:36 +msgid "An error occured" +msgstr "发生错误" + +#: mediagoblin/tools/response.py:51 +msgid "Operation not allowed" +msgstr "操作不允许" + +#: mediagoblin/tools/response.py:52 +msgid "" +"Sorry Dave, I can't let you do that!

You have tried to perform a " +"function that you are not allowed to. Have you been trying to delete all " +"user accounts again?" +msgstr "对不起老兄,我不能让你这样做!

您正在试着操作不允许您使用的功能。您难道想打算删除所有用户账户吗?" + +#: mediagoblin/tools/response.py:60 +msgid "" +"There doesn't seem to be a page at this address. Sorry!

If you're sure" +" the address is correct, maybe the page you're looking for has been moved or" +" deleted." +msgstr "不好意思,看起来这个网址上没有网页。

如果您确定这个网址是正确的,您在寻找的页面可能已经移动或是被删除了。" + +#: mediagoblin/tools/timesince.py:62 +msgid "year" +msgstr "年" + +#: mediagoblin/tools/timesince.py:63 +msgid "month" +msgstr "月" + +#: mediagoblin/tools/timesince.py:64 +msgid "week" +msgstr "周" + +#: mediagoblin/tools/timesince.py:65 +msgid "day" +msgstr "日" + +#: mediagoblin/tools/timesince.py:66 +msgid "hour" +msgstr "小时" + +#: mediagoblin/tools/timesince.py:67 +msgid "minute" +msgstr "分钟" + +#: mediagoblin/user_pages/forms.py:23 +msgid "Comment" +msgstr "评论" + +#: mediagoblin/user_pages/forms.py:25 +msgid "" +"You can use Markdown for" +" formatting." +msgstr "您可以用 Markdown 来排版。" + +#: mediagoblin/user_pages/forms.py:31 +msgid "I am sure I want to delete this" +msgstr "我确定我要删除这个媒体" + +#: mediagoblin/user_pages/forms.py:35 +msgid "I am sure I want to remove this item from the collection" +msgstr "我确定我要从合集中移除此项目" + +#: mediagoblin/user_pages/forms.py:39 +msgid "Collection" +msgstr "合集" + +#: mediagoblin/user_pages/forms.py:40 +msgid "-- Select --" +msgstr "— 请选择 —" + +#: mediagoblin/user_pages/forms.py:42 +msgid "Include a note" +msgstr "加注" + +#: mediagoblin/user_pages/lib.py:58 +msgid "commented on your post" +msgstr "在您的内容张贴评论" + +#: mediagoblin/user_pages/views.py:169 +msgid "Sorry, comments are disabled." +msgstr "抱歉,不开放评论。" + +#: mediagoblin/user_pages/views.py:174 +msgid "Oops, your comment was empty." +msgstr "啊,您的评论是空的。" + +#: mediagoblin/user_pages/views.py:180 +msgid "Your comment has been posted!" +msgstr "您的评论已经张贴完成!" + +#: mediagoblin/user_pages/views.py:205 +msgid "Please check your entries and try again." +msgstr "请检查项目并重试。" + +#: mediagoblin/user_pages/views.py:245 +msgid "You have to select or add a collection" +msgstr "您需要选择或是新增一个合集" + +#: mediagoblin/user_pages/views.py:256 +#, python-format +msgid "\"%s\" already in collection \"%s\"" +msgstr "“%s”已经在“%s”合集" + +#: mediagoblin/user_pages/views.py:262 +#, python-format +msgid "\"%s\" added to collection \"%s\"" +msgstr "“%s”加入“%s”合集" + +#: mediagoblin/user_pages/views.py:282 +msgid "You deleted the media." +msgstr "您已经删除此媒体。" + +#: mediagoblin/user_pages/views.py:289 +msgid "The media was not deleted because you didn't check that you were sure." +msgstr "由于您没有勾选确认,该媒体没有被移除。" + +#: mediagoblin/user_pages/views.py:296 +msgid "You are about to delete another user's media. Proceed with caution." +msgstr "您正在删除别人的媒体,请小心操作。" + +#: mediagoblin/user_pages/views.py:370 +msgid "You deleted the item from the collection." +msgstr "您已经从该合集中删除该项目。" + +#: mediagoblin/user_pages/views.py:374 +msgid "The item was not removed because you didn't check that you were sure." +msgstr "由于您没有勾选确认,该项目没有被移除。" + +#: mediagoblin/user_pages/views.py:382 +msgid "" +"You are about to delete an item from another user's collection. Proceed with" +" caution." +msgstr "您正在从别人的合集中删除项目,请小心操作。" + +#: mediagoblin/user_pages/views.py:415 +#, python-format +msgid "You deleted the collection \"%s\"" +msgstr "您已经删除“%s”合集。" + +#: mediagoblin/user_pages/views.py:422 +msgid "" +"The collection was not deleted because you didn't check that you were sure." +msgstr "由于您没有勾选确认,该合集没有被移除。" + +#: mediagoblin/user_pages/views.py:430 +msgid "" +"You are about to delete another user's collection. Proceed with caution." +msgstr "您正在删除别人的合集,请小心操作。" diff --git a/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.mo index 3fd4911a..4b7a2398 100644 Binary files a/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.mo and b/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.mo differ diff --git a/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.po index e2a8e680..05ecd4b5 100644 --- a/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.po @@ -5,14 +5,16 @@ # Translators: # , 2011 # Harry Chen , 2011-2012 +# medicalwei , 2013 # medicalwei , 2012 +# m13253 , 2013 msgid "" msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" "POT-Creation-Date: 2013-05-27 13:54-0500\n" -"PO-Revision-Date: 2013-05-27 18:54+0000\n" -"Last-Translator: cwebber \n" +"PO-Revision-Date: 2013-06-16 01:40+0000\n" +"Last-Translator: m13253 \n" "Language-Team: Chinese (Taiwan) (http://www.transifex.com/projects/p/mediagoblin/language/zh_TW/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -36,7 +38,7 @@ msgstr "Email 位址" #: mediagoblin/auth/forms.py:41 msgid "Username or Email" -msgstr "" +msgstr "使用者名稱或 email" #: mediagoblin/auth/forms.py:52 msgid "Username or email" @@ -44,15 +46,15 @@ msgstr "使用者名稱或 email" #: mediagoblin/auth/tools.py:31 msgid "Invalid User name or email address." -msgstr "" +msgstr "無效的使用者名稱或 email 位置。" #: mediagoblin/auth/tools.py:32 msgid "This field does not take email addresses." -msgstr "" +msgstr "本欄位不接受 email 位置。" #: mediagoblin/auth/tools.py:33 msgid "This field requires an email address." -msgstr "" +msgstr "本欄位需要 email 位置。" #: mediagoblin/auth/views.py:54 msgid "Sorry, registration is disabled on this instance." @@ -92,11 +94,11 @@ msgstr "重送認證信。" msgid "" "If that email address (case sensitive!) is registered an email has been sent" " with instructions on how to change your password." -msgstr "" +msgstr "如果那 email 位置 (請注意大小寫) 已經註冊,寫有修改密碼步驟的 email 已經送出。" #: mediagoblin/auth/views.py:269 msgid "Couldn't find someone with that username." -msgstr "" +msgstr "找不到相關的使用者名稱。" #: mediagoblin/auth/views.py:272 msgid "" @@ -173,15 +175,15 @@ msgstr "本網址出錯了" #: mediagoblin/edit/forms.py:63 msgid "License preference" -msgstr "" +msgstr "授權偏好" #: mediagoblin/edit/forms.py:69 msgid "This will be your default license on upload forms." -msgstr "" +msgstr "在上傳頁面,這將會是您預設的授權模式。" #: mediagoblin/edit/forms.py:71 msgid "Email me when others comment on my media" -msgstr "當有人對我的媒體評論時寄信給我" +msgstr "當有人對我的媒體留言時寄信給我" #: mediagoblin/edit/forms.py:83 msgid "The title can't be empty" @@ -225,7 +227,7 @@ msgstr "您加上了附件「%s」!" #: mediagoblin/edit/views.py:182 msgid "You can only edit your own profile." -msgstr "" +msgstr "您只能修改您自己的個人檔案。" #: mediagoblin/edit/views.py:188 msgid "You are editing a user's profile. Proceed with caution." @@ -241,7 +243,7 @@ msgstr "帳號設定已儲存" #: mediagoblin/edit/views.py:274 msgid "You need to confirm the deletion of your account." -msgstr "" +msgstr "您必須要確認是否刪除您的帳號。" #: mediagoblin/edit/views.py:310 mediagoblin/submit/views.py:138 #: mediagoblin/user_pages/views.py:222 @@ -263,7 +265,7 @@ msgstr "密碼錯誤" #: mediagoblin/edit/views.py:363 msgid "Your password was changed successfully" -msgstr "" +msgstr "您的密碼已經成功修改" #: mediagoblin/gmg_commands/assetlink.py:60 msgid "Cannot link theme... no theme set\n" @@ -280,24 +282,24 @@ msgstr "但是舊的目錄連結已經找到並移除。\n" #: mediagoblin/gmg_commands/assetlink.py:112 #, python-format msgid "Could not link \"%s\": %s exists and is not a symlink\n" -msgstr "" +msgstr "無法連結「%s」:%s 存在,且不是符號連結\n" #: mediagoblin/gmg_commands/assetlink.py:119 #, python-format msgid "Skipping \"%s\"; already set up.\n" -msgstr "" +msgstr "跳過「%s」,已經建置完成。\n" #: mediagoblin/gmg_commands/assetlink.py:124 #, python-format msgid "Old link found for \"%s\"; removing.\n" -msgstr "" +msgstr "找到「%s」舊的連結,刪除中。\n" #: mediagoblin/meddleware/csrf.py:134 msgid "" "CSRF cookie not present. This is most likely the result of a cookie blocker " "or somesuch.
Make sure to permit the settings of cookies for this " "domain." -msgstr "" +msgstr "跨網站存取 (CSRF) 的 cookie 不存在,有可能是 cookie 阻擋程式之類的程式導致的。
請允許此網域的 cookie 設定。" #: mediagoblin/media_types/__init__.py:111 #: mediagoblin/media_types/__init__.py:155 @@ -306,7 +308,7 @@ msgstr "抱歉,我不支援這樣的檔案格式 :(" #: mediagoblin/media_types/pdf/processing.py:136 msgid "unoconv failing to run, check log file" -msgstr "" +msgstr "unoconv 無法執行,請檢查紀錄檔" #: mediagoblin/media_types/video/processing.py:37 msgid "Video transcoding failed" @@ -335,7 +337,7 @@ msgstr "名稱" #: mediagoblin/plugins/oauth/forms.py:35 msgid "The name of the OAuth client" -msgstr "OAuth client 的名稱" +msgstr "OAuth 用戶程式的名稱" #: mediagoblin/plugins/oauth/forms.py:36 msgid "Description" @@ -359,7 +361,7 @@ msgid "" " Public - The client can't make confidential\n" " requests to the GNU MediaGoblin instance (e.g. client-side\n" " JavaScript client)." -msgstr "秘密 — OAuth client 可以對 GNU MediaGoblin 站台發送不被使用者代理攔截的請求 (例如伺服端的 client)。\n公開 — OAuth client 無法對 GNU MediaGoblin 站台發送秘密的請求 (例如客戶端的 JavaScript client)。" +msgstr "秘密 — OAuth 用戶程式可以對 GNU MediaGoblin 站台發送不被使用者代理攔截的請求 (例如伺服端的用戶程式)。\n公開 — OAuth 用戶程式無法對 GNU MediaGoblin 站台發送秘密的請求 (例如客戶端的 JavaScript 用戶程式)。" #: mediagoblin/plugins/oauth/forms.py:52 msgid "Redirect URI" @@ -369,23 +371,23 @@ msgstr "重定向 URI" msgid "" "The redirect URI for the applications, this field\n" " is required for public clients." -msgstr "此應用程式的重定向 URI,本欄位在公開類型的 OAuth client 為必填。" +msgstr "此應用程式的重定向 URI,本欄位在公開類型的 OAuth 用戶程式為必填。" #: mediagoblin/plugins/oauth/forms.py:66 msgid "This field is required for public clients" -msgstr "本欄位在公開類型的 OAuth client 為必填" +msgstr "本欄位在公開類型的用戶程式為必填" #: mediagoblin/plugins/oauth/views.py:56 msgid "The client {0} has been registered!" -msgstr "OAuth client {0} 註冊完成!" +msgstr "OAuth 用戶程式 {0} 註冊完成!" #: mediagoblin/plugins/oauth/templates/oauth/client/connections.html:22 msgid "OAuth client connections" -msgstr "" +msgstr "OAuth 用戶程式連線" #: mediagoblin/plugins/oauth/templates/oauth/client/list.html:22 msgid "Your OAuth clients" -msgstr "" +msgstr "您的 OAuth 用戶程式" #: mediagoblin/plugins/oauth/templates/oauth/client/register.html:29 #: mediagoblin/templates/mediagoblin/submit/collection.html:30 @@ -450,7 +452,7 @@ msgstr "媒體處理面板" #: mediagoblin/templates/mediagoblin/base.html:96 msgid "Log out" -msgstr "" +msgstr "登出" #: mediagoblin/templates/mediagoblin/base.html:99 #: mediagoblin/templates/mediagoblin/user_pages/user.html:156 @@ -577,7 +579,7 @@ msgstr "%(username)s 您好:\n\n要啟動 GNU MediaGoblin 帳號,請在您 msgid "" "Powered by MediaGoblin, a GNU project." -msgstr "" +msgstr "本站使用 MediaGoblin,這是一個 GNU 專案。" #: mediagoblin/templates/mediagoblin/bits/base_footer.html:24 #, python-format @@ -617,7 +619,7 @@ msgid "" "Create an account at this site\n" " or\n" " Set up MediaGoblin on your own server" -msgstr "" +msgstr "在本站建立您的帳號\n 或是\n 在您自己的伺服器上安裝 MediaGoblin" #: mediagoblin/templates/mediagoblin/bits/logo.html:23 #: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 @@ -664,20 +666,20 @@ msgstr "儲存變更" #: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 #, python-format msgid "Changing %(username)s's password" -msgstr "" +msgstr "更改 %(username)s 的密碼" #: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 msgid "Save" -msgstr "" +msgstr "儲存" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 #, python-format msgid "Really delete user '%(user_name)s' and all related media/comments?" -msgstr "" +msgstr "真的要刪除使用者「%(user_name)s」以及相關的媒體與留言?" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:35 msgid "Yes, really delete my account" -msgstr "" +msgstr "是的,我真的要把我的帳號刪除" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:44 #: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:48 @@ -699,11 +701,11 @@ msgstr "正在改變 %(username)s 的帳號設定" #: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 msgid "Change your password." -msgstr "" +msgstr "更改您的密碼。" #: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 msgid "Delete my account" -msgstr "" +msgstr "刪除我的帳號" #: mediagoblin/templates/mediagoblin/edit/edit_collection.html:29 #, python-format @@ -722,7 +724,7 @@ msgstr "編輯 %(username)s 的個人檔案" #: mediagoblin/templates/mediagoblin/listings/tag.html:35 #, python-format msgid "Media tagged with: %(tag_name)s" -msgstr "此媒體被 tag 成:%(tag_name)s" +msgstr "這個媒體具有以下標籤:%(tag_name)s" #: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 #: mediagoblin/templates/mediagoblin/media_displays/audio.html:56 @@ -773,7 +775,7 @@ msgstr " %(media_title)s 的照片" #: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 msgid "PDF file" -msgstr "" +msgstr "PDF 檔" #: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 msgid "Toggle Rotate" @@ -781,7 +783,7 @@ msgstr "切換旋轉" #: mediagoblin/templates/mediagoblin/media_displays/stl.html:113 msgid "Perspective" -msgstr "視角" +msgstr "透視" #: mediagoblin/templates/mediagoblin/media_displays/stl.html:116 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:117 @@ -820,14 +822,14 @@ msgid "" "Sorry, this video will not work because\n" " your web browser does not support HTML5 \n" " video." -msgstr "" +msgstr "抱歉,由於您的瀏覽器不支援 HTML5 影片,本影片無法播放" #: mediagoblin/templates/mediagoblin/media_displays/video.html:47 msgid "" "You can get a modern web browser that \n" " can play this video at \n" " http://getfirefox.com!" -msgstr "" +msgstr "您可以在 http://getfirefox.com 取得可以播放此影片的先進瀏覽器。" #: mediagoblin/templates/mediagoblin/media_displays/video.html:69 msgid "WebM file (640p; VP8/Vorbis)" @@ -880,19 +882,19 @@ msgstr "移除" #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:21 #, python-format msgid "%(username)s's collections" -msgstr "" +msgstr "%(username)s 的蒐藏" #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:28 #, python-format msgid "%(username)s's collections" -msgstr "" +msgstr "%(username)s 的蒐藏" #: mediagoblin/templates/mediagoblin/user_pages/comment_email.txt:19 #, python-format msgid "" "Hi %(username)s,\n" "%(comment_author)s commented on your post (%(comment_url)s) at %(instance_name)s\n" -msgstr "%(username)s 您好:\n%(comment_author)s 在 %(instance_name)s 對您的內容 (%(comment_url)s) 張貼評論\n" +msgstr "%(username)s 您好:\n%(comment_author)s 在 %(instance_name)s 對您的內容 (%(comment_url)s) 張貼留言\n" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format @@ -904,7 +906,7 @@ msgstr "%(username)s的媒體" msgid "" "%(username)s's media with tag %(tag)s" -msgstr "" +msgstr "標籤為 %(tag)s%(username)s 的媒體" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:48 #, python-format @@ -918,32 +920,32 @@ msgstr "❖ 瀏覽 %(username)s 的媒體" #: mediagoblin/templates/mediagoblin/user_pages/media.html:95 msgid "Add a comment" -msgstr "新增評論" +msgstr "新增留言" #: mediagoblin/templates/mediagoblin/user_pages/media.html:104 msgid "Add this comment" -msgstr "增加評論" +msgstr "增加留言" #: mediagoblin/templates/mediagoblin/user_pages/media.html:132 #: mediagoblin/templates/mediagoblin/user_pages/media.html:152 #: mediagoblin/templates/mediagoblin/user_pages/media.html:164 #, python-format msgid "%(formatted_time)s ago" -msgstr "" +msgstr "%(formatted_time)s 前" #: mediagoblin/templates/mediagoblin/user_pages/media.html:150 msgid "Added" -msgstr "" +msgstr "新增於" #: mediagoblin/templates/mediagoblin/user_pages/media.html:161 msgid "Created" -msgstr "" +msgstr "建立於" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:40 #, python-format msgid "Add “%(media_title)s” to a collection" -msgstr "" +msgstr "加入 “%(media_title)s” 至蒐藏" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:54 msgid "+" @@ -1022,7 +1024,7 @@ msgstr "這個使用者(還)沒有填寫個人檔案。" #: mediagoblin/templates/mediagoblin/user_pages/user.html:124 msgid "Browse collections" -msgstr "" +msgstr "瀏覽蒐藏" #: mediagoblin/templates/mediagoblin/user_pages/user.html:137 #, python-format @@ -1047,11 +1049,11 @@ msgstr " (移除)" #: mediagoblin/templates/mediagoblin/utils/collections.html:21 msgid "Collected in" -msgstr "" +msgstr "蒐集了" #: mediagoblin/templates/mediagoblin/utils/collections.html:40 msgid "Add to a collection" -msgstr "" +msgstr "加入至蒐藏" #: mediagoblin/templates/mediagoblin/utils/feed_link.html:21 #: mediagoblin/themes/airy/templates/mediagoblin/utils/feed_link.html:21 @@ -1125,31 +1127,31 @@ msgstr "不好意思,看起來這個網址上沒有網頁。

如果您 #: mediagoblin/tools/timesince.py:62 msgid "year" -msgstr "" +msgstr "年" #: mediagoblin/tools/timesince.py:63 msgid "month" -msgstr "" +msgstr "月" #: mediagoblin/tools/timesince.py:64 msgid "week" -msgstr "" +msgstr "週" #: mediagoblin/tools/timesince.py:65 msgid "day" -msgstr "" +msgstr "日" #: mediagoblin/tools/timesince.py:66 msgid "hour" -msgstr "" +msgstr "小時" #: mediagoblin/tools/timesince.py:67 msgid "minute" -msgstr "" +msgstr "分" #: mediagoblin/user_pages/forms.py:23 msgid "Comment" -msgstr "" +msgstr "留言" #: mediagoblin/user_pages/forms.py:25 msgid "" @@ -1168,7 +1170,7 @@ msgstr "我確定我要從蒐藏中移除此項目" #: mediagoblin/user_pages/forms.py:39 msgid "Collection" -msgstr "" +msgstr "蒐藏" #: mediagoblin/user_pages/forms.py:40 msgid "-- Select --" @@ -1180,11 +1182,11 @@ msgstr "加註" #: mediagoblin/user_pages/lib.py:58 msgid "commented on your post" -msgstr "在您的內容張貼評論" +msgstr "在您的內容張貼留言" #: mediagoblin/user_pages/views.py:169 msgid "Sorry, comments are disabled." -msgstr "" +msgstr "抱歉,留言被關閉。" #: mediagoblin/user_pages/views.py:174 msgid "Oops, your comment was empty." diff --git a/mediagoblin/init/celery/__init__.py b/mediagoblin/init/celery/__init__.py index 169cc935..57242bf6 100644 --- a/mediagoblin/init/celery/__init__.py +++ b/mediagoblin/init/celery/__init__.py @@ -16,12 +16,18 @@ import os import sys +import logging from celery import Celery from mediagoblin.tools.pluginapi import hook_runall -MANDATORY_CELERY_IMPORTS = ['mediagoblin.processing.task'] +_log = logging.getLogger(__name__) + + +MANDATORY_CELERY_IMPORTS = [ + 'mediagoblin.processing.task', + 'mediagoblin.notifications.task'] DEFAULT_SETTINGS_MODULE = 'mediagoblin.init.celery.dummy_settings_module' @@ -97,3 +103,13 @@ def setup_celery_from_config(app_config, global_config, if set_environ: os.environ['CELERY_CONFIG_MODULE'] = settings_module + + # Replace the default celery.current_app.conf if celery has already been + # initiated + from celery import current_app + + _log.info('Setting celery configuration from object "{0}"'.format( + settings_module)) + current_app.config_from_object(this_module) + + _log.debug('Celery broker host: {0}'.format(current_app.conf['BROKER_HOST'])) diff --git a/mediagoblin/media_types/stl/processing.py b/mediagoblin/media_types/stl/processing.py index 49382495..ce7a5d37 100644 --- a/mediagoblin/media_types/stl/processing.py +++ b/mediagoblin/media_types/stl/processing.py @@ -46,7 +46,7 @@ def sniff_handler(media_file, **kw): if kw.get('media') is not None: name, ext = os.path.splitext(kw['media'].filename) clean_ext = ext[1:].lower() - + if clean_ext in SUPPORTED_FILETYPES: _log.info('Found file extension in supported filetypes') return True diff --git a/mediagoblin/media_types/video/transcoders.py b/mediagoblin/media_types/video/transcoders.py index 90a767dd..9d6b7655 100644 --- a/mediagoblin/media_types/video/transcoders.py +++ b/mediagoblin/media_types/video/transcoders.py @@ -22,9 +22,15 @@ import logging import urllib import multiprocessing import gobject + +old_argv = sys.argv +sys.argv = [] + import pygst pygst.require('0.10') import gst + +sys.argv = old_argv import struct try: from PIL import Image diff --git a/mediagoblin/notifications/__init__.py b/mediagoblin/notifications/__init__.py new file mode 100644 index 00000000..4b7fbb8c --- /dev/null +++ b/mediagoblin/notifications/__init__.py @@ -0,0 +1,141 @@ +# 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 . + +import logging + +from mediagoblin.db.models import Notification, \ + CommentNotification, CommentSubscription +from mediagoblin.notifications.task import email_notification_task +from mediagoblin.notifications.tools import generate_comment_message + +_log = logging.getLogger(__name__) + +def trigger_notification(comment, media_entry, request): + ''' + Send out notifications about a new comment. + ''' + subscriptions = CommentSubscription.query.filter_by( + media_entry_id=media_entry.id).all() + + for subscription in subscriptions: + if not subscription.notify: + continue + + if comment.get_author == subscription.user: + continue + + cn = CommentNotification( + user_id=subscription.user_id, + subject_id=comment.id) + + cn.save() + + if subscription.send_email: + message = generate_comment_message( + subscription.user, + comment, + media_entry, + request) + + email_notification_task.apply_async([cn.id, message]) + + +def mark_notification_seen(notification): + if notification: + notification.seen = True + notification.save() + + +def mark_comment_notification_seen(comment_id, user): + notification = CommentNotification.query.filter_by( + user_id=user.id, + subject_id=comment_id).first() + + _log.debug('Marking {0} as seen.'.format(notification)) + + mark_notification_seen(notification) + + +def get_comment_subscription(user_id, media_entry_id): + return CommentSubscription.query.filter_by( + user_id=user_id, + media_entry_id=media_entry_id).first() + +def add_comment_subscription(user, media_entry): + ''' + Create a comment subscription for a User on a MediaEntry. + + Uses the User's wants_comment_notification to set email notifications for + the subscription to enabled/disabled. + ''' + cn = get_comment_subscription(user.id, media_entry.id) + + if not cn: + cn = CommentSubscription( + user_id=user.id, + media_entry_id=media_entry.id) + + cn.notify = True + + if not user.wants_comment_notification: + cn.send_email = False + + cn.save() + + +def silence_comment_subscription(user, media_entry): + ''' + Silence a subscription so that the user is never notified in any way about + new comments on an entry + ''' + cn = get_comment_subscription(user.id, media_entry.id) + + if cn: + cn.notify = False + cn.send_email = False + cn.save() + + +def remove_comment_subscription(user, media_entry): + cn = get_comment_subscription(user.id, media_entry.id) + + if cn: + cn.delete() + + +NOTIFICATION_FETCH_LIMIT = 100 + + +def get_notifications(user_id, only_unseen=True): + query = Notification.query.filter_by(user_id=user_id) + + if only_unseen: + query = query.filter_by(seen=False) + + notifications = query.limit( + NOTIFICATION_FETCH_LIMIT).all() + + return notifications + +def get_notification_count(user_id, only_unseen=True): + query = Notification.query.filter_by(user_id=user_id) + + if only_unseen: + query = query.filter_by(seen=False) + + count = query.count() + + return count diff --git a/mediagoblin/notifications/routing.py b/mediagoblin/notifications/routing.py new file mode 100644 index 00000000..e57956d3 --- /dev/null +++ b/mediagoblin/notifications/routing.py @@ -0,0 +1,25 @@ +# 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 . + +from mediagoblin.tools.routing import add_route + +add_route('mediagoblin.notifications.subscribe_comments', + '/u//m//notifications/subscribe/comments/', + 'mediagoblin.notifications.views:subscribe_comments') + +add_route('mediagoblin.notifications.silence_comments', + '/u//m//notifications/silence/', + 'mediagoblin.notifications.views:silence_comments') diff --git a/mediagoblin/notifications/task.py b/mediagoblin/notifications/task.py new file mode 100644 index 00000000..52573b57 --- /dev/null +++ b/mediagoblin/notifications/task.py @@ -0,0 +1,46 @@ +# 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 . + +import logging + +from celery import registry +from celery.task import Task + +from mediagoblin.tools.mail import send_email +from mediagoblin.db.models import CommentNotification + + +_log = logging.getLogger(__name__) + + +class EmailNotificationTask(Task): + ''' + Celery notification task. + + This task is executed by celeryd to offload long-running operations from + the web server. + ''' + def run(self, notification_id, message): + cn = CommentNotification.query.filter_by(id=notification_id).first() + _log.info('Sending notification email about {0}'.format(cn)) + + return send_email( + message['from'], + [message['to']], + message['subject'], + message['body']) + +email_notification_task = registry.tasks[EmailNotificationTask.name] diff --git a/mediagoblin/notifications/tools.py b/mediagoblin/notifications/tools.py new file mode 100644 index 00000000..25432780 --- /dev/null +++ b/mediagoblin/notifications/tools.py @@ -0,0 +1,55 @@ +# 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 . + +from mediagoblin.tools.template import render_template +from mediagoblin.tools.translate import pass_to_ugettext as _ +from mediagoblin import mg_globals + +def generate_comment_message(user, comment, media, request): + """ + Sends comment email to user when a comment is made on their media. + + Args: + - user: the user object to whom the email is sent + - comment: the comment object referencing user's media + - media: the media object the comment is about + - request: the request + """ + + comment_url = request.urlgen( + 'mediagoblin.user_pages.media_home.view_comment', + comment=comment.id, + user=media.get_uploader.username, + media=media.slug_or_id, + qualified=True) + '#comment' + + comment_author = comment.get_author.username + + rendered_email = render_template( + request, 'mediagoblin/user_pages/comment_email.txt', + {'username': user.username, + 'comment_author': comment_author, + 'comment_content': comment.content, + 'comment_url': comment_url}) + + return { + 'from': mg_globals.app_config['email_sender_address'], + 'to': user.email, + 'subject': '{instance_title} - {comment_author} '.format( + comment_author=comment_author, + instance_title=mg_globals.app_config['html_title']) \ + + _('commented on your post'), + 'body': rendered_email} diff --git a/mediagoblin/notifications/views.py b/mediagoblin/notifications/views.py new file mode 100644 index 00000000..d275bc92 --- /dev/null +++ b/mediagoblin/notifications/views.py @@ -0,0 +1,54 @@ +# 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 . + +from mediagoblin.tools.response import render_to_response, render_404, redirect +from mediagoblin.tools.translate import pass_to_ugettext as _ +from mediagoblin.decorators import (uses_pagination, get_user_media_entry, + get_media_entry_by_id, + require_active_login, user_may_delete_media, user_may_alter_collection, + get_user_collection, get_user_collection_item, active_user_from_url) + +from mediagoblin import messages + +from mediagoblin.notifications import add_comment_subscription, \ + silence_comment_subscription + +from werkzeug.exceptions import BadRequest + +@get_user_media_entry +@require_active_login +def subscribe_comments(request, media): + + add_comment_subscription(request.user, media) + + messages.add_message(request, + messages.SUCCESS, + _('Subscribed to comments on %s!') + % media.title) + + return redirect(request, location=media.url_for_self(request.urlgen)) + +@get_user_media_entry +@require_active_login +def silence_comments(request, media): + silence_comment_subscription(request.user, media) + + messages.add_message(request, + messages.SUCCESS, + _('You will not receive notifications for comments on' + ' %s.') % media.title) + + return redirect(request, location=media.url_for_self(request.urlgen)) diff --git a/mediagoblin/plugins/basic_auth/__init__.py b/mediagoblin/plugins/basic_auth/__init__.py index 71e96d73..a2efae92 100644 --- a/mediagoblin/plugins/basic_auth/__init__.py +++ b/mediagoblin/plugins/basic_auth/__init__.py @@ -13,8 +13,6 @@ # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -import uuid - from mediagoblin.plugins.basic_auth import forms as auth_forms from mediagoblin.plugins.basic_auth import tools as auth_tools from mediagoblin.db.models import User @@ -45,7 +43,6 @@ def create_user(registration_form): user.email = registration_form.email.data user.pw_hash = gen_password_hash( registration_form.password.data) - user.verification_key = unicode(uuid.uuid4()) user.save() return user diff --git a/mediagoblin/routing.py b/mediagoblin/routing.py index a650f22f..986eb2ed 100644 --- a/mediagoblin/routing.py +++ b/mediagoblin/routing.py @@ -35,6 +35,7 @@ def get_url_map(): import mediagoblin.edit.routing import mediagoblin.webfinger.routing import mediagoblin.listings.routing + import mediagoblin.notifications.routing for route in PluginManager().get_routes(): add_route(*route) diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css index 5b8226e6..8b57584d 100644 --- a/mediagoblin/static/css/base.css +++ b/mediagoblin/static/css/base.css @@ -129,6 +129,7 @@ header { .header_dropdown { margin-bottom: 20px; + padding: 0px 10px 0px 10px; } .header_dropdown li { @@ -384,6 +385,12 @@ a.comment_whenlink:hover { margin-top: 8px; } +.comment_active { + box-shadow: 0px 0px 15px 15px #378566; + background: #378566; + color: #f7f7f7; +} + textarea#comment_content { resize: vertical; width: 100%; diff --git a/mediagoblin/static/css/pdf_viewer.css b/mediagoblin/static/css/pdf_viewer.css deleted file mode 100644 index c04c8981..00000000 --- a/mediagoblin/static/css/pdf_viewer.css +++ /dev/null @@ -1,1448 +0,0 @@ -/* Copyright 2012 Mozilla Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -* { - padding: 0; - margin: 0; -} - -html { - height: 100%; -} - -body { - height: 100%; - background-color: #404040; - background-image: url(../extlib/pdf.js/web/images/texture.png); -} - -body, -input, -button, -select { - font: message-box; -} - -.hidden { - display: none; -} -[hidden] { - display: none !important; -} - -#viewerContainer:-webkit-full-screen { - top: 0px; - border-top: 2px solid transparent; - background-color: #404040; - background-image: url(../extlib/pdf.js/web/images/texture.png); - width: 100%; - height: 100%; - overflow: hidden; - cursor: none; -} - -#viewerContainer:-moz-full-screen { - top: 0px; - border-top: 2px solid transparent; - background-color: #404040; - background-image: url(../extlib/pdf.js/web/images/texture.png); - width: 100%; - height: 100%; - overflow: hidden; - cursor: none; -} - -#viewerContainer:fullscreen { - top: 0px; - border-top: 2px solid transparent; - background-color: #404040; - background-image: url(../extlib/pdf.js/web/images/texture.png); - width: 100%; - height: 100%; - overflow: hidden; - cursor: none; -} - - -:-webkit-full-screen .page { - margin-bottom: 100%; -} - -:-moz-full-screen .page { - margin-bottom: 100%; -} - -:fullscreen .page { - margin-bottom: 100%; -} - -#viewerContainer.presentationControls { - cursor: default; -} - -/* outer/inner center provides horizontal center */ -html[dir='ltr'] .outerCenter { - float: right; - position: relative; - right: 50%; -} -html[dir='rtl'] .outerCenter { - float: left; - position: relative; - left: 50%; -} -html[dir='ltr'] .innerCenter { - float: right; - position: relative; - right: -50%; -} -html[dir='rtl'] .innerCenter { - float: left; - position: relative; - left: -50%; -} - -#outerContainer { - width: 100%; - height: 100%; -} - -#sidebarContainer { - left: 0; - right: 0; - height: 200px; - visibility: hidden; - -webkit-transition-duration: 200ms; - -webkit-transition-timing-function: ease; - -moz-transition-duration: 200ms; - -moz-transition-timing-function: ease; - -ms-transition-duration: 200ms; - -ms-transition-timing-function: ease; - -o-transition-duration: 200ms; - -o-transition-timing-function: ease; - transition-duration: 200ms; - transition-timing-function: ease; - -} -html[dir='ltr'] #sidebarContainer { - -webkit-transition-property: top; - -moz-transition-property: top; - -ms-transition-property: top; - -o-transition-property: top; - transition-property: top; - top: -200px; -} -html[dir='rtl'] #sidebarContainer { - -webkit-transition-property: top; - -ms-transition-property: top; - -o-transition-property: top; - transition-property: top; - top: -200px; -} - -#outerContainer.sidebarMoving > #sidebarContainer, -#outerContainer.sidebarOpen > #sidebarContainer { - visibility: visible; -} -html[dir='ltr'] #outerContainer.sidebarOpen > #sidebarContainer { - left: 0px; -} -html[dir='rtl'] #outerContainer.sidebarOpen > #sidebarContainer { - right: 0px; -} - -#mainContainer { - top: 0; - right: 0; - bottom: 0; - left: 0; - min-width: 320px; - -webkit-transition-duration: 200ms; - -webkit-transition-timing-function: ease; - -moz-transition-duration: 200ms; - -moz-transition-timing-function: ease; - -ms-transition-duration: 200ms; - -ms-transition-timing-function: ease; - -o-transition-duration: 200ms; - -o-transition-timing-function: ease; - transition-duration: 200ms; - transition-timing-function: ease; -} -html[dir='ltr'] #outerContainer.sidebarOpen > #mainContainer { - -webkit-transition-property: left; - -moz-transition-property: left; - -ms-transition-property: left; - -o-transition-property: left; - transition-property: left; - left: 200px; -} -html[dir='rtl'] #outerContainer.sidebarOpen > #mainContainer { - -webkit-transition-property: right; - -moz-transition-property: right; - -ms-transition-property: right; - -o-transition-property: right; - transition-property: right; - right: 200px; -} - -#sidebarContent { - top: 32px; - bottom: 0; - overflow: auto; - height: 200px; - - background-color: hsla(0,0%,0%,.1); - box-shadow: inset -1px 0 0 hsla(0,0%,0%,.25); -} -html[dir='ltr'] #sidebarContent { - left: 0; -} -html[dir='rtl'] #sidebarContent { - right: 0; -} - -#viewerContainer { - overflow: auto; - box-shadow: inset 1px 0 0 hsla(0,0%,100%,.05); - top: 32px; - right: 0; - bottom: 0; - left: 0; - height: 480px; - width: 640px; -} - -.toolbar { - left: 0; - right: 0; - height: 32px; - z-index: 9999; - cursor: default; -} - -#toolbarContainer { - width: 100%; -} - -#toolbarSidebar { - width: 200px; - height: 32px; - background-image: url(../extlib/pdf.js/web/images/texture.png), - -webkit-linear-gradient(hsla(0,0%,30%,.99), hsla(0,0%,25%,.95)); - background-image: url(../extlib/pdf.js/web/images/texture.png), - -moz-linear-gradient(hsla(0,0%,30%,.99), hsla(0,0%,25%,.95)); - background-image: url(../extlib/pdf.js/web/images/texture.png), - -ms-linear-gradient(hsla(0,0%,30%,.99), hsla(0,0%,25%,.95)); - background-image: url(../extlib/pdf.js/web/images/texture.png), - -o-linear-gradient(hsla(0,0%,30%,.99), hsla(0,0%,25%,.95)); - background-image: url(../extlib/pdf.js/web/images/texture.png), - linear-gradient(hsla(0,0%,30%,.99), hsla(0,0%,25%,.95)); - box-shadow: inset -1px 0 0 rgba(0, 0, 0, 0.25), - - inset 0 -1px 0 hsla(0,0%,100%,.05), - 0 1px 0 hsla(0,0%,0%,.15), - 0 0 1px hsla(0,0%,0%,.1); -} - -#toolbarViewer, .findbar { - position: relative; - height: 32px; - background-color: #474747; /* IE9 */ - background-image: url(../extlib/pdf.js/web/images/texture.png), - -webkit-linear-gradient(hsla(0,0%,32%,.99), hsla(0,0%,27%,.95)); - background-image: url(../extlib/pdf.js/web/images/texture.png), - -moz-linear-gradient(hsla(0,0%,32%,.99), hsla(0,0%,27%,.95)); - background-image: url(../extlib/pdf.js/web/images/texture.png), - -ms-linear-gradient(hsla(0,0%,32%,.99), hsla(0,0%,27%,.95)); - background-image: url(../extlib/pdf.js/web/images/texture.png), - -o-linear-gradient(hsla(0,0%,32%,.99), hsla(0,0%,27%,.95)); - background-image: url(../extlib/pdf.js/web/images/texture.png), - linear-gradient(hsla(0,0%,32%,.99), hsla(0,0%,27%,.95)); - box-shadow: inset 1px 0 0 hsla(0,0%,100%,.08), - inset 0 1px 1px hsla(0,0%,0%,.15), - inset 0 -1px 0 hsla(0,0%,100%,.05), - 0 1px 0 hsla(0,0%,0%,.15), - 0 1px 1px hsla(0,0%,0%,.1); -} - -.findbar { - top: 64px; - z-index: 10000; - height: 32px; - - min-width: 16px; - padding: 0px 6px 0px 6px; - margin: 4px 2px 4px 2px; - color: hsl(0,0%,85%); - font-size: 12px; - line-height: 14px; - text-align: left; - cursor: default; -} - -html[dir='ltr'] .findbar { - left: 68px; -} - -html[dir='rtl'] .findbar { - right: 68px; -} - -.findbar label { - -webkit-user-select: none; - -moz-user-select: none; -} - -#findInput[data-status="pending"] { - background-image: url(../extlib/pdf.js/web/images/loading-small.png); - background-repeat: no-repeat; - background-position: right; -} - -.doorHanger { - border: 1px solid hsla(0,0%,0%,.5); - border-radius: 2px; - box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3); -} -.doorHanger:after, .doorHanger:before { - bottom: 100%; - border: solid transparent; - content: " "; - height: 0; - width: 0; - pointer-events: none; -} -.doorHanger:after { - border-bottom-color: hsla(0,0%,32%,.99); - border-width: 8px; -} -.doorHanger:before { - border-bottom-color: hsla(0,0%,0%,.5); - border-width: 9px; -} - -html[dir='ltr'] .doorHanger:after { - left: 13px; - margin-left: -8px; -} - -html[dir='ltr'] .doorHanger:before { - left: 13px; - margin-left: -9px; -} - -html[dir='rtl'] .doorHanger:after { - right: 13px; - margin-right: -8px; -} - -html[dir='rtl'] .doorHanger:before { - right: 13px; - margin-right: -9px; -} - -#findMsg { - font-style: italic; - color: #A6B7D0; -} - -.notFound { - background-color: rgb(255, 137, 153); -} - -html[dir='ltr'] #toolbarViewerLeft { - margin-left: -1px; -} -html[dir='rtl'] #toolbarViewerRight { - margin-left: -1px; -} - - -html[dir='ltr'] #toolbarViewerLeft, -html[dir='rtl'] #toolbarViewerRight { - position: absolute; - top: 0; - left: 0; -} -html[dir='ltr'] #toolbarViewerRight, -html[dir='rtl'] #toolbarViewerLeft { - position: absolute; - top: 0; - right: 0; -} -html[dir='ltr'] #toolbarViewerLeft > *, -html[dir='ltr'] #toolbarViewerMiddle > *, -html[dir='ltr'] #toolbarViewerRight > *, -html[dir='ltr'] .findbar > * { - float: left; -} -html[dir='rtl'] #toolbarViewerLeft > *, -html[dir='rtl'] #toolbarViewerMiddle > *, -html[dir='rtl'] #toolbarViewerRight > *, -html[dir='rtl'] .findbar > * { - float: right; -} - -html[dir='ltr'] .splitToolbarButton { - margin: 3px 2px 4px 0; - display: inline-block; -} -html[dir='rtl'] .splitToolbarButton { - margin: 3px 0 4px 2px; - display: inline-block; -} -html[dir='ltr'] .splitToolbarButton > .toolbarButton { - border-radius: 0; - float: left; -} -html[dir='rtl'] .splitToolbarButton > .toolbarButton { - border-radius: 0; - float: right; -} - -.toolbarButton { - border: 0 none; - background-color: rgba(0, 0, 0, 0); - width: 32px; - height: 25px; -} - -.toolbarButton > span { - display: inline-block; - width: 0; - height: 0; - overflow: hidden; -} - -.toolbarButton[disabled] { - opacity: .5; -} - -.toolbarButton.group { - margin-right: 0; -} - -.splitToolbarButton.toggled .toolbarButton { - margin: 0; -} - -.splitToolbarButton:hover > .toolbarButton, -.splitToolbarButton:focus > .toolbarButton, -.splitToolbarButton.toggled > .toolbarButton, -.toolbarButton.textButton { - background-color: hsla(0,0%,0%,.12); - background-image: -webkit-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-image: -moz-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-image: -ms-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-image: -o-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-image: linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-clip: padding-box; - border: 1px solid hsla(0,0%,0%,.35); - border-color: hsla(0,0%,0%,.32) hsla(0,0%,0%,.38) hsla(0,0%,0%,.42); - box-shadow: 0 1px 0 hsla(0,0%,100%,.05) inset, - 0 0 1px hsla(0,0%,100%,.15) inset, - 0 1px 0 hsla(0,0%,100%,.05); - -webkit-transition-property: background-color, border-color, box-shadow; - -webkit-transition-duration: 150ms; - -webkit-transition-timing-function: ease; - -moz-transition-property: background-color, border-color, box-shadow; - -moz-transition-duration: 150ms; - -moz-transition-timing-function: ease; - -ms-transition-property: background-color, border-color, box-shadow; - -ms-transition-duration: 150ms; - -ms-transition-timing-function: ease; - -o-transition-property: background-color, border-color, box-shadow; - -o-transition-duration: 150ms; - -o-transition-timing-function: ease; - transition-property: background-color, border-color, box-shadow; - transition-duration: 150ms; - transition-timing-function: ease; - -} -.splitToolbarButton > .toolbarButton:hover, -.splitToolbarButton > .toolbarButton:focus, -.dropdownToolbarButton:hover, -.toolbarButton.textButton:hover, -.toolbarButton.textButton:focus { - background-color: hsla(0,0%,0%,.2); - box-shadow: 0 1px 0 hsla(0,0%,100%,.05) inset, - 0 0 1px hsla(0,0%,100%,.15) inset, - 0 0 1px hsla(0,0%,0%,.05); - z-index: 199; -} -html[dir='ltr'] .splitToolbarButton > .toolbarButton:first-child, -html[dir='rtl'] .splitToolbarButton > .toolbarButton:last-child { - position: relative; - margin: 0; - margin-right: -1px; - border-top-left-radius: 2px; - border-bottom-left-radius: 2px; - border-right-color: transparent; -} -html[dir='ltr'] .splitToolbarButton > .toolbarButton:last-child, -html[dir='rtl'] .splitToolbarButton > .toolbarButton:first-child { - position: relative; - margin: 0; - margin-left: -1px; - border-top-right-radius: 2px; - border-bottom-right-radius: 2px; - border-left-color: transparent; -} -.splitToolbarButtonSeparator { - padding: 8px 0; - width: 1px; - background-color: hsla(0,0%,00%,.5); - z-index: 99; - box-shadow: 0 0 0 1px hsla(0,0%,100%,.08); - display: inline-block; - margin: 5px 0; -} -html[dir='ltr'] .splitToolbarButtonSeparator { - float: left; -} -html[dir='rtl'] .splitToolbarButtonSeparator { - float: right; -} -.splitToolbarButton:hover > .splitToolbarButtonSeparator, -.splitToolbarButton.toggled > .splitToolbarButtonSeparator { - padding: 12px 0; - margin: 1px 0; - box-shadow: 0 0 0 1px hsla(0,0%,100%,.03); - -webkit-transition-property: padding; - -webkit-transition-duration: 10ms; - -webkit-transition-timing-function: ease; - -moz-transition-property: padding; - -moz-transition-duration: 10ms; - -moz-transition-timing-function: ease; - -ms-transition-property: padding; - -ms-transition-duration: 10ms; - -ms-transition-timing-function: ease; - -o-transition-property: padding; - -o-transition-duration: 10ms; - -o-transition-timing-function: ease; - transition-property: padding; - transition-duration: 10ms; - transition-timing-function: ease; -} - -.toolbarButton, -.dropdownToolbarButton { - min-width: 16px; - padding: 2px 6px 0; - border: 1px solid transparent; - border-radius: 2px; - color: hsl(0,0%,95%); - font-size: 12px; - line-height: 14px; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - /* Opera does not support user-select, use <... unselectable="on"> instead */ - cursor: default; - -webkit-transition-property: background-color, border-color, box-shadow; - -webkit-transition-duration: 150ms; - -webkit-transition-timing-function: ease; - -moz-transition-property: background-color, border-color, box-shadow; - -moz-transition-duration: 150ms; - -moz-transition-timing-function: ease; - -ms-transition-property: background-color, border-color, box-shadow; - -ms-transition-duration: 150ms; - -ms-transition-timing-function: ease; - -o-transition-property: background-color, border-color, box-shadow; - -o-transition-duration: 150ms; - -o-transition-timing-function: ease; - transition-property: background-color, border-color, box-shadow; - transition-duration: 150ms; - transition-timing-function: ease; -} - -html[dir='ltr'] .toolbarButton, -html[dir='ltr'] .dropdownToolbarButton { - margin: 3px 2px 4px 0; -} -html[dir='rtl'] .toolbarButton, -html[dir='rtl'] .dropdownToolbarButton { - margin: 3px 0 4px 2px; -} - -.toolbarButton:hover, -.toolbarButton:focus, -.dropdownToolbarButton { - background-color: hsla(0,0%,0%,.12); - background-image: -webkit-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-image: -moz-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-image: -ms-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-image: -o-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-image: linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-clip: padding-box; - border: 1px solid hsla(0,0%,0%,.35); - border-color: hsla(0,0%,0%,.32) hsla(0,0%,0%,.38) hsla(0,0%,0%,.42); - box-shadow: 0 1px 0 hsla(0,0%,100%,.05) inset, - 0 0 1px hsla(0,0%,100%,.15) inset, - 0 1px 0 hsla(0,0%,100%,.05); -} - -.toolbarButton:hover:active, -.dropdownToolbarButton:hover:active { - background-color: hsla(0,0%,0%,.2); - background-image: -webkit-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-image: -moz-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-image: -ms-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-image: -o-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-image: linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - border-color: hsla(0,0%,0%,.35) hsla(0,0%,0%,.4) hsla(0,0%,0%,.45); - box-shadow: 0 1px 1px hsla(0,0%,0%,.1) inset, - 0 0 1px hsla(0,0%,0%,.2) inset, - 0 1px 0 hsla(0,0%,100%,.05); - -webkit-transition-property: background-color, border-color, box-shadow; - -webkit-transition-duration: 10ms; - -webkit-transition-timing-function: linear; - -moz-transition-property: background-color, border-color, box-shadow; - -moz-transition-duration: 10ms; - -moz-transition-timing-function: linear; - -ms-transition-property: background-color, border-color, box-shadow; - -ms-transition-duration: 10ms; - -ms-transition-timing-function: linear; - -o-transition-property: background-color, border-color, box-shadow; - -o-transition-duration: 10ms; - -o-transition-timing-function: linear; - transition-property: background-color, border-color, box-shadow; - transition-duration: 10ms; - transition-timing-function: linear; -} - -.toolbarButton.toggled, -.splitToolbarButton.toggled > .toolbarButton.toggled { - background-color: hsla(0,0%,0%,.3); - background-image: -webkit-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-image: -moz-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-image: -ms-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-image: -o-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-image: linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - border-color: hsla(0,0%,0%,.4) hsla(0,0%,0%,.45) hsla(0,0%,0%,.5); - box-shadow: 0 1px 1px hsla(0,0%,0%,.1) inset, - 0 0 1px hsla(0,0%,0%,.2) inset, - 0 1px 0 hsla(0,0%,100%,.05); - -webkit-transition-property: background-color, border-color, box-shadow; - -webkit-transition-duration: 10ms; - -webkit-transition-timing-function: linear; - -moz-transition-property: background-color, border-color, box-shadow; - -moz-transition-duration: 10ms; - -moz-transition-timing-function: linear; - -ms-transition-property: background-color, border-color, box-shadow; - -ms-transition-duration: 10ms; - -ms-transition-timing-function: linear; - -o-transition-property: background-color, border-color, box-shadow; - -o-transition-duration: 10ms; - -o-transition-timing-function: linear; - transition-property: background-color, border-color, box-shadow; - transition-duration: 10ms; - transition-timing-function: linear; -} - -.toolbarButton.toggled:hover:active, -.splitToolbarButton.toggled > .toolbarButton.toggled:hover:active { - background-color: hsla(0,0%,0%,.4); - border-color: hsla(0,0%,0%,.4) hsla(0,0%,0%,.5) hsla(0,0%,0%,.55); - box-shadow: 0 1px 1px hsla(0,0%,0%,.2) inset, - 0 0 1px hsla(0,0%,0%,.3) inset, - 0 1px 0 hsla(0,0%,100%,.05); -} - -.dropdownToolbarButton { - width: 120px; - max-width: 120px; - padding: 3px 2px 2px; - overflow: hidden; - background: url(../extlib/pdf.js/web/images/toolbarButton-menuArrows.png) no-repeat; -} -html[dir='ltr'] .dropdownToolbarButton { - background-position: 95%; -} -html[dir='rtl'] .dropdownToolbarButton { - background-position: 5%; -} - -.dropdownToolbarButton > select { - -webkit-appearance: none; - -moz-appearance: none; /* in the future this might matter, see bugzilla bug #649849 */ - min-width: 140px; - font-size: 12px; - color: hsl(0,0%,95%); - margin: 0; - padding: 0; - border: none; - background: rgba(0,0,0,0); /* Opera does not support 'transparent'