~handlerug/handlebot

ref: e2138e35984f582b50a481b58c332afae2841b1f handlebot/handlers.go -rw-r--r-- 3.2 KiB
e2138e35Umar Getagazov urlpreview: Parse Content-Disposition 3 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package main

import (
	"context"
	"errors"
	"fmt"
	"log"

	"git.sr.ht/~handlerug/handlebot/database"
	"git.sr.ht/~handlerug/handlebot/jisho"
	"git.sr.ht/~handlerug/handlebot/presentation"
	"git.sr.ht/~handlerug/handlebot/weather"
	"git.sr.ht/~handlerug/handlebot/wolframalpha"
)

const firstUsageMsg = "You have never used `.weather` before; invoke it with location first."
const invalidRangeMsg = "Weather data is only available for the next 168h or 7d."
const invalidSyntaxMsg = "Invalid command syntax."
const unimplementedMsg = "Forecasts have not been implemented yet. But you're always welcome to help with that! " + ForgeLink
const quotaReachedMsg = "Sorry, the API key seems to have reached its max quota."

const databaseErrMsg = "An error occured while working with the database"
const geocoderErrMsg = "An error occured while geocoding the address"
const forecasterErrMsg = "An error occured while fetching the weather"

var announceText = fmt.Sprintf("Serving text/gemini since 2021, yours truly — %s %s, multi-purpose IRC bot %s", BotName, BotVersion, ForgeLink)

func handleBots(ctx context.Context, req HandlerRequest) (string, error) {
	return announceText, nil
}

func handleJisho(ctx context.Context, req HandlerRequest) (string, error) {
	result, err := (&jisho.Client{}).Query(ctx, req.Args)
	if err != nil {
		return "", err
	}
	return presentation.Jisho(result), nil
}

func HandleWeather(ctx context.Context, req HandlerRequest) (string, error) {
	db := database.ForContext(ctx)
	f := weather.ForContext(ctx)
	if f == nil {
		return "Weather commands are disabled. To enable, set " +
			"OpenWeatherMap and MapQuest API keys in the " +
			"configuration.", nil
	}

	query := req.Args
	server := req.ServerHost
	nick := req.Event.Source.Name
	if query == "" {
		var err error
		query, err = db.GetUserLocation(ctx, server, nick)

		if errors.Is(err, database.ErrNoData) {
			return firstUsageMsg, nil
		} else if err != nil {
			return errorMsg(databaseErrMsg, err), err
		}

	} else {
		if err := db.PutUserLocation(ctx, server, nick, query); err != nil {
			return errorMsg(databaseErrMsg, err), err
		}
	}

	lat, lng, location, err := db.GetGeocodeResult(ctx, query)
	if errors.Is(err, database.ErrNoData) {
		lat, lng, location, err = f.Geocode(ctx, query)
		if err != nil {
			return errorMsg(geocoderErrMsg, err), err
		}

		if err := db.PutGeocodeResult(ctx, query, lat, lng, location); err != nil {
			log.Println("failed to save geocoding results to DB: ", err)
		}

	} else if err != nil {
		return databaseErrMsg, err
	}

	w, err := f.Weather(ctx, lat, lng)
	if err != nil {
		return errorMsg(forecasterErrMsg, err), err
	}
	return presentation.Weather(w, location), nil
}

func handleWolframAlpha(ctx context.Context, req HandlerRequest) (string, error) {
	client := wolframalpha.ForContext(ctx)
	if client == nil {
		return "Wolfram|Alpha is disabled. To enable it, set the " +
			"API key in the configuration.", nil
	}

	resp, err := client.Query(ctx, req.Args)
	if err != nil {
		if _, ok := err.(PublicError); ok {
			return err.Error(), nil
		} else {
			log.Println(err)
			return "Wolfram|Alpha API call failed; check the logs for more info.", nil
		}
	}
	return presentation.WolframAlpha(resp), err
}