forked from mueslo/pythonBits
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtracker.py
More file actions
112 lines (97 loc) · 4.39 KB
/
Copy pathtracker.py
File metadata and controls
112 lines (97 loc) · 4.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# -*- coding: utf-8 -*-
from __future__ import (absolute_import, division,
print_function, unicode_literals)
from builtins import * # noqa: F401, F403
import requests
import contextlib
import re
from . import __version__ as version, __title__ as title
from .config import config
from .logging import log
config.register('Tracker', 'announce_url',
"Please enter your personal announce URL")
config.register('Tracker', 'username', "Username", ask=True)
config.register('Tracker', 'password', "Password", ask=True, getpass=True)
config.register('Tracker', 'domain',
"Please enter the tracker's domain, e.g. 'mydomain.net'")
class TrackerException(Exception):
pass
class Tracker():
headers = {'User-Agent': '{}/{}'.format(title, version)}
def _login(self, session, _tries=0):
domain = config.get('Tracker', 'domain')
login_url = "https://{}/login.php".format(domain)
payload = {'username': config.get('Tracker', 'username'),
'password': config.get('Tracker', 'password'),
'keeplogged': "1",
'login': "Log in!"}
resp = session.post(login_url, data=payload)
resp.raise_for_status()
if 'href="login.php"' in resp.text:
if 'id="loginform"' in resp.text:
raise TrackerException("Login failed")
elif 'You are banned' in resp.text:
raise TrackerException("Login failed (login attempts exceeded)")
else:
# We encountered the login bug that sends you to "/" (which
# doesn't contain the login form) without logging you in
if _tries < 10:
log.debug('Encountered login bug; trying again')
self._login(session, _tries=_tries+1)
else:
log.debug('Encountered login bug; giving up after 10 login attempts')
raise TrackerException("Login failed")
elif 'logout.php' in resp.text:
# Login successful, find and remember logout URL
match = re.search(r"logout\.php\?auth=[0-9a-f]{32}", resp.text)
if match:
self._logout_url = "https://{}/{}".format(domain, match.group(0))
else:
raise TrackerException("Couldn't find logout URL")
else:
log.error(resp.text)
raise TrackerException("Couldn't determine login status from HTML")
def _logout(self, session):
logout_url = getattr(self, '_logout_url')
if logout_url:
delattr(self, '_logout_url')
resp = session.get(logout_url)
if 'logout.php' in resp.text:
raise TrackerException("Logout failed")
else:
raise TrackerException("No logout URL: Unable to logout")
@contextlib.contextmanager
def login(self):
log.notice("Logging in {} to {}",
config.get('Tracker', 'username'),
config.get('Tracker', 'domain'))
with requests.Session() as s:
s.headers.update(self.headers)
self._login(s)
yield s
self._logout(s)
log.notice("Logged out {} of ",
config.get('Tracker', 'username'),
config.get('Tracker', 'domain'))
def upload(self, **kwargs):
url = "https://{}/upload.php".format(config.get('Tracker', 'domain'))
with self.login() as session:
log.notice("Posting submission")
resp = session.post(url, **kwargs)
resp.raise_for_status()
# TODO: Catch this somehow:
# <p style="color: red;text-align:center;">You must enter at least one tag. Maximum length is 200 characters.</p>
if resp.history:
# todo: check if url is good, might have been logged out
# (unlikely)
return resp.url
else:
log.error('Response: %s' % resp)
err_match = re.search(r''.join((r'(No torrent file uploaded.*?)',
re.escape(r'</p>'))),
resp.text)
if err_match:
log.error('Error: %s' % err_match.group(1))
else:
log.error('Unknown error')
raise TrackerException('Failed to upload submission')