def get(self): """ Returns the currently playing track. Returns ------- http.Response A http response instance, 204 or 200 """ track, user = self.get_current_track() if track is None or user is None: return http.NoContent() # Get Pause State try: paused = int(redis.get('fm:player:paused')) except (ValueError, TypeError): paused = 0 elapsed = self.elapsed(paused=bool(paused)) headers = {'Paused': paused} response = { 'track': TrackSerializer().serialize(track), 'user': UserSerializer().serialize(user), 'player': { 'elapsed_time': elapsed, # ms 'elapsed_percentage': (elapsed / track.duration) * 100, # % 'elapsed_seconds': elapsed / 1000 # seconds } } return http.OK(response, headers=headers)
def get_client_credentials(): """Calls the spotify API to return the client credentials token """ token = redis.get('fm:spotify:token') if token is not None: return token r = requests.post( 'https://accounts.spotify.com/api/token', auth=( current_app.config.get('SPOTIFY_CLIENT_ID'), current_app.config.get('SPOTIFY_CLIENT_SECRET'), ), data={ 'grant_type': 'client_credentials', }) if r.status_code != httplib.OK: raise Exception('invalid status code response') json = r.json() token = json.get('access_token') expire = json.get('expires_in') redis.set('fm:spotify:token', token, ex=expire) return token
def elapsed(self, paused=False): """ Calculates the current playhead (durration) of the track based on two factors, 1: Track Start Time, 2: Total Pause Durration. elapsed = (now - (start + paused)) Returns ------- int Elapsed time in ms """ now = datetime.utcnow() # Always set tzinfo now = now.replace(tzinfo=dateutil.tz.tzutc()) # Get play start time start_time = redis.get('fm:player:start_time') if start_time is None: start_time = now else: start_time = dateutil.parser.parse(start_time).replace( tzinfo=dateutil.tz.tzutc()) # Get Pause Durration try: pause_durration = int(redis.get('fm:player:pause_duration')) except (ValueError, TypeError): pause_durration = 0 # If we are in a puase state we also need to add on the difference # between the pause start time and now to pause duration paused_start = None if paused: paused_start = redis.get('fm:player:pause_time') if paused_start is not None: paused_start = dateutil.parser.parse(paused_start).replace( tzinfo=dateutil.tz.tzutc()) pause_durration += int( (now - paused_start).total_seconds() * 1000) # Perform calculation diff = now - (start_time + timedelta(seconds=pause_durration / 1000)) elapsed = int(diff.total_seconds() * 1000) return elapsed
def get(self): """ Retrieve the current volume level for the physical player. """ try: volume = int(redis.get('fm:player:volume')) except (ValueError, TypeError): volume = 0 return http.OK({'volume': volume})
def is_mute(self): mute = redis.get('fm:player:mute') if mute is None: mute = 0 try: value = bool(int(mute)) except ValueError: value = False return value
def validate_session(session_id): """ Validates an incoming Session ID, ensures that it is valid by ensuring it matches with the correct user. Arguments --------- session_id : str The Session ID to Validate Returns ------- str or None User primary key or None if session is not valid """ # Get the user id from the session in redis user_id = redis.get(SESSION_KEY.format(session_id)) if user_id is None: return None user_key = USER_SESSION_KEY.format(user_id) # Convert fm:api:user:session:<user_id> to a set if a string if redis.type(user_key) == 'string': value = redis.get(user_key) redis.delete(user_key) redis.sadd(user_key, value) # Is the session id in the users sessions user_sessions = redis.smembers(user_key) if session_id not in user_sessions: return None serializer = URLSafeTimedSerializer(config.SECRET_KEY) if not serializer.loads(session_id) == user_id: return None return user_id
def get_current_track(self): """ Returns the currently playing track from redis. Returns ------- fm.models.spotify.Teack The currently playing track or None """ current = redis.get('fm:player:current') if current is None: return None, None uri, user = json.loads(current).values() track = Track.query.filter(Track.spotify_uri == uri).first() user = User.query.filter(User.id == user).first() return track, user