display in_reply_to stuff, new lookup subcommand

This commit is contained in:
gutmet 2020-09-22 08:09:34 +02:00
parent 86185bab30
commit 0afa5f9933
2 changed files with 55 additions and 20 deletions

View File

@ -49,24 +49,30 @@ To retweet a tweet with a specific ID:
drivel retweet TWEET_ID drivel retweet TWEET_ID
``` ```
To lookup tweets with specific IDs:
```
drivel lookup TWEET_ID1 [TWEET_ID2 TWEET_ID3 ...]
```
To update your status with optional media upload: To update your status with optional media upload:
``` ```
drivel status STATUS [FILE1, FILE2, ...] drivel status STATUS [FILE1 FILE2 ...]
``` ```
To reply to a tweet with a specific ID: To reply to a tweet with a specific ID:
``` ```
drivel reply TWEET_ID MESSAGE [FILE1, FILE2, ...] drivel reply TWEET_ID MESSAGE [FILE1 FILE2 ...]
``` ```
To quote a tweet with a specific ID: To quote a tweet with a specific ID:
``` ```
drivel quote TWEET_ID MESSAGE [FILE1, FILE2, ...] drivel quote TWEET_ID MESSAGE [FILE1 FILE2 ...]
``` ```

View File

@ -369,7 +369,7 @@ func exitIfInvalid(path string) {
func splitArguments(args []string) data { func splitArguments(args []string) data {
if len(args) < 1 { if len(args) < 1 {
fmt.Fprintln(os.Stderr, "Usage: drivel status STATUS [FILE1, FILE2, ...]") fmt.Fprintln(os.Stderr, "Usage: drivel status STATUS [FILE1 FILE2 ...]")
os.Exit(-1) os.Exit(-1)
} }
d := data{} d := data{}
@ -476,7 +476,7 @@ func updateStatus(args []string, previous ObjectID, embedTweet ObjectID) {
d := splitArguments(args) d := splitArguments(args)
httpClient := getClient() httpClient := getClient()
if embedTweet != "" { if embedTweet != "" {
tweets := lookup(httpClient, []string{string(embedTweet)}) tweets := _lookup(httpClient, []string{string(embedTweet)})
if len(tweets) == 1 { if len(tweets) == 1 {
d.status[0] += " " + tweets[0].URL() d.status[0] += " " + tweets[0].URL()
} }
@ -491,7 +491,7 @@ func status(args []string) error {
func reply(args []string) error { func reply(args []string) error {
if len(args) < 2 { if len(args) < 2 {
fmt.Fprintln(os.Stderr, "Usage: drivel reply TWEET_ID MESSAGE [FILE1, FILE2, ...]") fmt.Fprintln(os.Stderr, "Usage: drivel reply TWEET_ID MESSAGE [FILE1 FILE2 ...]")
os.Exit(-1) os.Exit(-1)
} }
updateStatus(args[1:], ObjectID(args[0]), "") updateStatus(args[1:], ObjectID(args[0]), "")
@ -500,7 +500,7 @@ func reply(args []string) error {
func quote(args []string) error { func quote(args []string) error {
if len(args) < 2 { if len(args) < 2 {
fmt.Println(os.Stderr, "Usage: drivel quote TWEET_ID MESSAGE [FILE1, FILE2, ...]") fmt.Println(os.Stderr, "Usage: drivel quote TWEET_ID MESSAGE [FILE1 FILE2 ...]")
os.Exit(-1) os.Exit(-1)
} }
updateStatus(args[1:], "", ObjectID(args[0])) updateStatus(args[1:], "", ObjectID(args[0]))
@ -508,12 +508,14 @@ func quote(args []string) error {
} }
type Status struct { type Status struct {
Full_text string Full_text string
Id_str string Id_str string
User StatusUser In_reply_to_screen_name string
Quoted_status *Status In_reply_to_status_id_str string
Retweeted_status *Status User StatusUser
Extended_entities Entities Quoted_status *Status
Retweeted_status *Status
Extended_entities Entities
} }
type Entities struct { type Entities struct {
@ -524,11 +526,23 @@ type Media struct {
Media_url string Media_url string
} }
func (m Status) InReplyTo() string {
if m.In_reply_to_status_id_str != "" {
return m.In_reply_to_screen_name + " (" + m.In_reply_to_status_id_str + ")"
} else {
return ""
}
}
func (m Status) String() string { func (m Status) String() string {
if m.Retweeted_status != nil { if m.Retweeted_status != nil {
return m.User.Screen_name + " retweeted " + m.Retweeted_status.String() return m.User.Screen_name + " retweeted " + m.Retweeted_status.String()
} }
s := m.User.Screen_name + " " + "(" + m.Id_str + ")" + ":\n" + m.Full_text s := m.User.Screen_name + " " + "(" + m.Id_str + ")"
if replyTo := m.InReplyTo(); replyTo != "" {
s += " in reply to " + replyTo
}
s += ":\n" + m.Full_text
allMedia := m.Extended_entities.Media allMedia := m.Extended_entities.Media
if len(allMedia) > 0 { if len(allMedia) > 0 {
s += "\n\nMedia:" s += "\n\nMedia:"
@ -542,6 +556,13 @@ func (m Status) String() string {
return s return s
} }
func PrintTweets(tweets []Status) {
for _, tweet := range tweets {
fmt.Println(tweet)
fmt.Println("---------")
}
}
func (m Status) URL() string { func (m Status) URL() string {
return "https://twitter.com/" + m.User.Screen_name + "/status/" + m.Id_str return "https://twitter.com/" + m.User.Screen_name + "/status/" + m.Id_str
} }
@ -551,7 +572,7 @@ type StatusUser struct {
Screen_name string Screen_name string
} }
func lookup(client *http.Client, ids []string) []Status { func _lookup(client *http.Client, ids []string) []Status {
log := func(err error) { optLogFatal("lookup "+strings.Join(ids, ","), err) } log := func(err error) { optLogFatal("lookup "+strings.Join(ids, ","), err) }
body := get(client, LOOKUP_ENDPOINT+LookupParameters(ids)) body := get(client, LOOKUP_ENDPOINT+LookupParameters(ids))
var tweets []Status var tweets []Status
@ -560,6 +581,16 @@ func lookup(client *http.Client, ids []string) []Status {
return tweets return tweets
} }
func lookup(args []string) error {
if len(args) < 1 {
fmt.Fprintln(os.Stderr, "USAGE: drivel lookup TWEET_ID1 [TWEET_ID2 TWEET_ID3 ...]")
os.Exit(-1)
}
tweets := _lookup(getClient(), args)
PrintTweets(tweets)
return nil
}
func timeline(endpoint string) { func timeline(endpoint string) {
log := func(err error) { optLogFatal("timeline", err) } log := func(err error) { optLogFatal("timeline", err) }
client := getClient() client := getClient()
@ -567,10 +598,7 @@ func timeline(endpoint string) {
var tweets []Status var tweets []Status
err := json.Unmarshal(body, &tweets) err := json.Unmarshal(body, &tweets)
log(err) log(err)
for _, tweet := range tweets { PrintTweets(tweets)
fmt.Println(tweet)
fmt.Println("---------")
}
} }
func mentions(args []string) error { func mentions(args []string) error {
@ -604,7 +632,7 @@ func retweet(args []string) error {
} }
client := getClient() client := getClient()
id := args[0] id := args[0]
tweets := lookup(client, []string{id}) tweets := _lookup(client, []string{id})
if len(tweets) != 1 { if len(tweets) != 1 {
log(errors.New("Could not find tweet " + id)) log(errors.New("Could not find tweet " + id))
} }
@ -644,6 +672,7 @@ func main() {
goutil.NewCommand("home", home, "get your home timeline"), goutil.NewCommand("home", home, "get your home timeline"),
goutil.NewCommand("mentions", mentions, "get your mention timeline"), goutil.NewCommand("mentions", mentions, "get your mention timeline"),
goutil.NewCommand("timeline", userTimeline, "get timeline of a specific user"), goutil.NewCommand("timeline", userTimeline, "get timeline of a specific user"),
goutil.NewCommand("lookup", lookup, "lookup tweets with specific IDs"),
goutil.NewCommand("reply", reply, "reply to a tweet with a specific ID"), 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("quote", quote, "quote retweet a tweet with a specific ID"),
goutil.NewCommand("retweet", retweet, "retweet a tweet with a specific ID"), goutil.NewCommand("retweet", retweet, "retweet a tweet with a specific ID"),