move status update to 'status' subcommand, new 'mentions' subcommand
This commit is contained in:
parent
a8535d3084
commit
c8f724f5fe
13
Readme.md
13
Readme.md
|
@ -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.
|
||||||
|
|
71
drivel.go
71
drivel.go
|
@ -20,6 +20,7 @@ const (
|
||||||
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user