tftornado.py 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  1. #!/usr/bin/env python
  2. ################################################################################
  3. # $Id: tftornado.py 2459 2007-01-31 16:54:50Z b4rt $
  4. # $Revision: 2459 $
  5. # $Date: 2007-01-31 10:54:50 -0600 (Wed, 31 Jan 2007) $
  6. ################################################################################
  7. #
  8. # Written by Bram Cohen
  9. # see LICENSE.txt for license information
  10. #
  11. ################################################################################
  12. #
  13. # tftornado.py - use BitTornado with torrentflux-b4rt
  14. # http://tf-b4rt.berlios.de/
  15. #
  16. ################################################################################
  17. from BitTornado import PSYCO
  18. if PSYCO.psyco:
  19. try:
  20. import psyco
  21. assert psyco.__version__ >= 0x010100f0
  22. psyco.full()
  23. except:
  24. pass
  25. from BitTornado.download_bt1 import BT1Download, defaults, parse_params, get_usage, get_response
  26. from BitTornado.RawServer import RawServer, UPnP_ERROR
  27. from random import seed
  28. from socket import error as socketerror
  29. from BitTornado.bencode import bencode
  30. from BitTornado.natpunch import UPnP_test
  31. from threading import Event
  32. from os.path import abspath, isfile
  33. from os import getpid, remove
  34. from sys import argv, stdout
  35. import sys
  36. from sha import sha
  37. from time import strftime
  38. from BitTornado.clock import clock
  39. from BitTornado import createPeerID, version
  40. assert sys.version >= '2', "Install Python 2.0 or greater"
  41. try:
  42. True
  43. except:
  44. True = 1
  45. False = 0
  46. PROFILER = False
  47. if __debug__: LOGFILE=open(argv[3]+"."+str(getpid()),"w")
  48. def traceMsg(msg):
  49. try:
  50. if __debug__:
  51. LOGFILE.write(msg + "\n")
  52. LOGFILE.flush()
  53. except:
  54. return
  55. #------------------------------------------------------------------------------#
  56. # tfb static methods #
  57. #------------------------------------------------------------------------------#
  58. def fmttime(n):
  59. """ fmttime """
  60. # short format :
  61. return fmttimeshort(n)
  62. # long format :
  63. # return fmttimelong(n)
  64. def fmttimeshort(n):
  65. """ fmttimeshort """
  66. if n == 0:
  67. return 'complete!'
  68. try:
  69. n = int(n)
  70. assert n >= 0 and n < 5184000 # 60 days
  71. except:
  72. return '<unknown>'
  73. m, s = divmod(n, 60)
  74. h, m = divmod(m, 60)
  75. d, h = divmod(h, 24)
  76. if d >= 7:
  77. return '-'
  78. elif d > 0:
  79. return '%dd %02d:%02d:%02d' % (d, h, m, s)
  80. else:
  81. return '%02d:%02d:%02d' % (h, m, s)
  82. def fmttimelong(n):
  83. """ fmttimelong """
  84. if n == 0:
  85. return 'complete!'
  86. try:
  87. n = int(n)
  88. assert n >= 0 and n < 5184000 # 60 days
  89. except:
  90. return '<unknown>'
  91. m, s = divmod(n, 60)
  92. h, m = divmod(m, 60)
  93. d, h = divmod(h, 24)
  94. y, d = divmod(d, 365)
  95. dec, y = divmod(y, 10)
  96. cent, dec = divmod(dec, 10)
  97. if cent > 0:
  98. return '%dcent %ddec %dy %dd %02d:%02d:%02d' % (cent, dec, y, d, h, m, s)
  99. elif dec > 0:
  100. return '%ddec %dy %dd %02d:%02d:%02d' % (dec, y, d, h, m, s)
  101. elif y > 0:
  102. return '%dy %dd %02d:%02d:%02d' % (y, d, h, m, s)
  103. elif d > 0:
  104. return '%dd %02d:%02d:%02d' % (d, h, m, s)
  105. else:
  106. return '%02d:%02d:%02d' % (h, m, s)
  107. def transferLog(message, ts):
  108. """ transferLog """
  109. try:
  110. FILE = open(transferLogFile,"a+")
  111. if not ts:
  112. FILE.write(message)
  113. else:
  114. FILE.write(strftime('[%Y/%m/%d - %H:%M:%S]') + " " + message)
  115. FILE.flush()
  116. FILE.close()
  117. except Exception, e:
  118. sys.stderr.write("Failed to write log-file : " + transferLogFile + "\n")
  119. #------------------------------------------------------------------------------#
  120. # HeadlessDisplayer #
  121. #------------------------------------------------------------------------------#
  122. class HeadlessDisplayer:
  123. def __init__(self):
  124. self.done = False
  125. self.file = ''
  126. self.running = '1'
  127. self.percentDone = ''
  128. self.timeEst = 'Connecting to Peers'
  129. self.downloadTo = ''
  130. self.downRate = ''
  131. self.upRate = ''
  132. self.shareRating = ''
  133. self.percentShare = ''
  134. self.upTotal = 0
  135. self.downTotal = 0
  136. self.seedStatus = ''
  137. self.peerStatus = ''
  138. self.seeds = ''
  139. self.peers = ''
  140. self.errors = []
  141. self.last_update_time = -1
  142. self.autoShutdown = 'False'
  143. self.user = 'unknown'
  144. self.size = 0
  145. self.shareKill = '100'
  146. self.distcopy = ''
  147. self.stoppedAt = ''
  148. self.dow = None
  149. self.displayCounter = 0
  150. def finished(self):
  151. if __debug__: traceMsg('finished - begin')
  152. self.done = True
  153. self.percentDone = '100'
  154. self.timeEst = 'Download Succeeded!'
  155. self.downRate = ''
  156. self.display()
  157. if self.autoShutdown == 'True':
  158. self.upRate = ''
  159. if self.stoppedAt == '':
  160. self.writeStatus()
  161. if __debug__: traceMsg('finished - end - raising ki')
  162. raise KeyboardInterrupt
  163. if __debug__: traceMsg('finished - end')
  164. def failed(self):
  165. if __debug__: traceMsg('failed - begin')
  166. self.done = True
  167. self.percentDone = '0'
  168. self.timeEst = 'Download Failed!'
  169. self.downRate = ''
  170. self.display()
  171. if self.autoShutdown == 'True':
  172. self.upRate = ''
  173. if self.stoppedAt == '':
  174. self.writeStatus()
  175. if __debug__:traceMsg('failed - end - raising ki')
  176. raise KeyboardInterrupt
  177. if __debug__: traceMsg('failed - end')
  178. def error(self, errormsg):
  179. self.errors.append(errormsg)
  180. # log error
  181. transferLog("error: " + errormsg + "\n", True)
  182. def chooseFile(self, default, size, saveas, dir):
  183. self.file = '%s (%.1f MB)' % (default, float(size) / (1 << 20))
  184. self.size = size
  185. if saveas != '':
  186. default = saveas
  187. self.downloadTo = abspath(default)
  188. return default
  189. def newpath(self, path):
  190. self.downloadTo = path
  191. def scrub_errs(self):
  192. new_errors = []
  193. try:
  194. if self.errors:
  195. last_errMsg = ''
  196. errCount = 0
  197. for err in self.errors:
  198. try:
  199. if last_errMsg == '':
  200. last_errMsg = err
  201. elif last_errMsg == err:
  202. errCount += 1
  203. elif last_errMsg != err:
  204. if errCount > 0:
  205. new_errors.append(last_errMsg + ' (x' + str(errCount+1) + ')')
  206. else:
  207. new_errors.append(last_errMsg)
  208. errCount = 0
  209. last_errMsg = err
  210. except:
  211. if __debug__: traceMsg('scrub_errs - Failed scrub')
  212. pass
  213. try:
  214. if len(new_errors) > 0:
  215. if last_errMsg != new_errors[len(new_errors)-1]:
  216. if errCount > 0:
  217. new_errors.append(last_errMsg + ' (x' + str(errCount+1) + ')')
  218. else:
  219. new_errors.append(last_errMsg)
  220. else:
  221. if errCount > 0:
  222. new_errors.append(last_errMsg + ' (x' + str(errCount+1) + ')')
  223. else:
  224. new_errors.append(last_errMsg)
  225. except:
  226. if __debug__: traceMsg('scrub_errs - Failed during scrub last Msg ')
  227. pass
  228. if len(self.errors) > 100:
  229. while len(self.errors) > 100 :
  230. del self.errors[0:99]
  231. self.errors = new_errors
  232. except:
  233. if __debug__: traceMsg('scrub_errs - Failed during scrub Errors')
  234. pass
  235. return new_errors
  236. def display(self, dpflag = Event(), fractionDone = None, timeEst = None,
  237. downRate = None, upRate = None, activity = None,
  238. statistics = None, **kws):
  239. if self.last_update_time + 0.1 > clock() and fractionDone not in (0.0, 1.0) and activity is not None:
  240. return
  241. self.last_update_time = clock()
  242. if fractionDone is not None:
  243. self.percentDone = str(float(int(fractionDone * 1000)) / 10)
  244. if timeEst is not None:
  245. self.timeEst = fmttime(timeEst)
  246. if activity is not None and not self.done:
  247. self.timeEst = activity
  248. if downRate is not None:
  249. self.downRate = '%.1f kB/s' % (float(downRate) / (1 << 10))
  250. if upRate is not None:
  251. self.upRate = '%.1f kB/s' % (float(upRate) / (1 << 10))
  252. if statistics is not None:
  253. if (statistics.shareRating < 0) or (statistics.shareRating > 100):
  254. self.shareRating = 'oo (%.1f MB up / %.1f MB down)' % (float(statistics.upTotal) / (1<<20), float(statistics.downTotal) / (1<<20))
  255. self.downTotal = statistics.downTotal
  256. self.upTotal = statistics.upTotal
  257. else:
  258. self.shareRating = '%.3f (%.1f MB up / %.1f MB down)' % (statistics.shareRating, float(statistics.upTotal) / (1<<20), float(statistics.downTotal) / (1<<20))
  259. self.downTotal = statistics.downTotal
  260. self.upTotal = statistics.upTotal
  261. if not self.done:
  262. self.seedStatus = '%d seen now, plus %.3f distributed copies' % (statistics.numSeeds,0.001*int(1000*statistics.numCopies))
  263. self.seeds = (str(statistics.numSeeds))
  264. else:
  265. self.seedStatus = '%d seen recently, plus %.3f distributed copies' % (statistics.numOldSeeds,0.001*int(1000*statistics.numCopies))
  266. self.seeds = (str(statistics.numOldSeeds))
  267. self.peers = '%d' % (statistics.numPeers)
  268. self.distcopy = '%.3f' % (0.001*int(1000*statistics.numCopies))
  269. self.peerStatus = '%d seen now, %.1f%% done at %.1f kB/s' % (statistics.numPeers,statistics.percentDone,float(statistics.torrentRate) / (1 << 10))
  270. dpflag.set()
  271. # process command-stack
  272. die = self.processCommandStack()
  273. # shutdown if requested
  274. if die:
  275. self.execShutdown()
  276. return;
  277. # ratio- + limit- checks / shutdown / stat
  278. if self.stoppedAt == '':
  279. die = False
  280. downRate = self.downTotal
  281. die = False
  282. if downRate == 0 and self.upTotal > 0:
  283. downRate = self.size
  284. if self.done:
  285. self.percentDone = '100'
  286. downRate = self.size
  287. if self.autoShutdown == 'True':
  288. transferLog("die-when-done set, setting shutdown-flag...\n", True)
  289. die = True
  290. if self.upTotal > 0:
  291. self.percentShare = '%.1f' % ((float(self.upTotal)/float(downRate))*100)
  292. else:
  293. self.percentShare = '0.0'
  294. if self.done and self.percentShare is not '' and self.autoShutdown == 'False':
  295. if (float(self.percentShare) >= float(self.shareKill)) and (self.shareKill != '0'):
  296. transferLog("seed-limit "+str(self.shareKill)+" reached, setting shutdown-flag...\n", True)
  297. die = True
  298. self.upRate = ''
  299. elif (not self.done) and (self.timeEst == 'complete!') and (self.percentDone == '100.0'):
  300. if (float(self.percentShare) >= float(self.shareKill)) and (self.shareKill != '0'):
  301. transferLog("seed-limit "+str(self.shareKill)+" reached, setting shutdown-flag...\n", True)
  302. die = True
  303. self.upRate = ''
  304. # shutdown / write stat-file
  305. if die:
  306. self.execShutdown()
  307. else:
  308. # write every 5 secs
  309. if self.displayCounter < 5:
  310. self.displayCounter += 1
  311. else:
  312. self.displayCounter = 0
  313. # write stat-file
  314. self.writeStatus()
  315. def processCommandStack(self):
  316. """ processCommandStack """
  317. if isfile(transferCommandFile):
  318. # process file
  319. transferLog("Processing command-file " + transferCommandFile + "...\n", True)
  320. try:
  321. # read file to mem
  322. f = open(transferCommandFile, 'r')
  323. commands = f.readlines()
  324. f.close
  325. # remove file
  326. try:
  327. remove(transferCommandFile)
  328. except:
  329. transferLog("Failed to remove command-file : " + transferCommandFile + "\n", True)
  330. pass
  331. # exec commands
  332. if len(commands) > 0:
  333. for command in commands:
  334. command = command.replace("\n", "")
  335. if len(command) > 0:
  336. # exec, early out when reading a quit-command
  337. if self.execCommand(command):
  338. return True
  339. else:
  340. transferLog("No commands found.\n", True)
  341. except:
  342. transferLog("Failed to read command-file : " + transferCommandFile + "\n", True)
  343. pass
  344. return False
  345. def execCommand(self, command):
  346. """ execCommand """
  347. opCode = command[0]
  348. # q
  349. if opCode == 'q':
  350. transferLog("command: stop-request, setting shutdown-flag...\n", True)
  351. return True
  352. # u
  353. elif opCode == 'u':
  354. if len(command) < 2:
  355. transferLog("invalid rate.\n", True)
  356. return False
  357. rateNew = command[1:]
  358. transferLog("command: setting upload-rate to " + rateNew + "...\n", True)
  359. self.dow.setUploadRate(int(rateNew))
  360. return False
  361. # d
  362. elif opCode == 'd':
  363. if len(command) < 2:
  364. transferLog("invalid rate.\n", True)
  365. return False
  366. rateNew = command[1:]
  367. transferLog("command: setting download-rate to " + rateNew + "...\n", True)
  368. self.dow.setDownloadRate(int(rateNew))
  369. return False
  370. # r
  371. elif opCode == 'r':
  372. if len(command) < 2:
  373. transferLog("invalid runtime-code.\n", True)
  374. return False
  375. runtimeNew = command[1]
  376. rt = ''
  377. if runtimeNew == '0':
  378. rt = 'False'
  379. elif runtimeNew == '1':
  380. rt = 'True'
  381. else:
  382. transferLog("runtime-code unknown: " + runtimeNew + "\n", True)
  383. return False
  384. transferLog("command: setting die-when-done to " + rt + "...\n", True)
  385. self.autoShutdown = rt
  386. return False
  387. # s
  388. elif opCode == 's':
  389. if len(command) < 2:
  390. transferLog("invalid sharekill.\n", True)
  391. return False
  392. sharekillNew = command[1:]
  393. transferLog("command: setting sharekill to " + sharekillNew + "...\n", True)
  394. self.shareKill = sharekillNew
  395. return False
  396. # default
  397. else:
  398. transferLog("op-code unknown: " + opCode + "\n", True)
  399. return False
  400. def execShutdown(self):
  401. """ execShutdown """
  402. transferLog("initializing shutdown...\n", True)
  403. # write stat
  404. if self.stoppedAt == '':
  405. if self.percentDone == '100':
  406. self.stoppedAt = '100'
  407. else:
  408. self.stoppedAt = str((float(self.percentDone)+100)*-1)
  409. self.timeEst = 'Torrent Stopped'
  410. self.running = '0'
  411. self.upRate = ''
  412. self.downRate = ''
  413. self.percentDone = self.stoppedAt
  414. self.writeStatus()
  415. # quit
  416. transferLog("tornado shutting down...\n", True)
  417. raise KeyboardInterrupt
  418. def writeStatus(self):
  419. """ writeStatus """
  420. lcount = 0
  421. while 1:
  422. lcount += 1
  423. try:
  424. f = open(transferStatFile, 'w')
  425. f.write(self.running + '\n')
  426. f.write(self.percentDone + '\n')
  427. f.write(self.timeEst + '\n')
  428. f.write(self.downRate + '\n')
  429. f.write(self.upRate + '\n')
  430. f.write(self.user + '\n')
  431. f.write(self.seeds + '+' + self.distcopy + '\n')
  432. f.write(self.peers + '\n')
  433. f.write(self.percentShare + '\n')
  434. f.write(self.shareKill + '\n')
  435. f.write(str(self.upTotal) + '\n')
  436. f.write(str(self.downTotal) + '\n')
  437. f.write(str(self.size))
  438. f.flush()
  439. f.close()
  440. break
  441. except:
  442. transferLog("Failed to open stat-file for writing : " + transferStatFile + "\n", True)
  443. if lcount > 30:
  444. break
  445. pass
  446. #------------------------------------------------------------------------------#
  447. # run #
  448. #------------------------------------------------------------------------------#
  449. def run(autoDie, shareKill, userName, params):
  450. try:
  451. h = HeadlessDisplayer()
  452. h.autoShutdown = autoDie
  453. h.shareKill = shareKill
  454. h.user = userName
  455. while 1:
  456. try:
  457. config = parse_params(params)
  458. except ValueError, e:
  459. print 'error: ' + str(e) + '\nrun with no args for parameter explanations'
  460. break
  461. if not config:
  462. print get_usage()
  463. break
  464. # log what we are starting up
  465. transferLog("tornado starting up :\n", True)
  466. transferLog(" - torrentfile : " + config['responsefile'] + "\n", True)
  467. transferLog(" - userName : " + userName + "\n", True)
  468. transferLog(" - transferStatFile : " + transferStatFile + "\n", True)
  469. transferLog(" - transferCommandFile : " + transferCommandFile + "\n", True)
  470. transferLog(" - transferLogFile : " + transferLogFile + "\n", True)
  471. transferLog(" - transferPidFile : " + transferPidFile + "\n", True)
  472. transferLog(" - autoDie : " + autoDie + "\n", True)
  473. transferLog(" - shareKill : " + shareKill + "\n", True)
  474. transferLog(" - minport : " + str(config['minport']) + "\n", True)
  475. transferLog(" - maxport : " + str(config['maxport']) + "\n", True)
  476. transferLog(" - max_upload_rate : " + str(config['max_upload_rate']) + "\n", True)
  477. transferLog(" - max_download_rate : " + str(config['max_download_rate']) + "\n", True)
  478. transferLog(" - min_uploads : " + str(config['min_uploads']) + "\n", True)
  479. transferLog(" - max_uploads : " + str(config['max_uploads']) + "\n", True)
  480. transferLog(" - min_peers : " + str(config['min_peers']) + "\n", True)
  481. transferLog(" - max_initiate : " + str(config['max_initiate']) + "\n", True)
  482. transferLog(" - max_connections : " + str(config['max_connections']) + "\n", True)
  483. transferLog(" - super_seeder : " + str(config['super_seeder']) + "\n", True)
  484. transferLog(" - security : " + str(config['security']) + "\n", True)
  485. transferLog(" - auto_kick : " + str(config['auto_kick']) + "\n", True)
  486. if 'crypto_allowed' in config:
  487. transferLog(" - crypto_allowed : " + str(config['crypto_allowed']) + "\n", True)
  488. if 'crypto_only' in config:
  489. transferLog(" - crypto_only : " + str(config['crypto_only']) + "\n", True)
  490. if 'crypto_stealth' in config:
  491. transferLog(" - crypto_stealth : " + str(config['crypto_stealth']) + "\n", True)
  492. transferLog(" - priority : " + str(config['priority']) + "\n", True)
  493. transferLog(" - alloc_type : " + str(config['alloc_type']) + "\n", True)
  494. transferLog(" - alloc_rate : " + str(config['alloc_rate']) + "\n", True)
  495. transferLog(" - buffer_reads : " + str(config['buffer_reads']) + "\n", True)
  496. transferLog(" - write_buffer_size : " + str(config['write_buffer_size']) + "\n", True)
  497. transferLog(" - check_hashes : " + str(config['check_hashes']) + "\n", True)
  498. transferLog(" - max_files_open : " + str(config['max_files_open']) + "\n", True)
  499. transferLog(" - upnp_nat_access : " + str(config['upnp_nat_access']) + "\n", True)
  500. # remove command-file if exists
  501. if isfile(transferCommandFile):
  502. try:
  503. transferLog("removing command-file " + transferCommandFile + "...\n", True)
  504. remove(transferCommandFile)
  505. except:
  506. pass
  507. # write pid-file
  508. currentPid = (str(getpid())).strip()
  509. transferLog("writing pid-file : " + transferPidFile + " (" + currentPid + ")\n", True)
  510. try:
  511. pidFile = open(transferPidFile, 'w')
  512. pidFile.write(currentPid + "\n")
  513. pidFile.flush()
  514. pidFile.close()
  515. except Exception, e:
  516. transferLog("Failed to write pid-file, shutting down : " + transferPidFile + " (" + currentPid + ")" + "\n", True)
  517. break
  518. myid = createPeerID()
  519. seed(myid)
  520. doneflag = Event()
  521. def disp_exception(text):
  522. print text
  523. rawserver = RawServer(doneflag, config['timeout_check_interval'],
  524. config['timeout'], ipv6_enable = config['ipv6_enabled'],
  525. failfunc = h.failed, errorfunc = disp_exception)
  526. upnp_type = UPnP_test(config['upnp_nat_access'])
  527. while True:
  528. try:
  529. listen_port = rawserver.find_and_bind(config['minport'], config['maxport'],
  530. config['bind'], ipv6_socket_style = config['ipv6_binds_v4'],
  531. upnp = upnp_type, randomizer = config['random_port'])
  532. break
  533. except socketerror, e:
  534. if upnp_type and e == UPnP_ERROR:
  535. print 'WARNING: COULD NOT FORWARD VIA UPnP'
  536. upnp_type = 0
  537. continue
  538. print "error: Couldn't listen - " + str(e)
  539. h.failed()
  540. return
  541. response = get_response(config['responsefile'], config['url'], h.error)
  542. if not response:
  543. break
  544. infohash = sha(bencode(response['info'])).digest()
  545. h.dow = BT1Download(h.display, h.finished, h.error, disp_exception, doneflag,
  546. config, response, infohash, myid, rawserver, listen_port)
  547. if not h.dow.saveAs(h.chooseFile, h.newpath):
  548. break
  549. if not h.dow.initFiles(old_style = True):
  550. break
  551. if not h.dow.startEngine():
  552. h.dow.shutdown()
  553. break
  554. h.dow.startRerequester()
  555. h.dow.autoStats()
  556. if not h.dow.am_I_finished():
  557. h.display(activity = 'connecting to peers')
  558. # log that we are done with startup
  559. transferLog("tornado up and running.\n", True)
  560. # listen forever
  561. rawserver.listen_forever(h.dow.getPortHandler())
  562. # shutdown
  563. h.display(activity = 'shutting down')
  564. h.dow.shutdown()
  565. break
  566. try:
  567. rawserver.shutdown()
  568. except:
  569. pass
  570. if not h.done:
  571. h.failed()
  572. finally:
  573. transferLog("removing pid-file : " + transferPidFile + "\n", True)
  574. try:
  575. remove(transferPidFile)
  576. except:
  577. transferLog("Failed to remove pid-file : " + transferPidFile + "\n", True)
  578. pass
  579. #------------------------------------------------------------------------------#
  580. # __main__ #
  581. #------------------------------------------------------------------------------#
  582. if __name__ == '__main__':
  583. if argv[1:] == ['--version']:
  584. print version
  585. sys.exit(0)
  586. # check argv-length
  587. if len(argv) < 5:
  588. print "Error : missing arguments, exiting. \n"
  589. sys.exit(0)
  590. # get/set stat-file
  591. transferStatFile = argv[4] + ".stat"
  592. # get/set cmd-file
  593. transferCommandFile = argv[4] + ".cmd"
  594. # get/set log-file
  595. transferLogFile = argv[4] + ".log"
  596. # get/set pid-file
  597. transferPidFile = argv[4] + ".pid"
  598. if PROFILER:
  599. import profile, pstats
  600. p = profile.Profile()
  601. p.runcall(run, argv[1],argv[2],argv[3],argv[5:])
  602. log = open('profile_data.'+strftime('%y%m%d%H%M%S')+'.txt','a')
  603. normalstdout = sys.stdout
  604. sys.stdout = log
  605. # pstats.Stats(p).strip_dirs().sort_stats('cumulative').print_stats()
  606. pstats.Stats(p).strip_dirs().sort_stats('time').print_stats()
  607. sys.stdout = normalstdout
  608. else:
  609. run(argv[1],argv[2],argv[3],argv[5:])
  610. # log exit
  611. transferLog("tornado exit.\n", True)