Closed Jorman closed 4 years ago
嗯,4.2不能登录了
同问,目前QB4.2.1,error log如下供参考:
Thu, 19 Dec 2019 17:14:34 main.py[line:44] INFO Auto Remove Torrents 1.4.6
Thu, 19 Dec 2019 17:14:34 main.py[line:46] INFO Loading configurations...
Thu, 19 Dec 2019 17:14:34 main.py[line:49] INFO Found 1 task(s) in the file.
Thu, 19 Dec 2019 17:14:34 task.py[line:115] INFO Running task 'my_task'...
Thu, 19 Dec 2019 17:14:34 task.py[line:75] INFO Logging in...
Thu, 19 Dec 2019 17:14:34 main.py[line:57] ERROR autoremovetorrents.exception.loginfailure.LoginFailure: The server returned HTTP 404.
Thu, 19 Dec 2019 17:14:34 main.py[line:58] ERROR Task my_task fails.
Thu, 19 Dec 2019 17:14:34 main.py[line:59] DEBUG Exception Logged
Traceback (most recent call last):
File "c:\users\xxx\appdata\local\programs\python\python37\lib\site-packages\autoremovetorrents\main.py", line 55, in pre_processor
Task(task_name, result[task_name], not view_mode).execute()
File "c:\users\xxx\appdata\local\programs\python\python37\lib\site-packages\autoremovetorrents\task.py", line 116, in execute
self._login()
File "c:\users\xxx\appdata\local\programs\python\python37\lib\site-packages\autoremovetorrents\task.py", line 77, in _login
self._client.login(self._username, self._password)
File "c:\users\xxx\appdata\local\programs\python\python37\lib\site-packages\autoremovetorrents\client\qbittorrent.py", line 34, in login
raise LoginFailure('The server returned HTTP %d.' % request.status_code)
autoremovetorrents.exception.loginfailure.LoginFailure: The server returned HTTP 404.
@colingpt Thanks for this, only one question, are these changes backwards compatible? If not, is possible to make some like this? https://github.com/Flexget/Flexget/pull/2525/commits/c0570d658d0dd776c6dad477bc4f34d51a3b8dfd So in this way either older or newer qBittorrent api can be used
@colingpt I tried your modification but don't work for me, qBittorrent 4.2.1. I modified the file and this work for me:
#-*- coding:utf-8 -*-
import requests
import time
from ..torrent import Torrent
from ..torrentstatus import TorrentStatus
from ..exception.loginfailure import LoginFailure
from ..exception.deletionfailure import DeletionFailure
from ..exception.connectionfailure import ConnectionFailure
class qBittorrent(object):
def __init__(self, host):
# Host
self._host = host
# Requests Session
self._session = requests.Session()
# Host
self._host = host
# Torrents list cache
self._torrents_list_cache = []
self._refresh_cycle = 30
self._refresh_time = 0
# Login to qBittorrent
def login(self, username, password):
try:
request = self._session.post(self._host+'/api/v2/auth/login', data={'username':username, 'password':password})
except Exception as exc:
raise ConnectionFailure(str(exc))
if request.status_code == 200:
if request.text == 'Fails.': # Fail
raise LoginFailure(request.text)
else:
raise LoginFailure('The server returned HTTP %d.' % request.status_code)
# Get qBittorrent Version
def version(self):
request = self._session.get(self._host+'/api/v2/app/version')
return ('qBittorrent %s' % request.text)
# Get Torrents List
def torrents_list(self):
# Request torrents list
torrent_hash = []
request = self._session.get(self._host+'/api/v2/torrents/info?filter=all')
result = request.json()
# Save to cache
self._torrents_list_cache = result
self._refresh_time = time.time()
# Get hash for each torrent
for torrent in result:
torrent_hash.append(torrent['hash'])
return torrent_hash
# Get Torrent's Generic Properties
def _torrent_generic_properties(self, torrent_hash):
return self._session.get(self._host+'/api/v2/torrents/properties?hash='+torrent_hash).json()
# Get Torrent's Tracker
def _torrent_trackers(self, torrent_hash):
return self._session.get(self._host+'/api/v2/torrents/trackers?hash='+torrent_hash).json()
# Get Torrent Properties
def torrent_properties(self, torrent_hash):
if time.time() - self._refresh_time > self._refresh_cycle: # Out of date
self.torrents_list()
for torrent in self._torrents_list_cache:
if torrent['hash'] == torrent_hash:
# Get other information
properties = self._torrent_generic_properties(torrent_hash)
trackers = self._torrent_trackers(torrent_hash)
return Torrent(
torrent['hash'], torrent['name'],
torrent['category'] if 'category' in torrent else torrent['label'],
[tracker['url'] for tracker in trackers],
qBittorrent._judge_status(torrent['state']),
torrent['state'] == 'stalledUP' or torrent['state'] == 'stalledDL',
torrent['size'], torrent['ratio'],
properties['total_uploaded'], properties['addition_date'],
properties['seeding_time'])
# Judge Torrent Status (qBittorrent doesn't have stopped status)
@staticmethod
def _judge_status(state):
if state == 'downloading' or state == 'stalledDL':
status = TorrentStatus.Downloading
elif state == 'queuedDL' or state == 'queuedUP':
status = TorrentStatus.Queued
elif state == 'uploading' or state == 'stalledUP':
status = TorrentStatus.Uploading
elif state == 'checkingUP' or state == 'checkingDL':
status = TorrentStatus.Checking
elif state == 'pausedUP' or state == 'pausedDL':
status = TorrentStatus.Paused
else:
status = TorrentStatus.Unknown
return status
# Remove Torrent
def remove_torrent(self, torrent_hash):
self._session.post(self._host+'/api/v2/torrents/delete?hashes=', data={'hashes':torrent_hash}+'&deleteFiles=false')
# Remove Torrent and Data
def remove_data(self, torrent_hash):
self._session.post(self._host+'/api/v2/torrents/delete?hashes=', data={'hashes':torrent_hash}+'&deleteFiles=true')
But is not backward compatible
False allarm, I got error on removing phase, I'll try to understand why
@colingpt I tried your modification but don't work for me, qBittorrent 4.2.1. I modified the file and this work for me:
#-*- coding:utf-8 -*- import requests import time from ..torrent import Torrent from ..torrentstatus import TorrentStatus from ..exception.loginfailure import LoginFailure from ..exception.deletionfailure import DeletionFailure from ..exception.connectionfailure import ConnectionFailure class qBittorrent(object): def __init__(self, host): # Host self._host = host # Requests Session self._session = requests.Session() # Host self._host = host # Torrents list cache self._torrents_list_cache = [] self._refresh_cycle = 30 self._refresh_time = 0 # Login to qBittorrent def login(self, username, password): try: request = self._session.post(self._host+'/api/v2/auth/login', data={'username':username, 'password':password}) except Exception as exc: raise ConnectionFailure(str(exc)) if request.status_code == 200: if request.text == 'Fails.': # Fail raise LoginFailure(request.text) else: raise LoginFailure('The server returned HTTP %d.' % request.status_code) # Get qBittorrent Version def version(self): request = self._session.get(self._host+'/api/v2/app/version') return ('qBittorrent %s' % request.text) # Get Torrents List def torrents_list(self): # Request torrents list torrent_hash = [] request = self._session.get(self._host+'/api/v2/torrents/info?filter=all') result = request.json() # Save to cache self._torrents_list_cache = result self._refresh_time = time.time() # Get hash for each torrent for torrent in result: torrent_hash.append(torrent['hash']) return torrent_hash # Get Torrent's Generic Properties def _torrent_generic_properties(self, torrent_hash): return self._session.get(self._host+'/api/v2/torrents/properties?hash='+torrent_hash).json() # Get Torrent's Tracker def _torrent_trackers(self, torrent_hash): return self._session.get(self._host+'/api/v2/torrents/trackers?hash='+torrent_hash).json() # Get Torrent Properties def torrent_properties(self, torrent_hash): if time.time() - self._refresh_time > self._refresh_cycle: # Out of date self.torrents_list() for torrent in self._torrents_list_cache: if torrent['hash'] == torrent_hash: # Get other information properties = self._torrent_generic_properties(torrent_hash) trackers = self._torrent_trackers(torrent_hash) return Torrent( torrent['hash'], torrent['name'], torrent['category'] if 'category' in torrent else torrent['label'], [tracker['url'] for tracker in trackers], qBittorrent._judge_status(torrent['state']), torrent['state'] == 'stalledUP' or torrent['state'] == 'stalledDL', torrent['size'], torrent['ratio'], properties['total_uploaded'], properties['addition_date'], properties['seeding_time']) # Judge Torrent Status (qBittorrent doesn't have stopped status) @staticmethod def _judge_status(state): if state == 'downloading' or state == 'stalledDL': status = TorrentStatus.Downloading elif state == 'queuedDL' or state == 'queuedUP': status = TorrentStatus.Queued elif state == 'uploading' or state == 'stalledUP': status = TorrentStatus.Uploading elif state == 'checkingUP' or state == 'checkingDL': status = TorrentStatus.Checking elif state == 'pausedUP' or state == 'pausedDL': status = TorrentStatus.Paused else: status = TorrentStatus.Unknown return status # Remove Torrent def remove_torrent(self, torrent_hash): self._session.post(self._host+'/api/v2/torrents/delete?hashes=', data={'hashes':torrent_hash}+'&deleteFiles=false') # Remove Torrent and Data def remove_data(self, torrent_hash): self._session.post(self._host+'/api/v2/torrents/delete?hashes=', data={'hashes':torrent_hash}+'&deleteFiles=true')
But is not backward compatible
Fri, 03 Jan 2020 15:33:27 main.py[line:57] ERROR TypeError: init() missing 1 required positional argument: 'seeding_time'
This working for me, just tried, is a mix from @colingpt code
#-*- coding:utf-8 -*-
import requests
import time
from ..torrent import Torrent
from ..torrentstatus import TorrentStatus
from ..exception.loginfailure import LoginFailure
from ..exception.deletionfailure import DeletionFailure
from ..exception.connectionfailure import ConnectionFailure
class qBittorrent(object):
def __init__(self, host):
# Host
self._host = host
# Requests Session
self._session = requests.Session()
# Host
self._host = host
# Torrents list cache
self._torrents_list_cache = []
self._refresh_cycle = 30
self._refresh_time = 0
# Login to qBittorrent
def login(self, username, password):
try:
request = self._session.post(self._host+'/api/v2/auth/login', data={'username':username, 'password':password})
except Exception as exc:
raise ConnectionFailure(str(exc))
if request.status_code == 200:
if request.text == 'Fails.': # Fail
raise LoginFailure(request.text)
else:
raise LoginFailure('The server returned HTTP %d.' % request.status_code)
# Get qBittorrent Version
def version(self):
request = self._session.get(self._host+'/api/v2/app/version')
return ('qBittorrent %s' % request.text)
# Get Torrents List
def torrents_list(self):
# Request torrents list
torrent_hash = []
request = self._session.get(self._host+'/api/v2/torrents/info?filter=all')
result = request.json()
# Save to cache
self._torrents_list_cache = result
self._refresh_time = time.time()
# Get hash for each torrent
for torrent in result:
torrent_hash.append(torrent['hash'])
return torrent_hash
# Get Torrent's Generic Properties
def _torrent_generic_properties(self, torrent_hash):
return self._session.get(self._host+'/api/v2/torrents/properties?hash='+torrent_hash).json()
# Get Torrent's Tracker
def _torrent_trackers(self, torrent_hash):
return self._session.get(self._host+'/api/v2/torrents/trackers?hash='+torrent_hash).json()
# Get Torrent Properties
def torrent_properties(self, torrent_hash):
if time.time() - self._refresh_time > self._refresh_cycle: # Out of date
self.torrents_list()
for torrent in self._torrents_list_cache:
if torrent['hash'] == torrent_hash:
# Get other information
properties = self._torrent_generic_properties(torrent_hash)
trackers = self._torrent_trackers(torrent_hash)
return Torrent(
torrent['hash'], torrent['name'],
torrent['category'] if 'category' in torrent else torrent['label'],
[tracker['url'] for tracker in trackers],
qBittorrent._judge_status(torrent['state']),
torrent['state'] == 'stalledUP' or torrent['state'] == 'stalledDL',
torrent['size'], torrent['ratio'],
properties['total_uploaded'], properties['addition_date'],
properties['seeding_time'])
# Judge Torrent Status (qBittorrent doesn't have stopped status)
@staticmethod
def _judge_status(state):
if state == 'downloading' or state == 'stalledDL':
status = TorrentStatus.Downloading
elif state == 'queuedDL' or state == 'queuedUP':
status = TorrentStatus.Queued
elif state == 'uploading' or state == 'stalledUP':
status = TorrentStatus.Uploading
elif state == 'checkingUP' or state == 'checkingDL':
status = TorrentStatus.Checking
elif state == 'pausedUP' or state == 'pausedDL':
status = TorrentStatus.Paused
else:
status = TorrentStatus.Unknown
return status
# Remove Torrent
def remove_torrent(self, torrent_hash):
# self._session.post(self._host+'/api/v2/torrents/delete?hashes=', data={'hashes':torrent_hash}+'&deleteFiles=false')
requests.get(self._host+'/api/v2/torrents/delete?hashes='+torrent_hash+'&deleteFiles=false')
# Remove Torrent and Data
def remove_data(self, torrent_hash):
# self._session.post(self._host+'/api/v2/torrents/delete?hashes=', data={'hashes':torrent_hash}+'&deleteFiles=true')
requests.get(self._host+'/api/v2/torrents/delete?hashes='+torrent_hash+'&deleteFiles=true')
Maybe there's a better way to do that, I'm not a programmer so
I will fix this problem as soon as possible.
Hi, is possible to support new api from version 4.2? More here https://github.com/qbittorrent/qBittorrent/wiki/Web-API-Documentation#get-torrent-list