presbeus 0.0.9 → 0.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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