diff options
212 files changed, 15878 insertions, 11315 deletions
@@ -8,10 +8,12 @@ variety of different ways and this software wouldn't exist without them. Thank you! * Aaron Williamson +* Aditi Mittal * Aeva Ntsc * Alejandro Villanueva * Aleksandar Micovic * Aleksej Serdjukov +* Alon Levy * Alex Camelio * András Veres-Szentkirályi * Bassam Kurdali @@ -21,13 +23,17 @@ Thank you! * Corey Farwell * Chris Moylan * Christopher Allan Webber +* David Thompson * Daniel Neel * Deb Nicholson * Derek Moore * Duncan Paterson * Elrond of Samba TNG * Emily O'Leary +* Gabi Thume +* Gabriel Saldana * Greg Grossmeier +* Hans Lo * Jakob Kramer * Jef van Schendel * Jessica Tallon @@ -36,25 +42,34 @@ Thank you! * Jorge Araya Navarro * Karen Rustad * Kuno Woudt +* Laura Arjona * Larisa Hoffenbecker * Luke Slater * Manuel Urbano Santos * Mark Holmquist +* Mats Sjöberg * Matt Lee * Michele Azzolari +* Mike Linksvayer +* Natalie Foust-Pilcher * Nathan Yergler * Odin Hørthe Omdal * Osama Khalid * Pablo J. Urbano Santos +* Praveen Kumar * Rasmus Larsson +* Rodney Ewing * Runar Petursson * Sacha De'Angeli * Sam Kleinman +* Sam Tuke * Sebastian Spaeth * Shawn Khan +* Simon Fondrie-Teitler * Stefano Zacchiroli * Tiberiu C. Turbureanu * Tran Thanh Bao +* Tryggvi Björgvinsson * Shawn Khan * Will Kahn-Greene @@ -64,4 +79,4 @@ If you think your name should be on this list, let us know! We also are currently borrowing an image in mediagoblin/static/images/media_thumbs/image.png from the wonderful people at http://tango.freedesktop.org/ which is in the public -domain... thanks Tango folks!
\ No newline at end of file +domain... thanks Tango folks! @@ -5,21 +5,21 @@ What is GNU MediaGoblin? ======================== -* Initially, a place to store all your photos that’s as awesome as, if - not more awesome than, existing network services (Flickr, SmugMug, - Picasa, etc) +* A place to store all your different media (photos, videos, audios, + and more!) that’s as awesome as, if not more awesome than, existing + network services (Flickr, YouTube, etc) * Customizable! * A place for people to collaborate and show off original and derived creations. Free, as in freedom. We’re a GNU project after all. -* Later, a place for all sorts of media, such as video, music, etc hosting. -* Later, federated with OStatus! +* Extensible: Plugins allow you to add new media types (3d models? + Presentations and documents? Yes, and more!) or extend old ones. +* A real community, and we'd love to have you join us! Is it ready for me to use? ========================== -Yes! But with caveats. The software is usable and there are instances -running, but it's still in its early stages. +Yes! Can I help/hang out/participate/whisper sweet nothings in your ear? diff --git a/docs/source/devel/migrations.rst b/docs/source/devel/migrations.rst new file mode 100644 index 00000000..16c02b04 --- /dev/null +++ b/docs/source/devel/migrations.rst @@ -0,0 +1,62 @@ +.. 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/>. + +========== +Migrations +========== + +So, about migrations. Every time we change the way the database +structure works, we need to add a migration so that people running +older codebases can have their databases updated to the new structure +when they run `./bin/gmg dbupdate`. + +The first time `./bin/gmg dbupdate` is run by a user, it creates the +tables at the current state that they're defined in models.py and sets +the migration number to the current migration... after all, migrations +only exist to get things to the current state of the db. After that, +every migration is run with dbupdate. + +There's a few things you need to know: + +- We use `sqlalchemy-migrate + <http://code.google.com/p/sqlalchemy-migrate/>`_. + See `their docs <https://sqlalchemy-migrate.readthedocs.org/>`_. +- `Alembic <https://bitbucket.org/zzzeek/alembic>`_ might be a better + choice than sqlalchemy-migrate now or in the future, but we + originally decided not to use it because it didn't have sqlite + support. It's not clear if that's changed. +- SQLAlchemy has two parts to it, the ORM and the "core" interface. + We DO NOT use the ORM when running migrations. Think about it: the + ORM is set up with an expectation that the models already reflect a + certain pattern. But if a person is moving from their old patern + and are running tools to *get to* the current pattern, of course + their current database structure doesn't match the state of the ORM! +- How to write migrations? Maybe there will be a tutorial here in the + future... in the meanwhile, look at existing migrations in + `mediagoblin/db/migrations.py` and look in + `mediagoblin/tests/test_sql_migrations.py` for examples. +- Common pattern: use `inspect_table` to get the current state + of the table before we run alterations on it. +- Make sure you set the RegisterMigration to be the next migration in + order. +- What happens if you're adding a *totally new* table? In this case, + you should copy the table in entirety as it exists into + migrations.py then create the tables based off of that... see + add_collection_tables. This is easier than reproducing the SQL by + hand. +- If you're writing a feature branch, you don't need to keep adding + migrations every time you change things around if your database + structure is in flux. Just alter your migrations so that they're + correct for the merge into master. + +That's it for now! Good luck! diff --git a/docs/source/index.rst b/docs/source/index.rst index 7f692d57..de6c9c0d 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -73,6 +73,8 @@ This guide covers writing new GNU MediaGoblin plugins. pluginwriter/quickstart pluginwriter/database pluginwriter/api + pluginwriter/tests + pluginwriter/media_type_hooks Part 4: Developer's Zone @@ -86,6 +88,7 @@ This chapter contains various information for developers. devel/codebase devel/storage devel/originaldesigndecisions + devel/migrations Indices and tables diff --git a/docs/source/pluginwriter/api.rst b/docs/source/pluginwriter/api.rst index df933511..29adb691 100644 --- a/docs/source/pluginwriter/api.rst +++ b/docs/source/pluginwriter/api.rst @@ -11,6 +11,7 @@ Dedication along with this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. +.. _plugin-api-chapter: ========== Plugin API @@ -23,7 +24,27 @@ Authors are encouraged to develop plugins and work with the MediaGoblin community to keep them up to date, but this API will be a moving target for a few releases. -Please check the release notes for updates! +Please check the :ref:`release-notes` for updates! + + +How are hooks added? Where do I find them? +------------------------------------------- + +Much of this document talks about hooks, both as in terms of regular +hooks and template hooks. But where do they come from, and how can +you find a list of them? + +For the moment, the best way to find available hooks is to check the +source code itself. (Yes, we should start a more official hook +listing with descriptions soon.) But many hooks you may need do not +exist yet: what to do then? + +The plan at present is that we are adding hooks as people need them, +with community discussion. If you find that you need a hook and +MediaGoblin at present doesn't provide it at present, please +`http://mediagoblin.org/pages/join.html <talk to us>`_! We'll +evaluate what to do from there. + :mod:`pluginapi` Module ----------------------- @@ -48,3 +69,254 @@ example might look like:: This means that when people enable your plugin in their config you'll be able to provide defaults as well as type validation. +You can access this via the app_config variables in mg_globals, or you +can use a shortcut to get your plugin's config section:: + + >>> from mediagoblin.tools import pluginapi + # Replace with the path to your plugin. + # (If an external package, it won't be part of mediagoblin.plugins) + >>> floobie_config = pluginapi.get_config('mediagoblin.plugins.floobifier') + >>> floobie_dir = floobie_config['floobie_dir'] + # This is the same as the above + >>> from mediagoblin import mg_globals + >>> config = mg_globals.global_config['plugins']['mediagoblin.plugins.floobifier'] + >>> floobie_dir = floobie_config['floobie_dir'] + +A tip: you have access to the `%(here)s` variable in your config, +which is the directory that the user's mediagoblin config is running +out of. So for example, your plugin may need a "floobie" directory to +store floobs in. You could give them a reasonable default that makes +use of the default `user_dev` location, but allow users to override +it, like so:: + + [plugin_spec] + floobie_dir = string(default="%(here)s/user_dev/floobs/") + +Note, this is relative to the user's mediagoblin config directory, +*not* your plugin directory! + + +Context Hooks +------------- + +View specific hooks ++++++++++++++++++++ + +You can hook up to almost any template called by any specific view +fairly easily. As long as the view directly or indirectly uses the +method ``render_to_response`` you can access the context via a hook +that has a key in the format of the tuple:: + + (view_symbolic_name, view_template_path) + +Where the "view symbolic name" is the same parameter used in +``request.urlgen()`` to look up the view. So say we're wanting to add +something to the context of the user's homepage. We look in +mediagoblin/user_pages/routing.py and see:: + + add_route('mediagoblin.user_pages.user_home', + '/u/<string:user>/', + 'mediagoblin.user_pages.views:user_home') + +Aha! That means that the name is ``mediagoblin.user_pages.user_home``. +Okay, so then we look at the view at the +``mediagoblin.user_pages.user_home`` method:: + + @uses_pagination + def user_home(request, page): + # [...] whole bunch of stuff here + return render_to_response( + request, + 'mediagoblin/user_pages/user.html', + {'user': user, + 'user_gallery_url': user_gallery_url, + 'media_entries': media_entries, + 'pagination': pagination}) + +Nice! So the template appears to be +``mediagoblin/user_pages/user.html``. Cool, that means that the key +is:: + + ("mediagoblin.user_pages.user_home", + "mediagoblin/user_pages/user.html") + +The context hook uses ``hook_transform()`` so that means that if we're +hooking into it, our hook will both accept one argument, ``context``, +and should return that modified object, like so:: + + def add_to_user_home_context(context): + context['foo'] = 'bar' + return context + + hooks = { + ("mediagoblin.user_pages.user_home", + "mediagoblin/user_pages/user.html"): add_to_user_home_context} + + +Global context hooks +++++++++++++++++++++ + +If you need to add something to the context of *every* view, it is not +hard; there are two hooks hook that also uses hook_transform (like the +above) but make available what you are providing to *every* view. + +Note that there is a slight, but critical, difference between the two. + +The most general one is the ``'template_global_context'`` hook. This +one is run only once, and is read into the global context... all views +will get access to what are in this dict. + +The slightly more expensive but more powerful one is +``'template_context_prerender'``. This one is not added to the global +context... it is added to the actual context of each individual +template render right before it is run! Because of this you also can +do some powerful and crazy things, such as checking the request object +or other parts of the context before passing them on. + + +Adding static resources +----------------------- + +It's possible to add static resources for your plugin. Say your +plugin needs some special javascript and images... how to provide +them? Then how to access them? MediaGoblin has a way! + + +Attaching to the hook ++++++++++++++++++++++ + +First, you need to register your plugin's resources with the hook. +This is pretty easy actually: you just need to provide a function that +passes back a PluginStatic object. + +.. autoclass:: mediagoblin.tools.staticdirect.PluginStatic + + +Running plugin assetlink +++++++++++++++++++++++++ + +In order for your plugin assets to be properly served by MediaGoblin, +your plugin's asset directory needs to be symlinked into the directory +that plugin assets are served from. To set this up, run:: + + ./bin/gmg assetlink + + +Using staticdirect +++++++++++++++++++ + +Once you have this, you will want to be able to of course link to your +assets! MediaGoblin has a "staticdirect" tool; you want to use this +like so in your templates:: + + staticdirect("css/monkeys.css", "mystaticname") + +Replace "mystaticname" with the name you passed to PluginStatic. The +staticdirect method is, for convenience, attached to the request +object, so you can access this in your templates like: + +.. code-block:: html + + <img alt="A funny bunny" + src="{{ request.staticdirect('images/funnybunny.png', 'mystaticname') }}" /> + + +Additional hook tips +-------------------- + +This section aims to explain some tips in regards to adding hooks to +the MediaGoblin repository. + +WTForms hooks ++++++++++++++ + +We haven't totally settled on a way to tranform wtforms form objects, +but here's one way. In your view:: + + from mediagoblin.foo.forms import SomeForm + + def some_view(request) + form_class = hook_transform('some_form_transform', SomeForm) + form = form_class(request.form) + +Then to hook into this form, do something in your plugin like:: + + import wtforms + + class SomeFormAdditions(wtforms.Form): + new_datefield = wtforms.DateField() + + def transform_some_form(orig_form): + class ModifiedForm(orig_form, SomeFormAdditions) + return ModifiedForm + + hooks = { + 'some_form_transform': transform_some_form} + + +Interfaces +++++++++++ + +If you want to add a pseudo-interface, it's not difficult to do so. +Just write the interface like so:: + + class FrobInterface(object): + """ + Interface for Frobbing. + + Classes implementing this interface should provide defrob and frob. + They may also implement double_frob, but it is not required; if + not provided, we will use a general technique. + """ + + def defrob(self, frobbed_obj): + """ + Take a frobbed_obj and defrob it. Returns the defrobbed object. + """ + raise NotImplementedError() + + def frob(self, normal_obj): + """ + Take a normal object and frob it. Returns the frobbed object. + """ + raise NotImplementedError() + + def double_frob(self, normal_obj): + """ + Frob this object and return it multiplied by two. + """ + return self.frob(normal_obj) * 2 + + + def some_frob_using_method(): + # something something something + frobber = hook_handle(FrobInterface) + frobber.frob(blah) + + # alternately you could have a default + frobber = hook_handle(FrobInterface) or DefaultFrobber + frobber.defrob(foo) + + +It's fine to use your interface as the key instead of a string if you +like. (Usually this is messy, but since interfaces are public and +since you need to import them into your plugin anyway, interfaces +might as well be keys.) + +Then a plugin providing your interface can be like:: + + from mediagoblin.foo.frobfrogs import FrobInterface + from frogfrobber import utils + + class FrogFrobber(FrobInterface): + """ + Takes a frogputer science approach to frobbing. + """ + def defrob(self, frobbed_obj): + return utils.frog_defrob(frobbed_obj) + + def frob(self, normal_obj): + return utils.frog_frob(normal_obj) + + hooks = { + FrobInterface: lambda: return FrogFrobber} diff --git a/docs/source/pluginwriter/database.rst b/docs/source/pluginwriter/database.rst index 58edf3a0..603a19eb 100644 --- a/docs/source/pluginwriter/database.rst +++ b/docs/source/pluginwriter/database.rst @@ -12,9 +12,12 @@ <http://creativecommons.org/publicdomain/zero/1.0/>. -======== -Database -======== +.. _plugin-database-chapter: + + +=========================== +Database models for plugins +=========================== Accessing Existing Data diff --git a/docs/source/pluginwriter/media_type_hooks.rst b/docs/source/pluginwriter/media_type_hooks.rst new file mode 100644 index 00000000..498b0b54 --- /dev/null +++ b/docs/source/pluginwriter/media_type_hooks.rst @@ -0,0 +1,38 @@ +================== + Media Type hooks +================== + +This documents the hooks that are currently available for ``media_type`` plugins. + +What hooks are available? +========================= + +'sniff_handler' +--------------- + +This hook is used by ``sniff_media`` in ``mediagoblin.media_types.__init__``. +Your media type should return its ``sniff_media`` method when this hook is +called. + +.. Note:: + Your ``sniff_media`` method should return either the ``media_type`` or + ``None``. + +'get_media_type_and_manager' +---------------------------- + +This hook is used by ``get_media_type_and_manager`` in +``mediagoblin.media_types.__init__``. When this hook is called, your media type +plugin should check if it can handle the given extension. If so, your media +type plugin should return the media type and media manager. + +('media_manager', MEDIA_TYPE) +----------------------------- + +If you already know the string representing the media type of a type +of media, you can pull down the manager specifically. Note that this +hook is not a string but a tuple of two strings, the latter being the +name of the media type. + +This is used by media entries to pull down their media managers, and +so on. diff --git a/docs/source/pluginwriter/quickstart.rst b/docs/source/pluginwriter/quickstart.rst index b5a63f79..6d45ea36 100644 --- a/docs/source/pluginwriter/quickstart.rst +++ b/docs/source/pluginwriter/quickstart.rst @@ -178,8 +178,10 @@ 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 the documentation on the :ref:`plugin-api-chapter` for code +samples and other things you can use when building your plugin. If +your plugin needs its own database models, see +:ref:`plugin-database-chapter`. See `Hitchhiker's Guide to Packaging <http://guide.python-distribute.org/>`_ for more information on diff --git a/docs/source/pluginwriter/tests.rst b/docs/source/pluginwriter/tests.rst new file mode 100644 index 00000000..fe99688f --- /dev/null +++ b/docs/source/pluginwriter/tests.rst @@ -0,0 +1,64 @@ +.. MediaGoblin Documentation + + Written in 2013 by MediaGoblin contributors + + To the extent possible under law, the author(s) have dedicated all + copyright and related and neighboring rights to this software to + the public domain worldwide. This software is distributed without + any warranty. + + You should have received a copy of the CC0 Public Domain + Dedication along with this software. If not, see + <http://creativecommons.org/publicdomain/zero/1.0/>. + +============================== +Writing unit tests for plugins +============================== + +Here's a brief guide to writing unit tests for plugins. However, it +isn't really ideal. It also hasn't been well tested... yes, there's +some irony there :) + +Some notes: we're using py.test and webtest for unit testing stuff. +Keep that in mind. + +My suggestion is to mime the behavior of `mediagoblin/tests/` and put +that in your own plugin, like `myplugin/tests/`. Copy over +`conftest.py` and `pytest.ini` to your tests directory, but possibly +change the `test_app` fixture to match your own tests' config needs. +For example:: + + import pkg_resources + # [...] + + @pytest.fixture() + def test_app(request): + return get_app( + request, + mgoblin_config=pkg_resources.resource_filename( + 'myplugin.tests', 'myplugin_mediagoblin.ini')) + +In any test module in your tests directory you can then do:: + + def test_somethingorother(test_app): + # real code goes here + pass + +And you'll get a mediagoblin application wrapped in webtest passed in +to your environment. + +If your plugin needs to define multiple configuration setups, you can +actually set up multiple fixtures very easily for this. You can just +set up multiple fixtures with different names that point to different +configs and pass them in as that named argument. + +To run the tests, from mediagoblin's directory (make sure that your +plugin has been added to your mediagoblin checkout's virtualenv!) do:: + + ./runtests.sh /path/to/myplugin/tests/ + +replacing `/path/to/myplugin/` with the actual path to your plugin. + +NOTE: again, the above is untested, but it should probably work. If +you run into trouble, `contact us +<http://mediagoblin.org/pages/join.html>`_, preferably on IRC! diff --git a/docs/source/siteadmin/deploying.rst b/docs/source/siteadmin/deploying.rst index 326d2243..a892bbd4 100644 --- a/docs/source/siteadmin/deploying.rst +++ b/docs/source/siteadmin/deploying.rst @@ -197,13 +197,14 @@ Change to the MediaGoblin directory that you just created:: cd /srv/mediagoblin.example.org -Clone the MediaGoblin repository:: +Clone the MediaGoblin repository and set up the git submodules:: git clone git://gitorious.org/mediagoblin/mediagoblin.git + cd mediagoblin + git submodule init && git submodule update Set up the in-package virtualenv:: - cd mediagoblin (virtualenv --system-site-packages . || virtualenv .) && ./bin/python setup.py develop .. note:: @@ -234,7 +235,7 @@ This concludes the initial configuration of the development environment. In the future, when you update your codebase, you should also run:: - ./bin/python setup.py develop --upgrade && ./bin/gmg dbupdate + ./bin/python setup.py develop --upgrade && ./bin/gmg dbupdate && git submodule fetch Note: If you are running an active site, depending on your server configuration, you may need to stop it first or the dbupdate command @@ -245,6 +246,23 @@ update) Deploy MediaGoblin Services --------------------------- +Edit site configuration +~~~~~~~~~~~~~~~~~~~~~~~ + +A few basic properties must be set before MediaGoblin will work. First +make a copy of ``mediagoblin.ini`` for editing so the original config +file isn't lost:: + + cp mediagoblin.ini mediagoblin_local.ini + +Then: + - Set ``email_sender_address`` to the address you wish to be used as + the sender for system-generated emails + - Edit ``direct_remote_path``, ``base_dir``, and ``base_url`` if + your mediagoblin directory is not the root directory of your + vhost. + + Configure MediaGoblin to use the PostgreSQL database ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -280,11 +298,11 @@ browser to confirm that the service is operable. .. _webserver-config: -Connect the Webserver to MediaGoblin with FastCGI -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -This section describes how to configure MediaGoblin to work via -FastCGI. Our configuration example will use nginx, however, you may +FastCGI and nginx +~~~~~~~~~~~~~~~~~ + +This configuration example will use nginx, however, you may use any webserver of your choice as long as it supports the FastCGI protocol. If you do not already have a web server, consider nginx, as the configuration files may be more clear than the @@ -350,6 +368,11 @@ this ``nginx.conf`` file should be modeled on the following:: alias /srv/mediagoblin.example.org/mediagoblin/user_dev/theme_static/; } + # Plugin static files (usually symlinked in) + location /plugin_static/ { + alias /srv/mediagoblin.example.org/mediagoblin/user_dev/plugin_static/; + } + # Mounting MediaGoblin itself via FastCGI. location / { fastcgi_pass 127.0.0.1:26543; @@ -385,6 +408,13 @@ Visit the site you've set up in your browser by visiting smaller deployments. However, for larger production deployments with larger processing requirements, see the ":doc:`production-deployments`" documentation. + + +Apache +~~~~~~ + +Instructions and scripts for running MediaGoblin on an Apache server +can be found on the `MediaGoblin wiki <http://wiki.mediagoblin.org/Deployment>`_. Security Considerations diff --git a/docs/source/siteadmin/media-types.rst b/docs/source/siteadmin/media-types.rst index 210094b9..3e8a94e9 100644 --- a/docs/source/siteadmin/media-types.rst +++ b/docs/source/siteadmin/media-types.rst @@ -18,16 +18,18 @@ Media Types ==================== In the future, there will be all sorts of media types you can enable, -but in the meanwhile there are three additional media types: video, audio -and ascii art. +but in the meanwhile there are five additional media types: video, audio, +ascii art, STL/3d models, PDF and Document. First, you should probably read ":doc:`configuration`" to make sure you know how to modify the mediagoblin config file. - Enabling Media Types ==================== +.. note:: + Media types are now plugins + Media types are enabled in your mediagoblin configuration file, typically it is created by copying ``mediagoblin.ini`` to ``mediagoblin_local.ini`` and then applying your changes to ``mediagoblin_local.ini``. If you don't already have a @@ -37,11 +39,13 @@ Most media types have additional dependencies that you will have to install. You will find descriptions on how to satisfy the requirements of each media type on this page. -To enable a media type, edit the ``media_types`` list in your -``mediagoblin_local.ini``. For example, if your system supported image and -video media types, then the list would look like this:: +To enable a media type, add the the media type under the ``[plugins]`` section +in you ``mediagoblin_local.ini``. For example, if your system supported image +and video media types, then it would look like this:: - media_types = mediagoblin.media_types.image, mediagoblin.media_types.video + [plugins] + [[mediagoblin.media_types.image]] + [[mediagoblin.media_types.video]] Note that after enabling new media types, you must run dbupdate like so:: @@ -83,8 +87,8 @@ good/bad/ugly). On Debianoid systems gstreamer0.10-ffmpeg -Add ``mediagoblin.media_types.video`` to the ``media_types`` list in your -``mediagoblin_local.ini`` and restart MediaGoblin. +Add ``[[mediagoblin.media_types.video]]`` under the ``[plugins]`` section in +your ``mediagoblin_local.ini`` and restart MediaGoblin. Run @@ -133,7 +137,7 @@ Then install ``scikits.audiolab`` for the spectrograms:: ./bin/pip install scikits.audiolab -Add ``mediagoblin.media_types.audio`` to the ``media_types`` list in your +Add ``[[mediagoblin.media_types.audio]]`` under the ``[plugins]`` section in your ``mediagoblin_local.ini`` and restart MediaGoblin. Run @@ -158,13 +162,8 @@ library, which is necessary for creating thumbnails of ascii art Next, modify (and possibly copy over from ``mediagoblin.ini``) your -``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 +``mediagoblin_local.ini``. In the ``[plugins]`` section, add +``[[mediagoblin.media_types.ascii]]``. Run @@ -184,7 +183,7 @@ your execution path. This feature has been tested with Blender 2.63. It may work on some earlier versions, but that is not guaranteed (and is surely not to work prior to Blender 2.5X). -Add ``mediagoblin.media_types.stl`` to the ``media_types`` list in your +Add ``[[mediagoblin.media_types.stl]]`` under the ``[plugins]`` section in your ``mediagoblin_local.ini`` and restart MediaGoblin. Run @@ -199,8 +198,16 @@ will be able to present them to your wide audience of admirers! PDF and Document ================ -To enable the "PDF and Document" support plugin, you need pdftocairo, pdfinfo, -unoconv with headless support. All executables must be on your execution path. +To enable the "PDF and Document" support plugin, you need: + +1. pdftocairo and pdfinfo for pdf only support. + +2. unoconv with headless support to support converting libreoffice supported + documents as well, such as doc/ppt/xls/odf/odg/odp and more. + For the full list see mediagoblin/media_types/pdf/processing.py, + unoconv_supported. + +All executables must be on your execution path. To install this on Fedora: @@ -208,6 +215,9 @@ To install this on Fedora: sudo yum install -y poppler-utils unoconv libreoffice-headless +Note: You can leave out unoconv and libreoffice-headless if you want only pdf +support. This will result in a much smaller list of dependencies. + pdf.js relies on git submodules, so be sure you have fetched them: .. code-block:: bash @@ -222,7 +232,7 @@ This feature has been tested on Fedora with: It may work on some earlier versions, but that is not guaranteed. -Add ``mediagoblin.media_types.pdf`` to the ``media_types`` list in your +Add ``[[mediagoblin.media_types.pdf]]`` under the ``[plugins]`` section in your ``mediagoblin_local.ini`` and restart MediaGoblin. Run diff --git a/docs/source/siteadmin/production-deployments.rst b/docs/source/siteadmin/production-deployments.rst index 1a32d95e..839d3ce5 100644 --- a/docs/source/siteadmin/production-deployments.rst +++ b/docs/source/siteadmin/production-deployments.rst @@ -22,12 +22,14 @@ MediaGoblin in actual production environments. Consider Deploy with Paste ----------------- -The instance configured with ``./lazyserver.sh`` is not ideal for a -production MediaGoblin deployment. Ideally, you should be able to use -an "init" or "control" script to launch and restart the MediaGoblin +The MediaGoblin WSGI application instance you get with ``./lazyserver.sh`` is +not ideal for a production MediaGoblin deployment. Ideally, you should be able +to use an "init" or "control" script to launch and restart the MediaGoblin process. -Use the following command as the basis for such a script: :: +Use the following command as the basis for such a script: + +.. code-block:: bash CELERY_ALWAYS_EAGER=true \ /srv/mediagoblin.example.org/mediagoblin/bin/paster serve \ @@ -41,7 +43,9 @@ synchronously, and the user will advance to the next page only after processing is complete. If we take Celery out of "always eager mode," the user will be able to immediately return to the MediaGoblin site while processing is ongoing. In these cases, use the following command -as the basis for your script: :: +as the basis for your script: + +.. code-block:: bash CELERY_ALWAYS_EAGER=false \ /srv/mediagoblin.example.org/mediagoblin/bin/paster serve \ @@ -52,30 +56,40 @@ as the basis for your script: :: Separate Celery --------------- -While the ``./lazyserver.sh`` configuration provides an efficient way to -start using a MediaGoblin instance, it is not suitable for production -deployments for several reasons: +MediaGoblin uses `Celery`_ to handle heavy and long-running tasks. Celery can +be launched in two ways: + +1. Embedded in the MediaGoblin WSGI application [#f-mediagoblin-wsgi-app]_. + This is the way ``./lazyserver.sh`` does it for you. It's simple as you + only have to run one process. The only bad thing with this is that the + heavy and long-running tasks will run *in* the webserver, keeping the user + waiting each time some heavy lifting is needed as in for example processing + a video. This could lead to problems as an aborted connection will halt any + processing and since most front-end web servers *will* terminate your + connection if it doesn't get any response from the MediaGoblin WSGI + application in a while. + +2. As a separate process communicating with the MediaGoblin WSGI application + via a `broker`_. This offloads the heavy lifting from the MediaGoblin WSGI + application and users will be able to continue to browse the site while the + media is being processed in the background. + +.. _`broker`: http://docs.celeryproject.org/en/latest/getting-started/brokers/ +.. _`celery`: http://www.celeryproject.org/ + -In nearly every scenario, work on the Celery queue will need to -balance with the demands of other processes, and cannot proceed -synchronously. This is a particularly relevant problem if you use -MediaGoblin to host video content. Processing with Celery ought to be -operationally separate from the MediaGoblin application itself, this -simplifies management and support better workload distribution. +.. [#f-mediagoblin-wsgi-app] The MediaGoblin WSGI application is the part that + of MediaGoblin that processes HTTP requests. -Basically, if you're doing anything beyond a trivial workload, such as -image hosting for a small set of users, or have limited media types -such as "ASCII art" or icon sharing, you will need to run ``celeryd`` -as a separate process. +To launch Celery separately from the MediaGoblin WSGI application: -Build an :ref:`init script <init-script>` around the following -command:: +1. Make sure that the ``CELERY_ALWAYS_EAGER`` environment variable is unset or + set to ``false`` when launching the MediaGoblin WSGI application. +2. Start the ``celeryd`` main process with - CELERY_CONFIG_MODULE=mediagoblin.init.celery.from_celery ./bin/celeryd + .. code-block:: bash -Modify your existing MediaGoblin and application init scripts, if -necessary, to prevent them from starting their own ``celeryd`` -processes. + CELERY_CONFIG_MODULE=mediagoblin.init.celery.from_celery ./bin/celeryd .. _sentry: @@ -102,7 +116,7 @@ These are scripts provided by the MediaGoblin community: Debian * `GNU MediaGoblin init scripts - <https://github.com/jwandborg/mediagoblin-init-scripts>`_ + <https://github.com/joar/mediagoblin-init-scripts>`_ by `Joar Wandborg <http://wandborg.se>`_ Arch Linux diff --git a/docs/source/siteadmin/relnotes.rst b/docs/source/siteadmin/relnotes.rst index 04863ec6..35415b66 100644 --- a/docs/source/siteadmin/relnotes.rst +++ b/docs/source/siteadmin/relnotes.rst @@ -11,6 +11,8 @@ Dedication along with this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. +.. _release-notes: + ============= Release Notes ============= @@ -19,6 +21,82 @@ 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.4.1 +===== + +This is a bugfix release for 0.4.0. This only implements one major +fix in the newly released document support which prevented the +"conversion via libreoffice" feature. + +If you were running 0.4.0 you can upgrade to v0.4.1 via a simple +switch and restarting mediagoblin/celery with no other actions. + +Otherwise, follow 0.4.0 instructions. + + +0.4.0 +===== + +**Do this to upgrade** + +1. Make sure to run + ``./bin/python setup.py develop --upgrade && ./bin/gmg dbupdate`` + after upgrading. +2. See "For Theme authors" if you have a custom theme. +3. Note that ``./bin/gmg theme assetlink`` is now just + ``./bin/gmg assetlink`` and covers both plugins and assets. + Keep on reading to hear more about new plugin features. +4. If you want to take advantage of new plugins that have statically + served assets, you are going to need to add the new "plugin_static" + section to your nginx config. Basically the following for nginx:: + + # Plugin static files (usually symlinked in) + location /plugin_static/ { + alias /srv/mediagoblin.example.org/mediagoblin/user_dev/plugin_static/; + } + + Similarly, if you've got a modified paste config, you may want to + borrow the app:plugin_static section from the default paste.ini + file. +5. We now use itsdangerous for sessions; if you had any references to + beaker in your paste config you can remove them. Again, see the + default paste.ini config +6. We also now use git submodules. Please do: + ``git submodule init && git submodule update`` + You will need to do this to use the new PDF support. + +**For theme authors** + +If you have your own theme or you have any "user modified templates", +please note the following: + +* mediagoblin/bits/ files above-content.html, body-end.html, + body-start.html now are renamed... they have underscores instead of + dashes in the filenames now :) +* There's a new file: ``mediagoblin/bits/frontpage_welcome.html``. + You can easily customize this to give a welcome page appropriate to + your site. + + +**New features** +* PDF media type! +* Improved plugin system. More flexible, better documented, with a + new plugin authoring section of the docs. +* itsdangerous based sessions. No more beaker! +* New, experimental Piwigo-based API. This means you should be able + to use MediaGoblin with something like Shotwell. (Again, a word of + caution: this is *very experimental*!) +* Human readable timestamps, and the option to display the original + date of an image when available (available as the + "original_date_visible" variable) +* Moved unit testing system from nosetests to py.test so we can better + handle issues with sqlalchemy exploding with different database + configurations. Long story :) +* You can now disable the ability to post comments. +* Tags now can be up to length 255 characters by default. + + 0.3.3 ===== diff --git a/docs/source/siteadmin/theming.rst b/docs/source/siteadmin/theming.rst index 98ec6de7..11ae3875 100644 --- a/docs/source/siteadmin/theming.rst +++ b/docs/source/siteadmin/theming.rst @@ -51,7 +51,7 @@ want to install this theme! Don't worry, it's fairly painless. 5. Link the assets so that they can be served by your web server:: - $ ./bin/gmg theme assetlink + $ ./bin/gmg assetlink .. Note:: diff --git a/mediagoblin.ini b/mediagoblin.ini index 4906546a..30dacadf 100644 --- a/mediagoblin.ini +++ b/mediagoblin.ini @@ -11,19 +11,15 @@ email_sender_address = "notice@mediagoblin.example.org" ## Uncomment and change to your DB's appropiate setting. ## Default is a local sqlite db "mediagoblin.db". +## Don't forget to run `./bin/gmg dbupdate` after having changed it. # sql_engine = postgresql:///mediagoblin -# set to false to enable sending notices +# Set to false to enable sending notices email_debug_mode = true # Set to false to disable registrations allow_registration = true -## Uncomment this to turn on video or enable other media types -## You may have to install dependencies, and will have to run ./bin/dbupdate -## See http://docs.mediagoblin.org/siteadmin/media-types.html for details. -# media_types = mediagoblin.media_types.image, mediagoblin.media_types.video - ## Uncomment this to put some user-overriding templates here # local_templates = %(here)s/user_dev/templates/ @@ -43,7 +39,9 @@ base_url = /mgoblin_media/ [celery] # Put celery stuff here -# place plugins here---each in their own subsection of [plugins]. see -# documentation for details. +# Place plugins here, each in their own subsection of [plugins]. +# See http://docs.mediagoblin.org/siteadmin/plugins.html for details. [plugins] [[mediagoblin.plugins.geolocation]] +[[mediagoblin.plugins.basic_auth]] +[[mediagoblin.media_types.image]] diff --git a/mediagoblin/_version.py b/mediagoblin/_version.py index 8437be8b..94629775 100644 --- a/mediagoblin/_version.py +++ b/mediagoblin/_version.py @@ -23,4 +23,4 @@ # see http://www.python.org/dev/peps/pep-0386/ -__version__ = "0.4.0.dev" +__version__ = "0.5.0.dev" diff --git a/mediagoblin/app.py b/mediagoblin/app.py index bf0e0f13..57e09e49 100644 --- a/mediagoblin/app.py +++ b/mediagoblin/app.py @@ -29,6 +29,7 @@ from mediagoblin.tools import common, session, translate, template from mediagoblin.tools.response import render_http_exception from mediagoblin.tools.theme import register_themes from mediagoblin.tools import request as mg_request +from mediagoblin.media_types.tools import media_type_warning from mediagoblin.mg_globals import setup_globals from mediagoblin.init.celery import setup_celery_from_config from mediagoblin.init.plugins import setup_plugins @@ -37,6 +38,8 @@ from mediagoblin.init import (get_jinja_loader, get_staticdirector, setup_storage) from mediagoblin.tools.pluginapi import PluginManager, hook_transform from mediagoblin.tools.crypto import setup_crypto +from mediagoblin.auth.tools import check_auth_enabled, no_auth_logout +from mediagoblin import notifications _log = logging.getLogger(__name__) @@ -67,6 +70,8 @@ class MediaGoblinApp(object): # Open and setup the config global_config, app_config = setup_global_and_app_config(config_path) + media_type_warning() + setup_crypto() ########################################## @@ -85,7 +90,7 @@ class MediaGoblinApp(object): setup_plugins() # Set up the database - self.db = setup_database() + self.db = setup_database(app_config['run_migrations']) # Register themes self.theme_registry, self.current_theme = register_themes(app_config) @@ -97,6 +102,11 @@ class MediaGoblinApp(object): PluginManager().get_template_paths() ) + # Check if authentication plugin is enabled and respond accordingly. + self.auth = check_auth_enabled() + if not self.auth: + app_config['allow_comments'] = False + # Set up storage systems self.public_store, self.queue_store = setup_storage() @@ -186,8 +196,14 @@ class MediaGoblinApp(object): request.urlgen = build_proxy + # Log user out if authentication_disabled + no_auth_logout(request) + + request.notifications = notifications + mg_request.setup_user_in_request(request) + request.controller_name = None try: found_rule, url_values = map_adapter.match(return_rule=True) request.matchdict = url_values @@ -201,6 +217,9 @@ class MediaGoblinApp(object): exc.get_description(environ))(environ, start_response) controller = endpoint_to_controller(found_rule) + # Make a reference to the controller's symbolic name on the request... + # used for lazy context modification + request.controller_name = found_rule.endpoint # pass the request through our meddleware classes try: diff --git a/mediagoblin/auth/__init__.py b/mediagoblin/auth/__init__.py index 621845ba..be5d0eed 100644 --- a/mediagoblin/auth/__init__.py +++ b/mediagoblin/auth/__init__.py @@ -13,3 +13,32 @@ # # 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.tools.pluginapi import hook_handle, hook_runall + + +def get_user(**kwargs): + """ Takes a kwarg such as username and returns a user object """ + return hook_handle("auth_get_user", **kwargs) + + +def create_user(register_form): + results = hook_runall("auth_create_user", register_form) + return results[0] + + +def extra_validation(register_form): + from mediagoblin.auth.tools import basic_extra_validation + + extra_validation_passes = basic_extra_validation(register_form) + if False in hook_runall("auth_extra_validation", register_form): + extra_validation_passes = False + return extra_validation_passes + + +def gen_password_hash(raw_pass, extra_salt=None): + return hook_handle("auth_gen_password_hash", raw_pass, extra_salt) + + +def check_password(raw_pass, stored_hash, extra_salt=None): + return hook_handle("auth_check_password", + raw_pass, stored_hash, extra_salt) diff --git a/mediagoblin/auth/forms.py b/mediagoblin/auth/forms.py index 33e1f45c..865502e9 100644 --- a/mediagoblin/auth/forms.py +++ b/mediagoblin/auth/forms.py @@ -16,61 +16,8 @@ import wtforms -from mediagoblin.tools.mail import normalize_email from mediagoblin.tools.translate import lazy_pass_to_ugettext as _ - -def normalize_user_or_email_field(allow_email=True, allow_user=True): - """Check if we were passed a field that matches a username and/or email pattern - - This is useful for fields that can take either a username or email - address. Use the parameters if you want to only allow a username for - instance""" - message = _(u'Invalid User name or email address.') - nomail_msg = _(u"This field does not take email addresses.") - nouser_msg = _(u"This field requires an email address.") - - def _normalize_field(form, field): - email = u'@' in field.data - if email: # normalize email address casing - if not allow_email: - raise wtforms.ValidationError(nomail_msg) - wtforms.validators.Email()(form, field) - field.data = normalize_email(field.data) - else: # lower case user names - if not allow_user: - raise wtforms.ValidationError(nouser_msg) - wtforms.validators.Length(min=3, max=30)(form, field) - wtforms.validators.Regexp(r'^\w+$')(form, field) - field.data = field.data.lower() - if field.data is None: # should not happen, but be cautious anyway - raise wtforms.ValidationError(message) - return _normalize_field - - -class RegistrationForm(wtforms.Form): - username = wtforms.TextField( - _('Username'), - [wtforms.validators.Required(), - normalize_user_or_email_field(allow_email=False)]) - password = wtforms.PasswordField( - _('Password'), - [wtforms.validators.Required(), - wtforms.validators.Length(min=5, max=1024)]) - email = wtforms.TextField( - _('Email address'), - [wtforms.validators.Required(), - normalize_user_or_email_field(allow_user=False)]) - - -class LoginForm(wtforms.Form): - username = wtforms.TextField( - _('Username or Email'), - [wtforms.validators.Required(), - normalize_user_or_email_field()]) - password = wtforms.PasswordField( - _('Password'), - [wtforms.validators.Required(), - wtforms.validators.Length(min=5, max=1024)]) +from mediagoblin.auth.tools import normalize_user_or_email_field class ForgotPassForm(wtforms.Form): @@ -85,9 +32,6 @@ class ChangePassForm(wtforms.Form): 'Password', [wtforms.validators.Required(), wtforms.validators.Length(min=5, max=1024)]) - userid = wtforms.HiddenField( - '', - [wtforms.validators.Required()]) token = wtforms.HiddenField( '', [wtforms.validators.Required()]) diff --git a/mediagoblin/auth/tools.py b/mediagoblin/auth/tools.py new file mode 100644 index 00000000..579775ff --- /dev/null +++ b/mediagoblin/auth/tools.py @@ -0,0 +1,210 @@ +# 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 wtforms + +from mediagoblin import mg_globals +from mediagoblin.tools.crypto import get_timed_signer_url +from mediagoblin.db.models import User +from mediagoblin.tools.mail import (normalize_email, send_email, + email_debug_message) +from mediagoblin.tools.template import render_template +from mediagoblin.tools.translate import lazy_pass_to_ugettext as _ +from mediagoblin.tools.pluginapi import hook_handle +from mediagoblin import auth + +_log = logging.getLogger(__name__) + + +def normalize_user_or_email_field(allow_email=True, allow_user=True): + """ + Check if we were passed a field that matches a username and/or email + pattern. + + This is useful for fields that can take either a username or email + address. Use the parameters if you want to only allow a username for + instance""" + message = _(u'Invalid User name or email address.') + nomail_msg = _(u"This field does not take email addresses.") + nouser_msg = _(u"This field requires an email address.") + + def _normalize_field(form, field): + email = u'@' in field.data + if email: # normalize email address casing + if not allow_email: + raise wtforms.ValidationError(nomail_msg) + wtforms.validators.Email()(form, field) + field.data = normalize_email(field.data) + else: # lower case user names + if not allow_user: + raise wtforms.ValidationError(nouser_msg) + wtforms.validators.Length(min=3, max=30)(form, field) + wtforms.validators.Regexp(r'^\w+$')(form, field) + field.data = field.data.lower() + if field.data is None: # should not happen, but be cautious anyway + raise wtforms.ValidationError(message) + return _normalize_field + + +EMAIL_VERIFICATION_TEMPLATE = ( + u"{uri}?" + u"token={verification_key}") + + +def send_verification_email(user, request, email=None, + rendered_email=None): + """ + Send the verification email to users to activate their accounts. + + Args: + - user: a user object + - request: the request + """ + if not email: + email = user.email + + if not rendered_email: + verification_key = get_timed_signer_url('mail_verification_token') \ + .dumps(user.id) + rendered_email = render_template( + request, 'mediagoblin/auth/verification_email.txt', + {'username': user.username, + 'verification_url': EMAIL_VERIFICATION_TEMPLATE.format( + uri=request.urlgen('mediagoblin.auth.verify_email', + qualified=True), + verification_key=verification_key)}) + + # TODO: There is no error handling in place + send_email( + mg_globals.app_config['email_sender_address'], + [email], + # TODO + # Due to the distributed nature of GNU MediaGoblin, we should + # find a way to send some additional information about the + # specific GNU MediaGoblin instance in the subject line. For + # example "GNU MediaGoblin @ Wandborg - [...]". + 'GNU MediaGoblin - Verify your email!', + rendered_email) + + +EMAIL_FP_VERIFICATION_TEMPLATE = ( + u"{uri}?" + u"token={fp_verification_key}") + + +def send_fp_verification_email(user, request): + """ + Send the verification email to users to change their password. + + Args: + - user: a user object + - request: the request + """ + fp_verification_key = get_timed_signer_url('mail_verification_token') \ + .dumps(user.id) + + rendered_email = render_template( + request, 'mediagoblin/auth/fp_verification_email.txt', + {'username': user.username, + 'verification_url': EMAIL_FP_VERIFICATION_TEMPLATE.format( + uri=request.urlgen('mediagoblin.auth.verify_forgot_password', + qualified=True), + fp_verification_key=fp_verification_key)}) + + # TODO: There is no error handling in place + send_email( + mg_globals.app_config['email_sender_address'], + [user.email], + 'GNU MediaGoblin - Change forgotten password!', + rendered_email) + + +def basic_extra_validation(register_form, *args): + users_with_username = User.query.filter_by( + username=register_form.username.data).count() + users_with_email = User.query.filter_by( + email=register_form.email.data).count() + + extra_validation_passes = True + + if users_with_username: + register_form.username.errors.append( + _(u'Sorry, a user with that name already exists.')) + extra_validation_passes = False + if users_with_email: + register_form.email.errors.append( + _(u'Sorry, a user with that email address already exists.')) + extra_validation_passes = False + + return extra_validation_passes + + +def register_user(request, register_form): + """ Handle user registration """ + extra_validation_passes = auth.extra_validation(register_form) + + if extra_validation_passes: + # Create the user + user = auth.create_user(register_form) + + # log the user in + request.session['user_id'] = unicode(user.id) + request.session.save() + + # send verification email + email_debug_message(request) + send_verification_email(user, request) + + return user + + return None + + +def check_login_simple(username, password): + user = auth.get_user(username=username) + if not user: + _log.info("User %r not found", username) + hook_handle("auth_fake_login_attempt") + return None + if not auth.check_password(password, user.pw_hash): + _log.warn("Wrong password for %r", username) + return None + _log.info("Logging %r in", username) + return user + + +def check_auth_enabled(): + if not hook_handle('authentication'): + _log.warning('No authentication is enabled') + return False + else: + return True + + +def no_auth_logout(request): + """Log out the user if authentication_disabled, but don't delete the messages""" + if not mg_globals.app.auth and 'user_id' in request.session: + del request.session['user_id'] + request.session.save() + + +def create_basic_user(form): + user = User() + user.username = form.username.data + user.email = form.email.data + user.save() + return user diff --git a/mediagoblin/auth/views.py b/mediagoblin/auth/views.py index dc408911..d54762b0 100644 --- a/mediagoblin/auth/views.py +++ b/mediagoblin/auth/views.py @@ -14,82 +14,43 @@ # 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 -import datetime +from itsdangerous import BadSignature from mediagoblin import messages, mg_globals from mediagoblin.db.models import User +from mediagoblin.tools.crypto import get_timed_signer_url +from mediagoblin.decorators import auth_enabled, allow_registration from mediagoblin.tools.response import render_to_response, redirect, render_404 from mediagoblin.tools.translate import pass_to_ugettext as _ -from mediagoblin.auth import lib as auth_lib +from mediagoblin.tools.mail import email_debug_message +from mediagoblin.tools.pluginapi import hook_handle from mediagoblin.auth import forms as auth_forms -from mediagoblin.auth.lib import send_verification_email, \ - send_fp_verification_email -from sqlalchemy import or_ - -def email_debug_message(request): - """ - If the server is running in email debug mode (which is - the current default), give a debug message to the user - so that they have an idea where to find their email. - """ - if mg_globals.app_config['email_debug_mode']: - # DEBUG message, no need to translate - messages.add_message(request, messages.DEBUG, - u"This instance is running in email debug mode. " - u"The email will be on the console of the server process.") +from mediagoblin.auth.tools import (send_verification_email, register_user, + send_fp_verification_email, + check_login_simple) +from mediagoblin import auth +@allow_registration +@auth_enabled def register(request): """The registration view. Note that usernames will always be lowercased. Email domains are lowercased while the first part remains case-sensitive. """ - # Redirects to indexpage if registrations are disabled - if not mg_globals.app_config["allow_registration"]: - messages.add_message( - request, - messages.WARNING, - _('Sorry, registration is disabled on this instance.')) - return redirect(request, "index") + if 'pass_auth' not in request.template_env.globals: + redirect_name = hook_handle('auth_no_pass_redirect') + return redirect(request, 'mediagoblin.plugins.{0}.register'.format( + redirect_name)) - register_form = auth_forms.RegistrationForm(request.form) + register_form = hook_handle("auth_get_registration_form", request) if request.method == 'POST' and register_form.validate(): # TODO: Make sure the user doesn't exist already - users_with_username = User.query.filter_by(username=register_form.data['username']).count() - users_with_email = User.query.filter_by(email=register_form.data['email']).count() - - extra_validation_passes = True - - if users_with_username: - register_form.username.errors.append( - _(u'Sorry, a user with that name already exists.')) - extra_validation_passes = False - if users_with_email: - register_form.email.errors.append( - _(u'Sorry, a user with that email address already exists.')) - extra_validation_passes = False - - if extra_validation_passes: - # Create the user - user = User() - user.username = register_form.data['username'] - user.email = register_form.data['email'] - user.pw_hash = auth_lib.bcrypt_gen_password_hash( - register_form.password.data) - user.verification_key = unicode(uuid.uuid4()) - user.save() - - # log the user in - request.session['user_id'] = unicode(user.id) - request.session.save() - - # send verification email - email_debug_message(request) - send_verification_email(user, request) + user = register_user(request, register_form) + if user: # redirect the user to their homepage... there will be a # message waiting for them to verify their email return redirect( @@ -99,33 +60,36 @@ def register(request): return render_to_response( request, 'mediagoblin/auth/register.html', - {'register_form': register_form}) + {'register_form': register_form, + 'post_url': request.urlgen('mediagoblin.auth.register')}) +@auth_enabled def login(request): """ MediaGoblin login view. If you provide the POST with 'next', it'll redirect to that view. """ - login_form = auth_forms.LoginForm(request.form) + if 'pass_auth' not in request.template_env.globals: + redirect_name = hook_handle('auth_no_pass_redirect') + return redirect(request, 'mediagoblin.plugins.{0}.login'.format( + redirect_name)) + + login_form = hook_handle("auth_get_login_form", request) login_failed = False if request.method == 'POST': - - username = login_form.data['username'] + username = login_form.username.data if login_form.validate(): - user = User.query.filter( - or_( - User.username == username, - User.email == username, + user = check_login_simple(username, login_form.password.data) - )).first() - - if user and user.check_login(login_form.password.data): + if user: # set up login in session + if login_form.stay_logged_in.data: + request.session['stay_logged_in'] = True request.session['user_id'] = unicode(user.id) request.session.save() @@ -134,10 +98,6 @@ def login(request): else: return redirect(request, "index") - # Some failure during login occured if we are here! - # Prevent detecting who's on this system by testing login - # attempt timings - auth_lib.fake_login_attempt() login_failed = True return render_to_response( @@ -146,6 +106,7 @@ def login(request): {'login_form': login_form, 'next': request.GET.get('next') or request.form.get('next'), 'login_failed': login_failed, + 'post_url': request.urlgen('mediagoblin.auth.login'), 'allow_registration': mg_globals.app_config["allow_registration"]}) @@ -164,16 +125,28 @@ def verify_email(request): you are lucky :) """ # If we don't have userid and token parameters, we can't do anything; 404 - if not 'userid' in request.GET or not 'token' in request.GET: + if not 'token' in request.GET: return render_404(request) - user = User.query.filter_by(id=request.args['userid']).first() + # Catch error if token is faked or expired + try: + token = get_timed_signer_url("mail_verification_token") \ + .loads(request.GET['token'], max_age=10*24*3600) + except BadSignature: + messages.add_message( + request, + messages.ERROR, + _('The verification key or user id is incorrect.')) - if user and user.verification_key == unicode(request.GET['token']): + return redirect( + request, + 'index') + + user = User.query.filter_by(id=int(token)).first() + + if user and user.email_verified is False: user.status = u'active' user.email_verified = True - user.verification_key = None - user.save() messages.add_message( @@ -215,9 +188,6 @@ def resend_activation(request): return redirect(request, "mediagoblin.user_pages.user_home", user=request.user['username']) - request.user.verification_key = unicode(uuid.uuid4()) - request.user.save() - email_debug_message(request) send_verification_email(request.user, request) @@ -237,13 +207,16 @@ def forgot_password(request): Sends an email with an url to renew forgotten password. Use GET querystring parameter 'username' to pre-populate the input field """ + if not 'pass_auth' in request.template_env.globals: + return redirect(request, 'index') + fp_form = auth_forms.ForgotPassForm(request.form, username=request.args.get('username')) if not (request.method == 'POST' and fp_form.validate()): # Either GET request, or invalid form submitted. Display the template return render_to_response(request, - 'mediagoblin/auth/forgot_password.html', {'fp_form': fp_form}) + 'mediagoblin/auth/forgot_password.html', {'fp_form': fp_form,}) # If we are here: method == POST and form is valid. username casing # has been sanitized. Store if a user was found by email. We should @@ -284,11 +257,6 @@ def forgot_password(request): # SUCCESS. Send reminder and return to login page if user: - user.fp_verification_key = unicode(uuid.uuid4()) - user.fp_token_expire = datetime.datetime.now() + \ - datetime.timedelta(days=10) - user.save() - email_debug_message(request) send_fp_verification_email(user, request) @@ -303,31 +271,44 @@ def verify_forgot_password(request): """ # get form data variables, and specifically check for presence of token formdata = _process_for_token(request) - if not formdata['has_userid_and_token']: + if not formdata['has_token']: return render_404(request) - formdata_token = formdata['vars']['token'] - formdata_userid = formdata['vars']['userid'] formdata_vars = formdata['vars'] + # Catch error if token is faked or expired + try: + token = get_timed_signer_url("mail_verification_token") \ + .loads(formdata_vars['token'], max_age=10*24*3600) + except BadSignature: + messages.add_message( + request, + messages.ERROR, + _('The verification key or user id is incorrect.')) + + return redirect( + request, + 'index') + # check if it's a valid user id - user = User.query.filter_by(id=formdata_userid).first() + user = User.query.filter_by(id=int(token)).first() + + # no user in db if not user: - return render_404(request) + messages.add_message( + request, messages.ERROR, + _('The user id is incorrect.')) + return redirect( + request, 'index') - # check if we have a real user and correct token - if ((user and user.fp_verification_key and - user.fp_verification_key == unicode(formdata_token) and - datetime.datetime.now() < user.fp_token_expire - and user.email_verified and user.status == 'active')): + # check if user active and has email verified + if user.email_verified and user.status == 'active': cp_form = auth_forms.ChangePassForm(formdata_vars) if request.method == 'POST' and cp_form.validate(): - user.pw_hash = auth_lib.bcrypt_gen_password_hash( + user.pw_hash = auth.gen_password_hash( cp_form.password.data) - user.fp_verification_key = None - user.fp_token_expire = None user.save() messages.add_message( @@ -339,12 +320,22 @@ def verify_forgot_password(request): return render_to_response( request, 'mediagoblin/auth/change_fp.html', - {'cp_form': cp_form}) + {'cp_form': cp_form,}) - # in case there is a valid id but no user with that id in the db - # or the token expired - else: - return render_404(request) + if not user.email_verified: + messages.add_message( + request, messages.ERROR, + _('You need to verify your email before you can reset your' + ' password.')) + + if not user.status == 'active': + messages.add_message( + request, messages.ERROR, + _('You are no longer an active user. Please contact the system' + ' admin to reactivate your accoutn.')) + + return redirect( + request, 'index') def _process_for_token(request): @@ -362,7 +353,6 @@ def _process_for_token(request): formdata = { 'vars': formdata_vars, - 'has_userid_and_token': - 'userid' in formdata_vars and 'token' in formdata_vars} + 'has_token': 'token' in formdata_vars} return formdata diff --git a/mediagoblin/config_spec.ini b/mediagoblin/config_spec.ini index 2af4adb2..d2ada163 100644 --- a/mediagoblin/config_spec.ini +++ b/mediagoblin/config_spec.ini @@ -5,12 +5,13 @@ html_title = string(default="GNU MediaGoblin") # link to source for this MediaGoblin site source_link = string(default="https://gitorious.org/mediagoblin/mediagoblin") -# Enabled media types -media_types = string_list(default=list("mediagoblin.media_types.image")) - # database stuff sql_engine = string(default="sqlite:///%(here)s/mediagoblin.db") +# This flag is used during testing to allow use of in-memory SQLite +# databases. It is not recommended to be used on a running instance. +run_migrations = boolean(default=False) + # Where temporary files used in processing and etc are kept workbench_path = string(default="%(here)s/user_dev/media/workbench") @@ -22,9 +23,10 @@ direct_remote_path = string(default="/mgoblin_static/") # set to false to enable sending notices email_debug_mode = boolean(default=True) +email_smtp_use_ssl = boolean(default=False) email_sender_address = string(default="notice@mediagoblin.example.org") email_smtp_host = string(default='') -email_smtp_port = integer(default=25) +email_smtp_port = integer(default=0) email_smtp_user = string(default=None) email_smtp_pass = string(default=None) @@ -69,6 +71,10 @@ theme_web_path = string(default="/theme_static/") theme_linked_assets_dir = string(default="%(here)s/user_dev/theme_static/") theme = string() +# plugin default assets directory +plugin_web_path = string(default="/plugin_static/") +plugin_linked_assets_dir = string(default="%(here)s/user_dev/plugin_static/") + [storage:publicstore] storage_class = string(default="mediagoblin.storage.filestorage:BasicFileStorage") @@ -130,7 +136,7 @@ spectrogram_fft_size = integer(default=4096) thumbnail_font = string(default=None) [media_type:mediagoblin.media_types.pdf] -pdf_js = boolean(default=False) +pdf_js = boolean(default=True) [celery] diff --git a/mediagoblin/db/base.py b/mediagoblin/db/base.py index 699a503a..c0cefdc2 100644 --- a/mediagoblin/db/base.py +++ b/mediagoblin/db/base.py @@ -24,18 +24,6 @@ Session = scoped_session(sessionmaker()) class GMGTableBase(object): query = Session.query_property() - @classmethod - def find(cls, query_dict): - return cls.query.filter_by(**query_dict) - - @classmethod - def find_one(cls, query_dict): - return cls.query.filter_by(**query_dict).first() - - @classmethod - def one(cls, query_dict): - return cls.find(query_dict).one() - def get(self, key): return getattr(self, key) diff --git a/mediagoblin/db/migration_tools.py b/mediagoblin/db/migration_tools.py index c0c7e998..aa22ef94 100644 --- a/mediagoblin/db/migration_tools.py +++ b/mediagoblin/db/migration_tools.py @@ -175,8 +175,7 @@ class MigrationManager(object): if self.name == u'__main__': return u"main mediagoblin tables" else: - # TODO: Use the friendlier media manager "human readable" name - return u'media type "%s"' % self.name + return u'plugin "%s"' % self.name def init_or_migrate(self): """ diff --git a/mediagoblin/db/migrations.py b/mediagoblin/db/migrations.py index 2c553396..fe4ffb3e 100644 --- a/mediagoblin/db/migrations.py +++ b/mediagoblin/db/migrations.py @@ -26,7 +26,7 @@ from sqlalchemy.sql import and_ from migrate.changeset.constraint import UniqueConstraint from mediagoblin.db.migration_tools import RegisterMigration, inspect_table -from mediagoblin.db.models import MediaEntry, Collection, User +from mediagoblin.db.models import MediaEntry, Collection, User, MediaComment MIGRATIONS = {} @@ -287,3 +287,95 @@ def unique_collections_slug(db): constraint.create() db.commit() + +@RegisterMigration(11, MIGRATIONS) +def drop_token_related_User_columns(db): + """ + Drop unneeded columns from the User table after switching to using + itsdangerous tokens for email and forgot password verification. + """ + metadata = MetaData(bind=db.bind) + user_table = inspect_table(metadata, 'core__users') + + verification_key = user_table.columns['verification_key'] + fp_verification_key = user_table.columns['fp_verification_key'] + fp_token_expire = user_table.columns['fp_token_expire'] + + verification_key.drop() + fp_verification_key.drop() + fp_token_expire.drop() + + db.commit() + + +class CommentSubscription_v0(declarative_base()): + __tablename__ = 'core__comment_subscriptions' + id = Column(Integer, primary_key=True) + + created = Column(DateTime, nullable=False, default=datetime.datetime.now) + + media_entry_id = Column(Integer, ForeignKey(MediaEntry.id), nullable=False) + + user_id = Column(Integer, ForeignKey(User.id), nullable=False) + + notify = Column(Boolean, nullable=False, default=True) + send_email = Column(Boolean, nullable=False, default=True) + + +class Notification_v0(declarative_base()): + __tablename__ = 'core__notifications' + id = Column(Integer, primary_key=True) + type = Column(Unicode) + + created = Column(DateTime, nullable=False, default=datetime.datetime.now) + + user_id = Column(Integer, ForeignKey(User.id), nullable=False, + index=True) + seen = Column(Boolean, default=lambda: False, index=True) + + +class CommentNotification_v0(Notification_v0): + __tablename__ = 'core__comment_notifications' + id = Column(Integer, ForeignKey(Notification_v0.id), primary_key=True) + + subject_id = Column(Integer, ForeignKey(MediaComment.id)) + + +class ProcessingNotification_v0(Notification_v0): + __tablename__ = 'core__processing_notifications' + + id = Column(Integer, ForeignKey(Notification_v0.id), primary_key=True) + + subject_id = Column(Integer, ForeignKey(MediaEntry.id)) + + +@RegisterMigration(12, MIGRATIONS) +def add_new_notification_tables(db): + metadata = MetaData(bind=db.bind) + + user_table = inspect_table(metadata, 'core__users') + mediaentry_table = inspect_table(metadata, 'core__media_entries') + mediacomment_table = inspect_table(metadata, 'core__media_comments') + + CommentSubscription_v0.__table__.create(db.bind) + + Notification_v0.__table__.create(db.bind) + CommentNotification_v0.__table__.create(db.bind) + ProcessingNotification_v0.__table__.create(db.bind) + + +@RegisterMigration(13, MIGRATIONS) +def pw_hash_nullable(db): + """Make pw_hash column nullable""" + metadata = MetaData(bind=db.bind) + user_table = inspect_table(metadata, "core__users") + + user_table.c.pw_hash.alter(nullable=True) + + # sqlite+sqlalchemy seems to drop this constraint during the + # migration, so we add it back here for now a bit manually. + if db.bind.url.drivername == 'sqlite': + constraint = UniqueConstraint('username', table=user_table) + constraint.create() + + db.commit() diff --git a/mediagoblin/db/mixin.py b/mediagoblin/db/mixin.py index 388bac89..57b27d83 100644 --- a/mediagoblin/db/mixin.py +++ b/mediagoblin/db/mixin.py @@ -28,25 +28,20 @@ real objects. """ import uuid +import re +from datetime import datetime from werkzeug.utils import cached_property from mediagoblin import mg_globals -from mediagoblin.auth import lib as auth_lib -from mediagoblin.media_types import get_media_managers, FileTypeNotSupported +from mediagoblin.media_types import FileTypeNotSupported from mediagoblin.tools import common, licenses +from mediagoblin.tools.pluginapi import hook_handle from mediagoblin.tools.text import cleaned_markdown_conversion from mediagoblin.tools.url import slugify class UserMixin(object): - def check_login(self, password): - """ - See if a user can login with this password - """ - return auth_lib.bcrypt_check_password( - password, self.pw_hash) - @property def bio_html(self): return cleaned_markdown_conversion(self.bio) @@ -208,14 +203,14 @@ class MediaEntryMixin(GenerateSlugMixin): Raises FileTypeNotSupported in case no such manager is enabled """ - # TODO, we should be able to make this a simple lookup rather - # than iterating through all media managers. - for media_type, manager in get_media_managers(): - if media_type == self.media_type: - return manager(self) + manager = hook_handle(('media_manager', self.media_type)) + if manager: + return manager(self) + # Not found? Then raise an error raise FileTypeNotSupported( - "MediaManager not in enabled types. Check media_types in config?") + "MediaManager not in enabled types. Check media_type plugins are" + " enabled in config?") def get_fail_exception(self): """ @@ -229,15 +224,60 @@ class MediaEntryMixin(GenerateSlugMixin): return licenses.get_license_by_url(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 exif_all: + label = re.sub('(.)([A-Z][a-z]+)', r'\1 \2', key) + yield label.replace('EXIF', '').replace('Image', ''), exif_all[key] + + def exif_display_data_short(self): + """Display a very short practical version of exif info""" 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] + exif_short = {} + + if 'Image DateTimeOriginal' in exif_all: + # format date taken + takendate = datetime.datetime.strptime( + exif_all['Image DateTimeOriginal']['printable'], + '%Y:%m:%d %H:%M:%S').date() + taken = takendate.strftime('%B %d %Y') + + exif_short.update({'Date Taken': taken}) + + aperture = None + if 'EXIF FNumber' in exif_all: + fnum = str(exif_all['EXIF FNumber']['printable']).split('/') + + # calculate aperture + if len(fnum) == 2: + aperture = "f/%.1f" % (float(fnum[0])/float(fnum[1])) + elif fnum[0] != 'None': + aperture = "f/%s" % (fnum[0]) + + if aperture: + exif_short.update({'Aperture': aperture}) + + short_keys = [ + ('Camera', 'Image Model', None), + ('Exposure', 'EXIF ExposureTime', lambda x: '%s sec' % x), + ('ISO Speed', 'EXIF ISOSpeedRatings', None), + ('Focal Length', 'EXIF FocalLength', lambda x: '%s mm' % x)] + + for label, key, fmt_func in short_keys: + try: + val = fmt_func(exif_all[key]['printable']) if fmt_func \ + else exif_all[key]['printable'] + exif_short.update({label: val}) + except KeyError: + pass + + return exif_short class MediaCommentMixin(object): @@ -249,6 +289,13 @@ class MediaCommentMixin(object): """ return cleaned_markdown_conversion(self.content) + def __repr__(self): + return '<{klass} #{id} {author} "{comment}">'.format( + klass=self.__class__.__name__, + id=self.id, + author=self.get_author, + comment=self.content) + class CollectionMixin(GenerateSlugMixin): def check_slug_used(self, slug): diff --git a/mediagoblin/db/models.py b/mediagoblin/db/models.py index 2412706e..826d47ba 100644 --- a/mediagoblin/db/models.py +++ b/mediagoblin/db/models.py @@ -24,15 +24,17 @@ import datetime from sqlalchemy import Column, Integer, Unicode, UnicodeText, DateTime, \ Boolean, ForeignKey, UniqueConstraint, PrimaryKeyConstraint, \ SmallInteger -from sqlalchemy.orm import relationship, backref +from sqlalchemy.orm import relationship, backref, with_polymorphic from sqlalchemy.orm.collections import attribute_mapped_collection from sqlalchemy.sql.expression import desc from sqlalchemy.ext.associationproxy import association_proxy from sqlalchemy.util import memoized_property + from mediagoblin.db.extratypes import PathTupleWithSlashes, JSONEncoded from mediagoblin.db.base import Base, DictReadAttrProxy -from mediagoblin.db.mixin import UserMixin, MediaEntryMixin, MediaCommentMixin, CollectionMixin, CollectionItemMixin +from mediagoblin.db.mixin import UserMixin, MediaEntryMixin, \ + MediaCommentMixin, CollectionMixin, CollectionItemMixin from mediagoblin.tools.files import delete_media_files from mediagoblin.tools.common import import_component @@ -55,21 +57,22 @@ class User(Base, UserMixin): id = Column(Integer, primary_key=True) username = Column(Unicode, nullable=False, unique=True) + # Note: no db uniqueness constraint on email because it's not + # reliable (many email systems case insensitive despite against + # the RFC) and because it would be a mess to implement at this + # point. email = Column(Unicode, nullable=False) - created = Column(DateTime, nullable=False, default=datetime.datetime.now) - pw_hash = Column(Unicode, nullable=False) + pw_hash = Column(Unicode) email_verified = Column(Boolean, default=False) + created = Column(DateTime, nullable=False, default=datetime.datetime.now) status = Column(Unicode, default=u"needs_email_verification", nullable=False) # Intented to be nullable=False, but migrations would not work for it # set to nullable=True implicitly. wants_comment_notification = Column(Boolean, default=True) license_preference = Column(Unicode) - verification_key = Column(Unicode) is_admin = Column(Boolean, default=False, nullable=False) url = Column(Unicode) bio = Column(UnicodeText) # ?? - fp_verification_key = Column(Unicode) - fp_token_expire = Column(DateTime) ## TODO # plugin data would be in a separate model @@ -388,6 +391,10 @@ class MediaComment(Base, MediaCommentMixin): backref=backref("posted_comments", lazy="dynamic", cascade="all, delete-orphan")) + get_entry = relationship(MediaEntry, + backref=backref("comments", + lazy="dynamic", + cascade="all, delete-orphan")) # Cascade: Comments are somewhat owned by their MediaEntry. # So do the full thing. @@ -480,9 +487,103 @@ class ProcessingMetaData(Base): return DictReadAttrProxy(self) +class CommentSubscription(Base): + __tablename__ = 'core__comment_subscriptions' + id = Column(Integer, primary_key=True) + + created = Column(DateTime, nullable=False, default=datetime.datetime.now) + + media_entry_id = Column(Integer, ForeignKey(MediaEntry.id), nullable=False) + media_entry = relationship(MediaEntry, + backref=backref('comment_subscriptions', + cascade='all, delete-orphan')) + + user_id = Column(Integer, ForeignKey(User.id), nullable=False) + user = relationship(User, + backref=backref('comment_subscriptions', + cascade='all, delete-orphan')) + + notify = Column(Boolean, nullable=False, default=True) + send_email = Column(Boolean, nullable=False, default=True) + + def __repr__(self): + return ('<{classname} #{id}: {user} {media} notify: ' + '{notify} email: {email}>').format( + id=self.id, + classname=self.__class__.__name__, + user=self.user, + media=self.media_entry, + notify=self.notify, + email=self.send_email) + + +class Notification(Base): + __tablename__ = 'core__notifications' + id = Column(Integer, primary_key=True) + type = Column(Unicode) + + created = Column(DateTime, nullable=False, default=datetime.datetime.now) + + user_id = Column(Integer, ForeignKey('core__users.id'), nullable=False, + index=True) + seen = Column(Boolean, default=lambda: False, index=True) + user = relationship( + User, + backref=backref('notifications', cascade='all, delete-orphan')) + + __mapper_args__ = { + 'polymorphic_identity': 'notification', + 'polymorphic_on': type + } + + def __repr__(self): + return '<{klass} #{id}: {user}: {subject} ({seen})>'.format( + id=self.id, + klass=self.__class__.__name__, + user=self.user, + subject=getattr(self, 'subject', None), + seen='unseen' if not self.seen else 'seen') + + +class CommentNotification(Notification): + __tablename__ = 'core__comment_notifications' + id = Column(Integer, ForeignKey(Notification.id), primary_key=True) + + subject_id = Column(Integer, ForeignKey(MediaComment.id)) + subject = relationship( + MediaComment, + backref=backref('comment_notifications', cascade='all, delete-orphan')) + + __mapper_args__ = { + 'polymorphic_identity': 'comment_notification' + } + + +class ProcessingNotification(Notification): + __tablename__ = 'core__processing_notifications' + + id = Column(Integer, ForeignKey(Notification.id), primary_key=True) + + subject_id = Column(Integer, ForeignKey(MediaEntry.id)) + subject = relationship( + MediaEntry, + backref=backref('processing_notifications', + cascade='all, delete-orphan')) + + __mapper_args__ = { + 'polymorphic_identity': 'processing_notification' + } + + +with_polymorphic( + Notification, + [ProcessingNotification, CommentNotification]) + MODELS = [ - User, MediaEntry, Tag, MediaTag, MediaComment, Collection, CollectionItem, MediaFile, FileKeynames, - MediaAttachmentFile, ProcessingMetaData] + User, MediaEntry, Tag, MediaTag, MediaComment, Collection, CollectionItem, + MediaFile, FileKeynames, MediaAttachmentFile, ProcessingMetaData, + Notification, CommentNotification, ProcessingNotification, + CommentSubscription] ###################################################### diff --git a/mediagoblin/db/models_v0.py b/mediagoblin/db/models_v0.py index ec51a1f5..bdedec2e 100644 --- a/mediagoblin/db/models_v0.py +++ b/mediagoblin/db/models_v0.py @@ -18,6 +18,29 @@ TODO: indexes on foreignkeys, where useful. """ +########################################################################### +# WHAT IS THIS FILE? +# ------------------ +# +# Upon occasion, someone runs into this file and wonders why we have +# both a models.py and a models_v0.py. +# +# The short of it is: you can ignore this file. +# +# The long version is, in two parts: +# +# - We used to use MongoDB, then we switched to SQL and SQLAlchemy. +# We needed to convert peoples' databases; the script we had would +# switch them to the first version right after Mongo, convert over +# all their tables, then run any migrations that were added after. +# +# - That script is now removed, but there is some discussion of +# writing a test that would set us at the first SQL migration and +# run everything after. If we wrote that, this file would still be +# useful. But for now, it's legacy! +# +########################################################################### + import datetime import sys diff --git a/mediagoblin/db/open.py b/mediagoblin/db/open.py index 0b1679fb..4ff0945f 100644 --- a/mediagoblin/db/open.py +++ b/mediagoblin/db/open.py @@ -52,10 +52,6 @@ class DatabaseMaster(object): def load_models(app_config): import mediagoblin.db.models - for media_type in app_config['media_types']: - _log.debug("Loading %s.models", media_type) - __import__(media_type + ".models") - for plugin in mg_globals.global_config.get('plugins', {}).keys(): _log.debug("Loading %s.models", plugin) try: diff --git a/mediagoblin/db/util.py b/mediagoblin/db/util.py index 6ffec44d..8431361a 100644 --- a/mediagoblin/db/util.py +++ b/mediagoblin/db/util.py @@ -24,7 +24,7 @@ from mediagoblin.db.models import MediaEntry, Tag, MediaTag, Collection def atomic_update(table, query_dict, update_values): - table.find(query_dict).update(update_values, + table.query.filter_by(**query_dict).update(update_values, synchronize_session=False) Session.commit() diff --git a/mediagoblin/decorators.py b/mediagoblin/decorators.py index f3535fcf..ca7be53c 100644 --- a/mediagoblin/decorators.py +++ b/mediagoblin/decorators.py @@ -18,11 +18,12 @@ from functools import wraps from urlparse import urljoin from werkzeug.exceptions import Forbidden, NotFound -from werkzeug.urls import url_quote from mediagoblin import mg_globals as mgg +from mediagoblin import messages from mediagoblin.db.models import MediaEntry, User from mediagoblin.tools.response import redirect, render_404 +from mediagoblin.tools.translate import pass_to_ugettext as _ def require_active_login(controller): @@ -86,8 +87,8 @@ def user_may_alter_collection(controller): """ @wraps(controller) def wrapper(request, *args, **kwargs): - creator_id = request.db.User.find_one( - {'username': request.matchdict['user']}).id + creator_id = request.db.User.query.filter_by( + username=request.matchdict['user']).first().id if not (request.user.is_admin or request.user.id == creator_id): raise Forbidden() @@ -161,15 +162,15 @@ def get_user_collection(controller): """ @wraps(controller) def wrapper(request, *args, **kwargs): - user = request.db.User.find_one( - {'username': request.matchdict['user']}) + user = request.db.User.query.filter_by( + username=request.matchdict['user']).first() if not user: return render_404(request) - collection = request.db.Collection.find_one( - {'slug': request.matchdict['collection'], - 'creator': user.id}) + collection = request.db.Collection.query.filter_by( + slug=request.matchdict['collection'], + creator=user.id).first() # Still no collection? Okay, 404. if not collection: @@ -186,14 +187,14 @@ def get_user_collection_item(controller): """ @wraps(controller) def wrapper(request, *args, **kwargs): - user = request.db.User.find_one( - {'username': request.matchdict['user']}) + user = request.db.User.query.filter_by( + username=request.matchdict['user']).first() if not user: return render_404(request) - collection_item = request.db.CollectionItem.find_one( - {'id': request.matchdict['collection_item'] }) + collection_item = request.db.CollectionItem.query.filter_by( + id=request.matchdict['collection_item']).first() # Still no collection item? Okay, 404. if not collection_item: @@ -235,3 +236,35 @@ def get_workbench(func): return func(*args, workbench=workbench, **kwargs) return new_func + + +def allow_registration(controller): + """ Decorator for if registration is enabled""" + @wraps(controller) + def wrapper(request, *args, **kwargs): + if not mgg.app_config["allow_registration"]: + messages.add_message( + request, + messages.WARNING, + _('Sorry, registration is disabled on this instance.')) + return redirect(request, "index") + + return controller(request, *args, **kwargs) + + return wrapper + + +def auth_enabled(controller): + """Decorator for if an auth plugin is enabled""" + @wraps(controller) + def wrapper(request, *args, **kwargs): + if not mgg.app.auth: + messages.add_message( + request, + messages.WARNING, + _('Sorry, authentication is disabled on this instance.')) + return redirect(request, 'index') + + return controller(request, *args, **kwargs) + + return wrapper diff --git a/mediagoblin/edit/forms.py b/mediagoblin/edit/forms.py index ef270237..85c243a0 100644 --- a/mediagoblin/edit/forms.py +++ b/mediagoblin/edit/forms.py @@ -16,9 +16,11 @@ import wtforms -from mediagoblin.tools.text import tag_length_validator, TOO_LONG_TAG_WARNING +from mediagoblin.tools.text import tag_length_validator from mediagoblin.tools.translate import lazy_pass_to_ugettext as _ from mediagoblin.tools.licenses import licenses_as_choices +from mediagoblin.auth.forms import normalize_user_or_email_field + class EditForm(wtforms.Form): title = wtforms.TextField( @@ -59,17 +61,12 @@ class EditProfileForm(wtforms.Form): class EditAccountForm(wtforms.Form): - old_password = wtforms.PasswordField( - _('Old password'), - description=_( - "Enter your old password to prove you own this account.")) - new_password = wtforms.PasswordField( - _('New password'), - [ - wtforms.validators.Optional(), - wtforms.validators.Length(min=6, max=30) - ], - id="password") + new_email = wtforms.TextField( + _('New email address'), + [wtforms.validators.Optional(), + normalize_user_or_email_field(allow_user=False)]) + wants_comment_notification = wtforms.BooleanField( + description=_("Email me when others comment on my media")) license_preference = wtforms.SelectField( _('License preference'), [ @@ -78,8 +75,6 @@ class EditAccountForm(wtforms.Form): ], choices=licenses_as_choices(), description=_('This will be your default license on upload forms.')) - wants_comment_notification = wtforms.BooleanField( - label=_("Email me when others comment on my media")) class EditAttachmentsForm(wtforms.Form): @@ -103,3 +98,16 @@ class EditCollectionForm(wtforms.Form): description=_( "The title part of this collection's address. " "You usually don't need to change this.")) + + +class ChangePassForm(wtforms.Form): + old_password = wtforms.PasswordField( + _('Old password'), + [wtforms.validators.Required()], + description=_( + "Enter your old password to prove you own this account.")) + new_password = wtforms.PasswordField( + _('New password'), + [wtforms.validators.Required(), + wtforms.validators.Length(min=6, max=30)], + id="password") diff --git a/mediagoblin/edit/routing.py b/mediagoblin/edit/routing.py index 035a766f..3592f708 100644 --- a/mediagoblin/edit/routing.py +++ b/mediagoblin/edit/routing.py @@ -24,3 +24,7 @@ add_route('mediagoblin.edit.account', '/edit/account/', 'mediagoblin.edit.views:edit_account') add_route('mediagoblin.edit.delete_account', '/edit/account/delete/', 'mediagoblin.edit.views:delete_account') +add_route('mediagoblin.edit.pass', '/edit/password/', + 'mediagoblin.edit.views:change_pass') +add_route('mediagoblin.edit.verify_email', '/edit/verify_email/', + 'mediagoblin.edit.views:verify_email') diff --git a/mediagoblin/edit/views.py b/mediagoblin/edit/views.py index bfcf65b5..6aa2acd9 100644 --- a/mediagoblin/edit/views.py +++ b/mediagoblin/edit/views.py @@ -16,25 +16,31 @@ from datetime import datetime +from itsdangerous import BadSignature from werkzeug.exceptions import Forbidden from werkzeug.utils import secure_filename from mediagoblin import messages from mediagoblin import mg_globals -from mediagoblin.auth import lib as auth_lib +from mediagoblin import auth +from mediagoblin.auth import tools as auth_tools from mediagoblin.edit import forms from mediagoblin.edit.lib import may_edit_media from mediagoblin.decorators import (require_active_login, active_user_from_url, - get_media_entry_by_id, - user_may_alter_collection, get_user_collection) -from mediagoblin.tools.response import render_to_response, \ - redirect, redirect_obj + get_media_entry_by_id, user_may_alter_collection, + get_user_collection) +from mediagoblin.tools.crypto import get_timed_signer_url +from mediagoblin.tools.mail import email_debug_message +from mediagoblin.tools.response import (render_to_response, + redirect, redirect_obj, render_404) from mediagoblin.tools.translate import pass_to_ugettext as _ +from mediagoblin.tools.template import render_template from mediagoblin.tools.text import ( convert_to_tag_list_of_dicts, media_tags_as_string) from mediagoblin.tools.url import slugify from mediagoblin.db.util import check_media_slug_used, check_collection_slug_used +from mediagoblin.db.models import User import mimetypes @@ -212,6 +218,10 @@ def edit_profile(request, url_user=None): {'user': user, 'form': form}) +EMAIL_VERIFICATION_TEMPLATE = ( + u'{uri}?' + u'token={verification_key}') + @require_active_login def edit_account(request): @@ -220,39 +230,22 @@ def edit_account(request): wants_comment_notification=user.wants_comment_notification, license_preference=user.license_preference) - if request.method == 'POST': - form_validated = form.validate() - - if form_validated and \ - form.wants_comment_notification.validate(form): - user.wants_comment_notification = \ - form.wants_comment_notification.data - - if form_validated and \ - form.new_password.data or form.old_password.data: - password_matches = auth_lib.bcrypt_check_password( - form.old_password.data, - user.pw_hash) - if password_matches: - #the entire form validates and the password matches - user.pw_hash = auth_lib.bcrypt_gen_password_hash( - form.new_password.data) - else: - form.old_password.errors.append(_('Wrong password')) + if request.method == 'POST' and form.validate(): + user.wants_comment_notification = form.wants_comment_notification.data + + user.license_preference = form.license_preference.data - if form_validated and \ - form.license_preference.validate(form): - user.license_preference = \ - form.license_preference.data + if form.new_email.data: + _update_email(request, form, user) - if form_validated and not form.errors: + if not form.errors: user.save() messages.add_message(request, - messages.SUCCESS, - _("Account settings saved")) + messages.SUCCESS, + _("Account settings saved")) return redirect(request, - 'mediagoblin.user_pages.user_home', - user=user.username) + 'mediagoblin.user_pages.user_home', + user=user.username) return render_to_response( request, @@ -312,9 +305,9 @@ def edit_collection(request, collection): form.slug.data, collection.id) # Make sure there isn't already a Collection with this title - existing_collection = request.db.Collection.find_one({ - 'creator': request.user.id, - 'title':form.title.data}) + existing_collection = request.db.Collection.query.filter_by( + creator=request.user.id, + title=form.title.data).first() if existing_collection and existing_collection.id != collection.id: messages.add_message( @@ -345,3 +338,117 @@ def edit_collection(request, collection): 'mediagoblin/edit/edit_collection.html', {'collection': collection, 'form': form}) + + +@require_active_login +def change_pass(request): + # If no password authentication, no need to change your password + if 'pass_auth' not in request.template_env.globals: + return redirect(request, 'index') + + form = forms.ChangePassForm(request.form) + user = request.user + + if request.method == 'POST' and form.validate(): + + if not auth.check_password( + form.old_password.data, user.pw_hash): + form.old_password.errors.append( + _('Wrong password')) + + return render_to_response( + request, + 'mediagoblin/edit/change_pass.html', + {'form': form, + 'user': user}) + + # Password matches + user.pw_hash = auth.gen_password_hash( + form.new_password.data) + user.save() + + messages.add_message( + request, messages.SUCCESS, + _('Your password was changed successfully')) + + return redirect(request, 'mediagoblin.edit.account') + + return render_to_response( + request, + 'mediagoblin/edit/change_pass.html', + {'form': form, + 'user': user}) + + +def verify_email(request): + """ + Email verification view for changing email address + """ + # If no token, we can't do anything + if not 'token' in request.GET: + return render_404(request) + + # Catch error if token is faked or expired + token = None + try: + token = get_timed_signer_url("mail_verification_token") \ + .loads(request.GET['token'], max_age=10*24*3600) + except BadSignature: + messages.add_message( + request, + messages.ERROR, + _('The verification key or user id is incorrect.')) + + return redirect( + request, + 'index') + + user = User.query.filter_by(id=int(token['user'])).first() + + if user: + user.email = token['email'] + user.save() + + messages.add_message( + request, + messages.SUCCESS, + _('Your email address has been verified.')) + + else: + messages.add_message( + request, + messages.ERROR, + _('The verification key or user id is incorrect.')) + + return redirect( + request, 'mediagoblin.user_pages.user_home', + user=user.username) + + +def _update_email(request, form, user): + new_email = form.new_email.data + users_with_email = User.query.filter_by( + email=new_email).count() + + if users_with_email: + form.new_email.errors.append( + _('Sorry, a user with that email address' + ' already exists.')) + + elif not users_with_email: + verification_key = get_timed_signer_url( + 'mail_verification_token').dumps({ + 'user': user.id, + 'email': new_email}) + + rendered_email = render_template( + request, 'mediagoblin/edit/verification.txt', + {'username': user.username, + 'verification_url': EMAIL_VERIFICATION_TEMPLATE.format( + uri=request.urlgen('mediagoblin.edit.verify_email', + qualified=True), + verification_key=verification_key)}) + + email_debug_message(request) + auth_tools.send_verification_email(user, request, new_email, + rendered_email) diff --git a/mediagoblin/gmg_commands/__init__.py b/mediagoblin/gmg_commands/__init__.py index 6aed4f6c..d8156126 100644 --- a/mediagoblin/gmg_commands/__init__.py +++ b/mediagoblin/gmg_commands/__init__.py @@ -41,11 +41,15 @@ SUBCOMMAND_MAP = { 'setup': 'mediagoblin.gmg_commands.dbupdate:dbupdate_parse_setup', 'func': 'mediagoblin.gmg_commands.dbupdate:dbupdate', 'help': 'Set up or update the SQL database'}, - 'theme': { - 'setup': 'mediagoblin.gmg_commands.theme:theme_parser_setup', - 'func': 'mediagoblin.gmg_commands.theme:theme', - 'help': 'Theming commands', - } + 'assetlink': { + 'setup': 'mediagoblin.gmg_commands.assetlink:assetlink_parser_setup', + 'func': 'mediagoblin.gmg_commands.assetlink:assetlink', + 'help': 'Link assets for themes and plugins for static serving'}, + # 'theme': { + # 'setup': 'mediagoblin.gmg_commands.theme:theme_parser_setup', + # 'func': 'mediagoblin.gmg_commands.theme:theme', + # 'help': 'Theming commands', + # } ## These might be useful, mayyyybe, but don't really work anymore ## due to mongo change and the "versatility" of sql options. diff --git a/mediagoblin/gmg_commands/assetlink.py b/mediagoblin/gmg_commands/assetlink.py new file mode 100644 index 00000000..148ebe9e --- /dev/null +++ b/mediagoblin/gmg_commands/assetlink.py @@ -0,0 +1,151 @@ +# 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 os + +from mediagoblin import mg_globals +from mediagoblin.init import setup_global_and_app_config +from mediagoblin.gmg_commands import util as commands_util +from mediagoblin.tools.theme import register_themes +from mediagoblin.tools.translate import pass_to_ugettext as _ +from mediagoblin.tools.common import simple_printer +from mediagoblin.tools import pluginapi + + +def assetlink_parser_setup(subparser): + # theme_subparsers = subparser.add_subparsers( + # dest=u"subcommand", + # help=u'Assetlink options') + + # # Install command + # install_parser = theme_subparsers.add_parser( + # u'install', help=u'Install a theme to this mediagoblin instance') + # install_parser.add_argument( + # u'themefile', help=u'The theme archive to be installed') + + # theme_subparsers.add_parser( + # u'assetlink', + # help=( + # u"Link the currently installed theme's assets " + # u"to the served theme asset directory")) + pass + + +########### +# Utilities +########### + +def link_theme_assets(theme, link_dir, printer=simple_printer): + """ + Returns a list of string of text telling the user what we did + which should be printable. + """ + link_dir = link_dir.rstrip(os.path.sep) + link_parent_dir = os.path.dirname(link_dir) + + if theme is None: + printer(_("Cannot link theme... no theme set\n")) + return + + def _maybe_unlink_link_dir(): + """unlink link directory if it exists""" + if os.path.lexists(link_dir) \ + and os.path.islink(link_dir): + os.unlink(link_dir) + return True + + return + + if theme.get('assets_dir') is None: + printer(_("No asset directory for this theme\n")) + if _maybe_unlink_link_dir(): + printer( + _("However, old link directory symlink found; removed.\n")) + return + + _maybe_unlink_link_dir() + + # make the link directory parent dirs if necessary + if not os.path.lexists(link_parent_dir): + os.makedirs(link_parent_dir) + + os.symlink( + theme['assets_dir'].rstrip(os.path.sep), + link_dir) + printer("Linked the theme's asset directory:\n %s\nto:\n %s\n" % ( + theme['assets_dir'], link_dir)) + + +def link_plugin_assets(plugin_static, plugins_link_dir, printer=simple_printer): + """ + Arguments: + - plugin_static: a mediagoblin.tools.staticdirect.PluginStatic instance + representing the static assets of this plugins' configuration + - plugins_link_dir: Base directory plugins are linked from + """ + # link_dir is the final directory we'll link to, a combination of + # the plugin assetlink directory and plugin_static.name + link_dir = os.path.join( + plugins_link_dir.rstrip(os.path.sep), plugin_static.name) + + # make the link directory parent dirs if necessary + if not os.path.lexists(plugins_link_dir): + os.makedirs(plugins_link_dir) + + # See if the link_dir already exists. + if os.path.lexists(link_dir): + # if this isn't a symlink, there's something wrong... error out. + if not os.path.islink(link_dir): + printer(_('Could not link "%s": %s exists and is not a symlink\n') % ( + plugin_static.name, link_dir)) + return + + # if this is a symlink and the path already exists, skip it. + if os.path.realpath(link_dir) == plugin_static.file_path: + # Is this comment helpful or not? + printer(_('Skipping "%s"; already set up.\n') % ( + plugin_static.name)) + return + + # Otherwise, it's a link that went to something else... unlink it + printer(_('Old link found for "%s"; removing.\n') % ( + plugin_static.name)) + os.unlink(link_dir) + + os.symlink( + plugin_static.file_path.rstrip(os.path.sep), + link_dir) + printer('Linked asset directory for plugin "%s":\n %s\nto:\n %s\n' % ( + plugin_static.name, + plugin_static.file_path.rstrip(os.path.sep), + link_dir)) + + +def assetlink(args): + """ + Link the asset directory of the currently installed theme and plugins + """ + mgoblin_app = commands_util.setup_app(args) + app_config = mg_globals.app_config + + # link theme + link_theme_assets(mgoblin_app.current_theme, app_config['theme_linked_assets_dir']) + + # link plugin assets + ## ... probably for this we need the whole application initialized + for plugin_static in pluginapi.hook_runall("static_setup"): + link_plugin_assets( + plugin_static, app_config['plugin_linked_assets_dir']) diff --git a/mediagoblin/gmg_commands/dbupdate.py b/mediagoblin/gmg_commands/dbupdate.py index 32700c40..00007567 100644 --- a/mediagoblin/gmg_commands/dbupdate.py +++ b/mediagoblin/gmg_commands/dbupdate.py @@ -42,7 +42,7 @@ class DatabaseData(object): self.name, self.models, self.migrations, session) -def gather_database_data(media_types, plugins): +def gather_database_data(plugins): """ Gather all database data relevant to the extensions we have installed so we can do migrations and table initialization. @@ -59,13 +59,6 @@ def gather_database_data(media_types, plugins): DatabaseData( u'__main__', MAIN_MODELS, MAIN_MIGRATIONS)) - # Then get all registered media managers (eventually, plugins) - for media_type in media_types: - models = import_component('%s.models:MODELS' % media_type) - migrations = import_component('%s.migrations:MIGRATIONS' % media_type) - managed_dbdata.append( - DatabaseData(media_type, models, migrations)) - for plugin in plugins: try: models = import_component('{0}.models:MODELS'.format(plugin)) @@ -78,6 +71,7 @@ def gather_database_data(media_types, plugins): except AttributeError as exc: _log.warning('Could not find MODELS in {0}.models, have you \ forgotten to add it? ({1})'.format(plugin, exc)) + models = [] try: migrations = import_component('{0}.migrations:MIGRATIONS'.format( @@ -91,6 +85,7 @@ forgotten to add it? ({1})'.format(plugin, exc)) except AttributeError as exc: _log.debug('Cloud not find MIGRATIONS in {0}.migrations, have you \ forgotten to add it? ({1})'.format(plugin, exc)) + migrations = {} if models: managed_dbdata.append( @@ -108,14 +103,25 @@ def run_dbupdate(app_config, global_config): in the future, plugins) """ + # Set up the database + db = setup_connection_and_db_from_config(app_config, migrations=True) + #Run the migrations + run_all_migrations(db, app_config, global_config) + + +def run_all_migrations(db, app_config, global_config): + """ + Initializes or migrates a database that already has a + connection setup and also initializes or migrates all + extensions based on the config files. + + It can be used to initialize an in-memory database for + testing. + """ # Gather information from all media managers / projects dbdatas = gather_database_data( - app_config['media_types'], global_config.get('plugins', {}).keys()) - # Set up the database - db = setup_connection_and_db_from_config(app_config, migrations=True) - Session = sessionmaker(bind=db.engine) # Setup media managers for all dbdata, run init/migrate and print info diff --git a/mediagoblin/gmg_commands/import_export.py b/mediagoblin/gmg_commands/import_export.py index d51a1e3e..98ec617d 100644 --- a/mediagoblin/gmg_commands/import_export.py +++ b/mediagoblin/gmg_commands/import_export.py @@ -63,7 +63,7 @@ def _import_media(db, args): # TODO: Add import of queue files queue_cache = BasicFileStorage(args._cache_path['queue']) - for entry in db.MediaEntry.find(): + for entry in db.MediaEntry.query.filter_by(): for name, path in entry.media_files.items(): _log.info('Importing: {0} - {1}'.format( entry.title.encode('ascii', 'replace'), @@ -204,7 +204,7 @@ def _export_media(db, args): # TODO: Add export of queue files queue_cache = BasicFileStorage(args._cache_path['queue']) - for entry in db.MediaEntry.find(): + for entry in db.MediaEntry.query.filter_by(): for name, path in entry.media_files.items(): _log.info(u'Exporting {0} - {1}'.format( entry.title, diff --git a/mediagoblin/gmg_commands/theme.py b/mediagoblin/gmg_commands/theme.py deleted file mode 100644 index 71abb982..00000000 --- a/mediagoblin/gmg_commands/theme.py +++ /dev/null @@ -1,122 +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 os - -from mediagoblin.init import setup_global_and_app_config -from mediagoblin.tools.theme import register_themes -from mediagoblin.tools.translate import pass_to_ugettext as _ -from mediagoblin.tools.common import simple_printer - - -def theme_parser_setup(subparser): - theme_subparsers = subparser.add_subparsers( - dest=u"subcommand", - help=u'Theme sub-commands') - - # Install command - install_parser = theme_subparsers.add_parser( - u'install', help=u'Install a theme to this mediagoblin instance') - install_parser.add_argument( - u'themefile', help=u'The theme archive to be installed') - - theme_subparsers.add_parser( - u'assetlink', - help=( - u"Link the currently installed theme's assets " - u"to the served theme asset directory")) - - -########### -# Utilities -########### - -def link_assets(theme, link_dir, printer=simple_printer): - """ - Returns a list of string of text telling the user what we did - which should be printable. - """ - link_dir = link_dir.rstrip(os.path.sep) - link_parent_dir = os.path.dirname(link_dir) - - results = [] - - if theme is None: - printer(_("Cannot link theme... no theme set\n")) - return results - - def _maybe_unlink_link_dir(): - """unlink link directory if it exists""" - if os.path.lexists(link_dir) \ - and os.path.islink(link_dir): - os.unlink(link_dir) - return True - - return results - - if theme.get('assets_dir') is None: - printer(_("No asset directory for this theme\n")) - if _maybe_unlink_link_dir(): - printer( - _("However, old link directory symlink found; removed.\n")) - return results - - _maybe_unlink_link_dir() - - # make the link directory parent dirs if necessary - if not os.path.lexists(link_parent_dir): - os.makedirs(link_parent_dir) - - os.symlink( - theme['assets_dir'].rstrip(os.path.sep), - link_dir) - printer("Linked the theme's asset directory:\n %s\nto:\n %s\n" % ( - theme['assets_dir'], link_dir)) - - -def install_theme(install_dir, themefile): - pass # TODO ;) - - -############# -# Subcommands -############# - -def assetlink_command(args): - """ - Link the asset directory of the currently installed theme - """ - global_config, app_config = setup_global_and_app_config(args.conf_file) - theme_registry, current_theme = register_themes(app_config) - link_assets(current_theme, app_config['theme_linked_assets_dir']) - - -def install_command(args): - """ - Handle the 'install this theme' subcommand - """ - global_config, app_config = setup_global_and_app_config(args.conf_file) - install_dir = app_config['theme_install_dir'] - install_theme(install_dir, args.themefile) - - -SUBCOMMANDS = { - 'assetlink': assetlink_command, - 'install': install_command} - - -def theme(args): - SUBCOMMANDS[args.subcommand](args) diff --git a/mediagoblin/gmg_commands/users.py b/mediagoblin/gmg_commands/users.py index 024c8498..e44b0aa9 100644 --- a/mediagoblin/gmg_commands/users.py +++ b/mediagoblin/gmg_commands/users.py @@ -15,7 +15,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. from mediagoblin.gmg_commands import util as commands_util -from mediagoblin.auth import lib as auth_lib +from mediagoblin import auth from mediagoblin import mg_globals def adduser_parser_setup(subparser): @@ -40,9 +40,9 @@ def adduser(args): db = mg_globals.database users_with_username = \ - db.User.find({ - 'username': args.username.lower(), - }).count() + db.User.query.filter_by( + username=args.username.lower() + ).count() if users_with_username: print u'Sorry, a user with that name already exists.' @@ -52,7 +52,7 @@ def adduser(args): entry = db.User() entry.username = unicode(args.username.lower()) entry.email = unicode(args.email) - entry.pw_hash = auth_lib.bcrypt_gen_password_hash(args.password) + entry.pw_hash = auth.gen_password_hash(args.password) entry.status = u'active' entry.email_verified = True entry.save() @@ -71,7 +71,8 @@ def makeadmin(args): db = mg_globals.database - user = db.User.one({'username': unicode(args.username.lower())}) + user = db.User.query.filter_by( + username=unicode(args.username.lower())).one() if user: user.is_admin = True user.save() @@ -94,9 +95,10 @@ def changepw(args): db = mg_globals.database - user = db.User.one({'username': unicode(args.username.lower())}) + user = db.User.query.filter_by( + username=unicode(args.username.lower())).one() if user: - user.pw_hash = auth_lib.bcrypt_gen_password_hash(args.password) + user.pw_hash = auth.gen_password_hash(args.password) user.save() print 'Password successfully changed' else: diff --git a/mediagoblin/i18n/ar/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/ar/LC_MESSAGES/mediagoblin.mo Binary files differindex 5e69858e..543830c8 100644 --- a/mediagoblin/i18n/ar/LC_MESSAGES/mediagoblin.mo +++ b/mediagoblin/i18n/ar/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/ar/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/ar/LC_MESSAGES/mediagoblin.po index 51c71c3a..1f086613 100644 --- a/mediagoblin/i18n/ar/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/ar/LC_MESSAGES/mediagoblin.po @@ -3,18 +3,19 @@ # This file is distributed under the same license as the PROJECT project. # # Translators: -# Majid Al-Dharrab <majid@aldharrab.com>, 2011. -# Mena Rezk Eid <minaeid90@gmail.com>, 2013. -# <Omar.w.kh@gmail.com>, 2011. -# <osamak@gnu.org>, 2011. +# Jiyda <jiydam@gmail.com>, 2013 +# Majid Al-Dharrab <majid@aldharrab.com>, 2011 +# minaeid90 <minaeid90@gmail.com>, 2013 +# OmarKH <Omar.w.kh@gmail.com>, 2011 +# OsamaK <osamak@gnu.org>, 2011 msgid "" msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" -"POT-Creation-Date: 2013-03-04 18:04-0600\n" -"PO-Revision-Date: 2013-03-05 00:04+0000\n" +"POT-Creation-Date: 2013-05-27 13:54-0500\n" +"PO-Revision-Date: 2013-05-27 18:54+0000\n" "Last-Translator: cwebber <cwebber@dustycloud.org>\n" -"Language-Team: LANGUAGE <LL@li.org>\n" +"Language-Team: Arabic (http://www.transifex.com/projects/p/mediagoblin/language/ar/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -22,34 +23,39 @@ 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/auth/forms.py:28 -msgid "Invalid User name or email address." -msgstr "" - -#: mediagoblin/auth/forms.py:29 -msgid "This field does not take email addresses." -msgstr "" - -#: mediagoblin/auth/forms.py:30 -msgid "This field requires an email address." -msgstr "" - -#: mediagoblin/auth/forms.py:52 mediagoblin/auth/forms.py:67 +#: mediagoblin/auth/forms.py:26 msgid "Username" msgstr "اسم المستخدم" -#: mediagoblin/auth/forms.py:56 mediagoblin/auth/forms.py:71 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 +#: mediagoblin/tests/test_util.py:110 msgid "Password" msgstr "كلمة السر" -#: mediagoblin/auth/forms.py:60 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "عنوان البريد الإلكتروني" -#: mediagoblin/auth/forms.py:78 -msgid "Username or email" +#: mediagoblin/auth/forms.py:41 +msgid "Username or Email" msgstr "" +#: mediagoblin/auth/forms.py:52 +msgid "Username or email" +msgstr "اسم المستخدم او الايميل" + +#: mediagoblin/auth/tools.py:31 +msgid "Invalid User name or email address." +msgstr "اسم مستخدم او ايميل غير صØÙŠØ." + +#: mediagoblin/auth/tools.py:32 +msgid "This field does not take email addresses." +msgstr "هذا الØÙ‚Ù„ لا يأخذ ايميل." + +#: mediagoblin/auth/tools.py:33 +msgid "This field requires an email address." +msgstr "هذا الØÙ‚Ù„ ÙŠØØªØ§Ø¬ ايميل." + #: mediagoblin/auth/views.py:54 msgid "Sorry, registration is disabled on this instance." msgstr "عÙوًا، التسجيل غير Ù…ØªØ§Ø Ù‡Ù†Ø§." @@ -60,56 +66,56 @@ msgstr "عذرًا، لقد اختار مستخدم آخر هذا الاسم." #: mediagoblin/auth/views.py:72 msgid "Sorry, a user with that email address already exists." -msgstr "" +msgstr "عذرًا، لقد اختار مستخدم آخر هذا الايميل." -#: mediagoblin/auth/views.py:174 +#: 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:180 +#: mediagoblin/auth/views.py:188 msgid "The verification key or user id is incorrect" msgstr "Ù…ÙØªØ§Ø التØÙ‚Ù‚ أو معر٠المستخدم خاطئ" -#: mediagoblin/auth/views.py:198 +#: 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:206 +#: mediagoblin/auth/views.py:214 msgid "You've already verified your email address!" msgstr "لقد قمت Ø¨Ø§Ù„ÙØ¹Ù„ بالتØÙ‚Ù‚ من عنوان البريد الإلكتروني الخاص بك!" -#: mediagoblin/auth/views.py:219 +#: mediagoblin/auth/views.py:227 msgid "Resent your verification email." msgstr "أعدنا إرسال رسالة التØÙ‚Ù‚." -#: mediagoblin/auth/views.py:250 +#: mediagoblin/auth/views.py:258 msgid "" "If that email address (case sensitive!) is registered an email has been sent" " with instructions on how to change your password." -msgstr "" +msgstr "إذا كان هذا الايميل(ØØ³Ø§Ø³ Ù„Ù„ØØ±ÙˆÙ الكبيرة والصغيرة!) Ù…ÙØ³Ø¬Ù„, Ùقد تم إرسال ايميل به تعليمات عن كيÙية تغيير رقمك السري." -#: mediagoblin/auth/views.py:261 +#: mediagoblin/auth/views.py:269 msgid "Couldn't find someone with that username." -msgstr "" +msgstr "لم نتمكن من العثور على Ø£ØØ¯ له أسم المستخدم هذا." -#: mediagoblin/auth/views.py:264 +#: mediagoblin/auth/views.py:272 msgid "" "An email has been sent with instructions on how to change your password." -msgstr "" +msgstr "لقد تم إرسال ايميل به تعليمات عن كيÙية تغيير رقمك السري." -#: mediagoblin/auth/views.py:271 +#: mediagoblin/auth/views.py:279 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." msgstr "تعذر إرسال رسالة استعادة كلمة السر لأن اسم المستخدم معطل أو لأننا لم نتØÙ‚Ù‚ من بريدك الإلكتروني." -#: mediagoblin/auth/views.py:328 +#: mediagoblin/auth/views.py:336 msgid "You can now log in using your new password." -msgstr "" +msgstr "تستطيع الآن الدخول باستخدام رقمك السري الجديد." -#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:93 +#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:82 #: mediagoblin/submit/forms.py:28 mediagoblin/submit/forms.py:47 #: mediagoblin/user_pages/forms.py:45 msgid "Title" @@ -120,13 +126,13 @@ msgid "Description of this work" msgstr "وص٠هذا العمل." #: mediagoblin/edit/forms.py:29 mediagoblin/edit/forms.py:52 -#: mediagoblin/edit/forms.py:97 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:86 mediagoblin/submit/forms.py:32 #: mediagoblin/submit/forms.py:51 mediagoblin/user_pages/forms.py:49 msgid "" "You can use\n" " <a href=\"http://daringfireball.net/projects/markdown/basics\">\n" " Markdown</a> for formatting." -msgstr "" +msgstr "بامكانك استخدام âŽ\n<a href=\"http://daringfireball.net/projects/markdown/basics\">âŽ\nMarkdown</a> للإدراج." #: mediagoblin/edit/forms.py:33 mediagoblin/submit/forms.py:36 msgid "Tags" @@ -134,13 +140,13 @@ msgstr "الوسوم" #: mediagoblin/edit/forms.py:35 mediagoblin/submit/forms.py:38 msgid "Separate tags by commas." -msgstr "" +msgstr "قم Ø¨ÙØµÙ„ Ø§Ù„Ù…ØØ¯Ø¯Ø§Øª Ø¨ÙØµÙ„Ø©." -#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:101 +#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:90 msgid "Slug" msgstr "المسار" -#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:102 +#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:91 msgid "The slug can't be empty" msgstr "لا يمكن ترك المسار ÙØ§Ø±ØºÙ‹Ø§" @@ -148,12 +154,12 @@ msgstr "لا يمكن ترك المسار ÙØ§Ø±ØºÙ‹Ø§" msgid "" "The title part of this media's address. You usually don't need to change " "this." -msgstr "" +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" @@ -165,48 +171,48 @@ msgstr "الموقع الإلكتروني" #: mediagoblin/edit/forms.py:58 msgid "This address contains errors" -msgstr "" +msgstr "العنوان ÙŠØØªÙˆÙŠ Ø¹Ù„Ù‰ اخطاء" #: mediagoblin/edit/forms.py:63 -msgid "Old password" -msgstr "" - -#: mediagoblin/edit/forms.py:64 -msgid "Enter your old password to prove you own this account." -msgstr "" - -#: mediagoblin/edit/forms.py:67 -msgid "New password" -msgstr "" - -#: mediagoblin/edit/forms.py:74 msgid "License preference" -msgstr "" +msgstr "ØªÙØ¶ÙŠÙ„ رخصة" -#: mediagoblin/edit/forms.py:80 +#: mediagoblin/edit/forms.py:69 msgid "This will be your default license on upload forms." -msgstr "" +msgstr "سو٠تكون هذه رخصتك المبدئية ÙÙŠ نماذج التØÙ…يل." -#: mediagoblin/edit/forms.py:82 +#: mediagoblin/edit/forms.py:71 msgid "Email me when others comment on my media" -msgstr "" +msgstr "ارسل لي رسالة عندما يقوم الاخرون بالتعليق على الميديا خاصتي" -#: mediagoblin/edit/forms.py:94 +#: mediagoblin/edit/forms.py:83 msgid "The title can't be empty" -msgstr "" +msgstr "لا يمكن ترك العنوان ÙØ§Ø±ØºÙ‹Ø§" -#: mediagoblin/edit/forms.py:96 mediagoblin/submit/forms.py:50 +#: mediagoblin/edit/forms.py:85 mediagoblin/submit/forms.py:50 #: mediagoblin/user_pages/forms.py:48 msgid "Description of this collection" -msgstr "" +msgstr "وص٠هذه المجموعة" -#: mediagoblin/edit/forms.py:103 +#: mediagoblin/edit/forms.py:92 msgid "" "The title part of this collection's address. You usually don't need to " "change this." -msgstr "" +msgstr "مقدمة عنوان هذه المجموعة, غالبا لن ØªØØªØ§Ø¬ لتغيره." + +#: mediagoblin/edit/forms.py:99 +msgid "Old password" +msgstr " كلمة السر القديمة" -#: mediagoblin/edit/views.py:66 +#: mediagoblin/edit/forms.py:101 +msgid "Enter your old password to prove you own this account." +msgstr "قم بإدخال رقمك السري القديم ØØªÙ‰ تثبت انك ØµØ§ØØ¨ هذا Ø§Ù„ØØ³Ø§Ø¨." + +#: mediagoblin/edit/forms.py:104 +msgid "New password" +msgstr "رقم سري جديد" + +#: mediagoblin/edit/views.py:67 msgid "An entry with that slug already exists for this user." msgstr "يوجد مل٠آخر بهذا المسار لدى هذى المستخدم." @@ -217,11 +223,11 @@ msgstr "أنت ØªØØ±Ù‘ر وسائط مستخدم آخر. كن ØØ°Ø±Ù‹Ø§ أثن #: mediagoblin/edit/views.py:155 #, python-format msgid "You added the attachment %s!" -msgstr "" +msgstr "لقد قمت Ø¨Ø¥Ø¶Ø§ÙØ© مرÙقة %s!" #: mediagoblin/edit/views.py:182 msgid "You can only edit your own profile." -msgstr "" +msgstr "يمكنك Ùقط تعديل ØØ³Ø§Ø¨Ùƒ الخاص" #: mediagoblin/edit/views.py:188 msgid "You are editing a user's profile. Proceed with caution." @@ -229,44 +235,63 @@ msgstr "أنت ØªØØ±Ù‘ر مل٠مستخدم آخر. كن ØØ°Ø±Ù‹Ø§ أثناء #: mediagoblin/edit/views.py:204 msgid "Profile changes saved" -msgstr "" +msgstr "تم ØÙظ تغيرات ØØ³Ø§Ø¨Ùƒ" -#: mediagoblin/edit/views.py:241 -msgid "Wrong password" -msgstr "كلمة سر خاطئة" - -#: mediagoblin/edit/views.py:252 +#: mediagoblin/edit/views.py:240 msgid "Account settings saved" -msgstr "" +msgstr "تم ØÙظ خصائص ØØ³Ø§Ø¨Ùƒ" -#: mediagoblin/edit/views.py:286 +#: mediagoblin/edit/views.py:274 msgid "You need to confirm the deletion of your account." -msgstr "" +msgstr "يجب عليك تأكيد إلغاء ØØ³Ø§Ø¨Ùƒ." -#: mediagoblin/edit/views.py:322 mediagoblin/submit/views.py:142 -#: mediagoblin/user_pages/views.py:214 +#: mediagoblin/edit/views.py:310 mediagoblin/submit/views.py:138 +#: mediagoblin/user_pages/views.py:222 #, python-format msgid "You already have a collection called \"%s\"!" -msgstr "" +msgstr "أنت لديك مجموعة تدعى \"%s\"!" -#: mediagoblin/edit/views.py:326 +#: mediagoblin/edit/views.py:314 msgid "A collection with that slug already exists for this user." -msgstr "" +msgstr "توجد مجموعة اخرى بهذا المسار لهذا المستخدم." -#: mediagoblin/edit/views.py:343 +#: mediagoblin/edit/views.py:329 msgid "You are editing another user's collection. Proceed with caution." +msgstr "أنت تعدل مجموعة مستخدم آخر. كن ØØ°Ø±Ù‹Ø§ أثناء العملية." + +#: mediagoblin/edit/views.py:348 +msgid "Wrong password" +msgstr "كلمة سر خاطئة" + +#: mediagoblin/edit/views.py:363 +msgid "Your password was changed successfully" msgstr "" -#: mediagoblin/gmg_commands/theme.py:58 +#: mediagoblin/gmg_commands/assetlink.py:60 msgid "Cannot link theme... no theme set\n" -msgstr "" +msgstr "لم يتم ربط الثيم... لاتوجد مجموعة ثيمات\n" -#: mediagoblin/gmg_commands/theme.py:71 +#: mediagoblin/gmg_commands/assetlink.py:73 msgid "No asset directory for this theme\n" -msgstr "" +msgstr "لا يوجد مسار جيد لهذا الثيم\n" -#: mediagoblin/gmg_commands/theme.py:74 +#: mediagoblin/gmg_commands/assetlink.py:76 msgid "However, old link directory symlink found; removed.\n" +msgstr "ولكن, الرابط القديم للمسار الذي تم ايجاده; ØÙذÙ.\n" + +#: mediagoblin/gmg_commands/assetlink.py:112 +#, python-format +msgid "Could not link \"%s\": %s exists and is not a symlink\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:119 +#, python-format +msgid "Skipping \"%s\"; already set up.\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:124 +#, python-format +msgid "Old link found for \"%s\"; removing.\n" msgstr "" #: mediagoblin/meddleware/csrf.py:134 @@ -274,55 +299,59 @@ msgid "" "CSRF cookie not present. This is most likely the result of a cookie blocker " "or somesuch.<br/>Make sure to permit the settings of cookies for this " "domain." -msgstr "" +msgstr "CSRF كوكيز غير موجودة, وهذا من الممكن ان يكون نتيجة لمانع الكوكيز او شئ من هذا القبيل.<br/>تأكد من أنك قمت Ø¨Ø§Ù„Ø³Ù…Ø§Ø Ù„Ø®ØµØ§Ø¦Øµ الكوكيز لهذا الميدان." -#: mediagoblin/media_types/__init__.py:61 -#: mediagoblin/media_types/__init__.py:102 +#: mediagoblin/media_types/__init__.py:111 +#: mediagoblin/media_types/__init__.py:155 msgid "Sorry, I don't support that file type :(" +msgstr "عذرا, انا لا ادعم هذا النوع من Ø§Ù„Ù…Ù„ÙØ§Øª :(" + +#: mediagoblin/media_types/pdf/processing.py:136 +msgid "unoconv failing to run, check log file" msgstr "" -#: mediagoblin/media_types/video/processing.py:36 +#: mediagoblin/media_types/video/processing.py:37 msgid "Video transcoding failed" -msgstr "" +msgstr "ÙØ´Ù„ ÙÙŠ تØÙˆÙŠÙ„ الÙيديو" #: mediagoblin/plugins/geolocation/templates/mediagoblin/plugins/geolocation/map.html:24 msgid "Location" -msgstr "" +msgstr "المكان" #: mediagoblin/plugins/geolocation/templates/mediagoblin/plugins/geolocation/map.html:52 #, python-format msgid "View on <a href=\"%(osm_url)s\">OpenStreetMap</a>" -msgstr "" +msgstr "عرض ÙÙŠ <a href=\"%(osm_url)s\">OpenStreetMap</a>" #: mediagoblin/plugins/oauth/forms.py:29 msgid "Allow" -msgstr "" +msgstr "سماØ" #: mediagoblin/plugins/oauth/forms.py:30 msgid "Deny" -msgstr "" +msgstr "Ø±ÙØ¶" #: mediagoblin/plugins/oauth/forms.py:34 msgid "Name" -msgstr "" +msgstr "الاسم" #: mediagoblin/plugins/oauth/forms.py:35 msgid "The name of the OAuth client" -msgstr "" +msgstr "اسم العميل Ø§Ù„Ù…Ù†Ø´ÙØ¦" #: mediagoblin/plugins/oauth/forms.py:36 msgid "Description" -msgstr "" +msgstr "الوصÙ" #: mediagoblin/plugins/oauth/forms.py:38 msgid "" "This will be visible to users allowing your\n" " application to authenticate as them." -msgstr "" +msgstr "سو٠يكون هذا مرئي بالنسبة للمستخدمين ØØªÙ‰ يتاØ\nللبرنامج خاصتك بالتصديق عليهم." #: mediagoblin/plugins/oauth/forms.py:40 msgid "Type" -msgstr "" +msgstr "النوع" #: mediagoblin/plugins/oauth/forms.py:45 msgid "" @@ -332,88 +361,88 @@ msgid "" " <strong>Public</strong> - The client can't make confidential\n" " requests to the GNU MediaGoblin instance (e.g. client-side\n" " JavaScript client)." -msgstr "" +msgstr "<strong>سري</strong> - يستطيع العميل\nان يقوم بطلب نسخة من GNU MediaGoblin والتي من الممكن ان \nيعترضه وكيل المستخدم (مثلا الخادم من جانب العميل).<br />\n<strong>عام</strong> - لا يستطيع العميل ارسال طلبات سرية\nلنسخة من GNU MediaGoblin (مثلا \nخادم Ø§Ù„Ø¬Ø§ÙØ§ سكريبت من جانب العميل)." #: mediagoblin/plugins/oauth/forms.py:52 msgid "Redirect URI" -msgstr "" +msgstr "تØÙˆÙŠÙ„ لينك" #: mediagoblin/plugins/oauth/forms.py:54 msgid "" "The redirect URI for the applications, this field\n" " is <strong>required</strong> for public clients." -msgstr "" +msgstr "الرابط الموجه للبرنامج, هذا الØÙ‚Ù„\n<strong>مطلوب</strong> لجمهور العملاء." #: mediagoblin/plugins/oauth/forms.py:66 msgid "This field is required for public clients" -msgstr "" +msgstr "هذا الØÙ‚Ù„ مطلوب لجمهور العملاء" -#: mediagoblin/plugins/oauth/views.py:59 +#: mediagoblin/plugins/oauth/views.py:56 msgid "The client {0} has been registered!" -msgstr "" +msgstr "العميل {0} تم تسجيله!" #: mediagoblin/plugins/oauth/templates/oauth/client/connections.html:22 msgid "OAuth client connections" -msgstr "" +msgstr "ارتباطات العميل المنشئ" #: mediagoblin/plugins/oauth/templates/oauth/client/list.html:22 msgid "Your OAuth clients" -msgstr "" +msgstr "عميلك المنشئ" #: mediagoblin/plugins/oauth/templates/oauth/client/register.html:29 #: mediagoblin/templates/mediagoblin/submit/collection.html:30 #: mediagoblin/templates/mediagoblin/submit/start.html:34 #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:68 msgid "Add" -msgstr "" +msgstr "اضÙ" -#: mediagoblin/processing/__init__.py:172 +#: mediagoblin/processing/__init__.py:193 msgid "Invalid file given for media type." -msgstr "" +msgstr "المل٠المعطى لهذا النوع من الميديا غير صØÙŠØ." #: mediagoblin/submit/forms.py:26 msgid "File" msgstr "الملÙ" -#: mediagoblin/submit/views.py:51 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "يجب أن تضع ملÙًا." -#: mediagoblin/submit/views.py:97 +#: mediagoblin/submit/views.py:93 msgid "Woohoo! Submitted!" msgstr "يا سلام! Ù†ÙØ´Ø±ÙŽØª!" -#: mediagoblin/submit/views.py:146 +#: mediagoblin/submit/views.py:144 #, python-format msgid "Collection \"%s\" added!" -msgstr "" +msgstr "تم Ø¥Ø¶Ø§ÙØ© المجموعة \"%s\"!" -#: mediagoblin/templates/mediagoblin/base.html:64 +#: mediagoblin/templates/mediagoblin/base.html:67 msgid "Verify your email!" msgstr "تأكد من بريدك الإلكترونى!" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:68 msgid "log out" -msgstr "" +msgstr "تسجيل خروج" -#: mediagoblin/templates/mediagoblin/base.html:70 +#: mediagoblin/templates/mediagoblin/base.html:73 #: mediagoblin/templates/mediagoblin/auth/login.html:28 #: mediagoblin/templates/mediagoblin/auth/login.html:36 #: mediagoblin/templates/mediagoblin/auth/login.html:54 msgid "Log in" msgstr "تسجيل دخول" -#: mediagoblin/templates/mediagoblin/base.html:79 +#: mediagoblin/templates/mediagoblin/base.html:82 #, python-format msgid "<a href=\"%(user_url)s\">%(user_name)s</a>'s account" -msgstr "" +msgstr "<a href=\"%(user_url)s\">%(user_name)s</a>'s ØØ³Ø§Ø¨" -#: mediagoblin/templates/mediagoblin/base.html:86 +#: mediagoblin/templates/mediagoblin/base.html:89 msgid "Change account settings" -msgstr "" +msgstr "تغيير خصائص Ø§Ù„ØØ³Ø§Ø¨" -#: mediagoblin/templates/mediagoblin/base.html:90 -#: mediagoblin/templates/mediagoblin/base.html:105 +#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:108 #: mediagoblin/templates/mediagoblin/admin/panel.html:21 #: mediagoblin/templates/mediagoblin/admin/panel.html:26 #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:21 @@ -421,79 +450,32 @@ msgstr "" msgid "Media processing panel" msgstr "Ù„ÙˆØØ© معالجة الوسائط" -#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:96 msgid "Log out" -msgstr "" +msgstr "تسجيل خروج" -#: mediagoblin/templates/mediagoblin/base.html:96 +#: mediagoblin/templates/mediagoblin/base.html:99 #: mediagoblin/templates/mediagoblin/user_pages/user.html:156 msgid "Add media" msgstr "أض٠وسائط" -#: mediagoblin/templates/mediagoblin/base.html:99 +#: mediagoblin/templates/mediagoblin/base.html:102 #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:41 msgid "Create new collection" -msgstr "" - -#: mediagoblin/templates/mediagoblin/base.html:122 -#, python-format -msgid "" -"Powered by <a href=\"http://mediagoblin.org/\" title='Version " -"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." -msgstr "" - -#: mediagoblin/templates/mediagoblin/base.html:125 -#, 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 "" +msgstr "إنشاء مجموعة جديدة" #: mediagoblin/templates/mediagoblin/error.html:24 msgid "Image of goblin stressing out" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:31 -msgid "Explore" -msgstr "استكشÙ" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:35 -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:36 -msgid "" -"To add your own media, place comments, and more, you can log in with your " -"MediaGoblin account." -msgstr "" +msgstr "صورة قزم مرتبك" -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Don't have one yet? It's easy!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:39 -#, 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:47 +#: mediagoblin/templates/mediagoblin/root.html:32 msgid "Most recent media" msgstr "Ø£ØØ¯Ø« الوسائط" #: mediagoblin/templates/mediagoblin/admin/panel.html:29 msgid "" "Here you can track the state of media being processed on this instance." -msgstr "" +msgstr "يمكنك متابعة عملية معالجة وسائط معرضك من هنا." #: mediagoblin/templates/mediagoblin/admin/panel.html:32 #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:32 @@ -513,34 +495,34 @@ msgstr "ÙØ´Ù„ت معالجة هذه Ø§Ù„Ù…Ù„ÙØ§Øª:" #: mediagoblin/templates/mediagoblin/admin/panel.html:90 #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:86 msgid "No failed entries!" -msgstr "" +msgstr "لا توجد مداخل ÙØ§Ø´Ù„Ø©!" #: mediagoblin/templates/mediagoblin/admin/panel.html:92 msgid "Last 10 successful uploads" -msgstr "" +msgstr "آخر 10 تØÙˆÙŠÙ„ات Ù†Ø§Ø¬ØØ©" #: mediagoblin/templates/mediagoblin/admin/panel.html:112 #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:107 msgid "No processed entries, yet!" -msgstr "" +msgstr "لا يوجد مداخل Ù…ÙØ¹Ø§Ù„جة بعد! " #: mediagoblin/templates/mediagoblin/auth/change_fp.html:28 #: mediagoblin/templates/mediagoblin/auth/change_fp.html:36 msgid "Set your new password" -msgstr "" +msgstr "قم بضبط رقمك السري الجديد" #: mediagoblin/templates/mediagoblin/auth/change_fp.html:39 msgid "Set password" -msgstr "" +msgstr "قم بضبط رقم سري" #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:23 #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:31 msgid "Recover password" -msgstr "" +msgstr "استعادة كلمة السر" #: mediagoblin/templates/mediagoblin/auth/forgot_password.html:34 msgid "Send instructions" -msgstr "" +msgstr "ارسل تعليمات" #: mediagoblin/templates/mediagoblin/auth/fp_verification_email.txt:19 #, python-format @@ -592,6 +574,53 @@ msgid "" "%(verification_url)s" msgstr "أهلًا يا %(username)sØŒ\n\nØ§ÙØªØ الرابط التالي\nÙÙŠ Ù…ØªØµÙØÙƒ Ù„ØªÙØ¹ÙŠÙ„ ØØ³Ø§Ø¨Ùƒ ÙÙŠ غنو ميدياغوبلن:\n\n%(verification_url)s" +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:21 +#, python-format +msgid "" +"Powered by <a href=\"http://mediagoblin.org/\" title='Version " +"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." +msgstr "برعاية <a href=\"http://mediagoblin.org/\" title='Version %(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> مشروع." + +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:24 +#, 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\">Source code</a> متاØ." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:20 +msgid "Explore" +msgstr "استكشÙ" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:22 +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "اهلا, Ù…Ø±ØØ¨Ø§ بك ÙÙŠ موقع MediaGoblin." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:24 +msgid "" +"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, an " +"extraordinarily great piece of media hosting software." +msgstr "هذا الموقع يقوم بتشغيل <a href=\"http://mediagoblin.org\">MediaGoblin</a>, وهو برنامج Ø§Ø³ØªØ¶Ø§ÙØ© ميديا ÙØ§Ø¦Ù‚ الروعة." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:25 +msgid "" +"To add your own media, place comments, and more, you can log in with your " +"MediaGoblin account." +msgstr "لكي تضي٠الميديا خاصتك, تضع التعليقات, والمزيد, يجب عليك الدخول Ø¨ØØ³Ø§Ø¨ MediaGoblin الخاص بك." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:27 +msgid "Don't have one yet? It's easy!" +msgstr "ليس لديك ÙˆØ§ØØ¯ ØØªÙ‰ الآن؟ انه سهل!" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:28 +#, python-format +msgid "" +"<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/bits/logo.html:23 #: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 msgid "MediaGoblin logo" @@ -601,18 +630,18 @@ msgstr "شعار ميدياغوبلن" #: mediagoblin/templates/mediagoblin/edit/attachments.html:35 #, python-format msgid "Editing attachments for %(media_title)s" -msgstr "" +msgstr "تعديل المرÙقات Ù„ %(media_title)s" #: mediagoblin/templates/mediagoblin/edit/attachments.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:159 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:175 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:182 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:198 msgid "Attachments" -msgstr "" +msgstr "مرÙقات" #: mediagoblin/templates/mediagoblin/edit/attachments.html:57 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:181 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:204 msgid "Add attachment" -msgstr "" +msgstr "أض٠مرÙقة" #: mediagoblin/templates/mediagoblin/edit/attachments.html:61 #: mediagoblin/templates/mediagoblin/edit/delete_account.html:42 @@ -627,26 +656,36 @@ msgstr "ألغÙ" #: mediagoblin/templates/mediagoblin/edit/attachments.html:63 #: mediagoblin/templates/mediagoblin/edit/edit.html:42 -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:52 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:55 #: mediagoblin/templates/mediagoblin/edit/edit_collection.html:33 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:40 msgid "Save changes" msgstr "اØÙظ التغييرات" +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:28 +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 +#, python-format +msgid "Changing %(username)s's password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 +msgid "Save" +msgstr "" + #: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 #, python-format msgid "Really delete user '%(user_name)s' and all related media/comments?" -msgstr "" +msgstr "هل تريد ÙØ¹Ù„ا إلغاء المستخدم '%(user_name)s' وكل الميديا/التعليقات المتعلقة به؟" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:35 msgid "Yes, really delete my account" -msgstr "" +msgstr "نعم, قم بإلغاء ØØ³Ø§Ø¨ÙŠ" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:48 #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49 msgid "Delete permanently" -msgstr "" +msgstr "Ø§ØØ°Ù نهائيًا" #: mediagoblin/templates/mediagoblin/edit/edit.html:23 #: mediagoblin/templates/mediagoblin/edit/edit.html:35 @@ -658,11 +697,15 @@ msgstr "ØªØØ±ÙŠØ± %(media_title)s" #: mediagoblin/templates/mediagoblin/edit/edit_account.html:40 #, python-format msgid "Changing %(username)s's account settings" +msgstr "نغيير %(username)s خصائص Ø§Ù„ØØ³Ø§Ø¨" + +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 +msgid "Change your password." msgstr "" -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:59 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 msgid "Delete my account" -msgstr "" +msgstr "Ø¥Ù„ØºÙ ØØ³Ø§Ø¨ÙŠ" #: mediagoblin/templates/mediagoblin/edit/edit_collection.html:29 #, python-format @@ -681,42 +724,45 @@ msgstr "ØªØØ±ÙŠØ± مل٠%(username)s الشخصي" #: mediagoblin/templates/mediagoblin/listings/tag.html:35 #, python-format msgid "Media tagged with: %(tag_name)s" -msgstr "" +msgstr "يتم ØªØØ¯ÙŠØ¯ الميديا ب: %(tag_name)s" #: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 #: mediagoblin/templates/mediagoblin/media_displays/audio.html:56 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:65 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:136 #: mediagoblin/templates/mediagoblin/media_displays/video.html:55 msgid "Download" -msgstr "" +msgstr "تØÙ…يل" #: mediagoblin/templates/mediagoblin/media_displays/ascii.html:38 msgid "Original" -msgstr "" +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 "" +msgstr "عذرا, لن يتم تشغيل الصوت لأن âŽ\nÂ»Ù…ØªØµÙØÙƒ لا يدعم HTML5 âŽ\n»صوتيا." #: 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 "" +msgstr "تستطيع Ø§Ù„ØØµÙˆÙ„ على Ù…ØªØµÙØ ØØ¯ÙŠØ« âŽ\n»يمكنه تشغيل الصوت ÙÙŠ <a href=\"http://getfirefox.com\">âŽ\n» http://getfirefox.com</a>!" #: mediagoblin/templates/mediagoblin/media_displays/audio.html:60 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:71 #: mediagoblin/templates/mediagoblin/media_displays/video.html:61 msgid "Original file" -msgstr "" +msgstr "مل٠أصلي" #: mediagoblin/templates/mediagoblin/media_displays/audio.html:63 msgid "WebM file (Vorbis codec)" -msgstr "" +msgstr "مل٠WebM (Vorbic كوديك)" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:59 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:87 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:93 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:99 @@ -725,65 +771,69 @@ msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/media.html:65 #, python-format msgid "Image for %(media_title)s" +msgstr "صورة Ù„%(media_title)s" + +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 +msgid "PDF file" msgstr "" #: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 msgid "Toggle Rotate" -msgstr "" +msgstr "تبديل التدوير" #: mediagoblin/templates/mediagoblin/media_displays/stl.html:113 msgid "Perspective" -msgstr "" +msgstr "منظور" #: mediagoblin/templates/mediagoblin/media_displays/stl.html:116 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:117 msgid "Front" -msgstr "" +msgstr "مقدمة" #: mediagoblin/templates/mediagoblin/media_displays/stl.html:120 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:121 msgid "Top" -msgstr "" +msgstr "أعلى" #: mediagoblin/templates/mediagoblin/media_displays/stl.html:124 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:125 msgid "Side" -msgstr "" +msgstr "جانب" #: mediagoblin/templates/mediagoblin/media_displays/stl.html:130 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:131 msgid "WebGL" -msgstr "" +msgstr "WebGL" #: mediagoblin/templates/mediagoblin/media_displays/stl.html:138 msgid "Download model" -msgstr "" +msgstr "تØÙ…يل نموذج" #: mediagoblin/templates/mediagoblin/media_displays/stl.html:146 msgid "File Format" -msgstr "" +msgstr "بنية الملÙ" #: mediagoblin/templates/mediagoblin/media_displays/stl.html:148 msgid "Object Height" -msgstr "" +msgstr "طول الكائن" #: mediagoblin/templates/mediagoblin/media_displays/video.html:44 msgid "" "Sorry, this video will not work because\n" " your web browser does not support HTML5 \n" " video." -msgstr "" +msgstr "عذرا, لن يتم تشغيل هذا الÙيديو لأن âŽ\nÂ»Ù…ØªØµÙØÙƒ لا يدعم HTML5 âŽ\n»Ùيديو." #: mediagoblin/templates/mediagoblin/media_displays/video.html:47 msgid "" "You can get a modern web browser that \n" " can play this video at <a href=\"http://getfirefox.com\">\n" " http://getfirefox.com</a>!" -msgstr "" +msgstr "تستطيع Ø§Ù„ØØµÙˆÙ„ على Ù…ØªØµÙØ ØØ¯ÙŠØ« âŽ\n»يمكنه تشغيل هذا الÙيديو ÙÙŠ <a href=\"http://getfirefox.com\">âŽ\n» http://getfirefox.com</a>!" #: mediagoblin/templates/mediagoblin/media_displays/video.html:69 msgid "WebM file (640p; VP8/Vorbis)" -msgstr "" +msgstr "WebM مل٠(640p; VP8/Vorbis)" #: mediagoblin/templates/mediagoblin/submit/collection.html:26 msgid "Add a collection" @@ -792,27 +842,27 @@ msgstr "Ø¥Ø¶Ø§ÙØ© مجموعة" #: mediagoblin/templates/mediagoblin/submit/start.html:23 #: mediagoblin/templates/mediagoblin/submit/start.html:30 msgid "Add your media" -msgstr "" +msgstr "اض٠الميديا الخاصة بك" #: mediagoblin/templates/mediagoblin/user_pages/collection.html:30 #, python-format msgid "%(collection_title)s (%(username)s's collection)" -msgstr "" +msgstr "%(collection_title)s (%(username)s's مجموعة)" #: mediagoblin/templates/mediagoblin/user_pages/collection.html:39 #, python-format msgid "%(collection_title)s by <a href=\"%(user_url)s\">%(username)s</a>" -msgstr "" +msgstr "%(collection_title)s بواسطة <a href=\"%(user_url)s\">%(username)s</a>" #: mediagoblin/templates/mediagoblin/user_pages/collection.html:52 #: mediagoblin/templates/mediagoblin/user_pages/media.html:79 msgid "Edit" -msgstr "" +msgstr "تعديل" #: mediagoblin/templates/mediagoblin/user_pages/collection.html:56 #: mediagoblin/templates/mediagoblin/user_pages/media.html:83 msgid "Delete" -msgstr "" +msgstr "إلغاء" #: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:30 #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 @@ -823,40 +873,40 @@ msgstr "أتود ØÙ‚ًا ØØ°Ù %(title)s?" #: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:31 #, python-format msgid "Really remove %(media_title)s from %(collection_title)s?" -msgstr "" +msgstr "هل تريد ÙØ¹Ù„ا إلغاء %(media_title)s من %(collection_title)s?" -#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:54 msgid "Remove" -msgstr "" +msgstr "إلغاء" #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:21 #, python-format msgid "%(username)s's collections" -msgstr "" +msgstr "%(username)s's مجموعات" #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:28 #, python-format msgid "<a href=\"%(user_url)s\">%(username)s</a>'s collections" -msgstr "" +msgstr "<a href=\"%(user_url)s\">%(username)s</a>'s مجموعات" #: mediagoblin/templates/mediagoblin/user_pages/comment_email.txt:19 #, python-format msgid "" "Hi %(username)s,\n" "%(comment_author)s commented on your post (%(comment_url)s) at %(instance_name)s\n" -msgstr "" +msgstr "اهلا, %(username)s,\n%(comment_author)s قام بالتعليق على مشاركتك (%(comment_url)s) ÙÙŠ %(instance_name)s\n" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format msgid "%(username)s's media" -msgstr "" +msgstr "%(username)s ميديا" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:38 #, python-format msgid "" "<a href=\"%(user_url)s\">%(username)s</a>'s media with tag <a " "href=\"%(tag_url)s\">%(tag)s</a>" -msgstr "" +msgstr "<a href=\"%(user_url)s\">\n%(username)s\n</a>\n's ميديا Ø¨Ø§Ù„Ù…ØØ¯Ø¯\n<a href=\"%(tag_url)s\">\n%(tag)s\n</a>" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:48 #, python-format @@ -866,40 +916,44 @@ msgstr "وسائط <a href=\"%(user_url)s\">%(username)s</a>" #: mediagoblin/templates/mediagoblin/user_pages/media.html:38 #, python-format msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>" -msgstr "" +msgstr "■اختيار الميديا بواسطة <a href=\"%(user_url)s\">%(username)s</a>" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:94 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:95 msgid "Add a comment" -msgstr "" +msgstr "أض٠تعليق" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 msgid "Add this comment" +msgstr "اض٠هذا التعليق" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:132 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:152 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:164 +#, python-format +msgid "%(formatted_time)s ago" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:123 -msgid "at" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:150 +msgid "Added" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:144 -#, python-format -msgid "" -"<h3>Added on</h3>\n" -" <p>%(date)s</p>" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:161 +msgid "Created" msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:40 #, python-format msgid "Add “%(media_title)s†to a collection" -msgstr "" +msgstr "Ø¥Ø¶Ø§ÙØ© “%(media_title)s†لمجموعة" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:54 msgid "+" -msgstr "" +msgstr "+" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:58 msgid "Add a new collection" -msgstr "" +msgstr "Ø¥Ø¶Ø§ÙØ© مجموعة جديدة" #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:29 msgid "" @@ -908,7 +962,7 @@ msgstr "يمكنك متابعة عملية معالجة وسائط معرضك Ù… #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:89 msgid "Your last 10 successful uploads" -msgstr "" +msgstr "آخر 10 تØÙ…يلات Ù†Ø§Ø¬ØØ© خاصة بك" #: mediagoblin/templates/mediagoblin/user_pages/user.html:31 #: mediagoblin/templates/mediagoblin/user_pages/user.html:89 @@ -970,7 +1024,7 @@ msgstr "لم يعبئ هذا العضو بيانات ملÙÙ‡ بعد." #: mediagoblin/templates/mediagoblin/user_pages/user.html:124 msgid "Browse collections" -msgstr "" +msgstr "ØªØØ¯ÙŠØ¯ مجموعة" #: mediagoblin/templates/mediagoblin/user_pages/user.html:137 #, python-format @@ -991,59 +1045,59 @@ msgstr "لا يبدو أنه توجد أي وسائط هنا ØØªÙ‰ الآن..." #: mediagoblin/templates/mediagoblin/utils/collection_gallery.html:49 msgid "(remove)" -msgstr "" +msgstr "(إلغاء)" #: mediagoblin/templates/mediagoblin/utils/collections.html:21 msgid "Collected in" -msgstr "" +msgstr "تم تجميعه ÙÙŠ" #: mediagoblin/templates/mediagoblin/utils/collections.html:40 msgid "Add to a collection" -msgstr "" +msgstr "Ø¥Ø¶Ø§ÙØ© مجموعة" #: mediagoblin/templates/mediagoblin/utils/feed_link.html:21 #: mediagoblin/themes/airy/templates/mediagoblin/utils/feed_link.html:21 msgid "feed icon" -msgstr "" +msgstr "ايقونة تغذية" #: mediagoblin/templates/mediagoblin/utils/feed_link.html:23 #: mediagoblin/themes/airy/templates/mediagoblin/utils/feed_link.html:23 msgid "Atom feed" -msgstr "" +msgstr "تغذية ذرية" #: mediagoblin/templates/mediagoblin/utils/license.html:25 msgid "All rights reserved" -msgstr "" +msgstr "جميع الØÙ‚وق Ù…ØÙوظة" #: mediagoblin/templates/mediagoblin/utils/pagination.html:39 msgid "↠Newer" -msgstr "" +msgstr "اجددâ†" #: mediagoblin/templates/mediagoblin/utils/pagination.html:45 msgid "Older →" -msgstr "" +msgstr "→اقدم" #: mediagoblin/templates/mediagoblin/utils/pagination.html:48 msgid "Go to page:" -msgstr "" +msgstr "اذهب إلى ØµÙØØ©:" #: mediagoblin/templates/mediagoblin/utils/prev_next.html:28 #: mediagoblin/templates/mediagoblin/utils/prev_next.html:33 msgid "newer" -msgstr "" +msgstr "اجدد" #: mediagoblin/templates/mediagoblin/utils/prev_next.html:39 #: mediagoblin/templates/mediagoblin/utils/prev_next.html:44 msgid "older" -msgstr "" +msgstr "اقدم" #: mediagoblin/templates/mediagoblin/utils/tags.html:20 msgid "Tagged with" -msgstr "" +msgstr "ØªØØ¯Ø¯ ب" -#: mediagoblin/tools/exif.py:80 +#: mediagoblin/tools/exif.py:83 msgid "Could not read the image file." -msgstr "" +msgstr "لم نستطيع قراءة هذه الصورة." #: mediagoblin/tools/response.py:35 msgid "Oops!" @@ -1051,36 +1105,60 @@ msgstr "ويØÙŠ!" #: mediagoblin/tools/response.py:36 msgid "An error occured" -msgstr "" +msgstr "ØØ¯Ø« خطأ" #: mediagoblin/tools/response.py:51 msgid "Operation not allowed" -msgstr "" +msgstr "غير Ù…Ø³Ù…ÙˆØ Ø¨Ù‡Ø°Ù‡ العملية" #: mediagoblin/tools/response.py:52 msgid "" "Sorry Dave, I can't let you do that!</p><p>You have tried to perform a " "function that you are not allowed to. Have you been trying to delete all " "user accounts again?" -msgstr "" +msgstr "عذرا ديÙ, لا استطيع ترك ØªÙØ¹Ù„ هذا!</p><p>لقد ØØ§ÙˆÙ„ت تشغيل خاصية ليست Ù…Ø³Ù…ÙˆØØ© لك. هل كنت ØªØØ§ÙˆÙ„ إلغاء جميع ØØ³Ø§Ø¨Ø§Øª المستخدمين مجددا؟" #: mediagoblin/tools/response.py:60 msgid "" "There doesn't seem to be a page at this address. Sorry!</p><p>If you're sure" " the address is correct, maybe the page you're looking for has been moved or" " deleted." +msgstr "يبدو أنه لا توجد ØµÙØØ© بهذا العنوان, عذرا</p><p>إذا كنت متأكد من ØµØØ© العنوان, من الممكن أن تكون Ø§Ù„ØµÙØØ© التي ØªØ¨ØØ« عنها قد تم نقلها أو إلغاءها." + +#: mediagoblin/tools/timesince.py:62 +msgid "year" +msgstr "" + +#: mediagoblin/tools/timesince.py:63 +msgid "month" +msgstr "" + +#: mediagoblin/tools/timesince.py:64 +msgid "week" +msgstr "" + +#: mediagoblin/tools/timesince.py:65 +msgid "day" +msgstr "" + +#: mediagoblin/tools/timesince.py:66 +msgid "hour" +msgstr "" + +#: mediagoblin/tools/timesince.py:67 +msgid "minute" msgstr "" #: mediagoblin/user_pages/forms.py:23 msgid "Comment" -msgstr "" +msgstr "تعليق" #: mediagoblin/user_pages/forms.py:25 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/user_pages/forms.py:31 msgid "I am sure I want to delete this" @@ -1088,87 +1166,91 @@ msgstr "أنا متأكد من رغبتي Ø¨ØØ°Ù هذا العمل" #: mediagoblin/user_pages/forms.py:35 msgid "I am sure I want to remove this item from the collection" -msgstr "" +msgstr "أنا متأكد من أنني أريد إلغاء هذه المادة من المجموعة" #: mediagoblin/user_pages/forms.py:39 msgid "Collection" -msgstr "" +msgstr "مجموعة" #: mediagoblin/user_pages/forms.py:40 msgid "-- Select --" -msgstr "" +msgstr "-- إختار --" #: mediagoblin/user_pages/forms.py:42 msgid "Include a note" -msgstr "" +msgstr "إدراج Ù…Ù„Ø§ØØ¸Ø©" -#: mediagoblin/user_pages/lib.py:56 +#: mediagoblin/user_pages/lib.py:58 msgid "commented on your post" +msgstr "قام بالتعليق على مشاركتك" + +#: mediagoblin/user_pages/views.py:169 +msgid "Sorry, comments are disabled." msgstr "" -#: mediagoblin/user_pages/views.py:166 +#: mediagoblin/user_pages/views.py:174 msgid "Oops, your comment was empty." -msgstr "" +msgstr "عذرا, لقد قمت بادخال تعليق ÙØ§Ø±Øº." -#: mediagoblin/user_pages/views.py:172 +#: mediagoblin/user_pages/views.py:180 msgid "Your comment has been posted!" -msgstr "" +msgstr "لقد تم إرسال تعليقك!" -#: mediagoblin/user_pages/views.py:197 +#: mediagoblin/user_pages/views.py:205 msgid "Please check your entries and try again." -msgstr "" +msgstr "من ÙØ¶Ù„Ùƒ قم Ø¨ÙØØµ المداخل وقم Ø¨Ø§Ù„Ù…ØØ§ÙˆÙ„Ø© مرة أخرى." -#: mediagoblin/user_pages/views.py:237 +#: mediagoblin/user_pages/views.py:245 msgid "You have to select or add a collection" -msgstr "" +msgstr "يجب عليك إختيار أو Ø¥Ø¶Ø§ÙØ© مجموعة" -#: mediagoblin/user_pages/views.py:248 +#: mediagoblin/user_pages/views.py:256 #, python-format msgid "\"%s\" already in collection \"%s\"" -msgstr "" +msgstr "\"%s\" توجد Ø¨Ø§Ù„ÙØ¹Ù„ ÙÙŠ المجموعة \"%s\"" -#: mediagoblin/user_pages/views.py:264 +#: mediagoblin/user_pages/views.py:262 #, python-format msgid "\"%s\" added to collection \"%s\"" -msgstr "" +msgstr "\"%s\" Ø£ÙØ¶ÙŠÙت للمجموعة \"%s\"" -#: mediagoblin/user_pages/views.py:286 +#: mediagoblin/user_pages/views.py:282 msgid "You deleted the media." -msgstr "" +msgstr "لقد قمت بإلغاء الميديا." -#: mediagoblin/user_pages/views.py:293 +#: mediagoblin/user_pages/views.py:289 msgid "The media was not deleted because you didn't check that you were sure." -msgstr "" +msgstr "لم يتم إلغاء الميديا لأنك لم تقم بإختيار انك متأكد من ذلك." -#: mediagoblin/user_pages/views.py:301 +#: mediagoblin/user_pages/views.py:296 msgid "You are about to delete another user's media. Proceed with caution." msgstr "أنت على وشك ØØ°Ù وسائط مستخدم آخر. كن ØØ°Ø±Ù‹Ø§ أثناء العملية." -#: mediagoblin/user_pages/views.py:375 +#: mediagoblin/user_pages/views.py:370 msgid "You deleted the item from the collection." -msgstr "" +msgstr "لقد قمت بإلغاء المادة من المجموعة." -#: mediagoblin/user_pages/views.py:379 +#: mediagoblin/user_pages/views.py:374 msgid "The item was not removed because you didn't check that you were sure." -msgstr "" +msgstr "لم يتم إلغاء المادة لأنك لم تقم بإختيار انك متأكد من ذلك." -#: mediagoblin/user_pages/views.py:389 +#: mediagoblin/user_pages/views.py:382 msgid "" "You are about to delete an item from another user's collection. Proceed with" " caution." -msgstr "" +msgstr "أنت على وشك ØØ°Ù مادة من مجموعة مستخدم آخر. كن ØØ°Ø±Ø§." -#: mediagoblin/user_pages/views.py:422 +#: mediagoblin/user_pages/views.py:415 #, python-format msgid "You deleted the collection \"%s\"" -msgstr "" +msgstr "لقد قمت بإلغاء المجموعة \"%s\"" -#: mediagoblin/user_pages/views.py:429 +#: mediagoblin/user_pages/views.py:422 msgid "" "The collection was not deleted because you didn't check that you were sure." -msgstr "" +msgstr "لم يتم إلغاء المجموعة لأنك لم تقم بإختيار انك متأكد من ذلك." -#: mediagoblin/user_pages/views.py:439 +#: mediagoblin/user_pages/views.py:430 msgid "" "You are about to delete another user's collection. Proceed with caution." -msgstr "" +msgstr "أنت على وشك ØØ°Ù مجموعة مستخدم آخر. كن ØØ°Ø±Ø§." diff --git a/mediagoblin/i18n/ca/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/ca/LC_MESSAGES/mediagoblin.mo Binary files differindex 495ef726..ec01d7f7 100644 --- a/mediagoblin/i18n/ca/LC_MESSAGES/mediagoblin.mo +++ b/mediagoblin/i18n/ca/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/ca/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/ca/LC_MESSAGES/mediagoblin.po index 28bdca82..9ebbdf18 100644 --- a/mediagoblin/i18n/ca/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/ca/LC_MESSAGES/mediagoblin.po @@ -3,17 +3,17 @@ # This file is distributed under the same license as the PROJECT project. # # Translators: -# Al fred <devaleitzer@aim.com>, 2011. -# <devaleitzer@aim.com>, 2011. -# <skarbat@gmail.com>, 2012. +# Al fred <devaleitzer@aim.com>, 2011 +# Al fred <devaleitzer@aim.com>, 2011 +# skarbat <skarbat@gmail.com>, 2012 msgid "" msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" -"POT-Creation-Date: 2013-03-04 18:04-0600\n" -"PO-Revision-Date: 2013-03-05 00:04+0000\n" +"POT-Creation-Date: 2013-05-27 13:54-0500\n" +"PO-Revision-Date: 2013-05-27 18:54+0000\n" "Last-Translator: cwebber <cwebber@dustycloud.org>\n" -"Language-Team: LANGUAGE <LL@li.org>\n" +"Language-Team: Catalan (http://www.transifex.com/projects/p/mediagoblin/language/ca/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -21,34 +21,39 @@ msgstr "" "Language: ca\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: mediagoblin/auth/forms.py:28 -msgid "Invalid User name or email address." -msgstr "" - -#: mediagoblin/auth/forms.py:29 -msgid "This field does not take email addresses." -msgstr "" - -#: mediagoblin/auth/forms.py:30 -msgid "This field requires an email address." -msgstr "" - -#: mediagoblin/auth/forms.py:52 mediagoblin/auth/forms.py:67 +#: mediagoblin/auth/forms.py:26 msgid "Username" msgstr "Nom d'usuari" -#: mediagoblin/auth/forms.py:56 mediagoblin/auth/forms.py:71 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 +#: mediagoblin/tests/test_util.py:110 msgid "Password" msgstr "Contrasenya" -#: mediagoblin/auth/forms.py:60 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "Adreça electrònica" -#: mediagoblin/auth/forms.py:78 +#: mediagoblin/auth/forms.py:41 +msgid "Username or Email" +msgstr "" + +#: mediagoblin/auth/forms.py:52 msgid "Username or email" msgstr "Nom d'usuari o correu" +#: mediagoblin/auth/tools.py:31 +msgid "Invalid User name or email address." +msgstr "" + +#: mediagoblin/auth/tools.py:32 +msgid "This field does not take email addresses." +msgstr "" + +#: mediagoblin/auth/tools.py:33 +msgid "This field requires an email address." +msgstr "" + #: mediagoblin/auth/views.py:54 msgid "Sorry, registration is disabled on this instance." msgstr "Ho sentim, el registre està desactivat en aquest cas." @@ -61,54 +66,54 @@ msgstr "Lamentablement aquest usuari ja existeix." msgid "Sorry, a user with that email address already exists." msgstr "Perdó, ja existeix un usuari amb aquesta adreça de correu." -#: mediagoblin/auth/views.py:174 +#: 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!" -#: mediagoblin/auth/views.py:180 +#: 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." -#: mediagoblin/auth/views.py:198 +#: mediagoblin/auth/views.py:206 msgid "You must be logged in so we know who to send the email to!" msgstr "Has d'estar conectat per saber a qui hem d'enviar el correu!" -#: mediagoblin/auth/views.py:206 +#: mediagoblin/auth/views.py:214 msgid "You've already verified your email address!" msgstr "Ja has verificat la teva adreça de correu!" -#: mediagoblin/auth/views.py:219 +#: mediagoblin/auth/views.py:227 msgid "Resent your verification email." msgstr "Torna'm a enviar el correu de verificació" -#: mediagoblin/auth/views.py:250 +#: mediagoblin/auth/views.py:258 msgid "" "If that email address (case sensitive!) is registered an email has been sent" " with instructions on how to change your password." msgstr "" -#: mediagoblin/auth/views.py:261 +#: mediagoblin/auth/views.py:269 msgid "Couldn't find someone with that username." msgstr "" -#: mediagoblin/auth/views.py:264 +#: mediagoblin/auth/views.py:272 msgid "" "An email has been sent with instructions on how to change your password." msgstr "S'ha enviat un correu amb instruccions de com cambiar la teva contrasenya" -#: mediagoblin/auth/views.py:271 +#: mediagoblin/auth/views.py:279 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." msgstr "No hem pogut enviar el correu de recuperació de contrasenya perquè el teu nom d'usuari és inactiu o bé l'adreça electrònica del teu compte no ha sigut verificada." -#: mediagoblin/auth/views.py:328 +#: mediagoblin/auth/views.py:336 msgid "You can now log in using your new password." msgstr "Ara et pots conectar amb la teva nova contrasenya." -#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:93 +#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:82 #: mediagoblin/submit/forms.py:28 mediagoblin/submit/forms.py:47 #: mediagoblin/user_pages/forms.py:45 msgid "Title" @@ -119,7 +124,7 @@ msgid "Description of this work" msgstr "Descripció d'aquest treball." #: mediagoblin/edit/forms.py:29 mediagoblin/edit/forms.py:52 -#: mediagoblin/edit/forms.py:97 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:86 mediagoblin/submit/forms.py:32 #: mediagoblin/submit/forms.py:51 mediagoblin/user_pages/forms.py:49 msgid "" "You can use\n" @@ -135,11 +140,11 @@ msgstr "Etiquetes" msgid "Separate tags by commas." msgstr "Separa els tags amb comes." -#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:101 +#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:90 msgid "Slug" msgstr "Llimac" -#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:102 +#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:91 msgid "The slug can't be empty" msgstr "El llimac no pot ésser buit" @@ -167,45 +172,45 @@ msgid "This address contains errors" msgstr "Aquesta adreça conté errors" #: mediagoblin/edit/forms.py:63 -msgid "Old password" -msgstr "Contrasenya antiga" - -#: mediagoblin/edit/forms.py:64 -msgid "Enter your old password to prove you own this account." -msgstr "Introdueix la teva contrasenya antiga per comprovar que aquest compte és teu." - -#: mediagoblin/edit/forms.py:67 -msgid "New password" -msgstr "Nova contrasenya" - -#: mediagoblin/edit/forms.py:74 msgid "License preference" msgstr "" -#: mediagoblin/edit/forms.py:80 +#: mediagoblin/edit/forms.py:69 msgid "This will be your default license on upload forms." msgstr "" -#: mediagoblin/edit/forms.py:82 +#: mediagoblin/edit/forms.py:71 msgid "Email me when others comment on my media" msgstr "Envia'm correu quan d'altres comentin al meu mitjà " -#: mediagoblin/edit/forms.py:94 +#: mediagoblin/edit/forms.py:83 msgid "The title can't be empty" msgstr "El tÃtol no pot ser buit" -#: mediagoblin/edit/forms.py:96 mediagoblin/submit/forms.py:50 +#: mediagoblin/edit/forms.py:85 mediagoblin/submit/forms.py:50 #: mediagoblin/user_pages/forms.py:48 msgid "Description of this collection" msgstr "Descripció d'aquesta col.lecció" -#: mediagoblin/edit/forms.py:103 +#: mediagoblin/edit/forms.py:92 msgid "" "The title part of this collection's address. You usually don't need to " "change this." msgstr "La part del tÃtol de l'adreça d'aquesta col.lecció. Normalment no cal que canviis això." -#: mediagoblin/edit/views.py:66 +#: mediagoblin/edit/forms.py:99 +msgid "Old password" +msgstr "Contrasenya antiga" + +#: mediagoblin/edit/forms.py:101 +msgid "Enter your old password to prove you own this account." +msgstr "Introdueix la teva contrasenya antiga per comprovar que aquest compte és teu." + +#: mediagoblin/edit/forms.py:104 +msgid "New password" +msgstr "Nova contrasenya" + +#: mediagoblin/edit/views.py:67 msgid "An entry with that slug already exists for this user." msgstr "Ja existeix una entrada amb aquest llimac per aquest usuari" @@ -230,44 +235,63 @@ msgstr "Esteu editant el perfil d'un usuari. Aneu amb compte" msgid "Profile changes saved" msgstr "Els canvis al perfil s'han guardat" -#: mediagoblin/edit/views.py:241 -msgid "Wrong password" -msgstr "Contrasenya errònia" - -#: mediagoblin/edit/views.py:252 +#: mediagoblin/edit/views.py:240 msgid "Account settings saved" msgstr "Els detalls del compte s'han guardat" -#: mediagoblin/edit/views.py:286 +#: mediagoblin/edit/views.py:274 msgid "You need to confirm the deletion of your account." msgstr "" -#: mediagoblin/edit/views.py:322 mediagoblin/submit/views.py:142 -#: mediagoblin/user_pages/views.py:214 +#: mediagoblin/edit/views.py:310 mediagoblin/submit/views.py:138 +#: mediagoblin/user_pages/views.py:222 #, python-format msgid "You already have a collection called \"%s\"!" msgstr "Ja tens una col.lecció anomenada \"%s\"!" -#: mediagoblin/edit/views.py:326 +#: mediagoblin/edit/views.py:314 msgid "A collection with that slug already exists for this user." msgstr "" -#: mediagoblin/edit/views.py:343 +#: mediagoblin/edit/views.py:329 msgid "You are editing another user's collection. Proceed with caution." msgstr "Estas editant la col.lecció d'un altre usuari. Prossegueix amb cautela." -#: mediagoblin/gmg_commands/theme.py:58 +#: mediagoblin/edit/views.py:348 +msgid "Wrong password" +msgstr "Contrasenya errònia" + +#: mediagoblin/edit/views.py:363 +msgid "Your password was changed successfully" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:60 msgid "Cannot link theme... no theme set\n" msgstr "No es pot enllaçar el tema... no hi ha tema establert\n" -#: mediagoblin/gmg_commands/theme.py:71 +#: mediagoblin/gmg_commands/assetlink.py:73 msgid "No asset directory for this theme\n" msgstr "" -#: mediagoblin/gmg_commands/theme.py:74 +#: mediagoblin/gmg_commands/assetlink.py:76 msgid "However, old link directory symlink found; removed.\n" msgstr "Tot i aixÃ, l'enllaç antic al directori s'ha trobat; eliminat.\n" +#: mediagoblin/gmg_commands/assetlink.py:112 +#, python-format +msgid "Could not link \"%s\": %s exists and is not a symlink\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:119 +#, python-format +msgid "Skipping \"%s\"; already set up.\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:124 +#, python-format +msgid "Old link found for \"%s\"; removing.\n" +msgstr "" + #: mediagoblin/meddleware/csrf.py:134 msgid "" "CSRF cookie not present. This is most likely the result of a cookie blocker " @@ -275,12 +299,16 @@ msgid "" "domain." msgstr "" -#: mediagoblin/media_types/__init__.py:61 -#: mediagoblin/media_types/__init__.py:102 +#: mediagoblin/media_types/__init__.py:111 +#: mediagoblin/media_types/__init__.py:155 msgid "Sorry, I don't support that file type :(" msgstr "Ho sento, no puc manegar aquest tipus d'arxiu :(" -#: mediagoblin/media_types/video/processing.py:36 +#: mediagoblin/media_types/pdf/processing.py:136 +msgid "unoconv failing to run, check log file" +msgstr "" + +#: mediagoblin/media_types/video/processing.py:37 msgid "Video transcoding failed" msgstr "La transformació del vÃdeo ha fallat" @@ -347,7 +375,7 @@ msgstr "La URI de redirecció per les aplicacions, aquest camp\n és msgid "This field is required for public clients" msgstr "Aquest camp és requeriment per a clients públics" -#: mediagoblin/plugins/oauth/views.py:59 +#: mediagoblin/plugins/oauth/views.py:56 msgid "The client {0} has been registered!" msgstr "El client {0} ha sigut enregistrat!" @@ -366,7 +394,7 @@ msgstr "" msgid "Add" msgstr "Afegir" -#: mediagoblin/processing/__init__.py:172 +#: mediagoblin/processing/__init__.py:193 msgid "Invalid file given for media type." msgstr "Aquest tipus de fitxer no és và lid." @@ -374,45 +402,45 @@ msgstr "Aquest tipus de fitxer no és và lid." msgid "File" msgstr "Fitxer" -#: mediagoblin/submit/views.py:51 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "Heu d'escollir un fitxer." -#: mediagoblin/submit/views.py:97 +#: mediagoblin/submit/views.py:93 msgid "Woohoo! Submitted!" msgstr "Visca! S'ha enviat!" -#: mediagoblin/submit/views.py:146 +#: mediagoblin/submit/views.py:144 #, python-format msgid "Collection \"%s\" added!" msgstr "S'ha afegit la col.leccio \"%s\"!" -#: mediagoblin/templates/mediagoblin/base.html:64 +#: mediagoblin/templates/mediagoblin/base.html:67 msgid "Verify your email!" msgstr "Verifica el teu correu electrònic" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:68 msgid "log out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:70 +#: mediagoblin/templates/mediagoblin/base.html:73 #: mediagoblin/templates/mediagoblin/auth/login.html:28 #: mediagoblin/templates/mediagoblin/auth/login.html:36 #: mediagoblin/templates/mediagoblin/auth/login.html:54 msgid "Log in" msgstr "Entra" -#: mediagoblin/templates/mediagoblin/base.html:79 +#: mediagoblin/templates/mediagoblin/base.html:82 #, python-format msgid "<a href=\"%(user_url)s\">%(user_name)s</a>'s account" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:86 +#: mediagoblin/templates/mediagoblin/base.html:89 msgid "Change account settings" msgstr "Modificar els ajustaments del compte" -#: mediagoblin/templates/mediagoblin/base.html:90 -#: mediagoblin/templates/mediagoblin/base.html:105 +#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:108 #: mediagoblin/templates/mediagoblin/admin/panel.html:21 #: mediagoblin/templates/mediagoblin/admin/panel.html:26 #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:21 @@ -420,72 +448,25 @@ msgstr "Modificar els ajustaments del compte" msgid "Media processing panel" msgstr "Quadre de processament de fitxers" -#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:96 msgid "Log out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:96 +#: mediagoblin/templates/mediagoblin/base.html:99 #: mediagoblin/templates/mediagoblin/user_pages/user.html:156 msgid "Add media" msgstr "Tots els fitxers" -#: mediagoblin/templates/mediagoblin/base.html:99 +#: mediagoblin/templates/mediagoblin/base.html:102 #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:41 msgid "Create new collection" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:122 -#, python-format -msgid "" -"Powered by <a href=\"http://mediagoblin.org/\" title='Version " -"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." -msgstr "" - -#: mediagoblin/templates/mediagoblin/base.html:125 -#, 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 "Alliberat segons la <a href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a href=\"%(source_link)s\">Codi font</a> disponible." - #: mediagoblin/templates/mediagoblin/error.html:24 msgid "Image of goblin stressing out" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:31 -msgid "Explore" -msgstr "Explorar" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "Hola, una benvinguda al MediaGoblin!" - -#: mediagoblin/templates/mediagoblin/root.html:35 -msgid "" -"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, an " -"extraordinarily great piece of media hosting software." -msgstr "El lloc esta usant <a href=\"http://mediagoblin.org\">MediaGoblin</a>, una gran i extraordinà ria peça de software per allotjar mitjans." - -#: mediagoblin/templates/mediagoblin/root.html:36 -msgid "" -"To add your own media, place comments, and more, you can log in with your " -"MediaGoblin account." -msgstr "Per afegir el teu propi mitjà , col.locar comentaris, i més, pots conectar-te amb el teu compte MediaGoblin." - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Don't have one yet? It's easy!" -msgstr "No en tens una encara? Es fà cil!" - -#: mediagoblin/templates/mediagoblin/root.html:39 -#, 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\">Crear un compte a aquest lloc</a> \no\n <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">Preparar MediaGoblin al teu propi servidor</a>" - -#: mediagoblin/templates/mediagoblin/root.html:47 +#: mediagoblin/templates/mediagoblin/root.html:32 msgid "Most recent media" msgstr "Mitjans més recents" @@ -591,6 +572,53 @@ msgid "" "%(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/bits/base_footer.html:21 +#, python-format +msgid "" +"Powered by <a href=\"http://mediagoblin.org/\" title='Version " +"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:24 +#, 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 "Alliberat segons la <a href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a href=\"%(source_link)s\">Codi font</a> disponible." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:20 +msgid "Explore" +msgstr "Explorar" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:22 +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "Hola, una benvinguda al MediaGoblin!" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:24 +msgid "" +"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, an " +"extraordinarily great piece of media hosting software." +msgstr "El lloc esta usant <a href=\"http://mediagoblin.org\">MediaGoblin</a>, una gran i extraordinà ria peça de software per allotjar mitjans." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:25 +msgid "" +"To add your own media, place comments, and more, you can log in with your " +"MediaGoblin account." +msgstr "Per afegir el teu propi mitjà , col.locar comentaris, i més, pots conectar-te amb el teu compte MediaGoblin." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:27 +msgid "Don't have one yet? It's easy!" +msgstr "No en tens una encara? Es fà cil!" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:28 +#, 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/bits/logo.html:23 #: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 msgid "MediaGoblin logo" @@ -603,13 +631,13 @@ msgid "Editing attachments for %(media_title)s" msgstr "Editant afegits per a %(media_title)s" #: mediagoblin/templates/mediagoblin/edit/attachments.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:159 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:175 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:182 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:198 msgid "Attachments" msgstr "" #: mediagoblin/templates/mediagoblin/edit/attachments.html:57 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:181 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:204 msgid "Add attachment" msgstr "" @@ -626,12 +654,22 @@ msgstr "Cancel·la" #: mediagoblin/templates/mediagoblin/edit/attachments.html:63 #: mediagoblin/templates/mediagoblin/edit/edit.html:42 -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:52 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:55 #: mediagoblin/templates/mediagoblin/edit/edit_collection.html:33 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:40 msgid "Save changes" msgstr "Desa els canvis" +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:28 +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 +#, python-format +msgid "Changing %(username)s's password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 +msgid "Save" +msgstr "" + #: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 #, python-format msgid "Really delete user '%(user_name)s' and all related media/comments?" @@ -642,7 +680,7 @@ msgid "Yes, really delete my account" msgstr "" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:48 #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49 msgid "Delete permanently" msgstr "Esborrar permanentment" @@ -659,7 +697,11 @@ msgstr "Edició %(media_title)s " msgid "Changing %(username)s's account settings" msgstr "Modificant els detalls del compte de %(username)s" -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:59 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 +msgid "Change your password." +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 msgid "Delete my account" msgstr "" @@ -684,6 +726,7 @@ msgstr "Mitjà marcat amb: %(tag_name)s" #: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 #: mediagoblin/templates/mediagoblin/media_displays/audio.html:56 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:65 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:136 #: mediagoblin/templates/mediagoblin/media_displays/video.html:55 msgid "Download" @@ -708,6 +751,7 @@ msgid "" msgstr "Pots obtenir un navegador web modern que \n »podrà reproduir l'à udio, a <a href=\"http://getfirefox.com\">\n » http://getfirefox.com</a>!" #: mediagoblin/templates/mediagoblin/media_displays/audio.html:60 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:71 #: mediagoblin/templates/mediagoblin/media_displays/video.html:61 msgid "Original file" msgstr "Arxiu original" @@ -716,6 +760,7 @@ msgstr "Arxiu original" msgid "WebM file (Vorbis codec)" msgstr "Arxiu WebM (Vorbis codec)" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:59 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:87 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:93 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:99 @@ -726,6 +771,10 @@ msgstr "Arxiu WebM (Vorbis codec)" msgid "Image for %(media_title)s" msgstr "Imatge per %(media_title)s" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 +msgid "PDF file" +msgstr "" + #: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 msgid "Toggle Rotate" msgstr "" @@ -824,7 +873,7 @@ msgstr "Realment vols esborrar %(title)s?" msgid "Really remove %(media_title)s from %(collection_title)s?" msgstr "Relment eliminar %(media_title)s de %(collection_title)s?" -#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:54 msgid "Remove" msgstr "Eliminar" @@ -867,24 +916,28 @@ msgstr "<a href=\"%(user_url)s\">%(username)s</a>'s media" msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>" msgstr "â– Navegant mitjà per a <a href=\"%(user_url)s\">%(username)s</a>" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:94 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:95 msgid "Add a comment" msgstr "Afegeix un comentari" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 msgid "Add this comment" msgstr "Afegir aquest comentari" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:123 -msgid "at" -msgstr "a" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:144 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:132 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:152 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:164 #, python-format -msgid "" -"<h3>Added on</h3>\n" -" <p>%(date)s</p>" -msgstr "<h3>Afegit el</h3>\n <p>%(date)s</p>" +msgid "%(formatted_time)s ago" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:150 +msgid "Added" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:161 +msgid "Created" +msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:40 @@ -1040,7 +1093,7 @@ msgstr "més antic" msgid "Tagged with" msgstr "" -#: mediagoblin/tools/exif.py:80 +#: mediagoblin/tools/exif.py:83 msgid "Could not read the image file." msgstr "No s'ha pogut llegir l'arxiu d'imatge" @@ -1070,6 +1123,30 @@ msgid "" " deleted." msgstr "" +#: mediagoblin/tools/timesince.py:62 +msgid "year" +msgstr "" + +#: mediagoblin/tools/timesince.py:63 +msgid "month" +msgstr "" + +#: mediagoblin/tools/timesince.py:64 +msgid "week" +msgstr "" + +#: mediagoblin/tools/timesince.py:65 +msgid "day" +msgstr "" + +#: mediagoblin/tools/timesince.py:66 +msgid "hour" +msgstr "" + +#: mediagoblin/tools/timesince.py:67 +msgid "minute" +msgstr "" + #: mediagoblin/user_pages/forms.py:23 msgid "Comment" msgstr "" @@ -1101,73 +1178,77 @@ msgstr "-- Sel.leccionar --" msgid "Include a note" msgstr "Incluir una nota" -#: mediagoblin/user_pages/lib.py:56 +#: mediagoblin/user_pages/lib.py:58 msgid "commented on your post" msgstr "comentat al teu post" -#: mediagoblin/user_pages/views.py:166 +#: mediagoblin/user_pages/views.py:169 +msgid "Sorry, comments are disabled." +msgstr "" + +#: mediagoblin/user_pages/views.py:174 msgid "Oops, your comment was empty." msgstr "Uups, el teu comentari era buit." -#: mediagoblin/user_pages/views.py:172 +#: mediagoblin/user_pages/views.py:180 msgid "Your comment has been posted!" msgstr "El teu comentari s'ha publicat!" -#: mediagoblin/user_pages/views.py:197 +#: mediagoblin/user_pages/views.py:205 msgid "Please check your entries and try again." msgstr "Si et plau, comprova les teves entrades i intenta-ho de nou." -#: mediagoblin/user_pages/views.py:237 +#: mediagoblin/user_pages/views.py:245 msgid "You have to select or add a collection" msgstr "Has de sel.leccionar o afegir una col.lecció" -#: mediagoblin/user_pages/views.py:248 +#: mediagoblin/user_pages/views.py:256 #, python-format msgid "\"%s\" already in collection \"%s\"" msgstr "\"%s\" ja és a la col.lecció \"%s\"" -#: mediagoblin/user_pages/views.py:264 +#: mediagoblin/user_pages/views.py:262 #, python-format msgid "\"%s\" added to collection \"%s\"" msgstr "\"%s\" afegir a la col.lecció \"%s\"" -#: mediagoblin/user_pages/views.py:286 +#: mediagoblin/user_pages/views.py:282 msgid "You deleted the media." msgstr "Has esborrat el mitjà " -#: mediagoblin/user_pages/views.py:293 +#: mediagoblin/user_pages/views.py:289 msgid "The media was not deleted because you didn't check that you were sure." msgstr "El mitjà no s'ha esborrat perque no has marcat que n'estiguessis segur." -#: mediagoblin/user_pages/views.py:301 +#: mediagoblin/user_pages/views.py:296 msgid "You are about to delete another user's media. Proceed with caution." msgstr "Ets a punt d'esborrar el mitjà d'un altre usuari. Prossegueix amb cautela." -#: mediagoblin/user_pages/views.py:375 +#: mediagoblin/user_pages/views.py:370 msgid "You deleted the item from the collection." msgstr "Has esborrat l'element de la col.lecció" -#: mediagoblin/user_pages/views.py:379 +#: mediagoblin/user_pages/views.py:374 msgid "The item was not removed because you didn't check that you were sure." msgstr "L'element no s'ha eliminat perque no has marcat que n'estiguessis segur." -#: mediagoblin/user_pages/views.py:389 +#: mediagoblin/user_pages/views.py:382 msgid "" "You are about to delete an item from another user's collection. Proceed with" " caution." msgstr "Ets a punt d'esborrar un element de la col.lecció d'un altre usuari. Prossegueix amb cautela." -#: mediagoblin/user_pages/views.py:422 +#: mediagoblin/user_pages/views.py:415 #, python-format msgid "You deleted the collection \"%s\"" msgstr "Has esborrat la col.lecció \"%s\"" -#: mediagoblin/user_pages/views.py:429 +#: mediagoblin/user_pages/views.py:422 msgid "" "The collection was not deleted because you didn't check that you were sure." msgstr "La col.lecció no s'ha esborrat perquè no has marcat que n'estiguessis segur." -#: mediagoblin/user_pages/views.py:439 +#: mediagoblin/user_pages/views.py:430 msgid "" "You are about to delete another user's collection. Proceed with caution." msgstr "Ets a punt d'esborrar la col.lecció d'un altre usuari. Prossegueix amb cautela." diff --git a/mediagoblin/i18n/da/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/da/LC_MESSAGES/mediagoblin.mo Binary files differindex 6b6827f0..53e3fedf 100644 --- a/mediagoblin/i18n/da/LC_MESSAGES/mediagoblin.mo +++ b/mediagoblin/i18n/da/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/da/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/da/LC_MESSAGES/mediagoblin.po index 8494aa60..c78c08ac 100644 --- a/mediagoblin/i18n/da/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/da/LC_MESSAGES/mediagoblin.po @@ -3,17 +3,17 @@ # 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. -# Tanja Trudslev <tanja.trudslev@gmail.com>, 2012. +# Morten Juhl-Johansen Zölde-Fejér <morten@writtenandread.net>, 2012 +# Olle Jonsson <olle.jonsson@gmail.com>, 2012 +# ttrudslev <tanja.trudslev@gmail.com>, 2012 msgid "" msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" -"POT-Creation-Date: 2013-03-04 18:04-0600\n" -"PO-Revision-Date: 2013-03-05 00:04+0000\n" +"POT-Creation-Date: 2013-05-27 13:54-0500\n" +"PO-Revision-Date: 2013-05-27 18:54+0000\n" "Last-Translator: cwebber <cwebber@dustycloud.org>\n" -"Language-Team: LANGUAGE <LL@li.org>\n" +"Language-Team: Danish (http://www.transifex.com/projects/p/mediagoblin/language/da/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -21,34 +21,39 @@ msgstr "" "Language: da\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: mediagoblin/auth/forms.py:28 -msgid "Invalid User name or email address." -msgstr "" - -#: mediagoblin/auth/forms.py:29 -msgid "This field does not take email addresses." -msgstr "" - -#: mediagoblin/auth/forms.py:30 -msgid "This field requires an email address." -msgstr "" - -#: mediagoblin/auth/forms.py:52 mediagoblin/auth/forms.py:67 +#: mediagoblin/auth/forms.py:26 msgid "Username" msgstr "Brugernavn" -#: mediagoblin/auth/forms.py:56 mediagoblin/auth/forms.py:71 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 +#: mediagoblin/tests/test_util.py:110 msgid "Password" msgstr "Kodeord" -#: mediagoblin/auth/forms.py:60 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "Email adresse" -#: mediagoblin/auth/forms.py:78 +#: mediagoblin/auth/forms.py:41 +msgid "Username or Email" +msgstr "" + +#: mediagoblin/auth/forms.py:52 msgid "Username or email" msgstr "Brugernavn eller email" +#: mediagoblin/auth/tools.py:31 +msgid "Invalid User name or email address." +msgstr "" + +#: mediagoblin/auth/tools.py:32 +msgid "This field does not take email addresses." +msgstr "" + +#: mediagoblin/auth/tools.py:33 +msgid "This field requires an email address." +msgstr "" + #: mediagoblin/auth/views.py:54 msgid "Sorry, registration is disabled on this instance." msgstr "Desværre, registrering er ikke muligt pÃ¥ denne instans" @@ -61,54 +66,54 @@ msgstr "Desværre, det brugernavn er allerede brugt" msgid "Sorry, a user with that email address already exists." msgstr "Desværre, en bruger er allerede oprettet for den email" -#: mediagoblin/auth/views.py:174 +#: mediagoblin/auth/views.py:182 msgid "" "Your email address has been verified. You may now login, edit your profile, " "and submit images!" msgstr "Din email adresse er blevet bekræftet. Du kan nu logge pÃ¥, ændre din profil, og indsende billeder!" -#: mediagoblin/auth/views.py:180 +#: mediagoblin/auth/views.py:188 msgid "The verification key or user id is incorrect" msgstr "Bekræftelsesnøglen eller brugerid er forkert" -#: mediagoblin/auth/views.py:198 +#: mediagoblin/auth/views.py:206 msgid "You must be logged in so we know who to send the email to!" msgstr "Du er nødt til at være logget ind, sÃ¥ vi ved hvem vi skal emaile!" -#: mediagoblin/auth/views.py:206 +#: mediagoblin/auth/views.py:214 msgid "You've already verified your email address!" msgstr "Du har allerede bekræftet din email adresse!" -#: mediagoblin/auth/views.py:219 +#: mediagoblin/auth/views.py:227 msgid "Resent your verification email." msgstr "Email til godkendelse sendt igen." -#: mediagoblin/auth/views.py:250 +#: mediagoblin/auth/views.py:258 msgid "" "If that email address (case sensitive!) is registered an email has been sent" " with instructions on how to change your password." msgstr "" -#: mediagoblin/auth/views.py:261 +#: mediagoblin/auth/views.py:269 msgid "Couldn't find someone with that username." msgstr "" -#: mediagoblin/auth/views.py:264 +#: mediagoblin/auth/views.py:272 msgid "" "An email has been sent with instructions on how to change your password." msgstr "En email er blevet sendt med instruktioner til at ændre dit kodeord." -#: mediagoblin/auth/views.py:271 +#: mediagoblin/auth/views.py:279 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." msgstr "Vi kunne ikke sende en kodeords nulstillings email da dit brugernavn er inaktivt, eller din konto's email adresse er ikke blevet godkendt." -#: mediagoblin/auth/views.py:328 +#: mediagoblin/auth/views.py:336 msgid "You can now log in using your new password." msgstr "Du kan nu logge ind med dit nye kodeord." -#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:93 +#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:82 #: mediagoblin/submit/forms.py:28 mediagoblin/submit/forms.py:47 #: mediagoblin/user_pages/forms.py:45 msgid "Title" @@ -119,7 +124,7 @@ msgid "Description of this work" msgstr "Beskrivelse af arbejdet" #: mediagoblin/edit/forms.py:29 mediagoblin/edit/forms.py:52 -#: mediagoblin/edit/forms.py:97 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:86 mediagoblin/submit/forms.py:32 #: mediagoblin/submit/forms.py:51 mediagoblin/user_pages/forms.py:49 msgid "" "You can use\n" @@ -135,11 +140,11 @@ msgstr "Tags" msgid "Separate tags by commas." msgstr "Separer tags med kommaer." -#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:101 +#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:90 msgid "Slug" msgstr "" -#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:102 +#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:91 msgid "The slug can't be empty" msgstr "" @@ -167,45 +172,45 @@ msgid "This address contains errors" msgstr "Denne adresse indeholder fejl" #: mediagoblin/edit/forms.py:63 -msgid "Old password" -msgstr "Gammelt kodeord" - -#: mediagoblin/edit/forms.py:64 -msgid "Enter your old password to prove you own this account." -msgstr "Skriv dit gamle kodeord for at bevise det er din konto." - -#: mediagoblin/edit/forms.py:67 -msgid "New password" -msgstr "Ny kodeord" - -#: mediagoblin/edit/forms.py:74 msgid "License preference" msgstr "" -#: mediagoblin/edit/forms.py:80 +#: mediagoblin/edit/forms.py:69 msgid "This will be your default license on upload forms." msgstr "" -#: mediagoblin/edit/forms.py:82 +#: mediagoblin/edit/forms.py:71 msgid "Email me when others comment on my media" msgstr "Email mig nÃ¥r andre kommenterer pÃ¥ mine medier" -#: mediagoblin/edit/forms.py:94 +#: mediagoblin/edit/forms.py:83 msgid "The title can't be empty" msgstr "Titlen kan ikke være tom" -#: mediagoblin/edit/forms.py:96 mediagoblin/submit/forms.py:50 +#: mediagoblin/edit/forms.py:85 mediagoblin/submit/forms.py:50 #: mediagoblin/user_pages/forms.py:48 msgid "Description of this collection" msgstr "Beskrivelse af denne samling" -#: mediagoblin/edit/forms.py:103 +#: mediagoblin/edit/forms.py:92 msgid "" "The title part of this collection's address. You usually don't need to " "change this." msgstr "Titeldelen af denne samlings's adresse. Du behøver normalt ikke ændre dette." -#: mediagoblin/edit/views.py:66 +#: mediagoblin/edit/forms.py:99 +msgid "Old password" +msgstr "Gammelt kodeord" + +#: mediagoblin/edit/forms.py:101 +msgid "Enter your old password to prove you own this account." +msgstr "Skriv dit gamle kodeord for at bevise det er din konto." + +#: mediagoblin/edit/forms.py:104 +msgid "New password" +msgstr "Ny kodeord" + +#: mediagoblin/edit/views.py:67 msgid "An entry with that slug already exists for this user." msgstr "" @@ -230,44 +235,63 @@ msgstr "Du er ved at ændre en bruger's profil. Pas pÃ¥." msgid "Profile changes saved" msgstr "Profilændringer gemt" -#: mediagoblin/edit/views.py:241 -msgid "Wrong password" -msgstr "Forkert kodeord" - -#: mediagoblin/edit/views.py:252 +#: mediagoblin/edit/views.py:240 msgid "Account settings saved" msgstr "Kontoindstillinger gemt" -#: mediagoblin/edit/views.py:286 +#: mediagoblin/edit/views.py:274 msgid "You need to confirm the deletion of your account." msgstr "" -#: mediagoblin/edit/views.py:322 mediagoblin/submit/views.py:142 -#: mediagoblin/user_pages/views.py:214 +#: mediagoblin/edit/views.py:310 mediagoblin/submit/views.py:138 +#: mediagoblin/user_pages/views.py:222 #, python-format msgid "You already have a collection called \"%s\"!" msgstr "Du har allerede en samling ved navn \"%s\"!" -#: mediagoblin/edit/views.py:326 +#: mediagoblin/edit/views.py:314 msgid "A collection with that slug already exists for this user." msgstr "" -#: mediagoblin/edit/views.py:343 +#: mediagoblin/edit/views.py:329 msgid "You are editing another user's collection. Proceed with caution." msgstr "Du er ved at ændre en anden bruger's samling. Pas pÃ¥." -#: mediagoblin/gmg_commands/theme.py:58 +#: mediagoblin/edit/views.py:348 +msgid "Wrong password" +msgstr "Forkert kodeord" + +#: mediagoblin/edit/views.py:363 +msgid "Your password was changed successfully" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:60 msgid "Cannot link theme... no theme set\n" msgstr "Kan ikke linke til tema... intet tema sat\n" -#: mediagoblin/gmg_commands/theme.py:71 +#: mediagoblin/gmg_commands/assetlink.py:73 msgid "No asset directory for this theme\n" msgstr "" -#: mediagoblin/gmg_commands/theme.py:74 +#: mediagoblin/gmg_commands/assetlink.py:76 msgid "However, old link directory symlink found; removed.\n" msgstr "" +#: mediagoblin/gmg_commands/assetlink.py:112 +#, python-format +msgid "Could not link \"%s\": %s exists and is not a symlink\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:119 +#, python-format +msgid "Skipping \"%s\"; already set up.\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:124 +#, python-format +msgid "Old link found for \"%s\"; removing.\n" +msgstr "" + #: mediagoblin/meddleware/csrf.py:134 msgid "" "CSRF cookie not present. This is most likely the result of a cookie blocker " @@ -275,12 +299,16 @@ msgid "" "domain." msgstr "" -#: mediagoblin/media_types/__init__.py:61 -#: mediagoblin/media_types/__init__.py:102 +#: mediagoblin/media_types/__init__.py:111 +#: mediagoblin/media_types/__init__.py:155 msgid "Sorry, I don't support that file type :(" msgstr "Desværre, jeg understøtter ikke den filtype :(" -#: mediagoblin/media_types/video/processing.py:36 +#: mediagoblin/media_types/pdf/processing.py:136 +msgid "unoconv failing to run, check log file" +msgstr "" + +#: mediagoblin/media_types/video/processing.py:37 msgid "Video transcoding failed" msgstr "" @@ -347,7 +375,7 @@ msgstr "" msgid "This field is required for public clients" msgstr "Dette felt er nødvendigt for offentlige klienter" -#: mediagoblin/plugins/oauth/views.py:59 +#: mediagoblin/plugins/oauth/views.py:56 msgid "The client {0} has been registered!" msgstr "Klienten {0} er blevet registreret!" @@ -366,7 +394,7 @@ msgstr "" msgid "Add" msgstr "" -#: mediagoblin/processing/__init__.py:172 +#: mediagoblin/processing/__init__.py:193 msgid "Invalid file given for media type." msgstr "Forkert fil for medietypen." @@ -374,45 +402,45 @@ msgstr "Forkert fil for medietypen." msgid "File" msgstr "Fil" -#: mediagoblin/submit/views.py:51 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "Du mÃ¥ give mig en fil" -#: mediagoblin/submit/views.py:97 +#: mediagoblin/submit/views.py:93 msgid "Woohoo! Submitted!" msgstr "Juhuu! Delt!" -#: mediagoblin/submit/views.py:146 +#: mediagoblin/submit/views.py:144 #, python-format msgid "Collection \"%s\" added!" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:64 +#: mediagoblin/templates/mediagoblin/base.html:67 msgid "Verify your email!" msgstr "Bekræft din email!" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:68 msgid "log out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:70 +#: mediagoblin/templates/mediagoblin/base.html:73 #: mediagoblin/templates/mediagoblin/auth/login.html:28 #: mediagoblin/templates/mediagoblin/auth/login.html:36 #: mediagoblin/templates/mediagoblin/auth/login.html:54 msgid "Log in" msgstr "Log ind" -#: mediagoblin/templates/mediagoblin/base.html:79 +#: mediagoblin/templates/mediagoblin/base.html:82 #, python-format msgid "<a href=\"%(user_url)s\">%(user_name)s</a>'s account" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:86 +#: mediagoblin/templates/mediagoblin/base.html:89 msgid "Change account settings" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:90 -#: mediagoblin/templates/mediagoblin/base.html:105 +#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:108 #: mediagoblin/templates/mediagoblin/admin/panel.html:21 #: mediagoblin/templates/mediagoblin/admin/panel.html:26 #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:21 @@ -420,72 +448,25 @@ msgstr "" msgid "Media processing panel" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:96 msgid "Log out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:96 +#: mediagoblin/templates/mediagoblin/base.html:99 #: mediagoblin/templates/mediagoblin/user_pages/user.html:156 msgid "Add media" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:99 +#: mediagoblin/templates/mediagoblin/base.html:102 #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:41 msgid "Create new collection" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:122 -#, python-format -msgid "" -"Powered by <a href=\"http://mediagoblin.org/\" title='Version " -"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." -msgstr "" - -#: mediagoblin/templates/mediagoblin/base.html:125 -#, 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/error.html:24 msgid "Image of goblin stressing out" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:31 -msgid "Explore" -msgstr "Udforsk" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "Hey, velkommen til denne MediaGoblin side!" - -#: mediagoblin/templates/mediagoblin/root.html:35 -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:36 -msgid "" -"To add your own media, place comments, and more, you can log in with your " -"MediaGoblin account." -msgstr "For at tilføje dine egne medier, skrive kommentarer, og mere, du kan logge ind med din MediaGoblin konto." - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Don't have one yet? It's easy!" -msgstr "Har du ikke en endnu? Det er let!" - -#: mediagoblin/templates/mediagoblin/root.html:39 -#, 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:47 +#: mediagoblin/templates/mediagoblin/root.html:32 msgid "Most recent media" msgstr "" @@ -591,6 +572,53 @@ msgid "" "%(verification_url)s" msgstr "" +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:21 +#, python-format +msgid "" +"Powered by <a href=\"http://mediagoblin.org/\" title='Version " +"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:24 +#, 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/bits/frontpage_welcome.html:20 +msgid "Explore" +msgstr "Udforsk" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:22 +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "Hey, velkommen til denne MediaGoblin side!" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:24 +msgid "" +"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, an " +"extraordinarily great piece of media hosting software." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:25 +msgid "" +"To add your own media, place comments, and more, you can log in with your " +"MediaGoblin account." +msgstr "For at tilføje dine egne medier, skrive kommentarer, og mere, du kan logge ind med din MediaGoblin konto." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:27 +msgid "Don't have one yet? It's easy!" +msgstr "Har du ikke en endnu? Det er let!" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:28 +#, 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/bits/logo.html:23 #: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 msgid "MediaGoblin logo" @@ -603,13 +631,13 @@ msgid "Editing attachments for %(media_title)s" msgstr "" #: mediagoblin/templates/mediagoblin/edit/attachments.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:159 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:175 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:182 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:198 msgid "Attachments" msgstr "" #: mediagoblin/templates/mediagoblin/edit/attachments.html:57 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:181 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:204 msgid "Add attachment" msgstr "" @@ -626,12 +654,22 @@ msgstr "Afbryd" #: mediagoblin/templates/mediagoblin/edit/attachments.html:63 #: mediagoblin/templates/mediagoblin/edit/edit.html:42 -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:52 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:55 #: mediagoblin/templates/mediagoblin/edit/edit_collection.html:33 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:40 msgid "Save changes" msgstr "Gem ændringer" +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:28 +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 +#, python-format +msgid "Changing %(username)s's password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 +msgid "Save" +msgstr "" + #: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 #, python-format msgid "Really delete user '%(user_name)s' and all related media/comments?" @@ -642,7 +680,7 @@ msgid "Yes, really delete my account" msgstr "" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:48 #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49 msgid "Delete permanently" msgstr "" @@ -659,7 +697,11 @@ msgstr "" msgid "Changing %(username)s's account settings" msgstr "" -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:59 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 +msgid "Change your password." +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 msgid "Delete my account" msgstr "" @@ -684,6 +726,7 @@ msgstr "" #: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 #: mediagoblin/templates/mediagoblin/media_displays/audio.html:56 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:65 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:136 #: mediagoblin/templates/mediagoblin/media_displays/video.html:55 msgid "Download" @@ -708,6 +751,7 @@ msgid "" msgstr "" #: mediagoblin/templates/mediagoblin/media_displays/audio.html:60 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:71 #: mediagoblin/templates/mediagoblin/media_displays/video.html:61 msgid "Original file" msgstr "" @@ -716,6 +760,7 @@ msgstr "" msgid "WebM file (Vorbis codec)" msgstr "" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:59 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:87 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:93 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:99 @@ -726,6 +771,10 @@ msgstr "" msgid "Image for %(media_title)s" msgstr "" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 +msgid "PDF file" +msgstr "" + #: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 msgid "Toggle Rotate" msgstr "" @@ -824,7 +873,7 @@ msgstr "" msgid "Really remove %(media_title)s from %(collection_title)s?" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:54 msgid "Remove" msgstr "" @@ -867,23 +916,27 @@ msgstr "" msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:94 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:95 msgid "Add a comment" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 msgid "Add this comment" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:123 -msgid "at" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:132 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:152 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:164 +#, python-format +msgid "%(formatted_time)s ago" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:144 -#, python-format -msgid "" -"<h3>Added on</h3>\n" -" <p>%(date)s</p>" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:150 +msgid "Added" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:161 +msgid "Created" msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 @@ -1040,7 +1093,7 @@ msgstr "" msgid "Tagged with" msgstr "" -#: mediagoblin/tools/exif.py:80 +#: mediagoblin/tools/exif.py:83 msgid "Could not read the image file." msgstr "" @@ -1070,6 +1123,30 @@ msgid "" " deleted." msgstr "" +#: mediagoblin/tools/timesince.py:62 +msgid "year" +msgstr "" + +#: mediagoblin/tools/timesince.py:63 +msgid "month" +msgstr "" + +#: mediagoblin/tools/timesince.py:64 +msgid "week" +msgstr "" + +#: mediagoblin/tools/timesince.py:65 +msgid "day" +msgstr "" + +#: mediagoblin/tools/timesince.py:66 +msgid "hour" +msgstr "" + +#: mediagoblin/tools/timesince.py:67 +msgid "minute" +msgstr "" + #: mediagoblin/user_pages/forms.py:23 msgid "Comment" msgstr "" @@ -1101,73 +1178,77 @@ msgstr "" msgid "Include a note" msgstr "" -#: mediagoblin/user_pages/lib.py:56 +#: mediagoblin/user_pages/lib.py:58 msgid "commented on your post" msgstr "" -#: mediagoblin/user_pages/views.py:166 +#: mediagoblin/user_pages/views.py:169 +msgid "Sorry, comments are disabled." +msgstr "" + +#: mediagoblin/user_pages/views.py:174 msgid "Oops, your comment was empty." msgstr "" -#: mediagoblin/user_pages/views.py:172 +#: mediagoblin/user_pages/views.py:180 msgid "Your comment has been posted!" msgstr "" -#: mediagoblin/user_pages/views.py:197 +#: mediagoblin/user_pages/views.py:205 msgid "Please check your entries and try again." msgstr "" -#: mediagoblin/user_pages/views.py:237 +#: mediagoblin/user_pages/views.py:245 msgid "You have to select or add a collection" msgstr "" -#: mediagoblin/user_pages/views.py:248 +#: mediagoblin/user_pages/views.py:256 #, python-format msgid "\"%s\" already in collection \"%s\"" msgstr "" -#: mediagoblin/user_pages/views.py:264 +#: mediagoblin/user_pages/views.py:262 #, python-format msgid "\"%s\" added to collection \"%s\"" msgstr "" -#: mediagoblin/user_pages/views.py:286 +#: mediagoblin/user_pages/views.py:282 msgid "You deleted the media." msgstr "" -#: mediagoblin/user_pages/views.py:293 +#: mediagoblin/user_pages/views.py:289 msgid "The media was not deleted because you didn't check that you were sure." msgstr "" -#: mediagoblin/user_pages/views.py:301 +#: mediagoblin/user_pages/views.py:296 msgid "You are about to delete another user's media. Proceed with caution." msgstr "" -#: mediagoblin/user_pages/views.py:375 +#: mediagoblin/user_pages/views.py:370 msgid "You deleted the item from the collection." msgstr "" -#: mediagoblin/user_pages/views.py:379 +#: mediagoblin/user_pages/views.py:374 msgid "The item was not removed because you didn't check that you were sure." msgstr "" -#: mediagoblin/user_pages/views.py:389 +#: mediagoblin/user_pages/views.py:382 msgid "" "You are about to delete an item from another user's collection. Proceed with" " caution." msgstr "" -#: mediagoblin/user_pages/views.py:422 +#: mediagoblin/user_pages/views.py:415 #, python-format msgid "You deleted the collection \"%s\"" msgstr "" -#: mediagoblin/user_pages/views.py:429 +#: mediagoblin/user_pages/views.py:422 msgid "" "The collection was not deleted because you didn't check that you were sure." msgstr "" -#: mediagoblin/user_pages/views.py:439 +#: mediagoblin/user_pages/views.py:430 msgid "" "You are about to delete another user's collection. Proceed with caution." msgstr "" diff --git a/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.mo Binary files differindex 5ae794fa..e2fcf85d 100644 --- a/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.mo +++ b/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.po index b3d82ee9..e2147070 100644 --- a/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.po @@ -3,26 +3,26 @@ # This file is distributed under the same license as the PROJECT project. # # Translators: -# <benjamin@lebsanft.org>, 2011. -# <cwebber@dustycloud.org>, 2011. -# Elrond <elrond+mediagoblin.org@samba-tng.org>, 2011-2012. -# Elrond <elrond+mediagoblin.org@samba-tng.org>, 2013. -# <jakob.kramer@gmx.de>, 2011, 2012. -# Jakob Kramer <jakob.kramer@gmx.de>, 2012-2013. -# Jan-Christoph Borchardt <JanCBorchardt@fsfe.org>, 2011. -# Jan-Christoph Borchardt <jan@unhosted.org>, 2011, 2012. -# <kyoo@kyoo.ch>, 2011. -# <mediagoblin.org@samba-tng.org>, 2011. -# Rafael Maguiña <rafael.maguina@gmail.com>, 2011. -# <sebastian@sspaeth.de>, 2012. -# Vinzenz Vietzke <vietzke@b1-systems.de>, 2012. -# Vinzenz Vietzke <vinz@fedoraproject.org>, 2011. +# piratenpanda <benjamin@lebsanft.org>, 2011 +# cwebber <cwebber@dustycloud.org>, 2011 +# Elrond <elrond+mediagoblin.org@samba-tng.org>, 2011-2012 +# Elrond <elrond+mediagoblin.org@samba-tng.org>, 2013 +# Jakob Kramer <jakob.kramer@gmx.de>, 2011, 2012 +# Jakob Kramer <jakob.kramer@gmx.de>, 2012-2013 +# Jan-Christoph Borchardt <hey@jancborchardt.net>, 2011 +# Jan-Christoph Borchardt <hey@jancborchardt.net>, 2011, 2012 +# Keyzo <kyoo@kyoo.ch>, 2011 +# Elrond <elrond+mediagoblin.org@samba-tng.org>, 2011 +# Art O. Pal <artopal@fastmail.fm>, 2011 +# spaetz <sebastian@sspaeth.de>, 2012 +# Vinzenz Vietzke <vinz@vinzv.de>, 2012 +# Vinzenz Vietzke <vinz@vinzv.de>, 2011 msgid "" msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" -"POT-Creation-Date: 2013-03-04 18:04-0600\n" -"PO-Revision-Date: 2013-03-07 13:16+0000\n" +"POT-Creation-Date: 2013-05-27 13:54-0500\n" +"PO-Revision-Date: 2013-05-28 10:43+0000\n" "Last-Translator: Elrond <elrond+mediagoblin.org@samba-tng.org>\n" "Language-Team: German (http://www.transifex.com/projects/p/mediagoblin/language/de/)\n" "MIME-Version: 1.0\n" @@ -32,34 +32,39 @@ msgstr "" "Language: de\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: mediagoblin/auth/forms.py:28 -msgid "Invalid User name or email address." -msgstr "Ungültiger Benutzername oder E-Mail-Adresse." - -#: mediagoblin/auth/forms.py:29 -msgid "This field does not take email addresses." -msgstr "Dieses Feld akzeptiert keine E-Mail-Adressen." - -#: mediagoblin/auth/forms.py:30 -msgid "This field requires an email address." -msgstr "Dieses Feld benötigt eine E-Mail-Adresse." - -#: mediagoblin/auth/forms.py:52 mediagoblin/auth/forms.py:67 +#: mediagoblin/auth/forms.py:26 msgid "Username" msgstr "Benutzername" -#: mediagoblin/auth/forms.py:56 mediagoblin/auth/forms.py:71 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 +#: mediagoblin/tests/test_util.py:110 msgid "Password" msgstr "Passwort" -#: mediagoblin/auth/forms.py:60 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "E-Mail-Adresse" -#: mediagoblin/auth/forms.py:78 +#: mediagoblin/auth/forms.py:41 +msgid "Username or Email" +msgstr "Benutzername oder E-Mail-Adresse" + +#: mediagoblin/auth/forms.py:52 msgid "Username or email" msgstr "Benutzername oder E-Mail-Adresse" +#: mediagoblin/auth/tools.py:31 +msgid "Invalid User name or email address." +msgstr "Ungültiger Benutzername oder E-Mail-Adresse." + +#: mediagoblin/auth/tools.py:32 +msgid "This field does not take email addresses." +msgstr "Dieses Feld akzeptiert keine E-Mail-Adressen." + +#: mediagoblin/auth/tools.py:33 +msgid "This field requires an email address." +msgstr "Dieses Feld benötigt eine E-Mail-Adresse." + #: mediagoblin/auth/views.py:54 msgid "Sorry, registration is disabled on this instance." msgstr "Benutzerregistrierung ist auf diesem Server leider deaktiviert." @@ -72,54 +77,54 @@ msgstr "Leider gibt es bereits einen Benutzer mit diesem Namen." msgid "Sorry, a user with that email address already exists." msgstr "Leider gibt es bereits einen Benutzer mit dieser E-Mail-Adresse." -#: mediagoblin/auth/views.py:174 +#: mediagoblin/auth/views.py:182 msgid "" "Your email address has been verified. You may now login, edit your profile, " "and submit images!" msgstr "Dein GNU MediaGoblin Konto wurde hiermit aktiviert. Du kannst dich jetzt anmelden, dein Profil bearbeiten und Medien hochladen." -#: mediagoblin/auth/views.py:180 +#: mediagoblin/auth/views.py:188 msgid "The verification key or user id is incorrect" msgstr "Der Aktivierungsschlüssel oder die Nutzerkennung ist falsch." -#: mediagoblin/auth/views.py:198 +#: 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:206 +#: mediagoblin/auth/views.py:214 msgid "You've already verified your email address!" msgstr "Deine E-Mail-Adresse wurde bereits aktiviert." -#: mediagoblin/auth/views.py:219 +#: mediagoblin/auth/views.py:227 msgid "Resent your verification email." msgstr "Aktivierungsmail wurde erneut versandt." -#: mediagoblin/auth/views.py:250 +#: mediagoblin/auth/views.py:258 msgid "" "If that email address (case sensitive!) is registered an email has been sent" " with instructions on how to change your password." msgstr "Falls jemand mit dieser E-Mail-Adresse (Groß- und Kleinschreibung wird unterschieden!) registriert ist, wurde eine E-Mail mit Anleitungen verschickt, wie Du Dein Passwort ändern kannst." -#: mediagoblin/auth/views.py:261 +#: mediagoblin/auth/views.py:269 msgid "Couldn't find someone with that username." msgstr "Es konnte niemand mit diesem Benutzernamen gefunden werden." -#: mediagoblin/auth/views.py:264 +#: mediagoblin/auth/views.py:272 msgid "" "An email has been sent with instructions on how to change your password." msgstr "Es wurde eine E-Mail mit der Anleitung zur Änderung des Passwortes an Dich gesendet." -#: mediagoblin/auth/views.py:271 +#: mediagoblin/auth/views.py:279 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." msgstr "Die E-Mail zur Wiederherstellung des Passworts konnte nicht verschickt werden, weil dein Benutzername inaktiv oder deine E-Mail-Adresse noch nicht aktiviert wurde." -#: mediagoblin/auth/views.py:328 +#: mediagoblin/auth/views.py:336 msgid "You can now log in using your new password." msgstr "Du kannst dich jetzt mit deinem neuen Passwort anmelden." -#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:93 +#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:82 #: mediagoblin/submit/forms.py:28 mediagoblin/submit/forms.py:47 #: mediagoblin/user_pages/forms.py:45 msgid "Title" @@ -130,7 +135,7 @@ msgid "Description of this work" msgstr "Beschreibung des Werkes" #: mediagoblin/edit/forms.py:29 mediagoblin/edit/forms.py:52 -#: mediagoblin/edit/forms.py:97 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:86 mediagoblin/submit/forms.py:32 #: mediagoblin/submit/forms.py:51 mediagoblin/user_pages/forms.py:49 msgid "" "You can use\n" @@ -146,11 +151,11 @@ msgstr "Schlagwörter" msgid "Separate tags by commas." msgstr "Kommaseparierte Schlagwörter" -#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:101 +#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:90 msgid "Slug" msgstr "Kurztitel" -#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:102 +#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:91 msgid "The slug can't be empty" msgstr "Bitte gib einen Kurztitel ein" @@ -178,45 +183,45 @@ 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:64 -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." - -#: mediagoblin/edit/forms.py:67 -msgid "New password" -msgstr "Neues Passwort" - -#: mediagoblin/edit/forms.py:74 msgid "License preference" msgstr "Bevorzugte Lizenz" -#: mediagoblin/edit/forms.py:80 +#: mediagoblin/edit/forms.py:69 msgid "This will be your default license on upload forms." msgstr "Dies wird Deine Standardlizenz in den Upload-Forumularen sein." -#: mediagoblin/edit/forms.py:82 +#: mediagoblin/edit/forms.py:71 msgid "Email me when others comment on my media" msgstr "Mir eine E-Mail schicken, wenn andere meine Medien kommentieren" -#: mediagoblin/edit/forms.py:94 +#: mediagoblin/edit/forms.py:83 msgid "The title can't be empty" msgstr "Der Titel kann nicht leer sein" -#: mediagoblin/edit/forms.py:96 mediagoblin/submit/forms.py:50 +#: mediagoblin/edit/forms.py:85 mediagoblin/submit/forms.py:50 #: mediagoblin/user_pages/forms.py:48 msgid "Description of this collection" msgstr "Beschreibung dieser Sammlung" -#: mediagoblin/edit/forms.py:103 +#: mediagoblin/edit/forms.py:92 msgid "" "The title part of this collection's address. You usually don't need to " "change this." msgstr "Der Titelteil dieser Sammlungsadresse. Du musst ihn normalerweise nicht ändern." -#: mediagoblin/edit/views.py:66 +#: mediagoblin/edit/forms.py:99 +msgid "Old password" +msgstr "Altes Passwort" + +#: mediagoblin/edit/forms.py:101 +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." + +#: mediagoblin/edit/forms.py:104 +msgid "New password" +msgstr "Neues Passwort" + +#: mediagoblin/edit/views.py:67 msgid "An entry with that slug already exists for this user." msgstr "Diesen Kurztitel hast du bereits vergeben." @@ -241,44 +246,63 @@ msgstr "Du bearbeitest das Profil eines anderen Nutzers. Sei bitte vorsichtig." msgid "Profile changes saved" msgstr "Das Profil wurde aktualisiert" -#: mediagoblin/edit/views.py:241 -msgid "Wrong password" -msgstr "Falsches Passwort" - -#: mediagoblin/edit/views.py:252 +#: mediagoblin/edit/views.py:240 msgid "Account settings saved" msgstr "Kontoeinstellungen gespeichert" -#: mediagoblin/edit/views.py:286 +#: mediagoblin/edit/views.py:274 msgid "You need to confirm the deletion of your account." msgstr "Du musst die Löschung deines Kontos bestätigen." -#: mediagoblin/edit/views.py:322 mediagoblin/submit/views.py:142 -#: mediagoblin/user_pages/views.py:214 +#: mediagoblin/edit/views.py:310 mediagoblin/submit/views.py:138 +#: mediagoblin/user_pages/views.py:222 #, python-format msgid "You already have a collection called \"%s\"!" msgstr "Du hast bereits eine Sammlung mit Namen »%s«!" -#: mediagoblin/edit/views.py:326 +#: mediagoblin/edit/views.py:314 msgid "A collection with that slug already exists for this user." msgstr "Eine Sammlung mit diesem Kurztitel existiert bereits für diesen Benutzer." -#: mediagoblin/edit/views.py:343 +#: mediagoblin/edit/views.py:329 msgid "You are editing another user's collection. Proceed with caution." msgstr "Du bearbeitest die Sammlung eines anderen Benutzers. Sei vorsichtig." -#: mediagoblin/gmg_commands/theme.py:58 +#: mediagoblin/edit/views.py:348 +msgid "Wrong password" +msgstr "Falsches Passwort" + +#: mediagoblin/edit/views.py:363 +msgid "Your password was changed successfully" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:60 msgid "Cannot link theme... no theme set\n" msgstr "Theme kann nicht verknüpft werden … Kein Theme gesetzt\n" -#: mediagoblin/gmg_commands/theme.py:71 +#: mediagoblin/gmg_commands/assetlink.py:73 msgid "No asset directory for this theme\n" msgstr "Für dieses Theme gibt es kein asset-Verzeichnis\n" -#: mediagoblin/gmg_commands/theme.py:74 +#: mediagoblin/gmg_commands/assetlink.py:76 msgid "However, old link directory symlink found; removed.\n" msgstr "Trotzdem wurde eine alte Verknüpfung gefunden; sie wurde entfernt\n" +#: mediagoblin/gmg_commands/assetlink.py:112 +#, python-format +msgid "Could not link \"%s\": %s exists and is not a symlink\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:119 +#, python-format +msgid "Skipping \"%s\"; already set up.\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:124 +#, python-format +msgid "Old link found for \"%s\"; removing.\n" +msgstr "" + #: mediagoblin/meddleware/csrf.py:134 msgid "" "CSRF cookie not present. This is most likely the result of a cookie blocker " @@ -286,12 +310,16 @@ msgid "" "domain." msgstr "Das CSRF cookie ist nicht vorhanden. Das liegt vermutlich an einem Cookie-Blocker oder ähnlichem.<br/>Bitte stelle sicher, dass Cookies von dieser Domäne erlaubt sind." -#: mediagoblin/media_types/__init__.py:61 -#: mediagoblin/media_types/__init__.py:102 +#: mediagoblin/media_types/__init__.py:111 +#: mediagoblin/media_types/__init__.py:155 msgid "Sorry, I don't support that file type :(" msgstr "Entschuldigung, dieser Dateityp wird nicht unterstützt." -#: mediagoblin/media_types/video/processing.py:36 +#: mediagoblin/media_types/pdf/processing.py:136 +msgid "unoconv failing to run, check log file" +msgstr "" + +#: mediagoblin/media_types/video/processing.py:37 msgid "Video transcoding failed" msgstr "Videokonvertierung fehlgeschlagen" @@ -358,17 +386,17 @@ msgstr "Die Weiterleitungs-URI für die Anwendung, dieses Feld\n ist msgid "This field is required for public clients" msgstr "Dieses Feld ist Pflicht für öffentliche Clients" -#: mediagoblin/plugins/oauth/views.py:59 +#: mediagoblin/plugins/oauth/views.py:56 msgid "The client {0} has been registered!" msgstr "Client {0} wurde registriert!" #: mediagoblin/plugins/oauth/templates/oauth/client/connections.html:22 msgid "OAuth client connections" -msgstr "" +msgstr "OAuth-Client-Verbindungen" #: mediagoblin/plugins/oauth/templates/oauth/client/list.html:22 msgid "Your OAuth clients" -msgstr "" +msgstr "Deine OAuth-Clients" #: mediagoblin/plugins/oauth/templates/oauth/client/register.html:29 #: mediagoblin/templates/mediagoblin/submit/collection.html:30 @@ -377,7 +405,7 @@ msgstr "" msgid "Add" msgstr "Hinzufügen" -#: mediagoblin/processing/__init__.py:172 +#: mediagoblin/processing/__init__.py:193 msgid "Invalid file given for media type." msgstr "Die Datei stimmt nicht mit dem gewählten Medientyp überein." @@ -385,45 +413,45 @@ msgstr "Die Datei stimmt nicht mit dem gewählten Medientyp überein." msgid "File" msgstr "Datei" -#: mediagoblin/submit/views.py:51 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "Du musst eine Datei angeben." -#: mediagoblin/submit/views.py:97 +#: mediagoblin/submit/views.py:93 msgid "Woohoo! Submitted!" msgstr "JAAA! Geschafft!" -#: mediagoblin/submit/views.py:146 +#: mediagoblin/submit/views.py:144 #, python-format msgid "Collection \"%s\" added!" msgstr "Sammlung »%s« hinzugefügt!" -#: mediagoblin/templates/mediagoblin/base.html:64 +#: mediagoblin/templates/mediagoblin/base.html:67 msgid "Verify your email!" msgstr "Bitte bestätige Deine E-Mail-Adresse!" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:68 msgid "log out" msgstr "abmelden" -#: mediagoblin/templates/mediagoblin/base.html:70 +#: mediagoblin/templates/mediagoblin/base.html:73 #: mediagoblin/templates/mediagoblin/auth/login.html:28 #: mediagoblin/templates/mediagoblin/auth/login.html:36 #: mediagoblin/templates/mediagoblin/auth/login.html:54 msgid "Log in" msgstr "Anmelden" -#: mediagoblin/templates/mediagoblin/base.html:79 +#: mediagoblin/templates/mediagoblin/base.html:82 #, python-format msgid "<a href=\"%(user_url)s\">%(user_name)s</a>'s account" msgstr "<a href=\"%(user_url)s\">%(user_name)s</a>s Konto" -#: mediagoblin/templates/mediagoblin/base.html:86 +#: mediagoblin/templates/mediagoblin/base.html:89 msgid "Change account settings" msgstr "Kontoeinstellungen ändern" -#: mediagoblin/templates/mediagoblin/base.html:90 -#: mediagoblin/templates/mediagoblin/base.html:105 +#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:108 #: mediagoblin/templates/mediagoblin/admin/panel.html:21 #: mediagoblin/templates/mediagoblin/admin/panel.html:26 #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:21 @@ -431,72 +459,25 @@ msgstr "Kontoeinstellungen ändern" msgid "Media processing panel" msgstr "Medienverarbeitung" -#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:96 msgid "Log out" msgstr "Abmelden" -#: mediagoblin/templates/mediagoblin/base.html:96 +#: mediagoblin/templates/mediagoblin/base.html:99 #: mediagoblin/templates/mediagoblin/user_pages/user.html:156 msgid "Add media" msgstr "Medien hinzufügen" -#: mediagoblin/templates/mediagoblin/base.html:99 +#: mediagoblin/templates/mediagoblin/base.html:102 #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:41 msgid "Create new collection" msgstr "Neues Album erstellen" -#: mediagoblin/templates/mediagoblin/base.html:122 -#, python-format -msgid "" -"Powered by <a href=\"http://mediagoblin.org/\" title='Version " -"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." -msgstr "Läuft mit <a href=\"http://mediagoblin.org/\" title='Version %(version)s'>MediaGoblin</a>, einem <a href=\"http://gnu.org/\">GNU</a>-Projekt." - -#: mediagoblin/templates/mediagoblin/base.html:125 -#, 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/error.html:24 msgid "Image of goblin stressing out" msgstr "Bild eines gestressten Goblins" -#: mediagoblin/templates/mediagoblin/root.html:31 -msgid "Explore" -msgstr "Entdecken" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "Hallo du, willkommen auf dieser MediaGoblin-Seite!" - -#: mediagoblin/templates/mediagoblin/root.html:35 -msgid "" -"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, an " -"extraordinarily great piece of media hosting software." -msgstr "Diese Webseite setzt <a href=\"http://mediagoblin.org\">MediaGoblin</a> ein, eine großartige Software für Medienhosting." - -#: mediagoblin/templates/mediagoblin/root.html:36 -msgid "" -"To add your own media, place comments, and more, you can log in with your " -"MediaGoblin account." -msgstr "Melde Dich mit Deinem MediaGoblin-Konto an, um eigene Medien hinzuzufügen, andere zu kommentieren und vieles mehr." - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Don't have one yet? It's easy!" -msgstr "Hast du noch keinen? Das geht ganz einfach!" - -#: mediagoblin/templates/mediagoblin/root.html:39 -#, 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\">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:47 +#: mediagoblin/templates/mediagoblin/root.html:32 msgid "Most recent media" msgstr "Neuste Medien" @@ -602,6 +583,53 @@ msgid "" "%(verification_url)s" msgstr "Hallo %(username)s,\n\num deinNutzerkonto bei GNU MediaGoblin zu aktivieren, musst du folgende Adresse in deinem Webbrowser öffnen:\n\n%(verification_url)s" +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:21 +#, python-format +msgid "" +"Powered by <a href=\"http://mediagoblin.org/\" title='Version " +"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." +msgstr "Läuft mit <a href=\"http://mediagoblin.org/\" title='Version %(version)s'>MediaGoblin</a>, einem <a href=\"http://gnu.org/\">GNU</a>-Projekt." + +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:24 +#, 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/bits/frontpage_welcome.html:20 +msgid "Explore" +msgstr "Entdecken" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:22 +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "Hallo du, willkommen auf dieser MediaGoblin-Seite!" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:24 +msgid "" +"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, an " +"extraordinarily great piece of media hosting software." +msgstr "Diese Webseite setzt <a href=\"http://mediagoblin.org\">MediaGoblin</a> ein, eine großartige Software für Medienhosting." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:25 +msgid "" +"To add your own media, place comments, and more, you can log in with your " +"MediaGoblin account." +msgstr "Melde Dich mit Deinem MediaGoblin-Konto an, um eigene Medien hinzuzufügen, andere zu kommentieren und vieles mehr." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:27 +msgid "Don't have one yet? It's easy!" +msgstr "Hast du noch keinen? Das geht ganz einfach!" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:28 +#, 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\">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/bits/logo.html:23 #: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 msgid "MediaGoblin logo" @@ -614,13 +642,13 @@ msgid "Editing attachments for %(media_title)s" msgstr "Bearbeite Anhänge von %(media_title)s" #: mediagoblin/templates/mediagoblin/edit/attachments.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:159 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:175 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:182 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:198 msgid "Attachments" msgstr "Anhänge" #: mediagoblin/templates/mediagoblin/edit/attachments.html:57 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:181 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:204 msgid "Add attachment" msgstr "Anhang hinzufügen" @@ -637,12 +665,22 @@ msgstr "Abbrechen" #: mediagoblin/templates/mediagoblin/edit/attachments.html:63 #: mediagoblin/templates/mediagoblin/edit/edit.html:42 -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:52 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:55 #: mediagoblin/templates/mediagoblin/edit/edit_collection.html:33 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:40 msgid "Save changes" msgstr "Änderungen speichern" +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:28 +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 +#, python-format +msgid "Changing %(username)s's password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 +msgid "Save" +msgstr "" + #: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 #, python-format msgid "Really delete user '%(user_name)s' and all related media/comments?" @@ -653,7 +691,7 @@ msgid "Yes, really delete my account" msgstr "Ja, ich möchte mein Konto wirklich löschen" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:48 #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49 msgid "Delete permanently" msgstr "Dauerhaft löschen" @@ -670,7 +708,11 @@ msgstr "%(media_title)s bearbeiten" msgid "Changing %(username)s's account settings" msgstr "%(username)ss Kontoeinstellungen ändern" -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:59 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 +msgid "Change your password." +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 msgid "Delete my account" msgstr "Mein Konto löschen" @@ -695,6 +737,7 @@ msgstr "Medien mit Schlagwort: %(tag_name)s" #: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 #: mediagoblin/templates/mediagoblin/media_displays/audio.html:56 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:65 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:136 #: mediagoblin/templates/mediagoblin/media_displays/video.html:55 msgid "Download" @@ -719,6 +762,7 @@ msgid "" 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/audio.html:60 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:71 #: mediagoblin/templates/mediagoblin/media_displays/video.html:61 msgid "Original file" msgstr "Originaldatei" @@ -727,6 +771,7 @@ msgstr "Originaldatei" msgid "WebM file (Vorbis codec)" msgstr "WebM-Datei (Vorbis-Codec)" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:59 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:87 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:93 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:99 @@ -737,6 +782,10 @@ msgstr "WebM-Datei (Vorbis-Codec)" msgid "Image for %(media_title)s" msgstr "Bild für %(media_title)s" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 +msgid "PDF file" +msgstr "PDF-Datei" + #: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 msgid "Toggle Rotate" msgstr "" @@ -835,7 +884,7 @@ msgstr "Möchtest du %(title)s wirklich löschen?" msgid "Really remove %(media_title)s from %(collection_title)s?" msgstr "Wirklich »%(media_title)s« aus »%(collection_title)s« entfernen?" -#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:54 msgid "Remove" msgstr "Entfernen" @@ -878,24 +927,28 @@ msgstr "<a href=\"%(user_url)s\">%(username)s</a>s Medien" 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:94 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:95 msgid "Add a comment" msgstr "Einen Kommentar schreiben" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 msgid "Add this comment" msgstr "Kommentar absenden" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:123 -msgid "at" -msgstr "um" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:144 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:132 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:152 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:164 #, python-format -msgid "" -"<h3>Added on</h3>\n" -" <p>%(date)s</p>" -msgstr "<h3>Veröffentlicht am</h3>\n <p>%(date)s</p>" +msgid "%(formatted_time)s ago" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:150 +msgid "Added" +msgstr "Hinzugefügt" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:161 +msgid "Created" +msgstr "Originaldatum" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:40 @@ -1051,7 +1104,7 @@ msgstr "älter" msgid "Tagged with" msgstr "Schlagwörter" -#: mediagoblin/tools/exif.py:80 +#: mediagoblin/tools/exif.py:83 msgid "Could not read the image file." msgstr "Die Bilddatei konnte nicht gelesen werden." @@ -1081,6 +1134,30 @@ msgid "" " deleted." msgstr "Tut uns Leid, aber unter der angegebenen Adresse gibt es keine Seite!</p><p>Wenn du sicher bist, dass die Adresse stimmt, wurde die Seite eventuell verschoben oder gelöscht." +#: mediagoblin/tools/timesince.py:62 +msgid "year" +msgstr "Jahr" + +#: mediagoblin/tools/timesince.py:63 +msgid "month" +msgstr "Monat" + +#: mediagoblin/tools/timesince.py:64 +msgid "week" +msgstr "Woche" + +#: mediagoblin/tools/timesince.py:65 +msgid "day" +msgstr "Tag" + +#: mediagoblin/tools/timesince.py:66 +msgid "hour" +msgstr "Stunde" + +#: mediagoblin/tools/timesince.py:67 +msgid "minute" +msgstr "Minute" + #: mediagoblin/user_pages/forms.py:23 msgid "Comment" msgstr "Kommentar" @@ -1112,73 +1189,77 @@ msgstr "-- Auswählen --" msgid "Include a note" msgstr "Notiz anfügen" -#: mediagoblin/user_pages/lib.py:56 +#: mediagoblin/user_pages/lib.py:58 msgid "commented on your post" msgstr "hat dein Medium kommentiert" -#: mediagoblin/user_pages/views.py:166 +#: mediagoblin/user_pages/views.py:169 +msgid "Sorry, comments are disabled." +msgstr "" + +#: mediagoblin/user_pages/views.py:174 msgid "Oops, your comment was empty." msgstr "Hoppla, der Kommentartext fehlte." -#: mediagoblin/user_pages/views.py:172 +#: mediagoblin/user_pages/views.py:180 msgid "Your comment has been posted!" msgstr "Dein Kommentar wurde angenommen!" -#: mediagoblin/user_pages/views.py:197 +#: mediagoblin/user_pages/views.py:205 msgid "Please check your entries and try again." msgstr "Bitte prüfe deinen Einträge und versuche erneut." -#: mediagoblin/user_pages/views.py:237 +#: mediagoblin/user_pages/views.py:245 msgid "You have to select or add a collection" msgstr "Du musst eine Sammlung auswählen oder hinzufügen" -#: mediagoblin/user_pages/views.py:248 +#: mediagoblin/user_pages/views.py:256 #, python-format msgid "\"%s\" already in collection \"%s\"" msgstr "»%s« ist bereits in der Sammlung »%s«" -#: mediagoblin/user_pages/views.py:264 +#: mediagoblin/user_pages/views.py:262 #, python-format msgid "\"%s\" added to collection \"%s\"" msgstr "»%s« zur Sammlung »%s« hinzugefügt" -#: mediagoblin/user_pages/views.py:286 +#: mediagoblin/user_pages/views.py:282 msgid "You deleted the media." msgstr "Du hast das Medium gelöscht." -#: mediagoblin/user_pages/views.py:293 +#: mediagoblin/user_pages/views.py:289 msgid "The media was not deleted because you didn't check that you were sure." msgstr "Das Medium wurde nicht gelöscht, da nicht angekreuzt hast, dass du es wirklich löschen möchtest." -#: mediagoblin/user_pages/views.py:301 +#: mediagoblin/user_pages/views.py:296 msgid "You are about to delete another user's media. Proceed with caution." msgstr "Du versuchst Medien eines anderen Nutzers zu löschen. Sei bitte vorsichtig." -#: mediagoblin/user_pages/views.py:375 +#: mediagoblin/user_pages/views.py:370 msgid "You deleted the item from the collection." msgstr "Du hast das Objekt aus der Sammlung gelöscht." -#: mediagoblin/user_pages/views.py:379 +#: mediagoblin/user_pages/views.py:374 msgid "The item was not removed because you didn't check that you were sure." msgstr "Das Objekt wurde nicht aus der Sammlung entfernt, weil du nicht bestätigt hast, dass du dir sicher bist." -#: mediagoblin/user_pages/views.py:389 +#: mediagoblin/user_pages/views.py:382 msgid "" "You are about to delete an item from another user's collection. Proceed with" " caution." msgstr "Du bist dabei ein Objekt aus der Sammlung eines anderen Nutzers zu entfernen. Sei vorsichtig." -#: mediagoblin/user_pages/views.py:422 +#: mediagoblin/user_pages/views.py:415 #, python-format msgid "You deleted the collection \"%s\"" msgstr "Du hast die Sammlung »%s« gelöscht" -#: mediagoblin/user_pages/views.py:429 +#: mediagoblin/user_pages/views.py:422 msgid "" "The collection was not deleted because you didn't check that you were sure." msgstr "Die Sammlung wurde nicht gelöscht, weil du nicht bestätigt hast, dass du dir sicher bist." -#: mediagoblin/user_pages/views.py:439 +#: mediagoblin/user_pages/views.py:430 msgid "" "You are about to delete another user's collection. Proceed with caution." msgstr "Du bist dabei eine Sammlung eines anderen Nutzers zu entfernen. Sei vorsichtig." diff --git a/mediagoblin/i18n/en/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/en/LC_MESSAGES/mediagoblin.po index 6950f515..1b22b786 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: 2013-03-11 17:21-0500\n" +"POT-Creation-Date: 2013-06-16 20:06-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,93 +17,98 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 0.9.6\n" -#: mediagoblin/auth/forms.py:28 -msgid "Invalid User name or email address." +#: mediagoblin/auth/forms.py:25 +msgid "Username" msgstr "" -#: mediagoblin/auth/forms.py:29 -msgid "This field does not take email addresses." +#: mediagoblin/auth/forms.py:29 mediagoblin/auth/forms.py:44 +#: mediagoblin/tests/test_util.py:110 +msgid "Password" msgstr "" -#: mediagoblin/auth/forms.py:30 -msgid "This field requires an email address." +#: mediagoblin/auth/forms.py:33 +msgid "Email address" msgstr "" -#: mediagoblin/auth/forms.py:52 mediagoblin/auth/forms.py:67 -msgid "Username" +#: mediagoblin/auth/forms.py:40 +msgid "Username or Email" msgstr "" -#: mediagoblin/auth/forms.py:56 mediagoblin/auth/forms.py:71 -msgid "Password" +#: mediagoblin/auth/forms.py:51 +msgid "Username or email" msgstr "" -#: mediagoblin/auth/forms.py:60 -msgid "Email address" +#: mediagoblin/auth/tools.py:42 +msgid "Invalid User name or email address." msgstr "" -#: mediagoblin/auth/forms.py:78 -msgid "Username or email" +#: mediagoblin/auth/tools.py:43 +msgid "This field does not take email addresses." msgstr "" -#: mediagoblin/auth/views.py:54 -msgid "Sorry, registration is disabled on this instance." +#: mediagoblin/auth/tools.py:44 +msgid "This field requires an email address." msgstr "" -#: mediagoblin/auth/views.py:68 +#: mediagoblin/auth/tools.py:109 msgid "Sorry, a user with that name already exists." msgstr "" -#: mediagoblin/auth/views.py:72 +#: mediagoblin/auth/tools.py:113 msgid "Sorry, a user with that email address already exists." msgstr "" -#: mediagoblin/auth/views.py:174 +#: mediagoblin/auth/views.py:43 +msgid "Sorry, registration is disabled on this instance." +msgstr "" + +#: mediagoblin/auth/views.py:133 msgid "" "Your email address has been verified. You may now login, edit your " "profile, and submit images!" msgstr "" -#: mediagoblin/auth/views.py:180 +#: mediagoblin/auth/views.py:139 msgid "The verification key or user id is incorrect" msgstr "" -#: mediagoblin/auth/views.py:198 +#: mediagoblin/auth/views.py:157 msgid "You must be logged in so we know who to send the email to!" msgstr "" -#: mediagoblin/auth/views.py:206 +#: mediagoblin/auth/views.py:165 msgid "You've already verified your email address!" msgstr "" -#: mediagoblin/auth/views.py:219 +#: mediagoblin/auth/views.py:178 msgid "Resent your verification email." msgstr "" -#: mediagoblin/auth/views.py:250 +#: mediagoblin/auth/views.py:209 msgid "" "If that email address (case sensitive!) is registered an email has been " "sent with instructions on how to change your password." msgstr "" -#: mediagoblin/auth/views.py:261 +#: mediagoblin/auth/views.py:220 msgid "Couldn't find someone with that username." msgstr "" -#: mediagoblin/auth/views.py:264 +#: mediagoblin/auth/views.py:223 msgid "An email has been sent with instructions on how to change your password." msgstr "" -#: mediagoblin/auth/views.py:271 +#: mediagoblin/auth/views.py:230 msgid "" "Could not send password recovery email as your username is inactive or " "your account's email address has not been verified." msgstr "" -#: mediagoblin/auth/views.py:328 +#: mediagoblin/auth/views.py:287 msgid "You can now log in using your new password." msgstr "" -#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:93 +#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:82 #: mediagoblin/submit/forms.py:28 mediagoblin/submit/forms.py:47 #: mediagoblin/user_pages/forms.py:45 msgid "Title" @@ -114,7 +119,7 @@ msgid "Description of this work" msgstr "" #: mediagoblin/edit/forms.py:29 mediagoblin/edit/forms.py:52 -#: mediagoblin/edit/forms.py:97 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:86 mediagoblin/submit/forms.py:32 #: mediagoblin/submit/forms.py:51 mediagoblin/user_pages/forms.py:49 msgid "" "You can use\n" @@ -131,11 +136,11 @@ msgstr "" msgid "Separate tags by commas." msgstr "" -#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:101 +#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:90 msgid "Slug" msgstr "" -#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:102 +#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:91 msgid "The slug can't be empty" msgstr "" @@ -163,45 +168,45 @@ msgid "This address contains errors" msgstr "" #: mediagoblin/edit/forms.py:63 -msgid "Old password" -msgstr "" - -#: mediagoblin/edit/forms.py:64 -msgid "Enter your old password to prove you own this account." -msgstr "" - -#: mediagoblin/edit/forms.py:67 -msgid "New password" -msgstr "" - -#: mediagoblin/edit/forms.py:74 msgid "License preference" msgstr "" -#: mediagoblin/edit/forms.py:80 +#: mediagoblin/edit/forms.py:69 msgid "This will be your default license on upload forms." msgstr "" -#: mediagoblin/edit/forms.py:82 +#: mediagoblin/edit/forms.py:71 msgid "Email me when others comment on my media" msgstr "" -#: mediagoblin/edit/forms.py:94 +#: mediagoblin/edit/forms.py:83 msgid "The title can't be empty" msgstr "" -#: mediagoblin/edit/forms.py:96 mediagoblin/submit/forms.py:50 +#: mediagoblin/edit/forms.py:85 mediagoblin/submit/forms.py:50 #: mediagoblin/user_pages/forms.py:48 msgid "Description of this collection" msgstr "" -#: mediagoblin/edit/forms.py:103 +#: mediagoblin/edit/forms.py:92 msgid "" "The title part of this collection's address. You usually don't need to " "change this." msgstr "" -#: mediagoblin/edit/views.py:66 +#: mediagoblin/edit/forms.py:99 +msgid "Old password" +msgstr "" + +#: mediagoblin/edit/forms.py:101 +msgid "Enter your old password to prove you own this account." +msgstr "" + +#: mediagoblin/edit/forms.py:104 +msgid "New password" +msgstr "" + +#: mediagoblin/edit/views.py:67 msgid "An entry with that slug already exists for this user." msgstr "" @@ -226,44 +231,63 @@ msgstr "" msgid "Profile changes saved" msgstr "" -#: mediagoblin/edit/views.py:241 -msgid "Wrong password" -msgstr "" - -#: mediagoblin/edit/views.py:252 +#: mediagoblin/edit/views.py:240 msgid "Account settings saved" msgstr "" -#: mediagoblin/edit/views.py:286 +#: mediagoblin/edit/views.py:274 msgid "You need to confirm the deletion of your account." msgstr "" -#: mediagoblin/edit/views.py:322 mediagoblin/submit/views.py:142 -#: mediagoblin/user_pages/views.py:214 +#: mediagoblin/edit/views.py:310 mediagoblin/submit/views.py:138 +#: mediagoblin/user_pages/views.py:222 #, python-format msgid "You already have a collection called \"%s\"!" msgstr "" -#: mediagoblin/edit/views.py:326 +#: mediagoblin/edit/views.py:314 msgid "A collection with that slug already exists for this user." msgstr "" -#: mediagoblin/edit/views.py:343 +#: mediagoblin/edit/views.py:329 msgid "You are editing another user's collection. Proceed with caution." msgstr "" -#: mediagoblin/gmg_commands/theme.py:58 +#: mediagoblin/edit/views.py:348 +msgid "Wrong password" +msgstr "" + +#: mediagoblin/edit/views.py:363 +msgid "Your password was changed successfully" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:60 msgid "Cannot link theme... no theme set\n" msgstr "" -#: mediagoblin/gmg_commands/theme.py:71 +#: mediagoblin/gmg_commands/assetlink.py:73 msgid "No asset directory for this theme\n" msgstr "" -#: mediagoblin/gmg_commands/theme.py:74 +#: mediagoblin/gmg_commands/assetlink.py:76 msgid "However, old link directory symlink found; removed.\n" msgstr "" +#: mediagoblin/gmg_commands/assetlink.py:112 +#, python-format +msgid "Could not link \"%s\": %s exists and is not a symlink\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:119 +#, python-format +msgid "Skipping \"%s\"; already set up.\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:124 +#, python-format +msgid "Old link found for \"%s\"; removing.\n" +msgstr "" + #: mediagoblin/meddleware/csrf.py:134 msgid "" "CSRF cookie not present. This is most likely the result of a cookie " @@ -271,11 +295,15 @@ msgid "" "this domain." msgstr "" -#: mediagoblin/media_types/__init__.py:61 -#: mediagoblin/media_types/__init__.py:102 +#: mediagoblin/media_types/__init__.py:111 +#: mediagoblin/media_types/__init__.py:155 msgid "Sorry, I don't support that file type :(" msgstr "" +#: mediagoblin/media_types/pdf/processing.py:136 +msgid "unoconv failing to run, check log file" +msgstr "" + #: mediagoblin/media_types/video/processing.py:37 msgid "Video transcoding failed" msgstr "" @@ -347,7 +375,7 @@ msgstr "" msgid "This field is required for public clients" msgstr "" -#: mediagoblin/plugins/oauth/views.py:59 +#: mediagoblin/plugins/oauth/views.py:56 msgid "The client {0} has been registered!" msgstr "" @@ -366,7 +394,7 @@ msgstr "" msgid "Add" msgstr "" -#: mediagoblin/processing/__init__.py:172 +#: mediagoblin/processing/__init__.py:193 msgid "Invalid file given for media type." msgstr "" @@ -374,45 +402,45 @@ msgstr "" msgid "File" msgstr "" -#: mediagoblin/submit/views.py:51 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "" -#: mediagoblin/submit/views.py:97 +#: mediagoblin/submit/views.py:93 msgid "Woohoo! Submitted!" msgstr "" -#: mediagoblin/submit/views.py:146 +#: mediagoblin/submit/views.py:144 #, python-format msgid "Collection \"%s\" added!" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:64 +#: mediagoblin/templates/mediagoblin/base.html:67 msgid "Verify your email!" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:68 msgid "log out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:70 +#: mediagoblin/templates/mediagoblin/base.html:73 #: mediagoblin/templates/mediagoblin/auth/login.html:28 #: mediagoblin/templates/mediagoblin/auth/login.html:36 #: mediagoblin/templates/mediagoblin/auth/login.html:54 msgid "Log in" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:79 +#: mediagoblin/templates/mediagoblin/base.html:82 #, python-format msgid "<a href=\"%(user_url)s\">%(user_name)s</a>'s account" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:86 +#: mediagoblin/templates/mediagoblin/base.html:89 msgid "Change account settings" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:90 -#: mediagoblin/templates/mediagoblin/base.html:105 +#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:108 #: mediagoblin/templates/mediagoblin/admin/panel.html:21 #: mediagoblin/templates/mediagoblin/admin/panel.html:26 #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:21 @@ -420,76 +448,25 @@ msgstr "" msgid "Media processing panel" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:96 msgid "Log out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:96 +#: mediagoblin/templates/mediagoblin/base.html:99 #: mediagoblin/templates/mediagoblin/user_pages/user.html:156 msgid "Add media" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:99 +#: mediagoblin/templates/mediagoblin/base.html:102 #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:41 msgid "Create new collection" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:122 -#, python-format -msgid "" -"Powered by <a href=\"http://mediagoblin.org/\" title='Version " -"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> " -"project." -msgstr "" - -#: mediagoblin/templates/mediagoblin/base.html:125 -#, 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/error.html:24 msgid "Image of goblin stressing out" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:31 -msgid "Explore" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:35 -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:36 -msgid "" -"To add your own media, place comments, and more, you can log in with your" -" MediaGoblin account." -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Don't have one yet? It's easy!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:39 -#, 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:47 +#: mediagoblin/templates/mediagoblin/root.html:32 msgid "Most recent media" msgstr "" @@ -594,6 +571,57 @@ msgid "" "%(verification_url)s" msgstr "" +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:21 +#, python-format +msgid "" +"Powered by <a href=\"http://mediagoblin.org/\" title='Version " +"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> " +"project." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:24 +#, 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/bits/frontpage_welcome.html:20 +msgid "Explore" +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:22 +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:24 +msgid "" +"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, " +"an extraordinarily great piece of media hosting software." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:25 +msgid "" +"To add your own media, place comments, and more, you can log in with your" +" MediaGoblin account." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:27 +msgid "Don't have one yet? It's easy!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:28 +#, python-format +msgid "" +"<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/bits/logo.html:23 #: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 msgid "MediaGoblin logo" @@ -606,13 +634,13 @@ msgid "Editing attachments for %(media_title)s" msgstr "" #: mediagoblin/templates/mediagoblin/edit/attachments.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:159 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:175 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:171 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:187 msgid "Attachments" msgstr "" #: mediagoblin/templates/mediagoblin/edit/attachments.html:57 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:181 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:193 msgid "Add attachment" msgstr "" @@ -629,12 +657,22 @@ msgstr "" #: mediagoblin/templates/mediagoblin/edit/attachments.html:63 #: mediagoblin/templates/mediagoblin/edit/edit.html:42 -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:52 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:55 #: mediagoblin/templates/mediagoblin/edit/edit_collection.html:33 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:40 msgid "Save changes" msgstr "" +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:28 +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 +#, python-format +msgid "Changing %(username)s's password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 +msgid "Save" +msgstr "" + #: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 #, python-format msgid "Really delete user '%(user_name)s' and all related media/comments?" @@ -645,7 +683,7 @@ msgid "Yes, really delete my account" msgstr "" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:48 #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49 msgid "Delete permanently" msgstr "" @@ -662,7 +700,11 @@ msgstr "" msgid "Changing %(username)s's account settings" msgstr "" -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:59 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 +msgid "Change your password." +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 msgid "Delete my account" msgstr "" @@ -687,6 +729,7 @@ msgstr "" #: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 #: mediagoblin/templates/mediagoblin/media_displays/audio.html:56 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:65 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:136 #: mediagoblin/templates/mediagoblin/media_displays/video.html:55 msgid "Download" @@ -711,6 +754,7 @@ msgid "" msgstr "" #: mediagoblin/templates/mediagoblin/media_displays/audio.html:60 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:71 #: mediagoblin/templates/mediagoblin/media_displays/video.html:61 msgid "Original file" msgstr "" @@ -719,6 +763,18 @@ msgstr "" msgid "WebM file (Vorbis codec)" msgstr "" +#: mediagoblin/templates/mediagoblin/media_displays/image.html:36 +msgid "Created" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/image.html:39 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:132 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:152 +#, python-format +msgid "%(formatted_time)s ago" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:59 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:87 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:93 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:99 @@ -729,6 +785,10 @@ msgstr "" msgid "Image for %(media_title)s" msgstr "" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 +msgid "PDF file" +msgstr "" + #: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 msgid "Toggle Rotate" msgstr "" @@ -827,7 +887,7 @@ msgstr "" msgid "Really remove %(media_title)s from %(collection_title)s?" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:54 msgid "Remove" msgstr "" @@ -871,23 +931,16 @@ msgstr "" msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:94 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:95 msgid "Add a comment" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 msgid "Add this comment" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:123 -msgid "at" -msgstr "" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:144 -#, python-format -msgid "" -"<h3>Added on</h3>\n" -" <p>%(date)s</p>" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:150 +msgid "Added" msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 @@ -1042,7 +1095,7 @@ msgstr "" msgid "Tagged with" msgstr "" -#: mediagoblin/tools/exif.py:80 +#: mediagoblin/tools/exif.py:83 msgid "Could not read the image file." msgstr "" @@ -1072,6 +1125,30 @@ msgid "" "moved or deleted." msgstr "" +#: mediagoblin/tools/timesince.py:62 +msgid "year" +msgstr "" + +#: mediagoblin/tools/timesince.py:63 +msgid "month" +msgstr "" + +#: mediagoblin/tools/timesince.py:64 +msgid "week" +msgstr "" + +#: mediagoblin/tools/timesince.py:65 +msgid "day" +msgstr "" + +#: mediagoblin/tools/timesince.py:66 +msgid "hour" +msgstr "" + +#: mediagoblin/tools/timesince.py:67 +msgid "minute" +msgstr "" + #: mediagoblin/user_pages/forms.py:23 msgid "Comment" msgstr "" @@ -1103,74 +1180,78 @@ msgstr "" msgid "Include a note" msgstr "" -#: mediagoblin/user_pages/lib.py:56 +#: mediagoblin/user_pages/lib.py:58 msgid "commented on your post" msgstr "" -#: mediagoblin/user_pages/views.py:166 +#: mediagoblin/user_pages/views.py:169 +msgid "Sorry, comments are disabled." +msgstr "" + +#: mediagoblin/user_pages/views.py:174 msgid "Oops, your comment was empty." msgstr "" -#: mediagoblin/user_pages/views.py:172 +#: mediagoblin/user_pages/views.py:180 msgid "Your comment has been posted!" msgstr "" -#: mediagoblin/user_pages/views.py:197 +#: mediagoblin/user_pages/views.py:205 msgid "Please check your entries and try again." msgstr "" -#: mediagoblin/user_pages/views.py:237 +#: mediagoblin/user_pages/views.py:245 msgid "You have to select or add a collection" msgstr "" -#: mediagoblin/user_pages/views.py:248 +#: mediagoblin/user_pages/views.py:256 #, python-format msgid "\"%s\" already in collection \"%s\"" msgstr "" -#: mediagoblin/user_pages/views.py:264 +#: mediagoblin/user_pages/views.py:262 #, python-format msgid "\"%s\" added to collection \"%s\"" msgstr "" -#: mediagoblin/user_pages/views.py:286 +#: mediagoblin/user_pages/views.py:282 msgid "You deleted the media." msgstr "" -#: mediagoblin/user_pages/views.py:293 +#: mediagoblin/user_pages/views.py:289 msgid "The media was not deleted because you didn't check that you were sure." msgstr "" -#: mediagoblin/user_pages/views.py:301 +#: mediagoblin/user_pages/views.py:296 msgid "You are about to delete another user's media. Proceed with caution." msgstr "" -#: mediagoblin/user_pages/views.py:375 +#: mediagoblin/user_pages/views.py:370 msgid "You deleted the item from the collection." msgstr "" -#: mediagoblin/user_pages/views.py:379 +#: mediagoblin/user_pages/views.py:374 msgid "The item was not removed because you didn't check that you were sure." msgstr "" -#: mediagoblin/user_pages/views.py:389 +#: mediagoblin/user_pages/views.py:382 msgid "" "You are about to delete an item from another user's collection. Proceed " "with caution." msgstr "" -#: mediagoblin/user_pages/views.py:422 +#: mediagoblin/user_pages/views.py:415 #, python-format msgid "You deleted the collection \"%s\"" msgstr "" -#: mediagoblin/user_pages/views.py:429 +#: mediagoblin/user_pages/views.py:422 msgid "" "The collection was not deleted because you didn't check that you were " "sure." msgstr "" -#: mediagoblin/user_pages/views.py:439 +#: mediagoblin/user_pages/views.py:430 msgid "You are about to delete another user's collection. Proceed with caution." msgstr "" diff --git a/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.mo Binary files differindex ac74a68b..645af16b 100644 --- a/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.mo +++ b/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.po index e7785d73..873869f0 100644 --- a/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/eo/LC_MESSAGES/mediagoblin.po @@ -3,18 +3,18 @@ # This file is distributed under the same license as the PROJECT project. # # Translators: -# <deletesoftware@yandex.ru>, 2013. -# <deletesoftware@yandex.ru>, 2011-2012. -# Fernando Inocencio <faigos@gmail.com>, 2011. -# <john_w1954@fastmail.fm>, 2011. +# aleksejrs <deletesoftware@yandex.ru>, 2013 +# aleksejrs <deletesoftware@yandex.ru>, 2011-2012 +# Fernando Inocencio <faigos@gmail.com>, 2011 +# tiguliano <john_w1954@fastmail.fm>, 2011 msgid "" msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" -"POT-Creation-Date: 2013-03-04 18:04-0600\n" -"PO-Revision-Date: 2013-03-10 16:50+0000\n" +"POT-Creation-Date: 2013-05-27 13:54-0500\n" +"PO-Revision-Date: 2013-06-01 21:16+0000\n" "Last-Translator: aleksejrs <deletesoftware@yandex.ru>\n" -"Language-Team: LANGUAGE <LL@li.org>\n" +"Language-Team: Esperanto (http://www.transifex.com/projects/p/mediagoblin/language/eo/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -22,34 +22,39 @@ msgstr "" "Language: eo\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: mediagoblin/auth/forms.py:28 -msgid "Invalid User name or email address." -msgstr "Nevalida ensalutnomo aÅ retpoÅtadreso." - -#: mediagoblin/auth/forms.py:29 -msgid "This field does not take email addresses." -msgstr "Ĉi tiu kampo ne akceptas retpoÅtadresojn." - -#: mediagoblin/auth/forms.py:30 -msgid "This field requires an email address." -msgstr "Ĉi tiu kampo postulas retpoÅtadreson." - -#: mediagoblin/auth/forms.py:52 mediagoblin/auth/forms.py:67 +#: mediagoblin/auth/forms.py:26 msgid "Username" msgstr "Uzantnomo" -#: mediagoblin/auth/forms.py:56 mediagoblin/auth/forms.py:71 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 +#: mediagoblin/tests/test_util.py:110 msgid "Password" msgstr "Pasvorto" -#: mediagoblin/auth/forms.py:60 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "RetpoÅtadreso" -#: mediagoblin/auth/forms.py:78 +#: mediagoblin/auth/forms.py:41 +msgid "Username or Email" +msgstr "Uzantonomo aÅ retpoÅtadreso" + +#: mediagoblin/auth/forms.py:52 msgid "Username or email" msgstr "Salutnomo aÅ retpoÅtadreso" +#: mediagoblin/auth/tools.py:31 +msgid "Invalid User name or email address." +msgstr "Nevalida ensalutnomo aÅ retpoÅtadreso." + +#: mediagoblin/auth/tools.py:32 +msgid "This field does not take email addresses." +msgstr "Ĉi tiu kampo ne akceptas retpoÅtadresojn." + +#: mediagoblin/auth/tools.py:33 +msgid "This field requires an email address." +msgstr "Ĉi tiu kampo postulas retpoÅtadreson." + #: mediagoblin/auth/views.py:54 msgid "Sorry, registration is disabled on this instance." msgstr "BedaÅrinde, registrado estas malaktivigita en tiu ĉi instalaĵo." @@ -62,54 +67,54 @@ msgstr "BedaÅrinde, uzanto kun tiu nomo jam ekzistas." msgid "Sorry, a user with that email address already exists." msgstr "Ni bedaÅras, sed konto kun tiu retpoÅtadreso jam ekzistas." -#: mediagoblin/auth/views.py:174 +#: 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:180 +#: 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:198 +#: 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:206 +#: mediagoblin/auth/views.py:214 msgid "You've already verified your email address!" msgstr "Vi jam konfirmis vian retpoÅtadreson!" -#: mediagoblin/auth/views.py:219 +#: mediagoblin/auth/views.py:227 msgid "Resent your verification email." msgstr "Resendi vian kontrol-mesaÄon." -#: mediagoblin/auth/views.py:250 +#: mediagoblin/auth/views.py:258 msgid "" "If that email address (case sensitive!) is registered an email has been sent" " with instructions on how to change your password." msgstr "Se tiu retpoÅtadreso (majuskloj gravas!) estas registrita, tien senditas retletero kun instrukcio pri kiel ÅanÄi vian pasvorton." -#: mediagoblin/auth/views.py:261 +#: mediagoblin/auth/views.py:269 msgid "Couldn't find someone with that username." msgstr "Trovitas neniu kun tiu ensalutnomo." -#: mediagoblin/auth/views.py:264 +#: mediagoblin/auth/views.py:272 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:271 +#: mediagoblin/auth/views.py:279 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." msgstr "Ni ne povas sendi pasvortsavan retleteron, ĉar aÅ via konto estas neaktiva, aÅ Äia retpoÅtadreso ne estis konfirmita." -#: mediagoblin/auth/views.py:328 +#: mediagoblin/auth/views.py:336 msgid "You can now log in using your new password." msgstr "Nun vi povas ensaluti per via nova pasvorto." -#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:93 +#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:82 #: mediagoblin/submit/forms.py:28 mediagoblin/submit/forms.py:47 #: mediagoblin/user_pages/forms.py:45 msgid "Title" @@ -120,7 +125,7 @@ msgid "Description of this work" msgstr "Priskribo de ĉi tiu verko" #: mediagoblin/edit/forms.py:29 mediagoblin/edit/forms.py:52 -#: mediagoblin/edit/forms.py:97 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:86 mediagoblin/submit/forms.py:32 #: mediagoblin/submit/forms.py:51 mediagoblin/user_pages/forms.py:49 msgid "" "You can use\n" @@ -136,11 +141,11 @@ msgstr "Etikedoj" msgid "Separate tags by commas." msgstr "Dividu la etikedojn per komoj." -#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:101 +#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:90 msgid "Slug" msgstr "La distingiga adresparto" -#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:102 +#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:91 msgid "The slug can't be empty" msgstr "La distingiga adresparto ne povas esti malplena" @@ -168,45 +173,45 @@ msgid "This address contains errors" msgstr "Ĉi tiu adreso enhavas erarojn" #: mediagoblin/edit/forms.py:63 -msgid "Old password" -msgstr "La malnova pasvorto" - -#: mediagoblin/edit/forms.py:64 -msgid "Enter your old password to prove you own this account." -msgstr "Enigu vian malnovan pasvorton por pruvi, ke ĉi tiu konto estas via." - -#: mediagoblin/edit/forms.py:67 -msgid "New password" -msgstr "La nova pasvorto" - -#: mediagoblin/edit/forms.py:74 msgid "License preference" msgstr "Permesila prefero" -#: mediagoblin/edit/forms.py:80 +#: mediagoblin/edit/forms.py:69 msgid "This will be your default license on upload forms." -msgstr "" +msgstr "Tiu ĉi permesilo estos antaÅelektita en la alÅutformularoj." -#: mediagoblin/edit/forms.py:82 +#: mediagoblin/edit/forms.py:71 msgid "Email me when others comment on my media" msgstr "RetpoÅtu min kiam aliaj komentas pri miaj alÅutaĵoj." -#: mediagoblin/edit/forms.py:94 +#: mediagoblin/edit/forms.py:83 msgid "The title can't be empty" msgstr "La titolo ne povas malpleni." -#: mediagoblin/edit/forms.py:96 mediagoblin/submit/forms.py:50 +#: mediagoblin/edit/forms.py:85 mediagoblin/submit/forms.py:50 #: mediagoblin/user_pages/forms.py:48 msgid "Description of this collection" msgstr "Priskribo de la kolekto" -#: mediagoblin/edit/forms.py:103 +#: mediagoblin/edit/forms.py:92 msgid "" "The title part of this collection's address. You usually don't need to " "change this." msgstr "La distingiga adresparto de ĉi tiu kolekto. Ordinare ne necesas Äin ÅanÄi." -#: mediagoblin/edit/views.py:66 +#: mediagoblin/edit/forms.py:99 +msgid "Old password" +msgstr "La malnova pasvorto" + +#: mediagoblin/edit/forms.py:101 +msgid "Enter your old password to prove you own this account." +msgstr "Enigu vian malnovan pasvorton por pruvi, ke ĉi tiu konto estas via." + +#: mediagoblin/edit/forms.py:104 +msgid "New password" +msgstr "La nova pasvorto" + +#: 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." @@ -231,44 +236,63 @@ msgstr "Vi redaktas profilon de alia uzanto. Agu singardeme." msgid "Profile changes saved" msgstr "ProfilÅanÄoj estis konservitaj" -#: mediagoblin/edit/views.py:241 -msgid "Wrong password" -msgstr "MalÄusta pasvorto" - -#: mediagoblin/edit/views.py:252 +#: mediagoblin/edit/views.py:240 msgid "Account settings saved" msgstr "Kontagordoj estis konservitaj" -#: mediagoblin/edit/views.py:286 +#: mediagoblin/edit/views.py:274 msgid "You need to confirm the deletion of your account." msgstr "Vi bezonas konfirmi la forigon de via konto." -#: mediagoblin/edit/views.py:322 mediagoblin/submit/views.py:142 -#: mediagoblin/user_pages/views.py:214 +#: mediagoblin/edit/views.py:310 mediagoblin/submit/views.py:138 +#: mediagoblin/user_pages/views.py:222 #, python-format msgid "You already have a collection called \"%s\"!" msgstr "Vi jam havas kolekton kun la nomo «%s»!" -#: mediagoblin/edit/views.py:326 +#: mediagoblin/edit/views.py:314 msgid "A collection with that slug already exists for this user." msgstr "Ĉi tiu uzanto jam havas kolekton kun tiu distingiga adresparto." -#: mediagoblin/edit/views.py:343 +#: mediagoblin/edit/views.py:329 msgid "You are editing another user's collection. Proceed with caution." msgstr "Vi redaktas kolekton de alia uzanto. Agu singardeme." -#: mediagoblin/gmg_commands/theme.py:58 +#: mediagoblin/edit/views.py:348 +msgid "Wrong password" +msgstr "MalÄusta pasvorto" + +#: mediagoblin/edit/views.py:363 +msgid "Your password was changed successfully" +msgstr "Via pasvorto estas sukcese ÅanÄita" + +#: mediagoblin/gmg_commands/assetlink.py:60 msgid "Cannot link theme... no theme set\n" msgstr "Alligo de etoso ne eblas… ne estas elektita ekzistanta etoso\n" -#: mediagoblin/gmg_commands/theme.py:71 +#: mediagoblin/gmg_commands/assetlink.py:73 msgid "No asset directory for this theme\n" msgstr "Mankas dosierujo kun aspektiloj por la etoso\n" -#: mediagoblin/gmg_commands/theme.py:74 +#: mediagoblin/gmg_commands/assetlink.py:76 msgid "However, old link directory symlink found; removed.\n" msgstr "Tamen trovitas — kaj forigitas — malnova simbola ligilo al dosierujo.\n" +#: mediagoblin/gmg_commands/assetlink.py:112 +#, python-format +msgid "Could not link \"%s\": %s exists and is not a symlink\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:119 +#, python-format +msgid "Skipping \"%s\"; already set up.\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:124 +#, python-format +msgid "Old link found for \"%s\"; removing.\n" +msgstr "" + #: mediagoblin/meddleware/csrf.py:134 msgid "" "CSRF cookie not present. This is most likely the result of a cookie blocker " @@ -276,12 +300,16 @@ msgid "" "domain." msgstr "" -#: mediagoblin/media_types/__init__.py:61 -#: mediagoblin/media_types/__init__.py:102 +#: mediagoblin/media_types/__init__.py:111 +#: mediagoblin/media_types/__init__.py:155 msgid "Sorry, I don't support that file type :(" msgstr "Mi pardonpetas, mi ne subtenas tiun dosiertipon :(" -#: mediagoblin/media_types/video/processing.py:36 +#: mediagoblin/media_types/pdf/processing.py:136 +msgid "unoconv failing to run, check log file" +msgstr "" + +#: mediagoblin/media_types/video/processing.py:37 msgid "Video transcoding failed" msgstr "Malsukcesis transkodado de filmo" @@ -348,7 +376,7 @@ msgstr "" msgid "This field is required for public clients" msgstr "" -#: mediagoblin/plugins/oauth/views.py:59 +#: mediagoblin/plugins/oauth/views.py:56 msgid "The client {0} has been registered!" msgstr "" @@ -367,7 +395,7 @@ msgstr "" msgid "Add" msgstr "Aldoni" -#: mediagoblin/processing/__init__.py:172 +#: mediagoblin/processing/__init__.py:193 msgid "Invalid file given for media type." msgstr "La provizita dosiero ne konformas al la informtipo." @@ -375,45 +403,45 @@ msgstr "La provizita dosiero ne konformas al la informtipo." msgid "File" msgstr "Dosiero" -#: mediagoblin/submit/views.py:51 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "Vi devas provizi dosieron." -#: mediagoblin/submit/views.py:97 +#: mediagoblin/submit/views.py:93 msgid "Woohoo! Submitted!" msgstr "Hura! AlÅutitas!" -#: mediagoblin/submit/views.py:146 +#: mediagoblin/submit/views.py:144 #, python-format msgid "Collection \"%s\" added!" msgstr "Kolekto «%s» aldonitas!" -#: mediagoblin/templates/mediagoblin/base.html:64 +#: mediagoblin/templates/mediagoblin/base.html:67 msgid "Verify your email!" msgstr "Konfirmu viecon de la retpoÅtadreso!" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:68 msgid "log out" msgstr "elsaluti" -#: mediagoblin/templates/mediagoblin/base.html:70 +#: mediagoblin/templates/mediagoblin/base.html:73 #: mediagoblin/templates/mediagoblin/auth/login.html:28 #: mediagoblin/templates/mediagoblin/auth/login.html:36 #: mediagoblin/templates/mediagoblin/auth/login.html:54 msgid "Log in" msgstr "Ensaluti" -#: mediagoblin/templates/mediagoblin/base.html:79 +#: mediagoblin/templates/mediagoblin/base.html:82 #, python-format msgid "<a href=\"%(user_url)s\">%(user_name)s</a>'s account" msgstr "Konto de <a href=\"%(user_url)s\">%(user_name)s</a>" -#: mediagoblin/templates/mediagoblin/base.html:86 +#: mediagoblin/templates/mediagoblin/base.html:89 msgid "Change account settings" msgstr "ÅœanÄi kontagordojn" -#: mediagoblin/templates/mediagoblin/base.html:90 -#: mediagoblin/templates/mediagoblin/base.html:105 +#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:108 #: mediagoblin/templates/mediagoblin/admin/panel.html:21 #: mediagoblin/templates/mediagoblin/admin/panel.html:26 #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:21 @@ -421,72 +449,25 @@ msgstr "ÅœanÄi kontagordojn" msgid "Media processing panel" msgstr "Kontrolejo pri dosierpreparado." -#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:96 msgid "Log out" msgstr "Elsaluti" -#: mediagoblin/templates/mediagoblin/base.html:96 +#: mediagoblin/templates/mediagoblin/base.html:99 #: mediagoblin/templates/mediagoblin/user_pages/user.html:156 msgid "Add media" msgstr "Aldoni dosieron" -#: mediagoblin/templates/mediagoblin/base.html:99 +#: mediagoblin/templates/mediagoblin/base.html:102 #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:41 msgid "Create new collection" msgstr "Krei novan kolekton" -#: mediagoblin/templates/mediagoblin/base.html:122 -#, python-format -msgid "" -"Powered by <a href=\"http://mediagoblin.org/\" title='Version " -"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." -msgstr "Funkcias per <a href=\"http://mediagoblin.org/\" title='Versio %(version)s'>MediaGoblin</a>, unu el la <a href=\"http://gnu.org/\">projektoj de GNU</a>." - -#: mediagoblin/templates/mediagoblin/base.html:125 -#, 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/error.html:24 msgid "Image of goblin stressing out" msgstr "Bildo de zorgigita koboldo" -#: mediagoblin/templates/mediagoblin/root.html:31 -msgid "Explore" -msgstr "ĈirkaÅrigardi" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "Saluton, kaj bonvenon al ĉi tiu MediaGoblina retpaÄaro!" - -#: mediagoblin/templates/mediagoblin/root.html:35 -msgid "" -"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, an " -"extraordinarily great piece of media hosting software." -msgstr "Ĉi tiu retpaÄaro funkcias per <a href=\"http://mediagoblin.org\">MediaGoblin</a>, eksterordinare bonega programaro por gastigado de aÅdâ€vidâ€dosieroj." - -#: mediagoblin/templates/mediagoblin/root.html:36 -msgid "" -"To add your own media, place comments, and more, you can log in with your " -"MediaGoblin account." -msgstr "Por aldoni viajn proprajn dosierojn, afiÅi komentariojn ktp, vi povas ensaluti je via MediaGoblina konto." - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Don't have one yet? It's easy!" -msgstr "Ĉu vi ankoraÅ ne havas tian? Ne malÄoju!" - -#: mediagoblin/templates/mediagoblin/root.html:39 -#, 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\">Kreu konton en ĉi tiu retejo</a>\n aÅ\n <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">ekfunkciigu MediaGoblin’on en via propra servilo</a>" - -#: mediagoblin/templates/mediagoblin/root.html:47 +#: mediagoblin/templates/mediagoblin/root.html:32 msgid "Most recent media" msgstr "Laste aldonitaj dosieroj" @@ -592,6 +573,53 @@ msgid "" "%(verification_url)s" msgstr "Sal %(username)s,\n\npor aktivigi vian GNU MediaGoblin konton, malfermu la sekvantan URLon en via retumilo:\n\n%(verification_url)s" +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:21 +#, python-format +msgid "" +"Powered by <a href=\"http://mediagoblin.org/\" title='Version " +"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." +msgstr "Funkcias per <a href=\"http://mediagoblin.org/\" title='Versio %(version)s'>MediaGoblin</a>, unu el la <a href=\"http://gnu.org/\">projektoj de GNU</a>." + +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:24 +#, 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/bits/frontpage_welcome.html:20 +msgid "Explore" +msgstr "ĈirkaÅrigardi" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:22 +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "Saluton, kaj bonvenon al ĉi tiu MediaGoblina retpaÄaro!" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:24 +msgid "" +"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, an " +"extraordinarily great piece of media hosting software." +msgstr "Ĉi tiu retpaÄaro funkcias per <a href=\"http://mediagoblin.org\">MediaGoblin</a>, eksterordinare bonega programaro por gastigado de aÅdâ€vidâ€dosieroj." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:25 +msgid "" +"To add your own media, place comments, and more, you can log in with your " +"MediaGoblin account." +msgstr "Por aldoni viajn proprajn dosierojn, afiÅi komentariojn ktp, vi povas ensaluti je via MediaGoblina konto." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:27 +msgid "Don't have one yet? It's easy!" +msgstr "Ĉu vi ankoraÅ ne havas tian? Ne malÄoju!" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:28 +#, 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/bits/logo.html:23 #: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 msgid "MediaGoblin logo" @@ -604,13 +632,13 @@ msgid "Editing attachments for %(media_title)s" msgstr "Aldoni kundosierojn por %(media_title)s" #: mediagoblin/templates/mediagoblin/edit/attachments.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:159 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:175 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:182 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:198 msgid "Attachments" msgstr "Kundosieroj" #: mediagoblin/templates/mediagoblin/edit/attachments.html:57 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:181 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:204 msgid "Add attachment" msgstr "Aldoni kundosieron" @@ -627,12 +655,22 @@ msgstr "Nuligi" #: mediagoblin/templates/mediagoblin/edit/attachments.html:63 #: mediagoblin/templates/mediagoblin/edit/edit.html:42 -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:52 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:55 #: mediagoblin/templates/mediagoblin/edit/edit_collection.html:33 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:40 msgid "Save changes" msgstr "Konservi ÅanÄojn" +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:28 +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 +#, python-format +msgid "Changing %(username)s's password" +msgstr "ÅœanÄado de pasvorto de %(username)s" + +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 +msgid "Save" +msgstr "Konservi" + #: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 #, python-format msgid "Really delete user '%(user_name)s' and all related media/comments?" @@ -643,7 +681,7 @@ msgid "Yes, really delete my account" msgstr "Jes, efektive forigi mian konton" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:48 #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49 msgid "Delete permanently" msgstr "Forigi senrevene" @@ -660,7 +698,11 @@ msgstr "Priredaktado de %(media_title)s" msgid "Changing %(username)s's account settings" msgstr "ÅœanÄado de kontagordoj de %(username)s" -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:59 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 +msgid "Change your password." +msgstr "ÅœanÄi la pasvorton" + +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 msgid "Delete my account" msgstr "Forigi mian konton." @@ -685,6 +727,7 @@ msgstr "Dosieroj kun etikedo: %(tag_name)s" #: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 #: mediagoblin/templates/mediagoblin/media_displays/audio.html:56 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:65 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:136 #: mediagoblin/templates/mediagoblin/media_displays/video.html:55 msgid "Download" @@ -709,6 +752,7 @@ msgid "" 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:60 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:71 #: mediagoblin/templates/mediagoblin/media_displays/video.html:61 msgid "Original file" msgstr "originalan dosieron" @@ -717,6 +761,7 @@ msgstr "originalan dosieron" msgid "WebM file (Vorbis codec)" msgstr "WebMan dosieron (kun Vorbisa kodaĵo)" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:59 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:87 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:93 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:99 @@ -727,6 +772,10 @@ msgstr "WebMan dosieron (kun Vorbisa kodaĵo)" msgid "Image for %(media_title)s" msgstr "Bildo de «%(media_title)s»" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 +msgid "PDF file" +msgstr "PDF-dosiero" + #: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 msgid "Toggle Rotate" msgstr "" @@ -825,7 +874,7 @@ msgstr "Ĉu vere forigi %(title)s?" msgid "Really remove %(media_title)s from %(collection_title)s?" msgstr "Ĉu vere forigi %(media_title)s el %(collection_title)s?" -#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:54 msgid "Remove" msgstr "Forigi" @@ -868,24 +917,28 @@ msgstr "Dosieroj de <a href=\"%(user_url)s\">%(username)s</a>" 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:94 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:95 msgid "Add a comment" msgstr "Aldoni komenton" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 msgid "Add this comment" msgstr "Aldoni ĉi tiun komenton" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:123 -msgid "at" -msgstr "je" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:144 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:132 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:152 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:164 #, python-format -msgid "" -"<h3>Added on</h3>\n" -" <p>%(date)s</p>" -msgstr "<h3>Aldonita je</h3>\n <p>la %(date)s</p>" +msgid "%(formatted_time)s ago" +msgstr "antaÅ %(formatted_time)s" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:150 +msgid "Added" +msgstr "Aldonita" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:161 +msgid "Created" +msgstr "Kreita" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:40 @@ -1041,7 +1094,7 @@ msgstr "malpli nova" msgid "Tagged with" msgstr "Markita per" -#: mediagoblin/tools/exif.py:80 +#: mediagoblin/tools/exif.py:83 msgid "Could not read the image file." msgstr "Malsukcesis lego de la bildodosiero" @@ -1071,6 +1124,30 @@ msgid "" " deleted." msgstr "" +#: mediagoblin/tools/timesince.py:62 +msgid "year" +msgstr "jaro(j)" + +#: mediagoblin/tools/timesince.py:63 +msgid "month" +msgstr "monato(j)" + +#: mediagoblin/tools/timesince.py:64 +msgid "week" +msgstr "semajno(j)" + +#: mediagoblin/tools/timesince.py:65 +msgid "day" +msgstr "tago(j)" + +#: mediagoblin/tools/timesince.py:66 +msgid "hour" +msgstr "horo(j)" + +#: mediagoblin/tools/timesince.py:67 +msgid "minute" +msgstr "minuto(j)" + #: mediagoblin/user_pages/forms.py:23 msgid "Comment" msgstr "Komenti" @@ -1102,73 +1179,77 @@ msgstr "-- Elektu --" msgid "Include a note" msgstr "Rimarko" -#: mediagoblin/user_pages/lib.py:56 +#: mediagoblin/user_pages/lib.py:58 msgid "commented on your post" msgstr "komentis je via afiÅo" -#: mediagoblin/user_pages/views.py:166 +#: mediagoblin/user_pages/views.py:169 +msgid "Sorry, comments are disabled." +msgstr "Ve, komentado estas malebligita." + +#: mediagoblin/user_pages/views.py:174 msgid "Oops, your comment was empty." msgstr "Oj, via komento estis malplena." -#: mediagoblin/user_pages/views.py:172 +#: mediagoblin/user_pages/views.py:180 msgid "Your comment has been posted!" msgstr "Via komento estis afiÅita!" -#: mediagoblin/user_pages/views.py:197 +#: mediagoblin/user_pages/views.py:205 msgid "Please check your entries and try again." msgstr "Bonvolu kontroli vian enigitaĵon kaj reprovi." -#: mediagoblin/user_pages/views.py:237 +#: mediagoblin/user_pages/views.py:245 msgid "You have to select or add a collection" msgstr "Necesas elekti aÅ aldoni kolekton" -#: mediagoblin/user_pages/views.py:248 +#: mediagoblin/user_pages/views.py:256 #, python-format msgid "\"%s\" already in collection \"%s\"" msgstr "«%s» jam estas en la kolekto «%s»" -#: mediagoblin/user_pages/views.py:264 +#: mediagoblin/user_pages/views.py:262 #, python-format msgid "\"%s\" added to collection \"%s\"" msgstr "«%s» estis aldonita al la kolekto «%s»" -#: mediagoblin/user_pages/views.py:286 +#: mediagoblin/user_pages/views.py:282 msgid "You deleted the media." msgstr "Vi forigis la dosieron." -#: mediagoblin/user_pages/views.py:293 +#: mediagoblin/user_pages/views.py:289 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:301 +#: mediagoblin/user_pages/views.py:296 msgid "You are about to delete another user's media. Proceed with caution." msgstr "Vi estas forigonta dosieron de alia uzanto. Estu singardema." -#: mediagoblin/user_pages/views.py:375 +#: mediagoblin/user_pages/views.py:370 msgid "You deleted the item from the collection." msgstr "Vi forigis la dosieron el la kolekto." -#: mediagoblin/user_pages/views.py:379 +#: mediagoblin/user_pages/views.py:374 msgid "The item was not removed 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:389 +#: mediagoblin/user_pages/views.py:382 msgid "" "You are about to delete an item from another user's collection. Proceed with" " caution." msgstr "Vi estas forigonta dosieron el kolekto de alia uzanto. Agu singardeme." -#: mediagoblin/user_pages/views.py:422 +#: mediagoblin/user_pages/views.py:415 #, python-format msgid "You deleted the collection \"%s\"" msgstr "Vi forigis la kolekton «%s»" -#: mediagoblin/user_pages/views.py:429 +#: mediagoblin/user_pages/views.py:422 msgid "" "The collection was not deleted because you didn't check that you were sure." msgstr "La kolekto ne estis forigita, ĉar vi ne konfirmis vian certecon per la markilo." -#: mediagoblin/user_pages/views.py:439 +#: mediagoblin/user_pages/views.py:430 msgid "" "You are about to delete another user's collection. Proceed with caution." msgstr "Vi estas forigonta kolekton de alia uzanto. Agu singardeme." diff --git a/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.mo Binary files differindex e2df0731..c5e50f53 100644 --- a/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.mo +++ b/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.po index 21dce0b1..8c2f046f 100644 --- a/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/es/LC_MESSAGES/mediagoblin.po @@ -3,25 +3,25 @@ # This file is distributed under the same license as the PROJECT project. # # Translators: -# <deletesoftware@yandex.ru>, 2011, 2012. -# <ekenbrand@hotmail.com>, 2011. -# <jacobo@gnu.org>, 2011-2012. -# Javier Di Mauro <javierdimauro@gmail.com>, 2011. -# <juangsub@gmail.com>, 2011. -# <juanma@kde.org.ar>, 2011, 2012. -# <larjona99@gmail.com>, 2012. -# Laura Arjona Reina <larjona99@gmail.com>, 2013. -# Mario Rodriguez <msrodriguez00@gmail.com>, 2011. -# <mu@member.fsf.org>, 2011. -# <shackra@riseup.net>, 2012. -# <stardustprincess17@hotmail.com>, 2012. +# aleksejrs <deletesoftware@yandex.ru>, 2011, 2012 +# ekenbrand <ekenbrand@hotmail.com>, 2011 +# nvjacobo <jacobo@gnu.org>, 2011-2012 +# Javier Di Mauro <javierdimauro@gmail.com>, 2011 +# case <juangsub@gmail.com>, 2011 +# juanman <juanma@kde.org.ar>, 2011, 2012 +# larjona <larjona99@gmail.com>, 2012 +# larjona <larjona99@gmail.com>, 2013 +# Mario Rodriguez <msrodriguez00@gmail.com>, 2011 +# Manuel Urbano Santos <mu@member.fsf.org>, 2011 +# shackra <shackra@riseup.net>, 2012 +# Elesa <stardustprincess17@hotmail.com>, 2012 msgid "" msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" -"POT-Creation-Date: 2013-03-04 18:04-0600\n" -"PO-Revision-Date: 2013-03-05 00:04+0000\n" -"Last-Translator: cwebber <cwebber@dustycloud.org>\n" +"POT-Creation-Date: 2013-05-27 13:54-0500\n" +"PO-Revision-Date: 2013-06-02 21:23+0000\n" +"Last-Translator: larjona <larjona99@gmail.com>\n" "Language-Team: Spanish (http://www.transifex.com/projects/p/mediagoblin/language/es/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -30,34 +30,39 @@ msgstr "" "Language: es\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: mediagoblin/auth/forms.py:28 -msgid "Invalid User name or email address." -msgstr "Nombre de usuario o correo electrónico inválido." - -#: mediagoblin/auth/forms.py:29 -msgid "This field does not take email addresses." -msgstr "Este campo no acepta direcciones de correo." - -#: mediagoblin/auth/forms.py:30 -msgid "This field requires an email address." -msgstr "Este campo requiere una dirección de correo." - -#: mediagoblin/auth/forms.py:52 mediagoblin/auth/forms.py:67 +#: mediagoblin/auth/forms.py:26 msgid "Username" msgstr "Nombre de usuario" -#: mediagoblin/auth/forms.py:56 mediagoblin/auth/forms.py:71 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 +#: mediagoblin/tests/test_util.py:110 msgid "Password" msgstr "Contraseña" -#: mediagoblin/auth/forms.py:60 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "Dirección de correo electrónico" -#: mediagoblin/auth/forms.py:78 +#: mediagoblin/auth/forms.py:41 +msgid "Username or Email" +msgstr "Nombre de usuario o correo electrónico" + +#: mediagoblin/auth/forms.py:52 msgid "Username or email" msgstr "Nombre de usuario o email" +#: mediagoblin/auth/tools.py:31 +msgid "Invalid User name or email address." +msgstr "Nombre de usuario o correo electrónico inválido." + +#: mediagoblin/auth/tools.py:32 +msgid "This field does not take email addresses." +msgstr "Este campo no acepta direcciones de correo." + +#: mediagoblin/auth/tools.py:33 +msgid "This field requires an email address." +msgstr "Este campo requiere una dirección de correo." + #: mediagoblin/auth/views.py:54 msgid "Sorry, registration is disabled on this instance." msgstr "Lo sentimos, el registro está deshabilitado en este momento." @@ -70,54 +75,54 @@ msgstr "Lo sentimos, ya existe un usuario con ese nombre." msgid "Sorry, a user with that email address already exists." msgstr "Lo sentimos, ya existe un usuario con esa dirección de email." -#: mediagoblin/auth/views.py:174 +#: 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 iniciar sesión, editar tu perfil, y enviar imágenes!" -#: mediagoblin/auth/views.py:180 +#: 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" -#: mediagoblin/auth/views.py:198 +#: 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!" -#: mediagoblin/auth/views.py:206 +#: 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:219 +#: mediagoblin/auth/views.py:227 msgid "Resent your verification email." msgstr "Se reenvió tu correo electrónico de verificación." -#: mediagoblin/auth/views.py:250 +#: mediagoblin/auth/views.py:258 msgid "" "If that email address (case sensitive!) is registered an email has been sent" " with instructions on how to change your password." msgstr "Si esa dirección de correo (¡sensible a mayúsculas y minúsculas!) está registrada, se ha enviado un correo con instrucciones para cambiar la contraseña." -#: mediagoblin/auth/views.py:261 +#: mediagoblin/auth/views.py:269 msgid "Couldn't find someone with that username." msgstr "No se ha podido encontrar a nadie con ese nombre de usuario." -#: mediagoblin/auth/views.py:264 +#: mediagoblin/auth/views.py:272 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." -#: mediagoblin/auth/views.py:271 +#: mediagoblin/auth/views.py:279 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." msgstr "No se pudo enviar un correo electrónico de recuperación de contraseñas porque tu nombre de usuario está inactivo o la dirección de su cuenta de correo electrónico no ha sido verificada." -#: mediagoblin/auth/views.py:328 +#: mediagoblin/auth/views.py:336 msgid "You can now log in using your new password." msgstr "Ahora tu puedes iniciar sesión usando tu nueva contraseña." -#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:93 +#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:82 #: mediagoblin/submit/forms.py:28 mediagoblin/submit/forms.py:47 #: mediagoblin/user_pages/forms.py:45 msgid "Title" @@ -128,7 +133,7 @@ msgid "Description of this work" msgstr "Descripción de esta obra" #: mediagoblin/edit/forms.py:29 mediagoblin/edit/forms.py:52 -#: mediagoblin/edit/forms.py:97 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:86 mediagoblin/submit/forms.py:32 #: mediagoblin/submit/forms.py:51 mediagoblin/user_pages/forms.py:49 msgid "" "You can use\n" @@ -144,11 +149,11 @@ msgstr "Etiquetas" msgid "Separate tags by commas." msgstr "Separa las etiquetas por comas." -#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:101 +#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:90 msgid "Slug" msgstr "Ficha" -#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:102 +#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:91 msgid "The slug can't be empty" msgstr "La ficha no puede estar vacÃa" @@ -176,45 +181,45 @@ 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:64 -msgid "Enter your old password to prove you own this account." -msgstr "Escriba la anterior contraseña para demostrar que esta cuenta te pertenece." - -#: mediagoblin/edit/forms.py:67 -msgid "New password" -msgstr "Nueva contraseña" - -#: mediagoblin/edit/forms.py:74 msgid "License preference" msgstr "Preferencias de licencia" -#: mediagoblin/edit/forms.py:80 +#: mediagoblin/edit/forms.py:69 msgid "This will be your default license on upload forms." msgstr "Ésta será tu licencia predeterminada en los formularios de subida." -#: mediagoblin/edit/forms.py:82 +#: mediagoblin/edit/forms.py:71 msgid "Email me when others comment on my media" msgstr "EnvÃame un correo cuando otros escriban comentarios sobre mi contenido" -#: mediagoblin/edit/forms.py:94 +#: mediagoblin/edit/forms.py:83 msgid "The title can't be empty" msgstr "El tÃtulo no puede estar vacÃo" -#: mediagoblin/edit/forms.py:96 mediagoblin/submit/forms.py:50 +#: mediagoblin/edit/forms.py:85 mediagoblin/submit/forms.py:50 #: mediagoblin/user_pages/forms.py:48 msgid "Description of this collection" msgstr "Descripción de esta colección" -#: mediagoblin/edit/forms.py:103 +#: mediagoblin/edit/forms.py:92 msgid "" "The title part of this collection's address. You usually don't need to " "change this." msgstr "El tÃtulo de la dirección de esta colección. Generalmente no necesitas cambiar esto." -#: mediagoblin/edit/views.py:66 +#: mediagoblin/edit/forms.py:99 +msgid "Old password" +msgstr "Vieja contraseña" + +#: mediagoblin/edit/forms.py:101 +msgid "Enter your old password to prove you own this account." +msgstr "Escriba la anterior contraseña para demostrar que esta cuenta te pertenece." + +#: mediagoblin/edit/forms.py:104 +msgid "New password" +msgstr "Nueva contraseña" + +#: 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." @@ -239,44 +244,63 @@ msgstr "Estás editando un perfil de usuario. Procede con precaución." msgid "Profile changes saved" msgstr "Los cambios de perfil fueron salvados" -#: mediagoblin/edit/views.py:241 -msgid "Wrong password" -msgstr "Contraseña incorrecta" - -#: mediagoblin/edit/views.py:252 +#: mediagoblin/edit/views.py:240 msgid "Account settings saved" msgstr "las configuraciones de cuenta fueron salvadas" -#: mediagoblin/edit/views.py:286 +#: mediagoblin/edit/views.py:274 msgid "You need to confirm the deletion of your account." msgstr "Necesitas confirmar el borrado de tu cuenta." -#: mediagoblin/edit/views.py:322 mediagoblin/submit/views.py:142 -#: mediagoblin/user_pages/views.py:214 +#: mediagoblin/edit/views.py:310 mediagoblin/submit/views.py:138 +#: mediagoblin/user_pages/views.py:222 #, python-format msgid "You already have a collection called \"%s\"!" msgstr "¡Ya tienes una colección llamada \"%s\"!" -#: mediagoblin/edit/views.py:326 +#: mediagoblin/edit/views.py:314 msgid "A collection with that slug already exists for this user." msgstr "Una colección con esa ficha ya existe para este usuario/a." -#: mediagoblin/edit/views.py:343 +#: mediagoblin/edit/views.py:329 msgid "You are editing another user's collection. Proceed with caution." msgstr "Estás editando la colección de otro usuario/a. Ten cuidado." -#: mediagoblin/gmg_commands/theme.py:58 +#: mediagoblin/edit/views.py:348 +msgid "Wrong password" +msgstr "Contraseña incorrecta" + +#: mediagoblin/edit/views.py:363 +msgid "Your password was changed successfully" +msgstr "Se ha cambiado la contraseña correctamente" + +#: mediagoblin/gmg_commands/assetlink.py:60 msgid "Cannot link theme... no theme set\n" msgstr "No se puede enlazar al tema... no hay un tema seleccionado\n" -#: mediagoblin/gmg_commands/theme.py:71 +#: mediagoblin/gmg_commands/assetlink.py:73 msgid "No asset directory for this theme\n" msgstr "No hay directorio activo para este tema\n\n\n" -#: mediagoblin/gmg_commands/theme.py:74 +#: mediagoblin/gmg_commands/assetlink.py:76 msgid "However, old link directory symlink found; removed.\n" msgstr "Sin embargo, se encontró un enlace simbólico de un directorio antiguo; ha sido borrado.\n" +#: mediagoblin/gmg_commands/assetlink.py:112 +#, python-format +msgid "Could not link \"%s\": %s exists and is not a symlink\n" +msgstr "No se pudo enlazar \"%s\": %s existe y no es un enlace simbólico\n" + +#: mediagoblin/gmg_commands/assetlink.py:119 +#, python-format +msgid "Skipping \"%s\"; already set up.\n" +msgstr "Omitiendo \"%s\"; ya está establecido.\n" + +#: mediagoblin/gmg_commands/assetlink.py:124 +#, python-format +msgid "Old link found for \"%s\"; removing.\n" +msgstr "Se encontró un enlace antiguo para \"%s\"; se eliminará.\n" + #: mediagoblin/meddleware/csrf.py:134 msgid "" "CSRF cookie not present. This is most likely the result of a cookie blocker " @@ -284,12 +308,16 @@ msgid "" "domain." msgstr "No se encuentra la cookie CSRF. Esto suele ser debido a un bloqueador de cookies o similar.<br/> Por favor asegúrate de permitir las cookies para este dominio." -#: mediagoblin/media_types/__init__.py:61 -#: mediagoblin/media_types/__init__.py:102 +#: mediagoblin/media_types/__init__.py:111 +#: mediagoblin/media_types/__init__.py:155 msgid "Sorry, I don't support that file type :(" msgstr "Lo sentidos, No soportamos ese tipo de archivo :(" -#: mediagoblin/media_types/video/processing.py:36 +#: mediagoblin/media_types/pdf/processing.py:136 +msgid "unoconv failing to run, check log file" +msgstr "ha fallado la ejecución de unoconv, comprueba el fichero de registro (log)" + +#: mediagoblin/media_types/video/processing.py:37 msgid "Video transcoding failed" msgstr "Ha fallado la conversión de vÃdeo" @@ -356,7 +384,7 @@ msgstr "La URI para redireccionar las aplicaciones, este campo es <strong>requer msgid "This field is required for public clients" msgstr "Este campo es requerido para los clientes públicos" -#: mediagoblin/plugins/oauth/views.py:59 +#: mediagoblin/plugins/oauth/views.py:56 msgid "The client {0} has been registered!" msgstr "¡El cliente {0} ha sido registrado!" @@ -375,7 +403,7 @@ msgstr "Tus clientes OAuth" msgid "Add" msgstr "Añadir " -#: mediagoblin/processing/__init__.py:172 +#: mediagoblin/processing/__init__.py:193 msgid "Invalid file given for media type." msgstr "Archivo inválido para el formato seleccionado." @@ -383,45 +411,45 @@ msgstr "Archivo inválido para el formato seleccionado." msgid "File" msgstr "Archivo" -#: mediagoblin/submit/views.py:51 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "Debes proporcionar un archivo." -#: mediagoblin/submit/views.py:97 +#: mediagoblin/submit/views.py:93 msgid "Woohoo! Submitted!" msgstr "¡Yuju! ¡Enviado!" -#: mediagoblin/submit/views.py:146 +#: mediagoblin/submit/views.py:144 #, python-format msgid "Collection \"%s\" added!" msgstr "¡Colección \"%s\" añadida!" -#: mediagoblin/templates/mediagoblin/base.html:64 +#: mediagoblin/templates/mediagoblin/base.html:67 msgid "Verify your email!" msgstr "¡Verifica tu email!" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:68 msgid "log out" msgstr "cerrar sesión" -#: mediagoblin/templates/mediagoblin/base.html:70 +#: mediagoblin/templates/mediagoblin/base.html:73 #: mediagoblin/templates/mediagoblin/auth/login.html:28 #: mediagoblin/templates/mediagoblin/auth/login.html:36 #: mediagoblin/templates/mediagoblin/auth/login.html:54 msgid "Log in" msgstr "Iniciar sesión" -#: mediagoblin/templates/mediagoblin/base.html:79 +#: mediagoblin/templates/mediagoblin/base.html:82 #, python-format msgid "<a href=\"%(user_url)s\">%(user_name)s</a>'s account" msgstr "Cuenta de <a href=\"%(user_url)s\">%(user_name)s</a>" -#: mediagoblin/templates/mediagoblin/base.html:86 +#: mediagoblin/templates/mediagoblin/base.html:89 msgid "Change account settings" msgstr "Cambiar la configuración de la cuenta" -#: mediagoblin/templates/mediagoblin/base.html:90 -#: mediagoblin/templates/mediagoblin/base.html:105 +#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:108 #: mediagoblin/templates/mediagoblin/admin/panel.html:21 #: mediagoblin/templates/mediagoblin/admin/panel.html:26 #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:21 @@ -429,72 +457,25 @@ msgstr "Cambiar la configuración de la cuenta" msgid "Media processing panel" msgstr "Panel de procesamiento de contenido" -#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:96 msgid "Log out" -msgstr "" +msgstr "Cerrar sesión" -#: mediagoblin/templates/mediagoblin/base.html:96 +#: mediagoblin/templates/mediagoblin/base.html:99 #: mediagoblin/templates/mediagoblin/user_pages/user.html:156 msgid "Add media" msgstr "Añadir contenido" -#: mediagoblin/templates/mediagoblin/base.html:99 +#: mediagoblin/templates/mediagoblin/base.html:102 #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:41 msgid "Create new collection" msgstr "Crear nueva colección" -#: mediagoblin/templates/mediagoblin/base.html:122 -#, python-format -msgid "" -"Powered by <a href=\"http://mediagoblin.org/\" title='Version " -"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." -msgstr "Funciona con <a href=\"http://mediagoblin.org/\" title='Version %(version)s'>MediaGoblin</a>, un proyecto <a href=\"http://gnu.org/\">GNU</a>." - -#: mediagoblin/templates/mediagoblin/base.html:125 -#, 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/error.html:24 msgid "Image of goblin stressing out" msgstr "Imagen de un goblin estresándose" -#: mediagoblin/templates/mediagoblin/root.html:31 -msgid "Explore" -msgstr "Explorar" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "Hola, ¡bienvenido a este sitio de MediaGoblin!" - -#: mediagoblin/templates/mediagoblin/root.html:35 -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 extraordinario programa libre para alojar, gestionar y compartir contenido multimedia." - -#: mediagoblin/templates/mediagoblin/root.html:36 -msgid "" -"To add your own media, place comments, and more, you can log in with your " -"MediaGoblin account." -msgstr "Para añadir tus propios contenidos, dejar comentarios y más, puedes iniciar sesión con tu cuenta de MediaGoblin." - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Don't have one yet? It's easy!" -msgstr "¿Aún no tienes una? ¡Es fácil!" - -#: mediagoblin/templates/mediagoblin/root.html:39 -#, 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\">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:47 +#: mediagoblin/templates/mediagoblin/root.html:32 msgid "Most recent media" msgstr "El contenido más reciente" @@ -600,6 +581,53 @@ msgid "" "%(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/bits/base_footer.html:21 +#, python-format +msgid "" +"Powered by <a href=\"http://mediagoblin.org/\" title='Version " +"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." +msgstr "Funciona con <a href=\"http://mediagoblin.org/\" title='Version %(version)s'>MediaGoblin</a>, un proyecto <a href=\"http://gnu.org/\">GNU</a>." + +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:24 +#, 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/bits/frontpage_welcome.html:20 +msgid "Explore" +msgstr "Explorar" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:22 +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "Hola, ¡bienvenido a este sitio de MediaGoblin!" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:24 +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 extraordinario programa libre para alojar, gestionar y compartir contenido multimedia." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:25 +msgid "" +"To add your own media, place comments, and more, you can log in with your " +"MediaGoblin account." +msgstr "Para añadir tus propios contenidos, dejar comentarios y más, puedes iniciar sesión con tu cuenta de MediaGoblin." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:27 +msgid "Don't have one yet? It's easy!" +msgstr "¿Aún no tienes una? ¡Es fácil!" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:28 +#, 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\">Crear una cuenta en este sitio</a>\n o\n <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">Instalar MediaGoblin en tu propio servidor</a>" + #: mediagoblin/templates/mediagoblin/bits/logo.html:23 #: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 msgid "MediaGoblin logo" @@ -612,13 +640,13 @@ msgid "Editing attachments for %(media_title)s" msgstr "Editando archivos adjuntos a %(media_title)s" #: mediagoblin/templates/mediagoblin/edit/attachments.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:159 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:175 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:182 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:198 msgid "Attachments" msgstr "Adjuntos" #: mediagoblin/templates/mediagoblin/edit/attachments.html:57 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:181 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:204 msgid "Add attachment" msgstr "Agregar adjunto" @@ -635,12 +663,22 @@ msgstr "Cancelar" #: mediagoblin/templates/mediagoblin/edit/attachments.html:63 #: mediagoblin/templates/mediagoblin/edit/edit.html:42 -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:52 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:55 #: mediagoblin/templates/mediagoblin/edit/edit_collection.html:33 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:40 msgid "Save changes" msgstr "Guardar cambios" +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:28 +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 +#, python-format +msgid "Changing %(username)s's password" +msgstr "Cambiando la contraseña de %(username)s" + +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 +msgid "Save" +msgstr "Guardar" + #: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 #, python-format msgid "Really delete user '%(user_name)s' and all related media/comments?" @@ -651,7 +689,7 @@ msgid "Yes, really delete my account" msgstr "SÃ, borrar mi cuenta" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:48 #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49 msgid "Delete permanently" msgstr "Eliminar permanentemente" @@ -668,7 +706,11 @@ msgstr "Editando %(media_title)s " msgid "Changing %(username)s's account settings" msgstr "Cambio de %(username)s la configuración de la cuenta " -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:59 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 +msgid "Change your password." +msgstr "Cambiar tu contraseña." + +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 msgid "Delete my account" msgstr "Borrar mi cuenta" @@ -693,6 +735,7 @@ msgstr "Contenido etiquetado con: %(tag_name)s" #: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 #: mediagoblin/templates/mediagoblin/media_displays/audio.html:56 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:65 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:136 #: mediagoblin/templates/mediagoblin/media_displays/video.html:55 msgid "Download" @@ -717,6 +760,7 @@ msgid "" msgstr "Tú puedes obtener un navegador 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:60 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:71 #: mediagoblin/templates/mediagoblin/media_displays/video.html:61 msgid "Original file" msgstr "Archivo original" @@ -725,6 +769,7 @@ msgstr "Archivo original" msgid "WebM file (Vorbis codec)" msgstr "Archivo WebM (códec Vorbis)" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:59 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:87 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:93 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:99 @@ -735,6 +780,10 @@ msgstr "Archivo WebM (códec Vorbis)" msgid "Image for %(media_title)s" msgstr "Imágenes para %(media_title)s" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 +msgid "PDF file" +msgstr "Fichero PDF" + #: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 msgid "Toggle Rotate" msgstr "Alternar Rotar" @@ -833,7 +882,7 @@ msgstr "¿Realmente deseas eliminar %(title)s?" msgid "Really remove %(media_title)s from %(collection_title)s?" msgstr "¿Realmente quieres quitar %(media_title)s de %(collection_title)s?" -#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:54 msgid "Remove" msgstr "Quitar" @@ -876,24 +925,28 @@ msgstr "Contenido de <a href=\"%(user_url)s\">%(username)s</a>" 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:94 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:95 msgid "Add a comment" msgstr "Añadir un comentario" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 msgid "Add this comment" msgstr "Añade un comentario " -#: mediagoblin/templates/mediagoblin/user_pages/media.html:123 -msgid "at" -msgstr "en" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:144 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:132 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:152 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:164 #, python-format -msgid "" -"<h3>Added on</h3>\n" -" <p>%(date)s</p>" -msgstr "<h3>Añadido en</h3>\n <p>%(date)s</p>" +msgid "%(formatted_time)s ago" +msgstr "hace %(formatted_time)s" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:150 +msgid "Added" +msgstr "Agregado" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:161 +msgid "Created" +msgstr "Creado" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:40 @@ -1049,7 +1102,7 @@ msgstr "Más viejo" msgid "Tagged with" msgstr "Marcado con" -#: mediagoblin/tools/exif.py:80 +#: mediagoblin/tools/exif.py:83 msgid "Could not read the image file." msgstr "No se pudo leer el archivo de imagen." @@ -1079,6 +1132,30 @@ msgid "" " deleted." msgstr "Parece que no hay ninguna página en esta dirección. ¡Lo siento!</p><p>Si estás seguro de que la dirección es correcta, quizá han borrado o movido la página que estás buscando." +#: mediagoblin/tools/timesince.py:62 +msgid "year" +msgstr "año" + +#: mediagoblin/tools/timesince.py:63 +msgid "month" +msgstr "mes" + +#: mediagoblin/tools/timesince.py:64 +msgid "week" +msgstr "semana" + +#: mediagoblin/tools/timesince.py:65 +msgid "day" +msgstr "dÃa" + +#: mediagoblin/tools/timesince.py:66 +msgid "hour" +msgstr "hora" + +#: mediagoblin/tools/timesince.py:67 +msgid "minute" +msgstr "minuto" + #: mediagoblin/user_pages/forms.py:23 msgid "Comment" msgstr "Comentario" @@ -1110,73 +1187,77 @@ msgstr "-- Selecciona --" msgid "Include a note" msgstr "Incluir una nota" -#: mediagoblin/user_pages/lib.py:56 +#: mediagoblin/user_pages/lib.py:58 msgid "commented on your post" msgstr "comentó tu publicación" -#: mediagoblin/user_pages/views.py:166 +#: mediagoblin/user_pages/views.py:169 +msgid "Sorry, comments are disabled." +msgstr "Lo siento, los comentarios están desactivados." + +#: mediagoblin/user_pages/views.py:174 msgid "Oops, your comment was empty." msgstr "Ups, tu comentario estaba vacÃo." -#: mediagoblin/user_pages/views.py:172 +#: mediagoblin/user_pages/views.py:180 msgid "Your comment has been posted!" msgstr "¡Tu comentario ha sido publicado!" -#: mediagoblin/user_pages/views.py:197 +#: mediagoblin/user_pages/views.py:205 msgid "Please check your entries and try again." msgstr "Por favor, revisa tus entradas e inténtalo de nuevo." -#: mediagoblin/user_pages/views.py:237 +#: mediagoblin/user_pages/views.py:245 msgid "You have to select or add a collection" msgstr "Tienes que seleccionar o añadir una colección" -#: mediagoblin/user_pages/views.py:248 +#: mediagoblin/user_pages/views.py:256 #, python-format msgid "\"%s\" already in collection \"%s\"" msgstr "%s\" ya está en la colección \"%s\"" -#: mediagoblin/user_pages/views.py:264 +#: mediagoblin/user_pages/views.py:262 #, python-format msgid "\"%s\" added to collection \"%s\"" msgstr "\"%s\" añadido a la colección \"%s\"" -#: mediagoblin/user_pages/views.py:286 +#: mediagoblin/user_pages/views.py:282 msgid "You deleted the media." msgstr "Eliminaste el contenido" -#: mediagoblin/user_pages/views.py:293 +#: mediagoblin/user_pages/views.py:289 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:301 +#: mediagoblin/user_pages/views.py:296 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. Procede con precaución." -#: mediagoblin/user_pages/views.py:375 +#: mediagoblin/user_pages/views.py:370 msgid "You deleted the item from the collection." msgstr "Borraste el Ãtem de la colección." -#: mediagoblin/user_pages/views.py:379 +#: mediagoblin/user_pages/views.py:374 msgid "The item was not removed because you didn't check that you were sure." msgstr "El Ãtem no fue removido porque no confirmaste que estuvieras seguro/a." -#: mediagoblin/user_pages/views.py:389 +#: mediagoblin/user_pages/views.py:382 msgid "" "You are about to delete an item from another user's collection. Proceed with" " caution." msgstr "Estás a punto de borrar un Ãtem de la colección de otro usuario. Procede con cuidado." -#: mediagoblin/user_pages/views.py:422 +#: mediagoblin/user_pages/views.py:415 #, python-format msgid "You deleted the collection \"%s\"" msgstr "Borraste la colección \"%s\"" -#: mediagoblin/user_pages/views.py:429 +#: mediagoblin/user_pages/views.py:422 msgid "" "The collection was not deleted because you didn't check that you were sure." msgstr "La colección no fue borrada porque no confirmaste que estuvieras seguro/a." -#: mediagoblin/user_pages/views.py:439 +#: mediagoblin/user_pages/views.py:430 msgid "" "You are about to delete another user's collection. Proceed with caution." msgstr "Estás a punto de borrar la colección de otro usuario. Procede con cuidado." diff --git a/mediagoblin/i18n/fa/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/fa/LC_MESSAGES/mediagoblin.mo Binary files differindex 4b319ebd..3422ad97 100644 --- a/mediagoblin/i18n/fa/LC_MESSAGES/mediagoblin.mo +++ b/mediagoblin/i18n/fa/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/fa/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/fa/LC_MESSAGES/mediagoblin.po index 028ab5d4..08e73e1a 100644 --- a/mediagoblin/i18n/fa/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/fa/LC_MESSAGES/mediagoblin.po @@ -3,15 +3,15 @@ # This file is distributed under the same license as the PROJECT project. # # Translators: -# <amir007ag@gmail.com>, 2012. +# Numb <amir007ag@gmail.com>, 2012 msgid "" msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" -"POT-Creation-Date: 2013-03-04 18:04-0600\n" -"PO-Revision-Date: 2013-03-05 00:04+0000\n" +"POT-Creation-Date: 2013-05-27 13:54-0500\n" +"PO-Revision-Date: 2013-05-27 18:54+0000\n" "Last-Translator: cwebber <cwebber@dustycloud.org>\n" -"Language-Team: LANGUAGE <LL@li.org>\n" +"Language-Team: Persian (http://www.transifex.com/projects/p/mediagoblin/language/fa/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -19,34 +19,39 @@ msgstr "" "Language: fa\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: mediagoblin/auth/forms.py:28 -msgid "Invalid User name or email address." -msgstr "" - -#: mediagoblin/auth/forms.py:29 -msgid "This field does not take email addresses." -msgstr "" - -#: mediagoblin/auth/forms.py:30 -msgid "This field requires an email address." -msgstr "" - -#: mediagoblin/auth/forms.py:52 mediagoblin/auth/forms.py:67 +#: mediagoblin/auth/forms.py:26 msgid "Username" msgstr "نام کاربری" -#: mediagoblin/auth/forms.py:56 mediagoblin/auth/forms.py:71 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 +#: mediagoblin/tests/test_util.py:110 msgid "Password" msgstr "گذرواٰژه" -#: mediagoblin/auth/forms.py:60 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "آدرس ایمیل" -#: mediagoblin/auth/forms.py:78 +#: mediagoblin/auth/forms.py:41 +msgid "Username or Email" +msgstr "" + +#: mediagoblin/auth/forms.py:52 msgid "Username or email" msgstr "" +#: mediagoblin/auth/tools.py:31 +msgid "Invalid User name or email address." +msgstr "" + +#: mediagoblin/auth/tools.py:32 +msgid "This field does not take email addresses." +msgstr "" + +#: mediagoblin/auth/tools.py:33 +msgid "This field requires an email address." +msgstr "" + #: mediagoblin/auth/views.py:54 msgid "Sorry, registration is disabled on this instance." msgstr "Ù…ØªØ§Ø³ÙØ§Ù†Ù‡ØŒØ«Ø¨ØªÙ†Ø§Ù… به طور موقت غیر ÙØ¹Ø§Ù„ است." @@ -59,54 +64,54 @@ msgstr "Ù…ØªØ§Ø³ÙØ§Ù†Ù‡ کاربری با این نام کاربری وجود Ø msgid "Sorry, a user with that email address already exists." msgstr "" -#: mediagoblin/auth/views.py:174 +#: 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:180 +#: mediagoblin/auth/views.py:188 msgid "The verification key or user id is incorrect" msgstr "این کد تاییدیه یا شناسه کاربری صØÛŒØ نیست." -#: mediagoblin/auth/views.py:198 +#: 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:206 +#: mediagoblin/auth/views.py:214 msgid "You've already verified your email address!" msgstr "" -#: mediagoblin/auth/views.py:219 +#: mediagoblin/auth/views.py:227 msgid "Resent your verification email." msgstr "ایمیل تاییدیه باز ارسال شد." -#: mediagoblin/auth/views.py:250 +#: mediagoblin/auth/views.py:258 msgid "" "If that email address (case sensitive!) is registered an email has been sent" " with instructions on how to change your password." msgstr "" -#: mediagoblin/auth/views.py:261 +#: mediagoblin/auth/views.py:269 msgid "Couldn't find someone with that username." msgstr "" -#: mediagoblin/auth/views.py:264 +#: mediagoblin/auth/views.py:272 msgid "" "An email has been sent with instructions on how to change your password." msgstr "" -#: mediagoblin/auth/views.py:271 +#: mediagoblin/auth/views.py:279 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." msgstr "" -#: mediagoblin/auth/views.py:328 +#: mediagoblin/auth/views.py:336 msgid "You can now log in using your new password." msgstr "" -#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:93 +#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:82 #: mediagoblin/submit/forms.py:28 mediagoblin/submit/forms.py:47 #: mediagoblin/user_pages/forms.py:45 msgid "Title" @@ -117,7 +122,7 @@ msgid "Description of this work" msgstr "" #: mediagoblin/edit/forms.py:29 mediagoblin/edit/forms.py:52 -#: mediagoblin/edit/forms.py:97 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:86 mediagoblin/submit/forms.py:32 #: mediagoblin/submit/forms.py:51 mediagoblin/user_pages/forms.py:49 msgid "" "You can use\n" @@ -133,11 +138,11 @@ msgstr "برچسب" msgid "Separate tags by commas." msgstr "" -#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:101 +#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:90 msgid "Slug" msgstr "" -#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:102 +#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:91 msgid "The slug can't be empty" msgstr "" @@ -165,45 +170,45 @@ msgid "This address contains errors" msgstr "" #: mediagoblin/edit/forms.py:63 -msgid "Old password" -msgstr "" - -#: mediagoblin/edit/forms.py:64 -msgid "Enter your old password to prove you own this account." -msgstr "" - -#: mediagoblin/edit/forms.py:67 -msgid "New password" -msgstr "" - -#: mediagoblin/edit/forms.py:74 msgid "License preference" msgstr "" -#: mediagoblin/edit/forms.py:80 +#: mediagoblin/edit/forms.py:69 msgid "This will be your default license on upload forms." msgstr "" -#: mediagoblin/edit/forms.py:82 +#: mediagoblin/edit/forms.py:71 msgid "Email me when others comment on my media" msgstr "" -#: mediagoblin/edit/forms.py:94 +#: mediagoblin/edit/forms.py:83 msgid "The title can't be empty" msgstr "" -#: mediagoblin/edit/forms.py:96 mediagoblin/submit/forms.py:50 +#: mediagoblin/edit/forms.py:85 mediagoblin/submit/forms.py:50 #: mediagoblin/user_pages/forms.py:48 msgid "Description of this collection" msgstr "" -#: mediagoblin/edit/forms.py:103 +#: mediagoblin/edit/forms.py:92 msgid "" "The title part of this collection's address. You usually don't need to " "change this." msgstr "" -#: mediagoblin/edit/views.py:66 +#: mediagoblin/edit/forms.py:99 +msgid "Old password" +msgstr "" + +#: mediagoblin/edit/forms.py:101 +msgid "Enter your old password to prove you own this account." +msgstr "" + +#: mediagoblin/edit/forms.py:104 +msgid "New password" +msgstr "" + +#: mediagoblin/edit/views.py:67 msgid "An entry with that slug already exists for this user." msgstr "" @@ -228,44 +233,63 @@ msgstr "شما در ØØ§Ù„ ویرایش نمایه کاربر دیگری Ù‡Ø³ØªÛ msgid "Profile changes saved" msgstr "" -#: mediagoblin/edit/views.py:241 -msgid "Wrong password" -msgstr "" - -#: mediagoblin/edit/views.py:252 +#: mediagoblin/edit/views.py:240 msgid "Account settings saved" msgstr "" -#: mediagoblin/edit/views.py:286 +#: mediagoblin/edit/views.py:274 msgid "You need to confirm the deletion of your account." msgstr "" -#: mediagoblin/edit/views.py:322 mediagoblin/submit/views.py:142 -#: mediagoblin/user_pages/views.py:214 +#: mediagoblin/edit/views.py:310 mediagoblin/submit/views.py:138 +#: mediagoblin/user_pages/views.py:222 #, python-format msgid "You already have a collection called \"%s\"!" msgstr "" -#: mediagoblin/edit/views.py:326 +#: mediagoblin/edit/views.py:314 msgid "A collection with that slug already exists for this user." msgstr "" -#: mediagoblin/edit/views.py:343 +#: mediagoblin/edit/views.py:329 msgid "You are editing another user's collection. Proceed with caution." msgstr "" -#: mediagoblin/gmg_commands/theme.py:58 +#: mediagoblin/edit/views.py:348 +msgid "Wrong password" +msgstr "" + +#: mediagoblin/edit/views.py:363 +msgid "Your password was changed successfully" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:60 msgid "Cannot link theme... no theme set\n" msgstr "" -#: mediagoblin/gmg_commands/theme.py:71 +#: mediagoblin/gmg_commands/assetlink.py:73 msgid "No asset directory for this theme\n" msgstr "" -#: mediagoblin/gmg_commands/theme.py:74 +#: mediagoblin/gmg_commands/assetlink.py:76 msgid "However, old link directory symlink found; removed.\n" msgstr "" +#: mediagoblin/gmg_commands/assetlink.py:112 +#, python-format +msgid "Could not link \"%s\": %s exists and is not a symlink\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:119 +#, python-format +msgid "Skipping \"%s\"; already set up.\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:124 +#, python-format +msgid "Old link found for \"%s\"; removing.\n" +msgstr "" + #: mediagoblin/meddleware/csrf.py:134 msgid "" "CSRF cookie not present. This is most likely the result of a cookie blocker " @@ -273,12 +297,16 @@ msgid "" "domain." msgstr "" -#: mediagoblin/media_types/__init__.py:61 -#: mediagoblin/media_types/__init__.py:102 +#: mediagoblin/media_types/__init__.py:111 +#: mediagoblin/media_types/__init__.py:155 msgid "Sorry, I don't support that file type :(" msgstr "" -#: mediagoblin/media_types/video/processing.py:36 +#: mediagoblin/media_types/pdf/processing.py:136 +msgid "unoconv failing to run, check log file" +msgstr "" + +#: mediagoblin/media_types/video/processing.py:37 msgid "Video transcoding failed" msgstr "" @@ -345,7 +373,7 @@ msgstr "" msgid "This field is required for public clients" msgstr "" -#: mediagoblin/plugins/oauth/views.py:59 +#: mediagoblin/plugins/oauth/views.py:56 msgid "The client {0} has been registered!" msgstr "" @@ -364,7 +392,7 @@ msgstr "" msgid "Add" msgstr "" -#: mediagoblin/processing/__init__.py:172 +#: mediagoblin/processing/__init__.py:193 msgid "Invalid file given for media type." msgstr "ÙØ§ÛŒÙ„ÛŒ نا معتبر برای نوع رسانه داده شده." @@ -372,45 +400,45 @@ msgstr "ÙØ§ÛŒÙ„ÛŒ نا معتبر برای نوع رسانه داده شده." msgid "File" msgstr "ÙØ§ÛŒÙ„" -#: mediagoblin/submit/views.py:51 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "شما باید ÙØ§ÛŒÙ„ÛŒ ارايه بدهید." -#: mediagoblin/submit/views.py:97 +#: mediagoblin/submit/views.py:93 msgid "Woohoo! Submitted!" msgstr "هورا!ثبت شد!" -#: mediagoblin/submit/views.py:146 +#: mediagoblin/submit/views.py:144 #, python-format msgid "Collection \"%s\" added!" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:64 +#: mediagoblin/templates/mediagoblin/base.html:67 msgid "Verify your email!" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:68 msgid "log out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:70 +#: mediagoblin/templates/mediagoblin/base.html:73 #: mediagoblin/templates/mediagoblin/auth/login.html:28 #: mediagoblin/templates/mediagoblin/auth/login.html:36 #: mediagoblin/templates/mediagoblin/auth/login.html:54 msgid "Log in" msgstr "ورود" -#: mediagoblin/templates/mediagoblin/base.html:79 +#: mediagoblin/templates/mediagoblin/base.html:82 #, python-format msgid "<a href=\"%(user_url)s\">%(user_name)s</a>'s account" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:86 +#: mediagoblin/templates/mediagoblin/base.html:89 msgid "Change account settings" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:90 -#: mediagoblin/templates/mediagoblin/base.html:105 +#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:108 #: mediagoblin/templates/mediagoblin/admin/panel.html:21 #: mediagoblin/templates/mediagoblin/admin/panel.html:26 #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:21 @@ -418,72 +446,25 @@ msgstr "" msgid "Media processing panel" msgstr "پنل رسیدگی به رسانه ها" -#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:96 msgid "Log out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:96 +#: mediagoblin/templates/mediagoblin/base.html:99 #: mediagoblin/templates/mediagoblin/user_pages/user.html:156 msgid "Add media" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:99 +#: mediagoblin/templates/mediagoblin/base.html:102 #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:41 msgid "Create new collection" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:122 -#, python-format -msgid "" -"Powered by <a href=\"http://mediagoblin.org/\" title='Version " -"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." -msgstr "" - -#: mediagoblin/templates/mediagoblin/base.html:125 -#, 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/error.html:24 msgid "Image of goblin stressing out" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:31 -msgid "Explore" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:35 -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:36 -msgid "" -"To add your own media, place comments, and more, you can log in with your " -"MediaGoblin account." -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Don't have one yet? It's easy!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:39 -#, 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:47 +#: mediagoblin/templates/mediagoblin/root.html:32 msgid "Most recent media" msgstr "" @@ -589,6 +570,53 @@ msgid "" "%(verification_url)s" msgstr "سلام %(username)s,\n\nبرای ÙØ¹Ø§Ù„ سازی شناسه کاربری گنو مدیاگوبلین خود ،پیوند زیر را در مرورگر خود باز کنید.\n\n%(verification_url)s" +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:21 +#, python-format +msgid "" +"Powered by <a href=\"http://mediagoblin.org/\" title='Version " +"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:24 +#, 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/bits/frontpage_welcome.html:20 +msgid "Explore" +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:22 +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:24 +msgid "" +"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, an " +"extraordinarily great piece of media hosting software." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:25 +msgid "" +"To add your own media, place comments, and more, you can log in with your " +"MediaGoblin account." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:27 +msgid "Don't have one yet? It's easy!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:28 +#, python-format +msgid "" +"<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/bits/logo.html:23 #: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 msgid "MediaGoblin logo" @@ -601,13 +629,13 @@ msgid "Editing attachments for %(media_title)s" msgstr "" #: mediagoblin/templates/mediagoblin/edit/attachments.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:159 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:175 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:182 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:198 msgid "Attachments" msgstr "" #: mediagoblin/templates/mediagoblin/edit/attachments.html:57 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:181 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:204 msgid "Add attachment" msgstr "" @@ -624,12 +652,22 @@ msgstr "انصراÙ" #: mediagoblin/templates/mediagoblin/edit/attachments.html:63 #: mediagoblin/templates/mediagoblin/edit/edit.html:42 -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:52 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:55 #: mediagoblin/templates/mediagoblin/edit/edit_collection.html:33 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:40 msgid "Save changes" msgstr "ذخیره تغییرات" +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:28 +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 +#, python-format +msgid "Changing %(username)s's password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 +msgid "Save" +msgstr "" + #: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 #, python-format msgid "Really delete user '%(user_name)s' and all related media/comments?" @@ -640,7 +678,7 @@ msgid "Yes, really delete my account" msgstr "" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:48 #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49 msgid "Delete permanently" msgstr "" @@ -657,7 +695,11 @@ msgstr "ویرایش %(media_title)s" msgid "Changing %(username)s's account settings" msgstr "" -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:59 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 +msgid "Change your password." +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 msgid "Delete my account" msgstr "" @@ -682,6 +724,7 @@ msgstr "" #: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 #: mediagoblin/templates/mediagoblin/media_displays/audio.html:56 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:65 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:136 #: mediagoblin/templates/mediagoblin/media_displays/video.html:55 msgid "Download" @@ -706,6 +749,7 @@ msgid "" msgstr "" #: mediagoblin/templates/mediagoblin/media_displays/audio.html:60 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:71 #: mediagoblin/templates/mediagoblin/media_displays/video.html:61 msgid "Original file" msgstr "" @@ -714,6 +758,7 @@ msgstr "" msgid "WebM file (Vorbis codec)" msgstr "" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:59 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:87 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:93 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:99 @@ -724,6 +769,10 @@ msgstr "" msgid "Image for %(media_title)s" msgstr "" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 +msgid "PDF file" +msgstr "" + #: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 msgid "Toggle Rotate" msgstr "" @@ -822,7 +871,7 @@ msgstr "" msgid "Really remove %(media_title)s from %(collection_title)s?" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:54 msgid "Remove" msgstr "" @@ -865,23 +914,27 @@ msgstr "<a href=\"%(user_url)s\">%(username)s</a>'s رسانه های" msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:94 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:95 msgid "Add a comment" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 msgid "Add this comment" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:123 -msgid "at" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:132 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:152 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:164 +#, python-format +msgid "%(formatted_time)s ago" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:144 -#, python-format -msgid "" -"<h3>Added on</h3>\n" -" <p>%(date)s</p>" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:150 +msgid "Added" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:161 +msgid "Created" msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 @@ -1038,7 +1091,7 @@ msgstr "" msgid "Tagged with" msgstr "" -#: mediagoblin/tools/exif.py:80 +#: mediagoblin/tools/exif.py:83 msgid "Could not read the image file." msgstr "" @@ -1068,6 +1121,30 @@ msgid "" " deleted." msgstr "" +#: mediagoblin/tools/timesince.py:62 +msgid "year" +msgstr "" + +#: mediagoblin/tools/timesince.py:63 +msgid "month" +msgstr "" + +#: mediagoblin/tools/timesince.py:64 +msgid "week" +msgstr "" + +#: mediagoblin/tools/timesince.py:65 +msgid "day" +msgstr "" + +#: mediagoblin/tools/timesince.py:66 +msgid "hour" +msgstr "" + +#: mediagoblin/tools/timesince.py:67 +msgid "minute" +msgstr "" + #: mediagoblin/user_pages/forms.py:23 msgid "Comment" msgstr "" @@ -1099,73 +1176,77 @@ msgstr "" msgid "Include a note" msgstr "" -#: mediagoblin/user_pages/lib.py:56 +#: mediagoblin/user_pages/lib.py:58 msgid "commented on your post" msgstr "" -#: mediagoblin/user_pages/views.py:166 +#: mediagoblin/user_pages/views.py:169 +msgid "Sorry, comments are disabled." +msgstr "" + +#: mediagoblin/user_pages/views.py:174 msgid "Oops, your comment was empty." msgstr "" -#: mediagoblin/user_pages/views.py:172 +#: mediagoblin/user_pages/views.py:180 msgid "Your comment has been posted!" msgstr "" -#: mediagoblin/user_pages/views.py:197 +#: mediagoblin/user_pages/views.py:205 msgid "Please check your entries and try again." msgstr "" -#: mediagoblin/user_pages/views.py:237 +#: mediagoblin/user_pages/views.py:245 msgid "You have to select or add a collection" msgstr "" -#: mediagoblin/user_pages/views.py:248 +#: mediagoblin/user_pages/views.py:256 #, python-format msgid "\"%s\" already in collection \"%s\"" msgstr "" -#: mediagoblin/user_pages/views.py:264 +#: mediagoblin/user_pages/views.py:262 #, python-format msgid "\"%s\" added to collection \"%s\"" msgstr "" -#: mediagoblin/user_pages/views.py:286 +#: mediagoblin/user_pages/views.py:282 msgid "You deleted the media." msgstr "" -#: mediagoblin/user_pages/views.py:293 +#: mediagoblin/user_pages/views.py:289 msgid "The media was not deleted because you didn't check that you were sure." msgstr "" -#: mediagoblin/user_pages/views.py:301 +#: mediagoblin/user_pages/views.py:296 msgid "You are about to delete another user's media. Proceed with caution." msgstr "" -#: mediagoblin/user_pages/views.py:375 +#: mediagoblin/user_pages/views.py:370 msgid "You deleted the item from the collection." msgstr "" -#: mediagoblin/user_pages/views.py:379 +#: mediagoblin/user_pages/views.py:374 msgid "The item was not removed because you didn't check that you were sure." msgstr "" -#: mediagoblin/user_pages/views.py:389 +#: mediagoblin/user_pages/views.py:382 msgid "" "You are about to delete an item from another user's collection. Proceed with" " caution." msgstr "" -#: mediagoblin/user_pages/views.py:422 +#: mediagoblin/user_pages/views.py:415 #, python-format msgid "You deleted the collection \"%s\"" msgstr "" -#: mediagoblin/user_pages/views.py:429 +#: mediagoblin/user_pages/views.py:422 msgid "" "The collection was not deleted because you didn't check that you were sure." msgstr "" -#: mediagoblin/user_pages/views.py:439 +#: mediagoblin/user_pages/views.py:430 msgid "" "You are about to delete another user's collection. Proceed with caution." msgstr "" diff --git a/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.mo Binary files differindex ada992ce..7bc860a0 100644 --- a/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.mo +++ b/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.po index b4c76bd2..6103c439 100644 --- a/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/fr/LC_MESSAGES/mediagoblin.po @@ -3,22 +3,22 @@ # This file is distributed under the same license as the PROJECT project. # # Translators: -# <a5565930@nepwk.com>, 2011. -# <alexispay@gmail.com>, 2012. -# <chesuidayeur@yahoo.fr>, 2011. -# <crash_bibit@hotmail.com>, 2013. -# <joehillen@gmail.com>, 2011. -# Laurent Pointecouteau <hell_pe@no-log.org>, 2013. -# <marktraceur@gmail.com>, 2011. -# <maxineb@members.fsf.org>, 2011. -# <transifex@wandborg.se>, 2011. -# Valentin Villenave <valentin@villenave.net>, 2011. +# ianux <a5565930@nepwk.com>, 2011 +# alcazar <alexispay@gmail.com>, 2012 +# chesuidayeur <chesuidayeur@yahoo.fr>, 2011 +# Bibit <crash_bibit@hotmail.com>, 2013 +# joehillen <joehillen@gmail.com>, 2011 +# hellpe <hell_pe@no-log.org>, 2013 +# MarkTraceur <marktraceur@gmail.com>, 2011 +# maxineb <maxineb@members.fsf.org>, 2011 +# joar <transifex@wandborg.se>, 2011 +# Valentin Villenave <valentin@villenave.net>, 2011 msgid "" msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" -"POT-Creation-Date: 2013-03-04 18:04-0600\n" -"PO-Revision-Date: 2013-03-05 00:04+0000\n" +"POT-Creation-Date: 2013-05-27 13:54-0500\n" +"PO-Revision-Date: 2013-05-27 18:54+0000\n" "Last-Translator: cwebber <cwebber@dustycloud.org>\n" "Language-Team: French (http://www.transifex.com/projects/p/mediagoblin/language/fr/)\n" "MIME-Version: 1.0\n" @@ -28,34 +28,39 @@ msgstr "" "Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: mediagoblin/auth/forms.py:28 -msgid "Invalid User name or email address." -msgstr "Nom d'utilisateur ou adresse de courriel invalide." - -#: mediagoblin/auth/forms.py:29 -msgid "This field does not take email addresses." -msgstr "" - -#: mediagoblin/auth/forms.py:30 -msgid "This field requires an email address." -msgstr "" - -#: mediagoblin/auth/forms.py:52 mediagoblin/auth/forms.py:67 +#: mediagoblin/auth/forms.py:26 msgid "Username" msgstr "Nom d'utilisateur" -#: mediagoblin/auth/forms.py:56 mediagoblin/auth/forms.py:71 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 +#: mediagoblin/tests/test_util.py:110 msgid "Password" msgstr "Mot de passe" -#: mediagoblin/auth/forms.py:60 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "Adresse e-mail" -#: mediagoblin/auth/forms.py:78 +#: mediagoblin/auth/forms.py:41 +msgid "Username or Email" +msgstr "" + +#: mediagoblin/auth/forms.py:52 msgid "Username or email" msgstr "Nom d'utilisateur ou email" +#: mediagoblin/auth/tools.py:31 +msgid "Invalid User name or email address." +msgstr "Nom d'utilisateur ou adresse de courriel invalide." + +#: mediagoblin/auth/tools.py:32 +msgid "This field does not take email addresses." +msgstr "" + +#: mediagoblin/auth/tools.py:33 +msgid "This field requires an email address." +msgstr "" + #: mediagoblin/auth/views.py:54 msgid "Sorry, registration is disabled on this instance." msgstr "L'inscription n'est pas activée sur ce serveur, désolé." @@ -68,54 +73,54 @@ msgstr "Un utilisateur existe déjà avec ce nom, désolé." 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:174 +#: 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 !" -#: mediagoblin/auth/views.py:180 +#: 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:198 +#: 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 !" -#: mediagoblin/auth/views.py:206 +#: 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:219 +#: mediagoblin/auth/views.py:227 msgid "Resent your verification email." msgstr "E-mail de vérification renvoyé." -#: mediagoblin/auth/views.py:250 +#: mediagoblin/auth/views.py:258 msgid "" "If that email address (case sensitive!) is registered an email has been sent" " with instructions on how to change your password." msgstr "" -#: mediagoblin/auth/views.py:261 +#: mediagoblin/auth/views.py:269 msgid "Couldn't find someone with that username." msgstr "Nom d'utilisateur introuvable." -#: mediagoblin/auth/views.py:264 +#: mediagoblin/auth/views.py:272 msgid "" "An email has been sent with instructions on how to change your password." msgstr "Un email contenant les instructions pour changer votre mot de passe viens de vous être envoyé" -#: mediagoblin/auth/views.py:271 +#: mediagoblin/auth/views.py:279 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." msgstr "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:328 +#: mediagoblin/auth/views.py:336 msgid "You can now log in using your new password." msgstr "Vous pouvez maintenant vous connecter avec votre nouveau mot de passe." -#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:93 +#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:82 #: mediagoblin/submit/forms.py:28 mediagoblin/submit/forms.py:47 #: mediagoblin/user_pages/forms.py:45 msgid "Title" @@ -126,7 +131,7 @@ msgid "Description of this work" msgstr "Descriptif pour ce travail" #: mediagoblin/edit/forms.py:29 mediagoblin/edit/forms.py:52 -#: mediagoblin/edit/forms.py:97 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:86 mediagoblin/submit/forms.py:32 #: mediagoblin/submit/forms.py:51 mediagoblin/user_pages/forms.py:49 msgid "" "You can use\n" @@ -142,11 +147,11 @@ msgstr "Tags" msgid "Separate tags by commas." msgstr "Séparez les champs avec des virgules." -#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:101 +#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:90 msgid "Slug" msgstr "Légende" -#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:102 +#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:91 msgid "The slug can't be empty" msgstr "La légende ne peut pas être laissée vide." @@ -174,45 +179,45 @@ msgid "This address contains errors" msgstr "Cette adresse contiens des erreurs" #: mediagoblin/edit/forms.py:63 -msgid "Old password" -msgstr "Ancien mot de passe." - -#: mediagoblin/edit/forms.py:64 -msgid "Enter your old password to prove you own this account." -msgstr "Entrez votre ancien mot de passe pour prouver que vous êtes bien le propriétaire de ce compte." - -#: mediagoblin/edit/forms.py:67 -msgid "New password" -msgstr "Nouveau mot de passe" - -#: mediagoblin/edit/forms.py:74 msgid "License preference" msgstr "" -#: mediagoblin/edit/forms.py:80 +#: mediagoblin/edit/forms.py:69 msgid "This will be your default license on upload forms." msgstr "" -#: mediagoblin/edit/forms.py:82 +#: mediagoblin/edit/forms.py:71 msgid "Email me when others comment on my media" msgstr "Me prévenir par email lorsque d'autres commentent mes médias" -#: mediagoblin/edit/forms.py:94 +#: mediagoblin/edit/forms.py:83 msgid "The title can't be empty" msgstr "Le titre ne peut être vide" -#: mediagoblin/edit/forms.py:96 mediagoblin/submit/forms.py:50 +#: mediagoblin/edit/forms.py:85 mediagoblin/submit/forms.py:50 #: mediagoblin/user_pages/forms.py:48 msgid "Description of this collection" msgstr "Description de cette collection" -#: mediagoblin/edit/forms.py:103 +#: mediagoblin/edit/forms.py:92 msgid "" "The title part of this collection's address. You usually don't need to " "change this." msgstr "Le titre affiché dans l'URL de la collection. Vous n'avez généralement pas besoin d'y toucher." -#: mediagoblin/edit/views.py:66 +#: mediagoblin/edit/forms.py:99 +msgid "Old password" +msgstr "Ancien mot de passe." + +#: mediagoblin/edit/forms.py:101 +msgid "Enter your old password to prove you own this account." +msgstr "Entrez votre ancien mot de passe pour prouver que vous êtes bien le propriétaire de ce compte." + +#: mediagoblin/edit/forms.py:104 +msgid "New password" +msgstr "Nouveau mot de passe" + +#: 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." @@ -237,44 +242,63 @@ msgstr "Vous vous apprêtez à modifier le profil d'un utilisateur. Veuillez pre msgid "Profile changes saved" msgstr "Les changements apportés au profile ont étés sauvegardés" -#: mediagoblin/edit/views.py:241 -msgid "Wrong password" -msgstr "Mauvais mot de passe" - -#: mediagoblin/edit/views.py:252 +#: mediagoblin/edit/views.py:240 msgid "Account settings saved" msgstr "Les changements des préférences du compte ont étés sauvegardés" -#: mediagoblin/edit/views.py:286 +#: mediagoblin/edit/views.py:274 msgid "You need to confirm the deletion of your account." msgstr "Vous devez confirmer la suppression de votre compte." -#: mediagoblin/edit/views.py:322 mediagoblin/submit/views.py:142 -#: mediagoblin/user_pages/views.py:214 +#: mediagoblin/edit/views.py:310 mediagoblin/submit/views.py:138 +#: mediagoblin/user_pages/views.py:222 #, python-format msgid "You already have a collection called \"%s\"!" msgstr "Vous avez déjà une collection appelée \"%s\" !" -#: mediagoblin/edit/views.py:326 +#: mediagoblin/edit/views.py:314 msgid "A collection with that slug already exists for this user." msgstr "" -#: mediagoblin/edit/views.py:343 +#: mediagoblin/edit/views.py:329 msgid "You are editing another user's collection. Proceed with caution." msgstr "Vous éditez la collection d'un autre utilisateurs. Faites attention." -#: mediagoblin/gmg_commands/theme.py:58 +#: mediagoblin/edit/views.py:348 +msgid "Wrong password" +msgstr "Mauvais mot de passe" + +#: mediagoblin/edit/views.py:363 +msgid "Your password was changed successfully" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:60 msgid "Cannot link theme... no theme set\n" msgstr "Impossible de lier le thème... Aucun thème associé\n" -#: mediagoblin/gmg_commands/theme.py:71 +#: mediagoblin/gmg_commands/assetlink.py:73 msgid "No asset directory for this theme\n" msgstr "Aucun répertoire \"asset\" pour ce thème\n" -#: mediagoblin/gmg_commands/theme.py:74 +#: mediagoblin/gmg_commands/assetlink.py:76 msgid "However, old link directory symlink found; removed.\n" msgstr "" +#: mediagoblin/gmg_commands/assetlink.py:112 +#, python-format +msgid "Could not link \"%s\": %s exists and is not a symlink\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:119 +#, python-format +msgid "Skipping \"%s\"; already set up.\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:124 +#, python-format +msgid "Old link found for \"%s\"; removing.\n" +msgstr "" + #: mediagoblin/meddleware/csrf.py:134 msgid "" "CSRF cookie not present. This is most likely the result of a cookie blocker " @@ -282,12 +306,16 @@ msgid "" "domain." msgstr "" -#: mediagoblin/media_types/__init__.py:61 -#: mediagoblin/media_types/__init__.py:102 +#: mediagoblin/media_types/__init__.py:111 +#: mediagoblin/media_types/__init__.py:155 msgid "Sorry, I don't support that file type :(" msgstr "Désolé, mais je ne prends pas en charge cette extension de fichier :(" -#: mediagoblin/media_types/video/processing.py:36 +#: mediagoblin/media_types/pdf/processing.py:136 +msgid "unoconv failing to run, check log file" +msgstr "" + +#: mediagoblin/media_types/video/processing.py:37 msgid "Video transcoding failed" msgstr "L'encodage de la vidéo à échoué" @@ -354,7 +382,7 @@ msgstr "L'URI de redirection pour l'application, ce champ est <strong>requis</st msgid "This field is required for public clients" msgstr "Ce champ est requis pour les clients publics" -#: mediagoblin/plugins/oauth/views.py:59 +#: mediagoblin/plugins/oauth/views.py:56 msgid "The client {0} has been registered!" msgstr "Le client {0} as été enregistré !" @@ -373,7 +401,7 @@ msgstr "" msgid "Add" msgstr "Ajouter" -#: mediagoblin/processing/__init__.py:172 +#: mediagoblin/processing/__init__.py:193 msgid "Invalid file given for media type." msgstr "Le fichier envoyé ne correspond pas au type de média." @@ -381,45 +409,45 @@ msgstr "Le fichier envoyé ne correspond pas au type de média." msgid "File" msgstr "Fichier" -#: mediagoblin/submit/views.py:51 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "Il vous faut fournir un fichier." -#: mediagoblin/submit/views.py:97 +#: mediagoblin/submit/views.py:93 msgid "Woohoo! Submitted!" msgstr "Youhou, c'est envoyé !" -#: mediagoblin/submit/views.py:146 +#: mediagoblin/submit/views.py:144 #, python-format msgid "Collection \"%s\" added!" msgstr "Collection \"%s\" ajoutée !" -#: mediagoblin/templates/mediagoblin/base.html:64 +#: mediagoblin/templates/mediagoblin/base.html:67 msgid "Verify your email!" msgstr "Vérifiez votre adresse e-mail !" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:68 msgid "log out" msgstr "Déconnexion" -#: mediagoblin/templates/mediagoblin/base.html:70 +#: mediagoblin/templates/mediagoblin/base.html:73 #: mediagoblin/templates/mediagoblin/auth/login.html:28 #: mediagoblin/templates/mediagoblin/auth/login.html:36 #: mediagoblin/templates/mediagoblin/auth/login.html:54 msgid "Log in" msgstr "S'identifier" -#: mediagoblin/templates/mediagoblin/base.html:79 +#: mediagoblin/templates/mediagoblin/base.html:82 #, python-format msgid "<a href=\"%(user_url)s\">%(user_name)s</a>'s account" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:86 +#: mediagoblin/templates/mediagoblin/base.html:89 msgid "Change account settings" msgstr "Changer les paramètres du compte" -#: mediagoblin/templates/mediagoblin/base.html:90 -#: mediagoblin/templates/mediagoblin/base.html:105 +#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:108 #: mediagoblin/templates/mediagoblin/admin/panel.html:21 #: mediagoblin/templates/mediagoblin/admin/panel.html:26 #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:21 @@ -427,72 +455,25 @@ msgstr "Changer les paramètres du compte" msgid "Media processing panel" msgstr "Panneau pour le traitement des médias" -#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:96 msgid "Log out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:96 +#: mediagoblin/templates/mediagoblin/base.html:99 #: mediagoblin/templates/mediagoblin/user_pages/user.html:156 msgid "Add media" msgstr "Ajouter des médias" -#: mediagoblin/templates/mediagoblin/base.html:99 +#: mediagoblin/templates/mediagoblin/base.html:102 #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:41 msgid "Create new collection" msgstr "Créer une nouvelle collection" -#: mediagoblin/templates/mediagoblin/base.html:122 -#, python-format -msgid "" -"Powered by <a href=\"http://mediagoblin.org/\" title='Version " -"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." -msgstr "" - -#: mediagoblin/templates/mediagoblin/base.html:125 -#, 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 "Disponible sous la licence <a href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a href=\"%(source_link)s\">Code source</a> disponible." - #: mediagoblin/templates/mediagoblin/error.html:24 msgid "Image of goblin stressing out" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:31 -msgid "Explore" -msgstr "Explorer" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "Bonjour, et bienvenue sur ce site MediaGoblin !" - -#: mediagoblin/templates/mediagoblin/root.html:35 -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." - -#: mediagoblin/templates/mediagoblin/root.html:36 -msgid "" -"To add your own media, place comments, and more, you can log in with your " -"MediaGoblin account." -msgstr "Pour ajouter vos propres médias, commenter, et bien plus encore, vous pouvez vous connecter avec votre compte MediaGoblin" - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Don't have one yet? It's easy!" -msgstr "Vous n'en avez pas ? C'est facile !" - -#: mediagoblin/templates/mediagoblin/root.html:39 -#, 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\">Créez un compte sur ce site</a>\n ou\n <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">Déployez MediaGoblin sur votre propre serveur</a>" - -#: mediagoblin/templates/mediagoblin/root.html:47 +#: mediagoblin/templates/mediagoblin/root.html:32 msgid "Most recent media" msgstr "Tout derniers media" @@ -598,6 +579,53 @@ msgid "" "%(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/bits/base_footer.html:21 +#, python-format +msgid "" +"Powered by <a href=\"http://mediagoblin.org/\" title='Version " +"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:24 +#, 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 "Disponible sous la licence <a href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a href=\"%(source_link)s\">Code source</a> disponible." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:20 +msgid "Explore" +msgstr "Explorer" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:22 +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "Bonjour, et bienvenue sur ce site MediaGoblin !" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:24 +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." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:25 +msgid "" +"To add your own media, place comments, and more, you can log in with your " +"MediaGoblin account." +msgstr "Pour ajouter vos propres médias, commenter, et bien plus encore, vous pouvez vous connecter avec votre compte MediaGoblin" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:27 +msgid "Don't have one yet? It's easy!" +msgstr "Vous n'en avez pas ? C'est facile !" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:28 +#, 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/bits/logo.html:23 #: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 msgid "MediaGoblin logo" @@ -610,13 +638,13 @@ msgid "Editing attachments for %(media_title)s" msgstr "Éditer les pièces jointes de %(media_title)s" #: mediagoblin/templates/mediagoblin/edit/attachments.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:159 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:175 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:182 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:198 msgid "Attachments" msgstr "Pièces jointes" #: mediagoblin/templates/mediagoblin/edit/attachments.html:57 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:181 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:204 msgid "Add attachment" msgstr "Ajouter une pièce jointe" @@ -633,12 +661,22 @@ msgstr "Annuler" #: mediagoblin/templates/mediagoblin/edit/attachments.html:63 #: mediagoblin/templates/mediagoblin/edit/edit.html:42 -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:52 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:55 #: mediagoblin/templates/mediagoblin/edit/edit_collection.html:33 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:40 msgid "Save changes" msgstr "Enregistrer les modifications" +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:28 +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 +#, python-format +msgid "Changing %(username)s's password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 +msgid "Save" +msgstr "" + #: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 #, python-format msgid "Really delete user '%(user_name)s' and all related media/comments?" @@ -649,7 +687,7 @@ msgid "Yes, really delete my account" msgstr "" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:48 #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49 msgid "Delete permanently" msgstr "Supprimer définitivement" @@ -666,7 +704,11 @@ msgstr "Modification de %(media_title)s" msgid "Changing %(username)s's account settings" msgstr "Changement des préférences du compte de %(username)s" -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:59 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 +msgid "Change your password." +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 msgid "Delete my account" msgstr "" @@ -691,6 +733,7 @@ msgstr "Médias taggés avec : %(tag_name)s " #: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 #: mediagoblin/templates/mediagoblin/media_displays/audio.html:56 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:65 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:136 #: mediagoblin/templates/mediagoblin/media_displays/video.html:55 msgid "Download" @@ -715,6 +758,7 @@ msgid "" msgstr "Vous pouvez obtenir un navigateur à jour capable de lire cette vidéo sur <a href=\"http://getfirefox.com\">\n\t http://getfirefox.com</a>!" #: mediagoblin/templates/mediagoblin/media_displays/audio.html:60 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:71 #: mediagoblin/templates/mediagoblin/media_displays/video.html:61 msgid "Original file" msgstr "Fichier original" @@ -723,6 +767,7 @@ msgstr "Fichier original" msgid "WebM file (Vorbis codec)" msgstr "fichier WebM (codec Vorbis)" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:59 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:87 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:93 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:99 @@ -733,6 +778,10 @@ msgstr "fichier WebM (codec Vorbis)" msgid "Image for %(media_title)s" msgstr "Image de %(media_title)s" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 +msgid "PDF file" +msgstr "" + #: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 msgid "Toggle Rotate" msgstr "" @@ -831,7 +880,7 @@ msgstr "Voulez-vous vraiment supprimer %(title)s ?" msgid "Really remove %(media_title)s from %(collection_title)s?" msgstr "Voulez vous vraiment retirer %(media_title)s de %(collection_title)s ?" -#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:54 msgid "Remove" msgstr "Retirer" @@ -874,24 +923,28 @@ msgstr "Médias de <a href=\"%(user_url)s\">%(username)s</a>" msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>" msgstr "â– Parcourir les médias de <a href=\"%(user_url)s\">%(username)s</a>" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:94 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:95 msgid "Add a comment" msgstr "Ajouter un commentaire" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 msgid "Add this comment" msgstr "Ajouter ce commentaire" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:123 -msgid "at" -msgstr "à " - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:144 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:132 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:152 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:164 #, python-format -msgid "" -"<h3>Added on</h3>\n" -" <p>%(date)s</p>" -msgstr "<h3>Ajouté le</h3>\n<p>%(date)s</p>" +msgid "%(formatted_time)s ago" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:150 +msgid "Added" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:161 +msgid "Created" +msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:40 @@ -1047,7 +1100,7 @@ msgstr "le plus vieux" msgid "Tagged with" msgstr "Taggé avec" -#: mediagoblin/tools/exif.py:80 +#: mediagoblin/tools/exif.py:83 msgid "Could not read the image file." msgstr "Impossible de lire l'image." @@ -1077,6 +1130,30 @@ msgid "" " deleted." msgstr "Il ne semble pas y avoir de page à cette adresse. Désolé ! </p><p>Si vous êtes sûr que l'adresse est correcte, peut-être que la page que vous recherchez a été déplacée ou supprimée." +#: mediagoblin/tools/timesince.py:62 +msgid "year" +msgstr "" + +#: mediagoblin/tools/timesince.py:63 +msgid "month" +msgstr "" + +#: mediagoblin/tools/timesince.py:64 +msgid "week" +msgstr "" + +#: mediagoblin/tools/timesince.py:65 +msgid "day" +msgstr "" + +#: mediagoblin/tools/timesince.py:66 +msgid "hour" +msgstr "" + +#: mediagoblin/tools/timesince.py:67 +msgid "minute" +msgstr "" + #: mediagoblin/user_pages/forms.py:23 msgid "Comment" msgstr "" @@ -1108,73 +1185,77 @@ msgstr "-- Sélectionner --" msgid "Include a note" msgstr "Inclure une note" -#: mediagoblin/user_pages/lib.py:56 +#: mediagoblin/user_pages/lib.py:58 msgid "commented on your post" msgstr "a commenté votre post" -#: mediagoblin/user_pages/views.py:166 +#: mediagoblin/user_pages/views.py:169 +msgid "Sorry, comments are disabled." +msgstr "" + +#: mediagoblin/user_pages/views.py:174 msgid "Oops, your comment was empty." msgstr "Oups, votre commentaire était vide." -#: mediagoblin/user_pages/views.py:172 +#: mediagoblin/user_pages/views.py:180 msgid "Your comment has been posted!" msgstr "Votre commentaire a été posté !" -#: mediagoblin/user_pages/views.py:197 +#: mediagoblin/user_pages/views.py:205 msgid "Please check your entries and try again." msgstr "Veuillez vérifier vos entrées et réessayer." -#: mediagoblin/user_pages/views.py:237 +#: mediagoblin/user_pages/views.py:245 msgid "You have to select or add a collection" msgstr "Vous devez sélectionner ou ajouter une collection" -#: mediagoblin/user_pages/views.py:248 +#: mediagoblin/user_pages/views.py:256 #, python-format msgid "\"%s\" already in collection \"%s\"" msgstr "\"%s\" est déjà dans la collection \"%s\"" -#: mediagoblin/user_pages/views.py:264 +#: mediagoblin/user_pages/views.py:262 #, python-format msgid "\"%s\" added to collection \"%s\"" msgstr "\"%s\" as été ajouté à la collection \"%s\"" -#: mediagoblin/user_pages/views.py:286 +#: mediagoblin/user_pages/views.py:282 msgid "You deleted the media." msgstr "Vous avez supprimé le media." -#: mediagoblin/user_pages/views.py:293 +#: mediagoblin/user_pages/views.py:289 msgid "The media was not deleted because you didn't check that you were sure." msgstr "Ce media n'a pas été supprimé car vous n'avez pas confirmer que vous étiez sur." -#: mediagoblin/user_pages/views.py:301 +#: mediagoblin/user_pages/views.py:296 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." -#: mediagoblin/user_pages/views.py:375 +#: mediagoblin/user_pages/views.py:370 msgid "You deleted the item from the collection." msgstr "Vous avez supprimé cet élément de la collection." -#: mediagoblin/user_pages/views.py:379 +#: mediagoblin/user_pages/views.py:374 msgid "The item was not removed because you didn't check that you were sure." msgstr "L'élément n'as pas été supprimé car vous n'avez pas confirmé votre certitude." -#: mediagoblin/user_pages/views.py:389 +#: mediagoblin/user_pages/views.py:382 msgid "" "You are about to delete an item from another user's collection. Proceed with" " caution." msgstr "Vous vous apprêtez à supprimer un élément de la collection d'un autre utilisateur. Procédez avec attention." -#: mediagoblin/user_pages/views.py:422 +#: mediagoblin/user_pages/views.py:415 #, python-format msgid "You deleted the collection \"%s\"" msgstr "Vous avez supprimé la collection \"%s\"" -#: mediagoblin/user_pages/views.py:429 +#: mediagoblin/user_pages/views.py:422 msgid "" "The collection was not deleted because you didn't check that you were sure." msgstr "La collection n'as pas été supprimée car vous n'avez pas confirmé votre certitude" -#: mediagoblin/user_pages/views.py:439 +#: mediagoblin/user_pages/views.py:430 msgid "" "You are about to delete another user's collection. Proceed with caution." msgstr "Vous vous apprêtez à supprimer la collection d'un autre utilisateur. Procédez avec attention." diff --git a/mediagoblin/i18n/he/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/he/LC_MESSAGES/mediagoblin.mo Binary files differindex ce2963f7..09412b0a 100644 --- a/mediagoblin/i18n/he/LC_MESSAGES/mediagoblin.mo +++ b/mediagoblin/i18n/he/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/he/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/he/LC_MESSAGES/mediagoblin.po index 12d932c8..4a5c2b52 100644 --- a/mediagoblin/i18n/he/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/he/LC_MESSAGES/mediagoblin.po @@ -3,16 +3,17 @@ # This file is distributed under the same license as the PROJECT project. # # Translators: -# <genghiskhan@gmx.ca>, 2012. -# Isratine Citizen <genghiskhan@gmx.ca>, 2012. +# GenghisKhan <genghiskhan@gmx.ca>, 2013 +# GenghisKhan <genghiskhan@gmx.ca>, 2012 +# GenghisKhan <genghiskhan@gmx.ca>, 2012 msgid "" msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" -"POT-Creation-Date: 2013-03-04 18:04-0600\n" -"PO-Revision-Date: 2013-03-05 00:04+0000\n" -"Last-Translator: cwebber <cwebber@dustycloud.org>\n" -"Language-Team: LANGUAGE <LL@li.org>\n" +"POT-Creation-Date: 2013-05-27 13:54-0500\n" +"PO-Revision-Date: 2013-06-01 07:11+0000\n" +"Last-Translator: GenghisKhan <genghiskhan@gmx.ca>\n" +"Language-Team: Hebrew (http://www.transifex.com/projects/p/mediagoblin/language/he/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -20,34 +21,39 @@ msgstr "" "Language: he\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: mediagoblin/auth/forms.py:28 -msgid "Invalid User name or email address." -msgstr "" - -#: mediagoblin/auth/forms.py:29 -msgid "This field does not take email addresses." -msgstr "" - -#: mediagoblin/auth/forms.py:30 -msgid "This field requires an email address." -msgstr "" - -#: mediagoblin/auth/forms.py:52 mediagoblin/auth/forms.py:67 +#: mediagoblin/auth/forms.py:26 msgid "Username" msgstr "×©× ×ž×©×ª×ž×©" -#: mediagoblin/auth/forms.py:56 mediagoblin/auth/forms.py:71 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 +#: mediagoblin/tests/test_util.py:110 msgid "Password" msgstr "סיסמה" -#: mediagoblin/auth/forms.py:60 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "כתובת דו×״ל" -#: mediagoblin/auth/forms.py:78 +#: mediagoblin/auth/forms.py:41 +msgid "Username or Email" +msgstr "×©× ×ž×©×ª×ž×© ×ו דו×״ל" + +#: mediagoblin/auth/forms.py:52 msgid "Username or email" msgstr "×©× ×ž×©×ª×ž×© ×ו דו×״ל" +#: mediagoblin/auth/tools.py:31 +msgid "Invalid User name or email address." +msgstr "×©× ×ž×©×ª×ž×© ×ו דו×״ל שגוי." + +#: mediagoblin/auth/tools.py:32 +msgid "This field does not take email addresses." +msgstr "שדה ×–×” ×œ× ×œ×•×§×— כתובות דו×״ל." + +#: mediagoblin/auth/tools.py:33 +msgid "This field requires an email address." +msgstr "שדה ×–×” מצריך כתובת דו×״ל." + #: mediagoblin/auth/views.py:54 msgid "Sorry, registration is disabled on this instance." msgstr "צר לי, ×¨×™×©×•× ×”×™× ×• ×ž× ×•×˜×¨×œ על שרת ×–×”." @@ -60,54 +66,54 @@ msgstr "צר לי, משתמש ×¢× ×©× ×–×” כבר ×§×™×™×." msgid "Sorry, a user with that email address already exists." msgstr "צר לי, משתמש ×¢× ×“×•×״ל ×–×” כבר ×§×™×™×." -#: mediagoblin/auth/views.py:174 +#: 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:180 +#: mediagoblin/auth/views.py:188 msgid "The verification key or user id is incorrect" msgstr "מפתח ×”×ימות ×ו זהות משתמש ×”×™× × ×©×’×•×™×™×" -#: mediagoblin/auth/views.py:198 +#: 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:206 +#: mediagoblin/auth/views.py:214 msgid "You've already verified your email address!" msgstr "כבר ×ימתת ×ת כתובת הדו×״ל שלך!" -#: mediagoblin/auth/views.py:219 +#: mediagoblin/auth/views.py:227 msgid "Resent your verification email." msgstr "שלח שוב ×ת דו×״ל ×”×ימות שלך." -#: mediagoblin/auth/views.py:250 +#: mediagoblin/auth/views.py:258 msgid "" "If that email address (case sensitive!) is registered an email has been sent" " with instructions on how to change your password." -msgstr "" +msgstr "במידה וכתובת הדו×״ל הזו (תלוי רישיות!) רשומה דו×״ל × ×©×œ×— ×¢× ×”×•×¨×ות ×‘× ×•×’×¢ לכיצד ×œ×©× ×•×ª ×ת סיסמתך." -#: mediagoblin/auth/views.py:261 +#: mediagoblin/auth/views.py:269 msgid "Couldn't find someone with that username." -msgstr "" +msgstr "×œ× ×”×™×” × ×™×ª×Ÿ ×œ×ž×¦×•× ×ž×™×©×”×• ×¢× ×©× ×ž×©×ª×ž×© ×–×”." -#: mediagoblin/auth/views.py:264 +#: mediagoblin/auth/views.py:272 msgid "" "An email has been sent with instructions on how to change your password." msgstr "דו×״ל × ×©×œ×— בצירוף הור×ות ×‘× ×•×’×¢ לכיצד × ×™×ª×Ÿ ×œ×©× ×•×ª ×ת סיסמתך." -#: mediagoblin/auth/views.py:271 +#: mediagoblin/auth/views.py:279 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." msgstr "×œ× ×”×™×” × ×™×ª×Ÿ לשלוח דו×״ל לשחזור סיסמה מ×חר ×•×©× ×”×ž×©×ª×ž×© שלך ××™× ×• פעיל ×ו שכתובת הדו×״ל של ×—×©×‘×•× ×š ×œ× ×ומתה." -#: mediagoblin/auth/views.py:328 +#: mediagoblin/auth/views.py:336 msgid "You can now log in using your new password." msgstr "כעת ביכולתך להתחבר ב×מצעות סיסמתך החדשה." -#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:93 +#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:82 #: mediagoblin/submit/forms.py:28 mediagoblin/submit/forms.py:47 #: mediagoblin/user_pages/forms.py:45 msgid "Title" @@ -118,7 +124,7 @@ msgid "Description of this work" msgstr "תי×ור של מל××›×” זו" #: mediagoblin/edit/forms.py:29 mediagoblin/edit/forms.py:52 -#: mediagoblin/edit/forms.py:97 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:86 mediagoblin/submit/forms.py:32 #: mediagoblin/submit/forms.py:51 mediagoblin/user_pages/forms.py:49 msgid "" "You can use\n" @@ -134,11 +140,11 @@ msgstr "תגיות" msgid "Separate tags by commas." msgstr "הפרד תגיות בעזרת פסיקי×." -#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:101 +#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:90 msgid "Slug" msgstr "חשופית" -#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:102 +#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:91 msgid "The slug can't be empty" msgstr "החשופית ×œ× ×™×›×•×œ×” להיות ריקה" @@ -166,45 +172,45 @@ msgid "This address contains errors" msgstr "כתובת זו מכילה שגי×ות" #: mediagoblin/edit/forms.py:63 -msgid "Old password" -msgstr "סיסמה ×™×©× ×”" - -#: mediagoblin/edit/forms.py:64 -msgid "Enter your old password to prove you own this account." -msgstr "הזן ×ת סיסמתך ×”×™×©× ×” כדי להוכיח ש×תה ×”×‘×¢×œ×™× ×©×œ חשבון ×–×”." - -#: mediagoblin/edit/forms.py:67 -msgid "New password" -msgstr "סיסמה חדשה" - -#: mediagoblin/edit/forms.py:74 msgid "License preference" -msgstr "" +msgstr "עדיפות רשיון" -#: mediagoblin/edit/forms.py:80 +#: mediagoblin/edit/forms.py:69 msgid "This will be your default license on upload forms." -msgstr "" +msgstr "×–×” ×™×”×™×” הרשיוןן המשתמט (ברירת מחדל) שלך בטופסי העל××”." -#: mediagoblin/edit/forms.py:82 +#: mediagoblin/edit/forms.py:71 msgid "Email me when others comment on my media" msgstr "שלח לי דו×״ל ×›×שר ××—×¨×™× ×ž×’×™×‘×™× ×¢×œ המדיה שלי" -#: mediagoblin/edit/forms.py:94 +#: mediagoblin/edit/forms.py:83 msgid "The title can't be empty" msgstr "הכותרת ×œ× ×™×›×•×œ×” להיות ריקה" -#: mediagoblin/edit/forms.py:96 mediagoblin/submit/forms.py:50 +#: mediagoblin/edit/forms.py:85 mediagoblin/submit/forms.py:50 #: mediagoblin/user_pages/forms.py:48 msgid "Description of this collection" msgstr "תי×ור ×וסף ×–×”" -#: mediagoblin/edit/forms.py:103 +#: mediagoblin/edit/forms.py:92 msgid "" "The title part of this collection's address. You usually don't need to " "change this." msgstr "×זור הכותרת של כתובת ×וסף ×–×”. לרוב ×ין הכרח ×œ×©× ×•×ª ×ת חלק ×–×”." -#: mediagoblin/edit/views.py:66 +#: mediagoblin/edit/forms.py:99 +msgid "Old password" +msgstr "סיסמה ×™×©× ×”" + +#: mediagoblin/edit/forms.py:101 +msgid "Enter your old password to prove you own this account." +msgstr "הזן ×ת סיסמתך ×”×™×©× ×” כדי להוכיח ש×תה ×”×‘×¢×œ×™× ×©×œ חשבון ×–×”." + +#: mediagoblin/edit/forms.py:104 +msgid "New password" +msgstr "סיסמה חדשה" + +#: mediagoblin/edit/views.py:67 msgid "An entry with that slug already exists for this user." msgstr "רשומה ×¢× ×—×©×•×¤×™×ª זו כבר קיימת עבור משתמש ×–×”." @@ -219,7 +225,7 @@ msgstr "הוספת ×ת התצריף %s!" #: mediagoblin/edit/views.py:182 msgid "You can only edit your own profile." -msgstr "" +msgstr "ב×פשרותך לערוך רק ×ת הדיוקן שלך." #: mediagoblin/edit/views.py:188 msgid "You are editing a user's profile. Proceed with caution." @@ -229,57 +235,80 @@ msgstr "×תה עורך דיוקן של משתמש. המשך בזהירות." msgid "Profile changes saved" msgstr "×©×™× ×•×™×™ דיוקן × ×©×ž×¨×•" -#: mediagoblin/edit/views.py:241 -msgid "Wrong password" -msgstr "סיסמה שגויה" - -#: mediagoblin/edit/views.py:252 +#: mediagoblin/edit/views.py:240 msgid "Account settings saved" msgstr "הגדרות חשבון × ×©×ž×¨×•" -#: mediagoblin/edit/views.py:286 +#: mediagoblin/edit/views.py:274 msgid "You need to confirm the deletion of your account." -msgstr "" +msgstr "עליך ל×מת ×ת המחיקה של ×—×©×‘×•× ×š." -#: mediagoblin/edit/views.py:322 mediagoblin/submit/views.py:142 -#: mediagoblin/user_pages/views.py:214 +#: mediagoblin/edit/views.py:310 mediagoblin/submit/views.py:138 +#: mediagoblin/user_pages/views.py:222 #, python-format msgid "You already have a collection called \"%s\"!" msgstr "כבר יש לך ×וסף שקרוי ×‘×©× \"%s\"!" -#: mediagoblin/edit/views.py:326 +#: mediagoblin/edit/views.py:314 msgid "A collection with that slug already exists for this user." msgstr "×וסף ×¢× ×—×©×•×¤×™×ª זו כבר ×§×™×™× ×¢×‘×•×¨ משתמש ×–×”." -#: mediagoblin/edit/views.py:343 +#: mediagoblin/edit/views.py:329 msgid "You are editing another user's collection. Proceed with caution." msgstr "×תה עורך ×וסף של משתמש ×חר. המשך בזהירות." -#: mediagoblin/gmg_commands/theme.py:58 +#: mediagoblin/edit/views.py:348 +msgid "Wrong password" +msgstr "סיסמה שגויה" + +#: mediagoblin/edit/views.py:363 +msgid "Your password was changed successfully" +msgstr "סיסמתך ×©×•× ×ª×” בהצלחה" + +#: mediagoblin/gmg_commands/assetlink.py:60 msgid "Cannot link theme... no theme set\n" msgstr "×œ× × ×™×ª×Ÿ לקשר ×ל מוטיב... ×œ× ×”×•×’×“×¨ מוטיב\n" -#: mediagoblin/gmg_commands/theme.py:71 +#: mediagoblin/gmg_commands/assetlink.py:73 msgid "No asset directory for this theme\n" msgstr "×ין מדור × ×›×¡ עבור מוטיב ×–×”\n" -#: mediagoblin/gmg_commands/theme.py:74 +#: mediagoblin/gmg_commands/assetlink.py:76 msgid "However, old link directory symlink found; removed.\n" msgstr "בכל ×ופן, קישור מדור symlink × ×ž×¦×; הוסר.\n" +#: mediagoblin/gmg_commands/assetlink.py:112 +#, python-format +msgid "Could not link \"%s\": %s exists and is not a symlink\n" +msgstr "×œ× ×”×™×ª×” ×פשרות לקשר ×ת \"%s\": %s ×§×™×™× ×•××™× ×• קישור סמלי (symlink)\n" + +#: mediagoblin/gmg_commands/assetlink.py:119 +#, python-format +msgid "Skipping \"%s\"; already set up.\n" +msgstr "מדלג על \"%s\"; כבר מוגדר.\n" + +#: mediagoblin/gmg_commands/assetlink.py:124 +#, python-format +msgid "Old link found for \"%s\"; removing.\n" +msgstr "קישור ישן × ×ž×¦× ×¢×‘×•×¨ \"%s\"; מסיר כעת.\n" + #: mediagoblin/meddleware/csrf.py:134 msgid "" "CSRF cookie not present. This is most likely the result of a cookie blocker " "or somesuch.<br/>Make sure to permit the settings of cookies for this " "domain." -msgstr "" +msgstr "עוגיית CSRF ×œ× × ×•×›×—×ª. ×–×” קרוב לווד××™ × ×•×‘×¢ ×ž×©×•× ×—×•×¡× ×¢×•×’×™×™×” ×ו משהו ×‘×¡×’× ×•×Ÿ.<br/>הבטח קביעה של עוגיות עבור ×ª×—×•× ×–×”." -#: mediagoblin/media_types/__init__.py:61 -#: mediagoblin/media_types/__init__.py:102 +#: mediagoblin/media_types/__init__.py:111 +#: mediagoblin/media_types/__init__.py:155 msgid "Sorry, I don't support that file type :(" msgstr "צר לי, ××™× × ×™ תומך בטיפוס קובץ ×–×” :(" -#: mediagoblin/media_types/video/processing.py:36 +#: mediagoblin/media_types/pdf/processing.py:136 +msgid "unoconv failing to run, check log file" +msgstr "unoconv × ×›×©×œ לפעול, בדוק קובץ יומן" + +#: mediagoblin/media_types/video/processing.py:37 msgid "Video transcoding failed" msgstr "המרת ויד×ו × ×›×©×œ×”" @@ -316,7 +345,7 @@ msgstr "תי×ור" msgid "" "This will be visible to users allowing your\n" " application to authenticate as them." -msgstr "" +msgstr "×–×” יר××” ×œ×ž×©×ª×ž×©×™× ×©×ž×ª×™×¨×™×\n ×œ×™×™×©×•×ž×™× ×©×œ×š ל×מת ×ות×." #: mediagoblin/plugins/oauth/forms.py:40 msgid "Type" @@ -346,17 +375,17 @@ msgstr "" msgid "This field is required for public clients" msgstr "שדה ×–×” ×”×™× ×• דרוש עבור לקוחות פומביי×" -#: mediagoblin/plugins/oauth/views.py:59 +#: mediagoblin/plugins/oauth/views.py:56 msgid "The client {0} has been registered!" msgstr "הלקוח {0} × ×¨×©×!" #: mediagoblin/plugins/oauth/templates/oauth/client/connections.html:22 msgid "OAuth client connections" -msgstr "" +msgstr "חיבורי לקוח OAuth" #: mediagoblin/plugins/oauth/templates/oauth/client/list.html:22 msgid "Your OAuth clients" -msgstr "" +msgstr "לקוחות OAuth שלך" #: mediagoblin/plugins/oauth/templates/oauth/client/register.html:29 #: mediagoblin/templates/mediagoblin/submit/collection.html:30 @@ -365,7 +394,7 @@ msgstr "" msgid "Add" msgstr "הוסף" -#: mediagoblin/processing/__init__.py:172 +#: mediagoblin/processing/__init__.py:193 msgid "Invalid file given for media type." msgstr "× ×™×ª×Ÿ קובץ שגוי עבור טיפוס מדיה." @@ -373,45 +402,45 @@ msgstr "× ×™×ª×Ÿ קובץ שגוי עבור טיפוס מדיה." msgid "File" msgstr "קובץ" -#: mediagoblin/submit/views.py:51 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "עליך לספק קובץ." -#: mediagoblin/submit/views.py:97 +#: mediagoblin/submit/views.py:93 msgid "Woohoo! Submitted!" msgstr "הידד! × ×©×œ×—!" -#: mediagoblin/submit/views.py:146 +#: mediagoblin/submit/views.py:144 #, python-format msgid "Collection \"%s\" added!" msgstr "×וסף \"%s\" התווסף!" -#: mediagoblin/templates/mediagoblin/base.html:64 +#: mediagoblin/templates/mediagoblin/base.html:67 msgid "Verify your email!" msgstr "×מת ×ת הדו×״ל שלך!" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:68 msgid "log out" msgstr "×”×ª× ×ª×§×•×ª" -#: mediagoblin/templates/mediagoblin/base.html:70 +#: mediagoblin/templates/mediagoblin/base.html:73 #: mediagoblin/templates/mediagoblin/auth/login.html:28 #: mediagoblin/templates/mediagoblin/auth/login.html:36 #: mediagoblin/templates/mediagoblin/auth/login.html:54 msgid "Log in" msgstr "התחברות" -#: mediagoblin/templates/mediagoblin/base.html:79 +#: mediagoblin/templates/mediagoblin/base.html:82 #, python-format msgid "<a href=\"%(user_url)s\">%(user_name)s</a>'s account" msgstr "החשבון של <a href=\"%(user_url)s\">%(user_name)s</a>" -#: mediagoblin/templates/mediagoblin/base.html:86 +#: mediagoblin/templates/mediagoblin/base.html:89 msgid "Change account settings" msgstr "×©× ×” הגדרות חשבון" -#: mediagoblin/templates/mediagoblin/base.html:90 -#: mediagoblin/templates/mediagoblin/base.html:105 +#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:108 #: mediagoblin/templates/mediagoblin/admin/panel.html:21 #: mediagoblin/templates/mediagoblin/admin/panel.html:26 #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:21 @@ -419,72 +448,25 @@ msgstr "×©× ×” הגדרות חשבון" msgid "Media processing panel" msgstr "לוח עיבוד מדיה" -#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:96 msgid "Log out" -msgstr "" +msgstr "×”×ª× ×ª×§×•×ª" -#: mediagoblin/templates/mediagoblin/base.html:96 +#: mediagoblin/templates/mediagoblin/base.html:99 #: mediagoblin/templates/mediagoblin/user_pages/user.html:156 msgid "Add media" msgstr "הוספת מדיה" -#: mediagoblin/templates/mediagoblin/base.html:99 +#: mediagoblin/templates/mediagoblin/base.html:102 #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:41 msgid "Create new collection" msgstr "צור ×וסף חדש" -#: mediagoblin/templates/mediagoblin/base.html:122 -#, python-format -msgid "" -"Powered by <a href=\"http://mediagoblin.org/\" title='Version " -"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." -msgstr "" - -#: mediagoblin/templates/mediagoblin/base.html:125 -#, 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/error.html:24 msgid "Image of goblin stressing out" msgstr "×ª×ž×•× ×” של גובלין מת×מץ יתר על המידה" -#: mediagoblin/templates/mediagoblin/root.html:31 -msgid "Explore" -msgstr "לחקור" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "×©×œ×•× ×œ×š, ברוך בו×ך ×ל ×תר MediaGoblin ×–×”!" - -#: mediagoblin/templates/mediagoblin/root.html:35 -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>, חתיכת ×ª×•×›× ×ª ×ירוח מדיה יוצ×ת מן הכלל." - -#: mediagoblin/templates/mediagoblin/root.html:36 -msgid "" -"To add your own media, place comments, and more, you can log in with your " -"MediaGoblin account." -msgstr "בכדי להוסיף ×ת המדיה שלך, ×œ×”×©×™× ×ª×’×•×‘×•×ª, ועוד, ביכולתך להתחבר ×¢× ×—×©×‘×•×Ÿ MediaGoblin." - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Don't have one yet? It's easy!" -msgstr "×ין ברשותך חשבון עדיין? ×–×” קל!" - -#: mediagoblin/templates/mediagoblin/root.html:39 -#, 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\">יצירת חשבון ×צל ×תר ×–×”</a>\n ×ו\n <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">להתקין ×ת MediaGoblin על שרתך</a>" - -#: mediagoblin/templates/mediagoblin/root.html:47 +#: mediagoblin/templates/mediagoblin/root.html:32 msgid "Most recent media" msgstr "המדיה ×”××—×¨×•× ×” ביותר" @@ -573,11 +555,11 @@ msgstr "שכחת ×ת סיסמתך?" #: mediagoblin/templates/mediagoblin/auth/register.html:28 #: mediagoblin/templates/mediagoblin/auth/register.html:36 msgid "Create an account!" -msgstr "יצירת חשבון!" +msgstr "צור חשבון!" #: mediagoblin/templates/mediagoblin/auth/register.html:40 msgid "Create" -msgstr "יצירה" +msgstr "צור" #: mediagoblin/templates/mediagoblin/auth/verification_email.txt:19 #, python-format @@ -590,6 +572,53 @@ msgid "" "%(verification_url)s" msgstr "×©×œ×•× %(username)s,\n\nבכדי להפעיל ×ת ×—×©×‘×•× ×š ×צל GNU MediaGoblin, עליך לפתוח ×ת הכתובת הב××”\nבתוך דפדפן הרשת שלך:\n\n%(verification_url)s" +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:21 +#, python-format +msgid "" +"Powered by <a href=\"http://mediagoblin.org/\" title='Version " +"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." +msgstr "×ž×ž×•× ×¢ על ידי <a href=\"http://mediagoblin.org/\" title='גירסה %(version)s'>MediaGoblin</a>, פרויקט <a href=\"http://gnu.org/\">GNU</a>." + +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:24 +#, 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/bits/frontpage_welcome.html:20 +msgid "Explore" +msgstr "לחקור" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:22 +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "×©×œ×•× ×œ×š, ברוך בו×ך ×ל ×תר MediaGoblin ×–×”!" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:24 +msgid "" +"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, an " +"extraordinarily great piece of media hosting software." +msgstr "×תר ×–×” מריץ <a href=\"http://mediagoblin.org\">MediaGoblin</a>, חתיכת ×ª×•×›× ×ª ×ירוח מדיה יוצ×ת מן הכלל." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:25 +msgid "" +"To add your own media, place comments, and more, you can log in with your " +"MediaGoblin account." +msgstr "בכדי להוסיף ×ת המדיה שלך, ×œ×”×©×™× ×ª×’×•×‘×•×ª, ועוד, ביכולתך להתחבר ×¢× ×—×©×‘×•×Ÿ MediaGoblin." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:27 +msgid "Don't have one yet? It's easy!" +msgstr "×ין ברשותך חשבון עדיין? ×–×” קל!" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:28 +#, python-format +msgid "" +"<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\">צור חשבון ב×תר ×–×”</a>\n ×ו\n <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">התקן ×ת MediaGoblin על שרתך</a>" + #: mediagoblin/templates/mediagoblin/bits/logo.html:23 #: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 msgid "MediaGoblin logo" @@ -602,13 +631,13 @@ msgid "Editing attachments for %(media_title)s" msgstr "עריכת ×ª×¦×¨×™×¤×™× ×¢×‘×•×¨ %(media_title)s" #: mediagoblin/templates/mediagoblin/edit/attachments.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:159 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:175 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:182 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:198 msgid "Attachments" msgstr "תצריפי×" #: mediagoblin/templates/mediagoblin/edit/attachments.html:57 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:181 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:204 msgid "Add attachment" msgstr "הוספת תצריף" @@ -625,23 +654,33 @@ msgstr "ביטול" #: mediagoblin/templates/mediagoblin/edit/attachments.html:63 #: mediagoblin/templates/mediagoblin/edit/edit.html:42 -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:52 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:55 #: mediagoblin/templates/mediagoblin/edit/edit_collection.html:33 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:40 msgid "Save changes" msgstr "שמור ×©×™× ×•×™×™×" +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:28 +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 +#, python-format +msgid "Changing %(username)s's password" +msgstr "×ž×©× ×” כעת ×ת הסיסמה של %(username)s'" + +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 +msgid "Save" +msgstr "שמור" + #: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 #, python-format msgid "Really delete user '%(user_name)s' and all related media/comments?" -msgstr "" +msgstr "ב×מת למחוק ×ת המשתמש '%(user_name)s' ו×ת כל המדיה/התגובות הקשורות?" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:35 msgid "Yes, really delete my account" -msgstr "" +msgstr "כן, ב×מת למחוק ×ת ×—×©×‘×•× ×™" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:48 #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49 msgid "Delete permanently" msgstr "מחק לצמיתות" @@ -658,9 +697,13 @@ msgstr "ערוך %(media_title)s" msgid "Changing %(username)s's account settings" msgstr "×©×™× ×•×™ הגדרות חשבון עבור %(username)s" -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:59 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 +msgid "Change your password." +msgstr "×©× ×” ×ת סיסמתך." + +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 msgid "Delete my account" -msgstr "" +msgstr "מחק ×ת החשבון שלי" #: mediagoblin/templates/mediagoblin/edit/edit_collection.html:29 #, python-format @@ -683,6 +726,7 @@ msgstr "מדיה מתויגת ×¢×: %(tag_name)s" #: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 #: mediagoblin/templates/mediagoblin/media_displays/audio.html:56 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:65 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:136 #: mediagoblin/templates/mediagoblin/media_displays/video.html:55 msgid "Download" @@ -704,9 +748,10 @@ 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>!" +msgstr "ביכולתך להשיג דפדפן רשת ×ž×•×“×¨× ×™ \n\tשכן מסוגל ×œ× ×’×Ÿ ×ת ×ודיו ×–×” ×צל <a href=\"http://getfirefox.com\">\n\t http://getfirefox.com</a>!" #: mediagoblin/templates/mediagoblin/media_displays/audio.html:60 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:71 #: mediagoblin/templates/mediagoblin/media_displays/video.html:61 msgid "Original file" msgstr "קובץ מקורי" @@ -715,6 +760,7 @@ msgstr "קובץ מקורי" msgid "WebM file (Vorbis codec)" msgstr "קובץ WebM (קודק Vorbis)" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:59 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:87 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:93 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:99 @@ -725,9 +771,13 @@ msgstr "קובץ WebM (קודק Vorbis)" msgid "Image for %(media_title)s" msgstr "×ª×ž×•× ×” עבור %(media_title)s" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 +msgid "PDF file" +msgstr "קובץ PDF" + #: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 msgid "Toggle Rotate" -msgstr "" +msgstr "החלף סיבוב" #: mediagoblin/templates/mediagoblin/media_displays/stl.html:113 msgid "Perspective" @@ -755,7 +805,7 @@ msgstr "" #: mediagoblin/templates/mediagoblin/media_displays/stl.html:138 msgid "Download model" -msgstr "" +msgstr "הורד מודל" #: mediagoblin/templates/mediagoblin/media_displays/stl.html:146 msgid "File Format" @@ -770,14 +820,14 @@ msgid "" "Sorry, this video will not work because\n" " your web browser does not support HTML5 \n" " video." -msgstr "" +msgstr "צר לי, ויד×ו ×–×” ×œ× ×™×¢×‘×•×“ מכיוון \n שדפדפן הרשת שלך ×œ× ×ª×•×ž×š \n ויד×ו של HTML5." #: mediagoblin/templates/mediagoblin/media_displays/video.html:47 msgid "" "You can get a modern web browser that \n" " can play this video at <a href=\"http://getfirefox.com\">\n" " http://getfirefox.com</a>!" -msgstr "" +msgstr "ביכולתך להשיג דפדפן רשת ×ž×•×“×¨× ×™ \n שכן מסוגל ×œ× ×’×Ÿ ×ת ויד×ו ×–×” ×צל <a href=\"http://getfirefox.com\">\n http://getfirefox.com</a>!" #: mediagoblin/templates/mediagoblin/media_displays/video.html:69 msgid "WebM file (640p; VP8/Vorbis)" @@ -823,19 +873,19 @@ msgstr "ב×מת למחוק ×ת %(title)s?" msgid "Really remove %(media_title)s from %(collection_title)s?" msgstr "ב×מת להסיר ×ת %(media_title)s מן %(collection_title)s?" -#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:54 msgid "Remove" msgstr "הסר" #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:21 #, python-format msgid "%(username)s's collections" -msgstr "" +msgstr "××•×¡×¤×™× ×©×œ %(username)s" #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:28 #, python-format msgid "<a href=\"%(user_url)s\">%(username)s</a>'s collections" -msgstr "" +msgstr "××•×¡×¤×™× ×©×œ <a href=\"%(user_url)s\">%(username)s</a>" #: mediagoblin/templates/mediagoblin/user_pages/comment_email.txt:19 #, python-format @@ -854,7 +904,7 @@ msgstr "המדיה של %(username)s" msgid "" "<a href=\"%(user_url)s\">%(username)s</a>'s media with tag <a " "href=\"%(tag_url)s\">%(tag)s</a>" -msgstr "" +msgstr "מדיה משתמש <a href=\"%(user_url)s\">%(username)s</a> ×¢× ×ª×’×™×ª <a href=\"%(tag_url)s\">%(tag)s</a>" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:48 #, python-format @@ -866,30 +916,34 @@ msgstr "המדיה של <a href=\"%(user_url)s\">%(username)s</a>" 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:94 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:95 msgid "Add a comment" msgstr "הוסף תגובה" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 msgid "Add this comment" msgstr "הוסף ×ת תגובה זו" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:123 -msgid "at" -msgstr "×צל" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:144 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:132 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:152 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:164 #, python-format -msgid "" -"<h3>Added on</h3>\n" -" <p>%(date)s</p>" -msgstr "<h3>הוסף בת×ריך</h3>\n <p>%(date)s</p>" +msgid "%(formatted_time)s ago" +msgstr "×ž×œ×¤× ×™ %(formatted_time)s" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:150 +msgid "Added" +msgstr "התווסף" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:161 +msgid "Created" +msgstr "× ×•×¦×¨" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:40 #, python-format msgid "Add “%(media_title)s†to a collection" -msgstr "" +msgstr "הוסף ×ת “%(media_title)s†×ל ×וסף" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:54 msgid "+" @@ -968,7 +1022,7 @@ msgstr "משתמש ×–×” ×œ× ×ž×™×œ× ×“×™×•×§×Ÿ (עדיין)." #: mediagoblin/templates/mediagoblin/user_pages/user.html:124 msgid "Browse collections" -msgstr "" +msgstr "עיון ב×וספי×" #: mediagoblin/templates/mediagoblin/user_pages/user.html:137 #, python-format @@ -997,7 +1051,7 @@ msgstr "" #: mediagoblin/templates/mediagoblin/utils/collections.html:40 msgid "Add to a collection" -msgstr "" +msgstr "הוסף ×ל ×וסף" #: mediagoblin/templates/mediagoblin/utils/feed_link.html:21 #: mediagoblin/themes/airy/templates/mediagoblin/utils/feed_link.html:21 @@ -1039,7 +1093,7 @@ msgstr "ישן יותר" msgid "Tagged with" msgstr "מתויגת ×¢×" -#: mediagoblin/tools/exif.py:80 +#: mediagoblin/tools/exif.py:83 msgid "Could not read the image file." msgstr "×œ× ×”×™×” × ×™×ª×Ÿ ×œ×§×¨×•× ×ת קובץ ×”×ª×ž×•× ×”." @@ -1069,9 +1123,33 @@ msgid "" " deleted." msgstr "×œ× × ×¨××” ×©×§×™×™× ×¢×ž×•×“ בכתובת זו. צר לי!</p><p>×× ×תה בטוח שהכתובת ×”×™× ×” מדויקת, ייתכן שהעמוד ש×תה מחפש כעת הועבר ×ו × ×ž×—×§." +#: mediagoblin/tools/timesince.py:62 +msgid "year" +msgstr "×©× ×”" + +#: mediagoblin/tools/timesince.py:63 +msgid "month" +msgstr "חודש" + +#: mediagoblin/tools/timesince.py:64 +msgid "week" +msgstr "שבוע" + +#: mediagoblin/tools/timesince.py:65 +msgid "day" +msgstr "יו×" + +#: mediagoblin/tools/timesince.py:66 +msgid "hour" +msgstr "שעה" + +#: mediagoblin/tools/timesince.py:67 +msgid "minute" +msgstr "דקה" + #: mediagoblin/user_pages/forms.py:23 msgid "Comment" -msgstr "" +msgstr "תגובה" #: mediagoblin/user_pages/forms.py:25 msgid "" @@ -1090,7 +1168,7 @@ msgstr "×× ×™ בטוח ×©×‘×¨×¦×•× ×™ להסיר ×ת פריט ×–×” מן ×”×ו #: mediagoblin/user_pages/forms.py:39 msgid "Collection" -msgstr "" +msgstr "×וסף" #: mediagoblin/user_pages/forms.py:40 msgid "-- Select --" @@ -1100,73 +1178,77 @@ msgstr "-- בחר --" msgid "Include a note" msgstr "הכללת פתק" -#: mediagoblin/user_pages/lib.py:56 +#: mediagoblin/user_pages/lib.py:58 msgid "commented on your post" msgstr "הגיב/×” על פרסומך" -#: mediagoblin/user_pages/views.py:166 +#: mediagoblin/user_pages/views.py:169 +msgid "Sorry, comments are disabled." +msgstr "מצטערי×, תגובות ×ž× ×•×˜×¨×œ×•×ª." + +#: mediagoblin/user_pages/views.py:174 msgid "Oops, your comment was empty." msgstr "×ופס, תגובתך היתה ריקה." -#: mediagoblin/user_pages/views.py:172 +#: mediagoblin/user_pages/views.py:180 msgid "Your comment has been posted!" msgstr "תגובתך פורסמה!" -#: mediagoblin/user_pages/views.py:197 +#: mediagoblin/user_pages/views.py:205 msgid "Please check your entries and try again." msgstr "×× × ×‘×“×•×§ ×ת רשומותיך ×•× ×¡×” שוב." -#: mediagoblin/user_pages/views.py:237 +#: mediagoblin/user_pages/views.py:245 msgid "You have to select or add a collection" msgstr "עליך לבחור ×ו להוסיף ×וסף" -#: mediagoblin/user_pages/views.py:248 +#: mediagoblin/user_pages/views.py:256 #, python-format msgid "\"%s\" already in collection \"%s\"" msgstr "\"%s\" כבר ×§×™×™× ×‘×וסף \"%s\"" -#: mediagoblin/user_pages/views.py:264 +#: mediagoblin/user_pages/views.py:262 #, python-format msgid "\"%s\" added to collection \"%s\"" msgstr "\"%s\" התווסף ×ל ×”×וסף \"%s\"" -#: mediagoblin/user_pages/views.py:286 +#: mediagoblin/user_pages/views.py:282 msgid "You deleted the media." msgstr "מחקת ×ת מדיה זו." -#: mediagoblin/user_pages/views.py:293 +#: mediagoblin/user_pages/views.py:289 msgid "The media was not deleted because you didn't check that you were sure." msgstr "המדיה ×œ× × ×ž×—×§×” מכיוון ×©×œ× ×¡×™×ž× ×ª ש×תה בטוח." -#: mediagoblin/user_pages/views.py:301 +#: mediagoblin/user_pages/views.py:296 msgid "You are about to delete another user's media. Proceed with caution." msgstr "בחרת למחוק מדיה של משתמש ×חר. המשך בזהירות." -#: mediagoblin/user_pages/views.py:375 +#: mediagoblin/user_pages/views.py:370 msgid "You deleted the item from the collection." msgstr "מחקת ×ת הפריט מן ×וסף ×–×”." -#: mediagoblin/user_pages/views.py:379 +#: mediagoblin/user_pages/views.py:374 msgid "The item was not removed because you didn't check that you were sure." msgstr "הפריט ×œ× ×”×•×¡×¨ מכיוון ×©×œ× ×¡×™×ž× ×ª ש×תה בטוח." -#: mediagoblin/user_pages/views.py:389 +#: mediagoblin/user_pages/views.py:382 msgid "" "You are about to delete an item from another user's collection. Proceed with" " caution." msgstr "בחרת למחוק פריט מן ×וסף של משתמש ×חר. המשך בזהירות." -#: mediagoblin/user_pages/views.py:422 +#: mediagoblin/user_pages/views.py:415 #, python-format msgid "You deleted the collection \"%s\"" msgstr "מחקת ×ת ×”×וסף \"%s\"" -#: mediagoblin/user_pages/views.py:429 +#: mediagoblin/user_pages/views.py:422 msgid "" "The collection was not deleted because you didn't check that you were sure." msgstr "×”×וסף ×œ× ×”×•×¡×¨ מכיוון ×©×œ× ×¡×™×ž× ×ª ש×תה בטוח." -#: mediagoblin/user_pages/views.py:439 +#: mediagoblin/user_pages/views.py:430 msgid "" "You are about to delete another user's collection. Proceed with caution." msgstr "בחרת למחוק ×וסף של משתמש ×חר. המשך בזהירות." diff --git a/mediagoblin/i18n/ia/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/ia/LC_MESSAGES/mediagoblin.mo Binary files differindex d9addaa6..d22f6ee6 100644 --- a/mediagoblin/i18n/ia/LC_MESSAGES/mediagoblin.mo +++ b/mediagoblin/i18n/ia/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/ia/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/ia/LC_MESSAGES/mediagoblin.po index 73180e86..c9f814fc 100644 --- a/mediagoblin/i18n/ia/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/ia/LC_MESSAGES/mediagoblin.po @@ -3,16 +3,16 @@ # This file is distributed under the same license as the PROJECT project. # # Translators: -# Aleksandr Brezhnev <abrezhnev@gmail.com>, 2012. -# Emilio Sepúlveda <djfunkinmixer@gmail.com>, 2011. +# Aleksandr Brezhnev <abrezhnev@gmail.com>, 2012 +# Emilio Sepúlveda <emisepulvedam@gmail.com>, 2011 msgid "" msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" -"POT-Creation-Date: 2013-03-04 18:04-0600\n" -"PO-Revision-Date: 2013-03-05 00:04+0000\n" +"POT-Creation-Date: 2013-05-27 13:54-0500\n" +"PO-Revision-Date: 2013-05-27 18:54+0000\n" "Last-Translator: cwebber <cwebber@dustycloud.org>\n" -"Language-Team: LANGUAGE <LL@li.org>\n" +"Language-Team: Interlingua (http://www.transifex.com/projects/p/mediagoblin/language/ia/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -20,34 +20,39 @@ msgstr "" "Language: ia\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: mediagoblin/auth/forms.py:28 -msgid "Invalid User name or email address." -msgstr "" - -#: mediagoblin/auth/forms.py:29 -msgid "This field does not take email addresses." -msgstr "" - -#: mediagoblin/auth/forms.py:30 -msgid "This field requires an email address." -msgstr "" - -#: mediagoblin/auth/forms.py:52 mediagoblin/auth/forms.py:67 +#: mediagoblin/auth/forms.py:26 msgid "Username" msgstr "Nomine de usator" -#: mediagoblin/auth/forms.py:56 mediagoblin/auth/forms.py:71 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 +#: mediagoblin/tests/test_util.py:110 msgid "Password" msgstr "Contrasigno" -#: mediagoblin/auth/forms.py:60 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "Adresse de e-posta" -#: mediagoblin/auth/forms.py:78 +#: mediagoblin/auth/forms.py:41 +msgid "Username or Email" +msgstr "" + +#: mediagoblin/auth/forms.py:52 msgid "Username or email" msgstr "" +#: mediagoblin/auth/tools.py:31 +msgid "Invalid User name or email address." +msgstr "" + +#: mediagoblin/auth/tools.py:32 +msgid "This field does not take email addresses." +msgstr "" + +#: mediagoblin/auth/tools.py:33 +msgid "This field requires an email address." +msgstr "" + #: mediagoblin/auth/views.py:54 msgid "Sorry, registration is disabled on this instance." msgstr "" @@ -60,54 +65,54 @@ msgstr "" msgid "Sorry, a user with that email address already exists." msgstr "" -#: mediagoblin/auth/views.py:174 +#: 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:180 +#: mediagoblin/auth/views.py:188 msgid "The verification key or user id is incorrect" msgstr "" -#: mediagoblin/auth/views.py:198 +#: 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:206 +#: mediagoblin/auth/views.py:214 msgid "You've already verified your email address!" msgstr "" -#: mediagoblin/auth/views.py:219 +#: mediagoblin/auth/views.py:227 msgid "Resent your verification email." msgstr "" -#: mediagoblin/auth/views.py:250 +#: mediagoblin/auth/views.py:258 msgid "" "If that email address (case sensitive!) is registered an email has been sent" " with instructions on how to change your password." msgstr "" -#: mediagoblin/auth/views.py:261 +#: mediagoblin/auth/views.py:269 msgid "Couldn't find someone with that username." msgstr "" -#: mediagoblin/auth/views.py:264 +#: mediagoblin/auth/views.py:272 msgid "" "An email has been sent with instructions on how to change your password." msgstr "" -#: mediagoblin/auth/views.py:271 +#: mediagoblin/auth/views.py:279 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." msgstr "" -#: mediagoblin/auth/views.py:328 +#: mediagoblin/auth/views.py:336 msgid "You can now log in using your new password." msgstr "" -#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:93 +#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:82 #: mediagoblin/submit/forms.py:28 mediagoblin/submit/forms.py:47 #: mediagoblin/user_pages/forms.py:45 msgid "Title" @@ -118,7 +123,7 @@ msgid "Description of this work" msgstr "" #: mediagoblin/edit/forms.py:29 mediagoblin/edit/forms.py:52 -#: mediagoblin/edit/forms.py:97 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:86 mediagoblin/submit/forms.py:32 #: mediagoblin/submit/forms.py:51 mediagoblin/user_pages/forms.py:49 msgid "" "You can use\n" @@ -134,11 +139,11 @@ msgstr "Etiquettas" msgid "Separate tags by commas." msgstr "" -#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:101 +#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:90 msgid "Slug" msgstr "" -#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:102 +#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:91 msgid "The slug can't be empty" msgstr "" @@ -166,45 +171,45 @@ msgid "This address contains errors" msgstr "" #: mediagoblin/edit/forms.py:63 -msgid "Old password" -msgstr "" - -#: mediagoblin/edit/forms.py:64 -msgid "Enter your old password to prove you own this account." -msgstr "" - -#: mediagoblin/edit/forms.py:67 -msgid "New password" -msgstr "" - -#: mediagoblin/edit/forms.py:74 msgid "License preference" msgstr "" -#: mediagoblin/edit/forms.py:80 +#: mediagoblin/edit/forms.py:69 msgid "This will be your default license on upload forms." msgstr "" -#: mediagoblin/edit/forms.py:82 +#: mediagoblin/edit/forms.py:71 msgid "Email me when others comment on my media" msgstr "" -#: mediagoblin/edit/forms.py:94 +#: mediagoblin/edit/forms.py:83 msgid "The title can't be empty" msgstr "" -#: mediagoblin/edit/forms.py:96 mediagoblin/submit/forms.py:50 +#: mediagoblin/edit/forms.py:85 mediagoblin/submit/forms.py:50 #: mediagoblin/user_pages/forms.py:48 msgid "Description of this collection" msgstr "" -#: mediagoblin/edit/forms.py:103 +#: mediagoblin/edit/forms.py:92 msgid "" "The title part of this collection's address. You usually don't need to " "change this." msgstr "" -#: mediagoblin/edit/views.py:66 +#: mediagoblin/edit/forms.py:99 +msgid "Old password" +msgstr "" + +#: mediagoblin/edit/forms.py:101 +msgid "Enter your old password to prove you own this account." +msgstr "" + +#: mediagoblin/edit/forms.py:104 +msgid "New password" +msgstr "" + +#: mediagoblin/edit/views.py:67 msgid "An entry with that slug already exists for this user." msgstr "" @@ -229,44 +234,63 @@ msgstr "" msgid "Profile changes saved" msgstr "" -#: mediagoblin/edit/views.py:241 -msgid "Wrong password" -msgstr "" - -#: mediagoblin/edit/views.py:252 +#: mediagoblin/edit/views.py:240 msgid "Account settings saved" msgstr "" -#: mediagoblin/edit/views.py:286 +#: mediagoblin/edit/views.py:274 msgid "You need to confirm the deletion of your account." msgstr "" -#: mediagoblin/edit/views.py:322 mediagoblin/submit/views.py:142 -#: mediagoblin/user_pages/views.py:214 +#: mediagoblin/edit/views.py:310 mediagoblin/submit/views.py:138 +#: mediagoblin/user_pages/views.py:222 #, python-format msgid "You already have a collection called \"%s\"!" msgstr "" -#: mediagoblin/edit/views.py:326 +#: mediagoblin/edit/views.py:314 msgid "A collection with that slug already exists for this user." msgstr "" -#: mediagoblin/edit/views.py:343 +#: mediagoblin/edit/views.py:329 msgid "You are editing another user's collection. Proceed with caution." msgstr "" -#: mediagoblin/gmg_commands/theme.py:58 +#: mediagoblin/edit/views.py:348 +msgid "Wrong password" +msgstr "" + +#: mediagoblin/edit/views.py:363 +msgid "Your password was changed successfully" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:60 msgid "Cannot link theme... no theme set\n" msgstr "" -#: mediagoblin/gmg_commands/theme.py:71 +#: mediagoblin/gmg_commands/assetlink.py:73 msgid "No asset directory for this theme\n" msgstr "" -#: mediagoblin/gmg_commands/theme.py:74 +#: mediagoblin/gmg_commands/assetlink.py:76 msgid "However, old link directory symlink found; removed.\n" msgstr "" +#: mediagoblin/gmg_commands/assetlink.py:112 +#, python-format +msgid "Could not link \"%s\": %s exists and is not a symlink\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:119 +#, python-format +msgid "Skipping \"%s\"; already set up.\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:124 +#, python-format +msgid "Old link found for \"%s\"; removing.\n" +msgstr "" + #: mediagoblin/meddleware/csrf.py:134 msgid "" "CSRF cookie not present. This is most likely the result of a cookie blocker " @@ -274,12 +298,16 @@ msgid "" "domain." msgstr "" -#: mediagoblin/media_types/__init__.py:61 -#: mediagoblin/media_types/__init__.py:102 +#: mediagoblin/media_types/__init__.py:111 +#: mediagoblin/media_types/__init__.py:155 msgid "Sorry, I don't support that file type :(" msgstr "" -#: mediagoblin/media_types/video/processing.py:36 +#: mediagoblin/media_types/pdf/processing.py:136 +msgid "unoconv failing to run, check log file" +msgstr "" + +#: mediagoblin/media_types/video/processing.py:37 msgid "Video transcoding failed" msgstr "" @@ -346,7 +374,7 @@ msgstr "" msgid "This field is required for public clients" msgstr "" -#: mediagoblin/plugins/oauth/views.py:59 +#: mediagoblin/plugins/oauth/views.py:56 msgid "The client {0} has been registered!" msgstr "" @@ -365,7 +393,7 @@ msgstr "" msgid "Add" msgstr "" -#: mediagoblin/processing/__init__.py:172 +#: mediagoblin/processing/__init__.py:193 msgid "Invalid file given for media type." msgstr "" @@ -373,45 +401,45 @@ msgstr "" msgid "File" msgstr "File" -#: mediagoblin/submit/views.py:51 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "" -#: mediagoblin/submit/views.py:97 +#: mediagoblin/submit/views.py:93 msgid "Woohoo! Submitted!" msgstr "" -#: mediagoblin/submit/views.py:146 +#: mediagoblin/submit/views.py:144 #, python-format msgid "Collection \"%s\" added!" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:64 +#: mediagoblin/templates/mediagoblin/base.html:67 msgid "Verify your email!" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:68 msgid "log out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:70 +#: mediagoblin/templates/mediagoblin/base.html:73 #: mediagoblin/templates/mediagoblin/auth/login.html:28 #: mediagoblin/templates/mediagoblin/auth/login.html:36 #: mediagoblin/templates/mediagoblin/auth/login.html:54 msgid "Log in" msgstr "Initiar session" -#: mediagoblin/templates/mediagoblin/base.html:79 +#: mediagoblin/templates/mediagoblin/base.html:82 #, python-format msgid "<a href=\"%(user_url)s\">%(user_name)s</a>'s account" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:86 +#: mediagoblin/templates/mediagoblin/base.html:89 msgid "Change account settings" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:90 -#: mediagoblin/templates/mediagoblin/base.html:105 +#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:108 #: mediagoblin/templates/mediagoblin/admin/panel.html:21 #: mediagoblin/templates/mediagoblin/admin/panel.html:26 #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:21 @@ -419,72 +447,25 @@ msgstr "" msgid "Media processing panel" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:96 msgid "Log out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:96 +#: mediagoblin/templates/mediagoblin/base.html:99 #: mediagoblin/templates/mediagoblin/user_pages/user.html:156 msgid "Add media" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:99 +#: mediagoblin/templates/mediagoblin/base.html:102 #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:41 msgid "Create new collection" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:122 -#, python-format -msgid "" -"Powered by <a href=\"http://mediagoblin.org/\" title='Version " -"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." -msgstr "" - -#: mediagoblin/templates/mediagoblin/base.html:125 -#, 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/error.html:24 msgid "Image of goblin stressing out" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:31 -msgid "Explore" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:35 -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:36 -msgid "" -"To add your own media, place comments, and more, you can log in with your " -"MediaGoblin account." -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Don't have one yet? It's easy!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:39 -#, 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:47 +#: mediagoblin/templates/mediagoblin/root.html:32 msgid "Most recent media" msgstr "" @@ -590,6 +571,53 @@ msgid "" "%(verification_url)s" msgstr "" +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:21 +#, python-format +msgid "" +"Powered by <a href=\"http://mediagoblin.org/\" title='Version " +"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:24 +#, 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/bits/frontpage_welcome.html:20 +msgid "Explore" +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:22 +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:24 +msgid "" +"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, an " +"extraordinarily great piece of media hosting software." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:25 +msgid "" +"To add your own media, place comments, and more, you can log in with your " +"MediaGoblin account." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:27 +msgid "Don't have one yet? It's easy!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:28 +#, python-format +msgid "" +"<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/bits/logo.html:23 #: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 msgid "MediaGoblin logo" @@ -602,13 +630,13 @@ msgid "Editing attachments for %(media_title)s" msgstr "" #: mediagoblin/templates/mediagoblin/edit/attachments.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:159 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:175 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:182 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:198 msgid "Attachments" msgstr "" #: mediagoblin/templates/mediagoblin/edit/attachments.html:57 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:181 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:204 msgid "Add attachment" msgstr "" @@ -625,12 +653,22 @@ msgstr "Cancellar" #: mediagoblin/templates/mediagoblin/edit/attachments.html:63 #: mediagoblin/templates/mediagoblin/edit/edit.html:42 -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:52 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:55 #: mediagoblin/templates/mediagoblin/edit/edit_collection.html:33 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:40 msgid "Save changes" msgstr "" +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:28 +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 +#, python-format +msgid "Changing %(username)s's password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 +msgid "Save" +msgstr "" + #: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 #, python-format msgid "Really delete user '%(user_name)s' and all related media/comments?" @@ -641,7 +679,7 @@ msgid "Yes, really delete my account" msgstr "" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:48 #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49 msgid "Delete permanently" msgstr "" @@ -658,7 +696,11 @@ msgstr "" msgid "Changing %(username)s's account settings" msgstr "" -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:59 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 +msgid "Change your password." +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 msgid "Delete my account" msgstr "" @@ -683,6 +725,7 @@ msgstr "" #: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 #: mediagoblin/templates/mediagoblin/media_displays/audio.html:56 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:65 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:136 #: mediagoblin/templates/mediagoblin/media_displays/video.html:55 msgid "Download" @@ -707,6 +750,7 @@ msgid "" msgstr "" #: mediagoblin/templates/mediagoblin/media_displays/audio.html:60 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:71 #: mediagoblin/templates/mediagoblin/media_displays/video.html:61 msgid "Original file" msgstr "" @@ -715,6 +759,7 @@ msgstr "" msgid "WebM file (Vorbis codec)" msgstr "" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:59 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:87 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:93 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:99 @@ -725,6 +770,10 @@ msgstr "" msgid "Image for %(media_title)s" msgstr "" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 +msgid "PDF file" +msgstr "" + #: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 msgid "Toggle Rotate" msgstr "" @@ -823,7 +872,7 @@ msgstr "" msgid "Really remove %(media_title)s from %(collection_title)s?" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:54 msgid "Remove" msgstr "" @@ -866,23 +915,27 @@ msgstr "" msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:94 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:95 msgid "Add a comment" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 msgid "Add this comment" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:123 -msgid "at" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:132 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:152 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:164 +#, python-format +msgid "%(formatted_time)s ago" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:144 -#, python-format -msgid "" -"<h3>Added on</h3>\n" -" <p>%(date)s</p>" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:150 +msgid "Added" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:161 +msgid "Created" msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 @@ -1039,7 +1092,7 @@ msgstr "" msgid "Tagged with" msgstr "" -#: mediagoblin/tools/exif.py:80 +#: mediagoblin/tools/exif.py:83 msgid "Could not read the image file." msgstr "" @@ -1069,6 +1122,30 @@ msgid "" " deleted." msgstr "" +#: mediagoblin/tools/timesince.py:62 +msgid "year" +msgstr "" + +#: mediagoblin/tools/timesince.py:63 +msgid "month" +msgstr "" + +#: mediagoblin/tools/timesince.py:64 +msgid "week" +msgstr "" + +#: mediagoblin/tools/timesince.py:65 +msgid "day" +msgstr "" + +#: mediagoblin/tools/timesince.py:66 +msgid "hour" +msgstr "" + +#: mediagoblin/tools/timesince.py:67 +msgid "minute" +msgstr "" + #: mediagoblin/user_pages/forms.py:23 msgid "Comment" msgstr "" @@ -1100,73 +1177,77 @@ msgstr "" msgid "Include a note" msgstr "" -#: mediagoblin/user_pages/lib.py:56 +#: mediagoblin/user_pages/lib.py:58 msgid "commented on your post" msgstr "" -#: mediagoblin/user_pages/views.py:166 +#: mediagoblin/user_pages/views.py:169 +msgid "Sorry, comments are disabled." +msgstr "" + +#: mediagoblin/user_pages/views.py:174 msgid "Oops, your comment was empty." msgstr "" -#: mediagoblin/user_pages/views.py:172 +#: mediagoblin/user_pages/views.py:180 msgid "Your comment has been posted!" msgstr "" -#: mediagoblin/user_pages/views.py:197 +#: mediagoblin/user_pages/views.py:205 msgid "Please check your entries and try again." msgstr "" -#: mediagoblin/user_pages/views.py:237 +#: mediagoblin/user_pages/views.py:245 msgid "You have to select or add a collection" msgstr "" -#: mediagoblin/user_pages/views.py:248 +#: mediagoblin/user_pages/views.py:256 #, python-format msgid "\"%s\" already in collection \"%s\"" msgstr "" -#: mediagoblin/user_pages/views.py:264 +#: mediagoblin/user_pages/views.py:262 #, python-format msgid "\"%s\" added to collection \"%s\"" msgstr "" -#: mediagoblin/user_pages/views.py:286 +#: mediagoblin/user_pages/views.py:282 msgid "You deleted the media." msgstr "" -#: mediagoblin/user_pages/views.py:293 +#: mediagoblin/user_pages/views.py:289 msgid "The media was not deleted because you didn't check that you were sure." msgstr "" -#: mediagoblin/user_pages/views.py:301 +#: mediagoblin/user_pages/views.py:296 msgid "You are about to delete another user's media. Proceed with caution." msgstr "" -#: mediagoblin/user_pages/views.py:375 +#: mediagoblin/user_pages/views.py:370 msgid "You deleted the item from the collection." msgstr "" -#: mediagoblin/user_pages/views.py:379 +#: mediagoblin/user_pages/views.py:374 msgid "The item was not removed because you didn't check that you were sure." msgstr "" -#: mediagoblin/user_pages/views.py:389 +#: mediagoblin/user_pages/views.py:382 msgid "" "You are about to delete an item from another user's collection. Proceed with" " caution." msgstr "" -#: mediagoblin/user_pages/views.py:422 +#: mediagoblin/user_pages/views.py:415 #, python-format msgid "You deleted the collection \"%s\"" msgstr "" -#: mediagoblin/user_pages/views.py:429 +#: mediagoblin/user_pages/views.py:422 msgid "" "The collection was not deleted because you didn't check that you were sure." msgstr "" -#: mediagoblin/user_pages/views.py:439 +#: mediagoblin/user_pages/views.py:430 msgid "" "You are about to delete another user's collection. Proceed with caution." msgstr "" diff --git a/mediagoblin/i18n/is_IS/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/is_IS/LC_MESSAGES/mediagoblin.mo Binary files differindex 376aace4..596ab843 100644 --- a/mediagoblin/i18n/is_IS/LC_MESSAGES/mediagoblin.mo +++ b/mediagoblin/i18n/is_IS/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/is_IS/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/is_IS/LC_MESSAGES/mediagoblin.po index 1b298a64..77896b87 100644 --- a/mediagoblin/i18n/is_IS/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/is_IS/LC_MESSAGES/mediagoblin.po @@ -3,15 +3,16 @@ # This file is distributed under the same license as the PROJECT project. # # Translators: -# <tryggvib@fsfi.is>, 2012. +# tryggvib <tryggvib@fsfi.is>, 2012 +# tryggvib <tryggvib@fsfi.is>, 2013 msgid "" msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" -"POT-Creation-Date: 2013-03-04 18:04-0600\n" -"PO-Revision-Date: 2013-03-05 00:04+0000\n" -"Last-Translator: cwebber <cwebber@dustycloud.org>\n" -"Language-Team: LANGUAGE <LL@li.org>\n" +"POT-Creation-Date: 2013-05-27 13:54-0500\n" +"PO-Revision-Date: 2013-06-05 22:51+0000\n" +"Last-Translator: tryggvib <tryggvib@fsfi.is>\n" +"Language-Team: Icelandic (Iceland) (http://www.transifex.com/projects/p/mediagoblin/language/is_IS/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -19,34 +20,39 @@ msgstr "" "Language: is_IS\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: mediagoblin/auth/forms.py:28 -msgid "Invalid User name or email address." -msgstr "" - -#: mediagoblin/auth/forms.py:29 -msgid "This field does not take email addresses." -msgstr "" - -#: mediagoblin/auth/forms.py:30 -msgid "This field requires an email address." -msgstr "" - -#: mediagoblin/auth/forms.py:52 mediagoblin/auth/forms.py:67 +#: mediagoblin/auth/forms.py:26 msgid "Username" msgstr "Notandanafn" -#: mediagoblin/auth/forms.py:56 mediagoblin/auth/forms.py:71 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 +#: mediagoblin/tests/test_util.py:110 msgid "Password" msgstr "Lykilorð" -#: mediagoblin/auth/forms.py:60 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "Netfang" -#: mediagoblin/auth/forms.py:78 +#: mediagoblin/auth/forms.py:41 +msgid "Username or Email" +msgstr "Notandanafn eða tölvupóstur" + +#: mediagoblin/auth/forms.py:52 msgid "Username or email" msgstr "Notandanafn eða netfang" +#: mediagoblin/auth/tools.py:31 +msgid "Invalid User name or email address." +msgstr "Ógilt notandanafn eða netfang" + +#: mediagoblin/auth/tools.py:32 +msgid "This field does not take email addresses." +msgstr "Þessi reitur tekur ekki við netföngum." + +#: mediagoblin/auth/tools.py:33 +msgid "This field requires an email address." +msgstr "à þennan reit verður að slá inn netfang." + #: mediagoblin/auth/views.py:54 msgid "Sorry, registration is disabled on this instance." msgstr "Þvà miður er nýskráning ekki leyfð á þessu svæði." @@ -59,54 +65,54 @@ msgstr "Þvà miður er nú þegar til notandi með þetta nafn." msgid "Sorry, a user with that email address already exists." msgstr "Þvà miður þá er annar notandi à kerfinu með þetta netfang skráð." -#: mediagoblin/auth/views.py:174 +#: mediagoblin/auth/views.py:182 msgid "" "Your email address has been verified. You may now login, edit your profile, " "and submit images!" msgstr "Netfangið þitt hefur verið staðfest. Þú getur núna innskráð þig, breytt kenniskránni þinni og sent inn efni!" -#: mediagoblin/auth/views.py:180 +#: mediagoblin/auth/views.py:188 msgid "The verification key or user id is incorrect" msgstr "Staðfestingarlykillinn eða notendaauðkennið er rangt" -#: mediagoblin/auth/views.py:198 +#: mediagoblin/auth/views.py:206 msgid "You must be logged in so we know who to send the email to!" msgstr "Þú verður að hafa innskráð þig svo við vitum hvert á að senda tölvupóstinn!" -#: mediagoblin/auth/views.py:206 +#: mediagoblin/auth/views.py:214 msgid "You've already verified your email address!" msgstr "Þú hefur staðfest netfangið þitt!" -#: mediagoblin/auth/views.py:219 +#: mediagoblin/auth/views.py:227 msgid "Resent your verification email." msgstr "Endursendi staðfestingartölvupóst" -#: mediagoblin/auth/views.py:250 +#: mediagoblin/auth/views.py:258 msgid "" "If that email address (case sensitive!) is registered an email has been sent" " with instructions on how to change your password." -msgstr "" +msgstr "Ef þetta netfang (há- og lágstafir skipta máli) er skráð hjá okkur hefur tölvupóstur verið sendur með leiðbeiningum um hvernig þú getur breytt lykilorðinu þÃnu." -#: mediagoblin/auth/views.py:261 +#: mediagoblin/auth/views.py:269 msgid "Couldn't find someone with that username." -msgstr "" +msgstr "Gat ekki fundið neinn með þetta notandanafn." -#: mediagoblin/auth/views.py:264 +#: mediagoblin/auth/views.py:272 msgid "" "An email has been sent with instructions on how to change your password." msgstr "Tölvupóstur hefur verið sendur með leiðbeiningum um hvernig þú átt að breyta lykilorðinu þÃnu." -#: mediagoblin/auth/views.py:271 +#: mediagoblin/auth/views.py:279 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." msgstr "Gat ekki sent tölvupóst um endurstillingu lykilorðs þvà notandanafnið þitt er óvirkt eða þá að þú hefur ekki staðfest netfangið þitt." -#: mediagoblin/auth/views.py:328 +#: mediagoblin/auth/views.py:336 msgid "You can now log in using your new password." msgstr "Þú getur núna innskráð þig með nýja lykilorðinu þÃnu." -#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:93 +#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:82 #: mediagoblin/submit/forms.py:28 mediagoblin/submit/forms.py:47 #: mediagoblin/user_pages/forms.py:45 msgid "Title" @@ -117,7 +123,7 @@ msgid "Description of this work" msgstr "Lýsing á þessu efni" #: mediagoblin/edit/forms.py:29 mediagoblin/edit/forms.py:52 -#: mediagoblin/edit/forms.py:97 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:86 mediagoblin/submit/forms.py:32 #: mediagoblin/submit/forms.py:51 mediagoblin/user_pages/forms.py:49 msgid "" "You can use\n" @@ -133,11 +139,11 @@ msgstr "Efnisorð" msgid "Separate tags by commas." msgstr "Aðskildu efnisorðin með kommum." -#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:101 +#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:90 msgid "Slug" msgstr "Vefslóðarormur" -#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:102 +#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:91 msgid "The slug can't be empty" msgstr "Vefslóðarormurinn getur ekki verið tómur" @@ -165,45 +171,45 @@ msgid "This address contains errors" msgstr "Þetta netfang inniheldur villur" #: mediagoblin/edit/forms.py:63 -msgid "Old password" -msgstr "Gamla lykilorðið" - -#: mediagoblin/edit/forms.py:64 -msgid "Enter your old password to prove you own this account." -msgstr "Skráðu gamla lykilorðið þitt til að sanna að þú átt þennan aðgang." - -#: mediagoblin/edit/forms.py:67 -msgid "New password" -msgstr "Nýtt lykilorð" - -#: mediagoblin/edit/forms.py:74 msgid "License preference" -msgstr "" +msgstr "Leyfiskjörstilling" -#: mediagoblin/edit/forms.py:80 +#: mediagoblin/edit/forms.py:69 msgid "This will be your default license on upload forms." -msgstr "" +msgstr "Þetta verður sjálfgefna leyfið þegar þú vilt hlaða upp efni." -#: mediagoblin/edit/forms.py:82 +#: mediagoblin/edit/forms.py:71 msgid "Email me when others comment on my media" msgstr "Senda mér tölvupóst þegar einhver bætir athugasemd við efnið mitt" -#: mediagoblin/edit/forms.py:94 +#: mediagoblin/edit/forms.py:83 msgid "The title can't be empty" msgstr "Þessi titill getur verið innihaldslaus" -#: mediagoblin/edit/forms.py:96 mediagoblin/submit/forms.py:50 +#: mediagoblin/edit/forms.py:85 mediagoblin/submit/forms.py:50 #: mediagoblin/user_pages/forms.py:48 msgid "Description of this collection" msgstr "Lýsing á þessu albúmi" -#: mediagoblin/edit/forms.py:103 +#: mediagoblin/edit/forms.py:92 msgid "" "The title part of this collection's address. You usually don't need to " "change this." msgstr "Titilhlutinn à vefslóð þessa albúms. Þú þarft vanalega ekki að breyta þessu." -#: mediagoblin/edit/views.py:66 +#: mediagoblin/edit/forms.py:99 +msgid "Old password" +msgstr "Gamla lykilorðið" + +#: mediagoblin/edit/forms.py:101 +msgid "Enter your old password to prove you own this account." +msgstr "Skráðu gamla lykilorðið þitt til að sanna að þú átt þennan aðgang." + +#: mediagoblin/edit/forms.py:104 +msgid "New password" +msgstr "Nýtt lykilorð" + +#: mediagoblin/edit/views.py:67 msgid "An entry with that slug already exists for this user." msgstr "Efni merkt með þessum vefslóðarormi er nú þegar til fyrir þennan notanda." @@ -218,7 +224,7 @@ msgstr "Þú bættir við viðhenginu %s!" #: mediagoblin/edit/views.py:182 msgid "You can only edit your own profile." -msgstr "" +msgstr "Þú getur bara breytt þinni eigin kenniskrá." #: mediagoblin/edit/views.py:188 msgid "You are editing a user's profile. Proceed with caution." @@ -228,57 +234,80 @@ msgstr "Þú ert að breyta kenniskrá notanda. Farðu mjög varlega." msgid "Profile changes saved" msgstr "Breytingar á kenniskrá vistaðar" -#: mediagoblin/edit/views.py:241 -msgid "Wrong password" -msgstr "Vitlaust lykilorð" - -#: mediagoblin/edit/views.py:252 +#: mediagoblin/edit/views.py:240 msgid "Account settings saved" msgstr "Aðgangsstillingar vistaðar" -#: mediagoblin/edit/views.py:286 +#: mediagoblin/edit/views.py:274 msgid "You need to confirm the deletion of your account." -msgstr "" +msgstr "Þú verður að samþykkja eyðingu á notandaaðganginum þÃnum." -#: mediagoblin/edit/views.py:322 mediagoblin/submit/views.py:142 -#: mediagoblin/user_pages/views.py:214 +#: mediagoblin/edit/views.py:310 mediagoblin/submit/views.py:138 +#: mediagoblin/user_pages/views.py:222 #, python-format msgid "You already have a collection called \"%s\"!" msgstr "Þú hefur nú þegar albúm sem kallast \"%s\"!" -#: mediagoblin/edit/views.py:326 +#: mediagoblin/edit/views.py:314 msgid "A collection with that slug already exists for this user." msgstr "Albúm með þessu vefslóðarormi er nú þegar til fyrir þennan notanda." -#: mediagoblin/edit/views.py:343 +#: mediagoblin/edit/views.py:329 msgid "You are editing another user's collection. Proceed with caution." msgstr "Þú ert að breyta albúmi annars notanda. Farðu mjög varlega." -#: mediagoblin/gmg_commands/theme.py:58 +#: mediagoblin/edit/views.py:348 +msgid "Wrong password" +msgstr "Vitlaust lykilorð" + +#: mediagoblin/edit/views.py:363 +msgid "Your password was changed successfully" +msgstr "Það tókst að breyta lykilorðinu þÃnu" + +#: mediagoblin/gmg_commands/assetlink.py:60 msgid "Cannot link theme... no theme set\n" msgstr "Get ekki hlekkjað à þema... ekkert þema stillt\n" -#: mediagoblin/gmg_commands/theme.py:71 +#: mediagoblin/gmg_commands/assetlink.py:73 msgid "No asset directory for this theme\n" msgstr "Engin eignamappa fyrir þetta þema\n" -#: mediagoblin/gmg_commands/theme.py:74 +#: mediagoblin/gmg_commands/assetlink.py:76 msgid "However, old link directory symlink found; removed.\n" msgstr "Fann samt gamlan táknrænan tengil á möppu; fjarlægður.\n" +#: mediagoblin/gmg_commands/assetlink.py:112 +#, python-format +msgid "Could not link \"%s\": %s exists and is not a symlink\n" +msgstr "Gat ekki tengt \"%s\": %s er til og er ekki sýndartengill\n" + +#: mediagoblin/gmg_commands/assetlink.py:119 +#, python-format +msgid "Skipping \"%s\"; already set up.\n" +msgstr "Hoppa yfir \"%s\"; hefur nú þegar verið sett upp.\n" + +#: mediagoblin/gmg_commands/assetlink.py:124 +#, python-format +msgid "Old link found for \"%s\"; removing.\n" +msgstr "Gamall tengill fannst fyrir \"%s\"; fjarlægi.\n" + #: mediagoblin/meddleware/csrf.py:134 msgid "" "CSRF cookie not present. This is most likely the result of a cookie blocker " "or somesuch.<br/>Make sure to permit the settings of cookies for this " "domain." -msgstr "" +msgstr "CSRF smygildi ekki til staðar. Þetta er lÃklegast orsakað af smygildishindrara eða einhverju þess háttar.<br/>Athugaðu hvort þú leyfir ekki alveg örugglega smygildi fyrir þetta lén." -#: mediagoblin/media_types/__init__.py:61 -#: mediagoblin/media_types/__init__.py:102 +#: mediagoblin/media_types/__init__.py:111 +#: mediagoblin/media_types/__init__.py:155 msgid "Sorry, I don't support that file type :(" msgstr "Ég styð þvà miður ekki þessa gerð af skrám :(" -#: mediagoblin/media_types/video/processing.py:36 +#: mediagoblin/media_types/pdf/processing.py:136 +msgid "unoconv failing to run, check log file" +msgstr "tekst ekki að keyra unoconv, athugaðu annálsskrá" + +#: mediagoblin/media_types/video/processing.py:37 msgid "Video transcoding failed" msgstr "Myndbandsþverkótun mistókst" @@ -345,17 +374,17 @@ msgstr "Ãframsendingarvefslóðin fyrir forritin, þessi reitur\n er msgid "This field is required for public clients" msgstr "Þessi reitur er nauðsynlegur fyrir opinbera biðlara" -#: mediagoblin/plugins/oauth/views.py:59 +#: mediagoblin/plugins/oauth/views.py:56 msgid "The client {0} has been registered!" msgstr "Biðlarinn {0} hefur verið skráður!" #: mediagoblin/plugins/oauth/templates/oauth/client/connections.html:22 msgid "OAuth client connections" -msgstr "" +msgstr "Biðlarartengingar OAuth" #: mediagoblin/plugins/oauth/templates/oauth/client/list.html:22 msgid "Your OAuth clients" -msgstr "" +msgstr "OAuth-biðlararnir þÃnir" #: mediagoblin/plugins/oauth/templates/oauth/client/register.html:29 #: mediagoblin/templates/mediagoblin/submit/collection.html:30 @@ -364,7 +393,7 @@ msgstr "" msgid "Add" msgstr "Bæta við" -#: mediagoblin/processing/__init__.py:172 +#: mediagoblin/processing/__init__.py:193 msgid "Invalid file given for media type." msgstr "Ógild skrá gefin fyrir þessa margmiðlunartegund." @@ -372,45 +401,45 @@ msgstr "Ógild skrá gefin fyrir þessa margmiðlunartegund." msgid "File" msgstr "Skrá" -#: mediagoblin/submit/views.py:51 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "Þú verður að gefa upp skrá." -#: mediagoblin/submit/views.py:97 +#: mediagoblin/submit/views.py:93 msgid "Woohoo! Submitted!" msgstr "Jibbà jei! Það tókst að senda inn!" -#: mediagoblin/submit/views.py:146 +#: mediagoblin/submit/views.py:144 #, python-format msgid "Collection \"%s\" added!" msgstr "Albúmið \"%s\" var búið til!" -#: mediagoblin/templates/mediagoblin/base.html:64 +#: mediagoblin/templates/mediagoblin/base.html:67 msgid "Verify your email!" msgstr "Staðfestu netfangið þitt!" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:68 msgid "log out" msgstr "útskrá" -#: mediagoblin/templates/mediagoblin/base.html:70 +#: mediagoblin/templates/mediagoblin/base.html:73 #: mediagoblin/templates/mediagoblin/auth/login.html:28 #: mediagoblin/templates/mediagoblin/auth/login.html:36 #: mediagoblin/templates/mediagoblin/auth/login.html:54 msgid "Log in" -msgstr "Innskráning" +msgstr "Innskrá" -#: mediagoblin/templates/mediagoblin/base.html:79 +#: mediagoblin/templates/mediagoblin/base.html:82 #, python-format msgid "<a href=\"%(user_url)s\">%(user_name)s</a>'s account" -msgstr "Notandaaðgangur <a href=\"%(user_url)s\">%(user_name)s</a>" +msgstr "Notandaaðgangur: <a href=\"%(user_url)s\">%(user_name)s</a>" -#: mediagoblin/templates/mediagoblin/base.html:86 +#: mediagoblin/templates/mediagoblin/base.html:89 msgid "Change account settings" msgstr "Breyta stillingum notandaaðgangs" -#: mediagoblin/templates/mediagoblin/base.html:90 -#: mediagoblin/templates/mediagoblin/base.html:105 +#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:108 #: mediagoblin/templates/mediagoblin/admin/panel.html:21 #: mediagoblin/templates/mediagoblin/admin/panel.html:26 #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:21 @@ -418,72 +447,25 @@ msgstr "Breyta stillingum notandaaðgangs" msgid "Media processing panel" msgstr "Margmiðlunarvinnsluskiki" -#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:96 msgid "Log out" -msgstr "" +msgstr "Skrá út" -#: mediagoblin/templates/mediagoblin/base.html:96 +#: mediagoblin/templates/mediagoblin/base.html:99 #: mediagoblin/templates/mediagoblin/user_pages/user.html:156 msgid "Add media" msgstr "Senda inn efni" -#: mediagoblin/templates/mediagoblin/base.html:99 +#: mediagoblin/templates/mediagoblin/base.html:102 #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:41 msgid "Create new collection" msgstr "Búa til nýtt albúm" -#: mediagoblin/templates/mediagoblin/base.html:122 -#, python-format -msgid "" -"Powered by <a href=\"http://mediagoblin.org/\" title='Version " -"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." -msgstr "" - -#: mediagoblin/templates/mediagoblin/base.html:125 -#, 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 "Gefið út undir <a href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a href=\"%(source_link)s\">Frumkóti</a> aðgengilegur." - #: mediagoblin/templates/mediagoblin/error.html:24 msgid "Image of goblin stressing out" msgstr "Mynd af durt à stresskasti" -#: mediagoblin/templates/mediagoblin/root.html:31 -msgid "Explore" -msgstr "Skoða" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "Hæ! Gakktu à bæinn á þetta MediaGoblin vefsvæði!" - -#: mediagoblin/templates/mediagoblin/root.html:35 -msgid "" -"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, an " -"extraordinarily great piece of media hosting software." -msgstr "Þetta vefsvæði keyrira á <a href=\"http://mediagoblin.org\">MediaGoblin</a> sem er ótrúlega frábær hugbúnaður til að geyma margmiðlunarefni." - -#: mediagoblin/templates/mediagoblin/root.html:36 -msgid "" -"To add your own media, place comments, and more, you can log in with your " -"MediaGoblin account." -msgstr "Til að senda inn þitt efni, gera athugasemdir og fleira getur þú skráð þig inn með þÃnum MediaGoblin aðgangi." - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Don't have one yet? It's easy!" -msgstr "Ertu ekki með aðgang? Það er auðvelt að búa til!" - -#: mediagoblin/templates/mediagoblin/root.html:39 -#, 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\">Búa til aðgang á þessari sÃðu</a>\n eða\n <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">Settu upp þinn eigin margmiðlunarþjón</a>" - -#: mediagoblin/templates/mediagoblin/root.html:47 +#: mediagoblin/templates/mediagoblin/root.html:32 msgid "Most recent media" msgstr "Nýlegt efni" @@ -589,6 +571,53 @@ msgid "" "%(verification_url)s" msgstr "Hæ %(username)s,\n\ntil að virkja GNU MediaGoblin aðganginn þinn, opnaðu þá eftirfarandi vefslóði Ã\nvafranum þÃnum:\n\n%(verification_url)s" +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:21 +#, python-format +msgid "" +"Powered by <a href=\"http://mediagoblin.org/\" title='Version " +"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." +msgstr "Keyrt af <a href=\"http://mediagoblin.org/\" title='Version %(version)s'>MediaGoblin</a>, sem er <a href=\"http://gnu.org/\">GNU</a> verkefni." + +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:24 +#, 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 "Gefið út undir <a href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a href=\"%(source_link)s\">Frumkóti</a> aðgengilegur." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:20 +msgid "Explore" +msgstr "Skoða" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:22 +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "Hæ! Gakktu à bæinn á þetta MediaGoblin vefsvæði!" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:24 +msgid "" +"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, an " +"extraordinarily great piece of media hosting software." +msgstr "Þetta vefsvæði keyrir á <a href=\"http://mediagoblin.org\">MediaGoblin</a> sem er ótrúlega frábær hugbúnaður til að geyma margmiðlunarefni." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:25 +msgid "" +"To add your own media, place comments, and more, you can log in with your " +"MediaGoblin account." +msgstr "Til að senda inn þitt efni, gera athugasemdir og fleira getur þú skráð þig inn með þÃnum MediaGoblin aðgangi." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:27 +msgid "Don't have one yet? It's easy!" +msgstr "Ertu ekki með aðgang? Það er auðvelt að búa til!" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:28 +#, 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\">Búa til aðgang á þessari sÃðu</a>\neða\n<a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">Settu upp þinn eigin margmiðlunarþjón</a>" + #: mediagoblin/templates/mediagoblin/bits/logo.html:23 #: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 msgid "MediaGoblin logo" @@ -601,13 +630,13 @@ msgid "Editing attachments for %(media_title)s" msgstr "Breyti viðhengjum við: %(media_title)s" #: mediagoblin/templates/mediagoblin/edit/attachments.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:159 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:175 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:182 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:198 msgid "Attachments" msgstr "Viðhengi" #: mediagoblin/templates/mediagoblin/edit/attachments.html:57 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:181 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:204 msgid "Add attachment" msgstr "Bæta við viðhengi" @@ -624,23 +653,33 @@ msgstr "Hætta við" #: mediagoblin/templates/mediagoblin/edit/attachments.html:63 #: mediagoblin/templates/mediagoblin/edit/edit.html:42 -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:52 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:55 #: mediagoblin/templates/mediagoblin/edit/edit_collection.html:33 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:40 msgid "Save changes" msgstr "Vista breytingar" +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:28 +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 +#, python-format +msgid "Changing %(username)s's password" +msgstr "Breyti lykilorði fyrir notandann: %(username)s" + +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 +msgid "Save" +msgstr "Vista" + #: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 #, python-format msgid "Really delete user '%(user_name)s' and all related media/comments?" -msgstr "" +msgstr "Virkilega eyða notanda '%(user_name)s' og tengt efni/athugasemdir?" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:35 msgid "Yes, really delete my account" -msgstr "" +msgstr "Já, ég vil örugglega eyða aðganginum mÃnum" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:48 #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49 msgid "Delete permanently" msgstr "Eytt algjörlega" @@ -657,9 +696,13 @@ msgstr "Breyti %(media_title)s" msgid "Changing %(username)s's account settings" msgstr "Breyti notandaaðgangsstillingum fyrir: %(username)s" -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:59 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 +msgid "Change your password." +msgstr "Breyta lykilorðinu þÃnu." + +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 msgid "Delete my account" -msgstr "" +msgstr "Eyða aðganginum mÃnum" #: mediagoblin/templates/mediagoblin/edit/edit_collection.html:29 #, python-format @@ -682,6 +725,7 @@ msgstr "Efni merkt með: %(tag_name)s" #: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 #: mediagoblin/templates/mediagoblin/media_displays/audio.html:56 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:65 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:136 #: mediagoblin/templates/mediagoblin/media_displays/video.html:55 msgid "Download" @@ -706,6 +750,7 @@ msgid "" msgstr "Þú getur náð à nýlegan vafra sem \n\tgetur spilað hljóðskrár á <a href=\"http://getfirefox.com\">\n\t http://getfirefox.com</a>!" #: mediagoblin/templates/mediagoblin/media_displays/audio.html:60 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:71 #: mediagoblin/templates/mediagoblin/media_displays/video.html:61 msgid "Original file" msgstr "Upphaflega skráin" @@ -714,6 +759,7 @@ msgstr "Upphaflega skráin" msgid "WebM file (Vorbis codec)" msgstr "WebM skrá (Vorbis vÃxlþjöppun)" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:59 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:87 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:93 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:99 @@ -724,6 +770,10 @@ msgstr "WebM skrá (Vorbis vÃxlþjöppun)" msgid "Image for %(media_title)s" msgstr "Mynd fyrir %(media_title)s" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 +msgid "PDF file" +msgstr "PDF skrá" + #: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 msgid "Toggle Rotate" msgstr "Stilla snúning af eða á" @@ -769,14 +819,14 @@ msgid "" "Sorry, this video will not work because\n" " your web browser does not support HTML5 \n" " video." -msgstr "" +msgstr "Þvà miður mun þetta myndband ekki virka þvÃ\n vafrinn þinn styður ekki HTML5 \n myndbönd." #: mediagoblin/templates/mediagoblin/media_displays/video.html:47 msgid "" "You can get a modern web browser that \n" " can play this video at <a href=\"http://getfirefox.com\">\n" " http://getfirefox.com</a>!" -msgstr "" +msgstr "Þú getur náð à nýlegan vafra sem \n sem getur spilað myndbandið á <a href=\"http://getfirefox.com\">\n http://getfirefox.com</a>!" #: mediagoblin/templates/mediagoblin/media_displays/video.html:69 msgid "WebM file (640p; VP8/Vorbis)" @@ -822,19 +872,19 @@ msgstr "Virkilega eyða %(title)s?" msgid "Really remove %(media_title)s from %(collection_title)s?" msgstr "Virkilega fjarlægja %(media_title)s úr %(collection_title)s albúminu?" -#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:54 msgid "Remove" msgstr "Fjarlægja" #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:21 #, python-format msgid "%(username)s's collections" -msgstr "" +msgstr "Albúm sem %(username)s á" #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:28 #, python-format msgid "<a href=\"%(user_url)s\">%(username)s</a>'s collections" -msgstr "" +msgstr "Albúm sem <a href=\"%(user_url)s\">%(username)s</a> á" #: mediagoblin/templates/mediagoblin/user_pages/comment_email.txt:19 #, python-format @@ -853,7 +903,7 @@ msgstr "Efni sem %(username)s á" msgid "" "<a href=\"%(user_url)s\">%(username)s</a>'s media with tag <a " "href=\"%(tag_url)s\">%(tag)s</a>" -msgstr "" +msgstr "Efni sem <a href=\"%(user_url)s\">%(username)s</a> á og er merkt með <a href=\"%(tag_url)s\">%(tag)s</a>" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:48 #, python-format @@ -865,30 +915,34 @@ msgstr "Efni sem <a href=\"%(user_url)s\">%(username)s</a> á" msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>" msgstr "â– Skoða efnið sem <a href=\"%(user_url)s\">%(username)s</a> setti inn" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:94 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:95 msgid "Add a comment" msgstr "Bæta við athugasemd" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 msgid "Add this comment" msgstr "Senda inn þessa athugasemd" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:123 -msgid "at" -msgstr "hjá" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:144 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:132 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:152 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:164 #, python-format -msgid "" -"<h3>Added on</h3>\n" -" <p>%(date)s</p>" -msgstr "<h3>Bætt við:</h3>\n <p>%(date)s</p>" +msgid "%(formatted_time)s ago" +msgstr "Fyrir %(formatted_time)s" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:150 +msgid "Added" +msgstr "Bætt við" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:161 +msgid "Created" +msgstr "Skapað" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:40 #, python-format msgid "Add “%(media_title)s†to a collection" -msgstr "" +msgstr "Setja '%(media_title)s' à albúm" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:54 msgid "+" @@ -967,7 +1021,7 @@ msgstr "Þessi notandi hefur ekki fyllt inn à upplýsingar um sig (ennþá)." #: mediagoblin/templates/mediagoblin/user_pages/user.html:124 msgid "Browse collections" -msgstr "" +msgstr "Skoða albúm" #: mediagoblin/templates/mediagoblin/user_pages/user.html:137 #, python-format @@ -992,11 +1046,11 @@ msgstr "(fjarlægja)" #: mediagoblin/templates/mediagoblin/utils/collections.html:21 msgid "Collected in" -msgstr "" +msgstr "Sett à albúm" #: mediagoblin/templates/mediagoblin/utils/collections.html:40 msgid "Add to a collection" -msgstr "" +msgstr "Setja à albúm" #: mediagoblin/templates/mediagoblin/utils/feed_link.html:21 #: mediagoblin/themes/airy/templates/mediagoblin/utils/feed_link.html:21 @@ -1038,7 +1092,7 @@ msgstr "eldri" msgid "Tagged with" msgstr "Merkt með" -#: mediagoblin/tools/exif.py:80 +#: mediagoblin/tools/exif.py:83 msgid "Could not read the image file." msgstr "Gat ekki lesið myndskrána." @@ -1068,9 +1122,33 @@ msgid "" " deleted." msgstr "Þvà miður! Það virðist ekki vera nein sÃða á þessari vefslóð.</p><p>Ef þú ert viss um að vefslóðin sé rétt hefur vefsÃðan sem þú ert að leita að kannski verið flutt eða fjarlægð." +#: mediagoblin/tools/timesince.py:62 +msgid "year" +msgstr "ár" + +#: mediagoblin/tools/timesince.py:63 +msgid "month" +msgstr "mánuður" + +#: mediagoblin/tools/timesince.py:64 +msgid "week" +msgstr "vika" + +#: mediagoblin/tools/timesince.py:65 +msgid "day" +msgstr "dagur" + +#: mediagoblin/tools/timesince.py:66 +msgid "hour" +msgstr "klukkustund" + +#: mediagoblin/tools/timesince.py:67 +msgid "minute" +msgstr "mÃnúta" + #: mediagoblin/user_pages/forms.py:23 msgid "Comment" -msgstr "" +msgstr "Athugasemd" #: mediagoblin/user_pages/forms.py:25 msgid "" @@ -1089,7 +1167,7 @@ msgstr "Ég er viss um að ég vilji fjarlægja þetta efni úr albúminu" #: mediagoblin/user_pages/forms.py:39 msgid "Collection" -msgstr "" +msgstr "Albúm" #: mediagoblin/user_pages/forms.py:40 msgid "-- Select --" @@ -1099,73 +1177,77 @@ msgstr "-- Velja --" msgid "Include a note" msgstr "Bæta við minnispunktum" -#: mediagoblin/user_pages/lib.py:56 +#: mediagoblin/user_pages/lib.py:58 msgid "commented on your post" msgstr "skrifaði athugasemd við færsluna þÃna" -#: mediagoblin/user_pages/views.py:166 +#: mediagoblin/user_pages/views.py:169 +msgid "Sorry, comments are disabled." +msgstr "Þvà miður, athugasemdir eru óvirkar." + +#: mediagoblin/user_pages/views.py:174 msgid "Oops, your comment was empty." msgstr "ObbosÃ! Athugasemdin þÃn var innihaldslaus." -#: mediagoblin/user_pages/views.py:172 +#: mediagoblin/user_pages/views.py:180 msgid "Your comment has been posted!" msgstr "Athugasemdin þÃn var skráð!" -#: mediagoblin/user_pages/views.py:197 +#: mediagoblin/user_pages/views.py:205 msgid "Please check your entries and try again." msgstr "Vinsamlegast kÃktu á innsendingarnar þÃnar og reyndu aftur." -#: mediagoblin/user_pages/views.py:237 +#: mediagoblin/user_pages/views.py:245 msgid "You have to select or add a collection" msgstr "Þú verður að velja eða búa til albúm" -#: mediagoblin/user_pages/views.py:248 +#: mediagoblin/user_pages/views.py:256 #, python-format msgid "\"%s\" already in collection \"%s\"" msgstr "\"%s\" er nú þegar à albúminu \"%s\"" -#: mediagoblin/user_pages/views.py:264 +#: mediagoblin/user_pages/views.py:262 #, python-format msgid "\"%s\" added to collection \"%s\"" msgstr "\"%s\" sett à albúmið \"%s\"" -#: mediagoblin/user_pages/views.py:286 +#: mediagoblin/user_pages/views.py:282 msgid "You deleted the media." msgstr "Þú eyddir þessu efni." -#: mediagoblin/user_pages/views.py:293 +#: mediagoblin/user_pages/views.py:289 msgid "The media was not deleted because you didn't check that you were sure." msgstr "Efninu var ekki eytt þar sem þú merktir ekki við að þú værir viss." -#: mediagoblin/user_pages/views.py:301 +#: mediagoblin/user_pages/views.py:296 msgid "You are about to delete another user's media. Proceed with caution." msgstr "Þú ert à þann mund að fara að eyða efni frá öðrum notanda. Farðu mjög varlega." -#: mediagoblin/user_pages/views.py:375 +#: mediagoblin/user_pages/views.py:370 msgid "You deleted the item from the collection." msgstr "Þú tókst þetta efni úr albúminu." -#: mediagoblin/user_pages/views.py:379 +#: mediagoblin/user_pages/views.py:374 msgid "The item was not removed because you didn't check that you were sure." msgstr "Þetta efni var ekki fjarlægt af þvà að þú merktir ekki við að þú værir viss." -#: mediagoblin/user_pages/views.py:389 +#: mediagoblin/user_pages/views.py:382 msgid "" "You are about to delete an item from another user's collection. Proceed with" " caution." msgstr "Þú ert à þann mund að fara að eyða efni úr albúmi annars notanda. Farðu mjög varlega." -#: mediagoblin/user_pages/views.py:422 +#: mediagoblin/user_pages/views.py:415 #, python-format msgid "You deleted the collection \"%s\"" msgstr "Þú eyddir albúminu \"%s\"" -#: mediagoblin/user_pages/views.py:429 +#: mediagoblin/user_pages/views.py:422 msgid "" "The collection was not deleted because you didn't check that you were sure." msgstr "Þessu albúmi var ekki eytt vegna þess að þu merktir ekki við að þú værir viss." -#: mediagoblin/user_pages/views.py:439 +#: mediagoblin/user_pages/views.py:430 msgid "" "You are about to delete another user's collection. Proceed with caution." msgstr "Þú ert à þann mund að fara að eyða albúmi annars notanda. Farðu mjög varlega." diff --git a/mediagoblin/i18n/it/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/it/LC_MESSAGES/mediagoblin.mo Binary files differindex 62451511..62575b62 100644 --- a/mediagoblin/i18n/it/LC_MESSAGES/mediagoblin.mo +++ b/mediagoblin/i18n/it/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/it/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/it/LC_MESSAGES/mediagoblin.po index e13345a7..c782fc62 100644 --- a/mediagoblin/i18n/it/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/it/LC_MESSAGES/mediagoblin.po @@ -3,18 +3,19 @@ # 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. -# <sun_lion@live.com>, 2012. +# Francesco Apruzzese <cescoap@gmail.com>, 2012 +# gdb <gaedeb01@gmail.com>, 2013 +# pikappa469 <pikappa469@alice.it>, 2011 +# nunni <robi@nunnisoft.ch>, 2011 +# Damtux <sun_lion@live.com>, 2012 msgid "" msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" -"POT-Creation-Date: 2013-03-04 18:04-0600\n" -"PO-Revision-Date: 2013-03-05 00:04+0000\n" +"POT-Creation-Date: 2013-05-27 13:54-0500\n" +"PO-Revision-Date: 2013-05-27 18:54+0000\n" "Last-Translator: cwebber <cwebber@dustycloud.org>\n" -"Language-Team: LANGUAGE <LL@li.org>\n" +"Language-Team: Italian (http://www.transifex.com/projects/p/mediagoblin/language/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -22,34 +23,39 @@ msgstr "" "Language: it\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: mediagoblin/auth/forms.py:28 -msgid "Invalid User name or email address." -msgstr "" - -#: mediagoblin/auth/forms.py:29 -msgid "This field does not take email addresses." -msgstr "" - -#: mediagoblin/auth/forms.py:30 -msgid "This field requires an email address." -msgstr "" - -#: mediagoblin/auth/forms.py:52 mediagoblin/auth/forms.py:67 +#: mediagoblin/auth/forms.py:26 msgid "Username" msgstr "Nome utente" -#: mediagoblin/auth/forms.py:56 mediagoblin/auth/forms.py:71 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 +#: mediagoblin/tests/test_util.py:110 msgid "Password" msgstr "Password" -#: mediagoblin/auth/forms.py:60 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "Indirizzo email" -#: mediagoblin/auth/forms.py:78 +#: mediagoblin/auth/forms.py:41 +msgid "Username or Email" +msgstr "" + +#: mediagoblin/auth/forms.py:52 msgid "Username or email" msgstr "Nome utente o indirizzo email" +#: mediagoblin/auth/tools.py:31 +msgid "Invalid User name or email address." +msgstr "" + +#: mediagoblin/auth/tools.py:32 +msgid "This field does not take email addresses." +msgstr "" + +#: mediagoblin/auth/tools.py:33 +msgid "This field requires an email address." +msgstr "" + #: mediagoblin/auth/views.py:54 msgid "Sorry, registration is disabled on this instance." msgstr "Spiacente, la registrazione è disabilitata su questa istanza." @@ -62,54 +68,54 @@ msgstr "Spiacente, esiste già un utente con quel nome." 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:174 +#: 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. Ora puoi accedere, modificare il tuo profilo e caricare immagini!" -#: mediagoblin/auth/views.py:180 +#: 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:198 +#: mediagoblin/auth/views.py:206 msgid "You must be logged in so we know who to send the email to!" msgstr "Devi effettuare l'accesso così possiamo sapere a chi inviare l'email!" -#: mediagoblin/auth/views.py:206 +#: 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:219 +#: mediagoblin/auth/views.py:227 msgid "Resent your verification email." msgstr "Rispedisci email di verifica" -#: mediagoblin/auth/views.py:250 +#: mediagoblin/auth/views.py:258 msgid "" "If that email address (case sensitive!) is registered an email has been sent" " with instructions on how to change your password." msgstr "" -#: mediagoblin/auth/views.py:261 +#: mediagoblin/auth/views.py:269 msgid "Couldn't find someone with that username." msgstr "" -#: mediagoblin/auth/views.py:264 +#: mediagoblin/auth/views.py:272 msgid "" "An email has been sent with instructions on how to change your password." msgstr "Ti è stata inviata un'email con le istruzioni per cambiare la tua password." -#: mediagoblin/auth/views.py:271 +#: mediagoblin/auth/views.py:279 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." msgstr "Impossibile inviare l'email di recupero password perchè il tuo nome utente è inattivo o il tuo indirizzo email non è stato verificato." -#: mediagoblin/auth/views.py:328 +#: mediagoblin/auth/views.py:336 msgid "You can now log in using your new password." msgstr "Ora puoi effettuare l'accesso con la nuova password." -#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:93 +#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:82 #: mediagoblin/submit/forms.py:28 mediagoblin/submit/forms.py:47 #: mediagoblin/user_pages/forms.py:45 msgid "Title" @@ -120,7 +126,7 @@ msgid "Description of this work" msgstr "Descrizione di questo lavoro" #: mediagoblin/edit/forms.py:29 mediagoblin/edit/forms.py:52 -#: mediagoblin/edit/forms.py:97 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:86 mediagoblin/submit/forms.py:32 #: mediagoblin/submit/forms.py:51 mediagoblin/user_pages/forms.py:49 msgid "" "You can use\n" @@ -136,11 +142,11 @@ msgstr "Tags" msgid "Separate tags by commas." msgstr "Separa le tags con la virgola." -#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:101 +#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:90 msgid "Slug" msgstr "" -#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:102 +#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:91 msgid "The slug can't be empty" msgstr "" @@ -168,45 +174,45 @@ msgid "This address contains errors" msgstr "Questo indirizzo contiene errori" #: mediagoblin/edit/forms.py:63 -msgid "Old password" -msgstr "Password vecchia" - -#: mediagoblin/edit/forms.py:64 -msgid "Enter your old password to prove you own this account." -msgstr "Inserisci la vecchia password per dimostrare di essere il proprietario dell'account." - -#: mediagoblin/edit/forms.py:67 -msgid "New password" -msgstr "Nuova password" - -#: mediagoblin/edit/forms.py:74 msgid "License preference" msgstr "" -#: mediagoblin/edit/forms.py:80 +#: mediagoblin/edit/forms.py:69 msgid "This will be your default license on upload forms." msgstr "" -#: mediagoblin/edit/forms.py:82 +#: mediagoblin/edit/forms.py:71 msgid "Email me when others comment on my media" msgstr "Inviami messaggi email quando altre persone commentano i miei files multimediali" -#: mediagoblin/edit/forms.py:94 +#: mediagoblin/edit/forms.py:83 msgid "The title can't be empty" msgstr "" -#: mediagoblin/edit/forms.py:96 mediagoblin/submit/forms.py:50 +#: mediagoblin/edit/forms.py:85 mediagoblin/submit/forms.py:50 #: mediagoblin/user_pages/forms.py:48 msgid "Description of this collection" msgstr "" -#: mediagoblin/edit/forms.py:103 +#: mediagoblin/edit/forms.py:92 msgid "" "The title part of this collection's address. You usually don't need to " "change this." msgstr "" -#: mediagoblin/edit/views.py:66 +#: mediagoblin/edit/forms.py:99 +msgid "Old password" +msgstr "Password vecchia" + +#: mediagoblin/edit/forms.py:101 +msgid "Enter your old password to prove you own this account." +msgstr "Inserisci la vecchia password per dimostrare di essere il proprietario dell'account." + +#: mediagoblin/edit/forms.py:104 +msgid "New password" +msgstr "Nuova password" + +#: mediagoblin/edit/views.py:67 msgid "An entry with that slug already exists for this user." msgstr "" @@ -231,44 +237,63 @@ msgstr "Stai modificando il profilo di un utente. Procedi con attenzione." msgid "Profile changes saved" msgstr "Cambiamenti del profilo salvati" -#: mediagoblin/edit/views.py:241 -msgid "Wrong password" -msgstr "Password errata" - -#: mediagoblin/edit/views.py:252 +#: mediagoblin/edit/views.py:240 msgid "Account settings saved" msgstr "Impostazioni del profilo salvate" -#: mediagoblin/edit/views.py:286 +#: mediagoblin/edit/views.py:274 msgid "You need to confirm the deletion of your account." msgstr "" -#: mediagoblin/edit/views.py:322 mediagoblin/submit/views.py:142 -#: mediagoblin/user_pages/views.py:214 +#: mediagoblin/edit/views.py:310 mediagoblin/submit/views.py:138 +#: mediagoblin/user_pages/views.py:222 #, python-format msgid "You already have a collection called \"%s\"!" msgstr "" -#: mediagoblin/edit/views.py:326 +#: mediagoblin/edit/views.py:314 msgid "A collection with that slug already exists for this user." msgstr "" -#: mediagoblin/edit/views.py:343 +#: mediagoblin/edit/views.py:329 msgid "You are editing another user's collection. Proceed with caution." msgstr "" -#: mediagoblin/gmg_commands/theme.py:58 +#: mediagoblin/edit/views.py:348 +msgid "Wrong password" +msgstr "Password errata" + +#: mediagoblin/edit/views.py:363 +msgid "Your password was changed successfully" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:60 msgid "Cannot link theme... no theme set\n" msgstr "" -#: mediagoblin/gmg_commands/theme.py:71 +#: mediagoblin/gmg_commands/assetlink.py:73 msgid "No asset directory for this theme\n" msgstr "" -#: mediagoblin/gmg_commands/theme.py:74 +#: mediagoblin/gmg_commands/assetlink.py:76 msgid "However, old link directory symlink found; removed.\n" msgstr "" +#: mediagoblin/gmg_commands/assetlink.py:112 +#, python-format +msgid "Could not link \"%s\": %s exists and is not a symlink\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:119 +#, python-format +msgid "Skipping \"%s\"; already set up.\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:124 +#, python-format +msgid "Old link found for \"%s\"; removing.\n" +msgstr "" + #: mediagoblin/meddleware/csrf.py:134 msgid "" "CSRF cookie not present. This is most likely the result of a cookie blocker " @@ -276,12 +301,16 @@ msgid "" "domain." msgstr "" -#: mediagoblin/media_types/__init__.py:61 -#: mediagoblin/media_types/__init__.py:102 +#: mediagoblin/media_types/__init__.py:111 +#: mediagoblin/media_types/__init__.py:155 msgid "Sorry, I don't support that file type :(" msgstr "Mi dispiace, non supporto questo tipo di file :(" -#: mediagoblin/media_types/video/processing.py:36 +#: mediagoblin/media_types/pdf/processing.py:136 +msgid "unoconv failing to run, check log file" +msgstr "" + +#: mediagoblin/media_types/video/processing.py:37 msgid "Video transcoding failed" msgstr "Transcodifica video fallita" @@ -348,7 +377,7 @@ msgstr "" msgid "This field is required for public clients" msgstr "" -#: mediagoblin/plugins/oauth/views.py:59 +#: mediagoblin/plugins/oauth/views.py:56 msgid "The client {0} has been registered!" msgstr "" @@ -367,7 +396,7 @@ msgstr "" msgid "Add" msgstr "Aggiungi" -#: mediagoblin/processing/__init__.py:172 +#: mediagoblin/processing/__init__.py:193 msgid "Invalid file given for media type." msgstr "File non valido per il tipo di file multimediale indicato." @@ -375,45 +404,45 @@ msgstr "File non valido per il tipo di file multimediale indicato." msgid "File" msgstr "File" -#: mediagoblin/submit/views.py:51 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "Devi specificare un file." -#: mediagoblin/submit/views.py:97 +#: mediagoblin/submit/views.py:93 msgid "Woohoo! Submitted!" msgstr "Evviva! Caricato!" -#: mediagoblin/submit/views.py:146 +#: mediagoblin/submit/views.py:144 #, python-format msgid "Collection \"%s\" added!" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:64 +#: mediagoblin/templates/mediagoblin/base.html:67 msgid "Verify your email!" msgstr "Verifica la tua email!" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:68 msgid "log out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:70 +#: mediagoblin/templates/mediagoblin/base.html:73 #: mediagoblin/templates/mediagoblin/auth/login.html:28 #: mediagoblin/templates/mediagoblin/auth/login.html:36 #: mediagoblin/templates/mediagoblin/auth/login.html:54 msgid "Log in" msgstr "Accedi" -#: mediagoblin/templates/mediagoblin/base.html:79 +#: mediagoblin/templates/mediagoblin/base.html:82 #, python-format msgid "<a href=\"%(user_url)s\">%(user_name)s</a>'s account" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:86 +#: mediagoblin/templates/mediagoblin/base.html:89 msgid "Change account settings" msgstr "Cambia le impostazioni dell'account" -#: mediagoblin/templates/mediagoblin/base.html:90 -#: mediagoblin/templates/mediagoblin/base.html:105 +#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:108 #: mediagoblin/templates/mediagoblin/admin/panel.html:21 #: mediagoblin/templates/mediagoblin/admin/panel.html:26 #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:21 @@ -421,72 +450,25 @@ msgstr "Cambia le impostazioni dell'account" msgid "Media processing panel" msgstr "Pannello di elaborazione files multimediali" -#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:96 msgid "Log out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:96 +#: mediagoblin/templates/mediagoblin/base.html:99 #: mediagoblin/templates/mediagoblin/user_pages/user.html:156 msgid "Add media" msgstr "Aggiungi files multimediali" -#: mediagoblin/templates/mediagoblin/base.html:99 +#: mediagoblin/templates/mediagoblin/base.html:102 #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:41 msgid "Create new collection" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:122 -#, python-format -msgid "" -"Powered by <a href=\"http://mediagoblin.org/\" title='Version " -"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." -msgstr "" - -#: mediagoblin/templates/mediagoblin/base.html:125 -#, 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 "Rilasciato con licenza <a href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a href=\"%(source_link)s\">Codice sorgente</a> disponibile." - #: mediagoblin/templates/mediagoblin/error.html:24 msgid "Image of goblin stressing out" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:31 -msgid "Explore" -msgstr "Esplora" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "Ciao, benvenuto in questo sito MediaGoblin!" - -#: mediagoblin/templates/mediagoblin/root.html:35 -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 per caricare e condividere files multimediali." - -#: mediagoblin/templates/mediagoblin/root.html:36 -msgid "" -"To add your own media, place comments, and more, you can log in with your " -"MediaGoblin account." -msgstr "Per aggiungere i tuoi file multimediali, scrivere commenti e altro puoi accedere con il tuo account MediaGoblin." - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Don't have one yet? It's easy!" -msgstr "Non ne hai già uno? E' semplice!" - -#: mediagoblin/templates/mediagoblin/root.html:39 -#, 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\">Crea un account in questo sito</a>\n oppure\n <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">Installa MediaGoblin sul tuo server</a>" - -#: mediagoblin/templates/mediagoblin/root.html:47 +#: mediagoblin/templates/mediagoblin/root.html:32 msgid "Most recent media" msgstr "Files multimediali più recenti" @@ -592,6 +574,53 @@ msgid "" "%(verification_url)s" msgstr "Ciao %(username)s,\n\nper attivare il tuo account GNU MediaGoblin, apri il seguente URL nel \ntuo navigatore web.\n\n%(verification_url)s" +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:21 +#, python-format +msgid "" +"Powered by <a href=\"http://mediagoblin.org/\" title='Version " +"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:24 +#, 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 "Rilasciato con licenza <a href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a href=\"%(source_link)s\">Codice sorgente</a> disponibile." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:20 +msgid "Explore" +msgstr "Esplora" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:22 +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "Ciao, benvenuto in questo sito MediaGoblin!" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:24 +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 per caricare e condividere files multimediali." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:25 +msgid "" +"To add your own media, place comments, and more, you can log in with your " +"MediaGoblin account." +msgstr "Per aggiungere i tuoi file multimediali, scrivere commenti e altro puoi accedere con il tuo account MediaGoblin." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:27 +msgid "Don't have one yet? It's easy!" +msgstr "Non ne hai già uno? E' semplice!" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:28 +#, 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/bits/logo.html:23 #: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 msgid "MediaGoblin logo" @@ -604,13 +633,13 @@ msgid "Editing attachments for %(media_title)s" msgstr "Stai modificando gli allegati di %(media_title)s" #: mediagoblin/templates/mediagoblin/edit/attachments.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:159 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:175 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:182 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:198 msgid "Attachments" msgstr "Allegati" #: mediagoblin/templates/mediagoblin/edit/attachments.html:57 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:181 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:204 msgid "Add attachment" msgstr "Aggiungi allegato" @@ -627,12 +656,22 @@ msgstr "Annulla" #: mediagoblin/templates/mediagoblin/edit/attachments.html:63 #: mediagoblin/templates/mediagoblin/edit/edit.html:42 -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:52 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:55 #: mediagoblin/templates/mediagoblin/edit/edit_collection.html:33 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:40 msgid "Save changes" msgstr "Salva i cambiamenti" +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:28 +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 +#, python-format +msgid "Changing %(username)s's password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 +msgid "Save" +msgstr "" + #: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 #, python-format msgid "Really delete user '%(user_name)s' and all related media/comments?" @@ -643,7 +682,7 @@ msgid "Yes, really delete my account" msgstr "" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:48 #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49 msgid "Delete permanently" msgstr "Elimina definitivamente" @@ -660,7 +699,11 @@ msgstr "Stai modificando %(media_title)s" msgid "Changing %(username)s's account settings" msgstr "Stai cambiando le impostazioni dell'account di %(username)s" -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:59 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 +msgid "Change your password." +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 msgid "Delete my account" msgstr "" @@ -685,6 +728,7 @@ msgstr "File taggato con: %(tag_name)s" #: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 #: mediagoblin/templates/mediagoblin/media_displays/audio.html:56 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:65 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:136 #: mediagoblin/templates/mediagoblin/media_displays/video.html:55 msgid "Download" @@ -709,6 +753,7 @@ msgid "" msgstr "Puoi scaricare un browser web moderno,\n\t in grado di leggere questo file audio, qui <a href=\"http://getfirefox.com\">\n\t http://getfirefox.com</a>!" #: mediagoblin/templates/mediagoblin/media_displays/audio.html:60 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:71 #: mediagoblin/templates/mediagoblin/media_displays/video.html:61 msgid "Original file" msgstr "File originario" @@ -717,6 +762,7 @@ msgstr "File originario" msgid "WebM file (Vorbis codec)" msgstr "File WebM (codec Vorbis)" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:59 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:87 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:93 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:99 @@ -727,6 +773,10 @@ msgstr "File WebM (codec Vorbis)" msgid "Image for %(media_title)s" msgstr "" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 +msgid "PDF file" +msgstr "" + #: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 msgid "Toggle Rotate" msgstr "" @@ -753,7 +803,7 @@ msgstr "" #: mediagoblin/templates/mediagoblin/media_displays/stl.html:130 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:131 msgid "WebGL" -msgstr "" +msgstr "WebGL" #: mediagoblin/templates/mediagoblin/media_displays/stl.html:138 msgid "Download model" @@ -825,7 +875,7 @@ msgstr "Vuoi davvero eliminare %(title)s?" msgid "Really remove %(media_title)s from %(collection_title)s?" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:54 msgid "Remove" msgstr "" @@ -868,24 +918,28 @@ msgstr "Files multimediali di <a href=\"%(user_url)s\">%(username)s</a>" msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>" msgstr "â– Stai guardando i files multimediali di <a href=\"%(user_url)s\">%(username)s</a>" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:94 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:95 msgid "Add a comment" msgstr "Aggiungi un commento" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 msgid "Add this comment" msgstr "Aggiungi questo commento" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:123 -msgid "at" -msgstr "a" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:144 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:132 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:152 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:164 #, python-format -msgid "" -"<h3>Added on</h3>\n" -" <p>%(date)s</p>" -msgstr "<h3>Aggiunto il</h3>\n <p>%(date)s</p>" +msgid "%(formatted_time)s ago" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:150 +msgid "Added" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:161 +msgid "Created" +msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:40 @@ -1041,7 +1095,7 @@ msgstr "più vecchio" msgid "Tagged with" msgstr "Taggato con" -#: mediagoblin/tools/exif.py:80 +#: mediagoblin/tools/exif.py:83 msgid "Could not read the image file." msgstr "Impossibile leggere il file immagine." @@ -1071,6 +1125,30 @@ msgid "" " deleted." msgstr "" +#: mediagoblin/tools/timesince.py:62 +msgid "year" +msgstr "" + +#: mediagoblin/tools/timesince.py:63 +msgid "month" +msgstr "" + +#: mediagoblin/tools/timesince.py:64 +msgid "week" +msgstr "" + +#: mediagoblin/tools/timesince.py:65 +msgid "day" +msgstr "" + +#: mediagoblin/tools/timesince.py:66 +msgid "hour" +msgstr "" + +#: mediagoblin/tools/timesince.py:67 +msgid "minute" +msgstr "" + #: mediagoblin/user_pages/forms.py:23 msgid "Comment" msgstr "" @@ -1102,73 +1180,77 @@ msgstr "" msgid "Include a note" msgstr "" -#: mediagoblin/user_pages/lib.py:56 +#: mediagoblin/user_pages/lib.py:58 msgid "commented on your post" msgstr "ha commentato il tuo post" -#: mediagoblin/user_pages/views.py:166 +#: mediagoblin/user_pages/views.py:169 +msgid "Sorry, comments are disabled." +msgstr "" + +#: mediagoblin/user_pages/views.py:174 msgid "Oops, your comment was empty." msgstr "Oops, il tuo commento era vuoto." -#: mediagoblin/user_pages/views.py:172 +#: mediagoblin/user_pages/views.py:180 msgid "Your comment has been posted!" msgstr "Il tuo commento è stato aggiunto!" -#: mediagoblin/user_pages/views.py:197 +#: mediagoblin/user_pages/views.py:205 msgid "Please check your entries and try again." msgstr "" -#: mediagoblin/user_pages/views.py:237 +#: mediagoblin/user_pages/views.py:245 msgid "You have to select or add a collection" msgstr "" -#: mediagoblin/user_pages/views.py:248 +#: mediagoblin/user_pages/views.py:256 #, python-format msgid "\"%s\" already in collection \"%s\"" msgstr "" -#: mediagoblin/user_pages/views.py:264 +#: mediagoblin/user_pages/views.py:262 #, python-format msgid "\"%s\" added to collection \"%s\"" msgstr "" -#: mediagoblin/user_pages/views.py:286 +#: mediagoblin/user_pages/views.py:282 msgid "You deleted the media." msgstr "Hai eliminato il file." -#: mediagoblin/user_pages/views.py:293 +#: mediagoblin/user_pages/views.py:289 msgid "The media was not deleted because you didn't check that you were sure." msgstr "Il file non è stato eliminato perchè non hai confermato di essere sicuro." -#: mediagoblin/user_pages/views.py:301 +#: mediagoblin/user_pages/views.py:296 msgid "You are about to delete another user's media. Proceed with caution." msgstr "Stai eliminando un file multimediale di un altro utente. Procedi con attenzione." -#: mediagoblin/user_pages/views.py:375 +#: mediagoblin/user_pages/views.py:370 msgid "You deleted the item from the collection." msgstr "" -#: mediagoblin/user_pages/views.py:379 +#: mediagoblin/user_pages/views.py:374 msgid "The item was not removed because you didn't check that you were sure." msgstr "" -#: mediagoblin/user_pages/views.py:389 +#: mediagoblin/user_pages/views.py:382 msgid "" "You are about to delete an item from another user's collection. Proceed with" " caution." msgstr "" -#: mediagoblin/user_pages/views.py:422 +#: mediagoblin/user_pages/views.py:415 #, python-format msgid "You deleted the collection \"%s\"" msgstr "" -#: mediagoblin/user_pages/views.py:429 +#: mediagoblin/user_pages/views.py:422 msgid "" "The collection was not deleted because you didn't check that you were sure." msgstr "" -#: mediagoblin/user_pages/views.py:439 +#: mediagoblin/user_pages/views.py:430 msgid "" "You are about to delete another user's collection. Proceed with caution." msgstr "" diff --git a/mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.mo Binary files differindex 1344c9bd..3c82d1ff 100644 --- a/mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.mo +++ b/mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.po index 008a6d27..97d68127 100644 --- a/mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/ja/LC_MESSAGES/mediagoblin.po @@ -3,16 +3,16 @@ # This file is distributed under the same license as the PROJECT project. # # Translators: -# <averym@gmail.com>, 2011. -# <parlegon@gmail.com>, 2013. +# Avery <averym@gmail.com>, 2011 +# parlegon <parlegon@gmail.com>, 2013 msgid "" msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" -"POT-Creation-Date: 2013-03-04 18:04-0600\n" -"PO-Revision-Date: 2013-03-05 00:04+0000\n" +"POT-Creation-Date: 2013-05-27 13:54-0500\n" +"PO-Revision-Date: 2013-05-27 18:54+0000\n" "Last-Translator: cwebber <cwebber@dustycloud.org>\n" -"Language-Team: LANGUAGE <LL@li.org>\n" +"Language-Team: Japanese (http://www.transifex.com/projects/p/mediagoblin/language/ja/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -20,34 +20,39 @@ msgstr "" "Language: ja\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: mediagoblin/auth/forms.py:28 -msgid "Invalid User name or email address." -msgstr "" - -#: mediagoblin/auth/forms.py:29 -msgid "This field does not take email addresses." -msgstr "" - -#: mediagoblin/auth/forms.py:30 -msgid "This field requires an email address." -msgstr "" - -#: mediagoblin/auth/forms.py:52 mediagoblin/auth/forms.py:67 +#: mediagoblin/auth/forms.py:26 msgid "Username" msgstr "ユーザãƒãƒ¼ãƒ " -#: mediagoblin/auth/forms.py:56 mediagoblin/auth/forms.py:71 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 +#: mediagoblin/tests/test_util.py:110 msgid "Password" msgstr "パスワード" -#: mediagoblin/auth/forms.py:60 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "メールアドレス" -#: mediagoblin/auth/forms.py:78 +#: mediagoblin/auth/forms.py:41 +msgid "Username or Email" +msgstr "" + +#: mediagoblin/auth/forms.py:52 msgid "Username or email" msgstr "" +#: mediagoblin/auth/tools.py:31 +msgid "Invalid User name or email address." +msgstr "" + +#: mediagoblin/auth/tools.py:32 +msgid "This field does not take email addresses." +msgstr "" + +#: mediagoblin/auth/tools.py:33 +msgid "This field requires an email address." +msgstr "" + #: mediagoblin/auth/views.py:54 msgid "Sorry, registration is disabled on this instance." msgstr "申ã—訳ã‚りã¾ã›ã‚“ãŒã€ã“ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ã§ç™»éŒ²ã¯ç„¡åйã«ãªã£ã¦ã„ã¾ã™ã€‚" @@ -60,54 +65,54 @@ msgstr "申ã—訳ã‚りã¾ã›ã‚“ãŒã€ãã®åå‰ã‚’æŒã¤ãƒ¦ãƒ¼ã‚¶ãƒ¼ãŒã™ã§ msgid "Sorry, a user with that email address already exists." msgstr "" -#: mediagoblin/auth/views.py:174 +#: 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:180 +#: mediagoblin/auth/views.py:188 msgid "The verification key or user id is incorrect" msgstr "検証ã‚ーã¾ãŸã¯ãƒ¦ãƒ¼ã‚¶ãƒ¼IDãŒé–“é•ã£ã¦ã„ã¾ã™" -#: mediagoblin/auth/views.py:198 +#: 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:206 +#: mediagoblin/auth/views.py:214 msgid "You've already verified your email address!" msgstr "" -#: mediagoblin/auth/views.py:219 +#: mediagoblin/auth/views.py:227 msgid "Resent your verification email." msgstr "検証メールをå†é€ã—ã¾ã—ãŸã€‚" -#: mediagoblin/auth/views.py:250 +#: mediagoblin/auth/views.py:258 msgid "" "If that email address (case sensitive!) is registered an email has been sent" " with instructions on how to change your password." msgstr "" -#: mediagoblin/auth/views.py:261 +#: mediagoblin/auth/views.py:269 msgid "Couldn't find someone with that username." msgstr "" -#: mediagoblin/auth/views.py:264 +#: mediagoblin/auth/views.py:272 msgid "" "An email has been sent with instructions on how to change your password." msgstr "" -#: mediagoblin/auth/views.py:271 +#: mediagoblin/auth/views.py:279 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." msgstr "" -#: mediagoblin/auth/views.py:328 +#: mediagoblin/auth/views.py:336 msgid "You can now log in using your new password." msgstr "" -#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:93 +#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:82 #: mediagoblin/submit/forms.py:28 mediagoblin/submit/forms.py:47 #: mediagoblin/user_pages/forms.py:45 msgid "Title" @@ -118,7 +123,7 @@ msgid "Description of this work" msgstr "" #: mediagoblin/edit/forms.py:29 mediagoblin/edit/forms.py:52 -#: mediagoblin/edit/forms.py:97 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:86 mediagoblin/submit/forms.py:32 #: mediagoblin/submit/forms.py:51 mediagoblin/user_pages/forms.py:49 msgid "" "You can use\n" @@ -134,11 +139,11 @@ msgstr "ã‚¿ã‚°" msgid "Separate tags by commas." msgstr "" -#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:101 +#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:90 msgid "Slug" msgstr "スラグ" -#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:102 +#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:91 msgid "The slug can't be empty" msgstr "スラグã¯å¿…è¦ã§ã™ã€‚" @@ -166,45 +171,45 @@ msgid "This address contains errors" msgstr "" #: mediagoblin/edit/forms.py:63 -msgid "Old password" -msgstr "" - -#: mediagoblin/edit/forms.py:64 -msgid "Enter your old password to prove you own this account." -msgstr "" - -#: mediagoblin/edit/forms.py:67 -msgid "New password" -msgstr "" - -#: mediagoblin/edit/forms.py:74 msgid "License preference" msgstr "" -#: mediagoblin/edit/forms.py:80 +#: mediagoblin/edit/forms.py:69 msgid "This will be your default license on upload forms." msgstr "" -#: mediagoblin/edit/forms.py:82 +#: mediagoblin/edit/forms.py:71 msgid "Email me when others comment on my media" msgstr "" -#: mediagoblin/edit/forms.py:94 +#: mediagoblin/edit/forms.py:83 msgid "The title can't be empty" msgstr "" -#: mediagoblin/edit/forms.py:96 mediagoblin/submit/forms.py:50 +#: mediagoblin/edit/forms.py:85 mediagoblin/submit/forms.py:50 #: mediagoblin/user_pages/forms.py:48 msgid "Description of this collection" msgstr "" -#: mediagoblin/edit/forms.py:103 +#: mediagoblin/edit/forms.py:92 msgid "" "The title part of this collection's address. You usually don't need to " "change this." msgstr "" -#: mediagoblin/edit/views.py:66 +#: mediagoblin/edit/forms.py:99 +msgid "Old password" +msgstr "" + +#: mediagoblin/edit/forms.py:101 +msgid "Enter your old password to prove you own this account." +msgstr "" + +#: mediagoblin/edit/forms.py:104 +msgid "New password" +msgstr "" + +#: mediagoblin/edit/views.py:67 msgid "An entry with that slug already exists for this user." msgstr "ãã®ã‚¹ãƒ©ã‚°ã‚’æŒã¤ã‚¨ãƒ³ãƒˆãƒªã¯ã€ã“ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¯æ—¢ã«å˜åœ¨ã—ã¾ã™ã€‚" @@ -229,44 +234,63 @@ msgstr "ã‚ãªãŸã¯ã€ä»–ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã®ãƒ—ãƒãƒ•ァイルを編集ã—ã¦ã„ msgid "Profile changes saved" msgstr "" -#: mediagoblin/edit/views.py:241 -msgid "Wrong password" -msgstr "" - -#: mediagoblin/edit/views.py:252 +#: mediagoblin/edit/views.py:240 msgid "Account settings saved" msgstr "" -#: mediagoblin/edit/views.py:286 +#: mediagoblin/edit/views.py:274 msgid "You need to confirm the deletion of your account." msgstr "" -#: mediagoblin/edit/views.py:322 mediagoblin/submit/views.py:142 -#: mediagoblin/user_pages/views.py:214 +#: mediagoblin/edit/views.py:310 mediagoblin/submit/views.py:138 +#: mediagoblin/user_pages/views.py:222 #, python-format msgid "You already have a collection called \"%s\"!" msgstr "" -#: mediagoblin/edit/views.py:326 +#: mediagoblin/edit/views.py:314 msgid "A collection with that slug already exists for this user." msgstr "" -#: mediagoblin/edit/views.py:343 +#: mediagoblin/edit/views.py:329 msgid "You are editing another user's collection. Proceed with caution." msgstr "" -#: mediagoblin/gmg_commands/theme.py:58 +#: mediagoblin/edit/views.py:348 +msgid "Wrong password" +msgstr "" + +#: mediagoblin/edit/views.py:363 +msgid "Your password was changed successfully" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:60 msgid "Cannot link theme... no theme set\n" msgstr "" -#: mediagoblin/gmg_commands/theme.py:71 +#: mediagoblin/gmg_commands/assetlink.py:73 msgid "No asset directory for this theme\n" msgstr "" -#: mediagoblin/gmg_commands/theme.py:74 +#: mediagoblin/gmg_commands/assetlink.py:76 msgid "However, old link directory symlink found; removed.\n" msgstr "" +#: mediagoblin/gmg_commands/assetlink.py:112 +#, python-format +msgid "Could not link \"%s\": %s exists and is not a symlink\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:119 +#, python-format +msgid "Skipping \"%s\"; already set up.\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:124 +#, python-format +msgid "Old link found for \"%s\"; removing.\n" +msgstr "" + #: mediagoblin/meddleware/csrf.py:134 msgid "" "CSRF cookie not present. This is most likely the result of a cookie blocker " @@ -274,12 +298,16 @@ msgid "" "domain." msgstr "" -#: mediagoblin/media_types/__init__.py:61 -#: mediagoblin/media_types/__init__.py:102 +#: mediagoblin/media_types/__init__.py:111 +#: mediagoblin/media_types/__init__.py:155 msgid "Sorry, I don't support that file type :(" msgstr "" -#: mediagoblin/media_types/video/processing.py:36 +#: mediagoblin/media_types/pdf/processing.py:136 +msgid "unoconv failing to run, check log file" +msgstr "" + +#: mediagoblin/media_types/video/processing.py:37 msgid "Video transcoding failed" msgstr "" @@ -346,7 +374,7 @@ msgstr "" msgid "This field is required for public clients" msgstr "" -#: mediagoblin/plugins/oauth/views.py:59 +#: mediagoblin/plugins/oauth/views.py:56 msgid "The client {0} has been registered!" msgstr "" @@ -365,7 +393,7 @@ msgstr "" msgid "Add" msgstr "è¿½åŠ " -#: mediagoblin/processing/__init__.py:172 +#: mediagoblin/processing/__init__.py:193 msgid "Invalid file given for media type." msgstr "" @@ -373,45 +401,45 @@ msgstr "" msgid "File" msgstr "ファイル" -#: mediagoblin/submit/views.py:51 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "ファイルをæä¾›ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" -#: mediagoblin/submit/views.py:97 +#: mediagoblin/submit/views.py:93 msgid "Woohoo! Submitted!" msgstr "投稿終了ï¼" -#: mediagoblin/submit/views.py:146 +#: mediagoblin/submit/views.py:144 #, python-format msgid "Collection \"%s\" added!" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:64 +#: mediagoblin/templates/mediagoblin/base.html:67 msgid "Verify your email!" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:68 msgid "log out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:70 +#: mediagoblin/templates/mediagoblin/base.html:73 #: mediagoblin/templates/mediagoblin/auth/login.html:28 #: mediagoblin/templates/mediagoblin/auth/login.html:36 #: mediagoblin/templates/mediagoblin/auth/login.html:54 msgid "Log in" msgstr "ãƒã‚°ã‚¤ãƒ³" -#: mediagoblin/templates/mediagoblin/base.html:79 +#: mediagoblin/templates/mediagoblin/base.html:82 #, python-format msgid "<a href=\"%(user_url)s\">%(user_name)s</a>'s account" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:86 +#: mediagoblin/templates/mediagoblin/base.html:89 msgid "Change account settings" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:90 -#: mediagoblin/templates/mediagoblin/base.html:105 +#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:108 #: mediagoblin/templates/mediagoblin/admin/panel.html:21 #: mediagoblin/templates/mediagoblin/admin/panel.html:26 #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:21 @@ -419,72 +447,25 @@ msgstr "" msgid "Media processing panel" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:96 msgid "Log out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:96 +#: mediagoblin/templates/mediagoblin/base.html:99 #: mediagoblin/templates/mediagoblin/user_pages/user.html:156 msgid "Add media" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:99 +#: mediagoblin/templates/mediagoblin/base.html:102 #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:41 msgid "Create new collection" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:122 -#, python-format -msgid "" -"Powered by <a href=\"http://mediagoblin.org/\" title='Version " -"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." -msgstr "" - -#: mediagoblin/templates/mediagoblin/base.html:125 -#, 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/error.html:24 msgid "Image of goblin stressing out" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:31 -msgid "Explore" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "ã“ã‚“ã«ã¡ã¯ã€ã“ã®MediaGoblinサイトã¸ã‚ˆã†ã“ãï¼" - -#: mediagoblin/templates/mediagoblin/root.html:35 -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:36 -msgid "" -"To add your own media, place comments, and more, you can log in with your " -"MediaGoblin account." -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Don't have one yet? It's easy!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:39 -#, 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:47 +#: mediagoblin/templates/mediagoblin/root.html:32 msgid "Most recent media" msgstr "" @@ -590,6 +571,53 @@ msgid "" "%(verification_url)s" msgstr "%(username)s様ã¸\n\nGNU MediaGoblinアカウントを検証ã«ã™ã‚‹ã«ã¯ã€ã“ã®URLã‚’é–‹ã„ã¦ãã ã•ã„。\n\n%(verification_url)s" +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:21 +#, python-format +msgid "" +"Powered by <a href=\"http://mediagoblin.org/\" title='Version " +"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:24 +#, 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/bits/frontpage_welcome.html:20 +msgid "Explore" +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:22 +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "ã“ã‚“ã«ã¡ã¯ã€ã“ã®MediaGoblinサイトã¸ã‚ˆã†ã“ãï¼" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:24 +msgid "" +"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, an " +"extraordinarily great piece of media hosting software." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:25 +msgid "" +"To add your own media, place comments, and more, you can log in with your " +"MediaGoblin account." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:27 +msgid "Don't have one yet? It's easy!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:28 +#, python-format +msgid "" +"<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/bits/logo.html:23 #: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 msgid "MediaGoblin logo" @@ -602,13 +630,13 @@ msgid "Editing attachments for %(media_title)s" msgstr "" #: mediagoblin/templates/mediagoblin/edit/attachments.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:159 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:175 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:182 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:198 msgid "Attachments" msgstr "" #: mediagoblin/templates/mediagoblin/edit/attachments.html:57 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:181 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:204 msgid "Add attachment" msgstr "" @@ -625,12 +653,22 @@ msgstr "ã‚ャンセル" #: mediagoblin/templates/mediagoblin/edit/attachments.html:63 #: mediagoblin/templates/mediagoblin/edit/edit.html:42 -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:52 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:55 #: mediagoblin/templates/mediagoblin/edit/edit_collection.html:33 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:40 msgid "Save changes" msgstr "投稿ã™ã‚‹" +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:28 +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 +#, python-format +msgid "Changing %(username)s's password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 +msgid "Save" +msgstr "" + #: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 #, python-format msgid "Really delete user '%(user_name)s' and all related media/comments?" @@ -641,7 +679,7 @@ msgid "Yes, really delete my account" msgstr "" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:48 #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49 msgid "Delete permanently" msgstr "" @@ -658,7 +696,11 @@ msgstr "%(media_title)sを編集ä¸" msgid "Changing %(username)s's account settings" msgstr "" -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:59 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 +msgid "Change your password." +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 msgid "Delete my account" msgstr "" @@ -683,6 +725,7 @@ msgstr "" #: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 #: mediagoblin/templates/mediagoblin/media_displays/audio.html:56 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:65 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:136 #: mediagoblin/templates/mediagoblin/media_displays/video.html:55 msgid "Download" @@ -707,6 +750,7 @@ msgid "" msgstr "" #: mediagoblin/templates/mediagoblin/media_displays/audio.html:60 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:71 #: mediagoblin/templates/mediagoblin/media_displays/video.html:61 msgid "Original file" msgstr "" @@ -715,6 +759,7 @@ msgstr "" msgid "WebM file (Vorbis codec)" msgstr "" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:59 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:87 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:93 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:99 @@ -725,6 +770,10 @@ msgstr "" msgid "Image for %(media_title)s" msgstr "" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 +msgid "PDF file" +msgstr "" + #: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 msgid "Toggle Rotate" msgstr "" @@ -823,7 +872,7 @@ msgstr "" msgid "Really remove %(media_title)s from %(collection_title)s?" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:54 msgid "Remove" msgstr "" @@ -866,23 +915,27 @@ msgstr "<a href=\"%(user_url)s\">%(username)s</a>ã•ã‚“ã®ã‚³ãƒ³ãƒ†ãƒ³ãƒ„" msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:94 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:95 msgid "Add a comment" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 msgid "Add this comment" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:123 -msgid "at" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:132 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:152 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:164 +#, python-format +msgid "%(formatted_time)s ago" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:144 -#, python-format -msgid "" -"<h3>Added on</h3>\n" -" <p>%(date)s</p>" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:150 +msgid "Added" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:161 +msgid "Created" msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 @@ -1039,7 +1092,7 @@ msgstr "" msgid "Tagged with" msgstr "" -#: mediagoblin/tools/exif.py:80 +#: mediagoblin/tools/exif.py:83 msgid "Could not read the image file." msgstr "" @@ -1069,6 +1122,30 @@ msgid "" " deleted." msgstr "" +#: mediagoblin/tools/timesince.py:62 +msgid "year" +msgstr "" + +#: mediagoblin/tools/timesince.py:63 +msgid "month" +msgstr "" + +#: mediagoblin/tools/timesince.py:64 +msgid "week" +msgstr "" + +#: mediagoblin/tools/timesince.py:65 +msgid "day" +msgstr "" + +#: mediagoblin/tools/timesince.py:66 +msgid "hour" +msgstr "" + +#: mediagoblin/tools/timesince.py:67 +msgid "minute" +msgstr "" + #: mediagoblin/user_pages/forms.py:23 msgid "Comment" msgstr "" @@ -1100,73 +1177,77 @@ msgstr "" msgid "Include a note" msgstr "" -#: mediagoblin/user_pages/lib.py:56 +#: mediagoblin/user_pages/lib.py:58 msgid "commented on your post" msgstr "" -#: mediagoblin/user_pages/views.py:166 +#: mediagoblin/user_pages/views.py:169 +msgid "Sorry, comments are disabled." +msgstr "" + +#: mediagoblin/user_pages/views.py:174 msgid "Oops, your comment was empty." msgstr "" -#: mediagoblin/user_pages/views.py:172 +#: mediagoblin/user_pages/views.py:180 msgid "Your comment has been posted!" msgstr "" -#: mediagoblin/user_pages/views.py:197 +#: mediagoblin/user_pages/views.py:205 msgid "Please check your entries and try again." msgstr "" -#: mediagoblin/user_pages/views.py:237 +#: mediagoblin/user_pages/views.py:245 msgid "You have to select or add a collection" msgstr "" -#: mediagoblin/user_pages/views.py:248 +#: mediagoblin/user_pages/views.py:256 #, python-format msgid "\"%s\" already in collection \"%s\"" msgstr "" -#: mediagoblin/user_pages/views.py:264 +#: mediagoblin/user_pages/views.py:262 #, python-format msgid "\"%s\" added to collection \"%s\"" msgstr "" -#: mediagoblin/user_pages/views.py:286 +#: mediagoblin/user_pages/views.py:282 msgid "You deleted the media." msgstr "" -#: mediagoblin/user_pages/views.py:293 +#: mediagoblin/user_pages/views.py:289 msgid "The media was not deleted because you didn't check that you were sure." msgstr "" -#: mediagoblin/user_pages/views.py:301 +#: mediagoblin/user_pages/views.py:296 msgid "You are about to delete another user's media. Proceed with caution." msgstr "" -#: mediagoblin/user_pages/views.py:375 +#: mediagoblin/user_pages/views.py:370 msgid "You deleted the item from the collection." msgstr "" -#: mediagoblin/user_pages/views.py:379 +#: mediagoblin/user_pages/views.py:374 msgid "The item was not removed because you didn't check that you were sure." msgstr "" -#: mediagoblin/user_pages/views.py:389 +#: mediagoblin/user_pages/views.py:382 msgid "" "You are about to delete an item from another user's collection. Proceed with" " caution." msgstr "" -#: mediagoblin/user_pages/views.py:422 +#: mediagoblin/user_pages/views.py:415 #, python-format msgid "You deleted the collection \"%s\"" msgstr "" -#: mediagoblin/user_pages/views.py:429 +#: mediagoblin/user_pages/views.py:422 msgid "" "The collection was not deleted because you didn't check that you were sure." msgstr "" -#: mediagoblin/user_pages/views.py:439 +#: mediagoblin/user_pages/views.py:430 msgid "" "You are about to delete another user's collection. Proceed with caution." msgstr "" diff --git a/mediagoblin/i18n/ko_KR/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/ko_KR/LC_MESSAGES/mediagoblin.mo Binary files differindex 69bf72bc..7d37ab7c 100644 --- a/mediagoblin/i18n/ko_KR/LC_MESSAGES/mediagoblin.mo +++ b/mediagoblin/i18n/ko_KR/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/ko_KR/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/ko_KR/LC_MESSAGES/mediagoblin.po index ac87c90f..5333de02 100644 --- a/mediagoblin/i18n/ko_KR/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/ko_KR/LC_MESSAGES/mediagoblin.po @@ -3,15 +3,15 @@ # This file is distributed under the same license as the PROJECT project. # # Translators: -# <newvgund@gmail.com>, 2012. +# Jin-hoon Kim <newvgund@gmail.com>, 2012 msgid "" msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" -"POT-Creation-Date: 2013-03-04 18:04-0600\n" -"PO-Revision-Date: 2013-03-05 00:04+0000\n" +"POT-Creation-Date: 2013-05-27 13:54-0500\n" +"PO-Revision-Date: 2013-05-27 18:54+0000\n" "Last-Translator: cwebber <cwebber@dustycloud.org>\n" -"Language-Team: LANGUAGE <LL@li.org>\n" +"Language-Team: Korean (Korea) (http://www.transifex.com/projects/p/mediagoblin/language/ko_KR/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -19,34 +19,39 @@ msgstr "" "Language: ko_KR\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: mediagoblin/auth/forms.py:28 -msgid "Invalid User name or email address." -msgstr "" - -#: mediagoblin/auth/forms.py:29 -msgid "This field does not take email addresses." -msgstr "" - -#: mediagoblin/auth/forms.py:30 -msgid "This field requires an email address." -msgstr "" - -#: mediagoblin/auth/forms.py:52 mediagoblin/auth/forms.py:67 +#: mediagoblin/auth/forms.py:26 msgid "Username" msgstr "ì‚¬ìš©ìž ì´ë¦„" -#: mediagoblin/auth/forms.py:56 mediagoblin/auth/forms.py:71 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 +#: mediagoblin/tests/test_util.py:110 msgid "Password" msgstr "비밀번호" -#: mediagoblin/auth/forms.py:60 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "email 주소" -#: mediagoblin/auth/forms.py:78 +#: mediagoblin/auth/forms.py:41 +msgid "Username or Email" +msgstr "" + +#: mediagoblin/auth/forms.py:52 msgid "Username or email" msgstr "ì‚¬ìš©ìž ì´ë¦„ ë˜ëŠ” email" +#: mediagoblin/auth/tools.py:31 +msgid "Invalid User name or email address." +msgstr "" + +#: mediagoblin/auth/tools.py:32 +msgid "This field does not take email addresses." +msgstr "" + +#: mediagoblin/auth/tools.py:33 +msgid "This field requires an email address." +msgstr "" + #: mediagoblin/auth/views.py:54 msgid "Sorry, registration is disabled on this instance." msgstr "죄송합니다. ì§€ê¸ˆì€ ê°€ìž… 하실 수 없습니다." @@ -59,54 +64,54 @@ msgstr "죄송합니다. 해당 ì‚¬ìš©ìž ì´ë¦„ì´ ì´ë¯¸ 존재 합니다." msgid "Sorry, a user with that email address already exists." msgstr "죄송합니다. 사용ìžì™€ 해당 ì´ë©”ì¼ì€ ì´ë¯¸ 등ë¡ë˜ì–´ 있습니다." -#: mediagoblin/auth/views.py:174 +#: mediagoblin/auth/views.py:182 msgid "" "Your email address has been verified. You may now login, edit your profile, " "and submit images!" msgstr "해당 email 주소가 ì´ë¯¸ ì¸ì¦ ë˜ì–´ 있습니다. 지금 로그ì¸í•˜ì‹œê³ ê³„ì • ì •ë³´ë¥¼ ìˆ˜ì •í•˜ê³ ì‚¬ì§„ì„ ì „ì†¡í•´ 보세요!" -#: mediagoblin/auth/views.py:180 +#: mediagoblin/auth/views.py:188 msgid "The verification key or user id is incorrect" msgstr "ì¸ì¦ 키 ë˜ëŠ” ì‚¬ìš©ìž IDê°€ 올바르지 않습니다." -#: mediagoblin/auth/views.py:198 +#: 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:206 +#: mediagoblin/auth/views.py:214 msgid "You've already verified your email address!" msgstr "ì´ë¯¸ ì¸ì¦ë°›ì€ email 주소를 ê°€ì§€ê³ ìžˆìŠµë‹ˆë‹¤!" -#: mediagoblin/auth/views.py:219 +#: mediagoblin/auth/views.py:227 msgid "Resent your verification email." msgstr "ì¸ì¦ ë©”ì¼ì„ 다시 ë³´ë‚´ 주세요." -#: mediagoblin/auth/views.py:250 +#: mediagoblin/auth/views.py:258 msgid "" "If that email address (case sensitive!) is registered an email has been sent" " with instructions on how to change your password." msgstr "" -#: mediagoblin/auth/views.py:261 +#: mediagoblin/auth/views.py:269 msgid "Couldn't find someone with that username." msgstr "" -#: mediagoblin/auth/views.py:264 +#: mediagoblin/auth/views.py:272 msgid "" "An email has been sent with instructions on how to change your password." msgstr "비밀번호를 변경하는 ë°©ë²•ì— ëŒ€í•œ 설명서가 ë©”ì¼ë¡œ ì „ì†¡ ë˜ì—ˆìŠµë‹ˆë‹¤." -#: mediagoblin/auth/views.py:271 +#: mediagoblin/auth/views.py:279 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." msgstr "사용ìžì˜ ì´ë¦„ì´ ì¡´ìž¬í•˜ì§€ 않거나, 사용ìžì˜ email 주소가 ì¸ì¦ë˜ì§€ 않아 비밀번호 복구 ë©”ì¼ì„ 보낼 수 없습니다." -#: mediagoblin/auth/views.py:328 +#: mediagoblin/auth/views.py:336 msgid "You can now log in using your new password." msgstr "ì´ì œ 새로운 비밀번호로 ë¡œê·¸ì¸ í•˜ì‹¤ 수 있습니다." -#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:93 +#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:82 #: mediagoblin/submit/forms.py:28 mediagoblin/submit/forms.py:47 #: mediagoblin/user_pages/forms.py:45 msgid "Title" @@ -117,7 +122,7 @@ msgid "Description of this work" msgstr "ì´ ìž‘ì—…ì— ëŒ€í•œ 설명" #: mediagoblin/edit/forms.py:29 mediagoblin/edit/forms.py:52 -#: mediagoblin/edit/forms.py:97 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:86 mediagoblin/submit/forms.py:32 #: mediagoblin/submit/forms.py:51 mediagoblin/user_pages/forms.py:49 msgid "" "You can use\n" @@ -133,11 +138,11 @@ msgstr "태그" msgid "Separate tags by commas." msgstr "태그는 , 로 구분 ë©ë‹ˆë‹¤." -#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:101 +#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:90 msgid "Slug" msgstr "'슬러그'" -#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:102 +#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:91 msgid "The slug can't be empty" msgstr "'슬러그'는 ê³µë°±ì¼ ìˆ˜ 없습니다." @@ -165,45 +170,45 @@ msgid "This address contains errors" msgstr "ì£¼ì†Œì— ì—러가 있습니다." #: mediagoblin/edit/forms.py:63 -msgid "Old password" -msgstr "ì˜ˆì „ 비밀번호" - -#: mediagoblin/edit/forms.py:64 -msgid "Enter your old password to prove you own this account." -msgstr "ê³„ì • 확ì¸ì„ 위해, ì´ì „ 비밀 번호를 ìž…ë ¥í•´ 주세요." - -#: mediagoblin/edit/forms.py:67 -msgid "New password" -msgstr "새로운 비밀번호" - -#: mediagoblin/edit/forms.py:74 msgid "License preference" msgstr "" -#: mediagoblin/edit/forms.py:80 +#: mediagoblin/edit/forms.py:69 msgid "This will be your default license on upload forms." msgstr "" -#: mediagoblin/edit/forms.py:82 +#: mediagoblin/edit/forms.py:71 msgid "Email me when others comment on my media" msgstr "ì œ ë¯¸ë””ì–´ì— ëŒ€í•œ 컨í…ì„ ì›í•œë‹¤ë©´, ë©”ì¼ì„ 보내주세요." -#: mediagoblin/edit/forms.py:94 +#: mediagoblin/edit/forms.py:83 msgid "The title can't be empty" msgstr "ì œëª©ì€ ê³µë°±ì¼ ìˆ˜ 없습니다." -#: mediagoblin/edit/forms.py:96 mediagoblin/submit/forms.py:50 +#: mediagoblin/edit/forms.py:85 mediagoblin/submit/forms.py:50 #: mediagoblin/user_pages/forms.py:48 msgid "Description of this collection" msgstr "모ìŒì§‘ì— ëŒ€í•œ 설명" -#: mediagoblin/edit/forms.py:103 +#: mediagoblin/edit/forms.py:92 msgid "" "The title part of this collection's address. You usually don't need to " "change this." msgstr "" -#: mediagoblin/edit/views.py:66 +#: mediagoblin/edit/forms.py:99 +msgid "Old password" +msgstr "ì˜ˆì „ 비밀번호" + +#: mediagoblin/edit/forms.py:101 +msgid "Enter your old password to prove you own this account." +msgstr "ê³„ì • 확ì¸ì„ 위해, ì´ì „ 비밀 번호를 ìž…ë ¥í•´ 주세요." + +#: mediagoblin/edit/forms.py:104 +msgid "New password" +msgstr "새로운 비밀번호" + +#: mediagoblin/edit/views.py:67 msgid "An entry with that slug already exists for this user." msgstr "해당 ìœ ì €ì— ëŒ€í•œ '슬러그'ê°€ ì´ë¯¸ 존재합니다." @@ -228,44 +233,63 @@ msgstr "사용ìžì˜ ê³„ì • ì •ë³´ë¥¼ ìˆ˜ì •í•˜ê³ ìžˆìŠµë‹ˆë‹¤. 조심해서 ìˆ msgid "Profile changes saved" msgstr "ê³„ì • ì •ë³´ê°€ ì €ìž¥ ë˜ì—ˆìŠµë‹ˆë‹¤." -#: mediagoblin/edit/views.py:241 -msgid "Wrong password" -msgstr "ìž˜ëª»ëœ ë¹„ë°€ë²ˆí˜¸" - -#: mediagoblin/edit/views.py:252 +#: mediagoblin/edit/views.py:240 msgid "Account settings saved" msgstr "ê³„ì • ì„¤ì •ì´ ì €ìž¥ ë˜ì—ˆìŠµë‹ˆë‹¤." -#: mediagoblin/edit/views.py:286 +#: mediagoblin/edit/views.py:274 msgid "You need to confirm the deletion of your account." msgstr "" -#: mediagoblin/edit/views.py:322 mediagoblin/submit/views.py:142 -#: mediagoblin/user_pages/views.py:214 +#: mediagoblin/edit/views.py:310 mediagoblin/submit/views.py:138 +#: mediagoblin/user_pages/views.py:222 #, python-format msgid "You already have a collection called \"%s\"!" msgstr "\"%s\" 모ìŒì§‘ì„ ì´ë¯¸ ê°€ì§€ê³ ìžˆìŠµë‹ˆë‹¤!" -#: mediagoblin/edit/views.py:326 +#: mediagoblin/edit/views.py:314 msgid "A collection with that slug already exists for this user." msgstr "" -#: mediagoblin/edit/views.py:343 +#: mediagoblin/edit/views.py:329 msgid "You are editing another user's collection. Proceed with caution." msgstr "다른 ìœ ì €ì˜ ëª¨ìŒì§‘ì„ ìˆ˜ì • 중 입니다. 주ì˜í•˜ì„¸ìš”." -#: mediagoblin/gmg_commands/theme.py:58 +#: mediagoblin/edit/views.py:348 +msgid "Wrong password" +msgstr "ìž˜ëª»ëœ ë¹„ë°€ë²ˆí˜¸" + +#: mediagoblin/edit/views.py:363 +msgid "Your password was changed successfully" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:60 msgid "Cannot link theme... no theme set\n" msgstr "í…Œë§ˆì— ì—°ê²°í• ìˆ˜ 없습니다... 테마 ì…‹ì´ ì—†ìŠµë‹ˆë‹¤.\n" -#: mediagoblin/gmg_commands/theme.py:71 +#: mediagoblin/gmg_commands/assetlink.py:73 msgid "No asset directory for this theme\n" msgstr "ì´ í…Œë§ˆë¥¼ 위한 ì—ì…‹ ë””ë ‰í† ë¦¬ê°€ 없습니다.\n" -#: mediagoblin/gmg_commands/theme.py:74 +#: mediagoblin/gmg_commands/assetlink.py:76 msgid "However, old link directory symlink found; removed.\n" msgstr "그런ë°, ì˜¤ëž˜ëœ ë””ë ‰í† ë¦¬ ì‹¬ë³¼ë¦ ë§í¬ë¥¼ 찾았습니다; 지워졌습니다.\n" +#: mediagoblin/gmg_commands/assetlink.py:112 +#, python-format +msgid "Could not link \"%s\": %s exists and is not a symlink\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:119 +#, python-format +msgid "Skipping \"%s\"; already set up.\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:124 +#, python-format +msgid "Old link found for \"%s\"; removing.\n" +msgstr "" + #: mediagoblin/meddleware/csrf.py:134 msgid "" "CSRF cookie not present. This is most likely the result of a cookie blocker " @@ -273,12 +297,16 @@ msgid "" "domain." msgstr "" -#: mediagoblin/media_types/__init__.py:61 -#: mediagoblin/media_types/__init__.py:102 +#: mediagoblin/media_types/__init__.py:111 +#: mediagoblin/media_types/__init__.py:155 msgid "Sorry, I don't support that file type :(" msgstr "죄송합니다. 해당 íƒ€ìž…ì˜ íŒŒì¼ì€ ì§€ì›í•˜ì§€ 않아요 :(" -#: mediagoblin/media_types/video/processing.py:36 +#: mediagoblin/media_types/pdf/processing.py:136 +msgid "unoconv failing to run, check log file" +msgstr "" + +#: mediagoblin/media_types/video/processing.py:37 msgid "Video transcoding failed" msgstr "비디오 ë³€í™˜ì— ì‹¤íŒ¨ 했습니다." @@ -345,7 +373,7 @@ msgstr "" msgid "This field is required for public clients" msgstr "ì´ í•ëª©ì€ ê³µê°œ 사용ìžë“¤ì„ 위해 ê¼ í•„ìš” 합니다." -#: mediagoblin/plugins/oauth/views.py:59 +#: mediagoblin/plugins/oauth/views.py:56 msgid "The client {0} has been registered!" msgstr "ì‚¬ìš©ìž {0}ë‹˜ì´ ë“±ë¡ ë˜ì—ˆìŠµë‹ˆë‹¤!" @@ -364,7 +392,7 @@ msgstr "" msgid "Add" msgstr "추가" -#: mediagoblin/processing/__init__.py:172 +#: mediagoblin/processing/__init__.py:193 msgid "Invalid file given for media type." msgstr "알수없는 미디어 íŒŒì¼ ìž…ë‹ˆë‹¤." @@ -372,45 +400,45 @@ msgstr "알수없는 미디어 íŒŒì¼ ìž…ë‹ˆë‹¤." msgid "File" msgstr "파ì¼" -#: mediagoblin/submit/views.py:51 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "파ì¼ì„ 등ë¡í•˜ì…”야 합니다." -#: mediagoblin/submit/views.py:97 +#: mediagoblin/submit/views.py:93 msgid "Woohoo! Submitted!" msgstr "ì´í–!! 등ë¡í–ˆìŠµë‹ˆë‹¤!" -#: mediagoblin/submit/views.py:146 +#: mediagoblin/submit/views.py:144 #, python-format msgid "Collection \"%s\" added!" msgstr "\"%s\" 모ìŒì§‘ì´ ì¶”ê°€ë˜ì—ˆìŠµë‹ˆë‹¤!" -#: mediagoblin/templates/mediagoblin/base.html:64 +#: mediagoblin/templates/mediagoblin/base.html:67 msgid "Verify your email!" msgstr "ë©”ì¼ì„ 확ì¸í•˜ì„¸ìš”!" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:68 msgid "log out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:70 +#: mediagoblin/templates/mediagoblin/base.html:73 #: mediagoblin/templates/mediagoblin/auth/login.html:28 #: mediagoblin/templates/mediagoblin/auth/login.html:36 #: mediagoblin/templates/mediagoblin/auth/login.html:54 msgid "Log in" msgstr "로그ì¸" -#: mediagoblin/templates/mediagoblin/base.html:79 +#: mediagoblin/templates/mediagoblin/base.html:82 #, python-format msgid "<a href=\"%(user_url)s\">%(user_name)s</a>'s account" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:86 +#: mediagoblin/templates/mediagoblin/base.html:89 msgid "Change account settings" msgstr "ê³„ì • ì„¤ì • 변경" -#: mediagoblin/templates/mediagoblin/base.html:90 -#: mediagoblin/templates/mediagoblin/base.html:105 +#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:108 #: mediagoblin/templates/mediagoblin/admin/panel.html:21 #: mediagoblin/templates/mediagoblin/admin/panel.html:26 #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:21 @@ -418,72 +446,25 @@ msgstr "ê³„ì • ì„¤ì • 변경" msgid "Media processing panel" msgstr "미디어 작업 패ë„" -#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:96 msgid "Log out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:96 +#: mediagoblin/templates/mediagoblin/base.html:99 #: mediagoblin/templates/mediagoblin/user_pages/user.html:156 msgid "Add media" msgstr "미디어 추가" -#: mediagoblin/templates/mediagoblin/base.html:99 +#: mediagoblin/templates/mediagoblin/base.html:102 #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:41 msgid "Create new collection" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:122 -#, python-format -msgid "" -"Powered by <a href=\"http://mediagoblin.org/\" title='Version " -"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." -msgstr "" - -#: mediagoblin/templates/mediagoblin/base.html:125 -#, 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 "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." - #: mediagoblin/templates/mediagoblin/error.html:24 msgid "Image of goblin stressing out" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:31 -msgid "Explore" -msgstr "íƒìƒ‰" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "안녕하세요! 미디어 ê³ ë¸”ë¦° 사ì´íŠ¸ì— ì˜¨ê±¸ í™˜ì˜ í•©ë‹ˆë‹¤!" - -#: mediagoblin/templates/mediagoblin/root.html:35 -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>으로 ìž‘ë™ ì¤‘ìž…ë‹ˆë‹¤. ì´ëŠ” 특ì´í•œ 미디어 호스팅 소프트웨어중 하나 입니다." - -#: mediagoblin/templates/mediagoblin/root.html:36 -msgid "" -"To add your own media, place comments, and more, you can log in with your " -"MediaGoblin account." -msgstr "ìžì‹ ì˜ ë¯¸ë””ì–´ë¥¼ ì¶”ê°€í•˜ê³ , ëŒ“ê¸€ì„ ë‚¨ê¸°ì„¸ìš”! 미디어 ê³ ë¸”ë¦° ê³„ì •ìœ¼ë¡œ ë‚´ì—ì„ í™•ì¸ í•˜ì‹¤ 수 있습니다!" - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Don't have one yet? It's easy!" -msgstr "ì•„ì§ ì•„ë¬´ê²ƒë„ ì—†ìœ¼ì‹œë‹¤êµ¬ìš”? 매우 쉽습니다!" - -#: mediagoblin/templates/mediagoblin/root.html:39 -#, 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\">ì‚¬ìš©ìž ê³„ì • 만들기</a>\n ë˜ëŠ”\n <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">서버를 위한 MediaGoblin ì„¤ì •í•˜ê¸°</a>" - -#: mediagoblin/templates/mediagoblin/root.html:47 +#: mediagoblin/templates/mediagoblin/root.html:32 msgid "Most recent media" msgstr "가장 ìµœê·¼ì— ë“±ë¡ëœ 미디어" @@ -589,6 +570,53 @@ msgid "" "%(verification_url)s" msgstr "안녕하세요 %(username)s님,\n\nGNU MediaGoblin ê³„ì •ì„ í™œì„±í™” í•˜ì‹œë ¤ë©´, ì•„ëž˜ì˜ URL 주소를 브ë¼ìš°ì ¸ë¡œ ì ‘ì†í•˜ì„¸ìš”.\n\n%(verification_url)s" +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:21 +#, python-format +msgid "" +"Powered by <a href=\"http://mediagoblin.org/\" title='Version " +"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:24 +#, 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 "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." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:20 +msgid "Explore" +msgstr "íƒìƒ‰" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:22 +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "안녕하세요! 미디어 ê³ ë¸”ë¦° 사ì´íŠ¸ì— ì˜¨ê±¸ í™˜ì˜ í•©ë‹ˆë‹¤!" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:24 +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>으로 ìž‘ë™ ì¤‘ìž…ë‹ˆë‹¤. ì´ëŠ” 특ì´í•œ 미디어 호스팅 소프트웨어중 하나 입니다." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:25 +msgid "" +"To add your own media, place comments, and more, you can log in with your " +"MediaGoblin account." +msgstr "ìžì‹ ì˜ ë¯¸ë””ì–´ë¥¼ ì¶”ê°€í•˜ê³ , ëŒ“ê¸€ì„ ë‚¨ê¸°ì„¸ìš”! 미디어 ê³ ë¸”ë¦° ê³„ì •ìœ¼ë¡œ ë‚´ì—ì„ í™•ì¸ í•˜ì‹¤ 수 있습니다!" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:27 +msgid "Don't have one yet? It's easy!" +msgstr "ì•„ì§ ì•„ë¬´ê²ƒë„ ì—†ìœ¼ì‹œë‹¤êµ¬ìš”? 매우 쉽습니다!" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:28 +#, python-format +msgid "" +"<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/bits/logo.html:23 #: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 msgid "MediaGoblin logo" @@ -601,13 +629,13 @@ msgid "Editing attachments for %(media_title)s" msgstr "%(media_title)sì˜ ì²¨ë¶€ ìˆ˜ì • 중..." #: mediagoblin/templates/mediagoblin/edit/attachments.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:159 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:175 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:182 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:198 msgid "Attachments" msgstr "첨부" #: mediagoblin/templates/mediagoblin/edit/attachments.html:57 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:181 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:204 msgid "Add attachment" msgstr "첨부 추가" @@ -624,12 +652,22 @@ msgstr "취소" #: mediagoblin/templates/mediagoblin/edit/attachments.html:63 #: mediagoblin/templates/mediagoblin/edit/edit.html:42 -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:52 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:55 #: mediagoblin/templates/mediagoblin/edit/edit_collection.html:33 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:40 msgid "Save changes" msgstr "ì €ìž¥" +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:28 +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 +#, python-format +msgid "Changing %(username)s's password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 +msgid "Save" +msgstr "" + #: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 #, python-format msgid "Really delete user '%(user_name)s' and all related media/comments?" @@ -640,7 +678,7 @@ msgid "Yes, really delete my account" msgstr "" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:48 #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49 msgid "Delete permanently" msgstr "ì˜êµ¬ì 으로 ì‚ì œ" @@ -657,7 +695,11 @@ msgstr "%(media_title)s 편집중..." msgid "Changing %(username)s's account settings" msgstr "%(username)s'ì˜ ê³„ì • ì„¤ì • 변경중..." -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:59 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 +msgid "Change your password." +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 msgid "Delete my account" msgstr "" @@ -682,6 +724,7 @@ msgstr "미디어는 다ìŒìœ¼ë¡œ 태그 ë˜ì—ˆìŠµë‹ˆë‹¤.: %(tag_name)s" #: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 #: mediagoblin/templates/mediagoblin/media_displays/audio.html:56 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:65 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:136 #: mediagoblin/templates/mediagoblin/media_displays/video.html:55 msgid "Download" @@ -706,6 +749,7 @@ msgid "" msgstr "사운드 파ì¼ì„ ìž¬ìƒ í•˜ì‹œë ¤ë©´\n\tì´ê³³ì—서 ìµœì‹ ì˜ ë¸Œë¼ìš°ì ¸ë¥¼ 다운받으세요! <a href=\"http://getfirefox.com\">\n\t http://getfirefox.com</a>!" #: mediagoblin/templates/mediagoblin/media_displays/audio.html:60 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:71 #: mediagoblin/templates/mediagoblin/media_displays/video.html:61 msgid "Original file" msgstr "ì›ë³¸ 파ì¼" @@ -714,6 +758,7 @@ msgstr "ì›ë³¸ 파ì¼" msgid "WebM file (Vorbis codec)" msgstr "WebM íŒŒì¼ (Vorbis ì½”ë±)" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:59 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:87 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:93 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:99 @@ -724,6 +769,10 @@ msgstr "WebM íŒŒì¼ (Vorbis ì½”ë±)" msgid "Image for %(media_title)s" msgstr "%(media_title)s ì´ë¯¸ì§€" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 +msgid "PDF file" +msgstr "" + #: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 msgid "Toggle Rotate" msgstr "" @@ -822,7 +871,7 @@ msgstr "%(title)s ì„ ì§€ìš°ì‹œê² ìŠµë‹ˆê¹Œ?" msgid "Really remove %(media_title)s from %(collection_title)s?" msgstr "%(collection_title)sì˜ %(media_title)sì„ ì‚ì œ í•˜ì‹œê² ìŠµë‹ˆê¹Œ?" -#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:54 msgid "Remove" msgstr "지우기" @@ -865,24 +914,28 @@ msgstr "<a href=\"%(user_url)s\">%(username)s</a>ì˜ ë¯¸ë””ì–´" 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:94 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:95 msgid "Add a comment" msgstr "ë§ê¸€ 달기" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 msgid "Add this comment" msgstr "ë§ê¸€ 추가" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:123 -msgid "at" -msgstr "ì—" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:144 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:132 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:152 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:164 #, python-format -msgid "" -"<h3>Added on</h3>\n" -" <p>%(date)s</p>" -msgstr "<h3>부가 기능</h3>\n <p>%(date)s</p>" +msgid "%(formatted_time)s ago" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:150 +msgid "Added" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:161 +msgid "Created" +msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:40 @@ -1038,7 +1091,7 @@ msgstr "ì´ì „" msgid "Tagged with" msgstr "태그 ì •ë³´" -#: mediagoblin/tools/exif.py:80 +#: mediagoblin/tools/exif.py:83 msgid "Could not read the image file." msgstr "ì´ë¯¸ì§€ 파ì¼ì„ ì½ì„ 수 없습니다." @@ -1068,6 +1121,30 @@ msgid "" " deleted." msgstr "" +#: mediagoblin/tools/timesince.py:62 +msgid "year" +msgstr "" + +#: mediagoblin/tools/timesince.py:63 +msgid "month" +msgstr "" + +#: mediagoblin/tools/timesince.py:64 +msgid "week" +msgstr "" + +#: mediagoblin/tools/timesince.py:65 +msgid "day" +msgstr "" + +#: mediagoblin/tools/timesince.py:66 +msgid "hour" +msgstr "" + +#: mediagoblin/tools/timesince.py:67 +msgid "minute" +msgstr "" + #: mediagoblin/user_pages/forms.py:23 msgid "Comment" msgstr "" @@ -1099,73 +1176,77 @@ msgstr "-- ì„ íƒ --" msgid "Include a note" msgstr "노트 추가" -#: mediagoblin/user_pages/lib.py:56 +#: mediagoblin/user_pages/lib.py:58 msgid "commented on your post" msgstr "ê²Œì‹œë¬¼ì— ë§ê¸€ì´ ë‹¬ë ¸ìŠµë‹ˆë‹¤." -#: mediagoblin/user_pages/views.py:166 +#: mediagoblin/user_pages/views.py:169 +msgid "Sorry, comments are disabled." +msgstr "" + +#: mediagoblin/user_pages/views.py:174 msgid "Oops, your comment was empty." msgstr "오우, ëŒ“ê¸€ì´ ë¹„ì—ˆìŠµë‹ˆë‹¤." -#: mediagoblin/user_pages/views.py:172 +#: mediagoblin/user_pages/views.py:180 msgid "Your comment has been posted!" msgstr "ëŒ“ê¸€ì´ ë“±ë¡ ë˜ì—ˆìŠµë‹ˆë‹¤!" -#: mediagoblin/user_pages/views.py:197 +#: mediagoblin/user_pages/views.py:205 msgid "Please check your entries and try again." msgstr "확ì¸ì„ í•˜ì‹œê³ ë‹¤ì‹œ 시ë„하세요." -#: mediagoblin/user_pages/views.py:237 +#: mediagoblin/user_pages/views.py:245 msgid "You have to select or add a collection" msgstr "모ìŒì§‘ì„ ì¶”ê°€í•˜ê±°ë‚˜ 기존 모ìŒì§‘ì„ ì„ íƒí•˜ì„¸ìš”." -#: mediagoblin/user_pages/views.py:248 +#: mediagoblin/user_pages/views.py:256 #, python-format msgid "\"%s\" already in collection \"%s\"" msgstr "\"%s\" 모ìŒì§‘ì´ ì´ë¯¸ 존재 합니다. \"%s\"" -#: mediagoblin/user_pages/views.py:264 +#: mediagoblin/user_pages/views.py:262 #, python-format msgid "\"%s\" added to collection \"%s\"" msgstr "\"%s\" 모ìŒì§‘ì„ ì¶”ê°€í–ˆìŠµë‹ˆë‹¤. \"%s\"" -#: mediagoblin/user_pages/views.py:286 +#: mediagoblin/user_pages/views.py:282 msgid "You deleted the media." msgstr "미디어를 ì‚ì œ 했습니다." -#: mediagoblin/user_pages/views.py:293 +#: mediagoblin/user_pages/views.py:289 msgid "The media was not deleted because you didn't check that you were sure." msgstr "í™•ì¸ ì²´í¬ë¥¼ 하지 않았습니다. 미디어는 ì‚ì œë˜ì§€ 않았습니다." -#: mediagoblin/user_pages/views.py:301 +#: mediagoblin/user_pages/views.py:296 msgid "You are about to delete another user's media. Proceed with caution." msgstr "다른 ì‚¬ëžŒì˜ ë¯¸ë””ì–´ë¥¼ ì‚ì œí•˜ë ¤ê³ í•©ë‹ˆë‹¤. 다시 한번 확ì¸í•˜ì„¸ìš”." -#: mediagoblin/user_pages/views.py:375 +#: mediagoblin/user_pages/views.py:370 msgid "You deleted the item from the collection." msgstr "모ìŒì§‘ì— ìžˆëŠ” í•ëª©ì„ ì‚ì œ 했습니다." -#: mediagoblin/user_pages/views.py:379 +#: mediagoblin/user_pages/views.py:374 msgid "The item was not removed because you didn't check that you were sure." msgstr "확ì¸ì„ 하지 않았습니다. í•ëª©ì€ ì‚ì œí•˜ì§€ 않았습니다." -#: mediagoblin/user_pages/views.py:389 +#: mediagoblin/user_pages/views.py:382 msgid "" "You are about to delete an item from another user's collection. Proceed with" " caution." msgstr "다른 사용ìžì˜ 모ìŒì§‘ì— ìžˆëŠ” í•ëª©ì„ ì‚ì œí•˜ì˜€ìŠµë‹ˆë‹¤. 주ì˜í•˜ì„¸ìš”." -#: mediagoblin/user_pages/views.py:422 +#: mediagoblin/user_pages/views.py:415 #, python-format msgid "You deleted the collection \"%s\"" msgstr "\"%s\" 모ìŒì§‘ì„ ì‚ì œí•˜ì…¨ìŠµë‹ˆë‹¤." -#: mediagoblin/user_pages/views.py:429 +#: mediagoblin/user_pages/views.py:422 msgid "" "The collection was not deleted because you didn't check that you were sure." msgstr "확ì¸ì„ 하지 않았습니다. 모ìŒì§‘ì€ ì‚ì œí•˜ì§€ 않았습니다." -#: mediagoblin/user_pages/views.py:439 +#: mediagoblin/user_pages/views.py:430 msgid "" "You are about to delete another user's collection. Proceed with caution." msgstr "다른 사용ìžì˜ 모ìŒì§‘ì„ ì‚ì œí•˜ë ¤ê³ í•©ë‹ˆë‹¤. 주ì˜í•˜ì„¸ìš”." diff --git a/mediagoblin/i18n/nl/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/nl/LC_MESSAGES/mediagoblin.mo Binary files differindex fe96d40e..4e6e51ce 100644 --- a/mediagoblin/i18n/nl/LC_MESSAGES/mediagoblin.mo +++ b/mediagoblin/i18n/nl/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/nl/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/nl/LC_MESSAGES/mediagoblin.po index 3fd26d23..14e4fb33 100644 --- a/mediagoblin/i18n/nl/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/nl/LC_MESSAGES/mediagoblin.po @@ -3,16 +3,16 @@ # This file is distributed under the same license as the PROJECT project. # # Translators: -# <mail@jefvanschendel.nl>, 2011, 2012. -# <mvanderboom@gmail.com>, 2012. +# schendje <mail@jefvanschendel.nl>, 2011, 2012 +# mvanderboom <mvanderboom@gmail.com>, 2012 msgid "" msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" -"POT-Creation-Date: 2013-03-04 18:04-0600\n" -"PO-Revision-Date: 2013-03-05 00:04+0000\n" +"POT-Creation-Date: 2013-05-27 13:54-0500\n" +"PO-Revision-Date: 2013-05-27 18:54+0000\n" "Last-Translator: cwebber <cwebber@dustycloud.org>\n" -"Language-Team: LANGUAGE <LL@li.org>\n" +"Language-Team: Dutch (http://www.transifex.com/projects/p/mediagoblin/language/nl/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -20,34 +20,39 @@ msgstr "" "Language: nl\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: mediagoblin/auth/forms.py:28 -msgid "Invalid User name or email address." -msgstr "" - -#: mediagoblin/auth/forms.py:29 -msgid "This field does not take email addresses." -msgstr "" - -#: mediagoblin/auth/forms.py:30 -msgid "This field requires an email address." -msgstr "" - -#: mediagoblin/auth/forms.py:52 mediagoblin/auth/forms.py:67 +#: mediagoblin/auth/forms.py:26 msgid "Username" msgstr "Gebruikersnaam" -#: mediagoblin/auth/forms.py:56 mediagoblin/auth/forms.py:71 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 +#: mediagoblin/tests/test_util.py:110 msgid "Password" msgstr "Wachtwoord" -#: mediagoblin/auth/forms.py:60 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "E-mail adres" -#: mediagoblin/auth/forms.py:78 +#: mediagoblin/auth/forms.py:41 +msgid "Username or Email" +msgstr "" + +#: mediagoblin/auth/forms.py:52 msgid "Username or email" msgstr "Gebruikersnaam of email-adres" +#: mediagoblin/auth/tools.py:31 +msgid "Invalid User name or email address." +msgstr "" + +#: mediagoblin/auth/tools.py:32 +msgid "This field does not take email addresses." +msgstr "" + +#: mediagoblin/auth/tools.py:33 +msgid "This field requires an email address." +msgstr "" + #: mediagoblin/auth/views.py:54 msgid "Sorry, registration is disabled on this instance." msgstr "Sorry, registratie is uitgeschakeld op deze instantie." @@ -60,54 +65,54 @@ msgstr "Sorry, er bestaat al een gebruiker met die naam." msgid "Sorry, a user with that email address already exists." msgstr "Sorry, een gebruiker met dat e-mailadres bestaat al." -#: mediagoblin/auth/views.py:174 +#: 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!" -#: mediagoblin/auth/views.py:180 +#: 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:198 +#: 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!" -#: mediagoblin/auth/views.py:206 +#: 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:219 +#: mediagoblin/auth/views.py:227 msgid "Resent your verification email." msgstr "Verificatie e-mail opnieuw opgestuurd." -#: mediagoblin/auth/views.py:250 +#: mediagoblin/auth/views.py:258 msgid "" "If that email address (case sensitive!) is registered an email has been sent" " with instructions on how to change your password." msgstr "" -#: mediagoblin/auth/views.py:261 +#: mediagoblin/auth/views.py:269 msgid "Couldn't find someone with that username." msgstr "" -#: mediagoblin/auth/views.py:264 +#: mediagoblin/auth/views.py:272 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." -#: mediagoblin/auth/views.py:271 +#: mediagoblin/auth/views.py:279 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." msgstr "Email kon niet verstuurd worden omdat je gebruikersnaam inactief is of omdat je e-mailadres nog niet geverifieerd is." -#: mediagoblin/auth/views.py:328 +#: mediagoblin/auth/views.py:336 msgid "You can now log in using your new password." msgstr "Je kunt nu inloggen met je nieuwe wachtwoord." -#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:93 +#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:82 #: mediagoblin/submit/forms.py:28 mediagoblin/submit/forms.py:47 #: mediagoblin/user_pages/forms.py:45 msgid "Title" @@ -118,7 +123,7 @@ msgid "Description of this work" msgstr "Beschrijving van dit werk" #: mediagoblin/edit/forms.py:29 mediagoblin/edit/forms.py:52 -#: mediagoblin/edit/forms.py:97 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:86 mediagoblin/submit/forms.py:32 #: mediagoblin/submit/forms.py:51 mediagoblin/user_pages/forms.py:49 msgid "" "You can use\n" @@ -134,11 +139,11 @@ msgstr "Etiket" msgid "Separate tags by commas." msgstr "Hou labels gescheiden met komma's." -#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:101 +#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:90 msgid "Slug" msgstr "Slug" -#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:102 +#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:91 msgid "The slug can't be empty" msgstr "De slug kan niet leeg zijn" @@ -166,45 +171,45 @@ msgid "This address contains errors" msgstr "Dit adres bevat fouten" #: mediagoblin/edit/forms.py:63 -msgid "Old password" -msgstr "Oud wachtwoord" - -#: mediagoblin/edit/forms.py:64 -msgid "Enter your old password to prove you own this account." -msgstr "Vul je oude wachtwoord in om te bewijzen dat dit jouw account is" - -#: mediagoblin/edit/forms.py:67 -msgid "New password" -msgstr "Nieuw wachtwoord" - -#: mediagoblin/edit/forms.py:74 msgid "License preference" msgstr "" -#: mediagoblin/edit/forms.py:80 +#: mediagoblin/edit/forms.py:69 msgid "This will be your default license on upload forms." msgstr "" -#: mediagoblin/edit/forms.py:82 +#: mediagoblin/edit/forms.py:71 msgid "Email me when others comment on my media" msgstr "" -#: mediagoblin/edit/forms.py:94 +#: mediagoblin/edit/forms.py:83 msgid "The title can't be empty" msgstr "" -#: mediagoblin/edit/forms.py:96 mediagoblin/submit/forms.py:50 +#: mediagoblin/edit/forms.py:85 mediagoblin/submit/forms.py:50 #: mediagoblin/user_pages/forms.py:48 msgid "Description of this collection" msgstr "" -#: mediagoblin/edit/forms.py:103 +#: mediagoblin/edit/forms.py:92 msgid "" "The title part of this collection's address. You usually don't need to " "change this." msgstr "" -#: mediagoblin/edit/views.py:66 +#: mediagoblin/edit/forms.py:99 +msgid "Old password" +msgstr "Oud wachtwoord" + +#: mediagoblin/edit/forms.py:101 +msgid "Enter your old password to prove you own this account." +msgstr "Vul je oude wachtwoord in om te bewijzen dat dit jouw account is" + +#: mediagoblin/edit/forms.py:104 +msgid "New password" +msgstr "Nieuw wachtwoord" + +#: 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." @@ -229,44 +234,63 @@ msgstr "U bent een gebruikersprofiel aan het aanpassen. Ga voorzichtig te werk." msgid "Profile changes saved" msgstr "Profielaanpassingen opgeslagen" -#: mediagoblin/edit/views.py:241 -msgid "Wrong password" -msgstr "Verkeerd wachtwoord" - -#: mediagoblin/edit/views.py:252 +#: mediagoblin/edit/views.py:240 msgid "Account settings saved" msgstr "Accountinstellingen opgeslagen" -#: mediagoblin/edit/views.py:286 +#: mediagoblin/edit/views.py:274 msgid "You need to confirm the deletion of your account." msgstr "" -#: mediagoblin/edit/views.py:322 mediagoblin/submit/views.py:142 -#: mediagoblin/user_pages/views.py:214 +#: mediagoblin/edit/views.py:310 mediagoblin/submit/views.py:138 +#: mediagoblin/user_pages/views.py:222 #, python-format msgid "You already have a collection called \"%s\"!" msgstr "" -#: mediagoblin/edit/views.py:326 +#: mediagoblin/edit/views.py:314 msgid "A collection with that slug already exists for this user." msgstr "" -#: mediagoblin/edit/views.py:343 +#: mediagoblin/edit/views.py:329 msgid "You are editing another user's collection. Proceed with caution." msgstr "" -#: mediagoblin/gmg_commands/theme.py:58 +#: mediagoblin/edit/views.py:348 +msgid "Wrong password" +msgstr "Verkeerd wachtwoord" + +#: mediagoblin/edit/views.py:363 +msgid "Your password was changed successfully" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:60 msgid "Cannot link theme... no theme set\n" msgstr "" -#: mediagoblin/gmg_commands/theme.py:71 +#: mediagoblin/gmg_commands/assetlink.py:73 msgid "No asset directory for this theme\n" msgstr "" -#: mediagoblin/gmg_commands/theme.py:74 +#: mediagoblin/gmg_commands/assetlink.py:76 msgid "However, old link directory symlink found; removed.\n" msgstr "" +#: mediagoblin/gmg_commands/assetlink.py:112 +#, python-format +msgid "Could not link \"%s\": %s exists and is not a symlink\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:119 +#, python-format +msgid "Skipping \"%s\"; already set up.\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:124 +#, python-format +msgid "Old link found for \"%s\"; removing.\n" +msgstr "" + #: mediagoblin/meddleware/csrf.py:134 msgid "" "CSRF cookie not present. This is most likely the result of a cookie blocker " @@ -274,12 +298,16 @@ msgid "" "domain." msgstr "" -#: mediagoblin/media_types/__init__.py:61 -#: mediagoblin/media_types/__init__.py:102 +#: mediagoblin/media_types/__init__.py:111 +#: mediagoblin/media_types/__init__.py:155 msgid "Sorry, I don't support that file type :(" msgstr "Sorry, dat bestandstype wordt niet ondersteunt." -#: mediagoblin/media_types/video/processing.py:36 +#: mediagoblin/media_types/pdf/processing.py:136 +msgid "unoconv failing to run, check log file" +msgstr "" + +#: mediagoblin/media_types/video/processing.py:37 msgid "Video transcoding failed" msgstr "" @@ -346,7 +374,7 @@ msgstr "" msgid "This field is required for public clients" msgstr "" -#: mediagoblin/plugins/oauth/views.py:59 +#: mediagoblin/plugins/oauth/views.py:56 msgid "The client {0} has been registered!" msgstr "" @@ -365,7 +393,7 @@ msgstr "" msgid "Add" msgstr "Voeg toe" -#: mediagoblin/processing/__init__.py:172 +#: mediagoblin/processing/__init__.py:193 msgid "Invalid file given for media type." msgstr "Verkeerd bestandsformaat voor mediatype opgegeven." @@ -373,45 +401,45 @@ msgstr "Verkeerd bestandsformaat voor mediatype opgegeven." msgid "File" msgstr "Bestand" -#: mediagoblin/submit/views.py:51 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "U moet een bestand aangeven." -#: mediagoblin/submit/views.py:97 +#: mediagoblin/submit/views.py:93 msgid "Woohoo! Submitted!" msgstr "Mooizo! Toegevoegd!" -#: mediagoblin/submit/views.py:146 +#: mediagoblin/submit/views.py:144 #, python-format msgid "Collection \"%s\" added!" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:64 +#: mediagoblin/templates/mediagoblin/base.html:67 msgid "Verify your email!" msgstr "Verifieer je e-mailadres!" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:68 msgid "log out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:70 +#: mediagoblin/templates/mediagoblin/base.html:73 #: mediagoblin/templates/mediagoblin/auth/login.html:28 #: mediagoblin/templates/mediagoblin/auth/login.html:36 #: mediagoblin/templates/mediagoblin/auth/login.html:54 msgid "Log in" msgstr "Inloggen" -#: mediagoblin/templates/mediagoblin/base.html:79 +#: mediagoblin/templates/mediagoblin/base.html:82 #, python-format msgid "<a href=\"%(user_url)s\">%(user_name)s</a>'s account" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:86 +#: mediagoblin/templates/mediagoblin/base.html:89 msgid "Change account settings" msgstr "Accountinstellingen aanpassen" -#: mediagoblin/templates/mediagoblin/base.html:90 -#: mediagoblin/templates/mediagoblin/base.html:105 +#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:108 #: mediagoblin/templates/mediagoblin/admin/panel.html:21 #: mediagoblin/templates/mediagoblin/admin/panel.html:26 #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:21 @@ -419,72 +447,25 @@ msgstr "Accountinstellingen aanpassen" msgid "Media processing panel" msgstr "Mediaverwerkingspaneel" -#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:96 msgid "Log out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:96 +#: mediagoblin/templates/mediagoblin/base.html:99 #: mediagoblin/templates/mediagoblin/user_pages/user.html:156 msgid "Add media" msgstr "Voeg media toe" -#: mediagoblin/templates/mediagoblin/base.html:99 +#: mediagoblin/templates/mediagoblin/base.html:102 #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:41 msgid "Create new collection" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:122 -#, python-format -msgid "" -"Powered by <a href=\"http://mediagoblin.org/\" title='Version " -"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." -msgstr "" - -#: mediagoblin/templates/mediagoblin/base.html:125 -#, 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/error.html:24 msgid "Image of goblin stressing out" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:31 -msgid "Explore" -msgstr "Verkennen" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "Hoi, welkom op deze MediaGoblin website!" - -#: mediagoblin/templates/mediagoblin/root.html:35 -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." - -#: mediagoblin/templates/mediagoblin/root.html:36 -msgid "" -"To add your own media, place comments, and more, you can log in with your " -"MediaGoblin account." -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Don't have one yet? It's easy!" -msgstr "Heb je er nog geen? Het is heel eenvoudig!" - -#: mediagoblin/templates/mediagoblin/root.html:39 -#, 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\">Creëer een account op deze website</a>\n of\n <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">Gebruik MediaGoblin op je eigen server</a>" - -#: mediagoblin/templates/mediagoblin/root.html:47 +#: mediagoblin/templates/mediagoblin/root.html:32 msgid "Most recent media" msgstr "Nieuwste media" @@ -590,6 +571,53 @@ msgid "" "%(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/bits/base_footer.html:21 +#, python-format +msgid "" +"Powered by <a href=\"http://mediagoblin.org/\" title='Version " +"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:24 +#, 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/bits/frontpage_welcome.html:20 +msgid "Explore" +msgstr "Verkennen" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:22 +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "Hoi, welkom op deze MediaGoblin website!" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:24 +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." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:25 +msgid "" +"To add your own media, place comments, and more, you can log in with your " +"MediaGoblin account." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:27 +msgid "Don't have one yet? It's easy!" +msgstr "Heb je er nog geen? Het is heel eenvoudig!" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:28 +#, 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/bits/logo.html:23 #: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 msgid "MediaGoblin logo" @@ -602,13 +630,13 @@ msgid "Editing attachments for %(media_title)s" msgstr "" #: mediagoblin/templates/mediagoblin/edit/attachments.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:159 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:175 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:182 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:198 msgid "Attachments" msgstr "" #: mediagoblin/templates/mediagoblin/edit/attachments.html:57 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:181 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:204 msgid "Add attachment" msgstr "" @@ -625,12 +653,22 @@ msgstr "Annuleren" #: mediagoblin/templates/mediagoblin/edit/attachments.html:63 #: mediagoblin/templates/mediagoblin/edit/edit.html:42 -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:52 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:55 #: mediagoblin/templates/mediagoblin/edit/edit_collection.html:33 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:40 msgid "Save changes" msgstr "Wijzigingen opslaan" +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:28 +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 +#, python-format +msgid "Changing %(username)s's password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 +msgid "Save" +msgstr "" + #: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 #, python-format msgid "Really delete user '%(user_name)s' and all related media/comments?" @@ -641,7 +679,7 @@ msgid "Yes, really delete my account" msgstr "" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:48 #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49 msgid "Delete permanently" msgstr "Permanent verwijderen" @@ -658,7 +696,11 @@ msgstr "%(media_title)s aanpassen" msgid "Changing %(username)s's account settings" msgstr "%(username)ss accountinstellingen aanpassen" -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:59 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 +msgid "Change your password." +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 msgid "Delete my account" msgstr "" @@ -683,6 +725,7 @@ msgstr "Media met het label: %(tag_name)s" #: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 #: mediagoblin/templates/mediagoblin/media_displays/audio.html:56 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:65 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:136 #: mediagoblin/templates/mediagoblin/media_displays/video.html:55 msgid "Download" @@ -707,6 +750,7 @@ msgid "" 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/audio.html:60 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:71 #: mediagoblin/templates/mediagoblin/media_displays/video.html:61 msgid "Original file" msgstr "" @@ -715,6 +759,7 @@ msgstr "" msgid "WebM file (Vorbis codec)" msgstr "" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:59 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:87 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:93 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:99 @@ -725,6 +770,10 @@ msgstr "" msgid "Image for %(media_title)s" msgstr "Afbeelding voor %(media_title)s" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 +msgid "PDF file" +msgstr "" + #: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 msgid "Toggle Rotate" msgstr "" @@ -823,7 +872,7 @@ msgstr "Zeker weten dat je %(title)s wil verwijderen?" msgid "Really remove %(media_title)s from %(collection_title)s?" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:54 msgid "Remove" msgstr "" @@ -866,24 +915,28 @@ msgstr "Media van <a href=\"%(user_url)s\"> %(username)s </a>" 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:94 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:95 msgid "Add a comment" msgstr "Geef een reactie" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 msgid "Add this comment" msgstr "Voeg dit bericht toe" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:123 -msgid "at" -msgstr "op" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:144 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:132 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:152 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:164 #, python-format -msgid "" -"<h3>Added on</h3>\n" -" <p>%(date)s</p>" -msgstr "<h3>Toegevoegd op</h3>\n <p>%(date)s</p>" +msgid "%(formatted_time)s ago" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:150 +msgid "Added" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:161 +msgid "Created" +msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:40 @@ -1039,7 +1092,7 @@ msgstr "ouder" msgid "Tagged with" msgstr "Getagged met" -#: mediagoblin/tools/exif.py:80 +#: mediagoblin/tools/exif.py:83 msgid "Could not read the image file." msgstr "Kon het afbeeldingsbestand niet lezen." @@ -1069,6 +1122,30 @@ msgid "" " deleted." msgstr "" +#: mediagoblin/tools/timesince.py:62 +msgid "year" +msgstr "" + +#: mediagoblin/tools/timesince.py:63 +msgid "month" +msgstr "" + +#: mediagoblin/tools/timesince.py:64 +msgid "week" +msgstr "" + +#: mediagoblin/tools/timesince.py:65 +msgid "day" +msgstr "" + +#: mediagoblin/tools/timesince.py:66 +msgid "hour" +msgstr "" + +#: mediagoblin/tools/timesince.py:67 +msgid "minute" +msgstr "" + #: mediagoblin/user_pages/forms.py:23 msgid "Comment" msgstr "" @@ -1100,73 +1177,77 @@ msgstr "" msgid "Include a note" msgstr "" -#: mediagoblin/user_pages/lib.py:56 +#: mediagoblin/user_pages/lib.py:58 msgid "commented on your post" msgstr "" -#: mediagoblin/user_pages/views.py:166 +#: mediagoblin/user_pages/views.py:169 +msgid "Sorry, comments are disabled." +msgstr "" + +#: mediagoblin/user_pages/views.py:174 msgid "Oops, your comment was empty." msgstr "Oeps, je bericht was leeg." -#: mediagoblin/user_pages/views.py:172 +#: mediagoblin/user_pages/views.py:180 msgid "Your comment has been posted!" msgstr "Je bericht is geplaatst!" -#: mediagoblin/user_pages/views.py:197 +#: mediagoblin/user_pages/views.py:205 msgid "Please check your entries and try again." msgstr "" -#: mediagoblin/user_pages/views.py:237 +#: mediagoblin/user_pages/views.py:245 msgid "You have to select or add a collection" msgstr "" -#: mediagoblin/user_pages/views.py:248 +#: mediagoblin/user_pages/views.py:256 #, python-format msgid "\"%s\" already in collection \"%s\"" msgstr "" -#: mediagoblin/user_pages/views.py:264 +#: mediagoblin/user_pages/views.py:262 #, python-format msgid "\"%s\" added to collection \"%s\"" msgstr "" -#: mediagoblin/user_pages/views.py:286 +#: mediagoblin/user_pages/views.py:282 msgid "You deleted the media." msgstr "Je hebt deze media verwijderd." -#: mediagoblin/user_pages/views.py:293 +#: mediagoblin/user_pages/views.py:289 msgid "The media was not deleted because you didn't check that you were sure." msgstr "Deze media was niet verwijderd omdat je niet hebt aangegeven dat je het zeker weet." -#: mediagoblin/user_pages/views.py:301 +#: mediagoblin/user_pages/views.py:296 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." -#: mediagoblin/user_pages/views.py:375 +#: mediagoblin/user_pages/views.py:370 msgid "You deleted the item from the collection." msgstr "" -#: mediagoblin/user_pages/views.py:379 +#: mediagoblin/user_pages/views.py:374 msgid "The item was not removed because you didn't check that you were sure." msgstr "" -#: mediagoblin/user_pages/views.py:389 +#: mediagoblin/user_pages/views.py:382 msgid "" "You are about to delete an item from another user's collection. Proceed with" " caution." msgstr "" -#: mediagoblin/user_pages/views.py:422 +#: mediagoblin/user_pages/views.py:415 #, python-format msgid "You deleted the collection \"%s\"" msgstr "" -#: mediagoblin/user_pages/views.py:429 +#: mediagoblin/user_pages/views.py:422 msgid "" "The collection was not deleted because you didn't check that you were sure." msgstr "" -#: mediagoblin/user_pages/views.py:439 +#: mediagoblin/user_pages/views.py:430 msgid "" "You are about to delete another user's collection. Proceed with caution." msgstr "" diff --git a/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.mo Binary files differindex f58e6a45..9cbd03b2 100644 --- a/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.mo +++ b/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.po index 12d34b55..6a11d5da 100644 --- a/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/nn_NO/LC_MESSAGES/mediagoblin.po @@ -3,14 +3,14 @@ # This file is distributed under the same license as the PROJECT project. # # Translators: -# <odin.omdal@gmail.com>, 2013. -# <odin.omdal@gmail.com>, 2011-2012. +# velmont <odin.omdal@gmail.com>, 2013 +# velmont <odin.omdal@gmail.com>, 2011-2012 msgid "" msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" -"POT-Creation-Date: 2013-03-04 18:04-0600\n" -"PO-Revision-Date: 2013-03-10 13:31+0000\n" +"POT-Creation-Date: 2013-05-27 13:54-0500\n" +"PO-Revision-Date: 2013-05-31 15:40+0000\n" "Last-Translator: velmont <odin.omdal@gmail.com>\n" "Language-Team: Norwegian Nynorsk (Norway) (http://www.transifex.com/projects/p/mediagoblin/language/nn_NO/)\n" "MIME-Version: 1.0\n" @@ -20,34 +20,39 @@ msgstr "" "Language: nn_NO\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: mediagoblin/auth/forms.py:28 -msgid "Invalid User name or email address." -msgstr "Ugyldig brukarnamn eller passord." - -#: mediagoblin/auth/forms.py:29 -msgid "This field does not take email addresses." -msgstr "Dette feltet tek ikkje epostadresser." - -#: mediagoblin/auth/forms.py:30 -msgid "This field requires an email address." -msgstr "Dette feltet krev ei epostadresse." - -#: mediagoblin/auth/forms.py:52 mediagoblin/auth/forms.py:67 +#: mediagoblin/auth/forms.py:26 msgid "Username" msgstr "Brukarnamn" -#: mediagoblin/auth/forms.py:56 mediagoblin/auth/forms.py:71 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 +#: mediagoblin/tests/test_util.py:110 msgid "Password" msgstr "Passord" -#: mediagoblin/auth/forms.py:60 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "Epost" -#: mediagoblin/auth/forms.py:78 +#: mediagoblin/auth/forms.py:41 +msgid "Username or Email" +msgstr "Brukarnamn eller epost" + +#: mediagoblin/auth/forms.py:52 msgid "Username or email" msgstr "Brukarnamn eller epost" +#: mediagoblin/auth/tools.py:31 +msgid "Invalid User name or email address." +msgstr "Ugyldig brukarnamn eller passord." + +#: mediagoblin/auth/tools.py:32 +msgid "This field does not take email addresses." +msgstr "Dette feltet tek ikkje epostadresser." + +#: mediagoblin/auth/tools.py:33 +msgid "This field requires an email address." +msgstr "Dette feltet krev ei epostadresse." + #: mediagoblin/auth/views.py:54 msgid "Sorry, registration is disabled on this instance." msgstr "Registrering er slege av. Orsak." @@ -60,54 +65,54 @@ msgstr "Ein konto med dette brukarnamnet finst allereide." msgid "Sorry, a user with that email address already exists." msgstr "Ein brukar med den epostadressa finst allereie." -#: mediagoblin/auth/views.py:174 +#: 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." -#: mediagoblin/auth/views.py:180 +#: 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:198 +#: mediagoblin/auth/views.py:206 msgid "You must be logged in so we know who to send the email to!" msgstr "Du mÃ¥ vera innlogga, slik me veit kven som skal ha eposten." -#: mediagoblin/auth/views.py:206 +#: mediagoblin/auth/views.py:214 msgid "You've already verified your email address!" msgstr "Du har allereie verifisiert epostadressa." -#: mediagoblin/auth/views.py:219 +#: mediagoblin/auth/views.py:227 msgid "Resent your verification email." msgstr "Send ein ny stadfestingsepost." -#: mediagoblin/auth/views.py:250 +#: mediagoblin/auth/views.py:258 msgid "" "If that email address (case sensitive!) is registered an email has been sent" " with instructions on how to change your password." msgstr "Dersom denne epostadressa er registrert, har ein epost med instruksjonar for Ã¥ endra passord vorte sendt til han." -#: mediagoblin/auth/views.py:261 +#: mediagoblin/auth/views.py:269 msgid "Couldn't find someone with that username." msgstr "Fann ingen med det brukarnamnet." -#: mediagoblin/auth/views.py:264 +#: mediagoblin/auth/views.py:272 msgid "" "An email has been sent with instructions on how to change your password." msgstr "Sender epost med instruksjonar for Ã¥ endra passordet ditt." -#: mediagoblin/auth/views.py:271 +#: mediagoblin/auth/views.py:279 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." msgstr "Kunne ikkje senda epost. Brukarnamnet ditt er inaktivt eller uverifisert." -#: mediagoblin/auth/views.py:328 +#: mediagoblin/auth/views.py:336 msgid "You can now log in using your new password." msgstr "Du kan no logga inn med det nye passordet ditt." -#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:93 +#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:82 #: mediagoblin/submit/forms.py:28 mediagoblin/submit/forms.py:47 #: mediagoblin/user_pages/forms.py:45 msgid "Title" @@ -118,7 +123,7 @@ msgid "Description of this work" msgstr "Skildring av verk" #: mediagoblin/edit/forms.py:29 mediagoblin/edit/forms.py:52 -#: mediagoblin/edit/forms.py:97 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:86 mediagoblin/submit/forms.py:32 #: mediagoblin/submit/forms.py:51 mediagoblin/user_pages/forms.py:49 msgid "" "You can use\n" @@ -134,11 +139,11 @@ msgstr "Merkelappar" msgid "Separate tags by commas." msgstr "Separer merkelappar med komma." -#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:101 +#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:90 msgid "Slug" msgstr "Nettnamn" -#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:102 +#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:91 msgid "The slug can't be empty" msgstr "Nettnamnet kan ikkje vera tomt" @@ -166,45 +171,45 @@ msgid "This address contains errors" msgstr "Adressa inneheld feil" #: mediagoblin/edit/forms.py:63 -msgid "Old password" -msgstr "Gamalt passort" - -#: mediagoblin/edit/forms.py:64 -msgid "Enter your old password to prove you own this account." -msgstr "Skriv inn det gamle passordet ditt for Ã¥ stadfesta at du eig denne kontoen." - -#: mediagoblin/edit/forms.py:67 -msgid "New password" -msgstr "Nytt passord" - -#: mediagoblin/edit/forms.py:74 msgid "License preference" msgstr "Lisens-val" -#: mediagoblin/edit/forms.py:80 +#: mediagoblin/edit/forms.py:69 msgid "This will be your default license on upload forms." msgstr "Dette vil vera standardvalet ditt for lisens." -#: mediagoblin/edit/forms.py:82 +#: mediagoblin/edit/forms.py:71 msgid "Email me when others comment on my media" msgstr "Send meg epost nÃ¥r andre kjem med innspel pÃ¥ verka mine." -#: mediagoblin/edit/forms.py:94 +#: mediagoblin/edit/forms.py:83 msgid "The title can't be empty" msgstr "Tittelen kjan ikkje vera tom" -#: mediagoblin/edit/forms.py:96 mediagoblin/submit/forms.py:50 +#: mediagoblin/edit/forms.py:85 mediagoblin/submit/forms.py:50 #: mediagoblin/user_pages/forms.py:48 msgid "Description of this collection" msgstr "Forklaringa til denne samlinga" -#: mediagoblin/edit/forms.py:103 +#: mediagoblin/edit/forms.py:92 msgid "" "The title part of this collection's address. You usually don't need to " "change this." msgstr "Tittel-delen av denne samlinga si adresse. Du treng normalt sett ikkje endra denne." -#: mediagoblin/edit/views.py:66 +#: mediagoblin/edit/forms.py:99 +msgid "Old password" +msgstr "Gamalt passort" + +#: mediagoblin/edit/forms.py:101 +msgid "Enter your old password to prove you own this account." +msgstr "Skriv inn det gamle passordet ditt for Ã¥ stadfesta at du eig denne kontoen." + +#: mediagoblin/edit/forms.py:104 +msgid "New password" +msgstr "Nytt passord" + +#: mediagoblin/edit/views.py:67 msgid "An entry with that slug already exists for this user." msgstr "Eit innlegg med denne adressetittelen finst allereie." @@ -229,44 +234,63 @@ msgstr "TrÃ¥ varsamt, du endrar nokon andre sin profil." msgid "Profile changes saved" msgstr "Lagra endring av profilen" -#: mediagoblin/edit/views.py:241 -msgid "Wrong password" -msgstr "Feil passord" - -#: mediagoblin/edit/views.py:252 +#: mediagoblin/edit/views.py:240 msgid "Account settings saved" msgstr "Lagra kontoinstellingar" -#: mediagoblin/edit/views.py:286 +#: mediagoblin/edit/views.py:274 msgid "You need to confirm the deletion of your account." msgstr "Du mÃ¥ stadfesta slettinga av kontoen din." -#: mediagoblin/edit/views.py:322 mediagoblin/submit/views.py:142 -#: mediagoblin/user_pages/views.py:214 +#: mediagoblin/edit/views.py:310 mediagoblin/submit/views.py:138 +#: mediagoblin/user_pages/views.py:222 #, python-format msgid "You already have a collection called \"%s\"!" msgstr "Du har allereie ei samling med namn «%s»." -#: mediagoblin/edit/views.py:326 +#: mediagoblin/edit/views.py:314 msgid "A collection with that slug already exists for this user." msgstr "Ei samling med den nettadressa finst allereie for denne brukaren." -#: mediagoblin/edit/views.py:343 +#: mediagoblin/edit/views.py:329 msgid "You are editing another user's collection. Proceed with caution." msgstr "Du endrar ein annan brukar si samling. TrÃ¥ varsamt." -#: mediagoblin/gmg_commands/theme.py:58 +#: mediagoblin/edit/views.py:348 +msgid "Wrong password" +msgstr "Feil passord" + +#: mediagoblin/edit/views.py:363 +msgid "Your password was changed successfully" +msgstr "Endra passord" + +#: mediagoblin/gmg_commands/assetlink.py:60 msgid "Cannot link theme... no theme set\n" msgstr "Cannot link theme... no theme set\n" -#: mediagoblin/gmg_commands/theme.py:71 +#: mediagoblin/gmg_commands/assetlink.py:73 msgid "No asset directory for this theme\n" msgstr "No asset directory for this theme\n" -#: mediagoblin/gmg_commands/theme.py:74 +#: mediagoblin/gmg_commands/assetlink.py:76 msgid "However, old link directory symlink found; removed.\n" msgstr "However, old link directory symlink found; removed.\n" +#: mediagoblin/gmg_commands/assetlink.py:112 +#, python-format +msgid "Could not link \"%s\": %s exists and is not a symlink\n" +msgstr "Kunne ikkje lenkja «%s»: %s eksisterer og er ikkje ei symlenkje\n" + +#: mediagoblin/gmg_commands/assetlink.py:119 +#, python-format +msgid "Skipping \"%s\"; already set up.\n" +msgstr "Hopper over «%s»: allereie satt opp.\n" + +#: mediagoblin/gmg_commands/assetlink.py:124 +#, python-format +msgid "Old link found for \"%s\"; removing.\n" +msgstr "Gamal lenkje funnen for «%s»; fjernar.\n" + #: mediagoblin/meddleware/csrf.py:134 msgid "" "CSRF cookie not present. This is most likely the result of a cookie blocker " @@ -274,12 +298,16 @@ msgid "" "domain." msgstr "Finn ikkje CSRF-cookien. Dette er truleg grunna ein cookie-blokkar.<br/>\nSjÃ¥ til at du tillet cookies for dette domenet." -#: mediagoblin/media_types/__init__.py:61 -#: mediagoblin/media_types/__init__.py:102 +#: mediagoblin/media_types/__init__.py:111 +#: mediagoblin/media_types/__init__.py:155 msgid "Sorry, I don't support that file type :(" msgstr "Orsak, stør ikkje den filtypen :(" -#: mediagoblin/media_types/video/processing.py:36 +#: mediagoblin/media_types/pdf/processing.py:136 +msgid "unoconv failing to run, check log file" +msgstr "klarte ikkje køyra unoconv, sjekk logg-fil" + +#: mediagoblin/media_types/video/processing.py:37 msgid "Video transcoding failed" msgstr "Skjedde noko gale med video transkodinga" @@ -346,7 +374,7 @@ msgstr "Omdirigerings-URI-en for programmene. Denne feltet <strong>krevst</stron msgid "This field is required for public clients" msgstr "Dette feltet krevst for opne (public) klientar" -#: mediagoblin/plugins/oauth/views.py:59 +#: mediagoblin/plugins/oauth/views.py:56 msgid "The client {0} has been registered!" msgstr "Klienten {0} er registrert." @@ -365,7 +393,7 @@ msgstr "Dine OAuth-klientar" msgid "Add" msgstr "Legg til" -#: mediagoblin/processing/__init__.py:172 +#: mediagoblin/processing/__init__.py:193 msgid "Invalid file given for media type." msgstr "Ugyldig fil for medietypen." @@ -373,45 +401,45 @@ msgstr "Ugyldig fil for medietypen." msgid "File" msgstr "Fil" -#: mediagoblin/submit/views.py:51 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "Du mÃ¥ velja ei fil." -#: mediagoblin/submit/views.py:97 +#: mediagoblin/submit/views.py:93 msgid "Woohoo! Submitted!" msgstr "Johoo! Opplasta!" -#: mediagoblin/submit/views.py:146 +#: mediagoblin/submit/views.py:144 #, python-format msgid "Collection \"%s\" added!" msgstr "La til samlinga «%s»." -#: mediagoblin/templates/mediagoblin/base.html:64 +#: mediagoblin/templates/mediagoblin/base.html:67 msgid "Verify your email!" msgstr "Verifiser epostadressa di." -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:68 msgid "log out" msgstr "Logg ut" -#: mediagoblin/templates/mediagoblin/base.html:70 +#: mediagoblin/templates/mediagoblin/base.html:73 #: mediagoblin/templates/mediagoblin/auth/login.html:28 #: mediagoblin/templates/mediagoblin/auth/login.html:36 #: mediagoblin/templates/mediagoblin/auth/login.html:54 msgid "Log in" msgstr "Logg inn" -#: mediagoblin/templates/mediagoblin/base.html:79 +#: mediagoblin/templates/mediagoblin/base.html:82 #, python-format msgid "<a href=\"%(user_url)s\">%(user_name)s</a>'s account" msgstr "<a href=\"%(user_url)s\">%(user_name)s</a> sin konto" -#: mediagoblin/templates/mediagoblin/base.html:86 +#: mediagoblin/templates/mediagoblin/base.html:89 msgid "Change account settings" msgstr "Endra kontoinstellingar" -#: mediagoblin/templates/mediagoblin/base.html:90 -#: mediagoblin/templates/mediagoblin/base.html:105 +#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:108 #: mediagoblin/templates/mediagoblin/admin/panel.html:21 #: mediagoblin/templates/mediagoblin/admin/panel.html:26 #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:21 @@ -419,72 +447,25 @@ msgstr "Endra kontoinstellingar" msgid "Media processing panel" msgstr "Verkprosesseringspanel" -#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:96 msgid "Log out" msgstr "Logg ut" -#: mediagoblin/templates/mediagoblin/base.html:96 +#: mediagoblin/templates/mediagoblin/base.html:99 #: mediagoblin/templates/mediagoblin/user_pages/user.html:156 msgid "Add media" msgstr "Legg til verk" -#: mediagoblin/templates/mediagoblin/base.html:99 +#: mediagoblin/templates/mediagoblin/base.html:102 #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:41 msgid "Create new collection" msgstr "Lag ny samling" -#: mediagoblin/templates/mediagoblin/base.html:122 -#, python-format -msgid "" -"Powered by <a href=\"http://mediagoblin.org/\" title='Version " -"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." -msgstr "Drive av <a href=\"http://mediagoblin.org\" title='Version %(version)s'>MediaGoblin</a>, eit <a href=\"http://gnu.org/\">GNU</a>-prosjekt." - -#: mediagoblin/templates/mediagoblin/base.html:125 -#, 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 "Lisensiert med <a href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a href=\"%(source_link)s\">Kjeldekode</a> er tilgjengeleg." - #: mediagoblin/templates/mediagoblin/error.html:24 msgid "Image of goblin stressing out" msgstr "Bilete av stressa goblin" -#: mediagoblin/templates/mediagoblin/root.html:31 -msgid "Explore" -msgstr "Utforsk" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "Heihei, velkomen til denne MediaGoblin-sida." - -#: mediagoblin/templates/mediagoblin/root.html:35 -msgid "" -"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, an " -"extraordinarily great piece of media hosting software." -msgstr "Denne sida køyrer <a href=\"http://mediagoblin.org\">MediaGoblin</a>, eit superbra program for Ã¥ visa fram dine kreative verk." - -#: mediagoblin/templates/mediagoblin/root.html:36 -msgid "" -"To add your own media, place comments, and more, you can log in with your " -"MediaGoblin account." -msgstr "Vil du leggja til eigne verk og innpel, so mÃ¥ du logga inn." - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Don't have one yet? It's easy!" -msgstr "Har du ikkje ein enno? Det er enkelt!" - -#: mediagoblin/templates/mediagoblin/root.html:39 -#, 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\">Opprett ein konto pÃ¥ denne sida</a> eller <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">set opp MediaGoblin pÃ¥ eigen tenar</a>" - -#: mediagoblin/templates/mediagoblin/root.html:47 +#: mediagoblin/templates/mediagoblin/root.html:32 msgid "Most recent media" msgstr "Nyaste verk" @@ -590,6 +571,53 @@ msgid "" "%(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/bits/base_footer.html:21 +#, python-format +msgid "" +"Powered by <a href=\"http://mediagoblin.org/\" title='Version " +"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." +msgstr "Drive av <a href=\"http://mediagoblin.org\" title='Version %(version)s'>MediaGoblin</a>, eit <a href=\"http://gnu.org/\">GNU</a>-prosjekt." + +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:24 +#, 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 "Lisensiert med <a href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a href=\"%(source_link)s\">Kjeldekode</a> er tilgjengeleg." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:20 +msgid "Explore" +msgstr "Utforsk" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:22 +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "Heihei, velkomen til denne MediaGoblin-sida." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:24 +msgid "" +"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, an " +"extraordinarily great piece of media hosting software." +msgstr "Denne sida køyrer <a href=\"http://mediagoblin.org\">MediaGoblin</a>, eit superbra program for Ã¥ visa fram dine kreative verk." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:25 +msgid "" +"To add your own media, place comments, and more, you can log in with your " +"MediaGoblin account." +msgstr "Vil du leggja til eigne verk og innpel, so mÃ¥ du logga inn." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:27 +msgid "Don't have one yet? It's easy!" +msgstr "Har du ikkje ein enno? Det er enkelt!" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:28 +#, 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\">Opprett ein konto pÃ¥ denne sida</a>\n eller\n <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">Set opp din eigen MediaGoblin-server</a>" + #: mediagoblin/templates/mediagoblin/bits/logo.html:23 #: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 msgid "MediaGoblin logo" @@ -602,13 +630,13 @@ msgid "Editing attachments for %(media_title)s" msgstr "Endrar vedlegg for %(media_title)s" #: mediagoblin/templates/mediagoblin/edit/attachments.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:159 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:175 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:182 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:198 msgid "Attachments" msgstr "Vedlegg" #: mediagoblin/templates/mediagoblin/edit/attachments.html:57 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:181 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:204 msgid "Add attachment" msgstr "Legg ved vedlegg" @@ -625,12 +653,22 @@ msgstr "Bryt av" #: mediagoblin/templates/mediagoblin/edit/attachments.html:63 #: mediagoblin/templates/mediagoblin/edit/edit.html:42 -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:52 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:55 #: mediagoblin/templates/mediagoblin/edit/edit_collection.html:33 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:40 msgid "Save changes" msgstr "Lagra" +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:28 +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 +#, python-format +msgid "Changing %(username)s's password" +msgstr "Endrar passordet til %(username)s" + +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 +msgid "Save" +msgstr "Lagra" + #: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 #, python-format msgid "Really delete user '%(user_name)s' and all related media/comments?" @@ -641,7 +679,7 @@ msgid "Yes, really delete my account" msgstr "Ja, slett kontoen min" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:48 #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49 msgid "Delete permanently" msgstr "Slett permanent" @@ -658,7 +696,11 @@ msgstr "Endrar %(media_title)s" msgid "Changing %(username)s's account settings" msgstr "Endrar kontoinnstellingane til %(username)s" -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:59 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 +msgid "Change your password." +msgstr "Endra passordet ditt." + +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 msgid "Delete my account" msgstr "Slett kontoen min" @@ -683,6 +725,7 @@ msgstr "Verk merka med: %(tag_name)s" #: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 #: mediagoblin/templates/mediagoblin/media_displays/audio.html:56 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:65 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:136 #: mediagoblin/templates/mediagoblin/media_displays/video.html:55 msgid "Download" @@ -707,6 +750,7 @@ msgid "" msgstr "Du kan skaffa ein moderne netlesar som kan spela av dette lydklippet hjÃ¥ <a href=\"http://opera.com/download\">http://opera.com/download</a>." #: mediagoblin/templates/mediagoblin/media_displays/audio.html:60 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:71 #: mediagoblin/templates/mediagoblin/media_displays/video.html:61 msgid "Original file" msgstr "Opphavleg fil" @@ -715,6 +759,7 @@ msgstr "Opphavleg fil" msgid "WebM file (Vorbis codec)" msgstr "WebM-fil (Vorbis-kodek)" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:59 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:87 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:93 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:99 @@ -725,6 +770,10 @@ msgstr "WebM-fil (Vorbis-kodek)" msgid "Image for %(media_title)s" msgstr "Bilete for %(media_title)s" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 +msgid "PDF file" +msgstr "PDF-fil" + #: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 msgid "Toggle Rotate" msgstr "SlÃ¥ av/pÃ¥ rotering" @@ -823,7 +872,7 @@ msgstr "Vil du verkeleg sletta %(title)s?" msgid "Really remove %(media_title)s from %(collection_title)s?" msgstr "Fjerna %(media_title)s frÃ¥ %(collection_title)s?" -#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:54 msgid "Remove" msgstr "Fjern" @@ -866,24 +915,28 @@ msgstr "<a href=\"%(user_url)s\">%(username)s</a> sine verk" msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>" msgstr "â– Ser pÃ¥ <a href=\"%(user_url)s\">%(username)s</a> sine verk" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:94 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:95 msgid "Add a comment" msgstr "Legg att innspel" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 msgid "Add this comment" msgstr "Legg til dette innspelet" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:123 -msgid "at" -msgstr "hjÃ¥" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:144 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:132 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:152 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:164 #, python-format -msgid "" -"<h3>Added on</h3>\n" -" <p>%(date)s</p>" -msgstr "<h3>Lagt til</h3>\n <p>%(date)s</p>" +msgid "%(formatted_time)s ago" +msgstr "%(formatted_time)s sidan" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:150 +msgid "Added" +msgstr "Lagt til" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:161 +msgid "Created" +msgstr "Oppretta" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:40 @@ -1039,7 +1092,7 @@ msgstr "eldre" msgid "Tagged with" msgstr "Merka med" -#: mediagoblin/tools/exif.py:80 +#: mediagoblin/tools/exif.py:83 msgid "Could not read the image file." msgstr "Klarte ikkje lesa biletefila." @@ -1069,6 +1122,30 @@ msgid "" " deleted." msgstr "Ser ikkje ut til Ã¥ finnast noko her. Orsak.</p>\n<p>Dersom du er sikker pÃ¥ at adressa finst, so er ho truleg flytta eller sletta." +#: mediagoblin/tools/timesince.py:62 +msgid "year" +msgstr "Ã¥r" + +#: mediagoblin/tools/timesince.py:63 +msgid "month" +msgstr "mÃ¥nad" + +#: mediagoblin/tools/timesince.py:64 +msgid "week" +msgstr "veke" + +#: mediagoblin/tools/timesince.py:65 +msgid "day" +msgstr "dag" + +#: mediagoblin/tools/timesince.py:66 +msgid "hour" +msgstr "time" + +#: mediagoblin/tools/timesince.py:67 +msgid "minute" +msgstr "minutt" + #: mediagoblin/user_pages/forms.py:23 msgid "Comment" msgstr "Innspel" @@ -1100,73 +1177,77 @@ msgstr "-- Vel --" msgid "Include a note" msgstr "Legg ved eit notat" -#: mediagoblin/user_pages/lib.py:56 +#: mediagoblin/user_pages/lib.py:58 msgid "commented on your post" msgstr "kom med innspel pÃ¥ innlegget ditt" -#: mediagoblin/user_pages/views.py:166 +#: mediagoblin/user_pages/views.py:169 +msgid "Sorry, comments are disabled." +msgstr "Innspel er avslege" + +#: mediagoblin/user_pages/views.py:174 msgid "Oops, your comment was empty." msgstr "Vops, innspelet ditt var tomt." -#: mediagoblin/user_pages/views.py:172 +#: mediagoblin/user_pages/views.py:180 msgid "Your comment has been posted!" msgstr "Innspelet ditt er lagt til." -#: mediagoblin/user_pages/views.py:197 +#: mediagoblin/user_pages/views.py:205 msgid "Please check your entries and try again." msgstr "Sjekk filene dine og prøv omatt." -#: mediagoblin/user_pages/views.py:237 +#: mediagoblin/user_pages/views.py:245 msgid "You have to select or add a collection" msgstr "Du mÃ¥ velja eller laga ei samling" -#: mediagoblin/user_pages/views.py:248 +#: mediagoblin/user_pages/views.py:256 #, python-format msgid "\"%s\" already in collection \"%s\"" msgstr "«%s» er allereie i samling «%s»" -#: mediagoblin/user_pages/views.py:264 +#: mediagoblin/user_pages/views.py:262 #, python-format msgid "\"%s\" added to collection \"%s\"" msgstr "«%s» lagt til samling «%s»" -#: mediagoblin/user_pages/views.py:286 +#: mediagoblin/user_pages/views.py:282 msgid "You deleted the media." msgstr "Du sletta verket." -#: mediagoblin/user_pages/views.py:293 +#: mediagoblin/user_pages/views.py:289 msgid "The media was not deleted because you didn't check that you were sure." msgstr "Sletta ikkje verket." -#: mediagoblin/user_pages/views.py:301 +#: mediagoblin/user_pages/views.py:296 msgid "You are about to delete another user's media. Proceed with caution." msgstr "Du er i ferd med Ã¥ sletta ein annan brukar sine verk. TrÃ¥ varsamt." -#: mediagoblin/user_pages/views.py:375 +#: mediagoblin/user_pages/views.py:370 msgid "You deleted the item from the collection." msgstr "Du fjerna fila frÃ¥ samlinga." -#: mediagoblin/user_pages/views.py:379 +#: mediagoblin/user_pages/views.py:374 msgid "The item was not removed because you didn't check that you were sure." msgstr "Fila var ikkje fjerna fordi du ikkje var sikker." -#: mediagoblin/user_pages/views.py:389 +#: mediagoblin/user_pages/views.py:382 msgid "" "You are about to delete an item from another user's collection. Proceed with" " caution." msgstr "Du er i ferd med Ã¥ fjerna ei fil frÃ¥ ein annan brukar si samling. TrÃ¥ varsamt." -#: mediagoblin/user_pages/views.py:422 +#: mediagoblin/user_pages/views.py:415 #, python-format msgid "You deleted the collection \"%s\"" msgstr "Samlinga «%s» sletta" -#: mediagoblin/user_pages/views.py:429 +#: mediagoblin/user_pages/views.py:422 msgid "" "The collection was not deleted because you didn't check that you were sure." msgstr "Sletta ikkje samlinga." -#: mediagoblin/user_pages/views.py:439 +#: mediagoblin/user_pages/views.py:430 msgid "" "You are about to delete another user's collection. Proceed with caution." msgstr "Du er i ferd med Ã¥ sletta ein annan brukar si samling. TrÃ¥ varsamt." diff --git a/mediagoblin/i18n/pl/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/pl/LC_MESSAGES/mediagoblin.mo Binary files differindex ea905b61..8b318329 100644 --- a/mediagoblin/i18n/pl/LC_MESSAGES/mediagoblin.mo +++ b/mediagoblin/i18n/pl/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/pl/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/pl/LC_MESSAGES/mediagoblin.po index 9edf8e2b..78ab219a 100644 --- a/mediagoblin/i18n/pl/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/pl/LC_MESSAGES/mediagoblin.po @@ -3,15 +3,16 @@ # This file is distributed under the same license as the PROJECT project. # # Translators: -# Daniel Koć <kocio@aster.pl>, 2012. +# Daniel Koć <kocio@aster.pl>, 2012 +# Sergiusz Pawlowicz <transifex@pawlowicz.name>, 2013 msgid "" msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" -"POT-Creation-Date: 2013-03-04 18:04-0600\n" -"PO-Revision-Date: 2013-03-05 00:04+0000\n" -"Last-Translator: cwebber <cwebber@dustycloud.org>\n" -"Language-Team: LANGUAGE <LL@li.org>\n" +"POT-Creation-Date: 2013-05-27 13:54-0500\n" +"PO-Revision-Date: 2013-05-28 13:51+0000\n" +"Last-Translator: Sergiusz Pawlowicz <transifex@pawlowicz.name>\n" +"Language-Team: Polish (http://www.transifex.com/projects/p/mediagoblin/language/pl/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -19,34 +20,39 @@ msgstr "" "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:28 -msgid "Invalid User name or email address." -msgstr "" - -#: mediagoblin/auth/forms.py:29 -msgid "This field does not take email addresses." -msgstr "" - -#: mediagoblin/auth/forms.py:30 -msgid "This field requires an email address." -msgstr "" - -#: mediagoblin/auth/forms.py:52 mediagoblin/auth/forms.py:67 +#: mediagoblin/auth/forms.py:26 msgid "Username" msgstr "Użytkownik" -#: mediagoblin/auth/forms.py:56 mediagoblin/auth/forms.py:71 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 +#: mediagoblin/tests/test_util.py:110 msgid "Password" msgstr "HasÅ‚o" -#: mediagoblin/auth/forms.py:60 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "Adres e-mail" -#: mediagoblin/auth/forms.py:78 +#: mediagoblin/auth/forms.py:41 +msgid "Username or Email" +msgstr "Nazwa konta lub adres poczty elektronicznej" + +#: mediagoblin/auth/forms.py:52 msgid "Username or email" msgstr "Użytkownik lub adres e-mail" +#: mediagoblin/auth/tools.py:31 +msgid "Invalid User name or email address." +msgstr "NieprawidÅ‚owa nazwa konta albo niewÅ‚aÅ›ciwy adres poczty elektronicznej." + +#: mediagoblin/auth/tools.py:32 +msgid "This field does not take email addresses." +msgstr "Niniejsze pole nie jest przeznaczone na adres poczty elektronicznej." + +#: mediagoblin/auth/tools.py:33 +msgid "This field requires an email address." +msgstr "Niniejsze pole wymaga podania adresu poczty elektronicznej." + #: mediagoblin/auth/views.py:54 msgid "Sorry, registration is disabled on this instance." msgstr "Niestety rejestracja w tym serwisie jest wyłączona." @@ -59,54 +65,54 @@ msgstr "Niestety użytkownik o takiej nazwie już istnieje." 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:174 +#: 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:180 +#: 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:198 +#: 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:206 +#: 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:219 +#: mediagoblin/auth/views.py:227 msgid "Resent your verification email." msgstr "WyÅ›lij ponownie e-mail weryfikujÄ…cy." -#: mediagoblin/auth/views.py:250 +#: mediagoblin/auth/views.py:258 msgid "" "If that email address (case sensitive!) is registered an email has been sent" " with instructions on how to change your password." -msgstr "" +msgstr "JeÅ›li ten adres poczty elektronicznej istnieje (uwzglÄ™dniajÄ…c wielkość liter!), wysÅ‚ano na niego list z instrukcjÄ…, w jaki sposób możesz zmienić swoje hasÅ‚o." -#: mediagoblin/auth/views.py:261 +#: mediagoblin/auth/views.py:269 msgid "Couldn't find someone with that username." -msgstr "" +msgstr "Nie potrafiÄ™ znaleźć nikogo o tej nazwie użytkownika." -#: mediagoblin/auth/views.py:264 +#: mediagoblin/auth/views.py:272 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:271 +#: mediagoblin/auth/views.py:279 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." msgstr "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:328 +#: mediagoblin/auth/views.py:336 msgid "You can now log in using your new password." -msgstr "Teraz możesz siÄ™ zalogować używajÄ…c nowe hasÅ‚o." +msgstr "Teraz możesz siÄ™ zalogować używajÄ…c nowego hasÅ‚a." -#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:93 +#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:82 #: mediagoblin/submit/forms.py:28 mediagoblin/submit/forms.py:47 #: mediagoblin/user_pages/forms.py:45 msgid "Title" @@ -117,7 +123,7 @@ msgid "Description of this work" msgstr "Opis tej pracy" #: mediagoblin/edit/forms.py:29 mediagoblin/edit/forms.py:52 -#: mediagoblin/edit/forms.py:97 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:86 mediagoblin/submit/forms.py:32 #: mediagoblin/submit/forms.py:51 mediagoblin/user_pages/forms.py:49 msgid "" "You can use\n" @@ -133,11 +139,11 @@ msgstr "Znaczniki" msgid "Separate tags by commas." msgstr "Rozdzielaj znaczniki przecinkami." -#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:101 +#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:90 msgid "Slug" msgstr "Slug" -#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:102 +#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:91 msgid "The slug can't be empty" msgstr "Slug nie może być pusty" @@ -165,45 +171,45 @@ 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:64 -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:67 -msgid "New password" -msgstr "Nowe hasÅ‚o" - -#: mediagoblin/edit/forms.py:74 msgid "License preference" -msgstr "" +msgstr "Ulubiona licencja" -#: mediagoblin/edit/forms.py:80 +#: mediagoblin/edit/forms.py:69 msgid "This will be your default license on upload forms." -msgstr "" +msgstr "To bÄ™dzie twoja domyÅ›lna licencja dla wgrywanych mediów." -#: mediagoblin/edit/forms.py:82 +#: mediagoblin/edit/forms.py:71 msgid "Email me when others comment on my media" msgstr "Powiadamiaj mnie e-mailem o komentarzach do moich mediów" -#: mediagoblin/edit/forms.py:94 +#: mediagoblin/edit/forms.py:83 msgid "The title can't be empty" msgstr "TytuÅ‚ nie może być pusty" -#: mediagoblin/edit/forms.py:96 mediagoblin/submit/forms.py:50 +#: mediagoblin/edit/forms.py:85 mediagoblin/submit/forms.py:50 #: mediagoblin/user_pages/forms.py:48 msgid "Description of this collection" msgstr "Opis tej kolekcji" -#: mediagoblin/edit/forms.py:103 +#: mediagoblin/edit/forms.py:92 msgid "" "The title part of this collection's address. You usually don't need to " "change this." msgstr "Część adresu zawierajÄ…ca tytuÅ‚. Zwykle nie musisz tego zmieniać." -#: mediagoblin/edit/views.py:66 +#: mediagoblin/edit/forms.py:99 +msgid "Old password" +msgstr "Stare hasÅ‚o" + +#: mediagoblin/edit/forms.py:101 +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:104 +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." @@ -214,11 +220,11 @@ msgstr "Edytujesz media innego użytkownika. Zachowaj ostrożność." #: mediagoblin/edit/views.py:155 #, python-format msgid "You added the attachment %s!" -msgstr "" +msgstr "DodaÅ‚eÅ› załącznik %s!" #: mediagoblin/edit/views.py:182 msgid "You can only edit your own profile." -msgstr "" +msgstr "Masz możliwość edycji tylko wÅ‚asnego profilu." #: mediagoblin/edit/views.py:188 msgid "You are editing a user's profile. Proceed with caution." @@ -228,57 +234,80 @@ msgstr "Edytujesz profil innego użytkownika. Zachowaj ostrożność." msgid "Profile changes saved" msgstr "Zapisano zmiany profilu" -#: mediagoblin/edit/views.py:241 -msgid "Wrong password" -msgstr "NieprawidÅ‚owe hasÅ‚o" - -#: mediagoblin/edit/views.py:252 +#: mediagoblin/edit/views.py:240 msgid "Account settings saved" msgstr "Zapisano ustawienia konta" -#: mediagoblin/edit/views.py:286 +#: mediagoblin/edit/views.py:274 msgid "You need to confirm the deletion of your account." -msgstr "" +msgstr "Musisz potwierdzić, że chcesz skasować swoje konto." -#: mediagoblin/edit/views.py:322 mediagoblin/submit/views.py:142 -#: mediagoblin/user_pages/views.py:214 +#: mediagoblin/edit/views.py:310 mediagoblin/submit/views.py:138 +#: mediagoblin/user_pages/views.py:222 #, python-format msgid "You already have a collection called \"%s\"!" msgstr "Kolekcja \"%s\" już istnieje!" -#: mediagoblin/edit/views.py:326 +#: mediagoblin/edit/views.py:314 msgid "A collection with that slug already exists for this user." msgstr "Kolekcja tego użytkownika z takim slugiem już istnieje." -#: mediagoblin/edit/views.py:343 +#: mediagoblin/edit/views.py:329 msgid "You are editing another user's collection. Proceed with caution." msgstr "Edytujesz kolekcjÄ™ innego użytkownika. Zachowaj ostrożność." -#: mediagoblin/gmg_commands/theme.py:58 +#: mediagoblin/edit/views.py:348 +msgid "Wrong password" +msgstr "NieprawidÅ‚owe hasÅ‚o" + +#: mediagoblin/edit/views.py:363 +msgid "Your password was changed successfully" +msgstr "Twoje hasÅ‚o zostaÅ‚o zmienione" + +#: mediagoblin/gmg_commands/assetlink.py:60 msgid "Cannot link theme... no theme set\n" msgstr "Nie można podlinkować motywu... nie wybrano motywu\n" -#: mediagoblin/gmg_commands/theme.py:71 +#: mediagoblin/gmg_commands/assetlink.py:73 msgid "No asset directory for this theme\n" msgstr "Brak katalogu danych dla tego motywu\n" -#: mediagoblin/gmg_commands/theme.py:74 +#: mediagoblin/gmg_commands/assetlink.py:76 msgid "However, old link directory symlink found; removed.\n" msgstr "Znaleziono stary odnoÅ›nik symboliczny do katalogu; usuniÄ™to.\n" +#: mediagoblin/gmg_commands/assetlink.py:112 +#, python-format +msgid "Could not link \"%s\": %s exists and is not a symlink\n" +msgstr "Nie mogÄ™ zrobić odnoÅ›nika \"%s\": %s istnieje i nie jest odnoÅ›nikiem\n" + +#: mediagoblin/gmg_commands/assetlink.py:119 +#, python-format +msgid "Skipping \"%s\"; already set up.\n" +msgstr "Opuszczam \"%s\"; już jest gotowe.\n" + +#: mediagoblin/gmg_commands/assetlink.py:124 +#, python-format +msgid "Old link found for \"%s\"; removing.\n" +msgstr "Znaleziono stary odnoÅ›nik dla \"%s\"; usuwam.\n" + #: mediagoblin/meddleware/csrf.py:134 msgid "" "CSRF cookie not present. This is most likely the result of a cookie blocker " "or somesuch.<br/>Make sure to permit the settings of cookies for this " "domain." -msgstr "" +msgstr "Ciasteczko CSFR nie jest dostÄ™pne. Najprawdopodobniej stosujesz jakÄ…Å› formÄ™ blokowania ciasteczek.<br/>Upewnij siÄ™, że nasz serwer może zakÅ‚adać ciasteczka w twojej przeglÄ…darce." -#: mediagoblin/media_types/__init__.py:61 -#: mediagoblin/media_types/__init__.py:102 +#: mediagoblin/media_types/__init__.py:111 +#: mediagoblin/media_types/__init__.py:155 msgid "Sorry, I don't support that file type :(" msgstr "NIestety, nie obsÅ‚ugujemy tego typu plików :-(" -#: mediagoblin/media_types/video/processing.py:36 +#: mediagoblin/media_types/pdf/processing.py:136 +msgid "unoconv failing to run, check log file" +msgstr "nie daÅ‚o siÄ™ uruchomić unoconv, sprawdź log" + +#: mediagoblin/media_types/video/processing.py:37 msgid "Video transcoding failed" msgstr "Konwersja wideo nie powiodÅ‚a siÄ™" @@ -315,7 +344,7 @@ msgstr "Opis" msgid "" "This will be visible to users allowing your\n" " application to authenticate as them." -msgstr "" +msgstr "To bÄ™dzie widoczne dla użytkowników, pozwalajÄ…c⎠twojej aplikacji uwierzytelniać siÄ™ jako oni." #: mediagoblin/plugins/oauth/forms.py:40 msgid "Type" @@ -345,17 +374,17 @@ msgstr "Przekierowanie URI dla aplikacji, to pole\n jest <strong>wyma msgid "This field is required for public clients" msgstr "To pole jest wymagane dla klientów publicznych" -#: mediagoblin/plugins/oauth/views.py:59 +#: mediagoblin/plugins/oauth/views.py:56 msgid "The client {0} has been registered!" msgstr "Klient {0} zostaÅ‚ zarejestrowany!" #: mediagoblin/plugins/oauth/templates/oauth/client/connections.html:22 msgid "OAuth client connections" -msgstr "" +msgstr "Połączenia do OAuth" #: mediagoblin/plugins/oauth/templates/oauth/client/list.html:22 msgid "Your OAuth clients" -msgstr "" +msgstr "Twoi klienci OAuth" #: mediagoblin/plugins/oauth/templates/oauth/client/register.html:29 #: mediagoblin/templates/mediagoblin/submit/collection.html:30 @@ -364,7 +393,7 @@ msgstr "" msgid "Add" msgstr "Dodaj" -#: mediagoblin/processing/__init__.py:172 +#: mediagoblin/processing/__init__.py:193 msgid "Invalid file given for media type." msgstr "NiewÅ‚aÅ›ciwy plik dla tego rodzaju mediów." @@ -372,45 +401,45 @@ msgstr "NiewÅ‚aÅ›ciwy plik dla tego rodzaju mediów." msgid "File" msgstr "Plik" -#: mediagoblin/submit/views.py:51 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "Musisz podać plik." -#: mediagoblin/submit/views.py:97 +#: mediagoblin/submit/views.py:93 msgid "Woohoo! Submitted!" msgstr "Hura! WysÅ‚ano!" -#: mediagoblin/submit/views.py:146 +#: mediagoblin/submit/views.py:144 #, python-format msgid "Collection \"%s\" added!" msgstr "Kolekcja \"%s\" zostaÅ‚a dodana!" -#: mediagoblin/templates/mediagoblin/base.html:64 +#: mediagoblin/templates/mediagoblin/base.html:67 msgid "Verify your email!" msgstr "Zweryfikuj swój adres e-mail!" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:68 msgid "log out" -msgstr "" +msgstr "wyloguj siÄ™" -#: mediagoblin/templates/mediagoblin/base.html:70 +#: mediagoblin/templates/mediagoblin/base.html:73 #: mediagoblin/templates/mediagoblin/auth/login.html:28 #: mediagoblin/templates/mediagoblin/auth/login.html:36 #: mediagoblin/templates/mediagoblin/auth/login.html:54 msgid "Log in" msgstr "Zaloguj siÄ™" -#: mediagoblin/templates/mediagoblin/base.html:79 +#: mediagoblin/templates/mediagoblin/base.html:82 #, python-format msgid "<a href=\"%(user_url)s\">%(user_name)s</a>'s account" -msgstr "" +msgstr "konto <a href=\"%(user_url)s\">%(user_name)s</a>" -#: mediagoblin/templates/mediagoblin/base.html:86 +#: mediagoblin/templates/mediagoblin/base.html:89 msgid "Change account settings" msgstr "ZmieÅ„ ustawienia konta" -#: mediagoblin/templates/mediagoblin/base.html:90 -#: mediagoblin/templates/mediagoblin/base.html:105 +#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:108 #: mediagoblin/templates/mediagoblin/admin/panel.html:21 #: mediagoblin/templates/mediagoblin/admin/panel.html:26 #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:21 @@ -418,72 +447,25 @@ msgstr "ZmieÅ„ ustawienia konta" msgid "Media processing panel" msgstr "Panel przetwarzania mediów" -#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:96 msgid "Log out" -msgstr "" +msgstr "Wyloguj siÄ™" -#: mediagoblin/templates/mediagoblin/base.html:96 +#: mediagoblin/templates/mediagoblin/base.html:99 #: mediagoblin/templates/mediagoblin/user_pages/user.html:156 msgid "Add media" msgstr "Dodaj media" -#: mediagoblin/templates/mediagoblin/base.html:99 +#: mediagoblin/templates/mediagoblin/base.html:102 #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:41 msgid "Create new collection" -msgstr "" - -#: mediagoblin/templates/mediagoblin/base.html:122 -#, python-format -msgid "" -"Powered by <a href=\"http://mediagoblin.org/\" title='Version " -"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." -msgstr "" - -#: mediagoblin/templates/mediagoblin/base.html:125 -#, 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>." +msgstr "Utwórz nowÄ… kolekcjÄ™" #: mediagoblin/templates/mediagoblin/error.html:24 msgid "Image of goblin stressing out" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:31 -msgid "Explore" -msgstr "Odkrywaj" +msgstr "Grafika zestresowanego goblina" -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "Cześć, witaj na stronie MediaGoblin!" - -#: mediagoblin/templates/mediagoblin/root.html:35 -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:36 -msgid "" -"To add your own media, place comments, and more, you can log in with your " -"MediaGoblin account." -msgstr "Aby dodawać swoje pliki, komentować i wykonywać inne czynnoÅ›ci, możesz siÄ™ zalogować na swoje konto MediaGoblin." - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Don't have one yet? It's easy!" -msgstr "Jeszcze go nie masz? To proste!" - -#: mediagoblin/templates/mediagoblin/root.html:39 -#, 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:47 +#: mediagoblin/templates/mediagoblin/root.html:32 msgid "Most recent media" msgstr "Najnowsze media" @@ -589,6 +571,53 @@ msgid "" "%(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/bits/base_footer.html:21 +#, python-format +msgid "" +"Powered by <a href=\"http://mediagoblin.org/\" title='Version " +"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." +msgstr "NapÄ™dzane przez oprogramowanie <a href=\"http://mediagoblin.org/\" title='w wersji %(version)s'>MediaGoblin</a>, bÄ™dÄ…ce częściÄ… projektu <a href=\"http://gnu.org/\">GNU</a>." + +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:24 +#, 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/bits/frontpage_welcome.html:20 +msgid "Explore" +msgstr "Odkrywaj" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:22 +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "Cześć, witaj na stronie MediaGoblin!" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:24 +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/bits/frontpage_welcome.html:25 +msgid "" +"To add your own media, place comments, and more, you can log in with your " +"MediaGoblin account." +msgstr "Aby dodawać swoje pliki, komentować i wykonywać inne czynnoÅ›ci, możesz siÄ™ zalogować na swoje konto MediaGoblin." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:27 +msgid "Don't have one yet? It's easy!" +msgstr "Jeszcze go nie masz? To proste!" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:28 +#, 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\">Załóż konto na tym serwerze</a>\n albo\n <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">Uruchom MediaGoblin na swoim wÅ‚asnym serwerze</a>" + #: mediagoblin/templates/mediagoblin/bits/logo.html:23 #: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 msgid "MediaGoblin logo" @@ -601,13 +630,13 @@ msgid "Editing attachments for %(media_title)s" msgstr "Edycja załączników do %(media_title)s" #: mediagoblin/templates/mediagoblin/edit/attachments.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:159 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:175 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:182 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:198 msgid "Attachments" msgstr "Załączniki" #: mediagoblin/templates/mediagoblin/edit/attachments.html:57 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:181 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:204 msgid "Add attachment" msgstr "Dodaj załącznik" @@ -624,23 +653,33 @@ msgstr "Anuluj" #: mediagoblin/templates/mediagoblin/edit/attachments.html:63 #: mediagoblin/templates/mediagoblin/edit/edit.html:42 -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:52 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:55 #: mediagoblin/templates/mediagoblin/edit/edit_collection.html:33 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:40 msgid "Save changes" msgstr "Zapisz zmiany" +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:28 +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 +#, python-format +msgid "Changing %(username)s's password" +msgstr "Zmieniam hasÅ‚o użytkownika %(username)s" + +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 +msgid "Save" +msgstr "Zachowaj" + #: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 #, python-format msgid "Really delete user '%(user_name)s' and all related media/comments?" -msgstr "" +msgstr "Czy naprawdÄ™ skasować użytkownika '%(user_name)s' oraz usunąć wszystkie jego pliki i komentarze?" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:35 msgid "Yes, really delete my account" -msgstr "" +msgstr "Tak, naprawdÄ™ chcÄ™ skasować swoje konto" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:48 #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49 msgid "Delete permanently" msgstr "UsuÅ„ na staÅ‚e" @@ -657,9 +696,13 @@ msgstr "Edytowanie %(media_title)s" msgid "Changing %(username)s's account settings" msgstr "Zmiana ustawieÅ„ konta %(username)s" -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:59 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 +msgid "Change your password." +msgstr "ZmieÅ„ swoje hasÅ‚o." + +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 msgid "Delete my account" -msgstr "" +msgstr "UsuÅ„ moje konto" #: mediagoblin/templates/mediagoblin/edit/edit_collection.html:29 #, python-format @@ -682,6 +725,7 @@ msgstr "Media ze znacznikami: %(tag_name)s" #: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 #: mediagoblin/templates/mediagoblin/media_displays/audio.html:56 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:65 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:136 #: mediagoblin/templates/mediagoblin/media_displays/video.html:55 msgid "Download" @@ -706,6 +750,7 @@ msgid "" 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:60 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:71 #: mediagoblin/templates/mediagoblin/media_displays/video.html:61 msgid "Original file" msgstr "Oryginalny plik" @@ -714,6 +759,7 @@ msgstr "Oryginalny plik" msgid "WebM file (Vorbis codec)" msgstr "plik WebM (kodek Vorbis)" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:59 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:87 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:93 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:99 @@ -724,59 +770,63 @@ msgstr "plik WebM (kodek Vorbis)" msgid "Image for %(media_title)s" msgstr "Grafika dla %(media_title)s" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 +msgid "PDF file" +msgstr "Plik PDF" + #: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 msgid "Toggle Rotate" -msgstr "" +msgstr "Obróć" #: mediagoblin/templates/mediagoblin/media_displays/stl.html:113 msgid "Perspective" -msgstr "" +msgstr "Perspektywa" #: mediagoblin/templates/mediagoblin/media_displays/stl.html:116 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:117 msgid "Front" -msgstr "" +msgstr "PoczÄ…tek" #: mediagoblin/templates/mediagoblin/media_displays/stl.html:120 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:121 msgid "Top" -msgstr "" +msgstr "Góra" #: mediagoblin/templates/mediagoblin/media_displays/stl.html:124 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:125 msgid "Side" -msgstr "" +msgstr "KrawÄ™dź" #: mediagoblin/templates/mediagoblin/media_displays/stl.html:130 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:131 msgid "WebGL" -msgstr "" +msgstr "WebGL" #: mediagoblin/templates/mediagoblin/media_displays/stl.html:138 msgid "Download model" -msgstr "" +msgstr "Pobierz model" #: mediagoblin/templates/mediagoblin/media_displays/stl.html:146 msgid "File Format" -msgstr "" +msgstr "Format pliku" #: mediagoblin/templates/mediagoblin/media_displays/stl.html:148 msgid "Object Height" -msgstr "" +msgstr "Wysokość obiektu" #: mediagoblin/templates/mediagoblin/media_displays/video.html:44 msgid "" "Sorry, this video will not work because\n" " your web browser does not support HTML5 \n" " video." -msgstr "" +msgstr "Niestety ten materiaÅ‚ nie bÄ™dzie widocznyâŽ, ponieważ twoja przeglÄ…darka nie⎠osbÅ‚uguje formatu HTML5." #: mediagoblin/templates/mediagoblin/media_displays/video.html:47 msgid "" "You can get a modern web browser that \n" " can play this video at <a href=\"http://getfirefox.com\">\n" " http://getfirefox.com</a>!" -msgstr "" +msgstr "Możesz pobrać porzÄ…dnÄ… przeglÄ…darkÄ™, która jest w stanie odtworzyć ten materiaÅ‚ filmowy, ze strony <a href=\"http://getfirefox.com/\">⎠http://getfirefox.com</a>!" #: mediagoblin/templates/mediagoblin/media_displays/video.html:69 msgid "WebM file (640p; VP8/Vorbis)" @@ -822,19 +872,19 @@ msgstr "Na pewno usunąć %(title)s?" msgid "Really remove %(media_title)s from %(collection_title)s?" msgstr "Na pewno usunąć %(media_title)s z %(collection_title)s?" -#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:54 msgid "Remove" msgstr "UsuÅ„" #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:21 #, python-format msgid "%(username)s's collections" -msgstr "" +msgstr "kolekcja użytkownika %(username)s" #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:28 #, python-format msgid "<a href=\"%(user_url)s\">%(username)s</a>'s collections" -msgstr "" +msgstr "kolekcje użytkownika <a href=\"%(user_url)s\">%(username)s</a>" #: mediagoblin/templates/mediagoblin/user_pages/comment_email.txt:19 #, python-format @@ -853,7 +903,7 @@ msgstr "Media użytkownika %(username)s" msgid "" "<a href=\"%(user_url)s\">%(username)s</a>'s media with tag <a " "href=\"%(tag_url)s\">%(tag)s</a>" -msgstr "" +msgstr "pliki użytkownika <a href=\"%(user_url)s\">%(username)s</a> z tagiem <a href=\"%(tag_url)s\">%(tag)s</a>" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:48 #, python-format @@ -865,30 +915,34 @@ msgstr "media użytkownika <a href=\"%(user_url)s\">%(username)s</a>" 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:94 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:95 msgid "Add a comment" msgstr "Dodaj komentarz" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 msgid "Add this comment" msgstr "Dodaj komentarz" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:123 -msgid "at" -msgstr "na" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:144 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:132 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:152 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:164 #, python-format -msgid "" -"<h3>Added on</h3>\n" -" <p>%(date)s</p>" -msgstr "<h3>Dodane</h3>\n <p>%(date)s</p>" +msgid "%(formatted_time)s ago" +msgstr "%(formatted_time)s temu" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:150 +msgid "Added" +msgstr "Dodano" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:161 +msgid "Created" +msgstr "Utworzono" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:40 #, python-format msgid "Add “%(media_title)s†to a collection" -msgstr "" +msgstr "Dodaj “%(media_title)s†do kolekcji" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:54 msgid "+" @@ -967,7 +1021,7 @@ msgstr "Ten użytkownik nie wypeÅ‚niÅ‚ (jeszcze) opisu swojego profilu." #: mediagoblin/templates/mediagoblin/user_pages/user.html:124 msgid "Browse collections" -msgstr "" +msgstr "PrzeglÄ…daj kolekcje" #: mediagoblin/templates/mediagoblin/user_pages/user.html:137 #, python-format @@ -988,15 +1042,15 @@ msgstr "Tu nie ma jeszcze żadnych mediów..." #: mediagoblin/templates/mediagoblin/utils/collection_gallery.html:49 msgid "(remove)" -msgstr "" +msgstr "(usuÅ„)" #: mediagoblin/templates/mediagoblin/utils/collections.html:21 msgid "Collected in" -msgstr "" +msgstr "Znajduje siÄ™ w kolekcji " #: mediagoblin/templates/mediagoblin/utils/collections.html:40 msgid "Add to a collection" -msgstr "" +msgstr "Dodaj do kolekcji" #: mediagoblin/templates/mediagoblin/utils/feed_link.html:21 #: mediagoblin/themes/airy/templates/mediagoblin/utils/feed_link.html:21 @@ -1038,7 +1092,7 @@ msgstr "starsze" msgid "Tagged with" msgstr "Znaczniki:" -#: mediagoblin/tools/exif.py:80 +#: mediagoblin/tools/exif.py:83 msgid "Could not read the image file." msgstr "Nie udaÅ‚o siÄ™ odczytać pliku grafiki." @@ -1048,29 +1102,53 @@ msgstr "Ups!" #: mediagoblin/tools/response.py:36 msgid "An error occured" -msgstr "" +msgstr "WystÄ…piÅ‚ błąd" #: mediagoblin/tools/response.py:51 msgid "Operation not allowed" -msgstr "" +msgstr "Operacja niedozwolona" #: mediagoblin/tools/response.py:52 msgid "" "Sorry Dave, I can't let you do that!</p><p>You have tried to perform a " "function that you are not allowed to. Have you been trying to delete all " "user accounts again?" -msgstr "" +msgstr "Misiaczku, nie możesz tego uczynić!</p><p>PróbowaÅ‚eÅ› wykonać dziaÅ‚anie, do którego nie masz uprawnieÅ„. Czy naprawdÄ™ chciaÅ‚eÅ› skasować znowu wszystkie konta?" #: mediagoblin/tools/response.py:60 msgid "" "There doesn't seem to be a page at this address. Sorry!</p><p>If you're sure" " the address is correct, maybe the page you're looking for has been moved or" " deleted." -msgstr "" +msgstr "WyglÄ…da na to, że nic tutaj nie ma!</p><p>JeÅ›li jesteÅ› pewny, że adres jest prawidÅ‚owy, być może strona zostaÅ‚a skasowana lub przeniesiona." + +#: mediagoblin/tools/timesince.py:62 +msgid "year" +msgstr "rok" + +#: mediagoblin/tools/timesince.py:63 +msgid "month" +msgstr "miesiÄ…c" + +#: mediagoblin/tools/timesince.py:64 +msgid "week" +msgstr "tydzieÅ„" + +#: mediagoblin/tools/timesince.py:65 +msgid "day" +msgstr "dzieÅ„" + +#: mediagoblin/tools/timesince.py:66 +msgid "hour" +msgstr "godzina" + +#: mediagoblin/tools/timesince.py:67 +msgid "minute" +msgstr "minuta" #: mediagoblin/user_pages/forms.py:23 msgid "Comment" -msgstr "" +msgstr "Komentarz" #: mediagoblin/user_pages/forms.py:25 msgid "" @@ -1089,7 +1167,7 @@ msgstr "Na pewno chcÄ™ usunąć ten element z kolekcji" #: mediagoblin/user_pages/forms.py:39 msgid "Collection" -msgstr "" +msgstr "Kolekcja" #: mediagoblin/user_pages/forms.py:40 msgid "-- Select --" @@ -1099,73 +1177,77 @@ msgstr "-- wybierz --" msgid "Include a note" msgstr "Dodaj notatkÄ™" -#: mediagoblin/user_pages/lib.py:56 +#: mediagoblin/user_pages/lib.py:58 msgid "commented on your post" msgstr "komentarze do twojego wpisu" -#: mediagoblin/user_pages/views.py:166 +#: mediagoblin/user_pages/views.py:169 +msgid "Sorry, comments are disabled." +msgstr "Komentowanie jest wyłączone." + +#: mediagoblin/user_pages/views.py:174 msgid "Oops, your comment was empty." msgstr "Ups, twój komentarz nie zawieraÅ‚ treÅ›ci." -#: mediagoblin/user_pages/views.py:172 +#: mediagoblin/user_pages/views.py:180 msgid "Your comment has been posted!" msgstr "Twój komentarz zostaÅ‚ opublikowany!" -#: mediagoblin/user_pages/views.py:197 +#: mediagoblin/user_pages/views.py:205 msgid "Please check your entries and try again." msgstr "Sprawdź swoje wpisy i spróbuj ponownie." -#: mediagoblin/user_pages/views.py:237 +#: mediagoblin/user_pages/views.py:245 msgid "You have to select or add a collection" msgstr "Musisz wybrać lub dodać kolekcjÄ™" -#: mediagoblin/user_pages/views.py:248 +#: mediagoblin/user_pages/views.py:256 #, python-format msgid "\"%s\" already in collection \"%s\"" msgstr "\"%s\" już obecne w kolekcji \"%s\"" -#: mediagoblin/user_pages/views.py:264 +#: mediagoblin/user_pages/views.py:262 #, python-format msgid "\"%s\" added to collection \"%s\"" msgstr "\"%s\" dodano do kolekcji \"%s\"" -#: mediagoblin/user_pages/views.py:286 +#: mediagoblin/user_pages/views.py:282 msgid "You deleted the media." msgstr "Media zostaÅ‚y usuniÄ™te." -#: mediagoblin/user_pages/views.py:293 +#: mediagoblin/user_pages/views.py:289 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:301 +#: mediagoblin/user_pages/views.py:296 msgid "You are about to delete another user's media. Proceed with caution." msgstr "Za chwilÄ™ usuniesz media innego użytkownika. Zachowaj ostrożność." -#: mediagoblin/user_pages/views.py:375 +#: mediagoblin/user_pages/views.py:370 msgid "You deleted the item from the collection." msgstr "Element zostaÅ‚ usuniÄ™ty z kolekcji." -#: mediagoblin/user_pages/views.py:379 +#: mediagoblin/user_pages/views.py:374 msgid "The item was not removed because you didn't check that you were sure." msgstr "Ten element nie zostaÅ‚ usuniÄ™ty, ponieważ nie zaznaczono, że jesteÅ› pewien." -#: mediagoblin/user_pages/views.py:389 +#: mediagoblin/user_pages/views.py:382 msgid "" "You are about to delete an item from another user's collection. Proceed with" " caution." msgstr "Zamierzasz usunąć element z kolekcji innego użytkownika. Zachowaj ostrożność." -#: mediagoblin/user_pages/views.py:422 +#: mediagoblin/user_pages/views.py:415 #, python-format msgid "You deleted the collection \"%s\"" msgstr "UsuniÄ™to kolekcjÄ™ \"%s\"" -#: mediagoblin/user_pages/views.py:429 +#: mediagoblin/user_pages/views.py:422 msgid "" "The collection was not deleted because you didn't check that you were sure." msgstr "Ta kolekcja nie zostaÅ‚a usuniÄ™ta, ponieważ nie zaznaczono, że jesteÅ› pewien." -#: mediagoblin/user_pages/views.py:439 +#: mediagoblin/user_pages/views.py:430 msgid "" "You are about to delete another user's collection. Proceed with caution." msgstr "Zamierzasz usunąć kolekcjÄ™ 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 Binary files differindex af50e027..5e83a7f2 100644 --- a/mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.mo +++ b/mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.po index 3b2ed203..fecb844c 100644 --- a/mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/pt_BR/LC_MESSAGES/mediagoblin.po @@ -3,16 +3,17 @@ # This file is distributed under the same license as the PROJECT project. # # Translators: -# Rafael Ferreira <rafael.f.f1@gmail.com>, 2013. -# <snd.noise@gmail.com>, 2011. -# ufa <ufa@technotroll.org>, 2011. -# Vinicius SM <viniciussm@rocketmail.com>, 2013. +# osc <snd.noise@gmail.com>, 2013 +# Rafael Ferreira <rafael.f.f1@gmail.com>, 2013 +# osc <snd.noise@gmail.com>, 2011 +# ufa <ufa@technotroll.org>, 2011 +# Canopus <viniciussm@rocketmail.com>, 2013 msgid "" msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" -"POT-Creation-Date: 2013-03-04 18:04-0600\n" -"PO-Revision-Date: 2013-03-05 00:04+0000\n" +"POT-Creation-Date: 2013-05-27 13:54-0500\n" +"PO-Revision-Date: 2013-05-27 18:54+0000\n" "Last-Translator: cwebber <cwebber@dustycloud.org>\n" "Language-Team: Portuguese (Brazil) (http://www.transifex.com/projects/p/mediagoblin/language/pt_BR/)\n" "MIME-Version: 1.0\n" @@ -22,34 +23,39 @@ msgstr "" "Language: pt_BR\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: mediagoblin/auth/forms.py:28 -msgid "Invalid User name or email address." -msgstr "Nome de usuário ou email inválido." - -#: mediagoblin/auth/forms.py:29 -msgid "This field does not take email addresses." -msgstr "Este campo não aceita endereços de email." - -#: mediagoblin/auth/forms.py:30 -msgid "This field requires an email address." -msgstr "Este campo requer um endereço de email." - -#: mediagoblin/auth/forms.py:52 mediagoblin/auth/forms.py:67 +#: mediagoblin/auth/forms.py:26 msgid "Username" msgstr "Nome de Usuário" -#: mediagoblin/auth/forms.py:56 mediagoblin/auth/forms.py:71 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 +#: mediagoblin/tests/test_util.py:110 msgid "Password" msgstr "Senha" -#: mediagoblin/auth/forms.py:60 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "Endereço de email" -#: mediagoblin/auth/forms.py:78 +#: mediagoblin/auth/forms.py:41 +msgid "Username or Email" +msgstr "" + +#: mediagoblin/auth/forms.py:52 msgid "Username or email" msgstr "Nome de usuário ou email" +#: mediagoblin/auth/tools.py:31 +msgid "Invalid User name or email address." +msgstr "Nome de usuário ou email inválido." + +#: mediagoblin/auth/tools.py:32 +msgid "This field does not take email addresses." +msgstr "Este campo não aceita endereços de email." + +#: mediagoblin/auth/tools.py:33 +msgid "This field requires an email address." +msgstr "Este campo requer um endereço de email." + #: mediagoblin/auth/views.py:54 msgid "Sorry, registration is disabled on this instance." msgstr "Desculpa, o registro está desativado neste momento." @@ -62,54 +68,54 @@ msgstr "Desculpe, um usuário com este nome já existe." msgid "Sorry, a user with that email address already exists." msgstr "Desculpe, um usuário com esse email já está cadastrado" -#: mediagoblin/auth/views.py:174 +#: 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!" -#: mediagoblin/auth/views.py:180 +#: 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:198 +#: mediagoblin/auth/views.py:206 msgid "You must be logged in so we know who to send the email to!" msgstr "Você precisa entrar primeiro para sabermos para quem mandar o email!" -#: mediagoblin/auth/views.py:206 +#: mediagoblin/auth/views.py:214 msgid "You've already verified your email address!" msgstr "Você já verificou seu email!" -#: mediagoblin/auth/views.py:219 +#: mediagoblin/auth/views.py:227 msgid "Resent your verification email." msgstr "O email de verificação foi enviado novamente." -#: mediagoblin/auth/views.py:250 +#: mediagoblin/auth/views.py:258 msgid "" "If that email address (case sensitive!) is registered an email has been sent" " with instructions on how to change your password." -msgstr "" +msgstr "Se esse endereço de email (sensÃvel a maiúsculo/minúsculo!) estiver registrado, um email será enviado com instruções para alterar sua senha." -#: mediagoblin/auth/views.py:261 +#: mediagoblin/auth/views.py:269 msgid "Couldn't find someone with that username." msgstr "Não foi possÃvel encontrar alguém com esse nome de usuário." -#: mediagoblin/auth/views.py:264 +#: mediagoblin/auth/views.py:272 msgid "" "An email has been sent with instructions on how to change your password." msgstr "Um email foi enviado com instruções para trocar sua senha." -#: mediagoblin/auth/views.py:271 +#: mediagoblin/auth/views.py:279 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." msgstr "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:328 +#: mediagoblin/auth/views.py:336 msgid "You can now log in using your new password." msgstr "Agora você pode entrar usando sua nova senha." -#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:93 +#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:82 #: mediagoblin/submit/forms.py:28 mediagoblin/submit/forms.py:47 #: mediagoblin/user_pages/forms.py:45 msgid "Title" @@ -120,7 +126,7 @@ msgid "Description of this work" msgstr "Descrição desse trabalho" #: mediagoblin/edit/forms.py:29 mediagoblin/edit/forms.py:52 -#: mediagoblin/edit/forms.py:97 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:86 mediagoblin/submit/forms.py:32 #: mediagoblin/submit/forms.py:51 mediagoblin/user_pages/forms.py:49 msgid "" "You can use\n" @@ -136,11 +142,11 @@ msgstr "Etiquetas" msgid "Separate tags by commas." msgstr "Separe as etiquetas com vÃrgulas." -#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:101 +#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:90 msgid "Slug" msgstr "Arquivo" -#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:102 +#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:91 msgid "The slug can't be empty" msgstr "O arquivo não pode estar vazio" @@ -168,45 +174,45 @@ msgid "This address contains errors" msgstr "Este endereço contém erros" #: mediagoblin/edit/forms.py:63 -msgid "Old password" -msgstr "Senha antiga" - -#: mediagoblin/edit/forms.py:64 -msgid "Enter your old password to prove you own this account." -msgstr "Digite sua senha antiga para provar que esta conta é sua." - -#: mediagoblin/edit/forms.py:67 -msgid "New password" -msgstr "Nova senha" - -#: mediagoblin/edit/forms.py:74 msgid "License preference" msgstr "Licença preferida" -#: mediagoblin/edit/forms.py:80 +#: mediagoblin/edit/forms.py:69 msgid "This will be your default license on upload forms." msgstr "Esta será sua licença padrão nos formulários de envio." -#: mediagoblin/edit/forms.py:82 +#: mediagoblin/edit/forms.py:71 msgid "Email me when others comment on my media" msgstr "Me enviar um email quando outras pessoas comentarem em minhas mÃdias" -#: mediagoblin/edit/forms.py:94 +#: mediagoblin/edit/forms.py:83 msgid "The title can't be empty" msgstr "O tÃtulo não pode ficar vazio" -#: mediagoblin/edit/forms.py:96 mediagoblin/submit/forms.py:50 +#: mediagoblin/edit/forms.py:85 mediagoblin/submit/forms.py:50 #: mediagoblin/user_pages/forms.py:48 msgid "Description of this collection" msgstr "Descrição desta coleção" -#: mediagoblin/edit/forms.py:103 +#: mediagoblin/edit/forms.py:92 msgid "" "The title part of this collection's address. You usually don't need to " "change this." msgstr "A parte do tÃtulo do endereço dessa coleção. Geralmente você não precisa mudar isso." -#: mediagoblin/edit/views.py:66 +#: mediagoblin/edit/forms.py:99 +msgid "Old password" +msgstr "Senha antiga" + +#: mediagoblin/edit/forms.py:101 +msgid "Enter your old password to prove you own this account." +msgstr "Digite sua senha antiga para provar que esta conta é sua." + +#: mediagoblin/edit/forms.py:104 +msgid "New password" +msgstr "Nova senha" + +#: 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" @@ -231,44 +237,63 @@ msgstr "Você está editando um perfil de usuário. Tenha cuidado." msgid "Profile changes saved" msgstr "As mudanças no perfil foram salvas" -#: mediagoblin/edit/views.py:241 -msgid "Wrong password" -msgstr "Senha errada" - -#: mediagoblin/edit/views.py:252 +#: mediagoblin/edit/views.py:240 msgid "Account settings saved" msgstr "As mudanças na conta foram salvas" -#: mediagoblin/edit/views.py:286 +#: mediagoblin/edit/views.py:274 msgid "You need to confirm the deletion of your account." msgstr "Você precisa confirmar a exclusão da sua conta." -#: mediagoblin/edit/views.py:322 mediagoblin/submit/views.py:142 -#: mediagoblin/user_pages/views.py:214 +#: mediagoblin/edit/views.py:310 mediagoblin/submit/views.py:138 +#: mediagoblin/user_pages/views.py:222 #, python-format msgid "You already have a collection called \"%s\"!" msgstr "Você já tem uma coleção chamada \"%s\"!" -#: mediagoblin/edit/views.py:326 +#: mediagoblin/edit/views.py:314 msgid "A collection with that slug already exists for this user." msgstr "Já existe uma coleção com este arquivo para este usuário." -#: mediagoblin/edit/views.py:343 +#: mediagoblin/edit/views.py:329 msgid "You are editing another user's collection. Proceed with caution." msgstr "Você está editando a coleção de um outro usuário. Prossiga com cuidado." -#: mediagoblin/gmg_commands/theme.py:58 +#: mediagoblin/edit/views.py:348 +msgid "Wrong password" +msgstr "Senha errada" + +#: mediagoblin/edit/views.py:363 +msgid "Your password was changed successfully" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:60 msgid "Cannot link theme... no theme set\n" msgstr "Não é possÃvel fazer link de tema... nenhum tema definido\n" -#: mediagoblin/gmg_commands/theme.py:71 +#: mediagoblin/gmg_commands/assetlink.py:73 msgid "No asset directory for this theme\n" msgstr "" -#: mediagoblin/gmg_commands/theme.py:74 +#: mediagoblin/gmg_commands/assetlink.py:76 msgid "However, old link directory symlink found; removed.\n" msgstr "" +#: mediagoblin/gmg_commands/assetlink.py:112 +#, python-format +msgid "Could not link \"%s\": %s exists and is not a symlink\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:119 +#, python-format +msgid "Skipping \"%s\"; already set up.\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:124 +#, python-format +msgid "Old link found for \"%s\"; removing.\n" +msgstr "" + #: mediagoblin/meddleware/csrf.py:134 msgid "" "CSRF cookie not present. This is most likely the result of a cookie blocker " @@ -276,12 +301,16 @@ msgid "" "domain." msgstr "Cookie CSFR não está presente. Isso é provavelmente o resultado de um bloqueador de cookies ou algo do tipo.<br/>Tenha certeza de autorizar este domÃnio a configurar cookies." -#: mediagoblin/media_types/__init__.py:61 -#: mediagoblin/media_types/__init__.py:102 +#: mediagoblin/media_types/__init__.py:111 +#: mediagoblin/media_types/__init__.py:155 msgid "Sorry, I don't support that file type :(" msgstr "Desculpe, não tenho suporte a este tipo de arquivo :(" -#: mediagoblin/media_types/video/processing.py:36 +#: mediagoblin/media_types/pdf/processing.py:136 +msgid "unoconv failing to run, check log file" +msgstr "" + +#: mediagoblin/media_types/video/processing.py:37 msgid "Video transcoding failed" msgstr "Conversão do vÃdeo falhou" @@ -348,7 +377,7 @@ msgstr "" msgid "This field is required for public clients" msgstr "Este campo é necessário para clientes públicos" -#: mediagoblin/plugins/oauth/views.py:59 +#: mediagoblin/plugins/oauth/views.py:56 msgid "The client {0} has been registered!" msgstr "O cliente {0} foi registrado!" @@ -367,7 +396,7 @@ msgstr "Seus clientes OAuth" msgid "Add" msgstr "Adicionar" -#: mediagoblin/processing/__init__.py:172 +#: mediagoblin/processing/__init__.py:193 msgid "Invalid file given for media type." msgstr "Arquivo inválido para esse tipo de mÃdia" @@ -375,45 +404,45 @@ msgstr "Arquivo inválido para esse tipo de mÃdia" msgid "File" msgstr "Arquivo" -#: mediagoblin/submit/views.py:51 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "Você deve fornecer um arquivo." -#: mediagoblin/submit/views.py:97 +#: mediagoblin/submit/views.py:93 msgid "Woohoo! Submitted!" msgstr "Eba! Enviado!" -#: mediagoblin/submit/views.py:146 +#: mediagoblin/submit/views.py:144 #, python-format msgid "Collection \"%s\" added!" msgstr "Coleção \"%s\" adicionada!" -#: mediagoblin/templates/mediagoblin/base.html:64 +#: mediagoblin/templates/mediagoblin/base.html:67 msgid "Verify your email!" msgstr "Verifique seu email!" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:68 msgid "log out" msgstr "sair" -#: mediagoblin/templates/mediagoblin/base.html:70 +#: mediagoblin/templates/mediagoblin/base.html:73 #: mediagoblin/templates/mediagoblin/auth/login.html:28 #: mediagoblin/templates/mediagoblin/auth/login.html:36 #: mediagoblin/templates/mediagoblin/auth/login.html:54 msgid "Log in" msgstr "Entrar" -#: mediagoblin/templates/mediagoblin/base.html:79 +#: mediagoblin/templates/mediagoblin/base.html:82 #, python-format msgid "<a href=\"%(user_url)s\">%(user_name)s</a>'s account" msgstr "Conta de <a href=\"%(user_url)s\">%(user_name)s</a>" -#: mediagoblin/templates/mediagoblin/base.html:86 +#: mediagoblin/templates/mediagoblin/base.html:89 msgid "Change account settings" msgstr "Mudar configurações da conta" -#: mediagoblin/templates/mediagoblin/base.html:90 -#: mediagoblin/templates/mediagoblin/base.html:105 +#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:108 #: mediagoblin/templates/mediagoblin/admin/panel.html:21 #: mediagoblin/templates/mediagoblin/admin/panel.html:26 #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:21 @@ -421,72 +450,25 @@ msgstr "Mudar configurações da conta" msgid "Media processing panel" msgstr "Painel de processamento de mÃdia" -#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:96 msgid "Log out" -msgstr "" +msgstr "Sair" -#: mediagoblin/templates/mediagoblin/base.html:96 +#: mediagoblin/templates/mediagoblin/base.html:99 #: mediagoblin/templates/mediagoblin/user_pages/user.html:156 msgid "Add media" msgstr "Adicionar mÃdia" -#: mediagoblin/templates/mediagoblin/base.html:99 +#: mediagoblin/templates/mediagoblin/base.html:102 #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:41 msgid "Create new collection" msgstr "Criar nova coleção" -#: mediagoblin/templates/mediagoblin/base.html:122 -#, python-format -msgid "" -"Powered by <a href=\"http://mediagoblin.org/\" title='Version " -"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." -msgstr "" - -#: mediagoblin/templates/mediagoblin/base.html:125 -#, 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 "Lançado sob a <a href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a href=\"%(source_link)s\">Código fonte</a> disponÃvel." - #: mediagoblin/templates/mediagoblin/error.html:24 msgid "Image of goblin stressing out" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:31 -msgid "Explore" -msgstr "Explorar" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "Olá, bem-vindo a este site MediaGoblin." - -#: mediagoblin/templates/mediagoblin/root.html:35 -msgid "" -"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, an " -"extraordinarily great piece of media hosting software." -msgstr "Este site roda o <a href=\"http://mediagoblin.org\">MediaGoblin</a>, um programa excelente para hospedar, gerenciar e compartilhar mÃdia." - -#: mediagoblin/templates/mediagoblin/root.html:36 -msgid "" -"To add your own media, place comments, and more, you can log in with your " -"MediaGoblin account." -msgstr "Para adicionar sua própria mÃdia, publicar comentários e mais outras coisas, você pode entrar com sua conta MediaGoblin." - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Don't have one yet? It's easy!" -msgstr " Ainda não tem uma conta? É facil!" - -#: mediagoblin/templates/mediagoblin/root.html:39 -#, 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\">Criar uma conta neste site</a>\nou\n<a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">Configurar MediaGoblin em seu próprio servidor</a>" +msgstr "Imagem do goblin se estressando" -#: mediagoblin/templates/mediagoblin/root.html:47 +#: mediagoblin/templates/mediagoblin/root.html:32 msgid "Most recent media" msgstr "MÃdia mais recente" @@ -592,6 +574,53 @@ msgid "" "%(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/bits/base_footer.html:21 +#, python-format +msgid "" +"Powered by <a href=\"http://mediagoblin.org/\" title='Version " +"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." +msgstr "Fornecido pelo <a href=\"http://mediagoblin.org/\" title='Version %(version)s'>MediaGoblin</a>, um projeto <a href=\"http://gnu.org/\">GNU</a>." + +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:24 +#, 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 "Lançado sob a <a href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a href=\"%(source_link)s\">Código fonte</a> disponÃvel." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:20 +msgid "Explore" +msgstr "Explorar" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:22 +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "Olá, bem-vindo a este site MediaGoblin." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:24 +msgid "" +"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, an " +"extraordinarily great piece of media hosting software." +msgstr "Este site roda o <a href=\"http://mediagoblin.org\">MediaGoblin</a>, um programa excelente para hospedar, gerenciar e compartilhar mÃdia." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:25 +msgid "" +"To add your own media, place comments, and more, you can log in with your " +"MediaGoblin account." +msgstr "Para adicionar sua própria mÃdia, publicar comentários e mais outras coisas, você pode entrar com sua conta MediaGoblin." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:27 +msgid "Don't have one yet? It's easy!" +msgstr " Ainda não tem uma conta? É facil!" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:28 +#, 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/bits/logo.html:23 #: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 msgid "MediaGoblin logo" @@ -604,13 +633,13 @@ msgid "Editing attachments for %(media_title)s" msgstr "Editando os anexos de %(media_title)s" #: mediagoblin/templates/mediagoblin/edit/attachments.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:159 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:175 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:182 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:198 msgid "Attachments" msgstr "Anexos" #: mediagoblin/templates/mediagoblin/edit/attachments.html:57 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:181 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:204 msgid "Add attachment" msgstr "Adicionar anexo" @@ -627,12 +656,22 @@ msgstr "Cancelar" #: mediagoblin/templates/mediagoblin/edit/attachments.html:63 #: mediagoblin/templates/mediagoblin/edit/edit.html:42 -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:52 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:55 #: mediagoblin/templates/mediagoblin/edit/edit_collection.html:33 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:40 msgid "Save changes" msgstr "Salvar mudanças" +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:28 +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 +#, python-format +msgid "Changing %(username)s's password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 +msgid "Save" +msgstr "" + #: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 #, python-format msgid "Really delete user '%(user_name)s' and all related media/comments?" @@ -643,7 +682,7 @@ msgid "Yes, really delete my account" msgstr "Sim, realmente deletar minha conta" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:48 #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49 msgid "Delete permanently" msgstr "Deletar permanentemente" @@ -660,7 +699,11 @@ msgstr "Editando %(media_title)s" msgid "Changing %(username)s's account settings" msgstr "Alterando as configurações da conta de %(username)s" -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:59 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 +msgid "Change your password." +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 msgid "Delete my account" msgstr "Deletar minha conta" @@ -685,6 +728,7 @@ msgstr "Etiquetas desta mÃdia: %(tag_name)s" #: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 #: mediagoblin/templates/mediagoblin/media_displays/audio.html:56 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:65 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:136 #: mediagoblin/templates/mediagoblin/media_displays/video.html:55 msgid "Download" @@ -709,6 +753,7 @@ msgid "" msgstr "Você pode obter um navegador moderno\n »capaz de reproduzir o áudio em <a href=\"http://getfirefox.com\">\n » http://getfirefox.com</a>!" #: mediagoblin/templates/mediagoblin/media_displays/audio.html:60 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:71 #: mediagoblin/templates/mediagoblin/media_displays/video.html:61 msgid "Original file" msgstr "Arquivo original" @@ -717,6 +762,7 @@ msgstr "Arquivo original" msgid "WebM file (Vorbis codec)" msgstr "Arquivo WebM (codec Vorbis)" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:59 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:87 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:93 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:99 @@ -727,6 +773,10 @@ msgstr "Arquivo WebM (codec Vorbis)" msgid "Image for %(media_title)s" msgstr "Imagem para %(media_title)s" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 +msgid "PDF file" +msgstr "" + #: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 msgid "Toggle Rotate" msgstr "Alternar Rotação" @@ -825,7 +875,7 @@ msgstr "Realmente apagar %(title)s ?" msgid "Really remove %(media_title)s from %(collection_title)s?" msgstr "Realmente remover %(media_title)s de %(collection_title)s?" -#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:54 msgid "Remove" msgstr "Apagar" @@ -856,7 +906,7 @@ msgstr "MÃdia de %(username)s's" msgid "" "<a href=\"%(user_url)s\">%(username)s</a>'s media with tag <a " "href=\"%(tag_url)s\">%(tag)s</a>" -msgstr "" +msgstr "MÃdias de <a href=\"%(user_url)s\">%(username)s</a> com a etiqueta <a href=\"%(tag_url)s\">%(tag)s</a>" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:48 #, python-format @@ -868,24 +918,28 @@ msgstr "MÃdia de <a href=\"%(user_url)s\"> %(username)s </a> " msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>" msgstr "â– Vendo mÃdia de <a href=\"%(user_url)s\">%(username)s</a>" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:94 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:95 msgid "Add a comment" msgstr "Adicionar um comentário" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 msgid "Add this comment" msgstr "Adicionar este comentário" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:123 -msgid "at" -msgstr "em" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:144 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:132 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:152 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:164 #, python-format -msgid "" -"<h3>Added on</h3>\n" -" <p>%(date)s</p>" -msgstr "<h3>Adicionado em</h3>\n<p>%(date)s</p>" +msgid "%(formatted_time)s ago" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:150 +msgid "Added" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:161 +msgid "Created" +msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:40 @@ -987,7 +1041,7 @@ msgstr "Aqui é onde sua mÃdia vai aparecer, mas parece que você não adiciono #: mediagoblin/templates/mediagoblin/utils/collection_gallery.html:84 #: mediagoblin/templates/mediagoblin/utils/object_gallery.html:70 msgid "There doesn't seem to be any media here yet..." -msgstr "Aparentemente não há nenhuma mÃdia aqui ainda..." +msgstr "Parece que ainda não há nenhuma mÃdia por aqui..." #: mediagoblin/templates/mediagoblin/utils/collection_gallery.html:49 msgid "(remove)" @@ -999,7 +1053,7 @@ msgstr "" #: mediagoblin/templates/mediagoblin/utils/collections.html:40 msgid "Add to a collection" -msgstr "" +msgstr "Adicionar a uma coleção" #: mediagoblin/templates/mediagoblin/utils/feed_link.html:21 #: mediagoblin/themes/airy/templates/mediagoblin/utils/feed_link.html:21 @@ -1041,7 +1095,7 @@ msgstr "mais antiga" msgid "Tagged with" msgstr "Etiquetas" -#: mediagoblin/tools/exif.py:80 +#: mediagoblin/tools/exif.py:83 msgid "Could not read the image file." msgstr "Não foi possÃvel ler o arquivo de imagem." @@ -1071,6 +1125,30 @@ msgid "" " deleted." msgstr "Parece que não há uma página com este endereço. Desculpe!</p><p>Se você tem certeza que este endereço está correto, talvez a página que esteja procurando tenha sido movida ou deletada." +#: mediagoblin/tools/timesince.py:62 +msgid "year" +msgstr "" + +#: mediagoblin/tools/timesince.py:63 +msgid "month" +msgstr "" + +#: mediagoblin/tools/timesince.py:64 +msgid "week" +msgstr "" + +#: mediagoblin/tools/timesince.py:65 +msgid "day" +msgstr "" + +#: mediagoblin/tools/timesince.py:66 +msgid "hour" +msgstr "" + +#: mediagoblin/tools/timesince.py:67 +msgid "minute" +msgstr "" + #: mediagoblin/user_pages/forms.py:23 msgid "Comment" msgstr "Comentário" @@ -1096,79 +1174,83 @@ msgstr "Coleção" #: mediagoblin/user_pages/forms.py:40 msgid "-- Select --" -msgstr "" +msgstr "-- Selecionar --" #: mediagoblin/user_pages/forms.py:42 msgid "Include a note" msgstr "Incluir uma nota" -#: mediagoblin/user_pages/lib.py:56 +#: mediagoblin/user_pages/lib.py:58 msgid "commented on your post" msgstr "comentou na sua publicação" -#: mediagoblin/user_pages/views.py:166 +#: mediagoblin/user_pages/views.py:169 +msgid "Sorry, comments are disabled." +msgstr "" + +#: mediagoblin/user_pages/views.py:174 msgid "Oops, your comment was empty." msgstr "Ops, seu comentário estava vazio." -#: mediagoblin/user_pages/views.py:172 +#: mediagoblin/user_pages/views.py:180 msgid "Your comment has been posted!" msgstr "Seu comentário foi postado!" -#: mediagoblin/user_pages/views.py:197 +#: mediagoblin/user_pages/views.py:205 msgid "Please check your entries and try again." -msgstr "" +msgstr "Por favor, verifique suas entradas e tente novamente." -#: mediagoblin/user_pages/views.py:237 +#: mediagoblin/user_pages/views.py:245 msgid "You have to select or add a collection" msgstr "Você deve selecionar ou adicionar uma coleção" -#: mediagoblin/user_pages/views.py:248 +#: mediagoblin/user_pages/views.py:256 #, python-format msgid "\"%s\" already in collection \"%s\"" msgstr "\"%s\" já está na coleção \"%s\"" -#: mediagoblin/user_pages/views.py:264 +#: mediagoblin/user_pages/views.py:262 #, python-format msgid "\"%s\" added to collection \"%s\"" msgstr "\"%s\" adicionado à coleção \"%s\"" -#: mediagoblin/user_pages/views.py:286 +#: mediagoblin/user_pages/views.py:282 msgid "You deleted the media." msgstr "Você deletou a mÃdia." -#: mediagoblin/user_pages/views.py:293 +#: mediagoblin/user_pages/views.py:289 msgid "The media was not deleted because you didn't check that you were sure." msgstr "A mÃdia não foi apagada porque você não marcou que tinha certeza." -#: mediagoblin/user_pages/views.py:301 +#: mediagoblin/user_pages/views.py:296 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." -#: mediagoblin/user_pages/views.py:375 +#: mediagoblin/user_pages/views.py:370 msgid "You deleted the item from the collection." msgstr "Você deletou o item da coleção." -#: mediagoblin/user_pages/views.py:379 +#: mediagoblin/user_pages/views.py:374 msgid "The item was not removed because you didn't check that you were sure." msgstr "O item não foi apagado porque você não marcou que tinha certeza." -#: mediagoblin/user_pages/views.py:389 +#: mediagoblin/user_pages/views.py:382 msgid "" "You are about to delete an item from another user's collection. Proceed with" " caution." msgstr "Você está prestes a remover um item da coleção de um outro usuário. Prossiga com cuidado." -#: mediagoblin/user_pages/views.py:422 +#: mediagoblin/user_pages/views.py:415 #, python-format msgid "You deleted the collection \"%s\"" msgstr "Você deletou a coleção \"%s\"" -#: mediagoblin/user_pages/views.py:429 +#: mediagoblin/user_pages/views.py:422 msgid "" "The collection was not deleted because you didn't check that you were sure." msgstr "A coleção não foi apagada porque você não marcou que tinha certeza." -#: mediagoblin/user_pages/views.py:439 +#: mediagoblin/user_pages/views.py:430 msgid "" "You are about to delete another user's collection. Proceed with caution." msgstr "Você está prestes a deletar a coleção de um outro usuário. Prossiga com cuidado." diff --git a/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.mo Binary files differindex 62cbf028..8cfdf339 100644 --- a/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.mo +++ b/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.po index da585d5c..af2d94d6 100644 --- a/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/ro/LC_MESSAGES/mediagoblin.po @@ -3,14 +3,14 @@ # This file is distributed under the same license as the PROJECT project. # # Translators: -# <gapop@hotmail.com>, 2011. -# George Pop <gapop@hotmail.com>, 2011-2013. +# George Pop <gapop@hotmail.com>, 2011 +# George Pop <gapop@hotmail.com>, 2011-2013 msgid "" msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" -"POT-Creation-Date: 2013-03-04 18:04-0600\n" -"PO-Revision-Date: 2013-03-10 04:13+0000\n" +"POT-Creation-Date: 2013-05-27 13:54-0500\n" +"PO-Revision-Date: 2013-05-27 20:40+0000\n" "Last-Translator: George Pop <gapop@hotmail.com>\n" "Language-Team: Romanian (http://www.transifex.com/projects/p/mediagoblin/language/ro/)\n" "MIME-Version: 1.0\n" @@ -20,34 +20,39 @@ msgstr "" "Language: ro\n" "Plural-Forms: nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));\n" -#: mediagoblin/auth/forms.py:28 -msgid "Invalid User name or email address." -msgstr "Nume de utilizator sau adresă de e-mail nevalidă." - -#: mediagoblin/auth/forms.py:29 -msgid "This field does not take email addresses." -msgstr "Această rubrică nu este pentru adrese de e-mail." - -#: mediagoblin/auth/forms.py:30 -msgid "This field requires an email address." -msgstr "Această rubrică trebuie completată cu o adresă de e-mail." - -#: mediagoblin/auth/forms.py:52 mediagoblin/auth/forms.py:67 +#: mediagoblin/auth/forms.py:26 msgid "Username" msgstr "Nume de utilizator" -#: mediagoblin/auth/forms.py:56 mediagoblin/auth/forms.py:71 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 +#: mediagoblin/tests/test_util.py:110 msgid "Password" msgstr "Parolă" -#: mediagoblin/auth/forms.py:60 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "Adresa de e-mail" -#: mediagoblin/auth/forms.py:78 +#: mediagoblin/auth/forms.py:41 +msgid "Username or Email" +msgstr "Numele de utilizator sau adresa de e-mail" + +#: mediagoblin/auth/forms.py:52 msgid "Username or email" msgstr "Numele de utilizator sau adresa de e-mail" +#: mediagoblin/auth/tools.py:31 +msgid "Invalid User name or email address." +msgstr "Nume de utilizator sau adresă de e-mail nevalidă." + +#: mediagoblin/auth/tools.py:32 +msgid "This field does not take email addresses." +msgstr "Această rubrică nu este pentru adrese de e-mail." + +#: mediagoblin/auth/tools.py:33 +msgid "This field requires an email address." +msgstr "Această rubrică trebuie completată cu o adresă de e-mail." + #: mediagoblin/auth/views.py:54 msgid "Sorry, registration is disabled on this instance." msgstr "Ne pare rău, dar înscrierile sunt dezactivate pe acest server." @@ -60,54 +65,54 @@ msgstr "Ne pare rău, există deja un utilizator cu acelaÈ™i nume." msgid "Sorry, a user with that email address already exists." msgstr "Există deja un utilizator înregistrat cu această adresă de e-mail." -#: mediagoblin/auth/views.py:174 +#: 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!" -#: mediagoblin/auth/views.py:180 +#: 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:198 +#: 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:206 +#: 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:219 +#: mediagoblin/auth/views.py:227 msgid "Resent your verification email." msgstr "E-mail-ul de verificare a fost retrimis." -#: mediagoblin/auth/views.py:250 +#: mediagoblin/auth/views.py:258 msgid "" "If that email address (case sensitive!) is registered an email has been sent" " with instructions on how to change your password." msgstr "Dacă adresa de e-mail este în baza noastră de date, atunci se va trimite imediat un mesaj cu instrucÈ›iuni pentru schimbarea parolei. ÈšineÈ›i cont de litere mari / litere mici la introducerea adresei!" -#: mediagoblin/auth/views.py:261 +#: mediagoblin/auth/views.py:269 msgid "Couldn't find someone with that username." msgstr "Nu există nimeni cu acest nume de utilizator." -#: mediagoblin/auth/views.py:264 +#: mediagoblin/auth/views.py:272 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:271 +#: mediagoblin/auth/views.py:279 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." msgstr "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:328 +#: mediagoblin/auth/views.py:336 msgid "You can now log in using your new password." msgstr "Acum te poÈ›i autentifica cu noua parolă." -#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:93 +#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:82 #: mediagoblin/submit/forms.py:28 mediagoblin/submit/forms.py:47 #: mediagoblin/user_pages/forms.py:45 msgid "Title" @@ -118,7 +123,7 @@ msgid "Description of this work" msgstr "Descrierea acestui fiÈ™ier" #: mediagoblin/edit/forms.py:29 mediagoblin/edit/forms.py:52 -#: mediagoblin/edit/forms.py:97 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:86 mediagoblin/submit/forms.py:32 #: mediagoblin/submit/forms.py:51 mediagoblin/user_pages/forms.py:49 msgid "" "You can use\n" @@ -134,11 +139,11 @@ msgstr "Cuvinte-cheie" msgid "Separate tags by commas." msgstr "Desparte cuvintele-cheie prin virgulă." -#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:101 +#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:90 msgid "Slug" msgstr "Identificator" -#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:102 +#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:91 msgid "The slug can't be empty" msgstr "Identificatorul nu poate să lipsească" @@ -166,45 +171,45 @@ 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:64 -msgid "Enter your old password to prove you own this account." -msgstr "Introdu vechea parolă pentru a demonstra că eÈ™ti titularul acestui cont." - -#: mediagoblin/edit/forms.py:67 -msgid "New password" -msgstr "Noua parolă" - -#: mediagoblin/edit/forms.py:74 msgid "License preference" msgstr "LicenÈ›a preferată" -#: mediagoblin/edit/forms.py:80 +#: mediagoblin/edit/forms.py:69 msgid "This will be your default license on upload forms." msgstr "Aceasta va fi licenÈ›a implicită pe formularele de upload." -#: mediagoblin/edit/forms.py:82 +#: mediagoblin/edit/forms.py:71 msgid "Email me when others comment on my media" msgstr "Trimite-mi un e-mail când alÈ›ii comentează fiÈ™ierele mele" -#: mediagoblin/edit/forms.py:94 +#: mediagoblin/edit/forms.py:83 msgid "The title can't be empty" msgstr "Titlul nu poate să fie gol" -#: mediagoblin/edit/forms.py:96 mediagoblin/submit/forms.py:50 +#: mediagoblin/edit/forms.py:85 mediagoblin/submit/forms.py:50 #: mediagoblin/user_pages/forms.py:48 msgid "Description of this collection" msgstr "Descriere pentru această colecÈ›ie" -#: mediagoblin/edit/forms.py:103 +#: mediagoblin/edit/forms.py:92 msgid "" "The title part of this collection's address. You usually don't need to " "change this." msgstr "Partea din adresa acestei colecÈ›ii care corespunde titlului. De regulă nu e necesar să faci o modificare." -#: mediagoblin/edit/views.py:66 +#: mediagoblin/edit/forms.py:99 +msgid "Old password" +msgstr "Vechea parolă" + +#: mediagoblin/edit/forms.py:101 +msgid "Enter your old password to prove you own this account." +msgstr "Introdu vechea parolă pentru a demonstra că eÈ™ti titularul acestui cont." + +#: mediagoblin/edit/forms.py:104 +msgid "New password" +msgstr "Noua parolă" + +#: 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." @@ -229,44 +234,63 @@ msgstr "Editezi profilul unui utilizator. Se recomandă prudență." msgid "Profile changes saved" msgstr "Modificările profilului au fost salvate" -#: mediagoblin/edit/views.py:241 -msgid "Wrong password" -msgstr "Parolă incorectă" - -#: mediagoblin/edit/views.py:252 +#: mediagoblin/edit/views.py:240 msgid "Account settings saved" msgstr "Setările pentru acest cont au fost salvate" -#: mediagoblin/edit/views.py:286 +#: mediagoblin/edit/views.py:274 msgid "You need to confirm the deletion of your account." msgstr "Trebuie să confirmi È™tergerea contului tău." -#: mediagoblin/edit/views.py:322 mediagoblin/submit/views.py:142 -#: mediagoblin/user_pages/views.py:214 +#: mediagoblin/edit/views.py:310 mediagoblin/submit/views.py:138 +#: mediagoblin/user_pages/views.py:222 #, python-format msgid "You already have a collection called \"%s\"!" msgstr "Ai deja o colecÈ›ie numită \"%s\"!" -#: mediagoblin/edit/views.py:326 +#: mediagoblin/edit/views.py:314 msgid "A collection with that slug already exists for this user." msgstr "O colecÈ›ie cu acelaÈ™i slug există deja pentru acest utilizator." -#: mediagoblin/edit/views.py:343 +#: mediagoblin/edit/views.py:329 msgid "You are editing another user's collection. Proceed with caution." msgstr "Lucrezi pe colecÈ›ia unui alt utilizator. Se recomandă prudență." -#: mediagoblin/gmg_commands/theme.py:58 +#: mediagoblin/edit/views.py:348 +msgid "Wrong password" +msgstr "Parolă incorectă" + +#: mediagoblin/edit/views.py:363 +msgid "Your password was changed successfully" +msgstr "Parola a fost schimbată cu succes" + +#: mediagoblin/gmg_commands/assetlink.py:60 msgid "Cannot link theme... no theme set\n" msgstr "Tema nu poate fi ataÈ™ată... nu există o temă selectată\n" -#: mediagoblin/gmg_commands/theme.py:71 +#: mediagoblin/gmg_commands/assetlink.py:73 msgid "No asset directory for this theme\n" msgstr "Nu există un folder de elemente pentru această temă\n" -#: mediagoblin/gmg_commands/theme.py:74 +#: mediagoblin/gmg_commands/assetlink.py:76 msgid "However, old link directory symlink found; removed.\n" msgstr "A fost însă găsit un symlink către vechiul folder; s-a È™ters.\n" +#: mediagoblin/gmg_commands/assetlink.py:112 +#, python-format +msgid "Could not link \"%s\": %s exists and is not a symlink\n" +msgstr "Nu s-a putut crea link pentru \"%s\": %s există deja È™i nu este symlink\n" + +#: mediagoblin/gmg_commands/assetlink.py:119 +#, python-format +msgid "Skipping \"%s\"; already set up.\n" +msgstr "S-a omis \"%s\"; configurat deja.\n" + +#: mediagoblin/gmg_commands/assetlink.py:124 +#, python-format +msgid "Old link found for \"%s\"; removing.\n" +msgstr "Există deja un link pentru \"%s\"; va fi È™ters.\n" + #: mediagoblin/meddleware/csrf.py:134 msgid "" "CSRF cookie not present. This is most likely the result of a cookie blocker " @@ -274,12 +298,16 @@ msgid "" "domain." msgstr "LipseÈ™te cookie-ul CSRF. Probabil că blocaÈ›i cookie-urile.<br/>AsiguraÈ›i-vă că există permisiunea setării cookie-urilor pentru acest domeniu." -#: mediagoblin/media_types/__init__.py:61 -#: mediagoblin/media_types/__init__.py:102 +#: mediagoblin/media_types/__init__.py:111 +#: mediagoblin/media_types/__init__.py:155 msgid "Sorry, I don't support that file type :(" msgstr "Scuze, nu recunosc acest tip de fiÈ™ier :(" -#: mediagoblin/media_types/video/processing.py:36 +#: mediagoblin/media_types/pdf/processing.py:136 +msgid "unoconv failing to run, check log file" +msgstr "unoconv nu poate fi executat; verificaÈ›i log-ul" + +#: mediagoblin/media_types/video/processing.py:37 msgid "Video transcoding failed" msgstr "Transcodarea video a eÈ™uat" @@ -346,7 +374,7 @@ msgstr "URI-ul de redirectare pentru aplicaÈ›ii, această rubrică\n msgid "This field is required for public clients" msgstr "Această rubrică este obligatorie pentru clienÈ›ii publici" -#: mediagoblin/plugins/oauth/views.py:59 +#: mediagoblin/plugins/oauth/views.py:56 msgid "The client {0} has been registered!" msgstr "Clientul {0} a fost înregistrat!" @@ -365,7 +393,7 @@ msgstr "ClienÈ›ii tăi OAuth" msgid "Add" msgstr "Adaugă" -#: mediagoblin/processing/__init__.py:172 +#: mediagoblin/processing/__init__.py:193 msgid "Invalid file given for media type." msgstr "Formatul fiÈ™ierului nu corespunde cu tipul de media selectat." @@ -373,45 +401,45 @@ msgstr "Formatul fiÈ™ierului nu corespunde cu tipul de media selectat." msgid "File" msgstr "FiÈ™ier" -#: mediagoblin/submit/views.py:51 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "Trebuie să selectezi un fiÈ™ier." -#: mediagoblin/submit/views.py:97 +#: mediagoblin/submit/views.py:93 msgid "Woohoo! Submitted!" msgstr "Ura! Trimis!" -#: mediagoblin/submit/views.py:146 +#: mediagoblin/submit/views.py:144 #, python-format msgid "Collection \"%s\" added!" msgstr "ColecÈ›ia \"%s\" a fost creată!" -#: mediagoblin/templates/mediagoblin/base.html:64 +#: mediagoblin/templates/mediagoblin/base.html:67 msgid "Verify your email!" msgstr "Verifică adresa de e-mail!" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:68 msgid "log out" msgstr "IeÈ™ire" -#: mediagoblin/templates/mediagoblin/base.html:70 +#: mediagoblin/templates/mediagoblin/base.html:73 #: mediagoblin/templates/mediagoblin/auth/login.html:28 #: mediagoblin/templates/mediagoblin/auth/login.html:36 #: mediagoblin/templates/mediagoblin/auth/login.html:54 msgid "Log in" msgstr "Autentificare" -#: mediagoblin/templates/mediagoblin/base.html:79 +#: mediagoblin/templates/mediagoblin/base.html:82 #, python-format msgid "<a href=\"%(user_url)s\">%(user_name)s</a>'s account" msgstr "Contul lui <a href=\"%(user_url)s\">%(user_name)s</a>" -#: mediagoblin/templates/mediagoblin/base.html:86 +#: mediagoblin/templates/mediagoblin/base.html:89 msgid "Change account settings" msgstr "Modifică setările contului" -#: mediagoblin/templates/mediagoblin/base.html:90 -#: mediagoblin/templates/mediagoblin/base.html:105 +#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:108 #: mediagoblin/templates/mediagoblin/admin/panel.html:21 #: mediagoblin/templates/mediagoblin/admin/panel.html:26 #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:21 @@ -419,72 +447,25 @@ msgstr "Modifică setările contului" msgid "Media processing panel" msgstr "Panou de procesare media" -#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:96 msgid "Log out" msgstr "IeÈ™ire" -#: mediagoblin/templates/mediagoblin/base.html:96 +#: mediagoblin/templates/mediagoblin/base.html:99 #: mediagoblin/templates/mediagoblin/user_pages/user.html:156 msgid "Add media" msgstr "Trimite fiÈ™ier" -#: mediagoblin/templates/mediagoblin/base.html:99 +#: mediagoblin/templates/mediagoblin/base.html:102 #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:41 msgid "Create new collection" msgstr "Creează colecÈ›ie nouă" -#: mediagoblin/templates/mediagoblin/base.html:122 -#, python-format -msgid "" -"Powered by <a href=\"http://mediagoblin.org/\" title='Version " -"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." -msgstr "Construit cu <a href=\"http://mediagoblin.org/\" title='Versiunea %(version)s'>MediaGoblin</a>, un proiect <a href=\"http://gnu.org/\">GNU</a>." - -#: mediagoblin/templates/mediagoblin/base.html:125 -#, 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/error.html:24 msgid "Image of goblin stressing out" msgstr "Imagine cu un goblin stresat" -#: mediagoblin/templates/mediagoblin/root.html:31 -msgid "Explore" -msgstr "Explorează" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "Salut, bine ai venit pe acest site MediaGoblin!" - -#: mediagoblin/templates/mediagoblin/root.html:35 -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." - -#: mediagoblin/templates/mediagoblin/root.html:36 -msgid "" -"To add your own media, place comments, and more, you can log in with your " -"MediaGoblin account." -msgstr "Pentru a adăuga fiÈ™ierele tale È™i pentru a comenta te poÈ›i autentifica cu contul tău MediaGoblin." - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Don't have one yet? It's easy!" -msgstr "ÃŽncă nu ai unul? E simplu!" - -#: mediagoblin/templates/mediagoblin/root.html:39 -#, 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\">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:47 +#: mediagoblin/templates/mediagoblin/root.html:32 msgid "Most recent media" msgstr "Cele mai recente fiÈ™iere" @@ -590,6 +571,53 @@ msgid "" "%(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/bits/base_footer.html:21 +#, python-format +msgid "" +"Powered by <a href=\"http://mediagoblin.org/\" title='Version " +"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." +msgstr "Construit cu <a href=\"http://mediagoblin.org/\" title='Versiunea %(version)s'>MediaGoblin</a>, un proiect <a href=\"http://gnu.org/\">GNU</a>." + +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:24 +#, 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/bits/frontpage_welcome.html:20 +msgid "Explore" +msgstr "Explorează" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:22 +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "Salut, bine ai venit pe acest site MediaGoblin!" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:24 +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." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:25 +msgid "" +"To add your own media, place comments, and more, you can log in with your " +"MediaGoblin account." +msgstr "Pentru a adăuga fiÈ™ierele tale È™i pentru a comenta te poÈ›i autentifica cu contul tău MediaGoblin." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:27 +msgid "Don't have one yet? It's easy!" +msgstr "ÃŽncă nu ai unul? E simplu!" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:28 +#, 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\">CreaÈ›i un cont pe acest site</a>\n sau\n <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">InstalaÈ›i MediaGoblin pe serverul dvs.</a>" + #: mediagoblin/templates/mediagoblin/bits/logo.html:23 #: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 msgid "MediaGoblin logo" @@ -602,13 +630,13 @@ msgid "Editing attachments for %(media_title)s" msgstr "Editare anexe la %(media_title)s" #: mediagoblin/templates/mediagoblin/edit/attachments.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:159 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:175 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:182 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:198 msgid "Attachments" msgstr "Anexe" #: mediagoblin/templates/mediagoblin/edit/attachments.html:57 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:181 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:204 msgid "Add attachment" msgstr "AtaÈ™ează" @@ -625,12 +653,22 @@ msgstr "Anulare" #: mediagoblin/templates/mediagoblin/edit/attachments.html:63 #: mediagoblin/templates/mediagoblin/edit/edit.html:42 -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:52 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:55 #: mediagoblin/templates/mediagoblin/edit/edit_collection.html:33 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:40 msgid "Save changes" msgstr "Salvează modificările" +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:28 +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 +#, python-format +msgid "Changing %(username)s's password" +msgstr "Se modifică parola pentru %(username)s" + +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 +msgid "Save" +msgstr "Salvează" + #: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 #, python-format msgid "Really delete user '%(user_name)s' and all related media/comments?" @@ -641,7 +679,7 @@ msgid "Yes, really delete my account" msgstr "Da, doresc È™tergerea contului meu" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:48 #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49 msgid "Delete permanently" msgstr "Șterge definitiv" @@ -658,7 +696,11 @@ msgstr "Editare %(media_title)s" msgid "Changing %(username)s's account settings" msgstr "Se modifică setările contului pentru userul %(username)s" -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:59 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 +msgid "Change your password." +msgstr "Modifică parolă." + +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 msgid "Delete my account" msgstr "Șterge contul meu" @@ -683,6 +725,7 @@ msgstr "FiÈ™ier etichetat cu cuvintele-cheie: %(tag_name)s" #: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 #: mediagoblin/templates/mediagoblin/media_displays/audio.html:56 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:65 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:136 #: mediagoblin/templates/mediagoblin/media_displays/video.html:55 msgid "Download" @@ -707,6 +750,7 @@ msgid "" 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:60 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:71 #: mediagoblin/templates/mediagoblin/media_displays/video.html:61 msgid "Original file" msgstr "FiÈ™ierul original" @@ -715,6 +759,7 @@ msgstr "FiÈ™ierul original" msgid "WebM file (Vorbis codec)" msgstr "FiÈ™ier WebM (codec Vorbis)" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:59 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:87 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:93 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:99 @@ -725,6 +770,10 @@ msgstr "FiÈ™ier WebM (codec Vorbis)" msgid "Image for %(media_title)s" msgstr "Imagine pentru %(media_title)s" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 +msgid "PDF file" +msgstr "FiÈ™ier PDF" + #: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 msgid "Toggle Rotate" msgstr "Rotire" @@ -823,7 +872,7 @@ msgstr "Sigur doreÈ™ti să È™tergi %(title)s?" msgid "Really remove %(media_title)s from %(collection_title)s?" msgstr "Sigur doreÈ™ti să È™tergi %(media_title)s din %(collection_title)s?" -#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:54 msgid "Remove" msgstr "Șterge" @@ -866,24 +915,28 @@ msgstr "FiÈ™ierele media ale lui <a href=\"%(user_url)s\">%(username)s</a>" 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:94 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:95 msgid "Add a comment" msgstr "Adaugă un comentariu" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 msgid "Add this comment" msgstr "Trimite acest comentariu" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:123 -msgid "at" -msgstr "la" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:144 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:132 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:152 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:164 #, python-format -msgid "" -"<h3>Added on</h3>\n" -" <p>%(date)s</p>" -msgstr "<h3>Adăugat la</h3>\n <p>%(date)s</p>" +msgid "%(formatted_time)s ago" +msgstr "în urmă cu %(formatted_time)s" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:150 +msgid "Added" +msgstr "Adăugat" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:161 +msgid "Created" +msgstr "Creat" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:40 @@ -1039,7 +1092,7 @@ msgstr "mai vechi" msgid "Tagged with" msgstr "Etichetat cu cuvintele-cheie" -#: mediagoblin/tools/exif.py:80 +#: mediagoblin/tools/exif.py:83 msgid "Could not read the image file." msgstr "FiÈ™ierul cu imaginea nu a putut fi citit." @@ -1069,6 +1122,30 @@ msgid "" " deleted." msgstr "Nu există nicio pagină la această adresă.</p><p>Dacă sunteÈ›i sigur că adresa este corectă, poate că pagina pe care o căutaÈ›i a fost mutată sau È™tearsă." +#: mediagoblin/tools/timesince.py:62 +msgid "year" +msgstr "anul" + +#: mediagoblin/tools/timesince.py:63 +msgid "month" +msgstr "luna" + +#: mediagoblin/tools/timesince.py:64 +msgid "week" +msgstr "săptămâna" + +#: mediagoblin/tools/timesince.py:65 +msgid "day" +msgstr "ziua" + +#: mediagoblin/tools/timesince.py:66 +msgid "hour" +msgstr "ora" + +#: mediagoblin/tools/timesince.py:67 +msgid "minute" +msgstr "minutul" + #: mediagoblin/user_pages/forms.py:23 msgid "Comment" msgstr "Comentariu" @@ -1100,73 +1177,77 @@ msgstr "-- Selectează --" msgid "Include a note" msgstr "Adaugă o notiță" -#: mediagoblin/user_pages/lib.py:56 +#: mediagoblin/user_pages/lib.py:58 msgid "commented on your post" msgstr "a făcut un comentariu la postarea ta" -#: mediagoblin/user_pages/views.py:166 +#: mediagoblin/user_pages/views.py:169 +msgid "Sorry, comments are disabled." +msgstr "Comentariile sunt dezactivate." + +#: mediagoblin/user_pages/views.py:174 msgid "Oops, your comment was empty." msgstr "Hopa, ai uitat să scrii comentariul." -#: mediagoblin/user_pages/views.py:172 +#: mediagoblin/user_pages/views.py:180 msgid "Your comment has been posted!" msgstr "Comentariul tău a fost trimis!" -#: mediagoblin/user_pages/views.py:197 +#: mediagoblin/user_pages/views.py:205 msgid "Please check your entries and try again." msgstr "Verifică datele È™i încearcă din nou." -#: mediagoblin/user_pages/views.py:237 +#: mediagoblin/user_pages/views.py:245 msgid "You have to select or add a collection" msgstr "Trebuie să alegi sau să creezi o colecÈ›ie" -#: mediagoblin/user_pages/views.py:248 +#: mediagoblin/user_pages/views.py:256 #, python-format msgid "\"%s\" already in collection \"%s\"" msgstr "\"%s\" este deja în colecÈ›ia \"%s\"" -#: mediagoblin/user_pages/views.py:264 +#: mediagoblin/user_pages/views.py:262 #, python-format msgid "\"%s\" added to collection \"%s\"" msgstr "\"%s\" a fost adăugat la colecÈ›ia \"%s\"" -#: mediagoblin/user_pages/views.py:286 +#: mediagoblin/user_pages/views.py:282 msgid "You deleted the media." msgstr "Ai È™ters acest fiÈ™ier" -#: mediagoblin/user_pages/views.py:293 +#: mediagoblin/user_pages/views.py:289 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:301 +#: mediagoblin/user_pages/views.py:296 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ță." -#: mediagoblin/user_pages/views.py:375 +#: mediagoblin/user_pages/views.py:370 msgid "You deleted the item from the collection." msgstr "Ai È™ters acest articol din colecÈ›ie." -#: mediagoblin/user_pages/views.py:379 +#: mediagoblin/user_pages/views.py:374 msgid "The item was not removed because you didn't check that you were sure." msgstr "Articolul nu a fost È™ters pentru că nu ai confirmat că eÈ™ti sigur(ă)." -#: mediagoblin/user_pages/views.py:389 +#: mediagoblin/user_pages/views.py:382 msgid "" "You are about to delete an item from another user's collection. Proceed with" " caution." msgstr "Urmează să È™tergi un articol din colecÈ›ia unui alt utilizator. Se recomandă prudență." -#: mediagoblin/user_pages/views.py:422 +#: mediagoblin/user_pages/views.py:415 #, python-format msgid "You deleted the collection \"%s\"" msgstr "Ai È™ters colecÈ›ia \"%s\"" -#: mediagoblin/user_pages/views.py:429 +#: mediagoblin/user_pages/views.py:422 msgid "" "The collection was not deleted because you didn't check that you were sure." msgstr "ColecÈ›ia nu a fost È™tearsă pentru că nu ai confirmat că eÈ™ti sigur(ă)." -#: mediagoblin/user_pages/views.py:439 +#: mediagoblin/user_pages/views.py:430 msgid "" "You are about to delete another user's collection. Proceed with caution." msgstr "Urmează să È™tergi colecÈ›ia unui alt utilizator. Se recomandă prudență." diff --git a/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.mo Binary files differindex 759f5337..ed28ff43 100644 --- a/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.mo +++ b/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.po index 0dc099ed..d0ff7bdd 100644 --- a/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/ru/LC_MESSAGES/mediagoblin.po @@ -3,16 +3,16 @@ # This file is distributed under the same license as the PROJECT project. # # Translators: -# <deletesoftware@yandex.ru>, 2013. -# <deletesoftware@yandex.ru>, 2011-2012. +# aleksejrs <deletesoftware@yandex.ru>, 2013 +# aleksejrs <deletesoftware@yandex.ru>, 2011-2012 msgid "" msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" -"POT-Creation-Date: 2013-03-04 18:04-0600\n" -"PO-Revision-Date: 2013-03-10 15:35+0000\n" +"POT-Creation-Date: 2013-05-27 13:54-0500\n" +"PO-Revision-Date: 2013-06-01 21:08+0000\n" "Last-Translator: aleksejrs <deletesoftware@yandex.ru>\n" -"Language-Team: LANGUAGE <LL@li.org>\n" +"Language-Team: Russian (http://www.transifex.com/projects/p/mediagoblin/language/ru/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -20,34 +20,39 @@ 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/auth/forms.py:28 -msgid "Invalid User name or email address." -msgstr "" - -#: mediagoblin/auth/forms.py:29 -msgid "This field does not take email addresses." -msgstr "Ðто поле не Ð´Ð»Ñ Ð°Ð´Ñ€ÐµÑа Ñлектронной почты." - -#: mediagoblin/auth/forms.py:30 -msgid "This field requires an email address." -msgstr "Ðто поле — Ð´Ð»Ñ Ð°Ð´Ñ€ÐµÑа Ñлектронной почты." - -#: mediagoblin/auth/forms.py:52 mediagoblin/auth/forms.py:67 +#: mediagoblin/auth/forms.py:26 msgid "Username" msgstr "Логин" -#: mediagoblin/auth/forms.py:56 mediagoblin/auth/forms.py:71 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 +#: mediagoblin/tests/test_util.py:110 msgid "Password" msgstr "Пароль" -#: mediagoblin/auth/forms.py:60 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "ÐÐ´Ñ€ÐµÑ Ñлектронной почты" -#: mediagoblin/auth/forms.py:78 +#: mediagoblin/auth/forms.py:41 +msgid "Username or Email" +msgstr "Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¸Ð»Ð¸ Ð°Ð´Ñ€ÐµÑ Ñлектронной почты" + +#: mediagoblin/auth/forms.py:52 msgid "Username or email" msgstr "Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¸Ð»Ð¸ Ð°Ð´Ñ€ÐµÑ Ñлектронной почты" +#: mediagoblin/auth/tools.py:31 +msgid "Invalid User name or email address." +msgstr "" + +#: mediagoblin/auth/tools.py:32 +msgid "This field does not take email addresses." +msgstr "Ðто поле не Ð´Ð»Ñ Ð°Ð´Ñ€ÐµÑа Ñлектронной почты." + +#: mediagoblin/auth/tools.py:33 +msgid "This field requires an email address." +msgstr "Ðто поле — Ð´Ð»Ñ Ð°Ð´Ñ€ÐµÑа Ñлектронной почты." + #: mediagoblin/auth/views.py:54 msgid "Sorry, registration is disabled on this instance." msgstr "Извините, на Ñтом Ñайте региÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð·Ð°Ð¿Ñ€ÐµÑ‰ÐµÐ½Ð°." @@ -60,54 +65,54 @@ msgstr "Извините, пользователь Ñ Ñтим именем уж msgid "Sorry, a user with that email address already exists." msgstr "Сожалеем, но на Ñтот Ð°Ð´Ñ€ÐµÑ Ñлектронной почты уже зарегиÑтрирована Ð´Ñ€ÑƒÐ³Ð°Ñ ÑƒÑ‡Ñ‘Ñ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ." -#: mediagoblin/auth/views.py:174 +#: 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:180 +#: mediagoblin/auth/views.py:188 msgid "The verification key or user id is incorrect" msgstr "Ðеверный ключ проверки или идентификатор пользователÑ" -#: mediagoblin/auth/views.py:198 +#: 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:206 +#: mediagoblin/auth/views.py:214 msgid "You've already verified your email address!" msgstr "Ð’Ñ‹ уже потвердили Ñвой Ð°Ð´Ñ€ÐµÑ Ñлектронной почты!" -#: mediagoblin/auth/views.py:219 +#: mediagoblin/auth/views.py:227 msgid "Resent your verification email." msgstr "ПереÑлать Ñообщение Ñ Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸ÐµÐ¼ аккаунта." -#: mediagoblin/auth/views.py:250 +#: mediagoblin/auth/views.py:258 msgid "" "If that email address (case sensitive!) is registered an email has been sent" " with instructions on how to change your password." msgstr "ЕÑли Ñ Ñтим адреÑом Ñлектронной почты (Ñравниваемым чувÑтвительно к региÑтру Ñимволов!) еÑть ÑƒÑ‡Ñ‘Ñ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ, то на него отправлено Ñообщение Ñ ÑƒÐºÐ°Ð·Ð°Ð½Ð¸Ñми о том, как Ñменить пароль." -#: mediagoblin/auth/views.py:261 +#: mediagoblin/auth/views.py:269 msgid "Couldn't find someone with that username." msgstr "Ðе найдено никого Ñ Ñ‚Ð°ÐºÐ¸Ð¼ именем пользователÑ." -#: mediagoblin/auth/views.py:264 +#: mediagoblin/auth/views.py:272 msgid "" "An email has been sent with instructions on how to change your password." msgstr "Вам отправлено Ñлектронное пиÑьмо Ñ Ð¸Ð½ÑтрукциÑми по Ñмене паролÑ." -#: mediagoblin/auth/views.py:271 +#: mediagoblin/auth/views.py:279 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." msgstr "Мы не можем отправить Ñообщение Ð´Ð»Ñ Ð²Ð¾ÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿Ð°Ñ€Ð¾Ð»Ñ, потому что ваша ÑƒÑ‡Ñ‘Ñ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ неактивна, либо указанный в ней Ð°Ð´Ñ€ÐµÑ Ñлектронной почты не был подтверждён." -#: mediagoblin/auth/views.py:328 +#: mediagoblin/auth/views.py:336 msgid "You can now log in using your new password." msgstr "Теперь вы можете войти, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ð²Ð°Ñˆ новый пароль." -#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:93 +#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:82 #: mediagoblin/submit/forms.py:28 mediagoblin/submit/forms.py:47 #: mediagoblin/user_pages/forms.py:45 msgid "Title" @@ -118,7 +123,7 @@ msgid "Description of this work" msgstr "ОпиÑание Ñтого произведениÑ" #: mediagoblin/edit/forms.py:29 mediagoblin/edit/forms.py:52 -#: mediagoblin/edit/forms.py:97 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:86 mediagoblin/submit/forms.py:32 #: mediagoblin/submit/forms.py:51 mediagoblin/user_pages/forms.py:49 msgid "" "You can use\n" @@ -134,11 +139,11 @@ msgstr "Метки" msgid "Separate tags by commas." msgstr "(через запÑтую)" -#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:101 +#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:90 msgid "Slug" msgstr "ÐžÑ‚Ð»Ð¸Ñ‡Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ñ‡Ð°Ñть адреÑа" -#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:102 +#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:91 msgid "The slug can't be empty" msgstr "ÐžÑ‚Ð»Ð¸Ñ‡Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ñ‡Ð°Ñть адреÑа необходима" @@ -166,45 +171,45 @@ msgid "This address contains errors" msgstr "Ðтот Ð°Ð´Ñ€ÐµÑ Ñодержит ошибки" #: mediagoblin/edit/forms.py:63 -msgid "Old password" -msgstr "Старый пароль" - -#: mediagoblin/edit/forms.py:64 -msgid "Enter your old password to prove you own this account." -msgstr "Введите Ñвой Ñтарый пароль в качеÑтве доказательÑтва, что Ñто ваша ÑƒÑ‡Ñ‘Ñ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ." - -#: mediagoblin/edit/forms.py:67 -msgid "New password" -msgstr "Ðовый пароль" - -#: mediagoblin/edit/forms.py:74 msgid "License preference" msgstr "ÐŸÑ€ÐµÐ´Ð¿Ð¾Ñ‡Ð¸Ñ‚Ð°ÐµÐ¼Ð°Ñ Ð»Ð¸Ñ†ÐµÐ½Ð·Ð¸Ñ" -#: mediagoblin/edit/forms.py:80 +#: mediagoblin/edit/forms.py:69 msgid "This will be your default license on upload forms." msgstr "Она будет лицензией по умолчанию Ð´Ð»Ñ Ð²Ð°ÑˆÐ¸Ñ… загрузок" -#: mediagoblin/edit/forms.py:82 +#: mediagoblin/edit/forms.py:71 msgid "Email me when others comment on my media" msgstr "УведомлÑть Ð¼ÐµÐ½Ñ Ð¿Ð¾ e-mail о комментариÑÑ… к моим файлам" -#: mediagoblin/edit/forms.py:94 +#: mediagoblin/edit/forms.py:83 msgid "The title can't be empty" msgstr "Ðазвание не может быть пуÑтым" -#: mediagoblin/edit/forms.py:96 mediagoblin/submit/forms.py:50 +#: mediagoblin/edit/forms.py:85 mediagoblin/submit/forms.py:50 #: mediagoblin/user_pages/forms.py:48 msgid "Description of this collection" msgstr "ОпиÑание Ñтой коллекции" -#: mediagoblin/edit/forms.py:103 +#: mediagoblin/edit/forms.py:92 msgid "" "The title part of this collection's address. You usually don't need to " "change this." msgstr "ÐžÑ‚Ð»Ð¸Ñ‡Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ñ‡Ð°Ñть адреÑа Ñтой коллекции, оÑÐ½Ð¾Ð²Ð°Ð½Ð½Ð°Ñ Ð½Ð° названии. Обычно не нужно её изменÑть." -#: mediagoblin/edit/views.py:66 +#: mediagoblin/edit/forms.py:99 +msgid "Old password" +msgstr "Старый пароль" + +#: mediagoblin/edit/forms.py:101 +msgid "Enter your old password to prove you own this account." +msgstr "Введите Ñвой Ñтарый пароль в качеÑтве доказательÑтва, что Ñто ваша ÑƒÑ‡Ñ‘Ñ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ." + +#: mediagoblin/edit/forms.py:104 +msgid "New password" +msgstr "Ðовый пароль" + +#: mediagoblin/edit/views.py:67 msgid "An entry with that slug already exists for this user." msgstr "У Ñтого Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ ÑƒÐ¶Ðµ еÑть файл Ñ Ñ‚Ð°ÐºÐ¾Ð¹ отличительной чаÑтью адреÑа." @@ -229,44 +234,63 @@ msgstr "Ð’Ñ‹ редактируете профиль пользователÑ. Ð msgid "Profile changes saved" msgstr "Ð˜Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ñ Ñохранены" -#: mediagoblin/edit/views.py:241 -msgid "Wrong password" -msgstr "Ðеправильный пароль" - -#: mediagoblin/edit/views.py:252 +#: mediagoblin/edit/views.py:240 msgid "Account settings saved" msgstr "ÐаÑтройки учётной запиÑи запиÑаны" -#: mediagoblin/edit/views.py:286 +#: mediagoblin/edit/views.py:274 msgid "You need to confirm the deletion of your account." msgstr "Вам нужно подтвердить, что вы хотите удалить Ñвою учётную запиÑÑŒ." -#: mediagoblin/edit/views.py:322 mediagoblin/submit/views.py:142 -#: mediagoblin/user_pages/views.py:214 +#: mediagoblin/edit/views.py:310 mediagoblin/submit/views.py:138 +#: mediagoblin/user_pages/views.py:222 #, python-format msgid "You already have a collection called \"%s\"!" msgstr "У Ð²Ð°Ñ ÑƒÐ¶Ðµ еÑть ÐºÐ¾Ð»Ð»ÐµÐºÑ†Ð¸Ñ Ñ Ð½Ð°Ð·Ð²Ð°Ð½Ð¸ÐµÐ¼ «%s»!" -#: mediagoblin/edit/views.py:326 +#: mediagoblin/edit/views.py:314 msgid "A collection with that slug already exists for this user." msgstr "У Ñтого Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ ÑƒÐ¶Ðµ еÑть ÐºÐ¾Ð»Ð»ÐµÐºÑ†Ð¸Ñ Ñ Ñ‚Ð°ÐºÐ¾Ð¹ отличительной чаÑтью адреÑа." -#: mediagoblin/edit/views.py:343 +#: mediagoblin/edit/views.py:329 msgid "You are editing another user's collection. Proceed with caution." msgstr "Ð’Ñ‹ редактируете коллекцию другого пользователÑ. Будьте оÑторожны." -#: mediagoblin/gmg_commands/theme.py:58 +#: mediagoblin/edit/views.py:348 +msgid "Wrong password" +msgstr "Ðеправильный пароль" + +#: mediagoblin/edit/views.py:363 +msgid "Your password was changed successfully" +msgstr "Ваш пароль Ñменён уÑпешно" + +#: mediagoblin/gmg_commands/assetlink.py:60 msgid "Cannot link theme... no theme set\n" msgstr "Ðевозможно привÑзать тему… не выбрано ÑущеÑтвующей темы\n" -#: mediagoblin/gmg_commands/theme.py:71 +#: mediagoblin/gmg_commands/assetlink.py:73 msgid "No asset directory for this theme\n" msgstr "У Ñтой темы отÑутÑтвует каталог Ñ Ñлементами оформлениÑ\n" -#: mediagoblin/gmg_commands/theme.py:74 +#: mediagoblin/gmg_commands/assetlink.py:76 msgid "However, old link directory symlink found; removed.\n" msgstr "Однако найдена (и удалена) ÑÑ‚Ð°Ñ€Ð°Ñ ÑимволичеÑÐºÐ°Ñ ÑÑылка на каталог.\n" +#: mediagoblin/gmg_commands/assetlink.py:112 +#, python-format +msgid "Could not link \"%s\": %s exists and is not a symlink\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:119 +#, python-format +msgid "Skipping \"%s\"; already set up.\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:124 +#, python-format +msgid "Old link found for \"%s\"; removing.\n" +msgstr "" + #: mediagoblin/meddleware/csrf.py:134 msgid "" "CSRF cookie not present. This is most likely the result of a cookie blocker " @@ -274,12 +298,16 @@ msgid "" "domain." msgstr "" -#: mediagoblin/media_types/__init__.py:61 -#: mediagoblin/media_types/__init__.py:102 +#: mediagoblin/media_types/__init__.py:111 +#: mediagoblin/media_types/__init__.py:155 msgid "Sorry, I don't support that file type :(" msgstr "Увы, Ñ Ð½Ðµ поддерживаю Ñтот тип файлов :(" -#: mediagoblin/media_types/video/processing.py:36 +#: mediagoblin/media_types/pdf/processing.py:136 +msgid "unoconv failing to run, check log file" +msgstr "" + +#: mediagoblin/media_types/video/processing.py:37 msgid "Video transcoding failed" msgstr "Перекодировка видео не удалаÑÑŒ" @@ -346,7 +374,7 @@ msgstr "" msgid "This field is required for public clients" msgstr "" -#: mediagoblin/plugins/oauth/views.py:59 +#: mediagoblin/plugins/oauth/views.py:56 msgid "The client {0} has been registered!" msgstr "Клиент {0} зарегиÑтрирован!" @@ -365,7 +393,7 @@ msgstr "" msgid "Add" msgstr "Добавить" -#: mediagoblin/processing/__init__.py:172 +#: mediagoblin/processing/__init__.py:193 msgid "Invalid file given for media type." msgstr "Ðеправильный формат файла." @@ -373,45 +401,45 @@ msgstr "Ðеправильный формат файла." msgid "File" msgstr "Файл" -#: mediagoblin/submit/views.py:51 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "Ð’Ñ‹ должны загрузить файл." -#: mediagoblin/submit/views.py:97 +#: mediagoblin/submit/views.py:93 msgid "Woohoo! Submitted!" msgstr "Ура! Файл загружен!" -#: mediagoblin/submit/views.py:146 +#: mediagoblin/submit/views.py:144 #, python-format msgid "Collection \"%s\" added!" msgstr "ÐšÐ¾Ð»Ð»ÐµÐºÑ†Ð¸Ñ Â«%s» добавлена!" -#: mediagoblin/templates/mediagoblin/base.html:64 +#: mediagoblin/templates/mediagoblin/base.html:67 msgid "Verify your email!" msgstr "Подтвердите ваш Ð°Ð´Ñ€ÐµÑ Ñлектронной почты!" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:68 msgid "log out" msgstr "завершение ÑеанÑа" -#: mediagoblin/templates/mediagoblin/base.html:70 +#: mediagoblin/templates/mediagoblin/base.html:73 #: mediagoblin/templates/mediagoblin/auth/login.html:28 #: mediagoblin/templates/mediagoblin/auth/login.html:36 #: mediagoblin/templates/mediagoblin/auth/login.html:54 msgid "Log in" msgstr "Войти" -#: mediagoblin/templates/mediagoblin/base.html:79 +#: mediagoblin/templates/mediagoblin/base.html:82 #, python-format msgid "<a href=\"%(user_url)s\">%(user_name)s</a>'s account" msgstr "Ð£Ñ‡Ñ‘Ñ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ <a href=\"%(user_url)s\">%(user_name)s</a>" -#: mediagoblin/templates/mediagoblin/base.html:86 +#: mediagoblin/templates/mediagoblin/base.html:89 msgid "Change account settings" msgstr "Изменить наÑтройки учётной запиÑи" -#: mediagoblin/templates/mediagoblin/base.html:90 -#: mediagoblin/templates/mediagoblin/base.html:105 +#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:108 #: mediagoblin/templates/mediagoblin/admin/panel.html:21 #: mediagoblin/templates/mediagoblin/admin/panel.html:26 #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:21 @@ -419,72 +447,25 @@ msgstr "Изменить наÑтройки учётной запиÑи" msgid "Media processing panel" msgstr "Панель обработки файлов" -#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:96 msgid "Log out" msgstr "Завершение ÑеанÑа" -#: mediagoblin/templates/mediagoblin/base.html:96 +#: mediagoblin/templates/mediagoblin/base.html:99 #: mediagoblin/templates/mediagoblin/user_pages/user.html:156 msgid "Add media" msgstr "Добавить файлы" -#: mediagoblin/templates/mediagoblin/base.html:99 +#: mediagoblin/templates/mediagoblin/base.html:102 #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:41 msgid "Create new collection" msgstr "Создать новую коллекцию" -#: mediagoblin/templates/mediagoblin/base.html:122 -#, python-format -msgid "" -"Powered by <a href=\"http://mediagoblin.org/\" title='Version " -"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." -msgstr "Работает на <a href=\"http://mediagoblin.org/\" title='ВерÑии %(version)s'>MediaGoblin</a>, проекте <a href=\"http://gnu.org/\">GNU</a>." - -#: mediagoblin/templates/mediagoblin/base.html:125 -#, 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/error.html:24 msgid "Image of goblin stressing out" msgstr "Изображение нервничающего гоблина" -#: mediagoblin/templates/mediagoblin/root.html:31 -msgid "Explore" -msgstr "Смотреть" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "Привет! Добро пожаловать на наш MediaGoblin’овый Ñайт!" - -#: mediagoblin/templates/mediagoblin/root.html:35 -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>, необыкновенно замечательном ПО Ð´Ð»Ñ Ñ…Ð¾Ñтинга мультимедийных файлов." - -#: mediagoblin/templates/mediagoblin/root.html:36 -msgid "" -"To add your own media, place comments, and more, you can log in with your " -"MediaGoblin account." -msgstr "Ð”Ð»Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ ÑобÑтвенных файлов, ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸ Ñ‚. п. вы можете предÑтавитьÑÑ Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ вашей MediaGoblin’овой учётной запиÑи." - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Don't have one yet? It's easy!" -msgstr "У Ð²Ð°Ñ ÐµÑ‘ ещё нет? Ðе проблема!" - -#: mediagoblin/templates/mediagoblin/root.html:39 -#, 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\">Создайте учётную запиÑÑŒ на Ñтом Ñайте</a>\n или\n <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">уÑтановите MediaGoblin на ÑобÑтвенный Ñервер</a>" - -#: mediagoblin/templates/mediagoblin/root.html:47 +#: mediagoblin/templates/mediagoblin/root.html:32 msgid "Most recent media" msgstr "Самые новые файлы" @@ -590,6 +571,53 @@ msgid "" "%(verification_url)s" msgstr "Привет, %(username)s!\n\nЧтобы активировать Ñвой аккаунт в GNU MediaGoblin, откройте в Ñвоём вебâ€Ð±Ñ€Ð°ÑƒÐ·ÐµÑ€Ðµ Ñледующую ÑÑылку:\n\n%(verification_url)s" +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:21 +#, python-format +msgid "" +"Powered by <a href=\"http://mediagoblin.org/\" title='Version " +"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." +msgstr "Работает на <a href=\"http://mediagoblin.org/\" title='ВерÑии %(version)s'>MediaGoblin</a>, проекте <a href=\"http://gnu.org/\">GNU</a>." + +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:24 +#, 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/bits/frontpage_welcome.html:20 +msgid "Explore" +msgstr "Смотреть" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:22 +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "Привет! Добро пожаловать на наш MediaGoblin’овый Ñайт!" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:24 +msgid "" +"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, an " +"extraordinarily great piece of media hosting software." +msgstr "Ðтот Ñайт работает на <a href=\"http://mediagoblin.org\">MediaGoblin</a>, необыкновенно замечательном ПО Ð´Ð»Ñ Ñ…Ð¾Ñтинга мультимедийных файлов." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:25 +msgid "" +"To add your own media, place comments, and more, you can log in with your " +"MediaGoblin account." +msgstr "Ð”Ð»Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ ÑобÑтвенных файлов, ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸ Ñ‚. п. вы можете предÑтавитьÑÑ Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ вашей MediaGoblin’овой учётной запиÑи." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:27 +msgid "Don't have one yet? It's easy!" +msgstr "У Ð²Ð°Ñ ÐµÑ‘ ещё нет? Ðе проблема!" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:28 +#, python-format +msgid "" +"<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/bits/logo.html:23 #: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 msgid "MediaGoblin logo" @@ -602,13 +630,13 @@ msgid "Editing attachments for %(media_title)s" msgstr "Добавление ÑопутÑтвующего файла Ð´Ð»Ñ %(media_title)s" #: mediagoblin/templates/mediagoblin/edit/attachments.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:159 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:175 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:182 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:198 msgid "Attachments" msgstr "СопутÑтвующие файлы" #: mediagoblin/templates/mediagoblin/edit/attachments.html:57 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:181 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:204 msgid "Add attachment" msgstr "Добавить ÑопутÑтвующий файл" @@ -625,12 +653,22 @@ msgstr "Отмена" #: mediagoblin/templates/mediagoblin/edit/attachments.html:63 #: mediagoblin/templates/mediagoblin/edit/edit.html:42 -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:52 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:55 #: mediagoblin/templates/mediagoblin/edit/edit_collection.html:33 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:40 msgid "Save changes" msgstr "Сохранить изменениÑ" +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:28 +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 +#, python-format +msgid "Changing %(username)s's password" +msgstr "Смена Ð¿Ð°Ñ€Ð¾Ð»Ñ %(username)s" + +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 +msgid "Save" +msgstr "Сохранить" + #: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 #, python-format msgid "Really delete user '%(user_name)s' and all related media/comments?" @@ -641,7 +679,7 @@ msgid "Yes, really delete my account" msgstr "Да, на Ñамом деле удалить мою учётную запиÑÑŒ" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:48 #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49 msgid "Delete permanently" msgstr "Удалить безвозвратно" @@ -658,7 +696,11 @@ msgstr "Редактирование %(media_title)s" msgid "Changing %(username)s's account settings" msgstr "ÐаÑтройка учётной запиÑи %(username)s" -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:59 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 +msgid "Change your password." +msgstr "Сменить пароль" + +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 msgid "Delete my account" msgstr "Удалить мою учётную запиÑÑŒ" @@ -683,6 +725,7 @@ msgstr "Файлы Ñ Ð¼ÐµÑ‚ÐºÐ¾Ð¹: %(tag_name)s" #: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 #: mediagoblin/templates/mediagoblin/media_displays/audio.html:56 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:65 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:136 #: mediagoblin/templates/mediagoblin/media_displays/video.html:55 msgid "Download" @@ -707,6 +750,7 @@ msgid "" msgstr "Ð’Ñ‹ можете Ñкачать Ñовременный браузер, \n\tÑпоÑобный проиграть Ñто аудио, Ñ <a href=\"http://getfirefox.com\">\n\t http://getfirefox.com</a>!" #: mediagoblin/templates/mediagoblin/media_displays/audio.html:60 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:71 #: mediagoblin/templates/mediagoblin/media_displays/video.html:61 msgid "Original file" msgstr "ИÑходный файл" @@ -715,6 +759,7 @@ msgstr "ИÑходный файл" msgid "WebM file (Vorbis codec)" msgstr "WebMâ€Ñ„айл (кодек — Vorbis)" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:59 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:87 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:93 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:99 @@ -725,6 +770,10 @@ msgstr "WebMâ€Ñ„айл (кодек — Vorbis)" msgid "Image for %(media_title)s" msgstr "Изображение «%(media_title)s»" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 +msgid "PDF file" +msgstr "PDF-файл" + #: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 msgid "Toggle Rotate" msgstr "" @@ -823,7 +872,7 @@ msgstr "Удалить %(title)s?" msgid "Really remove %(media_title)s from %(collection_title)s?" msgstr "Ð’ Ñамом деле иÑключить %(media_title)s из %(collection_title)s?" -#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:54 msgid "Remove" msgstr "ИÑключить" @@ -866,24 +915,28 @@ msgstr "Файлы Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ <a href=\"%(user_url)s\">%(username) 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:94 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:95 msgid "Add a comment" msgstr "Добавить комментарий" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 msgid "Add this comment" msgstr "Добавить Ñтот комментарий" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:123 -msgid "at" -msgstr "в" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:144 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:132 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:152 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:164 #, python-format -msgid "" -"<h3>Added on</h3>\n" -" <p>%(date)s</p>" -msgstr "<h3>Добавлено</h3>\n <p>%(date)s</p>" +msgid "%(formatted_time)s ago" +msgstr "%(formatted_time)s назад" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:150 +msgid "Added" +msgstr "Добавлен" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:161 +msgid "Created" +msgstr "Создан" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:40 @@ -1039,7 +1092,7 @@ msgstr "более Ñтарые" msgid "Tagged with" msgstr "Метки" -#: mediagoblin/tools/exif.py:80 +#: mediagoblin/tools/exif.py:83 msgid "Could not read the image file." msgstr "Ðе удалоÑÑŒ прочитать файл Ñ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸ÐµÐ¼." @@ -1069,6 +1122,30 @@ msgid "" " deleted." msgstr "" +#: mediagoblin/tools/timesince.py:62 +msgid "year" +msgstr "" + +#: mediagoblin/tools/timesince.py:63 +msgid "month" +msgstr "" + +#: mediagoblin/tools/timesince.py:64 +msgid "week" +msgstr "" + +#: mediagoblin/tools/timesince.py:65 +msgid "day" +msgstr "" + +#: mediagoblin/tools/timesince.py:66 +msgid "hour" +msgstr "" + +#: mediagoblin/tools/timesince.py:67 +msgid "minute" +msgstr "мин" + #: mediagoblin/user_pages/forms.py:23 msgid "Comment" msgstr "Комментировать" @@ -1100,73 +1177,77 @@ msgstr "-- Выберите --" msgid "Include a note" msgstr "Примечание" -#: mediagoblin/user_pages/lib.py:56 +#: mediagoblin/user_pages/lib.py:58 msgid "commented on your post" msgstr "оÑтавил комментарий к вашему файлу" -#: mediagoblin/user_pages/views.py:166 +#: mediagoblin/user_pages/views.py:169 +msgid "Sorry, comments are disabled." +msgstr "Сожалеем: возможноÑть ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¾Ñ‚ÐºÐ»ÑŽÑ‡ÐµÐ½Ð°." + +#: mediagoblin/user_pages/views.py:174 msgid "Oops, your comment was empty." msgstr "Ой, ваш комментарий был пуÑÑ‚." -#: mediagoblin/user_pages/views.py:172 +#: mediagoblin/user_pages/views.py:180 msgid "Your comment has been posted!" msgstr "Ваш комментарий размещён!" -#: mediagoblin/user_pages/views.py:197 +#: mediagoblin/user_pages/views.py:205 msgid "Please check your entries and try again." msgstr "ПожалуйÑта, проверьте введённое и попробуйте ещё раз." -#: mediagoblin/user_pages/views.py:237 +#: mediagoblin/user_pages/views.py:245 msgid "You have to select or add a collection" msgstr "Ðеобходимо выбрать или добавить коллекцию" -#: mediagoblin/user_pages/views.py:248 +#: mediagoblin/user_pages/views.py:256 #, python-format msgid "\"%s\" already in collection \"%s\"" msgstr "«%s» — уже в коллекции «%s»" -#: mediagoblin/user_pages/views.py:264 +#: mediagoblin/user_pages/views.py:262 #, python-format msgid "\"%s\" added to collection \"%s\"" msgstr "«%s» добавлено в коллекцию «%s»" -#: mediagoblin/user_pages/views.py:286 +#: mediagoblin/user_pages/views.py:282 msgid "You deleted the media." msgstr "Ð’Ñ‹ удалили файл." -#: mediagoblin/user_pages/views.py:293 +#: mediagoblin/user_pages/views.py:289 msgid "The media was not deleted because you didn't check that you were sure." msgstr "Файл не удалён, так как вы не подтвердили Ñвою уверенноÑть галочкой." -#: mediagoblin/user_pages/views.py:301 +#: mediagoblin/user_pages/views.py:296 msgid "You are about to delete another user's media. Proceed with caution." msgstr "Ð’Ñ‹ на пороге ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ñ„Ð°Ð¹Ð»Ð° другого пользователÑ. Будьте оÑторожны." -#: mediagoblin/user_pages/views.py:375 +#: mediagoblin/user_pages/views.py:370 msgid "You deleted the item from the collection." msgstr "Ð’Ñ‹ иÑключили файл из коллекции." -#: mediagoblin/user_pages/views.py:379 +#: mediagoblin/user_pages/views.py:374 msgid "The item was not removed because you didn't check that you were sure." msgstr "Файл не иÑключён из коллекции, так как вы не подтвердили Ñвоё намерение отметкой." -#: mediagoblin/user_pages/views.py:389 +#: mediagoblin/user_pages/views.py:382 msgid "" "You are about to delete an item from another user's collection. Proceed with" " caution." msgstr "Ð’Ñ‹ на пороге иÑÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ñ„Ð°Ð¹Ð»Ð° из коллекции другого пользователÑ. Будьте оÑторожны." -#: mediagoblin/user_pages/views.py:422 +#: mediagoblin/user_pages/views.py:415 #, python-format msgid "You deleted the collection \"%s\"" msgstr "Ð’Ñ‹ удалили коллекцию «%s»" -#: mediagoblin/user_pages/views.py:429 +#: mediagoblin/user_pages/views.py:422 msgid "" "The collection was not deleted because you didn't check that you were sure." msgstr "ÐšÐ¾Ð»Ð»ÐµÐºÑ†Ð¸Ñ Ð½Ðµ удалена, так как вы не подтвердили Ñвоё намерение отметкой." -#: mediagoblin/user_pages/views.py:439 +#: mediagoblin/user_pages/views.py:430 msgid "" "You are about to delete another user's collection. Proceed with caution." msgstr "Ð’Ñ‹ на пороге ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ ÐºÐ¾Ð»Ð»ÐµÐºÑ†Ð¸Ð¸ другого пользователÑ. Будьте оÑторожны." diff --git a/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.mo Binary files differindex bc92bb13..fd48a37f 100644 --- a/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.mo +++ b/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.po index 07932b77..e4d1bacc 100644 --- a/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/sk/LC_MESSAGES/mediagoblin.po @@ -3,20 +3,20 @@ # This file is distributed under the same license as the PROJECT project. # # Translators: -# Martin <zatroch.martin@gmail.com>, 2013. -# Martin Zatroch <zatroch.martin@gmail.com>, 2012. -# Morten Juhl-Johansen Zölde-Fejér <morten@writtenandread.net>, 2012. -# Olle Jonsson <olle.jonsson@gmail.com>, 2012. -# Tanja Trudslev <tanja.trudslev@gmail.com>, 2012. -# <zatroch.martin@gmail.com>, 2011-2012. +# martin <zatroch.martin@gmail.com>, 2013 +# martin <zatroch.martin@gmail.com>, 2012-2013 +# Morten Juhl-Johansen Zölde-Fejér <morten@writtenandread.net>, 2012 +# Olle Jonsson <olle.jonsson@gmail.com>, 2012 +# ttrudslev <tanja.trudslev@gmail.com>, 2012 +# martin <zatroch.martin@gmail.com>, 2011-2012 msgid "" msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" -"POT-Creation-Date: 2013-03-04 18:04-0600\n" -"PO-Revision-Date: 2013-03-05 00:04+0000\n" -"Last-Translator: cwebber <cwebber@dustycloud.org>\n" -"Language-Team: LANGUAGE <LL@li.org>\n" +"POT-Creation-Date: 2013-05-27 13:54-0500\n" +"PO-Revision-Date: 2013-05-28 07:47+0000\n" +"Last-Translator: martin <zatroch.martin@gmail.com>\n" +"Language-Team: Slovak (http://www.transifex.com/projects/p/mediagoblin/language/sk/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -24,34 +24,39 @@ msgstr "" "Language: sk\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" -#: mediagoblin/auth/forms.py:28 -msgid "Invalid User name or email address." -msgstr "Nesprávne použÃvateľské meno alebo e-mailová adresa." - -#: mediagoblin/auth/forms.py:29 -msgid "This field does not take email addresses." -msgstr "Toto pole neakceptuje e-mailové adresy." - -#: mediagoblin/auth/forms.py:30 -msgid "This field requires an email address." -msgstr "Toto pole vyžaduje e-mailovú adresu." - -#: mediagoblin/auth/forms.py:52 mediagoblin/auth/forms.py:67 +#: mediagoblin/auth/forms.py:26 msgid "Username" msgstr "PoužÃvateľské meno" -#: mediagoblin/auth/forms.py:56 mediagoblin/auth/forms.py:71 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 +#: mediagoblin/tests/test_util.py:110 msgid "Password" msgstr "Heslo" -#: mediagoblin/auth/forms.py:60 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "Email adresse" -#: mediagoblin/auth/forms.py:78 +#: mediagoblin/auth/forms.py:41 +msgid "Username or Email" +msgstr "Použivateľské meno alebo e-mail" + +#: mediagoblin/auth/forms.py:52 msgid "Username or email" msgstr "PoužÃvateľské meno alebo e-mailová adresa" +#: mediagoblin/auth/tools.py:31 +msgid "Invalid User name or email address." +msgstr "Nesprávne použÃvateľské meno alebo e-mailová adresa." + +#: mediagoblin/auth/tools.py:32 +msgid "This field does not take email addresses." +msgstr "Toto pole neakceptuje e-mailové adresy." + +#: mediagoblin/auth/tools.py:33 +msgid "This field requires an email address." +msgstr "Toto pole vyžaduje e-mailovú adresu." + #: mediagoblin/auth/views.py:54 msgid "Sorry, registration is disabled on this instance." msgstr "PrepáÄ, registrácia na danej inÅ¡tancii nie je povolená." @@ -64,54 +69,54 @@ msgstr "PrepáÄ, rovnaké použÃvateľské meno už existuje." msgid "Sorry, a user with that email address already exists." msgstr "PrepáÄ, rovnaká e-mailová adresa už bola použitá na vytvorenie úÄtu." -#: mediagoblin/auth/views.py:174 +#: 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 overená. Teraz sa môžeÅ¡ prihlásiÅ¥, upravovaÅ¥ profil a vkladaÅ¥ výtvory!" -#: mediagoblin/auth/views.py:180 +#: mediagoblin/auth/views.py:188 msgid "The verification key or user id is incorrect" msgstr "Overovacà kľúÄ, prÃpadne použÃvateľské meno je nesprávne." -#: mediagoblin/auth/views.py:198 +#: mediagoblin/auth/views.py:206 msgid "You must be logged in so we know who to send the email to!" msgstr "Je potrebné prihlásiÅ¥ sa, aby sme vedeli kam máme e-mail zaslaÅ¥!" -#: mediagoblin/auth/views.py:206 +#: mediagoblin/auth/views.py:214 msgid "You've already verified your email address!" msgstr "Už máš overenú e-mailovú adresu!" -#: mediagoblin/auth/views.py:219 +#: mediagoblin/auth/views.py:227 msgid "Resent your verification email." msgstr "Opätovne zaslaÅ¥ overovacà e-mail." -#: mediagoblin/auth/views.py:250 +#: mediagoblin/auth/views.py:258 msgid "" "If that email address (case sensitive!) is registered an email has been sent" " with instructions on how to change your password." msgstr "Pokiaľ daná e-mailová adresa (citlivá na veľkosÅ¥ pÃsma!) je registrovaná, e-mail z inÅ¡trukciami pre zmenu tvojho hesla bol zaslaný." -#: mediagoblin/auth/views.py:261 +#: mediagoblin/auth/views.py:269 msgid "Couldn't find someone with that username." msgstr "Nemožno nájsÅ¥ nikoho z daným použÃvateľským menom." -#: mediagoblin/auth/views.py:264 +#: mediagoblin/auth/views.py:272 msgid "" "An email has been sent with instructions on how to change your password." msgstr "E-mailová správa z inÅ¡trukciami na zmenu tvojho hesla bola zaslaná." -#: mediagoblin/auth/views.py:271 +#: mediagoblin/auth/views.py:279 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." msgstr "Nebolo možné zaslaÅ¥ e-mail na opätovné zÃskanie zabudnutého hesla, nakoľko tvoje použÃvateľské meno je neaktÃvne, prÃpadne e-mailová adresa nebola úspeÅ¡ne overená." -#: mediagoblin/auth/views.py:328 +#: mediagoblin/auth/views.py:336 msgid "You can now log in using your new password." msgstr "Už môžeÅ¡ použiÅ¥ nové heslo pri prihlasovanÃ." -#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:93 +#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:82 #: mediagoblin/submit/forms.py:28 mediagoblin/submit/forms.py:47 #: mediagoblin/user_pages/forms.py:45 msgid "Title" @@ -122,7 +127,7 @@ msgid "Description of this work" msgstr "Popis výtvoru" #: mediagoblin/edit/forms.py:29 mediagoblin/edit/forms.py:52 -#: mediagoblin/edit/forms.py:97 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:86 mediagoblin/submit/forms.py:32 #: mediagoblin/submit/forms.py:51 mediagoblin/user_pages/forms.py:49 msgid "" "You can use\n" @@ -138,11 +143,11 @@ msgstr "Å tÃtky" msgid "Separate tags by commas." msgstr "Oddeľ Å¡tÃtky pomocou Äiarky." -#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:101 +#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:90 msgid "Slug" msgstr "Unikátna ÄasÅ¥ adresy" -#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:102 +#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:91 msgid "The slug can't be empty" msgstr "Unikátna ÄasÅ¥ adresy nesmie byÅ¥ prázdna" @@ -170,45 +175,45 @@ msgid "This address contains errors" msgstr "Daná adresa obsahuje chybu" #: mediagoblin/edit/forms.py:63 -msgid "Old password" -msgstr "Staré heslo" - -#: mediagoblin/edit/forms.py:64 -msgid "Enter your old password to prove you own this account." -msgstr "Vlož svoje staré heslo na dôkaz toho, že vlastnÃÅ¡ daný úÄet." - -#: mediagoblin/edit/forms.py:67 -msgid "New password" -msgstr "Nové heslo" - -#: mediagoblin/edit/forms.py:74 msgid "License preference" msgstr "Preferencia licencie" -#: mediagoblin/edit/forms.py:80 +#: mediagoblin/edit/forms.py:69 msgid "This will be your default license on upload forms." msgstr "Nasledovná licencia bude použitá ako východzia pre vÅ¡etky tvoje výtvory." -#: mediagoblin/edit/forms.py:82 +#: mediagoblin/edit/forms.py:71 msgid "Email me when others comment on my media" msgstr "ZaÅ¡li mi e-mail keÄ ostatnà okomentujú môj výtvor" -#: mediagoblin/edit/forms.py:94 +#: mediagoblin/edit/forms.py:83 msgid "The title can't be empty" msgstr "Titulok nesmie byÅ¥ prázdny." -#: mediagoblin/edit/forms.py:96 mediagoblin/submit/forms.py:50 +#: mediagoblin/edit/forms.py:85 mediagoblin/submit/forms.py:50 #: mediagoblin/user_pages/forms.py:48 msgid "Description of this collection" msgstr "Popis danej kolekcie" -#: mediagoblin/edit/forms.py:103 +#: mediagoblin/edit/forms.py:92 msgid "" "The title part of this collection's address. You usually don't need to " "change this." msgstr "Titulná ÄasÅ¥ adresy danej kolekcie. Zmena poľa nepovinná." -#: mediagoblin/edit/views.py:66 +#: mediagoblin/edit/forms.py:99 +msgid "Old password" +msgstr "Staré heslo" + +#: mediagoblin/edit/forms.py:101 +msgid "Enter your old password to prove you own this account." +msgstr "Vlož svoje staré heslo na dôkaz toho, že vlastnÃÅ¡ daný úÄet." + +#: mediagoblin/edit/forms.py:104 +msgid "New password" +msgstr "Nové heslo" + +#: 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áš." @@ -233,44 +238,63 @@ msgstr "UpravujeÅ¡ profil iného použÃvateľa. Pristupuj zodpovedne. " msgid "Profile changes saved" msgstr "Zmeny v profile uložené" -#: mediagoblin/edit/views.py:241 -msgid "Wrong password" -msgstr "Nesprávne heslo" - -#: mediagoblin/edit/views.py:252 +#: mediagoblin/edit/views.py:240 msgid "Account settings saved" msgstr "Nastavenia úÄtu uložené" -#: mediagoblin/edit/views.py:286 +#: mediagoblin/edit/views.py:274 msgid "You need to confirm the deletion of your account." msgstr "PotrebujeÅ¡ potvrdiÅ¥ odstránenie svojho úÄtu." -#: mediagoblin/edit/views.py:322 mediagoblin/submit/views.py:142 -#: mediagoblin/user_pages/views.py:214 +#: mediagoblin/edit/views.py:310 mediagoblin/submit/views.py:138 +#: mediagoblin/user_pages/views.py:222 #, python-format msgid "You already have a collection called \"%s\"!" msgstr "Už máš kolekciu nazvanú ako \"%s\"!" -#: mediagoblin/edit/views.py:326 +#: mediagoblin/edit/views.py:314 msgid "A collection with that slug already exists for this user." msgstr "Kolekcia s týmto Å¡tÃtkom už máš." -#: mediagoblin/edit/views.py:343 +#: mediagoblin/edit/views.py:329 msgid "You are editing another user's collection. Proceed with caution." msgstr "UpravujeÅ¡ kolekciu iného použÃvateľa. Pristupuj zodpovedne. " -#: mediagoblin/gmg_commands/theme.py:58 +#: mediagoblin/edit/views.py:348 +msgid "Wrong password" +msgstr "Nesprávne heslo" + +#: mediagoblin/edit/views.py:363 +msgid "Your password was changed successfully" +msgstr "Tvoje heslo bolo úspeÅ¡ne zmenené" + +#: mediagoblin/gmg_commands/assetlink.py:60 msgid "Cannot link theme... no theme set\n" msgstr "Nemožno pripojiÅ¥ tému... téma nenastavená\n" -#: mediagoblin/gmg_commands/theme.py:71 +#: mediagoblin/gmg_commands/assetlink.py:73 msgid "No asset directory for this theme\n" msgstr "Žiadny prieÄinok položiek pre túto tému\n" -#: mediagoblin/gmg_commands/theme.py:74 +#: mediagoblin/gmg_commands/assetlink.py:76 msgid "However, old link directory symlink found; removed.\n" msgstr "Odstránené; hoci bol pôvodný symbolický odkaz adresára nájdený.\n" +#: mediagoblin/gmg_commands/assetlink.py:112 +#, python-format +msgid "Could not link \"%s\": %s exists and is not a symlink\n" +msgstr "Nemožno odkazovaÅ¥ na \"%s\": %s existuje a nie je symbolickým odkazom\n" + +#: mediagoblin/gmg_commands/assetlink.py:119 +#, python-format +msgid "Skipping \"%s\"; already set up.\n" +msgstr "Preskakujem \"%s\"; opakovane nastavené.\n" + +#: mediagoblin/gmg_commands/assetlink.py:124 +#, python-format +msgid "Old link found for \"%s\"; removing.\n" +msgstr "Nájdený starý odkaz pre \"%s\"; odstraňujem.\n" + #: mediagoblin/meddleware/csrf.py:134 msgid "" "CSRF cookie not present. This is most likely the result of a cookie blocker " @@ -278,12 +302,16 @@ msgid "" "domain." msgstr "CSRF \"cookie\" neprÃtomný. Toto vidÃÅ¡ najskôr ako výsledok blokovania \"cookie\" súborov a pod.<br/>Uisti sa, že máš povolené ukladanie \"cookies\" pre danú doménu." -#: mediagoblin/media_types/__init__.py:61 -#: mediagoblin/media_types/__init__.py:102 +#: mediagoblin/media_types/__init__.py:111 +#: mediagoblin/media_types/__init__.py:155 msgid "Sorry, I don't support that file type :(" msgstr "PrepáÄ, nepodporujem tento typ súborov =(" -#: mediagoblin/media_types/video/processing.py:36 +#: mediagoblin/media_types/pdf/processing.py:136 +msgid "unoconv failing to run, check log file" +msgstr "beh unoconv zlyhal, preskúmajte log záznam" + +#: mediagoblin/media_types/video/processing.py:37 msgid "Video transcoding failed" msgstr "Konvertovanie videa zlyhalo" @@ -350,7 +378,7 @@ msgstr "Presmerovacie URI pre aplikácie, toto pole\nje <strong>požadované</st msgid "This field is required for public clients" msgstr "Dané pole je požadované pre verejných klientov." -#: mediagoblin/plugins/oauth/views.py:59 +#: mediagoblin/plugins/oauth/views.py:56 msgid "The client {0} has been registered!" msgstr "Klient {0} bol registrovaný!" @@ -369,7 +397,7 @@ msgstr "Tvoji autorizovanà OAuth klienti" msgid "Add" msgstr "PridaÅ¥" -#: mediagoblin/processing/__init__.py:172 +#: mediagoblin/processing/__init__.py:193 msgid "Invalid file given for media type." msgstr "Nesprávny typ súboru pre dané médium." @@ -377,45 +405,45 @@ msgstr "Nesprávny typ súboru pre dané médium." msgid "File" msgstr "Súbor" -#: mediagoblin/submit/views.py:51 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "MusÃÅ¡ poskytnúť súbor." -#: mediagoblin/submit/views.py:97 +#: mediagoblin/submit/views.py:93 msgid "Woohoo! Submitted!" msgstr "Skvelé! Pridané!" -#: mediagoblin/submit/views.py:146 +#: mediagoblin/submit/views.py:144 #, python-format msgid "Collection \"%s\" added!" msgstr "Kolekcia \"%s\" pridaná!" -#: mediagoblin/templates/mediagoblin/base.html:64 +#: mediagoblin/templates/mediagoblin/base.html:67 msgid "Verify your email!" msgstr "Over si e-mailovú adresu!" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:68 msgid "log out" msgstr "odhlásiÅ¥ sa" -#: mediagoblin/templates/mediagoblin/base.html:70 +#: mediagoblin/templates/mediagoblin/base.html:73 #: mediagoblin/templates/mediagoblin/auth/login.html:28 #: mediagoblin/templates/mediagoblin/auth/login.html:36 #: mediagoblin/templates/mediagoblin/auth/login.html:54 msgid "Log in" msgstr "PrihlásiÅ¥ sa" -#: mediagoblin/templates/mediagoblin/base.html:79 +#: mediagoblin/templates/mediagoblin/base.html:82 #, python-format msgid "<a href=\"%(user_url)s\">%(user_name)s</a>'s account" msgstr "ÚÄet použÃvateľa <a href=\"%(user_url)s\">%(user_name)s</a>" -#: mediagoblin/templates/mediagoblin/base.html:86 +#: mediagoblin/templates/mediagoblin/base.html:89 msgid "Change account settings" msgstr "ZmeniÅ¥ nastavenia úÄtu" -#: mediagoblin/templates/mediagoblin/base.html:90 -#: mediagoblin/templates/mediagoblin/base.html:105 +#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:108 #: mediagoblin/templates/mediagoblin/admin/panel.html:21 #: mediagoblin/templates/mediagoblin/admin/panel.html:26 #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:21 @@ -423,72 +451,25 @@ msgstr "ZmeniÅ¥ nastavenia úÄtu" msgid "Media processing panel" msgstr "Sekcia spracovania výtvorov" -#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:96 msgid "Log out" -msgstr "" +msgstr "OdhlásiÅ¥ sa" -#: mediagoblin/templates/mediagoblin/base.html:96 +#: mediagoblin/templates/mediagoblin/base.html:99 #: mediagoblin/templates/mediagoblin/user_pages/user.html:156 msgid "Add media" msgstr "PridaÅ¥ výtvor" -#: mediagoblin/templates/mediagoblin/base.html:99 +#: mediagoblin/templates/mediagoblin/base.html:102 #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:41 msgid "Create new collection" msgstr "VytvoriÅ¥ novú kolekciu" -#: mediagoblin/templates/mediagoblin/base.html:122 -#, python-format -msgid "" -"Powered by <a href=\"http://mediagoblin.org/\" title='Version " -"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." -msgstr "Poháňa nás <a href=\"http://mediagoblin.org/\" title='Version %(version)s'>MediaGoblin</a>, súÄasÅ¥ projektu <a href=\"http://gnu.org/\">GNU</a>." - -#: mediagoblin/templates/mediagoblin/base.html:125 -#, 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 "Uvoľnené pod <a href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a href=\"%(source_link)s\">Zdrojový kód</a> plne dostupný." - #: mediagoblin/templates/mediagoblin/error.html:24 msgid "Image of goblin stressing out" msgstr "Obrázok hysterického goblina" -#: mediagoblin/templates/mediagoblin/root.html:31 -msgid "Explore" -msgstr "PreskúmaÅ¥" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "Ahoj, vitaj na tejto MediaGoblin stránke!" - -#: mediagoblin/templates/mediagoblin/root.html:35 -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Ã." - -#: mediagoblin/templates/mediagoblin/root.html:36 -msgid "" -"To add your own media, place comments, and more, you can log in with your " -"MediaGoblin account." -msgstr "Pre pridanie vlastných výtvorov, komentárov a viac.. sa prihlás zo svojim MediaGoblin úÄtom." - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Don't have one yet? It's easy!" -msgstr "Har du ikke en endnu? Det er let!" - -#: mediagoblin/templates/mediagoblin/root.html:39 -#, 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\">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:47 +#: mediagoblin/templates/mediagoblin/root.html:32 msgid "Most recent media" msgstr "Aktuálne výtvory" @@ -594,6 +575,53 @@ msgid "" "%(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/bits/base_footer.html:21 +#, python-format +msgid "" +"Powered by <a href=\"http://mediagoblin.org/\" title='Version " +"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." +msgstr "Poháňa nás <a href=\"http://mediagoblin.org/\" title='Version %(version)s'>MediaGoblin</a>, súÄasÅ¥ projektu <a href=\"http://gnu.org/\">GNU</a>." + +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:24 +#, 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 "Uvoľnené pod <a href=\"http://www.fsf.org/licensing/licenses/agpl-3.0.html\">AGPL</a>. <a href=\"%(source_link)s\">Zdrojový kód</a> plne dostupný." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:20 +msgid "Explore" +msgstr "PreskúmaÅ¥" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:22 +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "Ahoj, vitaj na tejto MediaGoblin stránke!" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:24 +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Ã." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:25 +msgid "" +"To add your own media, place comments, and more, you can log in with your " +"MediaGoblin account." +msgstr "Pre pridanie vlastných výtvorov, komentárov a viac.. sa prihlás zo svojim MediaGoblin úÄtom." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:27 +msgid "Don't have one yet? It's easy!" +msgstr "Har du ikke en endnu? Det er let!" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:28 +#, 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\">VytvoriÅ¥ úÄet na tejto stránke</a>\n alebo\n <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">NastaviÅ¥ MediaGoblin na vlastnom serveri</a>" + #: mediagoblin/templates/mediagoblin/bits/logo.html:23 #: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 msgid "MediaGoblin logo" @@ -606,13 +634,13 @@ msgid "Editing attachments for %(media_title)s" msgstr "Úprava prÃloh pre %(media_title)s" #: mediagoblin/templates/mediagoblin/edit/attachments.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:159 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:175 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:182 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:198 msgid "Attachments" msgstr "PrÃlohy" #: mediagoblin/templates/mediagoblin/edit/attachments.html:57 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:181 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:204 msgid "Add attachment" msgstr "PridaÅ¥ prÃlohu" @@ -629,12 +657,22 @@ msgstr "ZruÅ¡iÅ¥" #: mediagoblin/templates/mediagoblin/edit/attachments.html:63 #: mediagoblin/templates/mediagoblin/edit/edit.html:42 -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:52 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:55 #: mediagoblin/templates/mediagoblin/edit/edit_collection.html:33 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:40 msgid "Save changes" msgstr "UložiÅ¥ zmeny" +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:28 +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 +#, python-format +msgid "Changing %(username)s's password" +msgstr "MenÃm heslo použÃvateľa %(username)s" + +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 +msgid "Save" +msgstr "UložiÅ¥" + #: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 #, python-format msgid "Really delete user '%(user_name)s' and all related media/comments?" @@ -645,7 +683,7 @@ msgid "Yes, really delete my account" msgstr "Ãno, skutoÄne odstrániÅ¥ môj úÄet" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:48 #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49 msgid "Delete permanently" msgstr "OdstráňiÅ¥ permanentne" @@ -662,7 +700,11 @@ msgstr "Úprava %(media_title)s" msgid "Changing %(username)s's account settings" msgstr "MenÃm nastavenia úÄtu použÃvateľa %(username)s" -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:59 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 +msgid "Change your password." +msgstr "ZmeniÅ¥ svoje heslo." + +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 msgid "Delete my account" msgstr "OdstrániÅ¥ môj úÄet" @@ -687,6 +729,7 @@ msgstr "Výtvory oznaÄené ako: %(tag_name)s" #: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 #: mediagoblin/templates/mediagoblin/media_displays/audio.html:56 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:65 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:136 #: mediagoblin/templates/mediagoblin/media_displays/video.html:55 msgid "Download" @@ -711,6 +754,7 @@ msgid "" 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/audio.html:60 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:71 #: mediagoblin/templates/mediagoblin/media_displays/video.html:61 msgid "Original file" msgstr "Originálny súbor" @@ -719,6 +763,7 @@ msgstr "Originálny súbor" msgid "WebM file (Vorbis codec)" msgstr "WebM súbor (Vorbis kodek)" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:59 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:87 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:93 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:99 @@ -729,6 +774,10 @@ msgstr "WebM súbor (Vorbis kodek)" msgid "Image for %(media_title)s" msgstr "Obrázok pre %(media_title)s" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 +msgid "PDF file" +msgstr "PDF súbor" + #: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 msgid "Toggle Rotate" msgstr "Zapnúť rotáciu" @@ -827,7 +876,7 @@ msgstr "SkutoÄne odstrániÅ¥ %(title)s?" msgid "Really remove %(media_title)s from %(collection_title)s?" msgstr "SkutoÄne odstrániÅ¥ %(media_title)s z %(collection_title)s?" -#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:54 msgid "Remove" msgstr "OdstrániÅ¥" @@ -870,24 +919,28 @@ msgstr "Výtvory, ktoré vlastnà <a href=\"%(user_url)s\">%(username)s</a>" msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>" msgstr "â– Prehliadanie výtvorov od <a href=\"%(user_url)s\">%(username)s</a>" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:94 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:95 msgid "Add a comment" msgstr "PridaÅ¥ komentár" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 msgid "Add this comment" msgstr "PridaÅ¥ tento komentár" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:123 -msgid "at" -msgstr "o" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:144 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:132 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:152 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:164 #, python-format -msgid "" -"<h3>Added on</h3>\n" -" <p>%(date)s</p>" -msgstr "<h3>Pridané</h3>\n <p>%(date)s</p>" +msgid "%(formatted_time)s ago" +msgstr "pred %(formatted_time)s " + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:150 +msgid "Added" +msgstr "Pridané" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:161 +msgid "Created" +msgstr "Vytvorené" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:40 @@ -1043,7 +1096,7 @@ msgstr "starÅ¡ie" msgid "Tagged with" msgstr "OznaÄené ako" -#: mediagoblin/tools/exif.py:80 +#: mediagoblin/tools/exif.py:83 msgid "Could not read the image file." msgstr "Nemožno preÄÃtaÅ¥ súbor obrázka." @@ -1073,6 +1126,30 @@ msgid "" " deleted." msgstr "Zdá sa, že na tejto adrese sa niÄ nenachádza. PrepáÄ!</p><p>Pokiaľ si si istý, že adresa je správna, možno bola hľadaná stránka presunutá, respektÃve odstránená." +#: mediagoblin/tools/timesince.py:62 +msgid "year" +msgstr "rok" + +#: mediagoblin/tools/timesince.py:63 +msgid "month" +msgstr "mesiac" + +#: mediagoblin/tools/timesince.py:64 +msgid "week" +msgstr "týždeň" + +#: mediagoblin/tools/timesince.py:65 +msgid "day" +msgstr "deň" + +#: mediagoblin/tools/timesince.py:66 +msgid "hour" +msgstr "hodina" + +#: mediagoblin/tools/timesince.py:67 +msgid "minute" +msgstr "minúta" + #: mediagoblin/user_pages/forms.py:23 msgid "Comment" msgstr "Komentár" @@ -1104,73 +1181,77 @@ msgstr "-- VybraÅ¥ --" msgid "Include a note" msgstr "PridaÅ¥ poznámku" -#: mediagoblin/user_pages/lib.py:56 +#: mediagoblin/user_pages/lib.py:58 msgid "commented on your post" msgstr "okmentoval tvoj prÃspevok" -#: mediagoblin/user_pages/views.py:166 +#: mediagoblin/user_pages/views.py:169 +msgid "Sorry, comments are disabled." +msgstr "PrepáÄ, komentovanie je vypnuté." + +#: mediagoblin/user_pages/views.py:174 msgid "Oops, your comment was empty." msgstr "Hopla, tvoj komentár bol prázdny." -#: mediagoblin/user_pages/views.py:172 +#: mediagoblin/user_pages/views.py:180 msgid "Your comment has been posted!" msgstr "Tvoj komentár bol pridaný!" -#: mediagoblin/user_pages/views.py:197 +#: mediagoblin/user_pages/views.py:205 msgid "Please check your entries and try again." msgstr "ProsÃm skontroluj svoje položky a skús znova." -#: mediagoblin/user_pages/views.py:237 +#: mediagoblin/user_pages/views.py:245 msgid "You have to select or add a collection" msgstr "MusÃÅ¡ vybraÅ¥, prÃpadne pridaÅ¥ kolekciu" -#: mediagoblin/user_pages/views.py:248 +#: mediagoblin/user_pages/views.py:256 #, python-format msgid "\"%s\" already in collection \"%s\"" msgstr "\"%s\" sa už nachádza v kolekcii \"%s\"" -#: mediagoblin/user_pages/views.py:264 +#: mediagoblin/user_pages/views.py:262 #, python-format msgid "\"%s\" added to collection \"%s\"" msgstr "\"%s pridané do kolekcie \"%s\"" -#: mediagoblin/user_pages/views.py:286 +#: mediagoblin/user_pages/views.py:282 msgid "You deleted the media." msgstr "Výtvor bol tebou odstránený." -#: mediagoblin/user_pages/views.py:293 +#: mediagoblin/user_pages/views.py:289 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:301 +#: mediagoblin/user_pages/views.py:296 msgid "You are about to delete another user's media. Proceed with caution." msgstr "Chystáš sa odstrániÅ¥ výtvory niekoho iného. Pristupuj zodpovedne. " -#: mediagoblin/user_pages/views.py:375 +#: mediagoblin/user_pages/views.py:370 msgid "You deleted the item from the collection." msgstr "Položka bola z kolekcie odstránená." -#: mediagoblin/user_pages/views.py:379 +#: mediagoblin/user_pages/views.py:374 msgid "The item was not removed because you didn't check that you were sure." msgstr "Položka nebola odstránená, nakoľko polÃÄko potvrdenia nebolo oznaÄné." -#: mediagoblin/user_pages/views.py:389 +#: mediagoblin/user_pages/views.py:382 msgid "" "You are about to delete an item from another user's collection. Proceed with" " caution." msgstr "Chystáš sa odstrániÅ¥ položku z kolekcie iného použÃvateľa. Pristupuj zodpovedne. " -#: mediagoblin/user_pages/views.py:422 +#: mediagoblin/user_pages/views.py:415 #, python-format msgid "You deleted the collection \"%s\"" msgstr "Kolekcia \"%s\" bola úspeÅ¡ne odstránená." -#: mediagoblin/user_pages/views.py:429 +#: mediagoblin/user_pages/views.py:422 msgid "" "The collection was not deleted because you didn't check that you were sure." msgstr "Kolekcia nebola odstránená, nakoľko polÃÄko potrvdenia nebolo oznaÄené." -#: mediagoblin/user_pages/views.py:439 +#: mediagoblin/user_pages/views.py:430 msgid "" "You are about to delete another user's collection. Proceed with caution." msgstr "Chystáš sa odstrániÅ¥ kolekciu iného použÃvateľa. Pristupuj zodpovedne. " diff --git a/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.mo Binary files differindex dd3de81b..199e761c 100644 --- a/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.mo +++ b/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.po index 98d62d59..35635acf 100644 --- a/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/sl/LC_MESSAGES/mediagoblin.po @@ -3,15 +3,15 @@ # This file is distributed under the same license as the PROJECT project. # # Translators: -# Jure Repinc <jlp@holodeck1.com>, 2011. +# Jure Repinc <jlp@holodeck1.com>, 2011 msgid "" msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" -"POT-Creation-Date: 2013-03-04 18:04-0600\n" -"PO-Revision-Date: 2013-03-05 00:04+0000\n" +"POT-Creation-Date: 2013-05-27 13:54-0500\n" +"PO-Revision-Date: 2013-05-27 18:54+0000\n" "Last-Translator: cwebber <cwebber@dustycloud.org>\n" -"Language-Team: LANGUAGE <LL@li.org>\n" +"Language-Team: Slovenian (http://www.transifex.com/projects/p/mediagoblin/language/sl/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -19,34 +19,39 @@ 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/auth/forms.py:28 -msgid "Invalid User name or email address." -msgstr "" - -#: mediagoblin/auth/forms.py:29 -msgid "This field does not take email addresses." -msgstr "" - -#: mediagoblin/auth/forms.py:30 -msgid "This field requires an email address." -msgstr "" - -#: mediagoblin/auth/forms.py:52 mediagoblin/auth/forms.py:67 +#: mediagoblin/auth/forms.py:26 msgid "Username" msgstr "UporabniÅ¡ko ime" -#: mediagoblin/auth/forms.py:56 mediagoblin/auth/forms.py:71 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 +#: mediagoblin/tests/test_util.py:110 msgid "Password" msgstr "Geslo" -#: mediagoblin/auth/forms.py:60 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "E-poÅ¡tni naslov" -#: mediagoblin/auth/forms.py:78 +#: mediagoblin/auth/forms.py:41 +msgid "Username or Email" +msgstr "" + +#: mediagoblin/auth/forms.py:52 msgid "Username or email" msgstr "" +#: mediagoblin/auth/tools.py:31 +msgid "Invalid User name or email address." +msgstr "" + +#: mediagoblin/auth/tools.py:32 +msgid "This field does not take email addresses." +msgstr "" + +#: mediagoblin/auth/tools.py:33 +msgid "This field requires an email address." +msgstr "" + #: mediagoblin/auth/views.py:54 msgid "Sorry, registration is disabled on this instance." msgstr "Oprostite, prijava za ta izvod ni omogoÄena." @@ -59,54 +64,54 @@ msgstr "Oprostite, uporabnik s tem imenom že obstaja." msgid "Sorry, a user with that email address already exists." msgstr "" -#: mediagoblin/auth/views.py:174 +#: 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." -#: mediagoblin/auth/views.py:180 +#: 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:198 +#: 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:206 +#: mediagoblin/auth/views.py:214 msgid "You've already verified your email address!" msgstr "" -#: mediagoblin/auth/views.py:219 +#: mediagoblin/auth/views.py:227 msgid "Resent your verification email." msgstr "Ponovno poÅ¡iljanje potrditvene e-poÅ¡te." -#: mediagoblin/auth/views.py:250 +#: mediagoblin/auth/views.py:258 msgid "" "If that email address (case sensitive!) is registered an email has been sent" " with instructions on how to change your password." msgstr "" -#: mediagoblin/auth/views.py:261 +#: mediagoblin/auth/views.py:269 msgid "Couldn't find someone with that username." msgstr "" -#: mediagoblin/auth/views.py:264 +#: mediagoblin/auth/views.py:272 msgid "" "An email has been sent with instructions on how to change your password." msgstr "" -#: mediagoblin/auth/views.py:271 +#: mediagoblin/auth/views.py:279 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." msgstr "" -#: mediagoblin/auth/views.py:328 +#: mediagoblin/auth/views.py:336 msgid "You can now log in using your new password." msgstr "" -#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:93 +#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:82 #: mediagoblin/submit/forms.py:28 mediagoblin/submit/forms.py:47 #: mediagoblin/user_pages/forms.py:45 msgid "Title" @@ -117,7 +122,7 @@ msgid "Description of this work" msgstr "" #: mediagoblin/edit/forms.py:29 mediagoblin/edit/forms.py:52 -#: mediagoblin/edit/forms.py:97 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:86 mediagoblin/submit/forms.py:32 #: mediagoblin/submit/forms.py:51 mediagoblin/user_pages/forms.py:49 msgid "" "You can use\n" @@ -133,11 +138,11 @@ msgstr "Oznake" msgid "Separate tags by commas." msgstr "" -#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:101 +#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:90 msgid "Slug" msgstr "Oznaka" -#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:102 +#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:91 msgid "The slug can't be empty" msgstr "Oznaka ne sme biti prazna" @@ -165,45 +170,45 @@ msgid "This address contains errors" msgstr "" #: mediagoblin/edit/forms.py:63 -msgid "Old password" -msgstr "" - -#: mediagoblin/edit/forms.py:64 -msgid "Enter your old password to prove you own this account." -msgstr "" - -#: mediagoblin/edit/forms.py:67 -msgid "New password" -msgstr "" - -#: mediagoblin/edit/forms.py:74 msgid "License preference" msgstr "" -#: mediagoblin/edit/forms.py:80 +#: mediagoblin/edit/forms.py:69 msgid "This will be your default license on upload forms." msgstr "" -#: mediagoblin/edit/forms.py:82 +#: mediagoblin/edit/forms.py:71 msgid "Email me when others comment on my media" msgstr "" -#: mediagoblin/edit/forms.py:94 +#: mediagoblin/edit/forms.py:83 msgid "The title can't be empty" msgstr "" -#: mediagoblin/edit/forms.py:96 mediagoblin/submit/forms.py:50 +#: mediagoblin/edit/forms.py:85 mediagoblin/submit/forms.py:50 #: mediagoblin/user_pages/forms.py:48 msgid "Description of this collection" msgstr "" -#: mediagoblin/edit/forms.py:103 +#: mediagoblin/edit/forms.py:92 msgid "" "The title part of this collection's address. You usually don't need to " "change this." msgstr "" -#: mediagoblin/edit/views.py:66 +#: mediagoblin/edit/forms.py:99 +msgid "Old password" +msgstr "" + +#: mediagoblin/edit/forms.py:101 +msgid "Enter your old password to prove you own this account." +msgstr "" + +#: mediagoblin/edit/forms.py:104 +msgid "New password" +msgstr "" + +#: mediagoblin/edit/views.py:67 msgid "An entry with that slug already exists for this user." msgstr "Vnos s to oznako za tega uporabnika že obstaja." @@ -228,44 +233,63 @@ msgstr "Urejate uporabniÅ¡ki profil. Nadaljujte pazljivo." msgid "Profile changes saved" msgstr "" -#: mediagoblin/edit/views.py:241 -msgid "Wrong password" -msgstr "" - -#: mediagoblin/edit/views.py:252 +#: mediagoblin/edit/views.py:240 msgid "Account settings saved" msgstr "" -#: mediagoblin/edit/views.py:286 +#: mediagoblin/edit/views.py:274 msgid "You need to confirm the deletion of your account." msgstr "" -#: mediagoblin/edit/views.py:322 mediagoblin/submit/views.py:142 -#: mediagoblin/user_pages/views.py:214 +#: mediagoblin/edit/views.py:310 mediagoblin/submit/views.py:138 +#: mediagoblin/user_pages/views.py:222 #, python-format msgid "You already have a collection called \"%s\"!" msgstr "" -#: mediagoblin/edit/views.py:326 +#: mediagoblin/edit/views.py:314 msgid "A collection with that slug already exists for this user." msgstr "" -#: mediagoblin/edit/views.py:343 +#: mediagoblin/edit/views.py:329 msgid "You are editing another user's collection. Proceed with caution." msgstr "" -#: mediagoblin/gmg_commands/theme.py:58 +#: mediagoblin/edit/views.py:348 +msgid "Wrong password" +msgstr "" + +#: mediagoblin/edit/views.py:363 +msgid "Your password was changed successfully" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:60 msgid "Cannot link theme... no theme set\n" msgstr "" -#: mediagoblin/gmg_commands/theme.py:71 +#: mediagoblin/gmg_commands/assetlink.py:73 msgid "No asset directory for this theme\n" msgstr "" -#: mediagoblin/gmg_commands/theme.py:74 +#: mediagoblin/gmg_commands/assetlink.py:76 msgid "However, old link directory symlink found; removed.\n" msgstr "" +#: mediagoblin/gmg_commands/assetlink.py:112 +#, python-format +msgid "Could not link \"%s\": %s exists and is not a symlink\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:119 +#, python-format +msgid "Skipping \"%s\"; already set up.\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:124 +#, python-format +msgid "Old link found for \"%s\"; removing.\n" +msgstr "" + #: mediagoblin/meddleware/csrf.py:134 msgid "" "CSRF cookie not present. This is most likely the result of a cookie blocker " @@ -273,12 +297,16 @@ msgid "" "domain." msgstr "" -#: mediagoblin/media_types/__init__.py:61 -#: mediagoblin/media_types/__init__.py:102 +#: mediagoblin/media_types/__init__.py:111 +#: mediagoblin/media_types/__init__.py:155 msgid "Sorry, I don't support that file type :(" msgstr "" -#: mediagoblin/media_types/video/processing.py:36 +#: mediagoblin/media_types/pdf/processing.py:136 +msgid "unoconv failing to run, check log file" +msgstr "" + +#: mediagoblin/media_types/video/processing.py:37 msgid "Video transcoding failed" msgstr "" @@ -345,7 +373,7 @@ msgstr "" msgid "This field is required for public clients" msgstr "" -#: mediagoblin/plugins/oauth/views.py:59 +#: mediagoblin/plugins/oauth/views.py:56 msgid "The client {0} has been registered!" msgstr "" @@ -364,7 +392,7 @@ msgstr "" msgid "Add" msgstr "" -#: mediagoblin/processing/__init__.py:172 +#: mediagoblin/processing/__init__.py:193 msgid "Invalid file given for media type." msgstr "Za vrsto vsebine je bila podana napaÄna datoteka." @@ -372,45 +400,45 @@ msgstr "Za vrsto vsebine je bila podana napaÄna datoteka." msgid "File" msgstr "Datoteka" -#: mediagoblin/submit/views.py:51 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "Podati morate datoteko." -#: mediagoblin/submit/views.py:97 +#: mediagoblin/submit/views.py:93 msgid "Woohoo! Submitted!" msgstr "Juhej! Poslano." -#: mediagoblin/submit/views.py:146 +#: mediagoblin/submit/views.py:144 #, python-format msgid "Collection \"%s\" added!" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:64 +#: mediagoblin/templates/mediagoblin/base.html:67 msgid "Verify your email!" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:68 msgid "log out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:70 +#: mediagoblin/templates/mediagoblin/base.html:73 #: mediagoblin/templates/mediagoblin/auth/login.html:28 #: mediagoblin/templates/mediagoblin/auth/login.html:36 #: mediagoblin/templates/mediagoblin/auth/login.html:54 msgid "Log in" msgstr "Prijava" -#: mediagoblin/templates/mediagoblin/base.html:79 +#: mediagoblin/templates/mediagoblin/base.html:82 #, python-format msgid "<a href=\"%(user_url)s\">%(user_name)s</a>'s account" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:86 +#: mediagoblin/templates/mediagoblin/base.html:89 msgid "Change account settings" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:90 -#: mediagoblin/templates/mediagoblin/base.html:105 +#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:108 #: mediagoblin/templates/mediagoblin/admin/panel.html:21 #: mediagoblin/templates/mediagoblin/admin/panel.html:26 #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:21 @@ -418,72 +446,25 @@ msgstr "" msgid "Media processing panel" msgstr "Podokno obdelovanja vsebine" -#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:96 msgid "Log out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:96 +#: mediagoblin/templates/mediagoblin/base.html:99 #: mediagoblin/templates/mediagoblin/user_pages/user.html:156 msgid "Add media" msgstr "Dodaj vsebino" -#: mediagoblin/templates/mediagoblin/base.html:99 +#: mediagoblin/templates/mediagoblin/base.html:102 #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:41 msgid "Create new collection" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:122 -#, python-format -msgid "" -"Powered by <a href=\"http://mediagoblin.org/\" title='Version " -"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." -msgstr "" - -#: mediagoblin/templates/mediagoblin/base.html:125 -#, 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/error.html:24 msgid "Image of goblin stressing out" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:31 -msgid "Explore" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:35 -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:36 -msgid "" -"To add your own media, place comments, and more, you can log in with your " -"MediaGoblin account." -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Don't have one yet? It's easy!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:39 -#, 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:47 +#: mediagoblin/templates/mediagoblin/root.html:32 msgid "Most recent media" msgstr "" @@ -589,6 +570,53 @@ msgid "" "%(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/bits/base_footer.html:21 +#, python-format +msgid "" +"Powered by <a href=\"http://mediagoblin.org/\" title='Version " +"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:24 +#, 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/bits/frontpage_welcome.html:20 +msgid "Explore" +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:22 +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:24 +msgid "" +"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, an " +"extraordinarily great piece of media hosting software." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:25 +msgid "" +"To add your own media, place comments, and more, you can log in with your " +"MediaGoblin account." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:27 +msgid "Don't have one yet? It's easy!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:28 +#, python-format +msgid "" +"<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/bits/logo.html:23 #: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 msgid "MediaGoblin logo" @@ -601,13 +629,13 @@ msgid "Editing attachments for %(media_title)s" msgstr "" #: mediagoblin/templates/mediagoblin/edit/attachments.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:159 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:175 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:182 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:198 msgid "Attachments" msgstr "" #: mediagoblin/templates/mediagoblin/edit/attachments.html:57 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:181 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:204 msgid "Add attachment" msgstr "" @@ -624,12 +652,22 @@ msgstr "PrekliÄi" #: mediagoblin/templates/mediagoblin/edit/attachments.html:63 #: mediagoblin/templates/mediagoblin/edit/edit.html:42 -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:52 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:55 #: mediagoblin/templates/mediagoblin/edit/edit_collection.html:33 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:40 msgid "Save changes" msgstr "Shrani spremembe" +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:28 +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 +#, python-format +msgid "Changing %(username)s's password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 +msgid "Save" +msgstr "" + #: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 #, python-format msgid "Really delete user '%(user_name)s' and all related media/comments?" @@ -640,7 +678,7 @@ msgid "Yes, really delete my account" msgstr "" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:48 #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49 msgid "Delete permanently" msgstr "" @@ -657,7 +695,11 @@ msgstr "Urejanje %(media_title)s" msgid "Changing %(username)s's account settings" msgstr "" -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:59 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 +msgid "Change your password." +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 msgid "Delete my account" msgstr "" @@ -682,6 +724,7 @@ msgstr "" #: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 #: mediagoblin/templates/mediagoblin/media_displays/audio.html:56 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:65 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:136 #: mediagoblin/templates/mediagoblin/media_displays/video.html:55 msgid "Download" @@ -706,6 +749,7 @@ msgid "" msgstr "" #: mediagoblin/templates/mediagoblin/media_displays/audio.html:60 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:71 #: mediagoblin/templates/mediagoblin/media_displays/video.html:61 msgid "Original file" msgstr "" @@ -714,6 +758,7 @@ msgstr "" msgid "WebM file (Vorbis codec)" msgstr "" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:59 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:87 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:93 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:99 @@ -724,6 +769,10 @@ msgstr "" msgid "Image for %(media_title)s" msgstr "" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 +msgid "PDF file" +msgstr "" + #: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 msgid "Toggle Rotate" msgstr "" @@ -822,7 +871,7 @@ msgstr "" msgid "Really remove %(media_title)s from %(collection_title)s?" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:54 msgid "Remove" msgstr "" @@ -865,23 +914,27 @@ msgstr "Vsebina uporabnika <a href=\"%(user_url)s\">%(username)s</a>" msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:94 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:95 msgid "Add a comment" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 msgid "Add this comment" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:123 -msgid "at" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:132 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:152 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:164 +#, python-format +msgid "%(formatted_time)s ago" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:144 -#, python-format -msgid "" -"<h3>Added on</h3>\n" -" <p>%(date)s</p>" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:150 +msgid "Added" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:161 +msgid "Created" msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 @@ -1038,7 +1091,7 @@ msgstr "" msgid "Tagged with" msgstr "" -#: mediagoblin/tools/exif.py:80 +#: mediagoblin/tools/exif.py:83 msgid "Could not read the image file." msgstr "" @@ -1068,6 +1121,30 @@ msgid "" " deleted." msgstr "" +#: mediagoblin/tools/timesince.py:62 +msgid "year" +msgstr "" + +#: mediagoblin/tools/timesince.py:63 +msgid "month" +msgstr "" + +#: mediagoblin/tools/timesince.py:64 +msgid "week" +msgstr "" + +#: mediagoblin/tools/timesince.py:65 +msgid "day" +msgstr "" + +#: mediagoblin/tools/timesince.py:66 +msgid "hour" +msgstr "" + +#: mediagoblin/tools/timesince.py:67 +msgid "minute" +msgstr "" + #: mediagoblin/user_pages/forms.py:23 msgid "Comment" msgstr "" @@ -1099,73 +1176,77 @@ msgstr "" msgid "Include a note" msgstr "" -#: mediagoblin/user_pages/lib.py:56 +#: mediagoblin/user_pages/lib.py:58 msgid "commented on your post" msgstr "" -#: mediagoblin/user_pages/views.py:166 +#: mediagoblin/user_pages/views.py:169 +msgid "Sorry, comments are disabled." +msgstr "" + +#: mediagoblin/user_pages/views.py:174 msgid "Oops, your comment was empty." msgstr "" -#: mediagoblin/user_pages/views.py:172 +#: mediagoblin/user_pages/views.py:180 msgid "Your comment has been posted!" msgstr "" -#: mediagoblin/user_pages/views.py:197 +#: mediagoblin/user_pages/views.py:205 msgid "Please check your entries and try again." msgstr "" -#: mediagoblin/user_pages/views.py:237 +#: mediagoblin/user_pages/views.py:245 msgid "You have to select or add a collection" msgstr "" -#: mediagoblin/user_pages/views.py:248 +#: mediagoblin/user_pages/views.py:256 #, python-format msgid "\"%s\" already in collection \"%s\"" msgstr "" -#: mediagoblin/user_pages/views.py:264 +#: mediagoblin/user_pages/views.py:262 #, python-format msgid "\"%s\" added to collection \"%s\"" msgstr "" -#: mediagoblin/user_pages/views.py:286 +#: mediagoblin/user_pages/views.py:282 msgid "You deleted the media." msgstr "" -#: mediagoblin/user_pages/views.py:293 +#: mediagoblin/user_pages/views.py:289 msgid "The media was not deleted because you didn't check that you were sure." msgstr "" -#: mediagoblin/user_pages/views.py:301 +#: mediagoblin/user_pages/views.py:296 msgid "You are about to delete another user's media. Proceed with caution." msgstr "" -#: mediagoblin/user_pages/views.py:375 +#: mediagoblin/user_pages/views.py:370 msgid "You deleted the item from the collection." msgstr "" -#: mediagoblin/user_pages/views.py:379 +#: mediagoblin/user_pages/views.py:374 msgid "The item was not removed because you didn't check that you were sure." msgstr "" -#: mediagoblin/user_pages/views.py:389 +#: mediagoblin/user_pages/views.py:382 msgid "" "You are about to delete an item from another user's collection. Proceed with" " caution." msgstr "" -#: mediagoblin/user_pages/views.py:422 +#: mediagoblin/user_pages/views.py:415 #, python-format msgid "You deleted the collection \"%s\"" msgstr "" -#: mediagoblin/user_pages/views.py:429 +#: mediagoblin/user_pages/views.py:422 msgid "" "The collection was not deleted because you didn't check that you were sure." msgstr "" -#: mediagoblin/user_pages/views.py:439 +#: mediagoblin/user_pages/views.py:430 msgid "" "You are about to delete another user's collection. Proceed with caution." msgstr "" diff --git a/mediagoblin/i18n/sq/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/sq/LC_MESSAGES/mediagoblin.mo Binary files differindex 276f1273..0f113dcb 100644 --- a/mediagoblin/i18n/sq/LC_MESSAGES/mediagoblin.mo +++ b/mediagoblin/i18n/sq/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/sq/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/sq/LC_MESSAGES/mediagoblin.po index 5c965623..aabf18db 100644 --- a/mediagoblin/i18n/sq/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/sq/LC_MESSAGES/mediagoblin.po @@ -3,14 +3,14 @@ # This file is distributed under the same license as the PROJECT project. # # Translators: -# Besnik Bleta <besnik@programeshqip.org>, 2012. -# FIRST AUTHOR <EMAIL@ADDRESS>, 2012. +# Besnik <besnik@programeshqip.org>, 2012-2013 +# 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: 2013-03-04 18:04-0600\n" -"PO-Revision-Date: 2013-03-05 00:04+0000\n" +"POT-Creation-Date: 2013-05-27 13:54-0500\n" +"PO-Revision-Date: 2013-05-27 18:54+0000\n" "Last-Translator: cwebber <cwebber@dustycloud.org>\n" "Language-Team: Albanian (http://www.transifex.com/projects/p/mediagoblin/language/sq/)\n" "MIME-Version: 1.0\n" @@ -20,34 +20,39 @@ msgstr "" "Language: sq\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: mediagoblin/auth/forms.py:28 -msgid "Invalid User name or email address." -msgstr "" - -#: mediagoblin/auth/forms.py:29 -msgid "This field does not take email addresses." -msgstr "" - -#: mediagoblin/auth/forms.py:30 -msgid "This field requires an email address." -msgstr "" - -#: mediagoblin/auth/forms.py:52 mediagoblin/auth/forms.py:67 +#: mediagoblin/auth/forms.py:26 msgid "Username" msgstr "Emër përdoruesi" -#: mediagoblin/auth/forms.py:56 mediagoblin/auth/forms.py:71 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 +#: mediagoblin/tests/test_util.py:110 msgid "Password" msgstr "Fjalëkalim" -#: mediagoblin/auth/forms.py:60 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "Adresë email" -#: mediagoblin/auth/forms.py:78 +#: mediagoblin/auth/forms.py:41 +msgid "Username or Email" +msgstr "" + +#: mediagoblin/auth/forms.py:52 msgid "Username or email" msgstr "Emër përdoruesi ose email" +#: mediagoblin/auth/tools.py:31 +msgid "Invalid User name or email address." +msgstr "Emër përdoruesi ose adresë email e pavlefshme." + +#: mediagoblin/auth/tools.py:32 +msgid "This field does not take email addresses." +msgstr "Kjo fushë nuk është për adresa email." + +#: mediagoblin/auth/tools.py:33 +msgid "This field requires an email address." +msgstr "Kjo fushë lyp një adresë email." + #: mediagoblin/auth/views.py:54 msgid "Sorry, registration is disabled on this instance." msgstr "Na njdeni, regjistrimi në këtë instancë të shërbimit është i çaktivizuar." @@ -60,54 +65,54 @@ msgstr "Na ndjeni, ka tashmë një përdorues me këtë emër." 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:174 +#: 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:180 +#: 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:198 +#: 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:206 +#: 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:219 +#: mediagoblin/auth/views.py:227 msgid "Resent your verification email." msgstr "Ridërgoni email-in tuaj të verifikimit." -#: mediagoblin/auth/views.py:250 +#: mediagoblin/auth/views.py:258 msgid "" "If that email address (case sensitive!) is registered an email has been sent" " with instructions on how to change your password." -msgstr "" +msgstr "Nëse ajo adresë email (siç është shkruajtur!) është e regjistruar, është dërguar një email me udhëzime se si të ndryshoni fjalëkalimin tuaj." -#: mediagoblin/auth/views.py:261 +#: mediagoblin/auth/views.py:269 msgid "Couldn't find someone with that username." -msgstr "" +msgstr "S'u gjet dot dikush me atë emër përdoruesi." -#: mediagoblin/auth/views.py:264 +#: mediagoblin/auth/views.py:272 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:271 +#: mediagoblin/auth/views.py:279 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." msgstr "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:328 +#: mediagoblin/auth/views.py:336 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/edit/forms.py:93 +#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:82 #: mediagoblin/submit/forms.py:28 mediagoblin/submit/forms.py:47 #: mediagoblin/user_pages/forms.py:45 msgid "Title" @@ -118,7 +123,7 @@ msgid "Description of this work" msgstr "Përshkrim i kësaj pune" #: mediagoblin/edit/forms.py:29 mediagoblin/edit/forms.py:52 -#: mediagoblin/edit/forms.py:97 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:86 mediagoblin/submit/forms.py:32 #: mediagoblin/submit/forms.py:51 mediagoblin/user_pages/forms.py:49 msgid "" "You can use\n" @@ -134,11 +139,11 @@ msgstr "Etiketa" msgid "Separate tags by commas." msgstr "Ndajini etiketat me presje." -#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:101 +#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:90 msgid "Slug" msgstr "Identifikues" -#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:102 +#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:91 msgid "The slug can't be empty" msgstr "Identifikuesi s'mund të jetë i zbrazët" @@ -166,45 +171,45 @@ 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:64 -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:67 -msgid "New password" -msgstr "Fjalëkalimi i ri" - -#: mediagoblin/edit/forms.py:74 msgid "License preference" -msgstr "" +msgstr "Parapëlqime licence" -#: mediagoblin/edit/forms.py:80 +#: mediagoblin/edit/forms.py:69 msgid "This will be your default license on upload forms." -msgstr "" +msgstr "Kjo do të jetë licenca juaj parazgjedhje për forma ngarkimesh." -#: mediagoblin/edit/forms.py:82 +#: mediagoblin/edit/forms.py:71 msgid "Email me when others comment on my media" msgstr "Dërgomë email kur të tjerët komentojnë te media ime" -#: mediagoblin/edit/forms.py:94 +#: mediagoblin/edit/forms.py:83 msgid "The title can't be empty" msgstr "Titulli s'mund të jetë i zbrazët" -#: mediagoblin/edit/forms.py:96 mediagoblin/submit/forms.py:50 +#: mediagoblin/edit/forms.py:85 mediagoblin/submit/forms.py:50 #: mediagoblin/user_pages/forms.py:48 msgid "Description of this collection" msgstr "Përshkrim i këtij koleksioni" -#: mediagoblin/edit/forms.py:103 +#: mediagoblin/edit/forms.py:92 msgid "" "The title part of this collection's address. You usually don't need to " "change this." msgstr "Pjesa titull e adresës së këtij koleksioni. Zakonisht nuk keni pse e ndryshoni këtë." -#: mediagoblin/edit/views.py:66 +#: mediagoblin/edit/forms.py:99 +msgid "Old password" +msgstr "Fjalëkalimi i vjetër" + +#: mediagoblin/edit/forms.py:101 +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:104 +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." @@ -219,7 +224,7 @@ msgstr "Shtuat bashkangjitjen %s!" #: mediagoblin/edit/views.py:182 msgid "You can only edit your own profile." -msgstr "" +msgstr "Mund të përpunoni vetëm profilin tuaj." #: mediagoblin/edit/views.py:188 msgid "You are editing a user's profile. Proceed with caution." @@ -229,57 +234,80 @@ msgstr "Po përpunoni profilin e një përdoruesi. Hapni sytë." msgid "Profile changes saved" msgstr "Ndryshimet e profilit u ruajtën" -#: mediagoblin/edit/views.py:241 -msgid "Wrong password" -msgstr "Fjalëkalim i gabuar" - -#: mediagoblin/edit/views.py:252 +#: mediagoblin/edit/views.py:240 msgid "Account settings saved" msgstr "Rregullimet e llogarisë u ruajtën" -#: mediagoblin/edit/views.py:286 +#: mediagoblin/edit/views.py:274 msgid "You need to confirm the deletion of your account." -msgstr "" +msgstr "Lypset të ripohoni fshirjen e llogarisë suaj." -#: mediagoblin/edit/views.py:322 mediagoblin/submit/views.py:142 -#: mediagoblin/user_pages/views.py:214 +#: mediagoblin/edit/views.py:310 mediagoblin/submit/views.py:138 +#: mediagoblin/user_pages/views.py:222 #, python-format msgid "You already have a collection called \"%s\"!" -msgstr "Keni tashmë një koleksion të quajtur \"%s\"!" +msgstr "Keni tashmë një koleksion të quajtur \"%s\"!" -#: mediagoblin/edit/views.py:326 +#: mediagoblin/edit/views.py:314 msgid "A collection with that slug already exists for this user." msgstr "Ka tashmë një koleksion me atë identifikues për këtë përdorues." -#: mediagoblin/edit/views.py:343 +#: mediagoblin/edit/views.py:329 msgid "You are editing another user's collection. Proceed with caution." msgstr "Po përpunoni koleksionin e një tjetër përdoruesi. Hapni sytë." -#: mediagoblin/gmg_commands/theme.py:58 +#: mediagoblin/edit/views.py:348 +msgid "Wrong password" +msgstr "Fjalëkalim i gabuar" + +#: mediagoblin/edit/views.py:363 +msgid "Your password was changed successfully" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:60 msgid "Cannot link theme... no theme set\n" msgstr "Nuk krijohet dot lidhje për te tema... nuk ka temë të caktuar\n" -#: mediagoblin/gmg_commands/theme.py:71 +#: mediagoblin/gmg_commands/assetlink.py:73 msgid "No asset directory for this theme\n" msgstr "Nuk ka drejtori asetesh për këtë temë\n" -#: mediagoblin/gmg_commands/theme.py:74 +#: mediagoblin/gmg_commands/assetlink.py:76 msgid "However, old link directory symlink found; removed.\n" msgstr "Sidoqoftë, u gjet simlidhje e vjetër drejtorie lidhjesh; u hoq.\n" +#: mediagoblin/gmg_commands/assetlink.py:112 +#, python-format +msgid "Could not link \"%s\": %s exists and is not a symlink\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:119 +#, python-format +msgid "Skipping \"%s\"; already set up.\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:124 +#, python-format +msgid "Old link found for \"%s\"; removing.\n" +msgstr "" + #: mediagoblin/meddleware/csrf.py:134 msgid "" "CSRF cookie not present. This is most likely the result of a cookie blocker " "or somesuch.<br/>Make sure to permit the settings of cookies for this " "domain." -msgstr "" +msgstr "Pa cookie CSRF të pranishme. Ka shumë të ngjarë që të jetë punë e një bllokuesi cookie-sh ose të tillë.<br/>Sigurohuni që të lejoni depozitim cookie-sh për këtë përkatësi." -#: mediagoblin/media_types/__init__.py:61 -#: mediagoblin/media_types/__init__.py:102 +#: mediagoblin/media_types/__init__.py:111 +#: mediagoblin/media_types/__init__.py:155 msgid "Sorry, I don't support that file type :(" msgstr "Na ndjeni, nuk e mbullojmë këtë lloj kartele :(" -#: mediagoblin/media_types/video/processing.py:36 +#: mediagoblin/media_types/pdf/processing.py:136 +msgid "unoconv failing to run, check log file" +msgstr "" + +#: mediagoblin/media_types/video/processing.py:37 msgid "Video transcoding failed" msgstr "Ndërkodimi i videos dështoi" @@ -346,17 +374,17 @@ msgstr "URI ridrejtimi për zbatimin, kjo fushë\n është <strong>e msgid "This field is required for public clients" msgstr "Kjo fushë është e domosdoshme për klientë publikë" -#: mediagoblin/plugins/oauth/views.py:59 +#: mediagoblin/plugins/oauth/views.py:56 msgid "The client {0} has been registered!" msgstr "Klienti {0} u regjistrua!" #: mediagoblin/plugins/oauth/templates/oauth/client/connections.html:22 msgid "OAuth client connections" -msgstr "" +msgstr "Lidhje klienti OAuth" #: mediagoblin/plugins/oauth/templates/oauth/client/list.html:22 msgid "Your OAuth clients" -msgstr "" +msgstr "Klientët tuaj OAuth" #: mediagoblin/plugins/oauth/templates/oauth/client/register.html:29 #: mediagoblin/templates/mediagoblin/submit/collection.html:30 @@ -365,7 +393,7 @@ msgstr "" msgid "Add" msgstr "Shtoni" -#: mediagoblin/processing/__init__.py:172 +#: mediagoblin/processing/__init__.py:193 msgid "Invalid file given for media type." msgstr "Kartelë e gabuar e dhënë për llojin e medias." @@ -373,118 +401,71 @@ msgstr "Kartelë e gabuar e dhënë për llojin e medias." msgid "File" msgstr "Kartelë" -#: mediagoblin/submit/views.py:51 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "Duhet të jepni një kartelë." -#: mediagoblin/submit/views.py:97 +#: mediagoblin/submit/views.py:93 msgid "Woohoo! Submitted!" msgstr "Yhaaaaaa! U parashtrua!" -#: mediagoblin/submit/views.py:146 +#: mediagoblin/submit/views.py:144 #, python-format msgid "Collection \"%s\" added!" msgstr "U shtua koleksioni \"%s\"!" -#: mediagoblin/templates/mediagoblin/base.html:64 +#: mediagoblin/templates/mediagoblin/base.html:67 msgid "Verify your email!" msgstr "Verifikoni email-in tuaj!" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:68 msgid "log out" msgstr "dilni" -#: mediagoblin/templates/mediagoblin/base.html:70 +#: mediagoblin/templates/mediagoblin/base.html:73 #: mediagoblin/templates/mediagoblin/auth/login.html:28 #: mediagoblin/templates/mediagoblin/auth/login.html:36 #: mediagoblin/templates/mediagoblin/auth/login.html:54 msgid "Log in" msgstr "Hyni" -#: mediagoblin/templates/mediagoblin/base.html:79 +#: mediagoblin/templates/mediagoblin/base.html:82 #, python-format msgid "<a href=\"%(user_url)s\">%(user_name)s</a>'s account" msgstr "Llogaria e <a href=\"%(user_url)s\">%(user_name)s</a>" -#: mediagoblin/templates/mediagoblin/base.html:86 +#: mediagoblin/templates/mediagoblin/base.html:89 msgid "Change account settings" msgstr "Ndryshoni rregullime llogarie" -#: mediagoblin/templates/mediagoblin/base.html:90 -#: mediagoblin/templates/mediagoblin/base.html:105 +#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:108 #: mediagoblin/templates/mediagoblin/admin/panel.html:21 #: mediagoblin/templates/mediagoblin/admin/panel.html:26 #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:21 #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:26 msgid "Media processing panel" -msgstr "Paneli i Përpunimit të Medias" +msgstr "Paneli i përpunimit të medias" -#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:96 msgid "Log out" -msgstr "" +msgstr "Dilni" -#: mediagoblin/templates/mediagoblin/base.html:96 +#: mediagoblin/templates/mediagoblin/base.html:99 #: mediagoblin/templates/mediagoblin/user_pages/user.html:156 msgid "Add media" msgstr "Shtoni media" -#: mediagoblin/templates/mediagoblin/base.html:99 +#: mediagoblin/templates/mediagoblin/base.html:102 #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:41 msgid "Create new collection" msgstr "Krijoni koleksion të ri" -#: mediagoblin/templates/mediagoblin/base.html:122 -#, python-format -msgid "" -"Powered by <a href=\"http://mediagoblin.org/\" title='Version " -"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." -msgstr "" - -#: mediagoblin/templates/mediagoblin/base.html:125 -#, 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/error.html:24 msgid "Image of goblin stressing out" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:31 -msgid "Explore" -msgstr "Eksploroni" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "Tungjatjeta juaj, mirë se vini te ky site MediaGoblin!" - -#: mediagoblin/templates/mediagoblin/root.html:35 -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:36 -msgid "" -"To add your own media, place comments, and more, you can log in with your " -"MediaGoblin account." -msgstr "Për të shtuar media tuajën, për të bërë komente, dhe të tjera, mund të hyni përmes llogarisë suaj MediaGoblin." - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Don't have one yet? It's easy!" -msgstr "Nuk keni ende një të tillë? Është e lehtë!" - -#: mediagoblin/templates/mediagoblin/root.html:39 -#, 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>" +msgstr "Figurë e gungaçi duke bërë shtriqje" -#: mediagoblin/templates/mediagoblin/root.html:47 +#: mediagoblin/templates/mediagoblin/root.html:32 msgid "Most recent media" msgstr "Mediat më të reja" @@ -515,7 +496,7 @@ msgstr "Pa zëra të dështuar!" #: mediagoblin/templates/mediagoblin/admin/panel.html:92 msgid "Last 10 successful uploads" -msgstr "10 Ngarkimet e Fundit të Suksesshme" +msgstr "10 ngarkimet e fundit të suksesshme" #: mediagoblin/templates/mediagoblin/admin/panel.html:112 #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:107 @@ -590,6 +571,53 @@ msgid "" "%(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/bits/base_footer.html:21 +#, python-format +msgid "" +"Powered by <a href=\"http://mediagoblin.org/\" title='Version " +"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." +msgstr "Bazuar në <a href=\"http://mediagoblin.org/\" title='Version %(version)s'>MediaGoblin</a>, një projekt <a href=\"http://gnu.org/\">GNU</a>." + +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:24 +#, 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/bits/frontpage_welcome.html:20 +msgid "Explore" +msgstr "Eksploroni" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:22 +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "Tungjatjeta juaj, mirë se vini te ky site MediaGoblin!" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:24 +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/bits/frontpage_welcome.html:25 +msgid "" +"To add your own media, place comments, and more, you can log in with your " +"MediaGoblin account." +msgstr "Për të shtuar media tuajën, për të bërë komente, dhe të tjera, mund të hyni përmes llogarisë suaj MediaGoblin." + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:27 +msgid "Don't have one yet? It's easy!" +msgstr "Nuk keni ende një të tillë? Është e lehtë!" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:28 +#, 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/bits/logo.html:23 #: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 msgid "MediaGoblin logo" @@ -602,13 +630,13 @@ msgid "Editing attachments for %(media_title)s" msgstr "Po përpunohen bashkangjitjet për %(media_title)s" #: mediagoblin/templates/mediagoblin/edit/attachments.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:159 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:175 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:182 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:198 msgid "Attachments" msgstr "Bashkangjitje" #: mediagoblin/templates/mediagoblin/edit/attachments.html:57 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:181 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:204 msgid "Add attachment" msgstr "Shtoni bashkangjitje" @@ -625,23 +653,33 @@ msgstr "Anuloje" #: mediagoblin/templates/mediagoblin/edit/attachments.html:63 #: mediagoblin/templates/mediagoblin/edit/edit.html:42 -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:52 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:55 #: mediagoblin/templates/mediagoblin/edit/edit_collection.html:33 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:40 msgid "Save changes" msgstr "Ruaji ndryshimet" +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:28 +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 +#, python-format +msgid "Changing %(username)s's password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 +msgid "Save" +msgstr "" + #: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 #, python-format msgid "Really delete user '%(user_name)s' and all related media/comments?" -msgstr "" +msgstr "Të fshihet vërtet përdoruesi '%(user_name)s' dhe krejt media/komentet përkatëse?" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:35 msgid "Yes, really delete my account" -msgstr "" +msgstr "Po, fshijeni vërtet llogarinë time" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:48 #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49 msgid "Delete permanently" msgstr "Fshije përgjithmonë" @@ -658,10 +696,14 @@ msgstr "Po përpunohet %(media_title)s" msgid "Changing %(username)s's account settings" msgstr "Po ndryshohen rregullimet e llogarisë %(username)s" -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:59 -msgid "Delete my account" +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 +msgid "Change your password." msgstr "" +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 +msgid "Delete my account" +msgstr "Fshije llogarinë time" + #: mediagoblin/templates/mediagoblin/edit/edit_collection.html:29 #, python-format msgid "Editing %(collection_title)s" @@ -683,6 +725,7 @@ msgstr "Media e etiketuar me:: %(tag_name)s" #: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 #: mediagoblin/templates/mediagoblin/media_displays/audio.html:56 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:65 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:136 #: mediagoblin/templates/mediagoblin/media_displays/video.html:55 msgid "Download" @@ -707,6 +750,7 @@ msgid "" 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/audio.html:60 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:71 #: mediagoblin/templates/mediagoblin/media_displays/video.html:61 msgid "Original file" msgstr "Kartela origjinale" @@ -715,6 +759,7 @@ msgstr "Kartela origjinale" msgid "WebM file (Vorbis codec)" msgstr "Kartelë WebM (kodek Vorbis)" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:59 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:87 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:93 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:99 @@ -725,9 +770,13 @@ msgstr "Kartelë WebM (kodek Vorbis)" msgid "Image for %(media_title)s" msgstr "Figurë për %(media_title)s" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 +msgid "PDF file" +msgstr "" + #: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 msgid "Toggle Rotate" -msgstr "" +msgstr "Aktivizoni/Çaktivizoni Rrotullimin" #: mediagoblin/templates/mediagoblin/media_displays/stl.html:113 msgid "Perspective" @@ -770,14 +819,14 @@ msgid "" "Sorry, this video will not work because\n" " your web browser does not support HTML5 \n" " video." -msgstr "" +msgstr "Na ndjeni, kjo video nuk do të punojë ngaqë\n shfletuesi juaj web nuk mbulon videot\n HTML5." #: mediagoblin/templates/mediagoblin/media_displays/video.html:47 msgid "" "You can get a modern web browser that \n" " can play this video at <a href=\"http://getfirefox.com\">\n" " http://getfirefox.com</a>!" -msgstr "" +msgstr "Mund të merrni një shfletues web modern që \n është në gjendje ta shfaqë këtë video, te <a href=\"http://getfirefox.com\">\n http://getfirefox.com</a>!" #: mediagoblin/templates/mediagoblin/media_displays/video.html:69 msgid "WebM file (640p; VP8/Vorbis)" @@ -823,19 +872,19 @@ msgstr "Të fshihet vërtet %(title)s?" msgid "Really remove %(media_title)s from %(collection_title)s?" msgstr "Të hiqet vërtet %(media_title)s nga %(collection_title)s?" -#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:54 msgid "Remove" msgstr "Hiqe" #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:21 #, python-format msgid "%(username)s's collections" -msgstr "" +msgstr "Koleksione të %(username)s" #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:28 #, python-format msgid "<a href=\"%(user_url)s\">%(username)s</a>'s collections" -msgstr "" +msgstr "Koleksione të <a href=\"%(user_url)s\">%(username)s</a>" #: mediagoblin/templates/mediagoblin/user_pages/comment_email.txt:19 #, python-format @@ -854,7 +903,7 @@ msgstr "Media nga %(username)s" msgid "" "<a href=\"%(user_url)s\">%(username)s</a>'s media with tag <a " "href=\"%(tag_url)s\">%(tag)s</a>" -msgstr "" +msgstr "Media të <a href=\"%(user_url)s\">%(username)s</a> me etiketën <a href=\"%(tag_url)s\">%(tag)s</a>" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:48 #, python-format @@ -866,30 +915,34 @@ msgstr "Media nga <a href=\"%(user_url)s\">%(username)s</a>" 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:94 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:95 msgid "Add a comment" msgstr "Shtoni një koment" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 msgid "Add this comment" msgstr "Shtoje këtë koment" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:123 -msgid "at" -msgstr "te" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:144 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:132 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:152 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:164 #, python-format -msgid "" -"<h3>Added on</h3>\n" -" <p>%(date)s</p>" -msgstr "<h3>Shtuar më</h3>\n <p>%(date)s</p>" +msgid "%(formatted_time)s ago" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:150 +msgid "Added" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:161 +msgid "Created" +msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:40 #, python-format msgid "Add “%(media_title)s†to a collection" -msgstr "" +msgstr "Shtojeni “%(media_title)s†te një koleksion" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:54 msgid "+" @@ -968,7 +1021,7 @@ msgstr "Ky përdorues nuk e ka plotësuar (ende) profilin e vet." #: mediagoblin/templates/mediagoblin/user_pages/user.html:124 msgid "Browse collections" -msgstr "" +msgstr "Shfletoni koleksionet" #: mediagoblin/templates/mediagoblin/user_pages/user.html:137 #, python-format @@ -993,11 +1046,11 @@ msgstr "(hiqe)" #: mediagoblin/templates/mediagoblin/utils/collections.html:21 msgid "Collected in" -msgstr "" +msgstr "Pjesë e koleksionit" #: mediagoblin/templates/mediagoblin/utils/collections.html:40 msgid "Add to a collection" -msgstr "" +msgstr "Shtoje te një koleksion" #: mediagoblin/templates/mediagoblin/utils/feed_link.html:21 #: mediagoblin/themes/airy/templates/mediagoblin/utils/feed_link.html:21 @@ -1039,7 +1092,7 @@ msgstr "më të vjetra" msgid "Tagged with" msgstr "Etiketuar me" -#: mediagoblin/tools/exif.py:80 +#: mediagoblin/tools/exif.py:83 msgid "Could not read the image file." msgstr "Nuk lexoi dot kartelën e figurës." @@ -1069,9 +1122,33 @@ msgid "" " deleted." msgstr "Nuk duket se ka ndonjë faqe në këtë adresë. Na ndjeni!</p><p>Nëse jeni i sigurt se kjo adresë është e saktë, ndoshta faqja që po kërkoni është lëvizur ose fshirë." +#: mediagoblin/tools/timesince.py:62 +msgid "year" +msgstr "" + +#: mediagoblin/tools/timesince.py:63 +msgid "month" +msgstr "" + +#: mediagoblin/tools/timesince.py:64 +msgid "week" +msgstr "" + +#: mediagoblin/tools/timesince.py:65 +msgid "day" +msgstr "" + +#: mediagoblin/tools/timesince.py:66 +msgid "hour" +msgstr "" + +#: mediagoblin/tools/timesince.py:67 +msgid "minute" +msgstr "" + #: mediagoblin/user_pages/forms.py:23 msgid "Comment" -msgstr "" +msgstr "Koment" #: mediagoblin/user_pages/forms.py:25 msgid "" @@ -1090,7 +1167,7 @@ msgstr "Jam i sigurt se dua që të hiqet ky objekt prek koleksioni" #: mediagoblin/user_pages/forms.py:39 msgid "Collection" -msgstr "" +msgstr "Koleksion" #: mediagoblin/user_pages/forms.py:40 msgid "-- Select --" @@ -1100,73 +1177,77 @@ msgstr "-- Përzgjidhni --" msgid "Include a note" msgstr "Përfshini një shënim" -#: mediagoblin/user_pages/lib.py:56 +#: mediagoblin/user_pages/lib.py:58 msgid "commented on your post" msgstr "komentoi te postimi juaj" -#: mediagoblin/user_pages/views.py:166 +#: mediagoblin/user_pages/views.py:169 +msgid "Sorry, comments are disabled." +msgstr "" + +#: mediagoblin/user_pages/views.py:174 msgid "Oops, your comment was empty." msgstr "Hmmm, komenti juaj qe i zbrazët." -#: mediagoblin/user_pages/views.py:172 +#: mediagoblin/user_pages/views.py:180 msgid "Your comment has been posted!" msgstr "Komenti juaj u postua!" -#: mediagoblin/user_pages/views.py:197 +#: mediagoblin/user_pages/views.py:205 msgid "Please check your entries and try again." msgstr "Ju lutemi, kontrolloni zërat tuaj dhe riprovoni." -#: mediagoblin/user_pages/views.py:237 +#: mediagoblin/user_pages/views.py:245 msgid "You have to select or add a collection" msgstr "Duhet të përzgjidhni ose shtoni një koleksion" -#: mediagoblin/user_pages/views.py:248 +#: mediagoblin/user_pages/views.py:256 #, python-format msgid "\"%s\" already in collection \"%s\"" msgstr "\"%s\" gjendet tashmë te koleksioni \"%s\"" -#: mediagoblin/user_pages/views.py:264 +#: mediagoblin/user_pages/views.py:262 #, python-format msgid "\"%s\" added to collection \"%s\"" msgstr "\"%s\" u shtua te koleksioni \"%s\"" -#: mediagoblin/user_pages/views.py:286 +#: mediagoblin/user_pages/views.py:282 msgid "You deleted the media." msgstr "E fshitë median." -#: mediagoblin/user_pages/views.py:293 +#: mediagoblin/user_pages/views.py:289 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:301 +#: mediagoblin/user_pages/views.py:296 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. Hapni sytë." -#: mediagoblin/user_pages/views.py:375 +#: mediagoblin/user_pages/views.py:370 msgid "You deleted the item from the collection." msgstr "E fshitë objektin prej koleksionit." -#: mediagoblin/user_pages/views.py:379 +#: mediagoblin/user_pages/views.py:374 msgid "The item was not removed because you didn't check that you were sure." msgstr "Objekti nuk u fshi ngaqë, nuk pohuat se jeni të sigurt për këtë." -#: mediagoblin/user_pages/views.py:389 +#: mediagoblin/user_pages/views.py:382 msgid "" "You are about to delete an item from another user's collection. Proceed with" " caution." msgstr "Ju ndan një hap nga fshirja e një objekti prej koleksionit të një përdoruesi tjetër. Hapni sytë." -#: mediagoblin/user_pages/views.py:422 +#: mediagoblin/user_pages/views.py:415 #, python-format msgid "You deleted the collection \"%s\"" msgstr "E fshitë koleksionin \"%s\"" -#: mediagoblin/user_pages/views.py:429 +#: mediagoblin/user_pages/views.py:422 msgid "" "The collection was not deleted because you didn't check that you were sure." msgstr "Koleksioni nuk u fshi ngaqë, nuk pohuat se jeni të sigurt për këtë." -#: mediagoblin/user_pages/views.py:439 +#: mediagoblin/user_pages/views.py:430 msgid "" "You are about to delete another user's collection. Proceed with caution." msgstr "Ju ndan një hap nga fshirja e koleksionit të një përdoruesi tjetër. Hapni sytë." diff --git a/mediagoblin/i18n/sr/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/sr/LC_MESSAGES/mediagoblin.mo Binary files differindex f6918f71..5564d35d 100644 --- a/mediagoblin/i18n/sr/LC_MESSAGES/mediagoblin.mo +++ b/mediagoblin/i18n/sr/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/sr/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/sr/LC_MESSAGES/mediagoblin.po index d482151d..fcf8a666 100644 --- a/mediagoblin/i18n/sr/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/sr/LC_MESSAGES/mediagoblin.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" -"POT-Creation-Date: 2013-03-04 18:04-0600\n" -"PO-Revision-Date: 2013-03-05 00:04+0000\n" +"POT-Creation-Date: 2013-05-27 13:54-0500\n" +"PO-Revision-Date: 2013-05-27 18:54+0000\n" "Last-Translator: cwebber <cwebber@dustycloud.org>\n" "Language-Team: Serbian (http://www.transifex.com/projects/p/mediagoblin/language/sr/)\n" "MIME-Version: 1.0\n" @@ -18,32 +18,37 @@ msgstr "" "Language: sr\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -#: mediagoblin/auth/forms.py:28 -msgid "Invalid User name or email address." +#: mediagoblin/auth/forms.py:26 +msgid "Username" msgstr "" -#: mediagoblin/auth/forms.py:29 -msgid "This field does not take email addresses." +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 +#: mediagoblin/tests/test_util.py:110 +msgid "Password" msgstr "" -#: mediagoblin/auth/forms.py:30 -msgid "This field requires an email address." +#: mediagoblin/auth/forms.py:34 +msgid "Email address" msgstr "" -#: mediagoblin/auth/forms.py:52 mediagoblin/auth/forms.py:67 -msgid "Username" +#: mediagoblin/auth/forms.py:41 +msgid "Username or Email" msgstr "" -#: mediagoblin/auth/forms.py:56 mediagoblin/auth/forms.py:71 -msgid "Password" +#: mediagoblin/auth/forms.py:52 +msgid "Username or email" msgstr "" -#: mediagoblin/auth/forms.py:60 -msgid "Email address" +#: mediagoblin/auth/tools.py:31 +msgid "Invalid User name or email address." msgstr "" -#: mediagoblin/auth/forms.py:78 -msgid "Username or email" +#: mediagoblin/auth/tools.py:32 +msgid "This field does not take email addresses." +msgstr "" + +#: mediagoblin/auth/tools.py:33 +msgid "This field requires an email address." msgstr "" #: mediagoblin/auth/views.py:54 @@ -58,54 +63,54 @@ msgstr "" msgid "Sorry, a user with that email address already exists." msgstr "" -#: mediagoblin/auth/views.py:174 +#: 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:180 +#: mediagoblin/auth/views.py:188 msgid "The verification key or user id is incorrect" msgstr "" -#: mediagoblin/auth/views.py:198 +#: 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:206 +#: mediagoblin/auth/views.py:214 msgid "You've already verified your email address!" msgstr "" -#: mediagoblin/auth/views.py:219 +#: mediagoblin/auth/views.py:227 msgid "Resent your verification email." msgstr "" -#: mediagoblin/auth/views.py:250 +#: mediagoblin/auth/views.py:258 msgid "" "If that email address (case sensitive!) is registered an email has been sent" " with instructions on how to change your password." msgstr "" -#: mediagoblin/auth/views.py:261 +#: mediagoblin/auth/views.py:269 msgid "Couldn't find someone with that username." msgstr "" -#: mediagoblin/auth/views.py:264 +#: mediagoblin/auth/views.py:272 msgid "" "An email has been sent with instructions on how to change your password." msgstr "" -#: mediagoblin/auth/views.py:271 +#: mediagoblin/auth/views.py:279 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." msgstr "" -#: mediagoblin/auth/views.py:328 +#: mediagoblin/auth/views.py:336 msgid "You can now log in using your new password." msgstr "" -#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:93 +#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:82 #: mediagoblin/submit/forms.py:28 mediagoblin/submit/forms.py:47 #: mediagoblin/user_pages/forms.py:45 msgid "Title" @@ -116,7 +121,7 @@ msgid "Description of this work" msgstr "" #: mediagoblin/edit/forms.py:29 mediagoblin/edit/forms.py:52 -#: mediagoblin/edit/forms.py:97 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:86 mediagoblin/submit/forms.py:32 #: mediagoblin/submit/forms.py:51 mediagoblin/user_pages/forms.py:49 msgid "" "You can use\n" @@ -132,11 +137,11 @@ msgstr "" msgid "Separate tags by commas." msgstr "" -#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:101 +#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:90 msgid "Slug" msgstr "" -#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:102 +#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:91 msgid "The slug can't be empty" msgstr "" @@ -164,45 +169,45 @@ msgid "This address contains errors" msgstr "" #: mediagoblin/edit/forms.py:63 -msgid "Old password" -msgstr "" - -#: mediagoblin/edit/forms.py:64 -msgid "Enter your old password to prove you own this account." -msgstr "" - -#: mediagoblin/edit/forms.py:67 -msgid "New password" -msgstr "" - -#: mediagoblin/edit/forms.py:74 msgid "License preference" msgstr "" -#: mediagoblin/edit/forms.py:80 +#: mediagoblin/edit/forms.py:69 msgid "This will be your default license on upload forms." msgstr "" -#: mediagoblin/edit/forms.py:82 +#: mediagoblin/edit/forms.py:71 msgid "Email me when others comment on my media" msgstr "" -#: mediagoblin/edit/forms.py:94 +#: mediagoblin/edit/forms.py:83 msgid "The title can't be empty" msgstr "" -#: mediagoblin/edit/forms.py:96 mediagoblin/submit/forms.py:50 +#: mediagoblin/edit/forms.py:85 mediagoblin/submit/forms.py:50 #: mediagoblin/user_pages/forms.py:48 msgid "Description of this collection" msgstr "" -#: mediagoblin/edit/forms.py:103 +#: mediagoblin/edit/forms.py:92 msgid "" "The title part of this collection's address. You usually don't need to " "change this." msgstr "" -#: mediagoblin/edit/views.py:66 +#: mediagoblin/edit/forms.py:99 +msgid "Old password" +msgstr "" + +#: mediagoblin/edit/forms.py:101 +msgid "Enter your old password to prove you own this account." +msgstr "" + +#: mediagoblin/edit/forms.py:104 +msgid "New password" +msgstr "" + +#: mediagoblin/edit/views.py:67 msgid "An entry with that slug already exists for this user." msgstr "" @@ -227,44 +232,63 @@ msgstr "" msgid "Profile changes saved" msgstr "" -#: mediagoblin/edit/views.py:241 -msgid "Wrong password" -msgstr "" - -#: mediagoblin/edit/views.py:252 +#: mediagoblin/edit/views.py:240 msgid "Account settings saved" msgstr "" -#: mediagoblin/edit/views.py:286 +#: mediagoblin/edit/views.py:274 msgid "You need to confirm the deletion of your account." msgstr "" -#: mediagoblin/edit/views.py:322 mediagoblin/submit/views.py:142 -#: mediagoblin/user_pages/views.py:214 +#: mediagoblin/edit/views.py:310 mediagoblin/submit/views.py:138 +#: mediagoblin/user_pages/views.py:222 #, python-format msgid "You already have a collection called \"%s\"!" msgstr "" -#: mediagoblin/edit/views.py:326 +#: mediagoblin/edit/views.py:314 msgid "A collection with that slug already exists for this user." msgstr "" -#: mediagoblin/edit/views.py:343 +#: mediagoblin/edit/views.py:329 msgid "You are editing another user's collection. Proceed with caution." msgstr "" -#: mediagoblin/gmg_commands/theme.py:58 +#: mediagoblin/edit/views.py:348 +msgid "Wrong password" +msgstr "" + +#: mediagoblin/edit/views.py:363 +msgid "Your password was changed successfully" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:60 msgid "Cannot link theme... no theme set\n" msgstr "" -#: mediagoblin/gmg_commands/theme.py:71 +#: mediagoblin/gmg_commands/assetlink.py:73 msgid "No asset directory for this theme\n" msgstr "" -#: mediagoblin/gmg_commands/theme.py:74 +#: mediagoblin/gmg_commands/assetlink.py:76 msgid "However, old link directory symlink found; removed.\n" msgstr "" +#: mediagoblin/gmg_commands/assetlink.py:112 +#, python-format +msgid "Could not link \"%s\": %s exists and is not a symlink\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:119 +#, python-format +msgid "Skipping \"%s\"; already set up.\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:124 +#, python-format +msgid "Old link found for \"%s\"; removing.\n" +msgstr "" + #: mediagoblin/meddleware/csrf.py:134 msgid "" "CSRF cookie not present. This is most likely the result of a cookie blocker " @@ -272,12 +296,16 @@ msgid "" "domain." msgstr "" -#: mediagoblin/media_types/__init__.py:61 -#: mediagoblin/media_types/__init__.py:102 +#: mediagoblin/media_types/__init__.py:111 +#: mediagoblin/media_types/__init__.py:155 msgid "Sorry, I don't support that file type :(" msgstr "" -#: mediagoblin/media_types/video/processing.py:36 +#: mediagoblin/media_types/pdf/processing.py:136 +msgid "unoconv failing to run, check log file" +msgstr "" + +#: mediagoblin/media_types/video/processing.py:37 msgid "Video transcoding failed" msgstr "" @@ -344,7 +372,7 @@ msgstr "" msgid "This field is required for public clients" msgstr "" -#: mediagoblin/plugins/oauth/views.py:59 +#: mediagoblin/plugins/oauth/views.py:56 msgid "The client {0} has been registered!" msgstr "" @@ -363,7 +391,7 @@ msgstr "" msgid "Add" msgstr "" -#: mediagoblin/processing/__init__.py:172 +#: mediagoblin/processing/__init__.py:193 msgid "Invalid file given for media type." msgstr "" @@ -371,45 +399,45 @@ msgstr "" msgid "File" msgstr "" -#: mediagoblin/submit/views.py:51 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "" -#: mediagoblin/submit/views.py:97 +#: mediagoblin/submit/views.py:93 msgid "Woohoo! Submitted!" msgstr "" -#: mediagoblin/submit/views.py:146 +#: mediagoblin/submit/views.py:144 #, python-format msgid "Collection \"%s\" added!" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:64 +#: mediagoblin/templates/mediagoblin/base.html:67 msgid "Verify your email!" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:68 msgid "log out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:70 +#: mediagoblin/templates/mediagoblin/base.html:73 #: mediagoblin/templates/mediagoblin/auth/login.html:28 #: mediagoblin/templates/mediagoblin/auth/login.html:36 #: mediagoblin/templates/mediagoblin/auth/login.html:54 msgid "Log in" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:79 +#: mediagoblin/templates/mediagoblin/base.html:82 #, python-format msgid "<a href=\"%(user_url)s\">%(user_name)s</a>'s account" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:86 +#: mediagoblin/templates/mediagoblin/base.html:89 msgid "Change account settings" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:90 -#: mediagoblin/templates/mediagoblin/base.html:105 +#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:108 #: mediagoblin/templates/mediagoblin/admin/panel.html:21 #: mediagoblin/templates/mediagoblin/admin/panel.html:26 #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:21 @@ -417,72 +445,25 @@ msgstr "" msgid "Media processing panel" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:96 msgid "Log out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:96 +#: mediagoblin/templates/mediagoblin/base.html:99 #: mediagoblin/templates/mediagoblin/user_pages/user.html:156 msgid "Add media" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:99 +#: mediagoblin/templates/mediagoblin/base.html:102 #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:41 msgid "Create new collection" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:122 -#, python-format -msgid "" -"Powered by <a href=\"http://mediagoblin.org/\" title='Version " -"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." -msgstr "" - -#: mediagoblin/templates/mediagoblin/base.html:125 -#, 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/error.html:24 msgid "Image of goblin stressing out" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:31 -msgid "Explore" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:35 -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:36 -msgid "" -"To add your own media, place comments, and more, you can log in with your " -"MediaGoblin account." -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Don't have one yet? It's easy!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:39 -#, 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:47 +#: mediagoblin/templates/mediagoblin/root.html:32 msgid "Most recent media" msgstr "" @@ -588,6 +569,53 @@ msgid "" "%(verification_url)s" msgstr "" +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:21 +#, python-format +msgid "" +"Powered by <a href=\"http://mediagoblin.org/\" title='Version " +"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:24 +#, 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/bits/frontpage_welcome.html:20 +msgid "Explore" +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:22 +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:24 +msgid "" +"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, an " +"extraordinarily great piece of media hosting software." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:25 +msgid "" +"To add your own media, place comments, and more, you can log in with your " +"MediaGoblin account." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:27 +msgid "Don't have one yet? It's easy!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:28 +#, python-format +msgid "" +"<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/bits/logo.html:23 #: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 msgid "MediaGoblin logo" @@ -600,13 +628,13 @@ msgid "Editing attachments for %(media_title)s" msgstr "" #: mediagoblin/templates/mediagoblin/edit/attachments.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:159 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:175 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:182 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:198 msgid "Attachments" msgstr "" #: mediagoblin/templates/mediagoblin/edit/attachments.html:57 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:181 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:204 msgid "Add attachment" msgstr "" @@ -623,12 +651,22 @@ msgstr "" #: mediagoblin/templates/mediagoblin/edit/attachments.html:63 #: mediagoblin/templates/mediagoblin/edit/edit.html:42 -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:52 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:55 #: mediagoblin/templates/mediagoblin/edit/edit_collection.html:33 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:40 msgid "Save changes" msgstr "" +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:28 +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 +#, python-format +msgid "Changing %(username)s's password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 +msgid "Save" +msgstr "" + #: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 #, python-format msgid "Really delete user '%(user_name)s' and all related media/comments?" @@ -639,7 +677,7 @@ msgid "Yes, really delete my account" msgstr "" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:48 #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49 msgid "Delete permanently" msgstr "" @@ -656,7 +694,11 @@ msgstr "" msgid "Changing %(username)s's account settings" msgstr "" -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:59 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 +msgid "Change your password." +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 msgid "Delete my account" msgstr "" @@ -681,6 +723,7 @@ msgstr "" #: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 #: mediagoblin/templates/mediagoblin/media_displays/audio.html:56 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:65 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:136 #: mediagoblin/templates/mediagoblin/media_displays/video.html:55 msgid "Download" @@ -705,6 +748,7 @@ msgid "" msgstr "" #: mediagoblin/templates/mediagoblin/media_displays/audio.html:60 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:71 #: mediagoblin/templates/mediagoblin/media_displays/video.html:61 msgid "Original file" msgstr "" @@ -713,6 +757,7 @@ msgstr "" msgid "WebM file (Vorbis codec)" msgstr "" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:59 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:87 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:93 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:99 @@ -723,6 +768,10 @@ msgstr "" msgid "Image for %(media_title)s" msgstr "" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 +msgid "PDF file" +msgstr "" + #: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 msgid "Toggle Rotate" msgstr "" @@ -821,7 +870,7 @@ msgstr "" msgid "Really remove %(media_title)s from %(collection_title)s?" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:54 msgid "Remove" msgstr "" @@ -864,23 +913,27 @@ msgstr "" msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:94 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:95 msgid "Add a comment" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 msgid "Add this comment" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:123 -msgid "at" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:132 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:152 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:164 +#, python-format +msgid "%(formatted_time)s ago" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:144 -#, python-format -msgid "" -"<h3>Added on</h3>\n" -" <p>%(date)s</p>" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:150 +msgid "Added" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:161 +msgid "Created" msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 @@ -1037,7 +1090,7 @@ msgstr "" msgid "Tagged with" msgstr "" -#: mediagoblin/tools/exif.py:80 +#: mediagoblin/tools/exif.py:83 msgid "Could not read the image file." msgstr "" @@ -1067,6 +1120,30 @@ msgid "" " deleted." msgstr "" +#: mediagoblin/tools/timesince.py:62 +msgid "year" +msgstr "" + +#: mediagoblin/tools/timesince.py:63 +msgid "month" +msgstr "" + +#: mediagoblin/tools/timesince.py:64 +msgid "week" +msgstr "" + +#: mediagoblin/tools/timesince.py:65 +msgid "day" +msgstr "" + +#: mediagoblin/tools/timesince.py:66 +msgid "hour" +msgstr "" + +#: mediagoblin/tools/timesince.py:67 +msgid "minute" +msgstr "" + #: mediagoblin/user_pages/forms.py:23 msgid "Comment" msgstr "" @@ -1098,73 +1175,77 @@ msgstr "" msgid "Include a note" msgstr "" -#: mediagoblin/user_pages/lib.py:56 +#: mediagoblin/user_pages/lib.py:58 msgid "commented on your post" msgstr "" -#: mediagoblin/user_pages/views.py:166 +#: mediagoblin/user_pages/views.py:169 +msgid "Sorry, comments are disabled." +msgstr "" + +#: mediagoblin/user_pages/views.py:174 msgid "Oops, your comment was empty." msgstr "" -#: mediagoblin/user_pages/views.py:172 +#: mediagoblin/user_pages/views.py:180 msgid "Your comment has been posted!" msgstr "" -#: mediagoblin/user_pages/views.py:197 +#: mediagoblin/user_pages/views.py:205 msgid "Please check your entries and try again." msgstr "" -#: mediagoblin/user_pages/views.py:237 +#: mediagoblin/user_pages/views.py:245 msgid "You have to select or add a collection" msgstr "" -#: mediagoblin/user_pages/views.py:248 +#: mediagoblin/user_pages/views.py:256 #, python-format msgid "\"%s\" already in collection \"%s\"" msgstr "" -#: mediagoblin/user_pages/views.py:264 +#: mediagoblin/user_pages/views.py:262 #, python-format msgid "\"%s\" added to collection \"%s\"" msgstr "" -#: mediagoblin/user_pages/views.py:286 +#: mediagoblin/user_pages/views.py:282 msgid "You deleted the media." msgstr "" -#: mediagoblin/user_pages/views.py:293 +#: mediagoblin/user_pages/views.py:289 msgid "The media was not deleted because you didn't check that you were sure." msgstr "" -#: mediagoblin/user_pages/views.py:301 +#: mediagoblin/user_pages/views.py:296 msgid "You are about to delete another user's media. Proceed with caution." msgstr "" -#: mediagoblin/user_pages/views.py:375 +#: mediagoblin/user_pages/views.py:370 msgid "You deleted the item from the collection." msgstr "" -#: mediagoblin/user_pages/views.py:379 +#: mediagoblin/user_pages/views.py:374 msgid "The item was not removed because you didn't check that you were sure." msgstr "" -#: mediagoblin/user_pages/views.py:389 +#: mediagoblin/user_pages/views.py:382 msgid "" "You are about to delete an item from another user's collection. Proceed with" " caution." msgstr "" -#: mediagoblin/user_pages/views.py:422 +#: mediagoblin/user_pages/views.py:415 #, python-format msgid "You deleted the collection \"%s\"" msgstr "" -#: mediagoblin/user_pages/views.py:429 +#: mediagoblin/user_pages/views.py:422 msgid "" "The collection was not deleted because you didn't check that you were sure." msgstr "" -#: mediagoblin/user_pages/views.py:439 +#: mediagoblin/user_pages/views.py:430 msgid "" "You are about to delete another user's collection. Proceed with caution." msgstr "" diff --git a/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.mo Binary files differindex 28ea51f8..3b961e60 100644 --- a/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.mo +++ b/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.po index 76bda505..659de21b 100644 --- a/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/sv/LC_MESSAGES/mediagoblin.po @@ -3,14 +3,14 @@ # This file is distributed under the same license as the PROJECT project. # # Translators: -# <simon@ingenmansland.se>, 2011. -# <transifex@wandborg.se>, 2011, 2012. +# ingenman <simon@ingenmansland.se>, 2011 +# joar <transifex@wandborg.se>, 2011, 2012 msgid "" msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" -"POT-Creation-Date: 2013-03-04 18:04-0600\n" -"PO-Revision-Date: 2013-03-05 00:04+0000\n" +"POT-Creation-Date: 2013-05-27 13:54-0500\n" +"PO-Revision-Date: 2013-05-27 18:54+0000\n" "Last-Translator: cwebber <cwebber@dustycloud.org>\n" "Language-Team: Swedish (http://www.transifex.com/projects/p/mediagoblin/language/sv/)\n" "MIME-Version: 1.0\n" @@ -20,34 +20,39 @@ msgstr "" "Language: sv\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: mediagoblin/auth/forms.py:28 -msgid "Invalid User name or email address." -msgstr "" - -#: mediagoblin/auth/forms.py:29 -msgid "This field does not take email addresses." -msgstr "" - -#: mediagoblin/auth/forms.py:30 -msgid "This field requires an email address." -msgstr "" - -#: mediagoblin/auth/forms.py:52 mediagoblin/auth/forms.py:67 +#: mediagoblin/auth/forms.py:26 msgid "Username" msgstr "Användarnamn" -#: mediagoblin/auth/forms.py:56 mediagoblin/auth/forms.py:71 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 +#: mediagoblin/tests/test_util.py:110 msgid "Password" msgstr "Lösenord" -#: mediagoblin/auth/forms.py:60 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "E-postadress" -#: mediagoblin/auth/forms.py:78 +#: mediagoblin/auth/forms.py:41 +msgid "Username or Email" +msgstr "" + +#: mediagoblin/auth/forms.py:52 msgid "Username or email" msgstr "" +#: mediagoblin/auth/tools.py:31 +msgid "Invalid User name or email address." +msgstr "" + +#: mediagoblin/auth/tools.py:32 +msgid "This field does not take email addresses." +msgstr "" + +#: mediagoblin/auth/tools.py:33 +msgid "This field requires an email address." +msgstr "" + #: mediagoblin/auth/views.py:54 msgid "Sorry, registration is disabled on this instance." msgstr "Vi beklagar, registreringen är avtängd pÃ¥ den här instansen." @@ -60,54 +65,54 @@ msgstr "En användare med det användarnamnet finns redan." 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:174 +#: 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!" -#: mediagoblin/auth/views.py:180 +#: 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:198 +#: 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." -#: mediagoblin/auth/views.py:206 +#: 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:219 +#: mediagoblin/auth/views.py:227 msgid "Resent your verification email." msgstr "Skickade ett nytt verifierings-email." -#: mediagoblin/auth/views.py:250 +#: mediagoblin/auth/views.py:258 msgid "" "If that email address (case sensitive!) is registered an email has been sent" " with instructions on how to change your password." msgstr "" -#: mediagoblin/auth/views.py:261 +#: mediagoblin/auth/views.py:269 msgid "Couldn't find someone with that username." msgstr "" -#: mediagoblin/auth/views.py:264 +#: mediagoblin/auth/views.py:272 msgid "" "An email has been sent with instructions on how to change your password." msgstr "" -#: mediagoblin/auth/views.py:271 +#: mediagoblin/auth/views.py:279 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." msgstr "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:328 +#: mediagoblin/auth/views.py:336 msgid "You can now log in using your new password." msgstr "" -#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:93 +#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:82 #: mediagoblin/submit/forms.py:28 mediagoblin/submit/forms.py:47 #: mediagoblin/user_pages/forms.py:45 msgid "Title" @@ -118,7 +123,7 @@ msgid "Description of this work" msgstr "Beskrivning av verket" #: mediagoblin/edit/forms.py:29 mediagoblin/edit/forms.py:52 -#: mediagoblin/edit/forms.py:97 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:86 mediagoblin/submit/forms.py:32 #: mediagoblin/submit/forms.py:51 mediagoblin/user_pages/forms.py:49 msgid "" "You can use\n" @@ -134,11 +139,11 @@ msgstr "Taggar" msgid "Separate tags by commas." msgstr "" -#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:101 +#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:90 msgid "Slug" msgstr "Sökvägsnamn" -#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:102 +#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:91 msgid "The slug can't be empty" msgstr "Sökvägsnamnet kan inte vara tomt" @@ -166,45 +171,45 @@ msgid "This address contains errors" msgstr "" #: mediagoblin/edit/forms.py:63 -msgid "Old password" -msgstr "Tidigare lösenord" - -#: mediagoblin/edit/forms.py:64 -msgid "Enter your old password to prove you own this account." -msgstr "" - -#: mediagoblin/edit/forms.py:67 -msgid "New password" -msgstr "" - -#: mediagoblin/edit/forms.py:74 msgid "License preference" msgstr "" -#: mediagoblin/edit/forms.py:80 +#: mediagoblin/edit/forms.py:69 msgid "This will be your default license on upload forms." msgstr "" -#: mediagoblin/edit/forms.py:82 +#: mediagoblin/edit/forms.py:71 msgid "Email me when others comment on my media" msgstr "" -#: mediagoblin/edit/forms.py:94 +#: mediagoblin/edit/forms.py:83 msgid "The title can't be empty" msgstr "" -#: mediagoblin/edit/forms.py:96 mediagoblin/submit/forms.py:50 +#: mediagoblin/edit/forms.py:85 mediagoblin/submit/forms.py:50 #: mediagoblin/user_pages/forms.py:48 msgid "Description of this collection" msgstr "" -#: mediagoblin/edit/forms.py:103 +#: mediagoblin/edit/forms.py:92 msgid "" "The title part of this collection's address. You usually don't need to " "change this." msgstr "" -#: mediagoblin/edit/views.py:66 +#: mediagoblin/edit/forms.py:99 +msgid "Old password" +msgstr "Tidigare lösenord" + +#: mediagoblin/edit/forms.py:101 +msgid "Enter your old password to prove you own this account." +msgstr "" + +#: mediagoblin/edit/forms.py:104 +msgid "New password" +msgstr "" + +#: mediagoblin/edit/views.py:67 msgid "An entry with that slug already exists for this user." msgstr "Ett inlägg med det sökvägsnamnet existerar redan." @@ -229,44 +234,63 @@ msgstr "Var försiktig, du redigerar en annan användares profil." msgid "Profile changes saved" msgstr "" -#: mediagoblin/edit/views.py:241 -msgid "Wrong password" -msgstr "Fel lösenord" - -#: mediagoblin/edit/views.py:252 +#: mediagoblin/edit/views.py:240 msgid "Account settings saved" msgstr "" -#: mediagoblin/edit/views.py:286 +#: mediagoblin/edit/views.py:274 msgid "You need to confirm the deletion of your account." msgstr "" -#: mediagoblin/edit/views.py:322 mediagoblin/submit/views.py:142 -#: mediagoblin/user_pages/views.py:214 +#: mediagoblin/edit/views.py:310 mediagoblin/submit/views.py:138 +#: mediagoblin/user_pages/views.py:222 #, python-format msgid "You already have a collection called \"%s\"!" msgstr "" -#: mediagoblin/edit/views.py:326 +#: mediagoblin/edit/views.py:314 msgid "A collection with that slug already exists for this user." msgstr "" -#: mediagoblin/edit/views.py:343 +#: mediagoblin/edit/views.py:329 msgid "You are editing another user's collection. Proceed with caution." msgstr "" -#: mediagoblin/gmg_commands/theme.py:58 +#: mediagoblin/edit/views.py:348 +msgid "Wrong password" +msgstr "Fel lösenord" + +#: mediagoblin/edit/views.py:363 +msgid "Your password was changed successfully" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:60 msgid "Cannot link theme... no theme set\n" msgstr "" -#: mediagoblin/gmg_commands/theme.py:71 +#: mediagoblin/gmg_commands/assetlink.py:73 msgid "No asset directory for this theme\n" msgstr "" -#: mediagoblin/gmg_commands/theme.py:74 +#: mediagoblin/gmg_commands/assetlink.py:76 msgid "However, old link directory symlink found; removed.\n" msgstr "" +#: mediagoblin/gmg_commands/assetlink.py:112 +#, python-format +msgid "Could not link \"%s\": %s exists and is not a symlink\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:119 +#, python-format +msgid "Skipping \"%s\"; already set up.\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:124 +#, python-format +msgid "Old link found for \"%s\"; removing.\n" +msgstr "" + #: mediagoblin/meddleware/csrf.py:134 msgid "" "CSRF cookie not present. This is most likely the result of a cookie blocker " @@ -274,12 +298,16 @@ msgid "" "domain." msgstr "" -#: mediagoblin/media_types/__init__.py:61 -#: mediagoblin/media_types/__init__.py:102 +#: mediagoblin/media_types/__init__.py:111 +#: mediagoblin/media_types/__init__.py:155 msgid "Sorry, I don't support that file type :(" msgstr "" -#: mediagoblin/media_types/video/processing.py:36 +#: mediagoblin/media_types/pdf/processing.py:136 +msgid "unoconv failing to run, check log file" +msgstr "" + +#: mediagoblin/media_types/video/processing.py:37 msgid "Video transcoding failed" msgstr "" @@ -346,7 +374,7 @@ msgstr "" msgid "This field is required for public clients" msgstr "" -#: mediagoblin/plugins/oauth/views.py:59 +#: mediagoblin/plugins/oauth/views.py:56 msgid "The client {0} has been registered!" msgstr "" @@ -365,7 +393,7 @@ msgstr "" msgid "Add" msgstr "" -#: mediagoblin/processing/__init__.py:172 +#: mediagoblin/processing/__init__.py:193 msgid "Invalid file given for media type." msgstr "Ogiltig fil för mediatypen." @@ -373,45 +401,45 @@ msgstr "Ogiltig fil för mediatypen." msgid "File" msgstr "Fil" -#: mediagoblin/submit/views.py:51 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "Du mÃ¥ste ange en fil" -#: mediagoblin/submit/views.py:97 +#: mediagoblin/submit/views.py:93 msgid "Woohoo! Submitted!" msgstr "Tjohoo! Upladdat!" -#: mediagoblin/submit/views.py:146 +#: mediagoblin/submit/views.py:144 #, python-format msgid "Collection \"%s\" added!" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:64 +#: mediagoblin/templates/mediagoblin/base.html:67 msgid "Verify your email!" msgstr "Verifiera din e-postadress" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:68 msgid "log out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:70 +#: mediagoblin/templates/mediagoblin/base.html:73 #: mediagoblin/templates/mediagoblin/auth/login.html:28 #: mediagoblin/templates/mediagoblin/auth/login.html:36 #: mediagoblin/templates/mediagoblin/auth/login.html:54 msgid "Log in" msgstr "Logga in" -#: mediagoblin/templates/mediagoblin/base.html:79 +#: mediagoblin/templates/mediagoblin/base.html:82 #, python-format msgid "<a href=\"%(user_url)s\">%(user_name)s</a>'s account" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:86 +#: mediagoblin/templates/mediagoblin/base.html:89 msgid "Change account settings" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:90 -#: mediagoblin/templates/mediagoblin/base.html:105 +#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:108 #: mediagoblin/templates/mediagoblin/admin/panel.html:21 #: mediagoblin/templates/mediagoblin/admin/panel.html:26 #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:21 @@ -419,72 +447,25 @@ msgstr "" msgid "Media processing panel" msgstr "Mediabehandlingspanel" -#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:96 msgid "Log out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:96 +#: mediagoblin/templates/mediagoblin/base.html:99 #: mediagoblin/templates/mediagoblin/user_pages/user.html:156 msgid "Add media" msgstr "Lägg till media" -#: mediagoblin/templates/mediagoblin/base.html:99 +#: mediagoblin/templates/mediagoblin/base.html:102 #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:41 msgid "Create new collection" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:122 -#, python-format -msgid "" -"Powered by <a href=\"http://mediagoblin.org/\" title='Version " -"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." -msgstr "" - -#: mediagoblin/templates/mediagoblin/base.html:125 -#, 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/error.html:24 msgid "Image of goblin stressing out" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:31 -msgid "Explore" -msgstr "Utforska" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "Hej, välkommen till den här MediaGoblin-sidan!" - -#: mediagoblin/templates/mediagoblin/root.html:35 -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:36 -msgid "" -"To add your own media, place comments, and more, you can log in with your " -"MediaGoblin account." -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Don't have one yet? It's easy!" -msgstr "Har du inte ett redan?" - -#: mediagoblin/templates/mediagoblin/root.html:39 -#, 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:47 +#: mediagoblin/templates/mediagoblin/root.html:32 msgid "Most recent media" msgstr "Senast medier" @@ -590,6 +571,53 @@ msgid "" "%(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/bits/base_footer.html:21 +#, python-format +msgid "" +"Powered by <a href=\"http://mediagoblin.org/\" title='Version " +"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:24 +#, 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/bits/frontpage_welcome.html:20 +msgid "Explore" +msgstr "Utforska" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:22 +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "Hej, välkommen till den här MediaGoblin-sidan!" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:24 +msgid "" +"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, an " +"extraordinarily great piece of media hosting software." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:25 +msgid "" +"To add your own media, place comments, and more, you can log in with your " +"MediaGoblin account." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:27 +msgid "Don't have one yet? It's easy!" +msgstr "Har du inte ett redan?" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:28 +#, 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/bits/logo.html:23 #: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 msgid "MediaGoblin logo" @@ -602,13 +630,13 @@ msgid "Editing attachments for %(media_title)s" msgstr "" #: mediagoblin/templates/mediagoblin/edit/attachments.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:159 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:175 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:182 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:198 msgid "Attachments" msgstr "" #: mediagoblin/templates/mediagoblin/edit/attachments.html:57 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:181 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:204 msgid "Add attachment" msgstr "" @@ -625,12 +653,22 @@ msgstr "Avbryt" #: mediagoblin/templates/mediagoblin/edit/attachments.html:63 #: mediagoblin/templates/mediagoblin/edit/edit.html:42 -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:52 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:55 #: mediagoblin/templates/mediagoblin/edit/edit_collection.html:33 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:40 msgid "Save changes" msgstr "Spara ändringar" +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:28 +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 +#, python-format +msgid "Changing %(username)s's password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 +msgid "Save" +msgstr "" + #: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 #, python-format msgid "Really delete user '%(user_name)s' and all related media/comments?" @@ -641,7 +679,7 @@ msgid "Yes, really delete my account" msgstr "" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:48 #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49 msgid "Delete permanently" msgstr "" @@ -658,7 +696,11 @@ msgstr "Redigerar %(media_title)s" msgid "Changing %(username)s's account settings" msgstr "" -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:59 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 +msgid "Change your password." +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 msgid "Delete my account" msgstr "" @@ -683,6 +725,7 @@ msgstr "Media taggat med: %(tag_name)s" #: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 #: mediagoblin/templates/mediagoblin/media_displays/audio.html:56 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:65 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:136 #: mediagoblin/templates/mediagoblin/media_displays/video.html:55 msgid "Download" @@ -707,6 +750,7 @@ msgid "" msgstr "" #: mediagoblin/templates/mediagoblin/media_displays/audio.html:60 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:71 #: mediagoblin/templates/mediagoblin/media_displays/video.html:61 msgid "Original file" msgstr "" @@ -715,6 +759,7 @@ msgstr "" msgid "WebM file (Vorbis codec)" msgstr "" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:59 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:87 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:93 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:99 @@ -725,6 +770,10 @@ msgstr "" msgid "Image for %(media_title)s" msgstr "" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 +msgid "PDF file" +msgstr "" + #: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 msgid "Toggle Rotate" msgstr "" @@ -823,7 +872,7 @@ msgstr "Vill du verkligen radera %(title)s?" msgid "Really remove %(media_title)s from %(collection_title)s?" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:54 msgid "Remove" msgstr "" @@ -866,23 +915,27 @@ msgstr "<a href=\"%(user_url)s\">%(username)s</a>s media" msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:94 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:95 msgid "Add a comment" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 msgid "Add this comment" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:123 -msgid "at" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:132 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:152 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:164 +#, python-format +msgid "%(formatted_time)s ago" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:144 -#, python-format -msgid "" -"<h3>Added on</h3>\n" -" <p>%(date)s</p>" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:150 +msgid "Added" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:161 +msgid "Created" msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 @@ -1039,7 +1092,7 @@ msgstr "" msgid "Tagged with" msgstr "" -#: mediagoblin/tools/exif.py:80 +#: mediagoblin/tools/exif.py:83 msgid "Could not read the image file." msgstr "" @@ -1069,6 +1122,30 @@ msgid "" " deleted." msgstr "" +#: mediagoblin/tools/timesince.py:62 +msgid "year" +msgstr "" + +#: mediagoblin/tools/timesince.py:63 +msgid "month" +msgstr "" + +#: mediagoblin/tools/timesince.py:64 +msgid "week" +msgstr "" + +#: mediagoblin/tools/timesince.py:65 +msgid "day" +msgstr "" + +#: mediagoblin/tools/timesince.py:66 +msgid "hour" +msgstr "" + +#: mediagoblin/tools/timesince.py:67 +msgid "minute" +msgstr "" + #: mediagoblin/user_pages/forms.py:23 msgid "Comment" msgstr "" @@ -1100,73 +1177,77 @@ msgstr "" msgid "Include a note" msgstr "" -#: mediagoblin/user_pages/lib.py:56 +#: mediagoblin/user_pages/lib.py:58 msgid "commented on your post" msgstr "" -#: mediagoblin/user_pages/views.py:166 +#: mediagoblin/user_pages/views.py:169 +msgid "Sorry, comments are disabled." +msgstr "" + +#: mediagoblin/user_pages/views.py:174 msgid "Oops, your comment was empty." msgstr "" -#: mediagoblin/user_pages/views.py:172 +#: mediagoblin/user_pages/views.py:180 msgid "Your comment has been posted!" msgstr "" -#: mediagoblin/user_pages/views.py:197 +#: mediagoblin/user_pages/views.py:205 msgid "Please check your entries and try again." msgstr "" -#: mediagoblin/user_pages/views.py:237 +#: mediagoblin/user_pages/views.py:245 msgid "You have to select or add a collection" msgstr "" -#: mediagoblin/user_pages/views.py:248 +#: mediagoblin/user_pages/views.py:256 #, python-format msgid "\"%s\" already in collection \"%s\"" msgstr "" -#: mediagoblin/user_pages/views.py:264 +#: mediagoblin/user_pages/views.py:262 #, python-format msgid "\"%s\" added to collection \"%s\"" msgstr "" -#: mediagoblin/user_pages/views.py:286 +#: mediagoblin/user_pages/views.py:282 msgid "You deleted the media." msgstr "" -#: mediagoblin/user_pages/views.py:293 +#: mediagoblin/user_pages/views.py:289 msgid "The media was not deleted because you didn't check that you were sure." msgstr "" -#: mediagoblin/user_pages/views.py:301 +#: mediagoblin/user_pages/views.py:296 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." -#: mediagoblin/user_pages/views.py:375 +#: mediagoblin/user_pages/views.py:370 msgid "You deleted the item from the collection." msgstr "" -#: mediagoblin/user_pages/views.py:379 +#: mediagoblin/user_pages/views.py:374 msgid "The item was not removed because you didn't check that you were sure." msgstr "" -#: mediagoblin/user_pages/views.py:389 +#: mediagoblin/user_pages/views.py:382 msgid "" "You are about to delete an item from another user's collection. Proceed with" " caution." msgstr "" -#: mediagoblin/user_pages/views.py:422 +#: mediagoblin/user_pages/views.py:415 #, python-format msgid "You deleted the collection \"%s\"" msgstr "" -#: mediagoblin/user_pages/views.py:429 +#: mediagoblin/user_pages/views.py:422 msgid "" "The collection was not deleted because you didn't check that you were sure." msgstr "" -#: mediagoblin/user_pages/views.py:439 +#: mediagoblin/user_pages/views.py:430 msgid "" "You are about to delete another user's collection. Proceed with caution." msgstr "" diff --git a/mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.mo Binary files differindex 8cef4593..6e7ebd21 100644 --- a/mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.mo +++ b/mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.po index 3586ee78..b0bf1aa1 100644 --- a/mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/te/LC_MESSAGES/mediagoblin.po @@ -3,15 +3,15 @@ # This file is distributed under the same license as the PROJECT project. # # Translators: -# వీవెనౠ<veeven@gmail.com>, 2011. +# వీవెనౠ<veeven@gmail.com>, 2011 msgid "" msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" -"POT-Creation-Date: 2013-03-04 18:04-0600\n" -"PO-Revision-Date: 2013-03-05 00:04+0000\n" +"POT-Creation-Date: 2013-05-27 13:54-0500\n" +"PO-Revision-Date: 2013-05-27 18:54+0000\n" "Last-Translator: cwebber <cwebber@dustycloud.org>\n" -"Language-Team: LANGUAGE <LL@li.org>\n" +"Language-Team: Telugu (http://www.transifex.com/projects/p/mediagoblin/language/te/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -19,34 +19,39 @@ msgstr "" "Language: te\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: mediagoblin/auth/forms.py:28 -msgid "Invalid User name or email address." -msgstr "" - -#: mediagoblin/auth/forms.py:29 -msgid "This field does not take email addresses." -msgstr "" - -#: mediagoblin/auth/forms.py:30 -msgid "This field requires an email address." -msgstr "" - -#: mediagoblin/auth/forms.py:52 mediagoblin/auth/forms.py:67 +#: mediagoblin/auth/forms.py:26 msgid "Username" msgstr "వాడà±à°•à°°à°¿ పేరà±" -#: mediagoblin/auth/forms.py:56 mediagoblin/auth/forms.py:71 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 +#: mediagoblin/tests/test_util.py:110 msgid "Password" msgstr "సంకేతపదం" -#: mediagoblin/auth/forms.py:60 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "ఈమెయిలౠచిరà±à°¨à°¾à°®à°¾" -#: mediagoblin/auth/forms.py:78 +#: mediagoblin/auth/forms.py:41 +msgid "Username or Email" +msgstr "" + +#: mediagoblin/auth/forms.py:52 msgid "Username or email" msgstr "" +#: mediagoblin/auth/tools.py:31 +msgid "Invalid User name or email address." +msgstr "" + +#: mediagoblin/auth/tools.py:32 +msgid "This field does not take email addresses." +msgstr "" + +#: mediagoblin/auth/tools.py:33 +msgid "This field requires an email address." +msgstr "" + #: mediagoblin/auth/views.py:54 msgid "Sorry, registration is disabled on this instance." msgstr "" @@ -59,54 +64,54 @@ msgstr "" msgid "Sorry, a user with that email address already exists." msgstr "" -#: mediagoblin/auth/views.py:174 +#: 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:180 +#: mediagoblin/auth/views.py:188 msgid "The verification key or user id is incorrect" msgstr "" -#: mediagoblin/auth/views.py:198 +#: 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:206 +#: mediagoblin/auth/views.py:214 msgid "You've already verified your email address!" msgstr "" -#: mediagoblin/auth/views.py:219 +#: mediagoblin/auth/views.py:227 msgid "Resent your verification email." msgstr "" -#: mediagoblin/auth/views.py:250 +#: mediagoblin/auth/views.py:258 msgid "" "If that email address (case sensitive!) is registered an email has been sent" " with instructions on how to change your password." msgstr "" -#: mediagoblin/auth/views.py:261 +#: mediagoblin/auth/views.py:269 msgid "Couldn't find someone with that username." msgstr "" -#: mediagoblin/auth/views.py:264 +#: mediagoblin/auth/views.py:272 msgid "" "An email has been sent with instructions on how to change your password." msgstr "" -#: mediagoblin/auth/views.py:271 +#: mediagoblin/auth/views.py:279 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." msgstr "" -#: mediagoblin/auth/views.py:328 +#: mediagoblin/auth/views.py:336 msgid "You can now log in using your new password." msgstr "" -#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:93 +#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:82 #: mediagoblin/submit/forms.py:28 mediagoblin/submit/forms.py:47 #: mediagoblin/user_pages/forms.py:45 msgid "Title" @@ -117,7 +122,7 @@ msgid "Description of this work" msgstr "" #: mediagoblin/edit/forms.py:29 mediagoblin/edit/forms.py:52 -#: mediagoblin/edit/forms.py:97 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:86 mediagoblin/submit/forms.py:32 #: mediagoblin/submit/forms.py:51 mediagoblin/user_pages/forms.py:49 msgid "" "You can use\n" @@ -133,11 +138,11 @@ msgstr "" msgid "Separate tags by commas." msgstr "" -#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:101 +#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:90 msgid "Slug" msgstr "" -#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:102 +#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:91 msgid "The slug can't be empty" msgstr "" @@ -165,45 +170,45 @@ msgid "This address contains errors" msgstr "" #: mediagoblin/edit/forms.py:63 -msgid "Old password" -msgstr "" - -#: mediagoblin/edit/forms.py:64 -msgid "Enter your old password to prove you own this account." -msgstr "" - -#: mediagoblin/edit/forms.py:67 -msgid "New password" -msgstr "" - -#: mediagoblin/edit/forms.py:74 msgid "License preference" msgstr "" -#: mediagoblin/edit/forms.py:80 +#: mediagoblin/edit/forms.py:69 msgid "This will be your default license on upload forms." msgstr "" -#: mediagoblin/edit/forms.py:82 +#: mediagoblin/edit/forms.py:71 msgid "Email me when others comment on my media" msgstr "" -#: mediagoblin/edit/forms.py:94 +#: mediagoblin/edit/forms.py:83 msgid "The title can't be empty" msgstr "" -#: mediagoblin/edit/forms.py:96 mediagoblin/submit/forms.py:50 +#: mediagoblin/edit/forms.py:85 mediagoblin/submit/forms.py:50 #: mediagoblin/user_pages/forms.py:48 msgid "Description of this collection" msgstr "" -#: mediagoblin/edit/forms.py:103 +#: mediagoblin/edit/forms.py:92 msgid "" "The title part of this collection's address. You usually don't need to " "change this." msgstr "" -#: mediagoblin/edit/views.py:66 +#: mediagoblin/edit/forms.py:99 +msgid "Old password" +msgstr "" + +#: mediagoblin/edit/forms.py:101 +msgid "Enter your old password to prove you own this account." +msgstr "" + +#: mediagoblin/edit/forms.py:104 +msgid "New password" +msgstr "" + +#: mediagoblin/edit/views.py:67 msgid "An entry with that slug already exists for this user." msgstr "" @@ -228,44 +233,63 @@ msgstr "" msgid "Profile changes saved" msgstr "" -#: mediagoblin/edit/views.py:241 -msgid "Wrong password" -msgstr "" - -#: mediagoblin/edit/views.py:252 +#: mediagoblin/edit/views.py:240 msgid "Account settings saved" msgstr "" -#: mediagoblin/edit/views.py:286 +#: mediagoblin/edit/views.py:274 msgid "You need to confirm the deletion of your account." msgstr "" -#: mediagoblin/edit/views.py:322 mediagoblin/submit/views.py:142 -#: mediagoblin/user_pages/views.py:214 +#: mediagoblin/edit/views.py:310 mediagoblin/submit/views.py:138 +#: mediagoblin/user_pages/views.py:222 #, python-format msgid "You already have a collection called \"%s\"!" msgstr "" -#: mediagoblin/edit/views.py:326 +#: mediagoblin/edit/views.py:314 msgid "A collection with that slug already exists for this user." msgstr "" -#: mediagoblin/edit/views.py:343 +#: mediagoblin/edit/views.py:329 msgid "You are editing another user's collection. Proceed with caution." msgstr "" -#: mediagoblin/gmg_commands/theme.py:58 +#: mediagoblin/edit/views.py:348 +msgid "Wrong password" +msgstr "" + +#: mediagoblin/edit/views.py:363 +msgid "Your password was changed successfully" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:60 msgid "Cannot link theme... no theme set\n" msgstr "" -#: mediagoblin/gmg_commands/theme.py:71 +#: mediagoblin/gmg_commands/assetlink.py:73 msgid "No asset directory for this theme\n" msgstr "" -#: mediagoblin/gmg_commands/theme.py:74 +#: mediagoblin/gmg_commands/assetlink.py:76 msgid "However, old link directory symlink found; removed.\n" msgstr "" +#: mediagoblin/gmg_commands/assetlink.py:112 +#, python-format +msgid "Could not link \"%s\": %s exists and is not a symlink\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:119 +#, python-format +msgid "Skipping \"%s\"; already set up.\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:124 +#, python-format +msgid "Old link found for \"%s\"; removing.\n" +msgstr "" + #: mediagoblin/meddleware/csrf.py:134 msgid "" "CSRF cookie not present. This is most likely the result of a cookie blocker " @@ -273,12 +297,16 @@ msgid "" "domain." msgstr "" -#: mediagoblin/media_types/__init__.py:61 -#: mediagoblin/media_types/__init__.py:102 +#: mediagoblin/media_types/__init__.py:111 +#: mediagoblin/media_types/__init__.py:155 msgid "Sorry, I don't support that file type :(" msgstr "" -#: mediagoblin/media_types/video/processing.py:36 +#: mediagoblin/media_types/pdf/processing.py:136 +msgid "unoconv failing to run, check log file" +msgstr "" + +#: mediagoblin/media_types/video/processing.py:37 msgid "Video transcoding failed" msgstr "" @@ -345,7 +373,7 @@ msgstr "" msgid "This field is required for public clients" msgstr "" -#: mediagoblin/plugins/oauth/views.py:59 +#: mediagoblin/plugins/oauth/views.py:56 msgid "The client {0} has been registered!" msgstr "" @@ -364,7 +392,7 @@ msgstr "" msgid "Add" msgstr "" -#: mediagoblin/processing/__init__.py:172 +#: mediagoblin/processing/__init__.py:193 msgid "Invalid file given for media type." msgstr "" @@ -372,45 +400,45 @@ msgstr "" msgid "File" msgstr "" -#: mediagoblin/submit/views.py:51 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "" -#: mediagoblin/submit/views.py:97 +#: mediagoblin/submit/views.py:93 msgid "Woohoo! Submitted!" msgstr "" -#: mediagoblin/submit/views.py:146 +#: mediagoblin/submit/views.py:144 #, python-format msgid "Collection \"%s\" added!" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:64 +#: mediagoblin/templates/mediagoblin/base.html:67 msgid "Verify your email!" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:68 msgid "log out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:70 +#: mediagoblin/templates/mediagoblin/base.html:73 #: mediagoblin/templates/mediagoblin/auth/login.html:28 #: mediagoblin/templates/mediagoblin/auth/login.html:36 #: mediagoblin/templates/mediagoblin/auth/login.html:54 msgid "Log in" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:79 +#: mediagoblin/templates/mediagoblin/base.html:82 #, python-format msgid "<a href=\"%(user_url)s\">%(user_name)s</a>'s account" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:86 +#: mediagoblin/templates/mediagoblin/base.html:89 msgid "Change account settings" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:90 -#: mediagoblin/templates/mediagoblin/base.html:105 +#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:108 #: mediagoblin/templates/mediagoblin/admin/panel.html:21 #: mediagoblin/templates/mediagoblin/admin/panel.html:26 #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:21 @@ -418,72 +446,25 @@ msgstr "" msgid "Media processing panel" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:96 msgid "Log out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:96 +#: mediagoblin/templates/mediagoblin/base.html:99 #: mediagoblin/templates/mediagoblin/user_pages/user.html:156 msgid "Add media" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:99 +#: mediagoblin/templates/mediagoblin/base.html:102 #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:41 msgid "Create new collection" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:122 -#, python-format -msgid "" -"Powered by <a href=\"http://mediagoblin.org/\" title='Version " -"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." -msgstr "" - -#: mediagoblin/templates/mediagoblin/base.html:125 -#, 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/error.html:24 msgid "Image of goblin stressing out" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:31 -msgid "Explore" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:35 -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:36 -msgid "" -"To add your own media, place comments, and more, you can log in with your " -"MediaGoblin account." -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Don't have one yet? It's easy!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:39 -#, 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:47 +#: mediagoblin/templates/mediagoblin/root.html:32 msgid "Most recent media" msgstr "" @@ -589,6 +570,53 @@ msgid "" "%(verification_url)s" msgstr "" +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:21 +#, python-format +msgid "" +"Powered by <a href=\"http://mediagoblin.org/\" title='Version " +"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:24 +#, 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/bits/frontpage_welcome.html:20 +msgid "Explore" +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:22 +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:24 +msgid "" +"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, an " +"extraordinarily great piece of media hosting software." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:25 +msgid "" +"To add your own media, place comments, and more, you can log in with your " +"MediaGoblin account." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:27 +msgid "Don't have one yet? It's easy!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:28 +#, python-format +msgid "" +"<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/bits/logo.html:23 #: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 msgid "MediaGoblin logo" @@ -601,13 +629,13 @@ msgid "Editing attachments for %(media_title)s" msgstr "" #: mediagoblin/templates/mediagoblin/edit/attachments.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:159 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:175 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:182 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:198 msgid "Attachments" msgstr "" #: mediagoblin/templates/mediagoblin/edit/attachments.html:57 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:181 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:204 msgid "Add attachment" msgstr "" @@ -624,12 +652,22 @@ msgstr "à°°à°¦à±à°¦à±à°šà±‡à°¯à°¿" #: mediagoblin/templates/mediagoblin/edit/attachments.html:63 #: mediagoblin/templates/mediagoblin/edit/edit.html:42 -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:52 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:55 #: mediagoblin/templates/mediagoblin/edit/edit_collection.html:33 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:40 msgid "Save changes" msgstr "మారà±à°ªà±à°²à°¨à± à°à°¦à±à°°à°ªà°°à°šà±" +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:28 +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 +#, python-format +msgid "Changing %(username)s's password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 +msgid "Save" +msgstr "" + #: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 #, python-format msgid "Really delete user '%(user_name)s' and all related media/comments?" @@ -640,7 +678,7 @@ msgid "Yes, really delete my account" msgstr "" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:48 #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49 msgid "Delete permanently" msgstr "" @@ -657,7 +695,11 @@ msgstr "" msgid "Changing %(username)s's account settings" msgstr "" -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:59 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 +msgid "Change your password." +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 msgid "Delete my account" msgstr "" @@ -682,6 +724,7 @@ msgstr "" #: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 #: mediagoblin/templates/mediagoblin/media_displays/audio.html:56 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:65 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:136 #: mediagoblin/templates/mediagoblin/media_displays/video.html:55 msgid "Download" @@ -706,6 +749,7 @@ msgid "" msgstr "" #: mediagoblin/templates/mediagoblin/media_displays/audio.html:60 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:71 #: mediagoblin/templates/mediagoblin/media_displays/video.html:61 msgid "Original file" msgstr "" @@ -714,6 +758,7 @@ msgstr "" msgid "WebM file (Vorbis codec)" msgstr "" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:59 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:87 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:93 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:99 @@ -724,6 +769,10 @@ msgstr "" msgid "Image for %(media_title)s" msgstr "" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 +msgid "PDF file" +msgstr "" + #: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 msgid "Toggle Rotate" msgstr "" @@ -822,7 +871,7 @@ msgstr "" msgid "Really remove %(media_title)s from %(collection_title)s?" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:54 msgid "Remove" msgstr "" @@ -865,23 +914,27 @@ msgstr "" msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:94 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:95 msgid "Add a comment" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 msgid "Add this comment" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:123 -msgid "at" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:132 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:152 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:164 +#, python-format +msgid "%(formatted_time)s ago" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:144 -#, python-format -msgid "" -"<h3>Added on</h3>\n" -" <p>%(date)s</p>" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:150 +msgid "Added" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:161 +msgid "Created" msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 @@ -1038,7 +1091,7 @@ msgstr "" msgid "Tagged with" msgstr "" -#: mediagoblin/tools/exif.py:80 +#: mediagoblin/tools/exif.py:83 msgid "Could not read the image file." msgstr "" @@ -1068,6 +1121,30 @@ msgid "" " deleted." msgstr "" +#: mediagoblin/tools/timesince.py:62 +msgid "year" +msgstr "" + +#: mediagoblin/tools/timesince.py:63 +msgid "month" +msgstr "" + +#: mediagoblin/tools/timesince.py:64 +msgid "week" +msgstr "" + +#: mediagoblin/tools/timesince.py:65 +msgid "day" +msgstr "" + +#: mediagoblin/tools/timesince.py:66 +msgid "hour" +msgstr "" + +#: mediagoblin/tools/timesince.py:67 +msgid "minute" +msgstr "" + #: mediagoblin/user_pages/forms.py:23 msgid "Comment" msgstr "" @@ -1099,73 +1176,77 @@ msgstr "" msgid "Include a note" msgstr "" -#: mediagoblin/user_pages/lib.py:56 +#: mediagoblin/user_pages/lib.py:58 msgid "commented on your post" msgstr "" -#: mediagoblin/user_pages/views.py:166 +#: mediagoblin/user_pages/views.py:169 +msgid "Sorry, comments are disabled." +msgstr "" + +#: mediagoblin/user_pages/views.py:174 msgid "Oops, your comment was empty." msgstr "" -#: mediagoblin/user_pages/views.py:172 +#: mediagoblin/user_pages/views.py:180 msgid "Your comment has been posted!" msgstr "" -#: mediagoblin/user_pages/views.py:197 +#: mediagoblin/user_pages/views.py:205 msgid "Please check your entries and try again." msgstr "" -#: mediagoblin/user_pages/views.py:237 +#: mediagoblin/user_pages/views.py:245 msgid "You have to select or add a collection" msgstr "" -#: mediagoblin/user_pages/views.py:248 +#: mediagoblin/user_pages/views.py:256 #, python-format msgid "\"%s\" already in collection \"%s\"" msgstr "" -#: mediagoblin/user_pages/views.py:264 +#: mediagoblin/user_pages/views.py:262 #, python-format msgid "\"%s\" added to collection \"%s\"" msgstr "" -#: mediagoblin/user_pages/views.py:286 +#: mediagoblin/user_pages/views.py:282 msgid "You deleted the media." msgstr "" -#: mediagoblin/user_pages/views.py:293 +#: mediagoblin/user_pages/views.py:289 msgid "The media was not deleted because you didn't check that you were sure." msgstr "" -#: mediagoblin/user_pages/views.py:301 +#: mediagoblin/user_pages/views.py:296 msgid "You are about to delete another user's media. Proceed with caution." msgstr "" -#: mediagoblin/user_pages/views.py:375 +#: mediagoblin/user_pages/views.py:370 msgid "You deleted the item from the collection." msgstr "" -#: mediagoblin/user_pages/views.py:379 +#: mediagoblin/user_pages/views.py:374 msgid "The item was not removed because you didn't check that you were sure." msgstr "" -#: mediagoblin/user_pages/views.py:389 +#: mediagoblin/user_pages/views.py:382 msgid "" "You are about to delete an item from another user's collection. Proceed with" " caution." msgstr "" -#: mediagoblin/user_pages/views.py:422 +#: mediagoblin/user_pages/views.py:415 #, python-format msgid "You deleted the collection \"%s\"" msgstr "" -#: mediagoblin/user_pages/views.py:429 +#: mediagoblin/user_pages/views.py:422 msgid "" "The collection was not deleted because you didn't check that you were sure." msgstr "" -#: mediagoblin/user_pages/views.py:439 +#: mediagoblin/user_pages/views.py:430 msgid "" "You are about to delete another user's collection. Proceed with caution." msgstr "" diff --git a/mediagoblin/i18n/tr_TR/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/tr_TR/LC_MESSAGES/mediagoblin.mo Binary files differnew file mode 100644 index 00000000..4341870b --- /dev/null +++ b/mediagoblin/i18n/tr_TR/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/tr_TR/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/tr_TR/LC_MESSAGES/mediagoblin.po new file mode 100644 index 00000000..4155520f --- /dev/null +++ b/mediagoblin/i18n/tr_TR/LC_MESSAGES/mediagoblin.po @@ -0,0 +1,1252 @@ +# Translations template for PROJECT. +# Copyright (C) 2013 ORGANIZATION +# This file is distributed under the same license as the PROJECT project. +# +# Translators: +# Caner BAÅžARAN <basaran.caner@gmail.com>, 2013 +msgid "" +msgstr "" +"Project-Id-Version: GNU MediaGoblin\n" +"Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" +"POT-Creation-Date: 2013-05-27 13:54-0500\n" +"PO-Revision-Date: 2013-06-06 15:44+0000\n" +"Last-Translator: Caner BAÅžARAN <basaran.caner@gmail.com>\n" +"Language-Team: Turkish (Turkey) (http://www.transifex.com/projects/p/mediagoblin/language/tr_TR/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 0.9.6\n" +"Language: tr_TR\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: mediagoblin/auth/forms.py:26 +msgid "Username" +msgstr "Kullanıcı adı" + +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 +#: mediagoblin/tests/test_util.py:110 +msgid "Password" +msgstr "Parola" + +#: mediagoblin/auth/forms.py:34 +msgid "Email address" +msgstr "E-posta adresi" + +#: mediagoblin/auth/forms.py:41 +msgid "Username or Email" +msgstr "Kullanıcı adı veya E-posta" + +#: mediagoblin/auth/forms.py:52 +msgid "Username or email" +msgstr "Kullanıcı adı ya da e-posta" + +#: mediagoblin/auth/tools.py:31 +msgid "Invalid User name or email address." +msgstr "" + +#: mediagoblin/auth/tools.py:32 +msgid "This field does not take email addresses." +msgstr "" + +#: mediagoblin/auth/tools.py:33 +msgid "This field requires an email address." +msgstr "" + +#: mediagoblin/auth/views.py:54 +msgid "Sorry, registration is disabled on this instance." +msgstr "Üzgünüz, bu durumda kayıt devre dışıdır." + +#: mediagoblin/auth/views.py:68 +msgid "Sorry, a user with that name already exists." +msgstr "Maalesef, bu isimde bir kullanıcı mevcut." + +#: mediagoblin/auth/views.py:72 +msgid "Sorry, a user with that email address already exists." +msgstr "Üzgünüz, bu e-posta adresine sahip bir kullanıcı zaten var." + +#: mediagoblin/auth/views.py:182 +msgid "" +"Your email address has been verified. You may now login, edit your profile, " +"and submit images!" +msgstr "E-posta adresiniz doÄŸrulandı. Åžimdi giriÅŸ yapabilir, profilinizi düzenleyip ve yeni görüntüleri gönderebilirsiniz!" + +#: mediagoblin/auth/views.py:188 +msgid "The verification key or user id is incorrect" +msgstr "DoÄŸrulama anahtarı veya kullanıcı kimliÄŸi yanlış" + +#: mediagoblin/auth/views.py:206 +msgid "You must be logged in so we know who to send the email to!" +msgstr "" + +#: mediagoblin/auth/views.py:214 +msgid "You've already verified your email address!" +msgstr "Zaten e-posta adresinizi doÄŸruladınız!" + +#: mediagoblin/auth/views.py:227 +msgid "Resent your verification email." +msgstr "DoÄŸrulama e-postasını tekrar yolla." + +#: mediagoblin/auth/views.py:258 +msgid "" +"If that email address (case sensitive!) is registered an email has been sent" +" with instructions on how to change your password." +msgstr "" + +#: mediagoblin/auth/views.py:269 +msgid "Couldn't find someone with that username." +msgstr "" + +#: mediagoblin/auth/views.py:272 +msgid "" +"An email has been sent with instructions on how to change your password." +msgstr "Parolanızı nasıl deÄŸiÅŸtireceÄŸinizle ilgili adımları anlatan bir e-posta gönderildi." + +#: mediagoblin/auth/views.py:279 +msgid "" +"Could not send password recovery email as your username is inactive or your " +"account's email address has not been verified." +msgstr "" + +#: mediagoblin/auth/views.py:336 +msgid "You can now log in using your new password." +msgstr "Åžimdi yeni parolanızı giriÅŸ için kullanabilirsiniz." + +#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:82 +#: mediagoblin/submit/forms.py:28 mediagoblin/submit/forms.py:47 +#: mediagoblin/user_pages/forms.py:45 +msgid "Title" +msgstr "BaÅŸlık" + +#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:31 +msgid "Description of this work" +msgstr "" + +#: mediagoblin/edit/forms.py:29 mediagoblin/edit/forms.py:52 +#: mediagoblin/edit/forms.py:86 mediagoblin/submit/forms.py:32 +#: mediagoblin/submit/forms.py:51 mediagoblin/user_pages/forms.py:49 +msgid "" +"You can use\n" +" <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 "Etiketler" + +#: mediagoblin/edit/forms.py:35 mediagoblin/submit/forms.py:38 +msgid "Separate tags by commas." +msgstr "Etikerleri virgül ile ayırın." + +#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:90 +msgid "Slug" +msgstr "" + +#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:91 +msgid "The slug can't be empty" +msgstr "" + +#: mediagoblin/edit/forms.py:40 +msgid "" +"The title part of this media's address. You usually don't need to change " +"this." +msgstr "" + +#: mediagoblin/edit/forms.py:44 mediagoblin/submit/forms.py:41 +#: mediagoblin/templates/mediagoblin/utils/license.html:20 +msgid "License" +msgstr "" + +#: mediagoblin/edit/forms.py:50 +msgid "Bio" +msgstr "" + +#: mediagoblin/edit/forms.py:56 +msgid "Website" +msgstr "Web sitesi" + +#: mediagoblin/edit/forms.py:58 +msgid "This address contains errors" +msgstr "" + +#: mediagoblin/edit/forms.py:63 +msgid "License preference" +msgstr "" + +#: mediagoblin/edit/forms.py:69 +msgid "This will be your default license on upload forms." +msgstr "" + +#: mediagoblin/edit/forms.py:71 +msgid "Email me when others comment on my media" +msgstr "Medyama birisi yorum yazdığında bana e-posta at" + +#: mediagoblin/edit/forms.py:83 +msgid "The title can't be empty" +msgstr "" + +#: mediagoblin/edit/forms.py:85 mediagoblin/submit/forms.py:50 +#: mediagoblin/user_pages/forms.py:48 +msgid "Description of this collection" +msgstr "" + +#: mediagoblin/edit/forms.py:92 +msgid "" +"The title part of this collection's address. You usually don't need to " +"change this." +msgstr "" + +#: mediagoblin/edit/forms.py:99 +msgid "Old password" +msgstr "Eski parola" + +#: mediagoblin/edit/forms.py:101 +msgid "Enter your old password to prove you own this account." +msgstr "" + +#: mediagoblin/edit/forms.py:104 +msgid "New password" +msgstr "Yeni parola" + +#: mediagoblin/edit/views.py:67 +msgid "An entry with that slug already exists for this user." +msgstr "" + +#: mediagoblin/edit/views.py:85 +msgid "You are editing another user's media. Proceed with caution." +msgstr "BaÅŸka bir kullanıcının medyasını düzenlerken dikkatli davranın." + +#: mediagoblin/edit/views.py:155 +#, python-format +msgid "You added the attachment %s!" +msgstr "" + +#: mediagoblin/edit/views.py:182 +msgid "You can only edit your own profile." +msgstr "" + +#: mediagoblin/edit/views.py:188 +msgid "You are editing a user's profile. Proceed with caution." +msgstr "BaÅŸka bir kullanıcının profilini düzenlerken dikkatli davranın." + +#: mediagoblin/edit/views.py:204 +msgid "Profile changes saved" +msgstr "Profil deÄŸiÅŸiklikleri kaydedildi" + +#: mediagoblin/edit/views.py:240 +msgid "Account settings saved" +msgstr "Hesap ayarları kaydedildi" + +#: mediagoblin/edit/views.py:274 +msgid "You need to confirm the deletion of your account." +msgstr "" + +#: mediagoblin/edit/views.py:310 mediagoblin/submit/views.py:138 +#: mediagoblin/user_pages/views.py:222 +#, python-format +msgid "You already have a collection called \"%s\"!" +msgstr "" + +#: mediagoblin/edit/views.py:314 +msgid "A collection with that slug already exists for this user." +msgstr "" + +#: mediagoblin/edit/views.py:329 +msgid "You are editing another user's collection. Proceed with caution." +msgstr "" + +#: mediagoblin/edit/views.py:348 +msgid "Wrong password" +msgstr "Yanlış parola" + +#: mediagoblin/edit/views.py:363 +msgid "Your password was changed successfully" +msgstr "Parolanız baÅŸarılı bir ÅŸekilde deÄŸiÅŸtirildi" + +#: mediagoblin/gmg_commands/assetlink.py:60 +msgid "Cannot link theme... no theme set\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:73 +msgid "No asset directory for this theme\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:76 +msgid "However, old link directory symlink found; removed.\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:112 +#, python-format +msgid "Could not link \"%s\": %s exists and is not a symlink\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:119 +#, python-format +msgid "Skipping \"%s\"; already set up.\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:124 +#, python-format +msgid "Old link found for \"%s\"; removing.\n" +msgstr "" + +#: mediagoblin/meddleware/csrf.py:134 +msgid "" +"CSRF cookie not present. This is most likely the result of a cookie blocker " +"or somesuch.<br/>Make sure to permit the settings of cookies for this " +"domain." +msgstr "" + +#: mediagoblin/media_types/__init__.py:111 +#: mediagoblin/media_types/__init__.py:155 +msgid "Sorry, I don't support that file type :(" +msgstr "Üzgünüz, bu tip dosyaları desteklemiyoruz :(" + +#: mediagoblin/media_types/pdf/processing.py:136 +msgid "unoconv failing to run, check log file" +msgstr "" + +#: mediagoblin/media_types/video/processing.py:37 +msgid "Video transcoding failed" +msgstr "" + +#: mediagoblin/plugins/geolocation/templates/mediagoblin/plugins/geolocation/map.html:24 +msgid "Location" +msgstr "" + +#: mediagoblin/plugins/geolocation/templates/mediagoblin/plugins/geolocation/map.html:52 +#, python-format +msgid "View on <a href=\"%(osm_url)s\">OpenStreetMap</a>" +msgstr "" + +#: mediagoblin/plugins/oauth/forms.py:29 +msgid "Allow" +msgstr "" + +#: mediagoblin/plugins/oauth/forms.py:30 +msgid "Deny" +msgstr "" + +#: mediagoblin/plugins/oauth/forms.py:34 +msgid "Name" +msgstr "" + +#: mediagoblin/plugins/oauth/forms.py:35 +msgid "The name of the OAuth client" +msgstr "" + +#: mediagoblin/plugins/oauth/forms.py:36 +msgid "Description" +msgstr "" + +#: mediagoblin/plugins/oauth/forms.py:38 +msgid "" +"This will be visible to users allowing your\n" +" application to authenticate as them." +msgstr "" + +#: mediagoblin/plugins/oauth/forms.py:40 +msgid "Type" +msgstr "Tür" + +#: mediagoblin/plugins/oauth/forms.py:45 +msgid "" +"<strong>Confidential</strong> - The client can\n" +" make requests to the GNU MediaGoblin instance that can not be\n" +" intercepted by the user agent (e.g. server-side client).<br />\n" +" <strong>Public</strong> - The client can't make confidential\n" +" requests to the GNU MediaGoblin instance (e.g. client-side\n" +" JavaScript client)." +msgstr "" + +#: mediagoblin/plugins/oauth/forms.py:52 +msgid "Redirect URI" +msgstr "" + +#: mediagoblin/plugins/oauth/forms.py:54 +msgid "" +"The redirect URI for the applications, this field\n" +" is <strong>required</strong> for public clients." +msgstr "" + +#: mediagoblin/plugins/oauth/forms.py:66 +msgid "This field is required for public clients" +msgstr "" + +#: mediagoblin/plugins/oauth/views.py:56 +msgid "The client {0} has been registered!" +msgstr "" + +#: mediagoblin/plugins/oauth/templates/oauth/client/connections.html:22 +msgid "OAuth client connections" +msgstr "" + +#: mediagoblin/plugins/oauth/templates/oauth/client/list.html:22 +msgid "Your OAuth clients" +msgstr "" + +#: mediagoblin/plugins/oauth/templates/oauth/client/register.html:29 +#: mediagoblin/templates/mediagoblin/submit/collection.html:30 +#: mediagoblin/templates/mediagoblin/submit/start.html:34 +#: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:68 +msgid "Add" +msgstr "Ekle" + +#: mediagoblin/processing/__init__.py:193 +msgid "Invalid file given for media type." +msgstr "Bu medya türü için geçersiz dosya türü." + +#: mediagoblin/submit/forms.py:26 +msgid "File" +msgstr "Dosya" + +#: mediagoblin/submit/views.py:49 +msgid "You must provide a file." +msgstr "Bir dosya saÄŸlamanız gerekir." + +#: mediagoblin/submit/views.py:93 +msgid "Woohoo! Submitted!" +msgstr "Hoooop! Gönderildi!" + +#: mediagoblin/submit/views.py:144 +#, python-format +msgid "Collection \"%s\" added!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:67 +msgid "Verify your email!" +msgstr "E-postanızı doÄŸrulayın!" + +#: mediagoblin/templates/mediagoblin/base.html:68 +msgid "log out" +msgstr "çıkış" + +#: mediagoblin/templates/mediagoblin/base.html:73 +#: mediagoblin/templates/mediagoblin/auth/login.html:28 +#: mediagoblin/templates/mediagoblin/auth/login.html:36 +#: mediagoblin/templates/mediagoblin/auth/login.html:54 +msgid "Log in" +msgstr "GiriÅŸ" + +#: mediagoblin/templates/mediagoblin/base.html:82 +#, python-format +msgid "<a href=\"%(user_url)s\">%(user_name)s</a>'s account" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:89 +msgid "Change account settings" +msgstr "Hesap ayarlarını deÄŸiÅŸtir" + +#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:108 +#: mediagoblin/templates/mediagoblin/admin/panel.html:21 +#: mediagoblin/templates/mediagoblin/admin/panel.html:26 +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:21 +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:26 +msgid "Media processing panel" +msgstr "Madya iÅŸlem paneli" + +#: mediagoblin/templates/mediagoblin/base.html:96 +msgid "Log out" +msgstr "Çıkış" + +#: mediagoblin/templates/mediagoblin/base.html:99 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:156 +msgid "Add media" +msgstr "Medya ekle" + +#: mediagoblin/templates/mediagoblin/base.html:102 +#: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:41 +msgid "Create new collection" +msgstr "" + +#: mediagoblin/templates/mediagoblin/error.html:24 +msgid "Image of goblin stressing out" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:32 +msgid "Most recent media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/admin/panel.html:29 +msgid "" +"Here you can track the state of media being processed on this instance." +msgstr "" + +#: mediagoblin/templates/mediagoblin/admin/panel.html:32 +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:32 +msgid "Media in-processing" +msgstr "" + +#: mediagoblin/templates/mediagoblin/admin/panel.html:58 +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:56 +msgid "No media in-processing" +msgstr "" + +#: mediagoblin/templates/mediagoblin/admin/panel.html:61 +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:59 +msgid "These uploads failed to process:" +msgstr "" + +#: mediagoblin/templates/mediagoblin/admin/panel.html:90 +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:86 +msgid "No failed entries!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/admin/panel.html:92 +msgid "Last 10 successful uploads" +msgstr "" + +#: mediagoblin/templates/mediagoblin/admin/panel.html:112 +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:107 +msgid "No processed entries, yet!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:28 +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:36 +msgid "Set your new password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:39 +msgid "Set password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:23 +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:31 +msgid "Recover password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:34 +msgid "Send instructions" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/fp_verification_email.txt:19 +#, python-format +msgid "" +"Hi %(username)s,\n" +"\n" +"to change your GNU MediaGoblin password, open the following URL in \n" +"your web browser:\n" +"\n" +"%(verification_url)s\n" +"\n" +"If you think this is an error, just ignore this email and continue being\n" +"a happy goblin!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/login.html:39 +msgid "Logging in failed!" +msgstr "GiriÅŸ baÅŸarısız!" + +#: mediagoblin/templates/mediagoblin/auth/login.html:44 +msgid "Don't have an account yet?" +msgstr "Hala hesabınız yok mu?" + +#: mediagoblin/templates/mediagoblin/auth/login.html:45 +msgid "Create one here!" +msgstr "Åžimdi oluÅŸturun!" + +#: mediagoblin/templates/mediagoblin/auth/login.html:51 +msgid "Forgot your password?" +msgstr "Parolanı mı unuttun?" + +#: mediagoblin/templates/mediagoblin/auth/register.html:28 +#: mediagoblin/templates/mediagoblin/auth/register.html:36 +msgid "Create an account!" +msgstr "Hesap oluÅŸtur!" + +#: mediagoblin/templates/mediagoblin/auth/register.html:40 +msgid "Create" +msgstr "OluÅŸtur" + +#: mediagoblin/templates/mediagoblin/auth/verification_email.txt:19 +#, python-format +msgid "" +"Hi %(username)s,\n" +"\n" +"to activate your GNU MediaGoblin account, open the following URL in\n" +"your web browser:\n" +"\n" +"%(verification_url)s" +msgstr "Merhaba %(username)s,\n\nGNU MediaGoblin hesabınızı etkinleÅŸtirmek için, lütfen aÅŸağıdaki\nURL(baÄŸlantı)'yı Web tarayıcınızda açın:\n\n%(verification_url)s" + +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:21 +#, python-format +msgid "" +"Powered by <a href=\"http://mediagoblin.org/\" title='Version " +"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:24 +#, 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/bits/frontpage_welcome.html:20 +msgid "Explore" +msgstr "KeÅŸfet" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:22 +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:24 +msgid "" +"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, an " +"extraordinarily great piece of media hosting software." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:25 +msgid "" +"To add your own media, place comments, and more, you can log in with your " +"MediaGoblin account." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:27 +msgid "Don't have one yet? It's easy!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:28 +#, python-format +msgid "" +"<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/bits/logo.html:23 +#: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 +msgid "MediaGoblin logo" +msgstr "MediaGoblin logo" + +#: mediagoblin/templates/mediagoblin/edit/attachments.html:23 +#: mediagoblin/templates/mediagoblin/edit/attachments.html:35 +#, python-format +msgid "Editing attachments for %(media_title)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/attachments.html:44 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:182 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:198 +msgid "Attachments" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/attachments.html:57 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:204 +msgid "Add attachment" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/attachments.html:61 +#: mediagoblin/templates/mediagoblin/edit/delete_account.html:42 +#: mediagoblin/templates/mediagoblin/edit/edit.html:41 +#: mediagoblin/templates/mediagoblin/edit/edit_collection.html:32 +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:46 +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:52 +#: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:67 +#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:48 +msgid "Cancel" +msgstr "İptal" + +#: mediagoblin/templates/mediagoblin/edit/attachments.html:63 +#: mediagoblin/templates/mediagoblin/edit/edit.html:42 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:55 +#: mediagoblin/templates/mediagoblin/edit/edit_collection.html:33 +#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:40 +msgid "Save changes" +msgstr "DeÄŸiÅŸiklikleri kaydet" + +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:28 +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 +#, python-format +msgid "Changing %(username)s's password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 +msgid "Save" +msgstr "Kaydet" + +#: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 +#, python-format +msgid "Really delete user '%(user_name)s' and all related media/comments?" +msgstr "Gerçekten '%(user_name)s' kullanıcısını ve ilgili tüm medya/yorumları silmek istiyor musun?" + +#: mediagoblin/templates/mediagoblin/edit/delete_account.html:35 +msgid "Yes, really delete my account" +msgstr "Evet, gerçekten hesabımı silmek istiyorum" + +#: mediagoblin/templates/mediagoblin/edit/delete_account.html:44 +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:48 +#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49 +msgid "Delete permanently" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:23 +#: mediagoblin/templates/mediagoblin/edit/edit.html:35 +#, python-format +msgid "Editing %(media_title)s" +msgstr "%(media_title)s düzenleme" + +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:28 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:40 +#, python-format +msgid "Changing %(username)s's account settings" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 +msgid "Change your password." +msgstr "Parolanızı deÄŸiÅŸtirin." + +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 +msgid "Delete my account" +msgstr "Hesabımı sil" + +#: mediagoblin/templates/mediagoblin/edit/edit_collection.html:29 +#, python-format +msgid "Editing %(collection_title)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:23 +#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:34 +#, python-format +msgid "Editing %(username)s's profile" +msgstr "%(username)s profilini düzenleme" + +#: mediagoblin/templates/mediagoblin/listings/collection.html:30 +#: mediagoblin/templates/mediagoblin/listings/collection.html:35 +#: mediagoblin/templates/mediagoblin/listings/tag.html:30 +#: mediagoblin/templates/mediagoblin/listings/tag.html:35 +#, python-format +msgid "Media tagged with: %(tag_name)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 +#: mediagoblin/templates/mediagoblin/media_displays/audio.html:56 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:65 +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:136 +#: mediagoblin/templates/mediagoblin/media_displays/video.html:55 +msgid "Download" +msgstr "İndir" + +#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:38 +msgid "Original" +msgstr "Özgün" + +#: mediagoblin/templates/mediagoblin/media_displays/audio.html:44 +msgid "" +"Sorry, this audio will not work because \n" +"\tyour web browser does not support HTML5 \n" +"\taudio." +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/audio.html:47 +msgid "" +"You can get a modern web browser that \n" +"\tcan play the audio at <a href=\"http://getfirefox.com\">\n" +"\t http://getfirefox.com</a>!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/audio.html:60 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:71 +#: mediagoblin/templates/mediagoblin/media_displays/video.html:61 +msgid "Original file" +msgstr "Özgün dosya" + +#: mediagoblin/templates/mediagoblin/media_displays/audio.html:63 +msgid "WebM file (Vorbis codec)" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:59 +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:87 +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:93 +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:99 +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:105 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:59 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:65 +#, python-format +msgid "Image for %(media_title)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 +msgid "PDF file" +msgstr "PDF dosya" + +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 +msgid "Toggle Rotate" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:113 +msgid "Perspective" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:116 +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:117 +msgid "Front" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:120 +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:121 +msgid "Top" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:124 +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:125 +msgid "Side" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:130 +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:131 +msgid "WebGL" +msgstr "WebGL" + +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:138 +msgid "Download model" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:146 +msgid "File Format" +msgstr "Dosya Biçimi" + +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:148 +msgid "Object Height" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:44 +msgid "" +"Sorry, this video will not work because\n" +" your web browser does not support HTML5 \n" +" video." +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:47 +msgid "" +"You can get a modern web browser that \n" +" can play this video at <a href=\"http://getfirefox.com\">\n" +" http://getfirefox.com</a>!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:69 +msgid "WebM file (640p; VP8/Vorbis)" +msgstr "" + +#: mediagoblin/templates/mediagoblin/submit/collection.html:26 +msgid "Add a collection" +msgstr "" + +#: mediagoblin/templates/mediagoblin/submit/start.html:23 +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Add your media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/collection.html:30 +#, python-format +msgid "%(collection_title)s (%(username)s's collection)" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/collection.html:39 +#, python-format +msgid "%(collection_title)s by <a href=\"%(user_url)s\">%(username)s</a>" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/collection.html:52 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:79 +msgid "Edit" +msgstr "Düzenle" + +#: mediagoblin/templates/mediagoblin/user_pages/collection.html:56 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:83 +msgid "Delete" +msgstr "Si" + +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:30 +#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 +#, python-format +msgid "Really delete %(title)s?" +msgstr "Gerçekten %(title)s silmek istiyor musun?" + +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:31 +#, python-format +msgid "Really remove %(media_title)s from %(collection_title)s?" +msgstr "Gerçekten %(collection_title)s %(media_title)s kaldırmak istiyor musun?" + +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:54 +msgid "Remove" +msgstr "Kaldır" + +#: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:21 +#, python-format +msgid "%(username)s's collections" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:28 +#, python-format +msgid "<a href=\"%(user_url)s\">%(username)s</a>'s collections" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/comment_email.txt:19 +#, python-format +msgid "" +"Hi %(username)s,\n" +"%(comment_author)s commented on your post (%(comment_url)s) at %(instance_name)s\n" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 +#, python-format +msgid "%(username)s's media" +msgstr "%(username)s medyası" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:38 +#, python-format +msgid "" +"<a href=\"%(user_url)s\">%(username)s</a>'s media with tag <a " +"href=\"%(tag_url)s\">%(tag)s</a>" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:48 +#, python-format +msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media" +msgstr "<a href=\"%(user_url)s\">%(username)s</a> medyası" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:38 +#, python-format +msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:95 +msgid "Add a comment" +msgstr "Bir yorum ekle" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 +msgid "Add this comment" +msgstr "Bu yorumu ekle" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:132 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:152 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:164 +#, python-format +msgid "%(formatted_time)s ago" +msgstr "%(formatted_time)s önce" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:150 +msgid "Added" +msgstr "Eklendi" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:161 +msgid "Created" +msgstr "OluÅŸturuldu" + +#: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 +#: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:40 +#, python-format +msgid "Add “%(media_title)s†to a collection" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:54 +msgid "+" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:58 +msgid "Add a new collection" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:29 +msgid "" +"You can track the state of media being processed for your gallery here." +msgstr "Burada galerinizdeki iÅŸlenmekte olan medyanın durumunu takip edebilirsiniz." + +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:89 +msgid "Your last 10 successful uploads" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:31 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:89 +#, python-format +msgid "%(username)s's profile" +msgstr "%(username)s profili" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:43 +msgid "Sorry, no such user found." +msgstr "Üzgünüz, böyle bir kullanıcı bulunamadı." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:50 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:70 +msgid "Email verification needed" +msgstr "E-posta doÄŸrulaması gerekli" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:53 +msgid "Almost done! Your account still needs to be activated." +msgstr "Neredeyse bitti! Hesabınızı etkinleÅŸtirmeniz gerekiyor." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:58 +msgid "" +"An email should arrive in a few moments with instructions on how to do so." +msgstr "Bunun nasıl yapılacağı ile ilgili talimatlar, birkaç dakika içinde size e-posta ulaÅŸacak." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 +msgid "In case it doesn't:" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:65 +msgid "Resend verification email" +msgstr "DoÄŸrulama e-postası tekrar yolla" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:73 +msgid "" +"Someone has registered an account with this username, but it still has to be" +" activated." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:79 +#, python-format +msgid "" +"If you are that person but you've lost your verification email, you can <a " +"href=\"%(login_url)s\">log in</a> and resend it." +msgstr "DoÄŸrulama e-postasını kaybettiyseniz, <a href=\"%(login_url)s\">giriÅŸ</a> yapabilir ve yeniden yollayabilirsiniz." + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 +msgid "Here's a spot to tell others about yourself." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:100 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:117 +msgid "Edit profile" +msgstr "Profil düzenle" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:105 +msgid "This user hasn't filled in their profile (yet)." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:124 +msgid "Browse collections" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:137 +#, python-format +msgid "View all of %(username)s's media" +msgstr "%(username)s tüm medyasını göster" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:150 +msgid "" +"This is where your media will appear, but you don't seem to have added " +"anything yet." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:162 +#: mediagoblin/templates/mediagoblin/utils/collection_gallery.html:84 +#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:70 +msgid "There doesn't seem to be any media here yet..." +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/collection_gallery.html:49 +msgid "(remove)" +msgstr "(kaldır)" + +#: mediagoblin/templates/mediagoblin/utils/collections.html:21 +msgid "Collected in" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/collections.html:40 +msgid "Add to a collection" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/feed_link.html:21 +#: mediagoblin/themes/airy/templates/mediagoblin/utils/feed_link.html:21 +msgid "feed icon" +msgstr "besleme simgesi" + +#: mediagoblin/templates/mediagoblin/utils/feed_link.html:23 +#: mediagoblin/themes/airy/templates/mediagoblin/utils/feed_link.html:23 +msgid "Atom feed" +msgstr "Atom besleme" + +#: mediagoblin/templates/mediagoblin/utils/license.html:25 +msgid "All rights reserved" +msgstr "Tüm hakları saklıdır" + +#: mediagoblin/templates/mediagoblin/utils/pagination.html:39 +msgid "↠Newer" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/pagination.html:45 +msgid "Older →" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/pagination.html:48 +msgid "Go to page:" +msgstr "Sayfaya git:" + +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:28 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:33 +msgid "newer" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:39 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:44 +msgid "older" +msgstr "" + +#: mediagoblin/templates/mediagoblin/utils/tags.html:20 +msgid "Tagged with" +msgstr "" + +#: mediagoblin/tools/exif.py:83 +msgid "Could not read the image file." +msgstr "" + +#: mediagoblin/tools/response.py:35 +msgid "Oops!" +msgstr "Amaninnn boo!" + +#: mediagoblin/tools/response.py:36 +msgid "An error occured" +msgstr "" + +#: mediagoblin/tools/response.py:51 +msgid "Operation not allowed" +msgstr "" + +#: mediagoblin/tools/response.py:52 +msgid "" +"Sorry Dave, I can't let you do that!</p><p>You have tried to perform a " +"function that you are not allowed to. Have you been trying to delete all " +"user accounts again?" +msgstr "" + +#: mediagoblin/tools/response.py:60 +msgid "" +"There doesn't seem to be a page at this address. Sorry!</p><p>If you're sure" +" the address is correct, maybe the page you're looking for has been moved or" +" deleted." +msgstr "" + +#: mediagoblin/tools/timesince.py:62 +msgid "year" +msgstr "yıl" + +#: mediagoblin/tools/timesince.py:63 +msgid "month" +msgstr "ay" + +#: mediagoblin/tools/timesince.py:64 +msgid "week" +msgstr "hafta" + +#: mediagoblin/tools/timesince.py:65 +msgid "day" +msgstr "gün" + +#: mediagoblin/tools/timesince.py:66 +msgid "hour" +msgstr "saat" + +#: mediagoblin/tools/timesince.py:67 +msgid "minute" +msgstr "dakika" + +#: mediagoblin/user_pages/forms.py:23 +msgid "Comment" +msgstr "" + +#: mediagoblin/user_pages/forms.py:25 +msgid "" +"You can use <a " +"href=\"http://daringfireball.net/projects/markdown/basics\">Markdown</a> for" +" formatting." +msgstr "" + +#: mediagoblin/user_pages/forms.py:31 +msgid "I am sure I want to delete this" +msgstr "Bunu silmek için eminim" + +#: mediagoblin/user_pages/forms.py:35 +msgid "I am sure I want to remove this item from the collection" +msgstr "" + +#: mediagoblin/user_pages/forms.py:39 +msgid "Collection" +msgstr "" + +#: mediagoblin/user_pages/forms.py:40 +msgid "-- Select --" +msgstr "" + +#: mediagoblin/user_pages/forms.py:42 +msgid "Include a note" +msgstr "" + +#: mediagoblin/user_pages/lib.py:58 +msgid "commented on your post" +msgstr "" + +#: mediagoblin/user_pages/views.py:169 +msgid "Sorry, comments are disabled." +msgstr "Maalesef, yorum devre dışı." + +#: mediagoblin/user_pages/views.py:174 +msgid "Oops, your comment was empty." +msgstr "Amaninnn boo, yorumunuz boÅŸtu." + +#: mediagoblin/user_pages/views.py:180 +msgid "Your comment has been posted!" +msgstr "Yorumunuz gönderildi!" + +#: mediagoblin/user_pages/views.py:205 +msgid "Please check your entries and try again." +msgstr "" + +#: mediagoblin/user_pages/views.py:245 +msgid "You have to select or add a collection" +msgstr "" + +#: mediagoblin/user_pages/views.py:256 +#, python-format +msgid "\"%s\" already in collection \"%s\"" +msgstr "" + +#: mediagoblin/user_pages/views.py:262 +#, python-format +msgid "\"%s\" added to collection \"%s\"" +msgstr "" + +#: mediagoblin/user_pages/views.py:282 +msgid "You deleted the media." +msgstr "Medyayı sildiniz." + +#: mediagoblin/user_pages/views.py:289 +msgid "The media was not deleted because you didn't check that you were sure." +msgstr "Medya silinmedi çünkü emin olduÄŸunuzu onaylamadınız." + +#: mediagoblin/user_pages/views.py:296 +msgid "You are about to delete another user's media. Proceed with caution." +msgstr "BaÅŸka bir kullanıcının medyasını silerken dikkatli davranın." + +#: mediagoblin/user_pages/views.py:370 +msgid "You deleted the item from the collection." +msgstr "" + +#: mediagoblin/user_pages/views.py:374 +msgid "The item was not removed because you didn't check that you were sure." +msgstr "" + +#: mediagoblin/user_pages/views.py:382 +msgid "" +"You are about to delete an item from another user's collection. Proceed with" +" caution." +msgstr "" + +#: mediagoblin/user_pages/views.py:415 +#, python-format +msgid "You deleted the collection \"%s\"" +msgstr "" + +#: mediagoblin/user_pages/views.py:422 +msgid "" +"The collection was not deleted because you didn't check that you were sure." +msgstr "" + +#: mediagoblin/user_pages/views.py:430 +msgid "" +"You are about to delete another user's collection. Proceed with caution." +msgstr "" diff --git a/mediagoblin/i18n/zh_CN/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/zh_CN/LC_MESSAGES/mediagoblin.mo Binary files differnew file mode 100644 index 00000000..1ed5a4f1 --- /dev/null +++ b/mediagoblin/i18n/zh_CN/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/zh_CN/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/zh_CN/LC_MESSAGES/mediagoblin.po new file mode 100644 index 00000000..4bb714fe --- /dev/null +++ b/mediagoblin/i18n/zh_CN/LC_MESSAGES/mediagoblin.po @@ -0,0 +1,1256 @@ +# Translations template for PROJECT. +# Copyright (C) 2013 ORGANIZATION +# This file is distributed under the same license as the PROJECT project. +# +# Translators: +# <chc@citi.sinica.edu.tw>, 2011 +# cwebber <cwebber@dustycloud.org>, 2013 +# m13253 <m13253@hotmail.com>, 2013 +# medicalwei <medicalwei@gmail.com>, 2012 +# m13253 <m13253@hotmail.com>, 2013 +msgid "" +msgstr "" +"Project-Id-Version: GNU MediaGoblin\n" +"Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" +"POT-Creation-Date: 2013-05-27 13:54-0500\n" +"PO-Revision-Date: 2013-06-16 11:06+0000\n" +"Last-Translator: m13253 <m13253@hotmail.com>\n" +"Language-Team: Chinese (China) (http://www.transifex.com/projects/p/mediagoblin/language/zh_CN/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 0.9.6\n" +"Language: zh_CN\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: mediagoblin/auth/forms.py:26 +msgid "Username" +msgstr "用户å" + +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 +#: mediagoblin/tests/test_util.py:110 +msgid "Password" +msgstr "密ç " + +#: mediagoblin/auth/forms.py:34 +msgid "Email address" +msgstr "电å邮件地å€" + +#: mediagoblin/auth/forms.py:41 +msgid "Username or Email" +msgstr "ç”¨æˆ·åæˆ–电å邮件" + +#: mediagoblin/auth/forms.py:52 +msgid "Username or email" +msgstr "ç”¨æˆ·åæˆ–电å邮件" + +#: mediagoblin/auth/tools.py:31 +msgid "Invalid User name or email address." +msgstr "æ— æ•ˆç”¨æˆ·åæˆ–电å邮件地å€ã€‚" + +#: mediagoblin/auth/tools.py:32 +msgid "This field does not take email addresses." +msgstr "æ¤å—段ä¸èƒ½å¡«å†™ç”µå邮件地å€ã€‚" + +#: mediagoblin/auth/tools.py:33 +msgid "This field requires an email address." +msgstr "æ¤å—段需填写电å邮件地å€ã€‚" + +#: mediagoblin/auth/views.py:54 +msgid "Sorry, registration is disabled on this instance." +msgstr "抱æ‰ï¼Œæœ¬ç«™å·²æš‚åœæ³¨å†Œã€‚" + +#: mediagoblin/auth/views.py:68 +msgid "Sorry, a user with that name already exists." +msgstr "抱æ‰ï¼Œè¯¥ç”¨æˆ·åå·²å˜åœ¨ã€‚" + +#: mediagoblin/auth/views.py:72 +msgid "Sorry, a user with that email address already exists." +msgstr "抱æ‰ï¼Œå·²æœ‰ç”¨æˆ·ç”¨è¯¥ç”µå邮件注册。" + +#: mediagoblin/auth/views.py:182 +msgid "" +"Your email address has been verified. You may now login, edit your profile, " +"and submit images!" +msgstr "您的电å邮件地å€å·²è®¤è¯ã€‚您现在å¯ä»¥ç™»å½•ã€ä¿®æ”¹ä¸ªäººèµ„æ–™å¹¶ä¸Šä¼ å›¾ç‰‡äº†ï¼" + +#: mediagoblin/auth/views.py:188 +msgid "The verification key or user id is incorrect" +msgstr "验è¯ç 错误或用户 ID 错误" + +#: mediagoblin/auth/views.py:206 +msgid "You must be logged in so we know who to send the email to!" +msgstr "您必须登录以便让我们知é“将电å邮件å‘ç»™è°" + +#: mediagoblin/auth/views.py:214 +msgid "You've already verified your email address!" +msgstr "您已ç»è®¤è¯è¿‡ç”µå邮件地å€äº†ï¼" + +#: mediagoblin/auth/views.py:227 +msgid "Resent your verification email." +msgstr "é‡å‘认è¯é‚®ä»¶ã€‚" + +#: mediagoblin/auth/views.py:258 +msgid "" +"If that email address (case sensitive!) is registered an email has been sent" +" with instructions on how to change your password." +msgstr "若该邮件地å€ï¼ˆåŒºåˆ†å¤§å°å†™ï¼‰å·²è¢«æ³¨å†Œï¼Œåˆ™å¯†ç 修改说明已通过电å邮件é€è¾¾ã€‚" + +#: mediagoblin/auth/views.py:269 +msgid "Couldn't find someone with that username." +msgstr "找ä¸åˆ°æœ‰è¯¥ç”¨æˆ·å的人。" + +#: mediagoblin/auth/views.py:272 +msgid "" +"An email has been sent with instructions on how to change your password." +msgstr "密ç 修改说明已通过电å邮件é€è¾¾ã€‚" + +#: mediagoblin/auth/views.py:279 +msgid "" +"Could not send password recovery email as your username is inactive or your " +"account's email address has not been verified." +msgstr "æ— æ³•å‘é€å¯†ç æ‰¾å›žé‚®ä»¶ï¼Œå› ä¸ºæ‚¨çš„ç”¨æˆ·åæœªæ¿€æ´»æˆ–者您账户的电åé‚®ä»¶åœ°å€æœªè®¤è¯ã€‚" + +#: mediagoblin/auth/views.py:336 +msgid "You can now log in using your new password." +msgstr "您现在å¯ä»¥ç”¨æ–°çš„å¯†ç æ¥ç™»å½•了ï¼" + +#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:82 +#: mediagoblin/submit/forms.py:28 mediagoblin/submit/forms.py:47 +#: mediagoblin/user_pages/forms.py:45 +msgid "Title" +msgstr "æ ‡é¢˜" + +#: mediagoblin/edit/forms.py:28 mediagoblin/submit/forms.py:31 +msgid "Description of this work" +msgstr "该作å“çš„æè¿°" + +#: mediagoblin/edit/forms.py:29 mediagoblin/edit/forms.py:52 +#: mediagoblin/edit/forms.py:86 mediagoblin/submit/forms.py:32 +#: mediagoblin/submit/forms.py:51 mediagoblin/user_pages/forms.py:49 +msgid "" +"You can use\n" +" <a href=\"http://daringfireball.net/projects/markdown/basics\">\n" +" Markdown</a> for formatting." +msgstr "您å¯ä»¥ç”¨ <a href=\"http://wowubuntu.com/markdown/\">Markdown</a> æ¥æŽ’ç‰ˆã€‚" + +#: mediagoblin/edit/forms.py:33 mediagoblin/submit/forms.py:36 +msgid "Tags" +msgstr "æ ‡ç¾" + +#: mediagoblin/edit/forms.py:35 mediagoblin/submit/forms.py:38 +msgid "Separate tags by commas." +msgstr "用逗å·åˆ†é𔿠‡ç¾ã€‚" + +#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:90 +msgid "Slug" +msgstr "简称" + +#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:91 +msgid "The slug can't be empty" +msgstr "简称ä¸èƒ½ä¸ºç©º" + +#: mediagoblin/edit/forms.py:40 +msgid "" +"The title part of this media's address. You usually don't need to change " +"this." +msgstr "该媒体网å€çš„æ ‡é¢˜éƒ¨ä»½ã€‚通常ä¸éœ€è¦ä¿®æ”¹ã€‚" + +#: mediagoblin/edit/forms.py:44 mediagoblin/submit/forms.py:41 +#: mediagoblin/templates/mediagoblin/utils/license.html:20 +msgid "License" +msgstr "许å¯è¯" + +#: mediagoblin/edit/forms.py:50 +msgid "Bio" +msgstr "个性ç¾å" + +#: mediagoblin/edit/forms.py:56 +msgid "Website" +msgstr "网站" + +#: mediagoblin/edit/forms.py:58 +msgid "This address contains errors" +msgstr "本网å€å‡ºé”™äº†" + +#: mediagoblin/edit/forms.py:63 +msgid "License preference" +msgstr "许å¯è¯å好" + +#: mediagoblin/edit/forms.py:69 +msgid "This will be your default license on upload forms." +msgstr "è¿™å°†æ˜¯æ‚¨ä¸Šä¼ ç•Œé¢çš„默认许å¯è¯ã€‚" + +#: mediagoblin/edit/forms.py:71 +msgid "Email me when others comment on my media" +msgstr "当有人对我的媒体评论时给我电å邮件" + +#: mediagoblin/edit/forms.py:83 +msgid "The title can't be empty" +msgstr "æ ‡é¢˜ä¸èƒ½æ˜¯ç©ºçš„" + +#: mediagoblin/edit/forms.py:85 mediagoblin/submit/forms.py:50 +#: mediagoblin/user_pages/forms.py:48 +msgid "Description of this collection" +msgstr "这个åˆé›†çš„æè¿°" + +#: mediagoblin/edit/forms.py:92 +msgid "" +"The title part of this collection's address. You usually don't need to " +"change this." +msgstr "æ¤åˆé›†ç½‘å€çš„æ ‡é¢˜éƒ¨ä»½ï¼Œé€šå¸¸ä¸éœ€è¦ä¿®æ”¹ã€‚" + +#: mediagoblin/edit/forms.py:99 +msgid "Old password" +msgstr "旧的密ç " + +#: mediagoblin/edit/forms.py:101 +msgid "Enter your old password to prove you own this account." +msgstr "è¾“å…¥æ‚¨çš„æ—§å¯†ç æ¥è¯æ˜Žæ‚¨æ‹¥æœ‰è¿™ä¸ªè´¦æˆ·ã€‚" + +#: mediagoblin/edit/forms.py:104 +msgid "New password" +msgstr "新密ç " + +#: mediagoblin/edit/views.py:67 +msgid "An entry with that slug already exists for this user." +msgstr "这个简称已ç»è¢«åˆ«äººç”¨äº†" + +#: mediagoblin/edit/views.py:85 +msgid "You are editing another user's media. Proceed with caution." +msgstr "您æ£åœ¨ä¿®æ”¹åˆ«äººçš„媒体,请å°å¿ƒæ“作。" + +#: mediagoblin/edit/views.py:155 +#, python-format +msgid "You added the attachment %s!" +msgstr "æ‚¨åŠ ä¸Šäº†é™„ä»¶â€œ%sâ€ï¼" + +#: mediagoblin/edit/views.py:182 +msgid "You can only edit your own profile." +msgstr "您åªèƒ½ä¿®æ”¹è‡ªå·±çš„个人资料" + +#: mediagoblin/edit/views.py:188 +msgid "You are editing a user's profile. Proceed with caution." +msgstr "您æ£åœ¨ä¿®æ”¹åˆ«äººçš„个人资料,请å°å¿ƒæ“作。" + +#: mediagoblin/edit/views.py:204 +msgid "Profile changes saved" +msgstr "个人资料已修改" + +#: mediagoblin/edit/views.py:240 +msgid "Account settings saved" +msgstr "账户设置已ä¿å˜" + +#: mediagoblin/edit/views.py:274 +msgid "You need to confirm the deletion of your account." +msgstr "您需è¦ç¡®è®¤åˆ 除您的账户。" + +#: mediagoblin/edit/views.py:310 mediagoblin/submit/views.py:138 +#: mediagoblin/user_pages/views.py:222 +#, python-format +msgid "You already have a collection called \"%s\"!" +msgstr "æ‚¨å·²ç»æœ‰ä¸€ä¸ªç§°åšâ€œ%sâ€çš„åˆé›†äº†ï¼" + +#: mediagoblin/edit/views.py:314 +msgid "A collection with that slug already exists for this user." +msgstr "è¯¥ç”¨æˆ·å·²ç»æœ‰ä½¿ç”¨è¯¥ç®€ç§°çš„åˆé›†äº†ã€‚" + +#: mediagoblin/edit/views.py:329 +msgid "You are editing another user's collection. Proceed with caution." +msgstr "您æ£åœ¨ä¿®æ”¹åˆ«äººçš„åˆé›†ï¼Œè¯·å°å¿ƒæ“作。" + +#: mediagoblin/edit/views.py:348 +msgid "Wrong password" +msgstr "密ç 错误" + +#: mediagoblin/edit/views.py:363 +msgid "Your password was changed successfully" +msgstr "您的密ç å·²æˆåŠŸä¿®æ”¹" + +#: mediagoblin/gmg_commands/assetlink.py:60 +msgid "Cannot link theme... no theme set\n" +msgstr "æ— æ³•é“¾æŽ¥åˆ°ä¸»é¢˜â€¦â€¦æœªè®¾ç½®ä¸»é¢˜\n" + +#: mediagoblin/gmg_commands/assetlink.py:73 +msgid "No asset directory for this theme\n" +msgstr "æ¤ä¸»é¢˜æ²¡æœ‰ç´ æç›®å½•\n" + +#: mediagoblin/gmg_commands/assetlink.py:76 +msgid "However, old link directory symlink found; removed.\n" +msgstr "ä½†æ˜¯æ—§çš„ç›®å½•é“¾æŽ¥å·²ç»æ‰¾åˆ°å¹¶ç§»é™¤ã€‚\n" + +#: mediagoblin/gmg_commands/assetlink.py:112 +#, python-format +msgid "Could not link \"%s\": %s exists and is not a symlink\n" +msgstr "æ— æ³•é“¾æŽ¥åˆ°â€œ%sâ€ï¼šâ€œ%sâ€å·²å˜åœ¨ä¸”䏿˜¯é“¾æŽ¥\n" + +#: mediagoblin/gmg_commands/assetlink.py:119 +#, python-format +msgid "Skipping \"%s\"; already set up.\n" +msgstr "跳过“%sâ€ï¼›å·²è®¾ç½®è¿‡äº†ã€‚\n" + +#: mediagoblin/gmg_commands/assetlink.py:124 +#, python-format +msgid "Old link found for \"%s\"; removing.\n" +msgstr "“%sâ€çš„æ—§é“¾æŽ¥å·²ç»æ‰¾åˆ°å¹¶ç§»é™¤ã€‚\n" + +#: mediagoblin/meddleware/csrf.py:134 +msgid "" +"CSRF cookie not present. This is most likely the result of a cookie blocker " +"or somesuch.<br/>Make sure to permit the settings of cookies for this " +"domain." +msgstr "CSRF cookie ä¸å˜åœ¨ã€‚很å¯èƒ½æ˜¯ç”±ç±»ä¼¼ cookie å±è”½å™¨é€ æˆçš„。<br />请å…许本域åçš„ cookie 设定。" + +#: mediagoblin/media_types/__init__.py:111 +#: mediagoblin/media_types/__init__.py:155 +msgid "Sorry, I don't support that file type :(" +msgstr "抱æ‰ï¼Œæˆ‘䏿”¯æŒè¿™æ ·çš„æ–‡ä»¶æ ¼å¼ :(" + +#: mediagoblin/media_types/pdf/processing.py:136 +msgid "unoconv failing to run, check log file" +msgstr "æ— æ³•è¿è¡Œ unoconv,请检查日志" + +#: mediagoblin/media_types/video/processing.py:37 +msgid "Video transcoding failed" +msgstr "视频转ç 失败" + +#: mediagoblin/plugins/geolocation/templates/mediagoblin/plugins/geolocation/map.html:24 +msgid "Location" +msgstr "ä½ç½®" + +#: mediagoblin/plugins/geolocation/templates/mediagoblin/plugins/geolocation/map.html:52 +#, python-format +msgid "View on <a href=\"%(osm_url)s\">OpenStreetMap</a>" +msgstr "在 <a href=\"%(osm_url)s\">OpenStreetMap</a> 上观看" + +#: mediagoblin/plugins/oauth/forms.py:29 +msgid "Allow" +msgstr "å…许" + +#: mediagoblin/plugins/oauth/forms.py:30 +msgid "Deny" +msgstr "æ‹’ç»" + +#: mediagoblin/plugins/oauth/forms.py:34 +msgid "Name" +msgstr "åç§°" + +#: mediagoblin/plugins/oauth/forms.py:35 +msgid "The name of the OAuth client" +msgstr "OAuth client çš„åç§°" + +#: mediagoblin/plugins/oauth/forms.py:36 +msgid "Description" +msgstr "æè¿°" + +#: mediagoblin/plugins/oauth/forms.py:38 +msgid "" +"This will be visible to users allowing your\n" +" application to authenticate as them." +msgstr "本æè¿°å°†ä¼šè¢«è¿›è¡Œåº”用程åºè®¤è¯çš„用户看到。" + +#: mediagoblin/plugins/oauth/forms.py:40 +msgid "Type" +msgstr "类型" + +#: mediagoblin/plugins/oauth/forms.py:45 +msgid "" +"<strong>Confidential</strong> - The client can\n" +" make requests to the GNU MediaGoblin instance that can not be\n" +" intercepted by the user agent (e.g. server-side client).<br />\n" +" <strong>Public</strong> - The client can't make confidential\n" +" requests to the GNU MediaGoblin instance (e.g. client-side\n" +" JavaScript client)." +msgstr "<strong>秘密</strong> — OAuth client å¯ä»¥å¯¹ GNU MediaGoblin 站点å‘é€ä¸è¢«ç”¨æˆ·ä»£ç†æ‹¦æˆªçš„请求(例如æœåŠ¡ç«¯ä¸Šçš„ client)。\n<strong>公开</strong> — OAuth client æ— æ³•å¯¹ GNU MediaGoblin 站点å‘é€ç§˜å¯†çš„请求(例如客户端的 JavaScript client)。" + +#: mediagoblin/plugins/oauth/forms.py:52 +msgid "Redirect URI" +msgstr "é‡å®šå‘ URI" + +#: mediagoblin/plugins/oauth/forms.py:54 +msgid "" +"The redirect URI for the applications, this field\n" +" is <strong>required</strong> for public clients." +msgstr "æ¤åº”用程åºçš„é‡å®šå‘ URIï¼Œæœ¬å—æ®µåœ¨å…¬å¼€ç±»åž‹çš„ OAuth client 为<strong>å¿…å¡«</strong>。" + +#: mediagoblin/plugins/oauth/forms.py:66 +msgid "This field is required for public clients" +msgstr "æœ¬å—æ®µåœ¨å…¬å¼€ç±»åž‹çš„ OAuth client 为必填" + +#: mediagoblin/plugins/oauth/views.py:56 +msgid "The client {0} has been registered!" +msgstr "OAuth client {0} 注册完æˆï¼" + +#: mediagoblin/plugins/oauth/templates/oauth/client/connections.html:22 +msgid "OAuth client connections" +msgstr "OAuth client 连接" + +#: mediagoblin/plugins/oauth/templates/oauth/client/list.html:22 +msgid "Your OAuth clients" +msgstr "您的 OAuth client" + +#: mediagoblin/plugins/oauth/templates/oauth/client/register.html:29 +#: mediagoblin/templates/mediagoblin/submit/collection.html:30 +#: mediagoblin/templates/mediagoblin/submit/start.html:34 +#: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:68 +msgid "Add" +msgstr "å¢žåŠ " + +#: mediagoblin/processing/__init__.py:193 +msgid "Invalid file given for media type." +msgstr "æä¾›æ–‡ä»¶çš„媒体类型错误。" + +#: mediagoblin/submit/forms.py:26 +msgid "File" +msgstr "文件" + +#: mediagoblin/submit/views.py:49 +msgid "You must provide a file." +msgstr "您必须æä¾›ä¸€ä¸ªæ–‡ä»¶" + +#: mediagoblin/submit/views.py:93 +msgid "Woohoo! Submitted!" +msgstr "啊哈ï¼å·²æäº¤ï¼" + +#: mediagoblin/submit/views.py:144 +#, python-format +msgid "Collection \"%s\" added!" +msgstr "åˆé›†â€œ%sâ€å·²æ–°å¢žï¼" + +#: mediagoblin/templates/mediagoblin/base.html:67 +msgid "Verify your email!" +msgstr "确认您的电å邮件ï¼" + +#: mediagoblin/templates/mediagoblin/base.html:68 +msgid "log out" +msgstr "登出" + +#: mediagoblin/templates/mediagoblin/base.html:73 +#: mediagoblin/templates/mediagoblin/auth/login.html:28 +#: mediagoblin/templates/mediagoblin/auth/login.html:36 +#: mediagoblin/templates/mediagoblin/auth/login.html:54 +msgid "Log in" +msgstr "登录" + +#: mediagoblin/templates/mediagoblin/base.html:82 +#, python-format +msgid "<a href=\"%(user_url)s\">%(user_name)s</a>'s account" +msgstr "<a href=\"%(user_url)s\">%(user_name)s</a> 的账户" + +#: mediagoblin/templates/mediagoblin/base.html:89 +msgid "Change account settings" +msgstr "更改账户设置" + +#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:108 +#: mediagoblin/templates/mediagoblin/admin/panel.html:21 +#: mediagoblin/templates/mediagoblin/admin/panel.html:26 +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:21 +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:26 +msgid "Media processing panel" +msgstr "媒体处ç†é¢æ¿" + +#: mediagoblin/templates/mediagoblin/base.html:96 +msgid "Log out" +msgstr "登出" + +#: mediagoblin/templates/mediagoblin/base.html:99 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:156 +msgid "Add media" +msgstr "新增媒体" + +#: mediagoblin/templates/mediagoblin/base.html:102 +#: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:41 +msgid "Create new collection" +msgstr "新增åˆé›†" + +#: mediagoblin/templates/mediagoblin/error.html:24 +msgid "Image of goblin stressing out" +msgstr "满脸问å·çš„哥布林" + +#: mediagoblin/templates/mediagoblin/root.html:32 +msgid "Most recent media" +msgstr "最新的媒体" + +#: mediagoblin/templates/mediagoblin/admin/panel.html:29 +msgid "" +"Here you can track the state of media being processed on this instance." +msgstr "æ¤å¤„您å¯ä»¥è¿½è¸ªæœ¬ç«™ç‚¹å¤„ç†åª’体的状æ€ã€‚" + +#: mediagoblin/templates/mediagoblin/admin/panel.html:32 +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:32 +msgid "Media in-processing" +msgstr "媒体处ç†ä¸" + +#: mediagoblin/templates/mediagoblin/admin/panel.html:58 +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:56 +msgid "No media in-processing" +msgstr "没有æ£åœ¨å¤„ç†ä¸çš„媒体" + +#: mediagoblin/templates/mediagoblin/admin/panel.html:61 +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:59 +msgid "These uploads failed to process:" +msgstr "æ— æ³•å¤„ç†è¿™äº›ä¸Šä¼ 内容:" + +#: mediagoblin/templates/mediagoblin/admin/panel.html:90 +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:86 +msgid "No failed entries!" +msgstr "没有失败的纪录ï¼" + +#: mediagoblin/templates/mediagoblin/admin/panel.html:92 +msgid "Last 10 successful uploads" +msgstr "最近 10 次æˆåŠŸä¸Šä¼ çš„çºªå½•" + +#: mediagoblin/templates/mediagoblin/admin/panel.html:112 +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:107 +msgid "No processed entries, yet!" +msgstr "现在还没有处ç†çš„纪录ï¼" + +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:28 +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:36 +msgid "Set your new password" +msgstr "设置您的新密ç " + +#: mediagoblin/templates/mediagoblin/auth/change_fp.html:39 +msgid "Set password" +msgstr "设置新密ç " + +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:23 +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:31 +msgid "Recover password" +msgstr "找回密ç " + +#: mediagoblin/templates/mediagoblin/auth/forgot_password.html:34 +msgid "Send instructions" +msgstr "å‘逿‰¾å›žå¯†ç 说明" + +#: mediagoblin/templates/mediagoblin/auth/fp_verification_email.txt:19 +#, python-format +msgid "" +"Hi %(username)s,\n" +"\n" +"to change your GNU MediaGoblin password, open the following URL in \n" +"your web browser:\n" +"\n" +"%(verification_url)s\n" +"\n" +"If you think this is an error, just ignore this email and continue being\n" +"a happy goblin!" +msgstr "%(username)s 您好:\n\nè¦ä¿®æ”¹ GNU MediaGoblin 的密ç ,请在您的æµè§ˆå™¨ä¸æ‰“开下é¢çš„网å€ï¼š\n\n%(verification_url)s\n\n如果您认为这个是个误会,请忽略æ¤å°ä¿¡ä»¶ï¼Œç»§ç»å½“个快ä¹çš„哥布林ï¼" + +#: mediagoblin/templates/mediagoblin/auth/login.html:39 +msgid "Logging in failed!" +msgstr "登录失败ï¼" + +#: mediagoblin/templates/mediagoblin/auth/login.html:44 +msgid "Don't have an account yet?" +msgstr "还没有账户å—?" + +#: mediagoblin/templates/mediagoblin/auth/login.html:45 +msgid "Create one here!" +msgstr "在这里建立一个å§ï¼" + +#: mediagoblin/templates/mediagoblin/auth/login.html:51 +msgid "Forgot your password?" +msgstr "忘了密ç å—?" + +#: mediagoblin/templates/mediagoblin/auth/register.html:28 +#: mediagoblin/templates/mediagoblin/auth/register.html:36 +msgid "Create an account!" +msgstr "建立一个账户ï¼" + +#: mediagoblin/templates/mediagoblin/auth/register.html:40 +msgid "Create" +msgstr "建立" + +#: mediagoblin/templates/mediagoblin/auth/verification_email.txt:19 +#, python-format +msgid "" +"Hi %(username)s,\n" +"\n" +"to activate your GNU MediaGoblin account, open the following URL in\n" +"your web browser:\n" +"\n" +"%(verification_url)s" +msgstr "%(username)s 您好:\n\nè¦å¯åЍ GNU MediaGoblin 账户,请在您的æµè§ˆå™¨ä¸æ‰“开下é¢çš„网å€:\n\n%(verification_url)s" + +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:21 +#, python-format +msgid "" +"Powered by <a href=\"http://mediagoblin.org/\" title='Version " +"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." +msgstr "Powered by <a href=\"http://mediagoblin.org/\" title='Version %(version)s'>MediaGoblin</a>,一个 <a href=\"http://gnu.org/\">GNU</a> 项目。" + +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:24 +#, 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/bits/frontpage_welcome.html:20 +msgid "Explore" +msgstr "探索" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:22 +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "å˜¿ï¼æ¬¢è¿Žæ¥åˆ° MediaGoblin ç«™ï¼ " + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:24 +msgid "" +"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, an " +"extraordinarily great piece of media hosting software." +msgstr "本站使用 <a href=\"http://mediagoblin.org\">MediaGoblin</a>——与众ä¸åŒçš„媒体分享网站。" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:25 +msgid "" +"To add your own media, place comments, and more, you can log in with your " +"MediaGoblin account." +msgstr "您å¯ä»¥ç™»å½•您的 MediaGoblin è´¦æˆ·ä»¥ä¸Šä¼ åª’ä½“ã€å¼ 贴评论ç‰ç‰ã€‚" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:27 +msgid "Don't have one yet? It's easy!" +msgstr "没有账户å—?开账户很简å•ï¼" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:28 +#, python-format +msgid "" +"<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\">åœ¨æœ¬ç«™åˆ›å»ºå¸æˆ·</a>\n 或者\n <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">在您自己的æœåŠ¡å™¨ä¸Šæå»º MediaGoblin</a>" + +#: mediagoblin/templates/mediagoblin/bits/logo.html:23 +#: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 +msgid "MediaGoblin logo" +msgstr "MediaGoblin æ ‡å¿—" + +#: mediagoblin/templates/mediagoblin/edit/attachments.html:23 +#: mediagoblin/templates/mediagoblin/edit/attachments.html:35 +#, python-format +msgid "Editing attachments for %(media_title)s" +msgstr "编辑 %(media_title)s 的附件" + +#: mediagoblin/templates/mediagoblin/edit/attachments.html:44 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:182 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:198 +msgid "Attachments" +msgstr "附件" + +#: mediagoblin/templates/mediagoblin/edit/attachments.html:57 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:204 +msgid "Add attachment" +msgstr "新增附件" + +#: mediagoblin/templates/mediagoblin/edit/attachments.html:61 +#: mediagoblin/templates/mediagoblin/edit/delete_account.html:42 +#: mediagoblin/templates/mediagoblin/edit/edit.html:41 +#: mediagoblin/templates/mediagoblin/edit/edit_collection.html:32 +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:46 +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:52 +#: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:67 +#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:48 +msgid "Cancel" +msgstr "å–æ¶ˆ" + +#: mediagoblin/templates/mediagoblin/edit/attachments.html:63 +#: mediagoblin/templates/mediagoblin/edit/edit.html:42 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:55 +#: mediagoblin/templates/mediagoblin/edit/edit_collection.html:33 +#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:40 +msgid "Save changes" +msgstr "ä¿å˜æ›´æ”¹" + +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:28 +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 +#, python-format +msgid "Changing %(username)s's password" +msgstr "修改 %(username)s 的密ç " + +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 +msgid "Save" +msgstr "ä¿å˜" + +#: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 +#, python-format +msgid "Really delete user '%(user_name)s' and all related media/comments?" +msgstr "真的è¦åˆ 除用户 %(user_name)s åŠæ‰€æœ‰ç›¸å…³åª’体和评论å—?" + +#: mediagoblin/templates/mediagoblin/edit/delete_account.html:35 +msgid "Yes, really delete my account" +msgstr "æ˜¯çš„ï¼ŒçœŸçš„åˆ é™¤æˆ‘çš„è´¦æˆ·" + +#: mediagoblin/templates/mediagoblin/edit/delete_account.html:44 +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:48 +#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49 +msgid "Delete permanently" +msgstr "æ°¸ä¹…åˆ é™¤" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:23 +#: mediagoblin/templates/mediagoblin/edit/edit.html:35 +#, python-format +msgid "Editing %(media_title)s" +msgstr "编辑 %(media_title)s" + +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:28 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:40 +#, python-format +msgid "Changing %(username)s's account settings" +msgstr "æ£åœ¨æ”¹å˜ %(username)s 的账户设置" + +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 +msgid "Change your password." +msgstr "修改您的密ç 。" + +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 +msgid "Delete my account" +msgstr "åˆ é™¤æˆ‘çš„å¸æˆ·" + +#: mediagoblin/templates/mediagoblin/edit/edit_collection.html:29 +#, python-format +msgid "Editing %(collection_title)s" +msgstr "编辑 %(collection_title)s" + +#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:23 +#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:34 +#, python-format +msgid "Editing %(username)s's profile" +msgstr "编辑 %(username)s 的个人资料" + +#: mediagoblin/templates/mediagoblin/listings/collection.html:30 +#: mediagoblin/templates/mediagoblin/listings/collection.html:35 +#: mediagoblin/templates/mediagoblin/listings/tag.html:30 +#: mediagoblin/templates/mediagoblin/listings/tag.html:35 +#, python-format +msgid "Media tagged with: %(tag_name)s" +msgstr "æ¤åª’ä½“è¢«æ ‡è®°ä¸ºï¼š%(tag_name)s" + +#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 +#: mediagoblin/templates/mediagoblin/media_displays/audio.html:56 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:65 +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:136 +#: mediagoblin/templates/mediagoblin/media_displays/video.html:55 +msgid "Download" +msgstr "下载" + +#: mediagoblin/templates/mediagoblin/media_displays/ascii.html:38 +msgid "Original" +msgstr "æºæ–‡ä»¶" + +#: mediagoblin/templates/mediagoblin/media_displays/audio.html:44 +msgid "" +"Sorry, this audio will not work because \n" +"\tyour web browser does not support HTML5 \n" +"\taudio." +msgstr "抱æ‰ï¼Œæ¤å£°éŸ³æ— æ³•æ’æ”¾ï¼Œå› 为您的æµè§ˆå™¨ä¸æ”¯æŒ HTML5 音频。" + +#: mediagoblin/templates/mediagoblin/media_displays/audio.html:47 +msgid "" +"You can get a modern web browser that \n" +"\tcan play the audio at <a href=\"http://getfirefox.com\">\n" +"\t http://getfirefox.com</a>!" +msgstr "您å¯ä»¥åœ¨ <a href=\"http://getfirefox.com\">http://getfirefox.com</a> å–å¾—å¯ä»¥æ’放æ¤å£°éŸ³çš„æµè§ˆå™¨ï¼" + +#: mediagoblin/templates/mediagoblin/media_displays/audio.html:60 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:71 +#: mediagoblin/templates/mediagoblin/media_displays/video.html:61 +msgid "Original file" +msgstr "æºæ–‡ä»¶" + +#: mediagoblin/templates/mediagoblin/media_displays/audio.html:63 +msgid "WebM file (Vorbis codec)" +msgstr "WebM 文件(Vorbis ç¼–ç )" + +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:59 +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:87 +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:93 +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:99 +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:105 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:59 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:65 +#, python-format +msgid "Image for %(media_title)s" +msgstr "%(media_title)s 的照片" + +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 +msgid "PDF file" +msgstr "PDF 文件" + +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 +msgid "Toggle Rotate" +msgstr "åˆ‡æ¢æ—‹è½¬" + +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:113 +msgid "Perspective" +msgstr "é€è§†" + +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:116 +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:117 +msgid "Front" +msgstr "æ£é¢" + +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:120 +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:121 +msgid "Top" +msgstr "é¡¶é¢" + +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:124 +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:125 +msgid "Side" +msgstr "ä¾§é¢" + +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:130 +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:131 +msgid "WebGL" +msgstr "WebGL" + +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:138 +msgid "Download model" +msgstr "下载模型" + +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:146 +msgid "File Format" +msgstr "æ–‡ä»¶æ ¼å¼" + +#: mediagoblin/templates/mediagoblin/media_displays/stl.html:148 +msgid "Object Height" +msgstr "对象高度" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:44 +msgid "" +"Sorry, this video will not work because\n" +" your web browser does not support HTML5 \n" +" video." +msgstr "抱æ‰ï¼Œæ¤è§†é¢‘æ— æ³•æ’æ”¾ï¼Œå› 为您的æµè§ˆå™¨ä¸æ”¯æŒ HTML5 视频。" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:47 +msgid "" +"You can get a modern web browser that \n" +" can play this video at <a href=\"http://getfirefox.com\">\n" +" http://getfirefox.com</a>!" +msgstr "您å¯ä»¥åœ¨ <a href=\"http://getfirefox.com\">http://getfirefox.com</a> å–å¾—å¯ä»¥æ’放æ¤è§†é¢‘çš„æµè§ˆå™¨ï¼" + +#: mediagoblin/templates/mediagoblin/media_displays/video.html:69 +msgid "WebM file (640p; VP8/Vorbis)" +msgstr "WebM 文件(640pï¼›VP8/Vorbis)" + +#: mediagoblin/templates/mediagoblin/submit/collection.html:26 +msgid "Add a collection" +msgstr "新增åˆé›†" + +#: mediagoblin/templates/mediagoblin/submit/start.html:23 +#: mediagoblin/templates/mediagoblin/submit/start.html:30 +msgid "Add your media" +msgstr "åŠ å…¥æ‚¨çš„åª’ä½“" + +#: mediagoblin/templates/mediagoblin/user_pages/collection.html:30 +#, python-format +msgid "%(collection_title)s (%(username)s's collection)" +msgstr "%(collection_title)s (%(username)s çš„åˆé›†)" + +#: mediagoblin/templates/mediagoblin/user_pages/collection.html:39 +#, python-format +msgid "%(collection_title)s by <a href=\"%(user_url)s\">%(username)s</a>" +msgstr "%(collection_title)s by <a href=\"%(user_url)s\">%(username)s</a>" + +#: mediagoblin/templates/mediagoblin/user_pages/collection.html:52 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:79 +msgid "Edit" +msgstr "编辑" + +#: mediagoblin/templates/mediagoblin/user_pages/collection.html:56 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:83 +msgid "Delete" +msgstr "åˆ é™¤" + +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:30 +#: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:30 +#, python-format +msgid "Really delete %(title)s?" +msgstr "真的è¦åˆ 除 %(title)s å—?" + +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:31 +#, python-format +msgid "Really remove %(media_title)s from %(collection_title)s?" +msgstr "确定è¦ä»Ž %(collection_title)s 移除 %(media_title)s å—?" + +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:54 +msgid "Remove" +msgstr "移除" + +#: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:21 +#, python-format +msgid "%(username)s's collections" +msgstr "%(username)s çš„åˆé›†" + +#: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:28 +#, python-format +msgid "<a href=\"%(user_url)s\">%(username)s</a>'s collections" +msgstr "<a href=\"%(user_url)s\">%(username)s</a> çš„åˆé›†" + +#: mediagoblin/templates/mediagoblin/user_pages/comment_email.txt:19 +#, python-format +msgid "" +"Hi %(username)s,\n" +"%(comment_author)s commented on your post (%(comment_url)s) at %(instance_name)s\n" +msgstr "%(username)s 您好:\n%(comment_author)s 在 %(instance_name)s 对您的内容 (%(comment_url)s) å¼ è´´è¯„è®º\n" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 +#, python-format +msgid "%(username)s's media" +msgstr "%(username)s的媒体" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:38 +#, python-format +msgid "" +"<a href=\"%(user_url)s\">%(username)s</a>'s media with tag <a " +"href=\"%(tag_url)s\">%(tag)s</a>" +msgstr "<a href=\"%(user_url)s\">%(username)s</a> 的有 <a href=\"%(tag_url)s\">%(tag)s</a> æ ‡ç¾çš„媒体" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:48 +#, python-format +msgid "<a href=\"%(user_url)s\">%(username)s</a>'s media" +msgstr "<a href=\"%(user_url)s\">%(username)s</a> 的媒体" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:38 +#, 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:95 +msgid "Add a comment" +msgstr "新增评论" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 +msgid "Add this comment" +msgstr "å¢žåŠ è¯„è®º" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:132 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:152 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:164 +#, python-format +msgid "%(formatted_time)s ago" +msgstr "%(formatted_time)så‰" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:150 +msgid "Added" +msgstr "å·²å¢žåŠ " + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:161 +msgid "Created" +msgstr "已创建" + +#: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 +#: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:40 +#, python-format +msgid "Add “%(media_title)s†to a collection" +msgstr "把“%(media_title)sâ€åŠ å…¥åˆé›†" + +#: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:54 +msgid "+" +msgstr "+" + +#: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:58 +msgid "Add a new collection" +msgstr "新增新的åˆé›†" + +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:29 +msgid "" +"You can track the state of media being processed for your gallery here." +msgstr "您å¯ä»¥åœ¨è¿™é‡Œè¿½è¸ªæ‚¨çš„艺廊ä¸åª’体处ç†çš„状æ€ã€‚" + +#: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:89 +msgid "Your last 10 successful uploads" +msgstr "您的最近 10 次æˆåŠŸä¸Šä¼ çš„çºªå½•" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:31 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:89 +#, python-format +msgid "%(username)s's profile" +msgstr "%(username)s 的个人资料" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:43 +msgid "Sorry, no such user found." +msgstr "抱æ‰ï¼Œæ‰¾ä¸åˆ°è¯¥ç”¨æˆ·ã€‚" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:50 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:70 +msgid "Email verification needed" +msgstr "需è¦è®¤è¯ç”µå邮件地å€" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:53 +msgid "Almost done! Your account still needs to be activated." +msgstr "快完æˆäº†ï¼ä½†æ‚¨éœ€è¦æ¿€æ´»æ‚¨çš„账户。" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:58 +msgid "" +"An email should arrive in a few moments with instructions on how to do so." +msgstr "账户激活说明将在ç¨åŽé€è¾¾ã€‚" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:62 +msgid "In case it doesn't:" +msgstr "如果ä»ç„¶æ— 法认è¯ï¼Œæ‚¨å¯ä»¥ï¼š" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:65 +msgid "Resend verification email" +msgstr "é‡å‘认è¯é‚®ä»¶" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:73 +msgid "" +"Someone has registered an account with this username, but it still has to be" +" activated." +msgstr "有人用注册了该账户,但是该账户需è¦è¢«å¯ç”¨ã€‚" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:79 +#, python-format +msgid "" +"If you are that person but you've lost your verification email, you can <a " +"href=\"%(login_url)s\">log in</a> and resend it." +msgstr "如果您就是本人但是未收到认è¯ä¿¡ï¼Œæ‚¨å¯ä»¥<a href=\"%(login_url)s\">登录</a>ç„¶åŽé‡å‘一次。" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:96 +msgid "Here's a spot to tell others about yourself." +msgstr "这个地方能让您å‘他人介ç»è‡ªå·±ã€‚" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:100 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:117 +msgid "Edit profile" +msgstr "编辑个人资料" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:105 +msgid "This user hasn't filled in their profile (yet)." +msgstr "这个用户(还)没有填写个人资料。" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:124 +msgid "Browse collections" +msgstr "æµè§ˆåˆé›†" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:137 +#, python-format +msgid "View all of %(username)s's media" +msgstr "查看 %(username)s 的全部媒体" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:150 +msgid "" +"This is where your media will appear, but you don't seem to have added " +"anything yet." +msgstr "æ¤å¤„æ˜¯æ‚¨çš„åª’ä½“ä¼šå‡ºçŽ°çš„åœ°æ–¹ï¼Œä½†æ˜¯ä¼¼ä¹Žè¿˜æ²¡æœ‰åŠ å…¥ä»»ä½•ä¸œè¥¿ã€‚" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:162 +#: mediagoblin/templates/mediagoblin/utils/collection_gallery.html:84 +#: mediagoblin/templates/mediagoblin/utils/object_gallery.html:70 +msgid "There doesn't seem to be any media here yet..." +msgstr "那里好åƒè¿˜æ²¡æœ‰ä»»ä½•的媒体……" + +#: mediagoblin/templates/mediagoblin/utils/collection_gallery.html:49 +msgid "(remove)" +msgstr "(移除)" + +#: mediagoblin/templates/mediagoblin/utils/collections.html:21 +msgid "Collected in" +msgstr "åˆé›†äºŽ" + +#: mediagoblin/templates/mediagoblin/utils/collections.html:40 +msgid "Add to a collection" +msgstr "æ·»åŠ åˆ°åˆé›†" + +#: mediagoblin/templates/mediagoblin/utils/feed_link.html:21 +#: mediagoblin/themes/airy/templates/mediagoblin/utils/feed_link.html:21 +msgid "feed icon" +msgstr "feed å›¾æ ‡" + +#: mediagoblin/templates/mediagoblin/utils/feed_link.html:23 +#: mediagoblin/themes/airy/templates/mediagoblin/utils/feed_link.html:23 +msgid "Atom feed" +msgstr "Atom feed" + +#: mediagoblin/templates/mediagoblin/utils/license.html:25 +msgid "All rights reserved" +msgstr "ç‰ˆæƒæ‰€æœ‰" + +#: mediagoblin/templates/mediagoblin/utils/pagination.html:39 +msgid "↠Newer" +msgstr "↠更新的" + +#: mediagoblin/templates/mediagoblin/utils/pagination.html:45 +msgid "Older →" +msgstr "æ›´æ—§çš„ →" + +#: mediagoblin/templates/mediagoblin/utils/pagination.html:48 +msgid "Go to page:" +msgstr "跳到页数:" + +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:28 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:33 +msgid "newer" +msgstr "æ›´æ–°çš„" + +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:39 +#: mediagoblin/templates/mediagoblin/utils/prev_next.html:44 +msgid "older" +msgstr "æ›´æ—§çš„" + +#: mediagoblin/templates/mediagoblin/utils/tags.html:20 +msgid "Tagged with" +msgstr "æ ‡ç¾" + +#: mediagoblin/tools/exif.py:83 +msgid "Could not read the image file." +msgstr "æ— æ³•è¯»å–图片文件。" + +#: mediagoblin/tools/response.py:35 +msgid "Oops!" +msgstr "糟糕ï¼" + +#: mediagoblin/tools/response.py:36 +msgid "An error occured" +msgstr "å‘生错误" + +#: mediagoblin/tools/response.py:51 +msgid "Operation not allowed" +msgstr "æ“作ä¸å…许" + +#: mediagoblin/tools/response.py:52 +msgid "" +"Sorry Dave, I can't let you do that!</p><p>You have tried to perform a " +"function that you are not allowed to. Have you been trying to delete all " +"user accounts again?" +msgstr "对ä¸èµ·è€å…„,我ä¸èƒ½è®©ä½ è¿™æ ·åšï¼</p><p>您æ£åœ¨è¯•ç€æ“作ä¸å…è®¸æ‚¨ä½¿ç”¨çš„åŠŸèƒ½ã€‚æ‚¨éš¾é“æƒ³æ‰“ç®—åˆ é™¤æ‰€æœ‰ç”¨æˆ·è´¦æˆ·å—?" + +#: mediagoblin/tools/response.py:60 +msgid "" +"There doesn't seem to be a page at this address. Sorry!</p><p>If you're sure" +" the address is correct, maybe the page you're looking for has been moved or" +" deleted." +msgstr "ä¸å¥½æ„æ€ï¼Œçœ‹èµ·æ¥è¿™ä¸ªç½‘å€ä¸Šæ²¡æœ‰ç½‘页。</p><p>å¦‚æžœæ‚¨ç¡®å®šè¿™ä¸ªç½‘å€æ˜¯æ£ç¡®çš„,您在寻找的页é¢å¯èƒ½å·²ç»ç§»åŠ¨æˆ–æ˜¯è¢«åˆ é™¤äº†ã€‚" + +#: mediagoblin/tools/timesince.py:62 +msgid "year" +msgstr "å¹´" + +#: mediagoblin/tools/timesince.py:63 +msgid "month" +msgstr "月" + +#: mediagoblin/tools/timesince.py:64 +msgid "week" +msgstr "周" + +#: mediagoblin/tools/timesince.py:65 +msgid "day" +msgstr "æ—¥" + +#: mediagoblin/tools/timesince.py:66 +msgid "hour" +msgstr "å°æ—¶" + +#: mediagoblin/tools/timesince.py:67 +msgid "minute" +msgstr "分钟" + +#: mediagoblin/user_pages/forms.py:23 +msgid "Comment" +msgstr "评论" + +#: mediagoblin/user_pages/forms.py:25 +msgid "" +"You can use <a " +"href=\"http://daringfireball.net/projects/markdown/basics\">Markdown</a> for" +" formatting." +msgstr "您å¯ä»¥ç”¨ <a href=\"http://wowubuntu.com/markdown/\">Markdown</a> æ¥æŽ’ç‰ˆã€‚" + +#: mediagoblin/user_pages/forms.py:31 +msgid "I am sure I want to delete this" +msgstr "我确定我è¦åˆ 除这个媒体" + +#: mediagoblin/user_pages/forms.py:35 +msgid "I am sure I want to remove this item from the collection" +msgstr "我确定我è¦ä»Žåˆé›†ä¸ç§»é™¤æ¤é¡¹ç›®" + +#: mediagoblin/user_pages/forms.py:39 +msgid "Collection" +msgstr "åˆé›†" + +#: mediagoblin/user_pages/forms.py:40 +msgid "-- Select --" +msgstr "— 请选择 —" + +#: mediagoblin/user_pages/forms.py:42 +msgid "Include a note" +msgstr "åŠ æ³¨" + +#: mediagoblin/user_pages/lib.py:58 +msgid "commented on your post" +msgstr "åœ¨æ‚¨çš„å†…å®¹å¼ è´´è¯„è®º" + +#: mediagoblin/user_pages/views.py:169 +msgid "Sorry, comments are disabled." +msgstr "抱æ‰ï¼Œä¸å¼€æ”¾è¯„论。" + +#: mediagoblin/user_pages/views.py:174 +msgid "Oops, your comment was empty." +msgstr "啊,您的评论是空的。" + +#: mediagoblin/user_pages/views.py:180 +msgid "Your comment has been posted!" +msgstr "您的评论已ç»å¼ 贴完æˆï¼" + +#: mediagoblin/user_pages/views.py:205 +msgid "Please check your entries and try again." +msgstr "请检查项目并é‡è¯•。" + +#: mediagoblin/user_pages/views.py:245 +msgid "You have to select or add a collection" +msgstr "您需è¦é€‰æ‹©æˆ–是新增一个åˆé›†" + +#: mediagoblin/user_pages/views.py:256 +#, python-format +msgid "\"%s\" already in collection \"%s\"" +msgstr "“%sâ€å·²ç»åœ¨â€œ%sâ€åˆé›†" + +#: mediagoblin/user_pages/views.py:262 +#, python-format +msgid "\"%s\" added to collection \"%s\"" +msgstr "“%sâ€åŠ å…¥â€œ%sâ€åˆé›†" + +#: mediagoblin/user_pages/views.py:282 +msgid "You deleted the media." +msgstr "您已ç»åˆ 除æ¤åª’体。" + +#: mediagoblin/user_pages/views.py:289 +msgid "The media was not deleted because you didn't check that you were sure." +msgstr "由于您没有勾选确认,该媒体没有被移除。" + +#: mediagoblin/user_pages/views.py:296 +msgid "You are about to delete another user's media. Proceed with caution." +msgstr "您æ£åœ¨åˆ 除别人的媒体,请å°å¿ƒæ“作。" + +#: mediagoblin/user_pages/views.py:370 +msgid "You deleted the item from the collection." +msgstr "您已ç»ä»Žè¯¥åˆé›†ä¸åˆ 除该项目。" + +#: mediagoblin/user_pages/views.py:374 +msgid "The item was not removed because you didn't check that you were sure." +msgstr "由于您没有勾选确认,该项目没有被移除。" + +#: mediagoblin/user_pages/views.py:382 +msgid "" +"You are about to delete an item from another user's collection. Proceed with" +" caution." +msgstr "您æ£åœ¨ä»Žåˆ«äººçš„åˆé›†ä¸åˆ 除项目,请å°å¿ƒæ“作。" + +#: mediagoblin/user_pages/views.py:415 +#, python-format +msgid "You deleted the collection \"%s\"" +msgstr "您已ç»åˆ 除“%sâ€åˆé›†ã€‚" + +#: mediagoblin/user_pages/views.py:422 +msgid "" +"The collection was not deleted because you didn't check that you were sure." +msgstr "由于您没有勾选确认,该åˆé›†æ²¡æœ‰è¢«ç§»é™¤ã€‚" + +#: mediagoblin/user_pages/views.py:430 +msgid "" +"You are about to delete another user's collection. Proceed with caution." +msgstr "您æ£åœ¨åˆ 除别人的åˆé›†ï¼Œè¯·å°å¿ƒæ“作。" diff --git a/mediagoblin/i18n/zh_TW.Big5/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/zh_TW.Big5/LC_MESSAGES/mediagoblin.mo Binary files differindex d75d2eb2..c234ff00 100644 --- a/mediagoblin/i18n/zh_TW.Big5/LC_MESSAGES/mediagoblin.mo +++ b/mediagoblin/i18n/zh_TW.Big5/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/zh_TW.Big5/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/zh_TW.Big5/LC_MESSAGES/mediagoblin.po index a5e95640..a7ee8db6 100644 --- a/mediagoblin/i18n/zh_TW.Big5/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/zh_TW.Big5/LC_MESSAGES/mediagoblin.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" -"POT-Creation-Date: 2013-03-04 18:04-0600\n" -"PO-Revision-Date: 2013-03-05 00:04+0000\n" +"POT-Creation-Date: 2013-05-27 13:54-0500\n" +"PO-Revision-Date: 2013-05-27 18:54+0000\n" "Last-Translator: cwebber <cwebber@dustycloud.org>\n" "Language-Team: Chinese (Taiwan) (Big5) (http://www.transifex.com/projects/p/mediagoblin/language/zh_TW.Big5/)\n" "MIME-Version: 1.0\n" @@ -18,32 +18,37 @@ msgstr "" "Language: zh_TW.Big5\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: mediagoblin/auth/forms.py:28 -msgid "Invalid User name or email address." +#: mediagoblin/auth/forms.py:26 +msgid "Username" msgstr "" -#: mediagoblin/auth/forms.py:29 -msgid "This field does not take email addresses." +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 +#: mediagoblin/tests/test_util.py:110 +msgid "Password" msgstr "" -#: mediagoblin/auth/forms.py:30 -msgid "This field requires an email address." +#: mediagoblin/auth/forms.py:34 +msgid "Email address" msgstr "" -#: mediagoblin/auth/forms.py:52 mediagoblin/auth/forms.py:67 -msgid "Username" +#: mediagoblin/auth/forms.py:41 +msgid "Username or Email" msgstr "" -#: mediagoblin/auth/forms.py:56 mediagoblin/auth/forms.py:71 -msgid "Password" +#: mediagoblin/auth/forms.py:52 +msgid "Username or email" msgstr "" -#: mediagoblin/auth/forms.py:60 -msgid "Email address" +#: mediagoblin/auth/tools.py:31 +msgid "Invalid User name or email address." msgstr "" -#: mediagoblin/auth/forms.py:78 -msgid "Username or email" +#: mediagoblin/auth/tools.py:32 +msgid "This field does not take email addresses." +msgstr "" + +#: mediagoblin/auth/tools.py:33 +msgid "This field requires an email address." msgstr "" #: mediagoblin/auth/views.py:54 @@ -58,54 +63,54 @@ msgstr "" msgid "Sorry, a user with that email address already exists." msgstr "" -#: mediagoblin/auth/views.py:174 +#: 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:180 +#: mediagoblin/auth/views.py:188 msgid "The verification key or user id is incorrect" msgstr "" -#: mediagoblin/auth/views.py:198 +#: 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:206 +#: mediagoblin/auth/views.py:214 msgid "You've already verified your email address!" msgstr "" -#: mediagoblin/auth/views.py:219 +#: mediagoblin/auth/views.py:227 msgid "Resent your verification email." msgstr "" -#: mediagoblin/auth/views.py:250 +#: mediagoblin/auth/views.py:258 msgid "" "If that email address (case sensitive!) is registered an email has been sent" " with instructions on how to change your password." msgstr "" -#: mediagoblin/auth/views.py:261 +#: mediagoblin/auth/views.py:269 msgid "Couldn't find someone with that username." msgstr "" -#: mediagoblin/auth/views.py:264 +#: mediagoblin/auth/views.py:272 msgid "" "An email has been sent with instructions on how to change your password." msgstr "" -#: mediagoblin/auth/views.py:271 +#: mediagoblin/auth/views.py:279 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." msgstr "" -#: mediagoblin/auth/views.py:328 +#: mediagoblin/auth/views.py:336 msgid "You can now log in using your new password." msgstr "" -#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:93 +#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:82 #: mediagoblin/submit/forms.py:28 mediagoblin/submit/forms.py:47 #: mediagoblin/user_pages/forms.py:45 msgid "Title" @@ -116,7 +121,7 @@ msgid "Description of this work" msgstr "" #: mediagoblin/edit/forms.py:29 mediagoblin/edit/forms.py:52 -#: mediagoblin/edit/forms.py:97 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:86 mediagoblin/submit/forms.py:32 #: mediagoblin/submit/forms.py:51 mediagoblin/user_pages/forms.py:49 msgid "" "You can use\n" @@ -132,11 +137,11 @@ msgstr "" msgid "Separate tags by commas." msgstr "" -#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:101 +#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:90 msgid "Slug" msgstr "" -#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:102 +#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:91 msgid "The slug can't be empty" msgstr "" @@ -164,45 +169,45 @@ msgid "This address contains errors" msgstr "" #: mediagoblin/edit/forms.py:63 -msgid "Old password" -msgstr "" - -#: mediagoblin/edit/forms.py:64 -msgid "Enter your old password to prove you own this account." -msgstr "" - -#: mediagoblin/edit/forms.py:67 -msgid "New password" -msgstr "" - -#: mediagoblin/edit/forms.py:74 msgid "License preference" msgstr "" -#: mediagoblin/edit/forms.py:80 +#: mediagoblin/edit/forms.py:69 msgid "This will be your default license on upload forms." msgstr "" -#: mediagoblin/edit/forms.py:82 +#: mediagoblin/edit/forms.py:71 msgid "Email me when others comment on my media" msgstr "" -#: mediagoblin/edit/forms.py:94 +#: mediagoblin/edit/forms.py:83 msgid "The title can't be empty" msgstr "" -#: mediagoblin/edit/forms.py:96 mediagoblin/submit/forms.py:50 +#: mediagoblin/edit/forms.py:85 mediagoblin/submit/forms.py:50 #: mediagoblin/user_pages/forms.py:48 msgid "Description of this collection" msgstr "" -#: mediagoblin/edit/forms.py:103 +#: mediagoblin/edit/forms.py:92 msgid "" "The title part of this collection's address. You usually don't need to " "change this." msgstr "" -#: mediagoblin/edit/views.py:66 +#: mediagoblin/edit/forms.py:99 +msgid "Old password" +msgstr "" + +#: mediagoblin/edit/forms.py:101 +msgid "Enter your old password to prove you own this account." +msgstr "" + +#: mediagoblin/edit/forms.py:104 +msgid "New password" +msgstr "" + +#: mediagoblin/edit/views.py:67 msgid "An entry with that slug already exists for this user." msgstr "" @@ -227,44 +232,63 @@ msgstr "" msgid "Profile changes saved" msgstr "" -#: mediagoblin/edit/views.py:241 -msgid "Wrong password" -msgstr "" - -#: mediagoblin/edit/views.py:252 +#: mediagoblin/edit/views.py:240 msgid "Account settings saved" msgstr "" -#: mediagoblin/edit/views.py:286 +#: mediagoblin/edit/views.py:274 msgid "You need to confirm the deletion of your account." msgstr "" -#: mediagoblin/edit/views.py:322 mediagoblin/submit/views.py:142 -#: mediagoblin/user_pages/views.py:214 +#: mediagoblin/edit/views.py:310 mediagoblin/submit/views.py:138 +#: mediagoblin/user_pages/views.py:222 #, python-format msgid "You already have a collection called \"%s\"!" msgstr "" -#: mediagoblin/edit/views.py:326 +#: mediagoblin/edit/views.py:314 msgid "A collection with that slug already exists for this user." msgstr "" -#: mediagoblin/edit/views.py:343 +#: mediagoblin/edit/views.py:329 msgid "You are editing another user's collection. Proceed with caution." msgstr "" -#: mediagoblin/gmg_commands/theme.py:58 +#: mediagoblin/edit/views.py:348 +msgid "Wrong password" +msgstr "" + +#: mediagoblin/edit/views.py:363 +msgid "Your password was changed successfully" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:60 msgid "Cannot link theme... no theme set\n" msgstr "" -#: mediagoblin/gmg_commands/theme.py:71 +#: mediagoblin/gmg_commands/assetlink.py:73 msgid "No asset directory for this theme\n" msgstr "" -#: mediagoblin/gmg_commands/theme.py:74 +#: mediagoblin/gmg_commands/assetlink.py:76 msgid "However, old link directory symlink found; removed.\n" msgstr "" +#: mediagoblin/gmg_commands/assetlink.py:112 +#, python-format +msgid "Could not link \"%s\": %s exists and is not a symlink\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:119 +#, python-format +msgid "Skipping \"%s\"; already set up.\n" +msgstr "" + +#: mediagoblin/gmg_commands/assetlink.py:124 +#, python-format +msgid "Old link found for \"%s\"; removing.\n" +msgstr "" + #: mediagoblin/meddleware/csrf.py:134 msgid "" "CSRF cookie not present. This is most likely the result of a cookie blocker " @@ -272,12 +296,16 @@ msgid "" "domain." msgstr "" -#: mediagoblin/media_types/__init__.py:61 -#: mediagoblin/media_types/__init__.py:102 +#: mediagoblin/media_types/__init__.py:111 +#: mediagoblin/media_types/__init__.py:155 msgid "Sorry, I don't support that file type :(" msgstr "" -#: mediagoblin/media_types/video/processing.py:36 +#: mediagoblin/media_types/pdf/processing.py:136 +msgid "unoconv failing to run, check log file" +msgstr "" + +#: mediagoblin/media_types/video/processing.py:37 msgid "Video transcoding failed" msgstr "" @@ -344,7 +372,7 @@ msgstr "" msgid "This field is required for public clients" msgstr "" -#: mediagoblin/plugins/oauth/views.py:59 +#: mediagoblin/plugins/oauth/views.py:56 msgid "The client {0} has been registered!" msgstr "" @@ -363,7 +391,7 @@ msgstr "" msgid "Add" msgstr "" -#: mediagoblin/processing/__init__.py:172 +#: mediagoblin/processing/__init__.py:193 msgid "Invalid file given for media type." msgstr "" @@ -371,45 +399,45 @@ msgstr "" msgid "File" msgstr "" -#: mediagoblin/submit/views.py:51 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "" -#: mediagoblin/submit/views.py:97 +#: mediagoblin/submit/views.py:93 msgid "Woohoo! Submitted!" msgstr "" -#: mediagoblin/submit/views.py:146 +#: mediagoblin/submit/views.py:144 #, python-format msgid "Collection \"%s\" added!" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:64 +#: mediagoblin/templates/mediagoblin/base.html:67 msgid "Verify your email!" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:68 msgid "log out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:70 +#: mediagoblin/templates/mediagoblin/base.html:73 #: mediagoblin/templates/mediagoblin/auth/login.html:28 #: mediagoblin/templates/mediagoblin/auth/login.html:36 #: mediagoblin/templates/mediagoblin/auth/login.html:54 msgid "Log in" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:79 +#: mediagoblin/templates/mediagoblin/base.html:82 #, python-format msgid "<a href=\"%(user_url)s\">%(user_name)s</a>'s account" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:86 +#: mediagoblin/templates/mediagoblin/base.html:89 msgid "Change account settings" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:90 -#: mediagoblin/templates/mediagoblin/base.html:105 +#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:108 #: mediagoblin/templates/mediagoblin/admin/panel.html:21 #: mediagoblin/templates/mediagoblin/admin/panel.html:26 #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:21 @@ -417,72 +445,25 @@ msgstr "" msgid "Media processing panel" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:96 msgid "Log out" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:96 +#: mediagoblin/templates/mediagoblin/base.html:99 #: mediagoblin/templates/mediagoblin/user_pages/user.html:156 msgid "Add media" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:99 +#: mediagoblin/templates/mediagoblin/base.html:102 #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:41 msgid "Create new collection" msgstr "" -#: mediagoblin/templates/mediagoblin/base.html:122 -#, python-format -msgid "" -"Powered by <a href=\"http://mediagoblin.org/\" title='Version " -"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." -msgstr "" - -#: mediagoblin/templates/mediagoblin/base.html:125 -#, 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/error.html:24 msgid "Image of goblin stressing out" msgstr "" -#: mediagoblin/templates/mediagoblin/root.html:31 -msgid "Explore" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:35 -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:36 -msgid "" -"To add your own media, place comments, and more, you can log in with your " -"MediaGoblin account." -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Don't have one yet? It's easy!" -msgstr "" - -#: mediagoblin/templates/mediagoblin/root.html:39 -#, 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:47 +#: mediagoblin/templates/mediagoblin/root.html:32 msgid "Most recent media" msgstr "" @@ -588,6 +569,53 @@ msgid "" "%(verification_url)s" msgstr "" +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:21 +#, python-format +msgid "" +"Powered by <a href=\"http://mediagoblin.org/\" title='Version " +"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:24 +#, 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/bits/frontpage_welcome.html:20 +msgid "Explore" +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:22 +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:24 +msgid "" +"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, an " +"extraordinarily great piece of media hosting software." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:25 +msgid "" +"To add your own media, place comments, and more, you can log in with your " +"MediaGoblin account." +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:27 +msgid "Don't have one yet? It's easy!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:28 +#, python-format +msgid "" +"<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/bits/logo.html:23 #: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 msgid "MediaGoblin logo" @@ -600,13 +628,13 @@ msgid "Editing attachments for %(media_title)s" msgstr "" #: mediagoblin/templates/mediagoblin/edit/attachments.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:159 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:175 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:182 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:198 msgid "Attachments" msgstr "" #: mediagoblin/templates/mediagoblin/edit/attachments.html:57 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:181 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:204 msgid "Add attachment" msgstr "" @@ -623,12 +651,22 @@ msgstr "" #: mediagoblin/templates/mediagoblin/edit/attachments.html:63 #: mediagoblin/templates/mediagoblin/edit/edit.html:42 -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:52 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:55 #: mediagoblin/templates/mediagoblin/edit/edit_collection.html:33 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:40 msgid "Save changes" msgstr "" +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:28 +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 +#, python-format +msgid "Changing %(username)s's password" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 +msgid "Save" +msgstr "" + #: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 #, python-format msgid "Really delete user '%(user_name)s' and all related media/comments?" @@ -639,7 +677,7 @@ msgid "Yes, really delete my account" msgstr "" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:48 #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49 msgid "Delete permanently" msgstr "" @@ -656,7 +694,11 @@ msgstr "" msgid "Changing %(username)s's account settings" msgstr "" -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:59 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 +msgid "Change your password." +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 msgid "Delete my account" msgstr "" @@ -681,6 +723,7 @@ msgstr "" #: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 #: mediagoblin/templates/mediagoblin/media_displays/audio.html:56 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:65 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:136 #: mediagoblin/templates/mediagoblin/media_displays/video.html:55 msgid "Download" @@ -705,6 +748,7 @@ msgid "" msgstr "" #: mediagoblin/templates/mediagoblin/media_displays/audio.html:60 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:71 #: mediagoblin/templates/mediagoblin/media_displays/video.html:61 msgid "Original file" msgstr "" @@ -713,6 +757,7 @@ msgstr "" msgid "WebM file (Vorbis codec)" msgstr "" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:59 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:87 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:93 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:99 @@ -723,6 +768,10 @@ msgstr "" msgid "Image for %(media_title)s" msgstr "" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 +msgid "PDF file" +msgstr "" + #: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 msgid "Toggle Rotate" msgstr "" @@ -821,7 +870,7 @@ msgstr "" msgid "Really remove %(media_title)s from %(collection_title)s?" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:54 msgid "Remove" msgstr "" @@ -864,23 +913,27 @@ msgstr "" msgid "â– Browsing media by <a href=\"%(user_url)s\">%(username)s</a>" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:94 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:95 msgid "Add a comment" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 msgid "Add this comment" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:123 -msgid "at" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:132 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:152 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:164 +#, python-format +msgid "%(formatted_time)s ago" msgstr "" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:144 -#, python-format -msgid "" -"<h3>Added on</h3>\n" -" <p>%(date)s</p>" +#: mediagoblin/templates/mediagoblin/user_pages/media.html:150 +msgid "Added" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:161 +msgid "Created" msgstr "" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 @@ -1037,7 +1090,7 @@ msgstr "" msgid "Tagged with" msgstr "" -#: mediagoblin/tools/exif.py:80 +#: mediagoblin/tools/exif.py:83 msgid "Could not read the image file." msgstr "" @@ -1067,6 +1120,30 @@ msgid "" " deleted." msgstr "" +#: mediagoblin/tools/timesince.py:62 +msgid "year" +msgstr "" + +#: mediagoblin/tools/timesince.py:63 +msgid "month" +msgstr "" + +#: mediagoblin/tools/timesince.py:64 +msgid "week" +msgstr "" + +#: mediagoblin/tools/timesince.py:65 +msgid "day" +msgstr "" + +#: mediagoblin/tools/timesince.py:66 +msgid "hour" +msgstr "" + +#: mediagoblin/tools/timesince.py:67 +msgid "minute" +msgstr "" + #: mediagoblin/user_pages/forms.py:23 msgid "Comment" msgstr "" @@ -1098,73 +1175,77 @@ msgstr "" msgid "Include a note" msgstr "" -#: mediagoblin/user_pages/lib.py:56 +#: mediagoblin/user_pages/lib.py:58 msgid "commented on your post" msgstr "" -#: mediagoblin/user_pages/views.py:166 +#: mediagoblin/user_pages/views.py:169 +msgid "Sorry, comments are disabled." +msgstr "" + +#: mediagoblin/user_pages/views.py:174 msgid "Oops, your comment was empty." msgstr "" -#: mediagoblin/user_pages/views.py:172 +#: mediagoblin/user_pages/views.py:180 msgid "Your comment has been posted!" msgstr "" -#: mediagoblin/user_pages/views.py:197 +#: mediagoblin/user_pages/views.py:205 msgid "Please check your entries and try again." msgstr "" -#: mediagoblin/user_pages/views.py:237 +#: mediagoblin/user_pages/views.py:245 msgid "You have to select or add a collection" msgstr "" -#: mediagoblin/user_pages/views.py:248 +#: mediagoblin/user_pages/views.py:256 #, python-format msgid "\"%s\" already in collection \"%s\"" msgstr "" -#: mediagoblin/user_pages/views.py:264 +#: mediagoblin/user_pages/views.py:262 #, python-format msgid "\"%s\" added to collection \"%s\"" msgstr "" -#: mediagoblin/user_pages/views.py:286 +#: mediagoblin/user_pages/views.py:282 msgid "You deleted the media." msgstr "" -#: mediagoblin/user_pages/views.py:293 +#: mediagoblin/user_pages/views.py:289 msgid "The media was not deleted because you didn't check that you were sure." msgstr "" -#: mediagoblin/user_pages/views.py:301 +#: mediagoblin/user_pages/views.py:296 msgid "You are about to delete another user's media. Proceed with caution." msgstr "" -#: mediagoblin/user_pages/views.py:375 +#: mediagoblin/user_pages/views.py:370 msgid "You deleted the item from the collection." msgstr "" -#: mediagoblin/user_pages/views.py:379 +#: mediagoblin/user_pages/views.py:374 msgid "The item was not removed because you didn't check that you were sure." msgstr "" -#: mediagoblin/user_pages/views.py:389 +#: mediagoblin/user_pages/views.py:382 msgid "" "You are about to delete an item from another user's collection. Proceed with" " caution." msgstr "" -#: mediagoblin/user_pages/views.py:422 +#: mediagoblin/user_pages/views.py:415 #, python-format msgid "You deleted the collection \"%s\"" msgstr "" -#: mediagoblin/user_pages/views.py:429 +#: mediagoblin/user_pages/views.py:422 msgid "" "The collection was not deleted because you didn't check that you were sure." msgstr "" -#: mediagoblin/user_pages/views.py:439 +#: mediagoblin/user_pages/views.py:430 msgid "" "You are about to delete another user's collection. Proceed with caution." msgstr "" diff --git a/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.mo Binary files differindex 3d267cfc..4b7a2398 100644 --- a/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.mo +++ b/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.mo diff --git a/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.po index bd50df78..05ecd4b5 100644 --- a/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.po +++ b/mediagoblin/i18n/zh_TW/LC_MESSAGES/mediagoblin.po @@ -3,17 +3,19 @@ # This file is distributed under the same license as the PROJECT project. # # Translators: -# <chc@citi.sinica.edu.tw>, 2011. -# Harry Chen <harryhow@gmail.com>, 2011-2012. -# <medicalwei@gmail.com>, 2012. +# <chc@citi.sinica.edu.tw>, 2011 +# Harry Chen <harryhow@gmail.com>, 2011-2012 +# medicalwei <medicalwei@gmail.com>, 2013 +# medicalwei <medicalwei@gmail.com>, 2012 +# m13253 <m13253@hotmail.com>, 2013 msgid "" msgstr "" "Project-Id-Version: GNU MediaGoblin\n" "Report-Msgid-Bugs-To: http://issues.mediagoblin.org/\n" -"POT-Creation-Date: 2013-03-04 18:04-0600\n" -"PO-Revision-Date: 2013-03-05 00:04+0000\n" -"Last-Translator: cwebber <cwebber@dustycloud.org>\n" -"Language-Team: LANGUAGE <LL@li.org>\n" +"POT-Creation-Date: 2013-05-27 13:54-0500\n" +"PO-Revision-Date: 2013-06-16 01:40+0000\n" +"Last-Translator: m13253 <m13253@hotmail.com>\n" +"Language-Team: Chinese (Taiwan) (http://www.transifex.com/projects/p/mediagoblin/language/zh_TW/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -21,34 +23,39 @@ msgstr "" "Language: zh_TW\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: mediagoblin/auth/forms.py:28 -msgid "Invalid User name or email address." -msgstr "" - -#: mediagoblin/auth/forms.py:29 -msgid "This field does not take email addresses." -msgstr "" - -#: mediagoblin/auth/forms.py:30 -msgid "This field requires an email address." -msgstr "" - -#: mediagoblin/auth/forms.py:52 mediagoblin/auth/forms.py:67 +#: mediagoblin/auth/forms.py:26 msgid "Username" msgstr "使用者å稱" -#: mediagoblin/auth/forms.py:56 mediagoblin/auth/forms.py:71 +#: mediagoblin/auth/forms.py:30 mediagoblin/auth/forms.py:45 +#: mediagoblin/tests/test_util.py:110 msgid "Password" msgstr "密碼" -#: mediagoblin/auth/forms.py:60 +#: mediagoblin/auth/forms.py:34 msgid "Email address" msgstr "Email ä½å€" -#: mediagoblin/auth/forms.py:78 +#: mediagoblin/auth/forms.py:41 +msgid "Username or Email" +msgstr "使用者å稱或 email" + +#: mediagoblin/auth/forms.py:52 msgid "Username or email" msgstr "使用者å稱或 email" +#: mediagoblin/auth/tools.py:31 +msgid "Invalid User name or email address." +msgstr "無效的使用者å稱或 email ä½ç½®ã€‚" + +#: mediagoblin/auth/tools.py:32 +msgid "This field does not take email addresses." +msgstr "本欄ä½ä¸æŽ¥å— email ä½ç½®ã€‚" + +#: mediagoblin/auth/tools.py:33 +msgid "This field requires an email address." +msgstr "本欄ä½éœ€è¦ email ä½ç½®ã€‚" + #: mediagoblin/auth/views.py:54 msgid "Sorry, registration is disabled on this instance." msgstr "抱æ‰ï¼Œæœ¬ç«™å·²ç¶“æš«åœè¨»å†Šã€‚" @@ -61,54 +68,54 @@ msgstr "抱æ‰ï¼Œé€™å€‹ä½¿ç”¨è€…å稱已經å˜åœ¨ã€‚" msgid "Sorry, a user with that email address already exists." msgstr "抱æ‰ï¼Œæ¤ email ä½ç½®å·²ç¶“被註冊了。" -#: mediagoblin/auth/views.py:174 +#: mediagoblin/auth/views.py:182 msgid "" "Your email address has been verified. You may now login, edit your profile, " "and submit images!" msgstr "您的 email ä½å€å·²è¢«èªè‰ã€‚您已經å¯ä»¥ç™»å…¥ï¼Œç·¨è¼¯æ‚¨çš„個人檔案並上傳圖片ï¼" -#: mediagoblin/auth/views.py:180 +#: mediagoblin/auth/views.py:188 msgid "The verification key or user id is incorrect" msgstr "èªè‰ç¢¼æˆ–是使用者 ID 錯誤" -#: mediagoblin/auth/views.py:198 +#: 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:206 +#: mediagoblin/auth/views.py:214 msgid "You've already verified your email address!" msgstr "您的電å郵件已經確èªäº†ï¼" -#: mediagoblin/auth/views.py:219 +#: mediagoblin/auth/views.py:227 msgid "Resent your verification email." msgstr "é‡é€èªè‰ä¿¡ã€‚" -#: mediagoblin/auth/views.py:250 +#: mediagoblin/auth/views.py:258 msgid "" "If that email address (case sensitive!) is registered an email has been sent" " with instructions on how to change your password." -msgstr "" +msgstr "如果那 email ä½ç½® (請注æ„大å°å¯«) 已經註冊,寫有修改密碼æ¥é©Ÿçš„ email 已經é€å‡ºã€‚" -#: mediagoblin/auth/views.py:261 +#: mediagoblin/auth/views.py:269 msgid "Couldn't find someone with that username." -msgstr "" +msgstr "找ä¸åˆ°ç›¸é—œçš„使用者å稱。" -#: mediagoblin/auth/views.py:264 +#: mediagoblin/auth/views.py:272 msgid "" "An email has been sent with instructions on how to change your password." msgstr "修改密碼的指示已經由電å郵件寄é€åˆ°æ‚¨çš„信箱。" -#: mediagoblin/auth/views.py:271 +#: mediagoblin/auth/views.py:279 msgid "" "Could not send password recovery email as your username is inactive or your " "account's email address has not been verified." msgstr "無法傳é€å¯†ç¢¼å›žå¾©ä¿¡ä»¶ï¼Œå› 為您的使用者å稱已失效或是帳號尚未èªè‰ã€‚" -#: mediagoblin/auth/views.py:328 +#: mediagoblin/auth/views.py:336 msgid "You can now log in using your new password." msgstr "您ç¾åœ¨å¯ä»¥ç”¨æ–°çš„密碼登入了ï¼" -#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:93 +#: mediagoblin/edit/forms.py:25 mediagoblin/edit/forms.py:82 #: mediagoblin/submit/forms.py:28 mediagoblin/submit/forms.py:47 #: mediagoblin/user_pages/forms.py:45 msgid "Title" @@ -119,7 +126,7 @@ msgid "Description of this work" msgstr "這個作å“çš„æè¿°" #: mediagoblin/edit/forms.py:29 mediagoblin/edit/forms.py:52 -#: mediagoblin/edit/forms.py:97 mediagoblin/submit/forms.py:32 +#: mediagoblin/edit/forms.py:86 mediagoblin/submit/forms.py:32 #: mediagoblin/submit/forms.py:51 mediagoblin/user_pages/forms.py:49 msgid "" "You can use\n" @@ -135,11 +142,11 @@ msgstr "標籤" msgid "Separate tags by commas." msgstr "用逗號分隔標籤。" -#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:101 +#: mediagoblin/edit/forms.py:38 mediagoblin/edit/forms.py:90 msgid "Slug" msgstr "簡稱" -#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:102 +#: mediagoblin/edit/forms.py:39 mediagoblin/edit/forms.py:91 msgid "The slug can't be empty" msgstr "簡稱ä¸èƒ½ç‚ºç©ºç™½" @@ -167,45 +174,45 @@ msgid "This address contains errors" msgstr "本網å€å‡ºéŒ¯äº†" #: mediagoblin/edit/forms.py:63 -msgid "Old password" -msgstr "舊的密碼" - -#: mediagoblin/edit/forms.py:64 -msgid "Enter your old password to prove you own this account." -msgstr "è¼¸å…¥æ‚¨çš„èˆŠå¯†ç¢¼ä¾†è‰æ˜Žæ‚¨æ“有這個帳號。" - -#: mediagoblin/edit/forms.py:67 -msgid "New password" -msgstr "新密碼" - -#: mediagoblin/edit/forms.py:74 msgid "License preference" -msgstr "" +msgstr "授權å好" -#: mediagoblin/edit/forms.py:80 +#: mediagoblin/edit/forms.py:69 msgid "This will be your default license on upload forms." -msgstr "" +msgstr "在上傳é é¢ï¼Œé€™å°‡æœƒæ˜¯æ‚¨é è¨çš„æŽˆæ¬Šæ¨¡å¼ã€‚" -#: mediagoblin/edit/forms.py:82 +#: mediagoblin/edit/forms.py:71 msgid "Email me when others comment on my media" -msgstr "ç•¶æœ‰äººå°æˆ‘的媒體評論時寄信給我" +msgstr "ç•¶æœ‰äººå°æˆ‘的媒體留言時寄信給我" -#: mediagoblin/edit/forms.py:94 +#: mediagoblin/edit/forms.py:83 msgid "The title can't be empty" msgstr "標題ä¸èƒ½æ˜¯ç©ºçš„" -#: mediagoblin/edit/forms.py:96 mediagoblin/submit/forms.py:50 +#: mediagoblin/edit/forms.py:85 mediagoblin/submit/forms.py:50 #: mediagoblin/user_pages/forms.py:48 msgid "Description of this collection" msgstr "這個è’è—çš„æè¿°" -#: mediagoblin/edit/forms.py:103 +#: mediagoblin/edit/forms.py:92 msgid "" "The title part of this collection's address. You usually don't need to " "change this." msgstr "æ¤è’è—ç¶²å€çš„æ¨™é¡Œéƒ¨ä»½ï¼Œé€šå¸¸ä¸éœ€è¦ä¿®æ”¹ã€‚" -#: mediagoblin/edit/views.py:66 +#: mediagoblin/edit/forms.py:99 +msgid "Old password" +msgstr "舊的密碼" + +#: mediagoblin/edit/forms.py:101 +msgid "Enter your old password to prove you own this account." +msgstr "è¼¸å…¥æ‚¨çš„èˆŠå¯†ç¢¼ä¾†è‰æ˜Žæ‚¨æ“有這個帳號。" + +#: mediagoblin/edit/forms.py:104 +msgid "New password" +msgstr "新密碼" + +#: mediagoblin/edit/views.py:67 msgid "An entry with that slug already exists for this user." msgstr "這個簡稱已經被其他人用了" @@ -220,7 +227,7 @@ msgstr "æ‚¨åŠ ä¸Šäº†é™„ä»¶ã€Œ%sã€ï¼" #: mediagoblin/edit/views.py:182 msgid "You can only edit your own profile." -msgstr "" +msgstr "您åªèƒ½ä¿®æ”¹æ‚¨è‡ªå·±çš„個人檔案。" #: mediagoblin/edit/views.py:188 msgid "You are editing a user's profile. Proceed with caution." @@ -230,57 +237,80 @@ msgstr "您æ£åœ¨ä¿®æ”¹åˆ¥äººçš„個人檔案,請å°å¿ƒæ“作。" msgid "Profile changes saved" msgstr "個人檔案修改已儲å˜" -#: mediagoblin/edit/views.py:241 -msgid "Wrong password" -msgstr "密碼錯誤" - -#: mediagoblin/edit/views.py:252 +#: mediagoblin/edit/views.py:240 msgid "Account settings saved" msgstr "帳號è¨å®šå·²å„²å˜" -#: mediagoblin/edit/views.py:286 +#: mediagoblin/edit/views.py:274 msgid "You need to confirm the deletion of your account." -msgstr "" +msgstr "æ‚¨å¿…é ˆè¦ç¢ºèªæ˜¯å¦åˆªé™¤æ‚¨çš„帳號。" -#: mediagoblin/edit/views.py:322 mediagoblin/submit/views.py:142 -#: mediagoblin/user_pages/views.py:214 +#: mediagoblin/edit/views.py:310 mediagoblin/submit/views.py:138 +#: mediagoblin/user_pages/views.py:222 #, python-format msgid "You already have a collection called \"%s\"!" msgstr "您已經有一個稱åšã€Œ%sã€çš„è’è—了ï¼" -#: mediagoblin/edit/views.py:326 +#: mediagoblin/edit/views.py:314 msgid "A collection with that slug already exists for this user." msgstr "這個使用者已經有使用該簡稱的è’è—了。" -#: mediagoblin/edit/views.py:343 +#: mediagoblin/edit/views.py:329 msgid "You are editing another user's collection. Proceed with caution." msgstr "您æ£åœ¨ä¿®æ”¹åˆ¥äººçš„è’è—,請å°å¿ƒæ“作。" -#: mediagoblin/gmg_commands/theme.py:58 +#: mediagoblin/edit/views.py:348 +msgid "Wrong password" +msgstr "密碼錯誤" + +#: mediagoblin/edit/views.py:363 +msgid "Your password was changed successfully" +msgstr "您的密碼已經æˆåŠŸä¿®æ”¹" + +#: mediagoblin/gmg_commands/assetlink.py:60 msgid "Cannot link theme... no theme set\n" msgstr "無法連çµä½ˆæ™¯â€¦æ²’有æ¤ä½ˆæ™¯\n" -#: mediagoblin/gmg_commands/theme.py:71 +#: mediagoblin/gmg_commands/assetlink.py:73 msgid "No asset directory for this theme\n" msgstr "æ¤ä½ˆæ™¯æ²’æœ‰ç´ æç›®éŒ„\n" -#: mediagoblin/gmg_commands/theme.py:74 +#: mediagoblin/gmg_commands/assetlink.py:76 msgid "However, old link directory symlink found; removed.\n" msgstr "但是舊的目錄連çµå·²ç¶“找到並移除。\n" +#: mediagoblin/gmg_commands/assetlink.py:112 +#, python-format +msgid "Could not link \"%s\": %s exists and is not a symlink\n" +msgstr "無法連çµã€Œ%sã€ï¼š%s å˜åœ¨ï¼Œä¸”䏿˜¯ç¬¦è™Ÿé€£çµ\n" + +#: mediagoblin/gmg_commands/assetlink.py:119 +#, python-format +msgid "Skipping \"%s\"; already set up.\n" +msgstr "è·³éŽã€Œ%sã€ï¼Œå·²ç¶“建置完æˆã€‚\n" + +#: mediagoblin/gmg_commands/assetlink.py:124 +#, python-format +msgid "Old link found for \"%s\"; removing.\n" +msgstr "找到「%sã€èˆŠçš„連çµï¼Œåˆªé™¤ä¸ã€‚\n" + #: mediagoblin/meddleware/csrf.py:134 msgid "" "CSRF cookie not present. This is most likely the result of a cookie blocker " "or somesuch.<br/>Make sure to permit the settings of cookies for this " "domain." -msgstr "" +msgstr "跨網站å˜å– (CSRF) çš„ cookie ä¸å˜åœ¨ï¼Œæœ‰å¯èƒ½æ˜¯ cookie 阻擋程å¼ä¹‹é¡žçš„程å¼å°Žè‡´çš„。<br/>è«‹å…許æ¤ç¶²åŸŸçš„ cookie è¨å®šã€‚" -#: mediagoblin/media_types/__init__.py:61 -#: mediagoblin/media_types/__init__.py:102 +#: mediagoblin/media_types/__init__.py:111 +#: mediagoblin/media_types/__init__.py:155 msgid "Sorry, I don't support that file type :(" msgstr "抱æ‰ï¼Œæˆ‘䏿”¯æ´é€™æ¨£çš„æª”æ¡ˆæ ¼å¼ :(" -#: mediagoblin/media_types/video/processing.py:36 +#: mediagoblin/media_types/pdf/processing.py:136 +msgid "unoconv failing to run, check log file" +msgstr "unoconv 無法執行,請檢查紀錄檔" + +#: mediagoblin/media_types/video/processing.py:37 msgid "Video transcoding failed" msgstr "å½±åƒè½‰ç¢¼å¤±æ•—" @@ -307,7 +337,7 @@ msgstr "å稱" #: mediagoblin/plugins/oauth/forms.py:35 msgid "The name of the OAuth client" -msgstr "OAuth client çš„å稱" +msgstr "OAuth 用戶程å¼çš„å稱" #: mediagoblin/plugins/oauth/forms.py:36 msgid "Description" @@ -331,7 +361,7 @@ msgid "" " <strong>Public</strong> - The client can't make confidential\n" " requests to the GNU MediaGoblin instance (e.g. client-side\n" " JavaScript client)." -msgstr "<strong>秘密</strong> — OAuth client å¯ä»¥å° GNU MediaGoblin ç«™å°ç™¼é€ä¸è¢«ä½¿ç”¨è€…ä»£ç†æ””截的請求 (例如伺æœç«¯çš„ client)。\n<strong>公開</strong> — OAuth client ç„¡æ³•å° GNU MediaGoblin ç«™å°ç™¼é€ç§˜å¯†çš„請求 (例如客戶端的 JavaScript client)。" +msgstr "<strong>秘密</strong> — OAuth 用戶程å¼å¯ä»¥å° GNU MediaGoblin ç«™å°ç™¼é€ä¸è¢«ä½¿ç”¨è€…ä»£ç†æ””截的請求 (例如伺æœç«¯çš„用戶程å¼)。\n<strong>公開</strong> — OAuth 用戶程å¼ç„¡æ³•å° GNU MediaGoblin ç«™å°ç™¼é€ç§˜å¯†çš„請求 (例如客戶端的 JavaScript 用戶程å¼)。" #: mediagoblin/plugins/oauth/forms.py:52 msgid "Redirect URI" @@ -341,23 +371,23 @@ msgstr "é‡å®šå‘ URI" msgid "" "The redirect URI for the applications, this field\n" " is <strong>required</strong> for public clients." -msgstr "æ¤æ‡‰ç”¨ç¨‹å¼çš„é‡å®šå‘ URI,本欄ä½åœ¨å…¬é–‹é¡žåž‹çš„ OAuth client 為必填。" +msgstr "æ¤æ‡‰ç”¨ç¨‹å¼çš„é‡å®šå‘ URI,本欄ä½åœ¨å…¬é–‹é¡žåž‹çš„ OAuth 用戶程å¼ç‚ºå¿…填。" #: mediagoblin/plugins/oauth/forms.py:66 msgid "This field is required for public clients" -msgstr "本欄ä½åœ¨å…¬é–‹é¡žåž‹çš„ OAuth client 為必填" +msgstr "本欄ä½åœ¨å…¬é–‹é¡žåž‹çš„用戶程å¼ç‚ºå¿…å¡«" -#: mediagoblin/plugins/oauth/views.py:59 +#: mediagoblin/plugins/oauth/views.py:56 msgid "The client {0} has been registered!" -msgstr "OAuth client {0} 註冊完æˆï¼" +msgstr "OAuth ç”¨æˆ¶ç¨‹å¼ {0} 註冊完æˆï¼" #: mediagoblin/plugins/oauth/templates/oauth/client/connections.html:22 msgid "OAuth client connections" -msgstr "" +msgstr "OAuth 用戶程å¼é€£ç·š" #: mediagoblin/plugins/oauth/templates/oauth/client/list.html:22 msgid "Your OAuth clients" -msgstr "" +msgstr "您的 OAuth 用戶程å¼" #: mediagoblin/plugins/oauth/templates/oauth/client/register.html:29 #: mediagoblin/templates/mediagoblin/submit/collection.html:30 @@ -366,7 +396,7 @@ msgstr "" msgid "Add" msgstr "å¢žåŠ " -#: mediagoblin/processing/__init__.py:172 +#: mediagoblin/processing/__init__.py:193 msgid "Invalid file given for media type." msgstr "指定錯誤的媒體類別ï¼" @@ -374,45 +404,45 @@ msgstr "指定錯誤的媒體類別ï¼" msgid "File" msgstr "檔案" -#: mediagoblin/submit/views.py:51 +#: mediagoblin/submit/views.py:49 msgid "You must provide a file." msgstr "æ‚¨å¿…é ˆæä¾›ä¸€å€‹æª”案" -#: mediagoblin/submit/views.py:97 +#: mediagoblin/submit/views.py:93 msgid "Woohoo! Submitted!" msgstr "啊哈ï¼PO 上去啦ï¼" -#: mediagoblin/submit/views.py:146 +#: mediagoblin/submit/views.py:144 #, python-format msgid "Collection \"%s\" added!" msgstr "è’è—「%sã€æ–°å¢žå®Œæˆï¼" -#: mediagoblin/templates/mediagoblin/base.html:64 +#: mediagoblin/templates/mediagoblin/base.html:67 msgid "Verify your email!" msgstr "ç¢ºèªæ‚¨çš„é›»å郵件" -#: mediagoblin/templates/mediagoblin/base.html:65 +#: mediagoblin/templates/mediagoblin/base.html:68 msgid "log out" msgstr "登出" -#: mediagoblin/templates/mediagoblin/base.html:70 +#: mediagoblin/templates/mediagoblin/base.html:73 #: mediagoblin/templates/mediagoblin/auth/login.html:28 #: mediagoblin/templates/mediagoblin/auth/login.html:36 #: mediagoblin/templates/mediagoblin/auth/login.html:54 msgid "Log in" msgstr "登入" -#: mediagoblin/templates/mediagoblin/base.html:79 +#: mediagoblin/templates/mediagoblin/base.html:82 #, python-format msgid "<a href=\"%(user_url)s\">%(user_name)s</a>'s account" msgstr "<a href=\"%(user_url)s\">%(user_name)s</a> 的帳號" -#: mediagoblin/templates/mediagoblin/base.html:86 +#: mediagoblin/templates/mediagoblin/base.html:89 msgid "Change account settings" msgstr "更改帳號è¨å®š" -#: mediagoblin/templates/mediagoblin/base.html:90 -#: mediagoblin/templates/mediagoblin/base.html:105 +#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:108 #: mediagoblin/templates/mediagoblin/admin/panel.html:21 #: mediagoblin/templates/mediagoblin/admin/panel.html:26 #: mediagoblin/templates/mediagoblin/user_pages/processing_panel.html:21 @@ -420,72 +450,25 @@ msgstr "更改帳號è¨å®š" msgid "Media processing panel" msgstr "媒體處ç†é¢æ¿" -#: mediagoblin/templates/mediagoblin/base.html:93 +#: mediagoblin/templates/mediagoblin/base.html:96 msgid "Log out" -msgstr "" +msgstr "登出" -#: mediagoblin/templates/mediagoblin/base.html:96 +#: mediagoblin/templates/mediagoblin/base.html:99 #: mediagoblin/templates/mediagoblin/user_pages/user.html:156 msgid "Add media" msgstr "新增媒體" -#: mediagoblin/templates/mediagoblin/base.html:99 +#: mediagoblin/templates/mediagoblin/base.html:102 #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:41 msgid "Create new collection" msgstr "新增新的è’è—" -#: mediagoblin/templates/mediagoblin/base.html:122 -#, python-format -msgid "" -"Powered by <a href=\"http://mediagoblin.org/\" title='Version " -"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." -msgstr "" - -#: mediagoblin/templates/mediagoblin/base.html:125 -#, 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/error.html:24 msgid "Image of goblin stressing out" msgstr "滿臉å•號的哥布林" -#: mediagoblin/templates/mediagoblin/root.html:31 -msgid "Explore" -msgstr "探索" - -#: mediagoblin/templates/mediagoblin/root.html:33 -msgid "Hi there, welcome to this MediaGoblin site!" -msgstr "å˜¿ï¼æ¡è¿Žä¾†åˆ° MediaGoblin ç«™å°ï¼ " - -#: mediagoblin/templates/mediagoblin/root.html:35 -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> — 與眾ä¸åŒçš„媒體分享網站。" - -#: mediagoblin/templates/mediagoblin/root.html:36 -msgid "" -"To add your own media, place comments, and more, you can log in with your " -"MediaGoblin account." -msgstr "您å¯ä»¥ç™»å…¥æ‚¨çš„ MediaGoblin 帳號以進行上傳媒體ã€å¼µè²¼è©•è«–ç‰ç‰ã€‚" - -#: mediagoblin/templates/mediagoblin/root.html:38 -msgid "Don't have one yet? It's easy!" -msgstr "沒有帳號嗎?開帳號很簡單ï¼" - -#: mediagoblin/templates/mediagoblin/root.html:39 -#, 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\">在這個網站上建立帳號</a>\n 或是\n <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">在自己的伺æœå™¨ä¸Šå»ºç«‹ MediaGoblin</a>" - -#: mediagoblin/templates/mediagoblin/root.html:47 +#: mediagoblin/templates/mediagoblin/root.html:32 msgid "Most recent media" msgstr "最新的媒體" @@ -591,6 +574,53 @@ msgid "" "%(verification_url)s" msgstr "%(username)s 您好:\n\nè¦å•Ÿå‹• GNU MediaGoblin 帳號,請在您的ç€è¦½å™¨ä¸æ‰“開下é¢çš„ç¶²å€:\n\n%(verification_url)s" +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:21 +#, python-format +msgid "" +"Powered by <a href=\"http://mediagoblin.org/\" title='Version " +"%(version)s'>MediaGoblin</a>, a <a href=\"http://gnu.org/\">GNU</a> project." +msgstr "本站使用 <a href=\"http://mediagoblin.org/\" title='Version %(version)s'>MediaGoblin</a>,這是一個 <a href=\"http://gnu.org/\">GNU</a> 專案。" + +#: mediagoblin/templates/mediagoblin/bits/base_footer.html:24 +#, 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/bits/frontpage_welcome.html:20 +msgid "Explore" +msgstr "探索" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:22 +msgid "Hi there, welcome to this MediaGoblin site!" +msgstr "å˜¿ï¼æ¡è¿Žä¾†åˆ° MediaGoblin ç«™å°ï¼ " + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:24 +msgid "" +"This site is running <a href=\"http://mediagoblin.org\">MediaGoblin</a>, an " +"extraordinarily great piece of media hosting software." +msgstr "本站使用 <a href=\"http://mediagoblin.org\">MediaGoblin</a> — 與眾ä¸åŒçš„媒體分享網站。" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:25 +msgid "" +"To add your own media, place comments, and more, you can log in with your " +"MediaGoblin account." +msgstr "您å¯ä»¥ç™»å…¥æ‚¨çš„ MediaGoblin 帳號以進行上傳媒體ã€å¼µè²¼è©•è«–ç‰ç‰ã€‚" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:27 +msgid "Don't have one yet? It's easy!" +msgstr "沒有帳號嗎?開帳號很簡單ï¼" + +#: mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html:28 +#, python-format +msgid "" +"<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\">在本站建立您的帳號</a>\n 或是\n <a class=\"button_action\" href=\"http://wiki.mediagoblin.org/HackingHowto\">在您自己的伺æœå™¨ä¸Šå®‰è£ MediaGoblin</a>" + #: mediagoblin/templates/mediagoblin/bits/logo.html:23 #: mediagoblin/themes/airy/templates/mediagoblin/bits/logo.html:23 msgid "MediaGoblin logo" @@ -603,13 +633,13 @@ msgid "Editing attachments for %(media_title)s" msgstr "編輯 %(media_title)s 的附件" #: mediagoblin/templates/mediagoblin/edit/attachments.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:159 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:175 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:182 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:198 msgid "Attachments" msgstr "附件" #: mediagoblin/templates/mediagoblin/edit/attachments.html:57 -#: mediagoblin/templates/mediagoblin/user_pages/media.html:181 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:204 msgid "Add attachment" msgstr "新增附件" @@ -626,23 +656,33 @@ msgstr "å–æ¶ˆ" #: mediagoblin/templates/mediagoblin/edit/attachments.html:63 #: mediagoblin/templates/mediagoblin/edit/edit.html:42 -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:52 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:55 #: mediagoblin/templates/mediagoblin/edit/edit_collection.html:33 #: mediagoblin/templates/mediagoblin/edit/edit_profile.html:40 msgid "Save changes" msgstr "儲å˜è®Šæ›´" +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:28 +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:38 +#, python-format +msgid "Changing %(username)s's password" +msgstr "更改 %(username)s 的密碼" + +#: mediagoblin/templates/mediagoblin/edit/change_pass.html:45 +msgid "Save" +msgstr "儲å˜" + #: mediagoblin/templates/mediagoblin/edit/delete_account.html:28 #, python-format msgid "Really delete user '%(user_name)s' and all related media/comments?" -msgstr "" +msgstr "真的è¦åˆªé™¤ä½¿ç”¨è€…「%(user_name)sã€ä»¥åŠç›¸é—œçš„媒體與留言?" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:35 msgid "Yes, really delete my account" -msgstr "" +msgstr "æ˜¯çš„ï¼Œæˆ‘çœŸçš„è¦æŠŠæˆ‘çš„å¸³è™Ÿåˆªé™¤" #: mediagoblin/templates/mediagoblin/edit/delete_account.html:44 -#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:47 +#: mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html:48 #: mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html:49 msgid "Delete permanently" msgstr "永久刪除" @@ -659,9 +699,13 @@ msgstr "編輯 %(media_title)s" msgid "Changing %(username)s's account settings" msgstr "æ£åœ¨æ”¹è®Š %(username)s 的帳號è¨å®š" -#: mediagoblin/templates/mediagoblin/edit/edit_account.html:59 +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:46 +msgid "Change your password." +msgstr "更改您的密碼。" + +#: mediagoblin/templates/mediagoblin/edit/edit_account.html:62 msgid "Delete my account" -msgstr "" +msgstr "刪除我的帳號" #: mediagoblin/templates/mediagoblin/edit/edit_collection.html:29 #, python-format @@ -680,10 +724,11 @@ msgstr "編輯 %(username)s 的個人檔案" #: mediagoblin/templates/mediagoblin/listings/tag.html:35 #, python-format msgid "Media tagged with: %(tag_name)s" -msgstr "æ¤åª’體被 tag æˆï¼š%(tag_name)s" +msgstr "這個媒體具有以下標籤:%(tag_name)s" #: mediagoblin/templates/mediagoblin/media_displays/ascii.html:34 #: mediagoblin/templates/mediagoblin/media_displays/audio.html:56 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:65 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:136 #: mediagoblin/templates/mediagoblin/media_displays/video.html:55 msgid "Download" @@ -708,6 +753,7 @@ msgid "" msgstr "您å¯ä»¥åœ¨ <a href=\"http://getfirefox.com\">http://getfirefox.com</a> å–å¾—å¯ä»¥æ’放æ¤è²éŸ³çš„ç€è¦½å™¨ï¼" #: mediagoblin/templates/mediagoblin/media_displays/audio.html:60 +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:71 #: mediagoblin/templates/mediagoblin/media_displays/video.html:61 msgid "Original file" msgstr "原始檔案" @@ -716,6 +762,7 @@ msgstr "原始檔案" msgid "WebM file (Vorbis codec)" msgstr "WebM 檔案 (Vorbis 編碼)" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:59 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:87 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:93 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:99 @@ -726,13 +773,17 @@ msgstr "WebM 檔案 (Vorbis 編碼)" msgid "Image for %(media_title)s" msgstr " %(media_title)s 的照片" +#: mediagoblin/templates/mediagoblin/media_displays/pdf.html:79 +msgid "PDF file" +msgstr "PDF 檔" + #: mediagoblin/templates/mediagoblin/media_displays/stl.html:112 msgid "Toggle Rotate" msgstr "åˆ‡æ›æ—‹è½‰" #: mediagoblin/templates/mediagoblin/media_displays/stl.html:113 msgid "Perspective" -msgstr "視角" +msgstr "é€è¦–" #: mediagoblin/templates/mediagoblin/media_displays/stl.html:116 #: mediagoblin/templates/mediagoblin/media_displays/stl.html:117 @@ -771,14 +822,14 @@ msgid "" "Sorry, this video will not work because\n" " your web browser does not support HTML5 \n" " video." -msgstr "" +msgstr "抱æ‰ï¼Œç”±æ–¼æ‚¨çš„ç€è¦½å™¨ä¸æ”¯æ´ HTML5 å½±ç‰‡ï¼Œæœ¬å½±ç‰‡ç„¡æ³•æ’æ”¾" #: mediagoblin/templates/mediagoblin/media_displays/video.html:47 msgid "" "You can get a modern web browser that \n" " can play this video at <a href=\"http://getfirefox.com\">\n" " http://getfirefox.com</a>!" -msgstr "" +msgstr "您å¯ä»¥åœ¨ <a href=\"http://getfirefox.com\">http://getfirefox.com</a> å–å¾—å¯ä»¥æ’放æ¤å½±ç‰‡çš„先進ç€è¦½å™¨ã€‚" #: mediagoblin/templates/mediagoblin/media_displays/video.html:69 msgid "WebM file (640p; VP8/Vorbis)" @@ -824,26 +875,26 @@ msgstr "真的è¦åˆªé™¤ %(title)s?" msgid "Really remove %(media_title)s from %(collection_title)s?" msgstr "確定è¦å¾ž %(collection_title)s 移除 %(media_title)s 嗎?" -#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:53 +#: mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html:54 msgid "Remove" msgstr "移除" #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:21 #, python-format msgid "%(username)s's collections" -msgstr "" +msgstr "%(username)s çš„è’è—" #: mediagoblin/templates/mediagoblin/user_pages/collection_list.html:28 #, python-format msgid "<a href=\"%(user_url)s\">%(username)s</a>'s collections" -msgstr "" +msgstr "<a href=\"%(user_url)s\">%(username)s</a> çš„è’è—" #: mediagoblin/templates/mediagoblin/user_pages/comment_email.txt:19 #, python-format msgid "" "Hi %(username)s,\n" "%(comment_author)s commented on your post (%(comment_url)s) at %(instance_name)s\n" -msgstr "%(username)s 您好:\n%(comment_author)s 在 %(instance_name)s å°æ‚¨çš„內容 (%(comment_url)s) 張貼評論\n" +msgstr "%(username)s 您好:\n%(comment_author)s 在 %(instance_name)s å°æ‚¨çš„內容 (%(comment_url)s) 張貼留言\n" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 #, python-format @@ -855,7 +906,7 @@ msgstr "%(username)s的媒體" msgid "" "<a href=\"%(user_url)s\">%(username)s</a>'s media with tag <a " "href=\"%(tag_url)s\">%(tag)s</a>" -msgstr "" +msgstr "標籤為 <a href=\"%(tag_url)s\">%(tag)s</a> çš„ <a href=\"%(user_url)s\">%(username)s</a> 的媒體" #: mediagoblin/templates/mediagoblin/user_pages/gallery.html:48 #, python-format @@ -867,30 +918,34 @@ msgstr "<a href=\"%(user_url)s\">%(username)s</a> 的媒體" 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:94 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:95 msgid "Add a comment" -msgstr "新增評論" +msgstr "新增留言" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:102 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:104 msgid "Add this comment" -msgstr "å¢žåŠ è©•è«–" - -#: mediagoblin/templates/mediagoblin/user_pages/media.html:123 -msgid "at" -msgstr "在" +msgstr "å¢žåŠ ç•™è¨€" -#: mediagoblin/templates/mediagoblin/user_pages/media.html:144 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:132 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:152 +#: mediagoblin/templates/mediagoblin/user_pages/media.html:164 #, python-format -msgid "" -"<h3>Added on</h3>\n" -" <p>%(date)s</p>" -msgstr "<h3>åŠ å…¥æ—¥æœŸ</h3>\n <p>%(date)s</p>" +msgid "%(formatted_time)s ago" +msgstr "%(formatted_time)s å‰" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:150 +msgid "Added" +msgstr "新增於" + +#: mediagoblin/templates/mediagoblin/user_pages/media.html:161 +msgid "Created" +msgstr "建立於" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:28 #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:40 #, python-format msgid "Add “%(media_title)s†to a collection" -msgstr "" +msgstr "åŠ å…¥ “%(media_title)s†至è’è—" #: mediagoblin/templates/mediagoblin/user_pages/media_collect.html:54 msgid "+" @@ -969,7 +1024,7 @@ msgstr "這個使用者(é‚„)沒有填寫個人檔案。" #: mediagoblin/templates/mediagoblin/user_pages/user.html:124 msgid "Browse collections" -msgstr "" +msgstr "ç€è¦½è’è—" #: mediagoblin/templates/mediagoblin/user_pages/user.html:137 #, python-format @@ -994,11 +1049,11 @@ msgstr " (移除)" #: mediagoblin/templates/mediagoblin/utils/collections.html:21 msgid "Collected in" -msgstr "" +msgstr "è’集了" #: mediagoblin/templates/mediagoblin/utils/collections.html:40 msgid "Add to a collection" -msgstr "" +msgstr "åŠ å…¥è‡³è’è—" #: mediagoblin/templates/mediagoblin/utils/feed_link.html:21 #: mediagoblin/themes/airy/templates/mediagoblin/utils/feed_link.html:21 @@ -1040,7 +1095,7 @@ msgstr "更舊的" msgid "Tagged with" msgstr "標籤" -#: mediagoblin/tools/exif.py:80 +#: mediagoblin/tools/exif.py:83 msgid "Could not read the image file." msgstr "無法讀å–圖片檔案。" @@ -1070,9 +1125,33 @@ msgid "" " deleted." msgstr "ä¸å¥½æ„æ€ï¼Œçœ‹èµ·ä¾†é€™å€‹ç¶²å€ä¸Šæ²’有網é 。</p><p>å¦‚æžœæ‚¨ç¢ºå®šé€™å€‹ç¶²å€æ˜¯æ£ç¢ºçš„,您在尋找的é é¢å¯èƒ½å·²ç¶“移動或是被刪除了。" +#: mediagoblin/tools/timesince.py:62 +msgid "year" +msgstr "å¹´" + +#: mediagoblin/tools/timesince.py:63 +msgid "month" +msgstr "月" + +#: mediagoblin/tools/timesince.py:64 +msgid "week" +msgstr "週" + +#: mediagoblin/tools/timesince.py:65 +msgid "day" +msgstr "æ—¥" + +#: mediagoblin/tools/timesince.py:66 +msgid "hour" +msgstr "å°æ™‚" + +#: mediagoblin/tools/timesince.py:67 +msgid "minute" +msgstr "分" + #: mediagoblin/user_pages/forms.py:23 msgid "Comment" -msgstr "" +msgstr "留言" #: mediagoblin/user_pages/forms.py:25 msgid "" @@ -1091,7 +1170,7 @@ msgstr "我確定我è¦å¾žè’è—ä¸ç§»é™¤æ¤é …ç›®" #: mediagoblin/user_pages/forms.py:39 msgid "Collection" -msgstr "" +msgstr "è’è—" #: mediagoblin/user_pages/forms.py:40 msgid "-- Select --" @@ -1101,73 +1180,77 @@ msgstr "— è«‹é¸æ“‡ —" msgid "Include a note" msgstr "åŠ è¨»" -#: mediagoblin/user_pages/lib.py:56 +#: mediagoblin/user_pages/lib.py:58 msgid "commented on your post" -msgstr "在您的內容張貼評論" +msgstr "在您的內容張貼留言" + +#: mediagoblin/user_pages/views.py:169 +msgid "Sorry, comments are disabled." +msgstr "抱æ‰ï¼Œç•™è¨€è¢«é—œé–‰ã€‚" -#: mediagoblin/user_pages/views.py:166 +#: mediagoblin/user_pages/views.py:174 msgid "Oops, your comment was empty." msgstr "啊,您的留言是空的。" -#: mediagoblin/user_pages/views.py:172 +#: mediagoblin/user_pages/views.py:180 msgid "Your comment has been posted!" msgstr "您的留言已經張貼完æˆï¼" -#: mediagoblin/user_pages/views.py:197 +#: mediagoblin/user_pages/views.py:205 msgid "Please check your entries and try again." msgstr "è«‹æª¢æŸ¥é …ç›®ä¸¦é‡è©¦ã€‚" -#: mediagoblin/user_pages/views.py:237 +#: mediagoblin/user_pages/views.py:245 msgid "You have to select or add a collection" msgstr "您需è¦é¸æ“‡æˆ–是新增一個è’è—" -#: mediagoblin/user_pages/views.py:248 +#: mediagoblin/user_pages/views.py:256 #, python-format msgid "\"%s\" already in collection \"%s\"" msgstr "「%sã€å·²ç¶“在「%sã€è’è—" -#: mediagoblin/user_pages/views.py:264 +#: mediagoblin/user_pages/views.py:262 #, python-format msgid "\"%s\" added to collection \"%s\"" msgstr "「%sã€åŠ å…¥ã€Œ%sã€è’è—" -#: mediagoblin/user_pages/views.py:286 +#: mediagoblin/user_pages/views.py:282 msgid "You deleted the media." msgstr "您已經刪除æ¤åª’體。" -#: mediagoblin/user_pages/views.py:293 +#: mediagoblin/user_pages/views.py:289 msgid "The media was not deleted because you didn't check that you were sure." msgstr "由於您沒有勾é¸ç¢ºèªï¼Œè©²åª’體沒有被移除。" -#: mediagoblin/user_pages/views.py:301 +#: mediagoblin/user_pages/views.py:296 msgid "You are about to delete another user's media. Proceed with caution." msgstr "您æ£åœ¨åˆªé™¤åˆ¥äººçš„媒體,請å°å¿ƒæ“作。" -#: mediagoblin/user_pages/views.py:375 +#: mediagoblin/user_pages/views.py:370 msgid "You deleted the item from the collection." msgstr "您已經從該è’è—ä¸åˆªé™¤è©²é …目。" -#: mediagoblin/user_pages/views.py:379 +#: mediagoblin/user_pages/views.py:374 msgid "The item was not removed because you didn't check that you were sure." msgstr "由於您沒有勾é¸ç¢ºèªï¼Œè©²é …目沒有被移除。" -#: mediagoblin/user_pages/views.py:389 +#: mediagoblin/user_pages/views.py:382 msgid "" "You are about to delete an item from another user's collection. Proceed with" " caution." msgstr "您æ£åœ¨å¾žåˆ¥äººçš„è’è—ä¸åˆªé™¤é …目,請å°å¿ƒæ“作。" -#: mediagoblin/user_pages/views.py:422 +#: mediagoblin/user_pages/views.py:415 #, python-format msgid "You deleted the collection \"%s\"" msgstr "您已經刪除「%sã€è’è—。" -#: mediagoblin/user_pages/views.py:429 +#: mediagoblin/user_pages/views.py:422 msgid "" "The collection was not deleted because you didn't check that you were sure." msgstr "由於您沒有勾é¸ç¢ºèªï¼Œè©²è’è—æ²’有被移除。" -#: mediagoblin/user_pages/views.py:439 +#: mediagoblin/user_pages/views.py:430 msgid "" "You are about to delete another user's collection. Proceed with caution." msgstr "您æ£åœ¨åˆªé™¤åˆ¥äººçš„è’è—,請å°å¿ƒæ“作。" diff --git a/mediagoblin/init/__init__.py b/mediagoblin/init/__init__.py index d16027db..e0711416 100644 --- a/mediagoblin/init/__init__.py +++ b/mediagoblin/init/__init__.py @@ -24,6 +24,7 @@ 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, load_models +from mediagoblin.tools.pluginapi import hook_runall from mediagoblin.tools.workbench import WorkbenchManager from mediagoblin.storage import storage_system_from_config @@ -57,16 +58,20 @@ def setup_global_and_app_config(config_path): return global_config, app_config -def setup_database(): +def setup_database(run_migrations=False): app_config = mg_globals.app_config + global_config = mg_globals.global_config # Load all models for media types (plugins, ...) load_models(app_config) - # Set up the database - db = setup_connection_and_db_from_config(app_config) - - check_db_migrations_current(db) + db = setup_connection_and_db_from_config(app_config, run_migrations) + if run_migrations: + #Run the migrations to initialize/update the database. + from mediagoblin.gmg_commands.dbupdate import run_all_migrations + run_all_migrations(db, app_config, global_config) + else: + check_db_migrations_current(db) setup_globals(database=db) @@ -116,6 +121,12 @@ def get_staticdirector(app_config): direct_domains = {None: app_config['direct_remote_path'].strip()} direct_domains['theme'] = app_config['theme_web_path'].strip() + # Let plugins load additional paths + for plugin_static in hook_runall("static_setup"): + direct_domains[plugin_static.name] = "%s/%s" % ( + app_config['plugin_web_path'].rstrip('/'), + plugin_static.name) + return staticdirect.StaticDirect( direct_domains) diff --git a/mediagoblin/init/celery/__init__.py b/mediagoblin/init/celery/__init__.py index 169cc935..57242bf6 100644 --- a/mediagoblin/init/celery/__init__.py +++ b/mediagoblin/init/celery/__init__.py @@ -16,12 +16,18 @@ import os import sys +import logging from celery import Celery from mediagoblin.tools.pluginapi import hook_runall -MANDATORY_CELERY_IMPORTS = ['mediagoblin.processing.task'] +_log = logging.getLogger(__name__) + + +MANDATORY_CELERY_IMPORTS = [ + 'mediagoblin.processing.task', + 'mediagoblin.notifications.task'] DEFAULT_SETTINGS_MODULE = 'mediagoblin.init.celery.dummy_settings_module' @@ -97,3 +103,13 @@ def setup_celery_from_config(app_config, global_config, if set_environ: os.environ['CELERY_CONFIG_MODULE'] = settings_module + + # Replace the default celery.current_app.conf if celery has already been + # initiated + from celery import current_app + + _log.info('Setting celery configuration from object "{0}"'.format( + settings_module)) + current_app.config_from_object(this_module) + + _log.debug('Celery broker host: {0}'.format(current_app.conf['BROKER_HOST'])) diff --git a/mediagoblin/listings/views.py b/mediagoblin/listings/views.py index 35af7148..07dbb3d5 100644 --- a/mediagoblin/listings/views.py +++ b/mediagoblin/listings/views.py @@ -14,6 +14,7 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. +from mediagoblin import mg_globals from mediagoblin.db.models import MediaEntry from mediagoblin.db.util import media_entries_for_tag_slug from mediagoblin.tools.pagination import Pagination @@ -80,6 +81,17 @@ def atom_feed(request): link = request.urlgen('index', qualified=True) feed_title += "for all recent items" + atomlinks = [ + {'href': link, + 'rel': 'alternate', + 'type': 'text/html'}] + + if mg_globals.app_config["push_urls"]: + for push_url in mg_globals.app_config["push_urls"]: + atomlinks.append({ + 'rel': 'hub', + 'href': push_url}) + cursor = cursor.order_by(MediaEntry.created.desc()) cursor = cursor.limit(ATOM_DEFAULT_NR_OF_UPDATED_ITEMS) @@ -87,9 +99,8 @@ def atom_feed(request): feed_title, feed_url=request.url, id=link, - links=[{'href': link, - 'rel': 'alternate', - 'type': 'text/html'}]) + links=atomlinks) + for entry in cursor: feed.add(entry.get('title'), entry.description_html, diff --git a/mediagoblin/meddleware/csrf.py b/mediagoblin/meddleware/csrf.py index 661f0ba2..44d42d75 100644 --- a/mediagoblin/meddleware/csrf.py +++ b/mediagoblin/meddleware/csrf.py @@ -111,7 +111,7 @@ class CsrfMeddleware(BaseMeddleware): httponly=True) # update the Vary header - response.vary = (getattr(response, 'vary', None) or []) + ['Cookie'] + response.vary = list(getattr(response, 'vary', None) or []) + ['Cookie'] def _make_token(self, request): """Generate a new token to use for CSRF protection.""" diff --git a/mediagoblin/media_types/__init__.py b/mediagoblin/media_types/__init__.py index 20e1918e..134157dc 100644 --- a/mediagoblin/media_types/__init__.py +++ b/mediagoblin/media_types/__init__.py @@ -15,12 +15,10 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. import os -import sys import logging import tempfile -from mediagoblin import mg_globals -from mediagoblin.tools.common import import_component +from mediagoblin.tools.pluginapi import hook_handle from mediagoblin.tools.translate import lazy_pass_to_ugettext as _ _log = logging.getLogger(__name__) @@ -52,36 +50,6 @@ class MediaManagerBase(object): return hasattr(self, i) -class CompatMediaManager(object): - def __init__(self, mm_dict, entry=None): - self.mm_dict = mm_dict - self.entry = entry - - def __call__(self, entry): - "So this object can look like a class too, somehow" - assert self.entry is None - return self.__class__(self.mm_dict, entry) - - def __getitem__(self, i): - return self.mm_dict[i] - - def __contains__(self, i): - return (i in self.mm_dict) - - @property - def media_fetch_order(self): - return self.mm_dict.get('media_fetch_order') - - def sniff_handler(self, *args, **kwargs): - func = self.mm_dict.get("sniff_handler", None) - if func is not None: - return func(*args, **kwargs) - return False - - def __getattr__(self, i): - return self.mm_dict[i] - - def sniff_media(media): ''' Iterate through the enabled media types and find those suited @@ -98,40 +66,18 @@ def sniff_media(media): media_file.write(media.stream.read()) media.stream.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)) + media_type = hook_handle('sniff_handler', media_file, media=media) + if media_type: + _log.info('{0} accepts the file'.format(media_type)) + return media_type, hook_handle(('media_manager', media_type)) + 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 - """ - for media_type in mg_globals.app_config['media_types']: - yield media_type - - -def get_media_managers(): - ''' - Generator, yields all enabled media managers - ''' - for media_type in get_media_types(): - mm = import_component(media_type + ":MEDIA_MANAGER") - - if isinstance(mm, dict): - mm = CompatMediaManager(mm) - - yield media_type, mm - - def get_media_type_and_manager(filename): ''' Try to find the media type based on the file name, extension @@ -142,11 +88,10 @@ def get_media_type_and_manager(filename): # Get the file extension ext = os.path.splitext(filename)[1].lower() - 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 + # Omit the dot from the extension and match it against + # the media manager + if hook_handle('get_media_type_and_manager', ext[1:]): + return hook_handle('get_media_type_and_manager', ext[1:]) else: _log.info('File {0} has no file extension, let\'s hope the sniffers get it.'.format( filename)) diff --git a/mediagoblin/media_types/ascii/__init__.py b/mediagoblin/media_types/ascii/__init__.py index 0931e83a..4baf8dd3 100644 --- a/mediagoblin/media_types/ascii/__init__.py +++ b/mediagoblin/media_types/ascii/__init__.py @@ -17,15 +17,31 @@ from mediagoblin.media_types import MediaManagerBase from mediagoblin.media_types.ascii.processing import process_ascii, \ sniff_handler +from mediagoblin.tools import pluginapi + +ACCEPTED_EXTENSIONS = ["txt", "asc", "nfo"] +MEDIA_TYPE = 'mediagoblin.media_types.ascii' + + +def setup_plugin(): + config = pluginapi.get_config(MEDIA_TYPE) class ASCIIMediaManager(MediaManagerBase): human_readable = "ASCII" processor = staticmethod(process_ascii) - sniff_handler = staticmethod(sniff_handler) display_template = "mediagoblin/media_displays/ascii.html" default_thumb = "images/media_thumbs/ascii.jpg" - accepted_extensions = ["txt", "asc", "nfo"] - -MEDIA_MANAGER = ASCIIMediaManager + +def get_media_type_and_manager(ext): + if ext in ACCEPTED_EXTENSIONS: + return MEDIA_TYPE, ASCIIMediaManager + + +hooks = { + 'setup': setup_plugin, + 'get_media_type_and_manager': get_media_type_and_manager, + ('media_manager', MEDIA_TYPE): lambda: ASCIIMediaManager, + 'sniff_handler': sniff_handler, +} diff --git a/mediagoblin/media_types/ascii/processing.py b/mediagoblin/media_types/ascii/processing.py index 2f6079be..aca784e8 100644 --- a/mediagoblin/media_types/ascii/processing.py +++ b/mediagoblin/media_types/ascii/processing.py @@ -28,17 +28,19 @@ from mediagoblin.media_types.ascii import asciitoimage _log = logging.getLogger(__name__) SUPPORTED_EXTENSIONS = ['txt', 'asc', 'nfo'] +MEDIA_TYPE = 'mediagoblin.media_types.ascii' def sniff_handler(media_file, **kw): + _log.info('Sniffing {0}'.format(MEDIA_TYPE)) 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 MEDIA_TYPE - return False + return None def process_ascii(proc_state): diff --git a/mediagoblin/media_types/audio/__init__.py b/mediagoblin/media_types/audio/__init__.py index 2eb7300e..c7ed8d2d 100644 --- a/mediagoblin/media_types/audio/__init__.py +++ b/mediagoblin/media_types/audio/__init__.py @@ -17,14 +17,32 @@ from mediagoblin.media_types import MediaManagerBase from mediagoblin.media_types.audio.processing import process_audio, \ sniff_handler +from mediagoblin.tools import pluginapi + +# Why isn't .ogg in this list? It's still detected, but via sniffing, +# .ogg files could be either video or audio... sniffing determines which. + +ACCEPTED_EXTENSIONS = ["mp3", "flac", "wav", "m4a"] +MEDIA_TYPE = 'mediagoblin.media_types.audio' + + +def setup_plugin(): + config = pluginapi.get_config(MEDIA_TYPE) class AudioMediaManager(MediaManagerBase): human_readable = "Audio" processor = staticmethod(process_audio) - sniff_handler = staticmethod(sniff_handler) display_template = "mediagoblin/media_displays/audio.html" - accepted_extensions = ["mp3", "flac", "wav", "m4a"] -MEDIA_MANAGER = AudioMediaManager +def get_media_type_and_manager(ext): + if ext in ACCEPTED_EXTENSIONS: + return MEDIA_TYPE, AudioMediaManager + +hooks = { + 'setup': setup_plugin, + 'get_media_type_and_manager': get_media_type_and_manager, + 'sniff_handler': sniff_handler, + ('media_manager', MEDIA_TYPE): lambda: AudioMediaManager, +} diff --git a/mediagoblin/media_types/audio/processing.py b/mediagoblin/media_types/audio/processing.py index 101b83e5..22383bc1 100644 --- a/mediagoblin/media_types/audio/processing.py +++ b/mediagoblin/media_types/audio/processing.py @@ -27,19 +27,22 @@ from mediagoblin.media_types.audio.transcoders import (AudioTranscoder, _log = logging.getLogger(__name__) +MEDIA_TYPE = 'mediagoblin.media_types.audio' + def sniff_handler(media_file, **kw): + _log.info('Sniffing {0}'.format(MEDIA_TYPE)) try: transcoder = AudioTranscoder() data = transcoder.discover(media_file.name) except BadMediaFail: _log.debug('Audio discovery raised BadMediaFail') - return False + return None if data.is_audio == True and data.is_video == False: - return True + return MEDIA_TYPE - return False + return None def process_audio(proc_state): diff --git a/mediagoblin/media_types/image/__init__.py b/mediagoblin/media_types/image/__init__.py index 5130ef48..1bb9c6f3 100644 --- a/mediagoblin/media_types/image/__init__.py +++ b/mediagoblin/media_types/image/__init__.py @@ -13,23 +13,30 @@ # # 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 datetime from mediagoblin.media_types import MediaManagerBase from mediagoblin.media_types.image.processing import process_image, \ sniff_handler +from mediagoblin.tools import pluginapi + + +ACCEPTED_EXTENSIONS = ["jpg", "jpeg", "png", "gif", "tiff"] +MEDIA_TYPE = 'mediagoblin.media_types.image' + + +def setup_plugin(): + config = pluginapi.get_config('mediagoblin.media_types.image') class ImageMediaManager(MediaManagerBase): human_readable = "Image" processor = staticmethod(process_image) - sniff_handler = staticmethod(sniff_handler) display_template = "mediagoblin/media_displays/image.html" default_thumb = "images/media_thumbs/image.png" - accepted_extensions = ["jpg", "jpeg", "png", "gif", "tiff"] + media_fetch_order = [u'medium', u'original', u'thumb'] - + def get_original_date(self): """ Get the original date and time from the EXIF information. Returns @@ -52,4 +59,14 @@ class ImageMediaManager(MediaManagerBase): return None -MEDIA_MANAGER = ImageMediaManager +def get_media_type_and_manager(ext): + if ext in ACCEPTED_EXTENSIONS: + return MEDIA_TYPE, ImageMediaManager + + +hooks = { + 'setup': setup_plugin, + 'get_media_type_and_manager': get_media_type_and_manager, + 'sniff_handler': sniff_handler, + ('media_manager', MEDIA_TYPE): lambda: ImageMediaManager, +} diff --git a/mediagoblin/media_types/image/processing.py b/mediagoblin/media_types/image/processing.py index bc0ce3f8..baf2ac7e 100644 --- a/mediagoblin/media_types/image/processing.py +++ b/mediagoblin/media_types/image/processing.py @@ -35,6 +35,8 @@ PIL_FILTERS = { 'BICUBIC': Image.BICUBIC, 'ANTIALIAS': Image.ANTIALIAS} +MEDIA_TYPE = 'mediagoblin.media_types.image' + def resize_image(proc_state, resized, keyname, target_name, new_size, exif_tags, workdir): @@ -95,17 +97,18 @@ def resize_tool(proc_state, force, keyname, target_name, exif_tags, conversions_subdir) -SUPPORTED_FILETYPES = ['png', 'gif', 'jpg', 'jpeg'] +SUPPORTED_FILETYPES = ['png', 'gif', 'jpg', 'jpeg', 'tiff'] def sniff_handler(media_file, **kw): + _log.info('Sniffing {0}'.format(MEDIA_TYPE)) 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 if clean_ext in SUPPORTED_FILETYPES: _log.info('Found file extension in supported filetypes') - return True + return MEDIA_TYPE else: _log.debug('Media present, extension not found in {0}'.format( SUPPORTED_FILETYPES)) @@ -113,7 +116,7 @@ def sniff_handler(media_file, **kw): _log.warning('Need additional information (keyword argument \'media\')' ' to be able to handle sniffing') - return False + return None def process_image(proc_state): diff --git a/mediagoblin/media_types/pdf/__init__.py b/mediagoblin/media_types/pdf/__init__.py index f0ba7867..67509ddc 100644 --- a/mediagoblin/media_types/pdf/__init__.py +++ b/mediagoblin/media_types/pdf/__init__.py @@ -17,15 +17,31 @@ from mediagoblin.media_types import MediaManagerBase from mediagoblin.media_types.pdf.processing import process_pdf, \ sniff_handler +from mediagoblin.tools import pluginapi + +ACCEPTED_EXTENSIONS = ['pdf'] +MEDIA_TYPE = 'mediagoblin.media_types.pdf' + + +def setup_plugin(): + config = pluginapi.get_config(MEDIA_TYPE) class PDFMediaManager(MediaManagerBase): human_readable = "PDF" processor = staticmethod(process_pdf) - sniff_handler = staticmethod(sniff_handler) display_template = "mediagoblin/media_displays/pdf.html" default_thumb = "images/media_thumbs/pdf.jpg" - accepted_extensions = ["pdf"] -MEDIA_MANAGER = PDFMediaManager +def get_media_type_and_manager(ext): + if ext in ACCEPTED_EXTENSIONS: + return MEDIA_TYPE, PDFMediaManager + + +hooks = { + 'setup': setup_plugin, + 'get_media_type_and_manager': get_media_type_and_manager, + 'sniff_handler': sniff_handler, + ('media_manager', MEDIA_TYPE): lambda: PDFMediaManager, +} diff --git a/mediagoblin/media_types/pdf/processing.py b/mediagoblin/media_types/pdf/processing.py index 49742fd7..f35b4376 100644 --- a/mediagoblin/media_types/pdf/processing.py +++ b/mediagoblin/media_types/pdf/processing.py @@ -25,6 +25,8 @@ from mediagoblin.tools.translate import fake_ugettext_passthrough as _ _log = logging.getLogger(__name__) +MEDIA_TYPE = 'mediagoblin.media_types.pdf' + # TODO - cache (memoize) util # This is a list created via uniconv --show and hand removing some types that @@ -163,16 +165,17 @@ def check_prerequisites(): return True def sniff_handler(media_file, **kw): + _log.info('Sniffing {0}'.format(MEDIA_TYPE)) if not check_prerequisites(): - return False + return None 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 MEDIA_TYPE - return False + return None def create_pdf_thumb(original, thumb_filename, width, height): # Note: pdftocairo adds '.png', remove it @@ -250,8 +253,8 @@ def process_pdf(proc_state): else: pdf_filename = queued_filename.rsplit('.', 1)[0] + '.pdf' unoconv = where('unoconv') - call(executable=unoconv, - args=[unoconv, '-v', '-f', 'pdf', queued_filename]) + Popen(executable=unoconv, + args=[unoconv, '-v', '-f', 'pdf', queued_filename]).wait() if not os.path.exists(pdf_filename): _log.debug('unoconv failed to convert file to pdf') raise BadMediaFail() diff --git a/mediagoblin/media_types/stl/__init__.py b/mediagoblin/media_types/stl/__init__.py index 6ae8a8b9..1d2a8478 100644 --- a/mediagoblin/media_types/stl/__init__.py +++ b/mediagoblin/media_types/stl/__init__.py @@ -17,15 +17,30 @@ from mediagoblin.media_types import MediaManagerBase from mediagoblin.media_types.stl.processing import process_stl, \ sniff_handler +from mediagoblin.tools import pluginapi + +MEDIA_TYPE = 'mediagoblin.media_types.stl' +ACCEPTED_EXTENSIONS = ["obj", "stl"] + + +def setup_plugin(): + config = pluginapi.get_config(MEDIA_TYPE) class STLMediaManager(MediaManagerBase): human_readable = "stereo lithographics" processor = staticmethod(process_stl) - sniff_handler = staticmethod(sniff_handler) display_template = "mediagoblin/media_displays/stl.html" default_thumb = "images/media_thumbs/video.jpg" - accepted_extensions = ["obj", "stl"] -MEDIA_MANAGER = STLMediaManager +def get_media_type_and_manager(ext): + if ext in ACCEPTED_EXTENSIONS: + return MEDIA_TYPE, STLMediaManager + +hooks = { + 'setup': setup_plugin, + 'get_media_type_and_manager': get_media_type_and_manager, + 'sniff_handler': sniff_handler, + ('media_manager', MEDIA_TYPE): lambda: STLMediaManager, +} diff --git a/mediagoblin/media_types/stl/processing.py b/mediagoblin/media_types/stl/processing.py index 49382495..53751416 100644 --- a/mediagoblin/media_types/stl/processing.py +++ b/mediagoblin/media_types/stl/processing.py @@ -29,6 +29,7 @@ from mediagoblin.media_types.stl import model_loader _log = logging.getLogger(__name__) SUPPORTED_FILETYPES = ['stl', 'obj'] +MEDIA_TYPE = 'mediagoblin.media_types.stl' BLEND_FILE = pkg_resources.resource_filename( 'mediagoblin.media_types.stl', @@ -43,13 +44,14 @@ BLEND_SCRIPT = pkg_resources.resource_filename( def sniff_handler(media_file, **kw): + _log.info('Sniffing {0}'.format(MEDIA_TYPE)) if kw.get('media') is not None: name, ext = os.path.splitext(kw['media'].filename) clean_ext = ext[1:].lower() - + if clean_ext in SUPPORTED_FILETYPES: _log.info('Found file extension in supported filetypes') - return True + return MEDIA_TYPE else: _log.debug('Media present, extension not found in {0}'.format( SUPPORTED_FILETYPES)) @@ -57,7 +59,7 @@ def sniff_handler(media_file, **kw): _log.warning('Need additional information (keyword argument \'media\')' ' to be able to handle sniffing') - return False + return None def blender_render(config): diff --git a/mediagoblin/media_types/tools.py b/mediagoblin/media_types/tools.py new file mode 100644 index 00000000..fe7b3772 --- /dev/null +++ b/mediagoblin/media_types/tools.py @@ -0,0 +1,27 @@ +# 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 + +_log = logging.getLogger(__name__) + + +def media_type_warning(): + if mg_globals.app_config.get('media_types'): + _log.warning('Media_types have been converted to plugins. Old' + ' media_types will no longer work. Please convert them' + ' to plugins to continue using them.') diff --git a/mediagoblin/media_types/video/__init__.py b/mediagoblin/media_types/video/__init__.py index 569cf11a..e8a4308b 100644 --- a/mediagoblin/media_types/video/__init__.py +++ b/mediagoblin/media_types/video/__init__.py @@ -17,20 +17,35 @@ from mediagoblin.media_types import MediaManagerBase from mediagoblin.media_types.video.processing import process_video, \ sniff_handler +from mediagoblin.tools import pluginapi + +MEDIA_TYPE = 'mediagoblin.media_types.video' +ACCEPTED_EXTENSIONS = [ + "mp4", "mov", "webm", "avi", "3gp", "3gpp", "mkv", "ogv", "m4v"] + + +def setup_plugin(): + config = pluginapi.get_config(MEDIA_TYPE) class VideoMediaManager(MediaManagerBase): human_readable = "Video" processor = staticmethod(process_video) - sniff_handler = staticmethod(sniff_handler) display_template = "mediagoblin/media_displays/video.html" default_thumb = "images/media_thumbs/video.jpg" - accepted_extensions = [ - "mp4", "mov", "webm", "avi", "3gp", "3gpp", "mkv", "ogv", "m4v"] - + # Used by the media_entry.get_display_media method media_fetch_order = [u'webm_640', u'original'] default_webm_type = 'video/webm; codecs="vp8, vorbis"' -MEDIA_MANAGER = VideoMediaManager +def get_media_type_and_manager(ext): + if ext in ACCEPTED_EXTENSIONS: + return MEDIA_TYPE, VideoMediaManager + +hooks = { + 'setup': setup_plugin, + 'get_media_type_and_manager': get_media_type_and_manager, + 'sniff_handler': sniff_handler, + ('media_manager', MEDIA_TYPE): lambda: VideoMediaManager, +} diff --git a/mediagoblin/media_types/video/processing.py b/mediagoblin/media_types/video/processing.py index ff2c94a0..5386ba60 100644 --- a/mediagoblin/media_types/video/processing.py +++ b/mediagoblin/media_types/video/processing.py @@ -29,6 +29,8 @@ from .util import skip_transcode _log = logging.getLogger(__name__) _log.setLevel(logging.DEBUG) +MEDIA_TYPE = 'mediagoblin.media_types.video' + class VideoTranscodingFail(BaseProcessingFail): ''' @@ -41,17 +43,18 @@ def sniff_handler(media_file, **kw): transcoder = transcoders.VideoTranscoder() data = transcoder.discover(media_file.name) + _log.info('Sniffing {0}'.format(MEDIA_TYPE)) _log.debug('Discovered: {0}'.format(data)) if not data: _log.error('Could not discover {0}'.format( kw.get('media'))) - return False + return None if data['is_video'] == True: - return True + return MEDIA_TYPE - return False + return None def process_video(proc_state): @@ -186,7 +189,7 @@ def store_metadata(media_entry, metadata): [(key, tags_metadata[key]) for key in [ "application-name", "artist", "audio-codec", "bitrate", - "container-format", "copyright", "encoder", + "container-format", "copyright", "encoder", "encoder-version", "license", "nominal-bitrate", "title", "video-codec"] if key in tags_metadata]) @@ -203,7 +206,7 @@ def store_metadata(media_entry, metadata): dt.get_year(), dt.get_month(), dt.get_day(), dt.get_hour(), dt.get_minute(), dt.get_second(), dt.get_microsecond()).isoformat() - + metadata['tags'] = tags # Only save this field if there's something to save diff --git a/mediagoblin/media_types/video/transcoders.py b/mediagoblin/media_types/video/transcoders.py index 90a767dd..9d6b7655 100644 --- a/mediagoblin/media_types/video/transcoders.py +++ b/mediagoblin/media_types/video/transcoders.py @@ -22,9 +22,15 @@ import logging import urllib import multiprocessing import gobject + +old_argv = sys.argv +sys.argv = [] + import pygst pygst.require('0.10') import gst + +sys.argv = old_argv import struct try: from PIL import Image diff --git a/mediagoblin/notifications/__init__.py b/mediagoblin/notifications/__init__.py new file mode 100644 index 00000000..4b7fbb8c --- /dev/null +++ b/mediagoblin/notifications/__init__.py @@ -0,0 +1,141 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +import logging + +from mediagoblin.db.models import Notification, \ + CommentNotification, CommentSubscription +from mediagoblin.notifications.task import email_notification_task +from mediagoblin.notifications.tools import generate_comment_message + +_log = logging.getLogger(__name__) + +def trigger_notification(comment, media_entry, request): + ''' + Send out notifications about a new comment. + ''' + subscriptions = CommentSubscription.query.filter_by( + media_entry_id=media_entry.id).all() + + for subscription in subscriptions: + if not subscription.notify: + continue + + if comment.get_author == subscription.user: + continue + + cn = CommentNotification( + user_id=subscription.user_id, + subject_id=comment.id) + + cn.save() + + if subscription.send_email: + message = generate_comment_message( + subscription.user, + comment, + media_entry, + request) + + email_notification_task.apply_async([cn.id, message]) + + +def mark_notification_seen(notification): + if notification: + notification.seen = True + notification.save() + + +def mark_comment_notification_seen(comment_id, user): + notification = CommentNotification.query.filter_by( + user_id=user.id, + subject_id=comment_id).first() + + _log.debug('Marking {0} as seen.'.format(notification)) + + mark_notification_seen(notification) + + +def get_comment_subscription(user_id, media_entry_id): + return CommentSubscription.query.filter_by( + user_id=user_id, + media_entry_id=media_entry_id).first() + +def add_comment_subscription(user, media_entry): + ''' + Create a comment subscription for a User on a MediaEntry. + + Uses the User's wants_comment_notification to set email notifications for + the subscription to enabled/disabled. + ''' + cn = get_comment_subscription(user.id, media_entry.id) + + if not cn: + cn = CommentSubscription( + user_id=user.id, + media_entry_id=media_entry.id) + + cn.notify = True + + if not user.wants_comment_notification: + cn.send_email = False + + cn.save() + + +def silence_comment_subscription(user, media_entry): + ''' + Silence a subscription so that the user is never notified in any way about + new comments on an entry + ''' + cn = get_comment_subscription(user.id, media_entry.id) + + if cn: + cn.notify = False + cn.send_email = False + cn.save() + + +def remove_comment_subscription(user, media_entry): + cn = get_comment_subscription(user.id, media_entry.id) + + if cn: + cn.delete() + + +NOTIFICATION_FETCH_LIMIT = 100 + + +def get_notifications(user_id, only_unseen=True): + query = Notification.query.filter_by(user_id=user_id) + + if only_unseen: + query = query.filter_by(seen=False) + + notifications = query.limit( + NOTIFICATION_FETCH_LIMIT).all() + + return notifications + +def get_notification_count(user_id, only_unseen=True): + query = Notification.query.filter_by(user_id=user_id) + + if only_unseen: + query = query.filter_by(seen=False) + + count = query.count() + + return count diff --git a/mediagoblin/notifications/routing.py b/mediagoblin/notifications/routing.py new file mode 100644 index 00000000..e57956d3 --- /dev/null +++ b/mediagoblin/notifications/routing.py @@ -0,0 +1,25 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +from mediagoblin.tools.routing import add_route + +add_route('mediagoblin.notifications.subscribe_comments', + '/u/<string:user>/m/<string:media>/notifications/subscribe/comments/', + 'mediagoblin.notifications.views:subscribe_comments') + +add_route('mediagoblin.notifications.silence_comments', + '/u/<string:user>/m/<string:media>/notifications/silence/', + 'mediagoblin.notifications.views:silence_comments') diff --git a/mediagoblin/notifications/task.py b/mediagoblin/notifications/task.py new file mode 100644 index 00000000..52573b57 --- /dev/null +++ b/mediagoblin/notifications/task.py @@ -0,0 +1,46 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +import logging + +from celery import registry +from celery.task import Task + +from mediagoblin.tools.mail import send_email +from mediagoblin.db.models import CommentNotification + + +_log = logging.getLogger(__name__) + + +class EmailNotificationTask(Task): + ''' + Celery notification task. + + This task is executed by celeryd to offload long-running operations from + the web server. + ''' + def run(self, notification_id, message): + cn = CommentNotification.query.filter_by(id=notification_id).first() + _log.info('Sending notification email about {0}'.format(cn)) + + return send_email( + message['from'], + [message['to']], + message['subject'], + message['body']) + +email_notification_task = registry.tasks[EmailNotificationTask.name] diff --git a/mediagoblin/notifications/tools.py b/mediagoblin/notifications/tools.py new file mode 100644 index 00000000..25432780 --- /dev/null +++ b/mediagoblin/notifications/tools.py @@ -0,0 +1,55 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +from mediagoblin.tools.template import render_template +from mediagoblin.tools.translate import pass_to_ugettext as _ +from mediagoblin import mg_globals + +def generate_comment_message(user, comment, media, request): + """ + Sends comment email to user when a comment is made on their media. + + Args: + - user: the user object to whom the email is sent + - comment: the comment object referencing user's media + - media: the media object the comment is about + - request: the request + """ + + comment_url = request.urlgen( + 'mediagoblin.user_pages.media_home.view_comment', + comment=comment.id, + user=media.get_uploader.username, + media=media.slug_or_id, + qualified=True) + '#comment' + + comment_author = comment.get_author.username + + rendered_email = render_template( + request, 'mediagoblin/user_pages/comment_email.txt', + {'username': user.username, + 'comment_author': comment_author, + 'comment_content': comment.content, + 'comment_url': comment_url}) + + return { + 'from': mg_globals.app_config['email_sender_address'], + 'to': user.email, + 'subject': '{instance_title} - {comment_author} '.format( + comment_author=comment_author, + instance_title=mg_globals.app_config['html_title']) \ + + _('commented on your post'), + 'body': rendered_email} diff --git a/mediagoblin/notifications/views.py b/mediagoblin/notifications/views.py new file mode 100644 index 00000000..d275bc92 --- /dev/null +++ b/mediagoblin/notifications/views.py @@ -0,0 +1,54 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +from mediagoblin.tools.response import render_to_response, render_404, redirect +from mediagoblin.tools.translate import pass_to_ugettext as _ +from mediagoblin.decorators import (uses_pagination, get_user_media_entry, + get_media_entry_by_id, + require_active_login, user_may_delete_media, user_may_alter_collection, + get_user_collection, get_user_collection_item, active_user_from_url) + +from mediagoblin import messages + +from mediagoblin.notifications import add_comment_subscription, \ + silence_comment_subscription + +from werkzeug.exceptions import BadRequest + +@get_user_media_entry +@require_active_login +def subscribe_comments(request, media): + + add_comment_subscription(request.user, media) + + messages.add_message(request, + messages.SUCCESS, + _('Subscribed to comments on %s!') + % media.title) + + return redirect(request, location=media.url_for_self(request.urlgen)) + +@get_user_media_entry +@require_active_login +def silence_comments(request, media): + silence_comment_subscription(request.user, media) + + messages.add_message(request, + messages.SUCCESS, + _('You will not receive notifications for comments on' + ' %s.') % media.title) + + return redirect(request, location=media.url_for_self(request.urlgen)) diff --git a/mediagoblin/plugins/api/views.py b/mediagoblin/plugins/api/views.py index fde76fe4..9159fe65 100644 --- a/mediagoblin/plugins/api/views.py +++ b/mediagoblin/plugins/api/views.py @@ -27,7 +27,7 @@ from mediagoblin.media_types import sniff_media from mediagoblin.plugins.api.tools import api_auth, get_entry_serializable, \ json_response from mediagoblin.submit.lib import check_file_field, prepare_queue_task, \ - run_process_media + run_process_media, new_upload_entry _log = logging.getLogger(__name__) @@ -53,7 +53,7 @@ def post_entry(request): media_type, media_manager = sniff_media(media_file) - entry = request.db.MediaEntry() + entry = new_upload_entry(request.user) entry.media_type = unicode(media_type) entry.title = unicode(request.form.get('title') or splitext(media_file.filename)[0]) @@ -61,8 +61,6 @@ def post_entry(request): entry.description = unicode(request.form.get('description')) entry.license = unicode(request.form.get('license', '')) - entry.uploader = request.user.id - entry.generate_slug() # queue appropriately diff --git a/mediagoblin/plugins/basic_auth/__init__.py b/mediagoblin/plugins/basic_auth/__init__.py new file mode 100644 index 00000000..33a554b0 --- /dev/null +++ b/mediagoblin/plugins/basic_auth/__init__.py @@ -0,0 +1,88 @@ +# 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.plugins.basic_auth import forms as auth_forms +from mediagoblin.plugins.basic_auth import tools as auth_tools +from mediagoblin.auth.tools import create_basic_user +from mediagoblin.db.models import User +from mediagoblin.tools import pluginapi +from sqlalchemy import or_ + + +def setup_plugin(): + config = pluginapi.get_config('mediagoblin.plugins.basic_auth') + + +def get_user(**kwargs): + username = kwargs.pop('username', None) + if username: + user = User.query.filter( + or_( + User.username == username, + User.email == username, + )).first() + return user + + +def create_user(registration_form): + user = get_user(username=registration_form.username.data) + if not user and 'password' in registration_form: + user = create_basic_user(registration_form) + user.pw_hash = gen_password_hash( + registration_form.password.data) + user.save() + return user + + +def get_login_form(request): + return auth_forms.LoginForm(request.form) + + +def get_registration_form(request): + return auth_forms.RegistrationForm(request.form) + + +def gen_password_hash(raw_pass, extra_salt=None): + return auth_tools.bcrypt_gen_password_hash(raw_pass, extra_salt) + + +def check_password(raw_pass, stored_hash, extra_salt=None): + if stored_hash: + return auth_tools.bcrypt_check_password(raw_pass, + stored_hash, extra_salt) + return None + + +def auth(): + return True + + +def append_to_global_context(context): + context['pass_auth'] = True + return context + + +hooks = { + 'setup': setup_plugin, + 'authentication': auth, + 'auth_get_user': get_user, + 'auth_create_user': create_user, + 'auth_get_login_form': get_login_form, + 'auth_get_registration_form': get_registration_form, + 'auth_gen_password_hash': gen_password_hash, + 'auth_check_password': check_password, + 'auth_fake_login_attempt': auth_tools.fake_login_attempt, + 'template_global_context': append_to_global_context, +} diff --git a/mediagoblin/plugins/basic_auth/forms.py b/mediagoblin/plugins/basic_auth/forms.py new file mode 100644 index 00000000..6cf01b38 --- /dev/null +++ b/mediagoblin/plugins/basic_auth/forms.py @@ -0,0 +1,46 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +import wtforms + +from mediagoblin.tools.translate import lazy_pass_to_ugettext as _ +from mediagoblin.auth.tools import normalize_user_or_email_field + + +class RegistrationForm(wtforms.Form): + username = wtforms.TextField( + _('Username'), + [wtforms.validators.Required(), + normalize_user_or_email_field(allow_email=False)]) + password = wtforms.PasswordField( + _('Password'), + [wtforms.validators.Required(), + wtforms.validators.Length(min=5, max=1024)]) + email = wtforms.TextField( + _('Email address'), + [wtforms.validators.Required(), + normalize_user_or_email_field(allow_user=False)]) + + +class LoginForm(wtforms.Form): + username = wtforms.TextField( + _('Username or Email'), + [wtforms.validators.Required(), + normalize_user_or_email_field()]) + password = wtforms.PasswordField( + _('Password')) + stay_logged_in = wtforms.BooleanField( + label='', + description=_('Stay logged in')) diff --git a/mediagoblin/auth/lib.py b/mediagoblin/plugins/basic_auth/tools.py index 8829995a..1300bb9a 100644 --- a/mediagoblin/auth/lib.py +++ b/mediagoblin/plugins/basic_auth/tools.py @@ -13,14 +13,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 random - import bcrypt - -from mediagoblin.tools.mail import send_email -from mediagoblin.tools.template import render_template -from mediagoblin import mg_globals +import random def bcrypt_check_password(raw_pass, stored_hash, extra_salt=None): @@ -88,68 +82,3 @@ def fake_login_attempt(): randplus_hashed_pass = bcrypt.hashpw(hashed_pass, rand_salt) randplus_stored_hash == randplus_hashed_pass - - -EMAIL_VERIFICATION_TEMPLATE = ( - u"http://{host}{uri}?" - u"userid={userid}&token={verification_key}") - - -def send_verification_email(user, request): - """ - Send the verification email to users to activate their accounts. - - Args: - - user: a user object - - request: the request - """ - rendered_email = render_template( - request, 'mediagoblin/auth/verification_email.txt', - {'username': user.username, - 'verification_url': EMAIL_VERIFICATION_TEMPLATE.format( - host=request.host, - uri=request.urlgen('mediagoblin.auth.verify_email'), - userid=unicode(user.id), - verification_key=user.verification_key)}) - - # TODO: There is no error handling in place - send_email( - mg_globals.app_config['email_sender_address'], - [user.email], - # TODO - # Due to the distributed nature of GNU MediaGoblin, we should - # find a way to send some additional information about the - # specific GNU MediaGoblin instance in the subject line. For - # example "GNU MediaGoblin @ Wandborg - [...]". - 'GNU MediaGoblin - Verify your email!', - rendered_email) - - -EMAIL_FP_VERIFICATION_TEMPLATE = ( - u"http://{host}{uri}?" - u"userid={userid}&token={fp_verification_key}") - - -def send_fp_verification_email(user, request): - """ - Send the verification email to users to change their password. - - Args: - - user: a user object - - request: the request - """ - rendered_email = render_template( - request, 'mediagoblin/auth/fp_verification_email.txt', - {'username': user.username, - 'verification_url': EMAIL_FP_VERIFICATION_TEMPLATE.format( - host=request.host, - uri=request.urlgen('mediagoblin.auth.verify_forgot_password'), - userid=unicode(user.id), - fp_verification_key=user.fp_verification_key)}) - - # TODO: There is no error handling in place - send_email( - mg_globals.app_config['email_sender_address'], - [user.email], - 'GNU MediaGoblin - Change forgotten password!', - rendered_email) diff --git a/mediagoblin/plugins/httpapiauth/__init__.py b/mediagoblin/plugins/httpapiauth/__init__.py index 99b6a4b0..2b2d593c 100644 --- a/mediagoblin/plugins/httpapiauth/__init__.py +++ b/mediagoblin/plugins/httpapiauth/__init__.py @@ -18,6 +18,7 @@ import logging from werkzeug.exceptions import Unauthorized +from mediagoblin.auth.tools import check_login_simple from mediagoblin.plugins.api.tools import Auth _log = logging.getLogger(__name__) @@ -39,10 +40,10 @@ class HTTPAuth(Auth): if not request.authorization: return False - user = request.db.User.query.filter_by( - username=unicode(request.authorization['username'])).first() + user = check_login_simple(unicode(request.authorization['username']), + request.authorization['password']) - if user.check_login(request.authorization['password']): + if user: request.user = user return True else: diff --git a/mediagoblin/plugins/openid/__init__.py b/mediagoblin/plugins/openid/__init__.py new file mode 100644 index 00000000..ee88808c --- /dev/null +++ b/mediagoblin/plugins/openid/__init__.py @@ -0,0 +1,123 @@ +# 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 os +import uuid + +from sqlalchemy import or_ + +from mediagoblin.auth.tools import create_basic_user +from mediagoblin.db.models import User +from mediagoblin.plugins.openid.models import OpenIDUserURL +from mediagoblin.tools import pluginapi +from mediagoblin.tools.translate import lazy_pass_to_ugettext as _ + +PLUGIN_DIR = os.path.dirname(__file__) + + +def setup_plugin(): + config = pluginapi.get_config('mediagoblin.plugins.openid') + + routes = [ + ('mediagoblin.plugins.openid.register', + '/auth/openid/register/', + 'mediagoblin.plugins.openid.views:register'), + ('mediagoblin.plugins.openid.login', + '/auth/openid/login/', + 'mediagoblin.plugins.openid.views:login'), + ('mediagoblin.plugins.openid.finish_login', + '/auth/openid/login/finish/', + 'mediagoblin.plugins.openid.views:finish_login'), + ('mediagoblin.plugins.openid.edit', + '/edit/openid/', + 'mediagoblin.plugins.openid.views:start_edit'), + ('mediagoblin.plugins.openid.finish_edit', + '/edit/openid/finish/', + 'mediagoblin.plugins.openid.views:finish_edit'), + ('mediagoblin.plugins.openid.delete', + '/edit/openid/delete/', + 'mediagoblin.plugins.openid.views:delete_openid'), + ('mediagoblin.plugins.openid.finish_delete', + '/edit/openid/delete/finish/', + 'mediagoblin.plugins.openid.views:finish_delete')] + + pluginapi.register_routes(routes) + pluginapi.register_template_path(os.path.join(PLUGIN_DIR, 'templates')) + + pluginapi.register_template_hooks( + {'register_link': 'mediagoblin/plugins/openid/register_link.html', + 'login_link': 'mediagoblin/plugins/openid/login_link.html', + 'edit_link': 'mediagoblin/plugins/openid/edit_link.html'}) + + +def create_user(register_form): + if 'openid' in register_form: + username = register_form.username.data + user = User.query.filter( + or_( + User.username == username, + User.email == username, + )).first() + + if not user: + user = create_basic_user(register_form) + + new_entry = OpenIDUserURL() + new_entry.openid_url = register_form.openid.data + new_entry.user_id = user.id + new_entry.save() + + return user + + +def extra_validation(register_form): + openid = register_form.openid.data if 'openid' in \ + register_form else None + if openid: + openid_url_exists = OpenIDUserURL.query.filter_by( + openid_url=openid + ).count() + + extra_validation_passes = True + + if openid_url_exists: + register_form.openid.errors.append( + _('Sorry, an account is already registered to that OpenID.')) + extra_validation_passes = False + + return extra_validation_passes + + +def no_pass_redirect(): + return 'openid' + + +def add_to_form_context(context): + context['openid_link'] = True + return context + + +def Auth(): + return True + +hooks = { + 'setup': setup_plugin, + 'authentication': Auth, + 'auth_extra_validation': extra_validation, + 'auth_create_user': create_user, + 'auth_no_pass_redirect': no_pass_redirect, + ('mediagoblin.auth.register', + 'mediagoblin/auth/register.html'): add_to_form_context, +} diff --git a/mediagoblin/plugins/openid/forms.py b/mediagoblin/plugins/openid/forms.py new file mode 100644 index 00000000..f26024bd --- /dev/null +++ b/mediagoblin/plugins/openid/forms.py @@ -0,0 +1,41 @@ +# 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 wtforms + +from mediagoblin.tools.translate import lazy_pass_to_ugettext as _ +from mediagoblin.auth.tools import normalize_user_or_email_field + + +class RegistrationForm(wtforms.Form): + openid = wtforms.HiddenField( + '', + [wtforms.validators.Required()]) + username = wtforms.TextField( + _('Username'), + [wtforms.validators.Required(), + normalize_user_or_email_field(allow_email=False)]) + email = wtforms.TextField( + _('Email address'), + [wtforms.validators.Required(), + normalize_user_or_email_field(allow_user=False)]) + + +class LoginForm(wtforms.Form): + openid = wtforms.TextField( + _('OpenID'), + [wtforms.validators.Required(), + # Can openid's only be urls? + wtforms.validators.URL(message='Please enter a valid url.')]) diff --git a/mediagoblin/plugins/openid/models.py b/mediagoblin/plugins/openid/models.py new file mode 100644 index 00000000..6773f0ad --- /dev/null +++ b/mediagoblin/plugins/openid/models.py @@ -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/>. +from sqlalchemy import Column, Integer, Unicode, ForeignKey +from sqlalchemy.orm import relationship, backref + +from mediagoblin.db.models import User +from mediagoblin.db.base import Base + + +class OpenIDUserURL(Base): + __tablename__ = "openid__user_urls" + + id = Column(Integer, primary_key=True) + openid_url = Column(Unicode, nullable=False) + user_id = Column(Integer, ForeignKey(User.id), nullable=False) + + # OpenID's are owned by their user, so do the full thing. + user = relationship(User, backref=backref('openid_urls', + cascade='all, delete-orphan')) + + +# OpenID Store Models +class Nonce(Base): + __tablename__ = "openid__nonce" + + server_url = Column(Unicode, primary_key=True) + timestamp = Column(Integer, primary_key=True) + salt = Column(Unicode, primary_key=True) + + def __unicode__(self): + return u'Nonce: %r, %r' % (self.server_url, self.salt) + + +class Association(Base): + __tablename__ = "openid__association" + + server_url = Column(Unicode, primary_key=True) + handle = Column(Unicode, primary_key=True) + secret = Column(Unicode) + issued = Column(Integer) + lifetime = Column(Integer) + assoc_type = Column(Unicode) + + def __unicode__(self): + return u'Association: %r, %r' % (self.server_url, self.handle) + + +MODELS = [ + OpenIDUserURL, + Nonce, + Association +] diff --git a/mediagoblin/plugins/openid/store.py b/mediagoblin/plugins/openid/store.py new file mode 100644 index 00000000..8f9a7012 --- /dev/null +++ b/mediagoblin/plugins/openid/store.py @@ -0,0 +1,127 @@ +# 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 base64 +import time + +from openid.association import Association as OIDAssociation +from openid.store.interface import OpenIDStore +from openid.store import nonce + +from mediagoblin.plugins.openid.models import Association, Nonce + + +class SQLAlchemyOpenIDStore(OpenIDStore): + def __init__(self): + self.max_nonce_age = 6 * 60 * 60 + + def storeAssociation(self, server_url, association): + assoc = Association.query.filter_by( + server_url=server_url, handle=association.handle + ).first() + + if not assoc: + assoc = Association() + assoc.server_url = unicode(server_url) + assoc.handle = association.handle + + # django uses base64 encoding, python-openid uses a blob field for + # secret + assoc.secret = unicode(base64.encodestring(association.secret)) + assoc.issued = association.issued + assoc.lifetime = association.lifetime + assoc.assoc_type = association.assoc_type + assoc.save() + + def getAssociation(self, server_url, handle=None): + assocs = [] + if handle is not None: + assocs = Association.query.filter_by( + server_url=server_url, handle=handle + ) + else: + assocs = Association.query.filter_by( + server_url=server_url + ) + + if assocs.count() == 0: + return None + else: + associations = [] + for assoc in assocs: + association = OIDAssociation( + assoc.handle, base64.decodestring(assoc.secret), + assoc.issued, assoc.lifetime, assoc.assoc_type + ) + if association.getExpiresIn() == 0: + assoc.delete() + else: + associations.append((association.issued, association)) + + if not associations: + return None + associations.sort() + return associations[-1][1] + + def removeAssociation(self, server_url, handle): + assocs = Association.query.filter_by( + server_url=server_url, handle=handle + ).first() + + assoc_exists = True if assocs else False + for assoc in assocs: + assoc.delete() + return assoc_exists + + def useNonce(self, server_url, timestamp, salt): + if abs(timestamp - time.time()) > nonce.SKEW: + return False + + ononce = Nonce.query.filter_by( + server_url=server_url, + timestamp=timestamp, + salt=salt + ).first() + + if ononce: + return False + else: + ononce = Nonce() + ononce.server_url = server_url + ononce.timestamp = timestamp + ononce.salt = salt + ononce.save() + return True + + def cleanupNonces(self, _now=None): + if _now is None: + _now = int(time.time()) + expired = Nonce.query.filter( + Nonce.timestamp < (_now - nonce.SKEW) + ) + count = expired.count() + for each in expired: + each.delete() + return count + + def cleanupAssociations(self): + now = int(time.time()) + assoc = Association.query.all() + count = 0 + for each in assoc: + if (each.lifetime + each.issued) <= now: + each.delete() + count = count + 1 + return count diff --git a/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/add.html b/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/add.html new file mode 100644 index 00000000..8d308c81 --- /dev/null +++ b/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/add.html @@ -0,0 +1,44 @@ +{# +# 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/base.html" %} + +{% import "/mediagoblin/utils/wtforms.html" as wtforms_util %} + +{% block title -%} + {% trans %}Add an OpenID{% endtrans %} — {{ super() }} +{%- endblock %} + +{% block mediagoblin_content %} + <form action="{{ request.urlgen('mediagoblin.plugins.openid.edit') }}" + method="POST" enctype="multipart/form-data"> + {{ csrf_token }} + <div class="form_box"> + <h1>{% trans %}Add an OpenID{% endtrans %}</h1> + <p> + <a href="{{ request.urlgen('mediagoblin.plugins.openid.delete') }}"> + {% trans %}Delete an OpenID{% endtrans %} + </a> + </p> + {{ wtforms_util.render_divs(form, True) }} + <div class="form_submit_buttons"> + <input type="submit" value="{% trans %}Add{% endtrans %}" class="button_form"/> + </div> + </div> + </form> +{% endblock %} + diff --git a/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/delete.html b/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/delete.html new file mode 100644 index 00000000..84301b9e --- /dev/null +++ b/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/delete.html @@ -0,0 +1,43 @@ +{# +# 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/base.html" %} + +{% import "/mediagoblin/utils/wtforms.html" as wtforms_util %} + +{% block title -%} + {% trans %}Delete an OpenID{% endtrans %} — {{ super() }} +{%- endblock %} + +{% block mediagoblin_content %} + <form action="{{ request.urlgen('mediagoblin.plugins.openid.delete') }}" + method="POST" enctype="multipart/form-data"> + {{ csrf_token }} + <div class="form_box"> + <h1>{% trans %}Delete an OpenID{% endtrans %}</h1> + <p> + <a href="{{ request.urlgen('mediagoblin.plugins.openid.edit') }}"> + {% trans %}Add an OpenID{% endtrans %} + </a> + </p> + {{ wtforms_util.render_divs(form, True) }} + <div class="form_submit_buttons"> + <input type="submit" value="{% trans %}Delete{% endtrans %}" class="button_form"/> + </div> + </div> + </form> +{% endblock %} diff --git a/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/edit_link.html b/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/edit_link.html new file mode 100644 index 00000000..2e63e1f8 --- /dev/null +++ b/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/edit_link.html @@ -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/>. +#} + +{% block openid_edit_link %} + <p> + <a href="{{ request.urlgen('mediagoblin.plugins.openid.edit') }}"> + {% trans %}Edit your OpenID's{% endtrans %} + </a> + </p> +{% endblock %} diff --git a/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/login.html b/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/login.html new file mode 100644 index 00000000..33df7200 --- /dev/null +++ b/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/login.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/base.html" %} + +{% 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 title -%} + {% trans %}Log in{% endtrans %} — {{ super() }} +{%- endblock %} + +{% block mediagoblin_content %} + <form action="{{ post_url }}" + method="POST" enctype="multipart/form-data"> + {{ csrf_token }} + <div class="form_box"> + <h1>{% trans %}Log in{% endtrans %}</h1> + {% if login_failed %} + <div class="form_field_error"> + {% trans %}Logging in failed!{% endtrans %} + </div> + {% endif %} + {% if allow_registration %} + <p> + {% trans %}Log in to create an account!{% endtrans %} + </p> + {% endif %} + {% if pass_auth is defined %} + <p> + <a href="{{ request.urlgen('mediagoblin.auth.login') }}?{{ request.query_string }}"> + {%- trans %}Or login with a password!{% endtrans %} + </a> + </p> + {% endif %} + {{ wtforms_util.render_divs(login_form, True) }} + <div class="form_submit_buttons"> + <input type="submit" value="{% trans %}Log in{% endtrans %}" class="button_form"/> + </div> + {% if next %} + <input type="hidden" name="next" value="{{ next }}" class="button_form" + style="display: none;"/> + {% endif %} + </div> + </form> +{% endblock %} + diff --git a/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/login_link.html b/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/login_link.html new file mode 100644 index 00000000..e5e77d01 --- /dev/null +++ b/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/login_link.html @@ -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/>. +#} + +{% block openid_login_link %} + <p> + <a href="{{ request.urlgen('mediagoblin.plugins.openid.login') }}?{{ request.query_string }}"> + {%- trans %}Or login with OpenID!{% endtrans %} + </a> + </p> +{% endblock %} diff --git a/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/register_link.html b/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/register_link.html new file mode 100644 index 00000000..9bccb4d8 --- /dev/null +++ b/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/register_link.html @@ -0,0 +1,27 @@ +{# +# 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/>. +#} + +{% block openid_register_link %} + {% if openid_link is defined %} + <p> + <a href="{{ request.urlgen('mediagoblin.plugins.openid.login') }}"> + {%- trans %}Or register with OpenID!{% endtrans %} + </a> + </p> + {% endif %} +{% endblock %} diff --git a/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/request_form.html b/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/request_form.html new file mode 100644 index 00000000..68d028d0 --- /dev/null +++ b/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/request_form.html @@ -0,0 +1,24 @@ +{# +# 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/base.html" %} + +{% block mediagoblin_content %} + <div onload="document.getElementById('openid_message').submit()"> + {{ html|safe }} + </div> +{% endblock %} diff --git a/mediagoblin/plugins/openid/views.py b/mediagoblin/plugins/openid/views.py new file mode 100644 index 00000000..b639a4cb --- /dev/null +++ b/mediagoblin/plugins/openid/views.py @@ -0,0 +1,404 @@ +# 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 openid.consumer import consumer +from openid.consumer.discover import DiscoveryFailure +from openid.extensions.sreg import SRegRequest, SRegResponse + +from mediagoblin import mg_globals, messages +from mediagoblin.db.models import User +from mediagoblin.decorators import (auth_enabled, allow_registration, + require_active_login) +from mediagoblin.tools.response import redirect, render_to_response +from mediagoblin.tools.translate import pass_to_ugettext as _ +from mediagoblin.plugins.openid import forms as auth_forms +from mediagoblin.plugins.openid.models import OpenIDUserURL +from mediagoblin.plugins.openid.store import SQLAlchemyOpenIDStore +from mediagoblin.auth.tools import register_user + + +def _start_verification(request, form, return_to, sreg=True): + """ + Start OpenID Verification. + + Returns False if verification fails, otherwise, will return either a + redirect or render_to_response object + """ + openid_url = form.openid.data + c = consumer.Consumer(request.session, SQLAlchemyOpenIDStore()) + + # Try to discover provider + try: + auth_request = c.begin(openid_url) + except DiscoveryFailure: + # Discovery failed, return to login page + form.openid.errors.append( + _('Sorry, the OpenID server could not be found')) + + return False + + host = 'http://' + request.host + + if sreg: + # Ask provider for email and nickname + auth_request.addExtension(SRegRequest(required=['email', 'nickname'])) + + # Do we even need this? + if auth_request is None: + form.openid.errors.append( + _('No OpenID service was found for %s' % openid_url)) + + elif auth_request.shouldSendRedirect(): + # Begin the authentication process as a HTTP redirect + redirect_url = auth_request.redirectURL( + host, return_to) + + return redirect( + request, location=redirect_url) + + else: + # Send request as POST + form_html = auth_request.htmlMarkup( + host, host + return_to, + # Is this necessary? + form_tag_attrs={'id': 'openid_message'}) + + # Beware: this renders a template whose content is a form + # and some javascript to submit it upon page load. Non-JS + # users will have to click the form submit button to + # initiate OpenID authentication. + return render_to_response( + request, + 'mediagoblin/plugins/openid/request_form.html', + {'html': form_html}) + + return False + + +def _finish_verification(request): + """ + Complete OpenID Verification Process. + + If the verification failed, will return false, otherwise, will return + the response + """ + c = consumer.Consumer(request.session, SQLAlchemyOpenIDStore()) + + # Check the response from the provider + response = c.complete(request.args, request.base_url) + if response.status == consumer.FAILURE: + messages.add_message( + request, + messages.WARNING, + _('Verification of %s failed: %s' % + (response.getDisplayIdentifier(), response.message))) + + elif response.status == consumer.SUCCESS: + # Verification was successfull + return response + + elif response.status == consumer.CANCEL: + # Verification canceled + messages.add_message( + request, + messages.WARNING, + _('Verification cancelled')) + + return False + + +def _response_email(response): + """ Gets the email from the OpenID providers response""" + sreg_response = SRegResponse.fromSuccessResponse(response) + if sreg_response and 'email' in sreg_response: + return sreg_response.data['email'] + return None + + +def _response_nickname(response): + """ Gets the nickname from the OpenID providers response""" + sreg_response = SRegResponse.fromSuccessResponse(response) + if sreg_response and 'nickname' in sreg_response: + return sreg_response.data['nickname'] + return None + + +@auth_enabled +def login(request): + """OpenID Login View""" + login_form = auth_forms.LoginForm(request.form) + allow_registration = mg_globals.app_config["allow_registration"] + + # Can't store next in request.GET because of redirects to OpenID provider + # Store it in the session + next = request.GET.get('next') + request.session['next'] = next + + login_failed = False + + if request.method == 'POST' and login_form.validate(): + return_to = request.urlgen( + 'mediagoblin.plugins.openid.finish_login') + + success = _start_verification(request, login_form, return_to) + + if success: + return success + + login_failed = True + + return render_to_response( + request, + 'mediagoblin/plugins/openid/login.html', + {'login_form': login_form, + 'next': request.session.get('next'), + 'login_failed': login_failed, + 'post_url': request.urlgen('mediagoblin.plugins.openid.login'), + 'allow_registration': allow_registration}) + + +@auth_enabled +def finish_login(request): + """Complete OpenID Login Process""" + response = _finish_verification(request) + + if not response: + # Verification failed, redirect to login page. + return redirect(request, 'mediagoblin.plugins.openid.login') + + # Verification was successfull + query = OpenIDUserURL.query.filter_by( + openid_url=response.identity_url, + ).first() + user = query.user if query else None + + if user: + # Set up login in session + request.session['user_id'] = unicode(user.id) + request.session.save() + + if request.session.get('next'): + return redirect(request, location=request.session.pop('next')) + else: + return redirect(request, "index") + else: + # No user, need to register + if not mg_globals.app.auth: + messages.add_message( + request, + messages.WARNING, + _('Sorry, authentication is disabled on this instance.')) + return redirect(request, 'index') + + # Get email and nickname from response + email = _response_email(response) + username = _response_nickname(response) + + register_form = auth_forms.RegistrationForm(request.form, + openid=response.identity_url, + email=email, + username=username) + return render_to_response( + request, + 'mediagoblin/auth/register.html', + {'register_form': register_form, + 'post_url': request.urlgen('mediagoblin.plugins.openid.register')}) + + +@allow_registration +@auth_enabled +def register(request): + """OpenID Registration View""" + if request.method == 'GET': + # Need to connect to openid provider before registering a user to + # get the users openid url. If method is 'GET', then this page was + # acessed without logging in first. + return redirect(request, 'mediagoblin.plugins.openid.login') + + register_form = auth_forms.RegistrationForm(request.form) + + if register_form.validate(): + user = register_user(request, register_form) + + if user: + # redirect the user to their homepage... there will be a + # message waiting for them to verify their email + return redirect( + request, 'mediagoblin.user_pages.user_home', + user=user.username) + + return render_to_response( + request, + 'mediagoblin/auth/register.html', + {'register_form': register_form, + 'post_url': request.urlgen('mediagoblin.plugins.openid.register')}) + + +@require_active_login +def start_edit(request): + """Starts the process of adding an openid url to a users account""" + form = auth_forms.LoginForm(request.form) + + if request.method == 'POST' and form.validate(): + query = OpenIDUserURL.query.filter_by( + openid_url=form.openid.data + ).first() + user = query.user if query else None + + if not user: + return_to = request.urlgen('mediagoblin.plugins.openid.finish_edit') + success = _start_verification(request, form, return_to, False) + + if success: + return success + else: + form.openid.errors.append( + _('Sorry, an account is already registered to that OpenID.')) + + return render_to_response( + request, + 'mediagoblin/plugins/openid/add.html', + {'form': form, + 'post_url': request.urlgen('mediagoblin.plugins.openid.edit')}) + + +@require_active_login +def finish_edit(request): + """Finishes the process of adding an openid url to a user""" + response = _finish_verification(request) + + if not response: + # Verification failed, redirect to add openid page. + return redirect(request, 'mediagoblin.plugins.openid.edit') + + # Verification was successfull + query = OpenIDUserURL.query.filter_by( + openid_url=response.identity_url, + ).first() + user_exists = query.user if query else None + + if user_exists: + # user exists with that openid url, redirect back to edit page + messages.add_message( + request, + messages.WARNING, + _('Sorry, an account is already registered to that OpenID.')) + return redirect(request, 'mediagoblin.plugins.openid.edit') + + else: + # Save openid to user + user = User.query.filter_by( + id=request.session['user_id'] + ).first() + + new_entry = OpenIDUserURL() + new_entry.openid_url = response.identity_url + new_entry.user_id = user.id + new_entry.save() + + messages.add_message( + request, + messages.SUCCESS, + _('Your OpenID url was saved successfully.')) + + return redirect(request, 'mediagoblin.edit.account') + + +@require_active_login +def delete_openid(request): + """View to remove an openid from a users account""" + form = auth_forms.LoginForm(request.form) + + if request.method == 'POST' and form.validate(): + # Check if a user has this openid + query = OpenIDUserURL.query.filter_by( + openid_url=form.openid.data + ) + user = query.first().user if query.first() else None + + if user and user.id == int(request.session['user_id']): + count = len(user.openid_urls) + if not count > 1 and not user.pw_hash: + # Make sure the user has a pw or another OpenID + messages.add_message( + request, + messages.WARNING, + _("You can't delete your only OpenID URL unless you" + " have a password set")) + elif user: + # There is a user, but not the same user who is logged in + form.openid.errors.append( + _('That OpenID is not registered to this account.')) + + if not form.errors and not request.session.get('messages'): + # Okay to continue with deleting openid + return_to = request.urlgen( + 'mediagoblin.plugins.openid.finish_delete') + success = _start_verification(request, form, return_to, False) + + if success: + return success + + return render_to_response( + request, + 'mediagoblin/plugins/openid/delete.html', + {'form': form, + 'post_url': request.urlgen('mediagoblin.plugins.openid.delete')}) + + +@require_active_login +def finish_delete(request): + """Finishes the deletion of an OpenID from an user's account""" + response = _finish_verification(request) + + if not response: + # Verification failed, redirect to delete openid page. + return redirect(request, 'mediagoblin.plugins.openid.delete') + + query = OpenIDUserURL.query.filter_by( + openid_url=response.identity_url + ) + user = query.first().user if query.first() else None + + # Need to check this again because of generic openid urls such as google's + if user and user.id == int(request.session['user_id']): + count = len(user.openid_urls) + if count > 1 or user.pw_hash: + # User has more then one openid or also has a password. + query.first().delete() + + messages.add_message( + request, + messages.SUCCESS, + _('OpenID was successfully removed.')) + + return redirect(request, 'mediagoblin.edit.account') + + elif not count > 1: + messages.add_message( + request, + messages.WARNING, + _("You can't delete your only OpenID URL unless you have a " + "password set")) + + return redirect(request, 'mediagoblin.plugins.openid.delete') + + else: + messages.add_message( + request, + messages.WARNING, + _('That OpenID is not registered to this account.')) + + return redirect(request, 'mediagoblin.plugins.openid.delete') diff --git a/mediagoblin/plugins/piwigo/tools.py b/mediagoblin/plugins/piwigo/tools.py index 400be615..484ea531 100644 --- a/mediagoblin/plugins/piwigo/tools.py +++ b/mediagoblin/plugins/piwigo/tools.py @@ -14,6 +14,7 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. +from collections import namedtuple import logging import six @@ -27,6 +28,9 @@ from mediagoblin.tools.response import Response _log = logging.getLogger(__name__) +PwgError = namedtuple("PwgError", ["code", "msg"]) + + class PwgNamedArray(list): def __init__(self, l, item_name, as_attrib=()): self.item_name = item_name @@ -74,9 +78,18 @@ def _fill_element(el, data): def response_xml(result): r = ET.Element("rsp") r.set("stat", "ok") - _fill_element(r, result) + status = None + if isinstance(result, PwgError): + r.set("stat", "fail") + err = ET.SubElement(r, "err") + err.set("code", str(result.code)) + err.set("msg", result.msg) + if result.code >= 100 and result.code < 600: + status = result.code + else: + _fill_element(r, result) return Response(ET.tostring(r, encoding="utf-8", xml_declaration=True), - mimetype='text/xml') + mimetype='text/xml', status=status) class CmdTable(object): @@ -113,7 +126,7 @@ def check_form(form): if not form.validate(): _log.error("form validation failed for form %r", form) for f in form: - if len(f.error): + if len(f.errors): _log.error("Errors for %s: %r", f.name, f.errors) raise BadRequest() dump = [] @@ -140,7 +153,7 @@ class PWGSession(object): self.in_pwg_session = True return self - def __exit__(self, *args): + def __exit__(self, *args): # Restore state self.request.session = self.old_session self.request.user = self.old_user diff --git a/mediagoblin/plugins/piwigo/views.py b/mediagoblin/plugins/piwigo/views.py index b59247ad..ca723189 100644 --- a/mediagoblin/plugins/piwigo/views.py +++ b/mediagoblin/plugins/piwigo/views.py @@ -16,15 +16,23 @@ import logging import re +from os.path import splitext +import shutil from werkzeug.exceptions import MethodNotAllowed, BadRequest, NotImplemented from werkzeug.wrappers import BaseResponse from mediagoblin.meddleware.csrf import csrf_exempt -from mediagoblin.submit.lib import check_file_field -from mediagoblin.auth.lib import fake_login_attempt -from .tools import CmdTable, PwgNamedArray, response_xml, check_form, \ - PWGSession +from mediagoblin.auth.tools import check_login_simple +from mediagoblin.media_types import sniff_media +from mediagoblin.submit.lib import check_file_field, prepare_queue_task, \ + run_process_media, new_upload_entry + +from mediagoblin.user_pages.lib import add_media_to_collection +from mediagoblin.db.models import Collection + +from .tools import CmdTable, response_xml, check_form, \ + PWGSession, PwgNamedArray, PwgError from .forms import AddSimpleForm, AddForm @@ -35,16 +43,9 @@ _log = logging.getLogger(__name__) def pwg_login(request): username = request.form.get("username") password = request.form.get("password") - _log.debug("Login for %r/%r...", username, password) - user = request.db.User.query.filter_by(username=username).first() + user = check_login_simple(username, password) if not user: - _log.info("User %r not found", username) - fake_login_attempt() - return False - if not user.check_login(password): - _log.warn("Wrong password for %r", username) - return False - _log.info("Logging %r in", username) + return PwgError(999, 'Invalid username/password') request.session["user_id"] = user.id request.session.save() return True @@ -73,9 +74,21 @@ def pwg_session_getStatus(request): @CmdTable("pwg.categories.getList") def pwg_categories_getList(request): - catlist = ({'id': -29711, + catlist = [{'id': -29711, 'uppercats': "-29711", - 'name': "All my images"},) + 'name': "All my images"}] + + if request.user: + collections = Collection.query.filter_by( + get_creator=request.user).order_by(Collection.title) + + for c in collections: + catlist.append({'id': c.id, + 'uppercats': str(c.id), + 'name': c.title, + 'comment': c.description + }) + return { 'categories': PwgNamedArray( catlist, @@ -107,16 +120,69 @@ def pwg_images_addSimple(request): dump = [] for f in form: dump.append("%s=%r" % (f.name, f.data)) - _log.info("addimple: %r %s %r", request.form, " ".join(dump), request.files) + _log.info("addSimple: %r %s %r", request.form, " ".join(dump), + request.files) if not check_file_field(request, 'image'): raise BadRequest() - return {'image_id': 123456, 'url': ''} + filename = request.files['image'].filename + + # Sniff the submitted media to determine which + # media plugin should handle processing + media_type, media_manager = sniff_media( + request.files['image']) + + # create entry and save in database + entry = new_upload_entry(request.user) + entry.media_type = unicode(media_type) + entry.title = ( + unicode(form.name.data) + or unicode(splitext(filename)[0])) + + entry.description = unicode(form.comment.data) + + ''' + # Process the user's folksonomy "tags" + entry.tags = convert_to_tag_list_of_dicts( + form.tags.data) + ''' + + # Generate a slug from the title + entry.generate_slug() + + queue_file = prepare_queue_task(request.app, entry, filename) + + with queue_file: + shutil.copyfileobj(request.files['image'].stream, + queue_file, + length=4 * 1048576) + + # Save now so we have this data before kicking off processing + entry.save() + + # Pass off to processing + # + # (... don't change entry after this point to avoid race + # conditions with changes to the document via processing code) + feed_url = request.urlgen( + 'mediagoblin.user_pages.atom_feed', + qualified=True, user=request.user.username) + run_process_media(entry, feed_url) + + collection_id = form.category.data + if collection_id > 0: + collection = Collection.query.get(collection_id) + if collection is not None and collection.creator == request.user.id: + add_media_to_collection(collection, entry, "") + + return {'image_id': entry.id, 'url': entry.url_for_self(request.urlgen, + qualified=True)} + - md5sum_matcher = re.compile(r"^[0-9a-fA-F]{32}$") + def fetch_md5(request, parm_name, optional_parm=False): val = request.form.get(parm_name) if (val is None) and (not optional_parm): diff --git a/mediagoblin/routing.py b/mediagoblin/routing.py index a650f22f..986eb2ed 100644 --- a/mediagoblin/routing.py +++ b/mediagoblin/routing.py @@ -35,6 +35,7 @@ def get_url_map(): import mediagoblin.edit.routing import mediagoblin.webfinger.routing import mediagoblin.listings.routing + import mediagoblin.notifications.routing for route in PluginManager().get_routes(): add_route(*route) diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css index 0cb36753..84d274d1 100644 --- a/mediagoblin/static/css/base.css +++ b/mediagoblin/static/css/base.css @@ -129,6 +129,7 @@ header { .header_dropdown { margin-bottom: 20px; + padding: 0px 10px 0px 10px; } .header_dropdown li { @@ -333,6 +334,10 @@ text-align: center; width: 20px; } +.boolean { + margin-bottom: 8px; + } + textarea#description, textarea#bio { resize: vertical; height: 100px; @@ -384,6 +389,12 @@ a.comment_whenlink:hover { margin-top: 8px; } +.comment_active { + box-shadow: 0px 0px 15px 15px #378566; + background: #378566; + color: #f7f7f7; +} + textarea#comment_content { resize: vertical; width: 100%; @@ -433,9 +444,12 @@ a.thumb_entry_title { padding: 8px; } -.media_thumbnail img { - max-height: 135px; -} +/* For now, this is commented out since our thumbnails are actually 180px high. + * + * .media_thumbnail img { + * max-height: 135px; + * } + */ .thumb_entry_last { margin-right: 0px; @@ -481,6 +495,38 @@ img.media_icon { vertical-align: sub; } +/* EXIF information */ + +#exif_content h3 { + border-bottom: 1px solid #333; +} + +#exif_camera_information { + margin-bottom: 20px; +} + +#exif_additional_info { + display: none; +} + +#exif_additional_info table { + font-size: 11px; + margin-top: 10px; +} + +#exif_additional_info td { + vertical-align: top; + padding-bottom: 5px; +} + +#exif_content .col1 { + padding-right: 20px; +} + +#exif_additional_info table tr { + margin-bottom: 10px; +} + /* navigation */ .navigation { @@ -685,3 +731,29 @@ pre { width: 46%; } } + +/* Exif display */ +#exif_content h3 { + border-bottom: 1px solid #333; +} +#exif_camera_information { + margin-bottom: 20px; +} + +#exif_additional_info { + display: none; +} +#exif_additional_info table { + font-size: 11px; + margin-top: 10px; +} +#exif_additional_info td { + vertical-align: top; + padding-bottom: 5px; +} +#exif_content .col1 { + padding-right: 20px; +} +#exif_additional_info table tr { + margin-bottom: 10px; +} diff --git a/mediagoblin/static/css/pdf_viewer.css b/mediagoblin/static/css/pdf_viewer.css deleted file mode 100644 index c04c8981..00000000 --- a/mediagoblin/static/css/pdf_viewer.css +++ /dev/null @@ -1,1448 +0,0 @@ -/* Copyright 2012 Mozilla Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -* { - padding: 0; - margin: 0; -} - -html { - height: 100%; -} - -body { - height: 100%; - background-color: #404040; - background-image: url(../extlib/pdf.js/web/images/texture.png); -} - -body, -input, -button, -select { - font: message-box; -} - -.hidden { - display: none; -} -[hidden] { - display: none !important; -} - -#viewerContainer:-webkit-full-screen { - top: 0px; - border-top: 2px solid transparent; - background-color: #404040; - background-image: url(../extlib/pdf.js/web/images/texture.png); - width: 100%; - height: 100%; - overflow: hidden; - cursor: none; -} - -#viewerContainer:-moz-full-screen { - top: 0px; - border-top: 2px solid transparent; - background-color: #404040; - background-image: url(../extlib/pdf.js/web/images/texture.png); - width: 100%; - height: 100%; - overflow: hidden; - cursor: none; -} - -#viewerContainer:fullscreen { - top: 0px; - border-top: 2px solid transparent; - background-color: #404040; - background-image: url(../extlib/pdf.js/web/images/texture.png); - width: 100%; - height: 100%; - overflow: hidden; - cursor: none; -} - - -:-webkit-full-screen .page { - margin-bottom: 100%; -} - -:-moz-full-screen .page { - margin-bottom: 100%; -} - -:fullscreen .page { - margin-bottom: 100%; -} - -#viewerContainer.presentationControls { - cursor: default; -} - -/* outer/inner center provides horizontal center */ -html[dir='ltr'] .outerCenter { - float: right; - position: relative; - right: 50%; -} -html[dir='rtl'] .outerCenter { - float: left; - position: relative; - left: 50%; -} -html[dir='ltr'] .innerCenter { - float: right; - position: relative; - right: -50%; -} -html[dir='rtl'] .innerCenter { - float: left; - position: relative; - left: -50%; -} - -#outerContainer { - width: 100%; - height: 100%; -} - -#sidebarContainer { - left: 0; - right: 0; - height: 200px; - visibility: hidden; - -webkit-transition-duration: 200ms; - -webkit-transition-timing-function: ease; - -moz-transition-duration: 200ms; - -moz-transition-timing-function: ease; - -ms-transition-duration: 200ms; - -ms-transition-timing-function: ease; - -o-transition-duration: 200ms; - -o-transition-timing-function: ease; - transition-duration: 200ms; - transition-timing-function: ease; - -} -html[dir='ltr'] #sidebarContainer { - -webkit-transition-property: top; - -moz-transition-property: top; - -ms-transition-property: top; - -o-transition-property: top; - transition-property: top; - top: -200px; -} -html[dir='rtl'] #sidebarContainer { - -webkit-transition-property: top; - -ms-transition-property: top; - -o-transition-property: top; - transition-property: top; - top: -200px; -} - -#outerContainer.sidebarMoving > #sidebarContainer, -#outerContainer.sidebarOpen > #sidebarContainer { - visibility: visible; -} -html[dir='ltr'] #outerContainer.sidebarOpen > #sidebarContainer { - left: 0px; -} -html[dir='rtl'] #outerContainer.sidebarOpen > #sidebarContainer { - right: 0px; -} - -#mainContainer { - top: 0; - right: 0; - bottom: 0; - left: 0; - min-width: 320px; - -webkit-transition-duration: 200ms; - -webkit-transition-timing-function: ease; - -moz-transition-duration: 200ms; - -moz-transition-timing-function: ease; - -ms-transition-duration: 200ms; - -ms-transition-timing-function: ease; - -o-transition-duration: 200ms; - -o-transition-timing-function: ease; - transition-duration: 200ms; - transition-timing-function: ease; -} -html[dir='ltr'] #outerContainer.sidebarOpen > #mainContainer { - -webkit-transition-property: left; - -moz-transition-property: left; - -ms-transition-property: left; - -o-transition-property: left; - transition-property: left; - left: 200px; -} -html[dir='rtl'] #outerContainer.sidebarOpen > #mainContainer { - -webkit-transition-property: right; - -moz-transition-property: right; - -ms-transition-property: right; - -o-transition-property: right; - transition-property: right; - right: 200px; -} - -#sidebarContent { - top: 32px; - bottom: 0; - overflow: auto; - height: 200px; - - background-color: hsla(0,0%,0%,.1); - box-shadow: inset -1px 0 0 hsla(0,0%,0%,.25); -} -html[dir='ltr'] #sidebarContent { - left: 0; -} -html[dir='rtl'] #sidebarContent { - right: 0; -} - -#viewerContainer { - overflow: auto; - box-shadow: inset 1px 0 0 hsla(0,0%,100%,.05); - top: 32px; - right: 0; - bottom: 0; - left: 0; - height: 480px; - width: 640px; -} - -.toolbar { - left: 0; - right: 0; - height: 32px; - z-index: 9999; - cursor: default; -} - -#toolbarContainer { - width: 100%; -} - -#toolbarSidebar { - width: 200px; - height: 32px; - background-image: url(../extlib/pdf.js/web/images/texture.png), - -webkit-linear-gradient(hsla(0,0%,30%,.99), hsla(0,0%,25%,.95)); - background-image: url(../extlib/pdf.js/web/images/texture.png), - -moz-linear-gradient(hsla(0,0%,30%,.99), hsla(0,0%,25%,.95)); - background-image: url(../extlib/pdf.js/web/images/texture.png), - -ms-linear-gradient(hsla(0,0%,30%,.99), hsla(0,0%,25%,.95)); - background-image: url(../extlib/pdf.js/web/images/texture.png), - -o-linear-gradient(hsla(0,0%,30%,.99), hsla(0,0%,25%,.95)); - background-image: url(../extlib/pdf.js/web/images/texture.png), - linear-gradient(hsla(0,0%,30%,.99), hsla(0,0%,25%,.95)); - box-shadow: inset -1px 0 0 rgba(0, 0, 0, 0.25), - - inset 0 -1px 0 hsla(0,0%,100%,.05), - 0 1px 0 hsla(0,0%,0%,.15), - 0 0 1px hsla(0,0%,0%,.1); -} - -#toolbarViewer, .findbar { - position: relative; - height: 32px; - background-color: #474747; /* IE9 */ - background-image: url(../extlib/pdf.js/web/images/texture.png), - -webkit-linear-gradient(hsla(0,0%,32%,.99), hsla(0,0%,27%,.95)); - background-image: url(../extlib/pdf.js/web/images/texture.png), - -moz-linear-gradient(hsla(0,0%,32%,.99), hsla(0,0%,27%,.95)); - background-image: url(../extlib/pdf.js/web/images/texture.png), - -ms-linear-gradient(hsla(0,0%,32%,.99), hsla(0,0%,27%,.95)); - background-image: url(../extlib/pdf.js/web/images/texture.png), - -o-linear-gradient(hsla(0,0%,32%,.99), hsla(0,0%,27%,.95)); - background-image: url(../extlib/pdf.js/web/images/texture.png), - linear-gradient(hsla(0,0%,32%,.99), hsla(0,0%,27%,.95)); - box-shadow: inset 1px 0 0 hsla(0,0%,100%,.08), - inset 0 1px 1px hsla(0,0%,0%,.15), - inset 0 -1px 0 hsla(0,0%,100%,.05), - 0 1px 0 hsla(0,0%,0%,.15), - 0 1px 1px hsla(0,0%,0%,.1); -} - -.findbar { - top: 64px; - z-index: 10000; - height: 32px; - - min-width: 16px; - padding: 0px 6px 0px 6px; - margin: 4px 2px 4px 2px; - color: hsl(0,0%,85%); - font-size: 12px; - line-height: 14px; - text-align: left; - cursor: default; -} - -html[dir='ltr'] .findbar { - left: 68px; -} - -html[dir='rtl'] .findbar { - right: 68px; -} - -.findbar label { - -webkit-user-select: none; - -moz-user-select: none; -} - -#findInput[data-status="pending"] { - background-image: url(../extlib/pdf.js/web/images/loading-small.png); - background-repeat: no-repeat; - background-position: right; -} - -.doorHanger { - border: 1px solid hsla(0,0%,0%,.5); - border-radius: 2px; - box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3); -} -.doorHanger:after, .doorHanger:before { - bottom: 100%; - border: solid transparent; - content: " "; - height: 0; - width: 0; - pointer-events: none; -} -.doorHanger:after { - border-bottom-color: hsla(0,0%,32%,.99); - border-width: 8px; -} -.doorHanger:before { - border-bottom-color: hsla(0,0%,0%,.5); - border-width: 9px; -} - -html[dir='ltr'] .doorHanger:after { - left: 13px; - margin-left: -8px; -} - -html[dir='ltr'] .doorHanger:before { - left: 13px; - margin-left: -9px; -} - -html[dir='rtl'] .doorHanger:after { - right: 13px; - margin-right: -8px; -} - -html[dir='rtl'] .doorHanger:before { - right: 13px; - margin-right: -9px; -} - -#findMsg { - font-style: italic; - color: #A6B7D0; -} - -.notFound { - background-color: rgb(255, 137, 153); -} - -html[dir='ltr'] #toolbarViewerLeft { - margin-left: -1px; -} -html[dir='rtl'] #toolbarViewerRight { - margin-left: -1px; -} - - -html[dir='ltr'] #toolbarViewerLeft, -html[dir='rtl'] #toolbarViewerRight { - position: absolute; - top: 0; - left: 0; -} -html[dir='ltr'] #toolbarViewerRight, -html[dir='rtl'] #toolbarViewerLeft { - position: absolute; - top: 0; - right: 0; -} -html[dir='ltr'] #toolbarViewerLeft > *, -html[dir='ltr'] #toolbarViewerMiddle > *, -html[dir='ltr'] #toolbarViewerRight > *, -html[dir='ltr'] .findbar > * { - float: left; -} -html[dir='rtl'] #toolbarViewerLeft > *, -html[dir='rtl'] #toolbarViewerMiddle > *, -html[dir='rtl'] #toolbarViewerRight > *, -html[dir='rtl'] .findbar > * { - float: right; -} - -html[dir='ltr'] .splitToolbarButton { - margin: 3px 2px 4px 0; - display: inline-block; -} -html[dir='rtl'] .splitToolbarButton { - margin: 3px 0 4px 2px; - display: inline-block; -} -html[dir='ltr'] .splitToolbarButton > .toolbarButton { - border-radius: 0; - float: left; -} -html[dir='rtl'] .splitToolbarButton > .toolbarButton { - border-radius: 0; - float: right; -} - -.toolbarButton { - border: 0 none; - background-color: rgba(0, 0, 0, 0); - width: 32px; - height: 25px; -} - -.toolbarButton > span { - display: inline-block; - width: 0; - height: 0; - overflow: hidden; -} - -.toolbarButton[disabled] { - opacity: .5; -} - -.toolbarButton.group { - margin-right: 0; -} - -.splitToolbarButton.toggled .toolbarButton { - margin: 0; -} - -.splitToolbarButton:hover > .toolbarButton, -.splitToolbarButton:focus > .toolbarButton, -.splitToolbarButton.toggled > .toolbarButton, -.toolbarButton.textButton { - background-color: hsla(0,0%,0%,.12); - background-image: -webkit-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-image: -moz-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-image: -ms-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-image: -o-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-image: linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-clip: padding-box; - border: 1px solid hsla(0,0%,0%,.35); - border-color: hsla(0,0%,0%,.32) hsla(0,0%,0%,.38) hsla(0,0%,0%,.42); - box-shadow: 0 1px 0 hsla(0,0%,100%,.05) inset, - 0 0 1px hsla(0,0%,100%,.15) inset, - 0 1px 0 hsla(0,0%,100%,.05); - -webkit-transition-property: background-color, border-color, box-shadow; - -webkit-transition-duration: 150ms; - -webkit-transition-timing-function: ease; - -moz-transition-property: background-color, border-color, box-shadow; - -moz-transition-duration: 150ms; - -moz-transition-timing-function: ease; - -ms-transition-property: background-color, border-color, box-shadow; - -ms-transition-duration: 150ms; - -ms-transition-timing-function: ease; - -o-transition-property: background-color, border-color, box-shadow; - -o-transition-duration: 150ms; - -o-transition-timing-function: ease; - transition-property: background-color, border-color, box-shadow; - transition-duration: 150ms; - transition-timing-function: ease; - -} -.splitToolbarButton > .toolbarButton:hover, -.splitToolbarButton > .toolbarButton:focus, -.dropdownToolbarButton:hover, -.toolbarButton.textButton:hover, -.toolbarButton.textButton:focus { - background-color: hsla(0,0%,0%,.2); - box-shadow: 0 1px 0 hsla(0,0%,100%,.05) inset, - 0 0 1px hsla(0,0%,100%,.15) inset, - 0 0 1px hsla(0,0%,0%,.05); - z-index: 199; -} -html[dir='ltr'] .splitToolbarButton > .toolbarButton:first-child, -html[dir='rtl'] .splitToolbarButton > .toolbarButton:last-child { - position: relative; - margin: 0; - margin-right: -1px; - border-top-left-radius: 2px; - border-bottom-left-radius: 2px; - border-right-color: transparent; -} -html[dir='ltr'] .splitToolbarButton > .toolbarButton:last-child, -html[dir='rtl'] .splitToolbarButton > .toolbarButton:first-child { - position: relative; - margin: 0; - margin-left: -1px; - border-top-right-radius: 2px; - border-bottom-right-radius: 2px; - border-left-color: transparent; -} -.splitToolbarButtonSeparator { - padding: 8px 0; - width: 1px; - background-color: hsla(0,0%,00%,.5); - z-index: 99; - box-shadow: 0 0 0 1px hsla(0,0%,100%,.08); - display: inline-block; - margin: 5px 0; -} -html[dir='ltr'] .splitToolbarButtonSeparator { - float: left; -} -html[dir='rtl'] .splitToolbarButtonSeparator { - float: right; -} -.splitToolbarButton:hover > .splitToolbarButtonSeparator, -.splitToolbarButton.toggled > .splitToolbarButtonSeparator { - padding: 12px 0; - margin: 1px 0; - box-shadow: 0 0 0 1px hsla(0,0%,100%,.03); - -webkit-transition-property: padding; - -webkit-transition-duration: 10ms; - -webkit-transition-timing-function: ease; - -moz-transition-property: padding; - -moz-transition-duration: 10ms; - -moz-transition-timing-function: ease; - -ms-transition-property: padding; - -ms-transition-duration: 10ms; - -ms-transition-timing-function: ease; - -o-transition-property: padding; - -o-transition-duration: 10ms; - -o-transition-timing-function: ease; - transition-property: padding; - transition-duration: 10ms; - transition-timing-function: ease; -} - -.toolbarButton, -.dropdownToolbarButton { - min-width: 16px; - padding: 2px 6px 0; - border: 1px solid transparent; - border-radius: 2px; - color: hsl(0,0%,95%); - font-size: 12px; - line-height: 14px; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - /* Opera does not support user-select, use <... unselectable="on"> instead */ - cursor: default; - -webkit-transition-property: background-color, border-color, box-shadow; - -webkit-transition-duration: 150ms; - -webkit-transition-timing-function: ease; - -moz-transition-property: background-color, border-color, box-shadow; - -moz-transition-duration: 150ms; - -moz-transition-timing-function: ease; - -ms-transition-property: background-color, border-color, box-shadow; - -ms-transition-duration: 150ms; - -ms-transition-timing-function: ease; - -o-transition-property: background-color, border-color, box-shadow; - -o-transition-duration: 150ms; - -o-transition-timing-function: ease; - transition-property: background-color, border-color, box-shadow; - transition-duration: 150ms; - transition-timing-function: ease; -} - -html[dir='ltr'] .toolbarButton, -html[dir='ltr'] .dropdownToolbarButton { - margin: 3px 2px 4px 0; -} -html[dir='rtl'] .toolbarButton, -html[dir='rtl'] .dropdownToolbarButton { - margin: 3px 0 4px 2px; -} - -.toolbarButton:hover, -.toolbarButton:focus, -.dropdownToolbarButton { - background-color: hsla(0,0%,0%,.12); - background-image: -webkit-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-image: -moz-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-image: -ms-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-image: -o-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-image: linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-clip: padding-box; - border: 1px solid hsla(0,0%,0%,.35); - border-color: hsla(0,0%,0%,.32) hsla(0,0%,0%,.38) hsla(0,0%,0%,.42); - box-shadow: 0 1px 0 hsla(0,0%,100%,.05) inset, - 0 0 1px hsla(0,0%,100%,.15) inset, - 0 1px 0 hsla(0,0%,100%,.05); -} - -.toolbarButton:hover:active, -.dropdownToolbarButton:hover:active { - background-color: hsla(0,0%,0%,.2); - background-image: -webkit-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-image: -moz-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-image: -ms-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-image: -o-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-image: linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - border-color: hsla(0,0%,0%,.35) hsla(0,0%,0%,.4) hsla(0,0%,0%,.45); - box-shadow: 0 1px 1px hsla(0,0%,0%,.1) inset, - 0 0 1px hsla(0,0%,0%,.2) inset, - 0 1px 0 hsla(0,0%,100%,.05); - -webkit-transition-property: background-color, border-color, box-shadow; - -webkit-transition-duration: 10ms; - -webkit-transition-timing-function: linear; - -moz-transition-property: background-color, border-color, box-shadow; - -moz-transition-duration: 10ms; - -moz-transition-timing-function: linear; - -ms-transition-property: background-color, border-color, box-shadow; - -ms-transition-duration: 10ms; - -ms-transition-timing-function: linear; - -o-transition-property: background-color, border-color, box-shadow; - -o-transition-duration: 10ms; - -o-transition-timing-function: linear; - transition-property: background-color, border-color, box-shadow; - transition-duration: 10ms; - transition-timing-function: linear; -} - -.toolbarButton.toggled, -.splitToolbarButton.toggled > .toolbarButton.toggled { - background-color: hsla(0,0%,0%,.3); - background-image: -webkit-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-image: -moz-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-image: -ms-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-image: -o-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-image: linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - border-color: hsla(0,0%,0%,.4) hsla(0,0%,0%,.45) hsla(0,0%,0%,.5); - box-shadow: 0 1px 1px hsla(0,0%,0%,.1) inset, - 0 0 1px hsla(0,0%,0%,.2) inset, - 0 1px 0 hsla(0,0%,100%,.05); - -webkit-transition-property: background-color, border-color, box-shadow; - -webkit-transition-duration: 10ms; - -webkit-transition-timing-function: linear; - -moz-transition-property: background-color, border-color, box-shadow; - -moz-transition-duration: 10ms; - -moz-transition-timing-function: linear; - -ms-transition-property: background-color, border-color, box-shadow; - -ms-transition-duration: 10ms; - -ms-transition-timing-function: linear; - -o-transition-property: background-color, border-color, box-shadow; - -o-transition-duration: 10ms; - -o-transition-timing-function: linear; - transition-property: background-color, border-color, box-shadow; - transition-duration: 10ms; - transition-timing-function: linear; -} - -.toolbarButton.toggled:hover:active, -.splitToolbarButton.toggled > .toolbarButton.toggled:hover:active { - background-color: hsla(0,0%,0%,.4); - border-color: hsla(0,0%,0%,.4) hsla(0,0%,0%,.5) hsla(0,0%,0%,.55); - box-shadow: 0 1px 1px hsla(0,0%,0%,.2) inset, - 0 0 1px hsla(0,0%,0%,.3) inset, - 0 1px 0 hsla(0,0%,100%,.05); -} - -.dropdownToolbarButton { - width: 120px; - max-width: 120px; - padding: 3px 2px 2px; - overflow: hidden; - background: url(../extlib/pdf.js/web/images/toolbarButton-menuArrows.png) no-repeat; -} -html[dir='ltr'] .dropdownToolbarButton { - background-position: 95%; -} -html[dir='rtl'] .dropdownToolbarButton { - background-position: 5%; -} - -.dropdownToolbarButton > select { - -webkit-appearance: none; - -moz-appearance: none; /* in the future this might matter, see bugzilla bug #649849 */ - min-width: 140px; - font-size: 12px; - color: hsl(0,0%,95%); - margin: 0; - padding: 0; - border: none; - background: rgba(0,0,0,0); /* Opera does not support 'transparent' <select> background */ -} - -.dropdownToolbarButton > select > option { - background: hsl(0,0%,24%); -} - -#customScaleOption { - display: none; -} - -#pageWidthOption { - border-bottom: 1px rgba(255, 255, 255, .5) solid; -} - -html[dir='ltr'] .splitToolbarButton:first-child, -html[dir='ltr'] .toolbarButton:first-child, -html[dir='rtl'] .splitToolbarButton:last-child, -html[dir='rtl'] .toolbarButton:last-child { - margin-left: 4px; -} -html[dir='ltr'] .splitToolbarButton:last-child, -html[dir='ltr'] .toolbarButton:last-child, -html[dir='rtl'] .splitToolbarButton:first-child, -html[dir='rtl'] .toolbarButton:first-child { - margin-right: 4px; -} - -.toolbarButtonSpacer { - width: 30px; - display: inline-block; - height: 1px; -} - -.toolbarButtonFlexibleSpacer { - -webkit-box-flex: 1; - -moz-box-flex: 1; - min-width: 30px; -} - -.toolbarButton#sidebarToggle::before { - display: inline-block; - content: url(../extlib/pdf.js/web/images/toolbarButton-sidebarToggle.png); -} - -html[dir='ltr'] #findPrevious { - margin-left: 3px; -} -html[dir='ltr'] #findNext { - margin-right: 3px; -} - -html[dir='rtl'] #findPrevious { - margin-right: 3px; -} -html[dir='rtl'] #findNext { - margin-left: 3px; -} - -html[dir='ltr'] .toolbarButton.findPrevious::before { - display: inline-block; - content: url(../extlib/pdf.js/web/images/findbarButton-previous.png); -} - -html[dir='rtl'] .toolbarButton.findPrevious::before { - display: inline-block; - content: url(../extlib/pdf.js/web/images/findbarButton-previous-rtl.png); -} - -html[dir='ltr'] .toolbarButton.findNext::before { - display: inline-block; - content: url(../extlib/pdf.js/web/images/findbarButton-next.png); -} - -html[dir='rtl'] .toolbarButton.findNext::before { - display: inline-block; - content: url(../extlib/pdf.js/web/images/findbarButton-next-rtl.png); -} - -html[dir='ltr'] .toolbarButton.pageUp::before { - display: inline-block; - content: url(../extlib/pdf.js/web/images/toolbarButton-pageUp.png); -} - -html[dir='rtl'] .toolbarButton.pageUp::before { - display: inline-block; - content: url(../extlib/pdf.js/web/images/toolbarButton-pageUp-rtl.png); -} - -html[dir='ltr'] .toolbarButton.pageDown::before { - display: inline-block; - content: url(../extlib/pdf.js/web/images/toolbarButton-pageDown.png); -} - -html[dir='rtl'] .toolbarButton.pageDown::before { - display: inline-block; - content: url(../extlib/pdf.js/web/images/toolbarButton-pageDown-rtl.png); -} - -.toolbarButton.zoomOut::before { - display: inline-block; - content: url(../extlib/pdf.js/web/images/toolbarButton-zoomOut.png); -} - -.toolbarButton.zoomIn::before { - display: inline-block; - content: url(../extlib/pdf.js/web/images/toolbarButton-zoomIn.png); -} - -.toolbarButton.fullscreen::before { - display: inline-block; - content: url(../extlib/pdf.js/web/images/toolbarButton-fullscreen.png); -} - -.toolbarButton.print::before { - display: inline-block; - content: url(../extlib/pdf.js/web/images/toolbarButton-print.png); -} - -.toolbarButton.openFile::before { - display: inline-block; - content: url(../extlib/pdf.js/web/images/toolbarButton-openFile.png); -} - -.toolbarButton.download::before { - display: inline-block; - content: url(../extlib/pdf.js/web/images/toolbarButton-download.png); -} - -.toolbarButton.bookmark { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - margin-top: 3px; - padding-top: 4px; -} - -#viewBookmark[href='#'] { - opacity: .5; - pointer-events: none; -} - -.toolbarButton.bookmark::before { - content: url(../extlib/pdf.js/web/images/toolbarButton-bookmark.png); -} - -#viewThumbnail.toolbarButton::before { - display: inline-block; - content: url(../extlib/pdf.js/web/images/toolbarButton-viewThumbnail.png); -} - -#viewOutline.toolbarButton::before { - display: inline-block; - content: url(../extlib/pdf.js/web/images/toolbarButton-viewOutline.png); -} - -#viewFind.toolbarButton::before { - display: inline-block; - content: url(../extlib/pdf.js/web/images/toolbarButton-search.png); -} - - -.toolbarField { - padding: 3px 6px; - margin: 4px 0 4px 0; - border: 1px solid transparent; - border-radius: 2px; - background-color: hsla(0,0%,100%,.09); - background-image: -moz-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-clip: padding-box; - border: 1px solid hsla(0,0%,0%,.35); - border-color: hsla(0,0%,0%,.32) hsla(0,0%,0%,.38) hsla(0,0%,0%,.42); - box-shadow: 0 1px 0 hsla(0,0%,0%,.05) inset, - 0 1px 0 hsla(0,0%,100%,.05); - color: hsl(0,0%,95%); - font-size: 12px; - line-height: 14px; - outline-style: none; - -moz-transition-property: background-color, border-color, box-shadow; - -moz-transition-duration: 150ms; - -moz-transition-timing-function: ease; -} - -.toolbarField[type=checkbox] { - display: inline-block; - margin: 8px 0px; -} - -.toolbarField.pageNumber { - min-width: 16px; - text-align: right; - width: 40px; -} - -.toolbarField.pageNumber::-webkit-inner-spin-button, -.toolbarField.pageNumber::-webkit-outer-spin-button { - -webkit-appearance: none; - margin: 0; -} - -.toolbarField:hover { - background-color: hsla(0,0%,100%,.11); - border-color: hsla(0,0%,0%,.4) hsla(0,0%,0%,.43) hsla(0,0%,0%,.45); -} - -.toolbarField:focus { - background-color: hsla(0,0%,100%,.15); - border-color: hsla(204,100%,65%,.8) hsla(204,100%,65%,.85) hsla(204,100%,65%,.9); -} - -.toolbarLabel { - min-width: 16px; - padding: 3px 6px 3px 2px; - margin: 4px 2px 4px 0; - border: 1px solid transparent; - border-radius: 2px; - color: hsl(0,0%,85%); - font-size: 12px; - line-height: 14px; - text-align: left; - -webkit-user-select: none; - -moz-user-select: none; - cursor: default; -} - -#thumbnailView { - top: 0; - bottom: 0; - padding: 10px 10px 0; - overflow: auto; -} - -.thumbnail { - float: left; -} - -.thumbnail:not([data-loaded]) { - border: 1px dashed rgba(255, 255, 255, 0.5); - margin-bottom: 10px; -} - -.thumbnailImage { - -moz-transition-duration: 150ms; - border: 1px solid transparent; - box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.5), 0 2px 8px rgba(0, 0, 0, 0.3); - opacity: 0.8; - z-index: 99; -} - -.thumbnailSelectionRing { - border-radius: 2px; - padding: 7px; - -moz-transition-duration: 150ms; -} - -a:focus > .thumbnail > .thumbnailSelectionRing > .thumbnailImage, -.thumbnail:hover > .thumbnailSelectionRing > .thumbnailImage { - opacity: .9; -} - -a:focus > .thumbnail > .thumbnailSelectionRing, -.thumbnail:hover > .thumbnailSelectionRing { - background-color: hsla(0,0%,100%,.15); - background-image: -moz-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-clip: padding-box; - box-shadow: 0 1px 0 hsla(0,0%,100%,.05) inset, - 0 0 1px hsla(0,0%,100%,.2) inset, - 0 0 1px hsla(0,0%,0%,.2); - color: hsla(0,0%,100%,.9); -} - -.thumbnail.selected > .thumbnailSelectionRing > .thumbnailImage { - box-shadow: 0 0 0 1px hsla(0,0%,0%,.5); - opacity: 1; -} - -.thumbnail.selected > .thumbnailSelectionRing { - background-color: hsla(0,0%,100%,.3); - background-image: -moz-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-clip: padding-box; - box-shadow: 0 1px 0 hsla(0,0%,100%,.05) inset, - 0 0 1px hsla(0,0%,100%,.1) inset, - 0 0 1px hsla(0,0%,0%,.2); - color: hsla(0,0%,100%,1); -} - -#outlineView { - width: 192px; - top: 0; - bottom: 0; - padding: 4px 4px 0; - overflow: auto; - -webkit-user-select: none; - -moz-user-select: none; -} - -html[dir='ltr'] .outlineItem > .outlineItems { - margin-left: 20px; -} - -html[dir='rtl'] .outlineItem > .outlineItems { - margin-right: 20px; -} - -.outlineItem > a { - text-decoration: none; - display: inline-block; - min-width: 95%; - height: auto; - margin-bottom: 1px; - border-radius: 2px; - color: hsla(0,0%,100%,.8); - font-size: 13px; - line-height: 15px; - -moz-user-select: none; - white-space: normal; -} - -html[dir='ltr'] .outlineItem > a { - padding: 2px 0 5px 10px; -} - -html[dir='rtl'] .outlineItem > a { - padding: 2px 10px 5px 0; -} - -.outlineItem > a:hover { - background-color: hsla(0,0%,100%,.02); - background-image: -moz-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-clip: padding-box; - box-shadow: 0 1px 0 hsla(0,0%,100%,.05) inset, - 0 0 1px hsla(0,0%,100%,.2) inset, - 0 0 1px hsla(0,0%,0%,.2); - color: hsla(0,0%,100%,.9); -} - -.outlineItem.selected { - background-color: hsla(0,0%,100%,.08); - background-image: -moz-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-clip: padding-box; - box-shadow: 0 1px 0 hsla(0,0%,100%,.05) inset, - 0 0 1px hsla(0,0%,100%,.1) inset, - 0 0 1px hsla(0,0%,0%,.2); - color: hsla(0,0%,100%,1); -} - -.noOutline, -.noResults { - font-size: 12px; - color: hsla(0,0%,100%,.8); - font-style: italic; - cursor: default; -} - -#findScrollView { - position: absolute; - top: 10px; - bottom: 10px; - left: 10px; - width: 280px; -} - -#sidebarControls { - position:absolute; - width: 180px; - height: 32px; - left: 15px; - bottom: 35px; -} - -canvas { - margin: auto; - display: block; -} - -.page { - direction: ltr; - width: 816px; - height: 1056px; - margin: 1px auto -8px auto; - position: relative; - overflow: visible; - border: 9px solid transparent; - background-clip: content-box; - border-image: url(../extlib/pdf.js/web/images/shadow.png) 9 9 repeat; - background-color: white; -} - -.page > a { - display: block; - position: absolute; -} - -.page > a:hover { - opacity: 0.2; - background: #ff0; - box-shadow: 0px 2px 10px #ff0; -} - -.loadingIcon { - position: absolute; - display: block; - left: 0; - top: 0; - right: 0; - bottom: 0; - background: url('../extlib/pdf.js/web/images/loading-icon.gif') center no-repeat; -} - -#loadingBox { - position: absolute; - top: 50%; - margin-top: -25px; - left: 0; - right: 0; - text-align: center; - color: #ddd; - font-size: 14px; -} - -#loadingBar { - display: inline-block; - clear: both; - margin: 0px; - margin-top: 5px; - line-height: 0; - border-radius: 2px; - width: 200px; - height: 25px; - - background-color: hsla(0,0%,0%,.3); - background-image: -moz-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - background-image: -webkit-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); - border: 1px solid #000; - box-shadow: 0 1px 1px hsla(0,0%,0%,.1) inset, - 0 0 1px hsla(0,0%,0%,.2) inset, - 0 0 1px 1px rgba(255, 255, 255, 0.1); -} - -#loadingBar .progress { - display: inline-block; - float: left; - - background: #666; - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#b2b2b2), color-stop(100%,#898989)); - background: -webkit-linear-gradient(top, #b2b2b2 0%,#898989 100%); - background: -moz-linear-gradient(top, #b2b2b2 0%,#898989 100%); - background: -ms-linear-gradient(top, #b2b2b2 0%,#898989 100%); - background: -o-linear-gradient(top, #b2b2b2 0%,#898989 100%); - background: linear-gradient(top, #b2b2b2 0%,#898989 100%); - - border-top-left-radius: 2px; - border-bottom-left-radius: 2px; - - width: 0%; - height: 100%; -} - -#loadingBar .progress.full { - border-top-right-radius: 2px; - border-bottom-right-radius: 2px; -} - -#loadingBar .progress.indeterminate { - width: 100%; - height: 25px; - background-image: -moz-linear-gradient( 30deg, #404040, #404040 15%, #898989, #404040 85%, #404040); - background-image: -webkit-linear-gradient( 30deg, #404040, #404040 15%, #898989, #404040 85%, #404040); - background-image: -ms-linear-gradient( 30deg, #404040, #404040 15%, #898989, #404040 85%, #404040); - background-image: -o-linear-gradient( 30deg, #404040, #404040 15%, #898989, #404040 85%, #404040); - background-size: 75px 25px; - -moz-animation: progressIndeterminate 1s linear infinite; - -webkit-animation: progressIndeterminate 1s linear infinite; -} - -@-moz-keyframes progressIndeterminate { - from { background-position: 0px 0px; } - to { background-position: 75px 0px; } -} - -@-webkit-keyframes progressIndeterminate { - from { background-position: 0px 0px; } - to { background-position: 75px 0px; } -} - -.textLayer { - position: absolute; - left: 0; - top: 0; - right: 0; - bottom: 0; - color: #000; - font-family: sans-serif; - overflow: hidden; -} - -.textLayer > div { - color: transparent; - position: absolute; - line-height: 1; - white-space: pre; - cursor: text; -} - -.textLayer .highlight { - margin: -1px; - padding: 1px; - - background-color: rgba(180, 0, 170, 0.2); - border-radius: 4px; -} - -.textLayer .highlight.begin { - border-radius: 4px 0px 0px 4px; -} - -.textLayer .highlight.end { - border-radius: 0px 4px 4px 0px; -} - -.textLayer .highlight.middle { - border-radius: 0px; -} - -.textLayer .highlight.selected { - background-color: rgba(0, 100, 0, 0.2); -} - -/* TODO: file FF bug to support ::-moz-selection:window-inactive - so we can override the opaque grey background when the window is inactive; - see https://bugzilla.mozilla.org/show_bug.cgi?id=706209 */ -::selection { background:rgba(0,0,255,0.3); } -::-moz-selection { background:rgba(0,0,255,0.3); } - -.annotText > div { - z-index: 200; - position: absolute; - padding: 0.6em; - max-width: 20em; - background-color: #FFFF99; - box-shadow: 0px 2px 10px #333; - border-radius: 7px; -} - -.annotText > img { - position: absolute; - opacity: 0.6; -} - -.annotText > img:hover { - cursor: pointer; - opacity: 1; -} - -.annotText > div > h1 { - font-size: 1.2em; - border-bottom: 1px solid #000000; - margin: 0px; -} - -#errorWrapper { - background: none repeat scroll 0 0 #FF5555; - color: white; - left: 0; - position: absolute; - right: 0; - top: 32px; - z-index: 1000; - padding: 3px; - font-size: 0.8em; -} - -#errorMessageLeft { - float: left; -} - -#errorMessageRight { - float: right; -} - -#errorMoreInfo { - background-color: #FFFFFF; - color: black; - padding: 3px; - margin: 3px; - width: 98%; -} - -.clearBoth { - clear: both; -} - -.fileInput { - background: white; - color: black; - margin-top: 5px; -} - -#PDFBug { - background: none repeat scroll 0 0 white; - border: 1px solid #666666; - position: fixed; - top: 32px; - right: 0; - bottom: 0; - font-size: 10px; - padding: 0; - width: 300px; -} -#PDFBug .controls { - background:#EEEEEE; - border-bottom: 1px solid #666666; - padding: 3px; -} -#PDFBug .panels { - bottom: 0; - left: 0; - overflow: auto; - position: absolute; - right: 0; - top: 27px; -} -#PDFBug button.active { - font-weight: bold; -} -.debuggerShowText { - background: none repeat scroll 0 0 yellow; - color: blue; - opacity: 0.3; -} -.debuggerHideText:hover { - background: none repeat scroll 0 0 yellow; - opacity: 0.3; -} -#PDFBug .stats { - font-family: courier; - font-size: 10px; - white-space: pre; -} -#PDFBug .stats .title { - font-weight: bold; -} -#PDFBug table { - font-size: 10px; -} - -#viewer.textLayer-visible .textLayer > div, -#viewer.textLayer-hover .textLayer > div:hover { - background-color: white; - color: black; -} - -#viewer.textLayer-shadow .textLayer > div { - background-color: rgba(255,255,255, .6); - color: black; -} - -@page { - margin: 0; -} - -#printContainer { - display: none; -} - -@media print { - /* Rules for browsers that don't support mozPrintCallback. */ - #sidebarContainer, .toolbar, #loadingBox, #errorWrapper, .textLayer { - display: none; - } - - #mainContainer, #viewerContainer, .page, .page canvas { - position: static; - padding: 0; - margin: 0; - } - - .page { - float: left; - display: none; - box-shadow: none; - } - - .page[data-loaded] { - display: block; - } - - /* Rules for browsers that support mozPrintCallback */ - body[data-mozPrintCallback] #outerContainer { - display: none; - } - body[data-mozPrintCallback] #printContainer { - display: block; - } - #printContainer canvas { - position: relative; - top: 0; - left: 0; - } -} - -@media all and (max-width: 950px) { - html[dir='ltr'] #outerContainer.sidebarMoving .outerCenter, - html[dir='ltr'] #outerContainer.sidebarOpen .outerCenter { - float: left; - left: 180px; - } - html[dir='rtl'] #outerContainer.sidebarMoving .outerCenter, - html[dir='rtl'] #outerContainer.sidebarOpen .outerCenter { - float: right; - right: 180px; - } -} - -@media all and (max-width: 770px) { - #sidebarContainer { - top: 33px; - z-index: 100; - } - #sidebarContent { - top: 32px; - background-color: hsla(0,0%,0%,.7); - } - - html[dir='ltr'] #outerContainer.sidebarOpen > #mainContainer { - left: 0px; - } - html[dir='rtl'] #outerContainer.sidebarOpen > #mainContainer { - right: 0px; - } - - html[dir='ltr'] .outerCenter { - float: left; - left: 180px; - } - html[dir='rtl'] .outerCenter { - float: right; - right: 180px; - } -} - -@media all and (max-width: 600px) { - .hiddenSmallView { - display: none; - } - html[dir='ltr'] .outerCenter { - left: 156px; - } - html[dir='rtr'] .outerCenter { - right: 156px; - } - .toolbarButtonSpacer { - width: 0; - } -} - -@media all and (max-width: 500px) { - #scaleSelectContainer, #pageNumberLabel { - display: none; - } -} - diff --git a/mediagoblin/static/js/notifications.js b/mediagoblin/static/js/notifications.js new file mode 100644 index 00000000..0153463a --- /dev/null +++ b/mediagoblin/static/js/notifications.js @@ -0,0 +1,36 @@ +'use strict'; +/** + * 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 notifications = {}; + +(function (n) { + n._base = '/'; + n._endpoint = 'notifications/json'; + + n.init = function () { + $('.notification-gem').on('click', function () { + $('.header_dropdown_down:visible').click(); + }); + } + +})(notifications) + +$(document).ready(function () { + notifications.init(); +}); diff --git a/mediagoblin/static/js/pdf_viewer.js b/mediagoblin/static/js/pdf_viewer.js deleted file mode 100644 index 79c1e708..00000000 --- a/mediagoblin/static/js/pdf_viewer.js +++ /dev/null @@ -1,3615 +0,0 @@ -/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ -/* Copyright 2012 Mozilla Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/* globals PDFJS, PDFBug, FirefoxCom, Stats */ - -'use strict'; - -var DEFAULT_SCALE = 'auto'; -var DEFAULT_SCALE_DELTA = 1.1; -var UNKNOWN_SCALE = 0; -var CACHE_SIZE = 20; -var CSS_UNITS = 96.0 / 72.0; -var SCROLLBAR_PADDING = 40; -var VERTICAL_PADDING = 5; -var MIN_SCALE = 0.25; -var MAX_SCALE = 4.0; -var IMAGE_DIR = './images/'; -var SETTINGS_MEMORY = 20; -var ANNOT_MIN_SIZE = 10; -var RenderingStates = { - INITIAL: 0, - RUNNING: 1, - PAUSED: 2, - FINISHED: 3 -}; -var FindStates = { - FIND_FOUND: 0, - FIND_NOTFOUND: 1, - FIND_WRAPPED: 2, - FIND_PENDING: 3 -}; - -//#if (FIREFOX || MOZCENTRAL || B2G || GENERIC || CHROME) -//PDFJS.workerSrc = '../build/pdf.js'; -//#endif - -var mozL10n = document.mozL10n || document.webL10n; - -function getFileName(url) { - var anchor = url.indexOf('#'); - var query = url.indexOf('?'); - var end = Math.min( - anchor > 0 ? anchor : url.length, - query > 0 ? query : url.length); - return url.substring(url.lastIndexOf('/', end) + 1, end); -} - -function scrollIntoView(element, spot) { - // Assuming offsetParent is available (it's not available when viewer is in - // hidden iframe or object). We have to scroll: if the offsetParent is not set - // producing the error. See also animationStartedClosure. - var parent = element.offsetParent; - var offsetY = element.offsetTop + element.clientTop; - if (!parent) { - console.error('offsetParent is not set -- cannot scroll'); - return; - } - while (parent.clientHeight == parent.scrollHeight) { - offsetY += parent.offsetTop; - parent = parent.offsetParent; - if (!parent) - return; // no need to scroll - } - if (spot) - offsetY += spot.top; - parent.scrollTop = offsetY; -} - -var Cache = function cacheCache(size) { - var data = []; - this.push = function cachePush(view) { - var i = data.indexOf(view); - if (i >= 0) - data.splice(i); - data.push(view); - if (data.length > size) - data.shift().destroy(); - }; -}; - -var ProgressBar = (function ProgressBarClosure() { - - function clamp(v, min, max) { - return Math.min(Math.max(v, min), max); - } - - function ProgressBar(id, opts) { - - // Fetch the sub-elements for later - this.div = document.querySelector(id + ' .progress'); - - // Get options, with sensible defaults - this.height = opts.height || 100; - this.width = opts.width || 100; - this.units = opts.units || '%'; - - // Initialize heights - this.div.style.height = this.height + this.units; - } - - ProgressBar.prototype = { - - updateBar: function ProgressBar_updateBar() { - if (this._indeterminate) { - this.div.classList.add('indeterminate'); - return; - } - - var progressSize = this.width * this._percent / 100; - - if (this._percent > 95) - this.div.classList.add('full'); - else - this.div.classList.remove('full'); - this.div.classList.remove('indeterminate'); - - this.div.style.width = progressSize + this.units; - }, - - get percent() { - return this._percent; - }, - - set percent(val) { - this._indeterminate = isNaN(val); - this._percent = clamp(val, 0, 100); - this.updateBar(); - } - }; - - return ProgressBar; -})(); - -//#if FIREFOX || MOZCENTRAL -//#include firefoxcom.js -//#endif - -// Settings Manager - This is a utility for saving settings -// First we see if localStorage is available -// If not, we use FUEL in FF -// Use asyncStorage for B2G -var Settings = (function SettingsClosure() { -//#if !(FIREFOX || MOZCENTRAL || B2G) - var isLocalStorageEnabled = (function localStorageEnabledTest() { - // Feature test as per http://diveintohtml5.info/storage.html - // The additional localStorage call is to get around a FF quirk, see - // bug #495747 in bugzilla - try { - return 'localStorage' in window && window['localStorage'] !== null && - localStorage; - } catch (e) { - return false; - } - })(); -//#endif - - function Settings(fingerprint) { - this.fingerprint = fingerprint; - this.initializedPromise = new PDFJS.Promise(); - - var resolvePromise = (function settingsResolvePromise(db) { - this.initialize(db || '{}'); - this.initializedPromise.resolve(); - }).bind(this); - -//#if B2G -// asyncStorage.getItem('database', resolvePromise); -//#endif - -//#if FIREFOX || MOZCENTRAL -// resolvePromise(FirefoxCom.requestSync('getDatabase', null)); -//#endif - -//#if !(FIREFOX || MOZCENTRAL || B2G) - if (isLocalStorageEnabled) - resolvePromise(localStorage.getItem('database')); -//#endif - } - - Settings.prototype = { - initialize: function settingsInitialize(database) { - database = JSON.parse(database); - if (!('files' in database)) - database.files = []; - if (database.files.length >= SETTINGS_MEMORY) - database.files.shift(); - var index; - for (var i = 0, length = database.files.length; i < length; i++) { - var branch = database.files[i]; - if (branch.fingerprint == this.fingerprint) { - index = i; - break; - } - } - if (typeof index != 'number') - index = database.files.push({fingerprint: this.fingerprint}) - 1; - this.file = database.files[index]; - this.database = database; - }, - - set: function settingsSet(name, val) { - if (!this.initializedPromise.isResolved) - return; - - var file = this.file; - file[name] = val; - var database = JSON.stringify(this.database); - -//#if B2G -// asyncStorage.setItem('database', database); -//#endif - -//#if FIREFOX || MOZCENTRAL -// FirefoxCom.requestSync('setDatabase', database); -//#endif - -//#if !(FIREFOX || MOZCENTRAL || B2G) - if (isLocalStorageEnabled) - localStorage.setItem('database', database); -//#endif - }, - - get: function settingsGet(name, defaultValue) { - if (!this.initializedPromise.isResolved) - return defaultValue; - - return this.file[name] || defaultValue; - } - }; - - return Settings; -})(); - -var cache = new Cache(CACHE_SIZE); -var currentPageNumber = 1; - -var PDFFindController = { - startedTextExtraction: false, - - extractTextPromises: [], - - // If active, find results will be highlighted. - active: false, - - // Stores the text for each page. - pageContents: [], - - pageMatches: [], - - // Currently selected match. - selected: { - pageIdx: -1, - matchIdx: -1 - }, - - // Where find algorithm currently is in the document. - offset: { - pageIdx: null, - matchIdx: null - }, - - resumePageIdx: null, - - resumeCallback: null, - - state: null, - - dirtyMatch: false, - - findTimeout: null, - - initialize: function() { - var events = [ - 'find', - 'findagain', - 'findhighlightallchange', - 'findcasesensitivitychange' - ]; - - this.handleEvent = this.handleEvent.bind(this); - - for (var i = 0; i < events.length; i++) { - window.addEventListener(events[i], this.handleEvent); - } - }, - - calcFindMatch: function(pageIndex) { - var pageContent = this.pageContents[pageIndex]; - var query = this.state.query; - var caseSensitive = this.state.caseSensitive; - var queryLen = query.length; - - if (queryLen === 0) { - // Do nothing the matches should be wiped out already. - return; - } - - if (!caseSensitive) { - pageContent = pageContent.toLowerCase(); - query = query.toLowerCase(); - } - - var matches = []; - - var matchIdx = -queryLen; - while (true) { - matchIdx = pageContent.indexOf(query, matchIdx + queryLen); - if (matchIdx === -1) { - break; - } - - matches.push(matchIdx); - } - this.pageMatches[pageIndex] = matches; - this.updatePage(pageIndex); - if (this.resumePageIdx === pageIndex) { - var callback = this.resumeCallback; - this.resumePageIdx = null; - this.resumeCallback = null; - callback(); - } - }, - - extractText: function() { - if (this.startedTextExtraction) { - return; - } - this.startedTextExtraction = true; - - this.pageContents = []; - for (var i = 0, ii = PDFView.pdfDocument.numPages; i < ii; i++) { - this.extractTextPromises.push(new PDFJS.Promise()); - } - - var self = this; - function extractPageText(pageIndex) { - PDFView.pages[pageIndex].getTextContent().then( - function textContentResolved(data) { - // Build the find string. - var bidiTexts = data.bidiTexts; - var str = ''; - - for (var i = 0; i < bidiTexts.length; i++) { - str += bidiTexts[i].str; - } - - // Store the pageContent as a string. - self.pageContents.push(str); - - self.extractTextPromises[pageIndex].resolve(pageIndex); - if ((pageIndex + 1) < PDFView.pages.length) - extractPageText(pageIndex + 1); - } - ); - } - extractPageText(0); - return this.extractTextPromise; - }, - - handleEvent: function(e) { - if (this.state === null || e.type !== 'findagain') { - this.dirtyMatch = true; - } - this.state = e.detail; - this.updateUIState(FindStates.FIND_PENDING); - - this.extractText(); - - clearTimeout(this.findTimeout); - if (e.type === 'find') { - // Only trigger the find action after 250ms of silence. - this.findTimeout = setTimeout(this.nextMatch.bind(this), 250); - } else { - this.nextMatch(); - } - }, - - updatePage: function(idx) { - var page = PDFView.pages[idx]; - - if (this.selected.pageIdx === idx) { - // If the page is selected, scroll the page into view, which triggers - // rendering the page, which adds the textLayer. Once the textLayer is - // build, it will scroll onto the selected match. - page.scrollIntoView(); - } - - if (page.textLayer) { - page.textLayer.updateMatches(); - } - }, - - nextMatch: function() { - var pages = PDFView.pages; - var previous = this.state.findPrevious; - var numPages = PDFView.pages.length; - - this.active = true; - - if (this.dirtyMatch) { - // Need to recalculate the matches, reset everything. - this.dirtyMatch = false; - this.selected.pageIdx = this.selected.matchIdx = -1; - this.offset.pageIdx = previous ? numPages - 1 : 0; - this.offset.matchIdx = null; - this.hadMatch = false; - this.resumeCallback = null; - this.resumePageIdx = null; - this.pageMatches = []; - var self = this; - - for (var i = 0; i < numPages; i++) { - // Wipe out any previous highlighted matches. - this.updatePage(i); - - // As soon as the text is extracted start finding the matches. - this.extractTextPromises[i].onData(function(pageIdx) { - // Use a timeout since all the pages may already be extracted and we - // want to start highlighting before finding all the matches. - setTimeout(function() { - self.calcFindMatch(pageIdx); - }); - }); - } - } - - // If there's no query there's no point in searching. - if (this.state.query === '') { - this.updateUIState(FindStates.FIND_FOUND); - return; - } - - // If we're waiting on a page, we return since we can't do anything else. - if (this.resumeCallback) { - return; - } - - var offset = this.offset; - // If there's already a matchIdx that means we are iterating through a - // page's matches. - if (offset.matchIdx !== null) { - var numPageMatches = this.pageMatches[offset.pageIdx].length; - if ((!previous && offset.matchIdx + 1 < numPageMatches) || - (previous && offset.matchIdx > 0)) { - // The simple case, we just have advance the matchIdx to select the next - // match on the page. - this.hadMatch = true; - offset.matchIdx = previous ? offset.matchIdx - 1 : offset.matchIdx + 1; - this.updateMatch(true); - return; - } - // We went beyond the current page's matches, so we advance to the next - // page. - this.advanceOffsetPage(previous); - } - // Start searching through the page. - this.nextPageMatch(); - }, - - nextPageMatch: function() { - if (this.resumePageIdx !== null) - console.error('There can only be one pending page.'); - - var matchesReady = function(matches) { - var offset = this.offset; - var numMatches = matches.length; - var previous = this.state.findPrevious; - if (numMatches) { - // There were matches for the page, so initialize the matchIdx. - this.hadMatch = true; - offset.matchIdx = previous ? numMatches - 1 : 0; - this.updateMatch(true); - } else { - // No matches attempt to search the next page. - this.advanceOffsetPage(previous); - if (offset.wrapped) { - offset.matchIdx = null; - if (!this.hadMatch) { - // No point in wrapping there were no matches. - this.updateMatch(false); - return; - } - } - // Search the next page. - this.nextPageMatch(); - } - }.bind(this); - - var pageIdx = this.offset.pageIdx; - var pageMatches = this.pageMatches; - if (!pageMatches[pageIdx]) { - // The matches aren't ready setup a callback so we can be notified, - // when they are ready. - this.resumeCallback = function() { - matchesReady(pageMatches[pageIdx]); - }; - this.resumePageIdx = pageIdx; - return; - } - // The matches are finished already. - matchesReady(pageMatches[pageIdx]); - }, - - advanceOffsetPage: function(previous) { - var offset = this.offset; - var numPages = this.extractTextPromises.length; - offset.pageIdx = previous ? offset.pageIdx - 1 : offset.pageIdx + 1; - offset.matchIdx = null; - if (offset.pageIdx >= numPages || offset.pageIdx < 0) { - offset.pageIdx = previous ? numPages - 1 : 0; - offset.wrapped = true; - return; - } - }, - - updateMatch: function(found) { - var state = FindStates.FIND_NOTFOUND; - var wrapped = this.offset.wrapped; - this.offset.wrapped = false; - if (found) { - var previousPage = this.selected.pageIdx; - this.selected.pageIdx = this.offset.pageIdx; - this.selected.matchIdx = this.offset.matchIdx; - state = wrapped ? FindStates.FIND_WRAPPED : FindStates.FIND_FOUND; - // Update the currently selected page to wipe out any selected matches. - if (previousPage !== -1 && previousPage !== this.selected.pageIdx) { - this.updatePage(previousPage); - } - } - this.updateUIState(state, this.state.findPrevious); - if (this.selected.pageIdx !== -1) { - this.updatePage(this.selected.pageIdx, true); - } - }, - - updateUIState: function(state, previous) { - if (PDFView.supportsIntegratedFind) { - FirefoxCom.request('updateFindControlState', - {result: state, findPrevious: previous}); - return; - } - PDFFindBar.updateUIState(state, previous); - } -}; - -var PDFFindBar = { - // TODO: Enable the FindBar *AFTER* the pagesPromise in the load function - // got resolved - - opened: false, - - initialize: function() { - this.bar = document.getElementById('findbar'); - this.toggleButton = document.getElementById('viewFind'); - this.findField = document.getElementById('findInput'); - this.highlightAll = document.getElementById('findHighlightAll'); - this.caseSensitive = document.getElementById('findMatchCase'); - this.findMsg = document.getElementById('findMsg'); - this.findStatusIcon = document.getElementById('findStatusIcon'); - - var self = this; - this.toggleButton.addEventListener('click', function() { - self.toggle(); - }); - - this.findField.addEventListener('input', function() { - self.dispatchEvent(''); - }); - - this.bar.addEventListener('keydown', function(evt) { - switch (evt.keyCode) { - case 13: // Enter - if (evt.target === self.findField) { - self.dispatchEvent('again', evt.shiftKey); - } - break; - case 27: // Escape - self.close(); - break; - } - }); - - document.getElementById('findPrevious').addEventListener('click', - function() { self.dispatchEvent('again', true); } - ); - - document.getElementById('findNext').addEventListener('click', function() { - self.dispatchEvent('again', false); - }); - - this.highlightAll.addEventListener('click', function() { - self.dispatchEvent('highlightallchange'); - }); - - this.caseSensitive.addEventListener('click', function() { - self.dispatchEvent('casesensitivitychange'); - }); - }, - - dispatchEvent: function(aType, aFindPrevious) { - var event = document.createEvent('CustomEvent'); - event.initCustomEvent('find' + aType, true, true, { - query: this.findField.value, - caseSensitive: this.caseSensitive.checked, - highlightAll: this.highlightAll.checked, - findPrevious: aFindPrevious - }); - return window.dispatchEvent(event); - }, - - updateUIState: function(state, previous) { - var notFound = false; - var findMsg = ''; - var status = ''; - - switch (state) { - case FindStates.FIND_FOUND: - break; - - case FindStates.FIND_PENDING: - status = 'pending'; - break; - - case FindStates.FIND_NOTFOUND: - findMsg = mozL10n.get('find_not_found', null, 'Phrase not found'); - notFound = true; - break; - - case FindStates.FIND_WRAPPED: - if (previous) { - findMsg = mozL10n.get('find_reached_top', null, - 'Reached top of document, continued from bottom'); - } else { - findMsg = mozL10n.get('find_reached_bottom', null, - 'Reached end of document, continued from top'); - } - break; - } - - if (notFound) { - this.findField.classList.add('notFound'); - } else { - this.findField.classList.remove('notFound'); - } - - this.findField.setAttribute('data-status', status); - this.findMsg.textContent = findMsg; - }, - - open: function() { - if (this.opened) return; - - this.opened = true; - this.toggleButton.classList.add('toggled'); - this.bar.classList.remove('hidden'); - this.findField.select(); - this.findField.focus(); - }, - - close: function() { - if (!this.opened) return; - - this.opened = false; - this.toggleButton.classList.remove('toggled'); - this.bar.classList.add('hidden'); - - PDFFindController.active = false; - }, - - toggle: function() { - if (this.opened) { - this.close(); - } else { - this.open(); - } - } -}; - -var PDFView = { - pages: [], - thumbnails: [], - currentScale: UNKNOWN_SCALE, - currentScaleValue: null, - initialBookmark: document.location.hash.substring(1), - startedTextExtraction: false, - pageText: [], - container: null, - thumbnailContainer: null, - initialized: false, - fellback: false, - pdfDocument: null, - sidebarOpen: false, - pageViewScroll: null, - thumbnailViewScroll: null, - isFullscreen: false, - previousScale: null, - pageRotation: 0, - mouseScrollTimeStamp: 0, - mouseScrollDelta: 0, - lastScroll: 0, - previousPageNumber: 1, - - // called once when the document is loaded - initialize: function pdfViewInitialize() { - var self = this; - var container = this.container = document.getElementById('viewerContainer'); - this.pageViewScroll = {}; - this.watchScroll(container, this.pageViewScroll, updateViewarea); - - var thumbnailContainer = this.thumbnailContainer = - document.getElementById('thumbnailView'); - this.thumbnailViewScroll = {}; - this.watchScroll(thumbnailContainer, this.thumbnailViewScroll, - this.renderHighestPriority.bind(this)); - - PDFFindBar.initialize(); - PDFFindController.initialize(); - - this.initialized = true; - container.addEventListener('scroll', function() { - self.lastScroll = Date.now(); - }, false); - }, - - getPage: function pdfViewGetPage(n) { - return this.pdfDocument.getPage(n); - }, - - // Helper function to keep track whether a div was scrolled up or down and - // then call a callback. - watchScroll: function pdfViewWatchScroll(viewAreaElement, state, callback) { - state.down = true; - state.lastY = viewAreaElement.scrollTop; - viewAreaElement.addEventListener('scroll', function webViewerScroll(evt) { - var currentY = viewAreaElement.scrollTop; - var lastY = state.lastY; - if (currentY > lastY) - state.down = true; - else if (currentY < lastY) - state.down = false; - // else do nothing and use previous value - state.lastY = currentY; - callback(); - }, true); - }, - - setScale: function pdfViewSetScale(val, resetAutoSettings, noScroll) { - if (val == this.currentScale) - return; - - var pages = this.pages; - for (var i = 0; i < pages.length; i++) - pages[i].update(val * CSS_UNITS); - - if (!noScroll && this.currentScale != val) - this.pages[this.page - 1].scrollIntoView(); - this.currentScale = val; - - var event = document.createEvent('UIEvents'); - event.initUIEvent('scalechange', false, false, window, 0); - event.scale = val; - event.resetAutoSettings = resetAutoSettings; - window.dispatchEvent(event); - }, - - parseScale: function pdfViewParseScale(value, resetAutoSettings, noScroll) { - if ('custom' == value) - return; - - var scale = parseFloat(value); - this.currentScaleValue = value; - if (scale) { - this.setScale(scale, true, noScroll); - return; - } - - var container = this.container; - var currentPage = this.pages[this.page - 1]; - if (!currentPage) { - return; - } - - var pageWidthScale = (container.clientWidth - SCROLLBAR_PADDING) / - currentPage.width * currentPage.scale / CSS_UNITS; - var pageHeightScale = (container.clientHeight - VERTICAL_PADDING) / - currentPage.height * currentPage.scale / CSS_UNITS; - switch (value) { - case 'page-actual': - scale = 1; - break; - case 'page-width': - scale = pageWidthScale; - break; - case 'page-height': - scale = pageHeightScale; - break; - case 'page-fit': - scale = Math.min(pageWidthScale, pageHeightScale); - break; - case 'auto': - scale = Math.min(1.0, pageWidthScale); - break; - } - this.setScale(scale, resetAutoSettings, noScroll); - - selectScaleOption(value); - }, - - zoomIn: function pdfViewZoomIn() { - var newScale = (this.currentScale * DEFAULT_SCALE_DELTA).toFixed(2); - newScale = Math.ceil(newScale * 10) / 10; - newScale = Math.min(MAX_SCALE, newScale); - this.parseScale(newScale, true); - }, - - zoomOut: function pdfViewZoomOut() { - var newScale = (this.currentScale / DEFAULT_SCALE_DELTA).toFixed(2); - newScale = Math.floor(newScale * 10) / 10; - newScale = Math.max(MIN_SCALE, newScale); - this.parseScale(newScale, true); - }, - - set page(val) { - var pages = this.pages; - var input = document.getElementById('pageNumber'); - var event = document.createEvent('UIEvents'); - event.initUIEvent('pagechange', false, false, window, 0); - - if (!(0 < val && val <= pages.length)) { - this.previousPageNumber = val; - event.pageNumber = this.page; - window.dispatchEvent(event); - return; - } - - pages[val - 1].updateStats(); - this.previousPageNumber = currentPageNumber; - currentPageNumber = val; - event.pageNumber = val; - window.dispatchEvent(event); - - // checking if the this.page was called from the updateViewarea function: - // avoiding the creation of two "set page" method (internal and public) - if (updateViewarea.inProgress) - return; - - // Avoid scrolling the first page during loading - if (this.loading && val == 1) - return; - - pages[val - 1].scrollIntoView(); - }, - - get page() { - return currentPageNumber; - }, - - get supportsPrinting() { - var canvas = document.createElement('canvas'); - var value = 'mozPrintCallback' in canvas; - // shadow - Object.defineProperty(this, 'supportsPrinting', { value: value, - enumerable: true, - configurable: true, - writable: false }); - return value; - }, - - get supportsFullscreen() { - var doc = document.documentElement; - var support = doc.requestFullscreen || doc.mozRequestFullScreen || - doc.webkitRequestFullScreen; - - // Disable fullscreen button if we're in an iframe - if (!!window.frameElement) - support = false; - - Object.defineProperty(this, 'supportsFullScreen', { value: support, - enumerable: true, - configurable: true, - writable: false }); - return support; - }, - - get supportsIntegratedFind() { - var support = false; -//#if !(FIREFOX || MOZCENTRAL) -//#else -// support = FirefoxCom.requestSync('supportsIntegratedFind'); -//#endif - Object.defineProperty(this, 'supportsIntegratedFind', { value: support, - enumerable: true, - configurable: true, - writable: false }); - return support; - }, - - get supportsDocumentFonts() { - var support = true; -//#if !(FIREFOX || MOZCENTRAL) -//#else -// support = FirefoxCom.requestSync('supportsDocumentFonts'); -//#endif - Object.defineProperty(this, 'supportsDocumentFonts', { value: support, - enumerable: true, - configurable: true, - writable: false }); - return support; - }, - - get isHorizontalScrollbarEnabled() { - var div = document.getElementById('viewerContainer'); - return div.scrollWidth > div.clientWidth; - }, - - initPassiveLoading: function pdfViewInitPassiveLoading() { - if (!PDFView.loadingBar) { - PDFView.loadingBar = new ProgressBar('#loadingBar', {}); - } - - window.addEventListener('message', function window_message(e) { - var args = e.data; - - if (typeof args !== 'object' || !('pdfjsLoadAction' in args)) - return; - switch (args.pdfjsLoadAction) { - case 'progress': - PDFView.progress(args.loaded / args.total); - break; - case 'complete': - if (!args.data) { - PDFView.error(mozL10n.get('loading_error', null, - 'An error occurred while loading the PDF.'), e); - break; - } - PDFView.open(args.data, 0); - break; - } - }); - FirefoxCom.requestSync('initPassiveLoading', null); - }, - - setTitleUsingUrl: function pdfViewSetTitleUsingUrl(url) { - this.url = url; - try { - this.setTitle(decodeURIComponent(getFileName(url)) || url); - } catch (e) { - // decodeURIComponent may throw URIError, - // fall back to using the unprocessed url in that case - this.setTitle(url); - } - }, - - setTitle: function pdfViewSetTitle(title) { - document.title = title; -//#if B2G -// document.getElementById('activityTitle').textContent = title; -//#endif - }, - - open: function pdfViewOpen(url, scale, password) { - var parameters = {password: password}; - if (typeof url === 'string') { // URL - this.setTitleUsingUrl(url); - parameters.url = url; - } else if (url && 'byteLength' in url) { // ArrayBuffer - parameters.data = url; - } - - if (!PDFView.loadingBar) { - PDFView.loadingBar = new ProgressBar('#loadingBar', {}); - } - - this.pdfDocument = null; - var self = this; - self.loading = true; - PDFJS.getDocument(parameters).then( - function getDocumentCallback(pdfDocument) { - self.load(pdfDocument, scale); - self.loading = false; - }, - function getDocumentError(message, exception) { - if (exception && exception.name === 'PasswordException') { - if (exception.code === 'needpassword') { - var promptString = mozL10n.get('request_password', null, - 'PDF is protected by a password:'); - password = prompt(promptString); - if (password && password.length > 0) { - return PDFView.open(url, scale, password); - } - } - } - - var loadingErrorMessage = mozL10n.get('loading_error', null, - 'An error occurred while loading the PDF.'); - - if (exception && exception.name === 'InvalidPDFException') { - // change error message also for other builds - var loadingErrorMessage = mozL10n.get('invalid_file_error', null, - 'Invalid or corrupted PDF file.'); -//#if B2G -// window.alert(loadingErrorMessage); -// return window.close(); -//#endif - } - - if (exception && exception.name === 'MissingPDFException') { - // special message for missing PDF's - var loadingErrorMessage = mozL10n.get('missing_file_error', null, - 'Missing PDF file.'); - -//#if B2G -// window.alert(loadingErrorMessage); -// return window.close(); -//#endif - } - - var loadingIndicator = document.getElementById('loading'); - loadingIndicator.textContent = mozL10n.get('loading_error_indicator', - null, 'Error'); - var moreInfo = { - message: message - }; - self.error(loadingErrorMessage, moreInfo); - self.loading = false; - }, - function getDocumentProgress(progressData) { - self.progress(progressData.loaded / progressData.total); - } - ); - }, - - download: function pdfViewDownload() { - function noData() { - FirefoxCom.request('download', { originalUrl: url }); - } - var url = this.url.split('#')[0]; -//#if !(FIREFOX || MOZCENTRAL) - url += '#pdfjs.action=download'; - window.open(url, '_parent'); -//#else -// // Document isn't ready just try to download with the url. -// if (!this.pdfDocument) { -// noData(); -// return; -// } -// this.pdfDocument.getData().then( -// function getDataSuccess(data) { -// var blob = PDFJS.createBlob(data.buffer, 'application/pdf'); -// var blobUrl = window.URL.createObjectURL(blob); -// -// FirefoxCom.request('download', { blobUrl: blobUrl, originalUrl: url }, -// function response(err) { -// if (err) { -// // This error won't really be helpful because it's likely the -// // fallback won't work either (or is already open). -// PDFView.error('PDF failed to download.'); -// } -// window.URL.revokeObjectURL(blobUrl); -// } -// ); -// }, -// noData // Error occurred try downloading with just the url. -// ); -//#endif - }, - - fallback: function pdfViewFallback() { -//#if !(FIREFOX || MOZCENTRAL) -// return; -//#else -// // Only trigger the fallback once so we don't spam the user with messages -// // for one PDF. -// if (this.fellback) -// return; -// this.fellback = true; -// var url = this.url.split('#')[0]; -// FirefoxCom.request('fallback', url, function response(download) { -// if (!download) -// return; -// PDFView.download(); -// }); -//#endif - }, - - navigateTo: function pdfViewNavigateTo(dest) { - if (typeof dest === 'string') - dest = this.destinations[dest]; - if (!(dest instanceof Array)) - return; // invalid destination - // dest array looks like that: <page-ref> </XYZ|FitXXX> <args..> - var destRef = dest[0]; - var pageNumber = destRef instanceof Object ? - this.pagesRefMap[destRef.num + ' ' + destRef.gen + ' R'] : (destRef + 1); - if (pageNumber > this.pages.length) - pageNumber = this.pages.length; - if (pageNumber) { - this.page = pageNumber; - var currentPage = this.pages[pageNumber - 1]; - if (!this.isFullscreen) { // Avoid breaking fullscreen mode. - currentPage.scrollIntoView(dest); - } - } - }, - - getDestinationHash: function pdfViewGetDestinationHash(dest) { - if (typeof dest === 'string') - return PDFView.getAnchorUrl('#' + escape(dest)); - if (dest instanceof Array) { - var destRef = dest[0]; // see navigateTo method for dest format - var pageNumber = destRef instanceof Object ? - this.pagesRefMap[destRef.num + ' ' + destRef.gen + ' R'] : - (destRef + 1); - if (pageNumber) { - var pdfOpenParams = PDFView.getAnchorUrl('#page=' + pageNumber); - var destKind = dest[1]; - if (typeof destKind === 'object' && 'name' in destKind && - destKind.name == 'XYZ') { - var scale = (dest[4] || this.currentScale); - pdfOpenParams += '&zoom=' + (scale * 100); - if (dest[2] || dest[3]) { - pdfOpenParams += ',' + (dest[2] || 0) + ',' + (dest[3] || 0); - } - } - return pdfOpenParams; - } - } - return ''; - }, - - /** - * For the firefox extension we prefix the full url on anchor links so they - * don't come up as resource:// urls and so open in new tab/window works. - * @param {String} anchor The anchor hash include the #. - */ - getAnchorUrl: function getAnchorUrl(anchor) { -//#if !(FIREFOX || MOZCENTRAL) - return anchor; -//#else -// return this.url.split('#')[0] + anchor; -//#endif - }, - - /** - * Returns scale factor for the canvas. It makes sense for the HiDPI displays. - * @return {Object} The object with horizontal (sx) and vertical (sy) - scales. The scaled property is set to false if scaling is - not required, true otherwise. - */ - getOutputScale: function pdfViewGetOutputDPI() { - var pixelRatio = 'devicePixelRatio' in window ? window.devicePixelRatio : 1; - return { - sx: pixelRatio, - sy: pixelRatio, - scaled: pixelRatio != 1 - }; - }, - - /** - * Show the error box. - * @param {String} message A message that is human readable. - * @param {Object} moreInfo (optional) Further information about the error - * that is more technical. Should have a 'message' - * and optionally a 'stack' property. - */ - error: function pdfViewError(message, moreInfo) { - var moreInfoText = mozL10n.get('error_version_info', - {version: PDFJS.version || '?', build: PDFJS.build || '?'}, - 'PDF.js v{{version}} (build: {{build}})') + '\n'; - if (moreInfo) { - moreInfoText += - mozL10n.get('error_message', {message: moreInfo.message}, - 'Message: {{message}}'); - if (moreInfo.stack) { - moreInfoText += '\n' + - mozL10n.get('error_stack', {stack: moreInfo.stack}, - 'Stack: {{stack}}'); - } else { - if (moreInfo.filename) { - moreInfoText += '\n' + - mozL10n.get('error_file', {file: moreInfo.filename}, - 'File: {{file}}'); - } - if (moreInfo.lineNumber) { - moreInfoText += '\n' + - mozL10n.get('error_line', {line: moreInfo.lineNumber}, - 'Line: {{line}}'); - } - } - } - - var loadingBox = document.getElementById('loadingBox'); - loadingBox.setAttribute('hidden', 'true'); - -//#if !(FIREFOX || MOZCENTRAL) - var errorWrapper = document.getElementById('errorWrapper'); - errorWrapper.removeAttribute('hidden'); - - var errorMessage = document.getElementById('errorMessage'); - errorMessage.textContent = message; - - var closeButton = document.getElementById('errorClose'); - closeButton.onclick = function() { - errorWrapper.setAttribute('hidden', 'true'); - }; - - var errorMoreInfo = document.getElementById('errorMoreInfo'); - var moreInfoButton = document.getElementById('errorShowMore'); - var lessInfoButton = document.getElementById('errorShowLess'); - moreInfoButton.onclick = function() { - errorMoreInfo.removeAttribute('hidden'); - moreInfoButton.setAttribute('hidden', 'true'); - lessInfoButton.removeAttribute('hidden'); - }; - lessInfoButton.onclick = function() { - errorMoreInfo.setAttribute('hidden', 'true'); - moreInfoButton.removeAttribute('hidden'); - lessInfoButton.setAttribute('hidden', 'true'); - }; - moreInfoButton.removeAttribute('hidden'); - lessInfoButton.setAttribute('hidden', 'true'); - errorMoreInfo.value = moreInfoText; - - errorMoreInfo.rows = moreInfoText.split('\n').length - 1; -//#else -// console.error(message + '\n' + moreInfoText); -// this.fallback(); -//#endif - }, - - progress: function pdfViewProgress(level) { - var percent = Math.round(level * 100); - PDFView.loadingBar.percent = percent; - }, - - load: function pdfViewLoad(pdfDocument, scale) { - function bindOnAfterDraw(pageView, thumbnailView) { - // when page is painted, using the image as thumbnail base - pageView.onAfterDraw = function pdfViewLoadOnAfterDraw() { - thumbnailView.setImage(pageView.canvas); - }; - } - - this.pdfDocument = pdfDocument; - - var errorWrapper = document.getElementById('errorWrapper'); - errorWrapper.setAttribute('hidden', 'true'); - - var loadingBox = document.getElementById('loadingBox'); - loadingBox.setAttribute('hidden', 'true'); - var loadingIndicator = document.getElementById('loading'); - loadingIndicator.textContent = ''; - - var thumbsView = document.getElementById('thumbnailView'); - thumbsView.parentNode.scrollTop = 0; - - while (thumbsView.hasChildNodes()) - thumbsView.removeChild(thumbsView.lastChild); - - if ('_loadingInterval' in thumbsView) - clearInterval(thumbsView._loadingInterval); - - var container = document.getElementById('viewer'); - while (container.hasChildNodes()) - container.removeChild(container.lastChild); - - var pagesCount = pdfDocument.numPages; - var id = pdfDocument.fingerprint; - document.getElementById('numPages').textContent = - mozL10n.get('page_of', {pageCount: pagesCount}, 'of {{pageCount}}'); - document.getElementById('pageNumber').max = pagesCount; - - PDFView.documentFingerprint = id; - var store = PDFView.store = new Settings(id); - - this.pageRotation = 0; - - var pages = this.pages = []; - this.pageText = []; - this.startedTextExtraction = false; - var pagesRefMap = this.pagesRefMap = {}; - var thumbnails = this.thumbnails = []; - - var pagesPromise = new PDFJS.Promise(); - var self = this; - - var firstPagePromise = pdfDocument.getPage(1); - - // Fetch a single page so we can get a viewport that will be the default - // viewport for all pages - firstPagePromise.then(function(pdfPage) { - var viewport = pdfPage.getViewport(scale || 1.0); - var pagePromises = []; - for (var pageNum = 1; pageNum <= pagesCount; ++pageNum) { - var viewportClone = viewport.clone(); - var pageView = new PageView(container, pageNum, scale, - self.navigateTo.bind(self), - viewportClone); - var thumbnailView = new ThumbnailView(thumbsView, pageNum, - viewportClone); - bindOnAfterDraw(pageView, thumbnailView); - pages.push(pageView); - thumbnails.push(thumbnailView); - } - - var event = document.createEvent('CustomEvent'); - event.initCustomEvent('documentload', true, true, {}); - window.dispatchEvent(event); - - for (var pageNum = 1; pageNum <= pagesCount; ++pageNum) { - var pagePromise = pdfDocument.getPage(pageNum); - pagePromise.then(function(pdfPage) { - var pageNum = pdfPage.pageNumber; - var pageView = pages[pageNum - 1]; - if (!pageView.pdfPage) { - // The pdfPage might already be set if we've already entered - // pageView.draw() - pageView.setPdfPage(pdfPage); - } - var thumbnailView = thumbnails[pageNum - 1]; - if (!thumbnailView.pdfPage) { - thumbnailView.setPdfPage(pdfPage); - } - - var pageRef = pdfPage.ref; - var refStr = pageRef.num + ' ' + pageRef.gen + ' R'; - pagesRefMap[refStr] = pdfPage.pageNumber; - }); - pagePromises.push(pagePromise); - } - - PDFJS.Promise.all(pagePromises).then(function(pages) { - pagesPromise.resolve(pages); - }); - }); - - var storePromise = store.initializedPromise; - PDFJS.Promise.all([firstPagePromise, storePromise]).then(function() { - var storedHash = null; - if (store.get('exists', false)) { - var pageNum = store.get('page', '1'); - var zoom = store.get('zoom', PDFView.currentScale); - var left = store.get('scrollLeft', '0'); - var top = store.get('scrollTop', '0'); - - storedHash = 'page=' + pageNum + '&zoom=' + zoom + ',' + - left + ',' + top; - } - self.setInitialView(storedHash, scale); - }); - - pagesPromise.then(function() { - if (PDFView.supportsPrinting) { - pdfDocument.getJavaScript().then(function(javaScript) { - if (javaScript.length) { - console.warn('Warning: JavaScript is not supported'); - PDFView.fallback(); - } - // Hack to support auto printing. - var regex = /\bprint\s*\(/g; - for (var i = 0, ii = javaScript.length; i < ii; i++) { - var js = javaScript[i]; - if (js && regex.test(js)) { - setTimeout(function() { - window.print(); - }); - return; - } - } - }); - } - }); - - var destinationsPromise = pdfDocument.getDestinations(); - destinationsPromise.then(function(destinations) { - self.destinations = destinations; - }); - - // outline depends on destinations and pagesRefMap - var promises = [pagesPromise, destinationsPromise, - PDFView.animationStartedPromise]; - PDFJS.Promise.all(promises).then(function() { - pdfDocument.getOutline().then(function(outline) { - self.outline = new DocumentOutlineView(outline); - }); - - // Make all navigation keys work on document load, - // unless the viewer is embedded in another page. - if (window.parent.location === window.location) { - PDFView.container.focus(); - } - }); - - pdfDocument.getMetadata().then(function(data) { - var info = data.info, metadata = data.metadata; - self.documentInfo = info; - self.metadata = metadata; - - // Provides some basic debug information - console.log('PDF ' + pdfDocument.fingerprint + ' [' + - info.PDFFormatVersion + ' ' + (info.Producer || '-') + - ' / ' + (info.Creator || '-') + ']' + - (PDFJS.version ? ' (PDF.js: ' + PDFJS.version + ')' : '')); - - var pdfTitle; - if (metadata) { - if (metadata.has('dc:title')) - pdfTitle = metadata.get('dc:title'); - } - - if (!pdfTitle && info && info['Title']) - pdfTitle = info['Title']; - - if (pdfTitle) - self.setTitle(pdfTitle + ' - ' + document.title); - - if (info.IsAcroFormPresent) { - console.warn('Warning: AcroForm/XFA is not supported'); - PDFView.fallback(); - } - }); - }, - - setInitialView: function pdfViewSetInitialView(storedHash, scale) { - // Reset the current scale, as otherwise the page's scale might not get - // updated if the zoom level stayed the same. - this.currentScale = 0; - this.currentScaleValue = null; - if (this.initialBookmark) { - this.setHash(this.initialBookmark); - this.initialBookmark = null; - } - else if (storedHash) - this.setHash(storedHash); - else if (scale) { - this.parseScale(scale, true); - this.page = 1; - } - - if (PDFView.currentScale === UNKNOWN_SCALE) { - // Scale was not initialized: invalid bookmark or scale was not specified. - // Setting the default one. - this.parseScale(DEFAULT_SCALE, true); - } - }, - - renderHighestPriority: function pdfViewRenderHighestPriority() { - // Pages have a higher priority than thumbnails, so check them first. - var visiblePages = this.getVisiblePages(); - var pageView = this.getHighestPriority(visiblePages, this.pages, - this.pageViewScroll.down); - if (pageView) { - this.renderView(pageView, 'page'); - return; - } - // No pages needed rendering so check thumbnails. - if (this.sidebarOpen) { - var visibleThumbs = this.getVisibleThumbs(); - var thumbView = this.getHighestPriority(visibleThumbs, - this.thumbnails, - this.thumbnailViewScroll.down); - if (thumbView) - this.renderView(thumbView, 'thumbnail'); - } - }, - - getHighestPriority: function pdfViewGetHighestPriority(visible, views, - scrolledDown) { - // The state has changed figure out which page has the highest priority to - // render next (if any). - // Priority: - // 1 visible pages - // 2 if last scrolled down page after the visible pages - // 2 if last scrolled up page before the visible pages - var visibleViews = visible.views; - - var numVisible = visibleViews.length; - if (numVisible === 0) { - return false; - } - for (var i = 0; i < numVisible; ++i) { - var view = visibleViews[i].view; - if (!this.isViewFinished(view)) - return view; - } - - // All the visible views have rendered, try to render next/previous pages. - if (scrolledDown) { - var nextPageIndex = visible.last.id; - // ID's start at 1 so no need to add 1. - if (views[nextPageIndex] && !this.isViewFinished(views[nextPageIndex])) - return views[nextPageIndex]; - } else { - var previousPageIndex = visible.first.id - 2; - if (views[previousPageIndex] && - !this.isViewFinished(views[previousPageIndex])) - return views[previousPageIndex]; - } - // Everything that needs to be rendered has been. - return false; - }, - - isViewFinished: function pdfViewNeedsRendering(view) { - return view.renderingState === RenderingStates.FINISHED; - }, - - // Render a page or thumbnail view. This calls the appropriate function based - // on the views state. If the view is already rendered it will return false. - renderView: function pdfViewRender(view, type) { - var state = view.renderingState; - switch (state) { - case RenderingStates.FINISHED: - return false; - case RenderingStates.PAUSED: - PDFView.highestPriorityPage = type + view.id; - view.resume(); - break; - case RenderingStates.RUNNING: - PDFView.highestPriorityPage = type + view.id; - break; - case RenderingStates.INITIAL: - PDFView.highestPriorityPage = type + view.id; - view.draw(this.renderHighestPriority.bind(this)); - break; - } - return true; - }, - - setHash: function pdfViewSetHash(hash) { - if (!hash) - return; - - if (hash.indexOf('=') >= 0) { - var params = PDFView.parseQueryString(hash); - // borrowing syntax from "Parameters for Opening PDF Files" - if ('nameddest' in params) { - PDFView.navigateTo(params.nameddest); - return; - } - if ('page' in params) { - var pageNumber = (params.page | 0) || 1; - if ('zoom' in params) { - var zoomArgs = params.zoom.split(','); // scale,left,top - // building destination array - - // If the zoom value, it has to get divided by 100. If it is a string, - // it should stay as it is. - var zoomArg = zoomArgs[0]; - var zoomArgNumber = parseFloat(zoomArg); - if (zoomArgNumber) - zoomArg = zoomArgNumber / 100; - - var dest = [null, {name: 'XYZ'}, - zoomArgs.length > 1 ? (zoomArgs[1] | 0) : null, - zoomArgs.length > 2 ? (zoomArgs[2] | 0) : null, - zoomArg]; - var currentPage = this.pages[pageNumber - 1]; - currentPage.scrollIntoView(dest); - } else { - this.page = pageNumber; // simple page - } - } - if ('pagemode' in params) { - var toggle = document.getElementById('sidebarToggle'); - if (params.pagemode === 'thumbs' || params.pagemode === 'bookmarks') { - if (!this.sidebarOpen) { - toggle.click(); - } - this.switchSidebarView(params.pagemode === 'thumbs' ? - 'thumbs' : 'outline'); - } else if (params.pagemode === 'none' && this.sidebarOpen) { - toggle.click(); - } - } - } else if (/^\d+$/.test(hash)) // page number - this.page = hash; - else // named destination - PDFView.navigateTo(unescape(hash)); - }, - - switchSidebarView: function pdfViewSwitchSidebarView(view) { - var thumbsView = document.getElementById('thumbnailView'); - var outlineView = document.getElementById('outlineView'); - - var thumbsButton = document.getElementById('viewThumbnail'); - var outlineButton = document.getElementById('viewOutline'); - - switch (view) { - case 'thumbs': - var wasOutlineViewVisible = thumbsView.classList.contains('hidden'); - - thumbsButton.classList.add('toggled'); - outlineButton.classList.remove('toggled'); - thumbsView.classList.remove('hidden'); - outlineView.classList.add('hidden'); - - PDFView.renderHighestPriority(); - - if (wasOutlineViewVisible) { - // Ensure that the thumbnail of the current page is visible - // when switching from the outline view. - scrollIntoView(document.getElementById('thumbnailContainer' + - this.page)); - } - break; - - case 'outline': - thumbsButton.classList.remove('toggled'); - outlineButton.classList.add('toggled'); - thumbsView.classList.add('hidden'); - outlineView.classList.remove('hidden'); - - if (outlineButton.getAttribute('disabled')) - return; - break; - } - }, - - getVisiblePages: function pdfViewGetVisiblePages() { - if (!this.isFullscreen) { - return this.getVisibleElements(this.container, this.pages, true); - } else { - // The algorithm in getVisibleElements is broken in fullscreen mode. - var visible = [], page = this.page; - var currentPage = this.pages[page - 1]; - visible.push({ id: currentPage.id, view: currentPage }); - - return { first: currentPage, last: currentPage, views: visible}; - } - }, - - getVisibleThumbs: function pdfViewGetVisibleThumbs() { - return this.getVisibleElements(this.thumbnailContainer, this.thumbnails); - }, - - // Generic helper to find out what elements are visible within a scroll pane. - getVisibleElements: function pdfViewGetVisibleElements( - scrollEl, views, sortByVisibility) { - var top = scrollEl.scrollTop, bottom = top + scrollEl.clientHeight; - var left = scrollEl.scrollLeft, right = left + scrollEl.clientWidth; - - var visible = [], view; - var currentHeight, viewHeight, hiddenHeight, percentHeight; - var currentWidth, viewWidth; - for (var i = 0, ii = views.length; i < ii; ++i) { - view = views[i]; - currentHeight = view.el.offsetTop + view.el.clientTop; - viewHeight = view.el.clientHeight; - if ((currentHeight + viewHeight) < top) { - continue; - } - if (currentHeight > bottom) { - break; - } - currentWidth = view.el.offsetLeft + view.el.clientLeft; - viewWidth = view.el.clientWidth; - if ((currentWidth + viewWidth) < left || currentWidth > right) { - continue; - } - hiddenHeight = Math.max(0, top - currentHeight) + - Math.max(0, currentHeight + viewHeight - bottom); - percentHeight = ((viewHeight - hiddenHeight) * 100 / viewHeight) | 0; - - visible.push({ id: view.id, y: currentHeight, - view: view, percent: percentHeight }); - } - - var first = visible[0]; - var last = visible[visible.length - 1]; - - if (sortByVisibility) { - visible.sort(function(a, b) { - var pc = a.percent - b.percent; - if (Math.abs(pc) > 0.001) { - return -pc; - } - return a.id - b.id; // ensure stability - }); - } - return {first: first, last: last, views: visible}; - }, - - // Helper function to parse query string (e.g. ?param1=value&parm2=...). - parseQueryString: function pdfViewParseQueryString(query) { - var parts = query.split('&'); - var params = {}; - for (var i = 0, ii = parts.length; i < parts.length; ++i) { - var param = parts[i].split('='); - var key = param[0]; - var value = param.length > 1 ? param[1] : null; - params[unescape(key)] = unescape(value); - } - return params; - }, - - beforePrint: function pdfViewSetupBeforePrint() { - if (!this.supportsPrinting) { - var printMessage = mozL10n.get('printing_not_supported', null, - 'Warning: Printing is not fully supported by this browser.'); - this.error(printMessage); - return; - } - - var alertNotReady = false; - if (!this.pages.length) { - alertNotReady = true; - } else { - for (var i = 0, ii = this.pages.length; i < ii; ++i) { - if (!this.pages[i].pdfPage) { - alertNotReady = true; - break; - } - } - } - if (alertNotReady) { - var notReadyMessage = mozL10n.get('printing_not_ready', null, - 'Warning: The PDF is not fully loaded for printing.'); - window.alert(notReadyMessage); - return; - } - - var body = document.querySelector('body'); - body.setAttribute('data-mozPrintCallback', true); - for (var i = 0, ii = this.pages.length; i < ii; ++i) { - this.pages[i].beforePrint(); - } - }, - - afterPrint: function pdfViewSetupAfterPrint() { - var div = document.getElementById('printContainer'); - while (div.hasChildNodes()) - div.removeChild(div.lastChild); - }, - - fullscreen: function pdfViewFullscreen() { - var isFullscreen = document.fullscreenElement || document.mozFullScreen || - document.webkitIsFullScreen; - - if (isFullscreen) { - return false; - } - - var wrapper = document.getElementById('viewerContainer'); - if (document.documentElement.requestFullscreen) { - wrapper.requestFullscreen(); - } else if (document.documentElement.mozRequestFullScreen) { - wrapper.mozRequestFullScreen(); - } else if (document.documentElement.webkitRequestFullScreen) { - wrapper.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT); - } else { - return false; - } - - this.isFullscreen = true; - var currentPage = this.pages[this.page - 1]; - this.previousScale = this.currentScaleValue; - this.parseScale('page-fit', true); - - // Wait for fullscreen to take effect - setTimeout(function() { - currentPage.scrollIntoView(); - }, 0); - - this.showPresentationControls(); - return true; - }, - - exitFullscreen: function pdfViewExitFullscreen() { - this.isFullscreen = false; - this.parseScale(this.previousScale); - this.page = this.page; - this.clearMouseScrollState(); - this.hidePresentationControls(); - - // Ensure that the thumbnail of the current page is visible - // when exiting fullscreen mode. - scrollIntoView(document.getElementById('thumbnailContainer' + this.page)); - }, - - showPresentationControls: function pdfViewShowPresentationControls() { - var DELAY_BEFORE_HIDING_CONTROLS = 3000; - var wrapper = document.getElementById('viewerContainer'); - if (this.presentationControlsTimeout) { - clearTimeout(this.presentationControlsTimeout); - } else { - wrapper.classList.add('presentationControls'); - } - this.presentationControlsTimeout = setTimeout(function hideControls() { - wrapper.classList.remove('presentationControls'); - delete PDFView.presentationControlsTimeout; - }, DELAY_BEFORE_HIDING_CONTROLS); - }, - - hidePresentationControls: function pdfViewShowPresentationControls() { - if (!this.presentationControlsTimeout) { - return; - } - clearTimeout(this.presentationControlsTimeout); - delete this.presentationControlsTimeout; - - var wrapper = document.getElementById('viewerContainer'); - wrapper.classList.remove('presentationControls'); - }, - - rotatePages: function pdfViewPageRotation(delta) { - - this.pageRotation = (this.pageRotation + 360 + delta) % 360; - - for (var i = 0, l = this.pages.length; i < l; i++) { - var page = this.pages[i]; - page.update(page.scale, this.pageRotation); - } - - for (var i = 0, l = this.thumbnails.length; i < l; i++) { - var thumb = this.thumbnails[i]; - thumb.update(this.pageRotation); - } - - this.parseScale(this.currentScaleValue, true); - - this.renderHighestPriority(); - - var currentPage = this.pages[this.page - 1]; - if (!currentPage) { - return; - } - - // Wait for fullscreen to take effect - setTimeout(function() { - currentPage.scrollIntoView(); - }, 0); - }, - - /** - * This function flips the page in presentation mode if the user scrolls up - * or down with large enough motion and prevents page flipping too often. - * - * @this {PDFView} - * @param {number} mouseScrollDelta The delta value from the mouse event. - */ - mouseScroll: function pdfViewMouseScroll(mouseScrollDelta) { - var MOUSE_SCROLL_COOLDOWN_TIME = 50; - - var currentTime = (new Date()).getTime(); - var storedTime = this.mouseScrollTimeStamp; - - // In case one page has already been flipped there is a cooldown time - // which has to expire before next page can be scrolled on to. - if (currentTime > storedTime && - currentTime - storedTime < MOUSE_SCROLL_COOLDOWN_TIME) - return; - - // In case the user decides to scroll to the opposite direction than before - // clear the accumulated delta. - if ((this.mouseScrollDelta > 0 && mouseScrollDelta < 0) || - (this.mouseScrollDelta < 0 && mouseScrollDelta > 0)) - this.clearMouseScrollState(); - - this.mouseScrollDelta += mouseScrollDelta; - - var PAGE_FLIP_THRESHOLD = 120; - if (Math.abs(this.mouseScrollDelta) >= PAGE_FLIP_THRESHOLD) { - - var PageFlipDirection = { - UP: -1, - DOWN: 1 - }; - - // In fullscreen mode scroll one page at a time. - var pageFlipDirection = (this.mouseScrollDelta > 0) ? - PageFlipDirection.UP : - PageFlipDirection.DOWN; - this.clearMouseScrollState(); - var currentPage = this.page; - - // In case we are already on the first or the last page there is no need - // to do anything. - if ((currentPage == 1 && pageFlipDirection == PageFlipDirection.UP) || - (currentPage == this.pages.length && - pageFlipDirection == PageFlipDirection.DOWN)) - return; - - this.page += pageFlipDirection; - this.mouseScrollTimeStamp = currentTime; - } - }, - - /** - * This function clears the member attributes used with mouse scrolling in - * presentation mode. - * - * @this {PDFView} - */ - clearMouseScrollState: function pdfViewClearMouseScrollState() { - this.mouseScrollTimeStamp = 0; - this.mouseScrollDelta = 0; - } -}; - -var PageView = function pageView(container, id, scale, - navigateTo, defaultViewport) { - this.id = id; - - this.rotation = 0; - this.scale = scale || 1.0; - this.viewport = defaultViewport; - this.pdfPageRotate = defaultViewport.rotate; - - this.renderingState = RenderingStates.INITIAL; - this.resume = null; - - this.textContent = null; - this.textLayer = null; - - var anchor = document.createElement('a'); - anchor.name = '' + this.id; - - var div = this.el = document.createElement('div'); - div.id = 'pageContainer' + this.id; - div.className = 'page'; - div.style.width = Math.floor(this.viewport.width) + 'px'; - div.style.height = Math.floor(this.viewport.height) + 'px'; - - container.appendChild(anchor); - container.appendChild(div); - - this.setPdfPage = function pageViewSetPdfPage(pdfPage) { - this.pdfPage = pdfPage; - this.pdfPageRotate = pdfPage.rotate; - this.viewport = pdfPage.getViewport(this.scale); - this.stats = pdfPage.stats; - this.update(); - }; - - this.destroy = function pageViewDestroy() { - this.update(); - if (this.pdfPage) { - this.pdfPage.destroy(); - } - }; - - this.update = function pageViewUpdate(scale, rotation) { - this.renderingState = RenderingStates.INITIAL; - this.resume = null; - - if (typeof rotation !== 'undefined') { - this.rotation = rotation; - } - - this.scale = scale || this.scale; - - var totalRotation = (this.rotation + this.pdfPageRotate) % 360; - this.viewport = this.viewport.clone({ - scale: this.scale, - rotation: totalRotation - }); - - div.style.width = Math.floor(this.viewport.width) + 'px'; - div.style.height = Math.floor(this.viewport.height) + 'px'; - - while (div.hasChildNodes()) - div.removeChild(div.lastChild); - div.removeAttribute('data-loaded'); - - delete this.canvas; - - this.loadingIconDiv = document.createElement('div'); - this.loadingIconDiv.className = 'loadingIcon'; - div.appendChild(this.loadingIconDiv); - }; - - Object.defineProperty(this, 'width', { - get: function PageView_getWidth() { - return this.viewport.width; - }, - enumerable: true - }); - - Object.defineProperty(this, 'height', { - get: function PageView_getHeight() { - return this.viewport.height; - }, - enumerable: true - }); - - function setupAnnotations(pdfPage, viewport) { - function bindLink(link, dest) { - link.href = PDFView.getDestinationHash(dest); - link.onclick = function pageViewSetupLinksOnclick() { - if (dest) - PDFView.navigateTo(dest); - return false; - }; - } - function createElementWithStyle(tagName, item, rect) { - if (!rect) { - rect = viewport.convertToViewportRectangle(item.rect); - rect = PDFJS.Util.normalizeRect(rect); - } - var element = document.createElement(tagName); - element.style.left = Math.floor(rect[0]) + 'px'; - element.style.top = Math.floor(rect[1]) + 'px'; - element.style.width = Math.ceil(rect[2] - rect[0]) + 'px'; - element.style.height = Math.ceil(rect[3] - rect[1]) + 'px'; - return element; - } - function createTextAnnotation(item) { - var container = document.createElement('section'); - container.className = 'annotText'; - - var rect = viewport.convertToViewportRectangle(item.rect); - rect = PDFJS.Util.normalizeRect(rect); - // sanity check because of OOo-generated PDFs - if ((rect[3] - rect[1]) < ANNOT_MIN_SIZE) { - rect[3] = rect[1] + ANNOT_MIN_SIZE; - } - if ((rect[2] - rect[0]) < ANNOT_MIN_SIZE) { - rect[2] = rect[0] + (rect[3] - rect[1]); // make it square - } - var image = createElementWithStyle('img', item, rect); - var iconName = item.name; - image.src = IMAGE_DIR + 'annotation-' + - iconName.toLowerCase() + '.svg'; - image.alt = mozL10n.get('text_annotation_type', {type: iconName}, - '[{{type}} Annotation]'); - var content = document.createElement('div'); - content.setAttribute('hidden', true); - var title = document.createElement('h1'); - var text = document.createElement('p'); - content.style.left = Math.floor(rect[2]) + 'px'; - content.style.top = Math.floor(rect[1]) + 'px'; - title.textContent = item.title; - - if (!item.content && !item.title) { - content.setAttribute('hidden', true); - } else { - var e = document.createElement('span'); - var lines = item.content.split(/(?:\r\n?|\n)/); - for (var i = 0, ii = lines.length; i < ii; ++i) { - var line = lines[i]; - e.appendChild(document.createTextNode(line)); - if (i < (ii - 1)) - e.appendChild(document.createElement('br')); - } - text.appendChild(e); - image.addEventListener('mouseover', function annotationImageOver() { - content.removeAttribute('hidden'); - }, false); - - image.addEventListener('mouseout', function annotationImageOut() { - content.setAttribute('hidden', true); - }, false); - } - - content.appendChild(title); - content.appendChild(text); - container.appendChild(image); - container.appendChild(content); - - return container; - } - - pdfPage.getAnnotations().then(function(items) { - for (var i = 0; i < items.length; i++) { - var item = items[i]; - switch (item.type) { - case 'Link': - var link = createElementWithStyle('a', item); - link.href = item.url || ''; - if (!item.url) - bindLink(link, ('dest' in item) ? item.dest : null); - div.appendChild(link); - break; - case 'Text': - var textAnnotation = createTextAnnotation(item); - if (textAnnotation) - div.appendChild(textAnnotation); - break; - } - } - }); - } - - this.getPagePoint = function pageViewGetPagePoint(x, y) { - return this.viewport.convertToPdfPoint(x, y); - }; - - this.scrollIntoView = function pageViewScrollIntoView(dest) { - if (!dest) { - scrollIntoView(div); - return; - } - - var x = 0, y = 0; - var width = 0, height = 0, widthScale, heightScale; - var scale = 0; - switch (dest[1].name) { - case 'XYZ': - x = dest[2]; - y = dest[3]; - scale = dest[4]; - // If x and/or y coordinates are not supplied, default to - // _top_ left of the page (not the obvious bottom left, - // since aligning the bottom of the intended page with the - // top of the window is rarely helpful). - x = x !== null ? x : 0; - y = y !== null ? y : this.height / this.scale; - break; - case 'Fit': - case 'FitB': - scale = 'page-fit'; - break; - case 'FitH': - case 'FitBH': - y = dest[2]; - scale = 'page-width'; - break; - case 'FitV': - case 'FitBV': - x = dest[2]; - scale = 'page-height'; - break; - case 'FitR': - x = dest[2]; - y = dest[3]; - width = dest[4] - x; - height = dest[5] - y; - widthScale = (this.container.clientWidth - SCROLLBAR_PADDING) / - width / CSS_UNITS; - heightScale = (this.container.clientHeight - SCROLLBAR_PADDING) / - height / CSS_UNITS; - scale = Math.min(widthScale, heightScale); - break; - default: - return; - } - - if (scale && scale !== PDFView.currentScale) - PDFView.parseScale(scale, true, true); - else if (PDFView.currentScale === UNKNOWN_SCALE) - PDFView.parseScale(DEFAULT_SCALE, true, true); - - var boundingRect = [ - this.viewport.convertToViewportPoint(x, y), - this.viewport.convertToViewportPoint(x + width, y + height) - ]; - setTimeout(function pageViewScrollIntoViewRelayout() { - // letting page to re-layout before scrolling - var scale = PDFView.currentScale; - var x = Math.min(boundingRect[0][0], boundingRect[1][0]); - var y = Math.min(boundingRect[0][1], boundingRect[1][1]); - var width = Math.abs(boundingRect[0][0] - boundingRect[1][0]); - var height = Math.abs(boundingRect[0][1] - boundingRect[1][1]); - - scrollIntoView(div, {left: x, top: y, width: width, height: height}); - }, 0); - }; - - this.getTextContent = function pageviewGetTextContent() { - if (!this.textContent) { - this.textContent = this.pdfPage.getTextContent(); - } - return this.textContent; - }; - - this.draw = function pageviewDraw(callback) { - var pdfPage = this.pdfPage; - - if (!pdfPage) { - var promise = PDFView.getPage(this.id); - promise.then(function(pdfPage) { - this.setPdfPage(pdfPage); - this.draw(callback); - }.bind(this)); - return; - } - - if (this.renderingState !== RenderingStates.INITIAL) { - console.error('Must be in new state before drawing'); - } - - this.renderingState = RenderingStates.RUNNING; - - var canvas = document.createElement('canvas'); - canvas.id = 'page' + this.id; - div.appendChild(canvas); - this.canvas = canvas; - - var scale = this.scale, viewport = this.viewport; - var outputScale = PDFView.getOutputScale(); - canvas.width = Math.floor(viewport.width) * outputScale.sx; - canvas.height = Math.floor(viewport.height) * outputScale.sy; - - var textLayerDiv = null; - if (!PDFJS.disableTextLayer) { - textLayerDiv = document.createElement('div'); - textLayerDiv.className = 'textLayer'; - textLayerDiv.style.width = canvas.width + 'px'; - textLayerDiv.style.height = canvas.height + 'px'; - div.appendChild(textLayerDiv); - } - var textLayer = this.textLayer = - textLayerDiv ? new TextLayerBuilder(textLayerDiv, this.id - 1) : null; - - if (outputScale.scaled) { - var cssScale = 'scale(' + (1 / outputScale.sx) + ', ' + - (1 / outputScale.sy) + ')'; - CustomStyle.setProp('transform' , canvas, cssScale); - CustomStyle.setProp('transformOrigin' , canvas, '0% 0%'); - if (textLayerDiv) { - CustomStyle.setProp('transform' , textLayerDiv, cssScale); - CustomStyle.setProp('transformOrigin' , textLayerDiv, '0% 0%'); - } - } - - var ctx = canvas.getContext('2d'); - ctx.clearRect(0, 0, canvas.width, canvas.height); - // TODO(mack): use data attributes to store these - ctx._scaleX = outputScale.sx; - ctx._scaleY = outputScale.sy; - if (outputScale.scaled) { - ctx.scale(outputScale.sx, outputScale.sy); - } -//#if (FIREFOX || MOZCENTRAL) -// // Checking if document fonts are used only once -// var checkIfDocumentFontsUsed = !PDFView.pdfDocument.embeddedFontsUsed; -//#endif - - // Rendering area - - var self = this; - var renderingWasReset = false; - function pageViewDrawCallback(error) { - if (renderingWasReset) { - return; - } - - self.renderingState = RenderingStates.FINISHED; - - if (self.loadingIconDiv) { - div.removeChild(self.loadingIconDiv); - delete self.loadingIconDiv; - } - -//#if (FIREFOX || MOZCENTRAL) -// if (checkIfDocumentFontsUsed && PDFView.pdfDocument.embeddedFontsUsed && -// !PDFView.supportsDocumentFonts) { -// console.error(mozL10n.get('web_fonts_disabled', null, -// 'Web fonts are disabled: unable to use embedded PDF fonts.')); -// PDFView.fallback(); -// } -//#endif - if (error) { - PDFView.error(mozL10n.get('rendering_error', null, - 'An error occurred while rendering the page.'), error); - } - - self.stats = pdfPage.stats; - self.updateStats(); - if (self.onAfterDraw) - self.onAfterDraw(); - - cache.push(self); - - var event = document.createEvent('CustomEvent'); - event.initCustomEvent('pagerender', true, true, { - pageNumber: pdfPage.pageNumber - }); - div.dispatchEvent(event); - - callback(); - } - - var renderContext = { - canvasContext: ctx, - viewport: this.viewport, - textLayer: textLayer, - continueCallback: function pdfViewcContinueCallback(cont) { - if (self.renderingState === RenderingStates.INITIAL) { - // The page update() was called, we just need to abort any rendering. - renderingWasReset = true; - return; - } - - if (PDFView.highestPriorityPage !== 'page' + self.id) { - self.renderingState = RenderingStates.PAUSED; - self.resume = function resumeCallback() { - self.renderingState = RenderingStates.RUNNING; - cont(); - }; - return; - } - cont(); - } - }; - this.pdfPage.render(renderContext).then( - function pdfPageRenderCallback() { - pageViewDrawCallback(null); - }, - function pdfPageRenderError(error) { - pageViewDrawCallback(error); - } - ); - - if (textLayer) { - this.getTextContent().then( - function textContentResolved(textContent) { - textLayer.setTextContent(textContent); - } - ); - } - - setupAnnotations(this.pdfPage, this.viewport); - div.setAttribute('data-loaded', true); - }; - - this.beforePrint = function pageViewBeforePrint() { - var pdfPage = this.pdfPage; - - var viewport = pdfPage.getViewport(1); - // Use the same hack we use for high dpi displays for printing to get better - // output until bug 811002 is fixed in FF. - var PRINT_OUTPUT_SCALE = 2; - var canvas = this.canvas = document.createElement('canvas'); - canvas.width = Math.floor(viewport.width) * PRINT_OUTPUT_SCALE; - canvas.height = Math.floor(viewport.height) * PRINT_OUTPUT_SCALE; - canvas.style.width = (PRINT_OUTPUT_SCALE * viewport.width) + 'pt'; - canvas.style.height = (PRINT_OUTPUT_SCALE * viewport.height) + 'pt'; - var cssScale = 'scale(' + (1 / PRINT_OUTPUT_SCALE) + ', ' + - (1 / PRINT_OUTPUT_SCALE) + ')'; - CustomStyle.setProp('transform' , canvas, cssScale); - CustomStyle.setProp('transformOrigin' , canvas, '0% 0%'); - - var printContainer = document.getElementById('printContainer'); - printContainer.appendChild(canvas); - - var self = this; - canvas.mozPrintCallback = function(obj) { - var ctx = obj.context; - - ctx.save(); - ctx.fillStyle = 'rgb(255, 255, 255)'; - ctx.fillRect(0, 0, canvas.width, canvas.height); - ctx.restore(); - ctx.scale(PRINT_OUTPUT_SCALE, PRINT_OUTPUT_SCALE); - - var renderContext = { - canvasContext: ctx, - viewport: viewport - }; - - pdfPage.render(renderContext).then(function() { - // Tell the printEngine that rendering this canvas/page has finished. - obj.done(); - self.pdfPage.destroy(); - }, function(error) { - console.error(error); - // Tell the printEngine that rendering this canvas/page has failed. - // This will make the print proces stop. - if ('abort' in obj) - obj.abort(); - else - obj.done(); - self.pdfPage.destroy(); - }); - }; - }; - - this.updateStats = function pageViewUpdateStats() { - if (!this.stats) { - return; - } - - if (PDFJS.pdfBug && Stats.enabled) { - var stats = this.stats; - Stats.add(this.id, stats); - } - }; -}; - -var ThumbnailView = function thumbnailView(container, id, defaultViewport) { - var anchor = document.createElement('a'); - anchor.href = PDFView.getAnchorUrl('#page=' + id); - anchor.title = mozL10n.get('thumb_page_title', {page: id}, 'Page {{page}}'); - anchor.onclick = function stopNavigation() { - PDFView.page = id; - return false; - }; - - - this.pdfPage = undefined; - this.viewport = defaultViewport; - this.pdfPageRotate = defaultViewport.rotate; - - this.rotation = 0; - this.pageWidth = this.viewport.width; - this.pageHeight = this.viewport.height; - this.pageRatio = this.pageWidth / this.pageHeight; - this.id = id; - - this.canvasWidth = 98; - this.canvasHeight = this.canvasWidth / this.pageWidth * this.pageHeight; - this.scale = (this.canvasWidth / this.pageWidth); - - var div = this.el = document.createElement('div'); - div.id = 'thumbnailContainer' + id; - div.className = 'thumbnail'; - - if (id === 1) { - // Highlight the thumbnail of the first page when no page number is - // specified (or exists in cache) when the document is loaded. - div.classList.add('selected'); - } - - var ring = document.createElement('div'); - ring.className = 'thumbnailSelectionRing'; - ring.style.width = this.canvasWidth + 'px'; - ring.style.height = this.canvasHeight + 'px'; - - div.appendChild(ring); - anchor.appendChild(div); - container.appendChild(anchor); - - this.hasImage = false; - this.renderingState = RenderingStates.INITIAL; - - this.setPdfPage = function thumbnailViewSetPdfPage(pdfPage) { - this.pdfPage = pdfPage; - this.pdfPageRotate = pdfPage.rotate; - this.viewport = pdfPage.getViewport(1); - this.update(); - }; - - this.update = function thumbnailViewUpdate(rot) { - if (!this.pdfPage) { - return; - } - - if (rot !== undefined) { - this.rotation = rot; - } - - var totalRotation = (this.rotation + this.pdfPage.rotate) % 360; - this.viewport = this.viewport.clone({ - scale: 1, - rotation: totalRotation - }); - this.pageWidth = this.viewport.width; - this.pageHeight = this.viewport.height; - this.pageRatio = this.pageWidth / this.pageHeight; - - this.canvasHeight = this.canvasWidth / this.pageWidth * this.pageHeight; - this.scale = (this.canvasWidth / this.pageWidth); - - div.removeAttribute('data-loaded'); - ring.textContent = ''; - ring.style.width = this.canvasWidth + 'px'; - ring.style.height = this.canvasHeight + 'px'; - - this.hasImage = false; - this.renderingState = RenderingStates.INITIAL; - this.resume = null; - }; - - this.getPageDrawContext = function thumbnailViewGetPageDrawContext() { - var canvas = document.createElement('canvas'); - canvas.id = 'thumbnail' + id; - - canvas.width = this.canvasWidth; - canvas.height = this.canvasHeight; - canvas.className = 'thumbnailImage'; - canvas.setAttribute('aria-label', mozL10n.get('thumb_page_canvas', - {page: id}, 'Thumbnail of Page {{page}}')); - - div.setAttribute('data-loaded', true); - - ring.appendChild(canvas); - - var ctx = canvas.getContext('2d'); - ctx.save(); - ctx.fillStyle = 'rgb(255, 255, 255)'; - ctx.fillRect(0, 0, this.canvasWidth, this.canvasHeight); - ctx.restore(); - return ctx; - }; - - this.drawingRequired = function thumbnailViewDrawingRequired() { - return !this.hasImage; - }; - - this.draw = function thumbnailViewDraw(callback) { - if (!this.pdfPage) { - var promise = PDFView.getPage(this.id); - promise.then(function(pdfPage) { - this.setPdfPage(pdfPage); - this.draw(callback); - }.bind(this)); - return; - } - - if (this.renderingState !== RenderingStates.INITIAL) { - console.error('Must be in new state before drawing'); - } - - this.renderingState = RenderingStates.RUNNING; - if (this.hasImage) { - callback(); - return; - } - - var self = this; - var ctx = this.getPageDrawContext(); - var drawViewport = this.viewport.clone({ scale: this.scale }); - var renderContext = { - canvasContext: ctx, - viewport: drawViewport, - continueCallback: function(cont) { - if (PDFView.highestPriorityPage !== 'thumbnail' + self.id) { - self.renderingState = RenderingStates.PAUSED; - self.resume = function() { - self.renderingState = RenderingStates.RUNNING; - cont(); - }; - return; - } - cont(); - } - }; - this.pdfPage.render(renderContext).then( - function pdfPageRenderCallback() { - self.renderingState = RenderingStates.FINISHED; - callback(); - }, - function pdfPageRenderError(error) { - self.renderingState = RenderingStates.FINISHED; - callback(); - } - ); - this.hasImage = true; - }; - - this.setImage = function thumbnailViewSetImage(img) { - if (this.hasImage || !img) - return; - this.renderingState = RenderingStates.FINISHED; - var ctx = this.getPageDrawContext(); - ctx.drawImage(img, 0, 0, img.width, img.height, - 0, 0, ctx.canvas.width, ctx.canvas.height); - - this.hasImage = true; - }; -}; - -var DocumentOutlineView = function documentOutlineView(outline) { - var outlineView = document.getElementById('outlineView'); - while (outlineView.firstChild) - outlineView.removeChild(outlineView.firstChild); - - function bindItemLink(domObj, item) { - domObj.href = PDFView.getDestinationHash(item.dest); - domObj.onclick = function documentOutlineViewOnclick(e) { - PDFView.navigateTo(item.dest); - return false; - }; - } - - if (!outline) { - var noOutline = document.createElement('div'); - noOutline.classList.add('noOutline'); - noOutline.textContent = mozL10n.get('no_outline', null, - 'No Outline Available'); - outlineView.appendChild(noOutline); - return; - } - - var queue = [{parent: outlineView, items: outline}]; - while (queue.length > 0) { - var levelData = queue.shift(); - var i, n = levelData.items.length; - for (i = 0; i < n; i++) { - var item = levelData.items[i]; - var div = document.createElement('div'); - div.className = 'outlineItem'; - var a = document.createElement('a'); - bindItemLink(a, item); - a.textContent = item.title; - div.appendChild(a); - - if (item.items.length > 0) { - var itemsDiv = document.createElement('div'); - itemsDiv.className = 'outlineItems'; - div.appendChild(itemsDiv); - queue.push({parent: itemsDiv, items: item.items}); - } - - levelData.parent.appendChild(div); - } - } -}; - -// optimised CSS custom property getter/setter -var CustomStyle = (function CustomStyleClosure() { - - // As noted on: http://www.zachstronaut.com/posts/2009/02/17/ - // animate-css-transforms-firefox-webkit.html - // in some versions of IE9 it is critical that ms appear in this list - // before Moz - var prefixes = ['ms', 'Moz', 'Webkit', 'O']; - var _cache = { }; - - function CustomStyle() { - } - - CustomStyle.getProp = function get(propName, element) { - // check cache only when no element is given - if (arguments.length == 1 && typeof _cache[propName] == 'string') { - return _cache[propName]; - } - - element = element || document.documentElement; - var style = element.style, prefixed, uPropName; - - // test standard property first - if (typeof style[propName] == 'string') { - return (_cache[propName] = propName); - } - - // capitalize - uPropName = propName.charAt(0).toUpperCase() + propName.slice(1); - - // test vendor specific properties - for (var i = 0, l = prefixes.length; i < l; i++) { - prefixed = prefixes[i] + uPropName; - if (typeof style[prefixed] == 'string') { - return (_cache[propName] = prefixed); - } - } - - //if all fails then set to undefined - return (_cache[propName] = 'undefined'); - }; - - CustomStyle.setProp = function set(propName, element, str) { - var prop = this.getProp(propName); - if (prop != 'undefined') - element.style[prop] = str; - }; - - return CustomStyle; -})(); - -var TextLayerBuilder = function textLayerBuilder(textLayerDiv, pageIdx) { - var textLayerFrag = document.createDocumentFragment(); - - this.textLayerDiv = textLayerDiv; - this.layoutDone = false; - this.divContentDone = false; - this.pageIdx = pageIdx; - this.matches = []; - - this.beginLayout = function textLayerBuilderBeginLayout() { - this.textDivs = []; - this.textLayerQueue = []; - this.renderingDone = false; - }; - - this.endLayout = function textLayerBuilderEndLayout() { - this.layoutDone = true; - this.insertDivContent(); - }; - - this.renderLayer = function textLayerBuilderRenderLayer() { - var self = this; - var textDivs = this.textDivs; - var bidiTexts = this.textContent.bidiTexts; - var textLayerDiv = this.textLayerDiv; - var canvas = document.createElement('canvas'); - var ctx = canvas.getContext('2d'); - - // No point in rendering so many divs as it'd make the browser unusable - // even after the divs are rendered - var MAX_TEXT_DIVS_TO_RENDER = 100000; - if (textDivs.length > MAX_TEXT_DIVS_TO_RENDER) - return; - - for (var i = 0, ii = textDivs.length; i < ii; i++) { - var textDiv = textDivs[i]; - if ('isWhitespace' in textDiv.dataset) { - continue; - } - textLayerFrag.appendChild(textDiv); - - ctx.font = textDiv.style.fontSize + ' ' + textDiv.style.fontFamily; - var width = ctx.measureText(textDiv.textContent).width; - - if (width > 0) { - var textScale = textDiv.dataset.canvasWidth / width; - - var transform = 'scale(' + textScale + ', 1)'; - if (bidiTexts[i].dir === 'ttb') { - transform = 'rotate(90deg) ' + transform; - } - CustomStyle.setProp('transform' , textDiv, transform); - CustomStyle.setProp('transformOrigin' , textDiv, '0% 0%'); - - textLayerDiv.appendChild(textDiv); - } - } - - this.renderingDone = true; - this.updateMatches(); - - textLayerDiv.appendChild(textLayerFrag); - }; - - this.setupRenderLayoutTimer = function textLayerSetupRenderLayoutTimer() { - // Schedule renderLayout() if user has been scrolling, otherwise - // run it right away - var RENDER_DELAY = 200; // in ms - var self = this; - if (Date.now() - PDFView.lastScroll > RENDER_DELAY) { - // Render right away - this.renderLayer(); - } else { - // Schedule - if (this.renderTimer) - clearTimeout(this.renderTimer); - this.renderTimer = setTimeout(function() { - self.setupRenderLayoutTimer(); - }, RENDER_DELAY); - } - }; - - this.appendText = function textLayerBuilderAppendText(geom) { - var textDiv = document.createElement('div'); - - // vScale and hScale already contain the scaling to pixel units - var fontHeight = geom.fontSize * Math.abs(geom.vScale); - textDiv.dataset.canvasWidth = geom.canvasWidth * geom.hScale; - textDiv.dataset.fontName = geom.fontName; - - textDiv.style.fontSize = fontHeight + 'px'; - textDiv.style.fontFamily = geom.fontFamily; - textDiv.style.left = geom.x + 'px'; - textDiv.style.top = (geom.y - fontHeight) + 'px'; - - // The content of the div is set in the `setTextContent` function. - - this.textDivs.push(textDiv); - }; - - this.insertDivContent = function textLayerUpdateTextContent() { - // Only set the content of the divs once layout has finished, the content - // for the divs is available and content is not yet set on the divs. - if (!this.layoutDone || this.divContentDone || !this.textContent) - return; - - this.divContentDone = true; - - var textDivs = this.textDivs; - var bidiTexts = this.textContent.bidiTexts; - - for (var i = 0; i < bidiTexts.length; i++) { - var bidiText = bidiTexts[i]; - var textDiv = textDivs[i]; - if (!/\S/.test(bidiText.str)) { - textDiv.dataset.isWhitespace = true; - continue; - } - - textDiv.textContent = bidiText.str; - // bidiText.dir may be 'ttb' for vertical texts. - textDiv.dir = bidiText.dir === 'rtl' ? 'rtl' : 'ltr'; - } - - this.setupRenderLayoutTimer(); - }; - - this.setTextContent = function textLayerBuilderSetTextContent(textContent) { - this.textContent = textContent; - this.insertDivContent(); - }; - - this.convertMatches = function textLayerBuilderConvertMatches(matches) { - var i = 0; - var iIndex = 0; - var bidiTexts = this.textContent.bidiTexts; - var end = bidiTexts.length - 1; - var queryLen = PDFFindController.state.query.length; - - var lastDivIdx = -1; - var pos; - - var ret = []; - - // Loop over all the matches. - for (var m = 0; m < matches.length; m++) { - var matchIdx = matches[m]; - // # Calculate the begin position. - - // Loop over the divIdxs. - while (i !== end && matchIdx >= (iIndex + bidiTexts[i].str.length)) { - iIndex += bidiTexts[i].str.length; - i++; - } - - // TODO: Do proper handling here if something goes wrong. - if (i == bidiTexts.length) { - console.error('Could not find matching mapping'); - } - - var match = { - begin: { - divIdx: i, - offset: matchIdx - iIndex - } - }; - - // # Calculate the end position. - matchIdx += queryLen; - - // Somewhat same array as above, but use a > instead of >= to get the end - // position right. - while (i !== end && matchIdx > (iIndex + bidiTexts[i].str.length)) { - iIndex += bidiTexts[i].str.length; - i++; - } - - match.end = { - divIdx: i, - offset: matchIdx - iIndex - }; - ret.push(match); - } - - return ret; - }; - - this.renderMatches = function textLayerBuilder_renderMatches(matches) { - // Early exit if there is nothing to render. - if (matches.length === 0) { - return; - } - - var bidiTexts = this.textContent.bidiTexts; - var textDivs = this.textDivs; - var prevEnd = null; - var isSelectedPage = this.pageIdx === PDFFindController.selected.pageIdx; - var selectedMatchIdx = PDFFindController.selected.matchIdx; - var highlightAll = PDFFindController.state.highlightAll; - - var infty = { - divIdx: -1, - offset: undefined - }; - - function beginText(begin, className) { - var divIdx = begin.divIdx; - var div = textDivs[divIdx]; - div.textContent = ''; - - var content = bidiTexts[divIdx].str.substring(0, begin.offset); - var node = document.createTextNode(content); - if (className) { - var isSelected = isSelectedPage && - divIdx === selectedMatchIdx; - var span = document.createElement('span'); - span.className = className + (isSelected ? ' selected' : ''); - span.appendChild(node); - div.appendChild(span); - return; - } - div.appendChild(node); - } - - function appendText(from, to, className) { - var divIdx = from.divIdx; - var div = textDivs[divIdx]; - - var content = bidiTexts[divIdx].str.substring(from.offset, to.offset); - var node = document.createTextNode(content); - if (className) { - var span = document.createElement('span'); - span.className = className; - span.appendChild(node); - div.appendChild(span); - return; - } - div.appendChild(node); - } - - function highlightDiv(divIdx, className) { - textDivs[divIdx].className = className; - } - - var i0 = selectedMatchIdx, i1 = i0 + 1, i; - - if (highlightAll) { - i0 = 0; - i1 = matches.length; - } else if (!isSelectedPage) { - // Not highlighting all and this isn't the selected page, so do nothing. - return; - } - - for (i = i0; i < i1; i++) { - var match = matches[i]; - var begin = match.begin; - var end = match.end; - - var isSelected = isSelectedPage && i === selectedMatchIdx; - var highlightSuffix = (isSelected ? ' selected' : ''); - if (isSelected) - scrollIntoView(textDivs[begin.divIdx], {top: -50}); - - // Match inside new div. - if (!prevEnd || begin.divIdx !== prevEnd.divIdx) { - // If there was a previous div, then add the text at the end - if (prevEnd !== null) { - appendText(prevEnd, infty); - } - // clears the divs and set the content until the begin point. - beginText(begin); - } else { - appendText(prevEnd, begin); - } - - if (begin.divIdx === end.divIdx) { - appendText(begin, end, 'highlight' + highlightSuffix); - } else { - appendText(begin, infty, 'highlight begin' + highlightSuffix); - for (var n = begin.divIdx + 1; n < end.divIdx; n++) { - highlightDiv(n, 'highlight middle' + highlightSuffix); - } - beginText(end, 'highlight end' + highlightSuffix); - } - prevEnd = end; - } - - if (prevEnd) { - appendText(prevEnd, infty); - } - }; - - this.updateMatches = function textLayerUpdateMatches() { - // Only show matches, once all rendering is done. - if (!this.renderingDone) - return; - - // Clear out all matches. - var matches = this.matches; - var textDivs = this.textDivs; - var bidiTexts = this.textContent.bidiTexts; - var clearedUntilDivIdx = -1; - - // Clear out all current matches. - for (var i = 0; i < matches.length; i++) { - var match = matches[i]; - var begin = Math.max(clearedUntilDivIdx, match.begin.divIdx); - for (var n = begin; n <= match.end.divIdx; n++) { - var div = textDivs[n]; - div.textContent = bidiTexts[n].str; - div.className = ''; - } - clearedUntilDivIdx = match.end.divIdx + 1; - } - - if (!PDFFindController.active) - return; - - // Convert the matches on the page controller into the match format used - // for the textLayer. - this.matches = matches = - this.convertMatches(PDFFindController.pageMatches[this.pageIdx] || []); - - this.renderMatches(this.matches); - }; -}; - -document.addEventListener('DOMContentLoaded', function webViewerLoad(evt) { - PDFView.initialize(); - var params = PDFView.parseQueryString(document.location.search.substring(1)); - -//#if !(FIREFOX || MOZCENTRAL) - var file = params.file || DEFAULT_URL; -//#else -//var file = window.location.toString() -//#endif - -//#if !(FIREFOX || MOZCENTRAL) - if (!window.File || !window.FileReader || !window.FileList || !window.Blob) { - document.getElementById('openFile').setAttribute('hidden', 'true'); - } else { - document.getElementById('fileInput').value = null; - } -//#else -//document.getElementById('openFile').setAttribute('hidden', 'true'); -//#endif - - // Special debugging flags in the hash section of the URL. - var hash = document.location.hash.substring(1); - var hashParams = PDFView.parseQueryString(hash); - - if ('disableWorker' in hashParams) - PDFJS.disableWorker = (hashParams['disableWorker'] === 'true'); - -//#if !(FIREFOX || MOZCENTRAL) - var locale = navigator.language; - if ('locale' in hashParams) - locale = hashParams['locale']; - mozL10n.setLanguage(locale); -//#endif - - if ('textLayer' in hashParams) { - switch (hashParams['textLayer']) { - case 'off': - PDFJS.disableTextLayer = true; - break; - case 'visible': - case 'shadow': - case 'hover': - var viewer = document.getElementById('viewer'); - viewer.classList.add('textLayer-' + hashParams['textLayer']); - break; - } - } - -//#if !(FIREFOX || MOZCENTRAL) - if ('pdfBug' in hashParams) { -//#else -//if ('pdfBug' in hashParams && FirefoxCom.requestSync('pdfBugEnabled')) { -//#endif - PDFJS.pdfBug = true; - var pdfBug = hashParams['pdfBug']; - var enabled = pdfBug.split(','); - PDFBug.enable(enabled); - PDFBug.init(); - } - - if (!PDFView.supportsPrinting) { - document.getElementById('print').classList.add('hidden'); - } - - if (!PDFView.supportsFullscreen) { - document.getElementById('fullscreen').classList.add('hidden'); - } - - if (PDFView.supportsIntegratedFind) { - document.querySelector('#viewFind').classList.add('hidden'); - } - - // Listen for warnings to trigger the fallback UI. Errors should be caught - // and call PDFView.error() so we don't need to listen for those. - PDFJS.LogManager.addLogger({ - warn: function() { - PDFView.fallback(); - } - }); - - var mainContainer = document.getElementById('mainContainer'); - var outerContainer = document.getElementById('outerContainer'); - mainContainer.addEventListener('transitionend', function(e) { - if (e.target == mainContainer) { - var event = document.createEvent('UIEvents'); - event.initUIEvent('resize', false, false, window, 0); - window.dispatchEvent(event); - outerContainer.classList.remove('sidebarMoving'); - } - }, true); - - document.getElementById('sidebarToggle').addEventListener('click', - function() { - this.classList.toggle('toggled'); - outerContainer.classList.add('sidebarMoving'); - outerContainer.classList.toggle('sidebarOpen'); - PDFView.sidebarOpen = outerContainer.classList.contains('sidebarOpen'); - PDFView.renderHighestPriority(); - }); - - document.getElementById('viewThumbnail').addEventListener('click', - function() { - PDFView.switchSidebarView('thumbs'); - }); - - document.getElementById('viewOutline').addEventListener('click', - function() { - PDFView.switchSidebarView('outline'); - }); - - document.getElementById('previous').addEventListener('click', - function() { - PDFView.page--; - }); - - document.getElementById('next').addEventListener('click', - function() { - PDFView.page++; - }); - - document.querySelector('.zoomIn').addEventListener('click', - function() { - PDFView.zoomIn(); - }); - - document.querySelector('.zoomOut').addEventListener('click', - function() { - PDFView.zoomOut(); - }); - - document.getElementById('fullscreen').addEventListener('click', - function() { - PDFView.fullscreen(); - }); - - document.getElementById('openFile').addEventListener('click', - function() { - document.getElementById('fileInput').click(); - }); - - document.getElementById('print').addEventListener('click', - function() { - window.print(); - }); - - document.getElementById('download').addEventListener('click', - function() { - PDFView.download(); - }); - - document.getElementById('pageNumber').addEventListener('click', - function() { - this.select(); - }); - - document.getElementById('pageNumber').addEventListener('change', - function() { - // Handle the user inputting a floating point number. - PDFView.page = (this.value | 0); - - if (this.value !== (this.value | 0).toString()) { - this.value = PDFView.page; - } - }); - - document.getElementById('scaleSelect').addEventListener('change', - function() { - PDFView.parseScale(this.value); - }); - - document.getElementById('first_page').addEventListener('click', - function() { - PDFView.page = 1; - }); - - document.getElementById('last_page').addEventListener('click', - function() { - PDFView.page = PDFView.pdfDocument.numPages; - }); - - document.getElementById('page_rotate_ccw').addEventListener('click', - function() { - PDFView.rotatePages(-90); - }); - - document.getElementById('page_rotate_cw').addEventListener('click', - function() { - PDFView.rotatePages(90); - }); - -//#if (FIREFOX || MOZCENTRAL) -//if (FirefoxCom.requestSync('getLoadingType') == 'passive') { -// PDFView.setTitleUsingUrl(file); -// PDFView.initPassiveLoading(); -// return; -//} -//#endif - -//#if !B2G - PDFView.open(file, 0); -//#endif -}, true); - -function updateViewarea() { - - if (!PDFView.initialized) - return; - var visible = PDFView.getVisiblePages(); - var visiblePages = visible.views; - if (visiblePages.length === 0) { - return; - } - - PDFView.renderHighestPriority(); - - var currentId = PDFView.page; - var firstPage = visible.first; - - for (var i = 0, ii = visiblePages.length, stillFullyVisible = false; - i < ii; ++i) { - var page = visiblePages[i]; - - if (page.percent < 100) - break; - - if (page.id === PDFView.page) { - stillFullyVisible = true; - break; - } - } - - if (!stillFullyVisible) { - currentId = visiblePages[0].id; - } - - if (!PDFView.isFullscreen) { - updateViewarea.inProgress = true; // used in "set page" - PDFView.page = currentId; - updateViewarea.inProgress = false; - } - - var currentScale = PDFView.currentScale; - var currentScaleValue = PDFView.currentScaleValue; - var normalizedScaleValue = currentScaleValue == currentScale ? - currentScale * 100 : currentScaleValue; - - var pageNumber = firstPage.id; - var pdfOpenParams = '#page=' + pageNumber; - pdfOpenParams += '&zoom=' + normalizedScaleValue; - var currentPage = PDFView.pages[pageNumber - 1]; - var topLeft = currentPage.getPagePoint(PDFView.container.scrollLeft, - (PDFView.container.scrollTop - firstPage.y)); - pdfOpenParams += ',' + Math.round(topLeft[0]) + ',' + Math.round(topLeft[1]); - - var store = PDFView.store; - store.initializedPromise.then(function() { - store.set('exists', true); - store.set('page', pageNumber); - store.set('zoom', normalizedScaleValue); - store.set('scrollLeft', Math.round(topLeft[0])); - store.set('scrollTop', Math.round(topLeft[1])); - }); - var href = PDFView.getAnchorUrl(pdfOpenParams); - document.getElementById('viewBookmark').href = href; -} - -window.addEventListener('resize', function webViewerResize(evt) { - if (PDFView.initialized && - (document.getElementById('pageWidthOption').selected || - document.getElementById('pageFitOption').selected || - document.getElementById('pageAutoOption').selected)) - PDFView.parseScale(document.getElementById('scaleSelect').value); - updateViewarea(); -}); - -window.addEventListener('hashchange', function webViewerHashchange(evt) { - PDFView.setHash(document.location.hash.substring(1)); -}); - -window.addEventListener('change', function webViewerChange(evt) { - var files = evt.target.files; - if (!files || files.length === 0) - return; - - // Read the local file into a Uint8Array. - var fileReader = new FileReader(); - fileReader.onload = function webViewerChangeFileReaderOnload(evt) { - var buffer = evt.target.result; - var uint8Array = new Uint8Array(buffer); - PDFView.open(uint8Array, 0); - }; - - var file = files[0]; - fileReader.readAsArrayBuffer(file); - PDFView.setTitleUsingUrl(file.name); - - // URL does not reflect proper document location - hiding some icons. - document.getElementById('viewBookmark').setAttribute('hidden', 'true'); - document.getElementById('download').setAttribute('hidden', 'true'); -}, true); - -function selectScaleOption(value) { - var options = document.getElementById('scaleSelect').options; - var predefinedValueFound = false; - for (var i = 0; i < options.length; i++) { - var option = options[i]; - if (option.value != value) { - option.selected = false; - continue; - } - option.selected = true; - predefinedValueFound = true; - } - return predefinedValueFound; -} - -window.addEventListener('localized', function localized(evt) { - document.getElementsByTagName('html')[0].dir = mozL10n.getDirection(); - - // Adjust the width of the zoom box to fit the content. - PDFView.animationStartedPromise.then( - function() { - var container = document.getElementById('scaleSelectContainer'); - var select = document.getElementById('scaleSelect'); - select.setAttribute('style', 'min-width: inherit;'); - var width = select.clientWidth + 8; - select.setAttribute('style', 'min-width: ' + (width + 20) + 'px;'); - container.setAttribute('style', 'min-width: ' + width + 'px; ' + - 'max-width: ' + width + 'px;'); - }); -}, true); - -window.addEventListener('scalechange', function scalechange(evt) { - var customScaleOption = document.getElementById('customScaleOption'); - customScaleOption.selected = false; - - if (!evt.resetAutoSettings && - (document.getElementById('pageWidthOption').selected || - document.getElementById('pageFitOption').selected || - document.getElementById('pageAutoOption').selected)) { - updateViewarea(); - return; - } - - var predefinedValueFound = selectScaleOption('' + evt.scale); - if (!predefinedValueFound) { - customScaleOption.textContent = Math.round(evt.scale * 10000) / 100 + '%'; - customScaleOption.selected = true; - } - - document.getElementById('zoom_out').disabled = (evt.scale === MIN_SCALE); - document.getElementById('zoom_in').disabled = (evt.scale === MAX_SCALE); - - updateViewarea(); -}, true); - -window.addEventListener('pagechange', function pagechange(evt) { - var page = evt.pageNumber; - if (PDFView.previousPageNumber !== page) { - document.getElementById('pageNumber').value = page; - var selected = document.querySelector('.thumbnail.selected'); - if (selected) - selected.classList.remove('selected'); - var thumbnail = document.getElementById('thumbnailContainer' + page); - thumbnail.classList.add('selected'); - var visibleThumbs = PDFView.getVisibleThumbs(); - var numVisibleThumbs = visibleThumbs.views.length; - // If the thumbnail isn't currently visible scroll it into view. - if (numVisibleThumbs > 0) { - var first = visibleThumbs.first.id; - // Account for only one thumbnail being visible. - var last = numVisibleThumbs > 1 ? - visibleThumbs.last.id : first; - if (page <= first || page >= last) - scrollIntoView(thumbnail); - } - - } - document.getElementById('previous').disabled = (page <= 1); - document.getElementById('next').disabled = (page >= PDFView.pages.length); -}, true); - -// Firefox specific event, so that we can prevent browser from zooming -window.addEventListener('DOMMouseScroll', function(evt) { - if (evt.ctrlKey) { - evt.preventDefault(); - - var ticks = evt.detail; - var direction = (ticks > 0) ? 'zoomOut' : 'zoomIn'; - for (var i = 0, length = Math.abs(ticks); i < length; i++) - PDFView[direction](); - } else if (PDFView.isFullscreen) { - var FIREFOX_DELTA_FACTOR = -40; - PDFView.mouseScroll(evt.detail * FIREFOX_DELTA_FACTOR); - } -}, false); - -window.addEventListener('mousemove', function mousemove(evt) { - if (PDFView.isFullscreen) { - PDFView.showPresentationControls(); - } -}, false); - -window.addEventListener('mousedown', function mousedown(evt) { - if (PDFView.isFullscreen && evt.button === 0) { - // Enable clicking of links in fullscreen mode. - // Note: Only links that point to the currently loaded PDF document works. - var targetHref = evt.target.href; - var internalLink = targetHref && (targetHref.replace(/#.*$/, '') === - window.location.href.replace(/#.*$/, '')); - if (!internalLink) { - // Unless an internal link was clicked, advance a page in fullscreen mode. - evt.preventDefault(); - PDFView.page++; - } - } -}, false); - -window.addEventListener('click', function click(evt) { - if (PDFView.isFullscreen && evt.button === 0) { - // Necessary since preventDefault() in 'mousedown' won't stop - // the event propagation in all circumstances. - evt.preventDefault(); - } -}, false); - -window.addEventListener('keydown', function keydown(evt) { - var handled = false; - var cmd = (evt.ctrlKey ? 1 : 0) | - (evt.altKey ? 2 : 0) | - (evt.shiftKey ? 4 : 0) | - (evt.metaKey ? 8 : 0); - - // First, handle the key bindings that are independent whether an input - // control is selected or not. - if (cmd === 1 || cmd === 8 || cmd === 5 || cmd === 12) { - // either CTRL or META key with optional SHIFT. - switch (evt.keyCode) { - case 70: - if (!PDFView.supportsIntegratedFind) { - PDFFindBar.toggle(); - handled = true; - } - break; - case 61: // FF/Mac '=' - case 107: // FF '+' and '=' - case 187: // Chrome '+' - case 171: // FF with German keyboard - PDFView.zoomIn(); - handled = true; - break; - case 173: // FF/Mac '-' - case 109: // FF '-' - case 189: // Chrome '-' - PDFView.zoomOut(); - handled = true; - break; - case 48: // '0' - case 96: // '0' on Numpad of Swedish keyboard - PDFView.parseScale(DEFAULT_SCALE, true); - handled = false; // keeping it unhandled (to restore page zoom to 100%) - break; - } - } - - // CTRL or META with or without SHIFT. - if (cmd == 1 || cmd == 8 || cmd == 5 || cmd == 12) { - switch (evt.keyCode) { - case 71: // g - if (!PDFView.supportsIntegratedFind) { - PDFFindBar.dispatchEvent('again', cmd == 5 || cmd == 12); - handled = true; - } - break; - } - } - - if (handled) { - evt.preventDefault(); - return; - } - - // Some shortcuts should not get handled if a control/input element - // is selected. - var curElement = document.activeElement; - if (curElement && (curElement.tagName == 'INPUT' || - curElement.tagName == 'SELECT')) { - return; - } - var controlsElement = document.getElementById('toolbar'); - while (curElement) { - if (curElement === controlsElement && !PDFView.isFullscreen) - return; // ignoring if the 'toolbar' element is focused - curElement = curElement.parentNode; - } - - if (cmd === 0) { // no control key pressed at all. - switch (evt.keyCode) { - case 38: // up arrow - case 33: // pg up - case 8: // backspace - if (!PDFView.isFullscreen && PDFView.currentScaleValue !== 'page-fit') { - break; - } - /* in fullscreen mode */ - /* falls through */ - case 37: // left arrow - // horizontal scrolling using arrow keys - if (PDFView.isHorizontalScrollbarEnabled) { - break; - } - /* falls through */ - case 75: // 'k' - case 80: // 'p' - PDFView.page--; - handled = true; - break; - case 27: // esc key - if (!PDFView.supportsIntegratedFind && PDFFindBar.opened) { - PDFFindBar.close(); - handled = true; - } - break; - case 40: // down arrow - case 34: // pg down - case 32: // spacebar - if (!PDFView.isFullscreen && PDFView.currentScaleValue !== 'page-fit') { - break; - } - /* falls through */ - case 39: // right arrow - // horizontal scrolling using arrow keys - if (PDFView.isHorizontalScrollbarEnabled) { - break; - } - /* falls through */ - case 74: // 'j' - case 78: // 'n' - PDFView.page++; - handled = true; - break; - - case 36: // home - if (PDFView.isFullscreen) { - PDFView.page = 1; - handled = true; - } - break; - case 35: // end - if (PDFView.isFullscreen) { - PDFView.page = PDFView.pdfDocument.numPages; - handled = true; - } - break; - - case 82: // 'r' - PDFView.rotatePages(90); - break; - } - } - - if (cmd == 4) { // shift-key - switch (evt.keyCode) { - case 82: // 'r' - PDFView.rotatePages(-90); - break; - } - } - - if (handled) { - evt.preventDefault(); - PDFView.clearMouseScrollState(); - } -}); - -window.addEventListener('beforeprint', function beforePrint(evt) { - PDFView.beforePrint(); -}); - -window.addEventListener('afterprint', function afterPrint(evt) { - PDFView.afterPrint(); -}); - -(function fullscreenClosure() { - function fullscreenChange(e) { - var isFullscreen = document.fullscreenElement || document.mozFullScreen || - document.webkitIsFullScreen; - - if (!isFullscreen) { - PDFView.exitFullscreen(); - } - } - - window.addEventListener('fullscreenchange', fullscreenChange, false); - window.addEventListener('mozfullscreenchange', fullscreenChange, false); - window.addEventListener('webkitfullscreenchange', fullscreenChange, false); -})(); - -(function animationStartedClosure() { - // The offsetParent is not set until the pdf.js iframe or object is visible. - // Waiting for first animation. - var requestAnimationFrame = window.requestAnimationFrame || - window.mozRequestAnimationFrame || - window.webkitRequestAnimationFrame || - window.oRequestAnimationFrame || - window.msRequestAnimationFrame || - function startAtOnce(callback) { callback(); }; - PDFView.animationStartedPromise = new PDFJS.Promise(); - requestAnimationFrame(function onAnimationFrame() { - PDFView.animationStartedPromise.resolve(); - }); -})(); - -//#if B2G -//window.navigator.mozSetMessageHandler('activity', function(activity) { -// var url = activity.source.data.url; -// PDFView.open(url); -// var cancelButton = document.getElementById('activityClose'); -// cancelButton.addEventListener('click', function() { -// activity.postResult('close'); -// }); -//}); -//#endif diff --git a/mediagoblin/storage/cloudfiles.py b/mediagoblin/storage/cloudfiles.py index b6e57c91..250f06d4 100644 --- a/mediagoblin/storage/cloudfiles.py +++ b/mediagoblin/storage/cloudfiles.py @@ -75,7 +75,7 @@ class CloudFilesStorage(StorageInterface): _log.debug('Container: {0}'.format( self.container.name)) - self.container_uri = self.container.public_uri() + self.container_uri = self.container.public_ssl_uri() def _resolve_filepath(self, filepath): return '/'.join( diff --git a/mediagoblin/submit/lib.py b/mediagoblin/submit/lib.py index 7c3b8ab3..7e85696b 100644 --- a/mediagoblin/submit/lib.py +++ b/mediagoblin/submit/lib.py @@ -19,6 +19,7 @@ import uuid from werkzeug.utils import secure_filename from werkzeug.datastructures import FileStorage +from mediagoblin.db.models import MediaEntry from mediagoblin.processing import mark_entry_failed from mediagoblin.processing.task import process_media @@ -36,6 +37,16 @@ def check_file_field(request, field_name): return retval +def new_upload_entry(user): + """ + Create a new MediaEntry for uploading + """ + entry = MediaEntry() + entry.uploader = user.id + entry.license = user.license_preference + return entry + + def prepare_queue_task(app, entry, filename): """ Prepare a MediaEntry for the processing queue and get a queue file diff --git a/mediagoblin/submit/views.py b/mediagoblin/submit/views.py index e964ec12..3f9d5b2d 100644 --- a/mediagoblin/submit/views.py +++ b/mediagoblin/submit/views.py @@ -19,6 +19,7 @@ import mediagoblin.mg_globals as mg_globals from os.path import splitext import logging +import uuid _log = logging.getLogger(__name__) @@ -32,7 +33,9 @@ from mediagoblin.messages import add_message, SUCCESS from mediagoblin.media_types import sniff_media, \ InvalidFileType, FileTypeNotSupported from mediagoblin.submit.lib import check_file_field, prepare_queue_task, \ - run_process_media + run_process_media, new_upload_entry + +from mediagoblin.notifications import add_comment_subscription @require_active_login @@ -51,24 +54,26 @@ def submit_start(request): try: filename = request.files['file'].filename + # If the filename contains non ascii generate a unique name + if not all(ord(c) < 128 for c in filename): + filename = unicode(uuid.uuid4()) + splitext(filename)[-1] + # Sniff the submitted media to determine which # media plugin should handle processing media_type, media_manager = sniff_media( request.files['file']) # create entry and save in database - entry = request.db.MediaEntry() + entry = new_upload_entry(request.user) entry.media_type = unicode(media_type) entry.title = ( unicode(submit_form.title.data) - or unicode(splitext(filename)[0])) + or unicode(splitext(request.files['file'].filename)[0])) entry.description = unicode(submit_form.description.data) entry.license = unicode(submit_form.license.data) or None - entry.uploader = request.user.id - # Process the user's folksonomy "tags" entry.tags = convert_to_tag_list_of_dicts( submit_form.tags.data) @@ -94,6 +99,8 @@ def submit_start(request): run_process_media(entry, feed_url) add_message(request, SUCCESS, _('Woohoo! Submitted!')) + add_comment_subscription(request.user, entry) + return redirect(request, "mediagoblin.user_pages.user_home", user=request.user.username) except Exception as e: @@ -131,9 +138,9 @@ def add_collection(request, media=None): collection.generate_slug() # Make sure this user isn't duplicating an existing collection - existing_collection = request.db.Collection.find_one({ - 'creator': request.user.id, - 'title':collection.title}) + existing_collection = request.db.Collection.query.filter_by( + creator=request.user.id, + title=collection.title).first() if existing_collection: add_message(request, messages.ERROR, diff --git a/mediagoblin/templates/mediagoblin/auth/change_fp.html b/mediagoblin/templates/mediagoblin/auth/change_fp.html index 1f7d9aca..a3cf9cb9 100644 --- a/mediagoblin/templates/mediagoblin/auth/change_fp.html +++ b/mediagoblin/templates/mediagoblin/auth/change_fp.html @@ -34,11 +34,10 @@ {{ csrf_token }} <div class="form_box"> <h1>{% trans %}Set your new password{% endtrans %}</h1> - {{ wtforms_util.render_divs(cp_form) }} + {{ wtforms_util.render_divs(cp_form, True) }} <div class="form_submit_buttons"> <input type="submit" value="{% trans %}Set password{% endtrans %}" class="button_form"/> </div> </div> - </form> {% endblock %} diff --git a/mediagoblin/templates/mediagoblin/auth/forgot_password.html b/mediagoblin/templates/mediagoblin/auth/forgot_password.html index 46aeddef..6cfd2c85 100644 --- a/mediagoblin/templates/mediagoblin/auth/forgot_password.html +++ b/mediagoblin/templates/mediagoblin/auth/forgot_password.html @@ -29,7 +29,7 @@ {{ csrf_token }} <div class="form_box"> <h1>{% trans %}Recover password{% endtrans %}</h1> - {{ wtforms_util.render_divs(fp_form) }} + {{ wtforms_util.render_divs(fp_form, True) }} <div class="form_submit_buttons"> <input type="submit" value="{% trans %}Send instructions{% endtrans %}" class="button_form"/> </div> diff --git a/mediagoblin/templates/mediagoblin/auth/login.html b/mediagoblin/templates/mediagoblin/auth/login.html index 4a39059d..3329b5d0 100644 --- a/mediagoblin/templates/mediagoblin/auth/login.html +++ b/mediagoblin/templates/mediagoblin/auth/login.html @@ -29,7 +29,7 @@ {%- endblock %} {% block mediagoblin_content %} - <form action="{{ request.urlgen('mediagoblin.auth.login') }}" + <form action="{{ post_url }}" method="POST" enctype="multipart/form-data"> {{ csrf_token }} <div class="form_box"> @@ -41,15 +41,19 @@ {% endif %} {% if allow_registration %} <p> - {% trans %}Don't have an account yet?{% endtrans %} <a href="{{ request.urlgen('mediagoblin.auth.register') }}"> + {% trans %}Don't have an account yet?{% endtrans %} + <a href="{{ request.urlgen('mediagoblin.auth.register') }}"> {%- trans %}Create one here!{% endtrans %}</a> </p> {% endif %} - {{ wtforms_util.render_divs(login_form) }} - <p> - <a href="{{ request.urlgen('mediagoblin.auth.forgot_password') }}" id="forgot_password"> - {% trans %}Forgot your password?{% endtrans %}</a> - </p> + {% template_hook("login_link") %} + {{ wtforms_util.render_divs(login_form, True) }} + {% if pass_auth %} + <p> + <a href="{{ request.urlgen('mediagoblin.auth.forgot_password') }}" id="forgot_password"> + {% trans %}Forgot your password?{% endtrans %}</a> + </p> + {% endif %} <div class="form_submit_buttons"> <input type="submit" value="{% trans %}Log in{% endtrans %}" class="button_form"/> </div> diff --git a/mediagoblin/templates/mediagoblin/auth/register.html b/mediagoblin/templates/mediagoblin/auth/register.html index 6dff0207..a7b8033f 100644 --- a/mediagoblin/templates/mediagoblin/auth/register.html +++ b/mediagoblin/templates/mediagoblin/auth/register.html @@ -30,11 +30,12 @@ {% block mediagoblin_content %} - <form action="{{ request.urlgen('mediagoblin.auth.register') }}" + <form action="{{ post_url }}" method="POST" enctype="multipart/form-data"> <div class="form_box"> <h1>{% trans %}Create an account!{% endtrans %}</h1> - {{ wtforms_util.render_divs(register_form) }} + {% template_hook("register_link") %} + {{ wtforms_util.render_divs(register_form, True) }} {{ csrf_token }} <div class="form_submit_buttons"> <input type="submit" value="{% trans %}Create{% endtrans %}" @@ -42,6 +43,4 @@ </div> </div> </form> -<!-- Focus the username field by default --> -<script>$(document).ready(function(){$("#username").focus();});</script> {% endblock %} diff --git a/mediagoblin/templates/mediagoblin/base.html b/mediagoblin/templates/mediagoblin/base.html index 9c42a756..1fc4467c 100644 --- a/mediagoblin/templates/mediagoblin/base.html +++ b/mediagoblin/templates/mediagoblin/base.html @@ -34,6 +34,8 @@ src="{{ request.staticdirect('/js/extlib/jquery.js') }}"></script> <script type="text/javascript" src="{{ request.staticdirect('/js/header_dropdown.js') }}"></script> + <script type="text/javascript" + src="{{ request.staticdirect('/js/notifications.js') }}"></script> {# For clarification, the difference between the extra_head.html template # and the head template hook is that the former should be used by @@ -48,7 +50,7 @@ {% endblock mediagoblin_head %} </head> <body> - {% include 'mediagoblin/bits/body-start.html' %} + {% include 'mediagoblin/bits/body_start.html' %} {% block mediagoblin_body %} {% block mediagoblin_header %} <header> @@ -57,6 +59,12 @@ <div class="header_right"> {%- if request.user %} {% if request.user and request.user.status == 'active' %} + + {% set notification_count = request.notifications.get_notification_count(request.user.id) %} + {% if notification_count %} + <a href="#notifications" class="notification-gem button_action" title="Notifications"> + {{ notification_count }}</a> + {% endif %} <div class="button_action header_dropdown_down">▼</div> <div class="button_action header_dropdown_up">▲</div> {% elif request.user and request.user.status == "needs_email_verification" %} @@ -67,7 +75,7 @@ {% trans %}Verify your email!{% endtrans %}</a> or <a href="{{ request.urlgen('mediagoblin.auth.logout') }}">{% trans %}log out{% endtrans %}</a> {% endif %} - {%- else %} + {%- elif auth %} <a href="{{ request.urlgen('mediagoblin.auth.login') }}?next={{ request.base_url|urlencode }}"> {%- trans %}Log in{% endtrans -%} @@ -109,29 +117,21 @@ </a> </p> {% endif %} + {% include 'mediagoblin/fragments/header_notifications.html' %} </div> {% endif %} </header> {% endblock %} <div class="container"> - {% include 'mediagoblin/bits/above-content.html' %} + {% include 'mediagoblin/bits/above_content.html' %} <div class="mediagoblin_content"> {% include "mediagoblin/utils/messages.html" %} {% block mediagoblin_content %} {% endblock mediagoblin_content %} </div> - {%- block mediagoblin_footer %} - <footer> - {% trans -%} - Powered by <a href="http://mediagoblin.org/" title='Version {{ version }}'>MediaGoblin</a>, a <a href="http://gnu.org/">GNU</a> project. - {%- endtrans %} - {% trans source_link=app_config['source_link'] -%} - Released under the <a href="http://www.fsf.org/licensing/licenses/agpl-3.0.html">AGPL</a>. <a href="{{ source_link }}">Source code</a> available. - {%- endtrans %} - </footer> - {%- endblock mediagoblin_footer %} + {%- include "mediagoblin/bits/base_footer.html" %} </div> {%- endblock mediagoblin_body %} - {% include 'mediagoblin/bits/body-end.html' %} + {% include 'mediagoblin/bits/body_end.html' %} </body> </html> diff --git a/mediagoblin/templates/mediagoblin/bits/above-content.html b/mediagoblin/templates/mediagoblin/bits/above_content.html index bb7b9762..bb7b9762 100644 --- a/mediagoblin/templates/mediagoblin/bits/above-content.html +++ b/mediagoblin/templates/mediagoblin/bits/above_content.html diff --git a/mediagoblin/templates/mediagoblin/bits/base_footer.html b/mediagoblin/templates/mediagoblin/bits/base_footer.html new file mode 100644 index 00000000..80cd41b0 --- /dev/null +++ b/mediagoblin/templates/mediagoblin/bits/base_footer.html @@ -0,0 +1,28 @@ +{# +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011-2013 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/>. +#} + +{%- block mediagoblin_footer %} + <footer> + {% trans -%} + Powered by <a href="http://mediagoblin.org/" title='Version {{ version }}'>MediaGoblin</a>, a <a href="http://gnu.org/">GNU</a> project. + {%- endtrans %} + {% trans source_link=app_config['source_link'] -%} + Released under the <a href="http://www.fsf.org/licensing/licenses/agpl-3.0.html">AGPL</a>. <a href="{{ source_link }}">Source code</a> available. + {%- endtrans %} + </footer> +{%- endblock mediagoblin_footer -%} diff --git a/mediagoblin/templates/mediagoblin/bits/body-end.html b/mediagoblin/templates/mediagoblin/bits/body_end.html index bb7b9762..bb7b9762 100644 --- a/mediagoblin/templates/mediagoblin/bits/body-end.html +++ b/mediagoblin/templates/mediagoblin/bits/body_end.html diff --git a/mediagoblin/templates/mediagoblin/bits/body-start.html b/mediagoblin/templates/mediagoblin/bits/body_start.html index bb7b9762..bb7b9762 100644 --- a/mediagoblin/templates/mediagoblin/bits/body-start.html +++ b/mediagoblin/templates/mediagoblin/bits/body_start.html diff --git a/mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html b/mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html new file mode 100644 index 00000000..9ef28a4d --- /dev/null +++ b/mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html @@ -0,0 +1,41 @@ +{# +# 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/>. +#} + +{% if request.user %} + <h1>{% trans %}Explore{% endtrans %}</h1> + {% else %} + <h1>{% trans %}Hi there, welcome to this MediaGoblin site!{% endtrans %}</h1> + <img class="right_align" src="{{ request.staticdirect('/images/frontpage_image.png') }}" /> + <p>{% trans %}This site is running <a href="http://mediagoblin.org">MediaGoblin</a>, an extraordinarily great piece of media hosting software.{% endtrans %}</p> + {% if auth %} + <p>{% trans %}To add your own media, place comments, and more, you can log in with your MediaGoblin account.{% endtrans %}</p> + {% if allow_registration %} + <p>{% trans %}Don't have one yet? It's easy!{% endtrans %}</p> + {% trans register_url=request.urlgen('mediagoblin.auth.register') -%} + <a class="button_action_highlight" href="{{ register_url }}">Create an account at this site</a> + or + {%- endtrans %} + {% endif %} + {% endif %} + {% trans %} + <a class="button_action" href="http://wiki.mediagoblin.org/HackingHowto">Set up MediaGoblin on your own server</a> + {%- endtrans %} + + <div class="clear"></div> + {% endif %} + diff --git a/mediagoblin/templates/mediagoblin/edit/change_pass.html b/mediagoblin/templates/mediagoblin/edit/change_pass.html new file mode 100644 index 00000000..2a1ffee0 --- /dev/null +++ b/mediagoblin/templates/mediagoblin/edit/change_pass.html @@ -0,0 +1,52 @@ +{# +# 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/base.html" %} + +{% import "/mediagoblin/utils/wtforms.html" as wtforms_util %} + +{% block mediagoblin_head %} + <script type="text/javascript" + src="{{ request.staticdirect('/js/show_password.js') }}"></script> +{% endblock mediagoblin_head %} + +{% block title -%} + {% trans username=user.username -%} + Changing {{ username }}'s password + {%- endtrans %} — {{ super() }} +{%- endblock %} + +{% block mediagoblin_content %} + <form action="{{ request.urlgen('mediagoblin.edit.pass') }}" + method="POST" enctype="multipart/form-data"> + <div class="form_box edit_box"> + <h1> + {%- trans username=user.username -%} + Changing {{ username }}'s password + {%- endtrans -%} + </h1> + {{ wtforms_util.render_divs(form, True) }} + {{ csrf_token }} + <div class="form_submit_buttons"> + <input type="submit" value="{% trans %}Save{% endtrans %}" + class="button_form" /> + </div> + </div> + </form> +{% endblock %} + + diff --git a/mediagoblin/templates/mediagoblin/edit/edit_account.html b/mediagoblin/templates/mediagoblin/edit/edit_account.html index 7fe2c031..51293acb 100644 --- a/mediagoblin/templates/mediagoblin/edit/edit_account.html +++ b/mediagoblin/templates/mediagoblin/edit/edit_account.html @@ -41,16 +41,18 @@ Changing {{ username }}'s account settings {%- endtrans -%} </h1> - {{ wtforms_util.render_field_div(form.old_password) }} - {{ wtforms_util.render_field_div(form.new_password) }} - <div class="form_field_input"> - <p>{{ form.wants_comment_notification }} - {{ wtforms_util.render_label(form.wants_comment_notification) }}</p> - </div> - {{- wtforms_util.render_field_div(form.license_preference) }} - <div class="form_submit_buttons"> + {% if pass_auth is defined %} + <p> + <a href="{{ request.urlgen('mediagoblin.edit.pass') }}"> + {% trans %}Change your password.{% endtrans %} + </a> + </p> + {% endif %} + {% template_hook("edit_link") %} + {{ wtforms_util.render_divs(form, True) }} + <div class="form_submit_buttons"> <input type="submit" value="{% trans %}Save changes{% endtrans %}" class="button_form" /> - {{ csrf_token }} + {{ csrf_token }} </div> </div> </form> diff --git a/mediagoblin/templates/mediagoblin/edit/verification.txt b/mediagoblin/templates/mediagoblin/edit/verification.txt new file mode 100644 index 00000000..d53cd5e8 --- /dev/null +++ b/mediagoblin/templates/mediagoblin/edit/verification.txt @@ -0,0 +1,29 @@ +{# +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +-#} + +{% trans username=username, verification_url=verification_url|safe -%} +Hi, + +We wanted to verify that you are {{ username }}. If this is the case, then +please follow the link below to verify your new email address. + +{{ verification_url }} + +If you are not {{ username }} or didn't request an email change, you can ignore +this email. +{%- endtrans %} diff --git a/mediagoblin/templates/mediagoblin/fragments/header_notifications.html b/mediagoblin/templates/mediagoblin/fragments/header_notifications.html new file mode 100644 index 00000000..613100aa --- /dev/null +++ b/mediagoblin/templates/mediagoblin/fragments/header_notifications.html @@ -0,0 +1,40 @@ +{% set notifications = request.notifications.get_notifications(request.user.id) %} +{% if notifications %} + <div class="header_notifications"> + <h3>{% trans %}New comments{% endtrans %}</h3> + <ul> + {% for notification in notifications %} + {% set comment = notification.subject %} + {% set comment_author = comment.get_author %} + {% set media = comment.get_entry %} + <li class="comment_wrapper"> + <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) }}" + class="comment_authorlink"> + {{- comment_author.username -}} + </a> + <a href="{{ request.urlgen('mediagoblin.user_pages.media_home.view_comment', + comment=comment.id, + user=media.get_uploader.username, + media=media.slug_or_id) }}#comment" + class="comment_whenlink"> + <span title='{{- comment.created.strftime("%I:%M%p %Y-%m-%d") -}}'> + {%- trans formatted_time=timesince(comment.created) -%} + {{ formatted_time }} ago + {%- endtrans -%} + </span> + </a>: + </div> + <div class="comment_content"> + {% autoescape False -%} + {{ comment.content_html }} + {%- endautoescape %} + </div> + + </li> + {% endfor %} + </ul> + </div> +{% endif %} diff --git a/mediagoblin/templates/mediagoblin/media_displays/image.html b/mediagoblin/templates/mediagoblin/media_displays/image.html index 158dd67f..d0050f50 100644 --- a/mediagoblin/templates/mediagoblin/media_displays/image.html +++ b/mediagoblin/templates/mediagoblin/media_displays/image.html @@ -27,3 +27,20 @@ {{ super() }} {% template_hook("image_sideinfo") %} {% endblock %} + +{% block mediagoblin_after_added_sidebar %} + {% if app_config['original_date_visible'] %} + {% set original_date = media.media_manager.get_original_date() %} + + {% if original_date %} + <h3>{% trans %}Created{% endtrans %}</h3> + + <p><span title="{{ original_date.strftime("%I:%M%p %Y-%m-%d") }}"> + {%- trans formatted_time=timesince(original_date) -%} + {{ formatted_time }} ago + {%- endtrans -%} + </span></p> + {%- endif %} + {% endif %} +{% endblock %} + diff --git a/mediagoblin/templates/mediagoblin/media_displays/pdf.html b/mediagoblin/templates/mediagoblin/media_displays/pdf.html index e946f3ab..9319e87c 100644 --- a/mediagoblin/templates/mediagoblin/media_displays/pdf.html +++ b/mediagoblin/templates/mediagoblin/media_displays/pdf.html @@ -46,19 +46,21 @@ {%- endblock %} {% block mediagoblin_media %} -{% if pdf_js %} -<iframe width=640px height=480px - src="{{ request.staticdirect('/extlib/pdf.js/web/viewer.html') }}?file={{ pdf_view }} "> -</iframe> - -{% else %} - <a href="{{ pdf_view }}"> - <img id="medium" - class="media_image" - src="{{ medium_view }}" - alt="{% trans media_title=media.title -%} Image for {{ media_title}}{% endtrans %}"/> - </a> -{% endif %} + {% if pdf_js %} + <iframe width="640px" height="480px" + src="{{ request.staticdirect('/extlib/pdf.js/web/viewer.html') }}?file={{ pdf_view }} "> + </iframe> + {% else %} + <a href="{{ pdf_view }}"> + <img id="medium" + class="media_image" + src="{{ medium_view }}" + alt=" + {%- trans media_title=media.title -%} + Image for {{ media_title}} + {%- endtrans %}"/> + </a> + {% endif %} {% endblock %} {% block mediagoblin_sidebar %} diff --git a/mediagoblin/templates/mediagoblin/media_displays/stl.html b/mediagoblin/templates/mediagoblin/media_displays/stl.html index a89e0b4f..bc12ce4e 100644 --- a/mediagoblin/templates/mediagoblin/media_displays/stl.html +++ b/mediagoblin/templates/mediagoblin/media_displays/stl.html @@ -108,32 +108,26 @@ window.show_things = function () { <div style="padding: 4px;"> - <a class="button_action" onclick="show('perspective');" - title="{%- trans %}Toggle Rotate{% endtrans -%}"> + <a class="button_action" onclick="show('perspective');"> {%- trans %}Perspective{% endtrans -%} </a> - <a class="button_action" onclick="show('front_view');" - title="{%- trans %}Front{% endtrans -%}"> + <a class="button_action" onclick="show('front_view');"> {%- trans %}Front{% endtrans -%} </a> - <a class="button_action" onclick="show('top_view');" - title="{%- trans %}Top{% endtrans -%}"> + <a class="button_action" onclick="show('top_view');"> {%- trans %}Top{% endtrans -%} </a> - <a class="button_action" onclick="show('side_view');" - title="{%- trans %}Side{% endtrans -%}"> + <a class="button_action" onclick="show('side_view');"> {%- trans %}Side{% endtrans -%} </a> {% if media.media_data.file_type == "stl" %} <a id="webgl_button" class="button_action" - onclick="show_things();" - title="{%- trans %}WebGL{% endtrans -%}"> + onclick="show_things();"> {%- trans %}WebGL{% endtrans -%} </a> {% endif %} <a class="button_action" href="{{ model_download }}" - title="{%- trans %}Download{% endtrans -%}" style="float:right;"> {%- trans %}Download model{% endtrans -%} </a> diff --git a/mediagoblin/templates/mediagoblin/root.html b/mediagoblin/templates/mediagoblin/root.html index 529d89ef..15d53af1 100644 --- a/mediagoblin/templates/mediagoblin/root.html +++ b/mediagoblin/templates/mediagoblin/root.html @@ -27,23 +27,8 @@ {%- endblock mediagoblin_head %} {% block mediagoblin_content %} - {% if request.user %} - <h1>{% trans %}Explore{% endtrans %}</h1> - {% else %} - <h1>{% trans %}Hi there, welcome to this MediaGoblin site!{% endtrans %}</h1> - <img class="right_align" src="{{ request.staticdirect('/images/frontpage_image.png') }}" /> - <p>{% trans %}This site is running <a href="http://mediagoblin.org">MediaGoblin</a>, an extraordinarily great piece of media hosting software.{% endtrans %}</p> - <p>{% trans %}To add your own media, place comments, and more, you can log in with your MediaGoblin account.{% endtrans %}</p> - {% if allow_registration %} - <p>{% trans %}Don't have one yet? It's easy!{% endtrans %}</p> - {% trans register_url=request.urlgen('mediagoblin.auth.register') -%} - <a class="button_action_highlight" href="{{ register_url }}">Create an account at this site</a> - or - <a class="button_action" href="http://wiki.mediagoblin.org/HackingHowto">Set up MediaGoblin on your own server</a> - {%- endtrans %} - {% endif %} - <div class="clear"></div> - {% endif %} + {% include "mediagoblin/bits/frontpage_welcome.html" %} + <h2>{% trans %}Most recent media{% endtrans %}</h2> {{ object_gallery(request, media_entries, pagination) }} diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html index 667510d5..c16e4c78 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media.html @@ -81,20 +81,23 @@ user= media.get_uploader.username, media_id=media.id) %} <a class="button_action" href="{{ delete_url }}">{% trans %}Delete{% endtrans %}</a> + {% endif %} {% autoescape False %} <p>{{ media.description_html }}</p> {% endautoescape %} {% if comments %} - <a - {% if not request.user %} - href="{{ request.urlgen('mediagoblin.auth.login') }}" - {% endif %} - {% if app_config['allow_comments'] %} - class="button_action" id="button_addcomment" title="Add a comment"> - {% trans %}Add a comment{% endtrans %} - {% endif %} - </a> + {% if app_config['allow_comments'] %} + <a + {% if not request.user %} + href="{{ request.urlgen('mediagoblin.auth.login') }}" + {% endif %} + class="button_action" id="button_addcomment" title="Add a comment"> + {% trans %}Add a comment{% endtrans %} + </a> + {% include "mediagoblin/utils/comment-subscription.html" %} + + {% endif %} {% if request.user %} <form action="{{ request.urlgen('mediagoblin.user_pages.media_post_comment', user= media.get_uploader.username, @@ -154,19 +157,8 @@ {%- endtrans -%} </span></p> - {% if app_config['original_date_visible'] %} - {% set original_date = media.media_manager.get_original_date() %} - - {% if original_date %} - <h3>{% trans %}Created{% endtrans %}</h3> - - <p><span title="{{ original_date.strftime("%I:%M%p %Y-%m-%d") }}"> - {%- trans formatted_time=timesince(original_date) -%} - {{ formatted_time }} ago - {%- endtrans -%} - </span></p> - {%- endif %} - {% endif %} + {% block mediagoblin_after_added_sidebar %} + {% endblock %} {% if media.tags %} {% include "mediagoblin/utils/tags.html" %} diff --git a/mediagoblin/templates/mediagoblin/utils/comment-subscription.html b/mediagoblin/templates/mediagoblin/utils/comment-subscription.html new file mode 100644 index 00000000..bd367e80 --- /dev/null +++ b/mediagoblin/templates/mediagoblin/utils/comment-subscription.html @@ -0,0 +1,34 @@ +{# +# 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/>. +#} +{%- if request.user %} + {% set subscription = request.notifications.get_comment_subscription( + request.user.id, media.id) %} + {% if not subscription or not subscription.notify %} + <a type="submit" href="{{ request.urlgen('mediagoblin.notifications.subscribe_comments', + user=media.get_uploader.username, + media=media.slug_or_id)}}" + class="button_action">Subscribe to comments + </a> + {% else %} + <a type="submit" href="{{ request.urlgen('mediagoblin.notifications.silence_comments', + user=media.get_uploader.username, + media=media.slug_or_id)}}" + class="button_action">Silence comments + </a> + {% endif %} +{%- endif %} diff --git a/mediagoblin/templates/mediagoblin/utils/exif.html b/mediagoblin/templates/mediagoblin/utils/exif.html index a89e69c8..b62208e1 100644 --- a/mediagoblin/templates/mediagoblin/utils/exif.html +++ b/mediagoblin/templates/mediagoblin/utils/exif.html @@ -17,18 +17,51 @@ #} {% block exif_content %} +<noscript> + <style type="text/css"> + #exif_additional_info { + display: block; + } + </style> +</noscript> +<div id="exif_content"> {% if app_config['exif_visible'] and media.media_data and media.media_data.exif_all is defined and media.media_data.exif_all %} - <h3>EXIF</h3> - <table> + <h3>Camera Information</h3> + <table id="exif_camera_information"> + <tbody> + {% for label, value in media.exif_display_data_short().iteritems() %} + <tr> + <td class="col1">{{ label }}</td> + <td>{{ value }}</td> + </tr> + {% endfor %} + </tbody> + </table> + <h3 id="exif_additional_info_button" class="button_action"> + Additional Information + </h3> + <div id="exif_additional_info"> + <table class="exif_info"> {% for key, tag in media.exif_display_iter() %} <tr> - <td>{{ key }}</td> + <td class="col1">{{ key }}</td> <td>{{ tag.printable }}</td> </tr> {% endfor %} </table> + </div> {% endif %} +<script type="text/javascript"> +$(document).ready(function(){ + +$("#exif_additional_info_button").click(function(){ + $("#exif_additional_info").slideToggle("slow"); +}); + +}); +</script> +</div> <!-- end exif_content div --> {% endblock %} diff --git a/mediagoblin/templates/mediagoblin/utils/wtforms.html b/mediagoblin/templates/mediagoblin/utils/wtforms.html index be6976c2..e079274e 100644 --- a/mediagoblin/templates/mediagoblin/utils/wtforms.html +++ b/mediagoblin/templates/mediagoblin/utils/wtforms.html @@ -33,25 +33,37 @@ {%- endmacro %} {# Generically render a field #} -{% macro render_field_div(field) %} - {{- render_label_p(field) }} - <div class="form_field_input"> - {{ field }} - {%- if field.errors -%} - {% for error in field.errors %} - <p class="form_field_error">{{ error }}</p> - {% endfor %} - {%- endif %} - {%- if field.description %} - <p class="form_field_description">{{ field.description|safe }}</p> - {%- endif %} - </div> +{% macro render_field_div(field, autofocus_first=False) %} + {% if field.type == 'BooleanField' %} + {{ render_bool(field) }} + {% else %} + {{- render_label_p(field) }} + <div class="form_field_input"> + {% if autofocus_first %} + {{ field(autofocus=True) }} + {% else %} + {{ field }} + {% endif %} + {%- if field.errors -%} + {% for error in field.errors %} + <p class="form_field_error">{{ error }}</p> + {% endfor %} + {%- endif %} + {%- if field.description %} + <p class="form_field_description">{{ field.description|safe }}</p> + {%- endif %} + </div> + {% endif %} {%- endmacro %} {# Auto-render a form as a series of divs #} -{% macro render_divs(form) -%} +{% macro render_divs(form, autofocus_first=False) -%} {% for field in form %} - {{ render_field_div(field) }} + {% if autofocus_first and loop.first %} + {{ render_field_div(field, True) }} + {% else %} + {{ render_field_div(field) }} + {% endif %} {% endfor %} {%- endmacro %} @@ -74,3 +86,19 @@ </tr> {% endfor %} {%- endmacro %} + +{# Render a boolean field #} +{% macro render_bool(field) %} + <div class="boolean"> + <label for="{{ field.label.field_id }}"> + {{ field }}</input> + {{ field.description|safe }} + </label> + {%- if field.errors -%} + {% for error in field.errors %} + <p class="form_field_error">{{ error }}</p> + {% endfor %} + {% endif %} + </div> +{% endmacro %} + diff --git a/mediagoblin/tests/__init__.py b/mediagoblin/tests/__init__.py index 7a88281e..cf200791 100644 --- a/mediagoblin/tests/__init__.py +++ b/mediagoblin/tests/__init__.py @@ -14,21 +14,9 @@ # 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 - -from mediagoblin import mg_globals -from mediagoblin.tests.tools import TEST_USER_DEV - def setup_package(): import warnings from sqlalchemy.exc import SAWarning warnings.simplefilter("error", SAWarning) - - -def teardown_package(): - # Remove and reinstall user_dev directories - if os.path.exists(TEST_USER_DEV): - shutil.rmtree(TEST_USER_DEV) diff --git a/mediagoblin/tests/appconfig_context_modified.ini b/mediagoblin/tests/appconfig_context_modified.ini new file mode 100644 index 00000000..cc6721f5 --- /dev/null +++ b/mediagoblin/tests/appconfig_context_modified.ini @@ -0,0 +1,27 @@ +[mediagoblin] +direct_remote_path = /test_static/ +email_sender_address = "notice@mediagoblin.example.org" +email_debug_mode = true + +#Runs with an in-memory sqlite db for speed. +sql_engine = "sqlite://" +run_migrations = true + +# Celery shouldn't be set up by the application as it's setup via +# mediagoblin.init.celery.from_celery +celery_setup_elsewhere = true + +[storage:publicstore] +base_dir = %(here)s/user_dev/media/public +base_url = /mgoblin_media/ + +[storage:queuestore] +base_dir = %(here)s/user_dev/media/queue + +[celery] +CELERY_ALWAYS_EAGER = true +CELERY_RESULT_DBURI = "sqlite:///%(here)s/user_dev/celery.db" +BROKER_HOST = "sqlite:///%(here)s/user_dev/kombu.db" + +[plugins] +[[mediagoblin.tests.testplugins.modify_context]] diff --git a/mediagoblin/tests/appconfig_static_plugin.ini b/mediagoblin/tests/appconfig_static_plugin.ini new file mode 100644 index 00000000..5ce5c5bd --- /dev/null +++ b/mediagoblin/tests/appconfig_static_plugin.ini @@ -0,0 +1,27 @@ +[mediagoblin] +direct_remote_path = /test_static/ +email_sender_address = "notice@mediagoblin.example.org" +email_debug_mode = true + +#Runs with an in-memory sqlite db for speed. +sql_engine = "sqlite://" +run_migrations = true + +# Celery shouldn't be set up by the application as it's setup via +# mediagoblin.init.celery.from_celery +celery_setup_elsewhere = true + +[storage:publicstore] +base_dir = %(here)s/user_dev/media/public +base_url = /mgoblin_media/ + +[storage:queuestore] +base_dir = %(here)s/user_dev/media/queue + +[celery] +CELERY_ALWAYS_EAGER = true +CELERY_RESULT_DBURI = "sqlite:///%(here)s/user_dev/celery.db" +BROKER_HOST = "sqlite:///%(here)s/user_dev/kombu.db" + +[plugins] +[[mediagoblin.tests.testplugins.staticstuff]] diff --git a/mediagoblin/tests/auth_configs/__init__.py b/mediagoblin/tests/auth_configs/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/mediagoblin/tests/auth_configs/__init__.py diff --git a/mediagoblin/tests/auth_configs/authentication_disabled_appconfig.ini b/mediagoblin/tests/auth_configs/authentication_disabled_appconfig.ini new file mode 100644 index 00000000..a64e9e40 --- /dev/null +++ b/mediagoblin/tests/auth_configs/authentication_disabled_appconfig.ini @@ -0,0 +1,25 @@ +[mediagoblin] +direct_remote_path = /test_static/ +email_sender_address = "notice@mediagoblin.example.org" +email_debug_mode = true + +# TODO: Switch to using an in-memory database +sql_engine = "sqlite:///%(here)s/user_dev/mediagoblin.db" + +# Celery shouldn't be set up by the application as it's setup via +# mediagoblin.init.celery.from_celery +celery_setup_elsewhere = true + +[storage:publicstore] +base_dir = %(here)s/user_dev/media/public +base_url = /mgoblin_media/ + +[storage:queuestore] +base_dir = %(here)s/user_dev/media/queue + +[celery] +CELERY_ALWAYS_EAGER = true +CELERY_RESULT_DBURI = "sqlite:///%(here)s/user_dev/celery.db" +BROKER_HOST = "sqlite:///%(here)s/user_dev/kombu.db" + +[plugins] diff --git a/mediagoblin/tests/auth_configs/openid_appconfig.ini b/mediagoblin/tests/auth_configs/openid_appconfig.ini new file mode 100644 index 00000000..c2bd82fd --- /dev/null +++ b/mediagoblin/tests/auth_configs/openid_appconfig.ini @@ -0,0 +1,41 @@ +# 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/>. +[mediagoblin] +direct_remote_path = /test_static/ +email_sender_address = "notice@mediagoblin.example.org" +email_debug_mode = true + +# TODO: Switch to using an in-memory database +sql_engine = "sqlite:///%(here)s/user_dev/mediagoblin.db" + +# Celery shouldn't be set up by the application as it's setup via +# mediagoblin.init.celery.from_celery +celery_setup_elsewhere = true + +[storage:publicstore] +base_dir = %(here)s/user_dev/media/public +base_url = /mgoblin_media/ + +[storage:queuestore] +base_dir = %(here)s/user_dev/media/queue + +[celery] +CELERY_ALWAYS_EAGER = true +CELERY_RESULT_DBURI = "sqlite:///%(here)s/user_dev/celery.db" +BROKER_HOST = "sqlite:///%(here)s/user_dev/kombu.db" + +[plugins] +[[mediagoblin.plugins.openid]] diff --git a/mediagoblin/tests/conftest.py b/mediagoblin/tests/conftest.py index 25f495d6..dbb0aa0a 100644 --- a/mediagoblin/tests/conftest.py +++ b/mediagoblin/tests/conftest.py @@ -1,7 +1,25 @@ -from mediagoblin.tests import tools +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2013 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 pytest +from mediagoblin.tests import tools +from mediagoblin.tools.testing import _activate_testing + + @pytest.fixture() def test_app(request): """ @@ -13,3 +31,11 @@ def test_app(request): in differently to get_app. """ return tools.get_app(request) + + +@pytest.fixture() +def pt_fixture_enable_testing(): + """ + py.test fixture to enable testing mode in tools. + """ + _activate_testing() diff --git a/mediagoblin/tests/pytest.ini b/mediagoblin/tests/pytest.ini index d4aa2d69..e561c074 100644 --- a/mediagoblin/tests/pytest.ini +++ b/mediagoblin/tests/pytest.ini @@ -1,2 +1,2 @@ [pytest] -usefixtures = tmpdir
\ No newline at end of file +usefixtures = tmpdir pt_fixture_enable_testing diff --git a/mediagoblin/tests/test_auth.py b/mediagoblin/tests/test_auth.py index 755727f9..61503d32 100644 --- a/mediagoblin/tests/test_auth.py +++ b/mediagoblin/tests/test_auth.py @@ -13,54 +13,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/>. - import urlparse -import datetime +import pkg_resources +import pytest from mediagoblin import mg_globals -from mediagoblin.auth import lib as auth_lib from mediagoblin.db.models import User -from mediagoblin.tests.tools import fixture_add_user +from mediagoblin.tests.tools import get_app, fixture_add_user from mediagoblin.tools import template, mail - - -######################## -# Test bcrypt auth funcs -######################## - -def test_bcrypt_check_password(): - # Check known 'lollerskates' password against check function - assert auth_lib.bcrypt_check_password( - 'lollerskates', - '$2a$12$PXU03zfrVCujBhVeICTwtOaHTUs5FFwsscvSSTJkqx/2RQ0Lhy/nO') - - assert not auth_lib.bcrypt_check_password( - 'notthepassword', - '$2a$12$PXU03zfrVCujBhVeICTwtOaHTUs5FFwsscvSSTJkqx/2RQ0Lhy/nO') - - # Same thing, but with extra fake salt. - assert not auth_lib.bcrypt_check_password( - 'notthepassword', - '$2a$12$ELVlnw3z1FMu6CEGs/L8XO8vl0BuWSlUHgh0rUrry9DUXGMUNWwl6', - '3><7R45417') - - -def test_bcrypt_gen_password_hash(): - pw = 'youwillneverguessthis' - - # Normal password hash generation, and check on that hash - hashed_pw = auth_lib.bcrypt_gen_password_hash(pw) - assert auth_lib.bcrypt_check_password( - pw, hashed_pw) - assert not auth_lib.bcrypt_check_password( - 'notthepassword', hashed_pw) - - # Same thing, extra salt. - hashed_pw = auth_lib.bcrypt_gen_password_hash(pw, '3><7R45417') - assert auth_lib.bcrypt_check_password( - pw, hashed_pw, '3><7R45417') - assert not auth_lib.bcrypt_check_password( - 'notthepassword', hashed_pw, '3><7R45417') +from mediagoblin.auth import tools as auth_tools def test_register_views(test_app): @@ -132,8 +93,8 @@ def test_register_views(test_app): assert 'mediagoblin/user_pages/user.html' in template.TEMPLATE_TEST_CONTEXT ## Make sure user is in place - new_user = mg_globals.database.User.find_one( - {'username': u'happygirl'}) + new_user = mg_globals.database.User.query.filter_by( + username=u'happygirl').first() assert new_user assert new_user.status == u'needs_email_verification' assert new_user.email_verified == False @@ -156,24 +117,19 @@ def test_register_views(test_app): assert path == u'/auth/verify_email/' parsed_get_params = urlparse.parse_qs(get_params) - ### user should have these same parameters - assert parsed_get_params['userid'] == [ - unicode(new_user.id)] - assert parsed_get_params['token'] == [ - new_user.verification_key] - ## Try verifying with bs verification key, shouldn't work template.clear_test_template_context() response = test_app.get( - "/auth/verify_email/?userid=%s&token=total_bs" % unicode( - new_user.id)) + "/auth/verify_email/?token=total_bs") response.follow() - context = template.TEMPLATE_TEST_CONTEXT[ - 'mediagoblin/user_pages/user.html'] + + # Correct redirect? + assert urlparse.urlsplit(response.location)[2] == '/' + # assert context['verification_successful'] == True # TODO: Would be good to test messages here when we can do so... - new_user = mg_globals.database.User.find_one( - {'username': u'happygirl'}) + new_user = mg_globals.database.User.query.filter_by( + username=u'happygirl').first() assert new_user assert new_user.status == u'needs_email_verification' assert new_user.email_verified == False @@ -186,8 +142,8 @@ def test_register_views(test_app): 'mediagoblin/user_pages/user.html'] # assert context['verification_successful'] == True # TODO: Would be good to test messages here when we can do so... - new_user = mg_globals.database.User.find_one( - {'username': u'happygirl'}) + new_user = mg_globals.database.User.query.filter_by( + username=u'happygirl').first() assert new_user assert new_user.status == u'active' assert new_user.email_verified == True @@ -233,35 +189,17 @@ def test_register_views(test_app): path = urlparse.urlsplit(email_context['verification_url'])[2] get_params = urlparse.urlsplit(email_context['verification_url'])[3] - assert path == u'/auth/forgot_password/verify/' parsed_get_params = urlparse.parse_qs(get_params) - - # user should have matching parameters - new_user = mg_globals.database.User.find_one({'username': u'happygirl'}) - assert parsed_get_params['userid'] == [unicode(new_user.id)] - assert parsed_get_params['token'] == [new_user.fp_verification_key] - - ### The forgotten password token should be set to expire in ~ 10 days - # A few ticks have expired so there are only 9 full days left... - assert (new_user.fp_token_expire - datetime.datetime.now()).days == 9 + assert path == u'/auth/forgot_password/verify/' ## Try using a bs password-changing verification key, shouldn't work template.clear_test_template_context() response = test_app.get( - "/auth/forgot_password/verify/?userid=%s&token=total_bs" % unicode( - new_user.id), status=404) - assert response.status.split()[0] == u'404' # status="404 NOT FOUND" + "/auth/forgot_password/verify/?token=total_bs") + response.follow() - ## 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': u'happygirl'}) - real_token_expiration = new_user.fp_token_expire - new_user.fp_token_expire = datetime.datetime.now() - new_user.save() - response = test_app.get("%s?%s" % (path, get_params), status=404) - assert response.status.split()[0] == u'404' # status="404 NOT FOUND" - new_user.fp_token_expire = real_token_expiration - new_user.save() + # Correct redirect? + assert urlparse.urlsplit(response.location)[2] == '/' ## Verify step 1 of password-change works -- can see form to change password template.clear_test_template_context() @@ -272,7 +210,6 @@ def test_register_views(test_app): template.clear_test_template_context() response = test_app.post( '/auth/forgot_password/verify/', { - 'userid': parsed_get_params['userid'], 'password': 'iamveryveryhappy', 'token': parsed_get_params['token']}) response.follow() @@ -298,6 +235,7 @@ def test_authentication_views(test_app): # Make a new user test_user = fixture_add_user(active_user=False) + # Get login # --------- test_app.get('/auth/login/') @@ -310,7 +248,6 @@ def test_authentication_views(test_app): context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/auth/login.html'] form = context['login_form'] assert form.username.errors == [u'This field is required.'] - assert form.password.errors == [u'This field is required.'] # Failed login - blank user # ------------------------- @@ -328,9 +265,7 @@ def test_authentication_views(test_app): response = test_app.post( '/auth/login/', { 'username': u'chris'}) - context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/auth/login.html'] - form = context['login_form'] - assert form.password.errors == [u'This field is required.'] + assert 'mediagoblin/auth/login.html' in template.TEMPLATE_TEST_CONTEXT # Failed login - bad user # ----------------------- @@ -394,3 +329,47 @@ def test_authentication_views(test_app): 'password': 'toast', 'next' : '/u/chris/'}) assert urlparse.urlsplit(response.location)[2] == '/u/chris/' + + +@pytest.fixture() +def authentication_disabled_app(request): + return get_app( + request, + mgoblin_config=pkg_resources.resource_filename( + 'mediagoblin.tests.auth_configs', + 'authentication_disabled_appconfig.ini')) + + +def test_authentication_disabled_app(authentication_disabled_app): + # app.auth should = false + assert mg_globals.app.auth is False + + # Try to visit register page + template.clear_test_template_context() + response = authentication_disabled_app.get('/auth/register/') + response.follow() + + # Correct redirect? + assert urlparse.urlsplit(response.location)[2] == '/' + assert 'mediagoblin/root.html' in template.TEMPLATE_TEST_CONTEXT + + # Try to vist login page + template.clear_test_template_context() + response = authentication_disabled_app.get('/auth/login/') + response.follow() + + # Correct redirect? + assert urlparse.urlsplit(response.location)[2] == '/' + assert 'mediagoblin/root.html' in template.TEMPLATE_TEST_CONTEXT + + ## Test check_login_simple should return None + assert auth_tools.check_login_simple('test', 'simple') is None + + # Try to visit the forgot password page + template.clear_test_template_context() + response = authentication_disabled_app.get('/auth/register/') + response.follow() + + # Correct redirect? + assert urlparse.urlsplit(response.location)[2] == '/' + assert 'mediagoblin/root.html' in template.TEMPLATE_TEST_CONTEXT diff --git a/mediagoblin/tests/test_basic_auth.py b/mediagoblin/tests/test_basic_auth.py new file mode 100644 index 00000000..cdd80fca --- /dev/null +++ b/mediagoblin/tests/test_basic_auth.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/>. +from mediagoblin.plugins.basic_auth import tools as auth_tools +from mediagoblin.tools.testing import _activate_testing + +_activate_testing() + + +######################## +# Test bcrypt auth funcs +######################## + + +def test_bcrypt_check_password(): + # Check known 'lollerskates' password against check function + assert auth_tools.bcrypt_check_password( + 'lollerskates', + '$2a$12$PXU03zfrVCujBhVeICTwtOaHTUs5FFwsscvSSTJkqx/2RQ0Lhy/nO') + + assert not auth_tools.bcrypt_check_password( + 'notthepassword', + '$2a$12$PXU03zfrVCujBhVeICTwtOaHTUs5FFwsscvSSTJkqx/2RQ0Lhy/nO') + + # Same thing, but with extra fake salt. + assert not auth_tools.bcrypt_check_password( + 'notthepassword', + '$2a$12$ELVlnw3z1FMu6CEGs/L8XO8vl0BuWSlUHgh0rUrry9DUXGMUNWwl6', + '3><7R45417') + + +def test_bcrypt_gen_password_hash(): + pw = 'youwillneverguessthis' + + # Normal password hash generation, and check on that hash + hashed_pw = auth_tools.bcrypt_gen_password_hash(pw) + assert auth_tools.bcrypt_check_password( + pw, hashed_pw) + assert not auth_tools.bcrypt_check_password( + 'notthepassword', hashed_pw) + + # Same thing, extra salt. + hashed_pw = auth_tools.bcrypt_gen_password_hash(pw, '3><7R45417') + assert auth_tools.bcrypt_check_password( + pw, hashed_pw, '3><7R45417') + assert not auth_tools.bcrypt_check_password( + 'notthepassword', hashed_pw, '3><7R45417') diff --git a/mediagoblin/tests/test_celery_setup.py b/mediagoblin/tests/test_celery_setup.py index 5530c6f2..0184436a 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.task'] + 'foo.bar.baz', 'this.is.an.import', 'mediagoblin.processing.task', 'mediagoblin.notifications.task'] assert fake_celery_module.CELERY_RESULT_BACKEND == 'database' assert fake_celery_module.CELERY_RESULT_DBURI == ( 'sqlite:///' + diff --git a/mediagoblin/tests/test_edit.py b/mediagoblin/tests/test_edit.py index cda2607f..d70d0478 100644 --- a/mediagoblin/tests/test_edit.py +++ b/mediagoblin/tests/test_edit.py @@ -14,13 +14,14 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -import pytest +import urlparse from mediagoblin import mg_globals from mediagoblin.db.models import User from mediagoblin.tests.tools import fixture_add_user -from mediagoblin.tools import template -from mediagoblin.auth.lib import bcrypt_check_password +from mediagoblin import auth +from mediagoblin.tools import template, mail + class TestUserEdit(object): def setup(self): @@ -60,32 +61,34 @@ class TestUserEdit(object): self.login(test_app) # test that the password can be changed - # template.clear_test_template_context() + template.clear_test_template_context() res = test_app.post( - '/edit/account/', { + '/edit/password/', { 'old_password': 'toast', 'new_password': '123456', - 'wants_comment_notification': 'y' }) + res.follow() + + # Did we redirect to the correct page? + assert urlparse.urlsplit(res.location)[2] == '/edit/account/' - # Check for redirect on success - assert res.status_int == 302 # test_user has to be fetched again in order to have the current values test_user = User.query.filter_by(username=u'chris').first() - assert bcrypt_check_password('123456', test_user.pw_hash) + assert auth.check_password('123456', test_user.pw_hash) # Update current user passwd self.user_password = '123456' # test that the password cannot be changed if the given - # old_password is wrong template.clear_test_template_context() + # old_password is wrong + template.clear_test_template_context() test_app.post( - '/edit/account/', { + '/edit/password/', { 'old_password': 'toast', 'new_password': '098765', }) test_user = User.query.filter_by(username=u'chris').first() - assert not bcrypt_check_password('098765', test_user.pw_hash) + assert not auth.check_password('098765', test_user.pw_hash) def test_change_bio_url(self, test_app): @@ -138,4 +141,68 @@ class TestUserEdit(object): assert form.url.errors == [ u'This address contains errors'] + def test_email_change(self, test_app): + self.login(test_app) + + # Test email already in db + template.clear_test_template_context() + test_app.post( + '/edit/account/', { + 'new_email': 'chris@example.com', + 'password': 'toast'}) + + # Check form errors + context = template.TEMPLATE_TEST_CONTEXT[ + 'mediagoblin/edit/edit_account.html'] + assert context['form'].new_email.errors == [ + u'Sorry, a user with that email address already exists.'] + + # Test successful email change + template.clear_test_template_context() + res = test_app.post( + '/edit/account/', { + 'new_email': 'new@example.com', + 'password': 'toast'}) + res.follow() + + # Correct redirect? + assert urlparse.urlsplit(res.location)[2] == '/u/chris/' + + # Make sure we get email verification and try verifying + assert len(mail.EMAIL_TEST_INBOX) == 1 + message = mail.EMAIL_TEST_INBOX.pop() + assert message['To'] == 'new@example.com' + email_context = template.TEMPLATE_TEST_CONTEXT[ + 'mediagoblin/edit/verification.txt'] + assert email_context['verification_url'] in \ + message.get_payload(decode=True) + + path = urlparse.urlsplit(email_context['verification_url'])[2] + assert path == u'/edit/verify_email/' + + ## Try verifying with bs verification key, shouldn't work + template.clear_test_template_context() + res = test_app.get( + "/edit/verify_email/?token=total_bs") + res.follow() + + # Correct redirect? + assert urlparse.urlsplit(res.location)[2] == '/' + + # Email shouldn't be saved + email_in_db = mg_globals.database.User.query.filter_by( + email='new@example.com').first() + email = User.query.filter_by(username='chris').first().email + assert email_in_db is None + assert email == 'chris@example.com' + + # Verify email activation works + template.clear_test_template_context() + get_params = urlparse.urlsplit(email_context['verification_url'])[3] + res = test_app.get('%s?%s' % (path, get_params)) + res.follow() + + # New email saved? + email = User.query.filter_by(username='chris').first().email + assert email == 'new@example.com' # test changing the url inproperly diff --git a/mediagoblin/tests/test_exif.py b/mediagoblin/tests/test_exif.py index 824de3c2..c07e24ae 100644 --- a/mediagoblin/tests/test_exif.py +++ b/mediagoblin/tests/test_exif.py @@ -48,63 +48,324 @@ def test_exif_extraction(): assert gps == {} # Do we have the "useful" tags? - assert useful == { - 'EXIF Flash': { - 'field_type': 3, - 'printable': u'Flash did not fire', - 'field_offset': 380, - 'tag': 37385, - 'values': [0], - 'field_length': 2}, - 'EXIF ExposureTime': { - 'field_type': 5, - 'printable': '1/125', - 'field_offset': 700, - 'tag': 33434, - 'values': [[1, 125]], - 'field_length': 8}, - 'EXIF FocalLength': { - 'field_type': 5, - 'printable': '18', - 'field_offset': 780, - 'tag': 37386, - 'values': [[18, 1]], - 'field_length': 8}, - 'Image Model': { - 'field_type': 2, - 'printable': 'NIKON D80', - 'field_offset': 152, - 'tag': 272, - 'values': 'NIKON D80', - 'field_length': 10}, - 'Image Make': { - 'field_type': 2, - 'printable': 'NIKON CORPORATION', - 'field_offset': 134, - 'tag': 271, - 'values': 'NIKON CORPORATION', - 'field_length': 18}, - 'EXIF ExposureMode': { - 'field_type': 3, - 'printable': 'Manual Exposure', - 'field_offset': 584, - 'tag': 41986, - 'values': [1], - 'field_length': 2}, - 'EXIF ISOSpeedRatings': { - 'field_type': 3, - 'printable': '100', - 'field_offset': 260, - 'tag': 34855, - 'values': [100], - 'field_length': 2}, - 'EXIF FNumber': { - 'field_type': 5, - 'printable': '10', - 'field_offset': 708, - 'tag': 33437, - 'values': [[10, 1]], - 'field_length': 8}} + assert useful == {'EXIF CVAPattern': {'field_length': 8, + 'field_offset': 26224, + 'field_type': 7, + 'printable': u'[0, 2, 0, 2, 1, 2, 0, 1]', + 'tag': 41730, + 'values': [0, 2, 0, 2, 1, 2, 0, 1]}, + 'EXIF ColorSpace': {'field_length': 2, + 'field_offset': 476, + 'field_type': 3, + 'printable': u'sRGB', + 'tag': 40961, + 'values': [1]}, + 'EXIF ComponentsConfiguration': {'field_length': 4, + 'field_offset': 308, + 'field_type': 7, + 'printable': u'YCbCr', + 'tag': 37121, + 'values': [1, 2, 3, 0]}, + 'EXIF CompressedBitsPerPixel': {'field_length': 8, + 'field_offset': 756, + 'field_type': 5, + 'printable': u'4', + 'tag': 37122, + 'values': [[4, 1]]}, + 'EXIF Contrast': {'field_length': 2, + 'field_offset': 656, + 'field_type': 3, + 'printable': u'Soft', + 'tag': 41992, + 'values': [1]}, + 'EXIF CustomRendered': {'field_length': 2, + 'field_offset': 572, + 'field_type': 3, + 'printable': u'Normal', + 'tag': 41985, + 'values': [0]}, + 'EXIF DateTimeDigitized': {'field_length': 20, + 'field_offset': 736, + 'field_type': 2, + 'printable': u'2011:06:22 12:20:33', + 'tag': 36868, + 'values': u'2011:06:22 12:20:33'}, + 'EXIF DateTimeOriginal': {'field_length': 20, + 'field_offset': 716, + 'field_type': 2, + 'printable': u'2011:06:22 12:20:33', + 'tag': 36867, + 'values': u'2011:06:22 12:20:33'}, + 'EXIF DigitalZoomRatio': {'field_length': 8, + 'field_offset': 26232, + 'field_type': 5, + 'printable': u'1', + 'tag': 41988, + 'values': [[1, 1]]}, + 'EXIF ExifImageLength': {'field_length': 2, + 'field_offset': 500, + 'field_type': 3, + 'printable': u'2592', + 'tag': 40963, + 'values': [2592]}, + 'EXIF ExifImageWidth': {'field_length': 2, + 'field_offset': 488, + 'field_type': 3, + 'printable': u'3872', + 'tag': 40962, + 'values': [3872]}, + 'EXIF ExifVersion': {'field_length': 4, + 'field_offset': 272, + 'field_type': 7, + 'printable': u'0221', + 'tag': 36864, + 'values': [48, 50, 50, 49]}, + 'EXIF ExposureBiasValue': {'field_length': 8, + 'field_offset': 764, + 'field_type': 10, + 'printable': u'0', + 'tag': 37380, + 'values': [[0, 1]]}, + 'EXIF ExposureMode': {'field_length': 2, + 'field_offset': 584, + 'field_type': 3, + 'printable': u'Manual Exposure', + 'tag': 41986, + 'values': [1]}, + 'EXIF ExposureProgram': {'field_length': 2, + 'field_offset': 248, + 'field_type': 3, + 'printable': u'Manual', + 'tag': 34850, + 'values': [1]}, + 'EXIF ExposureTime': {'field_length': 8, + 'field_offset': 700, + 'field_type': 5, + 'printable': u'1/125', + 'tag': 33434, + 'values': [[1, 125]]}, + 'EXIF FNumber': {'field_length': 8, + 'field_offset': 708, + 'field_type': 5, + 'printable': u'10', + 'tag': 33437, + 'values': [[10, 1]]}, + 'EXIF FileSource': {'field_length': 1, + 'field_offset': 536, + 'field_type': 7, + 'printable': u'Digital Camera', + 'tag': 41728, + 'values': [3]}, + 'EXIF Flash': {'field_length': 2, + 'field_offset': 380, + 'field_type': 3, + 'printable': u'Flash did not fire', + 'tag': 37385, + 'values': [0]}, + 'EXIF FlashPixVersion': {'field_length': 4, + 'field_offset': 464, + 'field_type': 7, + 'printable': u'0100', + 'tag': 40960, + 'values': [48, 49, 48, 48]}, + 'EXIF FocalLength': {'field_length': 8, + 'field_offset': 780, + 'field_type': 5, + 'printable': u'18', + 'tag': 37386, + 'values': [[18, 1]]}, + 'EXIF FocalLengthIn35mmFilm': {'field_length': 2, + 'field_offset': 620, + 'field_type': 3, + 'printable': u'27', + 'tag': 41989, + 'values': [27]}, + 'EXIF GainControl': {'field_length': 2, + 'field_offset': 644, + 'field_type': 3, + 'printable': u'None', + 'tag': 41991, + 'values': [0]}, + 'EXIF ISOSpeedRatings': {'field_length': 2, + 'field_offset': 260, + 'field_type': 3, + 'printable': u'100', + 'tag': 34855, + 'values': [100]}, + 'EXIF InteroperabilityOffset': {'field_length': 4, + 'field_offset': 512, + 'field_type': 4, + 'printable': u'26240', + 'tag': 40965, + 'values': [26240]}, + 'EXIF LightSource': {'field_length': 2, + 'field_offset': 368, + 'field_type': 3, + 'printable': u'Unknown', + 'tag': 37384, + 'values': [0]}, + 'EXIF MaxApertureValue': {'field_length': 8, + 'field_offset': 772, + 'field_type': 5, + 'printable': u'18/5', + 'tag': 37381, + 'values': [[18, 5]]}, + 'EXIF MeteringMode': {'field_length': 2, + 'field_offset': 356, + 'field_type': 3, + 'printable': u'Pattern', + 'tag': 37383, + 'values': [5]}, + 'EXIF Saturation': {'field_length': 2, + 'field_offset': 668, + 'field_type': 3, + 'printable': u'Normal', + 'tag': 41993, + 'values': [0]}, + 'EXIF SceneCaptureType': {'field_length': 2, + 'field_offset': 632, + 'field_type': 3, + 'printable': u'Standard', + 'tag': 41990, + 'values': [0]}, + 'EXIF SceneType': {'field_length': 1, + 'field_offset': 548, + 'field_type': 7, + 'printable': u'Directly Photographed', + 'tag': 41729, + 'values': [1]}, + 'EXIF SensingMethod': {'field_length': 2, + 'field_offset': 524, + 'field_type': 3, + 'printable': u'One-chip color area', + 'tag': 41495, + 'values': [2]}, + 'EXIF Sharpness': {'field_length': 2, + 'field_offset': 680, + 'field_type': 3, + 'printable': u'Normal', + 'tag': 41994, + 'values': [0]}, + 'EXIF SubSecTime': {'field_length': 3, + 'field_offset': 428, + 'field_type': 2, + 'printable': u'10', + 'tag': 37520, + 'values': u'10'}, + 'EXIF SubSecTimeDigitized': {'field_length': 3, + 'field_offset': 452, + 'field_type': 2, + 'printable': u'10', + 'tag': 37522, + 'values': u'10'}, + 'EXIF SubSecTimeOriginal': {'field_length': 3, + 'field_offset': 440, + 'field_type': 2, + 'printable': u'10', + 'tag': 37521, + 'values': u'10'}, + 'EXIF SubjectDistanceRange': {'field_length': 2, + 'field_offset': 692, + 'field_type': 3, + 'printable': u'0', + 'tag': 41996, + 'values': [0]}, + 'EXIF WhiteBalance': {'field_length': 2, + 'field_offset': 596, + 'field_type': 3, + 'printable': u'Auto', + 'tag': 41987, + 'values': [0]}, + 'Image DateTime': {'field_length': 20, + 'field_offset': 194, + 'field_type': 2, + 'printable': u'2011:06:22 12:20:33', + 'tag': 306, + 'values': u'2011:06:22 12:20:33'}, + 'Image ExifOffset': {'field_length': 4, + 'field_offset': 126, + 'field_type': 4, + 'printable': u'214', + 'tag': 34665, + 'values': [214]}, + 'Image Make': {'field_length': 18, + 'field_offset': 134, + 'field_type': 2, + 'printable': u'NIKON CORPORATION', + 'tag': 271, + 'values': u'NIKON CORPORATION'}, + 'Image Model': {'field_length': 10, + 'field_offset': 152, + 'field_type': 2, + 'printable': u'NIKON D80', + 'tag': 272, + 'values': u'NIKON D80'}, + 'Image Orientation': {'field_length': 2, + 'field_offset': 42, + 'field_type': 3, + 'printable': u'Rotated 90 CCW', + 'tag': 274, + 'values': [6]}, + 'Image ResolutionUnit': {'field_length': 2, + 'field_offset': 78, + 'field_type': 3, + 'printable': u'Pixels/Inch', + 'tag': 296, + 'values': [2]}, + 'Image Software': {'field_length': 15, + 'field_offset': 178, + 'field_type': 2, + 'printable': u'Shotwell 0.9.3', + 'tag': 305, + 'values': u'Shotwell 0.9.3'}, + 'Image XResolution': {'field_length': 8, + 'field_offset': 162, + 'field_type': 5, + 'printable': u'300', + 'tag': 282, + 'values': [[300, 1]]}, + 'Image YCbCrPositioning': {'field_length': 2, + 'field_offset': 114, + 'field_type': 3, + 'printable': u'Co-sited', + 'tag': 531, + 'values': [2]}, + 'Image YResolution': {'field_length': 8, + 'field_offset': 170, + 'field_type': 5, + 'printable': u'300', + 'tag': 283, + 'values': [[300, 1]]}, + 'Thumbnail Compression': {'field_length': 2, + 'field_offset': 26280, + 'field_type': 3, + 'printable': u'JPEG (old-style)', + 'tag': 259, + 'values': [6]}, + 'Thumbnail ResolutionUnit': {'field_length': 2, + 'field_offset': 26316, + 'field_type': 3, + 'printable': u'Pixels/Inch', + 'tag': 296, + 'values': [2]}, + 'Thumbnail XResolution': {'field_length': 8, + 'field_offset': 26360, + 'field_type': 5, + 'printable': u'300', + 'tag': 282, + 'values': [[300, 1]]}, + 'Thumbnail YCbCrPositioning': {'field_length': 2, + 'field_offset': 26352, + 'field_type': 3, + 'printable': u'Co-sited', + 'tag': 531, + 'values': [2]}, + 'Thumbnail YResolution': {'field_length': 8, + 'field_offset': 26368, + 'field_type': 5, + 'printable': u'300', + 'tag': 283, + 'values': [[300, 1]]}} def test_exif_image_orientation(): diff --git a/mediagoblin/tests/test_mgoblin_app.ini b/mediagoblin/tests/test_mgoblin_app.ini index 2e876812..535cf1c1 100644 --- a/mediagoblin/tests/test_mgoblin_app.ini +++ b/mediagoblin/tests/test_mgoblin_app.ini @@ -3,8 +3,9 @@ direct_remote_path = /test_static/ email_sender_address = "notice@mediagoblin.example.org" email_debug_mode = true -# TODO: Switch to using an in-memory database -sql_engine = "sqlite:///%(here)s/test_user_dev/mediagoblin.db" +#Runs with an in-memory sqlite db for speed. +sql_engine = "sqlite://" +run_migrations = true # tag parsing tags_max_length = 50 @@ -12,22 +13,24 @@ tags_max_length = 50 # So we can start to test attachments: allow_attachments = True -media_types = mediagoblin.media_types.image, mediagoblin.media_types.pdf - [storage:publicstore] -base_dir = %(here)s/test_user_dev/media/public +base_dir = %(here)s/user_dev/media/public base_url = /mgoblin_media/ [storage:queuestore] -base_dir = %(here)s/test_user_dev/media/queue +base_dir = %(here)s/user_dev/media/queue [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" +CELERY_RESULT_DBURI = "sqlite:///%(here)s/user_dev/celery.db" +BROKER_HOST = "sqlite:///%(here)s/user_dev/kombu.db" [plugins] [[mediagoblin.plugins.api]] [[mediagoblin.plugins.oauth]] [[mediagoblin.plugins.httpapiauth]] [[mediagoblin.plugins.piwigo]] +[[mediagoblin.plugins.basic_auth]] +[[mediagoblin.plugins.openid]] +[[mediagoblin.media_types.image]] +[[mediagoblin.media_types.pdf]] diff --git a/mediagoblin/tests/test_misc.py b/mediagoblin/tests/test_misc.py index 755d863f..43ad0b6d 100644 --- a/mediagoblin/tests/test_misc.py +++ b/mediagoblin/tests/test_misc.py @@ -28,8 +28,10 @@ def test_user_deletes_other_comments(test_app): user_a = fixture_add_user(u"chris_a") user_b = fixture_add_user(u"chris_b") - media_a = fixture_media_entry(uploader=user_a.id, save=False) - media_b = fixture_media_entry(uploader=user_b.id, save=False) + media_a = fixture_media_entry(uploader=user_a.id, save=False, + expunge=False, fake_upload=False) + media_b = fixture_media_entry(uploader=user_b.id, save=False, + expunge=False, fake_upload=False) Session.add(media_a) Session.add(media_b) Session.flush() @@ -79,7 +81,7 @@ def test_user_deletes_other_comments(test_app): def test_media_deletes_broken_attachment(test_app): user_a = fixture_add_user(u"chris_a") - media = fixture_media_entry(uploader=user_a.id, save=False) + media = fixture_media_entry(uploader=user_a.id, save=False, expunge=False) media.attachment_files.append(dict( name=u"some name", filepath=[u"does", u"not", u"exist"], diff --git a/mediagoblin/tests/test_notifications.py b/mediagoblin/tests/test_notifications.py new file mode 100644 index 00000000..d52b8d5a --- /dev/null +++ b/mediagoblin/tests/test_notifications.py @@ -0,0 +1,151 @@ +# 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 pytest + +import urlparse + +from mediagoblin.tools import template, mail + +from mediagoblin.db.models import Notification, CommentNotification, \ + CommentSubscription +from mediagoblin.db.base import Session + +from mediagoblin.notifications import mark_comment_notification_seen + +from mediagoblin.tests.tools import fixture_add_comment, \ + fixture_media_entry, fixture_add_user, \ + fixture_comment_subscription + + +class TestNotifications: + @pytest.fixture(autouse=True) + def setup(self, test_app): + self.test_app = test_app + + # TODO: Possibly abstract into a decorator like: + # @as_authenticated_user('chris') + self.test_user = fixture_add_user() + + self.current_user = None + + self.login() + + def login(self, username=u'chris', password=u'toast'): + response = self.test_app.post( + '/auth/login/', { + 'username': username, + 'password': password}) + + response.follow() + + assert urlparse.urlsplit(response.location)[2] == '/' + assert 'mediagoblin/root.html' in template.TEMPLATE_TEST_CONTEXT + + ctx = template.TEMPLATE_TEST_CONTEXT['mediagoblin/root.html'] + + assert Session.merge(ctx['request'].user).username == username + + self.current_user = ctx['request'].user + + def logout(self): + self.test_app.get('/auth/logout/') + self.current_user = None + + @pytest.mark.parametrize('wants_email', [True, False]) + def test_comment_notification(self, wants_email): + ''' + Test + - if a notification is created when posting a comment on + another users media entry. + - that the comment data is consistent and exists. + + ''' + user = fixture_add_user('otherperson', password='nosreprehto', + wants_comment_notification=wants_email) + + user_id = user.id + + media_entry = fixture_media_entry(uploader=user.id, state=u'processed') + + media_entry_id = media_entry.id + + subscription = fixture_comment_subscription(media_entry) + + subscription_id = subscription.id + + media_uri_id = '/u/{0}/m/{1}/'.format(user.username, + media_entry.id) + media_uri_slug = '/u/{0}/m/{1}/'.format(user.username, + media_entry.slug) + + self.test_app.post( + media_uri_id + 'comment/add/', + { + 'comment_content': u'Test comment #42' + } + ) + + notifications = Notification.query.filter_by( + user_id=user.id).all() + + assert len(notifications) == 1 + + notification = notifications[0] + + assert type(notification) == CommentNotification + assert notification.seen == False + assert notification.user_id == user.id + assert notification.subject.get_author.id == self.test_user.id + assert notification.subject.content == u'Test comment #42' + + if wants_email == True: + assert mail.EMAIL_TEST_MBOX_INBOX == [ + {'from': 'notice@mediagoblin.example.org', + 'message': 'Content-Type: text/plain; \ +charset="utf-8"\nMIME-Version: 1.0\nContent-Transfer-Encoding: \ +base64\nSubject: GNU MediaGoblin - chris commented on your \ +post\nFrom: notice@mediagoblin.example.org\nTo: \ +otherperson@example.com\n\nSGkgb3RoZXJwZXJzb24sCmNocmlzIGNvbW1lbnRlZCBvbiB5b3VyIHBvc3QgKGh0dHA6Ly9sb2Nh\nbGhvc3Q6ODAvdS9vdGhlcnBlcnNvbi9tL3NvbWUtdGl0bGUvYy8xLyNjb21tZW50KSBhdCBHTlUg\nTWVkaWFHb2JsaW4KClRlc3QgY29tbWVudCAjNDIKCkdOVSBNZWRpYUdvYmxpbg==\n', + 'to': [u'otherperson@example.com']}] + else: + assert mail.EMAIL_TEST_MBOX_INBOX == [] + + # Save the ids temporarily because of DetachedInstanceError + notification_id = notification.id + comment_id = notification.subject.id + + self.logout() + self.login('otherperson', 'nosreprehto') + + self.test_app.get(media_uri_slug + '/c/{0}/'.format(comment_id)) + + notification = Notification.query.filter_by(id=notification_id).first() + + assert notification.seen == True + + self.test_app.get(media_uri_slug + '/notifications/silence/') + + subscription = CommentSubscription.query.filter_by(id=subscription_id)\ + .first() + + assert subscription.notify == False + + notifications = Notification.query.filter_by( + user_id=user_id).all() + + # User should not have been notified + assert len(notifications) == 1 diff --git a/mediagoblin/tests/test_openid.py b/mediagoblin/tests/test_openid.py new file mode 100644 index 00000000..23a2290e --- /dev/null +++ b/mediagoblin/tests/test_openid.py @@ -0,0 +1,373 @@ +# 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 urlparse +import pkg_resources +import pytest +import mock + +openid_consumer = pytest.importorskip( + "openid.consumer.consumer") + +from mediagoblin import mg_globals +from mediagoblin.db.base import Session +from mediagoblin.db.models import User +from mediagoblin.plugins.openid.models import OpenIDUserURL +from mediagoblin.tests.tools import get_app, fixture_add_user +from mediagoblin.tools import template + +# App with plugin enabled +@pytest.fixture() +def openid_plugin_app(request): + return get_app( + request, + mgoblin_config=pkg_resources.resource_filename( + 'mediagoblin.tests.auth_configs', + 'openid_appconfig.ini')) + + +class TestOpenIDPlugin(object): + def _setup(self, openid_plugin_app, value=True, edit=False, delete=False): + if value: + response = openid_consumer.SuccessResponse(mock.Mock(), mock.Mock()) + if edit or delete: + response.identity_url = u'http://add.myopenid.com' + else: + response.identity_url = u'http://real.myopenid.com' + self._finish_verification = mock.Mock(return_value=response) + else: + self._finish_verification = mock.Mock(return_value=False) + + @mock.patch('mediagoblin.plugins.openid.views._response_email', mock.Mock(return_value=None)) + @mock.patch('mediagoblin.plugins.openid.views._response_nickname', mock.Mock(return_value=None)) + @mock.patch('mediagoblin.plugins.openid.views._finish_verification', self._finish_verification) + def _setup_start(self, openid_plugin_app, edit, delete): + if edit: + self._start_verification = mock.Mock(return_value=openid_plugin_app.post( + '/edit/openid/finish/')) + elif delete: + self._start_verification = mock.Mock(return_value=openid_plugin_app.post( + '/edit/openid/delete/finish/')) + else: + self._start_verification = mock.Mock(return_value=openid_plugin_app.post( + '/auth/openid/login/finish/')) + _setup_start(self, openid_plugin_app, edit, delete) + + def test_bad_login(self, openid_plugin_app): + """ Test that attempts to login with invalid paramaters""" + + # Test GET request for auth/register page + res = openid_plugin_app.get('/auth/register/').follow() + + # Make sure it redirected to the correct place + assert urlparse.urlsplit(res.location)[2] == '/auth/openid/login/' + + # Test GET request for auth/login page + res = openid_plugin_app.get('/auth/login/') + res.follow() + + # Correct redirect? + assert urlparse.urlsplit(res.location)[2] == '/auth/openid/login/' + + # Test GET request for auth/openid/register page + res = openid_plugin_app.get('/auth/openid/register/') + res.follow() + + # Correct redirect? + assert urlparse.urlsplit(res.location)[2] == '/auth/openid/login/' + + # Test GET request for auth/openid/login/finish page + res = openid_plugin_app.get('/auth/openid/login/finish/') + res.follow() + + # Correct redirect? + assert urlparse.urlsplit(res.location)[2] == '/auth/openid/login/' + + # Test GET request for auth/openid/login page + res = openid_plugin_app.get('/auth/openid/login/') + + # Correct place? + assert 'mediagoblin/plugins/openid/login.html' in template.TEMPLATE_TEST_CONTEXT + + # Try to login with an empty form + template.clear_test_template_context() + openid_plugin_app.post( + '/auth/openid/login/', {}) + context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/plugins/openid/login.html'] + form = context['login_form'] + assert form.openid.errors == [u'This field is required.'] + + # Try to login with wrong form values + template.clear_test_template_context() + openid_plugin_app.post( + '/auth/openid/login/', { + 'openid': 'not_a_url.com'}) + context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/plugins/openid/login.html'] + form = context['login_form'] + assert form.openid.errors == [u'Please enter a valid url.'] + + # Should be no users in the db + assert User.query.count() == 0 + + # Phony OpenID URl + template.clear_test_template_context() + openid_plugin_app.post( + '/auth/openid/login/', { + 'openid': 'http://phoney.myopenid.com/'}) + context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/plugins/openid/login.html'] + form = context['login_form'] + assert form.openid.errors == [u'Sorry, the OpenID server could not be found'] + + def test_login(self, openid_plugin_app): + """Tests that test login and registion with openid""" + # Test finish_login redirects correctly when response = False + self._setup(openid_plugin_app, False) + + @mock.patch('mediagoblin.plugins.openid.views._finish_verification', self._finish_verification) + @mock.patch('mediagoblin.plugins.openid.views._start_verification', self._start_verification) + def _test_non_response(): + template.clear_test_template_context() + res = openid_plugin_app.post( + '/auth/openid/login/', { + 'openid': 'http://phoney.myopenid.com/'}) + res.follow() + + # Correct Place? + assert urlparse.urlsplit(res.location)[2] == '/auth/openid/login/' + assert 'mediagoblin/plugins/openid/login.html' in template.TEMPLATE_TEST_CONTEXT + _test_non_response() + + # Test login with new openid + # Need to clear_test_template_context before calling _setup + template.clear_test_template_context() + self._setup(openid_plugin_app) + + @mock.patch('mediagoblin.plugins.openid.views._finish_verification', self._finish_verification) + @mock.patch('mediagoblin.plugins.openid.views._start_verification', self._start_verification) + def _test_new_user(): + openid_plugin_app.post( + '/auth/openid/login/', { + 'openid': u'http://real.myopenid.com'}) + + # Right place? + assert 'mediagoblin/auth/register.html' in template.TEMPLATE_TEST_CONTEXT + context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/auth/register.html'] + register_form = context['register_form'] + + # Register User + res = openid_plugin_app.post( + '/auth/openid/register/', { + 'openid': register_form.openid.data, + 'username': u'chris', + 'email': u'chris@example.com'}) + res.follow() + + # Correct place? + assert urlparse.urlsplit(res.location)[2] == '/u/chris/' + assert 'mediagoblin/user_pages/user.html' in template.TEMPLATE_TEST_CONTEXT + + # No need to test if user is in logged in and verification email + # awaits, since openid uses the register_user function which is + # tested in test_auth + + # Logout User + openid_plugin_app.get('/auth/logout') + + # Get user and detach from session + test_user = mg_globals.database.User.query.filter_by( + username=u'chris').first() + Session.expunge(test_user) + + # Log back in + # Could not get it to work by 'POST'ing to /auth/openid/login/ + template.clear_test_template_context() + res = openid_plugin_app.post( + '/auth/openid/login/finish/', { + 'openid': u'http://real.myopenid.com'}) + res.follow() + + assert urlparse.urlsplit(res.location)[2] == '/' + assert 'mediagoblin/root.html' in template.TEMPLATE_TEST_CONTEXT + + # Make sure user is in the session + context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/root.html'] + session = context['request'].session + assert session['user_id'] == unicode(test_user.id) + + _test_new_user() + + # Test register with empty form + template.clear_test_template_context() + openid_plugin_app.post( + '/auth/openid/register/', {}) + context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/auth/register.html'] + register_form = context['register_form'] + + assert register_form.openid.errors == [u'This field is required.'] + assert register_form.email.errors == [u'This field is required.'] + assert register_form.username.errors == [u'This field is required.'] + + # Try to register with existing username and email + template.clear_test_template_context() + openid_plugin_app.post( + '/auth/openid/register/', { + 'openid': 'http://real.myopenid.com', + 'email': 'chris@example.com', + 'username': 'chris'}) + context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/auth/register.html'] + register_form = context['register_form'] + + assert register_form.username.errors == [u'Sorry, a user with that name already exists.'] + assert register_form.email.errors == [u'Sorry, a user with that email address already exists.'] + assert register_form.openid.errors == [u'Sorry, an account is already registered to that OpenID.'] + + def test_add_delete(self, openid_plugin_app): + """Test adding and deleting openids""" + # Add user + test_user = fixture_add_user(password='') + openid = OpenIDUserURL() + openid.openid_url = 'http://real.myopenid.com' + openid.user_id = test_user.id + openid.save() + + # Log user in + template.clear_test_template_context() + self._setup(openid_plugin_app) + + @mock.patch('mediagoblin.plugins.openid.views._finish_verification', self._finish_verification) + @mock.patch('mediagoblin.plugins.openid.views._start_verification', self._start_verification) + def _login_user(): + openid_plugin_app.post( + '/auth/openid/login/finish/', { + 'openid': u'http://real.myopenid.com'}) + + _login_user() + + # Try and delete only OpenID url + template.clear_test_template_context() + res = openid_plugin_app.post( + '/edit/openid/delete/', { + 'openid': 'http://real.myopenid.com'}) + assert 'mediagoblin/plugins/openid/delete.html' in template.TEMPLATE_TEST_CONTEXT + + # Add OpenID to user + # Empty form + template.clear_test_template_context() + res = openid_plugin_app.post( + '/edit/openid/', {}) + context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/plugins/openid/add.html'] + form = context['form'] + assert form.openid.errors == [u'This field is required.'] + + # Try with a bad url + template.clear_test_template_context() + openid_plugin_app.post( + '/edit/openid/', { + 'openid': u'not_a_url.com'}) + context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/plugins/openid/add.html'] + form = context['form'] + assert form.openid.errors == [u'Please enter a valid url.'] + + # Try with a url that's already registered + template.clear_test_template_context() + openid_plugin_app.post( + '/edit/openid/', { + 'openid': 'http://real.myopenid.com'}) + context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/plugins/openid/add.html'] + form = context['form'] + assert form.openid.errors == [u'Sorry, an account is already registered to that OpenID.'] + + # Test adding openid to account + # Need to clear_test_template_context before calling _setup + template.clear_test_template_context() + self._setup(openid_plugin_app, edit=True) + + # Need to remove openid_url from db because it was added at setup + openid = OpenIDUserURL.query.filter_by( + openid_url=u'http://add.myopenid.com') + openid.delete() + + @mock.patch('mediagoblin.plugins.openid.views._finish_verification', self._finish_verification) + @mock.patch('mediagoblin.plugins.openid.views._start_verification', self._start_verification) + def _test_add(): + # Successful add + template.clear_test_template_context() + res = openid_plugin_app.post( + '/edit/openid/', { + 'openid': u'http://add.myopenid.com'}) + res.follow() + + # Correct place? + assert urlparse.urlsplit(res.location)[2] == '/edit/account/' + assert 'mediagoblin/edit/edit_account.html' in template.TEMPLATE_TEST_CONTEXT + + # OpenID Added? + new_openid = mg_globals.database.OpenIDUserURL.query.filter_by( + openid_url=u'http://add.myopenid.com').first() + assert new_openid + + _test_add() + + # Test deleting openid from account + # Need to clear_test_template_context before calling _setup + template.clear_test_template_context() + self._setup(openid_plugin_app, delete=True) + + # Need to add OpenID back to user because it was deleted during + # patch + openid = OpenIDUserURL() + openid.openid_url = 'http://add.myopenid.com' + openid.user_id = test_user.id + openid.save() + + @mock.patch('mediagoblin.plugins.openid.views._finish_verification', self._finish_verification) + @mock.patch('mediagoblin.plugins.openid.views._start_verification', self._start_verification) + def _test_delete(self, test_user): + # Delete openid from user + # Create another user to test deleting OpenID that doesn't belong to them + new_user = fixture_add_user(username='newman') + openid = OpenIDUserURL() + openid.openid_url = 'http://realfake.myopenid.com/' + openid.user_id = new_user.id + openid.save() + + # Try and delete OpenID url that isn't the users + template.clear_test_template_context() + res = openid_plugin_app.post( + '/edit/openid/delete/', { + 'openid': 'http://realfake.myopenid.com/'}) + context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/plugins/openid/delete.html'] + form = context['form'] + assert form.openid.errors == [u'That OpenID is not registered to this account.'] + + # Delete OpenID + # Kind of weird to POST to delete/finish + template.clear_test_template_context() + res = openid_plugin_app.post( + '/edit/openid/delete/finish/', { + 'openid': u'http://add.myopenid.com'}) + res.follow() + + # Correct place? + assert urlparse.urlsplit(res.location)[2] == '/edit/account/' + assert 'mediagoblin/edit/edit_account.html' in template.TEMPLATE_TEST_CONTEXT + + # OpenID deleted? + new_openid = mg_globals.database.OpenIDUserURL.query.filter_by( + openid_url=u'http://add.myopenid.com').first() + assert not new_openid + + _test_delete(self, test_user) diff --git a/mediagoblin/tests/test_paste.ini b/mediagoblin/tests/test_paste.ini index 91ecbb84..a9595432 100644 --- a/mediagoblin/tests/test_paste.ini +++ b/mediagoblin/tests/test_paste.ini @@ -6,6 +6,8 @@ use = egg:Paste#urlmap / = mediagoblin /mgoblin_media/ = publicstore_serve /test_static/ = mediagoblin_static +/theme_static/ = theme_static +/plugin_static/ = plugin_static [app:mediagoblin] use = egg:mediagoblin#app @@ -13,12 +15,22 @@ config = %(here)s/mediagoblin.ini [app:publicstore_serve] use = egg:Paste#static -document_root = %(here)s/test_user_dev/media/public +document_root = %(here)s/user_dev/media/public [app:mediagoblin_static] use = egg:Paste#static document_root = %(here)s/mediagoblin/static/ +[app:theme_static] +use = egg:Paste#static +document_root = %(here)s/user_dev/theme_static/ +cache_max_age = 86400 + +[app:plugin_static] +use = egg:Paste#static +document_root = %(here)s/user_dev/plugin_static/ +cache_max_age = 86400 + [celery] CELERY_ALWAYS_EAGER = true diff --git a/mediagoblin/tests/test_piwigo.py b/mediagoblin/tests/test_piwigo.py index 18f95057..16ad0111 100644 --- a/mediagoblin/tests/test_piwigo.py +++ b/mediagoblin/tests/test_piwigo.py @@ -44,11 +44,13 @@ class Test_PWG(object): def test_session(self): resp = self.do_post("pwg.session.login", {"username": u"nouser", "password": "wrong"}) - assert resp.body == XML_PREFIX + '<rsp stat="ok">0</rsp>' + assert resp.body == XML_PREFIX \ + + '<rsp stat="fail"><err code="999" msg="Invalid username/password"/></rsp>' resp = self.do_post("pwg.session.login", {"username": self.username, "password": "wrong"}) - assert resp.body == XML_PREFIX + '<rsp stat="ok">0</rsp>' + assert resp.body == XML_PREFIX \ + + '<rsp stat="fail"><err code="999" msg="Invalid username/password"/></rsp>' resp = self.do_get("pwg.session.getStatus") assert resp.body == XML_PREFIX \ @@ -56,7 +58,7 @@ class Test_PWG(object): resp = self.do_post("pwg.session.login", {"username": self.username, "password": self.password}) - assert resp.body == XML_PREFIX + '<rsp stat="ok">1</rsp>' + assert resp.body == XML_PREFIX + '<rsp stat="ok">1</rsp>' resp = self.do_get("pwg.session.getStatus") assert resp.body == XML_PREFIX \ diff --git a/mediagoblin/tests/test_pluginapi.py b/mediagoblin/tests/test_pluginapi.py index 809b5ce9..eae0ce15 100644 --- a/mediagoblin/tests/test_pluginapi.py +++ b/mediagoblin/tests/test_pluginapi.py @@ -14,6 +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 os +import json import sys from configobj import ConfigObj @@ -24,7 +26,10 @@ from validate import VdtTypeError from mediagoblin import mg_globals from mediagoblin.init.plugins import setup_plugins from mediagoblin.init.config import read_mediagoblin_config +from mediagoblin.gmg_commands.assetlink import link_plugin_assets from mediagoblin.tools import pluginapi +from mediagoblin.tests.tools import get_app +from mediagoblin.tools.common import CollectingPrinter def with_cleanup(*modules_to_delete): @@ -323,3 +328,139 @@ def test_plugin_config(): # the callables thing shouldn't really have anything though. assert len(config['plugins'][ 'mediagoblin.tests.testplugins.callables1']) == 0 + + +@pytest.fixture() +def context_modified_app(request): + """ + Get a MediaGoblin app fixture using appconfig_context_modified.ini + """ + return get_app( + request, + mgoblin_config=pkg_resources.resource_filename( + 'mediagoblin.tests', 'appconfig_context_modified.ini')) + + +def test_modify_context(context_modified_app): + """ + Test that we can modify both the view/template specific and + global contexts for templates. + """ + # Specific thing passed into a page + result = context_modified_app.get("/modify_context/specific/") + assert result.body.strip() == """Specific page! + +specific thing: in yer specificpage +global thing: globally appended! +something: orother +doubleme: happyhappy""" + + # General test, should have global context variable only + result = context_modified_app.get("/modify_context/") + assert result.body.strip() == """General page! + +global thing: globally appended! +lol: cats +doubleme: joyjoy""" + + +@pytest.fixture() +def static_plugin_app(request): + """ + Get a MediaGoblin app fixture using appconfig_static_plugin.ini + """ + return get_app( + request, + mgoblin_config=pkg_resources.resource_filename( + 'mediagoblin.tests', 'appconfig_static_plugin.ini')) + + +def test_plugin_assetlink(static_plugin_app): + """ + Test that the assetlink command works correctly + """ + linked_assets_dir = mg_globals.app_config['plugin_linked_assets_dir'] + plugin_link_dir = os.path.join( + linked_assets_dir.rstrip(os.path.sep), + 'staticstuff') + + plugin_statics = pluginapi.hook_runall("static_setup") + assert len(plugin_statics) == 1 + plugin_static = plugin_statics[0] + + def run_assetlink(): + printer = CollectingPrinter() + + link_plugin_assets( + plugin_static, linked_assets_dir, printer) + + return printer + + # it shouldn't exist yet + assert not os.path.lexists(plugin_link_dir) + + # link dir doesn't exist, link it + result = run_assetlink().collection[0] + assert result == \ + 'Linked asset directory for plugin "staticstuff":\n %s\nto:\n %s\n' % ( + plugin_static.file_path.rstrip(os.path.sep), + plugin_link_dir) + assert os.path.lexists(plugin_link_dir) + assert os.path.islink(plugin_link_dir) + assert os.path.realpath(plugin_link_dir) == plugin_static.file_path + + # link dir exists, leave it alone + # (and it should exist still since we just ran it..) + result = run_assetlink().collection[0] + assert result == 'Skipping "staticstuff"; already set up.\n' + assert os.path.lexists(plugin_link_dir) + assert os.path.islink(plugin_link_dir) + assert os.path.realpath(plugin_link_dir) == plugin_static.file_path + + # link dir exists, is a symlink to somewhere else (re-link) + junk_file_path = os.path.join( + linked_assets_dir.rstrip(os.path.sep), + 'junk.txt') + with file(junk_file_path, 'w') as junk_file: + junk_file.write('barf') + + os.unlink(plugin_link_dir) + os.symlink(junk_file_path, plugin_link_dir) + + result = run_assetlink().combined_string + assert result == """Old link found for "staticstuff"; removing. +Linked asset directory for plugin "staticstuff": + %s +to: + %s +""" % (plugin_static.file_path.rstrip(os.path.sep), plugin_link_dir) + assert os.path.lexists(plugin_link_dir) + assert os.path.islink(plugin_link_dir) + assert os.path.realpath(plugin_link_dir) == plugin_static.file_path + + # link dir exists, but is a non-symlink + os.unlink(plugin_link_dir) + with file(plugin_link_dir, 'w') as clobber_file: + clobber_file.write('clobbered!') + + result = run_assetlink().collection[0] + assert result == 'Could not link "staticstuff": %s exists and is not a symlink\n' % ( + plugin_link_dir) + + with file(plugin_link_dir, 'r') as clobber_file: + assert clobber_file.read() == 'clobbered!' + + +def test_plugin_staticdirect(static_plugin_app): + """ + Test that the staticdirect utilities pull up the right things + """ + result = json.loads( + static_plugin_app.get('/staticstuff/').body) + + assert len(result) == 2 + + assert result['mgoblin_bunny_pic'] == '/test_static/images/bunny_pic.png' + assert result['plugin_bunny_css'] == \ + '/plugin_static/staticstuff/css/bunnify.css' + diff --git a/mediagoblin/tests/test_submission.py b/mediagoblin/tests/test_submission.py index 162b2d19..ac941063 100644 --- a/mediagoblin/tests/test_submission.py +++ b/mediagoblin/tests/test_submission.py @@ -26,7 +26,7 @@ from mediagoblin.tests.tools import fixture_add_user from mediagoblin import mg_globals from mediagoblin.db.models import MediaEntry from mediagoblin.tools import template -from mediagoblin.media_types.image import MEDIA_MANAGER as img_MEDIA_MANAGER +from mediagoblin.media_types.image import ImageMediaManager from mediagoblin.media_types.pdf.processing import check_prerequisites as pdf_check_prerequisites from .resources import GOOD_JPG, GOOD_PNG, EVIL_FILE, EVIL_JPG, EVIL_PNG, \ @@ -77,7 +77,7 @@ class TestSubmission: return {'upload_files': [('file', filename)]} def check_comments(self, request, media_id, count): - comments = request.db.MediaComment.find({'media_entry': media_id}) + comments = request.db.MediaComment.query.filter_by(media_entry=media_id) assert count == len(list(comments)) def test_missing_fields(self): @@ -122,7 +122,7 @@ class TestSubmission: assert 'mediagoblin/user_pages/user.html' in context def check_media(self, request, find_data, count=None): - media = MediaEntry.find(find_data) + media = MediaEntry.query.filter_by(**find_data) if count is not None: assert media.count() == count if count == 0: @@ -219,7 +219,7 @@ class TestSubmission: media = self.check_media(request, {'title': u'Balanced Goblin'}, 1) assert media.media_type == u'mediagoblin.media_types.image' - assert isinstance(media.media_manager, img_MEDIA_MANAGER) + assert isinstance(media.media_manager, ImageMediaManager) assert media.media_manager.entry == media @@ -240,8 +240,8 @@ class TestSubmission: request = context['request'] - media = request.db.MediaEntry.find_one({ - u'title': u'UNIQUE_TITLE_PLS_DONT_CREATE_OTHER_MEDIA_WITH_THIS_TITLE'}) + media = request.db.MediaEntry.query.filter_by( + title=u'UNIQUE_TITLE_PLS_DONT_CREATE_OTHER_MEDIA_WITH_THIS_TITLE').first() assert media.media_type == 'mediagoblin.media_types.image' @@ -252,7 +252,7 @@ class TestSubmission: 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}) + entry = mg_globals.database.MediaEntry.query.filter_by(title=title).first() assert entry.state == 'failed' assert entry.fail_error == u'mediagoblin.processing:BadMediaFail' diff --git a/mediagoblin/tests/testplugins/modify_context/__init__.py b/mediagoblin/tests/testplugins/modify_context/__init__.py new file mode 100644 index 00000000..164e66c1 --- /dev/null +++ b/mediagoblin/tests/testplugins/modify_context/__init__.py @@ -0,0 +1,55 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +from mediagoblin.tools import pluginapi +import pkg_resources + + +def append_to_specific_context(context): + context['specific_page_append'] = 'in yer specificpage' + return context + +def append_to_global_context(context): + context['global_append'] = 'globally appended!' + return context + +def double_doubleme(context): + if 'doubleme' in context: + context['doubleme'] = context['doubleme'] * 2 + return context + + +def setup_plugin(): + routes = [ + ('modify_context.specific_page', + '/modify_context/specific/', + 'mediagoblin.tests.testplugins.modify_context.views:specific'), + ('modify_context.general_page', + '/modify_context/', + 'mediagoblin.tests.testplugins.modify_context.views:general')] + + pluginapi.register_routes(routes) + pluginapi.register_template_path( + pkg_resources.resource_filename( + 'mediagoblin.tests.testplugins.modify_context', 'templates')) + + +hooks = { + 'setup': setup_plugin, + ('modify_context.specific_page', + 'contextplugin/specific.html'): append_to_specific_context, + 'template_global_context': append_to_global_context, + 'template_context_prerender': double_doubleme} diff --git a/mediagoblin/tests/testplugins/modify_context/templates/contextplugin/general.html b/mediagoblin/tests/testplugins/modify_context/templates/contextplugin/general.html new file mode 100644 index 00000000..9cf96d3e --- /dev/null +++ b/mediagoblin/tests/testplugins/modify_context/templates/contextplugin/general.html @@ -0,0 +1,5 @@ +General page! + +global thing: {{ global_append }} +lol: {{ lol }} +doubleme: {{ doubleme }} diff --git a/mediagoblin/tests/testplugins/modify_context/templates/contextplugin/specific.html b/mediagoblin/tests/testplugins/modify_context/templates/contextplugin/specific.html new file mode 100644 index 00000000..5b1b4c4a --- /dev/null +++ b/mediagoblin/tests/testplugins/modify_context/templates/contextplugin/specific.html @@ -0,0 +1,6 @@ +Specific page! + +specific thing: {{ specific_page_append }} +global thing: {{ global_append }} +something: {{ something }} +doubleme: {{ doubleme }} diff --git a/mediagoblin/tests/testplugins/modify_context/views.py b/mediagoblin/tests/testplugins/modify_context/views.py new file mode 100644 index 00000000..701ec6f9 --- /dev/null +++ b/mediagoblin/tests/testplugins/modify_context/views.py @@ -0,0 +1,33 @@ +# 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.tools.response import render_to_response + + +def specific(request): + return render_to_response( + request, + 'contextplugin/specific.html', + {"something": "orother", + "doubleme": "happy"}) + + +def general(request): + return render_to_response( + request, + 'contextplugin/general.html', + {"lol": "cats", + "doubleme": "joy"}) diff --git a/mediagoblin/tests/testplugins/staticstuff/__init__.py b/mediagoblin/tests/testplugins/staticstuff/__init__.py new file mode 100644 index 00000000..a2591646 --- /dev/null +++ b/mediagoblin/tests/testplugins/staticstuff/__init__.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.tools.staticdirect import PluginStatic +from mediagoblin.tools import pluginapi +from pkg_resources import resource_filename + +def setup_plugin(): + routes = [ + ('staticstuff.static_demo', + '/staticstuff/', + 'mediagoblin.tests.testplugins.staticstuff.views:static_demo')] + + pluginapi.register_routes(routes) + + +hooks = { + 'setup': setup_plugin, + 'static_setup': lambda: PluginStatic( + 'staticstuff', + resource_filename( + 'mediagoblin.tests.testplugins.staticstuff', + 'static'))} diff --git a/mediagoblin/tests/testplugins/staticstuff/static/css/bunnify.css b/mediagoblin/tests/testplugins/staticstuff/static/css/bunnify.css new file mode 100644 index 00000000..1294ab8a --- /dev/null +++ b/mediagoblin/tests/testplugins/staticstuff/static/css/bunnify.css @@ -0,0 +1,4 @@ +body { + background-color: #5edcf1; + color: #eb8add; +}
\ No newline at end of file diff --git a/mediagoblin/tests/testplugins/staticstuff/views.py b/mediagoblin/tests/testplugins/staticstuff/views.py new file mode 100644 index 00000000..34a5e8cb --- /dev/null +++ b/mediagoblin/tests/testplugins/staticstuff/views.py @@ -0,0 +1,28 @@ +# 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 json + +from werkzeug import Response + + +def static_demo(request): + return Response(json.dumps({ + # this does not exist, but we'll pretend it does ;) + 'mgoblin_bunny_pic': request.staticdirect( + 'images/bunny_pic.png'), + 'plugin_bunny_css': request.staticdirect( + 'css/bunnify.css', 'staticstuff')})) diff --git a/mediagoblin/tests/tools.py b/mediagoblin/tests/tools.py index 794ed940..98361adc 100644 --- a/mediagoblin/tests/tools.py +++ b/mediagoblin/tests/tools.py @@ -15,23 +15,22 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. -import sys import os import pkg_resources import shutil -from functools import wraps from paste.deploy import loadapp from webtest import TestApp from mediagoblin import mg_globals -from mediagoblin.db.models import User, MediaEntry, Collection +from mediagoblin.db.models import User, MediaEntry, Collection, MediaComment, \ + CommentSubscription, CommentNotification from mediagoblin.tools import testing from mediagoblin.init.config import read_mediagoblin_config from mediagoblin.db.base import Session from mediagoblin.meddleware import BaseMeddleware -from mediagoblin.auth.lib import bcrypt_gen_password_hash +from mediagoblin.auth import gen_password_hash from mediagoblin.gmg_commands.dbupdate import run_dbupdate @@ -40,8 +39,6 @@ TEST_SERVER_CONFIG = pkg_resources.resource_filename( 'mediagoblin.tests', 'test_paste.ini') TEST_APP_CONFIG = pkg_resources.resource_filename( 'mediagoblin.tests', 'test_mgoblin_app.ini') -TEST_USER_DEV = pkg_resources.resource_filename( - 'mediagoblin.tests', 'test_user_dev') USER_DEV_DIRECTORIES_TO_SETUP = ['media/public', 'media/queue'] @@ -103,7 +100,7 @@ def get_app(request, paste_config=None, mgoblin_config=None): # This is the directory we're copying the paste/mgoblin config stuff into run_dir = request.config._tmpdirhandler.mktemp( 'mgoblin_app', numbered=True) - user_dev_dir = run_dir.mkdir('test_user_dev').strpath + user_dev_dir = run_dir.mkdir('user_dev').strpath new_paste_config = run_dir.join('paste.ini').strpath new_mgoblin_config = run_dir.join('mediagoblin.ini').strpath @@ -167,13 +164,13 @@ def assert_db_meets_expected(db, expected): for collection_name, collection_data in expected.iteritems(): collection = db[collection_name] for expected_document in collection_data: - document = collection.find_one({'id': expected_document['id']}) + document = collection.query.filter_by(id=expected_document['id']).first() assert document is not None # make sure it exists assert document == expected_document # make sure it matches def fixture_add_user(username=u'chris', password=u'toast', - active_user=True): + active_user=True, wants_comment_notification=True): # Reuse existing user or create a new one test_user = User.query.filter_by(username=username).first() if test_user is None: @@ -181,11 +178,13 @@ def fixture_add_user(username=u'chris', password=u'toast', test_user.username = username test_user.email = username + u'@example.com' if password is not None: - test_user.pw_hash = bcrypt_gen_password_hash(password) + test_user.pw_hash = gen_password_hash(password) if active_user: test_user.email_verified = True test_user.status = u'active' + test_user.wants_comment_notification = wants_comment_notification + test_user.save() # Reload @@ -197,19 +196,79 @@ def fixture_add_user(username=u'chris', password=u'toast', return test_user +def fixture_comment_subscription(entry, notify=True, send_email=None): + if send_email is None: + uploader = User.query.filter_by(id=entry.uploader).first() + send_email = uploader.wants_comment_notification + + cs = CommentSubscription( + media_entry_id=entry.id, + user_id=entry.uploader, + notify=notify, + send_email=send_email) + + cs.save() + + cs = CommentSubscription.query.filter_by(id=cs.id).first() + + Session.expunge(cs) + + return cs + + +def fixture_add_comment_notification(entry_id, subject_id, user_id, + seen=False): + cn = CommentNotification(user_id=user_id, + seen=seen, + subject_id=subject_id) + cn.save() + + cn = CommentNotification.query.filter_by(id=cn.id).first() + + Session.expunge(cn) + + return cn + + def fixture_media_entry(title=u"Some title", slug=None, - uploader=None, save=True, gen_slug=True): + uploader=None, save=True, gen_slug=True, + state=u'unprocessed', fake_upload=True, + expunge=True): + """ + Add a media entry for testing purposes. + + Caution: if you're adding multiple entries with fake_upload=True, + make sure you save between them... otherwise you'll hit an + IntegrityError from multiple newly-added-MediaEntries adding + FileKeynames at once. :) + """ + if uploader is None: + uploader = fixture_add_user().id + entry = MediaEntry() entry.title = title entry.slug = slug - entry.uploader = uploader or fixture_add_user().id + entry.uploader = uploader entry.media_type = u'image' + entry.state = state + + if fake_upload: + entry.media_files = {'thumb': ['a', 'b', 'c.jpg'], + 'medium': ['d', 'e', 'f.png'], + 'original': ['g', 'h', 'i.png']} + entry.media_type = u'mediagoblin.media_types.image' if gen_slug: entry.generate_slug() + if save: entry.save() + if expunge: + entry = MediaEntry.query.filter_by(id=entry.id).first() + + Session.expunge(entry) + return entry @@ -232,3 +291,26 @@ def fixture_add_collection(name=u"My first Collection", user=None): Session.expunge(coll) return coll + +def fixture_add_comment(author=None, media_entry=None, comment=None): + if author is None: + author = fixture_add_user().id + + if media_entry is None: + media_entry = fixture_media_entry().id + + if comment is None: + comment = \ + 'Auto-generated test comment by user #{0} on media #{0}'.format( + author, media_entry) + + comment = MediaComment(author=author, + media_entry=media_entry, + content=comment) + + comment.save() + + Session.expunge(comment) + + return comment + diff --git a/mediagoblin/tools/exif.py b/mediagoblin/tools/exif.py index d0f9d0a6..6b3639e8 100644 --- a/mediagoblin/tools/exif.py +++ b/mediagoblin/tools/exif.py @@ -134,7 +134,7 @@ def _ratio_to_list(ratio): def get_useful(tags): - return dict((key, tag) for (key, tag) in tags.iteritems() if key in USEFUL_TAGS) + return dict((key, tag) for (key, tag) in tags.iteritems()) def get_gps_data(tags): diff --git a/mediagoblin/tools/mail.py b/mediagoblin/tools/mail.py index 4fa02ce5..0fabc5a9 100644 --- a/mediagoblin/tools/mail.py +++ b/mediagoblin/tools/mail.py @@ -16,7 +16,7 @@ import smtplib from email.MIMEText import MIMEText -from mediagoblin import mg_globals +from mediagoblin import mg_globals, messages from mediagoblin.tools import common ### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -90,7 +90,12 @@ def send_email(from_addr, to_addrs, subject, message_body): if common.TESTS_ENABLED or mg_globals.app_config['email_debug_mode']: mhost = FakeMhost() elif not mg_globals.app_config['email_debug_mode']: - mhost = smtplib.SMTP( + if mg_globals.app_config['email_smtp_use_ssl']: + smtp_init = smtplib.SMTP_SSL + else: + smtp_init = smtplib.SMTP + + mhost = smtp_init( mg_globals.app_config['email_smtp_host'], mg_globals.app_config['email_smtp_port']) @@ -135,3 +140,16 @@ def normalize_email(email): return None email = "@".join((em_user, em_dom.lower())) return email + + +def email_debug_message(request): + """ + If the server is running in email debug mode (which is + the current default), give a debug message to the user + so that they have an idea where to find their email. + """ + if mg_globals.app_config['email_debug_mode']: + # DEBUG message, no need to translate + messages.add_message(request, messages.DEBUG, + u"This instance is running in email debug mode. " + u"The email will be on the console of the server process.") diff --git a/mediagoblin/tools/response.py b/mediagoblin/tools/response.py index aaf31d0b..0be1f835 100644 --- a/mediagoblin/tools/response.py +++ b/mediagoblin/tools/response.py @@ -77,7 +77,7 @@ def render_http_exception(request, exc, description): elif stock_desc and exc.code == 404: return render_404(request) - return render_error(request, title=exc.args[0], + return render_error(request, title='{0} {1}'.format(exc.code, exc.name), err_msg=description, status=exc.code) diff --git a/mediagoblin/tools/session.py b/mediagoblin/tools/session.py index fdc32523..a57f69cc 100644 --- a/mediagoblin/tools/session.py +++ b/mediagoblin/tools/session.py @@ -17,10 +17,12 @@ import itsdangerous import logging -import crypto +from mediagoblin.tools import crypto _log = logging.getLogger(__name__) +MAX_AGE = 30 * 24 * 60 * 60 + class Session(dict): def __init__(self, *args, **kwargs): self.send_new_cookie = False @@ -64,5 +66,10 @@ class SessionManager(object): elif not session: response.delete_cookie(self.cookie_name) else: + if session.get('stay_logged_in', False): + max_age = MAX_AGE + else: + max_age = None + response.set_cookie(self.cookie_name, self.signer.dumps(session), - httponly=True) + max_age=max_age, httponly=True) diff --git a/mediagoblin/tools/staticdirect.py b/mediagoblin/tools/staticdirect.py index 31abc566..ef8b20d0 100644 --- a/mediagoblin/tools/staticdirect.py +++ b/mediagoblin/tools/staticdirect.py @@ -61,3 +61,41 @@ class StaticDirect(object): def get(self, filepath, domain=None): return '%s/%s' % ( self.domains[domain], filepath.lstrip('/')) + + +class PluginStatic(object): + """Pass this into the ``'static_setup'`` hook to register your + plugin's static directory. + + This has two mandatory attributes that you must pass in on class + init: + - name: this name will be both used for lookup in "urlgen" for + your plugin's static resources and for the subdirectory that + it'll be "mounted" to for serving via your web browser. It + *MUST* be unique. If writing a plugin bundled with MediaGoblin + please use the pattern 'coreplugin__foo' where 'foo' is your + plugin name. All external plugins should use their modulename, + so if your plugin is 'mg_bettertags' you should also call this + name 'mg_bettertags'. + - file_path: the directory your plugin's static resources are + located in. It's recommended that you use + pkg_resources.resource_filename() for this. + + An example of using this:: + + from pkg_resources import resource_filename + from mediagoblin.tools.staticdirect import PluginStatic + + hooks = { + 'static_setup': lambda: PluginStatic( + 'mg_bettertags', + resource_filename('mg_bettertags', 'static')) + } + + """ + def __init__(self, name, file_path): + self.name = name + self.file_path = file_path + + def __call__(self): + return self diff --git a/mediagoblin/tools/template.py b/mediagoblin/tools/template.py index 54aeac92..615ce129 100644 --- a/mediagoblin/tools/template.py +++ b/mediagoblin/tools/template.py @@ -27,7 +27,7 @@ from mediagoblin import messages from mediagoblin import _version from mediagoblin.tools import common from mediagoblin.tools.translate import set_thread_locale -from mediagoblin.tools.pluginapi import get_hook_templates +from mediagoblin.tools.pluginapi import get_hook_templates, hook_transform from mediagoblin.tools.timesince import timesince from mediagoblin.meddleware.csrf import render_csrf_form_token @@ -71,6 +71,7 @@ def get_jinja_env(template_loader, locale): template_env.globals['app_config'] = mg_globals.app_config template_env.globals['global_config'] = mg_globals.global_config template_env.globals['version'] = _version.__version__ + template_env.globals['auth'] = mg_globals.app.auth template_env.filters['urlencode'] = url_quote_plus @@ -80,6 +81,9 @@ def get_jinja_env(template_loader, locale): # allow for hooking up plugin templates template_env.globals['get_hook_templates'] = get_hook_templates + template_env.globals = hook_transform( + 'template_global_context', template_env.globals) + if exists(locale): SETUP_JINJA_ENVS[locale] = template_env @@ -103,6 +107,20 @@ def render_template(request, template_path, context): rendered_csrf_token = render_csrf_form_token(request) if rendered_csrf_token is not None: context['csrf_token'] = render_csrf_form_token(request) + + # allow plugins to do things to the context + if request.controller_name: + context = hook_transform( + (request.controller_name, template_path), + context) + + # More evil: allow plugins to possibly do something to the context + # in every request ever with access to the request and other + # variables. Note: this is slower than using + # template_global_context + context = hook_transform( + 'template_context_prerender', context) + rendered = template.render(context) if common.TESTS_ENABLED: diff --git a/mediagoblin/user_pages/views.py b/mediagoblin/user_pages/views.py index 738cc054..596d4c20 100644 --- a/mediagoblin/user_pages/views.py +++ b/mediagoblin/user_pages/views.py @@ -25,8 +25,9 @@ from mediagoblin.tools.response import render_to_response, render_404, \ from mediagoblin.tools.translate import pass_to_ugettext as _ from mediagoblin.tools.pagination import Pagination from mediagoblin.user_pages import forms as user_forms -from mediagoblin.user_pages.lib import (send_comment_email, - add_media_to_collection) +from mediagoblin.user_pages.lib import add_media_to_collection +from mediagoblin.notifications import trigger_notification, \ + add_comment_subscription, mark_comment_notification_seen from mediagoblin.decorators import (uses_pagination, get_user_media_entry, get_media_entry_by_id, @@ -34,6 +35,7 @@ from mediagoblin.decorators import (uses_pagination, get_user_media_entry, get_user_collection, get_user_collection_item, active_user_from_url) from werkzeug.contrib.atom import AtomFeed +from werkzeug.exceptions import MethodNotAllowed _log = logging.getLogger(__name__) @@ -110,6 +112,7 @@ def user_gallery(request, page, url_user=None): 'media_entries': media_entries, 'pagination': pagination}) + MEDIA_COMMENTS_PER_PAGE = 50 @@ -121,6 +124,9 @@ def media_home(request, media, page, **kwargs): """ comment_id = request.matchdict.get('comment', None) if comment_id: + if request.user: + mark_comment_notification_seen(comment_id, request.user) + pagination = Pagination( page, media.get_comments( mg_globals.app_config['comments_ascending']), @@ -136,7 +142,7 @@ def media_home(request, media, page, **kwargs): comment_form = user_forms.MediaCommentForm(request.form) - media_template_name = media.media_manager['display_template'] + media_template_name = media.media_manager.display_template return render_to_response( request, @@ -154,7 +160,8 @@ def media_post_comment(request, media): """ recieves POST from a MediaEntry() comment form, saves the comment. """ - assert request.method == 'POST' + if not request.method == 'POST': + raise MethodNotAllowed() comment = request.db.MediaComment() comment.media_entry = media.id @@ -179,11 +186,9 @@ def media_post_comment(request, media): request, messages.SUCCESS, _('Your comment has been posted!')) - media_uploader = media.get_uploader - #don't send email if you comment on your own post - if (comment.author != media_uploader and - media_uploader.wants_comment_notification): - send_comment_email(media_uploader, comment, media, request) + trigger_notification(comment, media, request) + + add_comment_subscription(request.user, media) return redirect_obj(request, media) @@ -14,6 +14,7 @@ use = egg:Paste#urlmap /mgoblin_media/ = publicstore_serve /mgoblin_static/ = mediagoblin_static /theme_static/ = theme_static +/plugin_static/ = plugin_static [app:mediagoblin] use = egg:mediagoblin#app @@ -56,6 +57,11 @@ use = egg:Paste#static document_root = %(here)s/user_dev/theme_static/ cache_max_age = 86400 +[app:plugin_static] +use = egg:Paste#static +document_root = %(here)s/user_dev/plugin_static/ +cache_max_age = 86400 + [filter:errors] use = egg:mediagoblin#errors debug = false @@ -45,19 +45,19 @@ setup( 'PasteScript', 'wtforms', 'py-bcrypt', - 'pytest', + 'pytest>=2.3.1', 'pytest-xdist', 'werkzeug>=0.7', 'celery==2.5.3', 'kombu==2.1.7', 'jinja2', 'sphinx', - 'Babel', + 'Babel<1.0', 'argparse', 'webtest<2', 'ConfigObj', 'Markdown', - 'sqlalchemy>=0.7.0', + 'sqlalchemy>=0.8.0', 'sqlalchemy-migrate', 'mock', 'itsdangerous', |