//MakeBody makes a dat body(message) line after stamp. func MakeBody(rec *record.Record, host, board string, table *mch.ResTable) string { body := rec.GetBodyValue("body", "") body += rec.MakeAttachLink(host) body = table.MakeRSSAnchor(body) body = MakeBracketLink(body, host, board, table) return body }
//renderAttach render the content of attach file with content-type=typ. func (t *threadCGI) renderAttach(rec *record.Record, suffix string, stamp int64, thumbnailSize string) { attachFile := rec.AttachPath(thumbnailSize) if attachFile == "" { return } typ := mime.TypeByExtension("." + suffix) if typ == "" { typ = "text/plain" } t.WR.Header().Set("Content-Type", typ) t.WR.Header().Set("Last-Modified", t.RFC822Time(stamp)) if !util.IsValidImage(typ, attachFile) { t.WR.Header().Set("Content-Disposition", "attachment") } decoded, err := base64.StdEncoding.DecodeString(rec.GetBodyValue("attach", "")) if err != nil { log.Println(err) t.Print404(nil, "") return } if thumbnailSize != "" && (cfg.ForceThumbnail || thumbnailSize == cfg.DefaultThumbnailSize) { decoded = util.MakeThumbnail(decoded, suffix, thumbnailSize) } _, err = t.WR.Write(decoded) if err != nil { log.Println(err) t.Print404(nil, "") } }
//doUpdateNode broadcast and get data for each new records. //if can get data (even if spam) return true, if fails to get, return false. //if no fail, broadcast updates to node in cache and added n to nodelist and searchlist. func doUpdateNode(rec *record.Record, n *node.Node) bool { mutex.Lock() deleteOldUpdated() if _, exist := updated[rec.Hash()]; exist { log.Println("already broadcasted", rec.ID) mutex.Unlock() return true } updated[rec.Hash()] = time.Now() mutex.Unlock() ca := thread.NewCache(rec.Datfile) var err error if !ca.Exists() || n == nil { log.Println("no cache or updates by myself, broadcast updates.") UpdatedRecord.register(rec.Head) manager.TellUpdate(ca.Datfile, rec.Stamp, rec.ID, n) if UpdatedRecord.wait() || n != nil { log.Println(rec.ID, "was gotten or don't have the record") } else { log.Println(rec.ID, "was NOT gotten, will call updates later") go func() { time.Sleep(10 * time.Minute) UpdateNodes(rec, n) }() } return true } log.Println("cache exists. get record from node n.") err = rec.GetData(n) switch err { case cfg.ErrGet: log.Println("could not get") return false case cfg.ErrSpam: log.Println("marked spam") return true default: log.Println("telling update") manager.TellUpdate(ca.Datfile, rec.Stamp, rec.ID, nil) manager.Join(n) return true } }
//printRecord renders record.txt , with records in cache ca. func (t *threadCGI) printRecord(ca *thread.Cache, rec *record.Record) { thumbnailSize := "" var suffix string var attachSize int64 if at := rec.GetBodyValue("attach", ""); at != "" { suffix = rec.GetBodyValue("suffix", "") attachFile := rec.AttachPath("") attachSize = int64(len(at)*57/78) + 1000 reg := regexp.MustCompile("^[0-9A-Za-z]+") if !reg.MatchString(suffix) { suffix = cfg.SuffixTXT } typ := mime.TypeByExtension("." + suffix) if typ == "" { typ = "text/plain" } if util.IsValidImage(typ, attachFile) { thumbnailSize = cfg.DefaultThumbnailSize } } body := rec.GetBodyValue("body", "") body = t.HTMLFormat(body, cfg.ThreadURL, t.Path(), false) removeID := rec.GetBodyValue("remove_id", "") if len(removeID) > 8 { removeID = removeID[:8] } resAnchor := t.ResAnchor(removeID, cfg.ThreadURL, t.Path(), false) id8 := rec.ID if len(id8) > 8 { id8 = id8[:8] } s := struct { Datfile string Rec *record.Record RecHead record.Head Sid string AttachSize int64 Suffix string Body template.HTML Thumbnail string RemoveID string ResAnchor string cgi.Defaults }{ ca.Datfile, rec, rec.CopyHead(), id8, attachSize, suffix, template.HTML(body), thumbnailSize, removeID, resAnchor, *t.Defaults(), } cgi.RenderTemplate("record", s, t.WR) }