jellyfin-kodi/resources/lib/objects/musicvideos.py

232 lines
8.8 KiB
Python

# -*- coding: utf-8 -*-
##################################################################################################
import datetime
import logging
import re
import urllib
from obj import Objects
from kodi import MusicVideos as KodiDb, queries as QU
from database import jellyfin_db, queries as QUEM
from helper import api, stop, validate, library_check, jellyfin_item, values, Local
##################################################################################################
LOG = logging.getLogger("JELLYFIN." + __name__)
##################################################################################################
class MusicVideos(KodiDb):
def __init__(self, server, jellyfindb, videodb, direct_path):
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 = []
KodiDb.__init__(self, videodb.cursor)
@stop()
@jellyfin_item()
@library_check()
def musicvideo(self, item, e_item, library):
''' 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_data = self.server.auth.get_server_info(self.server.auth.server_id)
server_address = self.server.auth.get_server_address(server_data, server_data['LastConnectionMode'])
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]
except TypeError:
update = False
LOG.debug("MvideoId for %s not found", obj['Id'])
obj['MvideoId'] = self.create_entry()
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'])
obj['Path'] = API.get_file_path(obj['Path'])
obj['LibraryId'] = library['Id']
obj['LibraryName'] = library['Name']
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 2021, 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.info("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.info("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 Exception("Failed to validate path. User stopped.")
obj['Path'] = obj['Path'].replace(obj['Filename'], "")
else:
obj['Path'] = "plugin://plugin.video.jellyfin/"
params = {
'filename': obj['Filename'].encode('utf-8'),
'id': obj['Id'],
'dbid': obj['MvideoId'],
'mode': "play"
}
obj['Filename'] = "%s?%s" % (obj['Path'], urllib.urlencode(params))
@stop()
@jellyfin_item()
def userdata(self, item, e_item):
''' This updates: Favorite, LastPlayedDate, Playcount, PlaybackPositionTicks
Poster with progress bar
'''
server_data = self.server.auth.get_server_info(self.server.auth.server_id)
server_address = self.server.auth.get_server_address(server_data, server_data['LastConnectionMode'])
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.info("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.info("DELETE musicvideo %s [%s/%s] %s", obj['MvideoId'], obj['PathId'], obj['FileId'], obj['Id'])