From b0c16675b8d8342c43c155580a8a415f56921202 Mon Sep 17 00:00:00 2001 From: Brais Moure Date: Thu, 15 Feb 2024 22:02:25 +0100 Subject: [PATCH] Supabase API --- link_bio/link_bio/api/ConfigCatAPI.py | 17 ++++++++ link_bio/link_bio/api/SupabaseAPI.py | 11 ++++- link_bio/link_bio/api/TwitchAPI.py | 7 ++-- link_bio/link_bio/api/api.py | 6 ++- link_bio/link_bio/components/featured_link.py | 23 +++++++++++ link_bio/link_bio/model/Featured.py | 7 ++++ link_bio/link_bio/model/Live.py | 6 +++ link_bio/link_bio/pages/courses.py | 2 +- link_bio/link_bio/pages/index.py | 5 +-- link_bio/link_bio/state/PageState.py | 12 +++--- link_bio/link_bio/views/header.py | 9 ++-- link_bio/link_bio/views/index_links.py | 41 ++++++++----------- link_bio/requirements.txt | 3 +- 13 files changed, 103 insertions(+), 46 deletions(-) create mode 100644 link_bio/link_bio/api/ConfigCatAPI.py create mode 100644 link_bio/link_bio/components/featured_link.py create mode 100644 link_bio/link_bio/model/Featured.py create mode 100644 link_bio/link_bio/model/Live.py diff --git a/link_bio/link_bio/api/ConfigCatAPI.py b/link_bio/link_bio/api/ConfigCatAPI.py new file mode 100644 index 00000000..28fd441f --- /dev/null +++ b/link_bio/link_bio/api/ConfigCatAPI.py @@ -0,0 +1,17 @@ +import os +import dotenv +import configcatclient + + +class ConfigCatAPI: + + dotenv.load_dotenv() + + CONFIGCAT_SDK_KEY = os.environ.get("CONFIGCAT_SDK_KEY") + + def __init__(self) -> None: + if self.CONFIGCAT_SDK_KEY != None: + self.configcat = configcatclient.get(self.CONFIGCAT_SDK_KEY) + + def schedule(self) -> str: + self.configcat.get_value("live_schedule", "") diff --git a/link_bio/link_bio/api/SupabaseAPI.py b/link_bio/link_bio/api/SupabaseAPI.py index 74b5e932..26dc0ca3 100644 --- a/link_bio/link_bio/api/SupabaseAPI.py +++ b/link_bio/link_bio/api/SupabaseAPI.py @@ -1,6 +1,7 @@ import os import dotenv from supabase import create_client, Client +from link_bio.model.Featured import Featured class SupabaseAPI: @@ -16,7 +17,7 @@ def __init__(self) -> None: self.SUPABASE_URL, self.SUPABASE_KEY ) - def featured(self) -> list: + def featured(self) -> list[Featured]: response = self.supabase.table("featured").select("*").execute() @@ -24,6 +25,12 @@ def featured(self) -> list: if len(response.data) > 0: for featured_item in response.data: - featured_data.append(featured_item) + featured_data.append( + Featured( + title=featured_item["title"], + image=featured_item["image"], + url=featured_item["url"] + ) + ) return featured_data diff --git a/link_bio/link_bio/api/TwitchAPI.py b/link_bio/link_bio/api/TwitchAPI.py index 34722d28..4eabdb4b 100644 --- a/link_bio/link_bio/api/TwitchAPI.py +++ b/link_bio/link_bio/api/TwitchAPI.py @@ -2,6 +2,7 @@ import dotenv import requests import time +from link_bio.model.Live import Live class TwitchAPI: @@ -37,7 +38,7 @@ def generate_token(self): def token_valid(self) -> bool: return time.time() < self.token_exp - def live(self, user: str) -> dict: + def live(self, user: str) -> Live: if not self.token_valid(): self.generate_token() @@ -52,6 +53,6 @@ def live(self, user: str) -> dict: if response.status_code == 200 and response.json()["data"]: data = response.json()["data"] - return {"live": True, "title": data[0]["title"]} + return Live(live=True, title=data[0]["title"]) - return {"live": False, "title": ""} + return Live(live=False, title="") diff --git a/link_bio/link_bio/api/api.py b/link_bio/link_bio/api/api.py index 4dc8dda6..22c1c434 100644 --- a/link_bio/link_bio/api/api.py +++ b/link_bio/link_bio/api/api.py @@ -1,4 +1,6 @@ import link_bio.constants as const +from link_bio.model.Featured import Featured +from link_bio.model.Live import Live from .TwitchAPI import TwitchAPI from .SupabaseAPI import SupabaseAPI @@ -10,9 +12,9 @@ async def repo() -> str: return const.REPO_URL -async def live(user: str) -> dict: +async def live(user: str) -> Live: return TWITCH_API.live(user) -async def featured() -> list: +async def featured() -> list[Featured]: return SUPABASE_API.featured() diff --git a/link_bio/link_bio/components/featured_link.py b/link_bio/link_bio/components/featured_link.py new file mode 100644 index 00000000..9fcc1c73 --- /dev/null +++ b/link_bio/link_bio/components/featured_link.py @@ -0,0 +1,23 @@ +import reflex as rx +import link_bio.styles.styles as styles +from link_bio.styles.styles import Size +from link_bio.model.Featured import Featured + + +def featured_link(featured: Featured) -> rx.Component: + return rx.link( + rx.vstack( + rx.image( + src=featured.image, + border_radius=Size.DEFAULT.value + ), + rx.text( + featured.title, + style=styles.button_body_style + ), + spacing=Size.SMALL.value, + align_items="start" + ), + href=featured.url, + is_external=True + ) diff --git a/link_bio/link_bio/model/Featured.py b/link_bio/link_bio/model/Featured.py new file mode 100644 index 00000000..1bd6a77c --- /dev/null +++ b/link_bio/link_bio/model/Featured.py @@ -0,0 +1,7 @@ +import reflex as rx + + +class Featured(rx.Base): + title: str + image: str + url: str diff --git a/link_bio/link_bio/model/Live.py b/link_bio/link_bio/model/Live.py new file mode 100644 index 00000000..11e5f522 --- /dev/null +++ b/link_bio/link_bio/model/Live.py @@ -0,0 +1,6 @@ +import reflex as rx + + +class Live(rx.Base): + live: bool + title: str diff --git a/link_bio/link_bio/pages/courses.py b/link_bio/link_bio/pages/courses.py index fa13b7c5..47fa5af7 100644 --- a/link_bio/link_bio/pages/courses.py +++ b/link_bio/link_bio/pages/courses.py @@ -27,7 +27,7 @@ def courses() -> rx.Component: rx.vstack( header( False, - PageState.is_live + live_status=PageState.live_status ), courses_links(), sponsors(), diff --git a/link_bio/link_bio/pages/index.py b/link_bio/link_bio/pages/index.py index 81e63bd9..a89a0230 100644 --- a/link_bio/link_bio/pages/index.py +++ b/link_bio/link_bio/pages/index.py @@ -23,10 +23,7 @@ def index() -> rx.Component: navbar(), rx.center( rx.vstack( - header( - live=PageState.is_live, - live_title=PageState.live_title - ), + header(live_status=PageState.live_status), index_links(PageState.featured_info), sponsors(), max_width=styles.MAX_WIDTH, diff --git a/link_bio/link_bio/state/PageState.py b/link_bio/link_bio/state/PageState.py index 09a808c6..b52c135e 100644 --- a/link_bio/link_bio/state/PageState.py +++ b/link_bio/link_bio/state/PageState.py @@ -1,19 +1,19 @@ +from enum import Flag import reflex as rx from link_bio.api.api import live, featured +from link_bio.model.Featured import Featured +from link_bio.model.Live import Live USER = "mouredev" class PageState(rx.State): - is_live: bool - live_title: str - featured_info: list[dict] + live_status = Live(live=False, title="") + featured_info: list[Featured] async def check_live(self): - live_data = await live(USER) - self.is_live = live_data["live"] - self.live_title = live_data["title"] + self.live_status = await live(USER) async def featured_links(self): self.featured_info = await featured() diff --git a/link_bio/link_bio/views/header.py b/link_bio/link_bio/views/header.py index a53ce49e..f8b4ea63 100644 --- a/link_bio/link_bio/views/header.py +++ b/link_bio/link_bio/views/header.py @@ -1,6 +1,7 @@ import reflex as rx import datetime import link_bio.constants as const +from link_bio.model.Live import Live from link_bio.styles.styles import Size from link_bio.styles.colors import Color, TextColor from link_bio.components.link_icon import link_icon @@ -8,12 +9,12 @@ from link_bio.components.link_button import link_button -def header(details=True, live=False, live_title="") -> rx.Component: +def header(details=True, live_status=Live(live=False, title="")) -> rx.Component: return rx.vstack( rx.hstack( rx.avatar( rx.cond( - live, + live_status.live, rx.link( rx.avatar_badge( rx.image( @@ -102,10 +103,10 @@ def header(details=True, live=False, live_title="") -> rx.Component: width="100%" ), rx.cond( - live, + live_status.live, link_button( "En directo", - live_title, + live_status.title, "/icons/twitch.svg", const.TWITCH_URL, highlight_color=Color.PURPLE.value diff --git a/link_bio/link_bio/views/index_links.py b/link_bio/link_bio/views/index_links.py index e5758ed7..bb29ce24 100644 --- a/link_bio/link_bio/views/index_links.py +++ b/link_bio/link_bio/views/index_links.py @@ -1,12 +1,14 @@ import reflex as rx import link_bio.constants as const +from link_bio.components.featured_link import featured_link +from link_bio.model.Featured import Featured from link_bio.routes import Route from link_bio.components.link_button import link_button from link_bio.components.title import title from link_bio.styles.styles import Size, Color -def index_links(featured=[]) -> rx.Component: +def index_links(featured: list[Featured]) -> rx.Component: return rx.vstack( title("Comunidad"), link_button( @@ -42,28 +44,21 @@ def index_links(featured=[]) -> rx.Component: const.YOUTUBE_SECONDARY_URL ), - # rx.cond( - # len(featured) > 0, - # rx.vstack( - # title("Destacado"), - # rx.foreach( - # featured, - # lambda item: rx.responsive_grid( - # rx.text(item) - # rx.link( - # rx.image( - # src=item["image"] - # ), - # rx.text( - # item["title"] - # ), - # href=item["url"], - # is_external=True - # ) - # ) - # ) - # ) - # ), + rx.cond( + featured, + rx.vstack( + title("Destacado"), + rx.responsive_grid( + rx.foreach( + featured, + featured_link + ), + columns=[1, 2], + spacing=Size.DEFAULT.value + ), + spacing=Size.DEFAULT.value + ) + ), title("Recursos y más"), link_button( diff --git a/link_bio/requirements.txt b/link_bio/requirements.txt index d82923af..917567f0 100644 --- a/link_bio/requirements.txt +++ b/link_bio/requirements.txt @@ -1,3 +1,4 @@ reflex==0.3.10 python-dotenv -supabase \ No newline at end of file +supabase +configcat-client \ No newline at end of file