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'
diff --git a/mediagoblin/templates/mediagoblin/edit/verification.txt b/mediagoblin/templates/mediagoblin/edit/verification.txt
new file mode 100644
index 00000000..d53cd5e8
--- /dev/null
+++ b/mediagoblin/templates/mediagoblin/edit/verification.txt
@@ -0,0 +1,29 @@
+{#
+# 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 .
+-#}
+
+{% trans username=username, verification_url=verification_url|safe -%}
+Hi,
+
+We wanted to verify that you are {{ username }}. If this is the case, then
+please follow the link below to verify your new email address.
+
+{{ verification_url }}
+
+If you are not {{ username }} or didn't request an email change, you can ignore
+this email.
+{%- endtrans %}
diff --git a/mediagoblin/templates/mediagoblin/fragments/header_notifications.html b/mediagoblin/templates/mediagoblin/fragments/header_notifications.html
new file mode 100644
index 00000000..613100aa
--- /dev/null
+++ b/mediagoblin/templates/mediagoblin/fragments/header_notifications.html
@@ -0,0 +1,40 @@
+{% set notifications = request.notifications.get_notifications(request.user.id) %}
+{% if notifications %}
+
+
{% trans %}New comments{% endtrans %}
+
+ {% for notification in notifications %}
+ {% set comment = notification.subject %}
+ {% set comment_author = comment.get_author %}
+ {% set media = comment.get_entry %}
+