mirror of
https://github.com/jellyfin/jellyfin-kodi.git
synced 2026-04-27 14:00:34 +00:00
Merge d49f656d77 into 7e885106ff
This commit is contained in:
commit
15987f4b69
18 changed files with 337 additions and 28 deletions
|
|
@ -263,6 +263,10 @@ def reset_kodi():
|
|||
if name not in ["version", "videoversiontype"]:
|
||||
videodb.cursor.execute("DELETE FROM " + name)
|
||||
|
||||
# Delete the custom videoversiontype entries
|
||||
if name == "videoversiontype":
|
||||
videodb.cursor.execute("DELETE from videoversiontype WHERE id > 40800 AND owner = 1")
|
||||
|
||||
if settings("enableMusic.bool") or dialog("yesno", "{jellyfin}", translate(33162)):
|
||||
|
||||
with Database("music") as musicdb:
|
||||
|
|
@ -427,3 +431,17 @@ def get_item(kodi_id, media):
|
|||
return
|
||||
|
||||
return item
|
||||
|
||||
def get_item_by_file_id(file_id, media):
|
||||
"""Get jellyfin item based on kodi file id and media."""
|
||||
with Database("jellyfin") as jellyfindb:
|
||||
item = jellyfin_db.JellyfinDatabase(jellyfindb.cursor).get_item_by_file_id(
|
||||
file_id, media
|
||||
)
|
||||
|
||||
if not item:
|
||||
LOG.debug("Not an jellyfin item")
|
||||
|
||||
return
|
||||
|
||||
return item
|
||||
|
|
|
|||
|
|
@ -61,6 +61,15 @@ class JellyfinDatabase:
|
|||
|
||||
return self.cursor.fetchall()
|
||||
|
||||
def get_item_by_file_id(self, *args):
|
||||
|
||||
try:
|
||||
self.cursor.execute(QU.get_item_by_file_id, args)
|
||||
|
||||
return self.cursor.fetchone()[0]
|
||||
except TypeError:
|
||||
return
|
||||
|
||||
def get_item_by_kodi_id(self, *args):
|
||||
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ WHERE parent_id = ?
|
|||
AND media_type = ?
|
||||
"""
|
||||
get_item_by_media_folder = """
|
||||
SELECT jellyfin_id, jellyfin_type
|
||||
SELECT jellyfin_id, jellyfin_type, jellyfin_parent_id
|
||||
FROM jellyfin
|
||||
WHERE media_folder = ?
|
||||
"""
|
||||
|
|
@ -39,6 +39,12 @@ FROM jellyfin
|
|||
WHERE jellyfin_id LIKE ?
|
||||
"""
|
||||
get_item_by_wild_obj = ["{Id}"]
|
||||
get_item_by_file_id = """
|
||||
SELECT jellyfin_id, parent_id, media_folder, jellyfin_type, checksum
|
||||
FROM jellyfin
|
||||
WHERE kodi_fileid = ?
|
||||
AND media_type = ?
|
||||
"""
|
||||
get_item_by_kodi = """
|
||||
SELECT jellyfin_id, parent_id, media_folder, jellyfin_type, checksum
|
||||
FROM jellyfin
|
||||
|
|
|
|||
|
|
@ -328,7 +328,9 @@ class GetItemWorker(threading.Thread):
|
|||
result = self.server.http.request(request, s)
|
||||
|
||||
for item in result["Items"]:
|
||||
|
||||
# Force Jellyfin to treat version as a movie to get the right metadata
|
||||
if settings("useVersions") == "true" and item["Type"] == "Video":
|
||||
item["Type"] = "Movie"
|
||||
if item["Type"] in self.output:
|
||||
self.output[item["Type"]].put(item)
|
||||
except HTTPException as error:
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ class Service(xbmc.Monitor):
|
|||
LOG.info("Platform: %s", settings("platformDetected"))
|
||||
LOG.info("Python Version: %s", sys.version)
|
||||
LOG.info("Using dynamic paths: %s", settings("useDirectPaths") == "0")
|
||||
LOG.info("Syncing video versions: %s", settings("useVersions") == "true")
|
||||
LOG.info("Log Level: %s", self.settings["log_level"])
|
||||
|
||||
verify_kodi_defaults()
|
||||
|
|
|
|||
|
|
@ -359,7 +359,9 @@ class FullSync(object):
|
|||
|
||||
for x in items:
|
||||
if x[0] not in current and x[1] == "Movie":
|
||||
obj.remove(x[0])
|
||||
# Parent ID tied to main version so check it before removing
|
||||
if x[2] not in current:
|
||||
obj.remove(x[0])
|
||||
|
||||
@progress()
|
||||
def tvshows(self, library, dialog):
|
||||
|
|
|
|||
|
|
@ -236,6 +236,11 @@ class API(object):
|
|||
elif self.item["Container"] == "bluray":
|
||||
path = "%s/BDMV/index.bdmv" % path
|
||||
|
||||
# Loop through configured path replacements searching for a match prior to slash correction
|
||||
for local_path in self.path_data.keys():
|
||||
if local_path in path:
|
||||
path = path.replace(local_path, self.path_data[local_path])
|
||||
|
||||
path = path.replace("\\\\", "\\")
|
||||
|
||||
if "\\" in path:
|
||||
|
|
@ -245,11 +250,6 @@ class API(object):
|
|||
protocol = path.split("://")[0]
|
||||
path = path.replace(protocol, protocol.lower())
|
||||
|
||||
# Loop through configured path replacements searching for a match
|
||||
for local_path in self.path_data.keys():
|
||||
if local_path in path:
|
||||
path = path.replace(local_path, self.path_data[local_path])
|
||||
|
||||
return path
|
||||
|
||||
def get_user_artwork(self, user_id):
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ class PlayUtils(object):
|
|||
|
||||
break
|
||||
|
||||
elif not self.is_selection(info) or len(info["MediaSources"]) == 1:
|
||||
elif not self.is_selection(info) or len(info["MediaSources"]) == 1 or settings("useVersions") == "true":
|
||||
|
||||
LOG.info("Skip source selection.")
|
||||
sources.append(info["MediaSources"][0])
|
||||
|
|
|
|||
|
|
@ -142,6 +142,9 @@ class API(object):
|
|||
def get_media_folders(self):
|
||||
return self.users("/Items")
|
||||
|
||||
def get_extras(self, item_id):
|
||||
return self.users("/Items/%s/SpecialFeatures" % item_id)
|
||||
|
||||
def get_item(self, item_id):
|
||||
return self.users("/Items/%s" % item_id)
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ from __future__ import division, absolute_import, print_function, unicode_litera
|
|||
|
||||
#################################################################################################
|
||||
|
||||
import os
|
||||
import threading
|
||||
import sys
|
||||
import json
|
||||
|
|
@ -935,6 +936,29 @@ def on_play(data, server):
|
|||
return
|
||||
|
||||
item = server.jellyfin.get_item(item[0])
|
||||
|
||||
# If using Video Versions, need to match the actual file as the kodi_id is always the primary
|
||||
if settings("useVersions") == "true":
|
||||
# Addon Mode matches the jellyfin_id's properly automatically
|
||||
# This may need to be done elsewhere as well until Kodi exposes versions properly
|
||||
|
||||
# Check the playing file against the primary file; if no match get the right one
|
||||
playing_file = os.path.basename(file)
|
||||
primary_file = os.path.basename(item["Path"])
|
||||
if playing_file != primary_file:
|
||||
from .kodi import Movies
|
||||
|
||||
# If not, search kodi database for the filename and get kodi fileid
|
||||
with database.Database("video") as videodb:
|
||||
path_id = Movies(videodb.cursor).get_path(file.replace(playing_file, ""))
|
||||
file_id = Movies(videodb.cursor).get_file(path_id, playing_file)
|
||||
|
||||
# Get the proper jellyfin_id for this file
|
||||
newitem = database.get_item_by_file_id(file_id, media)
|
||||
|
||||
# Get the correct item now with the new id
|
||||
item = server.jellyfin.get_item(newitem)
|
||||
|
||||
item["PlaybackInfo"] = {"Path": file}
|
||||
playutils.set_properties(
|
||||
item,
|
||||
|
|
|
|||
|
|
@ -86,21 +86,13 @@ class Kodi(object):
|
|||
def remove_path(self, *args):
|
||||
self.cursor.execute(QU.delete_path, args)
|
||||
|
||||
def add_file(self, filename, path_id):
|
||||
def add_file(self, *args):
|
||||
file_id = self.get_file(*args)
|
||||
|
||||
try:
|
||||
self.cursor.execute(
|
||||
QU.get_file,
|
||||
(
|
||||
filename,
|
||||
path_id,
|
||||
),
|
||||
)
|
||||
file_id = self.cursor.fetchone()[0]
|
||||
except TypeError:
|
||||
if file_id is None:
|
||||
|
||||
file_id = self.create_entry_file()
|
||||
self.cursor.execute(QU.add_file, (file_id, path_id, filename))
|
||||
self.cursor.execute(QU.add_file, (file_id,) + args)
|
||||
|
||||
return file_id
|
||||
|
||||
|
|
@ -113,6 +105,15 @@ class Kodi(object):
|
|||
if path_id is not None:
|
||||
self.cursor.execute(QU.delete_file_by_path, (path_id,) + args)
|
||||
|
||||
def get_file(self, *args):
|
||||
|
||||
try:
|
||||
self.cursor.execute(QU.get_file, args)
|
||||
|
||||
return self.cursor.fetchone()[0]
|
||||
except TypeError:
|
||||
return
|
||||
|
||||
def get_filename(self, *args):
|
||||
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import division, absolute_import, print_function, unicode_literals
|
||||
|
||||
import os
|
||||
import re
|
||||
from sqlite3 import DatabaseError
|
||||
|
||||
##################################################################################################
|
||||
|
||||
from ...helper import LazyLogger
|
||||
from ...helper import LazyLogger, settings
|
||||
|
||||
from .kodi import Kodi
|
||||
from . import queries as QU
|
||||
|
|
@ -63,6 +65,58 @@ class Movies(Kodi):
|
|||
if self.cursor.fetchone()[0] == 1:
|
||||
self.cursor.execute(QU.add_video_version, args)
|
||||
|
||||
def update_videoversion(self, *args):
|
||||
self.cursor.execute(QU.check_video_version)
|
||||
if self.cursor.fetchone()[0] == 1:
|
||||
self.cursor.execute(QU.update_video_version, args)
|
||||
|
||||
def check_videoversion(self, *args):
|
||||
self.cursor.execute(QU.count_video_version, args)
|
||||
return self.cursor.fetchone()[0]
|
||||
|
||||
def get_or_create_videoversiontype(self, name, filepath, extra=False):
|
||||
"""Retrieve or create a video version type based on the Jellyfin version name or filename."""
|
||||
# If versions are disabled, always return the standard edition
|
||||
if settings("useVersions") != "true":
|
||||
return 40400
|
||||
|
||||
# Change itemtype for extras. If other types added in the future, need to adjust.
|
||||
itemtype = self.itemtype + 1 if extra else self.itemtype
|
||||
|
||||
# Get the filename without extension
|
||||
filename = os.path.splitext(os.path.basename(filepath))[0]
|
||||
|
||||
# Remove Jellyfin-added suffixes--may need to add others
|
||||
test_name = re.sub(r"/(3D|DVD|Bluray)$", "", name)
|
||||
|
||||
# If the Jellyfin version name matches the filename completely, a good version name
|
||||
# wasn't created automatically, so extract it, or set to Standard Edition
|
||||
if not extra and test_name == filename:
|
||||
# Check for ' - XXXX' at end of the name to use for version name
|
||||
match = re.search(r" - (.+)$", name)
|
||||
if match:
|
||||
name = match.group(1).strip()
|
||||
else:
|
||||
name = None
|
||||
|
||||
# Set Standard Edition for empty names or DVD/Bluray folders
|
||||
if not name or filename.lower() in ("index", "video_ts"):
|
||||
return 40400
|
||||
|
||||
# Remove */3D suffixes that Jellyfin adds (ie '.mvc/3D') as long as 3D in the name already
|
||||
if '3D' in name[:-2]:
|
||||
name = re.sub(r'\.(\w{3,4})/3D$', lambda m: ' ' + m.group(1).upper(), name)
|
||||
|
||||
# Check if this version type already exists and return it
|
||||
self.cursor.execute(QU.get_video_version_type, (name, itemtype,))
|
||||
row = self.cursor.fetchone()
|
||||
if row:
|
||||
return row[0]
|
||||
|
||||
# Create a new version type and return the id
|
||||
self.cursor.execute(QU.add_video_version_type, (name, 1, itemtype))
|
||||
return self.cursor.lastrowid
|
||||
|
||||
def update(self, *args):
|
||||
self.cursor.execute(QU.update_movie, args)
|
||||
|
||||
|
|
@ -72,7 +126,39 @@ class Movies(Kodi):
|
|||
self.cursor.execute(QU.delete_file, (file_id,))
|
||||
self.cursor.execute(QU.check_video_version)
|
||||
if self.cursor.fetchone()[0] == 1:
|
||||
# Cleanup version types
|
||||
versions = self.get_videoversions(kodi_id)
|
||||
type_id = next((row[0] for row in versions if row[1] == file_id), None)
|
||||
self.cursor.execute(QU.delete_video_version, (file_id,))
|
||||
self.delete_unused_version_type(type_id)
|
||||
|
||||
# Remove all other versions; Jellyfin creates a new base entry if other versions are left
|
||||
for row in versions:
|
||||
self.delete_video_version(row[1], row[0])
|
||||
|
||||
def delete_video_version(self, file_id, type_id):
|
||||
"""Remove video version file and cleanup version type if unused."""
|
||||
self.cursor.execute(QU.delete_file, (file_id,))
|
||||
self.cursor.execute(QU.delete_video_version, (file_id,))
|
||||
self.delete_unused_version_type(type_id)
|
||||
|
||||
def delete_unused_version_type(self, type_id):
|
||||
"""Delete video version type if no references exist, and its not a builtin type."""
|
||||
if type_id and type_id > 40800:
|
||||
self.cursor.execute(QU.count_video_version_type, (type_id,))
|
||||
if self.cursor.fetchone()[0] == 0:
|
||||
self.cursor.execute(QU.delete_video_version_type, (type_id,))
|
||||
|
||||
def get_videoversions(self, kodi_id):
|
||||
self.cursor.execute(QU.get_video_versions, (kodi_id,))
|
||||
return self.cursor.fetchall()
|
||||
|
||||
def check_movie_file_primary(self, kodi_id, file_id):
|
||||
"""Return True if the movie row with idMovie matches the provided idFile."""
|
||||
self.cursor.execute(QU.check_movie_file_primary, (kodi_id, file_id))
|
||||
row = self.cursor.fetchone()
|
||||
|
||||
return row is not None
|
||||
|
||||
def get_rating_id(self, *args):
|
||||
|
||||
|
|
|
|||
|
|
@ -70,12 +70,13 @@ FROM files
|
|||
WHERE idPath = ?
|
||||
AND strFilename = ?
|
||||
"""
|
||||
get_file_obj = ["{FileId}"]
|
||||
get_file_obj = ["{PathId}", "{Filename}"]
|
||||
get_filename = """
|
||||
SELECT strFilename
|
||||
FROM files
|
||||
WHERE idFile = ?
|
||||
"""
|
||||
get_filename_obj = ["{FileId}"]
|
||||
get_all_people = """
|
||||
SELECT name, actor_id
|
||||
FROM actor
|
||||
|
|
@ -416,8 +417,30 @@ add_video_version_obj = [
|
|||
"{MovieId}",
|
||||
"movie",
|
||||
"{VideoVersionItemType}",
|
||||
40400,
|
||||
"{VideoVersionTypeId}",
|
||||
]
|
||||
update_video_version = """
|
||||
UPDATE videoversion
|
||||
SET idMedia = ?, media_type = ?, itemType = ?, idType = ?
|
||||
WHERE idFile = ?
|
||||
"""
|
||||
update_video_version_obj = [
|
||||
"{MovieId}",
|
||||
"movie",
|
||||
"{VideoVersionItemType}",
|
||||
"{VideoVersionTypeId}",
|
||||
"{FileId}",
|
||||
]
|
||||
count_video_version = """
|
||||
SELECT COUNT(*) FROM videoversion WHERE idFile = ? AND idMedia = ? AND idType = ?
|
||||
"""
|
||||
count_video_version_obj = ["{FileId}", "{MovieId}", "{VideoVersionTypeId}"]
|
||||
count_video_version_type = """
|
||||
SELECT COUNT(*) FROM videoversion WHERE idType = ?
|
||||
"""
|
||||
get_video_versions = """
|
||||
SELECT DISTINCT idType, idFile FROM videoversion WHERE idMedia = ?
|
||||
"""
|
||||
get_videoversion_itemtype = """
|
||||
SELECT itemType FROM videoversiontype WHERE id = ?
|
||||
"""
|
||||
|
|
@ -425,6 +448,18 @@ get_videoversion_itemtype_obj = ["{VideoVersionId}"]
|
|||
check_video_version = """
|
||||
SELECT COUNT(name) FROM sqlite_master WHERE type='table' AND name='videoversion'
|
||||
"""
|
||||
get_video_version_type = """
|
||||
SELECT id FROM videoversiontype WHERE name = ? and itemType = ?
|
||||
"""
|
||||
add_video_version_type = """
|
||||
INSERT INTO videoversiontype(name, owner, itemType) VALUES (?, ?, ?)
|
||||
"""
|
||||
get_max_video_version_type = """
|
||||
SELECT MAX(id) FROM videoversiontype
|
||||
"""
|
||||
check_movie_file_primary = """
|
||||
SELECT 1 FROM movie WHERE idMovie = ? AND idFile = ? LIMIT 1
|
||||
"""
|
||||
add_musicvideo = """
|
||||
INSERT INTO musicvideo(idMVideo, idFile, c00, c04, c05, c06, c07, c08, c09, c10,
|
||||
c11, c12, premiered)
|
||||
|
|
@ -801,6 +836,11 @@ delete_video_version = """
|
|||
DELETE FROM videoversion
|
||||
WHERE idFile = ?
|
||||
"""
|
||||
delete_video_version_type = """
|
||||
DELETE FROM videoversiontype
|
||||
WHERE id = ?
|
||||
AND owner = 1
|
||||
"""
|
||||
delete_set = """
|
||||
DELETE FROM sets
|
||||
WHERE idSet = ?
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ from ..helper import (
|
|||
jellyfin_item,
|
||||
values,
|
||||
Local,
|
||||
settings,
|
||||
)
|
||||
from ..helper import LazyLogger
|
||||
from ..helper.utils import find_library
|
||||
|
|
@ -66,6 +67,11 @@ class Movies(KodiDb):
|
|||
obj["PathId"] = e_item[2]
|
||||
obj["LibraryId"] = e_item[6]
|
||||
obj["LibraryName"] = self.jellyfin_db.get_view_name(obj["LibraryId"])
|
||||
|
||||
if settings("useVersions") == "true":
|
||||
# Only process primary movie files, not versions and extras; those are processed in add_versions.
|
||||
if not self.check_movie_file_primary(obj["MovieId"], obj["FileId"]):
|
||||
return
|
||||
except TypeError:
|
||||
update = False
|
||||
LOG.debug("MovieId %s not found", obj["Id"])
|
||||
|
|
@ -127,6 +133,7 @@ class Movies(KodiDb):
|
|||
tags.append("Favorite movies")
|
||||
|
||||
obj["Tags"] = tags
|
||||
obj["media_sources"] = item.get("MediaSources")
|
||||
|
||||
if update:
|
||||
self.movie_update(obj)
|
||||
|
|
@ -142,10 +149,80 @@ class Movies(KodiDb):
|
|||
self.add_people(*values(obj, QU.add_people_movie_obj))
|
||||
self.add_streams(*values(obj, QU.add_streams_obj))
|
||||
self.artwork.add(obj["Artwork"], obj["MovieId"], "movie")
|
||||
self.artwork.add(obj["Artwork"], obj["FileId"], "videoversion")
|
||||
self.item_ids.append(obj["Id"])
|
||||
self.current_type_ids = set()
|
||||
self.add_versions(API, obj)
|
||||
self.add_versions(API, obj, True) # Add extras as versions
|
||||
self.cleanup_versions(obj)
|
||||
|
||||
return not update
|
||||
|
||||
def add_versions(self, API, obj, extra=False):
|
||||
"""Add all additional media sources as Kodi versions."""
|
||||
if settings("useVersions") != "true" or (extra and settings("useExtras") != "true"):
|
||||
return
|
||||
|
||||
sources = self.server.jellyfin.get_extras(obj["Id"]) if extra else obj["media_sources"]
|
||||
for source in sources:
|
||||
if obj["Id"] == source["Id"]:
|
||||
# Found primary version, so skip
|
||||
continue
|
||||
|
||||
# Extras already in the right format from get_extras, but versions need to be pulled
|
||||
jfitem = source if extra else self.server.jellyfin.get_item(source["Id"])
|
||||
version = self.objects.map(jfitem, "Movie")
|
||||
version["MovieId"] = obj["MovieId"]
|
||||
version["LibraryId"] = obj["LibraryId"]
|
||||
version["JellyfinParentId"] = obj["Id"]
|
||||
|
||||
# Version specific metadata
|
||||
version["DateAdded"] = Local(version["DateAdded"]).split(".")[0].replace("T", " ")
|
||||
version["Resume"] = API.adjust_resume((version["Resume"] or 0) / 10000000.0)
|
||||
version["Runtime"] = round(float((version["Runtime"] or 0) / 10000000.0), 6)
|
||||
version["PlayCount"] = API.get_playcount(version["Played"], version["PlayCount"])
|
||||
version["Video"] = API.video_streams(version["Video"] or [], version["Container"])
|
||||
version["Audio"] = API.audio_streams(version["Audio"] or [])
|
||||
version["Streams"] = API.media_streams(version["Video"], version["Audio"], version["Subtitles"])
|
||||
version["Artwork"] = API.get_all_artwork(self.objects.map(jfitem, "Artwork"))
|
||||
if version["DatePlayed"]:
|
||||
version["DatePlayed"] = Local(version["DatePlayed"]).split(".")[0].replace("T", " ")
|
||||
|
||||
version["Path"] = API.get_file_path(version["Path"])
|
||||
self.get_path_filename(version)
|
||||
version["PathId"] = self.add_path(*values(version, QU.add_path_obj))
|
||||
|
||||
# Find the correct version name for this source
|
||||
version_type_id = self.get_or_create_videoversiontype(source.get("Name"), version["SourceFilename"], extra)
|
||||
version["VideoVersionTypeId"] = version_type_id
|
||||
version["VideoVersionItemType"] = self.itemtype + 1 if extra else self.itemtype
|
||||
self.current_type_ids.add(version_type_id)
|
||||
|
||||
version["FileId"] = self.get_file(*values(version, QU.get_file_obj))
|
||||
if version["FileId"]:
|
||||
# Version already exists
|
||||
self.update_videoversion(*values(version, QU.update_video_version_obj))
|
||||
self.jellyfin_db.update_reference(*values(version, QUEM.update_reference_obj))
|
||||
else:
|
||||
# Add the version file and version type
|
||||
version["FileId"] = self.add_file(*values(version, QU.add_file_obj))
|
||||
self.add_videoversion(*values(version, QU.add_video_version_obj))
|
||||
self.jellyfin_db.add_reference(*values(version, QUEM.add_reference_movie_obj))
|
||||
|
||||
self.update_file(*values(version, QU.update_file_obj))
|
||||
self.add_playstate(*values(version, QU.add_bookmark_obj))
|
||||
self.add_streams(*values(version, QU.add_streams_obj))
|
||||
self.artwork.add(version["Artwork"], version["FileId"], "videoversion")
|
||||
|
||||
def cleanup_versions(self, obj):
|
||||
"""Cleanup versions that are no longer in Jellyfin"""
|
||||
versions = self.get_videoversions(obj["MovieId"])
|
||||
for row in versions:
|
||||
type_id = row[0]
|
||||
file_id = row[1]
|
||||
if file_id != obj["FileId"] and type_id not in self.current_type_ids:
|
||||
self.delete_video_version(file_id, type_id)
|
||||
|
||||
def movie_add(self, obj):
|
||||
"""Add object to kodi."""
|
||||
obj["RatingId"] = self.create_entry_rating()
|
||||
|
|
@ -158,6 +235,15 @@ class Movies(KodiDb):
|
|||
obj["FileId"] = self.add_file(*values(obj, QU.add_file_obj))
|
||||
obj["VideoVersionItemType"] = self.itemtype
|
||||
|
||||
version_name = None
|
||||
for source in obj["media_sources"]:
|
||||
# First media source isn't always the main version, so find the correct version name for the primary
|
||||
if obj["Id"] == source["Id"]:
|
||||
version_name = source.get("Name")
|
||||
break
|
||||
version_type_id = self.get_or_create_videoversiontype(version_name, obj["SourceFilename"])
|
||||
obj["VideoVersionTypeId"] = version_type_id
|
||||
|
||||
self.add(*values(obj, QU.add_movie_obj))
|
||||
self.add_videoversion(*values(obj, QU.add_video_version_obj))
|
||||
self.jellyfin_db.add_reference(*values(obj, QUEM.add_reference_movie_obj))
|
||||
|
|
@ -217,6 +303,7 @@ class Movies(KodiDb):
|
|||
if "\\" in obj["Path"]
|
||||
else obj["Path"].rsplit("/", 1)[1]
|
||||
)
|
||||
obj["SourceFilename"] = obj["Filename"]
|
||||
|
||||
if self.direct_path:
|
||||
|
||||
|
|
@ -225,18 +312,20 @@ class Movies(KodiDb):
|
|||
|
||||
obj["Path"] = obj["Path"].replace(obj["Filename"], "")
|
||||
|
||||
sl = "\\" if "\\" in obj["Path"] else "/"
|
||||
"""check dvd directories and point it to ./VIDEO_TS/VIDEO_TS.IFO"""
|
||||
if validate_dvd_dir(obj["Path"] + obj["Filename"]):
|
||||
obj["Path"] = obj["Path"] + obj["Filename"] + "/VIDEO_TS/"
|
||||
obj["Path"] = obj["Path"] + obj["Filename"] + sl + "VIDEO_TS" + sl
|
||||
obj["Filename"] = "VIDEO_TS.IFO"
|
||||
LOG.debug("DVD directory %s", obj["Path"])
|
||||
|
||||
"""check bluray directories and point it to ./BDMV/index.bdmv"""
|
||||
if validate_bluray_dir(obj["Path"] + obj["Filename"]):
|
||||
obj["Path"] = obj["Path"] + obj["Filename"] + "/BDMV/"
|
||||
obj["Path"] = obj["Path"] + obj["Filename"] + sl + "BDMV" + sl
|
||||
obj["Filename"] = "index.bdmv"
|
||||
LOG.debug("Bluray directory %s", obj["Path"])
|
||||
|
||||
obj["SourceFilename"] = obj["Filename"]
|
||||
else:
|
||||
obj["Path"] = "plugin://plugin.video.jellyfin/%s/" % obj["LibraryId"]
|
||||
params = {
|
||||
|
|
|
|||
|
|
@ -616,7 +616,7 @@ class TVShows(KodiDb):
|
|||
|
||||
temp_obj = dict(obj)
|
||||
temp_obj["Filename"] = self.get_filename(
|
||||
*values(temp_obj, QU.get_file_obj)
|
||||
*values(temp_obj, QU.get_filename_obj)
|
||||
)
|
||||
temp_obj["Path"] = "plugin://plugin.video.jellyfin/"
|
||||
self.remove_file(*values(temp_obj, QU.delete_file_obj))
|
||||
|
|
@ -625,7 +625,7 @@ class TVShows(KodiDb):
|
|||
|
||||
temp_obj = dict(obj)
|
||||
temp_obj["Filename"] = self.get_filename(
|
||||
*values(temp_obj, QU.get_file_obj)
|
||||
*values(temp_obj, QU.get_filename_obj)
|
||||
)
|
||||
temp_obj["PathId"] = self.get_path("plugin://plugin.video.jellyfin/")
|
||||
temp_obj["FileId"] = self.add_file(*values(temp_obj, QU.add_file_obj))
|
||||
|
|
|
|||
|
|
@ -1257,3 +1257,10 @@ msgctxt "#33261"
|
|||
msgid "Off"
|
||||
msgstr "Off"
|
||||
|
||||
msgctxt "#30900"
|
||||
msgid "Sync video versions"
|
||||
msgstr "Sync video versions"
|
||||
|
||||
msgctxt "#30901"
|
||||
msgid "Sync video extras"
|
||||
msgstr "Sync video extras"
|
||||
|
|
|
|||
|
|
@ -1180,3 +1180,11 @@ msgstr "16.0 Mbps"
|
|||
msgctxt "#33239"
|
||||
msgid "96"
|
||||
msgstr "96"
|
||||
|
||||
msgctxt "#30900"
|
||||
msgid "Sync video versions"
|
||||
msgstr "Sync video versions"
|
||||
|
||||
msgctxt "#30901"
|
||||
msgid "Sync video extras"
|
||||
msgstr "Sync video extras"
|
||||
|
|
|
|||
|
|
@ -108,6 +108,19 @@
|
|||
</constraints>
|
||||
<control type="spinner" format="string"/>
|
||||
</setting>
|
||||
<setting id="useVersions" type="boolean" label="30900" help="">
|
||||
<level>0</level>
|
||||
<default>false</default>
|
||||
<control type="toggle"/>
|
||||
</setting>
|
||||
<setting id="useExtras" type="boolean" label="30901" help="" parent="useVersions">
|
||||
<level>0</level>
|
||||
<default>false</default>
|
||||
<dependencies>
|
||||
<dependency type="enable" setting="useVersions">true</dependency>
|
||||
</dependencies>
|
||||
<control type="toggle"/>
|
||||
</setting>
|
||||
</group>
|
||||
<group id="3" label="33175">
|
||||
<setting id="limitIndex" type="integer" label="30515" help="">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue