mirror of
https://github.com/Eggbertx/gochan.git
synced 2025-08-24 08:46:24 -07:00
streamline row/stmt/file closing and error handling/printing
This commit is contained in:
parent
f39f55eda6
commit
9986bc8a6f
11 changed files with 490 additions and 666 deletions
214
src/manage.go
214
src/manage.go
|
@ -28,20 +28,19 @@ func callManageFunction(w http.ResponseWriter, r *http.Request, data interface{}
|
|||
staffRank := getStaffRank()
|
||||
var managePageBuffer bytes.Buffer
|
||||
mangePageHTML := ""
|
||||
var err error
|
||||
|
||||
if action == "" {
|
||||
action = "announcements"
|
||||
}
|
||||
|
||||
err := global_header_tmpl.Execute(&managePageBuffer, config)
|
||||
if err != nil {
|
||||
if err = global_header_tmpl.Execute(&managePageBuffer, config); err != nil {
|
||||
fmt.Fprintf(writer, mangePageHTML+err.Error()+"\n</body>\n</html>")
|
||||
return
|
||||
}
|
||||
|
||||
err = manage_header_tmpl.Execute(&managePageBuffer, config)
|
||||
if err != nil {
|
||||
fmt.Println(mangePageHTML)
|
||||
if err = manage_header_tmpl.Execute(&managePageBuffer, config); err != nil {
|
||||
println(0, mangePageHTML)
|
||||
fmt.Fprintf(writer, mangePageHTML+err.Error()+"\n</body>\n</html>")
|
||||
return
|
||||
}
|
||||
|
@ -79,8 +78,7 @@ func getCurrentStaff() (string, error) {
|
|||
row := db.QueryRow("SELECT `data` FROM `" + config.DBprefix + "sessions` WHERE `key` = '" + key + "'")
|
||||
current_session := new(SessionsTable)
|
||||
|
||||
err := row.Scan(¤t_session.Data)
|
||||
if err != nil {
|
||||
if err := row.Scan(¤t_session.Data); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return current_session.Data, nil
|
||||
|
@ -104,7 +102,7 @@ func getStaffRank() int {
|
|||
|
||||
staff, err := getStaff(staffname)
|
||||
if err != nil {
|
||||
errorLog.Print(err.Error())
|
||||
handleError(1, err.Error())
|
||||
return 0
|
||||
}
|
||||
return staff.Rank
|
||||
|
@ -123,8 +121,7 @@ func createSession(key string, username string, password string, request *http.R
|
|||
}
|
||||
staff, err := getStaff(username)
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
errorLog.Print(err.Error())
|
||||
handleError(1, err.Error())
|
||||
return 1
|
||||
} else {
|
||||
success := bcrypt.CompareHashAndPassword([]byte(staff.PasswordChecksum), []byte(password))
|
||||
|
@ -138,12 +135,12 @@ func createSession(key string, username string, password string, request *http.R
|
|||
http.SetCookie(*writer, cookie)
|
||||
_, err := db.Exec("INSERT INTO `" + config.DBprefix + "sessions` (`key`, `data`, `expires`) VALUES('" + key + "','" + username + "', '" + getSpecificSQLDateTime(time.Now().Add(time.Duration(time.Hour*730))) + "')")
|
||||
if err != nil {
|
||||
errorLog.Print(err.Error())
|
||||
handleError(1, err.Error())
|
||||
return 2
|
||||
}
|
||||
_, err = db.Exec("UPDATE `" + config.DBprefix + "staff` SET `last_active` ='" + getSQLDateTime() + "' WHERE `username` = '" + username + "';")
|
||||
if err != nil {
|
||||
errorLog.Print(err.Error())
|
||||
handleError(1, err.Error())
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
@ -177,7 +174,7 @@ var manage_functions = map[string]ManageFunction{
|
|||
tableRows.Scan(&table)
|
||||
_, err = db.Exec("OPTIMIZE TABLE " + table)
|
||||
if err != nil {
|
||||
html += err.Error()
|
||||
html += handleError(1, err.Error()) + "<br />"
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -209,9 +206,8 @@ var manage_functions = map[string]ManageFunction{
|
|||
}
|
||||
manageConfigBuffer := bytes.NewBufferString("")
|
||||
|
||||
err := renderTemplate(manage_config_tmpl, "manage_config", manageConfigBuffer)
|
||||
if err != nil {
|
||||
html += err.Error()
|
||||
if err := renderTemplate(manage_config_tmpl, "manage_config", manageConfigBuffer); err != nil {
|
||||
html += handleError(1, err.Error())
|
||||
return
|
||||
}
|
||||
html += manageConfigBuffer.String()
|
||||
|
@ -223,40 +219,34 @@ var manage_functions = map[string]ManageFunction{
|
|||
html = "<img src=\"/css/purge.jpg\" />"
|
||||
rows, err := db.Query("SELECT `dir` FROM `" + config.DBprefix + "boards`")
|
||||
if err != nil {
|
||||
html += err.Error()
|
||||
html += handleError(1, err.Error())
|
||||
return
|
||||
}
|
||||
var board string
|
||||
for rows.Next() {
|
||||
err = rows.Scan(&board)
|
||||
if err != nil {
|
||||
html += err.Error()
|
||||
if err = rows.Scan(&board); err != nil {
|
||||
html += handleError(1, err.Error())
|
||||
return
|
||||
}
|
||||
_, err = deleteMatchingFiles(path.Join(config.DocumentRoot, board), ".html")
|
||||
if err != nil {
|
||||
html += err.Error()
|
||||
if _, err = deleteMatchingFiles(path.Join(config.DocumentRoot, board), ".html"); err != nil {
|
||||
html += handleError(1, err.Error())
|
||||
return
|
||||
}
|
||||
_, err = deleteMatchingFiles(path.Join(config.DocumentRoot, board, "res"), ".*")
|
||||
if err != nil {
|
||||
html += err.Error()
|
||||
if _, err = deleteMatchingFiles(path.Join(config.DocumentRoot, board, "res"), ".*"); err != nil {
|
||||
html += handleError(1, err.Error())
|
||||
return
|
||||
}
|
||||
_, err = deleteMatchingFiles(path.Join(config.DocumentRoot, board, "src"), ".*")
|
||||
if err != nil {
|
||||
html += err.Error()
|
||||
if _, err = deleteMatchingFiles(path.Join(config.DocumentRoot, board, "src"), ".*"); err != nil {
|
||||
html += handleError(1, err.Error())
|
||||
return
|
||||
}
|
||||
_, err = deleteMatchingFiles(path.Join(config.DocumentRoot, board, "thumb"), ".*")
|
||||
if err != nil {
|
||||
html += err.Error()
|
||||
if _, err = deleteMatchingFiles(path.Join(config.DocumentRoot, board, "thumb"), ".*"); err != nil {
|
||||
html += handleError(1, err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
_, err = db.Exec("TRUNCATE `" + config.DBprefix + "posts`")
|
||||
if err != nil {
|
||||
html += err.Error() + "<br />"
|
||||
if _, err = db.Exec("TRUNCATE `" + config.DBprefix + "posts`"); err != nil {
|
||||
html += handleError(1, err.Error()) + "<br />"
|
||||
return
|
||||
}
|
||||
db.Exec("ALTER TABLE `" + config.DBprefix + "posts` AUTO_INCREMENT = 1")
|
||||
|
@ -277,9 +267,7 @@ var manage_functions = map[string]ManageFunction{
|
|||
println(1, &result)
|
||||
|
||||
if sqlerr != nil {
|
||||
errortext := sqlerr.Error()
|
||||
html += errortext
|
||||
println(1, errortext)
|
||||
html += handleError(1, sqlerr.Error())
|
||||
} else {
|
||||
html += "Statement esecuted successfully."
|
||||
}
|
||||
|
@ -345,8 +333,7 @@ var manage_functions = map[string]ManageFunction{
|
|||
|
||||
rows, err := db.Query("SELECT `subject`,`message`,`poster`,`timestamp` FROM `" + config.DBprefix + "announcements` ORDER BY `id` DESC;")
|
||||
if err != nil {
|
||||
errorLog.Print(err.Error())
|
||||
html += err.Error()
|
||||
html += handleError(1, err.Error())
|
||||
return
|
||||
}
|
||||
iterations := 0
|
||||
|
@ -354,7 +341,7 @@ var manage_functions = map[string]ManageFunction{
|
|||
announcement := new(AnnouncementsTable)
|
||||
err = rows.Scan(&announcement.Subject, &announcement.Message, &announcement.Poster, &announcement.Timestamp)
|
||||
if err != nil {
|
||||
html += err.Error()
|
||||
html += handleError(1, err.Error())
|
||||
} else {
|
||||
html += "<div class=\"section-block\">\n" +
|
||||
"<div class=\"section-title-block\"><b>" + announcement.Subject + "</b> by " + announcement.Poster + " at " + humanReadableTime(announcement.Timestamp) + "</div>\n" +
|
||||
|
@ -381,14 +368,13 @@ var manage_functions = map[string]ManageFunction{
|
|||
ban_which = "both"
|
||||
}
|
||||
// if none of these are true, we can assume that the page was loaded without sending anything
|
||||
fmt.Println(ban_which)
|
||||
println(0, "ban_which"+ban_which)
|
||||
|
||||
if ban_which == "user" {
|
||||
//var banned_tripcode string
|
||||
banned_ip := request.PostFormValue("ip")
|
||||
|
||||
if banned_ip != "" {
|
||||
fmt.Println(banned_ip)
|
||||
println(0, banned_ip)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -397,14 +383,13 @@ var manage_functions = map[string]ManageFunction{
|
|||
|
||||
rows, err := db.Query("SELECT `dir` FROM `" + config.DBprefix + "boards`;")
|
||||
if err != nil {
|
||||
html += "<hr />" + err.Error()
|
||||
html += "<hr />" + handleError(1, err.Error())
|
||||
return
|
||||
}
|
||||
var board_dir string
|
||||
for rows.Next() {
|
||||
err = rows.Scan(&board_dir)
|
||||
if err != nil {
|
||||
html += "<hr />" + err.Error()
|
||||
if err = rows.Scan(&board_dir); err != nil {
|
||||
html += "<hr />" + handleError(1, err.Error())
|
||||
}
|
||||
boards_list_html += " <label>/" + board_dir + "/ <input type=\"checkbox\" id=\"" + board_dir + "\" class=\"board-check\"/></label> \n"
|
||||
}
|
||||
|
@ -450,8 +435,7 @@ var manage_functions = map[string]ManageFunction{
|
|||
|
||||
rows, err = db.Query("SELECT * FROM `" + config.DBprefix + "banlist`")
|
||||
if err != nil {
|
||||
html += "</table><br />" + err.Error()
|
||||
errorLog.Print(err.Error())
|
||||
html += "</table><br />" + handleError(1, err.Error())
|
||||
return
|
||||
}
|
||||
var ban BanlistTable
|
||||
|
@ -459,14 +443,12 @@ var manage_functions = map[string]ManageFunction{
|
|||
num_rows := 0
|
||||
for rows.Next() {
|
||||
if num_rows == 0 {
|
||||
|
||||
html += "<table width=\"100%%\" border=\"1\">\n" +
|
||||
"<tr><th>IP</th><th>Name/Tripcode</th><th>Message</th><th>Date added</th><th>Added by</th><th>Reason</th><th>Expires/expired</th><th></th></tr>"
|
||||
}
|
||||
err = rows.Scan(&ban.ID, &ban.AllowRead, &ban.IP, &ban.Name, &ban.Tripcode, &ban.Message, &ban.SilentBan, &ban.Boards, &ban.BannedBy, &ban.Timestamp, &ban.Expires, &ban.Reason, &ban.StaffNote, &ban.AppealMessage, &ban.AppealAt)
|
||||
if err != nil {
|
||||
html += "</table><br />" + err.Error()
|
||||
errorLog.Print(err.Error())
|
||||
html += "</table><br />" + handleError(1, err.Error())
|
||||
return
|
||||
}
|
||||
ban_name := ""
|
||||
|
@ -475,7 +457,7 @@ var manage_functions = map[string]ManageFunction{
|
|||
}
|
||||
|
||||
html += "<tr><td>" + ban.IP + "</td><td>" + ban_name + "</td><td>" + ban.Message + "</td><td>" + humanReadableTime(ban.Timestamp) + "</td><td>" + ban.BannedBy + "</td><td>" + ban.Reason + "</td><td>" + humanReadableTime(ban.Expires) + "</td><td>Delete</td></tr>"
|
||||
num_rows += 1
|
||||
num_rows++
|
||||
}
|
||||
if num_rows == 0 {
|
||||
html += "No banned IPs"
|
||||
|
@ -504,11 +486,8 @@ var manage_functions = map[string]ManageFunction{
|
|||
}
|
||||
row := db.QueryRow("SELECT `rank`,`boards` FROM `" + config.DBprefix + "staff` WHERE `username` = '" + current_staff + "'")
|
||||
staff := new(StaffTable)
|
||||
err = row.Scan(&staff.Rank, &staff.Boards)
|
||||
if err != nil {
|
||||
errorLog.Print("Error getting staff list: " + err.Error())
|
||||
println(1, "Error getting staff list: "+err.Error())
|
||||
html += err.Error()
|
||||
if err = row.Scan(&staff.Rank, &staff.Boards); err != nil {
|
||||
html += handleError(1, "Error getting staff list: "+err.Error())
|
||||
return
|
||||
}
|
||||
html = current_staff + ";" + strconv.Itoa(staff.Rank) + ";" + staff.Boards
|
||||
|
@ -599,31 +578,27 @@ var manage_functions = map[string]ManageFunction{
|
|||
board.EnableCatalog = (request.FormValue("enablecatalog") == "on")
|
||||
|
||||
//actually start generating stuff
|
||||
err = os.Mkdir(path.Join(config.DocumentRoot, board.Dir), 0777)
|
||||
if err != nil {
|
||||
if err = os.Mkdir(path.Join(config.DocumentRoot, board.Dir), 0777); err != nil {
|
||||
do = ""
|
||||
board_creation_status = "ERROR: directory /" + config.DocumentRoot + "/" + board.Dir + "/ already exists!"
|
||||
board_creation_status = handleError(1, "ERROR: directory /"+config.DocumentRoot+"/"+board.Dir+"/ already exists!")
|
||||
break
|
||||
}
|
||||
|
||||
err = os.Mkdir(path.Join(config.DocumentRoot, board.Dir, "res"), 0777)
|
||||
if err != nil {
|
||||
if err = os.Mkdir(path.Join(config.DocumentRoot, board.Dir, "res"), 0777); err != nil {
|
||||
do = ""
|
||||
board_creation_status = "ERROR: directory /" + config.DocumentRoot + "/" + board.Dir + "/res/ already exists!"
|
||||
board_creation_status = handleError(1, "ERROR: directory /"+config.DocumentRoot+"/"+board.Dir+"/res/ already exists!")
|
||||
break
|
||||
}
|
||||
|
||||
err = os.Mkdir(path.Join(config.DocumentRoot, board.Dir, "thumb"), 0777)
|
||||
if err != nil {
|
||||
if err = os.Mkdir(path.Join(config.DocumentRoot, board.Dir, "thumb"), 0777); err != nil {
|
||||
do = ""
|
||||
board_creation_status = "ERROR: directory /" + config.DocumentRoot + "/" + board.Dir + "/thumb/ already exists!"
|
||||
board_creation_status = handleError(1, "ERROR: directory /"+config.DocumentRoot+"/"+board.Dir+"/thumb/ already exists!")
|
||||
break
|
||||
}
|
||||
|
||||
err = os.Mkdir(path.Join(config.DocumentRoot, board.Dir, "src"), 0777)
|
||||
if err != nil {
|
||||
if err = os.Mkdir(path.Join(config.DocumentRoot, board.Dir, "src"), 0777); err != nil {
|
||||
do = ""
|
||||
board_creation_status = "ERROR: directory /" + config.DocumentRoot + "/" + board.Dir + "/src/ already exists!"
|
||||
board_creation_status = handleError(1, "ERROR: directory /"+config.DocumentRoot+"/"+board.Dir+"/src/ already exists!")
|
||||
break
|
||||
}
|
||||
stmt, err := db.Prepare(
|
||||
|
@ -632,21 +607,16 @@ var manage_functions = map[string]ManageFunction{
|
|||
"`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()
|
||||
board_creation_status = handleError(1, err.Error())
|
||||
break
|
||||
}
|
||||
defer closeStatement(stmt)
|
||||
|
||||
boardCreationTimestamp := getSpecificSQLDateTime(board.CreatedOn)
|
||||
|
||||
_, err = stmt.Exec(
|
||||
if _, 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,
|
||||
|
@ -654,18 +624,17 @@ var manage_functions = map[string]ManageFunction{
|
|||
&board.ForcedAnon, &board.MaxAge, &board.AutosageAfter,
|
||||
&board.NoImagesAfter, &board.MaxMessageLength, &board.EmbedsAllowed,
|
||||
&board.RedirectToThread, &board.RequireFile, &board.EnableCatalog,
|
||||
)
|
||||
if err != nil {
|
||||
); err != nil {
|
||||
do = ""
|
||||
board_creation_status = err.Error()
|
||||
println(1, "Error creating board: "+board_creation_status)
|
||||
handleError(1, "Error creating board: "+board_creation_status)
|
||||
break
|
||||
} else {
|
||||
board_creation_status = "Board created successfully"
|
||||
println(1, board_creation_status)
|
||||
println(2, board_creation_status)
|
||||
buildBoards(true, 0)
|
||||
resetBoardSectionArrays()
|
||||
println(1, "Boards rebuilt successfully")
|
||||
println(2, "Boards rebuilt successfully")
|
||||
done = true
|
||||
break
|
||||
}
|
||||
|
@ -677,17 +646,10 @@ var manage_functions = map[string]ManageFunction{
|
|||
default:
|
||||
// put the default column values in the text boxes
|
||||
rows, err = db.Query("SELECT `column_name`,`column_default` FROM `information_schema`.`columns` WHERE `table_name` = '" + config.DBprefix + "boards'")
|
||||
defer func() {
|
||||
if rows != nil {
|
||||
rows.Close()
|
||||
}
|
||||
}()
|
||||
if err != nil {
|
||||
html += err.Error()
|
||||
println(1, "Error getting column names from boards table:"+err.Error())
|
||||
html += handleError(1, "Error getting column names from boards table:"+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
for rows.Next() {
|
||||
var column_name string
|
||||
var column_default string
|
||||
|
@ -750,14 +712,17 @@ var manage_functions = map[string]ManageFunction{
|
|||
html = "<h1>Manage boards</h1>\n<form action=\"/manage?action=boards\" method=\"POST\">\n<input type=\"hidden\" name=\"do\" value=\"existing\" /><select name=\"boardselect\">\n<option>Select board...</option>\n"
|
||||
rows, err = db.Query("SELECT `dir` FROM `" + config.DBprefix + "boards`;")
|
||||
if err != nil {
|
||||
html += err.Error()
|
||||
html += handleError(1, err.Error())
|
||||
return
|
||||
}
|
||||
var board_dir string
|
||||
defer closeRows(rows)
|
||||
|
||||
for rows.Next() {
|
||||
var board_dir string
|
||||
rows.Scan(&board_dir)
|
||||
html += "<option>" + board_dir + "</option>\n"
|
||||
}
|
||||
|
||||
html += "</select> <input type=\"submit\" value=\"Edit\" /> <input type=\"submit\" value=\"Delete\" /></form><hr />" +
|
||||
"<h2>Create new board</h2>\n<span id=\"board-creation-message\">" + board_creation_status + "</span><br />"
|
||||
|
||||
|
@ -768,12 +733,11 @@ var manage_functions = map[string]ManageFunction{
|
|||
}
|
||||
all_sections, _ = getSectionArr("")
|
||||
|
||||
err := renderTemplate(manage_boards_tmpl, "manage_boards", manageBoardsBuffer,
|
||||
if err := renderTemplate(manage_boards_tmpl, "manage_boards", manageBoardsBuffer,
|
||||
&Wrapper{IName: "board", Data: []interface{}{board}},
|
||||
&Wrapper{IName: "section_arr", Data: all_sections},
|
||||
)
|
||||
if err != nil {
|
||||
html += err.Error()
|
||||
); err != nil {
|
||||
html += handleError(1, err.Error())
|
||||
return
|
||||
}
|
||||
html += manageBoardsBuffer.String()
|
||||
|
@ -810,7 +774,6 @@ var manage_functions = map[string]ManageFunction{
|
|||
"<a href=\"javascript:void(0)\" id=\"recentposts\" class=\"staffmenu-item\">Recent posts</a><br />\n" +
|
||||
"<a href=\"javascript:void(0)\" id=\"searchip\" class=\"staffmenu-item\">Search posts by IP</a><br />\n"
|
||||
}
|
||||
|
||||
return
|
||||
}},
|
||||
"rebuildfront": {
|
||||
|
@ -848,14 +811,11 @@ var manage_functions = map[string]ManageFunction{
|
|||
post := postInter.(PostTable)
|
||||
stmt, err := db.Prepare("UPDATE `" + config.DBprefix + "posts` SET `message` = ? WHERE `id` = ? AND `boardid` = ?")
|
||||
if err != nil {
|
||||
html += err.Error() + "<br />"
|
||||
html += handleError(1, err.Error()) + "<br />"
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
if stmt != nil {
|
||||
stmt.Close()
|
||||
}
|
||||
}()
|
||||
defer closeStatement(stmt)
|
||||
|
||||
stmt.Exec(formatMessage(post.MessageText), post.ID, post.BoardID)
|
||||
}
|
||||
html += "Done reparsing HTML<hr />" +
|
||||
|
@ -889,16 +849,18 @@ var manage_functions = map[string]ManageFunction{
|
|||
"AND `boardid` = `" + config.DBprefix + "boards`.`id` " +
|
||||
"ORDER BY `timestamp` DESC LIMIT " + limit + ";")
|
||||
if err != nil {
|
||||
html += "<tr><td>" + err.Error() + "</td></tr></table>"
|
||||
html += "<tr><td>" + handleError(1, err.Error()) + "</td></tr></table>"
|
||||
return
|
||||
}
|
||||
defer closeRows(rows)
|
||||
|
||||
for rows.Next() {
|
||||
recentpost := new(RecentPost)
|
||||
err = rows.Scan(&recentpost.BoardName, &recentpost.BoardID, &recentpost.PostID, &recentpost.ParentID, &recentpost.Message, &recentpost.IP, &recentpost.Timestamp)
|
||||
if err != nil {
|
||||
errorLog.Print(err.Error())
|
||||
return err.Error()
|
||||
if err = rows.Scan(&recentpost.BoardName, &recentpost.BoardID,
|
||||
&recentpost.PostID, &recentpost.ParentID, &recentpost.Message,
|
||||
&recentpost.IP, &recentpost.Timestamp,
|
||||
); err != nil {
|
||||
return handleError(1, err.Error())
|
||||
}
|
||||
html += "<tr><td><b>Post:</b> <a href=\"" + path.Join(config.SiteWebfolder, recentpost.BoardName, "/res/", strconv.Itoa(recentpost.ParentID)+".html#"+strconv.Itoa(recentpost.PostID)) + "\">" + recentpost.BoardName + "/" + strconv.Itoa(recentpost.PostID) + "</a><br /><b>IP:</b> " + recentpost.IP + "</td><td>" + recentpost.Message + "</td><td>" + recentpost.Timestamp.Format("01/02/06, 15:04") + "</td></tr>"
|
||||
}
|
||||
|
@ -920,16 +882,16 @@ var manage_functions = map[string]ManageFunction{
|
|||
"<tr><td><b>Username</b></td><td><b>Rank</b></td><td><b>Boards</b></td><td><b>Added on</b></td><td><b>Action</b></td></tr>\n"
|
||||
rows, err := db.Query("SELECT `username`,`rank`,`boards`,`added_on` FROM `" + config.DBprefix + "staff`;")
|
||||
if err != nil {
|
||||
html += "<tr><td>" + err.Error() + "</td></tr></table>"
|
||||
html += "<tr><td>" + handleError(1, err.Error()) + "</td></tr></table>"
|
||||
return
|
||||
}
|
||||
defer closeRows(rows)
|
||||
|
||||
iter := 1
|
||||
for rows.Next() {
|
||||
staff := new(StaffTable)
|
||||
err = rows.Scan(&staff.Username, &staff.Rank, &staff.Boards, &staff.AddedOn)
|
||||
if err != nil {
|
||||
errorLog.Print(err.Error())
|
||||
if err = rows.Scan(&staff.Username, &staff.Rank, &staff.Boards, &staff.AddedOn); err != nil {
|
||||
handleError(1, err.Error())
|
||||
return err.Error()
|
||||
}
|
||||
|
||||
|
@ -938,30 +900,22 @@ var manage_functions = map[string]ManageFunction{
|
|||
new_password := request.FormValue("password")
|
||||
new_rank := request.FormValue("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())
|
||||
serveErrorPage(writer, handleError(1, err.Error()))
|
||||
}
|
||||
defer closeStatement(stmt)
|
||||
|
||||
_, err = stmt.Exec(&new_username, bcryptSum(new_password), &new_rank)
|
||||
if err != nil {
|
||||
serveErrorPage(writer, err.Error())
|
||||
if _, err = stmt.Exec(&new_username, bcryptSum(new_password), &new_rank); err != nil {
|
||||
serveErrorPage(writer, handleError(1, err.Error()))
|
||||
}
|
||||
|
||||
} else if request.FormValue("do") == "del" && 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())
|
||||
serveErrorPage(writer, handleError(1, err.Error()))
|
||||
}
|
||||
defer closeStatement(stmt)
|
||||
|
||||
_, err = stmt.Exec(request.FormValue("username"))
|
||||
}
|
||||
|
||||
|
@ -975,7 +929,7 @@ var manage_functions = map[string]ManageFunction{
|
|||
rank = "janitor"
|
||||
}
|
||||
html += "<tr><td>" + staff.Username + "</td><td>" + rank + "</td><td>" + staff.Boards + "</td><td>" + humanReadableTime(staff.AddedOn) + "</td><td><a href=\"/manage?action=staff&do=del&username=" + staff.Username + "\" style=\"float:right;color:red;\">X</a></td></tr>\n"
|
||||
iter += 1
|
||||
iter++
|
||||
}
|
||||
html += "</table>\n\n<hr />\n<h2>Add new staff</h2>\n\n" +
|
||||
"<form action=\"/manage?action=staff\" onsubmit=\"return makeNewStaff();\" method=\"POST\">\n" +
|
||||
|
|
400
src/posting.go
400
src/posting.go
|
@ -133,13 +133,9 @@ func buildBoardPages(board *BoardsTable) (html string) {
|
|||
if err != nil {
|
||||
html += err.Error() + "<br />\n"
|
||||
}
|
||||
defer func() {
|
||||
if stmt != nil {
|
||||
stmt.Close()
|
||||
}
|
||||
}()
|
||||
err = stmt.QueryRow(board.ID, op_post.ID, nil_timestamp).Scan(&thread.NumReplies)
|
||||
if err != nil {
|
||||
defer closeStatement(stmt)
|
||||
|
||||
if err = stmt.QueryRow(board.ID, op_post.ID, nil_timestamp).Scan(&thread.NumReplies); err != nil {
|
||||
html += err.Error() + "<br />\n"
|
||||
}
|
||||
|
||||
|
@ -148,8 +144,7 @@ func buildBoardPages(board *BoardsTable) (html string) {
|
|||
if err != nil {
|
||||
html += err.Error() + "<br />\n"
|
||||
}
|
||||
err = stmt.QueryRow(board.ID, op_post.ID, nil_timestamp).Scan(&thread.NumImages)
|
||||
if err != nil {
|
||||
if err = stmt.QueryRow(board.ID, op_post.ID, nil_timestamp).Scan(&thread.NumImages); err != nil {
|
||||
html += err.Error() + "<br />\n"
|
||||
}
|
||||
|
||||
|
@ -204,6 +199,7 @@ func buildBoardPages(board *BoardsTable) (html string) {
|
|||
printf(2, "Number of files deleted: %d\n", num)
|
||||
// Order the threads, stickied threads first, then nonstickied threads.
|
||||
threads = append(stickied_threads, nonstickied_threads...)
|
||||
|
||||
// If there are no posts on the board
|
||||
if len(threads) == 0 {
|
||||
board.CurrentPage = 0
|
||||
|
@ -222,19 +218,43 @@ func buildBoardPages(board *BoardsTable) (html string) {
|
|||
|
||||
// Render board page template to the file,
|
||||
// packaging the board/section list, threads, and board info
|
||||
err = renderTemplate(img_boardpage_tmpl, "boardpage", board_page_file,
|
||||
if err = renderTemplate(img_header_tmpl, "img_header", board_page_file,
|
||||
&Wrapper{IName: "boards_", Data: all_boards},
|
||||
&Wrapper{IName: "sections_w", Data: all_sections},
|
||||
&Wrapper{IName: "posts_w", Data: []interface{}{
|
||||
PostTable{BoardID: board.ID},
|
||||
}},
|
||||
&Wrapper{IName: "op", Data: []interface{}{PostTable{}}},
|
||||
&Wrapper{IName: "board", Data: []interface{}{board}},
|
||||
); err != nil {
|
||||
errortext = fmt.Sprintf("Failed building /%s/res/%d.html: %s", board.Dir, 0, err.Error())
|
||||
html += errortext + "<br />\n"
|
||||
println(1, errortext)
|
||||
errorLog.Print(errortext)
|
||||
return
|
||||
}
|
||||
|
||||
if err = renderTemplate(img_boardpage_tmpl, "boardpage", board_page_file,
|
||||
&Wrapper{IName: "boards", Data: all_boards},
|
||||
&Wrapper{IName: "sections", Data: all_sections},
|
||||
&Wrapper{IName: "threads", Data: threads},
|
||||
&Wrapper{IName: "boardinfo", Data: boardinfo_i},
|
||||
)
|
||||
if err != nil {
|
||||
); err != nil {
|
||||
errortext = "Failed building /" + board.Dir + "/: " + err.Error()
|
||||
html += errortext + "<br />\n"
|
||||
errorLog.Print(errortext)
|
||||
println(1, errortext)
|
||||
return
|
||||
}
|
||||
|
||||
if err = renderTemplate(global_footer_tmpl, "global_footer", board_page_file); err != nil {
|
||||
errortext = "Failed building /" + board.Dir + "/: " + err.Error()
|
||||
html += errortext + "<br />\n"
|
||||
errorLog.Print(errortext)
|
||||
println(1, errortext)
|
||||
return
|
||||
}
|
||||
|
||||
html += "/" + board.Dir + "/ built successfully, no threads to build.\n"
|
||||
//benchmarkTimer("buildBoard"+strconv.Itoa(board.ID), start_time, false)
|
||||
return
|
||||
|
@ -248,12 +268,6 @@ func buildBoardPages(board *BoardsTable) (html string) {
|
|||
var pages_obj []BoardPageJSON
|
||||
|
||||
catalog_json_file, err := os.OpenFile(path.Join(config.DocumentRoot, board.Dir, "catalog.json"), os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0777)
|
||||
defer func() {
|
||||
if catalog_json_file != nil {
|
||||
catalog_json_file.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
if err != nil {
|
||||
errortext = "Failed opening /" + board.Dir + "/catalog.json: " + err.Error()
|
||||
html += errortext + "<br />\n"
|
||||
|
@ -261,6 +275,7 @@ func buildBoardPages(board *BoardsTable) (html string) {
|
|||
errorLog.Print(errortext)
|
||||
return
|
||||
}
|
||||
defer closeFile(catalog_json_file)
|
||||
|
||||
for page_num, page_threads := range thread_pages {
|
||||
// Package up board info for the template to use.
|
||||
|
@ -284,14 +299,38 @@ func buildBoardPages(board *BoardsTable) (html string) {
|
|||
println(1, errortext)
|
||||
continue
|
||||
}
|
||||
|
||||
// Render the boardpage template, given boards, sections, threads, and board info
|
||||
err = renderTemplate(img_boardpage_tmpl, "boardpage", current_page_file,
|
||||
if err = renderTemplate(img_header_tmpl, "img_header", current_page_file,
|
||||
&Wrapper{IName: "boards_", Data: all_boards},
|
||||
&Wrapper{IName: "sections_w", Data: all_sections},
|
||||
&Wrapper{IName: "posts_w", Data: []interface{}{
|
||||
PostTable{BoardID: board.ID},
|
||||
}},
|
||||
&Wrapper{IName: "op", Data: []interface{}{PostTable{}}},
|
||||
&Wrapper{IName: "board", Data: []interface{}{board}},
|
||||
); err != nil {
|
||||
errortext = fmt.Sprintf("Failed building /%s/res/%d.html: %s", board.Dir, 0, err.Error())
|
||||
html += errortext + "<br />\n"
|
||||
println(1, errortext)
|
||||
errorLog.Print(errortext)
|
||||
return
|
||||
}
|
||||
|
||||
if err = renderTemplate(img_boardpage_tmpl, "boardpage", current_page_file,
|
||||
&Wrapper{IName: "boards", Data: all_boards},
|
||||
&Wrapper{IName: "sections", Data: all_sections},
|
||||
&Wrapper{IName: "threads", Data: page_threads},
|
||||
&Wrapper{IName: "boardinfo", Data: boardinfo_i},
|
||||
)
|
||||
if err != nil {
|
||||
); err != nil {
|
||||
errortext = "Failed building /" + board.Dir + "/: " + err.Error()
|
||||
html += errortext + "<br />\n"
|
||||
errorLog.Print(errortext)
|
||||
println(1, errortext)
|
||||
return
|
||||
}
|
||||
|
||||
if err = renderTemplate(global_footer_tmpl, "global_footer", current_page_file); err != nil {
|
||||
errortext = "Failed building /" + board.Dir + "/: " + err.Error()
|
||||
html += errortext + "<br />\n"
|
||||
errorLog.Print(errortext)
|
||||
|
@ -334,7 +373,6 @@ func buildBoardPages(board *BoardsTable) (html string) {
|
|||
}
|
||||
|
||||
catalog_json, err := json.Marshal(pages_obj)
|
||||
|
||||
if err != nil {
|
||||
errortext = "Failed to marshal to JSON: " + err.Error()
|
||||
errorLog.Println(errortext)
|
||||
|
@ -343,19 +381,15 @@ func buildBoardPages(board *BoardsTable) (html string) {
|
|||
return
|
||||
}
|
||||
|
||||
_, err = catalog_json_file.Write(catalog_json)
|
||||
|
||||
if err != nil {
|
||||
if _, err = catalog_json_file.Write(catalog_json); err != nil {
|
||||
errortext = "Failed writing /" + board.Dir + "/catalog.json: " + err.Error()
|
||||
errorLog.Println(errortext)
|
||||
println(1, errortext)
|
||||
html += errortext + "<br />\n"
|
||||
return
|
||||
}
|
||||
|
||||
html += "/" + board.Dir + "/ built successfully.\n"
|
||||
}
|
||||
|
||||
//benchmarkTimer("buildBoard"+strconv.Itoa(board.ID), start_time, false)
|
||||
return
|
||||
}
|
||||
|
@ -411,8 +445,7 @@ func buildThreadPages(op *PostTable) (html string) {
|
|||
return
|
||||
}
|
||||
|
||||
err = stmt.QueryRow(op.BoardID).Scan(&boardDir, &anonymous)
|
||||
if err != nil {
|
||||
if err = stmt.QueryRow(op.BoardID).Scan(&boardDir, &anonymous); err != nil {
|
||||
errortext = "Failed getting board directory and board's anonymous setting from post: " + err.Error()
|
||||
html += errortext + "<br />\n"
|
||||
errorLog.Println(errortext)
|
||||
|
@ -458,14 +491,32 @@ func buildThreadPages(op *PostTable) (html string) {
|
|||
return
|
||||
}
|
||||
// render main page
|
||||
err = renderTemplate(img_threadpage_tmpl, "threadpage", current_page_file,
|
||||
if err = renderTemplate(img_header_tmpl, "img_header", current_page_file,
|
||||
&Wrapper{IName: "boards_", Data: all_boards},
|
||||
&Wrapper{IName: "sections_w", Data: all_sections},
|
||||
&Wrapper{IName: "posts_w", Data: append([]interface{}{op}, replies...)},
|
||||
)
|
||||
); err != nil {
|
||||
errortext = fmt.Sprintf("Failed building /%s/res/%d.html: %s", boardDir, op.ID, err.Error())
|
||||
html += errortext + "<br />\n"
|
||||
println(1, errortext)
|
||||
errorLog.Print(errortext)
|
||||
return
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
fmt.Sprintf("Failed building /%s/res/%d.html: %s", boardDir, op.ID, err.Error())
|
||||
if err = renderTemplate(img_threadpage_tmpl, "threadpage", current_page_file,
|
||||
&Wrapper{IName: "boards_", Data: all_boards},
|
||||
&Wrapper{IName: "sections_w", Data: all_sections},
|
||||
&Wrapper{IName: "posts_w", Data: append([]interface{}{op}, replies...)},
|
||||
); err != nil {
|
||||
errortext = fmt.Sprintf("Failed building /%s/res/%d.html: %s", boardDir, op.ID, err.Error())
|
||||
html += errortext + "<br />\n"
|
||||
println(1, errortext)
|
||||
errorLog.Print(errortext)
|
||||
return
|
||||
}
|
||||
|
||||
if err = renderTemplate(global_footer_tmpl, "global_footer", current_page_file); err != nil {
|
||||
errortext = fmt.Sprintf("Failed building /%s/res/%d.html: %s", boardDir, op.ID, err.Error())
|
||||
html += errortext + "<br />\n"
|
||||
println(1, errortext)
|
||||
errorLog.Print(errortext)
|
||||
|
@ -474,11 +525,6 @@ func buildThreadPages(op *PostTable) (html string) {
|
|||
|
||||
// Put together the thread JSON
|
||||
threadJSONFile, err := os.OpenFile(path.Join(config.DocumentRoot, boardDir, "res", strconv.Itoa(op.ID)+".json"), os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0777)
|
||||
defer func() {
|
||||
if threadJSONFile != nil {
|
||||
threadJSONFile.Close()
|
||||
}
|
||||
}()
|
||||
if err != nil {
|
||||
errortext = fmt.Sprintf("Failed opening /%s/res/%d.json: %s", boardDir, op.ID, err.Error())
|
||||
html += errortext + "<br />\n"
|
||||
|
@ -486,6 +532,8 @@ func buildThreadPages(op *PostTable) (html string) {
|
|||
errorLog.Print(errortext)
|
||||
return
|
||||
}
|
||||
defer closeFile(threadJSONFile)
|
||||
|
||||
// Create the wrapper object
|
||||
thread_json_wrapper := new(ThreadJSONWrapper)
|
||||
|
||||
|
@ -510,8 +558,7 @@ func buildThreadPages(op *PostTable) (html string) {
|
|||
return
|
||||
}
|
||||
|
||||
_, err = threadJSONFile.Write(threadJSON)
|
||||
if err != nil {
|
||||
if _, err = threadJSONFile.Write(threadJSON); err != nil {
|
||||
errortext = fmt.Sprintf("Failed writing /%s/res/%d.json: %s", boardDir, op.ID, err.Error())
|
||||
errorLog.Println(errortext)
|
||||
println(1, errortext)
|
||||
|
@ -525,35 +572,36 @@ func buildThreadPages(op *PostTable) (html string) {
|
|||
|
||||
for page_num, page_posts := range thread_pages {
|
||||
op.CurrentPage = page_num
|
||||
|
||||
current_page_filepath := path.Join(config.DocumentRoot, boardDir, "res", strconv.Itoa(op.ID)+"p"+strconv.Itoa(op.CurrentPage+1)+".html")
|
||||
current_page_file, err = os.OpenFile(current_page_filepath, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0777)
|
||||
if err != nil {
|
||||
errortext = "Failed opening " + current_page_filepath + ": " + err.Error()
|
||||
html += errortext + "<br />\n"
|
||||
println(1, errortext)
|
||||
errorLog.Println(errortext)
|
||||
html += handleError(1, "Failed opening "+current_page_filepath+": "+err.Error()) + "<br />\n"
|
||||
return
|
||||
}
|
||||
|
||||
// var postsSanitized []interface{}
|
||||
// for i := 0; i < len(page_posts); i++ {
|
||||
// postsSanitized = append(postsSanitized, sanitizePost(page_posts[i].(PostTable)))
|
||||
// }
|
||||
|
||||
err = renderTemplate(img_threadpage_tmpl, "threadpage", current_page_file,
|
||||
if err = renderTemplate(img_header_tmpl, "img_header", current_page_file,
|
||||
&Wrapper{IName: "boards_", Data: all_boards},
|
||||
&Wrapper{IName: "sections_w", Data: all_sections},
|
||||
//&Wrapper{IName: "posts_w", Data: postsSanitized},
|
||||
&Wrapper{IName: "posts_w", Data: page_posts},
|
||||
)
|
||||
if err != nil {
|
||||
errortext = fmt.Sprintf("Failed building /%s/%d: %s", boardDir, op.ID, err.Error())
|
||||
html += errortext + "<br />\n"
|
||||
println(1, errortext)
|
||||
errorLog.Print(errortext)
|
||||
&Wrapper{IName: "posts_w", Data: append([]interface{}{op}, replies...)},
|
||||
); err != nil {
|
||||
html += handleError(1, fmt.Sprintf("Failed building /%s/%d: %s", boardDir, op.ID, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if err = renderTemplate(img_threadpage_tmpl, "threadpage", current_page_file,
|
||||
&Wrapper{IName: "boards_", Data: all_boards},
|
||||
&Wrapper{IName: "sections_w", Data: all_sections},
|
||||
&Wrapper{IName: "posts_w", Data: page_posts},
|
||||
); err != nil {
|
||||
html += handleError(1, fmt.Sprintf("Failed building /%s/%d: %s", boardDir, op.ID, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if err = renderTemplate(global_footer_tmpl, "global_footer", current_page_file); err != nil {
|
||||
html += handleError(1, fmt.Sprintf("Failed building /%s/%d: %s", boardDir, op.ID, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
success_text := fmt.Sprintf("Built /%s/%dp%d successfully", boardDir, op.ID, op.CurrentPage+1)
|
||||
html += success_text + "<br />\n"
|
||||
println(2, success_text)
|
||||
|
@ -566,35 +614,24 @@ func buildFrontPage() (html string) {
|
|||
var front_arr []interface{}
|
||||
var recent_posts_arr []interface{}
|
||||
|
||||
var errortext string
|
||||
os.Remove(path.Join(config.DocumentRoot, "index.html"))
|
||||
front_file, err := os.OpenFile(path.Join(config.DocumentRoot, "index.html"), os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0777)
|
||||
defer func() {
|
||||
if front_file != nil {
|
||||
front_file.Close()
|
||||
}
|
||||
}()
|
||||
if err != nil {
|
||||
errortext = "Failed opening front page for writing: " + err.Error()
|
||||
errorLog.Println(errortext)
|
||||
return errortext + "<br />\n"
|
||||
return handleError(1, "Failed opening front page for writing: "+err.Error()) + "<br />\n"
|
||||
}
|
||||
defer closeFile(front_file)
|
||||
|
||||
// get front pages
|
||||
rows, err := db.Query("SELECT * FROM `" + config.DBprefix + "frontpage`")
|
||||
if err != nil {
|
||||
errortext = "Failed getting front page rows: " + err.Error()
|
||||
errorLog.Print(errortext)
|
||||
return errortext + "<br />"
|
||||
return handleError(1, "Failed getting front page rows: "+err.Error())
|
||||
}
|
||||
for rows.Next() {
|
||||
frontpage := new(FrontTable)
|
||||
frontpage.IName = "front page"
|
||||
err = rows.Scan(&frontpage.ID, &frontpage.Page, &frontpage.Order, &frontpage.Subject, &frontpage.Message, &frontpage.Timestamp, &frontpage.Poster, &frontpage.Email)
|
||||
if err != nil {
|
||||
errorLog.Print(err.Error())
|
||||
println(1, err.Error())
|
||||
return err.Error()
|
||||
if err = rows.Scan(&frontpage.ID, &frontpage.Page, &frontpage.Order, &frontpage.Subject,
|
||||
&frontpage.Message, &frontpage.Timestamp, &frontpage.Poster, &frontpage.Email); err != nil {
|
||||
return handleError(1, err.Error()) + "<br />"
|
||||
}
|
||||
front_arr = append(front_arr, frontpage)
|
||||
}
|
||||
|
@ -610,63 +647,41 @@ func buildFrontPage() (html string) {
|
|||
"WHERE `" + config.DBprefix + "posts`.`deleted_timestamp` = ? " +
|
||||
"AND `boardid` = `" + config.DBprefix + "boards`.`id` " +
|
||||
"ORDER BY `timestamp` DESC LIMIT ?")
|
||||
defer func() {
|
||||
if stmt != nil {
|
||||
stmt.Close()
|
||||
}
|
||||
}()
|
||||
if err != nil {
|
||||
errorLog.Print(err.Error())
|
||||
println(1, err.Error())
|
||||
return err.Error() + "<br />\n"
|
||||
return handleError(1, err.Error()) + "<br />"
|
||||
}
|
||||
defer closeStatement(stmt)
|
||||
|
||||
rows, err = stmt.Query(nil_timestamp, config.MaxRecentPosts)
|
||||
if err != nil {
|
||||
errortext = "Failed getting list of recent posts for front page: " + err.Error()
|
||||
errorLog.Print(errortext)
|
||||
println(1, errortext)
|
||||
return errortext + "<br />\n"
|
||||
return handleError(1, "Failed getting list of recent posts for front page: "+err.Error()) + "<br />"
|
||||
}
|
||||
for rows.Next() {
|
||||
recent_post := new(RecentPost)
|
||||
err = rows.Scan(&recent_post.PostID, &recent_post.ParentID, &recent_post.BoardName, &recent_post.BoardID, &recent_post.Name, &recent_post.Tripcode, &recent_post.Message, &recent_post.Filename, &recent_post.ThumbW, &recent_post.ThumbH)
|
||||
if err != nil {
|
||||
errortext = "Failed getting list of recent posts for front page: " + err.Error()
|
||||
errorLog.Print(errortext)
|
||||
println(1, errortext)
|
||||
return errortext + "<br />\n"
|
||||
return handleError(1, "Failed getting list of recent posts for front page: "+err.Error()) + "<br />"
|
||||
}
|
||||
recent_posts_arr = append(recent_posts_arr, recent_post)
|
||||
}
|
||||
|
||||
err = renderTemplate(front_page_tmpl, "frontpage", front_file,
|
||||
if err = renderTemplate(front_page_tmpl, "frontpage", front_file,
|
||||
&Wrapper{IName: "fronts", Data: front_arr},
|
||||
&Wrapper{IName: "boards", Data: all_boards},
|
||||
&Wrapper{IName: "sections", Data: all_sections},
|
||||
&Wrapper{IName: "recent posts", Data: recent_posts_arr},
|
||||
)
|
||||
if err != nil {
|
||||
errortext = "Failed executing front page template: " + err.Error()
|
||||
errorLog.Println(errortext)
|
||||
println(1, errortext)
|
||||
return errortext + "<br />\n"
|
||||
); err != nil {
|
||||
return handleError(1, "Failed executing front page template: "+err.Error()) + "<br />"
|
||||
}
|
||||
return "Front page rebuilt successfully.<br />"
|
||||
}
|
||||
|
||||
func buildBoardListJSON() (html string) {
|
||||
var errortext string
|
||||
board_list_file, err := os.OpenFile(path.Join(config.DocumentRoot, "boards.json"), os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0777)
|
||||
defer func() {
|
||||
if board_list_file != nil {
|
||||
board_list_file.Close()
|
||||
}
|
||||
}()
|
||||
if err != nil {
|
||||
errortext = "Failed opening board.json for writing: " + err.Error()
|
||||
errorLog.Println(errortext)
|
||||
return errortext + "<br />\n"
|
||||
return handleError(1, "Failed opening board.json for writing: "+err.Error()) + "<br />\n"
|
||||
}
|
||||
defer closeFile(board_list_file)
|
||||
|
||||
board_list_wrapper := new(BoardJSONWrapper)
|
||||
|
||||
|
@ -686,20 +701,11 @@ func buildBoardListJSON() (html string) {
|
|||
}
|
||||
|
||||
boardJSON, err := json.Marshal(board_list_wrapper)
|
||||
|
||||
if err != nil {
|
||||
errortext = "Failed marshal to JSON: " + err.Error()
|
||||
errorLog.Println(errortext)
|
||||
println(1, errortext)
|
||||
return errortext + "<br />\n"
|
||||
return handleError(1, "Failed marshal to JSON: "+err.Error()) + "<br />\n"
|
||||
}
|
||||
_, err = board_list_file.Write(boardJSON)
|
||||
|
||||
if err != nil {
|
||||
errortext = "Failed writing boards.json file: " + err.Error()
|
||||
errorLog.Println(errortext)
|
||||
println(1, errortext)
|
||||
return errortext + "<br />\n"
|
||||
if _, err = board_list_file.Write(boardJSON); err != nil {
|
||||
return handleError(1, "Failed writing boards.json file: "+err.Error()) + "<br />\n"
|
||||
}
|
||||
return "Board list JSON rebuilt successfully.<br />"
|
||||
}
|
||||
|
@ -711,14 +717,9 @@ func bumpThread(postID, boardID int) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if stmt != nil {
|
||||
stmt.Close()
|
||||
}
|
||||
}()
|
||||
defer closeStatement(stmt)
|
||||
|
||||
_, err = stmt.Exec(time.Now(), postID, boardID)
|
||||
if err != nil {
|
||||
if _, err = stmt.Exec(time.Now(), postID, boardID); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
@ -733,19 +734,13 @@ func checkBannedStatus(post *PostTable, writer *http.ResponseWriter) ([]interfac
|
|||
// var count int
|
||||
// var search string
|
||||
stmt, err := db.Prepare("SELECT `ip`, `name`, `tripcode`, `message`, `boards`, `timestamp`, `expires`, `appeal_at` FROM `" + config.DBprefix + "banlist` WHERE `ip` = ?")
|
||||
defer func() {
|
||||
if stmt != nil {
|
||||
stmt.Close()
|
||||
}
|
||||
}()
|
||||
if err != nil {
|
||||
errortext := "Error checking banned status: " + err.Error()
|
||||
println(1, errortext)
|
||||
errorLog.Print(errortext)
|
||||
return interfaces, nil
|
||||
handleError(1, "Error checking banned status: "+err.Error())
|
||||
return interfaces, err
|
||||
}
|
||||
err = stmt.QueryRow(&post.IP).Scan(&ban_entry.IP, &ban_entry.Name, &ban_entry.Tripcode, &ban_entry.Message, &ban_entry.Boards, &ban_entry.Timestamp, &ban_entry.Expires, &ban_entry.AppealAt)
|
||||
defer closeStatement(stmt)
|
||||
|
||||
err = stmt.QueryRow(&post.IP).Scan(&ban_entry.IP, &ban_entry.Name, &ban_entry.Tripcode, &ban_entry.Message, &ban_entry.Boards, &ban_entry.Timestamp, &ban_entry.Expires, &ban_entry.AppealAt)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
// the user isn't banned
|
||||
|
@ -780,15 +775,12 @@ func checkBannedStatus(post *PostTable, writer *http.ResponseWriter) ([]interfac
|
|||
}
|
||||
|
||||
func sinceLastPost(post *PostTable) int {
|
||||
var oldpost PostTable
|
||||
err := db.QueryRow("SELECT `timestamp` FROM `" + config.DBprefix + "posts` WHERE `ip` = '" + post.IP + "' ORDER BY `timestamp` DESC LIMIT 1").Scan(&oldpost.Timestamp)
|
||||
|
||||
since := time.Since(oldpost.Timestamp)
|
||||
if err == sql.ErrNoRows {
|
||||
var lastPostTime time.Time
|
||||
if err := db.QueryRow("SELECT `timestamp` FROM `" + config.DBprefix + "posts` WHERE `ip` = '" + post.IP + "' ORDER BY `timestamp` DESC LIMIT 1").Scan(&lastPostTime); err == sql.ErrNoRows {
|
||||
// no posts by that IP.
|
||||
return -1
|
||||
} else {
|
||||
return int(since.Seconds())
|
||||
return int(time.Since(lastPostTime).Seconds())
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
@ -849,7 +841,6 @@ func getVideoInfo(path string) (map[string]int, error) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return vidInfo, err
|
||||
}
|
||||
|
||||
|
@ -907,11 +898,8 @@ func insertPost(post PostTable, bump bool) (sql.Result, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
if stmt != nil {
|
||||
stmt.Close()
|
||||
}
|
||||
}()
|
||||
defer closeStatement(stmt)
|
||||
|
||||
result, err = stmt.Exec(
|
||||
post.BoardID, post.ParentID, post.Name, post.Tripcode,
|
||||
post.Email, post.Subject, post.MessageHTML, post.MessageText,
|
||||
|
@ -941,7 +929,6 @@ func makePost(w http.ResponseWriter, r *http.Request, data interface{}) {
|
|||
request = *r
|
||||
writer = w
|
||||
var maxMessageLength int
|
||||
var errorText string
|
||||
var post PostTable
|
||||
domain := r.Host
|
||||
var formName string
|
||||
|
@ -991,17 +978,13 @@ func makePost(w http.ResponseWriter, r *http.Request, data interface{}) {
|
|||
if err != nil {
|
||||
serveErrorPage(w, "Error getting board info.")
|
||||
errorLog.Print("Error getting board info: " + err.Error())
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
if stmt != nil {
|
||||
stmt.Close()
|
||||
}
|
||||
}()
|
||||
err = stmt.QueryRow(post.BoardID).Scan(&maxMessageLength)
|
||||
defer closeStatement(stmt)
|
||||
|
||||
if err != nil {
|
||||
serveErrorPage(w, "Requested board does not exist.")
|
||||
errorLog.Print("requested board does not exist. Error: " + err.Error())
|
||||
if err = stmt.QueryRow(post.BoardID).Scan(&maxMessageLength); err != nil {
|
||||
serveErrorPage(w, handleError(1, "Requested board does not exist."))
|
||||
return
|
||||
}
|
||||
|
||||
if len(post.MessageText) > maxMessageLength {
|
||||
|
@ -1048,6 +1031,11 @@ func makePost(w http.ResponseWriter, r *http.Request, data interface{}) {
|
|||
}
|
||||
|
||||
file, handler, err := request.FormFile("imagefile")
|
||||
defer func() {
|
||||
if file != nil {
|
||||
file.Close()
|
||||
}
|
||||
}()
|
||||
if err != nil {
|
||||
// no file was uploaded
|
||||
post.Filename = ""
|
||||
|
@ -1055,12 +1043,11 @@ func makePost(w http.ResponseWriter, r *http.Request, data interface{}) {
|
|||
} else {
|
||||
data, err := ioutil.ReadAll(file)
|
||||
if err != nil {
|
||||
serveErrorPage(w, "Couldn't read file: "+err.Error())
|
||||
serveErrorPage(w, handleError(1, "Couldn't read file: "+err.Error()))
|
||||
} else {
|
||||
post.FilenameOriginal = html.EscapeString(handler.Filename)
|
||||
filetype := getFileExtension(post.FilenameOriginal)
|
||||
thumbFiletype := filetype
|
||||
|
||||
if thumbFiletype == "gif" || thumbFiletype == "webm" {
|
||||
thumbFiletype = "jpg"
|
||||
}
|
||||
|
@ -1069,20 +1056,16 @@ func makePost(w http.ResponseWriter, r *http.Request, data interface{}) {
|
|||
boardArr, _ := getBoardArr(map[string]interface{}{"id": request.FormValue("boardid")}, "")
|
||||
if len(boardArr) == 0 {
|
||||
serveErrorPage(w, "No boards have been created yet")
|
||||
return
|
||||
}
|
||||
_boardDir, _ := getBoardArr(map[string]interface{}{"id": request.FormValue("boardid")}, "")
|
||||
boardDir := _boardDir[0].Dir
|
||||
filePath := path.Join(config.DocumentRoot, "/"+boardDir+"/src/", post.Filename)
|
||||
|
||||
thumbPath := path.Join(config.DocumentRoot, "/"+boardDir+"/thumb/", strings.Replace(post.Filename, "."+filetype, "t."+thumbFiletype, -1))
|
||||
|
||||
catalogThumbPath := path.Join(config.DocumentRoot, "/"+boardDir+"/thumb/", strings.Replace(post.Filename, "."+filetype, "c."+thumbFiletype, -1))
|
||||
|
||||
err := ioutil.WriteFile(filePath, data, 0777)
|
||||
if err != nil {
|
||||
errorText = "Couldn't write file \"" + post.Filename + "\"" + err.Error()
|
||||
println(0, errorText)
|
||||
errorLog.Println(errorText)
|
||||
if err := ioutil.WriteFile(filePath, data, 0777); err != nil {
|
||||
handleError(0, "Couldn't write file \""+post.Filename+"\""+err.Error())
|
||||
serveErrorPage(w, "Couldn't write file \""+post.FilenameOriginal+"\"")
|
||||
return
|
||||
}
|
||||
|
@ -1093,25 +1076,13 @@ func makePost(w http.ResponseWriter, r *http.Request, data interface{}) {
|
|||
var allowsVids bool
|
||||
vidStmt, err := db.Prepare("SELECT `embeds_allowed` FROM `" + config.DBprefix + "boards` WHERE `id` = ? LIMIT 1")
|
||||
if err != nil {
|
||||
errortext := err.Error()
|
||||
errorLog.Println(errorText)
|
||||
serveErrorPage(w, "Couldn't get board info: "+errorText)
|
||||
println(1, errortext)
|
||||
serveErrorPage(w, handleError(1, "Couldn't get board info: "+err.Error()))
|
||||
return
|
||||
}
|
||||
defer closeStatement(vidStmt)
|
||||
|
||||
defer func() {
|
||||
if vidStmt != nil {
|
||||
vidStmt.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
err = vidStmt.QueryRow(post.BoardID).Scan(&allowsVids)
|
||||
if err != nil {
|
||||
errortext := err.Error()
|
||||
errorLog.Println(errorText)
|
||||
serveErrorPage(w, "Couldn't get board info: "+errorText)
|
||||
println(1, errortext)
|
||||
if err = vidStmt.QueryRow(post.BoardID).Scan(&allowsVids); err != nil {
|
||||
serveErrorPage(w, handleError(1, "Couldn't get board info: "+err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -1126,31 +1097,25 @@ func makePost(w http.ResponseWriter, r *http.Request, data interface{}) {
|
|||
if post.ParentID == 0 {
|
||||
err := createVideoThumbnail(filePath, thumbPath, config.ThumbWidth)
|
||||
if err != nil {
|
||||
serveErrorPage(w, err.Error())
|
||||
printf(1, err.Error())
|
||||
serveErrorPage(w, handleError(1, err.Error()))
|
||||
return
|
||||
}
|
||||
} else {
|
||||
err := createVideoThumbnail(filePath, thumbPath, config.ThumbWidth_reply)
|
||||
if err != nil {
|
||||
serveErrorPage(w, err.Error())
|
||||
printf(1, err.Error())
|
||||
serveErrorPage(w, handleError(1, err.Error()))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
err := createVideoThumbnail(filePath, catalogThumbPath, config.ThumbWidth_catalog)
|
||||
if err != nil {
|
||||
serveErrorPage(w, err.Error())
|
||||
printf(1, err.Error())
|
||||
if err := createVideoThumbnail(filePath, catalogThumbPath, config.ThumbWidth_catalog); err != nil {
|
||||
serveErrorPage(w, handleError(1, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
outputBytes, err := exec.Command("ffprobe", "-v", "quiet", "-show_format", "-show_streams", filePath).CombinedOutput()
|
||||
if err != nil {
|
||||
errortext := "Error getting video info: " + err.Error()
|
||||
serveErrorPage(w, errortext)
|
||||
printf(1, errortext)
|
||||
serveErrorPage(w, handleError(1, "Error getting video info: "+err.Error()))
|
||||
return
|
||||
}
|
||||
if err == nil && outputBytes != nil {
|
||||
|
@ -1181,20 +1146,15 @@ func makePost(w http.ResponseWriter, r *http.Request, data interface{}) {
|
|||
// Attempt to load uploaded file with imaging library
|
||||
img, err := imaging.Open(filePath)
|
||||
if err != nil {
|
||||
errorText = "Couldn't open uploaded file \"" + post.Filename + "\"" + err.Error()
|
||||
errorLog.Println(errorText)
|
||||
println(1, errorText)
|
||||
os.Remove(filePath)
|
||||
handleError(1, "Couldn't open uploaded file \""+post.Filename+"\""+err.Error())
|
||||
serveErrorPage(w, "Upload filetype not supported")
|
||||
return
|
||||
} else {
|
||||
// Get image filesize
|
||||
stat, err := os.Stat(filePath)
|
||||
if err != nil {
|
||||
errortext := "Couldn't get image filesize: " + err.Error()
|
||||
errorLog.Println(errortext)
|
||||
println(1, errortext)
|
||||
serveErrorPage(w, errortext)
|
||||
serveErrorPage(w, handleError(1, "Couldn't get image filesize: "+err.Error()))
|
||||
return
|
||||
} else {
|
||||
post.Filesize = int(stat.Size())
|
||||
|
@ -1213,8 +1173,7 @@ func makePost(w http.ResponseWriter, r *http.Request, data interface{}) {
|
|||
|
||||
if request.FormValue("spoiler") == "on" {
|
||||
// If spoiler is enabled, symlink thumbnail to spoiler image
|
||||
_, err := os.Stat(path.Join(config.DocumentRoot, "spoiler.png"))
|
||||
if err != nil {
|
||||
if _, err := os.Stat(path.Join(config.DocumentRoot, "spoiler.png")); err != nil {
|
||||
serveErrorPage(w, "missing /spoiler.png")
|
||||
return
|
||||
} else {
|
||||
|
@ -1228,8 +1187,7 @@ func makePost(w http.ResponseWriter, r *http.Request, data interface{}) {
|
|||
// If image fits in thumbnail size, symlink thumbnail to original
|
||||
post.ThumbW = img.Bounds().Max.X
|
||||
post.ThumbH = img.Bounds().Max.Y
|
||||
err := syscall.Symlink(filePath, thumbPath)
|
||||
if err != nil {
|
||||
if err := syscall.Symlink(filePath, thumbPath); err != nil {
|
||||
serveErrorPage(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
@ -1241,21 +1199,15 @@ func makePost(w http.ResponseWriter, r *http.Request, data interface{}) {
|
|||
thumbnail = createImageThumbnail(img, "op")
|
||||
catalogThumbnail = createImageThumbnail(img, "catalog")
|
||||
println(1, catalogThumbPath)
|
||||
err = imaging.Save(catalogThumbnail, catalogThumbPath)
|
||||
if err != nil {
|
||||
errorLog.Println("Couldn't generate catalog thumbnail: " + err.Error())
|
||||
serveErrorPage(w, "Couldn't generate catalog thumbnail: "+err.Error())
|
||||
if err = imaging.Save(catalogThumbnail, catalogThumbPath); err != nil {
|
||||
serveErrorPage(w, handleError(1, "Couldn't generate catalog thumbnail: "+err.Error()))
|
||||
return
|
||||
}
|
||||
} else {
|
||||
thumbnail = createImageThumbnail(img, "reply")
|
||||
}
|
||||
err = imaging.Save(thumbnail, thumbPath)
|
||||
if err != nil {
|
||||
errortext := "Couldn't save thumbnail: " + err.Error()
|
||||
println(0, errortext)
|
||||
errorLog.Println(errortext)
|
||||
serveErrorPage(w, errortext)
|
||||
if err = imaging.Save(thumbnail, thumbPath); err != nil {
|
||||
serveErrorPage(w, handleError(1, "Couldn't save thumbnail: "+err.Error()))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -1285,10 +1237,8 @@ func makePost(w http.ResponseWriter, r *http.Request, data interface{}) {
|
|||
|
||||
isBanned, err := checkBannedStatus(&post, &w)
|
||||
if err != nil {
|
||||
errorText = "Error in checkBannedStatus: " + err.Error()
|
||||
handleError(1, "Error in checkBannedStatus: "+err.Error())
|
||||
serveErrorPage(w, err.Error())
|
||||
errorLog.Println(errorText)
|
||||
println(1, errorText)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -1296,11 +1246,8 @@ func makePost(w http.ResponseWriter, r *http.Request, data interface{}) {
|
|||
var banpage_buffer bytes.Buffer
|
||||
var banpage_html string
|
||||
banpage_buffer.Write([]byte(""))
|
||||
err = renderTemplate(banpage_tmpl, "banpage", &banpage_buffer, &Wrapper{IName: "bans", Data: isBanned})
|
||||
if err != nil {
|
||||
fmt.Fprintf(writer, banpage_html+err.Error()+"\n</body>\n</html>")
|
||||
println(1, err.Error())
|
||||
errorLog.Println(err.Error())
|
||||
if err = renderTemplate(banpage_tmpl, "banpage", &banpage_buffer, &Wrapper{IName: "bans", Data: isBanned}); err != nil {
|
||||
fmt.Fprintf(writer, banpage_html+handleError(1, err.Error())+"\n</body>\n</html>")
|
||||
return
|
||||
}
|
||||
fmt.Fprintf(w, banpage_buffer.String())
|
||||
|
@ -1310,7 +1257,7 @@ func makePost(w http.ResponseWriter, r *http.Request, data interface{}) {
|
|||
post = sanitizePost(post)
|
||||
result, err := insertPost(post, emailCommand != "sage")
|
||||
if err != nil {
|
||||
serveErrorPage(w, err.Error())
|
||||
serveErrorPage(w, handleError(1, err.Error()))
|
||||
return
|
||||
}
|
||||
postid, _ := result.LastInsertId()
|
||||
|
@ -1346,8 +1293,7 @@ func formatMessage(message string) string {
|
|||
for w, word := range lineWords {
|
||||
if strings.LastIndex(word, gt+gt) == 0 {
|
||||
//word is a backlink
|
||||
_, err := strconv.Atoi(word[8:])
|
||||
if err == nil {
|
||||
if _, err := strconv.Atoi(word[8:]); err == nil {
|
||||
// the link is in fact, a valid int
|
||||
var boardDir string
|
||||
var linkParent int
|
||||
|
|
|
@ -127,7 +127,7 @@ func (s GochanServer) ServeHTTP(writer http.ResponseWriter, request *http.Reques
|
|||
func initServer() {
|
||||
listener, err := net.Listen("tcp", config.ListenIP+":"+strconv.Itoa(config.Port))
|
||||
if err != nil {
|
||||
fmt.Printf("Failed listening on %s:%d, see log for details", config.ListenIP, config.Port)
|
||||
printf(0, "Failed listening on %s:%d, see log for details", config.ListenIP, config.Port)
|
||||
errorLog.Fatal(err.Error())
|
||||
}
|
||||
server = new(GochanServer)
|
||||
|
@ -182,7 +182,9 @@ func utilHandler(writer http.ResponseWriter, request *http.Request, data interfa
|
|||
fileOnly := request.FormValue("fileonly") == "on"
|
||||
deleteBtn := request.PostFormValue("delete_btn")
|
||||
reportBtn := request.PostFormValue("report_btn")
|
||||
if action == "" && deleteBtn != "Delete" && reportBtn != "Report" {
|
||||
editBtn := request.PostFormValue("edit_btn")
|
||||
|
||||
if action == "" && deleteBtn != "Delete" && reportBtn != "Report" && editBtn != "Edit" {
|
||||
http.Redirect(writer, request, path.Join(config.SiteWebfolder, "/"), http.StatusFound)
|
||||
return
|
||||
}
|
||||
|
@ -192,6 +194,19 @@ func utilHandler(writer http.ResponseWriter, request *http.Request, data interfa
|
|||
postsArr = append(postsArr, key[5:])
|
||||
}
|
||||
}
|
||||
|
||||
if editBtn == "Edit" {
|
||||
if len(postsArr) == 0 {
|
||||
serveErrorPage(writer, "You need to select one post to edit.")
|
||||
return
|
||||
} else if len(postsArr) > 1 {
|
||||
serveErrorPage(writer, "You can only edit one post at a time.")
|
||||
return
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if deleteBtn == "Delete" {
|
||||
// Delete a post or thread
|
||||
passwordMD5 := md5Sum(password)
|
||||
|
@ -213,17 +228,13 @@ func utilHandler(writer http.ResponseWriter, request *http.Request, data interfa
|
|||
post.ID, _ = strconv.Atoi(checkedPostID)
|
||||
|
||||
stmt, err := db.Prepare("SELECT `parentID`, `filename`, `password` FROM `" + config.DBprefix + "posts` WHERE `id` = ? AND `deleted_timestamp` = ?")
|
||||
defer func() {
|
||||
if stmt != nil {
|
||||
stmt.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
if err != nil {
|
||||
errorLog.Print(err.Error())
|
||||
println(1, err.Error())
|
||||
serveErrorPage(writer, err.Error())
|
||||
}
|
||||
defer closeStatement(stmt)
|
||||
|
||||
err = stmt.QueryRow(&post.ID, nil_timestamp).Scan(&post.ParentID, &post.Filename, &post.Password)
|
||||
|
||||
if err == sql.ErrNoRows {
|
||||
|
@ -279,7 +290,7 @@ func utilHandler(writer http.ResponseWriter, request *http.Request, data interfa
|
|||
// delete the post
|
||||
_, err = db.Exec("UPDATE `" + config.DBprefix + "posts` SET `deleted_timestamp` = '" + getSQLDateTime() + "' WHERE `id` = " + strconv.Itoa(post.ID))
|
||||
if post.ParentID == 0 {
|
||||
err = os.Remove(path.Join(config.DocumentRoot, board, "/res/"+strconv.Itoa(post.ID)+".html"))
|
||||
os.Remove(path.Join(config.DocumentRoot, board, "/res/"+strconv.Itoa(post.ID)+".html"))
|
||||
} else {
|
||||
_board, _ := getBoardArr(map[string]interface{}{"id": post.BoardID}, "") // getBoardArr("`id` = " + strconv.Itoa(boardid))
|
||||
buildBoardPages(&_board[0])
|
||||
|
|
|
@ -33,7 +33,7 @@ func connectToSQLServer() {
|
|||
|
||||
// get the number of tables in the database. If the number > 1, we can assume that initial setup has already been run
|
||||
var num_rows int
|
||||
err = db.QueryRow("SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = '" + config.DBname + "';").Scan(&num_rows)
|
||||
err = db.QueryRow("SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = '" + config.DBname + "'").Scan(&num_rows)
|
||||
if err == sql.ErrNoRows {
|
||||
num_rows = 0
|
||||
} else if err != nil {
|
||||
|
@ -50,8 +50,7 @@ func connectToSQLServer() {
|
|||
return
|
||||
} else {
|
||||
// check if initialsetupdb.sql still exists
|
||||
_, err := os.Stat("initialsetupdb.sql")
|
||||
if err != nil {
|
||||
if _, err := os.Stat("initialsetupdb.sql"); err != nil {
|
||||
println(0, "Initial setup file (initialsetupdb.sql) missing. Please reinstall gochan")
|
||||
errorLog.Fatal("Initial setup file (initialsetupdb.sql) missing. Please reinstall gochan")
|
||||
}
|
||||
|
@ -73,8 +72,7 @@ func connectToSQLServer() {
|
|||
|
||||
for _, statement := range initial_sql_arr {
|
||||
if statement != "" {
|
||||
_, err := db.Exec(statement)
|
||||
if err != nil {
|
||||
if _, err := db.Exec(statement); err != nil {
|
||||
println(0, "failed, see log for details.")
|
||||
errorLog.Fatal("Error executing initialsetupdb.sql: " + err.Error())
|
||||
return
|
||||
|
|
280
src/template.go
280
src/template.go
|
@ -1,14 +1,12 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"html"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
@ -115,7 +113,10 @@ var funcMap = template.FuncMap{
|
|||
return style != config.DefaultStyle_img
|
||||
},
|
||||
"getElement": func(in []interface{}, element int) interface{} {
|
||||
return in[element]
|
||||
if len(in) > element {
|
||||
return in[element]
|
||||
}
|
||||
return nil
|
||||
},
|
||||
"getInterface": func(in []interface{}, index int) interface{} {
|
||||
var nope interface{}
|
||||
|
@ -197,177 +198,119 @@ var funcMap = template.FuncMap{
|
|||
var (
|
||||
footer_data = FooterData{version, float32(0)}
|
||||
|
||||
banpage_tmpl_str string
|
||||
banpage_tmpl *template.Template
|
||||
|
||||
global_footer_tmpl_str string
|
||||
global_footer_tmpl *template.Template
|
||||
|
||||
global_header_tmpl_str string
|
||||
global_header_tmpl *template.Template
|
||||
|
||||
img_boardpage_tmpl_str string
|
||||
img_boardpage_tmpl *template.Template
|
||||
|
||||
img_threadpage_tmpl_str string
|
||||
img_threadpage_tmpl *template.Template
|
||||
|
||||
manage_header_tmpl_str string
|
||||
manage_header_tmpl *template.Template
|
||||
|
||||
manage_boards_tmpl_str string
|
||||
manage_boards_tmpl *template.Template
|
||||
|
||||
manage_config_tmpl_str string
|
||||
manage_config_tmpl *template.Template
|
||||
|
||||
front_page_tmpl_str string
|
||||
banpage_tmpl *template.Template
|
||||
global_footer_tmpl *template.Template
|
||||
global_header_tmpl *template.Template
|
||||
img_header_tmpl *template.Template
|
||||
img_boardpage_tmpl *template.Template
|
||||
img_threadpage_tmpl *template.Template
|
||||
img_post_form_tmpl *template.Template
|
||||
manage_header_tmpl *template.Template
|
||||
manage_boards_tmpl *template.Template
|
||||
manage_config_tmpl *template.Template
|
||||
front_page_tmpl *template.Template
|
||||
|
||||
template_buffer bytes.Buffer
|
||||
starting_time int
|
||||
)
|
||||
|
||||
func initTemplates() {
|
||||
resetBoardSectionArrays()
|
||||
banpage_tmpl_bytes, tmpl_err := ioutil.ReadFile(config.TemplateDir + "/banpage.html")
|
||||
if tmpl_err != nil {
|
||||
fmt.Println("Failed loading template \"" + config.TemplateDir + "/banpage.html\": " + tmpl_err.Error())
|
||||
os.Exit(2)
|
||||
}
|
||||
banpage_tmpl_str = "{{$config := getInterface .Data 0}}" +
|
||||
"{{$ban := getInterface .Data 1}}" +
|
||||
string(banpage_tmpl_bytes)
|
||||
banpage_tmpl, tmpl_err = template.New("banpage_tmpl").Funcs(funcMap).Parse(string(banpage_tmpl_str))
|
||||
if tmpl_err != nil {
|
||||
fmt.Println("Failed loading template \"" + config.TemplateDir + "/banpage.html\": " + tmpl_err.Error())
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
global_footer_tmpl_bytes, tmpl_err := ioutil.ReadFile(config.TemplateDir + "/global_footer.html")
|
||||
if tmpl_err != nil {
|
||||
fmt.Println("Failed loading template \"" + config.TemplateDir + "/global_footer.html\": " + tmpl_err.Error())
|
||||
os.Exit(2)
|
||||
}
|
||||
global_footer_tmpl_str = string(global_footer_tmpl_bytes)
|
||||
global_footer_tmpl, tmpl_err = template.New("global_footer_tmpl").Funcs(funcMap).Parse(string(global_footer_tmpl_str))
|
||||
if tmpl_err != nil {
|
||||
fmt.Println("Failed loading template \"" + config.TemplateDir + "/global_footer.html\": " + tmpl_err.Error())
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
global_header_tmpl_bytes, tmpl_err := ioutil.ReadFile(config.TemplateDir + "/global_header.html")
|
||||
if tmpl_err != nil {
|
||||
fmt.Println("Failed loading template \"" + config.TemplateDir + "/global_header.html\": " + tmpl_err.Error())
|
||||
os.Exit(2)
|
||||
}
|
||||
global_header_tmpl_str = string(global_header_tmpl_bytes)
|
||||
global_header_tmpl, tmpl_err = template.New("global_header_tmpl").Funcs(funcMap).Parse(string(global_header_tmpl_str))
|
||||
if tmpl_err != nil {
|
||||
fmt.Println("Failed loading template \"" + config.TemplateDir + "/global_header.html\": " + tmpl_err.Error())
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
img_boardpage_tmpl_bytes, _ := ioutil.ReadFile(path.Join(config.TemplateDir, "img_boardpage.html"))
|
||||
if tmpl_err != nil {
|
||||
fmt.Println("Failed loading template \"" + config.TemplateDir + "/img_boardpage.html\": " + tmpl_err.Error())
|
||||
os.Exit(2)
|
||||
}
|
||||
img_boardpage_tmpl_str = "{{$config := getInterface .Data 0}}" +
|
||||
"{{$board_arr := (getInterface .Data 1).Data}}" +
|
||||
"{{$section_arr := (getInterface .Data 2).Data}}" +
|
||||
"{{$thread_arr := (getInterface .Data 3).Data}}" +
|
||||
"{{$board_info := (getInterface .Data 4).Data}}" +
|
||||
"{{$board := getInterface $board_info 0}}" +
|
||||
string(img_boardpage_tmpl_bytes)
|
||||
img_boardpage_tmpl, tmpl_err = template.New("img_boardpage_tmpl").Funcs(funcMap).Parse(img_boardpage_tmpl_str)
|
||||
if tmpl_err != nil {
|
||||
fmt.Println("Failed loading template \"" + config.TemplateDir + "/img_boardpage.html: \"" + tmpl_err.Error())
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
img_threadpage_tmpl_bytes, _ := ioutil.ReadFile(path.Join(config.TemplateDir, "img_threadpage.html"))
|
||||
if tmpl_err != nil {
|
||||
fmt.Println("Failed loading template \"" + config.TemplateDir + "/img_threadpage.html\": " + tmpl_err.Error())
|
||||
os.Exit(2)
|
||||
}
|
||||
img_threadpage_tmpl_str = "{{$config := getInterface .Data 0}}" +
|
||||
"{{$board_arr := (getInterface .Data 1).Data}}" +
|
||||
"{{$section_arr := (getInterface .Data 2).Data}}" +
|
||||
"{{$post_arr := (getInterface .Data 3).Data}}" +
|
||||
"{{$op := getElement $post_arr 0}}" +
|
||||
"{{$board := getElement $board_arr (subtract $op.BoardID 1)}}" +
|
||||
string(img_threadpage_tmpl_bytes)
|
||||
img_threadpage_tmpl, tmpl_err = template.New("img_threadpage_tmpl").Funcs(funcMap).Parse(img_threadpage_tmpl_str)
|
||||
if tmpl_err != nil {
|
||||
fmt.Println("Failed loading template \"" + config.TemplateDir + "/img_threadpage.html: \"" + tmpl_err.Error())
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
manage_header_tmpl_bytes, err := ioutil.ReadFile(config.TemplateDir + "/manage_header.html")
|
||||
func loadTemplate(name string, filename string, before string) (*template.Template, error) {
|
||||
tmplBytes, err := ioutil.ReadFile(config.TemplateDir + "/" + filename)
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
manage_header_tmpl_str = string(manage_header_tmpl_bytes)
|
||||
manage_header_tmpl, tmpl_err = template.New("manage_header_tmpl").Funcs(funcMap).Parse(manage_header_tmpl_str)
|
||||
if tmpl_err != nil {
|
||||
fmt.Println("Failed loading template \"" + config.TemplateDir + "/manage_header.html\": " + tmpl_err.Error())
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
manage_boards_tmpl_bytes, err := ioutil.ReadFile(config.TemplateDir + "/manage_boards.html")
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
manage_boards_tmpl_str = "{{$config := getInterface .Data 0}}" +
|
||||
"{{$board := getInterface (getInterface .Data 1).Data 0}}" +
|
||||
"{{$section_arr := (getInterface .Data 2).Data}}" +
|
||||
string(manage_boards_tmpl_bytes)
|
||||
|
||||
manage_boards_tmpl, tmpl_err = template.New("manage_boards_tmpl").Funcs(funcMap).Parse(manage_boards_tmpl_str)
|
||||
if tmpl_err != nil {
|
||||
fmt.Println("Failed loading template \"" + config.TemplateDir + "/manage_boards.html\": " + tmpl_err.Error())
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
manage_config_tmpl_bytes, err := ioutil.ReadFile(config.TemplateDir + "/manage_config.html")
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
manage_config_tmpl_str = "{{$config := getInterface .Data 0}}" +
|
||||
string(manage_config_tmpl_bytes)
|
||||
|
||||
manage_config_tmpl, tmpl_err = template.New("manage_config_tmpl").Funcs(funcMap).Parse(manage_config_tmpl_str)
|
||||
if tmpl_err != nil {
|
||||
fmt.Println("Failed loading template \"" + config.TemplateDir + "/manage_config.html\": " + tmpl_err.Error())
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
front_page_tmpl_bytes, err := ioutil.ReadFile(config.TemplateDir + "/front.html")
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
os.Exit(2)
|
||||
}
|
||||
front_page_tmpl_str = "{{$config := getInterface .Data 0}}" +
|
||||
"{{$page_arr := getInterface .Data 1}}" +
|
||||
"{{$board_arr := getInterface .Data 2}}" +
|
||||
"{{$section_arr := getInterface .Data 3}}" +
|
||||
"{{$recent_posts_arr := getInterface .Data 4}}" +
|
||||
string(front_page_tmpl_bytes)
|
||||
front_page_tmpl, tmpl_err = template.New("front_page_tmpl").Funcs(funcMap).Parse(front_page_tmpl_str)
|
||||
if tmpl_err != nil {
|
||||
fmt.Println("Failed loading template \"" + config.TemplateDir + "/front.html\": " + tmpl_err.Error())
|
||||
os.Exit(2)
|
||||
return nil, err
|
||||
}
|
||||
tmplStr := before + string(tmplBytes)
|
||||
return template.New(name).Funcs(funcMap).Parse(tmplStr)
|
||||
}
|
||||
|
||||
func getTemplateAsString(templ template.Template) (string, error) {
|
||||
var buf bytes.Buffer
|
||||
err := templ.Execute(&buf, config)
|
||||
if err == nil {
|
||||
return buf.String(), nil
|
||||
func initTemplates() {
|
||||
var err error
|
||||
resetBoardSectionArrays()
|
||||
|
||||
banpage_tmpl, err = loadTemplate("banpage_tmpl", "banpage.html",
|
||||
"{{$config := getInterface .Data 0}}"+
|
||||
"{{$ban := getInterface .Data 1}}")
|
||||
if err != nil {
|
||||
println(0, "Failed loading template \""+config.TemplateDir+"/banpage.html: \""+err.Error())
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
global_footer_tmpl, err = loadTemplate("global_footer_tmpl", "global_footer.html", "{{$config := getInterface .Data 0}}")
|
||||
if err != nil {
|
||||
println(0, "Failed loading template \""+config.TemplateDir+"/global_footer.html: \""+err.Error())
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
global_header_tmpl, err = loadTemplate("global_header_tmpl", "global_header.html", "")
|
||||
if err != nil {
|
||||
println(0, "Failed loading template \""+config.TemplateDir+"/global_header.html: \""+err.Error())
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
img_header_tmpl, err = loadTemplate("img_header_tmpl", "img_header.html",
|
||||
"{{$config := getInterface .Data 0}}"+
|
||||
"{{$board_arr := (getInterface .Data 1).Data}}"+
|
||||
"{{$section_arr := (getInterface .Data 2).Data}}"+
|
||||
"{{$post_arr := (getInterface .Data 3).Data}}"+
|
||||
"{{$op := getElement $post_arr 0}}"+
|
||||
"{{$board := getElement $board_arr (subtract $op.BoardID 1)}}")
|
||||
if err != nil {
|
||||
println(0, "Failed loading template \""+config.TemplateDir+"/img_header.html: \""+err.Error())
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
img_boardpage_tmpl, err = loadTemplate("img_boardpage_tmpl", "img_boardpage.html",
|
||||
"{{$config := getInterface .Data 0}}"+
|
||||
"{{$board_arr := (getInterface .Data 1).Data}}"+
|
||||
"{{$section_arr := (getInterface .Data 2).Data}}"+
|
||||
"{{$thread_arr := (getInterface .Data 3).Data}}"+
|
||||
"{{$board_info := (getInterface .Data 4).Data}}"+
|
||||
"{{$board := getInterface $board_info 0}}")
|
||||
if err != nil {
|
||||
println(0, "Failed loading template \""+config.TemplateDir+"/img_boardpage.html: \""+err.Error())
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
img_threadpage_tmpl, err = loadTemplate("img_threadpage_tmpl", "img_threadpage.html",
|
||||
"{{$config := getInterface .Data 0}}"+
|
||||
"{{$board_arr := (getInterface .Data 1).Data}}"+
|
||||
"{{$section_arr := (getInterface .Data 2).Data}}"+
|
||||
"{{$post_arr := (getInterface .Data 3).Data}}"+
|
||||
"{{$op := getElement $post_arr 0}}"+
|
||||
"{{$board := getElement $board_arr (subtract $op.BoardID 1)}}")
|
||||
if err != nil {
|
||||
println(0, "Failed loading template \""+config.TemplateDir+"/img_threadpage.html: \""+err.Error())
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
manage_header_tmpl, err = loadTemplate("manage_header_tmpl", "manage_header.html", "")
|
||||
if err != nil {
|
||||
println(0, "Failed loading template \""+config.TemplateDir+"/manage_header.html: \""+err.Error())
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
manage_boards_tmpl, err = loadTemplate("manage_boards_tmpl", "manage_boards.html",
|
||||
"{{$config := getInterface .Data 0}}"+
|
||||
"{{$board := getInterface (getInterface .Data 1).Data 0}}"+
|
||||
"{{$section_arr := (getInterface .Data 2).Data}}")
|
||||
if err != nil {
|
||||
println(0, "Failed loading template \""+config.TemplateDir+"/manage_boards.html: \""+err.Error())
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
manage_config_tmpl, err = loadTemplate("manage_config_tmpl", "manage_config.html", "{{$config := getInterface .Data 0}}")
|
||||
if err != nil {
|
||||
println(0, "Failed loading template \""+config.TemplateDir+"/manage_config.html: \""+err.Error())
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
front_page_tmpl, err = loadTemplate("front_page_tmpl", "front.html",
|
||||
"{{$config := getInterface .Data 0}}"+
|
||||
"{{$page_arr := getInterface .Data 1}}"+
|
||||
"{{$board_arr := getInterface .Data 2}}"+
|
||||
"{{$section_arr := getInterface .Data 3}}"+
|
||||
"{{$recent_posts_arr := getInterface .Data 4}}")
|
||||
if err != nil {
|
||||
println(0, "Failed loading template \""+config.TemplateDir+"/front.html\": "+err.Error())
|
||||
os.Exit(2)
|
||||
}
|
||||
return "", err
|
||||
}
|
||||
|
||||
func getStyleLinks(w http.ResponseWriter, stylesheet string) {
|
||||
|
@ -376,9 +319,8 @@ func getStyleLinks(w http.ResponseWriter, stylesheet string) {
|
|||
styles_map[i] = config.Styles_img[i]
|
||||
}
|
||||
|
||||
err := manage_header_tmpl.Execute(w, config)
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
if err := manage_header_tmpl.Execute(w, config); err != nil {
|
||||
println(0, err.Error())
|
||||
os.Exit(2)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -418,8 +418,7 @@ func initConfig() {
|
|||
os.Exit(2)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(jfile, &config)
|
||||
if err != nil {
|
||||
if err = json.Unmarshal(jfile, &config); err != nil {
|
||||
printf(0, "Error parsing \"gochan.json\": %s\n", err.Error())
|
||||
os.Exit(2)
|
||||
}
|
||||
|
|
78
src/util.go
78
src/util.go
|
@ -4,6 +4,7 @@ import (
|
|||
"bytes"
|
||||
"crypto/md5"
|
||||
"crypto/sha1"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"html"
|
||||
"io"
|
||||
|
@ -74,6 +75,25 @@ func byteByByteReplace(input, from, to string) string {
|
|||
return input
|
||||
}
|
||||
|
||||
// for easier defer cleaning
|
||||
func closeFile(file *os.File) {
|
||||
if file != nil {
|
||||
file.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func closeRows(rows *sql.Rows) {
|
||||
if rows != nil {
|
||||
rows.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func closeStatement(stmt *sql.Stmt) {
|
||||
if stmt != nil {
|
||||
stmt.Close()
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Deletes files in a folder (root) that match a given regular expression.
|
||||
Returns the number of files that were deleted, and any error encountered.
|
||||
|
@ -166,23 +186,19 @@ func getBoardArr(parameterList map[string]interface{}, extra string) (boards []B
|
|||
printf(2, "queryString@getBoardArr: %s\n", queryString)
|
||||
|
||||
stmt, err := db.Prepare(queryString)
|
||||
defer func() {
|
||||
if stmt != nil {
|
||||
stmt.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
if err != nil {
|
||||
errorLog.Print(err.Error())
|
||||
return
|
||||
}
|
||||
defer closeStatement(stmt)
|
||||
|
||||
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() {
|
||||
board := new(BoardsTable)
|
||||
err = rows.Scan(
|
||||
board.IName = "board"
|
||||
if err = rows.Scan(
|
||||
&board.ID,
|
||||
&board.Order,
|
||||
&board.Dir,
|
||||
|
@ -208,11 +224,9 @@ func getBoardArr(parameterList map[string]interface{}, extra string) (boards []B
|
|||
&board.RedirectToThread,
|
||||
&board.RequireFile,
|
||||
&board.EnableCatalog,
|
||||
)
|
||||
board.IName = "board"
|
||||
if err != nil {
|
||||
); err != nil {
|
||||
errorLog.Print(err.Error())
|
||||
fmt.Println(err.Error())
|
||||
println(0, err.Error())
|
||||
return
|
||||
}
|
||||
boards = append(boards, *board)
|
||||
|
@ -243,16 +257,11 @@ func getPostArr(parameterList map[string]interface{}, extra string) (posts []int
|
|||
printf(2, "queryString@getPostArr queryString: %s\n", queryString)
|
||||
|
||||
stmt, err := db.Prepare(queryString)
|
||||
defer func() {
|
||||
if stmt != nil {
|
||||
stmt.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
if err != nil {
|
||||
errorLog.Print(err.Error())
|
||||
return
|
||||
}
|
||||
defer closeStatement(stmt)
|
||||
|
||||
rows, err := stmt.Query(parameterValues...)
|
||||
if err != nil {
|
||||
|
@ -261,20 +270,22 @@ func getPostArr(parameterList map[string]interface{}, extra string) (posts []int
|
|||
println(1, errortext)
|
||||
return
|
||||
}
|
||||
defer closeRows(rows)
|
||||
|
||||
// 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,
|
||||
post.IName = "post"
|
||||
if err = rows.Scan(&post.ID, &post.BoardID, &post.ParentID, &post.Name, &post.Tripcode,
|
||||
&post.Email, &post.Subject, &post.MessageHTML, &post.MessageText, &post.Password, &post.Filename,
|
||||
&post.FilenameOriginal, &post.FileChecksum, &post.Filesize, &post.ImageW,
|
||||
&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 {
|
||||
&post.Stickied, &post.Locked, &post.Reviewed, &post.Sillytag,
|
||||
); err != nil {
|
||||
errorLog.Print(err.Error())
|
||||
fmt.Println(err.Error())
|
||||
println(0, err.Error())
|
||||
return
|
||||
}
|
||||
posts = append(posts, post)
|
||||
|
@ -291,13 +302,13 @@ func getSectionArr(where string) (sections []interface{}, err error) {
|
|||
errorLog.Print(err.Error())
|
||||
return
|
||||
}
|
||||
defer closeRows(rows)
|
||||
|
||||
for rows.Next() {
|
||||
section := new(BoardSectionsTable)
|
||||
section.IName = "section"
|
||||
|
||||
err = rows.Scan(§ion.ID, §ion.Order, §ion.Hidden, §ion.Name, §ion.Abbreviation)
|
||||
if err != nil {
|
||||
if err = rows.Scan(§ion.ID, §ion.Order, §ion.Hidden, §ion.Name, §ion.Abbreviation); err != nil {
|
||||
errorLog.Print(err.Error())
|
||||
return
|
||||
}
|
||||
|
@ -367,13 +378,19 @@ func customError(v int, err error) (errored bool) {
|
|||
if err != nil {
|
||||
if config.Verbosity >= v {
|
||||
file, line, _ := getMetaInfo(1)
|
||||
fmt.Printf("[ERROR] %s:%d: %s\n", file, line, err.Error())
|
||||
printf(v, "[ERROR] %s:%d: %s\n", file, line, err.Error())
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func handleError(verbosity int, text string) string {
|
||||
printf(verbosity, text)
|
||||
errorLog.Println(text)
|
||||
return text
|
||||
}
|
||||
|
||||
func humanReadableTime(t time.Time) string {
|
||||
return t.Format(config.DateTimeFormat)
|
||||
}
|
||||
|
@ -475,6 +492,9 @@ func bToA(b bool) string {
|
|||
// Checks the validity of the Akismet API key given in the config file.
|
||||
func checkAkismetAPIKey() {
|
||||
resp, err := http.PostForm("https://rest.akismet.com/1.1/verify-key", url.Values{"key": {config.AkismetAPIKey}, "blog": {"http://" + config.SiteDomain}})
|
||||
if err != nil {
|
||||
handleError(1, err.Error())
|
||||
}
|
||||
defer func() {
|
||||
if resp != nil && resp.Body != nil {
|
||||
resp.Body.Close()
|
||||
|
@ -482,7 +502,7 @@ func checkAkismetAPIKey() {
|
|||
}()
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
errorLog.Print(err.Error())
|
||||
handleError(1, err.Error())
|
||||
}
|
||||
if string(body) == "invalid" {
|
||||
// This should disable the Akismet checks if the API key is not valid.
|
||||
|
@ -503,20 +523,20 @@ func checkPostForSpam(userIP string, userAgent string, referrer string,
|
|||
req, err := http.NewRequest("POST", "https://"+config.AkismetAPIKey+".rest.akismet.com/1.1/comment-check",
|
||||
strings.NewReader(data.Encode()))
|
||||
if err != nil {
|
||||
errorLog.Print(err.Error())
|
||||
handleError(1, err.Error())
|
||||
return "other_failure"
|
||||
}
|
||||
req.Header.Set("User-Agent", "gochan/1.0 | Akismet/0.1")
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
errorLog.Print(err.Error())
|
||||
handleError(1, err.Error())
|
||||
return "other_failure"
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
errorLog.Print(err.Error())
|
||||
handleError(1, err.Error())
|
||||
return "other_failure"
|
||||
}
|
||||
errorLog.Print("Response from Akismet: " + string(body))
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
<div id="footer">
|
||||
<a href="/">Home</a> | <a href="http://127.0.0.1:8080/#boards">Boards</a> | <a href="http://127.0.0.1:8080/#rules">Rules</a> | <a href="http://127.0.0.1:8080/#faq">FAQ</a><br />
|
||||
Powered by Gochan {{.Version}}<br />
|
||||
Generated in over 9000 hours
|
||||
<a href="{{$config.SiteWebfolder}}">Home</a> | <a href="{{$config.SiteWebfolder}}#boards">Boards</a> | <a href="{{$config.SiteWebfolder}}#rules">Rules</a> | <a href="{{$config.SiteWebfolder}}#faq">FAQ</a><br />
|
||||
Powered by <a href="http://github.com/eggbertx/gochan/">Gochan {{$config.Version}}</a><br />
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,36 +1,6 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>/{{$board.Dir}}/ - {{$board.Title}}</title>
|
||||
<script type="text/javascript" src="/javascript/jquery-3.3.1.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
var styles = [{{range $ii, $style := $config.Styles_img}}{{if gt $ii 0}}, {{end}}"{{$style}}"{{end}}];
|
||||
var webroot = "{{$config.SiteWebfolder}}";
|
||||
var thread_type = "board";
|
||||
</script>
|
||||
<script type="text/javascript" src="/javascript/gochan.js"></script>
|
||||
<script type="text/javascript" src="/javascript/manage.js"></script>
|
||||
<link rel="stylesheet" href="/css/global/img.css" />
|
||||
{{range $i, $style := $config.Styles_img}}
|
||||
<link rel="{{if isStyleNotDefault_img $style}}alternate {{end}}stylesheet" href="/css/{{$style}}/img.css" />{{end}}
|
||||
<link rel="shortcut icon" href="/favicon.png" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="topbar">
|
||||
{{range $i, $boardlink := $board_arr}}
|
||||
<a href="/{{$boardlink.Dir}}/" class="topbar-item">/{{$boardlink.Dir}}/</a>
|
||||
{{end}}
|
||||
</div>
|
||||
<div id="top-pane">
|
||||
<span id="board-title">{{$board.Title}}</span><br />
|
||||
<span id="board-subtitle">{{$board.Subtitle}}</span>
|
||||
</div>
|
||||
<hr />
|
||||
<div id="right-sidelinks">
|
||||
<a href="{{$config.SiteWebfolder}}{{$board.Dir}}/catalog.html">Board catalog</a><br />
|
||||
</div>
|
||||
|
||||
<div id="postbox-area">
|
||||
<form name="postform" action="/post" method="POST" enctype="multipart/form-data">
|
||||
<input type="hidden" name="threadid" value="0" />
|
||||
|
@ -81,16 +51,15 @@
|
|||
{{end}}{{end}}
|
||||
<div class="post-text">{{$reply.MessageHTML}}</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>{{end}}
|
||||
</div>
|
||||
<hr />
|
||||
{{end}}
|
||||
<hr />{{end}}
|
||||
<div id="right-bottom-content">
|
||||
<div id="report-delbox">
|
||||
<input type="hidden" name="board" value="{{$board.Dir}}" />
|
||||
<label>[<input type="checkbox" name="fileonly"/>File only]</label> <input type="password" size="10" name="password" id="delete-password" /> <input type="submit" name="delete_btn" value="Delete" onclick="return confirm('Are you sure you want to delete these posts?')" /><br />
|
||||
Reason: <input type="text" size="10" name="reason" id="reason" /> <input type="submit" value="Report" />
|
||||
Reason: <input type="text" size="10" name="reason" id="reason" /> <input type="submit" name="report_btn" value="Report" /><br />
|
||||
Edit post <input type="submit" name="edit_btn" value="Edit" />
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -117,10 +86,4 @@
|
|||
[{{range $i, $boardlink := $board_arr}} {{if gt $i 0}}/{{end}} <a href="/{{$boardlink.Dir}}/">{{$boardlink.Dir}}</a> {{end}}]
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<a href="{{$config.SiteWebfolder}}">Home</a> | <a href="{{$config.SiteWebfolder}}#boards">Boards</a> | <a href="{{$config.SiteWebfolder}}#rules">Rules</a> | <a href="{{$config.SiteWebfolder}}#faq">FAQ</a><br />
|
||||
Powered by <a href="http://github.com/eggbertx/gochan/">Gochan {{$config.Version}}</a><br />
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</div>
|
37
templates/img_header.html
Normal file
37
templates/img_header.html
Normal file
|
@ -0,0 +1,37 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
{{if stringNeq $op.Subject ""}}
|
||||
<title>/{{$board.Dir}}/ - {{truncateString $op.Subject 20 true}}</title>
|
||||
{{else}}{{if stringNeq $op.MessageHTML ""}}
|
||||
<title>/{{$board.Dir}}/ - {{truncateString $op.MessageText 20 true}}</title>
|
||||
{{end}}{{end}}
|
||||
<title>/{{$board.Dir}} - {{$board.Title}}</title>
|
||||
<script type="text/javascript" src="/javascript/jquery-3.3.1.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
var styles = [{{range $ii, $style := $config.Styles_img}}{{if gt $ii 0}}, {{end}}"{{$style}}"{{end}}];
|
||||
var webroot = "{{$config.SiteWebfolder}}";
|
||||
var thread_type = "thread";
|
||||
function changePage(sel) {
|
||||
window.location = webroot+"test/res/{{$op.ID}}p"+sel.value+".html";
|
||||
}
|
||||
</script>
|
||||
<script type="text/javascript" src="/javascript/gochan.js"></script>
|
||||
<script type="text/javascript" src="/javascript/manage.js"></script>
|
||||
<link rel="stylesheet" href="/css/global/img.css" />
|
||||
{{range $i, $style := $config.Styles_img}}
|
||||
<link rel="{{if isStyleNotDefault_img $style}}alternate {{end}}stylesheet" href="/css/{{$style}}/img.css" />{{end}}
|
||||
<link rel="shortcut icon" href="/favicon.png" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="topbar">
|
||||
{{range $i, $board := $board_arr}}
|
||||
<a href="/{{$board.Dir}}/" class="topbar-item">/{{$board.Dir}}/</a>
|
||||
{{end}}
|
||||
</div>
|
||||
<div id="top-pane">
|
||||
<span id="board-title">{{$board.Title}}</span><br />
|
||||
<span id="board-subtitle">{{$board.Subtitle}}</span>
|
||||
</div>
|
||||
<hr />
|
|
@ -1,40 +1,3 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
{{if stringNeq $op.Subject ""}}
|
||||
<title>/{{$board.Dir}}/ - {{truncateString $op.Subject 20 true}}</title>
|
||||
{{else}}{{if stringNeq $op.MessageHTML ""}}
|
||||
<title>/{{$board.Dir}}/ - {{truncateString $op.MessageText 20 true}}</title>
|
||||
{{end}}{{end}}
|
||||
<title>/{{$board.Dir}} - {{$board.Title}}</title>
|
||||
<script type="text/javascript" src="/javascript/jquery-3.3.1.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
var styles = [{{range $ii, $style := $config.Styles_img}}{{if gt $ii 0}}, {{end}}"{{$style}}"{{end}}];
|
||||
var webroot = "{{$config.SiteWebfolder}}";
|
||||
var thread_type = "thread";
|
||||
function changePage(sel) {
|
||||
window.location = webroot+"test/res/"+{{$op.ID}}+"p"+sel.value+".html";
|
||||
}
|
||||
</script>
|
||||
<script type="text/javascript" src="/javascript/gochan.js"></script>
|
||||
<script type="text/javascript" src="/javascript/manage.js"></script>
|
||||
<link rel="stylesheet" href="/css/global/img.css" />
|
||||
{{range $i, $style := $config.Styles_img}}
|
||||
<link rel="{{if isStyleNotDefault_img $style}}alternate {{end}}stylesheet" href="/css/{{$style}}/img.css" />{{end}}
|
||||
<link rel="shortcut icon" href="/favicon.png" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="topbar">
|
||||
{{range $i, $board := $board_arr}}
|
||||
<a href="/{{$board.Dir}}/" class="topbar-item">/{{$board.Dir}}/</a>
|
||||
{{end}}
|
||||
</div>
|
||||
<div id="top-pane">
|
||||
<span id="board-title">{{$board.Title}}</span><br />
|
||||
<span id="board-subtitle">{{$board.Subtitle}}</span>
|
||||
</div>
|
||||
<hr />
|
||||
<div id="threadlinks-top">
|
||||
<a href="{{$config.SiteWebfolder}}{{$board.Dir}}/board.html" >Return</a><br />
|
||||
<select id="changepage" onchange="changePage(this)">
|
||||
|
@ -50,7 +13,6 @@
|
|||
<div id="right-sidelinks">
|
||||
<a href="{{$config.SiteWebfolder}}{{$board.Dir}}/catalog.html">Board catalog</a><br />
|
||||
</div>
|
||||
|
||||
<div id="postbox-area">
|
||||
<form name="postform" action="/post" method="POST" enctype="multipart/form-data">
|
||||
<input type="hidden" name="threadid" value="{{$op.ID}}" />
|
||||
|
@ -77,8 +39,7 @@
|
|||
<a class="upload-container" href="{{$config.SiteWebfolder}}{{$board.Dir}}/src/{{$op.Filename}}"><img src="{{$config.SiteWebfolder}}{{$board.Dir}}/thumb/{{imageToThumbnailPath $op.Filename}}" width="{{$op.ThumbW}}" height="{{$op.ThumbH}}" class="upload" /></a>
|
||||
{{else}}
|
||||
<div class="file-deleted-box" style="text-align:center;">File removed</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{end}}{{end}}
|
||||
<input type="checkbox" id="check{{$op.ID}}" name="check{{$op.ID}}" /><label class="post-info" for="check{{$op.ID}}"> <span class="subject">{{$op.Subject}}</span> <span class="postername">{{if stringNeq $op.Email ""}}<a href="mailto:{{$op.Email}}">{{end}}{{if stringNeq $op.Name ""}}{{$op.Name}}{{else}}{{if stringEq $op.Tripcode ""}}{{$board.Anonymous}}{{end}}{{end}}{{if stringNeq $op.Email ""}}</a>{{end}}</span>{{if stringNeq $op.Tripcode ""}}<span class="tripcode">!{{$op.Tripcode}}</span>{{end}} {{formatTimestamp $op.Timestamp}} </label><a href="/{{$board.Dir}}/res/{{$op.ID}}.html#{{$op.ID}}">No.</a> <a href="javascript:quote({{$op.ID}})" class="backlink-click">{{$op.ID}}</a> <span class="post-links"> <span class="thread-ddown">[<a href="javascript:void(0)">▼</a>]</span></span><br />
|
||||
<div class="post-text">{{$op.MessageHTML}}</div>
|
||||
</div>
|
||||
|
@ -96,15 +57,15 @@
|
|||
{{end}}{{end}}
|
||||
<div class="post-text">{{$reply.MessageHTML}}</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}{{end}}
|
||||
</div>{{end}}{{end}}
|
||||
</div>
|
||||
<hr />
|
||||
<div id="right-bottom-content">
|
||||
<div id="report-delbox">
|
||||
<input type="hidden" name="board" value="{{$board.Dir}}" />
|
||||
<label>[<input type="checkbox" name="fileonly"/>File only]</label> <input type="password" size="10" name="password" id="delete-password" /> <input type="submit" name="delete_btn" value="Delete" onclick="return confirm('Are you sure you want to delete these posts?')" /><br />
|
||||
Reason: <input type="text" size="10" name="reason" id="reason" /> <input type="submit" value="Report" />
|
||||
Reason: <input type="text" size="10" name="reason" id="reason" /> <input type="submit" name="report_btn" value="Report" /><br />
|
||||
Edit post <input type="submit" name="edit_btn" value="Edit" />
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -129,10 +90,4 @@
|
|||
[{{range $i, $boardlink := $board_arr}} {{if gt $i 0}}/{{end}} <a href="/{{$boardlink.Dir}}/">{{$boardlink.Dir}}</a> {{end}}]
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<a href="{{$config.SiteWebfolder}}">Home</a> | <a href="{{$config.SiteWebfolder}}#boards">Boards</a> | <a href="{{$config.SiteWebfolder}}#rules">Rules</a> | <a href="{{$config.SiteWebfolder}}#faq">FAQ</a><br />
|
||||
Powered by <a href="http://github.com/eggbertx/gochan/">Gochan {{$config.Version}}</a><br />
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</div>
|
Loading…
Add table
Add a link
Reference in a new issue