📄 platform.py
字号:
# The contents of this file are subject to the BitTorrent Open Source License# Version 1.1 (the License). You may not copy or use this file, in either# source code or executable form, except in compliance with the License. You# may obtain a copy of the License at http://www.bittorrent.com/license/.## Software distributed under the License is distributed on an AS IS basis,# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License# for the specific language governing rights and limitations under the# License.# Written by Greg Hazel, Matt Chisholm, Uoti Urpala, and David Harrison# This module is strictly for cross platform compatibility items and# should not import anything from other BitTorrent modules.import osimport reimport sysimport timeimport tarfileimport gettextimport localeimport zurllib as urllibimport shutilimport tracebackif os.name == 'nt': import pywintypes import _winreg import win32api import win32file from win32com.shell import shellcon, shell import win32con import win32com.client import ctypes import struct FILE_ATTRIBUTE_SPARSE_FILE = 0x00000200 FILE_SUPPORTS_SPARSE_FILES = 0x00000040 FSCTL_QUERY_ALLOCATED_RANGES = 0x000940CFelif os.name == 'posix' and os.uname()[0] == 'Darwin': has_pyobjc = False try: from Foundation import NSBundle has_pyobjc = True except ImportError: passelse: try: import statvfs except ImportError: pass# NOTE: intentionally appears in the file before importing anything# from BitTorrent because it is called when setting --use_factory_defaults.def get_filesystem_encoding(errorfunc=None): def dummy_log(e): print e pass if not errorfunc: errorfunc = dummy_log default_encoding = 'utf8' if os.path.supports_unicode_filenames: encoding = None else: try: encoding = sys.getfilesystemencoding() except AttributeError: errorfunc("This version of Python cannot detect filesystem encoding.") if encoding is None: encoding = default_encoding errorfunc("Python failed to detect filesystem encoding. " "Assuming '%s' instead." % default_encoding) else: try: 'a1'.decode(encoding) except: errorfunc("Filesystem encoding '%s' is not supported. Using '%s' instead." % (encoding, default_encoding)) encoding = default_encoding return encoding# NOTE: intentionally appears in the file before importing anything# from BitTorrent because it is called when setting --use_factory_defaults.def get_dir_root(shellvars, default_to_home=True): def check_sysvars(x): y = os.path.expandvars(x) if y != x and os.path.isdir(y): return y return None dir_root = None for d in shellvars: dir_root = check_sysvars(d) if dir_root is not None: break else: if default_to_home: dir_root = os.path.expanduser('~') if dir_root == '~' or not os.path.isdir(dir_root): dir_root = None if get_filesystem_encoding() == None: try: dir_root = dir_root.decode(sys.getfilesystemencoding()) except: try: dir_root = dir_root.decode('utf8') except: pass return dir_root# NOTE: intentionally appears in the file before importing anything# from BitTorrent because it is called when setting --use_factory_defaults.def get_temp_dir(): shellvars = ['${TMP}', '${TEMP}'] dir_root = get_dir_root(shellvars, default_to_home=False) #this method is preferred to the envvars if os.name == 'nt': try_dir_root = win32api.GetTempPath() if try_dir_root is not None: dir_root = try_dir_root if dir_root is None: try_dir_root = None if os.name == 'nt': # this should basically never happen. GetTempPath always returns something try_dir_root = r'C:\WINDOWS\Temp' elif os.name == 'posix': try_dir_root = '/tmp' if (try_dir_root is not None and os.path.isdir(try_dir_root) and os.access(try_dir_root, os.R_OK|os.W_OK)): dir_root = try_dir_root return dir_rootMAX_DIR = 5_tmp_subdir = None# NOTE: intentionally appears in the file before importing anything# from BitTorrent because it is called when setting --use_factory_defaults.def encode_for_filesystem(path): assert isinstance(path, unicode) bad = False encoding = get_filesystem_encoding() if encoding == None: encoded_path = path else: try: encoded_path = path.encode(encoding) except: bad = True path.replace(u"%", urllib.quote(u"%")) encoded_path = path.encode(encoding, 'urlquote') return (encoded_path, bad)def decode_from_filesystem(path): encoding = get_filesystem_encoding() if encoding == None: assert isinstance(path, unicode) decoded_path = path else: assert isinstance(path, str) decoded_path = path.decode(encoding) return decoded_pathpath_wrap = decode_from_filesystemefs = encode_for_filesystem # abbreviate encode_for_filesystem.def efs2(path): # same as encode_for_filesystem, but doesn't bother returning "bad" return encode_for_filesystem(path)[0]# NOTE: intentionally appears in the file before importing anything# from BitTorrent because it is called when setting --use_factory_defaults.def get_temp_subdir(): """Creates a unique subdirectory of the platform temp directory. This revolves between MAX_DIR directory names deleting the oldest whenever MAX_DIR exist. Upon return the number of temporary subdirectories should never exceed MAX_DIR-1. If one has already been created for this execution, this returns that subdirectory. @return the absolute path of the created temporary directory. """ global _tmp_subdir if _tmp_subdir is not None: return _tmp_subdir tmp = get_temp_dir() target = None # holds the name of the directory that will be made. for i in xrange(MAX_DIR): subdir = efs2(u"BitTorrentTemp%d" % i) path = os.path.join(tmp, subdir) if not os.path.exists(path): target = path break # subdir should not in normal behavior be None. It can occur if something # prevented a directory from being removed on a previous call or if MAX_DIR # is changed. if target is None: subdir = efs2(u"BitTorrentTemp0") path = os.path.join(tmp, subdir) shutil.rmtree( path, ignore_errors = True ) target = path i = 0 # create the temp dir. os.mkdir(target) # delete the oldest directory. oldest_i = ( i + 1 ) % MAX_DIR oldest_subdir = efs2(u"BitTorrentTemp%d" % oldest_i) oldest_path = os.path.join(tmp, oldest_subdir) if os.path.exists( oldest_path ): shutil.rmtree( oldest_path, ignore_errors = True ) _tmp_subdir = target return target# NOTE: intentionally appears in the file before importing anything# from BitTorrent because it is called when setting --use_factory_defaults._config_dir = Nonedef set_config_dir(dir): """Set the root directory for configuration information.""" global _config_dir # Normally we won't set it this way. This is called if the # --use_factory_defaults command-line option is specfied. By changing # the config directory early in the initialization we can guarantee # that the system acts like a fresh install. _config_dir = dir# Set configuration directory before importing any other BitTorrent modules.if "--use_factory_defaults" in sys.argv or "-u" in sys.argv: temp_dir = get_temp_subdir() set_config_dir(temp_dir)from BitTorrent import app_name, version, LOCALE_URLfrom BitTorrent import languagefrom BitTorrent.sparse_set import SparseSetfrom BitTorrent.defer import ThreadedDeferredold_broken_config_subencoding = 'utf8'try: old_broken_config_subencoding = sys.getfilesystemencoding()except: passif sys.platform.startswith('win'): bttime = time.clockelse: bttime = time.timeis_frozen_exe = (os.name == 'nt') and hasattr(sys, 'frozen') and (sys.frozen == 'windows_exe')os_name = os.nameos_version = Noneif os_name == 'nt': wh = {(1, 4, 0): "95", (1, 4, 10): "98", (1, 4, 90): "ME", (2, 4, 0): "NT", (2, 5, 0): "2000", (2, 5, 1): "XP" , (2, 5, 2): "2003", (2, 6, 0): "Vista", } class OSVERSIONINFOEX(ctypes.Structure): _fields_ = [("dwOSVersionInfoSize", ctypes.c_ulong), ("dwMajorVersion", ctypes.c_ulong), ("dwMinorVersion", ctypes.c_ulong), ("dwBuildNumber", ctypes.c_ulong), ("dwPlatformId", ctypes.c_ulong), ("szCSDVersion", ctypes.c_char * 128), ("wServicePackMajor", ctypes.c_ushort), ("wServicePackMinor", ctypes.c_ushort), ("wSuiteMask", ctypes.c_ushort), ("wProductType", ctypes.c_byte), ("wReserved", ctypes.c_byte), ] class OSVERSIONINFO(ctypes.Structure): _fields_ = [("dwOSVersionInfoSize", ctypes.c_ulong), ("dwMajorVersion", ctypes.c_ulong), ("dwMinorVersion", ctypes.c_ulong), ("dwBuildNumber", ctypes.c_ulong), ("dwPlatformId", ctypes.c_ulong), ("szCSDVersion", ctypes.c_char * 128), ] o = OSVERSIONINFOEX() o.dwOSVersionInfoSize = 156 # sizeof(OSVERSIONINFOEX) r = ctypes.windll.kernel32.GetVersionExA(ctypes.byref(o)) if r: win_version_num = (o.dwPlatformId, o.dwMajorVersion, o.dwMinorVersion, o.wServicePackMajor, o.wServicePackMinor, o.dwBuildNumber) else: o = OSVERSIONINFOEX() o.dwOSVersionInfoSize = 148 # sizeof(OSVERSIONINFO) r = ctypes.windll.kernel32.GetVersionExA(ctypes.byref(o)) win_version_num = (o.dwPlatformId, o.dwMajorVersion, o.dwMinorVersion, 0, 0, o.dwBuildNumber) wk = (o.dwPlatformId, o.dwMajorVersion, o.dwMinorVersion) if wh.has_key(wk): os_version = wh[wk] else: os_version = wh[max(wh.keys())] sys.stderr.write("Couldn't identify windows version: wk:%s, %s, " "assuming '%s'\n" % (str(wk), str(win_version_num), os_version)) del wh, wkelif os_name == 'posix': os_version = os.uname()[0]def calc_unix_dirs(): appdir = '%s-%s'%(app_name, version) ip = os.path.join(efs2(u'share'), efs2(u'pixmaps'), appdir) dp = os.path.join(efs2(u'share'), efs2(u'doc'), appdir) lp = os.path.join(efs2(u'share'), efs2(u'locale')) return ip, dp, lpif is_frozen_exe: app_root = os.path.split(os.path.abspath(win32api.GetModuleFileName(0)))[0]else: app_root = os.path.split(os.path.abspath(sys.argv[0]))[0]doc_root = app_rootosx = Falseif os.name == 'posix': if os.uname()[0] == "Darwin": doc_root = app_root = app_root.encode('utf8') if has_pyobjc: doc_root = NSBundle.mainBundle().resourcePath() osx = Truedef no_really_makedirs(path): # the deal here is, directories like "C:\" exist but can not be created # (access denied). We check for the exception anyway because of the race # condition. if not os.path.exists(path): try: os.makedirs(path) except OSError, e: if e.errno != 17: # already exists raise# For string literal subdirectories, starting with unicode and then# converting to filesystem encoding may not always be necessary, but it seems
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -