new quote subcommand

This commit is contained in:
gutmet 2020-09-19 22:12:59 +02:00
parent cba6e63238
commit d3632b9b4a
2 changed files with 52 additions and 10 deletions

View File

@ -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.

View File

@ -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)