1
0
Fork 0
mirror of https://github.com/Eggbertx/gochan.git synced 2025-08-18 15:56:23 -07:00
gochan/pkg/gcsql/posts.go

199 lines
6.3 KiB
Go
Raw Normal View History

2022-01-30 18:15:15 -08:00
package gcsql
import (
"fmt"
"os"
"path"
"time"
"github.com/gochan-org/gochan/pkg/config"
"github.com/gochan-org/gochan/pkg/gcutil"
)
2022-01-30 18:15:15 -08:00
2022-08-18 16:48:21 -07:00
// SinceLastPost returns the number of seconds since the given IP address created a post
// (used for checking against the new thread/new reply cooldown)
func SinceLastPost(postIP string) (int, error) {
const sql = `SELECT MAX(created_on) FROM DBPREFIXposts WHERE ip = ?`
2022-01-30 18:15:15 -08:00
var when time.Time
2022-08-18 16:48:21 -07:00
err := QueryRowSQL(sql, interfaceSlice(postIP), interfaceSlice(&when))
2022-01-30 18:15:15 -08:00
if err != nil {
return -1, err
}
return int(time.Since(when).Seconds()), nil
}
// InsertPost insersts prepared post object into the SQL table so that it can be rendered
// Deprecated: This method was created to support old functionality during the database refactor of april 2020
// The code should be changed to reflect the new database design
func InsertPost(post *Post, bump bool) error {
const sql = `INSERT INTO DBPREFIXposts (id, thread_id, name, tripcode, is_role_signature, email, subject, ip, is_top_post, message, message_raw, banned_message, password)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
isNewThread := post.ParentID == 0
var threadID int
var err error
if isNewThread {
threadID, err = createThread(post.BoardID, post.Locked, post.Stickied, post.Autosage, false)
} else {
threadID, err = getThreadID(post.ParentID)
}
if err != nil {
return err
}
//Retrieves next free ID, explicitly inserts it, keeps retrying until succesfull insert or until a non-pk error is encountered.
//This is done because mysql doesnt support RETURNING and both LAST_INSERT_ID() and last_row_id() are not thread-safe
isPrimaryKeyError := true
for isPrimaryKeyError {
nextFreeID, err := getNextFreeID("DBPREFIXposts")
if err != nil {
return err
}
_, err = ExecSQL(sql, nextFreeID, threadID, post.Name, post.Tripcode, false, post.Email, post.Subject, post.IP, isNewThread, string(post.MessageHTML), post.MessageText, "", post.Password)
isPrimaryKeyError, err = errFilterDuplicatePrimaryKey(err)
if err != nil {
return err
}
if !isPrimaryKeyError {
post.ID = nextFreeID
}
}
if post.Filename != "" {
err = appendFile(post.ID, post.FilenameOriginal, post.Filename, post.FileChecksum, post.Filesize, false, post.ImageW, post.ImageH, post.ThumbW, post.ThumbH)
}
if err != nil {
return err
}
if bump {
return bumpThread(threadID)
}
return nil
}
// GetReplyCount gets the total amount non-deleted of replies in a thread
func GetReplyCount(postID int) (int, error) {
const sql = `SELECT COUNT(posts.id) FROM DBPREFIXposts as posts
JOIN (
SELECT threads.id FROM DBPREFIXthreads as threads
JOIN DBPREFIXposts as posts
ON posts.thread_id = threads.id
WHERE posts.id = ?
) as thread
ON posts.thread_id = thread.id
WHERE posts.is_deleted = FALSE`
var count int
err := QueryRowSQL(sql, interfaceSlice(postID), interfaceSlice(&count))
return count, err
}
// GetReplyFileCount gets the amount of files non-deleted posted in total in a thread
func GetReplyFileCount(postID int) (int, error) {
const sql = `SELECT COUNT(files.id) from DBPREFIXfiles as files
JOIN (SELECT posts.id FROM DBPREFIXposts as posts
JOIN (
SELECT threads.id FROM DBPREFIXthreads as threads
JOIN DBPREFIXposts as posts
ON posts.thread_id = threads.id
WHERE posts.id = ?
) as thread
ON posts.thread_id = thread.id
WHERE posts.is_deleted = FALSE) as posts
ON posts.id = files.post_id`
var count int
err := QueryRowSQL(sql, interfaceSlice(postID), interfaceSlice(&count))
return count, err
}
2022-08-27 23:37:59 -07:00
func GetPostsFromIP(ip string, limit int, onlyNotDeleted bool) ([]Post, error) {
sql := `SELECT
DBPREFIXposts.id,
thread_id AS threadid,
(SELECT id FROM DBPREFIXposts WHERE is_top_post = TRUE AND thread_id = threadid LIMIT 1),
(SELECT board_id FROM DBPREFIXthreads WHERE id = DBPREFIXposts.thread_id) as board_id,
created_on,name,tripcode,email,subject,message,message_raw,password,
COALESCE(files.filename,''),
COALESCE(files.original_filename,''),
COALESCE(files.thumbnail_width, 0),
COALESCE(files.thumbnail_height, 0),
COALESCE(files.width, 0),
COALESCE(files.height, 0)
FROM DBPREFIXposts LEFT OUTER JOIN DBPREFIXfiles AS files ON files.post_id = DBPREFIXposts.id
WHERE ip = ?`
if onlyNotDeleted {
sql += " AND is_deleted = 0"
}
sql += " ORDER BY id DESC LIMIT ?"
rows, err := QuerySQL(sql, ip, limit)
if err != nil {
return nil, err
}
var posts []Post
for rows.Next() {
var post Post
post.IP = ip
var drop int
if err = rows.Scan(
&post.ID, &drop, &post.ParentID,
&post.BoardID,
&post.Timestamp, &post.Name, &post.Tripcode, &post.Email, &post.Subject, &post.MessageHTML, &post.MessageText, &post.Password,
&post.Filename, &post.FilenameOriginal, &post.ThumbW, &post.ThumbH, &post.ImageW, &post.ImageH,
); err != nil {
return nil, err
}
posts = append(posts, post)
}
return posts, nil
}
func (p *Post) DeleteFiles(leaveDeletedBox bool) error {
board, boardWasFound, err := GetBoardFromPostID(p.ID)
if err != nil {
return err
}
if !boardWasFound {
return fmt.Errorf("could not find board for post %v", p.ID)
}
const filenameSQL = `SELECT filename FROM DBPREFIXfiles WHERE post_id = ?`
rows, err := QuerySQL(filenameSQL, p.ID)
if err != nil {
return err
}
var filenames []string
for rows.Next() {
var filename string
if err = rows.Scan(&filename); err != nil {
return err
}
filenames = append(filenames, filename)
}
systemCriticalCfg := config.GetSystemCriticalConfig()
//Remove files from disk
for _, filename := range filenames {
_, filenameBase, fileExt := gcutil.GetFileParts(filename)
thumbExt := fileExt
if thumbExt == "gif" || thumbExt == "webm" || thumbExt == "mp4" {
thumbExt = "jpg"
}
uploadPath := path.Join(systemCriticalCfg.DocumentRoot, board, "/src/", filenameBase+"."+fileExt)
thumbPath := path.Join(systemCriticalCfg.DocumentRoot, board, "/thumb/", filenameBase+"t."+thumbExt)
catalogThumbPath := path.Join(systemCriticalCfg.DocumentRoot, board, "/thumb/", filenameBase+"c."+thumbExt)
os.Remove(uploadPath)
os.Remove(thumbPath)
os.Remove(catalogThumbPath)
}
var sqlStr string
if leaveDeletedBox {
// leave a "File Deleted" box
sqlStr = `UPDATE DBPREFIXfiles SET filename = 'deleted', original_filename = 'deleted' WHERE post_id = ?`
} else {
sqlStr = `DELETE FROM DBPREFIXfiles WHERE post_id = ?`
}
_, err = ExecSQL(sqlStr, p.ID)
return err
}