def GET(self): rdio, current_user, user_id = get_rdio_and_current_user() if rdio and current_user: if user_id in config.ADMIN_USERS: form_input = get_input() if 'button' in form_input.keys(): action = form_input['button'] db = get_db() if action == 'doitnow_go_on_killme': if user_id in config.ADMIN_USERS: db.delete(USER_TABLE, where="rdio_user_id=%i" % user_id) raise web.seeother('/') elif action == 'clear_preferences': if user_id in config.ADMIN_USERS: db.update(USER_TABLE, where="rdio_user_id=%i" % user_id, prefs=BSONPostgresSerializer.from_dict({})) raise web.seeother('/admin') else: content=get_admin_content() db = get_db() users = db.select(USER_TABLE, what='rdio_user_id, last_use') users = dict([('s%s' % u['rdio_user_id'], u['last_use']) for u in users]) rdio_users = rdio.call('get', {'keys': ','.join(users.keys()), 'extras': '-*,username,url'})['result'] user_list = [(u['username'], u['url'], users[uid]) for uid, u in rdio_users.items()] user_list.sort(key=lambda x: x[2], reverse=True) return render.admin(env_message=get_environment_message(), admin=content, users=user_list) raise web.seeother('/')
def GET(self): form_input = get_input() action = form_input['button'] svc, current_user, user_id = get_rdio_and_current_user() db = get_db() where_to_next = '/' if action == 'new_email': new_email = make_unique_email() db.update(USER_TABLE, where="rdio_user_id=%i" % user_id, address=new_email) where_to_next += 'config?saved=True' elif action == 'save': where_to_next += 'config?saved=True' preferences = get_db_prefs(user_id, db=db) new_preferences = get_preferences_from_input(form_input) preferences.update(new_preferences) db.update(USER_TABLE, where="rdio_user_id=%i" % user_id, prefs=BSONPostgresSerializer.from_dict(preferences)) # circular import from discoversong.sources import SourceAppsManager for source_app in SourceAppsManager.ALL: for capability in source_app.capabilities: for configurable_thing in capability.config_options(): if isinstance(configurable_thing, ConfigStoredValue): new_value = configurable_thing.read_from_input(form_input) if not configurable_thing.store_as_db_field: preferences = get_db_prefs(user_id, db=db) preferences[configurable_thing.name] = new_value db.update(USER_TABLE, where="rdio_user_id=%i" % user_id, prefs=BSONPostgresSerializer.from_dict(preferences)) else: db.update(USER_TABLE, where="rdio_user_id=%i" % user_id, **{configurable_thing.name: new_value}) raise web.seeother(where_to_next)
def get_rdio_and_current_user(access_token=NOT_SPECIFIED, access_token_secret=NOT_SPECIFIED, request=True): if access_token and access_token_secret: try: rdio = get_rdio_with_access(access_token, access_token_secret) logging.error('got rdio %s' % rdio) # make sure that we can make an authenticated call currentUser = rdio.call('currentUser', {'extras': 'username'})['result'] rdio_user_id = int(currentUser['key'][1:]) if access_token == NOT_SPECIFIED and access_token_secret == NOT_SPECIFIED: access_token = web.cookies().get('at') access_token_secret = web.cookies().get('ats') db = get_db() db.update(USER_TABLE, where="rdio_user_id=%i" % rdio_user_id, token=access_token, secret=access_token_secret) logging.info('updated token and secret for user') except urllib2.HTTPError as ex: logging.exception(ex.message) # this almost certainly means that authentication has been revoked for the app. log out. if request: raise web.seeother('/logout') else: logging.error('could not get rdio with token and secret %s %s and cannot log out because not a web call' % (access_token, access_token_secret)) return None, None, None except Exception as ex2: logging.exception(ex2.message) return None, None, None return rdio, currentUser, int(currentUser['key'][1:]) else: return None, None, None
def POST(self): db = get_db() form_input = get_input() envelope = json.loads(form_input['envelope']) to_addresses = envelope['to'] for to_address in to_addresses: lookup = db.select(USER_TABLE, where="address='%s'" % to_address) if len(lookup) == 1: result = lookup[0] access_token = str(result['token']) access_token_secret = str(result['secret']) rdio, current_user, user_id = get_rdio_and_current_user(access_token=access_token, access_token_secret=access_token_secret) stats.got_email(user_id) subject = form_input['subject'] body = form_input['text'] try: title, artist = parse(subject, body) except Exception as e: logging.exception(e.message) return None search_results = well_formed_search(rdio, user_id, artist, title) return_results(rdio, user_id, search_results) return None
def well_formed_search(rdio, user_id, artist, title): db = get_db() prefs = get_db_prefs(user_id, db=db) or_search = prefs.get(Preferences.NoOrSearch, False) one_result = prefs.get(Preferences.OneResult, False) results = [] never_or = 'false' if or_search else 'true' stats.made_search(user_id) search_result = rdio.call('search', {'query': ' '.join([artist, title]), 'types': 'Track', 'never_or': never_or}) name_artist_pairs_found = {} for possible_hit in search_result['result']['results']: if possible_hit['canStream']: name = possible_hit['name'] artist_name = possible_hit['artist'] if name_artist_pairs_found.has_key((name, artist_name)): continue name_artist_pairs_found[(name, artist_name)] = True results.append((name, artist_name, possible_hit['shortUrl'], possible_hit['key'])) if one_result: break return results
def well_formed_search(rdio, user_id, artist, title): db = get_db() prefs = get_db_prefs(user_id, db=db) or_search = prefs.get(Preferences.NoOrSearch, False) one_result = prefs.get(Preferences.OneResult, False) results = [] never_or = "false" if or_search else "true" stats.made_search(user_id) search_result = rdio.call("search", {"query": " ".join([artist, title]), "types": "Track", "never_or": never_or}) name_artist_pairs_found = {} for possible_hit in search_result["result"]["results"]: if possible_hit["canStream"]: name = possible_hit["name"] artist_name = possible_hit["artist"] if name_artist_pairs_found.has_key((name, artist_name)): continue name_artist_pairs_found[(name, artist_name)] = True results.append((name, artist_name, possible_hit["shortUrl"], possible_hit["key"])) if one_result: break return results
def GET(self): rdio, currentUser, user_id = get_rdio_and_current_user() if rdio and currentUser: if user_id in config.ADMIN_USERS: input = get_input() if 'button' in input.keys(): action = input['button'] db = get_db() if action == 'doitnow_go_on_killme': if user_id in config.ADMIN_USERS: db.delete(USER_TABLE, where="rdio_user_id=%i" % user_id) raise web.seeother('/') elif action == 'clear_preferences': if user_id in config.ADMIN_USERS: db.update(USER_TABLE, where="rdio_user_id=%i" % user_id, prefs=BSONPostgresSerializer.from_dict({})) raise web.seeother('/admin') else: admin=get_admin_content() return render.admin(env_message=get_environment_message(), admin=admin) raise web.seeother('/')
def GET(self): rdio, currentUser = get_rdio_and_current_user() if rdio and currentUser: user_id = int(currentUser['key'][1:]) myPlaylists = rdio.call('getPlaylists')['result']['owned'] db = get_db() result = list(db.select('discoversong_user', what='address, playlist', where="rdio_user_id=%i" % user_id)) if len(result) == 0: access_token = web.cookies().get('at') access_token_secret = web.cookies().get('ats') db.insert('discoversong_user', rdio_user_id=user_id, address=make_unique_email(currentUser), token=access_token, secret=access_token_secret, playlist='new') result = list(db.select('discoversong_user', what='address, playlist', where="rdio_user_id=%i" % user_id))[0] else: result = result[0] message = '' if 'saved' in get_input(): message = ' Saved your selections.' return render.loggedin(name=currentUser['firstName'], message=message, to_address=result['address'], editform=editform(myPlaylists, result['playlist']) ) else: return render.loggedout()
def get_discoversong_user(user_id): assert user_id is not None db = get_db() disco_user = list(db.select(USER_TABLE, where="rdio_user_id=%i" % user_id)) if len(disco_user) == 0: access_token = web.cookies().get('at') access_token_secret = web.cookies().get('ats') db.insert(USER_TABLE, rdio_user_id=user_id, address=make_unique_email(), token=access_token, secret=access_token_secret, first_use=datetime.date.today(), last_use=datetime.date.today(), emails=0, searches=0, songs=0, prefs=BSONPostgresSerializer.from_dict({})) disco_user = list(db.select(USER_TABLE, where="rdio_user_id=%i" % user_id))[0] count = int(list(db.query("SELECT count(*) from %s" % USER_TABLE))[0]['count']) announce_new_user(count) else: disco_user = disco_user[0] def none_or_empty(strg): return strg is None or strg == '' def fields_need_update(field_names): for field in field_names: if not disco_user.has_key(field): return True if none_or_empty(disco_user[field]): return True return False if fields_need_update(['token', 'secret', 'address', 'prefs']): if fields_need_update(['token', 'secret']): access_token = web.cookies().get('at') access_token_secret = web.cookies().get('ats') db.update(USER_TABLE, where="rdio_user_id=%i" % user_id, secret=access_token_secret, token=access_token) if fields_need_update(['address']): db.update(USER_TABLE, where="rdio_user_id=%i" % user_id, address=make_unique_email()) if fields_need_update(['prefs']): db.update(USER_TABLE, where="rdio_user_id=%i" % user_id, prefs=BSONPostgresSerializer.from_dict({})) disco_user = list(db.select(USER_TABLE, where="rdio_user_id=%i" % user_id))[0] if not disco_user.has_key('prefs') or not disco_user['prefs']: logging.info('resetting preferences') db.update(USER_TABLE, where="rdio_user_id=%i" % user_id, prefs=BSONPostgresSerializer.from_dict({})) disco_user = list(db.select(USER_TABLE, where="rdio_user_id=%i" % user_id))[0] return disco_user, BSONPostgresSerializer.to_dict(disco_user['prefs'])
def GET(self): svc, current_user, user_id = get_rdio_and_current_user() if svc and current_user: if user_id in config.ADMIN_USERS: db = get_db() db_users = db.select(USER_TABLE, what='*') return render.admin_users(env_message=get_environment_message(), users=db_users) raise web.seeother('/')
def return_results(rdio, user_id, song_artist_url_list, from_tweet_id=None): db = get_db() prefs = get_db_prefs(user_id, db=db) playlist_key = prefs.get(Preferences.PlaylistToSaveTo, "new") add_to_collection = prefs.get(Preferences.AddToCollection, False) track_keys_list = [s[3] for s in song_artist_url_list] playlists_call = rdio.call("getPlaylists") if "result" in playlists_call: playlists = playlists_call["result"]["owned"] else: playlists = [] p_keys = [playlist["key"] for playlist in playlists] p_names = [playlist["name"] for playlist in playlists] if playlist_key in ["new", "alwaysnew"] or playlist_key not in p_keys: new_name = generate_playlist_name(p_names) result = rdio.call( "createPlaylist", { "name": new_name, "description": "Songs found by discoversong on %s." % datetime.datetime.now().strftime("%A, %d %b %Y %H:%M"), "tracks": ", ".join(track_keys_list), }, ) new_key = result["result"]["key"] if playlist_key == "new" or playlist_key not in p_keys: prefs[Preferences.PlaylistToSaveTo] = new_key db.update(USER_TABLE, where="rdio_user_id=%i" % user_id, prefs=BSONPostgresSerializer.from_dict(prefs)) # else leave 'alwaysnew' to repeat this behavior every time else: rdio.call("addToPlaylist", {"playlist": playlist_key, "tracks": ", ".join(track_keys_list)}) if add_to_collection: rdio.call("addToCollection", {"keys": ", ".join(track_keys_list)}) stats.found_songs(user_id, len(song_artist_url_list)) twitter_name_config = Capabilities.Twitter().config_options_dict()["twitter_name"] user, message = get_discoversong_user(user_id) twitter_name = "@" + twitter_name_config.get_value(user) reply_to_tweet_id = from_tweet_id song, artist, url, track_key = song_artist_url_list[0] try: tweet_about_found_song(song, artist, url, mention_name=twitter_name, reply_to_tweet_id=reply_to_tweet_id) except twython.TwythonError as twe: if twe.error_code == 403: pass
def GET(self): input = get_input() action = input['button'] rdio, currentUser = get_rdio_and_current_user() user_id = int(currentUser['key'][1:]) db = get_db() if action == 'save': db.update('discoversong_user', where="rdio_user_id=%i" % user_id, playlist=input['playlist']) raise web.seeother('/?saved=True')
def return_results(rdio, user_id, song_artist_url_list, from_tweet_id=None): db = get_db() prefs = get_db_prefs(user_id, db=db) playlist_key = prefs.get(Preferences.PlaylistToSaveTo, 'new') add_to_collection = prefs.get(Preferences.AddToCollection, False) track_keys_list = [s[3] for s in song_artist_url_list] playlists_call = rdio.call('getPlaylists') if 'result' in playlists_call: playlists = playlists_call['result']['owned'] else: playlists = [] p_keys = [playlist['key'] for playlist in playlists] p_names = [playlist['name'] for playlist in playlists] if playlist_key in ['new', 'alwaysnew'] or playlist_key not in p_keys: new_name = generate_playlist_name(p_names) result = rdio.call('createPlaylist', {'name': new_name, 'description': 'Songs found by discoversong on %s.' % datetime.datetime.now().strftime('%A, %d %b %Y %H:%M'), 'tracks': ', '.join(track_keys_list)}) new_key = result['result']['key'] if playlist_key == 'new' or playlist_key not in p_keys: prefs[Preferences.PlaylistToSaveTo] = new_key db.update(USER_TABLE, where="rdio_user_id=%i" % user_id, prefs=BSONPostgresSerializer.from_dict(prefs)) # else leave 'alwaysnew' to repeat this behavior every time else: rdio.call('addToPlaylist', {'playlist': playlist_key, 'tracks': ', '.join(track_keys_list)}) if add_to_collection: rdio.call('addToCollection', {'keys': ', '.join(track_keys_list)}) stats.found_songs(user_id, len(song_artist_url_list)) twitter_name_config = Capabilities.Twitter().config_options_dict()['twitter_name'] user, message = get_discoversong_user(user_id) twitter_name = '@' + twitter_name_config.get_value(user) reply_to_tweet_id = from_tweet_id song, artist, url, track_key = song_artist_url_list[0] try: tweet_about_found_song(song, artist, url, mention_name=twitter_name, reply_to_tweet_id=reply_to_tweet_id) except twython.TwythonError as twe: if twe.error_code == 403: pass
def get_admin_content(): fields = tuple() db = get_db() user_count = db.select(USER_TABLE, what='count(*)')[0]['count'] stats = db.select(STATS_TABLE, what='emails, searches, songs, visits')[0] fields += (Label(name='', description='ADMIN'),) fields += (Label(name='', description='User Count: %i' % user_count),) fields += (form.Button(name='button', value='clear_preferences', html='clear my preferences'),) fields += (form.Button(name='button', value='doitnow_go_on_killme', html='delete my user row'),) fields += (Label(name='', description='Visits: %i' % stats['visits']),) fields += (Label(name='', description='Emails: %i' % stats['emails']),) fields += (Label(name='', description='Searches: %i' % stats['searches']),) fields += (Label(name='', description='Songs: %i' % stats['songs']),) adminform = form.Form(*fields) return adminform()
def found_songs(user_id, songs): db = get_db() t = db.transaction() db.query('UPDATE %s SET songs = songs + %i WHERE rdio_user_id = %i' % (USER_TABLE, songs, user_id)) db.query('UPDATE %s SET songs = songs + %i' % (STATS_TABLE, songs)) t.commit()
def made_search(user_id): db = get_db() t = db.transaction() db.query('UPDATE %s SET searches = searches + 1 WHERE rdio_user_id = %i' % (USER_TABLE, user_id)) db.query('UPDATE %s SET searches = searches + 1' % STATS_TABLE) t.commit()
def got_email(user_id): db = get_db() t = db.transaction() db.query('UPDATE %s SET emails = emails + 1, last_use = current_date WHERE rdio_user_id = %i' % (USER_TABLE, user_id)) db.query('UPDATE %s SET emails = emails + 1' % STATS_TABLE) t.commit()
def get_db_prefs(user_id, db=None): if db is None: db = get_db() prefs = BSONPostgresSerializer.to_dict(list(db.select(USER_TABLE, what='prefs', where="rdio_user_id=%i" % user_id))[0]['prefs']) return prefs
def get_discoversong_user_by_twitter(twitter_name): db = get_db() disco_users = list(db.select(USER_TABLE, where="twitter_name='%s'" % twitter_name)) if len(disco_users) > 0: return disco_users[0] return None
def visited(user_id): db = get_db() t = db.transaction() db.query('UPDATE %s SET last_use = current_date WHERE rdio_user_id = %i' % (USER_TABLE, user_id)) db.query('UPDATE %s SET visits = visits + 1' % STATS_TABLE) t.commit()
def get_last_mention(): return get_db().select(STATS_TABLE, what='last_read_mention')[0]['last_read_mention']
def read_to_mention(last_mention): db = get_db() db.query('UPDATE %s SET last_read_mention = %s' % (STATS_TABLE, last_mention))
def POST(self): db = get_db() input = get_input() envelope = json.loads(input['envelope']) to_addresses = envelope['to'] print 'received email to', to_addresses for to_address in to_addresses: lookup = db.select('discoversong_user', what='rdio_user_id, playlist, token, secret', where="address='%s'" % to_address) if len(lookup) == 1: result = lookup[0] access_token = str(result['token']) access_token_secret = str(result['secret']) rdio, current_user = get_rdio_and_current_user(access_token=access_token, access_token_secret=access_token_secret) print 'found user', current_user['username'] subject = input['subject'] title, artist = parse(subject) print 'parsed artist', artist, 'title', title search_result = rdio.call('search', {'query': ' '.join([title, artist]), 'types': 'Track'}) track_keys = [] name_artist_pairs_found = {} for possible_hit in search_result['result']['results']: if possible_hit['canStream']: name = possible_hit['name'] artist_name = possible_hit['artist'] if name_artist_pairs_found.has_key((name, artist_name)): continue name_artist_pairs_found[(name, artist_name)] = True track_key = possible_hit['key'] track_keys.append(track_key) print 'found tracks', track_keys playlist_key = result['playlist'] if playlist_key in ['new', 'alwaysnew']: p_names = [playlist['name'] for playlist in rdio.call('getPlaylists')['result']['owned']] new_name = generate_playlist_name(p_names) print 'creating new playlist', new_name result = rdio.call('createPlaylist', {'name': new_name, 'description': 'Songs found by discoversong on %s.' % datetime.datetime.now().strftime('%A, %d %b %Y %H:%M'), 'tracks': ', '.join(track_keys)}) new_key = result['result']['key'] if playlist_key == 'new': print 'setting', new_key, 'as the playlist to use next time' user_id = int(current_user['key'][1:]) db.update('discoversong_user', where="rdio_user_id=%i" % user_id, playlist=new_key) # else leave 'alwaysnew' to repeat this behavior every time else: rdio.call('addToPlaylist', {'playlist': playlist_key, 'tracks': ', '.join(track_keys)}) return None