📄 utility.py
字号:
def eta_value(self, n, truncate = 3):
if n == -1:
return '<unknown>'
if not n:
return ''
n = int(n)
week, r1 = divmod(n, 60 * 60 * 24 * 7)
day, r2 = divmod(r1, 60 * 60 * 24)
hour, r3 = divmod(r2, 60 * 60)
minute, sec = divmod(r3, 60)
if week > 1000:
return '<unknown>'
weekstr = '%d' % (week) + self.lang.get('l_week')
daystr = '%d' % (day) + self.lang.get('l_day')
hourstr = '%d' % (hour) + self.lang.get('l_hour')
minutestr = '%02d' % (minute) + self.lang.get('l_minute')
secstr = '%02d' % (sec) + self.lang.get('l_second')
if week > 0:
text = weekstr
if truncate > 1:
text += ":" + daystr
if truncate > 2:
text += "-" + hourstr
elif day > 0:
text = daystr
if truncate > 1:
text += "-" + hourstr
if truncate > 2:
text += ":" + minutestr
elif hour > 0:
text = hourstr
if truncate > 1:
text += ":" + minutestr
if truncate > 2:
text += ":" + secstr
else:
text = minutestr
if truncate > 1:
text += ":" + secstr
return text
def getMetainfo(self, src, openoptions = 'rb', style = "file"):
if src is None:
return None
metainfo = None
try:
metainfo_file = None
# We're getting a url
if style == "rawdata":
return bdecode(src)
elif style == "url":
metainfo_file = urlopen(src)
# We're getting a file that exists
elif os.access(src, os.R_OK):
metainfo_file = open(src, openoptions)
if metainfo_file is not None:
metainfo = bdecode(metainfo_file.read())
metainfo_file.close()
except:
if metainfo_file is not None:
try:
metainfo_file.close()
except:
pass
metainfo = None
return metainfo
def speed_format(self, s, truncate = 1, stopearly = None):
return self.size_format(s, truncate, stopearly) + "/" + self.lang.get('l_second')
def size_format(self, s, truncate = None, stopearly = None, applylabel = True, rawsize = False, showbytes = False, labelonly = False, textonly = False):
size = 0.0
label = ""
if truncate is None:
truncate = 2
if ((s < 1024) and showbytes and stopearly is None) or stopearly == "Byte":
truncate = 0
size = s
text = "Byte"
elif ((s < 1048576) and stopearly is None) or stopearly == "KB":
size = (s/1024.0)
text = "KB"
elif ((s < 1073741824L) and stopearly is None) or stopearly == "MB":
size = (s/1048576.0)
text = "MB"
elif ((s < 1099511627776L) and stopearly is None) or stopearly == "GB":
size = (s/1073741824.0)
text = "GB"
else:
size = (s/1099511627776.0)
text = "TB"
if textonly:
return text
label = self.lang.get(text)
if labelonly:
return label
if rawsize:
return size
# At this point, only accepting 0, 1, or 2
if truncate == 0:
text = ('%.0f' % size)
elif truncate == 1:
text = ('%.1f' % size)
else:
text = ('%.2f' % size)
if applylabel:
text += ' ' + label
return text
def makeNumCtrl(self, parent, value, integerWidth = 6, fractionWidth = 0, min = 0, max = None, size = wx.DefaultSize):
if size != wx.DefaultSize:
autoSize = False
else:
autoSize = True
return masked.NumCtrl(parent,
value = value,
size = size,
integerWidth = integerWidth,
fractionWidth = fractionWidth,
allowNegative = False,
min = min,
max = max,
groupDigits = False,
useFixedWidthFont = False,
autoSize = autoSize)
def MakeTorrentDir(self):
torrentpath = os.path.join(self.getConfigPath(), "torrent")
pathexists = os.access(torrentpath, os.F_OK)
# If the torrent directory doesn't exist, create it now
if not pathexists:
os.mkdir(torrentpath)
def RemoveEmptyDir(self, basedir, removesubdirs = True):
# remove subdirectories
if removesubdirs:
for root, dirs, files in os.walk(basedir, topdown = False):
for name in dirs:
dirname = os.path.join(root, name)
# Only try to delete if it exists
if os.access(dirname, os.F_OK):
if not os.listdir(dirname):
os.rmdir(dirname)
#remove folder
if os.access(basedir, os.F_OK):
if not os.listdir(basedir):
os.rmdir(basedir)
def makeBitmap(self, bitmap, trans_color = wx.Colour(200, 200, 200)):
button_bmp = wx.Bitmap(os.path.join(self.getPath(), 'icons', bitmap), wx.BITMAP_TYPE_BMP)
button_mask = wx.Mask(button_bmp, trans_color)
button_bmp.SetMask(button_mask)
return button_bmp
def makeBitmapButton(self, parent, bitmap, tooltip, event, trans_color = wx.Colour(200, 200, 200)):
tooltiptext = self.lang.get(tooltip)
button_bmp = self.makeBitmap(bitmap, trans_color)
ID_BUTTON = wx.NewId()
button_btn = wx.BitmapButton(parent, ID_BUTTON, button_bmp, size=wx.Size(button_bmp.GetWidth()+18, button_bmp.GetHeight()+4))
button_btn.SetToolTipString(tooltiptext)
parent.Bind(wx.EVT_BUTTON, event, button_btn)
return button_btn
def getBTParams(self, skipcheck = False):
# Construct BT params
###########################
btparams = []
btparams.append("--display_interval")
btparams.append(self.config.Read('display_interval'))
# Use single port only
btparams.append("--minport")
btparams.append(self.config.Read('minport'))
btparams.append("--maxport")
btparams.append(self.config.Read('minport'))
# btparams.append("--random_port")
# btparams.append(self.config.Read('randomport'))
#if self.config.Read('ipv6') == "1":
# btparams.append("--ipv6_enable")
# btparams.append(self.config.Read('ipv6'))
# btparams.append("--ipv6_binds_v4")
# btparams.append(self.config.Read('ipv6_binds_v4'))
# Fast resume
btparams.append("--selector_enabled")
btparams.append(self.config.Read('fastresume'))
btparams.append("--auto_kick")
btparams.append(self.config.Read('kickban'))
btparams.append("--security")
btparams.append(self.config.Read('notsameip'))
btparams.append("--max_upload_rate")
btparams.append("0")
paramlist = [ "ip",
"bind",
"alloc_rate",
"alloc_type",
"double_check",
"triple_check",
"lock_while_reading",
"lock_files",
"min_peers",
"max_files_open",
"max_connections",
"upnp_nat_access",
"auto_flush" ]
for param in paramlist:
value = self.config.Read(param)
if value != "":
btparams.append("--" + param)
btparams.append(value)
config, args = parseargs(btparams, BTDefaults)
return config
# Check if str is a valid Windows file name (or unit name if unit is true)
# If the filename isn't valid: returns a fixed name
# If the filename is valid: returns an empty string
def fixWindowsName(self, name, unit = False):
if unit and (len(name) != 2 or name[1] != ':'):
return 'c:'
if not name or name == '.' or name == '..':
return '_'
if unit:
name = name[0]
fixed = False
if len(name) > 250:
name = name[:250]
fixed = True
fixedname = ''
spaces = 0
for c in name:
if c in self.invalidwinfilenamechar:
fixedname += '_'
fixed = True
else:
fixedname += c
if c == ' ':
spaces += 1
if fixed:
return fixedname
elif spaces == len(name):
# contains only spaces
return '_'
else:
return ''
def checkWinPath(self, parent, pathtocheck):
if pathtocheck and pathtocheck[-1] == '\\' and pathtocheck != '\\\\':
pathitems = pathtocheck[:-1].split('\\')
else:
pathitems = pathtocheck.split('\\')
nexttotest = 1
if self.isPathRelative(pathtocheck):
# Relative path
# Empty relative path is allowed
if pathtocheck == '':
return True
fixedname = self.fixWindowsName(pathitems[0])
if fixedname:
dlg = wx.MessageDialog(parent,
pathitems[0] + '\n' + \
self.lang.get('invalidwinname') + '\n'+ \
self.lang.get('suggestedname') + '\n\n' + \
fixedname,
self.lang.get('error'), wx.ICON_ERROR)
dlg.ShowModal()
dlg.Destroy()
return False
else:
# Absolute path
# An absolute path must have at least one '\'
if not '\\' in pathtocheck:
dlg = wx.MessageDialog(parent, pathitems[0] + '\n' + self.lang.get('errorinvalidpath'),
self.lang.get('error'), wx.ICON_ERROR)
dlg.ShowModal()
dlg.Destroy()
return False
if pathtocheck[:2] != '\\\\':
# Not a network path
fixedname = self.fixWindowsName(pathitems[0], unit = True)
if fixedname:
dlg = wx.MessageDialog(parent,
pathitems[0] + '\n' + \
self.lang.get('invalidwinname') + \
fixedname,
self.lang.get('error'), wx.ICON_ERROR)
dlg.ShowModal()
dlg.Destroy()
return False
else:
# Network path
nexttotest = 2
for name in pathitems[nexttotest:]:
fixedname = self.fixWindowsName(name)
if fixedname:
dlg = wx.MessageDialog(parent, name + '\n' + self.lang.get('errorinvalidwinname') + fixedname,
self.lang.get('error'), wx.ICON_ERROR)
dlg.ShowModal()
dlg.Destroy()
return False
return True
def isPathRelative(self, path):
if len(path) < 2 or path[1] != ':' and path[:2] != '\\\\':
return True
return False
# Get a dictionary with information about a font
def getInfoFromFont(self, font):
default = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
try:
if font.Ok():
font_to_use = font
else:
font_to_use = default
fontname = font_to_use.GetFaceName()
fontsize = font_to_use.GetPointSize()
fontstyle = font_to_use.GetStyle()
fontweight = font_to_use.GetWeight()
fontinfo = {'name': fontname,
'size': fontsize,
'style': fontstyle,
'weight': fontweight }
except:
fontinfo = {'name': "",
'size': 8,
'style': wx.FONTSTYLE_NORMAL,
'weight': wx.FONTWEIGHT_NORMAL }
return fontinfo
def getFontFromInfo(self, fontinfo):
size = fontinfo['size']
name = fontinfo['name']
style = fontinfo['style']
weight = fontinfo['weight']
try:
font = wx.Font(size, wx.DEFAULT, style, weight, faceName = name)
except:
font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
return font
# Make an entry for a popup menu
def makePopup(self, menu, event = None, label = "", extralabel = "", bindto = None):
text = ""
if label != "":
text = self.lang.get(label)
text += extralabel
newid = wx.NewId()
if event is not None:
if bindto is None:
bindto = menu
bindto.Bind(wx.EVT_MENU, event, id = newid)
menu.Append(newid, text)
return newid
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -