Skip to content

Commit 9e47ba5

Browse files
committed
[script.myepisodes] 3.2.0
1 parent 4a59012 commit 9e47ba5

File tree

7 files changed

+226
-165
lines changed

7 files changed

+226
-165
lines changed

script.myepisodes/addon.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
22
<addon id="script.myepisodes"
33
name="MyEpisodes"
4-
version="3.0.2"
4+
version="3.2.0"
55
provider-name="Maxime Hadjinlian">
66
<requires>
77
<import addon="xbmc.python" version="3.0.0"/>

script.myepisodes/changelog.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
3.2.0
2+
+ Important refactor and bug fixes.
13
3.0.2
24
+ Use "is_alive" instead of "is_Alive" that doesn't exists
35
3.0.1

script.myepisodes/default.py

Lines changed: 136 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import sys
55
import threading
66
import logging
7+
from typing import Callable
78

89
import xbmc
910
import xbmcvfs
@@ -12,7 +13,7 @@
1213
import utils
1314
import kodilogging
1415

15-
from myepisodes import MyEpisodes
16+
from myepisodes import MyEpisodes, SHOW_ID_ERR
1617

1718
_addon = xbmcaddon.Addon()
1819
_kodiversion = float(xbmcaddon.Addon("xbmc.addon").getAddonInfo("version")[0:4])
@@ -25,90 +26,85 @@
2526
logger = logging.getLogger(__name__)
2627

2728

28-
class MyeMonitor(xbmc.Monitor):
29-
def __init__(self, *args, **kwargs):
29+
class MEMonitor(xbmc.Monitor):
30+
def __init__(self, *args: int, **kwargs: Callable) -> None:
3031
xbmc.Monitor.__init__(self)
3132
self.action = kwargs["action"]
3233

33-
def onSettingsChanged(self):
34+
def onSettingsChanged(self) -> None:
3435
logger.debug("User changed settings")
3536
self.action()
3637

3738

38-
def _initMyEpisodes():
39-
username = utils.getSetting("Username")
40-
password = utils.getSetting("Password")
41-
42-
login_notif = _language(32912)
43-
if not username or not password:
44-
utils.notif(login_notif, time=2500)
45-
return None
46-
47-
mye = MyEpisodes(username, password)
48-
mye.login()
49-
if mye.is_logged:
50-
login_notif = f"{username} {_language(32911)}"
51-
utils.notif(login_notif, time=2500)
52-
53-
if mye.is_logged and (not mye.populate_shows()):
54-
utils.notif(_language(32927), time=2500)
55-
return mye
39+
class MEProperties:
40+
def __init__(self) -> None:
41+
self.showid = self.episode = self.season = 0
42+
self.title = ""
43+
self.is_excluded = False
44+
self.total_time = sys.maxsize
45+
self.last_pos = 0
5646

5747

58-
class MyePlayer(xbmc.Player):
59-
def __init__(self):
48+
class MEPlayer(xbmc.Player):
49+
def __init__(self) -> None:
6050
xbmc.Player.__init__(self)
61-
logger.debug("MyePlayer - init")
51+
logger.debug("MEPlayer - init")
52+
self._tracker = threading.Thread(target=self._track_position)
53+
self._reset()
6254

63-
self.mye = _initMyEpisodes()
55+
def _reset(self) -> None:
56+
logger.debug("_reset called")
57+
self.resetTracker()
58+
if hasattr(self, "mye"):
59+
del self.mye
60+
self.monitor = MEMonitor(action=self._reset)
61+
self.props = MEProperties()
62+
self._playback_lock = threading.Event()
63+
self.mye: MyEpisodes = MEPlayer.initMyEpisodes()
6464
if not self.mye.is_logged:
6565
return
66-
6766
logger.debug("MyePlayer - account is logged successfully.")
6867

69-
self.showid = self.episode = self.title = self.season = None
70-
self.is_excluded = False
71-
self._total_time = sys.maxsize
72-
self._last_pos = 0
73-
self._min_percent = utils.getSettingAsInt("watched-percent")
74-
self._tracker = None
75-
self._playback_lock = threading.Event()
76-
self.monitor = MyeMonitor(action=self._reset)
77-
78-
def _reset(self):
79-
logger.debug("_reset called")
80-
self.tearDown()
81-
if self.mye:
82-
del self.mye
83-
self.__init__()
84-
85-
def _trackPosition(self):
86-
while self._playback_lock.isSet() and not self.monitor.abortRequested():
87-
try:
88-
self._last_pos = self.getTime()
89-
except:
90-
self._playback_lock.clear()
91-
logger.debug(f"Tracker time = {self._last_pos}")
92-
xbmc.sleep(250)
93-
logger.debug(f"Tracker time (ended) = {self._last_pos}")
94-
95-
def setUp(self):
96-
self._playback_lock.set()
97-
self._tracker = threading.Thread(target=self._trackPosition)
98-
99-
def tearDown(self):
68+
def resetTracker(self) -> None:
10069
if hasattr(self, "_playback_lock"):
10170
self._playback_lock.clear()
10271
if not hasattr(self, "_tracker"):
10372
return
104-
if self._tracker is None:
105-
return
10673
if self._tracker.is_alive():
10774
self._tracker.join()
108-
self._tracker = None
75+
self._tracker = threading.Thread(target=self._track_position)
76+
77+
@classmethod
78+
def initMyEpisodes(cls) -> MyEpisodes:
79+
username = utils.getSetting("Username")
80+
password = utils.getSetting("Password")
81+
82+
login_notif = _language(32912)
83+
if not username or not password:
84+
utils.notif(login_notif, time=2500)
85+
return MyEpisodes("", "")
86+
87+
mye = MyEpisodes(username, password)
88+
mye.login()
89+
if mye.is_logged:
90+
login_notif = f"{username} {_language(32911)}"
91+
utils.notif(login_notif, time=2500)
10992

110-
def _addShow(self):
93+
if mye.is_logged and (not mye.populate_shows()):
94+
utils.notif(_language(32927), time=2500)
95+
return mye
11196

97+
def _track_position(self) -> None:
98+
while self._playback_lock.is_set() and not self.monitor.abortRequested():
99+
try:
100+
self.props.last_pos = self.getTime()
101+
except:
102+
self._playback_lock.clear()
103+
logger.debug("Tracker time = %d", self.props.last_pos)
104+
xbmc.sleep(250)
105+
logger.debug("Tracker time (ended) = %d", self.props.last_pos)
106+
107+
def _add_show(self) -> None:
112108
if not utils.getSettingAsBool("auto-add"):
113109
logger.debug("Auto-add function disabled.")
114110
return
@@ -117,118 +113,149 @@ def _addShow(self):
117113
self.mye.populate_shows()
118114

119115
# Add the show if it's not already in our account
120-
if self.showid in list(self.mye.shows.values()):
116+
if self.props.showid in list(self.mye.shows.values()):
121117
logger.debug("Show is already in the account.")
122118
return
123119

124-
was_added = self.mye.add_show(self.showid)
120+
was_added = self.mye.add_show(self.props.showid)
125121
added = 32926
126122
if was_added:
127123
added = 32925
128-
utils.notif(f"{self.title} {_language(added)}")
124+
utils.notif(f"{self.props.title} {_language(added)}")
129125

130126
# For backward compatibility
131-
def onPlayBackStarted(self):
127+
def onPlayBackStarted(self) -> None:
132128
if _kodiversion >= 17.9:
133129
return
134130
# This call is only for Krypton and below
135131
self.onAVStarted()
136132

137133
# Only available in Leia (18) and up
138-
def onAVStarted(self):
139-
self.setUp()
140-
self._total_time = self.getTotalTime()
134+
def onAVStarted(self) -> None:
135+
self._playback_lock.set()
136+
self.props.total_time = self.getTotalTime()
141137
self._tracker.start()
142138

143139
filename_full_path = self.getPlayingFile()
144140
# We don't want to take care of any URL because we can't really gain
145141
# information from it.
146-
self.is_excluded = False
142+
self.props.is_excluded = False
147143
if utils.is_excluded(filename_full_path):
148-
self.is_excluded = True
149-
self.tearDown()
144+
self.props.is_excluded = True
145+
self.resetTracker()
150146
return
151147

152148
# Try to find the title with the help of Kodi (Theses came from
153149
# Kodi.Subtitles add-ons)
154-
self.season = str(xbmc.getInfoLabel("VideoPlayer.Season"))
155-
logger.debug("Player - Season: {self.season}")
156-
self.episode = str(xbmc.getInfoLabel("VideoPlayer.Episode"))
157-
logger.debug("Player - Episode: {self.episode}")
158-
self.title = xbmc.getInfoLabel("VideoPlayer.TVshowtitle")
159-
logger.debug("Player - TVShow: {self.title}")
160-
if self.title == "":
150+
try:
151+
self.props.season = int(xbmc.getInfoLabel("VideoPlayer.Season"))
152+
except ValueError:
153+
self.props.season = 0
154+
logger.debug("Player - Season: %02d", self.props.season)
155+
156+
try:
157+
self.props.episode = int(xbmc.getInfoLabel("VideoPlayer.Episode"))
158+
except ValueError:
159+
self.props.episode = 0
160+
logger.debug("Player - Episode: %02d", self.props.episode)
161+
162+
self.props.title = xbmc.getInfoLabel("VideoPlayer.TVshowtitle")
163+
logger.debug("Player - TVShow: %s", self.props.title)
164+
165+
if self.props.title == "":
161166
filename = os.path.basename(filename_full_path)
162-
logger.debug("Player - Filename: {filename}")
163-
self.title, self.season, self.episode = self.mye.get_info(filename)
164-
logger.debug("Player - TVShow: {self.title}")
167+
logger.debug("Player - Filename: '%s'", filename)
168+
self.props.title, self.props.season, self.props.episode = self.mye.get_info(
169+
filename
170+
)
171+
logger.debug("Player - TVShow: '%s'", self.props.title)
165172

166173
logger.debug(
167-
f"Title: {self.title} - Season: {self.season} - Ep: {self.episode}"
174+
"Title: '%s' - Season: %02d - Ep: %02d ",
175+
self.props.title,
176+
self.props.season,
177+
self.props.episode,
168178
)
169-
if not self.season and not self.episode:
179+
if not self.props.season and not self.props.episode:
170180
# It's not a show. If it should be recognised as one. Send a bug.
171-
self.tearDown()
181+
self.resetTracker()
172182
return
173183

174-
self.showid = self.mye.find_show_id(self.title)
175-
if self.showid is None:
176-
utils.notif(f"{self.title} {_language(32923)}", time=3000)
177-
self.tearDown()
184+
self.props.showid = self.mye.find_show_id(self.props.title)
185+
if self.props.showid == SHOW_ID_ERR:
186+
utils.notif(f"{self.props.title} {_language(32923)}", time=3000)
187+
self.resetTracker()
178188
return
179189
logger.debug(
180-
f"Player - Found : {self.title} - {self.showid} (S{self.season} E{self.episode}"
190+
"Player - Found : '%s' - %02d (S%02d E%02d",
191+
self.props.title,
192+
self.props.showid,
193+
self.props.season,
194+
self.props.episode,
181195
)
182196

183-
utils.notif(self.title, time=2000)
184-
self._addShow()
197+
utils.notif(self.props.title, time=2000)
198+
self._add_show()
185199

186-
def onPlayBackStopped(self):
200+
def onPlayBackStopped(self) -> None:
187201
# User stopped the playback
188202
self.onPlayBackEnded()
189203

190-
def onPlayBackEnded(self):
191-
self.tearDown()
204+
def onPlayBackEnded(self) -> None:
205+
self.resetTracker()
192206

193-
logger.debug(f"onPlayBackEnded: is_exluded: {self.is_excluded}")
194-
if self.is_excluded:
207+
logger.debug("onPlayBackEnded: is_exluded: %r", self.props.is_excluded)
208+
if self.props.is_excluded:
195209
return
196210

197-
logger.debug(f"last_pos / total_time : {self._last_pos} / {self._total_time}")
198-
199-
actual_percent = (self._last_pos / self._total_time) * 100
200211
logger.debug(
201-
f"last_pos / total_time : {self._last_pos} / {self._total_time} = {actual_percent} %%",
212+
"last_pos / total_time : %d / %d",
213+
self.props.last_pos,
214+
self.props.total_time,
202215
)
203216

204-
logger.debug(f"min_percent: {self._min_percent}")
217+
actual_percent = (self.props.last_pos / self.props.total_time) * 100
218+
logger.debug(
219+
"last_pos / total_time : %d / %d = %d%%",
220+
self.props.last_pos,
221+
self.props.total_time,
222+
actual_percent,
223+
)
205224

206-
if actual_percent < self._min_percent:
225+
min_percent = min(utils.getSettingAsInt("watched-percent"), 95)
226+
logger.debug("min_percent: %d%%", min_percent)
227+
if actual_percent < min_percent:
207228
return
208229

209230
# In case it was deleted or whatever happened during playback
210-
self._addShow()
231+
self._add_show()
211232

212233
# Playback is finished, set the items to watched
213234
found = 32923
214-
if self.mye.set_episode_watched(self.showid, self.season, self.episode):
235+
if self.mye.set_episode_watched(
236+
self.props.showid, self.props.season, self.props.episode
237+
):
215238
found = 32924
216-
utils.notif(f"{self.title} ({self.season} - {self.episode}) {_language(found)}")
239+
utils.notif(
240+
f"{self.props.title} ({self.props.season:02} - {self.props.episode:02}) {_language(found)}"
241+
)
217242

218243

219244
if __name__ == "__main__":
220-
player = MyePlayer()
245+
player = MEPlayer()
221246
if not player.mye.is_logged:
222247
sys.exit(0)
223248

224249
logger.debug(
225-
f"[{_addon.getAddonInfo('name')}] - Version: {_addon.getAddonInfo('version')} Started"
250+
"[%s] - Version: %s Started",
251+
_addon.getAddonInfo("name"),
252+
_addon.getAddonInfo("version"),
226253
)
227254

228255
while not player.monitor.abortRequested():
229256
if player.monitor.waitForAbort(1):
230257
# Abort was requested while waiting. We should exit
231258
break
232259

233-
player.tearDown()
260+
player.resetTracker()
234261
sys.exit(0)

0 commit comments

Comments
 (0)