PlexBasicCredential.refresh_details()   F
last analyzed

Complexity

Conditions 9

Size

Total Lines 42

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 79.8826

Importance

Changes 0
Metric Value
dl 0
loc 42
ccs 1
cts 23
cp 0.0434
rs 3
c 0
b 0
f 0
cc 9
crap 79.8826
1 1
from plugin.core.environment import Environment
2 1
from plugin.models.m_plex.account import PlexAccount
3 1
from plugin.models.core import db
4
5 1
from exception_wrappers.libraries.playhouse.apsw_ext import *
0 ignored issues
show
Coding Style introduced by
The usage of wildcard imports like exception_wrappers.libraries.playhouse.apsw_ext should generally be avoided.
Loading history...
6 1
from xml.etree import ElementTree
7 1
import logging
8 1
import requests
9
10 1
log = logging.getLogger(__name__)
11
12
13 1
class PlexBasicCredential(Model):
14 1
    class Meta:
15 1
        database = db
16 1
        db_table = 'plex.credential.basic'
17
18 1
    account = ForeignKeyField(PlexAccount, 'basic_credentials', unique=True)
19
20 1
    password = CharField(null=True)
21
22
    # Authorization
23 1
    token_plex = CharField(null=True)
24 1
    token_server = CharField(null=True)
25
26 1
    @property
27
    def state(self):
28
        if self.token_plex is not None and self.token_server is not None:
29
            return 'valid'
30
31
        if self.password is not None:
32
            return 'warning'
33
34
        return 'empty'
35
36 1
    def refresh(self, force=False, save=True):
37
        # Refresh account details
38
        if not self.refresh_details(force):
39
            return False
40
41
        # Store changes in database
42
        if save:
43
            self.save()
44
45
        return True
46
47 1
    def refresh_details(self, force=False):
48
        if self.token_plex is None:
49
            # Missing token
50
            return False
51
52
        if not force and self.token_server:
53
            # Already authenticated
54
            return True
55
56
        if self.token_plex == 'anonymous':
57
            return self.refresh_anonymous()
58
59
        log.info('Refreshing plex credential: %r', self)
60
61
        # Fetch server token
62
        response = requests.get('https://plex.tv/api/resources?includeHttps=1', headers={
63
            'X-Plex-Token': self.token_plex
64
        })
65
66
        if not (200 <= response.status_code < 300):
0 ignored issues
show
Unused Code Coding Style introduced by
There is an unnecessary parenthesis after not.
Loading history...
67
            log.warn('Unable to retrieve servers from plex.tv (status_code: %s)', response.status_code)
68
            return False
69
70
        devices = ElementTree.fromstring(response.content)
71
72
        # Find server
73
        server = None
74
75
        for s in devices.findall('Device'):
76
            if s.attrib.get('clientIdentifier') != Environment.platform.machine_identifier:
77
                continue
78
79
            server = s
80
81
        if server is None:
82
            log.warn('Unable to find server with identifier: %r', Environment.platform.machine_identifier)
83
            return False
84
85
        # Update `token_server`
86
        self.token_server = server.attrib.get('accessToken') or self.token_plex
87
88
        return True
89
90 1
    def refresh_anonymous(self):
91
        log.info('Refreshing plex credential: %r (anonymous)', self)
92
93
        self.token_server = 'anonymous'
94
95
        return True
96
97 1
    def to_json(self, account):
98
        result = {
99
            'state': self.state,
100
101
            'username': account.username
102
        }
103
104
        if self.password:
105
            result['password'] = '*' * len(self.password)
106
        elif self.token_plex:
107
            result['password'] = '*' * 8
108
109
        return result
110