diff --git a/docs/hackinghowto.rst b/docs/hackinghowto.rst
index 08b228f1..914a5135 100644
--- a/docs/hackinghowto.rst
+++ b/docs/hackinghowto.rst
@@ -57,6 +57,11 @@ requirements::
sudo apt-get install mongodb git-core python python-dev \
python-lxml
+On Fedora::
+
+ yum install mongodb-server python-paste-deploy python-paste-script \
+ git-core python python-devel
+
.. YouCanHelp::
If you have instructions for other GNU/Linux distributions to set
diff --git a/mediagoblin.ini b/mediagoblin.ini
index 596107dc..e889646a 100644
--- a/mediagoblin.ini
+++ b/mediagoblin.ini
@@ -8,6 +8,9 @@ email_sender_address = "notice@mediagoblin.example.org"
# set to false to enable sending notices
email_debug_mode = true
+# Set to false to disable registrations
+allow_registration = true
+
## Uncomment this to put some user-overriding templates here
#local_templates = %(here)s/user_dev/templates/
diff --git a/mediagoblin/app.py b/mediagoblin/app.py
index 9454b403..ae39694f 100644
--- a/mediagoblin/app.py
+++ b/mediagoblin/app.py
@@ -20,18 +20,12 @@ import urllib
import routes
from webob import Request, exc
-from mediagoblin import routing, util, storage, staticdirect
-from mediagoblin.init.config import (
- read_mediagoblin_config, generate_validation_report)
+from mediagoblin import routing, util, storage
from mediagoblin.db.open import setup_connection_and_db_from_config
from mediagoblin.mg_globals import setup_globals
from mediagoblin.init.celery import setup_celery_from_config
-from mediagoblin.init import get_jinja_loader
-from mediagoblin.workbench import WorkbenchManager
-
-
-class Error(Exception): pass
-class ImproperlyConfigured(Error): pass
+from mediagoblin.init import get_jinja_loader, get_staticdirector, \
+ setup_global_and_app_config, setup_workbench
class MediaGoblinApp(object):
@@ -55,13 +49,7 @@ class MediaGoblinApp(object):
##############
# Open and setup the config
- global_config, validation_result = read_mediagoblin_config(config_path)
- app_config = global_config['mediagoblin']
- # report errors if necessary
- validation_report = generate_validation_report(
- global_config, validation_result)
- if validation_report:
- raise ImproperlyConfigured(validation_report)
+ global_config, app_config = setup_global_and_app_config(config_path)
##########################################
# Setup other connections / useful objects
@@ -85,19 +73,7 @@ class MediaGoblinApp(object):
self.routing = routing.get_mapper()
# set up staticdirector tool
- if app_config.has_key('direct_remote_path'):
- self.staticdirector = staticdirect.RemoteStaticDirect(
- app_config['direct_remote_path'].strip())
- elif app_config.has_key('direct_remote_paths'):
- direct_remote_path_lines = app_config[
- 'direct_remote_paths'].strip().splitlines()
- self.staticdirector = staticdirect.MultiRemoteStaticDirect(
- dict([line.strip().split(' ', 1)
- for line in direct_remote_path_lines]))
- else:
- raise ImproperlyConfigured(
- "One of direct_remote_path or "
- "direct_remote_paths must be provided")
+ self.staticdirector = get_staticdirector(app_config)
# Setup celery, if appropriate
if setup_celery and not app_config.get('celery_setup_elsewhere'):
@@ -117,9 +93,6 @@ class MediaGoblinApp(object):
#######################################################
setup_globals(
- app_config=app_config,
- global_config=global_config,
-
# TODO: No need to set these two up as globals, we could
# just read them out of mg_globals.app_config
email_sender_address=app_config['email_sender_address'],
@@ -130,8 +103,11 @@ class MediaGoblinApp(object):
db_connection=self.connection,
database=self.db,
public_store=self.public_store,
- queue_store=self.queue_store,
- workbench_manager=WorkbenchManager(app_config['workbench_path']))
+ queue_store=self.queue_store)
+
+ # Workbench *currently* only used by celery, so this only
+ # matters in always eager mode :)
+ setup_workbench()
def __call__(self, environ, start_response):
request = Request(environ)
diff --git a/mediagoblin/auth/views.py b/mediagoblin/auth/views.py
index 1d00f382..7fe507b1 100644
--- a/mediagoblin/auth/views.py
+++ b/mediagoblin/auth/views.py
@@ -18,6 +18,8 @@ import uuid
from webob import exc
+from mediagoblin import messages
+from mediagoblin import mg_globals
from mediagoblin.util import render_to_response, redirect
from mediagoblin.db.util import ObjectId
from mediagoblin.auth import lib as auth_lib
@@ -29,6 +31,14 @@ def register(request):
"""
Your classic registration view!
"""
+ # 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")
+
register_form = auth_forms.RegistrationForm(request.POST)
if request.method == 'POST' and register_form.validate():
@@ -51,7 +61,7 @@ def register(request):
entry['pw_hash'] = auth_lib.bcrypt_gen_password_hash(
request.POST['password'])
entry.save(validate=True)
-
+
send_verification_email(entry, request)
return redirect(request, "mediagoblin.auth.register_success")
@@ -97,13 +107,14 @@ def login(request):
'mediagoblin/auth/login.html',
{'login_form': login_form,
'next': request.GET.get('next') or request.POST.get('next'),
- 'login_failed': login_failed})
+ 'login_failed': login_failed,
+ 'allow_registration': mg_globals.app_config["allow_registration"]})
def logout(request):
# Maybe deleting the user_id parameter would be enough?
request.session.delete()
-
+
return redirect(request, "index")
@@ -124,16 +135,24 @@ def verify_email(request):
if user and user['verification_key'] == unicode(request.GET['token']):
user['status'] = u'active'
user['email_verified'] = True
- verification_successful = True
user.save()
+ verification_successful = True
+ messages.add_message(
+ request,
+ messages.SUCCESS,
+ ('Your email address has been verified. '
+ 'You may now login, edit your profile, and submit images!'))
else:
verification_successful = False
-
+ messages.add_message(request,
+ messages.ERROR,
+ 'The verification key or user id is incorrect')
+
return render_to_response(
request,
- 'mediagoblin/auth/verify_email.html',
+ 'mediagoblin/user_pages/user.html',
{'user': user,
- 'verification_successful': verification_successful})
+ 'verification_successful' : verification_successful})
def resend_activation(request):
diff --git a/mediagoblin/config_spec.ini b/mediagoblin/config_spec.ini
index aadf5c21..b6356b0e 100644
--- a/mediagoblin/config_spec.ini
+++ b/mediagoblin/config_spec.ini
@@ -21,6 +21,9 @@ direct_remote_path = string(default="/mgoblin_static/")
email_debug_mode = boolean(default=True)
email_sender_address = string(default="notice@mediagoblin.example.org")
+# Set to false to disable registrations
+allow_registration = boolean(default=True)
+
# By default not set, but you might want something like:
# "%(here)s/user_dev/templates/"
local_templates = string()
@@ -73,4 +76,4 @@ celeryd_eta_scheduler_precision = float()
# known lists
celery_routes = string_list()
-celery_imports = string_list()
\ No newline at end of file
+celery_imports = string_list()
diff --git a/mediagoblin/db/indexes.py b/mediagoblin/db/indexes.py
index d379a52b..a832e013 100644
--- a/mediagoblin/db/indexes.py
+++ b/mediagoblin/db/indexes.py
@@ -45,11 +45,13 @@ REQUIRED READING:
To remove deprecated indexes
----------------------------
-Removing deprecated indexes is easier, just do:
+Removing deprecated indexes is the same, just move the index into the
+deprecated indexes mapping.
-INACTIVE_INDEXES = {
- 'collection_name': [
- 'deprecated_index_identifier1', 'deprecated_index_identifier2']}
+DEPRECATED_INDEXES = {
+ 'collection_name': {
+ 'deprecated_index_identifier1': {
+ 'index': [index_foo_goes_here]}}
... etc.
diff --git a/mediagoblin/db/models.py b/mediagoblin/db/models.py
index 8aa35ca9..279cb9f2 100644
--- a/mediagoblin/db/models.py
+++ b/mediagoblin/db/models.py
@@ -147,31 +147,33 @@ class MediaEntry(Document):
"""
Provide a url to the previous entry from this user, if there is one
"""
- cursor = self.db.MediaEntry.find({'_id' : {"$lt": self['_id']},
- 'uploader': self['uploader']}).sort(
- '_id', DESCENDING).limit(1)
-
+ cursor = self.db.MediaEntry.find({'_id' : {"$gt": self['_id']},
+ 'uploader': self['uploader'],
+ 'state': 'processed'}).sort(
+ '_id', ASCENDING).limit(1)
if cursor.count():
return urlgen('mediagoblin.user_pages.media_home',
user=self.uploader()['username'],
- media=unicode(cursor[0]['_id']))
+ media=unicode(cursor[0]['slug']))
def url_to_next(self, urlgen):
"""
Provide a url to the next entry from this user, if there is one
"""
- cursor = self.db.MediaEntry.find({'_id' : {"$gt": self['_id']},
- 'uploader': self['uploader']}).sort(
- '_id', ASCENDING).limit(1)
+ cursor = self.db.MediaEntry.find({'_id' : {"$lt": self['_id']},
+ 'uploader': self['uploader'],
+ 'state': 'processed'}).sort(
+ '_id', DESCENDING).limit(1)
if cursor.count():
return urlgen('mediagoblin.user_pages.media_home',
user=self.uploader()['username'],
- media=unicode(cursor[0]['_id']))
+ media=unicode(cursor[0]['slug']))
def uploader(self):
return self.db.User.find_one({'_id': self['uploader']})
+
class MediaComment(Document):
__collection__ = 'media_comments'
diff --git a/mediagoblin/db/util.py b/mediagoblin/db/util.py
index 70c37945..37e6586f 100644
--- a/mediagoblin/db/util.py
+++ b/mediagoblin/db/util.py
@@ -81,18 +81,25 @@ def remove_deprecated_indexes(database, deprecated_indexes=DEPRECATED_INDEXES):
Args:
- database: pymongo or mongokit database instance.
- deprecated_indexes: the indexes to deprecate in the pattern of:
- {'collection': ['index_identifier1', 'index_identifier2']}
+ {'collection_name': {
+ 'identifier': {
+ 'index': [index_foo_goes_here],
+ 'unique': True}}
+
+ (... although we really only need the 'identifier' here, as the
+ rest of the information isn't used in this case. But it's kept
+ around so we can remember what it was)
Returns:
A list of indexes removed in form ('collection', 'index_name')
"""
indexes_removed = []
- for collection_name, index_names in deprecated_indexes.iteritems():
+ for collection_name, indexes in deprecated_indexes.iteritems():
collection = database[collection_name]
collection_indexes = collection.index_information().keys()
- for index_name in index_names:
+ for index_name, index_data in indexes.iteritems():
if index_name in collection_indexes:
collection.drop_index(index_name)
diff --git a/mediagoblin/edit/forms.py b/mediagoblin/edit/forms.py
index 2efdb9e4..0ed52af1 100644
--- a/mediagoblin/edit/forms.py
+++ b/mediagoblin/edit/forms.py
@@ -23,7 +23,8 @@ class EditForm(wtforms.Form):
'Title',
[wtforms.validators.Length(min=0, max=500)])
slug = wtforms.TextField(
- 'Slug')
+ 'Slug',
+ [wtforms.validators.Required(message="The slug can't be empty")])
description = wtforms.TextAreaField('Description of this work')
class EditProfileForm(wtforms.Form):
@@ -31,4 +32,5 @@ class EditProfileForm(wtforms.Form):
[wtforms.validators.Length(min=0, max=500)])
url = wtforms.TextField(
'Website',
- [wtforms.validators.URL(message='Improperly formed URL')])
+ [wtforms.validators.Optional(),
+ wtforms.validators.URL(message='Improperly formed URL')])
diff --git a/mediagoblin/edit/views.py b/mediagoblin/edit/views.py
index e064a9c3..3bcf788b 100644
--- a/mediagoblin/edit/views.py
+++ b/mediagoblin/edit/views.py
@@ -106,9 +106,9 @@ def edit_profile(request):
messages.add_message(request,
messages.SUCCESS,
'Profile edited!')
- return redirect(request,
- "mediagoblin.edit.profile",
- username=edit_username)
+ return redirect(request,
+ 'mediagoblin.user_pages.user_home',
+ user=edit_username)
return render_to_response(
request,
diff --git a/mediagoblin/init/__init__.py b/mediagoblin/init/__init__.py
index b8ed2456..6320d21b 100644
--- a/mediagoblin/init/__init__.py
+++ b/mediagoblin/init/__init__.py
@@ -15,8 +15,33 @@
# along with this program. If not, see
Don't have an account yet?
Create one here!
Don't have an account yet?
Create one here!
- {% if verification_successful %} - Your email address has been verified! - {% else %} - The verification key or user id is incorrect - {% endif %} -
-{% endblock %} diff --git a/mediagoblin/templates/mediagoblin/base.html b/mediagoblin/templates/mediagoblin/base.html index b71fca24..40bb085e 100644 --- a/mediagoblin/templates/mediagoblin/base.html +++ b/mediagoblin/templates/mediagoblin/base.html @@ -38,8 +38,12 @@- If you don't have an account, please - Register. -
+ {% if allow_registration %} ++ If you don't have an account, please + Register. +
+ {% endif %} {% endif %} {# temporarily, an "image gallery" that isn't one really ;) #} diff --git a/mediagoblin/templates/mediagoblin/submit/success.html b/mediagoblin/templates/mediagoblin/submit/success.html deleted file mode 100644 index afc9f9d1..00000000 --- a/mediagoblin/templates/mediagoblin/submit/success.html +++ /dev/null @@ -1,22 +0,0 @@ -{# -# GNU MediaGoblin -- federated, autonomous media hosting -# Copyright (C) 2011 Free Software Foundation, Inc -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see