Commit 3ffbb917 authored by Rafael's avatar Rafael

feat: resize and save thumbnails images of post album

parent 4c15de6a
Pipeline #20389105 passed with stage
in 1 minute and 41 seconds
......@@ -3,12 +3,24 @@ package generic
import (
"database/sql"
"fmt"
"image"
"image/gif"
"image/jpeg"
"image/png"
"log"
"math"
"math/rand"
"net/http"
"os"
"path/filepath"
"strconv"
"strings"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3/s3manager"
"github.com/nfnt/resize"
"gitlab.com/shereland/graphql/database"
)
......@@ -56,11 +68,12 @@ type album struct {
}
type photo struct {
postID string
albumTitle string
url string
title string
alt string
postID string
albumTitle string
url string
thumbnailURL string
title string
alt string
}
// GetPopularPosts get most popular posts from last week
......@@ -387,7 +400,8 @@ func getAlbuns(db *sql.DB, postsIDArray []string) map[string]interface{} {
// albuns := make(map[string][]map[string]string, 0)
albuns := make(map[string]interface{}, 0)
queryIDs := strings.Join(postsIDArray, ", ")
query := `SELECT blog_post.id, blog_album.title, blog_photo.image, blog_photo.title, blog_photo.alt
query := `SELECT blog_post.id, blog_album.title, blog_photo.image, blog_photo.image_thumbnail,
blog_photo.title, blog_photo.alt
FROM blog_post
INNER JOIN blog_album
ON blog_post.album_id = blog_album.id
......@@ -397,7 +411,7 @@ func getAlbuns(db *sql.DB, postsIDArray []string) map[string]interface{} {
rows, _ := db.Query(query)
for rows.Next() {
var p photo
if err := rows.Scan(&p.postID, &p.albumTitle, &p.url, &p.title, &p.alt); err != nil {
if err := rows.Scan(&p.postID, &p.albumTitle, &p.url, &p.thumbnailURL, &p.title, &p.alt); err != nil {
fmt.Println("Error on getAlbuns - err := rows.Scan")
fmt.Println(err)
}
......@@ -412,8 +426,8 @@ func getAlbuns(db *sql.DB, postsIDArray []string) map[string]interface{} {
mediaURL := os.Getenv("MEDIA_URL")
photo["title"] = p.title
photo["alt"] = p.alt
photo["image"] = mediaURL + p.url
photo["thumbnail"] = mediaURL + p.url
photo["image"] = mediaURL + "/" + p.url
photo["thumbnail"] = getThumbnail(db, mediaURL, p.url, p.thumbnailURL)
album := albuns[p.postID].(map[string]interface{})["photos"]
album = append(album.([]map[string]string), photo)
......@@ -423,6 +437,101 @@ func getAlbuns(db *sql.DB, postsIDArray []string) map[string]interface{} {
return albuns
}
// getThumbnail if thumbnail exist, just return it
// Otherwise:
// - Download the original
// - Resize
// - Save on S3 and on database
// - Return the thumbnail
// This is a slow function, but should be fast on most cases
// (thumbnail is persisted on db, so it should be called only on first time
// the album is opened)
func getThumbnail(db *sql.DB, mediaURL, photoURL, thumbnailURL string) string {
if thumbnailURL != "" {
return mediaURL + "/" + thumbnailURL
}
var err error
fileExtension := filepath.Ext(photoURL)
rand.Seed(time.Now().Unix())
randomImageName := "img-" + strconv.Itoa(rand.Int())
tempFileLocation := "/tmp/" + randomImageName + fileExtension
s3File := mediaURL + "/" + photoURL
fileNoExtension := strings.TrimSuffix(photoURL, filepath.Ext(photoURL))
// Download the original
response, e := http.Get(s3File)
if e != nil {
fmt.Println(e)
}
defer response.Body.Close()
// Resize
var img image.Image
if fileExtension == ".jpg" || fileExtension == ".jpeg" {
img, err = jpeg.Decode(response.Body)
} else if fileExtension == ".gif" {
img, err = gif.Decode(response.Body)
} else if fileExtension == ".png" {
img, err = png.Decode(response.Body)
} else {
fmt.Println("getThumbnail error: Format not recognized - " + photoURL)
}
if err != nil {
fmt.Println(err)
}
m := resize.Resize(0, 79, img, resize.Lanczos3)
// Save local
out, err := os.Create(tempFileLocation)
if err != nil {
log.Fatal(err)
}
defer out.Close()
png.Encode(out, m)
// Upload to S3
bucket := os.Getenv("AWS_S3_BUCKET")
acl := "public-read"
file, err := os.Open(tempFileLocation)
if err != nil {
fmt.Println("Failed to open file", tempFileLocation, err)
os.Exit(1)
}
defer file.Close()
conf := aws.Config{Region: aws.String("us-west-2")}
sess := session.New(&conf)
svc := s3manager.NewUploader(sess)
contentType := "image/png"
imageThumbnailName := fileNoExtension + "-thumbnail.png"
_, err = svc.Upload(&s3manager.UploadInput{
Bucket: aws.String(bucket),
Key: aws.String("media/" + imageThumbnailName),
Body: file,
ACL: &acl,
ContentType: &contentType,
})
if err != nil {
fmt.Println("error", err)
}
// Update database
query := `UPDATE blog_photo
SET image_thumbnail=?
WHERE image=?`
stmt, err := db.Prepare(query)
if err != nil {
fmt.Println("Failed to update blog_photo")
}
defer stmt.Close()
stmt.Exec(imageThumbnailName, photoURL)
return mediaURL + "/" + imageThumbnailName
}
// GetNumberOfPages return number of pages
func GetNumberOfPages(category string) int32 {
var numberOfPages int32
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment