Beispiel #1
0
  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('/')
Beispiel #2
0
  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)
Beispiel #3
0
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
Beispiel #4
0
 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
Beispiel #6
0
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
Beispiel #7
0
  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('/')
Beispiel #8
0
 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()
Beispiel #9
0
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'])
Beispiel #10
0
 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('/')
Beispiel #11
0
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
Beispiel #12
0
 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
Beispiel #14
0
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()
Beispiel #15
0
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()
Beispiel #16
0
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()
Beispiel #17
0
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()
Beispiel #18
0
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
Beispiel #19
0
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
Beispiel #20
0
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()
Beispiel #21
0
def get_last_mention():
  return get_db().select(STATS_TABLE, what='last_read_mention')[0]['last_read_mention']
Beispiel #22
0
def read_to_mention(last_mention):
  db = get_db()
  db.query('UPDATE %s SET last_read_mention = %s' % (STATS_TABLE, last_mention))
Beispiel #23
0
  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