1
0
Fork 0
mirror of https://github.com/Eggbertx/gochan.git synced 2025-08-03 07:36:23 -07:00

more parameters, new beta versioning scheme

This commit is contained in:
Joshua Merrell 2017-12-19 18:13:47 -08:00
parent ddf2aaff92
commit b9ab1f5ca2
7 changed files with 191 additions and 92 deletions

View file

@ -3,7 +3,7 @@ GOCHAN_DEBUG=1
GOCHAN_VERBOSE=2
GOCHAN_VERBOSITY=0 # This is set by "make release/debug/verbose"
GOCHAN_VERSION=1.5.1
GOCHAN_VERSION=1.5.b2
GOCHAN_BUILDTIME=$(shell date +%y%m%d.%H%M)
ifeq ($(GOOS), windows)
GOCHAN_BIN=gochan.exe

View file

@ -7,6 +7,6 @@
<h1>404: File not found</h1>
<img src="/error/lol 404.gif" border="0" alt="">
<p>The requested file could not be found on this server. Are you just typing random stuff in the address bar? If you followed a link from this site here, then post <a href="/site">here</a></p>
<hr><address>http://gochan.org powered by Gochan v1.5.1</address>
<hr><address>http://gochan.org powered by Gochan v1.5.b2</address>
</body>
</html>

View file

@ -7,6 +7,6 @@
<h1>500: Internal Server error</h1>
<img src="/error/derpy server.gif" border="0" alt="">
<p>The server encountered an error while trying to serve the page, and we apologize for the inconvenience. The <a href="https://en.wikipedia.org/wiki/Idiot">system administrator</a> will try to fix things as soon has he/she/it can.</p>
<hr><address>http://gochan.org powered by Gochan v1.5.1</address>
<hr><address>http://gochan.org powered by Gochan v1.5.b2</address>
</body>
</html>

View file

@ -647,63 +647,42 @@ var manage_functions = map[string]ManageFunction{
continue
}
//_, err := db.Prepare("INSERT INTO (" + generatePlaceholders(24, ", ") + ")")
_, err := db.Exec(
"INSERT INTO `" + config.DBprefix + "boards` (" +
"`order`, " +
"`dir`, " +
"`type`, " +
"`upload_type`, " +
"`title`, " +
"`subtitle`, " +
"`description`, " +
"`section`, " +
"`max_image_size`, " +
"`max_pages`, " +
"`locale`, " +
"`default_style`, " +
"`locked`, " +
"`created_on`, " +
"`anonymous`, " +
"`forced_anon`, " +
"`max_age`, " +
"`autosage_after`, " +
"`no_images_after`, " +
"`max_message_length`, " +
"`embeds_allowed`, " +
"`redirect_to_thread`, " +
"`require_file`, " +
"`enable_catalog`" +
") VALUES(" +
strconv.Itoa(board.Order) + ", '" +
board.Dir + "', " +
strconv.Itoa(board.Type) + ", " +
strconv.Itoa(board.UploadType) + ", '" +
board.Title + "', '" +
board.Subtitle + "', '" +
board.Description + "', " +
strconv.Itoa(board.Section) + ", " +
strconv.Itoa(board.MaxImageSize) + ", " +
strconv.Itoa(board.MaxPages) + ", '" +
board.Locale + "', '" +
board.DefaultStyle + "', " +
Btoa(board.Locked) + ", '" +
getSpecificSQLDateTime(board.CreatedOn) + "', '" +
board.Anonymous + "', " +
Btoa(board.ForcedAnon) + ", " +
strconv.Itoa(board.MaxAge) + ", " +
strconv.Itoa(board.AutosageAfter) + ", " +
strconv.Itoa(board.NoImagesAfter) + ", " +
strconv.Itoa(board.MaxMessageLength) + ", " +
Btoa(board.EmbedsAllowed) + ", " +
Btoa(board.RedirectToThread) + ", " +
Btoa(board.RequireFile) + ", " +
Btoa(board.EnableCatalog) + ")")
stmt, err := db.Prepare(
"INSERT INTO `" + config.DBprefix + "boards` (`order`,`dir`,`type`,`upload_type`,`title`,`subtitle`," +
"`description`,`section`,`max_image_size`,`max_pages`,`locale`,`default_style`,`locked`,`created_on`," +
"`anonymous`,`forced_anon`,`max_age`,`autosage_after`,`no_images_after`,`max_message_length`,`embeds_allowed`," +
"`redirect_to_thread`,`require_file`,`enable_catalog`) " +
"VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)")
defer func() {
if stmt != nil {
stmt.Close()
}
}()
if err != nil {
do = ""
board_creation_status = err.Error()
continue
}
boardCreationTimestamp := getSpecificSQLDateTime(board.CreatedOn)
_, err = stmt.Exec(
&board.Order, &board.Dir, &board.Type, &board.UploadType,
&board.Title, &board.Subtitle, &board.Description, &board.Section,
&board.MaxImageSize, &board.MaxPages, &board.Locale, &board.DefaultStyle,
&board.Locked, &boardCreationTimestamp, &board.Anonymous,
&board.ForcedAnon, &board.MaxAge, &board.AutosageAfter,
&board.NoImagesAfter, &board.MaxMessageLength, &board.EmbedsAllowed,
&board.RedirectToThread, &board.RequireFile, &board.EnableCatalog,
)
if err != nil {
do = ""
board_creation_status = err.Error()
continue
} else {
board_creation_status = "Board created successfully"
rebuildboards()
done = true
}
resetBoardSectionArrays()
@ -998,15 +977,32 @@ var manage_functions = map[string]ManageFunction{
new_username := request.FormValue("username")
new_password := request.FormValue("password")
new_rank := request.FormValue("rank")
_, err := db.Exec("INSERT INTO `" + config.DBprefix + "staff` (`username`, `password_checksum`, `rank`) VALUES('" + new_username + "','" + bcryptSum(new_password) + "', '" + new_rank + "');")
stmt, err := db.Prepare("INSERT INTO `" + config.DBprefix + "staff` (`username`, `password_checksum`, `rank`) VALUES(?,?,?)")
defer func() {
if stmt != nil {
stmt.Close()
}
}()
if err != nil {
serveErrorPage(writer, err.Error())
}
_, err = stmt.Exec(&new_username, bcryptSum(new_password), &new_rank)
if err != nil {
serveErrorPage(writer, err.Error())
}
} else if request.FormValue("do") == "del" && request.FormValue("username") != "" {
_, err := db.Exec("DELETE FROM `" + config.DBprefix + "staff` WHERE `username` = '" + request.FormValue("username") + "'")
stmt, err := db.Prepare("DELETE FROM `" + config.DBprefix + "staff` WHERE `username` = ?")
defer func() {
if stmt != nil {
stmt.Close()
}
}()
if err != nil {
serveErrorPage(writer, err.Error())
}
_, err = stmt.Exec(request.FormValue("username"))
}
var rank string

View file

@ -55,13 +55,13 @@ func generateTripCode(input string) string {
func buildBoards(all bool, which int) (html string) {
// if all is set to true, ignore which, otherwise, which = build only specified boardid
if !all {
_board, _ := getBoardArr("`id` = " + strconv.Itoa(which))
_board, _ := getBoardArr(map[string]interface{}{"id": which}, "")
board := _board[0]
html += buildBoardPages(&board) + "<br />\n"
html += buildThreads(true, board.ID, 0)
return
}
boards, _ := getBoardArr("")
boards, _ := getBoardArr(nil, "")
if len(boards) == 0 {
return html + "No boards to build.<br />\n"
}
@ -116,11 +116,16 @@ func buildBoardPages(board *BoardsTable) (html string) {
}
// Get all top level posts for the board.
op_posts, err := getPostArr("SELECT * FROM " + config.DBprefix + "posts WHERE `boardid` = " +
strconv.Itoa(board.ID) + " AND `parentid` = 0 AND `deleted_timestamp` = '" + nil_timestamp + "' ORDER BY `bumped` DESC")
//op_posts, err := getPostArr("SELECT * FROM " + config.DBprefix + "posts WHERE `boardid` = " +
// strconv.Itoa(board.ID) + " AND `parentid` = 0 AND `deleted_timestamp` = '" + nil_timestamp + "' ORDER BY `bumped` DESC")
op_posts, err := getPostArr(map[string]interface{}{
"boardid": board.ID,
"parentid": 0,
"deleted_timestamp": nil_timestamp,
}, " ORDER BY `bumped` DESC")
if err != nil {
html += err.Error() + "<br />"
op_posts = make([]interface{}, 0)
op_posts = nil //make([]interface{}, 0)
return
}
@ -128,11 +133,11 @@ func buildBoardPages(board *BoardsTable) (html string) {
for _, op_post_i := range op_posts {
var thread Thread
var posts_in_thread []interface{}
op_post := op_post_i.(PostTable)
thread.IName = "thread"
// Store the OP post for this thread
op_post := op_post_i.(PostTable)
//op_post := op_post_i.(PostTable)
// Get the number of replies to this thread.
stmt, err := db.Prepare("SELECT COUNT(*) FROM `" + config.DBprefix + "posts` WHERE `boardid` = ? AND `parentid` = ? AND `deleted_timestamp` = ?")
@ -159,22 +164,42 @@ func buildBoardPages(board *BoardsTable) (html string) {
html += err.Error() + "<br />\n"
}
thread.OP = op_post_i
thread.OP = op_post
if op_post.Stickied {
// If the thread is stickied, limit replies on the archive page to the
// configured value for stickied threads.
posts_in_thread, err = getPostArr("SELECT * FROM (SELECT * FROM " + config.DBprefix + "posts WHERE `boardid` = " + strconv.Itoa(board.ID) + " AND `parentid` = " + strconv.Itoa(op_post.ID) + " AND `deleted_timestamp` = '" + nil_timestamp + "' ORDER BY `id` DESC LIMIT " + strconv.Itoa(config.StickyRepliesOnBoardPage) + ") AS posts ORDER BY id ASC")
//posts_in_thread, err = getPostArr("SELECT * FROM (SELECT * FROM " + config.DBprefix + "posts WHERE `boardid` = " + strconv.Itoa(board.ID) + " AND `parentid` = " + strconv.Itoa(op_post.ID) + " AND `deleted_timestamp` = '" + nil_timestamp + "' ORDER BY `id` DESC LIMIT " + strconv.Itoa(config.StickyRepliesOnBoardPage) + ") AS posts ORDER BY id ASC")
posts_in_thread, err = getPostArr(map[string]interface{}{
"boardid": board.ID,
"parentid": op_post.ID,
"deleted_timestamp": nil_timestamp,
}, fmt.Sprintf(" ORDER BY `id` DESC LIMIT %d", config.StickyRepliesOnBoardPage))
if err != nil {
html += err.Error() + "<br />"
}
} else {
// Otherwise, limit the replies to the configured value for normal threads.
posts_in_thread, err = getPostArr("SELECT * FROM (SELECT * FROM " + config.DBprefix + "posts WHERE `boardid` = " + strconv.Itoa(board.ID) + " AND `parentid` = " + strconv.Itoa(op_post.ID) + " AND `deleted_timestamp` = '" + nil_timestamp + "' ORDER BY `id` DESC LIMIT " + strconv.Itoa(config.RepliesOnBoardPage) + ") AS posts ORDER BY id ASC")
//posts_in_thread, err = getPostArr("SELECT * FROM (SELECT * FROM " + config.DBprefix + "posts WHERE `boardid` = " + strconv.Itoa(board.ID) + " AND `parentid` = " + strconv.Itoa(op_post.ID) + " AND `deleted_timestamp` = '" + nil_timestamp + "' ORDER BY `id` DESC LIMIT " + strconv.Itoa(config.RepliesOnBoardPage) + ") AS posts ORDER BY id ASC")
/*
SELECT * FROM (
SELECT * FROM `gc_posts` WHERE
`boardid` = board.ID AND
`parentid` = op_post.ID AND
`deleted_timestamp` = '000'
ORDER BY `id` DESC LIMIT config.RepliesOnBoardPage
) AS posts ORDER BY id ASC;
*/
posts_in_thread, err = getPostArr(map[string]interface{}{
"boardid": board.ID,
"parentid": op_post.ID,
"deleted_timestamp": nil_timestamp,
}, fmt.Sprintf("ORDER BY `id` DESC LIMIT %d", config.RepliesOnBoardPage))
if err != nil {
html += err.Error() + "<br />"
}
}
if len(posts_in_thread) > 0 {
@ -366,19 +391,30 @@ func buildThreads(all bool, boardid, threadid int) (html string) {
// TODO: detect which page will be built and only build that one and the board page
// if all is set to true, ignore which, otherwise, which = build only specified boardid
if !all {
_thread, _ := getPostArr("SELECT * FROM " + config.DBprefix + "posts WHERE `boardid` = " + strconv.Itoa(boardid) + " AND `id` = " + strconv.Itoa(threadid) + " AND `parentid` = 0 AND `deleted_timestamp` = '" + nil_timestamp + "'")
thread := _thread[0]
thread_struct := thread.(PostTable)
html += buildThreadPages(&thread_struct) + "<br />\n"
//_thread, _ := getPostArr("SELECT * FROM " + config.DBprefix + "posts WHERE `boardid` = " + strconv.Itoa(boardid) + " AND `id` = " + strconv.Itoa(threadid) + " AND `parentid` = 0 AND `deleted_timestamp` = '" + nil_timestamp + "'")
_thread, _ := getPostArr(map[string]interface{}{
"boardid": boardid,
"id": threadid,
"parentid": 0,
"deleted_timestamp": nil_timestamp,
}, "")
thread := _thread[0].(PostTable)
//thread_struct := thread.(PostTable)
html += buildThreadPages(&thread) + "<br />\n"
return
}
threads, _ := getPostArr("SELECT * FROM " + config.DBprefix + "posts WHERE `boardid` = " + strconv.Itoa(boardid) + " AND `parentid` = 0 AND `deleted_timestamp` = '" + nil_timestamp + "'")
//threads, _ := getPostArr("SELECT * FROM " + config.DBprefix + "posts WHERE `boardid` = " + strconv.Itoa(boardid) + " AND `parentid` = 0 AND `deleted_timestamp` = '" + nil_timestamp + "'")
threads, _ := getPostArr(map[string]interface{}{
"boardid": boardid,
"parentid": 0,
"deleted_timestamp": nil_timestamp,
}, "")
if len(threads) == 0 {
return
}
for _, op := range threads {
op_struct := op.(PostTable)
html += buildThreadPages(&op_struct) + "<br />\n"
for _, op_i := range threads {
op := op_i.(PostTable)
html += buildThreadPages(&op) + "<br />\n"
}
return
}
@ -410,7 +446,12 @@ func buildThreadPages(op *PostTable) (html string) {
return
}
replies, err = getPostArr("SELECT * FROM " + config.DBprefix + "posts WHERE `boardid` = " + strconv.Itoa(op.BoardID) + " AND `parentid` = " + strconv.Itoa(op.ID) + " AND `deleted_timestamp` = '" + nil_timestamp + "' ORDER BY `id` ASC")
//replies, err = getPostArr("SELECT * FROM " + config.DBprefix + "posts WHERE `boardid` = " + strconv.Itoa(op.BoardID) + " AND `parentid` = " + strconv.Itoa(op.ID) + " AND `deleted_timestamp` = '" + nil_timestamp + "' ORDER BY `id` ASC")
replies, err = getPostArr(map[string]interface{}{
"boardid": op.BoardID,
"parentid": op.ID,
"deleted_timestamp": nil_timestamp,
}, "ORDER BY `ID` ASC")
if err != nil {
errortext = "Error building thread " + strconv.Itoa(op.ID) + ":" + err.Error()
html += errortext
@ -994,11 +1035,11 @@ func makePost(w http.ResponseWriter, r *http.Request, data interface{}) {
}
post.FilenameOriginal = escapeString(post.FilenameOriginal)
post.Filename = getNewFilename() + "." + getFileExtension(post.FilenameOriginal)
board_arr, _ := getBoardArr("`id` = " + request.FormValue("boardid"))
board_arr, _ := getBoardArr(map[string]interface{}{"id": request.FormValue("boardid")}, "") // getBoardArr("`id` = " + request.FormValue("boardid"))
if len(board_arr) == 0 {
serveErrorPage(w, "No boards have been created yet")
}
_board_dir, _ := getBoardArr("`id` = " + request.FormValue("boardid"))
_board_dir, _ := getBoardArr(map[string]interface{}{"id": request.FormValue("boardid")}, "") // getBoardArr("`id` = " + request.FormValue("boardid"))
board_dir := _board_dir[0].Dir
file_path := path.Join(config.DocumentRoot, "/"+board_dir+"/src/", post.Filename)
thumb_path := path.Join(config.DocumentRoot, "/"+board_dir+"/thumb/", strings.Replace(post.Filename, "."+filetype, "t."+thumb_filetype, -1))
@ -1143,7 +1184,7 @@ func makePost(w http.ResponseWriter, r *http.Request, data interface{}) {
postid, _ := result.LastInsertId()
post.ID = int(postid)
boards, _ := getBoardArr("")
boards, _ := getBoardArr(nil, "")
// rebuild the board page
buildBoards(false, post.BoardID)

View file

@ -268,7 +268,7 @@ func utilHandler(writer http.ResponseWriter, request *http.Request, data interfa
if parentId == 0 {
err = os.Remove(path.Join(config.DocumentRoot, board, "/res/"+post+".html"))
} else {
_board, _ := getBoardArr("`id` = " + strconv.Itoa(boardId))
_board, _ := getBoardArr(map[string]interface{}{"id": boardId}, "") // getBoardArr("`id` = " + strconv.Itoa(boardId))
buildBoardPages(&_board[0])
}

View file

@ -90,16 +90,41 @@ func deleteMatchingFiles(root, match string) (filesDeleted int, err error) {
// getBoardArr performs a query against the database, and returns an array of BoardsTables along with an error value.
// If specified, the string where is added to the query, prefaced by WHERE. An example valid value is where = "id = 1".
func getBoardArr(where string) (boards []BoardsTable, err error) {
if where == "" {
where = "1"
//func getBoardArr(where string) (boards []BoardsTable, err error) {
func getBoardArr(parameterList map[string]interface{}, extra string) (boards []BoardsTable, err error) {
queryString := "SELECT * FROM `" + config.DBprefix + "boards` "
numKeys := len(parameterList)
var parameterValues []interface{}
if numKeys > 0 {
queryString += "WHERE "
}
rows, err := db.Query("SELECT * FROM `" + config.DBprefix + "boards` WHERE " + where + " ORDER BY `order`;")
for key, value := range parameterList {
queryString += fmt.Sprintf("`%s` = ? AND ", key)
parameterValues = append(parameterValues, value)
}
// Find and remove any trailing instances of "AND "
if numKeys > 0 {
queryString = queryString[:len(queryString)-4]
}
queryString += fmt.Sprintf(" %s ORDER BY `order`", extra)
printf(1, "queryString@getBoardArr: %s\n", queryString)
stmt, err := db.Prepare(queryString)
defer func() {
if stmt != nil {
stmt.Close()
}
}()
if err != nil {
error_log.Print(err.Error())
return
}
rows, err := stmt.Query(parameterValues...)
// For each row in the results from the database, populate a new BoardsTable instance,
// then append it to the boards array we are going to return
for rows.Next() {
@ -143,12 +168,47 @@ func getBoardArr(where string) (boards []BoardsTable, err error) {
return
}
func getPostArr(sql string) (posts []interface{}, err error) {
rows, err := db.Query(sql)
// if parameterList is nil, ignore it and treat extra like a whole SQL query
func getPostArr(parameterList map[string]interface{}, extra string) (posts []interface{}, err error) {
queryString := "SELECT * FROM `" + config.DBprefix + "posts` "
numKeys := len(parameterList)
var parameterValues []interface{}
if numKeys > 0 {
queryString += "WHERE "
}
for key, value := range parameterList {
queryString += fmt.Sprintf("`%s` = ? AND ", key)
parameterValues = append(parameterValues, value)
}
// Find and remove any trailing instances of "AND "
if numKeys > 0 {
queryString = queryString[:len(queryString)-4]
}
queryString += " " + extra // " ORDER BY `order`"
printf(1, "queryString@getPostArr queryString: %s\n", queryString)
stmt, err := db.Prepare(queryString)
defer func() {
if stmt != nil {
stmt.Close()
}
}()
if err != nil {
error_log.Print(err.Error())
return
}
rows, err := stmt.Query(parameterValues...)
if err != nil {
error_log.Print(err.Error())
return
}
// For each row in the results from the database, populate a new PostTable instance,
// then append it to the posts array we are going to return
for rows.Next() {
var post PostTable
err = rows.Scan(&post.ID, &post.BoardID, &post.ParentID, &post.Name, &post.Tripcode,
@ -157,11 +217,14 @@ func getPostArr(sql string) (posts []interface{}, err error) {
&post.ImageH, &post.ThumbW, &post.ThumbH, &post.IP, &post.Tag, &post.Timestamp,
&post.Autosage, &post.PosterAuthority, &post.DeletedTimestamp, &post.Bumped,
&post.Stickied, &post.Locked, &post.Reviewed, &post.Sillytag)
post.IName = "post"
if err != nil {
error_log.Print("util.go:getPostArr() ERROR: " + err.Error())
error_log.Print(err.Error())
fmt.Println(err.Error())
return
} else {
posts = append(posts, post)
}
posts = append(posts, post)
}
return
}
@ -284,7 +347,7 @@ func resetBoardSectionArrays() {
all_boards = nil
all_sections = nil
all_boards_a, _ := getBoardArr("")
all_boards_a, _ := getBoardArr(nil, "")
for _, b := range all_boards_a {
all_boards = append(all_boards, b)
}
@ -295,9 +358,8 @@ func resetBoardSectionArrays() {
}
func searchStrings(item string, arr []string, permissive bool) int {
var length = len(arr)
for i := 0; i < length; i++ {
if item == arr[i] {
for i, str := range arr {
if item == str {
return i
}
}