diff --git a/.gitignore b/.gitignore index 65e3ba2..0ccfbbb 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,48 @@ -test/ +*.pyc +__pycache__ +# Built application files +*.apk +*.ap_ + +# Files for the ART/Dalvik VM +*.dex + +# Java class files +*.class + +# Generated files +bin/ +gen/ +out/ + +# Gradle files +.gradle/ +build/ + +# Local configuration file (sdk path, etc) +local.properties + +# Proguard folder generated by Eclipse +proguard/ + +# Log Files +*.log + +# Android Studio Navigation editor temp files +.navigation/ + +# Android Studio captures folder +captures/ + +# Intellij +*.iml +.idea/workspace.xml +.idea/tasks.xml +.idea/gradle.xml +.idea/libraries +.idea/ +# Keystore files +*.jks + +# External native build folder generated in Android Studio 2.2 and later +.externalNativeBuild diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..7420d4c --- /dev/null +++ b/.travis.yml @@ -0,0 +1,14 @@ +language: python +python: + - "3.2" + - "3.3" + - "3.4" + - "3.5" + - "3.6" +# command to install dependencies +install: + # Build/test dependencies + #- pip3 install -r requirements.txt + # Get fab to test fab + - python setup.py install + diff --git a/HISTORY b/HISTORY index 42d00ab..39983a6 100644 --- a/HISTORY +++ b/HISTORY @@ -1,3 +1,7 @@ +v3.9.0 - 2016.11.25 +* 修复各种网络错误 (by @Yufeikang). +* 修复验证码问题 (by @Yufeikang). + v3.8.2 - 2015.12.25 * Fixed: failed to get bdstoken (pull#214, by @zhaihj). diff --git a/README.md b/README.md index f4f06dd..bf05bc4 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,21 @@ +# 公告 + +很遗憾这个项目要和大家说再见了,因为下列原因: + +*1.这个项目使用的是百度webAPi,api不稳定经常变动 +*2.这个项目的界面构建语言是GTK,跨平台性能差,不易扩展 + +结束并不代表彻底结束,因为身在墙内,不可避免还不得不依赖百度网盘。最近没时间去调试百度的api,一直使用的是baidupcs的命令行版本,一直很稳定,作者也一直很勤劳的维护。而且baidupcs可以使用多线程加快下载速度。我使用的过程中速度还比较满意。所以,打算新开一个项目,使用electrion和react来构建GUI界面,使用baidupcs作为核心引擎构建一个全新的,跨平台的百度网盘自由版。 + +**所谓重生吧,因为我的个人时间有限。希望有兴趣的朋友可以和我一起加入到这个项目一起开发,一起学习。另外,如果有朋友比较擅长做UI或者交互,可以贡献力量的欢迎👏加入。希望我们能做出漂亮又实用的工具** + + 关于 ===== bcloud 是[百度网盘](http://pan.baidu.com)的Linux桌面客户端. +>[原项目地址](https://github.com/LiuLang/bcloud),大神@Liulang很久没有维护了。最近迁移到linux平台发现了这个好工具,还好自己学过Python,稍微修改了一下,现在可以使用了。如果没有大的变故,我来维护这个项目,方便国内的Linux党。如有问题,欢迎issues + 已经支持的Linux系统/版本: * ArchLinux @@ -14,9 +28,11 @@ bcloud 是[百度网盘](http://pan.baidu.com)的Linux桌面客户端. * OpenSuse 13 * Ubuntu 14.04 * Ubuntu 13.10 +* Ubuntu 16.04 * Linux Mint 17 + 类似项目 ======= [bypy](https://github.com/houtianze/bypy) 终端里使用的百度网盘客户端, 它 @@ -28,8 +44,18 @@ bcloud 是[百度网盘](http://pan.baidu.com)的Linux桌面客户端. 安装 ======= -请用户直接到 [bcloud-packages](https://github.com/LiuLang/bcloud-packages) -下载发行版相对应的安装包, 比如deb, rpm等.. +需要Python3支持 +安装执行: +``` +python3 setup.py install +``` +卸载执行: +```bash +python setup.py install --record files.txt #记录安装后文件的路径 + +cat files.txt | xargs rm -rf #删除这些文件 +``` +**最近有不少用户反馈安装后无法启动,原因大多数是因为缺少某些依赖的模块。我已经添加了部分依赖到requiements.txt文件中。如还有报错请大家issues的时候附上log** Q&A === diff --git a/bcloud/App.py b/bcloud/App.py index fd67aa9..8e7fd31 100644 --- a/bcloud/App.py +++ b/bcloud/App.py @@ -1,4 +1,3 @@ - # Copyright (C) 2014-2015 LiuLang # Use of this source code is governed by GPLv3 license that can be found # in http://www.gnu.org/licenses/gpl-3.0.html @@ -9,17 +8,21 @@ import traceback import gi + gi.require_version('Gdk', '3.0') from gi.repository import Gdk from gi.repository import Gio from gi.repository import GLib from gi.repository import GObject + gi.require_version('Gtk', '3.0') from gi.repository import Gtk + gi.require_version('Notify', '0.7') from gi.repository import Notify from bcloud import Config + Config.check_first() _ = Config._ from bcloud import const @@ -41,16 +44,18 @@ from bcloud.FileWatcher import WatchFileChange try: -# Ubuntu Unity uses appindicator instead of status icon + # Ubuntu Unity uses appindicator instead of status icon + import gi + + gi.require_version('AppIndicator3', '0.1') from gi.repository import AppIndicator3 as AppIndicator except ImportError: logger.debug(traceback.format_exc()) - if Config.GTK_LE_36: GObject.threads_init() (ICON_COL, NAME_COL, TOOLTIP_COL, COLOR_COL) = list(range(4)) -BLINK_DELTA = 250 # 字体闪烁间隔, 250 miliseconds +BLINK_DELTA = 250 # 字体闪烁间隔, 250 miliseconds BLINK_SUSTAINED = 3 # 字体闪烁持续时间, 5 seconds # 用于处理拖放上传 @@ -61,7 +66,6 @@ class App: - profile = None cookie = None tokens = None @@ -174,7 +178,7 @@ def on_app_startup(self, app): key, mod = Gtk.accelerator_parse('F5') self.window.connect('activate-default', self.reload_current_page) self.window.add_accelerator('activate-default', - self.accel_group, key, mod, Gtk.AccelFlags.VISIBLE) + self.accel_group, key, mod, Gtk.AccelFlags.VISIBLE) def on_app_activate(self, app): if not self.profile: @@ -312,6 +316,7 @@ def update_quota(self, quota_info, error=None): def update_avatar(self): '''更新用户头像''' + def do_update_avatar(info, error=None): if error or not info: logger.error('Failed to get user avatar: %s, %s' % @@ -323,6 +328,7 @@ def do_update_avatar(info, error=None): self.profile['username'], uname, ]) + if not self.profile['display-avatar']: return self.img_avatar.props.tooltip_text = '' @@ -375,7 +381,7 @@ def init_filewatcher(self): enable_sync = self.profile['enable-sync'] if enable_sync: sync_dir = self.profile['sync-dir'] - #self.filewatcher = WatchFileChange(sync_dir, self.upload_page.add_bg_task) + # self.filewatcher = WatchFileChange(sync_dir, self.upload_page.add_bg_task) self.filewatcher = WatchFileChange(sync_dir, self) self.filewatcher.start() @@ -411,8 +417,8 @@ def on_nav_selection_changed(self, nav_selection): def init_status_icon(self): def on_status_icon_popup_menu(status_icon, event_button, event_time): menu.popup(None, None, - lambda a,b: Gtk.StatusIcon.position_menu(menu, status_icon), - None, event_button, event_time) + lambda a, b: Gtk.StatusIcon.position_menu(menu, status_icon), + None, event_button, event_time) def on_status_icon_activate(status_icon): if self.window.props.visible: @@ -433,15 +439,15 @@ def on_status_icon_activate(status_icon): menu.append(sep_item) pause_upload_item = Gtk.MenuItem.new_with_label( - _('Pause Upload Tasks')) + _('Pause Upload Tasks')) pause_upload_item.connect('activate', - lambda item: self.upload_page.pause_tasks()) + lambda item: self.upload_page.pause_tasks()) menu.append(pause_upload_item) pause_download_item = Gtk.MenuItem.new_with_label( - _('Pause Download Tasks')) + _('Pause Download Tasks')) pause_download_item.connect('activate', - lambda item: self.download_page.pause_tasks()) + lambda item: self.download_page.pause_tasks()) menu.append(pause_download_item) sep_item = Gtk.SeparatorMenuItem() @@ -456,8 +462,8 @@ def on_status_icon_activate(status_icon): if 'AppIndicator' in globals(): self.status_icon = AppIndicator.Indicator.new(Config.NAME, - Config.NAME, - AppIndicator.IndicatorCategory.APPLICATION_STATUS) + Config.NAME, + AppIndicator.IndicatorCategory.APPLICATION_STATUS) self.status_icon.set_menu(menu) self.status_icon.set_status(AppIndicator.IndicatorStatus.ACTIVE) else: @@ -476,7 +482,7 @@ def blink(): row[COLOR_COL] = self.default_color return False return True - + start_time = time.time() for index, p in enumerate(self.notebook): if p == page: diff --git a/bcloud/Config.py b/bcloud/Config.py index 3ef9d0a..a343bd2 100644 --- a/bcloud/Config.py +++ b/bcloud/Config.py @@ -1,4 +1,3 @@ - # Copyright (C) 2014-2015 LiuLang # Use of this source code is governed by GPLv3 license that can be found # in http://www.gnu.org/licenses/gpl-3.0.html @@ -35,8 +34,10 @@ DBUS_APP_NAME = 'org.liulang.bcloud' APPNAME = 'BCloud' VERSION = bcloud.__version__ -HOMEPAGE = 'https://github.com/LiuLang/bcloud' -# https://github.com/LiuLang/bcloud/pulls +''' +LiuLang大神不知什么原因不再维护该代码了。我来试试 +''' +HOMEPAGE = 'https://github.com/Yufeikang/bcloud' AUTHORS = [ 'Alexzhang ', 'Aetf ', @@ -50,8 +51,9 @@ 'Zhenbo Li ', 'slawdan ', 'Zihao Wang ', + 'Kang ' ] -COPYRIGHT = 'Copyright (c) 2014-2015 LiuLang' +COPYRIGHT = 'Copyright (c) 2014-2016 LiuLang' DESCRIPTION = _('Baidu Pan client for GNU/Linux desktop users.') CACHE_DIR = os.path.join(HOME_DIR, '.cache', NAME) @@ -68,6 +70,7 @@ 'profiles': [], } + def check_first(): '''这里, 要创建基本的目录结构''' if not os.path.exists(CONF_DIR): @@ -75,6 +78,7 @@ def check_first(): if not os.path.exists(CACHE_DIR): os.makedirs(CACHE_DIR, exist_ok=True) + def load_conf(): '''获取基本设定信息, 里面存放着所有可用的profiles, 以及默认的profile''' if os.path.exists(_conf_file): @@ -84,10 +88,12 @@ def load_conf(): dump_conf(_base_conf) return _base_conf + def dump_conf(conf): with open(_conf_file, 'w') as fh: json.dump(conf, fh) + def get_cache_path(profile_name): '''获取这个帐户的缓存目录, 如果不存在, 就创建它''' path = os.path.join(CACHE_DIR, profile_name, 'cache') @@ -95,6 +101,7 @@ def get_cache_path(profile_name): os.makedirs(path, exist_ok=True) return path + def get_tmp_path(profile_name): '''获取这个帐户的临时文件目录, 可以存放验证码图片, 上传时的文件分片等''' path = os.path.join(CACHE_DIR, profile_name, 'tmp') @@ -102,6 +109,7 @@ def get_tmp_path(profile_name): os.makedirs(path, exist_ok=True) return path + def load_color_schema(): if not os.path.exists(COLOR_SCHEMA): return [] diff --git a/bcloud/Downloader.py b/bcloud/Downloader.py index 32c2616..1b7caa3 100644 --- a/bcloud/Downloader.py +++ b/bcloud/Downloader.py @@ -1,4 +1,3 @@ - # Copyright (C) 2014-2015 LiuLang # Use of this source code is governed by GPLv3 license that can be found # in http://www.gnu.org/licenses/gpl-3.0.html @@ -23,18 +22,19 @@ from bcloud import util from bcloud.log import logger -CHUNK_SIZE = 131072 # 128K -RETRIES = 3 # 连接失败时的重试次数 -DOWNLOAD_RETRIES = 10 # 下载线程的重试次数 +CHUNK_SIZE = 131072 # 128K +RETRIES = 3 # 连接失败时的重试次数 +DOWNLOAD_RETRIES = 10 # 下载线程的重试次数 THRESHOLD_TO_FLUSH = 500 # 磁盘写入数据次数超过这个值时, 就进行一次同步. -SMALL_FILE_SIZE = 1048576 # 1M, 下载小文件时用单线程下载 +SMALL_FILE_SIZE = 1048576 # 1M, 下载小文件时用单线程下载 (NAME_COL, PATH_COL, FSID_COL, SIZE_COL, CURRSIZE_COL, LINK_COL, - ISDIR_COL, SAVENAME_COL, SAVEDIR_COL, STATE_COL, STATENAME_COL, - HUMANSIZE_COL, PERCENT_COL) = list(range(13)) + ISDIR_COL, SAVENAME_COL, SAVEDIR_COL, STATE_COL, STATENAME_COL, + HUMANSIZE_COL, PERCENT_COL) = list(range(13)) BATCH_FINISISHED, BATCH_ERROR = -1, -2 + def get_tmp_filepath(dir_name, save_name): '''返回最终路径名及临时路径名''' filepath = os.path.join(dir_name, save_name) @@ -42,7 +42,6 @@ def get_tmp_filepath(dir_name, save_name): class DownloadBatch(threading.Thread): - def __init__(self, id_, queue, url, lock, start_size, end_size, fh, timeout): super().__init__() @@ -102,16 +101,16 @@ def download(self): if block: break except (OSError, AttributeError): - #self.queue.put((self.id_, BATCH_ERROR), block=False) + # self.queue.put((self.id_, BATCH_ERROR), block=False) logger.error(traceback.format_exc()) req = None - except : - req=None - logger.error( 'Time out occured.') - #self.queue.put((self.id_, BATCH_ERROR), block=False) - #return + except: + req = None + logger.error('Time out occured.') + # self.queue.put((self.id_, BATCH_ERROR), block=False) + # return + - else: logger.error('DownloadBatch, block is empty: %s, %s, %s, %s' % (offset, self.start_size, self.end_size, @@ -125,7 +124,7 @@ def download(self): self.fh.seek(offset) self.fh.write(block) self.queue.put((self.id_, len(block)), block=False) - offset = offset + len(block) + offset += len(block) # 下载完成 if offset >= self.end_size: self.queue.put((self.id_, BATCH_FINISISHED), block=False) @@ -140,13 +139,13 @@ class Downloader(threading.Thread, GObject.GObject): ''' __gsignals__ = { - 'started': (GObject.SIGNAL_RUN_LAST, GObject.TYPE_NONE, (str, )), + 'started': (GObject.SIGNAL_RUN_LAST, GObject.TYPE_NONE, (str,)), 'received': (GObject.SIGNAL_RUN_LAST, GObject.TYPE_NONE, (str, GObject.TYPE_INT64, GObject.TYPE_INT64)), - 'downloaded': (GObject.SIGNAL_RUN_LAST, GObject.TYPE_NONE, (str, )), + 'downloaded': (GObject.SIGNAL_RUN_LAST, GObject.TYPE_NONE, (str,)), # FSID, tmp-filepath 'disk-error': (GObject.SIGNAL_RUN_LAST, GObject.TYPE_NONE, (str, str)), - 'network-error': (GObject.SIGNAL_RUN_LAST, GObject.TYPE_NONE, (str, )), + 'network-error': (GObject.SIGNAL_RUN_LAST, GObject.TYPE_NONE, (str,)), } def __init__(self, parent, row): @@ -166,7 +165,7 @@ def download(self): if not os.path.exists(row[SAVEDIR_COL]): os.makedirs(row[SAVEDIR_COL], exist_ok=True) filepath, tmp_filepath, conf_filepath = get_tmp_filepath( - row[SAVEDIR_COL], row[SAVENAME_COL]) + row[SAVEDIR_COL], row[SAVENAME_COL]) if os.path.exists(filepath): if self.download_mode == DownloadMode.IGNORE: @@ -323,4 +322,5 @@ def stop(self): '''停止下载, 并删除之前下载的片段''' self.row[STATE_COL] = State.CANCELED + GObject.type_register(Downloader) diff --git a/bcloud/RequestCookie.py b/bcloud/RequestCookie.py index 870776f..2bdf8e3 100644 --- a/bcloud/RequestCookie.py +++ b/bcloud/RequestCookie.py @@ -41,3 +41,4 @@ def load_list(self, raw_items): return for item in raw_items: self.load(item) + diff --git a/bcloud/SigninDialog.py b/bcloud/SigninDialog.py index f38c03d..da4c198 100644 --- a/bcloud/SigninDialog.py +++ b/bcloud/SigninDialog.py @@ -1,4 +1,3 @@ - # Copyright (C) 2014-2015 LiuLang # Use of this source code is governed by GPLv3 license that can be found # in http://www.gnu.org/licenses/gpl-3.0.html @@ -12,6 +11,7 @@ from bcloud import auth from bcloud import Config + _ = Config._ from bcloud import gutil from bcloud.log import logger @@ -19,7 +19,7 @@ from bcloud import util from bcloud import Widgets -DELTA = 1 * 24 * 60 * 60 # 1 days +DELTA = 30 * 24 * 60 * 60 # 1 days class SigninVcodeDialog(Gtk.Dialog): @@ -108,7 +108,8 @@ def _refresh_vcode(info, error=None): self.vcodetype, callback=_refresh_vcode) def check_entry(self, *args): - if len(self.vcode_entry.get_text()) == 4: + '''中文验证码长度为2,英文验证码长度为4''' + if len(self.vcode_entry.get_text()) == 4 or len(self.vcode_entry.get_text()) == 2: self.response(Gtk.ResponseType.OK) def on_vcode_refresh_clicked(self, button): @@ -119,7 +120,6 @@ def on_vcode_confirm_clicked(self, button): class SigninDialog(Gtk.Dialog): - profile = None password_changed = False @@ -130,7 +130,7 @@ def __init__(self, app, auto_signin=True): self.set_default_size(460, 260) self.set_border_width(15) - + self.conf = Config.load_conf() self.profile = None @@ -139,7 +139,7 @@ def __init__(self, app, auto_signin=True): username_ls = Gtk.ListStore(str) for username in self.conf['profiles']: - username_ls.append([username,]) + username_ls.append([username, ]) self.username_combo = Gtk.ComboBox.new_with_entry() self.username_combo.set_model(username_ls) self.username_combo.set_entry_text_column(0) @@ -155,7 +155,7 @@ def __init__(self, app, auto_signin=True): box.pack_start(self.password_entry, False, False, 0) self.remember_check = Gtk.CheckButton.new_with_label( - _('Remember Password')) + _('Remember Password')) self.remember_check.props.margin_top = 20 if Config.GTK_GE_312: self.remember_check.props.margin_start = 20 @@ -165,7 +165,7 @@ def __init__(self, app, auto_signin=True): self.remember_check.connect('toggled', self.on_remember_check_toggled) self.signin_check = Gtk.CheckButton.new_with_label( - _('Signin Automatically')) + _('Signin Automatically')) self.signin_check.set_sensitive(False) if Config.GTK_GE_312: self.signin_check.props.margin_start = 20 @@ -184,7 +184,7 @@ def __init__(self, app, auto_signin=True): box.pack_end(self.infobar, False, False, 0) info_content = self.infobar.get_content_area() self.info_label = Gtk.Label.new( - _('Failed to sign in, please try again.')) + _('Failed to sign in, please try again.')) info_content.pack_start(self.info_label, False, False, 0) box.show_all() @@ -222,7 +222,7 @@ def on_username_changed(self, combo): def use_profile(self, username): model = self.username_combo.get_model() - for row in model: + for row in model: if row[0] == username: self.username_combo.set_active_iter(row.iter) break @@ -298,7 +298,7 @@ def on_post_login(info, error=None): logger.error('SigninDialog.on_post_login: %s, %s' % (info, error)) self.signin_failed( - _('Login failed, please try again')) + _('Login failed, please try again')) else: errno, query = info if errno == 0: @@ -319,15 +319,11 @@ def on_post_login(info, error=None): verifycode = dialog.get_vcode() codeString = dialog.codeString dialog.destroy() - if not verifycode or len(verifycode) != 4: - self.signin_failed(_('Please input verification code!')) - return - else: - self.signin_button.set_label(_('Get bdstoken...')) - gutil.async_call(auth.post_login, cookie, - tokens, username, - password_enc, rsakey, verifycode, - codeString, callback=on_post_login) + self.signin_button.set_label(_('Get bdstoken...')) + gutil.async_call(auth.post_login, cookie, + tokens, username, + password_enc, rsakey, verifycode, + codeString, callback=on_post_login) # 密码错误 elif errno == 4: logger.error('SigninDialog.on_post_login: %s, %s' % @@ -336,13 +332,34 @@ def on_post_login(info, error=None): # 验证码错误 elif errno == 6: self.signin_failed( - _('Verfication code error, please try again')) + _('Verfication code error, please try again')) # 需要短信验证 elif errno == 400031: logger.error('SigninDialog.on_post_login: %s, %s' % (info, error)) self.signin_failed( - _('Does not support SMS/Email verification!')) + _('Does not support SMS/Email verification!')) + # 登录失败,请在弹出的窗口操作,或重新登录 + elif errno == 120021: + logger.error('SigninDialog.on_post_login: %s, %s' % + (info, error)) + self.signin_failed( + _('NET:登录失败,请在弹出的窗口操作,或重新登录')) + elif errno == 120019: + logger.error('SigninDialog.on_post_login: %s, %s' % + (info, error)) + self.signin_failed( + _('NET:近期登录次数过多, 请先通过 passport.baidu.com 解除锁定')) + elif errno == 500010: + logger.error('SigninDialog.on_post_login: %s, %s' % + (info, error)) + self.signin_failed( + _('NET:登录过于频繁,请24小时后再试')) + elif errno == 400031: + logger.error('SigninDialog.on_post_login: %s, %s' % + (info, error)) + self.signin_failed( + _('NET:账号异常,请在当前网络环境下在百度网页端正常登录一次')) else: logger.error('SigninDialog.on_post_login: %s, %s' % (info, error)) @@ -353,7 +370,7 @@ def on_get_public_key(info, error=None): logger.error('SigninDialog.on_get_public_key: %s, %s' % (info, error)) self.signin_failed( - _('Failed to request public key, please try again')) + _('Failed to request public key, please try again')) else: pubkey = info['pubkey'] nonlocal rsakey @@ -383,7 +400,8 @@ def on_check_login(info, error=None): verifycode = dialog.get_vcode() codeString = dialog.codeString dialog.destroy() - if not verifycode or len(verifycode) != 4: + '''中文验证码长度为2,英文验证码长度为4''' + if not verifycode or (len(verifycode) != 4 and len(verifycode) != 2): self.signin_failed(_('Please input verification code!')) return else: @@ -424,13 +442,12 @@ def on_get_BAIDUID(uid_cookie, error=None): logger.error('SigninDialog.on_get_BAIDUID: %s, %s' % (uid_cookie, error)) self.signin_failed( - _('Failed to get BAIDUID cookie, please try again.')) + _('Failed to get BAIDUID cookie, please try again.')) else: cookie.load_list(uid_cookie) self.signin_button.set_label(_('Get TOKEN...')) gutil.async_call(auth.get_token, cookie, callback=on_get_token) - username = self.username_combo.get_child().get_text() password = self.password_entry.get_text() # 使用本地的缓存token, 有效期是三天 diff --git a/bcloud/UploadPage.py b/bcloud/UploadPage.py index 4171d8e..198fd36 100644 --- a/bcloud/UploadPage.py +++ b/bcloud/UploadPage.py @@ -543,7 +543,7 @@ def pause_tasks(self): self.pause_task(row, scan=False) def pause_task(self, row, scan=True): - '''暂停下载任务''' + '''暂停上传任务''' if row[STATE_COL] == State.UPLOADING: self.remove_worker(row[FID_COL], stop=False) if row[STATE_COL] in (State.UPLOADING, State.WAITING): @@ -554,7 +554,7 @@ def pause_task(self, row, scan=True): self.scan_tasks() def remove_task(self, row, scan=True): - '''删除下载任务''' + '''删除上传任务''' if row[STATE_COL] == State.UPLOADING: self.remove_worker(row[FID_COL], stop=True) self.remove_task_db(row[FID_COL]) diff --git a/bcloud/__init__.py b/bcloud/__init__.py index 2aadf97..cf9447f 100644 --- a/bcloud/__init__.py +++ b/bcloud/__init__.py @@ -3,4 +3,4 @@ # Use of this source code is governed by GPLv3 license that can be found # in http://www.gnu.org/licenses/gpl-3.0.html -__version__ = '3.8.2' +__version__ = '3.9.0' diff --git a/bcloud/auth.py b/bcloud/auth.py index 602d5d4..ed1ee57 100644 --- a/bcloud/auth.py +++ b/bcloud/auth.py @@ -1,4 +1,3 @@ - # Copyright (C) 2014-2015 LiuLang # Use of this source code is governed by GPLv3 license that can be found # in http://www.gnu.org/licenses/gpl-3.0.html @@ -22,10 +21,12 @@ from bcloud.RequestCookie import RequestCookie from bcloud import util + def get_ppui_logintime(): '''ppui_ligintime 这个字段, 是一个随机数.''' return str(random.randint(52000, 58535)) + def get_BAIDUID(): '''获取一个cookie - BAIDUID. @@ -43,6 +44,7 @@ def get_BAIDUID(): else: return None + def get_token(cookie): '''获取一个页面访问的token, 这里需要之前得到的BAIDUID 这个cookie值 @@ -66,7 +68,7 @@ def get_token(cookie): '&tt=', util.timestamp(), '&class=login&logintype=basicLogin', ]) - headers={ + headers = { 'Cookie': cookie.header_output(), 'Accept': const.ACCEPT_HTML, 'Cache-control': 'max-age=0', @@ -79,6 +81,7 @@ def get_token(cookie): return cookie, content_obj['data']['token'] return None + def get_UBI(cookie, tokens): '''检查登录历史, 可以获得一个Cookie - UBI. 返回的信息类似于: @@ -91,7 +94,7 @@ def get_UBI(cookie, tokens): '&tpl=pp&apiver=v3', '&tt=', util.timestamp(), ]) - headers={ + headers = { 'Cookie': cookie.header_output(), 'Referer': const.REFERER, } @@ -101,6 +104,7 @@ def get_UBI(cookie, tokens): else: return None + def check_login(cookie, tokens, username): '''进行登录验证, 主要是在服务器上验证这个帐户的状态. @@ -118,7 +122,7 @@ def check_login(cookie, tokens, username): '&username=', encoder.encode_uri_component(username), '&isphone=false', ]) - headers={ + headers = { 'Cookie': cookie.header_output(), 'Referer': const.REFERER, } @@ -129,6 +133,7 @@ def check_login(cookie, tokens, username): else: return None + def get_signin_vcode(cookie, codeString): '''获取登录时的验证码图片. @@ -139,7 +144,7 @@ def get_signin_vcode(cookie, codeString): 'cgi-bin/genimage?', codeString, ]) - headers={ + headers = { 'Cookie': cookie.header_output(), 'Referer': const.REFERER, } @@ -149,6 +154,7 @@ def get_signin_vcode(cookie, codeString): else: return None + def refresh_signin_vcode(cookie, tokens, vcodetype): '''刷新验证码. @@ -157,13 +163,13 @@ def refresh_signin_vcode(cookie, tokens, vcodetype): url = ''.join([ const.PASSPORT_BASE, 'v2/?reggetcodestr', - '&token=', tokens['token'], + '&token=', tokens, '&tpl=pp&apiver=v3', '&tt=', util.timestamp(), '&fr=ligin', '&vcodetype=', encoder.encode_uri(vcodetype), ]) - headers={ + headers = { 'Cookie': cookie.header_output(), 'Referer': const.REFERER, } @@ -178,6 +184,7 @@ def refresh_signin_vcode(cookie, tokens, vcodetype): logger.error(traceback.format_exc()) return None + def get_public_key(cookie, tokens): '''获取RSA公钥, 这个用于加密用户的密码 @@ -189,7 +196,7 @@ def get_public_key(cookie, tokens): '?token=', tokens['token'], '&tpl=pp&apiver=v3&tt=', util.timestamp(), ]) - headers={ + headers = { 'Cookie': cookie.header_output(), 'Referer': const.REFERER, } @@ -199,6 +206,7 @@ def get_public_key(cookie, tokens): return util.json_loads_single(req.data.decode()) return None + def post_login(cookie, tokens, username, password, rsakey, verifycode='', codestring=''): '''登录验证. @@ -214,15 +222,18 @@ def post_login(cookie, tokens, username, password, rsakey, verifycode='', ''' url = const.PASSPORT_LOGIN data = ''.join([ - 'staticpage=https%3A%2F%2Fpassport.baidu.com%2Fstatic%2Fpasspc-account%2Fhtml%2Fv3Jump.html', + 'staticpage=http%3A%2F%2Fyun.baidu.com%2Fres%2Fstatic%2Fthirdparty%2Fpass_v3_jump.html', + 'tpl=netdisk', + 'subpro=netdisk_web', + 'u=http%3A%2F%2Fyun.baidu.com%2Fdisk%2Fhome', '&charset=UTF-8', '&token=', tokens['token'], - '&tpl=pp&subpro=&apiver=v3', + '&apiver=v3', '&tt=', util.timestamp(), '&codestring=', codestring, - '&safeflg=0&u=http%3A%2F%2Fpassport.baidu.com%2F', - '&isPhone=', - '&quick_user=0&logintype=basicLogin&logLoginType=pc_loginBasic&idc=', + '&safeflg=0&u=http%3A%2F%2Fwww.baidu.com%2F', + '&isPhone=false', + '&quick_user=0&logintype=baseLogin&logLoginType=pc_loginBasic&idc=', '&loginmerge=true', '&username=', encoder.encode_uri_component(username), '&password=', encoder.encode_uri_component(password), @@ -230,43 +241,50 @@ def post_login(cookie, tokens, username, password, rsakey, verifycode='', '&mem_pass=on', '&rsakey=', rsakey, '&crypttype=12', - '&ppui_logintime=',get_ppui_logintime(), + '&ppui_logintime=', get_ppui_logintime(), '&callback=parent.bd__pcbs__28g1kg', ]) - headers={ + headers = { 'Accept': const.ACCEPT_HTML, - 'Cookie': cookie.sub_output('BAIDUID','HOSUPPORT', 'UBI'), - 'Referer': const.REFERER, + 'Cookie': cookie.sub_output('BAIDUID', 'HOSUPPORT', 'UBI'), + 'Referer': 'https://pan.baidu.com/', 'Connection': 'Keep-Alive', } req = net.urlopen(url, headers=headers, data=data.encode()) if req: - content= req.data.decode() - match = re.search('"(err_no[^"]+)"', content) - if not match: - return (-1, None) - query = dict(urllib.parse.parse_qsl(match.group(1))) - query['err_no'] = int(query['err_no']) - err_no = query['err_no'] - auth_cookie = req.headers.get_all('Set-Cookie') - - if err_no == 0: - return (0, auth_cookie) - # #!! not bind cellphone - elif err_no == 18: - return (0, auth_cookie) - # 要输入验证码 - elif err_no == 257: - return (err_no, query) - # 需要短信验证 - elif err_no == 400031: - return (err_no, query) + if req.getcode() == 200: + content = req.data.decode() + match = re.search('"(err_no[^"]+)"', content) + if not match: + return (-1, None) + query = dict(urllib.parse.parse_qsl(match.group(1))) + query['err_no'] = int(query['err_no']) + err_no = query['err_no'] + auth_cookie = req.headers.get_all('Set-Cookie') + + if err_no == 0: + return (0, auth_cookie) + # #!! not bind cellphone + elif err_no == 18: + return (0, auth_cookie) + # 要输入验证码 + elif err_no == 257 or err_no == 7: + return (err_no, query) + # 需要短信验证 + elif err_no == 400031: + return (err_no, query) + # 登录失败,请在弹出的窗口操作,或重新登录 + elif err_no == 120021: + return (err_no, query) + else: + return (err_no, None) else: - return (err_no, None) + return (-1, req.getcode()) else: return (-1, None) return (-1, None) + def parse_bdstoken(content): '''从页面中解析出bdstoken等信息. @@ -282,13 +300,14 @@ def parse_bdstoken(content): bdstoken = bds_match.group(1) return bdstoken + def get_bdstoken(cookie): '''从/disk/home页面获取bdstoken等token信息 这些token对于之后的请求非常重要. ''' url = const.PAN_REFERER - req = net.urlopen(url, headers={'Cookie': cookie.header_output()}) + req = net.urlopen(url, headers={'Cookie': cookie.header_output()}, cookie=cookie) if req: return parse_bdstoken(req.data.decode()) else: diff --git a/bcloud/const.py b/bcloud/const.py index 85c2761..fa68b98 100644 --- a/bcloud/const.py +++ b/bcloud/const.py @@ -20,7 +20,7 @@ USER_AGENT = 'Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Firefox/31.0 Iceweasel/31.2.0' PAN_URL = 'http://pan.baidu.com/' PAN_API_URL = PAN_URL + 'api/' -PAN_REFERER = 'http://pan.baidu.com/disk/home' +PAN_REFERER = 'https://pan.baidu.com/disk/home' SHARE_REFERER = PAN_URL + 'share/manage' # 一般的服务器名 @@ -33,14 +33,14 @@ ## 以下常量是模拟的PC客户端的参数. CHANNEL_URL = 'https://channel.api.duapp.com/rest/2.0/channel/channel?' -PC_USER_AGENT = 'netdisk;4.5.0.7;PC;PC-Windows;5.1.2600;WindowsBaiduYunGuanJia' +PC_USER_AGENT = 'netdisk;5.2.7.2;PC;PC-Windows;5.1.2600;WindowsBaiduYunGuanJia' PC_DEVICE_ID = '08002788772E' PC_DEVICE_NAME = '08002788772E' PC_DEVICE_TYPE = '2' PC_CLIENT_TYPE = '8' PC_APP_ID = '1981342' PC_DEVUID = 'BDIMXV2%2DO%5FFD60326573E54779892088D1378B27C6%2DC%5F0%2DD%5F42563835636437366130302d6662616539362064%2DM%5F08002788772E%2DV%5F0C94CA83' -PC_VERSION = '4.5.0.7' +PC_VERSION = '5.2.7.2' ## HTTP 请求时的一些常量 CONTENT_FORM = 'application/x-www-form-urlencoded' diff --git a/bcloud/gutil.py b/bcloud/gutil.py index 5aa370e..033d8ee 100644 --- a/bcloud/gutil.py +++ b/bcloud/gutil.py @@ -1,4 +1,3 @@ - # Copyright (C) 2014-2015 LiuLang # Use of this source code is governed by GPLv3 license that can be found # in http://www.gnu.org/licenses/gpl-3.0.html @@ -20,8 +19,10 @@ from bcloud import net from bcloud import pcs from bcloud import util + try: import keyring + keyring_available = True try: keyring.set_password("test", "utest", "ptest"); @@ -61,9 +62,9 @@ # 下载的文件保存到 'save-dir': Config.HOME_DIR, # 同时进行的下载任务数, 1~5 - 'concurr-download': 2, + 'concurr-download': 5, # 下载单个任务的线程数 1~10 - 'download-segments': 3, + 'download-segments': 8, # 隔5分钟后尝试重新下载 'retries-each': 5, # 60 秒后下载超时 @@ -74,7 +75,7 @@ 'confirm-download-deletion': True, # 同时进行的上传任务数, 1~5 - 'concurr-upload': 2, + 'concurr-upload': 3, # 上传隐藏文件. 'upload-hidden-files': True, # 上传时如果服务器端已存在同名文件时的操作方式 @@ -95,7 +96,7 @@ 'VideoPage': 0, }, } -RETRIES = 3 # 调用keyring模块与libgnome-keyring交互的尝试次数 +RETRIES = 3 # 调用keyring模块与libgnome-keyring交互的尝试次数 AVATAR_UPDATE_INTERVAL = 604800 # 用户头像更新频率, 默认是7天 @@ -105,6 +106,7 @@ def async_call(func, *args, callback=None): If error occurs in `func`, error will keep the traceback and passed to `callback` as second parameter. Always check `error` is not None. ''' + def do_call(): result = None error = None @@ -121,6 +123,7 @@ def do_call(): thread.daemon = True thread.start() + def xdg_open(uri): '''使用桌面环境中默认的程序打开指定的URI @@ -133,6 +136,7 @@ def xdg_open(uri): except FileNotFoundError: logger.error(traceback.format_exc()) + def update_liststore_image(liststore, tree_iters, col, pcs_files, dir_name, icon_size=96): '''下载文件缩略图, 并将它显示到liststore里. @@ -141,6 +145,7 @@ def update_liststore_image(liststore, tree_iters, col, pcs_files, dir_name, dir_name - 缓存目录, 下载到的图片会保存这个目录里. size - 指定图片的缩放大小, 默认是96px. ''' + def update_image(filepath, tree_iter): try: pix = GdkPixbuf.Pixbuf.new_from_file_at_size(filepath, icon_size, @@ -184,6 +189,7 @@ def dump_image(url, filepath): if status: GLib.idle_add(update_image, filepath, tree_iter) + def update_share_image(liststore, tree_iters, col, large_col, pcs_files, dir_name, icon_size, large_icon_size): '''下载文件缩略图, 并将它显示到liststore里. @@ -192,6 +198,7 @@ def update_share_image(liststore, tree_iters, col, large_col, pcs_files, pcs_files - 里面包含了几个必要的字段. dir_name - 缓存目录, 下载到的图片会保存这个目录里. ''' + def update_image(filepath, tree_iter): try: tree_path = liststore.get_path(tree_iter) @@ -204,7 +211,7 @@ def update_image(filepath, tree_iter): height * icon_size // width, GdkPixbuf.InterpType.NEAREST) liststore[tree_path][col] = small_pix - liststore[tree_path][large_col] = pix + liststore[tree_path][large_col] = pix except GLib.GError: logger.error(traceback.format_exc()) @@ -240,6 +247,7 @@ def dump_image(url, filepath): if status: GLib.idle_add(update_image, filepath, tree_iter) + def update_avatar(cookie, tokens, dir_name): '''获取用户头像信息''' uk = pcs.get_user_uk(cookie, tokens) @@ -250,8 +258,8 @@ def update_avatar(cookie, tokens, dir_name): return None img_path = os.path.join(dir_name, 'avatar.jpg') if (os.path.exists(img_path) and - time.time() - os.stat(img_path).st_mtime <= AVATAR_UPDATE_INTERVAL): - return (uk, user_info['uname'], img_path) + time.time() - os.stat(img_path).st_mtime <= AVATAR_UPDATE_INTERVAL): + return uk, user_info['uname'], img_path img_url = user_info['avatar_url'] if not img_url: return None @@ -261,7 +269,8 @@ def update_avatar(cookie, tokens, dir_name): return None with open(img_path, 'wb') as fh: fh.write(req.data) - return (uk, user_info['uname'], img_path) + return uk, user_info['uname'], img_path + def ellipse_text(text, length=10): if len(text) < length: @@ -269,6 +278,7 @@ def ellipse_text(text, length=10): else: return text[:8] + '..' + def load_profile(profile_name): '''读取特定帐户的配置信息 @@ -291,7 +301,7 @@ def load_profile(profile_name): for i in range(RETRIES): try: profile['password'] = keyring.get_password( - Config.DBUS_APP_NAME, profile['username']) + Config.DBUS_APP_NAME, profile['username']) break except (keyring.errors.InitError, dbus.exceptions.DBusException): logger.error(traceback.format_exc()) @@ -301,6 +311,7 @@ def load_profile(profile_name): profile['password'] = '' return profile + def dump_profile(profile): '''保存帐户的配置信息. @@ -322,10 +333,12 @@ def dump_profile(profile): with open(path, 'w') as fh: json.dump(profile, fh) + def reach_scrolled_bottom(adj): '''在ScrolledWindow里面, 滚动到了底部, 就需要尝试载入下一页的内容''' return (adj.get_upper() - adj.get_page_size() - adj.get_value()) < 80 + def tree_model_natsort(model, row1, row2, user_data=None): '''用natural sorting算法对TreeModel的一个column进行排序''' sort_column, sort_type = model.get_sort_column_id() @@ -339,10 +352,12 @@ def tree_model_natsort(model, row1, row2, user_data=None): else: return 1 + def escape(tooltip): '''Escape special characters in tooltip text''' return GLib.markup_escape_text(tooltip) + def text_buffer_get_all_text(buf): '''Get all text in a GtkTextBuffer''' return buf.get_text(buf.get_start_iter(), buf.get_end_iter(), False) diff --git a/bcloud/log.py b/bcloud/log.py index addb30b..1b60b82 100644 --- a/bcloud/log.py +++ b/bcloud/log.py @@ -1,4 +1,3 @@ - # Copyright (C) 2014-2015 LiuLang # Use of this source code is governed by GPLv3 license that can be found # in http://www.gnu.org/licenses/gpl-3.0.html @@ -8,7 +7,8 @@ import os import sys -def _init_logger(log_level, maxBytes=5*1024*1024, backupCount=5): + +def _init_logger(log_level, maxBytes=5 * 1024 * 1024, backupCount=5): log_file = os.path.expanduser('~/.config/bcloud/bcloud.log') dir_name = os.path.dirname(log_file) if not os.path.exists(dir_name): @@ -19,10 +19,15 @@ def _init_logger(log_level, maxBytes=5*1024*1024, backupCount=5): looger = logging.getLogger('bcloud') file_handler = RotatingFileHandler(log_file, maxBytes=maxBytes, backupCount=backupCount) - formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s') + formatter = logging.Formatter('%(asctime)s %(filename)s :%(lineno)s %(levelname)s %(message)s') file_handler.setFormatter(formatter) looger.addHandler(file_handler) + if log_level == logging.DEBUG: + console_handler = logging.StreamHandler() + console_handler.setFormatter(formatter) + looger.addHandler(console_handler) looger.setLevel(log_level) return looger -logger = _init_logger(logging.INFO) + +logger = _init_logger(logging.DEBUG) diff --git a/bcloud/net.py b/bcloud/net.py index 2305a48..5789eca 100644 --- a/bcloud/net.py +++ b/bcloud/net.py @@ -1,4 +1,3 @@ - # Copyright (C) 2014-2015 LiuLang # Use of this source code is governed by GPLv3 license that can be found # in http://www.gnu.org/licenses/gpl-3.0.html @@ -13,6 +12,8 @@ import urllib.request import zlib +from bcloud.RequestCookie import RequestCookie + from bcloud import const from bcloud.log import logger @@ -22,7 +23,8 @@ default_headers = { 'User-agent': const.USER_AGENT, 'Referer': const.PAN_REFERER, - #'x-requested-with': 'XMLHttpRequest', + 'Host': 'pan.baidu.com', + # 'x-requested-with': 'XMLHttpRequest', 'Accept': const.ACCEPT_JSON, 'Accept-language': 'zh-cn, zh;q=0.5', 'Accept-encoding': 'gzip, deflate', @@ -30,6 +32,7 @@ 'Cache-control': 'no-cache', } + def urloption(url, headers={}, retries=RETRIES): '''发送OPTION 请求''' headers_merged = default_headers.copy() @@ -44,15 +47,14 @@ def urloption(url, headers={}, retries=RETRIES): return resp except OSError: logger.error(traceback.format_exc()) - #return None + # return None except: logger.error(traceback.format_exc()) - #return None + # return None return None class ForbiddenHandler(urllib.request.HTTPErrorProcessor): - def http_error_403(self, req, fp, code, msg, headers): return fp @@ -66,13 +68,33 @@ def urlopen_simple(url, retries=RETRIES, timeout=TIMEOUT): return urllib.request.urlopen(url, timeout=timeout) except OSError: logger.error(traceback.format_exc()) - - except : + + except: logger.error(traceback.format_exc()) - + return None -def urlopen(url, headers={}, data=None, retries=RETRIES, timeout=TIMEOUT): + +class myRedirctHandler(urllib.request.HTTPRedirectHandler): + ''' + 该处理保证 302 跳转不丢失cookies + ''' + def __init__(self, cookies=RequestCookie()): + self.cookies = cookies + + def http_error_302(self, req, fp, code, msg, headers): + cookie = headers.get_all('Set-Cookie') + self.cookies.load_list(cookie) + + return super().http_error_302(req, fp, code, msg, headers) + + def redirect_request(self, req, fp, code, msg, headers, newurl): + if self.cookies is not None: + req.add_header('Cookie', self.cookies.header_output()) + return super().redirect_request(req, fp, code, msg, headers, newurl) + + +def urlopen(url, headers={}, data=None, retries=RETRIES, timeout=TIMEOUT, cookie=RequestCookie()): '''打开一个http连接, 并返回Request. headers 是一个dict. 默认提供了一些项目, 比如User-Agent, Referer等, 就 @@ -86,8 +108,9 @@ def urlopen(url, headers={}, data=None, retries=RETRIES, timeout=TIMEOUT): headers_merged = default_headers.copy() for key in headers.keys(): headers_merged[key] = headers[key] - opener = urllib.request.build_opener(ForbiddenHandler) - opener.addheaders = [(k, v) for k,v in headers_merged.items()] + redirectHandler = myRedirctHandler(cookie) + opener = urllib.request.build_opener(ForbiddenHandler, redirectHandler) + opener.addheaders = [(k, v) for k, v in headers_merged.items()] for i in range(retries): try: @@ -99,14 +122,15 @@ def urlopen(url, headers={}, data=None, retries=RETRIES, timeout=TIMEOUT): elif encoding == 'deflate': req.data = zlib.decompress(req.data, -zlib.MAX_WBITS) return req - except OSError: + except OSError as e: logger.error(traceback.format_exc()) - + except: logger.error(traceback.format_exc()) - + return None + def urlopen_without_redirect(url, headers={}, data=None, retries=RETRIES): '''请求一个URL, 并返回一个Response对象. 不处理重定向. @@ -130,9 +154,10 @@ def urlopen_without_redirect(url, headers={}, data=None, retries=RETRIES): logger.error(traceback.format_exc()) except: logger.error(traceback.format_exc()) - #return None + # return None return None + def post_multipart(url, headers, fields, files, retries=RETRIES): content_type, body = encode_multipart_formdata(fields, files) schema = urllib.parse.urlparse(url) @@ -159,9 +184,10 @@ def post_multipart(url, headers, fields, files, retries=RETRIES): logger.error(traceback.format_exc()) except: logger.error(traceback.format_exc()) - #return None + # return None return None + def encode_multipart_formdata(fields, files): BOUNDARY = b'----------ThIs_Is_tHe_bouNdaRY_$' S_BOUNDARY = b'--' + BOUNDARY @@ -172,7 +198,7 @@ def encode_multipart_formdata(fields, files): for (key, value) in fields: l.append(S_BOUNDARY) l.append('Content-Disposition: form-data; name="{0}"'.format( - key).encode()) + key).encode()) l.append(BLANK) l.append(value.encode()) for (key, filename, content) in files: @@ -188,5 +214,6 @@ def encode_multipart_formdata(fields, files): content_type = 'multipart/form-data; boundary={0}'.format(BOUNDARY.decode()) return content_type, body + def get_content_type(filename): return mimetypes.guess_type(filename)[0] or 'application/octet-stream' diff --git a/bcloud/pcs.py b/bcloud/pcs.py index bbe41f3..b1f8720 100644 --- a/bcloud/pcs.py +++ b/bcloud/pcs.py @@ -1,4 +1,3 @@ - # Copyright (C) 2014-2015 LiuLang # Use of this source code is governed by GPLv3 license that can be found # in http://www.gnu.org/licenses/gpl-3.0.html @@ -30,7 +29,7 @@ def get_quota(cookie, tokens): '''获取当前的存储空间的容量信息.''' url = ''.join([ const.PAN_API_URL, - 'quota?channel=chunlei&clienttype=0&web=1', + 'quota?channel=chunlei&clienttype=', const.PC_CLIENT_TYPE, '&web=1', '&t=', util.timestamp(), ]) req = net.urlopen(url, headers={'Cookie': cookie.header_output()}) @@ -40,19 +39,21 @@ def get_quota(cookie, tokens): else: return None + def get_user_uk(cookie, tokens): '''获取用户的uk''' url = 'http://yun.baidu.com' - req = net.urlopen(url, headers={'Cookie': cookie.header_output()}) + req = net.urlopen(url, headers={'Cookie': cookie.header_output()}, cookie=cookie) if req: content = req.data.decode() - match = re.findall('/share/home\?uk=(\d+)" target=', content) + match = re.findall(',\"uk\":(\d+),', content) if len(match) == 1: return match[0] else: logger.warn('pcs.get_user_uk(), failed to parse uk, %s' % url) return None + def get_user_info(tokens, uk): '''获取用户的部分信息. @@ -61,7 +62,7 @@ def get_user_info(tokens, uk): ''' url = ''.join([ const.PAN_URL, - 'pcloud/user/getinfo?channel=chunlei&clienttype=0&web=1', + 'pcloud/user/getinfo?channel=chunlei&clienttype=', const.PC_CLIENT_TYPE, '&web=1', '&bdstoken=', tokens['bdstoken'], '&query_uk=', uk, '&t=', util.timestamp(), @@ -73,6 +74,7 @@ def get_user_info(tokens, uk): return info['user_info'] return None + def list_share(cookie, tokens, uk, page=1): '''获取用户已经共享的所有文件的信息 @@ -90,7 +92,7 @@ def list_share(cookie, tokens, uk, page=1): '&start=', str(start), '&limit=', str(num), '&query_uk=', str(uk), - '&channel=chunlei&clienttype=0&web=1', + '&channel=chunlei&clienttype=', const.PC_CLIENT_TYPE, '&web=1', '&bdstoken=', tokens['bdstoken'], ]) req = net.urlopen(url, headers={ @@ -103,6 +105,7 @@ def list_share(cookie, tokens, uk, page=1): else: return None + def list_share_files(cookie, tokens, uk, shareid, dirname, page=1): '''列举出用户共享的某一个目录中的文件信息 @@ -116,7 +119,7 @@ def list_share_files(cookie, tokens, uk, shareid, dirname, page=1): return list_share_single_file(cookie, tokens, uk, shareid) url = ''.join([ const.PAN_URL, - 'share/list?channel=chunlei&clienttype=0&web=1&num=50', + 'share/list?channel=chunlei&clienttype=', const.PC_CLIENT_TYPE, '&web=1&num=50', '&t=', util.timestamp(), '&page=', str(page), '&dir=', encoder.encode_uri_component(dirname), @@ -138,6 +141,7 @@ def list_share_files(cookie, tokens, uk, shareid, dirname, page=1): return info['list'] return list_share_single_file(cookie, tokens, uk, shareid) + def list_share_single_file(cookie, tokens, uk, shareid): '''获取单独共享出来的文件. @@ -145,13 +149,14 @@ def list_share_single_file(cookie, tokens, uk, shareid): * http://pan.baidu.com/wap/link?uk=202032639&shareid=420754&third=0 * http://pan.baidu.com/share/link?uk=202032639&shareid=420754 ''' + def parse_share_page(content): tree = html.fromstring(content) script_sel = CSS('script') scripts = script_sel(tree) for script in scripts: if (script.text and (script.text.find('viewsingle_param') > -1 or - script.text.find('mpan.viewlist_param') > -1)): + script.text.find('mpan.viewlist_param') > -1)): break else: logger.warn('pcs.parse_share_page: failed to get filelist, %s', url) @@ -164,9 +169,9 @@ def parse_share_page(content): if start == -1 or end == -1: return None else: - json_str = script.text[start+19:end] + json_str = script.text[start + 19:end] else: - json_str = script.text[start+33:end] + json_str = script.text[start + 33:end] try: return json.loads(json.loads(json_str)) except ValueError: @@ -188,6 +193,7 @@ def parse_share_page(content): else: return None + def enable_share(cookie, tokens, fid_list): '''建立新的分享. @@ -199,21 +205,22 @@ def enable_share(cookie, tokens, fid_list): ''' url = ''.join([ const.PAN_URL, - 'share/set?channel=chunlei&clienttype=0&web=1', + 'share/set?channel=chunlei&clienttype=', const.PC_CLIENT_TYPE, '&web=1&app_id=250528', '&bdstoken=', tokens['bdstoken'], ]) data = encoder.encode_uri( - 'fid_list={0}&schannel=0&channel_list=[]'.format(fid_list)) + 'fid_list={0}&schannel=0&channel_list=[]'.format(fid_list)) req = net.urlopen(url, headers={ 'Cookie': cookie.header_output(), 'Content-type': const.CONTENT_FORM_UTF8, - }, data=data.encode()) + }, data=data.encode()) if req: content = req.data return json.loads(content.decode()) else: return None + def disable_share(cookie, tokens, shareid_list): '''取消分享. @@ -221,20 +228,21 @@ def disable_share(cookie, tokens, shareid_list): ''' url = ''.join([ const.PAN_URL, - 'share/cancel?channel=chunlei&clienttype=0&web=1', + 'share/cancel?channel=chunlei&clienttype=', const.PC_CLIENT_TYPE, '&web=1', '&bdstoken=', tokens['bdstoken'], ]) data = 'shareid_list=' + encoder.encode_uri(json.dumps(shareid_list)) req = net.urlopen(url, headers={ 'Cookie': cookie.header_output(), 'Content-type': const.CONTENT_FORM_UTF8, - }, data=data.encode()) + }, data=data.encode()) if req: content = req.data return json.loads(content.decode()) else: return None + def enable_private_share(cookie, tokens, fid_list): '''建立新的私密分享. @@ -243,9 +251,9 @@ def enable_private_share(cookie, tokens, fid_list): print('enable private share:', fid_list, cookie, tokens) url = ''.join([ const.PAN_URL, - 'share/set?channel=chunlei&clienttype=0&web=1', + 'share/set?channel=chunlei&clienttype=', const.PC_CLIENT_TYPE, '&web=1', '&bdstoken=', tokens['bdstoken'], - '&channel=chunlei&clienttype=0&web=1', + '&channel=chunlei&clienttype=', const.PC_CLIENT_TYPE, '&web=1', '&appid=250528', ]) print('url:', url) @@ -254,18 +262,19 @@ def enable_private_share(cookie, tokens, fid_list): 'fid_list=[', str(fid_list), ']', '&schannel=4&channel_list=[]', '&pwd=', passwd, - ])) + ])) print('data:', data) req = net.urlopen(url, headers={ 'Cookie': cookie.header_output(), 'Content-type': const.CONTENT_FORM_UTF8, - }, data=data.encode()) + }, data=data.encode()) if req: content = req.data return json.loads(content.decode()), passwd else: return None, passwd + def verify_share_password(uk, shareid, pwd, vcode=''): '''验证共享文件的密码. @@ -276,7 +285,7 @@ def verify_share_password(uk, shareid, pwd, vcode=''): ''' url = ''.join([ const.PAN_URL, - 'share/verify?&clienttype=0&web=1&channel=chunlei', + 'share/verify?&clienttype=', const.PC_CLIENT_TYPE, '&web=1&channel=chunlei', '&shareid=', shareid, '&uk=', uk, ]) @@ -293,6 +302,7 @@ def verify_share_password(uk, shareid, pwd, vcode=''): pass # TODO: need verify code return None + def get_share_uk_and_shareid(cookie, url): '''从共享链接中提示uk和shareid. @@ -305,6 +315,7 @@ def get_share_uk_and_shareid(cookie, url): * http://pan.baidu.com/share/link?uk=202032639&shareid=420754 * http://pan.baidu.com/s/1i3iQY48 ''' + def parse_share_uk(content): '''代码片段如下: @@ -352,6 +363,7 @@ def parse_uk_from_url(url): uk, shareid = parse_uk_from_url(url) return False, uk, shareid + def get_share_dirname(url): '''从url中提取出当前的目录''' dirname_match = re.search('(dir|path)=([^&]+)', @@ -361,15 +373,17 @@ def get_share_dirname(url): else: return None + def get_share_url_with_dirname(uk, shareid, dirname): '''得到共享目录的链接''' return ''.join([ - const.PAN_URL, 'wap/link', - '?shareid=', shareid, - '&uk=', uk, - '&dir=', encoder.encode_uri_component(dirname), - '&third=0', - ]) + const.PAN_URL, 'wap/link', + '?shareid=', shareid, + '&uk=', uk, + '&dir=', encoder.encode_uri_component(dirname), + '&third=0', + ]) + def share_transfer(cookie, tokens, shareid, uk, filelist, dest, upload_mode): ''' @@ -381,7 +395,7 @@ def share_transfer(cookie, tokens, shareid, uk, filelist, dest, upload_mode): ondup = const.UPLOAD_ONDUP[upload_mode] url = ''.join([ const.PAN_URL, - 'share/transfer?app_id=250528&channel=chunlei&clienttype=0&web=1', + 'share/transfer?app_id=250528&channel=chunlei&clienttype=', const.PC_CLIENT_TYPE, '&web=1', '&bdstoken=', tokens['bdstoken'], '&from=', uk, '&shareid=', shareid, @@ -412,7 +426,7 @@ def list_inbox(cookie, tokens, start=0, limit=20): '&start=', str(start), '&limit=', str(limit), '&_=', util.timestamp(), - '&channel=chunlei&clienttype=0&web=1', + '&channel=chunlei&clienttype=', const.PC_CLIENT_TYPE, '&web=1', '&bdstoken=', tokens['bdstoken'], ]) req = net.urlopen(url, headers={'Cookie': cookie.header_output()}) @@ -422,6 +436,7 @@ def list_inbox(cookie, tokens, start=0, limit=20): else: return None + def list_trash(cookie, tokens, path='/', page=1, num=100): '''获取回收站的信息. @@ -433,7 +448,7 @@ def list_trash(cookie, tokens, path='/', page=1, num=100): ''' url = ''.join([ const.PAN_API_URL, - 'recycle/list?channel=chunlei&clienttype=0&web=1', + 'recycle/list?channel=chunlei&clienttype=', const.PC_CLIENT_TYPE, '&web=1', '&num=', str(num), '&t=', util.timestamp(), '&dir=', encoder.encode_uri_component(path), @@ -449,6 +464,7 @@ def list_trash(cookie, tokens, path='/', page=1, num=100): else: return None + def restore_trash(cookie, tokens, fidlist): '''从回收站中还原文件/目录. @@ -456,7 +472,7 @@ def restore_trash(cookie, tokens, fidlist): ''' url = ''.join([ const.PAN_API_URL, - 'recycle/restore?channel=chunlei&clienttype=0&web=1', + 'recycle/restore?channel=chunlei&clienttype=', const.PC_CLIENT_TYPE, '&web=1', '&t=', util.timestamp(), '&bdstoken=', tokens['bdstoken'], ]) @@ -464,13 +480,14 @@ def restore_trash(cookie, tokens, fidlist): req = net.urlopen(url, headers={ 'Cookie': cookie.header_output(), 'Content-type': const.CONTENT_FORM_UTF8, - }, data=data.encode()) + }, data=data.encode()) if req: content = req.data return json.loads(content.decode()) else: return None + def delete_trash(cookie, tokens, fidlist): '''批量将文件从回收站中删除, 这一步不可还原!' @@ -480,38 +497,40 @@ def delete_trash(cookie, tokens, fidlist): ''' url = ''.join([ const.PAN_API_URL, - 'recycle/delete?channel=chunlei&clienttype=0&web=1', + 'recycle/delete?channel=chunlei&clienttype=', const.PC_CLIENT_TYPE, '&web=1', '&bdstoken=', tokens['bdstoken'], ]) data = 'fidlist=' + encoder.encode_uri_component(json.dumps(fidlist)) req = net.urlopen(url, headers={ 'Cookie': cookie.header_output(), 'Content-type': const.CONTENT_FORM_UTF8, - }, data=data.encode()) + }, data=data.encode()) if req: content = req.data return json.loads(content.decode()) else: return None + def clear_trash(cookie, tokens): '''清空回收站, 将里面的所有文件都删除.''' url = ''.join([ const.PAN_API_URL, - 'recycle/clear?channel=chunlei&clienttype=0&web=1', + 'recycle/clear?channel=chunlei&clienttype=', const.PC_CLIENT_TYPE, '&web=1', '&t=', util.timestamp(), '&bdstoken=', tokens['bdstoken'], ]) # 使用POST方式发送命令, 但data为空. req = net.urlopen(url, headers={ 'Cookie': cookie.header_output(), - }, data=''.encode()) + }, data=''.encode()) if req: content = req.data return json.loads(content.decode()) else: return None + def list_dir_all(cookie, tokens, path): '''得到一个目录中所有文件的信息, 并返回它的文件列表''' pcs_files = [] @@ -525,12 +544,15 @@ def list_dir_all(cookie, tokens, path): pcs_files.extend(content['list']) page = page + 1 + def list_dir(cookie, tokens, path, page=1, num=100): '''得到一个目录中的所有文件的信息(最多100条记录).''' timestamp = util.timestamp() url = ''.join([ const.PAN_API_URL, - 'list?channel=chunlei&clienttype=0&web=1', + 'list?channel=chunlei', + '&clienttype=', const.PC_CLIENT_TYPE, + '&web=1', '&num=', str(num), '&t=', timestamp, '&page=', str(page), @@ -550,6 +572,7 @@ def list_dir(cookie, tokens, path, page=1, num=100): else: return None + def mkdir(cookie, tokens, path): '''创建一个目录. @@ -557,8 +580,8 @@ def mkdir(cookie, tokens, path): @return 返回一个dict, 里面包含了fs_id, ctime等信息. ''' url = ''.join([ - const.PAN_API_URL, - 'create?a=commit&channel=chunlei&clienttype=0&web=1', + const.PAN_API_URL, + 'create?a=commit&channel=chunlei&clienttype=', const.PC_CLIENT_TYPE, '&web=1', '&bdstoken=', tokens['bdstoken'], ]) data = ''.join([ @@ -568,13 +591,14 @@ def mkdir(cookie, tokens, path): req = net.urlopen(url, headers={ 'Cookie': cookie.header_output(), 'Content-type': const.CONTENT_FORM_UTF8, - }, data=data.encode()) + }, data=data.encode()) if req: content = req.data return json.loads(content.decode()) else: return None + def delete_files(cookie, tokens, filelist): '''批量删除文件/目录. @@ -582,20 +606,21 @@ def delete_files(cookie, tokens, filelist): ''' url = ''.join([ const.PAN_API_URL, - 'filemanager?channel=chunlei&clienttype=0&web=1&opera=delete', + 'filemanager?channel=chunlei&clienttype=', const.PC_CLIENT_TYPE, '&web=1&opera=delete', '&bdstoken=', tokens['bdstoken'], ]) data = 'filelist=' + encoder.encode_uri_component(json.dumps(filelist)) req = net.urlopen(url, headers={ 'Content-type': const.CONTENT_FORM_UTF8, 'Cookie': cookie.header_output(), - }, data=data.encode()) + }, data=data.encode()) if req: content = req.data return json.loads(content.decode()) else: return None + def rename(cookie, tokens, filelist): '''批量重命名目录/文件. @@ -607,20 +632,21 @@ def rename(cookie, tokens, filelist): ''' url = ''.join([ const.PAN_API_URL, - 'filemanager?channel=chunlei&clienttype=0&web=1&opera=rename', + 'filemanager?channel=chunlei&clienttype=', const.PC_CLIENT_TYPE, '&web=1&opera=rename', '&bdstoken=', tokens['bdstoken'], ]) data = 'filelist=' + encoder.encode_uri_component(json.dumps(filelist)) req = net.urlopen(url, headers={ 'Content-type': const.CONTENT_FORM_UTF8, 'Cookie': cookie.header_output(), - }, data=data.encode()) + }, data=data.encode()) if req: content = req.data return json.loads(content.decode()) else: return None + def move(cookie, tokens, filelist): '''移动文件/目录到新的位置. @@ -631,20 +657,21 @@ def move(cookie, tokens, filelist): ''' url = ''.join([ const.PAN_API_URL, - 'filemanager?channel=chunlei&clienttype=0&web=1&opera=move', + 'filemanager?channel=chunlei&clienttype=', const.PC_CLIENT_TYPE, '&web=1&opera=move', '&bdstoken=', tokens['bdstoken'], ]) data = 'filelist=' + encoder.encode_uri_component(json.dumps(filelist)) req = net.urlopen(url, headers={ 'Cookie': cookie.header_output(), 'Content-type': const.CONTENT_FORM_UTF8, - }, data=data.encode()) + }, data=data.encode()) if req: content = req.data return json.loads(content.decode()) else: return None + def copy(cookie, tokens, filelist): '''复制文件/目录到新位置. @@ -655,14 +682,14 @@ def copy(cookie, tokens, filelist): ''' url = ''.join([ const.PAN_API_URL, - 'filemanager?channel=chunlei&clienttype=0&web=1&opera=copy', + 'filemanager?channel=chunlei&clienttype=', const.PC_CLIENT_TYPE, '&web=1&opera=copy', '&bdstoken=', tokens['bdstoken'], ]) data = 'filelist=' + encoder.encode_uri_component(json.dumps(filelist)) req = net.urlopen(url, headers={ 'Cookie': cookie.header_output(), 'Content-type': const.CONTENT_FORM_UTF8, - }, data=data.encode()) + }, data=data.encode()) if req: content = req.data return json.loads(content.decode()) @@ -685,7 +712,7 @@ def get_category(cookie, tokens, category, page=1): timestamp = util.timestamp() url = ''.join([ const.PAN_API_URL, - 'categorylist?channel=chunlei&clienttype=0&web=1', + 'categorylist?channel=chunlei&clienttype=', const.PC_CLIENT_TYPE, '&web=1', '&category=', str(category), '&pri=-1&num=100', '&t=', timestamp, @@ -701,6 +728,7 @@ def get_category(cookie, tokens, category, page=1): else: return None + def get_download_link(cookie, tokens, path): '''在下载之前, 要先获取最终的下载链接. @@ -711,7 +739,7 @@ def get_download_link(cookie, tokens, path): ''' metas = get_metas(cookie, tokens, path) if (not metas or metas.get('errno', -1) != 0 or - 'info' not in metas or len(metas['info']) != 1): + 'info' not in metas or len(metas['info']) != 1): logger.error('pcs.get_download_link(): %s' % metas) return None dlink = metas['info'][0]['dlink'] @@ -725,6 +753,7 @@ def get_download_link(cookie, tokens, path): else: return req.getheader('Location', url) + def stream_download(cookie, tokens, path): '''下载流媒体文件. @@ -737,12 +766,13 @@ def stream_download(cookie, tokens, path): '&app_id=250528', ]) req = net.urlopen_without_redirect(url, headers= - {'Cookie': cookie.header_output()}) + {'Cookie': cookie.header_output()}) if req: return req else: return None + def get_streaming_playlist(cookie, path, video_type='M3U8_AUTO_480'): '''获取流媒体(通常是视频)的播放列表. @@ -764,7 +794,7 @@ def get_streaming_playlist(cookie, path, video_type='M3U8_AUTO_480'): return None -#def upload_option(cookie, path): +# def upload_option(cookie, path): # '''上传之前的检查. # # path - 准备在服务器上放到的绝对路径. @@ -812,6 +842,7 @@ def upload(cookie, source_path, path, upload_mode): else: return None + def rapid_upload(cookie, tokens, source_path, path, upload_mode): '''快速上传''' ondup = const.UPLOAD_ONDUP[upload_mode] @@ -839,6 +870,7 @@ def rapid_upload(cookie, tokens, source_path, path, upload_mode): else: return None + def slice_upload(cookie, data): '''分片上传一个大文件 @@ -854,13 +886,14 @@ def slice_upload(cookie, data): ]) fields = [] files = [('file', ' ', data)] - headers = {'Accept': const.ACCEPT_HTML,'Origin': const.PAN_URL} + headers = {'Accept': const.ACCEPT_HTML, 'Origin': const.PAN_URL} req = net.post_multipart(url, headers, fields, files) if req: return json.loads(req.data.decode()) else: return None + def create_superfile(cookie, path, block_list): '''合并slice_upload()中产生的临时文件 @@ -897,7 +930,9 @@ def get_metas(cookie, tokens, filelist, dlink=True): filelist = [filelist, ] url = ''.join([ const.PAN_API_URL, - 'filemetas?channel=chunlei&clienttype=0&web=1', + 'filemetas?channel=chunlei', + '&clienttype=', const.PC_CLIENT_TYPE, + '&web=1', '&bdstoken=', tokens['bdstoken'], ]) if dlink: @@ -909,13 +944,14 @@ def get_metas(cookie, tokens, filelist, dlink=True): req = net.urlopen(url, headers={ 'Cookie': cookie.sub_output('BDUSS'), 'Content-type': const.CONTENT_FORM, - }, data=data.encode()) + }, data=data.encode()) if req: content = req.data return json.loads(content.decode()) else: return None + def search(cookie, tokens, key, path='/'): '''搜索全部文件, 根据文件名. @@ -924,7 +960,9 @@ def search(cookie, tokens, key, path='/'): ''' url = ''.join([ const.PAN_API_URL, - 'search?channel=chunlei&clienttype=0&web=1', + 'search?channel=chunlei', + '&clienttype=', const.PC_CLIENT_TYPE, + '&web=1', '&dir=', path, '&key=', key, '&recursion', @@ -938,6 +976,7 @@ def search(cookie, tokens, key, path='/'): else: return None + def cloud_add_link_task(cookie, tokens, source_url, save_path, vcode='', vcode_input=''): '''新建离线下载任务. @@ -948,7 +987,8 @@ def cloud_add_link_task(cookie, tokens, source_url, save_path, ''' url = ''.join([ const.PAN_URL, - 'rest/2.0/services/cloud_dl?channel=chunlei&clienttype=0&web=1', + 'rest/2.0/services/cloud_dl?channel=chunlei', + '&clienttype=', const.PC_CLIENT_TYPE, '&web=1', '&bdstoken=', tokens['bdstoken'], ]) type_ = '' @@ -976,6 +1016,7 @@ def cloud_add_link_task(cookie, tokens, source_url, save_path, else: return None + def cloud_add_bt_task(cookie, tokens, source_url, save_path, selected_idx, file_sha1='', vcode='', vcode_input=''): '''新建一个BT类的离线下载任务, 包括magent磁链. @@ -990,7 +1031,8 @@ def cloud_add_bt_task(cookie, tokens, source_url, save_path, selected_idx, ''' url = ''.join([ const.PAN_URL, - 'rest/2.0/services/cloud_dl?channel=chunlei&clienttype=0&web=1', + 'rest/2.0/services/cloud_dl?channel=chunlei', + '&clienttype=', const.PC_CLIENT_TYPE, '&web=1', '&bdstoken=', tokens['bdstoken'], ]) type_ = '2' @@ -1024,6 +1066,7 @@ def cloud_add_bt_task(cookie, tokens, source_url, save_path, selected_idx, else: return None + def cloud_query_sinfo(cookie, tokens, source_path): '''获取网盘中种子的信息, 比如里面的文件名, 文件大小等. @@ -1031,7 +1074,7 @@ def cloud_query_sinfo(cookie, tokens, source_path): ''' url = ''.join([ const.PAN_URL, - 'rest/2.0/services/cloud_dl?channel=chunlei&clienttype=0&web=1', + 'rest/2.0/services/cloud_dl?channel=chunlei', '&clienttype=', const.PC_CLIENT_TYPE, '&web=1', '&method=query_sinfo&app_id=250528', '&bdstoken=', tokens['bdstoken'], '&source_path=', encoder.encode_uri_component(source_path), @@ -1045,6 +1088,7 @@ def cloud_query_sinfo(cookie, tokens, source_path): else: return None + def cloud_query_magnetinfo(cookie, tokens, source_url, save_path): '''获取磁链的信息. @@ -1056,7 +1100,7 @@ def cloud_query_magnetinfo(cookie, tokens, source_url, save_path): ''' url = ''.join([ const.PAN_URL, - 'rest/2.0/services/cloud_dl?channel=chunlei&clienttype=0&web=1', + 'rest/2.0/services/cloud_dl?channel=chunlei', '&clienttype=', const.PC_CLIENT_TYPE, '&web=1', '&bdstoken=', tokens['bdstoken'], ]) data = ''.join([ @@ -1073,6 +1117,7 @@ def cloud_query_magnetinfo(cookie, tokens, source_url, save_path): else: return None + def cloud_list_task(cookie, tokens, start=0): '''获取当前离线下载的任务信息 @@ -1080,7 +1125,7 @@ def cloud_list_task(cookie, tokens, start=0): ''' url = ''.join([ const.PAN_URL, - 'rest/2.0/services/cloud_dl?channel=chunlei&clienttype=0&web=1', + 'rest/2.0/services/cloud_dl?channel=chunlei&clienttype=', const.PC_CLIENT_TYPE, '&web=1', '&bdstoken=', tokens['bdstoken'], '&need_task_info=1&status=255', '&start=', str(start), @@ -1094,6 +1139,7 @@ def cloud_list_task(cookie, tokens, start=0): else: return None + def cloud_query_task(cookie, tokens, task_ids): '''查询离线下载任务的信息, 比如进度, 是否完成下载等. @@ -1108,7 +1154,7 @@ def cloud_query_task(cookie, tokens, task_ids): '&bdstoken=', tokens['bdstoken'], '&task_ids=', ','.join(task_ids), '&t=', util.timestamp(), - '&channel=chunlei&clienttype=0&web=1', + '&channel=chunlei&clienttype=', const.PC_CLIENT_TYPE, '&web=1', ]) req = net.urlopen(url, headers={'Cookie': cookie.header_output()}) if req: @@ -1117,6 +1163,7 @@ def cloud_query_task(cookie, tokens, task_ids): else: return None + def cloud_cancel_task(cookie, tokens, task_id): '''取消离线下载任务. @@ -1130,7 +1177,7 @@ def cloud_cancel_task(cookie, tokens, task_id): '&task_id=', str(task_id), '&method=cancel_task&app_id=250528', '&t=', util.timestamp(), - '&channel=chunlei&clienttype=0&web=1', + '&channel=chunlei&clienttype=', const.PC_CLIENT_TYPE, '&web=1', ]) req = net.urlopen(url, headers={'Cookie': cookie.header_output()}) if req: @@ -1139,6 +1186,7 @@ def cloud_cancel_task(cookie, tokens, task_id): else: return None + def cloud_delete_task(cookie, tokens, task_id): '''删除一个离线下载任务, 不管这个任务是否已完成下载. @@ -1151,7 +1199,7 @@ def cloud_delete_task(cookie, tokens, task_id): '&task_id=', str(task_id), '&method=delete_task&app_id=250528', '&t=', util.timestamp(), - '&channel=chunlei&clienttype=0&web=1', + '&channel=chunlei&clienttype=', const.PC_CLIENT_TYPE, '&web=1', ]) req = net.urlopen(url, headers={'Cookie': cookie.header_output()}) if req: @@ -1160,12 +1208,13 @@ def cloud_delete_task(cookie, tokens, task_id): else: return None + def cloud_clear_task(cookie, tokens): '''清空离线下载的历史(已经完成或者取消的).''' url = ''.join([ const.PAN_URL, 'rest/2.0/services/cloud_dl?method=clear_task&app_id=250528', - '&channel=chunlei&clienttype=0&web=1', + '&channel=chunlei&clienttype=', const.PC_CLIENT_TYPE, '&web=1', '&t=', util.timestamp(), '&bdstoken=', tokens['bdstoken'], ]) @@ -1175,4 +1224,3 @@ def cloud_clear_task(cookie, tokens): return json.loads(content.decode()) else: return None - diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..785d1fb --- /dev/null +++ b/debian/changelog @@ -0,0 +1,24 @@ +bcloud (3.9.1+git20170619-1) unstable; urgency=medium + + * New upstream snapshot. + + -- Boyuan Yang <073plan@gmail.com> Wed, 28 Jun 2017 17:03:14 +0800 + +bcloud (3.9.1+git20170531-1) unstable; urgency=medium + + * New upstream snapshot. + + -- Boyuan Yang <073plan@gmail.com> Thu, 01 Jun 2017 19:38:14 +0800 + +bcloud (3.9.1+git20170526-1) unstable; urgency=medium + + * New upstream snapshot. + + Finished zh_CN translations. + + -- Boyuan Yang <073plan@gmail.com> Fri, 26 May 2017 21:31:47 +0800 + +bcloud (3.9.1+git20170406-1) unstable; urgency=medium + + * Initial repack for Debian unstable. + + -- Boyuan Yang <073plan@gmail.com> Mon, 24 Apr 2017 17:19:54 +0800 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..ec63514 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +9 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..c413799 --- /dev/null +++ b/debian/control @@ -0,0 +1,41 @@ +Source: bcloud +Maintainer: Yufei Kang +Uploaders: + Boyuan Yang <073plan@gmail.com>, +Section: python +Priority: optional +Build-Depends: + debhelper (>= 9), + dh-python, + python3-all, + python3-setuptools, +Standards-Version: 3.9.8 +X-Python3-Version: >= 3.3 +Homepage: https://github.com/Yufeikang/bcloud +Vcs-Git: https://github.com/Yufeikang/bcloud.git +Vcs-Browser: https://github.com/Yufeikang/bcloud.git + +Package: bcloud +Architecture: all +Depends: + gir1.2-appindicator3-0.1, + gir1.2-gnomekeyring-1.0, + gir1.2-gtk-3.0, + gir1.2-notify-0.7, + python3-crypto, + python3-cssselect, + python3-dbus, + python3-gi, + python3-keyring, + python3-lxml, + python3-pyinotify, + python3-urllib3, + ${misc:Depends}, + ${python3:Depends}, +Recommends: + notification-daemon, +Suggests: + gnome-icon-theme-symbolic, +Description: Baidu Pan client for Linux users + Alternative client of Baidu Pan (Baidu Personal Cloud) for Linux desktop + users. diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..929b70b --- /dev/null +++ b/debian/copyright @@ -0,0 +1,29 @@ +Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: bcloud +Upstream-Contact: Yufei Kang +Source: https://github.com/Yufeikang/bcloud + +Files: * +Copyright: 2014-2016, Liu Lang + 2016-2017, Yufei Kang +License: GPL-3 + +Files: debian/* +Copyright: 2017, Boyuan Yang <073plan@gmail.com> +License: GPL-3 + +License: GPL-3 + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License version 3 as + published by the Free Software Foundation. + . + This package is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + . + You should have received a copy of the GNU General Public License + along with this program. If not, see . + . + On Debian systems, the complete text of the GNU General Public + License version 3 can be found in "/usr/share/common-licenses/GPL-3". diff --git a/debian/docs b/debian/docs new file mode 100644 index 0000000..b43bf86 --- /dev/null +++ b/debian/docs @@ -0,0 +1 @@ +README.md diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..624ff3c --- /dev/null +++ b/debian/rules @@ -0,0 +1,6 @@ +#!/usr/bin/make -f + +export PYBUILD_NAME=bcloud + +%: + dh $@ --with python3 --buildsystem=pybuild diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 0000000..163aaf8 --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/debian/watch b/debian/watch new file mode 100644 index 0000000..70786fa --- /dev/null +++ b/debian/watch @@ -0,0 +1,4 @@ +version=4 +opts="filenamemangle=s%(?:.*?)?v?(\d[\d.]*)\.tar\.gz%bcloud-$1.tar.gz%" \ + https://github.com/Yufeikang/bcloud/tags \ + (?:.*?/)?v?(\d[\d.]*)\.tar\.gz debian uupdate diff --git a/po/bcloud.pot b/po/bcloud.pot index c1ab41a..5e4bf9c 100644 --- a/po/bcloud.pot +++ b/po/bcloud.pot @@ -8,48 +8,48 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-05-16 01:46+0800\n" +"POT-Creation-Date: 2017-05-26 21:27+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=CHARSET\n" +"Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: ../bcloud/App.py:100 ../bcloud/PreferencesDialog.py:18 +#: ../bcloud/App.py:104 ../bcloud/PreferencesDialog.py:18 msgid "Preferences" msgstr "" -#: ../bcloud/App.py:101 +#: ../bcloud/App.py:105 msgid "Sign out" msgstr "" -#: ../bcloud/App.py:102 +#: ../bcloud/App.py:106 msgid "About" msgstr "" -#: ../bcloud/App.py:103 ../bcloud/App.py:443 +#: ../bcloud/App.py:107 ../bcloud/App.py:450 msgid "Quit" msgstr "" -#: ../bcloud/App.py:155 +#: ../bcloud/App.py:160 msgid "Unknown" msgstr "" -#: ../bcloud/App.py:421 +#: ../bcloud/App.py:428 msgid "Show App" msgstr "" -#: ../bcloud/App.py:429 +#: ../bcloud/App.py:436 msgid "Pause Upload Tasks" msgstr "" -#: ../bcloud/App.py:435 +#: ../bcloud/App.py:442 msgid "Pause Download Tasks" msgstr "" -#: ../bcloud/App.py:489 +#: ../bcloud/App.py:496 #, python-brace-format msgid "{0} copied to clipboard" msgstr "" @@ -59,15 +59,15 @@ msgid "Select All" msgstr "" #: ../bcloud/BTBrowserDialog.py:64 ../bcloud/CloudPage.py:150 -#: ../bcloud/DownloadPage.py:223 ../bcloud/IconWindow.py:688 +#: ../bcloud/DownloadPage.py:246 ../bcloud/IconWindow.py:712 #: ../bcloud/SharePage.py:162 ../bcloud/TrashPage.py:141 #: ../bcloud/UploadPage.py:205 msgid "Name" msgstr "" #: ../bcloud/BTBrowserDialog.py:68 ../bcloud/CloudPage.py:157 -#: ../bcloud/DownloadPage.py:237 ../bcloud/IconWindow.py:704 -#: ../bcloud/PropertiesDialog.py:55 ../bcloud/SharePage.py:174 +#: ../bcloud/DownloadPage.py:260 ../bcloud/IconWindow.py:728 +#: ../bcloud/PropertiesDialog.py:58 ../bcloud/SharePage.py:174 #: ../bcloud/TrashPage.py:156 ../bcloud/UploadPage.py:219 msgid "Size" msgstr "" @@ -141,12 +141,12 @@ msgstr "" msgid "Create new cloud task" msgstr "" -#: ../bcloud/CloudPage.py:63 ../bcloud/DownloadPage.py:118 +#: ../bcloud/CloudPage.py:63 ../bcloud/DownloadPage.py:141 #: ../bcloud/UploadPage.py:92 msgid "Open target directory" msgstr "" -#: ../bcloud/CloudPage.py:78 ../bcloud/DownloadPage.py:144 +#: ../bcloud/CloudPage.py:78 ../bcloud/DownloadPage.py:167 #: ../bcloud/UploadPage.py:131 msgid "Remove selected tasks" msgstr "" @@ -159,7 +159,7 @@ msgstr "" msgid "New Link Task" msgstr "" -#: ../bcloud/CloudPage.py:114 ../bcloud/DownloadPage.py:171 +#: ../bcloud/CloudPage.py:114 ../bcloud/DownloadPage.py:194 #: ../bcloud/UploadPage.py:168 msgid "Open Directory" msgstr "" @@ -169,12 +169,12 @@ msgid "Clear" msgstr "" #: ../bcloud/CloudPage.py:123 ../bcloud/CloudPage.py:124 -#: ../bcloud/DownloadPage.py:192 ../bcloud/DownloadPage.py:792 +#: ../bcloud/DownloadPage.py:215 ../bcloud/DownloadPage.py:818 #: ../bcloud/TrashPage.py:66 ../bcloud/UploadPage.py:180 msgid "Remove" msgstr "" -#: ../bcloud/CloudPage.py:163 ../bcloud/DownloadPage.py:230 +#: ../bcloud/CloudPage.py:163 ../bcloud/DownloadPage.py:253 #: ../bcloud/UploadPage.py:212 msgid "Progress" msgstr "" @@ -213,7 +213,7 @@ msgstr "" msgid "Support http/https/ftp/thunder/qqdl/flashget/eMule/Magnet format" msgstr "" -#: ../bcloud/Config.py:55 +#: ../bcloud/Config.py:57 msgid "Baidu Pan client for GNU/Linux desktop users." msgstr "" @@ -233,93 +233,105 @@ msgstr "" msgid "ERROR" msgstr "" -#: ../bcloud/DownloadPage.py:68 ../bcloud/IconWindow.py:346 -#: ../bcloud/PreferencesDialog.py:93 +#: ../bcloud/DownloadPage.py:49 +msgid "Do you want to remove unfinished tasks?" +msgstr "" + +#: ../bcloud/DownloadPage.py:51 +msgid "Do you want to remove unfinished task?" +msgstr "" + +#: ../bcloud/DownloadPage.py:57 +msgid "Do not ask again" +msgstr "" + +#: ../bcloud/DownloadPage.py:91 ../bcloud/IconWindow.py:346 +#: ../bcloud/PreferencesDialog.py:110 msgid "Download" msgstr "" -#: ../bcloud/DownloadPage.py:70 +#: ../bcloud/DownloadPage.py:93 msgid "Downloading files" msgstr "" -#: ../bcloud/DownloadPage.py:101 ../bcloud/DownloadPage.py:163 +#: ../bcloud/DownloadPage.py:124 ../bcloud/DownloadPage.py:186 #: ../bcloud/UploadPage.py:75 ../bcloud/UploadPage.py:147 msgid "Start" msgstr "" -#: ../bcloud/DownloadPage.py:110 ../bcloud/DownloadPage.py:167 +#: ../bcloud/DownloadPage.py:133 ../bcloud/DownloadPage.py:190 #: ../bcloud/UploadPage.py:84 ../bcloud/UploadPage.py:151 msgid "Pause" msgstr "" -#: ../bcloud/DownloadPage.py:128 ../bcloud/DownloadPage.py:180 +#: ../bcloud/DownloadPage.py:151 ../bcloud/DownloadPage.py:203 msgid "Shutdown system after all tasks have finished" msgstr "" -#: ../bcloud/DownloadPage.py:152 ../bcloud/DownloadPage.py:187 +#: ../bcloud/DownloadPage.py:175 ../bcloud/DownloadPage.py:210 #: ../bcloud/UploadPage.py:139 ../bcloud/UploadPage.py:175 msgid "Remove completed tasks" msgstr "" -#: ../bcloud/DownloadPage.py:178 +#: ../bcloud/DownloadPage.py:201 msgid "Shutdown" msgstr "" -#: ../bcloud/DownloadPage.py:243 ../bcloud/UploadPage.py:225 +#: ../bcloud/DownloadPage.py:266 ../bcloud/UploadPage.py:225 msgid "State" msgstr "" -#: ../bcloud/DownloadPage.py:390 +#: ../bcloud/DownloadPage.py:413 msgid "Failed to scan folder to download" msgstr "" -#: ../bcloud/DownloadPage.py:392 +#: ../bcloud/DownloadPage.py:415 #, python-brace-format msgid "Please download {0} again" msgstr "" -#: ../bcloud/DownloadPage.py:415 +#: ../bcloud/DownloadPage.py:438 #, python-brace-format msgid "Task exists: {0}" msgstr "" -#: ../bcloud/DownloadPage.py:425 ../bcloud/UploadPage.py:495 +#: ../bcloud/DownloadPage.py:450 ../bcloud/UploadPage.py:495 #, python-brace-format msgid "" "From {0}\n" "To {1}" msgstr "" -#: ../bcloud/DownloadPage.py:509 +#: ../bcloud/DownloadPage.py:534 #, python-brace-format msgid "{0} downloaded" msgstr "" -#: ../bcloud/DownloadPage.py:532 +#: ../bcloud/DownloadPage.py:557 #, python-brace-format msgid "Error occurs will downloading {0}" msgstr "" -#: ../bcloud/DownloadPage.py:538 +#: ../bcloud/DownloadPage.py:563 #, python-brace-format msgid "Disk Error: failed to read/write {0}" msgstr "" -#: ../bcloud/DownloadPage.py:757 ../bcloud/DownloadPage.py:782 +#: ../bcloud/DownloadPage.py:783 ../bcloud/DownloadPage.py:808 #: ../bcloud/IconWindow.py:301 ../bcloud/IconWindow.py:328 #, python-brace-format msgid "Open With {0}" msgstr "" -#: ../bcloud/DownloadPage.py:760 ../bcloud/IconWindow.py:305 +#: ../bcloud/DownloadPage.py:786 ../bcloud/IconWindow.py:305 msgid "Open With" msgstr "" -#: ../bcloud/DownloadPage.py:772 ../bcloud/IconWindow.py:317 +#: ../bcloud/DownloadPage.py:798 ../bcloud/IconWindow.py:317 msgid "Other Application..." msgstr "" -#: ../bcloud/DownloadPage.py:785 ../bcloud/IconWindow.py:332 +#: ../bcloud/DownloadPage.py:811 ../bcloud/IconWindow.py:332 msgid "Open With Other Application..." msgstr "" @@ -355,7 +367,7 @@ msgstr "" msgid "Search documents and folders by name" msgstr "" -#: ../bcloud/IconWindow.py:176 ../bcloud/IconWindow.py:753 +#: ../bcloud/IconWindow.py:176 ../bcloud/IconWindow.py:777 msgid "Error: Move folder to itself!" msgstr "" @@ -372,7 +384,7 @@ msgstr "" msgid "Upload Folders..." msgstr "" -#: ../bcloud/IconWindow.py:239 ../bcloud/IconWindow.py:376 +#: ../bcloud/IconWindow.py:239 ../bcloud/IconWindow.py:379 msgid "Properties" msgstr "" @@ -396,39 +408,47 @@ msgstr "" msgid "Copy Link" msgstr "" -#: ../bcloud/IconWindow.py:349 ../bcloud/SharePage.py:59 +#: ../bcloud/IconWindow.py:349 +msgid "Download to..." +msgstr "" + +#: ../bcloud/IconWindow.py:352 ../bcloud/SharePage.py:59 msgid "Share" msgstr "" -#: ../bcloud/IconWindow.py:352 +#: ../bcloud/IconWindow.py:355 msgid "Private Share" msgstr "" -#: ../bcloud/IconWindow.py:358 ../bcloud/IconWindow.py:574 +#: ../bcloud/IconWindow.py:361 ../bcloud/IconWindow.py:598 msgid "Move To..." msgstr "" -#: ../bcloud/IconWindow.py:361 ../bcloud/IconWindow.py:598 +#: ../bcloud/IconWindow.py:364 ../bcloud/IconWindow.py:622 msgid "Copy To..." msgstr "" -#: ../bcloud/IconWindow.py:364 +#: ../bcloud/IconWindow.py:367 msgid "Rename..." msgstr "" -#: ../bcloud/IconWindow.py:370 +#: ../bcloud/IconWindow.py:373 msgid "Move to Trash" msgstr "" -#: ../bcloud/IconWindow.py:507 +#: ../bcloud/IconWindow.py:510 msgid "Failed to copy link" msgstr "" -#: ../bcloud/IconWindow.py:533 ../bcloud/IconWindow.py:553 +#: ../bcloud/IconWindow.py:537 +msgid "Save to..." +msgstr "" + +#: ../bcloud/IconWindow.py:557 ../bcloud/IconWindow.py:577 msgid "Failed to share selected files" msgstr "" -#: ../bcloud/IconWindow.py:711 ../bcloud/SharePage.py:180 +#: ../bcloud/IconWindow.py:735 ../bcloud/SharePage.py:180 msgid "Modified" msgstr "" @@ -463,131 +483,139 @@ msgid "Use Status Icon:" msgstr "" #: ../bcloud/PreferencesDialog.py:77 +msgid "Startup minimized:" +msgstr "" + +#: ../bcloud/PreferencesDialog.py:94 msgid "Display Avatar:" msgstr "" -#: ../bcloud/PreferencesDialog.py:95 +#: ../bcloud/PreferencesDialog.py:112 msgid "Save To:" msgstr "" -#: ../bcloud/PreferencesDialog.py:104 +#: ../bcloud/PreferencesDialog.py:121 msgid "Concurrent downloads:" msgstr "" -#: ../bcloud/PreferencesDialog.py:114 +#: ../bcloud/PreferencesDialog.py:131 msgid "Per task:" msgstr "" -#: ../bcloud/PreferencesDialog.py:122 +#: ../bcloud/PreferencesDialog.py:139 msgid "connections" msgstr "" -#: ../bcloud/PreferencesDialog.py:126 +#: ../bcloud/PreferencesDialog.py:143 msgid "Retries each:" msgstr "" -#: ../bcloud/PreferencesDialog.py:133 +#: ../bcloud/PreferencesDialog.py:150 msgid "0: disable retries" msgstr "" -#: ../bcloud/PreferencesDialog.py:135 +#: ../bcloud/PreferencesDialog.py:152 msgid "minutes" msgstr "" -#: ../bcloud/PreferencesDialog.py:139 +#: ../bcloud/PreferencesDialog.py:156 msgid "Download timeout:" msgstr "" -#: ../bcloud/PreferencesDialog.py:148 +#: ../bcloud/PreferencesDialog.py:165 msgid "seconds" msgstr "" -#: ../bcloud/PreferencesDialog.py:152 +#: ../bcloud/PreferencesDialog.py:169 msgid "File exists while downloading:" msgstr "" -#: ../bcloud/PreferencesDialog.py:156 ../bcloud/PreferencesDialog.py:200 +#: ../bcloud/PreferencesDialog.py:173 ../bcloud/PreferencesDialog.py:228 msgid "Do Nothing" msgstr "" -#: ../bcloud/PreferencesDialog.py:157 ../bcloud/PreferencesDialog.py:201 +#: ../bcloud/PreferencesDialog.py:174 ../bcloud/PreferencesDialog.py:229 msgid "Overwrite" msgstr "" -#: ../bcloud/PreferencesDialog.py:158 ../bcloud/PreferencesDialog.py:202 +#: ../bcloud/PreferencesDialog.py:175 ../bcloud/PreferencesDialog.py:230 msgid "Rename Automatically" msgstr "" -#: ../bcloud/PreferencesDialog.py:162 +#: ../bcloud/PreferencesDialog.py:179 msgid "What to do when downloading a file which already exists on local disk" msgstr "" -#: ../bcloud/PreferencesDialog.py:172 ../bcloud/UploadPage.py:48 +#: ../bcloud/PreferencesDialog.py:183 +msgid "Ask me when deleting unfinished tasks:" +msgstr "" + +#: ../bcloud/PreferencesDialog.py:200 ../bcloud/UploadPage.py:48 msgid "Upload" msgstr "" -#: ../bcloud/PreferencesDialog.py:174 +#: ../bcloud/PreferencesDialog.py:202 msgid "Concurrent uploads:" msgstr "" -#: ../bcloud/PreferencesDialog.py:184 +#: ../bcloud/PreferencesDialog.py:212 msgid "Upload hidden files:" msgstr "" -#: ../bcloud/PreferencesDialog.py:190 +#: ../bcloud/PreferencesDialog.py:218 msgid "Also upload hidden files and folders" msgstr "" -#: ../bcloud/PreferencesDialog.py:196 +#: ../bcloud/PreferencesDialog.py:224 msgid "File exists while uploading:" msgstr "" -#: ../bcloud/PreferencesDialog.py:205 +#: ../bcloud/PreferencesDialog.py:233 msgid "What to do when uploading a file which already exists on server" msgstr "" -#: ../bcloud/PreferencesDialog.py:209 +#: ../bcloud/PreferencesDialog.py:237 msgid "Enable Sync:" msgstr "" -#: ../bcloud/PreferencesDialog.py:217 +#: ../bcloud/PreferencesDialog.py:245 msgid "Sync Dir:" msgstr "" -#: ../bcloud/PreferencesDialog.py:226 +#: ../bcloud/PreferencesDialog.py:254 msgid "Dest Sync Dir:" msgstr "" -#: ../bcloud/PropertiesDialog.py:26 ../bcloud/PropertiesDialog.py:95 +#: ../bcloud/PropertiesDialog.py:26 ../bcloud/PropertiesDialog.py:98 msgid " Properties" msgstr "" -#: ../bcloud/PropertiesDialog.py:42 ../bcloud/PropertiesDialog.py:108 +#: ../bcloud/PropertiesDialog.py:45 ../bcloud/PropertiesDialog.py:114 msgid "Name:" msgstr "" -#: ../bcloud/PropertiesDialog.py:47 ../bcloud/PropertiesDialog.py:113 +#: ../bcloud/PropertiesDialog.py:50 ../bcloud/PropertiesDialog.py:119 msgid "Location:" msgstr "" -#: ../bcloud/PropertiesDialog.py:60 ../bcloud/PropertiesDialog.py:62 +#: ../bcloud/PropertiesDialog.py:63 ../bcloud/PropertiesDialog.py:65 msgid " bytes" msgstr "" -#: ../bcloud/PropertiesDialog.py:75 +#: ../bcloud/PropertiesDialog.py:78 msgid "Created:" msgstr "" -#: ../bcloud/PropertiesDialog.py:80 +#: ../bcloud/PropertiesDialog.py:83 msgid "Modified:" msgstr "" -#: ../bcloud/PropertiesDialog.py:125 +#: ../bcloud/PropertiesDialog.py:131 #, python-brace-format msgid "{0} folders, {1} files" msgstr "" -#: ../bcloud/PropertiesDialog.py:126 +#: ../bcloud/PropertiesDialog.py:132 msgid "Contents:" msgstr "" @@ -678,87 +706,103 @@ msgstr "" msgid "Remember Password" msgstr "" -#: ../bcloud/SigninDialog.py:165 +#: ../bcloud/SigninDialog.py:168 msgid "Signin Automatically" msgstr "" -#: ../bcloud/SigninDialog.py:171 ../bcloud/SigninDialog.py:240 +#: ../bcloud/SigninDialog.py:177 ../bcloud/SigninDialog.py:246 msgid "Sign in" msgstr "" -#: ../bcloud/SigninDialog.py:181 +#: ../bcloud/SigninDialog.py:187 msgid "Failed to sign in, please try again." msgstr "" -#: ../bcloud/SigninDialog.py:265 ../bcloud/SigninDialog.py:274 +#: ../bcloud/SigninDialog.py:271 ../bcloud/SigninDialog.py:280 msgid "In process..." msgstr "" -#: ../bcloud/SigninDialog.py:283 +#: ../bcloud/SigninDialog.py:289 msgid "Failed to get bdstoken!" msgstr "" -#: ../bcloud/SigninDialog.py:295 +#: ../bcloud/SigninDialog.py:301 msgid "Login failed, please try again" msgstr "" -#: ../bcloud/SigninDialog.py:300 ../bcloud/SigninDialog.py:320 +#: ../bcloud/SigninDialog.py:306 ../bcloud/SigninDialog.py:322 msgid "Get bdstoken..." msgstr "" -#: ../bcloud/SigninDialog.py:317 ../bcloud/SigninDialog.py:381 -msgid "Please input verification code!" -msgstr "" - -#: ../bcloud/SigninDialog.py:329 +#: ../bcloud/SigninDialog.py:331 msgid "Password error, please try again" msgstr "" -#: ../bcloud/SigninDialog.py:333 +#: ../bcloud/SigninDialog.py:335 msgid "Verfication code error, please try again" msgstr "" -#: ../bcloud/SigninDialog.py:339 +#: ../bcloud/SigninDialog.py:341 msgid "Does not support SMS/Email verification!" msgstr "" -#: ../bcloud/SigninDialog.py:343 +#: ../bcloud/SigninDialog.py:347 +msgid "NET:登录失败,请在弹出的窗口操作,或重新登录" +msgstr "" + +#: ../bcloud/SigninDialog.py:352 +msgid "NET:近期登录次数过多, 请先通过 passport.baidu.com 解除锁定" +msgstr "" + +#: ../bcloud/SigninDialog.py:357 +msgid "NET:登录过于频繁,请24小时后再试" +msgstr "" + +#: ../bcloud/SigninDialog.py:362 +msgid "NET:账号异常,请在当前网络环境下在百度网页端正常登录一次" +msgstr "" + +#: ../bcloud/SigninDialog.py:366 msgid "Unknown error, please try again" msgstr "" -#: ../bcloud/SigninDialog.py:350 +#: ../bcloud/SigninDialog.py:373 msgid "Failed to request public key, please try again" msgstr "" -#: ../bcloud/SigninDialog.py:365 +#: ../bcloud/SigninDialog.py:388 msgid "Failed to check login, please try again" msgstr "" -#: ../bcloud/SigninDialog.py:394 +#: ../bcloud/SigninDialog.py:405 +msgid "Please input verification code!" +msgstr "" + +#: ../bcloud/SigninDialog.py:418 msgid "Failed to get UBI, please try again." msgstr "" -#: ../bcloud/SigninDialog.py:397 +#: ../bcloud/SigninDialog.py:421 msgid "Check login" msgstr "" -#: ../bcloud/SigninDialog.py:405 +#: ../bcloud/SigninDialog.py:429 msgid "Failed to get token, please try again." msgstr "" -#: ../bcloud/SigninDialog.py:412 +#: ../bcloud/SigninDialog.py:436 msgid "Get UBI..." msgstr "" -#: ../bcloud/SigninDialog.py:421 +#: ../bcloud/SigninDialog.py:445 msgid "Failed to get BAIDUID cookie, please try again." msgstr "" -#: ../bcloud/SigninDialog.py:424 +#: ../bcloud/SigninDialog.py:448 msgid "Get TOKEN..." msgstr "" -#: ../bcloud/SigninDialog.py:442 +#: ../bcloud/SigninDialog.py:465 msgid "Get BAIDUID..." msgstr "" diff --git a/po/zh_CN.po b/po/zh_CN.po index 255f5c8..b0fcad9 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -2,54 +2,55 @@ # Copyright (C) 2014 THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # LiuLang , 2014. +# Boyuan Yang <073plan@gmail.coom>, 2017. # msgid "" msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" +"Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-05-16 01:46+0800\n" -"PO-Revision-Date: 2014-10-21 17:14+0800\n" -"Last-Translator: CzBiX \n" -"Language-Team: Chinese (simplified)\n" +"POT-Creation-Date: 2017-05-26 21:27+0800\n" +"PO-Revision-Date: 2017-05-26 21:29+0800\n" +"Last-Translator: Boyuan Yang <073plan@gmail.com>\n" +"Language-Team: Chinese (Simplified) \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 1.5.4\n" +"X-Generator: Poedit 1.8.11\n" -#: ../bcloud/App.py:100 ../bcloud/PreferencesDialog.py:18 +#: ../bcloud/App.py:104 ../bcloud/PreferencesDialog.py:18 msgid "Preferences" msgstr "首选项" -#: ../bcloud/App.py:101 +#: ../bcloud/App.py:105 msgid "Sign out" msgstr "注销" -#: ../bcloud/App.py:102 +#: ../bcloud/App.py:106 msgid "About" msgstr "关于" -#: ../bcloud/App.py:103 ../bcloud/App.py:443 +#: ../bcloud/App.py:107 ../bcloud/App.py:450 msgid "Quit" msgstr "退出" -#: ../bcloud/App.py:155 +#: ../bcloud/App.py:160 msgid "Unknown" msgstr "未知" -#: ../bcloud/App.py:421 +#: ../bcloud/App.py:428 msgid "Show App" msgstr "显示程序" -#: ../bcloud/App.py:429 +#: ../bcloud/App.py:436 msgid "Pause Upload Tasks" msgstr "暂停所有上传任务" -#: ../bcloud/App.py:435 +#: ../bcloud/App.py:442 msgid "Pause Download Tasks" msgstr "暂停所有下载任务" -#: ../bcloud/App.py:489 +#: ../bcloud/App.py:496 #, python-brace-format msgid "{0} copied to clipboard" msgstr "{0} 已被复制到剪贴板" @@ -59,15 +60,15 @@ msgid "Select All" msgstr "全选" #: ../bcloud/BTBrowserDialog.py:64 ../bcloud/CloudPage.py:150 -#: ../bcloud/DownloadPage.py:223 ../bcloud/IconWindow.py:688 +#: ../bcloud/DownloadPage.py:246 ../bcloud/IconWindow.py:712 #: ../bcloud/SharePage.py:162 ../bcloud/TrashPage.py:141 #: ../bcloud/UploadPage.py:205 msgid "Name" msgstr "文件名" #: ../bcloud/BTBrowserDialog.py:68 ../bcloud/CloudPage.py:157 -#: ../bcloud/DownloadPage.py:237 ../bcloud/IconWindow.py:704 -#: ../bcloud/PropertiesDialog.py:55 ../bcloud/SharePage.py:174 +#: ../bcloud/DownloadPage.py:260 ../bcloud/IconWindow.py:728 +#: ../bcloud/PropertiesDialog.py:58 ../bcloud/SharePage.py:174 #: ../bcloud/TrashPage.py:156 ../bcloud/UploadPage.py:219 msgid "Size" msgstr "大小" @@ -141,15 +142,15 @@ msgstr "离线下载" msgid "Create new cloud task" msgstr "新建离线下载" -#: ../bcloud/CloudPage.py:63 ../bcloud/DownloadPage.py:118 +#: ../bcloud/CloudPage.py:63 ../bcloud/DownloadPage.py:141 #: ../bcloud/UploadPage.py:92 msgid "Open target directory" msgstr "打开所在目录" -#: ../bcloud/CloudPage.py:78 ../bcloud/DownloadPage.py:144 +#: ../bcloud/CloudPage.py:78 ../bcloud/DownloadPage.py:167 #: ../bcloud/UploadPage.py:131 msgid "Remove selected tasks" -msgstr "删除选中的的任务" +msgstr "删除选中的任务" #: ../bcloud/CloudPage.py:86 ../bcloud/CloudPage.py:119 msgid "Remove completed cloud tasks" @@ -159,7 +160,7 @@ msgstr "删除已完成的离线任务" msgid "New Link Task" msgstr "新建链接任务" -#: ../bcloud/CloudPage.py:114 ../bcloud/DownloadPage.py:171 +#: ../bcloud/CloudPage.py:114 ../bcloud/DownloadPage.py:194 #: ../bcloud/UploadPage.py:168 msgid "Open Directory" msgstr "打开所在目录" @@ -169,12 +170,12 @@ msgid "Clear" msgstr "清空" #: ../bcloud/CloudPage.py:123 ../bcloud/CloudPage.py:124 -#: ../bcloud/DownloadPage.py:192 ../bcloud/DownloadPage.py:792 +#: ../bcloud/DownloadPage.py:215 ../bcloud/DownloadPage.py:818 #: ../bcloud/TrashPage.py:66 ../bcloud/UploadPage.py:180 msgid "Remove" msgstr "删除" -#: ../bcloud/CloudPage.py:163 ../bcloud/DownloadPage.py:230 +#: ../bcloud/CloudPage.py:163 ../bcloud/DownloadPage.py:253 #: ../bcloud/UploadPage.py:212 msgid "Progress" msgstr "进度" @@ -213,7 +214,7 @@ msgstr "将下载链接贴到这里, 每行一个" msgid "Support http/https/ftp/thunder/qqdl/flashget/eMule/Magnet format" msgstr "支持 HTTP/HTTPS/FTP/迅雷/旋风/快车/电驴/磁链 等格式" -#: ../bcloud/Config.py:55 +#: ../bcloud/Config.py:57 msgid "Baidu Pan client for GNU/Linux desktop users." msgstr "百度网盘的Linux客户端" @@ -233,57 +234,69 @@ msgstr "已取消" msgid "ERROR" msgstr "错误" -#: ../bcloud/DownloadPage.py:68 ../bcloud/IconWindow.py:346 -#: ../bcloud/PreferencesDialog.py:93 +#: ../bcloud/DownloadPage.py:49 +msgid "Do you want to remove unfinished tasks?" +msgstr "您是否想要移除未完成的任务?" + +#: ../bcloud/DownloadPage.py:51 +msgid "Do you want to remove unfinished task?" +msgstr "您是否想要移除未完成的任务?" + +#: ../bcloud/DownloadPage.py:57 +msgid "Do not ask again" +msgstr "不要再次询问" + +#: ../bcloud/DownloadPage.py:91 ../bcloud/IconWindow.py:346 +#: ../bcloud/PreferencesDialog.py:110 msgid "Download" msgstr "下载" -#: ../bcloud/DownloadPage.py:70 +#: ../bcloud/DownloadPage.py:93 msgid "Downloading files" msgstr "正在下载的任务" -#: ../bcloud/DownloadPage.py:101 ../bcloud/DownloadPage.py:163 +#: ../bcloud/DownloadPage.py:124 ../bcloud/DownloadPage.py:186 #: ../bcloud/UploadPage.py:75 ../bcloud/UploadPage.py:147 msgid "Start" msgstr "开始" -#: ../bcloud/DownloadPage.py:110 ../bcloud/DownloadPage.py:167 +#: ../bcloud/DownloadPage.py:133 ../bcloud/DownloadPage.py:190 #: ../bcloud/UploadPage.py:84 ../bcloud/UploadPage.py:151 msgid "Pause" msgstr "暂停" -#: ../bcloud/DownloadPage.py:128 ../bcloud/DownloadPage.py:180 +#: ../bcloud/DownloadPage.py:151 ../bcloud/DownloadPage.py:203 msgid "Shutdown system after all tasks have finished" -msgstr "" +msgstr "全部任务完成后关闭系统" -#: ../bcloud/DownloadPage.py:152 ../bcloud/DownloadPage.py:187 +#: ../bcloud/DownloadPage.py:175 ../bcloud/DownloadPage.py:210 #: ../bcloud/UploadPage.py:139 ../bcloud/UploadPage.py:175 msgid "Remove completed tasks" msgstr "删除所有已完成的任务" -#: ../bcloud/DownloadPage.py:178 +#: ../bcloud/DownloadPage.py:201 msgid "Shutdown" msgstr "关机" -#: ../bcloud/DownloadPage.py:243 ../bcloud/UploadPage.py:225 +#: ../bcloud/DownloadPage.py:266 ../bcloud/UploadPage.py:225 msgid "State" msgstr "状态" -#: ../bcloud/DownloadPage.py:390 +#: ../bcloud/DownloadPage.py:413 msgid "Failed to scan folder to download" msgstr "扫描目录出错" -#: ../bcloud/DownloadPage.py:392 +#: ../bcloud/DownloadPage.py:415 #, python-brace-format msgid "Please download {0} again" msgstr "请重新下载 {0}" -#: ../bcloud/DownloadPage.py:415 +#: ../bcloud/DownloadPage.py:438 #, python-brace-format msgid "Task exists: {0}" msgstr "任务已存在: {0}" -#: ../bcloud/DownloadPage.py:425 ../bcloud/UploadPage.py:495 +#: ../bcloud/DownloadPage.py:450 ../bcloud/UploadPage.py:495 #, python-brace-format msgid "" "From {0}\n" @@ -292,36 +305,36 @@ msgstr "" "从 {0}\n" "到{1}" -#: ../bcloud/DownloadPage.py:509 +#: ../bcloud/DownloadPage.py:534 #, python-brace-format msgid "{0} downloaded" msgstr "{0} 下载完成" -#: ../bcloud/DownloadPage.py:532 +#: ../bcloud/DownloadPage.py:557 #, python-brace-format msgid "Error occurs will downloading {0}" msgstr "在下载 {0} 时出错" -#: ../bcloud/DownloadPage.py:538 +#: ../bcloud/DownloadPage.py:563 #, python-brace-format msgid "Disk Error: failed to read/write {0}" msgstr "磁盘错误: 无法读取/写入 {0}" -#: ../bcloud/DownloadPage.py:757 ../bcloud/DownloadPage.py:782 +#: ../bcloud/DownloadPage.py:783 ../bcloud/DownloadPage.py:808 #: ../bcloud/IconWindow.py:301 ../bcloud/IconWindow.py:328 #, python-brace-format msgid "Open With {0}" msgstr "使用 {0} 打开" -#: ../bcloud/DownloadPage.py:760 ../bcloud/IconWindow.py:305 +#: ../bcloud/DownloadPage.py:786 ../bcloud/IconWindow.py:305 msgid "Open With" msgstr "打开方式" -#: ../bcloud/DownloadPage.py:772 ../bcloud/IconWindow.py:317 +#: ../bcloud/DownloadPage.py:798 ../bcloud/IconWindow.py:317 msgid "Other Application..." msgstr "其它程序..." -#: ../bcloud/DownloadPage.py:785 ../bcloud/IconWindow.py:332 +#: ../bcloud/DownloadPage.py:811 ../bcloud/IconWindow.py:332 msgid "Open With Other Application..." msgstr "使用其它程序打开..." @@ -357,7 +370,7 @@ msgstr "显示网盘中的所有文件" msgid "Search documents and folders by name" msgstr "搜索文件名" -#: ../bcloud/IconWindow.py:176 ../bcloud/IconWindow.py:753 +#: ../bcloud/IconWindow.py:176 ../bcloud/IconWindow.py:777 msgid "Error: Move folder to itself!" msgstr "错误: 无法将文件夹移动到自身" @@ -374,7 +387,7 @@ msgstr "上传文件..." msgid "Upload Folders..." msgstr "上传文件夹.." -#: ../bcloud/IconWindow.py:239 ../bcloud/IconWindow.py:376 +#: ../bcloud/IconWindow.py:239 ../bcloud/IconWindow.py:379 msgid "Properties" msgstr "属性" @@ -398,39 +411,47 @@ msgstr "离线下载" msgid "Copy Link" msgstr "复制链接地址" -#: ../bcloud/IconWindow.py:349 ../bcloud/SharePage.py:59 +#: ../bcloud/IconWindow.py:349 +msgid "Download to..." +msgstr "下载到..." + +#: ../bcloud/IconWindow.py:352 ../bcloud/SharePage.py:59 msgid "Share" msgstr "分享" -#: ../bcloud/IconWindow.py:352 +#: ../bcloud/IconWindow.py:355 msgid "Private Share" -msgstr "" +msgstr "私有共享" -#: ../bcloud/IconWindow.py:358 ../bcloud/IconWindow.py:574 +#: ../bcloud/IconWindow.py:361 ../bcloud/IconWindow.py:598 msgid "Move To..." msgstr "移动到..." -#: ../bcloud/IconWindow.py:361 ../bcloud/IconWindow.py:598 +#: ../bcloud/IconWindow.py:364 ../bcloud/IconWindow.py:622 msgid "Copy To..." msgstr "复制到..." -#: ../bcloud/IconWindow.py:364 +#: ../bcloud/IconWindow.py:367 msgid "Rename..." msgstr "重命名..." -#: ../bcloud/IconWindow.py:370 +#: ../bcloud/IconWindow.py:373 msgid "Move to Trash" msgstr "丢弃到回收站" -#: ../bcloud/IconWindow.py:507 +#: ../bcloud/IconWindow.py:510 msgid "Failed to copy link" msgstr "复制链接失败" -#: ../bcloud/IconWindow.py:533 ../bcloud/IconWindow.py:553 +#: ../bcloud/IconWindow.py:537 +msgid "Save to..." +msgstr "保存到..." + +#: ../bcloud/IconWindow.py:557 ../bcloud/IconWindow.py:577 msgid "Failed to share selected files" msgstr "无法分享选中的文件" -#: ../bcloud/IconWindow.py:711 ../bcloud/SharePage.py:180 +#: ../bcloud/IconWindow.py:735 ../bcloud/SharePage.py:180 msgid "Modified" msgstr "修改时间" @@ -451,8 +472,8 @@ msgid "" "Open the compressed version of videos, useful for those whose network " "connection is slow." msgstr "" -"播放压缩后视频(大概会压到480P, 画质可能会有损失).如果你的网速不理想, 这会很有" -"用" +"播放压缩后视频(大概会压到480P, 画质可能会有损失).如果你的网速不理想, 这会很" +"有用" #: ../bcloud/PreferencesDialog.py:49 msgid "Use notification:" @@ -467,131 +488,139 @@ msgid "Use Status Icon:" msgstr "最小化到系统托盘:" #: ../bcloud/PreferencesDialog.py:77 +msgid "Startup minimized:" +msgstr "最小化启动:" + +#: ../bcloud/PreferencesDialog.py:94 msgid "Display Avatar:" msgstr "显示用户头像:" -#: ../bcloud/PreferencesDialog.py:95 +#: ../bcloud/PreferencesDialog.py:112 msgid "Save To:" msgstr "保存到:" -#: ../bcloud/PreferencesDialog.py:104 +#: ../bcloud/PreferencesDialog.py:121 msgid "Concurrent downloads:" msgstr "同时下载:" -#: ../bcloud/PreferencesDialog.py:114 +#: ../bcloud/PreferencesDialog.py:131 msgid "Per task:" msgstr "每个下载任务:" -#: ../bcloud/PreferencesDialog.py:122 +#: ../bcloud/PreferencesDialog.py:139 msgid "connections" msgstr "个连接" -#: ../bcloud/PreferencesDialog.py:126 +#: ../bcloud/PreferencesDialog.py:143 msgid "Retries each:" msgstr "重连间隔:" -#: ../bcloud/PreferencesDialog.py:133 +#: ../bcloud/PreferencesDialog.py:150 msgid "0: disable retries" msgstr "0: 禁止重新连接" -#: ../bcloud/PreferencesDialog.py:135 +#: ../bcloud/PreferencesDialog.py:152 msgid "minutes" msgstr "分钟" -#: ../bcloud/PreferencesDialog.py:139 +#: ../bcloud/PreferencesDialog.py:156 msgid "Download timeout:" msgstr "下载超时:" -#: ../bcloud/PreferencesDialog.py:148 +#: ../bcloud/PreferencesDialog.py:165 msgid "seconds" msgstr "秒" -#: ../bcloud/PreferencesDialog.py:152 +#: ../bcloud/PreferencesDialog.py:169 msgid "File exists while downloading:" msgstr "下载时如果文件已存在:" -#: ../bcloud/PreferencesDialog.py:156 ../bcloud/PreferencesDialog.py:200 +#: ../bcloud/PreferencesDialog.py:173 ../bcloud/PreferencesDialog.py:228 msgid "Do Nothing" msgstr "什么都不做" -#: ../bcloud/PreferencesDialog.py:157 ../bcloud/PreferencesDialog.py:201 +#: ../bcloud/PreferencesDialog.py:174 ../bcloud/PreferencesDialog.py:229 msgid "Overwrite" msgstr "覆盖" -#: ../bcloud/PreferencesDialog.py:158 ../bcloud/PreferencesDialog.py:202 +#: ../bcloud/PreferencesDialog.py:175 ../bcloud/PreferencesDialog.py:230 msgid "Rename Automatically" msgstr "自动重命名" -#: ../bcloud/PreferencesDialog.py:162 +#: ../bcloud/PreferencesDialog.py:179 msgid "What to do when downloading a file which already exists on local disk" msgstr "当下载一个文件时, 本地有相同名称的文件存在" -#: ../bcloud/PreferencesDialog.py:172 ../bcloud/UploadPage.py:48 +#: ../bcloud/PreferencesDialog.py:183 +msgid "Ask me when deleting unfinished tasks:" +msgstr "删除未完成任务时询问我:" + +#: ../bcloud/PreferencesDialog.py:200 ../bcloud/UploadPage.py:48 msgid "Upload" msgstr "上传" -#: ../bcloud/PreferencesDialog.py:174 +#: ../bcloud/PreferencesDialog.py:202 msgid "Concurrent uploads:" msgstr "同时上传:" -#: ../bcloud/PreferencesDialog.py:184 +#: ../bcloud/PreferencesDialog.py:212 msgid "Upload hidden files:" msgstr "上传隐藏文件:" -#: ../bcloud/PreferencesDialog.py:190 +#: ../bcloud/PreferencesDialog.py:218 msgid "Also upload hidden files and folders" msgstr "同时上传隐藏文件文件和文件夹" -#: ../bcloud/PreferencesDialog.py:196 +#: ../bcloud/PreferencesDialog.py:224 msgid "File exists while uploading:" msgstr "上传时如果文件已存在:" -#: ../bcloud/PreferencesDialog.py:205 +#: ../bcloud/PreferencesDialog.py:233 msgid "What to do when uploading a file which already exists on server" msgstr "当上传一个文件到服务器时, 服务器上已经有同名文件存在" -#: ../bcloud/PreferencesDialog.py:209 +#: ../bcloud/PreferencesDialog.py:237 msgid "Enable Sync:" msgstr "打开同步:" -#: ../bcloud/PreferencesDialog.py:217 +#: ../bcloud/PreferencesDialog.py:245 msgid "Sync Dir:" msgstr "同步目录:" -#: ../bcloud/PreferencesDialog.py:226 +#: ../bcloud/PreferencesDialog.py:254 msgid "Dest Sync Dir:" msgstr "远程目录:" -#: ../bcloud/PropertiesDialog.py:26 ../bcloud/PropertiesDialog.py:95 +#: ../bcloud/PropertiesDialog.py:26 ../bcloud/PropertiesDialog.py:98 msgid " Properties" msgstr " 的属性" -#: ../bcloud/PropertiesDialog.py:42 ../bcloud/PropertiesDialog.py:108 +#: ../bcloud/PropertiesDialog.py:45 ../bcloud/PropertiesDialog.py:114 msgid "Name:" msgstr "文件名:" -#: ../bcloud/PropertiesDialog.py:47 ../bcloud/PropertiesDialog.py:113 +#: ../bcloud/PropertiesDialog.py:50 ../bcloud/PropertiesDialog.py:119 msgid "Location:" msgstr "位置:" -#: ../bcloud/PropertiesDialog.py:60 ../bcloud/PropertiesDialog.py:62 +#: ../bcloud/PropertiesDialog.py:63 ../bcloud/PropertiesDialog.py:65 msgid " bytes" msgstr " 字节" -#: ../bcloud/PropertiesDialog.py:75 +#: ../bcloud/PropertiesDialog.py:78 msgid "Created:" msgstr "创建:" -#: ../bcloud/PropertiesDialog.py:80 +#: ../bcloud/PropertiesDialog.py:83 msgid "Modified:" msgstr "修改:" -#: ../bcloud/PropertiesDialog.py:125 +#: ../bcloud/PropertiesDialog.py:131 #, python-brace-format msgid "{0} folders, {1} files" msgstr "{0} 个文件夹, {1} 个文件" -#: ../bcloud/PropertiesDialog.py:126 +#: ../bcloud/PropertiesDialog.py:132 msgid "Contents:" msgstr "内容:" @@ -682,87 +711,103 @@ msgstr "密码 .." msgid "Remember Password" msgstr "记住密码" -#: ../bcloud/SigninDialog.py:165 +#: ../bcloud/SigninDialog.py:168 msgid "Signin Automatically" msgstr "自动登录" -#: ../bcloud/SigninDialog.py:171 ../bcloud/SigninDialog.py:240 +#: ../bcloud/SigninDialog.py:177 ../bcloud/SigninDialog.py:246 msgid "Sign in" msgstr "登录" -#: ../bcloud/SigninDialog.py:181 +#: ../bcloud/SigninDialog.py:187 msgid "Failed to sign in, please try again." msgstr "登录失败, 请重试" -#: ../bcloud/SigninDialog.py:265 ../bcloud/SigninDialog.py:274 +#: ../bcloud/SigninDialog.py:271 ../bcloud/SigninDialog.py:280 msgid "In process..." msgstr "正在处理..." -#: ../bcloud/SigninDialog.py:283 +#: ../bcloud/SigninDialog.py:289 msgid "Failed to get bdstoken!" msgstr "获取bdstoken 失败!" -#: ../bcloud/SigninDialog.py:295 +#: ../bcloud/SigninDialog.py:301 msgid "Login failed, please try again" msgstr "登录失败, 请重试" -#: ../bcloud/SigninDialog.py:300 ../bcloud/SigninDialog.py:320 +#: ../bcloud/SigninDialog.py:306 ../bcloud/SigninDialog.py:322 msgid "Get bdstoken..." msgstr "获取bdstoken..." -#: ../bcloud/SigninDialog.py:317 ../bcloud/SigninDialog.py:381 -msgid "Please input verification code!" -msgstr "请输入验证码!" - -#: ../bcloud/SigninDialog.py:329 +#: ../bcloud/SigninDialog.py:331 msgid "Password error, please try again" msgstr "密码错误, 请重试" -#: ../bcloud/SigninDialog.py:333 +#: ../bcloud/SigninDialog.py:335 msgid "Verfication code error, please try again" msgstr "验证码错误, 请重试" -#: ../bcloud/SigninDialog.py:339 +#: ../bcloud/SigninDialog.py:341 msgid "Does not support SMS/Email verification!" msgstr "不支持手机短信/邮件验证!" -#: ../bcloud/SigninDialog.py:343 +#: ../bcloud/SigninDialog.py:347 +msgid "NET:登录失败,请在弹出的窗口操作,或重新登录" +msgstr "NET:登录失败,请在弹出的窗口操作,或重新登录" + +#: ../bcloud/SigninDialog.py:352 +msgid "NET:近期登录次数过多, 请先通过 passport.baidu.com 解除锁定" +msgstr "NET:近期登录次数过多, 请先通过 passport.baidu.com 解除锁定" + +#: ../bcloud/SigninDialog.py:357 +msgid "NET:登录过于频繁,请24小时后再试" +msgstr "NET:登录过于频繁,请24小时后再试" + +#: ../bcloud/SigninDialog.py:362 +msgid "NET:账号异常,请在当前网络环境下在百度网页端正常登录一次" +msgstr "NET:账号异常,请在当前网络环境下在百度网页端正常登录一次" + +#: ../bcloud/SigninDialog.py:366 msgid "Unknown error, please try again" msgstr "未知错误, 请重试" -#: ../bcloud/SigninDialog.py:350 +#: ../bcloud/SigninDialog.py:373 msgid "Failed to request public key, please try again" msgstr "获取公钥失败, 请重试" -#: ../bcloud/SigninDialog.py:365 +#: ../bcloud/SigninDialog.py:388 msgid "Failed to check login, please try again" msgstr "检测登录历史失败, 请重试" -#: ../bcloud/SigninDialog.py:394 +#: ../bcloud/SigninDialog.py:405 +msgid "Please input verification code!" +msgstr "请输入验证码!" + +#: ../bcloud/SigninDialog.py:418 msgid "Failed to get UBI, please try again." msgstr "获取UBI失败, 请重试" -#: ../bcloud/SigninDialog.py:397 +#: ../bcloud/SigninDialog.py:421 msgid "Check login" msgstr "检测登录历史" -#: ../bcloud/SigninDialog.py:405 +#: ../bcloud/SigninDialog.py:429 msgid "Failed to get token, please try again." msgstr "获取token失败, 请重试" -#: ../bcloud/SigninDialog.py:412 +#: ../bcloud/SigninDialog.py:436 msgid "Get UBI..." msgstr "获取UBI..." -#: ../bcloud/SigninDialog.py:421 +#: ../bcloud/SigninDialog.py:445 msgid "Failed to get BAIDUID cookie, please try again." msgstr "获取BAIDUID cookie失败, 请重试" -#: ../bcloud/SigninDialog.py:424 +#: ../bcloud/SigninDialog.py:448 msgid "Get TOKEN..." msgstr "获取 TOKEN..." -#: ../bcloud/SigninDialog.py:442 +#: ../bcloud/SigninDialog.py:465 msgid "Get BAIDUID..." msgstr "获取BAIDUID..." diff --git a/po/zh_TW.po b/po/zh_TW.po index 23f3498..a703bd9 100644 --- a/po/zh_TW.po +++ b/po/zh_TW.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-01-10 10:41+0800\n" +"POT-Creation-Date: 2017-05-26 21:27+0800\n" "PO-Revision-Date: 2014-10-21 17:15+0800\n" "Last-Translator: CzBiX \n" "Language-Team: Chinese (traditional)\n" @@ -17,39 +17,39 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.4\n" -#: ../bcloud/App.py:100 ../bcloud/PreferencesDialog.py:18 +#: ../bcloud/App.py:104 ../bcloud/PreferencesDialog.py:18 msgid "Preferences" msgstr "偏好設定" -#: ../bcloud/App.py:101 +#: ../bcloud/App.py:105 msgid "Sign out" msgstr "登出" -#: ../bcloud/App.py:102 +#: ../bcloud/App.py:106 msgid "About" msgstr "關於" -#: ../bcloud/App.py:103 ../bcloud/App.py:443 +#: ../bcloud/App.py:107 ../bcloud/App.py:450 msgid "Quit" msgstr "退出" -#: ../bcloud/App.py:155 +#: ../bcloud/App.py:160 msgid "Unknown" msgstr "未知" -#: ../bcloud/App.py:421 +#: ../bcloud/App.py:428 msgid "Show App" msgstr "顯示程式" -#: ../bcloud/App.py:429 +#: ../bcloud/App.py:436 msgid "Pause Upload Tasks" msgstr "暫停所有上傳任務" -#: ../bcloud/App.py:435 +#: ../bcloud/App.py:442 msgid "Pause Download Tasks" msgstr "暫停所有下載任務" -#: ../bcloud/App.py:489 +#: ../bcloud/App.py:496 #, python-brace-format msgid "{0} copied to clipboard" msgstr "{0} 已被複製到剪貼板" @@ -59,15 +59,15 @@ msgid "Select All" msgstr "全選" #: ../bcloud/BTBrowserDialog.py:64 ../bcloud/CloudPage.py:150 -#: ../bcloud/DownloadPage.py:223 ../bcloud/IconWindow.py:688 +#: ../bcloud/DownloadPage.py:246 ../bcloud/IconWindow.py:712 #: ../bcloud/SharePage.py:162 ../bcloud/TrashPage.py:141 #: ../bcloud/UploadPage.py:205 msgid "Name" msgstr "檔案名稱" #: ../bcloud/BTBrowserDialog.py:68 ../bcloud/CloudPage.py:157 -#: ../bcloud/DownloadPage.py:237 ../bcloud/IconWindow.py:704 -#: ../bcloud/PropertiesDialog.py:55 ../bcloud/SharePage.py:174 +#: ../bcloud/DownloadPage.py:260 ../bcloud/IconWindow.py:728 +#: ../bcloud/PropertiesDialog.py:58 ../bcloud/SharePage.py:174 #: ../bcloud/TrashPage.py:156 ../bcloud/UploadPage.py:219 msgid "Size" msgstr "大小" @@ -141,15 +141,15 @@ msgstr "離線下載" msgid "Create new cloud task" msgstr "新增離線下載" -#: ../bcloud/CloudPage.py:63 ../bcloud/DownloadPage.py:118 +#: ../bcloud/CloudPage.py:63 ../bcloud/DownloadPage.py:141 #: ../bcloud/UploadPage.py:92 msgid "Open target directory" msgstr "打開所在目錄" -#: ../bcloud/CloudPage.py:78 ../bcloud/DownloadPage.py:144 +#: ../bcloud/CloudPage.py:78 ../bcloud/DownloadPage.py:167 #: ../bcloud/UploadPage.py:131 msgid "Remove selected tasks" -msgstr "刪除選中的的任務" +msgstr "刪除選中的任務" #: ../bcloud/CloudPage.py:86 ../bcloud/CloudPage.py:119 msgid "Remove completed cloud tasks" @@ -159,7 +159,7 @@ msgstr "刪除已完成的離線任務" msgid "New Link Task" msgstr "新增連結任務" -#: ../bcloud/CloudPage.py:114 ../bcloud/DownloadPage.py:171 +#: ../bcloud/CloudPage.py:114 ../bcloud/DownloadPage.py:194 #: ../bcloud/UploadPage.py:168 msgid "Open Directory" msgstr "打開所在目錄" @@ -169,12 +169,12 @@ msgid "Clear" msgstr "清空" #: ../bcloud/CloudPage.py:123 ../bcloud/CloudPage.py:124 -#: ../bcloud/DownloadPage.py:192 ../bcloud/DownloadPage.py:792 +#: ../bcloud/DownloadPage.py:215 ../bcloud/DownloadPage.py:818 #: ../bcloud/TrashPage.py:66 ../bcloud/UploadPage.py:180 msgid "Remove" msgstr "刪除" -#: ../bcloud/CloudPage.py:163 ../bcloud/DownloadPage.py:230 +#: ../bcloud/CloudPage.py:163 ../bcloud/DownloadPage.py:253 #: ../bcloud/UploadPage.py:212 msgid "Progress" msgstr "進度" @@ -213,7 +213,7 @@ msgstr "將下載連結貼到這裡, 每行一個" msgid "Support http/https/ftp/thunder/qqdl/flashget/eMule/Magnet format" msgstr "支援 HTTP/HTTPS/FTP/迅雷/旋風/快車/電驢/磁鏈 等格式" -#: ../bcloud/Config.py:55 +#: ../bcloud/Config.py:57 msgid "Baidu Pan client for GNU/Linux desktop users." msgstr "百度網盤的 Linux 客戶端" @@ -233,57 +233,69 @@ msgstr "已取消" msgid "ERROR" msgstr "錯誤" -#: ../bcloud/DownloadPage.py:68 ../bcloud/IconWindow.py:346 -#: ../bcloud/PreferencesDialog.py:93 +#: ../bcloud/DownloadPage.py:49 +msgid "Do you want to remove unfinished tasks?" +msgstr "" + +#: ../bcloud/DownloadPage.py:51 +msgid "Do you want to remove unfinished task?" +msgstr "" + +#: ../bcloud/DownloadPage.py:57 +msgid "Do not ask again" +msgstr "" + +#: ../bcloud/DownloadPage.py:91 ../bcloud/IconWindow.py:346 +#: ../bcloud/PreferencesDialog.py:110 msgid "Download" msgstr "下載" -#: ../bcloud/DownloadPage.py:70 +#: ../bcloud/DownloadPage.py:93 msgid "Downloading files" msgstr "正在下載的任務" -#: ../bcloud/DownloadPage.py:101 ../bcloud/DownloadPage.py:163 +#: ../bcloud/DownloadPage.py:124 ../bcloud/DownloadPage.py:186 #: ../bcloud/UploadPage.py:75 ../bcloud/UploadPage.py:147 msgid "Start" msgstr "開始" -#: ../bcloud/DownloadPage.py:110 ../bcloud/DownloadPage.py:167 +#: ../bcloud/DownloadPage.py:133 ../bcloud/DownloadPage.py:190 #: ../bcloud/UploadPage.py:84 ../bcloud/UploadPage.py:151 msgid "Pause" msgstr "暫停" -#: ../bcloud/DownloadPage.py:128 ../bcloud/DownloadPage.py:180 +#: ../bcloud/DownloadPage.py:151 ../bcloud/DownloadPage.py:203 msgid "Shutdown system after all tasks have finished" msgstr "" -#: ../bcloud/DownloadPage.py:152 ../bcloud/DownloadPage.py:187 +#: ../bcloud/DownloadPage.py:175 ../bcloud/DownloadPage.py:210 #: ../bcloud/UploadPage.py:139 ../bcloud/UploadPage.py:175 msgid "Remove completed tasks" msgstr "刪除所有已完成的任務" -#: ../bcloud/DownloadPage.py:178 +#: ../bcloud/DownloadPage.py:201 msgid "Shutdown" msgstr "關機" -#: ../bcloud/DownloadPage.py:243 ../bcloud/UploadPage.py:225 +#: ../bcloud/DownloadPage.py:266 ../bcloud/UploadPage.py:225 msgid "State" msgstr "狀態" -#: ../bcloud/DownloadPage.py:390 +#: ../bcloud/DownloadPage.py:413 msgid "Failed to scan folder to download" msgstr "掃描目錄出錯" -#: ../bcloud/DownloadPage.py:392 +#: ../bcloud/DownloadPage.py:415 #, python-brace-format msgid "Please download {0} again" msgstr "請重新下載 {0}" -#: ../bcloud/DownloadPage.py:415 +#: ../bcloud/DownloadPage.py:438 #, python-brace-format msgid "Task exists: {0}" msgstr "任務已存在: {0}" -#: ../bcloud/DownloadPage.py:425 ../bcloud/UploadPage.py:495 +#: ../bcloud/DownloadPage.py:450 ../bcloud/UploadPage.py:495 #, python-brace-format msgid "" "From {0}\n" @@ -292,36 +304,36 @@ msgstr "" "從 {0}\n" "到{1}" -#: ../bcloud/DownloadPage.py:509 +#: ../bcloud/DownloadPage.py:534 #, python-brace-format msgid "{0} downloaded" msgstr "{0} 下載完成" -#: ../bcloud/DownloadPage.py:532 +#: ../bcloud/DownloadPage.py:557 #, python-brace-format msgid "Error occurs will downloading {0}" msgstr "在下載 {0} 時出錯" -#: ../bcloud/DownloadPage.py:538 +#: ../bcloud/DownloadPage.py:563 #, python-brace-format msgid "Disk Error: failed to read/write {0}" msgstr "硬碟錯誤: 無法讀取/寫入 {0}" -#: ../bcloud/DownloadPage.py:757 ../bcloud/DownloadPage.py:782 +#: ../bcloud/DownloadPage.py:783 ../bcloud/DownloadPage.py:808 #: ../bcloud/IconWindow.py:301 ../bcloud/IconWindow.py:328 #, python-brace-format msgid "Open With {0}" msgstr "使用 {0} 打開" -#: ../bcloud/DownloadPage.py:760 ../bcloud/IconWindow.py:305 +#: ../bcloud/DownloadPage.py:786 ../bcloud/IconWindow.py:305 msgid "Open With" msgstr "打開方式" -#: ../bcloud/DownloadPage.py:772 ../bcloud/IconWindow.py:317 +#: ../bcloud/DownloadPage.py:798 ../bcloud/IconWindow.py:317 msgid "Other Application..." msgstr "其它程序..." -#: ../bcloud/DownloadPage.py:785 ../bcloud/IconWindow.py:332 +#: ../bcloud/DownloadPage.py:811 ../bcloud/IconWindow.py:332 msgid "Open With Other Application..." msgstr "使用其它程序打開..." @@ -357,7 +369,7 @@ msgstr "顯示網盤中的所有檔案" msgid "Search documents and folders by name" msgstr "搜尋檔案名稱" -#: ../bcloud/IconWindow.py:176 ../bcloud/IconWindow.py:753 +#: ../bcloud/IconWindow.py:176 ../bcloud/IconWindow.py:777 msgid "Error: Move folder to itself!" msgstr "錯誤: 無法將目錄移動到自身" @@ -374,7 +386,7 @@ msgstr "上傳檔案..." msgid "Upload Folders..." msgstr "上傳目錄.." -#: ../bcloud/IconWindow.py:239 ../bcloud/IconWindow.py:376 +#: ../bcloud/IconWindow.py:239 ../bcloud/IconWindow.py:379 msgid "Properties" msgstr "屬性" @@ -398,39 +410,49 @@ msgstr "離線下載" msgid "Copy Link" msgstr "複製連結網址" -#: ../bcloud/IconWindow.py:349 ../bcloud/SharePage.py:59 +#: ../bcloud/IconWindow.py:349 +#, fuzzy +msgid "Download to..." +msgstr "下載" + +#: ../bcloud/IconWindow.py:352 ../bcloud/SharePage.py:59 msgid "Share" msgstr "分享" -#: ../bcloud/IconWindow.py:352 +#: ../bcloud/IconWindow.py:355 msgid "Private Share" msgstr "" -#: ../bcloud/IconWindow.py:358 ../bcloud/IconWindow.py:574 +#: ../bcloud/IconWindow.py:361 ../bcloud/IconWindow.py:598 msgid "Move To..." msgstr "移動到..." -#: ../bcloud/IconWindow.py:361 ../bcloud/IconWindow.py:598 +#: ../bcloud/IconWindow.py:364 ../bcloud/IconWindow.py:622 msgid "Copy To..." msgstr "複製到..." -#: ../bcloud/IconWindow.py:364 +#: ../bcloud/IconWindow.py:367 msgid "Rename..." msgstr "重命名..." -#: ../bcloud/IconWindow.py:370 +#: ../bcloud/IconWindow.py:373 msgid "Move to Trash" msgstr "丟進回收桶" -#: ../bcloud/IconWindow.py:507 +#: ../bcloud/IconWindow.py:510 msgid "Failed to copy link" msgstr "複製連結失敗" -#: ../bcloud/IconWindow.py:533 ../bcloud/IconWindow.py:553 +#: ../bcloud/IconWindow.py:537 +#, fuzzy +msgid "Save to..." +msgstr "保存到.." + +#: ../bcloud/IconWindow.py:557 ../bcloud/IconWindow.py:577 msgid "Failed to share selected files" msgstr "無法分享選中的檔案" -#: ../bcloud/IconWindow.py:711 ../bcloud/SharePage.py:180 +#: ../bcloud/IconWindow.py:735 ../bcloud/SharePage.py:180 msgid "Modified" msgstr "修改時間" @@ -467,131 +489,139 @@ msgid "Use Status Icon:" msgstr "最小化到系統托盤:" #: ../bcloud/PreferencesDialog.py:77 +msgid "Startup minimized:" +msgstr "" + +#: ../bcloud/PreferencesDialog.py:94 msgid "Display Avatar:" msgstr "顯示用戶頭像:" -#: ../bcloud/PreferencesDialog.py:95 +#: ../bcloud/PreferencesDialog.py:112 msgid "Save To:" msgstr "保存到:" -#: ../bcloud/PreferencesDialog.py:104 +#: ../bcloud/PreferencesDialog.py:121 msgid "Concurrent downloads:" msgstr "同時下載:" -#: ../bcloud/PreferencesDialog.py:114 +#: ../bcloud/PreferencesDialog.py:131 msgid "Per task:" msgstr "每個下載任務:" -#: ../bcloud/PreferencesDialog.py:122 +#: ../bcloud/PreferencesDialog.py:139 msgid "connections" msgstr "個連接" -#: ../bcloud/PreferencesDialog.py:126 +#: ../bcloud/PreferencesDialog.py:143 msgid "Retries each:" msgstr "重連間隔:" -#: ../bcloud/PreferencesDialog.py:133 +#: ../bcloud/PreferencesDialog.py:150 msgid "0: disable retries" msgstr "0: 禁止重新連接" -#: ../bcloud/PreferencesDialog.py:135 +#: ../bcloud/PreferencesDialog.py:152 msgid "minutes" msgstr "分鐘" -#: ../bcloud/PreferencesDialog.py:139 +#: ../bcloud/PreferencesDialog.py:156 msgid "Download timeout:" msgstr "下載超時:" -#: ../bcloud/PreferencesDialog.py:148 +#: ../bcloud/PreferencesDialog.py:165 msgid "seconds" msgstr "秒" -#: ../bcloud/PreferencesDialog.py:152 +#: ../bcloud/PreferencesDialog.py:169 msgid "File exists while downloading:" msgstr "下載時如果檔案已存在:" -#: ../bcloud/PreferencesDialog.py:156 ../bcloud/PreferencesDialog.py:200 +#: ../bcloud/PreferencesDialog.py:173 ../bcloud/PreferencesDialog.py:228 msgid "Do Nothing" msgstr "什麼都不做" -#: ../bcloud/PreferencesDialog.py:157 ../bcloud/PreferencesDialog.py:201 +#: ../bcloud/PreferencesDialog.py:174 ../bcloud/PreferencesDialog.py:229 msgid "Overwrite" msgstr "覆蓋" -#: ../bcloud/PreferencesDialog.py:158 ../bcloud/PreferencesDialog.py:202 +#: ../bcloud/PreferencesDialog.py:175 ../bcloud/PreferencesDialog.py:230 msgid "Rename Automatically" msgstr "自動重新命名" -#: ../bcloud/PreferencesDialog.py:162 +#: ../bcloud/PreferencesDialog.py:179 msgid "What to do when downloading a file which already exists on local disk" msgstr "當下載一個檔案時, 下載資料夾已有相同名稱的檔案存在" -#: ../bcloud/PreferencesDialog.py:172 ../bcloud/UploadPage.py:48 +#: ../bcloud/PreferencesDialog.py:183 +msgid "Ask me when deleting unfinished tasks:" +msgstr "" + +#: ../bcloud/PreferencesDialog.py:200 ../bcloud/UploadPage.py:48 msgid "Upload" msgstr "上傳" -#: ../bcloud/PreferencesDialog.py:174 +#: ../bcloud/PreferencesDialog.py:202 msgid "Concurrent uploads:" msgstr "同時上傳:" -#: ../bcloud/PreferencesDialog.py:184 +#: ../bcloud/PreferencesDialog.py:212 msgid "Upload hidden files:" msgstr "上傳隱藏文件:" -#: ../bcloud/PreferencesDialog.py:190 +#: ../bcloud/PreferencesDialog.py:218 msgid "Also upload hidden files and folders" msgstr "同時上傳隱藏文件文件和文件夾" -#: ../bcloud/PreferencesDialog.py:196 +#: ../bcloud/PreferencesDialog.py:224 msgid "File exists while uploading:" msgstr "上傳時如果檔案已存在:" -#: ../bcloud/PreferencesDialog.py:205 +#: ../bcloud/PreferencesDialog.py:233 msgid "What to do when uploading a file which already exists on server" msgstr "當上傳一個檔案到雲端時, 已經有同名檔案存在" -#: ../bcloud/PreferencesDialog.py:209 +#: ../bcloud/PreferencesDialog.py:237 msgid "Enable Sync:" msgstr "打開同步:" -#: ../bcloud/PreferencesDialog.py:217 +#: ../bcloud/PreferencesDialog.py:245 msgid "Sync Dir:" msgstr "同步目錄:" -#: ../bcloud/PreferencesDialog.py:226 +#: ../bcloud/PreferencesDialog.py:254 msgid "Dest Sync Dir:" msgstr "遠程目錄:" -#: ../bcloud/PropertiesDialog.py:26 ../bcloud/PropertiesDialog.py:95 +#: ../bcloud/PropertiesDialog.py:26 ../bcloud/PropertiesDialog.py:98 msgid " Properties" msgstr " 的屬性" -#: ../bcloud/PropertiesDialog.py:42 ../bcloud/PropertiesDialog.py:108 +#: ../bcloud/PropertiesDialog.py:45 ../bcloud/PropertiesDialog.py:114 msgid "Name:" msgstr "檔案名稱:" -#: ../bcloud/PropertiesDialog.py:47 ../bcloud/PropertiesDialog.py:113 +#: ../bcloud/PropertiesDialog.py:50 ../bcloud/PropertiesDialog.py:119 msgid "Location:" msgstr "位置:" -#: ../bcloud/PropertiesDialog.py:60 ../bcloud/PropertiesDialog.py:62 +#: ../bcloud/PropertiesDialog.py:63 ../bcloud/PropertiesDialog.py:65 msgid " bytes" msgstr " 字節" -#: ../bcloud/PropertiesDialog.py:75 +#: ../bcloud/PropertiesDialog.py:78 msgid "Created:" msgstr "新建:" -#: ../bcloud/PropertiesDialog.py:80 +#: ../bcloud/PropertiesDialog.py:83 msgid "Modified:" msgstr "修改:" -#: ../bcloud/PropertiesDialog.py:125 +#: ../bcloud/PropertiesDialog.py:131 #, python-brace-format msgid "{0} folders, {1} files" msgstr "{0} 個目錄, {1} 個檔案" -#: ../bcloud/PropertiesDialog.py:126 +#: ../bcloud/PropertiesDialog.py:132 msgid "Contents:" msgstr "內容:" @@ -682,87 +712,103 @@ msgstr "密碼 .." msgid "Remember Password" msgstr "記住密碼" -#: ../bcloud/SigninDialog.py:165 +#: ../bcloud/SigninDialog.py:168 msgid "Signin Automatically" msgstr "自動登錄" -#: ../bcloud/SigninDialog.py:171 ../bcloud/SigninDialog.py:240 +#: ../bcloud/SigninDialog.py:177 ../bcloud/SigninDialog.py:246 msgid "Sign in" msgstr "登錄" -#: ../bcloud/SigninDialog.py:181 +#: ../bcloud/SigninDialog.py:187 msgid "Failed to sign in, please try again." msgstr "登錄失敗, 請重試" -#: ../bcloud/SigninDialog.py:265 ../bcloud/SigninDialog.py:274 +#: ../bcloud/SigninDialog.py:271 ../bcloud/SigninDialog.py:280 msgid "In process..." msgstr "正在處理..." -#: ../bcloud/SigninDialog.py:283 +#: ../bcloud/SigninDialog.py:289 msgid "Failed to get bdstoken!" msgstr "獲取bdstoken 失敗!" -#: ../bcloud/SigninDialog.py:295 +#: ../bcloud/SigninDialog.py:301 msgid "Login failed, please try again" msgstr "登錄失敗, 請重試" -#: ../bcloud/SigninDialog.py:300 ../bcloud/SigninDialog.py:320 +#: ../bcloud/SigninDialog.py:306 ../bcloud/SigninDialog.py:322 msgid "Get bdstoken..." msgstr "獲取bdstoken..." -#: ../bcloud/SigninDialog.py:317 ../bcloud/SigninDialog.py:381 -msgid "Please input verification code!" -msgstr "請輸入驗證碼!" - -#: ../bcloud/SigninDialog.py:329 +#: ../bcloud/SigninDialog.py:331 msgid "Password error, please try again" msgstr "密碼錯誤, 請重試" -#: ../bcloud/SigninDialog.py:333 +#: ../bcloud/SigninDialog.py:335 msgid "Verfication code error, please try again" msgstr "驗證碼錯誤, 請重試" -#: ../bcloud/SigninDialog.py:339 +#: ../bcloud/SigninDialog.py:341 msgid "Does not support SMS/Email verification!" msgstr "不支持手機簡訊/郵件驗證!" -#: ../bcloud/SigninDialog.py:343 +#: ../bcloud/SigninDialog.py:347 +msgid "NET:登录失败,请在弹出的窗口操作,或重新登录" +msgstr "" + +#: ../bcloud/SigninDialog.py:352 +msgid "NET:近期登录次数过多, 请先通过 passport.baidu.com 解除锁定" +msgstr "" + +#: ../bcloud/SigninDialog.py:357 +msgid "NET:登录过于频繁,请24小时后再试" +msgstr "" + +#: ../bcloud/SigninDialog.py:362 +msgid "NET:账号异常,请在当前网络环境下在百度网页端正常登录一次" +msgstr "" + +#: ../bcloud/SigninDialog.py:366 msgid "Unknown error, please try again" msgstr "未知錯誤, 請重試" -#: ../bcloud/SigninDialog.py:350 +#: ../bcloud/SigninDialog.py:373 msgid "Failed to request public key, please try again" msgstr "獲取公鑰失敗, 請重試" -#: ../bcloud/SigninDialog.py:365 +#: ../bcloud/SigninDialog.py:388 msgid "Failed to check login, please try again" msgstr "檢測登錄歷史失敗, 請重試" -#: ../bcloud/SigninDialog.py:394 +#: ../bcloud/SigninDialog.py:405 +msgid "Please input verification code!" +msgstr "請輸入驗證碼!" + +#: ../bcloud/SigninDialog.py:418 msgid "Failed to get UBI, please try again." msgstr "獲取UBI失敗, 請重試" -#: ../bcloud/SigninDialog.py:397 +#: ../bcloud/SigninDialog.py:421 msgid "Check login" msgstr "檢測登錄歷史" -#: ../bcloud/SigninDialog.py:405 +#: ../bcloud/SigninDialog.py:429 msgid "Failed to get token, please try again." msgstr "獲取token失敗, 請重試" -#: ../bcloud/SigninDialog.py:412 +#: ../bcloud/SigninDialog.py:436 msgid "Get UBI..." msgstr "獲取UBI..." -#: ../bcloud/SigninDialog.py:421 +#: ../bcloud/SigninDialog.py:445 msgid "Failed to get BAIDUID cookie, please try again." msgstr "獲取BAIDUID cookie失敗, 請重試" -#: ../bcloud/SigninDialog.py:424 +#: ../bcloud/SigninDialog.py:448 msgid "Get TOKEN..." msgstr "獲取 TOKEN..." -#: ../bcloud/SigninDialog.py:442 +#: ../bcloud/SigninDialog.py:465 msgid "Get BAIDUID..." msgstr "獲取BAIDUID..." diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..decdca7 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +keyring +pycrypto==2.6.1 +lxml diff --git a/setup.py b/setup.py index 8eacf95..088ad3f 100755 --- a/setup.py +++ b/setup.py @@ -34,10 +34,10 @@ def build_data_files(): description = 'Baidu Pan client for Linux Desktop users', version = bcloud.__version__, license = 'GPLv3', - url = 'https://github.com/LiuLang/bcloud', + url = 'https://github.com/Yufeikang/bcloud', - author = 'LiuLang', - author_email = 'gsushzhsosgsu@gmail.com', + author = 'KangYufei', + author_email = 'kyf0722@gmail.com', packages = ['bcloud', ], scripts = scripts, diff --git a/share/locale/zh_CN/LC_MESSAGES/bcloud.mo b/share/locale/zh_CN/LC_MESSAGES/bcloud.mo index 9d51b2f..e459e1a 100644 Binary files a/share/locale/zh_CN/LC_MESSAGES/bcloud.mo and b/share/locale/zh_CN/LC_MESSAGES/bcloud.mo differ diff --git a/share/locale/zh_TW/LC_MESSAGES/bcloud.mo b/share/locale/zh_TW/LC_MESSAGES/bcloud.mo index dcd1513..4fd25e3 100644 Binary files a/share/locale/zh_TW/LC_MESSAGES/bcloud.mo and b/share/locale/zh_TW/LC_MESSAGES/bcloud.mo differ