mirror of
https://github.com/ViViDboarder/gopush.git
synced 2024-11-21 20:56:44 +00:00
Stuff
This commit is contained in:
commit
9df272c07c
103
gopush.go
Normal file
103
gopush.go
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"./goson"
|
||||||
|
"./pushbullet"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Options struct {
|
||||||
|
Token string
|
||||||
|
Message string
|
||||||
|
Device string
|
||||||
|
Push bool
|
||||||
|
List bool
|
||||||
|
SetActive bool
|
||||||
|
}
|
||||||
|
|
||||||
|
var options = Options{}
|
||||||
|
|
||||||
|
func loadArgs() {
|
||||||
|
token := flag.String("token", "", "Your API Token")
|
||||||
|
activeDevice := flag.String("d", "", "Set default device")
|
||||||
|
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
options.Token = *token
|
||||||
|
options.Device = *activeDevice
|
||||||
|
|
||||||
|
if options.Device != "" {
|
||||||
|
options.SetActive = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Positional args
|
||||||
|
if len(flag.Args()) == 0 {
|
||||||
|
options.List = true
|
||||||
|
} else if len(flag.Args()) == 1 {
|
||||||
|
options.Message = flag.Args()[0]
|
||||||
|
options.Push = true
|
||||||
|
} else if len(flag.Args()) == 2 {
|
||||||
|
options.Device = flag.Args()[0]
|
||||||
|
options.Message = flag.Args()[1]
|
||||||
|
options.Push = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
loadArgs()
|
||||||
|
|
||||||
|
config := goson.LoadConfig("gopush")
|
||||||
|
|
||||||
|
var ok bool
|
||||||
|
if options.Token != "" {
|
||||||
|
config.Set("token", options.Token)
|
||||||
|
} else {
|
||||||
|
options.Token, ok = config.GetString("token")
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
fmt.Println("No token found")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pb := pushbullet.New(options.Token)
|
||||||
|
|
||||||
|
if options.Device == "" {
|
||||||
|
activeDeviceIden, ok := config.GetString("activeDeviceIden")
|
||||||
|
if ok {
|
||||||
|
options.Device = activeDeviceIden
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pb.SetActiveDevice(options.Device)
|
||||||
|
|
||||||
|
if options.SetActive {
|
||||||
|
config.Set("activeDeviceIden", pb.ActiveDevice.Iden)
|
||||||
|
}
|
||||||
|
|
||||||
|
config.Write()
|
||||||
|
|
||||||
|
if options.Push {
|
||||||
|
pb.Push(options.Message)
|
||||||
|
} else if options.List {
|
||||||
|
devices := pb.GetDevices()
|
||||||
|
PrintDevices(devices, pb.ActiveDevice)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func PrintDevices(devices []pushbullet.Device, activeDevice pushbullet.Device) {
|
||||||
|
fmt.Println("Devices:")
|
||||||
|
var prefix string
|
||||||
|
for _, device := range devices {
|
||||||
|
if device.Iden == activeDevice.Iden {
|
||||||
|
prefix = " *"
|
||||||
|
} else {
|
||||||
|
prefix = " "
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(prefix + device.Format())
|
||||||
|
}
|
||||||
|
}
|
136
goson/goson.go
Normal file
136
goson/goson.go
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
package goson
|
||||||
|
|
||||||
|
/*
|
||||||
|
TODO: Better error handling
|
||||||
|
*/
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"os/user"
|
||||||
|
"path/filepath"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
defaultConfigPath = ".config"
|
||||||
|
defaultConfigFileName = "config.json"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
AppName string
|
||||||
|
Loaded bool
|
||||||
|
Saved bool
|
||||||
|
Contents map[string]interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the filepath for the config file
|
||||||
|
func (conf Config) FilePath() (fpath string, err error) {
|
||||||
|
u, err := user.Current()
|
||||||
|
if u != nil && err == nil {
|
||||||
|
fpath = filepath.Join(u.HomeDir, defaultConfigPath, conf.AppName, defaultConfigFileName)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load configuration from filesystem
|
||||||
|
func (conf *Config) Load() {
|
||||||
|
conf.Contents = make(map[string]interface{})
|
||||||
|
|
||||||
|
confFilePath, err := conf.FilePath()
|
||||||
|
fileBody, err := ioutil.ReadFile(confFilePath)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.Unmarshal(fileBody, &conf.Contents)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
conf.Loaded = true
|
||||||
|
conf.Saved = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieves Json data
|
||||||
|
func (conf Config) JsonData() ([]byte, error) {
|
||||||
|
return json.MarshalIndent(conf.Contents, "", " ")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write config file back to filesystem
|
||||||
|
func (conf Config) Write() {
|
||||||
|
data, err := conf.JsonData()
|
||||||
|
confFilePath, err := conf.FilePath()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
confDirname := filepath.Dir(confFilePath)
|
||||||
|
err = os.MkdirAll(confDirname, 0777)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ioutil.WriteFile(confFilePath, data, 0666)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
conf.Saved = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (conf *Config) Clear() {
|
||||||
|
conf.Contents = make(map[string]interface{})
|
||||||
|
conf.Saved = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets a value from the config
|
||||||
|
func (conf Config) Get(key string) (interface{}, bool) {
|
||||||
|
v, ok := conf.Contents[key]
|
||||||
|
return v, ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets a value from the config
|
||||||
|
func (conf Config) GetString(key string) (string, bool) {
|
||||||
|
v, ok := conf.Contents[key].(string)
|
||||||
|
return v, ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets a value from the config
|
||||||
|
func (conf Config) GetInt(key string) (int, bool) {
|
||||||
|
v, ok := conf.Contents[key].(int)
|
||||||
|
return v, ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns a list
|
||||||
|
func (conf Config) GetList(key string) (l []interface{}, ok bool) {
|
||||||
|
v, ok := conf.Get(key)
|
||||||
|
if ok {
|
||||||
|
l, ok = v.([]interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
return l, ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets a value in the config
|
||||||
|
func (conf *Config) Set(key string, value interface{}) {
|
||||||
|
conf.Contents[key] = value
|
||||||
|
conf.Saved = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets value and writes to file
|
||||||
|
func (conf *Config) SetAndWrite(key string, value interface{}) {
|
||||||
|
conf.Set(key, value)
|
||||||
|
conf.Write()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load config for app name
|
||||||
|
func LoadConfig(appName string) (conf Config) {
|
||||||
|
conf.AppName = appName
|
||||||
|
conf.Load()
|
||||||
|
return conf
|
||||||
|
}
|
194
pushbullet/pushbullet.go
Normal file
194
pushbullet/pushbullet.go
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
package pushbullet
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
host = "https://api.pushbullet.com/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func New(apiKey string) PushBullet {
|
||||||
|
return PushBullet{apiKey: apiKey}
|
||||||
|
}
|
||||||
|
|
||||||
|
type PushBullet struct {
|
||||||
|
apiKey string
|
||||||
|
client *http.Client
|
||||||
|
ActiveDevice Device
|
||||||
|
Devices []Device
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loads all devices for account into instance
|
||||||
|
func (pb *PushBullet) LoadDevices() []Device {
|
||||||
|
dl := new(DeviceList)
|
||||||
|
err := pb.pbRequest("GET", host+"/devices", nil, dl)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("error on pbRequest")
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
pb.Devices = dl.Devices
|
||||||
|
|
||||||
|
return dl.Devices
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lazy loaded version of LoadDevices
|
||||||
|
func (pb *PushBullet) GetDevices() []Device {
|
||||||
|
if len(pb.Devices) == 0 {
|
||||||
|
pb.LoadDevices()
|
||||||
|
}
|
||||||
|
|
||||||
|
return pb.Devices
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pb PushBullet) PushNote(message string) {
|
||||||
|
body := map[string]interface{}{
|
||||||
|
"type": "note",
|
||||||
|
"body": message,
|
||||||
|
}
|
||||||
|
|
||||||
|
pb.Push(body)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pb PushBullet) PushLink(title string, url string) {
|
||||||
|
pb.PushLinkWithBody(title, url, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pb PushBullet) PushLinkWithBody(title string, url string, messBody string) {
|
||||||
|
body := map[string]interface{}{
|
||||||
|
"type": "link",
|
||||||
|
"title": title,
|
||||||
|
"url": url,
|
||||||
|
"body": messBody,
|
||||||
|
}
|
||||||
|
|
||||||
|
pb.Push(body)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pushes a text message to active device
|
||||||
|
// TODO: handle response
|
||||||
|
func (pb PushBullet) Push(body map[string]interface{}) {
|
||||||
|
body["device_iden"] = pb.ActiveDevice.Iden
|
||||||
|
|
||||||
|
result := new(interface{})
|
||||||
|
pb.pbRequest("POST", host+"/pushes", body, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets active device by Nickname or Iden
|
||||||
|
func (pb *PushBullet) SetActiveDevice(key string) {
|
||||||
|
if len(pb.Devices) == 0 {
|
||||||
|
pb.LoadDevices()
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, d := range pb.Devices {
|
||||||
|
if d.Match(key) && d.CanPush() {
|
||||||
|
pb.ActiveDevice = d
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method for communicating with PushBullet
|
||||||
|
func (pb *PushBullet) pbRequest(method string, url string, body map[string]interface{}, result interface{}) error {
|
||||||
|
if pb.client == nil {
|
||||||
|
pb.client = &http.Client{}
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonBody, err := json.Marshal(body)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error marshalling body")
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
r, err := http.NewRequest(method, url, bytes.NewBuffer(jsonBody))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error on request create")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
r.Header.Add("Content-Type", "application/json")
|
||||||
|
r.Header.Add("Application-Type", "application/json")
|
||||||
|
r.Header.Add("User-Agent", "gopush")
|
||||||
|
|
||||||
|
r.SetBasicAuth(pb.apiKey, "")
|
||||||
|
|
||||||
|
resp, err := pb.client.Do(r)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error on request do")
|
||||||
|
fmt.Println(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer resp.Body.Close()
|
||||||
|
responseBody, err := ioutil.ReadAll(resp.Body)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error on request read")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = json.Unmarshal(responseBody, result)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Response types
|
||||||
|
|
||||||
|
type DeviceList struct {
|
||||||
|
Aliases []interface{}
|
||||||
|
Clients []interface{}
|
||||||
|
Devices []Device
|
||||||
|
Grants []interface{}
|
||||||
|
Pushes []interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeviceFingerprint struct {
|
||||||
|
mac_address string
|
||||||
|
android_id string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Device struct {
|
||||||
|
Iden string
|
||||||
|
Created float32
|
||||||
|
Nickname string
|
||||||
|
Modified float32
|
||||||
|
Push_token string
|
||||||
|
Fingerprint string
|
||||||
|
Active bool
|
||||||
|
Model string
|
||||||
|
App_version int32
|
||||||
|
Type string
|
||||||
|
Kind string
|
||||||
|
Pushable bool
|
||||||
|
Manufacturer string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns Android Fingerprint
|
||||||
|
func (d Device) AndroidFingerprint() (DeviceFingerprint, error) {
|
||||||
|
fp := new(DeviceFingerprint)
|
||||||
|
err := json.Unmarshal([]byte(d.Fingerprint), fp)
|
||||||
|
return *fp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns if the device is available for pushing
|
||||||
|
func (d Device) CanPush() bool {
|
||||||
|
return d.Active && d.Pushable
|
||||||
|
}
|
||||||
|
|
||||||
|
// Outputs the device in a friendly string format
|
||||||
|
func (d Device) Format() string {
|
||||||
|
return fmt.Sprintf("%s (%s)", d.Nickname, d.Kind)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true if key matches Nickname or Iden
|
||||||
|
func (d Device) Match(key string) bool {
|
||||||
|
if d.Nickname == key || d.Iden == key {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user