mirror of
https://github.com/spl0k/supysonic.git
synced 2024-12-22 17:06:17 +00:00
Adding some track info and implemented getRandomSongs.view
This commit is contained in:
parent
d217fa9d9d
commit
a6301111c2
46
api/albums_songs.py
Executable file
46
api/albums_songs.py
Executable file
@ -0,0 +1,46 @@
|
|||||||
|
# coding: utf-8
|
||||||
|
|
||||||
|
from flask import request
|
||||||
|
from web import app
|
||||||
|
from db import Track
|
||||||
|
import random
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
@app.route('/rest/getRandomSongs.view')
|
||||||
|
def rand_songs():
|
||||||
|
size = request.args.get('size', '10')
|
||||||
|
genre, fromYear, toYear, musicFolderId = map(request.args.get, [ 'genre', 'fromYear', 'toYear', 'musicFolderId' ])
|
||||||
|
|
||||||
|
try:
|
||||||
|
size = int(size) if size else 10
|
||||||
|
fromYear = int(fromYear) if fromYear else None
|
||||||
|
toYear = int(toYear) if toYear else None
|
||||||
|
fid = uuid.UUID(musicFolderId) if musicFolderId else None
|
||||||
|
except:
|
||||||
|
return request.formatter({
|
||||||
|
'error': {
|
||||||
|
'code': 0,
|
||||||
|
'message': 'Invalid parameter format'
|
||||||
|
}
|
||||||
|
}, error = True)
|
||||||
|
|
||||||
|
query = Track.query
|
||||||
|
if fromYear:
|
||||||
|
query = query.filter(Track.year >= fromYear)
|
||||||
|
if toYear:
|
||||||
|
query = query.filter(Track.year <= toYear)
|
||||||
|
if genre:
|
||||||
|
query = query.filter(Track.genre == genre)
|
||||||
|
if fid:
|
||||||
|
query = query.filter(Track.folder_id == fid)
|
||||||
|
tracks = query.all()
|
||||||
|
|
||||||
|
if not tracks:
|
||||||
|
return request.formatter({ 'randomSongs': {} })
|
||||||
|
|
||||||
|
return request.formatter({
|
||||||
|
'randomSongs': {
|
||||||
|
'song': [ random.choice(tracks).as_subsonic_child() for x in xrange(size) ]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
51
db.py
51
db.py
@ -3,7 +3,7 @@
|
|||||||
import config
|
import config
|
||||||
|
|
||||||
from sqlalchemy import create_engine, Column, ForeignKey
|
from sqlalchemy import create_engine, Column, ForeignKey
|
||||||
from sqlalchemy import Integer, String, Boolean, DateTime, Time
|
from sqlalchemy import Integer, String, Boolean, DateTime
|
||||||
from sqlalchemy.orm import scoped_session, sessionmaker, relationship, backref
|
from sqlalchemy.orm import scoped_session, sessionmaker, relationship, backref
|
||||||
from sqlalchemy.ext.declarative import declarative_base
|
from sqlalchemy.ext.declarative import declarative_base
|
||||||
|
|
||||||
@ -11,6 +11,7 @@ from sqlalchemy.types import TypeDecorator
|
|||||||
from sqlalchemy import BINARY
|
from sqlalchemy import BINARY
|
||||||
|
|
||||||
import uuid, datetime
|
import uuid, datetime
|
||||||
|
import os.path
|
||||||
|
|
||||||
class UUID(TypeDecorator):
|
class UUID(TypeDecorator):
|
||||||
impl = BINARY
|
impl = BINARY
|
||||||
@ -84,13 +85,59 @@ class Track(Base):
|
|||||||
disc = Column(Integer)
|
disc = Column(Integer)
|
||||||
number = Column(Integer)
|
number = Column(Integer)
|
||||||
title = Column(String)
|
title = Column(String)
|
||||||
duration = Column(Time)
|
year = Column(Integer, nullable = True)
|
||||||
|
genre = Column(String, nullable = True)
|
||||||
|
duration = Column(Integer)
|
||||||
album_id = Column(UUID, ForeignKey('album.id'))
|
album_id = Column(UUID, ForeignKey('album.id'))
|
||||||
path = Column(String, unique = True)
|
path = Column(String, unique = True)
|
||||||
|
bitrate = Column(Integer)
|
||||||
|
|
||||||
folder_id = Column(UUID, ForeignKey('folder.id'))
|
folder_id = Column(UUID, ForeignKey('folder.id'))
|
||||||
folder = relationship('MusicFolder')
|
folder = relationship('MusicFolder')
|
||||||
|
|
||||||
|
def as_subsonic_child(self):
|
||||||
|
info = {
|
||||||
|
'id': str(self.id),
|
||||||
|
'parent': str(self.album.id),
|
||||||
|
'isDir': False,
|
||||||
|
'title': self.title,
|
||||||
|
'album': self.album.name,
|
||||||
|
'artist': self.album.artist.name,
|
||||||
|
'track': self.number,
|
||||||
|
'size': os.path.getsize(self.path),
|
||||||
|
'contentType': 'audio/mpeg', # we only know how to read mp3s
|
||||||
|
'suffix': 'mp3', # same as above
|
||||||
|
'duration': self.duration,
|
||||||
|
'bitRate': self.bitrate,
|
||||||
|
'path': self.path[len(self.folder.path) + 1:],
|
||||||
|
'isVideo': False,
|
||||||
|
'discNumber': self.disc,
|
||||||
|
'albumId': str(self.album.id),
|
||||||
|
'artistId': str(self.album.artist.id),
|
||||||
|
'type': 'music'
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.year:
|
||||||
|
info['year'] = self.year
|
||||||
|
if self.genre:
|
||||||
|
info['genre'] = self.genre
|
||||||
|
|
||||||
|
# coverArt
|
||||||
|
# transcodedContentType
|
||||||
|
# transcodedSuffix
|
||||||
|
# userRating
|
||||||
|
# averageRating
|
||||||
|
# created
|
||||||
|
# starred
|
||||||
|
|
||||||
|
return info
|
||||||
|
|
||||||
|
def duration_str(self):
|
||||||
|
ret = '%02i:%02i' % ((self.duration % 3600) / 60, self.duration % 60)
|
||||||
|
if self.duration >= 3600:
|
||||||
|
ret = '%02i:%s' % (self.duration / 3600, ret)
|
||||||
|
return ret
|
||||||
|
|
||||||
def init_db():
|
def init_db():
|
||||||
Base.metadata.create_all(bind = engine)
|
Base.metadata.create_all(bind = engine)
|
||||||
|
|
||||||
|
12
scanner.py
12
scanner.py
@ -6,12 +6,6 @@ import eyeD3
|
|||||||
|
|
||||||
import db
|
import db
|
||||||
|
|
||||||
def seconds_to_time(secs):
|
|
||||||
th = secs / 3600
|
|
||||||
tm = (secs % 3600) / 60
|
|
||||||
ts = secs % 60
|
|
||||||
return datetime.time(int(th), int(tm), int(ts))
|
|
||||||
|
|
||||||
class Scanner:
|
class Scanner:
|
||||||
def __init__(self, session):
|
def __init__(self, session):
|
||||||
self.__session = session
|
self.__session = session
|
||||||
@ -49,6 +43,7 @@ class Scanner:
|
|||||||
def __scan_file(self, path, folder):
|
def __scan_file(self, path, folder):
|
||||||
tag = eyeD3.Tag()
|
tag = eyeD3.Tag()
|
||||||
tag.link(path)
|
tag.link(path)
|
||||||
|
audio_file = eyeD3.Mp3AudioFile(path)
|
||||||
|
|
||||||
al = self.__find_album(tag.getArtist(), tag.getAlbum())
|
al = self.__find_album(tag.getArtist(), tag.getAlbum())
|
||||||
tr = filter(lambda t: t.path == path, al.tracks)
|
tr = filter(lambda t: t.path == path, al.tracks)
|
||||||
@ -61,8 +56,11 @@ class Scanner:
|
|||||||
tr.disc = (tag.getDiscNum() or (1, 1))[0]
|
tr.disc = (tag.getDiscNum() or (1, 1))[0]
|
||||||
tr.number = tag.getTrackNum()[0]
|
tr.number = tag.getTrackNum()[0]
|
||||||
tr.title = tag.getTitle()
|
tr.title = tag.getTitle()
|
||||||
tr.duration = seconds_to_time(eyeD3.Mp3AudioFile(path).getPlayTime())
|
tr.year = tag.getYear()
|
||||||
|
tr.genre = tag.getGenre().name if tag.getGenre() else None
|
||||||
|
tr.duration = audio_file.getPlayTime()
|
||||||
tr.album = al
|
tr.album = al
|
||||||
|
tr.bitrate = audio_file.getBitRate()[1]
|
||||||
|
|
||||||
def __find_album(self, artist, album):
|
def __find_album(self, artist, album):
|
||||||
ar = self.__find_artist(artist)
|
ar = self.__find_artist(artist)
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
<table>
|
<table>
|
||||||
<tr><th>Artist</th><th>Album</th><th>Disc</th><th>#</th><th>Title</th><th>Len</th><th>Path</th></tr>
|
<tr><th>Artist</th><th>Album</th><th>Disc</th><th>#</th><th>Title</th><th>Len</th><th>Path</th></tr>
|
||||||
{% for track in tracks %}
|
{% for track in tracks %}
|
||||||
<tr><td>{{ track.album.artist.name }}</td><td>{{ track.album.name }}</td><td>{{ track.disc }}</td><td>{{ track.number }}</td><td>{{ track.title }}</td><td>{{ track.duration }}</td><td>{{ track.path }}</td></tr>
|
<tr><td>{{ track.album.artist.name }}</td><td>{{ track.album.name }}</td><td>{{ track.disc }}</td><td>{{ track.number }}</td><td>{{ track.title }}</td><td>{{ track.duration_str() }}</td><td>{{ track.path }}</td></tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
<p>{{ tracks|length }} tracks</p>
|
<p>{{ tracks|length }} tracks</p>
|
||||||
|
Loading…
Reference in New Issue
Block a user