func (self RedisDB) GetPost(messageID string) (*model.Post, error) { var p model.Post cmd := self.client.HGetAll(ARTICLE_POST_PREFIX + messageID) hashres, err := cmd.Result() if err == nil { mapRes := processHashResult(hashres) p.Board = mapRes["newsgroup"] p.Message_id = mapRes["message_id"] p.Parent = mapRes["ref_id"] p.PostName = mapRes["name"] p.PostSubject = mapRes["subject"] p.MessagePath = mapRes["path"] tmp, _ := strconv.Atoi(mapRes["time_posted"]) p.Posted = int64(tmp) p.Addr = mapRes["addr"] p.PostMessage = mapRes["message"] p.OP = len(p.Parent) == 0 if len(p.Parent) == 0 { p.Parent = p.Message_id } p.Sage = util.IsSage(p.PostSubject) atts, err := self.GetPostAttachments(messageID) if atts != nil { p.Files = append(p.Files, atts...) } // quiet fail p.Key, _ = self.client.Get(ARTICLE_KEY_PREFIX + messageID).Result() return &p, err } return &p, err }
// register a message with the database func (self RedisDB) RegisterArticle(message *model.Article) (err error) { pipe := self.client.Pipeline() defer pipe.Close() msgid := message.MessageID group := message.Newsgroup has, _ := self.HasNewsgroup(group) if !has { self.RegisterNewsgroup(group) } has, _ = self.HasArticle(msgid) if has { return } //insert IP addr := message.Addr ip := net.ParseIP(addr) if ip != nil { addr = util.ZeroIPString(ip) pipe.ZAddNX(IP_RANGE_BAN_KR, redis.Z{Score: 0.0, Member: addr}) } pipe.SAdd(IP_ARTICLE_KR_PREFIX+addr, msgid) now := util.TimeNow() // insert article metadata pipe.HMSet(ARTICLE_PREFIX+msgid, "msgid", msgid, "message_id_hash", util.HashMessageID(msgid), "message_newsgroup", group, "time_obtained", strconv.Itoa(int(now)), "message_ref_id", message.Reference) pipe.Set(HASH_MESSAGEID_PREFIX+util.HashMessageID(msgid), msgid, 0) // update newsgroup pipe.ZAddXX(GROUP_POSTTIME_WKR, redis.Z{Score: float64(now), Member: group}) pipe.ZAddNX(GROUP_ARTICLE_POSTTIME_WKR_PREFIX+group, redis.Z{Score: float64(now), Member: msgid}) // insert article post pipe.HMSet(ARTICLE_POST_PREFIX+msgid, "newsgroup", group, "message_id", msgid, "ref_id", message.Reference, "name", message.Name, "subject", message.Subject, "path", message.Path, "time_posted", strconv.Itoa(int(message.Posted)), "message", message.Text, "addr", addr) if group != "ctl" { // control messages aren't added to the global keyring pipe.ZAddNX(ARTICLE_WKR, redis.Z{Score: float64(now), Member: msgid}) } // set / update thread state if message.Reference == "" { // insert new thread for op pipe.ZAddNX(GROUP_THREAD_POSTTIME_WKR_PREFIX+group, redis.Z{Score: float64(message.Posted), Member: msgid}) pipe.ZAddNX(GROUP_THREAD_BUMPTIME_WKR_PREFIX+group, redis.Z{Score: float64(message.Posted), Member: msgid}) if group != "ctl" { pipe.ZAddNX(THREAD_BUMPTIME_WKR, redis.Z{Score: float64(message.Posted), Member: msgid}) } } else { ref := message.Reference if !util.IsSage(message.Subject) { // bump it nigguh pipe.ZAddXX(GROUP_THREAD_BUMPTIME_WKR_PREFIX+group, redis.Z{Score: float64(message.Posted), Member: ref}) pipe.ZAddXX(THREAD_BUMPTIME_WKR, redis.Z{Score: float64(message.Posted), Member: ref}) } // update last posted pipe.ZAddXX(GROUP_THREAD_POSTTIME_WKR_PREFIX+group, redis.Z{Score: float64(message.Posted), Member: ref}) pipe.ZAddNX(THREAD_POST_WKR+ref, redis.Z{Score: float64(message.Posted), Member: msgid}) } // register article header for k, val := range message.Header { k = strings.ToLower(k) for _, v := range val { k = strings.ToLower(k) header := "Name::" + k + "::Value::" + v pipe.SAdd(HEADER_KR_PREFIX+header, msgid) pipe.SAdd(MESSAGEID_HEADER_KR_PREFIX+msgid, header) } } // add nntp message numbers number, _ := self.client.ZIncrBy(ARTICLE_NUMBERS_PREFIX+"last", float64(1), group).Result() pipe.ZAddNX(ARTICLE_NUMBERS_PREFIX+"group::"+group, redis.Z{Score: number, Member: msgid}) // register all attachments atts := message.Attachments if atts != nil { for _, att := range atts { hash := att.Hash pipe.SAdd(ATTACHMENT_ARTICLE_KR_PREFIX+hash, msgid) pipe.SAdd(ARTICLE_ATTACHMENT_KR_PREFIX+msgid, hash) pipe.HSetNX(ATTACHMENT_PREFIX+hash, "message_id", msgid) pipe.HSetNX(ATTACHMENT_PREFIX+hash, "sha_hash", hash) pipe.HSetNX(ATTACHMENT_PREFIX+hash, "filename", att.Name) pipe.HSetNX(ATTACHMENT_PREFIX+hash, "filepath", att.Path) pipe.HSetNX(ATTACHMENT_PREFIX+hash, "mime", att.Mime) } } _, err = pipe.Exec() if err != nil { log.Println("failed to register nntp article", err) } return }