Beispiel #1
0
def clear(update: Update, context: CallbackContext) -> None:
	"""
	Limpia los torrents finalizados de la cola de descarga
	"""
	FINISHED_STATES = [
		'uploading',
		'pausedUP',
		'stalledUP',
		'queuedUP',
	]
	if int(update.effective_chat.id) not in config.ALLOWED_IDS:
		not_allowed(update)
	else:
		logger.info(' Un usuario CON permiso ha ejecutado /clear')
		qb = Client(config.TORRENT['server'])
		qb.login(config.TORRENT['user'], config.TORRENT['pass'])
		torrents = qb.torrents()
		del_torrents = len(torrents)
		for torrent in torrents:
			if torrent['state'] in FINISHED_STATES:
				qb.delete(torrent['hash'])
		torrents = qb.torrents()
		del_torrents = del_torrents - len(torrents)
		qb.logout()
		logger.info('{} torrents han sido eliminados de la cola'.format(del_torrents))
		if del_torrents != 0:
			update.message.reply_text('Borrados todos los torrents finalizados')
		else:
			update.message.reply_text('No se ha eliminado ningún torrent de la cola')
                                       pathMapping=path_mapping)
    elif settings.qBittorrent['bypass'].startswith(label):
        log.info("Bypassing any further processing as per category.")

    # Run a qbittorrent action after conversion.
    if settings.qBittorrent['actionafter']:
        # currently only support resuming or deleting torrent
        if settings.qBittorrent['actionafter'] == 'resume':
            log.debug("Sending action %s to qBittorrent" %
                      settings.qBittorrent['actionafter'])
            qb.resume(torrent_hash)
        elif settings.qBittorrent['actionafter'] == 'delete':
            # this will delete the torrent from qBittorrent but it WILL NOT delete the data
            log.debug("Sending action %s to qBittorrent" %
                      settings.qBittorrent['actionafter'])
            qb.delete(torrent_hash)
        elif settings.qBittorrent['actionafter'] == 'deletedata':
            # this will delete the torrent from qBittorrent and delete data
            log.debug("Sending action %s to qBittorrent" %
                      settings.qBittorrent['actionafter'])
            qb.delete_permanently(torrent_hash)

    if delete_dir:
        if os.path.exists(delete_dir):
            try:
                os.rmdir(delete_dir)
                log.debug("Successfully removed tempoary directory %s." %
                          delete_dir)
            except:
                log.exception("Unable to delete temporary directory")
except:
class QBittorrentDownloader:
    """
    Class that uses the qBittorrent Server API to download torrents
    """
    def __init__(self, url: str, username: str, password: str,
                 download_dir: str):
        """

        :param url:
        :param username:
        :param password:
        :param download_dir:
        """
        self.client = Client(url)
        self.client.login(username, password)
        self.download_dir = download_dir

    @classmethod
    def from_config(cls) -> "QBittorrentDownloader":
        """
        :return: A QBittorrentDownloader object based on the stored
                 configuration files
        """
        config = Config.load()
        return cls(config.qbittorrent_address, config.qbittorrent_username,
                   config.qbittorrent_password,
                   config.qbittorrent_download_dir)

    def download(self, torrents: List[TorrentDownload]):
        """
        Downloads a list of torrent files
        :param torrents: The torrents to download
        :return: None
        """
        for torrent in torrents:
            torrent_info = torrent.torrent_info

            print(f"Downloading Torrent: {torrent_info.filename}")

            if torrent_info.magnet_link is not None:
                self.client.download_from_link(torrent_info.magnet_link)
            else:
                assert torrent_info.torrent_file is not None
                torrent_file = torrent_info.torrent_file
                if not os.path.isfile(torrent_file):
                    torrent_file = "/tmp/torrentdltemp.torrent"
                    content = requests.get(torrent_info.torrent_file).content
                    with open(torrent_file, "wb") as f:
                        f.write(content)
                with open(torrent_file, "rb") as f:
                    self.client.download_from_file(f)

            time.sleep(1)

            while len(self.client.torrents()) > 0:
                for active in self.client.torrents():
                    if active["state"] not in [
                            "downloading", "metaDL", "stalledDL"
                    ]:
                        print("Done.     ")
                        torrent_path = os.path.join(self.download_dir,
                                                    active["name"])

                        if os.path.isdir(torrent_path):
                            children = [
                                os.path.join(torrent_path, x)
                                for x in os.listdir(torrent_path)
                            ]
                            children.sort(key=lambda x: os.path.getsize(x),
                                          reverse=True)
                            torrent_path = children[0]
                            ext = torrent_path.rsplit(".", 1)[1]
                            torrent.add_extension(ext)

                        self.client.delete(active["hash"])

                        if os.path.isdir(torrent.destination):
                            shutil.move(
                                torrent_path,
                                os.path.join(torrent.destination,
                                             os.path.basename(torrent_path)))
                        else:
                            shutil.move(torrent_path, torrent.destination)
                    else:
                        print(f"{(100 * active['progress']):.2f}%", end="\r")

                time.sleep(1)
Beispiel #4
0
class QBittorrentClient(BTClientBase):
    def __init__(self,
                 rpc_address,
                 rpc_port,
                 username,
                 password,
                 config={'use_https': False}):
        self.rpc_address = rpc_address
        self.rpc_port = rpc_port
        self.username = username
        self.password = password

        if 'use_https' in config:
            self.use_https = config['use_https']
        else:
            self.use_https = False

        self.rpc_addr = str(rpc_address) + ':' + str(rpc_port) + '/'
        if self.use_https:
            self.rpc_addr = 'https://' + self.rpc_addr
        else:
            self.rpc_addr = 'http://' + self.rpc_addr

        self.client = Client(self.rpc_addr)
        self.connected = False

    def connect(self):
        login_ret = self.client.login(username=self.username,
                                      password=self.password)

        if login_ret is None:
            self.connected = True
            ret = ClientRet(ret_type=2)
        else:
            ret = ClientRet(ret_type=-2)

        return ret

    def add_torrent(self, torrent_path, download_path=None):
        if not self.connected:
            return ClientRet(ret_type=-2)

        abs_torrent_path = str(Path(torrent_path).resolve())
        buf = open(abs_torrent_path, 'rb')

        if download_path is None:
            try:
                api_ret = self.client.download_from_file(buf)
                if 'Ok.' in api_ret:
                    buf.close()
                    info_hash = torf.Torrent.read(abs_torrent_path).infohash

                    ret = ClientRet(ret_type=3, ret_value=info_hash)
                else:
                    ret = ClientRet(ret_type=-3)
            except:
                ret = ClientRet(ret_type=-3)
            finally:
                return ret
        else:
            try:
                abs_download_path = str(Path(download_path).resolve())
                api_ret = self.client.download_from_file(
                    buf, save_path=abs_download_path)
                if 'Ok.' in api_ret:
                    buf.close()
                    info_hash = torf.Torrent.read(abs_torrent_path).infohash

                    ret = ClientRet(ret_type=3, ret_value=info_hash)
                else:
                    ret = ClientRet(ret_type=-3)
            except:
                ret = ClientRet(ret_type=-3)
            finally:
                return ret

    def list_torrents(self):
        if not self.connected:
            return ClientRet(ret_type=-2)

        torrent_list = self.client.torrents()
        session_status = {}
        for torrent in torrent_list:
            is_finished = math.isclose(torrent['progress'], 1)
            torrent_status = TorrentStatus(torrent_id=torrent['hash'],
                                           is_finished=is_finished,
                                           name=torrent['name'])

            session_status[torrent['hash']] = torrent_status

        ret = ClientRet(ret_type=4, ret_value=session_status)

        return ret

    def get_torrent_status(self, idx):
        if not self.connected:
            return ClientRet(ret_type=-2)

        tlist = self.client.torrents()
        for torrent in tlist:
            if idx == torrent[
                    'hash']:  # No progress info in get_torrent() method, really...
                is_finished = math.isclose(torrent['progress'], 1)
                torrent_status = TorrentStatus(torrent_id=torrent['hash'],
                                               is_finished=is_finished,
                                               name=torrent['name'])

                ret = ClientRet(ret_type=6, ret_value=torrent_status)
                return ret

        return ClientRet(ret_type=-6)

    def del_torrent(self, idx, remove_data=True):
        if not self.connected:
            return ClientRet(ret_type=-2)

        try:
            if remove_data:
                self.client.delete_permanently(idx)
            else:
                self.client.delete(idx)
            ret = ClientRet(ret_type=5)
        except:
            ret = ClientRet(ret_type=-5)
        finally:
            return ret

    def disconnect(self):
        if self.connected:
            self.client.logout()
            self.connected = False
        ret = ClientRet(ret_type=0)
        return ret
Beispiel #5
0
                time.sleep(10)
                #darn, the pause function isn't working too well. put this here for a cheap fix. todo: make this more stable.
                qb.pause(tor[0]['hash'])
                while (int(temp_cTime[0]) > 6):
                    t = time.localtime()
                    current_time = time.strftime("%H:%M:%S", t)
                    temp_cTime = current_time.split(':')
                    time.sleep(600)

                    #this is all very inefficient :(
                print('waking up...')
                qb.resume(tor[0]['hash'])
        if (tor[0]['progress']) == 1:
            print('Finished downloading ' + tor[0]['name'])
            qb.delete(tor[0]['hash'])
            magnetLinks.pop(0)
            searchAr.pop(0)
            searchDoc.truncate(0)
            magnetFile.truncate(0)
            for it in searchAr:
                searchDoc.write(it + '\n')
            for it in magnetLinks:
                magnetFile.write(it + '\n')
            #now i Need to make it so that the folder that gets downloaded, the mp4
            downloading = False
        else:
            time.sleep(60)
searchDoc.close()
magnetFile.close()
print('finished')
Beispiel #6
0
class AutoTorrent:
    def __init__(self):
        self.init_google_sheets()
        self.init_qb()
        self.downloading = {}

    def init_google_sheets(self):
        creds = None
        # The file token.pickle stores the user's access and refresh tokens, and is
        # created automatically when the authorization flow completes for the first
        # time.
        if os.path.exists('token.pickle'):
            with open('token.pickle', 'rb') as token:
                creds = pickle.load(token)
        # If there are no (valid) credentials available, let the user log in.
        if not creds or not creds.valid:
            if creds and creds.expired and creds.refresh_token:
                creds.refresh(Request())
            else:
                flow = InstalledAppFlow.from_client_secrets_file(
                    'credentials.json', SCOPES)
                creds = flow.run_local_server(port=0)
            # Save the credentials for the next run
            with open('token.pickle', 'wb') as token:
                pickle.dump(creds, token)
        self.google_sheets = build('sheets', 'v4', credentials=creds)

    def init_qb(self):
        self.qb = TorrentClient("http://127.0.0.1:8080/")
        self.qb.login("admin", "adminadmin")

    def get_movies(self):
        sheet = self.google_sheets.spreadsheets()
        result = sheet.values().get(spreadsheetId=SPREADSHEET_ID,
                                    range=RANGE_NAME).execute()
        values = result.get('values', [])

        if not values:
            print('No data found.')
        filtered = filter(
            lambda m: m[0] in ["No Descargada", "Auto Descargando"] and
            (len(m) < 5 or m[4] not in ["No", "Pocos Seeds"]), values)
        movies = map(lambda m: Movie(m[1], m[2]), filtered)
        return movies

    def download_movie(self, movie):
        torrent = movie.get_torrent()
        if not torrent:
            print("    Torrent not found for {}. Skipping".format(movie))
            self.update_movie_yts(movie, "No")
            return
        magnet = torrent.magnet
        path = movie.local_path
        if not os.path.isdir(path):
            os.mkdir(path)
        self.qb.download_from_link(magnet, savepath=path)
        self.update_movie(movie, "Auto Descargando")
        for t in self.qb.torrents():
            if os.path.normpath(t["save_path"]) == os.path.normpath(path):
                torrent_hash = t["hash"]
                break
        self.downloading[torrent_hash] = movie
        print("    Started downloading {}".format(movie))

    def update_movie(self, movie, status):
        sheet = self.google_sheets.spreadsheets()
        result = sheet.values().get(spreadsheetId=SPREADSHEET_ID,
                                    range=RANGE_NAME).execute()
        values = list(result.get('values', []))
        for value in values:
            if value[1] == movie.name and int(value[2]) == movie.year:
                value[0] = status
        body = {'values': values}
        sheet.values().update(spreadsheetId=SPREADSHEET_ID,
                              range=RANGE_NAME,
                              valueInputOption=VALUE_INPUT_OPTION,
                              body=body).execute()

    def update_movie_yts(self, movie, yts):
        sheet = self.google_sheets.spreadsheets()
        result = sheet.values().get(spreadsheetId=SPREADSHEET_ID,
                                    range=RANGE_NAME).execute()
        values = list(result.get('values', []))
        for value in values:
            if value[1] == movie.name and int(value[2]) == movie.year:
                if len(value) == 4:
                    value.append(yts)
                else:
                    value[4] = yts
        body = {'values': values}
        sheet.values().update(spreadsheetId=SPREADSHEET_ID,
                              range=RANGE_NAME,
                              valueInputOption=VALUE_INPUT_OPTION,
                              body=body).execute()

    def should_download(self):
        current_torrents = len(self.qb.torrents(filter="downloading"))
        less_than_max = current_torrents < MAX_CONCURRENT_DOWNLOADS
        just_started = len(self.downloading) < MAX_CONCURRENT_DOWNLOADS
        return less_than_max or just_started

    def start(self):
        movies = self.get_movies()
        while True:
            sleep(1)
            self.clean_torrents()
            if not self.should_download():
                continue
            movie = next(movies)
            print(movie)
            self.download_movie(movie)

    def clean_torrents(self):
        timed_out = []
        done = []
        for torrent in self.qb.torrents():
            if torrent["progress"] == 1:
                done.append(torrent["hash"])
            elif is_timed_out(torrent):
                timed_out.append(torrent["hash"])
        for h in timed_out:
            if h not in self.downloading:
                continue
            movie = self.downloading[h]
            print("{} timed out. Removing".format(movie))
            self.update_movie(movie, "No Descargada")
            self.update_movie_yts(movie, "Pocos Seeds")
            self.qb.delete(h)
            movie.delete_folder()
        for h in done:
            if h not in self.downloading:
                continue
            movie = self.downloading[h]
            self.update_movie(movie, "Descargada")
            self.qb.delete(h)
            movie.clean_folder()
            movie.move_to_drive()
            print("{} finished downloading. Moving to Google Drive".format(
                movie))
Beispiel #7
0
                        savePath = torrent['save_path']
                        nameFile = torrent['name']
                        magnet_uri = torrent['magnet_uri']

                        SLog.LogInfo(
                            "magnet_uri     : [{}]".format(magnet_uri))
                        SLog.LogInfo("torrent name   : [{}]".format(nameFile))
                        SLog.LogInfo("save path      : [{}]".format(savePath))

                        if not Options['dry-run']:
                            # delete torrent file du serveur qbitorrent
                            SLog.LogInfo("-" * 10)
                            SLog.LogInfo(
                                "del qbitorrent : [{}]".format(nameFile))
                            SLog.LogInfo("-" * 10)
                            qb.delete(hashFile)
            else:
                SLog.LogCritical("Bad hash   : [{}]".format(hashFile))
                SLog.LogCritical(
                    "-_|_-                                         -_|_-")
                SLog.LogCritical(
                    "      -_|_-                             -_|_-")
                SLog.LogCritical("            -_|_- /!\\          /!\\ -_|_-")
                SLog.LogCritical("                      ! exit !")
                SLog.LogCritical("            -_|_- \\|/          \\|/ -_|_-")
                SLog.LogCritical(
                    "      -_|_-                             -_|_-")
                SLog.LogCritical(
                    "-_|_-                                         -_|_-")
                sys.exit(1)