Commit 78ae61e282c99b3000782d6b7635f9448aa6295f
1 parent
44e216fd
Exists in
master
Interface inicial do 2o loop da tarefa e file upload modificado para salvar numa pasta de sessão
Showing
6 changed files
with
144 additions
and
52 deletions
Show diff stats
corretor.py
@@ -39,6 +39,8 @@ class Corretor: | @@ -39,6 +39,8 @@ class Corretor: | ||
39 | template = self.env.get_template('template.html') | 39 | template = self.env.get_template('template.html') |
40 | project.info['task_presenter'] = template.render(server=self.config['HOST_ENDPOINT']) | 40 | project.info['task_presenter'] = template.render(server=self.config['HOST_ENDPOINT']) |
41 | project.info['thumbnail'] = self.config['HOST_ENDPOINT'] + "/img/thumbnail.png" | 41 | project.info['thumbnail'] = self.config['HOST_ENDPOINT'] + "/img/thumbnail.png" |
42 | + project.info['sched'] = "incremental" | ||
43 | + project.allow_anonymous_contributors = False | ||
42 | pbclient.update_project(project) | 44 | pbclient.update_project(project) |
43 | 45 | ||
44 | def create_project(self): | 46 | def create_project(self): |
@@ -70,17 +72,26 @@ class Corretor: | @@ -70,17 +72,26 @@ class Corretor: | ||
70 | return '.' in filename and filename.rsplit('.', 1)[1] in allowed_extensions | 72 | return '.' in filename and filename.rsplit('.', 1)[1] in allowed_extensions |
71 | 73 | ||
72 | def upload_file(self): | 74 | def upload_file(self): |
75 | + upload_session_id = request.form['upload_session_id'] | ||
76 | + sign_name = request.form['sign_name'] | ||
73 | file = request.files['file'] | 77 | file = request.files['file'] |
74 | result_msg = "" | 78 | result_msg = "" |
75 | - code = 200 | ||
76 | - if file and self.__allowed_file(file.filename): | 79 | + code = 400 |
80 | + if (not pyutil.is_int(upload_session_id)): | ||
81 | + result_msg = "Invalid upload session id: " + upload_session_id | ||
82 | + elif file and not self.__allowed_file(file.filename): | ||
83 | + result_msg = file.filename + " extension is not acceptable." | ||
84 | + else: | ||
77 | filename = secure_filename(file.filename) | 85 | filename = secure_filename(file.filename) |
78 | - file.save(os.path.join(self.config['UPLOAD_FOLDER'], filename)) | 86 | + upload_dir = os.path.join(self.config['UPLOAD_FOLDER'], upload_session_id) |
87 | + if not os.path.exists(upload_dir): | ||
88 | + os.makedirs(upload_dir) | ||
89 | + uploaded_file = os.path.join(upload_dir, filename) | ||
90 | + file.save(uploaded_file) | ||
91 | + renamed_file = os.path.join(upload_dir, secure_filename(sign_name + "_CORRIGIDO.blend")) | ||
92 | + os.rename(uploaded_file, renamed_file) | ||
79 | # validar o .blend | 93 | # validar o .blend |
94 | + code = 200 | ||
80 | result_msg = "File " + filename + " was uploaded." | 95 | result_msg = "File " + filename + " was uploaded." |
81 | - else: | ||
82 | - result_msg = file.filename + " extension is not acceptable." | ||
83 | - code = 400 | ||
84 | pyutil.log(result_msg) | 96 | pyutil.log(result_msg) |
85 | return make_response(result_msg, code) | 97 | return make_response(result_msg, code) |
86 | - |
main.py
@@ -42,7 +42,7 @@ def upload_file(): | @@ -42,7 +42,7 @@ def upload_file(): | ||
42 | 42 | ||
43 | @app.route("/finish_task", methods=["POST"]) | 43 | @app.route("/finish_task", methods=["POST"]) |
44 | def finish_task(): | 44 | def finish_task(): |
45 | - # TODO | 45 | + # TODO read - request.data['upload_session_id'] e request.data['sign_name'] |
46 | return | 46 | return |
47 | 47 | ||
48 | def read_settings(app): | 48 | def read_settings(app): |
pyutil.py
@@ -59,3 +59,10 @@ def print_stack_trace(): | @@ -59,3 +59,10 @@ def print_stack_trace(): | ||
59 | 59 | ||
60 | def get_date_now(): | 60 | def get_date_now(): |
61 | return datetime.datetime.now().strftime('%Y-%m-%dT%H:%M:%S') | 61 | return datetime.datetime.now().strftime('%Y-%m-%dT%H:%M:%S') |
62 | + | ||
63 | +def is_int(string): | ||
64 | + try: | ||
65 | + int(string) | ||
66 | + return True | ||
67 | + except ValueError: | ||
68 | + return False |
view/assets/css/main.css
@@ -37,11 +37,15 @@ video { | @@ -37,11 +37,15 @@ video { | ||
37 | } | 37 | } |
38 | 38 | ||
39 | /* Body */ | 39 | /* Body */ |
40 | -#body-container { | 40 | +.body-container { |
41 | background: rgba(236, 238, 242, 1.0); | 41 | background: rgba(236, 238, 242, 1.0); |
42 | padding-bottom: 10px; | 42 | padding-bottom: 10px; |
43 | } | 43 | } |
44 | 44 | ||
45 | +#approval-container { | ||
46 | + display: none; | ||
47 | +} | ||
48 | + | ||
45 | /* Tabela */ | 49 | /* Tabela */ |
46 | .table-responsive { | 50 | .table-responsive { |
47 | border: none; | 51 | border: none; |
@@ -179,6 +183,11 @@ h6 { | @@ -179,6 +183,11 @@ h6 { | ||
179 | padding-right: 40px; | 183 | padding-right: 40px; |
180 | } | 184 | } |
181 | 185 | ||
186 | +#approval-task-container { | ||
187 | + padding-top: 6px; | ||
188 | + padding-right: 40px; | ||
189 | +} | ||
190 | + | ||
182 | .finish-task-button { | 191 | .finish-task-button { |
183 | float: right; | 192 | float: right; |
184 | padding-bottom: 0px; | 193 | padding-bottom: 0px; |
view/img/thumbnail.png
view/template.html
@@ -43,21 +43,23 @@ | @@ -43,21 +43,23 @@ | ||
43 | </table> | 43 | </table> |
44 | </div> | 44 | </div> |
45 | <div class="line-separator"></div> | 45 | <div class="line-separator"></div> |
46 | - <div id="body-container" class="row"> | 46 | + <div id="corretor-container" class="row body-container"> |
47 | <div id="avatar-container" class="col-sm-6"> | 47 | <div id="avatar-container" class="col-sm-6"> |
48 | <div class="row"> | 48 | <div class="row"> |
49 | - <h6>ANIMAÇÃO ATUAL "<span class="sign-label"></span>":</h6> | 49 | + <h6> |
50 | + ANIMAÇÃO ATUAL "<span class="sign-label"></span>": | ||
51 | + </h6> | ||
50 | </div> | 52 | </div> |
51 | <div class="row"> | 53 | <div class="row"> |
52 | - <video id="avatar-video" src="" | ||
53 | - preload="metadata" class="video-body" autoplay loop controls> | 54 | + <video id="avatar-video" src="" preload="metadata" |
55 | + class="video-body" autoplay loop controls> | ||
54 | <source type="video/webm"> | 56 | <source type="video/webm"> |
55 | </video> | 57 | </video> |
56 | </div> | 58 | </div> |
57 | <div class="row"> | 59 | <div class="row"> |
58 | - <a id="blend-link" href="" | ||
59 | - class="btn btn-default" download>DOWNLOAD ARQUIVO DE ANIMAÇÃO | ||
60 | - .BLENDER <img src="{{ server }}/img/blender.svg" | 60 | + <a id="blend-link" href="" class="btn btn-default" download>DOWNLOAD |
61 | + ARQUIVO DE ANIMAÇÃO .BLENDER <img | ||
62 | + src="{{ server }}/img/blender.svg" | ||
61 | style="width: 22px; height: 22px"></img> | 63 | style="width: 22px; height: 22px"></img> |
62 | </a> | 64 | </a> |
63 | </div> | 65 | </div> |
@@ -89,40 +91,23 @@ | @@ -89,40 +91,23 @@ | ||
89 | </div> | 91 | </div> |
90 | <div id="ref-container" class="col-sm-6"> | 92 | <div id="ref-container" class="col-sm-6"> |
91 | <div class="row"> | 93 | <div class="row"> |
92 | - <h6>VÍDEO DE REFERÊNCIA “<span class="sign-label"></span>” :</h6> | 94 | + <h6> |
95 | + VÍDEO DE REFERÊNCIA “<span class="sign-label"></span>”: | ||
96 | + </h6> | ||
93 | </div> | 97 | </div> |
94 | <div class="row"> | 98 | <div class="row"> |
95 | - <video id="ref-video" src="" | ||
96 | - preload="metadata" class="video-body" autoplay loop controls> | ||
97 | - <source type="video/mp4"> | 99 | + <video id="ref-video" src="" preload="metadata" class="video-body" |
100 | + autoplay loop controls> | ||
101 | + <source type="video/webm"> | ||
98 | </video> | 102 | </video> |
99 | </div> | 103 | </div> |
100 | <div class="row"> | 104 | <div class="row"> |
101 | - <a id="ref-video-link" href="" | ||
102 | - class="btn btn-default" download>DOWNLOAD VÍDEO DE REFERÊNCIA | ||
103 | - DO SINAL <img src="{{ server }}/img/download.svg" | 105 | + <a id="ref-video-link" href="" class="btn btn-default" download>DOWNLOAD |
106 | + VÍDEO DE REFERÊNCIA DO SINAL <img | ||
107 | + src="{{ server }}/img/download.svg" | ||
104 | style="width: 22px; height: 22px"></img> | 108 | style="width: 22px; height: 22px"></img> |
105 | </a> | 109 | </a> |
106 | </div> | 110 | </div> |
107 | - <!-- | ||
108 | - <div class="row"> | ||
109 | - <h5>ENVIAR NOVO VÍDEO DE REFERÊNCIA DO SINAL:</h5> | ||
110 | - </div> | ||
111 | - <div class="row"> | ||
112 | - <div class="col-sm-6"> | ||
113 | - <a href="#" class="btn btn-file" type="input"> <img | ||
114 | - src="{{ server }}/img/paperclip.svg" | ||
115 | - style="width: 22px; height: 22px"></img> ENVIAR | ||
116 | - </a> | ||
117 | - </div> | ||
118 | - <div class="col-sm-6"> | ||
119 | - <div class="progress"> | ||
120 | - <div class="progress-bar" role="progressbar" aria-valuenow="40" | ||
121 | - aria-valuemin="0" aria-valuemax="100" style="width: 40%"></div> | ||
122 | - </div> | ||
123 | - </div> | ||
124 | - </div> | ||
125 | - --> | ||
126 | <div id="finish-task-container" class="row"> | 111 | <div id="finish-task-container" class="row"> |
127 | <div id="finish-button" class="finish-task-button disabled-button "> | 112 | <div id="finish-button" class="finish-task-button disabled-button "> |
128 | FINALIZAR<img class="icon" src="{{ server }}/img/finish.svg"></img> | 113 | FINALIZAR<img class="icon" src="{{ server }}/img/finish.svg"></img> |
@@ -133,10 +118,54 @@ | @@ -133,10 +118,54 @@ | ||
133 | </div> | 118 | </div> |
134 | </div> | 119 | </div> |
135 | </div> | 120 | </div> |
121 | + <div id="approval-container" class="row body-container"> | ||
122 | + <div id="avatar-container" class="col-sm-6"> | ||
123 | + <div class="row"> | ||
124 | + <h6> | ||
125 | + ANIMAÇÃO"<span class="sign-label"></span>": | ||
126 | + </h6> | ||
127 | + </div> | ||
128 | + <div class="row"> | ||
129 | + <video id="avatar-video" | ||
130 | + src="{{ server }}/videos/ENSINADO_AVATAR.webm" preload="metadata" | ||
131 | + class="video-body" autoplay loop controls> | ||
132 | + <source type="video/webm"> | ||
133 | + </video> | ||
134 | + </div> | ||
135 | + </div> | ||
136 | + <div id="ref-container" class="col-sm-6"> | ||
137 | + <div class="row"> | ||
138 | + <h6> | ||
139 | + VÍDEO DE REFERÊNCIA “<span class="sign-label"></span>”: | ||
140 | + </h6> | ||
141 | + </div> | ||
142 | + <div class="row"> | ||
143 | + <video src="{{ server }}/videos/ENSINADO_REF.webm" | ||
144 | + preload="metadata" class="video-body" autoplay loop controls> | ||
145 | + <source type="video/mp4"> | ||
146 | + </video> | ||
147 | + </div> | ||
148 | + <div id="approval-task-container" class="row"> | ||
149 | + <div id="approved-button" class="finish-task-button enabled-button"> | ||
150 | + APROVADO<img class="icon" src="{{ server }}/img/finish.svg"></img> | ||
151 | + </div> | ||
152 | + <div id="fix-button" class="finish-task-button enabled-button"> | ||
153 | + CORRIGIR<img class="icon" src="{{ server }}/img/skip.svg"></img> | ||
154 | + </div> | ||
155 | + </div> | ||
156 | + </div> | ||
157 | + </div> | ||
136 | </div> | 158 | </div> |
137 | 159 | ||
138 | <script type="text/javascript"> | 160 | <script type="text/javascript"> |
139 | var base_url = "{{ server }}/videos/"; | 161 | var base_url = "{{ server }}/videos/"; |
162 | + var upload_session_id = generateSessionID(); | ||
163 | + var current_task_id = -1; | ||
164 | + | ||
165 | + function generateSessionID() { | ||
166 | + return (Math.random() + " ").substring(2, 10) | ||
167 | + + (Math.random() + " ").substring(2, 10); | ||
168 | + } | ||
140 | 169 | ||
141 | function resetUploadProgress() { | 170 | function resetUploadProgress() { |
142 | $("#upload-progress .progress-bar").css("width", "0%"); | 171 | $("#upload-progress .progress-bar").css("width", "0%"); |
@@ -146,8 +175,9 @@ | @@ -146,8 +175,9 @@ | ||
146 | $("#finish-button").removeClass("disabled-button"); | 175 | $("#finish-button").removeClass("disabled-button"); |
147 | $("#finish-button").addClass("enabled-button"); | 176 | $("#finish-button").addClass("enabled-button"); |
148 | $("#finish-button").off("click").on("click", function() { | 177 | $("#finish-button").off("click").on("click", function() { |
149 | - // enviar mensagem para exportar video | ||
150 | - saveAnswer(task, deferred, "OK"); | 178 | + // endpoint - /finish_task |
179 | + // enviar mensagem via POST para renderizar video - upload/<session_hash>/<task.info.sign_name>_CORRIGIDO.blend | ||
180 | + saveAnswer(task, deferred, "FINISHED"); | ||
151 | }); | 181 | }); |
152 | } | 182 | } |
153 | 183 | ||
@@ -165,7 +195,10 @@ | @@ -165,7 +195,10 @@ | ||
165 | $("#file-upload").fileupload( | 195 | $("#file-upload").fileupload( |
166 | { | 196 | { |
167 | url : "{{ server }}/upload", | 197 | url : "{{ server }}/upload", |
168 | - replaceFileInput : false, | 198 | + formData : { |
199 | + "upload_session_id" : upload_session_id, | ||
200 | + 'sign_name' : task.info.sign_name | ||
201 | + }, | ||
169 | add : function(e, data) { | 202 | add : function(e, data) { |
170 | resetUploadProgress(); | 203 | resetUploadProgress(); |
171 | $("#upload-file-name").text(data.files[0].name) | 204 | $("#upload-file-name").text(data.files[0].name) |
@@ -175,6 +208,7 @@ | @@ -175,6 +208,7 @@ | ||
175 | enableFinishButton(task, deferred); | 208 | enableFinishButton(task, deferred); |
176 | }, | 209 | }, |
177 | progressall : function(e, data) { | 210 | progressall : function(e, data) { |
211 | + //console.log(data); | ||
178 | var progress = parseInt(data.loaded / data.total * 100, | 212 | var progress = parseInt(data.loaded / data.total * 100, |
179 | 10); | 213 | 10); |
180 | $("#upload-progress .progress-bar").css("width", | 214 | $("#upload-progress .progress-bar").css("width", |
@@ -186,15 +220,31 @@ | @@ -186,15 +220,31 @@ | ||
186 | disableFinishButton(); | 220 | disableFinishButton(); |
187 | } | 221 | } |
188 | }); | 222 | }); |
223 | + | ||
189 | $("#upload-button").off("click").on("click", function() { | 224 | $("#upload-button").off("click").on("click", function() { |
190 | $("#file-upload").click(); | 225 | $("#file-upload").click(); |
191 | }); | 226 | }); |
192 | $("#skip-button").off("click").on("click", function() { | 227 | $("#skip-button").off("click").on("click", function() { |
193 | saveAnswer(task, deferred, "SKIP"); | 228 | saveAnswer(task, deferred, "SKIP"); |
194 | }); | 229 | }); |
230 | + $("#fix-button").off("click").on("click", function() { | ||
231 | + $("#approval-container").hide(); | ||
232 | + $("#corretor-container").show(); | ||
233 | + }); | ||
234 | + $("#approved-button").off("click").on("click", function() { | ||
235 | + saveAnswer(task, deferred, "FINISHED"); | ||
236 | + }); | ||
195 | } | 237 | } |
196 | 238 | ||
197 | - function saveAnswer(task, deferred, answer) { | 239 | + function saveAnswer(task, deferred, status) { |
240 | + var answer = { | ||
241 | + "status" : status | ||
242 | + }; | ||
243 | + if (status == "FINISHED") { | ||
244 | + answer["last_edit_date"] = moment(new Date()).format( | ||
245 | + "YYYY-MM-DDTHH:mm:ss") | ||
246 | + answer["last_upload_session_id"] = upload_session_id; | ||
247 | + } | ||
198 | pybossa.saveTask(task.id, answer).done(function() { | 248 | pybossa.saveTask(task.id, answer).done(function() { |
199 | $("#success").fadeIn(500); | 249 | $("#success").fadeIn(500); |
200 | $("#main-container").hide(); | 250 | $("#main-container").hide(); |
@@ -203,26 +253,41 @@ | @@ -203,26 +253,41 @@ | ||
203 | }, 2000); | 253 | }, 2000); |
204 | }); | 254 | }); |
205 | } | 255 | } |
206 | - | ||
207 | - function loadTaskInfo(info) { | ||
208 | - var sign_name = info.sign_name; | 256 | + |
257 | + function loadTaskInfo(task) { | ||
258 | + current_task_id = task.id; | ||
259 | + var sign_name = task.info.sign_name; | ||
209 | var blend_link = base_url + sign_name + "_AVATAR.blend"; | 260 | var blend_link = base_url + sign_name + "_AVATAR.blend"; |
210 | var avatar_vid_link = base_url + sign_name + "_AVATAR.webm"; | 261 | var avatar_vid_link = base_url + sign_name + "_AVATAR.webm"; |
211 | var ref_vid_link = base_url + sign_name + "_REF.webm"; | 262 | var ref_vid_link = base_url + sign_name + "_REF.webm"; |
212 | $(".sign-label").text(sign_name); | 263 | $(".sign-label").text(sign_name); |
213 | - $("#submission-date").text(moment(info.submission_date).format("DD/MM/YYYY")); | 264 | + $("#submission-date").text( |
265 | + moment(task.info.submission_date).format("DD/MM/YYYY")); | ||
214 | $("#avatar-video").attr("src", avatar_vid_link); | 266 | $("#avatar-video").attr("src", avatar_vid_link); |
215 | $("#ref-video").attr("src", ref_vid_link); | 267 | $("#ref-video").attr("src", ref_vid_link); |
216 | $("#ref-video-link").attr("href", ref_vid_link); | 268 | $("#ref-video-link").attr("href", ref_vid_link); |
217 | $("#blend-link").attr("href", blend_link); | 269 | $("#blend-link").attr("href", blend_link); |
270 | + | ||
271 | + var last_answer = task.info.last_answer; | ||
272 | + var hasLastAnswer = typeof last_answer != "undefined"; | ||
273 | + if (hasLastAnswer && last_answer.status == "FINISHED") { | ||
274 | + $("#last-edit-date").text( | ||
275 | + moment(last_answer.last_edit_date).format("DD/MM/YYYY")); | ||
276 | + $("#last-edit-by").text(last_answer.last_edit_by); | ||
277 | + } | ||
218 | } | 278 | } |
219 | 279 | ||
220 | pybossa.presentTask(function(task, deferred) { | 280 | pybossa.presentTask(function(task, deferred) { |
221 | - if (!$.isEmptyObject(task)) { | ||
222 | - loadTaskInfo(task.info); | 281 | + if (!$.isEmptyObject(task) && current_task_id != task.id) { |
282 | + loadTaskInfo(task); | ||
223 | setupButtons(task, deferred); | 283 | setupButtons(task, deferred); |
224 | $("#success").hide(); | 284 | $("#success").hide(); |
225 | $("#main-container").fadeIn(500); | 285 | $("#main-container").fadeIn(500); |
286 | + var hasLastAnswer = typeof task.info.last_answer != "undefined"; | ||
287 | + if (hasLastAnswer && task.info.last_answer.status == "FINISHED") { | ||
288 | + $("#corretor-container").hide(); | ||
289 | + $("#approval-container").show(); | ||
290 | + } | ||
226 | } else { | 291 | } else { |
227 | $("#main-container").hide(); | 292 | $("#main-container").hide(); |
228 | $("#finish").fadeIn(500); | 293 | $("#finish").fadeIn(500); |