//Make makes and returns record from Recstr func Make(line string) (*Record, error) { line = strings.TrimRight(line, "\r\n") buf := strings.Split(line, "<>") if len(buf) <= 2 || buf[0] == "" || buf[1] == "" || buf[2] == "" { err := errors.New("illegal format") return nil, err } idstr := buf[0] + "_" + buf[1] dec := util.FileDecode(buf[2]) if dec == "" || !strings.HasPrefix(buf[2], "thread_") { err := errors.New("illegal format " + buf[2]) // log.Println(err) return nil, err } buf[2] = util.FileEncode("thread", dec) vr, err := NewIDstr(buf[2], idstr) if err != nil { return nil, err } if err := vr.Parse(line); err != nil { log.Println(err) return nil, err } return vr, nil }
//checkInfo checks posted info and returs thread name. //if ok. func (m *mchCGI) checkInfo(info map[string]string) string { var key string if info["subject"] != "" { key = util.FileEncode("thread", info["subject"]) } else { n, err := strconv.ParseInt(info["key"], 10, 64) if err != nil { m.errorResp(err.Error(), info) return "" } key = keylib.GetFilekey(n) } switch { case info["body"] == "": m.errorResp("本文がありません.", info) return "" case thread.NewCache(key).Exists(), m.HasAuth(): case info["subject"] != "": m.errorResp("掲示版を作る権限がありません", info) return "" default: m.errorResp("掲示版がありません", info) return "" } if info["subject"] == "" && key == "" { m.errorResp("フォームが変です.", info) return "" } return key }
//printThreadAjax renders records in cache id for ajax. func (t *threadCGI) printThreadAjax(id string) { th := strings.Split(t.Path(), "/")[0] filePath := util.FileEncode("thread", th) ca := thread.NewCache(filePath) if !ca.HasRecord() { log.Println(filePath, "not found") return } fmt.Fprintln(t.WR, "<dl>") recs := ca.LoadRecords(record.Alive) for _, rec := range recs { if id == "" || rec.ID[:8] == id && rec.Load() == nil { t.printRecord(ca, rec) } } fmt.Fprintln(t.WR, "</dl>") }
//MakeBracketLink changes str in brackets to the html links format. func MakeBracketLink(body, datHost, board string, table *mch.ResTable) string { regs := []*regexp.Regexp{ regexp.MustCompile("^(?P<title>[^/]+)$"), regexp.MustCompile("^/(?P<type>[a-z]+)/(?P<title>[^/]+)$"), regexp.MustCompile("^(?P<title>[^/]+)/(?P<id>[0-9a-f]{8})$"), regexp.MustCompile("^/(?P<type>[a-z]+)/(?P<title>[^/]+)/(?P<id>[0-9a-f]{8})$"), } reg := regexp.MustCompile(`\[\[([^<>]+?)\]\]`) return reg.ReplaceAllStringFunc(body, func(str string) string { link := reg.FindStringSubmatch(str)[1] result := make(map[string]string) for _, r := range regs { if match := r.FindStringSubmatch(link); match != nil { for i, name := range r.SubexpNames() { result[name] = match[i] } break } } if result["title"] == "" { return result["body"] } if result["type"] == "" { result["type"] = "thread" } file := util.FileEncode(result["type"], result["title"]) datkey, err := GetDatkey(file) if err != nil { log.Println(err) return body } if result["id"] == "" { url := fmt.Sprintf("http://%s/test/read.cgi/%s/%d/", datHost, board, datkey) return fmt.Sprintf("[[%s(%s)]]", result["title"], url) } ca := thread.NewCache(file) table = mch.NewResTable(ca) no := table.ID2num[result["id"]] url := fmt.Sprintf("http://%s/test/read.cgi/%s/%d/%d", datHost, board, datkey, no) return fmt.Sprintf("[[%s(>>%d %s)]]", result["title"], no, url) }) }
//printThread renders whole thread list page. func (t *threadCGI) printThread(path, id string, nPage int) { if id != "" && t.Req.FormValue("ajax") != "" { t.printThreadAjax(id) return } filePath := util.FileEncode("thread", path) ca := thread.NewCache(filePath) rss := cfg.GatewayURL + "/rss" if t.printThreadHead(path, id, nPage, ca, rss) != nil { return } tags := strings.Fields(strings.TrimSpace(t.Req.FormValue("tag"))) if t.IsAdmin() && len(tags) > 0 { user.Add(ca.Datfile, tags) } t.printTag(ca) t.printThreadTop(path, id, nPage, ca) t.printPageNavi(path, nPage, ca, id) t.printThreadBody(id, nPage, ca) escapedPath := html.EscapeString(path) escapedPath = strings.Replace(escapedPath, " ", " ", -1) ss := struct { Cache *thread.Cache Message cgi.Message }{ ca, t.M, } cgi.RenderTemplate("thread_bottom", ss, t.WR) if ca.HasRecord() { t.printPageNavi(path, nPage, ca, id) fmt.Fprintf(t.WR, "</p>") } t.printPostForm(ca) t.printTag(ca) t.RemoveFileForm(ca, escapedPath) t.Footer(t.MakeMenubar("bottom", rss)) }