diff --git a/.gitignore b/.gitignore index f5c2ba31..9da56bab 100644 --- a/.gitignore +++ b/.gitignore @@ -10,7 +10,8 @@ mediagoblin.egg-info *.pyo docs/_build/ user_dev/ -mediagoblin_user.ini +paste_local.ini +mediagoblin_local.ini server-log.txt *~ *.swp diff --git a/.tx/config b/.tx/config new file mode 100644 index 00000000..711b5d94 --- /dev/null +++ b/.tx/config @@ -0,0 +1,8 @@ +[mediagoblin.mediagoblin] +file_filter = mediagoblin/i18n//LC_MESSAGES/mediagoblin.po +source_file = mediagoblin/i18n/en/LC_MESSAGES/mediagoblin.po +source_lang = en + +[main] +host = https://www.transifex.net + diff --git a/babel.ini b/babel.ini index 666270df..a4e3267a 100644 --- a/babel.ini +++ b/babel.ini @@ -10,4 +10,4 @@ encoding = utf-8 # # Extraction from JavaScript files # [javascript: mediagoblin/static/js/**.js] -# extract_messages = $._, jQuery._ \ No newline at end of file +# extract_messages = $._, jQuery._ diff --git a/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.mo b/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.mo new file mode 100644 index 00000000..ba625623 Binary files /dev/null and b/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.mo differ diff --git a/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.po new file mode 100644 index 00000000..715757fb --- /dev/null +++ b/mediagoblin/i18n/de/LC_MESSAGES/mediagoblin.po @@ -0,0 +1,25 @@ +# Translations template for PROJECT. +# Copyright (C) 2011 ORGANIZATION +# This file is distributed under the same license as the PROJECT project. +# +# , 2011. +msgid "" +msgstr "" +"Project-Id-Version: GNU MediaGoblin\n" +"Report-Msgid-Bugs-To: http://bugs.foocorp.net/projects/mediagoblin/issues\n" +"POT-Creation-Date: 2011-08-06 23:01-0500\n" +"PO-Revision-Date: 2011-08-07 14:06+0000\n" +"Last-Translator: cwebber \n" +"Language-Team: German (http://www.transifex.net/projects/p/mediagoblin/team/de/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 0.9.6\n" +"Language: de\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" + +#: mediagoblin/templates/mediagoblin/root.html:21 +msgid "Welcome to GNU MediaGoblin!" +msgstr "Willkommen bei GNU MediaGoblin!" + + diff --git a/mediagoblin/i18n/en/LC_MESSAGES/mediagoblin.po b/mediagoblin/i18n/en/LC_MESSAGES/mediagoblin.po new file mode 100644 index 00000000..5e54390d --- /dev/null +++ b/mediagoblin/i18n/en/LC_MESSAGES/mediagoblin.po @@ -0,0 +1,197 @@ +# Translations template for PROJECT. +# Copyright (C) 2011 ORGANIZATION +# This file is distributed under the same license as the PROJECT project. +# FIRST AUTHOR , 2011. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2011-08-08 10:20-0500\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 0.9.6\n" + +#: mediagoblin/templates/mediagoblin/base.html:22 +msgid "GNU MediaGoblin" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:45 +msgid "Mediagoblin logo" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:51 +msgid "Submit media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:62 +msgid "verify your email!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:72 +msgid "Login" +msgstr "" + +#: mediagoblin/templates/mediagoblin/base.html:88 +msgid "" +"Powered by MediaGoblin, a GNU project" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:21 +msgid "Welcome to GNU MediaGoblin!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:26 +msgid "Submit an item" +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:31 +#, python-format +msgid "If you have an account, you can Login." +msgstr "" + +#: mediagoblin/templates/mediagoblin/root.html:37 +#, python-format +msgid "" +"If you don't have an account, please Register." +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/login.html:26 +msgid "Log in" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/login.html:29 +msgid "Login failed!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/login.html:34 +#: mediagoblin/templates/mediagoblin/auth/register.html:30 +#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:35 +#: mediagoblin/templates/mediagoblin/submit/start.html:32 +msgid "Submit" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/login.html:42 +msgid "Don't have an account yet?" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/login.html:45 +msgid "Create one here!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/register.html:27 +msgid "Create an account!" +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/resent_verification_email.html:22 +msgid "Resent your verification email." +msgstr "" + +#: mediagoblin/templates/mediagoblin/auth/verification_email.txt:19 +#, python-format +msgid "" +"Hi %(username)s,\n" +"\n" +"to activate your GNU MediaGoblin account, open the following URL in\n" +"your web browser:\n" +"\n" +"%(verification_url)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:29 +#, python-format +msgid "Editing %(media_title)s" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:36 +msgid "Cancel" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/edit.html:37 +msgid "Save changes" +msgstr "" + +#: mediagoblin/templates/mediagoblin/edit/edit_profile.html:29 +#, python-format +msgid "Editing %(username)s's profile" +msgstr "" + +#: mediagoblin/templates/mediagoblin/listings/tag.html:29 +msgid "Media tagged with:" +msgstr "" + +#: mediagoblin/templates/mediagoblin/listings/tag.html:40 +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:46 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:101 +msgid "atom feed" +msgstr "" + +#: mediagoblin/templates/mediagoblin/submit/start.html:26 +msgid "Submit yer media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:30 +#, python-format +msgid "%(username)s's media" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/gallery.html:51 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:30 +msgid "Sorry, no such user found." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:37 +#: mediagoblin/templates/mediagoblin/user_pages/user.html:57 +msgid "Verification needed" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:40 +msgid "Almost done! Your account still needs to be verified." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:45 +msgid "An email should arrive in a few moments with instructions on how to do so." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:49 +msgid "In case it doesn't:" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:52 +msgid "Resend verification email" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:60 +msgid "" +"Someone has registered an account with this username, but it still has to" +" be verified." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:66 +#, python-format +msgid "" +"If you are that person but you've lost your verification email, you can " +"log in and resend it." +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:76 +#, python-format +msgid "%(username)s's profile" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:84 +msgid "Edit profile" +msgstr "" + +#: mediagoblin/templates/mediagoblin/user_pages/user.html:95 +#, python-format +msgid "View all of %(username)s's media" +msgstr "" + diff --git a/mediagoblin/process_media/__init__.py b/mediagoblin/process_media/__init__.py index 125b24e0..8e12ca4d 100644 --- a/mediagoblin/process_media/__init__.py +++ b/mediagoblin/process_media/__init__.py @@ -19,6 +19,7 @@ from mediagoblin.db.util import ObjectId from celery.task import task from mediagoblin import mg_globals as mgg +from contextlib import contextmanager THUMB_SIZE = 180, 180 @@ -31,6 +32,12 @@ def create_pub_filepath(entry, filename): unicode(entry['_id']), filename]) +@contextmanager +def closing(callback): + try: + yield callback + finally: + pass @task def process_media_initial(media_id): @@ -53,7 +60,7 @@ def process_media_initial(media_id): thumb_filepath = create_pub_filepath(entry, 'thumbnail.jpg') thumb_file = mgg.public_store.get_file(thumb_filepath, 'w') - with thumb_file: + with closing(thumb_file): thumb.save(thumb_file, "JPEG", quality=90) """ @@ -73,7 +80,7 @@ def process_media_initial(media_id): medium_filepath = create_pub_filepath(entry, 'medium.jpg') medium_file = mgg.public_store.get_file(medium_filepath, 'w') - with medium_file: + with closing(medium_file): medium.save(medium_file, "JPEG", quality=90) medium_processed = True @@ -84,7 +91,7 @@ def process_media_initial(media_id): with queued_file: original_filepath = create_pub_filepath(entry, queued_filepath[-1]) - with mgg.public_store.get_file(original_filepath, 'wb') as original_file: + with closing(mgg.public_store.get_file(original_filepath, 'wb')) as original_file: original_file.write(queued_file.read()) mgg.queue_store.delete_file(queued_filepath) diff --git a/mediagoblin/storage.py b/mediagoblin/storage.py index f9d2c3ea..25598c82 100644 --- a/mediagoblin/storage.py +++ b/mediagoblin/storage.py @@ -19,6 +19,7 @@ import re import shutil import urlparse import uuid +import cloudfiles from werkzeug.utils import secure_filename @@ -28,11 +29,21 @@ from mediagoblin import util # Errors ######## -class Error(Exception): pass -class InvalidFilepath(Error): pass -class NoWebServing(Error): pass -class NotImplementedError(Error): pass +class Error(Exception): + pass + + +class InvalidFilepath(Error): + pass + + +class NoWebServing(Error): + pass + + +class NotImplementedError(Error): + pass ############################################### @@ -117,7 +128,7 @@ class StorageInterface(object): Eg, if the filename doesn't exist: >>> storage_handler.get_unique_filename(['dir1', 'dir2', 'fname.jpg']) [u'dir1', u'dir2', u'fname.jpg'] - + But if a file does exist, let's get one back with at uuid tacked on: >>> storage_handler.get_unique_filename(['dir1', 'dir2', 'fname.jpg']) [u'dir1', u'dir2', u'd02c3571-dd62-4479-9d62-9e3012dada29-fname.jpg'] @@ -184,7 +195,7 @@ class BasicFileStorage(StorageInterface): """ return os.path.join( self.base_dir, *clean_listy_filepath(filepath)) - + def file_exists(self, filepath): return os.path.exists(self._resolve_filepath(filepath)) @@ -216,6 +227,65 @@ class BasicFileStorage(StorageInterface): return self._resolve_filepath(filepath) +class CloudFilesStorage(StorageInterface): + def __init__(self, **kwargs): + self.param_container = kwargs.get('cloudfiles_container') + self.param_user = kwargs.get('cloudfiles_user') + self.param_api_key = kwargs.get('cloudfiles_api_key') + self.param_host = kwargs.get('cloudfiles_host') + self.param_use_servicenet = kwargs.get('cloudfiles_use_servicenet') + + if not self.param_host: + print('No CloudFiles host URL specified, ' + 'defaulting to Rackspace US') + + self.connection = cloudfiles.get_connection( + username=self.param_user, + api_key=self.param_api_key, + servicenet=True if self.param_use_servicenet == 'true' or \ + self.param_use_servicenet == True else False) + + if not self.param_container == \ + self.connection.get_container(self.param_container): + self.container = self.connection.create_container( + self.param_container) + self.container.make_public( + ttl=60 * 60 * 2) + else: + self.container = self.connection.get_container( + self.param_container) + + def _resolve_filepath(self, filepath): + return '/'.join( + clean_listy_filepath(filepath)) + + def file_exists(self, filepath): + try: + object = self.container.get_object( + self._resolve_filepath(filepath)) + return True + except cloudfiles.errors.NoSuchObject: + return False + + def get_file(self, filepath, mode='r'): + try: + obj = self.container.get_object( + self._resolve_filepath(filepath)) + except cloudfiles.errors.NoSuchObject: + obj = self.container.create_object( + self._resolve_filepath(filepath)) + + return obj + + def delete_file(self, filepath): + # TODO: Also delete unused directories if empty (safely, with + # checks to avoid race conditions). + self.container.delete_object(filepath) + + def file_url(self, filepath): + return self.get_file(filepath).public_uri() + + class MountStorage(StorageInterface): def __init__(self, **kwargs): self.mounttab = {} @@ -391,7 +461,7 @@ def storage_system_from_config(paste_config, storage_prefix): for key, value in paste_config.iteritems() if prefix_re.match(key)]) - if config_params.has_key('storage_class'): + if 'storage_class' in config_params: storage_class = config_params['storage_class'] config_params.pop('storage_class') else: @@ -399,5 +469,3 @@ def storage_system_from_config(paste_config, storage_prefix): storage_class = util.import_component(storage_class) return storage_class(**config_params) - - diff --git a/mediagoblin/templates/mediagoblin/auth/login.html b/mediagoblin/templates/mediagoblin/auth/login.html index e25783ea..5750feb0 100644 --- a/mediagoblin/templates/mediagoblin/auth/login.html +++ b/mediagoblin/templates/mediagoblin/auth/login.html @@ -23,20 +23,27 @@
-

Log in

+

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

{% if login_failed %} -
Login failed!
+
+ {% trans %}Login failed!{% endtrans %} +
{% endif %} {{ wtforms_util.render_divs(login_form) }}
- +
{% if next %} {% endif %} {% if allow_registration %} -

Don't have an account yet?
Create one here!

+

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

{% endif %}
diff --git a/mediagoblin/templates/mediagoblin/auth/register.html b/mediagoblin/templates/mediagoblin/auth/register.html index f77b3782..623cbdfd 100644 --- a/mediagoblin/templates/mediagoblin/auth/register.html +++ b/mediagoblin/templates/mediagoblin/auth/register.html @@ -24,10 +24,11 @@
-

Create an account!

+

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

{{ wtforms_util.render_divs(register_form) }}
- +
diff --git a/mediagoblin/templates/mediagoblin/auth/resent_verification_email.html b/mediagoblin/templates/mediagoblin/auth/resent_verification_email.html index da3a9e99..8fd80ee9 100644 --- a/mediagoblin/templates/mediagoblin/auth/resent_verification_email.html +++ b/mediagoblin/templates/mediagoblin/auth/resent_verification_email.html @@ -19,6 +19,6 @@ {% block mediagoblin_content %}

- Resent your verification email. + {% trans %}Resent your verification email.{% endtrans %}

{% endblock %} diff --git a/mediagoblin/templates/mediagoblin/auth/verification_email.txt b/mediagoblin/templates/mediagoblin/auth/verification_email.txt index 7863374d..32053101 100644 --- a/mediagoblin/templates/mediagoblin/auth/verification_email.txt +++ b/mediagoblin/templates/mediagoblin/auth/verification_email.txt @@ -14,9 +14,13 @@ # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -#} +-#} + +{% trans username=username, verification_url=verification_url|safe -%} Hi {{ username }}, -to activate your GNU MediaGoblin account, open the following URL in your web browser +to activate your GNU MediaGoblin account, open the following URL in +your web browser: -{{ verification_url|safe }} +{{ verification_url }} +{%- endtrans %} diff --git a/mediagoblin/templates/mediagoblin/base.html b/mediagoblin/templates/mediagoblin/base.html index 4da685f9..986e0995 100644 --- a/mediagoblin/templates/mediagoblin/base.html +++ b/mediagoblin/templates/mediagoblin/base.html @@ -19,7 +19,7 @@ - {% block title %}GNU MediaGoblin{% endblock title %} + {% block title %}{% trans %}GNU MediaGoblin{% endtrans %}{% endblock title %} Mediagoblin logo + alt="{% trans %}Mediagoblin logo{% endtrans %}" /> {% endblock %} {% if request.user and request.user['status'] == 'active' %} - Submit media + {% trans %}Submit media{% endtrans %} {% endif %} {% block mediagoblin_header_title %}{% endblock %} @@ -59,7 +59,7 @@ - verify your email! + {% trans %}verify your email!{% endtrans %} {% endif %} logout) {% else %} - Login + {% trans %}Login{% endtrans %} {% endif %} @@ -85,7 +85,9 @@ {% block mediagoblin_footer %}
{% endblock %} diff --git a/mediagoblin/templates/mediagoblin/edit/edit.html b/mediagoblin/templates/mediagoblin/edit/edit.html index d19034cb..3dc170c8 100644 --- a/mediagoblin/templates/mediagoblin/edit/edit.html +++ b/mediagoblin/templates/mediagoblin/edit/edit.html @@ -26,15 +26,15 @@ media= media._id) }}" method="POST" enctype="multipart/form-data">
-

Editing {{ media.title }}

+

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

{{ wtforms_util.render_divs(form) }}
diff --git a/mediagoblin/templates/mediagoblin/edit/edit_profile.html b/mediagoblin/templates/mediagoblin/edit/edit_profile.html index a11b86d7..534e5f20 100644 --- a/mediagoblin/templates/mediagoblin/edit/edit_profile.html +++ b/mediagoblin/templates/mediagoblin/edit/edit_profile.html @@ -25,10 +25,14 @@ user['username'] }}" method="POST" enctype="multipart/form-data">
-

Editing {{ user['username'] }}'s profile

+

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

{{ wtforms_util.render_divs(form) }}
- +
diff --git a/mediagoblin/templates/mediagoblin/listings/tag.html b/mediagoblin/templates/mediagoblin/listings/tag.html index 6f10ec8d..a013797f 100644 --- a/mediagoblin/templates/mediagoblin/listings/tag.html +++ b/mediagoblin/templates/mediagoblin/listings/tag.html @@ -26,7 +26,7 @@ {% block mediagoblin_content -%}

- Media tagged with: {{ tag_name }} + {% trans %}Media tagged with:{% endtrans %} {{ tag_name }}

{% else %} {# This *should* not occur as the view makes sure we pass in a user. #} -

Sorry, no such user found.

+

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

{% endif %} {% endblock %} diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html index a1382518..afc0d903 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media.html @@ -38,24 +38,26 @@ {% endautoescape %}

- — uploaded on - {{ "%4d-%02d-%02d"|format(media.created.year, - media.created.month, media.created.day) }} - by - - {{- media.uploader().username }} + {% trans date="%4d-%02d-%02d"|format( + media.created.year, + media.created.month, media.created.day), + user_url=request.urlgen( + 'mediagoblin.user_pages.user_home', + user=media.uploader().username), + username=media.uploader().username -%} + — uploaded on {{ date }} by {{ username }} + {%- endtrans %}


-

Comments

+

{% trans %}Comments{% endtrans %}

{% if request.user %}
{{ wtforms_util.render_field_div(comment_form.comment_content) }}
- +
{% endif %} @@ -77,7 +79,7 @@ {% else %} -

Sorry, no such media found.

+

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

{% endif %} {% endblock %} diff --git a/mediagoblin/templates/mediagoblin/user_pages/user.html b/mediagoblin/templates/mediagoblin/user_pages/user.html index 76cf36be..1115fc56 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/user.html +++ b/mediagoblin/templates/mediagoblin/user_pages/user.html @@ -27,53 +27,62 @@ {% block mediagoblin_content -%} {# If no user... #} {% if not user %} -

Sorry, no such user found.

+

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

{# User exists, but needs verification #} {% elif user.status == "needs_email_verification" %} {% if user == request.user %} {# this should only be visible when you are this user #}

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

Verification needed

+

{% trans %}Verification needed{% endtrans %}

- Someone has registered an account with this username, but it - still has to be verified. + {% trans -%} + Someone has registered an account with this username, but it still has to be verified. + {%- endtrans %}

- If you are that person but you've lost your verification - email, you can - log in - and resend it. + {% trans login_url=request.urlgen('mediagoblin.auth.login') -%} + If you are that person but you've lost your verification email, you can log in and resend it. + {%- endtrans %}

{% endif %} {# Active(?) (or at least verified at some point) user, horray! #} {% else %} -

{{ user.username }}'s profile

+

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

{% include "mediagoblin/utils/profile.html" %} {% if request.user['_id'] == user['_id'] or request.user['is_admin'] %} Edit profile + user.username }}"> + {%- trans %}Edit profile{% endtrans -%} + {% endif %}
@@ -81,10 +90,16 @@ {% set pagination_base_url = user_gallery_url %} {% include "mediagoblin/utils/object_gallery.html" %}
-

View all of {{ user.username }}'s media

- atom feed +

+ + {% trans username=user.username -%} + View all of {{ username }}'s media{% endtrans -%} + +

+ + {%- trans %}atom feed{% endtrans -%} +
diff --git a/mediagoblin/templates/mediagoblin/utils/tags.html b/mediagoblin/templates/mediagoblin/utils/tags.html index ade41944..32db6e31 100644 --- a/mediagoblin/templates/mediagoblin/utils/tags.html +++ b/mediagoblin/templates/mediagoblin/utils/tags.html @@ -17,7 +17,7 @@ #} {% block tags_content -%} -

Tags

+

Tags

    {% for tag in media.tags %}
  • diff --git a/mediagoblin/util.py b/mediagoblin/util.py index 5880f856..c9f4a0ac 100644 --- a/mediagoblin/util.py +++ b/mediagoblin/util.py @@ -300,7 +300,7 @@ def send_email(from_addr, to_addrs, subject, message_body): TRANSLATIONS_PATH = pkg_resources.resource_filename( - 'mediagoblin', 'translations') + 'mediagoblin', 'i18n') def locale_to_lower_upper(locale): diff --git a/setup.py b/setup.py index 3508f5f0..40715dd0 100644 --- a/setup.py +++ b/setup.py @@ -44,6 +44,7 @@ setup( 'webtest', 'ConfigObj', 'Markdown', + 'python-cloudfiles', ## For now we're expecting that users will install this from ## their package managers. # 'lxml', @@ -52,6 +53,7 @@ setup( entry_points = """\ [console_scripts] gmg = mediagoblin.gmg_commands:main_cli + pybabel = mediagoblin.babel.messages.frontend:main [paste.app_factory] app = mediagoblin.app:paste_app_factory