1 # Written by Arno Bakker, George Milescu
2 # see LICENSE.txt for license information
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
9 # * Added arguments for proxymode
18 from traceback import print_exc
20 from BaseLib.Core.API import *
21 from BaseLib.Core.BitTornado.__init__ import version, report_email
22 from BaseLib.Core.Utilities.utilities import show_permid_short
23 from M2Crypto import EC
27 print "Usage: python proxy-cmdlinedl.py [options] torrent_file"
29 print "\t--port <port>"
30 print "\t-p <port>\t\tuse <port> to listen for connections"
31 print "\t\t\t\t(default is random value)"
32 print "\t--output <output-dir>"
33 print "\t-o <output-dir>\t\tuse <output-dir> for storing downloaded data"
34 print "\t\t\t\t(default is current directory)"
35 print "\t--state-dir <state-dir>"
36 print "\t\t\t\tuse <state-dir> for storing session data"
37 print "\t\t\t\t(default is /tmp/tmp-tribler)"
38 print "\t--proxymode <proxy-mode>"
39 print "\t\t\t\t[DEVEL] use <proxy-mode> to specify how the client behaves"
40 print "\t\t\t\t * proxy-mode = off: no proxy is being used (the client is either an helper, or it does not start use proxy connections)"
41 print "\t\t\t\t * proxy-mode = private: only proxy connections are being used"
42 print "\t\t\t\t * proxy-mode = speed: both proxy and direct connections are being used"
43 print "\t\t\t\t(default is off)"
44 print "\t--proxyservice <proxy-service>"
45 print "\t\t\t\t[DEVEL] use <proxy-mode> to specify how the client behaves"
46 print "\t\t\t\t * proxy-service = off: the current node can not be used as a proxy by other nodes"
47 print "\t\t\t\t * proxy-service = on: the current node can be used as a proxy by other nodes"
48 print "\t\t\t\t(default is off)"
49 print "\t--helpers <helpers>"
50 print "\t\t\t\t[DEVEL] use <helpers> to specify maximum number of helpers used or a torrent"
51 print "\t\t\t\t(default is 5)"
52 print "\t--test-mode <test-mode>"
53 print "\t\t\t\t[DEVEL] use <test-mode> to specify if the client runs as part of a test"
54 print "\t\t\t\t * test-mode = off: the client is not run as part of a test"
55 print "\t\t\t\t * test-mode = coord: the client is part of a test, as a coordinator"
56 print "\t\t\t\t * test-mode = helper: the client is part of a test, as a helper"
57 print "\t\t\t\t(default is off)"
58 print "\t--no-download"
59 print "\t\t\t\t[DEVEL] Don't download anything, just stay and wait"
60 print "\t\t\t\t(if not present the default to download the torrent data)"
62 print "\t-v\t\t\tprint version and exit"
64 print "\t-h\t\t\tprint this help screen"
66 print "Report bugs to <" + report_email + ">"
68 # Print version information
70 print version, "<" + report_email + ">"
72 # Print torrent statistics
73 def state_callback(ds):
75 # 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)
76 print >>sys.stderr, '%s %s %5.2f%% %s up %8.2fKB/s down %8.2fKB/s' % \
77 (d.get_def().get_name(), \
78 dlstatus_strings[ds.get_status()], \
79 ds.get_progress() * 100, \
81 ds.get_current_speed(UPLOAD), \
82 ds.get_current_speed(DOWNLOAD))
88 # opts = a list of (option, value) pairs
89 # args = the list of program arguments left after the option list was stripped
90 opts, args = getopt.getopt(sys.argv[1:], "hvo:p:", ["help", "version", "output-dir=", "port=", "proxymode=", "proxyservice=", "helpers=", "test-mode=", "state-dir=", "no-download"])
91 except getopt.GetoptError, err:
96 # init the default values
97 output_dir = os.getcwd()
98 port = random.randint(10000, 65535)
100 proxy_mode = PROXY_MODE_OFF
101 proxy_service = PROXYSERVICE_OFF
103 test_mode="off" # off, coord, helper
105 statedir = "/tmp/tmp-tribler"
107 # get values from arguments
108 for option, value in opts:
109 if option in ("-h", "--help"):
112 elif option in ("-o", "--output-dir"):
114 elif option in ("--state-dir"):
116 elif option in ("-p", "--port"):
118 elif option in ("--proxymode"):
120 proxy_mode = PROXY_MODE_OFF
121 elif value == "private":
122 proxy_mode = PROXY_MODE_PRIVATE
123 elif value == "speed":
124 proxy_mode = PROXY_MODE_SPEED
126 proxy_mode = PROXY_MODE_OFF
127 elif option in ("--proxyservice"):
129 proxy_service = PROXYSERVICE_OFF
131 proxy_service = PROXYSERVICE_ON
133 proxy_service = PROXYSERVICE_OFF
134 elif option in ("--helpers"):
136 elif option in ("--test-mode"):
138 elif option in ("-v", "--version"):
141 elif option in ("--no-download"):
144 assert False, "unhandled option"
146 # arg should have only one element left: the torrent file name
148 # if no_download is false (the client has to download torrent data), check number of arguments
149 if (no_download == False) and len(args) == 0:
153 print "Too many arguments"
158 # is no_download is false (the client has to download torrent data), get torrent file name
159 if (no_download == False):
160 torrent_file = args[0]
162 print "Press Ctrl-C to stop the download"
165 session_startup_config = SessionStartupConfig()
166 #statedir = tempfile.mkdtemp()
167 # ProxyDevel - set custom state dir
168 session_startup_config.set_state_dir(statedir)
169 session_startup_config.set_download_help_dir(os.path.join(statedir,"help_dir"))
170 session_startup_config.set_listen_port(port)
171 session_startup_config.set_megacache(True)
172 session_startup_config.set_overlay(True)
173 session_startup_config.set_dialback(True)
174 session_startup_config.set_internal_tracker(False)
175 # ProxyDevel - turn DHT off
176 session_startup_config.set_mainline_dht(False)
177 # ProxyDevel - turn buddycast off
178 session_startup_config.set_buddycast(False)
179 # ProxyDevel - set new core API values
180 session_startup_config.set_proxyservice_status(proxy_service)
182 s = Session(session_startup_config)
185 print "*** My Permid = ", show_permid_short(s.get_permid())
187 # ProxyDevel - Receive overlay messages from anyone
188 s.set_overlay_request_policy(AllowAllRequestPolicy())
190 if test_mode == "coord":
191 # add the helper 1 as a friend
193 helper1_keypair_filename = os.path.join("../../P2P-Testing-Infrastructure/ClientWorkingFolders/Proxy01/statedir","ec.pem")
194 helper1_keypair = EC.load_key(helper1_keypair_filename)
195 helper1_permid = str(helper1_keypair.pub().get_der())
196 # set helper1 ip address
197 helper1_ip="10.10.3.1"
198 # helper1_ip="141.85.224.203"
201 # add helper1 as a peer
202 peerdb = s.open_dbhandler(NTFY_PEERS)
204 peer['permid'] = helper1_permid
205 peer['ip'] = helper1_ip
206 peer['port'] = helper1_port
207 peer['last_seen'] = 0
208 peerdb.addPeer(peer['permid'], peer, update_dns=True, commit=True)
210 # add the helper 2 as a friend
212 helper2_keypair_filename = os.path.join("../../P2P-Testing-Infrastructure/ClientWorkingFolders/Proxy02/statedir","ec.pem")
213 helper2_keypair = EC.load_key(helper2_keypair_filename)
214 helper2_permid = str(helper2_keypair.pub().get_der())
215 # set helper2 ip address
216 helper2_ip="10.10.4.1"
217 # helper2_ip="141.85.224.204"
220 # add helper2 as a peer
221 peerdb = s.open_dbhandler(NTFY_PEERS)
223 peer['permid'] = helper2_permid
224 peer['ip'] = helper2_ip
225 peer['port'] = helper2_port
226 peer['last_seen'] = 0
227 peerdb.addPeer(peer['permid'], peer, update_dns=True, commit=True)
229 # ProxyDevel - if in no_download is false (the client has to download torrent data), then start downloading
230 if (no_download == False):
231 # setup and start download
232 download_startup_config = DownloadStartupConfig()
233 download_startup_config.set_dest_dir(output_dir);
234 # ProxyDevel - turn PEX off
235 download_startup_config.set_ut_pex_max_addrs_from_peer(0)
236 download_startup_config.set_proxy_mode(proxy_mode)
237 download_startup_config.set_no_helpers(helpers)
239 torrent_def = TorrentDef.load(torrent_file)
241 d = s.start_download(torrent_def, download_startup_config)
242 d.set_state_callback(state_callback, getpeerlist=False)
244 # if the client is a coordinator
245 if test_mode == "coord":
246 # allow time for the download to start, before starting the help request
249 for download in s.get_downloads():
251 print "*** COORDINATOR Sending help request"
253 peerlist.append(helper1_permid)
254 peerlist.append(helper2_permid)
255 download.ask_coopdl_helpers(peerlist)
258 # loop while waiting for CTRL-C (or any other signal/interrupt)
260 # - cannot use sys.stdin.read() - it means busy waiting when running
261 # the process in background
262 # - cannot use condition variable - that don't listen to KeyboardInterrupt
264 # time.sleep(sys.maxint) has "issues" on 64bit architectures; divide it
265 # by some value (2048) to solve problem
269 time.sleep(sys.maxint/2048)
276 #shutil.rmtree(statedir)
278 if __name__ == "__main__":