Initial commit: epaper-dashboard for 7.3" ACeP 7-Color display
- dashboard.py: plugin-based renderer with 4x4 grid layout - admin.py: web UI with layout editor + plugin configs - layout.py: pack algorithm, item placement, grid system - plugins/: clock, weather, system, spotify, strava, gmail, minimax, hello - network_watchdog.py: WiFi AP/client mode management - waveshare_epd_init.py: vendor driver stub
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
"""Gmail Unread - responsive."""
|
||||
import os, sys, json
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
|
||||
from plugins.base import Widget
|
||||
from palette import FG, INFO, OK, WARN, measure, fit_font, centered_text, is_small, is_wide
|
||||
|
||||
|
||||
class Widget(Widget):
|
||||
name = "gmail"
|
||||
label = "Gmail Unread"
|
||||
description = "Anzahl ungelesener Emails im Posteingang."
|
||||
category = "info"
|
||||
|
||||
config_schema = [
|
||||
{"key": "oauth_token_json", "label": "OAuth Token (JSON)", "type": "secret",
|
||||
"help": "token.json aus einem einmaligen OAuth-Flow."},
|
||||
]
|
||||
default_config = {"oauth_token_json": ""}
|
||||
|
||||
def fetch(self):
|
||||
tok = self.cfg("oauth_token_json")
|
||||
if not tok:
|
||||
return {"_error": "OAuth-Token fehlt"}
|
||||
try:
|
||||
from google.oauth2.credentials import Credentials
|
||||
from google.auth.transport.requests import Request
|
||||
from googleapiclient.discovery import build
|
||||
creds = Credentials.from_authorized_user_info(json.loads(tok))
|
||||
if creds.expired and creds.refresh_token:
|
||||
creds.refresh(Request())
|
||||
service = build("gmail", "v1", credentials=creds, cache_discovery=False)
|
||||
label = service.users().labels().get(userId="me", id="INBOX").execute()
|
||||
return {"unread": label.get("messagesUnread", 0)}
|
||||
except ImportError:
|
||||
return {"_error": "google-api-python-client nicht installiert"}
|
||||
except Exception as e:
|
||||
return {"_error": str(e)}
|
||||
|
||||
def render(self, draw, fonts, x, y, w, h):
|
||||
pad = 8
|
||||
draw.text((x + pad, y + pad), "GMAIL", font=fonts.get("24", fonts.get("20")), fill=INFO)
|
||||
d = self.fetch()
|
||||
if "_error" in d:
|
||||
font = fit_font(draw, "Konfig fehlt", fonts, w - 2 * pad, h - 80)
|
||||
centered_text(draw, "Konfig fehlt", x, y + 60, w, h - 60, font, WARN)
|
||||
return
|
||||
unread = d["unread"]
|
||||
color = OK if unread == 0 else WARN if unread < 10 else FG
|
||||
text = str(unread)
|
||||
# Big number centered
|
||||
if is_small(w, h):
|
||||
font = fit_font(draw, text, fonts, w - 2 * pad, h - 50)
|
||||
centered_text(draw, text, x, y, w, h - 30, font, color)
|
||||
else:
|
||||
font = fit_font(draw, text, fonts, w - 2 * pad, int(h * 0.6))
|
||||
centered_text(draw, text, x, y, w, int(h * 0.6), font, color)
|
||||
font_lbl = fit_font(draw, "Ungelesen", fonts, w - 2 * pad, 24)
|
||||
centered_text(draw, "Ungelesen", x, y + int(h * 0.7), w, h // 5, font_lbl, FG)
|
||||
Reference in New Issue
Block a user