aboutsummaryrefslogtreecommitdiffstats
path: root/mediagoblin/tools
diff options
context:
space:
mode:
Diffstat (limited to 'mediagoblin/tools')
-rw-r--r--mediagoblin/tools/common.py1
-rw-r--r--mediagoblin/tools/files.py2
-rw-r--r--mediagoblin/tools/mail.py7
-rw-r--r--mediagoblin/tools/pagination.py18
-rw-r--r--mediagoblin/tools/request.py12
-rw-r--r--mediagoblin/tools/response.py7
-rw-r--r--mediagoblin/tools/template.py23
-rw-r--r--mediagoblin/tools/text.py12
-rw-r--r--mediagoblin/tools/url.py2
9 files changed, 59 insertions, 25 deletions
diff --git a/mediagoblin/tools/common.py b/mediagoblin/tools/common.py
index ea4541a8..12d8309e 100644
--- a/mediagoblin/tools/common.py
+++ b/mediagoblin/tools/common.py
@@ -21,6 +21,7 @@ DISPLAY_IMAGE_FETCHING_ORDER = [u'medium', u'original', u'thumb']
global TESTS_ENABLED
TESTS_ENABLED = False
+
def import_component(import_string):
"""
Import a module component defined by STRING. Probably a method,
diff --git a/mediagoblin/tools/files.py b/mediagoblin/tools/files.py
index e0bf0569..10f1d994 100644
--- a/mediagoblin/tools/files.py
+++ b/mediagoblin/tools/files.py
@@ -23,7 +23,7 @@ def delete_media_files(media):
Arguments:
- media: A MediaEntry document
"""
- for listpath in media['media_files'].itervalues():
+ for listpath in media.media_files.itervalues():
mg_globals.public_store.delete_file(
listpath)
diff --git a/mediagoblin/tools/mail.py b/mediagoblin/tools/mail.py
index 826acdbf..9e00be7d 100644
--- a/mediagoblin/tools/mail.py
+++ b/mediagoblin/tools/mail.py
@@ -24,7 +24,7 @@ from mediagoblin.tools import common
### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# We have two "test inboxes" here:
-#
+#
# EMAIL_TEST_INBOX:
# ----------------
# If you're writing test views, you'll probably want to check this.
@@ -44,11 +44,12 @@ from mediagoblin.tools import common
# ***IMPORTANT!***
# ----------------
# 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_MBOX_INBOX = []
+
class FakeMhost(object):
"""
Just a fake mail host so we can capture and test messages
@@ -63,12 +64,14 @@ class FakeMhost(object):
'to': to_addrs,
'message': message})
+
def _clear_test_inboxes():
global EMAIL_TEST_INBOX
global EMAIL_TEST_MBOX_INBOX
EMAIL_TEST_INBOX = []
EMAIL_TEST_MBOX_INBOX = []
+
### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
### </Special email test stuff>
### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/mediagoblin/tools/pagination.py b/mediagoblin/tools/pagination.py
index 3ea96e6d..5ebc3c5a 100644
--- a/mediagoblin/tools/pagination.py
+++ b/mediagoblin/tools/pagination.py
@@ -19,8 +19,10 @@ import copy
from math import ceil, floor
from itertools import izip, count
+
PAGINATION_DEFAULT_PER_PAGE = 30
+
class Pagination(object):
"""
Pagination class for mongodb queries.
@@ -37,9 +39,9 @@ class Pagination(object):
Args:
- page: requested page
- per_page: number of objects per page
- - cursor: db cursor
- - jump_to_id: ObjectId, sets the page to the page containing the object
- with _id == jump_to_id.
+ - 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.per_page = per_page
@@ -51,7 +53,7 @@ class Pagination(object):
cursor = copy.copy(self.cursor)
for (doc, increment) in izip(cursor, count(0)):
- if doc['_id'] == jump_to_id:
+ if doc._id == jump_to_id:
self.page = 1 + int(floor(increment / self.per_page))
self.active_id = jump_to_id
@@ -91,19 +93,19 @@ class Pagination(object):
last = num
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
- """
+ """
new_get_params = copy.copy(get_params or {})
new_get_params['page'] = page_no
return "%s?%s" % (
base_url, urllib.urlencode(new_get_params))
def get_page_url(self, request, page_no):
- """
+ """
Get a new page url based of the request, and the new page number.
This is a nice wrapper around get_page_url_explicit()
- """
+ """
return self.get_page_url_explicit(
request.full_path, request.GET, page_no)
diff --git a/mediagoblin/tools/request.py b/mediagoblin/tools/request.py
index b1cbe119..7e193125 100644
--- a/mediagoblin/tools/request.py
+++ b/mediagoblin/tools/request.py
@@ -14,7 +14,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-from mediagoblin.db.util import ObjectId
+from mediagoblin.db.util import ObjectId, InvalidId
def setup_user_in_request(request):
"""
@@ -25,13 +25,17 @@ def setup_user_in_request(request):
request.user = None
return
- user = None
- user = request.app.db.User.one(
- {'_id': ObjectId(request.session['user_id'])})
+ try:
+ oid = ObjectId(request.session['user_id'])
+ except InvalidId:
+ user = None
+ else:
+ user = request.db.User.one({'_id': oid})
if not user:
# Something's wrong... this user doesn't exist? Invalidate
# this session.
+ print "Killing session for %r" % request.session['user_id']
request.session.invalidate()
request.user = user
diff --git a/mediagoblin/tools/response.py b/mediagoblin/tools/response.py
index 1477b9bc..c905097c 100644
--- a/mediagoblin/tools/response.py
+++ b/mediagoblin/tools/response.py
@@ -17,22 +17,25 @@
from webob import Response, exc
from mediagoblin.tools.template import render_template
+
def render_to_response(request, template, context, status=200):
"""Much like Django's shortcut.render()"""
return Response(
render_template(request, template, context),
status=status)
+
def render_404(request):
"""
Render a 404.
"""
return render_to_response(
- request, 'mediagoblin/404.html', {}, status=400)
+ request, 'mediagoblin/404.html', {}, status=404)
+
def redirect(request, *args, **kwargs):
"""Returns a HTTPFound(), takes a request and then urlgen params"""
-
+
querystring = None
if kwargs.get('querystring'):
querystring = kwargs.get('querystring')
diff --git a/mediagoblin/tools/template.py b/mediagoblin/tools/template.py
index a773ca99..54a40de6 100644
--- a/mediagoblin/tools/template.py
+++ b/mediagoblin/tools/template.py
@@ -17,18 +17,19 @@
from math import ceil
import jinja2
from babel.localedata import exists
-from babel.support import LazyProxy
from mediagoblin import mg_globals
from mediagoblin import messages
from mediagoblin.tools import common
from mediagoblin.tools.translate import setup_gettext
-from mediagoblin.middleware.csrf import render_csrf_form_token
+from mediagoblin.meddleware.csrf import render_csrf_form_token
+
SETUP_JINJA_ENVS = {}
+
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;
for now this is good enough.)
@@ -40,8 +41,11 @@ def get_jinja_env(template_loader, locale):
if SETUP_JINJA_ENVS.has_key(locale):
return SETUP_JINJA_ENVS[locale]
+ # jinja2.StrictUndefined will give exceptions on references
+ # to undefined/unknown variables in templates.
template_env = jinja2.Environment(
loader=template_loader, autoescape=True,
+ undefined=jinja2.StrictUndefined,
extensions=['jinja2.ext.i18n', 'jinja2.ext.autoescape'])
template_env.install_gettext_callables(
@@ -51,15 +55,19 @@ def get_jinja_env(template_loader, locale):
# All templates will know how to ...
# ... fetch all waiting messages and remove them from the queue
# ... construct a grid of thumbnails or other media
+ # ... have access to the global and app config
template_env.globals['fetch_messages'] = messages.fetch_messages
template_env.globals['gridify_list'] = gridify_list
template_env.globals['gridify_cursor'] = gridify_cursor
+ template_env.globals['app_config'] = mg_globals.app_config
+ template_env.globals['global_config'] = mg_globals.global_config
if exists(locale):
SETUP_JINJA_ENVS[locale] = template_env
return template_env
+
# We'll store context information here when doing unit tests
TEMPLATE_TEST_CONTEXT = {}
@@ -74,10 +82,12 @@ def render_template(request, template_path, context):
template = request.template_env.get_template(
template_path)
context['request'] = request
- context['csrf_token'] = render_csrf_form_token(request)
+ rendered_csrf_token = render_csrf_form_token(request)
+ if rendered_csrf_token is not None:
+ context['csrf_token'] = render_csrf_form_token(request)
rendered = template.render(context)
-
- if common.TESTS_ENABLED:
+
+ if common.TESTS_ENABLED:
TEMPLATE_TEST_CONTEXT[template_path] = context
return rendered
@@ -87,6 +97,7 @@ def clear_test_template_context():
global TEMPLATE_TEST_CONTEXT
TEMPLATE_TEST_CONTEXT = {}
+
def gridify_list(this_list, num_cols=5):
"""
Generates a list of lists where each sub-list's length depends on
diff --git a/mediagoblin/tools/text.py b/mediagoblin/tools/text.py
index de4bb281..d576224d 100644
--- a/mediagoblin/tools/text.py
+++ b/mediagoblin/tools/text.py
@@ -21,6 +21,7 @@ from lxml.html.clean import Cleaner
from mediagoblin import mg_globals
from mediagoblin.tools import url
+
# A super strict version of the lxml.html cleaner class
HTML_CLEANER = Cleaner(
scripts=True,
@@ -42,6 +43,8 @@ HTML_CLEANER = Cleaner(
host_whitelist=(),
whitelist_tags=set([]))
+TAGS_DELIMITER=',';
+
def clean_html(html):
# clean_html barfs on an empty string
if not html:
@@ -49,6 +52,7 @@ def clean_html(html):
return HTML_CLEANER.clean_html(html)
+
def convert_to_tag_list_of_dicts(tag_string):
"""
Filter input from incoming string containing user tags,
@@ -64,7 +68,7 @@ def convert_to_tag_list_of_dicts(tag_string):
# Split the tag string into a list of tags
for tag in stripped_tag_string.split(
- mg_globals.app_config['tags_delimiter']):
+ TAGS_DELIMITER):
# Ignore empty or duplicate tags
if tag.strip() and tag.strip() not in [t['name'] for t in taglist]:
@@ -73,6 +77,7 @@ def convert_to_tag_list_of_dicts(tag_string):
'slug': url.slugify(tag.strip())})
return taglist
+
def media_tags_as_string(media_entry_tags):
"""
Generate a string from a media item's tags, stored as a list of dicts
@@ -81,13 +86,15 @@ def media_tags_as_string(media_entry_tags):
"""
media_tag_string = ''
if media_entry_tags:
- media_tag_string = mg_globals.app_config['tags_delimiter'].join(
+ media_tag_string = (TAGS_DELIMITER+u' ').join(
[tag['name'] for tag in media_entry_tags])
return media_tag_string
+
TOO_LONG_TAG_WARNING = \
u'Tags must be shorter than %s characters. Tags that are too long: %s'
+
def tag_length_validator(form, field):
"""
Make sure tags do not exceed the maximum tag length.
@@ -105,6 +112,7 @@ def tag_length_validator(form, field):
MARKDOWN_INSTANCE = markdown.Markdown(safe_mode='escape')
+
def cleaned_markdown_conversion(text):
"""
Take a block of text, run it through MarkDown, and clean its HTML.
diff --git a/mediagoblin/tools/url.py b/mediagoblin/tools/url.py
index 458ef2c8..78b5dd63 100644
--- a/mediagoblin/tools/url.py
+++ b/mediagoblin/tools/url.py
@@ -17,8 +17,10 @@
import re
import translitcodec
+
_punct_re = re.compile(r'[\t !"#$%&\'()*\-/<=>?@\[\\\]^_`{|},.]+')
+
def slugify(text, delim=u'-'):
"""
Generates an ASCII-only slug. Taken from http://flask.pocoo.org/snippets/5/