diff --git a/README.md b/README.md index d5adf9c..bdc9770 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,6 @@ An alternative client for [WriteFreely](https://writefreely.org) ## Features * [X] Delete -* [ ] Edit * [X] Login * [X] Logout * [X] Posting @@ -14,7 +13,7 @@ An alternative client for [WriteFreely](https://writefreely.org) * [X] Publish to collection * [X] Right-to-left writing mode * [X] Logout -* [ ] Update +* [X] Update ## Usage -TBD +See the manual page, [yuki(1)](yuki.1) diff --git a/delete.go b/delete.go index c94104c..2f55ea8 100644 --- a/delete.go +++ b/delete.go @@ -7,13 +7,9 @@ import ( "github.com/spf13/cobra" ) -var ( - id string -) - var deleteCmd = &cobra.Command{ Use: "delete", - Aliases: []string{"rm"}, + Aliases: []string{"del", "rm"}, Short: "Permanently delete a published post", Run: func(cmd *cobra.Command, args []string) { id, err := cmd.Flags().GetString("id") @@ -27,16 +23,13 @@ var deleteCmd = &cobra.Command{ func init() { ConfInit() rootCmd.AddCommand(deleteCmd) - deleteCmd.Flags().StringVar(&id, "id", "", "Post ID") + deleteCmd.Flags().StringP("id", "i", "", "Post ID") + if err := deleteCmd.MarkFlagRequired("id"); err != nil { panic(err) } } func DoDelete(id string, args []string) { writefreely.InstanceURL = Config.Host - if len(id) == 0 { - log.Fatal("No ID has been provided!") - } - c := writefreely.NewClient() c.SetToken(Config.Token) diff --git a/post.go b/post.go index 04ef071..9e53bf5 100644 --- a/post.go +++ b/post.go @@ -8,14 +8,6 @@ import ( "github.com/tj/go-editor" ) -var ( - collection string - font string - lang string - rtl bool - title string -) - var postCmd = &cobra.Command{ Use: "post", Short: "Create a new post on the WriteFreely instance", @@ -49,11 +41,12 @@ var postCmd = &cobra.Command{ func init() { ConfInit() rootCmd.AddCommand(postCmd) - postCmd.Flags().StringVarP(&collection, "collection", "b", "", "Location for the post (default is Drafts if unset)") - postCmd.Flags().StringVarP(&font, "font", "f", "mono", "Which font to use for presentation") - postCmd.Flags().StringVarP(&lang, "lang", "l", "en", "Post language") - postCmd.Flags().BoolVarP(&rtl, "rtl", "r", false, "Whether to use right-to-left writing style (common in Middle Eastern languages)") - postCmd.Flags().StringVarP(&title, "title", "t", "", "Title for the entry") + postCmd.Flags().StringP("collection", "b", "", "Location for the post (default is Drafts if unset)") + postCmd.Flags().StringP("font", "f", "mono", "Which font to use for presentation (e.g. sans, serif, wrap, code)") + postCmd.Flags().StringP("lang", "l", "en", "ISO 639-1 language code (e.g. en or de)") + postCmd.Flags().BoolP("rtl", "r", false, "Whether to use right-to-left writing style (common in Middle Eastern languages)") + postCmd.Flags().StringP("title", "t", "", "Title for the entry") + if err := postCmd.MarkFlagRequired("title"); err != nil { panic(err) } } func DoPost(collection, font, lang string, rtl bool, title string, args []string) { @@ -64,10 +57,7 @@ func DoPost(collection, font, lang string, rtl bool, title string, args []string if rtl { log.Println("Using right-to-left writing style") } - if len(title) == 0 { - log.Fatal("No title specified!") - } - + data, err := editor.Read() if err != nil { diff --git a/root.go b/root.go index dfd3417..ca4b7a3 100644 --- a/root.go +++ b/root.go @@ -8,6 +8,7 @@ import ( var rootCmd = &cobra.Command{ Use: "yuki", Short: "An extraterrestial client for WriteFreely", + Version: FullVersion(), } func Execute() { diff --git a/update.go b/update.go new file mode 100644 index 0000000..709c7d1 --- /dev/null +++ b/update.go @@ -0,0 +1,103 @@ +package main + +import ( + "log" + + "code.laidback.moe/go-writefreely" + "github.com/spf13/cobra" + "github.com/tj/go-editor" +) + +var updateCmd = &cobra.Command{ + Use: "update", + Short: "Update a post on the WriteFreely instance (this will override contents)", + Run: func(cmd *cobra.Command, args []string) { + collection, err := cmd.Flags().GetString("collection") + if err != nil { + log.Fatal("Couldn't get the collection flag") + } + font, err := cmd.Flags().GetString("font") + if err != nil { + log.Fatal("Couldn't get the font flag") + } + id, err := cmd.Flags().GetString("id") + if err != nil { + log.Fatal("Couldn't get the id flag") + } + lang, err := cmd.Flags().GetString("lang") + if err != nil { + log.Fatal("Couldn't get the language flag") + } + rtl, err := cmd.Flags().GetBool("rtl") + if err != nil { + log.Fatal("Couldn't get the right-to-left flag") + } + title, err := cmd.Flags().GetString("title") + if err != nil { + log.Fatal("Couldn't get the title flag") + } + + DoUpdate(id, collection, font, lang, rtl, title, args) + }, +} + +func init() { + ConfInit() + updateCmd.Flags().StringP("collection", "b", "", "Location for the post, if unset, it will stay in Drafts, otherwise it gets moved to the specified collection") + updateCmd.Flags().StringP("font", "f", "mono", "Which font to use for presentation (e.g. sans, serif, wrap, code)") + updateCmd.Flags().StringP("id", "i", "", "Post ID") + updateCmd.Flags().StringP("lang", "l", "en", "ISO 639-1 language code (e.g. en or de)") + updateCmd.Flags().BoolP("rtl", "r", false, "Whether to use right-to-left writing style (common in Middle Eastern languages)") + updateCmd.Flags().StringP("title", "t", "", "Title for the post. Supplying a parameter but leaving it blank will remove any title currently in the post") + if err := updateCmd.MarkFlagRequired("id"); err != nil { panic(err) } + rootCmd.AddCommand(updateCmd) +} + +func DoUpdate(id, collection, font, lang string, rtl bool, title string, args []string) { + writefreely.InstanceURL = Config.Host + var err error + var w *writefreely.Post + + if rtl { + log.Println("Using right-to-left writing style") + } + + data, err := editor.Read() + + if err != nil { + log.Fatal("Unable to read content from editor") + } + + post := string(data) + + c := writefreely.NewClient() + c.SetToken(Config.Token) + + if len(collection) == 0 { + w, err = c.UpdatePost(&writefreely.PostParams{ + Title: title, + Content: post, + Font: font, + Language: &lang, + IsRTL: &rtl, + ID: id, + }) + } else { + w, err = c.UpdatePost(&writefreely.PostParams{ + Title: title, + Content: post, + Font: font, + Collection: collection, + Language: &lang, + IsRTL: &rtl, + ID: id, + }) + } + + if err != nil { + log.Fatal(err) + } + + log.Printf("[%s] Updated\n", w.ID) + +} diff --git a/yuki.1 b/yuki.1 new file mode 100644 index 0000000..0db9b5d --- /dev/null +++ b/yuki.1 @@ -0,0 +1,72 @@ +.Dd January 21, 2026 +.Dt YUKI 1 +.Os +.Sh NAME +.Nm yuki +.Nd An alternative client for WriteFreely +.Sh SYNOPSIS +.Nm +.Op Sy login +.Op Sy logout +.Op Sy new Fl t Ar title ... +.Op Sy rm Fl i Ar id +.Op Sy update Fl i Ar id ... +.Sh DESCRIPTION +This client is written entirely from scratch +using the go-writefreely library forked from +go-writeas. +.Pp +It can create, remove, and update posts, as +well as being able to log in and out. +.Sh USAGE +.Bl -tag -width 11n +.It login +Authenticates a user with WriteFreely +.It logout +Un-authenticates a user with WriteFreely, +permanently invalidating the access token +used with the request. +.It new +This creates a new post, associating it +with a user account. +.Pp +The following options are supported: +.Bl -tag -width 8n +.It Fl -collection +Location for the post, if unset, it +will be located in Drafts. +.It Fl -font +Which font to use for presentation, one of +sans, serif, wrap (monospace with word-wrapping), +code (monospace with syntax highlighting) or mono. +.It Fl -lang +ISO 639-1 language code for the post. +.It Fl -rtl +Whether to use right-to-left writing +style. +.It Fl -title +A title for the post. +This option is required +.El +.It rm +Delete permanently a post from WriteFreely. +.Bl -tag -width 8n +.It Fl -id +Identifier for the post. +This option is required +.El +.It update +Update an existing post (this can overwrite it), +it supports all the options outlined in +.Sy new , +as well as the one in +.Sy rm +.El +.Sh FILES +.Pa ~/.config/yuki.ini +.Sh LICENSE +This work is licensed under the terms of the Internet Systems Consortium License +.Sh AUTHORS +.An Shin'ya Minazuki Aq Mt shinyoukai@laidback.moe +.Sh BUGS +Hopefully none