def __init__(self, username): self.username = username """Email or user id.""" self.auth = Authenticator(username) """Handles OAuth 2.0 authentication.""" self._uri_cache = UriCache(username) """Cache of Spotify URIs.""" self.me = None """The Spotify user information.""" # Get authorization. self.auth.authenticate() # Get user information and validate it. self.me = self.get_api_v1("me") if not self.me: raise RuntimeError("Could not get account information.") if (self.me['email'] != username) and (self.me['id'] != username): raise RuntimeError( "\n\n\nInvalid email/user id entered!\n" "You entered: {}\n" "You signed in as: {} (email), {} (user id)".format(username, self.me['email'], self.me['id']) )
def __init__(self): super().__init__() self.title("PRMSystem") self.main_frame = tk.Frame(self, bg="#84CEEB") self.main_frame.pack(fill="both", expand="true") self.main_frame.pack_propagate(0) self.geometry("1024x600") self.resizable(0, 0) self.db = PRMS_Database() self.alphavantage_connection = AlphaVantageAPI(api_key="") self.news_connection = NewsConnection("") self.oanda_connection = OandaConnection(account_id="", api_key="") self.current_page = tk.Frame() self.show_frame(HomePage) menubar = Navbar(root=self) tk.Tk.config(self, menu=menubar) self.authenticator = Authenticator(self.db) LoginWindow(parent=self, authenticator=self.authenticator) self.protocol("WM_DELETE_WINDOW", self.quit_application)
def __init__(self, filename): self.filename = filename self.auth = Authenticator() if os.path.exists(self.filename): self.db = cPickle.load(open(self.filename, 'rb')) else: self.db = {} self.db["accounts"] = {} self.db["campaigns"] = {} self.db["ability_cache"] = [None] * (MAX_ABILITY_CACHE + 1 ) # list of Ability dicts self.db["ability_cache_index"] = 0 # Not including static json files in DB for efficiency if os.path.exists("weapons.json"): with open("weapons.json") as f: self.weapons = json.load(f) if os.path.exists("abilities.json"): with open("abilities.json", encoding="utf8") as f: # encoding for smart quotes self.abilities = json.load(f)
def handle_read(self): """Read all available bytes, and process as many packets as possible. """ t = time() if self.last_report + 5 < t and self.stream.tot_bytes > 0: self.last_report = t logger.debug( "%s: total/wasted bytes is %d/%d (%f wasted)" % (self.side, self.stream.tot_bytes, self.stream.wasted_bytes, 100 * float(self.stream.wasted_bytes) / self.stream.tot_bytes)) self.stream.append(self.recv(4092)) if self.out_of_sync: data = self.stream.read(len(self.stream)) self.stream.packet_finished() if self.other_side: self.other_side.send(data) return try: packet = parse_packet(self.stream, self.msg_spec, self.side) while packet != None: rebuild = False if packet['msgtype'] == 0x02 and self.side == 'client': # Determine which protocol message definitions to use. proto_version = packet['proto_version'] logger.info('Client requests protocol version %d' % proto_version) if not proto_version in messages.protocol: logger.error("Unsupported protocol version %d" % proto_version) self.handle_close() return self.username = packet['username'] self.msg_spec, self.other_side.msg_spec = messages.protocol[ proto_version] self.cipher = encryption.encryption_for_version( proto_version) self.other_side.cipher = self.cipher elif packet['msgtype'] == 0xfd: self.rsa_key = encryption.decode_public_key( packet['public_key']) self.encoded_rsa_key = packet['public_key'] packet['public_key'] = encryption.encode_public_key( self.other_side.rsa_key) if 'challenge_token' in packet: self.challenge_token = packet['challenge_token'] self.other_side.challenge_token = self.challenge_token self.other_side.server_id = packet['server_id'] if check_auth: packet['server_id'] = encryption.generate_server_id() else: packet['server_id'] = "-" self.server_id = packet['server_id'] rebuild = True elif packet['msgtype'] == 0xfc and self.side == 'client': self.shared_secret = encryption.decrypt_shared_secret( packet['shared_secret'], self.rsa_key) if (len(self.shared_secret) > 16 and self.cipher == encryption.RC4): logger.error("Unsupported protocol version") self.handle_close() return packet['shared_secret'] = encryption.encrypt_shared_secret( self.other_side.shared_secret, self.other_side.rsa_key) if 'challenge_token' in packet: challenge_token = encryption.decrypt_shared_secret( packet['challenge_token'], self.rsa_key) if challenge_token != self.challenge_token: self.kick("Invalid client reply") return packet[ 'challenge_token'] = encryption.encrypt_shared_secret( self.other_side.challenge_token, self.other_side.rsa_key) if auth: logger.info("Authenticating on server") auth.join_server(self.server_id, self.other_side.shared_secret, self.other_side.rsa_key) if check_auth: logger.info("Checking authenticity") if not Authenticator.check_player( self.username, self.other_side.server_id, self.shared_secret, self.rsa_key): self.kick("Unable to verify username") return rebuild = True elif packet['msgtype'] == 0xfc and self.side == 'server': logger.debug("Starting encryption") self.start_cipher() forward = True if self.plugin_mgr: forwarding = self.plugin_mgr.filter(packet, self.side) if forwarding and packet.modified: rebuild = True if rebuild: packet['raw_bytes'] = self.msg_spec[ packet['msgtype']].emit(packet) if forwarding and self.other_side is not None: self.other_side.send(packet['raw_bytes']) if packet['msgtype'] == 0xfc and self.side == 'server': self.other_side.start_cipher() # Since we know we're at a message boundary, we can inject # any messages in the queue. msgbytes = self.plugin_mgr.next_injected_msg_from(self.side) while self.other_side and msgbytes is not None: self.other_side.send(msgbytes) msgbytes = self.plugin_mgr.next_injected_msg_from( self.side) # Attempt to parse the next packet. packet = parse_packet(self.stream, self.msg_spec, self.side) except PartialPacketException: pass # Not all data for the current packet is available. except Exception: logger.error( "MinecraftProxy for %s caught exception, out of sync" % self.side) logger.error(traceback.format_exc()) logger.debug("Current stream buffer: %s" % repr(self.stream.buf)) self.out_of_sync = True self.stream.reset()
if __name__ == "__main__": logging.basicConfig(level=logging.ERROR) (host, port, opts, pcfg) = parse_args() if opts.logfile: config_logging(opts.logfile) if opts.loglvl: logging.root.setLevel(getattr(logging, opts.loglvl.upper())) if opts.user: while True: password = getpass("Minecraft account password: "******"Authenticating with %s" % opts.user) if auth.check(): break logger.error("Authentication failed") logger.debug("Credentials are valid") if opts.authenticate or opts.password_file: if opts.authenticate: credentials = minecraft_credentials() if credentials is None: logger.error("Can't find password file. " + "Use --user or --password-file option instead.") sys.exit(1) user, password = credentials else:
def _handle_client(self, connection): with closing(connection[0]) as sock: clt_spec, srv_spec = protocol[0] print t.bold("\nConnected to %s:%s" % connection[1]) print t.bold_cyan("\nExpecting Server Ping (0xfe) " + "or Handshake (0x02) packet") packet = parse_packet(sock, clt_spec) if packet['msgtype'] == 0xfe: send_packet(sock, srv_spec, {'msgtype': 0xff, 'reason': 'mc3p debugger'}) return elif packet['msgtype'] != 0x02: raise UnexpectedPacketException(packet['msgtype']) if packet['proto_version'] < 38: print t.bold_red("Error:"), print "Unsupported protocol version" return username = packet['username'] clt_spec, srv_spec = protocol[packet['proto_version']] print t.bold("\nGenerating RSA key pair") key = encryption.generate_key_pair() challenge = encryption.generate_challenge_token() server_id = encryption.generate_server_id() packet = {'msgtype': 0xfd, 'server_id': server_id, 'public_key': encryption.encode_public_key(key), 'challenge_token': challenge} send_packet(sock, srv_spec, packet) packet = parse_packet(sock, clt_spec, 0xfc) try: decrypted_token = encryption.decrypt_shared_secret( packet['challenge_token'], key ) except: decrypted_token = None if decrypted_token is None: try: decrypted_token = key.decrypt(packet['challenge_token']) except: pass if decrypted_token == challenge: print t.bold_red("\nError:"), print ("The challenge token was not padded " + "correctly. See ftp://ftp.rsasecurity.com/pub/" + "pkcs/pkcs-1/pkcs-1v2-1.pdf section 7.2.1 if " + "your library does not support PKCS#1 padding.") else: print t.bold_red("\nError:"), print "The challenge token is not encrypted correctly.\n" print PacketFormatter.bytes(decrypted_token, "Decrypted bytes: ", t.bold) return elif decrypted_token != challenge: print t.bold_red("\nError:"), print "Received challenge token does not", print "match the expected value.\n" print PacketFormatter.bytes(decrypted_token, "Received bytes: ", t.bold) print print PacketFormatter.bytes(challenge, "Expected bytes: ", t.bold) return secret = encryption.decrypt_shared_secret(packet['shared_secret'], key) if secret is None: print t.bold_red("\nError:"), print ("The shared secret was not padded" + "correctly. See ftp://ftp.rsasecurity.com/pub/" + "pkcs/pkcs-1/pkcs-1v2-1.pdf section 7.2.1 if " + "your library does not support PKCS#1 padding.") return print PacketFormatter.bytes(secret, "Shared secret: ", t.bold) if len(secret) != 16: print t.bold_red("\nError:"), print "The shared secret must be 16 bytes long", print "(received length is %s)" % len(secret) return print t.bold_cyan("\nAuthentication") print PacketFormatter.bytes(server_id, "Server ID: ", t.bold) print PacketFormatter.bytes(secret, "Shared secret: ", t.bold) print PacketFormatter.bytes(encryption.encode_public_key(key), "Public key: ", t.bold) print t.bold("Login hash: "), print Authenticator.login_hash(server_id, secret, key) if Authenticator.check_player(username, server_id, secret, key): print t.bold_green("Success:"), "You are authenticated" else: print t.bold_yellow("Warning:"), "You are not authenticated" send_packet(sock, srv_spec, {'msgtype': 0xfc, 'challenge_token': '', 'shared_secret': ''}) print t.bold("\nStarting AES encryption") clt_cipher = encryption.AES128CFB8(secret) srv_cipher = encryption.AES128CFB8(secret) backup_cipher = encryption.AES128CFB8(secret) parse_packet(sock, clt_spec, 0xcd, clt_cipher, backup_cipher) send_packet(sock, srv_spec, {'msgtype': 0x01, 'eid': 1337, 'level_type': 'flat', 'server_mode': 0, 'dimension': 0, 'difficulty': 2, 'unused': 0, 'max_players': 20}, srv_cipher) if self.send_chunks: while True: print packet = parse_packet(sock, clt_spec, cipher=clt_cipher) if packet['msgtype'] == 0x0d: break x, y, z = 5, 9, 5 send_packet(sock, srv_spec, {'msgtype': 0x06, 'x': x, 'y': y, 'z': z}, srv_cipher) send_packet(sock, srv_spec, {'msgtype': 0xca, 'abilities': 0b0100, 'walking_speed': 25, 'flying_speed': 12}, srv_cipher) send_packet(sock, srv_spec, {'msgtype': 0x04, 'time': 0}, srv_cipher) send_packet(sock, srv_spec, multi_chunk_packet(), srv_cipher) send_packet(sock, srv_spec, {'msgtype': 0x0d, 'x': x, 'y': y, 'stance': y + 1.5, 'z': z, 'yaw': 0, 'pitch': 0, 'on_ground': False}, srv_cipher) buffer = StringSocket() send_packet(buffer, srv_spec, {'msgtype': 0x03, 'chat_msg': 'First message'}, srv_cipher) send_packet(buffer, srv_spec, {'msgtype': 0x03, 'chat_msg': 'Second message'}, srv_cipher) sock.sendall(buffer.data) if self.stay_connected: while True: packet = parse_packet(sock, clt_spec, cipher=clt_cipher, title=True) if packet['msgtype'] == 0xff: break elif packet['msgtype'] == 0x00: send_packet(buffer, srv_spec, {'msgtype': 0x00, 'id': 0}, srv_cipher) break else: send_packet(sock, srv_spec, {'msgtype': 0xff, 'reason': "Successfully logged in"}, srv_cipher)
if __name__ == "__main__": logging.basicConfig(level=logging.ERROR) (host, port, opts, pcfg) = parse_args() if opts.logfile: util.config_logging(opts.logfile) if opts.loglvl: logging.root.setLevel(getattr(logging, opts.loglvl.upper())) if opts.user: while True: password = getpass("Minecraft account password: "******"Authenticating with %s" % opts.user) if auth.check(): break logger.error("Authentication failed") logger.debug("Credentials are valid") if opts.authenticate or opts.password_file: if opts.authenticate: credentials = minecraft_credentials() if credentials is None: logger.error("Can't find password file. " + "Use --user or --password-file option instead.") sys.exit(1) user, password = credentials else:
__author__ = 'smileya' from messaging import Message from authentication import Authenticator import urls #https://www.facebook.com/connect/login_success.html#access_token=CAAGm0PX4ZCpsBAKAZCS8vbuNy7hE1zB0jdScFiWPLboaB1hodBvvGmX10lb4ZA51j4tZBslYOo64ckaV2bRoCsRjZBYR3L6cBvsuuMPVAcwJHks9emOPmifDEHbu0IBBOOk0bPQGgZBUF5y5bvlIze3ZBOscHTXCuJIZAIYUrWAQQKpEYKfXzCy5AHAmzpJX5F8pAYZBfAbZAco61Rh0TY7kJZB&expires_in=3857 # ok so we'll need an access token and user ID andrew.smiley.90 # so let's try to send a basic request #guess we should commit too auth = Authenticator("CAAGm0PX4ZCpsBAOcrXW79ctGQ5IERvBr8A2zA5jUSiObrL27Y2bN9qil4VNl5bkKvp1yN1BmcR96f977MBkFpIJQwxWBbIqWY5gfPnRzLAFEFniXrUJTJiGisaMerDXykU85YGN271qATigljzX5AWxRuvJmdcbkrsZBcD5QTIkMMXCgE0RFIdREKZASy8QainaIEpGDrAeF73PZALID", "andrew.smiley.90") auth.login()
def require_basic_auth(): if not app.config.get('AUTHENTICATOR'): app.config['AUTHENTICATOR'] = Authenticator() if request.endpoint != "healthcheck" and not app.config['AUTHENTICATOR'].authenticate(): return Authenticator.challenge()
class SpotifyApi(object): """Interface to make API calls.""" def __init__(self, username): self.username = username """Email or user id.""" self.auth = Authenticator(username) """Handles OAuth 2.0 authentication.""" self._uri_cache = UriCache(username) """Cache of Spotify URIs.""" self.me = None """The Spotify user information.""" # Get authorization. self.auth.authenticate() # Get user information and validate it. self.me = self.get_api_v1("me") if not self.me: raise RuntimeError("Could not get account information.") if (self.me['email'] != username) and (self.me['id'] != username): raise RuntimeError( "\n\n\nInvalid email/user id entered!\n" "You entered: {}\n" "You signed in as: {} (email), {} (user id)".format(username, self.me['email'], self.me['id']) ) def get_email(self): return self.me['email'] def get_id(self): return self.me['id'] def get_display_name(self): return self.me['display_name'] def get_username(self): return self.username def is_premium(self): return self.me['product'] == "premium" def get_market(self): return self.me['country'] @common.async def play(self, track=None, context_uri=None, uris=None, device=None): """Play a Spotify track. Args: track (str, int): The track uri or position. context_uri (str): The context uri. uris (iter): Collection of uris to play. device (Device): A device to play. """ data = {} # Special case when playing a set of uris. if uris: data['uris'] = uris if common.is_int(track): data["offset"] = {"position": track} elif context_uri: # Set the context that we are playing in. data["context_uri"] = context_uri if common.is_int(track): data["offset"] = {"position": track} elif isinstance(track, basestring): data["offset"] = {"uri": track} # No context given, just play the track. elif track is not None and not context_uri: if isinstance(track, basestring) and track.startswith("spotify:track"): data['uris'] = [track] params = {} if device and device['id']: params["device_id"] = device['id'] self.put_api_v1("me/player/play", params, data) @common.async def transfer_playback(self, device, play=False): """Transfer playback to a different Device. Args: device (Device): The Device to transfer playback to. play (bool): Whether to ensure playback happens on new device. """ data = {"device_ids": [device['id']], "play": play} self.put_api_v1("me/player", data=data) @common.async def pause(self): """Pause the player.""" self.put_api_v1("me/player/pause") @common.async def next(self): """Play the next song.""" self.post_api_v1("me/player/next") @common.async def previous(self): """Play the previous song.""" self.post_api_v1("me/player/previous") @common.async def shuffle(self, shuffle): """Set the player to shuffle. Args: shuffle (bool): Whether to shuffle or not. """ q = urllib.urlencode({"state": shuffle}) url = "me/player/shuffle" self.put_api_v1(url, q) @common.async def repeat(self, repeat): """Set the player to repeat. Args: repeat (bool): Whether to repeat or not. """ q = urllib.urlencode({"state": repeat}) url = "me/player/repeat" self.put_api_v1(url, q) @common.async def volume(self, volume): """Set the player volume. Args: volume (int): Volume level. 0 - 100 (inclusive). """ q = urllib.urlencode({"volume_percent": volume}) url = "me/player/volume" self.put_api_v1(url, q) def get_player_state(self): """Returns the player state. The following information is returned: device, repeat_state, shuffle_state, context, timestamp, progress_ms, is_playing, item. Returns: dict: Information containing the player state. """ return self.get_api_v1("me/player") def get_currently_playing(self): """Get the currently playing Track. Returns: Track: The currently playing Track or NoneTrack. """ playing = self.get_api_v1("me/player/currently-playing") if playing: track = playing['item'] if track: playing.update(track) return Track(playing) else: return NoneTrack else: return NoneTrack def get_user_info(self, user_id): """Returns a dict of the a users info. The following information is returned: display_name, external_urls, followers, href, id, images, type, uri. user_id (str): The user_id. Returns: dict: Users information. """ return self.get_api_v1("users/{}".format(user_id)) def get_devices(self): """Return a list of devices with Spotify players running. Returns: list: The Devices. """ results = self.get_api_v1("me/player/devices") if results and "devices" in results: return tuple(Device(device) for device in results['devices']) else: return [] def search(self, types, query, limit=20): """Calls Spotify's search api. Args: types (tuple): Strings of the type of search (i.e, 'artist', 'track', 'album') query (str): The search query. limit (int): Limit of the amount of results to return per type of search in 'types'. Returns: dict: Collection of Artist, Album, and Track objects. """ type_str = ",".join(types) params = {'type': type_str, 'q': query, 'limit': limit} results = self.get_api_v1("search", params) cast = { 'artists': Artist, 'tracks': Track, 'albums': Album, } combined = [] if results: for type in types: # Results are plural (i.e, 'artists', 'albums', 'tracks') type = type + 's' combined.extend([cast[type](info) for info in results[type]['items']]) return combined @uri_cache def get_albums_from_artist(self, artist, type=("album", "single", "appears_on", "compilation"), market=None): """Get Albums from a certain Artist. Args: artist (Artist): The Artist. type (iter): Which types of albums to return. market (str): The market. Default is None which means use the account. Returns: tuple: The Albums. """ q = {"include_groups": ",".join(type), "market": market or self.get_market(), "limit": 50} url = "artists/{}/albums".format(artist['id']) page = self.get_api_v1(url, q) albums = self.extract_page(page) return tuple(Album(album) for album in albums) @uri_cache def get_top_tracks_from_artist(self, artist, market=None): """Get top tracks from a certain Artist. This also returns a pseudo-track to play the Artist context. Args: artist (Artist): The Artist to get Tracks from. market (str): The market. Default is None which means use the account. Returns: tuple: The Tracks. """ q = {"country": market or self.get_market()} url = "artists/{}/top-tracks".format(artist['id']) result = self.get_api_v1(url, q) if result: return tuple(Track(t) for t in result["tracks"]) else: return [] @uri_cache def get_selections_from_artist(self, artist, progress=None): """Return the selection from an Artist. This includes the top tracks and albums from the artist. Args: artist (Artist): The Artist. progress (Progress): Progress associated with this call. Returns: iter: The Tracks and Albums. """ selections = [] selections.extend(self.get_top_tracks_from_artist(artist)) if selections: progress.set_percent(0.5) selections.extend(self.get_albums_from_artist(artist)) if progress: progress.set_percent(1) return selections @uri_cache def get_all_tracks_from_artist(self, artist, progress=None): """Return all tracks from an Artist. This includes the top tracks and albums from the artist. Args: artist (Artist): The Artist. progress (Progress): Progress associated with this call. Returns: iter: The Tracks. """ albums = self.get_albums_from_artist(artist) if albums: n = len(albums) tracks = [] for i, a in enumerate(albums): for t in self.get_tracks_from_album(a): tracks.append(Track(t)) if progress: progress.set_percent(float(i)/n) tracks = (t for t in tracks if artist['name'] in str(t)) return tuple(tracks) @uri_cache def get_tracks_from_album(self, album, progress=None): """Get Tracks from a certain Album. Args: album (Album): The Album to get Tracks from. Returns: tuple: The Tracks. """ q = {"limit": 50} url = "albums/{}/tracks".format(album['id']) page = self.get_api_v1(url, q) tracks = [] for track in self.extract_page(page, progress): track['album'] = album tracks.append(Track(track)) return tuple(tracks) @uri_cache def get_tracks_from_playlist(self, playlist, progress=None): """Get Tracks from a certain Playlist. Args: playlist (Playlist): The Playlist to get Tracks from. progress (Progress): Progress associated with this call. Returns: tuple: The Tracks. """ # Special case for the "Saved" Playlist if playlist['uri'] == common.SAVED_TRACKS_CONTEXT_URI: return self._get_saved_tracks(progress) else: q = {"limit": 50} url = "users/{}/playlists/{}/tracks".format(playlist['owner']['id'], playlist['id']) page = self.get_api_v1(url, q) result = [Track(track["track"]) for track in self.extract_page(page, progress)] return tuple(result) @uri_cache def convert_context(self, context, progress=None): """Convert a Context to an Album, Playlist, or Artist. Args: context (dict): The Context to convert from. progress (Progress): Progress associated with this call. Returns: SpotifyObject: Album, Artist, or Playlist. """ context_type = context["type"] if context_type == "artist": return self.get_artist_from_context(context) elif context_type == common.ALL_ARTIST_TRACKS_CONTEXT_TYPE: return self.get_artist_from_context(context) elif context_type == "album": return self.get_album_from_context(context) elif context_type == "playlist": return self.get_playlist_from_context(context) @uri_cache def get_artist_from_context(self, context): """Return an Artist from a Context. Args: context (dict): The Context to convert from. Returns: Artist: The Artist. """ artist_id = id_from_uri(context["uri"]) result = self.get_api_v1("artists/{}".format(artist_id)) return Artist(result or {}) @uri_cache def get_album_from_context(self, context): """Return an Album from a Context. Args: context (dict): The Context to convert from. Returns: Album: The Album. """ album_id = id_from_uri(context["uri"]) result = self.get_api_v1("albums/{}".format(album_id)) return Album(result or {}) @uri_cache def get_playlist_from_context(self, context): """Return an Playlist from a Context. Args: context (dict): The Context to convert from. Returns: Playlist: The Playlist. """ if context["uri"] == common.SAVED_TRACKS_CONTEXT_URI: # TODO: Consider creating a common/factory function for # obtaining the Saved PLaylist. return Playlist({ "uri":common.SAVED_TRACKS_CONTEXT_URI, "name": "Saved" }) playlist_id = id_from_uri(context["uri"]) result = self.get_api_v1("playlists/{}".format(playlist_id)) return Playlist(result or {}) def add_track_to_playlist(self, track, playlist): """Add a Track to a Playlist. Args: track (Track): The Track to add. playlist (Playlist): The Playlist to add the Track to. Returns: tuple: The new set of Tracks with the new Track added. """ # Add the track. if playlist['uri'] == common.SAVED_TRACKS_CONTEXT_URI: q = {"ids": [track['id']]} url = "me/tracks" self.put_api_v1(url, q) else: q = {"uris": [track['uri']]} url = "playlists/{}/tracks".format(playlist['id']) self.post_api_v1(url, q) # Clear out current Cache. return self.get_tracks_from_playlist(playlist, force_clear=True) def _get_saved_tracks(self, progress=None): """Get the Tracks from the "Saved" songs. Args: progress (Progress): Progress associated with this call. Returns: tuple: The Tracks. """ q = {"limit": 50} url = "me/tracks" page = self.get_api_v1(url, q) return tuple(Track(saved["track"]) for saved in self.extract_page(page, progress)) def get_user(self, user_id=None): """Return a User from an id. Args: user_id (str): The user id. Returns: User: The User. """ if not user_id: user_id = self.get_id() result = self.get_api_v1("users/{}".format(user_id)) if result: return User(result) else: return {} @uri_cache def get_user_playlists(self, user, progress=None): """Get the Playlists from the current user. Args: user (User): The User. progress (Progress): Progress associated with this call. Return: tuple: The Playlists. """ q = {"limit": 50} url = "users/{}/playlists".format(user['id']) page = self.get_api_v1(url, q) return tuple([Playlist(p) for p in self.extract_page(page, progress)]) def extract_page(self, page, progress=None): """Extract all items from a page. Args: page (dict): The page object. progress (Progress): Progress associated with this call. Returns: list: All of the items. """ if page and "items" in page: i, n = 0, page['total'] lists = [] lists.extend(page['items']) while page['next'] is not None: page = self.get_api_v1(page['next'].split('/v1/')[-1]) lists.extend(page['items']) if progress: progress.set_percent(float(len(lists))/n) return lists else: return {} @needs_authentication def get_api_v1(self, endpoint, params=None): """Spotify v1 GET request. Args: endpoint (str): The API endpoint. params (dict): Query parameters (Default is None). Returns: dict: The JSON information. """ headers = {"Authorization": "%s %s" % (self.auth.token_type, self.auth.access_token)} url = "https://api.spotify.com/v1/{}".format(endpoint) resp = requests.get(url, params=params, headers=headers) resp.raise_for_status() data = json.loads(common.ascii(resp.text)) if resp.text else {} if not data: logger.info("GET returned no data") return data @needs_authentication def put_api_v1(self, endpoint, params=None, data=None): """Spotify v1 PUT request. Args: endpoint (str): The API endpoint. params (dict): Query parameters (Default is None). data (dict): Body data (Default is None). Returns: Reponse: The HTTP Reponse. """ headers = {"Authorization": "%s %s" % (self.auth.token_type, self.auth.access_token), "Content-Type": "application/json"} api_url = "https://api.spotify.com/v1/{}".format(endpoint) resp = requests.put(api_url, headers=headers, params=params, json=data) resp.raise_for_status() return resp @needs_authentication def post_api_v1(self, endpoint, params=None): """Spotify v1 POST request. Args: endpoint (str): The API endpoint. params (dict): Query parameters (Default is None). Returns: Reponse: The HTTP Reponse. """ headers = {"Authorization": "%s %s" % (self.auth.token_type, self.auth.access_token), "Content-Type": "application/json"} api_url = "https://api.spotify.com/v1/{}".format(endpoint) resp = requests.post(api_url, headers=headers, params=params) resp.raise_for_status() return common.ascii(resp.text)
def handle_read(self): """Read all available bytes, and process as many packets as possible. """ t = time() if self.last_report + 5 < t and self.stream.tot_bytes > 0: self.last_report = t logger.debug("%s: total/wasted bytes is %d/%d (%f wasted)" % ( self.side, self.stream.tot_bytes, self.stream.wasted_bytes, 100 * float(self.stream.wasted_bytes) / self.stream.tot_bytes)) self.stream.append(self.recv(4092)) if self.out_of_sync: data = self.stream.read(len(self.stream)) self.stream.packet_finished() if self.other_side: self.other_side.send(data) return try: packet = parse_packet(self.stream, self.msg_spec, self.side) while packet != None: rebuild = False if packet['msgtype'] == 0x02 and self.side == 'client': # Determine which protocol message definitions to use. proto_version = packet['proto_version'] logger.info('Client requests protocol version %d' % proto_version) if not proto_version in messages.protocol: logger.error("Unsupported protocol version %d" % proto_version) self.handle_close() return self.username = packet['username'] self.msg_spec, self.other_side.msg_spec = messages.protocol[proto_version] self.cipher = encryption.encryption_for_version(proto_version) self.other_side.cipher = self.cipher elif packet['msgtype'] == 0xfd: self.rsa_key = encryption.decode_public_key( packet['public_key'] ) self.encoded_rsa_key = packet['public_key'] packet['public_key'] = encryption.encode_public_key( self.other_side.rsa_key ) if 'challenge_token' in packet: self.challenge_token = packet['challenge_token'] self.other_side.challenge_token = self.challenge_token self.other_side.server_id = packet['server_id'] if check_auth: packet['server_id'] = encryption.generate_server_id() else: packet['server_id'] = "-" self.server_id = packet['server_id'] rebuild = True elif packet['msgtype'] == 0xfc and self.side == 'client': self.shared_secret = encryption.decrypt_shared_secret( packet['shared_secret'], self.rsa_key ) if (len(self.shared_secret) > 16 and self.cipher == encryption.RC4): logger.error("Unsupported protocol version") self.handle_close() return packet['shared_secret'] = encryption.encrypt_shared_secret( self.other_side.shared_secret, self.other_side.rsa_key ) if 'challenge_token' in packet: challenge_token = encryption.decrypt_shared_secret( packet['challenge_token'], self.rsa_key ) if challenge_token != self.challenge_token: self.kick("Invalid client reply") return packet['challenge_token'] = encryption.encrypt_shared_secret( self.other_side.challenge_token, self.other_side.rsa_key ) if auth: logger.info("Authenticating on server") auth.join_server(self.server_id, self.other_side.shared_secret, self.other_side.rsa_key) if check_auth: logger.info("Checking authenticity") if not Authenticator.check_player( self.username, self.other_side.server_id, self.shared_secret, self.rsa_key): self.kick("Unable to verify username") return rebuild = True elif packet['msgtype'] == 0xfc and self.side == 'server': logger.debug("Starting encryption") self.start_cipher() forward = True if self.plugin_mgr: forwarding = self.plugin_mgr.filter(packet, self.side) if forwarding and packet.modified: rebuild = True if rebuild: packet['raw_bytes'] = self.msg_spec[packet['msgtype']].emit(packet) if forwarding and self.other_side is not None: self.other_side.send(packet['raw_bytes']) if packet['msgtype'] == 0xfc and self.side == 'server': self.other_side.start_cipher() # Since we know we're at a message boundary, we can inject # any messages in the queue. msgbytes = self.plugin_mgr.next_injected_msg_from(self.side) while self.other_side and msgbytes is not None: self.other_side.send(msgbytes) msgbytes = self.plugin_mgr.next_injected_msg_from(self.side) # Attempt to parse the next packet. packet = parse_packet(self.stream,self.msg_spec, self.side) except PartialPacketException: pass # Not all data for the current packet is available. except Exception: logger.error("MinecraftProxy for %s caught exception, out of sync" % self.side) logger.error(traceback.format_exc()) logger.debug("Current stream buffer: %s" % repr(self.stream.buf)) self.out_of_sync = True self.stream.reset()