Compare commits

...

3 Commits

Author SHA1 Message Date
daru
d601ec5cf7 Fix 2022-05-14 18:41:45 +02:00
daru
fa91e9778c Auto build versioning 2022-05-14 18:39:04 +02:00
daru
e660b52bd4 Chat feature 2022-05-14 18:31:58 +02:00
5 changed files with 119 additions and 10 deletions

2
build.sh Executable file
View File

@@ -0,0 +1,2 @@
date=$(date '+%Y-%m-%dT%H:%M:%S')
go build -ldflags "-X main.buildTime=$date"

View File

@@ -17,7 +17,7 @@ import (
)
const (
husoVersion = "1.0"
husoVersion = "1.1"
registerSecret = "綾波レイ"
seasonApiJikan = "seasons/now"
userApiJikan = "users/"
@@ -33,7 +33,9 @@ const (
bucketAnime = "anime"
bucketMedia = "media"
bucketAppoint = "appoint"
bucketChat = "chat"
AppointSplit = "§"
chatLength = 10101
)
var (
@@ -50,6 +52,7 @@ var (
db *nutsdb.DB
jikanLimiter *rate.Limiter
logOut *RingBuf
buildTime string
)
func main() {
@@ -61,8 +64,8 @@ func main() {
logOut = NewRingBuf(10101)
color.Notice.Printf("huso %s %s\n", husoVersion, runtime.Version())
logOut.WriteLine(fmt.Sprintf("🎉 huso %s %s", husoVersion, runtime.Version()))
color.Notice.Printf("huso %s built on %s with %s\n", husoVersion, buildTime, runtime.Version())
logOut.WriteLine(fmt.Sprintf("🎉 huso %s built on %s with %s\n", husoVersion, buildTime, runtime.Version()))
jikanLimiter = rate.NewLimiter(rate.Every(time.Second), 1)

37
nuss.go
View File

@@ -10,7 +10,7 @@ import (
)
func ReadUser(username string) (*UserData, error) {
data, err := DbRead(bucketUsers, username)
data, err := DbRead(bucketUsers, []byte(username))
if err != nil {
return nil, err
}
@@ -108,7 +108,7 @@ func DeleteUserFromAnime(username string, userId, animeId int64) (*AnimeUser, er
Users: users,
}
if len(users) == 0 {
return tx.Delete(bucketAnime, keyBytes)
return DeleteAnime(tx, keyBytes)
}
newData, err := json.Marshal(users)
if err != nil {
@@ -144,7 +144,7 @@ func DeleteUserFromAnimes(userId int64) error {
users = users[:len(users)-1]
// check if anime needs recycling
if len(users) == 0 {
err = tx.Delete(bucketAnime, e.Key)
err = DeleteAnime(tx, e.Key)
if err != nil {
return err
}
@@ -167,6 +167,11 @@ func DeleteUserFromAnimes(userId int64) error {
})
}
func DeleteAnime(tx *nutsdb.Tx, keyBytes []byte) error {
tx.Delete(bucketChat, keyBytes)
return tx.Delete(bucketAnime, keyBytes)
}
func UpdateUserAnimeProgress(animeId, userId int64, progress int, updated time.Time) error {
return db.Update(
func(tx *nutsdb.Tx) error {
@@ -286,6 +291,29 @@ func ReadAppointments() ([]Appointment, error) {
return appoints, err
}
func ReadChat(animeId int64) (string, error) {
data, err := DbRead(bucketChat, Int64ToByte(animeId))
return string(data), err
}
func SaveChat(animeId int64, username, newMessage string) (string, error) {
var chat string
err := db.Update(
func(tx *nutsdb.Tx) error {
keyBytes := Int64ToByte(animeId)
e, err := tx.Get(bucketChat, keyBytes)
if err != nil {
chat = ""
} else {
chat = string(e.Value)
}
// add to chat message
chat = AddToChat(chat, newMessage, username)
return tx.Put(bucketChat, keyBytes, []byte(chat), nutsdb.Persistent)
})
return chat, err
}
func DbClean() error {
return db.Update(
func(tx *nutsdb.Tx) error {
@@ -301,11 +329,10 @@ func DbSave(bucket, key string, val []byte) error {
})
}
func DbRead(bucket, key string) ([]byte, error) {
func DbRead(bucket string, keyBytes []byte) ([]byte, error) {
var val []byte
err := db.View(
func(tx *nutsdb.Tx) error {
keyBytes := []byte(key)
e, err := tx.Get(bucket, keyBytes)
if err != nil {
return err

73
ober.go
View File

@@ -20,10 +20,12 @@ func RunWebserv() {
r.GET("/api/anime/{id}", Headers(AnimeGet))
r.GET("/api/animesearch", Headers(AnimeSearchGet))
r.GET("/api/appointment", Headers(AppointmentGet))
r.GET("/api/chat/{id}", Headers(ChatGet))
r.GET("/api/log", Headers(LogGet))
r.GET("/api/user/{user?}", Headers(UserGet))
r.GET("/api/watch/{user?}", Headers(WatchGet))
r.GET("/api/watchext/{user?}", Headers(WatchExtendedGet))
r.POST("/api/chat/{id}/{user}", Headers(ChatPost))
r.POST("/api/register", Headers(Register))
r.POST("/api/watch/{user}", Headers(WatchPost))
r.DELETE("/api/register", Headers(UnRegister))
@@ -82,7 +84,7 @@ func AnimeGet(ctx *fasthttp.RequestCtx) {
ctx.SetStatusCode(fasthttp.StatusBadRequest)
return
}
// check user exists
// check anime exists
malId, err := strconv.ParseInt(fmt.Sprintf("%s", idVal), 10, 64)
if err != nil {
ctx.WriteString(err.Error())
@@ -141,11 +143,41 @@ func AppointmentGet(ctx *fasthttp.RequestCtx) {
ctx.SetStatusCode(fasthttp.StatusNotImplemented)
}
func ChatGet(ctx *fasthttp.RequestCtx) {
idVal := ctx.UserValue("id")
if idVal == nil {
ctx.SetStatusCode(fasthttp.StatusBadRequest)
return
}
animeId, err := strconv.ParseInt(fmt.Sprintf("%s", idVal), 10, 64)
if err != nil {
ctx.WriteString(err.Error())
ctx.SetStatusCode(fasthttp.StatusBadRequest)
return
}
text, err := ReadChat(animeId)
if err != nil {
if strings.Contains(err.Error(), "not found") {
ctx.WriteString(err.Error())
ctx.SetStatusCode(fasthttp.StatusNotFound)
return
}
addErrorToCtx(ctx, err)
return
}
_, err = ctx.WriteString(text)
if err != nil {
addErrorToCtx(ctx, err)
return
}
ctx.SetContentType("text/plain; charset=utf-8")
ctx.SetStatusCode(fasthttp.StatusOK)
}
func LogGet(ctx *fasthttp.RequestCtx) {
_, err := ctx.WriteString(logOut.String())
if err != nil {
addErrorToCtx(ctx, err)
ctx.SetStatusCode(fasthttp.StatusInternalServerError)
return
}
ctx.SetContentType("text/plain; charset=utf-8")
@@ -317,6 +349,43 @@ func Register(ctx *fasthttp.RequestCtx) {
ctx.SetStatusCode(fasthttp.StatusOK)
}
func ChatPost(ctx *fasthttp.RequestCtx) {
auth := ctx.Request.Header.Peek("X-HUSO-AUTH")
if ctx.UserValue("id") == nil || ctx.UserValue("user") == nil || auth == nil || string(auth) == "" || !strings.Contains(string(ctx.Request.Header.ContentType()), "text/plain") {
ctx.SetStatusCode(fasthttp.StatusBadRequest)
return
}
username := fmt.Sprintf("%s", ctx.UserValue("user"))
legit, _ := GheddoAuth(username, string(auth))
if !legit {
ctx.SetStatusCode(fasthttp.StatusUnauthorized)
return
}
animeId, err := strconv.ParseInt(fmt.Sprintf("%s", ctx.UserValue("id")), 10, 64)
if err != nil {
ctx.WriteString(err.Error())
ctx.SetStatusCode(fasthttp.StatusBadRequest)
return
}
sent := strings.TrimSpace(string(ctx.PostBody()))
if sent == "" {
ctx.SetStatusCode(fasthttp.StatusBadRequest)
return
}
text, err := SaveChat(animeId, username, sent)
if err != nil {
addErrorToCtx(ctx, err)
return
}
_, err = ctx.WriteString(text)
if err != nil {
addErrorToCtx(ctx, err)
return
}
ctx.SetContentType("text/plain; charset=utf-8")
ctx.SetStatusCode(fasthttp.StatusOK)
}
func WatchPost(ctx *fasthttp.RequestCtx) {
processUpdateReq(ctx, true)
}

View File

@@ -3,6 +3,7 @@ package main
import (
"encoding/json"
"errors"
"fmt"
"time"
)
@@ -163,3 +164,10 @@ func FetchProgress(animeId, userId int64, username string, progress int) (int, t
// has no progress or dropped/hold
return 0, time.Now(), nil
}
func AddToChat(old, new, user string) string {
buf := NewRingBuf(chatLength)
buf.Write([]byte(old))
buf.Write([]byte(fmt.Sprintf("[%s][%s]: %s\n", time.Now().Format("02.01.|15:04:05"), user, new)))
return buf.String()
}