2 # see LICENSE.txt for license information
4 # single torrent checking without Thread
6 from BaseLib.Core.BitTornado.bencode import bdecode
7 from random import shuffle
10 import BaseLib.Core.Utilities.timeouturlopen as timeouturlopen
12 from traceback import print_exc
14 HTTP_TIMEOUT = 30 # seconds
18 def trackerChecking(torrent):
19 single_no_thread(torrent)
21 def single_no_thread(torrent):
23 (seeder, leecher) = (-2, -2) # default dead
24 if ( torrent["info"].get("announce-list", "") == "" ): # no announce-list
26 announce = torrent["info"]["announce"] # get the single tracker
27 (s, l) = singleTrackerStatus(torrent, announce)
28 seeder = max(seeder, s)
29 leecher = max(leecher, l)
32 else: # have announce-list
33 for announces in torrent["info"]["announce-list"]:
34 a_len = len(announces)
35 if (a_len == 0): # length = 0
37 if (a_len == 1): # length = 1
38 announce = announces[0]
39 (s, l) = singleTrackerStatus(torrent, announce)
40 seeder = max(seeder, s)
41 leecher = max(leecher, l)
43 aindex = torrent["info"]["announce-list"].index(announces)
45 # Arno: protect agaist DoS torrents with many trackers in announce list.
46 announces = announces[:16]
47 for announce in announces: # for eache announce
48 (s, l) = singleTrackerStatus(torrent, announce)
49 seeder = max(seeder, s)
50 leecher = max(leecher, l)
53 if (seeder > 0 or leecher > 0): # put the announce\
54 announces.remove(announce) # in front of the tier
55 announces.insert(0, announce)
56 torrent["info"]["announce-list"][aindex] = announces
60 if (seeder == -3 and leecher == -3):
61 pass # if interval problem, just keep the last status
63 torrent["seeder"] = seeder
64 torrent["leecher"] = leecher
65 if (torrent["seeder"] > 0 or torrent["leecher"] > 0):
66 torrent["status"] = "good"
67 elif (torrent["seeder"] == 0 and torrent["leecher"] == 0):
68 torrent["status"] = "unknown"
69 # torrent["seeder"] = 0
70 # torrent["leecher"] = 0
71 elif (torrent["seeder"] == -1 and torrent["leecher"] == -1): # unknown
72 torrent["status"] = "unknown"
73 # torrent["seeder"] = -1
74 # torrent["leecher"] = -1
75 else: # if seeder == -2 and leecher == -2, dead
76 torrent["status"] = "dead"
77 torrent["seeder"] = -2
78 torrent["leecher"] = -2
79 torrent["last_check_time"] = long(time())
83 def singleTrackerStatus(torrent, announce):
84 # return (-1, -1) means the status of torrent is unknown
85 # return (-2. -2) means the status of torrent is dead
86 # return (-3, -3) means the interval problem
87 info_hash = torrent["infohash"]
90 print >>sys.stderr,"TrackerChecking: Checking",announce,"for",`info_hash`
92 url = getUrl(announce, info_hash) # whether scrape support
93 if (url == None): # tracker url error
94 return (-2, -2) # use announce instead
96 #print 'Checking url: %s' % url
97 (seeder, leecher) = getStatus(url, info_hash)
100 print >>sys.stderr,"TrackerChecking: Result",(seeder,leecher)
102 (seeder, leecher) = (-2, -2)
103 return (seeder, leecher)
105 # generate the query URL
106 def getUrl(announce, info_hash):
107 if (announce == -1): # tracker url error
108 return None # return None
109 announce_index = announce.rfind("announce")
110 last_index = announce.rfind("/")
113 if (last_index +1 == announce_index): # srape supprot
114 url = url.replace("announce","scrape")
115 url += "?info_hash=" + urllib.quote(info_hash)
121 def getStatus(url, info_hash):
123 resp = timeouturlopen.urlOpenTimeout(url,timeout=HTTP_TIMEOUT)
124 response = resp.read()
128 return (-1, -1) # unknown
129 except AttributeError:
130 # print "AttributeError"
131 return (-2, -2) # dead
134 response_dict = bdecode(response)
137 # print "DeCode Error " + response
138 return (-2, -2) # dead
141 status = response_dict["files"][info_hash]
142 seeder = status["complete"]
145 leecher = status["incomplete"]
150 # print "KeyError " + info_hash + str(response_dict)
152 if response_dict.has_key("flags"): # may be interval problem
153 if response_dict["flags"].has_key("min_request_interval"):
154 # print "interval problem"
158 # print "KeyError " + info_hash + str(response_dict)
159 return (-2, -2) # dead
161 return (seeder, leecher)