murder 0.0.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. data/.gitignore +1 -0
  2. data/LICENSE +17 -0
  3. data/README +224 -0
  4. data/Rakefile +52 -0
  5. data/VERSION +1 -0
  6. data/dist/BitTornado/BT1/Choker.py +128 -0
  7. data/dist/BitTornado/BT1/Connecter.py +288 -0
  8. data/dist/BitTornado/BT1/Downloader.py +594 -0
  9. data/dist/BitTornado/BT1/DownloaderFeedback.py +155 -0
  10. data/dist/BitTornado/BT1/Encrypter.py +333 -0
  11. data/dist/BitTornado/BT1/FileSelector.py +245 -0
  12. data/dist/BitTornado/BT1/Filter.py +12 -0
  13. data/dist/BitTornado/BT1/HTTPDownloader.py +251 -0
  14. data/dist/BitTornado/BT1/NatCheck.py +95 -0
  15. data/dist/BitTornado/BT1/PiecePicker.py +320 -0
  16. data/dist/BitTornado/BT1/Rerequester.py +426 -0
  17. data/dist/BitTornado/BT1/Statistics.py +177 -0
  18. data/dist/BitTornado/BT1/Storage.py +584 -0
  19. data/dist/BitTornado/BT1/StorageWrapper.py +1045 -0
  20. data/dist/BitTornado/BT1/StreamCheck.py +135 -0
  21. data/dist/BitTornado/BT1/T2T.py +193 -0
  22. data/dist/BitTornado/BT1/Uploader.py +145 -0
  23. data/dist/BitTornado/BT1/__init__.py +1 -0
  24. data/dist/BitTornado/BT1/btformats.py +100 -0
  25. data/dist/BitTornado/BT1/fakeopen.py +89 -0
  26. data/dist/BitTornado/BT1/makemetafile.py +263 -0
  27. data/dist/BitTornado/BT1/track.py +1067 -0
  28. data/dist/BitTornado/ConfigDir.py +401 -0
  29. data/dist/BitTornado/ConfigReader.py +1068 -0
  30. data/dist/BitTornado/ConnChoice.py +31 -0
  31. data/dist/BitTornado/CreateIcons.py +105 -0
  32. data/dist/BitTornado/CurrentRateMeasure.py +37 -0
  33. data/dist/BitTornado/HTTPHandler.py +167 -0
  34. data/dist/BitTornado/PSYCO.py +5 -0
  35. data/dist/BitTornado/RateLimiter.py +153 -0
  36. data/dist/BitTornado/RateMeasure.py +75 -0
  37. data/dist/BitTornado/RawServer.py +195 -0
  38. data/dist/BitTornado/ServerPortHandler.py +188 -0
  39. data/dist/BitTornado/SocketHandler.py +375 -0
  40. data/dist/BitTornado/__init__.py +63 -0
  41. data/dist/BitTornado/bencode.py +319 -0
  42. data/dist/BitTornado/bitfield.py +162 -0
  43. data/dist/BitTornado/clock.py +27 -0
  44. data/dist/BitTornado/download_bt1.py +882 -0
  45. data/dist/BitTornado/inifile.py +169 -0
  46. data/dist/BitTornado/iprangeparse.py +194 -0
  47. data/dist/BitTornado/launchmanycore.py +381 -0
  48. data/dist/BitTornado/natpunch.py +254 -0
  49. data/dist/BitTornado/parseargs.py +137 -0
  50. data/dist/BitTornado/parsedir.py +150 -0
  51. data/dist/BitTornado/piecebuffer.py +86 -0
  52. data/dist/BitTornado/selectpoll.py +109 -0
  53. data/dist/BitTornado/subnetparse.py +218 -0
  54. data/dist/BitTornado/torrentlistparse.py +38 -0
  55. data/dist/BitTornado/zurllib.py +100 -0
  56. data/dist/murder_client.py +291 -0
  57. data/dist/murder_make_torrent.py +46 -0
  58. data/dist/murder_tracker.py +28 -0
  59. data/doc/examples/Capfile +28 -0
  60. data/lib/capistrano/recipes/deploy/strategy/murder.rb +52 -0
  61. data/lib/murder.rb +43 -0
  62. data/lib/murder/admin.rb +47 -0
  63. data/lib/murder/murder.rb +121 -0
  64. data/murder.gemspec +101 -0
  65. metadata +129 -0
@@ -0,0 +1,86 @@
1
+ # Written by John Hoffman
2
+ # see LICENSE.txt for license information
3
+
4
+ from array import array
5
+ from threading import Lock
6
+ # import inspect
7
+ try:
8
+ True
9
+ except:
10
+ True = 1
11
+ False = 0
12
+
13
+ DEBUG = False
14
+
15
+ class SingleBuffer:
16
+ def __init__(self, pool):
17
+ self.pool = pool
18
+ self.buf = array('c')
19
+
20
+ def init(self):
21
+ if DEBUG:
22
+ print self.count
23
+ '''
24
+ for x in xrange(6,1,-1):
25
+ try:
26
+ f = inspect.currentframe(x).f_code
27
+ print (f.co_filename,f.co_firstlineno,f.co_name)
28
+ del f
29
+ except:
30
+ pass
31
+ print ''
32
+ '''
33
+ self.length = 0
34
+
35
+ def append(self, s):
36
+ l = self.length+len(s)
37
+ self.buf[self.length:l] = array('c',s)
38
+ self.length = l
39
+
40
+ def __len__(self):
41
+ return self.length
42
+
43
+ def __getslice__(self, a, b):
44
+ if b > self.length:
45
+ b = self.length
46
+ if b < 0:
47
+ b += self.length
48
+ if a == 0 and b == self.length and len(self.buf) == b:
49
+ return self.buf # optimization
50
+ return self.buf[a:b]
51
+
52
+ def getarray(self):
53
+ return self.buf[:self.length]
54
+
55
+ def release(self):
56
+ if DEBUG:
57
+ print -self.count
58
+ self.pool.release(self)
59
+
60
+
61
+ class BufferPool:
62
+ def __init__(self):
63
+ self.pool = []
64
+ self.lock = Lock()
65
+ if DEBUG:
66
+ self.count = 0
67
+
68
+ def new(self):
69
+ self.lock.acquire()
70
+ if self.pool:
71
+ x = self.pool.pop()
72
+ else:
73
+ x = SingleBuffer(self)
74
+ if DEBUG:
75
+ self.count += 1
76
+ x.count = self.count
77
+ x.init()
78
+ self.lock.release()
79
+ return x
80
+
81
+ def release(self, x):
82
+ self.pool.append(x)
83
+
84
+
85
+ _pool = BufferPool()
86
+ PieceBuffer = _pool.new
@@ -0,0 +1,109 @@
1
+ # Written by Bram Cohen
2
+ # see LICENSE.txt for license information
3
+
4
+ from select import select, error
5
+ from time import sleep
6
+ from types import IntType
7
+ from bisect import bisect
8
+ POLLIN = 1
9
+ POLLOUT = 2
10
+ POLLERR = 8
11
+ POLLHUP = 16
12
+
13
+ class poll:
14
+ def __init__(self):
15
+ self.rlist = []
16
+ self.wlist = []
17
+
18
+ def register(self, f, t):
19
+ if type(f) != IntType:
20
+ f = f.fileno()
21
+ if (t & POLLIN):
22
+ insert(self.rlist, f)
23
+ else:
24
+ remove(self.rlist, f)
25
+ if (t & POLLOUT):
26
+ insert(self.wlist, f)
27
+ else:
28
+ remove(self.wlist, f)
29
+
30
+ def unregister(self, f):
31
+ if type(f) != IntType:
32
+ f = f.fileno()
33
+ remove(self.rlist, f)
34
+ remove(self.wlist, f)
35
+
36
+ def poll(self, timeout = None):
37
+ if self.rlist or self.wlist:
38
+ try:
39
+ r, w, e = select(self.rlist, self.wlist, [], timeout)
40
+ except ValueError:
41
+ return None
42
+ else:
43
+ sleep(timeout)
44
+ return []
45
+ result = []
46
+ for s in r:
47
+ result.append((s, POLLIN))
48
+ for s in w:
49
+ result.append((s, POLLOUT))
50
+ return result
51
+
52
+ def remove(list, item):
53
+ i = bisect(list, item)
54
+ if i > 0 and list[i-1] == item:
55
+ del list[i-1]
56
+
57
+ def insert(list, item):
58
+ i = bisect(list, item)
59
+ if i == 0 or list[i-1] != item:
60
+ list.insert(i, item)
61
+
62
+ def test_remove():
63
+ x = [2, 4, 6]
64
+ remove(x, 2)
65
+ assert x == [4, 6]
66
+ x = [2, 4, 6]
67
+ remove(x, 4)
68
+ assert x == [2, 6]
69
+ x = [2, 4, 6]
70
+ remove(x, 6)
71
+ assert x == [2, 4]
72
+ x = [2, 4, 6]
73
+ remove(x, 5)
74
+ assert x == [2, 4, 6]
75
+ x = [2, 4, 6]
76
+ remove(x, 1)
77
+ assert x == [2, 4, 6]
78
+ x = [2, 4, 6]
79
+ remove(x, 7)
80
+ assert x == [2, 4, 6]
81
+ x = [2, 4, 6]
82
+ remove(x, 5)
83
+ assert x == [2, 4, 6]
84
+ x = []
85
+ remove(x, 3)
86
+ assert x == []
87
+
88
+ def test_insert():
89
+ x = [2, 4]
90
+ insert(x, 1)
91
+ assert x == [1, 2, 4]
92
+ x = [2, 4]
93
+ insert(x, 3)
94
+ assert x == [2, 3, 4]
95
+ x = [2, 4]
96
+ insert(x, 5)
97
+ assert x == [2, 4, 5]
98
+ x = [2, 4]
99
+ insert(x, 2)
100
+ assert x == [2, 4]
101
+ x = [2, 4]
102
+ insert(x, 4)
103
+ assert x == [2, 4]
104
+ x = [2, 3, 4]
105
+ insert(x, 3)
106
+ assert x == [2, 3, 4]
107
+ x = []
108
+ insert(x, 3)
109
+ assert x == [3]
@@ -0,0 +1,218 @@
1
+ # Written by John Hoffman
2
+ # see LICENSE.txt for license information
3
+
4
+ from bisect import bisect, insort
5
+
6
+ try:
7
+ True
8
+ except:
9
+ True = 1
10
+ False = 0
11
+ bool = lambda x: not not x
12
+
13
+ hexbinmap = {
14
+ '0': '0000',
15
+ '1': '0001',
16
+ '2': '0010',
17
+ '3': '0011',
18
+ '4': '0100',
19
+ '5': '0101',
20
+ '6': '0110',
21
+ '7': '0111',
22
+ '8': '1000',
23
+ '9': '1001',
24
+ 'a': '1010',
25
+ 'b': '1011',
26
+ 'c': '1100',
27
+ 'd': '1101',
28
+ 'e': '1110',
29
+ 'f': '1111',
30
+ 'x': '0000',
31
+ }
32
+
33
+ chrbinmap = {}
34
+ for n in xrange(256):
35
+ b = []
36
+ nn = n
37
+ for i in xrange(8):
38
+ if nn & 0x80:
39
+ b.append('1')
40
+ else:
41
+ b.append('0')
42
+ nn <<= 1
43
+ chrbinmap[n] = ''.join(b)
44
+
45
+
46
+ def to_bitfield_ipv4(ip):
47
+ ip = ip.split('.')
48
+ if len(ip) != 4:
49
+ raise ValueError, "bad address"
50
+ b = []
51
+ for i in ip:
52
+ b.append(chrbinmap[int(i)])
53
+ return ''.join(b)
54
+
55
+ def to_bitfield_ipv6(ip):
56
+ b = ''
57
+ doublecolon = False
58
+
59
+ if ip == '':
60
+ raise ValueError, "bad address"
61
+ if ip == '::': # boundary handling
62
+ ip = ''
63
+ elif ip[:2] == '::':
64
+ ip = ip[1:]
65
+ elif ip[0] == ':':
66
+ raise ValueError, "bad address"
67
+ elif ip[-2:] == '::':
68
+ ip = ip[:-1]
69
+ elif ip[-1] == ':':
70
+ raise ValueError, "bad address"
71
+ for n in ip.split(':'):
72
+ if n == '': # double-colon
73
+ if doublecolon:
74
+ raise ValueError, "bad address"
75
+ doublecolon = True
76
+ b += ':'
77
+ continue
78
+ if n.find('.') >= 0: # IPv4
79
+ n = to_bitfield_ipv4(n)
80
+ b += n + '0'*(32-len(n))
81
+ continue
82
+ n = ('x'*(4-len(n))) + n
83
+ for i in n:
84
+ b += hexbinmap[i]
85
+ if doublecolon:
86
+ pos = b.find(':')
87
+ b = b[:pos]+('0'*(129-len(b)))+b[pos+1:]
88
+ if len(b) != 128: # always check size
89
+ raise ValueError, "bad address"
90
+ return b
91
+
92
+ ipv4addrmask = to_bitfield_ipv6('::ffff:0:0')[:96]
93
+
94
+ class IP_List:
95
+ def __init__(self):
96
+ self.ipv4list = []
97
+ self.ipv6list = []
98
+
99
+ def __nonzero__(self):
100
+ return bool(self.ipv4list or self.ipv6list)
101
+
102
+
103
+ def append(self, ip, depth = 256):
104
+ if ip.find(':') < 0: # IPv4
105
+ insort(self.ipv4list,to_bitfield_ipv4(ip)[:depth])
106
+ else:
107
+ b = to_bitfield_ipv6(ip)
108
+ if b.startswith(ipv4addrmask):
109
+ insort(self.ipv4list,b[96:][:depth-96])
110
+ else:
111
+ insort(self.ipv6list,b[:depth])
112
+
113
+
114
+ def includes(self, ip):
115
+ if not (self.ipv4list or self.ipv6list):
116
+ return False
117
+ if ip.find(':') < 0: # IPv4
118
+ b = to_bitfield_ipv4(ip)
119
+ else:
120
+ b = to_bitfield_ipv6(ip)
121
+ if b.startswith(ipv4addrmask):
122
+ b = b[96:]
123
+ if len(b) > 32:
124
+ l = self.ipv6list
125
+ else:
126
+ l = self.ipv4list
127
+ for map in l[bisect(l,b)-1:]:
128
+ if b.startswith(map):
129
+ return True
130
+ if map > b:
131
+ return False
132
+ return False
133
+
134
+
135
+ def read_fieldlist(self, file): # reads a list from a file in the format 'ip/len <whatever>'
136
+ f = open(file, 'r')
137
+ while True:
138
+ line = f.readline()
139
+ if not line:
140
+ break
141
+ line = line.strip().expandtabs()
142
+ if not line or line[0] == '#':
143
+ continue
144
+ try:
145
+ line, garbage = line.split(' ',1)
146
+ except:
147
+ pass
148
+ try:
149
+ line, garbage = line.split('#',1)
150
+ except:
151
+ pass
152
+ try:
153
+ ip, depth = line.split('/')
154
+ except:
155
+ ip = line
156
+ depth = None
157
+ try:
158
+ if depth is not None:
159
+ depth = int(depth)
160
+ self.append(ip,depth)
161
+ except:
162
+ print '*** WARNING *** could not parse IP range: '+line
163
+ f.close()
164
+
165
+
166
+ def set_intranet_addresses(self):
167
+ self.append('127.0.0.1',8)
168
+ self.append('10.0.0.0',8)
169
+ self.append('172.16.0.0',12)
170
+ self.append('192.168.0.0',16)
171
+ self.append('169.254.0.0',16)
172
+ self.append('::1')
173
+ self.append('fe80::',16)
174
+ self.append('fec0::',16)
175
+
176
+ def set_ipv4_addresses(self):
177
+ self.append('::ffff:0:0',96)
178
+
179
+ def ipv6_to_ipv4(ip):
180
+ ip = to_bitfield_ipv6(ip)
181
+ if not ip.startswith(ipv4addrmask):
182
+ raise ValueError, "not convertible to IPv4"
183
+ ip = ip[-32:]
184
+ x = ''
185
+ for i in range(4):
186
+ x += str(int(ip[:8],2))
187
+ if i < 3:
188
+ x += '.'
189
+ ip = ip[8:]
190
+ return x
191
+
192
+ def to_ipv4(ip):
193
+ if is_ipv4(ip):
194
+ _valid_ipv4(ip)
195
+ return ip
196
+ return ipv6_to_ipv4(ip)
197
+
198
+ def is_ipv4(ip):
199
+ return ip.find(':') < 0
200
+
201
+ def _valid_ipv4(ip):
202
+ ip = ip.split('.')
203
+ if len(ip) != 4:
204
+ raise ValueError
205
+ for i in ip:
206
+ chr(int(i))
207
+
208
+ def is_valid_ip(ip):
209
+ try:
210
+ if not ip:
211
+ return False
212
+ if is_ipv4(ip):
213
+ _valid_ipv4(ip)
214
+ return True
215
+ to_bitfield_ipv6(ip)
216
+ return True
217
+ except:
218
+ return False
@@ -0,0 +1,38 @@
1
+ # Written by John Hoffman
2
+ # see LICENSE.txt for license information
3
+
4
+ from binascii import unhexlify
5
+
6
+ try:
7
+ True
8
+ except:
9
+ True = 1
10
+ False = 0
11
+
12
+
13
+ # parses a list of torrent hashes, in the format of one hash per line in hex format
14
+
15
+ def parsetorrentlist(filename, parsed):
16
+ new_parsed = {}
17
+ added = {}
18
+ removed = parsed
19
+ f = open(filename, 'r')
20
+ while True:
21
+ l = f.readline()
22
+ if not l:
23
+ break
24
+ l = l.strip()
25
+ try:
26
+ if len(l) != 40:
27
+ raise ValueError, 'bad line'
28
+ h = unhexlify(l)
29
+ except:
30
+ print '*** WARNING *** could not parse line in torrent list: '+l
31
+ if parsed.has_key(h):
32
+ del removed[h]
33
+ else:
34
+ added[h] = True
35
+ new_parsed[h] = True
36
+ f.close()
37
+ return (new_parsed, added, removed)
38
+