2024-10-08 21:08:01 +02:00
|
|
|
package utils
|
|
|
|
|
|
|
|
import (
|
2024-10-28 12:57:45 +01:00
|
|
|
"bytes"
|
2024-10-09 21:04:10 +02:00
|
|
|
"encoding/json"
|
2024-12-17 14:26:32 +01:00
|
|
|
"errors"
|
2024-10-09 21:04:10 +02:00
|
|
|
"fmt"
|
2024-10-28 12:57:45 +01:00
|
|
|
"image"
|
|
|
|
"image/jpeg"
|
|
|
|
_ "image/jpeg"
|
|
|
|
_ "image/png"
|
|
|
|
"io/ioutil"
|
2024-12-17 14:26:32 +01:00
|
|
|
"net/http"
|
|
|
|
"net/url"
|
2024-10-08 21:08:01 +02:00
|
|
|
"os"
|
2024-10-28 12:57:45 +01:00
|
|
|
"path/filepath"
|
2024-10-10 14:13:55 +02:00
|
|
|
"regexp"
|
|
|
|
"strings"
|
|
|
|
"unicode"
|
2024-10-28 12:57:45 +01:00
|
|
|
|
|
|
|
"github.com/nfnt/resize"
|
2024-10-08 21:08:01 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
func CreateDirIfNotExists(dir string) error {
|
|
|
|
if _, err := os.Stat(dir); os.IsNotExist(err) {
|
|
|
|
return os.MkdirAll(dir, 0755)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2024-10-09 21:04:10 +02:00
|
|
|
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--")
|
|
|
|
}
|
|
|
|
|
2024-10-10 20:04:06 +02:00
|
|
|
func Print(v interface{}) {
|
|
|
|
fmt.Println("%#v", v)
|
|
|
|
}
|
|
|
|
|
2024-10-09 21:04:10 +02:00
|
|
|
func Sep() {
|
|
|
|
separator := "════════════════════════════════════════════════"
|
|
|
|
fmt.Println(separator)
|
|
|
|
}
|
2024-10-10 14:13:55 +02:00
|
|
|
|
|
|
|
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
|
|
|
|
}
|
2024-10-28 12:57:45 +01:00
|
|
|
|
|
|
|
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
|
|
|
|
}
|
2024-12-17 14:26:32 +01:00
|
|
|
|
|
|
|
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)
|
|
|
|
}
|