def reseeders_update(self): """ Get the pre-reseed list from database. And sent those un-reseed torrents to each reseeder depend on it's download status. """ pre_reseeder_list = self.get_online_reseeders() pre_cond = " OR ".join(["`{}`=0".format(i.db_column) for i in pre_reseeder_list]) result = db.exec("SELECT * FROM `seed_list` WHERE `download_id` != 0 AND ({})".format(pre_cond), r_dict=True, fetch_all=True) for t in result: # Traversal all un-reseed list try: dl_torrent = tc.get_torrent(t["download_id"]) except KeyError: # Un-exist pre-reseed torrent Logger.error("The pre-reseed Torrent: \"{0}\" isn't found in result, " "It's db-record will be deleted soon.".format(t["title"])) self._del_torrent_with_db(rid=t["id"]) if t["id"] in self.downloading_torrent_id_queue: self.downloading_torrent_id_queue.remove(t["id"]) else: tname = dl_torrent.name if int(dl_torrent.progress) is 100: # Get the download progress in percent. Logger.info("New completed torrent: \"{name}\" , Judge reseed or not.".format(name=tname)) for reseeder in pre_reseeder_list: Thread(target=reseeder.torrent_feed, args=(dl_torrent,), name="Thread-{}".format(reseeder.model_name()), daemon=True).start() # reseeder.torrent_feed(torrent=dl_torrent) if dl_torrent.id in self.downloading_torrent_id_queue: self.downloading_torrent_id_queue.remove(dl_torrent.id) elif dl_torrent.id in self.downloading_torrent_id_queue: pass # Wait until this torrent download completely. else: Logger.warning("Torrent:\"{name}\" is still downloading, Wait......".format(name=tname)) self.downloading_torrent_id_queue.append(dl_torrent.id)
def _get_torrent(torrent): """ Build-in function to get torrent class by it's id. :param torrent: int or class transmissionrpc.Torrent :return: class transmissionrpc.Torrent """ if isinstance(torrent, int): torrent = tc.get_torrent(torrent) return torrent
def _del_torrent_with_db(self, rid=None): """Delete torrent(both download and reseed) with data from transmission and database""" Logger.debug("Begin torrent's status check. If reach condition you set, You will get a warning.") if rid: sql = "SELECT * FROM `seed_list` WHERE `id`={}".format(rid) else: sql = "SELECT * FROM `seed_list`" time_now = time.time() for cow in db.exec(sql=sql, r_dict=True, fetch_all=True): sid = cow.pop("id") s_title = cow.pop("title") err = 0 reseed_list = [] torrent_id_list = [tid for tracker, tid in cow.items() if tid > 0] for tid in torrent_id_list: try: # Ensure torrent exist reseed_list.append(tc.get_torrent(torrent_id=tid)) except KeyError: # Mark err when the torrent is not exist. err += 1 delete = False if rid: delete = True Logger.warning("Force Delete. Which name: {}, Affect torrents: {}".format(s_title, torrent_id_list)) elif err is 0: # It means all torrents in this cow are exist,then check these torrent's status. reseed_stop_list = [] for t in reseed_list: if int(time_now - t.addedDate) > TIME_TORRENT_KEEP_MIN: # At least seed time if t.status == "stopped": # Mark the stopped torrent reseed_stop_list.append(t) elif setting.pre_delete_judge(torrent=t): _tid, _tname, _tracker = self._get_torrent_info(t) tc.stop_torrent(t.id) Logger.warning( "Reach Target you set, Torrent({tid}) \"{name}\" in Tracker \"{tracker}\" now stop, " "With Uploaded {si:.2f} MiB, Ratio {ro:.2f} , Keep time {ho:.2f} h." "".format(tid=_tid, name=_tname, tracker=_tracker, si=t.uploadedEver / 1024 / 1024, ro=t.uploadRatio, ho=(time.time() - t.startDate) / 60 / 60) ) if len(reseed_list) == len(reseed_stop_list): delete = True Logger.info("All torrents of \"{0}\" reach target, Will DELETE them soon.".format(s_title)) else: delete = True Logger.error("Some Torrents (\"{name}\", {er} of {co}) may not found, " "Delete all it's records from db".format(name=s_title, er=err, co=len(torrent_id_list))) if delete: # Delete torrents with it's data and db-records for tid in torrent_id_list: tc.remove_torrent(tid, delete_data=True) db.exec(sql="DELETE FROM `seed_list` WHERE `id` = {0}".format(sid))
def _get_torrent_info(t) -> tuple: """ Get torrent's information about tid, name and it's main tracker host. For main tracker host,if it is not in whole_tracker_list,will be rewrite to "download_id" :param t: int or class 'transmissionrpc.torrent.Torrent' :return: (tid, name, tracker) """ if isinstance(t, int): t = tc.get_torrent(t) # Return class 'transmissionrpc.torrent.Torrent' try: tracker = re.search(r"p[s]?://(?P<host>.+?)/", t.trackers[0]["announce"]).group("host") if tracker not in db.col_seed_list: raise AttributeError("Not reseed tracker.") except AttributeError: tracker = "download_id" # Rewrite tracker return t.id, t.name, tracker
def reseeders_update(self): """Get the pre-reseed list from database.""" pre_cond = " OR ".join([ "`{}`=0".format(i.db_column) for i in self.get_pre_reseeder_list() ]) result = db.exec( "SELECT * FROM `seed_list` WHERE `download_id` != 0 AND ({})". format(pre_cond), r_dict=True, fetch_all=True) for t in result: # Traversal all un-reseed list try: dl_torrent = tc.get_torrent(t["download_id"]) except KeyError: # Un-exist pre-reseed torrent logging.error( "The pre-reseed Torrent: \"{0}\" isn't found in result," " It's db-record will be deleted soon".format(t["title"])) Thread(target=self._del_torrent_with_db, args={ "rid": t["id"] }, daemon=True).start() else: tname = dl_torrent.name if int(dl_torrent.progress ) is 100: # Get the download progress in percent. logging.info( "New completed torrent: \"{name}\" ,Judge reseed or not." .format(name=tname)) self.reseeder_feed(dl_torrent=dl_torrent) if dl_torrent.id in self.downloading_torrent_id_queue: self.downloading_torrent_id_queue.remove(dl_torrent.id) elif dl_torrent.id in self.downloading_torrent_id_queue: pass # Wait until this torrent download completely. else: logging.warning( "Torrent:\"{name}\" is still downloading,Wait......". format(name=tname)) self.downloading_torrent_id_queue.append(dl_torrent.id)
def _get_torrent(torrent): if isinstance(torrent, int): torrent = tc.get_torrent(torrent) return torrent