Add notion util
This commit is contained in:
64
src/cloud_util/notion.py
Normal file
64
src/cloud_util/notion.py
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from dataclasses import asdict, dataclass, field
|
||||||
|
|
||||||
|
from notion_client import AsyncClient as Client
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Text:
|
||||||
|
content: str
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class RichText:
|
||||||
|
type: str
|
||||||
|
href: str | None = None
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class RichTextText(RichText):
|
||||||
|
type: str = "text"
|
||||||
|
text: Text = field(default_factory=lambda: Text(content=""))
|
||||||
|
|
||||||
|
|
||||||
|
class NotionAsync:
|
||||||
|
def __init__(self, token: str) -> None:
|
||||||
|
self._client = Client(auth=token)
|
||||||
|
|
||||||
|
def update_token(self, token: str) -> None:
|
||||||
|
self._client.aclose()
|
||||||
|
self._client = Client(auth=token)
|
||||||
|
|
||||||
|
async def block_is_table(self, block_id: str) -> bool:
|
||||||
|
block = await self._client.blocks.retrieve(block_id=block_id)
|
||||||
|
return block["type"] == "table"
|
||||||
|
|
||||||
|
async def get_table_width(self, table_id: str) -> int:
|
||||||
|
table = await self._client.blocks.retrieve(block_id=table_id)
|
||||||
|
return table["table"]["table_width"]
|
||||||
|
|
||||||
|
async def append_table_row_text(self, table_id: str, text_list: list[str]) -> None:
|
||||||
|
cells: list[RichText] = []
|
||||||
|
for content in text_list:
|
||||||
|
cells.append([asdict(RichTextText(text=Text(content)))]) # noqa: PERF401
|
||||||
|
await self.append_table_row(table_id=table_id, cells=cells)
|
||||||
|
|
||||||
|
async def append_table_row(self, table_id: str, cells: list[RichText]) -> None:
|
||||||
|
if not await self.block_is_table(table_id):
|
||||||
|
return
|
||||||
|
table_width = await self.get_table_width(table_id=table_id)
|
||||||
|
if table_width != len(cells):
|
||||||
|
return
|
||||||
|
await self._client.blocks.children.append(
|
||||||
|
block_id=table_id,
|
||||||
|
children=[
|
||||||
|
{
|
||||||
|
"object": "block",
|
||||||
|
"type": "table_row",
|
||||||
|
"table_row": {
|
||||||
|
"cells": cells,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
)
|
||||||
@@ -4,6 +4,7 @@ from fastapi import FastAPI
|
|||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
from src.cloud_util.mqtt import MQTT
|
from src.cloud_util.mqtt import MQTT
|
||||||
|
from src.cloud_util.notion import NotionAsync
|
||||||
from src.cloud_util.ticktick import TickTick
|
from src.cloud_util.ticktick import TickTick
|
||||||
from src.config import Config
|
from src.config import Config
|
||||||
from src.recorder.poo import PooRecorder
|
from src.recorder.poo import PooRecorder
|
||||||
@@ -11,8 +12,9 @@ from src.recorder.poo import PooRecorder
|
|||||||
Config.init()
|
Config.init()
|
||||||
|
|
||||||
ticktick = TickTick()
|
ticktick = TickTick()
|
||||||
|
notion = NotionAsync(token=Config.get_env(key="NOTION_TOKEN"))
|
||||||
mqtt = MQTT()
|
mqtt = MQTT()
|
||||||
poo_recorder = PooRecorder(mqtt)
|
poo_recorder = PooRecorder(mqtt=mqtt, notion=notion)
|
||||||
|
|
||||||
|
|
||||||
@asynccontextmanager
|
@asynccontextmanager
|
||||||
@@ -29,12 +31,14 @@ class PooRecordField(BaseModel):
|
|||||||
app = FastAPI(lifespan=_lifespan)
|
app = FastAPI(lifespan=_lifespan)
|
||||||
|
|
||||||
|
|
||||||
|
# Poo recorder
|
||||||
@app.post("/poo/record")
|
@app.post("/poo/record")
|
||||||
async def record(record_detail: PooRecordField) -> PooRecordField:
|
async def record(record_detail: PooRecordField) -> PooRecordField:
|
||||||
await poo_recorder.record(record_detail.status)
|
await poo_recorder.record(record_detail.status)
|
||||||
return record_detail
|
return record_detail
|
||||||
|
|
||||||
|
|
||||||
|
# ticktick
|
||||||
@app.get("/ticktick/auth/code")
|
@app.get("/ticktick/auth/code")
|
||||||
async def ticktick_auth(code: str, state: str) -> dict:
|
async def ticktick_auth(code: str, state: str) -> dict:
|
||||||
if ticktick.retrieve_access_token(code, state):
|
if ticktick.retrieve_access_token(code, state):
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
from datetime import datetime
|
|
||||||
|
|
||||||
from notion_client import AsyncClient as Client
|
|
||||||
|
|
||||||
from src.config import Config
|
|
||||||
|
|
||||||
|
|
||||||
class NotionClient:
|
|
||||||
def __init__(self) -> None:
|
|
||||||
self._notion = Client(auth=Config.get_env("NOTION_TOKEN"))
|
|
||||||
self._page_id = "3cf594afd0754497ba0a93b94912b897"
|
|
||||||
self._table_id = "9828b56c53de46c794673fe1d01ad522"
|
|
||||||
|
|
||||||
async def note(self, now: datetime, status: str) -> None:
|
|
||||||
formatted_date = now.strftime("%Y-%m-%d")
|
|
||||||
formatted_time = now.strftime("%H:%M")
|
|
||||||
await self._notion.blocks.children.append(
|
|
||||||
block_id=self._table_id,
|
|
||||||
children=[
|
|
||||||
{
|
|
||||||
"object": "block",
|
|
||||||
"type": "table_row",
|
|
||||||
"table_row": {
|
|
||||||
"cells": [
|
|
||||||
[{"type": "text", "text": {"content": formatted_date}}],
|
|
||||||
[{"type": "text", "text": {"content": formatted_time}}],
|
|
||||||
[{"type": "text", "text": {"content": status}}],
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
)
|
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from src.cloud_util.mqtt import MQTT
|
from src.cloud_util.mqtt import MQTT
|
||||||
|
from src.cloud_util.notion import NotionAsync
|
||||||
from src.config import Config
|
from src.config import Config
|
||||||
from src.recorder.notion_handle import NotionClient
|
|
||||||
|
|
||||||
|
|
||||||
class PooRecorder:
|
class PooRecorder:
|
||||||
@@ -14,18 +14,24 @@ class PooRecorder:
|
|||||||
ONLINE = "online"
|
ONLINE = "online"
|
||||||
OFFLINE = "offline"
|
OFFLINE = "offline"
|
||||||
|
|
||||||
def __init__(self, mqtt: MQTT) -> None:
|
def __init__(self, mqtt: MQTT, notion: NotionAsync) -> None:
|
||||||
print("Poo Recorder Initialization...")
|
print("Poo Recorder Initialization...")
|
||||||
self._notion = NotionClient()
|
self._notion = notion
|
||||||
|
self._table_id = Config.get_env("POO_RECORD_NOTION_TABLE_ID")
|
||||||
self._mqtt = mqtt
|
self._mqtt = mqtt
|
||||||
self._mqtt.publish(PooRecorder.CONFIG_TOPIC, PooRecorder.compose_config(), retain=True)
|
self._mqtt.publish(PooRecorder.CONFIG_TOPIC, PooRecorder.compose_config(), retain=True)
|
||||||
self._mqtt.publish(PooRecorder.AVAILABILITY_TOPIC, PooRecorder.ONLINE, retain=True)
|
self._mqtt.publish(PooRecorder.AVAILABILITY_TOPIC, PooRecorder.ONLINE, retain=True)
|
||||||
|
|
||||||
|
async def _note(self, now: datetime, status: str) -> None:
|
||||||
|
formatted_date = now.strftime("%Y-%m-%d")
|
||||||
|
formatted_time = now.strftime("%H:%M")
|
||||||
|
await self._notion.append_table_row_text(self._table_id, [formatted_date, formatted_time, status])
|
||||||
|
|
||||||
async def record(self, status: str) -> None:
|
async def record(self, status: str) -> None:
|
||||||
self._publish_text(status)
|
self._publish_text(status)
|
||||||
now = datetime.now(tz=datetime.now().astimezone().tzinfo)
|
now = datetime.now(tz=datetime.now().astimezone().tzinfo)
|
||||||
self._publish_time(now)
|
self._publish_time(now)
|
||||||
await self._notion.note(now, status)
|
await self._note(now, status)
|
||||||
|
|
||||||
def _publish_text(self, new_text: str) -> None:
|
def _publish_text(self, new_text: str) -> None:
|
||||||
self._mqtt.publish(PooRecorder.AVAILABILITY_TOPIC, PooRecorder.ONLINE, retain=True)
|
self._mqtt.publish(PooRecorder.AVAILABILITY_TOPIC, PooRecorder.ONLINE, retain=True)
|
||||||
|
|||||||
Reference in New Issue
Block a user