def initData(self, task_config=None, file_extension=None): if task_config is None: return False self.path_local = task_config.get("local", '') self.path_version = task_config.get("version", '') self.path_publish = task_config.get("publish", '') self.base_name = task_config.get("name", None) self.ver_padding = int(task_config.get("ver_padding", 3)) self.ver_prefix = task_config.get("ver_prefix", None) self.extension = capp.HOST_EXT[ 0] if file_extension is None else file_extension if self.base_name is None: return False self.__regexp = re.compile(u"{0}({1})(\d{{0,{2}}})({3})\Z".format( re.escape(self.base_name), utils.string_unicode(r"\w*") if self.ver_prefix is None else re.escape(self.ver_prefix), 4 if self.ver_padding is None else self.ver_padding, utils.string_unicode("\.[a-zA-Z]+") if self.extension is None else re.escape(self.extension))) self.__regexpAll = re.compile( u"({0})\w*({1})(\d{{0,{2}}})({3})\Z".format( '|'.join( [re.escape(n) for n in task_config.get("name_list", [])]), utils.string_unicode(r"\w*") if self.ver_prefix is None else re.escape(self.ver_prefix), 4 if self.ver_padding is None else self.ver_padding, utils.string_unicode("\.[a-zA-Z]+") if self.extension is None else re.escape(self.extension))) MAKE_PRINT_INFO_AND_DEBUG = None return True
def z_task_statuses(self, task_id): rstatuses = [] if not task_id is None: pstatuses = self.db.task_possible_statuses(task_id) pstatuses.sort(key=lambda val: val[dbtypes.STATUS_DATA_ORDER]) rstatuses = [[utils.string_unicode(st[dbtypes.STATUS_DATA_NAME]), int(st[dbtypes.STATUS_DATA_ID]), st[dbtypes.STATUS_DATA_FLAGS]] for st in pstatuses if st[dbtypes.STATUS_DATA_NAME] is not None] return rstatuses
def set_profile(self, acc): self.user_id = self.db.current_user_id() self.current_acc = acc if self.current_acc.get('login', '') == '': lg = self.db.execute('select * from "getUserLogin_byID"(%s)', self.user_id) self.current_acc['login'] = lg[0][0] self.current_acc.update({'id': self.user_id}) self.users = self.db.users() self.statuses = self.db.statuses() for u in self.users: id = int(u[dbtypes.USER_DATA_ID]) if id == self.user_id: self.user_name = utils.string_unicode(u[dbtypes.USER_DATA_FULL_NAME]) break self.log.debug('User id: %s', self.user_id) self.log.info('User name: %s', self.user_name) self.user_dir = self.current_acc.get('savepath', '') if not os.path.exists(self.user_dir): self.user_dir = self.select_work_directory() self.current_acc.update({'savepath': self.user_dir}) self.config.set_local_dir(self.user_dir) self.log.info('Save directory: %s', self.user_dir)
def z_thumbnails(self, fpath): tmp_dir = os.path.normpath(utils.tempdir()) mp = self.config.mirada() thumbs = [] if mp is not None and os.path.isfile(fpath): self.log.info("Generating thumbnails via Mirada for file: %s", fpath) if not utils.PY3: mp, fpath = utils.string_unicode(mp).encode(locale.getpreferredencoding()), utils.string_unicode(fpath).encode(locale.getpreferredencoding()) subprocess.call('"{0}" "{1}" --mode thumbstandalone --temp "{2}"'.format(mp, fpath, tmp_dir)) fname = os.path.basename(fpath) thumbs = [os.path.normpath(os.path.join(tmp_dir, t)) for t in os.listdir(tmp_dir) if t.startswith(fname)] if not utils.PY3: thumbs = [unicode(t.decode(locale.getpreferredencoding())) for t in thumbs] self.log.debug("Mirada generated: %s", thumbs) return thumbs
def send_message(self): msg = utils.string_unicode(self.te_message.toPlainText()) if len(msg) == 0 or self.task_id is None: return False send_links = {} send_attach = {} for fpath, as_link in self.attachments.items(): fpath = os.path.normpath(fpath) # Generate thumbnails thumbs = self.fman.z_thumbnails(fpath) if as_link: send_links[fpath] = thumbs else: send_attach[fpath] = thumbs newmsg = self.conn.send_message(self.task_id, msg, send_links, send_attach) if newmsg is not None: self.refresh.emit() self.clear() self.stop() return True return False
def update_savename(self): self.config.set_task_filename(self.task_id, utils.string_unicode(self.cb_taskFile.currentText())) self.fvers.setConfig(self.config.translate(self.task)) self.pb_publish.setEnabled(self.fvers.publish_path() is not None or self.fvers.next_version_path() is not None) ver = self.fvers.next_version if self.fvers.next_version_path() is not None else self.fvers.publish if not self.fvers.is_empty: self.le_taskFile.setText(ver[len(self.fvers.base_name):]) else: self.le_taskFile.clear()
def z_open_task_cerebro(self): task_id = self.config.task_for_file(capp.file_name(self.log)) task = self.db.task(task_id) if task is not None: webbrowser.open(utils.string_unicode(r"cerebro://{0}?tid={1}").format(task["path"] + task["name"], task_id)) return True return False
def sendReport(self): if self.task is None: self.log.error('No select task to publish') return False res = False opname = 'Save as New Version' if self.to_publish: opname = 'Publish' self.log.info('%s started...', opname) self.log.info('Task: %s', self.task["path"] + self.task["name"]) # Status status = None if self.cb_status.currentIndex() >= 0: status = self.statuses[self.cb_status.currentIndex()][1] # Text text = utils.string_unicode(self.te_report.toPlainText()) # Time h, m = self.cb_time.currentText().split("h ") h = int(h) if len(h) > 0 else 0 m = m.split("m")[0] m = int(m) if len(m) > 0 else 0 work_time = h * 60 + m try: processdata = {"local_file_path": u"", "version_file_path": u"", "publish_file_path": u"", "report": {}, "attachments": {}, "links": {}} processdata["report"]["plain_text"] = text processdata["report"]["work_time"] = work_time for fpath, as_link in self.attachments.items(): fpath = os.path.normpath(fpath) if as_link: processdata["links"][fpath] = [] else: processdata["attachments"][fpath] = [] version_file = None if self.to_publish and self.fvers.publish_path() is not None: version_file = self.fman.publish(self.task, processdata, status, self.ver_thumb, self.hashtags, self.cb_version.isChecked()) else: version_file = self.fman.version(self.task, processdata, status, self.ver_thumb, self.hashtags) if version_file: self.log.info('%s has been successfully.', opname) res = True self.conn.refresh_task(self.task_id) if res: self.stop() except Exception as err: self.log.error('EXCEPTION', exc_info=1) wapp.error(utils.error_unicode(err)) return res
def setFilter(self, text=None): if text is None or len(text) == 0: for i in range(self.tableWidget.rowCount()): self.tableWidget.setRowHidden(i, False) else: text = utils.string_unicode(text) for i in range(self.tableWidget.rowCount()): match = False cell = self.tableWidget.item(i, 0) if cell is not None and cell.contains(text): match = True self.tableWidget.setRowHidden(i, not match)
def trylogin(self): lgn = utils.string_unicode( self.cb_username.currentText()).lower().strip() psw = utils.string_unicode(self.le_password.text()).strip() url = utils.string_unicode(self.le_url.text()).lower().strip() if lgn != '' and psw != '': if self.acc.get('login', '') != lgn: acc = {} acc.setdefault('login', lgn) acc.setdefault('psw', psw) acc.setdefault('savepath', '') acc.setdefault('url', url) self.acc = acc self.acc.update({'login': lgn}) self.acc.update({'psw': psw}) self.acc.update({'url': url}) if self.login_as(self.acc): self.accept()
def file_name(self, file_path): if file_path is None: return None file_name = os.path.basename(file_path) base_name = u"" if self.ver_prefix is not None and self.ver_prefix in file_name: regexp = re.compile(u"(\w+){0}\w+{1}\Z".format( self.ver_prefix, utils.string_unicode("\.[a-zA-Z]+") if self.extension is None else re.escape(self.extension))) m = regexp.match(file_name) if m is not None: base_name = m.group(1) else: base_name = os.path.splitext(file_name)[0] return base_name
def load_config(self): self.log.debug('Loading connection config started...') self.cfg = jsonio.read(os.path.join(utils.configdir(), '.ula')) self.cfg.setdefault('autologin', True) self.cfg.setdefault('remember', True) self.cfg.setdefault('lastlogin', None) self.cfg.setdefault('accounts', []) accs = self.cfg.get('accounts') for acc in accs: if acc.get('psw'): try: acc["psw"] = utils.string_unicode(base64.b64decode(utils.string_byte(acc["psw"]))[:-len(acc["login"])]) except Exception: acc["psw"] = u'' self.log.debug('Autologin: %s, Remember: %s, Lastlogin: %s', self.cfg.get('autologin'), self.cfg.get('remember'), self.cfg.get('lastlogin')) self.log.debug('Loading connection config has been successfully.')
def __popupAt(self, pos): index = self.tableWidget.indexAt(pos) if not index.isValid(): return taskPath = None taskCerebro = None if self.task_id is not None: task = self.conn.task(self.task_id) if task is not None: task_paths = self.config.translate(task) taskCerebro = task["path"] + task["name"] taskPath = task_paths["publish"] if len( task_paths.get("publish", "")) > 0 else task_paths.get( "version", None) menu_options = [ "Open in Cerebro...", None, "Copy local path to Clipboard", "Show in Explorer..." ] res = wapp.menu(task, self.tableWidget.viewport().mapToGlobal(pos), menu_options, "menu_task") if res is not None: if res in menu_options and len(taskPath) and len( taskCerebro): if res == menu_options[0]: webbrowser.open( utils.string_unicode( r"cerebro://{0}?tid={1}").format( taskCerebro, self.task_id)) elif res == menu_options[2]: capp.copyToClipboard(taskPath) elif res == menu_options[3]: if not utils.show_dir(taskPath): wapp.error( "Directory does not exist: {}".format( taskPath)) else: # Hook used - update task data self.refresh.emit()
def save_config(self): self.log.debug('Save connection config started...') if self.current_acc and self.current_acc.get('id'): accs = self.cfg.get('accounts') self.cfg.update({'lastlogin': self.user_id}) saved = False for index, account in enumerate(accs): if account.get('id') == self.user_id: accs[index] = self.current_acc if not self.cfg.get('remember'): accs[index]['psw'] = u'' saved = True break if not saved: accs.insert(0, self.current_acc) if not self.cfg.get('remember'): accs[0]['psw'] = u'' """ else: self.cfg.update({'lastlogin': None}) for index, account in enumerate(accs): if account.get('id') == self.user_id: #accs.pop(index) accs[index]['psw'] = u'' break """ self.cfg.update({'accounts': accs}) save_cfg = copy.deepcopy(self.cfg) for acc in save_cfg["accounts"]: acc["psw"] = utils.string_unicode(base64.b64encode(utils.string_byte(acc["psw"] + acc["login"]))) jsonio.write(os.path.join(utils.configdir(), '.ula'), save_cfg) self.log.debug('Save connection config has been successfully.')
def start(self): server_address = ('localhost', standalone.SERVER_PORT) self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.bind(server_address) self.sock.listen(1) while not self.flag_stop: connection, client_address = self.sock.accept() data = standalone.recvall(connection) value = json.loads(utils.string_unicode(data)) response = { "function" : value["function"], "args": [], "versionMajor": standalone.VERSION_MAJOR, "versionMinor": standalone.VERSION_MINOR } if value["function"] == "check": if int(value["versionMajor"]) == standalone.VERSION_MAJOR: response["args"] = ["OK"] else: response["args"] = ["Incompatible protocol version"] connection.sendall(utils.string_byte(json.dumps(response))) connection.close() elif value["function"] == "menu_todolist": connection.close() menu.todolist() elif value["function"] == "menu_browser": connection.close() menu.browser() elif value["function"] == "menu_createreport": connection.close() menu.createreport() elif value["function"] == "menu_publish": connection.close() menu.publish() elif value["function"] == "menu_logout": connection.close() menu.logout() elif value["function"] == "menu_workdir": connection.close() menu.workdir() elif value["function"] == "menu_about": connection.close() menu.about() elif value["function"] == "stop": self.flag_stop = True connection.close() else: response["args"] = ["Unknown function name"] connection.sendall(utils.string_byte(json.dumps(response))) connection.close() self.sock.close() return 0
def update_tasks(self, tasks_db): if tasks_db is None: return False # Update universe IDs prj_ids = { int(t[dbtypes.TASK_DATA_PROJECT_ID]) for t in tasks_db if t is not None } for id in prj_ids: if id not in self.unid_by_prjid: self.unid_by_prjid[id] = int(self.db.execute('select * from "getUnid_byPrj"(%s)', id)[0][0]) if self.unid_by_prjid[id] not in self.config.config_pool: cfg = jsonio.parse(self.db.execute('select * from "attributeUniverse"(%s, 120)', self.unid_by_prjid[id])[0][0]) self.config.set_config(self.unid_by_prjid[id], cfg) # Current timestamp current_time = time.time() for t in tasks_db: if t is None: continue task = {} # ID task["id"] = int(t[dbtypes.TASK_DATA_ID]) # Thumb - moved to async thread task["thumbnail"] = None task["thumb_hashes"] = t[dbtypes.TASK_DATA_THUMBS] # Name task["name"] = utils.string_unicode(t[dbtypes.TASK_DATA_NAME]) # Path task["path"] = utils.string_unicode(t[dbtypes.TASK_DATA_PARENT_URL]) task["path_repr"] = task["path"][1:-1].replace("/", " > ") # UserID that has task in progress task["owned_user_id"] = None task["uname"] = None task["enabled_task"] = True # Status status_code = t[dbtypes.TASK_DATA_SELF_STATUS] status_name = "" status_xpm = None status_icon = None status_order = 0 for st in self.statuses: if status_code == st[dbtypes.STATUS_DATA_ID]: if cclib.has_flag(st[dbtypes.STATUS_DATA_FLAGS], dbtypes.STATUS_FLAG_WORK_STARTED): task["owned_user_id"] = 0 task["enabled_task"] = False status_name = st[dbtypes.STATUS_DATA_NAME] status_xpm = st[dbtypes.STATUS_DATA_ICON] status_order = int(st[dbtypes.STATUS_DATA_ORDER]) if len(st) > dbtypes.STATUS_DATA_ICON_HASH: if st[dbtypes.STATUS_DATA_ICON_HASH] not in self.cache_status: self.cache_status[st[dbtypes.STATUS_DATA_ICON_HASH]] = self.cargo.file(st[dbtypes.STATUS_DATA_ICON_HASH]) status_icon = self.cache_status[st[dbtypes.STATUS_DATA_ICON_HASH]] break if status_name is None: status_name = "" task["status"] = utils.string_unicode(status_name) task["status_id"] = int(status_code) if status_code is not None else status_code task["status_xpm"] = utils.string_byte(status_xpm) if status_xpm is not None else None task["status_icon"] = status_icon task["status_order"] = status_order # Start start = t[dbtypes.TASK_DATA_HUMAN_START] if start is None: start = t[dbtypes.TASK_DATA_OFFSET] task["start"] = datetime.datetime(2000, 1, 1, 3) + datetime.timedelta(start) # End end = t[dbtypes.TASK_DATA_HUMAN_FINISH] if end is None: end = start + (t[dbtypes.TASK_DATA_DURATION] if t[dbtypes.TASK_DATA_DURATION] is not None else 0) task["end"] = datetime.datetime(2000, 1, 1, 3) + datetime.timedelta(end) # Progress task["progress"] = t[dbtypes.TASK_DATA_PROGRESS] # Activity name task["activity"] = utils.string_unicode(t[dbtypes.TASK_DATA_ACTIVITY_NAME]) task["activity_id"] = int(t[dbtypes.TASK_DATA_ACTIVITY_ID]) # Has child tasks task["is_folder"] = cclib.has_flag(t[dbtypes.TASK_DATA_FLAGS], dbtypes.TASK_FLAG_HAS_CHILD) # Parent task task["parent"] = int(t[dbtypes.TASK_DATA_PARENT_ID]) # Empty files #task["files"] = None # Empty task definition task["definition"] = "" task["messages"] = [] # Config valid status task["valid_task"] = None task["valid_parent"] = None # Config name editable task["name_editable"] = False # Publish status name task["publish_status"] = None # Universe ID task["unid"] = self.unid_by_prjid[int(t[dbtypes.TASK_DATA_PROJECT_ID])] # Updated ts task["last_update"] = current_time # Task order from db task["order"] = int(t[dbtypes.TASK_DATA_ORDER]) # Custom color indicator task["indicator"] = None self.tasks_requested.append(task["id"]) self.alltasks[task["id"]] = task return True
def z_task_files(self, task_id): if task_id is None: return None with self.lock_cache: files = {} self.alltasks[task_id]["definition"] = "" self.alltasks[task_id]["messages"] = [] task_msgs = self.db.task_messages(task_id) # Append local and publish files conf = self.config.translate(self.alltasks[task_id]) fvers = vfile.VFile(conf) publish, local = fvers.publish_path(), fvers.local_path() local_versions = fvers.versionsAll.copy() last_versions = {} for filename, ver in local_versions.items(): if last_versions.get(ver[0], (-1, ''))[0] < ver[1]: last_versions[ver[0]] = (ver[1], filename) last_versions = [ f[1] for f in last_versions.values() ] if publish is not None and os.path.exists(publish) and os.path.splitext(publish)[1] in capp.HOST_EXT: file = {} file["name"] = os.path.basename(publish) file["path"] = utils.np(publish) file["thumbnail"] = None file["id"] = -1 file["version"] = None file["is_last_version"] = False file["date"] = datetime.datetime.fromtimestamp(os.path.getmtime(publish)) file["task_id"] = task_id files[file["id"]] = file if local is not None and os.path.exists(local) and os.path.splitext(local)[1] in capp.HOST_EXT: file = {} file["name"] = os.path.basename(local) file["path"] = utils.np(local) file["thumbnail"] = None file["id"] = -2 file["version"] = self.config.version_for_file(file["path"]) file["is_last_version"] = False file["date"] = datetime.datetime.fromtimestamp(os.path.getmtime(local)) file["task_id"] = task_id files[file["id"]] = file msgids = [] for m in task_msgs: # message fields msgid = int(m[dbtypes.MESSAGE_DATA_ID]) date = m[dbtypes.MESSAGE_DATA_CREATED] author = m[dbtypes.MESSAGE_DATA_CREATOR_NAME] msgids.append(msgid) # check uid if task is in progress if self.alltasks[task_id]["owned_user_id"] is not None and m[dbtypes.MESSAGE_DATA_TYPE] == dbtypes.MESSAGE_TYPE_STATUS_CHANGES: self.alltasks[task_id]["owned_user_id"] = int(m[dbtypes.MESSAGE_DATA_CREATOR_ID]) self.alltasks[task_id]["uname"] = utils.string_unicode(m[dbtypes.MESSAGE_DATA_CREATOR_NAME]) # check definition if m[dbtypes.MESSAGE_DATA_TYPE] == dbtypes.MESSAGE_TYPE_DEFINITION: msg = m[dbtypes.MESSAGE_DATA_TEXT] if msg is not None: self.alltasks[task_id]["definition"] += utils.string_unicode(msg) self.alltasks[task_id]["definition"] += '\n' if m[dbtypes.MESSAGE_DATA_TYPE] != dbtypes.MESSAGE_TYPE_DEFINITION: msg = m[dbtypes.MESSAGE_DATA_TEXT] if msg is not None: text = date.strftime("%d.%m.%Y") if not utils.PY3: text = text.decode(locale.getpreferredencoding()) self.alltasks[task_id]["messages"].insert(0, {'author' : utils.string_unicode(author), 'date' : text, 'msg' : utils.string_unicode(msg) }) dbfiles = self.db.message_attachments(set(msgids)) link_files = { f[dbtypes.ATTACHMENT_DATA_GROUP_ID] : {"id" : int(f[dbtypes.ATTACHMENT_DATA_ID]), "path" : utils.string_unicode(f[dbtypes.ATTACHMENT_DATA_FILE_NAME]), "thumbs" : [], "date" : f[dbtypes.ATTACHMENT_DATA_CREATED] } for f in dbfiles if f[dbtypes.ATTACHMENT_DATA_TAG] == dbtypes.ATTACHMENT_TAG_LINK } for f in dbfiles: if f[dbtypes.ATTACHMENT_DATA_GROUP_ID] in link_files and f[dbtypes.ATTACHMENT_DATA_TAG] == dbtypes.ATTACHMENT_TAG_THUMB1: link_files[f[dbtypes.ATTACHMENT_DATA_GROUP_ID]]["thumbs"].append(f[dbtypes.ATTACHMENT_DATA_HASH]) unique_paths = set() for f in link_files.values(): file_thumb = None for hash_db in reversed(f["thumbs"]): file_thumb = self.cargo.file(hash_db) if file_thumb is not None: break path = f["path"] if os.path.splitext(path)[1] in capp.HOST_EXT: path = utils.np(self.config.redirect_path(path)) if path in unique_paths: continue unique_paths.add(path) filename = os.path.basename(path) file = {} file["name"] = filename file["path"] = path file["thumbnail"] = file_thumb file["id"] = f["id"] file["version"] = fvers.file_version(path) file["is_last_version"] = filename in last_versions file["date"] = f["date"] file["task_id"] = task_id files[file["id"]] = file for i, (filename, ver) in enumerate(local_versions.items()): path = utils.np(os.path.join(fvers.path_version, filename)) if path in unique_paths: continue unique_paths.add(path) file = {} file["name"] = filename file["path"] = path file["thumbnail"] = None file["id"] = -(3 + i) file["version"] = ver[1] file["is_last_version"] = filename in last_versions file["date"] = datetime.datetime.fromtimestamp(os.path.getmtime(path)) file["task_id"] = task_id files[file["id"]] = file if not self.alltasks[task_id]["enabled_task"]: self.alltasks[task_id]["enabled_task"] = self.alltasks[task_id]["owned_user_id"] == self.user_id self.alltasks[task_id]["files"] = files return files
def send_data(data): msg = utils.string_byte(json.dumps(data)) response = send_message(msg) res = json.loads(utils.string_unicode(response)) return res