Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 613576f438 | |||
| a2a93adfb6 | |||
| 3b06d6b773 | |||
| f045e36119 | |||
| 60688d7a0e | |||
| 811028bebc |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1 +1 @@
|
|||||||
/mikuru-*
|
/mikuru
|
||||||
|
|||||||
15
Makefile
15
Makefile
@@ -1,13 +1,10 @@
|
|||||||
VERSION = `git describe --tags` || echo MIRAI
|
|
||||||
|
|
||||||
GO = go
|
GO = go
|
||||||
GOFLAGS = -v -buildvcs=false -buildmode=exe -ldflags "-w -X `${GO} list`.Version=${VERSION}"
|
GOFLAGS = -v -buildvcs=false -buildmode=exe -ldflags='-w -X "`${GO} list`.Version=${VERSION}" -X "`${GO} list`.Revision=${REVISION}"'
|
||||||
|
|
||||||
build: mikuru-login mikuru-post
|
VERSION ?= `git describe --tags`
|
||||||
|
REVISION ?= `git rev-list --all | wc -l`
|
||||||
|
|
||||||
mikuru-login:
|
build:
|
||||||
${GO} build ${GOFLAGS} ./cmd/$@
|
@${GO} build ${GOFLAGS}
|
||||||
mikuru-post:
|
|
||||||
${GO} build ${GOFLAGS} ./cmd/$@
|
|
||||||
clean:
|
clean:
|
||||||
rm -f mikuru-*
|
@rm -f mikuru
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
# Mikuru
|
# Mikuru
|
||||||
[Yarn.social](https://yarn.social) client where each task (except for logout) is handled by a separate program.
|
A [yarn.social](https://yarn.social) client from the future
|
||||||
|
|
||||||
## Current status
|
## Current status
|
||||||
|
* [X] Follow/Unfollow
|
||||||
* [X] Login
|
* [X] Login
|
||||||
* [X] Posting
|
* [X] Posting
|
||||||
* [ ] Timeline
|
* [ ] Timeline
|
||||||
|
|||||||
30
Taskfile.yml
Normal file
30
Taskfile.yml
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
# https://taskfile.dev
|
||||||
|
|
||||||
|
version: '3'
|
||||||
|
|
||||||
|
env:
|
||||||
|
GO: go
|
||||||
|
|
||||||
|
vars:
|
||||||
|
IMPORT: git.laidback.moe/shinyoukai/mikuru/mirai
|
||||||
|
tasks:
|
||||||
|
default:
|
||||||
|
cmds:
|
||||||
|
- task: build
|
||||||
|
build:
|
||||||
|
desc: Build the client
|
||||||
|
cmds:
|
||||||
|
- $GO build -ldflags='-s -w -X "{{.IMPORT}}.Version={{.VERSION}}" -X "{{.IMPORT}}.Revision={{.REVISION}}"' -v
|
||||||
|
vars:
|
||||||
|
REVISION:
|
||||||
|
sh: git rev-list --all | wc -l | tr -d ' '
|
||||||
|
VERSION:
|
||||||
|
sh: git describe --tags
|
||||||
|
clean:
|
||||||
|
desc: Remove generated files
|
||||||
|
cmds:
|
||||||
|
- rm -f mikuru
|
||||||
|
tidy:
|
||||||
|
desc: Update go.mod
|
||||||
|
cmds:
|
||||||
|
- $GO mod tidy
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"git.laidback.moe/shinyoukai/mikuru"
|
|
||||||
"go.yarn.social/client"
|
|
||||||
"github.com/tj/go-editor"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
config, err := os.UserConfigDir()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("%s\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
configPath := config + "/mikuru.ini"
|
|
||||||
mikuru.Parse(configPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
cli, err := client.NewClient(
|
|
||||||
client.WithURI(mikuru.Config.Host),
|
|
||||||
client.WithToken(mikuru.Config.Token),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
write(cli)
|
|
||||||
}
|
|
||||||
|
|
||||||
func write(cli *client.Client) {
|
|
||||||
var post string
|
|
||||||
|
|
||||||
data, err := editor.Read()
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("Unable to read content from editor")
|
|
||||||
}
|
|
||||||
|
|
||||||
post = string(data)
|
|
||||||
|
|
||||||
_, err = cli.Post(post, "")
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("Unable to publish tweet")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
45
follow.go
Normal file
45
follow.go
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"git.laidback.moe/shinyoukai/mikuru/mirai"
|
||||||
|
"go.yarn.social/client"
|
||||||
|
)
|
||||||
|
|
||||||
|
var followCmd = &cobra.Command{
|
||||||
|
Use: "follow <NICK> <URL>",
|
||||||
|
Short: "Track a twtxt.txt feed, located in a Yarn pod or otherwise",
|
||||||
|
Run: func(_ *cobra.Command, args []string) {
|
||||||
|
cli, err := client.NewClient(
|
||||||
|
client.WithURI(mirai.Config.Host),
|
||||||
|
client.WithToken(mirai.Config.Token),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
if len(args) != 2 {
|
||||||
|
log.Fatal("Not enough arguments")
|
||||||
|
}
|
||||||
|
nick := args[0]
|
||||||
|
url := args[1]
|
||||||
|
|
||||||
|
observe(cli, nick, url)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Could not follow %s at %s\n", nick, url)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
mirai.ConfInit()
|
||||||
|
rootCmd.AddCommand(followCmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
func observe(cli *client.Client, nick, url string) error {
|
||||||
|
err := cli.Follow(nick, url)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
5
go.mod
5
go.mod
@@ -3,6 +3,8 @@ module git.laidback.moe/shinyoukai/mikuru
|
|||||||
go 1.24.0
|
go 1.24.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/sirupsen/logrus v1.9.3
|
||||||
|
github.com/spf13/cobra v1.10.2
|
||||||
github.com/tj/go-editor v1.0.0
|
github.com/tj/go-editor v1.0.0
|
||||||
go.yarn.social/client v0.0.0-20250420114029-410ad71a453e
|
go.yarn.social/client v0.0.0-20250420114029-410ad71a453e
|
||||||
golang.org/x/term v0.38.0
|
golang.org/x/term v0.38.0
|
||||||
@@ -10,8 +12,9 @@ require (
|
|||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
github.com/pkg/errors v0.8.1 // indirect
|
github.com/pkg/errors v0.8.1 // indirect
|
||||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
github.com/spf13/pflag v1.0.9 // indirect
|
||||||
github.com/stretchr/testify v1.11.1 // indirect
|
github.com/stretchr/testify v1.11.1 // indirect
|
||||||
go.yarn.social/types v0.0.0-20250420113154-c5a6df6d2f22 // indirect
|
go.yarn.social/types v0.0.0-20250420113154-c5a6df6d2f22 // indirect
|
||||||
golang.org/x/sys v0.39.0 // indirect
|
golang.org/x/sys v0.39.0 // indirect
|
||||||
|
|||||||
9
go.sum
9
go.sum
@@ -1,6 +1,9 @@
|
|||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||||
|
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
@@ -11,14 +14,20 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
|
|||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
|
github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
|
||||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||||
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||||
|
github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=
|
||||||
|
github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=
|
||||||
|
github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY=
|
||||||
|
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||||
github.com/tj/go-editor v1.0.0 h1:VduwRZWk5gxHbzRkS4buB9BIFzAf6Jc+vd2bLZpHzSw=
|
github.com/tj/go-editor v1.0.0 h1:VduwRZWk5gxHbzRkS4buB9BIFzAf6Jc+vd2bLZpHzSw=
|
||||||
github.com/tj/go-editor v1.0.0/go.mod h1:Jj9Ze2Rn2yj5DmMppydZqr9LbkIcCWrehzZ+7udOT+w=
|
github.com/tj/go-editor v1.0.0/go.mod h1:Jj9Ze2Rn2yj5DmMppydZqr9LbkIcCWrehzZ+7udOT+w=
|
||||||
|
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||||
go.yarn.social/client v0.0.0-20250420114029-410ad71a453e h1:A4wok2/cSAbvWLjHhtCrW8dvv1XlgcGRj7H15150HhA=
|
go.yarn.social/client v0.0.0-20250420114029-410ad71a453e h1:A4wok2/cSAbvWLjHhtCrW8dvv1XlgcGRj7H15150HhA=
|
||||||
go.yarn.social/client v0.0.0-20250420114029-410ad71a453e/go.mod h1:+VjffjmcZMHIudGsZlnbPnavk0oSK6xf4olzExiojhg=
|
go.yarn.social/client v0.0.0-20250420114029-410ad71a453e/go.mod h1:+VjffjmcZMHIudGsZlnbPnavk0oSK6xf4olzExiojhg=
|
||||||
go.yarn.social/types v0.0.0-20250420113154-c5a6df6d2f22 h1:M34aQ3AaRKE2t7JOLwoemJ65r0e8c1z4TwuHzogHvZE=
|
go.yarn.social/types v0.0.0-20250420113154-c5a6df6d2f22 h1:M34aQ3AaRKE2t7JOLwoemJ65r0e8c1z4TwuHzogHvZE=
|
||||||
|
|||||||
@@ -2,13 +2,15 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"golang.org/x/term"
|
"golang.org/x/term"
|
||||||
"go.yarn.social/client"
|
"go.yarn.social/client"
|
||||||
"git.laidback.moe/shinyoukai/mikuru"
|
"git.laidback.moe/shinyoukai/mikuru/mirai"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -16,39 +18,38 @@ var (
|
|||||||
password string
|
password string
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
var loginCmd = &cobra.Command{
|
||||||
config, err := os.UserConfigDir()
|
Use: "login",
|
||||||
if err != nil {
|
Short: "Authenticate against a Yarn pod",
|
||||||
fmt.Println("Unable to obtain user's configuration directory")
|
Aliases: []string{"auth", "signin"},
|
||||||
os.Exit(1)
|
Args: cobra.MaximumNArgs(0),
|
||||||
}
|
Run: func(_ *cobra.Command, _ []string) {
|
||||||
configPath := config + "/mikuru.ini"
|
cli, err := client.NewClient(client.WithURI(mirai.Config.Host))
|
||||||
mikuru.Parse(configPath)
|
if err != nil {
|
||||||
|
log.Fatalf("Unable to create client\n%s\n", err)
|
||||||
|
}
|
||||||
|
signin(cli)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func init() {
|
||||||
cli, err := client.NewClient(client.WithURI(mikuru.Config.Host))
|
mirai.ConfInit()
|
||||||
if err != nil {
|
rootCmd.AddCommand(loginCmd)
|
||||||
fmt.Printf("%s", err)
|
|
||||||
fmt.Println("Error creating client")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
signin(cli)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func signin(cli *client.Client) {
|
func signin(cli *client.Client) {
|
||||||
fmt.Printf("Username: ")
|
fmt.Printf("Username: ")
|
||||||
fmt.Scanln(&username)
|
fmt.Scanln(&username)
|
||||||
|
|
||||||
if len(username) == 0 {
|
if len(username) == 0 {
|
||||||
fmt.Println("No value. Bailing out")
|
log.Fatal("No value. Bailing out")
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("Password: ")
|
fmt.Printf("Password: ")
|
||||||
data, err := term.ReadPassword(int(syscall.Stdin))
|
data, err := term.ReadPassword(int(syscall.Stdin))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Unable to obtain password: %s\n", err)
|
log.Fatalf("Unable to obtain password\n%s\n", err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
password := string(data)
|
password := string(data)
|
||||||
@@ -56,15 +57,14 @@ func signin(cli *client.Client) {
|
|||||||
res, err := cli.Login(username, password)
|
res, err := cli.Login(username, password)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Unable to login")
|
log.Fatalf("Unable to login\n%s\n", err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
token := strings.Trim(fmt.Sprintf(res.Token), "{}")
|
token := strings.Trim(fmt.Sprintf(res.Token), "{}")
|
||||||
|
|
||||||
|
|
||||||
fmt.Println("Login successful")
|
fmt.Println("Login successful")
|
||||||
fmt.Println("Place this token in your configuration file for later use")
|
fmt.Println("Place this token in your configuration file for later use")
|
||||||
fmt.Println("Do not share it with anyone, it's classified information")
|
fmt.Println("Do not share it with anyone, it's classified information!")
|
||||||
|
fmt.Println("")
|
||||||
fmt.Printf("token = %v\n", token)
|
fmt.Printf("token = %v\n", token)
|
||||||
}
|
}
|
||||||
27
mikuru.1
27
mikuru.1
@@ -3,15 +3,28 @@
|
|||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
.Nm mikuru
|
.Nm mikuru
|
||||||
.Nd A yarn-compatible twtxt client from the future
|
.Nd A yarn.social client from the future
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm
|
.Nm
|
||||||
|
.Op Cm login
|
||||||
|
.Op Cm post
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
This client has every single part of its functionality
|
This program was made by reverse engineering the reference client
|
||||||
handled by a separate program.
|
due to lack of known API documentation for the client library it uses.
|
||||||
.Sh SEE ALSO
|
.Pp
|
||||||
.Xr mikuru-login 1
|
It doesn't share any code with it, however.
|
||||||
.Xr mikuru-post 1
|
.Sh USAGE
|
||||||
.Xr mikuru-timeline 1
|
.Bl -tag -width 11n
|
||||||
|
.It login
|
||||||
|
Authenticate with a Yarn.social pod,
|
||||||
|
it will ask you for your credentials
|
||||||
|
(passwords are not echoed)
|
||||||
|
.It post
|
||||||
|
Publish a tweet to a Yarn.social pod,
|
||||||
|
it will open your text editor (usually $EDITOR),
|
||||||
|
and will fail if the variable is unset.
|
||||||
|
.El
|
||||||
|
.Sh FILES
|
||||||
|
.Pa ~/.config/mikuru.ini
|
||||||
.Sh AUTHORS
|
.Sh AUTHORS
|
||||||
.An Shin'ya Minazuki Aq Mt shinyoukai@laidback.moe
|
.An Shin'ya Minazuki Aq Mt shinyoukai@laidback.moe
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package mikuru
|
package mirai
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
"gopkg.in/ini.v1"
|
"gopkg.in/ini.v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -9,6 +11,16 @@ var Config struct {
|
|||||||
Token string
|
Token string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ConfInit() {
|
||||||
|
config, err := os.UserConfigDir()
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Unable to obtain user's configuration directory")
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
configPath := config + "/mikuru.ini"
|
||||||
|
Parse(configPath)
|
||||||
|
}
|
||||||
|
|
||||||
func Parse(file string) error {
|
func Parse(file string) error {
|
||||||
cfg, err := ini.Load(file)
|
cfg, err := ini.Load(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
17
mirai/version.go
Normal file
17
mirai/version.go
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
package mirai
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
Revision = "0"
|
||||||
|
Version = "0"
|
||||||
|
)
|
||||||
|
|
||||||
|
func FullVersion() string {
|
||||||
|
return fmt.Sprintf("%s (r%s)", Version, Revision)
|
||||||
|
}
|
||||||
|
func PrintVersion() string {
|
||||||
|
return fmt.Sprintf("%s", Version)
|
||||||
|
}
|
||||||
48
post.go
Normal file
48
post.go
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.laidback.moe/shinyoukai/mikuru/mirai"
|
||||||
|
"go.yarn.social/client"
|
||||||
|
"github.com/tj/go-editor"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
var postCmd = &cobra.Command{
|
||||||
|
Use: "post",
|
||||||
|
Aliases: []string{"tweet"},
|
||||||
|
Short: "Publish a new post to a Yarn pod",
|
||||||
|
Run: func(_ *cobra.Command, args []string) {
|
||||||
|
cli, err := client.NewClient(
|
||||||
|
client.WithURI(mirai.Config.Host),
|
||||||
|
client.WithToken(mirai.Config.Token),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Unable to create client\n%s\n", err)
|
||||||
|
}
|
||||||
|
write(cli)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
rootCmd.AddCommand(postCmd)
|
||||||
|
mirai.ConfInit()
|
||||||
|
}
|
||||||
|
|
||||||
|
func write(cli *client.Client) {
|
||||||
|
var post string
|
||||||
|
|
||||||
|
data, err := editor.Read()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Unable to read content from editor\n%s\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
post = string(data)
|
||||||
|
|
||||||
|
_, err = cli.Post(post, "")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Unable to publish tweet\n%s\n", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
20
root.go
Normal file
20
root.go
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"git.laidback.moe/shinyoukai/mikuru/mirai"
|
||||||
|
)
|
||||||
|
|
||||||
|
var rootCmd = &cobra.Command{
|
||||||
|
Use: "mikuru",
|
||||||
|
Short: "A client for Yarn.social from the future",
|
||||||
|
Version: mirai.FullVersion(),
|
||||||
|
}
|
||||||
|
|
||||||
|
func Execute() {
|
||||||
|
err := rootCmd.Execute()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
44
unfollow.go
Normal file
44
unfollow.go
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"git.laidback.moe/shinyoukai/mikuru/mirai"
|
||||||
|
"go.yarn.social/client"
|
||||||
|
)
|
||||||
|
|
||||||
|
var unfollowCmd = &cobra.Command{
|
||||||
|
Use: "unfollow <NICK>",
|
||||||
|
Short: "Cease to track a feed",
|
||||||
|
Run: func(_ *cobra.Command, args []string) {
|
||||||
|
cli, err := client.NewClient(
|
||||||
|
client.WithURI(mirai.Config.Host),
|
||||||
|
client.WithToken(mirai.Config.Token),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
if len(args) != 1 {
|
||||||
|
log.Fatal("Not enough arguments")
|
||||||
|
}
|
||||||
|
nick := args[0]
|
||||||
|
|
||||||
|
leave_alone(cli, nick)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Could not unfollow %s\n", nick)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
mirai.ConfInit()
|
||||||
|
rootCmd.AddCommand(unfollowCmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
func leave_alone(cli *client.Client, nick string) error {
|
||||||
|
err := cli.Unfollow(nick)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
13
version.go
13
version.go
@@ -1,13 +0,0 @@
|
|||||||
package mikuru
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
Version = "0"
|
|
||||||
)
|
|
||||||
|
|
||||||
func PrintVersion() string {
|
|
||||||
return fmt.Sprintf("%s", Version)
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user