hugo-medialog/utils/utils.go
Óscar M. Lage 80b872d6e9 Add FetchImageFromGoogle function for the images download
From now on we can use both: fanart and google for the images download. By
default it will be using fanart but if we want to use google because images
in fanart are not appropriate (or it didn't find anything because the
content is Spanish or reasons), we can add the following to the .md:

```yml
query: google
```

And it should use google for image searching instead of fanart.
2024-12-17 14:29:54 +01:00

173 lines
4.1 KiB
Go

package utils
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"image"
"image/jpeg"
_ "image/jpeg"
_ "image/png"
"io/ioutil"
"net/http"
"net/url"
"os"
"path/filepath"
"regexp"
"strings"
"unicode"
"github.com/nfnt/resize"
)
func CreateDirIfNotExists(dir string) error {
if _, err := os.Stat(dir); os.IsNotExist(err) {
return os.MkdirAll(dir, 0755)
}
return nil
}
func Debug(v interface{}, args ...string) {
// utils.Debug(variable)
debug, err := json.MarshalIndent(v, "", " ")
if err != nil {
fmt.Println("Error marshaling JSON:", err)
return
}
// Print a title if there is one
if len(args) > 0 {
fmt.Printf("%s\n", args[0])
}
fmt.Printf("DEBUG:\n%s\n", string(debug))
}
func DebugBody(body []byte) {
// utils.DebugBody(body)
var jsonResponse interface{}
err := json.Unmarshal(body, &jsonResponse)
if err != nil {
fmt.Println("Error unmarshaling JSON:", err)
}
Debug(jsonResponse, "--API RESPONSE--")
}
func Print(v interface{}) {
fmt.Println("%#v", v)
}
func Sep() {
separator := "════════════════════════════════════════════════"
fmt.Println(separator)
}
func Sluggify(s string) string {
slug := strings.ToLower(s)
var b strings.Builder
for _, r := range slug {
if unicode.IsLetter(r) || unicode.IsDigit(r) {
b.WriteRune(r)
} else {
switch r {
case ' ', '-', '_':
b.WriteRune('-')
}
}
}
slug = b.String()
reg := regexp.MustCompile("[^a-z0-9-]+")
slug = reg.ReplaceAllString(slug, "")
slug = strings.ReplaceAll(slug, "--", "-")
slug = strings.Trim(slug, "-")
return slug
}
func GenerateThumbnails(originalPath, slug, outputDir string, resolutions []uint) error {
// Open the original image
file, err := os.Open(originalPath)
if err != nil {
return fmt.Errorf("error opening original image: %w", err)
}
defer file.Close()
imgData, err := ioutil.ReadAll(file)
if err != nil {
return fmt.Errorf("error reading original image data: %w", err)
}
// Decode the original image
img, _, err := image.Decode(bytes.NewReader(imgData))
if err != nil {
return fmt.Errorf("error decoding image: %w", err)
}
// Generate thumbnails for each resolution
for _, res := range resolutions {
// Resize the image while maintaining the aspect ratio
thumbnail := resize.Resize(res, 0, img, resize.Lanczos3)
// Define the new filename with resolution suffix
thumbnailFilename := fmt.Sprintf("%s-%d.jpg", slug, res)
thumbnailPath := filepath.Join(outputDir, thumbnailFilename)
// Save the resized image
thumbnailFile, err := os.Create(thumbnailPath)
if err != nil {
return fmt.Errorf("error creating thumbnail file: %w", err)
}
defer thumbnailFile.Close()
err = jpeg.Encode(thumbnailFile, thumbnail, nil)
if err != nil {
return fmt.Errorf("error encoding thumbnail: %w", err)
}
fmt.Printf(" - Thumbnail saved successfully at: %s\n", thumbnailPath)
}
return nil
}
func FetchImageFromGoogle(query string) (string, error) {
apiKey := os.Getenv("GOOGLE_CUSTOM_SEARCH_ENGINE_API_KEY")
cx := os.Getenv("GOOGLE_CX")
searchURL := fmt.Sprintf("https://www.googleapis.com/customsearch/v1?q=%s&key=%s&searchType=image&num=1&cx=%s&gl=es&lr=lang_es", url.QueryEscape(query), apiKey, cx)
resp, err := http.Get(searchURL)
if err != nil {
error := fmt.Sprintf("Error fetching cover from Google Images API: %s\n", err)
fmt.Printf(error)
return "", errors.New(error)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
error := fmt.Sprintf("Error fetching cover, status code: %d\n", resp.StatusCode)
fmt.Printf(error)
return "", errors.New(error)
}
var result map[string]interface{}
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
error := fmt.Sprintf("Error decoding JSON response: %s\n", err)
fmt.Printf(error)
return "", errors.New(error)
}
if items, ok := result["items"].([]interface{}); ok && len(items) > 0 {
if link, ok := items[0].(map[string]interface{})["link"].(string); ok {
return link, nil
}
}
error := fmt.Sprintf("Other error has happened")
fmt.Printf(error)
return "", errors.New(error)
}