# frozen_string_literal: true require "yaml" require "tree" require_relative "skeksis/version" require_relative "skeksis/parser" require_relative "skeksis/htmlize" module Skeksis #class Error < StandardError; end Header = <<~HTML Gembridge

Directory Listing

HTML Footer = <<~HTML HTML class GemBridge def initialize config = YAML.load(File.read("config.yml")) @gemini_uri = config['skeksis_config']['gemini_uri'] @serve_dir = config['skeksis_config']['serve_dir'] @allowlist = Tree::TreeNode.new("ROOT", false) build_allowlist(@allowlist, @serve_dir) puts @allowlist.to_h end def build_allowlist(tree, path) Dir.each_child(path) do |child| full_path = Pathname.new(path).join(child) if child == ".serve_ok" tree.content = true end serve_ok = false if Dir.exist?(full_path) Dir.each_child(full_path) do |subchild| if subchild == ".serve_ok" serve_ok = true end end child_node = Tree::TreeNode.new(child, serve_ok) tree << child_node end end end def query(path, env) query_path = Pathname.new(path).each_filename.to_a @allowlist.children do |child| if child.name == query_path[0] and child.content == false return nil end end # Chomps the first / and builds path full_path = Pathname.new(@serve_dir) + path[1..-1] puts full_path.to_s if Dir.exist?(full_path) index_file = full_path + "index.gmi" if File.exist?(index_file) data = File.open(index_file, 'r').readlines [htmlize(data, env)] else create_dir_listing(full_path, env) end elsif File.exist?(full_path) file = File.open(full_path, 'r') data = file.readlines [htmlize(data, env)] else # path is invalid return nil end end def htmlize(data, env) Skeksis::Parser.parse(data, strip_blanks=true).htmlize(env['REQUEST_URI'], @gemini_uri) end private def load_style "" end def create_dir_listing(path, env) http = URI.parse(env['REQUEST_URI']) unless Dir.each_child(path).include?('.directory-listing-ok') return nil end listing = Dir.each_child(path).map do |i| if i == ".directory-listing-ok" or i == ".serve_ok" next end child_path = Pathname.new(path).join(i) puts child_path if Dir.exist?(child_path) and not Dir.each_child(child_path).include?('.serve_ok') next end uri_path = Pathname.new(env['PATH_INFO']).join(i) uri = URI::HTTP.build(host: http.host, port: http.port, path: uri_path.to_s) "#{i}
" end.join("\n") [Header + listing + Footer] end end end