mirror of
https://github.com/Eggbertx/gochan.git
synced 2025-08-25 01:26:23 -07:00
Add filename and username banning, add more de-deprecation stuff to posting/post.go
This commit is contained in:
parent
b69536b772
commit
379e846daf
10 changed files with 531 additions and 405 deletions
|
@ -1,11 +1,6 @@
|
|||
package posting
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"html"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/gochan-org/gochan/pkg/config"
|
||||
|
@ -15,82 +10,114 @@ import (
|
|||
"github.com/gochan-org/gochan/pkg/serverutil"
|
||||
)
|
||||
|
||||
const (
|
||||
_ = iota
|
||||
ThreadBan
|
||||
ImageBan
|
||||
FullBan
|
||||
)
|
||||
|
||||
// BanHandler is used for serving ban pages
|
||||
func BanHandler(writer http.ResponseWriter, request *http.Request) {
|
||||
appealMsg := request.FormValue("appealmsg")
|
||||
// banStatus, err := getBannedStatus(request) // TODO refactor to use ipban
|
||||
var banStatus gcsql.BanInfo
|
||||
var err error
|
||||
systemCritical := config.GetSystemCriticalConfig()
|
||||
siteConfig := config.GetSiteConfig()
|
||||
boardConfig := config.GetBoardConfig("")
|
||||
if appealMsg != "" {
|
||||
if banStatus.BannedForever() {
|
||||
fmt.Fprint(writer, "No.")
|
||||
return
|
||||
}
|
||||
escapedMsg := html.EscapeString(appealMsg)
|
||||
if err = gcsql.AddBanAppeal(banStatus.ID, escapedMsg); err != nil {
|
||||
serverutil.ServeErrorPage(writer, err.Error())
|
||||
}
|
||||
fmt.Fprint(writer,
|
||||
"Appeal sent. It will (hopefully) be read by a staff member. check "+systemCritical.WebRoot+"banned occasionally for a response",
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
gcutil.LogError(err).Msg("Failed getting banned status")
|
||||
serverutil.ServeErrorPage(writer, "Error getting banned status: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if err = serverutil.MinifyTemplate(gctemplates.Banpage, map[string]interface{}{
|
||||
"systemCritical": systemCritical,
|
||||
"siteConfig": siteConfig,
|
||||
"boardConfig": boardConfig,
|
||||
"ban": banStatus,
|
||||
"banBoards": banStatus.Boards,
|
||||
"post": gcsql.Post{},
|
||||
}, writer, "text/html"); err != nil {
|
||||
func showBanpage(ban gcsql.Ban, banType string, filename string, post *gcsql.Post, postBoard *gcsql.Board, writer http.ResponseWriter, request *http.Request) {
|
||||
// TODO: possibly split file/username/filename bans into separate page template
|
||||
err := serverutil.MinifyTemplate(gctemplates.Banpage, map[string]interface{}{
|
||||
"systemCritical": config.GetSystemCriticalConfig(),
|
||||
"siteConfig": config.GetSiteConfig(),
|
||||
"boardConfig": config.GetBoardConfig(postBoard.Dir),
|
||||
"ban": ban,
|
||||
"board": postBoard,
|
||||
}, writer, "text/html")
|
||||
if err != nil {
|
||||
gcutil.LogError(err).
|
||||
Str("template", "banpage").
|
||||
Msg("Failed minifying template")
|
||||
serverutil.ServeErrorPage(writer, "Error minifying page template: "+err.Error())
|
||||
Str("IP", post.IP).
|
||||
Str("building", "minifier").
|
||||
Str("banType", banType).
|
||||
Str("template", "banpage.html").Send()
|
||||
serverutil.ServeErrorPage(writer, "Error minifying page: "+err.Error())
|
||||
return
|
||||
}
|
||||
ev := gcutil.LogInfo().
|
||||
Str("IP", post.IP).
|
||||
Str("boardDir", postBoard.Dir).
|
||||
Str("banType", banType)
|
||||
switch banType {
|
||||
case "ip":
|
||||
ev.Msg("Rejected post from banned IP")
|
||||
case "username":
|
||||
ev.
|
||||
Str("name", post.Name).
|
||||
Str("tripcode", post.Tripcode).
|
||||
Msg("Rejected post with banned name/tripcode")
|
||||
case "filename":
|
||||
ev.
|
||||
Str("filename", filename).
|
||||
Msg("Rejected post with banned filename")
|
||||
}
|
||||
}
|
||||
|
||||
// Checks check poster's name/tripcode/file checksum (from Post post) for banned status
|
||||
// returns ban table if the user is banned or sql.ErrNoRows if they aren't
|
||||
func getBannedStatus(request *http.Request) (*gcsql.BanInfo, error) {
|
||||
formName := request.FormValue("postname")
|
||||
var tripcode string
|
||||
if formName != "" {
|
||||
parsedName := gcutil.ParseName(formName)
|
||||
tripcode += parsedName["name"]
|
||||
if tc, ok := parsedName["tripcode"]; ok {
|
||||
tripcode += "!" + tc
|
||||
}
|
||||
}
|
||||
ip := gcutil.GetRealIP(request)
|
||||
// func BanHandler(writer http.ResponseWriter, request *http.Request) {
|
||||
// ip := gcutil.GetRealIP(request)
|
||||
// ipBan, err := gcsql.CheckIPBan(ip, 0)
|
||||
// if err != nil {
|
||||
// gcutil.LogError(err).
|
||||
// Str("IP", ip).
|
||||
// Msg("Error checking IP banned status (/banned request)")
|
||||
// serverutil.ServeErrorPage(writer, "Error checking banned status: "+err.Error())
|
||||
// return
|
||||
// }
|
||||
|
||||
var filename string
|
||||
var checksum string
|
||||
file, fileHandler, err := request.FormFile("imagefile")
|
||||
if err == nil {
|
||||
html.EscapeString(fileHandler.Filename)
|
||||
if data, err2 := io.ReadAll(file); err2 == nil {
|
||||
checksum = fmt.Sprintf("%x", md5.Sum(data))
|
||||
}
|
||||
file.Close()
|
||||
// }
|
||||
|
||||
// checks the post for spam. It returns true if a ban page or an error page was served (causing MakePost() to return)
|
||||
func checkIpBan(post *gcsql.Post, postBoard *gcsql.Board, writer http.ResponseWriter, request *http.Request) bool {
|
||||
ipBan, err := gcsql.CheckIPBan(post.IP, postBoard.ID)
|
||||
if err != nil {
|
||||
gcutil.LogError(err).
|
||||
Str("IP", post.IP).
|
||||
Str("boardDir", postBoard.Dir).
|
||||
Msg("Error getting IP banned status")
|
||||
serverutil.ServeErrorPage(writer, "Error getting ban info"+err.Error())
|
||||
return true
|
||||
}
|
||||
return gcsql.CheckBan(ip, tripcode, filename, checksum)
|
||||
if ipBan == nil {
|
||||
return false // ip is not banned and there were no errors, keep going
|
||||
}
|
||||
// IP is banned
|
||||
showBanpage(ipBan, "ip", "", post, postBoard, writer, request)
|
||||
return true
|
||||
}
|
||||
|
||||
func checkUsernameBan(formName string, post *gcsql.Post, postBoard *gcsql.Board, writer http.ResponseWriter, request *http.Request) bool {
|
||||
if formName == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
nameBan, err := gcsql.CheckNameBan(formName, postBoard.ID)
|
||||
if err != nil {
|
||||
gcutil.LogError(err).
|
||||
Str("IP", post.IP).
|
||||
Str("name", formName).
|
||||
Str("boardDir", postBoard.Dir).
|
||||
Msg("Error getting name banned status")
|
||||
serverutil.ServeErrorPage(writer, "Error getting name ban info")
|
||||
return true
|
||||
}
|
||||
if nameBan == nil {
|
||||
return false // name is not banned
|
||||
}
|
||||
showBanpage(nameBan, "username", "", post, postBoard, writer, request)
|
||||
return true
|
||||
}
|
||||
|
||||
func checkFilenameBan(filename string, post *gcsql.Post, postBoard *gcsql.Board, writer http.ResponseWriter, request *http.Request) bool {
|
||||
if filename == "" {
|
||||
return false
|
||||
}
|
||||
filenameBan, err := gcsql.CheckFilenameBan(filename, postBoard.ID)
|
||||
if err != nil {
|
||||
gcutil.LogError(err).
|
||||
Str("IP", post.IP).
|
||||
Str("filename", filename).
|
||||
Str("boardDir", postBoard.Dir).
|
||||
Msg("Error getting name banned status")
|
||||
serverutil.ServeErrorPage(writer, "Error getting filename ban info")
|
||||
return true
|
||||
}
|
||||
if filenameBan == nil {
|
||||
return false
|
||||
}
|
||||
showBanpage(filenameBan, "filename", filename, post, postBoard, writer, request)
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
package posting
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"html"
|
||||
"image"
|
||||
|
@ -13,6 +12,7 @@ import (
|
|||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
@ -22,7 +22,6 @@ import (
|
|||
"github.com/gochan-org/gochan/pkg/building"
|
||||
"github.com/gochan-org/gochan/pkg/config"
|
||||
"github.com/gochan-org/gochan/pkg/gcsql"
|
||||
"github.com/gochan-org/gochan/pkg/gctemplates"
|
||||
"github.com/gochan-org/gochan/pkg/gcutil"
|
||||
"github.com/gochan-org/gochan/pkg/serverutil"
|
||||
)
|
||||
|
@ -31,9 +30,21 @@ const (
|
|||
yearInSeconds = 31536000
|
||||
)
|
||||
|
||||
var (
|
||||
ErrorPostTooLong = errors.New("post is too long")
|
||||
)
|
||||
|
||||
func rejectPost(reasonShort string, reasonLong string, data map[string]interface{}, writer http.ResponseWriter, request *http.Request) {
|
||||
gcutil.LogError(errors.New(reasonLong)).
|
||||
Str("rejectedPost", reasonShort).
|
||||
Str("IP", gcutil.GetRealIP(request)).
|
||||
Fields(data).Send()
|
||||
data["rejected"] = reasonLong
|
||||
serverutil.ServeError(writer, reasonLong, serverutil.IsRequestingJSON(request), data)
|
||||
}
|
||||
|
||||
// MakePost is called when a user accesses /post. Parse form data, then insert and build
|
||||
func MakePost(writer http.ResponseWriter, request *http.Request) {
|
||||
var maxMessageLength int
|
||||
var post gcsql.Post
|
||||
var formName string
|
||||
var nameCookie string
|
||||
|
@ -46,17 +57,33 @@ func MakePost(writer http.ResponseWriter, request *http.Request) {
|
|||
http.Redirect(writer, request, systemCritical.WebRoot, http.StatusFound)
|
||||
return
|
||||
}
|
||||
wantsJSON := serverutil.IsRequestingJSON(request)
|
||||
post.IP = gcutil.GetRealIP(request)
|
||||
post.ParentID, _ = strconv.Atoi(request.FormValue("threadid"))
|
||||
post.BoardID, _ = strconv.Atoi(request.FormValue("boardid"))
|
||||
var postBoard gcsql.Board
|
||||
postBoard, err := gcsql.GetBoardFromID(post.BoardID)
|
||||
var err error
|
||||
threadidStr := request.FormValue("threadid")
|
||||
if threadidStr != "" {
|
||||
// post is a reply
|
||||
if post.ThreadID, err = strconv.Atoi(threadidStr); err != nil {
|
||||
rejectPost("invalidFormData", "Invalid form data (invalid threadid)", map[string]interface{}{
|
||||
"threadidStr": threadidStr,
|
||||
}, writer, request)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
boardidStr := request.FormValue("boardid")
|
||||
boardID, err := strconv.Atoi(boardidStr)
|
||||
if err != nil {
|
||||
gcutil.LogError(err).
|
||||
Int("boardid", post.BoardID).
|
||||
Str("IP", post.IP).
|
||||
Msg("Error getting board info")
|
||||
serverutil.ServeErrorPage(writer, "Error getting board info: "+err.Error())
|
||||
rejectPost("invalidForm", "Invalid form data (invalid boardid)", map[string]interface{}{
|
||||
"boardidStr": boardidStr,
|
||||
}, writer, request)
|
||||
return
|
||||
}
|
||||
postBoard, err := gcsql.GetBoardFromID(boardID)
|
||||
if err != nil {
|
||||
rejectPost("boardInfoError", "Error getting board info: "+err.Error(), map[string]interface{}{
|
||||
"boardid": boardID,
|
||||
}, writer, request)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -86,32 +113,23 @@ func MakePost(writer http.ResponseWriter, request *http.Request) {
|
|||
}
|
||||
|
||||
post.Subject = request.FormValue("postsubject")
|
||||
post.MessageText = strings.Trim(request.FormValue("postmsg"), "\r\n")
|
||||
|
||||
if maxMessageLength, err = gcsql.GetMaxMessageLength(post.BoardID); err != nil {
|
||||
gcutil.LogError(err).
|
||||
Int("boardid", post.BoardID).
|
||||
Str("IP", post.IP).
|
||||
Msg("Error getting board info")
|
||||
serverutil.ServeErrorPage(writer, "Error getting board info: "+err.Error())
|
||||
post.MessageRaw = strings.TrimSpace(request.FormValue("postmsg"))
|
||||
if len(post.MessageRaw) > postBoard.MaxMessageLength {
|
||||
rejectPost("messageLength", "Message is too long", map[string]interface{}{
|
||||
"messageLength": len(post.MessageRaw),
|
||||
"boardid": boardID,
|
||||
}, writer, request)
|
||||
return
|
||||
}
|
||||
|
||||
if len(post.MessageText) > maxMessageLength {
|
||||
serverutil.ServeErrorPage(writer, "Post body is too long")
|
||||
if post.MessageRaw, err = ApplyWordFilters(post.MessageRaw, postBoard.Dir); err != nil {
|
||||
rejectPost("wordfilterError", "Error formatting post: "+err.Error(), map[string]interface{}{
|
||||
"boardDir": postBoard.Dir,
|
||||
}, writer, request)
|
||||
return
|
||||
}
|
||||
|
||||
if post.MessageText, err = ApplyWordFilters(post.MessageText, postBoard.Dir); err != nil {
|
||||
gcutil.LogError(err).
|
||||
Str("IP", post.IP).
|
||||
Str("boardDir", postBoard.Dir).
|
||||
Msg("Error applying wordfilters")
|
||||
serverutil.ServeErrorPage(writer, "Error formatting post: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
post.MessageHTML = FormatMessage(post.MessageText, postBoard.Dir)
|
||||
post.Message = FormatMessage(post.MessageRaw, postBoard.Dir)
|
||||
password := request.FormValue("postpassword")
|
||||
if password == "" {
|
||||
password = gcutil.RandomString(8)
|
||||
|
@ -135,11 +153,11 @@ func MakePost(writer http.ResponseWriter, request *http.Request) {
|
|||
MaxAge: yearInSeconds,
|
||||
})
|
||||
|
||||
post.Timestamp = time.Now()
|
||||
post.CreatedOn = time.Now()
|
||||
// post.PosterAuthority = getStaffRank(request)
|
||||
post.Bumped = time.Now()
|
||||
post.Stickied = request.FormValue("modstickied") == "on"
|
||||
post.Locked = request.FormValue("modlocked") == "on"
|
||||
// bumpedTimestamp := time.Now()
|
||||
// isSticky := request.FormValue("modstickied") == "on"
|
||||
// isLocked := request.FormValue("modlocked") == "on"
|
||||
|
||||
//post has no referrer, or has a referrer from a different domain, probably a spambot
|
||||
if !serverutil.ValidReferer(request) {
|
||||
|
@ -147,12 +165,13 @@ func MakePost(writer http.ResponseWriter, request *http.Request) {
|
|||
Str("spam", "badReferer").
|
||||
Str("IP", post.IP).
|
||||
Msg("Rejected post from possible spambot")
|
||||
serverutil.ServeError(writer, "Your post looks like spam", wantsJSON, nil)
|
||||
return
|
||||
}
|
||||
|
||||
akismetResult := serverutil.CheckPostForSpam(
|
||||
post.IP, request.Header.Get("User-Agent"), request.Referer(),
|
||||
post.Name, post.Email, post.MessageText,
|
||||
post.Name, post.Email, post.MessageRaw,
|
||||
)
|
||||
logEvent := gcutil.LogInfo().
|
||||
Str("User-Agent", request.Header.Get("User-Agent")).
|
||||
|
@ -160,55 +179,41 @@ func MakePost(writer http.ResponseWriter, request *http.Request) {
|
|||
switch akismetResult {
|
||||
case "discard":
|
||||
logEvent.Str("akismet", "discard").Send()
|
||||
serverutil.ServeErrorPage(writer, "Your post looks like spam.")
|
||||
serverutil.ServeError(writer, "Your post looks like spam.", wantsJSON, nil)
|
||||
return
|
||||
case "spam":
|
||||
logEvent.Str("akismet", "spam").Send()
|
||||
serverutil.ServeErrorPage(writer, "Your post looks like spam.")
|
||||
serverutil.ServeError(writer, "Your post looks like spam.", wantsJSON, nil)
|
||||
return
|
||||
default:
|
||||
logEvent.Discard()
|
||||
}
|
||||
|
||||
postDelay, _ := gcsql.SinceLastPost(post.IP)
|
||||
if postDelay > -1 {
|
||||
if post.ParentID == 0 && postDelay < boardConfig.NewThreadDelay {
|
||||
serverutil.ServeErrorPage(writer, "Please wait before making a new thread.")
|
||||
return
|
||||
} else if post.ParentID > 0 && postDelay < boardConfig.ReplyDelay {
|
||||
serverutil.ServeErrorPage(writer, "Please wait before making a reply.")
|
||||
return
|
||||
}
|
||||
var delay int
|
||||
var tooSoon bool
|
||||
if threadidStr == "" {
|
||||
// creating a new thread
|
||||
delay, err = gcsql.SinceLastThread(post.IP)
|
||||
tooSoon = delay < boardConfig.NewThreadDelay
|
||||
} else {
|
||||
delay, err = gcsql.SinceLastPost(post.IP)
|
||||
tooSoon = delay < boardConfig.ReplyDelay
|
||||
}
|
||||
|
||||
banStatus, err := getBannedStatus(request)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
gcutil.LogError(err).
|
||||
Str("IP", post.IP).
|
||||
Fields(gcutil.ParseName(formName)).
|
||||
Msg("Error getting banned status")
|
||||
serverutil.ServeErrorPage(writer, "Error getting banned status: "+err.Error())
|
||||
if err != nil {
|
||||
rejectPost("cooldownError", "Error checking post cooldown: "+err.Error(), map[string]interface{}{
|
||||
"boardDir": postBoard.Dir,
|
||||
}, writer, request)
|
||||
return
|
||||
}
|
||||
if tooSoon {
|
||||
rejectPost("cooldownError", "Please wait before making a new post", map[string]interface{}{}, writer, request)
|
||||
return
|
||||
}
|
||||
|
||||
boards, _ := gcsql.GetAllBoards()
|
||||
|
||||
if banStatus != nil && banStatus.IsBanned(postBoard.Dir) {
|
||||
var banpageBuffer bytes.Buffer
|
||||
|
||||
if err = serverutil.MinifyTemplate(gctemplates.Banpage, map[string]interface{}{
|
||||
"systemCritical": config.GetSystemCriticalConfig(),
|
||||
"siteConfig": config.GetSiteConfig(),
|
||||
"boardConfig": config.GetBoardConfig(""),
|
||||
"ban": banStatus,
|
||||
"banBoards": boards[post.BoardID-1].Dir,
|
||||
}, writer, "text/html"); err != nil {
|
||||
gcutil.LogError(err).
|
||||
Str("building", "minifier").Send()
|
||||
serverutil.ServeErrorPage(writer, "Error minifying page: "+err.Error())
|
||||
return
|
||||
}
|
||||
writer.Write(banpageBuffer.Bytes())
|
||||
if checkIpBan(&post, postBoard, writer, request) {
|
||||
return
|
||||
}
|
||||
if checkUsernameBan(formName, &post, postBoard, writer, request) {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -232,8 +237,7 @@ func MakePost(writer http.ResponseWriter, request *http.Request) {
|
|||
var filePath, thumbPath, catalogThumbPath string
|
||||
if err != nil || handler.Size == 0 {
|
||||
// no file was uploaded
|
||||
post.Filename = ""
|
||||
if strings.TrimSpace(post.MessageText) == "" {
|
||||
if strings.TrimSpace(post.MessageRaw) == "" {
|
||||
serverutil.ServeErrorPage(writer, "Post must contain a message if no image is uploaded.")
|
||||
return
|
||||
}
|
||||
|
@ -250,33 +254,21 @@ func MakePost(writer http.ResponseWriter, request *http.Request) {
|
|||
return
|
||||
}
|
||||
defer file.Close()
|
||||
post.FilenameOriginal = html.EscapeString(handler.Filename)
|
||||
ext := gcutil.GetFileExtension(post.FilenameOriginal)
|
||||
thumbExt := strings.ToLower(ext)
|
||||
if thumbExt == "gif" || thumbExt == "webm" || thumbExt == "mp4" {
|
||||
thumbExt = "jpg"
|
||||
}
|
||||
var upload gcsql.Upload
|
||||
upload.OriginalFilename = html.EscapeString(handler.Filename)
|
||||
|
||||
ext := strings.ToLower(filepath.Ext(upload.OriginalFilename))
|
||||
upload.Filename = getNewFilename() + ext
|
||||
|
||||
post.Filename = getNewFilename() + "." + ext
|
||||
boardExists := gcsql.DoesBoardExistByID(
|
||||
gcutil.HackyStringToInt(request.FormValue("boardid")))
|
||||
if !boardExists {
|
||||
serverutil.ServeErrorPage(writer, "No boards have been created yet")
|
||||
return
|
||||
}
|
||||
var _board = gcsql.Board{}
|
||||
err = _board.PopulateData(gcutil.HackyStringToInt(request.FormValue("boardid")))
|
||||
if err != nil {
|
||||
gcutil.LogError(err).
|
||||
Str("IP", post.IP).
|
||||
Str("posting", "updateBoard").Send()
|
||||
serverutil.ServeErrorPage(writer, "Server error: "+err.Error())
|
||||
return
|
||||
}
|
||||
boardDir := _board.Dir
|
||||
filePath = path.Join(systemCritical.DocumentRoot, boardDir, "src", post.Filename)
|
||||
thumbPath = path.Join(systemCritical.DocumentRoot, boardDir, "thumb", strings.Replace(post.Filename, "."+ext, "t."+thumbExt, -1))
|
||||
catalogThumbPath = path.Join(systemCritical.DocumentRoot, boardDir, "thumb", strings.Replace(post.Filename, "."+ext, "c."+thumbExt, -1))
|
||||
filePath = path.Join(systemCritical.DocumentRoot, postBoard.Dir, "src", upload.Filename)
|
||||
thumbPath = path.Join(systemCritical.DocumentRoot, postBoard.Dir, "thumb", upload.ThumbnailPath("thumb"))
|
||||
catalogThumbPath = path.Join(systemCritical.DocumentRoot, postBoard.Dir, "thumb", upload.ThumbnailPath("catalog"))
|
||||
|
||||
if err = os.WriteFile(filePath, data, 0644); err != nil {
|
||||
gcutil.LogError(err).
|
||||
|
@ -353,7 +345,7 @@ func MakePost(writer http.ResponseWriter, request *http.Request) {
|
|||
}
|
||||
}
|
||||
thumbType := "reply"
|
||||
if post.ParentID == 0 {
|
||||
if post.IsTopPost {
|
||||
thumbType = "op"
|
||||
}
|
||||
post.ThumbW, post.ThumbH = getThumbnailSize(post.ImageW, post.ImageH, boardDir, thumbType)
|
||||
|
@ -474,7 +466,7 @@ func MakePost(writer http.ResponseWriter, request *http.Request) {
|
|||
}
|
||||
|
||||
// rebuild the board page
|
||||
building.BuildBoards(false, post.BoardID)
|
||||
building.BuildBoards(false, postBoard.ID)
|
||||
building.BuildFrontPage()
|
||||
|
||||
if emailCommand == "noko" {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue