mirror of
https://github.com/jellyfin/jellyfin-kodi.git
synced 2024-12-27 11:16:11 +00:00
284 lines
9.8 KiB
Python
284 lines
9.8 KiB
Python
# -*- coding: utf-8 -*-
|
|
from __future__ import division, absolute_import, print_function, unicode_literals
|
|
|
|
##################################################################################################
|
|
|
|
import datetime
|
|
import re
|
|
from urllib.parse import urlencode
|
|
|
|
from ..database import jellyfin_db, queries as QUEM
|
|
from ..helper import api, stop, validate, jellyfin_item, values, Local, LazyLogger
|
|
from ..helper.utils import find_library
|
|
from ..helper.exceptions import PathValidationException
|
|
|
|
from .obj import Objects
|
|
from .kodi import MusicVideos as KodiDb, queries as QU
|
|
|
|
##################################################################################################
|
|
|
|
LOG = LazyLogger(__name__)
|
|
|
|
##################################################################################################
|
|
|
|
|
|
class MusicVideos(KodiDb):
|
|
|
|
def __init__(self, server, jellyfindb, videodb, direct_path, library=None):
|
|
|
|
self.server = server
|
|
self.jellyfin = jellyfindb
|
|
self.video = videodb
|
|
self.direct_path = direct_path
|
|
|
|
self.jellyfin_db = jellyfin_db.JellyfinDatabase(jellyfindb.cursor)
|
|
self.objects = Objects()
|
|
self.item_ids = []
|
|
self.library = library
|
|
|
|
KodiDb.__init__(self, videodb.cursor)
|
|
|
|
@stop
|
|
@jellyfin_item
|
|
def musicvideo(self, item, e_item):
|
|
"""If item does not exist, entry will be added.
|
|
If item exists, entry will be updated.
|
|
|
|
If we don't get the track number from Jellyfin, see if we can infer it
|
|
from the sortname attribute.
|
|
"""
|
|
server_address = self.server.auth.get_server_info(self.server.auth.server_id)[
|
|
"address"
|
|
]
|
|
API = api.API(item, server_address)
|
|
obj = self.objects.map(item, "MusicVideo")
|
|
update = True
|
|
|
|
try:
|
|
obj["MvideoId"] = e_item[0]
|
|
obj["FileId"] = e_item[1]
|
|
obj["PathId"] = e_item[2]
|
|
obj["LibraryId"] = e_item[6]
|
|
obj["LibraryName"] = self.jellyfin_db.get_view_name(obj["LibraryId"])
|
|
except TypeError:
|
|
update = False
|
|
|
|
library = self.library or find_library(self.server, item)
|
|
if not library:
|
|
# This item doesn't belong to a whitelisted library
|
|
return
|
|
|
|
LOG.debug("MvideoId for %s not found", obj["Id"])
|
|
obj["MvideoId"] = self.create_entry()
|
|
obj["LibraryId"] = library["Id"]
|
|
obj["LibraryName"] = library["Name"]
|
|
else:
|
|
if self.get(*values(obj, QU.get_musicvideo_obj)) is None:
|
|
|
|
update = False
|
|
LOG.info(
|
|
"MvideoId %s missing from kodi. repairing the entry.",
|
|
obj["MvideoId"],
|
|
)
|
|
|
|
if (obj.get("ProductionYear") or 0) > 9999:
|
|
obj["ProductionYear"] = int(str(obj["ProductionYear"])[:4])
|
|
|
|
if (obj.get("Year") or 0) > 9999:
|
|
obj["Year"] = int(str(obj["Year"])[:4])
|
|
|
|
obj["Path"] = API.get_file_path(obj["Path"])
|
|
obj["Genres"] = obj["Genres"] or []
|
|
obj["ArtistItems"] = obj["ArtistItems"] or []
|
|
obj["Studios"] = [
|
|
API.validate_studio(studio) for studio in (obj["Studios"] or [])
|
|
]
|
|
obj["Plot"] = API.get_overview(obj["Plot"])
|
|
obj["DateAdded"] = Local(obj["DateAdded"]).split(".")[0].replace("T", " ")
|
|
obj["DatePlayed"] = (
|
|
None
|
|
if not obj["DatePlayed"]
|
|
else Local(obj["DatePlayed"]).split(".")[0].replace("T", " ")
|
|
)
|
|
obj["PlayCount"] = API.get_playcount(obj["Played"], obj["PlayCount"])
|
|
obj["Resume"] = API.adjust_resume((obj["Resume"] or 0) / 10000000.0)
|
|
obj["Runtime"] = round(float((obj["Runtime"] or 0) / 10000000.0), 6)
|
|
obj["Premiere"] = (
|
|
Local(obj["Premiere"])
|
|
if obj["Premiere"]
|
|
else datetime.date(obj["Year"] or 1970, 1, 1)
|
|
)
|
|
obj["Genre"] = " / ".join(obj["Genres"])
|
|
obj["Studio"] = " / ".join(obj["Studios"])
|
|
obj["Artists"] = " / ".join(obj["Artists"] or [])
|
|
obj["Directors"] = " / ".join(obj["Directors"] or [])
|
|
obj["Video"] = API.video_streams(obj["Video"] or [], obj["Container"])
|
|
obj["Audio"] = API.audio_streams(obj["Audio"] or [])
|
|
obj["Streams"] = API.media_streams(obj["Video"], obj["Audio"], obj["Subtitles"])
|
|
obj["Artwork"] = API.get_all_artwork(self.objects.map(item, "Artwork"))
|
|
|
|
self.get_path_filename(obj)
|
|
|
|
if obj["Premiere"]:
|
|
obj["Premiere"] = str(obj["Premiere"]).split(".")[0].replace("T", " ")
|
|
|
|
for artist in obj["ArtistItems"]:
|
|
artist["Type"] = "Artist"
|
|
|
|
obj["People"] = obj["People"] or [] + obj["ArtistItems"]
|
|
obj["People"] = API.get_people_artwork(obj["People"])
|
|
|
|
if obj["Index"] is None and obj["SortTitle"] is not None:
|
|
search = re.search(r"^\d+\s?", obj["SortTitle"])
|
|
|
|
if search:
|
|
obj["Index"] = search.group()
|
|
|
|
tags = []
|
|
tags.extend(obj["Tags"] or [])
|
|
tags.append(obj["LibraryName"])
|
|
|
|
if obj["Favorite"]:
|
|
tags.append("Favorite musicvideos")
|
|
|
|
obj["Tags"] = tags
|
|
|
|
if update:
|
|
self.musicvideo_update(obj)
|
|
else:
|
|
self.musicvideo_add(obj)
|
|
|
|
self.update_path(*values(obj, QU.update_path_mvideo_obj))
|
|
self.update_file(*values(obj, QU.update_file_obj))
|
|
self.add_tags(*values(obj, QU.add_tags_mvideo_obj))
|
|
self.add_genres(*values(obj, QU.add_genres_mvideo_obj))
|
|
self.add_studios(*values(obj, QU.add_studios_mvideo_obj))
|
|
self.add_playstate(*values(obj, QU.add_bookmark_obj))
|
|
self.add_people(*values(obj, QU.add_people_mvideo_obj))
|
|
self.add_streams(*values(obj, QU.add_streams_obj))
|
|
self.artwork.add(obj["Artwork"], obj["MvideoId"], "musicvideo")
|
|
self.item_ids.append(obj["Id"])
|
|
|
|
return not update
|
|
|
|
def musicvideo_add(self, obj):
|
|
"""Add object to kodi."""
|
|
obj["PathId"] = self.add_path(*values(obj, QU.add_path_obj))
|
|
obj["FileId"] = self.add_file(*values(obj, QU.add_file_obj))
|
|
|
|
self.add(*values(obj, QU.add_musicvideo_obj))
|
|
self.jellyfin_db.add_reference(*values(obj, QUEM.add_reference_mvideo_obj))
|
|
LOG.debug(
|
|
"ADD mvideo [%s/%s/%s] %s: %s",
|
|
obj["PathId"],
|
|
obj["FileId"],
|
|
obj["MvideoId"],
|
|
obj["Id"],
|
|
obj["Title"],
|
|
)
|
|
|
|
def musicvideo_update(self, obj):
|
|
"""Update object to kodi."""
|
|
self.update(*values(obj, QU.update_musicvideo_obj))
|
|
self.jellyfin_db.update_reference(*values(obj, QUEM.update_reference_obj))
|
|
LOG.debug(
|
|
"UPDATE mvideo [%s/%s/%s] %s: %s",
|
|
obj["PathId"],
|
|
obj["FileId"],
|
|
obj["MvideoId"],
|
|
obj["Id"],
|
|
obj["Title"],
|
|
)
|
|
|
|
def get_path_filename(self, obj):
|
|
"""Get the path and filename and build it into protocol://path"""
|
|
obj["Filename"] = (
|
|
obj["Path"].rsplit("\\", 1)[1]
|
|
if "\\" in obj["Path"]
|
|
else obj["Path"].rsplit("/", 1)[1]
|
|
)
|
|
|
|
if self.direct_path:
|
|
|
|
if not validate(obj["Path"]):
|
|
raise PathValidationException("Failed to validate path. User stopped.")
|
|
|
|
obj["Path"] = obj["Path"].replace(obj["Filename"], "")
|
|
|
|
else:
|
|
obj["Path"] = "plugin://plugin.video.jellyfin/%s/" % obj["LibraryId"]
|
|
params = {
|
|
"filename": obj["Filename"],
|
|
"id": obj["Id"],
|
|
"dbid": obj["MvideoId"],
|
|
"mode": "play",
|
|
}
|
|
obj["Filename"] = "%s?%s" % (obj["Path"], urlencode(params))
|
|
|
|
@stop
|
|
@jellyfin_item
|
|
def userdata(self, item, e_item):
|
|
"""This updates: Favorite, LastPlayedDate, Playcount, PlaybackPositionTicks
|
|
Poster with progress bar
|
|
"""
|
|
server_address = self.server.auth.get_server_info(self.server.auth.server_id)[
|
|
"address"
|
|
]
|
|
API = api.API(item, server_address)
|
|
obj = self.objects.map(item, "MusicVideoUserData")
|
|
|
|
try:
|
|
obj["MvideoId"] = e_item[0]
|
|
obj["FileId"] = e_item[1]
|
|
except TypeError:
|
|
return
|
|
|
|
obj["Resume"] = API.adjust_resume((obj["Resume"] or 0) / 10000000.0)
|
|
obj["Runtime"] = round(float((obj["Runtime"] or 0) / 10000000.0), 6)
|
|
obj["PlayCount"] = API.get_playcount(obj["Played"], obj["PlayCount"])
|
|
|
|
if obj["DatePlayed"]:
|
|
obj["DatePlayed"] = Local(obj["DatePlayed"]).split(".")[0].replace("T", " ")
|
|
|
|
if obj["Favorite"]:
|
|
self.get_tag(*values(obj, QU.get_tag_mvideo_obj))
|
|
else:
|
|
self.remove_tag(*values(obj, QU.delete_tag_mvideo_obj))
|
|
|
|
self.add_playstate(*values(obj, QU.add_bookmark_obj))
|
|
self.jellyfin_db.update_reference(*values(obj, QUEM.update_reference_obj))
|
|
LOG.debug(
|
|
"USERDATA mvideo [%s/%s] %s: %s",
|
|
obj["FileId"],
|
|
obj["MvideoId"],
|
|
obj["Id"],
|
|
obj["Title"],
|
|
)
|
|
|
|
@stop
|
|
@jellyfin_item
|
|
def remove(self, item_id, e_item):
|
|
"""Remove mvideoid, fileid, pathid, jellyfin reference."""
|
|
obj = {"Id": item_id}
|
|
|
|
try:
|
|
obj["MvideoId"] = e_item[0]
|
|
obj["FileId"] = e_item[1]
|
|
obj["PathId"] = e_item[2]
|
|
except TypeError:
|
|
return
|
|
|
|
self.artwork.delete(obj["MvideoId"], "musicvideo")
|
|
self.delete(*values(obj, QU.delete_musicvideo_obj))
|
|
|
|
if self.direct_path:
|
|
self.remove_path(*values(obj, QU.delete_path_obj))
|
|
|
|
self.jellyfin_db.remove_item(*values(obj, QUEM.delete_item_obj))
|
|
LOG.debug(
|
|
"DELETE musicvideo %s [%s/%s] %s",
|
|
obj["MvideoId"],
|
|
obj["PathId"],
|
|
obj["FileId"],
|
|
obj["Id"],
|
|
)
|