import requests.exceptions from flask import request from api import models from api.api_errors import BadRequestError, NotFoundError from api.resources import AuthenticatedResource from api.resources.admin import _fetch_user_from_soundcloud, _make_insta_profile_result, _get_channel_from_youtube_api from api.resources import utils from tracker import db, aws_utils from tracker import soundcloud from tracker import spotify from tracker import twitter from tracker.spidering.spider_utils import extract_identifier_from_url_or_at_name from tracker.utils import null_safe_path from datetime import datetime class ScProfile(AuthenticatedResource): def get(self): query = request.args.get("q") if not query.startswith("https"): query = "https://soundcloud.com/{}".format(query) query = soundcloud.normalize_sc_url(query) try: profile = _fetch_user_from_soundcloud(dict(url=query)) if not profile: raise NotFoundError except requests.exceptions.HTTPError: raise NotFoundError( ( "Failed to locate a soundcloud profile for '{0}'. " "Try copy and pasting the url from the user's Soundcloud page. " "eg: https://soundcloud.com/alex".format(request.args.get("q")) ) ) return soundcloud.to_regression_profile(profile) def extract_id_from_url(request, domain=""): query = request.args.get("q") if not query: raise BadRequestError("q is required") query = extract_identifier_from_url_or_at_name(query, domain) if not query or len(query) < 2: raise BadRequestError("Invalid data sent") return query class InProfile(AuthenticatedResource): def get(self): value = request.args.get("q") return _make_insta_profile_result(value) class SpyProfile(AuthenticatedResource): def get(self): uri = request.args.get("q") if not uri or len(uri) < 10: raise BadRequestError if not "spotify:artist" in uri and not "open.spotify.com/artist/" in uri: raise BadRequestError if "?" in uri: uri = uri.split("?")[0] artist = spotify.lookup_artist(uri) if not artist: raise NotFoundError return dict( artist, name=artist["name"], username="", source_url=artist["external_urls"]["spotify"], avatar=next((i["url"] for i in artist["images"]), None), ) class TwProfile(AuthenticatedResource): def get(self): screen_name = extract_id_from_url(request, "twitter.com") req = requests.get( "https://twitter.com/intent/user?screen_name={}".format(screen_name), allow_redirects=False, ) if req.status_code == 404 or ( req.status_code == 302 and "suspended" in req.headers.get("Location") or "" ): return NotFoundError user = twitter.new_instance().fetch_user(screen_name, shallow=True) if not user: return NotFoundError return dict( user, id=user["id_str"], name=user["name"], username=user["screen_name"], avatar=user["profile_image_url_https"], source_url="https://twitter.com/" + user["screen_name"], ) class YtProfile(AuthenticatedResource): def get(self): url = request.args.get('q') channel_data = _get_channel_from_youtube_api(url) return dict( id=channel_data.ytid, name=channel_data.title, username='', avatar=channel_data.thumbnail, source_url="https://www.youtube.com/channel/" + channel_data.ytid, ) class RecommendedInfluencers(AuthenticatedResource): pass class ScRecommendedInfluencers(RecommendedInfluencers): def post(self): artist = soundcloud.add_regression_artist(self.user.name, request.json) if not artist.followers_download_completed: aws_utils.run_followers_download_task("sc", self.user.name, artist.scid) return utils.regression_artist_to_api_json(artist) def get(self): return { "regressionArtists": models.regression_artists(self.user.name), "recommendedScouts": [ dict(a, profile=soundcloud.to_regression_profile(a["profile"])) for a in soundcloud.get_recommended_influencers(self.user.name)[:30] ], } def delete(self): data = request.json record = soundcloud.get_regression_artist(scid=data["id"], username=self.user.name) if record: record.deleted = datetime.today() db.Session.commit() return "", 204