0
0
mirror of https://github.com/rls-moe/nyx synced 2025-08-19 06:18:38 +00:00

Images/Non-images post work, several bug fixes, UI fixes

This commit is contained in:
Tim Schuster
2017-03-13 18:45:23 +01:00
parent 4177901714
commit afd9ae71cf
21 changed files with 2206 additions and 23 deletions

21
http/admin/cleanup.go Normal file
View File

@@ -0,0 +1,21 @@
package admin
import (
"github.com/tidwall/buntdb"
"go.rls.moe/nyx/http/errw"
"go.rls.moe/nyx/http/middle"
"net/http"
)
func handleCleanup(w http.ResponseWriter, r *http.Request) {
db := middle.GetDB(r)
err := db.Update(func(tx *buntdb.Tx) error {
/* Insert cleanup codes here */
return nil
})
err = db.Shrink()
if err != nil {
errw.ErrorWriter(err, w, r)
return
}
}

View File

@@ -106,6 +106,8 @@ func handleDelPost(w http.ResponseWriter, r *http.Request) {
}
reply.Text = "[deleted]"
reply.Metadata["deleted"] = "yes"
reply.Image = nil
reply.Thumbnail = nil
err = resources.UpdateReply(tx, r.Host, board, reply)
if err != nil {
return err

View File

@@ -11,6 +11,7 @@ import (
"go.rls.moe/nyx/resources"
"html/template"
"net/http"
"strconv"
"time"
)
@@ -48,6 +49,10 @@ var (
},
"rateSpam": resources.SpamScore,
"makeCaptcha": resources.MakeCaptcha,
"dateFromID": resources.DateFromId,
"formatDate": func(date time.Time) string {
return date.Format("02 Jan 06 15:04:05")
},
}
)
@@ -78,15 +83,74 @@ func Router(r chi.Router) {
r.Get("/:board/board.html", serveBoard)
r.Post("/:board/new_thread.sh", handleNewThread)
r.Get("/:board/:thread/thread.html", serveThread)
r.Get("/:board/:thread/:post/post.html", servePost)
r.Get("/:board/:thread/:reply/:unused.png", serveFullImage)
r.Get("/:board/:thread/:reply/thumb.png", serveThumb)
r.Post("/:board/:thread/reply.sh", handleNewReply)
r.Handle("/captcha/:captchaId.png", resources.ServeCaptcha)
r.Handle("/captcha/:captchaId.wav", resources.ServeCaptcha)
r.Handle("/captcha/download/:captchaId.wav", resources.ServeCaptcha)
}
func servePost(w http.ResponseWriter, r *http.Request) {
return
func serveThumb(w http.ResponseWriter, r *http.Request) {
dat := bytes.NewBuffer([]byte{})
db := middle.GetDB(r)
err := db.View(func(tx *buntdb.Tx) error {
bName := chi.URLParam(r, "board")
tid, err := strconv.Atoi(chi.URLParam(r, "thread"))
if err != nil {
return err
}
rid, err := strconv.Atoi(chi.URLParam(r, "reply"))
if err != nil {
return err
}
reply, err := resources.GetReply(tx, r.Host, bName, tid, rid)
if err != nil {
return err
}
_, err = dat.Write(reply.Thumbnail)
if err != nil {
return err
}
return nil
})
if err != nil {
errw.ErrorWriter(err, w, r)
return
}
http.ServeContent(w, r, "thumb.png", time.Now(), bytes.NewReader(dat.Bytes()))
}
func serveFullImage(w http.ResponseWriter, r *http.Request) {
dat := bytes.NewBuffer([]byte{})
db := middle.GetDB(r)
err := db.View(func(tx *buntdb.Tx) error {
bName := chi.URLParam(r, "board")
tid, err := strconv.Atoi(chi.URLParam(r, "thread"))
if err != nil {
return err
}
rid, err := strconv.Atoi(chi.URLParam(r, "reply"))
if err != nil {
return err
}
reply, err := resources.GetReply(tx, r.Host, bName, tid, rid)
if err != nil {
return err
}
_, err = dat.Write(reply.Image)
if err != nil {
return err
}
return nil
})
if err != nil {
errw.ErrorWriter(err, w, r)
return
}
http.ServeContent(w, r, "image.png", time.Now(), bytes.NewReader(dat.Bytes()))
}
func serveDir(w http.ResponseWriter, r *http.Request) {

View File

@@ -1,12 +1,18 @@
package board
import (
"bytes"
"fmt"
"github.com/nfnt/resize"
"github.com/pressly/chi"
"github.com/tidwall/buntdb"
"go.rls.moe/nyx/http/errw"
"go.rls.moe/nyx/http/middle"
"go.rls.moe/nyx/resources"
"image"
_ "image/gif"
_ "image/jpeg"
"image/png"
"net/http"
"strconv"
)
@@ -17,6 +23,11 @@ func handleNewReply(w http.ResponseWriter, r *http.Request) {
errw.ErrorWriter(err, w, r)
return
}
err = r.ParseMultipartForm(10 * 1024 * 1024)
if err != nil {
errw.ErrorWriter(err, w, r)
return
}
if !resources.VerifyCaptcha(r) {
http.Redirect(w, r,
@@ -40,7 +51,7 @@ func handleNewReply(w http.ResponseWriter, r *http.Request) {
errw.ErrorWriter(errw.MakeErrorWithTitle("I'm sorry but I can't do that", "These are too many characters"), w, r)
return
}
if len(reply.Text) < 10 {
if len(reply.Text) < 5 {
errw.ErrorWriter(errw.MakeErrorWithTitle("I'm sorry but I can't do that", "These are not enough characters"), w, r)
return
}
@@ -53,6 +64,36 @@ func handleNewReply(w http.ResponseWriter, r *http.Request) {
return
}
{
file, _, err := r.FormFile("image")
if err != nil && err != http.ErrMissingFile {
errw.ErrorWriter(err, w, r)
return
} else if err != http.ErrMissingFile {
img, _, err := image.Decode(file)
if err != nil {
errw.ErrorWriter(err, w, r)
return
}
thumb := resize.Thumbnail(128, 128, img, resize.Lanczos3)
imgBuf := bytes.NewBuffer([]byte{})
err = png.Encode(imgBuf, img)
if err != nil {
errw.ErrorWriter(err, w, r)
return
}
fmt.Println("Image has size ", len(imgBuf.Bytes()))
reply.Image = imgBuf.Bytes()
imgBuf = bytes.NewBuffer([]byte{})
err = png.Encode(imgBuf, thumb)
if err != nil {
errw.ErrorWriter(err, w, r)
return
}
reply.Thumbnail = imgBuf.Bytes()
}
}
reply.Metadata = map[string]string{}
if r.FormValue("tripcode") != "" {
reply.Metadata["trip"] = resources.CalcTripCode(r.FormValue("tripcode"))

View File

@@ -1,12 +1,16 @@
package board
import (
"bytes"
"fmt"
"github.com/nfnt/resize"
"github.com/pressly/chi"
"github.com/tidwall/buntdb"
"go.rls.moe/nyx/http/errw"
"go.rls.moe/nyx/http/middle"
"go.rls.moe/nyx/resources"
"image"
"image/png"
"net/http"
)
@@ -16,6 +20,11 @@ func handleNewThread(w http.ResponseWriter, r *http.Request) {
errw.ErrorWriter(err, w, r)
return
}
err = r.ParseMultipartForm(10 * 1024 * 1024)
if err != nil {
errw.ErrorWriter(err, w, r)
return
}
if !resources.VerifyCaptcha(r) {
http.Redirect(w, r,
@@ -35,7 +44,7 @@ func handleNewThread(w http.ResponseWriter, r *http.Request) {
errw.ErrorWriter(errw.MakeErrorWithTitle("I'm sorry but I can't do that", "These are too many characters"), w, r)
return
}
if len(mainReply.Text) < 10 {
if len(mainReply.Text) < 5 {
errw.ErrorWriter(errw.MakeErrorWithTitle("I'm sorry but I can't do that", "These are not enough characters"), w, r)
return
}
@@ -48,6 +57,36 @@ func handleNewThread(w http.ResponseWriter, r *http.Request) {
return
}
{
file, _, err := r.FormFile("image")
if err != nil && err != http.ErrMissingFile {
errw.ErrorWriter(err, w, r)
return
} else if err != http.ErrMissingFile {
img, _, err := image.Decode(file)
if err != nil {
errw.ErrorWriter(err, w, r)
return
}
thumb := resize.Thumbnail(128, 128, img, resize.Lanczos3)
imgBuf := bytes.NewBuffer([]byte{})
err = png.Encode(imgBuf, img)
if err != nil {
errw.ErrorWriter(err, w, r)
return
}
fmt.Println("Image has size ", len(imgBuf.Bytes()))
mainReply.Image = imgBuf.Bytes()
imgBuf = bytes.NewBuffer([]byte{})
err = png.Encode(imgBuf, thumb)
if err != nil {
errw.ErrorWriter(err, w, r)
return
}
mainReply.Thumbnail = imgBuf.Bytes()
}
}
mainReply.Metadata = map[string]string{}
if r.FormValue("tripcode") != "" {
mainReply.Metadata["trip"] = resources.CalcTripCode(r.FormValue("tripcode"))

View File

@@ -2,10 +2,14 @@
<div class="postarea">
{{ if .Thread }}
<form id="postform"
action="/{{.Board.ShortName}}/{{.Thread.ID}}/reply.sh" method="POST">
action="/{{.Board.ShortName}}/{{.Thread.ID}}/reply.sh"
method="POST"
enctype="multipart/form-data">
{{ else }}
<form id="postform"
action="/{{.Board.ShortName}}/new_thread.sh" method="POST">
action="/{{.Board.ShortName}}/new_thread.sh"
method="POST"
enctype="multipart/form-data">
{{ end }}
<table>
<tbody>
@@ -41,7 +45,7 @@
placeholder="your comment"
rows="4"
cols="48"
minlength="10"
minlength="5"
required
></textarea>
</td>
@@ -97,9 +101,7 @@
Anonymous
{{ end }}
</span></label>
<span class="reflink">
<a href="/{{.Boardlink}}/{{.ThreadID}}/thread.html">No.{{.Reply.ID}}</a>
</span>
<span class="date">{{dateFromID .Reply.ID | formatDate}}</span>
{{ if .Session }}
{{ if eq (.Session.CAttr "mode") "admin" }}
<form class="delform" action="/mod/del_reply.sh" method="POST">
@@ -126,6 +128,18 @@
<span>
{{printf "[SpamScore: %f]" (rateSpam .Reply.Text) }}
</span>
<span class="reflink">
<a href="/{{.Boardlink}}/{{.ThreadID}}/thread.html">No.{{.Reply.ID}}</a>
</span>
{{ if .Reply.Thumbnail }}
<br />
<a target="_blank" href="/{{.Boardlink}}/{{.ThreadID}}/{{.Reply.ID}}/{{.Reply.ID}}.png">
<img
src="/{{.Boardlink}}/{{.ThreadID}}/{{.Reply.ID}}/thumb.png"
class="thumb"
/>
</a>
{{ end }}
{{ if .Reply.Metadata.deleted }}
<blockquote><blockquote class="deleted">
{{ renderText .Reply.Text }}
@@ -152,7 +166,7 @@
{{ end }}
{{range .GetReplies}}
{{ if ne .ID $threadrid }}
<table><tbody><tr><td class="doubledash">&gt;&gt;</td>
<table class="reply-table"><tbody><tr><td class="doubledash">&gt;&gt;</td>
<td class="reply" id="reply{{.ID}}">
{{ with dict "Reply" . "Boardlink" $boardlink "CSRF" $csrf "ThreadID" $threadid "Session" $session }}
{{ template "thread/reply" . }}

View File

@@ -16,9 +16,17 @@ div {
padding: 0;
}
blockquote blockquote { max-width: 80%; word-wrap: break-word; white-space: normal; }
blockquote blockquote {
word-wrap: break-word;
word-break: break-all;
white-space: normal;
padding: 2px;
margin-bottom: 1em;
margin-top: 1em;
margin-left: 40px;
margin-right: 40px;
}
.reply blockquote, blockquote :last-child { max-width: 80%; word-wrap: break-word; white-space: normal; }
.delform {
display: inline;
@@ -31,4 +39,12 @@ blockquote blockquote { max-width: 80%; word-wrap: break-word; white-space: norm
.deleted {
color: #707070;
}
.reply-table {
display: block;
}
.reply {
display: table;
}

View File

@@ -143,14 +143,13 @@ a:hover {
/* futaba_style.pl */
blockquote blockquote { margin-left: 0em; }
form { margin-bottom: 0px }
form .trap { display:none }
.postarea { text-align: center }
.postarea table { margin: 0px auto; text-align: left }
.thumb { border: none; float: left; margin: 2px 20px }
.nothumb { float: left; background: #eee; border: 2px dashed #aaa; text-align: center; margin: 2px 20px; padding: 1em 0.5em 1em 0.5em; }
.reply blockquote, blockquote :last-child { margin-bottom: 0em; }
.reflink a { color: inherit; text-decoration: none }
.reply .filesize { margin-left: 20px }
.userdelete { float: right; text-align: center; white-space: nowrap }