class Octodown::Renderer::Server

Attributes

file[R]
logger[R]
options[R]
path[R]
port[R]

Public Class Methods

new(_content, options = {}) click to toggle source
# File lib/octodown/renderer/server.rb, line 16
def initialize(_content, options = {})
  @logger = options[:logger]
  @file = options[:file]
  @options = options
  @path = File.dirname(File.expand_path(file.path))
  @port = options[:port]
  @websockets = []
  @mutex = Mutex.new
end

Public Instance Methods

app() click to toggle source

Cascade through this app and Rack::File app. If Server returns 404, Rack::File will try to serve a static file.

# File lib/octodown/renderer/server.rb, line 67
def app
  @app ||= Rack::Cascade.new([self, Rack::File.new(path)])
end
boot_server() click to toggle source
# File lib/octodown/renderer/server.rb, line 36
def boot_server
  logger.info "#{file.path} is getting octodown'd"
  logger.info "Server running on http://localhost:#{port}"
  Rack::Handler::Puma.run app,
                          Host: 'localhost',
                          Port: port,
                          Silent: true,
                          Threads: '2:8'
end
call(env) click to toggle source
# File lib/octodown/renderer/server.rb, line 61
def call(env)
  ::Faye::WebSocket.websocket?(env) ? render_ws(env) : render_http(env)
end
maybe_launch_browser() click to toggle source
# File lib/octodown/renderer/server.rb, line 46
def maybe_launch_browser
  return if options[:no_open]

  sleep 2.5

  @mutex.synchronize do
    if @websockets.empty?
      logger.info 'Loading preview in a new browser tab'
      Launchy.open "http://localhost:#{port}"
    else
      logger.info 'Re-using existing browser tab'
    end
  end
end
present() click to toggle source
# File lib/octodown/renderer/server.rb, line 26
def present
  register_listener

  Thread.new do
    maybe_launch_browser
  end

  boot_server
end

Private Instance Methods

body() click to toggle source

Render HTML body from Markdown

# File lib/octodown/renderer/server.rb, line 105
def body
  HTML.render render_md(file), options
end
log_clients(msg) click to toggle source
# File lib/octodown/renderer/server.rb, line 125
def log_clients(msg)
  logger.debug "#{msg}. Number of websocket clients: #{@websockets.size}"
end
register_listener() click to toggle source
# File lib/octodown/renderer/server.rb, line 109
def register_listener
  Octodown::Support::Services::Riposter.call file do
    logger.info "Changes to #{file.path} detected, updating"
    md = render_md(file)
    @websockets.each do |socket|
      Thread.new do
        socket.send md
      end
    end
  end
end
render_http(env) click to toggle source
# File lib/octodown/renderer/server.rb, line 92
def render_http(env)
  Rack::Response.new.tap do |res|
    res.headers.merge 'Content-Type' => 'text/html'
    res.status = valid_req?(env) ? 200 : 404
    res.write(body) if valid_req? env
  end.finish
end
render_md(f) click to toggle source
# File lib/octodown/renderer/server.rb, line 121
def render_md(f)
  Renderer::GithubMarkdown.render f, options
end
render_ws(env) click to toggle source
# File lib/octodown/renderer/server.rb, line 73
def render_ws(env)
  md = render_md(file)

  socket = ::Faye::WebSocket.new(env)

  socket.on(:open) do
    @websockets << socket
    log_clients('Client joined')
    socket.send md
  end

  socket.on(:close) do
    @websockets = @websockets.reject { |s| s == socket }
    log_clients('Client left')
  end

  socket.rack_response
end
valid_req?(env) click to toggle source
# File lib/octodown/renderer/server.rb, line 100
def valid_req?(env)
  env['PATH_INFO'] == '/' && env['REQUEST_METHOD'] == 'GET'
end