mirror of
https://github.com/ViViDboarder/gopush.git
synced 2024-11-24 11:16:33 +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