diff --git a/NOTES.md b/NOTES.md index 536d4a0d020a615ba93589e6e82f1e1d0cf37e2f..7651e9622b809eaec101d56d024ad6e6caa856e1 100644 --- a/NOTES.md +++ b/NOTES.md @@ -21,23 +21,17 @@ Switch between MAIL and BULLETIN modes? MAIL commands are documented ## Things to do * Run [godoc](http://localhost:6060/) and then review where the help text is lacking. - * ~~Move to a storage layer.~~ * Implement each command. - * Next: folder commands - ~~CREATE~~, ~~REMOVE~~, MODIFY, ~~INDEX~~, ~~SELECT~~ - * Messages: ~~ADD~~, ~~CURRENT~~, ~~DIRECTORY~~, ~~BACK~~, CHANGE, - ~~FIRST~~, ~~NEXT~~, ~~READ~~, ~~DELETE~~ - * Messages edit: CHANGE, REPLY, FORWARD + * Next: folder commands - MODIFY + * Messages edit: CHANGE, REPLY * Moving messages: COPY, MOVE + * Mark messages: MARK, UNMARK * Compound commands: SET and SHOW - make HELP work for them. - * Mail: MAIL, FORWARD, + * Mail: MAIL, FORWARD, RESPOND * Run this.Skew.Safe() before... each command? each write? * Handle broadcast messages - have bulletin watch a directory and display files from it. Then have them delete the file if it's older than 5 minutes (allow for failure) - * Cleanup help output. - * Remove the node/cluster/newsgroup/mailing-list related flags. - * Remove BBOARD references. - * format with `par w72j1` * Database * trigger to limit values for 'visibility'? * Add commands: @@ -46,6 +40,7 @@ Switch between MAIL and BULLETIN modes? MAIL commands are documented * Commands for a local mail system? * Commands to connect to Mattermost or mastodon? * Commands to manage users. + * Handle MARK for SELECT and DIRECTORY. Done: @@ -66,6 +61,11 @@ Done: * ~~this.Folder should be a storage.Folder.~~ * ~~Add some of the early announcements from the sources - see the conversion branch - to the GENERAL folder.~~ + * ~~Move to a storage layer.~~ + * ~~Cleanup help output.~~ + * ~~Remove the node/cluster/newsgroup/mailing-list related flags.~~ + * ~~Remove BBOARD references.~~ + * ~~format with `par w72j1`~~ ## Module links diff --git a/folders/messages.go b/folders/messages.go index d05b8e4e78b125038be7fea19698186fdaebb6ec..c787c4b3391734d3cbc4fb8fe036b4cf8ee3802d 100644 --- a/folders/messages.go +++ b/folders/messages.go @@ -158,3 +158,31 @@ func DeleteAllMessages() error { this.Q.DeleteAllMessages(ctx, this.Folder.Name) return nil } + +// SetMark sets a mark for message(s). +func SetMark(msgids []int64) error { + ctx := storage.Context() + + for _, msgid := range msgids { + this.Q.AddMark(ctx, storage.AddMarkParams{ + Folder: this.Folder.Name, + Login: this.User.Login, + Msgid: msgid, + }) + } + return nil +} + +// UnsetMark sets a mark for message(s). +func UnsetMark(msgids []int64) error { + ctx := storage.Context() + + for _, msgid := range msgids { + this.Q.DeleteMark(ctx, storage.DeleteMarkParams{ + Folder: this.Folder.Name, + Login: this.User.Login, + Msgid: msgid, + }) + } + return nil +} diff --git a/repl/command.go b/repl/command.go index 155216091ba65092a202f13850f81d69c139d40b..536814373143c8c9a5a588cd7ca872d7bf2c73d1 100644 --- a/repl/command.go +++ b/repl/command.go @@ -267,7 +267,7 @@ topic are grouped separately, or to restrict reading of certain messages to specified users. Once created, that message is automatically selected (see information on SELECT command). The commands that can be used to modify the folder's characteristics are: MODIFY, REMOVE, SET -ACCESS, SET BBOARD, SET NODE, and SET SYSTEM. +ACCESS, and SET SYSTEM. Format: CREATE folder-name @@ -703,6 +703,7 @@ information. Format: MARK [message-number or numbers]`, MaxArgs: 1, + Action: ActionMark, }, "UNMARK": { Description: `Sets the current or message-id message as unmarked. @@ -710,6 +711,7 @@ information. Format: UNMARK [message-number or numbers]`, MaxArgs: 1, + Action: ActionUnmark, }, "MODIFY": { Description: `Modifies the database information for the current folder. Only the owner @@ -1324,10 +1326,9 @@ privileged qualifier.`, }, }, "DEFAULT_EXPIRE": { - Description: `Specifies the number of days the message created by BBOARD (or direct -PMDF path) is to be retained. The default is 14 days. The highest -limit that can be specified is 30 days. This can be overridden by a -user with privileges. + Description: `Specifies the number of days the message is to be retained. The default +is 14 days. The highest limit that can be specified is 30 days. This can +be overridden by a user with privileges. This also specifies the default expiration date when adding a message. If no expiration date is entered when prompted for a date, or if @@ -1339,11 +1340,7 @@ used. If -1 is specified, messages will become permanent. If 0 is specified, no default expiration date will be present. The latter should never be -specified for a folder with a BBOARD, or else the messages will -disappear. - -NOTE: This value is the same value that SET BBOARD/EXPIRATION specifies. -If one is changed, the other will change also.`, +specified for a folder or else the messages will disappear.`, MinArgs: 1, MaxArgs: 1, }, @@ -1597,7 +1594,7 @@ the SELECT command, information about that folder is shown. "/FULL": { Description: ` Control whether all information of the folder is displayed. This includes the SYSTEM setting, the access list if the folder is private, - and BBOARD information. This information is only those who have access + and other information. This information is only those who have access to that folder.`, }, }, diff --git a/repl/messages.go b/repl/messages.go index 13b976325bbb4f50d4ea8e2b47a0cdbc026828c4..b0cd69c41a44059972f2113a81102da2856eff90 100644 --- a/repl/messages.go +++ b/repl/messages.go @@ -323,3 +323,37 @@ func ActionDelete(cmd *dclish.Command) error { } return nil } + +// ActionMark handles the `MARK` command. +func ActionMark(cmd *dclish.Command) error { + var err error + msgids := []int64{this.MsgID} + if len(cmd.Args) == 1 { + msgids, err = ParseNumberList(cmd.Args[0]) + if err != nil { + return err + } + } + err = folders.SetMark(msgids) + if err != nil { + fmt.Printf("ERROR: %s.\n", err) + } + return nil +} + +// ActionUnmark handles the `UNMARK` command. +func ActionUnmark(cmd *dclish.Command) error { + var err error + msgids := []int64{this.MsgID} + if len(cmd.Args) == 1 { + msgids, err = ParseNumberList(cmd.Args[0]) + if err != nil { + return err + } + } + err = folders.UnsetMark(msgids) + if err != nil { + fmt.Printf("ERROR: %s.\n", err) + } + return nil +} diff --git a/storage/queries/standard.sql b/storage/queries/standard.sql index 8edc1bb19ee80b6272f4838f16f00c480fc28023..3af17721a009c598d416580805560d934cfa0ab5 100644 --- a/storage/queries/standard.sql +++ b/storage/queries/standard.sql @@ -59,7 +59,7 @@ DELETE FROM seen WHERE folder = ? AND login = ? AND msgid = ?; INSERT INTO marks (folder, login, msgid) VALUES (?, ?, ?); -- name: ListMark :many -SELECT * FROM marks; +SELECT * FROM marks WHERE folder = ? AND login = ?; -- name: GetMark :one SELECT * FROM marks WHERE folder = ? AND login = ? AND msgid = ?; diff --git a/storage/standard.sql.go b/storage/standard.sql.go index 0c05956a06a2790d370fe0db195d9ac612319add..8ddd2c88551047c5fa34cfd1f88ac678d9501e57 100644 --- a/storage/standard.sql.go +++ b/storage/standard.sql.go @@ -508,11 +508,16 @@ func (q *Queries) ListFolders(ctx context.Context) ([]Folder, error) { } const listMark = `-- name: ListMark :many -SELECT login, folder, msgid FROM marks +SELECT login, folder, msgid FROM marks WHERE folder = ? AND login = ? ` -func (q *Queries) ListMark(ctx context.Context) ([]Mark, error) { - rows, err := q.db.QueryContext(ctx, listMark) +type ListMarkParams struct { + Folder string + Login string +} + +func (q *Queries) ListMark(ctx context.Context, arg ListMarkParams) ([]Mark, error) { + rows, err := q.db.QueryContext(ctx, listMark, arg.Folder, arg.Login) if err != nil { return nil, err }