PlexKodiConnect/resources/lib/plexdb_functions.py

507 lines
16 KiB
Python
Raw Normal View History

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals
2018-06-22 03:24:37 +10:00
from . import utils
from . import variables as v
2016-08-30 04:00:16 +10:00
###############################################################################
class Get_Plex_DB():
2016-02-10 21:00:32 +11:00
"""
Usage: with Get_Plex_DB() as plex_db:
plex_db.do_something()
2016-02-10 21:00:32 +11:00
On exiting "with" (no matter what), commits get automatically committed
and the db gets closed
"""
def __enter__(self):
2018-06-22 03:24:37 +10:00
self.plexconn = utils.kodi_sql('plex')
return Plex_DB_Functions(self.plexconn.cursor())
2016-02-10 21:00:32 +11:00
def __exit__(self, type, value, traceback):
self.plexconn.commit()
self.plexconn.close()
2016-02-10 21:00:32 +11:00
class Plex_DB_Functions():
def __init__(self, plexcursor):
self.plexcursor = plexcursor
def getViews(self):
"""
Returns a list of view_id
"""
views = []
query = '''
SELECT view_id
FROM view
'''
self.plexcursor.execute(query)
rows = self.plexcursor.fetchall()
for row in rows:
views.append(row[0])
return views
2016-01-28 06:41:28 +11:00
def getAllViewInfo(self):
"""
Returns a list of dicts for all Plex libraries:
{
'id': view_id,
'name': view_name,
'itemtype': kodi_type
'kodi_tagid'
'sync_to_kodi'
}
"""
plexcursor = self.plexcursor
2016-01-28 06:41:28 +11:00
views = []
query = '''SELECT * FROM view'''
plexcursor.execute(query)
rows = plexcursor.fetchall()
2016-01-28 06:41:28 +11:00
for row in rows:
views.append({'id': row[0],
'name': row[1],
'itemtype': row[2],
'kodi_tagid': row[3],
'sync_to_kodi': row[4]})
2016-01-28 06:41:28 +11:00
return views
def getView_byId(self, view_id):
"""
Returns tuple (view_name, kodi_type, kodi_tagid) for view_id
"""
query = '''
SELECT view_name, kodi_type, kodi_tagid
FROM view
WHERE view_id = ?
'''
self.plexcursor.execute(query, (view_id,))
view = self.plexcursor.fetchone()
return view
def getView_byType(self, kodi_type):
"""
Returns a list of dicts for kodi_type:
{'id': view_id, 'name': view_name, 'itemtype': kodi_type}
"""
views = []
query = '''
SELECT view_id, view_name, kodi_type
FROM view
WHERE kodi_type = ?
'''
self.plexcursor.execute(query, (kodi_type,))
rows = self.plexcursor.fetchall()
for row in rows:
views.append({
'id': row[0],
2016-01-28 06:41:28 +11:00
'name': row[1],
'itemtype': row[2]
})
return views
def getView_byName(self, view_name):
"""
Returns the view_id for view_name (or None)
"""
query = '''
SELECT view_id
FROM view
WHERE view_name = ?
'''
self.plexcursor.execute(query, (view_name,))
try:
view = self.plexcursor.fetchone()[0]
except TypeError:
view = None
return view
def addView(self, view_id, view_name, kodi_type, kodi_tagid, sync=True):
"""
Appends an entry to the view table
sync=False: Plex library won't be synced to Kodi
"""
query = '''
INSERT INTO view(
view_id, view_name, kodi_type, kodi_tagid, sync_to_kodi)
VALUES (?, ?, ?, ?, ?)
'''
self.plexcursor.execute(query,
(view_id,
view_name,
kodi_type,
kodi_tagid,
1 if sync is True else 0))
def updateView(self, view_name, kodi_tagid, view_id):
"""
Updates the view_id with view_name and kodi_tagid
"""
query = '''
UPDATE view
SET view_name = ?, kodi_tagid = ?
WHERE view_id = ?
'''
self.plexcursor.execute(query, (view_name, kodi_tagid, view_id))
def removeView(self, view_id):
query = '''
DELETE FROM view
WHERE view_id = ?
'''
self.plexcursor.execute(query, (view_id,))
2017-02-01 22:16:35 +11:00
def get_items_by_viewid(self, view_id):
"""
Returns a list for view_id with one item like this:
{
'plex_id': xxx
'kodi_type': xxx
}
"""
query = '''SELECT plex_id, kodi_type FROM plex WHERE view_id = ?'''
self.plexcursor.execute(query, (view_id, ))
rows = self.plexcursor.fetchall()
res = []
for row in rows:
res.append({'plex_id': row[0], 'kodi_type': row[1]})
return res
def getItem_byFileId(self, kodi_fileid, kodi_type):
2016-03-12 00:42:14 +11:00
"""
Returns plex_id for kodi_fileid and kodi_type
2016-03-18 02:03:02 +11:00
None if not found
2016-03-18 02:03:02 +11:00
"""
query = '''
2018-04-09 15:15:12 +10:00
SELECT plex_id FROM plex WHERE kodi_fileid = ? AND kodi_type = ?
LIMIT 1
'''
2018-04-09 15:15:12 +10:00
self.plexcursor.execute(query, (kodi_fileid, kodi_type))
2016-03-12 00:42:14 +11:00
try:
item = self.plexcursor.fetchone()[0]
2018-04-09 15:15:12 +10:00
except TypeError:
item = None
return item
2016-03-12 00:42:14 +11:00
def getItem_byId(self, plex_id):
"""
For plex_id, returns the tuple
(kodi_id, kodi_fileid, kodi_pathid, parent_id, kodi_type, plex_type)
None if not found
"""
query = '''
SELECT kodi_id, kodi_fileid, kodi_pathid, parent_id, kodi_type,
plex_type
FROM plex WHERE plex_id = ?
LIMIT 1
'''
self.plexcursor.execute(query, (plex_id,))
return self.plexcursor.fetchone()
2016-03-16 22:13:47 +11:00
def getItem_byWildId(self, plex_id):
"""
Returns a list of tuples (kodi_id, kodi_type) for plex_id (% appended)
"""
query = '''
SELECT kodi_id, kodi_type
FROM plex
WHERE plex_id LIKE ?
'''
2018-04-09 15:15:12 +10:00
self.plexcursor.execute(query, (plex_id + "%",))
return self.plexcursor.fetchall()
2016-03-16 22:13:47 +11:00
def getItem_byView(self, view_id):
"""
Returns kodi_id for view_id
"""
query = '''
SELECT kodi_id
FROM plex
WHERE view_id = ?
'''
self.plexcursor.execute(query, (view_id,))
return self.plexcursor.fetchall()
def getItem_byKodiId(self, kodi_id, kodi_type):
2016-03-12 00:42:14 +11:00
"""
Returns the tuple (plex_id, parent_id, plex_type) for kodi_id and
kodi_type
2016-03-12 00:42:14 +11:00
"""
query = '''
SELECT plex_id, parent_id, plex_type
FROM plex
2018-04-09 15:15:12 +10:00
WHERE kodi_id = ? AND kodi_type = ?
LIMIT 1
'''
self.plexcursor.execute(query, (kodi_id, kodi_type,))
return self.plexcursor.fetchone()
def getItem_byParentId(self, parent_id, kodi_type):
"""
Returns a list of tuples (plex_id, kodi_id, kodi_fileid) for parent_id,
kodi_type
"""
query = '''
SELECT plex_id, kodi_id, kodi_fileid
FROM plex
WHERE parent_id = ? AND kodi_type = ?
'''
self.plexcursor.execute(query, (parent_id, kodi_type,))
return self.plexcursor.fetchall()
def getItemId_byParentId(self, parent_id, kodi_type):
"""
Returns the tuple (plex_id, kodi_id) for parent_id, kodi_type
"""
query = '''
SELECT plex_id, kodi_id
FROM plex
WHERE parent_id = ?
AND kodi_type = ?
'''
self.plexcursor.execute(query, (parent_id, kodi_type,))
return self.plexcursor.fetchall()
2018-02-12 00:42:49 +11:00
def checksum(self, plex_type):
"""
Returns a list of tuples (plex_id, checksum) for plex_type
"""
query = '''
SELECT plex_id, checksum
FROM plex
WHERE plex_type = ?
'''
self.plexcursor.execute(query, (plex_type,))
return self.plexcursor.fetchall()
def addReference(self, plex_id, plex_type, kodi_id, kodi_type,
kodi_fileid=None, kodi_pathid=None, parent_id=None,
checksum=None, view_id=None):
"""
Appends or replaces an entry into the plex table
"""
query = '''
INSERT OR REPLACE INTO plex(
plex_id, kodi_id, kodi_fileid, kodi_pathid, plex_type,
2017-02-02 05:56:06 +11:00
kodi_type, parent_id, checksum, view_id, fanart_synced)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
'''
self.plexcursor.execute(query, (plex_id, kodi_id, kodi_fileid,
kodi_pathid, plex_type, kodi_type,
2017-02-02 05:56:06 +11:00
parent_id, checksum, view_id, 0))
def updateReference(self, plex_id, checksum):
"""
Updates checksum for plex_id
"""
query = "UPDATE plex SET checksum = ? WHERE plex_id = ?"
self.plexcursor.execute(query, (checksum, plex_id))
2016-05-31 16:06:42 +10:00
def updateParentId(self, plexid, parent_kodiid):
"""
Updates parent_id for plex_id
"""
query = "UPDATE plex SET parent_id = ? WHERE plex_id = ?"
self.plexcursor.execute(query, (parent_kodiid, plexid))
def removeItems_byParentId(self, parent_id, kodi_type):
"""
Removes all entries with parent_id and kodi_type
"""
query = '''
DELETE FROM plex
WHERE parent_id = ?
AND kodi_type = ?
'''
self.plexcursor.execute(query, (parent_id, kodi_type,))
def removeItem_byKodiId(self, kodi_id, kodi_type):
"""
Removes the one entry with kodi_id and kodi_type
"""
query = '''
DELETE FROM plex
WHERE kodi_id = ?
AND kodi_type = ?
'''
self.plexcursor.execute(query, (kodi_id, kodi_type,))
def removeItem(self, plex_id):
"""
Removes the one entry with plex_id
"""
self.plexcursor.execute('DELETE FROM plex WHERE plex_id = ?',
(plex_id,))
def itemsByType(self, plex_type):
"""
Returns a list of dicts for plex_type:
{
2017-02-02 22:27:21 +11:00
'plex_id': plex_id
'kodiId': kodi_id
'kodi_type': kodi_type
'plex_type': plex_type
}
"""
query = '''
SELECT plex_id, kodi_id, kodi_type
FROM plex
WHERE plex_type = ?
'''
self.plexcursor.execute(query, (plex_type, ))
result = []
for row in self.plexcursor.fetchall():
result.append({
2017-02-02 22:27:21 +11:00
'plex_id': row[0],
'kodiId': row[1],
'kodi_type': row[2],
'plex_type': plex_type
})
return result
2017-02-02 05:56:06 +11:00
def set_fanart_synched(self, plex_id):
"""
Sets the fanart_synced flag to 1 for plex_id
"""
2018-04-09 15:15:12 +10:00
query = 'UPDATE plex SET fanart_synced = 1 WHERE plex_id = ?'
2017-02-02 05:56:06 +11:00
self.plexcursor.execute(query, (plex_id,))
def get_missing_fanart(self):
"""
2017-02-02 22:27:21 +11:00
Returns a list of {'plex_id': x, 'plex_type': y} where fanart_synced
2017-02-02 05:56:06 +11:00
flag is set to 0
This only for plex_type is either movie or TV show
"""
query = '''
2017-02-02 22:27:21 +11:00
SELECT plex_id, plex_type FROM plex
2017-02-02 05:56:06 +11:00
WHERE fanart_synced = ?
AND (plex_type = ? OR plex_type = ?)
'''
self.plexcursor.execute(query,
(0, v.PLEX_TYPE_MOVIE, v.PLEX_TYPE_SHOW))
rows = self.plexcursor.fetchall()
result = []
for row in rows:
result.append({'plex_id': row[0],
2017-02-02 22:27:21 +11:00
'plex_type': row[1]})
2017-02-02 05:56:06 +11:00
return result
2018-04-28 17:12:29 +10:00
def plex_id_from_playlist_path(self, path):
"""
Given the Kodi playlist path [unicode], this will return the Plex id
[str] or None
"""
query = 'SELECT plex_id FROM playlists WHERE kodi_path = ? LIMIT 1'
self.plexcursor.execute(query, (path, ))
try:
plex_id = self.plexcursor.fetchone()[0]
except TypeError:
plex_id = None
return plex_id
2018-05-01 22:48:49 +10:00
def plex_ids_all_playlists(self):
"""
Returns a list of all Plex ids of playlists.
"""
answ = []
self.plexcursor.execute('SELECT plex_id FROM playlists')
for entry in self.plexcursor.fetchall():
answ.append(entry[0])
return answ
2018-07-11 05:19:08 +10:00
def all_kodi_playlist_paths(self):
2018-05-01 22:48:49 +10:00
"""
2018-07-11 05:19:08 +10:00
Returns a list of all Kodi playlist paths.
2018-05-01 22:48:49 +10:00
"""
answ = []
2018-07-11 05:19:08 +10:00
self.plexcursor.execute('SELECT kodi_path FROM playlists')
2018-05-01 22:48:49 +10:00
for entry in self.plexcursor.fetchall():
answ.append(entry[0])
return answ
def retrieve_playlist(self, playlist, plex_id=None, path=None,
kodi_hash=None):
"""
2018-07-12 05:24:27 +10:00
Returns a complete Playlist (empty one passed in via playlist)
for the entry with plex_id OR kodi_hash OR kodi_path.
Returns None if not found
2018-05-01 22:48:49 +10:00
"""
query = '''
SELECT plex_id, plex_name, plex_updatedat, kodi_path, kodi_type,
kodi_hash
FROM playlists
WHERE %s = ?
LIMIT 1
'''
if plex_id:
query = query % 'plex_id'
var = plex_id
elif kodi_hash:
query = query % 'kodi_hash'
var = kodi_hash
else:
query = query % 'kodi_path'
var = path
self.plexcursor.execute(query, (var, ))
answ = self.plexcursor.fetchone()
if not answ:
return
2018-07-12 05:24:27 +10:00
playlist.plex_id = answ[0]
2018-05-01 22:48:49 +10:00
playlist.plex_name = answ[1]
playlist.plex_updatedat = answ[2]
playlist.kodi_path = answ[3]
2018-07-12 05:24:27 +10:00
playlist.kodi_type = answ[4]
2018-05-01 22:48:49 +10:00
playlist.kodi_hash = answ[5]
return playlist
2018-04-28 17:12:29 +10:00
def insert_playlist_entry(self, playlist):
"""
Inserts or modifies an existing entry in the Plex playlists table.
"""
query = '''
INSERT OR REPLACE INTO playlists(
plex_id, plex_name, plex_updatedat, kodi_path, kodi_type,
kodi_hash)
VALUES (?, ?, ?, ?, ?, ?)
'''
self.plexcursor.execute(query,
2018-07-12 05:24:27 +10:00
(playlist.plex_id, playlist.plex_name,
2018-04-28 17:12:29 +10:00
playlist.plex_updatedat, playlist.kodi_path,
2018-07-12 05:24:27 +10:00
playlist.kodi_type, playlist.kodi_hash))
2018-04-28 17:12:29 +10:00
def delete_playlist_entry(self, playlist):
"""
Removes the entry for playlist [Playqueue_Object] from the Plex
playlists table.
Be sure to either set playlist.id or playlist.kodi_path
"""
2018-07-12 05:24:27 +10:00
if playlist.plex_id:
2018-04-28 17:12:29 +10:00
query = 'DELETE FROM playlists WHERE plex_id = ?'
2018-07-12 05:24:27 +10:00
var = playlist.plex_id
2018-04-28 17:12:29 +10:00
elif playlist.kodi_path:
query = 'DELETE FROM playlists WHERE kodi_path = ?'
var = playlist.kodi_path
else:
2018-07-12 05:24:27 +10:00
raise RuntimeError('Cannot delete playlist: %s' % playlist)
2018-04-28 17:12:29 +10:00
self.plexcursor.execute(query, (var, ))
def wipe_dbs():
"""
Completely resets the Plex database
"""
query = "SELECT name FROM sqlite_master WHERE type = 'table'"
with Get_Plex_DB() as plex_db:
plex_db.plexcursor.execute(query)
tables = plex_db.plexcursor.fetchall()
tables = [i[0] for i in tables]
for table in tables:
delete_query = 'DELETE FROM %s' % table
plex_db.plexcursor.execute(delete_query)