urbit-api 0.1.0 → 0.1.2
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 +4 -4
- data/README.md +86 -16
- data/lib/urbit/ack_message.rb +5 -8
- data/lib/urbit/api/version.rb +1 -1
- data/lib/urbit/channel.rb +10 -2
- data/lib/urbit/close_message.rb +11 -0
- data/lib/urbit/message.rb +2 -13
- data/lib/urbit/poke_message.rb +7 -0
- data/lib/urbit/receiver.rb +4 -4
- data/lib/urbit/ship.rb +44 -14
- data/lib/urbit/subscribe_message.rb +3 -8
- data/urbit-api.gemspec +0 -2
- 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: 8ffd645b7c5236244e5c081587835863586b11d035d3197e7e286fa223bc3c0f
|
4
|
+
data.tar.gz: 19e8360fbdf96a1149a99dc7218bd835ac3af5338f5ff0b0cfc0c907ea383f27
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 84a0d8b5144e08a43080f3d4b0caaecba73e9fd5a74f2d5f1c04f66f1577dc64ebdf44e2fb91716c2ce746b4c96062e0615a24c5a54d760fd1a0ae9ec8b9af36
|
7
|
+
data.tar.gz: 41e5ffab8a9b67bce7c1373ee932ab17834e5684da3de41bb6bc19fa44b115e0fea4472e78e672b4ddd7c74c4e970ba0a20cf9123f27db1d5b763d67ca1f2185
|
data/README.md
CHANGED
@@ -3,6 +3,8 @@
|
|
3
3
|
|
4
4
|
This library wraps the Urbit ship http interface exposing it as a Ruby gem.
|
5
5
|
|
6
|
+
[](https://github.com/urbit/awesome-urbit)
|
7
|
+
|
6
8
|
## Installation
|
7
9
|
|
8
10
|
Add this line to your application's Gemfile:
|
@@ -21,39 +23,107 @@ Or install it yourself as:
|
|
21
23
|
|
22
24
|
## Usage
|
23
25
|
|
24
|
-
```
|
25
|
-
|
26
|
-
require 'urbit/urbit'
|
26
|
+
```sh
|
27
|
+
> bin/console
|
27
28
|
|
28
29
|
# This will instantiate a ship that connects to the fake `~zod` dev server by default
|
29
30
|
# See Urbit docs for more info: https://urbit.org/using/develop/
|
30
|
-
ship = Urbit.new
|
31
|
+
[1] pry(main)> ship = Urbit.new
|
31
32
|
# => #<Urbit::Ship:0x00007fa74b87f920 ...
|
32
33
|
|
33
|
-
|
34
|
+
OR... with config file...
|
35
|
+
> ship = Urbit.connect(config_file: '_config-barsyr-latreb.yml')
|
36
|
+
|
37
|
+
> ship.logged_in?
|
34
38
|
# => false
|
35
39
|
|
36
|
-
ship.login
|
40
|
+
> ship.login
|
37
41
|
# => #<Urbit::Ship:0x00007fa74b87f920 ...
|
38
42
|
|
39
|
-
ship.logged_in?
|
43
|
+
> ship.logged_in?
|
40
44
|
# => true
|
41
45
|
|
42
|
-
|
43
|
-
# =>
|
46
|
+
> ship.to_s
|
47
|
+
# => "a Ship(name: '~barsyr-latreb', host: 'http://localhost', port: '8080')"
|
44
48
|
|
45
|
-
|
46
|
-
# =>
|
49
|
+
> receiver = ship.subscribe('graph-store', '/updates')
|
50
|
+
# => #<Urbit::Receiver:0x00007fd3928eba58
|
51
|
+
|
52
|
+
# Subscribing works by opening a Channel. Your ships has a collection of all it's open Channels.
|
53
|
+
> channel = ship.open_channels.first
|
54
|
+
# => #<Urbit::Channel:0x00007fa74b291e50 ...
|
47
55
|
|
48
|
-
|
56
|
+
# Every Channel has a unique key to identify it.
|
57
|
+
> channel.key
|
49
58
|
# => "16142890875c348d"
|
50
59
|
|
51
|
-
receiver
|
52
|
-
|
60
|
+
# The receiver will now be listening on the app and path you specified. Each time an event is sent in it will be stored in the receiver's facts collection.
|
61
|
+
> receiver.facts.count
|
62
|
+
=> 12
|
63
|
+
|
64
|
+
> receiver.facts.last
|
65
|
+
=> {:message=>
|
66
|
+
{"json"=>
|
67
|
+
{"graph-update"=>
|
68
|
+
{"add-nodes"=>
|
69
|
+
{"resource"=>{"name"=>"test0-996", "ship"=>"barsyr-latreb"},
|
70
|
+
"nodes"=>
|
71
|
+
{"/170141184504954066298369929365830487769"=>
|
72
|
+
{"post"=>
|
73
|
+
{"index"=>"/170141184504954066298369929365830487769",
|
74
|
+
"author"=>"barsyr-latreb",
|
75
|
+
"time-sent"=>1615564146267,
|
76
|
+
"signatures"=>[],
|
77
|
+
"contents"=>[],
|
78
|
+
"hash"=>"0x92b0.c976.58f0.3035.c126.64a0.3043.b962"},
|
79
|
+
"children"=>
|
80
|
+
{"2"=>
|
81
|
+
{"post"=>
|
82
|
+
{"index"=>"/170141184504954066298369929365830487769/2",
|
83
|
+
"author"=>"barsyr-latreb",
|
84
|
+
"time-sent"=>1615564146267,
|
85
|
+
"signatures"=>[],
|
86
|
+
"contents"=>[],
|
87
|
+
"hash"=>"0x2ffe.3ca7.20eb.11af.51f8.fbab.2b88.9f48"},
|
88
|
+
"children"=>nil},
|
89
|
+
"1"=>
|
90
|
+
{"post"=>
|
91
|
+
{"index"=>"/170141184504954066298369929365830487769/1",
|
92
|
+
"author"=>"barsyr-latreb",
|
93
|
+
"time-sent"=>1615564146267,
|
94
|
+
"signatures"=>[],
|
95
|
+
"contents"=>[],
|
96
|
+
"hash"=>"0x2ffe.3ca7.20eb.11af.51f8.fbab.2b88.9f48"},
|
97
|
+
"children"=>
|
98
|
+
{"1"=>
|
99
|
+
{"post"=>
|
100
|
+
{"index"=>"/170141184504954066298369929365830487769/1/1",
|
101
|
+
"author"=>"barsyr-latreb",
|
102
|
+
"time-sent"=>1615564146267,
|
103
|
+
"signatures"=>[],
|
104
|
+
"contents"=>[{"text"=>"Test 0.8"}, {"text"=>"Test 0.8"}],
|
105
|
+
"hash"=>"0x9516.25fc.ca7a.5bb9.356b.2fce.b29a.f372"},
|
106
|
+
"children"=>nil}}}}}}}}},
|
107
|
+
"id"=>2,
|
108
|
+
"response"=>"diff"
|
109
|
+
}
|
110
|
+
}
|
111
|
+
|
112
|
+
# Your ship keeps a collection of all the messages sent to urbit:
|
113
|
+
> channel.sent_messages.collect {|m| m.to_s}
|
114
|
+
=> [
|
115
|
+
"a Message({:action=>"poke", :app=>"hood", :id=>1, :json=>"Opening Airlock", :mark=>"helm-hi", :ship=>"barsyr-latreb"})",
|
116
|
+
"a Message({:action=>"subscribe", :app=>"graph-store", :id=>2, :path=>"/updates", :ship=>"barsyr-latreb"})",
|
117
|
+
"a Message({"id"=>3, "action"=>"ack", "event-id"=>"0"})",
|
118
|
+
"a Message({"id"=>4, "action"=>"ack", "event-id"=>"1"})",
|
119
|
+
"a Message({"id"=>5, "action"=>"ack", "event-id"=>"2"})"
|
120
|
+
]
|
121
|
+
|
122
|
+
# Retrieving your ship's base hash using scry....
|
123
|
+
> ship.scry('file-server', '/clay/base/hash', 'json')
|
124
|
+
# => {:status=>200, :code=>"ok", :body=>"\"e75k5\""}
|
53
125
|
|
54
|
-
# This receiver will now be listening on the app and path you specified. Each time an event is sent in it will be stored in the receiver's events collection.
|
55
126
|
```
|
56
|
-
|
57
127
|
### Configuration
|
58
128
|
|
59
129
|
Configure your ship using a config file or constructor keyword arguments. Either or both can be used; the keyword args will override any values set via config file.
|
data/lib/urbit/ack_message.rb
CHANGED
@@ -1,18 +1,15 @@
|
|
1
|
-
require 'json'
|
2
|
-
|
3
|
-
require 'urbit/message'
|
4
|
-
|
5
1
|
module Urbit
|
6
2
|
class AckMessage < Message
|
3
|
+
attr_reader :ack_id
|
4
|
+
|
7
5
|
def initialize(channel, sse_message_id)
|
8
|
-
|
9
|
-
@channel = channel
|
10
|
-
@id = 0
|
6
|
+
super(channel, 'ack')
|
11
7
|
@ack_id = sse_message_id
|
12
8
|
end
|
13
9
|
|
14
10
|
def to_h
|
15
|
-
|
11
|
+
# Need to use the older hash style due to the key having a dash.
|
12
|
+
{'id' => self.id, 'action' => self.action, 'event-id' => self.ack_id}
|
16
13
|
end
|
17
14
|
end
|
18
15
|
end
|
data/lib/urbit/api/version.rb
CHANGED
data/lib/urbit/channel.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
-
require 'faraday'
|
2
1
|
require 'securerandom'
|
3
2
|
|
4
3
|
require 'urbit/message'
|
5
4
|
require 'urbit/receiver'
|
5
|
+
require 'urbit/close_message'
|
6
|
+
require 'urbit/poke_message'
|
6
7
|
require 'urbit/subscribe_message'
|
7
8
|
|
8
9
|
module Urbit
|
@@ -29,8 +30,11 @@ module Urbit
|
|
29
30
|
!@is_open
|
30
31
|
end
|
31
32
|
|
33
|
+
#
|
34
|
+
# We open a channel by "poking" the urbit app 'hood' using the mark 'helm-hi'
|
35
|
+
#
|
32
36
|
def open(a_message_string)
|
33
|
-
m = Urbit::
|
37
|
+
m = Urbit::PokeMessage.new(self, "hood", "helm-hi", a_message_string)
|
34
38
|
@is_open = self.send_message(m)
|
35
39
|
end
|
36
40
|
|
@@ -58,6 +62,10 @@ module Urbit
|
|
58
62
|
self.open? ? "Open" : "Closed"
|
59
63
|
end
|
60
64
|
|
65
|
+
#
|
66
|
+
# Subscribe to an app at a path.
|
67
|
+
# Returns a Receiver which will begin to get back a stream of facts... which is a... Dictionary? Encyclopedia?
|
68
|
+
#
|
61
69
|
def subscribe(app, path)
|
62
70
|
m = Urbit::SubscribeMessage.new(self, app, path)
|
63
71
|
@is_subscribed = self.send_message(m)
|
data/lib/urbit/message.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'faraday'
|
1
2
|
require 'json'
|
2
3
|
|
3
4
|
module Urbit
|
@@ -5,7 +6,7 @@ module Urbit
|
|
5
6
|
attr_accessor :id
|
6
7
|
attr_reader :action, :app, :channel, :json, :mark
|
7
8
|
|
8
|
-
def initialize(channel, action, app, mark, json)
|
9
|
+
def initialize(channel, action, app = nil, mark = nil, json = nil)
|
9
10
|
@action = action
|
10
11
|
@app = app
|
11
12
|
@channel = channel
|
@@ -57,16 +58,4 @@ module Urbit
|
|
57
58
|
response
|
58
59
|
end
|
59
60
|
end
|
60
|
-
|
61
|
-
class CloseMessage < Message
|
62
|
-
def initialize(channel)
|
63
|
-
@action = 'delete'
|
64
|
-
@channel = channel
|
65
|
-
@id = 0
|
66
|
-
end
|
67
|
-
|
68
|
-
def to_h
|
69
|
-
{id: id, action: action}
|
70
|
-
end
|
71
|
-
end
|
72
61
|
end
|
data/lib/urbit/receiver.rb
CHANGED
@@ -4,21 +4,21 @@ require 'urbit/ack_message'
|
|
4
4
|
|
5
5
|
module Urbit
|
6
6
|
class Receiver < SSE::Client
|
7
|
-
attr_accessor :
|
7
|
+
attr_accessor :facts
|
8
8
|
|
9
9
|
def initialize(channel)
|
10
|
-
@
|
10
|
+
@facts = []
|
11
11
|
@headers = {'cookie' => channel.ship.cookie}
|
12
12
|
super(channel.url, {headers: @headers}) do |rec|
|
13
13
|
rec.on_event do |event|
|
14
14
|
typ = event.type
|
15
15
|
dat = JSON.parse(event.data)
|
16
|
-
self.
|
16
|
+
self.facts << {typ => dat}
|
17
17
|
channel.send_message(AckMessage.new(channel, event.id))
|
18
18
|
end
|
19
19
|
|
20
20
|
rec.on_error do |error|
|
21
|
-
self.
|
21
|
+
self.facts += ["I received an error fact: #{error.class}"]
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
data/lib/urbit/ship.rb
CHANGED
@@ -48,31 +48,65 @@ module Urbit
|
|
48
48
|
config.name
|
49
49
|
end
|
50
50
|
|
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
51
|
def open_channels
|
62
52
|
@channels.select {|c| c.open?}
|
63
53
|
end
|
64
54
|
|
55
|
+
def scry(app, path, mark)
|
56
|
+
self.login
|
57
|
+
scry_url = "#{self.config.api_base_url}/~/scry/#{app}#{path}.#{mark}"
|
58
|
+
|
59
|
+
response = Faraday.get(scry_url) do |req|
|
60
|
+
req.headers['Accept'] = 'application/json'
|
61
|
+
req.headers['Cookie'] = self.cookie
|
62
|
+
end
|
63
|
+
|
64
|
+
{status: response.status, code: response.reason_phrase, body: response.body}
|
65
|
+
end
|
66
|
+
|
67
|
+
def spider(mark_in, mark_out, thread, data)
|
68
|
+
self.login
|
69
|
+
url = "#{self.config.api_base_url}/spider/#{mark_in}/#{thread}/#{mark_out}.json"
|
70
|
+
|
71
|
+
response = Faraday.post(url) do |req|
|
72
|
+
req.headers['Accept'] = 'application/json'
|
73
|
+
req.headers['Cookie'] = self.cookie
|
74
|
+
req.body = data
|
75
|
+
end
|
76
|
+
|
77
|
+
{status: response.status, code: response.reason_phrase, body: response.body}
|
78
|
+
end
|
79
|
+
|
80
|
+
#
|
81
|
+
# Subscribe to an app at a path.
|
82
|
+
# Returns a Receiver which will begin to get back a stream of facts... which is a... Dictionary? Encyclopedia?
|
83
|
+
#
|
84
|
+
def subscribe(app, path)
|
85
|
+
self.login
|
86
|
+
(c = Channel.new self, self.make_channel_name).open("Creating a Subscription Channel.")
|
87
|
+
self.channels << c
|
88
|
+
c.subscribe(app, path)
|
89
|
+
end
|
90
|
+
|
65
91
|
def to_s
|
66
92
|
"a Ship(name: '#{self.pat_p}', host: '#{self.config.host}', port: '#{self.config.port}')"
|
67
93
|
end
|
68
94
|
|
69
95
|
private
|
70
96
|
|
97
|
+
def make_channel_name
|
98
|
+
"Channel-#{self.open_channels.count}"
|
99
|
+
end
|
100
|
+
|
71
101
|
def ensure_connections_closed
|
72
102
|
# Make sure all our created channels are closed by the GC
|
73
103
|
ObjectSpace.define_finalizer( self, self.class.finalize(channels) )
|
74
104
|
end
|
75
105
|
|
106
|
+
def login_url
|
107
|
+
"#{config.api_base_url}/~/login"
|
108
|
+
end
|
109
|
+
|
76
110
|
def parse_cookie(resp)
|
77
111
|
cookie = resp.headers['set-cookie']
|
78
112
|
return unless cookie
|
@@ -80,9 +114,5 @@ module Urbit
|
|
80
114
|
@auth_cookie, @path, @max_age = cookie.split(';')
|
81
115
|
self.logged_in = true if @auth_cookie
|
82
116
|
end
|
83
|
-
|
84
|
-
def login_url
|
85
|
-
"#{config.api_base_url}/~/login"
|
86
|
-
end
|
87
117
|
end
|
88
118
|
end
|
@@ -1,19 +1,14 @@
|
|
1
|
-
require 'json'
|
2
|
-
|
3
1
|
module Urbit
|
4
2
|
class SubscribeMessage < Message
|
5
3
|
attr_reader :path
|
6
4
|
|
7
5
|
def initialize(channel, app, path)
|
8
|
-
|
9
|
-
@
|
10
|
-
@channel = channel
|
11
|
-
@id = 0
|
12
|
-
@path = path
|
6
|
+
super(channel, 'subscribe', app)
|
7
|
+
@path = path
|
13
8
|
end
|
14
9
|
|
15
10
|
def to_h
|
16
|
-
{action: action, app: app, id: id, path: path, ship: ship.untilded_name}
|
11
|
+
{action: self.action, app: self.app, id: self.id, path: self.path, ship: self.ship.untilded_name}
|
17
12
|
end
|
18
13
|
end
|
19
14
|
end
|
data/urbit-api.gemspec
CHANGED
@@ -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"
|
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.1.
|
4
|
+
version: 0.1.2
|
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-
|
11
|
+
date: 2021-04-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -90,8 +90,10 @@ files:
|
|
90
90
|
- lib/urbit/api.rb
|
91
91
|
- lib/urbit/api/version.rb
|
92
92
|
- lib/urbit/channel.rb
|
93
|
+
- lib/urbit/close_message.rb
|
93
94
|
- lib/urbit/config.rb
|
94
95
|
- lib/urbit/message.rb
|
96
|
+
- lib/urbit/poke_message.rb
|
95
97
|
- lib/urbit/receiver.rb
|
96
98
|
- lib/urbit/ship.rb
|
97
99
|
- lib/urbit/subscribe_message.rb
|