Merge branch 'master' into test_submission_views_365
@ -57,6 +57,11 @@ requirements::
|
|||||||
sudo apt-get install mongodb git-core python python-dev \
|
sudo apt-get install mongodb git-core python python-dev \
|
||||||
python-lxml
|
python-lxml
|
||||||
|
|
||||||
|
On Fedora::
|
||||||
|
|
||||||
|
yum install mongodb-server python-paste-deploy python-paste-script \
|
||||||
|
git-core python python-devel
|
||||||
|
|
||||||
.. YouCanHelp::
|
.. YouCanHelp::
|
||||||
|
|
||||||
If you have instructions for other GNU/Linux distributions to set
|
If you have instructions for other GNU/Linux distributions to set
|
||||||
|
@ -8,6 +8,9 @@ email_sender_address = "notice@mediagoblin.example.org"
|
|||||||
# set to false to enable sending notices
|
# set to false to enable sending notices
|
||||||
email_debug_mode = true
|
email_debug_mode = true
|
||||||
|
|
||||||
|
# Set to false to disable registrations
|
||||||
|
allow_registration = true
|
||||||
|
|
||||||
## Uncomment this to put some user-overriding templates here
|
## Uncomment this to put some user-overriding templates here
|
||||||
#local_templates = %(here)s/user_dev/templates/
|
#local_templates = %(here)s/user_dev/templates/
|
||||||
|
|
||||||
|
@ -20,18 +20,12 @@ import urllib
|
|||||||
import routes
|
import routes
|
||||||
from webob import Request, exc
|
from webob import Request, exc
|
||||||
|
|
||||||
from mediagoblin import routing, util, storage, staticdirect
|
from mediagoblin import routing, util, storage
|
||||||
from mediagoblin.init.config import (
|
|
||||||
read_mediagoblin_config, generate_validation_report)
|
|
||||||
from mediagoblin.db.open import setup_connection_and_db_from_config
|
from mediagoblin.db.open import setup_connection_and_db_from_config
|
||||||
from mediagoblin.mg_globals import setup_globals
|
from mediagoblin.mg_globals import setup_globals
|
||||||
from mediagoblin.init.celery import setup_celery_from_config
|
from mediagoblin.init.celery import setup_celery_from_config
|
||||||
from mediagoblin.init import get_jinja_loader
|
from mediagoblin.init import get_jinja_loader, get_staticdirector, \
|
||||||
from mediagoblin.workbench import WorkbenchManager
|
setup_global_and_app_config, setup_workbench
|
||||||
|
|
||||||
|
|
||||||
class Error(Exception): pass
|
|
||||||
class ImproperlyConfigured(Error): pass
|
|
||||||
|
|
||||||
|
|
||||||
class MediaGoblinApp(object):
|
class MediaGoblinApp(object):
|
||||||
@ -55,13 +49,7 @@ class MediaGoblinApp(object):
|
|||||||
##############
|
##############
|
||||||
|
|
||||||
# Open and setup the config
|
# Open and setup the config
|
||||||
global_config, validation_result = read_mediagoblin_config(config_path)
|
global_config, app_config = setup_global_and_app_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)
|
|
||||||
|
|
||||||
##########################################
|
##########################################
|
||||||
# Setup other connections / useful objects
|
# Setup other connections / useful objects
|
||||||
@ -85,19 +73,7 @@ class MediaGoblinApp(object):
|
|||||||
self.routing = routing.get_mapper()
|
self.routing = routing.get_mapper()
|
||||||
|
|
||||||
# set up staticdirector tool
|
# set up staticdirector tool
|
||||||
if app_config.has_key('direct_remote_path'):
|
self.staticdirector = get_staticdirector(app_config)
|
||||||
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")
|
|
||||||
|
|
||||||
# Setup celery, if appropriate
|
# Setup celery, if appropriate
|
||||||
if setup_celery and not app_config.get('celery_setup_elsewhere'):
|
if setup_celery and not app_config.get('celery_setup_elsewhere'):
|
||||||
@ -117,9 +93,6 @@ class MediaGoblinApp(object):
|
|||||||
#######################################################
|
#######################################################
|
||||||
|
|
||||||
setup_globals(
|
setup_globals(
|
||||||
app_config=app_config,
|
|
||||||
global_config=global_config,
|
|
||||||
|
|
||||||
# TODO: No need to set these two up as globals, we could
|
# TODO: No need to set these two up as globals, we could
|
||||||
# just read them out of mg_globals.app_config
|
# just read them out of mg_globals.app_config
|
||||||
email_sender_address=app_config['email_sender_address'],
|
email_sender_address=app_config['email_sender_address'],
|
||||||
@ -130,8 +103,11 @@ class MediaGoblinApp(object):
|
|||||||
db_connection=self.connection,
|
db_connection=self.connection,
|
||||||
database=self.db,
|
database=self.db,
|
||||||
public_store=self.public_store,
|
public_store=self.public_store,
|
||||||
queue_store=self.queue_store,
|
queue_store=self.queue_store)
|
||||||
workbench_manager=WorkbenchManager(app_config['workbench_path']))
|
|
||||||
|
# Workbench *currently* only used by celery, so this only
|
||||||
|
# matters in always eager mode :)
|
||||||
|
setup_workbench()
|
||||||
|
|
||||||
def __call__(self, environ, start_response):
|
def __call__(self, environ, start_response):
|
||||||
request = Request(environ)
|
request = Request(environ)
|
||||||
|
@ -18,6 +18,8 @@ import uuid
|
|||||||
|
|
||||||
from webob import exc
|
from webob import exc
|
||||||
|
|
||||||
|
from mediagoblin import messages
|
||||||
|
from mediagoblin import mg_globals
|
||||||
from mediagoblin.util import render_to_response, redirect
|
from mediagoblin.util import render_to_response, redirect
|
||||||
from mediagoblin.db.util import ObjectId
|
from mediagoblin.db.util import ObjectId
|
||||||
from mediagoblin.auth import lib as auth_lib
|
from mediagoblin.auth import lib as auth_lib
|
||||||
@ -29,6 +31,14 @@ def register(request):
|
|||||||
"""
|
"""
|
||||||
Your classic registration view!
|
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)
|
register_form = auth_forms.RegistrationForm(request.POST)
|
||||||
|
|
||||||
if request.method == 'POST' and register_form.validate():
|
if request.method == 'POST' and register_form.validate():
|
||||||
@ -97,7 +107,8 @@ def login(request):
|
|||||||
'mediagoblin/auth/login.html',
|
'mediagoblin/auth/login.html',
|
||||||
{'login_form': login_form,
|
{'login_form': login_form,
|
||||||
'next': request.GET.get('next') or request.POST.get('next'),
|
'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):
|
def logout(request):
|
||||||
@ -124,16 +135,24 @@ def verify_email(request):
|
|||||||
if user and user['verification_key'] == unicode(request.GET['token']):
|
if user and user['verification_key'] == unicode(request.GET['token']):
|
||||||
user['status'] = u'active'
|
user['status'] = u'active'
|
||||||
user['email_verified'] = True
|
user['email_verified'] = True
|
||||||
verification_successful = True
|
|
||||||
user.save()
|
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:
|
else:
|
||||||
verification_successful = False
|
verification_successful = False
|
||||||
|
messages.add_message(request,
|
||||||
|
messages.ERROR,
|
||||||
|
'The verification key or user id is incorrect')
|
||||||
|
|
||||||
return render_to_response(
|
return render_to_response(
|
||||||
request,
|
request,
|
||||||
'mediagoblin/auth/verify_email.html',
|
'mediagoblin/user_pages/user.html',
|
||||||
{'user': user,
|
{'user': user,
|
||||||
'verification_successful': verification_successful})
|
'verification_successful' : verification_successful})
|
||||||
|
|
||||||
|
|
||||||
def resend_activation(request):
|
def resend_activation(request):
|
||||||
|
@ -21,6 +21,9 @@ direct_remote_path = string(default="/mgoblin_static/")
|
|||||||
email_debug_mode = boolean(default=True)
|
email_debug_mode = boolean(default=True)
|
||||||
email_sender_address = string(default="notice@mediagoblin.example.org")
|
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:
|
# By default not set, but you might want something like:
|
||||||
# "%(here)s/user_dev/templates/"
|
# "%(here)s/user_dev/templates/"
|
||||||
local_templates = string()
|
local_templates = string()
|
||||||
|
@ -45,11 +45,13 @@ REQUIRED READING:
|
|||||||
To remove deprecated indexes
|
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 = {
|
DEPRECATED_INDEXES = {
|
||||||
'collection_name': [
|
'collection_name': {
|
||||||
'deprecated_index_identifier1', 'deprecated_index_identifier2']}
|
'deprecated_index_identifier1': {
|
||||||
|
'index': [index_foo_goes_here]}}
|
||||||
|
|
||||||
... etc.
|
... etc.
|
||||||
|
|
||||||
|
@ -147,31 +147,33 @@ 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' : {"$lt": self['_id']},
|
cursor = self.db.MediaEntry.find({'_id' : {"$gt": self['_id']},
|
||||||
'uploader': self['uploader']}).sort(
|
'uploader': self['uploader'],
|
||||||
'_id', DESCENDING).limit(1)
|
'state': 'processed'}).sort(
|
||||||
|
'_id', ASCENDING).limit(1)
|
||||||
if cursor.count():
|
if cursor.count():
|
||||||
return urlgen('mediagoblin.user_pages.media_home',
|
return urlgen('mediagoblin.user_pages.media_home',
|
||||||
user=self.uploader()['username'],
|
user=self.uploader()['username'],
|
||||||
media=unicode(cursor[0]['_id']))
|
media=unicode(cursor[0]['slug']))
|
||||||
|
|
||||||
def url_to_next(self, urlgen):
|
def url_to_next(self, urlgen):
|
||||||
"""
|
"""
|
||||||
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' : {"$gt": self['_id']},
|
cursor = self.db.MediaEntry.find({'_id' : {"$lt": self['_id']},
|
||||||
'uploader': self['uploader']}).sort(
|
'uploader': self['uploader'],
|
||||||
'_id', ASCENDING).limit(1)
|
'state': 'processed'}).sort(
|
||||||
|
'_id', DESCENDING).limit(1)
|
||||||
|
|
||||||
if cursor.count():
|
if cursor.count():
|
||||||
return urlgen('mediagoblin.user_pages.media_home',
|
return urlgen('mediagoblin.user_pages.media_home',
|
||||||
user=self.uploader()['username'],
|
user=self.uploader()['username'],
|
||||||
media=unicode(cursor[0]['_id']))
|
media=unicode(cursor[0]['slug']))
|
||||||
|
|
||||||
def uploader(self):
|
def uploader(self):
|
||||||
return self.db.User.find_one({'_id': self['uploader']})
|
return self.db.User.find_one({'_id': self['uploader']})
|
||||||
|
|
||||||
|
|
||||||
class MediaComment(Document):
|
class MediaComment(Document):
|
||||||
__collection__ = 'media_comments'
|
__collection__ = 'media_comments'
|
||||||
|
|
||||||
|
@ -81,18 +81,25 @@ def remove_deprecated_indexes(database, deprecated_indexes=DEPRECATED_INDEXES):
|
|||||||
Args:
|
Args:
|
||||||
- database: pymongo or mongokit database instance.
|
- database: pymongo or mongokit database instance.
|
||||||
- deprecated_indexes: the indexes to deprecate in the pattern of:
|
- 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:
|
Returns:
|
||||||
A list of indexes removed in form ('collection', 'index_name')
|
A list of indexes removed in form ('collection', 'index_name')
|
||||||
"""
|
"""
|
||||||
indexes_removed = []
|
indexes_removed = []
|
||||||
|
|
||||||
for collection_name, index_names in deprecated_indexes.iteritems():
|
for collection_name, indexes in deprecated_indexes.iteritems():
|
||||||
collection = database[collection_name]
|
collection = database[collection_name]
|
||||||
collection_indexes = collection.index_information().keys()
|
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:
|
if index_name in collection_indexes:
|
||||||
collection.drop_index(index_name)
|
collection.drop_index(index_name)
|
||||||
|
|
||||||
|
@ -23,7 +23,8 @@ class EditForm(wtforms.Form):
|
|||||||
'Title',
|
'Title',
|
||||||
[wtforms.validators.Length(min=0, max=500)])
|
[wtforms.validators.Length(min=0, max=500)])
|
||||||
slug = wtforms.TextField(
|
slug = wtforms.TextField(
|
||||||
'Slug')
|
'Slug',
|
||||||
|
[wtforms.validators.Required(message="The slug can't be empty")])
|
||||||
description = wtforms.TextAreaField('Description of this work')
|
description = wtforms.TextAreaField('Description of this work')
|
||||||
|
|
||||||
class EditProfileForm(wtforms.Form):
|
class EditProfileForm(wtforms.Form):
|
||||||
@ -31,4 +32,5 @@ class EditProfileForm(wtforms.Form):
|
|||||||
[wtforms.validators.Length(min=0, max=500)])
|
[wtforms.validators.Length(min=0, max=500)])
|
||||||
url = wtforms.TextField(
|
url = wtforms.TextField(
|
||||||
'Website',
|
'Website',
|
||||||
[wtforms.validators.URL(message='Improperly formed URL')])
|
[wtforms.validators.Optional(),
|
||||||
|
wtforms.validators.URL(message='Improperly formed URL')])
|
||||||
|
@ -107,8 +107,8 @@ def edit_profile(request):
|
|||||||
messages.SUCCESS,
|
messages.SUCCESS,
|
||||||
'Profile edited!')
|
'Profile edited!')
|
||||||
return redirect(request,
|
return redirect(request,
|
||||||
"mediagoblin.edit.profile",
|
'mediagoblin.user_pages.user_home',
|
||||||
username=edit_username)
|
user=edit_username)
|
||||||
|
|
||||||
return render_to_response(
|
return render_to_response(
|
||||||
request,
|
request,
|
||||||
|
@ -15,8 +15,33 @@
|
|||||||
# 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 jinja2
|
import jinja2
|
||||||
|
from mediagoblin import staticdirect
|
||||||
|
from mediagoblin.init.config import (
|
||||||
|
read_mediagoblin_config, generate_validation_report)
|
||||||
|
from mediagoblin import mg_globals
|
||||||
|
from mediagoblin.mg_globals import setup_globals
|
||||||
|
from mediagoblin.workbench import WorkbenchManager
|
||||||
|
|
||||||
|
|
||||||
|
class Error(Exception): pass
|
||||||
|
class ImproperlyConfigured(Error): pass
|
||||||
|
|
||||||
|
|
||||||
|
def setup_global_and_app_config(config_path):
|
||||||
|
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)
|
||||||
|
|
||||||
|
setup_globals(
|
||||||
|
app_config=app_config,
|
||||||
|
global_config=global_config)
|
||||||
|
|
||||||
|
return global_config, app_config
|
||||||
|
|
||||||
def get_jinja_loader(user_template_path=None):
|
def get_jinja_loader(user_template_path=None):
|
||||||
"""
|
"""
|
||||||
Set up the Jinja template loaders, possibly allowing for user
|
Set up the Jinja template loaders, possibly allowing for user
|
||||||
@ -31,3 +56,27 @@ def get_jinja_loader(user_template_path=None):
|
|||||||
jinja2.PackageLoader('mediagoblin', 'templates')])
|
jinja2.PackageLoader('mediagoblin', 'templates')])
|
||||||
else:
|
else:
|
||||||
return jinja2.PackageLoader('mediagoblin', 'templates')
|
return jinja2.PackageLoader('mediagoblin', 'templates')
|
||||||
|
|
||||||
|
|
||||||
|
def get_staticdirector(app_config):
|
||||||
|
if app_config.has_key('direct_remote_path'):
|
||||||
|
return 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()
|
||||||
|
return 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")
|
||||||
|
|
||||||
|
|
||||||
|
def setup_workbench():
|
||||||
|
app_config = mg_globals.app_config
|
||||||
|
|
||||||
|
workbench_manager = WorkbenchManager(app_config['workbench_path'])
|
||||||
|
|
||||||
|
setup_globals(workbench_manager = workbench_manager)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
body {
|
body {
|
||||||
background-color: #272727;
|
background-color: #1F1F1F;
|
||||||
color: #f7f7f7;
|
color: #aaa;
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
padding:none;
|
padding:none;
|
||||||
margin:0px;
|
margin:0px;
|
||||||
@ -18,7 +18,7 @@ form {
|
|||||||
font-family: 'Carter One';
|
font-family: 'Carter One';
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
src: local('CarterOne'), url('http://themes.googleusercontent.com/font?kit=VjW2qt1pkqVtO22ObxgEBRsxEYwM7FgeyaSgU71cLG0') format('woff');
|
src: local('CarterOne'), url('http://themes.googleusercontent.com/font?kit=FWNn6ITYqL6or7ZTmBxRhq3fkYX5z1QtDUdIWoaaD_k') format('woff');
|
||||||
}
|
}
|
||||||
|
|
||||||
/* text styles */
|
/* text styles */
|
||||||
@ -33,13 +33,8 @@ h2{
|
|||||||
margin-top:20px;
|
margin-top:20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
|
||||||
font-family: sans-serif;
|
|
||||||
font-size:16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: #86D4B1;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
label {
|
label {
|
||||||
@ -56,15 +51,33 @@ label {
|
|||||||
.mediagoblin_header {
|
.mediagoblin_header {
|
||||||
width:100%;
|
width:100%;
|
||||||
height:36px;
|
height:36px;
|
||||||
background-color:#393939;
|
background-color:#2F2F2F;
|
||||||
padding-top:14px;
|
padding-top:14px;
|
||||||
margin-bottom:40px;
|
margin-bottom:40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.header_submit{
|
||||||
|
color:#272727;
|
||||||
|
background-color:#aaa;
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, from(##D2D2D2), to(#aaa));
|
||||||
|
background-image: -webkit-linear-gradient(top, #D2D2D2, #aaa);
|
||||||
|
background-image: -moz-linear-gradient(top, #D2D2D2, #aaa);
|
||||||
|
background-image: -ms-linear-gradient(top, #D2D2D2, #aaa);
|
||||||
|
background-image: -o-linear-gradient(top, #D2D2D2, #aaa);
|
||||||
|
background-image: linear-gradient(top, #D2D2D2, #aaa);
|
||||||
|
box-shadow:0px 0px 4px #000;
|
||||||
|
border-radius:5px 5px 5px 5px;
|
||||||
|
margin:8px;
|
||||||
|
padding:3px 8px;
|
||||||
|
text-decoration:none;
|
||||||
|
border:medium none;
|
||||||
|
font-family:'Carter One',arial,serif;
|
||||||
|
}
|
||||||
|
|
||||||
.mediagoblin_footer {
|
.mediagoblin_footer {
|
||||||
width:100%;
|
width:100%;
|
||||||
height:26px;
|
height:30px;
|
||||||
background-color:#393939;
|
background-color:#2F2F2F;
|
||||||
bottom:0px;
|
bottom:0px;
|
||||||
padding-top:8px;
|
padding-top:8px;
|
||||||
position:absolute;
|
position:absolute;
|
||||||
@ -77,19 +90,6 @@ label {
|
|||||||
padding-bottom:74px;
|
padding-bottom:74px;
|
||||||
}
|
}
|
||||||
|
|
||||||
a.mediagoblin_logo {
|
|
||||||
width:34px;
|
|
||||||
height:25px;
|
|
||||||
margin-right:10px;
|
|
||||||
background-image:url('../images/icon.png');
|
|
||||||
background-position:0px 0px;
|
|
||||||
display:inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
a.mediagoblin_logo:hover {
|
|
||||||
background-position:0px -28px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mediagoblin_header_right {
|
.mediagoblin_header_right {
|
||||||
float:right;
|
float:right;
|
||||||
}
|
}
|
||||||
@ -122,6 +122,10 @@ a.mediagoblin_logo:hover {
|
|||||||
text-align:center;
|
text-align:center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pagination_arrow{
|
||||||
|
margin:5px;
|
||||||
|
}
|
||||||
|
|
||||||
/* forms */
|
/* forms */
|
||||||
|
|
||||||
.form_box {
|
.form_box {
|
||||||
@ -130,7 +134,7 @@ text-align:center;
|
|||||||
background-repeat:repeat-x;
|
background-repeat:repeat-x;
|
||||||
font-size:18px;
|
font-size:18px;
|
||||||
padding-bottom:30px;
|
padding-bottom:30px;
|
||||||
padding-top:1px;
|
padding-top:30px;
|
||||||
margin-left:auto;
|
margin-left:auto;
|
||||||
margin-right:auto;
|
margin-right:auto;
|
||||||
display:block;
|
display:block;
|
||||||
@ -160,6 +164,7 @@ text-align:center;
|
|||||||
|
|
||||||
.form_field_error {
|
.form_field_error {
|
||||||
background-color:#87453b;
|
background-color:#87453b;
|
||||||
|
color:#fff;
|
||||||
border:none;
|
border:none;
|
||||||
font-size:16px;
|
font-size:16px;
|
||||||
padding:9px;
|
padding:9px;
|
||||||
@ -204,14 +209,14 @@ img.media_icon{
|
|||||||
/* navigation */
|
/* navigation */
|
||||||
|
|
||||||
.navigation_button{
|
.navigation_button{
|
||||||
width: 139px;
|
width:139px;
|
||||||
display:block;
|
display:block;
|
||||||
float:left;
|
float:left;
|
||||||
text-align: center;
|
text-align:center;
|
||||||
background-color: #393939;
|
background-color:#393939;
|
||||||
text-decoration: none;
|
text-decoration:none;
|
||||||
padding: 6px 0pt;
|
padding:12px 0pt;
|
||||||
font-family: 'Carter One', arial, serif;
|
font-family:'Carter One', arial, serif;
|
||||||
font-size:2em;
|
font-size:2em;
|
||||||
margin:0 0 20px
|
margin:0 0 20px
|
||||||
}
|
}
|
||||||
@ -257,11 +262,3 @@ ul.mediagoblin_messages {
|
|||||||
background-color: #f7f7f7;
|
background-color: #f7f7f7;
|
||||||
color:#272727;
|
color:#272727;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* profile stuff */
|
|
||||||
|
|
||||||
.profile_content {
|
|
||||||
padding: 6px;
|
|
||||||
background-color: #393939;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
Before Width: | Height: | Size: 1.6 KiB |
BIN
mediagoblin/static/images/logo.png
Normal file
After Width: | Height: | Size: 839 B |
BIN
mediagoblin/static/images/navigation_end.png
Normal file
After Width: | Height: | Size: 718 B |
BIN
mediagoblin/static/images/navigation_left.png
Normal file
After Width: | Height: | Size: 406 B |
BIN
mediagoblin/static/images/navigation_right.png
Normal file
After Width: | Height: | Size: 383 B |
BIN
mediagoblin/static/images/pagination_left.png
Normal file
After Width: | Height: | Size: 252 B |
BIN
mediagoblin/static/images/pagination_right.png
Normal file
After Width: | Height: | Size: 249 B |
@ -18,7 +18,4 @@ from routes.route import Route
|
|||||||
|
|
||||||
submit_routes = [
|
submit_routes = [
|
||||||
Route('mediagoblin.submit.start', '/',
|
Route('mediagoblin.submit.start', '/',
|
||||||
controller='mediagoblin.submit.views:submit_start'),
|
controller='mediagoblin.submit.views:submit_start')]
|
||||||
Route('mediagoblin.submit.success', '/success/',
|
|
||||||
template='mediagoblin/submit/success.html',
|
|
||||||
controller='mediagoblin.views:simple_template_render')]
|
|
||||||
|
@ -95,8 +95,3 @@ def submit_start(request):
|
|||||||
request,
|
request,
|
||||||
'mediagoblin/submit/start.html',
|
'mediagoblin/submit/start.html',
|
||||||
{'submit_form': submit_form})
|
{'submit_form': submit_form})
|
||||||
|
|
||||||
|
|
||||||
def submit_success(request):
|
|
||||||
return render_to_response(
|
|
||||||
request, 'mediagoblin/submit/success.html', {})
|
|
||||||
|
@ -35,7 +35,9 @@
|
|||||||
<input type="hidden" name="next" value="{{ next }}" class="button"
|
<input type="hidden" name="next" value="{{ next }}" class="button"
|
||||||
style="display: none;"/>
|
style="display: none;"/>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if allow_registration %}
|
||||||
<p>Don't have an account yet?<br /><a href="{{ request.urlgen('mediagoblin.auth.register') }}">Create one here!</a></p>
|
<p>Don't have an account yet?<br /><a href="{{ request.urlgen('mediagoblin.auth.register') }}">Create one here!</a></p>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -1,28 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
#}
|
|
||||||
{% extends "mediagoblin/base.html" %}
|
|
||||||
|
|
||||||
{% block mediagoblin_content %}
|
|
||||||
<p>
|
|
||||||
{% if verification_successful %}
|
|
||||||
Your email address has been verified!
|
|
||||||
{% else %}
|
|
||||||
The verification key or user id is incorrect
|
|
||||||
{% endif %}
|
|
||||||
</p>
|
|
||||||
{% endblock %}
|
|
@ -38,8 +38,12 @@
|
|||||||
<div class="container_16">
|
<div class="container_16">
|
||||||
<div class="grid_16">
|
<div class="grid_16">
|
||||||
{% block mediagoblin_logo %}
|
{% block mediagoblin_logo %}
|
||||||
<a class="mediagoblin_logo" href="{{ request.urlgen('index') }}"></a>
|
<a class="mediagoblin_logo" href="{{ request.urlgen('index') }}"><img src="{{ request.staticdirect('/images/logo.png') }}" alt="Mediagoblin logo" /></a>
|
||||||
{% endblock %}{% block mediagoblin_header_title %}{% endblock %}
|
{% endblock %}
|
||||||
|
{% if request.user %}
|
||||||
|
<a class="header_submit" href="{{ request.urlgen('mediagoblin.submit.start') }}">Submit media</a>
|
||||||
|
{% endif %}
|
||||||
|
{% block mediagoblin_header_title %}{% endblock %}
|
||||||
<div class="mediagoblin_header_right">
|
<div class="mediagoblin_header_right">
|
||||||
{% if request.user %}
|
{% if request.user %}
|
||||||
<a href="{{ request.urlgen('mediagoblin.user_pages.user_home',
|
<a href="{{ request.urlgen('mediagoblin.user_pages.user_home',
|
||||||
|
@ -29,11 +29,13 @@
|
|||||||
If you have an account, you can
|
If you have an account, you can
|
||||||
<a href="{{ request.urlgen('mediagoblin.auth.login') }}">Login</a>.
|
<a href="{{ request.urlgen('mediagoblin.auth.login') }}">Login</a>.
|
||||||
</p>
|
</p>
|
||||||
|
{% if allow_registration %}
|
||||||
<p>
|
<p>
|
||||||
If you don't have an account, please
|
If you don't have an account, please
|
||||||
<a href="{{ request.urlgen('mediagoblin.auth.register') }}">Register</a>.
|
<a href="{{ request.urlgen('mediagoblin.auth.register') }}">Register</a>.
|
||||||
</p>
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{# temporarily, an "image gallery" that isn't one really ;) #}
|
{# temporarily, an "image gallery" that isn't one really ;) #}
|
||||||
|
|
||||||
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
#}
|
|
||||||
{% extends "mediagoblin/base.html" %}
|
|
||||||
|
|
||||||
{% block mediagoblin_content %}
|
|
||||||
Woohoo! Submitted!
|
|
||||||
{% endblock %}
|
|
@ -55,7 +55,7 @@
|
|||||||
<form action="{{ request.urlgen('mediagoblin.user_pages.media_post_comment',
|
<form action="{{ request.urlgen('mediagoblin.user_pages.media_post_comment',
|
||||||
user= media.uploader().username,
|
user= media.uploader().username,
|
||||||
media=media._id) }}" method="POST">
|
media=media._id) }}" method="POST">
|
||||||
{{ wtforms_util.render_field_div(comment_form.comment) }}
|
{{ wtforms_util.render_field_div(comment_form.comment_content) }}
|
||||||
<div class="form_submit_buttons">
|
<div class="form_submit_buttons">
|
||||||
<input type="submit" value="Post comment!" class="button" />
|
<input type="submit" value="Post comment!" class="button" />
|
||||||
</div>
|
</div>
|
||||||
@ -65,7 +65,12 @@
|
|||||||
{% if comments %}
|
{% if comments %}
|
||||||
{% for comment in comments %}
|
{% for comment in comments %}
|
||||||
{% set comment_author = comment.author() %}
|
{% set comment_author = comment.author() %}
|
||||||
|
{% if pagination.active_id == comment._id %}
|
||||||
|
<div class="comment_wrapper comment_active" id="comment-{{ comment['_id'] }}">
|
||||||
|
<a name="comment" id="comment"></a>
|
||||||
|
{% else %}
|
||||||
<div class="comment_wrapper" id="comment-{{ comment['_id'] }}">
|
<div class="comment_wrapper" id="comment-{{ comment['_id'] }}">
|
||||||
|
{% endif %}
|
||||||
<div class="comment_content">
|
<div class="comment_content">
|
||||||
{% autoescape False %}
|
{% autoescape False %}
|
||||||
{{ comment.content_html }}
|
{{ comment.content_html }}
|
||||||
@ -77,7 +82,10 @@
|
|||||||
{{ comment_author['username'] }}</a> at
|
{{ comment_author['username'] }}</a> at
|
||||||
<!--</div>
|
<!--</div>
|
||||||
<div class="comment_datetime">-->
|
<div class="comment_datetime">-->
|
||||||
<a href="#comment-{{ comment['_id'] }}">
|
<a href="{{ request.urlgen('mediagoblin.user_pages.media_home.view_comment',
|
||||||
|
comment = comment['_id'],
|
||||||
|
user = media.uploader().username,
|
||||||
|
media = media._id) }}#comment">
|
||||||
{{ "%4d-%02d-%02d %02d:%02d"|format(comment.created.year,
|
{{ "%4d-%02d-%02d %02d:%02d"|format(comment.created.year,
|
||||||
comment.created.month,
|
comment.created.month,
|
||||||
comment.created.day,
|
comment.created.day,
|
||||||
@ -88,7 +96,10 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
{{ render_pagination(request, pagination) }}
|
{{ render_pagination(request, pagination,
|
||||||
|
request.urlgen('mediagoblin.user_pages.media_home',
|
||||||
|
user = media.uploader().username,
|
||||||
|
media = media._id)) }}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="grid_5 omega">
|
<div class="grid_5 omega">
|
||||||
|
@ -27,32 +27,24 @@
|
|||||||
{% block mediagoblin_content -%}
|
{% block mediagoblin_content -%}
|
||||||
{% if user %}
|
{% if user %}
|
||||||
<h1>{{ user.username }}'s profile</h1>
|
<h1>{{ user.username }}'s profile</h1>
|
||||||
|
<div class="grid_6 alpha">
|
||||||
{% include "mediagoblin/utils/profile.html" %}
|
{% include "mediagoblin/utils/profile.html" %}
|
||||||
|
|
||||||
{% if request.user['_id'] == user['_id'] or request.user['is_admin'] %}
|
{% if request.user['_id'] == user['_id'] or request.user['is_admin'] %}
|
||||||
<a href="{{ request.urlgen('mediagoblin.edit.profile') }}?username={{
|
<a href="{{ request.urlgen('mediagoblin.edit.profile') }}?username={{
|
||||||
user.username }}">Edit profile</a>
|
user.username }}">Edit profile</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
</div>
|
||||||
{% if request.user['_id'] == user['_id'] %}
|
<div class="grid_10 omega">
|
||||||
<p>
|
|
||||||
<a href="{{ request.urlgen('mediagoblin.submit.start') }}">Submit an item</a>
|
|
||||||
</p>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% set pagination_base_url = user_gallery_url %}
|
{% set pagination_base_url = user_gallery_url %}
|
||||||
{% include "mediagoblin/utils/object_gallery.html" %}
|
{% include "mediagoblin/utils/object_gallery.html" %}
|
||||||
|
|
||||||
<div class="clear"></div>
|
<div class="clear"></div>
|
||||||
|
|
||||||
<p><a href="{{ user_gallery_url }}">View all of {{ user.username }}'s media</a></p>
|
<p><a href="{{ user_gallery_url }}">View all of {{ user.username }}'s media</a></p>
|
||||||
|
|
||||||
<a href={{ request.urlgen(
|
<a href={{ request.urlgen(
|
||||||
'mediagoblin.user_pages.atom_feed',
|
'mediagoblin.user_pages.atom_feed',
|
||||||
user=user.username) }}>atom feed</a>
|
user=user.username) }}>atom feed</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
{# This *should* not occur as the view makes sure we pass in a user. #}
|
{# This *should* not occur as the view makes sure we pass in a user. #}
|
||||||
<p>Sorry, no such user found.<p/>
|
<p>Sorry, no such user found.<p/>
|
||||||
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -34,9 +34,16 @@
|
|||||||
{% if pagination.has_prev %}
|
{% if pagination.has_prev %}
|
||||||
<a href="{{ pagination.get_page_url_explicit(
|
<a href="{{ pagination.get_page_url_explicit(
|
||||||
base_url, get_params,
|
base_url, get_params,
|
||||||
pagination.page - 1) }}">« Prev</a>
|
pagination.page - 1) }}"><img class="pagination_arrow" src="/mgoblin_static/images/pagination_left.png" alt="Previous page" />Newer</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if pagination.has_next %}
|
||||||
|
<a href="{{ pagination.get_page_url_explicit(
|
||||||
|
base_url, get_params,
|
||||||
|
pagination.page + 1) }}">Older<img class="pagination_arrow" src="/mgoblin_static/images/pagination_right.png" alt="Next page" />
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
<br />
|
||||||
|
Go to page:
|
||||||
{%- for page in pagination.iter_pages() %}
|
{%- for page in pagination.iter_pages() %}
|
||||||
{% if page %}
|
{% if page %}
|
||||||
{% if page != pagination.page %}
|
{% if page != pagination.page %}
|
||||||
@ -50,12 +57,6 @@
|
|||||||
<span class="ellipsis">…</span>
|
<span class="ellipsis">…</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
|
|
||||||
{% if pagination.has_next %}
|
|
||||||
<a href="{{ pagination.get_page_url_explicit(
|
|
||||||
base_url, get_params,
|
|
||||||
pagination.page + 1) }}">Next »</a>
|
|
||||||
{% endif %}
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -24,20 +24,23 @@
|
|||||||
{# There are no previous entries for the very first media entry #}
|
{# There are no previous entries for the very first media entry #}
|
||||||
{% if prev_entry_url %}
|
{% if prev_entry_url %}
|
||||||
<a class="navigation_button navigation_left" href="{{ prev_entry_url }}">
|
<a class="navigation_button navigation_left" href="{{ prev_entry_url }}">
|
||||||
<
|
<img src="/mgoblin_static/images/navigation_left.png" alt="Previous image" />
|
||||||
</a>
|
</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
{# This is the first entry. display greyed-out 'previous' image #}
|
{# This is the first entry. display greyed-out 'previous' image #}
|
||||||
<p class="navigation_button">X</p>
|
<p class="navigation_button navigation_left">
|
||||||
|
<img src="/mgoblin_static/images/navigation_end.png" alt="No previous images" />
|
||||||
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{# Likewise, this could be the very last media entry #}
|
{# Likewise, this could be the very last media entry #}
|
||||||
{% if next_entry_url %}
|
{% if next_entry_url %}
|
||||||
<a class="navigation_button" href="{{ next_entry_url }}">
|
<a class="navigation_button" href="{{ next_entry_url }}">
|
||||||
>
|
<img src="/mgoblin_static/images/navigation_right.png" alt="Next image" />
|
||||||
</a>
|
</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
{# This is the last entry. display greyed-out 'next' image #}
|
{# This is the last entry. display greyed-out 'next' image #}
|
||||||
<p class="navigation_button">X</p>
|
<p class="navigation_button">
|
||||||
|
<img src="/mgoblin_static/images/navigation_end.png" alt="No following images" />
|
||||||
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
@ -17,19 +17,14 @@
|
|||||||
#}
|
#}
|
||||||
|
|
||||||
{% block profile_content -%}
|
{% block profile_content -%}
|
||||||
{% if user.url or user.bio %}
|
|
||||||
<div class="profile_content">
|
|
||||||
{% if user.url %}
|
|
||||||
<div class="profile_homepage">
|
|
||||||
<a href="{{ user.url }}">{{ user.url }}</a>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if user.bio %}
|
{% if user.bio %}
|
||||||
<div class="profile_bio">
|
<p>
|
||||||
{{ user.bio }}
|
{{ user.bio }}
|
||||||
</div>
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
{% if user.url %}
|
||||||
|
<p>
|
||||||
|
<a href="{{ user.url }}">{{ user.url }}</a>
|
||||||
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -189,7 +189,7 @@ def test_register_views(test_app):
|
|||||||
"/auth/verify_email/?userid=%s&token=total_bs" % unicode(
|
"/auth/verify_email/?userid=%s&token=total_bs" % unicode(
|
||||||
new_user['_id']))
|
new_user['_id']))
|
||||||
context = util.TEMPLATE_TEST_CONTEXT[
|
context = util.TEMPLATE_TEST_CONTEXT[
|
||||||
'mediagoblin/auth/verify_email.html']
|
'mediagoblin/user_pages/user.html']
|
||||||
assert context['verification_successful'] == False
|
assert context['verification_successful'] == False
|
||||||
new_user = mg_globals.database.User.find_one(
|
new_user = mg_globals.database.User.find_one(
|
||||||
{'username': 'happygirl'})
|
{'username': 'happygirl'})
|
||||||
@ -201,7 +201,7 @@ def test_register_views(test_app):
|
|||||||
util.clear_test_template_context()
|
util.clear_test_template_context()
|
||||||
test_app.get("%s?%s" % (path, get_params))
|
test_app.get("%s?%s" % (path, get_params))
|
||||||
context = util.TEMPLATE_TEST_CONTEXT[
|
context = util.TEMPLATE_TEST_CONTEXT[
|
||||||
'mediagoblin/auth/verify_email.html']
|
'mediagoblin/user_pages/user.html']
|
||||||
assert context['verification_successful'] == True
|
assert context['verification_successful'] == True
|
||||||
new_user = mg_globals.database.User.find_one(
|
new_user = mg_globals.database.User.find_one(
|
||||||
{'username': 'happygirl'})
|
{'username': 'happygirl'})
|
||||||
|
@ -17,5 +17,6 @@
|
|||||||
import wtforms
|
import wtforms
|
||||||
|
|
||||||
class MediaCommentForm(wtforms.Form):
|
class MediaCommentForm(wtforms.Form):
|
||||||
comment = wtforms.TextAreaField('Comment',
|
comment_content = wtforms.TextAreaField(
|
||||||
|
'Comment',
|
||||||
[wtforms.validators.Required()])
|
[wtforms.validators.Required()])
|
@ -24,6 +24,9 @@ user_routes = [
|
|||||||
Route('mediagoblin.user_pages.media_home', '/{user}/m/{media}/',
|
Route('mediagoblin.user_pages.media_home', '/{user}/m/{media}/',
|
||||||
requirements=dict(m_id="[0-9a-fA-F]{24}"),
|
requirements=dict(m_id="[0-9a-fA-F]{24}"),
|
||||||
controller="mediagoblin.user_pages.views:media_home"),
|
controller="mediagoblin.user_pages.views:media_home"),
|
||||||
|
Route('mediagoblin.user_pages.media_home.view_comment',
|
||||||
|
'/{user}/m/{media}/c/{comment}/',
|
||||||
|
controller="mediagoblin.user_pages.views:media_home"),
|
||||||
Route('mediagoblin.edit.edit_media', "/{user}/m/{media}/edit/",
|
Route('mediagoblin.edit.edit_media', "/{user}/m/{media}/edit/",
|
||||||
controller="mediagoblin.edit.views:edit_media"),
|
controller="mediagoblin.edit.views:edit_media"),
|
||||||
Route('mediagoblin.user_pages.atom_feed', '/{user}/atom/',
|
Route('mediagoblin.user_pages.atom_feed', '/{user}/atom/',
|
||||||
|
@ -95,8 +95,14 @@ def media_home(request, media, page, **kwargs):
|
|||||||
"""
|
"""
|
||||||
'Homepage' of a MediaEntry()
|
'Homepage' of a MediaEntry()
|
||||||
"""
|
"""
|
||||||
|
if ObjectId(request.matchdict.get('comment')):
|
||||||
|
pagination = Pagination(
|
||||||
|
page, media.get_comments(), MEDIA_COMMENTS_PER_PAGE,
|
||||||
|
ObjectId(request.matchdict.get('comment')))
|
||||||
|
else:
|
||||||
|
pagination = Pagination(
|
||||||
|
page, media.get_comments(), MEDIA_COMMENTS_PER_PAGE)
|
||||||
|
|
||||||
pagination = Pagination(page, media.get_comments(), MEDIA_COMMENTS_PER_PAGE)
|
|
||||||
comments = pagination()
|
comments = pagination()
|
||||||
|
|
||||||
comment_form = user_forms.MediaCommentForm(request.POST)
|
comment_form = user_forms.MediaCommentForm(request.POST)
|
||||||
@ -118,7 +124,7 @@ def media_post_comment(request):
|
|||||||
comment = request.db.MediaComment()
|
comment = request.db.MediaComment()
|
||||||
comment['media_entry'] = ObjectId(request.matchdict['media'])
|
comment['media_entry'] = ObjectId(request.matchdict['media'])
|
||||||
comment['author'] = request.user['_id']
|
comment['author'] = request.user['_id']
|
||||||
comment['content'] = request.POST['comment']
|
comment['content'] = request.POST['comment_content']
|
||||||
|
|
||||||
comment['content_html'] = cleaned_markdown_conversion(comment['content'])
|
comment['content_html'] = cleaned_markdown_conversion(comment['content'])
|
||||||
|
|
||||||
|
@ -14,6 +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/>.
|
||||||
|
|
||||||
|
from __future__ import division
|
||||||
|
|
||||||
from email.MIMEText import MIMEText
|
from email.MIMEText import MIMEText
|
||||||
import gettext
|
import gettext
|
||||||
import pkg_resources
|
import pkg_resources
|
||||||
@ -21,7 +23,7 @@ import smtplib
|
|||||||
import sys
|
import sys
|
||||||
import re
|
import re
|
||||||
import urllib
|
import urllib
|
||||||
from math import ceil
|
from math import ceil, floor
|
||||||
import copy
|
import copy
|
||||||
|
|
||||||
from babel.localedata import exists
|
from babel.localedata import exists
|
||||||
@ -35,6 +37,8 @@ from mediagoblin import mg_globals
|
|||||||
from mediagoblin import messages
|
from mediagoblin import messages
|
||||||
from mediagoblin.db.util import ObjectId
|
from mediagoblin.db.util import ObjectId
|
||||||
|
|
||||||
|
from itertools import izip, count
|
||||||
|
|
||||||
TESTS_ENABLED = False
|
TESTS_ENABLED = False
|
||||||
def _activate_testing():
|
def _activate_testing():
|
||||||
"""
|
"""
|
||||||
@ -133,7 +137,16 @@ def render_to_response(request, template, context):
|
|||||||
|
|
||||||
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"""
|
||||||
return exc.HTTPFound(location=request.urlgen(*args, **kwargs))
|
|
||||||
|
querystring = None
|
||||||
|
if kwargs.get('querystring'):
|
||||||
|
querystring = kwargs.get('querystring')
|
||||||
|
del kwargs['querystring']
|
||||||
|
|
||||||
|
return exc.HTTPFound(
|
||||||
|
location=''.join([
|
||||||
|
request.urlgen(*args, **kwargs),
|
||||||
|
querystring if querystring else '']))
|
||||||
|
|
||||||
|
|
||||||
def setup_user_in_request(request):
|
def setup_user_in_request(request):
|
||||||
@ -418,7 +431,8 @@ class Pagination(object):
|
|||||||
get actual data slice through __call__().
|
get actual data slice through __call__().
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, page, cursor, per_page=PAGINATION_DEFAULT_PER_PAGE):
|
def __init__(self, page, cursor, per_page=PAGINATION_DEFAULT_PER_PAGE,
|
||||||
|
jump_to_id=False):
|
||||||
"""
|
"""
|
||||||
Initializes Pagination
|
Initializes Pagination
|
||||||
|
|
||||||
@ -426,11 +440,25 @@ class Pagination(object):
|
|||||||
- 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
|
||||||
|
with _id == jump_to_id.
|
||||||
"""
|
"""
|
||||||
self.page = page
|
self.page = page
|
||||||
self.per_page = per_page
|
self.per_page = per_page
|
||||||
self.cursor = cursor
|
self.cursor = cursor
|
||||||
self.total_count = self.cursor.count()
|
self.total_count = self.cursor.count()
|
||||||
|
self.active_id = None
|
||||||
|
|
||||||
|
if jump_to_id:
|
||||||
|
cursor = copy.copy(self.cursor)
|
||||||
|
|
||||||
|
for (doc, increment) in izip(cursor, count(0)):
|
||||||
|
if doc['_id'] == jump_to_id:
|
||||||
|
self.page = 1 + int(floor(increment / self.per_page))
|
||||||
|
|
||||||
|
self.active_id = jump_to_id
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
def __call__(self):
|
def __call__(self):
|
||||||
"""
|
"""
|
||||||
|
@ -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/>.
|
||||||
|
|
||||||
|
from mediagoblin import mg_globals
|
||||||
from mediagoblin.util import render_to_response
|
from mediagoblin.util import render_to_response
|
||||||
from mediagoblin.db.util import DESCENDING
|
from mediagoblin.db.util import DESCENDING
|
||||||
|
|
||||||
@ -23,7 +24,8 @@ def root_view(request):
|
|||||||
|
|
||||||
return render_to_response(
|
return render_to_response(
|
||||||
request, 'mediagoblin/root.html',
|
request, 'mediagoblin/root.html',
|
||||||
{'media_entries': media_entries})
|
{'media_entries': media_entries,
|
||||||
|
'allow_registration': mg_globals.app_config["allow_registration"]})
|
||||||
|
|
||||||
|
|
||||||
def simple_template_render(request):
|
def simple_template_render(request):
|
||||||
|