/[gentoo-src]/bittorrent/bt_daemon.py
Gentoo

Contents of /bittorrent/bt_daemon.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (show annotations) (download) (as text)
Fri Apr 30 01:13:57 2004 UTC (12 years, 3 months ago) by carpaski
Branch: MAIN
File MIME type: text/x-python
First copy of the bt daemon... Read the code. I'm
lazy and busy at the moment, so I'm really not up
for documentation. -- NJ

1 #!/usr/bin/python -O
2
3 # Greatly modified by carpaski@gentoo.org
4 # btdownloadheadless written by Bram Cohen
5 # see LICENSE.txt for license information
6
7
8 # This is 2^x ... put the x below -- Chunk size for sha1 -- 18 == 256k
9 piece_size_pow2 = 18
10 delay = 0
11 debug = 0
12
13 # No trailing /
14 file_base = "/usr/portage/distfiles"
15 torrent_base = "/tmp/torrents"
16
17 COMMENT = "Gentoo Linux BitTorrent Mirror System"
18 tracker = "http://egret.gentoo.org:6969/announce"
19
20 # Useless variables
21 cols = 80
22 import BitTorrent
23 import os
24 from BitTorrent.download import download
25 from threading import Event,Thread
26 import types
27 import re
28 from os import listdir, getcwd, stat
29 from stat import ST_SIZE
30 from os.path import abspath,isdir,isfile,normpath
31 from sys import argv, stdout, path
32 from cStringIO import StringIO
33 from time import time,ctime,sleep
34
35 from BitTorrent.makemetafile import make_meta_file
36
37 def hours(n):
38 if n == -1:
39 return '<unknown>'
40 if n == 0:
41 return 'complete!'
42 n = long(n)
43 h, r = divmod(n, 60 * 60)
44 m, sec = divmod(r, 60)
45 if h > 1000000:
46 return '<unknown>'
47 if h > 0:
48 return '%d hour %02d min %02d sec' % (h, m, sec)
49 else:
50 return '%d min %02d sec' % (m, sec)
51
52 class HeadlessDisplayer:
53 def __init__(self):
54 self.done = False
55 self.file = ''
56 self.percentDone = ''
57 self.timeEst = ''
58 self.downloadTo = ''
59 self.downRate = ''
60 self.upRate = ''
61 self.downTotal = ''
62 self.upTotal = ''
63 self.errors = []
64 self.last_update_time = 0
65
66 def finished(self):
67 self.done = True
68 self.percentDone = '100'
69 self.timeEst = 'Download Succeeded!'
70 self.downRate = ''
71 self.display({})
72
73 def failed(self):
74 self.done = True
75 self.percentDone = '0'
76 self.timeEst = 'Download Failed!'
77 self.downRate = ''
78 self.display({})
79
80 def error(self, errormsg):
81 self.errors.append(errormsg)
82 self.display({})
83
84 def display(self, dict):
85 for x in self.errors:
86 print self.file+": "+str(x)
87 self.errors = []
88 return
89
90 def chooseFile(self, default, size, saveas, dir):
91 self.file = '%s (%.1f MB)' % (default, float(size) / (1 << 20))
92 if saveas != '':
93 default = saveas
94 self.downloadTo = abspath(default)
95 return default
96
97 def newpath(self, path):
98 self.downloadTo = path
99
100 def prefix_array(array,prefix,doblanks=1):
101 """Prepends a given prefix to each element in an Array/List/Tuple.
102 Returns a List."""
103 if type(array) not in [types.ListType, types.TupleType]:
104 raise TypeError, "List or Tuple expected. Got %s" % type(array)
105 newarray=[]
106 for x in array:
107 if x or doblanks:
108 newarray.append(prefix + x)
109 else:
110 newarray.append(x)
111 return newarray
112
113
114 def list_files(dirlist):
115 file_list = []
116 for mydir in dirlist:
117 if isdir(mydir):
118 try:
119 file_list += list_files(prefix_array(listdir(mydir),mydir+"/"))
120 except Exception,e:
121 print e
122 elif isfile(mydir):
123 file_list.append(mydir)
124 else:
125 print "Unknown type:",mydir
126 return file_list
127
128
129 def progress(amount):
130 # Dummy function for the create-torrent progress meter
131 pass
132
133
134
135
136 if __name__ == '__main__':
137
138 threads = {}
139 dirs = [torrent_base[:],file_base[:]]
140 re_file = re.compile("("+torrent_base[:]+"|"+file_base[:]+")(/.+?)(\.torrent)?$")
141
142 while(True):
143 files = list_files(dirs)
144 files.sort()
145 new_files = []
146 torrents = []
147
148 for f in files:
149 match = re_file.match(f)
150 if not match:
151 print "Failed to match:",f
152 else:
153 if match.group(1) == torrent_base:
154 if match.group(3): # It's a torrent, yay!
155 if match.group(2) not in torrents and stat(f)[ST_SIZE]>0:
156 torrents.append(match.group(2))
157 while(match.group(2) in new_files):
158 del new_files[new_files.index(match.group(2))]
159 elif torrent_base != file_base and debug:
160 print "Not a torrent file:",f
161 if match.group(1) == file_base:
162 if match.group(3) and torrent_base != file_base and debug:
163 print "Torrent in file directory:",f
164 elif match.group(2) not in torrents:
165 if debug:
166 print "New file:",f
167 new_files.append(match.group(2))
168
169 for t in threads.keys():
170 # Remove threads that we don't have a bittorrent for.
171 if t not in torrents:
172 print "Stopping torrent [%s]: %s" % (ctime(),t)
173 threads[t][0]._Thread__stop()
174 del threads[t]
175 while(t in torrents):
176 del torrents[torrents.index(t)]
177
178 elif not threads[t][0].isAlive():
179 print "Thread died [%s]: %s" % (ctime(),t)
180 del threads[t]
181
182 for t in torrents:
183 # Start threads up.
184 if t not in threads.keys():
185 print "Starting torrent [%s]: %s" % (ctime(),t)
186 h = HeadlessDisplayer()
187 try:
188 if not os.path.isdir(file_base+"/"+os.path.dirname(t)):
189 os.makedirs(file_base+"/"+os.path.dirname(t))
190 t_thread = Thread(target=download,name="BitTorrent::"+t,args=(['--responsefile', torrent_base+"/"+t+".torrent", '--saveas', file_base+"/"+t], h.chooseFile, h.display, h.finished, h.error, Event(), cols))
191 threads[t] = [t_thread,h]
192 t_thread.start()
193 sleep(delay)
194 except Exception, e:
195 print "Failed to start thread: %s" % (t)
196 print "Reason: %s" % (str(e))
197
198 for f in new_files:
199 # Create the torrents for files that don't have them.
200 try:
201 print "Creating torrent [%s]: %s" % (ctime(),f)
202 if not os.path.isdir(torrent_base+"/"+os.path.dirname(f)):
203 os.makedirs(torrent_base+"/"+os.path.dirname(f))
204 make_meta_file(file_base+"/"+f,tracker,piece_size_pow2,progress=progress,comment=COMMENT,target=torrent_base+"/"+f+".torrent")
205 except Exception, e:
206 print "Failed to create torrent: "+str(e)
207
208 sleep(1)

  ViewVC Help
Powered by ViewVC 1.1.20