diff --git a/api/annotation.py b/api/annotation.py index 84693c9..99fe356 100755 --- a/api/annotation.py +++ b/api/annotation.py @@ -18,7 +18,7 @@ def star(): except: return 2, request.error_formatter(0, 'Invalid %s id' % ent.__name__) - if starred_ent.query.filter(starred_ent.user_id == request.user.id).filter(starred_ent.starred_id == uid).first(): + if starred_ent.query.get((request.user.id, uid)): return 2, request.error_formatter(0, '%s already starred' % ent.__name__) e = ent.query.get(uid) if e: @@ -84,6 +84,42 @@ def unstar(): session.commit() return request.formatter({}) +@app.route('/rest/setRating.view', methods = [ 'GET', 'POST' ]) +def rate(): + id, rating = map(request.args.get, [ 'id', 'rating' ]) + if not id or not rating: + return request.error_formatter(10, 'Missing parameter') + + try: + uid = uuid.UUID(id) + rating = int(rating) + except: + return request.error_formatter(0, 'Invalid parameter') + + if not rating in xrange(6): + return request.error_formatter(0, 'rating must be between 0 and 5 (inclusive)') + + if rating == 0: + RatingTrack.query.filter(RatingTrack.user_id == request.user.id).filter(RatingTrack.rated_id == uid).delete() + RatingFolder.query.filter(RatingFolder.user_id == request.user.id).filter(RatingFolder.rated_id == uid).delete() + else: + rated = Track.query.get(uid) + rating_ent = RatingTrack + if not rated: + rated = Folder.query.get(uid) + rating_ent = RatingFolder + if not rated: + return request.error_formatter(70, 'Unknown id') + + rating_info = rating_ent.query.get((request.user.id, uid)) + if rating_info: + rating_info.rating = rating + else: + session.add(rating_ent(user = request.user, rated = rated, rating = rating)) + + session.commit() + return request.formatter({}) + @app.route('/rest/scrobble.view', methods = [ 'GET', 'POST' ]) def scrobble(): status, res = get_entity(request, Track) diff --git a/db.py b/db.py index 54fe6a5..184818a 100755 --- a/db.py +++ b/db.py @@ -2,7 +2,7 @@ import config -from sqlalchemy import create_engine, Column, ForeignKey +from sqlalchemy import create_engine, Column, ForeignKey, func from sqlalchemy import Integer, String, Boolean, DateTime from sqlalchemy.orm import scoped_session, sessionmaker, relationship, backref from sqlalchemy.ext.declarative import declarative_base @@ -92,10 +92,17 @@ class Folder(Base): if self.has_cover_art: info['coverArt'] = str(self.id) - starred = StarredFolder.query.filter(StarredFolder.starred_id == self.id).filter(StarredFolder.user_id == user.id).first() + starred = StarredFolder.query.get((user.id, self.id)) if starred: info['starred'] = starred.date.isoformat() + rating = RatingFolder.query.get((user.id, self.id)) + if rating: + info['userRating'] = rating.rating + avgRating = RatingFolder.query.filter(RatingFolder.rated_id == self.id).value(func.avg(RatingFolder.rating)) + if avgRating: + info['averageRating'] = avgRating + return info class Artist(Base): @@ -113,7 +120,7 @@ class Artist(Base): 'albumCount': len(self.albums) } - starred = StarredArtist.query.filter(StarredArtist.starred_id == self.id).filter(StarredArtist.user_id == user.id).first() + starred = StarredArtist.query.get((user.id, self.id)) if starred: info['starred'] = starred.date.isoformat() @@ -140,7 +147,7 @@ class Album(Base): if self.tracks[0].folder.has_cover_art: info['coverArt'] = str(self.tracks[0].folder_id) - starred = StarredAlbum.query.filter(StarredAlbum.starred_id == self.id).filter(StarredAlbum.user_id == user.id).first() + starred = StarredAlbum.query.get((user.id, self.id)) if starred: info['starred'] = starred.date.isoformat() @@ -205,14 +212,19 @@ class Track(Base): if self.folder.has_cover_art: info['coverArt'] = str(self.folder_id) - starred = StarredTrack.query.filter(StarredTrack.starred_id == self.id).filter(StarredTrack.user_id == user.id).first() + starred = StarredTrack.query.get((user.id, self.id)) if starred: info['starred'] = starred.date.isoformat() + rating = RatingTrack.query.get((user.id, self.id)) + if rating: + info['userRating'] = rating.rating + avgRating = RatingTrack.query.filter(RatingTrack.rated_id == self.id).value(func.avg(RatingTrack.rating)) + if avgRating: + info['averageRating'] = avgRating + # transcodedContentType # transcodedSuffix - # userRating - # averageRating return info @@ -265,6 +277,26 @@ class StarredTrack(Base): user = relationship('User') starred = relationship('Track') +class RatingFolder(Base): + __tablename__ = 'rating_folder' + + user_id = Column(UUID, ForeignKey('user.id'), primary_key = True) + rated_id = Column(UUID, ForeignKey('folder.id'), primary_key = True) + rating = Column(Integer) + + user = relationship('User') + rated = relationship('Folder') + +class RatingTrack(Base): + __tablename__ = 'rating_track' + + user_id = Column(UUID, ForeignKey('user.id'), primary_key = True) + rated_id = Column(UUID, ForeignKey('track.id'), primary_key = True) + rating = Column(Integer) + + user = relationship('User') + rated = relationship('Track') + def init_db(): Base.metadata.create_all(bind = engine)