Add genres
This commit is contained in:
parent
5f3b2e471b
commit
a3c354d4ef
|
@ -523,9 +523,8 @@ class PysonicApi(object):
|
||||||
def getGenres_view(self, **kwargs):
|
def getGenres_view(self, **kwargs):
|
||||||
response = ApiResponse()
|
response = ApiResponse()
|
||||||
response.add_child("genres")
|
response.add_child("genres")
|
||||||
response.add_child("genre", _parent="genres", value="Death Metal", songCount=420, albumCount=69)
|
for row in self.library.db.get_genres():
|
||||||
response.add_child("genre", _parent="genres", value="Metal", songCount=52, albumCount=3)
|
response.add_child("genre", _parent="genres", value=row["name"], songCount=420, albumCount=69)
|
||||||
response.add_child("genre", _parent="genres", value="Punk", songCount=34, albumCount=3)
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
|
|
|
@ -59,6 +59,9 @@ class PysonicDatabase(object):
|
||||||
'name' TEXT,
|
'name' TEXT,
|
||||||
UNIQUE(parent, name)
|
UNIQUE(parent, name)
|
||||||
)""",
|
)""",
|
||||||
|
"""CREATE TABLE 'genres' (
|
||||||
|
'id' INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
'name' TEXT UNIQUE)""",
|
||||||
"""CREATE TABLE 'artists' (
|
"""CREATE TABLE 'artists' (
|
||||||
'id' INTEGER PRIMARY KEY AUTOINCREMENT,
|
'id' INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
'libraryid' INTEGER,
|
'libraryid' INTEGER,
|
||||||
|
@ -75,6 +78,7 @@ class PysonicDatabase(object):
|
||||||
'id' INTEGER PRIMARY KEY AUTOINCREMENT,
|
'id' INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
'library' INTEGER,
|
'library' INTEGER,
|
||||||
'albumid' BOOLEAN,
|
'albumid' BOOLEAN,
|
||||||
|
'genre' INTEGER DEFAULT NULL,
|
||||||
'file' TEXT UNIQUE, -- path from the library root
|
'file' TEXT UNIQUE, -- path from the library root
|
||||||
'size' INTEGER NOT NULL DEFAULT -1,
|
'size' INTEGER NOT NULL DEFAULT -1,
|
||||||
'title' TEXT NOT NULL,
|
'title' TEXT NOT NULL,
|
||||||
|
@ -202,10 +206,76 @@ class PysonicDatabase(object):
|
||||||
return albums
|
return albums
|
||||||
|
|
||||||
@readcursor
|
@readcursor
|
||||||
def get_song(self, cursor, songid):
|
def get_songs(self, cursor, id=None, genre=None, sortby=None, order=None, limit=None):
|
||||||
for item in cursor.execute("SELECT * FROM songs WHERE id=?", (songid, )):
|
# TODO make this query massively uglier by joining albums and artists so that artistid etc can be a filter
|
||||||
return item
|
# or maybe lookup those IDs in the library layer?
|
||||||
return None
|
if order:
|
||||||
|
order = {"asc": "ASC", "desc": "DESC"}[order]
|
||||||
|
|
||||||
|
if sortby and sortby == "random":
|
||||||
|
sortby = "RANDOM()"
|
||||||
|
|
||||||
|
songs = []
|
||||||
|
|
||||||
|
q = """
|
||||||
|
SELECT
|
||||||
|
s.*,
|
||||||
|
alb.name as albumname,
|
||||||
|
alb.coverid as albumcoverid,
|
||||||
|
art.name as artistname,
|
||||||
|
g.name as genrename
|
||||||
|
FROM songs as s
|
||||||
|
INNER JOIN albums as alb
|
||||||
|
on s.albumid == alb.id
|
||||||
|
INNER JOIN artists as art
|
||||||
|
on alb.artistid = art.id
|
||||||
|
LEFT JOIN genres as g
|
||||||
|
on s.genre == g.id
|
||||||
|
"""
|
||||||
|
|
||||||
|
params = []
|
||||||
|
|
||||||
|
conditions = []
|
||||||
|
if id:
|
||||||
|
conditions.append("s.id = ?")
|
||||||
|
params.append(id)
|
||||||
|
if genre:
|
||||||
|
conditions.append("g.name = ?")
|
||||||
|
params.append(genre)
|
||||||
|
if conditions:
|
||||||
|
q += " WHERE " + " AND ".join(conditions)
|
||||||
|
|
||||||
|
if sortby:
|
||||||
|
q += " ORDER BY {}".format(sortby)
|
||||||
|
if order:
|
||||||
|
q += " {}".format(order)
|
||||||
|
|
||||||
|
if limit:
|
||||||
|
q += " LIMIT {}".format(limit) # TODO support limit pagination
|
||||||
|
|
||||||
|
print(q)
|
||||||
|
|
||||||
|
cursor.execute(q, params)
|
||||||
|
for row in cursor:
|
||||||
|
songs.append(row)
|
||||||
|
return songs
|
||||||
|
|
||||||
|
@readcursor
|
||||||
|
def get_genres(self, cursor, genre_id=None):
|
||||||
|
genres = []
|
||||||
|
q = "SELECT * FROM genres"
|
||||||
|
params = []
|
||||||
|
conditions = []
|
||||||
|
if genre_id:
|
||||||
|
conditions.append("id = ?")
|
||||||
|
params.append(genre_id)
|
||||||
|
if conditions:
|
||||||
|
q += " WHERE " + " AND ".join(conditions)
|
||||||
|
cursor.execute(q, params)
|
||||||
|
for row in cursor:
|
||||||
|
genres.append(row)
|
||||||
|
return genres
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -83,7 +83,7 @@ class PysonicLibrary(object):
|
||||||
return cover
|
return cover
|
||||||
|
|
||||||
def get_song(self, song_id):
|
def get_song(self, song_id):
|
||||||
song = self.db.get_song(song_id)
|
song = self.db.get_songs(id=song_id)[0]
|
||||||
library = self.db.get_libraries(song["library"])[0]
|
library = self.db.get_libraries(song["library"])[0]
|
||||||
song['_fullpath'] = os.path.join(library["path"], song["file"])
|
song['_fullpath'] = os.path.join(library["path"], song["file"])
|
||||||
return song
|
return song
|
||||||
|
|
|
@ -210,11 +210,17 @@ class PysonicFilesystemScanner(object):
|
||||||
writer.execute(q, params)
|
writer.execute(q, params)
|
||||||
|
|
||||||
# If the metadata has an artist or album name, update the relevant items
|
# If the metadata has an artist or album name, update the relevant items
|
||||||
|
# TODO ignore metadata if theyre blank
|
||||||
if "album" in meta:
|
if "album" in meta:
|
||||||
writer.execute("UPDATE albums SET name=? WHERE id=?", (meta["album"], row["albumid"]))
|
writer.execute("UPDATE albums SET name=? WHERE id=?", (meta["album"], row["albumid"]))
|
||||||
if "artist" in meta:
|
if "artist" in meta:
|
||||||
album = writer.execute("SELECT artistid FROM albums WHERE id=?", (row['albumid'], )).fetchone()
|
album = writer.execute("SELECT artistid FROM albums WHERE id=?", (row['albumid'], )).fetchone()
|
||||||
writer.execute("UPDATE artists SET name=? WHERE id=?", (meta["artist"], album["artistid"]))
|
writer.execute("UPDATE artists SET name=? WHERE id=?", (meta["artist"], album["artistid"]))
|
||||||
|
if "genre" in meta:
|
||||||
|
genre_name = meta["genre"].strip()
|
||||||
|
if genre_name:
|
||||||
|
genre_id = self.get_genre_id(writer, meta["genre"])
|
||||||
|
writer.execute("UPDATE songs SET genre=? WHERE id=?", (genre_id, row['id']))
|
||||||
|
|
||||||
# Commit every 50 items
|
# Commit every 50 items
|
||||||
processed += 1
|
processed += 1
|
||||||
|
@ -225,6 +231,13 @@ class PysonicFilesystemScanner(object):
|
||||||
if processed != 0:
|
if processed != 0:
|
||||||
writer.execute("COMMIT")
|
writer.execute("COMMIT")
|
||||||
|
|
||||||
|
def get_genre_id(self, cursor, genre_name):
|
||||||
|
genre_name = genre_name.title().strip() # normalize
|
||||||
|
for row in cursor.execute("SELECT * FROM genres WHERE name=?", (genre_name, )):
|
||||||
|
return row['id']
|
||||||
|
cursor.execute("INSERT INTO genres (name) VALUES (?)", (genre_name, ))
|
||||||
|
return cursor.lastrowid
|
||||||
|
|
||||||
def scan_file_metadata(self, fpath):
|
def scan_file_metadata(self, fpath):
|
||||||
"""
|
"""
|
||||||
Scan the file for metadata.
|
Scan the file for metadata.
|
||||||
|
@ -283,6 +296,10 @@ class PysonicFilesystemScanner(object):
|
||||||
meta["year"] = audio['TDRC'].text[0].year
|
meta["year"] = audio['TDRC'].text[0].year
|
||||||
except (KeyError, IndexError):
|
except (KeyError, IndexError):
|
||||||
pass
|
pass
|
||||||
|
try:
|
||||||
|
meta["genre"] = audio['TCON'].text[0]
|
||||||
|
except (KeyError, IndexError):
|
||||||
|
pass
|
||||||
logging.info("got all media info from %s", fpath)
|
logging.info("got all media info from %s", fpath)
|
||||||
|
|
||||||
return meta
|
return meta
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
beautifulsoup4==4.6.0
|
beautifulsoup4==4.6.0
|
||||||
cheroot==5.8.3
|
bs4==0.0.1
|
||||||
CherryPy==11.0.0
|
cheroot==6.0.0
|
||||||
lxml==3.8.0
|
CherryPy==14.0.1
|
||||||
mutagen==1.38
|
lxml==4.2.1
|
||||||
portend==2.1.2
|
more-itertools==4.1.0
|
||||||
pytz==2017.2
|
mutagen==1.40.0
|
||||||
six==1.10.0
|
portend==2.2
|
||||||
tempora==1.8
|
pysonic==0.0.1
|
||||||
|
pytz==2018.3
|
||||||
|
six==1.11.0
|
||||||
|
tempora==1.11
|
||||||
|
|
Loading…
Reference in New Issue