From 1b2e822cb74986e683b32ac5621dd6a8346a0d4d Mon Sep 17 00:00:00 2001 From: mattiluki <95551442+mattiluki@users.noreply.github.com> Date: Sat, 29 Nov 2025 02:10:42 +0100 Subject: [PATCH 1/2] Add concept overview for Google suite hub --- README.md | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..1a3791a --- /dev/null +++ b/README.md @@ -0,0 +1,58 @@ +# Google Suite Hub (Concept) + +This repository outlines a 4-in-1 personal dashboard that brings together Gmail, Google Tasks, Google Calendar, and a simple Habits tracker once authenticated with your Google account. + +## What it does +- **Unified sign-in**: Uses Google OAuth to request consent for Gmail, Tasks, and Calendar scopes. +- **Inbox snapshot**: Reads recent messages (Gmail) for quick triage. +- **Tasks board**: Surfaces Google Tasks lists and items for the signed-in user. +- **Calendar glance**: Shows upcoming events across calendars. +- **Habits**: Stores lightweight habit check-ins locally (separate from Google data) so you can see habits next to Google data. + +## Architecture sketch +- **Frontend**: Web UI (SPA or server-rendered) that hits a backend API after OAuth completes. +- **Backend**: Handles OAuth code exchange, stores tokens securely, and calls Google APIs. +- **Data storage**: A small database (e.g., SQLite/PostgreSQL) to persist user profiles, refresh tokens, and habit logs. +- **Google APIs**: Gmail API, Google Tasks API, Google Calendar API via REST (e.g., google-api-python-client). + +## OAuth setup (required) +1. Create a Google Cloud project. +2. Enable Gmail API, Google Tasks API, and Google Calendar API. +3. Configure OAuth consent screen and authorized redirect URIs. +4. Create OAuth 2.0 Client ID (Web application) and note the **Client ID** and **Client secret**. +5. Set environment variables for local development (example): + ```bash + export GOOGLE_CLIENT_ID="your-client-id" + export GOOGLE_CLIENT_SECRET="your-client-secret" + export OAUTH_REDIRECT_URI="http://localhost:8000/oauth/callback" + ``` + +## Minimal flow (backend) +1. Redirect the user to Google's OAuth URL with scopes: + - `https://www.googleapis.com/auth/gmail.readonly` + - `https://www.googleapis.com/auth/tasks.readonly` + - `https://www.googleapis.com/auth/calendar.readonly` +2. Exchange the authorization code for access + refresh tokens. +3. Persist tokens securely (per user) along with token expiry. +4. Use access tokens to call the respective APIs: + - Gmail: `users.messages.list` for recent messages. + - Tasks: `tasks.list` for the default list. + - Calendar: `events.list` for upcoming events. +5. Render aggregated data to the UI alongside locally stored habits. + +## Habits data model (local) +- `habit` table: `id`, `user_id`, `name`, `cadence` (e.g., daily/weekly), `created_at`. +- `habit_checkin` table: `id`, `habit_id`, `date`, `status` (done/skipped/partial). + +## Development checklist +- [ ] Choose a framework (e.g., FastAPI, Flask, or Next.js with API routes). +- [ ] Add OAuth endpoints (`/auth/login`, `/oauth/callback`). +- [ ] Implement token storage and refresh handling. +- [ ] Add Google API clients for Gmail, Tasks, Calendar. +- [ ] Create Habit CRUD + check-in endpoints. +- [ ] Build a dashboard UI that combines all data sources. + +## Notes and constraints +- This repo currently contains documentation only; the actual implementation requires configuring a Google Cloud project and secrets. +- Keep secrets out of version control; use environment variables or a secrets manager. +- When adding code, avoid try/catch around imports to keep import failures visible. From e9fd8c979cd6a0f7370219f9fc8315e3005c5017 Mon Sep 17 00:00:00 2001 From: mattiluki <95551442+mattiluki@users.noreply.github.com> Date: Sat, 29 Nov 2025 02:20:34 +0100 Subject: [PATCH 2/2] Add Flask demo dashboard with mock data --- README.md | 41 +++++++++++------ app.py | 89 +++++++++++++++++++++++++++++++++++ requirements.txt | 1 + templates/index.html | 107 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 223 insertions(+), 15 deletions(-) create mode 100644 app.py create mode 100644 requirements.txt create mode 100644 templates/index.html diff --git a/README.md b/README.md index 1a3791a..e73aa0f 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,24 @@ -# Google Suite Hub (Concept) +# Google Suite Hub (demo) -This repository outlines a 4-in-1 personal dashboard that brings together Gmail, Google Tasks, Google Calendar, and a simple Habits tracker once authenticated with your Google account. +Repo zawiera działającą, lokalną wersję demo 4‑w‑1: Gmail, Google Tasks, Google Calendar oraz Habits. Obecnie dane są przykładowe (mock), ale architektura i UI są gotowe do podpięcia prawdziwych usług Google przez OAuth. -## What it does -- **Unified sign-in**: Uses Google OAuth to request consent for Gmail, Tasks, and Calendar scopes. -- **Inbox snapshot**: Reads recent messages (Gmail) for quick triage. -- **Tasks board**: Surfaces Google Tasks lists and items for the signed-in user. -- **Calendar glance**: Shows upcoming events across calendars. -- **Habits**: Stores lightweight habit check-ins locally (separate from Google data) so you can see habits next to Google data. +## Co już działa +- **Dashboard webowy** (Flask + Jinja) z kartami: Gmail, Tasks, Calendar, Habits. +- **Przykładowe dane** po stronie backendu, żeby zobaczyć wygląd i układ aplikacji od razu po uruchomieniu. + +## Jak uruchomić lokalne demo +1. Upewnij się, że masz Python 3.11+. +2. Zainstaluj zależności: + ```bash + pip install -r requirements.txt + ``` +3. Uruchom serwer developerski: + ```bash + flask --app app run + ``` +4. Wejdź w przeglądarce na `http://localhost:5000` – zobaczysz połączony widok Gmail/Tasks/Calendar/Habits z mock danymi. + +> **Tip:** Kod szablonu jest w `templates/index.html`, a dane generuje `app.py` w funkcjach `mock_*`. ## Architecture sketch - **Frontend**: Web UI (SPA or server-rendered) that hits a backend API after OAuth completes. @@ -45,14 +56,14 @@ This repository outlines a 4-in-1 personal dashboard that brings together Gmail, - `habit_checkin` table: `id`, `habit_id`, `date`, `status` (done/skipped/partial). ## Development checklist -- [ ] Choose a framework (e.g., FastAPI, Flask, or Next.js with API routes). -- [ ] Add OAuth endpoints (`/auth/login`, `/oauth/callback`). -- [ ] Implement token storage and refresh handling. -- [ ] Add Google API clients for Gmail, Tasks, Calendar. -- [ ] Create Habit CRUD + check-in endpoints. -- [ ] Build a dashboard UI that combines all data sources. +- [x] Wybrać framework (Flask) i zbudować UI demo. +- [ ] Dodać endpointy OAuth (`/auth/login`, `/oauth/callback`). +- [ ] Zaimplementować przechowywanie/odświeżanie tokenów. +- [ ] Podłączyć klientów Google API (Gmail, Tasks, Calendar) zamiast mocków. +- [ ] Dodać CRUD na Habits + check-iny. +- [ ] Zintegrować realne dane z widokiem dashboardu. ## Notes and constraints -- This repo currently contains documentation only; the actual implementation requires configuring a Google Cloud project and secrets. +- Demo używa danych przykładowych; produkcyjnie trzeba skonfigurować Google Cloud project i sekrety. - Keep secrets out of version control; use environment variables or a secrets manager. - When adding code, avoid try/catch around imports to keep import failures visible. diff --git a/app.py b/app.py new file mode 100644 index 0000000..0d835c9 --- /dev/null +++ b/app.py @@ -0,0 +1,89 @@ +from __future__ import annotations + +from dataclasses import dataclass +from datetime import datetime, timedelta +from typing import List + +from flask import Flask, render_template + +app = Flask(__name__) + + +@dataclass +class Email: + sender: str + subject: str + received_at: datetime + snippet: str + + +@dataclass +class Task: + title: str + due: datetime | None + status: str + + +@dataclass +class CalendarEvent: + title: str + starts_at: datetime + ends_at: datetime + location: str | None = None + + +@dataclass +class Habit: + name: str + streak: int + note: str | None = None + + +def mock_emails() -> List[Email]: + now = datetime.utcnow() + return [ + Email("team@project.io", "Sprint review notes", now - timedelta(hours=1), "Nagranie i notatki z wczoraj"), + Email("billing@saas.com", "Faktura czerwiec", now - timedelta(hours=5), "Dziękujemy za płatność"), + Email("alerts@monitoring.io", "Status page update", now - timedelta(days=1), "Wszystkie systemy operacyjne"), + ] + + +def mock_tasks() -> List[Task]: + tomorrow = datetime.utcnow() + timedelta(days=1) + return [ + Task("Przygotować dema dla klienta", tomorrow, "in-progress"), + Task("Zaplanować posty na bloga", None, "todo"), + Task("Domknąć sprint", tomorrow + timedelta(days=1), "todo"), + ] + + +def mock_events() -> List[CalendarEvent]: + today = datetime.utcnow().replace(hour=9, minute=0, second=0, microsecond=0) + return [ + CalendarEvent("Status tygodniowy", today, today + timedelta(hours=1), "Meet"), + CalendarEvent("Demo klienta", today + timedelta(hours=2), today + timedelta(hours=3), "Zoom"), + CalendarEvent("1:1", today + timedelta(hours=4), today + timedelta(hours=4, minutes=30)), + ] + + +def mock_habits() -> List[Habit]: + return [ + Habit("Ćwiczenia", 5, "Poranny trening 20 min"), + Habit("Pisanie dziennika", 12, "3 rzeczy za które jesteś wdzięczny"), + Habit("Nauka", 7, "30 minut kursu"), + ] + + +@app.route("/") +def home(): + return render_template( + "index.html", + emails=mock_emails(), + tasks=mock_tasks(), + events=mock_events(), + habits=mock_habits(), + ) + + +if __name__ == "__main__": + app.run(debug=True) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..95fef4e --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +Flask==3.0.3 diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..e2d7292 --- /dev/null +++ b/templates/index.html @@ -0,0 +1,107 @@ + + +
+ + +Prosty, działający demo-front: Gmail, Tasks, Calendar i Habits z przykładowymi danymi.
+ +