presbeus 0.0.9 → 0.0.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +5 -5
  2. data/bin/presbeus +1 -242
  3. data/lib/presbeus.rb +243 -0
  4. metadata +3 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 0d96712d0bb6999d13c5dce40641a65ff92e25b5
4
- data.tar.gz: 64a58b44c3221f23eec0b60890356b4f234df67c
2
+ SHA256:
3
+ metadata.gz: 9468b0f4ea59ae7a4423a30a1cb56063d1187de95afcf44b25e1c2e9516e9963
4
+ data.tar.gz: b4a99e169929a912e22be83894126ae468def9483c18becc3e5500b0ab34cbf8
5
5
  SHA512:
6
- metadata.gz: b9a249a91fee22efd5fa33953d06c1c3ca5c5c2469dc8a984e8c3756b932e32b17597c24b5ebe96fbffae3c42e5f8af9cc27ec03461fda53e7efcd5fd1a5aeb0
7
- data.tar.gz: c9a75b482c028e2b5c69bd209c833c657f6c54b0109da31cf86f41e977d0e02d31e715961af088f466900bb95d5ca37e7016acad941150dfa3e40f66b56feeb2
6
+ metadata.gz: 40644f67bda26926f83ebfbc4d539b31dcdd9693d3cfc74b9848f91dd32167720f8a3aec82660e0a5dfc1bf9aaa69903d83e818cfed87f3649abb189b41cb713
7
+ data.tar.gz: ad07729edaf99ed476c2aea87c0e6942cb2411a60fdeef6e69b72714a8759bf264331aa9cb1ddd8eb0d9df44f7f97b6238f601d44a6ea699a862445a588f3e60
data/bin/presbeus CHANGED
@@ -1,244 +1,3 @@
1
1
  #!/usr/bin/env ruby
2
- require 'rest-client'
3
- require 'json'
4
- require 'yaml'
5
- require 'time_ago_in_words'
6
- require 'terminal-table'
7
- require 'highline'
8
- require 'colorize'
9
- require 'readline'
10
- #require 'websocket-eventmachine-client'
11
- require 'kontena-websocket-client'
12
- require 'open-uri'
13
-
14
- class Time
15
-
16
- alias_method :ago_in_words_no_timezone, :ago_in_words
17
-
18
- end
19
-
20
- class Presbeus
21
-
22
- def initialize_arguments
23
- argument(:help, [], "show this help") { help }
24
- argument(:realtime, [], "handle realtime event stream") { realtime }
25
- argument(:shell, [], "run in an interactive shell") { shell }
26
- argument(:devices, [], "list devices") { puts table devices }
27
- argument(:pushes, [], "list pushes") { puts table pushes_with_color }
28
- argument(:threads, [:device_id], "show threads for device") do
29
- |c| puts table threads c[0]
30
- end
31
- argument(:last, [:device_id], "show last thread for device") do |c|
32
- puts table last_thread c[0]
33
- end
34
- argument(:push, [:all], "push note to all devices") do |c|
35
- push c.join(" ")
36
- end
37
- argument(:thread, [:device_id, :thead_id], "show SMS thread") do |c|
38
- puts table thread_with_two_columns_wrap c[0], c[1]
39
- end
40
- argument(:sms, [:device_id, :phone_number, :all], "send SMS") do |c|
41
- send_sms c[0], c[1], c[2..-1].join(" ")
42
- end
43
- end
44
-
45
- def initialize
46
- initialize_arguments
47
- configuration_path = "#{ENV['HOME']}/.config/presbeus.yml"
48
- configuration = YAML.load_file configuration_path
49
- api_server = 'https://api.pushbullet.com'
50
- api_server = configuration["api_server"] if configuration.include? "api_server"
51
- @token = `#{configuration['password_command']}`.chomp
52
- @notify_command = configuration['notify_command']
53
- @headers = {"Access-Token" => @token, "Content-Type" => "json"}
54
- @api_prefix = api_server + '/v2/'
55
- end
56
-
57
- def realtime_no_reconnect
58
- uri = "wss://stream.pushbullet.com/websocket/#{@token}"
59
- Kontena::Websocket::Client.connect(uri, ping_timeout: 60) do |client|
60
- client.on_pong do |time, delay|
61
- p time, delay
62
- end
63
- client.read do |message|
64
- json = JSON.parse(message)
65
- type = json["type"]
66
- if type != "nop"
67
- if type == "tickle"
68
- puts(table(pushes_with_color(Time.now.to_i) do |push|
69
- `#{@notify_command} "#{push[1]}"` if @notify_command
70
- end))
71
- end
72
- else
73
- client.send message # pong
74
- end
75
- end
76
- end
77
- end
78
-
79
- def realtime
80
- while true
81
- begin
82
- realtime_no_reconnect
83
- rescue Kontena::Websocket::TimeoutError => e
84
- puts "timeout #{e}"
85
- end
86
- end
87
- end
88
-
89
- def post_v2 what, payload
90
- RestClient.post(
91
- @api_prefix + what, payload.to_json, @headers)
92
- end
93
-
94
- def get_v2 what
95
- response = RestClient.get(
96
- @api_prefix + what, @headers)
97
- JSON.parse response.body
98
- end
99
-
100
- def devices
101
- get_v2("devices")["devices"].map do |device|
102
- [device["iden"], device["model"]]
103
- end
104
- end
105
-
106
- def threads iden
107
- get_v2("permanents/#{iden}_threads")["threads"].reverse.map do |thread|
108
- require 'awesome_print'
109
- [thread["id"]] + thread["recipients"].map { |r| [r["address"], r["name"]] }.flatten
110
- end
111
- end
112
-
113
- def thread device, id
114
- get_v2("permanents/#{device}_thread_#{id}")["thread"]
115
- end
116
-
117
- def pushes modified_after = nil
118
- path = "pushes"
119
- path += "?modified_after=#{modified_after}" if modified_after
120
- get_v2(path)["pushes"].map do |push|
121
- [Time.at(push["created"].to_i).ago_in_words, push["body"]]
122
- end
123
- end
124
-
125
- def user_iden
126
- get_v2("users/me")["iden"]
127
- end
128
-
129
- def push message
130
- post_v2 "pushes", {
131
- title: "push from presbeus",
132
- type: "note",
133
- body: message,
134
- }
135
- end
136
-
137
- def send_sms device, conversation_iden, message
138
- post_v2 "ephemerals", {
139
- push: {
140
- conversation_iden: conversation_iden,
141
- message: message,
142
- package_name: "com.pushbullet.android",
143
- source_user_iden: user_iden,
144
- target_device_iden: device,
145
- type: "messaging_extension_reply"
146
- },
147
- type: "push"
148
- }
149
- end
150
-
151
- def table rows, config = {}
152
- t = Terminal::Table.new config.merge({:rows => rows})
153
- t.style = { border_top: false, border_bottom: false, border_y: '' }
154
- t
155
- end
156
-
157
- def wrap s, width
158
- s.gsub(/(.{1,#{width}})(\s+|\Z)/, "\\1\n")
159
- end
160
-
161
- def with_color string, width, background
162
- lines = string.split("\n")
163
- lines.map { |line| line.ljust(width).colorize(color: :black, background: background)}.join "\n"
164
- end
165
-
166
- def width
167
- HighLine::SystemExtensions.terminal_size[0]
168
- end
169
-
170
- def half_width
171
- width / 2 - 4
172
- end
173
-
174
- def width_2
175
- width - 4
176
- end
177
-
178
- def thread_with_two_columns_wrap device, id
179
- res = []
180
- thread(device, id).reverse.each do |message|
181
- text = [wrap(message["body"], half_width), ""]
182
- date = ["\n#{Time.at(message["timestamp"]).ago_in_words}", ""]
183
- if message["direction"] != "incoming"
184
- text[0] = with_color text[0], half_width, :white
185
- text.reverse!
186
- date.reverse!
187
- else
188
- text[0] = with_color text[0], half_width, :green
189
- end
190
- res << date
191
- res << text
192
- end
193
- res
194
- end
195
-
196
- def pushes_with_color modified_after = nil
197
- pushes(modified_after).reverse.map do |push|
198
- yield(push) if block_given?
199
- ["\n" + push[0] + "\n" + with_color(wrap(push[1], width_2), width_2, :green)]
200
- end
201
- end
202
-
203
- def last_thread device
204
- thread_with_two_columns_wrap device, threads(device).last[0]
205
- end
206
-
207
- def argument name, args, description
208
- @arguments ||= {}
209
- @arguments[name] = {args: args, description: description, block: Proc.new { |c| yield c } }
210
- end
211
-
212
- def help
213
- a = @arguments.to_a.map do |_|
214
- [_[0].to_s, _[1][:args].map { |x| x.to_s }.join(" "), _[1][:description]]
215
- end
216
- puts table a
217
- end
218
-
219
- def shell
220
- while buf = Readline.readline("> ", true)
221
- run buf.split
222
- end
223
- end
224
-
225
- def good_syntax? name, command
226
- args = @arguments[name][:args]
227
- count = args.size + 1
228
- args.include?(:all) ? command.size >= count : command.size == count
229
- end
230
-
231
- def run command
232
- if command.size > 0
233
- name = command[0].to_sym
234
- if @arguments.keys.include?(name) and good_syntax?(name, command)
235
- @arguments[name][:block].call command[1..-1]
236
- return
237
- end
238
- end
239
- help
240
- end
241
-
242
- end
243
-
2
+ require 'presbeus'
244
3
  Presbeus.new.run ARGV
data/lib/presbeus.rb ADDED
@@ -0,0 +1,243 @@
1
+ require 'rest-client'
2
+ require 'json'
3
+ require 'yaml'
4
+ require 'time_ago_in_words'
5
+ require 'terminal-table'
6
+ require 'highline'
7
+ require 'colorize'
8
+ require 'readline'
9
+ #require 'websocket-eventmachine-client'
10
+ require 'kontena-websocket-client'
11
+ require 'open-uri'
12
+
13
+ class Time
14
+
15
+ alias_method :ago_in_words_no_timezone, :ago_in_words
16
+
17
+ end
18
+
19
+ class Presbeus
20
+
21
+ def initialize_arguments
22
+ argument(:help, [], "show this help") { help }
23
+ argument(:realtime, [], "handle realtime event stream") { realtime }
24
+ argument(:shell, [], "run in an interactive shell") { shell }
25
+ argument(:devices, [], "list devices") { puts table devices }
26
+ argument(:pushes, [], "list pushes") { puts table pushes_with_color }
27
+ argument(:threads, [:device_id], "show threads for device") do
28
+ |c| puts table threads c[0]
29
+ end
30
+ argument(:last, [:device_id], "show last thread for device") do |c|
31
+ puts table last_thread c[0]
32
+ end
33
+ argument(:push, [:all], "push note to all devices") do |c|
34
+ push c.join(" ")
35
+ end
36
+ argument(:thread, [:device_id, :thead_id], "show SMS thread") do |c|
37
+ puts table thread_with_two_columns_wrap c[0], c[1]
38
+ end
39
+ argument(:sms, [:device_id, :phone_number, :all], "send SMS") do |c|
40
+ send_sms c[0], c[1], c[2..-1].join(" ")
41
+ end
42
+ end
43
+
44
+ def initialize
45
+ initialize_arguments
46
+ configuration_path = "#{ENV['HOME']}/.config/presbeus.yml"
47
+ configuration = YAML.load_file configuration_path
48
+ api_server = 'https://api.pushbullet.com'
49
+ api_server = configuration["api_server"] if configuration.include? "api_server"
50
+ @token = `#{configuration['password_command']}`.chomp
51
+ @notify_command = configuration['notify_command']
52
+ @headers = {"Access-Token" => @token, "Content-Type" => "json"}
53
+ @api_prefix = api_server + '/v2/'
54
+ end
55
+
56
+ def realtime_no_reconnect
57
+ uri = "wss://stream.pushbullet.com/websocket/#{@token}"
58
+ Kontena::Websocket::Client.connect(uri, ping_timeout: 60) do |client|
59
+ client.on_pong do |time, delay|
60
+ p time, delay
61
+ end
62
+ client.read do |message|
63
+ json = JSON.parse(message)
64
+ type = json["type"]
65
+ if type != "nop"
66
+ if type == "tickle"
67
+ puts(table(pushes_with_color(Time.now.to_i) do |push|
68
+ `#{@notify_command} "#{push[1]}"` if @notify_command
69
+ end))
70
+ end
71
+ else
72
+ client.send message # pong
73
+ end
74
+ end
75
+ end
76
+ end
77
+
78
+ def realtime
79
+ while true
80
+ begin
81
+ realtime_no_reconnect
82
+ rescue Kontena::Websocket::TimeoutError => e
83
+ puts "timeout #{e}"
84
+ end
85
+ end
86
+ end
87
+
88
+ def post_v2 what, payload
89
+ RestClient.post(
90
+ @api_prefix + what, payload.to_json, @headers)
91
+ end
92
+
93
+ def get_v2 what
94
+ response = RestClient.get(
95
+ @api_prefix + what, @headers)
96
+ JSON.parse response.body
97
+ end
98
+
99
+ def devices
100
+ get_v2("devices")["devices"].map do |device|
101
+ [device["iden"], device["model"]]
102
+ end
103
+ end
104
+
105
+ def threads iden
106
+ get_v2("permanents/#{iden}_threads")["threads"].reverse.map do |thread|
107
+ require 'awesome_print'
108
+ [thread["id"]] + thread["recipients"].map { |r| [r["address"], r["name"]] }.flatten
109
+ end
110
+ end
111
+
112
+ def thread device, id
113
+ get_v2("permanents/#{device}_thread_#{id}")["thread"]
114
+ end
115
+
116
+ def pushes modified_after = nil
117
+ path = "pushes"
118
+ path += "?modified_after=#{modified_after}" if modified_after
119
+ get_v2(path)["pushes"].map do |push|
120
+ [Time.at(push["created"].to_i).ago_in_words, push["body"]]
121
+ end
122
+ end
123
+
124
+ def user_iden
125
+ get_v2("users/me")["iden"]
126
+ end
127
+
128
+ def push message
129
+ post_v2 "pushes", {
130
+ title: "push from presbeus",
131
+ type: "note",
132
+ body: message,
133
+ }
134
+ end
135
+
136
+ def send_sms device, conversation_iden, message
137
+ post_v2 "ephemerals", {
138
+ push: {
139
+ conversation_iden: conversation_iden,
140
+ message: message,
141
+ package_name: "com.pushbullet.android",
142
+ source_user_iden: user_iden,
143
+ target_device_iden: device,
144
+ type: "messaging_extension_reply"
145
+ },
146
+ type: "push"
147
+ }
148
+ end
149
+
150
+ def table rows, config = {}
151
+ t = Terminal::Table.new config.merge({:rows => rows})
152
+ t.style = { border_top: false, border_bottom: false, border_y: '' }
153
+ t
154
+ end
155
+
156
+ def wrap s, width
157
+ s.gsub(/(.{1,#{width}})(\s+|\Z)/, "\\1\n")
158
+ end
159
+
160
+ def with_color string, width, background
161
+ lines = string.split("\n")
162
+ lines.map { |line| line.ljust(width).colorize(color: :black, background: background)}.join "\n"
163
+ end
164
+
165
+ def width
166
+ HighLine::SystemExtensions.terminal_size[0]
167
+ end
168
+
169
+ def half_width
170
+ width / 2 - 4
171
+ end
172
+
173
+ def width_2
174
+ width - 4
175
+ end
176
+
177
+ def thread_with_two_columns_wrap device, id
178
+ res = []
179
+ thread(device, id).reverse.each do |message|
180
+ text = [wrap(message["body"], half_width), ""]
181
+ date = ["\n#{Time.at(message["timestamp"]).ago_in_words}", ""]
182
+ if message["direction"] != "incoming"
183
+ text[0] = with_color text[0], half_width, :white
184
+ text.reverse!
185
+ date.reverse!
186
+ else
187
+ text[0] = with_color text[0], half_width, :green
188
+ end
189
+ res << date
190
+ res << text
191
+ end
192
+ res
193
+ end
194
+
195
+ def pushes_with_color modified_after = nil
196
+ pushes(modified_after).reverse.map do |push|
197
+ yield(push) if block_given?
198
+ ["\n" + push[0] + "\n" + with_color(wrap(push[1], width_2), width_2, :green)]
199
+ end
200
+ end
201
+
202
+ def last_thread device
203
+ thread_with_two_columns_wrap device, threads(device).last[0]
204
+ end
205
+
206
+ def argument name, args, description
207
+ @arguments ||= {}
208
+ @arguments[name] = {args: args, description: description, block: Proc.new { |c| yield c } }
209
+ end
210
+
211
+ def help
212
+ a = @arguments.to_a.map do |_|
213
+ [_[0].to_s, _[1][:args].map { |x| x.to_s }.join(" "), _[1][:description]]
214
+ end
215
+ puts table a
216
+ end
217
+
218
+ def shell
219
+ while buf = Readline.readline("> ", true)
220
+ run buf.split
221
+ end
222
+ end
223
+
224
+ def good_syntax? name, command
225
+ args = @arguments[name][:args]
226
+ count = args.size + 1
227
+ args.include?(:all) ? command.size >= count : command.size == count
228
+ end
229
+
230
+ def run command
231
+ if command.size > 0
232
+ name = command[0].to_sym
233
+ if @arguments.keys.include?(name) and good_syntax?(name, command)
234
+ @arguments[name][:block].call command[1..-1]
235
+ return
236
+ end
237
+ end
238
+ help
239
+ end
240
+
241
+ end
242
+
243
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: presbeus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.0.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Olivier Abdesselam
@@ -102,6 +102,7 @@ extensions: []
102
102
  extra_rdoc_files: []
103
103
  files:
104
104
  - bin/presbeus
105
+ - lib/presbeus.rb
105
106
  homepage: http://github.com/yazgoo/presbeus
106
107
  licenses:
107
108
  - MIT
@@ -122,7 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
122
123
  version: '0'
123
124
  requirements: []
124
125
  rubyforge_project:
125
- rubygems_version: 2.6.11
126
+ rubygems_version: 2.7.7
126
127
  signing_key:
127
128
  specification_version: 4
128
129
  summary: command line SMS client for pushbullet