mirror of
https://github.com/spl0k/supysonic.git
synced 2024-12-23 01:16:18 +00:00
Added some dates and optimized the scanner
This commit is contained in:
parent
c255d9be99
commit
a261d019a8
14
db.py
14
db.py
@ -8,7 +8,7 @@ from sqlalchemy.orm import scoped_session, sessionmaker, relationship, backref
|
|||||||
from sqlalchemy.ext.declarative import declarative_base
|
from sqlalchemy.ext.declarative import declarative_base
|
||||||
|
|
||||||
from sqlalchemy.types import TypeDecorator
|
from sqlalchemy.types import TypeDecorator
|
||||||
from sqlalchemy import BINARY
|
from sqlalchemy.types import BINARY
|
||||||
|
|
||||||
import uuid, datetime
|
import uuid, datetime
|
||||||
import os.path
|
import os.path
|
||||||
@ -39,6 +39,9 @@ class UUID(TypeDecorator):
|
|||||||
def gen_id_column():
|
def gen_id_column():
|
||||||
return Column(UUID, primary_key = True, default = uuid.uuid4)
|
return Column(UUID, primary_key = True, default = uuid.uuid4)
|
||||||
|
|
||||||
|
def now():
|
||||||
|
return datetime.datetime.now().replace(microsecond = 0)
|
||||||
|
|
||||||
engine = create_engine(config.get('DATABASE_URI'), convert_unicode = True)
|
engine = create_engine(config.get('DATABASE_URI'), convert_unicode = True)
|
||||||
session = scoped_session(sessionmaker(autocommit = False, autoflush = False, bind = engine))
|
session = scoped_session(sessionmaker(autocommit = False, autoflush = False, bind = engine))
|
||||||
|
|
||||||
@ -64,6 +67,7 @@ class Folder(Base):
|
|||||||
root = Column(Boolean, default = False)
|
root = Column(Boolean, default = False)
|
||||||
name = Column(String)
|
name = Column(String)
|
||||||
path = Column(String, unique = True)
|
path = Column(String, unique = True)
|
||||||
|
created = Column(DateTime, default = now)
|
||||||
has_cover_art = Column(Boolean, default = False)
|
has_cover_art = Column(Boolean, default = False)
|
||||||
last_scan = Column(DateTime, default = datetime.datetime.min)
|
last_scan = Column(DateTime, default = datetime.datetime.min)
|
||||||
|
|
||||||
@ -75,6 +79,7 @@ class Folder(Base):
|
|||||||
'id': str(self.id),
|
'id': str(self.id),
|
||||||
'isDir': True,
|
'isDir': True,
|
||||||
'title': self.name,
|
'title': self.name,
|
||||||
|
'created': self.created.isoformat()
|
||||||
}
|
}
|
||||||
if not self.root:
|
if not self.root:
|
||||||
info['parent'] = str(self.parent_id)
|
info['parent'] = str(self.parent_id)
|
||||||
@ -110,9 +115,12 @@ class Track(Base):
|
|||||||
genre = Column(String, nullable = True)
|
genre = Column(String, nullable = True)
|
||||||
duration = Column(Integer)
|
duration = Column(Integer)
|
||||||
album_id = Column(UUID, ForeignKey('album.id'))
|
album_id = Column(UUID, ForeignKey('album.id'))
|
||||||
path = Column(String, unique = True)
|
|
||||||
bitrate = Column(Integer)
|
bitrate = Column(Integer)
|
||||||
|
|
||||||
|
path = Column(String, unique = True)
|
||||||
|
created = Column(DateTime, default = now)
|
||||||
|
last_modification = Column(Integer)
|
||||||
|
|
||||||
root_folder_id = Column(UUID, ForeignKey('folder.id'))
|
root_folder_id = Column(UUID, ForeignKey('folder.id'))
|
||||||
root_folder = relationship('Folder', primaryjoin = Folder.id == root_folder_id)
|
root_folder = relationship('Folder', primaryjoin = Folder.id == root_folder_id)
|
||||||
folder_id = Column(UUID, ForeignKey('folder.id'))
|
folder_id = Column(UUID, ForeignKey('folder.id'))
|
||||||
@ -135,6 +143,7 @@ class Track(Base):
|
|||||||
'path': self.path[len(self.root_folder.path) + 1:],
|
'path': self.path[len(self.root_folder.path) + 1:],
|
||||||
'isVideo': False,
|
'isVideo': False,
|
||||||
'discNumber': self.disc,
|
'discNumber': self.disc,
|
||||||
|
'created': self.created.isoformat(),
|
||||||
'albumId': str(self.album.id),
|
'albumId': str(self.album.id),
|
||||||
'artistId': str(self.album.artist.id),
|
'artistId': str(self.album.artist.id),
|
||||||
'type': 'music'
|
'type': 'music'
|
||||||
@ -151,7 +160,6 @@ class Track(Base):
|
|||||||
# transcodedSuffix
|
# transcodedSuffix
|
||||||
# userRating
|
# userRating
|
||||||
# averageRating
|
# averageRating
|
||||||
# created
|
|
||||||
# starred
|
# starred
|
||||||
|
|
||||||
return info
|
return info
|
||||||
|
33
scanner.py
33
scanner.py
@ -9,6 +9,7 @@ import db
|
|||||||
class Scanner:
|
class Scanner:
|
||||||
def __init__(self, session):
|
def __init__(self, session):
|
||||||
self.__session = session
|
self.__session = session
|
||||||
|
self.__tracks = db.Track.query.all()
|
||||||
self.__artists = db.Artist.query.all()
|
self.__artists = db.Artist.query.all()
|
||||||
self.__folders = db.Folder.query.all()
|
self.__folders = db.Folder.query.all()
|
||||||
|
|
||||||
@ -27,19 +28,18 @@ class Scanner:
|
|||||||
folder.last_scan = datetime.datetime.now()
|
folder.last_scan = datetime.datetime.now()
|
||||||
|
|
||||||
def prune(self, folder):
|
def prune(self, folder):
|
||||||
for artist in db.Artist.query.all():
|
for track in [ t for t in self.__tracks if t.root_folder.id == folder.id and not os.path.exists(t.path) ]:
|
||||||
for album in artist.albums[:]:
|
track.album.tracks.remove(track)
|
||||||
for track in filter(lambda t: t.root_folder.id == folder.id, album.tracks):
|
|
||||||
if not os.path.exists(track.path):
|
|
||||||
album.tracks.remove(track)
|
|
||||||
track.folder.tracks.remove(track)
|
track.folder.tracks.remove(track)
|
||||||
self.__session.delete(track)
|
self.__session.delete(track)
|
||||||
self.__deleted_tracks += 1
|
self.__deleted_tracks += 1
|
||||||
if len(album.tracks) == 0:
|
|
||||||
artist.albums.remove(album)
|
for album in [ album for artist in self.__artists for album in artist.albums if len(album.tracks) == 0 ]:
|
||||||
|
album.artist.albums.remove(album)
|
||||||
self.__session.delete(album)
|
self.__session.delete(album)
|
||||||
self.__deleted_albums += 1
|
self.__deleted_albums += 1
|
||||||
if len(artist.albums) == 0:
|
|
||||||
|
for artist in [ a for a in self.__artists if len(a.albums) == 0 ]:
|
||||||
self.__session.delete(artist)
|
self.__session.delete(artist)
|
||||||
self.__deleted_artists += 1
|
self.__deleted_artists += 1
|
||||||
|
|
||||||
@ -51,17 +51,19 @@ class Scanner:
|
|||||||
self.check_cover_art(f)
|
self.check_cover_art(f)
|
||||||
|
|
||||||
def __scan_file(self, path, folder):
|
def __scan_file(self, path, folder):
|
||||||
tag = eyeD3.Tag()
|
tr = filter(lambda t: t.path == path, self.__tracks)
|
||||||
tag.link(path)
|
|
||||||
audio_file = eyeD3.Mp3AudioFile(path)
|
|
||||||
|
|
||||||
al = self.__find_album(tag.getArtist(), tag.getAlbum())
|
|
||||||
tr = filter(lambda t: t.path == path, al.tracks)
|
|
||||||
if not tr:
|
if not tr:
|
||||||
tr = db.Track(path = path, root_folder = folder, folder = self.__find_folder(path, folder))
|
tr = db.Track(path = path, root_folder = folder, folder = self.__find_folder(path, folder))
|
||||||
|
self.__tracks.append(tr)
|
||||||
self.__added_tracks += 1
|
self.__added_tracks += 1
|
||||||
else:
|
else:
|
||||||
tr = tr[0]
|
tr = tr[0]
|
||||||
|
if not os.path.getmtime(path) > tr.last_modification:
|
||||||
|
return
|
||||||
|
|
||||||
|
tag = eyeD3.Tag()
|
||||||
|
tag.link(path)
|
||||||
|
audio_file = eyeD3.Mp3AudioFile(path)
|
||||||
|
|
||||||
tr.disc = tag.getDiscNum()[0] or 1
|
tr.disc = tag.getDiscNum()[0] or 1
|
||||||
tr.number = tag.getTrackNum()[0] or 1
|
tr.number = tag.getTrackNum()[0] or 1
|
||||||
@ -69,8 +71,9 @@ class Scanner:
|
|||||||
tr.year = tag.getYear()
|
tr.year = tag.getYear()
|
||||||
tr.genre = tag.getGenre().name if tag.getGenre() else None
|
tr.genre = tag.getGenre().name if tag.getGenre() else None
|
||||||
tr.duration = audio_file.getPlayTime()
|
tr.duration = audio_file.getPlayTime()
|
||||||
tr.album = al
|
tr.album = self.__find_album(tag.getArtist(), tag.getAlbum())
|
||||||
tr.bitrate = audio_file.getBitRate()[1]
|
tr.bitrate = audio_file.getBitRate()[1]
|
||||||
|
tr.last_modification = os.path.getmtime(path)
|
||||||
|
|
||||||
def __find_album(self, artist, album):
|
def __find_album(self, artist, album):
|
||||||
ar = self.__find_artist(artist)
|
ar = self.__find_artist(artist)
|
||||||
|
Loading…
Reference in New Issue
Block a user