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.
- checksums.yaml +4 -4
- data/.ruby-version +2 -1
- data/README.md +191 -32
- data/bin/console +6 -3
- data/lib/urbit/ack_message.rb +14 -9
- data/lib/urbit/api/version.rb +1 -1
- data/lib/urbit/channel.rb +33 -22
- data/lib/urbit/chat_channel.rb +22 -0
- data/lib/urbit/close_message.rb +15 -0
- data/lib/urbit/fact.rb +206 -0
- data/lib/urbit/graph.rb +143 -0
- data/lib/urbit/message.rb +18 -24
- data/lib/urbit/node.rb +152 -0
- data/lib/urbit/parser.rb +62 -0
- data/lib/urbit/poke_message.rb +7 -0
- data/lib/urbit/receiver.rb +30 -10
- data/lib/urbit/setting.rb +30 -0
- data/lib/urbit/ship.rb +170 -15
- data/lib/urbit/subscribe_message.rb +8 -9
- data/misc/graph-store_graph +51 -0
- data/misc/graph-store_keys +15 -0
- data/misc/graph-store_node +34 -0
- data/misc/graph-store_update +76 -0
- data/misc/graph-update_add-graph +20 -0
- data/misc/graph-update_add-nodes +75 -0
- data/misc/post +12 -0
- data/misc/settings-store.json +52 -0
- data/urbit-api.gemspec +1 -3
- metadata +20 -4
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(
|
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
|
8
|
-
|
9
|
-
@
|
10
|
-
|
11
|
-
|
12
|
-
|
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@
|
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"
|