refactor out library class
This commit is contained in:
parent
bfcb528ddf
commit
c910de0eb0
|
@ -2,7 +2,7 @@ import logging
|
|||
import subprocess
|
||||
from time import time
|
||||
from threading import Thread
|
||||
from pysonic.library import LETTER_GROUPS
|
||||
from pysonic.database import LETTER_GROUPS
|
||||
from pysonic.types import MUSIC_TYPES
|
||||
from pysonic.apilib import formatresponse, ApiResponse
|
||||
import cherrypy
|
||||
|
@ -11,16 +11,15 @@ logging = logging.getLogger("api")
|
|||
|
||||
|
||||
class PysonicSubsonicApi(object):
|
||||
def __init__(self, db, library, options):
|
||||
def __init__(self, db, options):
|
||||
self.db = db
|
||||
self.library = library
|
||||
self.options = options
|
||||
|
||||
@cherrypy.expose
|
||||
@formatresponse
|
||||
def index(self):
|
||||
response = ApiResponse()
|
||||
response.add_child("totals", **self.library.db.get_stats())
|
||||
response.add_child("totals", **self.db.get_stats())
|
||||
return response
|
||||
|
||||
@cherrypy.expose
|
||||
|
@ -46,7 +45,7 @@ class PysonicSubsonicApi(object):
|
|||
def getMusicFolders_view(self, **kwargs):
|
||||
response = ApiResponse()
|
||||
response.add_child("musicFolders")
|
||||
for folder in self.library.get_libraries():
|
||||
for folder in self.db.get_libraries():
|
||||
response.add_child("musicFolder", _parent="musicFolders", id=folder["id"], name=folder["name"])
|
||||
return response
|
||||
|
||||
|
@ -58,7 +57,7 @@ class PysonicSubsonicApi(object):
|
|||
# TODO real lastmodified date
|
||||
# TODO deal with ignoredArticles
|
||||
response.add_child("indexes", lastModified="1502310831000", ignoredArticles="The El La Los Las Le Les")
|
||||
artists = self.library.get_artists(sortby="name", order="asc")
|
||||
artists = self.db.get_artists(sortby="name", order="asc")
|
||||
for letter in LETTER_GROUPS:
|
||||
index = response.add_child("index", _parent="indexes", name=letter.upper())
|
||||
for artist in artists:
|
||||
|
@ -83,7 +82,7 @@ class PysonicSubsonicApi(object):
|
|||
|
||||
qargs.update(limit=(offset, size))
|
||||
|
||||
albums = self.library.get_albums(**qargs)
|
||||
albums = self.db.get_albums(**qargs)
|
||||
|
||||
response = ApiResponse()
|
||||
|
||||
|
@ -111,7 +110,7 @@ class PysonicSubsonicApi(object):
|
|||
List either and artist or album dir
|
||||
"""
|
||||
dir_id = int(id)
|
||||
dirtype, dirinfo, entity = self.library.db.get_subsonic_musicdir(dirid=dir_id)
|
||||
dirtype, dirinfo, entity = self.db.get_subsonic_musicdir(dirid=dir_id)
|
||||
|
||||
response = ApiResponse()
|
||||
|
||||
|
@ -171,7 +170,7 @@ class PysonicSubsonicApi(object):
|
|||
def stream_view(self, id, maxBitRate="256", **kwargs):
|
||||
maxBitRate = int(maxBitRate)
|
||||
assert maxBitRate >= 32 and maxBitRate <= 320
|
||||
song = self.library.get_song(int(id))
|
||||
song = self.db.get_songs(id=int(id))[0]
|
||||
fpath = song["_fullpath"]
|
||||
media_bitrate = song.get("bitrate") / 1024 if song.get("bitrate") else 320
|
||||
to_bitrate = min(maxBitRate,
|
||||
|
@ -219,7 +218,7 @@ class PysonicSubsonicApi(object):
|
|||
if proc.returncode is None or proc.returncode == 0:
|
||||
logging.warning("transcoded {} in {}s".format(id, int(time() - start)))
|
||||
# if completed:
|
||||
# self.library.report_transcode(id, to_bitrate, length)
|
||||
# self.db.report_transcode(id, to_bitrate, length)
|
||||
else:
|
||||
logging.error("transcode of {} exited with code {} after {}s".format(id, proc.returncode,
|
||||
int(time() - start)))
|
||||
|
@ -248,7 +247,7 @@ class PysonicSubsonicApi(object):
|
|||
"""
|
||||
if id.startswith("pl-"): # get art from first track in playlist
|
||||
playlist_id = int(id[len("pl-"):])
|
||||
_, songs = self.library.get_playlist(playlist_id)
|
||||
songs = self.db.get_playlist_songs(playlist_id)
|
||||
for song in songs:
|
||||
if song["albumcoverid"]:
|
||||
id = song["albumcoverid"]
|
||||
|
@ -262,8 +261,7 @@ class PysonicSubsonicApi(object):
|
|||
else:
|
||||
id = int(id)
|
||||
|
||||
cover = self.library.get_cover(id)
|
||||
fpath = cover["_fullpath"]
|
||||
fpath = self.db.get_cover_path(id)
|
||||
type2ct = {
|
||||
'jpg': 'image/jpeg',
|
||||
'png': 'image/png',
|
||||
|
@ -280,14 +278,14 @@ class PysonicSubsonicApi(object):
|
|||
break
|
||||
total += len(data)
|
||||
yield data
|
||||
logging.info("\nSent {} bytes for {}".format(total, fpath))
|
||||
logging.info("sent {} bytes for {}".format(total, fpath))
|
||||
return content()
|
||||
getCoverArt_view._cp_config = {'response.stream': True}
|
||||
|
||||
@cherrypy.expose
|
||||
@formatresponse
|
||||
def getArtistInfo_view(self, id, includeNotPresent="true", **kwargs):
|
||||
info = self.library.get_artist_info(id)
|
||||
info = self.db.get_artist_info(id)
|
||||
response = ApiResponse()
|
||||
response.add_child("artistInfo")
|
||||
response.set_attrs("artistInfo", **info)
|
||||
|
@ -296,7 +294,7 @@ class PysonicSubsonicApi(object):
|
|||
@cherrypy.expose
|
||||
@formatresponse
|
||||
def getUser_view(self, username, **kwargs):
|
||||
user = {} if self.options.disable_auth else self.library.db.get_user(cherrypy.request.login)
|
||||
user = {} if self.options.disable_auth else self.db.get_user(cherrypy.request.login)
|
||||
response = ApiResponse()
|
||||
response.add_child("user",
|
||||
username=user["username"],
|
||||
|
@ -321,19 +319,19 @@ class PysonicSubsonicApi(object):
|
|||
@cherrypy.expose
|
||||
@formatresponse
|
||||
def star_view(self, id, **kwargs):
|
||||
self.library.set_starred(cherrypy.request.login, int(id), starred=True)
|
||||
self.db.set_starred(cherrypy.request.login, int(id), starred=True)
|
||||
return ApiResponse()
|
||||
|
||||
@cherrypy.expose
|
||||
@formatresponse
|
||||
def unstar_view(self, id, **kwargs):
|
||||
self.library.set_starred(cherrypy.request.login, int(id), starred=False)
|
||||
self.db.set_starred(cherrypy.request.login, int(id), starred=False)
|
||||
return ApiResponse()
|
||||
|
||||
@cherrypy.expose
|
||||
@formatresponse
|
||||
def getStarred_view(self, **kwargs):
|
||||
children = self.library.get_starred(cherrypy.request.login)
|
||||
children = self.db.get_starred(cherrypy.request.login)
|
||||
response = ApiResponse()
|
||||
response.add_child("starred")
|
||||
for item in children:
|
||||
|
@ -355,7 +353,7 @@ class PysonicSubsonicApi(object):
|
|||
"""
|
||||
response = ApiResponse()
|
||||
response.add_child("randomSongs")
|
||||
children = self.library.db.get_songs(limit=size, sortby="random")
|
||||
children = self.db.get_songs(limit=size, sortby="random")
|
||||
for song in children:
|
||||
moreargs = {}
|
||||
if song["format"]:
|
||||
|
@ -390,7 +388,7 @@ class PysonicSubsonicApi(object):
|
|||
def getGenres_view(self, **kwargs):
|
||||
response = ApiResponse()
|
||||
response.add_child("genres")
|
||||
for row in self.library.db.get_genres():
|
||||
for row in self.db.get_genres():
|
||||
response.add_child("genre", _parent="genres", value=row["name"], songCount=420, albumCount=69)
|
||||
return response
|
||||
|
||||
|
@ -418,7 +416,7 @@ class PysonicSubsonicApi(object):
|
|||
query = query.replace("*", "") # TODO handle this
|
||||
|
||||
artists = 0
|
||||
for item in self.library.get_artists(name_contains=query):
|
||||
for item in self.db.get_artists(name_contains=query):
|
||||
response.add_child("artist", _parent="searchResult2", id=item["id"], name=item["name"])
|
||||
artists += 1
|
||||
if artists >= artistCount:
|
||||
|
@ -426,7 +424,7 @@ class PysonicSubsonicApi(object):
|
|||
|
||||
# TODO make this more efficient
|
||||
albums = 0
|
||||
for album in self.library.get_albums(name_contains=query):
|
||||
for album in self.db.get_albums(name_contains=query):
|
||||
response.add_child("album", _parent="searchResult2",
|
||||
id=album["dir"],
|
||||
parent=album["artistdir"],
|
||||
|
@ -445,7 +443,7 @@ class PysonicSubsonicApi(object):
|
|||
|
||||
# TODO make this more efficient
|
||||
songs = 0
|
||||
for song in self.library.db.get_songs(title_contains=query):
|
||||
for song in self.db.get_songs(title_contains=query):
|
||||
response.add_child("song", _parent="searchResult2",
|
||||
id=song["id"],
|
||||
parent=song["albumdir"],
|
||||
|
@ -485,11 +483,11 @@ class PysonicSubsonicApi(object):
|
|||
def savePlayQueue_view(self, id, current, position, **kwargs):
|
||||
print("TODO save playqueue with items {} current {} position {}".format(id, repr(current), repr(position)))
|
||||
current = int(current)
|
||||
song = self.library.get_song(current)
|
||||
self.library.db.update_album_played(song['albumid'], time())
|
||||
self.library.db.increment_album_plays(song['albumid'])
|
||||
song = self.db.get_songs(id=current)[0]
|
||||
self.db.update_album_played(song['albumid'], time())
|
||||
self.db.increment_album_plays(song['albumid'])
|
||||
if int(position) == 0:
|
||||
self.library.db.increment_track_plays(current)
|
||||
self.db.increment_track_plays(current)
|
||||
# TODO save playlist with items ['378', '386', '384', '380', '383'] current 383 position 4471
|
||||
# id entries are strings!
|
||||
|
||||
|
@ -498,19 +496,19 @@ class PysonicSubsonicApi(object):
|
|||
def createPlaylist_view(self, name, songId, **kwargs):
|
||||
if type(songId) != list:
|
||||
songId = [songId]
|
||||
user = self.library.db.get_user(cherrypy.request.login)
|
||||
self.library.db.add_playlist(user["id"], name, songId)
|
||||
user = self.db.get_user(cherrypy.request.login)
|
||||
self.db.add_playlist(user["id"], name, songId)
|
||||
return ApiResponse()
|
||||
#TODO the response should be the new playlist, check the cap
|
||||
|
||||
@cherrypy.expose
|
||||
@formatresponse
|
||||
def getPlaylists_view(self, **kwargs):
|
||||
user = self.library.db.get_user(cherrypy.request.login)
|
||||
user = self.db.get_user(cherrypy.request.login)
|
||||
|
||||
response = ApiResponse()
|
||||
response.add_child("playlists")
|
||||
for playlist in self.library.db.get_playlists(user["id"]):
|
||||
for playlist in self.db.get_playlists(user["id"]):
|
||||
response.add_child("playlist",
|
||||
_parent="playlists",
|
||||
id=playlist["id"],
|
||||
|
@ -529,9 +527,10 @@ class PysonicSubsonicApi(object):
|
|||
@cherrypy.expose
|
||||
@formatresponse
|
||||
def getPlaylist_view(self, id, **kwargs):
|
||||
user = self.library.db.get_user(cherrypy.request.login)
|
||||
plinfo, songs = self.library.get_playlist(int(id))
|
||||
|
||||
id = int(id)
|
||||
user = self.db.get_user(cherrypy.request.login)
|
||||
plinfo = self.db.get_playlist(id)
|
||||
songs = self.db.get_playlist_songs(id)
|
||||
response = ApiResponse()
|
||||
response.add_child("playlist",
|
||||
id=plinfo["id"],
|
||||
|
@ -569,15 +568,16 @@ class PysonicSubsonicApi(object):
|
|||
@cherrypy.expose
|
||||
@formatresponse
|
||||
def updatePlaylist_view(self, playlistId, songIndexToRemove=None, songIdToAdd=None, **kwargs):
|
||||
user = self.library.db.get_user(cherrypy.request.login)
|
||||
plinfo, songs = self.library.get_playlist(int(playlistId))
|
||||
playlistId = int(playlistId)
|
||||
user = self.db.get_user(cherrypy.request.login)
|
||||
plinfo = self.db.get_playlist(playlistId)
|
||||
|
||||
assert plinfo["ownerid"] == user["id"]
|
||||
|
||||
if songIndexToRemove:
|
||||
self.library.db.remove_index_from_playlist(playlistId, songIndexToRemove)
|
||||
self.db.remove_index_from_playlist(playlistId, songIndexToRemove)
|
||||
elif songIdToAdd:
|
||||
self.library.db.add_to_playlist(playlistId, songIdToAdd)
|
||||
self.db.add_to_playlist(playlistId, songIdToAdd)
|
||||
#TODO there are more modification methods
|
||||
|
||||
return ApiResponse()
|
||||
|
@ -585,9 +585,9 @@ class PysonicSubsonicApi(object):
|
|||
@cherrypy.expose
|
||||
@formatresponse
|
||||
def deletePlaylist_view(self, id, **kwargs):
|
||||
user = self.library.db.get_user(cherrypy.request.login)
|
||||
plinfo, _ = self.library.get_playlist(int(id))
|
||||
user = self.db.get_user(cherrypy.request.login)
|
||||
plinfo = self.db.get_playlist(int(id))
|
||||
assert plinfo["ownerid"] == user["id"]
|
||||
|
||||
self.library.delete_playlist(plinfo["id"])
|
||||
self.db.delete_playlist(plinfo["id"])
|
||||
return ApiResponse()
|
||||
|
|
|
@ -3,7 +3,6 @@ import logging
|
|||
import cherrypy
|
||||
from sqlite3 import DatabaseError
|
||||
from pysonic.api import PysonicSubsonicApi
|
||||
from pysonic.library import PysonicLibrary
|
||||
from pysonic.database import PysonicDatabase, DuplicateRootException
|
||||
|
||||
|
||||
|
@ -35,15 +34,14 @@ def main():
|
|||
format="%(asctime)-15s %(levelname)-8s %(filename)s:%(lineno)d %(message)s")
|
||||
|
||||
db = PysonicDatabase(path=args.database_path)
|
||||
library = PysonicLibrary(db)
|
||||
for dirname in args.dirs:
|
||||
dirname = os.path.abspath(dirname)
|
||||
assert os.path.exists(dirname), "--dirs must be paths that exist"
|
||||
try:
|
||||
library.add_root_dir(dirname)
|
||||
db.add_root(dirname)
|
||||
except DuplicateRootException:
|
||||
pass
|
||||
library.update()
|
||||
db.update()
|
||||
|
||||
for username, password in args.user:
|
||||
try:
|
||||
|
@ -55,7 +53,7 @@ def main():
|
|||
# logging.warning("Artists: {}".format([i["name"] for i in library.get_artists()]))
|
||||
# logging.warning("Albums: {}".format(len(library.get_albums())))
|
||||
|
||||
api = PysonicSubsonicApi(db, library, args)
|
||||
api = PysonicSubsonicApi(db, args)
|
||||
api_config = {}
|
||||
if args.disable_auth:
|
||||
logging.warning("starting up with auth disabled")
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import os
|
||||
import sqlite3
|
||||
import logging
|
||||
from hashlib import sha512
|
||||
|
@ -5,7 +6,17 @@ from time import time
|
|||
from contextlib import closing
|
||||
from collections import Iterable
|
||||
|
||||
|
||||
from pysonic.scanner import PysonicFilesystemScanner
|
||||
|
||||
|
||||
logging = logging.getLogger("database")
|
||||
|
||||
|
||||
LETTER_GROUPS = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
|
||||
"u", "v", "w", "xyz", "0123456789"]
|
||||
|
||||
|
||||
keys_in_table = ["title", "album", "artist", "type", "size"]
|
||||
|
||||
|
||||
|
@ -49,11 +60,18 @@ class PysonicDatabase(object):
|
|||
self.db = None
|
||||
self.open()
|
||||
self.migrate()
|
||||
self.scanner = PysonicFilesystemScanner(self)
|
||||
|
||||
def open(self):
|
||||
self.db = sqlite3.connect(self.path, **self.sqlite_opts)
|
||||
self.db.row_factory = dict_factory
|
||||
|
||||
def update(self):
|
||||
"""
|
||||
Start the library media scanner ands
|
||||
"""
|
||||
self.scanner.init_scan()
|
||||
|
||||
def migrate(self):
|
||||
# Create db
|
||||
queries = ["""CREATE TABLE 'libraries' (
|
||||
|
@ -150,6 +168,16 @@ class PysonicDatabase(object):
|
|||
# logging.warning("db schema is version {}".format(version))
|
||||
pass
|
||||
|
||||
def get_artist_info(self, item_id):
|
||||
#TODO
|
||||
return {"biography": "placeholder biography",
|
||||
"musicBrainzId": "playerholder",
|
||||
"lastFmUrl": "https://www.last.fm/music/Placeholder",
|
||||
"smallImageUrl": "",
|
||||
"mediumImageUrl": "",
|
||||
"largeImageUrl": "",
|
||||
"similarArtists": []}
|
||||
|
||||
@cursor
|
||||
def get_stats(self, c):
|
||||
songs = c.execute("SELECT COUNT(*) as cnt FROM songs").fetchone()['cnt']
|
||||
|
@ -167,7 +195,7 @@ class PysonicDatabase(object):
|
|||
:return: int
|
||||
:raises: sqlite3.IntegrityError
|
||||
"""
|
||||
assert path.startswith("/")
|
||||
path = os.path.abspath(os.path.normpath(path))
|
||||
try:
|
||||
c.execute("INSERT INTO libraries ('name', 'path') VALUES (?, ?)", (name, path, ))
|
||||
c.execute("COMMIT")
|
||||
|
@ -348,11 +376,16 @@ class PysonicDatabase(object):
|
|||
return genres
|
||||
|
||||
@cursor
|
||||
def get_cover(self, c, coverid):
|
||||
def get_cover(self, c, cover_id):
|
||||
cover = None
|
||||
for cover in c.execute("SELECT * FROM covers WHERE id = ?", (coverid, )):
|
||||
for cover in c.execute("SELECT * FROM covers WHERE id = ?", (cover_id, )):
|
||||
return cover
|
||||
|
||||
def get_cover_path(self, cover_id):
|
||||
cover = self.get_cover(cover_id)
|
||||
library = self.get_libraries(cover["library"])[0]
|
||||
return os.path.join(library["path"], cover["path"])
|
||||
|
||||
@cursor
|
||||
def get_subsonic_musicdir(self, c, dirid):
|
||||
"""
|
||||
|
@ -469,12 +502,13 @@ class PysonicDatabase(object):
|
|||
|
||||
@cursor
|
||||
def empty_playlist(self, c, playlist_id):
|
||||
#TODO combine with ??
|
||||
#TODO combine with delete_playlist
|
||||
c.execute("DELETE FROM playlist_entries WHERE playlistid=?", (playlist_id, ))
|
||||
c.execute("COMMIT")
|
||||
|
||||
@cursor
|
||||
def delete_playlist(self, c, playlist_id):
|
||||
c.execute("DELETE FROM playlist_entries WHERE playlistid=?", (playlist_id, ))
|
||||
c.execute("DELETE FROM playlists WHERE id=?", (playlist_id, ))
|
||||
c.execute("COMMIT")
|
||||
|
||||
|
|
|
@ -1,98 +0,0 @@
|
|||
import os
|
||||
import logging
|
||||
from pysonic.scanner import PysonicFilesystemScanner
|
||||
from pysonic.types import MUSIC_TYPES
|
||||
|
||||
|
||||
LETTER_GROUPS = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
|
||||
"u", "v", "w", "xyz", "0123456789"]
|
||||
|
||||
|
||||
logging = logging.getLogger("library")
|
||||
|
||||
|
||||
def memoize(function):
|
||||
memo = {}
|
||||
|
||||
def wrapper(*args):
|
||||
if args in memo:
|
||||
return memo[args]
|
||||
else:
|
||||
rv = function(*args)
|
||||
memo[args] = rv
|
||||
return rv
|
||||
return wrapper
|
||||
|
||||
|
||||
class NoDataException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class PysonicLibrary(object):
|
||||
def __init__(self, database):
|
||||
self.db = database
|
||||
|
||||
self.get_libraries = self.db.get_libraries
|
||||
self.get_artists = self.db.get_artists
|
||||
self.get_albums = self.db.get_albums
|
||||
# self.get_song = self.db.get_song
|
||||
# self.get_cover = self.db.get_cover
|
||||
|
||||
self.scanner = PysonicFilesystemScanner(self)
|
||||
logging.info("library ready")
|
||||
|
||||
def update(self):
|
||||
"""
|
||||
Start the library media scanner ands
|
||||
"""
|
||||
self.scanner.init_scan()
|
||||
|
||||
def add_root_dir(self, path):
|
||||
"""
|
||||
The music library consists of a number of root dirs. This adds a new root
|
||||
"""
|
||||
path = os.path.abspath(os.path.normpath(path))
|
||||
self.db.add_root(path)
|
||||
|
||||
# def get_artists(self, *args, **kwargs):
|
||||
# artists = self.db.get_artists(*args, **kwargs)
|
||||
# for item in artists:
|
||||
# item["parent"] = item["libraryid"]
|
||||
# return artists
|
||||
|
||||
# def get_albums(self, *args, **kwargs):
|
||||
# albums = self.db.get_albums(*args, **kwargs)
|
||||
# for item in albums:
|
||||
# item["parent"] = item["artistid"]
|
||||
# return albums
|
||||
|
||||
def get_artist_info(self, item_id):
|
||||
#TODO
|
||||
return {"biography": "placeholder biography",
|
||||
"musicBrainzId": "playerholder",
|
||||
"lastFmUrl": "https://www.last.fm/music/Placeholder",
|
||||
"smallImageUrl": "",
|
||||
"mediumImageUrl": "",
|
||||
"largeImageUrl": "",
|
||||
"similarArtists": []}
|
||||
|
||||
def get_cover(self, cover_id):
|
||||
cover = self.db.get_cover(cover_id)
|
||||
library = self.db.get_libraries(cover["library"])[0]
|
||||
cover['_fullpath'] = os.path.join(library["path"], cover["path"])
|
||||
return cover
|
||||
|
||||
def get_song(self, 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
|
||||
|
||||
def get_playlist(self, playlist_id):
|
||||
playlist_info = self.db.get_playlist(playlist_id)
|
||||
songs = self.db.get_playlist_songs(playlist_id)
|
||||
return (playlist_info, songs)
|
||||
|
||||
def delete_playlist(self, playlist_id):
|
||||
self.db.empty_playlist(playlist_id)
|
||||
self.db.delete_playlist(playlist_id)
|
|
@ -18,8 +18,8 @@ RE_NUMBERS = re.compile(r'^([0-9]+)')
|
|||
|
||||
|
||||
class PysonicFilesystemScanner(object):
|
||||
def __init__(self, library):
|
||||
self.library = library
|
||||
def __init__(self, db):
|
||||
self.db = db
|
||||
|
||||
def init_scan(self):
|
||||
self.scanner = Thread(target=self.rescan, daemon=True)
|
||||
|
@ -31,7 +31,7 @@ class PysonicFilesystemScanner(object):
|
|||
"""
|
||||
start = time()
|
||||
logging.warning("Beginning library rescan")
|
||||
for parent in self.library.db.get_libraries():
|
||||
for parent in self.db.get_libraries():
|
||||
logging.info("Scanning {}".format(parent["path"]))
|
||||
self.scan_root(parent["id"], parent["path"])
|
||||
logging.warning("Rescan complete in %ss", round(time() - start, 3))
|
||||
|
@ -63,7 +63,7 @@ class PysonicFilesystemScanner(object):
|
|||
:type path list
|
||||
"""
|
||||
assert path
|
||||
# with closing(self.library.db.db.cursor()) as cursor:
|
||||
# with closing(self.db.db.cursor()) as cursor:
|
||||
parent_id = 0 # 0 indicates a top level item in the library
|
||||
for name in path:
|
||||
parent_id = self.create_or_get_dbdir(cursor, pid, parent_id, name)
|
||||
|
@ -109,7 +109,7 @@ class PysonicFilesystemScanner(object):
|
|||
if len(path) > 1:
|
||||
album = path[-1]
|
||||
|
||||
with closing(self.library.db.db.cursor()) as cursor:
|
||||
with closing(self.db.db.cursor()) as cursor:
|
||||
artist_id, artist_dirid = self.create_or_get_artist(cursor, pid, path[0])
|
||||
|
||||
album_id = None
|
||||
|
@ -226,8 +226,8 @@ class PysonicFilesystemScanner(object):
|
|||
q += "ORDER BY albumid"
|
||||
|
||||
#TODO scraping ID3 etc from the media files can be parallelized
|
||||
with closing(self.library.db.db.cursor()) as reader, \
|
||||
closing(self.library.db.db.cursor()) as writer:
|
||||
with closing(self.db.db.cursor()) as reader, \
|
||||
closing(self.db.db.cursor()) as writer:
|
||||
processed = 0 # commit batching counter
|
||||
for row in reader.execute(q):
|
||||
# Find meta, bail if the file was unreadable
|
||||
|
|
Loading…
Reference in New Issue