aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rwxr-xr-xdevtools/update_translations.sh3
-rw-r--r--docs/source/_static/goblin.png (renamed from docs/source/goblin.png)bin47763 -> 47763 bytes
-rw-r--r--docs/source/_static/snugglygoblin.png (renamed from docs/source/snugglygoblin.png)bin163754 -> 163754 bytes
-rw-r--r--docs/source/conf.py4
-rw-r--r--docs/source/index.rst55
-rw-r--r--docs/source/pluginwriter/foreward.rst43
-rw-r--r--docs/source/pluginwriter/quickstart.rst189
-rw-r--r--docs/source/siteadmin/about.rst (renamed from docs/source/about.rst)23
-rw-r--r--docs/source/siteadmin/codebase.rst (renamed from docs/source/codebase.rst)15
-rw-r--r--docs/source/siteadmin/configuration.rst (renamed from docs/source/configuration.rst)0
-rw-r--r--docs/source/siteadmin/deploying.rst (renamed from docs/source/deploying.rst)112
-rw-r--r--docs/source/siteadmin/foreword.rst (renamed from docs/source/foreword.rst)14
-rw-r--r--docs/source/siteadmin/help.rst (renamed from docs/source/help.rst)0
-rw-r--r--docs/source/siteadmin/media-types.rst (renamed from docs/source/media-types.rst)30
-rw-r--r--docs/source/siteadmin/plugins.rst137
-rw-r--r--docs/source/siteadmin/production-deployments.rst (renamed from docs/source/production-deployments.rst)18
-rw-r--r--docs/source/siteadmin/relnotes.rst52
-rw-r--r--docs/source/siteadmin/theming.rst (renamed from docs/source/theming.rst)0
-rw-r--r--extlib/freesound/audioprocessing.py616
-rw-r--r--extlib/html5slider/html5slider.js268
l---------lazycelery.sh1
l---------[-rwxr-xr-x]lazyserver.sh65
-rwxr-xr-xlazystarter.sh82
-rw-r--r--mediagoblin.ini5
-rw-r--r--mediagoblin/_version.py2
-rw-r--r--mediagoblin/app.py36
-rw-r--r--mediagoblin/auth/forms.py4
-rw-r--r--mediagoblin/auth/lib.py1
-rw-r--r--mediagoblin/auth/views.py3
-rw-r--r--mediagoblin/config_spec.ini32
-rw-r--r--mediagoblin/db/mixin.py11
-rw-r--r--mediagoblin/db/mongo/migrations.py30
-rw-r--r--mediagoblin/db/mongo/open.py4
-rw-r--r--mediagoblin/db/open.py6
-rw-r--r--mediagoblin/db/sql/convert.py131
-rw-r--r--mediagoblin/db/sql/extratypes.py4
-rw-r--r--mediagoblin/db/sql/migrations.py20
-rw-r--r--mediagoblin/db/sql/models.py16
-rw-r--r--mediagoblin/db/sql/models_v0.py320
-rw-r--r--mediagoblin/db/sql/open.py22
-rw-r--r--mediagoblin/db/sql_switch.py1
-rw-r--r--mediagoblin/edit/forms.py2
-rw-r--r--mediagoblin/edit/views.py7
-rw-r--r--mediagoblin/gmg_commands/__init__.py29
-rw-r--r--mediagoblin/gmg_commands/dbupdate.py11
-rw-r--r--mediagoblin/gmg_commands/import_export.py8
-rw-r--r--mediagoblin/gmg_commands/migrate.py11
-rw-r--r--mediagoblin/gmg_commands/wipealldata.py55
-rw-r--r--mediagoblin/i18n/ar/LC_MESSAGES/mediagoblin.mobin14278 -> 15284 bytes
-rw-r--r--mediagoblin/i18n/ar/LC_MESSAGES/mediagoblin.po268
-rw-r--r--mediagoblin/i18n/ca/LC_MESSAGES/mediagoblin.mobin13279 -> 14290 bytes
-rw-r--r--mediagoblin/i18n/ca/LC_MESSAGES/mediagoblin.po263
-rw-r--r--mediagoblin/i18n/da/LC_MESSAGES/mediagoblin.mobin0 -> 14015 bytes
-rw-r--r--mediagoblin/i18n/da/LC_MESSAGES/mediagoblin.po692
-rw-r--r--mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.mobin14018 -> 14744 bytes
-rw-r--r--mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.po360
-rw-r--r--mediagoblin/i18n/en/LC_MESSAGES/mediagoblin.po208
-rw-r--r--mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.mobin13828 -> 14932 bytes
-rw-r--r--mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.po254
-rw-r--r--mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.mobin14298 -> 15355 bytes
-rw-r--r--mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.po372
-rw-r--r--mediagoblin/i18n/fa/LC_MESSAGES/mediagoblin.mobin0 -> 15047 bytes
-rw-r--r--mediagoblin/i18n/fa/LC_MESSAGES/mediagoblin.po691
-rw-r--r--mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.mobin13938 -> 14988 bytes
-rw-r--r--mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.po324
-rw-r--r--mediagoblin/i18n/ia/LC_MESSAGES/mediagoblin.mobin13043 -> 14054 bytes
-rw-r--r--mediagoblin/i18n/ia/LC_MESSAGES/mediagoblin.po232
-rw-r--r--mediagoblin/i18n/it/LC_MESSAGES/mediagoblin.mobin13456 -> 14673 bytes
-rw-r--r--mediagoblin/i18n/it/LC_MESSAGES/mediagoblin.po360
-rw-r--r--mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.mobin13618 -> 14629 bytes
-rw-r--r--mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.po239
-rw-r--r--mediagoblin/i18n/nl/LC_MESSAGES/mediagoblin.mobin13526 -> 14408 bytes
-rw-r--r--mediagoblin/i18n/nl/LC_MESSAGES/mediagoblin.po344
-rw-r--r--mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.mobin12783 -> 13871 bytes
-rw-r--r--mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.po276
-rw-r--r--mediagoblin/i18n/pl/LC_MESSAGES/mediagoblin.mobin0 -> 14779 bytes
-rw-r--r--mediagoblin/i18n/pl/LC_MESSAGES/mediagoblin.po691
-rw-r--r--mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.mobin13158 -> 14165 bytes
-rw-r--r--mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.po290
-rw-r--r--mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.mobin14058 -> 15204 bytes
-rw-r--r--mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.po349
-rw-r--r--mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.mobin18027 -> 19464 bytes
-rw-r--r--mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.po256
-rw-r--r--mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.mobin14214 -> 15128 bytes
-rw-r--r--mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.po333
-rw-r--r--mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.mobin13232 -> 14243 bytes
-rw-r--r--mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.po260
-rw-r--r--mediagoblin/i18n/sq/LC_MESSAGES/mediagoblin.mobin0 -> 14894 bytes
-rw-r--r--mediagoblin/i18n/sq/LC_MESSAGES/mediagoblin.po680
-rw-r--r--mediagoblin/i18n/sr/LC_MESSAGES/mediagoblin.mobin13141 -> 14156 bytes
-rw-r--r--mediagoblin/i18n/sr/LC_MESSAGES/mediagoblin.po234
-rw-r--r--mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.mobin13361 -> 14377 bytes
-rw-r--r--mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.po292
-rw-r--r--mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.mobin13291 -> 14302 bytes
-rw-r--r--mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.po232
-rw-r--r--mediagoblin/i18n/zh_TW.Big5/LC_MESSAGES/mediagoblin.mobin0 -> 13949 bytes
-rw-r--r--mediagoblin/i18n/zh_TW.Big5/LC_MESSAGES/mediagoblin.po679
-rw-r--r--mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.mobin13179 -> 14019 bytes
-rw-r--r--mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.po291
-rw-r--r--mediagoblin/init/__init__.py5
-rw-r--r--mediagoblin/init/celery/__init__.py57
-rw-r--r--mediagoblin/init/celery/from_celery.py8
-rw-r--r--mediagoblin/init/plugins/__init__.py59
-rw-r--r--mediagoblin/listings/views.py4
-rw-r--r--mediagoblin/meddleware/csrf.py8
-rw-r--r--mediagoblin/media_types/__init__.py60
-rw-r--r--mediagoblin/media_types/ascii/__init__.py4
-rw-r--r--mediagoblin/media_types/ascii/asciitoimage.py26
-rw-r--r--mediagoblin/media_types/ascii/models.py14
-rw-r--r--mediagoblin/media_types/ascii/processing.py36
-rw-r--r--mediagoblin/media_types/audio/__init__.py25
l---------mediagoblin/media_types/audio/audioprocessing.py1
-rw-r--r--mediagoblin/media_types/audio/migrations.py17
-rw-r--r--mediagoblin/media_types/audio/models.py36
-rw-r--r--mediagoblin/media_types/audio/processing.py145
-rw-r--r--mediagoblin/media_types/audio/transcoders.py237
-rw-r--r--mediagoblin/media_types/image/__init__.py4
-rw-r--r--mediagoblin/media_types/image/models.py25
-rw-r--r--mediagoblin/media_types/image/processing.py146
-rw-r--r--mediagoblin/media_types/video/__init__.py12
-rw-r--r--mediagoblin/media_types/video/models.py6
-rw-r--r--mediagoblin/media_types/video/processing.py53
-rw-r--r--mediagoblin/media_types/video/transcoders.py200
-rw-r--r--mediagoblin/plugins/README6
-rw-r--r--mediagoblin/plugins/__init__.py16
-rw-r--r--mediagoblin/plugins/sampleplugin/README6
-rw-r--r--mediagoblin/plugins/sampleplugin/__init__.py (renamed from mediagoblin/submit/security.py)12
-rw-r--r--mediagoblin/plugins/sampleplugin/main.py42
-rw-r--r--mediagoblin/processing/__init__.py (renamed from mediagoblin/processing.py)79
-rw-r--r--mediagoblin/processing/task.py78
-rw-r--r--mediagoblin/static/css/audio.css84
-rw-r--r--mediagoblin/static/css/base.css92
-rw-r--r--mediagoblin/static/css/vjs-mg-skin.css415
-rw-r--r--mediagoblin/static/images/video-js.pngbin0 -> 4459 bytes
-rw-r--r--mediagoblin/static/js/audio.js229
-rw-r--r--mediagoblin/static/js/autofilledin_password.js25
l---------mediagoblin/static/js/extlib/html5slider.js1
-rw-r--r--mediagoblin/static/js/geolocation-map.js5
-rw-r--r--mediagoblin/static/js/header_dropdown.js30
-rw-r--r--mediagoblin/static/js/keyboard_navigation.js10
-rw-r--r--mediagoblin/static/js/show_password.js1
-rw-r--r--mediagoblin/storage/__init__.py2
-rw-r--r--mediagoblin/storage/cloudfiles.py9
-rw-r--r--mediagoblin/storage/mountstorage.py6
-rw-r--r--mediagoblin/submit/views.py24
-rw-r--r--mediagoblin/templates/mediagoblin/auth/login.html7
-rw-r--r--mediagoblin/templates/mediagoblin/base.html69
-rw-r--r--mediagoblin/templates/mediagoblin/media_displays/audio.html65
-rw-r--r--mediagoblin/templates/mediagoblin/media_displays/video.html4
-rw-r--r--mediagoblin/templates/mediagoblin/user_pages/media.html25
-rw-r--r--mediagoblin/templates/mediagoblin/utils/exif.html7
-rw-r--r--mediagoblin/templates/mediagoblin/utils/wtforms.html2
-rw-r--r--mediagoblin/tests/__init__.py14
-rw-r--r--mediagoblin/tests/test_auth.py1
-rw-r--r--mediagoblin/tests/test_celery_setup.py2
-rw-r--r--mediagoblin/tests/test_csrf_middleware.py5
-rw-r--r--mediagoblin/tests/test_mgoblin_app.ini6
-rw-r--r--mediagoblin/tests/test_migrations.py401
-rw-r--r--mediagoblin/tests/test_pluginapi.py158
-rw-r--r--mediagoblin/tests/test_processing.py20
-rw-r--r--mediagoblin/tests/test_submission.py359
-rw-r--r--mediagoblin/tests/test_submission/bigblue.pngbin0 -> 3142 bytes
-rw-r--r--mediagoblin/tests/test_tags.py1
-rw-r--r--mediagoblin/tests/test_workbench.py1
-rw-r--r--mediagoblin/tests/tools.py33
-rw-r--r--mediagoblin/tools/exif.py7
-rw-r--r--mediagoblin/tools/pluginapi.py147
-rw-r--r--mediagoblin/user_pages/views.py2
-rw-r--r--setup.py3
170 files changed, 11510 insertions, 4158 deletions
diff --git a/.gitignore b/.gitignore
index a15a5697..6875d78a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,7 +20,6 @@
/celery.db
/kombu.db
/server-log.txt
-/mediagoblin/db/sql_switch.py
# Tests
/mediagoblin/tests/user_dev/
diff --git a/devtools/update_translations.sh b/devtools/update_translations.sh
index 7fcb3d49..29743f94 100755
--- a/devtools/update_translations.sh
+++ b/devtools/update_translations.sh
@@ -38,6 +38,9 @@ echo "==> Extracting translations"
echo "==> Pushing extracted translations to Transifex"
./bin/tx push -s
+echo "==> Waiting 5 seconds, so the server can process the new stuff (hopefully)"
+sleep 5
+
# gets the new strings added to all files
echo "==> Re-Pulling translations from Transifex"
./bin/tx pull -a
diff --git a/docs/source/goblin.png b/docs/source/_static/goblin.png
index e20265e6..e20265e6 100644
--- a/docs/source/goblin.png
+++ b/docs/source/_static/goblin.png
Binary files differ
diff --git a/docs/source/snugglygoblin.png b/docs/source/_static/snugglygoblin.png
index f325ae4b..f325ae4b 100644
--- a/docs/source/snugglygoblin.png
+++ b/docs/source/_static/snugglygoblin.png
Binary files differ
diff --git a/docs/source/conf.py b/docs/source/conf.py
index aafcf128..41cf2529 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -48,9 +48,9 @@ copyright = u'2011, 2012 GNU MediaGoblin contributors'
# built documents.
#
# The short X.Y version.
-version = '0.3.0'
+version = '0.3.1'
# The full version, including alpha/beta/rc tags.
-release = '0.3.0-dev'
+release = '0.3.1.dev'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
diff --git a/docs/source/index.rst b/docs/source/index.rst
index 444ed688..569eda14 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -11,28 +11,52 @@
Dedication along with this software. If not, see
<http://creativecommons.org/publicdomain/zero/1.0/>.
-.. GNU MediaGoblin documentation master file, created by
- sphinx-quickstart on Thu Apr 7 20:10:27 2011.
- You can adapt this file completely to your liking, but it should at least
- contain the root `toctree` directive.
+===========================================
Welcome to GNU MediaGoblin's documentation!
===========================================
-Table of Contents:
+GNU MediaGoblin is a platform for sharing photos, video and other media
+in an environment that respects our freedom and independence.
+
+This is a Free Software project. It is built by contributors for all
+to use and enjoy. If you're intrested in contributing, see `the wiki
+<http://wiki.mediagoblin.org/>`_ which has pages that talk about the
+ways someone can contribute.
+
+
+Part 1: Site Administrator's Guide
+==================================
+
+This guide covers installing, configuring, deploying and running a GNU
+MediaGoblin website. It is written for site administrators.
+
+.. toctree::
+ :maxdepth: 1
+
+ siteadmin/foreword
+ siteadmin/about
+ siteadmin/deploying
+ siteadmin/production-deployments
+ siteadmin/configuration
+ siteadmin/media-types
+ siteadmin/help
+ siteadmin/relnotes
+ siteadmin/theming
+ siteadmin/plugins
+ siteadmin/codebase
+
+
+Part 2: Plugin Writer's Guide
+=============================
+
+This guide covers writing new GNU MediaGoblin plugins.
.. toctree::
- :maxdepth: 2
+ :maxdepth: 1
- foreword
- about
- deploying
- production-deployments
- configuration
- media-types
- help
- theming
- codebase
+ pluginwriter/foreward
+ pluginwriter/quickstart
Indices and tables
@@ -43,3 +67,4 @@ Indices and tables
.. * :ref:`modindex`
+This guide was built on |today|.
diff --git a/docs/source/pluginwriter/foreward.rst b/docs/source/pluginwriter/foreward.rst
new file mode 100644
index 00000000..fd3a0c22
--- /dev/null
+++ b/docs/source/pluginwriter/foreward.rst
@@ -0,0 +1,43 @@
+.. MediaGoblin Documentation
+
+ Written in 2011, 2012 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
+ <http://creativecommons.org/publicdomain/zero/1.0/>.
+
+========
+Foreword
+========
+
+About the Plugin Writer's Guide
+===============================
+
+This guide covers writing plugins for GNU MediaGoblin. It's very much
+a work in progress partially because we just started writing it and
+partially because the plugin API is currently in flux.
+
+
+Improving the Plugin Writer's Guide
+===================================
+
+There are a few ways---please pick whichever method is convenient for
+you!
+
+1. Write up a bug report in the bug tracker
+2. Tell someone on IRC ``#mediagoblin`` on Freenode.
+3. Write an email to the devel mailing list.
+
+Information about the bugtracker, IRC and the mailing list is all on
+the `join page`_.
+
+.. _join page: http://mediagoblin.org/join/
+
+Patches are the most helpful, but even feedback on what you think
+could be improved and how to improve it is also helpful.
+
diff --git a/docs/source/pluginwriter/quickstart.rst b/docs/source/pluginwriter/quickstart.rst
new file mode 100644
index 00000000..73531381
--- /dev/null
+++ b/docs/source/pluginwriter/quickstart.rst
@@ -0,0 +1,189 @@
+.. MediaGoblin Documentation
+
+ Written in 2011, 2012 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
+ <http://creativecommons.org/publicdomain/zero/1.0/>.
+
+
+===========
+Quick Start
+===========
+
+This is a quick start. It's not comprehensive, but it walks through
+writing a basic plugin called "sampleplugin" which logs "I've been
+started!" when ``setup_plugin()`` has been called.
+
+.. todo: Rewrite this to be a useful plugin
+
+
+Step 1: Files and directories
+=============================
+
+GNU MediaGoblin plugins are Python projects at heart. As such, you should
+use a standard Python project directory tree::
+
+ sampleplugin/
+ |- README
+ |- LICENSE
+ |- setup.py
+ |- sampleplugin/
+ |- __init__.py
+
+
+The outer ``sampleplugin`` directory holds all the project files.
+
+The ``README`` should cover what your plugin does, how to install it,
+how to configure it, and all the sorts of things a README should
+cover.
+
+The ``LICENSE`` should have the license under which you're
+distributing your plugin.
+
+The inner ``sampleplugin`` directory is the Python package that holds
+your plugin's code.
+
+The ``__init__.py`` denotes that this is a Python package. It also
+holds the plugin code.
+
+
+Step 2: README
+==============
+
+Here's a rough ``README``. Generally, you want more information
+because this is the file that most people open when they want to learn
+more about your project.
+
+::
+
+ README
+ ======
+
+ This is a sample plugin. It logs a line when ``setup__plugin()`` is
+ run.
+
+
+Step 3: LICENSE
+===============
+
+GNU MediaGoblin plugins must be licensed under the AGPLv3 or later. So
+the LICENSE file should be the AGPLv3 text which you can find at
+`<http://www.gnu.org/licenses/agpl-3.0.html>`_
+
+
+Step 4: setup.py
+================
+
+This file is used for packaging and distributing your plugin.
+
+We'll use a basic one::
+
+ from setuptools import setup, find_packages
+
+ setup(
+ name='sampleplugin',
+ version='1.0',
+ packages=find_packages(),
+ include_package_data=True,
+ install_requires=[],
+ license='AGPLv3',
+ )
+
+
+See `<http://docs.python.org/distutils/index.html#distutils-index>`_
+for more details.
+
+
+Step 5: the code
+================
+
+The code for ``__init__.py`` looks like this:
+
+.. code-block:: python
+ :linenos:
+ :emphasize-lines: 8,19
+
+ import logging
+ from mediagoblin.tools.pluginapi import Plugin, get_config
+
+
+ _log = logging.getLogger(__name__)
+
+
+ class SamplePlugin(Plugin):
+ """
+ This is a sample plugin class. It automatically registers itself
+ with MediaGoblin when this module is imported.
+
+ The setup_plugin method prints configuration for this plugin if
+ there is any.
+ """
+ def __init__(self):
+ pass
+
+ def setup_plugin(self):
+ _log.info("I've been started!")
+ config = get_config('sampleplugin')
+ if config:
+ _log.info('%r' % config)
+ else:
+ _log.info('There is no configuration set.')
+
+
+Line 8 defines a class called ``SamplePlugin`` that subclasses
+``Plugin`` from ``mediagoblin.tools.pluginapi``. When the class is
+defined, it gets registered with MediaGoblin and MediaGoblin will then
+call ``setup_plugin`` on it.
+
+Line 19 defines ``setup_plugin``. This gets called when MediaGoblin
+starts up after it's registered all the plugins. This is where you can
+do any initialization for your plugin.
+
+
+Step 6: Installation and configuration
+======================================
+
+To install the plugin for development, you need to make sure it's
+available to the Python interpreter that's running MediaGoblin.
+
+There are a couple of ways to do this, but we're going to pick the
+easy one.
+
+Use ``python`` from your MediaGoblin virtual environment and do::
+
+ python setup.py develop
+
+Any changes you make to your plugin will be available in your
+MediaGoblin virtual environment.
+
+Then adjust your ``mediagoblin.ini`` file to load the plugin::
+
+ [plugins]
+
+ [[sampleplugin]]
+
+
+Step 7: That's it!
+==================
+
+When you launch MediaGoblin, it'll load the plugin and you'll see
+evidence of that in the log file.
+
+That's it for the quick start!
+
+
+Where to go from here
+=====================
+
+See the documentation on the plugin API for code samples and other
+things you can use when building your plugin.
+
+See `Hitchhiker's Guide to Packaging
+<http://guide.python-distribute.org/>`_ for more information on
+packaging your plugin.
diff --git a/docs/source/about.rst b/docs/source/siteadmin/about.rst
index 7a6aa510..f9602397 100644
--- a/docs/source/about.rst
+++ b/docs/source/siteadmin/about.rst
@@ -19,8 +19,8 @@
:local:
-What is GNU MediaGoblin
-=======================
+What is GNU MediaGoblin?
+========================
In 2008, a number of free software developers and activists gathered
at the FSF to attempt to answer the question "What should software
@@ -36,15 +36,16 @@ freedom look like on the participatory web?" Their answer, the
Identi.ca and Libre.fm address the need for micro-blogging and music
sharing services and software that respect users' freedom and
-autonomy. GNU MediaGoblin emerges from this milieu to create a
-platform for us to share photos in an environment that respects our
-freedom and independence. In the future MediaGoblin will include
-support other media, like video, and provide tools to facilitate
+autonomy.
+
+GNU MediaGoblin emerges from this milieu to create a platform for us to share
+photos, video and other media in an environment that respects our freedom and
+independence. In the future MediaGoblin will provide tools to facilitate
collaboration on media projects.
-Why Build GNU MediaGoblin
-=========================
+Why Build GNU MediaGoblin?
+==========================
The Internet is designed---and works best---as a complex and endlessly
resilient network. When key services and media outlets are
@@ -62,8 +63,8 @@ make these kinds of services possible. We hope you'll join us, both
as users and as contributors.
-Who Contributes to the Project
-==============================
+Who Contributes to the Project?
+===============================
You do!
@@ -89,7 +90,7 @@ GNU MediaGoblin software is released under an AGPLv3 license.
See the ``COPYING`` file in the root of the source for details.
-Is MedaGobilin an official GNU project? What does that mean?
+Is MediaGoblin an official GNU project? What does that mean?
=============================================================
MediaGoblin is an official GNU project! This status means that we the
diff --git a/docs/source/codebase.rst b/docs/source/siteadmin/codebase.rst
index e784c9e5..3ef91290 100644
--- a/docs/source/codebase.rst
+++ b/docs/source/siteadmin/codebase.rst
@@ -55,8 +55,9 @@ Software Stack
* Data storage
- * `MongoDB <http://www.mongodb.org/>`_: the document database backend
- for storage
+ * `SQLAlchemy <http://sqlalchemy.org/>`_: SQL ORM and database
+ interaction library for Python. Currently we support sqlite and
+ postgress as backends.
* Web application
@@ -80,14 +81,6 @@ Software Stack
* `Celery <http://celeryproject.org/>`_: for task queuing (resizing
images, encoding video, ...)
- * `MongoKit <http://namlook.github.com/mongokit/>`_: the lightweight
- ORM for MongoDB we're using which will make it easier to define
- structures and all that (will be swapped out soon...)
-
- * `SQLAlchemy <http://sqlalchemy.org/>`_: SQL ORM and database
- interaction library for Python. We'll be moving to this in the
- upcoming move to SQL.
-
* `Babel <http://babel.edgewall.org>`_: Used to extract and compile
translations.
@@ -151,7 +144,7 @@ Here are some interesting files and what they do:
:routing.py: maps url paths to views
:views.py: views handle http requests
-:models.py: holds the mongodb schemas---these are the data structures
+:models.py: holds the sqlalchemy schemas---these are the data structures
we're working with
You'll notice that there are several sub-directories: tests,
diff --git a/docs/source/configuration.rst b/docs/source/siteadmin/configuration.rst
index a3dafa4c..a3dafa4c 100644
--- a/docs/source/configuration.rst
+++ b/docs/source/siteadmin/configuration.rst
diff --git a/docs/source/deploying.rst b/docs/source/siteadmin/deploying.rst
index ce39dc4e..788b06d7 100644
--- a/docs/source/deploying.rst
+++ b/docs/source/siteadmin/deploying.rst
@@ -11,6 +11,8 @@
Dedication along with this software. If not, see
<http://creativecommons.org/publicdomain/zero/1.0/>.
+.. _deploying-chapter:
+
=====================
Deploying MediaGoblin
=====================
@@ -41,49 +43,75 @@ MediaGoblin has the following core dependencies:
- Python 2.6 or 2.7
- `python-lxml <http://lxml.de/>`_
- `git <http://git-scm.com/>`_
-- `MongoDB <http://www.mongodb.org/>`_
+- `SQLite <http://www.sqlite.org/>`_/`PostgreSQL <http://www.postgresql.org/>`_
- `Python Imaging Library <http://www.pythonware.com/products/pil/>`_ (PIL)
- `virtualenv <http://www.virtualenv.org/>`_
On a DEB-based system (e.g Debian, gNewSense, Trisquel, Ubuntu, and
-derivatives) issue the following command: ::
+derivatives) issue the following command::
- sudo apt-get install mongodb git-core python python-dev python-lxml \
+ sudo apt-get install git-core python python-dev python-lxml \
python-imaging python-virtualenv
On a RPM-based system (e.g. Fedora, RedHat, and derivatives) issue the
-following command: ::
+following command::
- yum install mongodb-server python-paste-deploy python-paste-script \
+ yum install python-paste-deploy python-paste-script \
git-core python python-devel python-lxml python-imaging \
python-virtualenv
-Configure MongoDB
-~~~~~~~~~~~~~~~~~
+Configure PostgreSQL
+~~~~~~~~~~~~~~~~~~~~
+
+.. note::
+
+ MediaGoblin currently supports PostgreSQL and SQLite. The default is a
+ local SQLite database. This will "just work" for small deployments.
+
+ For medium to large deployments we recommend PostgreSQL.
+
+ If you don't want/need postgres, skip this section.
+
+These are the packages needed for Debian Wheezy (testing)::
+
+ sudo apt-get install postgresql postgresql-client python-psycopg2
+
+The installation process will create a new *system* user named ``postgres``,
+it will have privilegies sufficient to manage the database. We will create a
+new database user with restricted privilegies and a new database owned by our
+restricted database user for our MediaGoblin instance.
+
+In this example, the database user will be ``mediagoblin`` and the database
+name will be ``mediagoblin`` too.
+
+To create our new user, run::
+
+ sudo -u postgres createuser mediagoblin
+
+then answer NO to *all* the questions::
+
+ Shall the new role be a superuser? (y/n) n
+ Shall the new role be allowed to create databases? (y/n) n
+ Shall the new role be allowed to create more new roles? (y/n) n
-After installing MongoDB some preliminary database configuration may
-be necessary.
+then create the database all our MediaGoblin data should be stored in::
-Ensure that MongoDB `journaling
-<http://www.mongodb.org/display/DOCS/Journaling>`_ is enabled. Journaling
-is enabled by default in version 2.0 and later 64-bit MongoDB instances.
-Check your deployment, and consider enabling journaling if you're running
-32-bit systems or earlier version.
+ sudo -u postgres createdb -E UNICODE -O mediagoblin mediagoblin
-.. warning::
+where the first ``mediagoblin`` is the database owner and the second
+``mediagoblin`` is the database name.
- Running MongoDB without journaling risks general data corruption
- and raises the possibility of losing data within a 60-second
- window when the server restarts.
+.. caution:: Where is the password?
- MediaGoblin recommends enabling MongoDB's journaling feature by
- adding a ``--journal`` flag to the command line or a "``journal:
- true``" option to the configuration file.
+ These steps enable you to authenticate to the database in a password-less
+ manner via local UNIX authentication provided you run the MediaGoblin
+ application as a user with the same name as the user you created in
+ PostgreSQL.
-MongoDB can take a lot of space by default. If you're planning on
-running a smaller instance, consider the `scaling down guide
-<http://wiki.mediagoblin.org/Scaling_Down>`_ for some appropriate
-tradeoffs to conserve space.
+ More on this in :ref:`Drop Privileges for MediaGoblin <drop-privileges-for-mediagoblin>`.
+
+
+.. _drop-privileges-for-mediagoblin:
Drop Privileges for MediaGoblin
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -101,7 +129,7 @@ assumes your local git repository will be located at
Substitute your prefer ed local deployment path as needed.
This document assumes that all operations are performed as this
-user. To drop privileges to this user, run the following command: ::
+user. To drop privileges to this user, run the following command::
su - [mediagoblin]
@@ -113,7 +141,7 @@ Install MediaGoblin and Virtualenv
.. note::
- As of |version|, MediaGoblin has a rapid development pace. As a result
+ MediaGoblin is still developing rapidly. As a result
the following instructions recommend installing from the ``master``
branch of the git repository. Eventually production deployments will
want to transition to running from more consistent releases.
@@ -128,7 +156,7 @@ Clone the MediaGoblin repository::
git clone git://gitorious.org/mediagoblin/mediagoblin.git
-And setup the in-package virtualenv::
+And set up the in-package virtualenv::
cd mediagoblin
(virtualenv --system-site-packages . || virtualenv .) && ./bin/python setup.py develop
@@ -153,14 +181,36 @@ flup::
./bin/easy_install flup
This concludes the initial configuration of the development
-environment. In the future, if at any point you want update your
+environment. In the future, you want update your
codebase, you should also run::
- ./bin/python setup.py develop --upgrade && ./bin/gmg migrate.
+ ./bin/python setup.py develop --upgrade && ./bin/gmg dbupdate
Deploy MediaGoblin Services
---------------------------
+Configure MediaGoblin to use the PostgreSQL database
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you are using postgres, edit the ``[mediagoblin]`` section in your
+``mediagoblin_local.ini`` and put in::
+
+ sql_engine = postgresql:///mediagoblin
+
+if you are running the MediaGoblin application as the same 'user' as the
+database owner.
+
+
+Update database data structures
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Before you start using the database, you need to run::
+
+ ./bin/gmg dbupdate
+
+to populate the database with the MediaGoblin data structures.
+
+
Test the Server
~~~~~~~~~~~~~~~
@@ -260,7 +310,7 @@ example::
./lazyserver.sh --server-name=fcgi fcgi_host=127.0.0.1 fcgi_port=26543
Visit the site you've set up in your browser by visiting
-<http://mediagobilin.example.org>. You should see MediaGoblin!
+<http://mediagoblin.example.org>. You should see MediaGoblin!
.. note::
diff --git a/docs/source/foreword.rst b/docs/source/siteadmin/foreword.rst
index be0c84b8..4c425f8d 100644
--- a/docs/source/foreword.rst
+++ b/docs/source/siteadmin/foreword.rst
@@ -15,12 +15,12 @@
Foreword
========
-About the MediaGoblin Manual
-============================
+About the Site Administrator's Guide
+====================================
-This is the site administrator manual for MediaGoblin. It covers how
-to set up and configure MediaGoblin and the kind of information that
-someone running MediaGoblin would need to know.
+This is the site administrator manual for GNU MediaGoblin. It covers
+how to set up and configure MediaGoblin and the kind of information
+that someone running MediaGoblin would need to know.
We have other documentation at:
@@ -28,8 +28,8 @@ We have other documentation at:
* http://wiki.mediagoblin.org/ for our contributor/developer-focused wiki
-Improving the MediaGobiin Manual
-================================
+Improving the Site Administrator's Guide
+========================================
There are a few ways---please pick whichever method is convenient for
you!
diff --git a/docs/source/help.rst b/docs/source/siteadmin/help.rst
index 4b584ac1..4b584ac1 100644
--- a/docs/source/help.rst
+++ b/docs/source/siteadmin/help.rst
diff --git a/docs/source/media-types.rst b/docs/source/siteadmin/media-types.rst
index ec068422..1cf7f30c 100644
--- a/docs/source/media-types.rst
+++ b/docs/source/siteadmin/media-types.rst
@@ -18,7 +18,8 @@ Enabling Media Types
====================
In the future, there will be all sorts of media types you can enable,
-but in the meanwhile there's only one additional media type: video.
+but in the meanwhile there are two additional media type: video and
+ascii art.
First, you should probably read ":doc:`configuration`" to make sure
you know how to modify the mediagoblin config file.
@@ -30,21 +31,27 @@ To enable video, first install gstreamer and the python-gstreamer
bindings (as well as whatever gstremaer extensions you want,
good/bad/ugly). On Debianoid systems::
- sudo apt-get install python-gst0.10
+ sudo apt-get install python-gst0.10 gstreamer0.10-plugins-{base,bad,good,ugly} \
+ gstreamer0.10-ffmpeg
Next, modify (and possibly copy over from ``mediagoblin.ini``) your
-``mediagoblin_local.ini``. Uncomment this line in the ``[mediagoblin]``
-section::
+``mediagoblin_local.ini``. In the ``[mediagoblin]`` section, add
+``mediagoblin.media_types.video`` to the ``media_types`` list.
+
+For example, if your system supported image and video media types, then
+the list would look like this::
media_types = mediagoblin.media_types.image, mediagoblin.media_types.video
Now you should be able to submit videos, and mediagoblin should
transcode them.
-Note that you almost certainly want to separate Celery from the normal
-paste process or your users will probably find that their connections
-time out as the video transcodes. To set that up, check out the
-":doc:`production-deployments`" section of this manual.
+.. note::
+
+ You almost certainly want to separate Celery from the normal
+ paste process or your users will probably find that their connections
+ time out as the video transcodes. To set that up, check out the
+ ":doc:`production-deployments`" section of this manual.
Ascii art
@@ -58,8 +65,11 @@ library, which is necessary for creating thumbnails of ascii art::
Next, modify (and possibly copy over from ``mediagoblin.ini``) your
-``mediagoblin_local.ini``. Uncomment or add to the media_types line
-'mediagoblin.media_types.ascii' like so::
+``mediagoblin_local.ini``. In the ``[mediagoblin]`` section, add
+``mediagoblin.media_types.ascii`` to the ``media_types`` list.
+
+For example, if your system supported image and ascii art media types, then
+the list would look like this::
media_types = mediagoblin.media_types.image, mediagoblin.media_types.ascii
diff --git a/docs/source/siteadmin/plugins.rst b/docs/source/siteadmin/plugins.rst
new file mode 100644
index 00000000..41f2970f
--- /dev/null
+++ b/docs/source/siteadmin/plugins.rst
@@ -0,0 +1,137 @@
+=========
+ Plugins
+=========
+
+GNU MediaGoblin supports plugins that allow you to augment MediaGoblin's
+behavior.
+
+This chapter covers discovering, installing, configuring and removing
+plugins.
+
+
+Discovering plugins
+===================
+
+MediaGoblin comes with core plugins. Core plugins are located in the
+``mediagoblin.plugins`` module of the MediaGoblin code. Because they
+come with MediaGoblin, you don't have to install them, but you do have
+to add them to your config file if you're interested in using them.
+
+You can also write your own plugins and additionally find plugins
+elsewhere on the Internet. Once you find a plugin you like, you need
+to first install it, then add it to your configuration.
+
+.. todo: how do you find plugins on the internet?
+
+
+Installing plugins
+==================
+
+Core plugins
+------------
+
+MediaGoblin core plugins don't need to be installed because they come
+with MediaGoblin. Further, when you upgrade MediaGoblin, you will also
+get updates to the core plugins.
+
+
+Other plugins
+-------------
+
+If the plugin is available on the `Python Package Index
+<http://pypi.python.org/pypi>`_, then you can install the plugin with pip::
+
+ pip install <plugin-name>
+
+For example, if we wanted to install the plugin named
+"mediagoblin-restrictfive", we would do::
+
+ pip install mediagoblin-restrictfive
+
+.. Note::
+
+ If you're using a virtual environment, make sure to activate the
+ virtual environment before installing with pip. Otherwise the
+ plugin may get installed in a different environment than the one
+ MediaGoblin is installed in.
+
+Once you've installed the plugin software, you need to tell
+MediaGoblin that this is a plugin you want MediaGoblin to use. To do
+that, you edit the ``mediagoblin.ini`` file and add the plugin as a
+subsection of the plugin section.
+
+For example, say the "mediagoblin-restrictfive" plugin had the Python
+package path ``restrictfive``, then you would add ``restrictfive`` to
+the ``plugins`` section as a subsection::
+
+ [plugins]
+
+ [[restrictfive]]
+
+
+Configuring plugins
+===================
+
+Configuration for a plugin goes in the subsection for that plugin. Core
+plugins are documented in the administration guide. Other plugins
+should come with documentation that tells you how to configure them.
+
+Example 1: Core MediaGoblin plugin
+
+If you wanted to use the core MediaGoblin flatpages plugin, the module
+for that is ``mediagoblin.plugins.flatpages`` and you would add that
+to your ``.ini`` file like this::
+
+ [plugins]
+
+ [[mediagoblin.plugins.flatpages]]
+ # configuration for flatpages plugin here!
+ directory = /srv/mediagoblin/flatpages
+
+Example 2: Plugin that is not a core MediaGoblin plugin
+
+If you installed a hypothetical restrictfive plugin which is in the
+module ``restrictfive``, your ``.ini`` file might look like this (with
+comments making the bits clearer)::
+
+ [plugins]
+
+ [[restrictfive]]
+ # configuration for restrictfive here!
+
+Check the plugin's documentation for what configuration options are
+available.
+
+
+Removing plugins
+================
+
+To remove a plugin, use ``pip uninstall``. For example::
+
+ pip uninstall mediagoblin-restrictfive
+
+.. Note::
+
+ If you're using a virtual environment, make sure to activate the
+ virtual environment before uninstalling with pip. Otherwise the
+ plugin may get installed in a different environment.
+
+
+Upgrading plugins
+=================
+
+Core plugins
+------------
+
+Core plugins get upgraded automatically when you upgrade MediaGoblin
+because they come with MediaGoblin.
+
+
+Other plugins
+-------------
+
+For plugins that you install with pip, you can upgrade them with pip::
+
+ pip install -U <plugin-name>
+
+The ``-U`` tells pip to upgrade the package.
diff --git a/docs/source/production-deployments.rst b/docs/source/siteadmin/production-deployments.rst
index 1e6631db..356fab7f 100644
--- a/docs/source/production-deployments.rst
+++ b/docs/source/siteadmin/production-deployments.rst
@@ -85,8 +85,22 @@ Use an Init Script
Look in your system's ``/etc/init.d/`` or ``/etc/rc.d/`` directory for
examples of how to build scripts that will start, stop, and restart
MediaGoblin and Celery. These scripts will vary by
-distribution/operating system. In the future, MediaGoblin will provide
-example scripts as examples.
+distribution/operating system.
+
+These are scripts provided by the MediaGoblin community:
+
+Debian
+ * `GNU MediaGoblin init scripts
+ <https://github.com/jwandborg/mediagoblin-init-scripts>`_
+ by `Joar Wandborg <http://wandborg.se>`_
+
+Arch Linux
+ * `MediaGoblin - ArchLinux rc.d scripts
+ <http://whird.jpope.org/2012/04/14/mediagoblin-archlinux-rcd-scripts>`_
+ by `Jeremy Pope <http://jpope.org/>`_
+ * `Mediagoblin init script on Archlinux
+ <http://chimo.chromic.org/2012/03/01/mediagoblin-init-script-on-archlinux/>`_
+ by `Chimo <http://chimo.chromic.org/>`_
.. TODO insert init script here
.. TODO are additional concerns ?
diff --git a/docs/source/siteadmin/relnotes.rst b/docs/source/siteadmin/relnotes.rst
new file mode 100644
index 00000000..2efded73
--- /dev/null
+++ b/docs/source/siteadmin/relnotes.rst
@@ -0,0 +1,52 @@
+.. MediaGoblin Documentation
+
+ Written in 2012 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
+ <http://creativecommons.org/publicdomain/zero/1.0/>.
+
+=============
+Release Notes
+=============
+
+This chapter has important information for releases in it.
+If you're upgrading from a previous release, please read it
+carefully, or at least skim over it.
+
+
+0.3.0
+=====
+
+This release has one important change. You need to act when
+upgrading from a previous version!
+
+This release changes the database system from MongoDB to
+SQL(alchemy). If you want to setup a fresh instance, just
+follow the instructions in the deployment chapter. If on
+the other hand you want to continue to use one instance,
+read on.
+
+To convert your data from MongoDB to SQL(alchemy), you need
+to follow these steps:
+
+1. Make sure your MongoDB is still running and has your
+ data, it's needed for the conversion.
+
+2. Configure the ``sql_engine`` URI in the config to represent
+ your target database (see: :ref:`deploying-chapter`)
+
+3. You need an empty database.
+
+4. Then run the following command::
+
+ bin/gmg [-cf mediagoblin_config.ini] convert_mongo_to_sql
+
+5. Start your server and investigate.
+
+6. That's it.
diff --git a/docs/source/theming.rst b/docs/source/siteadmin/theming.rst
index 7584b688..7584b688 100644
--- a/docs/source/theming.rst
+++ b/docs/source/siteadmin/theming.rst
diff --git a/extlib/freesound/audioprocessing.py b/extlib/freesound/audioprocessing.py
new file mode 100644
index 00000000..c1dfe2eb
--- /dev/null
+++ b/extlib/freesound/audioprocessing.py
@@ -0,0 +1,616 @@
+#!/usr/bin/env python
+# processing.py -- various audio processing functions
+# Copyright (C) 2008 MUSIC TECHNOLOGY GROUP (MTG)
+# UNIVERSITAT POMPEU FABRA
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# Authors:
+# Bram de Jong <bram.dejong at domain.com where domain in gmail>
+# 2012, Joar Wandborg <first name at last name dot se>
+
+import Image, ImageDraw, ImageColor #@UnresolvedImport
+from functools import partial
+import math
+import numpy
+import os
+import re
+import signal
+
+
+def get_sound_type(input_filename):
+ sound_type = os.path.splitext(input_filename.lower())[1].strip(".")
+
+ if sound_type == "fla":
+ sound_type = "flac"
+ elif sound_type == "aif":
+ sound_type = "aiff"
+
+ return sound_type
+
+
+try:
+ import scikits.audiolab as audiolab
+except ImportError:
+ print "WARNING: audiolab is not installed so wav2png will not work"
+import subprocess
+
+class AudioProcessingException(Exception):
+ pass
+
+class TestAudioFile(object):
+ """A class that mimics audiolab.sndfile but generates noise instead of reading
+ a wave file. Additionally it can be told to have a "broken" header and thus crashing
+ in the middle of the file. Also useful for testing ultra-short files of 20 samples."""
+ def __init__(self, num_frames, has_broken_header=False):
+ self.seekpoint = 0
+ self.nframes = num_frames
+ self.samplerate = 44100
+ self.channels = 1
+ self.has_broken_header = has_broken_header
+
+ def seek(self, seekpoint):
+ self.seekpoint = seekpoint
+
+ def read_frames(self, frames_to_read):
+ if self.has_broken_header and self.seekpoint + frames_to_read > self.num_frames / 2:
+ raise RuntimeError()
+
+ num_frames_left = self.num_frames - self.seekpoint
+ will_read = num_frames_left if num_frames_left < frames_to_read else frames_to_read
+ self.seekpoint += will_read
+ return numpy.random.random(will_read)*2 - 1
+
+
+def get_max_level(filename):
+ max_value = 0
+ buffer_size = 4096
+ audio_file = audiolab.Sndfile(filename, 'r')
+ n_samples_left = audio_file.nframes
+
+ while n_samples_left:
+ to_read = min(buffer_size, n_samples_left)
+
+ try:
+ samples = audio_file.read_frames(to_read)
+ except RuntimeError:
+ # this can happen with a broken header
+ break
+
+ # convert to mono by selecting left channel only
+ if audio_file.channels > 1:
+ samples = samples[:,0]
+
+ max_value = max(max_value, numpy.abs(samples).max())
+
+ n_samples_left -= to_read
+
+ audio_file.close()
+
+ return max_value
+
+class AudioProcessor(object):
+ """
+ The audio processor processes chunks of audio an calculates the spectrac centroid and the peak
+ samples in that chunk of audio.
+ """
+ def __init__(self, input_filename, fft_size, window_function=numpy.hanning):
+ max_level = get_max_level(input_filename)
+
+ self.audio_file = audiolab.Sndfile(input_filename, 'r')
+ self.fft_size = fft_size
+ self.window = window_function(self.fft_size)
+ self.spectrum_range = None
+ self.lower = 100
+ self.higher = 22050
+ self.lower_log = math.log10(self.lower)
+ self.higher_log = math.log10(self.higher)
+ self.clip = lambda val, low, high: min(high, max(low, val))
+
+ # figure out what the maximum value is for an FFT doing the FFT of a DC signal
+ fft = numpy.fft.rfft(numpy.ones(fft_size) * self.window)
+ max_fft = (numpy.abs(fft)).max()
+ # set the scale to normalized audio and normalized FFT
+ self.scale = 1.0/max_level/max_fft if max_level > 0 else 1
+
+ def read(self, start, size, resize_if_less=False):
+ """ read size samples starting at start, if resize_if_less is True and less than size
+ samples are read, resize the array to size and fill with zeros """
+
+ # number of zeros to add to start and end of the buffer
+ add_to_start = 0
+ add_to_end = 0
+
+ if start < 0:
+ # the first FFT window starts centered around zero
+ if size + start <= 0:
+ return numpy.zeros(size) if resize_if_less else numpy.array([])
+ else:
+ self.audio_file.seek(0)
+
+ add_to_start = -start # remember: start is negative!
+ to_read = size + start
+
+ if to_read > self.audio_file.nframes:
+ add_to_end = to_read - self.audio_file.nframes
+ to_read = self.audio_file.nframes
+ else:
+ self.audio_file.seek(start)
+
+ to_read = size
+ if start + to_read >= self.audio_file.nframes:
+ to_read = self.audio_file.nframes - start
+ add_to_end = size - to_read
+
+ try:
+ samples = self.audio_file.read_frames(to_read)
+ except RuntimeError:
+ # this can happen for wave files with broken headers...
+ return numpy.zeros(size) if resize_if_less else numpy.zeros(2)
+
+ # convert to mono by selecting left channel only
+ if self.audio_file.channels > 1:
+ samples = samples[:,0]
+
+ if resize_if_less and (add_to_start > 0 or add_to_end > 0):
+ if add_to_start > 0:
+ samples = numpy.concatenate((numpy.zeros(add_to_start), samples), axis=1)
+
+ if add_to_end > 0:
+ samples = numpy.resize(samples, size)
+ samples[size - add_to_end:] = 0
+
+ return samples
+
+
+ def spectral_centroid(self, seek_point, spec_range=110.0):
+ """ starting at seek_point read fft_size samples, and calculate the spectral centroid """
+
+ samples = self.read(seek_point - self.fft_size/2, self.fft_size, True)
+
+ samples *= self.window
+ fft = numpy.fft.rfft(samples)
+ spectrum = self.scale * numpy.abs(fft) # normalized abs(FFT) between 0 and 1
+ length = numpy.float64(spectrum.shape[0])
+
+ # scale the db spectrum from [- spec_range db ... 0 db] > [0..1]
+ db_spectrum = ((20*(numpy.log10(spectrum + 1e-60))).clip(-spec_range, 0.0) + spec_range)/spec_range
+
+ energy = spectrum.sum()
+ spectral_centroid = 0
+
+ if energy > 1e-60:
+ # calculate the spectral centroid
+
+ if self.spectrum_range == None:
+ self.spectrum_range = numpy.arange(length)
+
+ spectral_centroid = (spectrum * self.spectrum_range).sum() / (energy * (length - 1)) * self.audio_file.samplerate * 0.5
+
+ # clip > log10 > scale between 0 and 1
+ spectral_centroid = (math.log10(self.clip(spectral_centroid, self.lower, self.higher)) - self.lower_log) / (self.higher_log - self.lower_log)
+
+ return (spectral_centroid, db_spectrum)
+
+
+ def peaks(self, start_seek, end_seek):
+ """ read all samples between start_seek and end_seek, then find the minimum and maximum peak
+ in that range. Returns that pair in the order they were found. So if min was found first,
+ it returns (min, max) else the other way around. """
+
+ # larger blocksizes are faster but take more mem...
+ # Aha, Watson, a clue, a tradeof!
+ block_size = 4096
+
+ max_index = -1
+ max_value = -1
+ min_index = -1
+ min_value = 1
+
+ if start_seek < 0:
+ start_seek = 0
+
+ if end_seek > self.audio_file.nframes:
+ end_seek = self.audio_file.nframes
+
+ if end_seek <= start_seek:
+ samples = self.read(start_seek, 1)
+ return (samples[0], samples[0])
+
+ if block_size > end_seek - start_seek:
+ block_size = end_seek - start_seek
+
+ for i in range(start_seek, end_seek, block_size):
+ samples = self.read(i, block_size)
+
+ local_max_index = numpy.argmax(samples)
+ local_max_value = samples[local_max_index]
+
+ if local_max_value > max_value:
+ max_value = local_max_value
+ max_index = local_max_index
+
+ local_min_index = numpy.argmin(samples)
+ local_min_value = samples[local_min_index]
+
+ if local_min_value < min_value:
+ min_value = local_min_value
+ min_index = local_min_index
+
+ return (min_value, max_value) if min_index < max_index else (max_value, min_value)
+
+
+def interpolate_colors(colors, flat=False, num_colors=256):
+ """ given a list of colors, create a larger list of colors interpolating
+ the first one. If flatten is True a list of numers will be returned. If
+ False, a list of (r,g,b) tuples. num_colors is the number of colors wanted
+ in the final list """
+
+ palette = []
+
+ for i in range(num_colors):
+ index = (i * (len(colors) - 1))/(num_colors - 1.0)
+ index_int = int(index)
+ alpha = index - float(index_int)
+
+ if alpha > 0:
+ r = (1.0 - alpha) * colors[index_int][0] + alpha * colors[index_int + 1][0]
+ g = (1.0 - alpha) * colors[index_int][1] + alpha * colors[index_int + 1][1]
+ b = (1.0 - alpha) * colors[index_int][2] + alpha * colors[index_int + 1][2]
+ else:
+ r = (1.0 - alpha) * colors[index_int][0]
+ g = (1.0 - alpha) * colors[index_int][1]
+ b = (1.0 - alpha) * colors[index_int][2]
+
+ if flat:
+ palette.extend((int(r), int(g), int(b)))
+ else:
+ palette.append((int(r), int(g), int(b)))
+
+ return palette
+
+
+def desaturate(rgb, amount):
+ """
+ desaturate colors by amount
+ amount == 0, no change
+ amount == 1, grey
+ """
+ luminosity = sum(rgb) / 3.0
+ desat = lambda color: color - amount * (color - luminosity)
+
+ return tuple(map(int, map(desat, rgb)))
+
+
+class WaveformImage(object):
+ """
+ Given peaks and spectral centroids from the AudioProcessor, this class will construct
+ a wavefile image which can be saved as PNG.
+ """
+ def __init__(self, image_width, image_height, palette=1):
+ if image_height % 2 == 0:
+ raise AudioProcessingException, "Height should be uneven: images look much better at uneven height"
+
+ if palette == 1:
+ background_color = (0,0,0)
+ colors = [
+ (50,0,200),
+ (0,220,80),
+ (255,224,0),
+ (255,70,0),
+ ]
+ elif palette == 2:
+ background_color = (0,0,0)
+ colors = [self.color_from_value(value/29.0) for value in range(0,30)]
+ elif palette == 3:
+ background_color = (213, 217, 221)
+ colors = map( partial(desaturate, amount=0.7), [
+ (50,0,200),
+ (0,220,80),
+ (255,224,0),
+ ])
+ elif palette == 4:
+ background_color = (213, 217, 221)
+ colors = map( partial(desaturate, amount=0.8), [self.color_from_value(value/29.0) for value in range(0,30)])
+
+ self.image = Image.new("RGB", (image_width, image_height), background_color)
+
+ self.image_width = image_width
+ self.image_height = image_height
+
+ self.draw = ImageDraw.Draw(self.image)
+ self.previous_x, self.previous_y = None, None
+
+ self.color_lookup = interpolate_colors(colors)
+ self.pix = self.image.load()
+
+ def color_from_value(self, value):
+ """ given a value between 0 and 1, return an (r,g,b) tuple """
+
+ return ImageColor.getrgb("hsl(%d,%d%%,%d%%)" % (int( (1.0 - value) * 360 ), 80, 50))
+
+ def draw_peaks(self, x, peaks, spectral_centroid):
+ """ draw 2 peaks at x using the spectral_centroid for color """
+
+ y1 = self.image_height * 0.5 - peaks[0] * (self.image_height - 4) * 0.5
+ y2 = self.image_height * 0.5 - peaks[1] * (self.image_height - 4) * 0.5
+
+ line_color = self.color_lookup[int(spectral_centroid*255.0)]
+
+ if self.previous_y != None:
+ self.draw.line([self.previous_x, self.previous_y, x, y1, x, y2], line_color)
+ else:
+ self.draw.line([x, y1, x, y2], line_color)
+
+ self.previous_x, self.previous_y = x, y2
+
+ self.draw_anti_aliased_pixels(x, y1, y2, line_color)
+
+ def draw_anti_aliased_pixels(self, x, y1, y2, color):
+ """ vertical anti-aliasing at y1 and y2 """
+
+ y_max = max(y1, y2)
+ y_max_int = int(y_max)
+ alpha = y_max - y_max_int
+
+ if alpha > 0.0 and alpha < 1.0 and y_max_int + 1 < self.image_height:
+ current_pix = self.pix[x, y_max_int + 1]
+
+ r = int((1-alpha)*current_pix[0] + alpha*color[0])
+ g = int((1-alpha)*current_pix[1] + alpha*color[1])
+ b = int((1-alpha)*current_pix[2] + alpha*color[2])
+
+ self.pix[x, y_max_int + 1] = (r,g,b)
+
+ y_min = min(y1, y2)
+ y_min_int = int(y_min)
+ alpha = 1.0 - (y_min - y_min_int)
+
+ if alpha > 0.0 and alpha < 1.0 and y_min_int - 1 >= 0:
+ current_pix = self.pix[x, y_min_int - 1]
+
+ r = int((1-alpha)*current_pix[0] + alpha*color[0])
+ g = int((1-alpha)*current_pix[1] + alpha*color[1])
+ b = int((1-alpha)*current_pix[2] + alpha*color[2])
+
+ self.pix[x, y_min_int - 1] = (r,g,b)
+
+ def save(self, filename):
+ # draw a zero "zero" line
+ a = 25
+ for x in range(self.image_width):
+ self.pix[x, self.image_height/2] = tuple(map(lambda p: p+a, self.pix[x, self.image_height/2]))
+
+ self.image.save(filename)
+
+
+class SpectrogramImage(object):
+ """
+ Given spectra from the AudioProcessor, this class will construct a wavefile image which
+ can be saved as PNG.
+ """
+ def __init__(self, image_width, image_height, fft_size):
+ self.image_width = image_width
+ self.image_height = image_height
+ self.fft_size = fft_size
+
+ self.image = Image.new("RGBA", (image_height, image_width))
+
+ colors = [
+ (0, 0, 0, 0),
+ (58/4, 68/4, 65/4, 255),
+ (80/2, 100/2, 153/2, 255),
+ (90, 180, 100, 255),
+ (224, 224, 44, 255),
+ (255, 60, 30, 255),
+ (255, 255, 255, 255)
+ ]
+ self.palette = interpolate_colors(colors)
+
+ # generate the lookup which translates y-coordinate to fft-bin
+ self.y_to_bin = []
+ f_min = 100.0
+ f_max = 22050.0
+ y_min = math.log10(f_min)
+ y_max = math.log10(f_max)
+ for y in range(self.image_height):
+ freq = math.pow(10.0, y_min + y / (image_height - 1.0) *(y_max - y_min))
+ bin = freq / 22050.0 * (self.fft_size/2 + 1)
+
+ if bin < self.fft_size/2:
+ alpha = bin - int(bin)
+
+ self.y_to_bin.append((int(bin), alpha * 255))
+
+ # this is a bit strange, but using image.load()[x,y] = ... is
+ # a lot slower than using image.putadata and then rotating the image
+ # so we store all the pixels in an array and then create the image when saving
+ self.pixels = []
+
+ def draw_spectrum(self, x, spectrum):
+ # for all frequencies, draw the pixels
+ for (index, alpha) in self.y_to_bin:
+ self.pixels.append( self.palette[int((255.0-alpha) * spectrum[index] + alpha * spectrum[index + 1])] )
+
+ # if the FFT is too small to fill up the image, fill with black to the top
+ for y in range(len(self.y_to_bin), self.image_height): #@UnusedVariable
+ self.pixels.append(self.palette[0])
+
+ def save(self, filename, quality=80):
+ assert filename.lower().endswith(".jpg")
+ self.image.putdata(self.pixels)
+ self.image.transpose(Image.ROTATE_90).save(filename, quality=quality)
+
+
+def create_wave_images(input_filename, output_filename_w, output_filename_s, image_width, image_height, fft_size, progress_callback=None):
+ """
+ Utility function for creating both wavefile and spectrum images from an audio input file.
+ """
+ processor = AudioProcessor(input_filename, fft_size, numpy.hanning)
+ samples_per_pixel = processor.audio_file.nframes / float(image_width)
+
+ waveform = WaveformImage(image_width, image_height)
+ spectrogram = SpectrogramImage(image_width, image_height, fft_size)
+
+ for x in range(image_width):
+
+ if progress_callback and x % (image_width/10) == 0:
+ progress_callback((x*100)/image_width)
+
+ seek_point = int(x * samples_per_pixel)
+ next_seek_point = int((x + 1) * samples_per_pixel)
+
+ (spectral_centroid, db_spectrum) = processor.spectral_centroid(seek_point)
+ peaks = processor.peaks(seek_point, next_seek_point)
+
+ waveform.draw_peaks(x, peaks, spectral_centroid)
+ spectrogram.draw_spectrum(x, db_spectrum)
+
+ if progress_callback:
+ progress_callback(100)
+
+ waveform.save(output_filename_w)
+ spectrogram.save(output_filename_s)
+
+
+class NoSpaceLeftException(Exception):
+ pass
+
+def convert_to_pcm(input_filename, output_filename):
+ """
+ converts any audio file type to pcm audio
+ """
+
+ if not os.path.exists(input_filename):
+ raise AudioProcessingException, "file %s does not exist" % input_filename
+
+ sound_type = get_sound_type(input_filename)
+
+ if sound_type == "mp3":
+ cmd = ["lame", "--decode", input_filename, output_filename]
+ elif sound_type == "ogg":
+ cmd = ["oggdec", input_filename, "-o", output_filename]
+ elif sound_type == "flac":
+ cmd = ["flac", "-f", "-d", "-s", "-o", output_filename, input_filename]
+ else:
+ return False
+
+ process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ (stdout, stderr) = process.communicate()
+
+ if process.returncode != 0 or not os.path.exists(output_filename):
+ if "No space left on device" in stderr + " " + stdout:
+ raise NoSpaceLeftException
+ raise AudioProcessingException, "failed converting to pcm data:\n" + " ".join(cmd) + "\n" + stderr + "\n" + stdout
+
+ return True
+
+
+def stereofy_and_find_info(stereofy_executble_path, input_filename, output_filename):
+ """
+ converts a pcm wave file to two channel, 16 bit integer
+ """
+
+ if not os.path.exists(input_filename):
+ raise AudioProcessingException, "file %s does not exist" % input_filename
+
+ cmd = [stereofy_executble_path, "--input", input_filename, "--output", output_filename]
+
+ process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ (stdout, stderr) = process.communicate()
+
+ if process.returncode != 0 or not os.path.exists(output_filename):
+ if "No space left on device" in stderr + " " + stdout:
+ raise NoSpaceLeftException
+ raise AudioProcessingException, "failed calling stereofy data:\n" + " ".join(cmd) + "\n" + stderr + "\n" + stdout
+
+ stdout = (stdout + " " + stderr).replace("\n", " ")
+
+ duration = 0
+ m = re.match(r".*#duration (?P<duration>[\d\.]+).*", stdout)
+ if m != None:
+ duration = float(m.group("duration"))
+
+ channels = 0
+ m = re.match(r".*#channels (?P<channels>\d+).*", stdout)
+ if m != None:
+ channels = float(m.group("channels"))
+
+ samplerate = 0
+ m = re.match(r".*#samplerate (?P<samplerate>\d+).*", stdout)
+ if m != None:
+ samplerate = float(m.group("samplerate"))
+
+ bitdepth = None
+ m = re.match(r".*#bitdepth (?P<bitdepth>\d+).*", stdout)
+ if m != None:
+ bitdepth = float(m.group("bitdepth"))
+
+ bitrate = (os.path.getsize(input_filename) * 8.0) / 1024.0 / duration if duration > 0 else 0
+
+ return dict(duration=duration, channels=channels, samplerate=samplerate, bitrate=bitrate, bitdepth=bitdepth)
+
+
+def convert_to_mp3(input_filename, output_filename, quality=70):
+ """
+ converts the incoming wave file to a mp3 file
+ """
+
+ if not os.path.exists(input_filename):
+ raise AudioProcessingException, "file %s does not exist" % input_filename
+
+ command = ["lame", "--silent", "--abr", str(quality), input_filename, output_filename]
+
+ process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ (stdout, stderr) = process.communicate()
+
+ if process.returncode != 0 or not os.path.exists(output_filename):
+ raise AudioProcessingException, stdout
+
+def convert_to_ogg(input_filename, output_filename, quality=1):
+ """
+ converts the incoming wave file to n ogg file
+ """
+
+ if not os.path.exists(input_filename):
+ raise AudioProcessingException, "file %s does not exist" % input_filename
+
+ command = ["oggenc", "-q", str(quality), input_filename, "-o", output_filename]
+
+ process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ (stdout, stderr) = process.communicate()
+
+ if process.returncode != 0 or not os.path.exists(output_filename):
+ raise AudioProcessingException, stdout
+
+def convert_using_ffmpeg(input_filename, output_filename):
+ """
+ converts the incoming wave file to stereo pcm using fffmpeg
+ """
+ TIMEOUT = 3 * 60
+ def alarm_handler(signum, frame):
+ raise AudioProcessingException, "timeout while waiting for ffmpeg"
+
+ if not os.path.exists(input_filename):
+ raise AudioProcessingException, "file %s does not exist" % input_filename
+
+ command = ["ffmpeg", "-y", "-i", input_filename, "-ac","1","-acodec", "pcm_s16le", "-ar", "44100", output_filename]
+
+ process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ signal.signal(signal.SIGALRM,alarm_handler)
+ signal.alarm(TIMEOUT)
+ (stdout, stderr) = process.communicate()
+ signal.alarm(0)
+ if process.returncode != 0 or not os.path.exists(output_filename):
+ raise AudioProcessingException, stdout
diff --git a/extlib/html5slider/html5slider.js b/extlib/html5slider/html5slider.js
new file mode 100644
index 00000000..e69c3d2b
--- /dev/null
+++ b/extlib/html5slider/html5slider.js
@@ -0,0 +1,268 @@
+/*
+html5slider - a JS implementation of <input type=range> for Firefox 4 and up
+https://github.com/fryn/html5slider
+
+Copyright (c) 2010-2011 Frank Yan, <http://frankyan.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+(function() {
+
+// test for native support
+var test = document.createElement('input');
+try {
+ test.type = 'range';
+ if (test.type == 'range')
+ return;
+} catch (e) {
+ return;
+}
+
+// test for required property support
+if (!document.mozSetImageElement || !('MozAppearance' in test.style))
+ return;
+
+var scale;
+var isMac = navigator.platform == 'MacIntel';
+var thumb = {
+ radius: isMac ? 9 : 6,
+ width: isMac ? 22 : 12,
+ height: isMac ? 16 : 20
+};
+var track = '-moz-linear-gradient(top, transparent ' + (isMac ?
+ '6px, #999 6px, #999 7px, #ccc 9px, #bbb 11px, #bbb 12px, transparent 12px' :
+ '9px, #999 9px, #bbb 10px, #fff 11px, transparent 11px') +
+ ', transparent)';
+var styles = {
+ 'min-width': thumb.width + 'px',
+ 'min-height': thumb.height + 'px',
+ 'max-height': thumb.height + 'px',
+ padding: 0,
+ border: 0,
+ 'border-radius': 0,
+ cursor: 'default',
+ 'text-indent': '-999999px' // -moz-user-select: none; breaks mouse capture
+};
+var onChange = document.createEvent('HTMLEvents');
+onChange.initEvent('change', true, false);
+
+if (document.readyState == 'loading')
+ document.addEventListener('DOMContentLoaded', initialize, true);
+else
+ initialize();
+
+function initialize() {
+ // create initial sliders
+ Array.forEach(document.querySelectorAll('input[type=range]'), transform);
+ // create sliders on-the-fly
+ document.addEventListener('DOMNodeInserted', onNodeInserted, true);
+}
+
+function onNodeInserted(e) {
+ check(e.target);
+ if (e.target.querySelectorAll)
+ Array.forEach(e.target.querySelectorAll('input'), check);
+}
+
+function check(input, async) {
+ if (input.localName != 'input' || input.type == 'range');
+ else if (input.getAttribute('type') == 'range')
+ transform(input);
+ else if (!async)
+ setTimeout(check, 0, input, true);
+}
+
+function transform(slider) {
+
+ var isValueSet, areAttrsSet, isChanged, isClick, prevValue, rawValue, prevX;
+ var min, max, step, range, value = slider.value;
+
+ // lazily create shared slider affordance
+ if (!scale) {
+ scale = document.body.appendChild(document.createElement('hr'));
+ style(scale, {
+ '-moz-appearance': isMac ? 'scale-horizontal' : 'scalethumb-horizontal',
+ display: 'block',
+ visibility: 'visible',
+ opacity: 1,
+ position: 'fixed',
+ top: '-999999px'
+ });
+ document.mozSetImageElement('__sliderthumb__', scale);
+ }
+
+ // reimplement value and type properties
+ var getValue = function() { return '' + value; };
+ var setValue = function setValue(val) {
+ value = '' + val;
+ isValueSet = true;
+ draw();
+ delete slider.value;
+ slider.value = value;
+ slider.__defineGetter__('value', getValue);
+ slider.__defineSetter__('value', setValue);
+ };
+ slider.__defineGetter__('value', getValue);
+ slider.__defineSetter__('value', setValue);
+ slider.__defineGetter__('type', function() { return 'range'; });
+
+ // sync properties with attributes
+ ['min', 'max', 'step'].forEach(function(prop) {
+ if (slider.hasAttribute(prop))
+ areAttrsSet = true;
+ slider.__defineGetter__(prop, function() {
+ return this.hasAttribute(prop) ? this.getAttribute(prop) : '';
+ });
+ slider.__defineSetter__(prop, function(val) {
+ val === null ? this.removeAttribute(prop) : this.setAttribute(prop, val);
+ });
+ });
+
+ // initialize slider
+ slider.readOnly = true;
+ style(slider, styles);
+ update();
+
+ slider.addEventListener('DOMAttrModified', function(e) {
+ // note that value attribute only sets initial value
+ if (e.attrName == 'value' && !isValueSet) {
+ value = e.newValue;
+ draw();
+ }
+ else if (~['min', 'max', 'step'].indexOf(e.attrName)) {
+ update();
+ areAttrsSet = true;
+ }
+ }, true);
+
+ slider.addEventListener('mousedown', onDragStart, true);
+ slider.addEventListener('keydown', onKeyDown, true);
+ slider.addEventListener('focus', onFocus, true);
+ slider.addEventListener('blur', onBlur, true);
+
+ function onDragStart(e) {
+ isClick = true;
+ setTimeout(function() { isClick = false; }, 0);
+ if (e.button || !range)
+ return;
+ var width = parseFloat(getComputedStyle(this, 0).width);
+ var multiplier = (width - thumb.width) / range;
+ if (!multiplier)
+ return;
+ // distance between click and center of thumb
+ var dev = e.clientX - this.getBoundingClientRect().left - thumb.width / 2 -
+ (value - min) * multiplier;
+ // if click was not on thumb, move thumb to click location
+ if (Math.abs(dev) > thumb.radius) {
+ isChanged = true;
+ this.value -= -dev / multiplier;
+ }
+ rawValue = value;
+ prevX = e.clientX;
+ this.addEventListener('mousemove', onDrag, true);
+ this.addEventListener('mouseup', onDragEnd, true);
+ }
+
+ function onDrag(e) {
+ var width = parseFloat(getComputedStyle(this, 0).width);
+ var multiplier = (width - thumb.width) / range;
+ if (!multiplier)
+ return;
+ rawValue += (e.clientX - prevX) / multiplier;
+ prevX = e.clientX;
+ isChanged = true;
+ this.value = rawValue;
+ }
+
+ function onDragEnd() {
+ this.removeEventListener('mousemove', onDrag, true);
+ this.removeEventListener('mouseup', onDragEnd, true);
+ }
+
+ function onKeyDown(e) {
+ if (e.keyCode > 36 && e.keyCode < 41) { // 37-40: left, up, right, down
+ onFocus.call(this);
+ isChanged = true;
+ this.value = value + (e.keyCode == 38 || e.keyCode == 39 ? step : -step);
+ }
+ }
+
+ function onFocus() {
+ if (!isClick)
+ this.style.boxShadow = !isMac ? '0 0 0 2px #fb0' :
+ '0 0 2px 1px -moz-mac-focusring, inset 0 0 1px -moz-mac-focusring';
+ }
+
+ function onBlur() {
+ this.style.boxShadow = '';
+ }
+
+ // determines whether value is valid number in attribute form
+ function isAttrNum(value) {
+ return !isNaN(value) && +value == parseFloat(value);
+ }
+
+ // validates min, max, and step attributes and redraws
+ function update() {
+ min = isAttrNum(slider.min) ? +slider.min : 0;
+ max = isAttrNum(slider.max) ? +slider.max : 100;
+ if (max < min)
+ max = min > 100 ? min : 100;
+ step = isAttrNum(slider.step) && slider.step > 0 ? +slider.step : 1;
+ range = max - min;
+ draw(true);
+ }
+
+ // recalculates value property
+ function calc() {
+ if (!isValueSet && !areAttrsSet)
+ value = slider.getAttribute('value');
+ if (!isAttrNum(value))
+ value = (min + max) / 2;;
+ // snap to step intervals (WebKit sometimes does not - bug?)
+ value = Math.round((value - min) / step) * step + min;
+ if (value < min)
+ value = min;
+ else if (value > max)
+ value = min + ~~(range / step) * step;
+ }
+
+ // renders slider using CSS background ;)
+ function draw(attrsModified) {
+ calc();
+ if (isChanged && value != prevValue)
+ slider.dispatchEvent(onChange);
+ isChanged = false;
+ if (!attrsModified && value == prevValue)
+ return;
+ prevValue = value;
+ var position = range ? (value - min) / range * 100 : 0;
+ var bg = '-moz-element(#__sliderthumb__) ' + position + '% no-repeat, ';
+ style(slider, { background: bg + track });
+ }
+
+}
+
+function style(element, styles) {
+ for (var prop in styles)
+ element.style.setProperty(prop, styles[prop], 'important');
+}
+
+})();
diff --git a/lazycelery.sh b/lazycelery.sh
new file mode 120000
index 00000000..4ff15b1d
--- /dev/null
+++ b/lazycelery.sh
@@ -0,0 +1 @@
+lazystarter.sh \ No newline at end of file
diff --git a/lazyserver.sh b/lazyserver.sh
index 843993e6..4ff15b1d 100755..120000
--- a/lazyserver.sh
+++ b/lazyserver.sh
@@ -1,64 +1 @@
-#!/bin/sh
-
-# GNU MediaGoblin -- federated, autonomous media hosting
-# Copyright (C) 2011 Free Software Foundation, Inc
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-#
-# This runs Mediagoblin using Paste with Celery set to always eager mode.
-#
-
-if [ "$1" = "-h" ]
-then
- echo "$0 [-h] [-c paste.ini] [ARGS_to_paster ...]"
- echo ""
- echo " For example:"
- echo " $0 -c fcgi.ini port_number=23371"
- echo " or: $0 --server-name=fcgi --log-file=paste.log"
- echo ""
- echo " The configfile defaults to paste_local.ini,"
- echo " if that is readable, otherwise paste.ini."
- exit 1
-fi
-
-PASTE_INI=paste.ini
-
-if [ -r paste_local.ini ]
-then
- PASTE_INI=paste_local.ini
-fi
-
-if [ "$1" = "-c" ]
-then
- PASTE_INI="$2"
- shift
- shift
-fi
-
-echo "Using paste config: $PASTE_INI"
-
-if [ -f ./bin/paster ]; then
- echo "Using ./bin/paster";
- export PASTER="./bin/paster";
-elif which paster > /dev/null; then
- echo "Using paster from \$PATH";
- export PASTER="paster";
-else
- echo "No paster found, exiting! X_X";
- exit 1
-fi
-
-set -x
-CELERY_ALWAYS_EAGER=true $PASTER serve $PASTE_INI "$@" --reload
+lazystarter.sh \ No newline at end of file
diff --git a/lazystarter.sh b/lazystarter.sh
new file mode 100755
index 00000000..d3770194
--- /dev/null
+++ b/lazystarter.sh
@@ -0,0 +1,82 @@
+#!/bin/sh
+
+# GNU MediaGoblin -- federated, autonomous media hosting
+# Copyright (C) 2011 Free Software Foundation, Inc
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+selfname=$(basename "$0")
+local_bin="./bin"
+case "$selfname" in
+ lazyserver.sh)
+ starter_cmd=paster
+ ini_prefix=paste
+ ;;
+ lazycelery.sh)
+ starter_cmd=celeryd
+ ini_prefix=mediagoblin
+ ;;
+ *)
+ echo "Start this script with the name lazyserver.sh or lazycelery.sh">&2
+ exit 1
+ ;;
+esac
+
+if [ "$1" = "-h" ]; then
+ echo "$0 [-h] [-c filename.ini] [ARGS_to_${starter_cmd} ...]"
+ echo ""
+ echo " For example:"
+ echo " $0 -c fcgi.ini port_number=23371"
+ echo " or: $0 --server-name=fcgi --log-file=paste.log"
+ echo ""
+ echo " The configfile defaults to ${ini_prefix}_local.ini,"
+ echo " if that is readable, otherwise ${ini_prefix}.ini."
+ exit 1
+fi
+
+if [ "$1" = "-c" ]; then
+ ini_file=$2
+ shift; shift
+elif [ -r "${ini_prefix}_local.ini" ]; then
+ ini_file="${ini_prefix}_local.ini"
+else
+ ini_file="${ini_prefix}.ini"
+fi
+
+echo "Using ${starter_cmd} config: ${ini_file}"
+
+if [ -f "${local_bin}/${starter_cmd}" ]; then
+ echo "Using ${local_bin}/${starter_cmd}"
+ starter="${local_bin}/${starter_cmd}"
+elif which "${starter_cmd}" > /dev/null; then
+ echo "Using ${starter_cmd} from \$PATH"
+ starter=$starter_cmd
+else
+ echo "No ${starter_cmd} found, exiting! X_X"
+ exit 1
+fi
+
+set -x
+export CELERY_ALWAYS_EAGER=true
+case "$selfname" in
+ lazyserver.sh)
+ $starter serve "$ini_file" "$@" --reload
+ ;;
+ lazycelery.sh)
+ MEDIAGOBLIN_CONFIG="${ini_file}" \
+ CELERY_CONFIG_MODULE=mediagoblin.init.celery.from_celery \
+ $starter "$@"
+ ;;
+ *) exit 1 ;;
+esac
diff --git a/mediagoblin.ini b/mediagoblin.ini
index 223f0f4a..ba7df36a 100644
--- a/mediagoblin.ini
+++ b/mediagoblin.ini
@@ -30,3 +30,8 @@ base_url = /mgoblin_media/
[celery]
# Put celery stuff here
+
+# place plugins here---each in their own subsection of [plugins]. see
+# documentation for details.
+#[plugins]
+
diff --git a/mediagoblin/_version.py b/mediagoblin/_version.py
index 381d1270..8d86b42f 100644
--- a/mediagoblin/_version.py
+++ b/mediagoblin/_version.py
@@ -23,4 +23,4 @@
# see http://www.python.org/dev/peps/pep-0386/
-__version__ = "0.3.0-dev"
+__version__ = "0.3.1.dev"
diff --git a/mediagoblin/app.py b/mediagoblin/app.py
index 0a57c091..97080ed8 100644
--- a/mediagoblin/app.py
+++ b/mediagoblin/app.py
@@ -27,6 +27,7 @@ from mediagoblin.tools.response import render_404
from mediagoblin.tools import request as mg_request
from mediagoblin.mg_globals import setup_globals
from mediagoblin.init.celery import setup_celery_from_config
+from mediagoblin.init.plugins import setup_plugins
from mediagoblin.init import (get_jinja_loader, get_staticdirector,
setup_global_and_app_config, setup_workbench, setup_database,
setup_storage, setup_beaker_cache)
@@ -52,6 +53,7 @@ class MediaGoblinApp(object):
setting up celery.)
"""
_log.info("GNU MediaGoblin %s main server starting", __version__)
+ _log.debug("Using config file %s", config_path)
##############
# Setup config
##############
@@ -63,6 +65,11 @@ class MediaGoblinApp(object):
# Setup other connections / useful objects
##########################################
+ # Set up plugins -- need to do this early so that plugins can
+ # affect startup.
+ _log.info("Setting up plugins.")
+ setup_plugins()
+
# Set up the database
self.connection, self.db = setup_database()
@@ -84,7 +91,7 @@ class MediaGoblinApp(object):
# Setup celery, if appropriate
if setup_celery and not app_config.get('celery_setup_elsewhere'):
- if os.environ.get('CELERY_ALWAYS_EAGER'):
+ if os.environ.get('CELERY_ALWAYS_EAGER', 'false').lower() == 'true':
setup_celery_from_config(
app_config, global_config,
force_celery_always_eager=True)
@@ -109,7 +116,7 @@ class MediaGoblinApp(object):
self.meddleware = [common.import_component(m)(self)
for m in meddleware.ENABLED_MEDDLEWARE]
- def __call__(self, environ, start_response):
+ def call_backend(self, environ, start_response):
request = Request(environ)
## Routing / controller loading stuff
@@ -167,7 +174,13 @@ class MediaGoblinApp(object):
request.matchdict = {} # in case our template expects it
return render_404(request)(environ, start_response)
- controller = common.import_component(route_match['controller'])
+ # import the controller, or if it's already a callable, call that
+ route_controller = route_match['controller']
+ if isinstance(route_controller, unicode) \
+ or isinstance(route_controller, str):
+ controller = common.import_component(route_match['controller'])
+ else:
+ controller = route_match['controller']
# pass the request through our meddleware classes
for m in self.meddleware:
@@ -184,15 +197,18 @@ class MediaGoblinApp(object):
for m in self.meddleware[::-1]:
m.process_response(request, response)
- # Reset the sql session, so that the next request
- # gets a fresh session
+ return response(environ, start_response)
+
+ def __call__(self, environ, start_response):
+ ## If more errors happen that look like unclean sessions:
+ # self.db.check_session_clean()
+
try:
+ return self.call_backend(environ, start_response)
+ finally:
+ # Reset the sql session, so that the next request
+ # gets a fresh session
self.db.reset_after_request()
- except TypeError:
- # We're still on mongo
- pass
-
- return response(environ, start_response)
def paste_app_factory(global_config, **app_config):
diff --git a/mediagoblin/auth/forms.py b/mediagoblin/auth/forms.py
index 1b3e214c..0b2bf959 100644
--- a/mediagoblin/auth/forms.py
+++ b/mediagoblin/auth/forms.py
@@ -48,14 +48,14 @@ class LoginForm(wtforms.Form):
class ForgotPassForm(wtforms.Form):
username = wtforms.TextField(
- 'Username or email',
+ _('Username or email'),
[wtforms.validators.Required()])
def validate_username(form, field):
if not (re.match(r'^\w+$', field.data) or
re.match(r'^.+@[^.].*\.[a-z]{2,10}$', field.data,
re.IGNORECASE)):
- raise wtforms.ValidationError(u'Incorrect input')
+ raise wtforms.ValidationError(_(u'Incorrect input'))
class ChangePassForm(wtforms.Form):
diff --git a/mediagoblin/auth/lib.py b/mediagoblin/auth/lib.py
index ddb58fe6..c5b046d2 100644
--- a/mediagoblin/auth/lib.py
+++ b/mediagoblin/auth/lib.py
@@ -14,7 +14,6 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-import os
import random
import bcrypt
diff --git a/mediagoblin/auth/views.py b/mediagoblin/auth/views.py
index 46c937b0..71a5f379 100644
--- a/mediagoblin/auth/views.py
+++ b/mediagoblin/auth/views.py
@@ -236,7 +236,8 @@ def forgot_password(request):
Sends an email with an url to renew forgotten password
"""
- fp_form = auth_forms.ForgotPassForm(request.POST)
+ fp_form = auth_forms.ForgotPassForm(request.POST,
+ username=request.GET.get('username'))
if request.method == 'POST' and fp_form.validate():
diff --git a/mediagoblin/config_spec.ini b/mediagoblin/config_spec.ini
index 866d799b..ce81b356 100644
--- a/mediagoblin/config_spec.ini
+++ b/mediagoblin/config_spec.ini
@@ -69,11 +69,41 @@ base_url = string(default="/mgoblin_media/")
storage_class = string(default="mediagoblin.storage.filestorage:BasicFileStorage")
base_dir = string(default="%(here)s/user_dev/media/queue")
+[media:medium]
+# Dimensions used when creating media display images.
+max_width = integer(default=640)
+max_height = integer(default=640)
+
+[media:thumb]
+# Dimensions used when creating media thumbnails
+# This is unfortunately not implemented in the media
+# types yet. You can help!
+# TODO: Make plugins follow the media size settings
+max_width = integer(default=180)
+max_height = integer(default=180)
-# Should we keep the original file?
[media_type:mediagoblin.media_types.video]
+# Should we keep the original file?
keep_original = boolean(default=False)
+# 0 means autodetect, autodetect means number_of_CPUs - 1
+vp8_threads = integer(default=0)
+# Range: 0..10
+vp8_quality = integer(default=8)
+# Range: -0.1..1
+vorbis_quality = float(default=0.3)
+
+
+[media_type:mediagoblin.media_types.audio]
+keep_original = boolean(default=True)
+# vorbisenc qualiy
+quality = float(default=0.3)
+create_spectrogram = boolean(default=True)
+spectrogram_fft_size = integer(default=4096)
+
+
+[media_type:mediagoblin.media_types.ascii]
+thumbnail_font = string(default=None)
[beaker.cache]
type = string(default="file")
diff --git a/mediagoblin/db/mixin.py b/mediagoblin/db/mixin.py
index 4f9e1b11..a5aded02 100644
--- a/mediagoblin/db/mixin.py
+++ b/mediagoblin/db/mixin.py
@@ -123,6 +123,17 @@ class MediaEntryMixin(object):
"""Return license dict for requested license"""
return licenses.SUPPORTED_LICENSES[self.license or ""]
+ def exif_display_iter(self):
+ from mediagoblin.tools.exif import USEFUL_TAGS
+
+ if not self.media_data:
+ return
+ exif_all = self.media_data.get("exif_all")
+
+ for key in USEFUL_TAGS:
+ if key in exif_all:
+ yield key, exif_all[key]
+
class MediaCommentMixin(object):
@property
diff --git a/mediagoblin/db/mongo/migrations.py b/mediagoblin/db/mongo/migrations.py
index 1984ecc4..569dec88 100644
--- a/mediagoblin/db/mongo/migrations.py
+++ b/mediagoblin/db/mongo/migrations.py
@@ -119,6 +119,7 @@ def media_type_image_to_multimedia_type_image(database):
{'$set': {'media_type': 'mediagoblin.media_types.image'}},
multi=True)
+
@RegisterMigration(8)
def mediaentry_add_license(database):
"""
@@ -140,6 +141,7 @@ def remove_calculated_html(database):
drop_table_field(database, 'media_entries', 'description_html')
drop_table_field(database, 'media_comments', 'content_html')
+
@RegisterMigration(10)
def convert_video_media_data(database):
"""
@@ -154,6 +156,7 @@ def convert_video_media_data(database):
document['media_data'] = document['media_data']['video']
collection.save(document)
+
@RegisterMigration(11)
def convert_gps_media_data(database):
"""
@@ -170,7 +173,34 @@ def convert_gps_media_data(database):
del document['media_data']['gps']
collection.save(document)
+
@RegisterMigration(12)
+def convert_exif_media_data(database):
+ """
+ Move media_data["exif"]["clean"] to media_data["exif_all"].
+ Drop media_data["exif"]["useful"]
+ In preparation for media_data.exif_all
+ """
+ collection = database['media_entries']
+ target = collection.find(
+ {'media_data.exif.clean': {'$exists': True}})
+
+ for document in target:
+ media_data = document['media_data']
+
+ exif_all = media_data['exif'].pop('clean')
+ if len(exif_all):
+ media_data['exif_all'] = exif_all
+
+ del media_data['exif']['useful']
+
+ assert len(media_data['exif']) == 0
+ del media_data['exif']
+
+ collection.save(document)
+
+
+@RegisterMigration(13)
def user_add_wants_comment_notification(database):
"""
Add wants_comment_notification to user model
diff --git a/mediagoblin/db/mongo/open.py b/mediagoblin/db/mongo/open.py
index bedc497b..c4f37b42 100644
--- a/mediagoblin/db/mongo/open.py
+++ b/mediagoblin/db/mongo/open.py
@@ -21,6 +21,10 @@ from mediagoblin.db.mongo import models
from mediagoblin.db.mongo.util import MigrationManager
+def load_models(app_config):
+ pass
+
+
def connect_database_from_config(app_config, use_pymongo=False):
"""
Connect to the main database, take config from app_config
diff --git a/mediagoblin/db/open.py b/mediagoblin/db/open.py
index 0163469f..f4c38511 100644
--- a/mediagoblin/db/open.py
+++ b/mediagoblin/db/open.py
@@ -21,7 +21,9 @@ except ImportError:
if use_sql:
from mediagoblin.db.sql.open import \
- setup_connection_and_db_from_config, check_db_migrations_current
+ setup_connection_and_db_from_config, check_db_migrations_current, \
+ load_models
else:
from mediagoblin.db.mongo.open import \
- setup_connection_and_db_from_config, check_db_migrations_current
+ setup_connection_and_db_from_config, check_db_migrations_current, \
+ load_models
diff --git a/mediagoblin/db/sql/convert.py b/mediagoblin/db/sql/convert.py
index d1492977..ac64cf8d 100644
--- a/mediagoblin/db/sql/convert.py
+++ b/mediagoblin/db/sql/convert.py
@@ -15,26 +15,27 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from copy import copy
+from itertools import chain, imap
-from mediagoblin.init import setup_global_and_app_config, setup_database
-from mediagoblin.db.mongo.util import ObjectId
+from mediagoblin.init import setup_global_and_app_config
-from mediagoblin.db.sql.models import (Base, User, MediaEntry, MediaComment,
- Tag, MediaTag, MediaFile, MediaAttachmentFile, MigrationData)
-from mediagoblin.media_types.image.models import ImageData
-from mediagoblin.media_types.video.models import VideoData
+from mediagoblin.db.sql.base import Session
+from mediagoblin.db.sql.models_v0 import Base_v0
+from mediagoblin.db.sql.models_v0 import (User, MediaEntry, MediaComment,
+ Tag, MediaTag, MediaFile, MediaAttachmentFile, MigrationData,
+ ImageData, VideoData, AsciiData, AudioData)
from mediagoblin.db.sql.open import setup_connection_and_db_from_config as \
sql_connect
from mediagoblin.db.mongo.open import setup_connection_and_db_from_config as \
mongo_connect
-from mediagoblin.db.sql.base import Session
obj_id_table = dict()
+
def add_obj_ids(entry, new_entry):
global obj_id_table
- print "%r -> %r" % (entry._id, new_entry.id)
+ print "\t%r -> SQL id %r" % (entry._id, new_entry.id)
obj_id_table[entry._id] = new_entry.id
@@ -43,6 +44,7 @@ def copy_attrs(entry, new_entry, attr_list):
val = entry[a]
setattr(new_entry, a, val)
+
def copy_reference_attr(entry, new_entry, ref_attr):
val = entry[ref_attr]
val = obj_id_table[val]
@@ -115,12 +117,9 @@ def convert_image(mk_db):
{'media_type': 'mediagoblin.media_types.image'}).sort('created'):
media_data = copy(media.media_data)
- # TODO: Fix after exif is migrated
- media_data.pop('exif', None)
-
if len(media_data):
media_data_row = ImageData(**media_data)
- media_data_row.media_entry = obj_id_table[media._id]
+ media_data_row.media_entry = obj_id_table[media['_id']]
session.add(media_data_row)
session.commit()
@@ -133,7 +132,7 @@ def convert_video(mk_db):
for media in mk_db.MediaEntry.find(
{'media_type': 'mediagoblin.media_types.video'}).sort('created'):
media_data_row = VideoData(**media.media_data)
- media_data_row.media_entry = obj_id_table[media._id]
+ media_data_row.media_entry = obj_id_table[media['_id']]
session.add(media_data_row)
session.commit()
@@ -178,53 +177,105 @@ def convert_media_comments(mk_db):
copy_attrs(entry, new_entry,
('created',
'content',))
- copy_reference_attr(entry, new_entry, "media_entry")
- copy_reference_attr(entry, new_entry, "author")
- session.add(new_entry)
- session.flush()
- add_obj_ids(entry, new_entry)
+ try:
+ copy_reference_attr(entry, new_entry, "media_entry")
+ copy_reference_attr(entry, new_entry, "author")
+ except KeyError as e:
+ print('KeyError in convert_media_comments(): {0}'.format(e))
+ else:
+ session.add(new_entry)
+ session.flush()
+ add_obj_ids(entry, new_entry)
session.commit()
session.close()
-def convert_add_migration_versions():
+media_types_tables = (
+ ("mediagoblin.media_types.image", (ImageData,)),
+ ("mediagoblin.media_types.video", (VideoData,)),
+ ("mediagoblin.media_types.ascii", (AsciiData,)),
+ ("mediagoblin.media_types.audio", (AudioData,)),
+ )
+
+
+def convert_add_migration_versions(dummy_sql_db):
session = Session()
- for name in ("__main__",
- "mediagoblin.media_types.image",
- "mediagoblin.media_types.video",
- ):
- m = MigrationData(name=name, version=0)
+ for name in chain(("__main__",),
+ imap(lambda e: e[0], media_types_tables)):
+ print "\tAdding %s" % (name,)
+ m = MigrationData(name=unicode(name), version=0)
session.add(m)
session.commit()
session.close()
+def cleanup_sql_tables(sql_db):
+ for mt, table_list in media_types_tables:
+ session = Session()
+
+ count = session.query(MediaEntry.media_type). \
+ filter_by(media_type=unicode(mt)).count()
+ print " %s: %d entries" % (mt, count)
+
+ if count == 0:
+ print "\tAnalyzing tables"
+ for tab in table_list:
+ cnt2 = session.query(tab).count()
+ print "\t %s: %d entries" % (tab.__tablename__, cnt2)
+ assert cnt2 == 0
+
+ print "\tRemoving migration info"
+ mi = session.query(MigrationData).filter_by(name=unicode(mt)).one()
+ session.delete(mi)
+ session.commit()
+ session.close()
+
+ print "\tDropping tables"
+ tables = [model.__table__ for model in table_list]
+ Base_v0.metadata.drop_all(sql_db.engine, tables=tables)
+
+ session.close()
+
+
+def print_header(title):
+ print "\n=== %s ===" % (title,)
+
+
+convert_call_list = (
+ ("Converting Users", convert_users),
+ ("Converting Media Entries", convert_media_entries),
+ ("Converting Media Data for Images", convert_image),
+ ("Cnnverting Media Data for Videos", convert_video),
+ ("Converting Tags for Media", convert_media_tags),
+ ("Converting Media Comments", convert_media_comments),
+ )
+
+sql_call_list = (
+ ("Filling Migration Tables", convert_add_migration_versions),
+ ("Analyzing/Cleaning SQL Data", cleanup_sql_tables),
+ )
+
def run_conversion(config_name):
global_config, app_config = setup_global_and_app_config(config_name)
sql_conn, sql_db = sql_connect(app_config)
mk_conn, mk_db = mongo_connect(app_config)
- Base.metadata.create_all(sql_db.engine)
-
- convert_users(mk_db)
- Session.remove()
- convert_media_entries(mk_db)
- Session.remove()
- convert_image(mk_db)
- Session.remove()
- convert_video(mk_db)
- Session.remove()
- convert_media_tags(mk_db)
- Session.remove()
- convert_media_comments(mk_db)
- Session.remove()
- convert_add_migration_versions()
- Session.remove()
+ Base_v0.metadata.create_all(sql_db.engine)
+
+ for title, func in convert_call_list:
+ print_header(title)
+ func(mk_db)
+ Session.remove()
+
+ for title, func in sql_call_list:
+ print_header(title)
+ func(sql_db)
+ Session.remove()
if __name__ == '__main__':
diff --git a/mediagoblin/db/sql/extratypes.py b/mediagoblin/db/sql/extratypes.py
index 8e078f14..f2304af0 100644
--- a/mediagoblin/db/sql/extratypes.py
+++ b/mediagoblin/db/sql/extratypes.py
@@ -15,7 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-from sqlalchemy.types import TypeDecorator, Unicode, VARCHAR
+from sqlalchemy.types import TypeDecorator, Unicode, TEXT
import json
@@ -50,7 +50,7 @@ class PathTupleWithSlashes(TypeDecorator):
class JSONEncoded(TypeDecorator):
"Represents an immutable structure as a json-encoded string."
- impl = VARCHAR
+ impl = TEXT
def process_bind_param(self, value, dialect):
if value is not None:
diff --git a/mediagoblin/db/sql/migrations.py b/mediagoblin/db/sql/migrations.py
index 98d0d0aa..3b7ee8b4 100644
--- a/mediagoblin/db/sql/migrations.py
+++ b/mediagoblin/db/sql/migrations.py
@@ -1,5 +1,5 @@
# GNU MediaGoblin -- federated, autonomous media hosting
-# Copyright (C) 2011 MediaGoblin contributors. See AUTHORS.
+# 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
@@ -14,4 +14,22 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
+from sqlalchemy import MetaData, Table
+
+from mediagoblin.db.sql.util import RegisterMigration
+
+
MIGRATIONS = {}
+
+
+@RegisterMigration(1, MIGRATIONS)
+def ogg_to_webm_audio(db_conn):
+ metadata = MetaData(bind=db_conn.bind)
+
+ file_keynames = Table('core__file_keynames', metadata, autoload=True,
+ autoload_with=db_conn.bind)
+
+ db_conn.execute(
+ file_keynames.update().where(file_keynames.c.name=='ogg').
+ values(name='webm_audio')
+ )
diff --git a/mediagoblin/db/sql/models.py b/mediagoblin/db/sql/models.py
index edf3eb0d..ba28ab7b 100644
--- a/mediagoblin/db/sql/models.py
+++ b/mediagoblin/db/sql/models.py
@@ -91,10 +91,11 @@ class MediaEntry(Base, MediaEntryMixin):
__tablename__ = "core__media_entries"
id = Column(Integer, primary_key=True)
- uploader = Column(Integer, ForeignKey('core__users.id'), nullable=False)
+ uploader = Column(Integer, ForeignKey(User.id), nullable=False, index=True)
title = Column(Unicode, nullable=False)
slug = Column(Unicode)
- created = Column(DateTime, nullable=False, default=datetime.datetime.now)
+ created = Column(DateTime, nullable=False, default=datetime.datetime.now,
+ index=True)
description = Column(UnicodeText) # ??
media_type = Column(Unicode, nullable=False)
state = Column(Unicode, default=u'unprocessed', nullable=False)
@@ -189,8 +190,9 @@ class MediaEntry(Base, MediaEntryMixin):
media_entry=self.id).first()
# No media data, so actually add a new one
- if not media_data:
+ if media_data is None:
media_data = self.media_data_table(
+ media_entry=self.id,
**kwargs)
session.add(media_data)
# Update old media data
@@ -292,8 +294,8 @@ class MediaTag(Base):
id = Column(Integer, primary_key=True)
media_entry = Column(
Integer, ForeignKey(MediaEntry.id),
- nullable=False)
- tag = Column(Integer, ForeignKey('core__tags.id'), nullable=False)
+ nullable=False, index=True)
+ tag = Column(Integer, ForeignKey(Tag.id), nullable=False, index=True)
name = Column(Unicode)
# created = Column(DateTime, nullable=False, default=datetime.datetime.now)
@@ -324,8 +326,8 @@ class MediaComment(Base, MediaCommentMixin):
id = Column(Integer, primary_key=True)
media_entry = Column(
- Integer, ForeignKey('core__media_entries.id'), nullable=False)
- author = Column(Integer, ForeignKey('core__users.id'), nullable=False)
+ Integer, ForeignKey(MediaEntry.id), nullable=False, index=True)
+ author = Column(Integer, ForeignKey(User.id), nullable=False)
created = Column(DateTime, nullable=False, default=datetime.datetime.now)
content = Column(UnicodeText, nullable=False)
diff --git a/mediagoblin/db/sql/models_v0.py b/mediagoblin/db/sql/models_v0.py
new file mode 100644
index 00000000..06f87d28
--- /dev/null
+++ b/mediagoblin/db/sql/models_v0.py
@@ -0,0 +1,320 @@
+# 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 <http://www.gnu.org/licenses/>.
+
+"""
+TODO: indexes on foreignkeys, where useful.
+"""
+
+
+import datetime
+import sys
+
+from sqlalchemy import (
+ Column, Integer, Unicode, UnicodeText, DateTime, Boolean, ForeignKey,
+ UniqueConstraint, PrimaryKeyConstraint, SmallInteger, Float)
+from sqlalchemy.ext.declarative import declarative_base
+from sqlalchemy.orm import relationship, backref
+from sqlalchemy.orm.collections import attribute_mapped_collection
+from sqlalchemy.ext.associationproxy import association_proxy
+from sqlalchemy.util import memoized_property
+
+from mediagoblin.db.sql.extratypes import PathTupleWithSlashes, JSONEncoded
+from mediagoblin.db.sql.base import GMGTableBase
+from mediagoblin.db.sql.base import Session
+
+
+Base_v0 = declarative_base(cls=GMGTableBase)
+
+
+class User(Base_v0):
+ """
+ TODO: We should consider moving some rarely used fields
+ into some sort of "shadow" table.
+ """
+ __tablename__ = "core__users"
+
+ id = Column(Integer, primary_key=True)
+ username = Column(Unicode, nullable=False, unique=True)
+ email = Column(Unicode, nullable=False)
+ created = Column(DateTime, nullable=False, default=datetime.datetime.now)
+ pw_hash = Column(Unicode, nullable=False)
+ email_verified = Column(Boolean, default=False)
+ status = Column(Unicode, default=u"needs_email_verification", nullable=False)
+ verification_key = Column(Unicode)
+ is_admin = Column(Boolean, default=False, nullable=False)
+ url = Column(Unicode)
+ bio = Column(UnicodeText) # ??
+ fp_verification_key = Column(Unicode)
+ fp_token_expire = Column(DateTime)
+
+ ## TODO
+ # plugin data would be in a separate model
+
+
+class MediaEntry(Base_v0):
+ """
+ TODO: Consider fetching the media_files using join
+ """
+ __tablename__ = "core__media_entries"
+
+ id = Column(Integer, primary_key=True)
+ uploader = Column(Integer, ForeignKey(User.id), nullable=False, index=True)
+ title = Column(Unicode, nullable=False)
+ slug = Column(Unicode)
+ created = Column(DateTime, nullable=False, default=datetime.datetime.now,
+ index=True)
+ description = Column(UnicodeText) # ??
+ media_type = Column(Unicode, nullable=False)
+ state = Column(Unicode, default=u'unprocessed', nullable=False)
+ # or use sqlalchemy.types.Enum?
+ license = Column(Unicode)
+
+ fail_error = Column(Unicode)
+ fail_metadata = Column(JSONEncoded)
+
+ queued_media_file = Column(PathTupleWithSlashes)
+
+ queued_task_id = Column(Unicode)
+
+ __table_args__ = (
+ UniqueConstraint('uploader', 'slug'),
+ {})
+
+ get_uploader = relationship(User)
+
+ media_files_helper = relationship("MediaFile",
+ collection_class=attribute_mapped_collection("name"),
+ cascade="all, delete-orphan"
+ )
+
+ attachment_files_helper = relationship("MediaAttachmentFile",
+ cascade="all, delete-orphan",
+ order_by="MediaAttachmentFile.created"
+ )
+
+ tags_helper = relationship("MediaTag",
+ cascade="all, delete-orphan"
+ )
+
+ def media_data_init(self, **kwargs):
+ """
+ Initialize or update the contents of a media entry's media_data row
+ """
+ session = Session()
+
+ media_data = session.query(self.media_data_table).filter_by(
+ media_entry=self.id).first()
+
+ # No media data, so actually add a new one
+ if media_data is None:
+ media_data = self.media_data_table(
+ media_entry=self.id,
+ **kwargs)
+ session.add(media_data)
+ # Update old media data
+ else:
+ for field, value in kwargs.iteritems():
+ setattr(media_data, field, value)
+
+ @memoized_property
+ def media_data_table(self):
+ # TODO: memoize this
+ models_module = self.media_type + '.models'
+ __import__(models_module)
+ return sys.modules[models_module].DATA_MODEL
+
+
+class FileKeynames(Base_v0):
+ """
+ keywords for various places.
+ currently the MediaFile keys
+ """
+ __tablename__ = "core__file_keynames"
+ id = Column(Integer, primary_key=True)
+ name = Column(Unicode, unique=True)
+
+ def __repr__(self):
+ return "<FileKeyname %r: %r>" % (self.id, self.name)
+
+ @classmethod
+ def find_or_new(cls, name):
+ t = cls.query.filter_by(name=name).first()
+ if t is not None:
+ return t
+ return cls(name=name)
+
+
+class MediaFile(Base_v0):
+ """
+ TODO: Highly consider moving "name" into a new table.
+ TODO: Consider preloading said table in software
+ """
+ __tablename__ = "core__mediafiles"
+
+ media_entry = Column(
+ Integer, ForeignKey(MediaEntry.id),
+ nullable=False)
+ name_id = Column(SmallInteger, ForeignKey(FileKeynames.id), nullable=False)
+ file_path = Column(PathTupleWithSlashes)
+
+ __table_args__ = (
+ PrimaryKeyConstraint('media_entry', 'name_id'),
+ {})
+
+ def __repr__(self):
+ return "<MediaFile %s: %r>" % (self.name, self.file_path)
+
+ name_helper = relationship(FileKeynames, lazy="joined", innerjoin=True)
+ name = association_proxy('name_helper', 'name',
+ creator=FileKeynames.find_or_new
+ )
+
+
+class MediaAttachmentFile(Base_v0):
+ __tablename__ = "core__attachment_files"
+
+ id = Column(Integer, primary_key=True)
+ media_entry = Column(
+ Integer, ForeignKey(MediaEntry.id),
+ nullable=False)
+ name = Column(Unicode, nullable=False)
+ filepath = Column(PathTupleWithSlashes)
+ created = Column(DateTime, nullable=False, default=datetime.datetime.now)
+
+
+class Tag(Base_v0):
+ __tablename__ = "core__tags"
+
+ id = Column(Integer, primary_key=True)
+ slug = Column(Unicode, nullable=False, unique=True)
+
+ def __repr__(self):
+ return "<Tag %r: %r>" % (self.id, self.slug)
+
+ @classmethod
+ def find_or_new(cls, slug):
+ t = cls.query.filter_by(slug=slug).first()
+ if t is not None:
+ return t
+ return cls(slug=slug)
+
+
+class MediaTag(Base_v0):
+ __tablename__ = "core__media_tags"
+
+ id = Column(Integer, primary_key=True)
+ media_entry = Column(
+ Integer, ForeignKey(MediaEntry.id),
+ nullable=False, index=True)
+ tag = Column(Integer, ForeignKey(Tag.id), nullable=False, index=True)
+ name = Column(Unicode)
+ # created = Column(DateTime, nullable=False, default=datetime.datetime.now)
+
+ __table_args__ = (
+ UniqueConstraint('tag', 'media_entry'),
+ {})
+
+ tag_helper = relationship(Tag)
+ slug = association_proxy('tag_helper', 'slug',
+ creator=Tag.find_or_new
+ )
+
+ def __init__(self, name=None, slug=None):
+ Base_v0.__init__(self)
+ if name is not None:
+ self.name = name
+ if slug is not None:
+ self.tag_helper = Tag.find_or_new(slug)
+
+
+class MediaComment(Base_v0):
+ __tablename__ = "core__media_comments"
+
+ id = Column(Integer, primary_key=True)
+ media_entry = Column(
+ Integer, ForeignKey(MediaEntry.id), nullable=False, index=True)
+ author = Column(Integer, ForeignKey(User.id), nullable=False)
+ created = Column(DateTime, nullable=False, default=datetime.datetime.now)
+ content = Column(UnicodeText, nullable=False)
+
+ get_author = relationship(User)
+
+
+class ImageData(Base_v0):
+ __tablename__ = "image__mediadata"
+
+ # The primary key *and* reference to the main media_entry
+ media_entry = Column(Integer, ForeignKey('core__media_entries.id'),
+ primary_key=True)
+ get_media_entry = relationship("MediaEntry",
+ backref=backref("image__media_data", cascade="all, delete-orphan"))
+
+ width = Column(Integer)
+ height = Column(Integer)
+ exif_all = Column(JSONEncoded)
+ gps_longitude = Column(Float)
+ gps_latitude = Column(Float)
+ gps_altitude = Column(Float)
+ gps_direction = Column(Float)
+
+
+class VideoData(Base_v0):
+ __tablename__ = "video__mediadata"
+
+ # The primary key *and* reference to the main media_entry
+ media_entry = Column(Integer, ForeignKey('core__media_entries.id'),
+ primary_key=True)
+ get_media_entry = relationship("MediaEntry",
+ backref=backref("video__media_data", cascade="all, delete-orphan"))
+
+ width = Column(SmallInteger)
+ height = Column(SmallInteger)
+
+
+class AsciiData(Base_v0):
+ __tablename__ = "ascii__mediadata"
+
+ # The primary key *and* reference to the main media_entry
+ media_entry = Column(Integer, ForeignKey('core__media_entries.id'),
+ primary_key=True)
+ get_media_entry = relationship("MediaEntry",
+ backref=backref("ascii__media_data", cascade="all, delete-orphan"))
+
+
+class AudioData(Base_v0):
+ __tablename__ = "audio__mediadata"
+
+ # The primary key *and* reference to the main media_entry
+ media_entry = Column(Integer, ForeignKey('core__media_entries.id'),
+ primary_key=True)
+ get_media_entry = relationship("MediaEntry",
+ backref=backref("audio__media_data", cascade="all, delete-orphan"))
+
+
+######################################################
+# Special, migrations-tracking table
+#
+# Not listed in MODELS because this is special and not
+# really migrated, but used for migrations (for now)
+######################################################
+
+class MigrationData(Base_v0):
+ __tablename__ = "core__migrations"
+
+ name = Column(Unicode, primary_key=True)
+ version = Column(Integer, nullable=False, default=0)
+
+######################################################
diff --git a/mediagoblin/db/sql/open.py b/mediagoblin/db/sql/open.py
index b1f389e8..ce5f0604 100644
--- a/mediagoblin/db/sql/open.py
+++ b/mediagoblin/db/sql/open.py
@@ -18,8 +18,9 @@
from sqlalchemy import create_engine
import logging
-from mediagoblin.db.sql.base import Session
-from mediagoblin.db.sql.models import Base
+from mediagoblin.db.sql.base import Base, Session
+
+_log = logging.getLogger(__name__)
class DatabaseMaster(object):
@@ -36,14 +37,29 @@ class DatabaseMaster(object):
Session.add(obj)
Session.flush()
+ def check_session_clean(self):
+ for dummy in Session():
+ _log.warn("STRANGE: There are elements in the sql session. "
+ "Please report this and help us track this down.")
+ break
+
def reset_after_request(self):
Session.rollback()
Session.remove()
+def load_models(app_config):
+ import mediagoblin.db.sql.models
+
+ if True:
+ for media_type in app_config['media_types']:
+ _log.debug("Loading %s.models", media_type)
+ __import__(media_type + ".models")
+
+
def setup_connection_and_db_from_config(app_config):
engine = create_engine(app_config['sql_engine'])
- logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO)
+ # logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO)
Session.configure(bind=engine)
return "dummy conn", DatabaseMaster(engine)
diff --git a/mediagoblin/db/sql_switch.py b/mediagoblin/db/sql_switch.py
new file mode 100644
index 00000000..571adbdb
--- /dev/null
+++ b/mediagoblin/db/sql_switch.py
@@ -0,0 +1 @@
+use_sql = True
diff --git a/mediagoblin/edit/forms.py b/mediagoblin/edit/forms.py
index d310c18f..e8fb450e 100644
--- a/mediagoblin/edit/forms.py
+++ b/mediagoblin/edit/forms.py
@@ -55,7 +55,7 @@ class EditProfileForm(wtforms.Form):
url = wtforms.TextField(
_('Website'),
[wtforms.validators.Optional(),
- wtforms.validators.URL(message="""This address contains errors""")])
+ wtforms.validators.URL(message=_("This address contains errors"))])
class EditAccountForm(wtforms.Form):
diff --git a/mediagoblin/edit/views.py b/mediagoblin/edit/views.py
index b7954cb5..59f6824f 100644
--- a/mediagoblin/edit/views.py
+++ b/mediagoblin/edit/views.py
@@ -14,10 +14,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-import uuid
-
from webob import exc
-from string import split
from cgi import FieldStorage
from datetime import datetime
@@ -33,9 +30,7 @@ from mediagoblin.decorators import require_active_login, get_user_media_entry
from mediagoblin.tools.response import render_to_response, redirect
from mediagoblin.tools.translate import pass_to_ugettext as _
from mediagoblin.tools.text import (
- clean_html, convert_to_tag_list_of_dicts,
- media_tags_as_string)
-from mediagoblin.tools.licenses import SUPPORTED_LICENSES
+ convert_to_tag_list_of_dicts, media_tags_as_string)
from mediagoblin.db.util import check_media_slug_used
diff --git a/mediagoblin/gmg_commands/__init__.py b/mediagoblin/gmg_commands/__init__.py
index 054e2616..4a608a69 100644
--- a/mediagoblin/gmg_commands/__init__.py
+++ b/mediagoblin/gmg_commands/__init__.py
@@ -28,7 +28,8 @@ SUBCOMMAND_MAP = {
'migrate': {
'setup': 'mediagoblin.gmg_commands.migrate:migrate_parser_setup',
'func': 'mediagoblin.gmg_commands.migrate:migrate',
- 'help': 'Apply all unapplied bulk migrations to the database'},
+ 'help': ('Migrate your Mongo database. '
+ '[DEPRECATED!] use convert_mongo_to_sql and dbupdate.')},
'adduser': {
'setup': 'mediagoblin.gmg_commands.users:adduser_parser_setup',
'func': 'mediagoblin.gmg_commands.users:adduser',
@@ -41,18 +42,6 @@ SUBCOMMAND_MAP = {
'setup': 'mediagoblin.gmg_commands.users:changepw_parser_setup',
'func': 'mediagoblin.gmg_commands.users:changepw',
'help': 'Makes admin an user'},
- 'wipealldata': {
- 'setup': 'mediagoblin.gmg_commands.wipealldata:wipe_parser_setup',
- 'func': 'mediagoblin.gmg_commands.wipealldata:wipe',
- 'help': 'Wipes **all** the data for this MediaGoblin instance'},
- 'env_export': {
- 'setup': 'mediagoblin.gmg_commands.import_export:import_export_parse_setup',
- 'func': 'mediagoblin.gmg_commands.import_export:env_export',
- 'help': 'Exports the data for this MediaGoblin instance'},
- 'env_import': {
- 'setup': 'mediagoblin.gmg_commands.import_export:import_export_parse_setup',
- 'func': 'mediagoblin.gmg_commands.import_export:env_import',
- 'help': 'Exports the data for this MediaGoblin instance'},
'dbupdate': {
'setup': 'mediagoblin.gmg_commands.dbupdate:dbupdate_parse_setup',
'func': 'mediagoblin.gmg_commands.dbupdate:dbupdate',
@@ -61,6 +50,20 @@ SUBCOMMAND_MAP = {
'setup': 'mediagoblin.gmg_commands.mongosql:mongosql_parser_setup',
'func': 'mediagoblin.gmg_commands.mongosql:mongosql',
'help': 'Convert Mongo DB data to SQL DB data'},
+
+ ## These might be useful, mayyyybe, but don't really work anymore
+ ## due to mongo change and the "versatility" of sql options.
+ ##
+ ## For now, commenting out. Might re-enable soonish?
+ #
+ # 'env_export': {
+ # 'setup': 'mediagoblin.gmg_commands.import_export:import_export_parse_setup',
+ # 'func': 'mediagoblin.gmg_commands.import_export:env_export',
+ # 'help': 'Exports the data for this MediaGoblin instance'},
+ # 'env_import': {
+ # 'setup': 'mediagoblin.gmg_commands.import_export:import_export_parse_setup',
+ # 'func': 'mediagoblin.gmg_commands.import_export:env_import',
+ # 'help': 'Imports the data for this MediaGoblin instance'},
}
diff --git a/mediagoblin/gmg_commands/dbupdate.py b/mediagoblin/gmg_commands/dbupdate.py
index 27698170..dc36be82 100644
--- a/mediagoblin/gmg_commands/dbupdate.py
+++ b/mediagoblin/gmg_commands/dbupdate.py
@@ -17,8 +17,7 @@
from sqlalchemy.orm import sessionmaker
from mediagoblin.db.sql.open import setup_connection_and_db_from_config
-from mediagoblin.db.sql.util import (
- MigrationManager, assure_migrations_table_setup)
+from mediagoblin.db.sql.util import MigrationManager
from mediagoblin.init import setup_global_and_app_config
from mediagoblin.tools.common import import_component
@@ -65,14 +64,13 @@ def gather_database_data(media_types):
return managed_dbdata
-def dbupdate(args):
+def run_dbupdate(app_config):
"""
Initialize or migrate the database as specified by the config file.
Will also initialize or migrate all extensions (media types, and
in the future, plugins)
"""
- globa_config, app_config = setup_global_and_app_config(args.conf_file)
# Gather information from all media managers / projects
dbdatas = gather_database_data(app_config['media_types'])
@@ -87,3 +85,8 @@ def dbupdate(args):
for dbdata in dbdatas:
migration_manager = dbdata.make_migration_manager(Session())
migration_manager.init_or_migrate()
+
+
+def dbupdate(args):
+ global_config, app_config = setup_global_and_app_config(args.conf_file)
+ run_dbupdate(app_config)
diff --git a/mediagoblin/gmg_commands/import_export.py b/mediagoblin/gmg_commands/import_export.py
index 20cc8fe4..72ebd8a8 100644
--- a/mediagoblin/gmg_commands/import_export.py
+++ b/mediagoblin/gmg_commands/import_export.py
@@ -61,13 +61,12 @@ def _import_media(db, args):
args._cache_path['media'])
# TODO: Add import of queue files
- queue_cache = BasicFileStorage(
- args._cache_path['queue'])
+ queue_cache = BasicFileStorage(args._cache_path['queue'])
for entry in db.MediaEntry.find():
for name, path in entry.media_files.items():
_log.info('Importing: {0} - {1}'.format(
- entry.title,
+ entry.title.encode('ascii', 'replace'),
name))
media_file = mg_globals.public_store.get_file(path, mode='wb')
@@ -203,8 +202,7 @@ def _export_media(db, args):
args._cache_path['media'])
# TODO: Add export of queue files
- queue_cache = BasicFileStorage(
- args._cache_path['queue'])
+ queue_cache = BasicFileStorage(args._cache_path['queue'])
for entry in db.MediaEntry.find():
for name, path in entry.media_files.items():
diff --git a/mediagoblin/gmg_commands/migrate.py b/mediagoblin/gmg_commands/migrate.py
index af541786..b915a528 100644
--- a/mediagoblin/gmg_commands/migrate.py
+++ b/mediagoblin/gmg_commands/migrate.py
@@ -16,13 +16,8 @@
import sys
-from mediagoblin.db.mongo import util as db_util
-from mediagoblin.db.mongo.open import setup_connection_and_db_from_config
from mediagoblin.init import setup_global_and_app_config
-# This MUST be imported so as to set up the appropriate migrations!
-from mediagoblin.db.mongo import migrations
-
def migrate_parser_setup(subparser):
pass
@@ -45,6 +40,12 @@ def migrate(args):
def run_migrate(conf_file):
+ # This MUST be imported so as to set up the appropriate migrations!
+ from mediagoblin.db.mongo import migrations
+
+ from mediagoblin.db.mongo import util as db_util
+ from mediagoblin.db.mongo.open import setup_connection_and_db_from_config
+
global_config, app_config = setup_global_and_app_config(conf_file)
connection, db = setup_connection_and_db_from_config(
diff --git a/mediagoblin/gmg_commands/wipealldata.py b/mediagoblin/gmg_commands/wipealldata.py
deleted file mode 100644
index 3081bbc0..00000000
--- a/mediagoblin/gmg_commands/wipealldata.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# 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 <http://www.gnu.org/licenses/>.
-
-import sys
-import pymongo
-import sys
-import os
-import shutil
-
-
-def wipe_parser_setup(subparser):
- pass
-
-
-def wipe(args):
- print "*** WARNING! ***"
- print ""
- print "Running this will destroy your mediagoblin database,"
- print "remove all your media files in user_dev/, etc."
- print ""
- print "ALSO: This command is currently a hack and will only remove"
- print " things properly on the default setup! If you've customized"
- print " your mediagoblin configs, it won't work (for now)."
-
- drop_it = raw_input(
- 'Are you **SURE** you want to destroy your environment? '
- '(if so, type "yes")> ')
-
- if not drop_it == 'yes':
- return
-
- print "nixing data in mongodb...."
- conn = pymongo.Connection()
- conn.drop_database('mediagoblin')
-
- for directory in [os.path.join(os.getcwd(), "user_dev", "media"),
- os.path.join(os.getcwd(), "user_dev", "beaker")]:
- if os.path.exists(directory):
- print "nixing %s...." % directory
- shutil.rmtree(directory)
-
- print "removed all your stuff!"
diff --git a/mediagoblin/i18n/ar/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/ar/LC_MESSAGES/mediagoblin.mo
index b23b0be4..5299a97b 100644
--- a/mediagoblin/i18n/ar/LC_MESSAGES/mediagoblin.mo
+++ b/mediagoblin/i18n/ar/LC_MESSAGES/mediagoblin.mo
Binary files differ
diff --git a/mediagoblin/i18n/ar/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/ar/LC_MESSAGES/mediagoblin.po
index 578be678..7a400a32 100644
--- a/mediagoblin/i18n/ar/LC_MESSAGES/mediagoblin.po
+++ b/mediagoblin/i18n/ar/LC_MESSAGES/mediagoblin.po
@@ -9,9 +9,9 @@
msgid ""
msgstr ""
"Project-Id-Version: GNU MediaGoblin\n"
-"Report-Msgid-Bugs-To: http://bugs.foocorp.net/projects/mediagoblin/issues\n"
-"POT-Creation-Date: 2012-01-29 13:31-0600\n"
-"PO-Revision-Date: 2012-01-29 19:29+0000\n"
+"Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n"
+"POT-Creation-Date: 2012-06-01 16:32-0500\n"
+"PO-Revision-Date: 2012-06-01 21:30+0000\n"
"Last-Translator: cwebber <cwebber@dustycloud.org>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
@@ -21,10 +21,6 @@ msgstr ""
"Language: ar\n"
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5\n"
-#: mediagoblin/processing.py:143
-msgid "Invalid file given for media type."
-msgstr ""
-
#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41
msgid "Username"
msgstr "اسم المستخدم"
@@ -37,60 +33,64 @@ msgstr "كلمة السر"
msgid "Email address"
msgstr "عنوان البريد الإلكتروني"
+#: mediagoblin/auth/forms.py:51
+msgid "Username or email"
+msgstr ""
+
+#: mediagoblin/auth/forms.py:58
+msgid "Incorrect input"
+msgstr ""
+
#: mediagoblin/auth/views.py:55
msgid "Sorry, registration is disabled on this instance."
msgstr "عÙوًا، التسجيل غير متاح هنا."
-#: mediagoblin/auth/views.py:73
+#: mediagoblin/auth/views.py:75
msgid "Sorry, a user with that name already exists."
msgstr "عذرًا، لقد اختار مستخدم آخر هذا الاسم."
-#: mediagoblin/auth/views.py:77
+#: mediagoblin/auth/views.py:79
msgid "Sorry, a user with that email address already exists."
msgstr ""
-#: mediagoblin/auth/views.py:180
+#: mediagoblin/auth/views.py:182
msgid ""
"Your email address has been verified. You may now login, edit your profile, "
"and submit images!"
-msgstr ""
-"تم التحقق من بريدك الإلكتروني. يمكنك الآن الولوج، وتحرير ملÙÙƒ الشخصي، ونشر "
-"الصور!"
+msgstr "تم التحقق من بريدك الإلكتروني. يمكنك الآن الولوج، وتحرير ملÙÙƒ الشخصي، ونشر الصور!"
-#: mediagoblin/auth/views.py:186
+#: mediagoblin/auth/views.py:188
msgid "The verification key or user id is incorrect"
msgstr "Ù…ÙØªØ§Ø­ التحقق أو معر٠المستخدم خاطئ"
-#: mediagoblin/auth/views.py:204
+#: 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:212
+#: mediagoblin/auth/views.py:214
msgid "You've already verified your email address!"
msgstr ""
-#: mediagoblin/auth/views.py:225
+#: mediagoblin/auth/views.py:227
msgid "Resent your verification email."
msgstr "أعدنا إرسال رسالة التحقق."
-#: mediagoblin/auth/views.py:260
+#: mediagoblin/auth/views.py:263
msgid ""
"An email has been sent with instructions on how to change your password."
msgstr ""
-#: mediagoblin/auth/views.py:270
+#: mediagoblin/auth/views.py:273
msgid ""
"Could not send password recovery email as your username is inactive or your "
"account's email address has not been verified."
-msgstr ""
-"تعذر إرسال رسالة استعادة كلمة السر لأن اسم المستخدم معطل أو لأننا لم نتحقق "
-"من بريدك الإلكتروني."
+msgstr "تعذر إرسال رسالة استعادة كلمة السر لأن اسم المستخدم معطل أو لأننا لم نتحقق من بريدك الإلكتروني."
-#: mediagoblin/auth/views.py:282
+#: mediagoblin/auth/views.py:285
msgid "Couldn't find someone with that username or email."
msgstr ""
-#: mediagoblin/auth/views.py:330
+#: mediagoblin/auth/views.py:333
msgid "You can now log in using your new password."
msgstr ""
@@ -133,6 +133,7 @@ msgid ""
msgstr ""
#: mediagoblin/edit/forms.py:44 mediagoblin/submit/forms.py:41
+#: mediagoblin/templates/mediagoblin/utils/license.html:20
msgid "License"
msgstr ""
@@ -144,6 +145,10 @@ msgstr "السيرة"
msgid "Website"
msgstr "الموقع الإلكتروني"
+#: mediagoblin/edit/forms.py:58
+msgid "This address contains errors"
+msgstr ""
+
#: mediagoblin/edit/forms.py:63
msgid "Old password"
msgstr ""
@@ -156,47 +161,48 @@ msgstr ""
msgid "New password"
msgstr ""
-#: mediagoblin/edit/views.py:68
+#: mediagoblin/edit/views.py:67
msgid "An entry with that slug already exists for this user."
msgstr "يوجد مل٠آخر بهذا المسار لدى هذى المستخدم."
-#: mediagoblin/edit/views.py:92
+#: mediagoblin/edit/views.py:88
msgid "You are editing another user's media. Proceed with caution."
msgstr "أنت تحرّر وسائط مستخدم آخر. كن حذرًا أثناء العملية."
-#: mediagoblin/edit/views.py:162
+#: mediagoblin/edit/views.py:158
msgid "You are editing a user's profile. Proceed with caution."
msgstr "أنت تحرّر مل٠مستخدم آخر. كن حذرًا أثناء العملية."
-#: mediagoblin/edit/views.py:180
+#: mediagoblin/edit/views.py:174
msgid "Profile changes saved"
msgstr ""
-#: mediagoblin/edit/views.py:206
+#: mediagoblin/edit/views.py:200
msgid "Wrong password"
msgstr ""
-#: mediagoblin/edit/views.py:222
+#: mediagoblin/edit/views.py:216
msgid "Account settings saved"
msgstr ""
-#: mediagoblin/media_types/__init__.py:77
-msgid "Could not extract any file extension from \"{filename}\""
+#: mediagoblin/media_types/__init__.py:60
+#: mediagoblin/media_types/__init__.py:120
+msgid "Sorry, I don't support that file type :("
msgstr ""
-#: mediagoblin/media_types/__init__.py:88
-msgid "Sorry, I don't support that file type :("
+#: mediagoblin/processing/__init__.py:127
+msgid "Invalid file given for media type."
msgstr ""
#: mediagoblin/submit/forms.py:26
msgid "File"
msgstr "الملÙ"
-#: mediagoblin/submit/views.py:54
+#: mediagoblin/submit/views.py:56
msgid "You must provide a file."
msgstr "يجب أن تضع ملÙًا."
-#: mediagoblin/submit/views.py:158
+#: mediagoblin/submit/views.py:163
msgid "Woohoo! Submitted!"
msgstr "يا سلام! Ù†ÙØ´Ø±ÙŽØª!"
@@ -216,36 +222,46 @@ msgstr "يبدو أنه لا توجد ØµÙØ­Ø© ÙÙŠ العنوان. عذرًا!"
msgid ""
"If you're sure the address is correct, maybe the page you're looking for has"
" been moved or deleted."
-msgstr ""
-"إن كنت متأكدًا من صحة العنوان ÙØ±Ø¨Ù…ا تكون Ø§Ù„ØµÙØ­Ø© التي تريدها Ù†Ùقلت أو Ø­ÙØ°Ùت."
+msgstr "إن كنت متأكدًا من صحة العنوان ÙØ±Ø¨Ù…ا تكون Ø§Ù„ØµÙØ­Ø© التي تريدها Ù†Ùقلت أو Ø­ÙØ°Ùت."
-#: mediagoblin/templates/mediagoblin/base.html:46
+#: mediagoblin/templates/mediagoblin/base.html:47
msgid "MediaGoblin logo"
msgstr "شعار ميدياغوبلن"
-#: mediagoblin/templates/mediagoblin/base.html:51
-#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
-msgid "Add media"
-msgstr "أض٠وسائط"
-
-#: mediagoblin/templates/mediagoblin/base.html:62
+#: mediagoblin/templates/mediagoblin/base.html:57
msgid "Verify your email!"
msgstr ""
-#: mediagoblin/templates/mediagoblin/base.html:69
-msgid "log out"
+#: mediagoblin/templates/mediagoblin/base.html:63
+msgid "+ Add media"
msgstr ""
-#: mediagoblin/templates/mediagoblin/base.html:72
-#: mediagoblin/templates/mediagoblin/auth/login.html:27
-#: mediagoblin/templates/mediagoblin/auth/login.html:45
+#: mediagoblin/templates/mediagoblin/base.html:65
+msgid "View your profile"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:66
+msgid "Log out"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:71
+#: mediagoblin/templates/mediagoblin/auth/login.html:32
+#: mediagoblin/templates/mediagoblin/auth/login.html:50
msgid "Log in"
msgstr "Ù„ÙØ¬"
-#: mediagoblin/templates/mediagoblin/base.html:84
+#: mediagoblin/templates/mediagoblin/base.html:85
msgid ""
"Powered by <a href=\"http://mediagoblin.org\">MediaGoblin</a>, a <a "
-"href=\"http://gnu.org/\">GNU</a> project"
+"href=\"http://gnu.org/\">GNU</a> project."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:88
+#, python-format
+msgid ""
+"Released under the <a "
+"href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a "
+"href=\"%(source_link)s\">Source code</a> available."
msgstr ""
#: mediagoblin/templates/mediagoblin/root.html:24
@@ -312,28 +328,21 @@ msgid ""
"\n"
"If you think this is an error, just ignore this email and continue being\n"
"a happy goblin!"
-msgstr ""
-"مرحبًا يا %(username)s،\n"
-"\n"
-"إن أردت تغيير كلمة سرك ÙÙŠ غنو ميدياغوبلن ÙØ§Ùتح الوصلة التالية ÙÙŠ Ù…ØªØµÙØ­Ùƒ:\n"
-"\n"
-"%(verification_url)s\n"
-"\n"
-"إن كنت ترى أن هذه الرسالة وصلتك خطأً ÙØªØ¬Ø§Ù‡Ù„ها واستمتع بحياتك!"
+msgstr "مرحبًا يا %(username)sØŒ\n\nإن أردت تغيير كلمة سرك ÙÙŠ غنو ميدياغوبلن ÙØ§Ùتح الوصلة التالية ÙÙŠ Ù…ØªØµÙØ­Ùƒ:\n\n%(verification_url)s\n\nإن كنت ترى أن هذه الرسالة وصلتك خطأً ÙØªØ¬Ø§Ù‡Ù„ها واستمتع بحياتك!"
-#: mediagoblin/templates/mediagoblin/auth/login.html:30
+#: mediagoblin/templates/mediagoblin/auth/login.html:35
msgid "Logging in failed!"
msgstr "ÙØ´Ù„ الولوج!"
-#: mediagoblin/templates/mediagoblin/auth/login.html:35
+#: mediagoblin/templates/mediagoblin/auth/login.html:40
msgid "Don't have an account yet?"
msgstr "ألا تملك حسابًا بعد؟"
-#: mediagoblin/templates/mediagoblin/auth/login.html:36
+#: mediagoblin/templates/mediagoblin/auth/login.html:41
msgid "Create one here!"
msgstr "أنشئ حسابًا هنا!"
-#: mediagoblin/templates/mediagoblin/auth/login.html:42
+#: mediagoblin/templates/mediagoblin/auth/login.html:47
msgid "Forgot your password?"
msgstr "أنسيت كلمة سرك؟"
@@ -354,13 +363,7 @@ msgid ""
"your web browser:\n"
"\n"
"%(verification_url)s"
-msgstr ""
-"أهلًا يا %(username)s،\n"
-"\n"
-"Ø§ÙØªØ­ الرابط التالي\n"
-"ÙÙŠ Ù…ØªØµÙØ­Ùƒ Ù„ØªÙØ¹ÙŠÙ„ حسابك ÙÙŠ غنو ميدياغوبلن:\n"
-"\n"
-"%(verification_url)s"
+msgstr "أهلًا يا %(username)sØŒ\n\nØ§ÙØªØ­ الرابط التالي\nÙÙŠ Ù…ØªØµÙØ­Ùƒ Ù„ØªÙØ¹ÙŠÙ„ حسابك ÙÙŠ غنو ميدياغوبلن:\n\n%(verification_url)s"
#: mediagoblin/templates/mediagoblin/edit/edit.html:29
#, python-format
@@ -395,18 +398,44 @@ msgid "Media tagged with: %(tag_name)s"
msgstr ""
#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:46
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:53
msgid "Original"
msgstr ""
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:33
+#: 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 <a href=\"http://getfirefox.com\">\n"
+"\t http://getfirefox.com</a>!"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:56
+msgid "Download"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:60
+msgid "original file"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:63
+msgid "WebM file (Vorbis codec)"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:40
msgid ""
"Sorry, this video will not work because \n"
"\t your web browser does not support HTML5 \n"
"\t video."
msgstr ""
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:36
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:43
msgid ""
"You can get a modern web browser that \n"
"\t can play this video at <a href=\"http://getfirefox.com\">\n"
@@ -431,55 +460,49 @@ msgstr ""
msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media"
msgstr "وسائط <a href=\"%(user_url)s\">%(username)s</a>"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:72
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:46
#, python-format
-msgid "Added on %(date)s."
-msgstr ""
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:81
-msgid "Edit"
-msgstr ""
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:85
-msgid "Delete"
+msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:67
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:73
#, python-format
-msgid "%(comment_count)s comment"
+msgid "Image for %(media_title)s"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:93
-#, python-format
-msgid "%(comment_count)s comments"
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:87
+msgid "Edit"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:95
-msgid "No comments yet."
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
+msgid "Delete"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:103
-msgid "Add one"
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:124
+msgid "Add a comment"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:112
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:131
msgid ""
"You can use <a "
"href=\"http://daringfireball.net/projects/markdown/basics\">Markdown</a> for"
" formatting."
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:116
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:135
msgid "Add this comment"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:138
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:154
msgid "at"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:153
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:174
#, python-format
-msgid "<p>â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a></p>"
+msgid ""
+"<h3>Added on</h3>\n"
+" <p>%(date)s</p>"
msgstr ""
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30
@@ -488,8 +511,8 @@ msgid "Really delete %(title)s?"
msgstr "أتود حقًا حذ٠%(title)s?"
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:50
-msgid "Delete Permanently"
-msgstr "احذ٠نهائيًا"
+msgid "Delete permanently"
+msgstr ""
#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:22
msgid "Media processing panel"
@@ -555,9 +578,7 @@ msgstr "سجّل أحدهم حسابًا بهذا الاسم، ولكننا با
msgid ""
"If you are that person but you've lost your verification email, you can <a "
"href=\"%(login_url)s\">log in</a> and resend it."
-msgstr ""
-"إن كنت أنت ذلك الشخص لكنك Ùقدت رسالة التحقق، يمكنك <a "
-"href=\"%(login_url)s\">الولوج</a> وإعادة إرسالها."
+msgstr "إن كنت أنت ذلك الشخص لكنك Ùقدت رسالة التحقق، يمكنك <a href=\"%(login_url)s\">الولوج</a> وإعادة إرسالها."
#: mediagoblin/templates/mediagoblin/user_pages/user.html:96
msgid "Here's a spot to tell others about yourself."
@@ -587,6 +608,10 @@ msgid ""
"anything yet."
msgstr "هنا ستظهر وسائطك، ولكن يبدو أنك لم تض٠شيئًا بعد."
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
+msgid "Add media"
+msgstr "أض٠وسائط"
+
#: mediagoblin/templates/mediagoblin/user_pages/user.html:163
#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72
msgid "There doesn't seem to be any media here yet..."
@@ -600,8 +625,13 @@ msgstr ""
msgid "Atom feed"
msgstr ""
-#: mediagoblin/templates/mediagoblin/utils/license.html:21
-msgid "License:"
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:25
+msgid "Location"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:38
+#, python-format
+msgid "View on <a href=\"%(osm_url)s\">OpenStreetMap</a>"
msgstr ""
#: mediagoblin/templates/mediagoblin/utils/license.html:25
@@ -620,25 +650,21 @@ msgstr ""
msgid "Go to page:"
msgstr ""
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:27
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:32
+#: 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:38
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:43
+#: 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 "View more media tagged with"
+msgid "Tagged with"
msgstr ""
-#: mediagoblin/templates/mediagoblin/utils/tags.html:25
-msgid "or"
-msgstr ""
-
-#: mediagoblin/tools/exif.py:68
+#: mediagoblin/tools/exif.py:75
msgid "Could not read the image file."
msgstr ""
@@ -646,24 +672,22 @@ msgstr ""
msgid "I am sure I want to delete this"
msgstr "أنا متأكد من رغبتي بحذ٠هذا العمل"
-#: mediagoblin/user_pages/views.py:155
+#: mediagoblin/user_pages/views.py:153
msgid "Oops, your comment was empty."
msgstr ""
-#: mediagoblin/user_pages/views.py:161
+#: mediagoblin/user_pages/views.py:159
msgid "Your comment has been posted!"
msgstr ""
-#: mediagoblin/user_pages/views.py:183
+#: mediagoblin/user_pages/views.py:185
msgid "You deleted the media."
msgstr ""
-#: mediagoblin/user_pages/views.py:190
+#: mediagoblin/user_pages/views.py:192
msgid "The media was not deleted because you didn't check that you were sure."
msgstr ""
-#: mediagoblin/user_pages/views.py:198
+#: mediagoblin/user_pages/views.py:200
msgid "You are about to delete another user's media. Proceed with caution."
msgstr "أنت على وشك حذ٠وسائط مستخدم آخر. كن حذرًا أثناء العملية."
-
-
diff --git a/mediagoblin/i18n/ca/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/ca/LC_MESSAGES/mediagoblin.mo
index 6fdb7cbf..a83cf921 100644
--- a/mediagoblin/i18n/ca/LC_MESSAGES/mediagoblin.mo
+++ b/mediagoblin/i18n/ca/LC_MESSAGES/mediagoblin.mo
Binary files differ
diff --git a/mediagoblin/i18n/ca/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/ca/LC_MESSAGES/mediagoblin.po
index 0c956b9b..be8c5e9a 100644
--- a/mediagoblin/i18n/ca/LC_MESSAGES/mediagoblin.po
+++ b/mediagoblin/i18n/ca/LC_MESSAGES/mediagoblin.po
@@ -8,9 +8,9 @@
msgid ""
msgstr ""
"Project-Id-Version: GNU MediaGoblin\n"
-"Report-Msgid-Bugs-To: http://bugs.foocorp.net/projects/mediagoblin/issues\n"
-"POT-Creation-Date: 2012-01-29 13:31-0600\n"
-"PO-Revision-Date: 2012-01-29 19:29+0000\n"
+"Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n"
+"POT-Creation-Date: 2012-06-01 16:32-0500\n"
+"PO-Revision-Date: 2012-06-01 21:30+0000\n"
"Last-Translator: cwebber <cwebber@dustycloud.org>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
@@ -20,10 +20,6 @@ msgstr ""
"Language: ca\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
-#: mediagoblin/processing.py:143
-msgid "Invalid file given for media type."
-msgstr "Aquest tipus de fitxer no és vàlid."
-
#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41
msgid "Username"
msgstr "Nom d'usuari"
@@ -36,59 +32,64 @@ msgstr "Contrasenya"
msgid "Email address"
msgstr "Adreça electrònica"
+#: mediagoblin/auth/forms.py:51
+msgid "Username or email"
+msgstr ""
+
+#: mediagoblin/auth/forms.py:58
+msgid "Incorrect input"
+msgstr ""
+
#: mediagoblin/auth/views.py:55
msgid "Sorry, registration is disabled on this instance."
msgstr "Ho sentim, el registre està desactivat en aquest cas."
-#: mediagoblin/auth/views.py:73
+#: mediagoblin/auth/views.py:75
msgid "Sorry, a user with that name already exists."
msgstr "Lamentablement aquest usuari ja existeix."
-#: mediagoblin/auth/views.py:77
+#: mediagoblin/auth/views.py:79
msgid "Sorry, a user with that email address already exists."
msgstr ""
-#: mediagoblin/auth/views.py:180
+#: mediagoblin/auth/views.py:182
msgid ""
"Your email address has been verified. You may now login, edit your profile, "
"and submit images!"
-msgstr ""
-"Ja s'ha verificat la vostra adreça electrònica. Ara podeu entrar, editar el "
-"vostre perfil i penjar imatge!"
+msgstr "Ja s'ha verificat la vostra adreça electrònica. Ara podeu entrar, editar el vostre perfil i penjar imatge!"
-#: mediagoblin/auth/views.py:186
+#: mediagoblin/auth/views.py:188
msgid "The verification key or user id is incorrect"
-msgstr ""
-"La clau de verificació o la identificació de l'usuari no són correctes."
+msgstr "La clau de verificació o la identificació de l'usuari no són correctes."
-#: mediagoblin/auth/views.py:204
+#: 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:212
+#: mediagoblin/auth/views.py:214
msgid "You've already verified your email address!"
msgstr ""
-#: mediagoblin/auth/views.py:225
+#: mediagoblin/auth/views.py:227
msgid "Resent your verification email."
msgstr "Torna'm a enviar el correu de verificació"
-#: mediagoblin/auth/views.py:260
+#: mediagoblin/auth/views.py:263
msgid ""
"An email has been sent with instructions on how to change your password."
msgstr ""
-#: mediagoblin/auth/views.py:270
+#: mediagoblin/auth/views.py:273
msgid ""
"Could not send password recovery email as your username is inactive or your "
"account's email address has not been verified."
msgstr ""
-#: mediagoblin/auth/views.py:282
+#: mediagoblin/auth/views.py:285
msgid "Couldn't find someone with that username or email."
msgstr ""
-#: mediagoblin/auth/views.py:330
+#: mediagoblin/auth/views.py:333
msgid "You can now log in using your new password."
msgstr ""
@@ -131,6 +132,7 @@ msgid ""
msgstr ""
#: mediagoblin/edit/forms.py:44 mediagoblin/submit/forms.py:41
+#: mediagoblin/templates/mediagoblin/utils/license.html:20
msgid "License"
msgstr ""
@@ -142,6 +144,10 @@ msgstr "Biografia"
msgid "Website"
msgstr "Lloc web"
+#: mediagoblin/edit/forms.py:58
+msgid "This address contains errors"
+msgstr ""
+
#: mediagoblin/edit/forms.py:63
msgid "Old password"
msgstr ""
@@ -154,47 +160,48 @@ msgstr ""
msgid "New password"
msgstr ""
-#: mediagoblin/edit/views.py:68
+#: mediagoblin/edit/views.py:67
msgid "An entry with that slug already exists for this user."
msgstr ""
-#: mediagoblin/edit/views.py:92
+#: mediagoblin/edit/views.py:88
msgid "You are editing another user's media. Proceed with caution."
msgstr "Esteu editant fitxers d'un altre usuari. Aneu amb compte."
-#: mediagoblin/edit/views.py:162
+#: mediagoblin/edit/views.py:158
msgid "You are editing a user's profile. Proceed with caution."
msgstr "Esteu editant el perfil d'un usuari. Aneu amb compte"
-#: mediagoblin/edit/views.py:180
+#: mediagoblin/edit/views.py:174
msgid "Profile changes saved"
msgstr ""
-#: mediagoblin/edit/views.py:206
+#: mediagoblin/edit/views.py:200
msgid "Wrong password"
msgstr ""
-#: mediagoblin/edit/views.py:222
+#: mediagoblin/edit/views.py:216
msgid "Account settings saved"
msgstr ""
-#: mediagoblin/media_types/__init__.py:77
-msgid "Could not extract any file extension from \"{filename}\""
-msgstr ""
-
-#: mediagoblin/media_types/__init__.py:88
+#: mediagoblin/media_types/__init__.py:60
+#: mediagoblin/media_types/__init__.py:120
msgid "Sorry, I don't support that file type :("
msgstr ""
+#: mediagoblin/processing/__init__.py:127
+msgid "Invalid file given for media type."
+msgstr "Aquest tipus de fitxer no és vàlid."
+
#: mediagoblin/submit/forms.py:26
msgid "File"
msgstr "Fitxer"
-#: mediagoblin/submit/views.py:54
+#: mediagoblin/submit/views.py:56
msgid "You must provide a file."
msgstr "Heu d'escollir un fitxer."
-#: mediagoblin/submit/views.py:158
+#: mediagoblin/submit/views.py:163
msgid "Woohoo! Submitted!"
msgstr "Visca! S'ha enviat!"
@@ -214,37 +221,46 @@ msgstr "Sembla que no hi ha cap pàgina en aquesta adreça. Ho sentim."
msgid ""
"If you're sure the address is correct, maybe the page you're looking for has"
" been moved or deleted."
-msgstr ""
-"Si esteu convençut que l'adreça és correcta, pot ser que la pàgina que "
-"cerqueu s'hagi canviat d'ubicació o s'hagi eliminat."
+msgstr "Si esteu convençut que l'adreça és correcta, pot ser que la pàgina que cerqueu s'hagi canviat d'ubicació o s'hagi eliminat."
-#: mediagoblin/templates/mediagoblin/base.html:46
+#: mediagoblin/templates/mediagoblin/base.html:47
msgid "MediaGoblin logo"
msgstr "Logo de mediagoblin"
-#: mediagoblin/templates/mediagoblin/base.html:51
-#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
-msgid "Add media"
-msgstr "Tots els fitxers"
-
-#: mediagoblin/templates/mediagoblin/base.html:62
+#: mediagoblin/templates/mediagoblin/base.html:57
msgid "Verify your email!"
msgstr ""
-#: mediagoblin/templates/mediagoblin/base.html:69
-msgid "log out"
+#: mediagoblin/templates/mediagoblin/base.html:63
+msgid "+ Add media"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:65
+msgid "View your profile"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:66
+msgid "Log out"
msgstr ""
-#: mediagoblin/templates/mediagoblin/base.html:72
-#: mediagoblin/templates/mediagoblin/auth/login.html:27
-#: mediagoblin/templates/mediagoblin/auth/login.html:45
+#: mediagoblin/templates/mediagoblin/base.html:71
+#: mediagoblin/templates/mediagoblin/auth/login.html:32
+#: mediagoblin/templates/mediagoblin/auth/login.html:50
msgid "Log in"
msgstr "Entra"
-#: mediagoblin/templates/mediagoblin/base.html:84
+#: mediagoblin/templates/mediagoblin/base.html:85
msgid ""
"Powered by <a href=\"http://mediagoblin.org\">MediaGoblin</a>, a <a "
-"href=\"http://gnu.org/\">GNU</a> project"
+"href=\"http://gnu.org/\">GNU</a> project."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:88
+#, python-format
+msgid ""
+"Released under the <a "
+"href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a "
+"href=\"%(source_link)s\">Source code</a> available."
msgstr ""
#: mediagoblin/templates/mediagoblin/root.html:24
@@ -313,19 +329,19 @@ msgid ""
"a happy goblin!"
msgstr ""
-#: mediagoblin/templates/mediagoblin/auth/login.html:30
+#: mediagoblin/templates/mediagoblin/auth/login.html:35
msgid "Logging in failed!"
msgstr "Inici de sessió ha fallat!"
-#: mediagoblin/templates/mediagoblin/auth/login.html:35
+#: mediagoblin/templates/mediagoblin/auth/login.html:40
msgid "Don't have an account yet?"
msgstr "Encara no teniu un compte?"
-#: mediagoblin/templates/mediagoblin/auth/login.html:36
+#: mediagoblin/templates/mediagoblin/auth/login.html:41
msgid "Create one here!"
msgstr "Creeu-ne un aquí!"
-#: mediagoblin/templates/mediagoblin/auth/login.html:42
+#: mediagoblin/templates/mediagoblin/auth/login.html:47
msgid "Forgot your password?"
msgstr ""
@@ -346,13 +362,7 @@ msgid ""
"your web browser:\n"
"\n"
"%(verification_url)s"
-msgstr ""
-"Hi %(username)s,\n"
-"\n"
-"to activate your GNU MediaGoblin account, open the following URL in\n"
-"your web browser:\n"
-"\n"
-"%(verification_url)s"
+msgstr "Hi %(username)s,\n\nto activate your GNU MediaGoblin account, open the following URL in\nyour web browser:\n\n%(verification_url)s"
#: mediagoblin/templates/mediagoblin/edit/edit.html:29
#, python-format
@@ -387,18 +397,44 @@ msgid "Media tagged with: %(tag_name)s"
msgstr ""
#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:46
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:53
msgid "Original"
msgstr ""
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:33
+#: 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 <a href=\"http://getfirefox.com\">\n"
+"\t http://getfirefox.com</a>!"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:56
+msgid "Download"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:60
+msgid "original file"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:63
+msgid "WebM file (Vorbis codec)"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:40
msgid ""
"Sorry, this video will not work because \n"
"\t your web browser does not support HTML5 \n"
"\t video."
msgstr ""
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:36
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:43
msgid ""
"You can get a modern web browser that \n"
"\t can play this video at <a href=\"http://getfirefox.com\">\n"
@@ -423,55 +459,49 @@ msgstr ""
msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media"
msgstr "<a href=\"%(user_url)s\">%(username)s</a>'s media"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:72
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:46
#, python-format
-msgid "Added on %(date)s."
-msgstr ""
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:81
-msgid "Edit"
-msgstr ""
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:85
-msgid "Delete"
+msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:67
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:73
#, python-format
-msgid "%(comment_count)s comment"
+msgid "Image for %(media_title)s"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:93
-#, python-format
-msgid "%(comment_count)s comments"
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:87
+msgid "Edit"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:95
-msgid "No comments yet."
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
+msgid "Delete"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:103
-msgid "Add one"
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:124
+msgid "Add a comment"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:112
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:131
msgid ""
"You can use <a "
"href=\"http://daringfireball.net/projects/markdown/basics\">Markdown</a> for"
" formatting."
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:116
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:135
msgid "Add this comment"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:138
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:154
msgid "at"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:153
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:174
#, python-format
-msgid "<p>â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a></p>"
+msgid ""
+"<h3>Added on</h3>\n"
+" <p>%(date)s</p>"
msgstr ""
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30
@@ -480,7 +510,7 @@ msgid "Really delete %(title)s?"
msgstr ""
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:50
-msgid "Delete Permanently"
+msgid "Delete permanently"
msgstr ""
#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:22
@@ -540,18 +570,14 @@ msgstr "Torna'm a enviar el correu de verificació"
msgid ""
"Someone has registered an account with this username, but it still has to be"
" activated."
-msgstr ""
-"Algú ja ha registrat un compte amb aquest nom d'usuari, però encara l'ha "
-"d'activar."
+msgstr "Algú ja ha registrat un compte amb aquest nom d'usuari, però encara l'ha d'activar."
#: mediagoblin/templates/mediagoblin/user_pages/user.html:79
#, python-format
msgid ""
"If you are that person but you've lost your verification email, you can <a "
"href=\"%(login_url)s\">log in</a> and resend it."
-msgstr ""
-"Si siu aqeust usuari però heu perdut el correu de verificació, podeu <a "
-"href=\"%(login_url)s\">entrar</a> i tornar-lo a enviar."
+msgstr "Si siu aqeust usuari però heu perdut el correu de verificació, podeu <a href=\"%(login_url)s\">entrar</a> i tornar-lo a enviar."
#: mediagoblin/templates/mediagoblin/user_pages/user.html:96
msgid "Here's a spot to tell others about yourself."
@@ -581,6 +607,10 @@ msgid ""
"anything yet."
msgstr ""
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
+msgid "Add media"
+msgstr "Tots els fitxers"
+
#: mediagoblin/templates/mediagoblin/user_pages/user.html:163
#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72
msgid "There doesn't seem to be any media here yet..."
@@ -594,8 +624,13 @@ msgstr "Icona RSS"
msgid "Atom feed"
msgstr ""
-#: mediagoblin/templates/mediagoblin/utils/license.html:21
-msgid "License:"
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:25
+msgid "Location"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:38
+#, python-format
+msgid "View on <a href=\"%(osm_url)s\">OpenStreetMap</a>"
msgstr ""
#: mediagoblin/templates/mediagoblin/utils/license.html:25
@@ -614,25 +649,21 @@ msgstr ""
msgid "Go to page:"
msgstr ""
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:27
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:32
+#: 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:38
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:43
+#: 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 "View more media tagged with"
+msgid "Tagged with"
msgstr ""
-#: mediagoblin/templates/mediagoblin/utils/tags.html:25
-msgid "or"
-msgstr ""
-
-#: mediagoblin/tools/exif.py:68
+#: mediagoblin/tools/exif.py:75
msgid "Could not read the image file."
msgstr ""
@@ -640,24 +671,22 @@ msgstr ""
msgid "I am sure I want to delete this"
msgstr ""
-#: mediagoblin/user_pages/views.py:155
+#: mediagoblin/user_pages/views.py:153
msgid "Oops, your comment was empty."
msgstr ""
-#: mediagoblin/user_pages/views.py:161
+#: mediagoblin/user_pages/views.py:159
msgid "Your comment has been posted!"
msgstr ""
-#: mediagoblin/user_pages/views.py:183
+#: mediagoblin/user_pages/views.py:185
msgid "You deleted the media."
msgstr ""
-#: mediagoblin/user_pages/views.py:190
+#: mediagoblin/user_pages/views.py:192
msgid "The media was not deleted because you didn't check that you were sure."
msgstr ""
-#: mediagoblin/user_pages/views.py:198
+#: mediagoblin/user_pages/views.py:200
msgid "You are about to delete another user's media. Proceed with caution."
msgstr ""
-
-
diff --git a/mediagoblin/i18n/da/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/da/LC_MESSAGES/mediagoblin.mo
new file mode 100644
index 00000000..3333638c
--- /dev/null
+++ b/mediagoblin/i18n/da/LC_MESSAGES/mediagoblin.mo
Binary files differ
diff --git a/mediagoblin/i18n/da/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/da/LC_MESSAGES/mediagoblin.po
new file mode 100644
index 00000000..ef33f0fb
--- /dev/null
+++ b/mediagoblin/i18n/da/LC_MESSAGES/mediagoblin.po
@@ -0,0 +1,692 @@
+# Translations template for PROJECT.
+# Copyright (C) 2012 ORGANIZATION
+# This file is distributed under the same license as the PROJECT project.
+#
+# Translators:
+# Morten Juhl-Johansen Zölde-Fejér <morten@writtenandread.net>, 2012.
+# Olle Jonsson <olle.jonsson@gmail.com>, 2012.
+msgid ""
+msgstr ""
+"Project-Id-Version: GNU MediaGoblin\n"
+"Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n"
+"POT-Creation-Date: 2012-06-01 16:32-0500\n"
+"PO-Revision-Date: 2012-06-01 21:30+0000\n"
+"Last-Translator: cwebber <cwebber@dustycloud.org>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 0.9.6\n"
+"Language: da\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+
+#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41
+msgid "Username"
+msgstr "Brugernavn"
+
+#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45
+msgid "Password"
+msgstr "Kodeord"
+
+#: mediagoblin/auth/forms.py:34
+msgid "Email address"
+msgstr "Email adresse"
+
+#: mediagoblin/auth/forms.py:51
+msgid "Username or email"
+msgstr ""
+
+#: mediagoblin/auth/forms.py:58
+msgid "Incorrect input"
+msgstr ""
+
+#: mediagoblin/auth/views.py:55
+msgid "Sorry, registration is disabled on this instance."
+msgstr ""
+
+#: mediagoblin/auth/views.py:75
+msgid "Sorry, a user with that name already exists."
+msgstr ""
+
+#: mediagoblin/auth/views.py:79
+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 ""
+
+#: 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 "Email til godkendelse sendt igen."
+
+#: mediagoblin/auth/views.py:263
+msgid ""
+"An email has been sent with instructions on how to change your password."
+msgstr ""
+
+#: mediagoblin/auth/views.py:273
+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:285
+msgid "Couldn't find someone with that username or email."
+msgstr ""
+
+#: mediagoblin/auth/views.py:333
+msgid "You can now log in using your new password."
+msgstr ""
+
+#: mediagoblin/edit/forms.py:25 mediagoblin/submit/forms.py:28
+msgid "Title"
+msgstr "Titel"
+
+#: 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/submit/forms.py:32
+msgid ""
+"You can use\n"
+" <a href=\"http://daringfireball.net/projects/markdown/basics\">\n"
+" Markdown</a> for formatting."
+msgstr ""
+
+#: 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
+msgid "Slug"
+msgstr ""
+
+#: mediagoblin/edit/forms.py:39
+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 "Websted"
+
+#: mediagoblin/edit/forms.py:58
+msgid "This address contains errors"
+msgstr ""
+
+#: mediagoblin/edit/forms.py:63
+msgid "Old password"
+msgstr ""
+
+#: mediagoblin/edit/forms.py:65
+msgid "Enter your old password to prove you own this account."
+msgstr ""
+
+#: mediagoblin/edit/forms.py:68
+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:88
+msgid "You are editing another user's media. Proceed with caution."
+msgstr ""
+
+#: mediagoblin/edit/views.py:158
+msgid "You are editing a user's profile. Proceed with caution."
+msgstr ""
+
+#: mediagoblin/edit/views.py:174
+msgid "Profile changes saved"
+msgstr ""
+
+#: mediagoblin/edit/views.py:200
+msgid "Wrong password"
+msgstr ""
+
+#: mediagoblin/edit/views.py:216
+msgid "Account settings saved"
+msgstr ""
+
+#: mediagoblin/media_types/__init__.py:60
+#: mediagoblin/media_types/__init__.py:120
+msgid "Sorry, I don't support that file type :("
+msgstr ""
+
+#: mediagoblin/processing/__init__.py:127
+msgid "Invalid file given for media type."
+msgstr ""
+
+#: mediagoblin/submit/forms.py:26
+msgid "File"
+msgstr "Fil"
+
+#: mediagoblin/submit/views.py:56
+msgid "You must provide a file."
+msgstr ""
+
+#: mediagoblin/submit/views.py:163
+msgid "Woohoo! Submitted!"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/404.html:22
+msgid "Image of 404 goblin stressing out"
+msgstr "Billede af stresset 404 goblin"
+
+#: mediagoblin/templates/mediagoblin/404.html:23
+msgid "Oops!"
+msgstr "Hovsa!"
+
+#: mediagoblin/templates/mediagoblin/404.html:24
+msgid "There doesn't seem to be a page at this address. Sorry!"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/404.html:26
+msgid ""
+"If you're sure the address is correct, maybe the page you're looking for has"
+" been moved or deleted."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:47
+msgid "MediaGoblin logo"
+msgstr "MediaGoblin logo"
+
+#: mediagoblin/templates/mediagoblin/base.html:57
+msgid "Verify your email!"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:63
+msgid "+ Add media"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:65
+msgid "View your profile"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:66
+msgid "Log out"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:71
+#: mediagoblin/templates/mediagoblin/auth/login.html:32
+#: mediagoblin/templates/mediagoblin/auth/login.html:50
+msgid "Log in"
+msgstr "Log ind"
+
+#: mediagoblin/templates/mediagoblin/base.html:85
+msgid ""
+"Powered by <a href=\"http://mediagoblin.org\">MediaGoblin</a>, a <a "
+"href=\"http://gnu.org/\">GNU</a> project."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:88
+#, python-format
+msgid ""
+"Released under the <a "
+"href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a "
+"href=\"%(source_link)s\">Source code</a> available."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/root.html:24
+msgid "Explore"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/root.html:26
+msgid "Hi there, welcome to this MediaGoblin site!"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/root.html:28
+msgid ""
+"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, an "
+"extraordinarily great piece of media hosting software."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/root.html:29
+msgid ""
+"To add your own media, place comments, save your favourites and more, you "
+"can log in with your MediaGoblin account."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/root.html:31
+msgid "Don't have one yet? It's easy!"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/root.html:32
+#, python-format
+msgid ""
+"<a class=\"button_action_highlight\" href=\"%(register_url)s\">Create an account at this site</a>\n"
+" or\n"
+" <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">Set up MediaGoblin on your own server</a>"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/root.html:40
+msgid "Most recent media"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/auth/change_fp.html:32
+msgid "Set your new password"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/auth/change_fp.html:35
+msgid "Set password"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27
+msgid "Recover password"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:30
+msgid "Send instructions"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/auth/fp_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:35
+msgid "Logging in failed!"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/auth/login.html:40
+msgid "Don't have an account yet?"
+msgstr "Har du endnu ikke en konto?"
+
+#: mediagoblin/templates/mediagoblin/auth/login.html:41
+msgid "Create one here!"
+msgstr "Opret en her!"
+
+#: mediagoblin/templates/mediagoblin/auth/login.html:47
+msgid "Forgot your password?"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/auth/register.html:32
+msgid "Create an account!"
+msgstr "Opret en konto!"
+
+#: mediagoblin/templates/mediagoblin/auth/register.html:36
+msgid "Create"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/auth/verification_email.txt:19
+#, python-format
+msgid ""
+"Hi %(username)s,\n"
+"\n"
+"to activate your GNU MediaGoblin account, open the following URL in\n"
+"your web browser:\n"
+"\n"
+"%(verification_url)s"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/edit/edit.html:29
+#, python-format
+msgid "Editing %(media_title)s"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/edit/edit.html:36
+#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49
+msgid "Cancel"
+msgstr "Afbryd"
+
+#: mediagoblin/templates/mediagoblin/edit/edit.html:37
+#: mediagoblin/templates/mediagoblin/edit/edit_account.html:40
+#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:35
+msgid "Save changes"
+msgstr "Gem ændringer"
+
+#: mediagoblin/templates/mediagoblin/edit/edit_account.html:34
+#, python-format
+msgid "Changing %(username)s's account settings"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29
+#, python-format
+msgid "Editing %(username)s's profile"
+msgstr "Redigerer %(username)s profil"
+
+#: 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/video.html:53
+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 ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:47
+msgid ""
+"You can get a modern web browser that \n"
+"\tcan play the audio at <a href=\"http://getfirefox.com\">\n"
+"\t http://getfirefox.com</a>!"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:56
+msgid "Download"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:60
+msgid "original file"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:63
+msgid "WebM file (Vorbis codec)"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:40
+msgid ""
+"Sorry, this video will not work because \n"
+"\t your web browser does not support HTML5 \n"
+"\t video."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:43
+msgid ""
+"You can get a modern web browser that \n"
+"\t can play this video at <a href=\"http://getfirefox.com\">\n"
+"\t http://getfirefox.com</a>!"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/submit/start.html:26
+msgid "Add your media"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/submit/start.html:30
+msgid "Add"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30
+#, python-format
+msgid "%(username)s's media"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:37
+#, python-format
+msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:46
+#, python-format
+msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:67
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:73
+#, python-format
+msgid "Image for %(media_title)s"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:87
+msgid "Edit"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
+msgid "Delete"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:124
+msgid "Add a comment"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:131
+msgid ""
+"You can use <a "
+"href=\"http://daringfireball.net/projects/markdown/basics\">Markdown</a> for"
+" formatting."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:135
+msgid "Add this comment"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:154
+msgid "at"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:174
+#, python-format
+msgid ""
+"<h3>Added on</h3>\n"
+" <p>%(date)s</p>"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30
+#, python-format
+msgid "Really delete %(title)s?"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:50
+msgid "Delete permanently"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:22
+msgid "Media processing panel"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:25
+msgid ""
+"You can track the state of media being processed for your gallery here."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:28
+msgid "Media in-processing"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:46
+msgid "No media in-processing"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:50
+msgid "These uploads failed to process:"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:31
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:89
+#, python-format
+msgid "%(username)s's profile"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:43
+msgid "Sorry, no such user found."
+msgstr "Desværre, fandt ikke den bruger."
+
+#: 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 "Næsten færdig! Din konto skal stadig aktiveres."
+
+#: 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 "Der skulle komme email om et par øjeblikke med instrukser om hvordan."
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:62
+msgid "In case it doesn't:"
+msgstr "Hvis det ikke gør:"
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:65
+msgid "Resend verification email"
+msgstr "Gensend verificeringsemail"
+
+#: 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 <a "
+"href=\"%(login_url)s\">log in</a> and resend it."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:96
+msgid "Here's a spot to tell others about yourself."
+msgstr "Her kan du fortælle andre om dig selv."
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:101
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:118
+msgid "Edit profile"
+msgstr "Ret profil"
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:106
+msgid "This user hasn't filled in their profile (yet)."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:125
+msgid "Change account settings"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:138
+#, python-format
+msgid "View all of %(username)s's media"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:151
+msgid ""
+"This is where your media will appear, but you don't seem to have added "
+"anything yet."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
+msgid "Add media"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:163
+#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72
+msgid "There doesn't seem to be any media here yet..."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/utils/feed_link.html:21
+msgid "feed icon"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/utils/feed_link.html:23
+msgid "Atom feed"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:25
+msgid "Location"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:38
+#, python-format
+msgid "View on <a href=\"%(osm_url)s\">OpenStreetMap</a>"
+msgstr ""
+
+#: 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:75
+msgid "Could not read the image file."
+msgstr ""
+
+#: mediagoblin/user_pages/forms.py:30
+msgid "I am sure I want to delete this"
+msgstr ""
+
+#: mediagoblin/user_pages/views.py:153
+msgid "Oops, your comment was empty."
+msgstr ""
+
+#: mediagoblin/user_pages/views.py:159
+msgid "Your comment has been posted!"
+msgstr ""
+
+#: mediagoblin/user_pages/views.py:185
+msgid "You deleted the media."
+msgstr ""
+
+#: mediagoblin/user_pages/views.py:192
+msgid "The media was not deleted because you didn't check that you were sure."
+msgstr ""
+
+#: mediagoblin/user_pages/views.py:200
+msgid "You are about to delete another user's media. Proceed with caution."
+msgstr ""
diff --git a/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.mo
index e3ba1606..0e83c06b 100644
--- a/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.mo
+++ b/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.mo
Binary files differ
diff --git a/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.po
index e435971a..f50f20fa 100644
--- a/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.po
+++ b/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.po
@@ -7,6 +7,7 @@
# <cwebber@dustycloud.org>, 2011.
# Elrond <elrond+mediagoblin.org@samba-tng.org>, 2011, 2012.
# <jakob.kramer@gmx.de>, 2011, 2012.
+# Jakob Kramer <jakob.kramer@gmx.de>, 2012.
# Jan-Christoph Borchardt <JanCBorchardt@fsfe.org>, 2011.
# Jan-Christoph Borchardt <jan@unhosted.org>, 2011, 2012.
# <kyoo@kyoo.ch>, 2011.
@@ -17,10 +18,10 @@ msgid ""
msgstr ""
"Project-Id-Version: GNU MediaGoblin\n"
"Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n"
-"POT-Creation-Date: 2012-01-29 13:47-0600\n"
-"PO-Revision-Date: 2012-02-05 20:23+0000\n"
-"Last-Translator: Jan-Christoph Borchardt <jan@unhosted.org>\n"
-"Language-Team: German (http://www.transifex.net/projects/p/mediagoblin/team/de/)\n"
+"POT-Creation-Date: 2012-04-30 10:48-0500\n"
+"PO-Revision-Date: 2012-05-20 17:28+0000\n"
+"Last-Translator: Jakob Kramer <jakob.kramer@gmx.de>\n"
+"Language-Team: German (http://www.transifex.net/projects/p/mediagoblin/language/de/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -28,10 +29,6 @@ msgstr ""
"Language: de\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
-#: mediagoblin/processing.py:143
-msgid "Invalid file given for media type."
-msgstr "Die Datei stimmt nicht mit dem gewählten Medientyp überein."
-
#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41
msgid "Username"
msgstr "Benutzername"
@@ -44,63 +41,64 @@ msgstr "Passwort"
msgid "Email address"
msgstr "E-Mail-Adresse"
+#: mediagoblin/auth/forms.py:51
+msgid "Username or email"
+msgstr "Benutzername oder E-Mail-Adresse"
+
+#: mediagoblin/auth/forms.py:58
+msgid "Incorrect input"
+msgstr "Fehlerhafte Eingabe"
+
#: mediagoblin/auth/views.py:55
msgid "Sorry, registration is disabled on this instance."
msgstr "Das Registrieren ist auf dieser Instanz leider deaktiviert."
-#: mediagoblin/auth/views.py:73
+#: mediagoblin/auth/views.py:75
msgid "Sorry, a user with that name already exists."
msgstr "Leider gibt es bereits einen Benutzer mit diesem Namen."
-#: mediagoblin/auth/views.py:77
+#: mediagoblin/auth/views.py:79
msgid "Sorry, a user with that email address already exists."
msgstr "Leider gibt es bereits einen Benutzer mit dieser E-Mail-Adresse."
-#: mediagoblin/auth/views.py:180
+#: mediagoblin/auth/views.py:182
msgid ""
"Your email address has been verified. You may now login, edit your profile, "
"and submit images!"
-msgstr ""
-"Deine E-Mail-Adresse wurde bestätigt. Du kannst dich nun anmelden, Dein "
-"Profil bearbeiten und Bilder hochladen!"
+msgstr "Deine E-Mail-Adresse wurde bestätigt. Du kannst dich nun anmelden, dein Profil bearbeiten und Bilder hochladen!"
-#: mediagoblin/auth/views.py:186
+#: mediagoblin/auth/views.py:188
msgid "The verification key or user id is incorrect"
msgstr "Der Bestätigungsschlüssel oder die Nutzernummer ist falsch."
-#: mediagoblin/auth/views.py:204
+#: mediagoblin/auth/views.py:206
msgid "You must be logged in so we know who to send the email to!"
msgstr "Du musst angemeldet sein, damit wir wissen, wer die Email bekommt."
-#: mediagoblin/auth/views.py:212
+#: mediagoblin/auth/views.py:214
msgid "You've already verified your email address!"
msgstr "Deine E-Mail-Adresse wurde bereits bestätigt."
-#: mediagoblin/auth/views.py:225
+#: mediagoblin/auth/views.py:227
msgid "Resent your verification email."
msgstr "Bestätigungs-E-Mail wurde erneut versandt."
-#: mediagoblin/auth/views.py:260
+#: mediagoblin/auth/views.py:263
msgid ""
"An email has been sent with instructions on how to change your password."
-msgstr ""
-"Es wurde eine Email mit Anweisungen für die Änderung des Passwortes an dich "
-"gesendet."
+msgstr "Es wurde eine Email mit Anweisungen für die Änderung des Passwortes an dich gesendet."
-#: mediagoblin/auth/views.py:270
+#: mediagoblin/auth/views.py:273
msgid ""
"Could not send password recovery email as your username is inactive or your "
"account's email address has not been verified."
-msgstr ""
-"E-Mail zur Wiederherstellung des Passworts konnte nicht gesendet werden, "
-"weil dein Benutzername inaktiv oder deine E-Mail-Adresse noch nicht "
-"verifiziert ist."
+msgstr "Die E-Mail zur Wiederherstellung des Passworts konnte nicht verschickt werden, weil dein Benutzername inaktiv oder deine E-Mail-Adresse noch nicht bestätigt wurde."
-#: mediagoblin/auth/views.py:282
+#: mediagoblin/auth/views.py:285
msgid "Couldn't find someone with that username or email."
msgstr "Es konnte niemand mit diesem Nutzernamen oder Email gefunden werden."
-#: mediagoblin/auth/views.py:330
+#: mediagoblin/auth/views.py:333
msgid "You can now log in using your new password."
msgstr "Du kannst dich jetzt mit deinem neuen Passwort anmelden."
@@ -118,14 +116,11 @@ msgid ""
"You can use\n"
" <a href=\"http://daringfireball.net/projects/markdown/basics\">\n"
" Markdown</a> for formatting."
-msgstr ""
-"Für Formatierung kannst du\n"
-" <a href=\"http://daringfireball.net/projects/markdown/basics\">\n"
-" Markdown</a> benutzen."
+msgstr "Die Texte lassen sich durch <a href=\"http://daringfireball.net/projects/markdown/basics\">Markdown</a> formatieren."
#: mediagoblin/edit/forms.py:33 mediagoblin/submit/forms.py:36
msgid "Tags"
-msgstr "Schlagworte"
+msgstr "Schlagwörter"
#: mediagoblin/edit/forms.py:35 mediagoblin/submit/forms.py:38
msgid "Separate tags by commas."
@@ -143,11 +138,10 @@ msgstr "Bitte gib einen Kurztitel ein"
msgid ""
"The title part of this media's address. You usually don't need to change "
"this."
-msgstr ""
-"Der Titelteil der Medienadresse. Normalerweise muss hier nichts geändert "
-"werden."
+msgstr "Der Titelteil der Medienadresse. Normalerweise muss hier nichts geändert werden."
#: mediagoblin/edit/forms.py:44 mediagoblin/submit/forms.py:41
+#: mediagoblin/templates/mediagoblin/utils/license.html:20
msgid "License"
msgstr "Lizenz"
@@ -159,60 +153,64 @@ msgstr "Biographie"
msgid "Website"
msgstr "Webseite"
+#: mediagoblin/edit/forms.py:58
+msgid "This address contains errors"
+msgstr "Diese Adresse ist fehlerhaft"
+
#: mediagoblin/edit/forms.py:63
msgid "Old password"
msgstr "Altes Passwort"
#: mediagoblin/edit/forms.py:65
msgid "Enter your old password to prove you own this account."
-msgstr ""
-"Gib dein altes Passwort ein, um zu bestätigen dass du dieses Konto besitzt."
+msgstr "Gib dein altes Passwort ein, um zu bestätigen, dass du dieses Konto besitzt."
#: mediagoblin/edit/forms.py:68
msgid "New password"
msgstr "Neues Passwort"
-#: mediagoblin/edit/views.py:68
+#: mediagoblin/edit/views.py:67
msgid "An entry with that slug already exists for this user."
msgstr "Diesen Kurztitel hast du bereits vergeben."
-#: mediagoblin/edit/views.py:92
+#: mediagoblin/edit/views.py:88
msgid "You are editing another user's media. Proceed with caution."
-msgstr "Du bearbeitest die Medien eines Anderen. Bitte sei vorsichtig."
+msgstr "Du bearbeitest die Medien eines Anderen. Sei bitte vorsichtig."
-#: mediagoblin/edit/views.py:162
+#: mediagoblin/edit/views.py:158
msgid "You are editing a user's profile. Proceed with caution."
-msgstr "Du bearbeitest das Profil eines Anderen. Bitte sei vorsichtig."
+msgstr "Du bearbeitest das Profil eines Anderen. Sei bitte vorsichtig."
-#: mediagoblin/edit/views.py:180
+#: mediagoblin/edit/views.py:174
msgid "Profile changes saved"
msgstr "Das Profil wurde aktualisiert"
-#: mediagoblin/edit/views.py:206
+#: mediagoblin/edit/views.py:200
msgid "Wrong password"
msgstr "Falsches Passwort"
-#: mediagoblin/edit/views.py:222
+#: mediagoblin/edit/views.py:216
msgid "Account settings saved"
msgstr "Kontoeinstellungen gespeichert"
-#: mediagoblin/media_types/__init__.py:77
-msgid "Could not extract any file extension from \"{filename}\""
-msgstr "Es konnten keine Dateierweiterungen von »{filename}« gelesen werden."
-
-#: mediagoblin/media_types/__init__.py:88
+#: mediagoblin/media_types/__init__.py:60
+#: mediagoblin/media_types/__init__.py:120
msgid "Sorry, I don't support that file type :("
msgstr "Entschuldigung, dieser Dateityp wird nicht unterstützt."
+#: mediagoblin/processing/__init__.py:127
+msgid "Invalid file given for media type."
+msgstr "Die Datei stimmt nicht mit dem gewählten Medientyp überein."
+
#: mediagoblin/submit/forms.py:26
msgid "File"
msgstr "Datei"
-#: mediagoblin/submit/views.py:54
+#: mediagoblin/submit/views.py:56
msgid "You must provide a file."
msgstr "Du musst eine Datei angeben."
-#: mediagoblin/submit/views.py:158
+#: mediagoblin/submit/views.py:163
msgid "Woohoo! Submitted!"
msgstr "Yeeeaaah! Geschafft!"
@@ -232,44 +230,51 @@ msgstr "Tut uns Leid, aber unter der angegebenen Adresse gibt es keine Seite!"
msgid ""
"If you're sure the address is correct, maybe the page you're looking for has"
" been moved or deleted."
-msgstr ""
-"Wenn du sicher bist, dass die Adresse stimmt, wurde die Seite eventuell "
-"verschoben oder gelöscht."
+msgstr "Wenn du sicher bist, dass die Adresse stimmt, wurde die Seite eventuell verschoben oder gelöscht."
-#: mediagoblin/templates/mediagoblin/base.html:46
+#: mediagoblin/templates/mediagoblin/base.html:47
msgid "MediaGoblin logo"
msgstr "MediaGoblin-Logo"
-#: mediagoblin/templates/mediagoblin/base.html:51
-#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
-msgid "Add media"
-msgstr "Medien hinzufügen"
-
-#: mediagoblin/templates/mediagoblin/base.html:62
+#: mediagoblin/templates/mediagoblin/base.html:57
msgid "Verify your email!"
msgstr "Bitte bestätige deine E-Mail-Adresse!"
-#: mediagoblin/templates/mediagoblin/base.html:69
-msgid "log out"
+#: mediagoblin/templates/mediagoblin/base.html:63
+msgid "+ Add media"
+msgstr "+ Medien hinzufügen"
+
+#: mediagoblin/templates/mediagoblin/base.html:65
+msgid "View your profile"
+msgstr "Dein Profil ansehen"
+
+#: mediagoblin/templates/mediagoblin/base.html:66
+msgid "Log out"
msgstr "Abmelden"
-#: mediagoblin/templates/mediagoblin/base.html:72
-#: mediagoblin/templates/mediagoblin/auth/login.html:27
-#: mediagoblin/templates/mediagoblin/auth/login.html:45
+#: mediagoblin/templates/mediagoblin/base.html:71
+#: mediagoblin/templates/mediagoblin/auth/login.html:32
+#: mediagoblin/templates/mediagoblin/auth/login.html:50
msgid "Log in"
msgstr "Anmelden"
-#: mediagoblin/templates/mediagoblin/base.html:84
+#: mediagoblin/templates/mediagoblin/base.html:85
msgid ""
"Powered by <a href=\"http://mediagoblin.org\">MediaGoblin</a>, a <a "
-"href=\"http://gnu.org/\">GNU</a> project"
-msgstr ""
-"Läuft mit <a href=\"http://mediagoblin.org/\">MediaGoblin</a>, einem <a "
-"href=\"http://gnu.org/\">GNU</a>-Projekt"
+"href=\"http://gnu.org/\">GNU</a> project."
+msgstr "Diese Seite setzt <a href=\"http://mediagoblin.org/\">MediaGoblin</a> ein, ein <a href=\"http://gnu.org/\">GNU</a>-Projekt."
+
+#: mediagoblin/templates/mediagoblin/base.html:88
+#, python-format
+msgid ""
+"Released under the <a "
+"href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a "
+"href=\"%(source_link)s\">Source code</a> available."
+msgstr "Veröffentlicht unter der <a href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a href=\"%(source_link)s\">Quellcode</a>."
#: mediagoblin/templates/mediagoblin/root.html:24
msgid "Explore"
-msgstr "Entdecke"
+msgstr "Entdecken"
#: mediagoblin/templates/mediagoblin/root.html:26
msgid "Hi there, welcome to this MediaGoblin site!"
@@ -279,17 +284,13 @@ msgstr "Hallo du, willkommen auf dieser MediaGoblin-Seite!"
msgid ""
"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, an "
"extraordinarily great piece of media hosting software."
-msgstr ""
-"Diese Seite läuft mit <a href=\"http://mediagoblin.org\">MediaGoblin</a>, "
-"einer großartigen Software für Medienhosting."
+msgstr "Diese Seite setzt <a href=\"http://mediagoblin.org\">MediaGoblin</a> ein, eine großartige Software für Medienhosting."
#: mediagoblin/templates/mediagoblin/root.html:29
msgid ""
"To add your own media, place comments, save your favourites and more, you "
"can log in with your MediaGoblin account."
-msgstr ""
-"Melde dich mit deinem MediaGoblin-Konto an, um eigene Medien hinzuzufügen, "
-"zu kommentieren, Favoriten zu speichern und mehr."
+msgstr "Melde dich mit deinem MediaGoblin-Konto an, um eigene Medien hinzuzufügen, zu kommentieren, Favoriten zu speichern und mehr."
#: mediagoblin/templates/mediagoblin/root.html:31
msgid "Don't have one yet? It's easy!"
@@ -301,10 +302,7 @@ msgid ""
"<a class=\"button_action_highlight\" href=\"%(register_url)s\">Create an account at this site</a>\n"
" or\n"
" <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">Set up MediaGoblin on your own server</a>"
-msgstr ""
-"<a class=\"button_action_highlight\" href=\"%(register_url)s\">Registriere dich auf dieser Seite</a>\n"
-" oder\n"
-" <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">Installiere MediaGoblin auf deinem eigenen Server</a>"
+msgstr "<a class=\"button_action_highlight\" href=\"%(register_url)s\">Registriere dich auf dieser Seite</a> oder <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">Installiere MediaGoblin auf deinem eigenen Server</a>"
#: mediagoblin/templates/mediagoblin/root.html:40
msgid "Most recent media"
@@ -324,7 +322,7 @@ msgstr "Passwort wiederherstellen"
#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:30
msgid "Send instructions"
-msgstr "Anleitung senden"
+msgstr "Anweisungen senden"
#: mediagoblin/templates/mediagoblin/auth/fp_verification_email.txt:19
#, python-format
@@ -338,28 +336,21 @@ msgid ""
"\n"
"If you think this is an error, just ignore this email and continue being\n"
"a happy goblin!"
-msgstr ""
-"Hi %(username)s,\n"
-"\n"
-"um dein GNU MediaGoblin Passwort zu ändern, öffne folgende URL in deinem Webbrowser:\n"
-"\n"
-"%(verification_url)s\n"
-"\n"
-"Wenn du denkst, dass das ein Fehler ist, ignoriere einfach diese E-Mail und bleib ein glücklicher Goblin!"
+msgstr "Hallo %(username)s,\n\num dein GNU-MediaGoblin-Passwort zu ändern, öffne folgende URL\nin deinem Webbrowser:\n\n%(verification_url)s\n\nWenn du denkst, dass es sich hierbei um einen Fehler handelt,\nignoriere einfach diese E-Mail und bleib ein glücklicher Goblin!"
-#: mediagoblin/templates/mediagoblin/auth/login.html:30
+#: mediagoblin/templates/mediagoblin/auth/login.html:35
msgid "Logging in failed!"
msgstr "Anmeldevorgang fehlgeschlagen!"
-#: mediagoblin/templates/mediagoblin/auth/login.html:35
+#: mediagoblin/templates/mediagoblin/auth/login.html:40
msgid "Don't have an account yet?"
msgstr "Hast du noch kein Konto?"
-#: mediagoblin/templates/mediagoblin/auth/login.html:36
+#: mediagoblin/templates/mediagoblin/auth/login.html:41
msgid "Create one here!"
msgstr "Registriere dich hier!"
-#: mediagoblin/templates/mediagoblin/auth/login.html:42
+#: mediagoblin/templates/mediagoblin/auth/login.html:47
msgid "Forgot your password?"
msgstr "Passwort vergessen?"
@@ -380,12 +371,7 @@ msgid ""
"your web browser:\n"
"\n"
"%(verification_url)s"
-msgstr ""
-"Hallo %(username)s,\n"
-"\n"
-"um dein Konto bei GNU MediaGoblin zu aktivieren, musst du folgende Adresse in deinem Webbrowser öffnen:\n"
-"\n"
-"%(verification_url)s"
+msgstr "Hallo %(username)s,\n\num dein Konto bei GNU MediaGoblin zu aktivieren, musst du folgende Adresse in deinem Webbrowser öffnen:\n\n%(verification_url)s"
#: mediagoblin/templates/mediagoblin/edit/edit.html:29
#, python-format
@@ -406,7 +392,7 @@ msgstr "Änderungen speichern"
#: mediagoblin/templates/mediagoblin/edit/edit_account.html:34
#, python-format
msgid "Changing %(username)s's account settings"
-msgstr "%(username)s's Kontoeinstellungen werden geändert"
+msgstr "%(username)ss Kontoeinstellungen werden geändert"
#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29
#, python-format
@@ -420,29 +406,38 @@ msgid "Media tagged with: %(tag_name)s"
msgstr "Medien mit Schlagwort: %(tag_name)s"
#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:46
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:57
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:53
msgid "Original"
msgstr "Original"
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:33
+#: 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 "Entschuldige, dieses Audiostück wird nicht funktionieren, weil dein Webbrowser kein HTML5-Audio unterstützt."
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:47
+msgid ""
+"You can get a modern web browser that \n"
+"\tcan play the audio at <a href=\"http://getfirefox.com\">\n"
+"\t http://getfirefox.com</a>!"
+msgstr "Hol dir auf <a href=\"http://getfirefox.com\">http://getfirefox.com</a> einen modernen Webbrowser, der dieses Audiostück abspielen kann!"
+
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:40
msgid ""
"Sorry, this video will not work because \n"
"\t your web browser does not support HTML5 \n"
"\t video."
-msgstr ""
-"Entschuldige, dieses Video wird nicht funktionieren weil \n"
-"<span class=\"whitespace other\" title=\"Tab\">»</span> dein Webbrowser kein HTML5 \n"
-"<span class=\"whitespace other\" title=\"Tab\">»</span> Video unterstützt."
+msgstr "Entschuldige, dieses Video wird nicht funktionieren, weil dein Webbrowser kein HTML5-Video unterstützt."
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:36
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:43
msgid ""
"You can get a modern web browser that \n"
"\t can play this video at <a href=\"http://getfirefox.com\">\n"
"\t http://getfirefox.com</a>!"
-msgstr ""
-"Hol dir einen modernen Webbrowser, der \n"
-"<span class=\"whitespace other\" title=\"Tab\">»</span> dieses Video abspielen kann, <a href=\"http://getfirefox.com\">\n"
-"<span class=\"whitespace other\" title=\"Tab\">»</span> Firefox</a>!"
+msgstr "Hol dir auf <a href=\"http://getfirefox.com\">http://getfirefox.com</a> einen modernen Webbrowser, der dieses Video abspielen kann!"
#: mediagoblin/templates/mediagoblin/submit/start.html:26
msgid "Add your media"
@@ -462,68 +457,59 @@ msgstr "%(username)ss Medien"
msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media"
msgstr "<a href=\"%(user_url)s\">%(username)s</a>s Medien"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:72
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:46
#, python-format
-msgid "Added on %(date)s."
-msgstr "Hinzugefügt am %(date)s."
+msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>"
+msgstr "â– Medien von <a href=\"%(user_url)s\">%(username)s</a>"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:81
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:67
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:73
+#, python-format
+msgid "Image for %(media_title)s"
+msgstr "Bild für %(media_title)s"
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:87
msgid "Edit"
msgstr "Bearbeiten"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:85
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
msgid "Delete"
msgstr "Löschen"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
-#, python-format
-msgid "%(comment_count)s comment"
-msgstr "%(comment_count)s Kommentar"
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:93
-#, python-format
-msgid "%(comment_count)s comments"
-msgstr "%(comment_count)s Kommentare"
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:124
+msgid "Add a comment"
+msgstr "Einen Kommentar schreiben"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:95
-msgid "No comments yet."
-msgstr "Bisher keine Kommentare."
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:103
-msgid "Add one"
-msgstr "Kommentiere etwas"
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:112
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:131
msgid ""
"You can use <a "
"href=\"http://daringfireball.net/projects/markdown/basics\">Markdown</a> for"
" formatting."
-msgstr ""
-"Für Formatierung kannst du <a "
-"href=\"http://daringfireball.net/projects/markdown/basics\">Markdown</a> "
-"benutzen."
+msgstr "Die Texte lassen sich durch <a href=\"http://daringfireball.net/projects/markdown/basics\">Markdown</a> formatieren."
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:116
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:135
msgid "Add this comment"
msgstr "Kommentar absenden"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:138
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:154
msgid "at"
-msgstr "bei"
+msgstr "um"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:153
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:174
#, python-format
-msgid "<p>â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a></p>"
-msgstr "<p>â– Medien von <a href=\"%(user_url)s\">%(username)s</a></p>"
+msgid ""
+"<h3>Added on</h3>\n"
+" <p>%(date)s</p>"
+msgstr "<h3>Veröffentlicht am</h3>\n <p>%(date)s</p>"
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30
#, python-format
msgid "Really delete %(title)s?"
-msgstr "%(title)s wirklich löschen?"
+msgstr "Möchtest du %(title)s wirklich löschen?"
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:50
-msgid "Delete Permanently"
-msgstr "Dauerhaft löschen."
+msgid "Delete permanently"
+msgstr "Dauerhaft löschen"
#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:22
msgid "Media processing panel"
@@ -532,9 +518,7 @@ msgstr "Medienverarbeitung"
#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:25
msgid ""
"You can track the state of media being processed for your gallery here."
-msgstr ""
-"Du kannst den Status der gerade in Bearbeitung befindlichen Medien hier "
-"betrachten."
+msgstr "Du kannst den Status der Medien, die sich gerade in Bearbeitung befinden, hier betrachten."
#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:28
msgid "Media in-processing"
@@ -570,9 +554,7 @@ msgstr "Fast fertig! Dein Konto muss noch freigeschaltet werden."
#: mediagoblin/templates/mediagoblin/user_pages/user.html:58
msgid ""
"An email should arrive in a few moments with instructions on how to do so."
-msgstr ""
-"Gleich solltest du eine E-Mail erhalten, die dir erklärt, was du noch machen"
-" musst."
+msgstr "Gleich solltest du eine E-Mail erhalten, die dir erklärt, was du noch machen musst."
#: mediagoblin/templates/mediagoblin/user_pages/user.html:62
msgid "In case it doesn't:"
@@ -580,25 +562,20 @@ msgstr "Wenn sie nicht ankommt:"
#: mediagoblin/templates/mediagoblin/user_pages/user.html:65
msgid "Resend verification email"
-msgstr "Bestätigung erneut senden"
+msgstr "Bestätigungs-E-Mail erneut senden"
#: 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 ""
-"Jemand hat bereits ein Konto mit diesem Benutzernamen registriert, aber es "
-"muss noch aktiviert werden."
+msgstr "Jemand hat bereits ein Konto mit diesem Benutzernamen registriert, aber es muss noch aktiviert werden."
#: 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 <a "
"href=\"%(login_url)s\">log in</a> and resend it."
-msgstr ""
-"Wenn dir dieses Konto gehört und die Bestätigungsmail verloren gegangen ist,"
-" kannst du dich <a href=\"%(login_url)s\">anmelden</a> und sie erneut "
-"senden."
+msgstr "Wenn dir dieses Konto gehört und die Bestätigungsmail verloren gegangen ist, kannst du dich <a href=\"%(login_url)s\">anmelden</a> und sie erneut senden."
#: mediagoblin/templates/mediagoblin/user_pages/user.html:96
msgid "Here's a spot to tell others about yourself."
@@ -628,6 +605,10 @@ msgid ""
"anything yet."
msgstr "Hier erscheinen deine Medien, sobald du etwas hochgeladen hast."
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
+msgid "Add media"
+msgstr "Medien hinzufügen"
+
#: mediagoblin/templates/mediagoblin/user_pages/user.html:163
#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72
msgid "There doesn't seem to be any media here yet..."
@@ -641,9 +622,14 @@ msgstr "Feed-Symbol"
msgid "Atom feed"
msgstr "Atom-Feed"
-#: mediagoblin/templates/mediagoblin/utils/license.html:21
-msgid "License:"
-msgstr "Lizenz:"
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:25
+msgid "Location"
+msgstr "Aufnahmeort"
+
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:38
+#, python-format
+msgid "View on <a href=\"%(osm_url)s\">OpenStreetMap</a>"
+msgstr "In <a href=\"%(osm_url)s\">OpenStreetMap</a> öffnen"
#: mediagoblin/templates/mediagoblin/utils/license.html:25
msgid "All rights reserved"
@@ -661,25 +647,21 @@ msgstr "Ältere →"
msgid "Go to page:"
msgstr "Zu Seite:"
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:27
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:32
+#: mediagoblin/templates/mediagoblin/utils/prev_next.html:28
+#: mediagoblin/templates/mediagoblin/utils/prev_next.html:33
msgid "newer"
msgstr "neuer"
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:38
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:43
+#: mediagoblin/templates/mediagoblin/utils/prev_next.html:39
+#: mediagoblin/templates/mediagoblin/utils/prev_next.html:44
msgid "older"
msgstr "älter"
#: mediagoblin/templates/mediagoblin/utils/tags.html:20
-msgid "View more media tagged with"
-msgstr "Mehr Medien anschauen mit dem Schlagwort"
+msgid "Tagged with"
+msgstr "Schlagwörter"
-#: mediagoblin/templates/mediagoblin/utils/tags.html:25
-msgid "or"
-msgstr "oder"
-
-#: mediagoblin/tools/exif.py:68
+#: mediagoblin/tools/exif.py:75
msgid "Could not read the image file."
msgstr "Die Bilddatei konnte nicht gelesen werden."
@@ -687,26 +669,22 @@ msgstr "Die Bilddatei konnte nicht gelesen werden."
msgid "I am sure I want to delete this"
msgstr "Ja, wirklich löschen"
-#: mediagoblin/user_pages/views.py:155
+#: mediagoblin/user_pages/views.py:153
msgid "Oops, your comment was empty."
msgstr "Ohh, der Kommentar war leer."
-#: mediagoblin/user_pages/views.py:161
+#: mediagoblin/user_pages/views.py:159
msgid "Your comment has been posted!"
msgstr "Dein Kommentar wurde gesendet!"
-#: mediagoblin/user_pages/views.py:183
+#: mediagoblin/user_pages/views.py:185
msgid "You deleted the media."
msgstr "Du hast das Medium gelöscht."
-#: mediagoblin/user_pages/views.py:190
+#: mediagoblin/user_pages/views.py:192
msgid "The media was not deleted because you didn't check that you were sure."
-msgstr ""
-"Das Medium wurde nicht gelöscht. Du musst ankreuzen, dass du es wirklich "
-"löschen möchtest."
+msgstr "Das Medium wurde nicht gelöscht, da nicht angekreuzt hast, dass du es wirklich löschen möchtest."
-#: mediagoblin/user_pages/views.py:198
+#: mediagoblin/user_pages/views.py:200
msgid "You are about to delete another user's media. Proceed with caution."
-msgstr "Du versuchst Medien eines anderen Nutzers zu löschen. Sei vorsichtig."
-
-
+msgstr "Du versuchst Medien eines anderen Nutzers zu löschen. Sei bitte vorsichtig."
diff --git a/mediagoblin/i18n/en/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/en/LC_MESSAGES/mediagoblin.po
index 7c64c09f..e2c8ca35 100644
--- a/mediagoblin/i18n/en/LC_MESSAGES/mediagoblin.po
+++ b/mediagoblin/i18n/en/LC_MESSAGES/mediagoblin.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2012-02-26 15:51-0600\n"
+"POT-Creation-Date: 2012-06-01 16:32-0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,10 +17,6 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 0.9.6\n"
-#: mediagoblin/processing.py:153
-msgid "Invalid file given for media type."
-msgstr ""
-
#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41
msgid "Username"
msgstr ""
@@ -33,6 +29,14 @@ msgstr ""
msgid "Email address"
msgstr ""
+#: mediagoblin/auth/forms.py:51
+msgid "Username or email"
+msgstr ""
+
+#: mediagoblin/auth/forms.py:58
+msgid "Incorrect input"
+msgstr ""
+
#: mediagoblin/auth/views.py:55
msgid "Sorry, registration is disabled on this instance."
msgstr ""
@@ -67,21 +71,21 @@ msgstr ""
msgid "Resent your verification email."
msgstr ""
-#: mediagoblin/auth/views.py:262
+#: mediagoblin/auth/views.py:263
msgid "An email has been sent with instructions on how to change your password."
msgstr ""
-#: mediagoblin/auth/views.py:272
+#: mediagoblin/auth/views.py:273
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:284
+#: mediagoblin/auth/views.py:285
msgid "Couldn't find someone with that username or email."
msgstr ""
-#: mediagoblin/auth/views.py:332
+#: mediagoblin/auth/views.py:333
msgid "You can now log in using your new password."
msgstr ""
@@ -125,6 +129,7 @@ msgid ""
msgstr ""
#: mediagoblin/edit/forms.py:44 mediagoblin/submit/forms.py:41
+#: mediagoblin/templates/mediagoblin/utils/license.html:20
msgid "License"
msgstr ""
@@ -136,6 +141,10 @@ msgstr ""
msgid "Website"
msgstr ""
+#: mediagoblin/edit/forms.py:58
+msgid "This address contains errors"
+msgstr ""
+
#: mediagoblin/edit/forms.py:63
msgid "Old password"
msgstr ""
@@ -148,47 +157,48 @@ msgstr ""
msgid "New password"
msgstr ""
-#: mediagoblin/edit/views.py:68
+#: mediagoblin/edit/views.py:67
msgid "An entry with that slug already exists for this user."
msgstr ""
-#: mediagoblin/edit/views.py:89
+#: mediagoblin/edit/views.py:88
msgid "You are editing another user's media. Proceed with caution."
msgstr ""
-#: mediagoblin/edit/views.py:159
+#: mediagoblin/edit/views.py:158
msgid "You are editing a user's profile. Proceed with caution."
msgstr ""
-#: mediagoblin/edit/views.py:175
+#: mediagoblin/edit/views.py:174
msgid "Profile changes saved"
msgstr ""
-#: mediagoblin/edit/views.py:201
+#: mediagoblin/edit/views.py:200
msgid "Wrong password"
msgstr ""
-#: mediagoblin/edit/views.py:217
+#: mediagoblin/edit/views.py:216
msgid "Account settings saved"
msgstr ""
-#: mediagoblin/media_types/__init__.py:77
-msgid "Could not extract any file extension from \"{filename}\""
+#: mediagoblin/media_types/__init__.py:60
+#: mediagoblin/media_types/__init__.py:120
+msgid "Sorry, I don't support that file type :("
msgstr ""
-#: mediagoblin/media_types/__init__.py:88
-msgid "Sorry, I don't support that file type :("
+#: mediagoblin/processing/__init__.py:127
+msgid "Invalid file given for media type."
msgstr ""
#: mediagoblin/submit/forms.py:26
msgid "File"
msgstr ""
-#: mediagoblin/submit/views.py:54
+#: mediagoblin/submit/views.py:56
msgid "You must provide a file."
msgstr ""
-#: mediagoblin/submit/views.py:156
+#: mediagoblin/submit/views.py:163
msgid "Woohoo! Submitted!"
msgstr ""
@@ -210,33 +220,44 @@ msgid ""
"has been moved or deleted."
msgstr ""
-#: mediagoblin/templates/mediagoblin/base.html:46
+#: mediagoblin/templates/mediagoblin/base.html:47
msgid "MediaGoblin logo"
msgstr ""
-#: mediagoblin/templates/mediagoblin/base.html:51
-#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
-msgid "Add media"
+#: mediagoblin/templates/mediagoblin/base.html:57
+msgid "Verify your email!"
msgstr ""
-#: mediagoblin/templates/mediagoblin/base.html:62
-msgid "Verify your email!"
+#: mediagoblin/templates/mediagoblin/base.html:63
+msgid "+ Add media"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:65
+msgid "View your profile"
msgstr ""
-#: mediagoblin/templates/mediagoblin/base.html:69
-msgid "log out"
+#: mediagoblin/templates/mediagoblin/base.html:66
+msgid "Log out"
msgstr ""
-#: mediagoblin/templates/mediagoblin/base.html:72
-#: mediagoblin/templates/mediagoblin/auth/login.html:27
-#: mediagoblin/templates/mediagoblin/auth/login.html:45
+#: mediagoblin/templates/mediagoblin/base.html:71
+#: mediagoblin/templates/mediagoblin/auth/login.html:32
+#: mediagoblin/templates/mediagoblin/auth/login.html:50
msgid "Log in"
msgstr ""
-#: mediagoblin/templates/mediagoblin/base.html:84
+#: mediagoblin/templates/mediagoblin/base.html:85
msgid ""
"Powered by <a href=\"http://mediagoblin.org\">MediaGoblin</a>, a <a "
-"href=\"http://gnu.org/\">GNU</a> project"
+"href=\"http://gnu.org/\">GNU</a> project."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:88
+#, python-format
+msgid ""
+"Released under the <a "
+"href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a"
+" href=\"%(source_link)s\">Source code</a> available."
msgstr ""
#: mediagoblin/templates/mediagoblin/root.html:24
@@ -308,19 +329,19 @@ msgid ""
"a happy goblin!"
msgstr ""
-#: mediagoblin/templates/mediagoblin/auth/login.html:30
+#: mediagoblin/templates/mediagoblin/auth/login.html:35
msgid "Logging in failed!"
msgstr ""
-#: mediagoblin/templates/mediagoblin/auth/login.html:35
+#: mediagoblin/templates/mediagoblin/auth/login.html:40
msgid "Don't have an account yet?"
msgstr ""
-#: mediagoblin/templates/mediagoblin/auth/login.html:36
+#: mediagoblin/templates/mediagoblin/auth/login.html:41
msgid "Create one here!"
msgstr ""
-#: mediagoblin/templates/mediagoblin/auth/login.html:42
+#: mediagoblin/templates/mediagoblin/auth/login.html:47
msgid "Forgot your password?"
msgstr ""
@@ -376,18 +397,44 @@ msgid "Media tagged with: %(tag_name)s"
msgstr ""
#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:46
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:53
msgid "Original"
msgstr ""
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:33
+#: 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 <a href=\"http://getfirefox.com\">\n"
+"\t http://getfirefox.com</a>!"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:56
+msgid "Download"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:60
+msgid "original file"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:63
+msgid "WebM file (Vorbis codec)"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:40
msgid ""
"Sorry, this video will not work because \n"
"\t your web browser does not support HTML5 \n"
"\t video."
msgstr ""
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:36
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:43
msgid ""
"You can get a modern web browser that \n"
"\t can play this video at <a href=\"http://getfirefox.com\">\n"
@@ -412,55 +459,49 @@ msgstr ""
msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:72
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:46
#, python-format
-msgid "Added on %(date)s."
+msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:81
-msgid "Edit"
-msgstr ""
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:85
-msgid "Delete"
-msgstr ""
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:67
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:73
#, python-format
-msgid "%(comment_count)s comment"
+msgid "Image for %(media_title)s"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:93
-#, python-format
-msgid "%(comment_count)s comments"
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:87
+msgid "Edit"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:95
-msgid "No comments yet."
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
+msgid "Delete"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:103
-msgid "Add one"
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:124
+msgid "Add a comment"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:112
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:131
msgid ""
"You can use <a "
"href=\"http://daringfireball.net/projects/markdown/basics\">Markdown</a> "
"for formatting."
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:116
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:135
msgid "Add this comment"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:138
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:154
msgid "at"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:153
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:174
#, python-format
-msgid "<p>â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a></p>"
+msgid ""
+"<h3>Added on</h3>\n"
+" <p>%(date)s</p>"
msgstr ""
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30
@@ -469,7 +510,7 @@ msgid "Really delete %(title)s?"
msgstr ""
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:50
-msgid "Delete Permanently"
+msgid "Delete permanently"
msgstr ""
#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:22
@@ -564,6 +605,10 @@ msgid ""
"anything yet."
msgstr ""
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
+msgid "Add media"
+msgstr ""
+
#: mediagoblin/templates/mediagoblin/user_pages/user.html:163
#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72
msgid "There doesn't seem to be any media here yet..."
@@ -577,8 +622,13 @@ msgstr ""
msgid "Atom feed"
msgstr ""
-#: mediagoblin/templates/mediagoblin/utils/license.html:21
-msgid "License:"
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:25
+msgid "Location"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:38
+#, python-format
+msgid "View on <a href=\"%(osm_url)s\">OpenStreetMap</a>"
msgstr ""
#: mediagoblin/templates/mediagoblin/utils/license.html:25
@@ -597,25 +647,21 @@ msgstr ""
msgid "Go to page:"
msgstr ""
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:27
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:32
+#: 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:38
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:43
+#: 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 "View more media tagged with"
-msgstr ""
-
-#: mediagoblin/templates/mediagoblin/utils/tags.html:25
-msgid "or"
+msgid "Tagged with"
msgstr ""
-#: mediagoblin/tools/exif.py:68
+#: mediagoblin/tools/exif.py:75
msgid "Could not read the image file."
msgstr ""
@@ -631,15 +677,15 @@ msgstr ""
msgid "Your comment has been posted!"
msgstr ""
-#: mediagoblin/user_pages/views.py:181
+#: mediagoblin/user_pages/views.py:185
msgid "You deleted the media."
msgstr ""
-#: mediagoblin/user_pages/views.py:188
+#: mediagoblin/user_pages/views.py:192
msgid "The media was not deleted because you didn't check that you were sure."
msgstr ""
-#: mediagoblin/user_pages/views.py:196
+#: mediagoblin/user_pages/views.py:200
msgid "You are about to delete another user's media. Proceed with caution."
msgstr ""
diff --git a/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.mo
index f5a660d9..7f3d06cf 100644
--- a/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.mo
+++ b/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.mo
Binary files differ
diff --git a/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.po
index b3088b25..083311a1 100644
--- a/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.po
+++ b/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.po
@@ -10,9 +10,9 @@ msgid ""
msgstr ""
"Project-Id-Version: GNU MediaGoblin\n"
"Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n"
-"POT-Creation-Date: 2012-02-09 09:30-0600\n"
-"PO-Revision-Date: 2012-02-26 19:34+0000\n"
-"Last-Translator: aleksejrs <deletesoftware@yandex.ru>\n"
+"POT-Creation-Date: 2012-06-01 16:32-0500\n"
+"PO-Revision-Date: 2012-06-01 21:30+0000\n"
+"Last-Translator: cwebber <cwebber@dustycloud.org>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -21,10 +21,6 @@ msgstr ""
"Language: eo\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
-#: mediagoblin/processing.py:153
-msgid "Invalid file given for media type."
-msgstr "La provizita dosiero ne konformas al la informtipo."
-
#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41
msgid "Username"
msgstr "Uzantnomo"
@@ -37,56 +33,64 @@ msgstr "Pasvorto"
msgid "Email address"
msgstr "RetpoÅtadreso"
+#: mediagoblin/auth/forms.py:51
+msgid "Username or email"
+msgstr "Salutnomo aÅ­ retpoÅtadreso"
+
+#: mediagoblin/auth/forms.py:58
+msgid "Incorrect input"
+msgstr "La enigitaĵo malÄustas"
+
#: mediagoblin/auth/views.py:55
msgid "Sorry, registration is disabled on this instance."
msgstr "Bedaŭrinde, registrado estas malaktivigita en tiu ĉi instalaĵo."
-#: mediagoblin/auth/views.py:73
+#: mediagoblin/auth/views.py:75
msgid "Sorry, a user with that name already exists."
msgstr "BedaÅ­rinde, uzanto kun tiu nomo jam ekzistas."
-#: mediagoblin/auth/views.py:77
+#: mediagoblin/auth/views.py:79
msgid "Sorry, a user with that email address already exists."
msgstr "Ni bedaÅ­ras, sed konto kun tiu retpoÅtadreso jam ekzistas."
-#: mediagoblin/auth/views.py:180
+#: mediagoblin/auth/views.py:182
msgid ""
"Your email address has been verified. You may now login, edit your profile, "
"and submit images!"
msgstr "Via retpoÅtadreso estas konfirmita. Vi povas nun ensaluti, redakti vian profilon, kaj alÅuti bildojn!"
-#: mediagoblin/auth/views.py:186
+#: mediagoblin/auth/views.py:188
msgid "The verification key or user id is incorrect"
msgstr "La kontrol-kodo aÅ­ la uzantonomo ne estas korekta"
-#: mediagoblin/auth/views.py:204
+#: mediagoblin/auth/views.py:206
msgid "You must be logged in so we know who to send the email to!"
msgstr "Vi devas esti ensalutita, por ke ni sciu, al kiu sendi la retleteron!"
-#: mediagoblin/auth/views.py:212
+#: mediagoblin/auth/views.py:214
msgid "You've already verified your email address!"
msgstr "Vi jam konfirmis vian retpoÅtadreson!"
-#: mediagoblin/auth/views.py:225
+#: mediagoblin/auth/views.py:227
msgid "Resent your verification email."
msgstr "Resendi vian kontrol-mesaÄon."
-#: mediagoblin/auth/views.py:260
+#: mediagoblin/auth/views.py:263
msgid ""
"An email has been sent with instructions on how to change your password."
msgstr "Senditas retletero kun instrukcio pri kiel ÅanÄi vian pasvorton."
-#: mediagoblin/auth/views.py:270
+#: mediagoblin/auth/views.py:273
msgid ""
"Could not send password recovery email as your username is inactive or your "
"account's email address has not been verified."
msgstr "Ni ne povas sendi pasvortsavan retleteron, ĉar aÅ­ via konto estas neaktiva, aÅ­ Äia retpoÅtadreso ne estis konfirmita."
-#: mediagoblin/auth/views.py:282
+#: mediagoblin/auth/views.py:285
msgid "Couldn't find someone with that username or email."
msgstr "Mi trovis neniun kun tiu salutnomo aÅ­ retpoÅtadreso."
-#: mediagoblin/auth/views.py:330
+#: mediagoblin/auth/views.py:333
msgid "You can now log in using your new password."
msgstr "Nun vi povas ensaluti per via nova pasvorto."
@@ -129,6 +133,7 @@ msgid ""
msgstr "La dosiertitol-bazita parto de la dosieradreso. Ordinare ne necesas Äin ÅanÄi."
#: mediagoblin/edit/forms.py:44 mediagoblin/submit/forms.py:41
+#: mediagoblin/templates/mediagoblin/utils/license.html:20
msgid "License"
msgstr "Permesilo"
@@ -140,6 +145,10 @@ msgstr "Bio"
msgid "Website"
msgstr "Retejo"
+#: mediagoblin/edit/forms.py:58
+msgid "This address contains errors"
+msgstr "Ĉi tiu adreso enhavas erarojn"
+
#: mediagoblin/edit/forms.py:63
msgid "Old password"
msgstr "La malnova pasvorto"
@@ -152,47 +161,48 @@ msgstr "Enigu vian malnovan pasvorton por pruvi, ke ĉi tiu konto estas via."
msgid "New password"
msgstr "La nova pasvorto"
-#: mediagoblin/edit/views.py:68
+#: mediagoblin/edit/views.py:67
msgid "An entry with that slug already exists for this user."
msgstr "Ĉi tiu uzanto jam havas dosieron kun tiu distingiga adresparto."
-#: mediagoblin/edit/views.py:92
+#: mediagoblin/edit/views.py:88
msgid "You are editing another user's media. Proceed with caution."
msgstr "Vi priredaktas dosieron de alia uzanto. Agu singardeme."
-#: mediagoblin/edit/views.py:162
+#: mediagoblin/edit/views.py:158
msgid "You are editing a user's profile. Proceed with caution."
msgstr "Vi redaktas profilon de alia uzanto. Agu singardeme."
-#: mediagoblin/edit/views.py:180
+#: mediagoblin/edit/views.py:174
msgid "Profile changes saved"
msgstr "ProfilÅanÄoj estis konservitaj"
-#: mediagoblin/edit/views.py:206
+#: mediagoblin/edit/views.py:200
msgid "Wrong password"
msgstr "MalÄusta pasvorto"
-#: mediagoblin/edit/views.py:222
+#: mediagoblin/edit/views.py:216
msgid "Account settings saved"
msgstr "Kontagordoj estis konservitaj"
-#: mediagoblin/media_types/__init__.py:77
-msgid "Could not extract any file extension from \"{filename}\""
-msgstr "Ne eblis eltrovi finaĵon de la dosiernomo «{filename}»"
-
-#: mediagoblin/media_types/__init__.py:88
+#: mediagoblin/media_types/__init__.py:60
+#: mediagoblin/media_types/__init__.py:120
msgid "Sorry, I don't support that file type :("
msgstr "Mi pardonpetas, mi ne subtenas tiun dosiertipon :("
+#: mediagoblin/processing/__init__.py:127
+msgid "Invalid file given for media type."
+msgstr "La provizita dosiero ne konformas al la informtipo."
+
#: mediagoblin/submit/forms.py:26
msgid "File"
msgstr "Dosiero"
-#: mediagoblin/submit/views.py:54
+#: mediagoblin/submit/views.py:56
msgid "You must provide a file."
msgstr "Vi devas provizi dosieron."
-#: mediagoblin/submit/views.py:158
+#: mediagoblin/submit/views.py:163
msgid "Woohoo! Submitted!"
msgstr "Hura! AlÅutitas!"
@@ -214,34 +224,45 @@ msgid ""
" been moved or deleted."
msgstr "Se vi estas certa, ke la adreso estas Äusta, eble la serĉata de vi paÄo estis movita aÅ­ forigita."
-#: mediagoblin/templates/mediagoblin/base.html:46
+#: mediagoblin/templates/mediagoblin/base.html:47
msgid "MediaGoblin logo"
msgstr "Emblemo de MediaGoblin"
-#: mediagoblin/templates/mediagoblin/base.html:51
-#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
-msgid "Add media"
-msgstr "Aldoni dosieron"
-
-#: mediagoblin/templates/mediagoblin/base.html:62
+#: mediagoblin/templates/mediagoblin/base.html:57
msgid "Verify your email!"
msgstr "Konfirmu viecon de la retpoÅtadreso!"
-#: mediagoblin/templates/mediagoblin/base.html:69
-msgid "log out"
-msgstr "elsaluti"
+#: mediagoblin/templates/mediagoblin/base.html:63
+msgid "+ Add media"
+msgstr "+ Aldoni dosieron"
+
+#: mediagoblin/templates/mediagoblin/base.html:65
+msgid "View your profile"
+msgstr "Vidi vian profilon"
+
+#: mediagoblin/templates/mediagoblin/base.html:66
+msgid "Log out"
+msgstr "Elsaluti"
-#: mediagoblin/templates/mediagoblin/base.html:72
-#: mediagoblin/templates/mediagoblin/auth/login.html:27
-#: mediagoblin/templates/mediagoblin/auth/login.html:45
+#: mediagoblin/templates/mediagoblin/base.html:71
+#: mediagoblin/templates/mediagoblin/auth/login.html:32
+#: mediagoblin/templates/mediagoblin/auth/login.html:50
msgid "Log in"
msgstr "Ensaluti"
-#: mediagoblin/templates/mediagoblin/base.html:84
+#: mediagoblin/templates/mediagoblin/base.html:85
msgid ""
"Powered by <a href=\"http://mediagoblin.org\">MediaGoblin</a>, a <a "
-"href=\"http://gnu.org/\">GNU</a> project"
-msgstr "Funkcias per <a href=\"http://mediagoblin.org\">MediaGoblin</a>, unu el la <a href=\"http://gnu.org/\">projektoj de GNU</a>"
+"href=\"http://gnu.org/\">GNU</a> project."
+msgstr "Funkcias per <a href=\"http://mediagoblin.org\">MediaGoblin</a>, unu el la <a href=\"http://gnu.org/\">projektoj de GNU</a>."
+
+#: mediagoblin/templates/mediagoblin/base.html:88
+#, python-format
+msgid ""
+"Released under the <a "
+"href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a "
+"href=\"%(source_link)s\">Source code</a> available."
+msgstr "Disponigita laÅ­ la permesilo <a href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. Haveblas<a href=\"%(source_link)s\">fontotekstaro</a>."
#: mediagoblin/templates/mediagoblin/root.html:24
msgid "Explore"
@@ -309,19 +330,19 @@ msgid ""
"a happy goblin!"
msgstr "Saluton, %(username)s,\n\npor ÅanÄi vian pasvorton ĉe GNUa MediaGoblin, sekvu la jenan retadreson per via TTT-legilo:\n\n%(verification_url)s\n\nSe vi pensas, ke ĉi tiu retletero estas sendita erare, simple ignoru Äin kaj plu restu feliĉa koboldo!"
-#: mediagoblin/templates/mediagoblin/auth/login.html:30
+#: mediagoblin/templates/mediagoblin/auth/login.html:35
msgid "Logging in failed!"
msgstr "Ensaluto malsukcesis!"
-#: mediagoblin/templates/mediagoblin/auth/login.html:35
+#: mediagoblin/templates/mediagoblin/auth/login.html:40
msgid "Don't have an account yet?"
msgstr "Ĉu ankoraŭ sen konto?"
-#: mediagoblin/templates/mediagoblin/auth/login.html:36
+#: mediagoblin/templates/mediagoblin/auth/login.html:41
msgid "Create one here!"
msgstr "Kreu Äin ĉi tie!"
-#: mediagoblin/templates/mediagoblin/auth/login.html:42
+#: mediagoblin/templates/mediagoblin/auth/login.html:47
msgid "Forgot your password?"
msgstr "Ĉu vi forgesis vian pasvorton?"
@@ -377,18 +398,44 @@ msgid "Media tagged with: %(tag_name)s"
msgstr "Dosieroj kun etikedo: %(tag_name)s"
#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:46
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:53
msgid "Original"
msgstr "Originalo"
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:33
+#: 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 "BedaÅ­rinde, ĉi tiu sonregistraĵo ne ludiÄos, \n\tĉar via TTT-legilo ne povas ludi\n\tsonaĵojn, afiÅitajn laÅ­ HTML5."
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:47
+msgid ""
+"You can get a modern web browser that \n"
+"\tcan play the audio at <a href=\"http://getfirefox.com\">\n"
+"\t http://getfirefox.com</a>!"
+msgstr "Vi povas akiri modernan TTT-legilon, kapablan \n\tsonigi la registraĵon ĉe <a href=\"http://getfirefox.com\">\n\t http://getfirefox.com</a>!"
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:56
+msgid "Download"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:60
+msgid "original file"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:63
+msgid "WebM file (Vorbis codec)"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:40
msgid ""
"Sorry, this video will not work because \n"
"\t your web browser does not support HTML5 \n"
"\t video."
msgstr "Bedaŭrinde ĉi tiu filmo ne spekteblas, ĉar\n<span class=\"whitespace other\" title=\"Tab\">»</span> via TTT-legilo ne subtenas montradon\n<span class=\"whitespace other\" title=\"Tab\">»</span> de filmoj laŭ HTML5."
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:36
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:43
msgid ""
"You can get a modern web browser that \n"
"\t can play this video at <a href=\"http://getfirefox.com\">\n"
@@ -413,64 +460,58 @@ msgstr "Dosieroj de %(username)s"
msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media"
msgstr "Dosieroj de <a href=\"%(user_url)s\">%(username)s</a>"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:72
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:46
+#, python-format
+msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>"
+msgstr "■ПроÑмотр файлов Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ <a href=\"%(user_url)s\">%(username)s</a>"
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:67
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:73
#, python-format
-msgid "Added on %(date)s."
-msgstr "Aldonita je %(date)s."
+msgid "Image for %(media_title)s"
+msgstr "Bildo de «%(media_title)s»"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:81
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:87
msgid "Edit"
msgstr "ÅœanÄi"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:85
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
msgid "Delete"
msgstr "Forigi"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
-#, python-format
-msgid "%(comment_count)s comment"
-msgstr "%(comment_count)s komento"
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:93
-#, python-format
-msgid "%(comment_count)s comments"
-msgstr "%(comment_count)s komentoj"
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:95
-msgid "No comments yet."
-msgstr "Estas neniom da komentoj."
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:124
+msgid "Add a comment"
+msgstr "Aldoni komenton"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:103
-msgid "Add one"
-msgstr "Komenti"
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:112
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:131
msgid ""
"You can use <a "
"href=\"http://daringfireball.net/projects/markdown/basics\">Markdown</a> for"
" formatting."
msgstr "Vi povas uzi por markado la lingvon «<a href=\"http://daringfireball.net/projects/markdown/basics\">Markdown</a>»."
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:116
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:135
msgid "Add this comment"
msgstr "Aldoni ĉi tiun komenton"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:138
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:154
msgid "at"
msgstr "je"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:153
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:174
#, python-format
-msgid "<p>â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a></p>"
-msgstr "<p>â– Foliumado de dosieraro de <a href=\"%(user_url)s\">%(username)s</a></p>"
+msgid ""
+"<h3>Added on</h3>\n"
+" <p>%(date)s</p>"
+msgstr "<h3>Aldonita je</h3>\n <p>la %(date)s</p>"
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30
#, python-format
msgid "Really delete %(title)s?"
-msgstr "Ĉu efektive forigi %(title)s?"
+msgstr "Ĉu vere forigi %(title)s?"
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:50
-msgid "Delete Permanently"
+msgid "Delete permanently"
msgstr "Forigi senrevene"
#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:22
@@ -567,6 +608,10 @@ msgid ""
"anything yet."
msgstr "Äœuste ĉi tie aperos viaj dosieroj, sed vi Åajne ankoraÅ­ nenion alÅutis."
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
+msgid "Add media"
+msgstr "Aldoni dosieron"
+
#: mediagoblin/templates/mediagoblin/user_pages/user.html:163
#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72
msgid "There doesn't seem to be any media here yet..."
@@ -580,9 +625,14 @@ msgstr "flusimbolo"
msgid "Atom feed"
msgstr "Atom-a informfluo"
-#: mediagoblin/templates/mediagoblin/utils/license.html:21
-msgid "License:"
-msgstr "Permesilo:"
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:25
+msgid "Location"
+msgstr "Loko"
+
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:38
+#, python-format
+msgid "View on <a href=\"%(osm_url)s\">OpenStreetMap</a>"
+msgstr "Vidi sur <a href=\"%(osm_url)s\">OpenStreetMap</a>"
#: mediagoblin/templates/mediagoblin/utils/license.html:25
msgid "All rights reserved"
@@ -600,48 +650,44 @@ msgstr "Malpli novaj →"
msgid "Go to page:"
msgstr "Iri al paÄo:"
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:27
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:32
+#: mediagoblin/templates/mediagoblin/utils/prev_next.html:28
+#: mediagoblin/templates/mediagoblin/utils/prev_next.html:33
msgid "newer"
msgstr "pli nova"
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:38
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:43
+#: mediagoblin/templates/mediagoblin/utils/prev_next.html:39
+#: mediagoblin/templates/mediagoblin/utils/prev_next.html:44
msgid "older"
msgstr "malpli nova"
#: mediagoblin/templates/mediagoblin/utils/tags.html:20
-msgid "View more media tagged with"
-msgstr "Vidi aliajn dosierojn kun la etikedo"
-
-#: mediagoblin/templates/mediagoblin/utils/tags.html:25
-msgid "or"
-msgstr "aÅ­"
+msgid "Tagged with"
+msgstr "Markita per"
-#: mediagoblin/tools/exif.py:68
+#: mediagoblin/tools/exif.py:75
msgid "Could not read the image file."
msgstr "Malsukcesis lego de la bildodosiero"
#: mediagoblin/user_pages/forms.py:30
msgid "I am sure I want to delete this"
-msgstr "Mi estas certa, ke mi volas forigi ĉi tion"
+msgstr "Jes, mi volas forigi ĉi tion."
-#: mediagoblin/user_pages/views.py:155
+#: mediagoblin/user_pages/views.py:153
msgid "Oops, your comment was empty."
msgstr "Oj, via komento estis malplena."
-#: mediagoblin/user_pages/views.py:161
+#: mediagoblin/user_pages/views.py:159
msgid "Your comment has been posted!"
msgstr "Via komento estis afiÅita!"
-#: mediagoblin/user_pages/views.py:183
+#: mediagoblin/user_pages/views.py:185
msgid "You deleted the media."
msgstr "Vi forigis la dosieron."
-#: mediagoblin/user_pages/views.py:190
+#: mediagoblin/user_pages/views.py:192
msgid "The media was not deleted because you didn't check that you were sure."
msgstr "La dosiero ne estis forigita, ĉar vi ne konfirmis vian certecon per la markilo."
-#: mediagoblin/user_pages/views.py:198
+#: mediagoblin/user_pages/views.py:200
msgid "You are about to delete another user's media. Proceed with caution."
msgstr "Vi estas forigonta dosieron de alia uzanto. Estu singardema."
diff --git a/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.mo
index 93a849fb..00452c3c 100644
--- a/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.mo
+++ b/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.mo
Binary files differ
diff --git a/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.po
index 3bb46098..782a6fb4 100644
--- a/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.po
+++ b/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.po
@@ -8,17 +8,18 @@
# <jacobo@gnu.org>, 2011, 2012.
# Javier Di Mauro <javierdimauro@gmail.com>, 2011.
# <juangsub@gmail.com>, 2011.
-# <juanma@kde.org.ar>, 2011.
+# <juanma@kde.org.ar>, 2011, 2012.
# Mario Rodriguez <msrodriguez00@gmail.com>, 2011.
# <mu@member.fsf.org>, 2011.
+# <shackra@riseup.net>, 2012.
msgid ""
msgstr ""
"Project-Id-Version: GNU MediaGoblin\n"
-"Report-Msgid-Bugs-To: http://bugs.foocorp.net/projects/mediagoblin/issues\n"
-"POT-Creation-Date: 2012-01-29 13:31-0600\n"
-"PO-Revision-Date: 2012-01-29 19:29+0000\n"
+"Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n"
+"POT-Creation-Date: 2012-06-01 16:32-0500\n"
+"PO-Revision-Date: 2012-06-01 21:30+0000\n"
"Last-Translator: cwebber <cwebber@dustycloud.org>\n"
-"Language-Team: Spanish (Castilian) (http://www.transifex.net/projects/p/mediagoblin/team/es/)\n"
+"Language-Team: Spanish (Castilian) (http://www.transifex.net/projects/p/mediagoblin/language/es/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -26,10 +27,6 @@ msgstr ""
"Language: es\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
-#: mediagoblin/processing.py:143
-msgid "Invalid file given for media type."
-msgstr "Archivo inválido para el formato seleccionado."
-
#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41
msgid "Username"
msgstr "Nombre de usuario"
@@ -42,68 +39,64 @@ msgstr "Contraseña"
msgid "Email address"
msgstr "Dirección de correo electrónico"
+#: mediagoblin/auth/forms.py:51
+msgid "Username or email"
+msgstr "Nombre de usuario o email"
+
+#: mediagoblin/auth/forms.py:58
+msgid "Incorrect input"
+msgstr "Los datos ingresados son incorrectos"
+
#: mediagoblin/auth/views.py:55
msgid "Sorry, registration is disabled on this instance."
msgstr "Lo sentimos, el registro está deshabilitado en este momento."
-#: mediagoblin/auth/views.py:73
+#: mediagoblin/auth/views.py:75
msgid "Sorry, a user with that name already exists."
msgstr "Lo sentimos, ya existe un usuario con ese nombre."
-#: mediagoblin/auth/views.py:77
+#: mediagoblin/auth/views.py:79
msgid "Sorry, a user with that email address already exists."
msgstr "Lo sentimos, ya existe un usuario con esa dirección de email."
-#: mediagoblin/auth/views.py:180
+#: mediagoblin/auth/views.py:182
msgid ""
"Your email address has been verified. You may now login, edit your profile, "
"and submit images!"
-msgstr ""
-"Tu dirección de correo electrónico ha sido verificada. ¡Ahora puedes "
-"ingresar, editar tu perfil, y enviar imágenes!"
+msgstr "Tu dirección de correo electrónico ha sido verificada. ¡Ahora puedes ingresar, editar tu perfil, y enviar imágenes!"
-#: mediagoblin/auth/views.py:186
+#: mediagoblin/auth/views.py:188
msgid "The verification key or user id is incorrect"
-msgstr ""
-"La clave de verificación o la identificación de usuario son incorrectas"
+msgstr "La clave de verificación o la identificación de usuario son incorrectas"
-#: mediagoblin/auth/views.py:204
+#: mediagoblin/auth/views.py:206
msgid "You must be logged in so we know who to send the email to!"
-msgstr ""
-"¡Debes iniciar sesión para que podamos saber a quién le enviamos el correo "
-"electrónico!"
+msgstr "¡Debes iniciar sesión para que podamos saber a quién le enviamos el correo electrónico!"
-#: mediagoblin/auth/views.py:212
+#: mediagoblin/auth/views.py:214
msgid "You've already verified your email address!"
msgstr "¡Ya has verificado tu dirección de correo!"
-#: mediagoblin/auth/views.py:225
+#: mediagoblin/auth/views.py:227
msgid "Resent your verification email."
msgstr "Se reenvió tu correo electrónico de verificación."
-#: mediagoblin/auth/views.py:260
+#: mediagoblin/auth/views.py:263
msgid ""
"An email has been sent with instructions on how to change your password."
-msgstr ""
-"Un correo electrónico ha sido enviado con instrucciones sobre cómo cambiar "
-"tu contraseña."
+msgstr "Un correo electrónico ha sido enviado con instrucciones sobre cómo cambiar tu contraseña."
-#: mediagoblin/auth/views.py:270
+#: mediagoblin/auth/views.py:273
msgid ""
"Could not send password recovery email as your username is inactive or your "
"account's email address has not been verified."
-msgstr ""
-"No se pudo enviar un correo electrónico de recuperación de contraseñas "
-"porque su nombre de usuario está inactivo o la dirección de su cuenta de "
-"correo electrónico no ha sido verificada."
+msgstr "No se pudo enviar un correo electrónico de recuperación de contraseñas porque su nombre de usuario está inactivo o la dirección de su cuenta de correo electrónico no ha sido verificada."
-#: mediagoblin/auth/views.py:282
+#: mediagoblin/auth/views.py:285
msgid "Couldn't find someone with that username or email."
-msgstr ""
-"No se pudo encontrar a alguien con ese nombre de usuario o correo "
-"electrónico."
+msgstr "No se pudo encontrar a alguien con ese nombre de usuario o correo electrónico."
-#: mediagoblin/auth/views.py:330
+#: mediagoblin/auth/views.py:333
msgid "You can now log in using your new password."
msgstr "Ahora tu puedes entrar usando tu nueva contraseña."
@@ -121,10 +114,7 @@ msgid ""
"You can use\n"
" <a href=\"http://daringfireball.net/projects/markdown/basics\">\n"
" Markdown</a> for formatting."
-msgstr ""
-"Tu puedes usar\n"
-" <a href=\"http://daringfireball.net/projects/markdown/basics\">\n"
-" Markdown</a> Para el formato."
+msgstr "Puedes usar\n <a href=\"http://daringfireball.net/projects/markdown/basics\">\n Markdown</a> para el formato."
#: mediagoblin/edit/forms.py:33 mediagoblin/submit/forms.py:36
msgid "Tags"
@@ -146,13 +136,12 @@ msgstr "La ficha no puede estar vacía"
msgid ""
"The title part of this media's address. You usually don't need to change "
"this."
-msgstr ""
-"El título de esta parte de la dirección de los contenidos. Por lo general no"
-" es necesario cambiar esto."
+msgstr "El título de esta parte de la dirección de los contenidos. Por lo general no es necesario cambiar esto."
#: mediagoblin/edit/forms.py:44 mediagoblin/submit/forms.py:41
+#: mediagoblin/templates/mediagoblin/utils/license.html:20
msgid "License"
-msgstr ""
+msgstr "Licencia"
#: mediagoblin/edit/forms.py:50
msgid "Bio"
@@ -162,60 +151,64 @@ msgstr "Bio"
msgid "Website"
msgstr "Sitio web"
+#: mediagoblin/edit/forms.py:58
+msgid "This address contains errors"
+msgstr "La dirección contiene errores"
+
#: mediagoblin/edit/forms.py:63
msgid "Old password"
msgstr "Vieja contraseña"
#: mediagoblin/edit/forms.py:65
msgid "Enter your old password to prove you own this account."
-msgstr ""
-"Escriba la anterior contraseña para demostrar la propiedad de la cuenta."
+msgstr "Escriba la anterior contraseña para demostrar la propiedad de la cuenta."
#: mediagoblin/edit/forms.py:68
msgid "New password"
msgstr "Nueva contraseña"
-#: mediagoblin/edit/views.py:68
+#: mediagoblin/edit/views.py:67
msgid "An entry with that slug already exists for this user."
msgstr "Una entrada con esa ficha ya existe para este usuario."
-#: mediagoblin/edit/views.py:92
+#: mediagoblin/edit/views.py:88
msgid "You are editing another user's media. Proceed with caution."
msgstr "Estás editando el contenido de otro usuario. Proceder con precaución."
-#: mediagoblin/edit/views.py:162
+#: mediagoblin/edit/views.py:158
msgid "You are editing a user's profile. Proceed with caution."
msgstr "Estás editando un perfil de usuario. Proceder con precaución."
-#: mediagoblin/edit/views.py:180
+#: mediagoblin/edit/views.py:174
msgid "Profile changes saved"
msgstr "Los cambios de perfil fueron salvados"
-#: mediagoblin/edit/views.py:206
+#: mediagoblin/edit/views.py:200
msgid "Wrong password"
msgstr "Contraseña incorrecta"
-#: mediagoblin/edit/views.py:222
+#: mediagoblin/edit/views.py:216
msgid "Account settings saved"
msgstr "las configuraciones de cuenta fueron salvadas"
-#: mediagoblin/media_types/__init__.py:77
-msgid "Could not extract any file extension from \"{filename}\""
-msgstr "No se pudo extraer ninguna extensión de archivo de \"{filename}\""
-
-#: mediagoblin/media_types/__init__.py:88
+#: mediagoblin/media_types/__init__.py:60
+#: mediagoblin/media_types/__init__.py:120
msgid "Sorry, I don't support that file type :("
msgstr "Lo sentidos, No soportamos ese tipo de archivo :("
+#: mediagoblin/processing/__init__.py:127
+msgid "Invalid file given for media type."
+msgstr "Archivo inválido para el formato seleccionado."
+
#: mediagoblin/submit/forms.py:26
msgid "File"
msgstr "Archivo"
-#: mediagoblin/submit/views.py:54
+#: mediagoblin/submit/views.py:56
msgid "You must provide a file."
msgstr "Debes proporcionar un archivo."
-#: mediagoblin/submit/views.py:158
+#: mediagoblin/submit/views.py:163
msgid "Woohoo! Submitted!"
msgstr "¡Yujú! ¡Enviado!"
@@ -235,40 +228,47 @@ msgstr "Parece no haber una página en esta dirección. ¡Lo siento!"
msgid ""
"If you're sure the address is correct, maybe the page you're looking for has"
" been moved or deleted."
-msgstr ""
-"Si estás seguro que la dirección es correcta, puede ser que la pagina haya "
-"sido movida o borrada."
+msgstr "Si estás seguro que la dirección es correcta, puede ser que la pagina haya sido movida o borrada."
-#: mediagoblin/templates/mediagoblin/base.html:46
+#: mediagoblin/templates/mediagoblin/base.html:47
msgid "MediaGoblin logo"
msgstr "Logo de MediaGoblin"
-#: mediagoblin/templates/mediagoblin/base.html:51
-#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
-msgid "Add media"
-msgstr "Añadir contenido"
-
-#: mediagoblin/templates/mediagoblin/base.html:62
+#: mediagoblin/templates/mediagoblin/base.html:57
msgid "Verify your email!"
msgstr "¡Verifica tu email!"
-#: mediagoblin/templates/mediagoblin/base.html:69
-msgid "log out"
-msgstr "Cerrar sesión"
+#: mediagoblin/templates/mediagoblin/base.html:63
+msgid "+ Add media"
+msgstr "+Agregar contenido"
+
+#: mediagoblin/templates/mediagoblin/base.html:65
+msgid "View your profile"
+msgstr "Ver tu perfil"
+
+#: mediagoblin/templates/mediagoblin/base.html:66
+msgid "Log out"
+msgstr "Salir "
-#: mediagoblin/templates/mediagoblin/base.html:72
-#: mediagoblin/templates/mediagoblin/auth/login.html:27
-#: mediagoblin/templates/mediagoblin/auth/login.html:45
+#: mediagoblin/templates/mediagoblin/base.html:71
+#: mediagoblin/templates/mediagoblin/auth/login.html:32
+#: mediagoblin/templates/mediagoblin/auth/login.html:50
msgid "Log in"
msgstr "Conectarse"
-#: mediagoblin/templates/mediagoblin/base.html:84
+#: mediagoblin/templates/mediagoblin/base.html:85
msgid ""
"Powered by <a href=\"http://mediagoblin.org\">MediaGoblin</a>, a <a "
-"href=\"http://gnu.org/\">GNU</a> project"
-msgstr ""
-"Potenciado por <a href=\"http://mediagoblin.org\">MediaGoblin</a>, a <a "
-"href=\"http://gnu.org/\">GNU</a> project"
+"href=\"http://gnu.org/\">GNU</a> project."
+msgstr "Potenciado por <a href=\"http://mediagoblin.org\">MediaGoblin</a>, un proyecto <a href=\"http://gnu.org/\">GNU</a>."
+
+#: mediagoblin/templates/mediagoblin/base.html:88
+#, python-format
+msgid ""
+"Released under the <a "
+"href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a "
+"href=\"%(source_link)s\">Source code</a> available."
+msgstr "Publicado bajo la <a href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a href=\"%(source_link)s\"> Código fuente</a> disponible."
#: mediagoblin/templates/mediagoblin/root.html:24
msgid "Explore"
@@ -282,18 +282,13 @@ msgstr "Hola, ¡bienvenido a este sitio de MediaGoblin!"
msgid ""
"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, an "
"extraordinarily great piece of media hosting software."
-msgstr ""
-"Este sitio está montado con <a "
-"href=\"http://mediagoblin.org\">MediaGoblin</a>, un programa libre buenísimo"
-" para gestionar contenido multimedia."
+msgstr "Este sitio está montado con <a href=\"http://mediagoblin.org\">MediaGoblin</a>, un programa libre buenísimo para gestionar contenido multimedia."
#: mediagoblin/templates/mediagoblin/root.html:29
msgid ""
"To add your own media, place comments, save your favourites and more, you "
"can log in with your MediaGoblin account."
-msgstr ""
-"Para añadir tus propios contenidos, dejar comentarios, guardar tus favoritos"
-" y más, puedes iniciar sesión con tu cuenta de MediaGoblin."
+msgstr "Para añadir tus propios contenidos, dejar comentarios, guardar tus favoritos y más, puedes iniciar sesión con tu cuenta de MediaGoblin."
#: mediagoblin/templates/mediagoblin/root.html:31
msgid "Don't have one yet? It's easy!"
@@ -305,10 +300,7 @@ msgid ""
"<a class=\"button_action_highlight\" href=\"%(register_url)s\">Create an account at this site</a>\n"
" or\n"
" <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">Set up MediaGoblin on your own server</a>"
-msgstr ""
-"<a class=\"button_action_highlight\" href=\"%(register_url)s\">Crea una cuenta en este sitio</a>\n"
-" o\n"
-" <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">Instala Mediagoblin en tu propio servidor</a>"
+msgstr "<a class=\"button_action_highlight\" href=\"%(register_url)s\">Crea una cuenta en este sitio</a>\n o\n <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">Instala Mediagoblin en tu propio servidor</a>"
#: mediagoblin/templates/mediagoblin/root.html:40
msgid "Most recent media"
@@ -342,28 +334,21 @@ msgid ""
"\n"
"If you think this is an error, just ignore this email and continue being\n"
"a happy goblin!"
-msgstr ""
-"Hola %(username)s,\n"
-"\n"
-"Para cambiar tu contraseña de GNU MediaGoblin, abre la siguiente URL en un navegador:\n"
-"\n"
-"%(verification_url)s \n"
-"\n"
-"Si piensas que esto es un error, simplemente ignora este mensaje y sigue siendo un trasgo feliz."
+msgstr "Hola %(username)s,\n\nPara cambiar tu contraseña de GNU MediaGoblin, abre la siguiente URL en un navegador:\n\n%(verification_url)s \n\nSi piensas que esto es un error, simplemente ignora este mensaje y sigue siendo un trasgo feliz."
-#: mediagoblin/templates/mediagoblin/auth/login.html:30
+#: mediagoblin/templates/mediagoblin/auth/login.html:35
msgid "Logging in failed!"
msgstr "¡Falló el inicio de sesión!"
-#: mediagoblin/templates/mediagoblin/auth/login.html:35
+#: mediagoblin/templates/mediagoblin/auth/login.html:40
msgid "Don't have an account yet?"
msgstr "¿No tienes una cuenta?"
-#: mediagoblin/templates/mediagoblin/auth/login.html:36
+#: mediagoblin/templates/mediagoblin/auth/login.html:41
msgid "Create one here!"
msgstr "¡Crea una aquí!"
-#: mediagoblin/templates/mediagoblin/auth/login.html:42
+#: mediagoblin/templates/mediagoblin/auth/login.html:47
msgid "Forgot your password?"
msgstr "¿Olvidaste tu contraseña?"
@@ -384,12 +369,7 @@ msgid ""
"your web browser:\n"
"\n"
"%(verification_url)s"
-msgstr ""
-"Hola %(username)s,\n"
-"\n"
-"para activar tu cuenta de GNU MediaGoblin, abre la siguiente URL en tu navegador:\n"
-"\n"
-"%(verification_url)s "
+msgstr "Hola %(username)s,\n\npara activar tu cuenta de GNU MediaGoblin, abre la siguiente URL en tu navegador:\n\n%(verification_url)s "
#: mediagoblin/templates/mediagoblin/edit/edit.html:29
#, python-format
@@ -410,7 +390,7 @@ msgstr "Guardar cambios"
#: mediagoblin/templates/mediagoblin/edit/edit_account.html:34
#, python-format
msgid "Changing %(username)s's account settings"
-msgstr "Cambio de %(username)s's la configuración de la cuenta "
+msgstr "Cambio de %(username)s la configuración de la cuenta "
#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29
#, python-format
@@ -424,29 +404,49 @@ msgid "Media tagged with: %(tag_name)s"
msgstr "Contenido etiquetado con: %(tag_name)s"
#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:46
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:53
msgid "Original"
msgstr "Original"
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:33
+#: 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 "Disculpa, este audio audio podría no funcionar porque \n\ttú explorador no soportar HTML5 \n\taudio."
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:47
+msgid ""
+"You can get a modern web browser that \n"
+"\tcan play the audio at <a href=\"http://getfirefox.com\">\n"
+"\t http://getfirefox.com</a>!"
+msgstr "Tú puedes obtener un explorador más moderno que \n\tpueda reproducir el audio <a href=\"http://getfirefox.com\">\n\t http://getfirefox.com</a>!"
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:56
+msgid "Download"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:60
+msgid "original file"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:63
+msgid "WebM file (Vorbis codec)"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:40
msgid ""
"Sorry, this video will not work because \n"
"\t your web browser does not support HTML5 \n"
"\t video."
-msgstr ""
-"Lo sentidos, este video no va funcionar porque\n"
-"<span class=\"whitespace other\" title=\"Tab\">»</span> Tu explorador web no soporta HTML5\n"
-"<span class=\"whitespace other\" title=\"Tab\">»</span> video."
+msgstr "Lo sentidos, este video no va funcionar porque\n<span class=\"whitespace other\" title=\"Tab\">»</span> Tu explorador web no soporta HTML5\n<span class=\"whitespace other\" title=\"Tab\">»</span> video."
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:36
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:43
msgid ""
"You can get a modern web browser that \n"
"\t can play this video at <a href=\"http://getfirefox.com\">\n"
"\t http://getfirefox.com</a>!"
-msgstr ""
-"Ti puedes conseguir un navegador web moderno que\n"
-"<span class=\"whitespace other\" title=\"Tab\">»</span> que puede reproducir este vídeo en <a href=\"http://getfirefox.com\">\n"
-"<span class=\"whitespace other\" title=\"Tab\">»</span> http://getfirefox.com</a>!"
+msgstr "Tú puedes conseguir un navegador web moderno que\n<span class=\"whitespace other\" title=\"Tab\">»</span> puede reproducir este vídeo en <a href=\"http://getfirefox.com\">\n<span class=\"whitespace other\" title=\"Tab\">»</span> http://getfirefox.com</a>!"
#: mediagoblin/templates/mediagoblin/submit/start.html:26
msgid "Add your media"
@@ -466,56 +466,50 @@ msgstr "Contenidos de %(username)s"
msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media"
msgstr "Contenido de <a href=\"%(user_url)s\">%(username)s</a>'s"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:72
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:46
#, python-format
-msgid "Added on %(date)s."
-msgstr "Agregado el %(date)s."
+msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>"
+msgstr "â– Explorando contenido de <a href=\"%(user_url)s\">%(username)s</a>"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:81
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:67
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:73
+#, python-format
+msgid "Image for %(media_title)s"
+msgstr "Imágenes para %(media_title)s"
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:87
msgid "Edit"
msgstr "Editar"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:85
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
msgid "Delete"
msgstr "Borrar"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
-#, python-format
-msgid "%(comment_count)s comment"
-msgstr "%(comment_count)s comentarios de"
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:93
-#, python-format
-msgid "%(comment_count)s comments"
-msgstr "%(comment_count)s comentarios de"
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:95
-msgid "No comments yet."
-msgstr "No hay comentarios aún. "
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:124
+msgid "Add a comment"
+msgstr "Añadir un comenario"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:103
-msgid "Add one"
-msgstr "Añadir un"
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:112
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:131
msgid ""
"You can use <a "
"href=\"http://daringfireball.net/projects/markdown/basics\">Markdown</a> for"
" formatting."
-msgstr ""
+msgstr "Puedes usar <a href=\"http://daringfireball.net/projects/markdown/basics\">Markdown</a> para el formato."
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:116
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:135
msgid "Add this comment"
msgstr "Añade un comentario "
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:138
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:154
msgid "at"
msgstr "en"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:153
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:174
#, python-format
-msgid "<p>â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a></p>"
-msgstr "<p>â– Buscar contenido por <a href=\"%(user_url)s\">%(username)s</a></p>"
+msgid ""
+"<h3>Added on</h3>\n"
+" <p>%(date)s</p>"
+msgstr "<h3>Añadido en</h3>\n <p>%(date)s</p>"
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30
#, python-format
@@ -523,7 +517,7 @@ msgid "Really delete %(title)s?"
msgstr "¿Realmente deseas eliminar %(title)s?"
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:50
-msgid "Delete Permanently"
+msgid "Delete permanently"
msgstr "Eliminar permanentemente"
#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:22
@@ -533,9 +527,7 @@ msgstr "Panel de procesamiento de contenido"
#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:25
msgid ""
"You can track the state of media being processed for your gallery here."
-msgstr ""
-"Puedes hacer un seguimiento del estado de tu contenido siendo procesado "
-"aquí."
+msgstr "Puedes hacer un seguimiento del estado de tu contenido siendo procesado aquí."
#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:28
msgid "Media in-processing"
@@ -571,9 +563,7 @@ msgstr "¡Casi hemos terminado! Solo falta activar la cuenta."
#: mediagoblin/templates/mediagoblin/user_pages/user.html:58
msgid ""
"An email should arrive in a few moments with instructions on how to do so."
-msgstr ""
-"En unos momentos te debería llegar un correo electrónico con las "
-"instrucciones para hacerlo."
+msgstr "En unos momentos te debería llegar un correo electrónico con las instrucciones para hacerlo."
#: mediagoblin/templates/mediagoblin/user_pages/user.html:62
msgid "In case it doesn't:"
@@ -587,18 +577,14 @@ msgstr "Reenviar correo electrónico de verificación"
msgid ""
"Someone has registered an account with this username, but it still has to be"
" activated."
-msgstr ""
-"Alguien ya registró una cuenta con ese nombre de usuario, pero todavía no "
-"fue activada."
+msgstr "Alguien ya registró una cuenta con ese nombre de usuario, pero todavía no fue activada."
#: 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 <a "
"href=\"%(login_url)s\">log in</a> and resend it."
-msgstr ""
-"Si tú eres esa persona, pero has perdido tu correo electrónico de "
-"verificación, puedes <a href=\"%(login_url)s\">acceder</a> y reenviarlo."
+msgstr "Si tú eres esa persona, pero has perdido tu correo electrónico de verificación, puedes <a href=\"%(login_url)s\">acceder</a> y reenviarlo."
#: mediagoblin/templates/mediagoblin/user_pages/user.html:96
msgid "Here's a spot to tell others about yourself."
@@ -626,8 +612,11 @@ msgstr "Ver todo el contenido de %(username)s"
msgid ""
"This is where your media will appear, but you don't seem to have added "
"anything yet."
-msgstr ""
-"Aquí es donde tú contenido estará, pero parece que aún no has agregado nada."
+msgstr "Aquí es donde tú contenido estará, pero parece que aún no has agregado nada."
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
+msgid "Add media"
+msgstr "Añadir contenido"
#: mediagoblin/templates/mediagoblin/user_pages/user.html:163
#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72
@@ -642,13 +631,18 @@ msgstr "ícono feed"
msgid "Atom feed"
msgstr "Atom feed"
-#: mediagoblin/templates/mediagoblin/utils/license.html:21
-msgid "License:"
-msgstr ""
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:25
+msgid "Location"
+msgstr "Locación"
+
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:38
+#, python-format
+msgid "View on <a href=\"%(osm_url)s\">OpenStreetMap</a>"
+msgstr "Ver en <a href=\"%(osm_url)s\">OpenStreetMap</a>"
#: mediagoblin/templates/mediagoblin/utils/license.html:25
msgid "All rights reserved"
-msgstr ""
+msgstr "Todos los derechos reservados"
#: mediagoblin/templates/mediagoblin/utils/pagination.html:39
msgid "↠Newer"
@@ -662,52 +656,44 @@ msgstr "Más viejo →"
msgid "Go to page:"
msgstr "Ir a la página:"
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:27
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:32
+#: mediagoblin/templates/mediagoblin/utils/prev_next.html:28
+#: mediagoblin/templates/mediagoblin/utils/prev_next.html:33
msgid "newer"
msgstr "Más nuevo"
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:38
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:43
+#: mediagoblin/templates/mediagoblin/utils/prev_next.html:39
+#: mediagoblin/templates/mediagoblin/utils/prev_next.html:44
msgid "older"
msgstr "Más viejo"
#: mediagoblin/templates/mediagoblin/utils/tags.html:20
-msgid "View more media tagged with"
-msgstr "Ver más contenido etiquetado con"
+msgid "Tagged with"
+msgstr "Marcado con"
-#: mediagoblin/templates/mediagoblin/utils/tags.html:25
-msgid "or"
-msgstr "o"
-
-#: mediagoblin/tools/exif.py:68
+#: mediagoblin/tools/exif.py:75
msgid "Could not read the image file."
-msgstr ""
+msgstr "No se pudo leer el archivo de imagen."
#: mediagoblin/user_pages/forms.py:30
msgid "I am sure I want to delete this"
msgstr "Estoy seguro de que quiero borrar esto"
-#: mediagoblin/user_pages/views.py:155
+#: mediagoblin/user_pages/views.py:153
msgid "Oops, your comment was empty."
msgstr "Ups, tu comentario estaba vacío."
-#: mediagoblin/user_pages/views.py:161
+#: mediagoblin/user_pages/views.py:159
msgid "Your comment has been posted!"
msgstr "¡Tu comentario ha sido publicado!"
-#: mediagoblin/user_pages/views.py:183
+#: mediagoblin/user_pages/views.py:185
msgid "You deleted the media."
msgstr "Eliminaste el contenido"
-#: mediagoblin/user_pages/views.py:190
+#: mediagoblin/user_pages/views.py:192
msgid "The media was not deleted because you didn't check that you were sure."
msgstr "El contenido no se eliminó porque no marcaste que estabas seguro."
-#: mediagoblin/user_pages/views.py:198
+#: mediagoblin/user_pages/views.py:200
msgid "You are about to delete another user's media. Proceed with caution."
-msgstr ""
-"Estás a punto de eliminar un contenido de otro usuario. Proceder con "
-"precaución."
-
-
+msgstr "Estás a punto de eliminar un contenido de otro usuario. Proceder con precaución."
diff --git a/mediagoblin/i18n/fa/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/fa/LC_MESSAGES/mediagoblin.mo
new file mode 100644
index 00000000..bf521753
--- /dev/null
+++ b/mediagoblin/i18n/fa/LC_MESSAGES/mediagoblin.mo
Binary files differ
diff --git a/mediagoblin/i18n/fa/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/fa/LC_MESSAGES/mediagoblin.po
new file mode 100644
index 00000000..c2980cb6
--- /dev/null
+++ b/mediagoblin/i18n/fa/LC_MESSAGES/mediagoblin.po
@@ -0,0 +1,691 @@
+# Translations template for PROJECT.
+# Copyright (C) 2012 ORGANIZATION
+# This file is distributed under the same license as the PROJECT project.
+#
+# Translators:
+# <amir007ag@gmail.com>, 2012.
+msgid ""
+msgstr ""
+"Project-Id-Version: GNU MediaGoblin\n"
+"Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n"
+"POT-Creation-Date: 2012-06-01 16:32-0500\n"
+"PO-Revision-Date: 2012-06-01 21:30+0000\n"
+"Last-Translator: cwebber <cwebber@dustycloud.org>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 0.9.6\n"
+"Language: fa\n"
+"Plural-Forms: nplurals=1; plural=0\n"
+
+#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41
+msgid "Username"
+msgstr "نام کاربری"
+
+#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45
+msgid "Password"
+msgstr "گذرواٰژه"
+
+#: mediagoblin/auth/forms.py:34
+msgid "Email address"
+msgstr "آدرس ایمیل"
+
+#: mediagoblin/auth/forms.py:51
+msgid "Username or email"
+msgstr ""
+
+#: mediagoblin/auth/forms.py:58
+msgid "Incorrect input"
+msgstr ""
+
+#: mediagoblin/auth/views.py:55
+msgid "Sorry, registration is disabled on this instance."
+msgstr "Ù…ØªØ§Ø³ÙØ§Ù†Ù‡ØŒØ«Ø¨ØªÙ†Ø§Ù… به طور موقت غیر ÙØ¹Ø§Ù„ است."
+
+#: mediagoblin/auth/views.py:75
+msgid "Sorry, a user with that name already exists."
+msgstr "Ù…ØªØ§Ø³ÙØ§Ù†Ù‡ کاربری با این نام کاربری وجود دارد."
+
+#: mediagoblin/auth/views.py:79
+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 "این کد تاییدیه یا شناسه کاربری صحیح نیست."
+
+#: 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:263
+msgid ""
+"An email has been sent with instructions on how to change your password."
+msgstr ""
+
+#: mediagoblin/auth/views.py:273
+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:285
+msgid "Couldn't find someone with that username or email."
+msgstr ""
+
+#: mediagoblin/auth/views.py:333
+msgid "You can now log in using your new password."
+msgstr ""
+
+#: mediagoblin/edit/forms.py:25 mediagoblin/submit/forms.py:28
+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/submit/forms.py:32
+msgid ""
+"You can use\n"
+" <a href=\"http://daringfireball.net/projects/markdown/basics\">\n"
+" Markdown</a> for formatting."
+msgstr ""
+
+#: 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
+msgid "Slug"
+msgstr ""
+
+#: mediagoblin/edit/forms.py:39
+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 "Old password"
+msgstr ""
+
+#: mediagoblin/edit/forms.py:65
+msgid "Enter your old password to prove you own this account."
+msgstr ""
+
+#: mediagoblin/edit/forms.py:68
+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:88
+msgid "You are editing another user's media. Proceed with caution."
+msgstr "شما در حال ویرایش رسانه کاربر دیگری هستید.با احتیاط عمل کنید"
+
+#: mediagoblin/edit/views.py:158
+msgid "You are editing a user's profile. Proceed with caution."
+msgstr "شما در حال ویرایش نمایه کاربر دیگری هستید.با احتیاط عمل کنید."
+
+#: mediagoblin/edit/views.py:174
+msgid "Profile changes saved"
+msgstr ""
+
+#: mediagoblin/edit/views.py:200
+msgid "Wrong password"
+msgstr ""
+
+#: mediagoblin/edit/views.py:216
+msgid "Account settings saved"
+msgstr ""
+
+#: mediagoblin/media_types/__init__.py:60
+#: mediagoblin/media_types/__init__.py:120
+msgid "Sorry, I don't support that file type :("
+msgstr ""
+
+#: mediagoblin/processing/__init__.py:127
+msgid "Invalid file given for media type."
+msgstr "ÙØ§ÛŒÙ„ÛŒ نا معتبر برای نوع رسانه داده شده."
+
+#: mediagoblin/submit/forms.py:26
+msgid "File"
+msgstr "ÙØ§ÛŒÙ„"
+
+#: mediagoblin/submit/views.py:56
+msgid "You must provide a file."
+msgstr "شما باید ÙØ§ÛŒÙ„ÛŒ ارايه بدهید."
+
+#: mediagoblin/submit/views.py:163
+msgid "Woohoo! Submitted!"
+msgstr "هورا!ثبت شد!"
+
+#: mediagoblin/templates/mediagoblin/404.html:22
+msgid "Image of 404 goblin stressing out"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/404.html:23
+msgid "Oops!"
+msgstr "اوه"
+
+#: mediagoblin/templates/mediagoblin/404.html:24
+msgid "There doesn't seem to be a page at this address. Sorry!"
+msgstr "Ù…ØªØ§Ø³ÙØ§Ù†Ù‡ به نظر نمی رسد Ú©Ù‡ چنین ØµÙØ­Ù‡ ای در این آدرس وجود داشته باشد!"
+
+#: mediagoblin/templates/mediagoblin/404.html:26
+msgid ""
+"If you're sure the address is correct, maybe the page you're looking for has"
+" been moved or deleted."
+msgstr "اگر مطمين هستین Ú©Ù‡ آدرس درست است،ممکن است ØµÙØ­Ù‡ ای Ú©Ù‡ شما آنرا جستجو Ù…ÛŒ کنید انتقال داده شده Ùˆ یا حذ٠شده باشد."
+
+#: mediagoblin/templates/mediagoblin/base.html:47
+msgid "MediaGoblin logo"
+msgstr "لوگو مدیاگوبلین"
+
+#: mediagoblin/templates/mediagoblin/base.html:57
+msgid "Verify your email!"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:63
+msgid "+ Add media"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:65
+msgid "View your profile"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:66
+msgid "Log out"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:71
+#: mediagoblin/templates/mediagoblin/auth/login.html:32
+#: mediagoblin/templates/mediagoblin/auth/login.html:50
+msgid "Log in"
+msgstr "ورود"
+
+#: mediagoblin/templates/mediagoblin/base.html:85
+msgid ""
+"Powered by <a href=\"http://mediagoblin.org\">MediaGoblin</a>, a <a "
+"href=\"http://gnu.org/\">GNU</a> project."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:88
+#, python-format
+msgid ""
+"Released under the <a "
+"href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a "
+"href=\"%(source_link)s\">Source code</a> available."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/root.html:24
+msgid "Explore"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/root.html:26
+msgid "Hi there, welcome to this MediaGoblin site!"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/root.html:28
+msgid ""
+"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, an "
+"extraordinarily great piece of media hosting software."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/root.html:29
+msgid ""
+"To add your own media, place comments, save your favourites and more, you "
+"can log in with your MediaGoblin account."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/root.html:31
+msgid "Don't have one yet? It's easy!"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/root.html:32
+#, python-format
+msgid ""
+"<a class=\"button_action_highlight\" href=\"%(register_url)s\">Create an account at this site</a>\n"
+" or\n"
+" <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">Set up MediaGoblin on your own server</a>"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/root.html:40
+msgid "Most recent media"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/auth/change_fp.html:32
+msgid "Set your new password"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/auth/change_fp.html:35
+msgid "Set password"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27
+msgid "Recover password"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:30
+msgid "Send instructions"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/auth/fp_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:35
+msgid "Logging in failed!"
+msgstr "ورود با خطا انجام شد!"
+
+#: mediagoblin/templates/mediagoblin/auth/login.html:40
+msgid "Don't have an account yet?"
+msgstr "آیا حساب کاربری ندارید؟"
+
+#: mediagoblin/templates/mediagoblin/auth/login.html:41
+msgid "Create one here!"
+msgstr "در اینجا یکی بسازید!"
+
+#: mediagoblin/templates/mediagoblin/auth/login.html:47
+msgid "Forgot your password?"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/auth/register.html:32
+msgid "Create an account!"
+msgstr "ساخت یک حساب کاربری!"
+
+#: mediagoblin/templates/mediagoblin/auth/register.html:36
+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برای ÙØ¹Ø§Ù„ سازی شناسه کاربری گنو مدیاگوبلین خود ،پیوند زیر را در مرورگر خود باز کنید.\n\n%(verification_url)s"
+
+#: mediagoblin/templates/mediagoblin/edit/edit.html:29
+#, python-format
+msgid "Editing %(media_title)s"
+msgstr "ویرایش %(media_title)s"
+
+#: mediagoblin/templates/mediagoblin/edit/edit.html:36
+#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49
+msgid "Cancel"
+msgstr "انصراÙ"
+
+#: mediagoblin/templates/mediagoblin/edit/edit.html:37
+#: mediagoblin/templates/mediagoblin/edit/edit_account.html:40
+#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:35
+msgid "Save changes"
+msgstr "ذخیره تغییرات"
+
+#: mediagoblin/templates/mediagoblin/edit/edit_account.html:34
+#, python-format
+msgid "Changing %(username)s's account settings"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29
+#, python-format
+msgid "Editing %(username)s's profile"
+msgstr "در حال ویرایش نمایه %(username)s"
+
+#: 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/video.html:53
+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 ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:47
+msgid ""
+"You can get a modern web browser that \n"
+"\tcan play the audio at <a href=\"http://getfirefox.com\">\n"
+"\t http://getfirefox.com</a>!"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:56
+msgid "Download"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:60
+msgid "original file"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:63
+msgid "WebM file (Vorbis codec)"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:40
+msgid ""
+"Sorry, this video will not work because \n"
+"\t your web browser does not support HTML5 \n"
+"\t video."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:43
+msgid ""
+"You can get a modern web browser that \n"
+"\t can play this video at <a href=\"http://getfirefox.com\">\n"
+"\t http://getfirefox.com</a>!"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/submit/start.html:26
+msgid "Add your media"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/submit/start.html:30
+msgid "Add"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30
+#, python-format
+msgid "%(username)s's media"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:37
+#, python-format
+msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media"
+msgstr "<a href=\"%(user_url)s\">%(username)s</a>'s رسانه های"
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:46
+#, python-format
+msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:67
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:73
+#, python-format
+msgid "Image for %(media_title)s"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:87
+msgid "Edit"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
+msgid "Delete"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:124
+msgid "Add a comment"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:131
+msgid ""
+"You can use <a "
+"href=\"http://daringfireball.net/projects/markdown/basics\">Markdown</a> for"
+" formatting."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:135
+msgid "Add this comment"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:154
+msgid "at"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:174
+#, python-format
+msgid ""
+"<h3>Added on</h3>\n"
+" <p>%(date)s</p>"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30
+#, python-format
+msgid "Really delete %(title)s?"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:50
+msgid "Delete permanently"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:22
+msgid "Media processing panel"
+msgstr "پنل رسیدگی به رسانه ها"
+
+#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:25
+msgid ""
+"You can track the state of media being processed for your gallery here."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:28
+msgid "Media in-processing"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:46
+msgid "No media in-processing"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:50
+msgid "These uploads failed to process:"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html: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 <a "
+"href=\"%(login_url)s\">log in</a> and resend it."
+msgstr "اگر شما آن کاربر هستید Ùˆ ایمیل تایید خود را Ú¯Ù… کرده اید،, Ù…ÛŒ توانید <a href=\"%(login_url)s\">log in</a> Ùˆ دوباره آنرا Ø¨ÙØ±Ø³ØªÛŒØ¯.."
+
+#: 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:101
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:118
+msgid "Edit profile"
+msgstr "ویرایش نمایه"
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:106
+msgid "This user hasn't filled in their profile (yet)."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:125
+msgid "Change account settings"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:138
+#, python-format
+msgid "View all of %(username)s's media"
+msgstr "نمایش تمامی رسانه های %(username)s"
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:151
+msgid ""
+"This is where your media will appear, but you don't seem to have added "
+"anything yet."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
+msgid "Add media"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:163
+#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72
+msgid "There doesn't seem to be any media here yet..."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/utils/feed_link.html:21
+msgid "feed icon"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/utils/feed_link.html:23
+msgid "Atom feed"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:25
+msgid "Location"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:38
+#, python-format
+msgid "View on <a href=\"%(osm_url)s\">OpenStreetMap</a>"
+msgstr ""
+
+#: 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:75
+msgid "Could not read the image file."
+msgstr ""
+
+#: mediagoblin/user_pages/forms.py:30
+msgid "I am sure I want to delete this"
+msgstr ""
+
+#: mediagoblin/user_pages/views.py:153
+msgid "Oops, your comment was empty."
+msgstr ""
+
+#: mediagoblin/user_pages/views.py:159
+msgid "Your comment has been posted!"
+msgstr ""
+
+#: mediagoblin/user_pages/views.py:185
+msgid "You deleted the media."
+msgstr ""
+
+#: mediagoblin/user_pages/views.py:192
+msgid "The media was not deleted because you didn't check that you were sure."
+msgstr ""
+
+#: mediagoblin/user_pages/views.py:200
+msgid "You are about to delete another user's media. Proceed with caution."
+msgstr ""
diff --git a/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.mo
index c29f7f08..bb86192a 100644
--- a/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.mo
+++ b/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.mo
Binary files differ
diff --git a/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.po
index 3bffeef8..91809571 100644
--- a/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.po
+++ b/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.po
@@ -13,11 +13,11 @@
msgid ""
msgstr ""
"Project-Id-Version: GNU MediaGoblin\n"
-"Report-Msgid-Bugs-To: http://bugs.foocorp.net/projects/mediagoblin/issues\n"
-"POT-Creation-Date: 2012-01-29 13:31-0600\n"
-"PO-Revision-Date: 2012-01-29 19:29+0000\n"
+"Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n"
+"POT-Creation-Date: 2012-06-01 16:32-0500\n"
+"PO-Revision-Date: 2012-06-01 21:30+0000\n"
"Last-Translator: cwebber <cwebber@dustycloud.org>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language-Team: French (http://www.transifex.net/projects/p/mediagoblin/language/fr/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -25,10 +25,6 @@ msgstr ""
"Language: fr\n"
"Plural-Forms: nplurals=2; plural=(n > 1)\n"
-#: mediagoblin/processing.py:143
-msgid "Invalid file given for media type."
-msgstr "Le fichier envoyé ne correspond pas au type de média."
-
#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41
msgid "Username"
msgstr "Nom d'utilisateur"
@@ -41,61 +37,64 @@ msgstr "Mot de passe"
msgid "Email address"
msgstr "Adresse e-mail"
+#: mediagoblin/auth/forms.py:51
+msgid "Username or email"
+msgstr ""
+
+#: mediagoblin/auth/forms.py:58
+msgid "Incorrect input"
+msgstr ""
+
#: mediagoblin/auth/views.py:55
msgid "Sorry, registration is disabled on this instance."
msgstr "L'inscription n'est pas activée sur ce serveur, désolé."
-#: mediagoblin/auth/views.py:73
+#: mediagoblin/auth/views.py:75
msgid "Sorry, a user with that name already exists."
msgstr "Un utilisateur existe déjà avec ce nom, désolé."
-#: mediagoblin/auth/views.py:77
+#: mediagoblin/auth/views.py:79
msgid "Sorry, a user with that email address already exists."
msgstr "Désolé, il existe déjà un utilisateur ayant cette adresse e-mail."
-#: mediagoblin/auth/views.py:180
+#: mediagoblin/auth/views.py:182
msgid ""
"Your email address has been verified. You may now login, edit your profile, "
"and submit images!"
-msgstr ""
-"Votre adresse e-mail a bien été vérifiée. Vous pouvez maintenant vous "
-"identifier, modifier votre profil, et soumettre des images !"
+msgstr "Votre adresse e-mail a bien été vérifiée. Vous pouvez maintenant vous identifier, modifier votre profil, et soumettre des images !"
-#: mediagoblin/auth/views.py:186
+#: mediagoblin/auth/views.py:188
msgid "The verification key or user id is incorrect"
msgstr "La clé de vérification ou le nom d'utilisateur est incorrect."
-#: mediagoblin/auth/views.py:204
+#: mediagoblin/auth/views.py:206
msgid "You must be logged in so we know who to send the email to!"
-msgstr ""
-"Vous devez être authentifié afin que nous sachions à qui envoyer l'e-mail !"
+msgstr "Vous devez être authentifié afin que nous sachions à qui envoyer l'e-mail !"
-#: mediagoblin/auth/views.py:212
+#: mediagoblin/auth/views.py:214
msgid "You've already verified your email address!"
msgstr "Votre adresse e-mail a déjà été vérifiée !"
-#: mediagoblin/auth/views.py:225
+#: mediagoblin/auth/views.py:227
msgid "Resent your verification email."
msgstr "E-mail de vérification renvoyé."
-#: mediagoblin/auth/views.py:260
+#: mediagoblin/auth/views.py:263
msgid ""
"An email has been sent with instructions on how to change your password."
msgstr ""
-#: mediagoblin/auth/views.py:270
+#: mediagoblin/auth/views.py:273
msgid ""
"Could not send password recovery email as your username is inactive or your "
"account's email address has not been verified."
-msgstr ""
-"Impossible d'envoyer un email de récupération de mot de passe : votre compte"
-" est inactif ou bien l'email de votre compte n'a pas été vérifiée."
+msgstr "Impossible d'envoyer un email de récupération de mot de passe : votre compte est inactif ou bien l'email de votre compte n'a pas été vérifiée."
-#: mediagoblin/auth/views.py:282
+#: mediagoblin/auth/views.py:285
msgid "Couldn't find someone with that username or email."
msgstr ""
-#: mediagoblin/auth/views.py:330
+#: mediagoblin/auth/views.py:333
msgid "You can now log in using your new password."
msgstr ""
@@ -138,6 +137,7 @@ msgid ""
msgstr ""
#: mediagoblin/edit/forms.py:44 mediagoblin/submit/forms.py:41
+#: mediagoblin/templates/mediagoblin/utils/license.html:20
msgid "License"
msgstr ""
@@ -149,6 +149,10 @@ msgstr "Bio"
msgid "Website"
msgstr "Site web"
+#: mediagoblin/edit/forms.py:58
+msgid "This address contains errors"
+msgstr ""
+
#: mediagoblin/edit/forms.py:63
msgid "Old password"
msgstr "Ancien mot de passe."
@@ -161,51 +165,48 @@ msgstr ""
msgid "New password"
msgstr ""
-#: mediagoblin/edit/views.py:68
+#: mediagoblin/edit/views.py:67
msgid "An entry with that slug already exists for this user."
msgstr "Une entrée existe déjà pour cet utilisateur avec la même légende."
-#: mediagoblin/edit/views.py:92
+#: mediagoblin/edit/views.py:88
msgid "You are editing another user's media. Proceed with caution."
-msgstr ""
-"Vous vous apprêtez à modifier le média d'un autre utilisateur. Veuillez "
-"prendre garde."
+msgstr "Vous vous apprêtez à modifier le média d'un autre utilisateur. Veuillez prendre garde."
-#: mediagoblin/edit/views.py:162
+#: mediagoblin/edit/views.py:158
msgid "You are editing a user's profile. Proceed with caution."
-msgstr ""
-"Vous vous apprêtez à modifier le profil d'un utilisateur. Veuillez prendre "
-"garde."
+msgstr "Vous vous apprêtez à modifier le profil d'un utilisateur. Veuillez prendre garde."
-#: mediagoblin/edit/views.py:180
+#: mediagoblin/edit/views.py:174
msgid "Profile changes saved"
msgstr ""
-#: mediagoblin/edit/views.py:206
+#: mediagoblin/edit/views.py:200
msgid "Wrong password"
msgstr "Mauvais mot de passe"
-#: mediagoblin/edit/views.py:222
+#: mediagoblin/edit/views.py:216
msgid "Account settings saved"
msgstr ""
-#: mediagoblin/media_types/__init__.py:77
-msgid "Could not extract any file extension from \"{filename}\""
-msgstr ""
-
-#: mediagoblin/media_types/__init__.py:88
+#: mediagoblin/media_types/__init__.py:60
+#: mediagoblin/media_types/__init__.py:120
msgid "Sorry, I don't support that file type :("
msgstr ""
+#: mediagoblin/processing/__init__.py:127
+msgid "Invalid file given for media type."
+msgstr "Le fichier envoyé ne correspond pas au type de média."
+
#: mediagoblin/submit/forms.py:26
msgid "File"
msgstr "Fichier"
-#: mediagoblin/submit/views.py:54
+#: mediagoblin/submit/views.py:56
msgid "You must provide a file."
msgstr "Il vous faut fournir un fichier."
-#: mediagoblin/submit/views.py:158
+#: mediagoblin/submit/views.py:163
msgid "Woohoo! Submitted!"
msgstr "Youhou, c'est envoyé !"
@@ -225,40 +226,47 @@ msgstr "Il ne semble pas y avoir de page à cette adresse. Désolé !"
msgid ""
"If you're sure the address is correct, maybe the page you're looking for has"
" been moved or deleted."
-msgstr ""
-"Si vous êtes sûr que l'adresse est correcte, peut-être la page que vous "
-"recherchez a été déplacée ou supprimée."
+msgstr "Si vous êtes sûr que l'adresse est correcte, peut-être la page que vous recherchez a été déplacée ou supprimée."
-#: mediagoblin/templates/mediagoblin/base.html:46
+#: mediagoblin/templates/mediagoblin/base.html:47
msgid "MediaGoblin logo"
msgstr "Logo MediaGoblin"
-#: mediagoblin/templates/mediagoblin/base.html:51
-#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
-msgid "Add media"
-msgstr "Ajouter des médias"
-
-#: mediagoblin/templates/mediagoblin/base.html:62
+#: mediagoblin/templates/mediagoblin/base.html:57
msgid "Verify your email!"
msgstr "Vérifiez votre adresse e-mail !"
-#: mediagoblin/templates/mediagoblin/base.html:69
-msgid "log out"
-msgstr "déconnexion"
+#: mediagoblin/templates/mediagoblin/base.html:63
+msgid "+ Add media"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:65
+msgid "View your profile"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:66
+msgid "Log out"
+msgstr ""
-#: mediagoblin/templates/mediagoblin/base.html:72
-#: mediagoblin/templates/mediagoblin/auth/login.html:27
-#: mediagoblin/templates/mediagoblin/auth/login.html:45
+#: mediagoblin/templates/mediagoblin/base.html:71
+#: mediagoblin/templates/mediagoblin/auth/login.html:32
+#: mediagoblin/templates/mediagoblin/auth/login.html:50
msgid "Log in"
msgstr "S'identifier"
-#: mediagoblin/templates/mediagoblin/base.html:84
+#: mediagoblin/templates/mediagoblin/base.html:85
msgid ""
"Powered by <a href=\"http://mediagoblin.org\">MediaGoblin</a>, a <a "
-"href=\"http://gnu.org/\">GNU</a> project"
+"href=\"http://gnu.org/\">GNU</a> project."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:88
+#, python-format
+msgid ""
+"Released under the <a "
+"href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a "
+"href=\"%(source_link)s\">Source code</a> available."
msgstr ""
-"Propulsé par <a href=\"http://mediagoblin.org\">MediaGoblin</a> , un projet "
-"<a href=\"http://gnu.org/\">GNU</a>"
#: mediagoblin/templates/mediagoblin/root.html:24
msgid "Explore"
@@ -272,17 +280,13 @@ msgstr "Bonjour, et bienvenu sur ce site MediaGoblin !"
msgid ""
"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, an "
"extraordinarily great piece of media hosting software."
-msgstr ""
-"Ce site fait tourner <a href=\"http://mediagoblin.org\">MediaGoblin</a>, un "
-"logiciel d'hébergement de média extraordinairement génial."
+msgstr "Ce site fait tourner <a href=\"http://mediagoblin.org\">MediaGoblin</a>, un logiciel d'hébergement de média extraordinairement génial."
#: mediagoblin/templates/mediagoblin/root.html:29
msgid ""
"To add your own media, place comments, save your favourites and more, you "
"can log in with your MediaGoblin account."
-msgstr ""
-"Ajoutez vos propres medias, commentez ceux des autres, sauvegardez vos "
-"préférés et plus encore ! Faites tout cela depuis votre compte MediaGoblin."
+msgstr "Ajoutez vos propres medias, commentez ceux des autres, sauvegardez vos préférés et plus encore ! Faites tout cela depuis votre compte MediaGoblin."
#: mediagoblin/templates/mediagoblin/root.html:31
msgid "Don't have one yet? It's easy!"
@@ -328,30 +332,21 @@ msgid ""
"\n"
"If you think this is an error, just ignore this email and continue being\n"
"a happy goblin!"
-msgstr ""
-"Bonjour %(username)s,\n"
-"\n"
-"Pour changer votre mot de passe GNU MediaGoblin, ouvrez l'URL suivante dans \n"
-"votre navigateur internet :\n"
-"\n"
-"%(verification_url)s\n"
-"\n"
-"Si vous pensez qu'il s'agit d'une erreur, ignorez simplement cet email et restez\n"
-"un goblin heureux !"
+msgstr "Bonjour %(username)s,\n\nPour changer votre mot de passe GNU MediaGoblin, ouvrez l'URL suivante dans \nvotre navigateur internet :\n\n%(verification_url)s\n\nSi vous pensez qu'il s'agit d'une erreur, ignorez simplement cet email et restez\nun goblin heureux !"
-#: mediagoblin/templates/mediagoblin/auth/login.html:30
+#: mediagoblin/templates/mediagoblin/auth/login.html:35
msgid "Logging in failed!"
msgstr "La connexion a échoué!"
-#: mediagoblin/templates/mediagoblin/auth/login.html:35
+#: mediagoblin/templates/mediagoblin/auth/login.html:40
msgid "Don't have an account yet?"
msgstr "Pas encore de compte ?"
-#: mediagoblin/templates/mediagoblin/auth/login.html:36
+#: mediagoblin/templates/mediagoblin/auth/login.html:41
msgid "Create one here!"
msgstr "Créez-en un ici !"
-#: mediagoblin/templates/mediagoblin/auth/login.html:42
+#: mediagoblin/templates/mediagoblin/auth/login.html:47
msgid "Forgot your password?"
msgstr "Vous avez oublié votre mot de passe ?"
@@ -372,12 +367,7 @@ msgid ""
"your web browser:\n"
"\n"
"%(verification_url)s"
-msgstr ""
-"Bonjour %(username)s,\n"
-"\n"
-"pour activer votre compte sur GNU MediaGoblin, veuillez vous rendre à l'adresse suivante avec votre navigateur web:\n"
-"\n"
-"%(verification_url)s"
+msgstr "Bonjour %(username)s,\n\npour activer votre compte sur GNU MediaGoblin, veuillez vous rendre à l'adresse suivante avec votre navigateur web:\n\n%(verification_url)s"
#: mediagoblin/templates/mediagoblin/edit/edit.html:29
#, python-format
@@ -412,18 +402,44 @@ msgid "Media tagged with: %(tag_name)s"
msgstr "Médias taggés avec : %(tag_name)s "
#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:46
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:53
msgid "Original"
msgstr "Original"
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:33
+#: 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 <a href=\"http://getfirefox.com\">\n"
+"\t http://getfirefox.com</a>!"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:56
+msgid "Download"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:60
+msgid "original file"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:63
+msgid "WebM file (Vorbis codec)"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:40
msgid ""
"Sorry, this video will not work because \n"
"\t your web browser does not support HTML5 \n"
"\t video."
msgstr ""
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:36
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:43
msgid ""
"You can get a modern web browser that \n"
"\t can play this video at <a href=\"http://getfirefox.com\">\n"
@@ -448,55 +464,49 @@ msgstr "Medias de %(username)s"
msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media"
msgstr "Médias de <a href=\"%(user_url)s\">%(username)s</a>"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:72
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:46
+#, python-format
+msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:67
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:73
#, python-format
-msgid "Added on %(date)s."
+msgid "Image for %(media_title)s"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:81
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:87
msgid "Edit"
msgstr "Éditer"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:85
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
msgid "Delete"
msgstr "Effacer"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
-#, python-format
-msgid "%(comment_count)s comment"
-msgstr ""
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:93
-#, python-format
-msgid "%(comment_count)s comments"
-msgstr ""
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:95
-msgid "No comments yet."
-msgstr ""
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:103
-msgid "Add one"
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:124
+msgid "Add a comment"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:112
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:131
msgid ""
"You can use <a "
"href=\"http://daringfireball.net/projects/markdown/basics\">Markdown</a> for"
" formatting."
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:116
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:135
msgid "Add this comment"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:138
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:154
msgid "at"
msgstr "à"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:153
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:174
#, python-format
-msgid "<p>â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a></p>"
+msgid ""
+"<h3>Added on</h3>\n"
+" <p>%(date)s</p>"
msgstr ""
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30
@@ -505,8 +515,8 @@ msgid "Really delete %(title)s?"
msgstr "Voulez-vous vraiment supprimer %(title)s ?"
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:50
-msgid "Delete Permanently"
-msgstr "Supprimer définitivement"
+msgid "Delete permanently"
+msgstr ""
#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:22
msgid "Media processing panel"
@@ -515,9 +525,7 @@ msgstr "Panneau pour le traitement des médias"
#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:25
msgid ""
"You can track the state of media being processed for your gallery here."
-msgstr ""
-"Vous pouvez suivre l'état des médias en cours de traitement pour votre "
-"galerie ici."
+msgstr "Vous pouvez suivre l'état des médias en cours de traitement pour votre galerie ici."
#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:28
msgid "Media in-processing"
@@ -553,9 +561,7 @@ msgstr "Presque fini ! Votre compte a encore besoin d'être activé."
#: mediagoblin/templates/mediagoblin/user_pages/user.html:58
msgid ""
"An email should arrive in a few moments with instructions on how to do so."
-msgstr ""
-"Un e-mail devrait vous parvenir dans quelques instants ; il vous indiquera "
-"comment procéder."
+msgstr "Un e-mail devrait vous parvenir dans quelques instants ; il vous indiquera comment procéder."
#: mediagoblin/templates/mediagoblin/user_pages/user.html:62
msgid "In case it doesn't:"
@@ -569,19 +575,14 @@ msgstr "Renvoyer l'e-mail de vérification"
msgid ""
"Someone has registered an account with this username, but it still has to be"
" activated."
-msgstr ""
-"Quelqu'un a enregistré un compte avec ce nom, mais il doit encore être "
-"activé."
+msgstr "Quelqu'un a enregistré un compte avec ce nom, mais il doit encore être activé."
#: 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 <a "
"href=\"%(login_url)s\">log in</a> and resend it."
-msgstr ""
-"Si c'est de vous qu'il s'agit, mais que vous avez perdu l'e-mail de "
-"vérification, vous pouvez vous <a href=\"%(login_url)s\">identifier</a> et "
-"le renvoyer."
+msgstr "Si c'est de vous qu'il s'agit, mais que vous avez perdu l'e-mail de vérification, vous pouvez vous <a href=\"%(login_url)s\">identifier</a> et le renvoyer."
#: mediagoblin/templates/mediagoblin/user_pages/user.html:96
msgid "Here's a spot to tell others about yourself."
@@ -609,9 +610,11 @@ msgstr "Voir tous les médias de %(username)s"
msgid ""
"This is where your media will appear, but you don't seem to have added "
"anything yet."
-msgstr ""
-"C'est là où vos médias apparaîssent, mais vous ne semblez pas avoir encore "
-"ajouté quoi que ce soit."
+msgstr "C'est là où vos médias apparaîssent, mais vous ne semblez pas avoir encore ajouté quoi que ce soit."
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
+msgid "Add media"
+msgstr "Ajouter des médias"
#: mediagoblin/templates/mediagoblin/user_pages/user.html:163
#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72
@@ -626,8 +629,13 @@ msgstr "icone de flux"
msgid "Atom feed"
msgstr "flux Atom"
-#: mediagoblin/templates/mediagoblin/utils/license.html:21
-msgid "License:"
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:25
+msgid "Location"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:38
+#, python-format
+msgid "View on <a href=\"%(osm_url)s\">OpenStreetMap</a>"
msgstr ""
#: mediagoblin/templates/mediagoblin/utils/license.html:25
@@ -646,25 +654,21 @@ msgstr ""
msgid "Go to page:"
msgstr "Aller à la page :"
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:27
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:32
+#: 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:38
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:43
+#: 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 "View more media tagged with"
+msgid "Tagged with"
msgstr ""
-#: mediagoblin/templates/mediagoblin/utils/tags.html:25
-msgid "or"
-msgstr ""
-
-#: mediagoblin/tools/exif.py:68
+#: mediagoblin/tools/exif.py:75
msgid "Could not read the image file."
msgstr ""
@@ -672,28 +676,22 @@ msgstr ""
msgid "I am sure I want to delete this"
msgstr "Je suis sûr de vouloir supprimer cela"
-#: mediagoblin/user_pages/views.py:155
+#: mediagoblin/user_pages/views.py:153
msgid "Oops, your comment was empty."
msgstr "Oups, votre commentaire était vide."
-#: mediagoblin/user_pages/views.py:161
+#: mediagoblin/user_pages/views.py:159
msgid "Your comment has been posted!"
msgstr "Votre commentaire a été posté !"
-#: mediagoblin/user_pages/views.py:183
+#: mediagoblin/user_pages/views.py:185
msgid "You deleted the media."
msgstr "Vous avez supprimé le media."
-#: mediagoblin/user_pages/views.py:190
+#: mediagoblin/user_pages/views.py:192
msgid "The media was not deleted because you didn't check that you were sure."
-msgstr ""
-"Ce media n'a pas été supprimé car vous n'avez pas confirmer que vous étiez "
-"sur."
+msgstr "Ce media n'a pas été supprimé car vous n'avez pas confirmer que vous étiez sur."
-#: mediagoblin/user_pages/views.py:198
+#: mediagoblin/user_pages/views.py:200
msgid "You are about to delete another user's media. Proceed with caution."
-msgstr ""
-"Vous êtes sur le point de supprimer des médias d'un autre utilisateur. "
-"Procédez avec prudence."
-
-
+msgstr "Vous êtes sur le point de supprimer des médias d'un autre utilisateur. Procédez avec prudence."
diff --git a/mediagoblin/i18n/ia/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/ia/LC_MESSAGES/mediagoblin.mo
index 5bf0f220..4515c7d9 100644
--- a/mediagoblin/i18n/ia/LC_MESSAGES/mediagoblin.mo
+++ b/mediagoblin/i18n/ia/LC_MESSAGES/mediagoblin.mo
Binary files differ
diff --git a/mediagoblin/i18n/ia/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/ia/LC_MESSAGES/mediagoblin.po
index 017cd64d..a80d6ac1 100644
--- a/mediagoblin/i18n/ia/LC_MESSAGES/mediagoblin.po
+++ b/mediagoblin/i18n/ia/LC_MESSAGES/mediagoblin.po
@@ -7,9 +7,9 @@
msgid ""
msgstr ""
"Project-Id-Version: GNU MediaGoblin\n"
-"Report-Msgid-Bugs-To: http://bugs.foocorp.net/projects/mediagoblin/issues\n"
-"POT-Creation-Date: 2012-01-29 13:31-0600\n"
-"PO-Revision-Date: 2012-01-29 19:29+0000\n"
+"Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n"
+"POT-Creation-Date: 2012-06-01 16:32-0500\n"
+"PO-Revision-Date: 2012-06-01 21:30+0000\n"
"Last-Translator: cwebber <cwebber@dustycloud.org>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
@@ -19,10 +19,6 @@ msgstr ""
"Language: ia\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
-#: mediagoblin/processing.py:143
-msgid "Invalid file given for media type."
-msgstr ""
-
#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41
msgid "Username"
msgstr "Nomine de usator"
@@ -35,56 +31,64 @@ msgstr "Contrasigno"
msgid "Email address"
msgstr "Adresse de e-posta"
+#: mediagoblin/auth/forms.py:51
+msgid "Username or email"
+msgstr ""
+
+#: mediagoblin/auth/forms.py:58
+msgid "Incorrect input"
+msgstr ""
+
#: mediagoblin/auth/views.py:55
msgid "Sorry, registration is disabled on this instance."
msgstr ""
-#: mediagoblin/auth/views.py:73
+#: mediagoblin/auth/views.py:75
msgid "Sorry, a user with that name already exists."
msgstr ""
-#: mediagoblin/auth/views.py:77
+#: mediagoblin/auth/views.py:79
msgid "Sorry, a user with that email address already exists."
msgstr ""
-#: mediagoblin/auth/views.py:180
+#: 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:186
+#: mediagoblin/auth/views.py:188
msgid "The verification key or user id is incorrect"
msgstr ""
-#: mediagoblin/auth/views.py:204
+#: 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:212
+#: mediagoblin/auth/views.py:214
msgid "You've already verified your email address!"
msgstr ""
-#: mediagoblin/auth/views.py:225
+#: mediagoblin/auth/views.py:227
msgid "Resent your verification email."
msgstr ""
-#: mediagoblin/auth/views.py:260
+#: mediagoblin/auth/views.py:263
msgid ""
"An email has been sent with instructions on how to change your password."
msgstr ""
-#: mediagoblin/auth/views.py:270
+#: mediagoblin/auth/views.py:273
msgid ""
"Could not send password recovery email as your username is inactive or your "
"account's email address has not been verified."
msgstr ""
-#: mediagoblin/auth/views.py:282
+#: mediagoblin/auth/views.py:285
msgid "Couldn't find someone with that username or email."
msgstr ""
-#: mediagoblin/auth/views.py:330
+#: mediagoblin/auth/views.py:333
msgid "You can now log in using your new password."
msgstr ""
@@ -127,6 +131,7 @@ msgid ""
msgstr ""
#: mediagoblin/edit/forms.py:44 mediagoblin/submit/forms.py:41
+#: mediagoblin/templates/mediagoblin/utils/license.html:20
msgid "License"
msgstr ""
@@ -138,6 +143,10 @@ msgstr ""
msgid "Website"
msgstr "Sito web"
+#: mediagoblin/edit/forms.py:58
+msgid "This address contains errors"
+msgstr ""
+
#: mediagoblin/edit/forms.py:63
msgid "Old password"
msgstr ""
@@ -150,47 +159,48 @@ msgstr ""
msgid "New password"
msgstr ""
-#: mediagoblin/edit/views.py:68
+#: mediagoblin/edit/views.py:67
msgid "An entry with that slug already exists for this user."
msgstr ""
-#: mediagoblin/edit/views.py:92
+#: mediagoblin/edit/views.py:88
msgid "You are editing another user's media. Proceed with caution."
msgstr ""
-#: mediagoblin/edit/views.py:162
+#: mediagoblin/edit/views.py:158
msgid "You are editing a user's profile. Proceed with caution."
msgstr ""
-#: mediagoblin/edit/views.py:180
+#: mediagoblin/edit/views.py:174
msgid "Profile changes saved"
msgstr ""
-#: mediagoblin/edit/views.py:206
+#: mediagoblin/edit/views.py:200
msgid "Wrong password"
msgstr ""
-#: mediagoblin/edit/views.py:222
+#: mediagoblin/edit/views.py:216
msgid "Account settings saved"
msgstr ""
-#: mediagoblin/media_types/__init__.py:77
-msgid "Could not extract any file extension from \"{filename}\""
+#: mediagoblin/media_types/__init__.py:60
+#: mediagoblin/media_types/__init__.py:120
+msgid "Sorry, I don't support that file type :("
msgstr ""
-#: mediagoblin/media_types/__init__.py:88
-msgid "Sorry, I don't support that file type :("
+#: mediagoblin/processing/__init__.py:127
+msgid "Invalid file given for media type."
msgstr ""
#: mediagoblin/submit/forms.py:26
msgid "File"
msgstr ""
-#: mediagoblin/submit/views.py:54
+#: mediagoblin/submit/views.py:56
msgid "You must provide a file."
msgstr ""
-#: mediagoblin/submit/views.py:158
+#: mediagoblin/submit/views.py:163
msgid "Woohoo! Submitted!"
msgstr ""
@@ -212,33 +222,44 @@ msgid ""
" been moved or deleted."
msgstr ""
-#: mediagoblin/templates/mediagoblin/base.html:46
+#: mediagoblin/templates/mediagoblin/base.html:47
msgid "MediaGoblin logo"
msgstr ""
-#: mediagoblin/templates/mediagoblin/base.html:51
-#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
-msgid "Add media"
+#: mediagoblin/templates/mediagoblin/base.html:57
+msgid "Verify your email!"
msgstr ""
-#: mediagoblin/templates/mediagoblin/base.html:62
-msgid "Verify your email!"
+#: mediagoblin/templates/mediagoblin/base.html:63
+msgid "+ Add media"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:65
+msgid "View your profile"
msgstr ""
-#: mediagoblin/templates/mediagoblin/base.html:69
-msgid "log out"
+#: mediagoblin/templates/mediagoblin/base.html:66
+msgid "Log out"
msgstr ""
-#: mediagoblin/templates/mediagoblin/base.html:72
-#: mediagoblin/templates/mediagoblin/auth/login.html:27
-#: mediagoblin/templates/mediagoblin/auth/login.html:45
+#: mediagoblin/templates/mediagoblin/base.html:71
+#: mediagoblin/templates/mediagoblin/auth/login.html:32
+#: mediagoblin/templates/mediagoblin/auth/login.html:50
msgid "Log in"
msgstr "Initiar session"
-#: mediagoblin/templates/mediagoblin/base.html:84
+#: mediagoblin/templates/mediagoblin/base.html:85
msgid ""
"Powered by <a href=\"http://mediagoblin.org\">MediaGoblin</a>, a <a "
-"href=\"http://gnu.org/\">GNU</a> project"
+"href=\"http://gnu.org/\">GNU</a> project."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:88
+#, python-format
+msgid ""
+"Released under the <a "
+"href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a "
+"href=\"%(source_link)s\">Source code</a> available."
msgstr ""
#: mediagoblin/templates/mediagoblin/root.html:24
@@ -307,19 +328,19 @@ msgid ""
"a happy goblin!"
msgstr ""
-#: mediagoblin/templates/mediagoblin/auth/login.html:30
+#: mediagoblin/templates/mediagoblin/auth/login.html:35
msgid "Logging in failed!"
msgstr ""
-#: mediagoblin/templates/mediagoblin/auth/login.html:35
+#: mediagoblin/templates/mediagoblin/auth/login.html:40
msgid "Don't have an account yet?"
msgstr ""
-#: mediagoblin/templates/mediagoblin/auth/login.html:36
+#: mediagoblin/templates/mediagoblin/auth/login.html:41
msgid "Create one here!"
msgstr ""
-#: mediagoblin/templates/mediagoblin/auth/login.html:42
+#: mediagoblin/templates/mediagoblin/auth/login.html:47
msgid "Forgot your password?"
msgstr ""
@@ -375,18 +396,44 @@ msgid "Media tagged with: %(tag_name)s"
msgstr ""
#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:46
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:53
msgid "Original"
msgstr ""
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:33
+#: 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 <a href=\"http://getfirefox.com\">\n"
+"\t http://getfirefox.com</a>!"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:56
+msgid "Download"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:60
+msgid "original file"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:63
+msgid "WebM file (Vorbis codec)"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:40
msgid ""
"Sorry, this video will not work because \n"
"\t your web browser does not support HTML5 \n"
"\t video."
msgstr ""
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:36
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:43
msgid ""
"You can get a modern web browser that \n"
"\t can play this video at <a href=\"http://getfirefox.com\">\n"
@@ -411,55 +458,49 @@ msgstr ""
msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:72
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:46
#, python-format
-msgid "Added on %(date)s."
+msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:81
-msgid "Edit"
-msgstr ""
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:85
-msgid "Delete"
-msgstr ""
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:67
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:73
#, python-format
-msgid "%(comment_count)s comment"
+msgid "Image for %(media_title)s"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:93
-#, python-format
-msgid "%(comment_count)s comments"
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:87
+msgid "Edit"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:95
-msgid "No comments yet."
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
+msgid "Delete"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:103
-msgid "Add one"
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:124
+msgid "Add a comment"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:112
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:131
msgid ""
"You can use <a "
"href=\"http://daringfireball.net/projects/markdown/basics\">Markdown</a> for"
" formatting."
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:116
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:135
msgid "Add this comment"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:138
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:154
msgid "at"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:153
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:174
#, python-format
-msgid "<p>â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a></p>"
+msgid ""
+"<h3>Added on</h3>\n"
+" <p>%(date)s</p>"
msgstr ""
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30
@@ -468,7 +509,7 @@ msgid "Really delete %(title)s?"
msgstr ""
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:50
-msgid "Delete Permanently"
+msgid "Delete permanently"
msgstr ""
#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:22
@@ -565,6 +606,10 @@ msgid ""
"anything yet."
msgstr ""
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
+msgid "Add media"
+msgstr ""
+
#: mediagoblin/templates/mediagoblin/user_pages/user.html:163
#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72
msgid "There doesn't seem to be any media here yet..."
@@ -578,8 +623,13 @@ msgstr ""
msgid "Atom feed"
msgstr ""
-#: mediagoblin/templates/mediagoblin/utils/license.html:21
-msgid "License:"
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:25
+msgid "Location"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:38
+#, python-format
+msgid "View on <a href=\"%(osm_url)s\">OpenStreetMap</a>"
msgstr ""
#: mediagoblin/templates/mediagoblin/utils/license.html:25
@@ -598,25 +648,21 @@ msgstr ""
msgid "Go to page:"
msgstr ""
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:27
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:32
+#: 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:38
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:43
+#: 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 "View more media tagged with"
+msgid "Tagged with"
msgstr ""
-#: mediagoblin/templates/mediagoblin/utils/tags.html:25
-msgid "or"
-msgstr ""
-
-#: mediagoblin/tools/exif.py:68
+#: mediagoblin/tools/exif.py:75
msgid "Could not read the image file."
msgstr ""
@@ -624,24 +670,22 @@ msgstr ""
msgid "I am sure I want to delete this"
msgstr ""
-#: mediagoblin/user_pages/views.py:155
+#: mediagoblin/user_pages/views.py:153
msgid "Oops, your comment was empty."
msgstr ""
-#: mediagoblin/user_pages/views.py:161
+#: mediagoblin/user_pages/views.py:159
msgid "Your comment has been posted!"
msgstr ""
-#: mediagoblin/user_pages/views.py:183
+#: mediagoblin/user_pages/views.py:185
msgid "You deleted the media."
msgstr ""
-#: mediagoblin/user_pages/views.py:190
+#: mediagoblin/user_pages/views.py:192
msgid "The media was not deleted because you didn't check that you were sure."
msgstr ""
-#: mediagoblin/user_pages/views.py:198
+#: mediagoblin/user_pages/views.py:200
msgid "You are about to delete another user's media. Proceed with caution."
msgstr ""
-
-
diff --git a/mediagoblin/i18n/it/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/it/LC_MESSAGES/mediagoblin.mo
index 9b94ec7f..2d19eb81 100644
--- a/mediagoblin/i18n/it/LC_MESSAGES/mediagoblin.mo
+++ b/mediagoblin/i18n/it/LC_MESSAGES/mediagoblin.mo
Binary files differ
diff --git a/mediagoblin/i18n/it/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/it/LC_MESSAGES/mediagoblin.po
index 2b896572..cdff3fd4 100644
--- a/mediagoblin/i18n/it/LC_MESSAGES/mediagoblin.po
+++ b/mediagoblin/i18n/it/LC_MESSAGES/mediagoblin.po
@@ -3,14 +3,15 @@
# This file is distributed under the same license as the PROJECT project.
#
# Translators:
+# Francesco Apruzzese <cescoap@gmail.com>, 2012.
# <pikappa469@alice.it>, 2011.
# <robi@nunnisoft.ch>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: GNU MediaGoblin\n"
-"Report-Msgid-Bugs-To: http://bugs.foocorp.net/projects/mediagoblin/issues\n"
-"POT-Creation-Date: 2012-01-29 13:31-0600\n"
-"PO-Revision-Date: 2012-01-29 19:29+0000\n"
+"Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n"
+"POT-Creation-Date: 2012-06-01 16:32-0500\n"
+"PO-Revision-Date: 2012-06-01 21:30+0000\n"
"Last-Translator: cwebber <cwebber@dustycloud.org>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
@@ -20,10 +21,6 @@ msgstr ""
"Language: it\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
-#: mediagoblin/processing.py:143
-msgid "Invalid file given for media type."
-msgstr "documento non valido come tipo multimediale."
-
#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41
msgid "Username"
msgstr "Nome utente"
@@ -36,63 +33,66 @@ msgstr "Password"
msgid "Email address"
msgstr "Indirizzo email"
+#: mediagoblin/auth/forms.py:51
+msgid "Username or email"
+msgstr ""
+
+#: mediagoblin/auth/forms.py:58
+msgid "Incorrect input"
+msgstr ""
+
#: mediagoblin/auth/views.py:55
msgid "Sorry, registration is disabled on this instance."
msgstr "Spiacente, registrazione è disabilitata su questa istanza"
-#: mediagoblin/auth/views.py:73
+#: mediagoblin/auth/views.py:75
msgid "Sorry, a user with that name already exists."
msgstr "Spiacente, esiste già un utente con quel nome"
-#: mediagoblin/auth/views.py:77
+#: mediagoblin/auth/views.py:79
msgid "Sorry, a user with that email address already exists."
msgstr "Siamo spiacenti, un utente con quell'indirizzo email esiste già."
-#: mediagoblin/auth/views.py:180
+#: mediagoblin/auth/views.py:182
msgid ""
"Your email address has been verified. You may now login, edit your profile, "
"and submit images!"
-msgstr ""
-"Il tuo indirizzo email è stato verificato. Puoi ora fare login, modificare "
-"il tuo profilo, e inserire immagini!"
+msgstr "Il tuo indirizzo email è stato verificato. Puoi ora fare login, modificare il tuo profilo, e inserire immagini!"
-#: mediagoblin/auth/views.py:186
+#: mediagoblin/auth/views.py:188
msgid "The verification key or user id is incorrect"
msgstr "La chiave di verifica o l'id utente è sbagliato"
-#: mediagoblin/auth/views.py:204
+#: mediagoblin/auth/views.py:206
msgid "You must be logged in so we know who to send the email to!"
-msgstr ""
-"Devi entrare col tuo profilo così possiamo sapere a chi inviare l'email!"
+msgstr "Devi entrare col tuo profilo così possiamo sapere a chi inviare l'email!"
-#: mediagoblin/auth/views.py:212
+#: mediagoblin/auth/views.py:214
msgid "You've already verified your email address!"
msgstr "Hai già verificato il tuo indirizzo email!"
-#: mediagoblin/auth/views.py:225
+#: mediagoblin/auth/views.py:227
msgid "Resent your verification email."
msgstr "Rispedisci email di verifica"
-#: mediagoblin/auth/views.py:260
+#: mediagoblin/auth/views.py:263
msgid ""
"An email has been sent with instructions on how to change your password."
-msgstr ""
+msgstr "Ti è stata inviata un'email con le istruzioni per cambiare la tua password."
-#: mediagoblin/auth/views.py:270
+#: mediagoblin/auth/views.py:273
msgid ""
"Could not send password recovery email as your username is inactive or your "
"account's email address has not been verified."
-msgstr ""
-"Impossibile inviare l'email di recupero password perchè il tuo nome utente è"
-" inattivo o il tuo account email non è stato verificato."
+msgstr "Impossibile inviare l'email di recupero password perchè il tuo nome utente è inattivo o il tuo account email non è stato verificato."
-#: mediagoblin/auth/views.py:282
+#: mediagoblin/auth/views.py:285
msgid "Couldn't find someone with that username or email."
-msgstr ""
+msgstr "Impossibile trovare qualcuno con questo username o password."
-#: mediagoblin/auth/views.py:330
+#: mediagoblin/auth/views.py:333
msgid "You can now log in using your new password."
-msgstr ""
+msgstr "Ora puoi effettuare il login con la nuova password."
#: mediagoblin/edit/forms.py:25 mediagoblin/submit/forms.py:28
msgid "Title"
@@ -116,7 +116,7 @@ msgstr "Tags"
#: mediagoblin/edit/forms.py:35 mediagoblin/submit/forms.py:38
msgid "Separate tags by commas."
-msgstr ""
+msgstr "Separa le tags con la virgola."
#: mediagoblin/edit/forms.py:38
msgid "Slug"
@@ -130,11 +130,12 @@ msgstr ""
msgid ""
"The title part of this media's address. You usually don't need to change "
"this."
-msgstr ""
+msgstr "Il titolo è parte dell'indirizzo del contenuto. Nella maggior parte dei casi non c'è bisogno di cambiarlo."
#: mediagoblin/edit/forms.py:44 mediagoblin/submit/forms.py:41
+#: mediagoblin/templates/mediagoblin/utils/license.html:20
msgid "License"
-msgstr ""
+msgstr "Licenza"
#: mediagoblin/edit/forms.py:50
msgid "Bio"
@@ -144,61 +145,64 @@ msgstr "Bio"
msgid "Website"
msgstr "Sito web"
+#: mediagoblin/edit/forms.py:58
+msgid "This address contains errors"
+msgstr ""
+
#: mediagoblin/edit/forms.py:63
msgid "Old password"
msgstr "Password vecchia"
#: mediagoblin/edit/forms.py:65
msgid "Enter your old password to prove you own this account."
-msgstr ""
+msgstr "Inserisci la vecchia password per dimostrare di essere il proprietario dell'account."
#: mediagoblin/edit/forms.py:68
msgid "New password"
-msgstr ""
+msgstr "Nuova password"
-#: mediagoblin/edit/views.py:68
+#: mediagoblin/edit/views.py:67
msgid "An entry with that slug already exists for this user."
msgstr ""
-#: mediagoblin/edit/views.py:92
+#: mediagoblin/edit/views.py:88
msgid "You are editing another user's media. Proceed with caution."
-msgstr ""
-"Stai modificando documenti multimediale di un altro utente. Procedi con "
-"attenzione."
+msgstr "Stai modificando documenti multimediale di un altro utente. Procedi con attenzione."
-#: mediagoblin/edit/views.py:162
+#: mediagoblin/edit/views.py:158
msgid "You are editing a user's profile. Proceed with caution."
msgstr "Stai modificando il profilo di un utente. Procedi con attenzione."
-#: mediagoblin/edit/views.py:180
+#: mediagoblin/edit/views.py:174
msgid "Profile changes saved"
-msgstr ""
+msgstr "Cambiamenti del profilo salvati"
-#: mediagoblin/edit/views.py:206
+#: mediagoblin/edit/views.py:200
msgid "Wrong password"
msgstr "Password errata"
-#: mediagoblin/edit/views.py:222
+#: mediagoblin/edit/views.py:216
msgid "Account settings saved"
-msgstr ""
-
-#: mediagoblin/media_types/__init__.py:77
-msgid "Could not extract any file extension from \"{filename}\""
-msgstr ""
+msgstr "Impostazioni del profilo salvate"
-#: mediagoblin/media_types/__init__.py:88
+#: mediagoblin/media_types/__init__.py:60
+#: mediagoblin/media_types/__init__.py:120
msgid "Sorry, I don't support that file type :("
-msgstr ""
+msgstr "Mi dispiace, non supporto questo tipo di file :("
+
+#: mediagoblin/processing/__init__.py:127
+msgid "Invalid file given for media type."
+msgstr "documento non valido come tipo multimediale."
#: mediagoblin/submit/forms.py:26
msgid "File"
msgstr "Documento"
-#: mediagoblin/submit/views.py:54
+#: mediagoblin/submit/views.py:56
msgid "You must provide a file."
msgstr "Devi specificare un documento."
-#: mediagoblin/submit/views.py:158
+#: mediagoblin/submit/views.py:163
msgid "Woohoo! Submitted!"
msgstr "Evviva! "
@@ -218,40 +222,47 @@ msgstr "Non sembra esserci una pagina a questo indirizzo. Spiacente!"
msgid ""
"If you're sure the address is correct, maybe the page you're looking for has"
" been moved or deleted."
-msgstr ""
-"Se sei sicuro che l'indirizzo è corretto, forse la pagina che stai cercando "
-"è stata spostata o cancellata."
+msgstr "Se sei sicuro che l'indirizzo è corretto, forse la pagina che stai cercando è stata spostata o cancellata."
-#: mediagoblin/templates/mediagoblin/base.html:46
+#: mediagoblin/templates/mediagoblin/base.html:47
msgid "MediaGoblin logo"
msgstr "MediaGoblin logo"
-#: mediagoblin/templates/mediagoblin/base.html:51
-#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
-msgid "Add media"
-msgstr "Aggiungi documenti multimediali"
-
-#: mediagoblin/templates/mediagoblin/base.html:62
+#: mediagoblin/templates/mediagoblin/base.html:57
msgid "Verify your email!"
msgstr "Verifica la tua email!"
-#: mediagoblin/templates/mediagoblin/base.html:69
-msgid "log out"
-msgstr "disconnettiti"
+#: mediagoblin/templates/mediagoblin/base.html:63
+msgid "+ Add media"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:65
+msgid "View your profile"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:66
+msgid "Log out"
+msgstr ""
-#: mediagoblin/templates/mediagoblin/base.html:72
-#: mediagoblin/templates/mediagoblin/auth/login.html:27
-#: mediagoblin/templates/mediagoblin/auth/login.html:45
+#: mediagoblin/templates/mediagoblin/base.html:71
+#: mediagoblin/templates/mediagoblin/auth/login.html:32
+#: mediagoblin/templates/mediagoblin/auth/login.html:50
msgid "Log in"
msgstr "Accedi"
-#: mediagoblin/templates/mediagoblin/base.html:84
+#: mediagoblin/templates/mediagoblin/base.html:85
msgid ""
"Powered by <a href=\"http://mediagoblin.org\">MediaGoblin</a>, a <a "
-"href=\"http://gnu.org/\">GNU</a> project"
+"href=\"http://gnu.org/\">GNU</a> project."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:88
+#, python-format
+msgid ""
+"Released under the <a "
+"href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a "
+"href=\"%(source_link)s\">Source code</a> available."
msgstr ""
-"Powered by <a href=\"http://mediagoblin.org\">MediaGoblin</a>, un progetto "
-"<a href=\"http://gnu.org/\">GNU</a>"
#: mediagoblin/templates/mediagoblin/root.html:24
msgid "Explore"
@@ -265,18 +276,13 @@ msgstr "Ciao, benvenuto a questo sito MediaGoblin!"
msgid ""
"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, an "
"extraordinarily great piece of media hosting software."
-msgstr ""
-"questo sito sta utilizzando <a "
-"href=\"http://mediagoblin.org\">Mediagoblin</a>, un ottimo programma di "
-"media hosting."
+msgstr "questo sito sta utilizzando <a href=\"http://mediagoblin.org\">Mediagoblin</a>, un ottimo programma di media hosting."
#: mediagoblin/templates/mediagoblin/root.html:29
msgid ""
"To add your own media, place comments, save your favourites and more, you "
"can log in with your MediaGoblin account."
-msgstr ""
-"Per aggiungere i tuoi file, scrivere commenti, salvare i tuoi preferiti e "
-"altro, devi entrare col tuo profilo MediaGoblin."
+msgstr "Per aggiungere i tuoi file, scrivere commenti, salvare i tuoi preferiti e altro, devi entrare col tuo profilo MediaGoblin."
#: mediagoblin/templates/mediagoblin/root.html:31
msgid "Don't have one yet? It's easy!"
@@ -296,11 +302,11 @@ msgstr "Documenti multimediali più recenti"
#: mediagoblin/templates/mediagoblin/auth/change_fp.html:32
msgid "Set your new password"
-msgstr ""
+msgstr "Imposta la nuova password"
#: mediagoblin/templates/mediagoblin/auth/change_fp.html:35
msgid "Set password"
-msgstr ""
+msgstr "Imposta password"
#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27
msgid "Recover password"
@@ -322,29 +328,21 @@ msgid ""
"\n"
"If you think this is an error, just ignore this email and continue being\n"
"a happy goblin!"
-msgstr ""
-"Ciao %(username)s,\n"
-"per cambiare la tua password MediaGoblin apri il seguente URL\n"
-"nel tuo web browser:\n"
-"\n"
-"%(verification_url)s\n"
-"\n"
-"Se pensi che sia un errore, ignora semplicemente questa email e continua ad essere \n"
-"un goblin felice!"
+msgstr "Ciao %(username)s,\nper cambiare la tua password MediaGoblin apri il seguente URL\nnel tuo web browser:\n\n%(verification_url)s\n\nSe pensi che sia un errore, ignora semplicemente questa email e continua ad essere \nun goblin felice!"
-#: mediagoblin/templates/mediagoblin/auth/login.html:30
+#: mediagoblin/templates/mediagoblin/auth/login.html:35
msgid "Logging in failed!"
msgstr "Accesso fallito!"
-#: mediagoblin/templates/mediagoblin/auth/login.html:35
+#: mediagoblin/templates/mediagoblin/auth/login.html:40
msgid "Don't have an account yet?"
msgstr "Non hai ancora un account?"
-#: mediagoblin/templates/mediagoblin/auth/login.html:36
+#: mediagoblin/templates/mediagoblin/auth/login.html:41
msgid "Create one here!"
msgstr "Creane uno qui!"
-#: mediagoblin/templates/mediagoblin/auth/login.html:42
+#: mediagoblin/templates/mediagoblin/auth/login.html:47
msgid "Forgot your password?"
msgstr "Hai dimenticato la password?"
@@ -365,12 +363,7 @@ msgid ""
"your web browser:\n"
"\n"
"%(verification_url)s"
-msgstr ""
-"Ciao %(username)s,\n"
-"\n"
-"per attivare il tuo account GNU MediaGoblin, apri il seguente URL nel tuo navigatore web.\n"
-"\n"
-"%(verification_url)s"
+msgstr "Ciao %(username)s,\n\nper attivare il tuo account GNU MediaGoblin, apri il seguente URL nel tuo navigatore web.\n\n%(verification_url)s"
#: mediagoblin/templates/mediagoblin/edit/edit.html:29
#, python-format
@@ -391,7 +384,7 @@ msgstr "Salva i cambiamenti"
#: mediagoblin/templates/mediagoblin/edit/edit_account.html:34
#, python-format
msgid "Changing %(username)s's account settings"
-msgstr ""
+msgstr "Cambio le impostazione dell'account %(username)s"
#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29
#, python-format
@@ -405,18 +398,44 @@ msgid "Media tagged with: %(tag_name)s"
msgstr "file taggato con:%(tag_name)s"
#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:46
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:53
msgid "Original"
msgstr "Originale"
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:33
+#: 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 <a href=\"http://getfirefox.com\">\n"
+"\t http://getfirefox.com</a>!"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:56
+msgid "Download"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:60
+msgid "original file"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:63
+msgid "WebM file (Vorbis codec)"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:40
msgid ""
"Sorry, this video will not work because \n"
"\t your web browser does not support HTML5 \n"
"\t video."
msgstr ""
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:36
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:43
msgid ""
"You can get a modern web browser that \n"
"\t can play this video at <a href=\"http://getfirefox.com\">\n"
@@ -425,11 +444,11 @@ msgstr ""
#: mediagoblin/templates/mediagoblin/submit/start.html:26
msgid "Add your media"
-msgstr ""
+msgstr "Aggiungi il tuo contenuto"
#: mediagoblin/templates/mediagoblin/submit/start.html:30
msgid "Add"
-msgstr ""
+msgstr "Aggiungi"
#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30
#, python-format
@@ -441,55 +460,49 @@ msgstr "file di %(username)s"
msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media"
msgstr "Documenti multimediali di <a href=\"%(user_url)s\">%(username)s</a>"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:72
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:46
#, python-format
-msgid "Added on %(date)s."
+msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:81
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:67
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:73
+#, python-format
+msgid "Image for %(media_title)s"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:87
msgid "Edit"
msgstr "Modifica"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:85
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
msgid "Delete"
msgstr "Elimina"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
-#, python-format
-msgid "%(comment_count)s comment"
-msgstr ""
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:93
-#, python-format
-msgid "%(comment_count)s comments"
-msgstr ""
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:95
-msgid "No comments yet."
-msgstr ""
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:103
-msgid "Add one"
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:124
+msgid "Add a comment"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:112
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:131
msgid ""
"You can use <a "
"href=\"http://daringfireball.net/projects/markdown/basics\">Markdown</a> for"
" formatting."
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:116
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:135
msgid "Add this comment"
-msgstr ""
+msgstr "Aggiungi questo commento"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:138
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:154
msgid "at"
msgstr "a"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:153
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:174
#, python-format
-msgid "<p>â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a></p>"
+msgid ""
+"<h3>Added on</h3>\n"
+" <p>%(date)s</p>"
msgstr ""
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30
@@ -498,8 +511,8 @@ msgid "Really delete %(title)s?"
msgstr "Vuoi davvero cancellare %(title)s?"
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:50
-msgid "Delete Permanently"
-msgstr "Cancella permanentemente"
+msgid "Delete permanently"
+msgstr ""
#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:22
msgid "Media processing panel"
@@ -544,8 +557,7 @@ msgstr "Quasi finito! Il tuo account deve ancora essere attivato."
#: mediagoblin/templates/mediagoblin/user_pages/user.html:58
msgid ""
"An email should arrive in a few moments with instructions on how to do so."
-msgstr ""
-"In breve dovresti ricevere un email contenente istruzioni su come fare."
+msgstr "In breve dovresti ricevere un email contenente istruzioni su come fare."
#: mediagoblin/templates/mediagoblin/user_pages/user.html:62
msgid "In case it doesn't:"
@@ -559,18 +571,14 @@ msgstr "Rispedisci email di verifica"
msgid ""
"Someone has registered an account with this username, but it still has to be"
" activated."
-msgstr ""
-"Qualcuno ha registrato un account con questo nome utente, ma deve ancora "
-"essere attivato."
+msgstr "Qualcuno ha registrato un account con questo nome utente, ma deve ancora essere attivato."
#: 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 <a "
"href=\"%(login_url)s\">log in</a> and resend it."
-msgstr ""
-"Se sei quella persona ma hai perso l'email di verifica, puoi <a "
-"href=\"%(login_url)s\">accedere</a> e rispedirlo."
+msgstr "Se sei quella persona ma hai perso l'email di verifica, puoi <a href=\"%(login_url)s\">accedere</a> e rispedirlo."
#: mediagoblin/templates/mediagoblin/user_pages/user.html:96
msgid "Here's a spot to tell others about yourself."
@@ -587,7 +595,7 @@ msgstr "Questo utente non ha (ancora) compilato il proprio profilo."
#: mediagoblin/templates/mediagoblin/user_pages/user.html:125
msgid "Change account settings"
-msgstr ""
+msgstr "Cambia le impostazioni dell'account"
#: mediagoblin/templates/mediagoblin/user_pages/user.html:138
#, python-format
@@ -598,9 +606,11 @@ msgstr "Visualizza tutti i file multimediali di %(username)s"
msgid ""
"This is where your media will appear, but you don't seem to have added "
"anything yet."
-msgstr ""
-"Questo è dove i tuoi documenti multimediali appariranno, ma sembra che tu "
-"non abbia ancora aggiunto niente."
+msgstr "Questo è dove i tuoi documenti multimediali appariranno, ma sembra che tu non abbia ancora aggiunto niente."
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
+msgid "Add media"
+msgstr "Aggiungi documenti multimediali"
#: mediagoblin/templates/mediagoblin/user_pages/user.html:163
#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72
@@ -615,73 +625,69 @@ msgstr "feed icon"
msgid "Atom feed"
msgstr "Atom feed"
-#: mediagoblin/templates/mediagoblin/utils/license.html:21
-msgid "License:"
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:25
+msgid "Location"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:38
+#, python-format
+msgid "View on <a href=\"%(osm_url)s\">OpenStreetMap</a>"
msgstr ""
#: mediagoblin/templates/mediagoblin/utils/license.html:25
msgid "All rights reserved"
-msgstr ""
+msgstr "Tutti i diritti riservati"
#: mediagoblin/templates/mediagoblin/utils/pagination.html:39
msgid "↠Newer"
-msgstr ""
+msgstr "↠Più recente"
#: mediagoblin/templates/mediagoblin/utils/pagination.html:45
msgid "Older →"
-msgstr ""
+msgstr "Più vecchio →"
#: mediagoblin/templates/mediagoblin/utils/pagination.html:48
msgid "Go to page:"
msgstr "Vai alla pagina:"
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:27
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:32
+#: mediagoblin/templates/mediagoblin/utils/prev_next.html:28
+#: mediagoblin/templates/mediagoblin/utils/prev_next.html:33
msgid "newer"
-msgstr ""
+msgstr "più recente"
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:38
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:43
+#: mediagoblin/templates/mediagoblin/utils/prev_next.html:39
+#: mediagoblin/templates/mediagoblin/utils/prev_next.html:44
msgid "older"
-msgstr ""
+msgstr "più vecchio"
#: mediagoblin/templates/mediagoblin/utils/tags.html:20
-msgid "View more media tagged with"
+msgid "Tagged with"
msgstr ""
-#: mediagoblin/templates/mediagoblin/utils/tags.html:25
-msgid "or"
-msgstr ""
-
-#: mediagoblin/tools/exif.py:68
+#: mediagoblin/tools/exif.py:75
msgid "Could not read the image file."
-msgstr ""
+msgstr "Non è possibile leggere il file dell'immagine"
#: mediagoblin/user_pages/forms.py:30
msgid "I am sure I want to delete this"
msgstr "Sono sicuro di volerlo cancellare"
-#: mediagoblin/user_pages/views.py:155
+#: mediagoblin/user_pages/views.py:153
msgid "Oops, your comment was empty."
msgstr "Oops, il tuo commento era vuoto."
-#: mediagoblin/user_pages/views.py:161
+#: mediagoblin/user_pages/views.py:159
msgid "Your comment has been posted!"
msgstr "Il tuo commento è stato aggiunto!"
-#: mediagoblin/user_pages/views.py:183
+#: mediagoblin/user_pages/views.py:185
msgid "You deleted the media."
msgstr "Hai cancellato il file"
-#: mediagoblin/user_pages/views.py:190
+#: mediagoblin/user_pages/views.py:192
msgid "The media was not deleted because you didn't check that you were sure."
-msgstr ""
-"Il file non è stato eliminato perchè non hai confermato di essere sicuro."
+msgstr "Il file non è stato eliminato perchè non hai confermato di essere sicuro."
-#: mediagoblin/user_pages/views.py:198
+#: mediagoblin/user_pages/views.py:200
msgid "You are about to delete another user's media. Proceed with caution."
-msgstr ""
-"Stai cancellando un documento multimediale di un altro utente. Procedi con "
-"attenzione."
-
-
+msgstr "Stai cancellando un documento multimediale di un altro utente. Procedi con attenzione."
diff --git a/mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.mo
index 3b24dd2d..861c0cab 100644
--- a/mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.mo
+++ b/mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.mo
Binary files differ
diff --git a/mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.po
index 35231f66..838375d9 100644
--- a/mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.po
+++ b/mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.po
@@ -7,9 +7,9 @@
msgid ""
msgstr ""
"Project-Id-Version: GNU MediaGoblin\n"
-"Report-Msgid-Bugs-To: http://bugs.foocorp.net/projects/mediagoblin/issues\n"
-"POT-Creation-Date: 2012-01-29 13:31-0600\n"
-"PO-Revision-Date: 2012-01-29 19:29+0000\n"
+"Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n"
+"POT-Creation-Date: 2012-06-01 16:32-0500\n"
+"PO-Revision-Date: 2012-06-01 21:30+0000\n"
"Last-Translator: cwebber <cwebber@dustycloud.org>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
@@ -19,10 +19,6 @@ msgstr ""
"Language: ja\n"
"Plural-Forms: nplurals=1; plural=0\n"
-#: mediagoblin/processing.py:143
-msgid "Invalid file given for media type."
-msgstr ""
-
#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41
msgid "Username"
msgstr "ユーザãƒãƒ¼ãƒ "
@@ -35,56 +31,64 @@ msgstr "パスワード"
msgid "Email address"
msgstr "メールアドレス"
+#: mediagoblin/auth/forms.py:51
+msgid "Username or email"
+msgstr ""
+
+#: mediagoblin/auth/forms.py:58
+msgid "Incorrect input"
+msgstr ""
+
#: mediagoblin/auth/views.py:55
msgid "Sorry, registration is disabled on this instance."
msgstr "申ã—訳ã‚りã¾ã›ã‚“ãŒã€ã“ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ã§ç™»éŒ²ã¯ç„¡åйã«ãªã£ã¦ã„ã¾ã™ã€‚"
-#: mediagoblin/auth/views.py:73
+#: mediagoblin/auth/views.py:75
msgid "Sorry, a user with that name already exists."
msgstr "申ã—訳ã‚りã¾ã›ã‚“ãŒã€ãã®åå‰ã‚’æŒã¤ãƒ¦ãƒ¼ã‚¶ãƒ¼ãŒã™ã§ã«å­˜åœ¨ã—ã¦ã„ã¾ã™ã€‚"
-#: mediagoblin/auth/views.py:77
+#: mediagoblin/auth/views.py:79
msgid "Sorry, a user with that email address already exists."
msgstr ""
-#: mediagoblin/auth/views.py:180
+#: 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:186
+#: mediagoblin/auth/views.py:188
msgid "The verification key or user id is incorrect"
msgstr "検証キーã¾ãŸã¯ãƒ¦ãƒ¼ã‚¶ãƒ¼IDãŒé–“é•ã£ã¦ã„ã¾ã™"
-#: mediagoblin/auth/views.py:204
+#: 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:212
+#: mediagoblin/auth/views.py:214
msgid "You've already verified your email address!"
msgstr ""
-#: mediagoblin/auth/views.py:225
+#: mediagoblin/auth/views.py:227
msgid "Resent your verification email."
msgstr "検証メールをå†é€ã—ã¾ã—ãŸã€‚"
-#: mediagoblin/auth/views.py:260
+#: mediagoblin/auth/views.py:263
msgid ""
"An email has been sent with instructions on how to change your password."
msgstr ""
-#: mediagoblin/auth/views.py:270
+#: mediagoblin/auth/views.py:273
msgid ""
"Could not send password recovery email as your username is inactive or your "
"account's email address has not been verified."
msgstr ""
-#: mediagoblin/auth/views.py:282
+#: mediagoblin/auth/views.py:285
msgid "Couldn't find someone with that username or email."
msgstr ""
-#: mediagoblin/auth/views.py:330
+#: mediagoblin/auth/views.py:333
msgid "You can now log in using your new password."
msgstr ""
@@ -127,6 +131,7 @@ msgid ""
msgstr ""
#: mediagoblin/edit/forms.py:44 mediagoblin/submit/forms.py:41
+#: mediagoblin/templates/mediagoblin/utils/license.html:20
msgid "License"
msgstr ""
@@ -138,6 +143,10 @@ msgstr "自己紹介"
msgid "Website"
msgstr "URL"
+#: mediagoblin/edit/forms.py:58
+msgid "This address contains errors"
+msgstr ""
+
#: mediagoblin/edit/forms.py:63
msgid "Old password"
msgstr ""
@@ -150,47 +159,48 @@ msgstr ""
msgid "New password"
msgstr ""
-#: mediagoblin/edit/views.py:68
+#: mediagoblin/edit/views.py:67
msgid "An entry with that slug already exists for this user."
msgstr "ãã®ã‚¹ãƒ©ã‚°ã‚’æŒã¤ã‚¨ãƒ³ãƒˆãƒªã¯ã€ã“ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¯æ—¢ã«å­˜åœ¨ã—ã¾ã™ã€‚"
-#: mediagoblin/edit/views.py:92
+#: mediagoblin/edit/views.py:88
msgid "You are editing another user's media. Proceed with caution."
msgstr "ã‚ãªãŸã¯ã€ä»–ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã®ãƒ¡ãƒ‡ã‚£ã‚¢ã‚’編集ã—ã¦ã„ã¾ã™ã€‚ã”æ³¨æ„ãã ã•ã„。"
-#: mediagoblin/edit/views.py:162
+#: mediagoblin/edit/views.py:158
msgid "You are editing a user's profile. Proceed with caution."
msgstr "ã‚ãªãŸã¯ã€ä»–ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã®ãƒ—ロファイルを編集ã—ã¦ã„ã¾ã™ã€‚ã”æ³¨æ„ãã ã•ã„。"
-#: mediagoblin/edit/views.py:180
+#: mediagoblin/edit/views.py:174
msgid "Profile changes saved"
msgstr ""
-#: mediagoblin/edit/views.py:206
+#: mediagoblin/edit/views.py:200
msgid "Wrong password"
msgstr ""
-#: mediagoblin/edit/views.py:222
+#: mediagoblin/edit/views.py:216
msgid "Account settings saved"
msgstr ""
-#: mediagoblin/media_types/__init__.py:77
-msgid "Could not extract any file extension from \"{filename}\""
+#: mediagoblin/media_types/__init__.py:60
+#: mediagoblin/media_types/__init__.py:120
+msgid "Sorry, I don't support that file type :("
msgstr ""
-#: mediagoblin/media_types/__init__.py:88
-msgid "Sorry, I don't support that file type :("
+#: mediagoblin/processing/__init__.py:127
+msgid "Invalid file given for media type."
msgstr ""
#: mediagoblin/submit/forms.py:26
msgid "File"
msgstr "ファイル"
-#: mediagoblin/submit/views.py:54
+#: mediagoblin/submit/views.py:56
msgid "You must provide a file."
msgstr "ファイルをæä¾›ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚"
-#: mediagoblin/submit/views.py:158
+#: mediagoblin/submit/views.py:163
msgid "Woohoo! Submitted!"
msgstr "投稿終了ï¼"
@@ -212,33 +222,44 @@ msgid ""
" been moved or deleted."
msgstr ""
-#: mediagoblin/templates/mediagoblin/base.html:46
+#: mediagoblin/templates/mediagoblin/base.html:47
msgid "MediaGoblin logo"
msgstr ""
-#: mediagoblin/templates/mediagoblin/base.html:51
-#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
-msgid "Add media"
+#: mediagoblin/templates/mediagoblin/base.html:57
+msgid "Verify your email!"
msgstr ""
-#: mediagoblin/templates/mediagoblin/base.html:62
-msgid "Verify your email!"
+#: mediagoblin/templates/mediagoblin/base.html:63
+msgid "+ Add media"
msgstr ""
-#: mediagoblin/templates/mediagoblin/base.html:69
-msgid "log out"
+#: mediagoblin/templates/mediagoblin/base.html:65
+msgid "View your profile"
msgstr ""
-#: mediagoblin/templates/mediagoblin/base.html:72
-#: mediagoblin/templates/mediagoblin/auth/login.html:27
-#: mediagoblin/templates/mediagoblin/auth/login.html:45
+#: mediagoblin/templates/mediagoblin/base.html:66
+msgid "Log out"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:71
+#: mediagoblin/templates/mediagoblin/auth/login.html:32
+#: mediagoblin/templates/mediagoblin/auth/login.html:50
msgid "Log in"
msgstr "ログイン"
-#: mediagoblin/templates/mediagoblin/base.html:84
+#: mediagoblin/templates/mediagoblin/base.html:85
msgid ""
"Powered by <a href=\"http://mediagoblin.org\">MediaGoblin</a>, a <a "
-"href=\"http://gnu.org/\">GNU</a> project"
+"href=\"http://gnu.org/\">GNU</a> project."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:88
+#, python-format
+msgid ""
+"Released under the <a "
+"href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a "
+"href=\"%(source_link)s\">Source code</a> available."
msgstr ""
#: mediagoblin/templates/mediagoblin/root.html:24
@@ -307,19 +328,19 @@ msgid ""
"a happy goblin!"
msgstr ""
-#: mediagoblin/templates/mediagoblin/auth/login.html:30
+#: mediagoblin/templates/mediagoblin/auth/login.html:35
msgid "Logging in failed!"
msgstr ""
-#: mediagoblin/templates/mediagoblin/auth/login.html:35
+#: mediagoblin/templates/mediagoblin/auth/login.html:40
msgid "Don't have an account yet?"
msgstr "ã¾ã ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’æŒã£ã¦ã„ã¾ã›ã‚“ã‹ï¼Ÿ"
-#: mediagoblin/templates/mediagoblin/auth/login.html:36
+#: mediagoblin/templates/mediagoblin/auth/login.html:41
msgid "Create one here!"
msgstr "ã“ã“ã§ä½œæˆï¼"
-#: mediagoblin/templates/mediagoblin/auth/login.html:42
+#: mediagoblin/templates/mediagoblin/auth/login.html:47
msgid "Forgot your password?"
msgstr ""
@@ -340,12 +361,7 @@ msgid ""
"your web browser:\n"
"\n"
"%(verification_url)s"
-msgstr ""
-"%(username)s様ã¸\n"
-"\n"
-"GNU MediaGoblinアカウントを検証ã«ã™ã‚‹ã«ã¯ã€ã“ã®URLã‚’é–‹ã„ã¦ãã ã•ã„。\n"
-"\n"
-"%(verification_url)s"
+msgstr "%(username)s様ã¸\n\nGNU MediaGoblinアカウントを検証ã«ã™ã‚‹ã«ã¯ã€ã“ã®URLã‚’é–‹ã„ã¦ãã ã•ã„。\n\n%(verification_url)s"
#: mediagoblin/templates/mediagoblin/edit/edit.html:29
#, python-format
@@ -380,18 +396,44 @@ msgid "Media tagged with: %(tag_name)s"
msgstr ""
#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:46
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:53
msgid "Original"
msgstr ""
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:33
+#: 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 <a href=\"http://getfirefox.com\">\n"
+"\t http://getfirefox.com</a>!"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:56
+msgid "Download"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:60
+msgid "original file"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:63
+msgid "WebM file (Vorbis codec)"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:40
msgid ""
"Sorry, this video will not work because \n"
"\t your web browser does not support HTML5 \n"
"\t video."
msgstr ""
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:36
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:43
msgid ""
"You can get a modern web browser that \n"
"\t can play this video at <a href=\"http://getfirefox.com\">\n"
@@ -416,55 +458,49 @@ msgstr ""
msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media"
msgstr "<a href=\"%(user_url)s\">%(username)s</a>ã•ã‚“ã®ã‚³ãƒ³ãƒ†ãƒ³ãƒ„"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:72
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:46
#, python-format
-msgid "Added on %(date)s."
-msgstr ""
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:81
-msgid "Edit"
+msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:85
-msgid "Delete"
-msgstr ""
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:67
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:73
#, python-format
-msgid "%(comment_count)s comment"
+msgid "Image for %(media_title)s"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:93
-#, python-format
-msgid "%(comment_count)s comments"
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:87
+msgid "Edit"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:95
-msgid "No comments yet."
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
+msgid "Delete"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:103
-msgid "Add one"
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:124
+msgid "Add a comment"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:112
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:131
msgid ""
"You can use <a "
"href=\"http://daringfireball.net/projects/markdown/basics\">Markdown</a> for"
" formatting."
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:116
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:135
msgid "Add this comment"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:138
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:154
msgid "at"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:153
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:174
#, python-format
-msgid "<p>â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a></p>"
+msgid ""
+"<h3>Added on</h3>\n"
+" <p>%(date)s</p>"
msgstr ""
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30
@@ -473,7 +509,7 @@ msgid "Really delete %(title)s?"
msgstr ""
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:50
-msgid "Delete Permanently"
+msgid "Delete permanently"
msgstr ""
#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:22
@@ -570,6 +606,10 @@ msgid ""
"anything yet."
msgstr ""
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
+msgid "Add media"
+msgstr ""
+
#: mediagoblin/templates/mediagoblin/user_pages/user.html:163
#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72
msgid "There doesn't seem to be any media here yet..."
@@ -583,8 +623,13 @@ msgstr ""
msgid "Atom feed"
msgstr ""
-#: mediagoblin/templates/mediagoblin/utils/license.html:21
-msgid "License:"
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:25
+msgid "Location"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:38
+#, python-format
+msgid "View on <a href=\"%(osm_url)s\">OpenStreetMap</a>"
msgstr ""
#: mediagoblin/templates/mediagoblin/utils/license.html:25
@@ -603,25 +648,21 @@ msgstr ""
msgid "Go to page:"
msgstr ""
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:27
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:32
+#: 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:38
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:43
+#: 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 "View more media tagged with"
+msgid "Tagged with"
msgstr ""
-#: mediagoblin/templates/mediagoblin/utils/tags.html:25
-msgid "or"
-msgstr ""
-
-#: mediagoblin/tools/exif.py:68
+#: mediagoblin/tools/exif.py:75
msgid "Could not read the image file."
msgstr ""
@@ -629,24 +670,22 @@ msgstr ""
msgid "I am sure I want to delete this"
msgstr ""
-#: mediagoblin/user_pages/views.py:155
+#: mediagoblin/user_pages/views.py:153
msgid "Oops, your comment was empty."
msgstr ""
-#: mediagoblin/user_pages/views.py:161
+#: mediagoblin/user_pages/views.py:159
msgid "Your comment has been posted!"
msgstr ""
-#: mediagoblin/user_pages/views.py:183
+#: mediagoblin/user_pages/views.py:185
msgid "You deleted the media."
msgstr ""
-#: mediagoblin/user_pages/views.py:190
+#: mediagoblin/user_pages/views.py:192
msgid "The media was not deleted because you didn't check that you were sure."
msgstr ""
-#: mediagoblin/user_pages/views.py:198
+#: mediagoblin/user_pages/views.py:200
msgid "You are about to delete another user's media. Proceed with caution."
msgstr ""
-
-
diff --git a/mediagoblin/i18n/nl/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/nl/LC_MESSAGES/mediagoblin.mo
index 0baae15d..1a395fea 100644
--- a/mediagoblin/i18n/nl/LC_MESSAGES/mediagoblin.mo
+++ b/mediagoblin/i18n/nl/LC_MESSAGES/mediagoblin.mo
Binary files differ
diff --git a/mediagoblin/i18n/nl/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/nl/LC_MESSAGES/mediagoblin.po
index c40671e6..1f696724d 100644
--- a/mediagoblin/i18n/nl/LC_MESSAGES/mediagoblin.po
+++ b/mediagoblin/i18n/nl/LC_MESSAGES/mediagoblin.po
@@ -4,13 +4,14 @@
#
# Translators:
# <mail@jefvanschendel.nl>, 2011, 2012.
+# <mvanderboom@gmail.com>, 2012.
msgid ""
msgstr ""
"Project-Id-Version: GNU MediaGoblin\n"
"Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n"
-"POT-Creation-Date: 2012-01-29 13:47-0600\n"
-"PO-Revision-Date: 2012-02-05 20:14+0000\n"
-"Last-Translator: schendje <mail@jefvanschendel.nl>\n"
+"POT-Creation-Date: 2012-04-30 10:48-0500\n"
+"PO-Revision-Date: 2012-05-08 17:52+0000\n"
+"Last-Translator: mvanderboom <mvanderboom@gmail.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -19,10 +20,6 @@ msgstr ""
"Language: nl\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
-#: mediagoblin/processing.py:143
-msgid "Invalid file given for media type."
-msgstr "Verkeerd bestandsformaat voor mediatype opgegeven."
-
#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41
msgid "Username"
msgstr "Gebruikersnaam"
@@ -35,63 +32,64 @@ msgstr "Wachtwoord"
msgid "Email address"
msgstr "E-mail adres"
+#: mediagoblin/auth/forms.py:51
+msgid "Username or email"
+msgstr "Gebruikersnaam of email-adres"
+
+#: mediagoblin/auth/forms.py:58
+msgid "Incorrect input"
+msgstr "Onjuiste invoer"
+
#: mediagoblin/auth/views.py:55
msgid "Sorry, registration is disabled on this instance."
msgstr "Sorry, registratie is uitgeschakeld op deze instantie."
-#: mediagoblin/auth/views.py:73
+#: mediagoblin/auth/views.py:75
msgid "Sorry, a user with that name already exists."
msgstr "Sorry, er bestaat al een gebruiker met die naam."
-#: mediagoblin/auth/views.py:77
+#: mediagoblin/auth/views.py:79
msgid "Sorry, a user with that email address already exists."
msgstr "Sorry, een gebruiker met dat e-mailadres bestaat al."
-#: mediagoblin/auth/views.py:180
+#: mediagoblin/auth/views.py:182
msgid ""
"Your email address has been verified. You may now login, edit your profile, "
"and submit images!"
-msgstr ""
-"Uw e-mailadres is geverifieerd. U kunt nu inloggen, uw profiel bewerken, en "
-"afbeeldingen toevoegen!"
+msgstr "Uw e-mailadres is geverifieerd. U kunt nu inloggen, uw profiel bewerken, en afbeeldingen toevoegen!"
-#: mediagoblin/auth/views.py:186
+#: mediagoblin/auth/views.py:188
msgid "The verification key or user id is incorrect"
msgstr "De verificatie sleutel of gebruikers-ID is onjuist"
-#: mediagoblin/auth/views.py:204
+#: mediagoblin/auth/views.py:206
msgid "You must be logged in so we know who to send the email to!"
-msgstr ""
-"Je moet ingelogd zijn, anders weten we niet waar we de e-mail naartoe moeten"
-" sturen!"
+msgstr "Je moet ingelogd zijn, anders weten we niet waar we de e-mail naartoe moeten sturen!"
-#: mediagoblin/auth/views.py:212
+#: mediagoblin/auth/views.py:214
msgid "You've already verified your email address!"
msgstr "Je hebt je e-mailadres al geverifieerd!"
-#: mediagoblin/auth/views.py:225
+#: mediagoblin/auth/views.py:227
msgid "Resent your verification email."
msgstr "Verificatie e-mail opnieuw opgestuurd."
-#: mediagoblin/auth/views.py:260
+#: mediagoblin/auth/views.py:263
msgid ""
"An email has been sent with instructions on how to change your password."
-msgstr ""
-"Een e-mail met instructies om je wachtwoord te veranderen is verstuurd."
+msgstr "Een e-mail met instructies om je wachtwoord te veranderen is verstuurd."
-#: mediagoblin/auth/views.py:270
+#: mediagoblin/auth/views.py:273
msgid ""
"Could not send password recovery email as your username is inactive or your "
"account's email address has not been verified."
-msgstr ""
-"Email kon niet verstuurd worden omdat je gebruikersnaam inactief is of omdat"
-" je e-mailadres nog niet geverifieerd is."
+msgstr "Email kon niet verstuurd worden omdat je gebruikersnaam inactief is of omdat je e-mailadres nog niet geverifieerd is."
-#: mediagoblin/auth/views.py:282
+#: mediagoblin/auth/views.py:285
msgid "Couldn't find someone with that username or email."
msgstr "Kon niemand vinden met die gebruikersnaam of dat e-mailadres."
-#: mediagoblin/auth/views.py:330
+#: mediagoblin/auth/views.py:333
msgid "You can now log in using your new password."
msgstr "Je kunt nu inloggen met je nieuwe wachtwoord."
@@ -109,10 +107,7 @@ msgid ""
"You can use\n"
" <a href=\"http://daringfireball.net/projects/markdown/basics\">\n"
" Markdown</a> for formatting."
-msgstr ""
-"Voor opmaak kun je <a "
-"href=\"http://daringfireball.net/projects/markdown/basics\">Markdown</a> "
-"gebruiken."
+msgstr "Voor opmaak kun je <a href=\"http://daringfireball.net/projects/markdown/basics\">Markdown</a> gebruiken."
#: mediagoblin/edit/forms.py:33 mediagoblin/submit/forms.py:36
msgid "Tags"
@@ -134,11 +129,10 @@ msgstr "De slug kan niet leeg zijn"
msgid ""
"The title part of this media's address. You usually don't need to change "
"this."
-msgstr ""
-"Het titelgedeelte van het adres van deze media. Normaal gesproken hoef je "
-"deze niet te veranderen."
+msgstr "Het titelgedeelte van het adres van deze media. Normaal gesproken hoef je deze niet te veranderen."
#: mediagoblin/edit/forms.py:44 mediagoblin/submit/forms.py:41
+#: mediagoblin/templates/mediagoblin/utils/license.html:20
msgid "License"
msgstr "Licentie"
@@ -150,6 +144,10 @@ msgstr "Bio"
msgid "Website"
msgstr "Website"
+#: mediagoblin/edit/forms.py:58
+msgid "This address contains errors"
+msgstr "Dit adres bevat fouten"
+
#: mediagoblin/edit/forms.py:63
msgid "Old password"
msgstr "Oud wachtwoord"
@@ -162,50 +160,48 @@ msgstr "Vul je oude wachtwoord in om te bewijzen dat dit jouw account is"
msgid "New password"
msgstr "Nieuw wachtwoord"
-#: mediagoblin/edit/views.py:68
+#: mediagoblin/edit/views.py:67
msgid "An entry with that slug already exists for this user."
msgstr "Er bestaat al een met die slug voor deze gebruiker."
-#: mediagoblin/edit/views.py:92
+#: mediagoblin/edit/views.py:88
msgid "You are editing another user's media. Proceed with caution."
-msgstr ""
-"U bent de media van een andere gebruiker aan het aanpassen. Ga voorzichtig "
-"te werk."
+msgstr "U bent de media van een andere gebruiker aan het aanpassen. Ga voorzichtig te werk."
-#: mediagoblin/edit/views.py:162
+#: mediagoblin/edit/views.py:158
msgid "You are editing a user's profile. Proceed with caution."
-msgstr ""
-"U bent een gebruikersprofiel aan het aanpassen. Ga voorzichtig te werk."
+msgstr "U bent een gebruikersprofiel aan het aanpassen. Ga voorzichtig te werk."
-#: mediagoblin/edit/views.py:180
+#: mediagoblin/edit/views.py:174
msgid "Profile changes saved"
msgstr "Profielaanpassingen opgeslagen"
-#: mediagoblin/edit/views.py:206
+#: mediagoblin/edit/views.py:200
msgid "Wrong password"
msgstr "Verkeerd wachtwoord"
-#: mediagoblin/edit/views.py:222
+#: mediagoblin/edit/views.py:216
msgid "Account settings saved"
msgstr "Accountinstellingen opgeslagen"
-#: mediagoblin/media_types/__init__.py:77
-msgid "Could not extract any file extension from \"{filename}\""
-msgstr "Kon geen bestandsextensie uit \"{filename}\" halen"
-
-#: mediagoblin/media_types/__init__.py:88
+#: mediagoblin/media_types/__init__.py:60
+#: mediagoblin/media_types/__init__.py:120
msgid "Sorry, I don't support that file type :("
msgstr "Sorry, dat bestandstype wordt niet ondersteunt."
+#: mediagoblin/processing/__init__.py:127
+msgid "Invalid file given for media type."
+msgstr "Verkeerd bestandsformaat voor mediatype opgegeven."
+
#: mediagoblin/submit/forms.py:26
msgid "File"
msgstr "Bestand"
-#: mediagoblin/submit/views.py:54
+#: mediagoblin/submit/views.py:56
msgid "You must provide a file."
msgstr "U moet een bestand aangeven."
-#: mediagoblin/submit/views.py:158
+#: mediagoblin/submit/views.py:163
msgid "Woohoo! Submitted!"
msgstr "Mooizo! Toegevoegd!"
@@ -225,41 +221,47 @@ msgstr "Het lijkt erop dat er geen pagina bestaat op dit adres. Sorry!"
msgid ""
"If you're sure the address is correct, maybe the page you're looking for has"
" been moved or deleted."
-msgstr ""
-"Als je zeker weet dat het adres klopt is de pagina misschien verplaatst of "
-"verwijderd."
+msgstr "Als je zeker weet dat het adres klopt is de pagina misschien verplaatst of verwijderd."
-#: mediagoblin/templates/mediagoblin/base.html:46
+#: mediagoblin/templates/mediagoblin/base.html:47
msgid "MediaGoblin logo"
msgstr "MediaGoblin logo"
-#: mediagoblin/templates/mediagoblin/base.html:51
-#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
-msgid "Add media"
-msgstr "Voeg media toe"
-
-#: mediagoblin/templates/mediagoblin/base.html:62
+#: mediagoblin/templates/mediagoblin/base.html:57
msgid "Verify your email!"
msgstr "Verifieer je e-mailadres!"
-#: mediagoblin/templates/mediagoblin/base.html:69
-msgid "log out"
-msgstr "uitloggen"
+#: mediagoblin/templates/mediagoblin/base.html:63
+msgid "+ Add media"
+msgstr "+ Media toevoegen"
+
+#: mediagoblin/templates/mediagoblin/base.html:65
+msgid "View your profile"
+msgstr "Profiel weergeven"
-#: mediagoblin/templates/mediagoblin/base.html:72
-#: mediagoblin/templates/mediagoblin/auth/login.html:27
-#: mediagoblin/templates/mediagoblin/auth/login.html:45
+#: mediagoblin/templates/mediagoblin/base.html:66
+msgid "Log out"
+msgstr "Afmelden"
+
+#: mediagoblin/templates/mediagoblin/base.html:71
+#: mediagoblin/templates/mediagoblin/auth/login.html:32
+#: mediagoblin/templates/mediagoblin/auth/login.html:50
msgid "Log in"
msgstr "Inloggen"
-#: mediagoblin/templates/mediagoblin/base.html:84
+#: mediagoblin/templates/mediagoblin/base.html:85
msgid ""
"Powered by <a href=\"http://mediagoblin.org\">MediaGoblin</a>, a <a "
-"href=\"http://gnu.org/\">GNU</a> project"
-msgstr ""
-"Aangedreven door &lt;a "
-"href=\"http://mediagoblin.org\"&gt;MediaGoblin&lt;/a&gt; , een &lt;a "
-"href=\"http://gnu.org/\"&gt;GNU-project&lt;/a&gt;"
+"href=\"http://gnu.org/\">GNU</a> project."
+msgstr "Hier draait <a href=\"http://mediagoblin.org\">MediaGoblin</a>, een <a href=\"http://gnu.org/\">GNU</a> project."
+
+#: mediagoblin/templates/mediagoblin/base.html:88
+#, python-format
+msgid ""
+"Released under the <a "
+"href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a "
+"href=\"%(source_link)s\">Source code</a> available."
+msgstr "Uitgegeven onder de <a href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>-licentie. <a href=\"%(source_link)s\">Broncode</a> available."
#: mediagoblin/templates/mediagoblin/root.html:24
msgid "Explore"
@@ -273,17 +275,13 @@ msgstr "Hoi, welkom op deze MediaGoblin website!"
msgid ""
"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, an "
"extraordinarily great piece of media hosting software."
-msgstr ""
-"Deze website draait <a href=\"http://mediagoblin.org\">MediaGoblin</a>, een "
-"buitengewoon goed stuk software voor mediahosting."
+msgstr "Deze website draait <a href=\"http://mediagoblin.org\">MediaGoblin</a>, een buitengewoon goed stuk software voor mediahosting."
#: mediagoblin/templates/mediagoblin/root.html:29
msgid ""
"To add your own media, place comments, save your favourites and more, you "
"can log in with your MediaGoblin account."
-msgstr ""
-"Om je eigen media toe te voegen, berichten te plaatsen, favorieten op te "
-"slaan en meer, kun je inloggen met je MediaGoblin account."
+msgstr "Om je eigen media toe te voegen, berichten te plaatsen, favorieten op te slaan en meer, kun je inloggen met je MediaGoblin account."
#: mediagoblin/templates/mediagoblin/root.html:31
msgid "Don't have one yet? It's easy!"
@@ -295,10 +293,7 @@ msgid ""
"<a class=\"button_action_highlight\" href=\"%(register_url)s\">Create an account at this site</a>\n"
" or\n"
" <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">Set up MediaGoblin on your own server</a>"
-msgstr ""
-"&lt;a class=\"button_action_highlight\" href=\"%(register_url)s\"&gt;Creëer een account op deze website&lt;/a&gt;\n"
-" of\n"
-" &lt;a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\"&gt;Gebruik MediaGoblin op je eigen server&lt;/a&gt;"
+msgstr "&lt;a class=\"button_action_highlight\" href=\"%(register_url)s\"&gt;Creëer een account op deze website&lt;/a&gt;\n of\n &lt;a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\"&gt;Gebruik MediaGoblin op je eigen server&lt;/a&gt;"
#: mediagoblin/templates/mediagoblin/root.html:40
msgid "Most recent media"
@@ -332,28 +327,21 @@ msgid ""
"\n"
"If you think this is an error, just ignore this email and continue being\n"
"a happy goblin!"
-msgstr ""
-"Hoi %(username)s,\n"
-"\n"
-"Om je wachtwoord voor GNU MediaGoblin te veranderen, moet je dit adres in je webbrowser openen:\n"
-"\n"
-"%(verification_url)s\n"
-"\n"
-"Als je denkt dat dit niet klopt, kun je deze e-mail gewoon negeren."
+msgstr "Hoi %(username)s,\n\nOm je wachtwoord voor GNU MediaGoblin te veranderen, moet je dit adres in je webbrowser openen:\n\n%(verification_url)s\n\nAls je denkt dat dit niet klopt, kun je deze e-mail gewoon negeren."
-#: mediagoblin/templates/mediagoblin/auth/login.html:30
+#: mediagoblin/templates/mediagoblin/auth/login.html:35
msgid "Logging in failed!"
msgstr "Inloggen is mislukt!"
-#: mediagoblin/templates/mediagoblin/auth/login.html:35
+#: mediagoblin/templates/mediagoblin/auth/login.html:40
msgid "Don't have an account yet?"
msgstr "Heeft u nog geen account?"
-#: mediagoblin/templates/mediagoblin/auth/login.html:36
+#: mediagoblin/templates/mediagoblin/auth/login.html:41
msgid "Create one here!"
msgstr "Maak er hier een!"
-#: mediagoblin/templates/mediagoblin/auth/login.html:42
+#: mediagoblin/templates/mediagoblin/auth/login.html:47
msgid "Forgot your password?"
msgstr "Wachtwoord vergeten?"
@@ -374,9 +362,7 @@ msgid ""
"your web browser:\n"
"\n"
"%(verification_url)s"
-msgstr ""
-"Hallo %(username)s , open de volgende URL in uw webbrowser om uw GNU "
-"MediaGoblin account te activeren: %(verification_url)s "
+msgstr "Hallo %(username)s , open de volgende URL in uw webbrowser om uw GNU MediaGoblin account te activeren: %(verification_url)s "
#: mediagoblin/templates/mediagoblin/edit/edit.html:29
#, python-format
@@ -411,27 +397,38 @@ msgid "Media tagged with: %(tag_name)s"
msgstr "Media met het label: %(tag_name)s"
#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:46
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:57
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:53
msgid "Original"
msgstr "Origineel"
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:33
+#: 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 "Sorry, dit geluidsfragment zal niet werken omdat\n»uw web-browser geen HTML5 ondersteuntâŽ\n»audio."
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:47
+msgid ""
+"You can get a modern web browser that \n"
+"\tcan play the audio at <a href=\"http://getfirefox.com\">\n"
+"\t http://getfirefox.com</a>!"
+msgstr "U kunt een moderne web-browser die \n\taudio kan afspelen vinden op <a href=\"http://getfirefox.com\">\n\t http://getfirefox.com</a>!"
+
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:40
msgid ""
"Sorry, this video will not work because \n"
"\t your web browser does not support HTML5 \n"
"\t video."
-msgstr ""
-"Sorry, deze video werkt niet omdat je webbrowser geen HTML5 video "
-"ondersteunt."
+msgstr "Sorry, deze video werkt niet omdat je webbrowser geen HTML5 video ondersteunt."
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:36
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:43
msgid ""
"You can get a modern web browser that \n"
"\t can play this video at <a href=\"http://getfirefox.com\">\n"
"\t http://getfirefox.com</a>!"
-msgstr ""
-"Je kunt een moderne webbrowser die deze video af kan spelen krijgen op <a "
-"href=\"http://getfirefox.com\">http://getfirefox.com</a>!"
+msgstr "Je kunt een moderne webbrowser die deze video af kan spelen krijgen op <a href=\"http://getfirefox.com\">http://getfirefox.com</a>!"
#: mediagoblin/templates/mediagoblin/submit/start.html:26
msgid "Add your media"
@@ -451,61 +448,50 @@ msgstr "Media van %(username)s"
msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media"
msgstr "Media van <a href=\"%(user_url)s\"> %(username)s </a>"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:72
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:46
#, python-format
-msgid "Added on %(date)s."
-msgstr "Toegevoegd op %(date)s."
+msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>"
+msgstr "â– Blader door media van <a href=\"%(user_url)s\">%(username)s</a>"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:81
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:67
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:73
+#, python-format
+msgid "Image for %(media_title)s"
+msgstr "Afbeelding voor %(media_title)s"
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:87
msgid "Edit"
msgstr "Pas aan"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:85
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
msgid "Delete"
msgstr "Verwijderen"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
-#, python-format
-msgid "%(comment_count)s comment"
-msgstr "%(comment_count)s bericht"
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:93
-#, python-format
-msgid "%(comment_count)s comments"
-msgstr "%(comment_count)s berichten"
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:95
-msgid "No comments yet."
-msgstr "Er zijn nog geen berichten."
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:103
-msgid "Add one"
-msgstr "Voeg er een toe"
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:124
+msgid "Add a comment"
+msgstr "Geef een reactie"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:112
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:131
msgid ""
"You can use <a "
"href=\"http://daringfireball.net/projects/markdown/basics\">Markdown</a> for"
" formatting."
-msgstr ""
-"Voor opmaak kun je &lt;a "
-"href=\"http://daringfireball.net/projects/markdown/basics\"&gt;Markdown&lt;/a&gt;"
-" gebruiken."
+msgstr "Voor opmaak kun je &lt;a href=\"http://daringfireball.net/projects/markdown/basics\"&gt;Markdown&lt;/a&gt; gebruiken."
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:116
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:135
msgid "Add this comment"
msgstr "Voeg dit bericht toe"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:138
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:154
msgid "at"
msgstr "op"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:153
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:174
#, python-format
-msgid "<p>â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a></p>"
-msgstr ""
-"<p>â– Media aan het bekijken van <a "
-"href=\"%(user_url)s\">%(username)s</a></p>"
+msgid ""
+"<h3>Added on</h3>\n"
+" <p>%(date)s</p>"
+msgstr "<h3>Toegevoegd op</h3>\n <p>%(date)s</p>"
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30
#, python-format
@@ -513,7 +499,7 @@ msgid "Really delete %(title)s?"
msgstr "Zeker weten dat je %(title)s wil verwijderen?"
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:50
-msgid "Delete Permanently"
+msgid "Delete permanently"
msgstr "Permanent verwijderen"
#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:22
@@ -559,9 +545,7 @@ msgstr "Bijna klaar! Je account moet nog geactiveerd worden."
#: mediagoblin/templates/mediagoblin/user_pages/user.html:58
msgid ""
"An email should arrive in a few moments with instructions on how to do so."
-msgstr ""
-"Een e-mail zou in een paar ogenblikken aan moeten komen met instructies "
-"hiertoe."
+msgstr "Een e-mail zou in een paar ogenblikken aan moeten komen met instructies hiertoe."
#: mediagoblin/templates/mediagoblin/user_pages/user.html:62
msgid "In case it doesn't:"
@@ -575,18 +559,14 @@ msgstr "Stuur de verificatie e-mail opnieuw op."
msgid ""
"Someone has registered an account with this username, but it still has to be"
" activated."
-msgstr ""
-"Iemand heeft een account met deze gebruikersnaam gemaakt, maar hij moet nog "
-"geactiveerd worden."
+msgstr "Iemand heeft een account met deze gebruikersnaam gemaakt, maar hij moet nog geactiveerd worden."
#: mediagoblin/templates/mediagoblin/user_pages/user.html:79
#, python-format
msgid ""
"If you are that person but you've lost your verification email, you can <a "
"href=\"%(login_url)s\">log in</a> and resend it."
-msgstr ""
-"Als u die persoon bent, maar de verificatie e-mail verloren hebt, kunt u <a "
-"href=\"%(login_url)s\">inloggen</a> en hem nogmaals verzenden."
+msgstr "Als u die persoon bent, maar de verificatie e-mail verloren hebt, kunt u <a href=\"%(login_url)s\">inloggen</a> en hem nogmaals verzenden."
#: mediagoblin/templates/mediagoblin/user_pages/user.html:96
msgid "Here's a spot to tell others about yourself."
@@ -614,9 +594,11 @@ msgstr "Bekijk alle media van %(username)s"
msgid ""
"This is where your media will appear, but you don't seem to have added "
"anything yet."
-msgstr ""
-"Dit is waar je nieuwe media zal verschijnen, maar het lijkt erop dat je nog "
-"niets heb toegevoegd."
+msgstr "Dit is waar je nieuwe media zal verschijnen, maar het lijkt erop dat je nog niets heb toegevoegd."
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
+msgid "Add media"
+msgstr "Voeg media toe"
#: mediagoblin/templates/mediagoblin/user_pages/user.html:163
#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72
@@ -631,9 +613,14 @@ msgstr "feed icoon"
msgid "Atom feed"
msgstr "Atom feed"
-#: mediagoblin/templates/mediagoblin/utils/license.html:21
-msgid "License:"
-msgstr "Licentie:"
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:25
+msgid "Location"
+msgstr "Locatie"
+
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:38
+#, python-format
+msgid "View on <a href=\"%(osm_url)s\">OpenStreetMap</a>"
+msgstr "Bekijken op <a href=\"%(osm_url)s\">OpenStreetMap</a>"
#: mediagoblin/templates/mediagoblin/utils/license.html:25
msgid "All rights reserved"
@@ -651,25 +638,21 @@ msgstr "Ouder →"
msgid "Go to page:"
msgstr "Ga naar pagina:"
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:27
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:32
+#: mediagoblin/templates/mediagoblin/utils/prev_next.html:28
+#: mediagoblin/templates/mediagoblin/utils/prev_next.html:33
msgid "newer"
msgstr "nieuwer"
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:38
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:43
+#: mediagoblin/templates/mediagoblin/utils/prev_next.html:39
+#: mediagoblin/templates/mediagoblin/utils/prev_next.html:44
msgid "older"
msgstr "ouder"
#: mediagoblin/templates/mediagoblin/utils/tags.html:20
-msgid "View more media tagged with"
-msgstr "Bekijk meer media gelabeld met"
-
-#: mediagoblin/templates/mediagoblin/utils/tags.html:25
-msgid "or"
-msgstr "of"
+msgid "Tagged with"
+msgstr "Getagged met"
-#: mediagoblin/tools/exif.py:68
+#: mediagoblin/tools/exif.py:75
msgid "Could not read the image file."
msgstr "Kon het afbeeldingsbestand niet lezen."
@@ -677,27 +660,22 @@ msgstr "Kon het afbeeldingsbestand niet lezen."
msgid "I am sure I want to delete this"
msgstr "Ik weet zeker dat ik dit wil verwijderen."
-#: mediagoblin/user_pages/views.py:155
+#: mediagoblin/user_pages/views.py:153
msgid "Oops, your comment was empty."
msgstr "Oeps, je bericht was leeg."
-#: mediagoblin/user_pages/views.py:161
+#: mediagoblin/user_pages/views.py:159
msgid "Your comment has been posted!"
msgstr "Je bericht is geplaatst!"
-#: mediagoblin/user_pages/views.py:183
+#: mediagoblin/user_pages/views.py:185
msgid "You deleted the media."
msgstr "Je hebt deze media verwijderd."
-#: mediagoblin/user_pages/views.py:190
+#: mediagoblin/user_pages/views.py:192
msgid "The media was not deleted because you didn't check that you were sure."
-msgstr ""
-"Deze media was niet verwijderd omdat je niet hebt aangegeven dat je het "
-"zeker weet."
+msgstr "Deze media was niet verwijderd omdat je niet hebt aangegeven dat je het zeker weet."
-#: mediagoblin/user_pages/views.py:198
+#: mediagoblin/user_pages/views.py:200
msgid "You are about to delete another user's media. Proceed with caution."
-msgstr ""
-"Je staat op het punt de media van iemand anders te verwijderen. Pas op."
-
-
+msgstr "Je staat op het punt de media van iemand anders te verwijderen. Pas op."
diff --git a/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.mo
index 01179e47..be6810e6 100644
--- a/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.mo
+++ b/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.mo
Binary files differ
diff --git a/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.po
index 1cc0b878..aaddade2 100644
--- a/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.po
+++ b/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.po
@@ -7,11 +7,11 @@
msgid ""
msgstr ""
"Project-Id-Version: GNU MediaGoblin\n"
-"Report-Msgid-Bugs-To: http://bugs.foocorp.net/projects/mediagoblin/issues\n"
-"POT-Creation-Date: 2012-01-29 13:31-0600\n"
-"PO-Revision-Date: 2012-01-29 19:29+0000\n"
+"Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n"
+"POT-Creation-Date: 2012-06-01 16:32-0500\n"
+"PO-Revision-Date: 2012-06-01 21:30+0000\n"
"Last-Translator: cwebber <cwebber@dustycloud.org>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language-Team: Norwegian Nynorsk (Norway) (http://www.transifex.net/projects/p/mediagoblin/language/nn_NO/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -19,10 +19,6 @@ msgstr ""
"Language: nn_NO\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
-#: mediagoblin/processing.py:143
-msgid "Invalid file given for media type."
-msgstr "Ugyldig fil for mediatypen."
-
#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41
msgid "Username"
msgstr "Brukarnamn"
@@ -35,59 +31,64 @@ msgstr "Passord"
msgid "Email address"
msgstr "Epost"
+#: mediagoblin/auth/forms.py:51
+msgid "Username or email"
+msgstr ""
+
+#: mediagoblin/auth/forms.py:58
+msgid "Incorrect input"
+msgstr ""
+
#: mediagoblin/auth/views.py:55
msgid "Sorry, registration is disabled on this instance."
msgstr "Registrering er slege av. Orsak."
-#: mediagoblin/auth/views.py:73
+#: mediagoblin/auth/views.py:75
msgid "Sorry, a user with that name already exists."
msgstr "Ein konto med dette brukarnamnet finst allereide."
-#: mediagoblin/auth/views.py:77
+#: mediagoblin/auth/views.py:79
msgid "Sorry, a user with that email address already exists."
msgstr ""
-#: mediagoblin/auth/views.py:180
+#: mediagoblin/auth/views.py:182
msgid ""
"Your email address has been verified. You may now login, edit your profile, "
"and submit images!"
-msgstr ""
-"Kontoen din er stadfesta. Du kan no logga inn, endra profilen din og lasta "
-"opp filer."
+msgstr "Kontoen din er stadfesta. Du kan no logga inn, endra profilen din og lasta opp filer."
-#: mediagoblin/auth/views.py:186
+#: mediagoblin/auth/views.py:188
msgid "The verification key or user id is incorrect"
msgstr "Stadfestingsnykelen eller brukar-ID-en din er feil."
-#: mediagoblin/auth/views.py:204
+#: 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:212
+#: mediagoblin/auth/views.py:214
msgid "You've already verified your email address!"
msgstr ""
-#: mediagoblin/auth/views.py:225
+#: mediagoblin/auth/views.py:227
msgid "Resent your verification email."
msgstr "Send ein ny stadfestingsepost."
-#: mediagoblin/auth/views.py:260
+#: mediagoblin/auth/views.py:263
msgid ""
"An email has been sent with instructions on how to change your password."
msgstr ""
-#: mediagoblin/auth/views.py:270
+#: mediagoblin/auth/views.py:273
msgid ""
"Could not send password recovery email as your username is inactive or your "
"account's email address has not been verified."
-msgstr ""
-"Kunne ikkje senda epost. Brukarnamnet ditt er inaktivt eller uverifisert."
+msgstr "Kunne ikkje senda epost. Brukarnamnet ditt er inaktivt eller uverifisert."
-#: mediagoblin/auth/views.py:282
+#: mediagoblin/auth/views.py:285
msgid "Couldn't find someone with that username or email."
msgstr ""
-#: mediagoblin/auth/views.py:330
+#: mediagoblin/auth/views.py:333
msgid "You can now log in using your new password."
msgstr ""
@@ -130,6 +131,7 @@ msgid ""
msgstr ""
#: mediagoblin/edit/forms.py:44 mediagoblin/submit/forms.py:41
+#: mediagoblin/templates/mediagoblin/utils/license.html:20
msgid "License"
msgstr ""
@@ -141,6 +143,10 @@ msgstr "Presentasjon"
msgid "Website"
msgstr "Heimeside"
+#: mediagoblin/edit/forms.py:58
+msgid "This address contains errors"
+msgstr ""
+
#: mediagoblin/edit/forms.py:63
msgid "Old password"
msgstr ""
@@ -153,47 +159,48 @@ msgstr ""
msgid "New password"
msgstr ""
-#: mediagoblin/edit/views.py:68
+#: mediagoblin/edit/views.py:67
msgid "An entry with that slug already exists for this user."
msgstr "Eit innlegg med denne adressetittelen finst allereie."
-#: mediagoblin/edit/views.py:92
+#: mediagoblin/edit/views.py:88
msgid "You are editing another user's media. Proceed with caution."
msgstr "Trå varsamt, du endrar nokon andre sine mediefiler."
-#: mediagoblin/edit/views.py:162
+#: mediagoblin/edit/views.py:158
msgid "You are editing a user's profile. Proceed with caution."
msgstr "Trå varsamt, du endrar nokon andre sin profil."
-#: mediagoblin/edit/views.py:180
+#: mediagoblin/edit/views.py:174
msgid "Profile changes saved"
msgstr ""
-#: mediagoblin/edit/views.py:206
+#: mediagoblin/edit/views.py:200
msgid "Wrong password"
msgstr ""
-#: mediagoblin/edit/views.py:222
+#: mediagoblin/edit/views.py:216
msgid "Account settings saved"
msgstr ""
-#: mediagoblin/media_types/__init__.py:77
-msgid "Could not extract any file extension from \"{filename}\""
-msgstr ""
-
-#: mediagoblin/media_types/__init__.py:88
+#: mediagoblin/media_types/__init__.py:60
+#: mediagoblin/media_types/__init__.py:120
msgid "Sorry, I don't support that file type :("
msgstr ""
+#: mediagoblin/processing/__init__.py:127
+msgid "Invalid file given for media type."
+msgstr "Ugyldig fil for mediatypen."
+
#: mediagoblin/submit/forms.py:26
msgid "File"
msgstr "Fil"
-#: mediagoblin/submit/views.py:54
+#: mediagoblin/submit/views.py:56
msgid "You must provide a file."
msgstr "Du må velja ei fil."
-#: mediagoblin/submit/views.py:158
+#: mediagoblin/submit/views.py:163
msgid "Woohoo! Submitted!"
msgstr "Johoo! Opplasta!"
@@ -213,40 +220,47 @@ msgstr "Det ser ikkje ut til å vera noko her... Orsak."
msgid ""
"If you're sure the address is correct, maybe the page you're looking for has"
" been moved or deleted."
-msgstr ""
-"Er du sikker på at adressa er korrekt, so er sida truleg flytta eller "
-"sletta."
+msgstr "Er du sikker på at adressa er korrekt, so er sida truleg flytta eller sletta."
-#: mediagoblin/templates/mediagoblin/base.html:46
+#: mediagoblin/templates/mediagoblin/base.html:47
msgid "MediaGoblin logo"
msgstr "MediaGoblin"
-#: mediagoblin/templates/mediagoblin/base.html:51
-#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
-msgid "Add media"
-msgstr "Legg til mediefiler"
-
-#: mediagoblin/templates/mediagoblin/base.html:62
+#: mediagoblin/templates/mediagoblin/base.html:57
msgid "Verify your email!"
msgstr ""
-#: mediagoblin/templates/mediagoblin/base.html:69
-msgid "log out"
+#: mediagoblin/templates/mediagoblin/base.html:63
+msgid "+ Add media"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:65
+msgid "View your profile"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:66
+msgid "Log out"
msgstr ""
-#: mediagoblin/templates/mediagoblin/base.html:72
-#: mediagoblin/templates/mediagoblin/auth/login.html:27
-#: mediagoblin/templates/mediagoblin/auth/login.html:45
+#: mediagoblin/templates/mediagoblin/base.html:71
+#: mediagoblin/templates/mediagoblin/auth/login.html:32
+#: mediagoblin/templates/mediagoblin/auth/login.html:50
msgid "Log in"
msgstr "Logg inn"
-#: mediagoblin/templates/mediagoblin/base.html:84
+#: mediagoblin/templates/mediagoblin/base.html:85
msgid ""
"Powered by <a href=\"http://mediagoblin.org\">MediaGoblin</a>, a <a "
-"href=\"http://gnu.org/\">GNU</a> project"
+"href=\"http://gnu.org/\">GNU</a> project."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:88
+#, python-format
+msgid ""
+"Released under the <a "
+"href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a "
+"href=\"%(source_link)s\">Source code</a> available."
msgstr ""
-"Drive av <a href=\"http://mediagoblin.org\">MediaGoblin</a>, eit <a "
-"href=\"http://gnu.org/\">GNU</a>-prosjekt"
#: mediagoblin/templates/mediagoblin/root.html:24
msgid "Explore"
@@ -312,28 +326,21 @@ msgid ""
"\n"
"If you think this is an error, just ignore this email and continue being\n"
"a happy goblin!"
-msgstr ""
-"Hei %(username)s,\n"
-"\n"
-"for å endra MediaGoblin-passordet ditt, opna fylgjande URL i ein netlesar:\n"
-"\n"
-" <%(verification_url)s>\n"
-"\n"
-"Dersom du mistenkjer dette er eit misstak, ignorer eposten og hald fram med å vera ein glad goblin!"
+msgstr "Hei %(username)s,\n\nfor å endra MediaGoblin-passordet ditt, opna fylgjande URL i ein netlesar:\n\n <%(verification_url)s>\n\nDersom du mistenkjer dette er eit misstak, ignorer eposten og hald fram med å vera ein glad goblin!"
-#: mediagoblin/templates/mediagoblin/auth/login.html:30
+#: mediagoblin/templates/mediagoblin/auth/login.html:35
msgid "Logging in failed!"
msgstr "Innlogging feila"
-#: mediagoblin/templates/mediagoblin/auth/login.html:35
+#: mediagoblin/templates/mediagoblin/auth/login.html:40
msgid "Don't have an account yet?"
msgstr "Har du ingen konto?"
-#: mediagoblin/templates/mediagoblin/auth/login.html:36
+#: mediagoblin/templates/mediagoblin/auth/login.html:41
msgid "Create one here!"
msgstr "Lag ein!"
-#: mediagoblin/templates/mediagoblin/auth/login.html:42
+#: mediagoblin/templates/mediagoblin/auth/login.html:47
msgid "Forgot your password?"
msgstr "Gløymd passordet?"
@@ -354,12 +361,7 @@ msgid ""
"your web browser:\n"
"\n"
"%(verification_url)s"
-msgstr ""
-"Hei %(username)s,\n"
-"\n"
-"opna fylgjande netadresse i netlesaren din for å aktivera kontoen din:\n"
-"\n"
-"%(verification_url)s"
+msgstr "Hei %(username)s,\n\nopna fylgjande netadresse i netlesaren din for å aktivera kontoen din:\n\n%(verification_url)s"
#: mediagoblin/templates/mediagoblin/edit/edit.html:29
#, python-format
@@ -394,18 +396,44 @@ msgid "Media tagged with: %(tag_name)s"
msgstr ""
#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:46
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:53
msgid "Original"
msgstr ""
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:33
+#: 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 <a href=\"http://getfirefox.com\">\n"
+"\t http://getfirefox.com</a>!"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:56
+msgid "Download"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:60
+msgid "original file"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:63
+msgid "WebM file (Vorbis codec)"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:40
msgid ""
"Sorry, this video will not work because \n"
"\t your web browser does not support HTML5 \n"
"\t video."
msgstr ""
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:36
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:43
msgid ""
"You can get a modern web browser that \n"
"\t can play this video at <a href=\"http://getfirefox.com\">\n"
@@ -430,55 +458,49 @@ msgstr ""
msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media"
msgstr "<a href=\"%(user_url)s\">%(username)s</a> sine mediefiler"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:72
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:46
#, python-format
-msgid "Added on %(date)s."
-msgstr ""
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:81
-msgid "Edit"
+msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:85
-msgid "Delete"
-msgstr ""
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:67
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:73
#, python-format
-msgid "%(comment_count)s comment"
+msgid "Image for %(media_title)s"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:93
-#, python-format
-msgid "%(comment_count)s comments"
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:87
+msgid "Edit"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:95
-msgid "No comments yet."
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
+msgid "Delete"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:103
-msgid "Add one"
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:124
+msgid "Add a comment"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:112
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:131
msgid ""
"You can use <a "
"href=\"http://daringfireball.net/projects/markdown/basics\">Markdown</a> for"
" formatting."
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:116
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:135
msgid "Add this comment"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:138
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:154
msgid "at"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:153
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:174
#, python-format
-msgid "<p>â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a></p>"
+msgid ""
+"<h3>Added on</h3>\n"
+" <p>%(date)s</p>"
msgstr ""
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30
@@ -487,8 +509,8 @@ msgid "Really delete %(title)s?"
msgstr "Vil du verkeleg sletta %(title)s?"
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:50
-msgid "Delete Permanently"
-msgstr "Slett permament"
+msgid "Delete permanently"
+msgstr ""
#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:22
msgid "Media processing panel"
@@ -554,9 +576,7 @@ msgstr "Dette brukarnamnet finst allereie, men det er ikkje aktivert."
msgid ""
"If you are that person but you've lost your verification email, you can <a "
"href=\"%(login_url)s\">log in</a> and resend it."
-msgstr ""
-"Viss dette er deg, kan du <a href=\"%(login_url)s\">logga inn</a> for å få "
-"tilsendt ny epost med stadfestingslenkje."
+msgstr "Viss dette er deg, kan du <a href=\"%(login_url)s\">logga inn</a> for å få tilsendt ny epost med stadfestingslenkje."
#: mediagoblin/templates/mediagoblin/user_pages/user.html:96
msgid "Here's a spot to tell others about yourself."
@@ -586,6 +606,10 @@ msgid ""
"anything yet."
msgstr "Her kjem mediefilene dine."
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
+msgid "Add media"
+msgstr "Legg til mediefiler"
+
#: mediagoblin/templates/mediagoblin/user_pages/user.html:163
#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72
msgid "There doesn't seem to be any media here yet..."
@@ -599,8 +623,13 @@ msgstr " "
msgid "Atom feed"
msgstr "Atom-kjelde"
-#: mediagoblin/templates/mediagoblin/utils/license.html:21
-msgid "License:"
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:25
+msgid "Location"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:38
+#, python-format
+msgid "View on <a href=\"%(osm_url)s\">OpenStreetMap</a>"
msgstr ""
#: mediagoblin/templates/mediagoblin/utils/license.html:25
@@ -619,25 +648,21 @@ msgstr ""
msgid "Go to page:"
msgstr ""
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:27
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:32
+#: 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:38
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:43
+#: 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 "View more media tagged with"
+msgid "Tagged with"
msgstr ""
-#: mediagoblin/templates/mediagoblin/utils/tags.html:25
-msgid "or"
-msgstr ""
-
-#: mediagoblin/tools/exif.py:68
+#: mediagoblin/tools/exif.py:75
msgid "Could not read the image file."
msgstr ""
@@ -645,25 +670,22 @@ msgstr ""
msgid "I am sure I want to delete this"
msgstr "Eg er sikker eg vil sletta dette"
-#: mediagoblin/user_pages/views.py:155
+#: mediagoblin/user_pages/views.py:153
msgid "Oops, your comment was empty."
msgstr ""
-#: mediagoblin/user_pages/views.py:161
+#: mediagoblin/user_pages/views.py:159
msgid "Your comment has been posted!"
msgstr ""
-#: mediagoblin/user_pages/views.py:183
+#: mediagoblin/user_pages/views.py:185
msgid "You deleted the media."
msgstr ""
-#: mediagoblin/user_pages/views.py:190
+#: mediagoblin/user_pages/views.py:192
msgid "The media was not deleted because you didn't check that you were sure."
msgstr ""
-#: mediagoblin/user_pages/views.py:198
+#: mediagoblin/user_pages/views.py:200
msgid "You are about to delete another user's media. Proceed with caution."
-msgstr ""
-"Du er i ferd med å sletta ein annan brukar sine mediefiler. Trå varsamt."
-
-
+msgstr "Du er i ferd med å sletta ein annan brukar sine mediefiler. Trå varsamt."
diff --git a/mediagoblin/i18n/pl/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/pl/LC_MESSAGES/mediagoblin.mo
new file mode 100644
index 00000000..71199d74
--- /dev/null
+++ b/mediagoblin/i18n/pl/LC_MESSAGES/mediagoblin.mo
Binary files differ
diff --git a/mediagoblin/i18n/pl/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/pl/LC_MESSAGES/mediagoblin.po
new file mode 100644
index 00000000..f527df7c
--- /dev/null
+++ b/mediagoblin/i18n/pl/LC_MESSAGES/mediagoblin.po
@@ -0,0 +1,691 @@
+# Translations template for PROJECT.
+# Copyright (C) 2012 ORGANIZATION
+# This file is distributed under the same license as the PROJECT project.
+#
+# Translators:
+# Daniel Koć <kocio@aster.pl>, 2012.
+msgid ""
+msgstr ""
+"Project-Id-Version: GNU MediaGoblin\n"
+"Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n"
+"POT-Creation-Date: 2012-06-01 16:32-0500\n"
+"PO-Revision-Date: 2012-06-01 21:30+0000\n"
+"Last-Translator: cwebber <cwebber@dustycloud.org>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 0.9.6\n"
+"Language: pl\n"
+"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n"
+
+#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41
+msgid "Username"
+msgstr "Użytkownik"
+
+#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45
+msgid "Password"
+msgstr "Hasło"
+
+#: mediagoblin/auth/forms.py:34
+msgid "Email address"
+msgstr "Adres e-mail"
+
+#: mediagoblin/auth/forms.py:51
+msgid "Username or email"
+msgstr "Użytkownik lub adres e-mail"
+
+#: mediagoblin/auth/forms.py:58
+msgid "Incorrect input"
+msgstr "Nieprawidłowe dane"
+
+#: mediagoblin/auth/views.py:55
+msgid "Sorry, registration is disabled on this instance."
+msgstr "Niestety rejestracja w tym serwisie jest wyłączona."
+
+#: mediagoblin/auth/views.py:75
+msgid "Sorry, a user with that name already exists."
+msgstr "Niestety użytkownik o takiej nazwie już istnieje."
+
+#: mediagoblin/auth/views.py:79
+msgid "Sorry, a user with that email address already exists."
+msgstr "Niestety użytkownik z tym adresem e-mail już istnieje."
+
+#: mediagoblin/auth/views.py:182
+msgid ""
+"Your email address has been verified. You may now login, edit your profile, "
+"and submit images!"
+msgstr "Twój adres e-mail został zweryfikowany. Możesz się teraz zalogować, wypełnić opis swojego profilu i wysyłać grafiki!"
+
+#: mediagoblin/auth/views.py:188
+msgid "The verification key or user id is incorrect"
+msgstr "Nieprawidłowy klucz weryfikacji lub identyfikator użytkownika."
+
+#: mediagoblin/auth/views.py:206
+msgid "You must be logged in so we know who to send the email to!"
+msgstr "Musisz się zalogować żebyśmy wiedzieli do kogo wysłać e-mail!"
+
+#: mediagoblin/auth/views.py:214
+msgid "You've already verified your email address!"
+msgstr "Twój adres e-mail już został zweryfikowany!"
+
+#: mediagoblin/auth/views.py:227
+msgid "Resent your verification email."
+msgstr "Wyślij ponownie e-mail weryfikujący."
+
+#: mediagoblin/auth/views.py:263
+msgid ""
+"An email has been sent with instructions on how to change your password."
+msgstr "Wysłano e-mail z instrukcjami jak zmienić hasło."
+
+#: mediagoblin/auth/views.py:273
+msgid ""
+"Could not send password recovery email as your username is inactive or your "
+"account's email address has not been verified."
+msgstr "Nie udało się wysłać e-maila w celu odzyskania hasła, ponieważ twoje konto jest nieaktywne lub twój adres e-mail nie został zweryfikowany."
+
+#: mediagoblin/auth/views.py:285
+msgid "Couldn't find someone with that username or email."
+msgstr "Nie znaleziono nikogo o takiej nazwie użytkownika lub adresie e-mail."
+
+#: mediagoblin/auth/views.py:333
+msgid "You can now log in using your new password."
+msgstr "Teraz możesz się zalogować używając nowe hasło."
+
+#: mediagoblin/edit/forms.py:25 mediagoblin/submit/forms.py:28
+msgid "Title"
+msgstr "Tytuł"
+
+#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:31
+msgid "Description of this work"
+msgstr "Opis tej pracy"
+
+#: mediagoblin/edit/forms.py:29 mediagoblin/edit/forms.py:52
+#: mediagoblin/submit/forms.py:32
+msgid ""
+"You can use\n"
+" <a href=\"http://daringfireball.net/projects/markdown/basics\">\n"
+" Markdown</a> for formatting."
+msgstr "Możesz formatować tekst za pomocą składni \n <a href=\"http://daringfireball.net/projects/markdown/basics\">\n Markdown</a>."
+
+#: mediagoblin/edit/forms.py:33 mediagoblin/submit/forms.py:36
+msgid "Tags"
+msgstr "Znaczniki"
+
+#: mediagoblin/edit/forms.py:35 mediagoblin/submit/forms.py:38
+msgid "Separate tags by commas."
+msgstr "Rozdzielaj znaczniki przecinkami."
+
+#: mediagoblin/edit/forms.py:38
+msgid "Slug"
+msgstr "Slug"
+
+#: mediagoblin/edit/forms.py:39
+msgid "The slug can't be empty"
+msgstr "Slug nie może być pusty"
+
+#: mediagoblin/edit/forms.py:40
+msgid ""
+"The title part of this media's address. You usually don't need to change "
+"this."
+msgstr "Fragment adresu mediów zawierający tytuł. Zwykle nie ma potrzeby aby go zmieniać."
+
+#: mediagoblin/edit/forms.py:44 mediagoblin/submit/forms.py:41
+#: mediagoblin/templates/mediagoblin/utils/license.html:20
+msgid "License"
+msgstr "Licencja"
+
+#: mediagoblin/edit/forms.py:50
+msgid "Bio"
+msgstr "Biogram"
+
+#: mediagoblin/edit/forms.py:56
+msgid "Website"
+msgstr "Strona internetowa"
+
+#: mediagoblin/edit/forms.py:58
+msgid "This address contains errors"
+msgstr "Ten adres zawiera błędy"
+
+#: mediagoblin/edit/forms.py:63
+msgid "Old password"
+msgstr "Stare hasło"
+
+#: mediagoblin/edit/forms.py:65
+msgid "Enter your old password to prove you own this account."
+msgstr "Wprowadź swoje stare hasło aby udowodnić, że to twoje konto."
+
+#: mediagoblin/edit/forms.py:68
+msgid "New password"
+msgstr "Nowe hasło"
+
+#: mediagoblin/edit/views.py:67
+msgid "An entry with that slug already exists for this user."
+msgstr "Adres z tym slugiem dla tego użytkownika już istnieje."
+
+#: mediagoblin/edit/views.py:88
+msgid "You are editing another user's media. Proceed with caution."
+msgstr "Edytujesz media innego użytkownika. Zachowaj ostrożność."
+
+#: mediagoblin/edit/views.py:158
+msgid "You are editing a user's profile. Proceed with caution."
+msgstr "Edytujesz profil innego użytkownika. Zachowaj ostrożność."
+
+#: mediagoblin/edit/views.py:174
+msgid "Profile changes saved"
+msgstr "Zapisano zmiany profilu"
+
+#: mediagoblin/edit/views.py:200
+msgid "Wrong password"
+msgstr "Nieprawidłowe hasło"
+
+#: mediagoblin/edit/views.py:216
+msgid "Account settings saved"
+msgstr "Zapisano ustawienia konta"
+
+#: mediagoblin/media_types/__init__.py:60
+#: mediagoblin/media_types/__init__.py:120
+msgid "Sorry, I don't support that file type :("
+msgstr "NIestety, nie obsługujemy tego typu plików :-("
+
+#: mediagoblin/processing/__init__.py:127
+msgid "Invalid file given for media type."
+msgstr "Niewłaściwy plik dla tego rodzaju mediów."
+
+#: mediagoblin/submit/forms.py:26
+msgid "File"
+msgstr "Plik"
+
+#: mediagoblin/submit/views.py:56
+msgid "You must provide a file."
+msgstr "Musisz podać plik."
+
+#: mediagoblin/submit/views.py:163
+msgid "Woohoo! Submitted!"
+msgstr "Hura! Wysłano!"
+
+#: mediagoblin/templates/mediagoblin/404.html:22
+msgid "Image of 404 goblin stressing out"
+msgstr "Grafika zestresowanego goblina 404."
+
+#: mediagoblin/templates/mediagoblin/404.html:23
+msgid "Oops!"
+msgstr "Ups!"
+
+#: mediagoblin/templates/mediagoblin/404.html:24
+msgid "There doesn't seem to be a page at this address. Sorry!"
+msgstr "Niestety, nie ma strony o takim adresie!"
+
+#: mediagoblin/templates/mediagoblin/404.html:26
+msgid ""
+"If you're sure the address is correct, maybe the page you're looking for has"
+" been moved or deleted."
+msgstr "Jeśli twoim zdaniem ten adres jest prawidłowy, to może poszukiwana strona została przeniesiona lub usunięta."
+
+#: mediagoblin/templates/mediagoblin/base.html:47
+msgid "MediaGoblin logo"
+msgstr "Logo MediaGoblin"
+
+#: mediagoblin/templates/mediagoblin/base.html:57
+msgid "Verify your email!"
+msgstr "Zweryfikuj swój adres e-mail!"
+
+#: mediagoblin/templates/mediagoblin/base.html:63
+msgid "+ Add media"
+msgstr "+ Dodaj media"
+
+#: mediagoblin/templates/mediagoblin/base.html:65
+msgid "View your profile"
+msgstr "Zobacz swój profil"
+
+#: mediagoblin/templates/mediagoblin/base.html:66
+msgid "Log out"
+msgstr "Wyloguj siÄ™"
+
+#: mediagoblin/templates/mediagoblin/base.html:71
+#: mediagoblin/templates/mediagoblin/auth/login.html:32
+#: mediagoblin/templates/mediagoblin/auth/login.html:50
+msgid "Log in"
+msgstr "Zaloguj siÄ™"
+
+#: mediagoblin/templates/mediagoblin/base.html:85
+msgid ""
+"Powered by <a href=\"http://mediagoblin.org\">MediaGoblin</a>, a <a "
+"href=\"http://gnu.org/\">GNU</a> project."
+msgstr "Obsługiwane przez <a href=\"http://mediagoblin.org\">MediaGoblin</a>, projekt <a href=\"http://gnu.org/\">GNU</a>."
+
+#: mediagoblin/templates/mediagoblin/base.html:88
+#, python-format
+msgid ""
+"Released under the <a "
+"href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a "
+"href=\"%(source_link)s\">Source code</a> available."
+msgstr "Opublikowane na licencji <a href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. Dostępny jest <a href=\"%(source_link)s\">kod źródłowy</a>."
+
+#: mediagoblin/templates/mediagoblin/root.html:24
+msgid "Explore"
+msgstr "Odkrywaj"
+
+#: mediagoblin/templates/mediagoblin/root.html:26
+msgid "Hi there, welcome to this MediaGoblin site!"
+msgstr "Cześć, witaj na stronie MediaGoblin!"
+
+#: mediagoblin/templates/mediagoblin/root.html:28
+msgid ""
+"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, an "
+"extraordinarily great piece of media hosting software."
+msgstr "Ten serwis działa w oparciu o <a href=\"http://mediagoblin.org\">MediaGoblin</a>, świetne oprogramowanie do publikowania mediów."
+
+#: mediagoblin/templates/mediagoblin/root.html:29
+msgid ""
+"To add your own media, place comments, save your favourites and more, you "
+"can log in with your MediaGoblin account."
+msgstr "Możesz się zalogować na swoje konto MediaGoblin aby publikować swoje media, komentować, oznaczać ulubione i o wiele więcej."
+
+#: mediagoblin/templates/mediagoblin/root.html:31
+msgid "Don't have one yet? It's easy!"
+msgstr "Jeszcze go nie masz? To proste!"
+
+#: mediagoblin/templates/mediagoblin/root.html:32
+#, python-format
+msgid ""
+"<a class=\"button_action_highlight\" href=\"%(register_url)s\">Create an account at this site</a>\n"
+" or\n"
+" <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">Set up MediaGoblin on your own server</a>"
+msgstr "<a class=\"button_action_highlight\" href=\"%(register_url)s\">Utwórz konto w tym serwisie</a>\n lub\n <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">załóż własny serwis MediaGoblin</a>"
+
+#: mediagoblin/templates/mediagoblin/root.html:40
+msgid "Most recent media"
+msgstr "Najnowsze media"
+
+#: mediagoblin/templates/mediagoblin/auth/change_fp.html:32
+msgid "Set your new password"
+msgstr "Podaj swoje nowe hasło"
+
+#: mediagoblin/templates/mediagoblin/auth/change_fp.html:35
+msgid "Set password"
+msgstr "Podaj hasło"
+
+#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27
+msgid "Recover password"
+msgstr "Odtwórz hasło"
+
+#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:30
+msgid "Send instructions"
+msgstr "Wyślij instrukcje"
+
+#: 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 "Cześć %(username)s,\n\naby zmienić twoje hasło dla GNU MediaGoblin, otwórz następującą stronę w swojej przeglądarce:\n\n%(verification_url)s\n\nJeśli sądzisz, że to pomyłka, po prostu zignoruj tę wiadomość i bądź nadal szczęśliwym goblinem!"
+
+#: mediagoblin/templates/mediagoblin/auth/login.html:35
+msgid "Logging in failed!"
+msgstr "Logowanie nie powiodło się!"
+
+#: mediagoblin/templates/mediagoblin/auth/login.html:40
+msgid "Don't have an account yet?"
+msgstr "Nie masz jeszcze konta?"
+
+#: mediagoblin/templates/mediagoblin/auth/login.html:41
+msgid "Create one here!"
+msgstr "Utwórz je tutaj!"
+
+#: mediagoblin/templates/mediagoblin/auth/login.html:47
+msgid "Forgot your password?"
+msgstr "Zapomniałeś hasła?"
+
+#: mediagoblin/templates/mediagoblin/auth/register.html:32
+msgid "Create an account!"
+msgstr "Utwórz konto!"
+
+#: mediagoblin/templates/mediagoblin/auth/register.html:36
+msgid "Create"
+msgstr "Utwórz"
+
+#: 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 "Cześć %(username)s,\n\naby aktywować twoje konto GNU MediaGoblin, otwórz następującą stronę w swojej przeglądarce:\n\n%(verification_url)s"
+
+#: mediagoblin/templates/mediagoblin/edit/edit.html:29
+#, python-format
+msgid "Editing %(media_title)s"
+msgstr "Edytowanie %(media_title)s"
+
+#: mediagoblin/templates/mediagoblin/edit/edit.html:36
+#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49
+msgid "Cancel"
+msgstr "Anuluj"
+
+#: mediagoblin/templates/mediagoblin/edit/edit.html:37
+#: mediagoblin/templates/mediagoblin/edit/edit_account.html:40
+#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:35
+msgid "Save changes"
+msgstr "Zapisz zmiany"
+
+#: mediagoblin/templates/mediagoblin/edit/edit_account.html:34
+#, python-format
+msgid "Changing %(username)s's account settings"
+msgstr "Zmiana ustawień konta %(username)s"
+
+#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29
+#, python-format
+msgid "Editing %(username)s's profile"
+msgstr "Edycja profilu %(username)s"
+
+#: mediagoblin/templates/mediagoblin/listings/tag.html:30
+#: mediagoblin/templates/mediagoblin/listings/tag.html:35
+#, python-format
+msgid "Media tagged with: %(tag_name)s"
+msgstr "Media ze znacznikami: %(tag_name)s"
+
+#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:53
+msgid "Original"
+msgstr "Oryginał"
+
+#: 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 "Niestety, ten plik dźwiękowy nie zostanie odtworzony, \n\tponieważ ta przeglądarka nie obsługuje znaczników \n\tdźwięku w HTML5."
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:47
+msgid ""
+"You can get a modern web browser that \n"
+"\tcan play the audio at <a href=\"http://getfirefox.com\">\n"
+"\t http://getfirefox.com</a>!"
+msgstr "Proszę pobrać przeglądarkę, która obsługuje \n\tdźwięk w HTML5, pod adresem <a href=\"http://getfirefox.com\">\n\t http://getfirefox.com</a>!"
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:56
+msgid "Download"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:60
+msgid "original file"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:63
+msgid "WebM file (Vorbis codec)"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:40
+msgid ""
+"Sorry, this video will not work because \n"
+"\t your web browser does not support HTML5 \n"
+"\t video."
+msgstr "Niestety nie można wyświetlić tego filmu, ponieważ\n\t twoja przeglądarka nie obsługuje filmów \n\t HTML5."
+
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:43
+msgid ""
+"You can get a modern web browser that \n"
+"\t can play this video at <a href=\"http://getfirefox.com\">\n"
+"\t http://getfirefox.com</a>!"
+msgstr "Możesz pobrać współczesną przeglądarkę, która obsługuje \n\t takie filmy, pod adresem <a href=\"http://getfirefox.com\">\n\t http://getfirefox.com</a>!"
+
+#: mediagoblin/templates/mediagoblin/submit/start.html:26
+msgid "Add your media"
+msgstr "Dodaj swoje media"
+
+#: mediagoblin/templates/mediagoblin/submit/start.html:30
+msgid "Add"
+msgstr "Dodaj"
+
+#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30
+#, python-format
+msgid "%(username)s's media"
+msgstr "Media użytkownika %(username)s"
+
+#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:37
+#, python-format
+msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media"
+msgstr "media użytkownika <a href=\"%(user_url)s\">%(username)s</a>"
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:46
+#, python-format
+msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>"
+msgstr "■Przeglądanie mediów użytkownika <a href=\"%(user_url)s\">%(username)s</a>"
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:67
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:73
+#, python-format
+msgid "Image for %(media_title)s"
+msgstr "Grafika dla %(media_title)s"
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:87
+msgid "Edit"
+msgstr "Edytuj"
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
+msgid "Delete"
+msgstr "Usuń"
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:124
+msgid "Add a comment"
+msgstr "Dodaj komentarz"
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:131
+msgid ""
+"You can use <a "
+"href=\"http://daringfireball.net/projects/markdown/basics\">Markdown</a> for"
+" formatting."
+msgstr "Możesz formatować przy pomocy składni <a href=\"http://daringfireball.net/projects/markdown/basics\">Markdown</a>."
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:135
+msgid "Add this comment"
+msgstr "Dodaj komentarz"
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:154
+msgid "at"
+msgstr "na"
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:174
+#, python-format
+msgid ""
+"<h3>Added on</h3>\n"
+" <p>%(date)s</p>"
+msgstr "<h3>Dodane</h3>\n <p>%(date)s</p>"
+
+#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30
+#, python-format
+msgid "Really delete %(title)s?"
+msgstr "Na pewno usunąć %(title)s?"
+
+#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:50
+msgid "Delete permanently"
+msgstr "Usuń na stałe"
+
+#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:22
+msgid "Media processing panel"
+msgstr "Panel przetwarzania mediów"
+
+#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:25
+msgid ""
+"You can track the state of media being processed for your gallery here."
+msgstr "Tutaj możesz śledzić stan mediów przesyłanych do twojej galerii."
+
+#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:28
+msgid "Media in-processing"
+msgstr "Przetwarzane media"
+
+#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:46
+msgid "No media in-processing"
+msgstr "Żadne media nie są obecnie przetwarzane"
+
+#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:50
+msgid "These uploads failed to process:"
+msgstr "NIe udało się przesłać tych plików:"
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:31
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:89
+#, python-format
+msgid "%(username)s's profile"
+msgstr "Profil użytkownika %(username)s"
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:43
+msgid "Sorry, no such user found."
+msgstr "Niestety, nie znaleziono takiego użytkownika."
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:50
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:70
+msgid "Email verification needed"
+msgstr "Wymagana weryfikacja adresu e-mail."
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:53
+msgid "Almost done! Your account still needs to be activated."
+msgstr "Prawie gotowe! Twoje konto oczekuje na aktywacjÄ™."
+
+#: 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 "Za kilka chwil powinieneś otrzymać e-mail z instrukcjami jak to zrobić."
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:62
+msgid "In case it doesn't:"
+msgstr "Jeśli nie nadejdzie:"
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:65
+msgid "Resend verification email"
+msgstr "Wyślij ponownie e-mail weryfikujący"
+
+#: 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 "Ktoś zarejestrował konto o tej nazwie, ale nadal oczekuje ono na aktywację."
+
+#: 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 <a "
+"href=\"%(login_url)s\">log in</a> and resend it."
+msgstr "Jeśli jesteś tą osobą, ale zgubiłeś swój e-mail weryfikujący, to możesz się <a href=\"%(login_url)s\">zalogować</a> i wysłać go ponownie."
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:96
+msgid "Here's a spot to tell others about yourself."
+msgstr "W tym miejscu można się przedstawić innym."
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:101
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:118
+msgid "Edit profile"
+msgstr "Edytuj profil"
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:106
+msgid "This user hasn't filled in their profile (yet)."
+msgstr "Ten użytkownik nie wypełnił (jeszcze) opisu swojego profilu."
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:125
+msgid "Change account settings"
+msgstr "Zmień ustawienia konta"
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:138
+#, python-format
+msgid "View all of %(username)s's media"
+msgstr "Zobacz wszystkie media użytkownika %(username)s"
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:151
+msgid ""
+"This is where your media will appear, but you don't seem to have added "
+"anything yet."
+msgstr "Tu będą widoczne twoje media, ale na razie niczego tu jeszcze nie ma."
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
+msgid "Add media"
+msgstr "Dodaj media"
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:163
+#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72
+msgid "There doesn't seem to be any media here yet..."
+msgstr "Tu nie ma jeszcze żadnych mediów..."
+
+#: mediagoblin/templates/mediagoblin/utils/feed_link.html:21
+msgid "feed icon"
+msgstr "ikona kanału"
+
+#: mediagoblin/templates/mediagoblin/utils/feed_link.html:23
+msgid "Atom feed"
+msgstr "Kanał Atom"
+
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:25
+msgid "Location"
+msgstr "Położenie"
+
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:38
+#, python-format
+msgid "View on <a href=\"%(osm_url)s\">OpenStreetMap</a>"
+msgstr "Zobacz na <a href=\"%(osm_url)s\">OpenStreetMap</a>"
+
+#: mediagoblin/templates/mediagoblin/utils/license.html:25
+msgid "All rights reserved"
+msgstr "Wszystkie prawa zastrzeżone"
+
+#: mediagoblin/templates/mediagoblin/utils/pagination.html:39
+msgid "↠Newer"
+msgstr "↠Nowsze"
+
+#: mediagoblin/templates/mediagoblin/utils/pagination.html:45
+msgid "Older →"
+msgstr "Starsze →"
+
+#: mediagoblin/templates/mediagoblin/utils/pagination.html:48
+msgid "Go to page:"
+msgstr "Idź do strony:"
+
+#: mediagoblin/templates/mediagoblin/utils/prev_next.html:28
+#: mediagoblin/templates/mediagoblin/utils/prev_next.html:33
+msgid "newer"
+msgstr "nowsze"
+
+#: mediagoblin/templates/mediagoblin/utils/prev_next.html:39
+#: mediagoblin/templates/mediagoblin/utils/prev_next.html:44
+msgid "older"
+msgstr "starsze"
+
+#: mediagoblin/templates/mediagoblin/utils/tags.html:20
+msgid "Tagged with"
+msgstr "Znaczniki:"
+
+#: mediagoblin/tools/exif.py:75
+msgid "Could not read the image file."
+msgstr "Nie udało się odczytać pliku grafiki."
+
+#: mediagoblin/user_pages/forms.py:30
+msgid "I am sure I want to delete this"
+msgstr "Na pewno chcę to usunąć"
+
+#: mediagoblin/user_pages/views.py:153
+msgid "Oops, your comment was empty."
+msgstr "Ups, twój komentarz nie zawierał treści."
+
+#: mediagoblin/user_pages/views.py:159
+msgid "Your comment has been posted!"
+msgstr "Twój komentarz został opublikowany!"
+
+#: mediagoblin/user_pages/views.py:185
+msgid "You deleted the media."
+msgstr "Media zostały usunięte."
+
+#: mediagoblin/user_pages/views.py:192
+msgid "The media was not deleted because you didn't check that you were sure."
+msgstr "Media nie zostały usunięte ponieważ nie potwierdziłeś, że jesteś pewien."
+
+#: mediagoblin/user_pages/views.py:200
+msgid "You are about to delete another user's media. Proceed with caution."
+msgstr "Za chwilę usuniesz media innego użytkownika. Zachowaj ostrożność."
diff --git a/mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.mo
index 6d2e6fc6..5b9b9b0c 100644
--- a/mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.mo
+++ b/mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.mo
Binary files differ
diff --git a/mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.po
index 14c54fb3..53bc1725 100644
--- a/mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.po
+++ b/mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.po
@@ -8,11 +8,11 @@
msgid ""
msgstr ""
"Project-Id-Version: GNU MediaGoblin\n"
-"Report-Msgid-Bugs-To: http://bugs.foocorp.net/projects/mediagoblin/issues\n"
-"POT-Creation-Date: 2012-01-29 13:31-0600\n"
-"PO-Revision-Date: 2012-01-29 19:29+0000\n"
+"Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n"
+"POT-Creation-Date: 2012-06-01 16:32-0500\n"
+"PO-Revision-Date: 2012-06-01 21:30+0000\n"
"Last-Translator: cwebber <cwebber@dustycloud.org>\n"
-"Language-Team: Portuguese (Brazil) (http://www.transifex.net/projects/p/mediagoblin/team/pt_BR/)\n"
+"Language-Team: Portuguese (Brazil) (http://www.transifex.net/projects/p/mediagoblin/language/pt_BR/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -20,10 +20,6 @@ msgstr ""
"Language: pt_BR\n"
"Plural-Forms: nplurals=2; plural=(n > 1)\n"
-#: mediagoblin/processing.py:143
-msgid "Invalid file given for media type."
-msgstr "Arquivo inválido para esse tipo de mídia"
-
#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41
msgid "Username"
msgstr "Nome de Usuário"
@@ -36,60 +32,64 @@ msgstr "Senha"
msgid "Email address"
msgstr "Endereço de email"
+#: mediagoblin/auth/forms.py:51
+msgid "Username or email"
+msgstr ""
+
+#: mediagoblin/auth/forms.py:58
+msgid "Incorrect input"
+msgstr ""
+
#: mediagoblin/auth/views.py:55
msgid "Sorry, registration is disabled on this instance."
msgstr "Desculpa, o registro está desativado neste momento."
-#: mediagoblin/auth/views.py:73
+#: mediagoblin/auth/views.py:75
msgid "Sorry, a user with that name already exists."
msgstr "Desculpe, um usuário com este nome já existe."
-#: mediagoblin/auth/views.py:77
+#: mediagoblin/auth/views.py:79
msgid "Sorry, a user with that email address already exists."
msgstr "Desculpe, um usuário com esse email já esta cadastrado"
-#: mediagoblin/auth/views.py:180
+#: mediagoblin/auth/views.py:182
msgid ""
"Your email address has been verified. You may now login, edit your profile, "
"and submit images!"
-msgstr ""
-"O seu endereço de e-mail foi verificado. Você pode agora fazer login, editar"
-" seu perfil, e enviar imagens!"
+msgstr "O seu endereço de e-mail foi verificado. Você pode agora fazer login, editar seu perfil, e enviar imagens!"
-#: mediagoblin/auth/views.py:186
+#: mediagoblin/auth/views.py:188
msgid "The verification key or user id is incorrect"
msgstr "A chave de verificação ou nome usuário estão incorretos."
-#: mediagoblin/auth/views.py:204
+#: 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:212
+#: mediagoblin/auth/views.py:214
msgid "You've already verified your email address!"
msgstr "Você já verifico seu email!"
-#: mediagoblin/auth/views.py:225
+#: mediagoblin/auth/views.py:227
msgid "Resent your verification email."
msgstr "O email de verificação foi reenviado."
-#: mediagoblin/auth/views.py:260
+#: mediagoblin/auth/views.py:263
msgid ""
"An email has been sent with instructions on how to change your password."
msgstr ""
-#: mediagoblin/auth/views.py:270
+#: mediagoblin/auth/views.py:273
msgid ""
"Could not send password recovery email as your username is inactive or your "
"account's email address has not been verified."
-msgstr ""
-"Não foi possível enviar o email de recuperação de senha, pois seu nome de "
-"usuário está inativo ou o email da sua conta não foi confirmado."
+msgstr "Não foi possível enviar o email de recuperação de senha, pois seu nome de usuário está inativo ou o email da sua conta não foi confirmado."
-#: mediagoblin/auth/views.py:282
+#: mediagoblin/auth/views.py:285
msgid "Couldn't find someone with that username or email."
msgstr ""
-#: mediagoblin/auth/views.py:330
+#: mediagoblin/auth/views.py:333
msgid "You can now log in using your new password."
msgstr ""
@@ -132,6 +132,7 @@ msgid ""
msgstr ""
#: mediagoblin/edit/forms.py:44 mediagoblin/submit/forms.py:41
+#: mediagoblin/templates/mediagoblin/utils/license.html:20
msgid "License"
msgstr ""
@@ -143,6 +144,10 @@ msgstr "Biografia"
msgid "Website"
msgstr "Website"
+#: mediagoblin/edit/forms.py:58
+msgid "This address contains errors"
+msgstr ""
+
#: mediagoblin/edit/forms.py:63
msgid "Old password"
msgstr "Senha antiga"
@@ -155,47 +160,48 @@ msgstr ""
msgid "New password"
msgstr ""
-#: mediagoblin/edit/views.py:68
+#: mediagoblin/edit/views.py:67
msgid "An entry with that slug already exists for this user."
msgstr "Uma entrada com esse arquivo já existe para esse usuário"
-#: mediagoblin/edit/views.py:92
+#: mediagoblin/edit/views.py:88
msgid "You are editing another user's media. Proceed with caution."
msgstr "Você está editando a mídia de outro usuário. Tenha cuidado."
-#: mediagoblin/edit/views.py:162
+#: mediagoblin/edit/views.py:158
msgid "You are editing a user's profile. Proceed with caution."
msgstr "Você está editando um perfil de usuário. Tenha cuidado."
-#: mediagoblin/edit/views.py:180
+#: mediagoblin/edit/views.py:174
msgid "Profile changes saved"
msgstr ""
-#: mediagoblin/edit/views.py:206
+#: mediagoblin/edit/views.py:200
msgid "Wrong password"
msgstr "Senha errada"
-#: mediagoblin/edit/views.py:222
+#: mediagoblin/edit/views.py:216
msgid "Account settings saved"
msgstr ""
-#: mediagoblin/media_types/__init__.py:77
-msgid "Could not extract any file extension from \"{filename}\""
-msgstr ""
-
-#: mediagoblin/media_types/__init__.py:88
+#: mediagoblin/media_types/__init__.py:60
+#: mediagoblin/media_types/__init__.py:120
msgid "Sorry, I don't support that file type :("
msgstr ""
+#: mediagoblin/processing/__init__.py:127
+msgid "Invalid file given for media type."
+msgstr "Arquivo inválido para esse tipo de mídia"
+
#: mediagoblin/submit/forms.py:26
msgid "File"
msgstr "Arquivo"
-#: mediagoblin/submit/views.py:54
+#: mediagoblin/submit/views.py:56
msgid "You must provide a file."
msgstr "Você deve fornecer um arquivo."
-#: mediagoblin/submit/views.py:158
+#: mediagoblin/submit/views.py:163
msgid "Woohoo! Submitted!"
msgstr "Eba! Enviado!"
@@ -215,40 +221,47 @@ msgstr "Aparentemente não existe uma página com esse endereço. Desculpe!"
msgid ""
"If you're sure the address is correct, maybe the page you're looking for has"
" been moved or deleted."
-msgstr ""
-"Se você está certo de que o endereço está correto, talvez a página que "
-"esteja procurando tenha sido apagada ou mudou de endereço"
+msgstr "Se você está certo de que o endereço está correto, talvez a página que esteja procurando tenha sido apagada ou mudou de endereço"
-#: mediagoblin/templates/mediagoblin/base.html:46
+#: mediagoblin/templates/mediagoblin/base.html:47
msgid "MediaGoblin logo"
msgstr "Logo MediaGoblin"
-#: mediagoblin/templates/mediagoblin/base.html:51
-#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
-msgid "Add media"
-msgstr "Adicionar mídia"
-
-#: mediagoblin/templates/mediagoblin/base.html:62
+#: mediagoblin/templates/mediagoblin/base.html:57
msgid "Verify your email!"
msgstr "Verifique seu email!"
-#: mediagoblin/templates/mediagoblin/base.html:69
-msgid "log out"
-msgstr "Sair"
+#: mediagoblin/templates/mediagoblin/base.html:63
+msgid "+ Add media"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:65
+msgid "View your profile"
+msgstr ""
-#: mediagoblin/templates/mediagoblin/base.html:72
-#: mediagoblin/templates/mediagoblin/auth/login.html:27
-#: mediagoblin/templates/mediagoblin/auth/login.html:45
+#: mediagoblin/templates/mediagoblin/base.html:66
+msgid "Log out"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:71
+#: mediagoblin/templates/mediagoblin/auth/login.html:32
+#: mediagoblin/templates/mediagoblin/auth/login.html:50
msgid "Log in"
msgstr "Entrar"
-#: mediagoblin/templates/mediagoblin/base.html:84
+#: mediagoblin/templates/mediagoblin/base.html:85
msgid ""
"Powered by <a href=\"http://mediagoblin.org\">MediaGoblin</a>, a <a "
-"href=\"http://gnu.org/\">GNU</a> project"
+"href=\"http://gnu.org/\">GNU</a> project."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:88
+#, python-format
+msgid ""
+"Released under the <a "
+"href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a "
+"href=\"%(source_link)s\">Source code</a> available."
msgstr ""
-"Desenvolvido por <a href=\"http://mediagoblin.org\">MediaGoblin</a>, um "
-"projeto <a href=\"http://gnu.org/\">GNU</a>"
#: mediagoblin/templates/mediagoblin/root.html:24
msgid "Explore"
@@ -314,29 +327,21 @@ msgid ""
"\n"
"If you think this is an error, just ignore this email and continue being\n"
"a happy goblin!"
-msgstr ""
-"Olá %(username)s,\n"
-"\n"
-"para alterar sua senha do GNU MediaGoblin, abra a seguinte URL\n"
-"no seu navegador web:\n"
-"\n"
-"%(verification_url)s\n"
-"\n"
-"Se você acha que isso é um erro, desconsidere esse email e continue sendo um goblin feliz"
+msgstr "Olá %(username)s,\n\npara alterar sua senha do GNU MediaGoblin, abra a seguinte URL\nno seu navegador web:\n\n%(verification_url)s\n\nSe você acha que isso é um erro, desconsidere esse email e continue sendo um goblin feliz"
-#: mediagoblin/templates/mediagoblin/auth/login.html:30
+#: mediagoblin/templates/mediagoblin/auth/login.html:35
msgid "Logging in failed!"
msgstr "Autenticação falhou"
-#: mediagoblin/templates/mediagoblin/auth/login.html:35
+#: mediagoblin/templates/mediagoblin/auth/login.html:40
msgid "Don't have an account yet?"
msgstr "Ainda não tem conta?"
-#: mediagoblin/templates/mediagoblin/auth/login.html:36
+#: mediagoblin/templates/mediagoblin/auth/login.html:41
msgid "Create one here!"
msgstr "Crie uma aqui!"
-#: mediagoblin/templates/mediagoblin/auth/login.html:42
+#: mediagoblin/templates/mediagoblin/auth/login.html:47
msgid "Forgot your password?"
msgstr "Esqueceu sua senha?"
@@ -357,12 +362,7 @@ msgid ""
"your web browser:\n"
"\n"
"%(verification_url)s"
-msgstr ""
-"Olá %(username)s,\n"
-"\n"
-"Para ativar sua conta GNU MediaGoblin, visite este endereço no seu navegador:\n"
-"\n"
-"%(verification_url)s"
+msgstr "Olá %(username)s,\n\nPara ativar sua conta GNU MediaGoblin, visite este endereço no seu navegador:\n\n%(verification_url)s"
#: mediagoblin/templates/mediagoblin/edit/edit.html:29
#, python-format
@@ -397,18 +397,44 @@ msgid "Media tagged with: %(tag_name)s"
msgstr ""
#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:46
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:53
msgid "Original"
msgstr "Original"
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:33
+#: 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 <a href=\"http://getfirefox.com\">\n"
+"\t http://getfirefox.com</a>!"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:56
+msgid "Download"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:60
+msgid "original file"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:63
+msgid "WebM file (Vorbis codec)"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:40
msgid ""
"Sorry, this video will not work because \n"
"\t your web browser does not support HTML5 \n"
"\t video."
msgstr ""
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:36
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:43
msgid ""
"You can get a modern web browser that \n"
"\t can play this video at <a href=\"http://getfirefox.com\">\n"
@@ -433,55 +459,49 @@ msgstr ""
msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media"
msgstr "Mídia de <a href=\"%(user_url)s\"> %(username)s </a> "
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:72
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:46
#, python-format
-msgid "Added on %(date)s."
+msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:81
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:67
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:73
+#, python-format
+msgid "Image for %(media_title)s"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:87
msgid "Edit"
msgstr "Editar"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:85
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
msgid "Delete"
msgstr "Apagar"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
-#, python-format
-msgid "%(comment_count)s comment"
-msgstr ""
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:93
-#, python-format
-msgid "%(comment_count)s comments"
-msgstr ""
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:95
-msgid "No comments yet."
-msgstr ""
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:103
-msgid "Add one"
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:124
+msgid "Add a comment"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:112
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:131
msgid ""
"You can use <a "
"href=\"http://daringfireball.net/projects/markdown/basics\">Markdown</a> for"
" formatting."
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:116
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:135
msgid "Add this comment"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:138
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:154
msgid "at"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:153
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:174
#, python-format
-msgid "<p>â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a></p>"
+msgid ""
+"<h3>Added on</h3>\n"
+" <p>%(date)s</p>"
msgstr ""
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30
@@ -490,8 +510,8 @@ msgid "Really delete %(title)s?"
msgstr "Realmente apagar %(title)s ?"
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:50
-msgid "Delete Permanently"
-msgstr "Apagar permanentemente"
+msgid "Delete permanently"
+msgstr ""
#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:22
msgid "Media processing panel"
@@ -500,8 +520,7 @@ msgstr "Painel de processamento de mídia"
#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:25
msgid ""
"You can track the state of media being processed for your gallery here."
-msgstr ""
-"Você pode verificar como a mídia esta sendo processada para sua galeria aqui"
+msgstr "Você pode verificar como a mídia esta sendo processada para sua galeria aqui"
#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:28
msgid "Media in-processing"
@@ -551,18 +570,14 @@ msgstr "Reenviar email de verificação"
msgid ""
"Someone has registered an account with this username, but it still has to be"
" activated."
-msgstr ""
-"Alguém registrou uma conta com esse nome de usuário, mas ainda precisa ser "
-"ativada."
+msgstr "Alguém registrou uma conta com esse nome de usuário, mas ainda precisa ser ativada."
#: 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 <a "
"href=\"%(login_url)s\">log in</a> and resend it."
-msgstr ""
-"Se você é essa pessoa, mas você perdeu seu e-mail de verificação, você pode "
-"<a href=\"%(login_url)s\">efetuar login</a> e reenviá-la."
+msgstr "Se você é essa pessoa, mas você perdeu seu e-mail de verificação, você pode <a href=\"%(login_url)s\">efetuar login</a> e reenviá-la."
#: mediagoblin/templates/mediagoblin/user_pages/user.html:96
msgid "Here's a spot to tell others about yourself."
@@ -590,9 +605,11 @@ msgstr "Ver todas as mídias de %(username)s"
msgid ""
"This is where your media will appear, but you don't seem to have added "
"anything yet."
-msgstr ""
-"Aqui é onde sua mídia vai aparecer, mas parece que você não adicionou nada "
-"ainda."
+msgstr "Aqui é onde sua mídia vai aparecer, mas parece que você não adicionou nada ainda."
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
+msgid "Add media"
+msgstr "Adicionar mídia"
#: mediagoblin/templates/mediagoblin/user_pages/user.html:163
#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72
@@ -607,8 +624,13 @@ msgstr "ícone feed"
msgid "Atom feed"
msgstr "Atom feed"
-#: mediagoblin/templates/mediagoblin/utils/license.html:21
-msgid "License:"
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:25
+msgid "Location"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:38
+#, python-format
+msgid "View on <a href=\"%(osm_url)s\">OpenStreetMap</a>"
msgstr ""
#: mediagoblin/templates/mediagoblin/utils/license.html:25
@@ -627,25 +649,21 @@ msgstr ""
msgid "Go to page:"
msgstr "Ir a página:"
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:27
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:32
+#: 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:38
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:43
+#: 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 "View more media tagged with"
-msgstr ""
-
-#: mediagoblin/templates/mediagoblin/utils/tags.html:25
-msgid "or"
+msgid "Tagged with"
msgstr ""
-#: mediagoblin/tools/exif.py:68
+#: mediagoblin/tools/exif.py:75
msgid "Could not read the image file."
msgstr ""
@@ -653,24 +671,22 @@ msgstr ""
msgid "I am sure I want to delete this"
msgstr "Eu tenho certeza de que quero pagar isso"
-#: mediagoblin/user_pages/views.py:155
+#: mediagoblin/user_pages/views.py:153
msgid "Oops, your comment was empty."
msgstr "Opa, seu comentáio estava vazio."
-#: mediagoblin/user_pages/views.py:161
+#: mediagoblin/user_pages/views.py:159
msgid "Your comment has been posted!"
msgstr "Seu comentário foi postado!"
-#: mediagoblin/user_pages/views.py:183
+#: mediagoblin/user_pages/views.py:185
msgid "You deleted the media."
msgstr "Você deletou a mídia."
-#: mediagoblin/user_pages/views.py:190
+#: mediagoblin/user_pages/views.py:192
msgid "The media was not deleted because you didn't check that you were sure."
msgstr ""
-#: mediagoblin/user_pages/views.py:198
+#: mediagoblin/user_pages/views.py:200
msgid "You are about to delete another user's media. Proceed with caution."
msgstr "Você vai apagar uma mídia de outro usuário. Tenha cuidado."
-
-
diff --git a/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.mo
index 226474af..b1426042 100644
--- a/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.mo
+++ b/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.mo
Binary files differ
diff --git a/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.po
index 9139e59d..a347d4aa 100644
--- a/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.po
+++ b/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.po
@@ -8,11 +8,11 @@
msgid ""
msgstr ""
"Project-Id-Version: GNU MediaGoblin\n"
-"Report-Msgid-Bugs-To: http://bugs.foocorp.net/projects/mediagoblin/issues\n"
-"POT-Creation-Date: 2012-01-29 13:31-0600\n"
-"PO-Revision-Date: 2012-01-29 19:29+0000\n"
+"Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n"
+"POT-Creation-Date: 2012-06-01 16:32-0500\n"
+"PO-Revision-Date: 2012-06-01 21:30+0000\n"
"Last-Translator: cwebber <cwebber@dustycloud.org>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language-Team: Romanian (http://www.transifex.net/projects/p/mediagoblin/language/ro/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -20,10 +20,6 @@ msgstr ""
"Language: ro\n"
"Plural-Forms: nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1))\n"
-#: mediagoblin/processing.py:143
-msgid "Invalid file given for media type."
-msgstr "Formatul fișierului nu corespunde cu tipul de media selectat."
-
#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41
msgid "Username"
msgstr "Nume de utilizator"
@@ -36,61 +32,64 @@ msgstr "Parolă"
msgid "Email address"
msgstr "Adresa de e-mail"
+#: mediagoblin/auth/forms.py:51
+msgid "Username or email"
+msgstr "Numele de utilizator sau adresa de e-mail"
+
+#: mediagoblin/auth/forms.py:58
+msgid "Incorrect input"
+msgstr "Input incorect"
+
#: mediagoblin/auth/views.py:55
msgid "Sorry, registration is disabled on this instance."
msgstr "Ne pare rău, dar înscrierile sunt dezactivate pe acest server."
-#: mediagoblin/auth/views.py:73
+#: mediagoblin/auth/views.py:75
msgid "Sorry, a user with that name already exists."
msgstr "Ne pare rău, există deja un utilizator cu același nume."
-#: mediagoblin/auth/views.py:77
+#: mediagoblin/auth/views.py:79
msgid "Sorry, a user with that email address already exists."
msgstr "Există deja un utilizator înregistrat cu această adresă de e-mail."
-#: mediagoblin/auth/views.py:180
+#: mediagoblin/auth/views.py:182
msgid ""
"Your email address has been verified. You may now login, edit your profile, "
"and submit images!"
-msgstr ""
-"Adresa ta de e-mail a fost verificată. Poți să te autentifici, să îți "
-"completezi profilul și să trimiți imagini!"
+msgstr "Adresa ta de e-mail a fost verificată. Poți să te autentifici, să îți completezi profilul și să trimiți imagini!"
-#: mediagoblin/auth/views.py:186
+#: mediagoblin/auth/views.py:188
msgid "The verification key or user id is incorrect"
msgstr "Cheie de verificare sau user ID incorect."
-#: mediagoblin/auth/views.py:204
+#: mediagoblin/auth/views.py:206
msgid "You must be logged in so we know who to send the email to!"
msgstr "Trebuie să fii autentificat ca să știm cui să trimitem mesajul!"
-#: mediagoblin/auth/views.py:212
+#: mediagoblin/auth/views.py:214
msgid "You've already verified your email address!"
msgstr "Adresa ta de e-mail a fost deja verificată!"
-#: mediagoblin/auth/views.py:225
+#: mediagoblin/auth/views.py:227
msgid "Resent your verification email."
msgstr "E-mail-ul de verificare a fost retrimis."
-#: mediagoblin/auth/views.py:260
+#: mediagoblin/auth/views.py:263
msgid ""
"An email has been sent with instructions on how to change your password."
msgstr "S-a trimis un e-mail cu instrucțiuni pentru schimbarea parolei."
-#: mediagoblin/auth/views.py:270
+#: mediagoblin/auth/views.py:273
msgid ""
"Could not send password recovery email as your username is inactive or your "
"account's email address has not been verified."
-msgstr ""
-"E-mailul pentru recuperarea parolei nu a putut fi trimis deoarece contul tău"
-" e inactiv sau adresa ta de e-mail nu a fost verificată."
+msgstr "E-mailul pentru recuperarea parolei nu a putut fi trimis deoarece contul tău e inactiv sau adresa ta de e-mail nu a fost verificată."
-#: mediagoblin/auth/views.py:282
+#: mediagoblin/auth/views.py:285
msgid "Couldn't find someone with that username or email."
-msgstr ""
-"Nu s-a găsit nicio persoană cu acel nume de utilizator sau adresă de e-mail."
+msgstr "Nu s-a găsit nicio persoană cu acel nume de utilizator sau adresă de e-mail."
-#: mediagoblin/auth/views.py:330
+#: mediagoblin/auth/views.py:333
msgid "You can now log in using your new password."
msgstr "Acum te poți autentifica cu noua parolă."
@@ -108,10 +107,7 @@ msgid ""
"You can use\n"
" <a href=\"http://daringfireball.net/projects/markdown/basics\">\n"
" Markdown</a> for formatting."
-msgstr ""
-"Poți folosi\n"
-" <a href=\"http://daringfireball.net/projects/markdown/basics\">\n"
-" Markdown</a> pentru formatare."
+msgstr "Poți folosi\n <a href=\"http://daringfireball.net/projects/markdown/basics\">\n Markdown</a> pentru formatare."
#: mediagoblin/edit/forms.py:33 mediagoblin/submit/forms.py:36
msgid "Tags"
@@ -133,13 +129,12 @@ msgstr "Identificatorul nu poate să lipsească"
msgid ""
"The title part of this media's address. You usually don't need to change "
"this."
-msgstr ""
-"Partea corespunzătoare titlului din adresa acestui fișier media. De regulă "
-"poate fi lăsată nemodificată."
+msgstr "Partea corespunzătoare titlului din adresa acestui fișier media. De regulă poate fi lăsată nemodificată."
#: mediagoblin/edit/forms.py:44 mediagoblin/submit/forms.py:41
+#: mediagoblin/templates/mediagoblin/utils/license.html:20
msgid "License"
-msgstr ""
+msgstr "Licența"
#: mediagoblin/edit/forms.py:50
msgid "Bio"
@@ -149,61 +144,64 @@ msgstr "Biografie"
msgid "Website"
msgstr "Sit Web"
+#: mediagoblin/edit/forms.py:58
+msgid "This address contains errors"
+msgstr "Această adresă prezintă erori"
+
#: mediagoblin/edit/forms.py:63
msgid "Old password"
msgstr "Vechea parolă"
#: mediagoblin/edit/forms.py:65
msgid "Enter your old password to prove you own this account."
-msgstr ""
-"Introdu vechea parolă pentru a demonstra că ești titularul acestui cont."
+msgstr "Introdu vechea parolă pentru a demonstra că ești titularul acestui cont."
#: mediagoblin/edit/forms.py:68
msgid "New password"
msgstr "Noua parolă"
-#: mediagoblin/edit/views.py:68
+#: mediagoblin/edit/views.py:67
msgid "An entry with that slug already exists for this user."
-msgstr ""
-"Există deja un entry cu același identificator pentru acest utilizator."
+msgstr "Există deja un entry cu același identificator pentru acest utilizator."
-#: mediagoblin/edit/views.py:92
+#: mediagoblin/edit/views.py:88
msgid "You are editing another user's media. Proceed with caution."
msgstr "Editezi fișierul unui alt utilizator. Se recomandă prudență."
-#: mediagoblin/edit/views.py:162
+#: mediagoblin/edit/views.py:158
msgid "You are editing a user's profile. Proceed with caution."
msgstr "Editezi profilul unui utilizator. Se recomandă prudență."
-#: mediagoblin/edit/views.py:180
+#: mediagoblin/edit/views.py:174
msgid "Profile changes saved"
msgstr "Modificările profilului au fost salvate"
-#: mediagoblin/edit/views.py:206
+#: mediagoblin/edit/views.py:200
msgid "Wrong password"
msgstr "Parolă incorectă"
-#: mediagoblin/edit/views.py:222
+#: mediagoblin/edit/views.py:216
msgid "Account settings saved"
msgstr "Setările pentru acest cont au fost salvate"
-#: mediagoblin/media_types/__init__.py:77
-msgid "Could not extract any file extension from \"{filename}\""
-msgstr "Nu s-a putut extrage o extensie de fiÈ™ier din „{filename}â€."
-
-#: mediagoblin/media_types/__init__.py:88
+#: mediagoblin/media_types/__init__.py:60
+#: mediagoblin/media_types/__init__.py:120
msgid "Sorry, I don't support that file type :("
msgstr "Scuze, nu recunosc acest tip de fișier :("
+#: mediagoblin/processing/__init__.py:127
+msgid "Invalid file given for media type."
+msgstr "Formatul fișierului nu corespunde cu tipul de media selectat."
+
#: mediagoblin/submit/forms.py:26
msgid "File"
msgstr "Fișier"
-#: mediagoblin/submit/views.py:54
+#: mediagoblin/submit/views.py:56
msgid "You must provide a file."
msgstr "Trebuie să selectezi un fișier."
-#: mediagoblin/submit/views.py:158
+#: mediagoblin/submit/views.py:163
msgid "Woohoo! Submitted!"
msgstr "Ura! Trimis!"
@@ -223,40 +221,47 @@ msgstr "Nu există nicio pagină la această adresă. Ne pare rău!"
msgid ""
"If you're sure the address is correct, maybe the page you're looking for has"
" been moved or deleted."
-msgstr ""
-"Dacă ești sigur că adresa e corectă, poate că pagina pe care o cauți a fost "
-"mutată sau ștearsă."
+msgstr "Dacă ești sigur că adresa e corectă, poate că pagina pe care o cauți a fost mutată sau ștearsă."
-#: mediagoblin/templates/mediagoblin/base.html:46
+#: mediagoblin/templates/mediagoblin/base.html:47
msgid "MediaGoblin logo"
msgstr "logo MediaGoblin"
-#: mediagoblin/templates/mediagoblin/base.html:51
-#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
-msgid "Add media"
-msgstr "Trimite fișier"
-
-#: mediagoblin/templates/mediagoblin/base.html:62
+#: mediagoblin/templates/mediagoblin/base.html:57
msgid "Verify your email!"
msgstr "Verifică adresa de e-mail!"
-#: mediagoblin/templates/mediagoblin/base.html:69
-msgid "log out"
-msgstr "ieșire"
+#: mediagoblin/templates/mediagoblin/base.html:63
+msgid "+ Add media"
+msgstr "+ Adaugă fișier media"
+
+#: mediagoblin/templates/mediagoblin/base.html:65
+msgid "View your profile"
+msgstr "Vezi profilul tău"
-#: mediagoblin/templates/mediagoblin/base.html:72
-#: mediagoblin/templates/mediagoblin/auth/login.html:27
-#: mediagoblin/templates/mediagoblin/auth/login.html:45
+#: mediagoblin/templates/mediagoblin/base.html:66
+msgid "Log out"
+msgstr "Ieșire"
+
+#: mediagoblin/templates/mediagoblin/base.html:71
+#: mediagoblin/templates/mediagoblin/auth/login.html:32
+#: mediagoblin/templates/mediagoblin/auth/login.html:50
msgid "Log in"
msgstr "Autentificare"
-#: mediagoblin/templates/mediagoblin/base.html:84
+#: mediagoblin/templates/mediagoblin/base.html:85
msgid ""
"Powered by <a href=\"http://mediagoblin.org\">MediaGoblin</a>, a <a "
-"href=\"http://gnu.org/\">GNU</a> project"
-msgstr ""
-"Construit cu <a href=\"http://mediagoblin.org\">MediaGoblin</a>, un proiect "
-"<a href=\"http://gnu.org/\">GNU</a>"
+"href=\"http://gnu.org/\">GNU</a> project."
+msgstr "Construit cu <a href=\"http://mediagoblin.org\">MediaGoblin</a>, un proiect <a href=\"http://gnu.org/\">GNU</a>."
+
+#: mediagoblin/templates/mediagoblin/base.html:88
+#, python-format
+msgid ""
+"Released under the <a "
+"href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a "
+"href=\"%(source_link)s\">Source code</a> available."
+msgstr "Publicat sub licența <a href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a href=\"%(source_link)s\">Codul sursă</a> este disponibil."
#: mediagoblin/templates/mediagoblin/root.html:24
msgid "Explore"
@@ -270,17 +275,13 @@ msgstr "Salut, bine ai venit pe acest site MediaGoblin!"
msgid ""
"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, an "
"extraordinarily great piece of media hosting software."
-msgstr ""
-"Acest site folosește <a href=\"http://mediagoblin.org\">MediaGoblin</a>, un "
-"software excepțional pentru găzduirea fișierelor media."
+msgstr "Acest site folosește <a href=\"http://mediagoblin.org\">MediaGoblin</a>, un software excepțional pentru găzduirea fișierelor media."
#: mediagoblin/templates/mediagoblin/root.html:29
msgid ""
"To add your own media, place comments, save your favourites and more, you "
"can log in with your MediaGoblin account."
-msgstr ""
-"Ca să adăugi propriile tale fișiere, să scrii comentarii, să salvezi "
-"favoritele tale și multe altele, autentifică-te cu contul tău MediaGoblin."
+msgstr "Ca să adăugi propriile tale fișiere, să scrii comentarii, să salvezi favoritele tale și multe altele, autentifică-te cu contul tău MediaGoblin."
#: mediagoblin/templates/mediagoblin/root.html:31
msgid "Don't have one yet? It's easy!"
@@ -292,10 +293,7 @@ msgid ""
"<a class=\"button_action_highlight\" href=\"%(register_url)s\">Create an account at this site</a>\n"
" or\n"
" <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">Set up MediaGoblin on your own server</a>"
-msgstr ""
-"<a class=\"button_action_highlight\" href=\"%(register_url)s\">Creează un cont pe acest site</a>\n"
-" sau\n"
-" <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">Instalează MediaGoblin pe serverul tău</a>"
+msgstr "<a class=\"button_action_highlight\" href=\"%(register_url)s\">Creează un cont pe acest site</a>\n sau\n <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">Instalează MediaGoblin pe serverul tău</a>"
#: mediagoblin/templates/mediagoblin/root.html:40
msgid "Most recent media"
@@ -329,28 +327,21 @@ msgid ""
"\n"
"If you think this is an error, just ignore this email and continue being\n"
"a happy goblin!"
-msgstr ""
-"Bună, %(username)s\n"
-"\n"
-"Pentru a schimba parola ta la GNU MediaGoblin, accesează adresa următoare:\n"
-"\n"
-"%(verification_url)s\n"
-"\n"
-"Dacă ai primit acest mesaj din greșeală, ignoră-l și fii mai departe un elf fericit!"
+msgstr "Bună, %(username)s\n\nPentru a schimba parola ta la GNU MediaGoblin, accesează adresa următoare:\n\n%(verification_url)s\n\nDacă ai primit acest mesaj din greșeală, ignoră-l și fii mai departe un elf fericit!"
-#: mediagoblin/templates/mediagoblin/auth/login.html:30
+#: mediagoblin/templates/mediagoblin/auth/login.html:35
msgid "Logging in failed!"
msgstr "Autentificare eșuată!"
-#: mediagoblin/templates/mediagoblin/auth/login.html:35
+#: mediagoblin/templates/mediagoblin/auth/login.html:40
msgid "Don't have an account yet?"
msgstr "Nu ai un cont?"
-#: mediagoblin/templates/mediagoblin/auth/login.html:36
+#: mediagoblin/templates/mediagoblin/auth/login.html:41
msgid "Create one here!"
msgstr "Creează-l aici!"
-#: mediagoblin/templates/mediagoblin/auth/login.html:42
+#: mediagoblin/templates/mediagoblin/auth/login.html:47
msgid "Forgot your password?"
msgstr "Ai uitat parola?"
@@ -371,12 +362,7 @@ msgid ""
"your web browser:\n"
"\n"
"%(verification_url)s"
-msgstr ""
-"Bună, %(username)s,\n"
-"\n"
-"pentru activarea contului tău la GNU MediaGoblin, accesează adresa următoare:\n"
-"\n"
-"%(verification_url)s"
+msgstr "Bună, %(username)s,\n\npentru activarea contului tău la GNU MediaGoblin, accesează adresa următoare:\n\n%(verification_url)s"
#: mediagoblin/templates/mediagoblin/edit/edit.html:29
#, python-format
@@ -411,28 +397,49 @@ msgid "Media tagged with: %(tag_name)s"
msgstr "Fișier etichetat cu tag-urile: %(tag_name)s"
#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:46
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:53
msgid "Original"
msgstr "Original"
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:33
+#: 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 "Ne pare rău, această înregistrare audio nu poate fi redată, deoarece \n\tbrowserul tău nu este compatibil cu funcția audio din HTML5."
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:47
+msgid ""
+"You can get a modern web browser that \n"
+"\tcan play the audio at <a href=\"http://getfirefox.com\">\n"
+"\t http://getfirefox.com</a>!"
+msgstr "Poți lua un browser modern \n\tcapabil să redea această înregistrare de la <a href=\"http://getfirefox.com\">\n\t http://getfirefox.com</a>!"
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:56
+msgid "Download"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:60
+msgid "original file"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:63
+msgid "WebM file (Vorbis codec)"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:40
msgid ""
"Sorry, this video will not work because \n"
"\t your web browser does not support HTML5 \n"
"\t video."
-msgstr ""
-"Ne pare rău, această înregistrare video nu funcționează deoarece \n"
-"<span class=\"whitespace other\" title=\"Tab\">»</span> browserul tău nu este compatibil cu funcția video din HTML5."
+msgstr "Ne pare rău, această înregistrare video nu poate fi redată deoarece \n<span class=\"whitespace other\" title=\"Tab\">»</span> browserul tău nu este compatibil cu funcția video din HTML5."
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:36
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:43
msgid ""
"You can get a modern web browser that \n"
"\t can play this video at <a href=\"http://getfirefox.com\">\n"
"\t http://getfirefox.com</a>!"
-msgstr ""
-"Poți lua un browser modern cu care\n"
-"<span class=\"whitespace other\" title=\"Tab\">»</span> care poți vedea această înregistrare video de la <a href=\"http://getfirefox.com\">\n"
-"<span class=\"whitespace other\" title=\"Tab\">»</span> http://getfirefox.com</a>!"
+msgstr "Poți lua un browser modern\n<span class=\"whitespace other\" title=\"Tab\">»</span> capabil să redea această înregistrare de la <a href=\"http://getfirefox.com\">\n<span class=\"whitespace other\" title=\"Tab\">»</span> http://getfirefox.com</a>!"
#: mediagoblin/templates/mediagoblin/submit/start.html:26
msgid "Add your media"
@@ -452,57 +459,50 @@ msgstr "Fișierele lui %(username)s"
msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media"
msgstr "Fișierele media ale lui <a href=\"%(user_url)s\">%(username)s</a>"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:72
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:46
+#, python-format
+msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>"
+msgstr "<p>■Fișierele media ale lui <a href=\"%(user_url)s\">%(username)s</a></p>"
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:67
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:73
#, python-format
-msgid "Added on %(date)s."
-msgstr "Adăugat la data %(date)s."
+msgid "Image for %(media_title)s"
+msgstr "Imagine pentru %(media_title)s"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:81
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:87
msgid "Edit"
msgstr "Editare"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:85
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
msgid "Delete"
msgstr "Șterge"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
-#, python-format
-msgid "%(comment_count)s comment"
-msgstr "%(comment_count)s comentariu"
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:93
-#, python-format
-msgid "%(comment_count)s comments"
-msgstr "%(comment_count)s comentarii"
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:95
-msgid "No comments yet."
-msgstr "Deocamdată nu există comentarii."
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:103
-msgid "Add one"
-msgstr "Trimite unul"
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:124
+msgid "Add a comment"
+msgstr "Adaugă un comentariu"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:112
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:131
msgid ""
"You can use <a "
"href=\"http://daringfireball.net/projects/markdown/basics\">Markdown</a> for"
" formatting."
-msgstr ""
+msgstr "Poți folosi <a href=\"http://daringfireball.net/projects/markdown/basics\">Markdown</a> pentru formatare."
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:116
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:135
msgid "Add this comment"
msgstr "Trimite acest comentariu"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:138
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:154
msgid "at"
msgstr "la"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:153
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:174
#, python-format
-msgid "<p>â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a></p>"
-msgstr ""
-"<p>■Fișierele media ale lui <a href=\"%(user_url)s\">%(username)s</a></p>"
+msgid ""
+"<h3>Added on</h3>\n"
+" <p>%(date)s</p>"
+msgstr "<h3>Adăugat la</h3>\n <p>%(date)s</p>"
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30
#, python-format
@@ -510,7 +510,7 @@ msgid "Really delete %(title)s?"
msgstr "Sigur dorești să ștergi %(title)s?"
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:50
-msgid "Delete Permanently"
+msgid "Delete permanently"
msgstr "Șterge definitiv"
#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:22
@@ -570,18 +570,14 @@ msgstr "Retrimite mesajul de verificare"
msgid ""
"Someone has registered an account with this username, but it still has to be"
" activated."
-msgstr ""
-"Cineva a înregistrat un cont cu acest nume de utilizator, dar contul nu a "
-"fost încă activat."
+msgstr "Cineva a înregistrat un cont cu acest nume de utilizator, dar contul nu a fost încă activat."
#: mediagoblin/templates/mediagoblin/user_pages/user.html:79
#, python-format
msgid ""
"If you are that person but you've lost your verification email, you can <a "
"href=\"%(login_url)s\">log in</a> and resend it."
-msgstr ""
-"Dacă tu ești persoana respectivă și nu mai ai e-mail-ul de verificare, poți "
-"să te <a href=\"%(login_url)s\">autentifici</a> pentru a-l retrimite."
+msgstr "Dacă tu ești persoana respectivă și nu mai ai e-mail-ul de verificare, poți să te <a href=\"%(login_url)s\">autentifici</a> pentru a-l retrimite."
#: mediagoblin/templates/mediagoblin/user_pages/user.html:96
msgid "Here's a spot to tell others about yourself."
@@ -609,9 +605,11 @@ msgstr "Vezi toate fișierele media ale lui %(username)s"
msgid ""
"This is where your media will appear, but you don't seem to have added "
"anything yet."
-msgstr ""
-"Aici vor apărea fișierele tale media, dar se pare că încă nu ai trimis "
-"nimic."
+msgstr "Aici vor apărea fișierele tale media, dar se pare că încă nu ai trimis nimic."
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
+msgid "Add media"
+msgstr "Trimite fișier"
#: mediagoblin/templates/mediagoblin/user_pages/user.html:163
#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72
@@ -626,13 +624,18 @@ msgstr "icon feed"
msgid "Atom feed"
msgstr "feed Atom"
-#: mediagoblin/templates/mediagoblin/utils/license.html:21
-msgid "License:"
-msgstr ""
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:25
+msgid "Location"
+msgstr "Locul"
+
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:38
+#, python-format
+msgid "View on <a href=\"%(osm_url)s\">OpenStreetMap</a>"
+msgstr "Vezi pe <a href=\"%(osm_url)s\">OpenStreetMap</a>"
#: mediagoblin/templates/mediagoblin/utils/license.html:25
msgid "All rights reserved"
-msgstr ""
+msgstr "Toate drepturile rezervate"
#: mediagoblin/templates/mediagoblin/utils/pagination.html:39
msgid "↠Newer"
@@ -646,52 +649,44 @@ msgstr "Mai vechi →"
msgid "Go to page:"
msgstr "Salt la pagina:"
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:27
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:32
+#: mediagoblin/templates/mediagoblin/utils/prev_next.html:28
+#: mediagoblin/templates/mediagoblin/utils/prev_next.html:33
msgid "newer"
msgstr "mai noi"
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:38
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:43
+#: mediagoblin/templates/mediagoblin/utils/prev_next.html:39
+#: mediagoblin/templates/mediagoblin/utils/prev_next.html:44
msgid "older"
msgstr "mai vechi"
#: mediagoblin/templates/mediagoblin/utils/tags.html:20
-msgid "View more media tagged with"
-msgstr "Vezi și alte fișiere etichetate cu tag-ul"
+msgid "Tagged with"
+msgstr "Etichete"
-#: mediagoblin/templates/mediagoblin/utils/tags.html:25
-msgid "or"
-msgstr "sau"
-
-#: mediagoblin/tools/exif.py:68
+#: mediagoblin/tools/exif.py:75
msgid "Could not read the image file."
-msgstr ""
+msgstr "Fișierul cu imaginea nu a putut fi citit."
#: mediagoblin/user_pages/forms.py:30
msgid "I am sure I want to delete this"
msgstr "Sunt sigur că doresc să șterg"
-#: mediagoblin/user_pages/views.py:155
+#: mediagoblin/user_pages/views.py:153
msgid "Oops, your comment was empty."
msgstr "Hopa, ai uitat să scrii comentariul."
-#: mediagoblin/user_pages/views.py:161
+#: mediagoblin/user_pages/views.py:159
msgid "Your comment has been posted!"
msgstr "Comentariul tău a fost trimis!"
-#: mediagoblin/user_pages/views.py:183
+#: mediagoblin/user_pages/views.py:185
msgid "You deleted the media."
msgstr "Ai șters acest fișier"
-#: mediagoblin/user_pages/views.py:190
+#: mediagoblin/user_pages/views.py:192
msgid "The media was not deleted because you didn't check that you were sure."
msgstr "Fișierul nu a fost șters deoarece nu ai confirmat că ești sigur."
-#: mediagoblin/user_pages/views.py:198
+#: mediagoblin/user_pages/views.py:200
msgid "You are about to delete another user's media. Proceed with caution."
-msgstr ""
-"Urmează să ștergi fișierele media ale unui alt utilizator. Se recomandă "
-"prudență."
-
-
+msgstr "Urmează să ștergi fișierele media ale unui alt utilizator. Se recomandă prudență."
diff --git a/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.mo
index eb6cc942..eb67fe5b 100644
--- a/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.mo
+++ b/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.mo
Binary files differ
diff --git a/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.po
index ea9d1dc3..58c36f78 100644
--- a/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.po
+++ b/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.po
@@ -8,9 +8,9 @@ msgid ""
msgstr ""
"Project-Id-Version: GNU MediaGoblin\n"
"Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n"
-"POT-Creation-Date: 2012-02-09 09:30-0600\n"
-"PO-Revision-Date: 2012-02-26 19:33+0000\n"
-"Last-Translator: aleksejrs <deletesoftware@yandex.ru>\n"
+"POT-Creation-Date: 2012-06-01 16:32-0500\n"
+"PO-Revision-Date: 2012-06-01 21:30+0000\n"
+"Last-Translator: cwebber <cwebber@dustycloud.org>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -19,10 +19,6 @@ msgstr ""
"Language: ru\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n"
-#: mediagoblin/processing.py:153
-msgid "Invalid file given for media type."
-msgstr "Ðеправильный формат файла."
-
#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41
msgid "Username"
msgstr "Логин"
@@ -35,56 +31,64 @@ msgstr "Пароль"
msgid "Email address"
msgstr "ÐÐ´Ñ€ÐµÑ Ñлектронной почты"
+#: mediagoblin/auth/forms.py:51
+msgid "Username or email"
+msgstr "Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¸Ð»Ð¸ Ð°Ð´Ñ€ÐµÑ Ñлектронной почты"
+
+#: mediagoblin/auth/forms.py:58
+msgid "Incorrect input"
+msgstr "Введённое не похоже на Ð¸Ð¼Ñ ÑƒÑ‡Ñ‘Ñ‚Ð½Ð¾Ð¹ запиÑи или Ð°Ð´Ñ€ÐµÑ Ñлектронной почты."
+
#: mediagoblin/auth/views.py:55
msgid "Sorry, registration is disabled on this instance."
msgstr "Извините, на Ñтом разделе региÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð·Ð°Ð¿Ñ€ÐµÑ‰ÐµÐ½Ð°."
-#: mediagoblin/auth/views.py:73
+#: mediagoblin/auth/views.py:75
msgid "Sorry, a user with that name already exists."
msgstr "Извините, пользователь Ñ Ñтим именем уже зарегиÑтрирован."
-#: mediagoblin/auth/views.py:77
+#: mediagoblin/auth/views.py:79
msgid "Sorry, a user with that email address already exists."
msgstr "Сожалеем, но на Ñтот Ð°Ð´Ñ€ÐµÑ Ñлектронной почты уже зарегиÑтрирована Ð´Ñ€ÑƒÐ³Ð°Ñ ÑƒÑ‡Ñ‘Ñ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ."
-#: mediagoblin/auth/views.py:180
+#: mediagoblin/auth/views.py:182
msgid ""
"Your email address has been verified. You may now login, edit your profile, "
"and submit images!"
-msgstr "ÐÐ´Ñ€ÐµÑ Ð²Ð°ÑˆÐµÐ¹ Ñлектронной потвержден. Ð’Ñ‹ теперь можете войти и начать редактировать Ñвой профиль и загружать новые изображениÑ!"
+msgstr "Ваш Ð°Ð´Ñ€ÐµÑ Ñлектронной почты потвержден. Ð’Ñ‹ теперь можете войти и начать редактировать Ñвой профиль и загружать новые изображениÑ!"
-#: mediagoblin/auth/views.py:186
+#: mediagoblin/auth/views.py:188
msgid "The verification key or user id is incorrect"
msgstr "Ðеверный ключ проверки или идентификатор пользователÑ"
-#: mediagoblin/auth/views.py:204
+#: 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:212
+#: mediagoblin/auth/views.py:214
msgid "You've already verified your email address!"
msgstr "Ð’Ñ‹ уже потвердили Ñвой Ð°Ð´Ñ€ÐµÑ Ñлектронной почты!"
-#: mediagoblin/auth/views.py:225
+#: mediagoblin/auth/views.py:227
msgid "Resent your verification email."
msgstr "ПереÑлать Ñообщение Ñ Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸ÐµÐ¼ аккаунта."
-#: mediagoblin/auth/views.py:260
+#: mediagoblin/auth/views.py:263
msgid ""
"An email has been sent with instructions on how to change your password."
msgstr "Вам отправлено Ñлектронное пиÑьмо Ñ Ð¸Ð½ÑтрукциÑми по Ñмене паролÑ."
-#: mediagoblin/auth/views.py:270
+#: mediagoblin/auth/views.py:273
msgid ""
"Could not send password recovery email as your username is inactive or your "
"account's email address has not been verified."
msgstr "Мы не можем отправить Ñообщение Ð´Ð»Ñ Ð²Ð¾ÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿Ð°Ñ€Ð¾Ð»Ñ, потому что ваша ÑƒÑ‡Ñ‘Ñ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ неактивна, либо указанный в ней Ð°Ð´Ñ€ÐµÑ Ñлектронной почты не был подтверждён."
-#: mediagoblin/auth/views.py:282
+#: mediagoblin/auth/views.py:285
msgid "Couldn't find someone with that username or email."
msgstr "Ðе найдено никого Ñ Ñ‚Ð°ÐºÐ¸Ð¼ именем Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¸Ð»Ð¸ адреÑом Ñлектронной почты."
-#: mediagoblin/auth/views.py:330
+#: mediagoblin/auth/views.py:333
msgid "You can now log in using your new password."
msgstr "Теперь вы можете войти, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ð²Ð°Ñˆ новый пароль."
@@ -127,6 +131,7 @@ msgid ""
msgstr "ЧаÑть адреÑа Ñтого файла, Ð¿Ñ€Ð¾Ð¸Ð·Ð²Ð¾Ð´Ð½Ð°Ñ Ð¾Ñ‚ его названиÑ. Её обычно не требуетÑÑ Ð¸Ð·Ð¼ÐµÐ½Ñть."
#: mediagoblin/edit/forms.py:44 mediagoblin/submit/forms.py:41
+#: mediagoblin/templates/mediagoblin/utils/license.html:20
msgid "License"
msgstr "ЛицензиÑ"
@@ -138,6 +143,10 @@ msgstr "БиографиÑ"
msgid "Website"
msgstr "Сайт"
+#: mediagoblin/edit/forms.py:58
+msgid "This address contains errors"
+msgstr "Этот Ð°Ð´Ñ€ÐµÑ Ñодержит ошибки"
+
#: mediagoblin/edit/forms.py:63
msgid "Old password"
msgstr "Старый пароль"
@@ -150,47 +159,48 @@ msgstr "Введите Ñвой Ñтарый пароль в качеÑтве д
msgid "New password"
msgstr "Ðовый пароль"
-#: mediagoblin/edit/views.py:68
+#: mediagoblin/edit/views.py:67
msgid "An entry with that slug already exists for this user."
msgstr "У Ñтого Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ ÑƒÐ¶Ðµ еÑть файл Ñ Ñ‚Ð°ÐºÐ¾Ð¹ отличительной чаÑтью адреÑа."
-#: mediagoblin/edit/views.py:92
+#: mediagoblin/edit/views.py:88
msgid "You are editing another user's media. Proceed with caution."
msgstr "Ð’Ñ‹ редактируете файлы другого пользователÑ. Будьте оÑторожны."
-#: mediagoblin/edit/views.py:162
+#: mediagoblin/edit/views.py:158
msgid "You are editing a user's profile. Proceed with caution."
msgstr "Ð’Ñ‹ редактируете профиль пользователÑ. Будьте оÑторожны."
-#: mediagoblin/edit/views.py:180
+#: mediagoblin/edit/views.py:174
msgid "Profile changes saved"
msgstr "Ð˜Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ñ Ñохранены"
-#: mediagoblin/edit/views.py:206
+#: mediagoblin/edit/views.py:200
msgid "Wrong password"
msgstr "Ðеправильный пароль"
-#: mediagoblin/edit/views.py:222
+#: mediagoblin/edit/views.py:216
msgid "Account settings saved"
msgstr "ÐаÑтройки учётной запиÑи запиÑаны"
-#: mediagoblin/media_types/__init__.py:77
-msgid "Could not extract any file extension from \"{filename}\""
-msgstr "Ðе удалоÑÑŒ найти раÑширение в имени файла «{filename}»"
-
-#: mediagoblin/media_types/__init__.py:88
+#: mediagoblin/media_types/__init__.py:60
+#: mediagoblin/media_types/__init__.py:120
msgid "Sorry, I don't support that file type :("
msgstr "Увы, Ñ Ð½Ðµ поддерживаю Ñтот тип файлов :("
+#: mediagoblin/processing/__init__.py:127
+msgid "Invalid file given for media type."
+msgstr "Ðеправильный формат файла."
+
#: mediagoblin/submit/forms.py:26
msgid "File"
msgstr "Файл"
-#: mediagoblin/submit/views.py:54
+#: mediagoblin/submit/views.py:56
msgid "You must provide a file."
msgstr "Вы должны загрузить файл."
-#: mediagoblin/submit/views.py:158
+#: mediagoblin/submit/views.py:163
msgid "Woohoo! Submitted!"
msgstr "Ура! Файл загружен!"
@@ -212,34 +222,45 @@ msgid ""
" been moved or deleted."
msgstr "Возможно, Ñтраница, которую вы ищете, была удалена или переехала."
-#: mediagoblin/templates/mediagoblin/base.html:46
+#: mediagoblin/templates/mediagoblin/base.html:47
msgid "MediaGoblin logo"
msgstr "Символ MediaGoblin"
-#: mediagoblin/templates/mediagoblin/base.html:51
-#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
-msgid "Add media"
-msgstr "Добавить файлы"
-
-#: mediagoblin/templates/mediagoblin/base.html:62
+#: mediagoblin/templates/mediagoblin/base.html:57
msgid "Verify your email!"
msgstr "Подтвердите ваш Ð°Ð´Ñ€ÐµÑ Ñлектронной почты!"
-#: mediagoblin/templates/mediagoblin/base.html:69
-msgid "log out"
-msgstr "завершение ÑеанÑа"
+#: mediagoblin/templates/mediagoblin/base.html:63
+msgid "+ Add media"
+msgstr "+ Добавить файл"
+
+#: mediagoblin/templates/mediagoblin/base.html:65
+msgid "View your profile"
+msgstr "ПоÑмотреть Ñвой профиль"
+
+#: mediagoblin/templates/mediagoblin/base.html:66
+msgid "Log out"
+msgstr "Завершение ÑеанÑа"
-#: mediagoblin/templates/mediagoblin/base.html:72
-#: mediagoblin/templates/mediagoblin/auth/login.html:27
-#: mediagoblin/templates/mediagoblin/auth/login.html:45
+#: mediagoblin/templates/mediagoblin/base.html:71
+#: mediagoblin/templates/mediagoblin/auth/login.html:32
+#: mediagoblin/templates/mediagoblin/auth/login.html:50
msgid "Log in"
msgstr "Войти"
-#: mediagoblin/templates/mediagoblin/base.html:84
+#: mediagoblin/templates/mediagoblin/base.html:85
msgid ""
"Powered by <a href=\"http://mediagoblin.org\">MediaGoblin</a>, a <a "
-"href=\"http://gnu.org/\">GNU</a> project"
-msgstr "Работает на <a href=\"http://mediagoblin.org\">MediaGoblin</a>, проекте <a href=\"http://gnu.org/\">GNU</a>"
+"href=\"http://gnu.org/\">GNU</a> project."
+msgstr "Работает на <a href=\"http://mediagoblin.org\">MediaGoblin</a>, проекте <a href=\"http://gnu.org/\">GNU</a>."
+
+#: mediagoblin/templates/mediagoblin/base.html:88
+#, python-format
+msgid ""
+"Released under the <a "
+"href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a "
+"href=\"%(source_link)s\">Source code</a> available."
+msgstr "Он опубликован на уÑловиÑÑ… <a href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. ДоÑтупны <a href=\"%(source_link)s\">иÑходные текÑты</a>."
#: mediagoblin/templates/mediagoblin/root.html:24
msgid "Explore"
@@ -307,19 +328,19 @@ msgid ""
"a happy goblin!"
msgstr "Привет, %(username)s,\n\nчтобы Ñменить Ñвой пароль от GNU MediaGoblin, откройте\nÑледующий URL вашим вебâ€Ð±Ñ€Ð°ÑƒÐ·ÐµÑ€Ð¾Ð¼:\n\n%(verification_url)s\n\nЕÑли вы думаете, что Ñто какаÑâ€Ñ‚о ошибка, то игнорируйте\nÑто Ñообщение и продолжайте быть ÑчаÑтливым гоблином!"
-#: mediagoblin/templates/mediagoblin/auth/login.html:30
+#: mediagoblin/templates/mediagoblin/auth/login.html:35
msgid "Logging in failed!"
msgstr "ÐÐ²Ñ‚Ð¾Ñ€Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð½ÐµÑƒÑпешна!"
-#: mediagoblin/templates/mediagoblin/auth/login.html:35
+#: mediagoblin/templates/mediagoblin/auth/login.html:40
msgid "Don't have an account yet?"
msgstr "Ещё нету аккаунта?"
-#: mediagoblin/templates/mediagoblin/auth/login.html:36
+#: mediagoblin/templates/mediagoblin/auth/login.html:41
msgid "Create one here!"
msgstr "Создайте здеÑÑŒ!"
-#: mediagoblin/templates/mediagoblin/auth/login.html:42
+#: mediagoblin/templates/mediagoblin/auth/login.html:47
msgid "Forgot your password?"
msgstr "Забыли Ñвой пароль?"
@@ -350,7 +371,7 @@ msgstr "Редактирование %(media_title)s"
#: mediagoblin/templates/mediagoblin/edit/edit.html:36
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49
msgid "Cancel"
-msgstr "Отменить"
+msgstr "Отмена"
#: mediagoblin/templates/mediagoblin/edit/edit.html:37
#: mediagoblin/templates/mediagoblin/edit/edit_account.html:40
@@ -375,18 +396,44 @@ msgid "Media tagged with: %(tag_name)s"
msgstr "Файлы Ñ Ð¼ÐµÑ‚ÐºÐ¾Ð¹: %(tag_name)s"
#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:46
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:53
msgid "Original"
msgstr "Оригинал"
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:33
+#: 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 "Сожалеем, Ñтот аудиоролик не проиграетÑÑ, âŽ\n» потому что ваш браузер не поддерживает âŽ\n» аудио в ÑоответÑтвии Ñо Ñтандартом HTML5."
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:47
+msgid ""
+"You can get a modern web browser that \n"
+"\tcan play the audio at <a href=\"http://getfirefox.com\">\n"
+"\t http://getfirefox.com</a>!"
+msgstr "Ð’Ñ‹ можете Ñкачать Ñовременный браузер, \n\tÑпоÑобный проиграть Ñто аудио, Ñ <a href=\"http://getfirefox.com\">\n\t http://getfirefox.com</a>!"
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:56
+msgid "Download"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:60
+msgid "original file"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:63
+msgid "WebM file (Vorbis codec)"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:40
msgid ""
"Sorry, this video will not work because \n"
"\t your web browser does not support HTML5 \n"
"\t video."
msgstr "Сожалеем, Ñтот ролик не проиграетÑÑ, âŽ\n» потому что ваш браузер не поддерживает âŽ\n» видео в ÑоответÑтвии Ñо Ñтандартом HTML5."
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:36
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:43
msgid ""
"You can get a modern web browser that \n"
"\t can play this video at <a href=\"http://getfirefox.com\">\n"
@@ -411,64 +458,58 @@ msgstr "Файлы %(username)s"
msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media"
msgstr "Файлы Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ <a href=\"%(user_url)s\">%(username)s</a>"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:72
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:46
#, python-format
-msgid "Added on %(date)s."
-msgstr "Добавлено %(date)s."
+msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>"
+msgstr "■ПроÑмотр файлов Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ <a href=\"%(user_url)s\">%(username)s</a>"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:81
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:67
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:73
+#, python-format
+msgid "Image for %(media_title)s"
+msgstr "Изображение «%(media_title)s»"
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:87
msgid "Edit"
msgstr "Изменить"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:85
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
msgid "Delete"
msgstr "Удалить"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
-#, python-format
-msgid "%(comment_count)s comment"
-msgstr "%(comment_count)s комментарий"
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:124
+msgid "Add a comment"
+msgstr "Добавить комментарий"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:93
-#, python-format
-msgid "%(comment_count)s comments"
-msgstr "%(comment_count)s комментариев"
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:95
-msgid "No comments yet."
-msgstr "Комментариев пока нет."
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:103
-msgid "Add one"
-msgstr "Комментировать"
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:112
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:131
msgid ""
"You can use <a "
"href=\"http://daringfireball.net/projects/markdown/basics\">Markdown</a> for"
" formatting."
msgstr "Ð”Ð»Ñ Ñ€Ð°Ð·Ð¼ÐµÑ‚ÐºÐ¸ можете иÑпользовать Ñзык <a href=\"http://daringfireball.net/projects/markdown/basics\">Markdown</a>."
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:116
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:135
msgid "Add this comment"
msgstr "Добавить Ñтот комментарий"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:138
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:154
msgid "at"
msgstr "в"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:153
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:174
#, python-format
-msgid "<p>â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a></p>"
-msgstr "<p>■ПроÑмотр файлов Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ <a href=\"%(user_url)s\">%(username)s</a></p>"
+msgid ""
+"<h3>Added on</h3>\n"
+" <p>%(date)s</p>"
+msgstr "<h3>Добавлено</h3>\n <p>%(date)s</p>"
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30
#, python-format
msgid "Really delete %(title)s?"
-msgstr "ДейÑтвительно удалить %(title)s?"
+msgstr "Удалить %(title)s?"
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:50
-msgid "Delete Permanently"
+msgid "Delete permanently"
msgstr "Удалить безвозвратно"
#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:22
@@ -565,6 +606,10 @@ msgid ""
"anything yet."
msgstr "Ваши файлы поÑвÑÑ‚ÑÑ Ð·Ð´ÐµÑÑŒ, когда вы их добавите."
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
+msgid "Add media"
+msgstr "Добавить файлы"
+
#: mediagoblin/templates/mediagoblin/user_pages/user.html:163
#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72
msgid "There doesn't seem to be any media here yet..."
@@ -578,9 +623,14 @@ msgstr "значок ленты"
msgid "Atom feed"
msgstr "лента в формате Atom"
-#: mediagoblin/templates/mediagoblin/utils/license.html:21
-msgid "License:"
-msgstr "ЛицензиÑ:"
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:25
+msgid "Location"
+msgstr "Ðа карте"
+
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:38
+#, python-format
+msgid "View on <a href=\"%(osm_url)s\">OpenStreetMap</a>"
+msgstr "ПоÑмотреть на <a href=\"%(osm_url)s\">OpenStreetMap</a>"
#: mediagoblin/templates/mediagoblin/utils/license.html:25
msgid "All rights reserved"
@@ -598,25 +648,21 @@ msgstr "Более Ñтарые →"
msgid "Go to page:"
msgstr "Перейти к Ñтранице:"
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:27
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:32
+#: 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:38
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:43
+#: 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 "View more media tagged with"
-msgstr "Ðайти другие файлы Ñ Ð¼ÐµÑ‚ÐºÐ¾Ð¹"
-
-#: mediagoblin/templates/mediagoblin/utils/tags.html:25
-msgid "or"
-msgstr "или"
+msgid "Tagged with"
+msgstr "Метки"
-#: mediagoblin/tools/exif.py:68
+#: mediagoblin/tools/exif.py:75
msgid "Could not read the image file."
msgstr "Ðе удалоÑÑŒ прочитать файл Ñ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸ÐµÐ¼."
@@ -624,22 +670,22 @@ msgstr "Ðе удалоÑÑŒ прочитать файл Ñ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ð
msgid "I am sure I want to delete this"
msgstr "Я уверен, что хочу удалить Ñто"
-#: mediagoblin/user_pages/views.py:155
+#: mediagoblin/user_pages/views.py:153
msgid "Oops, your comment was empty."
msgstr "Ой, ваш комментарий был пуÑÑ‚."
-#: mediagoblin/user_pages/views.py:161
+#: mediagoblin/user_pages/views.py:159
msgid "Your comment has been posted!"
msgstr "Ваш комментарий размещён!"
-#: mediagoblin/user_pages/views.py:183
+#: mediagoblin/user_pages/views.py:185
msgid "You deleted the media."
msgstr "Вы удалили файл."
-#: mediagoblin/user_pages/views.py:190
+#: mediagoblin/user_pages/views.py:192
msgid "The media was not deleted because you didn't check that you were sure."
msgstr "Файл не удалён, так как вы не подтвердили Ñвою уверенноÑть галочкой."
-#: mediagoblin/user_pages/views.py:198
+#: mediagoblin/user_pages/views.py:200
msgid "You are about to delete another user's media. Proceed with caution."
msgstr "Ð’Ñ‹ на пороге ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ñ„Ð°Ð¹Ð»Ð° другого пользователÑ. Будьте оÑторожны."
diff --git a/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.mo
index e79b6848..2a872fb2 100644
--- a/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.mo
+++ b/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.mo
Binary files differ
diff --git a/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.po
index 8cde8800..794f94ff 100644
--- a/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.po
+++ b/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.po
@@ -3,14 +3,15 @@
# This file is distributed under the same license as the PROJECT project.
#
# Translators:
+# Martin Zatroch <zatroch.martin@gmail.com>, 2012.
# <zatroch.martin@gmail.com>, 2011, 2012.
msgid ""
msgstr ""
"Project-Id-Version: GNU MediaGoblin\n"
-"Report-Msgid-Bugs-To: http://bugs.foocorp.net/projects/mediagoblin/issues\n"
-"POT-Creation-Date: 2012-01-29 13:31-0600\n"
-"PO-Revision-Date: 2012-01-29 19:29+0000\n"
-"Last-Translator: cwebber <cwebber@dustycloud.org>\n"
+"Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n"
+"POT-Creation-Date: 2012-04-30 10:48-0500\n"
+"PO-Revision-Date: 2012-05-07 12:12+0000\n"
+"Last-Translator: martin <zatroch.martin@gmail.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -19,10 +20,6 @@ msgstr ""
"Language: sk\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2\n"
-#: mediagoblin/processing.py:143
-msgid "Invalid file given for media type."
-msgstr "Odovzdaný nesprávny súbor pre daný typ média."
-
#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41
msgid "Username"
msgstr "Prihlasovacie meno"
@@ -35,64 +32,64 @@ msgstr "Heslo"
msgid "Email address"
msgstr "E-mailová adresa"
+#: mediagoblin/auth/forms.py:51
+msgid "Username or email"
+msgstr "Používateľské meno alebo e-mailová adresa"
+
+#: mediagoblin/auth/forms.py:58
+msgid "Incorrect input"
+msgstr "Nesprávny vstup"
+
#: mediagoblin/auth/views.py:55
msgid "Sorry, registration is disabled on this instance."
msgstr "PrepáÄ, registrácia na tejto inÅ¡tancii nie je povolená."
-#: mediagoblin/auth/views.py:73
+#: mediagoblin/auth/views.py:75
msgid "Sorry, a user with that name already exists."
msgstr "PrepáÄ, rovnaké prihlasovacie meno už niekto používa."
-#: mediagoblin/auth/views.py:77
+#: mediagoblin/auth/views.py:79
msgid "Sorry, a user with that email address already exists."
msgstr "PrepáÄ, používateľ s rovnakou e-mailovou adresou už existuje."
-#: mediagoblin/auth/views.py:180
+#: mediagoblin/auth/views.py:182
msgid ""
"Your email address has been verified. You may now login, edit your profile, "
"and submit images!"
-msgstr ""
-"Tvoja e-mailová adresa bola úspeÅ¡ne overená. MôžeÅ¡ sa hneÄ prihlásiÅ¥, "
-"upraviť svoj profil a vkladať výtvory! "
+msgstr "Tvoja e-mailová adresa bola úspeÅ¡ne overená. MôžeÅ¡ sa hneÄ prihlásiÅ¥, upraviÅ¥ svoj profil a vkladaÅ¥ výtvory! "
-#: mediagoblin/auth/views.py:186
+#: mediagoblin/auth/views.py:188
msgid "The verification key or user id is incorrect"
msgstr "Nesprávny overovací kÄ¾ÃºÄ alebo používateľský identifikátor"
-#: mediagoblin/auth/views.py:204
+#: mediagoblin/auth/views.py:206
msgid "You must be logged in so we know who to send the email to!"
-msgstr ""
-"Aby sme ti mohli zaslať e-mailovú správu, je potrebné byť prihláseným!"
+msgstr "Aby sme ti mohli zaslať e-mailovú správu, je potrebné byť prihláseným!"
-#: mediagoblin/auth/views.py:212
+#: mediagoblin/auth/views.py:214
msgid "You've already verified your email address!"
msgstr "Tvoja e-mailová adresa už bola raz overená!"
-#: mediagoblin/auth/views.py:225
+#: mediagoblin/auth/views.py:227
msgid "Resent your verification email."
msgstr "Opätovne zaslať overovaciu správu na e-mail."
-#: mediagoblin/auth/views.py:260
+#: mediagoblin/auth/views.py:263
msgid ""
"An email has been sent with instructions on how to change your password."
msgstr "E-mailová správa s inštrukciami pre zmenu tvojho hesla bola odoslaná."
-#: mediagoblin/auth/views.py:270
+#: mediagoblin/auth/views.py:273
msgid ""
"Could not send password recovery email as your username is inactive or your "
"account's email address has not been verified."
-msgstr ""
-"Nebolo ti možné zaslať e-mailovú správu ohľadom obnovy hesla, nakoľko je "
-"tvoje používateľské meno buÄ neaktívne alebo e-mailová adresa úÄtu "
-"neoverená."
+msgstr "Nebolo ti možné zaslaÅ¥ e-mailovú správu ohľadom obnovy hesla, nakoľko je tvoje používateľské meno buÄ neaktívne alebo e-mailová adresa úÄtu neoverená."
-#: mediagoblin/auth/views.py:282
+#: mediagoblin/auth/views.py:285
msgid "Couldn't find someone with that username or email."
-msgstr ""
-"Nebolo možné nájsť nikoho s týmto používateľským menom alebo e-mailovou "
-"adresou."
+msgstr "Nebolo možné nájsť nikoho s týmto používateľským menom alebo e-mailovou adresou."
-#: mediagoblin/auth/views.py:330
+#: mediagoblin/auth/views.py:333
msgid "You can now log in using your new password."
msgstr "Teraz sa môžeš prihlásiť so svojim novým heslom."
@@ -110,10 +107,7 @@ msgid ""
"You can use\n"
" <a href=\"http://daringfireball.net/projects/markdown/basics\">\n"
" Markdown</a> for formatting."
-msgstr ""
-"Môžeš využiť\n"
-" <a href=\"http://daringfireball.net/projects/markdown/basics\">\n"
-" Markdown</a> pri formátovaní."
+msgstr "Môžeš využiť\n <a href=\"http://daringfireball.net/projects/markdown/basics\">\n Markdown</a> pri formátovaní."
#: mediagoblin/edit/forms.py:33 mediagoblin/submit/forms.py:36
msgid "Tags"
@@ -138,8 +132,9 @@ msgid ""
msgstr "Titulná ÄasÅ¥ adresy tohto výtvoru. VäÄÅ¡inou nie je potrebná zmena."
#: mediagoblin/edit/forms.py:44 mediagoblin/submit/forms.py:41
+#: mediagoblin/templates/mediagoblin/utils/license.html:20
msgid "License"
-msgstr ""
+msgstr "Licencia"
#: mediagoblin/edit/forms.py:50
msgid "Bio"
@@ -149,6 +144,10 @@ msgstr "Bio"
msgid "Website"
msgstr "Webstránka"
+#: mediagoblin/edit/forms.py:58
+msgid "This address contains errors"
+msgstr "Adresa obsahuje chyby"
+
#: mediagoblin/edit/forms.py:63
msgid "Old password"
msgstr "Staré heslo"
@@ -161,47 +160,48 @@ msgstr "PotvrÄ, že vlastníš tento úÄet zadaním svojho starého hesla."
msgid "New password"
msgstr "Nové heslo"
-#: mediagoblin/edit/views.py:68
+#: mediagoblin/edit/views.py:67
msgid "An entry with that slug already exists for this user."
msgstr "Položku s rovnakou unikátnou ÄasÅ¥ou adresy už niekde máš."
-#: mediagoblin/edit/views.py:92
+#: mediagoblin/edit/views.py:88
msgid "You are editing another user's media. Proceed with caution."
msgstr "Upravuješ médiá niekoho iného. Dbaj na to."
-#: mediagoblin/edit/views.py:162
+#: mediagoblin/edit/views.py:158
msgid "You are editing a user's profile. Proceed with caution."
msgstr "Upravuješ používateľský profil. Dbaj na to."
-#: mediagoblin/edit/views.py:180
+#: mediagoblin/edit/views.py:174
msgid "Profile changes saved"
msgstr "Úpravy profilu uložené"
-#: mediagoblin/edit/views.py:206
+#: mediagoblin/edit/views.py:200
msgid "Wrong password"
msgstr "Nesprávne heslo"
-#: mediagoblin/edit/views.py:222
+#: mediagoblin/edit/views.py:216
msgid "Account settings saved"
msgstr "Nastavenia úÄtu uložené"
-#: mediagoblin/media_types/__init__.py:77
-msgid "Could not extract any file extension from \"{filename}\""
-msgstr "Nebolo možné extrahovať žiadnu súborovú príponu z \"{filename}\""
-
-#: mediagoblin/media_types/__init__.py:88
+#: mediagoblin/media_types/__init__.py:60
+#: mediagoblin/media_types/__init__.py:120
msgid "Sorry, I don't support that file type :("
msgstr "PrepáÄ, nepodporujem tento súborový typ =("
+#: mediagoblin/processing/__init__.py:127
+msgid "Invalid file given for media type."
+msgstr "Odovzdaný nesprávny súbor pre daný typ média."
+
#: mediagoblin/submit/forms.py:26
msgid "File"
msgstr "Súbor"
-#: mediagoblin/submit/views.py:54
+#: mediagoblin/submit/views.py:56
msgid "You must provide a file."
msgstr "Musíš poskytnúť súbor."
-#: mediagoblin/submit/views.py:158
+#: mediagoblin/submit/views.py:163
msgid "Woohoo! Submitted!"
msgstr "Juchú! Úspešne vložené!"
@@ -221,40 +221,47 @@ msgstr "Na danej adrese sa stránka zrejme nenachádza. PrepáÄ!"
msgid ""
"If you're sure the address is correct, maybe the page you're looking for has"
" been moved or deleted."
-msgstr ""
-"Ak vieš s istotou, že adresa je správna, tak najskôr bola hľadaná stánka "
-"presunutá alebo zmazaná."
+msgstr "Ak vieš s istotou, že adresa je správna, tak najskôr bola hľadaná stánka presunutá alebo zmazaná."
-#: mediagoblin/templates/mediagoblin/base.html:46
+#: mediagoblin/templates/mediagoblin/base.html:47
msgid "MediaGoblin logo"
msgstr "MediaGoblin logo"
-#: mediagoblin/templates/mediagoblin/base.html:51
-#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
-msgid "Add media"
-msgstr "Pridať výtvor"
-
-#: mediagoblin/templates/mediagoblin/base.html:62
+#: mediagoblin/templates/mediagoblin/base.html:57
msgid "Verify your email!"
msgstr "Over si e-mailovú adresu!"
-#: mediagoblin/templates/mediagoblin/base.html:69
-msgid "log out"
-msgstr "odhlásiť sa"
+#: mediagoblin/templates/mediagoblin/base.html:63
+msgid "+ Add media"
+msgstr "+ Pridať výtvor"
+
+#: mediagoblin/templates/mediagoblin/base.html:65
+msgid "View your profile"
+msgstr "Zobraziť svoj profil"
+
+#: mediagoblin/templates/mediagoblin/base.html:66
+msgid "Log out"
+msgstr "Odhlásiť sa"
-#: mediagoblin/templates/mediagoblin/base.html:72
-#: mediagoblin/templates/mediagoblin/auth/login.html:27
-#: mediagoblin/templates/mediagoblin/auth/login.html:45
+#: mediagoblin/templates/mediagoblin/base.html:71
+#: mediagoblin/templates/mediagoblin/auth/login.html:32
+#: mediagoblin/templates/mediagoblin/auth/login.html:50
msgid "Log in"
msgstr "Prihlásenie"
-#: mediagoblin/templates/mediagoblin/base.html:84
+#: mediagoblin/templates/mediagoblin/base.html:85
msgid ""
"Powered by <a href=\"http://mediagoblin.org\">MediaGoblin</a>, a <a "
-"href=\"http://gnu.org/\">GNU</a> project"
-msgstr ""
-"Poháňa nás <a href=\"http://mediagoblin.org\">MediaGoblin</a>, súÄasÅ¥ "
-"projektu <a href=\"http://gnu.org/\">GNU</a>"
+"href=\"http://gnu.org/\">GNU</a> project."
+msgstr "Poháňa nás <a href=\"http://mediagoblin.org\">MediaGoblin</a>, súÄasÅ¥ projektu <a href=\"http://gnu.org/\">GNU</a>."
+
+#: mediagoblin/templates/mediagoblin/base.html:88
+#, python-format
+msgid ""
+"Released under the <a "
+"href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a "
+"href=\"%(source_link)s\">Source code</a> available."
+msgstr "Vydané pod <a href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a href=\"%(source_link)s\">Zdrojový kód</a> dostupný."
#: mediagoblin/templates/mediagoblin/root.html:24
msgid "Explore"
@@ -268,17 +275,13 @@ msgstr "Ahoj, vitaj na tejto MediaGoblin stránke!"
msgid ""
"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, an "
"extraordinarily great piece of media hosting software."
-msgstr ""
-"Táto stránka používa <a href=\"http://mediagoblin.org\">MediaGoblin</a>, "
-"výnimoÄne skvelý kus softvéru na hostovanie médií."
+msgstr "Táto stránka používa <a href=\"http://mediagoblin.org\">MediaGoblin</a>, výnimoÄne skvelý kus softvéru na hostovanie médií."
#: mediagoblin/templates/mediagoblin/root.html:29
msgid ""
"To add your own media, place comments, save your favourites and more, you "
"can log in with your MediaGoblin account."
-msgstr ""
-"Pre pridanie vlastných výtvorov, vloženie komentárov, uloženie svojich "
-"obľúbených položiek a viac, sa musíš prihlásiÅ¥ so svojim MediaGoblin úÄtom."
+msgstr "Pre pridanie vlastných výtvorov, vloženie komentárov, uloženie svojich obľúbených položiek a viac, sa musíš prihlásiÅ¥ so svojim MediaGoblin úÄtom."
#: mediagoblin/templates/mediagoblin/root.html:31
msgid "Don't have one yet? It's easy!"
@@ -290,10 +293,7 @@ msgid ""
"<a class=\"button_action_highlight\" href=\"%(register_url)s\">Create an account at this site</a>\n"
" or\n"
" <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">Set up MediaGoblin on your own server</a>"
-msgstr ""
-"<a class=\"button_action_highlight\" href=\"%(register_url)s\">VytvoriÅ¥ úÄet na tejto stránke</a>\n"
-" alebo\n"
-" <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">Založiť MediaGoblin na vlastnom serveri</a>"
+msgstr "<a class=\"button_action_highlight\" href=\"%(register_url)s\">VytvoriÅ¥ úÄet na tejto stránke</a>\n alebo\n <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">ZaložiÅ¥ MediaGoblin na vlastnom serveri</a>"
#: mediagoblin/templates/mediagoblin/root.html:40
msgid "Most recent media"
@@ -327,28 +327,21 @@ msgid ""
"\n"
"If you think this is an error, just ignore this email and continue being\n"
"a happy goblin!"
-msgstr ""
-"Ahoj %(username)s,\n"
-"\n"
-"pre zmenu svojho hesla k GNU MediaGoblin úÄtu, otvor nasledujúci odkaz vo svojom prehliadaÄi:\n"
-"\n"
-"%(verification_url)s\n"
-"\n"
-"Pokiaľ si myslíš, že doÅ¡lo k omylu, tak jednoducho ignoruj túto správu a buÄ Å¡Å¥astným goblinom!"
+msgstr "Ahoj %(username)s,\n\npre zmenu svojho hesla k GNU MediaGoblin úÄtu, otvor nasledujúci odkaz vo svojom prehliadaÄi:\n\n%(verification_url)s\n\nPokiaľ si myslíš, že doÅ¡lo k omylu, tak jednoducho ignoruj túto správu a buÄ Å¡Å¥astným goblinom!"
-#: mediagoblin/templates/mediagoblin/auth/login.html:30
+#: mediagoblin/templates/mediagoblin/auth/login.html:35
msgid "Logging in failed!"
msgstr "Prihlásenie zlyhalo!"
-#: mediagoblin/templates/mediagoblin/auth/login.html:35
+#: mediagoblin/templates/mediagoblin/auth/login.html:40
msgid "Don't have an account yet?"
msgstr "EÅ¡te nemáš úÄet?"
-#: mediagoblin/templates/mediagoblin/auth/login.html:36
+#: mediagoblin/templates/mediagoblin/auth/login.html:41
msgid "Create one here!"
msgstr "Vytvor si jeden tu!"
-#: mediagoblin/templates/mediagoblin/auth/login.html:42
+#: mediagoblin/templates/mediagoblin/auth/login.html:47
msgid "Forgot your password?"
msgstr "Zabudnuté heslo?"
@@ -369,13 +362,7 @@ msgid ""
"your web browser:\n"
"\n"
"%(verification_url)s"
-msgstr ""
-"Ahoj %(username)s,\n"
-"\n"
-"pre aktiváciu tvojho GNU MediaGoblin úÄtu, otvor nasledujúci odkaz vo\n"
-"svojom prehliadaÄi:\n"
-"\n"
-"%(verification_url)s"
+msgstr "Ahoj %(username)s,\n\npre aktiváciu tvojho GNU MediaGoblin úÄtu, otvor nasledujúci odkaz vo\nsvojom prehliadaÄi:\n\n%(verification_url)s"
#: mediagoblin/templates/mediagoblin/edit/edit.html:29
#, python-format
@@ -410,29 +397,38 @@ msgid "Media tagged with: %(tag_name)s"
msgstr "Výtvory oznaÄené ako: %(tag_name)s"
#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:46
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:57
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:53
msgid "Original"
msgstr "Originál"
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:33
+#: 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 "PrepáÄ, tento zvukový súbor nepôjde prehraÅ¥, \n\tnakoľko tvoj prehliadaÄ nepodporuje HTML5 \n\taudio."
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:47
+msgid ""
+"You can get a modern web browser that \n"
+"\tcan play the audio at <a href=\"http://getfirefox.com\">\n"
+"\t http://getfirefox.com</a>!"
+msgstr "MôžeÅ¡ získaÅ¥ moderný prehliadaÄ, ktorý\n\ttento zvuk hravo prehrá <a href=\"http://getfirefox.com\">\n\t http://getfirefox.com</a>!"
+
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:40
msgid ""
"Sorry, this video will not work because \n"
"\t your web browser does not support HTML5 \n"
"\t video."
-msgstr ""
-"PrepáÄ, toto video nepôjde prehraÅ¥ \n"
-"<span class=\"whitespace other\" title=\"Tab\">»</span> tvoj webový prehliadaÄ nepodporuje HTML5 \n"
-"<span class=\"whitespace other\" title=\"Tab\">»</span> video."
+msgstr "PrepáÄ, toto video nepôjde prehraÅ¥ \n<span class=\"whitespace other\" title=\"Tab\">»</span> tvoj webový prehliadaÄ nepodporuje HTML5 \n<span class=\"whitespace other\" title=\"Tab\">»</span> video."
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:36
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:43
msgid ""
"You can get a modern web browser that \n"
"\t can play this video at <a href=\"http://getfirefox.com\">\n"
"\t http://getfirefox.com</a>!"
-msgstr ""
-"MôžeÅ¡ získaÅ¥ moderný prehliadaÄ, ktorý \n"
-"<span class=\"whitespace other\" title=\"Tab\">»</span> vie prehrať toto video na <a href=\"http://getfirefox.com\">\n"
-"<span class=\"whitespace other\" title=\"Tab\">»</span> http://getfirefox.com</a>!"
+msgstr "MôžeÅ¡ získaÅ¥ moderný prehliadaÄ, ktorý \n<span class=\"whitespace other\" title=\"Tab\">»</span> vie prehraÅ¥ toto video na <a href=\"http://getfirefox.com\">\n<span class=\"whitespace other\" title=\"Tab\">»</span> http://getfirefox.com</a>!"
#: mediagoblin/templates/mediagoblin/submit/start.html:26
msgid "Add your media"
@@ -452,57 +448,50 @@ msgstr "Výtvory, ktoré vlastní %(username)s"
msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media"
msgstr "Výtvory, ktoré vlastní <a href=\"%(user_url)s\">%(username)s</a>"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:72
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:46
+#, python-format
+msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>"
+msgstr "■Prezeranie výtvorov podľa <a href=\"%(user_url)s\">%(username)s</a>"
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:67
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:73
#, python-format
-msgid "Added on %(date)s."
-msgstr "Pridané v %(date)s."
+msgid "Image for %(media_title)s"
+msgstr "Obrázok pre %(media_title)s"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:81
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:87
msgid "Edit"
msgstr "Upraviť"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:85
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
msgid "Delete"
msgstr "Odstrániť"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
-#, python-format
-msgid "%(comment_count)s comment"
-msgstr "%(comment_count)s komentár"
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:93
-#, python-format
-msgid "%(comment_count)s comments"
-msgstr "%(comment_count)s komentáre"
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:95
-msgid "No comments yet."
-msgstr "Zatiaľ žiadny komentár."
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:124
+msgid "Add a comment"
+msgstr "Pridaj komentár"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:103
-msgid "Add one"
-msgstr "Pridaj jeden"
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:112
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:131
msgid ""
"You can use <a "
"href=\"http://daringfireball.net/projects/markdown/basics\">Markdown</a> for"
" formatting."
-msgstr ""
+msgstr "Môžeš využiť <a href=\"http://daringfireball.net/projects/markdown/basics\">Markdown</a> pre formátovanie."
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:116
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:135
msgid "Add this comment"
msgstr "Pridať tento komentár"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:138
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:154
msgid "at"
msgstr "o"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:153
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:174
#, python-format
-msgid "<p>â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a></p>"
-msgstr ""
-"<p>■Prezeranie výtvorov podľa <a href=\"%(user_url)s\">%(username)s</a></p>"
+msgid ""
+"<h3>Added on</h3>\n"
+" <p>%(date)s</p>"
+msgstr "<h3>Pridané</h3>\n <p>%(date)s</p>"
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30
#, python-format
@@ -510,8 +499,8 @@ msgid "Really delete %(title)s?"
msgstr "SkutoÄne odstrániÅ¥ %(title)s?"
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:50
-msgid "Delete Permanently"
-msgstr "Odstrániť navždy"
+msgid "Delete permanently"
+msgstr "Odstráň permanentne"
#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:22
msgid "Media processing panel"
@@ -570,18 +559,14 @@ msgstr "Opätovne zaslať overovaciu správu na e-mail"
msgid ""
"Someone has registered an account with this username, but it still has to be"
" activated."
-msgstr ""
-"ÚÄet s týmto prihlasovacím menom je už registrovaný, avÅ¡ak eÅ¡te stále "
-"neaktívny."
+msgstr "ÚÄet s týmto prihlasovacím menom je už registrovaný, avÅ¡ak eÅ¡te stále neaktívny."
#: mediagoblin/templates/mediagoblin/user_pages/user.html:79
#, python-format
msgid ""
"If you are that person but you've lost your verification email, you can <a "
"href=\"%(login_url)s\">log in</a> and resend it."
-msgstr ""
-"Pokiaľ si to ty, ale už nemáš overovaciu e-mailovú správu, tak sa môžeš <a "
-"href=\"%(login_url)s\">prihlásiť</a> a preposlať si ju."
+msgstr "Pokiaľ si to ty, ale už nemáš overovaciu e-mailovú správu, tak sa môžeš <a href=\"%(login_url)s\">prihlásiť</a> a preposlať si ju."
#: mediagoblin/templates/mediagoblin/user_pages/user.html:96
msgid "Here's a spot to tell others about yourself."
@@ -609,8 +594,11 @@ msgstr "Zhliadnuť všetky výtvory, ktoré vlastní %(username)s"
msgid ""
"This is where your media will appear, but you don't seem to have added "
"anything yet."
-msgstr ""
-"VÅ¡etky tvoje výtvory sa objavia práve tu, ale zatiaľ nemáš niÄ pridané."
+msgstr "VÅ¡etky tvoje výtvory sa objavia práve tu, ale zatiaľ nemáš niÄ pridané."
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
+msgid "Add media"
+msgstr "Pridať výtvor"
#: mediagoblin/templates/mediagoblin/user_pages/user.html:163
#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72
@@ -625,13 +613,18 @@ msgstr "ikona ÄítaÄky"
msgid "Atom feed"
msgstr "ČítaÄka Atom"
-#: mediagoblin/templates/mediagoblin/utils/license.html:21
-msgid "License:"
-msgstr ""
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:25
+msgid "Location"
+msgstr "Poloha"
+
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:38
+#, python-format
+msgid "View on <a href=\"%(osm_url)s\">OpenStreetMap</a>"
+msgstr "Zobraziť na <a href=\"%(osm_url)s\">OpenStreetMap</a>"
#: mediagoblin/templates/mediagoblin/utils/license.html:25
msgid "All rights reserved"
-msgstr ""
+msgstr "Všetky práva vyhradené"
#: mediagoblin/templates/mediagoblin/utils/pagination.html:39
msgid "↠Newer"
@@ -645,50 +638,44 @@ msgstr "Staršie →"
msgid "Go to page:"
msgstr "Prejsť na stránku:"
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:27
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:32
+#: mediagoblin/templates/mediagoblin/utils/prev_next.html:28
+#: mediagoblin/templates/mediagoblin/utils/prev_next.html:33
msgid "newer"
msgstr "novšie"
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:38
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:43
+#: mediagoblin/templates/mediagoblin/utils/prev_next.html:39
+#: mediagoblin/templates/mediagoblin/utils/prev_next.html:44
msgid "older"
msgstr "staršie"
#: mediagoblin/templates/mediagoblin/utils/tags.html:20
-msgid "View more media tagged with"
-msgstr "ZobraziÅ¥ viac výtvorov oznaÄených ako"
+msgid "Tagged with"
+msgstr "OznaÄené ako"
-#: mediagoblin/templates/mediagoblin/utils/tags.html:25
-msgid "or"
-msgstr "alebo"
-
-#: mediagoblin/tools/exif.py:68
+#: mediagoblin/tools/exif.py:75
msgid "Could not read the image file."
-msgstr ""
+msgstr "Nebolo možné preÄítaÅ¥ obrazový súbor."
#: mediagoblin/user_pages/forms.py:30
msgid "I am sure I want to delete this"
msgstr "JednoznaÄne to chcem odstrániÅ¥"
-#: mediagoblin/user_pages/views.py:155
+#: mediagoblin/user_pages/views.py:153
msgid "Oops, your comment was empty."
msgstr "Ajaj, tvoj komentár bol prázdny."
-#: mediagoblin/user_pages/views.py:161
+#: mediagoblin/user_pages/views.py:159
msgid "Your comment has been posted!"
msgstr "Tvoj komentár bol zaslaný!"
-#: mediagoblin/user_pages/views.py:183
+#: mediagoblin/user_pages/views.py:185
msgid "You deleted the media."
msgstr "Výtvor bol tebou odstránený."
-#: mediagoblin/user_pages/views.py:190
+#: mediagoblin/user_pages/views.py:192
msgid "The media was not deleted because you didn't check that you were sure."
msgstr "Výtvor nebol odstránený, nakoľko chýbalo tvoje potvrdenie."
-#: mediagoblin/user_pages/views.py:198
+#: mediagoblin/user_pages/views.py:200
msgid "You are about to delete another user's media. Proceed with caution."
msgstr "Chystáš sa odstrániť výtvory niekoho iného. Dbaj na to."
-
-
diff --git a/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.mo
index daa6b23b..8b1a77e6 100644
--- a/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.mo
+++ b/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.mo
Binary files differ
diff --git a/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.po
index 35fb4841..8edad604 100644
--- a/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.po
+++ b/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.po
@@ -7,9 +7,9 @@
msgid ""
msgstr ""
"Project-Id-Version: GNU MediaGoblin\n"
-"Report-Msgid-Bugs-To: http://bugs.foocorp.net/projects/mediagoblin/issues\n"
-"POT-Creation-Date: 2012-01-29 13:31-0600\n"
-"PO-Revision-Date: 2012-01-29 19:29+0000\n"
+"Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n"
+"POT-Creation-Date: 2012-06-01 16:32-0500\n"
+"PO-Revision-Date: 2012-06-01 21:30+0000\n"
"Last-Translator: cwebber <cwebber@dustycloud.org>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
@@ -19,10 +19,6 @@ msgstr ""
"Language: sl\n"
"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3)\n"
-#: mediagoblin/processing.py:143
-msgid "Invalid file given for media type."
-msgstr "Za vrsto vsebine je bila podana napaÄna datoteka."
-
#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41
msgid "Username"
msgstr "Uporabniško ime"
@@ -35,58 +31,64 @@ msgstr "Geslo"
msgid "Email address"
msgstr "E-poštni naslov"
+#: mediagoblin/auth/forms.py:51
+msgid "Username or email"
+msgstr ""
+
+#: mediagoblin/auth/forms.py:58
+msgid "Incorrect input"
+msgstr ""
+
#: mediagoblin/auth/views.py:55
msgid "Sorry, registration is disabled on this instance."
msgstr "Oprostite, prijava za ta izvod ni omogoÄena."
-#: mediagoblin/auth/views.py:73
+#: mediagoblin/auth/views.py:75
msgid "Sorry, a user with that name already exists."
msgstr "Oprostite, uporabnik s tem imenom že obstaja."
-#: mediagoblin/auth/views.py:77
+#: mediagoblin/auth/views.py:79
msgid "Sorry, a user with that email address already exists."
msgstr ""
-#: mediagoblin/auth/views.py:180
+#: mediagoblin/auth/views.py:182
msgid ""
"Your email address has been verified. You may now login, edit your profile, "
"and submit images!"
-msgstr ""
-"Vaš e-poštni naslov je bil potrjen. Sedaj se lahko prijavite, uredite svoj "
-"profil in pošljete slike."
+msgstr "Vaš e-poštni naslov je bil potrjen. Sedaj se lahko prijavite, uredite svoj profil in pošljete slike."
-#: mediagoblin/auth/views.py:186
+#: mediagoblin/auth/views.py:188
msgid "The verification key or user id is incorrect"
msgstr "Potrditveni kljuÄ ali uporabniÅ¡ka identifikacija je napaÄna"
-#: mediagoblin/auth/views.py:204
+#: 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:212
+#: mediagoblin/auth/views.py:214
msgid "You've already verified your email address!"
msgstr ""
-#: mediagoblin/auth/views.py:225
+#: mediagoblin/auth/views.py:227
msgid "Resent your verification email."
msgstr "Ponovno pošiljanje potrditvene e-pošte."
-#: mediagoblin/auth/views.py:260
+#: mediagoblin/auth/views.py:263
msgid ""
"An email has been sent with instructions on how to change your password."
msgstr ""
-#: mediagoblin/auth/views.py:270
+#: mediagoblin/auth/views.py:273
msgid ""
"Could not send password recovery email as your username is inactive or your "
"account's email address has not been verified."
msgstr ""
-#: mediagoblin/auth/views.py:282
+#: mediagoblin/auth/views.py:285
msgid "Couldn't find someone with that username or email."
msgstr ""
-#: mediagoblin/auth/views.py:330
+#: mediagoblin/auth/views.py:333
msgid "You can now log in using your new password."
msgstr ""
@@ -129,6 +131,7 @@ msgid ""
msgstr ""
#: mediagoblin/edit/forms.py:44 mediagoblin/submit/forms.py:41
+#: mediagoblin/templates/mediagoblin/utils/license.html:20
msgid "License"
msgstr ""
@@ -140,6 +143,10 @@ msgstr "Biografija"
msgid "Website"
msgstr "Spletna stran"
+#: mediagoblin/edit/forms.py:58
+msgid "This address contains errors"
+msgstr ""
+
#: mediagoblin/edit/forms.py:63
msgid "Old password"
msgstr ""
@@ -152,47 +159,48 @@ msgstr ""
msgid "New password"
msgstr ""
-#: mediagoblin/edit/views.py:68
+#: mediagoblin/edit/views.py:67
msgid "An entry with that slug already exists for this user."
msgstr "Vnos s to oznako za tega uporabnika že obstaja."
-#: mediagoblin/edit/views.py:92
+#: mediagoblin/edit/views.py:88
msgid "You are editing another user's media. Proceed with caution."
msgstr "Urejate vsebino drugega uporabnika. Nadaljujte pazljivo."
-#: mediagoblin/edit/views.py:162
+#: mediagoblin/edit/views.py:158
msgid "You are editing a user's profile. Proceed with caution."
msgstr "Urejate uporabniški profil. Nadaljujte pazljivo."
-#: mediagoblin/edit/views.py:180
+#: mediagoblin/edit/views.py:174
msgid "Profile changes saved"
msgstr ""
-#: mediagoblin/edit/views.py:206
+#: mediagoblin/edit/views.py:200
msgid "Wrong password"
msgstr ""
-#: mediagoblin/edit/views.py:222
+#: mediagoblin/edit/views.py:216
msgid "Account settings saved"
msgstr ""
-#: mediagoblin/media_types/__init__.py:77
-msgid "Could not extract any file extension from \"{filename}\""
-msgstr ""
-
-#: mediagoblin/media_types/__init__.py:88
+#: mediagoblin/media_types/__init__.py:60
+#: mediagoblin/media_types/__init__.py:120
msgid "Sorry, I don't support that file type :("
msgstr ""
+#: mediagoblin/processing/__init__.py:127
+msgid "Invalid file given for media type."
+msgstr "Za vrsto vsebine je bila podana napaÄna datoteka."
+
#: mediagoblin/submit/forms.py:26
msgid "File"
msgstr "Datoteka"
-#: mediagoblin/submit/views.py:54
+#: mediagoblin/submit/views.py:56
msgid "You must provide a file."
msgstr "Podati morate datoteko."
-#: mediagoblin/submit/views.py:158
+#: mediagoblin/submit/views.py:163
msgid "Woohoo! Submitted!"
msgstr "Juhej! Poslano."
@@ -212,37 +220,46 @@ msgstr "Oprostite. Videti je, da na tem naslovu ni nobene strani."
msgid ""
"If you're sure the address is correct, maybe the page you're looking for has"
" been moved or deleted."
-msgstr ""
-"ÄŒe ste v toÄnost naslova prepriÄani, je bila iskana stran morda premaknjena "
-"ali pa izbrisana."
+msgstr "ÄŒe ste v toÄnost naslova prepriÄani, je bila iskana stran morda premaknjena ali pa izbrisana."
-#: mediagoblin/templates/mediagoblin/base.html:46
+#: mediagoblin/templates/mediagoblin/base.html:47
msgid "MediaGoblin logo"
msgstr "Logotip MediaGoblin"
-#: mediagoblin/templates/mediagoblin/base.html:51
-#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
-msgid "Add media"
-msgstr "Dodaj vsebino"
-
-#: mediagoblin/templates/mediagoblin/base.html:62
+#: mediagoblin/templates/mediagoblin/base.html:57
msgid "Verify your email!"
msgstr ""
-#: mediagoblin/templates/mediagoblin/base.html:69
-msgid "log out"
+#: mediagoblin/templates/mediagoblin/base.html:63
+msgid "+ Add media"
msgstr ""
-#: mediagoblin/templates/mediagoblin/base.html:72
-#: mediagoblin/templates/mediagoblin/auth/login.html:27
-#: mediagoblin/templates/mediagoblin/auth/login.html:45
+#: mediagoblin/templates/mediagoblin/base.html:65
+msgid "View your profile"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:66
+msgid "Log out"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:71
+#: mediagoblin/templates/mediagoblin/auth/login.html:32
+#: mediagoblin/templates/mediagoblin/auth/login.html:50
msgid "Log in"
msgstr "Prijava"
-#: mediagoblin/templates/mediagoblin/base.html:84
+#: mediagoblin/templates/mediagoblin/base.html:85
msgid ""
"Powered by <a href=\"http://mediagoblin.org\">MediaGoblin</a>, a <a "
-"href=\"http://gnu.org/\">GNU</a> project"
+"href=\"http://gnu.org/\">GNU</a> project."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:88
+#, python-format
+msgid ""
+"Released under the <a "
+"href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a "
+"href=\"%(source_link)s\">Source code</a> available."
msgstr ""
#: mediagoblin/templates/mediagoblin/root.html:24
@@ -311,19 +328,19 @@ msgid ""
"a happy goblin!"
msgstr ""
-#: mediagoblin/templates/mediagoblin/auth/login.html:30
+#: mediagoblin/templates/mediagoblin/auth/login.html:35
msgid "Logging in failed!"
msgstr "Prijava ni uspela."
-#: mediagoblin/templates/mediagoblin/auth/login.html:35
+#: mediagoblin/templates/mediagoblin/auth/login.html:40
msgid "Don't have an account yet?"
msgstr "Å e nimate raÄuna?"
-#: mediagoblin/templates/mediagoblin/auth/login.html:36
+#: mediagoblin/templates/mediagoblin/auth/login.html:41
msgid "Create one here!"
msgstr "Ustvarite si ga."
-#: mediagoblin/templates/mediagoblin/auth/login.html:42
+#: mediagoblin/templates/mediagoblin/auth/login.html:47
msgid "Forgot your password?"
msgstr ""
@@ -344,13 +361,7 @@ msgid ""
"your web browser:\n"
"\n"
"%(verification_url)s"
-msgstr ""
-"Pozdravljeni, %(username)s\n"
-"\n"
-"Za aktivacijo svojega raÄuna GNU MediaGoblin odprite\n"
-"naslednji URL v svojem spletnem brskalniku:\n"
-"\n"
-"%(verification_url)s"
+msgstr "Pozdravljeni, %(username)s\n\nZa aktivacijo svojega raÄuna GNU MediaGoblin odprite\nnaslednji URL v svojem spletnem brskalniku:\n\n%(verification_url)s"
#: mediagoblin/templates/mediagoblin/edit/edit.html:29
#, python-format
@@ -385,18 +396,44 @@ msgid "Media tagged with: %(tag_name)s"
msgstr ""
#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:46
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:53
msgid "Original"
msgstr ""
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:33
+#: 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 <a href=\"http://getfirefox.com\">\n"
+"\t http://getfirefox.com</a>!"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:56
+msgid "Download"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:60
+msgid "original file"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:63
+msgid "WebM file (Vorbis codec)"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:40
msgid ""
"Sorry, this video will not work because \n"
"\t your web browser does not support HTML5 \n"
"\t video."
msgstr ""
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:36
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:43
msgid ""
"You can get a modern web browser that \n"
"\t can play this video at <a href=\"http://getfirefox.com\">\n"
@@ -421,55 +458,49 @@ msgstr ""
msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media"
msgstr "Vsebina uporabnika <a href=\"%(user_url)s\">%(username)s</a>"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:72
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:46
#, python-format
-msgid "Added on %(date)s."
-msgstr ""
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:81
-msgid "Edit"
+msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:85
-msgid "Delete"
-msgstr ""
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:67
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:73
#, python-format
-msgid "%(comment_count)s comment"
+msgid "Image for %(media_title)s"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:93
-#, python-format
-msgid "%(comment_count)s comments"
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:87
+msgid "Edit"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:95
-msgid "No comments yet."
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
+msgid "Delete"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:103
-msgid "Add one"
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:124
+msgid "Add a comment"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:112
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:131
msgid ""
"You can use <a "
"href=\"http://daringfireball.net/projects/markdown/basics\">Markdown</a> for"
" formatting."
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:116
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:135
msgid "Add this comment"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:138
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:154
msgid "at"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:153
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:174
#, python-format
-msgid "<p>â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a></p>"
+msgid ""
+"<h3>Added on</h3>\n"
+" <p>%(date)s</p>"
msgstr ""
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30
@@ -478,7 +509,7 @@ msgid "Really delete %(title)s?"
msgstr ""
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:50
-msgid "Delete Permanently"
+msgid "Delete permanently"
msgstr ""
#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:22
@@ -538,18 +569,14 @@ msgstr "Ponovno pošlji potrditveno e-pošto"
msgid ""
"Someone has registered an account with this username, but it still has to be"
" activated."
-msgstr ""
-"Nekdo je s tem uporabniÅ¡kim imenom že registriral raÄun, vendar mora biti Å¡e"
-" aktiviran."
+msgstr "Nekdo je s tem uporabniÅ¡kim imenom že registriral raÄun, vendar mora biti Å¡e aktiviran."
#: 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 <a "
"href=\"%(login_url)s\">log in</a> and resend it."
-msgstr ""
-"Če ste ta oseba vi, a ste izgubili potrditveno e-pošto, se lahko <a "
-"href=\"%(login_url)s\">prijavite</a> in jo ponovno pošljete."
+msgstr "Če ste ta oseba vi, a ste izgubili potrditveno e-pošto, se lahko <a href=\"%(login_url)s\">prijavite</a> in jo ponovno pošljete."
#: mediagoblin/templates/mediagoblin/user_pages/user.html:96
msgid "Here's a spot to tell others about yourself."
@@ -579,6 +606,10 @@ msgid ""
"anything yet."
msgstr "Tu bo prikazana vaÅ¡a vsebina, a trenutno Å¡e niste dodali niÄ."
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
+msgid "Add media"
+msgstr "Dodaj vsebino"
+
#: mediagoblin/templates/mediagoblin/user_pages/user.html:163
#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72
msgid "There doesn't seem to be any media here yet..."
@@ -592,8 +623,13 @@ msgstr "Ikona vira"
msgid "Atom feed"
msgstr "Ikona Atom"
-#: mediagoblin/templates/mediagoblin/utils/license.html:21
-msgid "License:"
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:25
+msgid "Location"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:38
+#, python-format
+msgid "View on <a href=\"%(osm_url)s\">OpenStreetMap</a>"
msgstr ""
#: mediagoblin/templates/mediagoblin/utils/license.html:25
@@ -612,25 +648,21 @@ msgstr ""
msgid "Go to page:"
msgstr ""
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:27
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:32
+#: 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:38
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:43
+#: 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 "View more media tagged with"
+msgid "Tagged with"
msgstr ""
-#: mediagoblin/templates/mediagoblin/utils/tags.html:25
-msgid "or"
-msgstr ""
-
-#: mediagoblin/tools/exif.py:68
+#: mediagoblin/tools/exif.py:75
msgid "Could not read the image file."
msgstr ""
@@ -638,24 +670,22 @@ msgstr ""
msgid "I am sure I want to delete this"
msgstr ""
-#: mediagoblin/user_pages/views.py:155
+#: mediagoblin/user_pages/views.py:153
msgid "Oops, your comment was empty."
msgstr ""
-#: mediagoblin/user_pages/views.py:161
+#: mediagoblin/user_pages/views.py:159
msgid "Your comment has been posted!"
msgstr ""
-#: mediagoblin/user_pages/views.py:183
+#: mediagoblin/user_pages/views.py:185
msgid "You deleted the media."
msgstr ""
-#: mediagoblin/user_pages/views.py:190
+#: mediagoblin/user_pages/views.py:192
msgid "The media was not deleted because you didn't check that you were sure."
msgstr ""
-#: mediagoblin/user_pages/views.py:198
+#: mediagoblin/user_pages/views.py:200
msgid "You are about to delete another user's media. Proceed with caution."
msgstr ""
-
-
diff --git a/mediagoblin/i18n/sq/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/sq/LC_MESSAGES/mediagoblin.mo
new file mode 100644
index 00000000..b349fcec
--- /dev/null
+++ b/mediagoblin/i18n/sq/LC_MESSAGES/mediagoblin.mo
Binary files differ
diff --git a/mediagoblin/i18n/sq/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/sq/LC_MESSAGES/mediagoblin.po
new file mode 100644
index 00000000..d013fe7d
--- /dev/null
+++ b/mediagoblin/i18n/sq/LC_MESSAGES/mediagoblin.po
@@ -0,0 +1,680 @@
+# Translations template for PROJECT.
+# Copyright (C) 2012 ORGANIZATION
+# This file is distributed under the same license as the PROJECT project.
+#
+# Translators:
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
+msgid ""
+msgstr ""
+"Project-Id-Version: GNU MediaGoblin\n"
+"Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n"
+"POT-Creation-Date: 2012-04-30 10:48-0500\n"
+"PO-Revision-Date: 2012-06-01 21:26+0000\n"
+"Last-Translator: Besnik <besnik@programeshqip.org>\n"
+"Language-Team: Albanian (http://www.transifex.net/projects/p/mediagoblin/language/sq/)\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: sq\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+
+#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41
+msgid "Username"
+msgstr "Emër përdoruesi"
+
+#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45
+msgid "Password"
+msgstr "Fjalëkalim"
+
+#: mediagoblin/auth/forms.py:34
+msgid "Email address"
+msgstr "Adresë email"
+
+#: mediagoblin/auth/forms.py:51
+msgid "Username or email"
+msgstr "Emër përdoruesi ose email"
+
+#: mediagoblin/auth/forms.py:58
+msgid "Incorrect input"
+msgstr "Futje e pasaktë"
+
+#: mediagoblin/auth/views.py:55
+msgid "Sorry, registration is disabled on this instance."
+msgstr "Na njdeni, regjistrimi në këtë instancë të shërbimit është i çaktivizuar."
+
+#: mediagoblin/auth/views.py:75
+msgid "Sorry, a user with that name already exists."
+msgstr "Na ndjeni, ka tashmë një përdorues me këtë emër."
+
+#: mediagoblin/auth/views.py:79
+msgid "Sorry, a user with that email address already exists."
+msgstr "Na ndjeni, ka tashmë një përdorues me këtë adresë email."
+
+#: mediagoblin/auth/views.py:182
+msgid ""
+"Your email address has been verified. You may now login, edit your profile, "
+"and submit images!"
+msgstr "Adresa juaj email u verifikua. Tani mund të bëni hyrjen, të përpunoni profilin tuaj, dhe të parashtroni figura!"
+
+#: mediagoblin/auth/views.py:188
+msgid "The verification key or user id is incorrect"
+msgstr "Kyçi i verifikimit ose id-ja e përdoruesit është e pasaktë"
+
+#: mediagoblin/auth/views.py:206
+msgid "You must be logged in so we know who to send the email to!"
+msgstr "Duhet të jeni i futur, që ta dimë kujt t'ia çojmë email-in!"
+
+#: mediagoblin/auth/views.py:214
+msgid "You've already verified your email address!"
+msgstr "Thuajse e keni verifikuar adresën tuaj email!"
+
+#: mediagoblin/auth/views.py:227
+msgid "Resent your verification email."
+msgstr "Ridërgoni email-in tuaj të verifikimit."
+
+#: mediagoblin/auth/views.py:263
+msgid ""
+"An email has been sent with instructions on how to change your password."
+msgstr "Është dërguar një email me udhëzime se si të ndryshoni fjalëkalimin tuaj."
+
+#: mediagoblin/auth/views.py:273
+msgid ""
+"Could not send password recovery email as your username is inactive or your "
+"account's email address has not been verified."
+msgstr "Email-i i ricaktimit të fjalëkalimit nuk u dërgua dot, ngaqë emri juaj i përdoruesit nuk është aktivizuar ose adresa email e llogarisë suaj nuk është verifikuar."
+
+#: mediagoblin/auth/views.py:285
+msgid "Couldn't find someone with that username or email."
+msgstr "Nuk u gjet dot dikush me atë emër përdoruesi ose email."
+
+#: mediagoblin/auth/views.py:333
+msgid "You can now log in using your new password."
+msgstr "Tani mun të hyni duke përdorur fjalëkalimin tuaj të ri."
+
+#: mediagoblin/edit/forms.py:25 mediagoblin/submit/forms.py:28
+msgid "Title"
+msgstr "Titull"
+
+#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:31
+msgid "Description of this work"
+msgstr "Përshkrim i kësaj pune"
+
+#: mediagoblin/edit/forms.py:29 mediagoblin/edit/forms.py:52
+#: mediagoblin/submit/forms.py:32
+msgid ""
+"You can use\n"
+" <a href=\"http://daringfireball.net/projects/markdown/basics\">\n"
+" Markdown</a> for formatting."
+msgstr "Mund të përdorni\n <a href=\"http://daringfireball.net/projects/markdown/basics\">\n Markdown</a> për formatim."
+
+#: mediagoblin/edit/forms.py:33 mediagoblin/submit/forms.py:36
+msgid "Tags"
+msgstr "Etiketa"
+
+#: mediagoblin/edit/forms.py:35 mediagoblin/submit/forms.py:38
+msgid "Separate tags by commas."
+msgstr "Ndajini etiketat me presje."
+
+#: mediagoblin/edit/forms.py:38
+msgid "Slug"
+msgstr "Identifikues"
+
+#: mediagoblin/edit/forms.py:39
+msgid "The slug can't be empty"
+msgstr "Identifikuesi s'mund të jetë i zbrazët"
+
+#: mediagoblin/edit/forms.py:40
+msgid ""
+"The title part of this media's address. You usually don't need to change "
+"this."
+msgstr "Titulli i adresës së kësaj medie. Zakonisht nuk keni nevojë ta ndryshoni këtë."
+
+#: mediagoblin/edit/forms.py:44 mediagoblin/submit/forms.py:41
+#: mediagoblin/templates/mediagoblin/utils/license.html:20
+msgid "License"
+msgstr "Leje"
+
+#: mediagoblin/edit/forms.py:50
+msgid "Bio"
+msgstr "Jetëshkrim"
+
+#: mediagoblin/edit/forms.py:56
+msgid "Website"
+msgstr "Site Web"
+
+#: mediagoblin/edit/forms.py:58
+msgid "This address contains errors"
+msgstr "Kjo adresë përmban gabime"
+
+#: mediagoblin/edit/forms.py:63
+msgid "Old password"
+msgstr "Fjalëkalimi i vjetër"
+
+#: mediagoblin/edit/forms.py:65
+msgid "Enter your old password to prove you own this account."
+msgstr "Jepni fjalëkalimin tuaj të vjetër që të provohet se këtë llogari e zotëroni ju."
+
+#: mediagoblin/edit/forms.py:68
+msgid "New password"
+msgstr "Fjalëkalimi i ri"
+
+#: mediagoblin/edit/views.py:67
+msgid "An entry with that slug already exists for this user."
+msgstr "Ka tashmë një zë me atë identifikues për këtë përdorues."
+
+#: mediagoblin/edit/views.py:88
+msgid "You are editing another user's media. Proceed with caution."
+msgstr "Po përpunoni media të një tjetër përdoruesi. Bëni kujdes."
+
+#: mediagoblin/edit/views.py:158
+msgid "You are editing a user's profile. Proceed with caution."
+msgstr "Po përpunoni profilin e një përdoruesi. Bëni kujdes."
+
+#: mediagoblin/edit/views.py:174
+msgid "Profile changes saved"
+msgstr "Ndryshimet e profilit u ruajtën"
+
+#: mediagoblin/edit/views.py:200
+msgid "Wrong password"
+msgstr "Fjalëkalim i gabuar"
+
+#: mediagoblin/edit/views.py:216
+msgid "Account settings saved"
+msgstr "Rregullimet e llogarisë u ruajtën"
+
+#: mediagoblin/media_types/__init__.py:60
+#: mediagoblin/media_types/__init__.py:120
+msgid "Sorry, I don't support that file type :("
+msgstr "Na ndjeni, nuk e mbullojmë këtë lloj kartele :("
+
+#: mediagoblin/processing/__init__.py:127
+msgid "Invalid file given for media type."
+msgstr "Kartelë e gabuar e dhënë për llojin e medias."
+
+#: mediagoblin/submit/forms.py:26
+msgid "File"
+msgstr "Kartelë"
+
+#: mediagoblin/submit/views.py:56
+msgid "You must provide a file."
+msgstr "Duhet të jepni një kartelë."
+
+#: mediagoblin/submit/views.py:163
+msgid "Woohoo! Submitted!"
+msgstr "Yhaaaaaa! U parashtrua!"
+
+#: mediagoblin/templates/mediagoblin/404.html:22
+msgid "Image of 404 goblin stressing out"
+msgstr "Figurë 404 e djallushit në siklet"
+
+#: mediagoblin/templates/mediagoblin/404.html:23
+msgid "Oops!"
+msgstr "Oooh!"
+
+#: mediagoblin/templates/mediagoblin/404.html:24
+msgid "There doesn't seem to be a page at this address. Sorry!"
+msgstr "Nuk duket të ketë ndonjë faqe te kjo adresë. Na ndjeni!"
+
+#: mediagoblin/templates/mediagoblin/404.html:26
+msgid ""
+"If you're sure the address is correct, maybe the page you're looking for has"
+" been moved or deleted."
+msgstr "Nëse jeni i sigurt se adresa është e saktë, ndoshta faqja që po kërkoni është fshirë ose kaluar gjetkë."
+
+#: mediagoblin/templates/mediagoblin/base.html:47
+msgid "MediaGoblin logo"
+msgstr "Logoja e MediaGoblin-it"
+
+#: mediagoblin/templates/mediagoblin/base.html:57
+msgid "Verify your email!"
+msgstr "Verifikoni email-in tuaj!"
+
+#: mediagoblin/templates/mediagoblin/base.html:63
+msgid "+ Add media"
+msgstr "+ Shtoni media"
+
+#: mediagoblin/templates/mediagoblin/base.html:65
+msgid "View your profile"
+msgstr "Shihni profilin tuaj"
+
+#: mediagoblin/templates/mediagoblin/base.html:66
+msgid "Log out"
+msgstr "Dilni"
+
+#: mediagoblin/templates/mediagoblin/base.html:71
+#: mediagoblin/templates/mediagoblin/auth/login.html:32
+#: mediagoblin/templates/mediagoblin/auth/login.html:50
+msgid "Log in"
+msgstr "Hyni"
+
+#: mediagoblin/templates/mediagoblin/base.html:85
+msgid ""
+"Powered by <a href=\"http://mediagoblin.org\">MediaGoblin</a>, a <a "
+"href=\"http://gnu.org/\">GNU</a> project."
+msgstr "Bazuar në <a href=\"http://mediagoblin.org\">MediaGoblin</a>, një projekt <a href=\"http://gnu.org/\">GNU</a>."
+
+#: mediagoblin/templates/mediagoblin/base.html:88
+#, python-format
+msgid ""
+"Released under the <a "
+"href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a "
+"href=\"%(source_link)s\">Source code</a> available."
+msgstr "Hedhur në qarkullim sipas <a href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL-së</a>. <a href=\"%(source_link)s\">Kodi burim</a> është i passhëm."
+
+#: mediagoblin/templates/mediagoblin/root.html:24
+msgid "Explore"
+msgstr "Eksploroni"
+
+#: mediagoblin/templates/mediagoblin/root.html:26
+msgid "Hi there, welcome to this MediaGoblin site!"
+msgstr "Tungjatjeta juaj, mirë se vini te ky site MediaGoblin!"
+
+#: mediagoblin/templates/mediagoblin/root.html:28
+msgid ""
+"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, an "
+"extraordinarily great piece of media hosting software."
+msgstr "Ky site përdor <a href=\"http://mediagoblin.org\">MediaGoblin</a>, një program jashtëzakonisht i shkëlqyer për strehim mediash."
+
+#: mediagoblin/templates/mediagoblin/root.html:29
+msgid ""
+"To add your own media, place comments, save your favourites and more, you "
+"can log in with your MediaGoblin account."
+msgstr "Që të shtoni median tuaj, të bëni komente, të ruani të parapëlqyerat tuaj, dhe të tjera gjëra të tilla, mund të hyni përmes llogarisë suaj MediaGoblin."
+
+#: mediagoblin/templates/mediagoblin/root.html:31
+msgid "Don't have one yet? It's easy!"
+msgstr "Nuk keni ende një të tillë? Është e lehtë!"
+
+#: mediagoblin/templates/mediagoblin/root.html:32
+#, python-format
+msgid ""
+"<a class=\"button_action_highlight\" href=\"%(register_url)s\">Create an account at this site</a>\n"
+" or\n"
+" <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">Set up MediaGoblin on your own server</a>"
+msgstr "<a class=\"button_action_highlight\" href=\"%(register_url)s\">Krijoni një llogarin te ky site</a>\n ose\n <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">Instaloni dhe rregulloni MediaGoblin-in te shërbyesi juaj</a>"
+
+#: mediagoblin/templates/mediagoblin/root.html:40
+msgid "Most recent media"
+msgstr "Mediat më të reja"
+
+#: mediagoblin/templates/mediagoblin/auth/change_fp.html:32
+msgid "Set your new password"
+msgstr "Caktoni fjalëkalimin tuaj të ri"
+
+#: mediagoblin/templates/mediagoblin/auth/change_fp.html:35
+msgid "Set password"
+msgstr "Caktoni fjalëkalim"
+
+#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27
+msgid "Recover password"
+msgstr "Rimerrni fjalëkalimin"
+
+#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:30
+msgid "Send instructions"
+msgstr "Dërgo udhëzime"
+
+#: 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 "Njatjeta %(username)s,\n\nqë të ndryshoni fjalëkalimin tuaj për GNU MediaGoblin, hapeni URL-në vijuese në \nshfletuesin tuaj web:\n\n%(verification_url)s\n\nNëse mendoni se këtu ka gabim, thjesht shpërfilleni këtë email dhe vazhdoni të jeni\nnjë djallush i lumtur!"
+
+#: mediagoblin/templates/mediagoblin/auth/login.html:35
+msgid "Logging in failed!"
+msgstr "Hyrja dështoi!"
+
+#: mediagoblin/templates/mediagoblin/auth/login.html:40
+msgid "Don't have an account yet?"
+msgstr "Nuk keni ende një llogari?"
+
+#: mediagoblin/templates/mediagoblin/auth/login.html:41
+msgid "Create one here!"
+msgstr "Krijoni një këtu!"
+
+#: mediagoblin/templates/mediagoblin/auth/login.html:47
+msgid "Forgot your password?"
+msgstr "Harruat fjalëkalimin tuaj?"
+
+#: mediagoblin/templates/mediagoblin/auth/register.html:32
+msgid "Create an account!"
+msgstr "Krijoni një llogari!"
+
+#: mediagoblin/templates/mediagoblin/auth/register.html:36
+msgid "Create"
+msgstr "Krijoje"
+
+#: 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 "Njatjeta %(username)s,\n\nqë të aktivizoni llogarinë tuaj te GNU MediaGoblin hapeni URL-në vijuese te\nshfletuesi juaj web:\n\n%(verification_url)s"
+
+#: mediagoblin/templates/mediagoblin/edit/edit.html:29
+#, python-format
+msgid "Editing %(media_title)s"
+msgstr "Po përpunohet %(media_title)s"
+
+#: mediagoblin/templates/mediagoblin/edit/edit.html:36
+#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49
+msgid "Cancel"
+msgstr "Anuloje"
+
+#: mediagoblin/templates/mediagoblin/edit/edit.html:37
+#: mediagoblin/templates/mediagoblin/edit/edit_account.html:40
+#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:35
+msgid "Save changes"
+msgstr "Ruaji ndryshimet"
+
+#: mediagoblin/templates/mediagoblin/edit/edit_account.html:34
+#, python-format
+msgid "Changing %(username)s's account settings"
+msgstr "Po ndryshohen rregullimet e llogarisë %(username)s"
+
+#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29
+#, python-format
+msgid "Editing %(username)s's profile"
+msgstr "Po përpunohet profili i %(username)s"
+
+#: mediagoblin/templates/mediagoblin/listings/tag.html:30
+#: mediagoblin/templates/mediagoblin/listings/tag.html:35
+#, python-format
+msgid "Media tagged with: %(tag_name)s"
+msgstr "Media e etiketuar me:: %(tag_name)s"
+
+#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:57
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:53
+msgid "Original"
+msgstr "Origjinal"
+
+#: 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 "Na ndjeni, zëri s'do të funksionojë, ngaqë \n\tshfletuesi juaj s'mbulon audio HTML5."
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:47
+msgid ""
+"You can get a modern web browser that \n"
+"\tcan play the audio at <a href=\"http://getfirefox.com\">\n"
+"\t http://getfirefox.com</a>!"
+msgstr "Një shfletues web modern që mund të luajë \n\taudion mund ta merrni te <a href=\"http://getfirefox.com\">\n\t http://getfirefox.com</a>!"
+
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:40
+msgid ""
+"Sorry, this video will not work because \n"
+"\t your web browser does not support HTML5 \n"
+"\t video."
+msgstr "Na ndjeni, kjo video s'do të funksionojë, ngaqë \n\t shfletuesi juaj web s'mbulon video HTML5."
+
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:43
+msgid ""
+"You can get a modern web browser that \n"
+"\t can play this video at <a href=\"http://getfirefox.com\">\n"
+"\t http://getfirefox.com</a>!"
+msgstr "Një shfletues web modern që \n\t mund ta luajë këtë video mund ta merrni te <a href=\"http://getfirefox.com\">\n\t http://getfirefox.com</a>!"
+
+#: mediagoblin/templates/mediagoblin/submit/start.html:26
+msgid "Add your media"
+msgstr "Shtoni media tuajën"
+
+#: mediagoblin/templates/mediagoblin/submit/start.html:30
+msgid "Add"
+msgstr "Shtoni"
+
+#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30
+#, python-format
+msgid "%(username)s's media"
+msgstr "Media nga %(username)s"
+
+#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:37
+#, python-format
+msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media"
+msgstr "Media nga <a href=\"%(user_url)s\">%(username)s</a>"
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:46
+#, python-format
+msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>"
+msgstr "â– Po shfletoni media nga <a href=\"%(user_url)s\">%(username)s</a>"
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:67
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:73
+#, python-format
+msgid "Image for %(media_title)s"
+msgstr "Figurë për %(media_title)s"
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:87
+msgid "Edit"
+msgstr "Përpunoni"
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
+msgid "Delete"
+msgstr "Fshije"
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:124
+msgid "Add a comment"
+msgstr "Shtoni një koment"
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:131
+msgid ""
+"You can use <a "
+"href=\"http://daringfireball.net/projects/markdown/basics\">Markdown</a> for"
+" formatting."
+msgstr "Për formatime mund të përdorni <a href=\"http://daringfireball.net/projects/markdown/basics\">Markdown</a>."
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:135
+msgid "Add this comment"
+msgstr "Shtoje këtë koment"
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:154
+msgid "at"
+msgstr "te"
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:174
+#, python-format
+msgid ""
+"<h3>Added on</h3>\n"
+" <p>%(date)s</p>"
+msgstr "<h3>Shtuar më</h3>\n <p>%(date)s</p>"
+
+#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30
+#, python-format
+msgid "Really delete %(title)s?"
+msgstr "Të fshihet vërtet %(title)s?"
+
+#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:50
+msgid "Delete permanently"
+msgstr "Fshije përgjithmonë"
+
+#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:22
+msgid "Media processing panel"
+msgstr "Paneli i Përpunimit të Medias"
+
+#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:25
+msgid ""
+"You can track the state of media being processed for your gallery here."
+msgstr "Gjendjen e medias që po përpunohet për galerinë tuaj mund ta ndiqni nga këtu."
+
+#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:28
+msgid "Media in-processing"
+msgstr "Media në përpunim"
+
+#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:46
+msgid "No media in-processing"
+msgstr "Pa media në përpunim"
+
+#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:50
+msgid "These uploads failed to process:"
+msgstr "Nuk arritën të kryheshin këto ngarkime:"
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:31
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:89
+#, python-format
+msgid "%(username)s's profile"
+msgstr "Profili i %(username)s"
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:43
+msgid "Sorry, no such user found."
+msgstr "Na ndjeni, nuk u gjet përdorues i tillë."
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:50
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:70
+msgid "Email verification needed"
+msgstr "Lypset verifikimi i email-it"
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:53
+msgid "Almost done! Your account still needs to be activated."
+msgstr "Pothuajse mbaruam! Llogaria juaj ende lyp aktivizimin."
+
+#: 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 "Brenda pak çastesh duhet t'ju mbërrijë një email me udhëzime se si të krhyet kjo."
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:62
+msgid "In case it doesn't:"
+msgstr "Në rast se jo:"
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:65
+msgid "Resend verification email"
+msgstr "Ridërgo email-in e verifikimit"
+
+#: 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 "Dikush ka regjistruar një llogari me këtë emër përdoruesi, por ajo duhet aktivizuar."
+
+#: 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 <a "
+"href=\"%(login_url)s\">log in</a> and resend it."
+msgstr "Nëse jeni ju ai person, por keni humbur email-in tuaj të verifikimit, mund të <a href=\"%(login_url)s\">hyni</a> dhe ta ridërgoni."
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:96
+msgid "Here's a spot to tell others about yourself."
+msgstr "Ja një vend t'i tregoni botës mbi veten."
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:101
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:118
+msgid "Edit profile"
+msgstr "Përpunoni profil"
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:106
+msgid "This user hasn't filled in their profile (yet)."
+msgstr "Ky përdorues nuk e ka plotësuar (ende) profilin e vet."
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:125
+msgid "Change account settings"
+msgstr "Ndryshoni rregullime llogarie"
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:138
+#, python-format
+msgid "View all of %(username)s's media"
+msgstr "Shihni krejt mediat nga %(username)s"
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:151
+msgid ""
+"This is where your media will appear, but you don't seem to have added "
+"anything yet."
+msgstr "Media juaj do të shfaqet këtu, por nuk duket të keni shtuar gjë ende."
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
+msgid "Add media"
+msgstr "Shtoni media"
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:163
+#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72
+msgid "There doesn't seem to be any media here yet..."
+msgstr "Nuk duket ende të ketë ndonjë media këtu..."
+
+#: mediagoblin/templates/mediagoblin/utils/feed_link.html:21
+msgid "feed icon"
+msgstr "ikonë prurjesh"
+
+#: mediagoblin/templates/mediagoblin/utils/feed_link.html:23
+msgid "Atom feed"
+msgstr "Prurje Atom"
+
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:25
+msgid "Location"
+msgstr "Vend"
+
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:38
+#, python-format
+msgid "View on <a href=\"%(osm_url)s\">OpenStreetMap</a>"
+msgstr "Shiheni te <a href=\"%(osm_url)s\">OpenStreetMap</a>"
+
+#: mediagoblin/templates/mediagoblin/utils/license.html:25
+msgid "All rights reserved"
+msgstr "Tërë të drejtat të rezervuara"
+
+#: mediagoblin/templates/mediagoblin/utils/pagination.html:39
+msgid "↠Newer"
+msgstr "↠Më të reja"
+
+#: mediagoblin/templates/mediagoblin/utils/pagination.html:45
+msgid "Older →"
+msgstr "Më të vjetra →"
+
+#: mediagoblin/templates/mediagoblin/utils/pagination.html:48
+msgid "Go to page:"
+msgstr "Shko te faqja:"
+
+#: mediagoblin/templates/mediagoblin/utils/prev_next.html:28
+#: mediagoblin/templates/mediagoblin/utils/prev_next.html:33
+msgid "newer"
+msgstr "më të reja"
+
+#: mediagoblin/templates/mediagoblin/utils/prev_next.html:39
+#: mediagoblin/templates/mediagoblin/utils/prev_next.html:44
+msgid "older"
+msgstr "më të vjetra"
+
+#: mediagoblin/templates/mediagoblin/utils/tags.html:20
+msgid "Tagged with"
+msgstr "Etiketuar me"
+
+#: mediagoblin/tools/exif.py:75
+msgid "Could not read the image file."
+msgstr "Nuk lexoi dot kartelën e figurës."
+
+#: mediagoblin/user_pages/forms.py:30
+msgid "I am sure I want to delete this"
+msgstr "Jam i sigurt që dua të fshihet kjo"
+
+#: mediagoblin/user_pages/views.py:153
+msgid "Oops, your comment was empty."
+msgstr "Hmmm, komenti juaj qe i zbrazët."
+
+#: mediagoblin/user_pages/views.py:159
+msgid "Your comment has been posted!"
+msgstr "Komenti juaj u postua!"
+
+#: mediagoblin/user_pages/views.py:185
+msgid "You deleted the media."
+msgstr "E fshitë median."
+
+#: mediagoblin/user_pages/views.py:192
+msgid "The media was not deleted because you didn't check that you were sure."
+msgstr "Media nuk u fshi ngaqë nuk i vutë shenjë pohimit se jeni i sigurt."
+
+#: mediagoblin/user_pages/views.py:200
+msgid "You are about to delete another user's media. Proceed with caution."
+msgstr "Ju ndan një hap nga fshirja e medias të një tjetër përdoruesi. Bëni kujdes."
diff --git a/mediagoblin/i18n/sr/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/sr/LC_MESSAGES/mediagoblin.mo
index 8191444c..bbecfadd 100644
--- a/mediagoblin/i18n/sr/LC_MESSAGES/mediagoblin.mo
+++ b/mediagoblin/i18n/sr/LC_MESSAGES/mediagoblin.mo
Binary files differ
diff --git a/mediagoblin/i18n/sr/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/sr/LC_MESSAGES/mediagoblin.po
index e0f59766..244b34d0 100644
--- a/mediagoblin/i18n/sr/LC_MESSAGES/mediagoblin.po
+++ b/mediagoblin/i18n/sr/LC_MESSAGES/mediagoblin.po
@@ -6,11 +6,11 @@
msgid ""
msgstr ""
"Project-Id-Version: GNU MediaGoblin\n"
-"Report-Msgid-Bugs-To: http://bugs.foocorp.net/projects/mediagoblin/issues\n"
-"POT-Creation-Date: 2012-01-29 13:31-0600\n"
-"PO-Revision-Date: 2012-01-29 19:29+0000\n"
+"Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n"
+"POT-Creation-Date: 2012-06-01 16:32-0500\n"
+"PO-Revision-Date: 2012-06-01 21:30+0000\n"
"Last-Translator: cwebber <cwebber@dustycloud.org>\n"
-"Language-Team: Serbian (http://www.transifex.net/projects/p/mediagoblin/team/sr/)\n"
+"Language-Team: Serbian (http://www.transifex.net/projects/p/mediagoblin/language/sr/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -18,10 +18,6 @@ msgstr ""
"Language: sr\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n"
-#: mediagoblin/processing.py:143
-msgid "Invalid file given for media type."
-msgstr ""
-
#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41
msgid "Username"
msgstr ""
@@ -34,56 +30,64 @@ msgstr ""
msgid "Email address"
msgstr ""
+#: mediagoblin/auth/forms.py:51
+msgid "Username or email"
+msgstr ""
+
+#: mediagoblin/auth/forms.py:58
+msgid "Incorrect input"
+msgstr ""
+
#: mediagoblin/auth/views.py:55
msgid "Sorry, registration is disabled on this instance."
msgstr ""
-#: mediagoblin/auth/views.py:73
+#: mediagoblin/auth/views.py:75
msgid "Sorry, a user with that name already exists."
msgstr ""
-#: mediagoblin/auth/views.py:77
+#: mediagoblin/auth/views.py:79
msgid "Sorry, a user with that email address already exists."
msgstr ""
-#: mediagoblin/auth/views.py:180
+#: 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:186
+#: mediagoblin/auth/views.py:188
msgid "The verification key or user id is incorrect"
msgstr ""
-#: mediagoblin/auth/views.py:204
+#: 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:212
+#: mediagoblin/auth/views.py:214
msgid "You've already verified your email address!"
msgstr ""
-#: mediagoblin/auth/views.py:225
+#: mediagoblin/auth/views.py:227
msgid "Resent your verification email."
msgstr ""
-#: mediagoblin/auth/views.py:260
+#: mediagoblin/auth/views.py:263
msgid ""
"An email has been sent with instructions on how to change your password."
msgstr ""
-#: mediagoblin/auth/views.py:270
+#: mediagoblin/auth/views.py:273
msgid ""
"Could not send password recovery email as your username is inactive or your "
"account's email address has not been verified."
msgstr ""
-#: mediagoblin/auth/views.py:282
+#: mediagoblin/auth/views.py:285
msgid "Couldn't find someone with that username or email."
msgstr ""
-#: mediagoblin/auth/views.py:330
+#: mediagoblin/auth/views.py:333
msgid "You can now log in using your new password."
msgstr ""
@@ -126,6 +130,7 @@ msgid ""
msgstr ""
#: mediagoblin/edit/forms.py:44 mediagoblin/submit/forms.py:41
+#: mediagoblin/templates/mediagoblin/utils/license.html:20
msgid "License"
msgstr ""
@@ -137,6 +142,10 @@ msgstr ""
msgid "Website"
msgstr ""
+#: mediagoblin/edit/forms.py:58
+msgid "This address contains errors"
+msgstr ""
+
#: mediagoblin/edit/forms.py:63
msgid "Old password"
msgstr ""
@@ -149,47 +158,48 @@ msgstr ""
msgid "New password"
msgstr ""
-#: mediagoblin/edit/views.py:68
+#: mediagoblin/edit/views.py:67
msgid "An entry with that slug already exists for this user."
msgstr ""
-#: mediagoblin/edit/views.py:92
+#: mediagoblin/edit/views.py:88
msgid "You are editing another user's media. Proceed with caution."
msgstr ""
-#: mediagoblin/edit/views.py:162
+#: mediagoblin/edit/views.py:158
msgid "You are editing a user's profile. Proceed with caution."
msgstr ""
-#: mediagoblin/edit/views.py:180
+#: mediagoblin/edit/views.py:174
msgid "Profile changes saved"
msgstr ""
-#: mediagoblin/edit/views.py:206
+#: mediagoblin/edit/views.py:200
msgid "Wrong password"
msgstr ""
-#: mediagoblin/edit/views.py:222
+#: mediagoblin/edit/views.py:216
msgid "Account settings saved"
msgstr ""
-#: mediagoblin/media_types/__init__.py:77
-msgid "Could not extract any file extension from \"{filename}\""
+#: mediagoblin/media_types/__init__.py:60
+#: mediagoblin/media_types/__init__.py:120
+msgid "Sorry, I don't support that file type :("
msgstr ""
-#: mediagoblin/media_types/__init__.py:88
-msgid "Sorry, I don't support that file type :("
+#: mediagoblin/processing/__init__.py:127
+msgid "Invalid file given for media type."
msgstr ""
#: mediagoblin/submit/forms.py:26
msgid "File"
msgstr ""
-#: mediagoblin/submit/views.py:54
+#: mediagoblin/submit/views.py:56
msgid "You must provide a file."
msgstr ""
-#: mediagoblin/submit/views.py:158
+#: mediagoblin/submit/views.py:163
msgid "Woohoo! Submitted!"
msgstr ""
@@ -211,33 +221,44 @@ msgid ""
" been moved or deleted."
msgstr ""
-#: mediagoblin/templates/mediagoblin/base.html:46
+#: mediagoblin/templates/mediagoblin/base.html:47
msgid "MediaGoblin logo"
msgstr ""
-#: mediagoblin/templates/mediagoblin/base.html:51
-#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
-msgid "Add media"
+#: mediagoblin/templates/mediagoblin/base.html:57
+msgid "Verify your email!"
msgstr ""
-#: mediagoblin/templates/mediagoblin/base.html:62
-msgid "Verify your email!"
+#: mediagoblin/templates/mediagoblin/base.html:63
+msgid "+ Add media"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:65
+msgid "View your profile"
msgstr ""
-#: mediagoblin/templates/mediagoblin/base.html:69
-msgid "log out"
+#: mediagoblin/templates/mediagoblin/base.html:66
+msgid "Log out"
msgstr ""
-#: mediagoblin/templates/mediagoblin/base.html:72
-#: mediagoblin/templates/mediagoblin/auth/login.html:27
-#: mediagoblin/templates/mediagoblin/auth/login.html:45
+#: mediagoblin/templates/mediagoblin/base.html:71
+#: mediagoblin/templates/mediagoblin/auth/login.html:32
+#: mediagoblin/templates/mediagoblin/auth/login.html:50
msgid "Log in"
msgstr ""
-#: mediagoblin/templates/mediagoblin/base.html:84
+#: mediagoblin/templates/mediagoblin/base.html:85
msgid ""
"Powered by <a href=\"http://mediagoblin.org\">MediaGoblin</a>, a <a "
-"href=\"http://gnu.org/\">GNU</a> project"
+"href=\"http://gnu.org/\">GNU</a> project."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:88
+#, python-format
+msgid ""
+"Released under the <a "
+"href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a "
+"href=\"%(source_link)s\">Source code</a> available."
msgstr ""
#: mediagoblin/templates/mediagoblin/root.html:24
@@ -306,19 +327,19 @@ msgid ""
"a happy goblin!"
msgstr ""
-#: mediagoblin/templates/mediagoblin/auth/login.html:30
+#: mediagoblin/templates/mediagoblin/auth/login.html:35
msgid "Logging in failed!"
msgstr ""
-#: mediagoblin/templates/mediagoblin/auth/login.html:35
+#: mediagoblin/templates/mediagoblin/auth/login.html:40
msgid "Don't have an account yet?"
msgstr ""
-#: mediagoblin/templates/mediagoblin/auth/login.html:36
+#: mediagoblin/templates/mediagoblin/auth/login.html:41
msgid "Create one here!"
msgstr ""
-#: mediagoblin/templates/mediagoblin/auth/login.html:42
+#: mediagoblin/templates/mediagoblin/auth/login.html:47
msgid "Forgot your password?"
msgstr ""
@@ -374,18 +395,44 @@ msgid "Media tagged with: %(tag_name)s"
msgstr ""
#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:46
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:53
msgid "Original"
msgstr ""
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:33
+#: 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 <a href=\"http://getfirefox.com\">\n"
+"\t http://getfirefox.com</a>!"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:56
+msgid "Download"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:60
+msgid "original file"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:63
+msgid "WebM file (Vorbis codec)"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:40
msgid ""
"Sorry, this video will not work because \n"
"\t your web browser does not support HTML5 \n"
"\t video."
msgstr ""
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:36
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:43
msgid ""
"You can get a modern web browser that \n"
"\t can play this video at <a href=\"http://getfirefox.com\">\n"
@@ -410,55 +457,49 @@ msgstr ""
msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:72
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:46
#, python-format
-msgid "Added on %(date)s."
+msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:81
-msgid "Edit"
-msgstr ""
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:85
-msgid "Delete"
-msgstr ""
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:67
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:73
#, python-format
-msgid "%(comment_count)s comment"
+msgid "Image for %(media_title)s"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:93
-#, python-format
-msgid "%(comment_count)s comments"
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:87
+msgid "Edit"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:95
-msgid "No comments yet."
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
+msgid "Delete"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:103
-msgid "Add one"
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:124
+msgid "Add a comment"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:112
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:131
msgid ""
"You can use <a "
"href=\"http://daringfireball.net/projects/markdown/basics\">Markdown</a> for"
" formatting."
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:116
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:135
msgid "Add this comment"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:138
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:154
msgid "at"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:153
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:174
#, python-format
-msgid "<p>â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a></p>"
+msgid ""
+"<h3>Added on</h3>\n"
+" <p>%(date)s</p>"
msgstr ""
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30
@@ -467,7 +508,7 @@ msgid "Really delete %(title)s?"
msgstr ""
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:50
-msgid "Delete Permanently"
+msgid "Delete permanently"
msgstr ""
#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:22
@@ -564,6 +605,10 @@ msgid ""
"anything yet."
msgstr ""
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
+msgid "Add media"
+msgstr ""
+
#: mediagoblin/templates/mediagoblin/user_pages/user.html:163
#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72
msgid "There doesn't seem to be any media here yet..."
@@ -577,8 +622,13 @@ msgstr ""
msgid "Atom feed"
msgstr ""
-#: mediagoblin/templates/mediagoblin/utils/license.html:21
-msgid "License:"
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:25
+msgid "Location"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:38
+#, python-format
+msgid "View on <a href=\"%(osm_url)s\">OpenStreetMap</a>"
msgstr ""
#: mediagoblin/templates/mediagoblin/utils/license.html:25
@@ -597,25 +647,21 @@ msgstr ""
msgid "Go to page:"
msgstr ""
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:27
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:32
+#: 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:38
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:43
+#: 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 "View more media tagged with"
+msgid "Tagged with"
msgstr ""
-#: mediagoblin/templates/mediagoblin/utils/tags.html:25
-msgid "or"
-msgstr ""
-
-#: mediagoblin/tools/exif.py:68
+#: mediagoblin/tools/exif.py:75
msgid "Could not read the image file."
msgstr ""
@@ -623,24 +669,22 @@ msgstr ""
msgid "I am sure I want to delete this"
msgstr ""
-#: mediagoblin/user_pages/views.py:155
+#: mediagoblin/user_pages/views.py:153
msgid "Oops, your comment was empty."
msgstr ""
-#: mediagoblin/user_pages/views.py:161
+#: mediagoblin/user_pages/views.py:159
msgid "Your comment has been posted!"
msgstr ""
-#: mediagoblin/user_pages/views.py:183
+#: mediagoblin/user_pages/views.py:185
msgid "You deleted the media."
msgstr ""
-#: mediagoblin/user_pages/views.py:190
+#: mediagoblin/user_pages/views.py:192
msgid "The media was not deleted because you didn't check that you were sure."
msgstr ""
-#: mediagoblin/user_pages/views.py:198
+#: mediagoblin/user_pages/views.py:200
msgid "You are about to delete another user's media. Proceed with caution."
msgstr ""
-
-
diff --git a/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.mo
index 095deaa2..fef6d4e0 100644
--- a/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.mo
+++ b/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.mo
Binary files differ
diff --git a/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.po
index 91791796..81430bb8 100644
--- a/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.po
+++ b/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.po
@@ -8,11 +8,11 @@
msgid ""
msgstr ""
"Project-Id-Version: GNU MediaGoblin\n"
-"Report-Msgid-Bugs-To: http://bugs.foocorp.net/projects/mediagoblin/issues\n"
-"POT-Creation-Date: 2012-01-29 13:31-0600\n"
-"PO-Revision-Date: 2012-01-29 19:29+0000\n"
+"Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n"
+"POT-Creation-Date: 2012-06-01 16:32-0500\n"
+"PO-Revision-Date: 2012-06-01 21:30+0000\n"
"Last-Translator: cwebber <cwebber@dustycloud.org>\n"
-"Language-Team: Swedish (http://www.transifex.net/projects/p/mediagoblin/team/sv/)\n"
+"Language-Team: Swedish (http://www.transifex.net/projects/p/mediagoblin/language/sv/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -20,10 +20,6 @@ msgstr ""
"Language: sv\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
-#: mediagoblin/processing.py:143
-msgid "Invalid file given for media type."
-msgstr "Ogiltig fil för mediatypen."
-
#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41
msgid "Username"
msgstr "Användarnamn"
@@ -36,61 +32,64 @@ msgstr "Lösenord"
msgid "Email address"
msgstr "E-postadress"
+#: mediagoblin/auth/forms.py:51
+msgid "Username or email"
+msgstr ""
+
+#: mediagoblin/auth/forms.py:58
+msgid "Incorrect input"
+msgstr ""
+
#: mediagoblin/auth/views.py:55
msgid "Sorry, registration is disabled on this instance."
msgstr "Vi beklagar, registreringen är avtängd på den här instansen."
-#: mediagoblin/auth/views.py:73
+#: mediagoblin/auth/views.py:75
msgid "Sorry, a user with that name already exists."
msgstr "En användare med det användarnamnet finns redan."
-#: mediagoblin/auth/views.py:77
+#: mediagoblin/auth/views.py:79
msgid "Sorry, a user with that email address already exists."
msgstr "Det finns redan en användare med den e-postadressen."
-#: mediagoblin/auth/views.py:180
+#: mediagoblin/auth/views.py:182
msgid ""
"Your email address has been verified. You may now login, edit your profile, "
"and submit images!"
-msgstr ""
-"Din e-postadress är verifierad. Du kan nu logga in, redigera din profil och "
-"ladda upp filer!"
+msgstr "Din e-postadress är verifierad. Du kan nu logga in, redigera din profil och ladda upp filer!"
-#: mediagoblin/auth/views.py:186
+#: mediagoblin/auth/views.py:188
msgid "The verification key or user id is incorrect"
msgstr "Verifieringsnyckeln eller användar-IDt är fel."
-#: mediagoblin/auth/views.py:204
+#: mediagoblin/auth/views.py:206
msgid "You must be logged in so we know who to send the email to!"
-msgstr ""
-"Du måste vara inloggad för att vi ska kunna skicka meddelandet till dig."
+msgstr "Du måste vara inloggad för att vi ska kunna skicka meddelandet till dig."
-#: mediagoblin/auth/views.py:212
+#: mediagoblin/auth/views.py:214
msgid "You've already verified your email address!"
msgstr "Du har redan verifierat din e-postadress!"
-#: mediagoblin/auth/views.py:225
+#: mediagoblin/auth/views.py:227
msgid "Resent your verification email."
msgstr "Skickade ett nytt verifierings-email."
-#: mediagoblin/auth/views.py:260
+#: mediagoblin/auth/views.py:263
msgid ""
"An email has been sent with instructions on how to change your password."
msgstr ""
-#: mediagoblin/auth/views.py:270
+#: mediagoblin/auth/views.py:273
msgid ""
"Could not send password recovery email as your username is inactive or your "
"account's email address has not been verified."
-msgstr ""
-"Kunde inte skicka e-poståterställning av lösenord eftersom ditt användarnamn"
-" är inaktivt eller kontots e-postadress har inte verifierats."
+msgstr "Kunde inte skicka e-poståterställning av lösenord eftersom ditt användarnamn är inaktivt eller kontots e-postadress har inte verifierats."
-#: mediagoblin/auth/views.py:282
+#: mediagoblin/auth/views.py:285
msgid "Couldn't find someone with that username or email."
msgstr ""
-#: mediagoblin/auth/views.py:330
+#: mediagoblin/auth/views.py:333
msgid "You can now log in using your new password."
msgstr ""
@@ -133,6 +132,7 @@ msgid ""
msgstr ""
#: mediagoblin/edit/forms.py:44 mediagoblin/submit/forms.py:41
+#: mediagoblin/templates/mediagoblin/utils/license.html:20
msgid "License"
msgstr ""
@@ -144,6 +144,10 @@ msgstr "Presentation"
msgid "Website"
msgstr "Hemsida"
+#: mediagoblin/edit/forms.py:58
+msgid "This address contains errors"
+msgstr ""
+
#: mediagoblin/edit/forms.py:63
msgid "Old password"
msgstr "Tidigare lösenord"
@@ -156,47 +160,48 @@ msgstr ""
msgid "New password"
msgstr ""
-#: mediagoblin/edit/views.py:68
+#: mediagoblin/edit/views.py:67
msgid "An entry with that slug already exists for this user."
msgstr "Ett inlägg med det sökvägsnamnet existerar redan."
-#: mediagoblin/edit/views.py:92
+#: mediagoblin/edit/views.py:88
msgid "You are editing another user's media. Proceed with caution."
msgstr "Var försiktig, du redigerar någon annans inlägg."
-#: mediagoblin/edit/views.py:162
+#: mediagoblin/edit/views.py:158
msgid "You are editing a user's profile. Proceed with caution."
msgstr "Var försiktig, du redigerar en annan användares profil."
-#: mediagoblin/edit/views.py:180
+#: mediagoblin/edit/views.py:174
msgid "Profile changes saved"
msgstr ""
-#: mediagoblin/edit/views.py:206
+#: mediagoblin/edit/views.py:200
msgid "Wrong password"
msgstr "Fel lösenord"
-#: mediagoblin/edit/views.py:222
+#: mediagoblin/edit/views.py:216
msgid "Account settings saved"
msgstr ""
-#: mediagoblin/media_types/__init__.py:77
-msgid "Could not extract any file extension from \"{filename}\""
-msgstr ""
-
-#: mediagoblin/media_types/__init__.py:88
+#: mediagoblin/media_types/__init__.py:60
+#: mediagoblin/media_types/__init__.py:120
msgid "Sorry, I don't support that file type :("
msgstr ""
+#: mediagoblin/processing/__init__.py:127
+msgid "Invalid file given for media type."
+msgstr "Ogiltig fil för mediatypen."
+
#: mediagoblin/submit/forms.py:26
msgid "File"
msgstr "Fil"
-#: mediagoblin/submit/views.py:54
+#: mediagoblin/submit/views.py:56
msgid "You must provide a file."
msgstr "Du måste ange en fil"
-#: mediagoblin/submit/views.py:158
+#: mediagoblin/submit/views.py:163
msgid "Woohoo! Submitted!"
msgstr "Tjohoo! Upladdat!"
@@ -216,40 +221,47 @@ msgstr "Ledsen, det verkar inte vara någonting här."
msgid ""
"If you're sure the address is correct, maybe the page you're looking for has"
" been moved or deleted."
-msgstr ""
-"Om du är säker på att adressen stämmer så kanske sidan du letar efter har "
-"flyttats eller tagits bort."
+msgstr "Om du är säker på att adressen stämmer så kanske sidan du letar efter har flyttats eller tagits bort."
-#: mediagoblin/templates/mediagoblin/base.html:46
+#: mediagoblin/templates/mediagoblin/base.html:47
msgid "MediaGoblin logo"
msgstr "MediaGoblin-logotyp"
-#: mediagoblin/templates/mediagoblin/base.html:51
-#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
-msgid "Add media"
-msgstr "Lägg till media"
-
-#: mediagoblin/templates/mediagoblin/base.html:62
+#: mediagoblin/templates/mediagoblin/base.html:57
msgid "Verify your email!"
msgstr "Verifiera din e-postadress"
-#: mediagoblin/templates/mediagoblin/base.html:69
-msgid "log out"
-msgstr "Logga ut"
+#: mediagoblin/templates/mediagoblin/base.html:63
+msgid "+ Add media"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:65
+msgid "View your profile"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:66
+msgid "Log out"
+msgstr ""
-#: mediagoblin/templates/mediagoblin/base.html:72
-#: mediagoblin/templates/mediagoblin/auth/login.html:27
-#: mediagoblin/templates/mediagoblin/auth/login.html:45
+#: mediagoblin/templates/mediagoblin/base.html:71
+#: mediagoblin/templates/mediagoblin/auth/login.html:32
+#: mediagoblin/templates/mediagoblin/auth/login.html:50
msgid "Log in"
msgstr "Logga in"
-#: mediagoblin/templates/mediagoblin/base.html:84
+#: mediagoblin/templates/mediagoblin/base.html:85
msgid ""
"Powered by <a href=\"http://mediagoblin.org\">MediaGoblin</a>, a <a "
-"href=\"http://gnu.org/\">GNU</a> project"
+"href=\"http://gnu.org/\">GNU</a> project."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:88
+#, python-format
+msgid ""
+"Released under the <a "
+"href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a "
+"href=\"%(source_link)s\">Source code</a> available."
msgstr ""
-"Drivs av <a href=\"http://mediagoblin.org\">MediaGoblin</a>, ett <a "
-"href=\"http://gnu.org/\">GNU</a>-projekt"
#: mediagoblin/templates/mediagoblin/root.html:24
msgid "Explore"
@@ -315,29 +327,21 @@ msgid ""
"\n"
"If you think this is an error, just ignore this email and continue being\n"
"a happy goblin!"
-msgstr ""
-"Hej %(username)s,\n"
-"\n"
-"för att ändra ditt GNU MediaGoblin-lösenord, öppna följande länk i\n"
-"din webbläsare:\n"
-"\n"
-"%(verification_url)s\n"
-"\n"
-"Om du misstänker att du fått detta epostmeddelanade av misstag, ignorera det och fortsätt vara ett glatt troll!"
+msgstr "Hej %(username)s,\n\nför att ändra ditt GNU MediaGoblin-lösenord, öppna följande länk i\ndin webbläsare:\n\n%(verification_url)s\n\nOm du misstänker att du fått detta epostmeddelanade av misstag, ignorera det och fortsätt vara ett glatt troll!"
-#: mediagoblin/templates/mediagoblin/auth/login.html:30
+#: mediagoblin/templates/mediagoblin/auth/login.html:35
msgid "Logging in failed!"
msgstr "Inloggning misslyckades!"
-#: mediagoblin/templates/mediagoblin/auth/login.html:35
+#: mediagoblin/templates/mediagoblin/auth/login.html:40
msgid "Don't have an account yet?"
msgstr "Har du inget konto än?"
-#: mediagoblin/templates/mediagoblin/auth/login.html:36
+#: mediagoblin/templates/mediagoblin/auth/login.html:41
msgid "Create one here!"
msgstr "Skapa ett här!"
-#: mediagoblin/templates/mediagoblin/auth/login.html:42
+#: mediagoblin/templates/mediagoblin/auth/login.html:47
msgid "Forgot your password?"
msgstr "Glömt ditt lösenord?"
@@ -358,12 +362,7 @@ msgid ""
"your web browser:\n"
"\n"
"%(verification_url)s"
-msgstr ""
-"Hej %(username)s,\n"
-"\n"
-"öppna den följande webbadressen i din webbläsare för att aktivera ditt konto på GNU MediaGoblin:\n"
-"\n"
-"%(verification_url)s"
+msgstr "Hej %(username)s,\n\nöppna den följande webbadressen i din webbläsare för att aktivera ditt konto på GNU MediaGoblin:\n\n%(verification_url)s"
#: mediagoblin/templates/mediagoblin/edit/edit.html:29
#, python-format
@@ -398,18 +397,44 @@ msgid "Media tagged with: %(tag_name)s"
msgstr "Media taggat med: %(tag_name)s"
#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:46
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:53
msgid "Original"
msgstr "Original"
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:33
+#: 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 <a href=\"http://getfirefox.com\">\n"
+"\t http://getfirefox.com</a>!"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:56
+msgid "Download"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:60
+msgid "original file"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:63
+msgid "WebM file (Vorbis codec)"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:40
msgid ""
"Sorry, this video will not work because \n"
"\t your web browser does not support HTML5 \n"
"\t video."
msgstr ""
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:36
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:43
msgid ""
"You can get a modern web browser that \n"
"\t can play this video at <a href=\"http://getfirefox.com\">\n"
@@ -434,55 +459,49 @@ msgstr "%(username)ss media"
msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media"
msgstr "<a href=\"%(user_url)s\">%(username)s</a>s media"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:72
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:46
#, python-format
-msgid "Added on %(date)s."
-msgstr ""
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:81
-msgid "Edit"
+msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:85
-msgid "Delete"
-msgstr ""
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:67
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:73
#, python-format
-msgid "%(comment_count)s comment"
+msgid "Image for %(media_title)s"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:93
-#, python-format
-msgid "%(comment_count)s comments"
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:87
+msgid "Edit"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:95
-msgid "No comments yet."
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
+msgid "Delete"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:103
-msgid "Add one"
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:124
+msgid "Add a comment"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:112
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:131
msgid ""
"You can use <a "
"href=\"http://daringfireball.net/projects/markdown/basics\">Markdown</a> for"
" formatting."
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:116
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:135
msgid "Add this comment"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:138
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:154
msgid "at"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:153
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:174
#, python-format
-msgid "<p>â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a></p>"
+msgid ""
+"<h3>Added on</h3>\n"
+" <p>%(date)s</p>"
msgstr ""
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30
@@ -491,8 +510,8 @@ msgid "Really delete %(title)s?"
msgstr "Vill du verkligen radera %(title)s?"
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:50
-msgid "Delete Permanently"
-msgstr "Radera permanent"
+msgid "Delete permanently"
+msgstr ""
#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:22
msgid "Media processing panel"
@@ -537,8 +556,7 @@ msgstr "Nästan klar! Ditt konto behöver bara aktiveras."
#: mediagoblin/templates/mediagoblin/user_pages/user.html:58
msgid ""
"An email should arrive in a few moments with instructions on how to do so."
-msgstr ""
-"Ett e-postmeddelande med instruktioner kommer att hamna hos dig inom kort."
+msgstr "Ett e-postmeddelande med instruktioner kommer att hamna hos dig inom kort."
#: mediagoblin/templates/mediagoblin/user_pages/user.html:62
msgid "In case it doesn't:"
@@ -552,19 +570,14 @@ msgstr "Skicka ett nytt e-postmeddelande"
msgid ""
"Someone has registered an account with this username, but it still has to be"
" activated."
-msgstr ""
-"Någon har redan registrerat ett konto med det här användarnamnet men det har"
-" inte aktiverats."
+msgstr "Någon har redan registrerat ett konto med det här användarnamnet men det har inte aktiverats."
#: mediagoblin/templates/mediagoblin/user_pages/user.html:79
#, python-format
msgid ""
"If you are that person but you've lost your verification email, you can <a "
"href=\"%(login_url)s\">log in</a> and resend it."
-msgstr ""
-"Om det är du som är den personen och har förlorat ditt e-postmeddelande med "
-"detaljer om hur du verifierar ditt konto så kan du <a "
-"href=\"%(login_url)s\">logga in</a> och begära ett nytt."
+msgstr "Om det är du som är den personen och har förlorat ditt e-postmeddelande med detaljer om hur du verifierar ditt konto så kan du <a href=\"%(login_url)s\">logga in</a> och begära ett nytt."
#: mediagoblin/templates/mediagoblin/user_pages/user.html:96
msgid "Here's a spot to tell others about yourself."
@@ -592,9 +605,11 @@ msgstr "Se all media från %(username)s"
msgid ""
"This is where your media will appear, but you don't seem to have added "
"anything yet."
-msgstr ""
-"Här kommer din media att dyka upp, du verkar inte ha lagt till någonting "
-"ännu."
+msgstr "Här kommer din media att dyka upp, du verkar inte ha lagt till någonting ännu."
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
+msgid "Add media"
+msgstr "Lägg till media"
#: mediagoblin/templates/mediagoblin/user_pages/user.html:163
#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72
@@ -609,8 +624,13 @@ msgstr "feed-ikon"
msgid "Atom feed"
msgstr "Atom-feed"
-#: mediagoblin/templates/mediagoblin/utils/license.html:21
-msgid "License:"
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:25
+msgid "Location"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:38
+#, python-format
+msgid "View on <a href=\"%(osm_url)s\">OpenStreetMap</a>"
msgstr ""
#: mediagoblin/templates/mediagoblin/utils/license.html:25
@@ -629,25 +649,21 @@ msgstr ""
msgid "Go to page:"
msgstr ""
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:27
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:32
+#: 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:38
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:43
+#: 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 "View more media tagged with"
-msgstr ""
-
-#: mediagoblin/templates/mediagoblin/utils/tags.html:25
-msgid "or"
+msgid "Tagged with"
msgstr ""
-#: mediagoblin/tools/exif.py:68
+#: mediagoblin/tools/exif.py:75
msgid "Could not read the image file."
msgstr ""
@@ -655,24 +671,22 @@ msgstr ""
msgid "I am sure I want to delete this"
msgstr "Jag är säker på att jag vill radera detta"
-#: mediagoblin/user_pages/views.py:155
+#: mediagoblin/user_pages/views.py:153
msgid "Oops, your comment was empty."
msgstr ""
-#: mediagoblin/user_pages/views.py:161
+#: mediagoblin/user_pages/views.py:159
msgid "Your comment has been posted!"
msgstr ""
-#: mediagoblin/user_pages/views.py:183
+#: mediagoblin/user_pages/views.py:185
msgid "You deleted the media."
msgstr ""
-#: mediagoblin/user_pages/views.py:190
+#: mediagoblin/user_pages/views.py:192
msgid "The media was not deleted because you didn't check that you were sure."
msgstr ""
-#: mediagoblin/user_pages/views.py:198
+#: mediagoblin/user_pages/views.py:200
msgid "You are about to delete another user's media. Proceed with caution."
msgstr "Du tänker radera en annan användares media. Var försiktig."
-
-
diff --git a/mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.mo
index 9467a3f1..fab9369b 100644
--- a/mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.mo
+++ b/mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.mo
Binary files differ
diff --git a/mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.po
index 24155bff..da64d577 100644
--- a/mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.po
+++ b/mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.po
@@ -7,9 +7,9 @@
msgid ""
msgstr ""
"Project-Id-Version: GNU MediaGoblin\n"
-"Report-Msgid-Bugs-To: http://bugs.foocorp.net/projects/mediagoblin/issues\n"
-"POT-Creation-Date: 2012-01-29 13:31-0600\n"
-"PO-Revision-Date: 2012-01-29 19:29+0000\n"
+"Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n"
+"POT-Creation-Date: 2012-06-01 16:32-0500\n"
+"PO-Revision-Date: 2012-06-01 21:30+0000\n"
"Last-Translator: cwebber <cwebber@dustycloud.org>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
@@ -19,10 +19,6 @@ msgstr ""
"Language: te\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
-#: mediagoblin/processing.py:143
-msgid "Invalid file given for media type."
-msgstr ""
-
#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41
msgid "Username"
msgstr "వాడà±à°•à°°à°¿ పేరà±"
@@ -35,56 +31,64 @@ msgstr "సంకేతపదం"
msgid "Email address"
msgstr "ఈమెయిలౠచిరà±à°¨à°¾à°®à°¾"
+#: mediagoblin/auth/forms.py:51
+msgid "Username or email"
+msgstr ""
+
+#: mediagoblin/auth/forms.py:58
+msgid "Incorrect input"
+msgstr ""
+
#: mediagoblin/auth/views.py:55
msgid "Sorry, registration is disabled on this instance."
msgstr ""
-#: mediagoblin/auth/views.py:73
+#: mediagoblin/auth/views.py:75
msgid "Sorry, a user with that name already exists."
msgstr ""
-#: mediagoblin/auth/views.py:77
+#: mediagoblin/auth/views.py:79
msgid "Sorry, a user with that email address already exists."
msgstr ""
-#: mediagoblin/auth/views.py:180
+#: 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:186
+#: mediagoblin/auth/views.py:188
msgid "The verification key or user id is incorrect"
msgstr ""
-#: mediagoblin/auth/views.py:204
+#: 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:212
+#: mediagoblin/auth/views.py:214
msgid "You've already verified your email address!"
msgstr ""
-#: mediagoblin/auth/views.py:225
+#: mediagoblin/auth/views.py:227
msgid "Resent your verification email."
msgstr ""
-#: mediagoblin/auth/views.py:260
+#: mediagoblin/auth/views.py:263
msgid ""
"An email has been sent with instructions on how to change your password."
msgstr ""
-#: mediagoblin/auth/views.py:270
+#: mediagoblin/auth/views.py:273
msgid ""
"Could not send password recovery email as your username is inactive or your "
"account's email address has not been verified."
msgstr ""
-#: mediagoblin/auth/views.py:282
+#: mediagoblin/auth/views.py:285
msgid "Couldn't find someone with that username or email."
msgstr ""
-#: mediagoblin/auth/views.py:330
+#: mediagoblin/auth/views.py:333
msgid "You can now log in using your new password."
msgstr ""
@@ -127,6 +131,7 @@ msgid ""
msgstr ""
#: mediagoblin/edit/forms.py:44 mediagoblin/submit/forms.py:41
+#: mediagoblin/templates/mediagoblin/utils/license.html:20
msgid "License"
msgstr ""
@@ -138,6 +143,10 @@ msgstr ""
msgid "Website"
msgstr ""
+#: mediagoblin/edit/forms.py:58
+msgid "This address contains errors"
+msgstr ""
+
#: mediagoblin/edit/forms.py:63
msgid "Old password"
msgstr ""
@@ -150,47 +159,48 @@ msgstr ""
msgid "New password"
msgstr ""
-#: mediagoblin/edit/views.py:68
+#: mediagoblin/edit/views.py:67
msgid "An entry with that slug already exists for this user."
msgstr ""
-#: mediagoblin/edit/views.py:92
+#: mediagoblin/edit/views.py:88
msgid "You are editing another user's media. Proceed with caution."
msgstr ""
-#: mediagoblin/edit/views.py:162
+#: mediagoblin/edit/views.py:158
msgid "You are editing a user's profile. Proceed with caution."
msgstr ""
-#: mediagoblin/edit/views.py:180
+#: mediagoblin/edit/views.py:174
msgid "Profile changes saved"
msgstr ""
-#: mediagoblin/edit/views.py:206
+#: mediagoblin/edit/views.py:200
msgid "Wrong password"
msgstr ""
-#: mediagoblin/edit/views.py:222
+#: mediagoblin/edit/views.py:216
msgid "Account settings saved"
msgstr ""
-#: mediagoblin/media_types/__init__.py:77
-msgid "Could not extract any file extension from \"{filename}\""
+#: mediagoblin/media_types/__init__.py:60
+#: mediagoblin/media_types/__init__.py:120
+msgid "Sorry, I don't support that file type :("
msgstr ""
-#: mediagoblin/media_types/__init__.py:88
-msgid "Sorry, I don't support that file type :("
+#: mediagoblin/processing/__init__.py:127
+msgid "Invalid file given for media type."
msgstr ""
#: mediagoblin/submit/forms.py:26
msgid "File"
msgstr ""
-#: mediagoblin/submit/views.py:54
+#: mediagoblin/submit/views.py:56
msgid "You must provide a file."
msgstr ""
-#: mediagoblin/submit/views.py:158
+#: mediagoblin/submit/views.py:163
msgid "Woohoo! Submitted!"
msgstr ""
@@ -212,33 +222,44 @@ msgid ""
" been moved or deleted."
msgstr ""
-#: mediagoblin/templates/mediagoblin/base.html:46
+#: mediagoblin/templates/mediagoblin/base.html:47
msgid "MediaGoblin logo"
msgstr ""
-#: mediagoblin/templates/mediagoblin/base.html:51
-#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
-msgid "Add media"
+#: mediagoblin/templates/mediagoblin/base.html:57
+msgid "Verify your email!"
msgstr ""
-#: mediagoblin/templates/mediagoblin/base.html:62
-msgid "Verify your email!"
+#: mediagoblin/templates/mediagoblin/base.html:63
+msgid "+ Add media"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:65
+msgid "View your profile"
msgstr ""
-#: mediagoblin/templates/mediagoblin/base.html:69
-msgid "log out"
+#: mediagoblin/templates/mediagoblin/base.html:66
+msgid "Log out"
msgstr ""
-#: mediagoblin/templates/mediagoblin/base.html:72
-#: mediagoblin/templates/mediagoblin/auth/login.html:27
-#: mediagoblin/templates/mediagoblin/auth/login.html:45
+#: mediagoblin/templates/mediagoblin/base.html:71
+#: mediagoblin/templates/mediagoblin/auth/login.html:32
+#: mediagoblin/templates/mediagoblin/auth/login.html:50
msgid "Log in"
msgstr ""
-#: mediagoblin/templates/mediagoblin/base.html:84
+#: mediagoblin/templates/mediagoblin/base.html:85
msgid ""
"Powered by <a href=\"http://mediagoblin.org\">MediaGoblin</a>, a <a "
-"href=\"http://gnu.org/\">GNU</a> project"
+"href=\"http://gnu.org/\">GNU</a> project."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:88
+#, python-format
+msgid ""
+"Released under the <a "
+"href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a "
+"href=\"%(source_link)s\">Source code</a> available."
msgstr ""
#: mediagoblin/templates/mediagoblin/root.html:24
@@ -307,19 +328,19 @@ msgid ""
"a happy goblin!"
msgstr ""
-#: mediagoblin/templates/mediagoblin/auth/login.html:30
+#: mediagoblin/templates/mediagoblin/auth/login.html:35
msgid "Logging in failed!"
msgstr "à°ªà±à°°à°µà±‡à°¶à°‚ విఫలమయà±à°¯à°¿à°‚ది!"
-#: mediagoblin/templates/mediagoblin/auth/login.html:35
+#: mediagoblin/templates/mediagoblin/auth/login.html:40
msgid "Don't have an account yet?"
msgstr "మీకౠఇంకా ఖాతా లేదా?"
-#: mediagoblin/templates/mediagoblin/auth/login.html:36
+#: mediagoblin/templates/mediagoblin/auth/login.html:41
msgid "Create one here!"
msgstr ""
-#: mediagoblin/templates/mediagoblin/auth/login.html:42
+#: mediagoblin/templates/mediagoblin/auth/login.html:47
msgid "Forgot your password?"
msgstr "మీ సంకేతపదానà±à°¨à°¿ మరà±à°šà°¿à°ªà±‹à°¯à°¾à°°à°¾?"
@@ -375,18 +396,44 @@ msgid "Media tagged with: %(tag_name)s"
msgstr ""
#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:46
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:53
msgid "Original"
msgstr ""
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:33
+#: 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 <a href=\"http://getfirefox.com\">\n"
+"\t http://getfirefox.com</a>!"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:56
+msgid "Download"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:60
+msgid "original file"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:63
+msgid "WebM file (Vorbis codec)"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:40
msgid ""
"Sorry, this video will not work because \n"
"\t your web browser does not support HTML5 \n"
"\t video."
msgstr ""
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:36
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:43
msgid ""
"You can get a modern web browser that \n"
"\t can play this video at <a href=\"http://getfirefox.com\">\n"
@@ -411,55 +458,49 @@ msgstr ""
msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:72
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:46
#, python-format
-msgid "Added on %(date)s."
+msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:81
-msgid "Edit"
-msgstr ""
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:85
-msgid "Delete"
-msgstr ""
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:67
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:73
#, python-format
-msgid "%(comment_count)s comment"
+msgid "Image for %(media_title)s"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:93
-#, python-format
-msgid "%(comment_count)s comments"
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:87
+msgid "Edit"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:95
-msgid "No comments yet."
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
+msgid "Delete"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:103
-msgid "Add one"
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:124
+msgid "Add a comment"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:112
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:131
msgid ""
"You can use <a "
"href=\"http://daringfireball.net/projects/markdown/basics\">Markdown</a> for"
" formatting."
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:116
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:135
msgid "Add this comment"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:138
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:154
msgid "at"
msgstr ""
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:153
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:174
#, python-format
-msgid "<p>â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a></p>"
+msgid ""
+"<h3>Added on</h3>\n"
+" <p>%(date)s</p>"
msgstr ""
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30
@@ -468,7 +509,7 @@ msgid "Really delete %(title)s?"
msgstr ""
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:50
-msgid "Delete Permanently"
+msgid "Delete permanently"
msgstr ""
#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:22
@@ -565,6 +606,10 @@ msgid ""
"anything yet."
msgstr ""
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
+msgid "Add media"
+msgstr ""
+
#: mediagoblin/templates/mediagoblin/user_pages/user.html:163
#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72
msgid "There doesn't seem to be any media here yet..."
@@ -578,8 +623,13 @@ msgstr ""
msgid "Atom feed"
msgstr ""
-#: mediagoblin/templates/mediagoblin/utils/license.html:21
-msgid "License:"
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:25
+msgid "Location"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:38
+#, python-format
+msgid "View on <a href=\"%(osm_url)s\">OpenStreetMap</a>"
msgstr ""
#: mediagoblin/templates/mediagoblin/utils/license.html:25
@@ -598,25 +648,21 @@ msgstr ""
msgid "Go to page:"
msgstr ""
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:27
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:32
+#: 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:38
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:43
+#: 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 "View more media tagged with"
+msgid "Tagged with"
msgstr ""
-#: mediagoblin/templates/mediagoblin/utils/tags.html:25
-msgid "or"
-msgstr ""
-
-#: mediagoblin/tools/exif.py:68
+#: mediagoblin/tools/exif.py:75
msgid "Could not read the image file."
msgstr ""
@@ -624,24 +670,22 @@ msgstr ""
msgid "I am sure I want to delete this"
msgstr ""
-#: mediagoblin/user_pages/views.py:155
+#: mediagoblin/user_pages/views.py:153
msgid "Oops, your comment was empty."
msgstr ""
-#: mediagoblin/user_pages/views.py:161
+#: mediagoblin/user_pages/views.py:159
msgid "Your comment has been posted!"
msgstr ""
-#: mediagoblin/user_pages/views.py:183
+#: mediagoblin/user_pages/views.py:185
msgid "You deleted the media."
msgstr ""
-#: mediagoblin/user_pages/views.py:190
+#: mediagoblin/user_pages/views.py:192
msgid "The media was not deleted because you didn't check that you were sure."
msgstr ""
-#: mediagoblin/user_pages/views.py:198
+#: mediagoblin/user_pages/views.py:200
msgid "You are about to delete another user's media. Proceed with caution."
msgstr ""
-
-
diff --git a/mediagoblin/i18n/zh_TW.Big5/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/zh_TW.Big5/LC_MESSAGES/mediagoblin.mo
new file mode 100644
index 00000000..254d31f3
--- /dev/null
+++ b/mediagoblin/i18n/zh_TW.Big5/LC_MESSAGES/mediagoblin.mo
Binary files differ
diff --git a/mediagoblin/i18n/zh_TW.Big5/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/zh_TW.Big5/LC_MESSAGES/mediagoblin.po
new file mode 100644
index 00000000..f9ae04e4
--- /dev/null
+++ b/mediagoblin/i18n/zh_TW.Big5/LC_MESSAGES/mediagoblin.po
@@ -0,0 +1,679 @@
+# Translations template for PROJECT.
+# Copyright (C) 2012 ORGANIZATION
+# This file is distributed under the same license as the PROJECT project.
+#
+# Translators:
+msgid ""
+msgstr ""
+"Project-Id-Version: GNU MediaGoblin\n"
+"Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n"
+"POT-Creation-Date: 2012-04-30 10:48-0500\n"
+"PO-Revision-Date: 2011-08-07 03:51+0000\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: Chinese (Taiwan) (Big5) (http://www.transifex.net/projects/p/mediagoblin/language/zh_TW.Big5/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 0.9.6\n"
+"Language: zh_TW.Big5\n"
+"Plural-Forms: nplurals=1; plural=0\n"
+
+#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41
+msgid "Username"
+msgstr ""
+
+#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45
+msgid "Password"
+msgstr ""
+
+#: mediagoblin/auth/forms.py:34
+msgid "Email address"
+msgstr ""
+
+#: mediagoblin/auth/forms.py:51
+msgid "Username or email"
+msgstr ""
+
+#: mediagoblin/auth/forms.py:58
+msgid "Incorrect input"
+msgstr ""
+
+#: mediagoblin/auth/views.py:55
+msgid "Sorry, registration is disabled on this instance."
+msgstr ""
+
+#: mediagoblin/auth/views.py:75
+msgid "Sorry, a user with that name already exists."
+msgstr ""
+
+#: mediagoblin/auth/views.py:79
+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 ""
+
+#: 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:263
+msgid ""
+"An email has been sent with instructions on how to change your password."
+msgstr ""
+
+#: mediagoblin/auth/views.py:273
+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:285
+msgid "Couldn't find someone with that username or email."
+msgstr ""
+
+#: mediagoblin/auth/views.py:333
+msgid "You can now log in using your new password."
+msgstr ""
+
+#: mediagoblin/edit/forms.py:25 mediagoblin/submit/forms.py:28
+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/submit/forms.py:32
+msgid ""
+"You can use\n"
+" <a href=\"http://daringfireball.net/projects/markdown/basics\">\n"
+" Markdown</a> for formatting."
+msgstr ""
+
+#: 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
+msgid "Slug"
+msgstr ""
+
+#: mediagoblin/edit/forms.py:39
+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 "Old password"
+msgstr ""
+
+#: mediagoblin/edit/forms.py:65
+msgid "Enter your old password to prove you own this account."
+msgstr ""
+
+#: mediagoblin/edit/forms.py:68
+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:88
+msgid "You are editing another user's media. Proceed with caution."
+msgstr ""
+
+#: mediagoblin/edit/views.py:158
+msgid "You are editing a user's profile. Proceed with caution."
+msgstr ""
+
+#: mediagoblin/edit/views.py:174
+msgid "Profile changes saved"
+msgstr ""
+
+#: mediagoblin/edit/views.py:200
+msgid "Wrong password"
+msgstr ""
+
+#: mediagoblin/edit/views.py:216
+msgid "Account settings saved"
+msgstr ""
+
+#: mediagoblin/media_types/__init__.py:60
+#: mediagoblin/media_types/__init__.py:120
+msgid "Sorry, I don't support that file type :("
+msgstr ""
+
+#: mediagoblin/processing/__init__.py:127
+msgid "Invalid file given for media type."
+msgstr ""
+
+#: mediagoblin/submit/forms.py:26
+msgid "File"
+msgstr ""
+
+#: mediagoblin/submit/views.py:56
+msgid "You must provide a file."
+msgstr ""
+
+#: mediagoblin/submit/views.py:163
+msgid "Woohoo! Submitted!"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/404.html:22
+msgid "Image of 404 goblin stressing out"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/404.html:23
+msgid "Oops!"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/404.html:24
+msgid "There doesn't seem to be a page at this address. Sorry!"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/404.html:26
+msgid ""
+"If you're sure the address is correct, maybe the page you're looking for has"
+" been moved or deleted."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:47
+msgid "MediaGoblin logo"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:57
+msgid "Verify your email!"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:63
+msgid "+ Add media"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:65
+msgid "View your profile"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:66
+msgid "Log out"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:71
+#: mediagoblin/templates/mediagoblin/auth/login.html:32
+#: mediagoblin/templates/mediagoblin/auth/login.html:50
+msgid "Log in"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:85
+msgid ""
+"Powered by <a href=\"http://mediagoblin.org\">MediaGoblin</a>, a <a "
+"href=\"http://gnu.org/\">GNU</a> project."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/base.html:88
+#, python-format
+msgid ""
+"Released under the <a "
+"href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a "
+"href=\"%(source_link)s\">Source code</a> available."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/root.html:24
+msgid "Explore"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/root.html:26
+msgid "Hi there, welcome to this MediaGoblin site!"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/root.html:28
+msgid ""
+"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, an "
+"extraordinarily great piece of media hosting software."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/root.html:29
+msgid ""
+"To add your own media, place comments, save your favourites and more, you "
+"can log in with your MediaGoblin account."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/root.html:31
+msgid "Don't have one yet? It's easy!"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/root.html:32
+#, python-format
+msgid ""
+"<a class=\"button_action_highlight\" href=\"%(register_url)s\">Create an account at this site</a>\n"
+" or\n"
+" <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">Set up MediaGoblin on your own server</a>"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/root.html:40
+msgid "Most recent media"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/auth/change_fp.html:32
+msgid "Set your new password"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/auth/change_fp.html:35
+msgid "Set password"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:27
+msgid "Recover password"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:30
+msgid "Send instructions"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/auth/fp_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:35
+msgid "Logging in failed!"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/auth/login.html:40
+msgid "Don't have an account yet?"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/auth/login.html:41
+msgid "Create one here!"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/auth/login.html:47
+msgid "Forgot your password?"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/auth/register.html:32
+msgid "Create an account!"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/auth/register.html:36
+msgid "Create"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/auth/verification_email.txt:19
+#, python-format
+msgid ""
+"Hi %(username)s,\n"
+"\n"
+"to activate your GNU MediaGoblin account, open the following URL in\n"
+"your web browser:\n"
+"\n"
+"%(verification_url)s"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/edit/edit.html:29
+#, python-format
+msgid "Editing %(media_title)s"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/edit/edit.html:36
+#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49
+msgid "Cancel"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/edit/edit.html:37
+#: mediagoblin/templates/mediagoblin/edit/edit_account.html:40
+#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:35
+msgid "Save changes"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/edit/edit_account.html:34
+#, python-format
+msgid "Changing %(username)s's account settings"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29
+#, python-format
+msgid "Editing %(username)s's profile"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/listings/tag.html:30
+#: mediagoblin/templates/mediagoblin/listings/tag.html:35
+#, python-format
+msgid "Media tagged with: %(tag_name)s"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:57
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:53
+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 ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:47
+msgid ""
+"You can get a modern web browser that \n"
+"\tcan play the audio at <a href=\"http://getfirefox.com\">\n"
+"\t http://getfirefox.com</a>!"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:40
+msgid ""
+"Sorry, this video will not work because \n"
+"\t your web browser does not support HTML5 \n"
+"\t video."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:43
+msgid ""
+"You can get a modern web browser that \n"
+"\t can play this video at <a href=\"http://getfirefox.com\">\n"
+"\t http://getfirefox.com</a>!"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/submit/start.html:26
+msgid "Add your media"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/submit/start.html:30
+msgid "Add"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30
+#, python-format
+msgid "%(username)s's media"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:37
+#, python-format
+msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:46
+#, python-format
+msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:67
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:73
+#, python-format
+msgid "Image for %(media_title)s"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:87
+msgid "Edit"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
+msgid "Delete"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:124
+msgid "Add a comment"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:131
+msgid ""
+"You can use <a "
+"href=\"http://daringfireball.net/projects/markdown/basics\">Markdown</a> for"
+" formatting."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:135
+msgid "Add this comment"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:154
+msgid "at"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:174
+#, python-format
+msgid ""
+"<h3>Added on</h3>\n"
+" <p>%(date)s</p>"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30
+#, python-format
+msgid "Really delete %(title)s?"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:50
+msgid "Delete permanently"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:22
+msgid "Media processing panel"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:25
+msgid ""
+"You can track the state of media being processed for your gallery here."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:28
+msgid "Media in-processing"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:46
+msgid "No media in-processing"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:50
+msgid "These uploads failed to process:"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:31
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:89
+#, python-format
+msgid "%(username)s's profile"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:43
+msgid "Sorry, no such user found."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:50
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:70
+msgid "Email verification needed"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html: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 <a "
+"href=\"%(login_url)s\">log in</a> 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:101
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:118
+msgid "Edit profile"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:106
+msgid "This user hasn't filled in their profile (yet)."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:125
+msgid "Change account settings"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:138
+#, python-format
+msgid "View all of %(username)s's media"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:151
+msgid ""
+"This is where your media will appear, but you don't seem to have added "
+"anything yet."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
+msgid "Add media"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:163
+#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72
+msgid "There doesn't seem to be any media here yet..."
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/utils/feed_link.html:21
+msgid "feed icon"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/utils/feed_link.html:23
+msgid "Atom feed"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:25
+msgid "Location"
+msgstr ""
+
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:38
+#, python-format
+msgid "View on <a href=\"%(osm_url)s\">OpenStreetMap</a>"
+msgstr ""
+
+#: 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:75
+msgid "Could not read the image file."
+msgstr ""
+
+#: mediagoblin/user_pages/forms.py:30
+msgid "I am sure I want to delete this"
+msgstr ""
+
+#: mediagoblin/user_pages/views.py:153
+msgid "Oops, your comment was empty."
+msgstr ""
+
+#: mediagoblin/user_pages/views.py:159
+msgid "Your comment has been posted!"
+msgstr ""
+
+#: mediagoblin/user_pages/views.py:185
+msgid "You deleted the media."
+msgstr ""
+
+#: mediagoblin/user_pages/views.py:192
+msgid "The media was not deleted because you didn't check that you were sure."
+msgstr ""
+
+#: mediagoblin/user_pages/views.py:200
+msgid "You are about to delete another user's media. 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 e907562e..840da4a3 100644
--- a/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.mo
+++ b/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.mo
Binary files differ
diff --git a/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.po
index 03571c01..72d0e707 100644
--- a/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.po
+++ b/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.po
@@ -8,10 +8,10 @@
msgid ""
msgstr ""
"Project-Id-Version: GNU MediaGoblin\n"
-"Report-Msgid-Bugs-To: http://bugs.foocorp.net/projects/mediagoblin/issues\n"
-"POT-Creation-Date: 2012-01-29 13:31-0600\n"
-"PO-Revision-Date: 2012-01-29 19:29+0000\n"
-"Last-Translator: cwebber <cwebber@dustycloud.org>\n"
+"Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n"
+"POT-Creation-Date: 2012-04-30 10:48-0500\n"
+"PO-Revision-Date: 2012-05-01 17:18+0000\n"
+"Last-Translator: Harry Chen <harryhow@gmail.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -20,10 +20,6 @@ msgstr ""
"Language: zh_TW\n"
"Plural-Forms: nplurals=1; plural=0\n"
-#: mediagoblin/processing.py:143
-msgid "Invalid file given for media type."
-msgstr "指定錯誤的媒體類別ï¼"
-
#: mediagoblin/auth/forms.py:25 mediagoblin/auth/forms.py:41
msgid "Username"
msgstr "使用者å稱"
@@ -36,56 +32,64 @@ msgstr "密碼"
msgid "Email address"
msgstr "é›»å­éƒµä»¶ä½ç½®"
+#: mediagoblin/auth/forms.py:51
+msgid "Username or email"
+msgstr "使用者å稱或是電å­éƒµä»¶"
+
+#: mediagoblin/auth/forms.py:58
+msgid "Incorrect input"
+msgstr "輸入錯誤"
+
#: mediagoblin/auth/views.py:55
msgid "Sorry, registration is disabled on this instance."
msgstr "抱歉, 這個項目已經被暫åœè¨»å†Š."
-#: mediagoblin/auth/views.py:73
+#: mediagoblin/auth/views.py:75
msgid "Sorry, a user with that name already exists."
msgstr "抱歉, 這個使用者å稱已經存在."
-#: mediagoblin/auth/views.py:77
+#: mediagoblin/auth/views.py:79
msgid "Sorry, a user with that email address already exists."
msgstr "抱歉,此電å­éƒµä»¶å·²è¢«è¨»å†Šäº†ã€‚"
-#: mediagoblin/auth/views.py:180
+#: 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:186
+#: mediagoblin/auth/views.py:188
msgid "The verification key or user id is incorrect"
msgstr "èªè­‰ç¢¼æˆ–是使用者帳號錯誤"
-#: mediagoblin/auth/views.py:204
+#: 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:212
+#: mediagoblin/auth/views.py:214
msgid "You've already verified your email address!"
msgstr "你的電å­éƒµä»¶å·²ç¶“確èªäº†ï¼"
-#: mediagoblin/auth/views.py:225
+#: mediagoblin/auth/views.py:227
msgid "Resent your verification email."
msgstr "é‡é€èªè­‰ä¿¡."
-#: mediagoblin/auth/views.py:260
+#: mediagoblin/auth/views.py:263
msgid ""
"An email has been sent with instructions on how to change your password."
msgstr "修改密碼的指示已經由電å­éƒµä»¶å¯„é€åˆ°ä½ çš„信箱。"
-#: mediagoblin/auth/views.py:270
+#: mediagoblin/auth/views.py:273
msgid ""
"Could not send password recovery email as your username is inactive or your "
"account's email address has not been verified."
msgstr "無法傳é€å¯†ç¢¼å›žå¾©ä¿¡ä»¶ï¼Œå› ç‚ºä½ çš„使用者å稱已失效或是帳號尚未èªè­‰ã€‚"
-#: mediagoblin/auth/views.py:282
+#: mediagoblin/auth/views.py:285
msgid "Couldn't find someone with that username or email."
msgstr "找ä¸åˆ°ç›¸é—œçš„使用者å稱或是電å­éƒµä»¶ã€‚"
-#: mediagoblin/auth/views.py:330
+#: mediagoblin/auth/views.py:333
msgid "You can now log in using your new password."
msgstr "ä½ ç¾åœ¨å¯ä»¥ç”¨æ–°çš„密碼登入了ï¼"
@@ -103,10 +107,7 @@ msgid ""
"You can use\n"
" <a href=\"http://daringfireball.net/projects/markdown/basics\">\n"
" Markdown</a> for formatting."
-msgstr ""
-"ä½ å¯ä»¥ç”¨\n"
-" <a href=\"http://daringfireball.net/projects/markdown/basics\">\n"
-" Markdown</a> 來排版."
+msgstr "ä½ å¯ä»¥ç”¨\n <a href=\"http://daringfireball.net/projects/markdown/basics\">\n Markdown</a> 來排版."
#: mediagoblin/edit/forms.py:33 mediagoblin/submit/forms.py:36
msgid "Tags"
@@ -131,8 +132,9 @@ msgid ""
msgstr "此媒體網å€çš„å稱。你通常ä¸éœ€è¦è®Šå‹•這個的。"
#: mediagoblin/edit/forms.py:44 mediagoblin/submit/forms.py:41
+#: mediagoblin/templates/mediagoblin/utils/license.html:20
msgid "License"
-msgstr ""
+msgstr "授權"
#: mediagoblin/edit/forms.py:50
msgid "Bio"
@@ -142,6 +144,10 @@ msgstr "自我介紹"
msgid "Website"
msgstr "網站"
+#: mediagoblin/edit/forms.py:58
+msgid "This address contains errors"
+msgstr "æ­¤ä½å€ä¸­æœ‰èª¤"
+
#: mediagoblin/edit/forms.py:63
msgid "Old password"
msgstr "舊的密碼"
@@ -154,47 +160,48 @@ msgstr "è¼¸å…¥ä½ çš„èˆŠå¯†ç¢¼ä¾†è­‰æ˜Žä½ æ“æœ‰é€™å€‹å¸³è™Ÿã€‚"
msgid "New password"
msgstr "新密碼"
-#: mediagoblin/edit/views.py:68
+#: mediagoblin/edit/views.py:67
msgid "An entry with that slug already exists for this user."
msgstr "這個自訂字串已經被其他人用了"
-#: mediagoblin/edit/views.py:92
+#: mediagoblin/edit/views.py:88
msgid "You are editing another user's media. Proceed with caution."
msgstr "你正在編輯他人的媒體檔案. 請謹慎處ç†."
-#: mediagoblin/edit/views.py:162
+#: mediagoblin/edit/views.py:158
msgid "You are editing a user's profile. Proceed with caution."
msgstr "你正在編輯一ä½ç”¨æˆ¶çš„æª”案. 請謹慎處ç†."
-#: mediagoblin/edit/views.py:180
+#: mediagoblin/edit/views.py:174
msgid "Profile changes saved"
msgstr "修改的檔案已存檔"
-#: mediagoblin/edit/views.py:206
+#: mediagoblin/edit/views.py:200
msgid "Wrong password"
msgstr "密碼錯誤"
-#: mediagoblin/edit/views.py:222
+#: mediagoblin/edit/views.py:216
msgid "Account settings saved"
msgstr "帳號設定已存檔"
-#: mediagoblin/media_types/__init__.py:77
-msgid "Could not extract any file extension from \"{filename}\""
-msgstr "無法從 \"{filename}\"分æžå‡ºä»»ä½•的附檔å"
-
-#: mediagoblin/media_types/__init__.py:88
+#: mediagoblin/media_types/__init__.py:60
+#: mediagoblin/media_types/__init__.py:120
msgid "Sorry, I don't support that file type :("
msgstr "æŠ±æ­‰ï¼Œæˆ‘ä¸æ”¯æ´é€™æ¨£çš„æª”æ¡ˆæ ¼å¼ :("
+#: mediagoblin/processing/__init__.py:127
+msgid "Invalid file given for media type."
+msgstr "指定錯誤的媒體類別ï¼"
+
#: mediagoblin/submit/forms.py:26
msgid "File"
msgstr "檔案"
-#: mediagoblin/submit/views.py:54
+#: mediagoblin/submit/views.py:56
msgid "You must provide a file."
msgstr "ä½ å¿…é ˆæä¾›ä¸€å€‹æª”案"
-#: mediagoblin/submit/views.py:158
+#: mediagoblin/submit/views.py:163
msgid "Woohoo! Submitted!"
msgstr "呼呼! é€å‡ºåŽ»åš•!"
@@ -216,36 +223,45 @@ msgid ""
" been moved or deleted."
msgstr "如果你確定這個ä½å€æ˜¯æ­£ç¢ºçš„,或許你在找的網é å·²ç¶“被移除或是刪除了。"
-#: mediagoblin/templates/mediagoblin/base.html:46
+#: mediagoblin/templates/mediagoblin/base.html:47
msgid "MediaGoblin logo"
msgstr "MediaGoblin 標誌"
-#: mediagoblin/templates/mediagoblin/base.html:51
-#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
-msgid "Add media"
-msgstr "新增媒體檔案"
-
-#: mediagoblin/templates/mediagoblin/base.html:62
+#: mediagoblin/templates/mediagoblin/base.html:57
msgid "Verify your email!"
msgstr "確èªä½ çš„é›»å­éƒµä»¶"
-#: mediagoblin/templates/mediagoblin/base.html:69
-msgid "log out"
+#: mediagoblin/templates/mediagoblin/base.html:63
+msgid "+ Add media"
+msgstr "+ 加入媒體"
+
+#: mediagoblin/templates/mediagoblin/base.html:65
+msgid "View your profile"
+msgstr "檢視你個人檔案"
+
+#: mediagoblin/templates/mediagoblin/base.html:66
+msgid "Log out"
msgstr "登出"
-#: mediagoblin/templates/mediagoblin/base.html:72
-#: mediagoblin/templates/mediagoblin/auth/login.html:27
-#: mediagoblin/templates/mediagoblin/auth/login.html:45
+#: mediagoblin/templates/mediagoblin/base.html:71
+#: mediagoblin/templates/mediagoblin/auth/login.html:32
+#: mediagoblin/templates/mediagoblin/auth/login.html:50
msgid "Log in"
msgstr "登入"
-#: mediagoblin/templates/mediagoblin/base.html:84
+#: mediagoblin/templates/mediagoblin/base.html:85
msgid ""
"Powered by <a href=\"http://mediagoblin.org\">MediaGoblin</a>, a <a "
-"href=\"http://gnu.org/\">GNU</a> project"
-msgstr ""
-"由 <a href=\"http://mediagoblin.org\">MediaGoblin</a>製作, 它是一個 <a "
-"href=\"http://gnu.org/\">GNU</a> 專案"
+"href=\"http://gnu.org/\">GNU</a> project."
+msgstr "由 <a href=\"http://mediagoblin.org\">MediaGoblin</a>製作, 它是一個 <a href=\"http://gnu.org/\">GNU</a> 專案"
+
+#: mediagoblin/templates/mediagoblin/base.html:88
+#, python-format
+msgid ""
+"Released under the <a "
+"href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a "
+"href=\"%(source_link)s\">Source code</a> available."
+msgstr "基於<a href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>授權釋出. <a href=\"%(source_link)s\">å–得原始碼</a>."
#: mediagoblin/templates/mediagoblin/root.html:24
msgid "Explore"
@@ -259,9 +275,7 @@ msgstr "å˜¿ï¼æ­¡è¿Žä¾†åˆ° 媒體怪ç¸(MediaGoblin) 網站"
msgid ""
"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, an "
"extraordinarily great piece of media hosting software."
-msgstr ""
-"此網站正é‹è¡Œ <a href=\"http://mediagoblin.org\">媒體怪ç¸(MediaGoblin)</a>, "
-"他是一個超讚的媒體分享架站軟體."
+msgstr "此網站正é‹è¡Œ <a href=\"http://mediagoblin.org\">媒體怪ç¸(MediaGoblin)</a>, 他是一個超讚的媒體分享架站軟體."
#: mediagoblin/templates/mediagoblin/root.html:29
msgid ""
@@ -279,10 +293,7 @@ msgid ""
"<a class=\"button_action_highlight\" href=\"%(register_url)s\">Create an account at this site</a>\n"
" or\n"
" <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">Set up MediaGoblin on your own server</a>"
-msgstr ""
-"&lt;a class=\"button_action_highlight\" href=\"%(register_url)s\"&gt;在這網站建立帳號&lt;/a&gt;\n"
-" 或是\n"
-" &lt;a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\"&gt;建立一個自己的媒體怪ç¸(MedaiGoblin)&lt;/a&gt;"
+msgstr "<a class=\"button_action_highlight\" href=\"%(register_url)s\">在這網站建立帳號</a>\n 或是\n <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">在你的伺æœå™¨ä¸Šå»ºç«‹ä¸€å€‹è‡ªå·±çš„媒體怪ç¸(MedaiGoblin)</a>"
#: mediagoblin/templates/mediagoblin/root.html:40
msgid "Most recent media"
@@ -316,28 +327,21 @@ msgid ""
"\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"
-"如果你èªç‚ºé€™å€‹æ˜¯å€‹èª¤æœƒï¼Œè«‹å¿½ç•¥æ­¤å°ä¿¡ä»¶ï¼Œç¹¼çºŒç•¶å€‹å¿«æ¨‚çš„goblin!"
+msgstr "å—¨ %(username)s,\n\nè¦æ›´æ”¹ GNU MediaGoblin的密碼,在ç€è¦½å™¨ä¸­æ‰“開下é¢çš„ç¶²å€:\n\n%(verification_url)s\n\n如果你èªç‚ºé€™å€‹æ˜¯å€‹èª¤æœƒï¼Œè«‹å¿½ç•¥æ­¤å°ä¿¡ä»¶ï¼Œç¹¼çºŒç•¶å€‹å¿«æ¨‚çš„goblin!"
-#: mediagoblin/templates/mediagoblin/auth/login.html:30
+#: mediagoblin/templates/mediagoblin/auth/login.html:35
msgid "Logging in failed!"
msgstr "登入失敗ï¼"
-#: mediagoblin/templates/mediagoblin/auth/login.html:35
+#: mediagoblin/templates/mediagoblin/auth/login.html:40
msgid "Don't have an account yet?"
msgstr "還沒有帳號嗎?"
-#: mediagoblin/templates/mediagoblin/auth/login.html:36
+#: mediagoblin/templates/mediagoblin/auth/login.html:41
msgid "Create one here!"
msgstr "在這裡建立一個å§!"
-#: mediagoblin/templates/mediagoblin/auth/login.html:42
+#: mediagoblin/templates/mediagoblin/auth/login.html:47
msgid "Forgot your password?"
msgstr "忘了密碼嗎?"
@@ -358,12 +362,7 @@ msgid ""
"your web browser:\n"
"\n"
"%(verification_url)s"
-msgstr ""
-"å—¨ %(username)s,\n"
-"\n"
-"啟動 GNU MediaGoblin 帳號, 在你的ç€è¦½å™¨ä¸­æ‰“開下é¢çš„ç¶²å€:\n"
-"\n"
-"%(verification_url)s"
+msgstr "å—¨ %(username)s,\n\n啟動 GNU MediaGoblin 帳號, 在你的ç€è¦½å™¨ä¸­æ‰“開下é¢çš„ç¶²å€:\n\n%(verification_url)s"
#: mediagoblin/templates/mediagoblin/edit/edit.html:29
#, python-format
@@ -398,29 +397,38 @@ msgid "Media tagged with: %(tag_name)s"
msgstr "此媒體被標識為:%(tag_name)s"
#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:46
+#: mediagoblin/templates/mediagoblin/media_displays/audio.html:57
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:53
msgid "Original"
msgstr "原始的"
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:33
+#: 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 <a href=\"http://getfirefox.com\">\n"
+"\t http://getfirefox.com</a>!"
+msgstr "ä½ å¯ä»¥åœ¨æ­¤å–å¾—å¯ä»¥æ’­æ”¾éŸ³æ¨‚çš„ç€è¦½å™¨ <a href=\"http://getfirefox.com\">\n\t http://getfirefox.com</a>!"
+
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:40
msgid ""
"Sorry, this video will not work because \n"
"\t your web browser does not support HTML5 \n"
"\t video."
-msgstr ""
-"抱歉, 此影片無法使用,因為 \n"
-"<span class=\"whitespace other\" title=\"Tab\">»</span> ä½ çš„ç€è¦½å™¨ä¸æ”¯æ´ HTML5 \n"
-"<span class=\"whitespace other\" title=\"Tab\">»</span> 的影片."
+msgstr "抱歉, 此影片無法使用,因為 \n<span class=\"whitespace other\" title=\"Tab\">»</span> ä½ çš„ç€è¦½å™¨ä¸æ”¯æ´ HTML5 \n<span class=\"whitespace other\" title=\"Tab\">»</span> 的影片."
-#: mediagoblin/templates/mediagoblin/media_displays/video.html:36
+#: mediagoblin/templates/mediagoblin/media_displays/video.html:43
msgid ""
"You can get a modern web browser that \n"
"\t can play this video at <a href=\"http://getfirefox.com\">\n"
"\t http://getfirefox.com</a>!"
-msgstr ""
-"ä½ å¯ä»¥å–å¾—\n"
-"<span class=\"whitespace other\" title=\"Tab\">»</span> 播放這樣檔案的最新ç€è¦½å™¨ <a href=\"http://getfirefox.com\">\n"
-"<span class=\"whitespace other\" title=\"Tab\">»</span> http://getfirefox.com</a>!"
+msgstr "ä½ å¯ä»¥å–å¾—\n<span class=\"whitespace other\" title=\"Tab\">»</span> 播放這樣檔案的最新ç€è¦½å™¨ <a href=\"http://getfirefox.com\">\n<span class=\"whitespace other\" title=\"Tab\">»</span> http://getfirefox.com</a>!"
#: mediagoblin/templates/mediagoblin/submit/start.html:26
msgid "Add your media"
@@ -440,56 +448,50 @@ msgstr "%(username)s的媒體"
msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media"
msgstr "<a href=\"%(user_url)s\">%(username)s</a>的媒體檔案"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:72
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:46
+#, python-format
+msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>"
+msgstr "â– ç”± <a href=\"%(user_url)s\">%(username)s</a>ç€è¦½åª’體檔案"
+
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:67
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:73
#, python-format
-msgid "Added on %(date)s."
-msgstr "%(date)s. 加入"
+msgid "Image for %(media_title)s"
+msgstr " %(media_title)s的照片"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:81
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:87
msgid "Edit"
msgstr "編輯"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:85
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
msgid "Delete"
msgstr "刪除"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:91
-#, python-format
-msgid "%(comment_count)s comment"
-msgstr "%(comment_count)s è©•è«–"
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:93
-#, python-format
-msgid "%(comment_count)s comments"
-msgstr "%(comment_count)s è©•è«–"
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:124
+msgid "Add a comment"
+msgstr "新增評論"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:95
-msgid "No comments yet."
-msgstr "尚未有評論"
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:103
-msgid "Add one"
-msgstr "新增一個"
-
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:112
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:131
msgid ""
"You can use <a "
"href=\"http://daringfireball.net/projects/markdown/basics\">Markdown</a> for"
" formatting."
-msgstr ""
+msgstr "ä½ å¯ä»¥ç”¨ <a href=\"http://daringfireball.net/projects/markdown/basics\"> Markdown</a> 來排版."
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:116
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:135
msgid "Add this comment"
msgstr "增加此評論"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:138
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:154
msgid "at"
msgstr "在"
-#: mediagoblin/templates/mediagoblin/user_pages/media.html:153
+#: mediagoblin/templates/mediagoblin/user_pages/media.html:174
#, python-format
-msgid "<p>â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a></p>"
-msgstr "<p>■以%(username)sç€è¦½åª’體檔案 <a href=\"%(user_url)s\"></a></p>"
+msgid ""
+"<h3>Added on</h3>\n"
+" <p>%(date)s</p>"
+msgstr "<h3>加入日期</h3>\n <p>%(date)s</p>"
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30
#, python-format
@@ -497,7 +499,7 @@ msgid "Really delete %(title)s?"
msgstr "真的è¦åˆªé™¤ %(title)s?"
#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:50
-msgid "Delete Permanently"
+msgid "Delete permanently"
msgstr "æ°¸é åˆªé™¤"
#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:22
@@ -594,6 +596,10 @@ msgid ""
"anything yet."
msgstr "這個地方是你的媒體檔案會出ç¾çš„地方,但是你似乎還沒有加入任何æ±è¥¿ã€‚"
+#: mediagoblin/templates/mediagoblin/user_pages/user.html:157
+msgid "Add media"
+msgstr "新增媒體檔案"
+
#: mediagoblin/templates/mediagoblin/user_pages/user.html:163
#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:72
msgid "There doesn't seem to be any media here yet..."
@@ -607,13 +613,18 @@ msgstr "feed圖示"
msgid "Atom feed"
msgstr "Atom feed"
-#: mediagoblin/templates/mediagoblin/utils/license.html:21
-msgid "License:"
-msgstr ""
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:25
+msgid "Location"
+msgstr "ä½ç½®"
+
+#: mediagoblin/templates/mediagoblin/utils/geolocation_map.html:38
+#, python-format
+msgid "View on <a href=\"%(osm_url)s\">OpenStreetMap</a>"
+msgstr "在 <a href=\"%(osm_url)s\">OpenStreetMap</a>上觀看"
#: mediagoblin/templates/mediagoblin/utils/license.html:25
msgid "All rights reserved"
-msgstr ""
+msgstr "版權所有"
#: mediagoblin/templates/mediagoblin/utils/pagination.html:39
msgid "↠Newer"
@@ -627,50 +638,44 @@ msgstr "更舊 →"
msgid "Go to page:"
msgstr "è·³åˆ°é æ•¸ï¼š"
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:27
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:32
+#: 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:38
-#: mediagoblin/templates/mediagoblin/utils/prev_next.html:43
+#: 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 "View more media tagged with"
-msgstr "看更多被標籤的媒體"
+msgid "Tagged with"
+msgstr "標籤為"
-#: mediagoblin/templates/mediagoblin/utils/tags.html:25
-msgid "or"
-msgstr "或是"
-
-#: mediagoblin/tools/exif.py:68
+#: mediagoblin/tools/exif.py:75
msgid "Could not read the image file."
-msgstr ""
+msgstr "無法讀å–å½±åƒæª”案。"
#: mediagoblin/user_pages/forms.py:30
msgid "I am sure I want to delete this"
msgstr "我確定我想è¦åˆªé™¤"
-#: mediagoblin/user_pages/views.py:155
+#: mediagoblin/user_pages/views.py:153
msgid "Oops, your comment was empty."
msgstr "啊,你的留言是空的。"
-#: mediagoblin/user_pages/views.py:161
+#: mediagoblin/user_pages/views.py:159
msgid "Your comment has been posted!"
msgstr "你的留言已經刊登ï¼"
-#: mediagoblin/user_pages/views.py:183
+#: mediagoblin/user_pages/views.py:185
msgid "You deleted the media."
msgstr "你已刪除此媒體檔案。"
-#: mediagoblin/user_pages/views.py:190
+#: mediagoblin/user_pages/views.py:192
msgid "The media was not deleted because you didn't check that you were sure."
msgstr "此媒體檔案尚未被刪除因為你還沒有確èªä½ çœŸçš„è¦åˆªé™¤ã€‚"
-#: mediagoblin/user_pages/views.py:198
+#: mediagoblin/user_pages/views.py:200
msgid "You are about to delete another user's media. Proceed with caution."
msgstr "你在刪除其他人的媒體檔案。請å°å¿ƒè™•ç†å–”。"
-
-
diff --git a/mediagoblin/init/__init__.py b/mediagoblin/init/__init__.py
index 7ac59db1..1d8115cb 100644
--- a/mediagoblin/init/__init__.py
+++ b/mediagoblin/init/__init__.py
@@ -24,7 +24,7 @@ from mediagoblin.init.config import (
from mediagoblin import mg_globals
from mediagoblin.mg_globals import setup_globals
from mediagoblin.db.open import setup_connection_and_db_from_config, \
- check_db_migrations_current
+ check_db_migrations_current, load_models
from mediagoblin.workbench import WorkbenchManager
from mediagoblin.storage import storage_system_from_config
@@ -56,6 +56,9 @@ def setup_global_and_app_config(config_path):
def setup_database():
app_config = mg_globals.app_config
+ # Load all models for media types (plugins, ...)
+ load_models(app_config)
+
# Set up the database
connection, db = setup_connection_and_db_from_config(app_config)
diff --git a/mediagoblin/init/celery/__init__.py b/mediagoblin/init/celery/__init__.py
index 29ccd83a..fc595ea7 100644
--- a/mediagoblin/init/celery/__init__.py
+++ b/mediagoblin/init/celery/__init__.py
@@ -17,28 +17,18 @@
import os
import sys
+from celery import Celery
-MANDATORY_CELERY_IMPORTS = ['mediagoblin.processing']
+
+MANDATORY_CELERY_IMPORTS = ['mediagoblin.processing.task']
DEFAULT_SETTINGS_MODULE = 'mediagoblin.init.celery.dummy_settings_module'
-def setup_celery_from_config(app_config, global_config,
- settings_module=DEFAULT_SETTINGS_MODULE,
- force_celery_always_eager=False,
- set_environ=True):
+def get_celery_settings_dict(app_config, global_config,
+ force_celery_always_eager=False):
"""
- Take a mediagoblin app config and try to set up a celery settings
- module from this.
-
- Args:
- - app_config: the application config section
- - global_config: the entire ConfigObj loaded config, all sections
- - settings_module: the module to populate, as a string
- - force_celery_always_eager: whether or not to force celery into
- always eager mode; good for development and small installs
- - set_environ: if set, this will CELERY_CONFIG_MODULE to the
- settings_module
+ Get a celery settings dictionary from reading the config
"""
if 'celery' in global_config:
celery_conf = global_config['celery']
@@ -61,6 +51,41 @@ def setup_celery_from_config(app_config, global_config,
celery_settings['CELERY_ALWAYS_EAGER'] = True
celery_settings['CELERY_EAGER_PROPAGATES_EXCEPTIONS'] = True
+ return celery_settings
+
+
+def setup_celery_app(app_config, global_config,
+ settings_module=DEFAULT_SETTINGS_MODULE,
+ force_celery_always_eager=False):
+ """
+ Setup celery without using terrible setup-celery-module hacks.
+ """
+ celery_settings = get_celery_settings_dict(
+ app_config, global_config, force_celery_always_eager)
+ celery_app = Celery()
+ celery_app.config_from_object(celery_settings)
+
+
+def setup_celery_from_config(app_config, global_config,
+ settings_module=DEFAULT_SETTINGS_MODULE,
+ force_celery_always_eager=False,
+ set_environ=True):
+ """
+ Take a mediagoblin app config and try to set up a celery settings
+ module from this.
+
+ Args:
+ - app_config: the application config section
+ - global_config: the entire ConfigObj loaded config, all sections
+ - settings_module: the module to populate, as a string
+ - force_celery_always_eager: whether or not to force celery into
+ always eager mode; good for development and small installs
+ - set_environ: if set, this will CELERY_CONFIG_MODULE to the
+ settings_module
+ """
+ celery_settings = get_celery_settings_dict(
+ app_config, global_config, force_celery_always_eager)
+
__import__(settings_module)
this_module = sys.modules[settings_module]
diff --git a/mediagoblin/init/celery/from_celery.py b/mediagoblin/init/celery/from_celery.py
index 5a44efe3..b8297255 100644
--- a/mediagoblin/init/celery/from_celery.py
+++ b/mediagoblin/init/celery/from_celery.py
@@ -24,7 +24,7 @@ OUR_MODULENAME = __name__
def setup_self(check_environ_for_conf=True, module_name=OUR_MODULENAME,
- default_conf_file='mediagoblin.ini'):
+ default_conf_file=None):
"""
Transform this module into a celery config module by reading the
mediagoblin config file. Set the environment variable
@@ -35,6 +35,12 @@ def setup_self(check_environ_for_conf=True, module_name=OUR_MODULENAME,
Note that if celery_setup_elsewhere is set in your config file,
this simply won't work.
"""
+ if not default_conf_file:
+ if os.path.exists(os.path.abspath('mediagoblin_local.ini')):
+ default_conf_file = 'mediagoblin_local.ini'
+ else:
+ default_conf_file = 'mediagoblin.ini'
+
if check_environ_for_conf:
mgoblin_conf_file = os.path.abspath(
os.environ.get('MEDIAGOBLIN_CONFIG', default_conf_file))
diff --git a/mediagoblin/init/plugins/__init__.py b/mediagoblin/init/plugins/__init__.py
new file mode 100644
index 00000000..279a5ede
--- /dev/null
+++ b/mediagoblin/init/plugins/__init__.py
@@ -0,0 +1,59 @@
+# 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 <http://www.gnu.org/licenses/>.
+
+import logging
+
+from mediagoblin import mg_globals
+from mediagoblin.tools import pluginapi
+
+
+_log = logging.getLogger(__name__)
+
+
+def setup_plugins():
+ """This loads, configures and registers plugins
+
+ See plugin documentation for more details.
+ """
+
+ global_config = mg_globals.global_config
+ plugin_section = global_config.get('plugins', {})
+
+ if not plugin_section:
+ _log.info("No plugins to load")
+ return
+
+ pcache = pluginapi.PluginCache()
+
+ # Go through and import all the modules that are subsections of
+ # the [plugins] section.
+ for plugin_module, config in plugin_section.items():
+ _log.info("Importing plugin module: %s" % plugin_module)
+ # If this throws errors, that's ok--it'll halt mediagoblin
+ # startup.
+ __import__(plugin_module)
+
+ # Note: One side-effect of importing things is that anything that
+ # subclassed pluginapi.Plugin is registered.
+
+ # Go through all the plugin classes, instantiate them, and call
+ # setup_plugin so they can figure things out.
+ for plugin_class in pcache.plugin_classes:
+ name = plugin_class.__module__ + "." + plugin_class.__name__
+ _log.info("Loading plugin: %s" % name)
+ plugin_obj = plugin_class()
+ plugin_obj.setup_plugin()
+ pcache.register_plugin_object(plugin_obj)
diff --git a/mediagoblin/listings/views.py b/mediagoblin/listings/views.py
index 9244293f..a8824390 100644
--- a/mediagoblin/listings/views.py
+++ b/mediagoblin/listings/views.py
@@ -74,9 +74,7 @@ def tag_atom_feed(request):
"""
tag_slug = request.matchdict[u'tag']
- cursor = request.db.MediaEntry.find(
- {u'state': u'processed',
- u'tags.slug': tag_slug})
+ cursor = media_entries_for_tag_slug(request.db, tag_slug)
cursor = cursor.sort('created', DESCENDING)
cursor = cursor.limit(ATOM_DEFAULT_NR_OF_UPDATED_ITEMS)
diff --git a/mediagoblin/meddleware/csrf.py b/mediagoblin/meddleware/csrf.py
index ea8372bf..74502dc4 100644
--- a/mediagoblin/meddleware/csrf.py
+++ b/mediagoblin/meddleware/csrf.py
@@ -14,8 +14,8 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-import hashlib
import random
+import logging
from webob.exc import HTTPForbidden
from wtforms import Form, HiddenField, validators
@@ -23,6 +23,8 @@ from wtforms import Form, HiddenField, validators
from mediagoblin import mg_globals
from mediagoblin.meddleware import BaseMeddleware
+_log = logging.getLogger(__name__)
+
# Use the system (hardware-based) random number generator if it exists.
# -- this optimization is lifted from Django
if hasattr(random, 'SystemRandom'):
@@ -78,7 +80,7 @@ class CsrfMeddleware(BaseMeddleware):
request.environ['CSRF_TOKEN'] = \
request.cookies[mg_globals.app_config['csrf_cookie_name']]
- except KeyError, e:
+ except KeyError:
# if it doesn't exist, make a new one
request.environ['CSRF_TOKEN'] = self._make_token(request)
@@ -126,6 +128,7 @@ class CsrfMeddleware(BaseMeddleware):
if cookie_token is None:
# the CSRF cookie must be present in the request
+ _log.error('CSRF cookie not present')
return HTTPForbidden()
# get the form token and confirm it matches
@@ -139,4 +142,5 @@ class CsrfMeddleware(BaseMeddleware):
# either the tokens didn't match or the form token wasn't
# present; either way, the request is denied
+ _log.error('CSRF validation failed')
return HTTPForbidden()
diff --git a/mediagoblin/media_types/__init__.py b/mediagoblin/media_types/__init__.py
index 5128826b..93d2319f 100644
--- a/mediagoblin/media_types/__init__.py
+++ b/mediagoblin/media_types/__init__.py
@@ -16,10 +16,13 @@
import os
import sys
+import logging
+import tempfile
from mediagoblin import mg_globals
from mediagoblin.tools.translate import lazy_pass_to_ugettext as _
+_log = logging.getLogger(__name__)
class FileTypeNotSupported(Exception):
pass
@@ -28,6 +31,35 @@ class InvalidFileType(Exception):
pass
+def sniff_media(media):
+ '''
+ Iterate through the enabled media types and find those suited
+ for a certain file.
+ '''
+
+ try:
+ return get_media_type_and_manager(media.filename)
+ except FileTypeNotSupported:
+ _log.info('No media handler found by file extension. Doing it the expensive way...')
+ # Create a temporary file for sniffers suchs as GStreamer-based
+ # Audio video
+ media_file = tempfile.NamedTemporaryFile()
+ media_file.write(media.file.read())
+ media.file.seek(0)
+
+ for media_type, manager in get_media_managers():
+ _log.info('Sniffing {0}'.format(media_type))
+ if manager['sniff_handler'](media_file, media=media):
+ _log.info('{0} accepts the file'.format(media_type))
+ return media_type, manager
+ else:
+ _log.debug('{0} did not accept the file'.format(media_type))
+
+ raise FileTypeNotSupported(
+ # TODO: Provide information on which file types are supported
+ _(u'Sorry, I don\'t support that file type :('))
+
+
def get_media_types():
"""
Generator, yields the available media types
@@ -42,7 +74,7 @@ def get_media_managers():
'''
for media_type in get_media_types():
__import__(media_type)
-
+
yield media_type, sys.modules[media_type].MEDIA_MANAGER
@@ -67,22 +99,22 @@ def get_media_manager(_media_type):
def get_media_type_and_manager(filename):
'''
- Get the media type and manager based on a filename
+ Try to find the media type based on the file name, extension
+ specifically. This is used as a speedup, the sniffing functionality
+ then falls back on more in-depth bitsniffing of the source file.
'''
if filename.find('.') > 0:
# Get the file extension
ext = os.path.splitext(filename)[1].lower()
- else:
- raise InvalidFileType(
- _(u'Could not extract any file extension from "{filename}"').format(
- filename=filename))
- for media_type, manager in get_media_managers():
- # Omit the dot from the extension and match it against
- # the media manager
- if ext[1:] in manager['accepted_extensions']:
- return media_type, manager
+ for media_type, manager in get_media_managers():
+ # Omit the dot from the extension and match it against
+ # the media manager
+ if ext[1:] in manager['accepted_extensions']:
+ return media_type, manager
else:
- raise FileTypeNotSupported(
- # TODO: Provide information on which file types are supported
- _(u'Sorry, I don\'t support that file type :('))
+ _log.info('File {0} has no file extension, let\'s hope the sniffers get it.'.format(
+ filename))
+
+ raise FileTypeNotSupported(
+ _(u'Sorry, I don\'t support that file type :('))
diff --git a/mediagoblin/media_types/ascii/__init__.py b/mediagoblin/media_types/ascii/__init__.py
index 1c8ca562..856d1d7b 100644
--- a/mediagoblin/media_types/ascii/__init__.py
+++ b/mediagoblin/media_types/ascii/__init__.py
@@ -14,13 +14,15 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-from mediagoblin.media_types.ascii.processing import process_ascii
+from mediagoblin.media_types.ascii.processing import process_ascii, \
+ sniff_handler
MEDIA_MANAGER = {
"human_readable": "ASCII",
"processor": process_ascii, # alternately a string,
# 'mediagoblin.media_types.image.processing'?
+ "sniff_handler": sniff_handler,
"display_template": "mediagoblin/media_displays/ascii.html",
"default_thumb": "images/media_thumbs/ascii.jpg",
"accepted_extensions": [
diff --git a/mediagoblin/media_types/ascii/asciitoimage.py b/mediagoblin/media_types/ascii/asciitoimage.py
index e1c4fb44..108de023 100644
--- a/mediagoblin/media_types/ascii/asciitoimage.py
+++ b/mediagoblin/media_types/ascii/asciitoimage.py
@@ -23,6 +23,7 @@ import os
_log = logging.getLogger(__name__)
+
class AsciiToImage(object):
'''
Converter of ASCII art into image files, preserving whitespace
@@ -33,31 +34,12 @@ class AsciiToImage(object):
- font_size: Font size, ``int``
default: 11
'''
-
- # Font file path
- _font = None
-
- _font_size = 11
-
- # ImageFont instance
- _if = None
-
- # ImageFont
- _if_dims = None
-
- # Image instance
- _im = None
-
def __init__(self, **kw):
- if kw.get('font'):
- self._font = kw.get('font')
- else:
- self._font = pkg_resources.resource_filename(
+ self._font = kw.get('font', pkg_resources.resource_filename(
'mediagoblin.media_types.ascii',
- os.path.join('fonts', 'Inconsolata.otf'))
+ os.path.join('fonts', 'Inconsolata.otf')))
- if kw.get('font_size'):
- self._font_size = kw.get('font_size')
+ self._font_size = kw.get('font_size', 11)
self._if = ImageFont.truetype(
self._font,
diff --git a/mediagoblin/media_types/ascii/models.py b/mediagoblin/media_types/ascii/models.py
index 03907339..865c216c 100644
--- a/mediagoblin/media_types/ascii/models.py
+++ b/mediagoblin/media_types/ascii/models.py
@@ -15,19 +15,21 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-from mediagoblin.db.sql.models import Base
+from mediagoblin.db.sql.base import Base
from sqlalchemy import (
- Column, Integer, Unicode, UnicodeText, DateTime, Boolean, ForeignKey,
- UniqueConstraint)
+ Column, Integer, ForeignKey)
+from sqlalchemy.orm import relationship, backref
class AsciiData(Base):
__tablename__ = "ascii__mediadata"
- id = Column(Integer, primary_key=True)
- media_entry = Column(
- Integer, ForeignKey('core__media_entries.id'), nullable=False)
+ # The primary key *and* reference to the main media_entry
+ media_entry = Column(Integer, ForeignKey('core__media_entries.id'),
+ primary_key=True)
+ get_media_entry = relationship("MediaEntry",
+ backref=backref("ascii__media_data", cascade="all, delete-orphan"))
DATA_MODEL = AsciiData
diff --git a/mediagoblin/media_types/ascii/processing.py b/mediagoblin/media_types/ascii/processing.py
index 7ece866e..04d1166c 100644
--- a/mediagoblin/media_types/ascii/processing.py
+++ b/mediagoblin/media_types/ascii/processing.py
@@ -19,22 +19,37 @@ import Image
import logging
from mediagoblin import mg_globals as mgg
-from mediagoblin.processing import create_pub_filepath, THUMB_SIZE
+from mediagoblin.processing import create_pub_filepath
from mediagoblin.media_types.ascii import asciitoimage
_log = logging.getLogger(__name__)
+SUPPORTED_EXTENSIONS = ['txt', 'asc', 'nfo']
+
+
+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_EXTENSIONS:
+ return True
+
+ return False
+
+
def process_ascii(entry):
'''
Code to process a txt file
'''
+ ascii_config = mgg.global_config['media_type:mediagoblin.media_types.ascii']
workbench = mgg.workbench_manager.create_workbench()
# Conversions subdirectory to avoid collisions
conversions_subdir = os.path.join(
workbench.dir, 'conversions')
os.mkdir(conversions_subdir)
- queued_filepath = entry['queued_media_file']
+ queued_filepath = entry.queued_media_file
queued_filename = workbench.localized_file(
mgg.queue_store, queued_filepath,
'source')
@@ -63,13 +78,23 @@ def process_ascii(entry):
tmp_thumb_filename = os.path.join(
conversions_subdir, thumb_filepath[-1])
- converter = asciitoimage.AsciiToImage()
+ ascii_converter_args = {}
+
+ if ascii_config['thumbnail_font']:
+ ascii_converter_args.update(
+ {'font': ascii_config['thumbnail_font']})
+
+ converter = asciitoimage.AsciiToImage(
+ **ascii_converter_args)
thumb = converter._create_image(
queued_file.read())
with file(tmp_thumb_filename, 'w') as thumb_file:
- thumb.thumbnail(THUMB_SIZE, Image.ANTIALIAS)
+ thumb.thumbnail(
+ (mgg.global_config['media:thumb']['max_width'],
+ mgg.global_config['media:thumb']['max_height']),
+ Image.ANTIALIAS)
thumb.save(thumb_file)
_log.debug('Copying local file to public storage')
@@ -84,7 +109,6 @@ def process_ascii(entry):
as original_file:
original_file.write(queued_file.read())
-
queued_file.seek(0) # Rewind *again*
unicode_filepath = create_pub_filepath(entry, 'ascii-portable.txt')
@@ -101,7 +125,7 @@ def process_ascii(entry):
'xmlcharrefreplace'))
mgg.queue_store.delete_file(queued_filepath)
- entry['queued_media_file'] = []
+ entry.queued_media_file = []
media_files_dict = entry.setdefault('media_files', {})
media_files_dict['thumb'] = thumb_filepath
media_files_dict['unicode'] = unicode_filepath
diff --git a/mediagoblin/media_types/audio/__init__.py b/mediagoblin/media_types/audio/__init__.py
new file mode 100644
index 00000000..9b33f9e3
--- /dev/null
+++ b/mediagoblin/media_types/audio/__init__.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 <http://www.gnu.org/licenses/>.
+
+from mediagoblin.media_types.audio.processing import process_audio, \
+ sniff_handler
+
+MEDIA_MANAGER = {
+ 'human_readable': 'Audio',
+ 'processor': process_audio,
+ 'sniff_handler': sniff_handler,
+ 'display_template': 'mediagoblin/media_displays/audio.html',
+ 'accepted_extensions': ['mp3', 'flac', 'ogg', 'wav', 'm4a']}
diff --git a/mediagoblin/media_types/audio/audioprocessing.py b/mediagoblin/media_types/audio/audioprocessing.py
new file mode 120000
index 00000000..c5e3c52c
--- /dev/null
+++ b/mediagoblin/media_types/audio/audioprocessing.py
@@ -0,0 +1 @@
+../../../extlib/freesound/audioprocessing.py \ No newline at end of file
diff --git a/mediagoblin/media_types/audio/migrations.py b/mediagoblin/media_types/audio/migrations.py
new file mode 100644
index 00000000..f54c23ea
--- /dev/null
+++ b/mediagoblin/media_types/audio/migrations.py
@@ -0,0 +1,17 @@
+# 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 <http://www.gnu.org/licenses/>.
+
+MIGRATIONS = {}
diff --git a/mediagoblin/media_types/audio/models.py b/mediagoblin/media_types/audio/models.py
new file mode 100644
index 00000000..5f18d2c2
--- /dev/null
+++ b/mediagoblin/media_types/audio/models.py
@@ -0,0 +1,36 @@
+# 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 <http://www.gnu.org/licenses/>.
+
+
+from mediagoblin.db.sql.base import Base
+
+from sqlalchemy import (
+ Column, Integer, ForeignKey)
+from sqlalchemy.orm import relationship, backref
+
+
+class AudioData(Base):
+ __tablename__ = "audio__mediadata"
+
+ # The primary key *and* reference to the main media_entry
+ media_entry = Column(Integer, ForeignKey('core__media_entries.id'),
+ primary_key=True)
+ get_media_entry = relationship("MediaEntry",
+ backref=backref("audio__media_data", cascade="all, delete-orphan"))
+
+
+DATA_MODEL = AudioData
+MODELS = [AudioData]
diff --git a/mediagoblin/media_types/audio/processing.py b/mediagoblin/media_types/audio/processing.py
new file mode 100644
index 00000000..558a37f0
--- /dev/null
+++ b/mediagoblin/media_types/audio/processing.py
@@ -0,0 +1,145 @@
+# 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 <http://www.gnu.org/licenses/>.
+
+import logging
+import tempfile
+import os
+
+from mediagoblin import mg_globals as mgg
+from mediagoblin.processing import (create_pub_filepath, BadMediaFail,
+ FilenameBuilder)
+
+from mediagoblin.media_types.audio.transcoders import (AudioTranscoder,
+ AudioThumbnailer)
+
+_log = logging.getLogger(__name__)
+
+def sniff_handler(media_file, **kw):
+ try:
+ transcoder = AudioTranscoder()
+ data = transcoder.discover(media_file.name)
+ except BadMediaFail:
+ _log.debug('Audio discovery raised BadMediaFail')
+ return False
+
+ if data.is_audio == True and data.is_video == False:
+ return True
+
+ return False
+
+def process_audio(entry):
+ audio_config = mgg.global_config['media_type:mediagoblin.media_types.audio']
+
+ workbench = mgg.workbench_manager.create_workbench()
+
+ queued_filepath = entry.queued_media_file
+ queued_filename = workbench.localized_file(
+ mgg.queue_store, queued_filepath,
+ 'source')
+ name_builder = FilenameBuilder(queued_filename)
+
+ webm_audio_filepath = create_pub_filepath(
+ entry,
+ '{original}.webm'.format(
+ original=os.path.splitext(
+ queued_filepath[-1])[0]))
+
+ if audio_config['keep_original']:
+ with open(queued_filename, 'rb') as queued_file:
+ original_filepath = create_pub_filepath(
+ entry, name_builder.fill('{basename}{ext}'))
+
+ with mgg.public_store.get_file(original_filepath, 'wb') as \
+ original_file:
+ _log.debug('Saving original...')
+ original_file.write(queued_file.read())
+
+ entry.media_files['original'] = original_filepath
+
+ transcoder = AudioTranscoder()
+
+ with tempfile.NamedTemporaryFile() as webm_audio_tmp:
+
+ transcoder.transcode(
+ queued_filename,
+ webm_audio_tmp.name,
+ quality=audio_config['quality'])
+
+ transcoder.discover(webm_audio_tmp.name)
+
+ _log.debug('Saving medium...')
+ mgg.public_store.get_file(webm_audio_filepath, 'wb').write(
+ webm_audio_tmp.read())
+
+ entry.media_files['webm_audio'] = webm_audio_filepath
+
+ # entry.media_data_init(length=int(data.audiolength))
+
+ if audio_config['create_spectrogram']:
+ spectrogram_filepath = create_pub_filepath(
+ entry,
+ '{original}-spectrogram.jpg'.format(
+ original=os.path.splitext(
+ queued_filepath[-1])[0]))
+
+ with tempfile.NamedTemporaryFile(suffix='.wav') as wav_tmp:
+ _log.info('Creating WAV source for spectrogram')
+ transcoder.transcode(
+ queued_filename,
+ wav_tmp.name,
+ mux_string='wavenc')
+
+ thumbnailer = AudioThumbnailer()
+
+ with tempfile.NamedTemporaryFile(suffix='.jpg') as spectrogram_tmp:
+ thumbnailer.spectrogram(
+ wav_tmp.name,
+ spectrogram_tmp.name,
+ width=mgg.global_config['media:medium']['max_width'],
+ fft_size=audio_config['spectrogram_fft_size'])
+
+ _log.debug('Saving spectrogram...')
+ mgg.public_store.get_file(spectrogram_filepath, 'wb').write(
+ spectrogram_tmp.read())
+
+ entry.media_files['spectrogram'] = spectrogram_filepath
+
+ with tempfile.NamedTemporaryFile(suffix='.jpg') as thumb_tmp:
+ thumbnailer.thumbnail_spectrogram(
+ spectrogram_tmp.name,
+ thumb_tmp.name,
+ (mgg.global_config['media:thumb']['max_width'],
+ mgg.global_config['media:thumb']['max_height']))
+
+ thumb_filepath = create_pub_filepath(
+ entry,
+ '{original}-thumbnail.jpg'.format(
+ original=os.path.splitext(
+ queued_filepath[-1])[0]))
+
+ mgg.public_store.get_file(thumb_filepath, 'wb').write(
+ thumb_tmp.read())
+
+ entry.media_files['thumb'] = thumb_filepath
+ else:
+ entry.media_files['thumb'] = ['fake', 'thumb', 'path.jpg']
+
+ mgg.queue_store.delete_file(queued_filepath)
+
+ entry.save()
+
+ # clean up workbench
+ workbench.destroy_self()
diff --git a/mediagoblin/media_types/audio/transcoders.py b/mediagoblin/media_types/audio/transcoders.py
new file mode 100644
index 00000000..be80aa0e
--- /dev/null
+++ b/mediagoblin/media_types/audio/transcoders.py
@@ -0,0 +1,237 @@
+# 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 <http://www.gnu.org/licenses/>.
+
+import pdb
+import logging
+import Image
+
+from mediagoblin.processing import BadMediaFail
+from mediagoblin.media_types.audio import audioprocessing
+
+
+_log = logging.getLogger(__name__)
+
+CPU_COUNT = 2 # Just assuming for now
+
+# IMPORT MULTIPROCESSING
+try:
+ import multiprocessing
+ try:
+ CPU_COUNT = multiprocessing.cpu_count()
+ except NotImplementedError:
+ _log.warning('multiprocessing.cpu_count not implemented!\n'
+ 'Assuming 2 CPU cores')
+except ImportError:
+ _log.warning('Could not import multiprocessing, assuming 2 CPU cores')
+
+# IMPORT GOBJECT
+try:
+ import gobject
+ gobject.threads_init()
+except ImportError:
+ raise Exception('gobject could not be found')
+
+# IMPORT PYGST
+try:
+ import pygst
+
+ # We won't settle for less. For now, this is an arbitrary limit
+ # as we have not tested with > 0.10
+ pygst.require('0.10')
+
+ import gst
+
+ import gst.extend.discoverer
+except ImportError:
+ raise Exception('gst/pygst >= 0.10 could not be imported')
+
+import numpy
+
+
+class AudioThumbnailer(object):
+ def __init__(self):
+ _log.info('Initializing {0}'.format(self.__class__.__name__))
+
+ def spectrogram(self, src, dst, **kw):
+ width = kw['width']
+ height = int(kw.get('height', float(width) * 0.3))
+ fft_size = kw.get('fft_size', 2048)
+ callback = kw.get('progress_callback')
+
+ processor = audioprocessing.AudioProcessor(
+ src,
+ fft_size,
+ numpy.hanning)
+
+ samples_per_pixel = processor.audio_file.nframes / float(width)
+
+ spectrogram = audioprocessing.SpectrogramImage(width, height, fft_size)
+
+ for x in range(width):
+ if callback and x % (width / 10) == 0:
+ callback((x * 100) / width)
+
+ seek_point = int(x * samples_per_pixel)
+
+ (spectral_centroid, db_spectrum) = processor.spectral_centroid(
+ seek_point)
+
+ spectrogram.draw_spectrum(x, db_spectrum)
+
+ if callback:
+ callback(100)
+
+ spectrogram.save(dst)
+
+ def thumbnail_spectrogram(self, src, dst, thumb_size):
+ '''
+ Takes a spectrogram and creates a thumbnail from it
+ '''
+ if not (type(thumb_size) == tuple and len(thumb_size) == 2):
+ raise Exception('thumb_size argument should be a tuple(width, height)')
+
+ im = Image.open(src)
+
+ im_w, im_h = [float(i) for i in im.size]
+ th_w, th_h = [float(i) for i in thumb_size]
+
+ wadsworth_position = im_w * 0.3
+
+ start_x = max((
+ wadsworth_position - ((im_h * (th_w / th_h)) / 2.0),
+ 0.0))
+
+ stop_x = start_x + (im_h * (th_w / th_h))
+
+ th = im.crop((
+ int(start_x), 0,
+ int(stop_x), int(im_h)))
+
+ if th.size[0] > th_w or th.size[1] > th_h:
+ th.thumbnail(thumb_size, Image.ANTIALIAS)
+
+ th.save(dst)
+
+
+class AudioTranscoder(object):
+ def __init__(self):
+ _log.info('Initializing {0}'.format(self.__class__.__name__))
+
+ # Instantiate MainLoop
+ self._loop = gobject.MainLoop()
+ self._failed = None
+
+ def discover(self, src):
+ self._src_path = src
+ _log.info('Discovering {0}'.format(src))
+ self._discovery_path = src
+
+ self._discoverer = gst.extend.discoverer.Discoverer(
+ self._discovery_path)
+ self._discoverer.connect('discovered', self.__on_discovered)
+ self._discoverer.discover()
+
+ self._loop.run() # Run MainLoop
+
+ if self._failed:
+ raise self._failed
+
+ # Once MainLoop has returned, return discovery data
+ return getattr(self, '_discovery_data', False)
+
+ def __on_discovered(self, data, is_media):
+ if not is_media:
+ self._failed = BadMediaFail()
+ _log.error('Could not discover {0}'.format(self._src_path))
+ self.halt()
+
+ _log.debug('Discovered: {0}'.format(data.__dict__))
+
+ self._discovery_data = data
+
+ # Gracefully shut down MainLoop
+ self.halt()
+
+ def transcode(self, src, dst, **kw):
+ _log.info('Transcoding {0} into {1}'.format(src, dst))
+ self._discovery_data = kw.get('data', self.discover(src))
+
+ self.__on_progress = kw.get('progress_callback')
+
+ quality = kw.get('quality', 0.3)
+
+ mux_string = kw.get(
+ 'mux_string',
+ 'vorbisenc quality={0} ! webmmux'.format(quality))
+
+ # Set up pipeline
+ self.pipeline = gst.parse_launch(
+ 'filesrc location="{src}" ! '
+ 'decodebin2 ! queue ! audiorate tolerance={tolerance} ! '
+ 'audioconvert ! audio/x-raw-float,channels=2 ! '
+ '{mux_string} ! '
+ 'progressreport silent=true ! '
+ 'filesink location="{dst}"'.format(
+ src=src,
+ tolerance=80000000,
+ mux_string=mux_string,
+ dst=dst))
+
+ self.bus = self.pipeline.get_bus()
+ self.bus.add_signal_watch()
+ self.bus.connect('message', self.__on_bus_message)
+
+ self.pipeline.set_state(gst.STATE_PLAYING)
+
+ self._loop.run()
+
+ def __on_bus_message(self, bus, message):
+ _log.debug(message)
+
+ if (message.type == gst.MESSAGE_ELEMENT
+ and message.structure.get_name() == 'progress'):
+ data = dict(message.structure)
+
+ if self.__on_progress:
+ self.__on_progress(data)
+
+ _log.info('{0}% done...'.format(
+ data.get('percent')))
+ elif message.type == gst.MESSAGE_EOS:
+ _log.info('Done')
+ self.halt()
+
+ def halt(self):
+ if getattr(self, 'pipeline', False):
+ self.pipeline.set_state(gst.STATE_NULL)
+ del self.pipeline
+ _log.info('Quitting MainLoop gracefully...')
+ gobject.idle_add(self._loop.quit)
+
+if __name__ == '__main__':
+ import sys
+ logging.basicConfig()
+ _log.setLevel(logging.INFO)
+
+ #transcoder = AudioTranscoder()
+ #data = transcoder.discover(sys.argv[1])
+ #res = transcoder.transcode(*sys.argv[1:3])
+
+ thumbnailer = AudioThumbnailer()
+
+ thumbnailer.spectrogram(*sys.argv[1:], width=640)
+
+ pdb.set_trace()
diff --git a/mediagoblin/media_types/image/__init__.py b/mediagoblin/media_types/image/__init__.py
index 98e0c32a..d4720fab 100644
--- a/mediagoblin/media_types/image/__init__.py
+++ b/mediagoblin/media_types/image/__init__.py
@@ -14,13 +14,15 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-from mediagoblin.media_types.image.processing import process_image
+from mediagoblin.media_types.image.processing import process_image, \
+ sniff_handler
MEDIA_MANAGER = {
"human_readable": "Image",
"processor": process_image, # alternately a string,
# 'mediagoblin.media_types.image.processing'?
+ "sniff_handler": sniff_handler,
"display_template": "mediagoblin/media_displays/image.html",
"default_thumb": "images/media_thumbs/image.jpg",
"accepted_extensions": ["jpg", "jpeg", "png", "gif", "tiff"]}
diff --git a/mediagoblin/media_types/image/models.py b/mediagoblin/media_types/image/models.py
index f333cbb8..fc518daa 100644
--- a/mediagoblin/media_types/image/models.py
+++ b/mediagoblin/media_types/image/models.py
@@ -1,7 +1,26 @@
-from mediagoblin.db.sql.models import Base
+# 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 <http://www.gnu.org/licenses/>.
+
+
+from mediagoblin.db.sql.base import Base
from sqlalchemy import (
Column, Integer, Float, ForeignKey)
+from sqlalchemy.orm import relationship, backref
+from mediagoblin.db.sql.extratypes import JSONEncoded
class ImageData(Base):
@@ -10,8 +29,12 @@ class ImageData(Base):
# The primary key *and* reference to the main media_entry
media_entry = Column(Integer, ForeignKey('core__media_entries.id'),
primary_key=True)
+ get_media_entry = relationship("MediaEntry",
+ backref=backref("image__media_data", cascade="all, delete-orphan"))
+
width = Column(Integer)
height = Column(Integer)
+ exif_all = Column(JSONEncoded)
gps_longitude = Column(Float)
gps_latitude = Column(Float)
gps_altitude = Column(Float)
diff --git a/mediagoblin/media_types/image/processing.py b/mediagoblin/media_types/image/processing.py
index 6ba91a15..bbfcd32d 100644
--- a/mediagoblin/media_types/image/processing.py
+++ b/mediagoblin/media_types/image/processing.py
@@ -16,12 +16,69 @@
import Image
import os
+import logging
from mediagoblin import mg_globals as mgg
from mediagoblin.processing import BadMediaFail, \
- create_pub_filepath, THUMB_SIZE, MEDIUM_SIZE
+ create_pub_filepath, FilenameBuilder
from mediagoblin.tools.exif import exif_fix_image_orientation, \
- extract_exif, clean_exif, get_gps_data, get_useful
+ extract_exif, clean_exif, get_gps_data, get_useful, \
+ exif_image_needs_rotation
+
+_log = logging.getLogger(__name__)
+
+
+def resize_image(entry, filename, new_path, exif_tags, workdir, new_size,
+ size_limits=(0, 0)):
+ """Store a resized version of an image and return its pathname.
+
+ Arguments:
+ entry -- the entry for the image to resize
+ filename -- the filename of the original image being resized
+ new_path -- public file path for the new resized image
+ exif_tags -- EXIF data for the original image
+ workdir -- directory path for storing converted image files
+ new_size -- 2-tuple size for the resized image
+ """
+ try:
+ resized = Image.open(filename)
+ except IOError:
+ raise BadMediaFail()
+ resized = exif_fix_image_orientation(resized, exif_tags) # Fix orientation
+ resized.thumbnail(new_size, Image.ANTIALIAS)
+
+ # Copy the new file to the conversion subdir, then remotely.
+ tmp_resized_filename = os.path.join(workdir, new_path[-1])
+ with file(tmp_resized_filename, 'w') as resized_file:
+ resized.save(resized_file)
+ mgg.public_store.copy_local_to_storage(tmp_resized_filename, new_path)
+
+
+SUPPORTED_FILETYPES = ['png', 'gif', 'jpg', 'jpeg']
+
+
+def sniff_handler(media_file, **kw):
+ if kw.get('media') is not None: # That's a double negative!
+ name, ext = os.path.splitext(kw['media'].filename)
+ clean_ext = ext[1:].lower() # Strip the . from ext and make lowercase
+
+ _log.debug('name: {0}\next: {1}\nlower_ext: {2}'.format(
+ name,
+ ext,
+ clean_ext))
+
+ if clean_ext in SUPPORTED_FILETYPES:
+ _log.info('Found file extension in supported filetypes')
+ return True
+ else:
+ _log.debug('Media present, extension not found in {0}'.format(
+ SUPPORTED_FILETYPES))
+ else:
+ _log.warning('Need additional information (keyword argument \'media\')'
+ ' to be able to handle sniffing')
+
+ return False
+
def process_image(entry):
"""
@@ -32,72 +89,48 @@ def process_image(entry):
conversions_subdir = os.path.join(
workbench.dir, 'conversions')
os.mkdir(conversions_subdir)
-
queued_filepath = entry.queued_media_file
queued_filename = workbench.localized_file(
mgg.queue_store, queued_filepath,
'source')
-
- filename_bits = os.path.splitext(queued_filename)
- basename = os.path.split(filename_bits[0])[1]
- extension = filename_bits[1].lower()
+ name_builder = FilenameBuilder(queued_filename)
# EXIF extraction
exif_tags = extract_exif(queued_filename)
gps_data = get_gps_data(exif_tags)
- try:
- thumb = Image.open(queued_filename)
- except IOError:
- raise BadMediaFail()
-
- thumb = exif_fix_image_orientation(thumb, exif_tags)
-
- thumb.thumbnail(THUMB_SIZE, Image.ANTIALIAS)
-
- # Copy the thumb to the conversion subdir, then remotely.
- thumb_filename = 'thumbnail' + extension
- thumb_filepath = create_pub_filepath(entry, thumb_filename)
-
- tmp_thumb_filename = os.path.join(
- conversions_subdir, thumb_filename)
-
- with file(tmp_thumb_filename, 'w') as thumb_file:
- thumb.save(thumb_file)
-
- mgg.public_store.copy_local_to_storage(
- tmp_thumb_filename, thumb_filepath)
+ # Always create a small thumbnail
+ thumb_filepath = create_pub_filepath(
+ entry, name_builder.fill('{basename}.thumbnail{ext}'))
+ resize_image(entry, queued_filename, thumb_filepath,
+ exif_tags, conversions_subdir,
+ (mgg.global_config['media:thumb']['max_width'],
+ mgg.global_config['media:thumb']['max_height']))
# If the size of the original file exceeds the specified size of a `medium`
- # file, a `medium.jpg` files is created and later associated with the media
+ # file, a `.medium.jpg` files is created and later associated with the media
# entry.
medium = Image.open(queued_filename)
-
- # Fix orientation
- medium = exif_fix_image_orientation(medium, exif_tags)
-
- if medium.size[0] > MEDIUM_SIZE[0] or medium.size[1] > MEDIUM_SIZE[1]:
- medium.thumbnail(MEDIUM_SIZE, Image.ANTIALIAS)
-
- medium_filename = 'medium' + extension
- medium_filepath = create_pub_filepath(entry, medium_filename)
-
- tmp_medium_filename = os.path.join(
- conversions_subdir, medium_filename)
-
- with file(tmp_medium_filename, 'w') as medium_file:
- medium.save(medium_file)
-
- mgg.public_store.copy_local_to_storage(
- tmp_medium_filename, medium_filepath)
+ if medium.size[0] > mgg.global_config['media:medium']['max_width'] \
+ or medium.size[1] > mgg.global_config['media:medium']['max_height'] \
+ or exif_image_needs_rotation(exif_tags):
+ medium_filepath = create_pub_filepath(
+ entry, name_builder.fill('{basename}.medium{ext}'))
+ resize_image(
+ entry, queued_filename, medium_filepath,
+ exif_tags, conversions_subdir,
+ (mgg.global_config['media:medium']['max_width'],
+ mgg.global_config['media:medium']['max_height']))
+ else:
+ medium_filepath = None
# we have to re-read because unlike PIL, not everything reads
# things in string representation :)
queued_file = file(queued_filename, 'rb')
with queued_file:
- #create_pub_filepath(entry, queued_filepath[-1])
- original_filepath = create_pub_filepath(entry, basename + extension)
+ original_filepath = create_pub_filepath(
+ entry, name_builder.fill('{basename}{ext}'))
with mgg.public_store.get_file(original_filepath, 'wb') \
as original_file:
@@ -111,17 +144,14 @@ def process_image(entry):
media_files_dict = entry.setdefault('media_files', {})
media_files_dict['thumb'] = thumb_filepath
media_files_dict['original'] = original_filepath
- media_files_dict['medium'] = medium_filepath
+ if medium_filepath:
+ media_files_dict['medium'] = medium_filepath
# Insert exif data into database
- media_data = entry.setdefault('media_data', {})
-
- # TODO: Fix for sql media_data, when exif is in sql
- if media_data is not None:
- media_data['exif'] = {
- 'clean': clean_exif(exif_tags)}
- media_data['exif']['useful'] = get_useful(
- media_data['exif']['clean'])
+ exif_all = clean_exif(exif_tags)
+
+ if len(exif_all):
+ entry.media_data_init(exif_all=exif_all)
if len(gps_data):
for key in list(gps_data.keys()):
diff --git a/mediagoblin/media_types/video/__init__.py b/mediagoblin/media_types/video/__init__.py
index 579fdc6a..3faa5b9f 100644
--- a/mediagoblin/media_types/video/__init__.py
+++ b/mediagoblin/media_types/video/__init__.py
@@ -14,16 +14,16 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-from mediagoblin.media_types.video.processing import process_video
+from mediagoblin.media_types.video.processing import process_video, \
+ sniff_handler
MEDIA_MANAGER = {
"human_readable": "Video",
- "processor": process_video, # alternately a string,
- # 'mediagoblin.media_types.image.processing'?
+ "processor": process_video, # alternately a string,
+ # 'mediagoblin.media_types.image.processing'?
+ "sniff_handler": sniff_handler,
"display_template": "mediagoblin/media_displays/video.html",
"default_thumb": "images/media_thumbs/video.jpg",
- # TODO: This list should be autogenerated based on gst plugins
"accepted_extensions": [
- "mp4", "mov", "webm", "avi", "3gp", "3gpp", "mkv", "ogv", "ogg",
- "m4v"]}
+ "mp4", "mov", "webm", "avi", "3gp", "3gpp", "mkv", "ogv", "m4v"]}
diff --git a/mediagoblin/media_types/video/models.py b/mediagoblin/media_types/video/models.py
index 0d064f5f..35ed92bf 100644
--- a/mediagoblin/media_types/video/models.py
+++ b/mediagoblin/media_types/video/models.py
@@ -15,10 +15,11 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-from mediagoblin.db.sql.models import Base
+from mediagoblin.db.sql.base import Base
from sqlalchemy import (
Column, Integer, SmallInteger, ForeignKey)
+from sqlalchemy.orm import relationship, backref
class VideoData(Base):
@@ -27,6 +28,9 @@ class VideoData(Base):
# The primary key *and* reference to the main media_entry
media_entry = Column(Integer, ForeignKey('core__media_entries.id'),
primary_key=True)
+ get_media_entry = relationship("MediaEntry",
+ backref=backref("video__media_data", cascade="all, delete-orphan"))
+
width = Column(SmallInteger)
height = Column(SmallInteger)
diff --git a/mediagoblin/media_types/video/processing.py b/mediagoblin/media_types/video/processing.py
index 3a479802..5bbcc92f 100644
--- a/mediagoblin/media_types/video/processing.py
+++ b/mediagoblin/media_types/video/processing.py
@@ -16,30 +16,37 @@
import tempfile
import logging
-import os
from mediagoblin import mg_globals as mgg
-from mediagoblin.processing import mark_entry_failed, \
- THUMB_SIZE, MEDIUM_SIZE, create_pub_filepath
+from mediagoblin.processing import \
+ create_pub_filepath, FilenameBuilder
from . import transcoders
-logging.basicConfig()
-
_log = logging.getLogger(__name__)
_log.setLevel(logging.DEBUG)
-def process_video(entry):
- """
- Code to process a video
+def sniff_handler(media_file, **kw):
+ transcoder = transcoders.VideoTranscoder()
+ data = transcoder.discover(media_file.name)
+
+ _log.debug('Discovered: {0}'.format(data))
+
+ if not data:
+ _log.error('Could not discover {0}'.format(
+ kw.get('media')))
+ return False
- Much of this code is derived from the arista-transcoder script in
- the arista PyPI package and changed to match the needs of
- MediaGoblin
+ if data['is_video'] == True:
+ return True
- This function sets up the arista video encoder in some kind of new thread
- and attaches callbacks to that child process, hopefully, the
- entry-complete callback will be called when the video is done.
+ return False
+
+
+def process_video(entry):
+ """
+ Process a video entry, transcode the queued media files (originals) and
+ create a thumbnail for the entry.
"""
video_config = mgg.global_config['media_type:mediagoblin.media_types.video']
@@ -49,24 +56,24 @@ def process_video(entry):
queued_filename = workbench.localized_file(
mgg.queue_store, queued_filepath,
'source')
+ name_builder = FilenameBuilder(queued_filename)
medium_filepath = create_pub_filepath(
- entry,
- '{original}-640p.webm'.format(
- original=os.path.splitext(
- queued_filepath[-1])[0] # Select the
- ))
+ entry, name_builder.fill('{basename}-640p.webm'))
thumbnail_filepath = create_pub_filepath(
- entry, 'thumbnail.jpg')
-
+ entry, name_builder.fill('{basename}.thumbnail.jpg'))
# Create a temporary file for the video destination
tmp_dst = tempfile.NamedTemporaryFile()
with tmp_dst:
# Transcode queued file to a VP8/vorbis file that fits in a 640x640 square
- transcoder = transcoders.VideoTranscoder(queued_filename, tmp_dst.name)
+ transcoder = transcoders.VideoTranscoder()
+ transcoder.transcode(queued_filename, tmp_dst.name,
+ vp8_quality=video_config['vp8_quality'],
+ vp8_threads=video_config['vp8_threads'],
+ vorbis_quality=video_config['vorbis_quality'])
# Push transcoded video to public storage
_log.debug('Saving medium...')
@@ -82,7 +89,7 @@ def process_video(entry):
height=transcoder.dst_data.videoheight)
# Create a temporary file for the video thumbnail
- tmp_thumb = tempfile.NamedTemporaryFile()
+ tmp_thumb = tempfile.NamedTemporaryFile(suffix='.jpg')
with tmp_thumb:
# Create a thumbnail.jpg that fits in a 180x180 square
diff --git a/mediagoblin/media_types/video/transcoders.py b/mediagoblin/media_types/video/transcoders.py
index 6137c3bf..e03f721f 100644
--- a/mediagoblin/media_types/video/transcoders.py
+++ b/mediagoblin/media_types/video/transcoders.py
@@ -17,47 +17,40 @@
from __future__ import division
import os
-os.putenv('GST_DEBUG_DUMP_DOT_DIR', '/tmp')
-
import sys
import logging
-import pdb
import urllib
+import multiprocessing
+import gobject
+import pygst
+pygst.require('0.10')
+import gst
+import struct
+import Image
+
+from gst.extend import discoverer
_log = logging.getLogger(__name__)
-logging.basicConfig()
-_log.setLevel(logging.DEBUG)
+
+gobject.threads_init()
CPU_COUNT = 2
-try:
- import multiprocessing
- try:
- CPU_COUNT = multiprocessing.cpu_count()
- except NotImplementedError:
- _log.warning('multiprocessing.cpu_count not implemented')
- pass
-except ImportError:
- _log.warning('Could not import multiprocessing, defaulting to 2 CPU cores')
- pass
try:
- import gtk
-except:
- raise Exception('Could not find pygtk')
+ CPU_COUNT = multiprocessing.cpu_count()
+except NotImplementedError:
+ _log.warning('multiprocessing.cpu_count not implemented')
-try:
- import gobject
- gobject.threads_init()
-except:
- raise Exception('gobject could not be found')
+os.putenv('GST_DEBUG_DUMP_DOT_DIR', '/tmp')
-try:
- import pygst
- pygst.require('0.10')
- import gst
- from gst.extend import discoverer
-except:
- raise Exception('gst/pygst 0.10 could not be found')
+
+def pixbuf_to_pilbuf(buf):
+ data = list()
+ for i in range(0, len(buf), 3):
+ r, g, b = struct.unpack('BBB', buf[i:i + 3])
+ data.append((r, g, b))
+
+ return data
class VideoThumbnailer:
@@ -79,6 +72,11 @@ class VideoThumbnailer:
Set up playbin pipeline in order to get video properties.
Initializes and runs the gobject.MainLoop()
+
+ Abstract
+ - Set up a playbin with a fake audio sink and video sink. Load the video
+ into the playbin
+ - Initialize
'''
self.errors = []
@@ -112,9 +110,10 @@ class VideoThumbnailer:
self.loop.run()
def _on_bus_message(self, bus, message):
- _log.debug(' BUS MESSAGE: {0}'.format(message))
+ _log.debug(' thumbnail playbin: {0}'.format(message))
if message.type == gst.MESSAGE_ERROR:
+ _log.error('thumbnail playbin: {0}'.format(message))
gobject.idle_add(self._on_bus_error)
elif message.type == gst.MESSAGE_STATE_CHANGED:
@@ -161,13 +160,14 @@ class VideoThumbnailer:
return False
def _on_thumbnail_bus_message(self, bus, message):
- _log.debug('Thumbnail bus called, message: {0}'.format(message))
+ _log.debug('thumbnail: {0}'.format(message))
if message.type == gst.MESSAGE_ERROR:
_log.error(message)
gobject.idle_add(self._on_bus_error)
if message.type == gst.MESSAGE_STATE_CHANGED:
+ _log.debug('State changed')
_prev, state, _pending = message.parse_state_changed()
if (state == gst.STATE_PAUSED and
@@ -191,6 +191,7 @@ class VideoThumbnailer:
break
# Apply the wadsworth constant, fallback to 1 second
+ # TODO: Will break if video is shorter than 1 sec
seek_amount = max(self.duration / 100 * 30, 1 * gst.SECOND)
_log.debug('seek amount: {0}'.format(seek_amount))
@@ -211,14 +212,18 @@ class VideoThumbnailer:
_log.info(message)
self.shutdown()
else:
- pass
- #self.thumbnail_pipeline.set_state(gst.STATE_PAUSED)
- #pdb.set_trace()
+ _log.debug('Seek successful')
+ self.thumbnail_pipeline.set_state(gst.STATE_PAUSED)
+ else:
+ _log.debug('Won\'t seek: \t{0}\n\t{1}'.format(
+ self.state,
+ message.src))
def buffer_probe_handler_real(self, pad, buff, name):
'''
Capture buffers as gdk_pixbufs when told to.
'''
+ _log.info('Capturing frame')
try:
caps = buff.caps
if caps is None:
@@ -232,29 +237,28 @@ class VideoThumbnailer:
width = filters["width"]
height = filters["height"]
- pixbuf = gtk.gdk.pixbuf_new_from_data(
- buff.data, gtk.gdk.COLORSPACE_RGB, False, 8,
- width, height, width * 3)
+ im = Image.new('RGB', (width, height))
- # NOTE: 200x136 is sort of arbitrary. it's larger than what
- # the ui uses at the time of this writing.
- # new_width, new_height = scaled_size((width, height), (200, 136))
+ data = pixbuf_to_pilbuf(buff.data)
- #pixbuf = pixbuf.scale_simple(
- #new_width, new_height, gtk.gdk.INTERP_BILINEAR)
+ im.putdata(data)
+
+ im.save(self.dest_path)
- pixbuf.save(self.dest_path, 'jpeg')
_log.info('Saved thumbnail')
- del pixbuf
+
self.shutdown()
- except gst.QueryError:
- pass
+
+ except gst.QueryError as e:
+ _log.error('QueryError: {0}'.format(e))
+
return False
def buffer_probe_handler(self, pad, buff, name):
'''
Proxy function for buffer_probe_handler_real
'''
+ _log.debug('Attaching real buffer handler to gobject idle event')
gobject.idle_add(
lambda: self.buffer_probe_handler_real(pad, buff, name))
@@ -270,12 +274,12 @@ class VideoThumbnailer:
return 0
try:
- return pipeline.query_duration(gst.FORMAT_TIME)[0]
+ return pipeline.query_duration(gst.FORMAT_TIME)[0]
except gst.QueryError:
return self._get_duration(pipeline, retries + 1)
def _on_timeout(self):
- _log.error('TIMEOUT! DROP EVERYTHING!')
+ _log.error('Timeout in thumbnailer!')
self.shutdown()
def _on_bus_error(self, *args):
@@ -320,12 +324,11 @@ class VideoThumbnailer:
self.bus.disconnect(self.watch_id)
self.bus = None
-
def __halt_final(self):
_log.info('Done')
if self.errors:
_log.error(','.join(self.errors))
-
+
self.loop.quit()
@@ -341,15 +344,37 @@ class VideoTranscoder:
that it was refined afterwards and therefore is done more
correctly.
'''
- def __init__(self, src, dst, **kwargs):
+ def __init__(self):
_log.info('Initializing VideoTranscoder...')
self.loop = gobject.MainLoop()
+
+ def transcode(self, src, dst, **kwargs):
+ '''
+ Transcode a video file into a 'medium'-sized version.
+ '''
self.source_path = src
self.destination_path = dst
- # Options
- self.destination_dimensions = kwargs.get('dimensions') or (640, 640)
+ # vp8enc options
+ self.destination_dimensions = kwargs.get('dimensions', (640, 640))
+ self.vp8_quality = kwargs.get('vp8_quality', 8)
+ # Number of threads used by vp8enc:
+ # number of real cores - 1 as per recommendation on
+ # <http://www.webmproject.org/tools/encoder-parameters/#6-multi-threaded-encode-and-decode>
+ self.vp8_threads = kwargs.get('vp8_threads', CPU_COUNT - 1)
+
+ # 0 means auto-detect, but dict.get() only falls back to CPU_COUNT
+ # if value is None, this will correct our incompatibility with
+ # dict.get()
+ # This will also correct cases where there's only 1 CPU core, see
+ # original self.vp8_threads assignment above.
+ if self.vp8_threads == 0:
+ self.vp8_threads = CPU_COUNT
+
+ # vorbisenc options
+ self.vorbis_quality = kwargs.get('vorbis_quality', 0.3)
+
self._progress_callback = kwargs.get('progress_callback') or None
if not type(self.destination_dimensions) == tuple:
@@ -358,6 +383,34 @@ class VideoTranscoder:
self._setup()
self._run()
+ def discover(self, src):
+ '''
+ Discover properties about a media file
+ '''
+ _log.info('Discovering {0}'.format(src))
+
+ self.source_path = src
+ self._setup_discover(discovered_callback=self.__on_discovered)
+
+ self.discoverer.discover()
+
+ self.loop.run()
+
+ if hasattr(self, '_discovered_data'):
+ return self._discovered_data.__dict__
+ else:
+ return None
+
+ def __on_discovered(self, data, is_media):
+ _log.debug('Discovered: {0}'.format(data))
+ if not is_media:
+ self.__stop()
+ raise Exception('Could not discover {0}'.format(self.source_path))
+
+ self._discovered_data = data
+
+ self.__stop_mainloop()
+
def _setup(self):
self._setup_discover()
self._setup_pipeline()
@@ -370,12 +423,14 @@ class VideoTranscoder:
_log.debug('Initializing MainLoop()')
self.loop.run()
- def _setup_discover(self):
+ def _setup_discover(self, **kw):
_log.debug('Setting up discoverer')
self.discoverer = discoverer.Discoverer(self.source_path)
# Connect self.__discovered to the 'discovered' event
- self.discoverer.connect('discovered', self.__discovered)
+ self.discoverer.connect(
+ 'discovered',
+ kw.get('discovered_callback', self.__discovered))
def __discovered(self, data, is_media):
'''
@@ -422,7 +477,7 @@ class VideoTranscoder:
self.ffmpegcolorspace = gst.element_factory_make(
'ffmpegcolorspace', 'ffmpegcolorspace')
self.pipeline.add(self.ffmpegcolorspace)
-
+
self.videoscale = gst.element_factory_make('ffvideoscale', 'videoscale')
#self.videoscale.set_property('method', 2) # I'm not sure this works
#self.videoscale.set_property('add-borders', 0)
@@ -432,8 +487,9 @@ class VideoTranscoder:
self.pipeline.add(self.capsfilter)
self.vp8enc = gst.element_factory_make('vp8enc', 'vp8enc')
- self.vp8enc.set_property('quality', 6)
- self.vp8enc.set_property('threads', 2)
+ self.vp8enc.set_property('quality', self.vp8_quality)
+ self.vp8enc.set_property('threads', self.vp8_threads)
+ self.vp8enc.set_property('max-latency', 25)
self.pipeline.add(self.vp8enc)
# Audio elements
@@ -456,7 +512,7 @@ class VideoTranscoder:
self.pipeline.add(self.audiocapsfilter)
self.vorbisenc = gst.element_factory_make('vorbisenc', 'vorbisenc')
- self.vorbisenc.set_property('quality', 1)
+ self.vorbisenc.set_property('quality', self.vorbis_quality)
self.pipeline.add(self.vorbisenc)
# WebMmux & filesink
@@ -516,7 +572,6 @@ class VideoTranscoder:
# Setup the message bus and connect _on_message to the pipeline
self._setup_bus()
-
def _on_dynamic_pad(self, dbin, pad, islast):
'''
Callback called when ``decodebin2`` has a pad that we can connect to
@@ -561,11 +616,11 @@ class VideoTranscoder:
t = message.type
- if t == gst.MESSAGE_EOS:
+ if message.type == gst.MESSAGE_EOS:
self._discover_dst_and_stop()
_log.info('Done')
- elif t == gst.MESSAGE_ELEMENT:
+ elif message.type == gst.MESSAGE_ELEMENT:
if message.structure.get_name() == 'progress':
data = dict(message.structure)
@@ -587,7 +642,6 @@ class VideoTranscoder:
self.dst_discoverer.discover()
-
def __dst_discovered(self, data, is_media):
self.dst_data = data
@@ -596,8 +650,9 @@ class VideoTranscoder:
def __stop(self):
_log.debug(self.loop)
- # Stop executing the pipeline
- self.pipeline.set_state(gst.STATE_NULL)
+ if hasattr(self, 'pipeline'):
+ # Stop executing the pipeline
+ self.pipeline.set_state(gst.STATE_NULL)
# This kills the loop, mercifully
gobject.idle_add(self.__stop_mainloop)
@@ -615,14 +670,15 @@ class VideoTranscoder:
if __name__ == '__main__':
os.nice(19)
+ logging.basicConfig()
from optparse import OptionParser
parser = OptionParser(
- usage='%prog [-v] -a [ video | thumbnail ] SRC DEST')
+ usage='%prog [-v] -a [ video | thumbnail | discover ] SRC [ DEST ]')
parser.add_option('-a', '--action',
dest='action',
- help='One of "video" or "thumbnail"')
+ help='One of "video", "discover" or "thumbnail"')
parser.add_option('-v',
dest='verbose',
@@ -646,13 +702,17 @@ if __name__ == '__main__':
_log.debug(args)
- if not len(args) == 2:
+ if not len(args) == 2 and not options.action == 'discover':
parser.print_help()
sys.exit()
+ transcoder = VideoTranscoder()
+
if options.action == 'thumbnail':
VideoThumbnailer(*args)
elif options.action == 'video':
def cb(data):
print('I\'m a callback!')
- transcoder = VideoTranscoder(*args, progress_callback=cb)
+ transcoder.transcode(*args, progress_callback=cb)
+ elif options.action == 'discover':
+ print transcoder.discover(*args).__dict__
diff --git a/mediagoblin/plugins/README b/mediagoblin/plugins/README
new file mode 100644
index 00000000..a2b92334
--- /dev/null
+++ b/mediagoblin/plugins/README
@@ -0,0 +1,6 @@
+========
+ README
+========
+
+This directory holds the MediaGoblin core plugins. These plugins are not
+enabled by default. See documentation for enabling plugins.
diff --git a/mediagoblin/plugins/__init__.py b/mediagoblin/plugins/__init__.py
new file mode 100644
index 00000000..719b56e7
--- /dev/null
+++ b/mediagoblin/plugins/__init__.py
@@ -0,0 +1,16 @@
+# 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 <http://www.gnu.org/licenses/>.
+
diff --git a/mediagoblin/plugins/sampleplugin/README b/mediagoblin/plugins/sampleplugin/README
new file mode 100644
index 00000000..15411d8e
--- /dev/null
+++ b/mediagoblin/plugins/sampleplugin/README
@@ -0,0 +1,6 @@
+========
+ README
+========
+
+This is a sample plugin. It does nothing interesting other than show
+one way to structure a MediaGoblin plugin. \ No newline at end of file
diff --git a/mediagoblin/submit/security.py b/mediagoblin/plugins/sampleplugin/__init__.py
index 5dbc0db4..b87348af 100644
--- a/mediagoblin/submit/security.py
+++ b/mediagoblin/plugins/sampleplugin/__init__.py
@@ -14,13 +14,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-from mimetypes import guess_type
-ALLOWED = ['image/jpeg', 'image/png', 'image/tiff', 'image/gif']
-
-
-def check_filetype(posted_file):
- if not guess_type(posted_file.filename)[0] in ALLOWED:
- return False
-
- return True
+# This imports the module that has the Plugin subclass in it which
+# causes that module to get imported and that class to get registered.
+import mediagoblin.plugins.sampleplugin.main
diff --git a/mediagoblin/plugins/sampleplugin/main.py b/mediagoblin/plugins/sampleplugin/main.py
new file mode 100644
index 00000000..67cc70a5
--- /dev/null
+++ b/mediagoblin/plugins/sampleplugin/main.py
@@ -0,0 +1,42 @@
+# 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 <http://www.gnu.org/licenses/>.
+
+import logging
+from mediagoblin.tools.pluginapi import Plugin, get_config
+
+
+_log = logging.getLogger(__name__)
+
+
+class SamplePlugin(Plugin):
+ """
+ This is a sample plugin class. It automatically registers itself
+ with mediagoblin when this module is imported.
+
+ The setup_plugin method prints configuration for this plugin if
+ it exists.
+ """
+ def __init__(self):
+ self._setup_plugin_called = 0
+
+ def setup_plugin(self):
+ _log.info('Sample plugin set up!')
+ config = get_config('mediagoblin.plugins.sampleplugin')
+ if config:
+ _log.info('%r' % config)
+ else:
+ _log.info('There is no configuration set.')
+ self._setup_plugin_called += 1
diff --git a/mediagoblin/processing.py b/mediagoblin/processing/__init__.py
index 1c84c557..4a827af4 100644
--- a/mediagoblin/processing.py
+++ b/mediagoblin/processing/__init__.py
@@ -15,21 +15,15 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
+import os
-from celery.task import Task
-
-from mediagoblin.db.util import ObjectId, atomic_update
+from mediagoblin.db.util import atomic_update
from mediagoblin import mg_globals as mgg
from mediagoblin.tools.translate import lazy_pass_to_ugettext as _
-from mediagoblin.media_types import get_media_manager
-
_log = logging.getLogger(__name__)
-THUMB_SIZE = 180, 180
-MEDIUM_SIZE = 640, 640
-
def create_pub_filepath(entry, filename):
return mgg.public_store.get_unique_filepath(
@@ -37,57 +31,36 @@ def create_pub_filepath(entry, filename):
unicode(entry._id),
filename])
+class FilenameBuilder(object):
+ """Easily slice and dice filenames.
-################################
-# Media processing initial steps
-################################
+ Initialize this class with an original file path, then use the fill()
+ method to create new filenames based on the original.
-class ProcessMedia(Task):
"""
- DEPRECATED -- This now resides in the individual media plugins
+ MAX_FILENAME_LENGTH = 255 # VFAT's maximum filename length
- Pass this entry off for processing.
- """
- def run(self, media_id):
- """
- Pass the media entry off to the appropriate processing function
- (for now just process_image...)
- """
- entry = mgg.database.MediaEntry.one(
- {'_id': ObjectId(media_id)})
-
- # Try to process, and handle expected errors.
- try:
- #__import__(entry.media_type)
- manager = get_media_manager(entry.media_type)
- _log.debug('Processing {0}'.format(entry))
- manager['processor'](entry)
- except BaseProcessingFail, exc:
- mark_entry_failed(entry._id, exc)
- return
- except ImportError, exc:
- _log.error(
- 'Entry {0} failed to process due to an import error: {1}'\
- .format(
- entry.title,
- exc))
-
- mark_entry_failed(entry._id, exc)
-
- entry.state = u'processed'
- entry.save()
-
- def on_failure(self, exc, task_id, args, kwargs, einfo):
- """
- If the processing failed we should mark that in the database.
+ def __init__(self, path):
+ """Initialize a builder from an original file path."""
+ self.dirpath, self.basename = os.path.split(path)
+ self.basename, self.ext = os.path.splitext(self.basename)
+ self.ext = self.ext.lower()
+
+ def fill(self, fmtstr):
+ """Build a new filename based on the original.
+
+ The fmtstr argument can include the following:
+ {basename} -- the original basename, with the extension removed
+ {ext} -- the original extension, always lowercase
+
+ If necessary, {basename} will be truncated so the filename does not
+ exceed this class' MAX_FILENAME_LENGTH in length.
- Assuming that the exception raised is a subclass of
- BaseProcessingFail, we can use that to get more information
- about the failure and store that for conveying information to
- users about the failure, etc.
"""
- entry_id = args[0]
- mark_entry_failed(entry_id, exc)
+ basename_len = (self.MAX_FILENAME_LENGTH -
+ len(fmtstr.format(basename='', ext=self.ext)))
+ return fmtstr.format(basename=self.basename[:basename_len],
+ ext=self.ext)
def mark_entry_failed(entry_id, exc):
diff --git a/mediagoblin/processing/task.py b/mediagoblin/processing/task.py
new file mode 100644
index 00000000..901d293b
--- /dev/null
+++ b/mediagoblin/processing/task.py
@@ -0,0 +1,78 @@
+# 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 <http://www.gnu.org/licenses/>.
+
+import logging
+
+from celery.task import Task
+
+from mediagoblin import mg_globals as mgg
+from mediagoblin.db.util import ObjectId
+from mediagoblin.media_types import get_media_manager
+from mediagoblin.processing import mark_entry_failed, BaseProcessingFail
+
+_log = logging.getLogger(__name__)
+
+
+################################
+# Media processing initial steps
+################################
+
+class ProcessMedia(Task):
+ """
+ DEPRECATED -- This now resides in the individual media plugins
+
+ Pass this entry off for processing.
+ """
+ def run(self, media_id):
+ """
+ Pass the media entry off to the appropriate processing function
+ (for now just process_image...)
+ """
+ entry = mgg.database.MediaEntry.one(
+ {'_id': ObjectId(media_id)})
+
+ # Try to process, and handle expected errors.
+ try:
+ #__import__(entry.media_type)
+ manager = get_media_manager(entry.media_type)
+ _log.debug('Processing {0}'.format(entry))
+ manager['processor'](entry)
+ except BaseProcessingFail, exc:
+ mark_entry_failed(entry._id, exc)
+ return
+ except ImportError, exc:
+ _log.error(
+ 'Entry {0} failed to process due to an import error: {1}'\
+ .format(
+ entry.title,
+ exc))
+
+ mark_entry_failed(entry._id, exc)
+
+ entry.state = u'processed'
+ entry.save()
+
+ def on_failure(self, exc, task_id, args, kwargs, einfo):
+ """
+ If the processing failed we should mark that in the database.
+
+ Assuming that the exception raised is a subclass of
+ BaseProcessingFail, we can use that to get more information
+ about the failure and store that for conveying information to
+ users about the failure, etc.
+ """
+ entry_id = args[0]
+ mark_entry_failed(entry_id, exc)
diff --git a/mediagoblin/static/css/audio.css b/mediagoblin/static/css/audio.css
new file mode 100644
index 00000000..e007a0e1
--- /dev/null
+++ b/mediagoblin/static/css/audio.css
@@ -0,0 +1,84 @@
+.audio-spectrogram {
+ position: relative;
+}
+.playhead {
+ position: absolute;
+ top: 0;
+ left: 0;
+ background: rgba(134, 212, 177, 0.3);
+ border-right: thin solid #ffaa00;
+ height: 100%;
+ -webkit-transition: width .1s ease-out;
+ -moz-transition: width .1s ease-out;
+ transition: width .1s ease-out;
+}
+.audio-control-play-pause {
+ position: absolute;
+ bottom: 0;
+ left: 5px;
+ cursor: pointer;
+ /* background: rgba(0, 0, 0, 0.7); */
+ font-size: 40px;
+ width: 50px;
+ text-shadow: 0 0 10px black;
+}
+ .audio-control-play-pause.playing {
+ color: #b71500;
+ letter-spacing: -17px;
+ margin-left: -7px;
+ }
+ .audio-control-play-pause.paused {
+ /* Warning: this means the the play button shows! */
+ color: rgb(134, 212, 177);
+ }
+
+.buffered-indicators {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ height: 2px;
+}
+ .buffered-indicators div {
+ position: absolute;
+ height: 2px;
+ left: 0;
+ background: rgba(134, 177, 212, 1);
+
+ -webkit-transition: left 1s ease-out;
+ -moz-transition: left 1s ease-out;
+ transition: left 1s ease-out;
+
+ -webkit-transition: width 1s ease-out;
+ -moz-transition: width 1s ease-out;
+ transition: width 1s ease-out;
+
+ cursor: pointer;
+ }
+
+.seekbar {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+}
+
+.audio-currentTime {
+ position: absolute;
+ bottom: 0;
+ right: 0;
+ background: rgba(0, 0, 0, 0.7);
+}
+
+.audio-volume {
+ position: absolute;
+ left: 50px;
+ bottom: 10px;
+ opacity: 0.3;
+ -moz-transition: opacity .1s ease-in-out;
+ -webkit-transition: opacity .1s ease-in-out;
+ transition: opacity .1s ease-in-out;
+}
+ .audio-spectrogram:hover .audio-volume {
+ opacity: 0.7;
+ }
diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css
index 0a0d0dcd..e4cd91ca 100644
--- a/mediagoblin/static/css/base.css
+++ b/mediagoblin/static/css/base.css
@@ -26,10 +26,9 @@
}
body {
- background-color: #111;
- background-image: url("../images/background.png");
+ background-color: #161616;
color: #C3C3C3;
- padding: none;
+ padding: 0;
margin: 0px;
height: 100%;
font: 16px 'Lato', 'Helvetica Neue', Arial, 'Liberation Sans', FreeSans, sans-serif;
@@ -114,24 +113,70 @@ input, textarea {
header {
width: 100%;
- padding-top: 14px;
- margin-bottom: 20px;
- border-bottom: 1px solid #333;
+ padding: 0;
+ margin-bottom: 42px;
+ background-color: #303030;
+ border-bottom: 1px solid #252525;
}
.header_right {
+ margin: 8px;
+ display: inline-block;
float: right;
- margin: 8px 0px 8px 8px;
+}
+
+.header_right ul {
+ display: none;
+ position: absolute;
+ top: 42px;
+ right: 0px;
+ background: #252525;
+ padding: 20px;
+}
+
+.header_right li {
+ list-style: none;
+}
+
+.dropdown {
+ display: inline-block;
+ color: #c3c3c3;
+ background-color: #424242;
+ border: 1px solid;
+ border-color: #464646 #2B2B2B #252525;
+ border-radius: 4px;
+ padding: 3px 8px;
+ font-size: 16px;
+ text-decoration: none;
+ font-style: normal;
+ font-weight: bold;
+ cursor: pointer;
+ position: relative;
+}
+
+.dropdown_items {
+ position: absolute;
+ right: 0px;
+ top: 25px;
+ background-color: #424242;
+ padding: 10px;
+ width: 160px;
+ border-radius: 5px 0 5px 5px;
+ box-shadow: 0 2px 1px black;
+}
+
+.dropdown_items a {
+ display: block;
}
a.logo {
color: #fff;
font-weight: bold;
- margin: 8px 8px 8px 0;
}
.logo img {
vertical-align: middle;
+ margin: 6px 8px;
}
.mediagoblin_content {
@@ -144,7 +189,7 @@ footer {
height: 30px;
border-top: 1px solid #333;
bottom: 0px;
- padding-top: 8px;
+ padding: 8px 0;
text-align: center;
font-size: 0.875em;
clear: both;
@@ -241,7 +286,7 @@ text-align: center;
}
.media_sidebar p {
- padding-left: 8px;
+ margin-left: 8px;
}
/* forms */
@@ -310,18 +355,23 @@ textarea#description, textarea#bio {
/* comments */
+.comment_wrapper {
+ margin-top: 20px;
+ margin-bottom: 20px;
+}
+
+.comment_wrapper p {
+ margin-bottom: 2px;
+}
+
.comment_author {
- margin-bottom: 40px;
padding-top: 4px;
font-size: 0.9em;
}
.comment_content {
- margin-bottom: 30px;
-}
-
-.comment_content p {
- margin-bottom: 0px;
+ margin-left: 8px;
+ margin-top: 8px;
}
textarea#comment_content {
@@ -560,13 +610,17 @@ table.media_panel th {
padding: 9px 14px;
}
+ header {
+ text-align: center;
+ }
+
.header_right {
+ margin-right: 2%;
float: none;
- display: inline-block;
}
- header {
- text-align: center;
+ a.logo {
+ margin-left: 2%;
}
}
diff --git a/mediagoblin/static/css/vjs-mg-skin.css b/mediagoblin/static/css/vjs-mg-skin.css
new file mode 100644
index 00000000..98c4eb95
--- /dev/null
+++ b/mediagoblin/static/css/vjs-mg-skin.css
@@ -0,0 +1,415 @@
+.video-js {
+ background-color: #000; position: relative; padding: 0; outline: none;
+
+ /* Start with 10px for base font size so other dimensions can be em based and easily calculable. */
+ font-size: 10px;
+
+ width: 650px !important;
+ height: 366px !important;
+
+
+ /* Allow poster to be vertially aligned. */
+ vertical-align: middle;
+ /* display: table-cell; */ /*This works in Safari but not Firefox.*/
+}
+
+/* Playback technology elements expand to the width/height of the containing div. <video> or <object> */
+.video-js .vjs-tech { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
+
+/* Fix for Firefox 9 fullscreen (only if it is enabled). Not needed when checking fullScreenEnabled. */
+.video-js:-moz-full-screen { position: absolute; }
+
+/* Fullscreen Styles */
+body.vjs-full-window {
+ padding: 0; margin: 0;
+ height: 100%; overflow-y: auto; /* Fix for IE6 full-window. http://www.cssplay.co.uk/layouts/fixed.html */
+}
+.video-js.vjs-fullscreen {
+ position: fixed; overflow: hidden; z-index: 1000; left: 0; top: 0; bottom: 0; right: 0; width: 100% !important; height: 100% !important;
+ _position: absolute; /* IE6 Full-window (underscore hack) */
+}
+.video-js:-webkit-full-screen {
+ width: 100% !important; height: 100% !important;
+}
+
+/* Poster Styles */
+.vjs-poster {
+ margin: 0 auto; padding: 0; cursor: pointer;
+
+ /* Scale with the size of the player div. Works when poster is vertically shorter, but stretches when it's less wide. */
+ position: relative; width: 100%; max-height: 100%;
+}
+
+/* Subtiles Styles */
+.video-js .vjs-subtitles { color: #fff; font-size: 20px; text-align: center; position: absolute; bottom: 40px; left: 0; right: 0; }
+
+/* Fading sytles, used to fade control bar. */
+.vjs-fade-in {
+ visibility: visible !important; /* Needed to make sure things hide in older browsers too. */
+ opacity: 0.9 !important;
+
+ -webkit-transition: visibility 0s linear 0s, opacity 0.3s linear;
+ -moz-transition: visibility 0s linear 0s, opacity 0.3s linear;
+ -ms-transition: visibility 0s linear 0s, opacity 0.3s linear;
+ -o-transition: visibility 0s linear 0s, opacity 0.3s linear;
+ transition: visibility 0s linear 0s, opacity 0.3s linear;
+}
+.vjs-fade-out {
+ visibility: hidden !important;
+ opacity: 0 !important;
+
+ -webkit-transition: visibility 0s linear 1.5s,opacity 1.5s linear;
+ -moz-transition: visibility 0s linear 1.5s,opacity 1.5s linear;
+ -ms-transition: visibility 0s linear 1.5s,opacity 1.5s linear;
+ -o-transition: visibility 0s linear 1.5s,opacity 1.5s linear;
+ transition: visibility 0s linear 1.5s,opacity 1.5s linear;
+}
+
+/* The control bar
+---------------------------------------------------------------------------------- */
+.vjs-mg-skin .vjs-controls {
+ position: absolute;
+ bottom: 0; /* Distance from the bottom of the box/video. Keep 0. Use height to add more bottom margin. */
+ left: 0; right: 0; /* 100% width of div */
+ margin: 0; padding: 0; /* Controls are absolutely position, so no padding necessary */
+ height: 30px; /* Including any margin you want above or below control items */
+ color: #fff; border-top: 1px solid #404040; border-bottom: 1px solid #1f1f1f;
+
+ /* CSS Gradient */
+ /* Can use the Ultimate CSS Gradient Generator: http://www.colorzilla.com/gradient-editor/ */
+ background: #242424; /* Old browsers */
+ background: -moz-linear-gradient(top, #242424 50%, #1f1f1f 50%, #171717 100%); /* FF3.6+ */
+ background: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(50%,#242424), color-stop(50%,#1f1f1f), color-stop(100%,#171717)); /* Chrome,Safari4+ */
+ background: -webkit-linear-gradient(top, #242424 50%,#1f1f1f 50%,#171717 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, #242424 50%,#1f1f1f 50%,#171717 100%); /* Opera11.10+ */
+ background: -ms-linear-gradient(top, #242424 50%,#1f1f1f 50%,#171717 100%); /* IE10+ */
+ /* Filter was causing a lot of weird issues in IE. Elements would stop showing up, or other styles would break. */
+ /*filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#242424', endColorstr='#171717',GradientType=0 );*/ /* IE6-9 */
+ background: linear-gradient(top, #242424 50%,#1f1f1f 50%,#171717 100%); /* W3C */
+
+ /* Start hidden and with 0 opacity. Opacity is used to fade in modern browsers. */
+ /* Can't use display block to hide initially because widths of slider handles aren't calculated and avaialbe for positioning correctly. */
+ visibility: hidden;
+ opacity: 0;
+}
+
+/* General styles for individual controls. */
+.vjs-mg-skin .vjs-control {
+ position: relative; float: left;
+ text-align: center; margin: 0; padding: 0;
+}
+
+.vjs-mg-skin .vjs-control:focus {
+ outline: 0;
+}
+
+/* Hide control text visually, but have it available for screenreaders: h5bp.com/v */
+.vjs-mg-skin .vjs-control-text { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; }
+
+
+
+/* Play/Pause
+-------------------------------------------------------------------------------- */
+.vjs-mg-skin .vjs-play-control { width: 38px; height: 30px; border-right: 1px solid #101010; cursor: pointer !important; border-left: 1px solid #333; border-bottom: 1px solid #1F1F1F; }
+/* Play Icon */
+.vjs-mg-skin.vjs-paused .vjs-play-control div { width: 15px; height: 17px; background: url('../images/video-js.png'); margin: 0; margin-left: 13px; margin-top: 7px; }
+.vjs-mg-skin.vjs-playing .vjs-play-control div { width: 15px; height: 17px; background: url('../images/video-js.png') -25px 0; margin: 0; margin-left: 13px; margin-top: 7px; }
+
+
+/* Rewind
+-------------------------------------------------------------------------------- */
+.vjs-mg-skin .vjs-rewind-control { width: 5em; cursor: pointer !important; }
+.vjs-mg-skin .vjs-rewind-control div { width: 19px; height: 16px; background: url('../images/video-js.png'); margin: 0.5em auto 0; }
+
+/* Volume/Mute
+-------------------------------------------------------------------------------- */
+.vjs-mg-skin .vjs-mute-control { width: 38px; height: 30px; border-left: 1px solid #333; cursor: pointer !important; float: right; }
+.vjs-mg-skin .vjs-mute-control div { width: 22px; height: 16px; background: url('../images/video-js.png') -75px -25px; margin:0; margin-left: 8px; margin-top: 8px; }
+.vjs-mg-skin .vjs-mute-control.vjs-vol-0 div { background: url('../images/video-js.png') 0 -25px; }
+.vjs-mg-skin .vjs-mute-control.vjs-vol-1 div { background: url('../images/video-js.png') -25px -25px; }
+.vjs-mg-skin .vjs-mute-control.vjs-vol-2 div { background: url('../images/video-js.png') -50px -25px; }
+
+
+.vjs-mg-skin .vjs-volume-control { width: 85px; height: 30px; float: right; border-right: 1px solid #333; }
+.vjs-mg-skin .vjs-volume-bar {
+ position: relative; width: 70px; height: 0.6em; margin:0; margin-left: 2px; margin-top: 11px; cursor: pointer !important;
+
+ /* -moz-border-radius: 0.3em; -webkit-border-radius: 0.3em; border-radius: 0.3em; */
+
+ background: #666;
+ background: -moz-linear-gradient(top, #333, #666);
+ background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#333), to(#666));
+ background: -webkit-linear-gradient(top, #333, #666);
+ background: -o-linear-gradient(top, #333, #666);
+ background: -ms-linear-gradient(top, #333, #666);
+ background: linear-gradient(top, #333, #666);
+}
+
+.video-js:-moz .vjs-volume-bar { margin-top: 12px; }
+
+.vjs-mg-skin .vjs-volume-level {
+ position: absolute; top: 0; left: 0; height: 0.6em;
+
+ /* -moz-border-radius: 0.3em; -webkit-border-radius: 0.3em; border-radius: 0.3em; */
+ /* CSS Gradient. */
+ background: #86D4B1; /* Old browsers */
+ background: -moz-linear-gradient(top, #86D4B1 0%, #5d937a 50%, #86D4B1 100%);
+ background: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(0%,#86D4B1), color-stop(50%,#5d937a), color-stop(100%,#86D4B1));
+ background: -webkit-linear-gradient(top, #86D4B1 0%,#5d937a 50%,#86D4B1 100%);
+ background: -o-linear-gradient(top, #86D4B1 0%,#5d937a 50%,#86D4B1 100%);
+ background: -ms-linear-gradient(top, #86D4B1 0%,#5d937a 50%,#86D4B1 100%);
+ background: linear-gradient(top, #86D4B1 0%,#5d937a 50%,#86D4B1 100%);
+
+
+}
+.vjs-mg-skin .vjs-volume-handle {
+ position: absolute; top: -4px; width: 14px; height: 14px; left: 0;
+ background: url('../images/video-js.png') 0 -50px;
+}
+
+.video-js:-moz .vjs-volume-handle { top: -1px;}
+
+
+
+
+/* Progress
+-------------------------------------------------------------------------------- */
+.vjs-mg-skin div.vjs-progress-control {
+ position: absolute;
+ top: -15px;
+ width: 100%;
+ height: 12px;
+}
+
+/* Box containing play and load progresses. Also acts as seek scrubber. */
+.vjs-mg-skin .vjs-progress-holder {
+ position: relative; cursor: pointer !important; /*overflow: hidden;*/
+ padding: 0; margin: 0; /* Placement within the progress control item */
+ height: 12px;
+ border-top: 1px solid #333;
+ border-bottom: 1px solid #111;
+
+
+/* -moz-border-radius: 0.6em; -webkit-border-radius: 0.6em; border-radius: 0.6em; */
+
+ /* CSS Gradient */
+ background: #111;
+ background: -moz-linear-gradient(top, #111, #262626);
+ background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#111), to(#262626));
+ background: -webkit-linear-gradient(top, #111, #262626);
+ background: -o-linear-gradient(top, #111, #262626);
+ background: -ms-linear-gradient(top, #111, #262626);
+ background: linear-gradient(top, #111, #262626);
+}
+.vjs-mg-skin .vjs-progress-holder .vjs-play-progress,
+.vjs-mg-skin .vjs-progress-holder .vjs-load-progress { /* Progress Bars */
+ position: absolute; display: block; height: 12px; margin: 0; padding: 0;
+ left: 0; top: 0; /*Needed for IE6*/
+ /* -moz-border-radius: 0.6em; -webkit-border-radius: 0.6em; border-radius: 0.6em; */
+
+ /*width: 0;*/
+}
+
+.vjs-mg-skin .vjs-play-progress {
+ /* CSS Gradient. */
+ background: #86D4B1; /* Old browsers */
+ background: -moz-linear-gradient(top, #86D4B1 0%, #5d937a 50%, #86D4B1 100%);
+ background: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(0%,#86D4B1), color-stop(50%,#5d937a), color-stop(100%,#86D4B1));
+ background: -webkit-linear-gradient(top, #86D4B1 0%,#5d937a 50%,#86D4B1 100%);
+ background: -o-linear-gradient(top, #86D4B1 0%,#5d937a 50%,#86D4B1 100%);
+ background: -ms-linear-gradient(top, #86D4B1 0%,#5d937a 50%,#86D4B1 100%);
+ background: linear-gradient(top, #86D4B1 0%,#5d937a 50%,#86D4B1 100%);
+
+ background: #86D4B1;
+ background: -moz-linear-gradient(top, #5d937a 0%, #5d937a 50%, #86D4B1 50%, #5d937a 100%);
+ background: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(0%,#5d937a), color-stop(50%,#86D4B1), color-stop(50%,#86D4B1), color-stop(100%,#5d937a));
+ background: -webkit-linear-gradient(top, #5d937a 0%,#86D4B1 50%,#86D4B1 50%,#5d937a 100%);
+ background: -o-linear-gradient(top, #5d937a 0%,#86D4B1 50%,#5d937a 50%, 100%);
+ background: -ms-linear-gradient(top, #5d937a 0%,#86D4B1 50%,#86D4B1 50%,#5d937a 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#86D4B1', endColorstr='#5d937a',GradientType=0 );
+ background: linear-gradient(top, #5d937a 0%,#86D4B1 50%,#86D4B1 50%,#5d937a 100%);
+}
+.vjs-mg-skin .vjs-load-progress {
+ opacity: 0.8;
+
+ /* CSS Gradient */
+ background: #666;
+ background: -moz-linear-gradient(top, #666, #333);
+ background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#666), to(#333));
+ background: -webkit-linear-gradient(top, #666, #333);
+ background: -o-linear-gradient(top, #666, #333);
+ background: -ms-linear-gradient(top, #666, #333);
+ background: linear-gradient(top, #666, #333);
+}
+
+.vjs-mg-skin div.vjs-seek-handle {
+ position: absolute;
+ width: 16px; height: 16px; /* Match img pixles */
+ margin-top: -0.2em;
+ left: 0; top: 0; /*Needed for IE6*/
+
+ background: url('../images/video-js.png') 0 -50px;
+ /* CSS Curved Corners. Needed to make shadows curved. */
+ -moz-border-radius: 0.8em; -webkit-border-radius: 0.8em; border-radius: 0.8em;
+ /* CSS Shadows */
+ -webkit-box-shadow: 0 2px 4px 0 #000; -moz-box-shadow: 0 2px 4px 0 #000; box-shadow: 0 2px 4px 0 #000;
+}
+/* Time Display
+-------------------------------------------------------------------------------- */
+.vjs-mg-skin .vjs-time-controls {
+ height: 18px; width: 45px;
+ margin-top: 5px;
+ margin-left: 5px;
+ font-size: 14px; line-height: 18px; font-weight: normal; font-family: Helvetica, Arial, sans-serif;
+ border-left: 1px solid #000000;
+ border-top: 1px solid #000;
+ border-bottom: 1px solid #333;
+ border-right: 1px solid #333;
+ -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px;
+
+ /* CSS Gradient */
+ background: #111;
+ background: -moz-linear-gradient(top, #111, #262626);
+ background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#111), to(#262626));
+ background: -webkit-linear-gradient(top, #111, #262626);
+ background: -o-linear-gradient(top, #111, #262626);
+ background: -ms-linear-gradient(top, #111, #262626);
+ background: linear-gradient(top, #111, #262626);
+
+
+}
+
+.vjs-mg-skin .vjs-current-time { }
+
+.vjs-mg-skin .vjs-duration { right: 0; display: none; }
+.vjs-mg-skin .vjs-remaining-time { display: block; }
+
+.vjs-time-divider { }
+
+.vjs-mg-skin .vjs-time-control { font-size: 12px; line-height: 16px; font-weight: normal; font-family: Helvetica, Arial, sans-serif; }
+.vjs-mg-skin .vjs-time-control span { line-height: 25px; /* Centering vertically */ }
+
+.vjs-mg-skin .vjs-time-divider { display: none; visibility: hidden; }
+
+/* Fullscreen
+-------------------------------------------------------------------------------- */
+.vjs-secondary-controls { float: right; }
+
+.vjs-mg-skin .vjs-fullscreen-control { height: 30px; width: 38px; cursor: pointer !important; float: right; border-left: 1px solid #111; }
+.vjs-mg-skin .vjs-fullscreen-control div { width: 16px; height: 16px; background: url('../images/video-js.png') -50px 0; margin: 0; margin-left: 11px; margin-top: 8px; }
+
+.video-js.vjs-fullscreen .vjs-fullscreen-control div { background: url('../images/video-js.png') -75px 0; }
+.video-js:-webkit-full-screen .vjs-fullscreen-control div { background: url('../images/video-js.png') -75px 0; }
+
+
+
+/* Big Play Button (at start)
+---------------------------------------------------------*/
+.vjs-mg-skin .vjs-big-play-button {
+ display: block; /* Start hidden */ z-index: 2;
+ position: absolute; top: 50%; left: 50%; width: 8.0em; height: 8.0em; margin: -43px 0 0 -43px; text-align: center; vertical-align: center; cursor: pointer !important;
+ border: 0.3em solid #86D4B1; opacity: 0.95;
+ -webkit-border-radius: 25px; -moz-border-radius: 25px; border-radius: 25px;
+
+ background: #454545;
+ background: -moz-linear-gradient(top, #454545 0%, #232323 50%, #161616 50%, #3f3f3f 100%);
+ background: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(0%,#454545), color-stop(50%,#232323), color-stop(50%,#161616), color-stop(100%,#3f3f3f));
+ background: -webkit-linear-gradient(top, #454545 0%,#232323 50%,#161616 50%,#3f3f3f 100%);
+ background: -o-linear-gradient(top, #454545 0%,#232323 50%,#161616 50%,#3f3f3f 100%);
+ background: -ms-linear-gradient(top, #454545 0%,#232323 50%,#161616 50%,#3f3f3f 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#454545', endColorstr='#3f3f3f',GradientType=0 );
+ background: linear-gradient(top, #454545 0%,#232323 50%,#161616 50%,#3f3f3f 100%);
+
+ /* CSS Shadows */
+ -webkit-box-shadow: 4px 4px 8px #000; -moz-box-shadow: 4px 4px 8px #000; box-shadow: 4px 4px 8px #000;
+}
+
+.vjs-mg-skin div.vjs-big-play-button:hover {
+ -webkit-box-shadow: 0 0 80px #fff; -moz-box-shadow: 0 0 80px #fff; box-shadow: 0 0 80px #fff;
+}
+
+.vjs-mg-skin div.vjs-big-play-button span {
+ position: absolute; top: 50%; left: 50%;
+ display: block; width: 35px; height: 42px;
+ margin: -20px 0 0 -15px; /* Using negative margin to center image. */
+ background: url('../images/video-js.png') -100px 0;
+}
+
+/* Loading Spinner
+---------------------------------------------------------*/
+/* CSS Spinners by Kilian Valkhof - http://kilianvalkhof.com/2010/css-xhtml/css3-loading-spinners-without-images/ */
+.vjs-loading-spinner {
+ display: none;
+ position: absolute; top: 50%; left: 50%; width: 55px; height: 55px;
+ margin: -28px 0 0 -28px;
+ -webkit-animation-name: rotatethis;
+ -webkit-animation-duration:1s;
+ -webkit-animation-iteration-count:infinite;
+ -webkit-animation-timing-function:linear;
+ -moz-animation-name: rotatethis;
+ -moz-animation-duration:1s;
+ -moz-animation-iteration-count:infinite;
+ -moz-animation-timing-function:linear;
+}
+
+@-webkit-keyframes rotatethis {
+ 0% {-webkit-transform:scale(0.6) rotate(0deg); }
+ 12.5% {-webkit-transform:scale(0.6) rotate(0deg); }
+ 12.51% {-webkit-transform:scale(0.6) rotate(45deg); }
+ 25% {-webkit-transform:scale(0.6) rotate(45deg); }
+ 25.01% {-webkit-transform:scale(0.6) rotate(90deg);}
+ 37.5% {-webkit-transform:scale(0.6) rotate(90deg);}
+ 37.51% {-webkit-transform:scale(0.6) rotate(135deg);}
+ 50% {-webkit-transform:scale(0.6) rotate(135deg);}
+ 50.01% {-webkit-transform:scale(0.6) rotate(180deg);}
+ 62.5% {-webkit-transform:scale(0.6) rotate(180deg);}
+ 62.51% {-webkit-transform:scale(0.6) rotate(225deg);}
+ 75% {-webkit-transform:scale(0.6) rotate(225deg);}
+ 75.01% {-webkit-transform:scale(0.6) rotate(270deg);}
+ 87.5% {-webkit-transform:scale(0.6) rotate(270deg);}
+ 87.51% {-webkit-transform:scale(0.6) rotate(315deg);}
+ 100% {-webkit-transform:scale(0.6) rotate(315deg);}
+}
+
+@-moz-keyframes rotatethis {
+ 0% {-moz-transform:scale(0.6) rotate(0deg);}
+ 12.5% {-moz-transform:scale(0.6) rotate(0deg);}
+ 12.51% {-moz-transform:scale(0.6) rotate(45deg);}
+ 25% {-moz-transform:scale(0.6) rotate(45deg);}
+ 25.01% {-moz-transform:scale(0.6) rotate(90deg);}
+ 37.5% {-moz-transform:scale(0.6) rotate(90deg);}
+ 37.51% {-moz-transform:scale(0.6) rotate(135deg);}
+ 50% {-moz-transform:scale(0.6) rotate(135deg);}
+ 50.01% {-moz-transform:scale(0.6) rotate(180deg);}
+ 62.5% {-moz-transform:scale(0.6) rotate(180deg);}
+ 62.51% {-moz-transform:scale(0.6) rotate(225deg);}
+ 75% {-moz-transform:scale(0.6) rotate(225deg);}
+ 75.01% {-moz-transform:scale(0.6) rotate(270deg);}
+ 87.5% {-moz-transform:scale(0.6) rotate(270deg);}
+ 87.51% {-moz-transform:scale(0.6) rotate(315deg);}
+ 100% {-moz-transform:scale(0.6) rotate(315deg);}
+}
+/* Each circle */
+div.vjs-loading-spinner .ball1 { opacity: 0.12; position:absolute; left: 20px; top: 0px; width: 13px; height: 13px; background: #fff;
+ border-radius: 13px; -webkit-border-radius: 13px; -moz-border-radius: 13px; border: 1px solid #ccc; }
+
+div.vjs-loading-spinner .ball2 { opacity: 0.25; position:absolute; left: 34px; top: 6px; width: 13px; height: 13px; background: #fff;
+ border-radius: 13px; -webkit-border-radius: 13px; -moz-border-radius: 13px; border: 1px solid #ccc; }
+
+div.vjs-loading-spinner .ball3 { opacity: 0.37; position:absolute; left: 40px; top: 20px; width: 13px; height: 13px; background: #fff;
+ border-radius: 13px; -webkit-border-radius: 13px; -moz-border-radius: 13px; border: 1px solid #ccc; }
+
+div.vjs-loading-spinner .ball4 { opacity: 0.50; position:absolute; left: 34px; top: 34px; width: 13px; height: 13px; background: #fff;
+ border-radius: 10px; -webkit-border-radius: 10px; -moz-border-radius: 15px; border: 1px solid #ccc; }
+
+div.vjs-loading-spinner .ball5 { opacity: 0.62; position:absolute; left: 20px; top: 40px; width: 13px; height: 13px; background: #fff;
+ border-radius: 13px; -webkit-border-radius: 13px; -moz-border-radius: 13px; border: 1px solid #ccc; }
+
+div.vjs-loading-spinner .ball6 { opacity: 0.75; position:absolute; left: 6px; top: 34px; width: 13px; height: 13px; background: #fff;
+ border-radius: 13px; -webkit-border-radius: 13px; -moz-border-radius: 13px; border: 1px solid #ccc; }
+
+div.vjs-loading-spinner .ball7 { opacity: 0.87; position:absolute; left: 0px; top: 20px; width: 13px; height: 13px; background: #fff;
+ border-radius: 13px; -webkit-border-radius: 13px; -moz-border-radius: 13px; border: 1px solid #ccc; }
+
+div.vjs-loading-spinner .ball8 { opacity: 1.00; position:absolute; left: 6px; top: 6px; width: 13px; height: 13px; background: #fff;
+ border-radius: 13px; -webkit-border-radius: 13px; -moz-border-radius: 13px; border: 1px solid #ccc; }
diff --git a/mediagoblin/static/images/video-js.png b/mediagoblin/static/images/video-js.png
new file mode 100644
index 00000000..58cd813d
--- /dev/null
+++ b/mediagoblin/static/images/video-js.png
Binary files differ
diff --git a/mediagoblin/static/js/audio.js b/mediagoblin/static/js/audio.js
new file mode 100644
index 00000000..50d58cd9
--- /dev/null
+++ b/mediagoblin/static/js/audio.js
@@ -0,0 +1,229 @@
+/**
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+var audioPlayer = new Object();
+
+(function (audioPlayer) {
+ audioPlayer.init = function (audioElement) {
+ audioPlayer.audioElement = audioElement;
+
+ console.log(audioElement);
+
+ attachEvents();
+
+ $(audioElement).hide();
+ };
+
+ function attachEvents () {
+ audioPlayer.audioElement.addEventListener(
+ 'durationchange', audioPlayer.durationChange, true);
+ audioPlayer.audioElement.addEventListener(
+ 'timeupdate', audioPlayer.timeUpdate, true);
+ audioPlayer.audioElement.addEventListener(
+ 'progress', audioPlayer.onProgress, true);
+ audioPlayer.audioElement.addEventListener(
+ 'ended', audioPlayer.onEnded, true);
+
+ $(document).ready( function () {
+ $('.audio-spectrogram').delegate(
+ '.seekbar', 'click', audioPlayer.onSeek);
+ $('.audio-spectrogram').delegate(
+ '.audio-control-play-pause', 'click', audioPlayer.playPause);
+ $('.audio-spectrogram').delegate(
+ '.audio-volume', 'change', audioPlayer.onVolumeChange);
+ $('.audio-media').delegate(
+ '.audio-spectrogram', 'attachedControls',
+ audioPlayer.onControlsAttached);
+ });
+ }
+
+ audioPlayer.onVolumeChange = function(e) {
+ console.log('volume change', e);
+ audioPlayer.audioElement.volume = e.target.value;
+ }
+
+ audioPlayer.onControlsAttached = function(e) {
+ console.log('Controls attached', e);
+ $('.audio-spectrogram .audio-volume').val(
+ Math.round(audioPlayer.audioElement.volume, 2));
+ }
+
+ audioPlayer.onProgress = function(e) {
+ /**
+ * Handler for file download progress
+ */
+ console.log(e);
+
+ var buffered = audioPlayer.audioElement.buffered;
+
+ ranges = new Array();
+
+ var indicators = $('.audio-spectrogram .buffered-indicators div');
+
+ for (var i = 0; i < buffered.length; i++) {
+ if (!(i in indicators)) {
+ $('<div style="display: none;"></div>')
+ .appendTo($('.audio-spectrogram .buffered-indicators'))
+ .fadeIn(500);
+ indicators = $('.audio-spectrogram .buffered-indicators div');
+ }
+ var posStart = ((buffered.start(i) / audioPlayer.audioElement.duration)
+ * audioPlayer.imageElement.width());
+ var posStop = ((buffered.end(i) / audioPlayer.audioElement.duration)
+ * audioPlayer.imageElement.width());
+ console.log('indicators', indicators);
+
+ var indicator = $(indicators[i]);
+
+ indicator.css('left', posStart);
+ indicator.css('width', posStop - posStart);
+ }
+
+ /*
+ * Clean up unused indicators
+ */
+ if (indicators.length > buffered.length) {
+ for (var i = buffered.length; i < indicators.length; i++) {
+ $(indicators[i]).fadeOut(500, function () {
+ this.remove();
+ });
+ }
+ }
+ };
+
+ audioPlayer.onSeek = function (e) {
+ /**
+ * Callback handler for seek event, which is a .click() event on the
+ * .seekbar element
+ */
+ console.log('onSeek', e);
+
+ var im = audioPlayer.imageElement;
+ var pos = (e.offsetX || e.originalEvent.layerX) / im.width();
+
+ audioPlayer.audioElement.currentTime = pos * audioPlayer.audioElement.duration;
+ audioPlayer.audioElement.play();
+ audioPlayer.setState(audioPlayer.PLAYING);
+ };
+
+ audioPlayer.onEnded = function (e) {
+ audioPlayer.setState(audioPlayer.PAUSED);
+ }
+
+ audioPlayer.playPause = function (e) {
+ console.log('playPause', e);
+ if (audioPlayer.audioElement.paused) {
+ audioPlayer.audioElement.play();
+ audioPlayer.setState(audioPlayer.PLAYING);
+ } else {
+ audioPlayer.audioElement.pause();
+ audioPlayer.setState(audioPlayer.PAUSED);
+ }
+ };
+
+ audioPlayer.NULL = null;
+ audioPlayer.PLAYING = 2;
+ audioPlayer.PAUSED = 4;
+
+ audioPlayer.state = audioPlayer.NULL;
+
+ audioPlayer.setState = function (state) {
+ if (state == audioPlayer.state) {
+ return;
+ } else {
+ audioPlayer.state = state;
+ }
+
+ switch (state) {
+ case audioPlayer.PLAYING:
+ $('.audio-spectrogram .audio-control-play-pause')
+ .removeClass('paused').addClass('playing')
+ .text('▮▮');
+ break;
+ case audioPlayer.PAUSED:
+ $('.audio-spectrogram .audio-control-play-pause')
+ .removeClass('playing').addClass('paused')
+ .text('â–¶');
+ break;
+ }
+ };
+
+ audioPlayer.durationChange = function () {
+ // ???
+ };
+
+ audioPlayer.timeUpdate = function () {
+ /**
+ * Callback handler for the timeupdate event, responsible for
+ * updating the playhead
+ */
+ var currentTime = audioPlayer.audioElement.currentTime;
+ var playhead = audioPlayer.imageElement.parent().find('.playhead');
+ playhead.css('width', (currentTime / audioPlayer.audioElement.duration)
+ * audioPlayer.imageElement.width());
+ var time = formatTime(currentTime);
+ var duration = formatTime(audioPlayer.audioElement.duration);
+ audioPlayer.imageElement.parent()
+ .find('.audio-currentTime')
+ .text(time + '/' + duration);
+ };
+
+ function formatTime(seconds) {
+ /**
+ * Format a time duration in (hh:)?mm:ss manner
+ */
+ var h = Math.floor(seconds / (60 * 60));
+ var m = Math.floor((seconds - h * 60 * 60) / 60);
+ var s = Math.round(seconds - h * 60 * 60 - m * 60);
+ return '' + (h ? (h < 10 ? '0' + h : h) + ':' : '') + (m < 10 ? '0' + m : m) + ':' + (s < 10 ? '0' + s : s);
+ }
+
+ audioPlayer.formatTime = formatTime;
+
+ audioPlayer.attachToImage = function (imageElement) {
+ /**
+ * Attach the player to an image element
+ */
+ console.log(imageElement);
+
+ var im = $(imageElement);
+
+ audioPlayer.imageElement = im;
+
+ $('<div class="playhead"></div>').appendTo(im.parent());
+ $('<div class="buffered-indicators"></div>').appendTo(im.parent());
+ $('<div class="seekbar"></div>').appendTo(im.parent());
+ $('<div class="audio-control-play-pause paused">â–¶</div>').appendTo(im.parent());
+ $('<div class="audio-currentTime">00:00</div>').appendTo(im.parent());
+ $('<input type="range" class="audio-volume"'
+ +'value="1" min="0" max="1" step="0.001" />').appendTo(im.parent());
+ $('.audio-spectrogram').trigger('attachedControls');
+ };
+})(audioPlayer);
+
+$(document).ready(function () {
+ if (!$('.audio-media').length) {
+ return;
+ }
+
+ console.log('Initializing audio player');
+
+ audioElements = $('.audio-media .audio-player');
+ audioPlayer.init(audioElements[0]);
+ audioPlayer.attachToImage($('.audio-spectrogram img')[0]);
+});
diff --git a/mediagoblin/static/js/autofilledin_password.js b/mediagoblin/static/js/autofilledin_password.js
new file mode 100644
index 00000000..45e867fe
--- /dev/null
+++ b/mediagoblin/static/js/autofilledin_password.js
@@ -0,0 +1,25 @@
+/**
+ * GNU MediaGoblin -- federated, autonomous media hosting
+ * Copyright (C) 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 <http://www.gnu.org/licenses/>.
+ */
+
+$(document).ready(function(){
+ $('#forgot_password').click(function(event){
+ event.preventDefault();
+ window.location.pathname = $(this).attr('href') + '?username=' +
+ $('#username').val();
+ });
+});
diff --git a/mediagoblin/static/js/extlib/html5slider.js b/mediagoblin/static/js/extlib/html5slider.js
new file mode 120000
index 00000000..feae2cb8
--- /dev/null
+++ b/mediagoblin/static/js/extlib/html5slider.js
@@ -0,0 +1 @@
+../../../../extlib/html5slider/html5slider.js \ No newline at end of file
diff --git a/mediagoblin/static/js/geolocation-map.js b/mediagoblin/static/js/geolocation-map.js
index a2c62045..de49a37d 100644
--- a/mediagoblin/static/js/geolocation-map.js
+++ b/mediagoblin/static/js/geolocation-map.js
@@ -17,6 +17,11 @@
*/
$(document).ready(function () {
+ if (!$('#tile-map').length) {
+ return;
+ }
+ console.log('Initializing map');
+
var longitude = Number(
$('#tile-map #gps-longitude').val());
var latitude = Number(
diff --git a/mediagoblin/static/js/header_dropdown.js b/mediagoblin/static/js/header_dropdown.js
new file mode 100644
index 00000000..643bafa4
--- /dev/null
+++ b/mediagoblin/static/js/header_dropdown.js
@@ -0,0 +1,30 @@
+/**
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+$(document).ready(function() {
+ $(".dropdown_items").hide();
+ $(document).mouseup(function(e) {
+ if($(e.target).is(".dropdown")) {
+ $(".dropdown_items").toggle();
+ } else if($(e.target).is(".dropdown_items")) {
+ return;
+ } else {
+ $(".dropdown_items").hide();
+ }
+ });
+});
diff --git a/mediagoblin/static/js/keyboard_navigation.js b/mediagoblin/static/js/keyboard_navigation.js
index d4039a3c..7401e4d8 100644
--- a/mediagoblin/static/js/keyboard_navigation.js
+++ b/mediagoblin/static/js/keyboard_navigation.js
@@ -16,6 +16,15 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+/* It must be wrapped into a function and you also cannot use
+ * $(':not(textarea, input)') because of some reason. */
+
+$(document).ready(function(){
+ $('textarea, input').keydown(function(event){
+ event.stopPropagation();
+ });
+});
+
$(document).keydown(function(event){
switch(event.which){
case 37:
@@ -30,4 +39,3 @@ $(document).keydown(function(event){
break;
}
});
-
diff --git a/mediagoblin/static/js/show_password.js b/mediagoblin/static/js/show_password.js
index e42d44ea..b3fbc862 100644
--- a/mediagoblin/static/js/show_password.js
+++ b/mediagoblin/static/js/show_password.js
@@ -17,6 +17,7 @@
*/
$(document).ready(function(){
+ //Create a duplicate password field. We could change the input type dynamically, but this angers the IE gods (not just IE6).
$("#password").after('<input type="text" value="" name="password_clear" id="password_clear" /><label><input type="checkbox" id="password_boolean" />Show password</label>');
$('#password_clear').hide();
$('#password_boolean').click(function(){
diff --git a/mediagoblin/storage/__init__.py b/mediagoblin/storage/__init__.py
index e7ea1aa5..3df56c2e 100644
--- a/mediagoblin/storage/__init__.py
+++ b/mediagoblin/storage/__init__.py
@@ -14,9 +14,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-import os
import shutil
-import urlparse
import uuid
from werkzeug.utils import secure_filename
diff --git a/mediagoblin/storage/cloudfiles.py b/mediagoblin/storage/cloudfiles.py
index 46843274..ce517932 100644
--- a/mediagoblin/storage/cloudfiles.py
+++ b/mediagoblin/storage/cloudfiles.py
@@ -42,6 +42,9 @@ class CloudFilesStorage(StorageInterface):
self.param_host = kwargs.get('cloudfiles_host')
self.param_use_servicenet = kwargs.get('cloudfiles_use_servicenet')
+ # the Mime Type webm doesn't exists, let's add it
+ mimetypes.add_type("video/webm", "webm")
+
if not self.param_host:
print('No CloudFiles host URL specified, '
'defaulting to Rackspace US')
@@ -70,8 +73,7 @@ class CloudFilesStorage(StorageInterface):
def file_exists(self, filepath):
try:
- object = self.container.get_object(
- self._resolve_filepath(filepath))
+ self.container.get_object( self._resolve_filepath(filepath))
return True
except cloudfiles.errors.NoSuchObject:
return False
@@ -92,6 +94,9 @@ class CloudFilesStorage(StorageInterface):
if mimetype:
obj.content_type = mimetype[0]
+ # this should finally fix the bug #429
+ meta_data = {'mime-type' : mimetype[0]}
+ obj.metadata = meta_data
return CloudFilesStorageObjectWrapper(obj, *args, **kwargs)
diff --git a/mediagoblin/storage/mountstorage.py b/mediagoblin/storage/mountstorage.py
index 3fdf4ef0..dffc619b 100644
--- a/mediagoblin/storage/mountstorage.py
+++ b/mediagoblin/storage/mountstorage.py
@@ -17,6 +17,10 @@
from mediagoblin.storage import StorageInterface, clean_listy_filepath
+class MountError(Exception):
+ pass
+
+
class MountStorage(StorageInterface):
"""
Experimental "Mount" virtual Storage Interface
@@ -105,7 +109,7 @@ class MountStorage(StorageInterface):
def resolve_to_backend(self, filepath):
backend, filepath = self._resolve_to_backend(filepath)
if backend is None:
- raise Error("Path not mounted")
+ raise MountError("Path not mounted")
return backend, filepath
def __repr__(self, table=None, indent=[]):
diff --git a/mediagoblin/submit/views.py b/mediagoblin/submit/views.py
index 1e145e9d..517fb646 100644
--- a/mediagoblin/submit/views.py
+++ b/mediagoblin/submit/views.py
@@ -20,7 +20,8 @@ from os.path import splitext
from cgi import FieldStorage
from celery import registry
-import urllib,urllib2
+import urllib
+import urllib2
import logging
_log = logging.getLogger(__name__)
@@ -32,10 +33,11 @@ from mediagoblin.tools.text import convert_to_tag_list_of_dicts
from mediagoblin.tools.translate import pass_to_ugettext as _
from mediagoblin.tools.response import render_to_response, redirect
from mediagoblin.decorators import require_active_login
-from mediagoblin.submit import forms as submit_forms, security
-from mediagoblin.processing import mark_entry_failed, ProcessMedia
+from mediagoblin.submit import forms as submit_forms
+from mediagoblin.processing import mark_entry_failed
+from mediagoblin.processing.task import ProcessMedia
from mediagoblin.messages import add_message, SUCCESS
-from mediagoblin.media_types import get_media_type_and_manager, \
+from mediagoblin.media_types import sniff_media, \
InvalidFileType, FileTypeNotSupported
@@ -55,7 +57,11 @@ def submit_start(request):
else:
try:
filename = request.POST['file'].filename
- media_type, media_manager = get_media_type_and_manager(filename)
+
+ # Sniff the submitted media to determine which
+ # media plugin should handle processing
+ media_type, media_manager = sniff_media(
+ request.POST['file'])
# create entry and save in database
entry = request.db.MediaEntry()
@@ -130,9 +136,10 @@ def submit_start(request):
raise
if mg_globals.app_config["push_urls"]:
- feed_url=request.urlgen(
+ feed_url = request.urlgen(
'mediagoblin.user_pages.atom_feed',
- qualified=True,user=request.user.username)
+ qualified=True,
+ user=request.user.username)
hubparameters = {
'hub.mode': 'publish',
'hub.url': feed_url}
@@ -159,10 +166,9 @@ def submit_start(request):
user=request.user.username)
except Exception as e:
'''
- This section is intended to catch exceptions raised in
+ This section is intended to catch exceptions raised in
mediagobling.media_types
'''
-
if isinstance(e, InvalidFileType) or \
isinstance(e, FileTypeNotSupported):
submit_form.file.errors.append(
diff --git a/mediagoblin/templates/mediagoblin/auth/login.html b/mediagoblin/templates/mediagoblin/auth/login.html
index 39f07d33..8161ea9d 100644
--- a/mediagoblin/templates/mediagoblin/auth/login.html
+++ b/mediagoblin/templates/mediagoblin/auth/login.html
@@ -19,6 +19,11 @@
{% import "/mediagoblin/utils/wtforms.html" as wtforms_util %}
+{% block mediagoblin_head %}
+ <script type="text/javascript"
+ src="{{ request.staticdirect('/js/autofilledin_password.js') }}"></script>
+{% endblock %}
+
{% block mediagoblin_content %}
<form action="{{ request.urlgen('mediagoblin.auth.login') }}"
method="POST" enctype="multipart/form-data">
@@ -38,7 +43,7 @@
{% endif %}
{{ wtforms_util.render_divs(login_form) }}
<p>
- <a href="{{ request.urlgen('mediagoblin.auth.forgot_password') }}">
+ <a href="{{ request.urlgen('mediagoblin.auth.forgot_password') }}" id="forgot_password">
{% trans %}Forgot your password?{% endtrans %}</a>
</p>
<div class="form_submit_buttons">
diff --git a/mediagoblin/templates/mediagoblin/base.html b/mediagoblin/templates/mediagoblin/base.html
index be81c27b..1a3408cd 100644
--- a/mediagoblin/templates/mediagoblin/base.html
+++ b/mediagoblin/templates/mediagoblin/base.html
@@ -28,6 +28,8 @@
<link rel="shortcut icon"
href="{{ request.staticdirect('/images/goblin.ico') }}" />
<script src="{{ request.staticdirect('/js/extlib/jquery.js') }}"></script>
+ <script type="text/javascript"
+ src="{{ request.staticdirect('/js/header_dropdown.js') }}"></script>
<!--[if lt IE 9]>
<script src="{{ request.staticdirect('/js/extlib/html5shiv.js') }}"></script>
<![endif]-->
@@ -36,44 +38,43 @@
</head>
<body>
{% block mediagoblin_body %}
- <div class="container">
{% block mediagoblin_header %}
- <header>
- {% block mediagoblin_logo %}
- <a class="logo"
- href="{{ request.urlgen('index') }}"
- ><img src="{{ request.staticdirect('/images/logo.png') }}"
- alt="{% trans %}MediaGoblin logo{% endtrans %}" /></a>
- {% endblock mediagoblin_logo %}
- {% if request.user and request.user.status == 'active' %}
- <a class="button_action"
- href="{{ request.urlgen('mediagoblin.submit.start') }}">
- {% trans %}Add media{% endtrans %}
- </a>
- {% endif %}
- {% block mediagoblin_header_title %}{% endblock %}
- <div class="header_right">
- {% if request.user %}
- {# the following link should only appear when verification is needed #}
- {% if request.user.status == "needs_email_verification" %}
- <a href="{{ request.urlgen('mediagoblin.user_pages.user_home',
- user=request.user.username) }}"
- class="button_action_highlight">
- {% trans %}Verify your email!{% endtrans %}</a>
- {% endif %}
-
+ <header>
+ {% block mediagoblin_logo %}
+ <a class="logo"
+ href="{{ request.urlgen('index') }}"
+ ><img src="{{ request.staticdirect('/images/logo.png') }}"
+ alt="{% trans %}MediaGoblin logo{% endtrans %}" /></a>
+ {% endblock mediagoblin_logo %}
+ {% block mediagoblin_header_title %}{% endblock %}
+ <div class="header_right">
+ {% if request.user %}
+ {# the following link should only appear when verification is needed #}
+ {% if request.user.status == "needs_email_verification" %}
<a href="{{ request.urlgen('mediagoblin.user_pages.user_home',
- user= request.user.username) }}">
- {{ request.user.username }}</a>
-
- (<a href="{{ request.urlgen('mediagoblin.auth.logout') }}">{% trans %}log out{% endtrans %}</a>)
- {% else %}
- <a href="{{ request.urlgen('mediagoblin.auth.login') }}">
- {% trans %}Log in{% endtrans %}</a>
+ user=request.user.username) }}"
+ class="button_action_highlight">
+ {% trans %}Verify your email!{% endtrans %}</a>
{% endif %}
- </div>
- </header>
+ <div class="dropdown">
+ {{ request.user.username }} â–¾
+ <div class="dropdown_items">
+ {% if request.user and request.user.status == 'active' %}
+ <a href="{{ request.urlgen('mediagoblin.submit.start') }}">{% trans %}+ Add media{% endtrans %}</a>
+ {% endif %}
+ <a href="{{ request.urlgen('mediagoblin.user_pages.user_home', user= request.user.username) }}">{% trans %}View your profile{% endtrans %}</a>
+ <a class="button_action" href="{{ request.urlgen('mediagoblin.auth.logout') }}">{% trans %}Log out{% endtrans %}</a>
+ </div>
+ </div>
+ {% else %}
+ <a href="{{ request.urlgen('mediagoblin.auth.login') }}">
+ {% trans %}Log in{% endtrans %}</a>
+ {% endif %}
+ </div>
+ <div class="clear"></div>
+ </header>
{% endblock %}
+ <div class="container">
<div class="mediagoblin_content">
{% include "mediagoblin/utils/messages.html" %}
{% block mediagoblin_content %}
diff --git a/mediagoblin/templates/mediagoblin/media_displays/audio.html b/mediagoblin/templates/mediagoblin/media_displays/audio.html
new file mode 100644
index 00000000..9713aa49
--- /dev/null
+++ b/mediagoblin/templates/mediagoblin/media_displays/audio.html
@@ -0,0 +1,65 @@
+{#
+# 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 <http://www.gnu.org/licenses/>.
+#}
+
+{% extends 'mediagoblin/user_pages/media.html' %}
+
+{% block mediagoblin_head %}
+ {{ super() }}
+ <link rel="stylesheet" type="text/css" href="{{ request.staticdirect('/css/audio.css') }}" />
+ <script type="text/javascript" src="{{ request.staticdirect(
+ '/js/extlib/html5slider.js') }}"></script>
+ <script type="text/javascript" src="{{ request.staticdirect(
+ '/js/audio.js') }}"></script>
+{% endblock %}
+
+{% block mediagoblin_media %}
+ <div class="audio-media">
+ {% if 'spectrogram' in media.media_files %}
+ <div class="audio-spectrogram">
+ <img src="{{ request.app.public_store.file_url(
+ media.media_files.spectrogram) }}"
+ alt="Spectrogram" />
+ </div>
+ {% endif %}
+ <audio class="audio-player" controls="controls"
+ preload="metadata">
+ <source src="{{ request.app.public_store.file_url(
+ media.media_files.webm_audio) }}" type="audio/webm; codecs=vorbis" />
+ <div class="no_html5">
+ {%- trans -%}Sorry, this audio will not work because
+ your web browser does not support HTML5
+ audio.{%- endtrans -%}<br/>
+ {%- trans -%}You can get a modern web browser that
+ can play the audio at <a href="http://getfirefox.com">
+ http://getfirefox.com</a>!{%- endtrans -%}
+ </div>
+ </audio>
+ </div>
+{% endblock %}
+
+{% block mediagoblin_sidebar %}
+ <h3>{% trans %}Download{% endtrans %}</h3>
+ <ul>
+ {% if 'original' in media.media_files %}
+ <li><a href="{{ request.app.public_store.file_url(
+ media.media_files.original) }}">{% trans %}original file{% endtrans %}</a>
+ {% endif %}
+ <li><a href="{{ request.app.public_store.file_url(
+ media.media_files.webm_audio) }}">{% trans %}WebM file (Vorbis codec){% endtrans %}</a>
+ </ul>
+{% endblock %}
diff --git a/mediagoblin/templates/mediagoblin/media_displays/video.html b/mediagoblin/templates/mediagoblin/media_displays/video.html
index cf68b61b..86c277aa 100644
--- a/mediagoblin/templates/mediagoblin/media_displays/video.html
+++ b/mediagoblin/templates/mediagoblin/media_displays/video.html
@@ -22,12 +22,12 @@
{{ super() }}
<script type="text/javascript"
src="{{ request.staticdirect('/js/extlib/video-js/video.js') }}"></script>
- <link href="{{ request.staticdirect('/js/extlib/video-js/video-js.css') }}" rel="stylesheet">
+ <link href="{{ request.staticdirect('/css/vjs-mg-skin.css') }}" rel="stylesheet">
{% endblock %}
{% block mediagoblin_media %}
<div class="video-player" style="position: relative;">
- <video class="video-js vjs-default-skin"
+ <video class="video-js vjs-mg-skin"
width="{{ media.media_data.width }}"
height="{{ media.media_data.height }}"
controls="controls"
diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html
index 70a367f9..21990442 100644
--- a/mediagoblin/templates/mediagoblin/user_pages/media.html
+++ b/mediagoblin/templates/mediagoblin/user_pages/media.html
@@ -64,12 +64,14 @@
media.media_files['original']) }}">
<img class="media_image"
src="{{ display_media }}"
- alt="Image for {{ media.title }}" />
+ alt="{% trans media_title=media.title -%}
+ Image for {{ media_title }}{% endtrans %}" />
</a>
{% else %}
<img class="media_image"
src="{{ display_media }}"
- alt="Image for {{ media.title }}" />
+ alt="{% trans media_title=media.title -%}
+ Image for {{ media_title }}{% endtrans %}" />
{% endif %}
{% endblock %}
</div>
@@ -114,8 +116,6 @@
</p>
{% endif %}
{% if comments %}
- <h3>
- <div class="right_align">
<a
{% if not request.user %}
href="{{ request.urlgen('mediagoblin.auth.login') }}"
@@ -123,8 +123,6 @@
class="button_action" id="button_addcomment" title="Add a comment">
{% trans %}Add a comment{% endtrans %}
</a>
- </div>
- </h3>
{% if request.user %}
<form action="{{ request.urlgen('mediagoblin.user_pages.media_post_comment',
user= media.get_uploader.username,
@@ -147,10 +145,7 @@
{% else %}
<div class="comment_wrapper" id="comment-{{ comment._id }}">
{% endif %}
- <div class="comment_content">
- {% autoescape False %}
- {{ comment.content_html }}
- {% endautoescape %}
+ <div class="comment_author">
<img src="{{ request.staticdirect('/images/icon_comment.png') }}" />
<a href="{{ request.urlgen('mediagoblin.user_pages.user_home',
user = comment_author.username) }}">
@@ -162,7 +157,12 @@
user = media.get_uploader.username,
media = media.slug_or_id) }}#comment">
{{ comment.created.strftime("%I:%M%p %Y-%m-%d") }}
- </a>
+ </a>:
+ </div>
+ <div class="comment_content">
+ {% autoescape False %}
+ {{ comment.content_html }}
+ {% endautoescape %}
</div>
</div>
{% endfor %}
@@ -184,6 +184,9 @@
{% include "mediagoblin/utils/geolocation_map.html" %}
{% include "mediagoblin/utils/exif.html" %}
+
+ {% block mediagoblin_sidebar %}
+ {% endblock %}
</div>
<div class="clear"></div>
{% endblock %}
diff --git a/mediagoblin/templates/mediagoblin/utils/exif.html b/mediagoblin/templates/mediagoblin/utils/exif.html
index 37f274fe..a89e69c8 100644
--- a/mediagoblin/templates/mediagoblin/utils/exif.html
+++ b/mediagoblin/templates/mediagoblin/utils/exif.html
@@ -18,11 +18,12 @@
{% block exif_content %}
{% if app_config['exif_visible']
- and media.media_data.exif is defined
- and media.media_data.exif.has_key('useful') %}
+ and media.media_data
+ and media.media_data.exif_all is defined
+ and media.media_data.exif_all %}
<h3>EXIF</h3>
<table>
- {% for key, tag in media.media_data.exif.useful.items() %}
+ {% for key, tag in media.exif_display_iter() %}
<tr>
<td>{{ key }}</td>
<td>{{ tag.printable }}</td>
diff --git a/mediagoblin/templates/mediagoblin/utils/wtforms.html b/mediagoblin/templates/mediagoblin/utils/wtforms.html
index a85a3d96..58ecb8e0 100644
--- a/mediagoblin/templates/mediagoblin/utils/wtforms.html
+++ b/mediagoblin/templates/mediagoblin/utils/wtforms.html
@@ -25,7 +25,7 @@
{{ field }}
{%- if field.errors -%}
{% for error in field.errors %}
- <p class="form_field_error">{{ error }}</p>
+ <p class="form_field_error">{{ _(error) }}</p>
{% endfor %}
{%- endif %}
{% if field.description -%}
diff --git a/mediagoblin/tests/__init__.py b/mediagoblin/tests/__init__.py
index 15a5add0..4e84914a 100644
--- a/mediagoblin/tests/__init__.py
+++ b/mediagoblin/tests/__init__.py
@@ -14,10 +14,12 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-from mediagoblin import mg_globals
+import os
+import shutil
+from mediagoblin import mg_globals
from mediagoblin.tests.tools import (
- MEDIAGOBLIN_TEST_DB_NAME, suicide_if_bad_celery_environ)
+ TEST_USER_DEV, suicide_if_bad_celery_environ)
def setup_package():
@@ -25,8 +27,6 @@ def setup_package():
def teardown_package():
- if ((mg_globals.db_connection
- and mg_globals.database.name == MEDIAGOBLIN_TEST_DB_NAME)):
- print "Killing db ..."
- mg_globals.db_connection.drop_database(MEDIAGOBLIN_TEST_DB_NAME)
- print "... done"
+ # Remove and reinstall user_dev directories
+ if os.path.exists(TEST_USER_DEV):
+ shutil.rmtree(TEST_USER_DEV)
diff --git a/mediagoblin/tests/test_auth.py b/mediagoblin/tests/test_auth.py
index 3a33c66c..8f988af3 100644
--- a/mediagoblin/tests/test_auth.py
+++ b/mediagoblin/tests/test_auth.py
@@ -269,6 +269,7 @@ def test_register_views(test_app):
## Try using an expired token to change password, shouldn't work
template.clear_test_template_context()
+ new_user = mg_globals.database.User.find_one({'username': 'happygirl'})
real_token_expiration = new_user.fp_token_expire
new_user.fp_token_expire = datetime.datetime.now()
new_user.save()
diff --git a/mediagoblin/tests/test_celery_setup.py b/mediagoblin/tests/test_celery_setup.py
index fd600f56..5530c6f2 100644
--- a/mediagoblin/tests/test_celery_setup.py
+++ b/mediagoblin/tests/test_celery_setup.py
@@ -48,7 +48,7 @@ def test_setup_celery_from_config():
assert isinstance(fake_celery_module.CELERYD_ETA_SCHEDULER_PRECISION, float)
assert fake_celery_module.CELERY_RESULT_PERSISTENT is True
assert fake_celery_module.CELERY_IMPORTS == [
- 'foo.bar.baz', 'this.is.an.import', 'mediagoblin.processing']
+ 'foo.bar.baz', 'this.is.an.import', 'mediagoblin.processing.task']
assert fake_celery_module.CELERY_RESULT_BACKEND == 'database'
assert fake_celery_module.CELERY_RESULT_DBURI == (
'sqlite:///' +
diff --git a/mediagoblin/tests/test_csrf_middleware.py b/mediagoblin/tests/test_csrf_middleware.py
index f49dc94e..ad433fe8 100644
--- a/mediagoblin/tests/test_csrf_middleware.py
+++ b/mediagoblin/tests/test_csrf_middleware.py
@@ -14,11 +14,6 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-import urlparse
-import datetime
-
-from nose.tools import assert_equal
-
from mediagoblin.tests.tools import setup_fresh_app
from mediagoblin import mg_globals
diff --git a/mediagoblin/tests/test_mgoblin_app.ini b/mediagoblin/tests/test_mgoblin_app.ini
index 01bf0972..3b979ff7 100644
--- a/mediagoblin/tests/test_mgoblin_app.ini
+++ b/mediagoblin/tests/test_mgoblin_app.ini
@@ -2,7 +2,9 @@
direct_remote_path = /test_static/
email_sender_address = "notice@mediagoblin.example.org"
email_debug_mode = true
-db_name = __mediagoblin_tests__
+
+# TODO: Switch to using an in-memory database
+sql_engine = "sqlite:///%(here)s/test_user_dev/mediagoblin.db"
# tag parsing
tags_max_length = 50
@@ -27,3 +29,5 @@ lock_dir = %(here)s/test_user_dev/beaker/cache/lock
[celery]
CELERY_ALWAYS_EAGER = true
+CELERY_RESULT_DBURI = "sqlite:///%(here)s/test_user_dev/celery.db"
+BROKER_HOST = "sqlite:///%(here)s/test_user_dev/kombu.db"
diff --git a/mediagoblin/tests/test_migrations.py b/mediagoblin/tests/test_migrations.py
deleted file mode 100644
index f6e6c1a8..00000000
--- a/mediagoblin/tests/test_migrations.py
+++ /dev/null
@@ -1,401 +0,0 @@
-# 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 <http://www.gnu.org/licenses/>.
-
-
-from nose.tools import assert_raises
-from pymongo import Connection
-
-from mediagoblin.tests.tools import (
- install_fixtures_simple, assert_db_meets_expected)
-from mediagoblin.db.mongo.util import (
- RegisterMigration, MigrationManager, ObjectId,
- MissingCurrentMigration)
-from mediagoblin.db.mongo.migrations import add_table_field
-
-# This one will get filled with local migrations
-TEST_MIGRATION_REGISTRY = {}
-# this one won't get filled
-TEST_EMPTY_MIGRATION_REGISTRY = {}
-
-MIGRATION_DB_NAME = u'__mediagoblin_test_migrations__'
-
-
-######################
-# Fake test migrations
-######################
-
-@RegisterMigration(1, TEST_MIGRATION_REGISTRY)
-def creature_add_magical_powers(database):
- """
- Add lists of magical powers.
-
- This defaults to [], an empty list. Since we haven't declared any
- magical powers, all existing monsters, setting to an empty list is
- fine.
- """
- add_table_field(database, 'creatures', 'magical_powers', [])
-
-
-@RegisterMigration(2, TEST_MIGRATION_REGISTRY)
-def creature_rename_num_legs_to_num_limbs(database):
- """
- It turns out we want to track how many limbs a creature has, not
- just how many legs. We don't care about the ambiguous distinction
- between arms/legs currently.
- """
- # $rename not available till 1.7.2+, Debian Stable only includes
- # 1.4.4... we should do renames manually for now :(
-
- collection = database['creatures']
- target = collection.find(
- {'num_legs': {'$exists': True}})
-
- for document in target:
- # A lame manual renaming.
- document['num_limbs'] = document.pop('num_legs')
- collection.save(document)
-
-
-@RegisterMigration(3, TEST_MIGRATION_REGISTRY)
-def creature_remove_is_demon(database):
- """
- It turns out we don't care much about whether creatures are demons
- or not.
- """
- database['creatures'].update(
- {'is_demon': {'$exists': True}},
- {'$unset': {'is_demon': 1}},
- multi=True)
-
-
-@RegisterMigration(4, TEST_MIGRATION_REGISTRY)
-def level_exits_dict_to_list(database):
- """
- For the sake of the indexes we want to write, and because we
- intend to add more flexible fields, we want to move level exits
- from like:
-
- {'big_door': 'castle_level_id',
- 'trapdoor': 'dungeon_level_id'}
-
- to like:
-
- [{'name': 'big_door',
- 'exits_to': 'castle_level_id'},
- {'name': 'trapdoor',
- 'exits_to': 'dungeon_level_id'}]
- """
- collection = database['levels']
- target = collection.find(
- {'exits': {'$type': 3}})
-
- for level in target:
- new_exits = []
- for exit_name, exits_to in level['exits'].items():
- new_exits.append(
- {'name': exit_name,
- 'exits_to': exits_to})
-
- level['exits'] = new_exits
- collection.save(level)
-
-
-CENTIPEDE_OBJECTID = ObjectId()
-WOLF_OBJECTID = ObjectId()
-WIZARDSNAKE_OBJECTID = ObjectId()
-
-UNMIGRATED_DBDATA = {
- 'creatures': [
- {'_id': CENTIPEDE_OBJECTID,
- 'name': 'centipede',
- 'num_legs': 100,
- 'is_demon': False},
- {'_id': WOLF_OBJECTID,
- 'name': 'wolf',
- 'num_legs': 4,
- 'is_demon': False},
- # don't ask me what a wizardsnake is.
- {'_id': WIZARDSNAKE_OBJECTID,
- 'name': 'wizardsnake',
- 'num_legs': 0,
- 'is_demon': True}],
- 'levels': [
- {'_id': 'necroplex',
- 'name': 'The Necroplex',
- 'description': 'A complex full of pure deathzone.',
- 'exits': {
- 'deathwell': 'evilstorm',
- 'portal': 'central_park'}},
- {'_id': 'evilstorm',
- 'name': 'Evil Storm',
- 'description': 'A storm full of pure evil.',
- 'exits': {}}, # you can't escape the evilstorm
- {'_id': 'central_park',
- 'name': 'Central Park, NY, NY',
- 'description': "New York's friendly Central Park.",
- 'exits': {
- 'portal': 'necroplex'}}]}
-
-
-EXPECTED_POST_MIGRATION_UNMIGRATED_DBDATA = {
- 'creatures': [
- {'_id': CENTIPEDE_OBJECTID,
- 'name': 'centipede',
- 'num_limbs': 100,
- 'magical_powers': []},
- {'_id': WOLF_OBJECTID,
- 'name': 'wolf',
- 'num_limbs': 4,
- # kept around namely to check that it *isn't* removed!
- 'magical_powers': []},
- {'_id': WIZARDSNAKE_OBJECTID,
- 'name': 'wizardsnake',
- 'num_limbs': 0,
- 'magical_powers': []}],
- 'levels': [
- {'_id': 'necroplex',
- 'name': 'The Necroplex',
- 'description': 'A complex full of pure deathzone.',
- 'exits': [
- {'name': 'deathwell',
- 'exits_to': 'evilstorm'},
- {'name': 'portal',
- 'exits_to': 'central_park'}]},
- {'_id': 'evilstorm',
- 'name': 'Evil Storm',
- 'description': 'A storm full of pure evil.',
- 'exits': []}, # you can't escape the evilstorm
- {'_id': 'central_park',
- 'name': 'Central Park, NY, NY',
- 'description': "New York's friendly Central Park.",
- 'exits': [
- {'name': 'portal',
- 'exits_to': 'necroplex'}]}]}
-
-# We want to make sure that if we're at migration 3, migration 3
-# doesn't get re-run.
-
-SEMI_MIGRATED_DBDATA = {
- 'creatures': [
- {'_id': CENTIPEDE_OBJECTID,
- 'name': 'centipede',
- 'num_limbs': 100,
- 'magical_powers': []},
- {'_id': WOLF_OBJECTID,
- 'name': 'wolf',
- 'num_limbs': 4,
- # kept around namely to check that it *isn't* removed!
- 'is_demon': False,
- 'magical_powers': [
- 'ice_breath', 'death_stare']},
- {'_id': WIZARDSNAKE_OBJECTID,
- 'name': 'wizardsnake',
- 'num_limbs': 0,
- 'magical_powers': [
- 'death_rattle', 'sneaky_stare',
- 'slithery_smoke', 'treacherous_tremors'],
- 'is_demon': True}],
- 'levels': [
- {'_id': 'necroplex',
- 'name': 'The Necroplex',
- 'description': 'A complex full of pure deathzone.',
- 'exits': {
- 'deathwell': 'evilstorm',
- 'portal': 'central_park'}},
- {'_id': 'evilstorm',
- 'name': 'Evil Storm',
- 'description': 'A storm full of pure evil.',
- 'exits': {}}, # you can't escape the evilstorm
- {'_id': 'central_park',
- 'name': 'Central Park, NY, NY',
- 'description': "New York's friendly Central Park.",
- 'exits': {
- 'portal': 'necroplex'}}]}
-
-
-EXPECTED_POST_MIGRATION_SEMI_MIGRATED_DBDATA = {
- 'creatures': [
- {'_id': CENTIPEDE_OBJECTID,
- 'name': 'centipede',
- 'num_limbs': 100,
- 'magical_powers': []},
- {'_id': WOLF_OBJECTID,
- 'name': 'wolf',
- 'num_limbs': 4,
- # kept around namely to check that it *isn't* removed!
- 'is_demon': False,
- 'magical_powers': [
- 'ice_breath', 'death_stare']},
- {'_id': WIZARDSNAKE_OBJECTID,
- 'name': 'wizardsnake',
- 'num_limbs': 0,
- 'magical_powers': [
- 'death_rattle', 'sneaky_stare',
- 'slithery_smoke', 'treacherous_tremors'],
- 'is_demon': True}],
- 'levels': [
- {'_id': 'necroplex',
- 'name': 'The Necroplex',
- 'description': 'A complex full of pure deathzone.',
- 'exits': [
- {'name': 'deathwell',
- 'exits_to': 'evilstorm'},
- {'name': 'portal',
- 'exits_to': 'central_park'}]},
- {'_id': 'evilstorm',
- 'name': 'Evil Storm',
- 'description': 'A storm full of pure evil.',
- 'exits': []}, # you can't escape the evilstorm
- {'_id': 'central_park',
- 'name': 'Central Park, NY, NY',
- 'description': "New York's friendly Central Park.",
- 'exits': [
- {'name': 'portal',
- 'exits_to': 'necroplex'}]}]}
-
-
-class TestMigrations(object):
- def setUp(self):
- # Set up the connection, drop an existing possible database
- self.connection = Connection()
- self.connection.drop_database(MIGRATION_DB_NAME)
- self.db = Connection()[MIGRATION_DB_NAME]
- self.migration_manager = MigrationManager(
- self.db, TEST_MIGRATION_REGISTRY)
- self.empty_migration_manager = MigrationManager(
- self.db, TEST_EMPTY_MIGRATION_REGISTRY)
- self.run_migrations = []
-
- def tearDown(self):
- self.connection.drop_database(MIGRATION_DB_NAME)
-
- def _record_migration(self, migration_number, migration_func):
- self.run_migrations.append((migration_number, migration_func))
-
- def test_migrations_registered_and_sorted(self):
- """
- Make sure that migrations get registered and are sorted right
- in the migration manager
- """
- assert TEST_MIGRATION_REGISTRY == {
- 1: creature_add_magical_powers,
- 2: creature_rename_num_legs_to_num_limbs,
- 3: creature_remove_is_demon,
- 4: level_exits_dict_to_list}
- assert self.migration_manager.sorted_migrations == [
- (1, creature_add_magical_powers),
- (2, creature_rename_num_legs_to_num_limbs),
- (3, creature_remove_is_demon),
- (4, level_exits_dict_to_list)]
- assert self.empty_migration_manager.sorted_migrations == []
-
- def test_run_full_migrations(self):
- """
- Make sure that running the full migration suite from 0 updates
- everything
- """
- self.migration_manager.set_current_migration(0)
- assert self.migration_manager.database_current_migration() == 0
- install_fixtures_simple(self.db, UNMIGRATED_DBDATA)
- self.migration_manager.migrate_new(post_callback=self._record_migration)
-
- assert self.run_migrations == [
- (1, creature_add_magical_powers),
- (2, creature_rename_num_legs_to_num_limbs),
- (3, creature_remove_is_demon),
- (4, level_exits_dict_to_list)]
-
- assert_db_meets_expected(
- self.db, EXPECTED_POST_MIGRATION_UNMIGRATED_DBDATA)
-
- # Make sure the migration is recorded correctly
- assert self.migration_manager.database_current_migration() == 4
-
- # run twice! It should do nothing the second time.
- # ------------------------------------------------
- self.run_migrations = []
- self.migration_manager.migrate_new(post_callback=self._record_migration)
- assert self.run_migrations == []
- assert_db_meets_expected(
- self.db, EXPECTED_POST_MIGRATION_UNMIGRATED_DBDATA)
- assert self.migration_manager.database_current_migration() == 4
-
-
- def test_run_partial_migrations(self):
- """
- Make sure that running full migration suite from 3 only runs
- last migration
- """
- self.migration_manager.set_current_migration(3)
- assert self.migration_manager.database_current_migration() == 3
- install_fixtures_simple(self.db, SEMI_MIGRATED_DBDATA)
- self.migration_manager.migrate_new(post_callback=self._record_migration)
-
- assert self.run_migrations == [
- (4, level_exits_dict_to_list)]
-
- assert_db_meets_expected(
- self.db, EXPECTED_POST_MIGRATION_SEMI_MIGRATED_DBDATA)
-
- # Make sure the migration is recorded correctly
- assert self.migration_manager.database_current_migration() == 4
-
- def test_migrations_recorded_as_latest(self):
- """
- Make sure that if we don't have a migration_status
- pre-recorded it's marked as the latest
- """
- self.migration_manager.install_migration_version_if_missing()
- assert self.migration_manager.database_current_migration() == 4
-
- def test_no_migrations_recorded_as_zero(self):
- """
- Make sure that if we don't have a migration_status
- but there *are* no migrations that it's marked as 0
- """
- self.empty_migration_manager.install_migration_version_if_missing()
- assert self.empty_migration_manager.database_current_migration() == 0
-
- def test_migrations_to_run(self):
- """
- Make sure we get the right list of migrations to run
- """
- self.migration_manager.set_current_migration(0)
-
- assert self.migration_manager.migrations_to_run() == [
- (1, creature_add_magical_powers),
- (2, creature_rename_num_legs_to_num_limbs),
- (3, creature_remove_is_demon),
- (4, level_exits_dict_to_list)]
-
- self.migration_manager.set_current_migration(3)
-
- assert self.migration_manager.migrations_to_run() == [
- (4, level_exits_dict_to_list)]
-
- self.migration_manager.set_current_migration(4)
-
- assert self.migration_manager.migrations_to_run() == []
-
-
- def test_no_migrations_raises_exception(self):
- """
- If we don't have the current migration set in the database,
- this should error out.
- """
- assert_raises(
- MissingCurrentMigration,
- self.migration_manager.migrations_to_run)
diff --git a/mediagoblin/tests/test_pluginapi.py b/mediagoblin/tests/test_pluginapi.py
new file mode 100644
index 00000000..c5c614f6
--- /dev/null
+++ b/mediagoblin/tests/test_pluginapi.py
@@ -0,0 +1,158 @@
+# 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 <http://www.gnu.org/licenses/>.
+
+import sys
+from configobj import ConfigObj
+from mediagoblin import mg_globals
+from mediagoblin.init.plugins import setup_plugins
+from mediagoblin.tools import pluginapi
+from nose.tools import eq_
+
+
+def with_cleanup(*modules_to_delete):
+ def _with_cleanup(fun):
+ """Wrapper that saves and restores mg_globals"""
+ def _with_cleanup_inner(*args, **kwargs):
+ old_app_config = mg_globals.app_config
+ old_global_config = mg_globals.global_config
+ # Need to delete icky modules before and after so as to make
+ # sure things work correctly.
+ for module in modules_to_delete:
+ try:
+ del sys.modules[module]
+ except KeyError:
+ pass
+ # The plugin cache gets populated as a side-effect of
+ # importing, so it's best to clear it before and after a test.
+ pcache = pluginapi.PluginCache()
+ pcache.clear()
+ try:
+ return fun(*args, **kwargs)
+ finally:
+ mg_globals.app_config = old_app_config
+ mg_globals.global_config = old_global_config
+ # Need to delete icky modules before and after so as to make
+ # sure things work correctly.
+ for module in modules_to_delete:
+ try:
+ del sys.modules[module]
+ except KeyError:
+ pass
+ pcache.clear()
+
+ _with_cleanup_inner.__name__ = fun.__name__
+ return _with_cleanup_inner
+ return _with_cleanup
+
+
+def build_config(sections):
+ """Builds a ConfigObj object with specified data
+
+ :arg sections: list of ``(section_name, section_data,
+ subsection_list)`` tuples where section_data is a dict and
+ subsection_list is a list of ``(section_name, section_data,
+ subsection_list)``, ...
+
+ For example:
+
+ >>> build_config([
+ ... ('mediagoblin', {'key1': 'val1'}, []),
+ ... ('section2', {}, [
+ ... ('subsection1', {}, [])
+ ... ])
+ ... ])
+ """
+ cfg = ConfigObj()
+ cfg.filename = 'foo'
+ def _iter_section(cfg, section_list):
+ for section_name, data, subsection_list in section_list:
+ cfg[section_name] = data
+ _iter_section(cfg[section_name], subsection_list)
+
+ _iter_section(cfg, sections)
+ return cfg
+
+
+@with_cleanup()
+def test_no_plugins():
+ """Run setup_plugins with no plugins in config"""
+ cfg = build_config([('mediagoblin', {}, [])])
+ mg_globals.app_config = cfg['mediagoblin']
+ mg_globals.global_config = cfg
+
+ pcache = pluginapi.PluginCache()
+ setup_plugins()
+
+ # Make sure we didn't load anything.
+ eq_(len(pcache.plugin_classes), 0)
+ eq_(len(pcache.plugin_objects), 0)
+
+
+@with_cleanup('mediagoblin.plugins.sampleplugin',
+ 'mediagoblin.plugins.sampleplugin.main')
+def test_one_plugin():
+ """Run setup_plugins with a single working plugin"""
+ cfg = build_config([
+ ('mediagoblin', {}, []),
+ ('plugins', {}, [
+ ('mediagoblin.plugins.sampleplugin', {}, [])
+ ])
+ ])
+
+ mg_globals.app_config = cfg['mediagoblin']
+ mg_globals.global_config = cfg
+
+ pcache = pluginapi.PluginCache()
+ setup_plugins()
+
+ # Make sure we only found one plugin class
+ eq_(len(pcache.plugin_classes), 1)
+ # Make sure the class is the one we think it is.
+ eq_(pcache.plugin_classes[0].__name__, 'SamplePlugin')
+
+ # Make sure there was one plugin created
+ eq_(len(pcache.plugin_objects), 1)
+ # Make sure we called setup_plugin on SamplePlugin
+ eq_(pcache.plugin_objects[0]._setup_plugin_called, 1)
+
+
+@with_cleanup('mediagoblin.plugins.sampleplugin',
+ 'mediagoblin.plugins.sampleplugin.main')
+def test_same_plugin_twice():
+ """Run setup_plugins with a single working plugin twice"""
+ cfg = build_config([
+ ('mediagoblin', {}, []),
+ ('plugins', {}, [
+ ('mediagoblin.plugins.sampleplugin', {}, []),
+ ('mediagoblin.plugins.sampleplugin', {}, []),
+ ])
+ ])
+
+ mg_globals.app_config = cfg['mediagoblin']
+ mg_globals.global_config = cfg
+
+ pcache = pluginapi.PluginCache()
+ setup_plugins()
+
+ # Make sure we only found one plugin class
+ eq_(len(pcache.plugin_classes), 1)
+ # Make sure the class is the one we think it is.
+ eq_(pcache.plugin_classes[0].__name__, 'SamplePlugin')
+
+ # Make sure there was one plugin created
+ eq_(len(pcache.plugin_objects), 1)
+ # Make sure we called setup_plugin on SamplePlugin
+ eq_(pcache.plugin_objects[0]._setup_plugin_called, 1)
diff --git a/mediagoblin/tests/test_processing.py b/mediagoblin/tests/test_processing.py
new file mode 100644
index 00000000..fe8489aa
--- /dev/null
+++ b/mediagoblin/tests/test_processing.py
@@ -0,0 +1,20 @@
+#!/usr/bin/env python
+
+from nose.tools import assert_equal
+
+from mediagoblin import processing
+
+class TestProcessing(object):
+ def run_fill(self, input, format, output=None):
+ builder = processing.FilenameBuilder(input)
+ result = builder.fill(format)
+ if output is None:
+ return result
+ assert_equal(output, result)
+
+ def test_easy_filename_fill(self):
+ self.run_fill('/home/user/foo.TXT', '{basename}bar{ext}', 'foobar.txt')
+
+ def test_long_filename_fill(self):
+ self.run_fill('{0}.png'.format('A' * 300), 'image-{basename}{ext}',
+ 'image-{0}.png'.format('A' * 245))
diff --git a/mediagoblin/tests/test_submission.py b/mediagoblin/tests/test_submission.py
index 1f56779e..bf1b87aa 100644
--- a/mediagoblin/tests/test_submission.py
+++ b/mediagoblin/tests/test_submission.py
@@ -15,30 +15,34 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import urlparse
-import pkg_resources
-import re
+import os
-from nose.tools import assert_equal, assert_true, assert_false
+from nose.tools import assert_equal, assert_true
+from pkg_resources import resource_filename
-from mediagoblin.tests.tools import setup_fresh_app, get_test_app, \
+from mediagoblin.tests.tools import get_test_app, \
fixture_add_user
from mediagoblin import mg_globals
-from mediagoblin.tools import template, common
-
-GOOD_JPG = pkg_resources.resource_filename(
- 'mediagoblin.tests', 'test_submission/good.jpg')
-GOOD_PNG = pkg_resources.resource_filename(
- 'mediagoblin.tests', 'test_submission/good.png')
-EVIL_FILE = pkg_resources.resource_filename(
- 'mediagoblin.tests', 'test_submission/evil')
-EVIL_JPG = pkg_resources.resource_filename(
- 'mediagoblin.tests', 'test_submission/evil.jpg')
-EVIL_PNG = pkg_resources.resource_filename(
- 'mediagoblin.tests', 'test_submission/evil.png')
+from mediagoblin.tools import template
+
+
+def resource(filename):
+ return resource_filename('mediagoblin.tests', 'test_submission/' + filename)
+
+
+GOOD_JPG = resource('good.jpg')
+GOOD_PNG = resource('good.png')
+EVIL_FILE = resource('evil')
+EVIL_JPG = resource('evil.jpg')
+EVIL_PNG = resource('evil.png')
+BIG_BLUE = resource('bigblue.png')
GOOD_TAG_STRING = 'yin,yang'
BAD_TAG_STRING = 'rage,' + 'f' * 26 + 'u' * 26
+FORM_CONTEXT = ['mediagoblin/submit/start.html', 'submit_form']
+REQUEST_CONTEXT = ['mediagoblin/user_pages/user.html', 'request']
+
class TestSubmission:
def setUp(self):
@@ -61,234 +65,193 @@ class TestSubmission:
def logout(self):
self.test_app.get('/auth/logout/')
+ def do_post(self, data, *context_keys, **kwargs):
+ url = kwargs.pop('url', '/submit/')
+ do_follow = kwargs.pop('do_follow', False)
+ template.clear_test_template_context()
+ response = self.test_app.post(url, data, **kwargs)
+ if do_follow:
+ response.follow()
+ context_data = template.TEMPLATE_TEST_CONTEXT
+ for key in context_keys:
+ context_data = context_data[key]
+ return response, context_data
+
+ def upload_data(self, filename):
+ return {'upload_files': [('file', filename)]}
+
+ def check_comments(self, request, media_id, count):
+ comments = request.db.MediaComment.find({'media_entry': media_id})
+ assert_equal(count, len(list(comments)))
+
def test_missing_fields(self):
# Test blank form
# ---------------
- template.clear_test_template_context()
- response = self.test_app.post(
- '/submit/', {})
- context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/submit/start.html']
- form = context['submit_form']
- assert form.file.errors == [u'You must provide a file.']
+ response, form = self.do_post({}, *FORM_CONTEXT)
+ assert_equal(form.file.errors, [u'You must provide a file.'])
# Test blank file
# ---------------
- template.clear_test_template_context()
- response = self.test_app.post(
- '/submit/', {
- 'title': 'test title'})
- context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/submit/start.html']
- form = context['submit_form']
- assert form.file.errors == [u'You must provide a file.']
-
-
- def test_normal_uploads(self):
- # Test JPG
- # --------
- template.clear_test_template_context()
- response = self.test_app.post(
- '/submit/', {
- 'title': 'Normal upload 1'
- }, upload_files=[(
- 'file', GOOD_JPG)])
+ response, form = self.do_post({'title': 'test title'}, *FORM_CONTEXT)
+ assert_equal(form.file.errors, [u'You must provide a file.'])
- # User should be redirected
- response.follow()
- assert_equal(
- urlparse.urlsplit(response.location)[2],
- '/u/chris/')
- assert template.TEMPLATE_TEST_CONTEXT.has_key(
- 'mediagoblin/user_pages/user.html')
+ def check_url(self, response, path):
+ assert_equal(urlparse.urlsplit(response.location)[2], path)
+ def check_normal_upload(self, title, filename):
+ response, context = self.do_post({'title': title}, do_follow=True,
+ **self.upload_data(filename))
+ self.check_url(response, '/u/{0}/'.format(self.test_user.username))
+ assert_true('mediagoblin/user_pages/user.html' in context)
# Make sure the media view is at least reachable, logged in...
- self.test_app.get('/u/chris/m/normal-upload-1/')
+ url = '/u/{0}/m/{1}/'.format(self.test_user.username,
+ title.lower().replace(' ', '-'))
+ self.test_app.get(url)
# ... and logged out too.
self.logout()
- self.test_app.get('/u/chris/m/normal-upload-1/')
- # Log back in for the remaining tests.
- self.login()
+ self.test_app.get(url)
- # Test PNG
- # --------
- template.clear_test_template_context()
- response = self.test_app.post(
- '/submit/', {
- 'title': 'Normal upload 2'
- }, upload_files=[(
- 'file', GOOD_PNG)])
+ def test_normal_jpg(self):
+ self.check_normal_upload('Normal upload 1', GOOD_JPG)
- response.follow()
- assert_equal(
- urlparse.urlsplit(response.location)[2],
- '/u/chris/')
- assert template.TEMPLATE_TEST_CONTEXT.has_key(
- 'mediagoblin/user_pages/user.html')
+ def test_normal_png(self):
+ self.check_normal_upload('Normal upload 2', GOOD_PNG)
+
+ def check_media(self, request, find_data, count=None):
+ media = request.db.MediaEntry.find(find_data)
+ if count is not None:
+ assert_equal(media.count(), count)
+ if count == 0:
+ return
+ return media[0]
def test_tags(self):
# Good tag string
# --------
- template.clear_test_template_context()
- response = self.test_app.post(
- '/submit/', {
- 'title': 'Balanced Goblin',
- 'tags': GOOD_TAG_STRING
- }, upload_files=[(
- 'file', GOOD_JPG)])
+ response, request = self.do_post({'title': 'Balanced Goblin',
+ 'tags': GOOD_TAG_STRING},
+ *REQUEST_CONTEXT, do_follow=True,
+ **self.upload_data(GOOD_JPG))
+ media = self.check_media(request, {'title': 'Balanced Goblin'}, 1)
+ assert media.tags[0]['name'] == u'yin'
+ assert media.tags[0]['slug'] == u'yin'
- # New media entry with correct tags should be created
- response.follow()
- context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/user_pages/user.html']
- request = context['request']
- media = request.db.MediaEntry.find({'title': 'Balanced Goblin'})[0]
- assert_equal(media.tags,
- [{'name': u'yin', 'slug': u'yin'},
- {'name': u'yang', 'slug': u'yang'}])
+ assert media.tags[1]['name'] == u'yang'
+ assert media.tags[1]['slug'] == u'yang'
# Test tags that are too long
# ---------------
- template.clear_test_template_context()
- response = self.test_app.post(
- '/submit/', {
- 'title': 'Balanced Goblin',
- 'tags': BAD_TAG_STRING
- }, upload_files=[(
- 'file', GOOD_JPG)])
-
- # Too long error should be raised
- context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/submit/start.html']
- form = context['submit_form']
- assert form.tags.errors == [
- u'Tags must be shorter than 50 characters. Tags that are too long'\
- ': ffffffffffffffffffffffffffuuuuuuuuuuuuuuuuuuuuuuuuuu']
+ response, form = self.do_post({'title': 'Balanced Goblin',
+ 'tags': BAD_TAG_STRING},
+ *FORM_CONTEXT,
+ **self.upload_data(GOOD_JPG))
+ assert_equal(form.tags.errors, [
+ u'Tags must be shorter than 50 characters. ' \
+ 'Tags that are too long: ' \
+ 'ffffffffffffffffffffffffffuuuuuuuuuuuuuuuuuuuuuuuuuu'])
def test_delete(self):
- template.clear_test_template_context()
- response = self.test_app.post(
- '/submit/', {
- 'title': 'Balanced Goblin',
- }, upload_files=[(
- 'file', GOOD_JPG)])
-
- # Post image
- response.follow()
-
- request = template.TEMPLATE_TEST_CONTEXT[
- 'mediagoblin/user_pages/user.html']['request']
-
- media = request.db.MediaEntry.find({'title': 'Balanced Goblin'})[0]
-
- # Does media entry exist?
- assert_true(media)
+ response, request = self.do_post({'title': 'Balanced Goblin'},
+ *REQUEST_CONTEXT, do_follow=True,
+ **self.upload_data(GOOD_JPG))
+ media = self.check_media(request, {'title': 'Balanced Goblin'}, 1)
+ media_id = media.id
# Add a comment, so we can test for its deletion later.
- get_comments = lambda: list(
- request.db.MediaComment.find({'media_entry': media._id}))
- assert_false(get_comments())
- response = self.test_app.post(
- request.urlgen('mediagoblin.user_pages.media_post_comment',
- user=self.test_user.username,
- media=media._id),
- {'comment_content': 'i love this test'})
- response.follow()
- assert_true(get_comments())
+ self.check_comments(request, media_id, 0)
+ comment_url = request.urlgen(
+ 'mediagoblin.user_pages.media_post_comment',
+ user=self.test_user.username, media=media_id)
+ response = self.do_post({'comment_content': 'i love this test'},
+ url=comment_url, do_follow=True)[0]
+ self.check_comments(request, media_id, 1)
# Do not confirm deletion
# ---------------------------------------------------
- response = self.test_app.post(
- request.urlgen('mediagoblin.user_pages.media_confirm_delete',
- # No work: user=media.uploader().username,
- user=self.test_user.username,
- media=media._id),
- # no value means no confirm
- {})
-
- response.follow()
-
- request = template.TEMPLATE_TEST_CONTEXT[
- 'mediagoblin/user_pages/user.html']['request']
-
- media = request.db.MediaEntry.find({'title': 'Balanced Goblin'})[0]
-
- # Does media entry still exist?
- assert_true(media)
+ delete_url = request.urlgen(
+ 'mediagoblin.user_pages.media_confirm_delete',
+ user=self.test_user.username, media=media_id)
+ # Empty data means don't confirm
+ response = self.do_post({}, do_follow=True, url=delete_url)[0]
+ media = self.check_media(request, {'title': 'Balanced Goblin'}, 1)
+ media_id = media.id
# Confirm deletion
# ---------------------------------------------------
- response = self.test_app.post(
- request.urlgen('mediagoblin.user_pages.media_confirm_delete',
- # No work: user=media.uploader().username,
- user=self.test_user.username,
- media=media._id),
- {'confirm': 'y'})
-
- response.follow()
+ response, request = self.do_post({'confirm': 'y'}, *REQUEST_CONTEXT,
+ do_follow=True, url=delete_url)
+ self.check_media(request, {'_id': media_id}, 0)
+ self.check_comments(request, media_id, 0)
- request = template.TEMPLATE_TEST_CONTEXT[
- 'mediagoblin/user_pages/user.html']['request']
-
- # Does media entry still exist?
- assert_false(
- request.db.MediaEntry.find(
- {'_id': media._id}).count())
-
- # How about the comment?
- assert_false(get_comments())
-
- def test_malicious_uploads(self):
+ def test_evil_file(self):
# Test non-suppoerted file with non-supported extension
# -----------------------------------------------------
+ response, form = self.do_post({'title': 'Malicious Upload 1'},
+ *FORM_CONTEXT,
+ **self.upload_data(EVIL_FILE))
+ assert_equal(len(form.file.errors), 1)
+ assert 'Sorry, I don\'t support that file type :(' == \
+ str(form.file.errors[0])
+
+ def test_sniffing(self):
+ '''
+ Test sniffing mechanism to assert that regular uploads work as intended
+ '''
template.clear_test_template_context()
response = self.test_app.post(
'/submit/', {
- 'title': 'Malicious Upload 1'
+ 'title': 'UNIQUE_TITLE_PLS_DONT_CREATE_OTHER_MEDIA_WITH_THIS_TITLE'
}, upload_files=[(
- 'file', EVIL_FILE)])
+ 'file', GOOD_JPG)])
+
+ response.follow()
+
+ context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/user_pages/user.html']
+
+ request = context['request']
+
+ media = request.db.MediaEntry.find_one({
+ u'title': u'UNIQUE_TITLE_PLS_DONT_CREATE_OTHER_MEDIA_WITH_THIS_TITLE'})
- context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/submit/start.html']
- form = context['submit_form']
- assert re.match(r'^Could not extract any file extension from ".*?"$', str(form.file.errors[0]))
- assert len(form.file.errors) == 1
+ assert media.media_type == 'mediagoblin.media_types.image'
+ def check_false_image(self, title, filename):
# NOTE: The following 2 tests will ultimately fail, but they
# *will* pass the initial form submission step. Instead,
# they'll be caught as failures during the processing step.
+ response, context = self.do_post({'title': title}, do_follow=True,
+ **self.upload_data(filename))
+ self.check_url(response, '/u/{0}/'.format(self.test_user.username))
+ entry = mg_globals.database.MediaEntry.find_one({'title': title})
+ assert_equal(entry.state, 'failed')
+ assert_equal(entry.fail_error, u'mediagoblin.processing:BadMediaFail')
+ def test_evil_jpg(self):
# Test non-supported file with .jpg extension
# -------------------------------------------
- template.clear_test_template_context()
- response = self.test_app.post(
- '/submit/', {
- 'title': 'Malicious Upload 2'
- }, upload_files=[(
- 'file', EVIL_JPG)])
- response.follow()
- assert_equal(
- urlparse.urlsplit(response.location)[2],
- '/u/chris/')
-
- entry = mg_globals.database.MediaEntry.find_one(
- {'title': 'Malicious Upload 2'})
- assert_equal(entry.state, 'failed')
- assert_equal(
- entry.fail_error,
- u'mediagoblin.processing:BadMediaFail')
+ self.check_false_image('Malicious Upload 2', EVIL_JPG)
+ def test_evil_png(self):
# Test non-supported file with .png extension
# -------------------------------------------
- template.clear_test_template_context()
- response = self.test_app.post(
- '/submit/', {
- 'title': 'Malicious Upload 3'
- }, upload_files=[(
- 'file', EVIL_PNG)])
- response.follow()
- assert_equal(
- urlparse.urlsplit(response.location)[2],
- '/u/chris/')
-
- entry = mg_globals.database.MediaEntry.find_one(
- {'title': 'Malicious Upload 3'})
- assert_equal(entry.state, 'failed')
- assert_equal(
- entry.fail_error,
- u'mediagoblin.processing:BadMediaFail')
+ self.check_false_image('Malicious Upload 3', EVIL_PNG)
+
+ def test_processing(self):
+ data = {'title': 'Big Blue'}
+ response, request = self.do_post(data, *REQUEST_CONTEXT, do_follow=True,
+ **self.upload_data(BIG_BLUE))
+ media = self.check_media(request, data, 1)
+ last_size = 1024 ** 3 # Needs to be larger than bigblue.png
+ for key, basename in (('original', 'bigblue.png'),
+ ('medium', 'bigblue.medium.png'),
+ ('thumb', 'bigblue.thumbnail.png')):
+ # Does the processed image have a good filename?
+ filename = resource_filename(
+ 'mediagoblin.tests',
+ os.path.join('test_user_dev/media/public',
+ *media.media_files.get(key, [])))
+ assert_true(filename.endswith('_' + basename))
+ # Is it smaller than the last processed image we looked at?
+ size = os.stat(filename).st_size
+ assert_true(last_size > size)
+ last_size = size
diff --git a/mediagoblin/tests/test_submission/bigblue.png b/mediagoblin/tests/test_submission/bigblue.png
new file mode 100644
index 00000000..2b2c2a44
--- /dev/null
+++ b/mediagoblin/tests/test_submission/bigblue.png
Binary files differ
diff --git a/mediagoblin/tests/test_tags.py b/mediagoblin/tests/test_tags.py
index 79f925aa..bc657660 100644
--- a/mediagoblin/tests/test_tags.py
+++ b/mediagoblin/tests/test_tags.py
@@ -15,7 +15,6 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from mediagoblin.tests.tools import setup_fresh_app
-from mediagoblin import mg_globals
from mediagoblin.tools import text
@setup_fresh_app
diff --git a/mediagoblin/tests/test_workbench.py b/mediagoblin/tests/test_workbench.py
index b5243a9b..04a74653 100644
--- a/mediagoblin/tests/test_workbench.py
+++ b/mediagoblin/tests/test_workbench.py
@@ -17,7 +17,6 @@
import os
import tempfile
-from nose.tools import assert_raises
from mediagoblin import workbench
from mediagoblin.tests.test_storage import get_tmp_filestorage
diff --git a/mediagoblin/tests/tools.py b/mediagoblin/tests/tools.py
index 7cf355b0..5b4e3746 100644
--- a/mediagoblin/tests/tools.py
+++ b/mediagoblin/tests/tools.py
@@ -26,8 +26,11 @@ from mediagoblin.tools import testing
from mediagoblin.init.config import read_mediagoblin_config
from mediagoblin.decorators import _make_safe
from mediagoblin.db.open import setup_connection_and_db_from_config
+from mediagoblin.db.sql.base import Session
from mediagoblin.meddleware import BaseMeddleware
from mediagoblin.auth.lib import bcrypt_gen_password_hash
+from mediagoblin.gmg_commands.dbupdate import run_dbupdate
+from mediagoblin.init.celery import setup_celery_app
MEDIAGOBLIN_TEST_DB_NAME = u'__mediagoblin_tests__'
@@ -125,26 +128,19 @@ def get_test_app(dump_old_app=True):
global_config, validation_result = read_mediagoblin_config(TEST_APP_CONFIG)
app_config = global_config['mediagoblin']
- # Wipe database
- # @@: For now we're dropping collections, but we could also just
- # collection.remove() ?
- connection, db = setup_connection_and_db_from_config(app_config)
- assert db.name == MEDIAGOBLIN_TEST_DB_NAME
-
- collections_to_wipe = [
- collection
- for collection in db.collection_names()
- if not collection.startswith('system.')]
-
- for collection in collections_to_wipe:
- db.drop_collection(collection)
-
- # TODO: Drop and recreate indexes
+ # Run database setup/migrations
+ run_dbupdate(app_config)
# setup app and return
test_app = loadapp(
'config:' + TEST_SERVER_CONFIG)
+ Session.rollback()
+ Session.remove()
+
+ # Re-setup celery
+ setup_celery_app(app_config, global_config)
+
# Insert the TestingMeddleware, which can do some
# sanity checks on every request/response.
# Doing it this way is probably not the cleanest way.
@@ -216,4 +212,11 @@ def fixture_add_user(username = u'chris', password = 'toast',
test_user.save()
+ # Reload
+ test_user = mg_globals.database.User.find_one({'username': username})
+
+ # ... and detach from session:
+ from mediagoblin.db.sql.base import Session
+ Session.expunge(test_user)
+
return test_user
diff --git a/mediagoblin/tools/exif.py b/mediagoblin/tools/exif.py
index de6dd128..448a342e 100644
--- a/mediagoblin/tools/exif.py
+++ b/mediagoblin/tools/exif.py
@@ -32,6 +32,13 @@ USEFUL_TAGS = [
'EXIF UserComment',
]
+def exif_image_needs_rotation(exif_tags):
+ """
+ Returns True if EXIF orientation requires rotation
+ """
+ return 'Image Orientation' in exif_tags \
+ and exif_tags['Image Orientation'].values[0] != 1
+
def exif_fix_image_orientation(im, exif_tags):
"""
Translate any EXIF orientation to raw orientation
diff --git a/mediagoblin/tools/pluginapi.py b/mediagoblin/tools/pluginapi.py
new file mode 100644
index 00000000..74d05def
--- /dev/null
+++ b/mediagoblin/tools/pluginapi.py
@@ -0,0 +1,147 @@
+# 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 <http://www.gnu.org/licenses/>.
+
+"""
+This module implements the plugin api bits and provides the plugin
+base.
+
+Two things about things in this module:
+
+1. they should be excessively well documented because we should pull
+ from this file for the docs
+
+2. they should be well tested
+
+
+How do plugins work?
+====================
+
+Plugins are structured like any Python project. You create a Python package.
+In that package, you define a high-level ``__init__.py`` that either defines
+or imports modules that define classes that inherit from the ``Plugin`` class.
+
+Additionally, you want a LICENSE file that specifies the license and a
+``setup.py`` that specifies the metadata for packaging your plugin. A rough
+file structure could look like this::
+
+ myplugin/
+ |- setup.py # plugin project packaging metadata
+ |- README # holds plugin project information
+ |- LICENSE # holds license information
+ |- myplugin/ # plugin package directory
+ |- __init__.py # imports myplugin.main
+ |- main.py # code for plugin
+
+
+Lifecycle
+=========
+
+1. All the modules listed as subsections of the ``plugins`` section in
+ the config file are imported. This causes any ``Plugin`` subclasses in
+ those modules to be defined and when the classes are defined they get
+ automatically registered with the ``PluginCache``.
+
+2. After all plugin modules are imported, registered plugin classes are
+ instantiated and ``setup_plugin`` is called for each plugin object.
+
+ Plugins can do any setup they need to do in their ``setup_plugin``
+ method.
+"""
+
+import logging
+
+from mediagoblin import mg_globals
+
+
+_log = logging.getLogger(__name__)
+
+
+class PluginCache(object):
+ """Cache of plugin things"""
+ __state = {
+ # list of plugin classes
+ "plugin_classes": [],
+
+ # list of plugin objects
+ "plugin_objects": []
+ }
+
+ def clear(self):
+ """This is only useful for testing."""
+ del self.plugin_classes[:]
+ del self.plugin_objects[:]
+
+ def __init__(self):
+ self.__dict__ = self.__state
+
+ def register_plugin_class(self, plugin_class):
+ """Registers a plugin class"""
+ self.plugin_classes.append(plugin_class)
+
+ def register_plugin_object(self, plugin_obj):
+ """Registers a plugin object"""
+ self.plugin_objects.append(plugin_obj)
+
+
+class MetaPluginClass(type):
+ """Metaclass for PluginBase derivatives"""
+ def __new__(cls, name, bases, attrs):
+ new_class = super(MetaPluginClass, cls).__new__(cls, name, bases, attrs)
+ parents = [b for b in bases if isinstance(b, MetaPluginClass)]
+ if not parents:
+ return new_class
+ PluginCache().register_plugin_class(new_class)
+ return new_class
+
+
+class Plugin(object):
+ """Exttend this class for plugins.
+
+ Example::
+
+ from mediagoblin.tools.pluginapi import Plugin
+
+ class MyPlugin(Plugin):
+ ...
+
+ def setup_plugin(self):
+ ....
+
+ """
+
+ __metaclass__ = MetaPluginClass
+
+ def setup_plugin(self):
+ pass
+
+
+def get_config(key):
+ """Retrieves the configuration for a specified plugin by key
+
+ Example:
+
+ >>> get_config('mediagoblin.plugins.sampleplugin')
+ {'foo': 'bar'}
+ >>> get_config('myplugin')
+ {}
+ >>> get_config('flatpages')
+ {'directory': '/srv/mediagoblin/pages', 'nesting': 1}}
+
+ """
+
+ global_config = mg_globals.global_config
+ plugin_section = global_config.get('plugins', {})
+ return plugin_section.get(key, {})
diff --git a/mediagoblin/user_pages/views.py b/mediagoblin/user_pages/views.py
index d8db8fee..4c5e7e9a 100644
--- a/mediagoblin/user_pages/views.py
+++ b/mediagoblin/user_pages/views.py
@@ -312,7 +312,7 @@ def processing_panel(request):
# Get media entries which are in-processing
processing_entries = request.db.MediaEntry.find(
{'uploader': user._id,
- 'state': 'processing'}).sort('created', DESCENDING)
+ 'state': 'unprocessed'}).sort('created', DESCENDING)
# Get media entries which have failed to process
failed_entries = request.db.MediaEntry.find(
diff --git a/setup.py b/setup.py
index 3e382e56..37f2e19f 100644
--- a/setup.py
+++ b/setup.py
@@ -45,8 +45,6 @@ setup(
'PasteScript',
'beaker',
'routes',
- 'pymongo',
- 'mongokit',
'webob<=1.2a2',
'wtforms',
'py-bcrypt',
@@ -64,7 +62,6 @@ setup(
'Markdown',
'sqlalchemy',
'sqlalchemy-migrate',
- 'kombu-sqlalchemy',
## For now we're expecting that users will install this from
## their package managers.
# 'lxml',