mirror of
https://github.com/Eggbertx/gochan.git
synced 2025-08-28 08:06:24 -07:00
Add top post code, post insertion code, and captcha de code
TODO: revisit captcha to make it less clunky
This commit is contained in:
parent
3abf174ba2
commit
45e2a76473
2 changed files with 110 additions and 10 deletions
|
@ -21,9 +21,12 @@ const (
|
|||
)
|
||||
|
||||
var (
|
||||
ErrNotTopPost = errors.New("not the top post in the thread")
|
||||
ErrPostDoesNotExist = errors.New("post does not exist")
|
||||
ErrPostDeleted = errors.New("post is deleted")
|
||||
ErrNotTopPost = errors.New("not the top post in the thread")
|
||||
ErrPostDoesNotExist = errors.New("post does not exist")
|
||||
ErrPostDeleted = errors.New("post is deleted")
|
||||
ErrorPostAlreadySent = errors.New("post already submitted")
|
||||
// TempPosts is a cached list of all of the posts in the temporary posts table, used for temporarily storing CAPTCHA
|
||||
TempPosts []Post
|
||||
)
|
||||
|
||||
func GetPostFromID(id int, onlyNotDeleted bool) (*Post, error) {
|
||||
|
@ -32,10 +35,10 @@ func GetPostFromID(id int, onlyNotDeleted bool) (*Post, error) {
|
|||
query += " AND is_deleted = 0"
|
||||
}
|
||||
post := new(Post)
|
||||
post.ID = id
|
||||
err := QueryRowSQL(query, interfaceSlice(id), interfaceSlice(
|
||||
&post.ID, &post.ThreadID, &post.IsTopPost, &post.IP, &post.CreatedOn, &post.Name, &post.Tripcode, &post.IsRoleSignature,
|
||||
&post.Email, &post.Subject, &post.Message, &post.MessageRaw, &post.Password, &post.DeletedAt, &post.IsDeleted, &post.BannedMessage,
|
||||
&post.ID, &post.ThreadID, &post.IsTopPost, &post.IP, &post.CreatedOn, &post.Name,
|
||||
&post.Tripcode, &post.IsRoleSignature, &post.Email, &post.Subject, &post.Message,
|
||||
&post.MessageRaw, &post.Password, &post.DeletedAt, &post.IsDeleted, &post.BannedMessage,
|
||||
))
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, ErrPostDoesNotExist
|
||||
|
@ -44,6 +47,52 @@ func GetPostFromID(id int, onlyNotDeleted bool) (*Post, error) {
|
|||
return post, err
|
||||
}
|
||||
|
||||
func GetTopPostInThread(postID int) (int, error) {
|
||||
const query = `SELECT id FROM DBPREFIXposts WHERE thread_id = (
|
||||
SELECT thread_id FROM DBPREFIXposts WHERE id = ?
|
||||
) AND is_top_post = TRUE ORDER BY id ASC LIMIT 1`
|
||||
var id int
|
||||
err := QueryRowSQL(query, interfaceSlice(postID), interfaceSlice(&id))
|
||||
return id, err
|
||||
}
|
||||
|
||||
func GetThreadTopPost(threadID int) (*Post, error) {
|
||||
const query = selectPostsBaseSQL + "WHERE thread_id = ? AND is_top_post = TRUE LIMIT 1"
|
||||
post := new(Post)
|
||||
err := QueryRowSQL(query, interfaceSlice(threadID), interfaceSlice(
|
||||
&post.ID, &post.ThreadID, &post.IsTopPost, &post.IP, &post.CreatedOn, &post.Name,
|
||||
&post.Tripcode, &post.IsRoleSignature, &post.Email, &post.Subject, &post.Message,
|
||||
&post.MessageRaw, &post.Password, &post.DeletedAt, &post.IsDeleted, &post.BannedMessage,
|
||||
))
|
||||
return post, err
|
||||
}
|
||||
|
||||
func GetBoardTopPosts(boardID int, onlyNotDeleted bool) ([]Post, error) {
|
||||
query := selectPostsBaseSQL + "WHERE board_id = ?"
|
||||
if onlyNotDeleted {
|
||||
query += " AND is_deleted = FALSE"
|
||||
}
|
||||
rows, err := QuerySQL(query, boardID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var posts []Post
|
||||
for rows.Next() {
|
||||
var post Post
|
||||
err = rows.Scan(
|
||||
&post.ID, &post.ThreadID, &post.IsTopPost, &post.IP, &post.CreatedOn, &post.Name,
|
||||
&post.Tripcode, &post.IsRoleSignature, &post.Email, &post.Subject, &post.Message,
|
||||
&post.MessageRaw, &post.Password, &post.DeletedAt, &post.IsDeleted, &post.BannedMessage,
|
||||
)
|
||||
if err != nil {
|
||||
return posts, err
|
||||
}
|
||||
posts = append(posts, post)
|
||||
}
|
||||
return posts, nil
|
||||
}
|
||||
|
||||
// GetPostPassword returns the password checksum of the post with the given ID
|
||||
func GetPostPassword(id int) (string, error) {
|
||||
const query = `SELECT password FROM DBPREFIXposts WHERE id = ?`
|
||||
|
@ -170,6 +219,45 @@ func (p *Post) Delete() error {
|
|||
return err
|
||||
}
|
||||
|
||||
func (p *Post) Insert(bumpThread bool, boardID int, locked bool, stickied bool, anchored bool, cyclical bool) error {
|
||||
if p.ID > 0 {
|
||||
// already inserted
|
||||
return ErrorPostAlreadySent
|
||||
}
|
||||
insertSQL := `INSERT INTO DBPREFIXposts
|
||||
(thread_id, is_top_post, ip, created_on, name, tripcode, is_role_signature, email, subject,
|
||||
message, message_raw, password)
|
||||
VALUES(?,?,?,CURRENT_TIMESTAMP,?,?,?,?,?,?,?,?)`
|
||||
bumpSQL := `UPDATE DBPREFIXthreads SET last_bump = CURRENT_TIMESTAMP WHERE id = ?`
|
||||
var err error
|
||||
if p.ThreadID == 0 {
|
||||
// thread doesn't exist yet, this is a new post
|
||||
p.IsTopPost = true
|
||||
var threadID int
|
||||
threadID, err = createThread(boardID, locked, stickied, anchored, cyclical)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p.ThreadID = threadID
|
||||
}
|
||||
|
||||
id, err := getNextFreeID("DBPREFIXposts")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = ExecSQL(insertSQL,
|
||||
p.ThreadID, p.IsTopPost, p.IP, p.Name, p.Tripcode, p.IsRoleSignature, p.Email, p.Subject,
|
||||
p.Message, p.MessageRaw, p.Password,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
p.ID = id
|
||||
if bumpThread {
|
||||
_, err = ExecSQL(bumpSQL, p.ThreadID)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (p *Post) WebPath() string {
|
||||
webRoot := config.GetSystemCriticalConfig().WebRoot
|
||||
var threadID, opID, boardID int
|
||||
|
|
|
@ -79,6 +79,19 @@ func ServeCaptcha(writer http.ResponseWriter, request *http.Request) {
|
|||
}
|
||||
writer.Header().Add("Content-Type", "text/html")
|
||||
captchaID := request.FormValue("captchaid")
|
||||
boardIDstr := request.FormValue("boardid")
|
||||
boardID, err := strconv.Atoi(boardIDstr)
|
||||
if err != nil {
|
||||
gcutil.LogError(err).
|
||||
Str("ip", gcutil.GetRealIP(request)).
|
||||
Str("boardid", boardIDstr).Send()
|
||||
serverutil.ServeError(writer, fmt.Sprintf("Invalid boardid value %q", boardIDstr),
|
||||
useJSON, map[string]interface{}{
|
||||
"boardid": boardIDstr,
|
||||
})
|
||||
serverutil.ServeErrorPage(writer, fmt.Sprintf("Invalid boardid value %q", boardIDstr))
|
||||
return
|
||||
}
|
||||
captchaAnswer := request.FormValue("captchaanswer")
|
||||
if captchaID != "" && request.FormValue("didreload") != "1" {
|
||||
goodAnswer := base64Captcha.DefaultMemStore.Verify(captchaID, captchaAnswer, true)
|
||||
|
@ -86,12 +99,11 @@ func ServeCaptcha(writer http.ResponseWriter, request *http.Request) {
|
|||
if tempPostIndex > -1 && tempPostIndex < len(gcsql.TempPosts) {
|
||||
// came from a /post redirect, insert the specified temporary post
|
||||
// and redirect to the thread
|
||||
|
||||
gcsql.InsertPost(&gcsql.TempPosts[tempPostIndex], emailCommand == "noko")
|
||||
building.BuildBoards(false, gcsql.TempPosts[tempPostIndex].BoardID)
|
||||
gcsql.TempPosts[tempPostIndex].Insert(emailCommand != "sage", boardID, false, false, false, false)
|
||||
building.BuildBoards(false, boardID)
|
||||
building.BuildFrontPage()
|
||||
|
||||
url := gcsql.TempPosts[tempPostIndex].GetURL(false)
|
||||
url := gcsql.TempPosts[tempPostIndex].WebPath()
|
||||
|
||||
// move the end Post to the current index and remove the old end Post. We don't
|
||||
// really care about order as long as tempPost validation doesn't get jumbled up
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue