Exemplo n.º 1
0
 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)
Exemplo n.º 2
0
    def update_torrent_info_from_rpc_to_db(self,
                                           last_id_db=None,
                                           force_check=False):
        """
        Sync torrent's id from transmission to database,
        List Start on last check id,and will return the max id as the last check id.
        """
        torrent_list = tc.get_torrents()  # Cache the torrent list
        new_torrent_list = [
            t for t in torrent_list if t.id > self.last_id_check
        ]
        if new_torrent_list:
            last_id_now = max([t.id for t in new_torrent_list])
            if last_id_db is None:
                last_id_db = db.get_max_in_seed_list(
                    column_list=db.col_seed_list[2:])
            Logger.debug("Max tid, transmission: {tr}, database: {db}".format(
                tr=last_id_now, db=last_id_db))

            if not force_check:  # Normal Update
                Logger.info(
                    "Some new torrents were add to transmission, Sync to db~")
                for i in new_torrent_list:  # Upsert the new torrent
                    db.upsert_seed_list(self._get_torrent_info(i))

            elif int(last_id_now) != int(
                    last_id_db
            ):  # Check the torrent 's record between tr and db
                total_num_in_tr = len(set([t.name for t in torrent_list]))
                total_num_in_db = db.exec(
                    sql="SELECT COUNT(*) FROM `seed_list`")[0]
                if int(total_num_in_tr) >= int(total_num_in_db):
                    Logger.info("Upsert the whole torrent id to database.")
                    for t in torrent_list:  # Upsert the whole torrent
                        db.upsert_seed_list(self._get_torrent_info(t))
                else:
                    Logger.error(
                        "The torrent list didn't match with db-records, Clean the whole \"seed_list\" for safety."
                    )
                    db.exec(sql="DELETE FROM `seed_list` WHERE 1"
                            )  # Delete all line from seed_list
                    self.update_torrent_info_from_rpc_to_db(last_id_db=0)

            self.last_id_check = last_id_now
        else:
            Logger.debug("No new torrent(s), Return with nothing to do.")
        return self.last_id_check
Exemplo n.º 3
0
 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)
Exemplo n.º 4
0
    def reseeder_feed(self, dl_torrent):
        pre_reseeder_list = self.get_pre_reseeder_list()
        tname = dl_torrent.name
        cow = db.exec(
            "SELECT * FROM `seed_list` WHERE `download_id`='{did}'".format(
                did=dl_torrent.id),
            r_dict=True)

        reseed_status = False
        for pat in pattern_group:
            search = re.search(pat, tname)
            if search:
                logging.debug("The search group dict: {gr}".format(
                    gr=search.groupdict()))
                for reseeder in [
                        r for r in pre_reseeder_list
                        if int(cow[r.db_column]) == 0
                ]:  # Site feed
                    try:
                        tag = reseeder.torrent_feed(torrent=dl_torrent,
                                                    name_pattern=search)
                    except Exception as e:
                        logging.critical(
                            "{}, Will start A reseeder online check soon.".
                            format(e.args[0]))
                        Thread(target=self._online_check, daemon=True).start()
                        pass
                    else:
                        db.upsert_seed_list((tag, tname, reseeder.db_column))
                reseed_status = True
                break

        if not reseed_status:  # Update seed_id == -1 if no matched pattern
            logging.warning(
                "No match pattern,Mark \"{}\" As Un-reseed torrent,Stop watching."
                .format(tname))
            for reseeder in pre_reseeder_list:
                db.upsert_seed_list((-1, tname, reseeder.db_column))
Exemplo n.º 5
0
    def torrent_feed(self, torrent):
        torrent = self._get_torrent(torrent)
        reseed_tag, = db.exec(
            "SELECT `{}` FROM `seed_list` WHERE `download_id` = {}".format(self.db_column, torrent.id)
        )

        if reseed_tag in [None, 0, "0"] and reseed_tag not in [-1, "-1"]:
            # It means that the pre-reseed torrent in this site is not reseed before,
            # And this torrent not marked as an un-reseed torrent.
            self._assist_delay()
            Logger.info("Autoseed-{mo} Get A feed torrent: {na}".format(mo=self.name, na=torrent.name))

            reseed_tag = -1
            try:
                reseed_tag = self.torrent_reseed(torrent)
            except Exception as e:  # TODO 针对不同的Error情况做不同的更新(e.g. 因为网络问题则置0,其他情况置1)
                err_name = type(e).__name__
                Logger.error(
                    "Reseed not success in Site: {} for torrent: {}, "
                    "With Exception: {}, {}".format(self.name, torrent.name, err_name, e)
                )
            finally:
                db.upsert_seed_list((reseed_tag, torrent.name, self.db_column))
Exemplo n.º 6
0
    def torrent_feed(self, torrent):
        torrent = self._get_torrent(torrent)
        reseed_tag, = db.exec(
            "SELECT `{}` FROM `seed_list` WHERE `download_id` = {}".format(self.db_column, torrent.id)
        )

        if reseed_tag in [None, 0, "0"] and reseed_tag not in [-1, "-1"]:
            # It means that the pre-reseed torrent in this site is not reseed before,
            # And this torrent not marked as an un-reseed torrent.
            self._assist_delay()
            Logger.info("Autoseed-{mo} Get A feed torrent: {na}".format(mo=self.name, na=torrent.name))

            reseed_tag = -1
            try:
                reseed_tag = self.torrent_reseed(torrent)
            except Exception as e:  # TODO 针对不同的Error情况做不同的更新(e.g. 因为网络问题则置0,其他情况置1)
                err_name = type(e).__name__
                Logger.error(
                    "Reseed not success in Site: {} for torrent: {}, "
                    "With Exception: {}, {}".format(self.name, torrent.name, err_name, e)
                )
            finally:
                db.upsert_seed_list((reseed_tag, torrent.name, self.db_column))
Exemplo n.º 7
0
    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))
Exemplo n.º 8
0
 def _shut_unreseeder_db():
     Logger.debug("Set un-reseeder's column into -1.")
     for tracker in unactive_tracker_list:  # Set un_reseed column into -1
         db.exec(
             sql="UPDATE `seed_list` SET `{cow}` = -1 WHERE `{cow}` = 0 "
             .format(cow=tracker))
Exemplo n.º 9
0
 def _shut_unreseeder_db(self):
     for tracker in self.unactive_tracker_list:  # Set un_reseed column into -1
         db.exec(
             sql="UPDATE `seed_list` SET `{cow}` = -1 WHERE `{cow}` = 0 ".
             format(cow=tracker))
Exemplo n.º 10
0
    def _del_torrent_with_db(self):
        """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."
        )

        time_now = time.time()
        t_all_list = tc.get_torrents()
        t_name_list = set(map(lambda x: x.name, t_all_list))

        for t_name in t_name_list:
            t_list = list(filter(lambda x: x.name == t_name, t_all_list))
            t_list_len = len(t_list)
            t_list_stop = 0
            for t in t_list:
                if t.status == "stopped":
                    t_list_stop += 1
                    continue

                _tid, _tname, _tracker = self._get_torrent_info(t)

                # 0 means OK, 1 means tracker warning, 2 means tracker error, 3 means local error.
                if t.error > 1:
                    tc.stop_torrent(t.id)
                    Logger.warning(
                        "Torrent Error, Torrent({tid}) \"{name}\" in Tracker \"{tracker}\" now stop, "
                        "Error code : {code} {msg}."
                        "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,
                                  code=t.error,
                                  msg=t.errorString))

                if int(time_now - t.addedDate
                       ) > TIME_TORRENT_KEEP_MIN:  # At least seed time
                    if setting.pre_delete_judge(torrent=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 t_list_stop == t_list_len:  # Delete torrents with it's data and db-records
                Logger.info(
                    "All torrents of \"{0}\" reach target, Will DELETE them soon."
                    .format(t_name))
                tid_list = map(lambda x: x.id, t_list)
                for tid in tid_list:
                    tc.remove_torrent(tid, delete_data=True)
                db.exec("DELETE FROM `seed_list` WHERE `title` = %s",
                        (t_name, ))