Esempio n. 1
0
 def __init__(self, parent=None):
     super(GetAllFoldersWorker, self).__init__(parent)
     self._disk = None
     self.org_infos = None
     self._mutex = QMutex()
     self._is_work = False
     self.move_infos = None
Esempio n. 2
0
class Callback(QThread):
    '''回调显示进度'''
    def __init__(self, task, parent=None):
        super(Callback, self).__init__(parent)
        self._task = task
        self._mutex = QMutex()
        self._stopped = True
        self._emit_msg = ''

    @property
    def emit_msg(self):
        return self._emit_msg

    def run(self):
        if self._stopped:
            self._mutex.lock()
            self._stopped = False
            old_size = self._task.now_size
            old_rate = int(1000 * old_size / self._task.total_size)
            old_time = time()
            sleep(uniform(0.5, 2))
            now_size = self._task.now_size
            now_rate = int(1000 * now_size / self._task.total_size)
            now_time = time()
            if old_size != now_size and old_rate != now_rate:
                speed = change_size_unit((now_size - old_size) / (now_time - old_time)) + '/s'
                self._task.speed = speed
                self._task.rate = now_rate
                self._emit_msg = show_progress(self._task.name, self._task.total_size, self._task.now_size, speed)
            self._stopped = True
            self._mutex.unlock()
Esempio n. 3
0
 def __init__(self, parent=None):
     super(SetPwdWorker, self).__init__(parent)
     self._disk = None
     self.infos = []
     self._work_id = -1
     self._mutex = QMutex()
     self._is_work = False
Esempio n. 4
0
 def __init__(self, parent=None):
     super(RecManipulator, self).__init__(parent)
     self._disk = None
     self._mutex = QMutex()
     self._is_work = False
     self._action = None
     self._folders = []
     self._files = []
Esempio n. 5
0
 def __init__(self, parent=None):
     super(RenameMkdirWorker, self).__init__(parent)
     self._disk = None
     self._work_id = -1
     self._folder_list = None
     self.infos = None
     self._mutex = QMutex()
     self._is_work = False
Esempio n. 6
0
 def __init__(self, parent=None):
     super(DescPwdFetcher, self).__init__(parent)
     self._disk = None
     self.infos = None
     self.download = False
     self.dl_path = ""
     self._mutex = QMutex()
     self._is_work = False
Esempio n. 7
0
 def __init__(self, parent=None):
     super(GetMoreInfoWorker, self).__init__(parent)
     self._disk = None
     self._infos = None
     self._url = ''
     self._pwd = ''
     self._emit_link = False
     self._mutex = QMutex()
     self._is_work = False
Esempio n. 8
0
 def __init__(self, parent=None):
     super(CheckUpdateWorker, self).__init__(parent)
     self._ver = ''
     self._manual = False
     self._mutex = QMutex()
     self._is_work = False
     self._folder_id = None
     self._api = 'https://api.github.com/repos/rachpt/lanzou-gui/releases/latest'
     self._api_mirror = 'https://gitee.com/api/v5/repos/rachpt/lanzou-gui/releases/latest'
Esempio n. 9
0
 def __init__(self, parent=None):
     super(ListRefresher, self).__init__(parent)
     self._disk = None
     self._fid = -1
     self.r_files = True
     self.r_folders = True
     self.r_path = True
     self._mutex = QMutex()
     self._is_work = False
Esempio n. 10
0
 def __init__(self, parent=None):
     super(GetSharedInfo, self).__init__(parent)
     self._disk = None
     self.share_url = ""
     self.pwd = ""
     self.is_file = ""
     self.is_folder = ""
     self._mutex = QMutex()
     self._is_work = False
     self._pat = r"(https?://(\w[-\w]*\.)?lanzou[a-z].com/[a-z]?[-/a-zA-Z0-9]+)[^a-zA-Z0-9]*([a-zA-Z0-9]+\w+)?"
Esempio n. 11
0
 def __init__(self, thread=3, parent=None):
     super(TaskManager, self).__init__(parent)
     self._disk = None
     self._tasks = {}
     self._queues = []
     self._thread = thread
     self._count = 0
     self._mutex = QMutex()
     self._is_work = False
     self._old_msg = ""
     self._workers = {}
     self._allow_big_file = False
Esempio n. 12
0
class RemoveFilesWorker(QThread):
    '''删除文件(夹)线程'''
    msg = pyqtSignal(object, object)
    finished = pyqtSignal()

    def __init__(self, parent=None):
        super(RemoveFilesWorker, self).__init__(parent)
        self._disk = None
        self.infos = None
        self._mutex = QMutex()
        self._is_work = False

    def set_disk(self, disk):
        self._disk = disk

    def set_values(self, infos):
        self.infos = infos
        self.start()

    def __del__(self):
        self.wait()

    def stop(self):
        self._mutex.lock()
        self._is_work = False
        self._mutex.unlock()

    def run(self):
        if not self._is_work:
            self._mutex.lock()
            self._is_work = True
            if not self.infos:
                self._is_work = False
                self._mutex.unlock()
                return
            for i in self.infos:
                try:
                    self._disk.delete(i['fid'], i['is_file'])
                except TimeoutError:
                    self.msg.emit(f"删除 {i['name']} 因网络超时失败!", 3000)
                except Exception as e:
                    logger.error(f"RemoveFileWorker error: e={e}")
            self.finished.emit()
            self._is_work = False
            self._mutex.unlock()
        else:
            self.msg.emit("后台正在运行删除指令!", 3100)
Esempio n. 13
0
class GetRecListsWorker(QThread):
    '''获取回收站列表'''
    folders = pyqtSignal(object)
    infos = pyqtSignal(object, object)
    msg = pyqtSignal(str, int)

    def __init__(self, parent=None):
        super(GetRecListsWorker, self).__init__(parent)
        self._disk = None
        self._mutex = QMutex()
        self._is_work = False
        self._folder_id = None

    def set_disk(self, disk):
        self._disk = disk

    def set_values(self, fid):
        # 用于获取回收站指定文件夹内文件信息
        self._folder_id = fid
        self.start()

    def __del__(self):
        self.wait()

    def stop(self):
        self._mutex.lock()
        self._is_work = False
        self._mutex.unlock()

    def run(self):
        if not self._is_work:
            self._mutex.lock()
            self._is_work = True
            try:
                if self._folder_id:
                    file_lists = self._disk.get_rec_file_list(
                        folder_id=self._folder_id)
                    self._folder_id = None
                    self.folders.emit(file_lists)
                    raise UserWarning
                dir_lists = self._disk.get_rec_dir_list()
                file_lists = self._disk.get_rec_file_list(folder_id=-1)
                self.infos.emit(dir_lists, file_lists)
                self.msg.emit("刷新列表成功!", 2000)
            except TimeoutError:
                self.msg.emit("网络超时,请稍后重试!", 6000)
            except UserWarning:
                pass
            except Exception as e:
                logger.error(f"GetRecListsWorker error: e={e}")
            self._is_work = False
            self._mutex.unlock()
        else:
            self.msg.emit("后台正在运行,请稍后重试!", 3100)
Esempio n. 14
0
class LogoutWorker(QThread):
    '''登出'''
    succeeded = pyqtSignal()
    msg = pyqtSignal(str, int)

    def __init__(self, parent=None):
        super(LogoutWorker, self).__init__(parent)
        self._disk = None
        self.update_ui = True
        self._mutex = QMutex()
        self._is_work = False

    def set_disk(self, disk):
        self._disk = disk

    def set_values(self, update_ui=True):
        self.update_ui = update_ui
        self.start()

    def __del__(self):
        self.wait()

    def stop(self):
        self._mutex.lock()
        self._is_work = False
        self._mutex.unlock()

    def run(self):
        if not self._is_work:
            self._mutex.lock()
            self._is_work = True
            try:
                res = self._disk.logout()
                if res == LanZouCloud.SUCCESS:
                    if self.update_ui:
                        self.succeeded.emit()
                    self.msg.emit("已经退出登录!", 4000)
                else:
                    self.msg.emit("失败,请重试!", 5000)
            except TimeoutError:
                self.msg.emit("网络超时,请稍后重试!", 6000)
            except Exception as e:
                logger.error(f"LogoutWorker error: e={e}")
            self._is_work = False
            self._mutex.unlock()
        else:
            self.msg.emit("后台正在运行,请稍后重试!", 3100)
Esempio n. 15
0
 def __init__(self, parent=None):
     super(RemoveFilesWorker, self).__init__(parent)
     self._disk = None
     self.infos = None
     self._mutex = QMutex()
     self._is_work = False
Esempio n. 16
0
class GetAllFoldersWorker(QThread):
    '''获取所有文件夹name与fid,用于文件移动'''
    infos = pyqtSignal(object, object)
    msg = pyqtSignal(str, int)
    moved = pyqtSignal(bool, bool, bool)

    def __init__(self, parent=None):
        super(GetAllFoldersWorker, self).__init__(parent)
        self._disk = None
        self.org_infos = None
        self._mutex = QMutex()
        self._is_work = False
        self.move_infos = None

    def set_disk(self, disk):
        self._disk = disk

    def set_values(self, org_infos):
        self.org_infos = org_infos  # 对话框标识文件与文件夹
        self.move_infos = []  # 清除上次影响
        self.start()

    def move_file(self, infos):
        '''移动文件至新的文件夹'''
        self.move_infos = infos  # file_id, folder_id, f_name, type(size)
        self.start()

    def __del__(self):
        self.wait()

    def stop(self):
        self._mutex.lock()
        self._is_work = False
        self._mutex.unlock()

    def move_file_folder(self, info, no_err: bool, r_files: bool,
                         r_folders: bool):
        """移动文件(夹)"""
        # no_err 判断是否需要更新 UI
        if info.is_file:  # 文件
            if self._disk.move_file(info.id,
                                    info.new_id) == LanZouCloud.SUCCESS:
                self.msg.emit(f"{info.name} 移动成功!", 3000)
                no_err = True
                r_files = True
            else:
                self.msg.emit(f"移动文件{info.name}失败!", 4000)
        else:  # 文件夹
            if self._disk.move_folder(info.id,
                                      info.new_id) == LanZouCloud.SUCCESS:
                self.msg.emit(f"{info.name} 移动成功!", 3000)
                no_err = True
                r_folders = True
            else:
                self.msg.emit(f"移动文件夹 {info.name} 失败!移动的文件夹中不能包含子文件夹!", 4000)
        return no_err, r_files, r_folders

    def run(self):
        if not self._is_work:
            self._mutex.lock()
            self._is_work = True
            if self.move_infos:  # 移动文件
                no_err = False
                r_files = False
                r_folders = False
                for info in self.move_infos:
                    try:
                        no_err, r_files, r_folders = self.move_file_folder(
                            info, no_err, r_files, r_folders)
                    except TimeoutError:
                        self.msg.emit(f"移动文件(夹) {info.name} 失败,网络超时!请稍后重试",
                                      5000)
                    except Exception as e:
                        logger.error(f"GetAllFoldersWorker error: e={e}")
                        self.msg.emit(f"移动文件(夹) {info.name} 失败,未知错误!", 5000)
                if no_err:  # 没有错误就更新ui
                    sleep(2.1)  # 等一段时间后才更新文件列表
                    self.moved.emit(r_files, r_folders, False)
            else:  # 获取所有文件夹
                try:
                    self.msg.emit("网络请求中,请稍候……", 0)
                    all_dirs_dict = self._disk.get_move_folders().name_id
                    self.infos.emit(self.org_infos, all_dirs_dict)
                    self.msg.emit("", 0)  # 删除提示信息
                except TimeoutError:
                    self.msg.emit("网络超时!稍后重试", 6000)
                except Exception as e:
                    logger.error(f"GetAllFoldersWorker error: e={e}")
            self._is_work = False
            self._mutex.unlock()
        else:
            self.msg.emit("后台正在运行,请稍后重试!", 3100)
Esempio n. 17
0
class DescPwdFetcher(QThread):
    '''获取描述与提取码 线程'''
    desc = pyqtSignal(object)
    tasks = pyqtSignal(object)
    msg = pyqtSignal(object, object)

    def __init__(self, parent=None):
        super(DescPwdFetcher, self).__init__(parent)
        self._disk = None
        self.infos = None
        self.download = False
        self.dl_path = ""
        self._mutex = QMutex()
        self._is_work = False

    def set_disk(self, disk):
        self._disk = disk

    def set_values(self, infos, download=False, dl_path=""):
        self.infos = infos  # 列表的列表
        self.download = download  # 标识激发下载器
        self.dl_path = dl_path
        self.start()

    def __del__(self):
        self.wait()

    def stop(self):
        self._mutex.lock()
        self._is_work = False
        self._mutex.unlock()

    def run(self):
        if not self._is_work:
            self._mutex.lock()
            self._is_work = True
            try:
                if not self.infos:
                    raise UserWarning
                _tasks = {}
                _infos = []
                for info in self.infos:
                    if info.id:  # disk 运行
                        if info.is_file:  # 文件
                            res = self._disk.get_share_info(info.id, is_file=True)
                        else:  # 文件夹
                            res = self._disk.get_share_info(info.id, is_file=False)
                        if res.code == LanZouCloud.SUCCESS:
                            info.pwd = res.pwd
                            info.url = res.url
                            info.desc = res.desc
                        elif res.code == LanZouCloud.NETWORK_ERROR:
                            self.msg.emit("网络错误,请稍后重试!", 6000)
                            continue
                    _infos.append(info)  # info -> lanzou.gui.models.FileInfos
                    _tasks[info.url] = DlJob(infos=info, path=self.dl_path, total_file=1)
                if self.download:
                    self.tasks.emit(_tasks)
                else:  # 激发简介更新
                    self.desc.emit(_infos)
            except TimeoutError:
                self.msg.emit("网络超时,请稍后重试!", 6000)
            except UserWarning:
                pass
            except Exception as e:
                logger.error(f"GetPwdFetcher error: e={e}")
            self._is_work = False
            self._mutex.unlock()
        else:
            self.msg.emit("后台正在运行指令!请稍后重试", 3100)
Esempio n. 18
0
class RecManipulator(QThread):
    '''操作回收站'''
    msg = pyqtSignal(str, int)
    succeeded = pyqtSignal()

    def __init__(self, parent=None):
        super(RecManipulator, self).__init__(parent)
        self._disk = None
        self._mutex = QMutex()
        self._is_work = False
        self._action = None
        self._folders = []
        self._files = []

    def set_disk(self, disk):
        self._disk = disk

    def set_values(self, infos, action):
        # 操作回收站选定行
        self._action = None
        self._folders = []
        self._files = []
        for item in infos:
            if isinstance(item, RecFile):
                self._files.append(item.id)
            elif isinstance(item, RecFolder):
                self._folders.append(item.id)
        self._action = action
        self.start()

    def __del__(self):
        self.wait()

    def stop(self):
        self._mutex.lock()
        self._is_work = False
        self._mutex.unlock()

    def run(self):
        if not self._is_work:
            self._mutex.lock()
            self._is_work = True
            try:
                res = None
                if self._action == "recovery":
                    if self._files or self._folders:
                        res = self._disk.recovery_multi(
                            self._files, self._folders)
                        if res == LanZouCloud.SUCCESS:
                            self.msg.emit("选定文件(夹)恢复成功,即将刷新列表", 2500)
                elif self._action == "delete":
                    if self._files or self._folders:
                        if self._files or self._folders:
                            res = self._disk.delete_rec_multi(
                                self._files, self._folders)
                            if res == LanZouCloud.SUCCESS:
                                self.msg.emit("选定文件(夹)彻底删除成功,即将刷新列表", 2500)
                elif self._action == "clean":
                    res = self._disk.clean_rec()
                    if res == LanZouCloud.SUCCESS:
                        self.msg.emit("清空回收站成功,即将刷新列表", 2500)
                elif self._action == "recovery_all":
                    res = self._disk.recovery_all()
                    if res == LanZouCloud.SUCCESS:
                        self.msg.emit("文件(夹)全部还原成功,即将刷新列表", 2500)
                if isinstance(res, int):
                    if res == LanZouCloud.FAILED:
                        self.msg.emit("失败,请重试!", 4500)
                    elif res == LanZouCloud.NETWORK_ERROR:
                        self.msg.emit("网络错误,请稍后重试!", 4500)
                    else:
                        sleep(2.6)
                        self.succeeded.emit()
            except TimeoutError:
                self.msg.emit("网络超时,请稍后重试!", 6000)
            except Exception as e:
                logger.error(f"RecManipulator error: e={e}")
            self._is_work = False
            self._action = None
            self._folders = []
            self._files = []
            self._mutex.unlock()
        else:
            self.msg.emit("后台正在运行,请稍后重试!", 3100)
Esempio n. 19
0
class RenameMkdirWorker(QThread):
    """重命名、修改简介与新建文件夹 线程"""
    # infos = pyqtSignal(object, object)
    msg = pyqtSignal(str, int)
    update = pyqtSignal(object, object, object, object)

    def __init__(self, parent=None):
        super(RenameMkdirWorker, self).__init__(parent)
        self._disk = None
        self._work_id = -1
        self._folder_list = None
        self.infos = None
        self._mutex = QMutex()
        self._is_work = False

    def set_disk(self, disk):
        self._disk = disk

    def set_values(self, infos, work_id, folder_list):
        self.infos = infos  # 对话框标识文件与文件夹
        self._work_id = work_id
        self._folder_list = folder_list
        self.start()

    def __del__(self):
        self.wait()

    def stop(self):
        self._mutex.lock()
        self._is_work = False
        self._mutex.unlock()

    def run(self):
        if not self._is_work:
            self._mutex.lock()
            self._is_work = True

            action = self.infos[0]
            try:
                if action == 'new':  # 新建文件夹
                    new_name = self.infos[1]
                    new_des = self.infos[2]
                    if new_name in self._folder_list.keys():
                        self.msg.emit(f"文件夹已存在:{new_name}", 7000)
                    else:
                        res = self._disk.mkdir(self._work_id, new_name,
                                               new_des)
                        if res == LanZouCloud.MKDIR_ERROR:
                            self.msg.emit(f"创建文件夹失败:{new_name}", 7000)
                        else:
                            sleep(1.5)  # 暂停一下,否则无法获取新建的文件夹
                            self.update.emit(self._work_id, False, True,
                                             False)  # 此处仅更新文件夹,并显示
                            self.msg.emit(f"成功创建文件夹:{new_name}", 4000)
                else:  # 重命名、修改简介
                    has_file = False
                    has_folder = False
                    failed = False
                    for info in self.infos[1]:
                        if info.is_file:  # 修改文件描述
                            res = self._disk.set_desc(info.id,
                                                      info.new_des,
                                                      is_file=info.is_file)
                            if res == LanZouCloud.SUCCESS:
                                has_file = True
                            else:
                                failed = True
                        else:  # 修改文件夹,action == "folder"
                            name = info.new_name or info.nmae
                            res = self._disk._set_dir_info(
                                info.id, str(name), str(info.new_des))
                            if res == LanZouCloud.SUCCESS:
                                has_folder = True
                            else:
                                failed = True
                    self.update.emit(self._work_id, has_file, has_folder,
                                     False)
                    if failed:
                        self.msg.emit("有发生错误!", 6000)
                    else:
                        self.msg.emit("修改成功!", 4000)
            except TimeoutError:
                self.msg.emit("网络超时,请稍后重试!", 6000)
            except Exception as e:
                logger.error(f"RenameMikdirWorker error: e={e}")

            self._is_work = False
            self._mutex.unlock()
        else:
            self.msg.emit("后台正在运行,请稍后重试!", 3100)
Esempio n. 20
0
 def __init__(self, task, parent=None):
     super(Callback, self).__init__(parent)
     self._task = task
     self._mutex = QMutex()
     self._stopped = True
     self._emit_msg = ''
Esempio n. 21
0
 def __init__(self, parent=None):
     super(GetRecListsWorker, self).__init__(parent)
     self._disk = None
     self._mutex = QMutex()
     self._is_work = False
     self._folder_id = None
Esempio n. 22
0
    QHBoxLayout,
    QLabel,
    QLineEdit,
    QMessageBox,
    QProgressBar,
    QPushButton,
    QStatusBar,
    QVBoxLayout,
    QWidget,
)

WorkerRespnose = namedtuple(
    "WorkerRespnose",
    "thumb_img title author medias media_counts publish_date")

DownloadCountsMutex = QMutex()


# seperate worker thread for background processing and to avoid UI freez
class WorkerThread(QThread):
    # setup response signal
    worker_response = pyqtSignal(WorkerRespnose)
    # setup error signal
    worker_err_response = pyqtSignal()

    # additional parameter as url

    def __init__(self, media_id):
        # invoke the __init__ of super as well
        super(WorkerThread, self).__init__()
        self.media_id = media_id
Esempio n. 23
0
class ListRefresher(QThread):
    '''跟新目录文件与文件夹列表线程'''
    infos = pyqtSignal(object)
    err_msg = pyqtSignal(str, int)

    def __init__(self, parent=None):
        super(ListRefresher, self).__init__(parent)
        self._disk = None
        self._fid = -1
        self.r_files = True
        self.r_folders = True
        self.r_path = True
        self._mutex = QMutex()
        self._is_work = False

    def set_disk(self, disk):
        self._disk = disk

    def set_values(self, fid, r_files=True, r_folders=True, r_path=True):
        if not self._is_work:
            self._fid = fid
            self.r_files = r_files
            self.r_folders = r_folders
            self.r_path = r_path
            self.start()
        else:
            self.err_msg.emit("正在更新目录,请稍后再试!", 3100)

    def __del__(self):
        self.wait()

    def stop(self):
        self._mutex.lock()
        self._is_work = False
        self._mutex.unlock()

    def goto_root_dir(self):
        self._fid = -1
        self.run()

    def run(self):
        if not self._is_work:
            self._mutex.lock()
            self._is_work = True
            emit_infos = {}
            # 传递更新内容
            emit_infos['r'] = {
                'fid': self._fid,
                'files': self.r_files,
                'folders': self.r_folders,
                'path': self.r_path
            }
            try:
                if self.r_files:
                    # [i.id, i.name, i.size, i.time, i.downs, i.has_pwd, i.has_des]
                    info = {
                        i.name: i
                        for i in self._disk.get_file_list(self._fid)
                    }
                    emit_infos['file_list'] = {
                        key: info.get(key)
                        for key in sorted(info.keys())
                    }  # {name-File}
                if self.r_folders:
                    folders, full_path = self._disk.get_dir_list(self._fid)
                    if not full_path and not folders and self._fid != -1:
                        self.err_msg.emit(f"文件夹id {self._fid} 不存在,将切换到更目录",
                                          2900)
                        self._is_work = False
                        self._mutex.unlock()
                        return self.goto_root_dir()
                    info = {i.name: i for i in folders}
                    emit_infos['folder_list'] = {
                        key: info.get(key)
                        for key in sorted(info.keys())
                    }  # {name-Folder}
                    emit_infos['path_list'] = full_path
            except TimeoutError:
                self.err_msg.emit("网络超时,无法更新目录,稍后再试!", 7000)
            except Exception as e:
                self.err_msg.emit("未知错误,无法更新目录,稍后再试!", 7000)
                logger.error(f"ListRefresher error: e={e}")
            else:
                self.infos.emit(emit_infos)
            self._is_work = False
            self._mutex.unlock()
Esempio n. 24
0
class TaskManager(QThread):
    """任务控制器线程,控制后台上传下载"""
    mgr_msg = pyqtSignal(str, int)
    mgr_finished = pyqtSignal(int)
    update = pyqtSignal()

    def __init__(self, thread=3, parent=None):
        super(TaskManager, self).__init__(parent)
        self._disk = None
        self._tasks = {}
        self._queues = []
        self._thread = thread
        self._count = 0
        self._mutex = QMutex()
        self._is_work = False
        self._old_msg = ""
        self._workers = {}
        self._allow_big_file = False

    def set_allow_big_file(self, allow_big_file):
        self._allow_big_file = allow_big_file

    def set_disk(self, disk):
        self._disk = disk

    def set_thread(self, thread):
        self._thread = thread

    def stop_task(self, task):
        """暂停任务"""
        if task.url in self._workers and self._workers[task.url].isRunning():
            logger.debug(f"Stop job: {task.url}")
            try:
                self._tasks[task.url].pause = True
                self._workers[task.url].stop()
                self._tasks[task.url].run = False
            except Exception as err:
                logger.error(f"Stop task: err={err}")
        else:
            logger.debug(f"Stop job: {task.url} is not running!")
        self.update.emit()

    def start_task(self, task):
        """开始已暂停任务"""
        if task.url not in self._workers:
            self.add_task(task)
        elif not self._workers[task.url].isRunning():
            logger.debug(f"Start job: {task}")
            self._workers[task.url].start()
            self._tasks[task.url].run = True
            self._tasks[task.url].pause = False
            self.update.emit()
        self.start()

    def add_task(self, task):
        logger.debug(f"TaskMgr add one: added={task.added}, pause={task.pause}")
        if task.url not in self._tasks.keys():
            self._tasks[task.url] = task
        task.added = False
        task.pause = False
        task.info = None
        self.start()

    def add_tasks(self, tasks: dict):
        logger.debug(f"TaskMgr add: tasks={tasks}")
        self._tasks.update(tasks)
        self.start()

    def del_task(self, task):
        logger.debug(f"TaskMgr del: url={task.url}")
        if task in self._queues:
            self._queues.remove(task)
        if task.url in self._tasks:
            del self._tasks[task.url]
        if task.url in self._workers:
            del self._workers[task.url]

    def _task_to_queue(self):
        for task in self._tasks.values():
            if not task.added and not task.pause and task not in self._queues:
                logger.debug(f"TaskMgr task2queue: url={task.url}")
                self._queues.append(task)
                task.added = True

    def __del__(self):
        self.wait()

    def _ahead_msg(self, msg):
        if self._old_msg != msg:
            if self._count == 1:
                self.mgr_msg.emit(msg, 0)
            else:
                self.mgr_msg.emit(f"有{self._count}个后台任务正在运行", 0)
            self._old_msg = msg

    def _ahead_error(self):
        self.update.emit()

    def _ahead_folder_error(self, code, file):
        # 需要单独考虑,不在 task中
        pass

    def _update_emit(self):
        self.update.emit()

    def _add_thread(self, task):
        self.update.emit()
        logger.debug(f"TaskMgr count: count={self._count}")
        self._count -= 1
        del self._workers[task.url]
        # 发送所有任务完成信号
        failed_task_num = 0
        for task in self._tasks.values():
            if not task.info:
                if task.rate < 1000:
                    return None
            else:
                failed_task_num += 1
        logger.debug(f"TaskMgr all finished!: failed_task_num={failed_task_num}")
        self.mgr_finished.emit(failed_task_num)

    def stop(self):
        self._mutex.lock()
        self._is_work = False
        self._mutex.unlock()

    def run(self):
        if not self._is_work:
            self._mutex.lock()
            self._is_work = True
            while True:
                self._task_to_queue()
                if not self._queues:
                    break
                while self._count >= self._thread:
                    self.sleep(1)
                self._count += 1
                task = self._queues.pop()
                logger.debug(f"TaskMgr run: url={task.url}")
                if task.type == 'dl':
                    self._workers[task.url] = Downloader(self._disk, task, Callback)
                    self.mgr_msg.emit(f"准备下载:<font color='#FFA500'>{task.name}</font>", 0)
                else:
                    self._workers[task.url] = Uploader(self._disk, task, Callback, self._allow_big_file)
                    self.mgr_msg.emit(f"准备上传:<font color='#FFA500'>{task.name}</font>", 0)
                try:
                    self._workers[task.url].finished_.connect(self._add_thread)
                    self._workers[task.url].proc.connect(self._ahead_msg)
                    self._workers[task.url].update.connect(self._update_emit)
                    self._workers[task.url].folder_file_failed.connect(self._ahead_folder_error)
                    self._workers[task.url].failed.connect(self._ahead_error)
                    self._workers[task.url].start()
                except Exception as err:
                    logger.error(f"TaskMgr Error: err={err}")
            self._is_work = False
            self._mutex.unlock()
Esempio n. 25
0
class CheckUpdateWorker(QThread):
    '''检测软件更新'''
    infos = pyqtSignal(object, object)
    bg_update_infos = pyqtSignal(object, object)

    def __init__(self, parent=None):
        super(CheckUpdateWorker, self).__init__(parent)
        self._ver = ''
        self._manual = False
        self._mutex = QMutex()
        self._is_work = False
        self._folder_id = None
        self._api = 'https://api.github.com/repos/rachpt/lanzou-gui/releases/latest'
        self._api_mirror = 'https://gitee.com/api/v5/repos/rachpt/lanzou-gui/releases/latest'

    def set_values(self, ver: str, manual: bool = False):
        # 检查更新
        self._ver = ver
        self._manual = manual
        self.start()

    def __del__(self):
        self.wait()

    def stop(self):
        self._mutex.lock()
        self._is_work = False
        self._mutex.unlock()

    def run(self):
        if not self._is_work:
            self._mutex.lock()
            self._is_work = True
            resp = None
            try:
                resp = requests.get(self._api).json()
            except (requests.RequestException, TimeoutError,
                    requests.exceptions.ConnectionError):
                logger.debug("chcek update from github error")
                try:
                    resp = requests.get(self._api_mirror).json()
                except:
                    logger.debug("chcek update from gitee error")
            except Exception as e:
                logger.error(f"CheckUpdateWorker error: e={e}")
            if resp:
                try:
                    tag_name, msg = resp['tag_name'], resp['body']
                    ver = self._ver.replace('v', '').split('-')[0].split('.')
                    ver2 = tag_name.replace('v', '').split('-')[0].split('.')
                    local_version = int(ver[0]) * 100 + int(ver[1]) * 10 + int(
                        ver[2])
                    remote_version = int(ver2[0]) * 100 + int(
                        ver2[1]) * 10 + int(ver2[2])
                    if remote_version > local_version:
                        urls = re.findall(r'https?://[-\.a-zA-Z0-9/_#?&%@]+',
                                          msg)
                        for url in urls:
                            new_url = f'<a href="{url}">{url}</a>'
                            msg = msg.replace(url, new_url)
                        msg = msg.replace('\n', '<br />')
                        self.infos.emit(tag_name, msg)
                        if not self._manual:  # 打开软件时检测更新
                            self.bg_update_infos.emit(tag_name, msg)
                    elif self._manual:
                        self.infos.emit("0", "目前还没有发布新版本!")
                except AttributeError:
                    if self._manual:
                        self.infos.emit("v0.0.0", "检查更新时发生异常,请重试!")
                except Exception as e:
                    logger.error(f"Check Update Version error: e={e}")
            else:
                if self._manual:
                    self.infos.emit(
                        "v0.0.0",
                        f"检查更新时 <a href='{self._api}'>api.github.com</a>、<a href='{self._api_mirror}'>gitee.com</a> 拒绝连接,请稍后重试!"
                    )
            self._manual = False
            self._is_work = False
            self._mutex.unlock()
        else:
            if self._manual:
                self.infos.emit("v0.0.0", "后台正在运行,请稍等!")
Esempio n. 26
0
class GetMoreInfoWorker(QThread):
    '''获取文件直链、文件(夹)提取码描述,用于登录后显示更多信息'''
    infos = pyqtSignal(object)
    share_url = pyqtSignal(object)
    dl_link = pyqtSignal(object)
    msg = pyqtSignal(str, int)

    def __init__(self, parent=None):
        super(GetMoreInfoWorker, self).__init__(parent)
        self._disk = None
        self._infos = None
        self._url = ''
        self._pwd = ''
        self._emit_link = False
        self._mutex = QMutex()
        self._is_work = False

    def set_disk(self, disk):
        self._disk = disk

    def set_values(self, infos, emit_link=False):
        self._infos = infos
        self._emit_link = emit_link
        self.start()

    def get_dl_link(self, url, pwd):
        self._url = url
        self._pwd = pwd
        self.start()

    def __del__(self):
        self.wait()

    def stop(self):
        self._mutex.lock()
        self._is_work = False
        self._mutex.unlock()

    def run(self):
        # infos: ID/None,文件名,大小,日期,下载次数(dl_count),提取码(pwd),描述(desc),|链接(share-url)
        if not self._is_work and self._infos:
            self._mutex.lock()
            self._is_work = True
            try:
                if not self._url:  # 获取普通信息
                    if isinstance(self._infos, Infos):
                        if self._infos.id:  # 从 disk 运行
                            self.msg.emit("网络请求中,请稍候……", 0)
                            _info = self._disk.get_share_info(
                                self._infos.id, is_file=self._infos.is_file)
                            self._infos.desc = _info.desc
                            self._infos.pwd = _info.pwd
                            self._infos.url = _info.url
                        if self._emit_link:
                            self.share_url.emit(self._infos)
                        else:
                            self.infos.emit(self._infos)
                        self.msg.emit("", 0)  # 删除提示信息
                else:  # 获取下载直链
                    res = self._disk.get_file_info_by_url(self._url, self._pwd)
                    if res.code == LanZouCloud.SUCCESS:
                        self.dl_link.emit("{}".format(res.durl or "无"))  # 下载直链
                    elif res.code == LanZouCloud.NETWORK_ERROR:
                        self.dl_link.emit("网络错误!获取失败")  # 下载直链
                    else:
                        self.dl_link.emit("其它错误!")  # 下载直链
            except TimeoutError:
                self.msg.emit("网络超时!稍后重试", 6000)
            except Exception as e:
                logger.error(f"GetMoreInfoWorker error: e={e}")
            self._is_work = False
            self._url = ''
            self._pwd = ''
            self._mutex.unlock()
        else:
            self.msg.emit("后台正在运行,请稍后重试!", 3100)
Esempio n. 27
0
    def __init__(self) -> None:
        super(MainWindow, self).__init__()
        self.setWindowTitle("ASET")

        self.document_base = None
        self.preprocessing_phase = None
        self.matching_phase = None
        self.statistics = Statistics(True)
        self.collect_statistics = True

        # set up the api_thread and api and connect slots and signals
        self.feedback_mutex = QMutex()
        self.feedback_cond = QWaitCondition()
        self.api = ASETAPI(self.feedback_mutex, self.feedback_cond)
        self.api_thread = QThread()
        self.api.moveToThread(self.api_thread)
        self._connect_slots_and_signals()
        self.api_thread.start()

        # set up the status bar
        self.status_bar = self.statusBar()
        self.status_bar.setFont(STATUS_BAR_FONT)

        self.status_widget = QWidget(self.status_bar)
        self.status_widget_layout = QHBoxLayout(self.status_widget)
        self.status_widget_layout.setContentsMargins(0, 0, 0, 0)
        self.status_widget_message = QLabel()
        self.status_widget_message.setFont(STATUS_BAR_FONT)

        self.status_widget_message.setMinimumWidth(10)
        self.status_widget_layout.addWidget(self.status_widget_message)
        self.status_widget_progress = QProgressBar()
        self.status_widget_progress.setMinimumWidth(10)
        self.status_widget_progress.setMaximumWidth(200)
        self.status_widget_progress.setTextVisible(False)
        self.status_widget_progress.setMaximumHeight(20)
        self.status_widget_layout.addWidget(self.status_widget_progress)
        self.status_bar.addPermanentWidget(self.status_widget)

        # set up the actions
        self._all_actions = []
        self._was_enabled = []

        self.exit_action = QAction("&Exit", self)
        self.exit_action.setIcon(QIcon("aset_ui/resources/leave.svg"))
        self.exit_action.setStatusTip("Exit the application.")
        self.exit_action.triggered.connect(QApplication.instance().quit)
        self._all_actions.append(self.exit_action)

        self.show_document_base_creator_widget_action = QAction("&Create new document base", self)
        self.show_document_base_creator_widget_action.setIcon(QIcon("aset_ui/resources/two_documents.svg"))
        self.show_document_base_creator_widget_action.setStatusTip(
            "Create a new document base from a collection of .txt files and a list of attribute names."
        )
        self.show_document_base_creator_widget_action.triggered.connect(self.show_document_base_creator_widget_task)
        self._all_actions.append(self.show_document_base_creator_widget_action)

        self.add_attribute_action = QAction("&Add attribute", self)
        self.add_attribute_action.setIcon(QIcon("aset_ui/resources/plus.svg"))
        self.add_attribute_action.setStatusTip("Add a new attribute to the document base.")
        self.add_attribute_action.triggered.connect(self.add_attribute_task)
        self.add_attribute_action.setEnabled(False)
        self._all_actions.append(self.add_attribute_action)

        self.remove_attribute_action = QAction("&Remove attribute", self)
        self.remove_attribute_action.setIcon(QIcon("aset_ui/resources/trash.svg"))
        self.remove_attribute_action.setStatusTip("Remove an attribute from the document base.")
        self.remove_attribute_action.triggered.connect(self.remove_attribute_task)
        self.remove_attribute_action.setEnabled(False)
        self._all_actions.append(self.remove_attribute_action)

        self.forget_matches_for_attribute_action = QAction("&Forget matches for attribute", self)
        self.forget_matches_for_attribute_action.setIcon(QIcon("aset_ui/resources/redo.svg"))
        self.forget_matches_for_attribute_action.setStatusTip("Forget the matches for a single attribute.")
        self.forget_matches_for_attribute_action.triggered.connect(self.forget_matches_for_attribute_task)
        self.forget_matches_for_attribute_action.setEnabled(False)
        self._all_actions.append(self.forget_matches_for_attribute_action)

        self.load_document_base_from_bson_action = QAction("&Load document base", self)
        self.load_document_base_from_bson_action.setIcon(QIcon("aset_ui/resources/folder.svg"))
        self.load_document_base_from_bson_action.setStatusTip("Load an existing document base from a .bson file.")
        self.load_document_base_from_bson_action.triggered.connect(self.load_document_base_from_bson_task)
        self._all_actions.append(self.load_document_base_from_bson_action)

        self.save_document_base_to_bson_action = QAction("&Save document base", self)
        self.save_document_base_to_bson_action.setIcon(QIcon("aset_ui/resources/save.svg"))
        self.save_document_base_to_bson_action.setStatusTip("Save the document base in a .bson file.")
        self.save_document_base_to_bson_action.triggered.connect(self.save_document_base_to_bson_task)
        self.save_document_base_to_bson_action.setEnabled(False)
        self._all_actions.append(self.save_document_base_to_bson_action)

        self.save_table_to_csv_action = QAction("&Export table to CSV", self)
        self.save_table_to_csv_action.setIcon(QIcon("aset_ui/resources/table.svg"))
        self.save_table_to_csv_action.setStatusTip("Save the table to a .csv file.")
        self.save_table_to_csv_action.triggered.connect(self.save_table_to_csv_task)
        self.save_table_to_csv_action.setEnabled(False)
        self._all_actions.append(self.save_table_to_csv_action)

        self.forget_matches_action = QAction("&Forget all matches", self)
        self.forget_matches_action.setIcon(QIcon("aset_ui/resources/redo.svg"))
        self.forget_matches_action.setStatusTip("Forget the matches for all attributes.")
        self.forget_matches_action.triggered.connect(self.forget_matches_task)
        self.forget_matches_action.setEnabled(False)
        self._all_actions.append(self.forget_matches_action)

        self.load_and_run_default_preprocessing_phase_action = QAction(
            "&Load and run default preprocessing phase", self
        )
        self.load_and_run_default_preprocessing_phase_action.setStatusTip(
            "Load the default preprocessing phase and run it on the document collection."
        )
        self.load_and_run_default_preprocessing_phase_action.setIcon(QIcon("aset_ui/resources/run_run.svg"))
        self.load_and_run_default_preprocessing_phase_action.setDisabled(True)
        self.load_and_run_default_preprocessing_phase_action.triggered.connect(
            self.load_and_run_default_preprocessing_phase_task
        )
        self._all_actions.append(self.load_and_run_default_preprocessing_phase_action)

        self.load_preprocessing_phase_from_config_action = QAction("&Load preprocessing phase", self)
        self.load_preprocessing_phase_from_config_action.setStatusTip(
            "Load a preprocessing phase from a .json configuration file."
        )
        self.load_preprocessing_phase_from_config_action.triggered.connect(
            self.load_preprocessing_phase_from_config_task
        )
        self._all_actions.append(self.load_preprocessing_phase_from_config_action)

        self.save_preprocessing_phase_to_config_action = QAction("&Save preprocessing phase", self)
        self.save_preprocessing_phase_to_config_action.setStatusTip(
            "Save the preprocessing phase in a .json configuration file."
        )
        self.save_preprocessing_phase_to_config_action.triggered.connect(self.save_preprocessing_phase_to_config_task)
        self.save_preprocessing_phase_to_config_action.setEnabled(False)
        self._all_actions.append(self.save_preprocessing_phase_to_config_action)

        self.run_preprocessing_phase_action = QAction("Run preprocessing phase", self)
        self.run_preprocessing_phase_action.setIcon(QIcon("aset_ui/resources/run.svg"))
        self.run_preprocessing_phase_action.setStatusTip("Run the preprocessing phase on the document collection.")
        self.run_preprocessing_phase_action.triggered.connect(self.run_preprocessing_phase_task)
        self.run_preprocessing_phase_action.setEnabled(False)
        self._all_actions.append(self.run_preprocessing_phase_action)

        self.load_and_run_default_matching_phase_action = QAction(
            "&Load and run default matching phase", self
        )
        self.load_and_run_default_matching_phase_action.setStatusTip(
            "Load the default matching phase and run it on the document collection."
        )
        self.load_and_run_default_matching_phase_action.setIcon(QIcon("aset_ui/resources/run_run.svg"))
        self.load_and_run_default_matching_phase_action.setDisabled(True)
        self.load_and_run_default_matching_phase_action.triggered.connect(
            self.load_and_run_default_preprocessing_phase_task
        )
        self._all_actions.append(self.load_and_run_default_matching_phase_action)

        self.load_matching_phase_from_config_action = QAction("&Load matching phase", self)
        self.load_matching_phase_from_config_action.setStatusTip(
            "Load a matching phase from a .json configuration file."
        )
        self.load_matching_phase_from_config_action.triggered.connect(self.load_matching_phase_from_config_task)
        self._all_actions.append(self.load_matching_phase_from_config_action)

        self.save_matching_phase_to_config_action = QAction("&Save matching phase", self)
        self.save_matching_phase_to_config_action.setStatusTip("Save the matching phase in a .json configuration file.")
        self.save_matching_phase_to_config_action.triggered.connect(self.save_matching_phase_to_config_task)
        self.save_matching_phase_to_config_action.setEnabled(False)
        self._all_actions.append(self.save_matching_phase_to_config_action)

        self.run_matching_phase_action = QAction("Run matching phase", self)
        self.run_matching_phase_action.setIcon(QIcon("aset_ui/resources/run.svg"))
        self.run_matching_phase_action.setStatusTip("Run the matching phase on the document collection.")
        self.run_matching_phase_action.triggered.connect(self.run_matching_phase_task)
        self.run_matching_phase_action.setEnabled(False)
        self._all_actions.append(self.run_matching_phase_action)

        self.enable_collect_statistics_action = QAction("&Enable statistics", self)
        self.enable_collect_statistics_action.setIcon(QIcon("aset_ui/resources/statistics.svg"))
        self.enable_collect_statistics_action.setStatusTip("Enable collecting statistics.")
        self.enable_collect_statistics_action.triggered.connect(self.enable_collect_statistics_task)
        self.enable_collect_statistics_action.setEnabled(False)
        self._all_actions.append(self.enable_collect_statistics_action)

        self.disable_collect_statistics_action = QAction("&Disable statistics", self)
        self.disable_collect_statistics_action.setIcon(QIcon("aset_ui/resources/statistics_incorrect.svg"))
        self.disable_collect_statistics_action.setStatusTip("Disable collecting statistics.")
        self.disable_collect_statistics_action.triggered.connect(self.disable_collect_statistics_task)
        self._all_actions.append(self.disable_collect_statistics_action)

        self.save_statistics_to_json_action = QAction("&Save statistics", self)
        self.save_statistics_to_json_action.setIcon(QIcon("aset_ui/resources/statistics_save.svg"))
        self.save_statistics_to_json_action.setStatusTip("Save the statistics to a .json file.")
        self.save_statistics_to_json_action.triggered.connect(self.save_statistics_to_json_task)
        self.save_statistics_to_json_action.setEnabled(False)
        self._all_actions.append(self.save_statistics_to_json_action)

        # set up the menu bar
        self.menubar = self.menuBar()
        self.menubar.setFont(MENU_FONT)

        self.file_menu = self.menubar.addMenu("&File")
        self.file_menu.setFont(MENU_FONT)
        self.file_menu.addAction(self.exit_action)

        self.document_base_menu = self.menubar.addMenu("&Document Base")
        self.document_base_menu.setFont(MENU_FONT)
        self.document_base_menu.addAction(self.show_document_base_creator_widget_action)
        self.document_base_menu.addSeparator()
        self.document_base_menu.addAction(self.load_document_base_from_bson_action)
        self.document_base_menu.addAction(self.save_document_base_to_bson_action)
        self.document_base_menu.addSeparator()
        self.document_base_menu.addAction(self.save_table_to_csv_action)
        self.document_base_menu.addSeparator()
        self.document_base_menu.addAction(self.add_attribute_action)
        self.document_base_menu.addAction(self.remove_attribute_action)
        self.document_base_menu.addSeparator()
        self.document_base_menu.addAction(self.forget_matches_for_attribute_action)
        self.document_base_menu.addAction(self.forget_matches_action)

        self.preprocessing_menu = self.menubar.addMenu("&Preprocessing")
        self.preprocessing_menu.setFont(MENU_FONT)
        self.preprocessing_menu.addAction(self.load_and_run_default_preprocessing_phase_action)
        self.preprocessing_menu.addSeparator()
        self.preprocessing_menu.addAction(self.load_preprocessing_phase_from_config_action)
        self.preprocessing_menu.addAction(self.save_preprocessing_phase_to_config_action)
        self.preprocessing_menu.addSeparator()
        self.preprocessing_menu.addAction(self.run_preprocessing_phase_action)

        self.matching_menu = self.menubar.addMenu("&Matching")
        self.matching_menu.setFont(MENU_FONT)
        self.matching_menu.addAction(self.load_and_run_default_matching_phase_action)
        self.matching_menu.addSeparator()
        self.matching_menu.addAction(self.load_matching_phase_from_config_action)
        self.matching_menu.addAction(self.save_matching_phase_to_config_action)
        self.matching_menu.addSeparator()
        self.matching_menu.addAction(self.run_matching_phase_action)

        self.statistics_menu = self.menubar.addMenu("&Statistics")
        self.statistics_menu.setFont(MENU_FONT)
        self.statistics_menu.addAction(self.enable_collect_statistics_action)
        self.statistics_menu.addAction(self.disable_collect_statistics_action)
        self.statistics_menu.addSeparator()
        self.statistics_menu.addAction(self.save_statistics_to_json_action)

        # start menu
        self.start_menu_widget = QWidget()
        self.start_menu_layout = QVBoxLayout(self.start_menu_widget)
        self.start_menu_layout.setContentsMargins(0, 0, 0, 0)
        self.start_menu_layout.setSpacing(30)
        self.start_menu_layout.setAlignment(Qt.AlignmentFlag.AlignTop)
        self.start_menu_widget.setMaximumWidth(400)

        self.start_menu_header = QLabel("Welcome to ASET!")
        self.start_menu_header.setFont(HEADER_FONT)
        self.start_menu_layout.addWidget(self.start_menu_header)

        self.start_menu_create_new_document_base_widget = QWidget()
        self.start_menu_create_new_document_base_layout = QVBoxLayout(self.start_menu_create_new_document_base_widget)
        self.start_menu_create_new_document_base_layout.setContentsMargins(0, 0, 0, 0)
        self.start_menu_create_new_document_base_layout.setSpacing(10)
        self.start_menu_layout.addWidget(self.start_menu_create_new_document_base_widget)

        self.start_menu_create_new_document_base_subheader = QLabel("Create a new document base.")
        self.start_menu_create_new_document_base_subheader.setFont(SUBHEADER_FONT)
        self.start_menu_create_new_document_base_layout.addWidget(self.start_menu_create_new_document_base_subheader)

        self.start_menu_create_new_document_base_wrapper_widget = QWidget()
        self.start_menu_create_new_document_base_wrapper_layout = QHBoxLayout(
            self.start_menu_create_new_document_base_wrapper_widget)
        self.start_menu_create_new_document_base_wrapper_layout.setContentsMargins(0, 0, 0, 0)
        self.start_menu_create_new_document_base_wrapper_layout.setSpacing(20)
        self.start_menu_create_new_document_base_wrapper_layout.setAlignment(Qt.AlignmentFlag.AlignLeft)
        self.start_menu_create_new_document_base_layout.addWidget(
            self.start_menu_create_new_document_base_wrapper_widget)

        self.start_menu_create_document_base_button = QPushButton()
        self.start_menu_create_document_base_button.setFixedHeight(45)
        self.start_menu_create_document_base_button.setFixedWidth(45)
        self.start_menu_create_document_base_button.setIcon(QIcon("aset_ui/resources/two_documents.svg"))
        self.start_menu_create_document_base_button.clicked.connect(self.show_document_base_creator_widget_task)
        self.start_menu_create_new_document_base_wrapper_layout.addWidget(self.start_menu_create_document_base_button)

        self.start_menu_create_document_base_label = QLabel(
            "Create a new document base from a directory\nof .txt files and a list of attribute names.")
        self.start_menu_create_document_base_label.setFont(LABEL_FONT)
        self.start_menu_create_new_document_base_wrapper_layout.addWidget(self.start_menu_create_document_base_label)

        self.start_menu_load_document_base_widget = QWidget()
        self.start_menu_load_document_base_layout = QVBoxLayout(self.start_menu_load_document_base_widget)
        self.start_menu_load_document_base_layout.setContentsMargins(0, 0, 0, 0)
        self.start_menu_load_document_base_layout.setSpacing(10)
        self.start_menu_layout.addWidget(self.start_menu_load_document_base_widget)

        self.start_menu_load_document_base_subheader = QLabel("Load an existing document base.")
        self.start_menu_load_document_base_subheader.setFont(SUBHEADER_FONT)
        self.start_menu_load_document_base_layout.addWidget(self.start_menu_load_document_base_subheader)

        self.start_menu_load_document_base_wrapper_widget = QWidget()
        self.start_menu_load_document_base_wrapper_layout = QHBoxLayout(
            self.start_menu_load_document_base_wrapper_widget)
        self.start_menu_load_document_base_wrapper_layout.setContentsMargins(0, 0, 0, 0)
        self.start_menu_load_document_base_wrapper_layout.setSpacing(20)
        self.start_menu_load_document_base_wrapper_layout.setAlignment(Qt.AlignmentFlag.AlignLeft)
        self.start_menu_load_document_base_layout.addWidget(self.start_menu_load_document_base_wrapper_widget)

        self.start_menu_load_document_base_button = QPushButton()
        self.start_menu_load_document_base_button.setFixedHeight(45)
        self.start_menu_load_document_base_button.setFixedWidth(45)
        self.start_menu_load_document_base_button.setIcon(QIcon("aset_ui/resources/folder.svg"))
        self.start_menu_load_document_base_button.clicked.connect(self.load_document_base_from_bson_task)
        self.start_menu_load_document_base_wrapper_layout.addWidget(self.start_menu_load_document_base_button)

        self.start_menu_load_document_base_label = QLabel("Load an existing document base\nfrom a .bson file.")
        self.start_menu_load_document_base_label.setFont(LABEL_FONT)
        self.start_menu_load_document_base_wrapper_layout.addWidget(self.start_menu_load_document_base_label)

        # main UI
        self.central_widget = QWidget(self)
        self.central_widget_layout = QHBoxLayout(self.central_widget)
        self.central_widget_layout.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.setCentralWidget(self.central_widget)

        self.document_base_creator_widget = DocumentBaseCreatorWidget(self)
        self.document_base_viewer_widget = DocumentBaseViewerWidget(self)
        self.interactive_matching_widget = InteractiveMatchingWidget(self)

        self.document_base_creator_widget.hide()
        self.document_base_viewer_widget.hide()
        self.interactive_matching_widget.hide()
        self.central_widget_layout.addWidget(self.start_menu_widget)
        self.central_widget_layout.update()

        self.resize(1400, 800)
        self.show()

        logger.info("Initialized MainWindow.")
Esempio n. 28
0
class GetSharedInfo(QThread):
    '''提取界面获取分享链接信息'''
    infos = pyqtSignal(object)
    msg = pyqtSignal(str, int)
    update = pyqtSignal()
    clean = pyqtSignal()

    def __init__(self, parent=None):
        super(GetSharedInfo, self).__init__(parent)
        self._disk = None
        self.share_url = ""
        self.pwd = ""
        self.is_file = ""
        self.is_folder = ""
        self._mutex = QMutex()
        self._is_work = False
        self._pat = r"(https?://(\w[-\w]*\.)?lanzou[a-z].com/[a-z]?[-/a-zA-Z0-9]+)[^a-zA-Z0-9]*([a-zA-Z0-9]+\w+)?"

    def set_disk(self, disk):
        self._disk = disk

    def set_values(self, text, pwd_input=""):
        '''获取分享链接信息'''
        text = text.strip()
        pwd_input = pwd_input.strip()
        if not text:
            self.update.emit()
            return None
        for share_url, _, pwd in re.findall(self._pat, text):
            if is_file_url(share_url):  # 文件链接
                is_file = True
                is_folder = False
                self.msg.emit("正在获取文件链接信息……", 20000)
            elif is_folder_url(share_url):  # 文件夹链接
                is_folder = True
                is_file = False
                self.msg.emit("正在获取文件夹链接信息,可能需要几秒钟,请稍候……", 500000)
            else:
                self.msg.emit(f"{share_url} 为非法链接!", 0)
                self.update.emit()
                return None
            self.clean.emit()  # 清理旧的显示信息
            self.share_url = share_url
            if pwd_input:
                self.pwd = pwd_input
            elif pwd:
                self.pwd = pwd
            else:  # 一个或两个汉字的提取码
                pwd_ = text.split(' ')[-1].split(':')[-1].split(':')[-1]
                self.pwd = pwd_ if 1<= len(pwd_) <= 2  else ''
            self.is_file = is_file
            self.is_folder = is_folder
            self.start()
            break

    def __del__(self):
        self.wait()

    def stop(self):  # 用于手动停止
        self._mutex.lock()
        self._is_work = False
        self._mutex.unlock()

    def emit_msg(self, infos):
        '''根据查询信息发送状态信号'''
        show_time = 2999  # 提示显示时间,单位 ms
        if infos.code == LanZouCloud.FILE_CANCELLED:
            self.msg.emit("<font color='red'>文件不存在,或已删除!</font>", show_time)
        elif infos.code == LanZouCloud.URL_INVALID:
            self.msg.emit("<font color='red'>链接非法!</font>", show_time)
        elif infos.code == LanZouCloud.PASSWORD_ERROR:
            self.msg.emit(f"<font color='red'>提取码 [<b><font color='magenta'>{self.pwd}</font></b>] 错误!</font>", show_time)
        elif infos.code == LanZouCloud.LACK_PASSWORD:
            self.msg.emit("<font color='red'>请在链接后面跟上提取码,空格分割!</font>", show_time)
        elif infos.code == LanZouCloud.NETWORK_ERROR:
            self.msg.emit("<font color='red'>网络错误!</font>", show_time)
        elif infos.code == LanZouCloud.SUCCESS:
            self.msg.emit("<font color='#00CC00'>提取成功!</font>", show_time)
        else:
            self.msg.emit(f"<font color='red'>未知错误 code={infos.code}!</font>", show_time * 4)

    def run(self):
        if not self._is_work:
            self._mutex.lock()
            self._is_work = True
            try:
                if self.is_file:  # 链接为文件
                    _infos = self._disk.get_share_info_by_url(self.share_url, self.pwd)
                    self.emit_msg(_infos)
                    self.infos.emit(_infos)
                elif self.is_folder:  # 链接为文件夹
                    _infos = self._disk.get_folder_info_by_url(self.share_url, self.pwd)
                    self.emit_msg(_infos)
                    self.infos.emit(_infos)
                else:
                    logger.error(f"GetShareInfo error: Not a file or folder!")
            except TimeoutError:
                self.msg.emit("font color='red'>网络超时!请稍后重试</font>", 5000)
            except Exception as e:
                self.msg.emit(f"font color='red'>未知错误:{e}</font>", 5000)
                logger.error(f"GetShareInfo error: e={e}")
            self._is_work = False
            self.update.emit()
            self._mutex.unlock()
        else:
            self.msg.emit("<font color='blue'>后台正在运行,稍后重试!</font>", 4000)
Esempio n. 29
0
 def __init__(self, parent=None):
     super(LogoutWorker, self).__init__(parent)
     self._disk = None
     self.update_ui = True
     self._mutex = QMutex()
     self._is_work = False
Esempio n. 30
0
class SetPwdWorker(QThread):
    '''设置文件(夹)提取码 线程'''
    msg = pyqtSignal(str, int)
    update = pyqtSignal(object, object, object, object)

    def __init__(self, parent=None):
        super(SetPwdWorker, self).__init__(parent)
        self._disk = None
        self.infos = []
        self._work_id = -1
        self._mutex = QMutex()
        self._is_work = False

    def set_disk(self, disk):
        self._disk = disk

    def set_values(self, infos, work_id):
        self.infos = infos
        self._work_id = work_id
        self.start()

    def __del__(self):
        self.wait()

    def stop(self):
        self._mutex.lock()
        self._is_work = False
        self._mutex.unlock()

    def run(self):
        if not self._is_work:
            self._mutex.lock()
            self._is_work = True
            try:
                has_file = False
                has_folder = False
                failed = False
                failed_code = ""
                for infos in self.infos:
                    if infos.is_file:  # 文件
                        has_file = True
                        new_pwd = infos.new_pwd
                        if 2 > len(new_pwd) >= 1 or len(new_pwd) > 6:
                            self.msg.emit("文件提取码为2-6位字符,关闭请留空!", 4000)
                            raise UserWarning
                    else:  # 文件夹
                        has_folder = True
                        new_pwd = infos.new_pwd
                        if 2 > len(new_pwd) >= 1 or len(new_pwd) > 12:
                            self.msg.emit("文件夹提取码为0-12位字符,关闭请留空!", 4000)
                            raise UserWarning
                    res = self._disk.set_passwd(infos.id, infos.new_pwd,
                                                infos.is_file)
                    if res != LanZouCloud.SUCCESS:
                        failed_code = failed_code + str(res)
                        failed = True
                if failed:
                    self.msg.emit(f"❌部分提取码变更失败:{failed_code},请勿使用特殊符号!", 4000)
                else:
                    self.msg.emit("✅提取码变更成功!♬", 3000)

                self.update.emit(self._work_id, has_file, has_folder, False)
            except TimeoutError:
                self.msg.emit("网络超时,请稍后重试!", 6000)
            except UserWarning:
                pass
            except Exception as e:
                logger.error(f"SetPwdWorker error: e={e}")
            self._is_work = False
            self._mutex.unlock()
        else:
            self.msg.emit("后台正在运行,请稍后重试!", 3100)