Commit | Line | Data |
---|---|---|
945d0937 | 1 | # GNU MediaGoblin -- federated, autonomous media hosting |
7ab18019 | 2 | # Copyright (C) 2016 MediaGoblin contributors. See AUTHORS. |
945d0937 | 3 | # |
4 | # This program is free software: you can redistribute it and/or modify | |
5 | # it under the terms of the GNU Affero General Public License as published by | |
6 | # the Free Software Foundation, either version 3 of the License, or | |
7 | # (at your option) any later version. | |
8 | # | |
9 | # This program is distributed in the hope that it will be useful, | |
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | # GNU Affero General Public License for more details. | |
13 | # | |
14 | # You should have received a copy of the GNU Affero General Public License | |
15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
16 | ||
17 | import six | |
18 | ||
19 | from datetime import datetime | |
20 | ||
21 | from itsdangerous import BadSignature | |
22 | from werkzeug.exceptions import Forbidden | |
23 | from werkzeug.utils import secure_filename | |
24 | ||
25 | from mediagoblin import messages | |
26 | from mediagoblin import mg_globals | |
27 | ||
067b1b07 | 28 | from mediagoblin.plugins.subtitles import forms |
945d0937 | 29 | from mediagoblin.decorators import (require_active_login, active_user_from_url, |
c36c6833 | 30 | get_media_entry_by_id, user_may_delete_media) |
945d0937 | 31 | from mediagoblin.tools.metadata import (compact_and_validate, DEFAULT_CHECKER, |
32 | DEFAULT_SCHEMA) | |
33 | from mediagoblin.tools.response import (render_to_response, | |
34 | redirect, redirect_obj, render_404) | |
35 | ||
36 | import mimetypes | |
37 | ||
b2ba593d | 38 | from mediagoblin.plugins.subtitles.tools import open_subtitle,save_subtitle |
945d0937 | 39 | |
40 | UNSAFE_MIMETYPES = [ | |
41 | 'text/html', | |
42 | 'text/svg+xml'] | |
43 | ||
44 | @get_media_entry_by_id | |
45 | @user_may_delete_media | |
46 | @require_active_login | |
47 | def edit_subtitles(request, media): | |
a9b7bd60 BS |
48 | # This was originally quite a long list of allowed extensions, but as far as |
49 | # I understand, Video.js only supports WebVTT format subtitles: | |
50 | # https://docs.videojs.com/docs/guides/text-tracks.html | |
51 | allowed_extensions = ['vtt'] | |
945d0937 | 52 | form = forms.EditSubtitlesForm(request.form) |
53 | ||
54 | # Add any subtitles | |
55 | if 'subtitle_file' in request.files \ | |
56 | and request.files['subtitle_file']: | |
57 | if mimetypes.guess_type( | |
58 | request.files['subtitle_file'].filename)[0] in \ | |
59 | UNSAFE_MIMETYPES: | |
60 | public_filename = secure_filename('{0}.notsafe'.format( | |
61 | request.files['subtitle_file'].filename)) | |
62 | else: | |
63 | public_filename = secure_filename( | |
64 | request.files['subtitle_file'].filename) | |
05a39583 | 65 | filepath = request.files['subtitle_file'].filename |
5430bc2c | 66 | if filepath.split('.')[-1] not in allowed_extensions : |
05a39583 | 67 | messages.add_message( |
68 | request, | |
69 | messages.ERROR, | |
70 | ("Invalid subtitle file")) | |
71 | ||
72 | return redirect(request, | |
73 | location=media.url_for_self(request.urlgen)) | |
5430bc2c | 74 | subtitle_public_filepath = mg_globals.public_store.get_unique_filepath( |
945d0937 | 75 | ['media_entries', six.text_type(media.id), 'subtitle', |
76 | public_filename]) | |
77 | ||
13422829 | 78 | with mg_globals.public_store.get_file( |
79 | subtitle_public_filepath, 'wb') as subtitle_public_file: | |
945d0937 | 80 | subtitle_public_file.write( |
81 | request.files['subtitle_file'].stream.read()) | |
13422829 | 82 | request.files['subtitle_file'].stream.close() |
945d0937 | 83 | |
84 | media.subtitle_files.append(dict( | |
85 | name=form.subtitle_language.data \ | |
86 | or request.files['subtitle_file'].filename, | |
87 | filepath=subtitle_public_filepath, | |
88 | created=datetime.utcnow(), | |
89 | )) | |
90 | ||
91 | media.save() | |
92 | ||
93 | messages.add_message( | |
94 | request, | |
95 | messages.SUCCESS, | |
13422829 | 96 | ("You added the subtitle %s!") % |
945d0937 | 97 | (form.subtitle_language.data or |
98 | request.files['subtitle_file'].filename)) | |
99 | ||
100 | return redirect(request, | |
101 | location=media.url_for_self(request.urlgen)) | |
102 | return render_to_response( | |
103 | request, | |
067b1b07 | 104 | 'mediagoblin/plugins/subtitles/subtitles.html', |
945d0937 | 105 | {'media': media, |
106 | 'form': form}) | |
107 | ||
108 | ||
109 | @require_active_login | |
110 | @get_media_entry_by_id | |
111 | @user_may_delete_media | |
b2ba593d | 112 | def custom_subtitles(request,media,id=None): |
113 | id = request.matchdict['id'] | |
114 | path = "" | |
115 | for subtitle in media.subtitle_files: | |
116 | if subtitle["id"] == id: | |
117 | path = subtitle["filepath"] | |
19b4f431 | 118 | text = "" |
119 | value = open_subtitle(path) | |
120 | text, status = value[0], value[1] | |
121 | if status == True : | |
122 | form = forms.CustomizeSubtitlesForm(request.form, | |
123 | subtitle=text) | |
124 | if request.method == 'POST' and form.validate(): | |
125 | subtitle_data = form.subtitle.data | |
126 | status = save_subtitle(path,subtitle_data) | |
127 | if status == True: | |
128 | messages.add_message( | |
129 | request, | |
130 | messages.SUCCESS, | |
131 | ("Subtitle file changed!!!")) | |
132 | return redirect(request, | |
133 | location=media.url_for_self(request.urlgen)) | |
134 | else : | |
135 | messages.add_message( | |
136 | request, | |
137 | messages.ERROR, | |
138 | ("Couldn't edit the subtitles!!!")) | |
139 | return redirect(request, | |
140 | location=media.url_for_self(request.urlgen)) | |
141 | ||
142 | return render_to_response( | |
143 | request, | |
144 | "mediagoblin/plugins/subtitles/custom_subtitles.html", | |
145 | {"id": id, | |
146 | "media": media, | |
147 | "form": form }) | |
148 | else: | |
149 | index = 0 | |
150 | for subtitle in media.subtitle_files: | |
151 | if subtitle["id"] == id: | |
152 | delete_container = index | |
153 | media.subtitle_files.pop(delete_container) | |
154 | media.save() | |
155 | break | |
156 | index += 1 | |
5b42f934 | 157 | messages.add_message( |
158 | request, | |
19b4f431 | 159 | messages.ERROR, |
160 | ("File link broken! Upload the subtitle again")) | |
13422829 | 161 | return redirect(request, |
162 | location=media.url_for_self(request.urlgen)) | |
945d0937 | 163 | |
eaeed602 | 164 | |
165 | @require_active_login | |
166 | @get_media_entry_by_id | |
167 | @user_may_delete_media | |
c36c6833 | 168 | def delete_subtitles(request,media): |
b2ba593d | 169 | id = request.matchdict['id'] |
eaeed602 | 170 | delete_container = None |
171 | index = 0 | |
172 | for subtitle in media.subtitle_files: | |
b2ba593d | 173 | if subtitle["id"] == id: |
174 | path = subtitle["filepath"] | |
175 | mg_globals.public_store.delete_file(path) | |
eaeed602 | 176 | delete_container = index |
eaeed602 | 177 | media.subtitle_files.pop(delete_container) |
178 | media.save() | |
179 | break | |
b2ba593d | 180 | index += 1 |
eaeed602 | 181 | |
182 | messages.add_message( | |
183 | request, | |
184 | messages.SUCCESS, | |
185 | ("Subtitle file deleted!!!")) | |
186 | ||
187 | return redirect(request, | |
19b4f431 | 188 | location=media.url_for_self(request.urlgen)) |