transmission.py 6.05 KB
Newer Older
1
# Author: Mr_Orange <[email protected]>
echel0n's avatar
echel0n committed
2
# URL: https://sickrage.ca
3
#
echel0n's avatar
echel0n committed
4
# This file is part of SickRage.
5
#
echel0n's avatar
echel0n committed
6
# SickRage is free software: you can redistribute it and/or modify
7
8
9
10
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
echel0n's avatar
echel0n committed
11
# SickRage is distributed in the hope that it will be useful,
12
13
14
15
16
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
echel0n's avatar
echel0n committed
17
# along with SickRage.  If not, see <http://www.gnu.org/licenses/>.
18

19
20
from __future__ import unicode_literals

21
import json
22
import os
23
24
from base64 import b64encode

25
import sickrage
26
from sickrage.clients import GenericClient
27

echel0n's avatar
echel0n committed
28

29
30
class TransmissionAPI(GenericClient):
    def __init__(self, host=None, username=None, password=None):
echel0n's avatar
echel0n committed
31

32
        super(TransmissionAPI, self).__init__('Transmission', host, username, password)
echel0n's avatar
echel0n committed
33

Alexandre Beloin's avatar
Alexandre Beloin committed
34
        if not self.host.endswith('/'):
35
            self.host += '/'
Alexandre Beloin's avatar
Alexandre Beloin committed
36
37
38
39
40
41
42
43

        if self.rpcurl.startswith('/'):
            self.rpcurl = self.rpcurl[1:]

        if self.rpcurl.endswith('/'):
            self.rpcurl = self.rpcurl[:-1]

        self.url = self.host + self.rpcurl + '/rpc'
44
45

    def _get_auth(self):
echel0n's avatar
echel0n committed
46
        self.response = self.session.post(self.url,
47
48
49
50
                                          data=json.dumps({'method': 'session-get', }),
                                          timeout=120,
                                          auth=(self.username, self.password),
                                          verify=bool(sickrage.app.config.torrent_verify_cert))
51
52

        # get auth session header
53
        self.auth = self.response.headers['x-transmission-session-id'] if self.response is not None else None
54
55
        if not self.auth:
            return
echel0n's avatar
echel0n committed
56

labrys's avatar
labrys committed
57
        # Validating Transmission authorization
58
59
60
        self._request(method='post',
                      data=json.dumps({'arguments': {}, 'method': 'session-get'}),
                      headers={'x-transmission-session-id': self.auth})
echel0n's avatar
echel0n committed
61
62

        return self.auth
63

64
65
66
67
    def _request(self, *args, **kwargs):
        kwargs.setdefault('headers', {}).update({'x-transmission-session-id': self.auth})
        return super(TransmissionAPI, self)._request(*args, **kwargs)

68
    def _add_torrent_uri(self, result):
69
70
71
72
        arguments = {
            'filename': result.url,
            'paused': 1 if sickrage.app.config.torrent_paused else 0,
        }
73

74
75
        if os.path.isabs(sickrage.app.config.torrent_path):
            arguments['download-dir'] = sickrage.app.config.torrent_path
76

77
78
79
80
        post_data = json.dumps({
            'arguments': arguments,
            'method': 'torrent-add'
        })
81

82
83
        if self._request(method='post', data=post_data):
            return self.response.json()['result'] == "success"
84
85

    def _add_torrent_file(self, result):
86
87
88
89
        arguments = {
            'metainfo': b64encode(result.content),
            'paused': 1 if sickrage.app.config.torrent_paused else 0
        }
90

91
92
        if os.path.isabs(sickrage.app.config.torrent_path):
            arguments['download-dir'] = sickrage.app.config.torrent_path
93

94
95
96
97
        post_data = json.dumps({
            'arguments': arguments,
            'method': 'torrent-add'
        })
98

99
100
        if self._request(method='post', data=post_data):
            return self.response.json()['result'] == "success"
101
102

    def _set_torrent_ratio(self, result):
103
        ratio = None
104
        if isinstance(result.ratio, (int, long)):
sammy2142's avatar
sammy2142 committed
105
106
            ratio = result.ratio

107
108
        mode = 0
        if ratio:
nielsenj's avatar
nielsenj committed
109
            if float(ratio) == -1:
110
111
                ratio = 0
                mode = 2
nielsenj's avatar
nielsenj committed
112
            elif float(ratio) >= 0:
113
114
                ratio = float(ratio)
                mode = 1  # Stop seeding at seedRatioLimit
115

116
117
118
119
120
        arguments = {
            'ids': [result.hash],
            'seedRatioLimit': ratio,
            'seedRatioMode': mode
        }
121

122
123
124
125
        post_data = json.dumps({
            'arguments': arguments,
            'method': 'torrent-set'
        })
126

127
128
        if self._request(method='post', data=post_data):
            return self.response.json()['result'] == "success"
129

130
    def _set_torrent_seed_time(self, result):
131
132
        if sickrage.app.config.torrent_seed_time and sickrage.app.config.torrent_seed_time != -1:
            time = int(60 * float(sickrage.app.config.torrent_seed_time))
133
134
135
136
137
            arguments = {
                'ids': [result.hash],
                'seedIdleLimit': time,
                'seedIdleMode': 1
            }
138

139
140
141
142
            post_data = json.dumps({
                'arguments': arguments,
                'method': 'torrent-set'
            })
143

144
145
            if self._request(method='post', data=post_data):
                return self.response.json()['result'] == "success"
146
147
148
        else:
            return True

149
    def _set_torrent_priority(self, result):
Adam's avatar
Adam committed
150
        arguments = {'ids': [result.hash]}
151
152
153
154
155
156
157

        if result.priority == -1:
            arguments['priority-low'] = []
        elif result.priority == 1:
            # set high priority for all files in torrent
            arguments['priority-high'] = []
            # move torrent to the top if the queue
158
            arguments['queuePosition'] = 0
159
            if sickrage.app.config.torrent_high_bandwidth:
160
                arguments['bandwidthPriority'] = 1
161
162
        else:
            arguments['priority-normal'] = []
echel0n's avatar
echel0n committed
163

164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
        post_data = json.dumps({
            'arguments': arguments,
            'method': 'torrent-set'
        })

        if self._request(method='post', data=post_data):
            return self.response.json()['result'] == "success"

    def remove_torrent(self, info_hash):
        arguments = {
            'ids': [info_hash],
            'delete-local-data': 1,
        }

        post_data = json.dumps({
            'arguments': arguments,
            'method': 'torrent-remove',
        })
182

183
184
        if self._request(method='post', data=post_data):
            return self.response.json()['result'] == "success"
echel0n's avatar
echel0n committed
185

186
187

api = TransmissionAPI()