Merge branch 'master' of git://gitorious.org/mediagoblin/mediagoblin

This commit is contained in:
Aditi
2013-08-09 16:38:55 +05:30
18 changed files with 1725 additions and 64 deletions

View File

@@ -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"))

View File

@@ -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)
tmp_thumb = os.path.join(workbench.dir, thumbnail_basename)
with tmp_thumb:
# Create a thumbnail.jpg that fits in a 180x180 square
transcoders.VideoThumbnailerMarkII(
queued_filename,
tmp_thumb.name,
180)
# 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.name, thumbnail_filepath)
entry.media_files['thumb'] = thumbnail_filepath
# 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

View File

@@ -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();
});
});

View File

@@ -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>

View File

@@ -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 %}

View File

@@ -50,6 +50,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 +63,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,

View File

@@ -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."""))

View File

@@ -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')

View File

@@ -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):