ruby-web 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) hide show
  1. data/ChangeLog +474 -0
  2. data/INSTALL.txt +9 -0
  3. data/InstalledFiles +180 -0
  4. data/LICENSE.txt +74 -0
  5. data/Rakefile +529 -0
  6. data/TODO +65 -0
  7. data/doc/additional.xml +149 -0
  8. data/doc/core.xml +652 -0
  9. data/doc/credits/index.xml +52 -0
  10. data/doc/credits/php.contributors.xml +118 -0
  11. data/doc/credits/php.language-snippets.ent +622 -0
  12. data/doc/install/index.xml +136 -0
  13. data/doc/install/mac/index.xml +21 -0
  14. data/doc/install/ruby-web.install.rb.instructions.xml +7 -0
  15. data/doc/install/unix/index.xml +46 -0
  16. data/doc/install/win/apache1.xml +166 -0
  17. data/doc/install/win/apache2.xml +141 -0
  18. data/doc/install/win/iis.xml +162 -0
  19. data/doc/install/win/index.xml +24 -0
  20. data/doc/install/win/installer.xml +31 -0
  21. data/doc/install/win/manual.xml +43 -0
  22. data/doc/manual.xml +69 -0
  23. data/doc/old/apache_cgi.txt +23 -0
  24. data/doc/old/fastcgi.txt +23 -0
  25. data/doc/old/mod_ruby.txt +21 -0
  26. data/doc/old/snippets.rdoc +183 -0
  27. data/doc/old/webrick.txt +23 -0
  28. data/doc/old/windows_cgi.txt +9 -0
  29. data/doc/tutorial.xml +14 -0
  30. data/doc/xsl/manual-multi.xsl +10 -0
  31. data/doc/xsl/manual-pdf.xsl +6 -0
  32. data/doc/xsl/manual-single.xsl +6 -0
  33. data/doc/xsl/manual.css +22 -0
  34. data/install.rb +1022 -0
  35. data/lib/formatter.rb +314 -0
  36. data/lib/html-parser.rb +429 -0
  37. data/lib/htmlrepair.rb +113 -0
  38. data/lib/htmlsplit.rb +842 -0
  39. data/lib/sgml-parser.rb +332 -0
  40. data/lib/web.rb +68 -0
  41. data/lib/web/assertinclude.rb +129 -0
  42. data/lib/web/config.rb +50 -0
  43. data/lib/web/connection.rb +1070 -0
  44. data/lib/web/convenience.rb +154 -0
  45. data/lib/web/formreader.rb +318 -0
  46. data/lib/web/htmlparser/html-parser.rb +429 -0
  47. data/lib/web/htmlparser/sgml-parser.rb +332 -0
  48. data/lib/web/htmltools/element.rb +296 -0
  49. data/lib/web/htmltools/stparser.rb +276 -0
  50. data/lib/web/htmltools/tags.rb +286 -0
  51. data/lib/web/htmltools/tree.rb +139 -0
  52. data/lib/web/htmltools/xmltree.rb +160 -0
  53. data/lib/web/htmltools/xpath.rb +71 -0
  54. data/lib/web/info.rb +63 -0
  55. data/lib/web/load.rb +210 -0
  56. data/lib/web/mime.rb +87 -0
  57. data/lib/web/phprb.rb +340 -0
  58. data/lib/web/resources/test/cookie.rb +33 -0
  59. data/lib/web/resources/test/counter.rb +20 -0
  60. data/lib/web/resources/test/multipart.rb +14 -0
  61. data/lib/web/resources/test/redirect.rb +8 -0
  62. data/lib/web/resources/test/stock.rb +33 -0
  63. data/lib/web/sapi/apache.rb +129 -0
  64. data/lib/web/sapi/fastcgi.rb +22 -0
  65. data/lib/web/sapi/install/apache.rb +180 -0
  66. data/lib/web/sapi/install/iis.rb +93 -0
  67. data/lib/web/sapi/install/macosx.rb +90 -0
  68. data/lib/web/sapi/webrick.rb +86 -0
  69. data/lib/web/session.rb +83 -0
  70. data/lib/web/shim/cgi.rb +129 -0
  71. data/lib/web/shim/rails.rb +175 -0
  72. data/lib/web/stringio.rb +78 -0
  73. data/lib/web/strscanparser.rb +24 -0
  74. data/lib/web/tagparser.rb +96 -0
  75. data/lib/web/testing.rb +666 -0
  76. data/lib/web/traceoutput.rb +75 -0
  77. data/lib/web/unit.rb +56 -0
  78. data/lib/web/upload.rb +59 -0
  79. data/lib/web/validate.rb +52 -0
  80. data/lib/web/wiki.rb +557 -0
  81. data/lib/web/wiki/linker.rb +72 -0
  82. data/lib/web/wiki/page.rb +201 -0
  83. data/lib/webunit.rb +27 -0
  84. data/lib/webunit/assert.rb +152 -0
  85. data/lib/webunit/converter.rb +154 -0
  86. data/lib/webunit/cookie.rb +118 -0
  87. data/lib/webunit/domwalker.rb +185 -0
  88. data/lib/webunit/exception.rb +14 -0
  89. data/lib/webunit/form.rb +116 -0
  90. data/lib/webunit/frame.rb +37 -0
  91. data/lib/webunit/htmlelem.rb +122 -0
  92. data/lib/webunit/image.rb +26 -0
  93. data/lib/webunit/jscript.rb +31 -0
  94. data/lib/webunit/link.rb +33 -0
  95. data/lib/webunit/params.rb +321 -0
  96. data/lib/webunit/parser.rb +229 -0
  97. data/lib/webunit/response.rb +464 -0
  98. data/lib/webunit/runtest.rb +41 -0
  99. data/lib/webunit/table.rb +148 -0
  100. data/lib/webunit/testcase.rb +45 -0
  101. data/lib/webunit/ui/cui/testrunner.rb +50 -0
  102. data/lib/webunit/utils.rb +68 -0
  103. data/lib/webunit/webunit.rb +28 -0
  104. data/test/dev/action.rb +83 -0
  105. data/test/dev/forms.rb +104 -0
  106. data/test/dev/forms2.rb +104 -0
  107. data/test/dev/parser.rb +17 -0
  108. data/test/dev/scripts/dump.rb +24 -0
  109. data/test/dev/scripts/makedist.rb +62 -0
  110. data/test/dev/scripts/uri.rb +41 -0
  111. data/test/dev/scripts/uri/common.rb +432 -0
  112. data/test/dev/scripts/uri/ftp.rb +149 -0
  113. data/test/dev/scripts/uri/generic.rb +1106 -0
  114. data/test/dev/scripts/uri/http.rb +76 -0
  115. data/test/dev/scripts/uri/https.rb +26 -0
  116. data/test/dev/scripts/uri/ldap.rb +238 -0
  117. data/test/dev/scripts/uri/mailto.rb +260 -0
  118. data/test/dev/scripts/urireg.rb +174 -0
  119. data/test/dev/simpledispatcher.rb +156 -0
  120. data/test/dev/test.action.rb +146 -0
  121. data/test/dev/test.formreader.rb +463 -0
  122. data/test/dev/test.simpledispatcher.rb +186 -0
  123. data/test/dev/webunit/conv/digit-0.rb +21 -0
  124. data/test/dev/webunit/conv/digit-1.rb +17 -0
  125. data/test/dev/webunit/conv/digit.rb +23 -0
  126. data/test/dev/webunit/conv/test_digit-0.rb +16 -0
  127. data/test/dev/webunit/conv/test_digit-1.rb +19 -0
  128. data/test/dev/webunit/conv/test_digit.rb +26 -0
  129. data/test/dev/webunit/conv/test_digit_view-0.rb +76 -0
  130. data/test/dev/webunit/conv/test_digit_view-1.rb +102 -0
  131. data/test/dev/webunit/conv/test_digit_view.rb +134 -0
  132. data/test/installation/htdocs/cgi_test.rb +296 -0
  133. data/test/installation/htdocs/test_install.rb +4 -0
  134. data/test/installation/runwebtest.rb +5 -0
  135. data/test/installation/test_cookie.rb +128 -0
  136. data/test/installation/test_form.rb +47 -0
  137. data/test/installation/test_multipart.rb +51 -0
  138. data/test/installation/test_request.rb +24 -0
  139. data/test/installation/test_response.rb +35 -0
  140. data/test/unit/htdocs/cookie.rb +32 -0
  141. data/test/unit/htdocs/multipart.rb +28 -0
  142. data/test/unit/htdocs/redirect.rb +12 -0
  143. data/test/unit/htdocs/simple.rb +13 -0
  144. data/test/unit/htdocs/stock.rb +33 -0
  145. data/test/unit/test_assert.rb +162 -0
  146. data/test/unit/test_cookie.rb +114 -0
  147. data/test/unit/test_domwalker.rb +77 -0
  148. data/test/unit/test_form.rb +42 -0
  149. data/test/unit/test_frame.rb +40 -0
  150. data/test/unit/test_htmlelem.rb +74 -0
  151. data/test/unit/test_image.rb +45 -0
  152. data/test/unit/test_jscript.rb +57 -0
  153. data/test/unit/test_link.rb +85 -0
  154. data/test/unit/test_multipart.rb +51 -0
  155. data/test/unit/test_params.rb +210 -0
  156. data/test/unit/test_parser.rb +53 -0
  157. data/test/unit/test_response.rb +150 -0
  158. data/test/unit/test_table.rb +70 -0
  159. data/test/unit/test_utils.rb +106 -0
  160. data/test/unit/test_webunit.rb +28 -0
  161. data/test/web/mod_ruby_stub.rb +39 -0
  162. data/test/web/test.assertinclude.rb +109 -0
  163. data/test/web/test.buffer.rb +182 -0
  164. data/test/web/test.code.loader.rb +78 -0
  165. data/test/web/test.config.rb +31 -0
  166. data/test/web/test.error.handling.rb +91 -0
  167. data/test/web/test.formreader-2.0.rb +352 -0
  168. data/test/web/test.load.rb +125 -0
  169. data/test/web/test.mime-type.rb +23 -0
  170. data/test/web/test.narf.cgi.rb +106 -0
  171. data/test/web/test.phprb.rb +239 -0
  172. data/test/web/test.request.rb +368 -0
  173. data/test/web/test.response.rb +637 -0
  174. data/test/web/test.ruby-web.rb +10 -0
  175. data/test/web/test.session.rb +50 -0
  176. data/test/web/test.shim.cgi.rb +96 -0
  177. data/test/web/test.tagparser.rb +65 -0
  178. data/test/web/test.template2.rb +297 -0
  179. data/test/web/test.testing2.rb +318 -0
  180. data/test/web/test.upload.rb +45 -0
  181. data/test/web/test.validate.rb +46 -0
  182. data/test/web/test.web.test.rb +495 -0
  183. data/test/wiki/test.history.rb +297 -0
  184. data/test/wiki/test.illustration_page.rb +287 -0
  185. data/test/wiki/test.linker.rb +197 -0
  186. data/test/wiki/test.tarpit.rb +56 -0
  187. data/test/wiki/test.wiki.rb +300 -0
  188. data/test/wikitestroot/admin.rb +7 -0
  189. data/test/wikitestroot/wiki.rb +6 -0
  190. metadata +234 -0
@@ -0,0 +1,75 @@
1
+ # TODO: trace output is woefully broken
2
+
3
+ # TODO: formerly on Web::close:
4
+ # if Web::display_trace
5
+ # trace_output
6
+ # end
7
+
8
+
9
+ module Web
10
+ # Web::display_trace controls the display of trace variables
11
+ @@display_trace = false
12
+ class << self
13
+ attr_accessor :display_trace
14
+ end
15
+
16
+ TRACE_STYLESHEET=<<-EOF
17
+ <style type="text/css">
18
+ span.tracecontent { background-color:white; color:black;font: 10pt verdana, arial; }
19
+ span.tracecontent table { font: 10pt verdana, arial; cellspacing:0; cellpadding:0; margin-bottom:25}
20
+ span.tracecontent tr.subhead { background-color:cccccc;}
21
+ span.tracecontent th { padding:0,3,0,3 }
22
+ span.tracecontent th.alt { background-color:black; color:white; padding:3,3,2,3; }
23
+ span.tracecontent td { padding:0,3,0,3 }
24
+ span.tracecontent tr.alt { background-color:eeeeee }
25
+ span.tracecontent h1 { font: 24pt verdana, arial; margin:0,0,0,0}
26
+ span.tracecontent h2 { font: 18pt verdana, arial; margin:0,0,0,0}
27
+ span.tracecontent h3 { font: 12pt verdana, arial; margin:0,0,0,0}
28
+ span.tracecontent th a { color:darkblue; font: 8pt verdana, arial; }
29
+ span.tracecontent a { color:darkblue;text-decoration:none }
30
+ span.tracecontent a:hover { color:darkblue;text-decoration:underline; }
31
+ span.tracecontent div.outer { width:90%; margin:15,15,15,15}
32
+ span.tracecontent table.viewmenu td { background-color:006699; color:white; padding:0,5,0,5; }
33
+ span.tracecontent table.viewmenu td.end { padding:0,0,0,0; }
34
+ span.tracecontent table.viewmenu a {color:white; font: 8pt verdana, arial; }
35
+ span.tracecontent table.viewmenu a:hover {color:white; font: 8pt verdana, arial; }
36
+ span.tracecontent a.tinylink {color:darkblue; font: 8pt verdana, arial;text-decoration:underline;}
37
+ span.tracecontent a.link {color:darkblue; text-decoration:underline;}
38
+ span.tracecontent div.buffer {padding-top:7; padding-bottom:17;}
39
+ span.tracecontent .small { font: 8pt verdana, arial }
40
+ span.tracecontent table td { padding-right:20 }
41
+ span.tracecontent table td.nopad { padding-right:5 }
42
+ </style>
43
+ EOF
44
+
45
+ class Connection
46
+ def Connection.trace_output_template
47
+ template = <<-EOF
48
+ <div>
49
+ <h1>Request Details</h1><br>
50
+ <table cellspacing="0" cellpadding="0" border="1" style="width:100%;border-collapse:collapse;">
51
+ <tr>
52
+ <th class="alt" align="Left" colspan=2><h3><b>Request Parameters</b></h3></th></tr>
53
+ <narf:foreach from=parameters item=parameter>
54
+ <tr><th width=150>{$parameter.key}</th><td>{$parameter.value}</td></tr>
55
+ </narf:foreach>
56
+ </table>
57
+ <br>
58
+ <table cellspacing="0" cellpadding="0" border="1" style="width:100%;border-collapse:collapse;">
59
+ <tr><th class="alt" align="Left" colspan=2><h3><b>Cookies</b></h3></th></tr>
60
+ <narf:foreach from=cookies item=cookie>
61
+ <tr><th width=150>{$cookie.key}</th><td>{$cookie.value}</td></tr>
62
+ </narf:foreach>
63
+ </table>
64
+ <br>
65
+ <table cellspacing="0" cellpadding="0" border="1" style="width:100%;border-collapse:collapse;">
66
+ <tr><th class="alt" align="Left" colspan=2><h3><b>Session</b></h3></th></tr>
67
+ <narf:foreach from=session item=sessionitem>
68
+ <tr><th width=150>{$sessionitem.key}</th><td>{$sessionitem.value}</td></tr>
69
+ </table>
70
+ </div>
71
+ EOF
72
+ end
73
+ end
74
+ end
75
+
@@ -0,0 +1,56 @@
1
+ require 'web'
2
+ require 'webunit/webunit'
3
+
4
+ module Web
5
+ module Unit
6
+ include WebUnit
7
+ include WebUnit::Utils
8
+ attr_reader :response
9
+
10
+ def setup_webunit
11
+ @urlbase = ENV['URLBASE'] ? ENV['URLBASE'] : 'http://localhost/'
12
+ @urlbase = orthop_url( @urlbase )
13
+ @urlbase << '/' unless @urlbase =~ %r!/$!
14
+ $stderr.puts "URLBASE is #{@urlbase}" if $DEBUG
15
+ $URLBASE = @urlbase
16
+ WebUnit::Response::reset
17
+ @cookies_kept = WebUnit::Cookies::instance.cookies
18
+ Web::cookie::clear
19
+ end
20
+
21
+ def update_cookies
22
+ Web::cookie = Hash.new
23
+ Cookies.instance.cookies.each do |k, v|
24
+ Web::cookie[k.first] = v['value']
25
+ end
26
+ end
27
+
28
+ def reverse_update_cookies
29
+ Cookies::clear
30
+ Web::cookie.each do |k,v|
31
+ Cookies::add( k, v )
32
+ end
33
+ end
34
+
35
+ def do_request( url, params={} )
36
+ reverse_update_cookies
37
+ url = @urlbase + url unless (url.index(@urlbase) == 0)
38
+ @response = Response::get( url )
39
+ update_cookies
40
+ end
41
+
42
+ def do_submit( params={} )
43
+ reverse_update_cookies
44
+ form = @response.form
45
+ params.each do |k,v|
46
+ form.params[k].value = v
47
+ end
48
+ @response = form.submit
49
+ update_cookies
50
+ end
51
+
52
+ def assert_title( expected, document=@response )
53
+ assert_equal( expected, document.title )
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,59 @@
1
+ require 'tempfile'
2
+
3
+ module Web
4
+ # == Purpose
5
+ # This class delegates to the uploaded Tempfile, and adds
6
+ # content type and original filename attributes.
7
+ #
8
+ # If you are testing a multipart/form, use this class
9
+ # to pretend you uploaded a file:
10
+ #
11
+ # "uploaded_file" => Upload.new(anIO,
12
+ # "image/png",
13
+ # "my_favorite_image.png" )
14
+ #
15
+ # See Web::Testing for more information.
16
+ #
17
+ class Upload
18
+ attr_reader :content_type, :original_filename
19
+
20
+ def initialize( tempfile, content_type, original_filename )
21
+ if (tempfile.is_a? String)
22
+ contents = File.open( tempfile, "r" ) { |f| f.read }
23
+ tempfile = Tempfile.new("Web")
24
+ tempfile.binmode
25
+ tempfile.write contents
26
+ tempfile.rewind
27
+ end
28
+
29
+ @content_type = content_type
30
+ @original_filename = original_filename
31
+ @tempfile = tempfile
32
+ end
33
+
34
+ def local_path
35
+ @tempfile.path
36
+ end
37
+
38
+ # use this method to move an upload somewhere you care about
39
+ def save( filename )
40
+ File.open( filename, "w" ) { |f|
41
+ f.binmode
42
+ f.write( self.read )
43
+ }
44
+ end
45
+
46
+ # how do I get the contents of an upload?
47
+ def read
48
+ @tempfile.rewind
49
+ @tempfile.read
50
+ end
51
+
52
+ # how do I get in IO object from an upload?
53
+ def open
54
+ @tempfile.rewind
55
+ yield @tempfile
56
+ end
57
+ end
58
+
59
+ end
@@ -0,0 +1,52 @@
1
+ module Web
2
+ def Web::rule( params = {} )
3
+ Web::ruleset ||= Array.new
4
+ Web::ruleset.push Rule.new( params )
5
+ end
6
+
7
+ def Web::validate
8
+ problems = Array.new
9
+ Web::ruleset.each do |r|
10
+ unless Web[r.field] =~ r.regexp
11
+ problems.push r
12
+ raise Web::FatalValidationError.new(r) if (r.malformed == :fatal)
13
+ end
14
+ end
15
+ problems
16
+ end
17
+
18
+ class Connection
19
+ attr_accessor :ruleset
20
+ end
21
+
22
+ class Web::FatalValidationError < Error
23
+ attr_reader :rule
24
+ def initialize( rule )
25
+ @rule = rule
26
+ super( rule.message )
27
+ end
28
+ end
29
+
30
+ class Rule
31
+ attr_reader :field, :regexp, :message, :malformed
32
+ def initialize( params = {} )
33
+ [:field, :regexp].each do |k|
34
+ unless params.has_key? k
35
+ raise ArgumentError.new( "Web::rule is missing required parameter (:#{k})" )
36
+ else
37
+ self.instance_variable_set("@#{k}".intern, params[k] )
38
+ end
39
+ end
40
+
41
+ [:message, :malformed ].each do |k|
42
+ if params.has_key? k
43
+ self.instance_variable_set("@#{k}".intern, params[k] )
44
+ end
45
+ end
46
+
47
+ @field = @field.to_s
48
+ @malformed ||= :continue
49
+
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,557 @@
1
+ require 'web'
2
+ require 'web/wiki/linker'
3
+ require 'web/wiki/page'
4
+ require 'yaml'
5
+ require 'ftools'
6
+ require 'strscan'
7
+ require 'ipaddr'
8
+
9
+ module Web
10
+ # == Purpose
11
+ # This wiki exists to:
12
+ # * Serve http://www.narf-lib.org
13
+ # * Test the utility of features in the NARF toolkit, and serve
14
+ # as an example of how to build a decent-sized application
15
+ # with NARF
16
+ # * Be a nice, useful wiki; aka UseMod with HTMLArea integration
17
+ # and image uploads
18
+ #
19
+ # == Usage
20
+ # This is the quickest way to embed the narf wiki:
21
+ #
22
+ # #!/usr/bin/env ruby
23
+ # require 'web/wiki'
24
+ # Web::process{
25
+ # Web::Wiki::handle_request()
26
+ # }
27
+ #
28
+ # You will enjoy your wiki more, however, by fiddling with
29
+ # a few config settings. Here what a production wiki.rb might
30
+ # look like:
31
+ #
32
+ # #!/usr/bin/env ruby
33
+ # require 'web/wiki'
34
+ #
35
+ # Web::process{
36
+ # # this line allows me to overload the default templates
37
+ # Web::config[:load_path] << "../"
38
+ #
39
+ # # here I set a number of config variables.
40
+ # Web::Wiki::set_pref( :store_url => "/pages/",
41
+ # :store_dir => "../pages/",
42
+ # :home_page => "NarfRocks",
43
+ # :resourceurl => "/resources" )
44
+ #
45
+ # # finally, I handle the request
46
+ # Web::Wiki.handle_request
47
+ # }
48
+ #
49
+ # The default templates for the NARF wiki are located in
50
+ #
51
+ # site_lib/web/wiki/resources/
52
+ #
53
+ # Append your template dir to the :load_path and
54
+ # only worry about overriding the templates you care about.
55
+ # Chances are, you'll care about these two templates:
56
+ #
57
+ # template.html:: the overall template
58
+ # home.html:: the template for the homepage
59
+ #
60
+ # The following preferences can make a difference for
61
+ # your wiki:
62
+ #
63
+ # store_dir::
64
+ # Web::Wiki uses YAML to save pages. By default,
65
+ # these pages will be saved in "./pages/".
66
+ # store_url::
67
+ # If you make your store files publicly accessible,
68
+ # Web::Wiki can let the webserver handle any the download
69
+ # of any upload page assets.
70
+ # home_page::
71
+ # The default home page for the wiki is HomePage. Set the
72
+ # HomePage to something meaningful in your wiki.
73
+ # resourceurl::
74
+ # By default, the NARF wiki will download various resource files
75
+ # from sitelib/web/wiki/resources. This makes installation easy,
76
+ # but a single visit to the edit page will incur the hit of
77
+ # executing ruby for every single image. Make these files
78
+ # accessible online and tell NARF where to find them, and
79
+ # things should run more quickly.
80
+ #
81
+ # == Credits
82
+ # Web::Wiki must extend its thanks to these very, very useful projects:
83
+ #
84
+ # YAML:: http://yaml4r.sourceforge.net/
85
+ # HTMLArea:: http://sourceforge.net/projects/itools-htmlarea/
86
+ #
87
+ class Wiki
88
+
89
+ # It seems nicer to define the class
90
+ # methods on an object and
91
+ # delegate a few class methods
92
+ def Wiki.method_missing( symbol, *args )
93
+ if [:handle_request,
94
+ :store_dir,
95
+ :store_url,
96
+ :store_basedir,
97
+ :more_news,
98
+ :page_list,
99
+ :open_permissions ].include? symbol
100
+ wiki.send symbol, *args
101
+ else
102
+ super( symbol, args )
103
+ end
104
+ end
105
+
106
+ @@wiki = nil
107
+ def Wiki.wiki
108
+ @@wiki ||= Wiki.new
109
+ end
110
+
111
+ def Wiki.wipe #:nodoc:
112
+ @@wiki = nil
113
+ end
114
+
115
+ @@preferences = nil
116
+ def Wiki.preferences
117
+ @@preferences ||= {"baseurl" => Web::script_name,
118
+ "resourceurl" => "{$baseurl}/resources",
119
+ "store_dir" => "./pages/",
120
+ "tarpit_dir" => "./tarpit/",
121
+ "resource_dir" => File.join( File.dirname( __FILE__ ),
122
+ "wiki",
123
+ "resources" ),
124
+ "vandals" => "vandals.txt",
125
+ "home_page" => "HomePage",
126
+ "home_template" => "home.html",
127
+ "allowed_actions" => Wiki::Request.actions.keys
128
+ }
129
+ end
130
+
131
+ def Wiki.pref( key )
132
+ key = key.to_s unless (key.kind_of? String)
133
+ pref = Wiki.preferences[key]
134
+ while (pref =~ /\{\$([^\}]*)\}/)
135
+ variable = $1
136
+ pref.gsub!( /\{\$#{variable}\}/, Wiki.pref( variable.strip ) || "")
137
+ end
138
+ pref
139
+ end
140
+
141
+ def Wiki.set_pref( new_prefs={} )
142
+ new_prefs.each{ |key,value|
143
+ key = key.to_s unless (key.kind_of? String)
144
+ Wiki.preferences[key] = value
145
+ }
146
+ end
147
+ #-------------------------------------------------------------
148
+
149
+ module Store #:nodoc:
150
+
151
+ def move_asset( from, filename )
152
+ historical = File.expand_path(filename)
153
+ i=0
154
+ while( File.exists? historical )
155
+ i += 1
156
+ historical = File.dirname( historical ) + "/\#" + i.to_s + "." + File.basename( historical ).gsub( /^\#\d*\./, "" )
157
+ end
158
+
159
+ File.move( filename, historical ) if File.exists? filename
160
+
161
+ if (from.is_a? Web::Upload)
162
+ from.save(filename)
163
+ else
164
+ File.move( from, filename )
165
+ end
166
+ end
167
+
168
+ def page_list
169
+ Dir[store_dir + "/*.yaml"].entries.collect { |e|
170
+ File.basename( e, ".yaml" ).gsub( /-slash-/, "/" )
171
+ }
172
+ end
173
+
174
+ def store( name )
175
+ File.join( store_dir, name.gsub(/\//, "-slash-") + ".yaml" )
176
+ end
177
+
178
+ def load_page( name = Web["page.name"] )
179
+ if name.size == 0
180
+ if (Web.path_info)
181
+ name = Web.path_info.gsub( Regexp.new(Web.script_name), "" ).gsub(/^\/|\.html$/,"")
182
+ end
183
+ if name.size == 0
184
+ name = Web::Wiki::pref( :home_page )
185
+ end
186
+ end
187
+
188
+ page = ""
189
+ page_file = store( name )
190
+ if File.exists? page_file
191
+ File.open( page_file, "r" ) { |f|
192
+ page = YAML.load( f )
193
+ }
194
+ else
195
+ page = Web::Wiki::Page.new( name )
196
+ end
197
+
198
+ {/\\r/ => "\r",
199
+ /\\n/ => "\n",
200
+ /\\"/ => "\"",
201
+ /\\'/ => "'", }.each{ |find, replace|
202
+ page.content.gsub!( find, replace )
203
+ }
204
+ page
205
+ end
206
+
207
+ def news
208
+ more_news[0..4]
209
+ end
210
+
211
+ def more_news
212
+ if File.exists?(store_dir + "/more_news.yaml")
213
+ contents = File.open( store_dir + "/more_news.yaml" ) { |f| f.read }
214
+ unless contents.empty?
215
+ YAML.load(contents)
216
+ else
217
+ [ ]
218
+ end
219
+ else
220
+ [ ]
221
+ end
222
+ end
223
+
224
+ def recent
225
+ if File.exists?(store_dir + "/recent.yaml")
226
+ contents = File.open( store_dir + "/recent.yaml" ) { |f| f.read }
227
+ unless contents.empty?
228
+ YAML.load(contents)
229
+ else
230
+ [ ]
231
+ end
232
+ else
233
+ [ ]
234
+ end
235
+ end
236
+
237
+ def save( page )
238
+ # save a slim version of the page for recent changes
239
+ rcpage = page.clone
240
+ rcpage.content = ""
241
+ rcpage.history = [ ]
242
+
243
+ rc = more_news
244
+ rc = rc.unshift(rcpage) unless rcpage.comment.empty?
245
+ rc.pop if rc.size > Page::max_revisions
246
+ yaml = rc.to_yaml
247
+ File.open( store_dir + "/more_news.yaml", "w" ) { |f|
248
+ f.write(yaml)
249
+ }
250
+
251
+ rc = recent
252
+ rc = rc.unshift(rcpage)
253
+
254
+ recent_page_names = [ ]
255
+ rc.delete_if do |p|
256
+ if recent_page_names.include? p.name
257
+ true
258
+ else
259
+ recent_page_names.push p.name
260
+ false
261
+ end
262
+ end
263
+ rc.pop if rc.size > Page::max_revisions
264
+ yaml = rc.to_yaml
265
+ File.open( store_dir + "/recent.yaml", "w" ) do |f|
266
+ f.write(yaml)
267
+ end
268
+
269
+ comment = page.comment
270
+ # clear out comment now that we've saved more news
271
+ page.comment = ""
272
+ yaml = page.to_yaml
273
+ File.open( store( page.name ), "w" ) { |f|
274
+ f.write(yaml)
275
+ }
276
+ end
277
+
278
+
279
+ def store_basedir
280
+ if ( vandal? )
281
+ Wiki.pref( "tarpit_dir" )
282
+ else
283
+ Wiki.pref( "store_dir" )
284
+ end
285
+ end
286
+
287
+ def store_dir
288
+ unless (File.exists? store_dirname)
289
+ File.makedirs( store_dirname)
290
+ end
291
+ store_dirname
292
+ end
293
+
294
+ def store_url
295
+ Wiki::pref( :store_url ) || Wiki::pref( :store_dir )
296
+ end
297
+
298
+ def store_dirname
299
+ unless ( store_basedir =~ /^(\w:)?\// )
300
+ File.expand_path( Dir.pwd + "/" + self.store_basedir )
301
+ else
302
+ store_basedir
303
+ end
304
+ end
305
+
306
+ def vandal?
307
+ vandal = false
308
+ vandals.each do |pattern|
309
+ if pattern =~ ENV["REMOTE_ADDR"]
310
+ vandal = true
311
+ break
312
+ end
313
+ end
314
+ vandal
315
+ end
316
+
317
+ def vandals
318
+ @vandals ||= if File.exists?( Wiki.pref("vandals") || "" )
319
+ File.open( Wiki.pref("vandals") ) { |f|
320
+ f.to_a
321
+ }.collect{ |line|
322
+ /^#{line.chomp.strip.gsub(/"/, '')}/
323
+ }
324
+ else
325
+ [ ]
326
+ end
327
+ end
328
+
329
+ def open_permissions
330
+ require 'find'
331
+ Find.find( store_dir ) { |name|
332
+ begin
333
+ if File.directory? name
334
+ File.chmod( 0777, name )
335
+ else
336
+ File.chmod( 0666, name )
337
+ end
338
+ rescue Exception
339
+ # this should be more specific to access errors
340
+ end
341
+ }
342
+ end
343
+
344
+ end
345
+
346
+ include Wiki::Store
347
+
348
+ #-------------------------------------------------------------
349
+
350
+ def handle_request
351
+ Request.new( self ).handle_request
352
+ #unless (Wiki.pref("added_exit_handler"))
353
+ #
354
+ # Wiki.set_pref("added_exit_handler" => true )
355
+ #end
356
+ end
357
+
358
+ class Request # :nodoc:
359
+
360
+ attr_accessor :template, :content_template, :wiki
361
+
362
+ def initialize( wiki )
363
+ @page = @handled = false
364
+ @wiki = wiki
365
+ @template = if (File.basename(Web.script_name || '') == "admin.rb")
366
+ "admin.html"
367
+ else
368
+ "template.html"
369
+ end
370
+ end
371
+
372
+ attr_writer :page
373
+ def page
374
+ unless @page
375
+ @page = self.wiki.load_page
376
+ unless (Web["revision"] == nil || Web["revision"].empty? || Web["revision"].to_s == "0")
377
+ history = @page.history
378
+ revision = history.find{ |p|
379
+ Web["revision"].to_i == p.revision
380
+ }
381
+ revision.history = history
382
+ @page = revision || @page
383
+ end
384
+ end
385
+ @page
386
+ end
387
+
388
+ attr_writer :vars
389
+ def vars
390
+ @vars ||= {"page" => self.page,
391
+ "wiki" => self.wiki,
392
+ "action" => Web["action"],
393
+ "baseurl" => Web::Wiki::pref(:baseurl),
394
+ "resourceurl" => Web::Wiki::pref(:resourceurl),
395
+ }
396
+ end
397
+
398
+ def handle_request
399
+ cmd = Web["action"]
400
+ cmd = "default" if cmd.empty? || cmd == "view_revision"
401
+ cmd = "download_resource" if Web::path_info =~ /^\/resources\//
402
+ cmd = "default" unless Web::Wiki::pref("allowed_actions").include?(cmd)
403
+
404
+ Request.actions[cmd].call(self)
405
+
406
+
407
+ unless @handled
408
+ Web::config[:load_path] << Web::Wiki::pref("resource_dir")
409
+ self.vars["content_template"] = self.content_template
410
+ Web::local.merge!( self.vars )
411
+ Web::load( self.template ) if self.template
412
+ @handled = true
413
+ end
414
+ end
415
+
416
+ @@actions = {}
417
+ def Request.actions
418
+ @@actions
419
+ end
420
+
421
+ def Request.action( name, &action )
422
+ Action.new name, &action
423
+ end
424
+
425
+
426
+ class Action #:nodoc:
427
+ attr_accessor :name
428
+ def initialize( name, &action )
429
+ @name = name
430
+ @action = action
431
+ Request.actions[name] = self
432
+ end
433
+
434
+ def call( request )
435
+ if (self.name == "default")
436
+ request.content_template = request.page.template
437
+ else
438
+ request.content_template = self.name + ".html"
439
+ end
440
+ @action.call(request) if @action
441
+ if ( [ "illustration.html",
442
+ "images.html" ].include? request.content_template )
443
+ request.template = request.content_template
444
+ end
445
+ end
446
+ end
447
+
448
+ [ "default", "page_history", "images", "more_news" ].each{ |boring_action|
449
+ action( boring_action )
450
+ }
451
+
452
+ #action( "more_news_rss_0.91" ) {|r|
453
+ # r.template = "more_news_rss_0.91.html"
454
+ #}
455
+
456
+ action( "edit" ) { |r|
457
+ r.page.comment = "";
458
+ r.vars["options"] = {
459
+ "content_editor" => case Web::env["http_user_agent"]
460
+ when /MSIE.*Windows/
461
+ "ie-content_editor.html"
462
+ when /Mozilla.*(?!MSIE).*Windows/
463
+ "ekit-content_editor.html"
464
+ else
465
+ "default-content_editor.html"
466
+ end,
467
+ "page_types" => ["Normal", "Illustration"],
468
+ "align" => ["left", "center", "right"],
469
+ "valign" => ["top", "middle", "bottom"],
470
+ }
471
+ }
472
+
473
+ def download_file( basedir, requested_asset )
474
+ self.template = nil
475
+ self.content_template = nil
476
+
477
+ basedir = File.expand_path( basedir )
478
+ requested_asset = File.expand_path( File.join(basedir,
479
+ requested_asset.gsub( /\\/, "/") ) )
480
+ # security check on the requested_asset --
481
+ # it must be underneath the basedir
482
+ if ( requested_asset.index( basedir ) == 0 && \
483
+ File.exists?( requested_asset ) )
484
+ # deliver the file
485
+ Web.content_type = Web.get_mime_type( requested_asset )
486
+ Web.write File.open(requested_asset, "r" ) { |f|
487
+ f.read
488
+ }
489
+ Web.flush
490
+ else
491
+ Web.status = "404";
492
+ Web.write "404 File Not Found"
493
+ Web.flush
494
+ end
495
+ end
496
+
497
+ action( "download" ) { |r|
498
+ r.download_file( r.page.dir,Web["asset"] )
499
+ }
500
+
501
+ action("download_resource") { |r|
502
+ r.download_file( Wiki::pref(:resource_dir),
503
+ Web::path_info.gsub( /^\/resources/, '' ) )
504
+ }
505
+
506
+
507
+
508
+ ["select_illustration", "insert_download"].each{ |images_target|
509
+ action(images_target) { |r|
510
+ r.template = "images.html"
511
+ }
512
+ }
513
+
514
+ action( "Upload" ) { |r|
515
+ r.content_template = "images.html"
516
+ r.vars["action"] = Web["calling_action"]
517
+ Dir.mkdir r.page.dir unless (File.exists? r.page.dir)
518
+ r.wiki.move_asset( Web["upload"],
519
+ File.join( r.page.dir,
520
+ File.basename(Web["upload"] \
521
+ .original_filename \
522
+ .gsub( /\\/, "/") ) ) )
523
+ }
524
+
525
+ action( "asset_history" ) { |r|
526
+ r.vars["asset"] = { "name" => Web["asset"],
527
+ "history" => r.page.historical_assets[Web["asset"]] }
528
+ }
529
+
530
+ action( "Save" ) { |r|
531
+ # patrick's (seemed simpler at the moment)
532
+ # comment out if you want to try the
533
+ # simple dispatcher code below
534
+ r.page.set_by_request
535
+ r.wiki.save( r.page )
536
+
537
+ # redirect back to default
538
+ Web::request["action"] = ["default"]
539
+ Web::clear()
540
+ r.handle_request
541
+ }
542
+
543
+
544
+
545
+ action( "delete_asset" ) { |r|
546
+ r.content_template = "images.html"
547
+ r.vars["action"] = Web["calling_action"]
548
+ r.wiki.move_asset( File.join( r.page.dir, File.basename( Web["asset"] ) ),
549
+ File.join( r.page.dir, File.basename( "\#deleted." + Web["asset"] ) ) )
550
+ }
551
+
552
+ end
553
+
554
+ end
555
+ end
556
+
557
+ Wiki = Web::Wiki