147 lines
4.9 KiB
Go
147 lines
4.9 KiB
Go
package codegen
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strings"
|
|
)
|
|
|
|
// GenerateHandlerHookEvents generates hook_events.go file for handlers
|
|
func GenerateHandlerHookEvents(handlersJsonPath string, outputDir string) {
|
|
// Create output directory if it doesn't exist
|
|
err := os.MkdirAll(outputDir, os.ModePerm)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
// Read handlers.json
|
|
handlersJson, err := os.ReadFile(handlersJsonPath)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
// Parse handlers.json
|
|
var handlers []RouteHandler
|
|
err = json.Unmarshal(handlersJson, &handlers)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
// Create hook_events.go file
|
|
outFilePath := filepath.Join(outputDir, "hook_events.go")
|
|
f, err := os.Create(outFilePath)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer f.Close()
|
|
|
|
// Write package declaration and imports
|
|
f.WriteString("package handlers\n\n")
|
|
f.WriteString("import (\n")
|
|
//f.WriteString("\t\"seanime/internal/hook_resolver\"\n")
|
|
|
|
imports := []string{
|
|
"\"seanime/internal/api/anilist\"",
|
|
"\"seanime/internal/api/tvdb\"",
|
|
"\"seanime/internal/continuity\"",
|
|
"\"seanime/internal/database/models\"",
|
|
"\"seanime/internal/debrid/client\"",
|
|
"\"seanime/internal/debrid/debrid\"",
|
|
"\"seanime/internal/extension\"",
|
|
"hibikemanga \"seanime/internal/extension/hibike/manga\"",
|
|
"hibikeonlinestream \"seanime/internal/extension/hibike/onlinestream\"",
|
|
"hibiketorrent \"seanime/internal/extension/hibike/torrent\"",
|
|
"\"seanime/internal/extension_playground\"",
|
|
"\"seanime/internal/extension_repo\"",
|
|
"\"seanime/internal/hook_resolver\"",
|
|
"\"seanime/internal/library/anime\"",
|
|
"\"seanime/internal/library/summary\"",
|
|
"\"seanime/internal/manga\"",
|
|
"\"seanime/internal/manga/downloader\"",
|
|
"\"seanime/internal/mediastream\"",
|
|
"\"seanime/internal/onlinestream\"",
|
|
"\"seanime/internal/report\"",
|
|
"\"seanime/internal/sync\"",
|
|
"\"seanime/internal/torrent_clients/torrent_client\"",
|
|
"\"seanime/internal/torrents/torrent\"",
|
|
"\"seanime/internal/torrentstream\"",
|
|
"\"seanime/internal/updater\"",
|
|
}
|
|
|
|
for _, imp := range imports {
|
|
f.WriteString("\t" + imp + "\n")
|
|
}
|
|
|
|
f.WriteString(")\n\n")
|
|
|
|
// Generate events for each handler
|
|
for _, handler := range handlers {
|
|
// Skip if handler name is empty or doesn't start with 'Handle'
|
|
if handler.Name == "" || !strings.HasPrefix(handler.Name, "Handle") {
|
|
continue
|
|
}
|
|
|
|
// Generate the "Requested" event
|
|
f.WriteString(fmt.Sprintf("// %sRequestedEvent is triggered when %s is requested.\n", handler.Name, handler.TrimmedName))
|
|
f.WriteString("// Prevent default to skip the default behavior and return your own data.\n")
|
|
f.WriteString(fmt.Sprintf("type %sRequestedEvent struct {\n", handler.Name))
|
|
f.WriteString("\thook_resolver.Event\n")
|
|
|
|
// Add path parameters
|
|
for _, param := range handler.Api.Params {
|
|
f.WriteString(fmt.Sprintf("\t%s %s `json:\"%s\"`\n", pascalCase(param.Name), param.GoType, param.JsonName))
|
|
}
|
|
|
|
// Add body fields
|
|
for _, field := range handler.Api.BodyFields {
|
|
goType := field.GoType
|
|
if goType == "__STRUCT__" || goType == "[]__STRUCT__" || (strings.HasPrefix(goType, "map[") && strings.Contains(goType, "__STRUCT__")) {
|
|
goType = field.InlineStructType
|
|
}
|
|
goType = strings.Replace(goType, "handlers.", "", 1)
|
|
addPointer := isCustomStruct(goType)
|
|
if addPointer {
|
|
goType = "*" + goType
|
|
}
|
|
f.WriteString(fmt.Sprintf("\t%s %s `json:\"%s\"`\n", pascalCase(field.Name), goType, field.JsonName))
|
|
}
|
|
|
|
// If handler returns something other than bool or true, add a Data field to store the result
|
|
if handler.Api.ReturnGoType != "" && handler.Api.ReturnGoType != "true" && handler.Api.ReturnGoType != "bool" {
|
|
returnGoType := strings.Replace(handler.Api.ReturnGoType, "handlers.", "", 1)
|
|
addPointer := isCustomStruct(returnGoType)
|
|
if addPointer {
|
|
returnGoType = "*" + returnGoType
|
|
}
|
|
f.WriteString(fmt.Sprintf("\t// Empty data object, will be used if the hook prevents the default behavior\n"))
|
|
f.WriteString(fmt.Sprintf("\tData %s `json:\"data\"`\n", returnGoType))
|
|
}
|
|
|
|
f.WriteString("}\n\n")
|
|
|
|
// Generate the response event if handler returns something other than bool or true
|
|
if handler.Api.ReturnGoType != "" && handler.Api.ReturnGoType != "true" && handler.Api.ReturnGoType != "bool" {
|
|
returnGoType := strings.Replace(handler.Api.ReturnGoType, "handlers.", "", 1)
|
|
addPointer := isCustomStruct(returnGoType)
|
|
if addPointer {
|
|
returnGoType = "*" + returnGoType
|
|
}
|
|
f.WriteString(fmt.Sprintf("// %sEvent is triggered after processing %s.\n", handler.Name, handler.TrimmedName))
|
|
f.WriteString(fmt.Sprintf("type %sEvent struct {\n", handler.Name))
|
|
f.WriteString("\thook_resolver.Event\n")
|
|
f.WriteString(fmt.Sprintf("\tData %s `json:\"data\"`\n", returnGoType))
|
|
f.WriteString("}\n\n")
|
|
}
|
|
}
|
|
|
|
cmd := exec.Command("gofmt", "-w", outFilePath)
|
|
cmd.Run()
|
|
}
|
|
|
|
func pascalCase(s string) string {
|
|
return strings.ReplaceAll(strings.Title(strings.ReplaceAll(s, "_", " ")), " ", "")
|
|
}
|