Passed
Push — master ( aeb165...d9ae97 )
by Dean
03:04
created

Account.refresh()   F

Complexity

Conditions 10

Size

Total Lines 36

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 94.2302
Metric Value
dl 0
loc 36
ccs 1
cts 18
cp 0.0556
rs 3.1304
cc 10
crap 94.2302

How to fix   Complexity   

Complexity

Complex classes like Account.refresh() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1 1
from plugin.models.core import db
2
3 1
from datetime import datetime, timedelta
4 1
from playhouse.apsw_ext import *
0 ignored issues
show
Coding Style introduced by
The usage of wildcard imports like playhouse.apsw_ext should generally be avoided.
Loading history...
5 1
import logging
6 1
import requests
7
8 1
REFRESH_INTERVAL = timedelta(days=1)
9
10 1
log = logging.getLogger(__name__)
11
12
13 1
class Account(Model):
14 1
    class Meta:
15 1
        database = db
16
17 1
    name = CharField(null=True, unique=True)
18 1
    thumb = TextField(null=True)
19
20 1
    deleted = BooleanField(default=False)
21 1
    refreshed_at = DateTimeField(null=True)
22
23 1
    def __init__(self, *args, **kwargs):
24
        super(Account, self).__init__(*args, **kwargs)
25
26
        self._plex_account = None
27
        self._trakt_account = None
28
29 1
    @property
30
    def plex(self):
31
        if self._plex_account:
32
            return self._plex_account
33
34
        return self.plex_accounts.first()
0 ignored issues
show
Bug introduced by
The Instance of Account does not seem to have a member named plex_accounts.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
35
36 1
    @plex.setter
37
    def plex(self, value):
38
        self._plex_account = value
39
40 1
    @property
41
    def trakt(self):
42
        if self._trakt_account:
43
            return self._trakt_account
44
45
        return self.trakt_accounts.first()
0 ignored issues
show
Bug introduced by
The Instance of Account does not seem to have a member named trakt_accounts.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
46
47 1
    @trakt.setter
48
    def trakt(self, value):
49
        self._trakt_account = value
50
51 1
    @property
52
    def refreshed_ts(self):
53
        if self.refreshed_at is None:
54
            return None
55
56
        return (self.refreshed_at - datetime(1970, 1, 1)).total_seconds()
57
58 1
    def thumb_url(self, update=False):
59
        if self.deleted or (self.thumb and not update):
60
            return self.thumb
61
62
        # Build thumb from `plex` and `trakt` accounts
63
        thumb = self.build_thumb()
64
65
        # If `thumb` has changed, store in database
66
        if thumb != self.thumb:
67
            self.thumb = thumb
68
            self.save()
69
70
        return thumb
71
72 1
    def refresh(self, force=False, save=True):
73
        if self.deleted:
74
            return False
75
76
        # Check if refresh is required
77
        if self.refresh_required():
78
            force = True
79
80
        # Only refresh account every `REFRESH_INTERVAL`
81
        if not force and self.refreshed_at:
82
            since_refresh = datetime.utcnow() - self.refreshed_at
83
84
            if since_refresh < REFRESH_INTERVAL:
85
                return False
86
87
        # Retrieve trakt/plex accounts
88
        p = self.plex
89
        t = self.trakt
90
91
        # Set `name` to trakt/plex username (if `name` isn't already set)
92
        if self.name is None and (t or p):
93
            self.name = t.username or p.username
94
95
        # Update account thumb
96
        self.thumb = self.build_thumb(
97
            plex=p,
98
            trakt=t
99
        )
100
101
        # Store changes in database
102
        self.refreshed_at = datetime.utcnow()
103
104
        if save:
105
            self.save()
106
107
        return True
108
109 1
    def refresh_required(self):
110
        if self.thumb is None:
111
            return True
112
113
        return False
114
115 1
    def build_thumb(self, plex=None, trakt=None):
116
        if self.deleted:
117
            return None
118
119
        # Check if trakt thumbnail exists
120
        t = trakt or self.trakt
121
        t_thumb = t.thumb_url('404') if t else None
122
123
        if t_thumb:
124
            response = requests.get(t_thumb)
125
126
            # Check response is valid
127
            if 200 <= response.status_code < 300:
128
                log.debug('Using trakt account thumbnail')
129
                return t.thumb_url()
130
131
        # Return plex thumbnail
132
        p = plex or self.plex
133
        p_thumb = p.thumb_url() if p else None
134
135
        return p_thumb
136
137 1
    def to_json(self, full=False):
138
        result = {
139
            'id': self.id,
0 ignored issues
show
Bug introduced by
The Instance of Account does not seem to have a member named id.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
140
            'name': self.name,
141
            'deleted': self.deleted,
142
143
            'thumb_url': self.thumb_url()
144
        }
145
146
        if not full:
147
            return result
148
149
        # plex
150
        plex = self.plex
151
152
        if plex:
153
            result['plex'] = plex.to_json(full=full)
154
155
        # trakt
156
        trakt = self.trakt
157
158
        if trakt:
159
            result['trakt'] = trakt.to_json(full=full)
160
161
        return result
162
163 1
    def __repr__(self):
164
        return '<Account name: %r>' % (
165
            self.name
166
        )
167