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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 466e396f78dad90e05ab4b1010f8c6638ab79468f9adf47f6704ab91f39c4a29
4
- data.tar.gz: cf2ca6d9f02d70f0a2cd421cc3b1a28d95ba612842ee5a8b6faea6738d3e8e1c
3
+ metadata.gz: 2cef1b4e2c8a8a7ef8ba203f66e92e516e563c7b32119e98ee55366983e72dd3
4
+ data.tar.gz: dc6267d7c21e034c6725309a15678b09b4e0d8713990b5e975c94ef25475caed
5
5
  SHA512:
6
- metadata.gz: c8012c2739134932ec79654cd9a33edb993dcb88304195574d890bad04bc82e2c6e47ca0f46cae5e3fc288deae7766f173ed7ee25c5f9f9e86fad6a66588cdae
7
- data.tar.gz: 402992b7ee1782c62025f75d9c1c537ad267db4397346bb04961988c2cfde0d1dc6f233a44f3c8067e0023c22b07c215f9a633d0f33d5325fea4dc6a9650c7dd
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
 
@@ -1,5 +1,5 @@
1
1
  module Urbit
2
2
  module Api
3
- VERSION = "0.2.1"
3
+ VERSION = "0.3.0"
4
4
  end
5
5
  end
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
- # Attach this new fact as a node to its Graph.
15
- if self.graph_update?
16
- puts self.add_nodes_json
17
- Urbit::AddNodesParser.new(for_graph: (self.ship.graph(resource: self.resource)), with_json: self.add_nodes_json).add_nodes
18
- end
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
- !self.contents["json"].nil? && !self.contents["json"]["graph-update"].nil?
46
+ false
36
47
  end
37
48
 
38
49
  def is_acknowledged?
39
50
  !@ack.nil?
40
51
  end
41
52
 
42
- def resource
43
- return nil unless self.graph_update?
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 Fact(#{self.to_h})"
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
@@ -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.new(channel: channel, event: event))
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.2.1
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: 2021-10-09 00:00:00.000000000 Z
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: