Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 1 addition & 11 deletions src/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,13 +111,7 @@ async def exec_api_actions(

try:
if http_request.ok:
suffix_req_cost: str = (
"Remaining Requests over Rate-Limit (%s/%s)"
% (
http_request.headers["X-RateLimit-Remaining"],
http_request.headers["X-RateLimit-Limit"],
)
)
suffix_req_cost: str = f'Remaining Requests over Rate-Limit ({http_request.headers["X-RateLimit-Remaining"]}/{http_request.headers["X-RateLimit-Limit"]})'
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function AsyncGithubAPILite.exec_api_actions refactored with the following changes:

This removes the following comments ( why? ):

# Same for this case, but we assert that the data received is malformed.
# So for this case, we special handle it by identifying the message.
# If any of those conditions weren't met, retry again.
# Whenever we tried too much, we don't know if we are rate-limited, because the request will make the ClientResponse.ok set to True.


# For this action, decode the README (base64) in utf-8 (str) then sterilized unnecessary newline.
if action is GithubRunnerActions.FETCH_README:
Expand All @@ -143,15 +137,13 @@ async def exec_api_actions(
)
return None

# If any of those conditions weren't met, retry again.
else:
self.logger.warning(
"Conditions were not met, continuing again after 3 seconds (as a penalty)."
)
await sleep(0.6)
continue

# Same for this case, but we assert that the data received is malformed.
except SyntaxError as e:
self.logger.warning(
f"Fetched Data is either incomplete or malformed. Attempting to re-fetch... | Info: {e} at line {e.__traceback__.tb_lineno}." # type: ignore
Expand All @@ -160,8 +152,6 @@ async def exec_api_actions(
await sleep(0.6)
continue

# Whenever we tried too much, we don't know if we are rate-limited, because the request will make the ClientResponse.ok set to True.
# So for this case, we special handle it by identifying the message.
except KeyError as e:
if serialized_response["message"].startswith(
"API rate limit exceeded"
Expand Down
142 changes: 68 additions & 74 deletions src/badge.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,15 +100,13 @@ async def _handle_b64(
msg: str = f"Passed `action` parameter is not a {Base64Actions}! Please contact the developer if this issue occured in Online Runner."
self.logger.critical(msg)

self.print_exception(GithubRunnerLevelMessages.ERROR, msg, None)
terminate(ExitReturnCodes.ILLEGAL_CONDITION_EXIT)

else:
msg = f"The given value in `ctx_inout` parameter is not a {Base64String.__name__}! Please contact the developer about this issue."
self.logger.error(msg)

self.print_exception(GithubRunnerLevelMessages.ERROR, msg, None)
terminate(ExitReturnCodes.ILLEGAL_CONDITION_EXIT)

self.print_exception(GithubRunnerLevelMessages.ERROR, msg, None)
terminate(ExitReturnCodes.ILLEGAL_CONDITION_EXIT)
Comment on lines -103 to +109
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function BadgeConstructor._handle_b64 refactored with the following changes:


async def check_and_update_badge(self, readme_ctx: Base64String) -> Base64Bytes:
"""
Expand Down Expand Up @@ -155,12 +153,9 @@ async def check_and_update_badge(self, readme_ctx: Base64String) -> Base64Bytes:
)

self.logger.info(
(
f"Badge with Identifier {identifier_name} found! Substituting the old badge."
)
f"Badge with Identifier {identifier_name} found! Substituting the old badge."
if self.envs["BADGE_IDENTIFIER_NAME"] == identifier_name
else "Badge with Identifier (%s) not found! New badge will append on the top of the contents of README.md. Please arrange/move the badge once changes has been pushed!"
% self.envs["BADGE_IDENTIFIER_NAME"]
else f'Badge with Identifier ({self.envs["BADGE_IDENTIFIER_NAME"]}) not found! New badge will append on the top of the contents of README.md. Please arrange/move the badge once changes has been pushed!'
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function BadgeConstructor.check_and_update_badge refactored with the following changes:

)

self.logger.info(
Expand Down Expand Up @@ -293,12 +288,14 @@ async def construct_badge(self) -> BadgeStructure:
picked_activity = ActivityDictName(list(presence_ctx.keys())[0])

self.logger.info(
f"Preferred Activity %s %s"
% (
self.envs["PREFERRED_ACTIVITY_TO_DISPLAY"],
"exists!"
if is_preferred_exists
else f"does not exists. Using other activity such as {picked_activity}.",
(
"Preferred Activity %s %s"
% (
self.envs["PREFERRED_ACTIVITY_TO_DISPLAY"],
"exists!"
if is_preferred_exists
else f"does not exists. Using other activity such as {picked_activity}.",
)
Comment on lines -296 to +298
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function BadgeConstructor.construct_badge refactored with the following changes:

This removes the following comments ( why? ):

# Supposedly have to check for any activity, but we have to be specific here instead.
# ! Special handle for CustomActivity.
# Since activities can display time remaining or elapsed, check the context if timestamps exists so that it can display `remaining` instead of `elapsed`.
# * Also, since this mf doesn't like '+=', let's do the manual with type.
# ! This only works whenever there's an activity and PREFERRED_PRESENCE_CONTEXT or TIME_DISPLAY_OUTPUT is not disabled.
# Display the seperator instead.
# * Otherwise, we don't have to output anything since there's no context to seperate.
# Append the seperator. This one is a condition-hell since we have to consider two other values and the state of the badge.
# * Resolve for the case of `elapsed`.
# ! Seperator #2, Literally invoke the seperator since we assert that the time display is enabled.
# * Appends the User's State whenever presence_ctx is zero or otherwise, append the activity's application name.
# Append the spotify current music if the picked_activity is SPOTIFY_ACTIVITY or else...
# * Appends Activity or User's State if `STATIC_SUBJECT_STRING` is not None, otherwise, use the STATIC_SUBJECT_STRING.

)
)

Expand All @@ -315,8 +312,8 @@ async def construct_badge(self) -> BadgeStructure:
# This is a component of subject_output. Check if we should append User's State instead of Activity State in the Subject.
state_string = "%s_STRING" % (
picked_activity
if picked_activity != PreferredActivityDisplay.CUSTOM_ACTIVITY.name # ! Special handle for CustomActivity.
else "%s_STATUS" % self.user_ctx["statuses"]["status"].name.upper()
if picked_activity != PreferredActivityDisplay.CUSTOM_ACTIVITY.name
else f'{self.user_ctx["statuses"]["status"].name.upper()}_STATUS'
)

# Are there an no activity present and STATIC_SUBJECT_STRING is empty? Then use `BADGE_BASE_SUBJECT`.
Expand All @@ -340,38 +337,39 @@ async def construct_badge(self) -> BadgeStructure:
(
", "
if self.envs["STATUS_CONTEXT_SEPERATOR"] is None
else " %s " % self.envs["STATUS_CONTEXT_SEPERATOR"]
else f' {self.envs["STATUS_CONTEXT_SEPERATOR"]} '
)
# ! This only works whenever there's an activity and PREFERRED_PRESENCE_CONTEXT or TIME_DISPLAY_OUTPUT is not disabled.
# * Otherwise, we don't have to output anything since there's no context to seperate.
if (
self.envs["PREFERRED_PRESENCE_CONTEXT"]
is not ContextOnSubject.CONTEXT_DISABLED
or self.envs["TIME_DISPLAY_OUTPUT"]
is not PreferredTimeDisplay.TIME_DISABLED
)
and picked_activity != PreferredActivityDisplay.CUSTOM_ACTIVITY.name # Supposedly have to check for any activity, but we have to be specific here instead.
and picked_activity
!= PreferredActivityDisplay.CUSTOM_ACTIVITY.name
else ""
)

# As we handle the seperator, we have to handle how we display the string in the status part of the badge.
status_output = BadgeStructure(
( # * Appends Activity or User's State if `STATIC_SUBJECT_STRING` is not None, otherwise, use the STATIC_SUBJECT_STRING.
"%s " % self.envs[state_string]
(
f"{self.envs[state_string]} "
if self.envs["STATIC_SUBJECT_STRING"] is not None
else ""
)
+ (
( # * Appends the User's State whenever presence_ctx is zero or otherwise, append the activity's application name.
self.envs[
"%s_STATUS_STRING"
% self.user_ctx["statuses"]["status"].name.upper()
]
)
self.envs[
f'{self.user_ctx["statuses"]["status"].name.upper()}_STATUS_STRING'
]
if not contains_activities
else presence_ctx[picked_activity]["name" if picked_activity != PreferredActivityDisplay.CUSTOM_ACTIVITY.name else "state"]
else presence_ctx[picked_activity][
"name"
if picked_activity
!= PreferredActivityDisplay.CUSTOM_ACTIVITY.name
else "state"
]
)
+ ( # Append the seperator. This one is a condition-hell since we have to consider two other values and the state of the badge.
+ (
(
seperator # ! Seperator #1, This contains the `PREFERRED_PRESENCE_CONTEXT` of the activity, if available and its a RICH_PRESENCE.
+ (
Expand All @@ -383,33 +381,38 @@ async def construct_badge(self) -> BadgeStructure:
]
)
)
if picked_activity == PreferredActivityDisplay.RICH_PRESENCE.name
if picked_activity
== PreferredActivityDisplay.RICH_PRESENCE.name
and self.envs["PREFERRED_PRESENCE_CONTEXT"]
is not ContextOnSubject.CONTEXT_DISABLED # Other activities is not included at this point since it only gives minimal info.
else ""
)
+ ( # Append the spotify current music if the picked_activity is SPOTIFY_ACTIVITY or else...
seperator
+ (
"{0} by {1}".format(
presence_ctx[picked_activity]["details"],
presence_ctx[picked_activity]["state"],
)
+ (
(
seperator
+ (
(
" (%s)"
% presence_ctx[picked_activity]["assets"]["large_text"]
"{0} by {1}".format(
presence_ctx[picked_activity]["details"],
presence_ctx[picked_activity]["state"],
)
+ (
f' ({presence_ctx[picked_activity]["assets"]["large_text"]})'
if self.envs[
"SPOTIFY_INCLUDE_ALBUM_PLAYLIST_NAME"
]
else ""
)
)
if self.envs["SPOTIFY_INCLUDE_ALBUM_PLAYLIST_NAME"]
else ""
)
)
if picked_activity == PreferredActivityDisplay.SPOTIFY_ACTIVITY.name
if picked_activity
== PreferredActivityDisplay.SPOTIFY_ACTIVITY.name
else seperator
if self.envs["TIME_DISPLAY_OUTPUT"]
is not PreferredTimeDisplay.TIME_DISABLED
and contains_activities
else "" # Display the seperator instead.
else ""
)
)

Expand All @@ -419,16 +422,9 @@ async def construct_badge(self) -> BadgeStructure:
is not PreferredTimeDisplay.TIME_DISABLED
and contains_activities # This handles all activities, no exemptions.
):
# ! Seperator #2, Literally invoke the seperator since we assert that the time display is enabled.
# * Also, since this mf doesn't like '+=', let's do the manual with type.

# Since activities can display time remaining or elapsed, check the context if timestamps exists so that it can display `remaining` instead of `elapsed`.

contains_timestamps: Union[None, str] = presence_ctx[
picked_activity
].get("timestamps")

if contains_timestamps:
if contains_timestamps := presence_ctx[picked_activity].get(
"timestamps"
):
has_remaining: Union[None, str] = presence_ctx[picked_activity][
"timestamps"
].get("end")
Expand Down Expand Up @@ -463,10 +459,9 @@ async def construct_badge(self) -> BadgeStructure:
)

status_output = BadgeStructure(
status_output + f" | {running_time} of {end_time}"
f"{status_output} | {running_time} of {end_time}"
)

# * Resolve for the case of `elapsed`.
else:
time_option: PreferredTimeDisplay = self.envs[
"TIME_DISPLAY_OUTPUT"
Expand Down Expand Up @@ -506,7 +501,7 @@ async def construct_badge(self) -> BadgeStructure:
if time_option is PreferredTimeDisplay.HOURS_MINUTES:
# On this case, calculate if there some minute that can still be converted to hours.
while True:
if parsed_time / 60 >= 1:
if parsed_time >= 60:
hours += 1
parsed_time -= 60
continue
Expand Down Expand Up @@ -541,7 +536,11 @@ async def construct_badge(self) -> BadgeStructure:
status_output = BadgeElements(
status_output
+ (
(f"{hours} %s" % TIME_STRINGS[0] if hours >= 1 else "")
(
f"{hours} %s" % TIME_STRINGS[0]
if hours >= 1
else ""
)
+ (" " if hours and minutes else "")
+ (
f"{minutes} %s" % TIME_STRINGS[1]
Expand All @@ -553,14 +552,7 @@ async def construct_badge(self) -> BadgeStructure:
if seconds >= 1
else ""
)
+ (
f" %s"
% self.envs[
"TIME_DISPLAY_%s_OVERRIDE_STRING" % "ELAPSED"
if not has_remaining
else "REMAINING"
]
)
+ f""" {self.envs['TIME_DISPLAY_ELAPSED_OVERRIDE_STRING' if not has_remaining else "REMAINING"]}"""
)
if is_time_displayable
else "Just started."
Expand Down Expand Up @@ -613,12 +605,14 @@ async def construct_badge(self) -> BadgeStructure:
# Except that instead of focusing in the picked_activity, it was now considering any activity.
subject_color: ColorHEX = ColorHEX(
self.envs[
"%s_COLOR"
% (
"%s_STATUS" % self.user_ctx["statuses"]["status"].name.upper()
if contains_activities
or self.envs["STATIC_SUBJECT_STRING"] is None
else state_string.removesuffix("_STRING")
(
"%s_COLOR"
% (
f'{self.user_ctx["statuses"]["status"].name.upper()}_STATUS'
if contains_activities
or self.envs["STATIC_SUBJECT_STRING"] is None
else state_string.removesuffix("_STRING")
)
)
]
)
Expand Down
17 changes: 5 additions & 12 deletions src/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,7 @@ async def _get_discord_user(self) -> User:
self.user_ctx["discriminator"] = user_info.discriminator

self.logger.info(
"Discord User %s Fetched."
% (self.user_ctx["name"] + self.user_ctx["discriminator"])
f'Discord User {self.user_ctx["name"] + self.user_ctx["discriminator"]} Fetched.'
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function DiscordClientHandler._get_discord_user refactored with the following changes:

)

except NotFound as e:
Expand Down Expand Up @@ -164,21 +163,16 @@ async def _get_activities_via_guild(self, fetched_user: User) -> None:
fetched_user,
)

# Once type checked, fetch the user from guild and fetch it as a member from that guild.
fetched_member: Optional[Member] = fetched_user.mutual_guilds[0].get_member(
if fetched_member := fetched_user.mutual_guilds[0].get_member(
fetched_user.id
)

if (
fetched_member
): # ! Since `get_member` enforce Optional, then we assert here that it will never be Optional or lead to None.
):
if not fetched_member.activities:
self.logger.warning(f"User {fetched_member} doesn't have any activity.")

else:
self.logger.info(
f"User {fetched_member} contains {len(fetched_member.activities)} activit%s."
% ("y" if not len(fetched_member.activities) > 1 else "ies")
% ("y" if len(fetched_member.activities) <= 1 else "ies")
Comment on lines -167 to +175
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function DiscordClientHandler._get_activities_via_guild refactored with the following changes:

  • Use named expression to simplify assignment and conditional (use-named-expression)
  • Simplify logical expression using De Morgan identities [×2] (de-morgan)

This removes the following comments ( why? ):

# ! Since `get_member` enforce Optional, then we assert here that it will never be Optional or lead to None.
# Once type checked, fetch the user from guild and fetch it as a member from that guild.

)

# For every activity exists, we store them uniquely. This means duplicated activities (same activity) will be ignored.
Expand All @@ -190,7 +184,7 @@ async def _get_activities_via_guild(self, fetched_user: User) -> None:
f"Activity Assessment {idx + 1}/{len(fetched_member.activities)} | {each_activities}"
)

if not each_activities.__class__.__name__ in unique_activities:
if each_activities.__class__.__name__ not in unique_activities:
self.logger.debug(
f"Activity {each_activities.__class__.__name__} was not in the list. (The list contains {unique_activities})"
)
Expand Down Expand Up @@ -242,7 +236,6 @@ async def _get_activities_via_guild(self, fetched_user: User) -> None:
)

else:

msg: str = "The requested user -> member (from the guild) does not exists! This was already asserted on the previous methods which means this shoudn't happen in the first place. Please contact the developer about this issue, if persists."
self.logger.error(msg)

Expand Down
Loading