def from_data(cls, data: ExtDict, user_2: Union[ExtDict, AbstractUser], client: Client) -> FriendRequest: user_1 = AbstractUser( name=data.get(Index.REQUEST_SENDER_NAME, "unknown"), id=data.getcast(Index.REQUEST_SENDER_ID, 0, int), account_id=data.getcast(Index.REQUEST_SENDER_ACCOUNT_ID, 0, int), client=client, ) if isinstance(user_2, ExtDict): user_2 = AbstractUser(**user_2, client=client) indicator = data.getcast(Index.REQUEST_INDICATOR, 0, int) is_normal = indicator ^ 1 return cls( id=data.getcast(Index.REQUEST_ID, 0, int), timestamp=str(data.get(Index.REQUEST_TIMESTAMP, "unknown")), body=Coder.do_base64(data.get(Index.REQUEST_BODY, ""), encode=False, errors="replace"), is_read=(not data.get(Index.REQUEST_STATUS)), author=(user_1 if is_normal else user_2), recipient=(user_2 if is_normal else user_1), type=MessageOrRequestType.from_value(indicator, 0), client=client, )
def from_data(cls, data: ExtDict, user_2: Union[ExtDict, AbstractUser], client: Client) -> Message: user_1 = AbstractUser( name=data.get(Index.MESSAGE_SENDER_NAME, "unknown"), id=data.getcast(Index.MESSAGE_SENDER_ID, 0, int), account_id=data.getcast(Index.MESSAGE_SENDER_ACCOUNT_ID, 0, int), client=client, ) if isinstance(user_2, ExtDict): user_2 = AbstractUser(**user_2, client=client) indicator = data.getcast(Index.MESSAGE_INDICATOR, 0, int) is_normal = indicator ^ 1 subject = Coder.do_base64(data.get(Index.MESSAGE_SUBJECT, ""), encode=False, errors="replace") return Message( id=data.getcast(Index.MESSAGE_ID, 0, int), timestamp=data.get(Index.MESSAGE_TIMESTAMP, "unknown"), subject=subject, is_read=bool(data.getcast(Index.MESSAGE_IS_READ, 0, int)), author=(user_1 if is_normal else user_2), recipient=(user_2 if is_normal else user_1), type=MessageOrRequestType.from_value(indicator, 0), client=client, )
def from_data(cls, data: ExtDict, type: str = "normal", *, client: Client) -> AbstractUser: return cls( account_id=data.getcast(Index.USER_ACCOUNT_ID, 0, int), id=data.getcast(Index.USER_PLAYER_ID, 0, int), name=data.get(Index.USER_NAME, "unknown"), client=client, )
def from_data(cls, data: ExtDict, *, custom: bool = True, client: Client) -> Song: return cls( # name and author - cp1252 encoding seems to fix weird characters - Alex1304 name=fix_song_encoding(data.get(Index.SONG_TITLE, "unknown")), author=fix_song_encoding(data.get(Index.SONG_AUTHOR, "unknown")), id=data.getcast(Index.SONG_ID, 0, int), size=data.getcast(Index.SONG_SIZE, 0.0, float), links=dict( normal=Route.NEWGROUNDS_SONG_LISTEN + data.get(Index.SONG_ID, ""), download=unquote(data.get(Index.SONG_URL, "")), ), custom=custom, client=client, )
def from_data(cls, data: ExtDict, client: Client) -> UserStats: return cls( account_id=data.getcast(Index.USER_ACCOUNT_ID, 0, int), name=data.get(Index.USER_NAME, "unknown"), id=data.getcast(Index.USER_PLAYER_ID, 0, int), stars=data.getcast(Index.USER_STARS, 0, int), demons=data.getcast(Index.USER_DEMONS, 0, int), cp=data.getcast(Index.USER_CREATOR_POINTS, 0, int), diamonds=data.getcast(Index.USER_DIAMONDS, 0, int), coins=data.getcast(Index.USER_COINS, 0, int), secret_coins=data.getcast(Index.USER_SECRET_COINS, 0, int), place=data.getcast(Index.USER_TOP_PLACE, 0, int), client=client, )
def from_data(cls, data: ExtDict, client: Client) -> Gauntlet: try: level_ids = tuple(map(int, data.get(Index.GAUNTLET_LEVEL_IDS, "").split(","))) except ValueError: level_ids = () gid = data.getcast(Index.GAUNTLET_ID, 0, int) name = Converter.get_gauntlet_name(gid) return cls(id=gid, name=name, level_ids=level_ids, client=client)
def from_data(cls, data: ExtDict, author: Union[ExtDict, AbstractUser], client: Client) -> Comment: if isinstance(author, ExtDict): if any(key.isdigit() for key in author.keys()): author = AbstractUser.from_data(author, client=client) else: author = AbstractUser(**author, client=client) color_string = data.get(Index.COMMENT_COLOR, "255,255,255") color = Color.from_rgb(*map(int, color_string.split(","))) return cls( body=Coder.do_base64(data.get(Index.COMMENT_BODY, ""), encode=False, errors="replace"), rating=data.getcast(Index.COMMENT_RATING, 0, int), timestamp=data.get(Index.COMMENT_TIMESTAMP, "unknown"), id=data.getcast(Index.COMMENT_ID, 0, int), is_spam=bool(data.getcast(Index.COMMENT_IS_SPAM, 0, int)), type=CommentType.from_value( data.getcast(Index.COMMENT_TYPE, 0, int), 0), color=color, level_id=data.getcast(Index.COMMENT_LEVEL_ID, 0, int), level_percentage=data.getcast(Index.COMMENT_LEVEL_PERCENTAGE, -1, int), author=author, client=client, )
def from_data(cls, data: ExtDict, client: Client) -> MapPack: try: level_ids = tuple(map(int, data.get(Index.MAP_PACK_LEVEL_IDS, "").split(","))) except ValueError: level_ids = () color_string = data.get(Index.MAP_PACK_COLOR, "255,255,255") color = Color.from_rgb(*map(int, color_string.split(","))) difficulty = Converter.value_to_pack_difficulty( data.getcast(Index.MAP_PACK_DIFFICULTY, 0, int) ) return cls( id=data.getcast(Index.MAP_PACK_ID, 0, int), name=data.get(Index.MAP_PACK_NAME, "unknown"), level_ids=level_ids, stars=data.getcast(Index.MAP_PACK_STARS, 0, int), coins=data.getcast(Index.MAP_PACK_COINS, 0, int), difficulty=difficulty, color=color, client=client, )
async def get_level_comments( self, level_id: int, strategy: CommentStrategy, amount: int, exclude: Tuple[Type[BaseException]] = (), ) -> List[Tuple[ExtDict, ExtDict]]: # comment, user payload = ( Params() .create_new() .put_definer("levelid", level_id) .put_page(0) .put_total(0) .put_mode(strategy.value) .put_count(amount) .finish() ) codes = { -1: MissingAccess(f"Failed to get comments of a level by ID: {level_id!r}."), -2: NothingFound("gd.Comment"), } resp = await self.http.request( Route.GET_COMMENTS, payload, error_codes=codes, exclude=exclude ) if resp is None: return [] splitted = Parser().split("#").take(0).split("|").parse(resp) parser = Parser().with_split("~").should_map() res = [] for elem in filter(is_not_empty, splitted): com_data, user_data, *_ = map(parser.parse, elem.split(":")) com_data.update({"1": level_id, "101": 0, "102": 0}) user_data = ExtDict( account_id=user_data.getcast(Index.USER_ACCOUNT_ID, 0, int), id=com_data.getcast(Index.COMMENT_AUTHOR_ID, 0, int), name=user_data.get(Index.USER_NAME, "unknown"), ) res.append((com_data, user_data)) return res
def from_data(cls, data: ExtDict, strategy: LevelLeaderboardStrategy, client: Client) -> LevelRecord: return cls( account_id=data.getcast(Index.USER_ACCOUNT_ID, 0, int), name=data.get(Index.USER_NAME, "unknown"), id=data.getcast(Index.USER_PLAYER_ID, 0, int), level_id=data.getcast(Index.USER_LEVEL_ID, 0, int), place=data.getcast(Index.USER_TOP_PLACE, 0, int), percentage=data.getcast(Index.USER_PERCENT, 0, int), coins=data.getcast(Index.USER_SECRET_COINS, 0, int), timestamp=data.get(Index.USER_RECORD_TIMESTAMP, "unknown"), type=strategy, client=client, )
def from_data( cls, data: ExtDict, creator: Union[ExtDict, AbstractUser], song: Union[ExtDict, Song], client: Client, ) -> Level: if isinstance(creator, ExtDict): creator = AbstractUser(**creator, client=client) if isinstance(song, ExtDict): if any(key.isdigit() for key in song.keys()): song = Song.from_data(song, client=client) else: song = Song(**song, client=client) string = data.get(Index.LEVEL_PASS) if string is None: copyable, password = False, None else: if string == ZERO_STR: copyable, password = False, None else: try: # decode password password = Coder.decode(type="levelpass", string=string) except Exception: # failed to get password copyable, password = False, None else: copyable = True if not password: password = None else: # password is in format 1XXXXXX password = password[1:] password = int(password) if password.isdigit() else None desc = Coder.do_base64( data.get(Index.LEVEL_DESCRIPTION, ""), encode=False, errors="replace" ) level_data = data.get(Index.LEVEL_DATA, "") try: level_data = Coder.unzip(level_data) except Exception: # conversion failed pass diff = data.getcast(Index.LEVEL_DIFFICULTY, 0, int) demon_diff = data.getcast(Index.LEVEL_DEMON_DIFFICULTY, 0, int) is_demon = bool(data.getcast(Index.LEVEL_IS_DEMON, 0, int)) is_auto = bool(data.getcast(Index.LEVEL_IS_AUTO, 0, int)) difficulty = Converter.convert_level_difficulty( diff=diff, demon_diff=demon_diff, is_demon=is_demon, is_auto=is_auto ) return cls( id=data.getcast(Index.LEVEL_ID, 0, int), name=data.get(Index.LEVEL_NAME, "unknown"), description=desc, version=data.getcast(Index.LEVEL_VERSION, 0, int), creator=creator, song=song, data=level_data, password=password, copyable=copyable, is_demon=is_demon, is_auto=is_auto, low_detail_mode=bool(data.get(Index.LEVEL_HAS_LDM)), difficulty=difficulty, stars=data.getcast(Index.LEVEL_STARS, 0, int), coins=data.getcast(Index.LEVEL_COIN_COUNT, 0, int), verified_coins=bool(data.getcast(Index.LEVEL_COIN_VERIFIED, 0, int)), is_epic=bool(data.getcast(Index.LEVEL_IS_EPIC, 0, int)), original=data.getcast(Index.LEVEL_ORIGINAL, 0, int), downloads=data.getcast(Index.LEVEL_DOWNLOADS, 0, int), rating=data.getcast(Index.LEVEL_LIKES, 0, int), score=data.getcast(Index.LEVEL_FEATURED_SCORE, 0, int), uploaded_timestamp=data.get(Index.LEVEL_UPLOADED_TIMESTAMP, "unknown"), last_updated_timestamp=data.get(Index.LEVEL_LAST_UPDATED_TIMESTAMP, "unknown"), length=LevelLength.from_value(data.getcast(Index.LEVEL_LENGTH, 0, int), "XL"), game_version=data.getcast(Index.LEVEL_GAME_VERSION, 0, int), stars_requested=data.getcast(Index.LEVEL_REQUESTED_STARS, 0, int), object_count=data.getcast(Index.LEVEL_OBJECT_COUNT, 0, int), type=TimelyType.from_value(data.getcast(Index.LEVEL_TIMELY_TYPE, 0, int), 0), time_n=data.getcast(Index.LEVEL_TIMELY_INDEX, -1, int), cooldown=data.getcast(Index.LEVEL_TIMELY_COOLDOWN, -1, int), client=client, )
def from_data(cls, data: ExtDict, client: Client) -> User: youtube = data.get(Index.USER_YOUTUBE, "") youtube = { "normal": youtube, "link": "https://www.youtube.com/channel/" + youtube } twitter = data.get(Index.USER_TWITTER, "") twitter = {"normal": twitter, "link": "https://twitter.com/" + twitter} twitch = data.get(Index.USER_TWITCH, "") twitch = {"normal": twitch, "link": "https://twitch.tv/" + twitch} return cls( name=data.get(Index.USER_NAME, "unknown"), id=data.getcast(Index.USER_PLAYER_ID, 0, int), stars=data.getcast(Index.USER_STARS, 0, int), demons=data.getcast(Index.USER_DEMONS, 0, int), secret_coins=data.getcast(Index.USER_SECRET_COINS, 0, int), coins=data.getcast(Index.USER_COINS, 0, int), cp=data.getcast(Index.USER_CREATOR_POINTS, 0, int), diamonds=data.getcast(Index.USER_DIAMONDS, 0, int), role=data.getcast(Index.USER_ROLE, 0, int), global_rank=data.getcast(Index.USER_GLOBAL_RANK, None, int), account_id=data.getcast(Index.USER_ACCOUNT_ID, 0, int), youtube=youtube, twitter=twitter, twitch=twitch, message_policy=MessagePolicyType.from_value( data.getcast(Index.USER_PRIVATE_MESSAGE_POLICY, 0, int), 0), friend_request_policy=FriendRequestPolicyType.from_value( data.getcast(Index.USER_FRIEND_REQUEST_POLICY, 0, int), 0), comment_policy=CommentPolicyType.from_value( data.getcast(Index.USER_COMMENT_HISTORY_POLICY, 0, int), 0), icon_setup=IconSet( main_icon=data.getcast(Index.USER_ICON, 1, int), color_1=colors[data.getcast(Index.USER_COLOR_1, 0, int)], color_2=colors[data.getcast(Index.USER_COLOR_2, 0, int)], main_icon_type=IconType.from_value( data.getcast(Index.USER_ICON_TYPE, 0, int), 0), has_glow_outline=bool( data.getcast(Index.USER_GLOW_OUTLINE_2, 0, int)), icon_cube=data.getcast(Index.USER_ICON_CUBE, 1, int), icon_ship=data.getcast(Index.USER_ICON_SHIP, 1, int), icon_ball=data.getcast(Index.USER_ICON_BALL, 1, int), icon_ufo=data.getcast(Index.USER_ICON_UFO, 1, int), icon_wave=data.getcast(Index.USER_ICON_WAVE, 1, int), icon_robot=data.getcast(Index.USER_ICON_ROBOT, 1, int), icon_spider=data.getcast(Index.USER_ICON_SPIDER, 1, int), icon_explosion=data.getcast(Index.USER_EXPLOSION, 1, int), client=client, ), client=client, )