|
@@ -0,0 +1,105 @@
|
|
|
+
|
|
|
+from gi.repository import Riddle
|
|
|
+from gi.repository import Gio
|
|
|
+from gi.repository import GLib
|
|
|
+import threading
|
|
|
+import hashlib
|
|
|
+
|
|
|
+class RiddleClient:
|
|
|
+
|
|
|
+ GROUP_NAME = "riddle-btt"
|
|
|
+
|
|
|
+ def __init__(self):
|
|
|
+ self.loop = GLib.MainLoop()
|
|
|
+ self.__service = Riddle.construct_best_available_service()
|
|
|
+ self.infohashes = set()
|
|
|
+ self.addresses = set()
|
|
|
+
|
|
|
+ self.mirror_riddles_infohash_map = {}
|
|
|
+ self.peer_riddles_infohash_map = {}
|
|
|
+
|
|
|
+ self.mirror_peers = {}
|
|
|
+ self.peer_peers = {}
|
|
|
+
|
|
|
+ self.riddle_sets = {}
|
|
|
+
|
|
|
+ self.__service.connect("discovered_peer", self.__discovery_made)
|
|
|
+ self.__service.join_group(self.GROUP_NAME)
|
|
|
+
|
|
|
+ threading.Thread(target=self.__mainloop).start()
|
|
|
+
|
|
|
+ def __mainloop(self):
|
|
|
+ self.loop.run()
|
|
|
+
|
|
|
+ def add_riddles(self, infohash, port, is_mirror):
|
|
|
+ public_ip = self.__service.get_public_ip()
|
|
|
+ socket_address = Gio.InetSocketAddress.new_from_string(public_ip.to_string(), port)
|
|
|
+
|
|
|
+ mirror_riddle = Riddle.SharedKeyRiddle.new(self.__get_key(infohash, True))
|
|
|
+ mirror_riddle.set_group(self.GROUP_NAME)
|
|
|
+
|
|
|
+ peer_riddle = Riddle.SharedKeyRiddle.new(self.__get_key(infohash, False))
|
|
|
+ peer_riddle.set_group(self.GROUP_NAME)
|
|
|
+ peer_riddle.set_app_socket_address(socket_address)
|
|
|
+ print("Created")
|
|
|
+ self.infohashes.add(infohash)
|
|
|
+
|
|
|
+ self.mirror_riddles_infohash_map[mirror_riddle] = infohash
|
|
|
+ if(infohash not in self.mirror_peers):
|
|
|
+ self.mirror_peers[infohash] = []
|
|
|
+
|
|
|
+ self.peer_riddles_infohash_map[peer_riddle] = infohash
|
|
|
+ if(infohash not in self.peer_peers):
|
|
|
+ self.peer_peers[infohash] = []
|
|
|
+
|
|
|
+ self.__service.register_riddle(peer_riddle)
|
|
|
+ if(is_mirror):
|
|
|
+ mirror_riddle.set_app_socket_address(socket_address)
|
|
|
+ self.__service.register_riddle(mirror_riddle)
|
|
|
+
|
|
|
+ print("Registered")
|
|
|
+
|
|
|
+ self.__service.publish_riddle(peer_riddle)
|
|
|
+ self.__service.publish_riddle(mirror_riddle)
|
|
|
+
|
|
|
+ print("Registered")
|
|
|
+
|
|
|
+ self.riddle_sets[infohash] = [peer_riddle, mirror_riddle]
|
|
|
+
|
|
|
+ def republish_riddle(self, infohash):
|
|
|
+ for riddle in self.riddle_sets[infohash]:
|
|
|
+ self.__service.publish_riddle(riddle)
|
|
|
+
|
|
|
+ def __discovery_made(self, service, address, riddle):
|
|
|
+ print("Discovery made: {}".format(address))
|
|
|
+
|
|
|
+ if(address.to_string() in self.addresses):
|
|
|
+ print("Already disovered")
|
|
|
+ return
|
|
|
+ else:
|
|
|
+ self.addresses.add(address.to_string())
|
|
|
+
|
|
|
+ if(riddle in self.mirror_riddles_infohash_map):
|
|
|
+ infohash = self.mirror_riddles_infohash_map[riddle]
|
|
|
+ self.mirror_peers[infohash].append(address)
|
|
|
+
|
|
|
+ elif(riddle in self.peer_riddles_infohash_map):
|
|
|
+ infohash = self.peer_riddles_infohash_map[riddle]
|
|
|
+ self.peer_peers[infohash].append(address)
|
|
|
+
|
|
|
+
|
|
|
+ else:
|
|
|
+ print("Discovery made but no matching infohash found.")
|
|
|
+
|
|
|
+ def __get_key(self, infohash, mirror):
|
|
|
+ hasher = hashlib.sha256()
|
|
|
+ hasher.update(infohash.encode())
|
|
|
+ res = hasher.digest()
|
|
|
+
|
|
|
+ if(mirror):
|
|
|
+ hasher = hashlib.sha256()
|
|
|
+ hasher.update(res)
|
|
|
+ res = hasher.digest()
|
|
|
+
|
|
|
+ return res
|
|
|
+
|