Class: Methan::Server

Inherits:
Object
  • Object
show all
Defined in:
lib/methan/server.rb

Constant Summary collapse

DEFAULT_HOST =
"0.0.0.0"
DEFAULT_PORT =
5550
ROUTES =
{
  "GET:/style.css" => :style_css,
  "GET:/" => :index,
}

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app = nil) ⇒ Server

Returns a new instance of Server.



41
42
43
# File 'lib/methan/server.rb', line 41

def initialize(app=nil)
  @app = app
end

Class Method Details

.rackup(args = {}) ⇒ Object



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/methan/server.rb', line 18

def rackup(args={})
  args[:'Host'] = args.delete('host') if args['host']
  args[:'Port'] = args.delete('port') if args['port']
  options = {
    environment: ENV['RACK_ENV'] || "development",
    pid:         nil,
    'Port':        DEFAULT_PORT,
    'Host':        DEFAULT_HOST,
    'AccessLog':   [],
    config:      File.join(File.dirname(__FILE__), 'server/config.ru'),
  }
  options.update(args.deep_symbolize_keys)
  ENV["RACK_ENV"] = options[:environment]
  Rack::Server.start(options)
end

Instance Method Details

#call(env) ⇒ Object

Rack interface method.



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/methan/server.rb', line 46

def call(env)
  req = ::Rack::Request.new(env)
  route_method = nil
  ROUTES.each do |route, method|
    http_method, path = route.split(":", 2)
    if req.path == path and http_method.to_s.upcase == req.request_method.to_s.upcase
      route_method = "#{http_method.to_s.downcase}_#{method.to_s}".to_sym
      break
    end
  end

  response = nil
  if not route_method.nil? and self.respond_to?(route_method, true)
    response = self.send(route_method, req)
  else
    ## show
    filename = req.path.dup
    filename = filename.gsub(/^\//, "")
    filename = "#{filename}.md" unless filename =~ /^\.md$/
    showpath = File.join(Dir.pwd, filename)
    puts showpath
    if File.exists?(showpath)
      response = get_show(req)
    end
  end

  # 404 not found
  response = gen_404_response() if response.nil?
  # response finished
  response.finish
end

#gen_404_responseRack::Response

Generate 404 Response

Returns:

  • (Rack::Response)


176
177
178
179
# File 'lib/methan/server.rb', line 176

def gen_404_response()
  response = gen_response("<h1>404 Not Found</h1>", 404)
  return response
end

#gen_response(body, status = 200, headers = {}) ⇒ Rack::Response

Generate Rack::Response

Parameters:

  • body (String)

    Response body.

  • status (Fixnum) (defaults to: 200)

    Status code.

  • headers (Hash) (defaults to: {})

    Headers.

Returns:

  • (Rack::Response)


162
163
164
165
166
167
168
169
170
171
172
# File 'lib/methan/server.rb', line 162

def gen_response(body, status=200, headers={})
  response = Rack::Response.new do |r|
    r.status = status
    r['Content-Type'] = "text/html" unless headers.key?('Content-Type')
    headers.each do |key, val|
      r[key] = val
    end
    r.write body
  end
  return response
end

#get_index(req) ⇒ Object



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/methan/server.rb', line 84

def get_index(req)
  current_dir = Dir.pwd
  path = File.join(current_dir, "**/*.md")
  # bindings
  @files = Dir.glob(path).map do |file|
    file_id = file.gsub(current_dir, "")
    file_id = file_id.gsub(/\.md$/, "").gsub(/^\//, "")
    dat = {
      id: file_id,
      name: File.basename(file),
      path: file,
    }
    File.open(file) do |f|
      title = f.gets
      title = title.gsub(/^\#\s+/, "").gsub(/\s+\#$/, "").strip
      dat[:title] = title
    end
    dat
  end
  @files.sort!{|a, b| a[:id] <=> b[:id] }
  @files.reverse!
  src = File.read(make_template_path("index.html.erb"))
  erb = ERB.new(src)
  body = erb.result(binding)
  return gen_response(body)
end

#get_show(req) ⇒ Object



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/methan/server.rb', line 111

def get_show(req)
  path = req.path.dup
  file_id = path.gsub(/^\//, "")
  if file_id =~ /\.md$/
    filename = file_id
    file_id  = file_id.gsub(/\.md$/, "")
  else
    filename = "#{file_id}.md"
  end
  filepath = File.join(Dir.pwd, filename)

  # bindings
  @file_id  = file_id
  @filename = filename
  @src = File.read(filepath)
  @html = markdown_to_html(@src)

  # to html
  src = File.read(make_template_path("show.html.erb"))
  erb = ERB.new(src)
  body = erb.result(binding)
  return gen_response(body)
end

#get_style_css(req) ⇒ Object



78
79
80
81
82
# File 'lib/methan/server.rb', line 78

def get_style_css(req)
  filepath = File.join(File.dirname(__FILE__), "server/static/style.css")
  src = File.read(filepath)
  gen_response(src, 200, {'Content-Type' => 'text/css'})
end

#make_template_path(filename) ⇒ String

Generate ERB template file path.

Parameters:

  • filename (String)

    template file name.

Returns:

  • (String)


184
185
186
# File 'lib/methan/server.rb', line 184

def make_template_path(filename)
  return File.join(templates_dir, filename)
end

#markdown_to_html(src) ⇒ Object

Convert Markdown source to HTML.

Parameters:

  • src (String)

    Markdown source.



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/methan/server.rb', line 137

def markdown_to_html(src)
  render_options = {
    prettify: true,
  }
  renderer = MdRenderer.new(render_options)
  extensions = {
    no_intra_emphasis: true,
    autolink: true,
    tables: true,
    fenced_code_blocks: true,
    strikethrough: true,
    underline: true,
    quote: true,
    footnotes: true,
  }
  md = ::Redcarpet::Markdown.new(renderer, extensions)
  html = md.render(src)
  return html
end

#templates_dirString

Return templates directory path.

Returns:

  • (String)


190
191
192
# File 'lib/methan/server.rb', line 190

def templates_dir
  return File.join(File.dirname(__FILE__), 'server/templates')
end