Implement LIST OVERVIEW.FMT command

This commit is contained in:
ChronosX88 2022-02-05 22:10:00 +03:00
parent 5edc89b9ef
commit 70e75b1c63
Signed by: ChronosXYZ
GPG Key ID: 085A69A82C8C511A
2 changed files with 26 additions and 13 deletions

View File

@ -30,7 +30,7 @@
- :heavy_check_mark: `STAT` - :heavy_check_mark: `STAT`
- :construction: Articles overview - :construction: Articles overview
- :heavy_check_mark: `OVER` - :heavy_check_mark: `OVER`
- :x: `LIST OVERVIEW.FMT` - :heavy_check_mark: `LIST OVERVIEW.FMT`
- :x: `HDR` - :x: `HDR`
- :x: `LIST HEADERS` - :x: `LIST HEADERS`
- :heavy_check_mark: Group and Article Selection - :heavy_check_mark: Group and Article Selection

View File

@ -71,8 +71,6 @@ func (h *Handler) handleQuit(s *Session, command string, arguments []string, id
} }
func (h *Handler) handleList(s *Session, command string, arguments []string, id uint) error { func (h *Handler) handleList(s *Session, command string, arguments []string, id uint) error {
sb := strings.Builder{}
listType := "" listType := ""
if len(arguments) != 0 { if len(arguments) != 0 {
listType = arguments[0] listType = arguments[0]
@ -86,6 +84,7 @@ func (h *Handler) handleList(s *Session, command string, arguments []string, id
fallthrough fallthrough
case "ACTIVE": case "ACTIVE":
{ {
dw := s.tconn.DotWriter()
var groups []models.Group var groups []models.Group
var err error var err error
if len(arguments) == 2 { if len(arguments) == 2 {
@ -97,7 +96,7 @@ func (h *Handler) handleList(s *Session, command string, arguments []string, id
if err != nil { if err != nil {
return err return err
} }
sb.Write([]byte(protocol.NNTPResponse{Code: 215, Message: "list of newsgroups follows"}.String() + protocol.CRLF)) dw.Write([]byte(protocol.NNTPResponse{Code: 215, Message: "list of newsgroups follows"}.String() + protocol.CRLF))
for _, v := range groups { for _, v := range groups {
// TODO set actual post permission status // TODO set actual post permission status
c, err := h.backend.GetArticlesCount(&v) c, err := h.backend.GetArticlesCount(&v)
@ -113,14 +112,16 @@ func (h *Handler) handleList(s *Session, command string, arguments []string, id
if err != nil { if err != nil {
return err return err
} }
sb.Write([]byte(fmt.Sprintf("%s %d %d n"+protocol.CRLF, v.GroupName, highWaterMark, lowWaterMark))) dw.Write([]byte(fmt.Sprintf("%s %d %d n"+protocol.CRLF, v.GroupName, highWaterMark, lowWaterMark)))
} else { } else {
sb.Write([]byte(fmt.Sprintf("%s 0 1 n"+protocol.CRLF, v.GroupName))) dw.Write([]byte(fmt.Sprintf("%s 0 1 n"+protocol.CRLF, v.GroupName)))
} }
} }
return dw.Close()
} }
case "NEWSGROUPS": case "NEWSGROUPS":
{ {
dw := s.tconn.DotWriter()
var groups []models.Group var groups []models.Group
var err error var err error
if len(arguments) == 2 { if len(arguments) == 2 {
@ -132,7 +133,7 @@ func (h *Handler) handleList(s *Session, command string, arguments []string, id
return err return err
} }
sb.Write([]byte(protocol.NNTPResponse{Code: 215, Message: "list of newsgroups follows"}.String() + protocol.CRLF)) dw.Write([]byte(protocol.NNTPResponse{Code: 215, Message: "list of newsgroups follows"}.String() + protocol.CRLF))
for _, v := range groups { for _, v := range groups {
desc := "" desc := ""
if v.Description == nil { if v.Description == nil {
@ -140,18 +141,30 @@ func (h *Handler) handleList(s *Session, command string, arguments []string, id
} else { } else {
desc = *v.Description desc = *v.Description
} }
sb.Write([]byte(fmt.Sprintf("%s %s"+protocol.CRLF, v.GroupName, desc))) dw.Write([]byte(fmt.Sprintf("%s %s"+protocol.CRLF, v.GroupName, desc)))
} }
return dw.Close()
}
case "OVERVIEW.FMT":
{
dw := s.tconn.DotWriter()
dw.Write([]byte(protocol.NNTPResponse{Code: 215, Message: "Order of fields in overview database."}.String() + protocol.CRLF))
dw.Write([]byte("Subject:" + protocol.CRLF))
dw.Write([]byte("From:" + protocol.CRLF))
dw.Write([]byte("Date:" + protocol.CRLF))
dw.Write([]byte("Message-ID:" + protocol.CRLF))
dw.Write([]byte("References:" + protocol.CRLF))
dw.Write([]byte(":bytes" + protocol.CRLF))
dw.Write([]byte(":lines" + protocol.CRLF))
return dw.Close()
} }
default: default:
{ {
return s.tconn.PrintfLine(protocol.ErrSyntaxError.String()) return s.tconn.PrintfLine(protocol.ErrSyntaxError.String())
} }
} }
sb.Write([]byte(protocol.MultilineEnding))
return s.tconn.PrintfLine(sb.String())
} }
func (h *Handler) handleModeReader(s *Session, command string, arguments []string, id uint) error { func (h *Handler) handleModeReader(s *Session, command string, arguments []string, id uint) error {
@ -165,7 +178,7 @@ func (h *Handler) handleModeReader(s *Session, command string, arguments []strin
(&s.capabilities).Remove(protocol.ModeReaderCapability) (&s.capabilities).Remove(protocol.ModeReaderCapability)
(&s.capabilities).Remove(protocol.ListCapability) (&s.capabilities).Remove(protocol.ListCapability)
(&s.capabilities).Add(protocol.Capability{Type: protocol.ReaderCapability}) (&s.capabilities).Add(protocol.Capability{Type: protocol.ReaderCapability})
(&s.capabilities).Add(protocol.Capability{Type: protocol.ListCapability, Params: "ACTIVE NEWSGROUPS"}) (&s.capabilities).Add(protocol.Capability{Type: protocol.ListCapability, Params: "ACTIVE NEWSGROUPS OVERVIEW.FMT"})
s.mode = SessionModeReader s.mode = SessionModeReader
return s.tconn.PrintfLine(protocol.NNTPResponse{Code: 201, Message: "Reader mode, posting prohibited"}.String()) // TODO vary on auth status return s.tconn.PrintfLine(protocol.NNTPResponse{Code: 201, Message: "Reader mode, posting prohibited"}.String()) // TODO vary on auth status