Commit 78ae61e282c99b3000782d6b7635f9448aa6295f

Authored by Adabriand Furtado
1 parent 44e216fd
Exists in master

Interface inicial do 2o loop da tarefa e file upload modificado para salvar numa pasta de sessão

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

7.33 KB | W: | H:

34.6 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin
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);