move status update to 'status' subcommand, new 'mentions' subcommand

This commit is contained in:
gutmet 2020-09-17 16:56:18 +02:00
parent a8535d3084
commit c8f724f5fe
2 changed files with 78 additions and 14 deletions

View File

@ -1,7 +1,7 @@
drivel drivel
======== ========
drivel is a Twitter command line interface for status updates and media upload. drivel is a Twitter command line interface for status updates, media upload and mentions.
My personal opinion is that you shouldn't be on Twitter in the first place, but My personal opinion is that you shouldn't be on Twitter in the first place, but
anyway... anyway...
@ -21,8 +21,17 @@ go build drivel.go credentials.go
usage usage
----- -----
To get your last 100 mentions:
``` ```
drivel STATUS [FILE1, FILE2, ...] drivel mentions
```
To update your status with optional media upload:
```
drivel status STATUS [FILE1, FILE2, ...]
``` ```
with any number of files, as long as they are .jpg, .png, .gif or .mp4 and smaller than 5 MB each. On first use, drivel will ask you to go to [https://apps.twitter.com/app/new](https://apps.twitter.com/app/new), register a new app and create an access token. Those values will be stored in HOME/.drivel/ for later use. with any number of files, as long as they are .jpg, .png, .gif or .mp4 and smaller than 5 MB each. On first use, drivel will ask you to go to [https://apps.twitter.com/app/new](https://apps.twitter.com/app/new), register a new app and create an access token. Those values will be stored in HOME/.drivel/ for later use.

View File

@ -16,10 +16,11 @@ import (
) )
const ( const (
MAX_BYTES = 5 * 1024 * 1024 MAX_BYTES = 5 * 1024 * 1024
CHARACTER_LIMIT = 280 CHARACTER_LIMIT = 280
UPLOAD_ENDPOINT = "https://upload.twitter.com/1.1/media/upload.json" UPLOAD_ENDPOINT = "https://upload.twitter.com/1.1/media/upload.json"
STATUS_ENDPOINT = "https://api.twitter.com/1.1/statuses/update.json" STATUS_ENDPOINT = "https://api.twitter.com/1.1/statuses/update.json"
MENTIONS_ENDPOINT = "https://api.twitter.com/1.1/statuses/mentions_timeline.json?tweet_mode=extended&count=100"
) )
func optLogFatal(decorum string, err error) { func optLogFatal(decorum string, err error) {
@ -122,12 +123,26 @@ func getMimetype(file string) string {
} }
} }
func get(client *http.Client, url string) []byte {
return _send(client, url, nil, false)
}
func send(client *http.Client, url string, vals url.Values) []byte { func send(client *http.Client, url string, vals url.Values) []byte {
return _send(client, url, vals, true)
}
func _send(client *http.Client, url string, vals url.Values, usePost bool) []byte {
log := func(err error) { log := func(err error) {
v, _ := json.Marshal(vals) v, _ := json.Marshal(vals)
optLogFatal("send "+url+" "+string(v), err) optLogFatal("send "+url+" "+string(v), err)
} }
resp, err := client.PostForm(url, vals) var resp *http.Response
var err error
if usePost {
resp, err = client.PostForm(url, vals)
} else {
resp, err = client.Get(url)
}
log(err) log(err)
defer resp.Body.Close() defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body) body, err := ioutil.ReadAll(resp.Body)
@ -238,14 +253,14 @@ func exitIfInvalid(path string) {
} }
} }
func splitArguments() data { func splitArguments(args []string) data {
if len(os.Args) < 2 { if len(args) < 1 {
fmt.Fprintln(os.Stderr, "Usage: drivel STATUS [FILE1, FILE2, ...]") fmt.Fprintln(os.Stderr, "Usage: drivel status STATUS [FILE1, FILE2, ...]")
os.Exit(-1) os.Exit(-1)
} }
d := data{} d := data{}
d.status = splitStatus(os.Args[1]) d.status = splitStatus(args[0])
for _, arg := range os.Args[2:] { for _, arg := range args[1:] {
exitIfInvalid(arg) exitIfInvalid(arg)
switch kind(arg) { switch kind(arg) {
case PIC: case PIC:
@ -344,8 +359,48 @@ func (d *data) push(client *http.Client) {
} }
} }
func main() { func status(args []string) error {
d := splitArguments() d := splitArguments(args)
httpClient := getClient() httpClient := getClient()
d.push(httpClient) d.push(httpClient)
return nil
}
type Mention struct {
Full_text string
User MentionUser
}
func (m Mention) String() string {
return m.User.Name + ":\n" + m.Full_text
}
type MentionUser struct {
Name string
}
func mentions(args []string) error {
log := func(err error) { optLogFatal("mentions", err) }
client := getClient()
body := get(client, MENTIONS_ENDPOINT)
var mentions []Mention
err := json.Unmarshal(body, &mentions)
log(err)
for _, mention := range mentions {
fmt.Println(mention)
fmt.Println("---------")
}
return nil
}
func main() {
commands := []goutil.Command{
goutil.NewCommand("status", status, "post a status with message and/or media"),
goutil.NewCommand("mentions", mentions, "get your mentions"),
}
err := goutil.Execute(commands)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
} }