urbit-api 0.1.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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"