1
0
mirror of https://github.com/spl0k/supysonic.git synced 2024-11-14 14:12:17 +00:00

Adding some track info and implemented getRandomSongs.view

This commit is contained in:
Alban 2012-10-20 18:05:37 +02:00
parent d217fa9d9d
commit a6301111c2
5 changed files with 102 additions and 10 deletions

46
api/albums_songs.py Executable file
View 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
View File

@ -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)

View File

@ -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)

View File

@ -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>

1
web.py
View File

@ -182,4 +182,5 @@ def scan_folder(id = None):
import api.system import api.system
import api.browse import api.browse
import api.user import api.user
import api.albums_songs