Whitespace and formatting cleanup.

* Removed trailing whitespace
* Line length < 80 where possible
* Honor conventions on number of blank lines
* Honor conventions about spaces around :, =
This commit is contained in:
Nathan Yergler 2011-10-01 15:10:02 -07:00
parent 573aba86b5
commit 243c3843bd
38 changed files with 135 additions and 113 deletions

View File

@ -91,7 +91,7 @@ class MediaGoblinApp(object):
# object. # object.
####################################################### #######################################################
setup_globals(app = self) setup_globals(app=self)
# Workbench *currently* only used by celery, so this only # Workbench *currently* only used by celery, so this only
# matters in always eager mode :) # matters in always eager mode :)
@ -101,7 +101,6 @@ class MediaGoblinApp(object):
self.middleware = [util.import_component(m)(self) self.middleware = [util.import_component(m)(self)
for m in middleware.ENABLED_MIDDLEWARE] for m in middleware.ENABLED_MIDDLEWARE]
def __call__(self, environ, start_response): def __call__(self, environ, start_response):
request = Request(environ) request = Request(environ)

View File

@ -59,9 +59,10 @@ class ForgotPassForm(wtforms.Form):
'Username or email', 'Username or email',
[wtforms.validators.Required()]) [wtforms.validators.Required()])
def validate_username(form,field): def validate_username(form, field):
if not (re.match(r'^\w+$',field.data) or if not (re.match(r'^\w+$', field.data) or
re.match(r'^.+@[^.].*\.[a-z]{2,10}$',field.data, re.IGNORECASE)): re.match(r'^.+@[^.].*\.[a-z]{2,10}$', field.data,
re.IGNORECASE)):
raise wtforms.ValidationError(u'Incorrect input') raise wtforms.ValidationError(u'Incorrect input')
@ -82,4 +83,3 @@ class ChangePassForm(wtforms.Form):
token = wtforms.HiddenField( token = wtforms.HiddenField(
'', '',
[wtforms.validators.Required()]) [wtforms.validators.Required()])

View File

@ -93,6 +93,7 @@ EMAIL_VERIFICATION_TEMPLATE = (
u"http://{host}{uri}?" u"http://{host}{uri}?"
u"userid={userid}&token={verification_key}") u"userid={userid}&token={verification_key}")
def send_verification_email(user, request): def send_verification_email(user, request):
""" """
Send the verification email to users to activate their accounts. Send the verification email to users to activate their accounts.
@ -127,6 +128,7 @@ EMAIL_FP_VERIFICATION_TEMPLATE = (
u"http://{host}{uri}?" u"http://{host}{uri}?"
u"userid={userid}&token={fp_verification_key}") u"userid={userid}&token={fp_verification_key}")
def send_fp_verification_email(user, request): def send_fp_verification_email(user, request):
""" """
Send the verification email to users to change their password. Send the verification email to users to change their password.
@ -150,4 +152,3 @@ def send_fp_verification_email(user, request):
[user['email']], [user['email']],
'GNU MediaGoblin - Change forgotten password!', 'GNU MediaGoblin - Change forgotten password!',
rendered_email) rendered_email)

View File

@ -33,7 +33,8 @@ auth_routes = [
controller='mediagoblin.views:simple_template_render'), controller='mediagoblin.views:simple_template_render'),
Route('mediagoblin.auth.forgot_password', '/forgot_password/', Route('mediagoblin.auth.forgot_password', '/forgot_password/',
controller='mediagoblin.auth.views:forgot_password'), controller='mediagoblin.auth.views:forgot_password'),
Route('mediagoblin.auth.verify_forgot_password', '/forgot_password/verify/', Route('mediagoblin.auth.verify_forgot_password',
'/forgot_password/verify/',
controller='mediagoblin.auth.views:verify_forgot_password'), controller='mediagoblin.auth.views:verify_forgot_password'),
Route('mediagoblin.auth.fp_changed_success', Route('mediagoblin.auth.fp_changed_success',
'/forgot_password/changed_success/', '/forgot_password/changed_success/',

View File

@ -233,8 +233,7 @@ def forgot_password(request):
request, 'mediagoblin.user_pages.user_home', request, 'mediagoblin.user_pages.user_home',
user=user['username']) user=user['username'])
# do not reveal whether or not there is a matching user
# do not reveal whether or not there is a matching user, just move along
return redirect(request, 'mediagoblin.auth.fp_email_sent') return redirect(request, 'mediagoblin.auth.fp_email_sent')
return render_to_response( return render_to_response(

View File

@ -23,7 +23,7 @@ Database Abstraction/Wrapper Layer
pymongo. Read beow for why, but note that nobody is actually doing pymongo. Read beow for why, but note that nobody is actually doing
this and there's no proof that we'll ever support more than this and there's no proof that we'll ever support more than
MongoDB... it would be a huge amount of work to do so. MongoDB... it would be a huge amount of work to do so.
If you really want to prove that possible, jump on IRC and talk to If you really want to prove that possible, jump on IRC and talk to
us about making such a branch. In the meanwhile, it doesn't hurt to us about making such a branch. In the meanwhile, it doesn't hurt to
have things as they are... if it ever makes it hard for us to have things as they are... if it ever makes it hard for us to

View File

@ -93,8 +93,9 @@ MEDIAENTRY_INDEXES = {
('created', DESCENDING)]}, ('created', DESCENDING)]},
'state_uploader_tags_created': { 'state_uploader_tags_created': {
# Indexing on processed?, media uploader, associated tags, and timestamp # Indexing on processed?, media uploader, associated tags, and
# Used for showing media items matching a tag search, most recent first. # timestamp Used for showing media items matching a tag
# search, most recent first.
'index': [('state', ASCENDING), 'index': [('state', ASCENDING),
('uploader', ASCENDING), ('uploader', ASCENDING),
('tags.slug', DESCENDING), ('tags.slug', DESCENDING),

View File

@ -87,7 +87,7 @@ def mediaentry_add_fail_error_and_metadata(database):
{'fail_error': {'$exists': False}}, {'fail_error': {'$exists': False}},
{'$set': {'fail_error': None}}, {'$set': {'fail_error': None}},
multi=True) multi=True)
collection.update( collection.update(
{'fail_metadata': {'$exists': False}}, {'fail_metadata': {'$exists': False}},
{'$set': {'fail_metadata': {}}}, {'$set': {'fail_metadata': {}}},

View File

@ -14,7 +14,8 @@
# You should have received a copy of the GNU Affero General Public License # 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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import datetime, uuid import datetime
import uuid
from mongokit import Document from mongokit import Document
@ -69,17 +70,17 @@ class User(Document):
'username': unicode, 'username': unicode,
'email': unicode, 'email': unicode,
'created': datetime.datetime, 'created': datetime.datetime,
'plugin_data': dict, # plugins can dump stuff here. 'plugin_data': dict, # plugins can dump stuff here.
'pw_hash': unicode, 'pw_hash': unicode,
'email_verified': bool, 'email_verified': bool,
'status': unicode, 'status': unicode,
'verification_key': unicode, 'verification_key': unicode,
'is_admin': bool, 'is_admin': bool,
'url' : unicode, 'url': unicode,
'bio' : unicode, # May contain markdown 'bio': unicode, # May contain markdown
'bio_html': unicode, # May contain plaintext, or HTML 'bio_html': unicode, # May contain plaintext, or HTML
'fp_verification_key': unicode, # forgotten password verification key 'fp_verification_key': unicode, # forgotten password verification key
'fp_token_expire': datetime.datetime 'fp_token_expire': datetime.datetime,
} }
required_fields = ['username', 'created', 'pw_hash', 'email'] required_fields = ['username', 'created', 'pw_hash', 'email']
@ -174,8 +175,8 @@ class MediaEntry(Document):
critical to this piece of media but may be usefully relevant to people critical to this piece of media but may be usefully relevant to people
viewing the work. (currently unused.) viewing the work. (currently unused.)
- fail_error: path to the exception raised - fail_error: path to the exception raised
- fail_metadata: - fail_metadata:
""" """
__collection__ = 'media_entries' __collection__ = 'media_entries'
@ -184,11 +185,11 @@ class MediaEntry(Document):
'title': unicode, 'title': unicode,
'slug': unicode, 'slug': unicode,
'created': datetime.datetime, 'created': datetime.datetime,
'description': unicode, # May contain markdown/up 'description': unicode, # May contain markdown/up
'description_html': unicode, # May contain plaintext, or HTML 'description_html': unicode, # May contain plaintext, or HTML
'media_type': unicode, 'media_type': unicode,
'media_data': dict, # extra data relevant to this media_type 'media_data': dict, # extra data relevant to this media_type
'plugin_data': dict, # plugins can dump stuff here. 'plugin_data': dict, # plugins can dump stuff here.
'tags': [dict], 'tags': [dict],
'state': unicode, 'state': unicode,
@ -220,7 +221,8 @@ class MediaEntry(Document):
return self.db.MediaComment.find({ return self.db.MediaComment.find({
'media_entry': self['_id']}).sort('created', DESCENDING) 'media_entry': self['_id']}).sort('created', DESCENDING)
def get_display_media(self, media_map, fetch_order=DISPLAY_IMAGE_FETCHING_ORDER): def get_display_media(self, media_map,
fetch_order=DISPLAY_IMAGE_FETCHING_ORDER):
""" """
Find the best media for display. Find the best media for display.
@ -273,7 +275,7 @@ class MediaEntry(Document):
""" """
Provide a url to the previous entry from this user, if there is one Provide a url to the previous entry from this user, if there is one
""" """
cursor = self.db.MediaEntry.find({'_id' : {"$gt": self['_id']}, cursor = self.db.MediaEntry.find({'_id': {"$gt": self['_id']},
'uploader': self['uploader'], 'uploader': self['uploader'],
'state': 'processed'}).sort( 'state': 'processed'}).sort(
'_id', ASCENDING).limit(1) '_id', ASCENDING).limit(1)
@ -286,7 +288,7 @@ class MediaEntry(Document):
""" """
Provide a url to the next entry from this user, if there is one Provide a url to the next entry from this user, if there is one
""" """
cursor = self.db.MediaEntry.find({'_id' : {"$lt": self['_id']}, cursor = self.db.MediaEntry.find({'_id': {"$lt": self['_id']},
'uploader': self['uploader'], 'uploader': self['uploader'],
'state': 'processed'}).sort( 'state': 'processed'}).sort(
'_id', DESCENDING).limit(1) '_id', DESCENDING).limit(1)
@ -353,4 +355,3 @@ def register_models(connection):
Register all models in REGISTER_MODELS with this connection. Register all models in REGISTER_MODELS with this connection.
""" """
connection.register(REGISTER_MODELS) connection.register(REGISTER_MODELS)

View File

@ -29,7 +29,7 @@ def connect_database_from_config(app_config, use_pymongo=False):
port = app_config.get('db_port') port = app_config.get('db_port')
if port: if port:
port = asint(port) port = asint(port)
if use_pymongo: if use_pymongo:
connection = pymongo.Connection( connection = pymongo.Connection(
app_config.get('db_host'), port) app_config.get('db_host'), port)

View File

@ -118,11 +118,12 @@ def remove_deprecated_indexes(database, deprecated_indexes=DEPRECATED_INDEXES):
################# #################
# The default migration registry... # The default migration registry...
# #
# Don't set this yourself! RegisterMigration will automatically fill # Don't set this yourself! RegisterMigration will automatically fill
# this with stuff via decorating methods in migrations.py # this with stuff via decorating methods in migrations.py
class MissingCurrentMigration(Exception): pass class MissingCurrentMigration(Exception):
pass
MIGRATIONS = {} MIGRATIONS = {}

View File

@ -119,6 +119,7 @@ def get_user_media_entry(controller):
return _make_safe(wrapper, controller) return _make_safe(wrapper, controller)
def get_media_entry_by_id(controller): def get_media_entry_by_id(controller):
""" """
Pass in a MediaEntry based off of a url component Pass in a MediaEntry based off of a url component
@ -138,4 +139,3 @@ def get_media_entry_by_id(controller):
return controller(request, media=media, *args, **kwargs) return controller(request, media=media, *args, **kwargs)
return _make_safe(wrapper, controller) return _make_safe(wrapper, controller)

View File

@ -13,5 +13,3 @@
# #
# You should have received a copy of the GNU Affero General Public License # 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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.

View File

@ -119,7 +119,7 @@ def edit_attachments(request, media):
name=request.POST['attachment_name'] \ name=request.POST['attachment_name'] \
or request.POST['attachment_file'].filename, or request.POST['attachment_file'].filename,
filepath=attachment_public_filepath, filepath=attachment_public_filepath,
created=datetime.utcnow() created=datetime.utcnow(),
)) ))
media.save() media.save()

View File

@ -28,7 +28,7 @@ SUBCOMMAND_MAP = {
'setup': 'mediagoblin.gmg_commands.migrate:migrate_parser_setup', 'setup': 'mediagoblin.gmg_commands.migrate:migrate_parser_setup',
'func': 'mediagoblin.gmg_commands.migrate:migrate', 'func': 'mediagoblin.gmg_commands.migrate:migrate',
'help': 'Apply all unapplied bulk migrations to the database'}, 'help': 'Apply all unapplied bulk migrations to the database'},
'adduser':{ 'adduser': {
'setup': 'mediagoblin.gmg_commands.users:adduser_parser_setup', 'setup': 'mediagoblin.gmg_commands.users:adduser_parser_setup',
'func': 'mediagoblin.gmg_commands.users:adduser', 'func': 'mediagoblin.gmg_commands.users:adduser',
'help': 'Creates an user'}, 'help': 'Creates an user'},
@ -80,4 +80,3 @@ def main_cli():
if __name__ == '__main__': if __name__ == '__main__':
main_cli() main_cli()

View File

@ -91,7 +91,7 @@ def _import_database(db, args):
args.mongorestore_path, args.mongorestore_path,
'-d', db.name, '-d', db.name,
os.path.join(args._cache_path['database'], db.name)]) os.path.join(args._cache_path['database'], db.name)])
p.wait() p.wait()
_log.info('...Database imported') _log.info('...Database imported')
@ -229,7 +229,8 @@ def env_export(args):
''' '''
if args.cache_path: if args.cache_path:
if os.path.exists(args.cache_path): if os.path.exists(args.cache_path):
_log.error('The cache directory must not exist before you run this script') _log.error('The cache directory must not exist '
'before you run this script')
_log.error('Cache directory: {0}'.format(args.cache_path)) _log.error('Cache directory: {0}'.format(args.cache_path))
return False return False
@ -245,7 +246,7 @@ def env_export(args):
globa_config, app_config = setup_global_and_app_config(args.conf_file) globa_config, app_config = setup_global_and_app_config(args.conf_file)
setup_storage() setup_storage()
connection, db = setup_connection_and_db_from_config( connection, db = setup_connection_and_db_from_config(
app_config, use_pymongo=True) app_config, use_pymongo=True)

View File

@ -55,13 +55,13 @@ def migrate(args):
for collection, index_name in removed_indexes: for collection, index_name in removed_indexes:
print "Removed index '%s' in collection '%s'" % ( print "Removed index '%s' in collection '%s'" % (
index_name, collection) index_name, collection)
# Migrate # Migrate
print "\n== Applying migrations... ==" print "\n== Applying migrations... =="
migration_manager.migrate_new( migration_manager.migrate_new(
pre_callback=_print_started_migration, pre_callback=_print_started_migration,
post_callback=_print_finished_migration) post_callback=_print_finished_migration)
# Add new indexes # Add new indexes
print "\n== Adding new indexes... ==" print "\n== Adding new indexes... =="
new_indexes = db_util.add_new_indexes(db) new_indexes = db_util.add_new_indexes(db)

View File

@ -41,7 +41,7 @@ def adduser(args):
db = mg_globals.database db = mg_globals.database
users_with_username = \ users_with_username = \
db.User.find({ db.User.find({
'username': args.username.lower() 'username': args.username.lower(),
}).count() }).count()
if users_with_username: if users_with_username:
@ -74,7 +74,7 @@ def makeadmin(args):
db = mg_globals.database db = mg_globals.database
user = db.User.one({'username':unicode(args.username.lower())}) user = db.User.one({'username': unicode(args.username.lower())})
if user: if user:
user['is_admin'] = True user['is_admin'] = True
user.save() user.save()
@ -100,11 +100,10 @@ def changepw(args):
db = mg_globals.database db = mg_globals.database
user = db.User.one({'username':unicode(args.username.lower())}) user = db.User.one({'username': unicode(args.username.lower())})
if user: if user:
user['pw_hash'] = auth_lib.bcrypt_gen_password_hash(args.password) user['pw_hash'] = auth_lib.bcrypt_gen_password_hash(args.password)
user.save() user.save()
print 'Password successfully changed' print 'Password successfully changed'
else: else:
print 'The user doesn\'t exist' print 'The user doesn\'t exist'

View File

@ -29,8 +29,12 @@ from mediagoblin.workbench import WorkbenchManager
from mediagoblin.storage import storage_system_from_config from mediagoblin.storage import storage_system_from_config
class Error(Exception): pass class Error(Exception):
class ImproperlyConfigured(Error): pass pass
class ImproperlyConfigured(Error):
pass
def setup_global_and_app_config(config_path): def setup_global_and_app_config(config_path):
@ -76,8 +80,8 @@ def setup_database():
"in fact they appear to be from the future?!") "in fact they appear to be from the future?!")
setup_globals( setup_globals(
db_connection = connection, db_connection=connection,
database = db) database=db)
return connection, db return connection, db
@ -126,8 +130,8 @@ def setup_storage():
queue_store = storage_system_from_config(global_config[key_long]) queue_store = storage_system_from_config(global_config[key_long])
setup_globals( setup_globals(
public_store = public_store, public_store=public_store,
queue_store = queue_store) queue_store=queue_store)
return public_store, queue_store return public_store, queue_store
@ -137,7 +141,7 @@ def setup_workbench():
workbench_manager = WorkbenchManager(app_config['workbench_path']) workbench_manager = WorkbenchManager(app_config['workbench_path'])
setup_globals(workbench_manager = workbench_manager) setup_globals(workbench_manager=workbench_manager)
def setup_beaker_cache(): def setup_beaker_cache():

View File

@ -84,6 +84,6 @@ def setup_celery_from_config(app_config, global_config,
for key, value in celery_settings.iteritems(): for key, value in celery_settings.iteritems():
setattr(this_module, key, value) setattr(this_module, key, value)
if set_environ: if set_environ:
os.environ['CELERY_CONFIG_MODULE'] = settings_module os.environ['CELERY_CONFIG_MODULE'] = settings_module

View File

@ -44,7 +44,7 @@ def setup_self(check_environ_for_conf=True, module_name=OUR_MODULENAME,
if not os.path.exists(mgoblin_conf_file): if not os.path.exists(mgoblin_conf_file):
raise IOError( raise IOError(
"MEDIAGOBLIN_CONFIG not set or file does not exist") "MEDIAGOBLIN_CONFIG not set or file does not exist")
# By setting the environment variable here we should ensure that # By setting the environment variable here we should ensure that
# this is the module that gets set up. # this is the module that gets set up.
os.environ['CELERY_CONFIG_MODULE'] = module_name os.environ['CELERY_CONFIG_MODULE'] = module_name

View File

@ -73,7 +73,7 @@ def read_mediagoblin_config(config_path, config_spec=CONFIG_SPEC_PATH):
# For now the validator just works with the default functions, # For now the validator just works with the default functions,
# but in the future if we want to add additional validation/configuration # but in the future if we want to add additional validation/configuration
# functions we'd add them to validator.functions here. # functions we'd add them to validator.functions here.
# #
# See also: # See also:
# http://www.voidspace.org.uk/python/validate.html#adding-functions # http://www.voidspace.org.uk/python/validate.html#adding-functions
validator = Validator() validator = Validator()

View File

@ -25,4 +25,3 @@ tag_routes = [
Route('mediagoblin.listings.tag_atom_feed', "/{tag}/atom/", Route('mediagoblin.listings.tag_atom_feed', "/{tag}/atom/",
controller="mediagoblin.listings.views:tag_atom_feed"), controller="mediagoblin.listings.views:tag_atom_feed"),
] ]

View File

@ -46,7 +46,7 @@ def tag_listing(request, page):
{u'state': u'processed', {u'state': u'processed',
u'tags.slug': tag_slug}) u'tags.slug': tag_slug})
cursor = cursor.sort('created', DESCENDING) cursor = cursor.sort('created', DESCENDING)
pagination = Pagination(page, cursor) pagination = Pagination(page, cursor)
media_entries = pagination() media_entries = pagination()
@ -63,6 +63,7 @@ def tag_listing(request, page):
ATOM_DEFAULT_NR_OF_UPDATED_ITEMS = 15 ATOM_DEFAULT_NR_OF_UPDATED_ITEMS = 15
def tag_atom_feed(request): def tag_atom_feed(request):
""" """
generates the atom feed with the tag images generates the atom feed with the tag images

View File

@ -20,11 +20,13 @@ SUCCESS = 'success'
WARNING = 'warning' WARNING = 'warning'
ERROR = 'error' ERROR = 'error'
def add_message(request, level, text): def add_message(request, level, text):
messages = request.session.setdefault('messages', []) messages = request.session.setdefault('messages', [])
messages.append({'level': level, 'text': text}) messages.append({'level': level, 'text': text})
request.session.save() request.session.save()
def fetch_messages(request, clear_from_session=True): def fetch_messages(request, clear_from_session=True):
messages = request.session.get('messages') messages = request.session.get('messages')
if messages and clear_from_session: if messages and clear_from_session:

View File

@ -14,6 +14,7 @@
# You should have received a copy of the GNU Affero General Public License # 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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
class NoOpMiddleware(object): class NoOpMiddleware(object):
def __init__(self, mg_app): def __init__(self, mg_app):

View File

@ -65,9 +65,10 @@ class ProcessMedia(Task):
""" """
If the processing failed we should mark that in the database. If the processing failed we should mark that in the database.
Assuming that the exception raised is a subclass of BaseProcessingFail, Assuming that the exception raised is a subclass of
we can use that to get more information about the failure and store that BaseProcessingFail, we can use that to get more information
for conveying information to users about the failure, etc. about the failure and store that for conveying information to
users about the failure, etc.
""" """
entry_id = args[0] entry_id = args[0]
mark_entry_failed(entry_id, exc) mark_entry_failed(entry_id, exc)
@ -80,10 +81,10 @@ def mark_entry_failed(entry_id, exc):
""" """
Mark a media entry as having failed in its conversion. Mark a media entry as having failed in its conversion.
Uses the exception that was raised to mark more information. If the Uses the exception that was raised to mark more information. If
exception is a derivative of BaseProcessingFail then we can store extra the exception is a derivative of BaseProcessingFail then we can
information that can be useful for users telling them why their media failed store extra information that can be useful for users telling them
to process. why their media failed to process.
Args: Args:
- entry_id: The id of the media entry - entry_id: The id of the media entry
@ -164,7 +165,8 @@ def process_image(entry):
with queued_file: with queued_file:
original_filepath = create_pub_filepath(entry, queued_filepath[-1]) original_filepath = create_pub_filepath(entry, queued_filepath[-1])
with mgg.public_store.get_file(original_filepath, 'wb') as original_file: with mgg.public_store.get_file(original_filepath, 'wb') \
as original_file:
original_file.write(queued_file.read()) original_file.write(queued_file.read())
mgg.queue_store.delete_file(queued_filepath) mgg.queue_store.delete_file(queued_filepath)

View File

@ -16,17 +16,18 @@
from mediagoblin.util import lazy_pass_to_ugettext as _ from mediagoblin.util import lazy_pass_to_ugettext as _
class BaseProcessingFail(Exception): class BaseProcessingFail(Exception):
""" """
Base exception that all other processing failure messages should Base exception that all other processing failure messages should
subclass from. subclass from.
You shouldn't call this itself; instead you should subclass it You shouldn't call this itself; instead you should subclass it
and provid the exception_path and general_message applicable to and provid the exception_path and general_message applicable to
this error. this error.
""" """
general_message = u'' general_message = u''
@property @property
def exception_path(self): def exception_path(self):
return u"%s:%s" % ( return u"%s:%s" % (
@ -34,8 +35,8 @@ class BaseProcessingFail(Exception):
def __init__(self, **metadata): def __init__(self, **metadata):
self.metadata = metadata or {} self.metadata = metadata or {}
class BadMediaFail(BaseProcessingFail): class BadMediaFail(BaseProcessingFail):
""" """
Error that should be raised when an inappropriate file was given Error that should be raised when an inappropriate file was given

View File

@ -27,6 +27,7 @@ from mediagoblin.storage import StorageInterface, clean_listy_filepath
import cloudfiles import cloudfiles
import mimetypes import mimetypes
class CloudFilesStorage(StorageInterface): class CloudFilesStorage(StorageInterface):
''' '''
OpenStack/Rackspace Cloud's Swift/CloudFiles support OpenStack/Rackspace Cloud's Swift/CloudFiles support

View File

@ -13,5 +13,3 @@
# #
# You should have received a copy of the GNU Affero General Public License # 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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.

View File

@ -16,9 +16,9 @@
from mimetypes import guess_type from mimetypes import guess_type
ALLOWED = ['image/jpeg', 'image/png', 'image/tiff', 'image/gif'] ALLOWED = ['image/jpeg', 'image/png', 'image/tiff', 'image/gif']
def check_filetype(posted_file): def check_filetype(posted_file):
if not guess_type(posted_file.filename)[0] in ALLOWED: if not guess_type(posted_file.filename)[0] in ALLOWED:
return False return False

View File

@ -61,8 +61,8 @@ def submit_start(request):
entry['description'] = unicode(request.POST.get('description')) entry['description'] = unicode(request.POST.get('description'))
entry['description_html'] = cleaned_markdown_conversion( entry['description_html'] = cleaned_markdown_conversion(
entry['description']) entry['description'])
entry['media_type'] = u'image' # heh entry['media_type'] = u'image' # heh
entry['uploader'] = request.user['_id'] entry['uploader'] = request.user['_id']
# Process the user's folksonomy "tags" # Process the user's folksonomy "tags"
@ -90,8 +90,10 @@ def submit_start(request):
# We generate this ourselves so we know what the taks id is for # We generate this ourselves so we know what the taks id is for
# retrieval later. # retrieval later.
# (If we got it off the task's auto-generation, there'd be a risk of
# a race condition when we'd save after sending off the task) # (If we got it off the task's auto-generation, there'd be
# a risk of a race condition when we'd save after sending
# off the task)
task_id = unicode(uuid.uuid4()) task_id = unicode(uuid.uuid4())
entry['queued_task_id'] = task_id entry['queued_task_id'] = task_id
@ -113,8 +115,8 @@ def submit_start(request):
# expect a lot of users to run things in this way we have to # expect a lot of users to run things in this way we have to
# capture stuff here. # capture stuff here.
# #
# ... not completely the diaper pattern because the exception is # ... not completely the diaper pattern because the
# re-raised :) # exception is re-raised :)
mark_entry_failed(entry[u'_id'], exc) mark_entry_failed(entry[u'_id'], exc)
# re-raise the exception # re-raise the exception
raise raise
@ -122,7 +124,7 @@ def submit_start(request):
add_message(request, SUCCESS, _('Woohoo! Submitted!')) add_message(request, SUCCESS, _('Woohoo! Submitted!'))
return redirect(request, "mediagoblin.user_pages.user_home", return redirect(request, "mediagoblin.user_pages.user_home",
user = request.user['username']) user=request.user['username'])
return render_to_response( return render_to_response(
request, request,

View File

@ -13,5 +13,3 @@
# #
# You should have received a copy of the GNU Affero General Public License # 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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.

View File

@ -53,7 +53,7 @@ def user_home(request, page):
#if no data is available, return NotFound #if no data is available, return NotFound
if media_entries == None: if media_entries == None:
return render_404(request) return render_404(request)
user_gallery_url = request.urlgen( user_gallery_url = request.urlgen(
'mediagoblin.user_pages.user_gallery', 'mediagoblin.user_pages.user_gallery',
user=user['username']) user=user['username'])
@ -66,6 +66,7 @@ def user_home(request, page):
'media_entries': media_entries, 'media_entries': media_entries,
'pagination': pagination}) 'pagination': pagination})
@uses_pagination @uses_pagination
def user_gallery(request, page): def user_gallery(request, page):
"""'Gallery' of a User()""" """'Gallery' of a User()"""
@ -85,7 +86,7 @@ def user_gallery(request, page):
#if no data is available, return NotFound #if no data is available, return NotFound
if media_entries == None: if media_entries == None:
return render_404(request) return render_404(request)
return render_to_response( return render_to_response(
request, request,
'mediagoblin/user_pages/gallery.html', 'mediagoblin/user_pages/gallery.html',
@ -95,6 +96,7 @@ def user_gallery(request, page):
MEDIA_COMMENTS_PER_PAGE = 50 MEDIA_COMMENTS_PER_PAGE = 50
@get_user_media_entry @get_user_media_entry
@uses_pagination @uses_pagination
def media_home(request, media, page, **kwargs): def media_home(request, media, page, **kwargs):
@ -142,8 +144,8 @@ def media_post_comment(request):
'Comment posted!') 'Comment posted!')
return redirect(request, 'mediagoblin.user_pages.media_home', return redirect(request, 'mediagoblin.user_pages.media_home',
media = request.matchdict['media'], media=request.matchdict['media'],
user = request.matchdict['user']) user=request.matchdict['user'])
@get_user_media_entry @get_user_media_entry
@ -184,6 +186,7 @@ def media_confirm_delete(request, media):
ATOM_DEFAULT_NR_OF_UPDATED_ITEMS = 15 ATOM_DEFAULT_NR_OF_UPDATED_ITEMS = 15
def atom_feed(request): def atom_feed(request):
""" """
generates the atom feed with the newest images generates the atom feed with the newest images
@ -204,7 +207,7 @@ def atom_feed(request):
feed = AtomFeed(request.matchdict['user'], feed = AtomFeed(request.matchdict['user'],
feed_url=request.url, feed_url=request.url,
url=request.host_url) url=request.host_url)
for entry in cursor: for entry in cursor:
feed.add(entry.get('title'), feed.add(entry.get('title'),
entry.get('description_html'), entry.get('description_html'),

View File

@ -45,6 +45,8 @@ from itertools import izip, count
DISPLAY_IMAGE_FETCHING_ORDER = [u'medium', u'original', u'thumb'] DISPLAY_IMAGE_FETCHING_ORDER = [u'medium', u'original', u'thumb']
TESTS_ENABLED = False TESTS_ENABLED = False
def _activate_testing(): def _activate_testing():
""" """
Call this to activate testing in util.py Call this to activate testing in util.py
@ -78,7 +80,7 @@ SETUP_JINJA_ENVS = {}
def get_jinja_env(template_loader, locale): def get_jinja_env(template_loader, locale):
""" """
Set up the Jinja environment, Set up the Jinja environment,
(In the future we may have another system for providing theming; (In the future we may have another system for providing theming;
for now this is good enough.) for now this is good enough.)
@ -147,7 +149,7 @@ def render_to_response(request, template, context, status=200):
def redirect(request, *args, **kwargs): def redirect(request, *args, **kwargs):
"""Returns a HTTPFound(), takes a request and then urlgen params""" """Returns a HTTPFound(), takes a request and then urlgen params"""
querystring = None querystring = None
if kwargs.get('querystring'): if kwargs.get('querystring'):
querystring = kwargs.get('querystring') querystring = kwargs.get('querystring')
@ -197,6 +199,7 @@ def import_component(import_string):
_punct_re = re.compile(r'[\t !"#$%&\'()*\-/<=>?@\[\\\]^_`{|},.]+') _punct_re = re.compile(r'[\t !"#$%&\'()*\-/<=>?@\[\\\]^_`{|},.]+')
def slugify(text, delim=u'-'): def slugify(text, delim=u'-'):
""" """
Generates an ASCII-only slug. Taken from http://flask.pocoo.org/snippets/5/ Generates an ASCII-only slug. Taken from http://flask.pocoo.org/snippets/5/
@ -213,7 +216,7 @@ def slugify(text, delim=u'-'):
### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# We have two "test inboxes" here: # We have two "test inboxes" here:
# #
# EMAIL_TEST_INBOX: # EMAIL_TEST_INBOX:
# ---------------- # ----------------
# If you're writing test views, you'll probably want to check this. # If you're writing test views, you'll probably want to check this.
@ -233,7 +236,7 @@ def slugify(text, delim=u'-'):
# ***IMPORTANT!*** # ***IMPORTANT!***
# ---------------- # ----------------
# Before running tests that call functions which send email, you should # Before running tests that call functions which send email, you should
# always call _clear_test_inboxes() to "wipe" the inboxes clean. # always call _clear_test_inboxes() to "wipe" the inboxes clean.
EMAIL_TEST_INBOX = [] EMAIL_TEST_INBOX = []
EMAIL_TEST_MBOX_INBOX = [] EMAIL_TEST_MBOX_INBOX = []
@ -253,6 +256,7 @@ class FakeMhost(object):
'to': to_addrs, 'to': to_addrs,
'message': message}) 'message': message})
def _clear_test_inboxes(): def _clear_test_inboxes():
global EMAIL_TEST_INBOX global EMAIL_TEST_INBOX
global EMAIL_TEST_MBOX_INBOX global EMAIL_TEST_MBOX_INBOX
@ -263,6 +267,7 @@ def _clear_test_inboxes():
### </Special email test stuff> ### </Special email test stuff>
### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def send_email(from_addr, to_addrs, subject, message_body): def send_email(from_addr, to_addrs, subject, message_body):
""" """
Simple email sending wrapper, use this so we can capture messages Simple email sending wrapper, use this so we can capture messages
@ -418,7 +423,7 @@ def convert_to_tag_list_of_dicts(tag_string):
# Split the tag string into a list of tags # Split the tag string into a list of tags
for tag in stripped_tag_string.split( for tag in stripped_tag_string.split(
mg_globals.app_config['tags_delimiter']): mg_globals.app_config['tags_delimiter']):
# Ignore empty or duplicate tags # Ignore empty or duplicate tags
if tag.strip() and tag.strip() not in [t['name'] for t in taglist]: if tag.strip() and tag.strip() not in [t['name'] for t in taglist]:
@ -437,12 +442,13 @@ def media_tags_as_string(media_entry_tags):
media_tag_string = '' media_tag_string = ''
if media_entry_tags: if media_entry_tags:
media_tag_string = mg_globals.app_config['tags_delimiter'].join( media_tag_string = mg_globals.app_config['tags_delimiter'].join(
[tag['name'] for tag in media_entry_tags]) [tag['name'] for tag in media_entry_tags])
return media_tag_string return media_tag_string
TOO_LONG_TAG_WARNING = \ TOO_LONG_TAG_WARNING = \
u'Tags must be shorter than %s characters. Tags that are too long: %s' u'Tags must be shorter than %s characters. Tags that are too long: %s'
def tag_length_validator(form, field): def tag_length_validator(form, field):
""" """
Make sure tags do not exceed the maximum tag length. Make sure tags do not exceed the maximum tag length.
@ -460,6 +466,7 @@ def tag_length_validator(form, field):
MARKDOWN_INSTANCE = markdown.Markdown(safe_mode='escape') MARKDOWN_INSTANCE = markdown.Markdown(safe_mode='escape')
def cleaned_markdown_conversion(text): def cleaned_markdown_conversion(text):
""" """
Take a block of text, run it through MarkDown, and clean its HTML. Take a block of text, run it through MarkDown, and clean its HTML.
@ -474,6 +481,7 @@ def cleaned_markdown_conversion(text):
SETUP_GETTEXTS = {} SETUP_GETTEXTS = {}
def setup_gettext(locale): def setup_gettext(locale):
""" """
Setup the gettext instance based on this locale Setup the gettext instance based on this locale
@ -558,6 +566,7 @@ def fake_ugettext_passthrough(string):
PAGINATION_DEFAULT_PER_PAGE = 30 PAGINATION_DEFAULT_PER_PAGE = 30
class Pagination(object): class Pagination(object):
""" """
Pagination class for mongodb queries. Pagination class for mongodb queries.
@ -574,9 +583,9 @@ class Pagination(object):
Args: Args:
- page: requested page - page: requested page
- per_page: number of objects per page - per_page: number of objects per page
- cursor: db cursor - cursor: db cursor
- jump_to_id: ObjectId, sets the page to the page containing the object - jump_to_id: ObjectId, sets the page to the page containing the
with _id == jump_to_id. object with _id == jump_to_id.
""" """
self.page = page self.page = page
self.per_page = per_page self.per_page = per_page
@ -594,7 +603,6 @@ class Pagination(object):
self.active_id = jump_to_id self.active_id = jump_to_id
break break
def __call__(self): def __call__(self):
""" """
Returns slice of objects for the requested page Returns slice of objects for the requested page
@ -628,20 +636,18 @@ class Pagination(object):
last = num last = num
def get_page_url_explicit(self, base_url, get_params, page_no): def get_page_url_explicit(self, base_url, get_params, page_no):
""" """Get a page url by adding a page= parameter to the base url
Get a page url by adding a page= parameter to the base url """
"""
new_get_params = copy.copy(get_params or {}) new_get_params = copy.copy(get_params or {})
new_get_params['page'] = page_no new_get_params['page'] = page_no
return "%s?%s" % ( return "%s?%s" % (
base_url, urllib.urlencode(new_get_params)) base_url, urllib.urlencode(new_get_params))
def get_page_url(self, request, page_no): def get_page_url(self, request, page_no):
""" """Get a new page url based of the request, and the new page number.
Get a new page url based of the request, and the new page number.
This is a nice wrapper around get_page_url_explicit() This is a nice wrapper around get_page_url_explicit()
""" """
return self.get_page_url_explicit( return self.get_page_url_explicit(
request.path_info, request.GET, page_no) request.path_info, request.GET, page_no)
@ -682,6 +688,7 @@ def render_404(request):
return render_to_response( return render_to_response(
request, 'mediagoblin/404.html', {}, status=400) request, 'mediagoblin/404.html', {}, status=400)
def delete_media_files(media): def delete_media_files(media):
""" """
Delete all files associated with a MediaEntry Delete all files associated with a MediaEntry

View File

@ -19,6 +19,7 @@ from mediagoblin.util import render_to_response, Pagination
from mediagoblin.db.util import DESCENDING from mediagoblin.db.util import DESCENDING
from mediagoblin.decorators import uses_pagination from mediagoblin.decorators import uses_pagination
@uses_pagination @uses_pagination
def root_view(request, page): def root_view(request, page):
cursor = request.db.MediaEntry.find( cursor = request.db.MediaEntry.find(

View File

@ -42,8 +42,10 @@ class Workbench(object):
def __unicode__(self): def __unicode__(self):
return unicode(self.dir) return unicode(self.dir)
def __str__(self): def __str__(self):
return str(self.dir) return str(self.dir)
def __repr__(self): def __repr__(self):
return repr(self.dir) return repr(self.dir)
@ -140,7 +142,7 @@ class WorkbenchManager(object):
self.base_workbench_dir = os.path.abspath(base_workbench_dir) self.base_workbench_dir = os.path.abspath(base_workbench_dir)
if not os.path.exists(self.base_workbench_dir): if not os.path.exists(self.base_workbench_dir):
os.makedirs(self.base_workbench_dir) os.makedirs(self.base_workbench_dir)
def create_workbench(self): def create_workbench(self):
""" """
Create and return the path to a new workbench (directory). Create and return the path to a new workbench (directory).

View File

@ -29,16 +29,17 @@ def get_version():
if mo: if mo:
return mo.group(1) return mo.group(1)
else: else:
raise RuntimeError("Unable to find version string in %s." % VERSIONFILE) raise RuntimeError("Unable to find version string in %s." %
VERSIONFILE)
setup( setup(
name = "mediagoblin", name="mediagoblin",
version = get_version(), version=get_version(),
packages=find_packages(exclude=['ez_setup', 'examples', 'tests']), packages=find_packages(exclude=['ez_setup', 'examples', 'tests']),
zip_safe=False, zip_safe=False,
# scripts and dependencies # scripts and dependencies
install_requires = [ install_requires=[
'setuptools', 'setuptools',
'PasteScript', 'PasteScript',
'beaker', 'beaker',
@ -66,7 +67,7 @@ setup(
# 'lxml', # 'lxml',
], ],
test_suite='nose.collector', test_suite='nose.collector',
entry_points = """\ entry_points="""\
[console_scripts] [console_scripts]
gmg = mediagoblin.gmg_commands:main_cli gmg = mediagoblin.gmg_commands:main_cli
pybabel = mediagoblin.babel.messages.frontend:main pybabel = mediagoblin.babel.messages.frontend:main
@ -83,7 +84,6 @@ setup(
[babel.extractors] [babel.extractors]
jinja2 = jinja2.ext:babel_extract jinja2 = jinja2.ext:babel_extract
""", """,
license='AGPLv3', license='AGPLv3',
author='Free Software Foundation and contributors', author='Free Software Foundation and contributors',
author_email='cwebber@gnu.org', author_email='cwebber@gnu.org',