Loading batch/batch.go +8 −3 Original line number Diff line number Diff line Loading @@ -89,16 +89,21 @@ func Reseed() int { seedMsgs, err := GetSeedMessages() ask.CheckErr(err) for i := range seedMsgs { u, err := q.GetUser(ctx, seedMsgs[i].Login) logins, err := q.GetLogins(ctx) ask.CheckErr(err) if u.Login == "" { userCreated := make(map[string]bool, len(logins)) for _, login := range logins { userCreated[login] = true } for i := range seedMsgs { if !userCreated[seedMsgs[i].Login] { _, err = q.AddUser(ctx, storage.AddUserParams{ Login: seedMsgs[i].Login, Name: seedMsgs[i].Name, Disabled: 1, }) ask.CheckErr(err) userCreated[seedMsgs[i].Login] = true } ask.CheckErr(q.SeedCreateMessage(ctx, storage.SeedCreateMessageParams{ Folder: "GENERAL", Loading batch/messages.go +1 −1 Original line number Diff line number Diff line Loading @@ -50,7 +50,7 @@ func GetSeedMessages() ([]SeedMessage, error) { var login, name, subj string var date time.Time for i := 0; i < 3; i++ { for i := range 3 { line := strings.TrimSpace(lines[i]) switch { case strings.HasPrefix(line, "From: "): Loading batch/seed/1991-bulletin_doc→batch/seed/1991t-bulletin_doc +0 −0 File moved. View file repl/messages.go +171 −4 Original line number Diff line number Diff line Loading @@ -65,10 +65,100 @@ func ActionDirectory(cmd *dclish.Command) error { this.Folder = folder this.ReadFirstCall = true } msgs, err := folders.ListMessages(this.Folder.Name) // Get base message list based on filter flags. ctx := storage.Context() var msgs []storage.Message var err error switch { case cmd.Flags["/ALL"].Set: msgs, err = folders.ListMessages(this.Folder.Name) case cmd.Flags["/MARKED"].Set: msgs, err = folders.ListMessagesMarked(this.User.Login, this.Folder.Name) case cmd.Flags["/UNMARKED"].Set: msgs, err = folders.ListMessagesUnmarked(this.User.Login, this.Folder.Name) case cmd.Flags["/SEEN"].Set: msgs, err = folders.ListMessagesSeen(this.User.Login, this.Folder.Name) case cmd.Flags["/NEW"].Set || cmd.Flags["/UNSEEN"].Set: msgs, err = folders.ListMessagesUnseen(this.User.Login, this.Folder.Name) case cmd.Flags["/SEARCH"].Set: msgs, err = this.Q.Search(ctx, nullStr(cmd.Flags["/SEARCH"].Value), 1, this.Folder.Name) case cmd.Flags["/SUBJECT"].Set: msgs, err = this.Q.SearchSubject(ctx, nullStr(cmd.Flags["/SUBJECT"].Value), 1, this.Folder.Name) case cmd.Flags["/REPLY"].Set: if this.MsgID == 0 { fmt.Println("No current message for /REPLY.") return nil } curMsg, e := this.Q.ReadMessage(ctx, this.Folder.Name, this.MsgID) if e != nil { return e } replySubj := "Re: " + curMsg.Subject all, e := folders.ListMessages(this.Folder.Name) if e != nil { return e } for _, m := range all { if strings.HasPrefix(m.Subject, replySubj) { msgs = append(msgs, m) } } default: msgs, err = folders.ListMessages(this.Folder.Name) } if err != nil { return err } // Apply /START filter. if cmd.Flags["/START"].Set && cmd.Flags["/START"].Value != "" { start, e := strconv.ParseInt(cmd.Flags["/START"].Value, 10, 64) if e != nil { return fmt.Errorf("invalid /START value: %w", e) } filtered := make([]storage.Message, 0, len(msgs)) for _, m := range msgs { if m.ID >= start { filtered = append(filtered, m) } } msgs = filtered } // Apply /END filter. if cmd.Flags["/END"].Set && cmd.Flags["/END"].Value != "" { end, e := strconv.ParseInt(cmd.Flags["/END"].Value, 10, 64) if e != nil { return fmt.Errorf("invalid /END value: %w", e) } filtered := make([]storage.Message, 0, len(msgs)) for _, m := range msgs { if m.ID <= end { filtered = append(filtered, m) } } msgs = filtered } // Apply /SINCE filter. if cmd.Flags["/SINCE"].Set { since := time.Now().Truncate(24 * time.Hour) if cmd.Flags["/SINCE"].Value != "" { var e error since, e = time.Parse("2006-01-02", cmd.Flags["/SINCE"].Value) if e != nil { return fmt.Errorf("invalid /SINCE date (use YYYY-MM-DD): %w", e) } } filtered := make([]storage.Message, 0, len(msgs)) for _, m := range msgs { if !m.CreateAt.Before(since) { filtered = append(filtered, m) } } msgs = filtered } if len(msgs) == 0 { fmt.Println("There are no messages present.") return nil Loading Loading @@ -585,25 +675,102 @@ func ActionPrint(cmd *dclish.Command) error { func ActionRead(cmd *dclish.Command) error { defer func() { this.ReadFirstCall = false }() msgid := this.MsgID if !this.ReadFirstCall && len(cmd.Args) == 0 { // Handle filter flags to find the starting message. ctx := storage.Context() switch { case cmd.Flags["/NEW"].Set || cmd.Flags["/UNSEEN"].Set: id, err := this.Q.NextMsgid(ctx, this.Folder.Name, 0, this.User.Login) if err != nil { return err } if id == 0 { fmt.Println("No unread messages.") return nil } msgid = id case cmd.Flags["/MARKED"].Set: msgs, err := folders.ListMessagesMarked(this.User.Login, this.Folder.Name) if err != nil { return err } if len(msgs) == 0 { fmt.Println("No marked messages.") return nil } msgid = msgs[0].ID case cmd.Flags["/UNMARKED"].Set: msgs, err := folders.ListMessagesUnmarked(this.User.Login, this.Folder.Name) if err != nil { return err } if len(msgs) == 0 { fmt.Println("No unmarked messages.") return nil } msgid = msgs[0].ID case cmd.Flags["/SEEN"].Set: msgs, err := folders.ListMessagesSeen(this.User.Login, this.Folder.Name) if err != nil { return err } if len(msgs) == 0 { fmt.Println("No seen messages.") return nil } msgid = msgs[0].ID case cmd.Flags["/SINCE"].Set: since := time.Now().Truncate(24 * time.Hour) if cmd.Flags["/SINCE"].Value != "" { var err error since, err = time.Parse("2006-01-02", cmd.Flags["/SINCE"].Value) if err != nil { return fmt.Errorf("invalid /SINCE date (use YYYY-MM-DD): %w", err) } } allMsgs, err := folders.ListMessages(this.Folder.Name) if err != nil { return err } found := false for _, m := range allMsgs { if !m.CreateAt.Before(since) { msgid = m.ID found = true break } } if !found { fmt.Println("No messages since specified date.") return nil } case !this.ReadFirstCall && len(cmd.Args) == 0: msgid = folders.NextMsgid(this.User.Login, this.Folder.Name, msgid) if msgid < this.MsgID { fmt.Println("No more unread messages.") return nil } } else if len(cmd.Args) == 1 { case len(cmd.Args) == 1: var err error msgid, err = strconv.ParseInt(cmd.Args[0], 10, 64) if err != nil { return err } } this.MsgID = msgid msg, err := folders.GetMessage(this.User.Login, this.Folder.Name, msgid) if err != nil { return err } if pager.Pager(msg.String()) { seen := false if cmd.Flags["/PAGE"].Value == "false" { fmt.Print(msg.String()) seen = true } else { seen = pager.Pager(msg.String()) } if seen { if err := folders.MarkSeen([]int64{msgid}); err != nil { return err } Loading storage/queries/users.sql +4 −0 Original line number Diff line number Diff line Loading @@ -2,6 +2,10 @@ -- name: GetUser :one SELECT * FROM users WHERE login = ?; -- GetLogins gets the list of logins. -- name: GetLogins :many SELECT login FROM users; -- AddUser adds the user. -- name: AddUser :one INSERT INTO users Loading Loading
batch/batch.go +8 −3 Original line number Diff line number Diff line Loading @@ -89,16 +89,21 @@ func Reseed() int { seedMsgs, err := GetSeedMessages() ask.CheckErr(err) for i := range seedMsgs { u, err := q.GetUser(ctx, seedMsgs[i].Login) logins, err := q.GetLogins(ctx) ask.CheckErr(err) if u.Login == "" { userCreated := make(map[string]bool, len(logins)) for _, login := range logins { userCreated[login] = true } for i := range seedMsgs { if !userCreated[seedMsgs[i].Login] { _, err = q.AddUser(ctx, storage.AddUserParams{ Login: seedMsgs[i].Login, Name: seedMsgs[i].Name, Disabled: 1, }) ask.CheckErr(err) userCreated[seedMsgs[i].Login] = true } ask.CheckErr(q.SeedCreateMessage(ctx, storage.SeedCreateMessageParams{ Folder: "GENERAL", Loading
batch/messages.go +1 −1 Original line number Diff line number Diff line Loading @@ -50,7 +50,7 @@ func GetSeedMessages() ([]SeedMessage, error) { var login, name, subj string var date time.Time for i := 0; i < 3; i++ { for i := range 3 { line := strings.TrimSpace(lines[i]) switch { case strings.HasPrefix(line, "From: "): Loading
repl/messages.go +171 −4 Original line number Diff line number Diff line Loading @@ -65,10 +65,100 @@ func ActionDirectory(cmd *dclish.Command) error { this.Folder = folder this.ReadFirstCall = true } msgs, err := folders.ListMessages(this.Folder.Name) // Get base message list based on filter flags. ctx := storage.Context() var msgs []storage.Message var err error switch { case cmd.Flags["/ALL"].Set: msgs, err = folders.ListMessages(this.Folder.Name) case cmd.Flags["/MARKED"].Set: msgs, err = folders.ListMessagesMarked(this.User.Login, this.Folder.Name) case cmd.Flags["/UNMARKED"].Set: msgs, err = folders.ListMessagesUnmarked(this.User.Login, this.Folder.Name) case cmd.Flags["/SEEN"].Set: msgs, err = folders.ListMessagesSeen(this.User.Login, this.Folder.Name) case cmd.Flags["/NEW"].Set || cmd.Flags["/UNSEEN"].Set: msgs, err = folders.ListMessagesUnseen(this.User.Login, this.Folder.Name) case cmd.Flags["/SEARCH"].Set: msgs, err = this.Q.Search(ctx, nullStr(cmd.Flags["/SEARCH"].Value), 1, this.Folder.Name) case cmd.Flags["/SUBJECT"].Set: msgs, err = this.Q.SearchSubject(ctx, nullStr(cmd.Flags["/SUBJECT"].Value), 1, this.Folder.Name) case cmd.Flags["/REPLY"].Set: if this.MsgID == 0 { fmt.Println("No current message for /REPLY.") return nil } curMsg, e := this.Q.ReadMessage(ctx, this.Folder.Name, this.MsgID) if e != nil { return e } replySubj := "Re: " + curMsg.Subject all, e := folders.ListMessages(this.Folder.Name) if e != nil { return e } for _, m := range all { if strings.HasPrefix(m.Subject, replySubj) { msgs = append(msgs, m) } } default: msgs, err = folders.ListMessages(this.Folder.Name) } if err != nil { return err } // Apply /START filter. if cmd.Flags["/START"].Set && cmd.Flags["/START"].Value != "" { start, e := strconv.ParseInt(cmd.Flags["/START"].Value, 10, 64) if e != nil { return fmt.Errorf("invalid /START value: %w", e) } filtered := make([]storage.Message, 0, len(msgs)) for _, m := range msgs { if m.ID >= start { filtered = append(filtered, m) } } msgs = filtered } // Apply /END filter. if cmd.Flags["/END"].Set && cmd.Flags["/END"].Value != "" { end, e := strconv.ParseInt(cmd.Flags["/END"].Value, 10, 64) if e != nil { return fmt.Errorf("invalid /END value: %w", e) } filtered := make([]storage.Message, 0, len(msgs)) for _, m := range msgs { if m.ID <= end { filtered = append(filtered, m) } } msgs = filtered } // Apply /SINCE filter. if cmd.Flags["/SINCE"].Set { since := time.Now().Truncate(24 * time.Hour) if cmd.Flags["/SINCE"].Value != "" { var e error since, e = time.Parse("2006-01-02", cmd.Flags["/SINCE"].Value) if e != nil { return fmt.Errorf("invalid /SINCE date (use YYYY-MM-DD): %w", e) } } filtered := make([]storage.Message, 0, len(msgs)) for _, m := range msgs { if !m.CreateAt.Before(since) { filtered = append(filtered, m) } } msgs = filtered } if len(msgs) == 0 { fmt.Println("There are no messages present.") return nil Loading Loading @@ -585,25 +675,102 @@ func ActionPrint(cmd *dclish.Command) error { func ActionRead(cmd *dclish.Command) error { defer func() { this.ReadFirstCall = false }() msgid := this.MsgID if !this.ReadFirstCall && len(cmd.Args) == 0 { // Handle filter flags to find the starting message. ctx := storage.Context() switch { case cmd.Flags["/NEW"].Set || cmd.Flags["/UNSEEN"].Set: id, err := this.Q.NextMsgid(ctx, this.Folder.Name, 0, this.User.Login) if err != nil { return err } if id == 0 { fmt.Println("No unread messages.") return nil } msgid = id case cmd.Flags["/MARKED"].Set: msgs, err := folders.ListMessagesMarked(this.User.Login, this.Folder.Name) if err != nil { return err } if len(msgs) == 0 { fmt.Println("No marked messages.") return nil } msgid = msgs[0].ID case cmd.Flags["/UNMARKED"].Set: msgs, err := folders.ListMessagesUnmarked(this.User.Login, this.Folder.Name) if err != nil { return err } if len(msgs) == 0 { fmt.Println("No unmarked messages.") return nil } msgid = msgs[0].ID case cmd.Flags["/SEEN"].Set: msgs, err := folders.ListMessagesSeen(this.User.Login, this.Folder.Name) if err != nil { return err } if len(msgs) == 0 { fmt.Println("No seen messages.") return nil } msgid = msgs[0].ID case cmd.Flags["/SINCE"].Set: since := time.Now().Truncate(24 * time.Hour) if cmd.Flags["/SINCE"].Value != "" { var err error since, err = time.Parse("2006-01-02", cmd.Flags["/SINCE"].Value) if err != nil { return fmt.Errorf("invalid /SINCE date (use YYYY-MM-DD): %w", err) } } allMsgs, err := folders.ListMessages(this.Folder.Name) if err != nil { return err } found := false for _, m := range allMsgs { if !m.CreateAt.Before(since) { msgid = m.ID found = true break } } if !found { fmt.Println("No messages since specified date.") return nil } case !this.ReadFirstCall && len(cmd.Args) == 0: msgid = folders.NextMsgid(this.User.Login, this.Folder.Name, msgid) if msgid < this.MsgID { fmt.Println("No more unread messages.") return nil } } else if len(cmd.Args) == 1 { case len(cmd.Args) == 1: var err error msgid, err = strconv.ParseInt(cmd.Args[0], 10, 64) if err != nil { return err } } this.MsgID = msgid msg, err := folders.GetMessage(this.User.Login, this.Folder.Name, msgid) if err != nil { return err } if pager.Pager(msg.String()) { seen := false if cmd.Flags["/PAGE"].Value == "false" { fmt.Print(msg.String()) seen = true } else { seen = pager.Pager(msg.String()) } if seen { if err := folders.MarkSeen([]int64{msgid}); err != nil { return err } Loading
storage/queries/users.sql +4 −0 Original line number Diff line number Diff line Loading @@ -2,6 +2,10 @@ -- name: GetUser :one SELECT * FROM users WHERE login = ?; -- GetLogins gets the list of logins. -- name: GetLogins :many SELECT login FROM users; -- AddUser adds the user. -- name: AddUser :one INSERT INTO users Loading