task_manager.py 8.88 KB
# -*- coding: UTF-8 -*-

import json
import os
import pbclient
import pyutil
import requests
import shutil
import logging

def load_json(filename):
    r = {}
    try:
        fp = open(filename, 'r')
        if (fp):
            r = json.load(fp)
        fp.close()
    except:
        pass
    return r

def save_json(data, filename, idt = 4):
    try:
        fp = open(filename, 'w')
        if (fp):
            json.dump(data, fp, ensure_ascii = False, indent = idt, sort_keys = True)
        fp.close()
    except:
        pyutil.print_stack_trace()
        return False
    return True

class task_config():
    def __init__(self, json_data):
        self.data = {}
        self.data["db_host"] = json_data.get("db_host", "localhost")
        self.data["db_timeout"] = json_data.get("db_timeout", 30)
        self.data["db_port"] = json_data.get("db_port", 200)
        self.data["pb_api_key"] = json_data.get("pb_api_key", "")
        self.data["pb_endpoint"] = json_data.get("pb_endpoint", "http://localhost/pybossa/")
        self.data["corretor"] = dict(json_data.get("corretor", {}))
        self.data["validador"] = dict(json_data.get("validador", {}))
        self.data["wikilibras"] = dict(json_data.get("wikilibras", {}))
        self.set_pb_config(self.data["pb_api_key"], self.data["pb_endpoint"])
        self.data["corretor"]["project_id"] = self.get_pb_project_id(self.data["corretor"]["short_name"])
        self.data["validador"]["project_id"] = self.get_pb_project_id(self.data["validador"]["short_name"])
        self.data["wikilibras"]["project_id"] = self.get_pb_project_id(self.data["wikilibras"]["short_name"])
        logging.getLogger("requests").setLevel(logging.ERROR)

    def set_pb_config(self, pb_api_key, pb_endpoint):
        pbclient.set('api_key', self.data["pb_api_key"])
        pbclient.set('endpoint', self.data["pb_endpoint"])

    def get_pb_project_id(self, pb_short_name):
        projects = pbclient.find_project(short_name = pb_short_name)
        if (len(projects) > 0):
            return projects[0].id
        else:
            return None

    def to_string(self):
        return json.dumps(self.data, sort_keys = True, ensure_ascii = False, indent = 4)

    def __get__(self, endpoint):
        try:
            r = requests.get(('http://%s:%s/%s' % (self.data["db_host"], self.data["db_port"], endpoint)), timeout = self.data["db_timeout"])
            return r
        except:
            return {}

    def get_data_by_version(self, version):
        r = self.__get__("sinais?version=%d" % (version))
        if (r != {}):
            # pyutil.log(json.dumps(r.json(), ensure_ascii = False, indent = 4))
            return r.json()
        else:
            return []

    def get_data_by_version_selo(self, version, selo):
        r = self.__get__("sinais?version=%d&selo=%s" % (version, selo))
        if (r != {}):
            # pyutil.log(json.dumps(r.json(), ensure_ascii = False, indent = 4))
            return r.json()
        else:
            return []

    def get_data_by_selo(self, selo):
        r = self.__get__("sinais?&selo=%s" % (selo))
        if (r != {}):
            # pyutil.log(json.dumps(r.json(), ensure_ascii = False, indent = 4))
            return r.json()
        else:
            return []

    def get_listall(self):
        r = self.__get__("listall")
        if (r != {}):
            # pyutil.log(json.dumps(r.json(), ensure_ascii = False, indent = 4))
            return r.json()
        else:
            return []

    def get_version(self):
        r = self.__get__("version")
        if (r != {}):
            version = r.json()["version"]
            if (isinstance(version, int)):
                return version
        return 0

    def get_file(self, url, filename):
        try:
            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
        except:
            pass
        return False

    def run(self, project):
        try:
            video_path = project.get("video_path", "view/videos")
            proj_name = project.get("short_name", "")
            proj_id = project.get("project_id", "")
            database = os.path.join(os.path.dirname(os.path.abspath('__file__')), "database.json")
            database_bak = database + ".bak"
            control = load_json(database)
            changed = False
            # server_version = self.get_version()
            # for i in range(1, server_version + 1):
            dbquery = None

            # selos
            # 1 - wikilibras
            # 2 - especialista
            # 3 - invalido_wikilibras
            # 4 - invalido_especialista
            # 5 - animadores
            # 6 - invalido_animadores
            # 7 - null

            if (proj_name == "corretor_sinais"):
                dbquery = self.get_data_by_selo("invalido_especialista")

            if (proj_name == "validador_sinais"):
                dbquery = self.get_data_by_selo("wikilibras") + self.get_data_by_selo("animadores")

            if (proj_name == "wikilibras"):
                dbquery = self.get_data_by_selo("null")

            for j in dbquery:
                add_task = False
                current_sinal_name = str(j["nome"]).upper()
                current_version = int(j["version"])

                if (current_sinal_name in control):
                    if (control[current_sinal_name] < current_version):
                        control[current_sinal_name] = current_version
                        changed = True
                        add_task = True
                else:
                    control[current_sinal_name] = current_version
                    changed = True
                    add_task = True

                if(add_task):
                    avatar_url = "http://%s:%s/blender/%s" % (str(self.data["db_host"]), str(self.data["db_port"]), str(j[u"nome"] + ".blend"))
                    video_ref_url = "http://%s:%s/%s" % (str(self.data["db_host"]), str(self.data["db_port"]), str(j[u"file"]))
                    video_ava_url = "http://%s:%s/avatar/%s" % (str(self.data["db_host"]), str(self.data["db_port"]), str(j[u"nome"] + ".webm"))

                    avatar_out = os.path.join(video_path, str(j[u"nome"] + "_AVATAR.blend"))
                    video_ref_out = os.path.join(video_path, str(j[u"nome"] + "_REF.webm"))
                    video_ava_out = os.path.join(video_path, str(j[u"nome"] + "_AVATAR.webm"))

                    # cria diretorio de destino caso nao exista
                    if not os.path.exists(video_path):
                        os.makedirs(video_path)

                    # remove arquivos existentes relativos a pasta "avatar_out"
                    if pyutil.file_exists(avatar_out):
                        os.unlink(avatar_out)

                    # remove arquivos existentes relativos a pasta "video_ref_out"
                    if pyutil.file_exists(video_ref_out):
                        os.unlink(video_ref_out)

                    # remove arquivos existentes relativos a pasta "video_ava_out"
                    if pyutil.file_exists(video_ava_out):
                        os.unlink(video_ava_out)

                    # faz download do arquivo blend
                    self.get_file(avatar_url, avatar_out)

                    # faz download do video renderizado
                    self.get_file(video_ava_url, video_ava_out)

                    # faz download do video de referencia
                    if (self.get_file(video_ref_url, video_ref_out)):
                        pyutil.log("%s: creating task: %s version: %s stamp: %s" % (proj_name, j[u"nome"], j[u"version"], j[u"nomeSelo"]))
                        task = dict(sign_name = j[u"nome"], submission_date = pyutil.get_date_now())
                        response_task = pbclient.create_task(proj_id, task)
                        pyutil.log(str(response_task))
                    else:
                        # nao foi possivel fazer o download do video de referencia (tarefa nao adicionada)
                        pyutil.log("%s: file not found: %s" % (proj_name, video_ref_url))

                if (changed):
                    # verifica se arquivo database.json existe para realizar backup
                    if ((os.path.isfile(database) == 1) and (os.path.exists(database) == 1)):

                        # verifica se arquivo database.json.bak existe para remover
                        if ((os.path.isfile(database_bak) == 1) and (os.path.exists(database_bak) == 1)):
                            os.remove(database_bak)

                        # faz backup antes de salvar nova base de dados
                        shutil.copy(database, database_bak)

                    # salva nova base de dados
                    save_json(control, database, 2)
        except:
            pyutil.print_stack_trace()