Merge pull request #475 from oddstr13/plural(s)

Fix: Get specific library vs list of libraries
This commit is contained in:
mcarlton00 2021-02-24 21:12:37 -05:00 committed by GitHub
commit 01b114c19e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 88 additions and 33 deletions

View file

@ -5,6 +5,8 @@ from __future__ import division, absolute_import, print_function, unicode_litera
from database import queries as QU from database import queries as QU
from helper import LazyLogger from helper import LazyLogger
from jellyfin.utils import sqlite_namedtuple_factory
################################################################################################## ##################################################################################################
LOG = LazyLogger(__name__) LOG = LazyLogger(__name__)
@ -16,6 +18,7 @@ class JellyfinDatabase():
def __init__(self, cursor): def __init__(self, cursor):
self.cursor = cursor self.cursor = cursor
cursor.row_factory = sqlite_namedtuple_factory
def get_item_by_id(self, *args): def get_item_by_id(self, *args):
self.cursor.execute(QU.get_item, args) self.cursor.execute(QU.get_item, args)
@ -124,8 +127,8 @@ class JellyfinDatabase():
def remove_view(self, *args): def remove_view(self, *args):
self.cursor.execute(QU.delete_view, args) self.cursor.execute(QU.delete_view, args)
def get_views(self, *args): def get_views(self):
self.cursor.execute(QU.get_views, args) self.cursor.execute(QU.get_views)
return self.cursor.fetchall() return self.cursor.fetchall()

View file

@ -66,7 +66,7 @@ FROM jellyfin
WHERE jellyfin_parent_id = ? WHERE jellyfin_parent_id = ?
""" """
get_view = """ get_view = """
SELECT view_name, media_type SELECT *
FROM view FROM view
WHERE view_id = ? WHERE view_id = ?
""" """

View file

@ -811,7 +811,7 @@ def get_themes(api_client):
with Database('jellyfin') as jellyfindb: with Database('jellyfin') as jellyfindb:
all_views = jellyfin_db.JellyfinDatabase(jellyfindb.cursor).get_views() all_views = jellyfin_db.JellyfinDatabase(jellyfindb.cursor).get_views()
views = [x[0] for x in all_views if x[2] in ('movies', 'tvshows', 'mixed')] views = [x.view_id for x in all_views if x.media_type in ('movies', 'tvshows', 'mixed')]
items = {} items = {}
server = api_client.config.data['auth.server'] server = api_client.config.data['auth.server']

View file

@ -82,13 +82,13 @@ class FullSync(object):
for selected in libraries: for selected in libraries:
if selected not in [x.replace('Mixed:', "") for x in self.sync['Libraries']]: if selected not in [x.replace('Mixed:', "") for x in self.sync['Libraries']]:
library = self.get_libraries(selected) library = self.get_library(selected)
if library: if library:
self.sync['Libraries'].append("Mixed:%s" % selected if library[1] == 'mixed' else selected) self.sync['Libraries'].append("Mixed:%s" % selected)
if library[1] in ('mixed', 'movies'): if library.media_type in ('mixed', 'movies'):
self.sync['Libraries'].append('Boxsets:%s' % selected) self.sync['Libraries'].append('Boxsets:%s' % selected)
else: else:
self.sync['Libraries'].append(selected) self.sync['Libraries'].append(selected)
@ -100,13 +100,13 @@ class FullSync(object):
if not xmls.advanced_settings() and self.sync['Libraries']: if not xmls.advanced_settings() and self.sync['Libraries']:
self.start() self.start()
def get_libraries(self, library_id=None): def get_libraries(self):
with Database('jellyfin') as jellyfindb: with Database('jellyfin') as jellyfindb:
if library_id is None: return jellyfin_db.JellyfinDatabase(jellyfindb.cursor).get_views()
return jellyfin_db.JellyfinDatabase(jellyfindb.cursor).get_views()
else: def get_library(self, library_id):
return jellyfin_db.JellyfinDatabase(jellyfindb.cursor).get_view(library_id) with Database('jellyfin') as jellyfindb:
return jellyfin_db.JellyfinDatabase(jellyfindb.cursor).get_view(library_id)
def mapping(self): def mapping(self):
@ -129,9 +129,8 @@ class FullSync(object):
libraries = [] libraries = []
for library in self.get_libraries(): for library in self.get_libraries():
if library.media_type in ('movies', 'tvshows', 'musicvideos', 'music', 'mixed'):
if library[2] in ('movies', 'tvshows', 'musicvideos', 'music', 'mixed'): libraries.append({'Id': library.view_id, 'Name': library.view_name, 'Media': library.media_type})
libraries.append({'Id': library[0], 'Name': library[1], 'Media': library[2]})
libraries = self.select_libraries(libraries) libraries = self.select_libraries(libraries)
@ -223,11 +222,12 @@ class FullSync(object):
if not sync_id or sync_id == 'Refresh': if not sync_id or sync_id == 'Refresh':
libraries = self.get_libraries() libraries = self.get_libraries()
else: else:
libraries = self.get_libraries(sync_id) _lib = self.get_library(sync_id)
libraries = [_lib] if _lib else []
for entry in libraries: for entry in libraries:
if entry[2] == 'boxsets': if entry.media_type == 'boxsets':
boxset_library = {'Id': entry[0], 'Name': entry[1]} boxset_library = {'Id': entry.view_id, 'Name': entry.view_name}
break break
if boxset_library: if boxset_library:
@ -524,7 +524,7 @@ class FullSync(object):
db = jellyfin_db.JellyfinDatabase(jellyfindb.cursor) db = jellyfin_db.JellyfinDatabase(jellyfindb.cursor)
library = db.get_view(library_id.replace('Mixed:', "")) library = db.get_view(library_id.replace('Mixed:', ""))
items = db.get_item_by_media_folder(library_id.replace('Mixed:', "")) items = db.get_item_by_media_folder(library_id.replace('Mixed:', ""))
media = 'music' if library[1] == 'music' else 'video' media = 'music' if library.media_type == 'music' else 'video'
if media == 'music': if media == 'music':
settings('MusicRescan.bool', False) settings('MusicRescan.bool', False)
@ -535,7 +535,7 @@ class FullSync(object):
with self.library.music_database_lock if media == 'music' else self.library.database_lock: with self.library.music_database_lock if media == 'music' else self.library.database_lock:
with Database(media) as kodidb: with Database(media) as kodidb:
if library[1] == 'mixed': if library.media_type == 'mixed':
movies = [x for x in items if x[1] == 'Movie'] movies = [x for x in items if x[1] == 'Movie']
tvshows = [x for x in items if x[1] == 'Series'] tvshows = [x for x in items if x[1] == 'Series']
@ -545,7 +545,7 @@ class FullSync(object):
for item in movies: for item in movies:
obj(item[0]) obj(item[0])
dialog.update(int((float(count) / float(len(items)) * 100)), heading="%s: %s" % (translate('addon_name'), library[0])) dialog.update(int((float(count) / float(len(items)) * 100)), heading="%s: %s" % (translate('addon_name'), library.view_name))
count += 1 count += 1
obj = TVShows(self.server, jellyfindb, kodidb, direct_path, library).remove obj = TVShows(self.server, jellyfindb, kodidb, direct_path, library).remove
@ -553,7 +553,7 @@ class FullSync(object):
for item in tvshows: for item in tvshows:
obj(item[0]) obj(item[0])
dialog.update(int((float(count) / float(len(items)) * 100)), heading="%s: %s" % (translate('addon_name'), library[0])) dialog.update(int((float(count) / float(len(items)) * 100)), heading="%s: %s" % (translate('addon_name'), library.view_name))
count += 1 count += 1
else: else:
default_args = (self.server, jellyfindb, kodidb, direct_path) default_args = (self.server, jellyfindb, kodidb, direct_path)

View file

@ -1,3 +1,5 @@
from collections import namedtuple
from six import string_types from six import string_types
from six.moves import collections_abc from six.moves import collections_abc
@ -41,3 +43,15 @@ def clean_none_dict_values(obj):
queue.append(value) queue.append(value)
return obj return obj
def sqlite_namedtuple_factory(cursor, row):
"""
Usage:
con.row_factory = namedtuple_factory
http://peter-hoffmann.com/2010/python-sqlite-namedtuple-factory.html
"""
fields = [col[0] for col in cursor.description]
Row = namedtuple("Row", fields)
return Row(*row)

View file

@ -471,10 +471,10 @@ class Library(threading.Thread):
available = [x for x in sync['SortedViews'] if x not in whitelist] available = [x for x in sync['SortedViews'] if x not in whitelist]
for library in available: for library in available:
name, media = db.get_view(library) view = db.get_view(library)
if media in ('movies', 'tvshows', 'musicvideos', 'mixed', 'music'): if view.media_type in ('movies', 'tvshows', 'musicvideos', 'mixed', 'music'):
libraries.append({'Id': library, 'Name': name}) libraries.append({'Id': view.view_id, 'Name': view.view_name})
choices = [x['Name'] for x in libraries] choices = [x['Name'] for x in libraries]
choices.insert(0, translate(33121)) choices.insert(0, translate(33121))

View file

@ -174,9 +174,8 @@ class Views(object):
removed = [] removed = []
for view in views: for view in views:
if view.view_id not in self.sync['SortedViews']:
if view[0] not in self.sync['SortedViews']: removed.append(view.view_id)
removed.append(view[0])
if removed: if removed:
event('RemoveLibrary', {'Id': ','.join(removed)}) event('RemoveLibrary', {'Id': ','.join(removed)})
@ -204,7 +203,7 @@ class Views(object):
view = db.get_view(library) view = db.get_view(library)
if view: if view:
view = {'Id': library, 'Name': view[0], 'Tag': view[0], 'Media': view[1]} view = {'Id': library, 'Name': view.view_name, 'Tag': view.view_name, 'Media': view.media_type}
if view['Media'] == 'mixed': if view['Media'] == 'mixed':
for media in ('movies', 'tvshows'): for media in ('movies', 'tvshows'):
@ -697,10 +696,10 @@ class Views(object):
except IndexError as error: except IndexError as error:
LOG.exception(error) LOG.exception(error)
for library in (libraries or []): for library in libraries:
view = {'Id': library[0], 'Name': library[1], 'Tag': library[1], 'Media': library[2]} view = {'Id': library.view_id, 'Name': library.view_name, 'Tag': library.view_name, 'Media': library.media_type}
if library[0] in [x.replace('Mixed:', "") for x in self.sync['Whitelist']]: # Synced libraries if library.view_id in [x.replace('Mixed:', "") for x in self.sync['Whitelist']]: # Synced libraries
if view['Media'] in ('movies', 'tvshows', 'musicvideos', 'mixed'): if view['Media'] in ('movies', 'tvshows', 'musicvideos', 'mixed'):

View file

@ -0,0 +1,39 @@
from sqlite3 import Cursor
from typing import Any, List, Optional, NamedTuple
class ViewRow(NamedTuple):
view_id: str
view_name: str
media_type: str
class JellyfinDatabase:
cursor: Cursor = ...
def __init__(self, cursor: Cursor) -> None: ...
def get_view(self, *args: Any) -> Optional[ViewRow]: ...
def get_views(self) -> List[ViewRow]: ...
# def get_item_by_id(self, *args: Any): ...
# def add_reference(self, *args: Any) -> None: ...
# def update_reference(self, *args: Any) -> None: ...
# def update_parent_id(self, *args: Any) -> None: ...
# def get_item_id_by_parent_id(self, *args: Any): ...
# def get_item_by_parent_id(self, *args: Any): ...
# def get_item_by_media_folder(self, *args: Any): ...
# def get_item_by_wild_id(self, item_id: Any): ...
# def get_checksum(self, *args: Any): ...
# def get_item_by_kodi_id(self, *args: Any): ...
# def get_full_item_by_kodi_id(self, *args: Any): ...
# def get_media_by_id(self, *args: Any): ...
# def get_media_by_parent_id(self, *args: Any): ...
# def remove_item(self, *args: Any) -> None: ...
# def remove_items_by_parent_id(self, *args: Any) -> None: ...
# def remove_item_by_kodi_id(self, *args: Any) -> None: ...
# def remove_wild_item(self, item_id: Any) -> None: ...
# def get_view_name(self, item_id: Any): ...
# def add_view(self, *args: Any) -> None: ...
# def remove_view(self, *args: Any) -> None: ...
# def get_views_by_media(self, *args: Any): ...
# def get_items_by_media(self, *args: Any): ...
# def remove_media_by_parent_id(self, *args: Any) -> None: ...