-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
141 lines (117 loc) · 4.06 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package main
import (
"context"
"encoding/json"
"fmt"
"github.com/aws/aws-lambda-go/lambda"
"github.com/oguzhantasimaz/unsplash-recap/unsplash"
"github.com/oguzhantasimaz/unsplash-recap/upstash"
"github.com/oguzhantasimaz/unsplash-recap/utils"
log "github.com/sirupsen/logrus"
"os"
)
type UnsplashRecapEvent struct {
Body string `json:"body"`
}
func (u *UnsplashRecapEvent) Validate() error {
if u.Body == "" {
return fmt.Errorf("body is empty")
}
return nil
}
func main() {
lambda.Start(HandleRequest)
}
func HandleRequest(ctx context.Context, event UnsplashRecapEvent) (*utils.Response, error) {
// Validate event
err := event.Validate()
if err != nil {
return utils.JSONResponse(400, err.Error(), err.Error()), nil
}
accessKey := os.Getenv("UNSPLASH_ACCESS_KEY")
if accessKey == "" {
return utils.JSONResponse(500, "unsplash access key is empty", utils.ErrorResponseBody{Message: "unsplash access key is empty"}), fmt.Errorf("unsplash access key is empty")
}
redisUrl := os.Getenv("UPSTASH_REDIS_REST_URL")
if redisUrl == "" {
return utils.JSONResponse(500, "redis url is empty", utils.ErrorResponseBody{Message: "redis url is empty"}), fmt.Errorf("redis url is empty")
}
redisToken := os.Getenv("UPSTASH_REDIS_REST_TOKEN")
if redisToken == "" {
return utils.JSONResponse(500, "redis token is empty", utils.ErrorResponseBody{Message: "redis token is empty"}), fmt.Errorf("redis token is empty")
}
username, err := utils.GetUsernameFromBody(event.Body)
if err != nil {
return utils.JSONResponse(400, err.Error(), utils.ErrorResponseBody{Message: err.Error()}), nil
}
// Create Upstash Redis REST client
client := upstash.NewClient(redisUrl, redisToken)
// Check if username is cached
cached, err := client.Get(username)
if err != nil {
log.Error(err)
return utils.JSONResponse(500, err.Error(), utils.ErrorResponseBody{Message: err.Error()}), fmt.Errorf("failed to get cached username: %s", err.Error())
}
if cached != nil {
log.Printf("username: %s is cached", username)
// Unmarshal cached username
var recap *unsplash.Recap
err = json.Unmarshal([]byte(*cached), &recap)
if err != nil {
return utils.JSONResponse(500, err.Error(), utils.ErrorResponseBody{Message: err.Error()}), fmt.Errorf("failed to unmarshal cached username: %s", err.Error())
}
return utils.JSONResponse(200, "Success", recap), nil
}
// Get recap
var recap *unsplash.Recap
recap, err = getRecap(username, accessKey)
if err != nil {
return utils.JSONResponse(500, err.Error(), utils.ErrorResponseBody{Message: err.Error()}), nil
}
if recap == nil {
return utils.JSONResponse(500, "recap is nil", utils.ErrorResponseBody{Message: "recap is nil"}), nil
}
if recap.TotalPhotos == 0 {
return utils.JSONResponse(500, "user has no photos", utils.ErrorResponseBody{Message: "user has no photos"}), nil
}
err = client.Set(username, recap)
if err != nil {
log.Error(err)
return utils.JSONResponse(500, err.Error(), utils.ErrorResponseBody{Message: err.Error()}), fmt.Errorf("failed to set cached username: %s", err.Error())
}
return utils.JSONResponse(200, "Success", recap), nil
}
func getRecap(username, accessKey string) (*unsplash.Recap, error) {
client := unsplash.NewClient(accessKey)
var err error
var photos []*unsplash.UserPhoto
// Get first list of photos
photos, err = client.Photo().GetUserPhotos(username, 1)
if err != nil {
return nil, err
}
if len(photos) == 0 {
return nil, fmt.Errorf("user has no photos")
}
if photos[0].CreatedAt.Year() < 2023 {
return nil, fmt.Errorf("user has no photos in 2023")
}
if len(photos) == 30 {
// Get users photo if last photo is still in 2023 get next page
for i := 2; utils.CheckLastPhotoYear(photos, 2023); i++ {
newPagePhotos, err := client.Photo().GetUserPhotos(username, i)
if err != nil {
return nil, err
}
if len(newPagePhotos) < 30 {
photos = append(photos, newPagePhotos...)
break
}
photos = append(photos, newPagePhotos...)
}
}
// Filter photos by year
photos = utils.FilterByYear(photos, 2023)
// Get recap
return utils.GetRecapFromPhotos(photos), nil
}