GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — master ( dab5ac...44ae45 )
by David
01:38
created

Player._thread_tracker()   F

Complexity

Conditions 10

Size

Total Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 10
c 2
b 1
f 0
dl 0
loc 29
rs 3.1304

How to fix   Complexity   

Complexity

Complex classes like Player._thread_tracker() 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
#!/usr/bin/python
2
# -*- coding: UTF-8 -*-
3
4
import os
5
import xbmc
6
import json
7
import threading
8
9
from interface import notify
10
from utils import log
11
from utils import get_setting
12
from utils import get_str
13
14
class Player(xbmc.Player):
15
    def __init__(self, api):
16
        xbmc.Player.__init__(self)
17
        self._api = api
18
        self._tracker = None
19
        self._playback_lock = threading.Event()
20
21
    def onPlayBackStarted(self):
22
        self._stop_tracker()
23
        if self._api.isLoggedIn:
24
            self._detect_item()
25
26
    def onPlayBackStopped(self):
27
        log("Stop clear")
28
        self._stop_tracker()
29
30
    def onPlayBackEnded(self):
31
        log("End clear")
32
        self._stop_tracker()
33
34
    def _detect_item(self):
35
        self._item = {}
36
        _data = json.loads(xbmc.executeJSONRPC(json.dumps({
37
            "jsonrpc": "2.0", "method": "Player.GetItem",
38
            "params": {
39
                "properties": ["showtitle", "title", "season", "episode", "file", "tvshowid", "imdbnumber","genre" ,"year"],
40
                "playerid": 1},
41
            "id": "VideoGetItem"})))["result"]["item"]
42
        is_tv = _data["tvshowid"] != -1 and _data["season"] > 0 and _data["episode"] > 0
43
        if is_tv:
44
            _data["imdbnumber"] = json.loads(xbmc.executeJSONRPC(json.dumps({
45
                "jsonrpc": "2.0", "method": "VideoLibrary.GetTVShowDetails",
46
                "params": {"tvshowid": _data["tvshowid"], "properties": ["imdbnumber"]},
47
                "id": 1
48
            })))["result"]["tvshowdetails"]["imdbnumber"]
49
50
        log("Full: {0}".format(_data))
51
        if ("imdbnumber" not in _data or _data["imdbnumber"] == '') and _data['file']:
52
            _r = self._api.detect_by_file(filename=_data['file'])
53
            if isinstance(_r, dict) and "type" in _r:
54
                if _r["type"] == "episode":
55
                    # TESTED
56
                    if "episode" in _r:
57
                        self._item = {
58
                            "type": "episodes",
59
                            "title": _r["show"]["title"],
60
                            "simkl": _r["episode"]["ids"]["simkl"],
61
                            "season": _r["episode"]["season"],
62
                            "episode": _r["episode"]["episode"]
63
                        }
64
                elif _r["type"] == "movie" and "movie" in _r:
65
                    # TESTED
66
                    self._item = {
67
                        "type": "movies",
68
                        "title": _r["movie"]["title"],
69
                        "year": _r["movie"]["year"],
70
                        "simkl": _r["movie"]["ids"]["simkl"]
71
                    }
72
73
        if not self._item and (_data["title"] or _data["showtitle"]):
74
            if is_tv:
75
                # TESTED
76
                self._item = {
77
                    "type": "shows",
78
                    "title": _data["showtitle"],
79
                    "tvdb": _data["imdbnumber"],
80
                    "season": _data["season"],
81
                    "episode": _data["episode"]
82
                }
83
            else:
84
                # TESTED
85
                self._item = {
86
                    "type": "movies",
87
                    "title": _data["title"],
88
                    "year": _data["year"],
89
                    "imdb": _data["imdbnumber"],
90
                }
91
92
        if self._item:
93
            self._run_tracker()
94
95
    def _run_tracker(self):
96
        self._playback_lock.set()
97
        self._tracker = threading.Thread(target=self._thread_tracker)
98
        self._tracker.start()
99
100
    def _stop_tracker(self):
101
        if hasattr(self, '_playback_lock'): self._playback_lock.clear()
102
        if not hasattr(self, '_tracker'): return
103
        if self._tracker is None: return
104
        if self._tracker.isAlive(): self._tracker.join()
105
        self._tracker = None
106
107
    def _thread_tracker(self):
108
        log("in tracker thread")
109
        # try:
110
        total_time = self.getTotalTime()
111
        perc_mark = int(get_setting("scr-pct"))
112
        self._is_detected = True
113
        while self._playback_lock.isSet() and not xbmc.abortRequested:
114
            try:
115
                if min(99, 100 * self.getTime() / total_time) >= perc_mark:
116
                    success = self._api.mark_as_watched(self._item)
117
                    if not success:
118
                        log("Failed to scrobble")
119
                        notify("Failed to scrobble, retrying later") # Serialize this
120
                    while not success:
121
                        log("Retrying")
122
                        if (self.getTime() / total_time) > 0.95:
123
                            log("Stopped scrobbling")
124
                            notify("Finally, failed to scrobble")
125
                            break
126
                        xbmc.sleep(30000)
127
                        success = self._api.mark_as_watched(self._item)
128
                    if success and bool(get_setting("bubble")):
129
                        self._show_bubble(self._item)
130
131
                    self._playback_lock.clear()
132
            except:
133
                self._playback_lock.clear()
134
            xbmc.sleep(1000)
135
        log('track stop')
136
        # except:
137
        #     pass
138
139
    def _show_bubble(self, item):
140
        log("in bubble")
141
        if "title" in item:
142
            txt = ''
143
            title = item["title"]
144
            if "episode" in item:
145
                txt = "- S{:02}E{:02}".format(item["season"], item["episode"])
146
            elif "year" in item:
147
                title = "".join([title, " (", str(item["year"]), ")"])
148
149
            log("Show Bubble")
150
            notify(get_str(32028).format(txt), title=title)
151
152
    @staticmethod
153
    def getMediaType():
154
        if xbmc.getCondVisibility('Container.Content(tvshows)'):
155
            return "show"
156
        elif xbmc.getCondVisibility('Container.Content(seasons)'):
157
            return "season"
158
        elif xbmc.getCondVisibility('Container.Content(episodes)'):
159
            return "episode"
160
        elif xbmc.getCondVisibility('Container.Content(movies)'):
161
            return "movie"
162
        else:
163
            return None