예제 #1
0
    def connect(self):
        if self.qb is not None:
            return self.qb

        url = cleanHost(self.conf("host"), protocol=True, ssl=False)

        if self.conf("username") and self.conf("password"):
            self.qb = QBittorrentClient(url, username=self.conf("username"), password=self.conf("password"))
        else:
            self.qb = QBittorrentClient(url)

        return self.qb
예제 #2
0
    def connect(self):
        if self.qb is not None:
            self.qb.logout()

        url = cleanHost(self.conf('host'), protocol = True, ssl = False)

        if self.conf('username') and self.conf('password'):
            self.qb = QBittorrentClient(url)
            self.qb.login(username=self.conf('username'), password=self.conf('password'))
        else:
            self.qb = QBittorrentClient(url)

        return self.qb._is_authenticated
예제 #3
0
    def connect(self, reconnect = False):
        if not reconnect and self.qb is not None:
            return self.qb

        url = cleanHost(self.conf('host'), protocol = True, ssl = False)
        
        if self.conf('username') and self.conf('password'):
            self.qb = QBittorrentClient(url)
            self.qb.login(username=self.conf('username'),password=self.conf('password'))
        else:
            self.qb = QBittorrentClient(url)

        return self.qb
예제 #4
0
    def connect(self):
        if self.qb is not None:
            self.qb.logout()

        url = cleanHost(self.conf('host'), protocol = True, ssl = False)

        if self.conf('username') and self.conf('password'):
            self.qb = QBittorrentClient(url)
            self.qb.login(username=self.conf('username'), password=self.conf('password'))
        else:
            self.qb = QBittorrentClient(url)

        return self.qb._is_authenticated
예제 #5
0
    def connect(self):
        if self.qb is not None:
            return self.qb

        url = cleanHost(self.conf('host'), protocol=True, ssl=False)

        if self.conf('username') and self.conf('password'):
            self.qb = QBittorrentClient(url,
                                        username=self.conf('username'),
                                        password=self.conf('password'))
        else:
            self.qb = QBittorrentClient(url)

        return self.qb
예제 #6
0
class qBittorrent(DownloaderBase):

    protocol = ['torrent', 'torrent_magnet']
    qb = None

    def __init__(self):
        super(qBittorrent, self).__init__()

    def connect(self):
        if self.qb is not None:
            return self.qb

        url = cleanHost(self.conf('host'), protocol = True, ssl = False)

        if self.conf('username') and self.conf('password'):
            self.qb = QBittorrentClient(
                url,
                username = self.conf('username'),
                password = self.conf('password')
            )
        else:
            self.qb = QBittorrentClient(url)

        return self.qb

    def test(self):
        """ Check if connection works
        :return: bool
        """

        if self.connect():
            return True

        return False

    def download(self, data = None, media = None, filedata = None):
        """ Send a torrent/nzb file to the downloader

        :param data: dict returned from provider
            Contains the release information
        :param media: media dict with information
            Used for creating the filename when possible
        :param filedata: downloaded torrent/nzb filedata
            The file gets downloaded in the searcher and send to this function
            This is done to have failed checking before using the downloader, so the downloader
            doesn't need to worry about that
        :return: boolean
            One faile returns false, but the downloaded should log his own errors
        """

        if not media: media = {}
        if not data: data = {}

        log.debug('Sending "%s" to qBittorrent.', (data.get('name')))

        if not self.connect():
            return False

        if not filedata and data.get('protocol') == 'torrent':
            log.error('Failed sending torrent, no data')
            return False


        if data.get('protocol') == 'torrent_magnet':
            filedata = self.magnetToTorrent(data.get('url'))

            if filedata is False:
                return False

            data['protocol'] = 'torrent'

        info = bdecode(filedata)["info"]
        torrent_hash = sha1(bencode(info)).hexdigest()

        # Convert base 32 to hex
        if len(torrent_hash) == 32:
            torrent_hash = b16encode(b32decode(torrent_hash))

        # Send request to qBittorrent
        try:
            self.qb.add_file(filedata)

            return self.downloadReturnId(torrent_hash)
        except Exception as e:
            log.error('Failed to send torrent to qBittorrent: %s', e)
            return False

    def getTorrentStatus(self, torrent):

        if torrent.state in ('uploading', 'queuedUP', 'stalledUP'):
            return 'seeding'

        if torrent.progress == 1:
            return 'completed'

        return 'busy'

    def getAllDownloadStatus(self, ids):
        """ Get status of all active downloads

        :param ids: list of (mixed) downloader ids
            Used to match the releases for this downloader as there could be
            other downloaders active that it should ignore
        :return: list of releases
        """

        log.debug('Checking qBittorrent download status.')

        if not self.connect():
            return []

        try:
            torrents = self.qb.get_torrents()

            release_downloads = ReleaseDownloadList(self)

            for torrent in torrents:
                if torrent.hash in ids:
                    torrent.update_general() # get extra info
                    torrent_filelist = torrent.get_files()

                    torrent_files = []
                    torrent_dir = os.path.join(torrent.save_path, torrent.name)

                    if os.path.isdir(torrent_dir):
                        torrent.save_path = torrent_dir

                    if len(torrent_filelist) > 1 and os.path.isdir(torrent_dir): # multi file torrent, path.isdir check makes sure we're not in the root download folder
                        for root, _, files in os.walk(torrent.save_path):
                            for f in files:
                                torrent_files.append(sp(os.path.join(root, f)))

                    else: # multi or single file placed directly in torrent.save_path
                        for f in torrent_filelist:
                            file_path = os.path.join(torrent.save_path, f.name)
                            if os.path.isfile(file_path):
                                torrent_files.append(sp(file_path))

                    release_downloads.append({
                        'id': torrent.hash,
                        'name': torrent.name,
                        'status': self.getTorrentStatus(torrent),
                        'seed_ratio': torrent.ratio,
                        'original_status': torrent.state,
                        'timeleft': torrent.progress * 100 if torrent.progress else -1, # percentage
                        'folder': sp(torrent.save_path),
                        'files': torrent_files
                    })

            return release_downloads

        except Exception as e:
            log.error('Failed to get status from qBittorrent: %s', e)
            return []

    def pause(self, release_download, pause = True):
        if not self.connect():
            return False

        torrent = self.qb.get_torrent(release_download['id'])
        if torrent is None:
            return False

        if pause:
            return torrent.pause()
        return torrent.resume()

    def removeFailed(self, release_download):
        log.info('%s failed downloading, deleting...', release_download['name'])
        return self.processComplete(release_download, delete_files = True)

    def processComplete(self, release_download, delete_files):
        log.debug('Requesting qBittorrent to remove the torrent %s%s.',
                  (release_download['name'], ' and cleanup the downloaded files' if delete_files else ''))

        if not self.connect():
            return False

        torrent = self.qb.find_torrent(release_download['id'])

        if torrent is None:
            return False

        if delete_files:
            torrent.delete() # deletes torrent with data
        else:
            torrent.remove() # just removes the torrent, doesn't delete data

        return True
예제 #7
0
class qBittorrent(DownloaderBase):

    protocol = ['torrent', 'torrent_magnet']
    qb = None

    def __init__(self):
        super(qBittorrent, self).__init__()

    def connect(self):
        if self.qb is not None:
            self.qb.logout()

        url = cleanHost(self.conf('host'), protocol = True, ssl = False)

        if self.conf('username') and self.conf('password'):
            self.qb = QBittorrentClient(url)
            self.qb.login(username=self.conf('username'), password=self.conf('password'))
        else:
            self.qb = QBittorrentClient(url)

        return self.qb._is_authenticated

    def test(self):
        """ Check if connection works
        :return: bool
        """
        return self.connect()

    def download(self, data = None, media = None, filedata = None):
        """ Send a torrent/nzb file to the downloader

        :param data: dict returned from provider
            Contains the release information
        :param media: media dict with information
            Used for creating the filename when possible
        :param filedata: downloaded torrent/nzb filedata
            The file gets downloaded in the searcher and send to this function
            This is done to have failed checking before using the downloader, so the downloader
            doesn't need to worry about that
        :return: boolean
            One fail returns false, but the downloader should log his own errors
        """

        if not media: media = {}
        if not data: data = {}

        log.debug('Sending "%s" to qBittorrent.', (data.get('name')))

        if not self.connect():
            return False

        if not filedata and data.get('protocol') == 'torrent':
            log.error('Failed sending torrent, no data')
            return False

        if data.get('protocol') == 'torrent_magnet':
            # Send request to qBittorrent directly as a magnet
            try:
                self.qb.download_from_link(data.get('url'), label=self.conf('label'))
                torrent_hash = re.findall('urn:btih:([\w]{32,40})', data.get('url'))[0].upper()
                log.info('Torrent [magnet] sent to QBittorrent successfully.')
                return self.downloadReturnId(torrent_hash)

            except Exception as e:
                log.error('Failed to send torrent to qBittorrent: %s', e)
                return False

        if data.get('protocol')  == 'torrent':
             info = bdecode(filedata)["info"]
             torrent_hash = sha1(bencode(info)).hexdigest()

             # Convert base 32 to hex
             if len(torrent_hash) == 32:
                torrent_hash = b16encode(b32decode(torrent_hash))

             # Send request to qBittorrent
             try:
                self.qb.download_from_file(filedata, label=self.conf('label'))
                log.info('Torrent [file] sent to QBittorrent successfully.')
                return self.downloadReturnId(torrent_hash)
             except Exception as e:
                log.error('Failed to send torrent to qBittorrent: %s', e)
                return False

    def getTorrentStatus(self, torrent):

        if torrent['state'] in ('uploading', 'queuedUP', 'stalledUP'):
            return 'seeding'

        if torrent['progress'] == 1:
            return 'completed'

        return 'busy'

    def getAllDownloadStatus(self, ids):
        """ Get status of all active downloads

        :param ids: list of (mixed) downloader ids
            Used to match the releases for this downloader as there could be
            other downloaders active that it should ignore
        :return: list of releases
        """

        log.debug('Checking qBittorrent download status.')

        if not self.connect():
            return []

        try:
            torrents = self.qb.torrents(status='all', label=self.conf('label'))

            release_downloads = ReleaseDownloadList(self)

            for torrent in torrents:
                if torrent['hash'] in ids:
                    torrent_filelist = self.qb.get_torrent_files(torrent['hash'])

                    torrent_files = []
                    torrent_dir = os.path.join(torrent['save_path'], torrent['name'])

                    if os.path.isdir(torrent_dir):
                        torrent['save_path'] = torrent_dir

                    if len(torrent_filelist) > 1 and os.path.isdir(torrent_dir): # multi file torrent, path.isdir check makes sure we're not in the root download folder
                        for root, _, files in os.walk(torrent['save_path']):
                            for f in files:
                                torrent_files.append(sp(os.path.join(root, f)))

                    else: # multi or single file placed directly in torrent.save_path
                        for f in torrent_filelist:
                            file_path = os.path.join(torrent['save_path'], f['name'])
                            if os.path.isfile(file_path):
                                torrent_files.append(sp(file_path))

                    release_downloads.append({
                        'id': torrent['hash'],
                        'name': torrent['name'],
                        'status': self.getTorrentStatus(torrent),
                        'seed_ratio': torrent['ratio'],
                        'original_status': torrent['state'],
                        'timeleft': str(timedelta(seconds = torrent['eta'])),
                        'folder': sp(torrent['save_path']),
                        'files': torrent_files
                    })

            return release_downloads

        except Exception as e:
            log.error('Failed to get status from qBittorrent: %s', e)
            return []

    def pause(self, release_download, pause = True):
        if not self.connect():
            return False

        torrent = self.qb.get_torrent(release_download['id'])
        if torrent is None:
            return False

        if pause:
            return self.qb.pause(release_download['id'])
        return self.qb.resume(release_download['id'])

    def removeFailed(self, release_download):
        log.info('%s failed downloading, deleting...', release_download['name'])
        return self.processComplete(release_download, delete_files = True)

    def processComplete(self, release_download, delete_files):
        log.debug('Requesting qBittorrent to remove the torrent %s%s.',
                  (release_download['name'], ' and cleanup the downloaded files' if delete_files else ''))

        if not self.connect():
            return False

        torrent = self.qb.get_torrent(release_download['id'])

        if torrent is None:
            return False

        if delete_files:
            self.qb.delete_permanently(release_download['id']) # deletes torrent with data
        else:
            self.qb.delete(release_download['id']) # just removes the torrent, doesn't delete data

        return True
예제 #8
0
class qBittorrent(DownloaderBase):

    protocol = ['torrent', 'torrent_magnet']
    qb = None

    def __init__(self):
        super(qBittorrent, self).__init__()

    def connect(self):
        if self.qb is not None:
            return self.qb

        url = cleanHost(self.conf('host'), protocol=True, ssl=False)

        if self.conf('username') and self.conf('password'):
            self.qb = QBittorrentClient(url,
                                        username=self.conf('username'),
                                        password=self.conf('password'))
        else:
            self.qb = QBittorrentClient(url)

        return self.qb

    def test(self):
        if self.connect():
            return True

        return False

    def download(self, data=None, media=None, filedata=None):
        if not media: media = {}
        if not data: data = {}

        log.debug('Sending "%s" to qBittorrent.', (data.get('name')))

        if not self.connect():
            return False

        if not filedata and data.get('protocol') == 'torrent':
            log.error('Failed sending torrent, no data')
            return False

        if data.get('protocol') == 'torrent_magnet':
            filedata = self.magnetToTorrent(data.get('url'))

            if filedata is False:
                return False

            data['protocol'] = 'torrent'

        info = bdecode(filedata)["info"]
        torrent_hash = sha1(bencode(info)).hexdigest()

        # Convert base 32 to hex
        if len(torrent_hash) == 32:
            torrent_hash = b16encode(b32decode(torrent_hash))

        # Send request to qBittorrent
        try:
            self.qb.add_file(filedata)

            return self.downloadReturnId(torrent_hash)
        except Exception as e:
            log.error('Failed to send torrent to qBittorrent: %s', e)
            return False

    def getTorrentStatus(self, torrent):

        if torrent.state in ('uploading', 'queuedUP', 'stalledUP'):
            return 'seeding'

        if torrent.progress == 1:
            return 'completed'

        return 'busy'

    def getAllDownloadStatus(self, ids):
        log.debug('Checking qBittorrent download status.')

        if not self.connect():
            return []

        try:
            torrents = self.qb.get_torrents()

            release_downloads = ReleaseDownloadList(self)

            for torrent in torrents:
                if torrent.hash in ids:
                    torrent.update_general()  # get extra info
                    torrent_filelist = torrent.get_files()

                    torrent_files = []
                    torrent_dir = os.path.join(torrent.save_path, torrent.name)

                    if os.path.isdir(torrent_dir):
                        torrent.save_path = torrent_dir

                    if len(torrent_filelist) > 1 and os.path.isdir(
                            torrent_dir
                    ):  # multi file torrent, path.isdir check makes sure we're not in the root download folder
                        for root, _, files in os.walk(torrent.save_path):
                            for f in files:
                                torrent_files.append(sp(os.path.join(root, f)))

                    else:  # multi or single file placed directly in torrent.save_path
                        for f in torrent_filelist:
                            file_path = os.path.join(torrent.save_path, f.name)
                            if os.path.isfile(file_path):
                                torrent_files.append(sp(file_path))

                    release_downloads.append({
                        'id':
                        torrent.hash,
                        'name':
                        torrent.name,
                        'status':
                        self.getTorrentStatus(torrent),
                        'seed_ratio':
                        torrent.ratio,
                        'original_status':
                        torrent.state,
                        'timeleft':
                        torrent.progress *
                        100 if torrent.progress else -1,  # percentage
                        'folder':
                        sp(torrent.save_path),
                        'files':
                        torrent_files
                    })

            return release_downloads

        except Exception as e:
            log.error('Failed to get status from qBittorrent: %s', e)
            return []

    def pause(self, release_download, pause=True):
        if not self.connect():
            return False

        torrent = self.qb.get_torrent(release_download['id'])
        if torrent is None:
            return False

        if pause:
            return torrent.pause()
        return torrent.resume()

    def removeFailed(self, release_download):
        log.info('%s failed downloading, deleting...',
                 release_download['name'])
        return self.processComplete(release_download, delete_files=True)

    def processComplete(self, release_download, delete_files):
        log.debug(
            'Requesting qBittorrent to remove the torrent %s%s.',
            (release_download['name'],
             ' and cleanup the downloaded files' if delete_files else ''))

        if not self.connect():
            return False

        torrent = self.qb.find_torrent(release_download['id'])

        if torrent is None:
            return False

        if delete_files:
            torrent.delete()  # deletes torrent with data
        else:
            torrent.remove()  # just removes the torrent, doesn't delete data

        return True
예제 #9
0
class qBittorrent(DownloaderBase):

    protocol = ["torrent", "torrent_magnet"]
    qb = None

    def __init__(self):
        super(qBittorrent, self).__init__()

    def connect(self):
        if self.qb is not None:
            return self.qb

        url = cleanHost(self.conf("host"), protocol=True, ssl=False)

        if self.conf("username") and self.conf("password"):
            self.qb = QBittorrentClient(url, username=self.conf("username"), password=self.conf("password"))
        else:
            self.qb = QBittorrentClient(url)

        return self.qb

    def test(self):
        if self.connect():
            return True

        return False

    def download(self, data=None, media=None, filedata=None):
        if not media:
            media = {}
        if not data:
            data = {}

        log.debug('Sending "%s" to qBittorrent.', (data.get("name")))

        if not self.connect():
            return False

        if not filedata and data.get("protocol") == "torrent":
            log.error("Failed sending torrent, no data")
            return False

        if data.get("protocol") == "torrent_magnet":
            filedata = self.magnetToTorrent(data.get("url"))

            if filedata is False:
                return False

            data["protocol"] = "torrent"

        info = bdecode(filedata)["info"]
        torrent_hash = sha1(bencode(info)).hexdigest()

        # Convert base 32 to hex
        if len(torrent_hash) == 32:
            torrent_hash = b16encode(b32decode(torrent_hash))

        # Send request to qBittorrent
        try:
            self.qb.add_file(filedata)

            return self.downloadReturnId(torrent_hash)
        except Exception as e:
            log.error("Failed to send torrent to qBittorrent: %s", e)
            return False

    def getTorrentStatus(self, torrent):

        if torrent.state in ("uploading", "queuedUP", "stalledUP"):
            return "seeding"

        if torrent.progress == 1:
            return "completed"

        return "busy"

    def getAllDownloadStatus(self, ids):
        log.debug("Checking qBittorrent download status.")

        if not self.connect():
            return []

        try:
            torrents = self.qb.get_torrents()

            release_downloads = ReleaseDownloadList(self)

            for torrent in torrents:
                if torrent.hash in ids:
                    torrent.update_general()  # get extra info
                    torrent_filelist = torrent.get_files()

                    torrent_files = []
                    torrent_dir = os.path.join(torrent.save_path, torrent.name)

                    if os.path.isdir(torrent_dir):
                        torrent.save_path = torrent_dir

                    if len(torrent_filelist) > 1 and os.path.isdir(
                        torrent_dir
                    ):  # multi file torrent, path.isdir check makes sure we're not in the root download folder
                        for root, _, files in os.walk(torrent.save_path):
                            for f in files:
                                torrent_files.append(sp(os.path.join(root, f)))

                    else:  # multi or single file placed directly in torrent.save_path
                        for f in torrent_filelist:
                            file_path = os.path.join(torrent.save_path, f.name)
                            if os.path.isfile(file_path):
                                torrent_files.append(sp(file_path))

                    release_downloads.append(
                        {
                            "id": torrent.hash,
                            "name": torrent.name,
                            "status": self.getTorrentStatus(torrent),
                            "seed_ratio": torrent.ratio,
                            "original_status": torrent.state,
                            "timeleft": torrent.progress * 100 if torrent.progress else -1,  # percentage
                            "folder": sp(torrent.save_path),
                            "files": torrent_files,
                        }
                    )

            return release_downloads

        except Exception as e:
            log.error("Failed to get status from qBittorrent: %s", e)
            return []

    def pause(self, release_download, pause=True):
        if not self.connect():
            return False

        torrent = self.qb.get_torrent(release_download["id"])
        if torrent is None:
            return False

        if pause:
            return torrent.pause()
        return torrent.resume()

    def removeFailed(self, release_download):
        log.info("%s failed downloading, deleting...", release_download["name"])
        return self.processComplete(release_download, delete_files=True)

    def processComplete(self, release_download, delete_files):
        log.debug(
            "Requesting qBittorrent to remove the torrent %s%s.",
            (release_download["name"], " and cleanup the downloaded files" if delete_files else ""),
        )

        if not self.connect():
            return False

        torrent = self.qb.find_torrent(release_download["id"])

        if torrent is None:
            return False

        if delete_files:
            torrent.delete()  # deletes torrent with data
        else:
            torrent.remove()  # just removes the torrent, doesn't delete data

        return True