#!/usr/bin/env python # Adam's BitTorrent client # This is evil, and probably shouldn't be used. # Based upon btdownloadheadless.py: # Written by Bram Cohen # see LICENSE.txt for license information MAX_DOWN = 3 MAX_INBOUND = 4 MAX_UP = 1 RATE_UP = 4 INTERVAL = 300 DEST_DIR = "/home/azz/Incoming" import sys, threading, os, signal sys.path = ["/home/azz/src/BitTorrent-3.1-azz"] + sys.path from BitTorrent.download import download assert sys.version >= '2', "Install Python 2.0 or greater" if os.environ.has_key("http_proxy"): del os.environ["http_proxy"] def format_time(n): if n == -1: return '??h??m??' n = int(n) h, r = divmod(n, 60 * 60) m, sec = divmod(r, 60) if h > 1000000: return '++:++:++' return '%02dh%02dm%02d' % (h, m, sec) class HeadlessDisplayer: def __init__(self, cols): self.cols = cols self.done = 0 self.filename = "" self.filesize = 0 self.dest = "" self.errors = "none" self.activity = "none" self.percentDone = '' self.timeEst = '' self.downRate = None self.upRate = None def terminate(self, code): os.kill(os.getpid(), signal.SIGINT) def finished(self): self.done = 1 print "\nDownload complete." self.percentDone = '100' self.activity = "Download complete" self.downRate = None self.display() #self.terminate(0) def failed(self): self.done = 1 print "\nDownload failed." self.percentDone = '0' self.activity = "Download failed" self.downRate = None self.display() self.terminate(1) def error(self, errormsg): # FIXME timestamp print "\nError: " + errormsg self.display() def display(self, fractionDone = None, timeEst = None, downRate = None, upRate = None, activity = None): if fractionDone is not None: self.percentDone = str(float(int(fractionDone * 1000)) / 10) if timeEst is not None: self.timeEst = format_time(timeEst) if activity is not None: self.activity = activity if downRate is not None: self.downRate = '%.1fKiB/s' % (float(downRate) / (1 << 10)) if upRate is not None: self.upRate = '%.1fKiB/s' % (float(upRate) / (1 << 10)) if activity is None and timeEst is not None: action = "downloading" else: action = self.activity if fractionDone is not None: action += "; " + self.percentDone + "% done" if timeEst is not None: action += ", " + self.timeEst + " remaining" if self.downRate is not None: action += ", " + self.downRate + " down" if self.upRate is not None: action += ", " + self.upRate + " up" s = (action + " " * self.cols)[:self.cols - 1] sys.stdout.write("\r" + s) sys.stdout.flush() def chooseFile(self, default, size, saveas, dir): self.filename = os.path.basename(os.path.abspath(default)) self.filesize = size print "\nSource: %s (%.1fMiB)" % (self.filename, float(self.filesize) / (1 << 20)) self.dest = os.path.join(DEST_DIR, self.filename) if saveas != '': self.dest = saveas return self.dest def run(params): try: import curses curses.initscr() cols = curses.COLS curses.endwin() except: cols = 80 h = HeadlessDisplayer(cols) download(params, h.chooseFile, h.display, h.finished, h.error, threading.Event(), cols) if not h.done: h.failed() if __name__ == '__main__': if len(sys.argv) == 2 and sys.argv[1][:2] != "--": if sys.argv[0].endswith("btfast"): args = ["--max_inbound", "20", "--max_upload_rate", "15"] else: args = ["--max_initiate", str(MAX_DOWN), "--min_peers", str(MAX_DOWN), "--max_uploads", str(MAX_UP), "--max_inbound", str(MAX_INBOUND), "--max_upload_rate", str(RATE_UP), "--rerequest_interval", str(INTERVAL)] if sys.argv[1][:5] == "http:": args += ["--url", sys.argv[1].replace(" ", "%20")] else: args += ["--responsefile", sys.argv[1]] run(args) else: run(sys.argv[1:])