@@ -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)
|
||||
|
||||
13
delete.go
13
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)
|
||||
|
||||
|
||||
22
post.go
22
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,9 +57,6 @@ 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()
|
||||
|
||||
|
||||
1
root.go
1
root.go
@@ -8,6 +8,7 @@ import (
|
||||
var rootCmd = &cobra.Command{
|
||||
Use: "yuki",
|
||||
Short: "An extraterrestial client for WriteFreely",
|
||||
Version: FullVersion(),
|
||||
}
|
||||
|
||||
func Execute() {
|
||||
|
||||
103
update.go
Normal file
103
update.go
Normal file
@@ -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)
|
||||
|
||||
}
|
||||
72
yuki.1
Normal file
72
yuki.1
Normal file
@@ -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
|
||||
Reference in New Issue
Block a user