Implement THREAD command

This commit is contained in:
ChronosX88 2022-04-15 05:45:40 +03:00
parent f65363ccf8
commit 7d5d277a1f
Signed by: ChronosXYZ
GPG Key ID: 085A69A82C8C511A
3 changed files with 40 additions and 0 deletions

View File

@ -238,3 +238,9 @@ func (sb *SQLiteBackend) GetNewThreads(g *models.Group, perPage int, pageNum int
return numbers, sb.db.Select(&numbers, "SELECT atg.article_number FROM articles INNER JOIN articles_to_groups atg on atg.article_id = articles.id WHERE atg.group_id = ? AND articles.thread IS NULL ORDER BY articles.created_at DESC LIMIT ? OFFSET ?", g.ID, perPage, perPage*pageNum) return numbers, sb.db.Select(&numbers, "SELECT atg.article_number FROM articles INNER JOIN articles_to_groups atg on atg.article_id = articles.id WHERE atg.group_id = ? AND articles.thread IS NULL ORDER BY articles.created_at DESC LIMIT ? OFFSET ?", g.ID, perPage, perPage*pageNum)
} }
func (sb *SQLiteBackend) GetThread(g *models.Group, threadNum int) ([]int, error) {
var numbers []int
return numbers, sb.db.Select(&numbers, "SELECT atg.article_number FROM articles INNER JOIN articles_to_groups atg on atg.article_id = articles.id WHERE atg.group_id = ? AND articles.thread = json_extract((SELECT articles.header from articles INNER JOIN articles_to_groups a on articles.id = a.article_id WHERE a.group_id = ? AND a.article_number = ?), '$.Message-Id[0]') ORDER BY articles.created_at", g.ID, g.ID, threadNum)
}

View File

@ -23,4 +23,5 @@ type StorageBackend interface {
GetNextArticleByNum(g *models.Group, a *models.Article) (models.Article, error) GetNextArticleByNum(g *models.Group, a *models.Article) (models.Article, error)
GetArticlesByRange(g *models.Group, low, high int64) ([]models.Article, error) GetArticlesByRange(g *models.Group, low, high int64) ([]models.Article, error)
GetNewThreads(g *models.Group, perPage int, pageNum int) ([]int, error) GetNewThreads(g *models.Group, perPage int, pageNum int) ([]int, error)
GetThread(g *models.Group, threadNum int) ([]int, error)
} }

View File

@ -53,6 +53,7 @@ func NewHandler(b backend.StorageBackend, serverDomain, uploadPath string) *Hand
// project-specific extensions // project-specific extensions
"NEWTHREADS": h.handleNewThreads, "NEWTHREADS": h.handleNewThreads,
"THREAD": h.handleThread,
} }
h.serverDomain = serverDomain h.serverDomain = serverDomain
h.uploadPath = uploadPath h.uploadPath = uploadPath
@ -905,6 +906,38 @@ func (h *Handler) handleNewThreads(s *Session, command string, arguments []strin
return dw.Close() return dw.Close()
} }
func (h *Handler) handleThread(s *Session, command string, arguments []string, id uint) error {
s.tconn.StartResponse(id)
defer s.tconn.EndResponse(id)
if s.currentGroup == nil {
return s.tconn.PrintfLine(protocol.NNTPResponse{Code: 412, Message: "no newsgroup selected"}.String())
}
if len(arguments) == 0 {
return s.tconn.PrintfLine(protocol.ErrSyntaxError.String())
}
threadNumber, err := strconv.Atoi(arguments[0])
if err != nil {
return s.tconn.PrintfLine(protocol.ErrSyntaxError.String())
}
threadNums, err := h.backend.GetThread(s.currentGroup, threadNumber)
if err != nil {
if err != sql.ErrNoRows {
return err
}
}
dw := s.tconn.DotWriter()
dw.Write([]byte(protocol.NNTPResponse{Code: 226, Message: "Thread articles follows" + protocol.CRLF}.String()))
for _, v := range threadNums {
dw.Write([]byte(strconv.Itoa(v) + protocol.CRLF))
}
return dw.Close()
}
func (h *Handler) Handle(s *Session, message string, id uint) error { func (h *Handler) Handle(s *Session, message string, id uint) error {
splittedMessage := strings.Split(message, " ") splittedMessage := strings.Split(message, " ")
for i, v := range splittedMessage { for i, v := range splittedMessage {