mirror of
https://github.com/IllusionMan1212/kotapi-go.git
synced 2026-10-24 10:12:29 +00:00
initial commit
This commit is contained in:
@@ -0,0 +1,242 @@
|
||||
package routes
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"illusionman1212/kotapi-go/db"
|
||||
"illusionman1212/kotapi-go/models"
|
||||
"image/jpeg"
|
||||
"image/png"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/edwvee/exiffix"
|
||||
"github.com/gorilla/mux"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
)
|
||||
|
||||
func RandomHandler(w http.ResponseWriter, req *http.Request) {
|
||||
var kot models.Kot
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Header().Set("Access-Control-Allow-Methods", "GET")
|
||||
|
||||
max, err := db.Kots.EstimatedDocumentCount(db.Ctx)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(`{ "error": "An error has occurred while querying the database", "status": 500, "failed": true }`))
|
||||
return
|
||||
}
|
||||
|
||||
// seed the default source using the current time in unix nanosecond format
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
// generate random number between 0 and `max`
|
||||
num := rand.Intn(int(max + 1))
|
||||
|
||||
// find the random kot document and store it in the `kot` variable
|
||||
err = db.Kots.FindOne(db.Ctx, bson.M{"id": num}).Decode(&kot)
|
||||
if err != nil {
|
||||
if err == mongo.ErrNoDocuments {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
w.Write([]byte(`{ "error": "Not found","status": 404, "failed": true }`))
|
||||
} else {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(`{ "error": "An unknown error has occurred","status": 500, "failed": true }`))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// create a json from the kot struct variable and then write it as a response
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte(`{
|
||||
"id": "` + strconv.Itoa(int(kot.MyID)) + `",
|
||||
"url": "` + kot.Url + `",
|
||||
"compressed_url": "` + kot.CompressedUrl + `",
|
||||
"status": 200,
|
||||
"failed": false
|
||||
}`))
|
||||
}
|
||||
|
||||
func IdHandler(w http.ResponseWriter, req *http.Request) {
|
||||
params := mux.Vars(req)
|
||||
var kot models.Kot
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Header().Set("Access-Control-Allow-Methods", "GET")
|
||||
|
||||
id, err := strconv.Atoi(params["id"])
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(`{ "error": "Invalid or incomplete request","status": 400, "failed": true }`))
|
||||
return
|
||||
}
|
||||
|
||||
err = db.Kots.FindOne(db.Ctx, bson.M{"id": id}).Decode(&kot)
|
||||
if err != nil {
|
||||
if err == mongo.ErrNoDocuments {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
w.Write([]byte(`{ "error": "Not found","status": 404, "failed": true }`))
|
||||
} else {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(`{ "error": "An unknown error has occurred","status": 500, "failed": true }`))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte(`{
|
||||
"id": "` + strconv.Itoa(int(kot.MyID)) + `",
|
||||
"url": "` + kot.Url + `",
|
||||
"compressed_url": "` + kot.CompressedUrl + `",
|
||||
"status": 200,
|
||||
"failed": false
|
||||
}`))
|
||||
}
|
||||
|
||||
func AddKotHandler(w http.ResponseWriter, req *http.Request) {
|
||||
var kot models.Kot
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Header().Set("Access-Control-Allow-Methods", "POST")
|
||||
|
||||
// 10 MB file size limit
|
||||
req.ParseMultipartForm(10 << 20)
|
||||
|
||||
file, handler, err := req.FormFile("image")
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(`{ "error": "Invalid or incomplete request","status": 400, "failed": true }`))
|
||||
return
|
||||
}
|
||||
|
||||
password := req.Form.Get("password")
|
||||
if password == "" {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(`{ "error": "Invalid or incomplete request","status": 400, "failed": true }`))
|
||||
return
|
||||
}
|
||||
if password != os.Getenv("PASSWORD") {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte(`{ "error": "Not authorized","status": 401, "failed": true }`))
|
||||
return
|
||||
}
|
||||
|
||||
filename := make([]byte, 16)
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
_, err = rand.Read(filename)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(`{ "error": "An unknown error has occurred","status": 500, "failed": true }`))
|
||||
return
|
||||
}
|
||||
|
||||
extensions := strings.Split(handler.Filename, ".")
|
||||
extension := strings.ToLower(extensions[len(extensions)-1])
|
||||
|
||||
defer file.Close()
|
||||
|
||||
data := make([]byte, handler.Size)
|
||||
file.Read(data)
|
||||
compressedData := data
|
||||
|
||||
if extension == "png" {
|
||||
enc := &png.Encoder{
|
||||
CompressionLevel: png.BestCompression,
|
||||
}
|
||||
buf := &bytes.Buffer{}
|
||||
decodedImage, err := png.Decode(bytes.NewReader(data))
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(`{ "error": "An error occurred while compressing the image","status": 500, "failed": true }`))
|
||||
return
|
||||
}
|
||||
enc.Encode(buf, decodedImage)
|
||||
compressedData = buf.Bytes()
|
||||
} else if extension == "jpeg" || extension == "jpg" {
|
||||
decodedImage, _, err := exiffix.Decode(bytes.NewReader(data))
|
||||
buf := &bytes.Buffer{}
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(`{ "error": "An error occurred while compressed the image","status": 500, "failed": true }`))
|
||||
return
|
||||
}
|
||||
|
||||
jpeg.Encode(buf, decodedImage, &jpeg.Options{Quality: 75})
|
||||
compressedData = buf.Bytes()
|
||||
}
|
||||
|
||||
os.Mkdir("./kots", 0755)
|
||||
os.Mkdir("./kots/compressed", 0755)
|
||||
newFile, err := os.Create(fmt.Sprintf("./kots/%x.%s", filename, extension))
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(`{ "error": "An error occurred while writing the file","status": 500, "failed": true }`))
|
||||
return
|
||||
}
|
||||
|
||||
defer newFile.Close()
|
||||
newFile.Write(data)
|
||||
|
||||
compressedNewFile, err := os.Create(fmt.Sprintf("./kots/compressed/%x.%s", filename, extension))
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(`{ "error": "An error occurred while writing compressed file","status": 500, "failed": true }`))
|
||||
return
|
||||
}
|
||||
|
||||
defer compressedNewFile.Close()
|
||||
compressedNewFile.Write(compressedData)
|
||||
|
||||
count, err := db.Kots.EstimatedDocumentCount(db.Ctx)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(`{ "error": "An unknown error has occurred","status": 500, "failed": true }`))
|
||||
return
|
||||
}
|
||||
|
||||
kot.ID = primitive.NewObjectIDFromTimestamp(time.Now())
|
||||
kot.MyID = int32(count + 1)
|
||||
kot.Url = fmt.Sprintf("%s/kots/%x.%s", os.Getenv("BASE_URL"), filename, extension)
|
||||
kot.CompressedUrl = fmt.Sprintf("%s/kots/compressed/%x.%s", os.Getenv("BASE_URL"), filename, extension)
|
||||
|
||||
_, err = db.Kots.InsertOne(db.Ctx, kot)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(`{ "error": "An unknown error has occurred","status": 500, "failed": true }`))
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte(`{ "message": "Successfully welcomed a new kot :)" "status": 200, "failed": false }`))
|
||||
}
|
||||
|
||||
func KotsHandler(w http.ResponseWriter, req *http.Request) {
|
||||
filename := mux.Vars(req)
|
||||
filepath := fmt.Sprintf("./kots/%s", filename["filename"])
|
||||
_, err := os.Stat(filepath)
|
||||
if err != nil {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
w.Write([]byte(`{ "error": "Not found","status": 404, "failed": true }`))
|
||||
return
|
||||
}
|
||||
http.ServeFile(w, req, filepath)
|
||||
}
|
||||
|
||||
func KotsCompressedHandler(w http.ResponseWriter, req *http.Request) {
|
||||
filename := mux.Vars(req)
|
||||
filepath := fmt.Sprintf("./kots/compressed/%s", filename["filename"])
|
||||
_, err := os.Stat(filepath)
|
||||
if err != nil {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
w.Write([]byte(`{ "error": "Not found","status": 404, "failed": true }`))
|
||||
return
|
||||
}
|
||||
http.ServeFile(w, req, filepath)
|
||||
}
|
||||
Reference in New Issue
Block a user