From d3632b9b4a0429692a7dab165c8d95a0c953544e Mon Sep 17 00:00:00 2001 From: gutmet Date: Sat, 19 Sep 2020 22:12:59 +0200 Subject: [PATCH] new quote subcommand --- Readme.md | 10 ++++++++-- drivel.go | 52 ++++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 52 insertions(+), 10 deletions(-) diff --git a/Readme.md b/Readme.md index 22098ba..334b649 100644 --- a/Readme.md +++ b/Readme.md @@ -2,7 +2,7 @@ drivel ======== drivel is a Twitter command line interface for status updates, media upload, -your home timeline, your mention timeline, replies and likes. +your home timeline, your mention timeline, replies, quotes and likes. My personal opinion is that you shouldn't be on Twitter in the first place, but anyway... @@ -47,13 +47,19 @@ To update your status with optional media upload... drivel status STATUS [FILE1, FILE2, ...] ``` -...or reply to a tweet with a specific ID: +...reply to a tweet with a specific ID... ``` drivel reply TWEET_ID MESSAGE [FILE1, FILE2, ...] ``` +...or quote a tweet with a specific ID... + +``` +drivel quote TWEET_ID MESSAGE [FILE1, FILE2, ...] +``` + with any number of files, as long as they are .jpg, .png, .gif or .mp4 and smaller than 50 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. diff --git a/drivel.go b/drivel.go index f23e857..5f32c99 100644 --- a/drivel.go +++ b/drivel.go @@ -24,6 +24,7 @@ const ( 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=200" HOME_ENDPOINT = "https://api.twitter.com/1.1/statuses/home_timeline.json?tweet_mode=extended&count=200" + LOOKUP_ENDPOINT = "https://api.twitter.com/1.1/statuses/lookup.json?tweet_mode=extended" LIKE_ENDPOINT = "https://api.twitter.com/1.1/favorites/create.json" ) @@ -101,14 +102,14 @@ type ProcessingInfo struct { Error TwitterError } -type PollStatusResponse struct { - Processing_info ProcessingInfo -} - func PollStatusParameters(mediaID ObjectID) string { return "?command=STATUS&media_id=" + string(mediaID) } +type PollStatusResponse struct { + Processing_info ProcessingInfo +} + func UpdateStatusRequest(status string, mediaIDs []ObjectID, previousStatusID ObjectID) url.Values { r := map[string][]string{"status": {status}} if len(mediaIDs) > 0 { @@ -130,6 +131,10 @@ type UpdateStatusResponse struct { Id_str string } +func LookupParameters(ids []string) string { + return "&id=" + strings.Join(ids, ",") +} + var mimetype = map[string]string{ ".mp4": "video/mp4", ".jpg": "image/jpeg", @@ -465,14 +470,21 @@ func (d *data) push(client *http.Client, previous ObjectID) { } } -func updateStatus(args []string, previous ObjectID) { +func updateStatus(args []string, previous ObjectID, embedTweet ObjectID) { d := splitArguments(args) httpClient := getClient() + if embedTweet != "" { + tweets := lookup(httpClient, []string{string(embedTweet)}) + if len(tweets) == 1 { + d.status[0] += " " + tweets[0].URL() + } + } + d.push(httpClient, previous) } func status(args []string) error { - updateStatus(args, "") + updateStatus(args, "", "") return nil } @@ -481,7 +493,16 @@ func reply(args []string) error { fmt.Fprintln(os.Stderr, "Usage: drivel reply TWEET_ID MESSAGE [FILE1, FILE2, ...]") os.Exit(-1) } - updateStatus(args[1:], ObjectID(args[0])) + updateStatus(args[1:], ObjectID(args[0]), "") + return nil +} + +func quote(args []string) error { + if len(args) < 2 { + fmt.Println(os.Stderr, "Usage: drivel quote TWEET_ID MESSAGE [FILE1, FILE2, ...]") + os.Exit(-1) + } + updateStatus(args[1:], "", ObjectID(args[0])) return nil } @@ -495,8 +516,22 @@ func (m Status) String() string { return m.User.Name + " " + "(" + m.Id_str + ")" + ":\n" + m.Full_text } +func (m Status) URL() string { + return "https://twitter.com/" + m.User.Screen_name + "/status/" + m.Id_str +} + type StatusUser struct { - Name string + Name string + Screen_name string +} + +func lookup(client *http.Client, ids []string) []Status { + log := func(err error) { optLogFatal("lookup "+strings.Join(ids, ","), err) } + body := get(client, LOOKUP_ENDPOINT+LookupParameters(ids)) + var tweets []Status + err := json.Unmarshal(body, &tweets) + log(err) + return tweets } func timeline(endpoint string) { @@ -550,6 +585,7 @@ func main() { goutil.NewCommand("home", home, "get your home timeline"), goutil.NewCommand("mentions", mentions, "get your mention timeline"), goutil.NewCommand("reply", reply, "reply to a tweet with a specific ID"), + goutil.NewCommand("quote", quote, "quote retweet a tweet with a specific ID"), goutil.NewCommand("like", like, "like a tweet with a specific ID"), } err := goutil.Execute(commands)