Parse json messages on autosync

This commit is contained in:
Zoe Roux 2024-03-21 00:34:11 +01:00
parent 22d0d064f7
commit a8fe8e2e13
No known key found for this signature in database
12 changed files with 49 additions and 13 deletions

View File

@ -1,13 +1,22 @@
import json import logging
import os import os
import dataclasses_json
import pika import pika
from pika import spec from pika import spec
from pika.adapters.blocking_connection import BlockingChannel from pika.adapters.blocking_connection import BlockingChannel
import pika.credentials import pika.credentials
from datetime import date, datetime
from autosync.models.message import Message
from autosync.services.aggregate import Aggregate from autosync.services.aggregate import Aggregate
from autosync.services.simkl import Simkl from autosync.services.simkl import Simkl
dataclasses_json.cfg.global_config.encoders[date] = date.isoformat
dataclasses_json.cfg.global_config.decoders[date] = date.fromisoformat
dataclasses_json.cfg.global_config.encoders[datetime] = datetime.isoformat
dataclasses_json.cfg.global_config.decoders[datetime] = datetime.fromisoformat
logging.basicConfig(level=logging.INFO)
service = Aggregate([Simkl()]) service = Aggregate([Simkl()])
@ -17,8 +26,12 @@ def on_message(
properties: spec.BasicProperties, properties: spec.BasicProperties,
body: bytes, body: bytes,
): ):
status = json.loads(body) try:
status = Message.from_json(body)
service.update(status.user, status.resource, status) service.update(status.user, status.resource, status)
except Exception as e:
logging.exception("Error processing message.", exc_info=e)
logging.exception("Body: %s", body)
def main(): def main():
@ -41,4 +54,5 @@ def main():
channel.basic_consume( channel.basic_consume(
queue=queue_name, on_message_callback=on_message, auto_ack=True queue=queue_name, on_message_callback=on_message, auto_ack=True
) )
logging.info("Listening for autosync.")
channel.start_consuming() channel.start_consuming()

View File

@ -1,9 +1,10 @@
from typing import Literal from typing import Literal
from dataclasses import dataclass from dataclasses import dataclass
from dataclasses_json import dataclass_json, LetterCase
from .metadataid import MetadataID from .metadataid import MetadataID
@dataclass_json(letter_case=LetterCase.CAMEL)
@dataclass @dataclass
class Episode: class Episode:
external_id: dict[str, MetadataID] external_id: dict[str, MetadataID]

View File

@ -1,4 +1,5 @@
from dataclasses import dataclass from dataclasses import dataclass
from dataclasses_json import dataclass_json, LetterCase
from autosync.models.episode import Episode from autosync.models.episode import Episode
from autosync.models.movie import Movie from autosync.models.movie import Movie
@ -7,12 +8,14 @@ from autosync.models.user import User
from autosync.models.watch_status import WatchStatus from autosync.models.watch_status import WatchStatus
@dataclass_json(letter_case=LetterCase.CAMEL)
@dataclass @dataclass
class WatchStatusMessage(WatchStatus): class WatchStatusMessage(WatchStatus):
user: User user: User
resource: Movie | Show | Episode resource: Movie | Show | Episode
@dataclass_json(letter_case=LetterCase.CAMEL)
@dataclass @dataclass
class Message: class Message:
action: str action: str

View File

@ -1,7 +1,9 @@
from dataclasses import dataclass from dataclasses import dataclass
from dataclasses_json import dataclass_json, LetterCase
from typing import Optional from typing import Optional
@dataclass_json(letter_case=LetterCase.CAMEL)
@dataclass @dataclass
class MetadataID: class MetadataID:
data_id: str data_id: str

View File

@ -1,10 +1,12 @@
from typing import Literal, Optional from typing import Literal, Optional
from datetime import date from datetime import date
from dataclasses import dataclass from dataclasses import dataclass
from dataclasses_json import dataclass_json, LetterCase
from .metadataid import MetadataID from .metadataid import MetadataID
@dataclass_json(letter_case=LetterCase.CAMEL)
@dataclass @dataclass
class Movie: class Movie:
name: str name: str

View File

@ -1,10 +1,12 @@
from typing import Literal, Optional from typing import Literal, Optional
from datetime import date from datetime import date
from dataclasses import dataclass from dataclasses import dataclass
from dataclasses_json import dataclass_json, LetterCase
from .metadataid import MetadataID from .metadataid import MetadataID
@dataclass_json(letter_case=LetterCase.CAMEL)
@dataclass @dataclass
class Show: class Show:
name: str name: str

View File

@ -1,8 +1,10 @@
from datetime import datetime, time from datetime import datetime, time
from dataclasses import dataclass from dataclasses import dataclass
from dataclasses_json import dataclass_json, LetterCase
from typing import Optional from typing import Optional
@dataclass_json(letter_case=LetterCase.CAMEL)
@dataclass @dataclass
class JwtToken: class JwtToken:
token_type: str token_type: str
@ -12,6 +14,7 @@ class JwtToken:
expire_at: datetime expire_at: datetime
@dataclass_json(letter_case=LetterCase.CAMEL)
@dataclass @dataclass
class ExternalToken: class ExternalToken:
id: str id: str
@ -20,6 +23,7 @@ class ExternalToken:
token: JwtToken token: JwtToken
@dataclass_json(letter_case=LetterCase.CAMEL)
@dataclass @dataclass
class User: class User:
id: str id: str

View File

@ -1,21 +1,23 @@
from datetime import date from datetime import date
from dataclasses import dataclass from dataclasses import dataclass
from dataclasses_json import dataclass_json, LetterCase
from typing import Optional from typing import Optional
from enum import Enum from enum import Enum
class Status(str, Enum): class Status(str, Enum):
COMPLETED = "completed" COMPLETED = "Completed"
WATCHING = "watching" WATCHING = "Watching"
DROPED = "droped" DROPED = "Droped"
PLANNED = "planned" PLANNED = "Planned"
DELETED = "deleted" DELETED = "Deleted"
@dataclass_json(letter_case=LetterCase.CAMEL)
@dataclass @dataclass
class WatchStatus: class WatchStatus:
added_date: date added_date: date
played_date: date played_date: Optional[date]
status: Status status: Status
watched_time: Optional[int] watched_time: Optional[int]
watched_percent: Optional[int] watched_percent: Optional[int]

View File

@ -18,4 +18,9 @@ class Aggregate(Service):
def update(self, user: User, resource: Movie | Show | Episode, status: WatchStatus): def update(self, user: User, resource: Movie | Show | Episode, status: WatchStatus):
for service in self._services: for service in self._services:
try:
service.update(user, resource, status) service.update(user, resource, status)
except Exception as e:
logging.exception(
"Unhandled error on autosync %s:", service.name, exc_info=e
)

View File

@ -1,5 +1,4 @@
import os import os
from typing_extensions import assert_type
import requests import requests
import logging import logging

View File

@ -1,2 +1,3 @@
pika pika
requets requests
dataclasses-json

View File

@ -7,6 +7,7 @@
watchfiles watchfiles
pika pika
requests requests
dataclasses-json
]); ]);
dotnet = with pkgs.dotnetCorePackages; dotnet = with pkgs.dotnetCorePackages;
combinePackages [ combinePackages [