class Urbit::Ship
Attributes
channels[R]
config[R]
logged_in[RW]
Public Class Methods
finalize(channels)
click to toggle source
# File lib/urbit/ship.rb, line 20 def self.finalize(channels) proc { channels.each { |c| c.close } } end
new(config: Config.new)
click to toggle source
# File lib/urbit/ship.rb, line 12 def initialize(config: Config.new) @auth_cookie = nil @channels = [] @config = config @graphs = [] @logged_in = false end
Public Instance Methods
graph(resource:)
click to toggle source
# File lib/urbit/ship.rb, line 32 def graph(resource:) self.graphs.find {|g| g.resource == resource} end
graph_names()
click to toggle source
A helper method to just print out the descriptive names of all the ship's graphs.
# File lib/urbit/ship.rb, line 59 def graph_names self.graphs.collect {|g| g.resource} end
graphs(flush_cache: false)
click to toggle source
Answers a collection of all the top-level graphs on this ship. This collection is cached and will need to be invalidated to discover new graphs.
# File lib/urbit/ship.rb, line 40 def graphs(flush_cache: false) @graphs = [] if flush_cache if @graphs.empty? if self.logged_in? r = self.scry(app: 'graph-store', path: '/keys') if r[:body] body = JSON.parse r[:body] body["graph-update"]["keys"].each do |k| @graphs << Graph.new(ship: self, graph_name: k["name"], host_ship_name: k["ship"]) end end end end @graphs end
logged_in?()
click to toggle source
# File lib/urbit/ship.rb, line 24 def logged_in? logged_in end
login()
click to toggle source
# File lib/urbit/ship.rb, line 63 def login return self if logged_in? ensure_connections_closed response = Faraday.post(login_url, "password=#{config.code}") parse_cookie(response) self end
name()
click to toggle source
# File lib/urbit/ship.rb, line 72 def name config.name end
open_channels()
click to toggle source
# File lib/urbit/ship.rb, line 101 def open_channels @channels.select {|c| c.open?} end
pat_p()
click to toggle source
# File lib/urbit/ship.rb, line 97 def pat_p config.name end
poke(app:, mark:, message:)
click to toggle source
Poke an app with a message using a mark.
Returns a Channel
which has been created and opened and will begin
to get back a stream of facts via its Receiver.
# File lib/urbit/ship.rb, line 111 def poke(app:, mark:, message:) (self.add_channel).poke(app: app, mark: mark, message: message) end
remove_graph(graph:)
click to toggle source
# File lib/urbit/ship.rb, line 76 def remove_graph(graph:) delete_json = %Q({ "delete": { "resource": { "ship": "#{self.name}", "name": "#{graph.name}" } } }) spider = self.spider(mark_in: 'graph-view-action', mark_out: 'json', thread: 'graph-delete', data: delete_json, args: ["NO_RESPONSE"]) if (retcode = (200 == spider[:status])) self.graphs.delete graph end retcode end
scry(app:, path:, mark: 'json')
click to toggle source
# File lib/urbit/ship.rb, line 115 def scry(app:, path:, mark: 'json') self.login mark = ".#{mark}" unless mark.empty? scry_url = "#{self.config.api_base_url}/~/scry/#{app}#{path}#{mark}" response = Faraday.get(scry_url) do |req| req.headers['Accept'] = 'application/json' req.headers['Cookie'] = self.cookie end {status: response.status, code: response.reason_phrase, body: response.body} end
spider(mark_in:, mark_out:, thread:, data:, args: [])
click to toggle source
# File lib/urbit/ship.rb, line 128 def spider(mark_in:, mark_out:, thread:, data:, args: []) self.login url = "#{self.config.api_base_url}/spider/#{mark_in}/#{thread}/#{mark_out}.json" # TODO: This is a huge hack due to the fact that certain spider operations are known to # not return when they should. Instead I just set the timeout low and catch the # error and act like everything is ok. if args.include?("NO_RESPONSE") conn = Faraday::Connection.new() conn.options.timeout = 1 conn.options.open_timeout = 1 begin response = conn.post(url) do |req| req.headers['Accept'] = 'application/json' req.headers['Cookie'] = self.cookie req.body = data end rescue Faraday::TimeoutError return {status: 200, code: "ok", body: "null"} end end response = Faraday.post(url) do |req| req.headers['Accept'] = 'application/json' req.headers['Cookie'] = self.cookie req.body = data end {status: response.status, code: response.reason_phrase, body: response.body} end
subscribe(app:, path:)
click to toggle source
Subscribe to an app at a path.
Returns a Channel
which has been created and opened and will begin
to get back a stream of facts via its Receiver.
# File lib/urbit/ship.rb, line 166 def subscribe(app:, path:) (self.add_channel).subscribe(app: app, path: path) end
to_h()
click to toggle source
# File lib/urbit/ship.rb, line 170 def to_h {name: "#{self.pat_p}", host: "#{self.config.host}", port: "#{self.config.port}"} end
to_s()
click to toggle source
# File lib/urbit/ship.rb, line 174 def to_s "a Ship(#{self.to_h})" end
untilded_name()
click to toggle source
# File lib/urbit/ship.rb, line 93 def untilded_name name.gsub('~', '') end
Private Instance Methods
add_channel()
click to toggle source
# File lib/urbit/ship.rb, line 180 def add_channel self.login self.channels << (c = Channel.new(ship: self, name: self.make_channel_name)) c end
ensure_connections_closed()
click to toggle source
# File lib/urbit/ship.rb, line 190 def ensure_connections_closed # Make sure all our created channels are closed by the GC ObjectSpace.define_finalizer( self, self.class.finalize(channels) ) end
login_url()
click to toggle source
# File lib/urbit/ship.rb, line 195 def login_url "#{config.api_base_url}/~/login" end
make_channel_name()
click to toggle source
# File lib/urbit/ship.rb, line 186 def make_channel_name "Channel-#{self.open_channels.count}" end