use go templates for the web pages

This commit is contained in:
lyx0 2023-12-20 02:06:05 +01:00
parent 7ce0212c80
commit ae4237e0e8
4 changed files with 167 additions and 6 deletions

View file

@ -389,6 +389,7 @@ func (app *application) handleCommand(message twitch.PrivateMessage) {
} }
type command struct { type command struct {
Name string
Alias []string Alias []string
Description string Description string
Level string Level string
@ -399,264 +400,308 @@ type command struct {
// Required is < > // Required is < >
var helpText = map[string]command{ var helpText = map[string]command{
"bttv": { "bttv": {
Name: "bttv",
Alias: []string{"bttv", "betterttv"}, Alias: []string{"bttv", "betterttv"},
Description: "Returns the search URL for a given BTTV emote.", Description: "Returns the search URL for a given BTTV emote.",
Level: "0", Level: "0",
Usage: "()bttv <emote name>", Usage: "()bttv <emote name>",
}, },
"catbox": { "catbox": {
Name: "catbox",
Alias: nil, Alias: nil,
Description: "Downloads the video of a given link with yt-dlp and then uploads the video to catbox.moe.", Description: "Downloads the video of a given link with yt-dlp and then uploads the video to catbox.moe.",
Level: "420", Level: "420",
Usage: "()catbox <link>", Usage: "()catbox <link>",
}, },
"coin": { "coin": {
Name: "coin",
Alias: []string{"coin", "coinflip", "cf"}, Alias: []string{"coin", "coinflip", "cf"},
Description: "Flip a coin.", Description: "Flip a coin.",
Level: "0", Level: "0",
Usage: "()coin", Usage: "()coin",
}, },
"command add": { "command add": {
Name: "command add",
Alias: nil, Alias: nil,
Description: "Adds a channel command to the database.", Description: "Adds a channel command to the database.",
Level: "250", Level: "250",
Usage: "()add command <command name> <command text>", Usage: "()add command <command name> <command text>",
}, },
"command edit level": { "command edit level": {
Name: "command edit level",
Alias: nil, Alias: nil,
Description: "Edits the required level of a channel command with the given name.", Description: "Edits the required level of a channel command with the given name.",
Level: "250", Level: "250",
Usage: "()command edit level <command name> <new command level>", Usage: "()command edit level <command name> <new command level>",
}, },
"command delete": { "command delete": {
Name: "command delete",
Alias: nil, Alias: nil,
Description: "Deletes the channel command with the given name.", Description: "Deletes the channel command with the given name.",
Level: "250", Level: "250",
Usage: "()command delete <command name>", Usage: "()command delete <command name>",
}, },
"commands": { "commands": {
Name: "commands",
Alias: nil, Alias: nil,
Description: "Returns a link to the commands in the channel.", Description: "Returns a link to the commands in the channel.",
Level: "0", Level: "0",
Usage: "()commands", Usage: "()commands",
}, },
"currency": { "currency": {
Name: "currency",
Alias: []string{"currency", "money"}, Alias: []string{"currency", "money"},
Description: "Returns the exchange rate for two currencies. Only three letter abbreviations are supported ( List of supported currencies: https://decapi.me/misc/currency?list ).", Description: "Returns the exchange rate for two currencies. Only three letter abbreviations are supported ( List of supported currencies: https://decapi.me/misc/currency?list ).",
Level: "0", Level: "0",
Usage: "()currency <curr> to <curr>", Usage: "()currency <curr> to <curr>",
}, },
"debug env": { "debug env": {
Name: "debug env",
Alias: nil, Alias: nil,
Description: "Returns the environment currently running in.", Description: "Returns the environment currently running in.",
Level: "100", Level: "100",
Usage: "()debug env", Usage: "()debug env",
}, },
"debug user": { "debug user": {
Name: "debug user",
Alias: nil, Alias: nil,
Description: "Returns additional information about a user.", Description: "Returns additional information about a user.",
Level: "100", Level: "100",
Usage: "()debug user <username>", Usage: "()debug user <username>",
}, },
"debug command": { "debug command": {
Name: "debug command",
Alias: nil, Alias: nil,
Description: "Returns additional informations about a command.", Description: "Returns additional informations about a command.",
Level: "100", Level: "100",
Usage: "()debug command <command name>", Usage: "()debug command <command name>",
}, },
"debug timers": { "debug timers": {
Name: "debug timers",
Alias: nil, Alias: nil,
Description: "Returns a list of timers currently running in the channel with additional informations.", Description: "Returns a list of timers currently running in the channel with additional informations.",
Level: "100", Level: "100",
Usage: "()debug timers", Usage: "()debug timers",
}, },
"duckduckgo": { "duckduckgo": {
Name: "duckduckgo",
Alias: []string{"duckduckgo", "ddg"}, Alias: []string{"duckduckgo", "ddg"},
Description: "Returns the duckduckgo search URL for a given query.", Description: "Returns the duckduckgo search URL for a given query.",
Level: "0", Level: "0",
Usage: "()duckduckgo <query>", Usage: "()duckduckgo <query>",
}, },
"ffz": { "ffz": {
Name: "ffz",
Alias: []string{"ffz", "frankerfacez"}, Alias: []string{"ffz", "frankerfacez"},
Description: "Returns the search URL for a given FFZ emote.", Description: "Returns the search URL for a given FFZ emote.",
Level: "0", Level: "0",
Usage: "()ffz <emote name>", Usage: "()ffz <emote name>",
}, },
"firstline": { "firstline": {
Name: "firstline",
Alias: []string{"firstline", "fl"}, Alias: []string{"firstline", "fl"},
Description: "Returns the first message a user has sent in a channel", Description: "Returns the first message a user has sent in a channel",
Level: "0", Level: "0",
Usage: "()firstline <channel> <username>", Usage: "()firstline <channel> <username>",
}, },
"followage": { "followage": {
Name: "followage",
Alias: []string{"followage", "fa"}, Alias: []string{"followage", "fa"},
Description: "Returns how long a user has been following a channel.", Description: "Returns how long a user has been following a channel.",
Level: "0", Level: "0",
Usage: "()followage <channel> <username>", Usage: "()followage <channel> <username>",
}, },
"godocs": { "godocs": {
Name: "godocs",
Alias: nil, Alias: nil,
Description: "Returns the godocs.io search URL for a given query.", Description: "Returns the godocs.io search URL for a given query.",
Level: "0", Level: "0",
Usage: "()godoc <query>", Usage: "()godoc <query>",
}, },
"gofile": { "gofile": {
Name: "gofile",
Alias: nil, Alias: nil,
Description: "Downloads the video of a given link with yt-dlp and then uploads the video to gofile.io.", Description: "Downloads the video of a given link with yt-dlp and then uploads the video to gofile.io.",
Level: "420", Level: "420",
Usage: "()gofile <link>", Usage: "()gofile <link>",
}, },
"google": { "google": {
Name: "google",
Alias: nil, Alias: nil,
Description: "Returns the google search URL for a given query.", Description: "Returns the google search URL for a given query.",
Level: "0", Level: "0",
Usage: "()google <query>", Usage: "()google <query>",
}, },
"help": { "help": {
Name: "help",
Alias: nil, Alias: nil,
Description: "Returns more information about a command 4Head.", Description: "Returns more information about a command 4Head.",
Level: "0", Level: "0",
Usage: "()help <command name>", Usage: "()help <command name>",
}, },
"join": { "join": {
Name: "join",
Alias: nil, Alias: nil,
Description: "Adds the bot to a given channel.", Description: "Adds the bot to a given channel.",
Level: "1000", Level: "1000",
Usage: "()join <channel name>", Usage: "()join <channel name>",
}, },
"kappa": { "kappa": {
Name: "kappa",
Alias: nil, Alias: nil,
Description: "Downloads the video of a given link with yt-dlp and then uploads the video to kappa.lol.", Description: "Downloads the video of a given link with yt-dlp and then uploads the video to kappa.lol.",
Level: "420", Level: "420",
Usage: "()kappa <link>", Usage: "()kappa <link>",
}, },
"lastfm": { "lastfm": {
Name: "lastfm",
Alias: nil, Alias: nil,
Description: `Look up the last played title for a user on last.fm. If you "$set lastfm" a last.fm username the command will use that username if no other username is specified.`, Description: `Look up the last played title for a user on last.fm. If you "$set lastfm" a last.fm username the command will use that username if no other username is specified.`,
Level: "0", Level: "0",
Usage: "()lastfm [username]", Usage: "()lastfm [username]",
}, },
"osrs": { "osrs": {
Name: "osrs",
Alias: nil, Alias: nil,
Description: "Returns the oldschool runescape wiki search URL for a given query.", Description: "Returns the oldschool runescape wiki search URL for a given query.",
Level: "0", Level: "0",
Usage: "()osrs <query>", Usage: "()osrs <query>",
}, },
"part": { "part": {
Name: "part",
Alias: nil, Alias: nil,
Description: "Removes the bot from a given channel.", Description: "Removes the bot from a given channel.",
Level: "1000", Level: "1000",
Usage: "()part <channel name>", Usage: "()part <channel name>",
}, },
"phonetic": { "phonetic": {
Name: "phonetic",
Alias: []string{"phonetic", "ph"}, Alias: []string{"phonetic", "ph"},
Description: "Translates the input to the character equivalent on a phonetic russian keyboard layout. Layout and general functionality is the same as on https://russian.typeit.org/", Description: "Translates the input to the character equivalent on a phonetic russian keyboard layout. Layout and general functionality is the same as on https://russian.typeit.org/",
Level: "0", Level: "0",
Usage: "()phonetic <input>", Usage: "()phonetic <input>",
}, },
"ping": { "ping": {
Name: "ping",
Alias: nil, Alias: nil,
Description: "Hopefully returns a pong monkaS.", Description: "Hopefully returns a pong monkaS.",
Level: "0", Level: "0",
Usage: "()ping", Usage: "()ping",
}, },
"predb search": { "predb search": {
Name: "predb search",
Alias: nil, Alias: nil,
Description: "Returns the last 100 predb.net search results for a given query.", Description: "Returns the last 100 predb.net search results for a given query.",
Level: "100", Level: "100",
Usage: "()predb search <query>", Usage: "()predb search <query>",
}, },
"predb group": { "predb group": {
Name: "predb group",
Alias: nil, Alias: nil,
Description: "Returns the last 100 predb.net group results for a given release group.", Description: "Returns the last 100 predb.net group results for a given release group.",
Level: "100", Level: "100",
Usage: "()predb group <group>", Usage: "()predb group <group>",
}, },
"preview": { "preview": {
Name: "preview",
Alias: []string{"preview", "thumbnail"}, Alias: []string{"preview", "thumbnail"},
Description: "Returns a link to an (almost) live screenshot of a live channel.", Description: "Returns a link to an (almost) live screenshot of a live channel.",
Level: "0", Level: "0",
Usage: "()thumbnail <channel>", Usage: "()thumbnail <channel>",
}, },
"randomxkcd": { "randomxkcd": {
Name: "randomxkcd",
Alias: []string{"randomxkcd", "rxkcd"}, Alias: []string{"randomxkcd", "rxkcd"},
Description: "Returns a link to a random xkcd comic.", Description: "Returns a link to a random xkcd comic.",
Level: "0", Level: "0",
Usage: "()randomxkcd", Usage: "()randomxkcd",
}, },
"seventv": { "seventv": {
Name: "seventv",
Alias: []string{"seventv", "7tv"}, Alias: []string{"seventv", "7tv"},
Description: "Returns the search URL for a given SevenTV emote.", Description: "Returns the search URL for a given SevenTV emote.",
Level: "0", Level: "0",
Usage: "()seventv <emote name>", Usage: "()seventv <emote name>",
}, },
"set lastfm": { "set lastfm": {
Name: "set lastfm",
Alias: nil, Alias: nil,
Description: "Allows you to set a last.fm username that will be used for $lastfm lookups if no other username is specified.", Description: "Allows you to set a last.fm username that will be used for $lastfm lookups if no other username is specified.",
Level: "0", Level: "0",
Usage: "()set lastfm <username>", Usage: "()set lastfm <username>",
}, },
"set location": { "set location": {
Name: "set location",
Alias: nil, Alias: nil,
Description: "Allows you to set a location that will be used for $weather lookups if no other location is specified.", Description: "Allows you to set a location that will be used for $weather lookups if no other location is specified.",
Level: "0", Level: "0",
Usage: "()set location <location>", Usage: "()set location <location>",
}, },
"timer add": { "timer add": {
Name: "timer add",
Alias: nil, Alias: nil,
Description: "Adds a new timer to the channel.", Description: "Adds a new timer to the channel.",
Level: "500", Level: "500",
Usage: "()timer add <name> <repeat> <text>", Usage: "()timer add <name> <repeat> <text>",
}, },
"timer delete": { "timer delete": {
Name: "timer delete",
Alias: nil, Alias: nil,
Description: "Deletes a timer from the channel.", Description: "Deletes a timer from the channel.",
Level: "500", Level: "500",
Usage: "()timer delete <name>", Usage: "()timer delete <name>",
}, },
"timer edit": { "timer edit": {
Name: "timer edit",
Alias: nil, Alias: nil,
Description: "Edits a timer from the channel.", Description: "Edits a timer from the channel.",
Level: "500", Level: "500",
Usage: "()timer edit <name> <repeat> <text>", Usage: "()timer edit <name> <repeat> <text>",
}, },
"timers": { "timers": {
Name: "timers",
Alias: nil, Alias: nil,
Description: "Returns a link to the currently active timers in the channel.", Description: "Returns a link to the currently active timers in the channel.",
Level: "0", Level: "0",
Usage: "()timers", Usage: "()timers",
}, },
"user edit level": { "user edit level": {
Name: "user edit level",
Alias: []string{"user set level"}, Alias: []string{"user set level"},
Description: "Edits the user level for a given username.", Description: "Edits the user level for a given username.",
Level: "1000", Level: "1000",
Usage: "()user edit level <username> <level>", Usage: "()user edit level <username> <level>",
}, },
"uid": { "uid": {
Name: "uid",
Alias: []string{"uid", "userid"}, Alias: []string{"uid", "userid"},
Description: "Returns the Twitch user ID for a given username.", Description: "Returns the Twitch user ID for a given username.",
Level: "0", Level: "0",
Usage: "()uid <username>", Usage: "()uid <username>",
}, },
"wa": { "wa": {
Name: "wa",
Alias: []string{"wa", "query"}, Alias: []string{"wa", "query"},
Description: "Queries the Wolfram|Alpha API about the input.", Description: "Queries the Wolfram|Alpha API about the input.",
Level: "100", Level: "100",
Usage: "()wa <input>", Usage: "()wa <input>",
}, },
"weather": { "weather": {
Name: "weather",
Alias: nil, Alias: nil,
Description: `Returns the weather for a given location. If you "$set location" your location, the command will use that location if no other location is specified.`, Description: `Returns the weather for a given location. If you "$set location" your location, the command will use that location if no other location is specified.`,
Level: "0", Level: "0",
Usage: "()weather [location]", Usage: "()weather [location]",
}, },
"xkcd": { "xkcd": {
Name: "xkcd",
Alias: nil, Alias: nil,
Description: "Returns the link to the latest xkcd comic.", Description: "Returns the link to the latest xkcd comic.",
Level: "0", Level: "0",
Usage: "()xkcd", Usage: "()xkcd",
}, },
"yaf": { "yaf": {
Name: "yaf",
Alias: nil, Alias: nil,
Description: "Downloads the video of a given link with yt-dlp and then uploads the video to yaf.li.", Description: "Downloads the video of a given link with yt-dlp and then uploads the video to yaf.li.",
Level: "420", Level: "420",

View file

@ -2,15 +2,19 @@ package main
import ( import (
"fmt" "fmt"
"html/template"
"net/http" "net/http"
"sort"
"strings" "strings"
"github.com/julienschmidt/httprouter" "github.com/julienschmidt/httprouter"
"github.com/lyx0/nourybot/internal/common" "github.com/lyx0/nourybot/internal/common"
"github.com/lyx0/nourybot/internal/data"
) )
func (app *application) startRouter() { func (app *application) startRouter() {
router := httprouter.New() router := httprouter.New()
router.GET("/", app.homeRoute)
router.GET("/status", app.statusPageRoute) router.GET("/status", app.statusPageRoute)
router.GET("/commands/:channel", app.channelCommandsRoute) router.GET("/commands/:channel", app.channelCommandsRoute)
router.GET("/commands", app.commandsRoute) router.GET("/commands", app.commandsRoute)
@ -19,16 +23,78 @@ func (app *application) startRouter() {
app.Log.Fatal(http.ListenAndServe(":8080", router)) app.Log.Fatal(http.ListenAndServe(":8080", router))
} }
func (app *application) commandsRoute(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { type commandsRouteData struct {
Commands map[string]command
}
func (app *application) commandsRoute(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
t, err := template.ParseFiles("./web/templates/commands.page.gohtml")
if err != nil {
app.Log.Error(err)
return
}
// The slice of timers is only used to log them at
// the start so it looks a bit nicer.
var cs []string var cs []string
var text string
allHelpText := app.GetAllHelpText() // Iterate over all timers and then add them onto the scheduler.
cs = append(cs, fmt.Sprintf("General commands: \n\n%s", allHelpText)) for i, v := range helpText {
// idk why this works but it does so no touchy touchy.
// https://github.com/robfig/cron/issues/420#issuecomment-940949195
i, v := i, v
_ = i
var c string
text = strings.Join(cs, "") if v.Alias == nil {
c = fmt.Sprintf("Name: %s\nDescription: %s\nLevel: %s\nUsage: %s\n\n", i, v.Description, v.Level, v.Usage)
} else {
c = fmt.Sprintf("Name: %s\nAliases: %s\nDescription: %s\nLevel: %s\nUsage: %s\n\n", i, v.Alias, v.Description, v.Level, v.Usage)
}
// Add new value to the slice
cs = append(cs, c)
}
sort.Strings(cs)
data := &commandsRouteData{helpText}
err = t.Execute(w, data)
if err != nil {
app.Log.Error(err)
return
}
}
type homeRouteData struct {
Name string
Channels []*data.Channel
}
func (app *application) homeRoute(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
t, err := template.ParseFiles("./web/templates/home.page.gohtml")
if err != nil {
app.Log.Error(err)
return
}
allChannel, err := app.Models.Channels.GetAll()
if err != nil {
app.Log.Error(err)
return
}
app.Log.Infow("All channels:",
"channel", allChannel)
data := &homeRouteData{name, allChannel}
err = t.Execute(w, data)
if err != nil {
app.Log.Error(err)
return
}
fmt.Fprintf(w, fmt.Sprint(text))
} }
func (app *application) channelCommandsRoute(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { func (app *application) channelCommandsRoute(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {

View file

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta content="width=device-width,initial-scale=1" name="viewport">
<title>nourybot - lidl twitch bot</title>
<meta property="og:title" content="nourybot - lidl twitch bot">
<meta property="og:description" content="nourybot">
</head>
<h1>Commands</h1>
<p>General commands:</p>
{{ with .Commands }}
{{ range . }}
<p>
<b>Name:</b> {{ .Name }} </br>
{{ if .Alias }}
<b>Alias:</b> {{ .Alias}} </br>
{{ else }}
{{ end}}
<b>Description:</b> {{ .Description }} </br>
<b>Level:</b> {{ .Level }} </br>
<b>Usage:</b> {{ .Usage }} </br>
</p>
{{ end }}
{{ end }}

View file

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta content="width=device-width,initial-scale=1" name="viewport">
<title>nourybot - lidl twitch bot</title>
<meta property="og:title" content="nourybot - lidl twitch bot">
<meta property="og:description" content="nourybot">
</head>
<h1>nourybot</h1>
<p>Channels connected to:</hp>
<table>
<tr>
<th>Twitch ID</th>
<th>Username</th>
</tr>
{{ with .Channels }}
{{ range . }}
<tr>
<td>{{ .TwitchID }}</td>
<td>{{ .Login }}</td>
</tr>
{{ end }}
</table>
{{ end }}