Skip to content

Commit

Permalink
Attempt to fix resume and watching marks
Browse files Browse the repository at this point in the history
  • Loading branch information
quarckster committed Nov 1, 2018
1 parent 0259d8e commit 057c34a
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 56 deletions.
29 changes: 16 additions & 13 deletions resources/lib/addonworker.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,16 @@ def show_items(items, add_indexes=False):
extra_info = {"trailer": trailer_link(item), "mediatype": mediatype_map[item["type"]]}
# If not serials or multiseries movie, create playable item
if item["type"] not in ["serial", "docuserial", "tvshow"] and not item["subtype"]:
watching_info = KinoPubClient("watching").get(
data={"id": item["id"]})["item"]["videos"][0]
extra_info.update(watching_info)
link = get_internal_link(
"play",
id=item["id"],
title=title,
info=json.dumps(video_info(item, extra_info)),
art=item["posters"]["big"]
)
watching_info = KinoPubClient("watching").get(
data={"id": item["id"]})["item"]["videos"][0]
extra_info.update({"playcount": watching_info["status"]})
li.setProperty("isPlayable", "true")
li.setResumeTime(watching_info["time"], watching_info["duration"])
isdir = False
Expand Down Expand Up @@ -217,7 +217,6 @@ def episodes(id):
if video["title"]:
episode_title = "{} | {}".format(episode_title, video["title"].encode("utf-8"))
info = video_info(item, {
"season": 1,
"episode": video["number"],
"time": watching_episode["time"],
"duration": watching_episode["duration"],
Expand Down Expand Up @@ -290,11 +289,11 @@ def season_episodes(id, season_number):


@route("/play")
def play(id, title, video_data=None, info=None, art=None):
if not video_data or not info:
def play(id, title, info, video_data=None, art=None):
if not video_data:
response = KinoPubClient("items/{}".format(id)).get()
video_data = video_data or response["item"]["videos"][0]
info = info or video_info(response["item"])
video_data = response["item"]["videos"][0]
info = video_info(response["item"], json.loads(info))
video_data = json.loads(video_data) if isinstance(video_data, str) else video_data
info = json.loads(info) if isinstance(info, str) else info
if "files" not in video_data:
Expand All @@ -314,7 +313,7 @@ def play(id, title, video_data=None, info=None, art=None):
art={"poster": art},
subtitles=[subtitle["url"] for subtitle in video_data["subtitles"]]
)
player = Player(li)
player = Player(list_item=li)
xbmcplugin.setResolvedUrl(request.handle, True, li)
while player.is_playing:
player.set_marktime()
Expand Down Expand Up @@ -401,26 +400,30 @@ def watching():

@route("/watching_movies")
def watching_movies():
response = KinoPubClient("watching/movies").get()
xbmcplugin.setContent(request.handle, "movies")
for item in response["items"]:
for item in KinoPubClient("watching/movies").get()["items"]:
li = ExtendedListItem(
item["title"].encode("utf-8"),
art={"poster": item["posters"]["big"]},
properties={"id": str(item["id"])},
properties={"id": item["id"]},
info={"video": {"mediatype": mediatype_map[item["type"]]}},
addContextMenuItems=True
)
if item["subtype"] == "multi":
link = get_internal_link("view_episodes", id=item["id"])
isdir = True
else:
response = KinoPubClient("watching").get(data={"id": item["id"]})
watching_info = response["item"]["videos"][0]
li.setProperty("isPlayable", "true")
li.setInfo("video", {"duration": watching_info["duration"]})
li.setResumeTime(watching_info["time"])
link = get_internal_link(
"play",
id=item["id"],
title=item["title"].encode("utf-8"),
art=item["posters"]["big"]
art=item["posters"]["big"],
info=json.dumps(watching_info)
)
isdir = False
xbmcplugin.addDirectoryItem(request.handle, link, li, isdir)
Expand Down
15 changes: 6 additions & 9 deletions resources/lib/listitem.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@ def __init__(self, name, label2="", iconImage="", thumbnailImage="", path="", ar
super(ExtendedListItem, self).__init__(name, label2, iconImage, thumbnailImage, path)
if info:
self.setInfos(**info)
self.setResumeTime(
info["video"].get("time", 0),
info["video"].get("duration", 0)
)
self.setResumeTime(info.get("video", {}).get("time"))
if art:
self.setArt(art)
if properties:
Expand Down Expand Up @@ -79,9 +76,9 @@ def setInfos(self, **info):
for info_type, info_value in info.items():
self.setInfo(info_type, info_value)

def setResumeTime(self, resumetime, totaltime):
if not totaltime:
return
if (100 * resumetime / float(totaltime) <=
get_adv_setting("video", "playcountminimumpercent")):
def setResumeTime(self, resumetime, totaltime=None):
totaltime = float(totaltime or self.getduration())
if (resumetime is not None and 100 * resumetime / totaltime <=
get_adv_setting("video", "playcountminimumpercent") and
resumetime > get_adv_setting("video", "ignoresecondsatstart")):
self.setProperties(resumetime=resumetime, totaltime=totaltime)
76 changes: 44 additions & 32 deletions resources/lib/player.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,57 +7,69 @@

class Player(xbmc.Player):

def __new__(cls, *args, **kwargs):
return super(Player, cls).__new__(cls)

def __init__(self, list_item):
def __init__(self, list_item=None):
super(Player, self).__init__()
self.list_item = list_item
self.is_playing = True
self.marktime = 0
super(Player, self).__init__()

def set_marktime(self):
if self.isPlaying():
self.marktime = int(self.getTime())

@property
def ignore_marktime(self):
def should_make_resume_point(self):
# https://kodi.wiki/view/HOW-TO:Modify_automatic_watch_and_resume_points#Settings_explained
return (self.marktime > get_adv_setting("video", "ignoresecondsatstart") and
not self.should_mark_as_watched)

@property
def should_mark_as_watched(self):
return (100 * self.marktime / float(self.list_item.getduration()) >
get_adv_setting("video", "playcountminimumpercent"))

@property
def should_reset_resume_point(self):
return (
self.marktime <= get_adv_setting("video", "ignoresecondsatstart") or
(100 * self.marktime / float(self.list_item.getduration()) >=
100 - get_adv_setting("video", "ignorepercentatend"))
self.marktime < get_adv_setting("video", "ignoresecondsatstart") and
(float(self.list_item.getProperty("resumetime")) >
get_adv_setting("video", "ignoresecondsatstart"))
)

@property
def _base_data(self):
id = self.list_item.getProperty("id")
video_number = self.list_item.getVideoInfoTag().getEpisode()
season_number = self.list_item.getVideoInfoTag().getSeason()
if season_number != -1:
data = {"id": id, "season": season_number, "video": video_number}
else:
data = {"id": id, "video": 1 if video_number == -1 else video_number}
return data

def onPlayBackStopped(self):
if not self.ignore_marktime:
video_number = self.list_item.getVideoInfoTag().getEpisode()
video_number = 1 if video_number == -1 else video_number
season_number = self.list_item.getVideoInfoTag().getSeason()
season_number = None if season_number == -1 else season_number
KinoPubClient("watching/marktime").get(data={
"id": self.list_item.getProperty("id"),
"video": video_number,
"time": self.marktime,
"season": season_number
})
xbmc.executebuiltin("Container.Refresh")
self.is_playing = False
data = self._base_data
if self.should_make_resume_point:
data["time"] = self.marktime
KinoPubClient("watching/marktime").get(data=data)
elif self.should_mark_as_watched and self.list_item.getVideoInfoTag().getPlayCount() < 1:
data["status"] = 1
KinoPubClient("watching/toggle").get(data=data)
elif self.should_reset_resume_point:
data["time"] = 0
KinoPubClient("watching/marktime").get(data=data)
else:
return
xbmc.executebuiltin("Container.Refresh")

def onPlayBackEnded(self):
self.is_playing = False
if self.list_item.getVideoInfoTag().getPlayCount() < 1:
video_number = self.list_item.getVideoInfoTag().getEpisode()
video_number = 1 if video_number == -1 else video_number
season_number = self.list_item.getVideoInfoTag().getSeason()
season_number = None if season_number == -1 else season_number
KinoPubClient("watching/toggle").get(data={
"id": self.list_item.getProperty("id"),
"video": video_number,
"season": season_number,
"status": 1
})
data = self._base_data
data["status"] = 1
KinoPubClient("watching/toggle").get(data=data)
xbmc.executebuiltin("Container.Refresh")
self.is_playing = False

def onPlaybackError(self):
self.is_playing = False
6 changes: 4 additions & 2 deletions tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,14 +165,15 @@ def side_effect(value):


def test_play(play, main, ExtendedListItem, xbmcplugin):
from resources.lib.addonutils import video_info
stream, video_quality = play
main()
title = actionPlay_response["item"]["title"].encode("utf-8")
link = "https://example.com/{}/{}".format(stream, video_quality.rstrip("p"))
ExtendedListItem.assert_called_with(
title,
path=link,
info={"video": {}},
info={"video": video_info(actionPlay_response["item"])},
properties={"id": str(actionPlay_response["item"]["id"])},
art={"poster": None},
subtitles=[]
Expand Down Expand Up @@ -208,6 +209,8 @@ def test_items(main, items, ExtendedListItem, xbmcplugin, mocker):

def make_info(item):
extra_info = {"trailer": trailer_link(item), "mediatype": mediatype_map[item["type"]]}
if item["type"] not in ["serial", "docuserial", "tvshow"]:
extra_info.update({"time": 0, "duration": 1, "status": 0})
return json.dumps(video_info(item, extra_info))

expected_results = []
Expand Down Expand Up @@ -373,7 +376,6 @@ def test_view_episodes(request, main, view_episodes, ExtendedListItem, xbmcplugi
if video["title"]:
episode_title = "{} | {}".format(episode_title, video["title"].encode("utf-8"))
info = video_info(item, {
"season": 1,
"episode": video["number"],
"playcount": video["watched"],
"time": watching_episode["time"],
Expand Down

0 comments on commit 057c34a

Please sign in to comment.