root/lang/ruby/ekfloras/ekfloras.rb @ 1023

Revision 1023, 3.8 kB (checked in by cho45, 7 years ago)

lang/ruby/ekfloras/plugins/paging.rb,
lang/ruby/ekfloras/ekfloras.rb:

entries の上書きがちゃんとうごいていなかった。
paging で数がすくないときにバグがあった

  • Property svn:executable set to *
Line 
1#!/usr/bin/env ruby
2#
3
4$LOAD_PATH.unshift "lib"
5
6require "cgi"
7require "pathname"
8require "ostruct"
9
10begin
11        begin
12                require "rubygems"
13        rescue LoadError
14        end
15        require "erubis"
16rescue LoadError
17        require "erb"
18end
19
20require "module/pluggable"
21
22class Ekfloras
23        DEFAULT_OPTS = {
24                :title    => "Ekfloras test",
25                :flavour  => ".html",
26                :data_dir => "data",
27                :data_ext => ".txt",
28        }.freeze
29
30        class Entry < OpenStruct; end
31
32        class Plugin
33                def init(ekfloras)
34                        @ekfloras = ekfloras
35                        # priority を返す
36                        # 数字が小さいほど先に実行される
37                        100
38                end
39
40                # 本体の entries のうわがき
41                # 上書きしないなら定義してはいけない
42                # 定義されているプラグインのうち、
43                # 最も priority が高いもののみ使用される。
44                def entries
45                end
46                undef entries
47
48                # ソートしたりフィルタしたりする
49                def filter(entries)
50                        entries
51                end
52
53                # 出力加工用
54                def last(out)
55                        out
56                end
57
58                # あと処理用
59                def finish
60                end
61        end
62
63        pluggable :plugins, :base_class => Plugin
64
65        attr_accessor :path_info, :flavour, :entries
66        attr_accessor :home, :server_root, :opts, :cgi
67        attr_accessor :stash
68
69        def initialize(cgi, opts=DEFAULT_OPTS.dup)
70                @cgi             = cgi
71                @opts            = opts
72                @opts[:data_dir] = Pathname.new(@opts[:data_dir])
73                @data            = Pathname.new(opts[:data_dir])
74                @home            = @cgi.script_name
75                @server_root     = @cgi.server_name
76                @stash           = {}
77        end
78
79        def run
80                @path_info = Pathname.new(@cgi.path_info.to_s)
81                @flavour   = @path_info.extname
82                @flavour   = @opts[:flavour] if @flavour.empty?
83                @path_info = @path_info.parent if @path_info.basename(".*") == "index"
84                @path_info = @path_info.dirname + @path_info.basename(".*")
85
86                # initialize plugins and get priorities
87                @priorities = plugins.init(self).sort_by {|k,v| v}
88
89                entries_plugin = @priorities.find {|n,q| plugins[n].respond_to? :entries }
90                @entries   = entries_plugin ? plugins[entries_plugin[0]].entries : list_entries()
91
92                @entries = @entries.sort_by {|i|
93                        i.time
94                }.reverse
95
96
97                case @path_info.to_s
98                when %r|^/(\d{4})(?:/(\d\d)(?:/(\d\d))?)?|
99                        _, year, month, day = *Regexp.last_match
100                        @entries.reject! {|i|
101                                ![["%Y", year], ["%m", month], ["%d", day]].all? {|f,k|
102                                        !k || i.time.strftime(f) == k
103                                }
104                        }
105                else
106                        @entries.reject! {|i|
107                                i.name !~ /#{@path_info}/
108                        }
109                end
110
111                # call plugins' filters
112                @entries = call_plugins(:filter, @entries)
113
114                show({
115                        :title       => @opts[:title],
116                        :path_info   => @path_info,
117                        :flavour     => @flavour,
118                        :entries     => @entries,
119                        :home        => @home,
120                        :server_root => @server_root,
121                }.merge(@stash))
122
123                call_plugins :finish
124        rescue SystemExit
125        rescue Exception => e
126                @flavour = ".html"
127                $stderr.puts e
128                $stderr.puts e.backtrace.join("\n\t")
129                show({
130                        :error => e,
131                        :status => "500 Exception raised",
132                })
133        end
134
135        def list_entries
136                Pathname.glob(@data + "**/*#{@opts[:data_ext]}").map {|f|
137                        content = f.readlines
138                        name = f.relative_path_from(@opts[:data_dir])
139                        Entry.new({
140                                :title => content.first,
141                                :body  => content[1..-1].join,
142                                :time  => f.mtime,
143                                :path  => f,
144                                :name  => "/#{name.dirname + name.basename(".*")}"
145                        })
146                }
147        end
148
149        def call_plugins(name, arg=nil)
150                @priorities.each do |n,q|
151                        next unless plugins[n].respond_to? name
152                        if arg
153                                arg = plugins[n].send(name, arg)
154                        else
155                                plugins[n].send(name)
156                        end
157                end
158                arg
159        end
160
161
162        def show(stash)
163                stash = OpenStruct.new(stash)
164
165                erb = (defined? Erubis) ? Erubis::Eruby : ERB
166                ret = erb.new(File.read("template#{@flavour}")).result(binding)
167
168                ret = call_plugins(:last, ret) unless stash.error
169
170                puts "Status: #{stash.status}" if stash.status
171                puts ret
172                exit
173        end
174end
175
176if $stdout.tty?
177        Ekfloras.new(OpenStruct.new({
178                #:path_info => "/test/index.html"
179                #:path_info => "/2007/"
180                #:path_info => "/test01"
181                :path_info => "/intro.html"
182        })).run
183else
184        Ekfloras.new(CGI.new).run
185end
Note: See TracBrowser for help on using the browser.