summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--components/storage.rb7
-rw-r--r--components/stream.rb37
-rw-r--r--controllers/cartridges.rb52
-rw-r--r--controllers/instance.rb13
-rw-r--r--ports/dsl/nano-bots.rb8
5 files changed, 109 insertions, 8 deletions
diff --git a/components/storage.rb b/components/storage.rb
index bdf0efe..d34dac7 100644
--- a/components/storage.rb
+++ b/components/storage.rb
@@ -29,6 +29,13 @@ module NanoBot
path
end
+ def self.cartridges_path
+ [
+ ENV.fetch('NANO_BOTS_CARTRIDGES_DIRECTORY', nil),
+ "#{user_home!.sub(%r{/$}, '')}/.local/share/nano-bots/cartridges"
+ ].uniq.filter { |path| File.directory?(path) }.compact.first
+ end
+
def self.cartridge_path(path)
partial = File.join(File.dirname(path), File.basename(path, File.extname(path)))
diff --git a/components/stream.rb b/components/stream.rb
new file mode 100644
index 0000000..45c4a2b
--- /dev/null
+++ b/components/stream.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+require 'stringio'
+
+module NanoBot
+ module Components
+ class Stream < StringIO
+ def write(*args)
+ if @callback
+ @accumulated += args.first
+ @callback.call(@accumulated, args.first, false)
+ end
+ super
+ end
+
+ def callback=(block)
+ @accumulated = ''
+ @callback = block
+ end
+
+ def finish
+ flush
+ result = string.clone
+ truncate(0)
+ rewind
+
+ if @callback
+ @callback.call(@accumulated, nil, true)
+ @callback = nil
+ @accumulated = nil
+ end
+
+ result
+ end
+ end
+ end
+end
diff --git a/controllers/cartridges.rb b/controllers/cartridges.rb
new file mode 100644
index 0000000..3e3b192
--- /dev/null
+++ b/controllers/cartridges.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+require_relative '../components/storage'
+require_relative '../logic/helpers/hash'
+require_relative '../logic/cartridge/default'
+
+module NanoBot
+ module Controllers
+ class Cartridges
+ def self.all
+ files = {}
+
+ path = Components::Storage.cartridges_path
+
+ Dir.glob("#{path}/**/*.{yml,yaml}").each do |file|
+ files[Pathname.new(file).realpath] = {
+ base: path,
+ path: Pathname.new(file).realpath
+ }
+ end
+
+ cartridges = []
+
+ files.values.uniq.map do |file|
+ cartridge = Logic::Helpers::Hash.symbolize_keys(
+ YAML.safe_load(File.read(file[:path]), permitted_classes: [Symbol])
+ ).merge({
+ system: {
+ id: file[:path].to_s.sub(/^#{Regexp.escape(file[:base])}/, '').sub(%r{^/}, '').sub(/\.[^.]+\z/,
+ ''),
+ path: file[:path],
+ base: file[:base]
+ }
+ })
+
+ next if cartridge[:meta][:name].nil?
+
+ cartridges << cartridge
+ # rescue StandardError => _e
+ end
+
+ cartridges.sort_by { |cartridge| cartridge[:meta][:name] }
+
+ cartridges.prepend(
+ { system: { id: '-' }, meta: { name: 'Default', symbol: '🤖' } }
+ )
+
+ cartridges
+ end
+ end
+ end
+end
diff --git a/controllers/instance.rb b/controllers/instance.rb
index 80ac9be..e0729e6 100644
--- a/controllers/instance.rb
+++ b/controllers/instance.rb
@@ -5,6 +5,7 @@ require 'yaml'
require_relative '../logic/helpers/hash'
require_relative '../components/provider'
require_relative '../components/storage'
+require_relative '../components/stream'
require_relative './interfaces/repl'
require_relative './interfaces/eval'
require_relative './session'
@@ -30,16 +31,14 @@ module NanoBot
@session.state
end
- def eval(input)
+ def eval(input, &block)
+ @stream.callback = block if block && @stream.is_a?(Components::Stream)
+
Interfaces::Eval.evaluate(input, @cartridge, @session)
- return unless @stream.is_a?(StringIO)
+ return unless @stream.is_a?(Components::Stream)
- @stream.flush
- result = @stream.string.clone
- @stream.truncate(0)
- @stream.rewind
- result
+ @stream.finish
end
def repl
diff --git a/ports/dsl/nano-bots.rb b/ports/dsl/nano-bots.rb
index 40bed1d..89da466 100644
--- a/ports/dsl/nano-bots.rb
+++ b/ports/dsl/nano-bots.rb
@@ -3,12 +3,18 @@
require 'dotenv/load'
require_relative '../../static/gem'
+require_relative '../../controllers/cartridges'
require_relative '../../controllers/instance'
require_relative '../../controllers/interfaces/cli'
+require_relative '../../components/stream'
module NanoBot
def self.new(cartridge: '-', state: '-')
- Controllers::Instance.new(cartridge_path: cartridge, state:, stream: StringIO.new)
+ Controllers::Instance.new(cartridge_path: cartridge, state:, stream: Components::Stream.new)
+ end
+
+ def self.cartridges
+ Controllers::Cartridges.all
end
def self.cli