[Streams] Minimize Twitch API calls (#4938)

* Minimize the API calls

* Address Jack's review.

* Check for self.id first.

* *inhales*

* Update redbot/cogs/streams/streamtypes.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Apply suggestions from code review

* Update redbot/cogs/streams/streamtypes.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
This commit is contained in:
PredaaA 2021-04-05 22:10:41 +02:00 committed by GitHub
parent 67fa735555
commit 9a7c178db5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -27,7 +27,7 @@ from redbot.core.utils.chat_formatting import humanize_number, humanize_timedelt
TWITCH_BASE_URL = "https://api.twitch.tv"
TWITCH_ID_ENDPOINT = TWITCH_BASE_URL + "/helix/users"
TWITCH_STREAMS_ENDPOINT = TWITCH_BASE_URL + "/helix/streams/"
TWITCH_COMMUNITIES_ENDPOINT = TWITCH_BASE_URL + "/helix/communities"
TWITCH_FOLLOWS_ENDPOINT = TWITCH_ID_ENDPOINT + "/follows"
YOUTUBE_BASE_URL = "https://www.googleapis.com/youtube/v3"
YOUTUBE_CHANNELS_ENDPOINT = YOUTUBE_BASE_URL + "/channels"
@ -352,73 +352,59 @@ class TwitchStream(Stream):
return None, {}
async def is_online(self):
if not self.id:
self.id = await self.fetch_id()
user_profile_data = None
if self.id is None:
user_profile_data = await self._fetch_user_profile()
url = TWITCH_STREAMS_ENDPOINT
params = {"user_id": self.id}
code, data = await self.get_data(url, params)
if code == 200:
if not data["data"]:
stream_code, stream_data = await self.get_data(
TWITCH_STREAMS_ENDPOINT, {"user_id": self.id}
)
if stream_code == 200:
if not stream_data["data"]:
raise OfflineStream()
self.name = data["data"][0]["user_name"]
data = data["data"][0]
data["game_name"] = None
data["followers"] = None
data["view_count"] = None
data["profile_image_url"] = None
data["login"] = None
game_id = data["game_id"]
if game_id:
__, game_data = await self.get_data(
"https://api.twitch.tv/helix/games", {"id": game_id}
)
if game_data:
game_data = game_data["data"][0]
data["game_name"] = game_data["name"]
__, user_data = await self.get_data(
"https://api.twitch.tv/helix/users/follows", {"to_id": self.id}
if user_profile_data is None:
user_profile_data = await self._fetch_user_profile()
final_data = dict.fromkeys(
("game_name", "followers", "login", "profile_image_url", "view_count")
)
if user_data:
followers = user_data["total"]
data["followers"] = followers
__, user_profile_data = await self.get_data(
"https://api.twitch.tv/helix/users", {"id": self.id}
)
if user_profile_data:
profile_image_url = user_profile_data["data"][0]["profile_image_url"]
data["profile_image_url"] = profile_image_url
data["view_count"] = user_profile_data["data"][0]["view_count"]
data["login"] = user_profile_data["data"][0]["login"]
if user_profile_data is not None:
final_data["login"] = user_profile_data["login"]
final_data["profile_image_url"] = user_profile_data["profile_image_url"]
final_data["view_count"] = user_profile_data["view_count"]
is_rerun = False
return self.make_embed(data), is_rerun
elif code == 400:
stream_data = stream_data["data"][0]
final_data["user_name"] = self.name = stream_data["user_name"]
final_data["game_name"] = stream_data["game_name"]
final_data["thumbnail_url"] = stream_data["thumbnail_url"]
final_data["title"] = stream_data["title"]
final_data["type"] = stream_data["type"]
__, follows_data = await self.get_data(TWITCH_FOLLOWS_ENDPOINT, {"to_id": self.id})
if follows_data:
final_data["followers"] = follows_data["total"]
return self.make_embed(final_data), final_data["type"] == "rerun"
elif stream_code == 400:
raise InvalidTwitchCredentials()
elif code == 404:
elif stream_code == 404:
raise StreamNotFound()
else:
raise APIError(data)
raise APIError(stream_data)
async def fetch_id(self):
header = {"Client-ID": str(self._client_id)}
if self._bearer is not None:
header = {**header, "Authorization": f"Bearer {self._bearer}"}
url = TWITCH_ID_ENDPOINT
params = {"login": self.name}
status, data = await self.get_data(url, params)
if status == 200:
async def _fetch_user_profile(self):
code, data = await self.get_data(TWITCH_ID_ENDPOINT, {"login": self.name})
if code == 200:
if not data["data"]:
raise StreamNotFound()
return data["data"][0]["id"]
elif status == 400:
if self.id is None:
self.id = data["data"][0]["id"]
return data["data"][0]
elif code == 400:
raise StreamNotFound()
elif status == 401:
elif code == 401:
raise InvalidTwitchCredentials()
else:
raise APIError(data)