清华大佬耗费三个月吐血整理的几百G的资源,免费分享!....>>>
# -*- coding: utf-8 -*- from xmlrpclib import ServerProxy, Fault from os.path import join, isfile, abspath from SimpleXMLRPCServer import SimpleXMLRPCServer from urlparse import urlparse import sys import xmlrpclib SimpleXMLRPCServer.allow_reuse_address = 1 #避免循环请求和长链请求。之所以用6是采用了六度分隔的原理 MAX_HISTORY_LENGTH = 6 UNHANDLED = 100 ACCESS_DENIED = 200 class UnhandledQuery(Fault): def __init__(self, message="Counldn't handle the query"): Fault.__init__(self, UNHANDLED, message) class AccessDenied(Fault): def __init__(self, message='Access denied'): Fault.__init__(self, ACCESS_DENIED, message) def inside(dirs, name): the_dir = abspath(dirs) name = abspath(name) return name.startswith(join(the_dir, '')) def getPort(url): name = urlparse(url)[1] parts = name.split(':') return int(parts[-1]) class Node: def __init__(self, url, dirname, secret): self.url = url self.dirname = dirname self.secret = secret self.known = set() def query(self, query, history=[]): try: return self._handle(query) except UnhandledQuery: history = history + [self.url] if len(history) >= MAX_HISTORY_LENGTH: raise return self._broadcast(query, history) def hello(self, other): self.known.add(other) return 0 def fetch(self, query, secret): """找到并下载资源""" if secret != self.secret: raise AccessDenied result = self.query(query) f = open(join(self.dirname, query), 'wb') f.write(result.data) f.close() return 0 def _start(self): #启动XML_RPC服务器 s = SimpleXMLRPCServer(("", getPort(self.url)), logRequests=False) s.register_instance(self) s.serve_forever() def _handle(self, query): """处理请求""" name = join(self.dirname, query) if not isfile(name): raise UnhandledQuery if not inside(self.dirname, name): raise AccessDenied return xmlrpclib.Binary(open(name, 'rb').read()) def _broadcast(self, query, history): """将查询广播到所有已知的Node""" for other in self.known.copy(): if other in history: continue try: s = ServerProxy(other) return s.query(query, history) except Fault, f: if f.faultCode == UNHANDLED: pass else: self.known.remove(other) except: self.known.remove(other) raise UnhandledQuery def main(): url, directory, secret = sys.argv[1:] n = Node(url, directory, secret) n._start() if __name__ == '__main__': try: main() except KeyboardInterrupt: sys.exit()