def get(self): self.write( self.render_string("bare_header.html", title="Adding Groups")) self.write("<h2>Associating Groups</h2>") self.write("<h3>These Songs:</h3><ul>") songs = cache.get_user(self.user, "admin_associate_groups_songs") or [] for song_id in songs: song = Song.load_from_id(song_id) self.write("<li>%s</li>" % song.data['title']) self.write("</ul><h3>Songs In These Albums:</h3><ul>") albums = cache.get_user(self.user, "admin_associate_groups_albums") or [] for album_set in albums: album = Album.load_from_id(album_set[0]) self.write( "<li>%s (%s)</li>" % (album.data['name'], config.station_id_friendly[album_set[1]])) self.write("</ul><select id='associate_group_id'>") for row in db.c.fetch_all( "SELECT group_id, group_name FROM r4_groups ORDER BY group_name" ): self.write("<option value='%s'>%s</option>" % (row['group_id'], row['group_name'])) self.write("</select><br />") self.write( "<button onclick=\"window.location.href='/admin/tools/associate_groups_finish/' + document.getElementById('associate_group_id').value\">Associate</button>" ) self.write( "<br /><br /><a href='/admin/tools/associate_groups_cache_reset'>Reset the list above.</a>" ) self.write(self.render_string("basic_footer.html"))
def get(self, group_id): group = SongGroup.load_from_id(group_id) songs = cache.get_user(self.user, "admin_associate_groups_songs") or [] cache.set_user(self.user, "admin_associate_groups_songs", []) for song_id in songs: group.associate_song_id(song_id) albums = cache.get_user(self.user, "admin_associate_groups_albums") or [] cache.set_user(self.user, "admin_associate_groups_albums", []) for album_set in albums: album = Album.load_from_id_with_songs(album_set[0], album_set[1]) for song in album.data['songs']: group.associate_song_id(song['id']) self.write(self.render_string("bare_header.html", title="Added Groups")) self.write("<p>Now associated.</p><p><a href='/admin/tools/associate_groups'>Start over.</a></p>") self.write(self.render_string("basic_footer.html"))
def get(self, group_id): #pylint: disable=W0221 group = SongGroup.load_from_id(group_id) songs = cache.get_user(self.user, "admin_associate_groups_songs") or [] cache.set_user(self.user, "admin_associate_groups_songs", []) for song_id in songs: group.associate_song_id(song_id) albums = cache.get_user(self.user, "admin_associate_groups_albums") or [] cache.set_user(self.user, "admin_associate_groups_albums", []) for album_set in albums: album = Album.load_from_id_with_songs(album_set[0], album_set[1]) for song in album.data['songs']: group.associate_song_id(song['id']) self.write(self.render_string("bare_header.html", title="Added Groups")) self.write("<p>Now associated.</p><p><a href='/admin/tools/associate_groups'>Start over.</a></p>") self.write(self.render_string("basic_footer.html"))
def post(self): albums = cache.get_user(self.user, "admin_associate_groups_albums") if not albums: albums = [] albums.append((self.get_argument("album_id"), self.get_argument("album_sid"))) cache.set_user(self.user, "admin_associate_groups_albums", albums) self.append_standard("album_added")
def post(self): songs = cache.get_user(self.user, "admin_associate_groups_songs") if not songs: songs = [] songs.append(self.get_argument("song_id")) cache.set_user(self.user, "admin_associate_groups_songs", songs) self.append_standard("song_added")
def get_requests(self, refresh = False): if self.id <= 1: return [] requests = cache.get_user(self, "requests") if refresh or (not requests or len(requests) == 0): line_sid = self.get_request_line_sid() requests = db.c.fetch_all( "SELECT r4_request_store.song_id AS id, r4_request_store.reqstor_order AS order, r4_request_store.reqstor_id AS request_id, " "song_rating AS rating, song_title AS title, song_length AS length, r4_song_sid.song_cool AS cool, r4_song_sid.song_cool_end AS cool_end, " "r4_song_sid.song_elec_blocked AS elec_blocked, r4_song_sid.song_elec_blocked_by AS elec_blocked_by, " "r4_song_sid.song_elec_blocked_num AS elec_blocked_num, r4_song_sid.song_exists AS valid, " "r4_song_sid.album_id AS album_id, r4_albums.album_name " "FROM r4_request_store " "JOIN r4_songs USING (song_id) " "LEFT JOIN r4_song_sid ON (r4_song_sid.sid = %s AND r4_songs.song_id = r4_song_sid.song_id) " "LEFT JOIN r4_song_ratings ON (r4_request_store.song_id = r4_song_ratings.song_id) " "JOIN r4_albums ON (r4_song_sid.album_id = r4_albums.album_id) " "WHERE r4_request_store.user_id = %s " "ORDER BY reqstor_order, reqstor_id", (line_sid, self.id)) if not requests: requests = [] for song in requests: if not song['album_name']: song['albums'] = [ { "id": song['album_id'], "name": db.c.fetch_var("SELECT album_name FROM r4_albums WHERE album_id = %s", (song['album_id'],)) } ] else: song['albums'] = [ { "name": song['album_name'], "id": song['album_id'] } ] song.pop('album_name', None) song.pop('album_id', None) cache.set_user(self, "requests", requests) return requests
def get(self): self.write( self.render_string("bare_header.html", title="%s One Up Tool" % config.station_id_friendly[self.sid]) ) self.write("<script>\nwindow.top.refresh_all_screens = false;\n</script>") self.write("<h2>%s DJ Election Tool</h2>" % config.station_id_friendly[self.sid]) self.write("<ul><li>Once committed, the election cannot be changed.</li>") self.write( "<li>Pulling songs from other stations is possible and will not affect cooldown on the other station. (it will affect voting stats)" ) self.write("<li>Song order in elections is randomized for each user.</li>") self.write("</ul><hr>") songs = cache.get_user(self.user.id, "dj_election") if not songs: self.write("<p>No election started yet.</p>") else: self.write("<ul>") for song in songs: self.write( "<li>%s<br>%s<br><a onclick=\"window.top.call_api('admin/remove_from_dj_election', { 'song_id': %s });\">Remove</a></li>" % (song.data["title"], song.albums[0].data["name"], song.id) ) self.write("</ul>") self.write("<a onclick=\"window.top.call_api('admin/commit_dj_election');\">Commit to Queue</a>") self.write(self.render_string("basic_footer.html"))
def post(self): songs = cache.get_user(self.user.id, self.return_name) if not songs: raise APIException("no_dj_election", "No songs found queued for a DJ election.") for song in songs: if song.id == self.get_argument("song_id"): songs.remove(song) cache.set_user(self.user.id, self.return_name, songs) self.append(self.return_name, { "success": True })
def post(self): songs = cache.get_user(self.user.id, self.return_name) if songs: to_output = [] for song in songs: to_output.append(song.to_dict()) self.append(self.return_name, to_output) else: self.append(self.return_name, [])
def post(self): songs = cache.get_user(self.user.id, "dj_election") if not songs: raise APIException("no_dj_election", "No songs found queued for a DJ election.") elec = events.election.Election.create(self.sid) for song in songs: elec.add_song(song) cache.set_user(self.user.id, "dj_election", None) self.append(self.return_name, { "success": True })
def post(self): songs = cache.get_user(self.user.id, "dj_election") if not songs: raise APIException("no_dj_election", "No songs found queued for a DJ election.") elec = events.election.Election.create(self.sid) for song in songs: elec.add_song(song) cache.set_user(self.user.id, "dj_election", None) self.append(self.return_name, {"success": True})
def post(self): songs = cache.get_user(self.user.id, self.return_name) if not songs: songs = [] songs.append(playlist.Song.load_from_id(self.get_argument("song_id"), self.get_argument("song_sid"))) cache.set_user(self.user.id, self.return_name, songs) to_output = [] for song in songs: to_output.append(song.to_dict()) self.append(self.return_name, to_output)
def get(self): self.write(self.render_string("bare_header.html", title="Adding Groups")) self.write("<h2>Associating Groups</h2>") self.write("<h3>These Songs:</h3><ul>") songs = cache.get_user(self.user, "admin_associate_groups_songs") or [] for song_id in songs: song = Song.load_from_id(song_id) self.write("<li>%s</li>" % song.data['title']) self.write("</ul><h3>Songs In These Albums:</h3><ul>") albums = cache.get_user(self.user, "admin_associate_groups_albums") or [] for album_set in albums: album = Album.load_from_id(album_set[0]) self.write("<li>%s (%s)</li>" % (album.data['name'], config.station_id_friendly[album_set[1]])) self.write("</ul><select id='associate_group_id'>") for row in db.c.fetch_all("SELECT group_id, group_name FROM r4_groups ORDER BY group_name"): self.write("<option value='%s'>%s</option>" % (row['group_id'], row['group_name'])) self.write("</select><br />") self.write("<button onclick=\"window.location.href='/admin/tools/associate_groups_finish/' + document.getElementById('associate_group_id').value\">Associate</button>") self.write("<br /><br /><a href='/admin/tools/associate_groups_cache_reset'>Reset the list above.</a>") self.write(self.render_string("basic_footer.html"))
def post(self): songs = cache.get_user(self.user.id, "dj_election") if not songs: raise APIException("no_dj_election", "No songs found queued for a DJ election.") if self.get_argument("sched_id", None) and not self.user.is_admin: if not self.user.id == db.c.fetch_var("SELECT sched_dj_user_id FROM r4_schedule WHERE sched_id = %s", (self.get_argument("sched_id"),)): raise APIException("auth_required", http_code=403) elec = events.election.Election.create(self.sid, self.get_argument("sched_id")) for song in songs: elec.add_song(song) cache.set_user(self.user.id, "dj_election", None) self.append(self.return_name, { "success": True })
def _auth_registered_user(self, ip_address, api_key, bypass=False): if not bypass: keys = cache.get_user(self, "api_keys") if not keys: if not api_key in self._get_all_api_keys(): log.debug( "auth", "Invalid user ID %s and/or API key %s." % (self.id, api_key)) return elif not api_key in keys: log.debug( "auth", "Invalid user ID %s and/or API key %s from cache." % (self.id, api_key)) return # Set as authorized and begin populating information # Pay attention to the "AS _variable" names in the SQL fields, they won't get exported to private JSONable dict self.authorized = True user_data = None if not user_data: user_data = db.c_old.fetch_row( "SELECT user_id, username, user_new_privmsg, user_avatar, user_avatar_type AS _user_avatar_type, radio_listenkey AS radio_listen_key, group_id AS _group_id, radio_totalratings AS _total_ratings " "FROM phpbb_users WHERE user_id = %s", (self.id, )) self.data.update(user_data) if self.data['_user_avatar_type'] == 1: self.data['user_avatar'] = _AVATAR_PATH % self.data['user_avatar'] elif self.data['_user_avatar_type'] > 0: pass else: self.data['user_avatar'] = "images/blank.png" # Privileged folk - donors, admins, etc - get perks. # The numbers are the phpBB group IDs. if self.data['_group_id'] in (5, 4, 8, 12, 15, 14, 17): self.data['radio_perks'] = True #elif config.get("developer_mode"): # self.data['radio_perks'] = True # Admin and station manager groups if self.data['_group_id'] in (5, 12, 15, 14, 17): self.data['radio_admin'] = True # jfinalfunk is a special case since he floats around outside the main admin groups elif self.id == 9575: self.data['radio_admin'] = True if self.data['_total_ratings'] > config.get( "rating_allow_all_threshold"): self.data['radio_rate_anything'] = True if not self.data['radio_listen_key']: self.generate_listen_key()
def attach_info_to_request(request, playlist = False, artists = False): # Front-load all non-animated content ahead of the schedule content # Since the schedule content is the most animated on R3, setting this content to load # first has a good impact on the perceived animation smoothness since table redrawing # doesn't have to take place during the first few frames. if request.user: request.append("user", request.user.to_private_dict()) if playlist or 'all_albums' in request.request.arguments: request.append("all_albums", api_requests.playlist.get_all_albums(request.sid, request.user)) else: request.append("album_diff", cache.get_station(request.sid, 'album_diff')) if artists or 'all_artists' in request.request.arguments: request.append("all_artists", cache.get_station(request.sid, 'all_artists')) request.append("request_line", cache.get_station(request.sid, "request_line")) # request.append("calendar", cache.get("calendar")) request.append("listeners_current", cache.get_station(request.sid, "listeners_current")) sched_next = [] sched_history = [] sched_current = {} if request.user: request.append("requests", request.user.get_requests()) sched_current = cache.get_station(request.sid, "sched_current") if request.user.is_tunedin(): sched_current.get_song().data['rating_allowed'] = True sched_current = sched_current.to_dict(request.user) for evt in cache.get_station(request.sid, "sched_next"): sched_next.append(evt.to_dict(request.user)) for evt in cache.get_station(request.sid, "sched_history"): sched_history.append(evt.to_dict(request.user, check_rating_acl=True)) else: sched_current = cache.get_station(request.sid, "sched_current_dict") sched_next = cache.get_station(request.sid, "sched_next_dict") sched_history = cache.get_station(request.sid, "sched_history_dict") request.append("sched_current", sched_current) request.append("sched_next", sched_next) request.append("sched_history", sched_history) if request.user: if not request.user.is_anonymous(): user_vote_cache = cache.get_user(request.user, "vote_history") temp_current = list() temp_current.append(sched_current) if user_vote_cache: for history in user_vote_cache: for event in (sched_history + sched_next + temp_current): if history[0] == event['id']: api_requests.vote.append_success_to_request(request, event['id'], history[1]) elif request.user.data['listener_voted_entry'] > 0 and request.user.data['listener_lock_sid'] == request.sid: api_requests.vote.append_success_to_request(request, sched_next[0].id, request.user.data['listener_voted_entry'])
def _auth_registered_user(self, api_key, bypass=False): if not bypass: keys = cache.get_user(self, "api_keys") if keys and api_key in keys: pass elif not api_key in self.get_all_api_keys(): log.debug( "auth", "Invalid user ID %s and/or API key %s." % (self.id, api_key)) return # Set as authorized and begin populating information # Pay attention to the "AS _variable" names in the SQL fields, they won't get exported to private JSONable dict self.authorized = True user_data = None if not user_data: user_data = db.c.fetch_row( "SELECT user_id AS id, COALESCE(radio_username, username) AS name, user_avatar AS avatar, radio_requests_paused AS requests_paused, " "user_avatar_type AS _avatar_type, radio_listenkey AS listen_key, group_id AS _group_id, radio_totalratings AS _total_ratings, discord_user_id AS _discord_user_id " "FROM phpbb_users WHERE user_id = %s", (self.id, ), ) self.data.update(user_data) self.data["avatar"] = solve_avatar(self.data["_avatar_type"], self.data["avatar"]) self.data.pop("_avatar_type") # Privileged folk - donors, admins, etc - get perks. # The numbers are the phpBB group IDs. if self.data["_group_id"] in (5, 4, 8, 18): self.data["perks"] = True # Admin and station manager groups if self.data["_group_id"] in (5, 18): self.data["admin"] = True self.data.pop("_group_id") if self.data["perks"]: self.data["rate_anything"] = True elif self.data["_total_ratings"] > config.get( "rating_allow_all_threshold"): self.data["rate_anything"] = True self.data.pop("_total_ratings") if not self.data["listen_key"]: self.generate_listen_key() self.data[ "uses_oauth"] = True if self.data["_discord_user_id"] else False self.data.pop("_discord_user_id")
def _auth_registered_user(self, ip_address, api_key, bypass=False): if not bypass: keys = cache.get_user(self, "api_keys") if not keys: if not api_key in self.get_all_api_keys(): log.debug( "auth", "Invalid user ID %s and/or API key %s." % (self.id, api_key)) return elif not api_key in keys: log.debug( "auth", "Invalid user ID %s and/or API key %s (from cache)." % (self.id, api_key)) return # Set as authorized and begin populating information # Pay attention to the "AS _variable" names in the SQL fields, they won't get exported to private JSONable dict self.authorized = True user_data = None if not user_data: user_data = db.c.fetch_row( "SELECT user_id AS id, username AS name, user_new_privmsg AS new_privmsg, user_avatar AS avatar, radio_requests_paused AS requests_paused, " "user_avatar_type AS _avatar_type, radio_listenkey AS listen_key, group_id AS _group_id, radio_totalratings AS _total_ratings " "FROM phpbb_users WHERE user_id = %s", (self.id, )) self.data.update(user_data) self.data['avatar'] = solve_avatar(self.data['_avatar_type'], self.data['avatar']) self.data.pop("_avatar_type") # Privileged folk - donors, admins, etc - get perks. # The numbers are the phpBB group IDs. if self.data['_group_id'] in (5, 4, 8, 18): self.data['perks'] = True # Admin and station manager groups if self.data['_group_id'] in (5, 18): self.data['admin'] = True self.data.pop("_group_id") if self.data['perks']: self.data['rate_anything'] = True elif self.data['_total_ratings'] > config.get( "rating_allow_all_threshold"): self.data['rate_anything'] = True self.data.pop("_total_ratings") if not self.data['listen_key']: self.generate_listen_key()
def _auth_registered_user(self, ip_address, api_key, bypass = False): if not bypass: # TODO: Users can have multiple keys, should we cache them all? key = cache.get_user(self, "api_key") if not key: key = db.c.fetch_row("SELECT api_key, api_is_rainwave FROM r4_api_keys WHERE user_id = %s AND api_key = %s", (self.id, api_key)) if not key: log.debug("auth", "Invalid user ID %s and/or API key %s." % (self.id, api_key)) return cache.set_user(self, "api_key", key) if key['api_key'] != api_key: log.debug("auth", "Invalid user ID %s and/or API key %s from cache." % (self.id, api_key)) return if key['api_is_rainwave']: self._official_ui = True # Set as authorized and begin populating information # Pay attention to the "AS _variable" names in the SQL fields, they won't get exported to private JSONable dict self.authorized = True user_data = None # user_data = cache.get_user(self, "db_data") if not user_data: user_data = db.c_old.fetch_row("SELECT user_id, username, user_new_privmsg, user_avatar, user_avatar_type AS _user_avatar_type, radio_listenkey AS radio_listen_key, group_id AS _group_id " "FROM phpbb_users WHERE user_id = %s", (self.id,)) cache.set_user(self, "db_data", user_data) self.data.update(user_data) if self.data['_user_avatar_type'] == 1: self.data['user_avatar'] = _AVATAR_PATH % self.data['user_avatar'] elif self.data['_user_avatar_type'] > 0: pass else: self.data['user_avatar'] = "images/blank.png" # Privileged folk - donors, admins, etc - get perks. # The numbers are the phpBB group IDs. if self.data['_group_id'] in [5, 4, 8, 12, 15, 14, 17]: self.data['radio_perks'] = True # Admin and station manager groups if self.data['_group_id'] in [5, 12, 15, 14, 17]: self.data['radio_admin'] = True # jfinalfunk is a special case since he floats around outside the main admin groups elif self.id == 9575: self.data['radio_admin'] = True if not self.data['radio_listen_key']: self.generate_listen_key()
def _auth_registered_user(self, ip_address, api_key, bypass = False): if not bypass: keys = cache.get_user(self, "api_keys") if not keys: if not api_key in self._get_all_api_keys(): log.debug("auth", "Invalid user ID %s and/or API key %s." % (self.id, api_key)) return elif not api_key in keys: log.debug("auth", "Invalid user ID %s and/or API key %s from cache." % (self.id, api_key)) return # Set as authorized and begin populating information # Pay attention to the "AS _variable" names in the SQL fields, they won't get exported to private JSONable dict self.authorized = True user_data = None if not user_data: user_data = db.c_old.fetch_row("SELECT user_id, username, user_new_privmsg, user_avatar, user_avatar_type AS _user_avatar_type, radio_listenkey AS radio_listen_key, group_id AS _group_id, radio_totalratings AS _total_ratings " "FROM phpbb_users WHERE user_id = %s", (self.id,)) self.data.update(user_data) if self.data['_user_avatar_type'] == 1: self.data['user_avatar'] = _AVATAR_PATH % self.data['user_avatar'] elif self.data['_user_avatar_type'] > 0: pass else: self.data['user_avatar'] = "images/blank.png" # Privileged folk - donors, admins, etc - get perks. # The numbers are the phpBB group IDs. if self.data['_group_id'] in (5, 4, 8, 12, 15, 14, 17): self.data['radio_perks'] = True #elif config.get("developer_mode"): # self.data['radio_perks'] = True # Admin and station manager groups if self.data['_group_id'] in (5, 12, 15, 14, 17): self.data['radio_admin'] = True # jfinalfunk is a special case since he floats around outside the main admin groups elif self.id == 9575: self.data['radio_admin'] = True if self.data['_total_ratings'] > config.get("rating_allow_all_threshold"): self.data['radio_rate_anything'] = True if not self.data['radio_listen_key']: self.generate_listen_key()
def _auth_registered_user(self, api_key, bypass = False): if not bypass: keys = cache.get_user(self, "api_keys") if not keys: if not api_key in self.get_all_api_keys(): log.debug("auth", "Invalid user ID %s and/or API key %s." % (self.id, api_key)) return elif not api_key in keys: log.debug("auth", "Invalid user ID %s and/or API key %s (from cache)." % (self.id, api_key)) return # Set as authorized and begin populating information # Pay attention to the "AS _variable" names in the SQL fields, they won't get exported to private JSONable dict self.authorized = True user_data = None if not user_data: user_data = db.c.fetch_row( "SELECT user_id AS id, username AS name, user_new_privmsg AS new_privmsg, user_avatar AS avatar, radio_requests_paused AS requests_paused, " "user_avatar_type AS _avatar_type, radio_listenkey AS listen_key, group_id AS _group_id, radio_totalratings AS _total_ratings " "FROM phpbb_users WHERE user_id = %s", (self.id,) ) self.data.update(user_data) self.data['avatar'] = solve_avatar(self.data['_avatar_type'], self.data['avatar']) self.data.pop("_avatar_type") # Privileged folk - donors, admins, etc - get perks. # The numbers are the phpBB group IDs. if self.data['_group_id'] in (5, 4, 8, 18): self.data['perks'] = True # Admin and station manager groups if self.data['_group_id'] in (5, 18): self.data['admin'] = True self.data.pop("_group_id") if self.data['perks']: self.data['rate_anything'] = True elif self.data['_total_ratings'] > config.get("rating_allow_all_threshold"): self.data['rate_anything'] = True self.data.pop("_total_ratings") if not self.data['listen_key']: self.generate_listen_key()
def get_listener_record(self, use_cache=True): listener = None if self.id > 1: listener = cache.get_user(self.id, "listener_record") if not listener or not use_cache: listener = db.c.fetch_row("SELECT " "listener_id, sid, listener_lock AS lock, listener_lock_sid AS lock_sid, listener_lock_counter AS lock_counter, listener_voted_entry AS voted_entry " "FROM r4_listeners " "WHERE user_id = %s AND listener_purge = FALSE", (self.id,)) else: listener = db.c.fetch_row("SELECT " "listener_id, sid, listener_lock AS lock, listener_lock_sid AS lock_sid, listener_lock_counter AS lock_counter, listener_voted_entry AS voted_entry " "FROM r4_listeners " "WHERE listener_ip = %s AND listener_purge = FALSE", (self.ip_address,)) if listener: self.data.update(listener) if self.id > 1: cache.set_user(self.id, "listener_record", listener) return listener
def get(self): self.write(self.render_string("bare_header.html", title="%s DJ Election Tool" % config.station_id_friendly[self.sid])) self.write("<script>\nwindow.top.refresh_all_screens = true;\n</script>") if self.get_argument("sched_id", None): self.write("<h2>%s Elections" % (db.c.fetch_var("SELECT sched_name FROM r4_schedule WHERE sched_id = %s", (self.get_argument("sched_id"),)))) self.write(" (%s)</h2>" % config.station_id_friendly[db.c.fetch_var("SELECT sid FROM r4_schedule WHERE sched_id = %s", (self.get_argument("sched_id"),))]) else: self.write("<h2>%s DJ Election Tool</h2>" % config.station_id_friendly[self.sid]) self.write("<ul><li>Once committed, the election cannot be edited.</li>") self.write("<li>Pulling songs from other stations is possible and will not affect cooldown on the other station. (it will affect voting stats on other stations)") self.write("<li>Song order in elections is randomized for each user - do not rely on the order.</li>") self.write("<li>Putting in 1 song will disable voting on the election.</li>") self.write("</ul><hr>") songs = cache.get_user(self.user.id, "dj_election") if not songs: self.write("<p>No election started yet.</p>") else: self.write("<ul>") for song in songs: self.write("<li>%s<br>%s<br><a onclick=\"window.top.call_api('admin/remove_from_dj_election', { 'song_id': %s });\">Remove</a></li>" % (song.data['title'], song.albums[0].data['name'], song.id)) self.write("</ul>") if not self.get_argument("sched_id", None): self.write("<a onclick=\"window.top.call_api('admin/commit_dj_election');\">Commit to Queue</a>") else: self.write("<a onclick=\"window.top.call_api('admin/commit_dj_election?sched_id=%s');\">Add to DJ Block</a>" % (self.get_argument("sched_id"),)) if self.get_argument("sched_id", None): self.write("<hr>") has_elections = False for election_id in db.c.fetch_list("SELECT elec_id FROM r4_elections WHERE sched_id = %s AND elec_used = FALSE ORDER BY elec_id", (self.get_argument("sched_id"),)): has_elections = True elec = Election.load_by_id(election_id) self.write("<ul>") for song in elec.songs: self.write("<li>%s (%s - %s)</li>" % (song.data['title'], song.albums[0].data['name'], song.artists[0].data['name'])) self.write("<li><a onclick=\"window.top.call_api('admin/delete_election?elec_id=%s');\">(delete election)</a></li>" % elec.id) self.write("</ul>") if not has_elections: self.write("<div>No elections queued yet.</div>") self.write(self.render_string("basic_footer.html"))
def get_requests(self, refresh=False): if self.id <= 1: return [] requests = cache.get_user(self, "requests") if refresh or (not requests or len(requests) == 0): line_sid = self.get_request_line_sid() requests = db.c.fetch_all( "SELECT r4_request_store.song_id AS id, r4_request_store.reqstor_order AS order, r4_request_store.reqstor_id AS request_id, " "song_rating AS rating, song_title AS title, song_length AS length, r4_song_sid.song_cool AS cool, r4_song_sid.song_cool_end AS cool_end, " "r4_song_sid.song_elec_blocked AS elec_blocked, r4_song_sid.song_elec_blocked_by AS elec_blocked_by, " "r4_song_sid.song_elec_blocked_num AS elec_blocked_num, r4_song_sid.song_exists AS valid, " "r4_song_sid.album_id AS album_id, r4_albums.album_name " "FROM r4_request_store " "JOIN r4_songs USING (song_id) " "LEFT JOIN r4_song_sid ON (r4_song_sid.sid = %s AND r4_songs.song_id = r4_song_sid.song_id) " "LEFT JOIN r4_song_ratings ON (r4_request_store.song_id = r4_song_ratings.song_id) " "JOIN r4_albums ON (r4_song_sid.album_id = r4_albums.album_id) " "WHERE r4_request_store.user_id = %s " "ORDER BY reqstor_order, reqstor_id", (line_sid, self.id)) if not requests: requests = [] for song in requests: if not song['album_name']: song['albums'] = [{ "id": song['album_id'], "name": db.c.fetch_var( "SELECT album_name FROM r4_albums WHERE album_id = %s", (song['album_id'], )) }] else: song['albums'] = [{ "name": song['album_name'], "id": song['album_id'] }] song.pop('album_name', None) song.pop('album_id', None) cache.set_user(self, "requests", requests) return requests
def get(self): self.write( self.render_string("bare_header.html", title="%s DJ Election Tool" % config.station_id_friendly[self.sid])) self.write( "<script>\nwindow.top.refresh_all_screens = true;\n</script>") if self.get_argument("sched_id", None): self.write("<h2>%s Elections" % (db.c.fetch_var( "SELECT sched_name FROM r4_schedule WHERE sched_id = %s", (self.get_argument("sched_id"), )))) self.write(" (%s)</h2>" % config.station_id_friendly[db.c.fetch_var( "SELECT sid FROM r4_schedule WHERE sched_id = %s", (self.get_argument("sched_id"), ))]) else: self.write("<h2>%s DJ Election Tool</h2>" % config.station_id_friendly[self.sid]) self.write( "<ul><li>Once committed, the election cannot be edited.</li>") self.write( "<li>Pulling songs from other stations is possible and will not affect cooldown on the other station. (it will affect voting stats on other stations)" ) self.write( "<li>Song order in elections is randomized for each user - do not rely on the order.</li>" ) self.write( "<li>Putting in 1 song will disable voting on the election.</li>") self.write("</ul><hr>") songs = cache.get_user(self.user.id, "dj_election") if not songs: self.write("<p>No election started yet.</p>") else: self.write("<ul>") for song in songs: self.write( "<li>%s<br>%s<br><a onclick=\"window.top.call_api('admin/remove_from_dj_election', { 'song_id': %s });\">Remove</a></li>" % (song.data['title'], song.albums[0].data['name'], song.id)) self.write("</ul>") if not self.get_argument("sched_id", None): self.write( "<a onclick=\"window.top.call_api('admin/commit_dj_election');\">Commit to Queue</a>" ) else: self.write( "<a onclick=\"window.top.call_api('admin/commit_dj_election?sched_id=%s');\">Add to DJ Block</a>" % (self.get_argument("sched_id"), )) if self.get_argument("sched_id", None): self.write("<hr>") has_elections = False for election_id in db.c.fetch_list( "SELECT elec_id FROM r4_elections WHERE sched_id = %s AND elec_used = FALSE ORDER BY elec_id", (self.get_argument("sched_id"), )): has_elections = True elec = Election.load_by_id(election_id) self.write("<ul>") for song in elec.songs: self.write( "<li>%s (%s - %s)</li>" % (song.data['title'], song.albums[0].data['name'], song.artists[0].data['name'])) self.write( "<li><a onclick=\"window.top.call_api('admin/delete_election?elec_id=%s');\">(delete election)</a></li>" % elec.id) self.write("</ul>") if not has_elections: self.write("<div>No elections queued yet.</div>") self.write(self.render_string("basic_footer.html"))
def attach_info_to_request(request, extra_list=None, all_lists=False): # Front-load all non-animated content ahead of the schedule content # Since the schedule content is the most animated on R3, setting this content to load # first has a good impact on the perceived animation smoothness since table redrawing # doesn't have to take place during the first few frames. if request.user: request.append("user", request.user.to_private_dict()) if not request.mobile: if all_lists or (extra_list == "all_albums" ) or 'all_albums' in request.request.arguments: request.append( "all_albums", api_requests.playlist.get_all_albums(request.sid, request.user)) else: request.append("album_diff", cache.get_station(request.sid, 'album_diff')) if all_lists or (extra_list == "all_artists" ) or 'all_artists' in request.request.arguments: request.append("all_artists", api_requests.playlist.get_all_artists(request.sid)) if all_lists or (extra_list == "all_groups" ) or 'all_groups' in request.request.arguments: request.append("all_groups", api_requests.playlist.get_all_groups(request.sid)) if all_lists or ( extra_list == "current_listeners" ) or 'current_listeners' in request.request.arguments or request.get_cookie( "r4_active_list") == "current_listeners": request.append("current_listeners", cache.get_station(request.sid, "current_listeners")) request.append("request_line", cache.get_station(request.sid, "request_line")) sched_next = None sched_history = None sched_current = None if request.user and not request.user.is_anonymous(): request.append("requests", request.user.get_requests(request.sid)) sched_current = cache.get_station(request.sid, "sched_current") if not sched_current: raise APIException( "server_just_started", "Rainwave is Rebooting, Please Try Again in a Few Minutes", http_code=500) if request.user.is_tunedin(): sched_current.get_song().data['rating_allowed'] = True sched_current = sched_current.to_dict(request.user) sched_next = [] sched_next_objects = cache.get_station(request.sid, "sched_next") for evt in sched_next_objects: sched_next.append(evt.to_dict(request.user)) if len(sched_next) > 0 and request.user.is_tunedin( ) and sched_next_objects[0].is_election: sched_next[0]['voting_allowed'] = True if request.user.is_tunedin() and request.user.has_perks(): for i in range(1, len(sched_next)): if sched_next_objects[i].is_election: sched_next[i]['voting_allowed'] = True sched_history = [] for evt in cache.get_station(request.sid, "sched_history"): sched_history.append( evt.to_dict(request.user, check_rating_acl=True)) elif request.user: sched_current = cache.get_station(request.sid, "sched_current_dict") if not sched_current: raise APIException( "server_just_started", "Rainwave is Rebooting, Please Try Again in a Few Minutes", http_code=500) sched_next = cache.get_station(request.sid, "sched_next_dict") sched_history = cache.get_station(request.sid, "sched_history_dict") if len(sched_next) > 0 and request.user.is_tunedin( ) and sched_next[0]['type'] == "Election": sched_next[0]['voting_allowed'] = True request.append("sched_current", sched_current) request.append("sched_next", sched_next) request.append("sched_history", sched_history) if request.user: if not request.user.is_anonymous(): user_vote_cache = cache.get_user(request.user, "vote_history") temp_current = list() temp_current.append(sched_current) if user_vote_cache: for history in user_vote_cache: for event in (sched_history + sched_next + temp_current): if history[0] == event['id']: api_requests.vote.append_success_to_request( request, event['id'], history[1]) else: if len(sched_next) > 0 and request.user.data[ 'voted_entry'] > 0 and request.user.data[ 'lock_sid'] == request.sid: api_requests.vote.append_success_to_request( request, sched_next[0]['id'], request.user.data['voted_entry']) request.append("all_stations_info", cache.get("all_stations_info"))
def vote(self, entry_id, event, lock_count): # Subtract a previous vote from the song's total if there was one already_voted = False if self.user.is_anonymous(): # log.debug("vote", "Anon already voted: %s" % (self.user.id, self.user.data['voted_entry'])) if self.user.data['voted_entry'] and self.user.data['voted_entry'] == entry_id: # immediately return and a success will be registered return True if self.user.data['voted_entry']: already_voted = self.user.data['voted_entry'] else: previous_vote = db.c.fetch_row("SELECT entry_id, vote_id, song_id FROM r4_vote_history WHERE user_id = %s AND elec_id = %s", (self.user.id, event.id)) # log.debug("vote", "Already voted: %s" % repr(already_voted)) if previous_vote and previous_vote['entry_id'] == entry_id: # immediately return and a success will be registered return True elif previous_vote: already_voted = previous_vote['entry_id'] db.c.start_transaction() try: if already_voted: if not event.add_vote_to_entry(already_voted, -1): log.warn("vote", "Could not subtract vote from entry: listener ID %s voting for entry ID %s." % (self.user.data['listener_id'], already_voted)) raise APIException("internal_error") # If this is a new vote, we need to check to make sure the listener is not locked. if not already_voted and self.user.data['lock'] and self.user.data['lock_sid'] != self.sid: raise APIException("user_locked", "User locked to %s for %s more songs." % (config.station_id_friendly[self.user.data['lock_sid']], self.user.data['lock_counter'])) # Issue the listener lock (will extend a lock if necessary) if not self.user.lock_to_sid(self.sid, lock_count): log.warn("vote", "Could not lock user: listener ID %s voting for entry ID %s, tried to lock for %s events." % (self.user.data['listener_id'], entry_id, lock_count)) raise APIException("internal_error", "Internal server error. User is now locked to station ID %s." % self.sid) if self.user.is_anonymous(): if not db.c.update("UPDATE r4_listeners SET listener_voted_entry = %s WHERE listener_id = %s", (entry_id, self.user.data['listener_id'])): log.warn("vote", "Could not set voted_entry: listener ID %s voting for entry ID %s." % (self.user.data['listener_id'], entry_id)) raise APIException("internal_error") self.user.update({ "listener_voted_entry": entry_id }) else: if already_voted: db.c.update("UPDATE r4_vote_history SET song_id = %s, entry_id = %s WHERE user_id = %s and entry_id = %s", (event.get_entry(entry_id).id, entry_id, self.user.id, already_voted)) else: time_window = int(timestamp()) - 1209600 vote_count = db.c.fetch_var("SELECT COUNT(vote_id) FROM r4_vote_history WHERE vote_time > %s AND user_id = %s", (time_window, self.user.id)) db.c.execute("SELECT user_id, COUNT(song_id) AS c FROM r4_vote_history WHERE vote_time > %s GROUP BY user_id HAVING COUNT(song_id) > %s", (time_window, vote_count)) rank = db.c.rowcount + 1 db.c.update( "INSERT INTO r4_vote_history (elec_id, entry_id, user_id, song_id, vote_at_rank, vote_at_count, sid) " "VALUES (%s, %s, %s, %s, %s, %s, %s)", (event.id, entry_id, self.user.id, event.get_entry(entry_id).id, rank, vote_count, event.sid)) db.c.update("UPDATE phpbb_users SET radio_inactive = FALSE, radio_last_active = %s, radio_totalvotes = %s WHERE user_id = %s", (timestamp(), vote_count, self.user.id)) user_vote_cache = cache.get_user(self.user, "vote_history") if not user_vote_cache: user_vote_cache = [] found = False for voted in user_vote_cache: if voted[0] == event.id: found = True voted[1] = entry_id while len(user_vote_cache) > 5: user_vote_cache.pop(0) if not found: user_vote_cache.append([event.id, entry_id]) print "setting user cache: %s" % user_vote_cache cache.set_user(self.user, "vote_history", user_vote_cache) # Register vote if not event.add_vote_to_entry(entry_id): log.warn("vote", "Could not add vote to entry: listener ID %s voting for entry ID %s." % (self.user.data['listener_id'], entry_id)) raise APIException("internal_error") db.c.commit() except: db.c.rollback() raise return True
def vote(self, entry_id, event, lock_count): # Subtract a previous vote from the song's total if there was one already_voted = False if self.user.is_anonymous(): log.debug("vote", "Anon already voted: %s" % (self.user.id, self.user.data['listener_voted_entry'])) if self.user.data['listener_voted_entry'] and self.user.data['listener_voted_entry'] == entry_id: raise APIException("already_voted_for_song") if self.user.data['listener_voted_entry']: already_voted = True if not event.add_vote_to_entry(entry_id, -1): log.warn("vote", "Could not subtract vote from entry: listener ID %s voting for entry ID %s." % (self.user.data['listener_id'], entry_id)) raise APIException("internal_error") else: already_voted = db.c.fetch_row("SELECT entry_id, vote_id, song_id FROM r4_vote_history WHERE user_id = %s AND elec_id = %s", (self.user.id, event.id)) log.debug("vote", "Already voted: %s" % repr(already_voted)) if already_voted and already_voted['entry_id'] == entry_id: raise APIException("already_voted_for_song") elif already_voted: log.debug("vote", "Subtracting vote from %s" % already_voted['entry_id']) if not event.add_vote_to_entry(already_voted['entry_id'], -1): log.warn("vote", "Could not subtract vote from entry: listener ID %s voting for entry ID %s." % (self.user.data['listener_id'], entry_id)) raise APIException("internal_error") # If this is a new vote, we need to check to make sure the listener is not locked. if not already_voted and self.user.data['listener_lock'] and self.user.data['listener_lock_sid'] != self.sid: raise APIException("user_locked", "User locked to %s for %s more songs." % (config.station_id_friendly[self.user.data['listener_lock_sid']], self.user.data['listener_lock_counter'])) # Issue the listener lock (will extend a lock if necessary) if not self.user.lock_to_sid(self.sid, lock_count): log.warn("vote", "Could not lock user: listener ID %s voting for entry ID %s, tried to lock for %s events." % (self.user.data['listener_id'], entry_id, lock_count)) raise APIException("internal_error", "Internal server error. User is now locked to station ID %s." % self.sid) # Make sure the vote is tracked track_success = False if self.user.is_anonymous(): if not db.c.update("UPDATE r4_listeners SET listener_voted_entry = %s WHERE listener_id = %s", (entry_id, self.user.data['listener_id'])): log.warn("vote", "Could not set voted_entry: listener ID %s voting for entry ID %s." % (self.user.data['listener_id'], entry_id)) raise APIException("internal_error") self.user.update({ "listener_voted_entry": entry_id }) track_success = True else: if already_voted: db.c.update("UPDATE r4_vote_history SET song_id = %s, entry_id = %s WHERE vote_id = %s", (event.get_entry(entry_id).id, entry_id, already_voted['vote_id'])) else: time_window = int(time.time()) - 1209600 vote_count = db.c.fetch_var("SELECT COUNT(vote_id) FROM r4_vote_history WHERE vote_time > %s AND user_id = %s", (time_window, self.user.id)) db.c.execute("SELECT user_id, COUNT(song_id) AS c FROM r4_vote_history WHERE vote_time > %s GROUP BY user_id HAVING COUNT(song_id) > %s", (time_window, vote_count)) rank = db.c.rowcount + 1 db.c.update( "INSERT INTO r4_vote_history (elec_id, entry_id, user_id, song_id, vote_at_rank, vote_at_count) " "VALUES (%s, %s, %s, %s, %s, %s)", (event.id, entry_id, self.user.id, event.get_entry(entry_id).id, rank, vote_count)) track_success = True user_vote_cache = cache.get_user(self.user, "vote_history") if not user_vote_cache: user_vote_cache = [] while len(user_vote_cache) > 5: user_vote_cache.pop(0) user_vote_cache.append((event.id, entry_id)) cache.set_user(self.user, "vote_history", user_vote_cache) # Register vote if not event.add_vote_to_entry(entry_id): log.warn("vote", "Could not add vote to entry: listener ID %s voting for entry ID %s." % (self.user.data['listener_id'], entry_id)) raise APIException("internal_error")
def vote(self, entry_id, event, lock_count): # Subtract a previous vote from the song's total if there was one already_voted = False if self.user.is_anonymous(): # log.debug("vote", "Anon already voted: %s" % (self.user.data['voted_entry'],)) if (self.user.data["voted_entry"] and self.user.data["voted_entry"] == entry_id): # immediately return and a success will be registered return True if self.user.data["voted_entry"]: already_voted = self.user.data["voted_entry"] else: previous_vote = db.c.fetch_row( "SELECT entry_id, vote_id, song_id FROM r4_vote_history WHERE user_id = %s AND elec_id = %s", (self.user.id, event.id), ) # log.debug("vote", "Already voted: %s" % repr(already_voted)) if previous_vote and previous_vote["entry_id"] == entry_id: # immediately return and a success will be registered return True elif previous_vote: already_voted = previous_vote["entry_id"] db.c.start_transaction() try: if already_voted: if not event.add_vote_to_entry(already_voted, -1): log.warn( "vote", "Could not subtract vote from entry: listener ID %s voting for entry ID %s." % (self.user.data["listener_id"], already_voted), ) raise APIException("internal_error") # If this is a new vote, we need to check to make sure the listener is not locked. if (not already_voted and self.user.data["lock"] and self.user.data["lock_sid"] != self.sid): raise APIException( "user_locked", "User locked to %s for %s more song(s)." % ( config.station_id_friendly[self.user.data["lock_sid"]], self.user.data["lock_counter"], ), ) # Issue the listener lock (will extend a lock if necessary) if not self.user.lock_to_sid(self.sid, lock_count): log.warn( "vote", "Could not lock user: listener ID %s voting for entry ID %s, tried to lock for %s events." % (self.user.data["listener_id"], entry_id, lock_count), ) raise APIException( "internal_error", "Internal server error. User is now locked to station ID %s." % self.sid, ) if self.user.is_anonymous(): if not db.c.update( "UPDATE r4_listeners SET listener_voted_entry = %s WHERE listener_id = %s", (entry_id, self.user.data["listener_id"]), ): log.warn( "vote", "Could not set voted_entry: listener ID %s voting for entry ID %s." % (self.user.data["listener_id"], entry_id), ) raise APIException("internal_error") self.user.update({"voted_entry": entry_id}) else: if already_voted: db.c.update( "UPDATE r4_vote_history SET song_id = %s, entry_id = %s WHERE user_id = %s and entry_id = %s", ( event.get_entry(entry_id).id, entry_id, self.user.id, already_voted, ), ) else: db.c.update( "INSERT INTO r4_vote_history (elec_id, entry_id, user_id, song_id, sid) " "VALUES (%s, %s, %s, %s, %s)", ( event.id, entry_id, self.user.id, event.get_entry(entry_id).id, event.sid, ), ) db.c.update( "UPDATE phpbb_users SET radio_inactive = FALSE, radio_last_active = %s WHERE user_id = %s", (timestamp(), self.user.id), ) autovoted_entry = event.has_request_by_user(self.user.id) if autovoted_entry: event.add_vote_to_entry( autovoted_entry.data["entry_id"], -1) user_vote_cache = cache.get_user(self.user, "vote_history") if not user_vote_cache: user_vote_cache = [] found = False for voted in user_vote_cache: if voted[0] == event.id: found = True voted[1] = entry_id while len(user_vote_cache) > 5: user_vote_cache.pop(0) if not found: user_vote_cache.append([event.id, entry_id]) cache.set_user(self.user, "vote_history", user_vote_cache) # Register vote if not event.add_vote_to_entry(entry_id): log.warn( "vote", "Could not add vote to entry: listener ID %s voting for entry ID %s." % (self.user.data["listener_id"], entry_id), ) raise APIException("internal_error") db.c.commit() except: db.c.rollback() raise return True
def attach_info_to_request( request, extra_list=None, all_lists=False, live_voting=False ): # Front-load all non-animated content ahead of the schedule content # Since the schedule content is the most animated on R3, setting this content to load # first has a good impact on the perceived animation smoothness since table redrawing # doesn't have to take place during the first few frames. if request.user: request.append("user", request.user.to_private_dict()) if request.user.is_dj(): attach_dj_info_to_request(request) if not request.mobile: if ( all_lists or (extra_list == "all_albums") or (extra_list == "album") or "all_albums" in request.request.arguments ): request.append( "all_albums", api_requests.playlist.get_all_albums(request.sid, request.user), ) else: request.append("album_diff", cache.get_station(request.sid, "album_diff")) if ( all_lists or (extra_list == "all_artists") or (extra_list == "artist") or "all_artists" in request.request.arguments ): request.append( "all_artists", api_requests.playlist.get_all_artists(request.sid) ) if ( all_lists or (extra_list == "all_groups") or (extra_list == "group") or "all_groups" in request.request.arguments ): request.append( "all_groups", api_requests.playlist.get_all_groups(request.sid) ) if ( all_lists or (extra_list == "current_listeners") or "current_listeners" in request.request.arguments or request.get_cookie("r4_active_list") == "current_listeners" ): request.append( "current_listeners", cache.get_station(request.sid, "current_listeners") ) request.append("request_line", cache.get_station(request.sid, "request_line")) sched_next = None sched_history = None sched_current = None if request.user and not request.user.is_anonymous(): request.append("requests", request.user.get_requests(request.sid)) sched_current = cache.get_station(request.sid, "sched_current") if not sched_current: raise APIException( "server_just_started", "Rainwave is Rebooting, Please Try Again in a Few Minutes", http_code=500, ) if request.user.is_tunedin(): sched_current.get_song().data["rating_allowed"] = True sched_current = sched_current.to_dict(request.user) sched_next = [] sched_next_objects = cache.get_station(request.sid, "sched_next") for evt in sched_next_objects: sched_next.append(evt.to_dict(request.user)) if ( len(sched_next) > 0 and request.user.is_tunedin() and sched_next_objects[0].is_election and len(sched_next_objects[0].songs) > 1 ): sched_next[0]["voting_allowed"] = True if request.user.is_tunedin() and request.user.has_perks(): for i in range(1, len(sched_next)): if ( sched_next_objects[i].is_election and len(sched_next_objects[i].songs) > 1 ): sched_next[i]["voting_allowed"] = True sched_history = [] for evt in cache.get_station(request.sid, "sched_history"): sched_history.append(evt.to_dict(request.user, check_rating_acl=True)) elif request.user: sched_current = cache.get_station(request.sid, "sched_current_dict") if not sched_current: raise APIException( "server_just_started", "Rainwave is Rebooting, Please Try Again in a Few Minutes", http_code=500, ) sched_next = cache.get_station(request.sid, "sched_next_dict") sched_history = cache.get_station(request.sid, "sched_history_dict") if ( len(sched_next) > 0 and request.user.is_tunedin() and sched_next[0]["type"] == "Election" and len(sched_next[0]["songs"]) > 1 ): sched_next[0]["voting_allowed"] = True request.append("sched_current", sched_current) request.append("sched_next", sched_next) request.append("sched_history", sched_history) if request.user: if not request.user.is_anonymous(): user_vote_cache = cache.get_user(request.user, "vote_history") if user_vote_cache: request.append("already_voted", user_vote_cache) else: if ( len(sched_next) > 0 and request.user.data.get("voted_entry") and request.user.data.get("voted_entry") > 0 and request.user.data["lock_sid"] == request.sid ): request.append( "already_voted", [(sched_next[0]["id"], request.user.data["voted_entry"])], ) request.append("all_stations_info", cache.get("all_stations_info")) if live_voting: request.append("live_voting", cache.get_station(request.sid, "live_voting"))
def vote(self, entry_id, event, lock_count): # Subtract a previous vote from the song's total if there was one already_voted = False if self.user.is_anonymous(): log.debug( "vote", "Anon already voted: %s" % (self.user.id, self.user.data['listener_voted_entry'])) if self.user.data['listener_voted_entry'] and self.user.data[ 'listener_voted_entry'] == entry_id: raise APIException("already_voted_for_song") if self.user.data['listener_voted_entry']: already_voted = True if not event.add_vote_to_entry(entry_id, -1): log.warn( "vote", "Could not subtract vote from entry: listener ID %s voting for entry ID %s." % (self.user.data['listener_id'], entry_id)) raise APIException("internal_error") else: already_voted = db.c.fetch_row( "SELECT entry_id, vote_id, song_id FROM r4_vote_history WHERE user_id = %s AND elec_id = %s", (self.user.id, event.id)) log.debug("vote", "Already voted: %s" % repr(already_voted)) if already_voted and already_voted['entry_id'] == entry_id: raise APIException("already_voted_for_song") elif already_voted: log.debug( "vote", "Subtracting vote from %s" % already_voted['entry_id']) if not event.add_vote_to_entry(already_voted['entry_id'], -1): log.warn( "vote", "Could not subtract vote from entry: listener ID %s voting for entry ID %s." % (self.user.data['listener_id'], entry_id)) raise APIException("internal_error") # If this is a new vote, we need to check to make sure the listener is not locked. if not already_voted and self.user.data[ 'listener_lock'] and self.user.data[ 'listener_lock_sid'] != self.sid: raise APIException( "user_locked", "User locked to %s for %s more songs." % (config.station_id_friendly[ self.user.data['listener_lock_sid']], self.user.data['listener_lock_counter'])) # Issue the listener lock (will extend a lock if necessary) if not self.user.lock_to_sid(self.sid, lock_count): log.warn( "vote", "Could not lock user: listener ID %s voting for entry ID %s, tried to lock for %s events." % (self.user.data['listener_id'], entry_id, lock_count)) raise APIException( "internal_error", "Internal server error. User is now locked to station ID %s." % self.sid) # Make sure the vote is tracked track_success = False if self.user.is_anonymous(): if not db.c.update( "UPDATE r4_listeners SET listener_voted_entry = %s WHERE listener_id = %s", (entry_id, self.user.data['listener_id'])): log.warn( "vote", "Could not set voted_entry: listener ID %s voting for entry ID %s." % (self.user.data['listener_id'], entry_id)) raise APIException("internal_error") self.user.update({"listener_voted_entry": entry_id}) track_success = True else: if already_voted: db.c.update( "UPDATE r4_vote_history SET song_id = %s, entry_id = %s WHERE vote_id = %s", (event.get_entry(entry_id).id, entry_id, already_voted['vote_id'])) else: time_window = int(time.time()) - 1209600 vote_count = db.c.fetch_var( "SELECT COUNT(vote_id) FROM r4_vote_history WHERE vote_time > %s AND user_id = %s", (time_window, self.user.id)) db.c.execute( "SELECT user_id, COUNT(song_id) AS c FROM r4_vote_history WHERE vote_time > %s GROUP BY user_id HAVING COUNT(song_id) > %s", (time_window, vote_count)) rank = db.c.rowcount + 1 db.c.update( "INSERT INTO r4_vote_history (elec_id, entry_id, user_id, song_id, vote_at_rank, vote_at_count) " "VALUES (%s, %s, %s, %s, %s, %s)", (event.id, entry_id, self.user.id, event.get_entry(entry_id).id, rank, vote_count)) track_success = True user_vote_cache = cache.get_user(self.user, "vote_history") if not user_vote_cache: user_vote_cache = [] while len(user_vote_cache) > 5: user_vote_cache.pop(0) user_vote_cache.append((event.id, entry_id)) cache.set_user(self.user, "vote_history", user_vote_cache) # Register vote if not event.add_vote_to_entry(entry_id): log.warn( "vote", "Could not add vote to entry: listener ID %s voting for entry ID %s." % (self.user.data['listener_id'], entry_id)) raise APIException("internal_error")
def attach_info_to_request(request, extra_list = None, all_lists = False): # Front-load all non-animated content ahead of the schedule content # Since the schedule content is the most animated on R3, setting this content to load # first has a good impact on the perceived animation smoothness since table redrawing # doesn't have to take place during the first few frames. if request.user: request.append("user", request.user.to_private_dict()) if not request.mobile: if all_lists or (extra_list == "all_albums") or 'all_albums' in request.request.arguments: request.append("all_albums", api_requests.playlist.get_all_albums(request.sid, request.user)) else: request.append("album_diff", cache.get_station(request.sid, 'album_diff')) if all_lists or (extra_list == "all_artists") or 'all_artists' in request.request.arguments: request.append("all_artists", api_requests.playlist.get_all_artists(request.sid)) if all_lists or (extra_list == "all_groups") or 'all_groups' in request.request.arguments: request.append("all_groups", api_requests.playlist.get_all_groups(request.sid)) if all_lists or (extra_list == "current_listeners") or 'current_listeners' in request.request.arguments or request.get_cookie("r4_active_list") == "current_listeners": request.append("current_listeners", cache.get_station(request.sid, "current_listeners")) request.append("request_line", cache.get_station(request.sid, "request_line")) sched_next = None sched_history = None sched_current = None if request.user and not request.user.is_anonymous(): request.append("requests", request.user.get_requests(request.sid)) sched_current = cache.get_station(request.sid, "sched_current") if not sched_current: raise APIException("server_just_started", "Rainwave is Rebooting, Please Try Again in a Few Minutes", http_code=500) if request.user.is_tunedin(): sched_current.get_song().data['rating_allowed'] = True sched_current = sched_current.to_dict(request.user) sched_next = [] sched_next_objects = cache.get_station(request.sid, "sched_next") for evt in sched_next_objects: sched_next.append(evt.to_dict(request.user)) if len(sched_next) > 0 and request.user.is_tunedin() and sched_next_objects[0].is_election and len(sched_next_objects[0].songs) > 1: sched_next[0]['voting_allowed'] = True if request.user.is_tunedin() and request.user.has_perks(): for i in range(1, len(sched_next)): if sched_next_objects[i].is_election and len(sched_next_objects[0].songs) > 1: sched_next[i]['voting_allowed'] = True sched_history = [] for evt in cache.get_station(request.sid, "sched_history"): sched_history.append(evt.to_dict(request.user, check_rating_acl=True)) elif request.user: sched_current = cache.get_station(request.sid, "sched_current_dict") if not sched_current: raise APIException("server_just_started", "Rainwave is Rebooting, Please Try Again in a Few Minutes", http_code=500) sched_next = cache.get_station(request.sid, "sched_next_dict") sched_history = cache.get_station(request.sid, "sched_history_dict") if len(sched_next) > 0 and request.user.is_tunedin() and sched_next[0]['type'] == "Election" and len(sched_next[0]['songs']) > 1: sched_next[0]['voting_allowed'] = True request.append("sched_current", sched_current) request.append("sched_next", sched_next) request.append("sched_history", sched_history) if request.user: if not request.user.is_anonymous(): user_vote_cache = cache.get_user(request.user, "vote_history") temp_current = list() temp_current.append(sched_current) if user_vote_cache: for history in user_vote_cache: for event in (sched_history + sched_next + temp_current): if history[0] == event['id']: api_requests.vote.append_success_to_request(request, event['id'], history[1]) else: if len(sched_next) > 0 and request.user.data['voted_entry'] > 0 and request.user.data['lock_sid'] == request.sid: api_requests.vote.append_success_to_request(request, sched_next[0]['id'], request.user.data['voted_entry']) request.append("all_stations_info", cache.get("all_stations_info"))