def get_top(cls, after=None, before=None, song_num=10, album_num=10, keys_only=False): # Sanitize our range dates. Dates instead of times make caching # more convenient, and I don't even think we can ask for times # anyway if before is None: before = datetime.date.today() + datetime.timedelta(days=1) else: if isinstance(before, datetime.datetime): before = before.date() before += datetime.timedelta(days=1) if after is None: after = datetime.date.today() - datetime.timedelta(days=6) elif isinstance(after, datetime.datetime): after = after.date() cached_songs = cls.get_cached_query(cls.TOP_SONGS, before, after) cached_albums = cls.get_cached_query(cls.TOP_ALBUMS, before, after) # If our caches exist and are sufficient if not (cached_songs is None or cached_songs.need_fetch(song_num) or cached_albums is None or cached_albums.need_fetch(album_num)): songs = cached_songs.results albums = cached_albums.results else: new_plays = cls.get(before=before, after=after, is_new=True, num=1000) songs = {} albums = {} for play in new_plays: song_key = play.song_key if song_key in songs: songs[song_key] += 1 else: songs[song_key] = 1 if play.song_key is not None and play.song.album_key is not None: album_key = play.song.album_key if album_key in albums: albums[album_key] += 1 else: albums[album_key] = 1 songs = songs.items() albums = albums.items() if not keys_only: songs = [(Song.get(song), count) for song,count in songs] if not keys_only: albums = [(Album.get(album), count) for album,count in albums] songs = sorted(songs, key=(lambda x: x[1]), reverse=True)[:song_num] albums = sorted(albums, key=(lambda x: x[1]), reverse=True)[:album_num] cached_songs return (songs, albums)
def song(self): return Song.get(self.song_key)
def get_top(cls, after=None, before=None, song_num=10, album_num=10, keys_only=False): # Sanitize our range dates. Dates instead of times make caching # more convenient, and I don't even think we can ask for times # anyway if before is None and after is None: before, after = last_week_span() elif before is None: before = last_week_span(after + datetime.timedelta(6))[0] elif after is None: after = last_week_span(before)[1] cached_songs = CountTableCache.fetch(cls.TOP_SONGS%(before, after)) cached_albums = CountTableCache.fetch(cls.TOP_ALBUMS%(before, after)) cached = False # If our caches exist and are sufficient if not (True or cached_songs.need_fetch(song_num) or cached_albums.need_fetch(album_num)): song_counts = cached_songs.results album_counts = cached_albums.results cached = True else: new_plays, cursor, more = cls.get( before=before, after=after, is_new=True, num=1000, page=True) song_counts = {} album_counts = {} for play in new_plays: song_key = play.song_key if song_key in song_counts: song_counts[song_key] += 1 else: song_counts[song_key] = 1 if play.song_key is not None and play.song.album_key is not None: album_key = play.song.album_key if album_key in album_counts: album_counts[album_key] += 1 else: album_counts[album_key] = 1 logging.debug(song_counts) if not keys_only: if song_counts: songs = zip(Song.get(song_counts.keys()), song_counts.values()) else: songs = [] if album_counts: albums = zip(Album.get(album_counts.keys()), album_counts.values()) else: albums = [] else: songs = song_counts.iteritems() albums = album_counts.iteritems() if not cached: cached_songs.set(song_counts, more) cached_albums.set(album_counts, more) cached_songs.save() cached_albums.save() songs = sorted(songs, key=itemgetter(1), reverse=True)[:song_num] albums = sorted(albums, key=itemgetter(1), reverse=True)[:album_num] return (songs, albums)