ConfigReader.py 55 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195
  1. #written by John Hoffman
  2. from ConnChoice import *
  3. from wxPython.wx import *
  4. from types import IntType, FloatType, StringType
  5. from download_bt1 import defaults
  6. from ConfigDir import ConfigDir
  7. import sys,os
  8. import socket
  9. from parseargs import defaultargs
  10. from BTcrypto import CRYPTO_OK
  11. try:
  12. True
  13. except:
  14. True = 1
  15. False = 0
  16. try:
  17. wxFULL_REPAINT_ON_RESIZE
  18. except:
  19. wxFULL_REPAINT_ON_RESIZE = 0 # fix for wx pre-2.5
  20. if (sys.platform == 'win32'):
  21. _FONT = 9
  22. else:
  23. _FONT = 10
  24. def HexToColor(s):
  25. r,g,b = s.split(' ')
  26. return wxColour(red=int(r,16), green=int(g,16), blue=int(b,16))
  27. def hex2(c):
  28. h = hex(c)[2:]
  29. if len(h) == 1:
  30. h = '0'+h
  31. return h
  32. def ColorToHex(c):
  33. return hex2(c.Red()) + ' ' + hex2(c.Green()) + ' ' + hex2(c.Blue())
  34. ratesettingslist = []
  35. for x in connChoices:
  36. if not x.has_key('super-seed'):
  37. ratesettingslist.append(x['name'])
  38. configFileDefaults = [
  39. #args only available for the gui client
  40. ('win32_taskbar_icon', 1,
  41. "whether to iconize do system try or not on win32"),
  42. ('gui_stretchwindow', 0,
  43. "whether to stretch the download status window to fit the torrent name"),
  44. ('gui_displaystats', 1,
  45. "whether to display statistics on peers and seeds"),
  46. ('gui_displaymiscstats', 1,
  47. "whether to display miscellaneous other statistics"),
  48. ('gui_ratesettingsdefault', ratesettingslist[0],
  49. "the default setting for maximum upload rate and users"),
  50. ('gui_ratesettingsmode', 'full',
  51. "what rate setting controls to display; options are 'none', 'basic', and 'full'"),
  52. ('gui_forcegreenonfirewall', 0,
  53. "forces the status icon to be green even if the client seems to be firewalled"),
  54. ('gui_default_savedir', '',
  55. "default save directory"),
  56. ('last_saved', '', # hidden; not set in config
  57. "where the last torrent was saved"),
  58. ('gui_font', _FONT,
  59. "the font size to use"),
  60. ('gui_saveas_ask', -1,
  61. "whether to ask where to download to (0 = never, 1 = always, -1 = automatic resume"),
  62. ]
  63. def setwxconfigfiledefaults():
  64. CHECKINGCOLOR = ColorToHex(wxSystemSettings_GetColour(wxSYS_COLOUR_3DSHADOW))
  65. DOWNLOADCOLOR = ColorToHex(wxSystemSettings_GetColour(wxSYS_COLOUR_ACTIVECAPTION))
  66. configFileDefaults.extend([
  67. ('gui_checkingcolor', CHECKINGCOLOR,
  68. "progress bar checking color"),
  69. ('gui_downloadcolor', DOWNLOADCOLOR,
  70. "progress bar downloading color"),
  71. ('gui_seedingcolor', '00 FF 00',
  72. "progress bar seeding color"),
  73. ])
  74. defaultsToIgnore = ['responsefile', 'url', 'priority']
  75. class configReader:
  76. def __init__(self):
  77. self.configfile = wxConfig("BitTorrent",style=wxCONFIG_USE_LOCAL_FILE)
  78. self.configMenuBox = None
  79. self.advancedMenuBox = None
  80. self.cryptoMenuBox = None
  81. self._configReset = True # run reset for the first time
  82. setwxconfigfiledefaults()
  83. defaults.extend(configFileDefaults)
  84. self.defaults = defaultargs(defaults)
  85. self.configDir = ConfigDir('gui')
  86. self.configDir.setDefaults(defaults,defaultsToIgnore)
  87. if self.configDir.checkConfig():
  88. self.config = self.configDir.loadConfig()
  89. else:
  90. self.config = self.configDir.getConfig()
  91. self.importOldGUIConfig()
  92. self.configDir.saveConfig()
  93. updated = False # make all config default changes here
  94. if self.config['gui_ratesettingsdefault'] not in ratesettingslist:
  95. self.config['gui_ratesettingsdefault'] = (
  96. self.defaults['gui_ratesettingsdefault'] )
  97. updated = True
  98. if self.config['ipv6_enabled'] and (
  99. sys.version_info < (2,3) or not socket.has_ipv6 ):
  100. self.config['ipv6_enabled'] = 0
  101. updated = True
  102. for c in ['gui_checkingcolor','gui_downloadcolor','gui_seedingcolor']:
  103. try:
  104. HexToColor(self.config[c])
  105. except:
  106. self.config[c] = self.defaults[c]
  107. updated = True
  108. if updated:
  109. self.configDir.saveConfig()
  110. self.configDir.deleteOldCacheData(self.config['expire_cache_data'])
  111. def importOldGUIConfig(self):
  112. oldconfig = wxConfig("BitTorrent",style=wxCONFIG_USE_LOCAL_FILE)
  113. cont, s, i = oldconfig.GetFirstEntry()
  114. if not cont:
  115. oldconfig.DeleteAll()
  116. return False
  117. while cont: # import old config data
  118. if self.config.has_key(s):
  119. t = oldconfig.GetEntryType(s)
  120. try:
  121. if t == 1:
  122. assert type(self.config[s]) == type('')
  123. self.config[s] = oldconfig.Read(s)
  124. elif t == 2 or t == 3:
  125. assert type(self.config[s]) == type(1)
  126. self.config[s] = int(oldconfig.ReadInt(s))
  127. elif t == 4:
  128. assert type(self.config[s]) == type(1.0)
  129. self.config[s] = oldconfig.ReadFloat(s)
  130. except:
  131. pass
  132. cont, s, i = oldconfig.GetNextEntry(i)
  133. # oldconfig.DeleteAll()
  134. return True
  135. def resetConfigDefaults(self):
  136. for p,v in self.defaults.items():
  137. if not p in defaultsToIgnore:
  138. self.config[p] = v
  139. self.configDir.saveConfig()
  140. def writeConfigFile(self):
  141. self.configDir.saveConfig()
  142. def WriteLastSaved(self, l):
  143. self.config['last_saved'] = l
  144. self.configDir.saveConfig()
  145. def getcheckingcolor(self):
  146. return HexToColor(self.config['gui_checkingcolor'])
  147. def getdownloadcolor(self):
  148. return HexToColor(self.config['gui_downloadcolor'])
  149. def getseedingcolor(self):
  150. return HexToColor(self.config['gui_seedingcolor'])
  151. def configReset(self):
  152. r = self._configReset
  153. self._configReset = False
  154. return r
  155. def getConfigDir(self):
  156. return self.configDir
  157. def getIconDir(self):
  158. return self.configDir.getIconDir()
  159. def getTorrentData(self,t):
  160. return self.configDir.getTorrentData(t)
  161. def setColorIcon(self, xxicon, xxiconptr, xxcolor):
  162. idata = wxMemoryDC()
  163. idata.SelectObject(xxicon)
  164. idata.SetBrush(wxBrush(xxcolor,wxSOLID))
  165. idata.DrawRectangle(0,0,16,16)
  166. idata.SelectObject(wxNullBitmap)
  167. xxiconptr.Refresh()
  168. def getColorFromUser(self, parent, colInit):
  169. data = wxColourData()
  170. if colInit.Ok():
  171. data.SetColour(colInit)
  172. data.SetCustomColour(0, self.checkingcolor)
  173. data.SetCustomColour(1, self.downloadcolor)
  174. data.SetCustomColour(2, self.seedingcolor)
  175. dlg = wxColourDialog(parent,data)
  176. if not dlg.ShowModal():
  177. return colInit
  178. return dlg.GetColourData().GetColour()
  179. def configMenu(self, parent):
  180. self.parent = parent
  181. try:
  182. self.FONT = self.config['gui_font']
  183. self.default_font = wxFont(self.FONT, wxDEFAULT, wxNORMAL, wxNORMAL, False)
  184. self.checkingcolor = HexToColor(self.config['gui_checkingcolor'])
  185. self.downloadcolor = HexToColor(self.config['gui_downloadcolor'])
  186. self.seedingcolor = HexToColor(self.config['gui_seedingcolor'])
  187. if (self.configMenuBox is not None):
  188. try:
  189. self.configMenuBox.Close()
  190. except wxPyDeadObjectError, e:
  191. self.configMenuBox = None
  192. self.configMenuBox = wxFrame(None, -1, 'BitTornado Preferences', size = (1,1),
  193. style = wxDEFAULT_FRAME_STYLE|wxFULL_REPAINT_ON_RESIZE)
  194. if (sys.platform == 'win32'):
  195. self.icon = self.parent.icon
  196. self.configMenuBox.SetIcon(self.icon)
  197. panel = wxPanel(self.configMenuBox, -1)
  198. self.panel = panel
  199. def StaticText(text, font = self.FONT, underline = False, color = None, panel = panel):
  200. x = wxStaticText(panel, -1, text, style = wxALIGN_LEFT)
  201. x.SetFont(wxFont(font, wxDEFAULT, wxNORMAL, wxNORMAL, underline))
  202. if color is not None:
  203. x.SetForegroundColour(color)
  204. return x
  205. colsizer = wxFlexGridSizer(cols = 1, vgap = 8)
  206. self.gui_stretchwindow_checkbox = wxCheckBox(panel, -1, "Stretch window to fit torrent name *")
  207. self.gui_stretchwindow_checkbox.SetFont(self.default_font)
  208. self.gui_stretchwindow_checkbox.SetValue(self.config['gui_stretchwindow'])
  209. self.gui_displaystats_checkbox = wxCheckBox(panel, -1, "Display peer and seed statistics")
  210. self.gui_displaystats_checkbox.SetFont(self.default_font)
  211. self.gui_displaystats_checkbox.SetValue(self.config['gui_displaystats'])
  212. self.gui_displaymiscstats_checkbox = wxCheckBox(panel, -1, "Display miscellaneous other statistics")
  213. self.gui_displaymiscstats_checkbox.SetFont(self.default_font)
  214. self.gui_displaymiscstats_checkbox.SetValue(self.config['gui_displaymiscstats'])
  215. self.buffering_checkbox = wxCheckBox(panel, -1, "Enable read/write buffering *")
  216. self.buffering_checkbox.SetFont(self.default_font)
  217. self.buffering_checkbox.SetValue(self.config['buffer_reads'])
  218. self.breakup_checkbox = wxCheckBox(panel, -1, "Break-up seed bitfield to foil ISP manipulation")
  219. self.breakup_checkbox.SetFont(self.default_font)
  220. self.breakup_checkbox.SetValue(self.config['breakup_seed_bitfield'])
  221. self.autoflush_checkbox = wxCheckBox(panel, -1, "Flush data to disk every 5 minutes")
  222. self.autoflush_checkbox.SetFont(self.default_font)
  223. self.autoflush_checkbox.SetValue(self.config['auto_flush'])
  224. if sys.version_info >= (2,3) and socket.has_ipv6:
  225. self.ipv6enabled_checkbox = wxCheckBox(panel, -1, "Initiate and receive connections via IPv6 *")
  226. self.ipv6enabled_checkbox.SetFont(self.default_font)
  227. self.ipv6enabled_checkbox.SetValue(self.config['ipv6_enabled'])
  228. self.gui_forcegreenonfirewall_checkbox = wxCheckBox(panel, -1,
  229. "Force icon to display green when firewalled")
  230. self.gui_forcegreenonfirewall_checkbox.SetFont(self.default_font)
  231. self.gui_forcegreenonfirewall_checkbox.SetValue(self.config['gui_forcegreenonfirewall'])
  232. cryptoButton = wxButton(panel, -1, 'Encryption/Security Settings...')
  233. self.minport_data = wxSpinCtrl(panel, -1, '', (-1,-1), (self.FONT*8, -1))
  234. self.minport_data.SetFont(self.default_font)
  235. self.minport_data.SetRange(1,65535)
  236. self.minport_data.SetValue(self.config['minport'])
  237. self.maxport_data = wxSpinCtrl(panel, -1, '', (-1,-1), (self.FONT*8, -1))
  238. self.maxport_data.SetFont(self.default_font)
  239. self.maxport_data.SetRange(1,65535)
  240. self.maxport_data.SetValue(self.config['maxport'])
  241. self.randomport_checkbox = wxCheckBox(panel, -1, "randomize")
  242. self.randomport_checkbox.SetFont(self.default_font)
  243. self.randomport_checkbox.SetValue(self.config['random_port'])
  244. self.gui_font_data = wxSpinCtrl(panel, -1, '', (-1,-1), (self.FONT*5, -1))
  245. self.gui_font_data.SetFont(self.default_font)
  246. self.gui_font_data.SetRange(8,16)
  247. self.gui_font_data.SetValue(self.config['gui_font'])
  248. self.gui_ratesettingsdefault_data=wxChoice(panel, -1, choices = ratesettingslist)
  249. self.gui_ratesettingsdefault_data.SetFont(self.default_font)
  250. self.gui_ratesettingsdefault_data.SetStringSelection(self.config['gui_ratesettingsdefault'])
  251. self.maxdownload_data = wxSpinCtrl(panel, -1, '', (-1,-1), (self.FONT*7, -1))
  252. self.maxdownload_data.SetFont(self.default_font)
  253. self.maxdownload_data.SetRange(0,5000)
  254. self.maxdownload_data.SetValue(self.config['max_download_rate'])
  255. self.gui_ratesettingsmode_data=wxRadioBox(panel, -1, 'Rate Settings Mode',
  256. choices = [ 'none', 'basic', 'full' ] )
  257. self.gui_ratesettingsmode_data.SetFont(self.default_font)
  258. self.gui_ratesettingsmode_data.SetStringSelection(self.config['gui_ratesettingsmode'])
  259. if (sys.platform == 'win32'):
  260. self.win32_taskbar_icon_checkbox = wxCheckBox(panel, -1, "Minimize to system tray")
  261. self.win32_taskbar_icon_checkbox.SetFont(self.default_font)
  262. self.win32_taskbar_icon_checkbox.SetValue(self.config['win32_taskbar_icon'])
  263. self.upnp_data=wxChoice(panel, -1,
  264. choices = ['disabled', 'type 1 (fast)', 'type 2 (slow)'])
  265. self.upnp_data.SetFont(self.default_font)
  266. self.upnp_data.SetSelection(self.config['upnp_nat_access'])
  267. self.gui_default_savedir_ctrl = wxTextCtrl(parent = panel, id = -1,
  268. value = self.config['gui_default_savedir'],
  269. size = (26*self.FONT, -1), style = wxTE_PROCESS_TAB)
  270. self.gui_default_savedir_ctrl.SetFont(self.default_font)
  271. self.gui_savemode_data=wxRadioBox(panel, -1, 'Ask where to save: *',
  272. choices = [ 'always', 'never', 'auto-resume' ] )
  273. self.gui_savemode_data.SetFont(self.default_font)
  274. self.gui_savemode_data.SetSelection(1-self.config['gui_saveas_ask'])
  275. self.checkingcolor_icon = wxEmptyBitmap(16,16)
  276. self.checkingcolor_iconptr = wxStaticBitmap(panel, -1, self.checkingcolor_icon)
  277. self.setColorIcon(self.checkingcolor_icon, self.checkingcolor_iconptr, self.checkingcolor)
  278. self.downloadcolor_icon = wxEmptyBitmap(16,16)
  279. self.downloadcolor_iconptr = wxStaticBitmap(panel, -1, self.downloadcolor_icon)
  280. self.setColorIcon(self.downloadcolor_icon, self.downloadcolor_iconptr, self.downloadcolor)
  281. self.seedingcolor_icon = wxEmptyBitmap(16,16)
  282. self.seedingcolor_iconptr = wxStaticBitmap(panel, -1, self.seedingcolor_icon)
  283. self.setColorIcon(self.seedingcolor_icon, self.downloadcolor_iconptr, self.seedingcolor)
  284. rowsizer = wxFlexGridSizer(cols = 2, hgap = 20)
  285. block12sizer = wxFlexGridSizer(cols = 1, vgap = 12)
  286. block1sizer = wxFlexGridSizer(cols = 1, vgap = 2)
  287. if (sys.platform == 'win32'):
  288. block1sizer.Add(self.win32_taskbar_icon_checkbox)
  289. block1sizer.Add(self.gui_stretchwindow_checkbox)
  290. block1sizer.Add(self.gui_displaystats_checkbox)
  291. block1sizer.Add(self.gui_displaymiscstats_checkbox)
  292. block1sizer.Add(self.buffering_checkbox)
  293. block1sizer.Add(self.breakup_checkbox)
  294. block1sizer.Add(self.autoflush_checkbox)
  295. if sys.version_info >= (2,3) and socket.has_ipv6:
  296. block1sizer.Add(self.ipv6enabled_checkbox)
  297. block1sizer.Add(self.gui_forcegreenonfirewall_checkbox)
  298. block12sizer.Add(block1sizer)
  299. block12sizer.Add(cryptoButton, 0, wxALIGN_CENTER)
  300. colorsizer = wxStaticBoxSizer(wxStaticBox(panel, -1, "Gauge Colors:"), wxVERTICAL)
  301. colorsizer1 = wxFlexGridSizer(cols = 7)
  302. colorsizer1.Add(StaticText(' Checking: '), 1, wxALIGN_BOTTOM)
  303. colorsizer1.Add(self.checkingcolor_iconptr, 1, wxALIGN_BOTTOM)
  304. colorsizer1.Add(StaticText(' Downloading: '), 1, wxALIGN_BOTTOM)
  305. colorsizer1.Add(self.downloadcolor_iconptr, 1, wxALIGN_BOTTOM)
  306. colorsizer1.Add(StaticText(' Seeding: '), 1, wxALIGN_BOTTOM)
  307. colorsizer1.Add(self.seedingcolor_iconptr, 1, wxALIGN_BOTTOM)
  308. colorsizer1.Add(StaticText(' '))
  309. minsize = self.checkingcolor_iconptr.GetBestSize()
  310. minsize.SetHeight(minsize.GetHeight()+5)
  311. colorsizer1.SetMinSize(minsize)
  312. colorsizer.Add(colorsizer1)
  313. block12sizer.Add(colorsizer, 1, wxALIGN_LEFT)
  314. rowsizer.Add(block12sizer)
  315. block3sizer = wxFlexGridSizer(cols = 1)
  316. portsettingsSizer = wxStaticBoxSizer(wxStaticBox(panel, -1, "Port Range:*"), wxVERTICAL)
  317. portsettingsSizer1 = wxGridSizer(cols = 2, vgap = 1)
  318. portsettingsSizer1.Add(StaticText('From: '), 1, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT)
  319. portsettingsSizer1.Add(self.minport_data, 1, wxALIGN_BOTTOM)
  320. portsettingsSizer1.Add(StaticText('To: '), 1, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT)
  321. portsettingsSizer1.Add(self.maxport_data, 1, wxALIGN_BOTTOM)
  322. portsettingsSizer.Add(portsettingsSizer1)
  323. portsettingsSizer.Add(self.randomport_checkbox, 1, wxALIGN_CENTER)
  324. block3sizer.Add(portsettingsSizer, 1, wxALIGN_CENTER)
  325. block3sizer.Add(StaticText(' '))
  326. block3sizer.Add(self.gui_ratesettingsmode_data, 1, wxALIGN_CENTER)
  327. block3sizer.Add(StaticText(' '))
  328. ratesettingsSizer = wxFlexGridSizer(cols = 1, vgap = 2)
  329. ratesettingsSizer.Add(StaticText('Default Rate Setting: *'), 1, wxALIGN_CENTER)
  330. ratesettingsSizer.Add(self.gui_ratesettingsdefault_data, 1, wxALIGN_CENTER)
  331. block3sizer.Add(ratesettingsSizer, 1, wxALIGN_CENTER)
  332. if (sys.platform == 'win32'):
  333. block3sizer.Add(StaticText(' '))
  334. upnpSizer = wxFlexGridSizer(cols = 1, vgap = 2)
  335. upnpSizer.Add(StaticText('UPnP Port Forwarding: *'), 1, wxALIGN_CENTER)
  336. upnpSizer.Add(self.upnp_data, 1, wxALIGN_CENTER)
  337. block3sizer.Add(upnpSizer, 1, wxALIGN_CENTER)
  338. rowsizer.Add(block3sizer)
  339. colsizer.Add(rowsizer)
  340. block4sizer = wxFlexGridSizer(cols = 3, hgap = 15)
  341. savepathsizer = wxFlexGridSizer(cols = 2, vgap = 1)
  342. savepathsizer.Add(StaticText('Default Save Path: *'))
  343. savepathsizer.Add(StaticText(' '))
  344. savepathsizer.Add(self.gui_default_savedir_ctrl, 1, wxEXPAND)
  345. savepathButton = wxButton(panel, -1, '...', size = (18,18))
  346. # savepathButton.SetFont(self.default_font)
  347. savepathsizer.Add(savepathButton, 0, wxALIGN_CENTER)
  348. savepathsizer.Add(self.gui_savemode_data, 0, wxALIGN_CENTER)
  349. block4sizer.Add(savepathsizer, -1, wxALIGN_BOTTOM)
  350. fontsizer = wxFlexGridSizer(cols = 1, vgap = 2)
  351. fontsizer.Add(StaticText(''))
  352. fontsizer.Add(StaticText('Font: *'), 1, wxALIGN_CENTER)
  353. fontsizer.Add(self.gui_font_data, 1, wxALIGN_CENTER)
  354. block4sizer.Add(fontsizer, 1, wxALIGN_CENTER_VERTICAL)
  355. dratesettingsSizer = wxFlexGridSizer(cols = 1, vgap = 2)
  356. dratesettingsSizer.Add(StaticText('Default Max'), 1, wxALIGN_CENTER)
  357. dratesettingsSizer.Add(StaticText('Download Rate'), 1, wxALIGN_CENTER)
  358. dratesettingsSizer.Add(StaticText('(kB/s): *'), 1, wxALIGN_CENTER)
  359. dratesettingsSizer.Add(self.maxdownload_data, 1, wxALIGN_CENTER)
  360. dratesettingsSizer.Add(StaticText('(0 = disabled)'), 1, wxALIGN_CENTER)
  361. block4sizer.Add(dratesettingsSizer, 1, wxALIGN_CENTER_VERTICAL)
  362. colsizer.Add(block4sizer, 0, wxALIGN_CENTER)
  363. savesizer = wxGridSizer(cols = 4, hgap = 10)
  364. saveButton = wxButton(panel, -1, 'Save')
  365. # saveButton.SetFont(self.default_font)
  366. savesizer.Add(saveButton, 0, wxALIGN_CENTER)
  367. cancelButton = wxButton(panel, -1, 'Cancel')
  368. # cancelButton.SetFont(self.default_font)
  369. savesizer.Add(cancelButton, 0, wxALIGN_CENTER)
  370. defaultsButton = wxButton(panel, -1, 'Revert to Defaults')
  371. # defaultsButton.SetFont(self.default_font)
  372. savesizer.Add(defaultsButton, 0, wxALIGN_CENTER)
  373. advancedButton = wxButton(panel, -1, 'Advanced...')
  374. # advancedButton.SetFont(self.default_font)
  375. savesizer.Add(advancedButton, 0, wxALIGN_CENTER)
  376. colsizer.Add(savesizer, 1, wxALIGN_CENTER)
  377. resizewarningtext=StaticText('* These settings will not take effect until the next time you start BitTorrent', self.FONT-2)
  378. colsizer.Add(resizewarningtext, 1, wxALIGN_CENTER)
  379. border = wxBoxSizer(wxHORIZONTAL)
  380. border.Add(colsizer, 1, wxEXPAND | wxALL, 4)
  381. panel.SetSizer(border)
  382. panel.SetAutoLayout(True)
  383. self.advancedConfig = {}
  384. self.cryptoConfig = {}
  385. def setDefaults(evt, self = self):
  386. try:
  387. self.minport_data.SetValue(self.defaults['minport'])
  388. self.maxport_data.SetValue(self.defaults['maxport'])
  389. self.randomport_checkbox.SetValue(self.defaults['random_port'])
  390. self.gui_stretchwindow_checkbox.SetValue(self.defaults['gui_stretchwindow'])
  391. self.gui_displaystats_checkbox.SetValue(self.defaults['gui_displaystats'])
  392. self.gui_displaymiscstats_checkbox.SetValue(self.defaults['gui_displaymiscstats'])
  393. self.buffering_checkbox.SetValue(self.defaults['buffer_reads'])
  394. self.breakup_checkbox.SetValue(self.defaults['breakup_seed_bitfield'])
  395. self.autoflush_checkbox.SetValue(self.defaults['auto_flush'])
  396. if sys.version_info >= (2,3) and socket.has_ipv6:
  397. self.ipv6enabled_checkbox.SetValue(self.defaults['ipv6_enabled'])
  398. self.gui_forcegreenonfirewall_checkbox.SetValue(self.defaults['gui_forcegreenonfirewall'])
  399. self.gui_font_data.SetValue(self.defaults['gui_font'])
  400. self.gui_ratesettingsdefault_data.SetStringSelection(self.defaults['gui_ratesettingsdefault'])
  401. self.maxdownload_data.SetValue(self.defaults['max_download_rate'])
  402. self.gui_ratesettingsmode_data.SetStringSelection(self.defaults['gui_ratesettingsmode'])
  403. self.gui_default_savedir_ctrl.SetValue(self.defaults['gui_default_savedir'])
  404. self.gui_savemode_data.SetSelection(1-self.defaults['gui_saveas_ask'])
  405. self.checkingcolor = HexToColor(self.defaults['gui_checkingcolor'])
  406. self.setColorIcon(self.checkingcolor_icon, self.checkingcolor_iconptr, self.checkingcolor)
  407. self.downloadcolor = HexToColor(self.defaults['gui_downloadcolor'])
  408. self.setColorIcon(self.downloadcolor_icon, self.downloadcolor_iconptr, self.downloadcolor)
  409. self.seedingcolor = HexToColor(self.defaults['gui_seedingcolor'])
  410. self.setColorIcon(self.seedingcolor_icon, self.seedingcolor_iconptr, self.seedingcolor)
  411. if (sys.platform == 'win32'):
  412. self.win32_taskbar_icon_checkbox.SetValue(self.defaults['win32_taskbar_icon'])
  413. self.upnp_data.SetSelection(self.defaults['upnp_nat_access'])
  414. # reset advanced and crypto windows too
  415. self.advancedConfig = {}
  416. for key in ['ip', 'bind', 'min_peers', 'max_initiate', 'display_interval',
  417. 'alloc_type', 'alloc_rate', 'max_files_open', 'max_connections', 'super_seeder',
  418. 'ipv6_binds_v4', 'double_check', 'triple_check', 'lock_files', 'lock_while_reading',
  419. 'expire_cache_data']:
  420. self.advancedConfig[key] = self.defaults[key]
  421. self.cryptoConfig = {}
  422. for key in ['security', 'auto_kick',
  423. 'crypto_allowed', 'crypto_only', 'crypto_stealth']:
  424. self.cryptoConfig[key] = self.config[key]
  425. self.CloseAdvanced()
  426. except:
  427. self.parent.exception()
  428. def saveConfigs(evt, self = self):
  429. try:
  430. self.config['gui_stretchwindow']=int(self.gui_stretchwindow_checkbox.GetValue())
  431. self.config['gui_displaystats']=int(self.gui_displaystats_checkbox.GetValue())
  432. self.config['gui_displaymiscstats']=int(self.gui_displaymiscstats_checkbox.GetValue())
  433. buffering=int(self.buffering_checkbox.GetValue())
  434. self.config['buffer_reads']=buffering
  435. if buffering:
  436. self.config['write_buffer_size']=self.defaults['write_buffer_size']
  437. else:
  438. self.config['write_buffer_size']=0
  439. self.config['breakup_seed_bitfield']=int(self.breakup_checkbox.GetValue())
  440. if self.autoflush_checkbox.GetValue():
  441. self.config['auto_flush']=5
  442. else:
  443. self.config['auto_flush']=0
  444. if sys.version_info >= (2,3) and socket.has_ipv6:
  445. self.config['ipv6_enabled']=int(self.ipv6enabled_checkbox.GetValue())
  446. self.config['gui_forcegreenonfirewall']=int(self.gui_forcegreenonfirewall_checkbox.GetValue())
  447. self.config['minport']=self.minport_data.GetValue()
  448. self.config['maxport']=self.maxport_data.GetValue()
  449. self.config['random_port']=int(self.randomport_checkbox.GetValue())
  450. self.config['gui_font']=self.gui_font_data.GetValue()
  451. self.config['gui_ratesettingsdefault']=self.gui_ratesettingsdefault_data.GetStringSelection()
  452. self.config['max_download_rate']=self.maxdownload_data.GetValue()
  453. self.config['gui_ratesettingsmode']=self.gui_ratesettingsmode_data.GetStringSelection()
  454. self.config['gui_default_savedir']=self.gui_default_savedir_ctrl.GetValue()
  455. self.config['gui_saveas_ask']=1-self.gui_savemode_data.GetSelection()
  456. self.config['gui_checkingcolor']=ColorToHex(self.checkingcolor)
  457. self.config['gui_downloadcolor']=ColorToHex(self.downloadcolor)
  458. self.config['gui_seedingcolor']=ColorToHex(self.seedingcolor)
  459. if (sys.platform == 'win32'):
  460. self.config['win32_taskbar_icon']=int(self.win32_taskbar_icon_checkbox.GetValue())
  461. self.config['upnp_nat_access']=self.upnp_data.GetSelection()
  462. if self.advancedConfig:
  463. for key,val in self.advancedConfig.items():
  464. self.config[key] = val
  465. if self.cryptoConfig:
  466. for key,val in self.cryptoConfig.items():
  467. self.config[key] = val
  468. self.writeConfigFile()
  469. self._configReset = True
  470. self.Close()
  471. except:
  472. self.parent.exception()
  473. def cancelConfigs(evt, self = self):
  474. self.Close()
  475. def savepath_set(evt, self = self):
  476. try:
  477. d = self.gui_default_savedir_ctrl.GetValue()
  478. if d == '':
  479. d = self.config['last_saved']
  480. dl = wxDirDialog(self.panel, 'Choose a default directory to save to',
  481. d, style = wxDD_DEFAULT_STYLE | wxDD_NEW_DIR_BUTTON)
  482. if dl.ShowModal() == wxID_OK:
  483. self.gui_default_savedir_ctrl.SetValue(dl.GetPath())
  484. except:
  485. self.parent.exception()
  486. def checkingcoloricon_set(evt, self = self):
  487. try:
  488. newcolor = self.getColorFromUser(self.panel,self.checkingcolor)
  489. self.setColorIcon(self.checkingcolor_icon, self.checkingcolor_iconptr, newcolor)
  490. self.checkingcolor = newcolor
  491. except:
  492. self.parent.exception()
  493. def downloadcoloricon_set(evt, self = self):
  494. try:
  495. newcolor = self.getColorFromUser(self.panel,self.downloadcolor)
  496. self.setColorIcon(self.downloadcolor_icon, self.downloadcolor_iconptr, newcolor)
  497. self.downloadcolor = newcolor
  498. except:
  499. self.parent.exception()
  500. def seedingcoloricon_set(evt, self = self):
  501. try:
  502. newcolor = self.getColorFromUser(self.panel,self.seedingcolor)
  503. self.setColorIcon(self.seedingcolor_icon, self.seedingcolor_iconptr, newcolor)
  504. self.seedingcolor = newcolor
  505. except:
  506. self.parent.exception()
  507. EVT_BUTTON(self.configMenuBox, saveButton.GetId(), saveConfigs)
  508. EVT_BUTTON(self.configMenuBox, cancelButton.GetId(), cancelConfigs)
  509. EVT_BUTTON(self.configMenuBox, defaultsButton.GetId(), setDefaults)
  510. EVT_BUTTON(self.configMenuBox, advancedButton.GetId(), self.advancedMenu)
  511. EVT_BUTTON(self.configMenuBox, cryptoButton.GetId(), self.cryptoMenu)
  512. EVT_BUTTON(self.configMenuBox, savepathButton.GetId(), savepath_set)
  513. EVT_LEFT_DOWN(self.checkingcolor_iconptr, checkingcoloricon_set)
  514. EVT_LEFT_DOWN(self.downloadcolor_iconptr, downloadcoloricon_set)
  515. EVT_LEFT_DOWN(self.seedingcolor_iconptr, seedingcoloricon_set)
  516. self.configMenuBox.Show ()
  517. border.Fit(panel)
  518. self.configMenuBox.Fit()
  519. except:
  520. self.parent.exception()
  521. def Close(self):
  522. self.CloseAdvanced()
  523. if self.configMenuBox is not None:
  524. try:
  525. self.configMenuBox.Close ()
  526. except wxPyDeadObjectError, e:
  527. pass
  528. self.configMenuBox = None
  529. def advancedMenu(self, event = None):
  530. try:
  531. if not self.advancedConfig:
  532. for key in ['ip', 'bind', 'min_peers', 'max_initiate', 'display_interval',
  533. 'alloc_type', 'alloc_rate', 'max_files_open', 'max_connections', 'super_seeder',
  534. 'ipv6_binds_v4', 'double_check', 'triple_check', 'lock_files', 'lock_while_reading',
  535. 'expire_cache_data']:
  536. self.advancedConfig[key] = self.config[key]
  537. if (self.advancedMenuBox is not None):
  538. try:
  539. self.advancedMenuBox.Close ()
  540. except wxPyDeadObjectError, e:
  541. self.advancedMenuBox = None
  542. self.advancedMenuBox = wxFrame(None, -1, 'BitTornado Advanced Preferences', size = (1,1),
  543. style = wxDEFAULT_FRAME_STYLE|wxFULL_REPAINT_ON_RESIZE)
  544. if (sys.platform == 'win32'):
  545. self.advancedMenuBox.SetIcon(self.icon)
  546. panel = wxPanel(self.advancedMenuBox, -1)
  547. def StaticText(text, font = self.FONT, underline = False, color = None, panel = panel):
  548. x = wxStaticText(panel, -1, text, style = wxALIGN_LEFT)
  549. x.SetFont(wxFont(font, wxDEFAULT, wxNORMAL, wxNORMAL, underline))
  550. if color is not None:
  551. x.SetForegroundColour(color)
  552. return x
  553. colsizer = wxFlexGridSizer(cols = 1, hgap = 13, vgap = 13)
  554. warningtext = StaticText('CHANGE THESE SETTINGS AT YOUR OWN RISK', self.FONT+4, True, 'Red')
  555. colsizer.Add(warningtext, 1, wxALIGN_CENTER)
  556. self.ip_data = wxTextCtrl(parent = panel, id = -1,
  557. value = self.advancedConfig['ip'],
  558. size = (self.FONT*13, int(self.FONT*2.2)), style = wxTE_PROCESS_TAB)
  559. self.ip_data.SetFont(self.default_font)
  560. self.bind_data = wxTextCtrl(parent = panel, id = -1,
  561. value = self.advancedConfig['bind'],
  562. size = (self.FONT*13, int(self.FONT*2.2)), style = wxTE_PROCESS_TAB)
  563. self.bind_data.SetFont(self.default_font)
  564. if sys.version_info >= (2,3) and socket.has_ipv6:
  565. self.ipv6bindsv4_data=wxChoice(panel, -1,
  566. choices = ['separate sockets', 'single socket'])
  567. self.ipv6bindsv4_data.SetFont(self.default_font)
  568. self.ipv6bindsv4_data.SetSelection(self.advancedConfig['ipv6_binds_v4'])
  569. self.minpeers_data = wxSpinCtrl(panel, -1, '', (-1,-1), (self.FONT*7, -1))
  570. self.minpeers_data.SetFont(self.default_font)
  571. self.minpeers_data.SetRange(10,100)
  572. self.minpeers_data.SetValue(self.advancedConfig['min_peers'])
  573. # max_initiate = 2*minpeers
  574. self.displayinterval_data = wxSpinCtrl(panel, -1, '', (-1,-1), (self.FONT*7, -1))
  575. self.displayinterval_data.SetFont(self.default_font)
  576. self.displayinterval_data.SetRange(100,2000)
  577. self.displayinterval_data.SetValue(int(self.advancedConfig['display_interval']*1000))
  578. self.alloctype_data=wxChoice(panel, -1,
  579. choices = ['normal', 'background', 'pre-allocate', 'sparse'])
  580. self.alloctype_data.SetFont(self.default_font)
  581. self.alloctype_data.SetStringSelection(self.advancedConfig['alloc_type'])
  582. self.allocrate_data = wxSpinCtrl(panel, -1, '', (-1,-1), (self.FONT*7,-1))
  583. self.allocrate_data.SetFont(self.default_font)
  584. self.allocrate_data.SetRange(1,100)
  585. self.allocrate_data.SetValue(int(self.advancedConfig['alloc_rate']))
  586. self.locking_data=wxChoice(panel, -1,
  587. choices = ['no locking', 'lock while writing', 'lock always'])
  588. self.locking_data.SetFont(self.default_font)
  589. if self.advancedConfig['lock_files']:
  590. if self.advancedConfig['lock_while_reading']:
  591. self.locking_data.SetSelection(2)
  592. else:
  593. self.locking_data.SetSelection(1)
  594. else:
  595. self.locking_data.SetSelection(0)
  596. self.doublecheck_data=wxChoice(panel, -1,
  597. choices = ['no extra checking', 'double-check', 'triple-check'])
  598. self.doublecheck_data.SetFont(self.default_font)
  599. if self.advancedConfig['double_check']:
  600. if self.advancedConfig['triple_check']:
  601. self.doublecheck_data.SetSelection(2)
  602. else:
  603. self.doublecheck_data.SetSelection(1)
  604. else:
  605. self.doublecheck_data.SetSelection(0)
  606. self.maxfilesopen_choices = ['50', '100', '200', 'no limit ']
  607. self.maxfilesopen_data=wxChoice(panel, -1, choices = self.maxfilesopen_choices)
  608. self.maxfilesopen_data.SetFont(self.default_font)
  609. setval = self.advancedConfig['max_files_open']
  610. if setval == 0:
  611. setval = 'no limit '
  612. else:
  613. setval = str(setval)
  614. if not setval in self.maxfilesopen_choices:
  615. setval = self.maxfilesopen_choices[0]
  616. self.maxfilesopen_data.SetStringSelection(setval)
  617. self.maxconnections_choices = ['no limit ', '20', '30', '40', '50', '60', '100', '200']
  618. self.maxconnections_data=wxChoice(panel, -1, choices = self.maxconnections_choices)
  619. self.maxconnections_data.SetFont(self.default_font)
  620. setval = self.advancedConfig['max_connections']
  621. if setval == 0:
  622. setval = 'no limit '
  623. else:
  624. setval = str(setval)
  625. if not setval in self.maxconnections_choices:
  626. setval = self.maxconnections_choices[0]
  627. self.maxconnections_data.SetStringSelection(setval)
  628. self.superseeder_data=wxChoice(panel, -1,
  629. choices = ['normal', 'super-seed'])
  630. self.superseeder_data.SetFont(self.default_font)
  631. self.superseeder_data.SetSelection(self.advancedConfig['super_seeder'])
  632. self.expirecache_choices = ['never ', '3', '5', '7', '10', '15', '30', '60', '90']
  633. self.expirecache_data=wxChoice(panel, -1, choices = self.expirecache_choices)
  634. setval = self.advancedConfig['expire_cache_data']
  635. if setval == 0:
  636. setval = 'never '
  637. else:
  638. setval = str(setval)
  639. if not setval in self.expirecache_choices:
  640. setval = self.expirecache_choices[0]
  641. self.expirecache_data.SetFont(self.default_font)
  642. self.expirecache_data.SetStringSelection(setval)
  643. twocolsizer = wxFlexGridSizer(cols = 2, hgap = 20)
  644. datasizer = wxFlexGridSizer(cols = 2, vgap = 2)
  645. datasizer.Add(StaticText('Local IP: '), 1, wxALIGN_CENTER_VERTICAL)
  646. datasizer.Add(self.ip_data)
  647. datasizer.Add(StaticText('IP to bind to: '), 1, wxALIGN_CENTER_VERTICAL)
  648. datasizer.Add(self.bind_data)
  649. if sys.version_info >= (2,3) and socket.has_ipv6:
  650. datasizer.Add(StaticText('IPv6 socket handling: '), 1, wxALIGN_CENTER_VERTICAL)
  651. datasizer.Add(self.ipv6bindsv4_data)
  652. datasizer.Add(StaticText('Minimum number of peers: '), 1, wxALIGN_CENTER_VERTICAL)
  653. datasizer.Add(self.minpeers_data)
  654. datasizer.Add(StaticText('Display interval (ms): '), 1, wxALIGN_CENTER_VERTICAL)
  655. datasizer.Add(self.displayinterval_data)
  656. datasizer.Add(StaticText('Disk allocation type:'), 1, wxALIGN_CENTER_VERTICAL)
  657. datasizer.Add(self.alloctype_data)
  658. datasizer.Add(StaticText('Allocation rate (MiB/s):'), 1, wxALIGN_CENTER_VERTICAL)
  659. datasizer.Add(self.allocrate_data)
  660. datasizer.Add(StaticText('File locking:'), 1, wxALIGN_CENTER_VERTICAL)
  661. datasizer.Add(self.locking_data)
  662. datasizer.Add(StaticText('Extra data checking:'), 1, wxALIGN_CENTER_VERTICAL)
  663. datasizer.Add(self.doublecheck_data)
  664. datasizer.Add(StaticText('Max files open:'), 1, wxALIGN_CENTER_VERTICAL)
  665. datasizer.Add(self.maxfilesopen_data)
  666. datasizer.Add(StaticText('Max peer connections:'), 1, wxALIGN_CENTER_VERTICAL)
  667. datasizer.Add(self.maxconnections_data)
  668. datasizer.Add(StaticText('Default seeding mode:'), 1, wxALIGN_CENTER_VERTICAL)
  669. datasizer.Add(self.superseeder_data)
  670. datasizer.Add(StaticText('Expire resume data(days):'), 1, wxALIGN_CENTER_VERTICAL)
  671. datasizer.Add(self.expirecache_data)
  672. twocolsizer.Add(datasizer)
  673. infosizer = wxFlexGridSizer(cols = 1)
  674. self.hinttext = StaticText('', self.FONT, False, 'Blue')
  675. infosizer.Add(self.hinttext, 1, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL)
  676. infosizer.SetMinSize((180,100))
  677. twocolsizer.Add(infosizer, 1, wxEXPAND)
  678. colsizer.Add(twocolsizer)
  679. savesizer = wxGridSizer(cols = 3, hgap = 20)
  680. okButton = wxButton(panel, -1, 'OK')
  681. # okButton.SetFont(self.default_font)
  682. savesizer.Add(okButton, 0, wxALIGN_CENTER)
  683. cancelButton = wxButton(panel, -1, 'Cancel')
  684. # cancelButton.SetFont(self.default_font)
  685. savesizer.Add(cancelButton, 0, wxALIGN_CENTER)
  686. defaultsButton = wxButton(panel, -1, 'Revert to Defaults')
  687. # defaultsButton.SetFont(self.default_font)
  688. savesizer.Add(defaultsButton, 0, wxALIGN_CENTER)
  689. colsizer.Add(savesizer, 1, wxALIGN_CENTER)
  690. resizewarningtext=StaticText('None of these settings will take effect until the next time you start BitTorrent', self.FONT-2)
  691. colsizer.Add(resizewarningtext, 1, wxALIGN_CENTER)
  692. border = wxBoxSizer(wxHORIZONTAL)
  693. border.Add(colsizer, 1, wxEXPAND | wxALL, 4)
  694. panel.SetSizer(border)
  695. panel.SetAutoLayout(True)
  696. def setDefaults(evt, self = self):
  697. try:
  698. self.ip_data.SetValue(self.defaults['ip'])
  699. self.bind_data.SetValue(self.defaults['bind'])
  700. if sys.version_info >= (2,3) and socket.has_ipv6:
  701. self.ipv6bindsv4_data.SetSelection(self.defaults['ipv6_binds_v4'])
  702. self.minpeers_data.SetValue(self.defaults['min_peers'])
  703. self.displayinterval_data.SetValue(int(self.defaults['display_interval']*1000))
  704. self.alloctype_data.SetStringSelection(self.defaults['alloc_type'])
  705. self.allocrate_data.SetValue(int(self.defaults['alloc_rate']))
  706. if self.defaults['lock_files']:
  707. if self.defaults['lock_while_reading']:
  708. self.locking_data.SetSelection(2)
  709. else:
  710. self.locking_data.SetSelection(1)
  711. else:
  712. self.locking_data.SetSelection(0)
  713. if self.defaults['double_check']:
  714. if self.defaults['triple_check']:
  715. self.doublecheck_data.SetSelection(2)
  716. else:
  717. self.doublecheck_data.SetSelection(1)
  718. else:
  719. self.doublecheck_data.SetSelection(0)
  720. setval = self.defaults['max_files_open']
  721. if setval == 0:
  722. setval = 'no limit '
  723. else:
  724. setval = str(setval)
  725. if not setval in self.maxfilesopen_choices:
  726. setval = self.maxfilesopen_choices[0]
  727. self.maxfilesopen_data.SetStringSelection(setval)
  728. setval = self.defaults['max_connections']
  729. if setval == 0:
  730. setval = 'no limit '
  731. else:
  732. setval = str(setval)
  733. if not setval in self.maxconnections_choices:
  734. setval = self.maxconnections_choices[0]
  735. self.maxconnections_data.SetStringSelection(setval)
  736. self.superseeder_data.SetSelection(int(self.defaults['super_seeder']))
  737. setval = self.defaults['expire_cache_data']
  738. if setval == 0:
  739. setval = 'never '
  740. else:
  741. setval = str(setval)
  742. if not setval in self.expirecache_choices:
  743. setval = self.expirecache_choices[0]
  744. self.expirecache_data.SetStringSelection(setval)
  745. except:
  746. self.parent.exception()
  747. def saveConfigs(evt, self = self):
  748. try:
  749. self.advancedConfig['ip'] = self.ip_data.GetValue()
  750. self.advancedConfig['bind'] = self.bind_data.GetValue()
  751. if sys.version_info >= (2,3) and socket.has_ipv6:
  752. self.advancedConfig['ipv6_binds_v4'] = self.ipv6bindsv4_data.GetSelection()
  753. self.advancedConfig['min_peers'] = self.minpeers_data.GetValue()
  754. self.advancedConfig['display_interval'] = float(self.displayinterval_data.GetValue())/1000
  755. self.advancedConfig['alloc_type'] = self.alloctype_data.GetStringSelection()
  756. self.advancedConfig['alloc_rate'] = float(self.allocrate_data.GetValue())
  757. self.advancedConfig['lock_files'] = int(self.locking_data.GetSelection() >= 1)
  758. self.advancedConfig['lock_while_reading'] = int(self.locking_data.GetSelection() > 1)
  759. self.advancedConfig['double_check'] = int(self.doublecheck_data.GetSelection() >= 1)
  760. self.advancedConfig['triple_check'] = int(self.doublecheck_data.GetSelection() > 1)
  761. try:
  762. self.advancedConfig['max_files_open'] = int(self.maxfilesopen_data.GetStringSelection())
  763. except: # if it ain't a number, it must be "no limit"
  764. self.advancedConfig['max_files_open'] = 0
  765. try:
  766. self.advancedConfig['max_connections'] = int(self.maxconnections_data.GetStringSelection())
  767. self.advancedConfig['max_initiate'] = min(
  768. 2*self.advancedConfig['min_peers'], self.advancedConfig['max_connections'])
  769. except: # if it ain't a number, it must be "no limit"
  770. self.advancedConfig['max_connections'] = 0
  771. self.advancedConfig['max_initiate'] = 2*self.advancedConfig['min_peers']
  772. self.advancedConfig['super_seeder']=int(self.superseeder_data.GetSelection())
  773. try:
  774. self.advancedConfig['expire_cache_data'] = int(self.expirecache_data.GetStringSelection())
  775. except:
  776. self.advancedConfig['expire_cache_data'] = 0
  777. self.advancedMenuBox.Close()
  778. except:
  779. self.parent.exception()
  780. def cancelConfigs(evt, self = self):
  781. self.advancedMenuBox.Close()
  782. def ip_hint(evt, self = self):
  783. self.hinttext.SetLabel('\n\n\nThe IP reported to the tracker.\n' +
  784. 'unless the tracker is on the\n' +
  785. 'same intranet as this client,\n' +
  786. 'the tracker will autodetect the\n' +
  787. "client's IP and ignore this\n" +
  788. "value.")
  789. def bind_hint(evt, self = self):
  790. self.hinttext.SetLabel('\n\n\nThe IP the client will bind to.\n' +
  791. 'Only useful if your machine is\n' +
  792. 'directly handling multiple IPs.\n' +
  793. "If you don't know what this is,\n" +
  794. "leave it blank.")
  795. def ipv6bindsv4_hint(evt, self = self):
  796. self.hinttext.SetLabel('\n\n\nCertain operating systems will\n' +
  797. 'open IPv4 protocol connections on\n' +
  798. 'an IPv6 socket; others require you\n' +
  799. "to open two sockets on the same\n" +
  800. "port, one IPv4 and one IPv6.")
  801. def minpeers_hint(evt, self = self):
  802. self.hinttext.SetLabel('\n\n\nThe minimum number of peers the\n' +
  803. 'client tries to stay connected\n' +
  804. 'with. Do not set this higher\n' +
  805. 'unless you have a very fast\n' +
  806. "connection and a lot of system\n" +
  807. "resources.")
  808. def displayinterval_hint(evt, self = self):
  809. self.hinttext.SetLabel('\n\n\nHow often to update the\n' +
  810. 'graphical display, in 1/1000s\n' +
  811. 'of a second. Setting this too low\n' +
  812. "will strain your computer's\n" +
  813. "processor and video access.")
  814. def alloctype_hint(evt, self = self):
  815. self.hinttext.SetLabel('\n\nHow to allocate disk space.\n' +
  816. 'normal allocates space as data is\n' +
  817. 'received, background also adds\n' +
  818. "space in the background, pre-\n" +
  819. "allocate reserves up front, and\n" +
  820. 'sparse is only for filesystems\n' +
  821. 'that support it by default.')
  822. def allocrate_hint(evt, self = self):
  823. self.hinttext.SetLabel('\n\n\nAt what rate to allocate disk\n' +
  824. 'space when allocating in the\n' +
  825. 'background. Set this too high on a\n' +
  826. "slow filesystem and your download\n" +
  827. "will slow to a crawl.")
  828. def locking_hint(evt, self = self):
  829. self.hinttext.SetLabel('\n\n\n\nFile locking prevents other\n' +
  830. 'programs (including other instances\n' +
  831. 'of BitTorrent) from accessing files\n' +
  832. "you are downloading.")
  833. def doublecheck_hint(evt, self = self):
  834. self.hinttext.SetLabel('\n\n\nHow much extra checking to do\n' +
  835. 'making sure no data is corrupted.\n' +
  836. 'Double-check mode uses more CPU,\n' +
  837. "while triple-check mode increases\n" +
  838. "disk accesses.")
  839. def maxfilesopen_hint(evt, self = self):
  840. self.hinttext.SetLabel('\n\n\nThe maximum number of files to\n' +
  841. 'keep open at the same time. Zero\n' +
  842. 'means no limit. Please note that\n' +
  843. "if this option is in effect,\n" +
  844. "files are not guaranteed to be\n" +
  845. "locked.")
  846. def maxconnections_hint(evt, self = self):
  847. self.hinttext.SetLabel('\n\nSome operating systems, most\n' +
  848. 'notably Windows 9x/ME combined\n' +
  849. 'with certain network drivers,\n' +
  850. "cannot handle more than a certain\n" +
  851. "number of open ports. If the\n" +
  852. "client freezes, try setting this\n" +
  853. "to 60 or below.")
  854. def superseeder_hint(evt, self = self):
  855. self.hinttext.SetLabel('\n\nThe "super-seed" method allows\n' +
  856. 'a single source to more efficiently\n' +
  857. 'seed a large torrent, but is not\n' +
  858. "necessary in a well-seeded torrent,\n" +
  859. "and causes problems with statistics.\n" +
  860. "Unless you routinely seed torrents\n" +
  861. "you can enable this by selecting\n" +
  862. '"SUPER-SEED" for connection type.\n' +
  863. '(once enabled it does not turn off.)')
  864. def expirecache_hint(evt, self = self):
  865. self.hinttext.SetLabel('\n\nThe client stores temporary data\n' +
  866. 'in order to handle downloading only\n' +
  867. 'specific files from the torrent and\n' +
  868. "so it can resume downloads more\n" +
  869. "quickly. This sets how long the\n" +
  870. "client will keep this data before\n" +
  871. "deleting it to free disk space.")
  872. EVT_BUTTON(self.advancedMenuBox, okButton.GetId(), saveConfigs)
  873. EVT_BUTTON(self.advancedMenuBox, cancelButton.GetId(), cancelConfigs)
  874. EVT_BUTTON(self.advancedMenuBox, defaultsButton.GetId(), setDefaults)
  875. EVT_ENTER_WINDOW(self.ip_data, ip_hint)
  876. EVT_ENTER_WINDOW(self.bind_data, bind_hint)
  877. if sys.version_info >= (2,3) and socket.has_ipv6:
  878. EVT_ENTER_WINDOW(self.ipv6bindsv4_data, ipv6bindsv4_hint)
  879. EVT_ENTER_WINDOW(self.minpeers_data, minpeers_hint)
  880. EVT_ENTER_WINDOW(self.displayinterval_data, displayinterval_hint)
  881. EVT_ENTER_WINDOW(self.alloctype_data, alloctype_hint)
  882. EVT_ENTER_WINDOW(self.allocrate_data, allocrate_hint)
  883. EVT_ENTER_WINDOW(self.locking_data, locking_hint)
  884. EVT_ENTER_WINDOW(self.doublecheck_data, doublecheck_hint)
  885. EVT_ENTER_WINDOW(self.maxfilesopen_data, maxfilesopen_hint)
  886. EVT_ENTER_WINDOW(self.maxconnections_data, maxconnections_hint)
  887. EVT_ENTER_WINDOW(self.superseeder_data, superseeder_hint)
  888. EVT_ENTER_WINDOW(self.expirecache_data, expirecache_hint)
  889. self.advancedMenuBox.Show ()
  890. border.Fit(panel)
  891. self.advancedMenuBox.Fit()
  892. except:
  893. self.parent.exception()
  894. def CloseAdvanced(self):
  895. if self.advancedMenuBox is not None:
  896. try:
  897. self.advancedMenuBox.Close()
  898. except wxPyDeadObjectError, e:
  899. self.advancedMenuBox = None
  900. def cryptoMenu(self, event = None):
  901. try:
  902. if not self.cryptoConfig:
  903. for key in ['security', 'auto_kick',
  904. 'crypto_allowed', 'crypto_only', 'crypto_stealth']:
  905. self.cryptoConfig[key] = self.config[key]
  906. if (self.cryptoMenuBox is not None):
  907. try:
  908. self.cryptoMenuBox.Close ()
  909. except wxPyDeadObjectError, e:
  910. self.cryptoMenuBox = None
  911. self.cryptoMenuBox = wxFrame(None, -1, 'BitTornado Encryption/Security Preferences', size = (1,1),
  912. style = wxDEFAULT_FRAME_STYLE|wxFULL_REPAINT_ON_RESIZE)
  913. if (sys.platform == 'win32'):
  914. self.cryptoMenuBox.SetIcon(self.icon)
  915. panel = wxPanel(self.cryptoMenuBox, -1)
  916. # self.panel = panel
  917. def StaticText(text, font = self.FONT, underline = False, color = None, panel = panel):
  918. x = wxStaticText(panel, -1, text, style = wxALIGN_LEFT)
  919. x.SetFont(wxFont(font, wxDEFAULT, wxNORMAL, wxNORMAL, underline))
  920. if color is not None:
  921. x.SetForegroundColour(color)
  922. return x
  923. colsizer = wxFlexGridSizer(cols = 1, hgap = 13, vgap = 13)
  924. self.cryptomode_data=wxRadioBox(panel, -1, 'Encryption',
  925. style = wxRA_SPECIFY_COLS, majorDimension = 1,
  926. choices = [
  927. 'no encryption permitted',
  928. 'encryption enabled (default)',
  929. 'encrypted connections only',
  930. 'full stealth encryption'+
  931. ' (may cause effective firewalling)' ] )
  932. self.cryptomode_data.SetFont(self.default_font)
  933. if self.cryptoConfig['crypto_stealth']:
  934. m = 3
  935. elif self.cryptoConfig['crypto_only']:
  936. m = 2
  937. elif self.cryptoConfig['crypto_allowed']:
  938. m = 1
  939. else:
  940. m = 0
  941. self.cryptomode_data.SetSelection(m)
  942. if not CRYPTO_OK: # no crypto library in place
  943. self.cryptomode_data.Enable(False)
  944. self.security_checkbox = wxCheckBox(panel, -1, "Don't allow multiple connections from the same IP")
  945. self.security_checkbox.SetFont(self.default_font)
  946. self.security_checkbox.SetValue(self.cryptoConfig['security'])
  947. self.autokick_checkbox = wxCheckBox(panel, -1, "Kick/ban clients that send you bad data")
  948. self.autokick_checkbox.SetFont(self.default_font)
  949. self.autokick_checkbox.SetValue(self.cryptoConfig['auto_kick'])
  950. colsizer.Add(self.cryptomode_data)
  951. block2sizer = wxFlexGridSizer(cols = 1, vgap = 2)
  952. block2sizer.Add(self.security_checkbox)
  953. block2sizer.Add(self.autokick_checkbox)
  954. colsizer.Add(block2sizer)
  955. savesizer = wxGridSizer(cols = 3, hgap = 20)
  956. okButton = wxButton(panel, -1, 'OK')
  957. savesizer.Add(okButton, 0, wxALIGN_CENTER)
  958. cancelButton = wxButton(panel, -1, 'Cancel')
  959. savesizer.Add(cancelButton, 0, wxALIGN_CENTER)
  960. defaultsButton = wxButton(panel, -1, 'Revert to Defaults')
  961. savesizer.Add(defaultsButton, 0, wxALIGN_CENTER)
  962. colsizer.Add(savesizer, 1, wxALIGN_CENTER)
  963. resizewarningtext=StaticText('None of these settings will take effect until the next time you start BitTorrent', self.FONT-2)
  964. colsizer.Add(resizewarningtext, 1, wxALIGN_CENTER)
  965. border = wxBoxSizer(wxHORIZONTAL)
  966. border.Add(colsizer, 1, wxEXPAND | wxALL, 4)
  967. panel.SetSizer(border)
  968. panel.SetAutoLayout(True)
  969. def setDefaults(evt, self = self):
  970. try:
  971. if self.defaults['crypto_stealth']:
  972. m = 3
  973. elif self.defaults['crypto_only']:
  974. m = 2
  975. elif self.defaults['crypto_allowed']:
  976. m = 1
  977. else:
  978. m = 0
  979. self.cryptomode_data.SetSelection(m)
  980. self.security_checkbox.SetValue(self.defaults['security'])
  981. self.autokick_checkbox.SetValue(self.defaults['auto_kick'])
  982. except:
  983. self.parent.exception()
  984. def saveConfigs(evt, self = self):
  985. try:
  986. m = self.cryptomode_data.GetSelection()
  987. self.cryptoConfig['crypto_stealth'] = int(m==3)
  988. self.cryptoConfig['crypto_only'] = int(m>=2)
  989. self.cryptoConfig['crypto_allowed'] = int(m>=1)
  990. self.cryptoConfig['security']=int(self.security_checkbox.GetValue())
  991. self.cryptoConfig['auto_kick']=int(self.autokick_checkbox.GetValue())
  992. self.cryptoMenuBox.Close()
  993. except:
  994. self.parent.exception()
  995. def cancelConfigs(evt, self = self):
  996. self.cryptoMenuBox.Close()
  997. EVT_BUTTON(self.cryptoMenuBox, okButton.GetId(), saveConfigs)
  998. EVT_BUTTON(self.cryptoMenuBox, cancelButton.GetId(), cancelConfigs)
  999. EVT_BUTTON(self.cryptoMenuBox, defaultsButton.GetId(), setDefaults)
  1000. self.cryptoMenuBox.Show ()
  1001. border.Fit(panel)
  1002. self.cryptoMenuBox.Fit()
  1003. except:
  1004. self.parent.exception()
  1005. def CloseCrypt(self):
  1006. if self.cryptMenuBox is not None:
  1007. try:
  1008. self.cryptMenuBox.Close()
  1009. except wxPyDeadObjectError, e:
  1010. self.cryptMenuBox = None