root/lang/ruby/lily/lily.cgi

Revision 3487, 12.2 kB (checked in by kan, 12 months ago)

imported lily (ruby blosxom cron)

Line 
1#!/usr/bin/ruby -Ke
2require 'net/http'
3require 'time.rb'
4require 'kconv'
5require 'cgi'
6require 'sdbm'
7
8begin
9  require 'uconv'
10rescue LoadError
11end
12
13class String
14  def to_euc
15    NKF::nkf( '-m0 -e', self )
16  end
17
18  def to_sjis
19    NKF::nkf( '-m0 -s', self )
20  end
21
22  def to_jis
23    NKF::nkf( '-m0 -j', self )
24  end
25end
26
27class Lily
28
29  def initialize(cgi,env)
30    @version = "0.1.5"
31    @ruby_version = ::RUBY_VERSION
32
33    @cgi                 = cgi
34    @blog_title          = env['blog_title']
35    @blog_description    = env['blog_description']
36    @blog_language       = env['blog_language']
37    @datadir             = env['datadir']
38    @flavourdir          = env['flavourdir']
39    @depth               = env['depth'].to_i
40    @num_entries         = env['num_entries'].to_i
41    @default_flavour     = env['default_flavour']
42    @show_future_entries = env['show_future_entries'].to_i
43    @plugindir           = env['plugindir']
44    @encode              = env['encode']
45    @file_extension      = env['file_extension'].split(/ /)
46    @author              = env['author']
47    @mail                = env['mail']
48    if env['url'] == ""
49      @url = "http://#{@cgi.server_name}#{@cgi.script_name}"
50    else
51      @url = env['url']
52    end
53    @env = env
54
55    Dir.glob("#{@plugindir}/*.rb") do |f|
56      File::open(f,"r"){|src|
57        begin
58          self.instance_eval(src.read)
59        rescue Exception
60        end
61      }
62    end
63
64    @ptimes = {}
65    begin
66      File::open("#{@datadir}/.entrydate","r"){|f|
67        f.readlines.each{|pts|
68          file, time = pts.split(/@@/)
69          @ptimes[file] = Time.rfc2822(time)
70        }
71      }
72    rescue
73    end
74   
75    File::open(__FILE__) do |data|
76      data.gets("__END__\n")
77      eval data.read
78    end
79  end
80
81  def enc_char
82    if @encode == 'sjis'
83      'Shift_JIS'
84    elsif @encode == 'euc'
85      'EUC-JP'
86    elsif @encode == 'jis'
87      'iso-2022-jp'
88    elsif @encode == 'utf-8'
89      'utf-8'
90    else
91    end
92  end
93
94  def get_conf(name)
95    begin
96      if name =~ /(.+)::(.+)/
97        eval("#{$1}_#{$2}")
98      else
99        eval("@#{name}")
100      end
101    rescue NameError
102      error_out()
103    end
104  end
105 
106  def get_post_time(file)
107    @ptimes[file] ||=
108    begin
109      mtime = File::stat(file).mtime
110      @entrydate ||= File::open("#{@datadir}/.entrydate","a")
111      @entrydate.puts "#{file}@@#{mtime.rfc2822}"
112      mtime
113    end
114  end
115 
116  def convert(str)
117    if str.nil?
118      return nil
119    end
120    unless @encode.nil?
121      if @encode == "sjis"
122        begin
123          Uconv.u8tosjis(str)
124        rescue Exception
125          str.tosjis
126        end
127      elsif @encode == "jis"
128        begin
129          Uconv.u8tosjis(str).tojis
130        rescue Exception
131          str.tojis
132        end
133      elsif @encode == "euc"
134        begin
135          Uconv.u8toeuc(str)
136        rescue Exception
137          str.toeuc
138        end
139      elsif @encode == "utf-8"
140        begin
141          Uconv.u8toeuc(str)
142          str
143        rescue Exception
144          begin
145            Uconv.euctou8(str.toeuc)
146          rescue Exception
147            str
148          end
149        end
150      else
151        str
152      end
153    else
154      str
155    end
156  end
157 
158  def disp
159    @storys   = []
160    @echo_off = false
161    @flavour  = @default_flavour
162
163    pcnt = 0
164    @path_info = ""
165    @story_tmpl = nil
166    @date_tmpl = nil
167
168    unless @cgi.path_info.nil?
169      pi_ar = @cgi.path_info.split(/\//)
170      pi_ar.each do |pi|
171        if (pi == "" or pi =~ /^[a-zA-Z].*$/) and pi !~ /(.*)\.(.*)$/
172          @path_info << "/" + pi
173          pcnt += 1
174        else
175          break
176        end
177      end
178      if pi_ar[pcnt] =~ /(.+)\.(.+)$/
179        @flavour = $2
180        if $1 != "index"
181          @file_extension.each do |fext|
182            if File.file?("#{@datadir}/#{@path_info}/#{$1}.#{fext}")
183              @path_info << "/#{$1}.#{fext}"
184              break
185            end
186          end
187        end
188        pcnt += 1
189      end
190      @path_info_yr = pi_ar[pcnt]
191      @path_info_mo = pi_ar[pcnt+1]
192      if @path_info_mo.nil?
193        @path_info_mo_num = nil
194      else
195        if @path_info_mo =~ /\d{2}/
196          @path_info_mo_num = @path_info_mo
197        else
198          @path_info_mo_num = ["Jan","Feb","March","Apr","May","Jun",
199                               "Jul","Aug","Sep","Oct","Nov","Dec"]\
200                               .index(@path_info_mo)
201          if !(@path_info_mo_num.nil?) and @path_info_mo_num < 10
202            @path_info_mo_num = "0" + @path_info_mo_num.to_s
203          end
204        end
205      end
206      @path_info_da = pi_ar[pcnt+2]
207    end
208    @path_info.sub!(/^\/+/,"/")
209    @path_info.sub!(/^\/$/,"")
210   
211    if File.file?("#{@datadir}/#{@path_info}")
212      @storys.push("#{@datadir}/#{@path_info}")
213    else
214      files = []
215      if @depth == 0
216        @file_extension.each do |fext|
217          files += Dir.glob("#{@datadir}/#{@path_info}/*.#{fext}")
218        end
219      else
220        @file_extension.each do |fext|
221          files += Dir.glob("#{@datadir}/#{@path_info}/**/*.#{fext}")
222        end
223      end
224
225      files.each{|f|
226        day = get_post_time(f)
227        if @path_info_yr.nil? or @path_info_yr == ""
228          @storys.push(f)
229        else
230          if @path_info_yr == day.year.to_s
231            if @path_info_mo_num.nil? or @path_info_mo_num == ""
232              @storys.push(f)
233            else
234              if @path_info_mo_num == day.strftime("%m")
235                if @path_info_da.nil? or @path_info_da == ""
236                  @storys.push(f)
237                else
238                  if @path_info_da == day.strftime("%d")
239                    @storys.push(f)
240                  end
241                end
242              end
243            end
244          end
245        end
246      }
247    end
248   
249    @storys = @storys.sort {|f1,f2|
250      get_post_time(f2) <=> get_post_time(f1)
251    }
252
253    if (@path_info.nil? or
254        @path_info == '' or
255        @path_info == '/') and
256       ((@path_info_yr.nil? or
257         @path_info_yr == '') and
258        (@path_info_mo.nil? or
259         @path_info_mo == '') and
260        (@path_info_da.nil? or
261         @path_info_da == ''))
262      @storys = @storys[0,@num_entries]
263    end
264   
265    Dir.glob("#{@plugindir}/*.rb"){|f|
266      begin
267        eval("#{File.basename(f,".*")}")
268      rescue NameError
269      end
270    }
271
272    unless @echo_off
273      begin
274        File.open("#{@flavourdir}/content_type.#{@flavour}","r"){|f|
275          print "Content-type: #{f.gets.chomp};charset=#{enc_char}\n\n";
276        }
277      rescue Exception
278        print "Content-type: text/html;charset=#{enc_char}\n\n";
279      end
280
281      disp_head
282
283      @prev_story_date = nil
284      @storys.each do |f|
285        disp_date(f)
286        disp_story(f)
287      end
288   
289      disp_foot
290    end
291  end
292 
293  def disp_head
294    begin
295      File::open("#{@flavourdir}/head.#{@flavour}","r"){|f|
296        str = f.read.gsub(/\$([a-z][a-z0-9_:]*)/){
297                  "\#{get_conf(\"#{$1}\")}" }
298        eval("print <<EOS\n#{convert(str)}\nEOS")
299      }
300    rescue Exception
301      @default_head.gsub!(/\$([a-z][a-z0-9_:]*)/){
302                "\#{get_conf(\"#{$1}\")}" }
303      eval("print <<EOS\n#{convert(@default_head)}\nEOS")
304    end
305  end
306 
307  def disp_date(file)
308    day = get_post_time(file)
309    @ti = day.to_s
310    @yr = day.year
311    @mo = day.strftime("%b")
312    @mo_num = day.strftime("%m")
313    @da = day.strftime("%d")
314    @dw = day.strftime("%a")
315    @hr = day.strftime("%H")
316    @min = day.strftime("%M")
317    @sec = day.strftime("%S")
318   
319    if !@prev_entry_date.nil?
320      if @prev_entry_date.year == day.year and
321         @prev_entry_date.mon == day.mon and
322         @prev_entry_date.day == day.day
323        return
324      end
325    end
326
327    @prev_entry_date = day
328    if @date_tmpl.nil?
329      begin
330        File::open("#{@flavourdir}/date.#{@flavour}","r"){|f|
331          @date_tmpl = str = f.read.gsub(/\$([a-z][a-z0-9_:]*)/){
332                    "\#{get_conf(\"#{$1}\")}" }
333        }
334      rescue Exception
335        @date_tmpl = @default_date.gsub!(/\$([a-z][a-z0-9_:]*)/){
336                  "\#{get_conf(\"#{$1}\")}" }
337      end
338    end
339   
340    eval("print <<EOS\n#{convert(@date_tmpl)}\nEOS")
341  end
342 
343  def disp_story(file)
344    File::open(file,"r"){|f|
345      @title = convert(f.gets.chomp)
346      @body = convert(f.read)
347      reg = Regexp.new("#{@datadir}/(.*)/([^.]*)\.(.*)")
348      file.sub(reg){ @path = $1; @fn = $2; @fext = $3}
349     
350    }
351
352    Dir.glob("#{@plugindir}/*.rb"){|f|
353      begin
354        eval("#{File.basename(f,".*")}_filter")
355      rescue NameError
356      end
357    }
358    if @story_tmpl.nil?
359      begin
360        File::open("#{@flavourdir}/story.#{@flavour}","r"){|f|
361          str = f.read.gsub(/\$([a-z][a-z0-9_:]*)/){
362                    "\#{get_conf(\"#{$1}\")}" }
363          @story_tmpl = str.gsub!(/\n/,'')
364        }
365      rescue Exception
366        @story_tmpl = @default_story.gsub!(/\$([a-z][a-z0-9_:]*)/){
367                         "\#{get_conf(\"#{$1}\")}" }
368      end
369    end
370   
371    eval("print <<EOS\n#{convert(@story_tmpl)}\nEOS")
372  end
373 
374  def disp_foot
375    begin
376      File::open("#{@flavourdir}/foot.#{@flavour}","r"){|f|
377        str = f.read.gsub(/\$([a-z][a-z0-9_:]*)/){
378                  "\#{get_conf(\"#{$1}\")}" }
379        eval("print <<EOS\n#{convert(str)}\nEOS")
380      }
381    rescue Exception
382      @default_foot.gsub!(/\$([a-z][a-z0-9_:]*)/){
383                "\#{get_conf(\"#{$1}\")}" }
384      eval("print <<EOS\n#{convert(@default_foot)}\nEOS")
385    end
386  end
387
388end
389
390def error_out
391  print "Content-Type:text/html\n\n"
392  print $!,"<BR>";
393  $@.each {|x| print CGI.escapeHTML(x), "<BR>\n"}
394end
395
396def load_env
397  env = Hash.new
398
399  File::open("./lily.cfg","r"){|f|
400    f.read.each_line do |line|
401      item = line.chomp.split(/\s+/)
402      key = item.shift
403      env[key] = item.join(' ')
404    end
405  }
406 
407  return env
408end
409
410if __FILE__ == $0
411  begin
412    env  = load_env
413    blog = Lily.new(CGI.new, env)
414    blog.disp
415  rescue Exception
416    error_out()
417  end
418end
419
420__END__
421@default_head = <<EOS
422<?xml version="1.0" encoding="$enc::char"?>
423<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
424   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
425<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
426  <head>
427    <title>$blog_title</title>
428    <link rel="start" href="$url" />
429    <style type="text/css">
430                body {
431                    font-family: Verdana; /* experimental */
432                    margin-right: 10%;
433                    margin-left: 10%;
434                    background-color: white;
435                    color: black;
436                }
437                h1 {
438                    font-family: comic sans ms;
439                    font-size: 200%;
440                    margin-top: 1em;
441                    margin-bottom: 0;
442                }
443                h2 {
444                    margin-top: 1em;
445                    color: #333333;
446                    /* border-bottom: #99ff55 2px double; */
447                    padding: .5ex .5ex .5ex .5ex;
448                }
449                h3 {
450                    margin-top: 2em;
451                    border-bottom: black 1px solid;
452                    padding: .5ex .5ex .5ex .5ex;
453                }
454                li, p {
455                    line-height: 140%;
456                }
457                p {
458                    margin-left: 1.0ex;
459                }
460                pre, ul {
461                    line-height: 120%;
462                }
463                em {
464                    font-weight: bold;
465                    font-style: normal;
466                }
467                strong {
468                    color: #f00;
469                    font-weight: bold;
470                }
471                a {
472                    text-decoration: none;
473                }
474                h3 a{
475                    color: black;
476                    border: none;
477                }
478                blockquote {
479                    margin-left: 2em;
480                    padding: 5px;
481                    border: gray dashed 1px;
482                }
483                .description {
484                    color: #555555;
485                    width: 100%;
486                    padding: 1em;
487                }
488                #powered{
489                    font-size: 9px;
490                    text-align: right;
491                    padding: 0.5em;
492                }
493    </style>
494  </head>
495  <body>
496    <h1>$blog_title</h1>
497    <div class="description">
498      $blog_description
499    </div>
500    <div class="contents">
501EOS
502@default_date = <<EOS
503EOS
504@default_story = <<EOS
505      <h3>$title</h3>
506      <div class="entory">
507        $body
508      </div>
509EOS
510@default_foot = <<EOS
511    </div>
512    <p id="powered">
513        Generated by <a href="http://www.mikihoshi.com/lily" title="">lily</a> $version<br />
514        Powered by <a href="http://www.ruby-lang.org/" title="ruby-lang.org">ruby</a> $ruby_version
515    </p>
516  </body>
517</html>
518EOS
Note: See TracBrowser for help on using the browser.