# -*- coding: utf-8 -*- from __future__ import division, absolute_import, print_function, unicode_literals ################################################################################################## from . import artwork from . import queries as QU from helper import values from sqlite3 import IntegrityError from helper import LazyLogger ################################################################################################## LOG = LazyLogger(__name__) ################################################################################################## class Kodi(object): def __init__(self): self.artwork = artwork.Artwork(self.cursor) try: self.cursor.execute(QU.get_all_people) except: # Failed to load the table. Has the table been created? self._people_cache = {} else: self._people_cache = dict(self.cursor.fetchall()) def create_entry_path(self): self.cursor.execute(QU.create_path) return self.cursor.fetchone()[0] + 1 def create_entry_file(self): self.cursor.execute(QU.create_file) return self.cursor.fetchone()[0] + 1 def create_entry_genre(self): self.cursor.execute(QU.create_genre) return self.cursor.fetchone()[0] + 1 def create_entry_studio(self): self.cursor.execute(QU.create_studio) return self.cursor.fetchone()[0] + 1 def create_entry_bookmark(self): self.cursor.execute(QU.create_bookmark) return self.cursor.fetchone()[0] + 1 def create_entry_tag(self): self.cursor.execute(QU.create_tag) return self.cursor.fetchone()[0] + 1 def add_path(self, *args): path_id = self.get_path(*args) if path_id is None: path_id = self.create_entry_path() self.cursor.execute(QU.add_path, (path_id,) + args) return path_id def get_path(self, *args): try: self.cursor.execute(QU.get_path, args) return self.cursor.fetchone()[0] except TypeError: return def update_path(self, *args): self.cursor.execute(QU.update_path, args) def remove_path(self, *args): self.cursor.execute(QU.delete_path, args) def add_file(self, filename, path_id): try: self.cursor.execute(QU.get_file, (filename, path_id,)) file_id = self.cursor.fetchone()[0] except TypeError: file_id = self.create_entry_file() self.cursor.execute(QU.add_file, (file_id, path_id, filename)) return file_id def update_file(self, *args): self.cursor.execute(QU.update_file, args) def remove_file(self, path, *args): path_id = self.get_path(path) if path_id is not None: self.cursor.execute(QU.delete_file_by_path, (path_id,) + args) def get_filename(self, *args): try: self.cursor.execute(QU.get_filename, args) return self.cursor.fetchone()[0] except TypeError: return "" def add_people(self, people, *args): def add_thumbnail(person_id, person, person_type): if person['imageurl']: art = person_type.lower() if "writing" in art: art = "writer" self.artwork.update(person['imageurl'], person_id, art, "thumb") cast_order = 1 bulk_updates = {} for person in people: person_id = self.get_person(person['Name']) if person['Type'] == 'Actor': sql = QU.update_actor role = person.get('Role') bulk_updates.setdefault(sql, []).append((person_id,) + args + (role, cast_order,)) cast_order += 1 elif person['Type'] == 'Director': sql = QU.update_link.replace("{LinkType}", 'director_link') bulk_updates.setdefault(sql, []).append((person_id,) + args) elif person['Type'] == 'Writer': sql = QU.update_link.replace("{LinkType}", 'writer_link') bulk_updates.setdefault(sql, []).append((person_id,) + args) elif person['Type'] == 'Artist': sql = QU.update_link.replace("{LinkType}", 'actor_link') bulk_updates.setdefault(sql, []).append((person_id,) + args) add_thumbnail(person_id, person, person['Type']) for sql, parameters in bulk_updates.items(): self.cursor.executemany(sql, parameters) def add_person(self, *args): self.cursor.execute(QU.add_person, args) return self.cursor.lastrowid def _get_person(self, *args): try: return self.add_person(*args) except IntegrityError: # The person already exists in the database # Now we can do the expensive operation of fetching the id self.cursor.execute(QU.get_person, args) return self.cursor.fetchone()[0] def get_person(self, *args): try: return self._people_cache[args] except KeyError: person_id = self._get_person(*args) self._people_cache[args] = person_id return person_id def add_genres(self, genres, *args): ''' Delete current genres first for clean slate. ''' self.cursor.execute(QU.delete_genres, args) for genre in genres: self.cursor.execute(QU.update_genres, (self.get_genre(genre),) + args) def add_genre(self, *args): genre_id = self.create_entry_genre() self.cursor.execute(QU.add_genre, (genre_id,) + args) return genre_id def get_genre(self, *args): try: self.cursor.execute(QU.get_genre, args) return self.cursor.fetchone()[0] except TypeError: return self.add_genre(*args) def add_studios(self, studios, *args): for studio in studios: studio_id = self.get_studio(studio) self.cursor.execute(QU.update_studios, (studio_id,) + args) def add_studio(self, *args): studio_id = self.create_entry_studio() self.cursor.execute(QU.add_studio, (studio_id,) + args) return studio_id def get_studio(self, *args): try: self.cursor.execute(QU.get_studio, args) return self.cursor.fetchone()[0] except TypeError: return self.add_studio(*args) def add_streams(self, file_id, streams, runtime): ''' First remove any existing entries Then re-add video, audio and subtitles. ''' self.cursor.execute(QU.delete_streams, (file_id,)) if streams: for track in streams['video']: track['FileId'] = file_id track['Runtime'] = runtime self.add_stream_video(*values(track, QU.add_stream_video_obj)) for track in streams['audio']: track['FileId'] = file_id self.add_stream_audio(*values(track, QU.add_stream_audio_obj)) for track in streams['subtitle']: self.add_stream_sub(*values({'language': track, 'FileId': file_id}, QU.add_stream_sub_obj)) def add_stream_video(self, *args): self.cursor.execute(QU.add_stream_video, args) def add_stream_audio(self, *args): self.cursor.execute(QU.add_stream_audio, args) def add_stream_sub(self, *args): self.cursor.execute(QU.add_stream_sub, args) def add_playstate(self, file_id, playcount, date_played, resume, *args): ''' Delete the existing resume point. Set the watched count. ''' self.cursor.execute(QU.delete_bookmark, (file_id,)) self.set_playcount(playcount, date_played, file_id) if resume: bookmark_id = self.create_entry_bookmark() self.cursor.execute(QU.add_bookmark, (bookmark_id, file_id, resume,) + args) def set_playcount(self, *args): self.cursor.execute(QU.update_playcount, args) def add_tags(self, tags, *args): self.cursor.execute(QU.delete_tags, args) for tag in tags: tag_id = self.get_tag(tag, *args) def add_tag(self, *args): tag_id = self.create_entry_tag() self.cursor.execute(QU.add_tag, (tag_id,) + args) return tag_id def get_tag(self, tag, *args): try: self.cursor.execute(QU.get_tag, (tag,)) tag_id = self.cursor.fetchone()[0] except TypeError: tag_id = self.add_tag(tag) self.cursor.execute(QU.update_tag, (tag_id,) + args) return tag_id def remove_tag(self, tag, *args): try: self.cursor.execute(QU.get_tag, (tag,)) tag_id = self.cursor.fetchone()[0] except TypeError: return self.cursor.execute(QU.delete_tag, (tag_id,) + args)