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