urbit-api 0.2.1 → 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/README.md +26 -0
- data/lib/urbit/api/version.rb +1 -1
- data/lib/urbit/fact.rb +158 -18
- data/lib/urbit/parser.rb +14 -0
- data/lib/urbit/receiver.rb +1 -1
- data/lib/urbit/setting.rb +30 -0
- data/lib/urbit/ship.rb +40 -4
- data/misc/settings-store.json +52 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2cef1b4e2c8a8a7ef8ba203f66e92e516e563c7b32119e98ee55366983e72dd3
|
4
|
+
data.tar.gz: dc6267d7c21e034c6725309a15678b09b4e0d8713990b5e975c94ef25475caed
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9b19087253b1b6864e0941b94513f530aee01856357d590468e670273412a273a8ad4e514bc21c21ea86bc24877e4cc72b9ce475cbf218c2f53efafd462e2cb7
|
7
|
+
data.tar.gz: 1443c08a0370fd78bf33dca3c701aba09669421d434b10a475544a0828fe1eaae3ac1a222aa963654e29e800b3f7ab019efd73bbd2d9dbb6b00f4c775f52e63c
|
data/README.md
CHANGED
@@ -187,6 +187,32 @@ a Node({:index=>"170.141.184.505.209.627.337.970.761.265.544.429.568", :author=>
|
|
187
187
|
"170.141.184.505.209.375.247.350.471.711.992.578.048"
|
188
188
|
"170.141.184.505.209.545.972.004.310.065.795.301.376"
|
189
189
|
"170.141.184.505.209.627.337.970.761.265.544.429.568"
|
190
|
+
|
191
|
+
#
|
192
|
+
# --------------------------------------------------------------------
|
193
|
+
# %settings-store
|
194
|
+
# --------------------------------------------------------------------
|
195
|
+
#
|
196
|
+
> ship.setting(desk: 'landscape', bucket: 'calm').each {|e| p e};nil
|
197
|
+
["hideUtilities", false]
|
198
|
+
["hideGroups", false]
|
199
|
+
["hideAvatars", true]
|
200
|
+
["hideUnreads", true]
|
201
|
+
["hideNicknames", true]
|
202
|
+
|
203
|
+
> ship.subscribe(app: 'settings-store', path: '/all')
|
204
|
+
=> a Channel (Open) on ~barsyr-latreb(name: 'Channel-0', key: '164375139513eacb')
|
205
|
+
|
206
|
+
# We are now listening for changes in any settings on the ship. Go to Landscape and toggle the "Hide Groups" button...
|
207
|
+
Received a Fact for [a Channel (Open) on ~barsyr-latreb(name: 'Channel-0', key: '164375139513eacb')] -- [message] -- [{"json":{"settings-event":{"put-entry":{"bucket-key":"calm","desk":"landscape","entry-key":"hideGroups","value":true}}},"id":1,"response":"diff"}]
|
208
|
+
|
209
|
+
> ship.setting(desk: 'landscape', bucket: 'calm').each {|e| p e};nil
|
210
|
+
["hideUtilities", false]
|
211
|
+
**["hideGroups", true]**
|
212
|
+
["hideAvatars", true]
|
213
|
+
["hideUnreads", true]
|
214
|
+
["hideNicknames", true]
|
215
|
+
|
190
216
|
```
|
191
217
|
### Configuration
|
192
218
|
|
data/lib/urbit/api/version.rb
CHANGED
data/lib/urbit/fact.rb
CHANGED
@@ -10,39 +10,48 @@ module Urbit
|
|
10
10
|
@channel = channel
|
11
11
|
@data = event.data
|
12
12
|
@type = event.type
|
13
|
+
puts "Received a Fact for [#{channel}] -- [#{@type}] -- [#{@data}]"
|
14
|
+
end
|
13
15
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
#
|
17
|
+
# This is a Facotry method to make the proper Fact subclass from
|
18
|
+
# a Channel Event.
|
19
|
+
#
|
20
|
+
def self.collect(channel:, event:)
|
21
|
+
contents = JSON.parse(event.data)
|
22
|
+
return Fact.new(channel: channel, event: event) if contents["json"].nil?
|
23
|
+
return SettingsEventFact.new(channel: channel, event: event) if contents["json"]["settings-event"]
|
24
|
+
|
25
|
+
return Fact.new(channel: channel, event: event) if contents["json"]["graph-update"].nil?
|
26
|
+
return AddGraphFact.new(channel: channel, event: event) if contents["json"]["graph-update"]["add-graph"]
|
27
|
+
return AddNodesFact.new(channel: channel, event: event) if contents["json"]["graph-update"]["add-nodes"]
|
28
|
+
return RemoveGraphFact.new(channel: channel, event: event) if contents["json"]["graph-update"]["remove-graph"]
|
29
|
+
|
30
|
+
return Fact.new(channel: channel, event: event)
|
19
31
|
end
|
20
32
|
|
21
33
|
def add_ack(ack:)
|
22
34
|
@ack = :ack
|
23
35
|
end
|
24
36
|
|
25
|
-
def add_nodes_json
|
26
|
-
return nil unless self.graph_update?
|
27
|
-
self.contents["json"]["graph-update"]["add-nodes"]
|
28
|
-
end
|
29
|
-
|
30
37
|
def contents
|
31
38
|
JSON.parse(@data)
|
32
39
|
end
|
33
40
|
|
41
|
+
def for_this_ship?
|
42
|
+
self.ship == @channel.ship
|
43
|
+
end
|
44
|
+
|
34
45
|
def graph_update?
|
35
|
-
|
46
|
+
false
|
36
47
|
end
|
37
48
|
|
38
49
|
def is_acknowledged?
|
39
50
|
!@ack.nil?
|
40
51
|
end
|
41
52
|
|
42
|
-
def
|
43
|
-
|
44
|
-
r = self.contents["json"]["graph-update"]["add-nodes"]["resource"]
|
45
|
-
"~#{r["ship"]}/#{r["name"]}"
|
53
|
+
def raw_json
|
54
|
+
nil
|
46
55
|
end
|
47
56
|
|
48
57
|
def ship
|
@@ -52,15 +61,146 @@ module Urbit
|
|
52
61
|
def to_h
|
53
62
|
{
|
54
63
|
ship: self.ship.to_h,
|
55
|
-
resource: self.resource,
|
56
64
|
acknowleged: self.is_acknowledged?,
|
57
65
|
is_graph_update: self.graph_update?
|
58
|
-
# contents: self.contents
|
59
66
|
}
|
60
67
|
end
|
61
68
|
|
62
69
|
def to_s
|
63
|
-
"a
|
70
|
+
"a #{self.class.name}(#{self.to_h})"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
class GraphUpdateFact < Fact
|
75
|
+
def initialize(channel:, event:)
|
76
|
+
super channel: channel, event: event
|
77
|
+
end
|
78
|
+
|
79
|
+
#
|
80
|
+
# Attach this new fact as a node to its Graph.
|
81
|
+
#
|
82
|
+
def attach_parser
|
83
|
+
# puts "Received a graph update for [#{self.ship.graph(resource: self.resource)}]"
|
84
|
+
if self.incoming_graph
|
85
|
+
# puts "Received an add_graph event: #{self.raw_json} on #{self.resource}"
|
86
|
+
self.create_parser
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def create_parser
|
91
|
+
nil
|
92
|
+
end
|
93
|
+
|
94
|
+
def graph_update?
|
95
|
+
true
|
96
|
+
end
|
97
|
+
|
98
|
+
def incoming_graph
|
99
|
+
self.ship.graph(resource: self.resource)
|
100
|
+
end
|
101
|
+
|
102
|
+
def resource
|
103
|
+
return "~#{self.resource_h["ship"]}/#{self.resource_h["name"]}" unless self.resource_h.nil?
|
104
|
+
end
|
105
|
+
|
106
|
+
def resource_h
|
107
|
+
self.raw_json["resource"]
|
108
|
+
end
|
109
|
+
|
110
|
+
def root_h
|
111
|
+
self.contents["json"]["graph-update"]
|
112
|
+
end
|
113
|
+
|
114
|
+
def to_h
|
115
|
+
super.merge!(resource: self.resource)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
class AddGraphFact < GraphUpdateFact
|
120
|
+
def initialize(channel:, event:)
|
121
|
+
super channel: channel, event: event
|
122
|
+
end
|
123
|
+
|
124
|
+
def create_parser
|
125
|
+
Urbit::AddGraphParser.new(for_graph: incoming_graph, with_json: self.raw_json).add_nodes
|
126
|
+
end
|
127
|
+
|
128
|
+
def raw_json
|
129
|
+
self.root_h["add-graph"]
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
class AddNodesFact < GraphUpdateFact
|
134
|
+
def initialize(channel:, event:)
|
135
|
+
super channel: channel, event: event
|
136
|
+
end
|
137
|
+
|
138
|
+
def create_parser
|
139
|
+
Urbit::AddNodesParser.new(for_graph: incoming_graph, with_json: self.raw_json).add_nodes
|
140
|
+
end
|
141
|
+
|
142
|
+
def raw_json
|
143
|
+
self.root_h["add-nodes"]
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
class RemoveGraphFact < GraphUpdateFact
|
148
|
+
def initialize(channel:, event:)
|
149
|
+
super channel: channel, event: event
|
150
|
+
end
|
151
|
+
|
152
|
+
def create_parser
|
153
|
+
Urbit::RemoveGraphParser.new(for_graph: incoming_graph, with_json: self.raw_json)
|
154
|
+
end
|
155
|
+
|
156
|
+
def raw_json
|
157
|
+
self.root_h["remove-graph"]
|
158
|
+
end
|
159
|
+
|
160
|
+
def resource_h
|
161
|
+
self.raw_json
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
class SettingsEventFact < Fact
|
166
|
+
def initialize(channel:, event:)
|
167
|
+
super channel: channel, event: event
|
168
|
+
|
169
|
+
if self.for_this_ship?
|
170
|
+
# See if we already have this setting, if no add it, if yes update it.
|
171
|
+
if (entries = channel.ship.setting(bucket: self.bucket))
|
172
|
+
entries[self.entry] = self.value
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def bucket
|
178
|
+
self.contents["bucket-key"]
|
179
|
+
end
|
180
|
+
|
181
|
+
def contents
|
182
|
+
JSON.parse(@data)["json"]["settings-event"]["put-entry"]
|
183
|
+
end
|
184
|
+
|
185
|
+
def desk
|
186
|
+
self.contents["desk"]
|
187
|
+
end
|
188
|
+
|
189
|
+
def entry
|
190
|
+
self.contents["entry-key"]
|
191
|
+
end
|
192
|
+
|
193
|
+
def to_h
|
194
|
+
super.merge!({
|
195
|
+
bucket: self.bucket,
|
196
|
+
desk: self.desk,
|
197
|
+
entry: self.entry,
|
198
|
+
value: self.value
|
199
|
+
})
|
200
|
+
end
|
201
|
+
|
202
|
+
def value
|
203
|
+
self.contents["value"]
|
64
204
|
end
|
65
205
|
end
|
66
206
|
end
|
data/lib/urbit/parser.rb
CHANGED
@@ -38,6 +38,9 @@ module Urbit
|
|
38
38
|
@j["graph"]
|
39
39
|
end
|
40
40
|
|
41
|
+
def resource_hash
|
42
|
+
@j["resource"]
|
43
|
+
end
|
41
44
|
end
|
42
45
|
|
43
46
|
class AddNodesParser < Parser
|
@@ -45,4 +48,15 @@ module Urbit
|
|
45
48
|
@j["nodes"]
|
46
49
|
end
|
47
50
|
end
|
51
|
+
|
52
|
+
class RemoveGraphParser < Parser
|
53
|
+
def nodes_hash
|
54
|
+
nil
|
55
|
+
end
|
56
|
+
|
57
|
+
def resource_hash
|
58
|
+
@j["resource"]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
48
62
|
end
|
data/lib/urbit/receiver.rb
CHANGED
@@ -13,7 +13,7 @@ module Urbit
|
|
13
13
|
# We are now listening on a socket for SSE::Events. This block will be called for each one.
|
14
14
|
rec.on_event do |event|
|
15
15
|
# Wrap the returned event in a Fact.
|
16
|
-
@facts << (f = Fact.
|
16
|
+
@facts << (f = Fact.collect(channel: channel, event: event))
|
17
17
|
|
18
18
|
# We need to acknowlege each message or urbit will eventually disconnect us.
|
19
19
|
# We record the ack with the Fact itself.
|
@@ -0,0 +1,30 @@
|
|
1
|
+
|
2
|
+
module Urbit
|
3
|
+
class Setting
|
4
|
+
attr_reader :bucket
|
5
|
+
|
6
|
+
def initialize(ship:, desk:, setting:)
|
7
|
+
@ship = ship
|
8
|
+
@desk = desk
|
9
|
+
@bucket = setting.first
|
10
|
+
@entries = setting.last
|
11
|
+
end
|
12
|
+
|
13
|
+
def entries(bucket: nil)
|
14
|
+
return @entries if (bucket.nil? || @bucket == bucket)
|
15
|
+
{}
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_h
|
19
|
+
{
|
20
|
+
desk: @desk,
|
21
|
+
bucket: self.bucket,
|
22
|
+
entries: self.entries
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_s
|
27
|
+
"a Setting(#{self.to_h})"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/urbit/ship.rb
CHANGED
@@ -3,6 +3,7 @@ require 'faraday'
|
|
3
3
|
require 'urbit/channel'
|
4
4
|
require 'urbit/config'
|
5
5
|
require 'urbit/graph'
|
6
|
+
require 'urbit/setting'
|
6
7
|
|
7
8
|
module Urbit
|
8
9
|
class Ship
|
@@ -14,6 +15,7 @@ module Urbit
|
|
14
15
|
@channels = []
|
15
16
|
@config = config
|
16
17
|
@graphs = []
|
18
|
+
@settings = []
|
17
19
|
@logged_in = false
|
18
20
|
end
|
19
21
|
|
@@ -73,7 +75,7 @@ module Urbit
|
|
73
75
|
config.name
|
74
76
|
end
|
75
77
|
|
76
|
-
def remove_graph(graph:)
|
78
|
+
def remove_graph(desk: 'landscape', graph:)
|
77
79
|
delete_json = %Q({
|
78
80
|
"delete": {
|
79
81
|
"resource": {
|
@@ -83,13 +85,47 @@ module Urbit
|
|
83
85
|
}
|
84
86
|
})
|
85
87
|
|
86
|
-
spider = self.spider(mark_in: 'graph-view-action', mark_out: 'json', thread: 'graph-delete', data: delete_json, args: ["NO_RESPONSE"])
|
88
|
+
spider = self.spider(desk: desk, mark_in: 'graph-view-action', mark_out: 'json', thread: 'graph-delete', data: delete_json, args: ["NO_RESPONSE"])
|
87
89
|
if (retcode = (200 == spider[:status]))
|
88
90
|
self.graphs.delete graph
|
89
91
|
end
|
90
92
|
retcode
|
91
93
|
end
|
92
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
|
+
|
93
129
|
def untilded_name
|
94
130
|
name.gsub('~', '')
|
95
131
|
end
|
@@ -125,9 +161,9 @@ module Urbit
|
|
125
161
|
{status: response.status, code: response.reason_phrase, body: response.body}
|
126
162
|
end
|
127
163
|
|
128
|
-
def spider(mark_in:, mark_out:, thread:, data:, args: [])
|
164
|
+
def spider(desk: 'landscape', mark_in:, mark_out:, thread:, data:, args: [])
|
129
165
|
self.login
|
130
|
-
url = "#{self.config.api_base_url}/spider/#{mark_in}/#{thread}/#{mark_out}.json"
|
166
|
+
url = "#{self.config.api_base_url}/spider/#{desk}/#{mark_in}/#{thread}/#{mark_out}.json"
|
131
167
|
|
132
168
|
# TODO: This is a huge hack due to the fact that certain spider operations are known to
|
133
169
|
# not return when they should. Instead I just set the timeout low and catch the
|
@@ -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
|
+
]
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: urbit-api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daryl Richter
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-02-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -100,6 +100,7 @@ files:
|
|
100
100
|
- lib/urbit/parser.rb
|
101
101
|
- lib/urbit/poke_message.rb
|
102
102
|
- lib/urbit/receiver.rb
|
103
|
+
- lib/urbit/setting.rb
|
103
104
|
- lib/urbit/ship.rb
|
104
105
|
- lib/urbit/subscribe_message.rb
|
105
106
|
- lib/urbit/urbit.rb
|
@@ -110,6 +111,7 @@ files:
|
|
110
111
|
- misc/graph-update_add-graph
|
111
112
|
- misc/graph-update_add-nodes
|
112
113
|
- misc/post
|
114
|
+
- misc/settings-store.json
|
113
115
|
- urbit-api.gemspec
|
114
116
|
homepage: https://www.ngzax.com
|
115
117
|
licenses:
|