Merge remote-tracking branch 'origin/master' into is315

This commit is contained in:
cfdv
2011-06-20 12:50:44 -05:00
15 changed files with 160 additions and 34 deletions

View File

@@ -14,6 +14,8 @@
# 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.util import cleaned_markdown_conversion
from mongokit import DocumentMigration
@@ -33,5 +35,19 @@ class MediaEntryMigration(DocumentMigration):
self.collection.update(
self.target, self.update, multi=True, safe=True)
def allmigration02_add_description_html(self):
"""
Now that we can have rich descriptions via Markdown, we should
update all existing entries to record the rich description versions.
"""
self.target = {'description_html': {'$exists': False}}
if not self.status:
for doc in self.collection.find(self.target):
self.update = {
'$set': {
'description_html': cleaned_markdown_conversion(
doc['description'])}}
MIGRATE_CLASSES = ['MediaEntry']

View File

@@ -75,7 +75,8 @@ class MediaEntry(Document):
'title': unicode,
'slug': unicode,
'created': datetime.datetime,
'description': unicode,
'description': unicode, # May contain markdown/up
'description_html': unicode, # May contain plaintext, or HTML
'media_type': unicode,
'media_data': dict, # extra data relevant to this media_type
'plugin_data': dict, # plugins can dump stuff here.

View File

@@ -17,11 +17,13 @@
from webob import exc
from mediagoblin.util import render_to_response, redirect
from mediagoblin.util import render_to_response, redirect, clean_html
from mediagoblin.edit import forms
from mediagoblin.edit.lib import may_edit_media
from mediagoblin.decorators import require_active_login, get_user_media_entry
import markdown
@get_user_media_entry
@require_active_login
@@ -47,7 +49,14 @@ def edit_media(request, media):
u'An entry with that slug already exists for this user.')
else:
media['title'] = request.POST['title']
media['description'] = request.POST['description']
media['description'] = request.POST.get('description')
md = markdown.Markdown(
safe_mode = 'escape')
media['description_html'] = clean_html(
md.convert(
media['description']))
media['slug'] = request.POST['slug']
media.save()

View File

@@ -19,7 +19,8 @@ from cgi import FieldStorage
from werkzeug.utils import secure_filename
from mediagoblin.util import render_to_response, redirect
from mediagoblin.util import (
render_to_response, redirect, cleaned_markdown_conversion)
from mediagoblin.decorators import require_active_login
from mediagoblin.submit import forms as submit_forms, security
from mediagoblin.process_media import process_media_initial
@@ -46,8 +47,14 @@ def submit_start(request):
# create entry and save in database
entry = request.db.MediaEntry()
entry['title'] = request.POST['title'] or unicode(splitext(filename)[0])
entry['title'] = (
request.POST['title']
or unicode(splitext(filename)[0]))
entry['description'] = request.POST.get('description')
entry['description_html'] = cleaned_markdown_conversion(
entry['description'])
entry['media_type'] = u'image' # heh
entry['uploader'] = request.user['_id']

View File

@@ -25,7 +25,9 @@
</h1>
<img class="media_image" src="{{ request.app.public_store.file_url(
media.media_files.main) }}" />
<p>{{ media.description }}</p>
{% autoescape False %}
<p>{{ media.description_html }}</p>
{% endautoescape %}
<p>Uploaded on
{{ "%4d-%02d-%02d"|format(media.created.year,
media.created.month, media.created.day) }}

View File

@@ -242,17 +242,69 @@ def test_authentication_views(test_app):
test_user.save()
# Get login
# ---------
test_app.get('/auth/login/')
# Make sure it rendered with the appropriate template
assert util.TEMPLATE_TEST_CONTEXT.has_key(
'mediagoblin/auth/login.html')
# Log in as that user
# Failed login - blank form
# -------------------------
util.clear_test_template_context()
response = test_app.post('/auth/login/')
context = util.TEMPLATE_TEST_CONTEXT['mediagoblin/auth/login.html']
form = context['login_form']
assert form.username.errors == [u'This field is required.']
assert form.password.errors == [u'This field is required.']
# Failed login - blank user
# -------------------------
util.clear_test_template_context()
response = test_app.post(
'/auth/login/', {
'password': u'toast'})
context = util.TEMPLATE_TEST_CONTEXT['mediagoblin/auth/login.html']
form = context['login_form']
assert form.username.errors == [u'This field is required.']
# Failed login - blank password
# -----------------------------
util.clear_test_template_context()
response = test_app.post(
'/auth/login/', {
'username': u'chris'})
context = util.TEMPLATE_TEST_CONTEXT['mediagoblin/auth/login.html']
form = context['login_form']
assert form.password.errors == [u'This field is required.']
# Failed login - bad user
# -----------------------
util.clear_test_template_context()
response = test_app.post(
'/auth/login/', {
'username': u'steve',
'password': 'toast'})
context = util.TEMPLATE_TEST_CONTEXT['mediagoblin/auth/login.html']
assert context['login_failed']
# Failed login - bad password
# ---------------------------
util.clear_test_template_context()
response = test_app.post(
'/auth/login/', {
'username': u'chris',
'password': 'jam'})
context = util.TEMPLATE_TEST_CONTEXT['mediagoblin/auth/login.html']
assert context['login_failed']
# Successful login
# ----------------
util.clear_test_template_context()
response = test_app.post(
'/auth/login/', {
'username': u'chris',
'password': 'toast'})
# User should be redirected
response.follow()
assert_equal(
urlparse.urlsplit(response.location)[2],
@@ -260,10 +312,38 @@ def test_authentication_views(test_app):
assert util.TEMPLATE_TEST_CONTEXT.has_key(
'mediagoblin/root.html')
# Make sure we're in the session or something
session = util.TEMPLATE_TEST_CONTEXT['mediagoblin/root.html']['request'].session
# Make sure user is in the session
context = util.TEMPLATE_TEST_CONTEXT['mediagoblin/root.html']
session = context['request'].session
assert session['user_id'] == unicode(test_user['_id'])
# Log out as that user
# Make sure we're not in the session
# Successful logout
# -----------------
util.clear_test_template_context()
response = test_app.get('/auth/logout/')
# Should be redirected to index page
response.follow()
assert_equal(
urlparse.urlsplit(response.location)[2],
'/')
assert util.TEMPLATE_TEST_CONTEXT.has_key(
'mediagoblin/root.html')
# Make sure the user is not in the session
context = util.TEMPLATE_TEST_CONTEXT['mediagoblin/root.html']
session = context['request'].session
assert session.has_key('user_id') == False
# User is redirected to custom URL if POST['next'] is set
# -------------------------------------------------------
util.clear_test_template_context()
response = test_app.post(
'/auth/login/', {
'username': u'chris',
'password': 'toast',
'next' : '/u/chris/'})
assert_equal(
urlparse.urlsplit(response.location)[2],
'/u/chris/')

View File

@@ -30,7 +30,7 @@ from mediagoblin.db.open import setup_connection_and_db_from_config
MEDIAGOBLIN_TEST_DB_NAME = '__mediagoblinunittests__'
TEST_SERVER_CONFIG = pkg_resources.resource_filename(
'mediagoblin.tests', 'test_server.ini')
'mediagoblin.tests', 'test_paste.ini')
TEST_APP_CONFIG = pkg_resources.resource_filename(
'mediagoblin.tests', 'test_mgoblin_app.ini')
TEST_USER_DEV = pkg_resources.resource_filename(

View File

@@ -108,10 +108,10 @@ def atom_feed(request):
feed = AtomFeed(request.matchdict['user'],
feed_url=request.url,
url=request.host_url)
for entry in cursor:
feed.add(entry.get('title'),
entry.get('description'),
entry.get('description_html'),
content_type='html',
author=request.matchdict['user'],
updated=entry.get('created'),

View File

@@ -29,11 +29,11 @@ import jinja2
import translitcodec
from webob import Response, exc
from lxml.html.clean import Cleaner
import markdown
from mediagoblin import mg_globals
from mediagoblin.db.util import ObjectId
TESTS_ENABLED = False
def _activate_testing():
"""
@@ -98,7 +98,7 @@ def get_jinja_env(template_loader, locale):
template_env = jinja2.Environment(
loader=template_loader, autoescape=True,
extensions=['jinja2.ext.i18n'])
extensions=['jinja2.ext.i18n', 'jinja2.ext.autoescape'])
template_env.install_gettext_callables(
mg_globals.translations.gettext,
@@ -376,6 +376,16 @@ def clean_html(html):
return HTML_CLEANER.clean_html(html)
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.
"""
return clean_html(MARKDOWN_INSTANCE.convert(text))
SETUP_GETTEXTS = {}
def setup_gettext(locale):