diff --git a/main.py b/main.py index a93339f..0c2b677 100644 --- a/main.py +++ b/main.py @@ -1,70 +1,113 @@ -import aiohttp +"""Bring! TRMNL plugin""" + import asyncio +import copy import datetime import os import time +from dataclasses import dataclass, field +from typing import List -from dotenv import load_dotenv - +import aiohttp +from aiohttp.web_exceptions import HTTPException from bring_api import Bring from bring_api.exceptions import BringException +from dotenv import load_dotenv load_dotenv() EXCEPTION_SLEEP_INTERVAL = 60 +PLUGIN_SLEEP_INTERVAL = 60 * 15 # 15 minutes + + +@dataclass +class BringList: + """Represents a Bring list""" + + name: str = "" + uuid: str = "" + items: List[str] = field(default_factory=list) + + def __eq__(self, other): + if isinstance(other, BringList): + return ( + self.name == other.name + and self.uuid == other.uuid + and set(self.items) == set(other.items) + ) + return False + class BringPlugin: - SLEEP_INTERVAL = 15 * 60 # 15 minutes + """ + Class syncing Bring shopping list with TRMNL. + The plugin currently supports only one shopping list. + """ def __init__(self): - self.email = os.getenv('EMAIL') - self.password = os.getenv('PASSWORD') - self.webhook_url = os.getenv('WEBHOOK_URL') - self.items = [] + self.email = os.getenv("EMAIL") + self.password = os.getenv("PASSWORD") + self.webhook_url = os.getenv("WEBHOOK_URL") + self.bring = None + self.existing_list = None - async def grabItems(self): - itemObjs = (await self.bring.get_list(self.list)).items.purchase - items = [item.itemId for item in itemObjs] + async def grab_items(self, bring_list): + """Grabs the items of the list using the list's uuid""" + item_objs = (await self.bring.get_list(bring_list.uuid)).items.purchase + bring_list.items = [item.itemId for item in item_objs] print(f"Successfully fetched items at {datetime.datetime.now().isoformat()}") - print(f"Items = {items}") - return items - - async def sendItemsToTerminal(self, session, items): - if set (self.items) == set(items): - print(f"The items list hasn't changed since the last fetch.") - print(f"Skipping sending updates to TRMNL.") + print(f"Items = {bring_list.items}") + + async def send_list_to_trmnl(self, session, bring_list): + """Sends the list to TRMNL if it has changed""" + if self.existing_list == bring_list: + print("The items list hasn't changed since the last fetch.") + print("Skipping sending updates to TRMNL.") return - self.items = items + self.existing_list = bring_list try: await session.post( self.webhook_url, - json={'merge_variables': {'items': items}}, - headers={'Content-Type': 'application/json'}, - raise_for_status=True) - + json={ + "merge_variables": { + "items": self.existing_list.items, + "list_name": self.existing_list.name, + } + }, + headers={"Content-Type": "application/json"}, + raise_for_status=True, + ) + current_timestamp = datetime.datetime.now().isoformat() print(f"Items sent successfully to TRMNL at {current_timestamp}") - except Exception as e: + except HTTPException as e: print(f"Exception occurred during sending items to TRMNL: {e}") async def run(self): + """Start the plugin""" async with aiohttp.ClientSession() as session: self.bring = Bring(session, self.email, self.password) await self.bring.login() while True: - self.list = (await self.bring.load_lists()).lists[0].listUuid - items = await self.grabItems() - await self.sendItemsToTerminal(session, items) - time.sleep(self.SLEEP_INTERVAL) + new_list = None + if self.existing_list: + new_list = copy.deepcopy(self.existing_list) + else: + bring_api_list = (await self.bring.load_lists()).lists[0] + new_list = BringList(name=bring_api_list.name, uuid=bring_api_list.listUuid) + + await self.grab_items(new_list) + await self.send_list_to_trmnl(session, new_list) + time.sleep(PLUGIN_SLEEP_INTERVAL) if __name__ == "__main__": bring_plugin = BringPlugin() loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) - + while True: try: loop.run_until_complete(bring_plugin.run()) @@ -72,7 +115,7 @@ if __name__ == "__main__": print(f"Bring exception occured: {e}") print(f"Sleeping for {EXCEPTION_SLEEP_INTERVAL} seconds.") time.sleep(EXCEPTION_SLEEP_INTERVAL) - print(f"Retrying the service") + print("Retrying the service") except Exception as e: print(f"Unknown exception occured: {e}") - raise \ No newline at end of file + raise diff --git a/views/full-height.liquid b/views/full-height.liquid index 18f4d1e..6766825 100644 --- a/views/full-height.liquid +++ b/views/full-height.liquid @@ -24,8 +24,7 @@ {% for item in items_to_display %} {% assign number_of_items_displayed = number_of_items_displayed | plus: 1 %}