murder 0.0.0.pre

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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)