From 19ba17d95066e55afde4db125cf139aae1831650 Mon Sep 17 00:00:00 2001 From: saksham1115 Date: Fri, 3 Jun 2016 11:55:46 +0000 Subject: [PATCH] Subtitle built over attachments : working --- mediagoblin/config_spec.ini | 3 +- mediagoblin/db/models.py | 27 +++++++- mediagoblin/edit/forms.py | 6 ++ mediagoblin/edit/views.py | 58 ++++++++++++++++ .../templates/mediagoblin/edit/subtitles.html | 69 +++++++++++++++++++ .../mediagoblin/media_displays/video.html | 6 +- .../mediagoblin/user_pages/media.html | 27 ++++++++ mediagoblin/tools/files.py | 7 ++ mediagoblin/user_pages/routing.py | 5 ++ 9 files changed, 203 insertions(+), 5 deletions(-) create mode 100644 mediagoblin/templates/mediagoblin/edit/subtitles.html diff --git a/mediagoblin/config_spec.ini b/mediagoblin/config_spec.ini index 6ded23fd..7acc72c2 100644 --- a/mediagoblin/config_spec.ini +++ b/mediagoblin/config_spec.ini @@ -81,7 +81,8 @@ celery_setup_elsewhere = boolean(default=False) # 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 # 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 csrf_cookie_name = string(default='mediagoblin_csrftoken') diff --git a/mediagoblin/db/models.py b/mediagoblin/db/models.py index 5393f679..9bbb252b 100644 --- a/mediagoblin/db/models.py +++ b/mediagoblin/db/models.py @@ -573,6 +573,15 @@ class MediaEntry(Base, MediaEntryMixin, CommentingMixin): 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", cascade="all, delete-orphan" # should be automatically deleted ) @@ -888,6 +897,22 @@ class MediaAttachmentFile(Base): """A dict like view on this object""" 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): __tablename__ = "core__tags" @@ -1581,7 +1606,7 @@ class Graveyard(Base): return context MODELS = [ LocalUser, RemoteUser, User, MediaEntry, Tag, MediaTag, Comment, TextComment, - Collection, CollectionItem, MediaFile, FileKeynames, MediaAttachmentFile, + Collection, CollectionItem, MediaFile, FileKeynames, MediaAttachmentFile, MediaSubtitleFile, ProcessingMetaData, Notification, Client, CommentSubscription, Report, UserBan, Privilege, PrivilegeUserAssociation, RequestToken, AccessToken, NonceTimestamp, Activity, Generator, Location, GenericModelReference, Graveyard] diff --git a/mediagoblin/edit/forms.py b/mediagoblin/edit/forms.py index 83e83c3c..f98b672d 100644 --- a/mediagoblin/edit/forms.py +++ b/mediagoblin/edit/forms.py @@ -100,6 +100,12 @@ class EditAttachmentsForm(wtforms.Form): attachment_file = wtforms.FileField( 'File') +class EditSubtitlesForm(wtforms.Form): + subtitle_name = wtforms.StringField( + 'Title') + subtitle_file = wtforms.FileField( + 'File') + class EditCollectionForm(wtforms.Form): title = wtforms.StringField( diff --git a/mediagoblin/edit/views.py b/mediagoblin/edit/views.py index 521359f5..dfc256e2 100644 --- a/mediagoblin/edit/views.py +++ b/mediagoblin/edit/views.py @@ -181,6 +181,64 @@ def edit_attachments(request, media): else: 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 def legacy_edit_profile(request): """redirect the old /edit/profile/?username=USER to /u/USER/edit/""" diff --git a/mediagoblin/templates/mediagoblin/edit/subtitles.html b/mediagoblin/templates/mediagoblin/edit/subtitles.html new file mode 100644 index 00000000..023388f1 --- /dev/null +++ b/mediagoblin/templates/mediagoblin/edit/subtitles.html @@ -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 . +#} +{%- 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 %} +
+
+

+ {%- trans media_title=media.title -%} + Editing subtitles for {{ media_title }} + {%- endtrans -%} +

+
+ +
+ + {% if media.subtitle_files|count %} +

{% trans %}subtitles{% endtrans %}

+ + {% endif %} + +

{% trans %}Add subtitle{% endtrans %}

+ {{- wtforms_util.render_divs(form) }} + +
+
+{% endblock %} diff --git a/mediagoblin/templates/mediagoblin/media_displays/video.html b/mediagoblin/templates/mediagoblin/media_displays/video.html index c9a27702..8e3a202f 100644 --- a/mediagoblin/templates/mediagoblin/media_displays/video.html +++ b/mediagoblin/templates/mediagoblin/media_displays/video.html @@ -60,9 +60,9 @@ {% else %} type="{{ media.media_manager['default_webm_type'] }}" {% endif %} /> - {%- for attachment in media.attachment_files %} - + {%- for subtitle in media.subtitle_files %} + {%- endfor %}
{%- trans -%}Sorry, this video will not work because diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html index f76e0a8f..529f638c 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media.html @@ -233,6 +233,33 @@

{%- endif %} + {%- if media.subtitle_files|count %} +

{% trans %}Subtitles{% endtrans %}

+ + {%- 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 %} +

{% trans %}Subtitles{% endtrans %}

+ {%- endif %} +

+ + {%- trans %}Add subtitle{% endtrans -%} + +

+ {%- endif %} {% block mediagoblin_sidebar %} {% endblock %} diff --git a/mediagoblin/tools/files.py b/mediagoblin/tools/files.py index 2c486ac8..0509a387 100644 --- a/mediagoblin/tools/files.py +++ b/mediagoblin/tools/files.py @@ -41,5 +41,12 @@ def delete_media_files(media): except OSError: 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: raise OSError(", ".join(no_such_files)) diff --git a/mediagoblin/user_pages/routing.py b/mediagoblin/user_pages/routing.py index 68cb0a3b..f7abf7bf 100644 --- a/mediagoblin/user_pages/routing.py +++ b/mediagoblin/user_pages/routing.py @@ -111,6 +111,11 @@ add_route('mediagoblin.edit.attachments', '/u//m//attachments/', 'mediagoblin.edit.views:edit_attachments') +add_route('mediagoblin.edit.subtitles', + '/u//m//subtitles/', + 'mediagoblin.edit.views:edit_subtitles') + + add_route('mediagoblin.edit.metadata', '/u//m//metadata/', 'mediagoblin.edit.views:edit_metadata') -- 2.25.1