urbit-api 0.1.0 → 0.3.0

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.
data/lib/urbit/ship.rb CHANGED
@@ -2,6 +2,8 @@ require 'faraday'
2
2
 
3
3
  require 'urbit/channel'
4
4
  require 'urbit/config'
5
+ require 'urbit/graph'
6
+ require 'urbit/setting'
5
7
 
6
8
  module Urbit
7
9
  class Ship
@@ -12,6 +14,8 @@ module Urbit
12
14
  @auth_cookie = nil
13
15
  @channels = []
14
16
  @config = config
17
+ @graphs = []
18
+ @settings = []
15
19
  @logged_in = false
16
20
  end
17
21
 
@@ -27,6 +31,37 @@ module Urbit
27
31
  auth_cookie
28
32
  end
29
33
 
34
+ def graph(resource:)
35
+ self.graphs.find {|g| g.resource == resource}
36
+ end
37
+
38
+ #
39
+ # Answers a collection of all the top-level graphs on this ship.
40
+ # This collection is cached and will need to be invalidated to discover new graphs.
41
+ #
42
+ def graphs(flush_cache: false)
43
+ @graphs = [] if flush_cache
44
+ if @graphs.empty?
45
+ if self.logged_in?
46
+ r = self.scry(app: 'graph-store', path: '/keys')
47
+ if r[:body]
48
+ body = JSON.parse r[:body]
49
+ body["graph-update"]["keys"].each do |k|
50
+ @graphs << Graph.new(ship: self, graph_name: k["name"], host_ship_name: k["ship"])
51
+ end
52
+ end
53
+ end
54
+ end
55
+ @graphs
56
+ end
57
+
58
+ #
59
+ # A helper method to just print out the descriptive names of all the ship's graphs.
60
+ #
61
+ def graph_names
62
+ self.graphs.collect {|g| g.resource}
63
+ end
64
+
30
65
  def login
31
66
  return self if logged_in?
32
67
 
@@ -40,6 +75,57 @@ module Urbit
40
75
  config.name
41
76
  end
42
77
 
78
+ def remove_graph(desk: 'landscape', graph:)
79
+ delete_json = %Q({
80
+ "delete": {
81
+ "resource": {
82
+ "ship": "#{self.name}",
83
+ "name": "#{graph.name}"
84
+ }
85
+ }
86
+ })
87
+
88
+ spider = self.spider(desk: desk, mark_in: 'graph-view-action', mark_out: 'json', thread: 'graph-delete', data: delete_json, args: ["NO_RESPONSE"])
89
+ if (retcode = (200 == spider[:status]))
90
+ self.graphs.delete graph
91
+ end
92
+ retcode
93
+ end
94
+
95
+ #
96
+ # Answers the entries for the specified desk and bucket.
97
+ #
98
+ def setting(desk: 'landscape', bucket:)
99
+ if (settings = self.settings(desk: desk))
100
+ settings.each do |setting|
101
+ if (entries = setting.entries(bucket: bucket))
102
+ return entries
103
+ end
104
+ end
105
+ end
106
+ {}
107
+ end
108
+
109
+ #
110
+ # Answers a collection of all the settings for this ship.
111
+ # This collection is cached and will need to be invalidated to discover new settings.
112
+ #
113
+ def settings(desk: 'landscape', flush_cache: false)
114
+ @settings = [] if flush_cache
115
+ if @settings.empty?
116
+ if self.logged_in?
117
+ scry = self.scry(app: "settings-store", path: "/desk/#{desk}", mark: "json")
118
+ if scry[:body]
119
+ body = JSON.parse scry[:body]
120
+ body["desk"].each do |k|
121
+ @settings << Setting.new(ship: self, desk: desk, setting: k)
122
+ end
123
+ end
124
+ end
125
+ end
126
+ @settings
127
+ end
128
+
43
129
  def untilded_name
44
130
  name.gsub('~', '')
45
131
  end
@@ -48,31 +134,104 @@ module Urbit
48
134
  config.name
49
135
  end
50
136
 
51
- # Opening a channel always creates a new channel which will
52
- # remain open until this ship is disconnected at which point it
53
- # will be closed.
54
- def open_channel(a_name)
55
- login
56
- (c = Channel.new self, a_name).open("Opening Airlock")
57
- self.channels << c
58
- c
59
- end
60
-
61
137
  def open_channels
62
138
  @channels.select {|c| c.open?}
63
139
  end
64
140
 
141
+ #
142
+ # Poke an app with a message using a mark.
143
+ #
144
+ # Returns a Channel which has been created and opened and will begin
145
+ # to get back a stream of facts via its Receiver.
146
+ #
147
+ def poke(app:, mark:, message:)
148
+ (self.add_channel).poke(app: app, mark: mark, message: message)
149
+ end
150
+
151
+ def scry(app:, path:, mark: 'json')
152
+ self.login
153
+ mark = ".#{mark}" unless mark.empty?
154
+ scry_url = "#{self.config.api_base_url}/~/scry/#{app}#{path}#{mark}"
155
+
156
+ response = Faraday.get(scry_url) do |req|
157
+ req.headers['Accept'] = 'application/json'
158
+ req.headers['Cookie'] = self.cookie
159
+ end
160
+
161
+ {status: response.status, code: response.reason_phrase, body: response.body}
162
+ end
163
+
164
+ def spider(desk: 'landscape', mark_in:, mark_out:, thread:, data:, args: [])
165
+ self.login
166
+ url = "#{self.config.api_base_url}/spider/#{desk}/#{mark_in}/#{thread}/#{mark_out}.json"
167
+
168
+ # TODO: This is a huge hack due to the fact that certain spider operations are known to
169
+ # not return when they should. Instead I just set the timeout low and catch the
170
+ # error and act like everything is ok.
171
+ if args.include?("NO_RESPONSE")
172
+ conn = Faraday::Connection.new()
173
+ conn.options.timeout = 1
174
+ conn.options.open_timeout = 1
175
+
176
+ begin
177
+ response = conn.post(url) do |req|
178
+ req.headers['Accept'] = 'application/json'
179
+ req.headers['Cookie'] = self.cookie
180
+ req.body = data
181
+ end
182
+ rescue Faraday::TimeoutError
183
+ return {status: 200, code: "ok", body: "null"}
184
+ end
185
+ end
186
+
187
+ response = Faraday.post(url) do |req|
188
+ req.headers['Accept'] = 'application/json'
189
+ req.headers['Cookie'] = self.cookie
190
+ req.body = data
191
+ end
192
+
193
+ {status: response.status, code: response.reason_phrase, body: response.body}
194
+ end
195
+
196
+ #
197
+ # Subscribe to an app at a path.
198
+ #
199
+ # Returns a Channel which has been created and opened and will begin
200
+ # to get back a stream of facts via its Receiver.
201
+ #
202
+ def subscribe(app:, path:)
203
+ (self.add_channel).subscribe(app: app, path: path)
204
+ end
205
+
206
+ def to_h
207
+ {name: "#{self.pat_p}", host: "#{self.config.host}", port: "#{self.config.port}"}
208
+ end
209
+
65
210
  def to_s
66
- "a Ship(name: '#{self.pat_p}', host: '#{self.config.host}', port: '#{self.config.port}')"
211
+ "a Ship(#{self.to_h})"
67
212
  end
68
213
 
69
214
  private
70
215
 
216
+ def add_channel
217
+ self.login
218
+ self.channels << (c = Channel.new(ship: self, name: self.make_channel_name))
219
+ c
220
+ end
221
+
222
+ def make_channel_name
223
+ "Channel-#{self.open_channels.count}"
224
+ end
225
+
71
226
  def ensure_connections_closed
72
227
  # Make sure all our created channels are closed by the GC
73
228
  ObjectSpace.define_finalizer( self, self.class.finalize(channels) )
74
229
  end
75
230
 
231
+ def login_url
232
+ "#{config.api_base_url}/~/login"
233
+ end
234
+
76
235
  def parse_cookie(resp)
77
236
  cookie = resp.headers['set-cookie']
78
237
  return unless cookie
@@ -80,9 +239,5 @@ module Urbit
80
239
  @auth_cookie, @path, @max_age = cookie.split(';')
81
240
  self.logged_in = true if @auth_cookie
82
241
  end
83
-
84
- def login_url
85
- "#{config.api_base_url}/~/login"
86
- end
87
242
  end
88
243
  end
@@ -1,19 +1,18 @@
1
- require 'json'
2
-
3
1
  module Urbit
4
2
  class SubscribeMessage < Message
5
3
  attr_reader :path
6
4
 
7
- def initialize(channel, app, path)
8
- @action = 'subscribe'
9
- @app = app
10
- @channel = channel
11
- @id = 0
12
- @path = path
5
+ def initialize(channel:, app:, path:)
6
+ super(channel: channel, app: app)
7
+ @path = path
8
+ end
9
+
10
+ def action
11
+ "subscribe"
13
12
  end
14
13
 
15
14
  def to_h
16
- {action: action, app: app, id: id, path: path, ship: ship.untilded_name}
15
+ {action: self.action, app: self.app, id: self.id, path: self.path, ship: self.ship.untilded_name}
17
16
  end
18
17
  end
19
18
  end
@@ -0,0 +1,51 @@
1
+ {
2
+ :status => 200,
3
+ :code => "ok",
4
+ :body =>" {
5
+ "graph-update": {
6
+ "add-graph": {
7
+ "graph":{},
8
+ "resource" : {
9
+ "name": "dec74689ad",
10
+ "ship": "zod"
11
+ },
12
+ "mark" : "graph-validator-chat",
13
+ "overwrite":true
14
+ }
15
+ }
16
+ }
17
+ }
18
+
19
+
20
+ {
21
+ "status": 200,
22
+ "code": "ok",
23
+ "body": {
24
+ "graph-update": {
25
+ "add-graph": {
26
+ "graph": {
27
+ "170141184505196673936784618510385938432": {
28
+ "post" : {
29
+ "index": "/170141184505196673936784618510385938432",
30
+ "author": "zod",
31
+ "time-sent": 1628715932642,
32
+ "signatures": [
33
+ {"signature": "0x2.7d8e.58d0.ee70.c720.e0c7.0fbe.40be.f68c.0401.950e.1bb8.9eda.cb66.3726.8995.3ca2.2d51.aa34.fcc8.ea00.1193.9145.38c9.7fea.8285.bd4e.d390.a195.f7e6.0870.5f7c.c73b.67a7.d19c.375b.fc29.aac7.6879.04fa.6a0f.cb7f.9001", "life": 1 ,"ship": "zod\}
34
+ ],
35
+ "contents": [
36
+ {"text" : "test?"}
37
+ ],
38
+ "hash": "0x9f63.9634.3b9c.31c8.3831.c3ef.902f.bda3"},
39
+ "children":null
40
+ }
41
+ },
42
+ "resource" : {
43
+ "name": "dec74689ad",
44
+ "ship": "zod"
45
+ },
46
+ "mark": "graph-validator-chat",
47
+ "overwrite": true
48
+ }
49
+ }
50
+ }
51
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ :status => 200,
3
+ :code => "ok",
4
+ :body => {
5
+ "graph-update": {
6
+ "keys": [
7
+ {"name": "announce", "ship": "darlur"},
8
+ {"name": "test0-996", "ship": "barsyr-latreb"},
9
+ {"name": "test1-4287", "ship": "barsyr-latreb"},
10
+ {"name": "welcome-to-urbit-community", "ship": "darrux-landes"},
11
+ {"name": "help-desk-4556", "ship": "darlur"}
12
+ ]
13
+ }
14
+ }
15
+ }
@@ -0,0 +1,34 @@
1
+ [1] pry(main)> ship = Urbit.connect(config_file: '_config-barsyr-latreb.yml')
2
+ => a Ship(name: '~barsyr-latreb', host: 'http://localhost', port: '8080')
3
+
4
+ [2] pry(main)> ship.scry('graph-store', "/graph/~darlur/announce/node/siblings/newest/lone/1")
5
+ =>
6
+ :status => 200,
7
+ :code => "ok",
8
+ :body => {
9
+ "graph-update": {
10
+ "add-nodes": {
11
+ "resource": {
12
+ "name": "announce",
13
+ "ship": "darlur"
14
+ },
15
+ "nodes" : {
16
+ "/170141184505036957608427254348286787584": {
17
+ "post" : {
18
+ "index": "/170141184505036957608427254348286787584",
19
+ "author": "darlur",
20
+ "time-sent": 1620057693019,
21
+ "signatures": [
22
+ {"signature": "0x5468.e5ec.1955.3e10.14a6.5fc0.054e.0e1b.fe01.1272.0a2c.e3c8.37a5.6717.ed7d.4b0c.3102.3966.4caa.edeb.e89e.3194.be17.f6a7.0622.4775.5e8f.7e92.16d2.c552.5ecd.d28b.17a6.aad5.089b.3623.eb8b.1b62.1525.0571.2d9f.9001", "life ": 3, "ship": "darlur"}
23
+ ],
24
+ "contents": [
25
+ {\"text\":\"We are now running urbit v1.5."}
26
+ ],
27
+ "hash": "0x5468.e5ec.1955.3e10.14a6.5fc0.054e.0e1b"
28
+ },
29
+ "children":null
30
+ }
31
+ }
32
+ }
33
+ }
34
+ }
@@ -0,0 +1,76 @@
1
+ [8] pry(main)> channel.receiver.facts.each {|f| puts f};nil
2
+ {:message => {
3
+ "ok" => "ok",
4
+ "id" => 1,
5
+ "response" => "subscribe"}
6
+ }
7
+ {:message => {
8
+ "json" => {
9
+ "graph-update" => {
10
+ "add-nodes" => {
11
+ "resource" => {
12
+ "name" => "top-shelf-6391",
13
+ "ship" => "winter-paches"
14
+ },
15
+ "nodes" => {
16
+ "/170141184505207442993270453156437819392" => {
17
+ "post" => {
18
+ "index"=>"/170141184505207442993270453156437819392",
19
+ "author"=>"winter-paches",
20
+ "time-sent"=>1629299723410,
21
+ "signatures"=>[{"signature"=>"0x1.5003.94a6.2a10.7baf.ba44.a4d9.0353.e61a.0200.fdb2.fccf.f760.e1a0.bd20.dafa.f17e.e759.c8ab.f3b2.bb03.ccfa.1f10.c060.b063.cf32.48f6.ce27.4cae.462a.a228.47e9.5642.6476.5664.a918.839b.4053.91fe.b08c.f18c.525f.7001", "life"=>3, "ship"=>"winter-paches"}],
22
+ "contents"=>[{"text"=>"i will be really sad if hockey goes even more the way of the other sports."}],
23
+ "hash"=>"0xa801.ca53.1508.3dd7.dd22.526c.81a9.f30d"},
24
+ "children"=>nil
25
+ }
26
+ }
27
+ }
28
+ }
29
+ }, "id"=>1, "response"=>"diff"}}
30
+ {:message => {
31
+ "json" => {
32
+ "graph-update"=>{"add-nodes"=>{"resource"=>{"name"=>"top-shelf-6391", "ship"=>"winter-paches"}, "nodes"=>{"/170141184505207446323799471187231244288"=>{"post"=>{"index"=>"/170141184505207446323799471187231244288", "author"=>"rivlyt-dotnet", "time-sent"=>1629299904766, "signatures"=>[{"signature"=>"0x668d.5edb.31d1.18ee.fb3a.7bd0.e6e6.6582.fe01.d7c0.61a7.aadf.c1b0.7e9c.26ad.8412.c3a5.6221.eff0.d25f.f505.18d9.693c.a888.debd.635d.c692.b138.9f5e.d52d.513d.291f.326b.2261.4a08.7680.58d0.e654.3556.bbd5.d43f.9001", "life"=>1, "ship"=>"rivlyt-dotnet"}], "contents"=>[{"url"=>"http://www.hockeyworldblog.com/wp-content/uploads/2009/07/SamiKapanenKalPa.jpg"}, {"text"=>""}], "hash"=>"0x668d.5edb.31d1.18ee.fb3a.7bd0.e6e6.6582"}, "children"=>nil}}}}}, "id"=>1, "response"=>"diff"}}
33
+ {:message => {
34
+ "json" => {
35
+ "graph-update" => {
36
+ "add-nodes" => {
37
+ "resource" => {
38
+ "name" => "dm-inbox",
39
+ "ship" => "barsyr-latreb"
40
+ },
41
+ "nodes" => {
42
+ "/3830645248/170141184505207462626569476439992696832" => {
43
+ "post" => {
44
+ "index" => "/3830645248/170141184505207462626569476439992696832",
45
+ "author" => "winter-paches",
46
+ "time-sent" => 1629300788090,
47
+ "signatures" => [
48
+ {"signature" => "0x8b2.4b04.d55d.38fb.3561.6840.7312.2c5d.3e80.6494.9c69.0c8c.5480.21d8.87e1.93d4.79ca.e299.8482.17d6.b1d5.075f.837e.e1c9.9776.1a10.1710.f62a.6f68.8415.e85f.62c9.ff0f.b5b7.e605.bb8f.ee6e.d856.8505.08eb.901f.5001",
49
+ "life"=>3,
50
+ "ship"=>"winter-paches"}
51
+ ],
52
+ "contents"=>[
53
+ {"text"=>"still there?"}
54
+ ],
55
+ "hash" => "0x22c9.2c13.5574.e3ec.d585.a101.cc48.b174"
56
+ },
57
+ "children" => {
58
+ "170141184505210800341365283904498434048" :{
59
+ "post" : {
60
+ "index": "/3830645248/170141184505210800341365283904498434048",
61
+ "author": "winter-paches",
62
+ "time-sent\":1629481725905,
63
+ "signatures\":[{\"signature\":\"0x2cbc.3fa5.5e05.1851.0bc0.c139.7356.86dc.fa01.24bf.82c7.078d.59b7.7365.de54.87de.6043.7cca.1bcc.5746.cb4e.6585.f81e.ab97.edf4.9b5e.e499.1df3.486f.965b.0247.6cdd.8ed8.2a70.37f1.f9ec.97dd.6d55.19f5.0b0d.e17f.9001\",\"life\":3,\"ship\":\"winter-paches\"}],
64
+ "contents\":[{\"text\":\"two\"}],
65
+ "hash\":\"0x2cbc.3fa5.5e05.1851.0bc0.c139.7356.86dc\"
66
+ },
67
+ "children": null
68
+ }
69
+ }
70
+ }
71
+ }
72
+ }
73
+ }
74
+ },
75
+ "id"=>1,
76
+ "response"=>"diff"}}
@@ -0,0 +1,20 @@
1
+ {
2
+ :message=> {
3
+ "json"=> {
4
+ "graph-update"=> {
5
+ "add-graph"=> {
6
+ "graph" => {
7
+ },
8
+ "resource" => {
9
+ "name" => "test1-4287",
10
+ "ship" => "barsyr-latreb"
11
+ },
12
+ "mark" => "graph-validator-publish",
13
+ "overwrite" => true
14
+ }
15
+ }
16
+ },
17
+ "id" => 2,
18
+ "response" => "diff"
19
+ }
20
+ }
@@ -0,0 +1,75 @@
1
+ {
2
+ :message => {
3
+ "json" => {
4
+ "graph-update" => {
5
+ "add-nodes" => {
6
+ "resource" => {
7
+ "name" => "test1-4287",
8
+ "ship" => "barsyr-latreb"
9
+ },
10
+ "nodes" => {
11
+ "/170141184505020984719232265951207489536/2" => {
12
+ "post" => {
13
+ "index" => "/170141184505020984719232265951207489536/2",
14
+ "author" => "barsyr-latreb",
15
+ "time-sent" => 1619191801085,
16
+ "signatures"=> [
17
+ {
18
+ "signature" => "0x1.284d.9ddd.b0ca.3b77.ce22.bea4.4fad.1018.0200.fb46.de9e.541a.7c0d.c680.20a3.986c.ce0f.944b.4f48.cdb1.64aa.bc8a.ce34.c7ee.bcc4.47ce.7dd2.8b98.12b8.c69b.98ae.73e3.3a40.592e.11b2.1445.6cbf.bfbc.6e60.6815.e1bf.7001",
19
+ "life"=>3,
20
+ "ship"=>"barsyr-latreb"
21
+ }
22
+ ],
23
+ "contents" => [],
24
+ "hash" =>"0x9426.ceee.d865.1dbb.e711.5f52.27d6.880c"
25
+ },
26
+ "children" => nil
27
+ },
28
+ "/170141184505020984719232265951207489536/1/1" => {
29
+ "post" => {
30
+ "index" => "/170141184505020984719232265951207489536/1/1",
31
+ "author" => "barsyr-latreb",
32
+ "time-sent" =>1619191801085,
33
+ "signatures" => [
34
+ {
35
+ "signature" => "0x4abf.c85f.4db6.bda6.a5ca.155c.f479.c1ee.0080.36c0.7fc4.fc07.5492.fba6.0eac.bcd1.6cde.3f05.46cb.7654.cb78.8baa.f398.37d6.5098.a7ce.6a07.6cfe.5f99.6ee2.b3a1.6717.ac2d.c396.6a86.5495.d88e.fc55.cbbf.0e1e.70ff.3001",
36
+ "life" =>3,
37
+ "ship" => "barsyr-latreb"
38
+ }
39
+ ],
40
+ "contents" => [
41
+ {"text" => "Post 1"},
42
+ {"text" => "First post of the graph store portion of the airlock implementation."}
43
+ ],
44
+ "hash" => "0x957f.90be.9b6d.7b4d.4b94.2ab9.e8f3.83dc"
45
+ },
46
+ "children" => nil
47
+ },
48
+ "/170141184505020984719232265951207489536"=>
49
+ {"post"=>
50
+ {"index"=>"/170141184505020984719232265951207489536",
51
+ "author"=>"barsyr-latreb",
52
+ "time-sent"=>1619191801085,
53
+ "signatures"=>
54
+ [{"signature"=>
55
+ "0x6401.1904.eca5.c18c.d9a4.cf52.d00d.6bc5.8080.247c.6a06.3709.44ce.ad7e.fd14.bccb.c982.3df6.dba3.c727.cccd.f433.47b5.2342.780c.0b27.4fd8.85eb.4c67.5466.565c.3fc6.66c5.1832.72da.2557.940b.3549.14a7.66ab.e1df.3001",
56
+ "life"=>3,
57
+ "ship"=>"barsyr-latreb"}],
58
+ "contents"=>[],
59
+ "hash"=>"0xc802.3209.d94b.8319.b349.9ea5.a01a.d78b"},
60
+ "children"=>nil},
61
+ "/170141184505020984719232265951207489536/1"=>
62
+ {"post"=>
63
+ {"index"=>"/170141184505020984719232265951207489536/1",
64
+ "author"=>"barsyr-latreb",
65
+ "time-sent"=>1619191801085,
66
+ "signatures"=>
67
+ [{"signature"=>
68
+ "0x1.284d.9ddd.b0ca.3b77.ce22.bea4.4fad.1018.0200.fb46.de9e.541a.7c0d.c680.20a3.986c.ce0f.944b.4f48.cdb1.64aa.bc8a.ce34.c7ee.bcc4.47ce.7dd2.8b98.12b8.c69b.98ae.73e3.3a40.592e.11b2.1445.6cbf.bfbc.6e60.6815.e1bf.7001",
69
+ "life"=>3,
70
+ "ship"=>"barsyr-latreb"}],
71
+ "contents"=>[],
72
+ "hash"=>"0x9426.ceee.d865.1dbb.e711.5f52.27d6.880c"},
73
+ "children"=>nil}}}}},
74
+ "id"=>2,
75
+ "response"=>"diff"}}
data/misc/post ADDED
@@ -0,0 +1,12 @@
1
+ "post" => {
2
+ "index" => "/170141184504863525594513045663867817951",
3
+ "author" => "barsyr-latreb",
4
+ "time-sent" => 1610655924876,
5
+ "signatures" => [],
6
+ "contents" => [
7
+ {"text" => "~all : another new planet has coalesced..."},
8
+ {"mention"=> "barsyr-latreb"},
9
+ {"text" => "."}
10
+ ],
11
+ "hash" => nil
12
+ },
@@ -0,0 +1,52 @@
1
+ ship.scry(app: 'settings-store', path: '/desk/landscape', mark: 'json')
2
+
3
+ {
4
+ :status => 200,
5
+ :code => "ok",
6
+ :body => {
7
+ "desk": {
8
+ "calm": {
9
+ "hideAvatars": true,
10
+ "hideNicknames": true
11
+ },
12
+ "urbit-visor-permissions": {
13
+ "https://urbitdashboard.com": [
14
+ "shipName", "shipURL", "scry", "subscribe", "poke", "thread"
15
+ ]
16
+ }
17
+ }
18
+ }
19
+ }
20
+
21
+
22
+ pry(main)> ship.subscribe(app: 'settings-store', path: '/all')
23
+ => a Channel (Open) on ~barsyr-latreb(name: 'Channel-0', key: '164192001782807f')
24
+
25
+ pry(main)> Received a Fact for [a Channel (Open) on ~barsyr-latreb(name: 'Channel-0', key: '164192001782807f')
26
+ ] -- [message
27
+ ] -- [
28
+ {
29
+ "ok": "ok",
30
+ "id": 1,
31
+ "response": "subscribe"
32
+ }
33
+ ]
34
+
35
+ pry(main)> Received a Fact for [a Channel (Open) on ~barsyr-latreb(name: 'Channel-0', key: '164192001782807f')
36
+ ] -- [message
37
+ ] -- [
38
+ {
39
+ "json": {
40
+ "settings-event": {
41
+ "put-entry": {
42
+ "bucket-key": "calm",
43
+ "desk": "landscape",
44
+ "entry-key": "hideUnreads",
45
+ "value": true
46
+ }
47
+ }
48
+ },
49
+ "id": 1,
50
+ "response": "diff"
51
+ }
52
+ ]
data/urbit-api.gemspec CHANGED
@@ -4,7 +4,7 @@ Gem::Specification.new do |spec|
4
4
  spec.name = "urbit-api"
5
5
  spec.version = Urbit::Api::VERSION
6
6
  spec.authors = ["Daryl Richter"]
7
- spec.email = ["daryl@deliverycircle.com"]
7
+ spec.email = ["daryl@ngzax.com"]
8
8
 
9
9
  spec.summary = %q{The Ruby interface to the Urbit HTTP API}
10
10
  spec.description = %q{Access your urbit ship the ruby way. It's a Martian gem.}
@@ -13,8 +13,6 @@ Gem::Specification.new do |spec|
13
13
 
14
14
  spec.required_ruby_version = Gem::Requirement.new(">= 2.7.2")
15
15
 
16
- # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
17
-
18
16
  spec.metadata["homepage_uri"] = spec.homepage
19
17
  spec.metadata["source_code_uri"] = "https://github.com/Zaxonomy/urbit-ruby"
20
18
  spec.metadata["changelog_uri"] = "https://github.com/Zaxonomy/urbit-ruby/CHANGELOG.md"