Ver Fonte

마크다운 최소한 기능 추가

잉여개발기 há 2 anos atrás
pai
commit
7235e1c444

+ 0 - 2
route/bbs_w_delete.py

@@ -40,8 +40,6 @@ def bbs_w_delete(bbs_num = '', post_num = '', comment_num = ''):
 
 
                 set_code = comment_num_split[len(comment_num_split) - 1]
                 set_code = comment_num_split[len(comment_num_split) - 1]
 
 
-                print(set_id, set_code)
-
                 curs.execute(db_change("update bbs_data set set_data = '' where set_code = ? and set_id = ?"), [set_code, set_id])
                 curs.execute(db_change("update bbs_data set set_data = '' where set_code = ? and set_id = ?"), [set_code, set_id])
                 
                 
                 return redirect(conn, '/bbs/w/' + bbs_num_str + '/' + post_num_str)
                 return redirect(conn, '/bbs/w/' + bbs_num_str + '/' + post_num_str)

+ 2 - 1
route/go_api_w_render.py

@@ -54,6 +54,8 @@ def api_w_render(db_set, name = '', tool = ''):
                 data_type = 'api_from'
                 data_type = 'api_from'
             elif tool == 'include':
             elif tool == 'include':
                 data_type = 'api_include'
                 data_type = 'api_include'
+            elif tool == 'backlink':
+                data_type = 'backlink'
             else:
             else:
                 data_type = 'api_thread'
                 data_type = 'api_thread'
 
 
@@ -99,7 +101,6 @@ def api_w_render(db_set, name = '', tool = ''):
                         data = subprocess.Popen([os.path.join(".", "route_go", "bin", "main.arm64.exe"), sys._getframe().f_code.co_name, db_set, other_set], stdout = subprocess.PIPE).communicate()[0]
                         data = subprocess.Popen([os.path.join(".", "route_go", "bin", "main.arm64.exe"), sys._getframe().f_code.co_name, db_set, other_set], stdout = subprocess.PIPE).communicate()[0]
 
 
                 data = data.decode('utf8')
                 data = data.decode('utf8')
-                print(data)
 
 
                 return flask.Response(response = data, status = 200, mimetype = 'application/json')
                 return flask.Response(response = data, status = 200, mimetype = 'application/json')
         else:
         else:

BIN
route_go/bin/main.amd64.bin


BIN
route_go/bin/main.amd64.exe


BIN
route_go/bin/main.arm64.bin


BIN
route_go/bin/main.arm64.exe


+ 1 - 0
route_go/go.mod

@@ -8,6 +8,7 @@ require (
 	github.com/go-sql-driver/mysql v1.8.0
 	github.com/go-sql-driver/mysql v1.8.0
 	github.com/microcosm-cc/bluemonday v1.0.26
 	github.com/microcosm-cc/bluemonday v1.0.26
 	github.com/russross/blackfriday/v2 v2.1.0
 	github.com/russross/blackfriday/v2 v2.1.0
+	github.com/yuin/goldmark v1.7.0
 	modernc.org/sqlite v1.29.5
 	modernc.org/sqlite v1.29.5
 )
 )
 
 

+ 2 - 0
route_go/go.sum

@@ -41,6 +41,8 @@ github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNl
 github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
 github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
 github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.7.0 h1:EfOIvIMZIzHdB/R/zVrikYLPPwJlfMcNczJFMs1m6sA=
+github.com/yuin/goldmark v1.7.0/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=

+ 3 - 3
route_go/route/api_recent_change.go

@@ -47,13 +47,13 @@ func Api_recent_change(call_arg []string) {
 	}
 	}
 	defer rows.Close()
 	defer rows.Close()
 
 
-	var id string
-	var title string
-
 	var data_list [][]string
 	var data_list [][]string
 	admin_auth := tool.Get_admin_auth(db, db_set, other_set["ip"])
 	admin_auth := tool.Get_admin_auth(db, db_set, other_set["ip"])
 
 
 	for rows.Next() {
 	for rows.Next() {
+		var id string
+		var title string
+
 		err := rows.Scan(&id, &title)
 		err := rows.Scan(&id, &title)
 		if err != nil {
 		if err != nil {
 			return
 			return

+ 85 - 0
route_go/route/api_recent_discuss.go

@@ -0,0 +1,85 @@
+package route
+
+import (
+	"database/sql"
+	"encoding/json"
+	"opennamu/route/tool"
+	"strconv"
+)
+
+func Api_recent_discuss(call_arg []string) {
+	db_set := map[string]string{}
+	json.Unmarshal([]byte(call_arg[0]), &db_set)
+
+	other_set := map[string]string{}
+	json.Unmarshal([]byte(call_arg[1]), &other_set)
+
+	db := tool.DB_connect(db_set)
+	if db == nil {
+		return
+	}
+	defer db.Close()
+
+	limit_int, err := strconv.Atoi(other_set["limit"])
+	if err != nil {
+		return
+	}
+
+	if limit_int > 50 || limit_int < 0 {
+		limit_int = 50
+	}
+
+	var stmt *sql.Stmt
+
+	set_type := other_set["set_type"]
+	if set_type == "normal" {
+		stmt, err = db.Prepare(tool.DB_change(db_set, "select title, sub, date, code from rd where not stop = 'O' order by date desc limit ?"))
+	} else if set_type == "close" {
+		stmt, err = db.Prepare(tool.DB_change(db_set, "select title, sub, date, code from rd where stop = 'O' order by date desc limit ?"))
+	} else {
+		stmt, err = db.Prepare(tool.DB_change(db_set, "select title, sub, date, code from rd where stop != 'O' order by date asc limit ?"))
+	}
+
+	if err != nil {
+		return
+	}
+	defer stmt.Close()
+
+	rows, err := stmt.Query(limit_int)
+	if err != nil {
+		return
+	}
+	defer rows.Close()
+
+	// var data_list [][]string
+	// admin_auth := tool.Get_admin_auth(db, db_set, other_set["ip"])
+
+	for rows.Next() {
+		var title string
+		var sub string
+		var date string
+		var code string
+
+		err := rows.Scan(&title, &sub, &date, &code)
+		if err != nil {
+			return
+		}
+
+		stmt, err := db.Prepare(tool.DB_change(db_set, "select ip from topic where code = ? order by id + 0 desc limit 1"))
+		if err != nil {
+			return
+		}
+		defer stmt.Close()
+
+		var ip string
+
+		err = stmt.QueryRow(code).Scan(&ip)
+		if err != nil {
+			if err == sql.ErrNoRows {
+				ip = ""
+			} else {
+				return
+			}
+		}
+	}
+}

+ 80 - 6
route_go/route/tool/markdown.go

@@ -1,22 +1,96 @@
 package tool
 package tool
 
 
 import (
 import (
+	"bytes"
 	"database/sql"
 	"database/sql"
+	"regexp"
 
 
-	"github.com/microcosm-cc/bluemonday"
-	"github.com/russross/blackfriday/v2"
+	"github.com/yuin/goldmark"
+	"github.com/yuin/goldmark/extension"
+	"github.com/yuin/goldmark/renderer/html"
 )
 )
 
 
 func Markdown(db *sql.DB, db_set map[string]string, data map[string]string) map[string]interface{} {
 func Markdown(db *sql.DB, db_set map[string]string, data map[string]string) map[string]interface{} {
 	input := []byte(data["data"])
 	input := []byte(data["data"])
+	backlink := map[string]map[string]string{}
+	link_count := 0
 
 
-	unsafe := blackfriday.Run(input)
-	html := bluemonday.UGCPolicy().SanitizeBytes(unsafe)
+	markdown := goldmark.New(
+		goldmark.WithExtensions(extension.Strikethrough, extension.Table),
+		goldmark.WithRendererOptions(html.WithHardWraps()),
+	)
+
+	var buf bytes.Buffer
+	if err := markdown.Convert(input, &buf); err != nil {
+		panic(err)
+	}
+
+	string_data := buf.String()
+
+	r := regexp.MustCompile(`\[([^\[\]]+)\]\(([^\(\)]*)\)`)
+	string_data = r.ReplaceAllStringFunc(string_data, func(m string) string {
+		match := r.FindStringSubmatch(m)
+
+		return "<a href=\"" + match[2] + "\">" + match[1] + "</a>"
+	})
+
+	// p := bluemonday.UGCPolicy()
+	// result := p.Sanitize(string_data)
+
+	r = regexp.MustCompile(`<a href="([^"]+)"`)
+	result := r.ReplaceAllStringFunc(string_data, func(m string) string {
+		match := r.FindStringSubmatch(m)
+
+		m1, _ := regexp.MatchString(`^https?:\/\/`, match[1])
+		if m1 {
+			return "<a href=\"" + match[1] + "\" class=\"opennamu_link_out\" target=\"_blank\""
+		} else {
+			if _, ok := backlink[match[1]]; !ok {
+				backlink[match[1]] = map[string]string{}
+			}
+
+			var exist string
+
+			stmt, err := db.Prepare(DB_change(db_set, "select title from data where title = ?"))
+			if err != nil {
+				exist = ""
+			}
+			defer stmt.Close()
+
+			err = stmt.QueryRow(match[1]).Scan(&exist)
+			if err != nil {
+				exist = ""
+			}
+
+			backlink[match[1]][""] = ""
+			link_count += 1
+
+			class := ""
+			if exist == "" {
+				class = "opennamu_not_exist_link"
+			}
+
+			return "<a href=\"/w/" + match[1] + "\" class=\"" + class + "\""
+		}
+	})
+
+	end_backlink := [][]string{}
+	for k1, v1 := range backlink {
+		for k2, v2 := range v1 {
+			end_backlink = append(end_backlink, []string{
+				data["doc_name"],
+				k1,
+				k2,
+				v2,
+			})
+		}
+	}
 
 
 	end_data := make(map[string]interface{})
 	end_data := make(map[string]interface{})
-	end_data["data"] = string(html)
+	end_data["data"] = result
 	end_data["js_data"] = ""
 	end_data["js_data"] = ""
-	end_data["backlink"] = []string{}
+	end_data["backlink"] = end_backlink
+	end_data["link_count"] = link_count
 
 
 	return end_data
 	return end_data
 }
 }

+ 2 - 1
route_go/route/tool/namumark.go

@@ -4,7 +4,8 @@ func Namumark() map[string]interface{} {
 	end_data := make(map[string]interface{})
 	end_data := make(map[string]interface{})
 	end_data["data"] = ""
 	end_data["data"] = ""
 	end_data["js_data"] = ""
 	end_data["js_data"] = ""
-	end_data["backlink"] = []string{}
+	end_data["backlink"] = [][]string{}
+	end_data["link_count"] = 0
 
 
 	return end_data
 	return end_data
 }
 }

+ 102 - 3
route_go/route/tool/render.go

@@ -9,7 +9,7 @@ import (
 func Get_render(db *sql.DB, db_set map[string]string, doc_name string, data string, render_type string) map[string]string {
 func Get_render(db *sql.DB, db_set map[string]string, doc_name string, data string, render_type string) map[string]string {
 	var markup string
 	var markup string
 
 
-	if render_type == "api_view" || render_type == "api_from" || render_type == "api_include" {
+	if render_type == "api_view" || render_type == "api_from" || render_type == "api_include" || render_type == "backlink" {
 		stmt, err := db.Prepare(DB_change(db_set, "select set_data from data_set where doc_name = ? and set_name = 'document_markup'"))
 		stmt, err := db.Prepare(DB_change(db_set, "select set_data from data_set where doc_name = ? and set_name = 'document_markup'"))
 		if err != nil {
 		if err != nil {
 			return map[string]string{}
 			return map[string]string{}
@@ -50,11 +50,28 @@ func Get_render(db *sql.DB, db_set map[string]string, doc_name string, data stri
 }
 }
 
 
 func Get_render_direct(db *sql.DB, db_set map[string]string, doc_name string, data string, markup string, render_name string, render_type string) map[string]string {
 func Get_render_direct(db *sql.DB, db_set map[string]string, doc_name string, data string, markup string, render_name string, render_type string) map[string]string {
+	from := ""
+	include := ""
+	backlink := ""
+	if render_type == "api_include" {
+		include = "1"
+	} else if render_type == "api_from" {
+		from = "1"
+	} else if render_type == "backlink" {
+		backlink = "1"
+	}
+
+	if render_type == "api_view" || render_type == "api_from" || render_type == "api_include" || render_type == "backlink" {
+		render_type = "view"
+	}
+
 	doc_data_set := map[string]string{
 	doc_data_set := map[string]string{
 		"doc_name":    doc_name,
 		"doc_name":    doc_name,
 		"data":        data,
 		"data":        data,
 		"render_name": render_name,
 		"render_name": render_name,
 		"render_type": render_type,
 		"render_type": render_type,
+		"from":        from,
+		"include":     include,
 	}
 	}
 
 
 	render_data := make(map[string]interface{})
 	render_data := make(map[string]interface{})
@@ -63,9 +80,91 @@ func Get_render_direct(db *sql.DB, db_set map[string]string, doc_name string, da
 	} else if markup == "markdown" {
 	} else if markup == "markdown" {
 		render_data = Markdown(db, db_set, doc_data_set)
 		render_data = Markdown(db, db_set, doc_data_set)
 	} else {
 	} else {
-		render_data["data"] = data
+		render_data["data"] = "<div id=\"opennamu_render_complete\">" + data + "</div>"
 		render_data["js_data"] = ""
 		render_data["js_data"] = ""
-		render_data["backlink"] = []string{}
+		render_data["backlink"] = [][]string{}
+	}
+
+	if backlink == "1" {
+		stmt, err := db.Prepare(DB_change(db_set, "delete from back where link = ?"))
+		if err != nil {
+			return map[string]string{}
+		}
+		defer stmt.Close()
+
+		_, err = stmt.Exec(doc_name)
+		if err != nil {
+			return map[string]string{}
+		}
+
+		stmt, err = db.Prepare(DB_change(db_set, "delete from back where title = ? and type = 'no'"))
+		if err != nil {
+			return map[string]string{}
+		}
+		defer stmt.Close()
+
+		_, err = stmt.Exec(doc_name)
+		if err != nil {
+			return map[string]string{}
+		}
+
+		stmt, err = db.Prepare(DB_change(db_set, "delete from data_set where doc_name = ? and set_name = 'link_count'"))
+		if err != nil {
+			return map[string]string{}
+		}
+		defer stmt.Close()
+
+		_, err = stmt.Exec(doc_name)
+		if err != nil {
+			return map[string]string{}
+		}
+
+		stmt, err = db.Prepare(DB_change(db_set, "delete from data_set where doc_name = ? and set_name = 'doc_type'"))
+		if err != nil {
+			return map[string]string{}
+		}
+		defer stmt.Close()
+
+		_, err = stmt.Exec(doc_name)
+		if err != nil {
+			return map[string]string{}
+		}
+
+		end_backlink := render_data["backlink"].([][]string)
+		for for_a := 0; for_a < len(end_backlink); for_a++ {
+			stmt, err := db.Prepare(DB_change(db_set, "insert into back (link, title, type, data) values (?, ?, ?, ?)"))
+			if err != nil {
+				return map[string]string{}
+			}
+			defer stmt.Close()
+
+			_, err = stmt.Exec(end_backlink[0], end_backlink[1], end_backlink[2])
+			if err != nil {
+				return map[string]string{}
+			}
+		}
+
+		stmt, err = db.Prepare(DB_change(db_set, "insert into data_set (doc_name, doc_rev, set_name, set_data) values (?, '', 'link_count', ?)"))
+		if err != nil {
+			return map[string]string{}
+		}
+		defer stmt.Close()
+
+		_, err = stmt.Exec(doc_name, render_data["link_count"].(int))
+		if err != nil {
+			return map[string]string{}
+		}
+
+		stmt, err = db.Prepare(DB_change(db_set, "insert into data_set (doc_name, doc_rev, set_name, set_data) values (?, '', 'doc_type', ?)"))
+		if err != nil {
+			return map[string]string{}
+		}
+		defer stmt.Close()
+
+		_, err = stmt.Exec(doc_name, "")
+		if err != nil {
+			return map[string]string{}
+		}
 	}
 	}
 
 
 	return map[string]string{
 	return map[string]string{