Save JSON in DB

This commit is contained in:
2024-09-22 11:42:20 +02:00
parent 2be1191a03
commit f914ca6597
6 changed files with 149 additions and 14 deletions

View File

@ -22,6 +22,26 @@ logger: logging.Logger = logging.getLogger(__name__)
image_file_format: Literal["webp"] = "webp"
async def update_scraped_json(model_instance: models.Model, new_json_data: dict) -> None:
"""Update the JSON data for the drop campaign.
Args:
model_instance (models.Model): The Django model instance which must have a 'scraped_json' attribute.
new_json_data (dict): The new JSON data to be updated.
"""
if await sync_to_async(hasattr)(model_instance, "scraped_json"):
if model_instance.scraped_json: # type: ignore[attr-defined]
model_instance.scraped_json.json_data = new_json_data # type: ignore[attr-defined]
await model_instance.scraped_json.asave() # type: ignore[attr-defined]
else:
scraped_json_instance: ScrapedJson = await ScrapedJson.objects.acreate(json_data=new_json_data)
model_instance.scraped_json = scraped_json_instance # type: ignore[attr-defined]
await model_instance.asave()
else:
logger.error("The model instance does not have a 'scraped_json' attribute.")
model_instance.save()
def wrong_typename(data: dict, expected: str) -> bool:
"""Check if the data is the expected type.
@ -170,6 +190,17 @@ def fetch_image(image_url: str) -> bytes | None:
class User(AbstractUser): ...
class ScrapedJson(models.Model):
json_data = models.JSONField(unique=True, help_text="The JSON data from the Twitch API.")
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
ordering: ClassVar[list[str]] = ["-created_at"]
def __str__(self) -> str:
return f"{self.pk}"
class Owner(models.Model):
"""The company or person that owns the game.
@ -296,7 +327,7 @@ class Game(models.Model):
logger.info("Updated %s fields for %s", updated, self)
# Handle the owner of the game.
if owner:
if owner and await sync_to_async(lambda: self not in owner.games.all())(): # type: ignore[attr-defined]
await owner.games.aadd(self) # type: ignore # noqa: PGH003
await self.asave()
logger.info("Added game %s for %s", self, owner)
@ -363,6 +394,13 @@ class DropCampaign(models.Model):
game = models.ForeignKey(Game, on_delete=models.CASCADE, related_name="drop_campaigns", null=True)
scraped_json = models.ForeignKey(
ScrapedJson,
null=True,
on_delete=models.SET_NULL,
help_text="Reference to the JSON data from the Twitch API.",
)
class Meta:
ordering: ClassVar[list[str]] = ["ends_at"]
@ -405,6 +443,9 @@ class DropCampaign(models.Model):
if wrong_typename(data, "DropCampaign"):
return self
# Save the JSON data for debugging purposes.
await update_scraped_json(model_instance=self, new_json_data=data)
field_mapping: dict[str, str] = {
"name": "name",
"accountLinkURL": "account_link_url", # TODO(TheLovinator): Should archive site. # noqa: TD003
@ -601,7 +642,7 @@ class Benefit(models.Model):
if updated > 0:
logger.info("Updated %s fields for %s", updated, self)
if time_based_drop:
if time_based_drop and await sync_to_async(lambda: self not in time_based_drop.benefits.all())(): # type: ignore[attr-defined]
await time_based_drop.benefits.aadd(self) # type: ignore # noqa: PGH003
await time_based_drop.asave()
logger.info("Added benefit %s for %s", self, time_based_drop)
@ -685,6 +726,13 @@ class RewardCampaign(models.Model):
game = models.ForeignKey(Game, on_delete=models.CASCADE, related_name="reward_campaigns", null=True)
scraped_json = models.ForeignKey(
ScrapedJson,
null=True,
on_delete=models.SET_NULL,
help_text="Reference to the JSON data from the Twitch API.",
)
class Meta:
ordering: ClassVar[list[str]] = ["-starts_at"]
@ -719,6 +767,9 @@ class RewardCampaign(models.Model):
if wrong_typename(data, "RewardCampaign"):
return self
# Save the JSON data for debugging purposes.
await update_scraped_json(model_instance=self, new_json_data=data)
field_mapping: dict[str, str] = {
"name": "name",
"brand": "brand",
@ -910,18 +961,18 @@ class Reward(models.Model):
logger.info("Updated %s fields for %s", updated, self)
banner_image_url = data.get("bannerImage", {}).get("image1xURL")
if banner_image_url:
await sync_to_async(self.download_banner_image)()
if banner_image_url != self.banner_image_url:
self.banner_image_url = banner_image_url
await self.asave()
if banner_image_url and banner_image_url != self.banner_image_url:
# await sync_to_async(self.download_banner_image)()
# TODO(TheLovinator): Download the image. # noqa: TD003
self.banner_image_url = banner_image_url
await self.asave()
thumbnail_image_url = data.get("thumbnailImage", {}).get("image1xURL")
if thumbnail_image_url:
await sync_to_async(self.download_thumbnail_image)()
if thumbnail_image_url != self.thumbnail_image_url:
self.thumbnail_image_url = thumbnail_image_url
await self.asave()
if thumbnail_image_url and thumbnail_image_url != self.thumbnail_image_url:
# await sync_to_async(self.download_thumbnail_image)()
# TODO(TheLovinator): Download the image. # noqa: TD003
self.thumbnail_image_url = thumbnail_image_url
await self.asave()
if reward_campaign and await sync_to_async(lambda: reward_campaign != self.campaign)():
self.campaign = reward_campaign