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)
def run(self): try: if is_file_url(self.url): # 下载文件 res = self._disk.down_file_by_url(self.url, self.pwd, self.save_path, self._show_progress) elif is_folder_url(self.url): # 下载文件夹 res = self._disk.down_dir_by_url( self.url, self.pwd, self.save_path, self._show_progress, mkdir=True, failed_callback=self._down_failed) else: return if res == 0: self.download_rate.emit(self.url, 1000) else: self.download_failed.emit(self.url, res) logger.debug(f"Download res: {res}") except TimeoutError: logger.error("Download TimeOut") self.download_failed.emit(self.url, "网络连接错误!") except Exception as e: logger.error(f"Download error: {e=}") self.download_failed.emit(self.url, f"未知错误!{e}")
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: {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=}") self._is_work = False self._mutex.unlock()
def run(self): if not self._task: logger.error("Upload task is empty!") return None self._task.run = True try: if os.path.isdir(self._task.url): code, fid, isfile = self._disk.upload_dir(self._task, self._callback, self._allow_big_file) else: code, fid, isfile = self._disk.upload_file(self._task, self._task.url, self._task.fid, self._callback, self._allow_big_file) except TimeoutError: self._task.info = LanZouCloud.NETWORK_ERROR self.update.emit() except Exception as err: logger.error(f"Upload error: err={err}") self._task.info = err self.update.emit() else: if code == LanZouCloud.SUCCESS: if self._task.pwd: self._disk.set_passwd(fid, self._task.pwd, is_file=isfile) if self._task.desc: self._disk.set_desc(fid, self._task.desc, is_file=isfile) self._task.rate = 1000 # 回调线程可能在休眠 self._task.run = False self.finished_.emit(self._task)
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)
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=}") 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=}") self._is_work = False self._mutex.unlock() else: self.msg.emit("后台正在运行,请稍后重试!", 3100)
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=}") self._is_work = False self._mutex.unlock() else: self.msg.emit("后台正在运行,请稍后重试!", 3100)
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=}") 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=}") 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", "后台正在运行,请稍等!")
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=}") else: logger.debug(f"Stop job: {task.url} is not running!") self.update.emit()
def call_auto_get_cookie(self): """自动读取浏览器cookie槽函数""" try: self._cookie = get_cookie_from_browser() except Exception as e: logger.error(f"Browser_cookie3 Error: {e}") self.auto_get_cookie_ok.setPlainText(f"❌获取失败,错误信息\n{e}") else: if self._cookie: self._user = self._pwd = '' self.auto_get_cookie_ok.setPlainText("✅获取成功即将登录……") QTimer.singleShot(2000, self._close_dialog) else: self.auto_get_cookie_ok.setPlainText("❌获取失败\n请提前使用支持的浏览器登录蓝奏云,读取前完全退出浏览器!\n支持的浏览器与顺序:\nchrome, chromium, opera, edge, firefox")
def call_auto_get_cookie(self): """自动读取浏览器cookie槽函数""" try: self._cookie = get_cookie_from_browser() except Exception as e: logger.error(f"Browser_cookie3 Error: {e}") self.auto_get_cookie_ok.setText(f"❌获取失败,错误信息:{e}") else: if self._cookie: self._user = self._pwd = '' self.auto_get_cookie_ok.setText("✅获取成功即将登录……") QTimer.singleShot(2000, self._close_dialog) else: self.auto_get_cookie_ok.setText( "❌获取失败,请提前使用 Firefox/Chrome 登录蓝奏云!")
def is_folder_url(share_url: str) -> bool: """判断是否为文件夹的分享链接""" base_pat = r'https?://(\w[-\w]*\.)?lanzou[six].com/.+' user_pat = r'https?://(\w[-\w]*\.)?lanzou[six].com/b[a-zA-Z0-9]{7,}/?' if not re.fullmatch(base_pat, share_url): return False elif re.fullmatch(user_pat, share_url): return True else: # VIP 用户的 URL 很随意 try: html = requests.get(share_url, headers=headers).text html = remove_notes(html) return True if re.search(r'id="infos"', html) else False except (requests.RequestException, Exception) as e: logger.error(f"Unexpected error: e={e}") return False
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()
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)
def is_file_url(share_url: str) -> bool: """判断是否为文件的分享链接""" base_pat = r'https?://(\w[-\w]*\.)?lanzou[six].com/.+' user_pat = r'https?://(\w[-\w]*\.)?lanzou[six].com/i[a-z0-9]{5,}/?' # 普通用户 URL 规则 if not re.fullmatch(base_pat, share_url): return False elif re.fullmatch(user_pat, share_url): return True else: # VIP 用户的 URL 很随意 try: html = requests.get(share_url, headers=headers).text html = remove_notes(html) return True if re.search(r'class="fileinfo"|id="file"|文件描述', html) else False except (requests.RequestException, Exception) as e: logger.error(f"Unexpected error: {e=}") return False
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)
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) _tasks[info.url] = DlJob(name=info.name, url=info.url, pwd=info.pwd, path=self.dl_path) 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=}") self._is_work = False self._mutex.unlock() else: self.msg.emit("后台正在运行指令!请稍后重试", 3100)
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)
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=}") self._is_work = False self._mutex.unlock() else: self.msg.emit("后台正在运行,请稍后重试!", 3100)
def run(self): if not self._task: logger.error("Download task is empty!") return None self._task.run = True try: if is_file_url(self._task.url): # 下载文件 res = self._disk.down_file_by_url(self._task.url, self._task, self._callback) elif is_folder_url(self._task.url): # 下载文件夹 res = self._disk.down_dir_by_url(self._task, self._callback) else: raise UserWarning if res == 0: self._task.rate = 1000 # 回调线程可能在休眠 self.update.emit() else: self._task.info = why_error(res) logger.debug(f"Download : res={res}") self.failed.emit() except TimeoutError: self._task.info = "网络连接错误!" logger.error("Download TimeOut") self.failed.emit() except Exception as err: self._task.info = f"未知错误!err={err}" logger.error(f"Download error: err={err}") self.failed.emit() except UserWarning: pass self._task.run = False self.finished_.emit(self._task)
def run(self): try: if self.cookie: res = self._disk.login_by_cookie(self.cookie) if res == LanZouCloud.SUCCESS: if not self.username: username = self._disk.get_user_name() if isinstance(username, str): self.update_username.emit(username) logger.debug(f"login by Cookie: {username=}") self.code.emit( True, "<font color='#00CC00'>通过<b>Cookie</b>登录<b>成功</b>! ≧◉◡◉≦</font>", 5000) return None logger.debug(f"login by Cookie err: {res=}") if (not self.username or not self.password) and not self.cookie: logger.debug("login err: No UserName、No cookie") self.code.emit(False, "<font color='red'>登录失败: 没有用户或密码</font>", 3000) else: res = self._disk.login(self.username, self.password) if res == LanZouCloud.SUCCESS: self.code.emit( True, "<font color='#00CC00'>登录<b>成功</b>! ≧◉◡◉≦</font>", 5000) _cookie = self._disk.get_cookie() self.update_cookie.emit(_cookie) else: logger.debug(f"login err: {res=}") self.code.emit( False, "<font color='red'>登录失败,可能是用户名或密码错误!</font>", 8000) self.update_cookie.emit(None) except TimeoutError: self.code.emit(False, "<font color='red'>网络超时!</font>", 3000) except Exception as e: logger.error(f"LoginLuncher error: {e=}")
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=}") self._is_work = False self._url = '' self._pwd = '' self._mutex.unlock() else: self.msg.emit("后台正在运行,请稍后重试!", 3100)
def run(self): if not self._is_work: self._mutex.lock() self._is_work = True while True: if not self._tasks: break while self._count >= self._thread: self.sleep(1) self._count += 1 url = list(self._tasks.keys())[0] task = self._tasks[url] logger.debug(f"DownloadMgr run: {task=}") self.downloaders[url] = Downloader() self.downloaders[url].set_disk(self._disk) self.downloaders_msg.emit( "准备下载:<font color='#FFA500'>{}</font>".format(task.name), 8000) try: self.downloaders[url].finished.connect( lambda: self._add_thread(url)) self.downloaders[url].download_proc.connect( self._ahead_msg) self.downloaders[url].download_rate.connect( self._ahead_rate) self.downloaders[url].folder_file_failed.connect( self._ahead_folder_error) self.downloaders[url].download_failed.connect( self._ahead_error) self._dl_ing[url] = task._replace(run=True) self.downloaders[url].set_values(task.name, task.url, task.pwd, task.path) except Exception as exp: logger.error(f"DownloadMgr Error: {exp=}") del self._tasks[url] self._is_work = False self._mutex.unlock()
def run(self): if not self._is_work: self._mutex.lock() self._is_work = True while True: if not self._tasks: logger.debug(f"upload finished!") break self._furl = list(self._tasks.keys())[0] self._task = self._tasks[self._furl] logger.debug(f"run task: {self._task=}") if not os.path.exists(self._furl): logger.error(f"upload file not exist : {self._furl}") msg = f"<b>ERROR :</b> <font color='red'>文件不存在:{self._furl}</font>" self.code.emit(msg, 3100) continue if os.path.isdir(self._furl): logger.error(f"upload dir : {self._furl}") msg = f"<b>INFO :</b> <font color='#00CC00'>批量上传文件夹:{self._furl}</font>" self.code.emit(msg, 30000) self._disk.upload_dir(self._furl, self._task.id, self._show_progress, None, self._allow_big_file) else: msg = f"<b>INFO :</b> <font color='#00CC00'>上传文件:{self._furl}</font>" self.code.emit(msg, 20000) try: code, fid, isfile = self._disk.upload_file(self._task.furl, self._task.id, self._show_progress, self._allow_big_file) except TimeoutError: msg = "<b>ERROR :</b> <font color='red'>网络连接超时,请重试!</font>" self.code.emit(msg, 3100) self._task = self._task._replace(info="网络连接超时") self.update.emit({self._furl: self._task}) except Exception as e: logger.error(f"UploadWorker error: {e=}") self._task = self._task._replace(info="未知错误") self.update.emit({self._furl: self._task}) else: self._task = self._task._replace(info="上传成功") if code == LanZouCloud.SUCCESS: if self._task.set_pwd: self._disk.set_passwd(fid, self._task.pwd, is_file=isfile) if self._task.set_desc: self._disk.set_desc(fid, self._task.desc, is_file=isfile) del self._tasks[self._furl] self._is_work = False self._mutex.unlock()