# -*- coding: utf-8 -*- from flask import request, make_response from werkzeug import secure_filename import pbclient import os import pyutil import checkout import requests import shutil import tempfile class Corretor: def __init__(self, configuration, template_env): self.config = configuration self.env = template_env self.__setup_pb_client() self.__setup_upload_folder() def __setup_pb_client(self): pbclient.set('endpoint', self.config['PYBOSSA_ENDPOINT']) pbclient.set('api_key', self.config['PYBOSSA_API_KEY']) def __setup_upload_folder(self): upload_folder = self.config['UPLOAD_FOLDER'] if not os.path.exists(upload_folder): os.makedirs(upload_folder) def __find_project(self, app_short_name): projects = pbclient.find_project(short_name=app_short_name) return projects[0] if len(projects) > 0 else None def __setup_project(self, project): self.__update_project_info(project) def __setup_project(self, project): #self.__create_tasks(project) self.__update_project_info(project) def __create_tasks(self, project): test_signs = ["ENSINADO", "ENTANTO", "ENTENDIDO"] for sign in test_signs: task = dict(sign_name=sign, submission_date=pyutil.get_date_now()) pbclient.create_task(project.id, task) def __update_project_info(self, project): template = self.env.get_template('index.html') project.info['task_presenter'] = template.render(server=self.config['HOST_STATIC_FILES_ENDPOINT'], server_backend=self.config['HOST_ENDPOINT'], app_shortname=self.config['PYBOSSA_APP_SHORT_NAME']) project.info['thumbnail'] = self.config['HOST_STATIC_FILES_ENDPOINT'] + "/img/thumbnail.png" project.info['sched'] = "incremental" project.info['published'] = True project.allow_anonymous_contributors = False pbclient.update_project(project) def __find_task(self, project_id, task_id): tasks = pbclient.find_tasks(project_id, id=task_id) return tasks[0] if len(tasks) > 0 else None def __find_taskruns(self, project_id, task_id): return pbclient.find_taskruns(project_id, id=task_id) def __number_of_taskruns(self, project_id, task_id): taskruns = self.__find_taskruns(project_id, task_id) return len(taskruns) def __close_task(self, project_id, task_id): pyutil.log("Closing the task with ID=" + str(task_id) + ".") task = self.__find_task(project_id, task_id) number_of_taskruns = self.__number_of_taskruns(project_id, task_id) task.n_answers = number_of_taskruns + 1 pbclient.update_task(task) return "The task with ID=" + str(task_id) + " was closed." def finish_task(self): user_id = request.form['upload_session_id'] pyutil.log(str(user_id)) task_id = request.form['task_id'] api_host = self.config['SERVER_HOST'] api_dbhost = self.config['API_DB_HOST'] sign_name = request.form['sign_name'] project_id = request.form['project_id'] number_of_approval = int(request.form['number_of_approval']) agreement_number = self.config['AGREEMENT_NUMBER'] result_msg = "" code = 200 if (number_of_approval >= agreement_number): tmp_dir = tempfile.NamedTemporaryFile().name if not os.path.exists(tmp_dir): os.makedirs(tmp_dir) blend_path = os.path.join(tmp_dir, sign_name + ".blend") video_path = os.path.join(tmp_dir, sign_name + ".webm") blend_url = ('http://%s/corretor/uploads/%s/%s.blend' % (api_host, user_id, sign_name)) video_url = ('http://%s/corretor/uploads/%s/%s.webm' % (api_host, user_id, sign_name)) blend_downloaded = self.get_file(blend_url, blend_path) video_downloaded = self.get_file(video_url, video_path) if (blend_downloaded and video_downloaded): files_to_upload = [ ("video", (video_path, open(video_path,"rb"))), ("video", (blend_path, open(blend_path, "rb"))) ] values = { "nome": sign_name, "selo": 5, "wikilibras": True, "overwrite": True } r = requests.post(("%s/addsinal" % (api_dbhost)), files=files_to_upload, data=values) pyutil.log("Request: " + str(r)) pyutil.log(str(r.headers)) shutil.rmtree(tmp_dir) else: pyutil.log("files: %s or %s was not downloaded" % (blend_url, video_url)) result_msg = self.__close_task(project_id, task_id) else: result_msg = "The task with ID=" + str(task_id) + " didn't reach the agreement number yet." pyutil.log(result_msg) return make_response(result_msg, code) def render_video(self): upload_session_id = request.form['upload_session_id'] sign_name = request.form['sign_name'] upload_dir = os.path.join(self.config['UPLOAD_FOLDER'], upload_session_id) blend_file = os.path.join(upload_dir, sign_name + ".blend") checkout_result = checkout.render_video(upload_dir, blend_file, sign_name) pyutil.log("render_video code: " + str(checkout_result)) code = 0 result_msg = "" if(checkout_result == 0): result_msg = "Successfully rendered the video." code = 200 else: result_msg = "Error while rendering the video." code = 400 pyutil.log(result_msg) return make_response(result_msg, code) def create_project(self): app_short_name = self.config['PYBOSSA_APP_SHORT_NAME'] project = self.__find_project(app_short_name) result_msg = "" if (project): result_msg = "The project " + app_short_name + " was already created." else: project = pbclient.create_project(self.config['PYBOSSA_APP_NAME'], app_short_name, self.config['PYBOSSA_APP_DESCRIPTION']) if (project): self.__setup_project(project) result_msg = "The project " + app_short_name + " was created." else: result_msg = "The project " + app_short_name + " couldn't be created. Check the server log for details." pyutil.log(result_msg) return result_msg def update_project(self): app_short_name = self.config['PYBOSSA_APP_SHORT_NAME'] project = self.__find_project(app_short_name) self.__update_project_info(project) result_msg = "The project " + app_short_name + " was updated." pyutil.log(result_msg) return result_msg def __allowed_file(self, filename): allowed_extensions = set(['blend']) return '.' in filename and filename.rsplit('.', 1)[1] in allowed_extensions def get_file(self, url, filename): r = requests.get(url, stream = True) if (r.status_code == 200): with open(filename, 'wb') as f: for chunk in r.iter_content(chunk_size = 1024): if chunk: f.write(chunk) return True return False def upload_file(self): upload_session_id = request.form['upload_session_id'] sign_name = request.form['sign_name'] file = request.files['file'] result_msg = "" code = 400 if (not pyutil.is_int(upload_session_id)): result_msg = "Invalid upload session id: " + upload_session_id elif file and not self.__allowed_file(file.filename): result_msg = file.filename + " extension is not acceptable." else: filename = secure_filename(file.filename) upload_dir = os.path.join(self.config['UPLOAD_FOLDER'], upload_session_id) if not os.path.exists(upload_dir): os.makedirs(upload_dir) uploaded_file = os.path.join(upload_dir, filename) file.save(uploaded_file) renamed_file = os.path.join(upload_dir, secure_filename(sign_name + ".blend")) os.rename(uploaded_file, renamed_file) checkout_result = checkout.check_action(renamed_file, sign_name) pyutil.log("checkout_result code: " + str(checkout_result)) if (checkout_result == 0): result_msg = "File " + filename + " was uploaded." code = 200 else: result_msg = "File " + filename + " has not expected structure of blend file. " code = 400 pyutil.log(result_msg) return make_response(result_msg, code)