aboutsummaryrefslogtreecommitdiffstats
path: root/mediagoblin
diff options
context:
space:
mode:
Diffstat (limited to 'mediagoblin')
-rw-r--r--mediagoblin/app.py3
-rw-r--r--mediagoblin/config_spec.ini8
-rw-r--r--mediagoblin/db/migration_tools.py19
-rw-r--r--mediagoblin/db/models.py15
-rw-r--r--mediagoblin/gmg_commands/dbupdate.py27
-rw-r--r--mediagoblin/media_types/audio/__init__.py3
-rw-r--r--mediagoblin/media_types/video/processing.py110
-rw-r--r--mediagoblin/notifications/__init__.py2
-rw-r--r--mediagoblin/static/images/home_goblin.pngbin0 -> 61657 bytes
-rw-r--r--mediagoblin/static/js/comment_show.js13
-rw-r--r--mediagoblin/templates/mediagoblin/base.html10
-rw-r--r--mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html4
-rw-r--r--mediagoblin/templates/mediagoblin/fragments/header_notifications.html2
-rw-r--r--mediagoblin/templates/mediagoblin/user_pages/media.html6
-rw-r--r--mediagoblin/templates/mediagoblin/utils/comment-subscription.html3
-rw-r--r--mediagoblin/tests/test_sql_migrations.py42
-rw-r--r--mediagoblin/tools/session.py2
-rw-r--r--mediagoblin/tools/template.py19
-rw-r--r--mediagoblin/user_pages/forms.py4
-rw-r--r--mediagoblin/user_pages/routing.py4
-rw-r--r--mediagoblin/user_pages/views.py17
21 files changed, 219 insertions, 94 deletions
diff --git a/mediagoblin/app.py b/mediagoblin/app.py
index 57e09e49..e9177eff 100644
--- a/mediagoblin/app.py
+++ b/mediagoblin/app.py
@@ -39,7 +39,6 @@ from mediagoblin.init import (get_jinja_loader, get_staticdirector,
from mediagoblin.tools.pluginapi import PluginManager, hook_transform
from mediagoblin.tools.crypto import setup_crypto
from mediagoblin.auth.tools import check_auth_enabled, no_auth_logout
-from mediagoblin import notifications
_log = logging.getLogger(__name__)
@@ -199,8 +198,6 @@ class MediaGoblinApp(object):
# Log user out if authentication_disabled
no_auth_logout(request)
- request.notifications = notifications
-
mg_request.setup_user_in_request(request)
request.controller_name = None
diff --git a/mediagoblin/config_spec.ini b/mediagoblin/config_spec.ini
index d2ada163..81dadd25 100644
--- a/mediagoblin/config_spec.ini
+++ b/mediagoblin/config_spec.ini
@@ -75,6 +75,12 @@ theme = string()
plugin_web_path = string(default="/plugin_static/")
plugin_linked_assets_dir = string(default="%(here)s/user_dev/plugin_static/")
+[jinja2]
+# Jinja2 supports more directives than the minimum required by mediagoblin.
+# This setting allows users creating custom templates to specify a list of
+# additional extensions they want to use. example value:
+# extensions = jinja2.ext.loopcontrols , jinja2.ext.with_
+extensions = string_list(default=list())
[storage:publicstore]
storage_class = string(default="mediagoblin.storage.filestorage:BasicFileStorage")
@@ -116,7 +122,7 @@ vp8_quality = integer(default=8)
vorbis_quality = float(default=0.3)
# Autoplay the video when page is loaded?
-auto_play = boolean(default=True)
+auto_play = boolean(default=False)
[[skip_transcode]]
mime_types = string_list(default=list("video/webm"))
diff --git a/mediagoblin/db/migration_tools.py b/mediagoblin/db/migration_tools.py
index aa22ef94..e75f3757 100644
--- a/mediagoblin/db/migration_tools.py
+++ b/mediagoblin/db/migration_tools.py
@@ -29,7 +29,7 @@ class MigrationManager(object):
to the latest migrations, etc.
"""
- def __init__(self, name, models, migration_registry, session,
+ def __init__(self, name, models, foundations, migration_registry, session,
printer=simple_printer):
"""
Args:
@@ -40,6 +40,7 @@ class MigrationManager(object):
"""
self.name = unicode(name)
self.models = models
+ self.foundations = foundations
self.session = session
self.migration_registry = migration_registry
self._sorted_migrations = None
@@ -140,6 +141,18 @@ class MigrationManager(object):
self.session.bind,
tables=[model.__table__ for model in self.models])
+ def populate_table_foundations(self):
+ """
+ Create the table foundations (default rows) as layed out in FOUNDATIONS
+ in mediagoblin.db.models
+ """
+ for Model, rows in self.foundations.items():
+ self.printer(u' + Laying foundations for %s table\n' %
+ (Model.__name__))
+ for parameters in rows:
+ new_row = Model(**parameters)
+ self.session.add(new_row)
+
def create_new_migration_record(self):
"""
Create a new migration record for this migration set
@@ -202,9 +215,9 @@ class MigrationManager(object):
self.init_tables()
# auto-set at latest migration number
- self.create_new_migration_record()
-
+ self.create_new_migration_record()
self.printer(u"done.\n")
+ self.populate_table_foundations()
self.set_current_migration()
return u'inited'
diff --git a/mediagoblin/db/models.py b/mediagoblin/db/models.py
index 74dea44e..f0cbce2a 100644
--- a/mediagoblin/db/models.py
+++ b/mediagoblin/db/models.py
@@ -651,6 +651,21 @@ MODELS = [
MediaAttachmentFile, ProcessingMetaData, Notification, CommentNotification,
ProcessingNotification, CommentSubscription]
+"""
+ Foundations are the default rows that are created immediately after the tables
+ are initialized. Each entry to this dictionary should be in the format of:
+ ModelConstructorObject:List of Dictionaries
+ (Each Dictionary represents a row on the Table to be created, containing each
+ of the columns' names as a key string, and each of the columns' values as a
+ value)
+
+ ex. [NOTE THIS IS NOT BASED OFF OF OUR USER TABLE]
+ user_foundations = [{'name':u'Joanna', 'age':24},
+ {'name':u'Andrea', 'age':41}]
+
+ FOUNDATIONS = {User:user_foundations}
+"""
+FOUNDATIONS = {}
######################################################
# Special, migrations-tracking table
diff --git a/mediagoblin/gmg_commands/dbupdate.py b/mediagoblin/gmg_commands/dbupdate.py
index 00007567..961752f6 100644
--- a/mediagoblin/gmg_commands/dbupdate.py
+++ b/mediagoblin/gmg_commands/dbupdate.py
@@ -32,14 +32,15 @@ def dbupdate_parse_setup(subparser):
class DatabaseData(object):
- def __init__(self, name, models, migrations):
+ def __init__(self, name, models, foundations, migrations):
self.name = name
self.models = models
+ self.foundations = foundations
self.migrations = migrations
def make_migration_manager(self, session):
return MigrationManager(
- self.name, self.models, self.migrations, session)
+ self.name, self.models, self.foundations, self.migrations, session)
def gather_database_data(plugins):
@@ -54,10 +55,11 @@ def gather_database_data(plugins):
# Add main first
from mediagoblin.db.models import MODELS as MAIN_MODELS
from mediagoblin.db.migrations import MIGRATIONS as MAIN_MIGRATIONS
+ from mediagoblin.db.models import FOUNDATIONS as MAIN_FOUNDATIONS
managed_dbdata.append(
DatabaseData(
- u'__main__', MAIN_MODELS, MAIN_MIGRATIONS))
+ u'__main__', MAIN_MODELS, MAIN_FOUNDATIONS, MAIN_MIGRATIONS))
for plugin in plugins:
try:
@@ -83,13 +85,26 @@ forgotten to add it? ({1})'.format(plugin, exc))
migrations = {}
except AttributeError as exc:
- _log.debug('Cloud not find MIGRATIONS in {0}.migrations, have you \
+ _log.debug('Could not find MIGRATIONS in {0}.migrations, have you \
forgotten to add it? ({1})'.format(plugin, exc))
migrations = {}
+ try:
+ foundations = import_component('{0}.models:FOUNDATIONS'.format(plugin))
+ except ImportError as exc:
+ _log.debug('No foundations found for {0}: {1}'.format(
+ plugin,
+ exc))
+
+ foundations = {}
+ except AttributeError as exc:
+ _log.debug('Could not find FOUNDATIONS in {0}.models, have you \
+forgotten to add it? ({1})'.format(plugin, exc))
+ foundations = {}
+
if models:
managed_dbdata.append(
- DatabaseData(plugin, models, migrations))
+ DatabaseData(plugin, models, foundations, migrations))
return managed_dbdata
@@ -111,7 +126,7 @@ def run_dbupdate(app_config, global_config):
def run_all_migrations(db, app_config, global_config):
"""
- Initializes or migrates a database that already has a
+ Initializes or migrates a database that already has a
connection setup and also initializes or migrates all
extensions based on the config files.
diff --git a/mediagoblin/media_types/audio/__init__.py b/mediagoblin/media_types/audio/__init__.py
index 90f842ba..c7ed8d2d 100644
--- a/mediagoblin/media_types/audio/__init__.py
+++ b/mediagoblin/media_types/audio/__init__.py
@@ -19,6 +19,9 @@ from mediagoblin.media_types.audio.processing import process_audio, \
sniff_handler
from mediagoblin.tools import pluginapi
+# Why isn't .ogg in this list? It's still detected, but via sniffing,
+# .ogg files could be either video or audio... sniffing determines which.
+
ACCEPTED_EXTENSIONS = ["mp3", "flac", "wav", "m4a"]
MEDIA_TYPE = 'mediagoblin.media_types.audio'
diff --git a/mediagoblin/media_types/video/processing.py b/mediagoblin/media_types/video/processing.py
index 5386ba60..857c1647 100644
--- a/mediagoblin/media_types/video/processing.py
+++ b/mediagoblin/media_types/video/processing.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 tempfile import NamedTemporaryFile
+import os.path
import logging
import datetime
@@ -73,79 +73,77 @@ def process_video(proc_state):
queued_filename = proc_state.get_queued_filename()
name_builder = FilenameBuilder(queued_filename)
- medium_filepath = create_pub_filepath(
- entry, name_builder.fill('{basename}-640p.webm'))
+ medium_basename = name_builder.fill('{basename}-640p.webm')
+ medium_filepath = create_pub_filepath(entry, medium_basename)
- thumbnail_filepath = create_pub_filepath(
- entry, name_builder.fill('{basename}.thumbnail.jpg'))
+ thumbnail_basename = name_builder.fill('{basename}.thumbnail.jpg')
+ thumbnail_filepath = create_pub_filepath(entry, thumbnail_basename)
# Create a temporary file for the video destination (cleaned up with workbench)
- tmp_dst = NamedTemporaryFile(dir=workbench.dir, delete=False)
- with tmp_dst:
- # Transcode queued file to a VP8/vorbis file that fits in a 640x640 square
- progress_callback = ProgressCallback(entry)
+ tmp_dst = os.path.join(workbench.dir, medium_basename)
+ # Transcode queued file to a VP8/vorbis file that fits in a 640x640 square
+ progress_callback = ProgressCallback(entry)
- dimensions = (
- mgg.global_config['media:medium']['max_width'],
- mgg.global_config['media:medium']['max_height'])
+ dimensions = (
+ mgg.global_config['media:medium']['max_width'],
+ mgg.global_config['media:medium']['max_height'])
- # Extract metadata and keep a record of it
- metadata = transcoders.VideoTranscoder().discover(queued_filename)
- store_metadata(entry, metadata)
+ # Extract metadata and keep a record of it
+ metadata = transcoders.VideoTranscoder().discover(queued_filename)
+ store_metadata(entry, metadata)
- # Figure out whether or not we need to transcode this video or
- # if we can skip it
- if skip_transcode(metadata):
- _log.debug('Skipping transcoding')
+ # Figure out whether or not we need to transcode this video or
+ # if we can skip it
+ if skip_transcode(metadata):
+ _log.debug('Skipping transcoding')
- dst_dimensions = metadata['videowidth'], metadata['videoheight']
+ dst_dimensions = metadata['videowidth'], metadata['videoheight']
# Push original file to public storage
- _log.debug('Saving original...')
- proc_state.copy_original(queued_filepath[-1])
+ _log.debug('Saving original...')
+ proc_state.copy_original(queued_filepath[-1])
- did_transcode = False
- else:
- transcoder = transcoders.VideoTranscoder()
+ did_transcode = False
+ else:
+ transcoder = transcoders.VideoTranscoder()
- transcoder.transcode(queued_filename, tmp_dst.name,
- vp8_quality=video_config['vp8_quality'],
- vp8_threads=video_config['vp8_threads'],
- vorbis_quality=video_config['vorbis_quality'],
- progress_callback=progress_callback,
- dimensions=dimensions)
+ transcoder.transcode(queued_filename, tmp_dst,
+ vp8_quality=video_config['vp8_quality'],
+ vp8_threads=video_config['vp8_threads'],
+ vorbis_quality=video_config['vorbis_quality'],
+ progress_callback=progress_callback,
+ dimensions=dimensions)
- dst_dimensions = transcoder.dst_data.videowidth,\
- transcoder.dst_data.videoheight
+ dst_dimensions = transcoder.dst_data.videowidth,\
+ transcoder.dst_data.videoheight
- # Push transcoded video to public storage
- _log.debug('Saving medium...')
- mgg.public_store.copy_local_to_storage(tmp_dst.name, medium_filepath)
- _log.debug('Saved medium')
+ # Push transcoded video to public storage
+ _log.debug('Saving medium...')
+ mgg.public_store.copy_local_to_storage(tmp_dst, medium_filepath)
+ _log.debug('Saved medium')
- entry.media_files['webm_640'] = medium_filepath
+ entry.media_files['webm_640'] = medium_filepath
- did_transcode = True
+ did_transcode = True
- # Save the width and height of the transcoded video
- entry.media_data_init(
- width=dst_dimensions[0],
- height=dst_dimensions[1])
+ # Save the width and height of the transcoded video
+ entry.media_data_init(
+ width=dst_dimensions[0],
+ height=dst_dimensions[1])
# Temporary file for the video thumbnail (cleaned up with workbench)
- tmp_thumb = NamedTemporaryFile(dir=workbench.dir, suffix='.jpg', delete=False)
-
- with tmp_thumb:
- # Create a thumbnail.jpg that fits in a 180x180 square
- transcoders.VideoThumbnailerMarkII(
- queued_filename,
- tmp_thumb.name,
- 180)
-
- # Push the thumbnail to public storage
- _log.debug('Saving thumbnail...')
- mgg.public_store.copy_local_to_storage(tmp_thumb.name, thumbnail_filepath)
- entry.media_files['thumb'] = thumbnail_filepath
+ tmp_thumb = os.path.join(workbench.dir, thumbnail_basename)
+
+ # Create a thumbnail.jpg that fits in a 180x180 square
+ transcoders.VideoThumbnailerMarkII(
+ queued_filename,
+ tmp_thumb,
+ 180)
+
+ # Push the thumbnail to public storage
+ _log.debug('Saving thumbnail...')
+ mgg.public_store.copy_local_to_storage(tmp_thumb, thumbnail_filepath)
+ entry.media_files['thumb'] = thumbnail_filepath
# save the original... but only if we did a transcoding
# (if we skipped transcoding and just kept the original anyway as the main
diff --git a/mediagoblin/notifications/__init__.py b/mediagoblin/notifications/__init__.py
index 4b7fbb8c..ed9f8d78 100644
--- a/mediagoblin/notifications/__init__.py
+++ b/mediagoblin/notifications/__init__.py
@@ -18,7 +18,6 @@ import logging
from mediagoblin.db.models import Notification, \
CommentNotification, CommentSubscription
-from mediagoblin.notifications.task import email_notification_task
from mediagoblin.notifications.tools import generate_comment_message
_log = logging.getLogger(__name__)
@@ -50,6 +49,7 @@ def trigger_notification(comment, media_entry, request):
media_entry,
request)
+ from mediagoblin.notifications.task import email_notification_task
email_notification_task.apply_async([cn.id, message])
diff --git a/mediagoblin/static/images/home_goblin.png b/mediagoblin/static/images/home_goblin.png
new file mode 100644
index 00000000..5ba9afeb
--- /dev/null
+++ b/mediagoblin/static/images/home_goblin.png
Binary files differ
diff --git a/mediagoblin/static/js/comment_show.js b/mediagoblin/static/js/comment_show.js
index c5ccee66..df3c1093 100644
--- a/mediagoblin/static/js/comment_show.js
+++ b/mediagoblin/static/js/comment_show.js
@@ -15,12 +15,25 @@
* 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/>.
*/
+var content="";
+function previewComment(){
+ if ($('#comment_content').val() && (content != $('#comment_content').val())) {
+ content = $('#comment_content').val();
+ $.post($('#previewURL').val(),$('#form_comment').serialize(),
+ function(data){
+ preview = JSON.parse(data)
+ $('#comment_preview').replaceWith("<div id=comment_preview><h3>" + $('#previewText').val() +"</h3><br />" + preview.content +
+ "<hr style='border: 1px solid #333;' /></div>");
+ });
+ }
+}
$(document).ready(function(){
$('#form_comment').hide();
$('#button_addcomment').click(function(){
$(this).fadeOut('fast');
$('#form_comment').slideDown(function(){
+ setInterval("previewComment()",1000);
$('#comment_content').focus();
});
});
diff --git a/mediagoblin/templates/mediagoblin/base.html b/mediagoblin/templates/mediagoblin/base.html
index 1fc4467c..65dbebc0 100644
--- a/mediagoblin/templates/mediagoblin/base.html
+++ b/mediagoblin/templates/mediagoblin/base.html
@@ -60,13 +60,13 @@
{%- if request.user %}
{% if request.user and request.user.status == 'active' %}
- {% set notification_count = request.notifications.get_notification_count(request.user.id) %}
+ {% set notification_count = get_notification_count(request.user.id) %}
{% if notification_count %}
- <a href="#notifications" class="notification-gem button_action" title="Notifications">
- {{ notification_count }}</a>
+ <a href="#notifications" class="notification-gem button_action" title="Notifications">
+ {{ notification_count }}</a>
{% endif %}
- <div class="button_action header_dropdown_down">&#9660;</div>
- <div class="button_action header_dropdown_up">&#9650;</div>
+ <a href="#header" class="button_action header_dropdown_down">&#9660;</a>
+ <a href="#no_header" class="button_action header_dropdown_up">&#9650;</a>
{% elif request.user and request.user.status == "needs_email_verification" %}
{# the following link should only appear when verification is needed #}
<a href="{{ request.urlgen('mediagoblin.user_pages.user_home',
diff --git a/mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html b/mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html
index 9ef28a4d..e2463328 100644
--- a/mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html
+++ b/mediagoblin/templates/mediagoblin/bits/frontpage_welcome.html
@@ -19,8 +19,8 @@
{% if request.user %}
<h1>{% trans %}Explore{% endtrans %}</h1>
{% else %}
+ <img class="right_align" src="{{ request.staticdirect('/images/home_goblin.png') }}" />
<h1>{% trans %}Hi there, welcome to this MediaGoblin site!{% endtrans %}</h1>
- <img class="right_align" src="{{ request.staticdirect('/images/frontpage_image.png') }}" />
<p>{% trans %}This site is running <a href="http://mediagoblin.org">MediaGoblin</a>, an extraordinarily great piece of media hosting software.{% endtrans %}</p>
{% if auth %}
<p>{% trans %}To add your own media, place comments, and more, you can log in with your MediaGoblin account.{% endtrans %}</p>
@@ -33,7 +33,7 @@
{% endif %}
{% endif %}
{% trans %}
- <a class="button_action" href="http://wiki.mediagoblin.org/HackingHowto">Set up MediaGoblin on your own server</a>
+ <a class="button_action" href="http://mediagoblin.readthedocs.org/">Set up MediaGoblin on your own server</a>
{%- endtrans %}
<div class="clear"></div>
diff --git a/mediagoblin/templates/mediagoblin/fragments/header_notifications.html b/mediagoblin/templates/mediagoblin/fragments/header_notifications.html
index 613100aa..70d7935a 100644
--- a/mediagoblin/templates/mediagoblin/fragments/header_notifications.html
+++ b/mediagoblin/templates/mediagoblin/fragments/header_notifications.html
@@ -1,4 +1,4 @@
-{% set notifications = request.notifications.get_notifications(request.user.id) %}
+{% set notifications = get_notifications(request.user.id) %}
{% if notifications %}
<div class="header_notifications">
<h3>{% trans %}New comments{% endtrans %}</h3>
diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html
index c16e4c78..39935b40 100644
--- a/mediagoblin/templates/mediagoblin/user_pages/media.html
+++ b/mediagoblin/templates/mediagoblin/user_pages/media.html
@@ -90,7 +90,8 @@
{% if app_config['allow_comments'] %}
<a
{% if not request.user %}
- href="{{ request.urlgen('mediagoblin.auth.login') }}"
+ href="{{ request.urlgen('mediagoblin.auth.login') }}?next={{
+ request.base_url|urlencode }}"
{% endif %}
class="button_action" id="button_addcomment" title="Add a comment">
{% trans %}Add a comment{% endtrans %}
@@ -107,7 +108,10 @@
<input type="submit" value="{% trans %}Add this comment{% endtrans %}" class="button_action" />
{{ csrf_token }}
</div>
+ <input type="hidden" value="{{ request.urlgen('mediagoblin.user_pages.media_preview_comment') }}" id="previewURL" />
+ <input type="hidden" value="{% trans %}Comment Preview{% endtrans %}" id="previewText"/>
</form>
+ <div id="comment_preview"></div>
{% endif %}
<ul style="list-style:none">
{% for comment in comments %}
diff --git a/mediagoblin/templates/mediagoblin/utils/comment-subscription.html b/mediagoblin/templates/mediagoblin/utils/comment-subscription.html
index bd367e80..75da5e89 100644
--- a/mediagoblin/templates/mediagoblin/utils/comment-subscription.html
+++ b/mediagoblin/templates/mediagoblin/utils/comment-subscription.html
@@ -16,8 +16,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#}
{%- if request.user %}
- {% set subscription = request.notifications.get_comment_subscription(
- request.user.id, media.id) %}
+ {% set subscription = get_comment_subscription(request.user.id, media.id) %}
{% if not subscription or not subscription.notify %}
<a type="submit" href="{{ request.urlgen('mediagoblin.notifications.subscribe_comments',
user=media.get_uploader.username,
diff --git a/mediagoblin/tests/test_sql_migrations.py b/mediagoblin/tests/test_sql_migrations.py
index 2fc4c043..3d67fdf6 100644
--- a/mediagoblin/tests/test_sql_migrations.py
+++ b/mediagoblin/tests/test_sql_migrations.py
@@ -58,6 +58,10 @@ class Level1(Base1):
SET1_MODELS = [Creature1, Level1]
+FOUNDATIONS = {Creature1:[{'name':u'goblin','num_legs':2,'is_demon':False},
+ {'name':u'cerberus','num_legs':4,'is_demon':True}]
+ }
+
SET1_MIGRATIONS = {}
#######################################################
@@ -542,7 +546,6 @@ def _insert_migration3_objects(session):
session.commit()
-
def create_test_engine():
from sqlalchemy import create_engine
engine = create_engine('sqlite:///:memory:', echo=False)
@@ -572,7 +575,7 @@ def test_set1_to_set3():
printer = CollectingPrinter()
migration_manager = MigrationManager(
- u'__main__', SET1_MODELS, SET1_MIGRATIONS, Session(),
+ u'__main__', SET1_MODELS, FOUNDATIONS, SET1_MIGRATIONS, Session(),
printer)
# Check latest migration and database current migration
@@ -585,11 +588,13 @@ def test_set1_to_set3():
assert result == u'inited'
# Check output
assert printer.combined_string == (
- "-> Initializing main mediagoblin tables... done.\n")
+ "-> Initializing main mediagoblin tables... done.\n" + \
+ " + Laying foundations for Creature1 table\n" )
# Check version in database
assert migration_manager.latest_migration == 0
assert migration_manager.database_current_migration == 0
+
# Install the initial set
# -----------------------
@@ -597,8 +602,8 @@ def test_set1_to_set3():
# Try to "re-migrate" with same manager settings... nothing should happen
migration_manager = MigrationManager(
- u'__main__', SET1_MODELS, SET1_MIGRATIONS, Session(),
- printer)
+ u'__main__', SET1_MODELS, FOUNDATIONS, SET1_MIGRATIONS,
+ Session(), printer)
assert migration_manager.init_or_migrate() == None
# Check version in database
@@ -639,6 +644,20 @@ def test_set1_to_set3():
# Now check to see if stuff seems to be in there.
session = Session()
+ # Check the creation of the foundation rows on the creature table
+ creature = session.query(Creature1).filter_by(
+ name=u'goblin').one()
+ assert creature.num_legs == 2
+ assert creature.is_demon == False
+
+ creature = session.query(Creature1).filter_by(
+ name=u'cerberus').one()
+ assert creature.num_legs == 4
+ assert creature.is_demon == True
+
+
+ # Check the creation of the inserted rows on the creature and levels tables
+
creature = session.query(Creature1).filter_by(
name=u'centipede').one()
assert creature.num_legs == 100
@@ -679,7 +698,7 @@ def test_set1_to_set3():
# isn't said to be updated yet
printer = CollectingPrinter()
migration_manager = MigrationManager(
- u'__main__', SET3_MODELS, SET3_MIGRATIONS, Session(),
+ u'__main__', SET3_MODELS, FOUNDATIONS, SET3_MIGRATIONS, Session(),
printer)
assert migration_manager.latest_migration == 8
@@ -706,7 +725,7 @@ def test_set1_to_set3():
# Make sure version matches expected
migration_manager = MigrationManager(
- u'__main__', SET3_MODELS, SET3_MIGRATIONS, Session(),
+ u'__main__', SET3_MODELS, FOUNDATIONS, SET3_MIGRATIONS, Session(),
printer)
assert migration_manager.latest_migration == 8
assert migration_manager.database_current_migration == 8
@@ -772,6 +791,15 @@ def test_set1_to_set3():
# Now check to see if stuff seems to be in there.
session = Session()
+
+
+ # Start with making sure that the foundations did not run again
+ assert session.query(Creature3).filter_by(
+ name=u'goblin').count() == 1
+ assert session.query(Creature3).filter_by(
+ name=u'cerberus').count() == 1
+
+ # Then make sure the models have been migrated correctly
creature = session.query(Creature3).filter_by(
name=u'centipede').one()
assert creature.num_limbs == 100.0
diff --git a/mediagoblin/tools/session.py b/mediagoblin/tools/session.py
index d79afb66..a57f69cc 100644
--- a/mediagoblin/tools/session.py
+++ b/mediagoblin/tools/session.py
@@ -17,7 +17,7 @@
import itsdangerous
import logging
-import crypto
+from mediagoblin.tools import crypto
_log = logging.getLogger(__name__)
diff --git a/mediagoblin/tools/template.py b/mediagoblin/tools/template.py
index 615ce129..fa290611 100644
--- a/mediagoblin/tools/template.py
+++ b/mediagoblin/tools/template.py
@@ -32,7 +32,6 @@ from mediagoblin.tools.timesince import timesince
from mediagoblin.meddleware.csrf import render_csrf_form_token
-
SETUP_JINJA_ENVS = {}
@@ -50,6 +49,12 @@ def get_jinja_env(template_loader, locale):
if locale in SETUP_JINJA_ENVS:
return SETUP_JINJA_ENVS[locale]
+ # The default config does not require a [jinja2] block.
+ # You may create one if you wish to enable additional jinja2 extensions,
+ # see example in config_spec.ini
+ jinja2_config = mg_globals.global_config.get('jinja2', {})
+ local_exts = jinja2_config.get('extensions', [])
+
# jinja2.StrictUndefined will give exceptions on references
# to undefined/unknown variables in templates.
template_env = jinja2.Environment(
@@ -57,7 +62,7 @@ def get_jinja_env(template_loader, locale):
undefined=jinja2.StrictUndefined,
extensions=[
'jinja2.ext.i18n', 'jinja2.ext.autoescape',
- TemplateHookExtension])
+ TemplateHookExtension] + local_exts)
template_env.install_gettext_callables(
mg_globals.thread_scope.translations.ugettext,
@@ -84,6 +89,16 @@ def get_jinja_env(template_loader, locale):
template_env.globals = hook_transform(
'template_global_context', template_env.globals)
+ #### THIS IS TEMPORARY, PLEASE FIX IT
+ ## Notifications stuff is not yet a plugin (and we're not sure it will be),
+ ## but it needs to add stuff to the context. This is THE WRONG WAY TO DO IT
+ from mediagoblin import notifications
+ template_env.globals['get_notifications'] = notifications.get_notifications
+ template_env.globals[
+ 'get_notification_count'] = notifications.get_notification_count
+ template_env.globals[
+ 'get_comment_subscription'] = notifications.get_comment_subscription
+
if exists(locale):
SETUP_JINJA_ENVS[locale] = template_env
diff --git a/mediagoblin/user_pages/forms.py b/mediagoblin/user_pages/forms.py
index 9a193680..ac8084c5 100644
--- a/mediagoblin/user_pages/forms.py
+++ b/mediagoblin/user_pages/forms.py
@@ -23,7 +23,7 @@ class MediaCommentForm(wtforms.Form):
_('Comment'),
[wtforms.validators.Required()],
description=_(u'You can use '
- u'<a href="http://daringfireball.net/projects/markdown/basics">'
+ u'<a href="http://daringfireball.net/projects/markdown/basics" target="_blank">'
u'Markdown</a> for formatting.'))
class ConfirmDeleteForm(wtforms.Form):
@@ -47,5 +47,5 @@ class MediaCollectForm(wtforms.Form):
collection_description = wtforms.TextAreaField(
_('Description of this collection'),
description=_("""You can use
- <a href="http://daringfireball.net/projects/markdown/basics">
+ <a href="http://daringfireball.net/projects/markdown/basics" target="_blank">
Markdown</a> for formatting."""))
diff --git a/mediagoblin/user_pages/routing.py b/mediagoblin/user_pages/routing.py
index 9cb665b5..b1dde397 100644
--- a/mediagoblin/user_pages/routing.py
+++ b/mediagoblin/user_pages/routing.py
@@ -32,6 +32,10 @@ add_route('mediagoblin.user_pages.media_post_comment',
'/u/<string:user>/m/<int:media_id>/comment/add/',
'mediagoblin.user_pages.views:media_post_comment')
+add_route('mediagoblin.user_pages.media_preview_comment',
+ '/ajax/comment/preview/',
+ 'mediagoblin.user_pages.views:media_preview_comment')
+
add_route('mediagoblin.user_pages.user_gallery',
'/u/<string:user>/gallery/',
'mediagoblin.user_pages.views:user_gallery')
diff --git a/mediagoblin/user_pages/views.py b/mediagoblin/user_pages/views.py
index 596d4c20..91ea04b8 100644
--- a/mediagoblin/user_pages/views.py
+++ b/mediagoblin/user_pages/views.py
@@ -16,19 +16,20 @@
import logging
import datetime
+import json
from mediagoblin import messages, mg_globals
from mediagoblin.db.models import (MediaEntry, MediaTag, Collection,
CollectionItem, User)
from mediagoblin.tools.response import render_to_response, render_404, \
redirect, redirect_obj
+from mediagoblin.tools.text import cleaned_markdown_conversion
from mediagoblin.tools.translate import pass_to_ugettext as _
from mediagoblin.tools.pagination import Pagination
from mediagoblin.user_pages import forms as user_forms
from mediagoblin.user_pages.lib import add_media_to_collection
from mediagoblin.notifications import trigger_notification, \
add_comment_subscription, mark_comment_notification_seen
-
from mediagoblin.decorators import (uses_pagination, get_user_media_entry,
get_media_entry_by_id,
require_active_login, user_may_delete_media, user_may_alter_collection,
@@ -36,6 +37,7 @@ from mediagoblin.decorators import (uses_pagination, get_user_media_entry,
from werkzeug.contrib.atom import AtomFeed
from werkzeug.exceptions import MethodNotAllowed
+from werkzeug.wrappers import Response
_log = logging.getLogger(__name__)
@@ -166,6 +168,7 @@ def media_post_comment(request, media):
comment = request.db.MediaComment()
comment.media_entry = media.id
comment.author = request.user.id
+ print request.form['comment_content']
comment.content = unicode(request.form['comment_content'])
# Show error message if commenting is disabled.
@@ -193,6 +196,18 @@ def media_post_comment(request, media):
return redirect_obj(request, media)
+
+def media_preview_comment(request):
+ """Runs a comment through markdown so it can be previewed."""
+ # If this isn't an ajax request, render_404
+ if not request.is_xhr:
+ return render_404(request)
+
+ comment = unicode(request.form['comment_content'])
+ cleancomment = { "content":cleaned_markdown_conversion(comment)}
+
+ return Response(json.dumps(cleancomment))
+
@get_media_entry_by_id
@require_active_login
def media_collect(request, media):