diff --git a/internal/backend/sqlite/sqlite.go b/internal/backend/sqlite/sqlite.go index e973188..e879e0e 100644 --- a/internal/backend/sqlite/sqlite.go +++ b/internal/backend/sqlite/sqlite.go @@ -132,6 +132,9 @@ func (sb *SQLiteBackend) GetArticle(messageID string) (models.Article, error) { if err := sb.db.Get(&a, "SELECT * FROM articles WHERE json_extract(articles.header, '$.Message-Id[0]') = ?", messageID); err != nil { return a, err } + if err := sb.db.Get(&a.ArticleNumber, "SELECT article_number FROM articles_to_groups WHERE article_id = ?", a.ID); err != nil { + return a, err + } return a, json.Unmarshal([]byte(a.HeaderRaw), &a.Header) } @@ -140,6 +143,7 @@ func (sb *SQLiteBackend) GetArticleByNumber(g *models.Group, num int) (models.Ar if err := sb.db.Get(&a, "SELECT articles.* FROM articles INNER JOIN articles_to_groups atg on atg.article_id = articles.id WHERE atg.article_number = ? AND atg.group_id = ?", num, g.ID); err != nil { return a, err } + a.ArticleNumber = num return a, json.Unmarshal([]byte(a.HeaderRaw), &a.Header) } diff --git a/internal/models/article.go b/internal/models/article.go index 3acdc1f..6a6ee08 100644 --- a/internal/models/article.go +++ b/internal/models/article.go @@ -7,10 +7,12 @@ import ( ) type Article struct { - ID int `db:"id"` - CreatedAt time.Time `db:"created_at"` - HeaderRaw string `db:"header"` - Header textproto.MIMEHeader `db:"-"` - Body string `db:"body"` - Thread sql.NullString `db:"thread"` + ID int `db:"id"` + CreatedAt time.Time `db:"created_at"` + HeaderRaw string `db:"header"` + Body string `db:"body"` + Thread sql.NullString `db:"thread"` + + Header textproto.MIMEHeader `db:"-"` + ArticleNumber int `db:"-"` } diff --git a/internal/server/handler.go b/internal/server/handler.go index 63f1360..e0d5b5f 100644 --- a/internal/server/handler.go +++ b/internal/server/handler.go @@ -197,6 +197,15 @@ func (h *Handler) handleGroup(s *Session, command string, arguments []string, id s.currentGroup = &g + if lowWaterMark != 0 { + a, err := h.backend.GetArticleByNumber(&g, lowWaterMark) + if err != nil { + return err + } + + s.currentArticle = &a + } + return s.tconn.PrintfLine(protocol.NNTPResponse{ Code: 211, Message: fmt.Sprintf("%d %d %d %s", articlesCount, lowWaterMark, highWaterMark, g.GroupName), @@ -395,28 +404,35 @@ func (h *Handler) handleArticle(s *Session, command string, arguments []string, s.tconn.StartResponse(id) defer s.tconn.EndResponse(id) - if len(arguments) == 0 && s.currentArticle == nil { - return s.tconn.PrintfLine(protocol.NNTPResponse{Code: 420, Message: "No current article selected"}.String()) + var err error + getByArticleNum := true + if len(arguments) == 0 { + if s.currentArticle == nil { + return s.tconn.PrintfLine(protocol.NNTPResponse{Code: 420, Message: "No current article selected"}.String()) + } + getByArticleNum = false } if len(arguments) > 1 { return s.tconn.PrintfLine(protocol.ErrSyntaxError.String()) } - getByArticleNum := true - num, err := strconv.Atoi(arguments[0]) - if err != nil { - getByArticleNum = false + var num int + if getByArticleNum { + num, err = strconv.Atoi(arguments[0]) + if err != nil { + getByArticleNum = false + } } if getByArticleNum && s.currentGroup == nil { return s.tconn.PrintfLine(protocol.NNTPResponse{Code: 412, Message: "No newsgroup selected"}.String()) } - var a models.Article + var a *models.Article if getByArticleNum { - a, err = h.backend.GetArticleByNumber(s.currentGroup, num) + article, err := h.backend.GetArticleByNumber(s.currentGroup, num) if err != nil { if err == sql.ErrNoRows { return s.tconn.PrintfLine(protocol.NNTPResponse{Code: 423, Message: "No article with that number"}.String()) @@ -424,8 +440,10 @@ func (h *Handler) handleArticle(s *Session, command string, arguments []string, return err } } - } else { - a, err = h.backend.GetArticle(arguments[0]) + a = &article + s.currentArticle = &article + } else if len(arguments) > 0 { + article, err := h.backend.GetArticle(arguments[0]) if err != nil { if err == sql.ErrNoRows { return s.tconn.PrintfLine(protocol.NNTPResponse{Code: 430, Message: "No Such Article Found"}.String()) @@ -433,10 +451,13 @@ func (h *Handler) handleArticle(s *Session, command string, arguments []string, return err } } + a = &article + s.currentArticle = &article + } else { + a = s.currentArticle + num = s.currentArticle.ArticleNumber } - s.currentArticle = &a - switch command { case protocol.CommandArticle: {