parent
8f30a466ff
commit
0f1e2e7dec
2 changed files with 184 additions and 55 deletions
|
@ -1719,6 +1719,7 @@ class Music(Items):
|
||||||
# Update album artwork
|
# Update album artwork
|
||||||
artwork.modify_artwork(artworks, albumid, v.KODI_TYPE_ALBUM, kodicursor)
|
artwork.modify_artwork(artworks, albumid, v.KODI_TYPE_ALBUM, kodicursor)
|
||||||
|
|
||||||
|
@catch_exceptions(warnuser=True)
|
||||||
def remove(self, plex_id):
|
def remove(self, plex_id):
|
||||||
"""
|
"""
|
||||||
Completely remove the item with plex_id from the Kodi and Plex DBs.
|
Completely remove the item with plex_id from the Kodi and Plex DBs.
|
||||||
|
@ -1728,92 +1729,124 @@ class Music(Items):
|
||||||
try:
|
try:
|
||||||
kodi_id = plex_dbitem[0]
|
kodi_id = plex_dbitem[0]
|
||||||
file_id = plex_dbitem[1]
|
file_id = plex_dbitem[1]
|
||||||
|
path_id = plex_dbitem[2]
|
||||||
parent_id = plex_dbitem[3]
|
parent_id = plex_dbitem[3]
|
||||||
kodi_type = plex_dbitem[4]
|
kodi_type = plex_dbitem[4]
|
||||||
LOG.info("Removing %s with kodi_id: %s, parent_id: %s, file_id: %s",
|
LOG.info('Removing plex_id %s with kodi_type %s, kodi_id %s, '
|
||||||
kodi_type, kodi_id, parent_id, file_id)
|
'parent_id %s, file_id %s, pathid %s',
|
||||||
|
plex_id, kodi_type, kodi_id, parent_id, file_id, path_id)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
LOG.debug('Cannot delete item with plex id %s from Kodi', plex_id)
|
LOG.debug('Cannot delete item with plex id %s from Kodi', plex_id)
|
||||||
return
|
return
|
||||||
|
|
||||||
# Remove the plex reference
|
# Remove the plex reference
|
||||||
self.plex_db.removeItem(plex_id)
|
self.plex_db.removeItem(plex_id)
|
||||||
##### SONG #####
|
##### SONG #####
|
||||||
if kodi_type == v.KODI_TYPE_SONG:
|
if kodi_type == v.KODI_TYPE_SONG:
|
||||||
# Delete song
|
# Delete song and orphaned artists and albums
|
||||||
self.remove_song(kodi_id)
|
self._remove_song(kodi_id, path_id=path_id)
|
||||||
# Album verification
|
# Album verification
|
||||||
|
album = self.plex_db.getItem_byKodiId(parent_id,
|
||||||
for item in self.plex_db.getItem_byWildId(plex_id):
|
v.KODI_TYPE_ALBUM)
|
||||||
|
if not self.plex_db.getItem_byParentId(parent_id,
|
||||||
item_kid = item[0]
|
v.KODI_TYPE_SONG):
|
||||||
item_kodi_type = item[1]
|
# No song left for album - so delete the album
|
||||||
|
self.plex_db.removeItem(album[0])
|
||||||
if item_kodi_type == v.KODI_TYPE_ALBUM:
|
self._remove_album(parent_id)
|
||||||
childs = self.plex_db.getItem_byParentId(item_kid,
|
|
||||||
v.KODI_TYPE_SONG)
|
|
||||||
if not childs:
|
|
||||||
# Delete album
|
|
||||||
self.remove_album(item_kid)
|
|
||||||
|
|
||||||
##### ALBUM #####
|
##### ALBUM #####
|
||||||
elif kodi_type == v.KODI_TYPE_ALBUM:
|
elif kodi_type == v.KODI_TYPE_ALBUM:
|
||||||
# Delete songs, album
|
# Delete songs, album
|
||||||
album_songs = self.plex_db.getItem_byParentId(kodi_id,
|
songs = self.plex_db.getItem_byParentId(kodi_id,
|
||||||
v.KODI_TYPE_SONG)
|
v.KODI_TYPE_SONG)
|
||||||
for song in album_songs:
|
for song in songs:
|
||||||
self.remove_song(song[1])
|
self._remove_song(song[1], path_id=song[2])
|
||||||
# Remove plex songs
|
# Remove songs from Plex table
|
||||||
self.plex_db.removeItems_byParentId(kodi_id,
|
self.plex_db.removeItems_byParentId(kodi_id,
|
||||||
v.KODI_TYPE_SONG)
|
v.KODI_TYPE_SONG)
|
||||||
# Remove the album
|
# Remove the album and associated orphaned entries
|
||||||
self.remove_album(kodi_id)
|
self._remove_album(kodi_id)
|
||||||
|
|
||||||
##### IF ARTIST #####
|
##### IF ARTIST #####
|
||||||
elif kodi_type == v.KODI_TYPE_ARTIST:
|
elif kodi_type == v.KODI_TYPE_ARTIST:
|
||||||
# Delete songs, album, artist
|
# Delete songs, album, artist
|
||||||
albums = self.plex_db.getItem_byParentId(kodi_id, v.KODI_TYPE_ALBUM)
|
albums = self.plex_db.getItem_byParentId(kodi_id, v.KODI_TYPE_ALBUM)
|
||||||
for album in albums:
|
for album in albums:
|
||||||
albumid = album[1]
|
songs = self.plex_db.getItem_byParentId(album[1],
|
||||||
album_songs = self.plex_db.getItem_byParentId(albumid,
|
v.KODI_TYPE_SONG)
|
||||||
v.KODI_TYPE_SONG)
|
for song in songs:
|
||||||
for song in album_songs:
|
self._remove_song(song[1], path_id=song[2])
|
||||||
self.remove_song(song[1])
|
# Remove entries for the songs in the Plex db
|
||||||
# Remove plex song
|
self.plex_db.removeItems_byParentId(album[1], v.KODI_TYPE_SONG)
|
||||||
self.plex_db.removeItems_byParentId(albumid, v.KODI_TYPE_SONG)
|
|
||||||
# Remove plex artist
|
|
||||||
self.plex_db.removeItems_byParentId(albumid, v.KODI_TYPE_ARTIST)
|
|
||||||
# Remove kodi album
|
# Remove kodi album
|
||||||
self.remove_album(albumid)
|
self._remove_album(album[1])
|
||||||
# Remove plex albums
|
# Remove album entries in the Plex db
|
||||||
self.plex_db.removeItems_byParentId(kodi_id, v.KODI_TYPE_ALBUM)
|
self.plex_db.removeItems_byParentId(kodi_id, v.KODI_TYPE_ALBUM)
|
||||||
# Remove artist
|
# Remove artist
|
||||||
self.remove_artist(kodi_id)
|
self._remove_artist(kodi_id)
|
||||||
|
|
||||||
LOG.debug("Deleted plex_id %s from kodi database", plex_id)
|
LOG.debug("Deleted plex_id %s from kodi database", plex_id)
|
||||||
|
|
||||||
def remove_song(self, kodi_id):
|
def _remove_song(self, kodi_id, path_id=None):
|
||||||
"""
|
"""
|
||||||
Remove song, and only the song
|
Remove song, orphaned artists and orphaned paths
|
||||||
"""
|
"""
|
||||||
|
if not path_id:
|
||||||
|
query = 'SELECT idPath FROM song WHERE idSong = ? LIMIT 1'
|
||||||
|
self.kodicursor.execute(query, (kodi_id, ))
|
||||||
|
try:
|
||||||
|
path_id = self.kodicursor.fetchone()[0]
|
||||||
|
except TypeError:
|
||||||
|
pass
|
||||||
|
artist_to_delete = self.kodi_db.delete_song_from_song_artist(kodi_id)
|
||||||
|
if artist_to_delete:
|
||||||
|
# Delete the artist reference in the Plex table
|
||||||
|
artist = self.plex_db.getItem_byKodiId(artist_to_delete,
|
||||||
|
v.KODI_TYPE_ARTIST)
|
||||||
|
try:
|
||||||
|
plex_id = artist[0]
|
||||||
|
except TypeError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
self.plex_db.removeItem(plex_id)
|
||||||
|
self._remove_artist(artist_to_delete)
|
||||||
|
self.kodicursor.execute('DELETE FROM song WHERE idSong = ?',
|
||||||
|
(kodi_id, ))
|
||||||
|
# Check whether we have orphaned path entries
|
||||||
|
query = 'SELECT idPath FROM song WHERE idPath = ? LIMIT 1'
|
||||||
|
self.kodicursor.execute(query, (path_id, ))
|
||||||
|
if not self.kodicursor.fetchone():
|
||||||
|
self.kodicursor.execute('DELETE FROM path WHERE idPath = ?',
|
||||||
|
(path_id, ))
|
||||||
|
if v.KODIVERSION < 18:
|
||||||
|
self.kodi_db.delete_song_from_song_genre(kodi_id)
|
||||||
|
query = 'DELETE FROM albuminfosong WHERE idAlbumInfoSong = ?'
|
||||||
|
self.kodicursor.execute(query, (kodi_id, ))
|
||||||
self.artwork.delete_artwork(kodi_id, v.KODI_TYPE_SONG, self.kodicursor)
|
self.artwork.delete_artwork(kodi_id, v.KODI_TYPE_SONG, self.kodicursor)
|
||||||
self.kodicursor.execute("DELETE FROM song WHERE idSong = ?",
|
|
||||||
(kodi_id,))
|
|
||||||
|
|
||||||
def remove_album(self, kodi_id):
|
def _remove_album(self, kodi_id):
|
||||||
"""
|
'''
|
||||||
Remove an album, and only the album
|
Remove an album
|
||||||
"""
|
'''
|
||||||
|
self.kodi_db.delete_album_from_discography(kodi_id)
|
||||||
|
if v.KODIVERSION < 18:
|
||||||
|
self.kodi_db.delete_album_from_album_genre(kodi_id)
|
||||||
|
query = 'DELETE FROM albuminfosong WHERE idAlbumInfo = ?'
|
||||||
|
self.kodicursor.execute(query, (kodi_id, ))
|
||||||
|
self.kodicursor.execute('DELETE FROM album_artist WHERE idAlbum = ?',
|
||||||
|
(kodi_id, ))
|
||||||
|
self.kodicursor.execute('DELETE FROM album WHERE idAlbum = ?',
|
||||||
|
(kodi_id, ))
|
||||||
self.artwork.delete_artwork(kodi_id, v.KODI_TYPE_ALBUM, self.kodicursor)
|
self.artwork.delete_artwork(kodi_id, v.KODI_TYPE_ALBUM, self.kodicursor)
|
||||||
self.kodicursor.execute("DELETE FROM album WHERE idAlbum = ?",
|
|
||||||
(kodi_id,))
|
|
||||||
|
|
||||||
def remove_artist(self, kodi_id):
|
def _remove_artist(self, kodi_id):
|
||||||
"""
|
'''
|
||||||
Remove an artist, and only the artist
|
Remove an artist and associated songs and albums
|
||||||
"""
|
'''
|
||||||
|
self.kodicursor.execute('DELETE FROM album_artist WHERE idArtist = ?',
|
||||||
|
(kodi_id, ))
|
||||||
|
self.kodicursor.execute('DELETE FROM artist WHERE idArtist = ?',
|
||||||
|
(kodi_id, ))
|
||||||
|
self.kodicursor.execute('DELETE FROM song_artist WHERE idArtist = ?',
|
||||||
|
(kodi_id, ))
|
||||||
|
self.kodicursor.execute('DELETE FROM discography WHERE idArtist = ?',
|
||||||
|
(kodi_id, ))
|
||||||
self.artwork.delete_artwork(kodi_id,
|
self.artwork.delete_artwork(kodi_id,
|
||||||
v.KODI_TYPE_ARTIST,
|
v.KODI_TYPE_ARTIST,
|
||||||
self.kodicursor)
|
self.kodicursor)
|
||||||
self.kodicursor.execute("DELETE FROM artist WHERE idArtist = ?",
|
|
||||||
(kodi_id,))
|
|
||||||
|
|
|
@ -907,6 +907,102 @@ class KodiDBMethods(object):
|
||||||
self.cursor.execute(query, (name, artistid,))
|
self.cursor.execute(query, (name, artistid,))
|
||||||
return artistid
|
return artistid
|
||||||
|
|
||||||
|
def delete_song_from_song_artist(self, song_id):
|
||||||
|
"""
|
||||||
|
Deletes son from song_artist table and possibly orphaned roles
|
||||||
|
Will returned an orphaned idArtist or None if not orphaned
|
||||||
|
"""
|
||||||
|
query = '''
|
||||||
|
SELECT idArtist, idRole FROM song_artist WHERE idSong = ? LIMIT 1
|
||||||
|
'''
|
||||||
|
self.cursor.execute(query, (song_id, ))
|
||||||
|
artist = self.cursor.fetchone()
|
||||||
|
if artist is None:
|
||||||
|
# No entry to begin with
|
||||||
|
return
|
||||||
|
# Delete the entry
|
||||||
|
self.cursor.execute('DELETE FROM song_artist WHERE idSong = ?',
|
||||||
|
(song_id, ))
|
||||||
|
# Check whether we need to delete orphaned roles
|
||||||
|
query = 'SELECT idRole FROM song_artist WHERE idRole = ? LIMIT 1'
|
||||||
|
self.cursor.execute(query, (artist[1], ))
|
||||||
|
if not self.cursor.fetchone():
|
||||||
|
# Delete orphaned role
|
||||||
|
self.cursor.execute('DELETE FROM role WHERE idRole = ?',
|
||||||
|
(artist[1], ))
|
||||||
|
# Check whether we need to delete orphaned artists
|
||||||
|
query = 'SELECT idArtist FROM song_artist WHERE idArtist = ? LIMIT 1'
|
||||||
|
self.cursor.execute(query, (artist[0], ))
|
||||||
|
if self.cursor.fetchone():
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
return artist[0]
|
||||||
|
|
||||||
|
def delete_album_from_discography(self, album_id):
|
||||||
|
"""
|
||||||
|
Removes the album with id album_id from the table discography
|
||||||
|
"""
|
||||||
|
# Need to get the album name as a string first!
|
||||||
|
query = 'SELECT strAlbum, iYear FROM album WHERE idAlbum = ? LIMIT 1'
|
||||||
|
self.cursor.execute(query, (album_id, ))
|
||||||
|
try:
|
||||||
|
name, year = self.cursor.fetchone()
|
||||||
|
except TypeError:
|
||||||
|
return
|
||||||
|
query = 'SELECT idArtist FROM album_artist WHERE idAlbum = ? LIMIT 1'
|
||||||
|
self.cursor.execute(query, (album_id, ))
|
||||||
|
artist = self.cursor.fetchone()
|
||||||
|
if not artist:
|
||||||
|
return
|
||||||
|
query = '''
|
||||||
|
DELETE FROM discography
|
||||||
|
WHERE idArtist = ?, strAlbum = ?, strYear = ?
|
||||||
|
'''
|
||||||
|
self.cursor.execute(query, (artist[0], name, year))
|
||||||
|
|
||||||
|
def delete_song_from_song_genre(self, song_id):
|
||||||
|
"""
|
||||||
|
Deletes the one entry with id song_id from the song_genre table.
|
||||||
|
Will also delete orphaned genres from genre table
|
||||||
|
"""
|
||||||
|
query = 'SELECT idGenre FROM song_genre WHERE idSong = ?'
|
||||||
|
self.cursor.execute(query, (song_id, ))
|
||||||
|
genres = self.cursor.fetchall()
|
||||||
|
self.cursor.execute('DELETE FROM song_genre WHERE idSong = ?',
|
||||||
|
(song_id, ))
|
||||||
|
# Check for orphaned genres in both song_genre and album_genre tables
|
||||||
|
query = 'SELECT idGenre FROM song_genre WHERE idGenre = ? LIMIT 1'
|
||||||
|
query2 = 'SELECT idGenre FROM album_genre WHERE idGenre = ? LIMIT 1'
|
||||||
|
for genre in genres:
|
||||||
|
self.cursor.execute(query, (genre[0], ))
|
||||||
|
if not self.cursor.fetchone():
|
||||||
|
self.cursor.execute(query2, (genre[0], ))
|
||||||
|
if not self.cursor.fetchone():
|
||||||
|
self.cursor.execute('DELETE FROM genre WHERE idGenre = ?',
|
||||||
|
(genre[0], ))
|
||||||
|
|
||||||
|
def delete_album_from_album_genre(self, album_id):
|
||||||
|
"""
|
||||||
|
Deletes the one entry with id album_id from the album_genre table.
|
||||||
|
Will also delete orphaned genres from genre table
|
||||||
|
"""
|
||||||
|
query = 'SELECT idGenre FROM album_genre WHERE idAlbum = ?'
|
||||||
|
self.cursor.execute(query, (album_id, ))
|
||||||
|
genres = self.cursor.fetchall()
|
||||||
|
self.cursor.execute('DELETE FROM album_genre WHERE idAlbum = ?',
|
||||||
|
(album_id, ))
|
||||||
|
# Check for orphaned genres in both album_genre and song_genre tables
|
||||||
|
query = 'SELECT idGenre FROM album_genre WHERE idGenre = ? LIMIT 1'
|
||||||
|
query2 = 'SELECT idGenre FROM song_genre WHERE idGenre = ? LIMIT 1'
|
||||||
|
for genre in genres:
|
||||||
|
self.cursor.execute(query, (genre[0], ))
|
||||||
|
if not self.cursor.fetchone():
|
||||||
|
self.cursor.execute(query2, (genre[0], ))
|
||||||
|
if not self.cursor.fetchone():
|
||||||
|
self.cursor.execute('DELETE FROM genre WHERE idGenre = ?',
|
||||||
|
(genre[0], ))
|
||||||
|
|
||||||
|
|
||||||
def addAlbum(self, name, musicbrainz):
|
def addAlbum(self, name, musicbrainz):
|
||||||
query = 'SELECT idAlbum FROM album WHERE strMusicBrainzAlbumID = ?'
|
query = 'SELECT idAlbum FROM album WHERE strMusicBrainzAlbumID = ?'
|
||||||
self.cursor.execute(query, (musicbrainz,))
|
self.cursor.execute(query, (musicbrainz,))
|
||||||
|
|
Loading…
Reference in a new issue