PageRenderTime 45ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 1ms

/docs/hive.cgi

http://ruby-hive.googlecode.com/
Ruby | 361 lines | 314 code | 37 blank | 10 comment | 24 complexity | 1d9e95ee8b1af6a0c8294808010c1c67 MD5 | raw file
  1. #!/usr/local/bin/ruby
  2. #Heavily adapted from mikiwiki.
  3. require 'cgi'
  4. require 'yaml'
  5. include YAML
  6. class Wiki
  7. def initialize(name, url)
  8. @name = name
  9. @url = url
  10. @db = WikiDB.new(@name)
  11. @hive = restore(@name + '/hive.yaml') || {
  12. :meta => { :code => { :start => "<div class='code'", :end => '</div>' }},
  13. :link => { '\$([a-z]+):' => { :name => 0, :page => 1 } }
  14. }
  15. @meta = @hive[:meta]
  16. @link = @hive[:link]
  17. @brs = []
  18. end
  19. def restore(file)
  20. File.open(file){|f| YAML::load(f)} if FileTest.exists?(file)
  21. end
  22. def make_link(pname, aname = nil)
  23. aname = pname if !aname
  24. if @db.key?(pname)
  25. m = %(<a href="#{@url+'?page='+ CGI::escape(pname)}">#{aname}</a>)
  26. else
  27. m = %(#{aname}<a href="#{@url+'?page='+ CGI::escape(pname)}">?</a>)
  28. end
  29. end
  30. def linking(str,page)
  31. #custom
  32. @link.keys.each {|exp|
  33. str.gsub!(Regexp.new(exp)){|m|
  34. m = %(<a href="#{@url}?page=#{$~[@link[exp][:page]]}">#{$~[@link[exp][:name]]}</a>)
  35. }
  36. }
  37. #normal link
  38. str.gsub!(/\[\[(.+?)\]\]/){|m|
  39. pname = $1
  40. case pname
  41. when /(.+?)\|(.*?)\|(\d+?)\|(\d+?)\|(.+)/
  42. alt = $1
  43. lnk = $2
  44. width = $3
  45. height = $4
  46. if /.+\.((jpe?g)|(gif)|(png)|)/ =~ $5
  47. unless lnk
  48. m = %(<img src="#{$&}" alt="#{alt}" width="#{width}" height="#{height}" border='0' />)
  49. else
  50. m = %(<a href="#{lnk}"><img src="#{$&}" alt="#{alt}" width="#{width}" height="#{height}" border='0' /></a>)
  51. end
  52. end
  53. when /^([^:]+):(.+)/
  54. name = $1
  55. link = $2
  56. if name =~ /http|ftp|mailto|https|irc|svn/
  57. m = %(<a href="#{pname}">#{pname}</a>)
  58. else
  59. m = %(<a href="#{link}">#{name}</a>)
  60. end
  61. when /(.+?)>(.+)/
  62. m = make_link($2, $1)
  63. else
  64. m = make_link(pname)
  65. end
  66. }
  67. #mode
  68. str.gsub!(/\(\((.+?)\)\)/){|m|
  69. sstr = $1
  70. if /\(\((.+?)\|(.+)\)\)/ =~ m
  71. aname = $1
  72. cname = $2
  73. if /(.+?)\|(.+)/ =~ $2
  74. m = %(<a href="#{@url}?mode=#{$1}&amp;page=#{$2}">#{aname}</a>)
  75. else
  76. if cname == 'edit'
  77. m = %(<a href="#{@url}?mode=#{cname}&amp;page=#{page}">#{aname}</a>)
  78. else
  79. m = %(<a href="#{@url}?mode=#{cname}">#{aname}</a>)
  80. end
  81. end
  82. else
  83. case sstr
  84. when 'page'
  85. m = page
  86. when 'copy'
  87. m = "&copy;"
  88. end
  89. end
  90. }
  91. str
  92. end
  93. def meta(str)
  94. return case str.chomp when /^\|([^ \t:]+):(.*)/
  95. if @meta[$1.to_sym]
  96. @meta[$1.to_sym][:start] + $2 + @meta[$1.to_sym][:end] + '$'
  97. else
  98. "<#{$1}>" + $2 + "</#{$1}>" + '$'
  99. end
  100. #multilined.
  101. when /^\[([^ \t:]+):/
  102. if @meta[$1.to_sym]
  103. @brs << @meta[$1.to_sym][:end]
  104. @meta[$1.to_sym][:start] + '$'
  105. else
  106. @brs << "</#{$1}>"
  107. "<#{$1}>" + '$'
  108. end
  109. when /^\] *$/
  110. (@brs.pop || '') + '$'
  111. else
  112. str
  113. end
  114. end
  115. def cleanup(str)
  116. str.gsub("\t", "&nbsp;&nbsp;&nbsp;&nbsp;").gsub(" ", "&nbsp;&nbsp;").gsub(/~+/){|m|
  117. if m == '~'
  118. m = ''
  119. else
  120. m = '~'
  121. end
  122. }.gsub(/<\|/,'&lt;').gsub(/\|>/,'&gt;').gsub(/~~/,'~')
  123. end
  124. def convert(s, page = nil)
  125. return s.split(/\n/).collect{|str|cleanup meta linking(str,page)}.collect{|str|
  126. case str
  127. when /(.*)\$$/
  128. $1
  129. else
  130. str + '<br/>'
  131. end
  132. }
  133. end
  134. def disp(page = 'FrontPage')
  135. page = 'FrontPage' unless page
  136. if @db.key?(page)
  137. main_frame(convert(@db[page], page), page)
  138. else
  139. edit(page)
  140. end
  141. end
  142. def edit(page)
  143. content = ""
  144. if @db.key?(page)
  145. content = @db[page]
  146. else
  147. content = "[[#{page}]]\n\n"
  148. end
  149. field = <<EOS
  150. edit : #{page}
  151. </p>
  152. <form method="post" action="#{@url}">
  153. <p>
  154. <textarea name="data" cols="120" rows="60">#{CGI::escapeHTML(content)}</textarea><br />
  155. <input type="hidden" name="mode" value="write" />
  156. <input type="hidden" name="page" value="#{page}" />
  157. <input type="submit" value="save" />
  158. <input type="reset" value="clear" />
  159. </p>
  160. </form>
  161. <p class="content">
  162. EOS
  163. main_frame(field, page)
  164. end
  165. def put(page, data)
  166. if data == ""
  167. if @db.key?(page)
  168. @db.delete(page)
  169. disp
  170. return
  171. end
  172. else
  173. @db[page] = data
  174. end
  175. end
  176. def write(page, data)
  177. put(page, data)
  178. disp(page)
  179. end
  180. def index(exp = nil)
  181. list = <<HEAD
  182. Index of #{@name}<br/><br/>
  183. <form method='get' action='#{@url}'>
  184. <input type="text" name="filter" value="#{exp}" />
  185. <input type="hidden" name="mode" value="index" />
  186. <input type="submit" value="filter" />
  187. </form>
  188. HEAD
  189. if !exp
  190. exp = Regexp.new('.*')
  191. else
  192. exp = Regexp.new(exp)
  193. end
  194. @db.keys.sort.each{|key|
  195. list += %(<a href="#{@url+'?page='+ key}">#{key}</a><br/>\n) if key =~ exp
  196. }
  197. main_frame(list, '')
  198. end
  199. def create
  200. field = <<EOS
  201. create new wiki page.
  202. </p>
  203. <form method="post" action="#{@url}">
  204. <p>
  205. <input type="hidden" name="mode" value="edit" />
  206. <input type="text" name="page" value="" />
  207. <input type="submit" value="create" />
  208. </p>
  209. </form>
  210. <p class="content">
  211. EOS
  212. main_frame(field, '')
  213. end
  214. def style
  215. css = ""
  216. File::open("#{@name}/hive.css","r"){|f|
  217. css = f.read
  218. }
  219. print <<EOS
  220. Content-type:text/css
  221. #{css}
  222. EOS
  223. end
  224. def main_frame(content, page)
  225. print <<EOS
  226. Content-type:text/html
  227. <?xml version="1.0"?>
  228. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
  229. <html xmlns="http://www.w3.org/1999/xhtml">
  230. <head>
  231. <link type="text/css" rel="stylesheet" href="/cgi-bin/site.css" >
  232. <link rel="stylesheet" type="text/css" href="#{@url}?mode=style" />
  233. <title>#{@name}</title>
  234. </head>
  235. <body>
  236. <p class="head">
  237. #{convert(@db['PageHead'],page)}
  238. </p>
  239. <p class="content">
  240. #{content}
  241. </p>
  242. <p class="tail">
  243. #{convert(@db['PageTail'],page)}
  244. </p>
  245. </body>
  246. </html>
  247. EOS
  248. end
  249. def has_page?(page)
  250. @db.key?(page)
  251. end
  252. end
  253. class WikiDB
  254. include FileTest
  255. def initialize(name)
  256. @name = name
  257. Dir.mkdir(@name) unless directory?(@name)
  258. end
  259. def read(key)
  260. begin
  261. File::open("#{@name}/#{key}","r"){|f| return f.read }
  262. rescue
  263. end
  264. end
  265. def write(key, value)
  266. File::open("#{@name}/#{key}","w"){|f|
  267. f.flock(File::LOCK_EX)
  268. f.print value
  269. f.flock(File::LOCK_UN)
  270. }
  271. end
  272. def [](key)
  273. read(key)
  274. end
  275. def []=(key,value)
  276. write(key, value)
  277. end
  278. def key?(key)
  279. exist?("#{@name}/#{key}")
  280. end
  281. def keys
  282. Dir.entries(@name).delete_if{|e|
  283. if /\.\.?/ =~ e then true end
  284. }
  285. end
  286. def delete(key)
  287. File::delete("#{@name}/#{page}")
  288. end
  289. end
  290. if __FILE__ == $0
  291. begin
  292. cgi = CGI.new
  293. wiki = Wiki.new('hive', 'hive.cgi')
  294. unless wiki.has_page?('PageHead')
  295. head = <<EOS
  296. ((New|create)) | [[FrontPage>FrontPage]] | ((Edit|edit)) | ((Index|index))
  297. EOS
  298. wiki.put('PageHead',head)
  299. end
  300. unless wiki.has_page?('PageTail')
  301. tail = <<EOS
  302. EOS
  303. wiki.put('PageTail',tail)
  304. end
  305. case cgi["mode"][0]
  306. when 'create'
  307. wiki.create
  308. when 'index'
  309. wiki.index cgi['filter']
  310. when 'edit'
  311. wiki.edit(cgi["page"][0])
  312. when 'write'
  313. wiki.write(cgi["page"][0],cgi["data"][0])
  314. when 'style'
  315. wiki.style
  316. else
  317. wiki.disp(cgi["page"][0])
  318. end
  319. rescue Exception
  320. print "Content-Type: text/plain\n\n"
  321. puts "#$! (#{$!.class})\n\n"
  322. puts $@.join( "\n" )
  323. end
  324. end