ruby-web 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
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