remove old named files

This commit is contained in:
pluja 2024-02-10 13:50:07 +01:00
parent 240f6c9cd1
commit 2a26a3d35b
2 changed files with 0 additions and 503 deletions

View File

@ -1,179 +0,0 @@
package server
import (
"bytes"
"fmt"
"image"
"image/color"
"image/draw"
"image/png"
"io"
"net/http"
"strings"
"github.com/golang/freetype"
"github.com/golang/freetype/truetype"
"github.com/kataras/iris/v12"
"github.com/rs/zerolog/log"
"golang.org/x/image/font"
"golang.org/x/image/font/gofont/gomonobold"
"pluja.dev/kycnot.me/database"
)
func (s *Server) handleVerifyPow(c iris.Context) {
// Get id, nonce and proof from the request
id := c.Params().Get("id")
nonce := c.Params().Get("nonce")
// Verify the proof of work
valid := s.PowChallenger.PowVerifyProof(id, nonce)
// Return the result
c.JSON(iris.Map{
"valid": valid,
"status": iris.StatusOK,
})
}
// Proxies the request to the logo URL of a service by its ID
func (s *Server) handleApiPicture(c iris.Context) {
id := c.Params().Get("id")
service, err := database.Pb.GetServiceById(id)
if err != nil {
log.Error().Err(err).Msg("Could not get service")
respondWithPlaceholder(c, "?")
return
}
if service.LogoURL == "" {
log.Debug().Msgf("Image %s not found in cache", service.ID)
respondWithPlaceholder(c, service.Name)
return
}
if imageData, err := s.Cache.Get(fmt.Sprintf("img-%s", service.ID)); err == nil {
log.Debug().Msgf("Found image %s in cache", service.ID)
ctt, _ := s.Cache.Get(fmt.Sprintf("ctt-%s", service.ID))
c.ContentType(string(ctt))
c.StatusCode(iris.StatusOK)
c.Write(imageData)
return
}
log.Debug().Msgf("Image %s not found in cache", service.ID)
client := &http.Client{}
req, err := http.NewRequest("GET", service.LogoURL, nil)
if err != nil {
log.Error().Err(err).Msg("Failed to create HTTP request")
return
}
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.3")
req.Header.Set("Referer", service.Urls[0])
resp, err := client.Do(req)
if err != nil || resp.StatusCode != http.StatusOK {
log.Error().Err(err).Msg("Could not get image")
respondWithPlaceholder(c, service.Name)
return
}
defer resp.Body.Close()
bodyBytes, err := io.ReadAll(resp.Body)
if err != nil {
log.Error().Err(err).Msg("Could not read response body")
respondWithPlaceholder(c, service.Name)
return
}
if bodyBytes == nil {
log.Error().Msg("Could not read response body")
respondWithPlaceholder(c, service.Name)
return
}
s.Cache.Set(fmt.Sprintf("img-%s", service.ID), bodyBytes)
s.Cache.Set(fmt.Sprintf("ctt-%s", service.ID), []byte(resp.Header.Get("Content-Type")))
c.ContentType(resp.Header.Get("Content-Type"))
c.StatusCode(iris.StatusOK)
c.Write(bodyBytes)
}
func respondWithPlaceholder(c iris.Context, serviceName string) {
log.Debug().Msgf("Generating placeholder for %s", serviceName)
const width, height = 250, 250
const margin = 15
firstLetter := strings.ToUpper(string(serviceName[0]))
// Create an image
img := image.NewRGBA(image.Rect(0, 0, width, height))
// Set background to black
draw.Draw(img, img.Bounds(), image.NewUniform(color.Black), image.Point{}, draw.Src)
// Load the monospace font
f, err := truetype.Parse(gomonobold.TTF)
if err != nil {
log.Error().Err(err).Msg("could not parse font")
return
}
// Initialize freetype context
ctx := freetype.NewContext()
ctx.SetDPI(72)
ctx.SetFont(f)
// Parse hex color and set text color
var r, g, b uint8
hexColor := "#84cc16"
_, err = fmt.Sscanf(hexColor, "#%02x%02x%02x", &r, &g, &b)
if err != nil {
log.Error().Err(err).Msg("Invalid hex color")
return
}
textColor := color.RGBA{R: r, G: g, B: b, A: 255}
ctx.SetSrc(image.NewUniform(textColor))
ctx.SetClip(img.Bounds())
ctx.SetDst(img)
// Dynamically calculate the maximum font size
var fontSize float64
var textWidth, textHeight int
for fontSize = 205; fontSize > 10; fontSize -= 0.5 {
ctx.SetFontSize(fontSize)
opts := truetype.Options{Size: fontSize}
face := truetype.NewFace(f, &opts)
textWidth = font.MeasureString(face, firstLetter).Round()
ascent, descent := face.Metrics().Ascent, face.Metrics().Descent
textHeight = (ascent + descent).Ceil()
if textWidth <= width-margin*2 && textHeight <= height-margin*2 {
break
}
}
// Calculate position for the text
x := (width - textWidth) / 2
y := (height-textHeight)/2 + textHeight - int(ctx.PointToFixed(fontSize*0.2)>>6)
pt := freetype.Pt(x, y)
// Draw the text
if _, err := ctx.DrawString(firstLetter, pt); err != nil {
log.Error().Err(err).Msg("Failed to draw string")
return
}
// Encode to PNG
var buf bytes.Buffer
if err := png.Encode(&buf, img); err != nil {
log.Error().Err(err).Msg("Failed to encode image")
return
}
c.ContentType("image/png")
c.StatusCode(iris.StatusOK)
c.Write(buf.Bytes())
}

View File

@ -1,324 +0,0 @@
package server
import (
"fmt"
"math/rand"
"strings"
"github.com/kataras/iris/v12"
"github.com/rs/zerolog/log"
"pluja.dev/kycnot.me/database"
"pluja.dev/kycnot.me/utils"
)
func (s *Server) handleIndex(c iris.Context) {
nokycPf := []string{
"KYC-Free Crypto Freedom.",
"Goodbye KYC, hello privacy.",
"KYC is a scam. Don't fall for it.",
}
t := c.URLParam("t")
q := c.URLParam("q")
// Currencies
xmr := c.URLParam("xmr")
btc := c.URLParam("btc")
ln := c.URLParam("ln")
cash := c.URLParam("cash")
fiat := c.URLParam("fiat")
filters := []string{"(listed=true && pending=false)"}
if t != "" && t != "all" {
filters = append(filters, fmt.Sprintf("(type='%v')", t))
}
if q != "" {
filters = append(
filters,
fmt.Sprintf("(name~'%v' || description~'%v' || tags~'%v')", q, q, q),
)
}
if xmr != "" {
filters = append(filters, fmt.Sprintf("(xmr=%v)", xmr == "on"))
}
if btc != "" {
filters = append(filters, fmt.Sprintf("(btc=%v)", btc == "on"))
}
if ln != "" {
filters = append(filters, fmt.Sprintf("(lightning=%v)", ln == "on"))
}
if cash != "" {
filters = append(filters, fmt.Sprintf("(cash=%v)", cash == "on"))
}
if fiat != "" {
filters = append(filters, fmt.Sprintf("(fiat=%v)", fiat == "on"))
}
services, err := database.Pb.GetServices(
fmt.Sprintf("(%v)", strings.Join(filters, " && ")),
"score,@random",
)
if err != nil {
log.Error().Err(err).Msg("Could not get services from Pocketbase")
c.HTML("<h3>%s</h3>", err.Error())
return
}
c.ViewLayout("main")
data := iris.Map{
"Title": "Home",
"Filters": map[string]string{
"Type": t,
"Query": q,
"Xmr": xmr,
"Btc": btc,
"Ln": ln,
"Cash": cash,
"Fiat": fiat,
},
"Current": "index",
"Services": services,
"RandomPitch": nokycPf[rand.Intn(len(nokycPf))],
}
if err := c.View("index", data); err != nil {
c.HTML("<h3>%s</h3>", err.Error())
return
}
}
func (s *Server) handleService(c iris.Context) {
serviceName := strings.ToLower(c.Params().Get("name"))
service, err := database.Pb.GetServiceByNameOrUrl(serviceName)
if err != nil {
log.Error().Err(err).Msgf("Could not get service %v from database", serviceName)
c.HTML("<h3>%s</h3>", err.Error())
return
}
// TODO: Compute score in background when needed!
// Update score in background
//upd := c.URLParam("update", "")
//if upd == "true" {
// go utils.UpdateScore(service)
//}
//utils.ComputeScore(service)
c.ViewLayout("main")
data := iris.Map{
"Title": fmt.Sprintf("%v | Service", serviceName),
"Service": service,
"Attributes": service.Expand["attributes"],
}
if err := c.View("service", data); err != nil {
c.HTML("<h3>%s</h3>", err.Error())
return
}
}
func (s *Server) handleAttribute(c iris.Context) {
attributeId := strings.ToLower(c.Params().Get("id"))
// Get service from database by name
attribute, err := database.Pb.GetAttribute(attributeId)
if err != nil {
log.Error().Err(err).Msgf("Could not get attribute %v from database", attributeId)
c.HTML("<h3>%s</h3>", err.Error())
return
}
// Get all services that have this attribute
services, err := database.Pb.GetServices(
fmt.Sprintf("(attributes~'%v')", attributeId),
"score",
)
if err != nil {
log.Error().Err(err).Msgf("Could not get services with attribute %v from database", attributeId)
c.HTML("<h3>%s</h3>", err.Error())
return
}
c.ViewLayout("main")
data := iris.Map{
"Title": fmt.Sprintf("%v", attribute.Title),
"Attribute": attribute,
"Services": services,
}
if err := c.View("attribute", data); err != nil {
c.HTML("<h3>%s</h3>", err.Error())
return
}
}
func (s *Server) handleRequestServiceForm(c iris.Context) {
challenge, id, difficulty, err := s.PowChallenger.PowGenerateChallenge(16)
if err != nil {
c.HTML("<h3>%s</h3>", err.Error())
return
}
attributes, err := database.Pb.GetAttributes("", "-rating")
if err != nil {
log.Error().Err(err).Msg("Could not get attributes from database")
c.HTML("<h3>%s</h3>", err.Error())
return
}
c.ViewLayout("main")
data := iris.Map{
"Title": "Request a service",
"Current": "request",
"Pow": map[string]interface{}{
"Challenge": challenge,
"Difficulty": difficulty,
"Id": id,
},
"Attributes": attributes,
"Error": c.URLParam("error"),
"Message": c.URLParam("message"),
}
if err := c.View("request_service", data); err != nil {
c.HTML("<h3>%s</h3>", err.Error())
return
}
}
func (s *Server) handleAbout(c iris.Context) {
c.ViewLayout("main")
data := iris.Map{
"Title": "About",
"Current": "about",
}
if err := c.View("about", data); err != nil {
c.HTML("<h3>%s</h3>", err.Error())
return
}
}
func (s *Server) handlePending(c iris.Context) {
services, err := database.Pb.GetServices("pending=true", "score")
if err != nil {
log.Error().Err(err).Msg("Could not get services from database")
c.HTML("<h3>%s</h3>", err.Error())
return
}
c.ViewLayout("main")
data := iris.Map{
"Title": "Pending",
"Services": services,
}
if err := c.View("pending", data); err != nil {
c.HTML("<h3>%s</h3>", err.Error())
return
}
}
type RequestFormData struct {
Type string `form:"type"`
Category string `form:"category"`
Name string `form:"name"`
Description string `form:"description"`
Urls string `form:"urls"`
LogoUrl string `form:"logo_url"`
TosUrls string `form:"tos_urls"`
OnionUrls string `form:"onion_urls"`
Tags string `form:"tags"`
Xmr bool `form:"xmr"`
Btc bool `form:"btc"`
Ln bool `form:"ln"`
Fiat bool `form:"fiat"`
Cash bool `form:"cash"`
KYCLevel int `form:"kyc_level"`
Attributes []string `form:"attributes"`
PowNonce string `form:"pow-nonce"`
PowId string `form:"pow-id"`
}
func (s *Server) handlePostRequestServiceForm(c iris.Context) {
log.Info().Msg("Handling request service form")
log.Debug().Msg("Handling request service form")
var data RequestFormData
if err := c.ReadForm(&data); err != nil {
log.Debug().Err(err).Msg("Could not parse form data")
c.Redirect("/request/service?error=Invalid%20Form", iris.StatusSeeOther)
return
}
log.Printf("Nonce: %v, ID: %v", data.PowNonce, data.PowId)
if !s.PowChallenger.PowVerifyProof(data.PowId, data.PowNonce) {
log.Debug().Msg("Invalid PoW")
c.Redirect("/request/service?error=Invalid%20Captcha", iris.StatusSeeOther)
return
}
if data.KYCLevel < 0 || data.KYCLevel >= 4 {
log.Debug().Msgf("Invalid KYC Level value: %v", c.FormValue("kyc_level"))
c.Redirect("/request/service?error=Invalid%20KYC%20Level", iris.StatusSeeOther)
return
}
if len(data.Attributes) < 3 {
log.Debug().Msgf("Invalid number of attributes: %v", len(data.Attributes))
c.Redirect("/request/service?error=You%20must%20select%20at%20least%203%20attributes", iris.StatusSeeOther)
return
}
var service database.Service
// Parse tags
ts := strings.ReplaceAll(data.Tags, " ", ",")
// Remove trailing commas
ts = strings.TrimSuffix(ts, ",")
// Remove duplicate commas
ts = strings.ReplaceAll(ts, ",,", ",")
// Remove leading commas
ts = strings.TrimPrefix(ts, ",")
// Convert to lowercase
ts = strings.ToLower(ts)
// Create tags array
tags := strings.Split(ts, ",")
service.Tags = tags
service.Name = strings.ToLower(data.Name)
service.Description = data.Description
service.LogoURL = utils.UrlParser(data.LogoUrl)
service.Urls = utils.UrlListParser(data.Urls)
service.TosUrls = utils.UrlListParser(data.TosUrls)
service.OnionUrls = utils.UrlListParser(data.OnionUrls)
service.Xmr = data.Xmr
service.Btc = data.Btc
service.Lightning = data.Ln
service.Fiat = data.Fiat
service.Cash = data.Cash
service.Pending = true
service.Listed = false
service.Type = data.Type
if service.Type == "service" {
service.Category = data.Category
} else {
service.Category = ""
}
service.KycLevel = data.KYCLevel
service.Attributes = data.Attributes
service.Score = utils.ComputeScore(&service)
// Save service to database
err := database.Pb.CreateService(service)
if err != nil {
log.Error().Err(err).Msg("Could not save service to database")
c.Redirect("/request/service?error=internal-error", iris.StatusSeeOther)
return
}
// TODO: Update score in background
// go utils.UpdateScore(sv)
c.Redirect("/request/service?message=Success!", iris.StatusSeeOther)
}