from datetime import timedelta, date from flask import request from api import models, api_errors from api.resources import AuthenticatedResource from api.resources.charts import SpotifyOlap from tracker import db from tracker.soundcloud_analyzer import get_results class SoundCloudAnalyzer(AuthenticatedResource): default_filters = dict( minPlaysYesterday=1000, timePeriod=1, strength=20, noiseReduction=0.6, ) def post(self): filters = {**self.default_filters, **(request.get_json().get('filters') or {})} period = filters['timePeriod'] if period == 0: slope_arg_name = 'min_slope15' rsq_arg_name = 'min_rsq15' elif period == 1: slope_arg_name = 'min_slope22' rsq_arg_name = 'min_rsq22' elif period == 2: slope_arg_name = 'min_slope29' rsq_arg_name = 'min_rsq29' else: raise api_errors.BadRequestError(f"Unknown timePeriod '{period}'") kwargs = { slope_arg_name: filters['strength'], rsq_arg_name: filters['noiseReduction'], 'min_plays_yesterday': filters['minPlaysYesterday'], 'country_codes': filters['country_codes'], } all_rows = list(get_results(**kwargs)) return { "matrix": all_rows, "schema": [ "scid", "artist_scid", # "is_scouted", "release_days_ago", "likes", "followers", "total_plays", "plays_yesterday", "slope_rolling7", "slope22", "slope29", "rsq7", "rsq22", "rsq29", "avg_daily_plays", ], } class SoundCloudTrackByScid(AuthenticatedResource): def get(self): scids = [int(scid.strip()) for scid in (request.args.get("scids") or "").split(",")] ids_list = db.Session.execute('''select scid, (data->'user'->>'id')::int from sc_tracks where scid = any (:scids)''', params=dict(scids=scids)).fetchall() tracks = list(models.soundcloud_tracks(scids)) artists = list(models.artists("sc", [r[1] for r in ids_list])) return { "results": [ { "track_scid": r[0], "track": next((t["track"] for t in tracks if t["scid"] == r[0]), None), "artist": next((a["artist"] for a in artists if a["scid"] == r[1]), None), } for r in ids_list ] } class SpotifyAnalyzer(SpotifyOlap): def post(self): return { "matrix": self.get_spyids(self.get_filters(), limit=10000, offset=0), "schema": [ "track_spyid", "artist_spyid", "release_days_ago", "track_popularity", "artist_popularity", "followers" ] } class SpotifyTracksById(AuthenticatedResource): def get(self): spyids = [s.strip() for s in (request.args.get("spyids") or "").split(",")] return { "results": list(models.spotify_tracks(spyids, with_artist_stats=False)) } class InstagramAnalyzer(AuthenticatedResource): def post(self): sql = ''' with lags as (select inid, as_of::date, followed_by_count, followed_by_count - lag(followed_by_count, 1) over (partition by inid order by as_of) delta, lag(as_of, 1) over (partition by inid order by as_of) d1, as_of::date - (lag(as_of, 1) over (partition by inid order by as_of))::date days from in_stats where as_of > '2019-06-01'::date and as_of::date = any (array[ current_date, current_date-1, current_date-2, current_date-3, current_date-4, current_date-5, current_date-6, current_date-7, current_date-8, current_date-9, current_date-10, current_date-11, current_date-12, current_date-13, current_date-14 ]::date[]) ), growers as ( select inid, followed_by_count, delta::float / days::float change, delta::float / days::float / followed_by_count::float pct from lags where days > 0 and followed_by_count > 500 and delta::float / days::float / followed_by_count::float > 0.01 ) select 'in/'||inid, growers.followed_by_count, growers.change, growers.pct from growers join in_artists using (inid) ''' return { "matrix": db.Session.execute(sql).fetchall(), "schema": [ "artistKey", # "last_scouted_days_ago", "followers", "avg_change_followers", "avg_pct_change_followers", ] } class SpotifyTracksById(AuthenticatedResource): def get(self): spyids = [s.strip() for s in (request.args.get("spyids") or "").split(",")] return { "results": list(models.spotify_tracks(spyids, with_artist_stats=False)) }