From a6301111c2af2a2e24aea68e9e6356de40a0c2be Mon Sep 17 00:00:00 2001 From: Alban Date: Sat, 20 Oct 2012 18:05:37 +0200 Subject: [PATCH] Adding some track info and implemented getRandomSongs.view --- api/albums_songs.py | 46 ++++++++++++++++++++++++++++++++++++++++ db.py | 51 +++++++++++++++++++++++++++++++++++++++++++-- scanner.py | 12 +++++------ templates/home.html | 2 +- web.py | 1 + 5 files changed, 102 insertions(+), 10 deletions(-) create mode 100755 api/albums_songs.py diff --git a/api/albums_songs.py b/api/albums_songs.py new file mode 100755 index 0000000..e07db20 --- /dev/null +++ b/api/albums_songs.py @@ -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) ] + } + }) + diff --git a/db.py b/db.py index e127d29..c4f0a19 100755 --- a/db.py +++ b/db.py @@ -3,7 +3,7 @@ import config 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.ext.declarative import declarative_base @@ -11,6 +11,7 @@ from sqlalchemy.types import TypeDecorator from sqlalchemy import BINARY import uuid, datetime +import os.path class UUID(TypeDecorator): impl = BINARY @@ -84,13 +85,59 @@ class Track(Base): disc = Column(Integer) number = Column(Integer) 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')) path = Column(String, unique = True) + bitrate = Column(Integer) folder_id = Column(UUID, ForeignKey('folder.id')) 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(): Base.metadata.create_all(bind = engine) diff --git a/scanner.py b/scanner.py index 719696b..a521abe 100755 --- a/scanner.py +++ b/scanner.py @@ -6,12 +6,6 @@ import eyeD3 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: def __init__(self, session): self.__session = session @@ -49,6 +43,7 @@ class Scanner: def __scan_file(self, path, folder): tag = eyeD3.Tag() 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) @@ -61,8 +56,11 @@ class Scanner: tr.disc = (tag.getDiscNum() or (1, 1))[0] tr.number = tag.getTrackNum()[0] 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.bitrate = audio_file.getBitRate()[1] def __find_album(self, artist, album): ar = self.__find_artist(artist) diff --git a/templates/home.html b/templates/home.html index 904f550..9b7c49b 100755 --- a/templates/home.html +++ b/templates/home.html @@ -41,7 +41,7 @@ {% for track in tracks %} - + {% endfor %}
ArtistAlbumDisc#TitleLenPath
{{ track.album.artist.name }}{{ track.album.name }}{{ track.disc }}{{ track.number }}{{ track.title }}{{ track.duration }}{{ track.path }}
{{ track.album.artist.name }}{{ track.album.name }}{{ track.disc }}{{ track.number }}{{ track.title }}{{ track.duration_str() }}{{ track.path }}

{{ tracks|length }} tracks

diff --git a/web.py b/web.py index eaff244..0ff02e4 100755 --- a/web.py +++ b/web.py @@ -182,4 +182,5 @@ def scan_folder(id = None): import api.system import api.browse import api.user +import api.albums_songs