Skip to content

Commit

Permalink
Merge pull request #70 from jphacks/feature/calendar_with_weather
Browse files Browse the repository at this point in the history
Feature/calendar with weather
  • Loading branch information
motty-mio2 authored Nov 18, 2023
2 parents 5a3132f + 66d96d4 commit 26db235
Show file tree
Hide file tree
Showing 8 changed files with 141 additions and 20 deletions.
37 changes: 37 additions & 0 deletions src/alembic/versions/2023_11_18_2152-78f98d411652_.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
"""empty message
Revision ID: 0ea1059c8f7c
Revises: 8bd32b7bb552
Create Date: 2023-11-18 21:52:58.786979
"""
from typing import Sequence, Union

import sqlalchemy as sa

from alembic import op


# revision identifiers, used by Alembic.
revision: str = "0ea1059c8f7c"
down_revision: Union[str, None] = "8bd32b7bb552"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.add_column("session", sa.Column("created_at", sa.DateTime(), nullable=False))
op.add_column("session", sa.Column("weather_code", sa.Integer(), nullable=False))
op.add_column("user", sa.Column("ido_longitude", sa.Float(), nullable=False))
op.add_column("user", sa.Column("keido_latitude", sa.Float(), nullable=False))
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column("user", "keido_latitude")
op.drop_column("user", "ido_longitude")
op.drop_column("session", "weather_code")
op.drop_column("session", "created_at")
# ### end Alembic commands ###
28 changes: 17 additions & 11 deletions src/kb_2315/backend/api/endpoints/calendar.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
from fastapi.responses import PlainTextResponse
from icalendar import Calendar, Event

from kb_2315.backend.crud import crud_sensor, crud_session, crud_shoe
from kb_2315.backend.crud import crud_session, crud_shoe
from kb_2315.backend.models import Session
from kb_2315.backend.weather.code2icon import weather_code2icon


router = APIRouter()
Expand All @@ -14,27 +15,32 @@
@router.get("/")
def get_calendar(shoe_id: int | None = None) -> PlainTextResponse:
JST = timezone(timedelta(hours=+9), "JST")
sessions: list[Session] = crud_session.search_session_by(shoe_id=shoe_id)

if shoe_id is None:
shoe_name: str = "靴"
sessions: list[Session] = crud_session.search_session_by()
else:
shoe_name = crud_shoe.search_shoe_by(shoe_id=shoe_id)[0].name
sessions = crud_session.search_session_by(shoe_id=shoe_id)
shoe_names: dict[int, str] = {}

def _search_shoes(shoe_id: int | None) -> str:
if shoe_id is None:
return "靴"
elif shoe_id in shoe_names.keys():
return shoe_names[shoe_id]
else:
shoe_names[shoe_id] = crud_shoe.search_shoe_by(shoe_id=shoe_id)[0].name
return shoe_names[shoe_id]

cal: Calendar = Calendar()
cal["summary"] = f"{shoe_name} の乾燥記録"
cal["summary"] = f"{_search_shoes(shoe_id=shoe_id)} の乾燥記録"
cal["scale"] = "GREGORIAN"
cal["method"] = "PUBLISH"
cal["X-WR-CALNAME"] = f"{shoe_name} の乾燥記録"
cal["X-WR-CALNAME"] = f"{_search_shoes(shoe_id=shoe_id)} の乾燥記録"
cal["X-WR-TIMEZONE"] = "Asia/Tokyo"

for s in sessions:
try:
last_time: datetime = crud_sensor.search_sensor_by(session_id=s.session_id)[0].time
last_time: datetime = s.created_at

e: Event = Event(
SUMMARY=f"{crud_shoe.search_shoe_by(shoe_id= s.shoe_id)[0].name} を履いた",
SUMMARY=f"天気: { weather_code2icon(s.weather_code)}, {_search_shoes(shoe_id=s.shoe_id)} を履いた",
DTSTART=datetime(
last_time.year, last_time.month, last_time.day, time(7, 0).hour, time(7, 0).minute, tzinfo=JST
)
Expand Down
19 changes: 14 additions & 5 deletions src/kb_2315/backend/api/endpoints/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
from fastapi import APIRouter

from kb_2315 import notify
from kb_2315.backend.crud import crud_session
from kb_2315.backend.crud import crud_session, crud_user
from kb_2315.backend.models import User
from kb_2315.backend.schemas import schema_session
from kb_2315.config import conf

Expand All @@ -13,9 +14,17 @@

@router.get("/")
def create_session(device_id: int) -> schema_session.create_session:
session_id: UUID = crud_session.add_session(device_id=device_id)

notify.line.send_message(message=f"乾燥を開始しました\n{conf.host_url}/analyze/?session_id={session_id}\n\n靴を選んでください")
notify.line.shoe_select_carousel(session_id=session_id)
user: User = crud_user.search_user_by()[0]

session_id: UUID = crud_session.add_session(user=user, device_id=device_id)

notify.line.send_message(
message=f"乾燥を開始しました\n{conf.host_url}/analyze/?session_id={session_id}\n\n靴を選んでください",
send_to_id=user.line_channel_id,
)
notify.line.shoe_select_carousel(
session_id=session_id,
send_to_id=user.line_channel_id,
)

return schema_session.create_session(session_id=session_id)
6 changes: 4 additions & 2 deletions src/kb_2315/backend/crud/crud_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,19 @@

from sqlalchemy.orm import Query

from kb_2315.backend.models import Session
from kb_2315.backend.models import Session, User
from kb_2315.backend.weather import api as weather_api

from .base_crud import base_CRUD


class CRUD_Session(base_CRUD):
def add_session(self, device_id: int, shoe_id: int | None = None) -> UUID:
def add_session(self, user: User, device_id: int, shoe_id: int | None = None) -> UUID:
with self._Session() as session:
new_session = Session()
new_session.shoe_id = shoe_id
new_session.device_id = device_id
new_session.weather_code = weather_api.get_weather_code(user.ido_longitude, user.keido_latitude)

session.add(new_session)
session.commit()
Expand Down
6 changes: 5 additions & 1 deletion src/kb_2315/backend/models/model_session.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import uuid
from datetime import datetime
from typing import TYPE_CHECKING
from uuid import UUID

from sqlalchemy import ForeignKey, Integer, Uuid
from sqlalchemy import DateTime, ForeignKey, Integer, Uuid
from sqlalchemy.orm import Mapped, mapped_column, relationship

from kb_2315.backend.db.base import Base
Expand All @@ -21,4 +22,7 @@ class Session(Base):
device_id: Mapped[int] = mapped_column(Integer, nullable=False)
shoe_id: Mapped[int | None] = mapped_column(Integer, ForeignKey("shoe.id"), nullable=True)

weather_code: Mapped[int] = mapped_column(Integer, nullable=False)
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, nullable=False)

sensors: Mapped[list[Sensor]] = relationship("Sensor", backref="event")
5 changes: 4 additions & 1 deletion src/kb_2315/backend/models/model_user.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from sqlalchemy import Integer, String
from sqlalchemy import Float, Integer, String
from sqlalchemy.orm import Mapped, mapped_column

from kb_2315.backend.db.base import Base
Expand All @@ -8,3 +8,6 @@ class User(Base):
id: Mapped[int] = mapped_column(Integer, primary_key=True)
name: Mapped[str] = mapped_column(String, default="Taro")
line_channel_id: Mapped[str] = mapped_column(String, nullable=True)

ido_longitude: Mapped[float] = mapped_column(Float, nullable=False)
keido_latitude: Mapped[float] = mapped_column(Float, nullable=False)
15 changes: 15 additions & 0 deletions src/kb_2315/backend/weather/api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import requests


def get_weather_code(ido_longitude: float, keido_latitude: float) -> int:
url: str = (
f"https://api.open-meteo.com/v1/forecast?latitude={ido_longitude}&longitude={keido_latitude}"
"&timezone=Asia%2FTokyo&forecast_days&current=weather_code"
)

try:
r = requests.get(url).json()
return r.get("daily").get("weather_code")
except Exception:
# 困ったら曇り
return 2
45 changes: 45 additions & 0 deletions src/kb_2315/backend/weather/code2icon.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
def weather_code2icon(weather_code: int) -> str:
"""
WMO 天気コードを4分類にする
https://open-meteo.com/en/docs
https://www.jodc.go.jp/data_format/weather-code_j.html#:~:text=%E7%8F%BE%E5%9C%A8%E5%A4%A9%E5%80%99(Present%20Weather)%20(WMO%20Code%204677)
"""
if weather_code in ["0", "1"]:
# 晴れ
return "☀"

elif weather_code in ["2", "3"]:
# 曇り
return "☁"

elif weather_code in [
# 雨
"45",
"48",
"51",
"53",
"55",
"56",
"57",
"61",
"63",
"65",
"66",
"67",
"80",
"81",
"82",
"95",
"96",
"99",
]:
return "🌧"

elif weather_code in ["71", "73", "75", "77", "85", "86"]:
# 雪
return "🌨"

# その他
else:
# その他,曇りとする
return "☁"

0 comments on commit 26db235

Please sign in to comment.