diff --git a/.env b/.env
index 5844601..df09d75 100644
--- a/.env
+++ b/.env
@@ -1,2 +1 @@
-PORT=8080
PORT=3001
diff --git a/README.md b/README.md
index eef5dd7..441343c 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,16 @@
-# Hash maps
+# Random Image API
## Usage
-**http://`host`:`port`/render?seed=`any`&w=`[1..100]`&h=`[1..100]`**
-> width and height are not required, default is 7x7
+host: https://readyyyk-randimgapi.onrender.com/
+**http://`host`:`port`/hashmaps?`...[url params]`**
+**http://`host`:`port`/picsum?`...[url params]`**
+> width and height defaults:
+> - hashmaps - 7x7
+> - picsum - 64x64
-> returns `svg` image
+> returns:
+> - hashmaps - `svg` image
+> - picsum - `jpeg` image
## Installation
diff --git a/hashMaps b/hashMaps
new file mode 100755
index 0000000..701d567
Binary files /dev/null and b/hashMaps differ
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..80bdbed
--- /dev/null
+++ b/index.html
@@ -0,0 +1,17 @@
+
+ https://github.com/readyyyk/randImgAPI
+
+
+
+ Use some of these routes:
+
+
+ Use these url params:
+
+ - seed int/string
+ - w int (for hashmaps <100)
+ - h int (for hashmaps <100)
+
\ No newline at end of file
diff --git a/main.go b/main.go
index 2f26542..df0f318 100644
--- a/main.go
+++ b/main.go
@@ -6,19 +6,74 @@ import (
svg "github.com/ajstarks/svgo"
"github.com/joho/godotenv"
"io"
+ "math"
"math/rand"
"net/http"
"os"
"strconv"
+ "time"
)
+func checkError(err error, httpCode int, httpRes http.ResponseWriter) bool {
+ if err != nil {
+ httpRes.WriteHeader(httpCode)
+ fmt.Println(" [ERROR] - " + err.Error())
+ return true
+ }
+ return false
+}
+
+func stringToInt64(s string) int64 {
+ seed := int64(1)
+ for _, c := range s {
+ seed *= int64(c - '0')
+ }
+ return seed
+}
+
+func getWHUrlParams(req *http.Request, w *int, h *int, maxW int, maxH int) (err error) {
+ if !req.URL.Query().Has("w") && !req.URL.Query().Has("h") {
+ return nil
+ }
+ if req.URL.Query().Has("w") {
+ wUrl, err := strconv.Atoi(req.URL.Query().Get("w"))
+ if err != nil {
+ return err
+ }
+ if wUrl < 1 || wUrl > maxW {
+ return err
+ }
+ *w, *h = wUrl, wUrl
+ }
+ if req.URL.Query().Has("h") {
+ hUrl, err := strconv.Atoi(req.URL.Query().Get("h"))
+ if err != nil {
+ return err
+ }
+ if hUrl < 1 || hUrl > maxH {
+ return err
+ }
+ *h = hUrl
+ }
+ return nil
+}
+
func main() {
+ http.HandleFunc("/", func(res http.ResponseWriter, req *http.Request) {
+ fileData, err := os.ReadFile("index.html")
+ if checkError(err, http.StatusInternalServerError, res) {
+ return
+ }
+ res.Header().Set("Content-Type", "text/html")
+ _, _ = res.Write(fileData)
+ })
+
// seed - required
// w - width (if not defined 7) in range [1..100]
// h - height (if not defined 7 or same as defined width) in range [1..100]
// /render?seed=any&w=number&h=number
- http.HandleFunc("/render", func(res http.ResponseWriter, req *http.Request) {
- fmt.Println("[hashMap]")
+ http.HandleFunc("/hashmap", func(res http.ResponseWriter, req *http.Request) {
+ fmt.Println("\n[hashMap]")
if req.Method != "GET" {
res.WriteHeader(http.StatusBadRequest)
return
@@ -26,40 +81,20 @@ func main() {
res.Header().Set("Content-Type", "image/svg+xml")
// setting random seed
- seedStr := req.URL.Query().Get("seed")
- seed := int64(1)
- for _, c := range seedStr {
- seed *= int64(c - '0')
+ seed := time.Now().UnixNano()
+ if req.URL.Query().Has("seed") {
+ seed = stringToInt64(req.URL.Query().Get("seed"))
}
- fmt.Println(seed)
rand.Seed(seed)
+ fmt.Println("seed: ", seed)
// getting width and height with default 7x7 and in range of [1..100]
w, h := 7, 7
- if req.URL.Query().Has("w") {
- wUrl, err := strconv.Atoi(req.URL.Query().Get("w"))
- if err != nil {
- res.WriteHeader(http.StatusBadRequest)
- return
- }
- if wUrl < 1 || wUrl > 100 {
- res.WriteHeader(http.StatusBadRequest)
- return
- }
- w, h = wUrl, wUrl
- }
- if req.URL.Query().Has("w") {
- hUrl, err := strconv.Atoi(req.URL.Query().Get("h"))
- if err != nil {
- res.WriteHeader(http.StatusBadRequest)
- return
- }
- if hUrl < 1 || hUrl > 100 {
- res.WriteHeader(http.StatusBadRequest)
- return
- }
- h = hUrl
- }
+ checkError(
+ getWHUrlParams(req, &w, &h, 100, 100),
+ http.StatusBadRequest,
+ res,
+ )
colors := []string{"#000", "#fff"}
img := svg.New(res)
@@ -72,64 +107,82 @@ func main() {
}
img.End()
})
+
http.HandleFunc("/picsum", func(res http.ResponseWriter, req *http.Request) {
- fmt.Println("[picsum]")
+ fmt.Println("\n[picsum]")
if req.Method != "GET" {
res.WriteHeader(http.StatusBadRequest)
return
}
- if !req.URL.Query().Has("seed") {
- res.WriteHeader(http.StatusBadRequest)
- return
+
+ // setting random seed
+ seed := strconv.Itoa(int(time.Now().UnixNano()))
+ if req.URL.Query().Has("seed") {
+ seed = req.URL.Query().Get("seed")
}
+ fmt.Println(" seed: " + seed)
// fetching info from picsum/.../info and getting donwload url
- fetchedData, err := http.Get("https://picsum.photos/seed/" + req.URL.Query().Get("seed") + "/info")
- if err != nil {
- res.WriteHeader(http.StatusInternalServerError)
- panic(err)
+ fetchedData, err := http.Get("https://picsum.photos/seed/" + seed + "/info")
+ if checkError(err, http.StatusInternalServerError, res) {
return
}
+
data, err := io.ReadAll(fetchedData.Body)
- if err != nil {
- res.WriteHeader(http.StatusInternalServerError)
- panic(err)
+ if checkError(err, http.StatusInternalServerError, res) {
return
}
+
type downloadUrl struct {
Url string `json:"download_url"`
}
var url downloadUrl
err = json.Unmarshal(data, &url)
- if err != nil {
- res.WriteHeader(http.StatusInternalServerError)
- panic(err)
+ if checkError(err, http.StatusInternalServerError, res) {
return
}
// processing download url
- url.Url = url.Url[:len(url.Url)-9] + "64/64"
+ w, h := 64, 64
+ checkError(
+ getWHUrlParams(req, &w, &h, math.MaxInt, math.MaxInt),
+ http.StatusBadRequest,
+ res,
+ )
- // fetching entire image
+ isSecondSlash := false
+ for i := len(url.Url) - 1; i >= -1; i-- {
+ if url.Url[i] != '/' {
+ continue
+ }
+ if !isSecondSlash {
+ isSecondSlash = true
+ continue
+ }
+ url.Url = url.Url[0 : i+1]
+ break
+ }
+ url.Url = url.Url + strconv.Itoa(w) + "/" + strconv.Itoa(h)
+
+ // reading image
fetchedData, err = http.Get(url.Url)
- if err != nil {
- res.WriteHeader(http.StatusInternalServerError)
- panic(err)
+ if checkError(err, http.StatusInternalServerError, res) {
return
}
+
data, err = io.ReadAll(fetchedData.Body)
- if err != nil {
- res.WriteHeader(http.StatusInternalServerError)
- panic(err)
+ if checkError(err, http.StatusInternalServerError, res) {
return
}
- res.Header().Set("Content-Type", "image/jpeg")
+ // writing response
+ res.Header().Set("Content-Type", req.Header.Get("Content-Type"))
_, _ = res.Write(data)
- res.WriteHeader(http.StatusOK)
return
})
+
err := godotenv.Load(".env")
+ fmt.Println("[SERVER] - starting on :" + os.Getenv("PORT") + " ...")
err = http.ListenAndServe(":"+os.Getenv("PORT"), nil)
if err != nil {
panic(err)