You've already forked nyx
mirror of
https://github.com/rls-moe/nyx
synced 2025-08-19 06:18:38 +00:00
Added Moderation Tools, Captcha & Trollthrottle
This commit is contained in:
@@ -38,6 +38,28 @@ func TestBoard(tx *buntdb.Tx, hostname, shortname string) (error) {
|
||||
return err
|
||||
}
|
||||
|
||||
func UpdateBoard(tx *buntdb.Tx, hostname string, b *Board) error {
|
||||
if err := TestBoard(tx, hostname, b.ShortName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dat, err := json.Marshal(b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, replaced, err := tx.Set(
|
||||
fmt.Sprintf(boardPath, escapeString(hostname), escapeString(b.ShortName)),
|
||||
string(dat),
|
||||
nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !replaced {
|
||||
return errors.New("Board " + escapeString(b.ShortName) + " does not exist")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetBoard(tx *buntdb.Tx, hostname, shortname string) (*Board, error) {
|
||||
var ret = &Board{}
|
||||
dat, err := tx.Get(
|
||||
|
16
resources/captcha.go
Normal file
16
resources/captcha.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package resources
|
||||
|
||||
import (
|
||||
"github.com/dchest/captcha"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func MakeCaptcha() string {
|
||||
return captcha.NewLen(5)
|
||||
}
|
||||
|
||||
func VerifyCaptcha(r *http.Request) bool {
|
||||
return captcha.VerifyString(r.FormValue("captchaId"), r.FormValue("captchaSolution"))
|
||||
}
|
||||
|
||||
var ServeCaptcha = captcha.Server(captcha.StdWidth, captcha.StdHeight)
|
@@ -12,6 +12,7 @@ var fountain = snowflakes.Generator{
|
||||
0, time.UTC).Unix(),
|
||||
}
|
||||
|
||||
func getID() (int64, error) {
|
||||
return fountain.NewID()
|
||||
func getID() (int, error) {
|
||||
id, err := fountain.NewID()
|
||||
return int(id), err
|
||||
}
|
||||
|
@@ -10,10 +10,10 @@ import (
|
||||
)
|
||||
|
||||
type Reply struct {
|
||||
ID int64 `json:"id"`
|
||||
ID int `json:"id"`
|
||||
Text string `json:"text"`
|
||||
Image []byte `json:"image"`
|
||||
Thread int64 `json:"thread"`
|
||||
Thread int `json:"thread"`
|
||||
Board string `json:"board"`
|
||||
Metadata Metadata `json:"meta"`
|
||||
}
|
||||
@@ -52,7 +52,33 @@ func NewReply(tx *buntdb.Tx, host, board string, thread *Thread, in *Reply, noId
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetReply(tx *buntdb.Tx, host, board string, thread, id int64) (*Reply, error) {
|
||||
func UpdateReply(tx *buntdb.Tx, host, board string, r *Reply) error {
|
||||
if err := TestBoard(tx, host, board); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := TestThread(tx, host, board, r.Thread); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dat, err := json.Marshal(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, replaced, err := tx.Set(
|
||||
fmt.Sprintf(replyPath, escapeString(host), escapeString(board), r.Thread, r.ID),
|
||||
string(dat),
|
||||
nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !replaced {
|
||||
return fmt.Errorf("Reply %d/%d does not exist", r.Thread, r.ID)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetReply(tx *buntdb.Tx, host, board string, thread, id int) (*Reply, error) {
|
||||
var ret = &Reply{}
|
||||
dat, err := tx.Get(
|
||||
fmt.Sprintf(replyPath, escapeString(host), escapeString(board), thread, id),
|
||||
@@ -66,7 +92,7 @@ func GetReply(tx *buntdb.Tx, host, board string, thread, id int64) (*Reply, erro
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func DelReply(tx *buntdb.Tx, host, board string, thread, id int64) error {
|
||||
func DelReply(tx *buntdb.Tx, host, board string, thread, id int) error {
|
||||
if _, err := tx.Delete(
|
||||
fmt.Sprintf(replyPath, escapeString(host), escapeString(board), thread, id),
|
||||
); err != nil {
|
||||
@@ -75,7 +101,7 @@ func DelReply(tx *buntdb.Tx, host, board string, thread, id int64) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func ListReplies(tx *buntdb.Tx, host, board string, thread int64) ([]*Reply, error) {
|
||||
func ListReplies(tx *buntdb.Tx, host, board string, thread int) ([]*Reply, error) {
|
||||
var replyList = []*Reply{}
|
||||
var err error
|
||||
|
||||
@@ -84,7 +110,7 @@ func ListReplies(tx *buntdb.Tx, host, board string, thread int64) ([]*Reply, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tx.DescendKeys(
|
||||
tx.AscendKeys(
|
||||
fmt.Sprintf(
|
||||
replySPath,
|
||||
escapeString(host),
|
||||
@@ -98,9 +124,6 @@ func ListReplies(tx *buntdb.Tx, host, board string, thread int64) ([]*Reply, err
|
||||
return false
|
||||
}
|
||||
replyList = append(replyList, reply)
|
||||
if len(replyList) >= 100 {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
|
@@ -1,7 +1,12 @@
|
||||
package resources
|
||||
|
||||
import (
|
||||
"compress/flate"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io"
|
||||
"math"
|
||||
"math/rand"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -10,3 +15,55 @@ func OperateReplyText(unsafe string) template.HTML {
|
||||
unsafe = strings.Replace(unsafe, "\n", "<br />", -1)
|
||||
return template.HTML(unsafe)
|
||||
}
|
||||
|
||||
var (
|
||||
blacklist = []string{
|
||||
"spam",
|
||||
"pizza",
|
||||
"buy",
|
||||
"free",
|
||||
"subscription",
|
||||
"penis",
|
||||
"nazi",
|
||||
}
|
||||
)
|
||||
|
||||
func SpamScore(spam string) (float64, error) {
|
||||
spam = strings.ToLower(spam)
|
||||
|
||||
counter := &byteCounter{1}
|
||||
compressor, err := flate.NewWriter(counter, flate.BestSpeed)
|
||||
if err != nil {
|
||||
return 0.0, err
|
||||
}
|
||||
_, err = io.WriteString(compressor, spam)
|
||||
if err != nil {
|
||||
return 0.0, err
|
||||
}
|
||||
compressor.Flush()
|
||||
compressor.Close()
|
||||
blScore := 1.0
|
||||
for _, v := range blacklist {
|
||||
blScore += float64(strings.Count(spam, v))
|
||||
}
|
||||
|
||||
score := float64(len(spam)) / float64(counter.p)
|
||||
|
||||
return (score * blScore) / 100, nil
|
||||
}
|
||||
|
||||
type byteCounter struct {
|
||||
p int
|
||||
}
|
||||
|
||||
func (b *byteCounter) Write(p []byte) (n int, err error) {
|
||||
b.p += len(p)
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
func CaptchaPass(spamScore float64) bool {
|
||||
chance := math.Max(0, math.Min(0.65*math.Atan(7.1*spamScore), 0.99))
|
||||
take := rand.Float64()
|
||||
fmt.Printf("Chance: %f, Take %f", chance, take)
|
||||
return take > chance
|
||||
}
|
||||
|
@@ -8,8 +8,8 @@ import (
|
||||
)
|
||||
|
||||
type Thread struct {
|
||||
ID int64 `json:"id"`
|
||||
StartReply int64 `json:"start"`
|
||||
ID int `json:"id"`
|
||||
StartReply int `json:"start"`
|
||||
Board string `json:"board"`
|
||||
Metadata Metadata `json:"-"`
|
||||
|
||||
@@ -66,7 +66,7 @@ func NewThread(tx *buntdb.Tx, host, board string, in *Thread, in2 *Reply) error
|
||||
return NewReply(tx, host, board, in, in2, true)
|
||||
}
|
||||
|
||||
func TestThread(tx *buntdb.Tx, host, board string, id int64) error {
|
||||
func TestThread(tx *buntdb.Tx, host, board string, id int) error {
|
||||
err := TestBoard(tx, host, board)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -78,7 +78,7 @@ func TestThread(tx *buntdb.Tx, host, board string, id int64) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func GetThread(tx *buntdb.Tx, host, board string, id int64) (*Thread, error) {
|
||||
func GetThread(tx *buntdb.Tx, host, board string, id int) (*Thread, error) {
|
||||
var ret = &Thread{}
|
||||
dat, err := tx.Get(
|
||||
fmt.Sprintf(threadPath, escapeString(host), escapeString(board), id),
|
||||
@@ -94,7 +94,7 @@ func GetThread(tx *buntdb.Tx, host, board string, id int64) (*Thread, error) {
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func DelThread(tx *buntdb.Tx, host, board string, id int64) error {
|
||||
func DelThread(tx *buntdb.Tx, host, board string, id int) error {
|
||||
if _, err := tx.Delete(
|
||||
fmt.Sprintf(threadPath, escapeString(host), escapeString(board), id),
|
||||
); err != nil {
|
||||
|
Reference in New Issue
Block a user