class MemoRack::MemoApp

Public Class Methods

new(app, options={}) click to toggle source
Calls superclass method MemoRack::Core::new
# File lib/memorack/memoapp.rb, line 13
def initialize(app, options={})
        super(options)

        @app = app
        define_statics(@root, *@themes)

        # ファイル監視を行う
        watcher(@root, @directory_watcher) if @directory_watcher
end

Public Instance Methods

call(env) click to toggle source
# File lib/memorack/memoapp.rb, line 23
def call(env)
        content_type = 'text/html'

        path_info = unescape_path_info(env)

        # ロケールの更新
        update_locale(env)

        case path_info
        when '/'
                content = render_with_mustache :index, :markdown
        when /\.css$/
                result = pass(env, @statics)
                return result unless result.first == 404

                begin
                        content_type = 'text/css'
                        content = render_css(path_info)
                rescue Errno::ENOENT => e
                        return error(env, 404)
                end
        else
                locals = {env: env, path_info: path_info}
                content ||= render_content(path_info, locals)
                content ||= render_page(path_info, locals)
        end

        return [200, {'Content-Type' => content_type}, [content.to_s]] if content

        pass(env) { |env, code|
                error(env, code)
        } 
end
define_statics(*args) click to toggle source

静的ファイルの参照先を定義する

# File lib/memorack/memoapp.rb, line 58
def define_statics(*args)
        @statics = [] unless @statics

        @statics |= args.collect { |root| Rack::File.new(root) }
end
error(env, code, body = nil, content_type = 'text/plain; charset=utf-8') click to toggle source

エラー

# File lib/memorack/memoapp.rb, line 91
def error(env, code, body = nil, content_type = 'text/plain; charset=utf-8')
        path_info = unescape_path_info(env)

        if body
                body = [body.to_s, path_info] unless body.kind_of?(Array)
        else
                fullpath = file_search("/#{code}", {views: @themes})
                ext = split_extname(fullpath)[1]
                locals = {env: env, path_info: path_info, page: {name: "Error #{code}"}}

                if ext && Tilt.registered?(ext)
                        template = Pathname.new(fullpath)
                else
                        template = "Error #{code}: #{path_info}"
                        ext = nil
                end

                content = render_with_mustache template, ext, {mustache: 'error.html'}, locals

                if content
                        content_type = 'text/html'
                        body = [content.to_s]
                else
                        body = ["Error #{code}: ", path_info]
                end
        end

        [code, {'Content-Type' => content_type, }, body]
end
pass(env, apps = @statics + [@app]) { |env, 404| ... } click to toggle source

次のアプリにパスする

# File lib/memorack/memoapp.rb, line 77
def pass(env, apps = @statics + [@app])
        apps.each { |app|
                next unless app

                result =  app.call(env)
                return result unless result.first == 404
        }

        return yield(env, 404) if block_given?

        error(env, 404, 'File not found: ')
end
redirect(url, code = 301) click to toggle source

リダイレクト

# File lib/memorack/memoapp.rb, line 71
def redirect(url, code = 301)
        # 301 = 恒久的, 302 = 一時的, 303, 410
        [code, {'Content-Type' => 'text/html', 'Location' => url}, ['Redirect: ', url]]
end
unescape_path_info(env) click to toggle source

PATH_INFO を unescape して取出す

# File lib/memorack/memoapp.rb, line 65
def unescape_path_info(env)
        path_info = URI.unescape(env['PATH_INFO'])
        path_info.force_encoding('UTF-8')
end
watcher(path = '.', interval = 1.0) click to toggle source

ファイル監視を行う

# File lib/memorack/memoapp.rb, line 122
def watcher(path = '.', interval = 1.0)
        require 'directory_watcher'

        interval = 1.0 if interval == true # 旧バージョンとの互換性のため

        dw = DirectoryWatcher.new path, :pre_load => true
        dw.interval = interval
        dw.stable = 2
        dw.glob = '**/*'
        dw.add_observer { |*args|
                t = Time.now.strftime("%Y-%m-%d %H:%M:%S")
                puts "[#{t}] regeneration: #{args.size} files changed"

                @menu = nil
        }

        dw.start
end