Compare commits
No commits in common. "6206898fb127a464aa191baf67075cf819f546f5" and "6b1fb30171327a87629a4558fb74724b37d4d953" have entirely different histories.
6206898fb1
...
6b1fb30171
|
@ -317,5 +317,5 @@ func (e *EPD) sendImg(img image.Image) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func isdark(r, g, b, _ uint32) bool {
|
func isdark(r, g, b, _ uint32) bool {
|
||||||
return r < 65535 || g < 65535 || b < 65535
|
return r < 255 || g < 255 || b < 255
|
||||||
}
|
}
|
||||||
|
|
11
fete/fete.go
|
@ -5,6 +5,7 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/carlmjohnson/requests"
|
"github.com/carlmjohnson/requests"
|
||||||
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
@ -82,6 +83,16 @@ func (c *Client) GetFete(ctx context.Context, date time.Time) (res *Fete, err er
|
||||||
err = requests.URL("https://fetedujour.fr").
|
err = requests.URL("https://fetedujour.fr").
|
||||||
Pathf("/api/v2/%v/json-normal-%d-%d", c.config.APIKey, date.Day(), date.Month()).
|
Pathf("/api/v2/%v/json-normal-%d-%d", c.config.APIKey, date.Day(), date.Month()).
|
||||||
UserAgent("e-paper-display").
|
UserAgent("e-paper-display").
|
||||||
|
AddValidator(func(resp *http.Response) error {
|
||||||
|
if resp.StatusCode >= 400 {
|
||||||
|
body, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Fete API error: %s, %s", resp.Header, string(body))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}).
|
||||||
Client(c.client).
|
Client(c.client).
|
||||||
ToJSON(&res).
|
ToJSON(&res).
|
||||||
Fetch(ctx)
|
Fetch(ctx)
|
||||||
|
|
BIN
icons/01d.png
Before Width: | Height: | Size: 945 B |
BIN
icons/02d.png
Before Width: | Height: | Size: 1.6 KiB |
BIN
icons/03d.png
Before Width: | Height: | Size: 837 B |
BIN
icons/04d.png
Before Width: | Height: | Size: 1.8 KiB |
BIN
icons/09d.png
Before Width: | Height: | Size: 2.6 KiB |
BIN
icons/10d.png
Before Width: | Height: | Size: 2.5 KiB |
BIN
icons/11d.png
Before Width: | Height: | Size: 2.8 KiB |
BIN
icons/13d.png
Before Width: | Height: | Size: 1.7 KiB |
BIN
icons/50d.png
Before Width: | Height: | Size: 650 B |
156
img.go
|
@ -2,60 +2,43 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"embed"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/Crocmagnon/display-epaper/epd"
|
"github.com/Crocmagnon/display-epaper/epd"
|
||||||
"github.com/Crocmagnon/display-epaper/fete"
|
"github.com/Crocmagnon/display-epaper/fete"
|
||||||
"github.com/Crocmagnon/display-epaper/quotes"
|
|
||||||
"github.com/Crocmagnon/display-epaper/transports"
|
"github.com/Crocmagnon/display-epaper/transports"
|
||||||
"github.com/Crocmagnon/display-epaper/weather"
|
|
||||||
"github.com/llgcode/draw2d"
|
"github.com/llgcode/draw2d"
|
||||||
"github.com/llgcode/draw2d/draw2dimg"
|
"github.com/llgcode/draw2d/draw2dimg"
|
||||||
"image"
|
"image"
|
||||||
"image/color"
|
"image/color"
|
||||||
"log"
|
|
||||||
"math"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:embed icons
|
|
||||||
var icons embed.FS
|
|
||||||
|
|
||||||
const (
|
|
||||||
leftX = 20
|
|
||||||
rightX = 530
|
|
||||||
)
|
|
||||||
|
|
||||||
func getBlack(
|
func getBlack(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
nowFunc func() time.Time,
|
nowFunc func() time.Time,
|
||||||
transportsClient *transports.Client,
|
transportsClient *transports.Client,
|
||||||
feteClient *fete.Client,
|
feteClient *fete.Client,
|
||||||
weatherClient *weather.Client,
|
|
||||||
) (*image.RGBA, error) {
|
) (*image.RGBA, error) {
|
||||||
bus, err := transportsClient.GetTCLPassages(ctx, 290)
|
bus, err := transportsClient.GetTCLPassages(ctx, 290)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error getting bus:", err)
|
return nil, fmt.Errorf("getting bus: %w", err)
|
||||||
}
|
}
|
||||||
tram, err := transportsClient.GetTCLPassages(ctx, 34068)
|
tram, err := transportsClient.GetTCLPassages(ctx, 34068)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error getting tram:", err)
|
return nil, fmt.Errorf("getting tram: %w", err)
|
||||||
}
|
}
|
||||||
velovRoc, err := transportsClient.GetVelovStation(ctx, 10044)
|
velovRoc, err := transportsClient.GetVelovStation(ctx, 10044)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error getting velov:", err)
|
return nil, fmt.Errorf("getting velov: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fetes, err := feteClient.GetFete(ctx, nowFunc())
|
fetes, err := feteClient.GetFete(ctx, nowFunc())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error getting fetes:", err)
|
return nil, fmt.Errorf("getting fetes: %w", err)
|
||||||
}
|
}
|
||||||
wthr, err := weatherClient.GetWeather(ctx)
|
|
||||||
if err != nil {
|
_ = fetes
|
||||||
log.Println("error getting weather:", err)
|
|
||||||
}
|
|
||||||
quote := quotes.GetQuote(nowFunc())
|
|
||||||
|
|
||||||
img := newWhite()
|
img := newWhite()
|
||||||
|
|
||||||
|
@ -65,100 +48,36 @@ func getBlack(
|
||||||
gc.SetFillColor(color.RGBA{255, 255, 255, 255})
|
gc.SetFillColor(color.RGBA{255, 255, 255, 255})
|
||||||
gc.SetStrokeColor(color.RGBA{0, 0, 0, 255})
|
gc.SetStrokeColor(color.RGBA{0, 0, 0, 255})
|
||||||
|
|
||||||
drawTCL(gc, bus, 55)
|
rect(gc, 0, 0, 800, 480)
|
||||||
drawTCL(gc, tram, 190)
|
|
||||||
drawVelov(gc, velovRoc, 350)
|
drawTCL(gc, bus, 30)
|
||||||
drawDate(gc, nowFunc())
|
drawTCL(gc, tram, 150)
|
||||||
drawFete(gc, fetes)
|
drawVelov(gc, velovRoc, 290)
|
||||||
drawWeather(gc, wthr)
|
drawDateFete(gc, fetes, nowFunc())
|
||||||
drawQuote(gc, quote)
|
|
||||||
|
|
||||||
return img, nil
|
return img, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func drawQuote(gc *draw2dimg.GraphicContext, quote string) {
|
|
||||||
text(gc, quote, 15, leftX, 450)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func drawWeather(gc *draw2dimg.GraphicContext, wthr *weather.Prevision) {
|
|
||||||
if wthr == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(wthr.Daily) == 0 || len(wthr.Daily[0].Weather) == 0 {
|
|
||||||
log.Println("missing daily or daily weather")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
daily := wthr.Daily[0]
|
|
||||||
dailyWeather := daily.Weather[0]
|
|
||||||
err := drawWeatherIcon(gc, dailyWeather)
|
|
||||||
if err != nil {
|
|
||||||
log.Println("Failed to draw weather icon:", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
text(gc, formatTemp(wthr.Current.Temp), 23, leftX, 120)
|
|
||||||
|
|
||||||
text(gc, "max "+formatTemp(daily.Temp.Max), 18, 120, 45)
|
|
||||||
text(gc, fmt.Sprintf("pluie %v%%", int(math.Round(daily.Pop*100))), 18, 120, 80)
|
|
||||||
text(gc, dailyWeather.Description, 18, 120, 115)
|
|
||||||
}
|
|
||||||
|
|
||||||
func drawWeatherIcon(gc *draw2dimg.GraphicContext, dailyWeather weather.Weather) error {
|
|
||||||
icon := strings.TrimSuffix(dailyWeather.Icon, "d")
|
|
||||||
icon = strings.TrimSuffix(icon, "n")
|
|
||||||
f, err := icons.Open(fmt.Sprintf("icons/%sd.png", icon))
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("opening icon: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
img, _, err := image.Decode(f)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("decoding icon: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
gc.DrawImage(img)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func formatTemp(temp float64) string {
|
|
||||||
return fmt.Sprintf("%v°C", int(math.Round(temp)))
|
|
||||||
}
|
|
||||||
|
|
||||||
func drawVelov(gc *draw2dimg.GraphicContext, station *transports.Station, yOffset float64) {
|
func drawVelov(gc *draw2dimg.GraphicContext, station *transports.Station, yOffset float64) {
|
||||||
if station == nil {
|
x := float64(600)
|
||||||
return
|
text(gc, station.Name, 15, x, yOffset)
|
||||||
|
text(gc, fmt.Sprintf("V : %v - P : %v", station.BikesAvailable, station.DocksAvailable), 15, x, yOffset+30)
|
||||||
|
//text(gc, fmt.Sprintf("P : %v", station.DocksAvailable), 15, x, yOffset+60)
|
||||||
}
|
}
|
||||||
|
|
||||||
text(gc, station.Name, 23, rightX, yOffset)
|
func drawDateFete(gc *draw2dimg.GraphicContext, fetes *fete.Fete, now time.Time) {
|
||||||
text(gc, fmt.Sprintf("V : %v - P : %v", station.BikesAvailable, station.DocksAvailable), 23, rightX, yOffset+30)
|
text(gc, now.Format("15:04"), 40, 20, 190)
|
||||||
}
|
text(gc, getDate(now), 50, 20, 255)
|
||||||
|
text(gc, fetes.Name, 18, 20, 290)
|
||||||
func drawDate(gc *draw2dimg.GraphicContext, now time.Time) {
|
|
||||||
text(gc, now.Format("15:04"), 110, leftX, 300)
|
|
||||||
text(gc, getDate(now), 30, leftX, 345)
|
|
||||||
}
|
|
||||||
|
|
||||||
func drawFete(gc *draw2dimg.GraphicContext, fetes *fete.Fete) {
|
|
||||||
if fetes == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
text(gc, fmt.Sprintf("On fête les %s", fetes.Name), 18, leftX, 380)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func drawTCL(gc *draw2dimg.GraphicContext, passages *transports.Passages, yoffset float64) {
|
func drawTCL(gc *draw2dimg.GraphicContext, passages *transports.Passages, yoffset float64) {
|
||||||
if passages == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, passage := range passages.Passages {
|
for i, passage := range passages.Passages {
|
||||||
x := float64(rightX + i*120)
|
x := float64(600 + i*100)
|
||||||
text(gc, passage.Ligne, 23, x, yoffset)
|
text(gc, passage.Ligne, 15, x, yoffset)
|
||||||
for j, delay := range passage.Delays {
|
for j, delay := range passage.Delays {
|
||||||
y := yoffset + float64(j+1)*35
|
y := yoffset + float64(j+1)*30
|
||||||
text(gc, delay, 23, x, y)
|
text(gc, delay, 15, x, y)
|
||||||
if j >= 2 { // limit number of delays displayed
|
if j >= 2 { // limit number of delays displayed
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -171,6 +90,8 @@ func text(gc *draw2dimg.GraphicContext, s string, size, x, y float64) {
|
||||||
gc.SetFontData(draw2d.FontData{Name: fontName})
|
gc.SetFontData(draw2d.FontData{Name: fontName})
|
||||||
gc.SetFontSize(size)
|
gc.SetFontSize(size)
|
||||||
gc.FillStringAt(s, x, y)
|
gc.FillStringAt(s, x, y)
|
||||||
|
gc.SetLineWidth(2)
|
||||||
|
gc.StrokeStringAt(s, x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newWhite() *image.RGBA {
|
func newWhite() *image.RGBA {
|
||||||
|
@ -194,28 +115,7 @@ func rect(gc *draw2dimg.GraphicContext, x1, y1, x2, y2 float64) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func getDate(now time.Time) string {
|
func getDate(now time.Time) string {
|
||||||
return fmt.Sprintf("%v %v %v", getDow(now), getDay(now), getMonth(now))
|
return fmt.Sprintf("%v %v", getDay(now), getMonth(now))
|
||||||
}
|
|
||||||
|
|
||||||
func getDow(now time.Time) string {
|
|
||||||
switch now.Weekday() {
|
|
||||||
case time.Monday:
|
|
||||||
return "lun"
|
|
||||||
case time.Tuesday:
|
|
||||||
return "mar"
|
|
||||||
case time.Wednesday:
|
|
||||||
return "mer"
|
|
||||||
case time.Thursday:
|
|
||||||
return "jeu"
|
|
||||||
case time.Friday:
|
|
||||||
return "ven"
|
|
||||||
case time.Saturday:
|
|
||||||
return "sam"
|
|
||||||
case time.Sunday:
|
|
||||||
return "dim"
|
|
||||||
}
|
|
||||||
|
|
||||||
return "?"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func getDay(now time.Time) string {
|
func getDay(now time.Time) string {
|
||||||
|
|
8
main.go
|
@ -4,7 +4,6 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"github.com/Crocmagnon/display-epaper/fete"
|
"github.com/Crocmagnon/display-epaper/fete"
|
||||||
"github.com/Crocmagnon/display-epaper/transports"
|
"github.com/Crocmagnon/display-epaper/transports"
|
||||||
"github.com/Crocmagnon/display-epaper/weather"
|
|
||||||
"github.com/golang/freetype/truetype"
|
"github.com/golang/freetype/truetype"
|
||||||
"github.com/llgcode/draw2d"
|
"github.com/llgcode/draw2d"
|
||||||
_ "golang.org/x/image/bmp"
|
_ "golang.org/x/image/bmp"
|
||||||
|
@ -35,12 +34,7 @@ func main() {
|
||||||
CacheLocation: os.Getenv("FETE_CACHE_LOCATION"),
|
CacheLocation: os.Getenv("FETE_CACHE_LOCATION"),
|
||||||
})
|
})
|
||||||
|
|
||||||
weatherClient := weather.New(nil, weather.Config{
|
if err := run(ctx, transportsClient, feteClient); err != nil {
|
||||||
APIKey: os.Getenv("WEATHER_API_KEY"),
|
|
||||||
CacheLocation: os.Getenv("WEATHER_CACHE_LOCATION"),
|
|
||||||
})
|
|
||||||
|
|
||||||
if err := run(ctx, transportsClient, feteClient, weatherClient); err != nil {
|
|
||||||
log.Fatal("error: ", err)
|
log.Fatal("error: ", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
405
quotes/data.go
|
@ -1,405 +0,0 @@
|
||||||
package quotes
|
|
||||||
|
|
||||||
// Courtesy of ChatGPT.
|
|
||||||
|
|
||||||
var january = [31]string{
|
|
||||||
"La nouvelle année commence toujours mieux avec du pain frais.",
|
|
||||||
"Un bon pétrissage vaut plus que mille discours.",
|
|
||||||
"Pour un pain bien cuit, patience et chaleur sont de mise.",
|
|
||||||
"À four ouvert, pâte brûlée.",
|
|
||||||
"Le pain partagé est toujours meilleur.",
|
|
||||||
"On ne fait pas lever la pâte en la pressant.",
|
|
||||||
"Pain croustillant, matin gagnant.",
|
|
||||||
"Sans sel dans la pâte, le pain reste fade.",
|
|
||||||
"Il faut du temps pour faire lever le meilleur des pains.",
|
|
||||||
"Qui veut une croûte dorée doit savoir attendre.",
|
|
||||||
"Une farine bien tamisée fait la mie plus fine.",
|
|
||||||
"Même la mie la plus tendre a besoin de croûte.",
|
|
||||||
"Le bon boulanger connaît son four comme son âme.",
|
|
||||||
"Un pain trop vite cuit n’a jamais de goût.",
|
|
||||||
"Le pain du matin est un trésor quotidien.",
|
|
||||||
"Il faut de la levure pour toute grande aventure.",
|
|
||||||
"Entre pétrir et cuire, tout est dans le timing.",
|
|
||||||
"Mie aérée, artisan comblé.",
|
|
||||||
"Qui ne farine pas sa planche colle son pain.",
|
|
||||||
"Le four mal allumé ne cuit que des regrets.",
|
|
||||||
"Un pain bien doré attire les gourmands du quartier.",
|
|
||||||
"Point de croissant sans beurre, point de vie sans saveur.",
|
|
||||||
"Le levain qui dort ne nourrit personne.",
|
|
||||||
"Pour un pain parfait, la main doit être légère.",
|
|
||||||
"Pain trop pétri, croûte trop durcie.",
|
|
||||||
"Le secret d’un bon pain réside dans la chaleur du four et du cœur.",
|
|
||||||
"Plus on attend, plus le pain grandit.",
|
|
||||||
"Une miche pour deux fait oublier les soucis.",
|
|
||||||
"Le boulanger lève tôt, et la pâte avec lui.",
|
|
||||||
"À pain chaud, miel bienvenu.",
|
|
||||||
"Un pain pour chaque jour, un bonheur pour toujours.",
|
|
||||||
}
|
|
||||||
|
|
||||||
var february = [29]string{
|
|
||||||
"Un pain bien pétri ne craint pas l'hiver.",
|
|
||||||
"Pain cuit trop vite, croûte qui s’effrite.",
|
|
||||||
"Qui sème du blé, récolte des miches dorées.",
|
|
||||||
"Sans amour, même le meilleur pain reste fade.",
|
|
||||||
"Un four bien chaud fait lever la pâte comme il faut.",
|
|
||||||
"À petite miche, grand plaisir.",
|
|
||||||
"Qui cuit doucement, savoure longuement.",
|
|
||||||
"Le bon pain se prépare avec soin, pas en chemin.",
|
|
||||||
"Pas de levain, pas de lendemain.",
|
|
||||||
"Chaque grain de blé a son destin dans une miche.",
|
|
||||||
"Pain trop salé, ami délaissé.",
|
|
||||||
"Qui goûte la croûte, goûte la vérité.",
|
|
||||||
"Mie trop dense, pain sans danse.",
|
|
||||||
"Pour un pain parfait, il faut l'eau de la pluie et la chaleur du feu.",
|
|
||||||
"Le levain est l’âme du pain.",
|
|
||||||
"Dans un four trop froid, rien ne se fait grand.",
|
|
||||||
"Farine bien choisie, pain qui réjouit.",
|
|
||||||
"Le bon pain attend toujours son heure.",
|
|
||||||
"Un pain levé d’hier fait des merveilles aujourd’hui.",
|
|
||||||
"Il faut nourrir le levain pour qu'il fasse grandir le pain.",
|
|
||||||
"Un four bien allumé réchauffe plus que des mots.",
|
|
||||||
"Sans pétrin, point de festin.",
|
|
||||||
"Pain bien formé, fête assurée.",
|
|
||||||
"Il faut respecter la pâte pour qu’elle donne le meilleur d’elle-même.",
|
|
||||||
"Une miche bien dorée n’a pas besoin de discours.",
|
|
||||||
"Pain du matin, chaleur dans les mains.",
|
|
||||||
"Le pain du pauvre vaut mieux que l’or du riche.",
|
|
||||||
"Tant que le four est chaud, le boulanger a du travail.",
|
|
||||||
"Pain mal pétri, croûte sans vie.",
|
|
||||||
}
|
|
||||||
|
|
||||||
var march = [31]string{
|
|
||||||
"Mars arrive avec le vent, mais le bon pain reste constant.",
|
|
||||||
"À pain chaud, sourire éclatant.",
|
|
||||||
"Une miche oubliée finit toujours par sécher.",
|
|
||||||
"Qui veut une croûte dorée ne doit pas se presser.",
|
|
||||||
"Le pain qui lève trop vite finit par retomber.",
|
|
||||||
"Le four mal fermé laisse échapper le bonheur.",
|
|
||||||
"Dans chaque grain de blé, il y a un pain qui sommeille.",
|
|
||||||
"Pain du jour, force de toujours.",
|
|
||||||
"Mieux vaut une croûte trop dure qu'une pâte trop crue.",
|
|
||||||
"La farine bien moulue fait la mie douce comme la soie.",
|
|
||||||
"Le boulanger sage ne se presse jamais.",
|
|
||||||
"Un pain à partager est un bonheur multiplié.",
|
|
||||||
"La levure ne s’improvise pas, elle se cultive.",
|
|
||||||
"Qui fait lever son pain avec soin n’a jamais faim.",
|
|
||||||
"Mie tendre, journée plus douce.",
|
|
||||||
"Le pain que l’on attend est le plus savoureux.",
|
|
||||||
"Pas de bon pain sans un brin de patience.",
|
|
||||||
"Même sous la pluie, la farine trouve son chemin vers la miche.",
|
|
||||||
"Un bon levain fait durer le festin.",
|
|
||||||
"Le pain bien cuit nourrit plus que l'estomac.",
|
|
||||||
"Sous une croûte dorée, tout est douceur.",
|
|
||||||
"Mie aérée, journée réussie.",
|
|
||||||
"Le secret d'un pain réussi : du temps et de la flamme.",
|
|
||||||
"Le pain pétri avec amour est toujours meilleur.",
|
|
||||||
"Même un petit pain fait un grand festin.",
|
|
||||||
"Quand le four est chaud, tout est possible.",
|
|
||||||
"Chaque grain de farine compte dans le pétrin.",
|
|
||||||
"Le bon pain sait attendre son heure dans le four.",
|
|
||||||
"Mieux vaut un pain simple bien fait qu'un festin compliqué.",
|
|
||||||
"En mars, le pain se prépare aux premiers rayons du printemps.",
|
|
||||||
"Pain cuit en mars, douceur pour les journées qui s’éclaircissent.",
|
|
||||||
}
|
|
||||||
|
|
||||||
var april = [30]string{
|
|
||||||
"En avril, le pain se dore sous le soleil timide.",
|
|
||||||
"Qui rit en avril, pétrit en douceur.",
|
|
||||||
"Le pain bien levé chasse les doutes du boulanger.",
|
|
||||||
"À pâte bien travaillée, mie légère assurée.",
|
|
||||||
"Quand le four parle, le boulanger écoute.",
|
|
||||||
"Il faut du levain pour affronter les caprices d'avril.",
|
|
||||||
"Sans farine fine, la miche ne se dessine.",
|
|
||||||
"Le pain qui chante dans le four annonce une bonne journée.",
|
|
||||||
"Point de bon pain sans un soupçon de patience.",
|
|
||||||
"Même en avril, la pâte n'aime pas les courants d'air.",
|
|
||||||
"À pain du matin, sourires jusqu'au soir.",
|
|
||||||
"Qui sème en avril, pétrit en mai.",
|
|
||||||
"Un bon pétrissage vaut bien une journée de travail.",
|
|
||||||
"Le pain qui ne lève pas est un cœur qui reste fermé.",
|
|
||||||
"En avril, pain tendre est un bonheur sincère.",
|
|
||||||
"Le boulanger qui sème ne manque jamais de farine.",
|
|
||||||
"Pain mal doré, journée ratée.",
|
|
||||||
"Le pain lève au rythme du cœur de celui qui le fait.",
|
|
||||||
"Avril pluvieux fait le pain précieux.",
|
|
||||||
"Qui cuit sans hâte, mange sans regret.",
|
|
||||||
"La mie légère est fille du temps et de l'effort.",
|
|
||||||
"Le boulanger patient fait toujours lever la pâte.",
|
|
||||||
"Pain bien levé, soucis envolés.",
|
|
||||||
"Chaque miche a sa saison, chaque croûte a sa raison.",
|
|
||||||
"En avril, le pain se lève malgré la pluie.",
|
|
||||||
"Le bon pain n’a pas d’âge, mais il a toujours du goût.",
|
|
||||||
"Même une petite miche a besoin de chaleur.",
|
|
||||||
"Avril timide, mie solide.",
|
|
||||||
"Pétrir doucement, c’est savourer longtemps.",
|
|
||||||
"Le four d'avril est plein de promesses pour l’été.",
|
|
||||||
}
|
|
||||||
|
|
||||||
var may = [31]string{
|
|
||||||
"En mai, le pain lève comme les fleurs dans les champs.",
|
|
||||||
"Mie dorée en mai, gourmandise assurée.",
|
|
||||||
"Le boulanger de mai travaille avec le soleil en souriant.",
|
|
||||||
"Pain chaud en mai, bonheur partagé.",
|
|
||||||
"Avec le blé de mai, le pain n’a jamais failli.",
|
|
||||||
"Un bon pain en mai vaut plus que mille festins.",
|
|
||||||
"Pétrir en mai, c'est préparer l'été.",
|
|
||||||
"Le levain bien nourri fait des miches comme au paradis.",
|
|
||||||
"Même le pain a ses saisons, et mai est le plus doux.",
|
|
||||||
"En mai, le pain se dore sous les rayons de l'aube.",
|
|
||||||
"Pain levé en mai, saveur de la liberté.",
|
|
||||||
"Le pain du matin est la promesse d’un jour radieux.",
|
|
||||||
"Qui pétrit en mai prépare l’abondance de demain.",
|
|
||||||
"En mai, pain au four, maison en fête.",
|
|
||||||
"Le secret du pain de mai, c'est la chaleur du four et celle du cœur.",
|
|
||||||
"Pain fait avec soin est toujours un pain divin.",
|
|
||||||
"Le levain de mai est la force de l’été.",
|
|
||||||
"Chaque miche de mai raconte l’histoire du blé passé.",
|
|
||||||
"Mai fleuri, four nourri.",
|
|
||||||
"Le pain de mai réchauffe même sans four.",
|
|
||||||
"Avec du bon levain, tout pain est un festin.",
|
|
||||||
"En mai, qui fait du pain récolte des sourires.",
|
|
||||||
"La pâte pétrie en mai est plus légère qu’un nuage.",
|
|
||||||
"Le boulanger de mai ne manque jamais de blé.",
|
|
||||||
"En mai, pain cuit vaut mille mots doux.",
|
|
||||||
"Quand le soleil de mai brille, le pain se dore à merveille.",
|
|
||||||
"Pain trop pressé en mai ne fait jamais honneur.",
|
|
||||||
"La farine de mai sent la promesse des moissons.",
|
|
||||||
"Un bon pain en mai est le prélude de l’été.",
|
|
||||||
"Chaque miche de mai est un régal pour les repas en extérieur.",
|
|
||||||
"Sous le ciel clair de mai, le pain se transforme en délice.",
|
|
||||||
}
|
|
||||||
|
|
||||||
var june = [30]string{
|
|
||||||
"En juin, le pain se lève avec les premiers blés.",
|
|
||||||
"Sous le soleil de juin, la croûte se dore sans fin.",
|
|
||||||
"Le pain bien fait en juin nourrit jusqu'au lendemain.",
|
|
||||||
"Le boulanger de juin façonne la mie comme le vent sculpte les champs.",
|
|
||||||
"À pain bien pétri, mie légère sous un ciel d’été.",
|
|
||||||
"Juin sans pain, c’est comme un jour sans soleil.",
|
|
||||||
"Le pain de juin réchauffe les cœurs même sous la chaleur.",
|
|
||||||
"Mie de juin, douceur en chemin.",
|
|
||||||
"En juin, qui ne lève pas sa pâte reste sur la touche.",
|
|
||||||
"Juin donne aux miches la saveur des jours longs.",
|
|
||||||
"Avec du pain fait en juin, chaque repas devient festin.",
|
|
||||||
"Le four de juin est l’ami du boulanger comme le soleil l’est du blé.",
|
|
||||||
"Qui pétrit en juin prépare les festins d’été.",
|
|
||||||
"Le pain bien doré de juin est le fruit du travail bien fait.",
|
|
||||||
"En juin, les miches se parent de la couleur des blés.",
|
|
||||||
"Pain levé en juin, fête assurée pour demain.",
|
|
||||||
"Chaque miche de juin a le goût du soleil et de la fête.",
|
|
||||||
"En juin, le blé se prépare, et le pain suit le même chemin.",
|
|
||||||
"Le pain de juin nourrit plus qu’un simple festin.",
|
|
||||||
"Sous le ciel de juin, tout pain est promesse de l’été.",
|
|
||||||
"Le levain de juin porte en lui toute la chaleur des jours à venir.",
|
|
||||||
"En juin, chaque fournée est un hommage à la terre.",
|
|
||||||
"Pain pétri en juin, saveurs divines pour le festin.",
|
|
||||||
"Avec la chaleur de juin, même le plus petit pain grandit.",
|
|
||||||
"Juin chante avec le pain qui lève doucement.",
|
|
||||||
"Le boulanger de juin n’a besoin que de farine et d’un ciel sans nuage.",
|
|
||||||
"En juin, un pain bien cuit annonce un bel été.",
|
|
||||||
"Le four de juin est un compagnon fidèle pour tout boulanger.",
|
|
||||||
"Le pain doré sous le soleil de juin reste gravé dans les cœurs.",
|
|
||||||
"Le pain de juin est le compagnon des repas en plein air.",
|
|
||||||
}
|
|
||||||
|
|
||||||
var july = [31]string{
|
|
||||||
"En juillet, le pain dore plus vite que les épis.",
|
|
||||||
"Sous le soleil de juillet, la croûte est toujours parfaite.",
|
|
||||||
"Le pain de juillet nourrit les longues soirées d’été.",
|
|
||||||
"Juillet, mois du blé, mois du pain bien levé.",
|
|
||||||
"Pain chaud en juillet, bonheur partagé sous le ciel étoilé.",
|
|
||||||
"En juillet, qui pétrit récolte des sourires dorés.",
|
|
||||||
"Le four de juillet ne connaît pas la pause, comme le soleil.",
|
|
||||||
"À pain bien doré, saveur de l’été retrouvé.",
|
|
||||||
"Juillet chante dans la miche, comme le vent dans les champs.",
|
|
||||||
"Le pain de juillet porte en lui la chaleur des jours heureux.",
|
|
||||||
"Mie légère en juillet, journée sans nuages.",
|
|
||||||
"Juillet offre au pain la douceur des soirées d’été.",
|
|
||||||
"En juillet, la farine danse sous les mains du boulanger.",
|
|
||||||
"À four chaud en juillet, mie tendre à souhait.",
|
|
||||||
"Pain pétri en juillet, festin assuré pour l’été.",
|
|
||||||
"Sous le soleil de juillet, chaque miche est une fête.",
|
|
||||||
"La croûte de juillet est un hommage aux champs dorés.",
|
|
||||||
"Qui lève sa pâte en juillet ne manque jamais de blé.",
|
|
||||||
"En juillet, chaque pain est un rayon de soleil.",
|
|
||||||
"Le pain bien levé de juillet accompagne chaque repas avec fierté.",
|
|
||||||
"Même les petits pains de juillet ont le goût de la fête.",
|
|
||||||
"Le four de juillet fait danser la mie comme la brise dans les blés.",
|
|
||||||
"Pain doré sous le soleil de juillet, plaisir garanti.",
|
|
||||||
"Le boulanger de juillet connaît l’art du pain comme le ciel connaît le soleil.",
|
|
||||||
"En juillet, un pain bien cuit fait oublier les soucis.",
|
|
||||||
"Chaque miche de juillet est remplie de la générosité de la terre.",
|
|
||||||
"Pain levé sous la chaleur de juillet, saveur inégalée.",
|
|
||||||
"Le pain de juillet est une promesse de jours heureux.",
|
|
||||||
"Avec un pain bien fait en juillet, tout festin devient mémorable.",
|
|
||||||
"La chaleur de juillet scelle le destin de chaque miche.",
|
|
||||||
"En juillet, le pain se fait léger pour les chaudes journées.",
|
|
||||||
}
|
|
||||||
|
|
||||||
var august = [31]string{
|
|
||||||
"En août, le pain croustille sous la chaleur du four et du ciel.",
|
|
||||||
"Pain d'août, mie tendre et croûte en fête.",
|
|
||||||
"Le pain d'août nourrit autant qu'il réjouit.",
|
|
||||||
"À four chaud en août, mie aérée et bonheur partout.",
|
|
||||||
"Le pain de l’été est un trésor de générosité.",
|
|
||||||
"Août brûlant fait lever la pâte doucement.",
|
|
||||||
"Sous le soleil d'août, le pain s’habille d’or.",
|
|
||||||
"Pain doré en août, festin sans aucun doute.",
|
|
||||||
"Le boulanger d'août connaît la patience sous la chaleur.",
|
|
||||||
"Pain bien levé, août enchanté.",
|
|
||||||
"Chaque miche d'août porte en elle la richesse des moissons.",
|
|
||||||
"Août généreux, pain savoureux.",
|
|
||||||
"Le pain cuit en août a le goût des champs dorés.",
|
|
||||||
"Mie tendre et croûte dorée sont les fruits du travail d'août.",
|
|
||||||
"À pain bien pétri, août se rit.",
|
|
||||||
"En août, chaque miche est un hommage au blé mûr.",
|
|
||||||
"Le four d'août réchauffe les cœurs autant que le pain nourrit.",
|
|
||||||
"Pain cuit avec soin en août, festin en vue.",
|
|
||||||
"En août, un bon pain vaut plus que mille festins.",
|
|
||||||
"Le pain d'août est la saveur des longues soirées estivales.",
|
|
||||||
"Chaque grain de blé moissonné en août devient un pain doré.",
|
|
||||||
"Pain levé sous le ciel d'août, saveur inoubliable.",
|
|
||||||
"Même sous la chaleur d'août, le boulanger ne faiblit pas.",
|
|
||||||
"Le pain d'août se cuit avec le cœur et la patience.",
|
|
||||||
"Mie légère en août, été parfait sans aucun doute.",
|
|
||||||
"Un pain bien doré en août vaut toutes les douceurs.",
|
|
||||||
"Le four brûlant d'août fait naître des miches croquantes.",
|
|
||||||
"Août offre au pain une saveur venue des champs dorés.",
|
|
||||||
"Chaque miche en août est un rayon de soleil.",
|
|
||||||
"Pain pétri en août, festin parfait pour un été radieux.",
|
|
||||||
"Mie fraîche en août, plaisir assuré.",
|
|
||||||
}
|
|
||||||
|
|
||||||
var september = [30]string{
|
|
||||||
"En septembre, le pain se prépare pour l’hiver à venir.",
|
|
||||||
"Le pain de septembre est le reflet des récoltes de l’été.",
|
|
||||||
"Mie bien aérée en septembre, journées dorées assurées.",
|
|
||||||
"À pain bien cuit, septembre sourit.",
|
|
||||||
"En septembre, le four réchauffe plus que le pain.",
|
|
||||||
"Chaque miche de septembre porte les promesses de l’automne.",
|
|
||||||
"Le pain de septembre se nourrit des derniers rayons d’été.",
|
|
||||||
"Le boulanger de septembre sait que chaque grain compte.",
|
|
||||||
"Pain pétri avec soin en septembre, saveur d’automne assurée.",
|
|
||||||
"Sous la lumière douce de septembre, le pain se dore à merveille.",
|
|
||||||
"Le pain de septembre est le délice des journées fraîches.",
|
|
||||||
"En septembre, même le pain a le goût des nouvelles saisons.",
|
|
||||||
"Mie de septembre, douceur dans chaque bouchée.",
|
|
||||||
"Le four de septembre est prêt pour les pains d’automne.",
|
|
||||||
"Un bon pain en septembre est la promesse d’un hiver bien nourri.",
|
|
||||||
"Pain bien levé, septembre apaisé.",
|
|
||||||
"Chaque miche de septembre est une préparation pour les jours froids.",
|
|
||||||
"En septembre, le levain se prépare à la fraîcheur des matins.",
|
|
||||||
"Le pain doré de septembre est le meilleur compagnon des soirées qui s’allongent.",
|
|
||||||
"À four bien chaud en septembre, mie toujours tendre.",
|
|
||||||
"Le pain de septembre est le fruit du travail des mois chauds.",
|
|
||||||
"Sous le ciel de septembre, le pain est une douce transition.",
|
|
||||||
"Le boulanger de septembre voit chaque miche comme une promesse.",
|
|
||||||
"Pain cuit en septembre, plaisir d’automne.",
|
|
||||||
"Chaque tranche de pain de septembre a le goût des récoltes.",
|
|
||||||
"Septembre partage le pain comme il partage les récoltes.",
|
|
||||||
"Le four de septembre réchauffe le pain comme les cœurs.",
|
|
||||||
"En septembre, chaque miche est une ode aux saisons passées.",
|
|
||||||
"Le pain de septembre se prépare pour la saison des fêtes.",
|
|
||||||
"Le four de septembre est prêt pour les premières miches d’automne.",
|
|
||||||
}
|
|
||||||
|
|
||||||
var october = [31]string{
|
|
||||||
"En octobre, le pain se dore sous les premières brises d’automne.",
|
|
||||||
"À pain bien levé, octobre en beauté.",
|
|
||||||
"Le pain d’octobre se nourrit des vents frais et des jours raccourcis.",
|
|
||||||
"Chaque miche d’octobre porte la richesse des champs dorés.",
|
|
||||||
"Pain cuit avec soin en octobre, réchauffe les soirées d’automne.",
|
|
||||||
"En octobre, la pâte se prépare pour les jours plus frais.",
|
|
||||||
"Le four d’octobre est le gardien des secrets du pain parfait.",
|
|
||||||
"Mie légère en octobre, douceur assurée malgré le froid.",
|
|
||||||
"Le pain d’octobre est un régal pour les jours qui se refroidissent.",
|
|
||||||
"Sous les feuilles d’octobre, le pain se dore à souhait.",
|
|
||||||
"Chaque tranche de pain en octobre est un réconfort pour les soirées longues.",
|
|
||||||
"Le boulanger d’octobre sait que la patience fait la mie.",
|
|
||||||
"Pain bien pétri en octobre, festin pour les mois froids.",
|
|
||||||
"En octobre, même le pain a besoin d’un peu de chaleur.",
|
|
||||||
"Le pain d’octobre est l’accompagnement idéal pour les repas d’automne.",
|
|
||||||
"À four chaud en octobre, chaque miche est une promesse de confort.",
|
|
||||||
"Le levain d’octobre prépare les pâtes pour l’hiver.",
|
|
||||||
"Pain doré sous le ciel d’octobre, douceur pour chaque repas.",
|
|
||||||
"En octobre, le pain se prépare comme les feuilles tombent.",
|
|
||||||
"Chaque miche en octobre a le goût de la saison qui s’achève.",
|
|
||||||
"Pain bien levé en octobre, chaleur dans chaque bouchée.",
|
|
||||||
"Sous la fraîcheur d’octobre, le pain est une source de réconfort.",
|
|
||||||
"Le four d’octobre transforme chaque pâte en délice automnal.",
|
|
||||||
"Pain pétri avec soin en octobre, festin pour les soirées fraîches.",
|
|
||||||
"Le pain d’octobre est un préambule aux douceurs de l’hiver.",
|
|
||||||
"En octobre, chaque miche est un hommage aux récoltes passées.",
|
|
||||||
"Le boulanger d’octobre prépare le pain pour les jours froids à venir.",
|
|
||||||
"Chaque croûte en octobre raconte l’histoire des saisons changeantes.",
|
|
||||||
"Pain bien fait en octobre, bonheur pour chaque saison.",
|
|
||||||
"Chaque miche d’octobre est un délice pour les repas d’automne.",
|
|
||||||
"Sous les feuilles d’octobre, le pain se transforme en régal.",
|
|
||||||
}
|
|
||||||
|
|
||||||
var november = [30]string{
|
|
||||||
"En novembre, le pain est le réconfort des journées fraîches.",
|
|
||||||
"Le pain de novembre se nourrit de la chaleur des foyers.",
|
|
||||||
"À chaque miche en novembre, une chaleur pour les cœurs.",
|
|
||||||
"Le four en novembre est le gardien des saveurs d’automne.",
|
|
||||||
"Pain bien cuit en novembre, douceur pour les soirées longues.",
|
|
||||||
"Sous la brume de novembre, le pain réchauffe comme un bon feu.",
|
|
||||||
"Chaque miche de novembre porte en elle la promesse de l’hiver.",
|
|
||||||
"Le pain d’octobre donne son meilleur en novembre.",
|
|
||||||
"En novembre, le pain se fait compagnon des jours gris.",
|
|
||||||
"À four chaud en novembre, chaque tranche est un réconfort.",
|
|
||||||
"Le pain de novembre est la chaleur du foyer dans les jours froids.",
|
|
||||||
"Pain bien pétri en novembre, bonheur pour les soirées d’hiver.",
|
|
||||||
"Le boulanger de novembre sait transformer la farine en chaleur.",
|
|
||||||
"Sous le ciel de novembre, le pain est un baume pour l’âme.",
|
|
||||||
"Mie tendre en novembre, douceur dans chaque bouchée.",
|
|
||||||
"Le pain d’en novembre est le meilleur ami des repas en famille.",
|
|
||||||
"En novembre, le pain se cuit lentement pour mieux réchauffer.",
|
|
||||||
"Chaque miche de novembre se fait festive sous la lueur des chandelles.",
|
|
||||||
"Le four de novembre est le préparateur des festins d’hiver.",
|
|
||||||
"Pain doré en novembre, chaleur assurée.",
|
|
||||||
"Le pain bien levé en novembre annonce des repas chaleureux.",
|
|
||||||
"Sous la douceur de novembre, le pain est un régal réconfortant.",
|
|
||||||
"Le boulanger de novembre prépare des miches pour les fêtes.",
|
|
||||||
"Pain pétri avec soin en novembre, réchauffe les soirées hivernales.",
|
|
||||||
"Chaque croûte en novembre est un hommage à la saison qui change.",
|
|
||||||
"Le pain de novembre est l’élément central des repas de famille.",
|
|
||||||
"En novembre, le four est un havre de chaleur pour le pain.",
|
|
||||||
"Le pain d’hiver commence à se préparer en novembre.",
|
|
||||||
"À pain bien cuit en novembre, le réconfort est assuré.",
|
|
||||||
"Pain de novembre, douceur pour les soirées longues.",
|
|
||||||
}
|
|
||||||
|
|
||||||
var december = [31]string{
|
|
||||||
"En décembre, le pain est la chaleur des longues soirées d’hiver.",
|
|
||||||
"Le pain de décembre est le réconfort après les journées froides.",
|
|
||||||
"À chaque miche de décembre, une fête pour les papilles.",
|
|
||||||
"Le four en décembre est le gardien des saveurs des fêtes.",
|
|
||||||
"Pain bien cuit en décembre, bonheur sous le sapin.",
|
|
||||||
"Sous la neige de décembre, le pain réchauffe comme un bon feu.",
|
|
||||||
"Chaque tranche de pain en décembre est un délice pour les repas festifs.",
|
|
||||||
"Le pain de décembre porte en lui la magie des fêtes.",
|
|
||||||
"En décembre, le pain se cuit lentement pour remplir les maisons de chaleur.",
|
|
||||||
"À four bien chaud en décembre, chaque miche est une célébration.",
|
|
||||||
"Le pain de décembre est l’accompagnement parfait des repas de fin d’année.",
|
|
||||||
"Pain bien pétri en décembre, douceur pour les soirées en famille.",
|
|
||||||
"Le boulanger de décembre transforme la farine en festin hivernal.",
|
|
||||||
"Sous les lumières de décembre, le pain est une douceur réconfortante.",
|
|
||||||
"Mie tendre en décembre, chaleur dans chaque bouchée.",
|
|
||||||
"Le pain d’hiver commence à se préparer en décembre.",
|
|
||||||
"En décembre, chaque miche est un hommage aux traditions des fêtes.",
|
|
||||||
"Le four de décembre est prêt pour les festins de fin d’année.",
|
|
||||||
"Pain doré en décembre, plaisir des fêtes.",
|
|
||||||
"Le pain bien levé en décembre rend les repas plus joyeux.",
|
|
||||||
"Sous le froid de décembre, le pain est un baume pour l’âme.",
|
|
||||||
"Le boulanger de décembre prépare des miches pour les fêtes de fin d’année.",
|
|
||||||
"Pain pétri avec soin en décembre, réchauffe les soirées les plus froides.",
|
|
||||||
"Chaque croûte en décembre est un hommage à la saison des fêtes.",
|
|
||||||
"Le pain de décembre est un symbole de chaleur et de convivialité.",
|
|
||||||
"En décembre, le four transforme chaque pâte en délice hivernal.",
|
|
||||||
"Le pain de décembre est le réconfort après les festivités.",
|
|
||||||
"À pain bien cuit en décembre, les fêtes sont pleines de saveur.",
|
|
||||||
"Mie tendre en décembre, plaisir des soirées hivernales.",
|
|
||||||
"À chaque miche de décembre, un cadeau pour les papilles.",
|
|
||||||
"Pain bien cuit en décembre, régal des repas de fin d’année.",
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
package quotes
|
|
||||||
|
|
||||||
import "time"
|
|
||||||
|
|
||||||
func GetQuote(date time.Time) string {
|
|
||||||
switch date.Month() {
|
|
||||||
case time.January:
|
|
||||||
return january[date.Day()]
|
|
||||||
case time.February:
|
|
||||||
return february[date.Day()]
|
|
||||||
case time.March:
|
|
||||||
return march[date.Day()]
|
|
||||||
case time.April:
|
|
||||||
return april[date.Day()]
|
|
||||||
case time.May:
|
|
||||||
return may[date.Day()]
|
|
||||||
case time.June:
|
|
||||||
return june[date.Day()]
|
|
||||||
case time.July:
|
|
||||||
return july[date.Day()]
|
|
||||||
case time.August:
|
|
||||||
return august[date.Day()]
|
|
||||||
case time.September:
|
|
||||||
return september[date.Day()]
|
|
||||||
case time.October:
|
|
||||||
return october[date.Day()]
|
|
||||||
case time.November:
|
|
||||||
return november[date.Day()]
|
|
||||||
case time.December:
|
|
||||||
return december[date.Day()]
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
|
@ -4,37 +4,25 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"github.com/Crocmagnon/display-epaper/fete"
|
"github.com/Crocmagnon/display-epaper/fete"
|
||||||
"github.com/Crocmagnon/display-epaper/transports"
|
"github.com/Crocmagnon/display-epaper/transports"
|
||||||
"github.com/Crocmagnon/display-epaper/weather"
|
|
||||||
"github.com/llgcode/draw2d/draw2dimg"
|
"github.com/llgcode/draw2d/draw2dimg"
|
||||||
"log"
|
"log"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func run(
|
func run(ctx context.Context, transportsClient *transports.Client, feteClient *fete.Client) error {
|
||||||
ctx context.Context,
|
img, err := getBlack(ctx, func() time.Time {
|
||||||
transportsClient *transports.Client,
|
|
||||||
feteClient *fete.Client,
|
|
||||||
weatherClient *weather.Client,
|
|
||||||
) error {
|
|
||||||
img, err := getBlack(
|
|
||||||
ctx,
|
|
||||||
func() time.Time {
|
|
||||||
t, err := time.Parse(time.DateOnly, "2024-08-01zzz")
|
t, err := time.Parse(time.DateOnly, "2024-08-01zzz")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return time.Now()
|
return time.Now()
|
||||||
}
|
}
|
||||||
return t
|
return t
|
||||||
},
|
}, transportsClient, feteClient)
|
||||||
transportsClient,
|
|
||||||
feteClient,
|
|
||||||
weatherClient,
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
if err := draw2dimg.SaveToPngFile("out/black.png", img); err != nil {
|
draw2dimg.SaveToPngFile("out/black.png", img)
|
||||||
log.Fatalf("error saving image: %v", err)
|
|
||||||
}
|
log.Println("done")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,13 +6,12 @@ import (
|
||||||
"github.com/Crocmagnon/display-epaper/epd"
|
"github.com/Crocmagnon/display-epaper/epd"
|
||||||
"github.com/Crocmagnon/display-epaper/fete"
|
"github.com/Crocmagnon/display-epaper/fete"
|
||||||
"github.com/Crocmagnon/display-epaper/transports"
|
"github.com/Crocmagnon/display-epaper/transports"
|
||||||
"github.com/Crocmagnon/display-epaper/weather"
|
|
||||||
"log"
|
"log"
|
||||||
"periph.io/x/host/v3"
|
"periph.io/x/host/v3"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func run(ctx context.Context, transportsClient *transports.Client, feteClient *fete.Client, weatherClient *weather.Client) error {
|
func run(ctx context.Context, transportsClient *transports.Client, feteClient *fete.Client) error {
|
||||||
_, err := host.Init()
|
_, err := host.Init()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("initializing host: %w", err)
|
return fmt.Errorf("initializing host: %w", err)
|
||||||
|
@ -31,19 +30,13 @@ func run(ctx context.Context, transportsClient *transports.Client, feteClient *f
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
|
||||||
err = loop(
|
err = loop(ctx, display, transportsClient, feteClient)
|
||||||
ctx,
|
|
||||||
display,
|
|
||||||
transportsClient,
|
|
||||||
feteClient,
|
|
||||||
weatherClient,
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("error looping: %v\n", err)
|
log.Printf("error looping: %v\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Println("time.Sleep(10m)")
|
log.Println("time.Sleep(30s)")
|
||||||
time.Sleep(10 * time.Minute)
|
time.Sleep(30 * time.Second)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +45,6 @@ func loop(
|
||||||
display *epd.EPD,
|
display *epd.EPD,
|
||||||
transportsClient *transports.Client,
|
transportsClient *transports.Client,
|
||||||
feteClient *fete.Client,
|
feteClient *fete.Client,
|
||||||
weatherClient *weather.Client,
|
|
||||||
) error {
|
) error {
|
||||||
defer func() {
|
defer func() {
|
||||||
if err := display.Sleep(); err != nil {
|
if err := display.Sleep(); err != nil {
|
||||||
|
@ -67,13 +59,7 @@ func loop(
|
||||||
|
|
||||||
display.Clear()
|
display.Clear()
|
||||||
|
|
||||||
black, err := getBlack(
|
black, err := getBlack(ctx, time.Now, transportsClient, feteClient)
|
||||||
ctx,
|
|
||||||
time.Now,
|
|
||||||
transportsClient,
|
|
||||||
feteClient,
|
|
||||||
weatherClient,
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("getting black: %w", err)
|
return fmt.Errorf("getting black: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,180 +0,0 @@
|
||||||
package weather
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"github.com/carlmjohnson/requests"
|
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Config struct {
|
|
||||||
APIKey string
|
|
||||||
CacheLocation string
|
|
||||||
}
|
|
||||||
|
|
||||||
type Client struct {
|
|
||||||
config Config
|
|
||||||
client *http.Client
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(httpClient *http.Client, config Config) *Client {
|
|
||||||
return &Client{
|
|
||||||
config: config,
|
|
||||||
client: httpClient,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type Prevision struct {
|
|
||||||
Lat float64 `json:"lat"`
|
|
||||||
Lon float64 `json:"lon"`
|
|
||||||
Timezone string `json:"timezone"`
|
|
||||||
TimezoneOffset int `json:"timezone_offset"`
|
|
||||||
Current struct {
|
|
||||||
Dt int `json:"dt"`
|
|
||||||
Sunrise int `json:"sunrise"`
|
|
||||||
Sunset int `json:"sunset"`
|
|
||||||
Temp float64 `json:"temp"`
|
|
||||||
FeelsLike float64 `json:"feels_like"`
|
|
||||||
Pressure int `json:"pressure"`
|
|
||||||
Humidity int `json:"humidity"`
|
|
||||||
DewPoint float64 `json:"dew_point"`
|
|
||||||
Uvi float64 `json:"uvi"`
|
|
||||||
Clouds int `json:"clouds"`
|
|
||||||
Visibility int `json:"visibility"`
|
|
||||||
WindSpeed float64 `json:"wind_speed"`
|
|
||||||
WindDeg int `json:"wind_deg"`
|
|
||||||
WindGust float64 `json:"wind_gust"`
|
|
||||||
Weather []struct {
|
|
||||||
Id int `json:"id"`
|
|
||||||
Main string `json:"main"`
|
|
||||||
Description string `json:"description"`
|
|
||||||
Icon string `json:"icon"`
|
|
||||||
} `json:"weather"`
|
|
||||||
} `json:"current"`
|
|
||||||
Daily []Daily `json:"daily"`
|
|
||||||
Alerts []struct {
|
|
||||||
SenderName string `json:"sender_name"`
|
|
||||||
Event string `json:"event"`
|
|
||||||
Start int `json:"start"`
|
|
||||||
End int `json:"end"`
|
|
||||||
Description string `json:"description"`
|
|
||||||
Tags []string `json:"tags"`
|
|
||||||
} `json:"alerts"`
|
|
||||||
}
|
|
||||||
|
|
||||||
var errTooOld = errors.New("prevision is too old")
|
|
||||||
|
|
||||||
func loadFromDisk(location string) (Prevision, error) {
|
|
||||||
stat, err := os.Stat(location)
|
|
||||||
if err != nil {
|
|
||||||
return Prevision{}, fmt.Errorf("getting file info: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if stat.ModTime().Add(10 * time.Minute).Before(time.Now()) {
|
|
||||||
return Prevision{}, errTooOld
|
|
||||||
}
|
|
||||||
|
|
||||||
file, err := os.Open(location)
|
|
||||||
if err != nil {
|
|
||||||
return Prevision{}, fmt.Errorf("opening prevision: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
var res Prevision
|
|
||||||
if err = json.NewDecoder(file).Decode(&res); err != nil {
|
|
||||||
return Prevision{}, fmt.Errorf("decoding prevision: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p Prevision) dumpToDisk(location string) error {
|
|
||||||
file, err := os.Create(location)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("creating prevision: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
if err = json.NewEncoder(file).Encode(p); err != nil {
|
|
||||||
return fmt.Errorf("dumping prevision: %w", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type Daily struct {
|
|
||||||
Dt int `json:"dt"`
|
|
||||||
Sunrise int `json:"sunrise"`
|
|
||||||
Sunset int `json:"sunset"`
|
|
||||||
Moonrise int `json:"moonrise"`
|
|
||||||
Moonset int `json:"moonset"`
|
|
||||||
MoonPhase float64 `json:"moon_phase"`
|
|
||||||
Summary string `json:"summary"`
|
|
||||||
Temp struct {
|
|
||||||
Day float64 `json:"day"`
|
|
||||||
Min float64 `json:"min"`
|
|
||||||
Max float64 `json:"max"`
|
|
||||||
Night float64 `json:"night"`
|
|
||||||
Eve float64 `json:"eve"`
|
|
||||||
Morn float64 `json:"morn"`
|
|
||||||
} `json:"temp"`
|
|
||||||
FeelsLike struct {
|
|
||||||
Day float64 `json:"day"`
|
|
||||||
Night float64 `json:"night"`
|
|
||||||
Eve float64 `json:"eve"`
|
|
||||||
Morn float64 `json:"morn"`
|
|
||||||
} `json:"feels_like"`
|
|
||||||
Pressure int `json:"pressure"`
|
|
||||||
Humidity int `json:"humidity"`
|
|
||||||
DewPoint float64 `json:"dew_point"`
|
|
||||||
WindSpeed float64 `json:"wind_speed"`
|
|
||||||
WindDeg int `json:"wind_deg"`
|
|
||||||
WindGust float64 `json:"wind_gust"`
|
|
||||||
Weather []Weather `json:"weather"`
|
|
||||||
Clouds int `json:"clouds"`
|
|
||||||
Pop float64 `json:"pop"`
|
|
||||||
Rain float64 `json:"rain"`
|
|
||||||
Uvi float64 `json:"uvi"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Weather struct {
|
|
||||||
Id int `json:"id"`
|
|
||||||
Main string `json:"main"`
|
|
||||||
Description string `json:"description"`
|
|
||||||
Icon string `json:"icon"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Client) GetWeather(ctx context.Context) (res *Prevision, err error) {
|
|
||||||
if val, err := loadFromDisk(c.config.CacheLocation); nil == err {
|
|
||||||
log.Println("found weather in cache")
|
|
||||||
return &val, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Println("querying weather")
|
|
||||||
|
|
||||||
err = requests.URL("https://api.openweathermap.org/data/3.0/onecall").
|
|
||||||
Client(c.client).
|
|
||||||
Param("lat", "45.78").
|
|
||||||
Param("lon", "4.89").
|
|
||||||
Param("appid", c.config.APIKey).
|
|
||||||
Param("units", "metric").
|
|
||||||
Param("lang", "fr").
|
|
||||||
Param("exclude", "minutely,hourly").
|
|
||||||
ToJSON(&res).
|
|
||||||
Fetch(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("calling openweathermap: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := res.dumpToDisk(c.config.CacheLocation); err != nil {
|
|
||||||
log.Printf("error dumping files to disk: %v\n", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return res, nil
|
|
||||||
}
|
|