def find_queue_time_limit(user, song): """ Return seconds left of limit """ next = False if QUEUE_TIME_LIMIT: limit = models.TimeDelta(**QUEUE_TIME_LIMIT[0]) duration = models.TimeDelta(**QUEUE_TIME_LIMIT[1]) start = datetime.datetime.now() - duration #Fetch all queued objects by that user in given time period Q = models.Queue.objects.filter(requested__gt=start, requested_by=user).order_by("id") total_seconds = limit.total_seconds() - song.get_songlength() if Q.count(): queued_seconds = Q.aggregate(Sum("song__song_length"))[ "song__song_length__sum"] #Length of all songs queued seconds_left = total_seconds - queued_seconds earliest = Q[0].requested next = earliest + duration if seconds_left <= 0: seconds_left = seconds_left + song.get_songlength() return (True, seconds_left, next) return (False, seconds_left, next) return (False, total_seconds, next) return (False, False, next)
def queue_song(song, user, event=True, force=False): event_metadata = {'song': song.id, 'user': user.id} if user.get_profile().is_hellbanned(): return False if SELFQUEUE_DISABLED and song.is_connected_to(user): models.send_notification("You can't request your own songs!", user) return False # To update lock time and other stats # select_for_update is used to lock the song row, so no other request # can modify it at the same time. song = models.Song.objects.select_for_update().get(id=song.id) num_dj_hours = getattr(settings, 'DJ_HOURS', 0) if not force and num_dj_hours: # Don't allow requests to be played during DJ hours play_start = models.Queue(song=song).get_eta() hours_at_start = get_dj_hours(play_start, num_dj_hours) play_end = play_start + datetime.timedelta( seconds=song.get_songlength()) if play_end.day == play_start.day: hours_at_end = hours_at_start else: hours_at_end = get_dj_hours(play_end, num_dj_hours) if play_start.hour in hours_at_start or play_end.hour in hours_at_end: if datetime.datetime.now().hour in hours_at_start: s = "Queuing songs is disabled during DJ Random sessions. DJ Random has the floor!!!" else: s = "Queuing songs during hour of expected play time is not allowed. DJ Random will have the floor!!!" models.send_notification(s, user) return False key = "songqueuenum-" + str(user.id) EVS = [] Q = False time = song.create_lock_time() result = True total_req_count = models.Queue.objects.filter(played=False).count() if total_req_count < MIN_QUEUE_SONGS_LIMIT and not song.is_locked(): Q = models.Queue.objects.filter(played=False, requested_by=user) user_req_and_play_count = Q.count() total_req_and_play_count = total_req_count now_playing = get_now_playing_song() if now_playing: total_req_and_play_count += 1 if now_playing.requested_by == user: user_req_and_play_count += 1 # Is user the only one requesting (and also same user as requester of # currently playing song) ? Then allow forced queueing. # In all other cases there's at least one other requester and # then the normal rules apply. if user_req_and_play_count == total_req_and_play_count: force = True time_full, time_left, time_next = find_queue_time_limit(user, song) time_left_delta = models.TimeDelta(seconds=time_left) if not force: if time_full: result = False models.send_notification( "Song is too long. Remaining timeslot : %s. Next timeslot change: <span class='tzinfo'>%s</span>" % (time_left_delta.to_string(), time_next.strftime("%H:%M")), user) requests = cache.get(key, None) if not Q: Q = models.Queue.objects.filter(played=False, requested_by=user) if requests == None: requests = Q.count() else: requests = len(requests) if result and requests >= settings.SONGS_IN_QUEUE: models.send_notification( "You have reached your unplayed queue entry limit! Please wait for your requests to play.", user) result = False if result and song.is_locked(): # In a case, this should not append since user (from view) can't reqs song locked models.send_notification("Song is already locked", user) result = False if result and LOWRATE and song.rating and song.rating <= LOWRATE[ 'lowvote']: if Q.filter(song__rating__lte=LOWRATE['lowvote']).count( ) >= LOWRATE['limit']: models.send_notification( "Anti-Crap: Song Request Denied (Rating Too Low For Current Queue)", user) result = False if result: song.locked_until = datetime.datetime.now() + time song.save() Q = models.Queue(song=song, requested_by=user, played=False) Q.eta = Q.get_eta() Q.save() EVS.append('a_queue_%i' % song.id) #Need to add logic to decrease or delete when song gets played #cache.set(key, requests + 1, 600) if event: get_queue(True) # generate new queue cached object EVS.append('queue') msg = "%s has been queued." % escape(song.title) msg += " It is expected to play at <span class='tzinfo'>%s</span>." % Q.eta.strftime( "%H:%M") if time_left != False: msg += " Remaining timeslot : %s." % time_left_delta.to_string( ) models.send_notification(msg, user) models.add_event(eventlist=EVS, metadata=event_metadata) return Q
def queue_song(song, user, event=True, force=False): event_metadata = {'song': song.id, 'user': user.id} if SELFQUEUE_DISABLED and song.is_connected_to(user): models.send_notification("You can't request your own songs!", user) return False #To update lock time and other stats song = models.Song.objects.get(id=song.id) key = "songqueuenum-" + str(user.id) EVS = [] Q = False time = song.create_lock_time() result = True if models.Queue.objects.filter(played=False).count( ) < MIN_QUEUE_SONGS_LIMIT and not song.is_locked(): force = True time_full, time_left, time_next = find_queue_time_limit(user, song) time_left_delta = models.TimeDelta(seconds=time_left) if not force: if time_full: result = False models.send_notification( "Song is too long. Remaining timeslot : %s. Next timeslot change: <span class='tzinfo'>%s</span>" % (time_left_delta.to_string(), time_next.strftime("%H:%M")), user) requests = cache.get(key, None) Q = models.Queue.objects.filter(played=False, requested_by=user) if requests == None: requests = Q.count() else: requests = num(requests) if result and requests >= settings.SONGS_IN_QUEUE: models.send_notification( "You have reached your unplayed queue entry limit! Please wait for your requests to play.", user) result = False if result and song.is_locked(): # In a case, this should not append since user (from view) can't reqs song locked models.send_notification("Song is already locked", user) result = False if result and LOWRATE and song.rating and song.rating <= LOWRATE[ 'lowvote']: if Q.filter(song__rating__lte=LOWRATE['lowvote']).count( ) >= LOWRATE['limit']: models.send_notification( "Anti-Crap: Song Request Denied (Rating Too Low For Current Queue)", user) result = False if result: song.locked_until = datetime.datetime.now() + time song.save() Q = models.Queue(song=song, requested_by=user, played=False) Q.eta = Q.get_eta() Q.save() EVS.append('a_queue_%i' % song.id) #Need to add logic to decrease or delete when song gets played #cache.set(key, requests + 1, 600) if event: bla = get_queue(True) # generate new queue cached object EVS.append('queue') msg = "%s has been queued." % escape(song.title) msg += " It is expected to play at <span class='tzinfo'>%s</span>." % Q.eta.strftime( "%H:%M") if time_left != False: msg += " Remaining timeslot : %s." % time_left_delta.to_string( ) models.send_notification(msg, user) models.add_event(eventlist=EVS, metadata=event_metadata) return Q