urbit-api 0.2.1 → 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.
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: