diff --git a/server/djrandom/model/mp3.py b/server/djrandom/model/mp3.py
index 12b9c631d2a99323141937a0c044e1909feba6af..755af8a6c4a2b32057afdf0df3759deb14635203 100644
--- a/server/djrandom/model/mp3.py
+++ b/server/djrandom/model/mp3.py
@@ -136,6 +136,17 @@ class MP3(Base):
         """Return N random songs that were never played."""
         return cls.get_random_songs(n, where_clause=(cls.play_count == 0))
 
+    @classmethod
+    def uploads_by_day(cls, days=30):
+        # select to_days(uploaded_at) as d, count(*) from mp3 group by d order by d asc;
+        result = []
+        for row in Session.query(func.to_days(cls.uploaded_at).label('day'),
+                                 func.count('*').label('count')).filter(
+                                 cls.uploaded_at > date_limit).group_by(
+                                 'day').order_by('day asc'):
+            result.append(row.count)
+        return result
+
 
 class PlayLog(Base):
 
@@ -171,6 +182,15 @@ class PlayLog(Base):
                 hashes = [None] * n
             yield (plog.sha1, hashes)
 
+    @classmethod
+    def top_songs_for_user(cls, userid, days=30, n=10):
+        """Return the top played songs for a user."""
+        date_limit = datetime.now() - timedelta(days)
+        return Session.query(cls.sha1, func.count(cls.sha1).label('count')
+            ).filter((cls.userid == userid)
+                     & (cls.stamp > date_limit)
+            ).group_by(cls.sha1).order_by('count desc').limit(n)
+
 
 class SearchLog(Base):