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) }