instrumentation: add next-share/
[cs-p2p-next.git] / instrumentation / next-share / BaseLib / Tools / cmdlinedl.py
1 # Written by Arno Bakker, George Milescu 
2 # see LICENSE.txt for license information
3 #
4 # Razvan Deaconescu, 2008:
5 #       * corrected problem when running in background
6 #       * added usage and print_version functions
7 #       * uses getopt for command line argument parsing
8
9 import sys
10 import shutil
11 import time
12 import tempfile
13 import random
14 import os
15 import getopt
16 from traceback import print_exc
17
18 from BaseLib.Core.API import *
19 from BaseLib.Core.BitTornado.__init__ import version, report_email
20
21 # Print usage message
22 def usage():
23     print "Usage: python cmdlinedl.py [options] torrentfile_or_url"
24     print "Options:"
25     print "\t--port <port>"
26     print "\t-p <port>\t\tuse <port> to listen for connections"
27     print "\t\t\t\t(default is random value)"
28     print "\t--output <output-dir>"
29     print "\t-o <output-dir>\t\tuse <output-dir> for storing downloaded data"
30     print "\t\t\t\t(default is current directory)"
31     print "\t--version"
32     print "\t-v\t\t\tprint version and exit"
33     print "\t--help"
34     print "\t-h\t\t\tprint this help screen"
35     print
36     print "Report bugs to <" + report_email + ">"
37
38 # Print version information
39 def print_version():
40     print version, "<" + report_email + ">"
41
42 # Print torrent statistics
43 def state_callback(ds):
44     d = ds.get_download()
45 #    print >>sys.stderr,`d.get_def().get_name()`,dlstatus_strings[ds.get_status()],ds.get_progress(),"%",ds.get_error(),"up",ds.get_current_speed(UPLOAD),"down",ds.get_current_speed(DOWNLOAD)
46     print >>sys.stderr, '%s %s %5.2f%% %s up %8.2fKB/s down %8.2fKB/s' % \
47             (d.get_def().get_name(), \
48             dlstatus_strings[ds.get_status()], \
49             ds.get_progress() * 100, \
50             ds.get_error(), \
51             ds.get_current_speed(UPLOAD), \
52             ds.get_current_speed(DOWNLOAD))
53
54     return (1.0, False)
55
56 def main():
57     try:
58         # opts = a list of (option, value) pairs
59         # args = the list of program arguments left after the option list was stripped
60         opts, args = getopt.getopt(sys.argv[1:], "hvo:p:", ["help", "version", "output-dir", "port"])
61     except getopt.GetoptError, err:
62         print str(err)
63         usage()
64         sys.exit(2)
65
66     # init to default values
67     output_dir = os.getcwd()
68     port = random.randint(10000, 65535)
69
70     for o, a in opts:
71         if o in ("-h", "--help"):
72             usage()
73             sys.exit(0)
74         elif o in ("-o", "--output-dir"):
75             output_dir = a
76         elif o in ("-p", "--port"):
77             port = int(a)
78         elif o in ("-v", "--version"):
79             print_version()
80             sys.exit(0)
81         else:
82             assert False, "unhandled option"
83
84     if len(args) == 0:
85         usage()
86         sys.exit(2)
87
88     if len(args) > 1:
89         print "Too many arguments"
90         usage()
91         sys.exit(2)
92     torrentfile_or_url = args[0]
93
94     print "Press Ctrl-C to stop the download"
95
96     # setup session
97     sscfg = SessionStartupConfig()
98     statedir = tempfile.mkdtemp()
99     sscfg.set_state_dir(statedir)
100     sscfg.set_listen_port(port)
101     sscfg.set_megacache(False)
102     sscfg.set_overlay(False)
103     sscfg.set_dialback(True)
104     sscfg.set_internal_tracker(False)
105     
106     s = Session(sscfg)
107
108     # setup and start download
109     dscfg = DownloadStartupConfig()
110     dscfg.set_dest_dir(output_dir);
111     #dscfg.set_max_speed( UPLOAD, 10 )
112
113     if torrentfile_or_url.startswith("http") or torrentfile_or_url.startswith(P2PURL_SCHEME):
114         tdef = TorrentDef.load_from_url(torrentfile_or_url)
115     else: 
116         tdef = TorrentDef.load(torrentfile_or_url)
117     if tdef.get_live():
118         raise ValueError("cmdlinedl does not support live torrents")
119         
120     d = s.start_download(tdef, dscfg)
121     d.set_state_callback(state_callback, getpeerlist=False)
122    
123     #
124     # loop while waiting for CTRL-C (or any other signal/interrupt)
125     #
126     # - cannot use sys.stdin.read() - it means busy waiting when running
127     #   the process in background
128     # - cannot use condition variable - that don't listen to KeyboardInterrupt
129     #
130     # time.sleep(sys.maxint) has "issues" on 64bit architectures; divide it
131     # by some value (2048) to solve problem
132     #
133     try:
134         while True:
135             time.sleep(sys.maxint/2048)
136     except:
137         print_exc()
138
139     s.shutdown()
140     time.sleep(3)
141     shutil.rmtree(statedir)
142
143
144 if __name__ == "__main__":
145     main()