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,75 @@
1
+ # Written by Bram Cohen
2
+ # see LICENSE.txt for license information
3
+
4
+ from clock import clock
5
+ try:
6
+ True
7
+ except:
8
+ True = 1
9
+ False = 0
10
+
11
+ FACTOR = 0.999
12
+
13
+ class RateMeasure:
14
+ def __init__(self):
15
+ self.last = None
16
+ self.time = 1.0
17
+ self.got = 0.0
18
+ self.remaining = None
19
+ self.broke = False
20
+ self.got_anything = False
21
+ self.last_checked = None
22
+ self.rate = 0
23
+ self.lastten = False
24
+
25
+ def data_came_in(self, amount):
26
+ if not self.got_anything:
27
+ self.got_anything = True
28
+ self.last = clock()
29
+ return
30
+ self.update(amount)
31
+
32
+ def data_rejected(self, amount):
33
+ pass
34
+
35
+ def get_time_left(self, left):
36
+ t = clock()
37
+ if not self.got_anything:
38
+ return None
39
+ if t - self.last > 15:
40
+ self.update(0)
41
+ try:
42
+ remaining = left/self.rate
43
+ if not self.lastten and remaining <= 10:
44
+ self.lastten = True
45
+ if self.lastten:
46
+ return remaining
47
+ delta = max(remaining/20,2)
48
+ if self.remaining is None:
49
+ self.remaining = remaining
50
+ elif abs(self.remaining-remaining) > delta:
51
+ self.remaining = remaining
52
+ else:
53
+ self.remaining -= t - self.last_checked
54
+ except ZeroDivisionError:
55
+ self.remaining = None
56
+ if self.remaining is not None and self.remaining < 0.1:
57
+ self.remaining = 0.1
58
+ self.last_checked = t
59
+ return self.remaining
60
+
61
+ def update(self, amount):
62
+ t = clock()
63
+ t1 = int(t)
64
+ l1 = int(self.last)
65
+ for i in xrange(l1,t1):
66
+ self.time *= FACTOR
67
+ self.got *= FACTOR
68
+ self.got += amount
69
+ if t - self.last < 20:
70
+ self.time += t - self.last
71
+ self.last = t
72
+ try:
73
+ self.rate = self.got / self.time
74
+ except ZeroDivisionError:
75
+ pass
@@ -0,0 +1,195 @@
1
+ # Written by Bram Cohen
2
+ # see LICENSE.txt for license information
3
+
4
+ from bisect import insort
5
+ from SocketHandler import SocketHandler, UPnP_ERROR
6
+ import socket
7
+ from cStringIO import StringIO
8
+ from traceback import print_exc
9
+ from select import error
10
+ from threading import Thread, Event
11
+ from time import sleep
12
+ from clock import clock
13
+ import sys
14
+ try:
15
+ True
16
+ except:
17
+ True = 1
18
+ False = 0
19
+
20
+
21
+ def autodetect_ipv6():
22
+ try:
23
+ assert sys.version_info >= (2,3)
24
+ assert socket.has_ipv6
25
+ socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
26
+ except:
27
+ return 0
28
+ return 1
29
+
30
+ def autodetect_socket_style():
31
+ if sys.platform.find('linux') < 0:
32
+ return 1
33
+ else:
34
+ try:
35
+ f = open('/proc/sys/net/ipv6/bindv6only','r')
36
+ dual_socket_style = int(f.read())
37
+ f.close()
38
+ return int(not dual_socket_style)
39
+ except:
40
+ return 0
41
+
42
+
43
+ READSIZE = 100000
44
+
45
+ class RawServer:
46
+ def __init__(self, doneflag, timeout_check_interval, timeout, noisy = True,
47
+ ipv6_enable = True, failfunc = lambda x: None, errorfunc = None,
48
+ sockethandler = None, excflag = Event()):
49
+ self.timeout_check_interval = timeout_check_interval
50
+ self.timeout = timeout
51
+ self.servers = {}
52
+ self.single_sockets = {}
53
+ self.dead_from_write = []
54
+ self.doneflag = doneflag
55
+ self.noisy = noisy
56
+ self.failfunc = failfunc
57
+ self.errorfunc = errorfunc
58
+ self.exccount = 0
59
+ self.funcs = []
60
+ self.externally_added = []
61
+ self.finished = Event()
62
+ self.tasks_to_kill = []
63
+ self.excflag = excflag
64
+
65
+ if sockethandler is None:
66
+ sockethandler = SocketHandler(timeout, ipv6_enable, READSIZE)
67
+ self.sockethandler = sockethandler
68
+ self.add_task(self.scan_for_timeouts, timeout_check_interval)
69
+
70
+ def get_exception_flag(self):
71
+ return self.excflag
72
+
73
+ def _add_task(self, func, delay, id = None):
74
+ assert float(delay) >= 0
75
+ insort(self.funcs, (clock() + delay, func, id))
76
+
77
+ def add_task(self, func, delay = 0, id = None):
78
+ assert float(delay) >= 0
79
+ self.externally_added.append((func, delay, id))
80
+
81
+ def scan_for_timeouts(self):
82
+ self.add_task(self.scan_for_timeouts, self.timeout_check_interval)
83
+ self.sockethandler.scan_for_timeouts()
84
+
85
+ def bind(self, port, bind = '', reuse = False,
86
+ ipv6_socket_style = 1, upnp = False):
87
+ self.sockethandler.bind(port, bind, reuse, ipv6_socket_style, upnp)
88
+
89
+ def find_and_bind(self, minport, maxport, bind = '', reuse = False,
90
+ ipv6_socket_style = 1, upnp = 0, randomizer = False):
91
+ return self.sockethandler.find_and_bind(minport, maxport, bind, reuse,
92
+ ipv6_socket_style, upnp, randomizer)
93
+
94
+ def start_connection_raw(self, dns, socktype, handler = None):
95
+ return self.sockethandler.start_connection_raw(dns, socktype, handler)
96
+
97
+ def start_connection(self, dns, handler = None, randomize = False):
98
+ return self.sockethandler.start_connection(dns, handler, randomize)
99
+
100
+ def get_stats(self):
101
+ return self.sockethandler.get_stats()
102
+
103
+ def pop_external(self):
104
+ while self.externally_added:
105
+ (a, b, c) = self.externally_added.pop(0)
106
+ self._add_task(a, b, c)
107
+
108
+
109
+ def listen_forever(self, handler):
110
+ self.sockethandler.set_handler(handler)
111
+ try:
112
+ while not self.doneflag.isSet():
113
+ try:
114
+ self.pop_external()
115
+ self._kill_tasks()
116
+ if self.funcs:
117
+ period = self.funcs[0][0] + 0.001 - clock()
118
+ else:
119
+ period = 2 ** 30
120
+ if period < 0:
121
+ period = 0
122
+ events = self.sockethandler.do_poll(period)
123
+ if self.doneflag.isSet():
124
+ return
125
+ while self.funcs and self.funcs[0][0] <= clock():
126
+ garbage1, func, id = self.funcs.pop(0)
127
+ if id in self.tasks_to_kill:
128
+ pass
129
+ try:
130
+ # print func.func_name
131
+ func()
132
+ except (SystemError, MemoryError), e:
133
+ self.failfunc(str(e))
134
+ return
135
+ except KeyboardInterrupt:
136
+ # self.exception(True)
137
+ return
138
+ except:
139
+ if self.noisy:
140
+ self.exception()
141
+ self.sockethandler.close_dead()
142
+ self.sockethandler.handle_events(events)
143
+ if self.doneflag.isSet():
144
+ return
145
+ self.sockethandler.close_dead()
146
+ except (SystemError, MemoryError), e:
147
+ self.failfunc(str(e))
148
+ return
149
+ except error:
150
+ if self.doneflag.isSet():
151
+ return
152
+ except KeyboardInterrupt:
153
+ # self.exception(True)
154
+ return
155
+ except:
156
+ self.exception()
157
+ if self.exccount > 10:
158
+ return
159
+ finally:
160
+ # self.sockethandler.shutdown()
161
+ self.finished.set()
162
+
163
+ def is_finished(self):
164
+ return self.finished.isSet()
165
+
166
+ def wait_until_finished(self):
167
+ self.finished.wait()
168
+
169
+ def _kill_tasks(self):
170
+ if self.tasks_to_kill:
171
+ new_funcs = []
172
+ for (t, func, id) in self.funcs:
173
+ if id not in self.tasks_to_kill:
174
+ new_funcs.append((t, func, id))
175
+ self.funcs = new_funcs
176
+ self.tasks_to_kill = []
177
+
178
+ def kill_tasks(self, id):
179
+ self.tasks_to_kill.append(id)
180
+
181
+ def exception(self, kbint = False):
182
+ if not kbint:
183
+ self.excflag.set()
184
+ self.exccount += 1
185
+ if self.errorfunc is None:
186
+ print_exc()
187
+ else:
188
+ data = StringIO()
189
+ print_exc(file = data)
190
+ # print data.getvalue() # report exception here too
191
+ if not kbint: # don't report here if it's a keyboard interrupt
192
+ self.errorfunc(data.getvalue())
193
+
194
+ def shutdown(self):
195
+ self.sockethandler.shutdown()
@@ -0,0 +1,188 @@
1
+ # Written by John Hoffman
2
+ # see LICENSE.txt for license information
3
+
4
+ from cStringIO import StringIO
5
+ #from RawServer import RawServer
6
+ try:
7
+ True
8
+ except:
9
+ True = 1
10
+ False = 0
11
+
12
+ from BT1.Encrypter import protocol_name
13
+
14
+ default_task_id = []
15
+
16
+ class SingleRawServer:
17
+ def __init__(self, info_hash, multihandler, doneflag, protocol):
18
+ self.info_hash = info_hash
19
+ self.doneflag = doneflag
20
+ self.protocol = protocol
21
+ self.multihandler = multihandler
22
+ self.rawserver = multihandler.rawserver
23
+ self.finished = False
24
+ self.running = False
25
+ self.handler = None
26
+ self.taskqueue = []
27
+
28
+ def shutdown(self):
29
+ if not self.finished:
30
+ self.multihandler.shutdown_torrent(self.info_hash)
31
+
32
+ def _shutdown(self):
33
+ if not self.finished:
34
+ self.finished = True
35
+ self.running = False
36
+ self.rawserver.kill_tasks(self.info_hash)
37
+ if self.handler:
38
+ self.handler.close_all()
39
+
40
+ def _external_connection_made(self, c, options, already_read):
41
+ if self.running:
42
+ c.set_handler(self.handler)
43
+ self.handler.externally_handshaked_connection_made(
44
+ c, options, already_read)
45
+
46
+ ### RawServer functions ###
47
+
48
+ def add_task(self, func, delay=0, id = default_task_id):
49
+ if id is default_task_id:
50
+ id = self.info_hash
51
+ if not self.finished:
52
+ self.rawserver.add_task(func, delay, id)
53
+
54
+ # def bind(self, port, bind = '', reuse = False):
55
+ # pass # not handled here
56
+
57
+ def start_connection(self, dns, handler = None):
58
+ if not handler:
59
+ handler = self.handler
60
+ c = self.rawserver.start_connection(dns, handler)
61
+ return c
62
+
63
+ # def listen_forever(self, handler):
64
+ # pass # don't call with this
65
+
66
+ def start_listening(self, handler):
67
+ self.handler = handler
68
+ self.running = True
69
+ return self.shutdown # obviously, doesn't listen forever
70
+
71
+ def is_finished(self):
72
+ return self.finished
73
+
74
+ def get_exception_flag(self):
75
+ return self.rawserver.get_exception_flag()
76
+
77
+
78
+ class NewSocketHandler: # hand a new socket off where it belongs
79
+ def __init__(self, multihandler, connection):
80
+ self.multihandler = multihandler
81
+ self.connection = connection
82
+ connection.set_handler(self)
83
+ self.closed = False
84
+ self.buffer = StringIO()
85
+ self.complete = False
86
+ self.next_len, self.next_func = 1, self.read_header_len
87
+ self.multihandler.rawserver.add_task(self._auto_close, 15)
88
+
89
+ def _auto_close(self):
90
+ if not self.complete:
91
+ self.close()
92
+
93
+ def close(self):
94
+ if not self.closed:
95
+ self.connection.close()
96
+ self.closed = True
97
+
98
+
99
+ # header format:
100
+ # connection.write(chr(len(protocol_name)) + protocol_name +
101
+ # (chr(0) * 8) + self.encrypter.download_id + self.encrypter.my_id)
102
+
103
+ # copied from Encrypter and modified
104
+
105
+ def read_header_len(self, s):
106
+ l = ord(s)
107
+ return l, self.read_header
108
+
109
+ def read_header(self, s):
110
+ self.protocol = s
111
+ return 8, self.read_reserved
112
+
113
+ def read_reserved(self, s):
114
+ self.options = s
115
+ return 20, self.read_download_id
116
+
117
+ def read_download_id(self, s):
118
+ if self.multihandler.singlerawservers.has_key(s):
119
+ if self.multihandler.singlerawservers[s].protocol == self.protocol:
120
+ return True
121
+ return None
122
+
123
+ def read_dead(self, s):
124
+ return None
125
+
126
+ def data_came_in(self, garbage, s):
127
+ while True:
128
+ if self.closed:
129
+ return
130
+ i = self.next_len - self.buffer.tell()
131
+ if i > len(s):
132
+ self.buffer.write(s)
133
+ return
134
+ self.buffer.write(s[:i])
135
+ s = s[i:]
136
+ m = self.buffer.getvalue()
137
+ self.buffer.reset()
138
+ self.buffer.truncate()
139
+ try:
140
+ x = self.next_func(m)
141
+ except:
142
+ self.next_len, self.next_func = 1, self.read_dead
143
+ raise
144
+ if x is None:
145
+ self.close()
146
+ return
147
+ if x == True: # ready to process
148
+ self.multihandler.singlerawservers[m]._external_connection_made(
149
+ self.connection, self.options, s)
150
+ self.complete = True
151
+ return
152
+ self.next_len, self.next_func = x
153
+
154
+ def connection_flushed(self, ss):
155
+ pass
156
+
157
+ def connection_lost(self, ss):
158
+ self.closed = True
159
+
160
+ class MultiHandler:
161
+ def __init__(self, rawserver, doneflag):
162
+ self.rawserver = rawserver
163
+ self.masterdoneflag = doneflag
164
+ self.singlerawservers = {}
165
+ self.connections = {}
166
+ self.taskqueues = {}
167
+
168
+ def newRawServer(self, info_hash, doneflag, protocol=protocol_name):
169
+ new = SingleRawServer(info_hash, self, doneflag, protocol)
170
+ self.singlerawservers[info_hash] = new
171
+ return new
172
+
173
+ def shutdown_torrent(self, info_hash):
174
+ self.singlerawservers[info_hash]._shutdown()
175
+ del self.singlerawservers[info_hash]
176
+
177
+ def listen_forever(self):
178
+ self.rawserver.listen_forever(self)
179
+ for srs in self.singlerawservers.values():
180
+ srs.finished = True
181
+ srs.running = False
182
+ srs.doneflag.set()
183
+
184
+ ### RawServer handler functions ###
185
+ # be wary of name collisions
186
+
187
+ def external_connection_made(self, ss):
188
+ NewSocketHandler(self, ss)