Subtitle built over attachments : working
This commit is contained in:
parent
74bc86732e
commit
19ba17d950
@ -81,7 +81,8 @@ celery_setup_elsewhere = boolean(default=False)
|
|||||||
# Whether or not users are able to upload files of any filetype with
|
# Whether or not users are able to upload files of any filetype with
|
||||||
# their media entries -- This is useful if you want to provide the
|
# their media entries -- This is useful if you want to provide the
|
||||||
# source files for a media file but can also be a HUGE security risk.
|
# source files for a media file but can also be a HUGE security risk.
|
||||||
allow_attachments = boolean(default=True)
|
allow_attachments = boolean(default=False)
|
||||||
|
allow_subtitles = boolean(default=True)
|
||||||
|
|
||||||
# Cookie stuff
|
# Cookie stuff
|
||||||
csrf_cookie_name = string(default='mediagoblin_csrftoken')
|
csrf_cookie_name = string(default='mediagoblin_csrftoken')
|
||||||
|
@ -573,6 +573,15 @@ class MediaEntry(Base, MediaEntryMixin, CommentingMixin):
|
|||||||
name=v["name"], filepath=v["filepath"])
|
name=v["name"], filepath=v["filepath"])
|
||||||
)
|
)
|
||||||
|
|
||||||
|
subtitle_files_helper = relationship("MediaSubtitleFile",
|
||||||
|
cascade="all, delete-orphan",
|
||||||
|
order_by="MediaSubtitleFile.created"
|
||||||
|
)
|
||||||
|
subtitle_files = association_proxy("subtitle_files_helper", "dict_view",
|
||||||
|
creator=lambda v: MediaSubtitleFile(
|
||||||
|
name=v["name"], filepath=v["filepath"])
|
||||||
|
)
|
||||||
|
|
||||||
tags_helper = relationship("MediaTag",
|
tags_helper = relationship("MediaTag",
|
||||||
cascade="all, delete-orphan" # should be automatically deleted
|
cascade="all, delete-orphan" # should be automatically deleted
|
||||||
)
|
)
|
||||||
@ -888,6 +897,22 @@ class MediaAttachmentFile(Base):
|
|||||||
"""A dict like view on this object"""
|
"""A dict like view on this object"""
|
||||||
return DictReadAttrProxy(self)
|
return DictReadAttrProxy(self)
|
||||||
|
|
||||||
|
class MediaSubtitleFile(Base):
|
||||||
|
__tablename__ = "core__subtitle_files"
|
||||||
|
|
||||||
|
id = Column(Integer, primary_key=True)
|
||||||
|
media_entry = Column(
|
||||||
|
Integer, ForeignKey(MediaEntry.id),
|
||||||
|
nullable=False)
|
||||||
|
name = Column(Unicode, nullable=False)
|
||||||
|
filepath = Column(PathTupleWithSlashes)
|
||||||
|
created = Column(DateTime, nullable=False, default=datetime.datetime.utcnow)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def dict_view(self):
|
||||||
|
"""A dict like view on this object"""
|
||||||
|
return DictReadAttrProxy(self)
|
||||||
|
|
||||||
|
|
||||||
class Tag(Base):
|
class Tag(Base):
|
||||||
__tablename__ = "core__tags"
|
__tablename__ = "core__tags"
|
||||||
@ -1581,7 +1606,7 @@ class Graveyard(Base):
|
|||||||
return context
|
return context
|
||||||
MODELS = [
|
MODELS = [
|
||||||
LocalUser, RemoteUser, User, MediaEntry, Tag, MediaTag, Comment, TextComment,
|
LocalUser, RemoteUser, User, MediaEntry, Tag, MediaTag, Comment, TextComment,
|
||||||
Collection, CollectionItem, MediaFile, FileKeynames, MediaAttachmentFile,
|
Collection, CollectionItem, MediaFile, FileKeynames, MediaAttachmentFile, MediaSubtitleFile,
|
||||||
ProcessingMetaData, Notification, Client, CommentSubscription, Report,
|
ProcessingMetaData, Notification, Client, CommentSubscription, Report,
|
||||||
UserBan, Privilege, PrivilegeUserAssociation, RequestToken, AccessToken,
|
UserBan, Privilege, PrivilegeUserAssociation, RequestToken, AccessToken,
|
||||||
NonceTimestamp, Activity, Generator, Location, GenericModelReference, Graveyard]
|
NonceTimestamp, Activity, Generator, Location, GenericModelReference, Graveyard]
|
||||||
|
@ -100,6 +100,12 @@ class EditAttachmentsForm(wtforms.Form):
|
|||||||
attachment_file = wtforms.FileField(
|
attachment_file = wtforms.FileField(
|
||||||
'File')
|
'File')
|
||||||
|
|
||||||
|
class EditSubtitlesForm(wtforms.Form):
|
||||||
|
subtitle_name = wtforms.StringField(
|
||||||
|
'Title')
|
||||||
|
subtitle_file = wtforms.FileField(
|
||||||
|
'File')
|
||||||
|
|
||||||
|
|
||||||
class EditCollectionForm(wtforms.Form):
|
class EditCollectionForm(wtforms.Form):
|
||||||
title = wtforms.StringField(
|
title = wtforms.StringField(
|
||||||
|
@ -181,6 +181,64 @@ def edit_attachments(request, media):
|
|||||||
else:
|
else:
|
||||||
raise Forbidden("Attachments are disabled")
|
raise Forbidden("Attachments are disabled")
|
||||||
|
|
||||||
|
@get_media_entry_by_id
|
||||||
|
@require_active_login
|
||||||
|
def edit_subtitles(request, media):
|
||||||
|
if mg_globals.app_config['allow_subtitles']:
|
||||||
|
form = forms.EditSubtitlesForm(request.form)
|
||||||
|
|
||||||
|
# Add any subtitles
|
||||||
|
if 'subtitle_file' in request.files \
|
||||||
|
and request.files['subtitle_file']:
|
||||||
|
if mimetypes.guess_type(
|
||||||
|
request.files['subtitle_file'].filename)[0] in \
|
||||||
|
UNSAFE_MIMETYPES:
|
||||||
|
public_filename = secure_filename('{0}.notsafe'.format(
|
||||||
|
request.files['subtitle_file'].filename))
|
||||||
|
else:
|
||||||
|
public_filename = secure_filename(
|
||||||
|
request.files['subtitle_file'].filename)
|
||||||
|
|
||||||
|
subtitle_public_filepath \
|
||||||
|
= mg_globals.public_store.get_unique_filepath(
|
||||||
|
['media_entries', six.text_type(media.id), 'subtitle',
|
||||||
|
public_filename])
|
||||||
|
|
||||||
|
subtitle_public_file = mg_globals.public_store.get_file(
|
||||||
|
subtitle_public_filepath, 'wb')
|
||||||
|
|
||||||
|
try:
|
||||||
|
subtitle_public_file.write(
|
||||||
|
request.files['subtitle_file'].stream.read())
|
||||||
|
finally:
|
||||||
|
request.files['subtitle_file'].stream.close()
|
||||||
|
|
||||||
|
media.subtitle_files.append(dict(
|
||||||
|
name=form.subtitle_name.data \
|
||||||
|
or request.files['subtitle_file'].filename,
|
||||||
|
filepath=subtitle_public_filepath,
|
||||||
|
created=datetime.utcnow(),
|
||||||
|
))
|
||||||
|
|
||||||
|
media.save()
|
||||||
|
|
||||||
|
messages.add_message(
|
||||||
|
request,
|
||||||
|
messages.SUCCESS,
|
||||||
|
_("You added the subttile %s!") %
|
||||||
|
(form.subtitle_name.data or
|
||||||
|
request.files['subtitle_file'].filename))
|
||||||
|
|
||||||
|
return redirect(request,
|
||||||
|
location=media.url_for_self(request.urlgen))
|
||||||
|
return render_to_response(
|
||||||
|
request,
|
||||||
|
'mediagoblin/edit/subtitles.html',
|
||||||
|
{'media': media,
|
||||||
|
'form': form})
|
||||||
|
else:
|
||||||
|
raise Forbidden("Subtitles are disabled")
|
||||||
|
|
||||||
@require_active_login
|
@require_active_login
|
||||||
def legacy_edit_profile(request):
|
def legacy_edit_profile(request):
|
||||||
"""redirect the old /edit/profile/?username=USER to /u/USER/edit/"""
|
"""redirect the old /edit/profile/?username=USER to /u/USER/edit/"""
|
||||||
|
69
mediagoblin/templates/mediagoblin/edit/subtitles.html
Normal file
69
mediagoblin/templates/mediagoblin/edit/subtitles.html
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
{#
|
||||||
|
# GNU MediaGoblin -- federated, autonomous media hosting
|
||||||
|
# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS.
|
||||||
|
#
|
||||||
|
# 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" %}
|
||||||
|
|
||||||
|
{% import "/mediagoblin/utils/wtforms.html" as wtforms_util %}
|
||||||
|
|
||||||
|
{% block title -%}
|
||||||
|
{% trans media_title=media.title -%}
|
||||||
|
Editing subtitles for {{ media_title }}
|
||||||
|
{%- endtrans %} — {{ super() }}
|
||||||
|
{%- endblock %}
|
||||||
|
|
||||||
|
{% block mediagoblin_content %}
|
||||||
|
<form action="{{ request.urlgen('mediagoblin.edit.subtitles',
|
||||||
|
user= media.get_actor.username,
|
||||||
|
media_id=media.id) }}"
|
||||||
|
method="POST" enctype="multipart/form-data">
|
||||||
|
<div class="form_box">
|
||||||
|
<h1>
|
||||||
|
{%- trans media_title=media.title -%}
|
||||||
|
Editing subtitles for {{ media_title }}
|
||||||
|
{%- endtrans -%}
|
||||||
|
</h1>
|
||||||
|
<div style="text-align: center;" >
|
||||||
|
<img src="{{ media.thumb_url }}" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% if media.subtitle_files|count %}
|
||||||
|
<h2>{% trans %}subtitles{% endtrans %}</h2>
|
||||||
|
<ul>
|
||||||
|
{%- for subtitle in media.subtitle_files %}
|
||||||
|
<li>
|
||||||
|
<a target="_blank" href="{{ request.app.public_store.file_url(
|
||||||
|
subtitle['filepath']) }}">
|
||||||
|
{{- subtitle.name -}}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{%- endfor %}
|
||||||
|
</ul>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<h2>{% trans %}Add subtitle{% endtrans %}</h2>
|
||||||
|
{{- wtforms_util.render_divs(form) }}
|
||||||
|
<div class="form_submit_buttons">
|
||||||
|
<a class="button_action" href="{{ media.url_for_self(request.urlgen) }}">
|
||||||
|
{%- trans %}Cancel{% endtrans -%}
|
||||||
|
</a>
|
||||||
|
<input type="submit" value="{% trans %}Save changes{% endtrans %}"
|
||||||
|
class="button_form" />
|
||||||
|
{{ csrf_token }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
@ -60,9 +60,9 @@
|
|||||||
{% else %}
|
{% else %}
|
||||||
type="{{ media.media_manager['default_webm_type'] }}"
|
type="{{ media.media_manager['default_webm_type'] }}"
|
||||||
{% endif %} />
|
{% endif %} />
|
||||||
{%- for attachment in media.attachment_files %}
|
{%- for subtitle in media.subtitle_files %}
|
||||||
<track src="{{ request.app.public_store.file_url(attachment.filepath) }}"
|
<track src="{{ request.app.public_store.file_url(subtitle.filepath) }}"
|
||||||
label = "{{- attachment.name -}}" kind="subtitles" >
|
label = "{{ subtitle.name }}" kind="subtitles" >
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
<div class="no_html5">
|
<div class="no_html5">
|
||||||
{%- trans -%}Sorry, this video will not work because
|
{%- trans -%}Sorry, this video will not work because
|
||||||
|
@ -233,6 +233,33 @@
|
|||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
{%- if media.subtitle_files|count %}
|
||||||
|
<h3>{% trans %}Subtitles{% endtrans %}</h3>
|
||||||
|
<ul>
|
||||||
|
{%- for subtitle in media.subtitle_files %}
|
||||||
|
<li>
|
||||||
|
<a href="{{ request.app.public_store.file_url(subtitle.filepath) }}">
|
||||||
|
{{- subtitle.name -}}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{%- endfor %}
|
||||||
|
</ul>
|
||||||
|
{%- endif %}
|
||||||
|
{%- if app_config['allow_subtitles']
|
||||||
|
and request.user
|
||||||
|
and (media.actor == request.user.id
|
||||||
|
or request.user.has_privilege('admin')) %}
|
||||||
|
{%- if not media.subtitle_files|count %}
|
||||||
|
<h3>{% trans %}Subtitles{% endtrans %}</h3>
|
||||||
|
{%- endif %}
|
||||||
|
<p>
|
||||||
|
<a href="{{ request.urlgen('mediagoblin.edit.subtitles',
|
||||||
|
user=media.get_actor.username,
|
||||||
|
media_id=media.id) }}">
|
||||||
|
{%- trans %}Add subtitle{% endtrans -%}
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
{% block mediagoblin_sidebar %}
|
{% block mediagoblin_sidebar %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -41,5 +41,12 @@ def delete_media_files(media):
|
|||||||
except OSError:
|
except OSError:
|
||||||
no_such_files.append("/".join(attachment['filepath']))
|
no_such_files.append("/".join(attachment['filepath']))
|
||||||
|
|
||||||
|
for subtitle in media.subtitle_files:
|
||||||
|
try:
|
||||||
|
mg_globals.public_store.delete_file(
|
||||||
|
subtitle['filepath'])
|
||||||
|
except OSError:
|
||||||
|
no_such_files.append("/".join(subtitle['filepath']))
|
||||||
|
|
||||||
if no_such_files:
|
if no_such_files:
|
||||||
raise OSError(", ".join(no_such_files))
|
raise OSError(", ".join(no_such_files))
|
||||||
|
@ -111,6 +111,11 @@ add_route('mediagoblin.edit.attachments',
|
|||||||
'/u/<string:user>/m/<int:media_id>/attachments/',
|
'/u/<string:user>/m/<int:media_id>/attachments/',
|
||||||
'mediagoblin.edit.views:edit_attachments')
|
'mediagoblin.edit.views:edit_attachments')
|
||||||
|
|
||||||
|
add_route('mediagoblin.edit.subtitles',
|
||||||
|
'/u/<string:user>/m/<int:media_id>/subtitles/',
|
||||||
|
'mediagoblin.edit.views:edit_subtitles')
|
||||||
|
|
||||||
|
|
||||||
add_route('mediagoblin.edit.metadata',
|
add_route('mediagoblin.edit.metadata',
|
||||||
'/u/<string:user>/m/<int:media_id>/metadata/',
|
'/u/<string:user>/m/<int:media_id>/metadata/',
|
||||||
'mediagoblin.edit.views:edit_metadata')
|
'mediagoblin.edit.views:edit_metadata')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user