Soks 0.0.7 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (109) hide show
  1. data/LICENSE.txt +2 -0
  2. data/README.txt +3 -2
  3. data/TODO.txt +31 -0
  4. data/bin/soks-create-wiki.rb +0 -1
  5. data/lib/authenticators.rb +30 -4
  6. data/lib/helpers/counter-helpers.rb +132 -0
  7. data/lib/helpers/default-helpers.rb +170 -169
  8. data/lib/helpers/mail2wiki-helper.rb +18 -22
  9. data/lib/helpers/maintenance-helpers.rb +149 -0
  10. data/lib/helpers/rss2wiki-helper.rb +7 -8
  11. data/lib/soks-model.rb +82 -54
  12. data/lib/soks-servlet.rb +126 -108
  13. data/lib/soks-storage.rb +74 -11
  14. data/lib/soks-utils.rb +77 -3
  15. data/lib/soks-view.rb +169 -103
  16. data/lib/soks.rb +5 -23
  17. data/templates/default/attachment/newpage.js +4 -13
  18. data/templates/default/attachment/print_stylesheet.css +2 -7
  19. data/templates/default/caches/readme.txt +1 -0
  20. data/templates/default/content/Api%20for%20classes%20to%20modify%20the%20wiki.textile +2 -0
  21. data/templates/default/content/Author.textile +4 -1
  22. data/templates/default/content/Automatic%20Summaries.textile +16 -53
  23. data/templates/default/content/Automatic%20linking%20between%20pages.textile +3 -3
  24. data/templates/default/content/{bug%3A%20competing%20edits.textile → Bug%3A%20Competing%20edits.textile} +9 -0
  25. data/templates/default/content/Bug%3A%20Does%20not%20make%20use%20of%20if%2Dmodified%2Dsince%20r.textile +2 -0
  26. data/templates/default/content/Bug%3A%20E%2Dmail%20addresses%20with%20hyphens%20not%20recognised.textile +17 -0
  27. data/templates/default/content/Bug%3A%20Email%20adresses%20in%20page%20titles%20cause%20incorrec.textile +3 -0
  28. data/templates/default/content/Bug%3A%20GEM%20limits%20title%20lengths.textile +3 -1
  29. data/templates/default/content/Bug%3A%20Memory%20leak.textile +13 -0
  30. data/templates/default/content/Bug%3A%20Pages%20that%20link%20here%20may%20not%20appear%20on%20r.textile +13 -0
  31. data/templates/default/content/Bug%3A%20Textile%20mishandles%20paragraphs.textile +4 -0
  32. data/templates/default/content/Bug%3A%20Unanticipated%20Rollbacks.textile +2 -0
  33. data/templates/default/content/Bug%3A%20notextile%20does%20not%20prevent%20page%20inserts.textile +2 -0
  34. data/templates/default/content/Home%20Page.textile +3 -1
  35. data/templates/default/content/How%20to%20administrate%20this%20wiki.textile +23 -13
  36. data/templates/default/content/How%20to%20change%20the%20way%20this%20wiki%20looks.textile +3 -1
  37. data/templates/default/content/How%20to%20export%20a%20site%20from%20this%20wiki.textile +22 -0
  38. data/templates/default/content/How%20to%20get%20the%20latest%20Soks%20from%20cvs.textile +2 -0
  39. data/templates/default/content/How%20to%20hack%20soks.textile +2 -0
  40. data/templates/default/content/How%20to%20import%20a%20site%20from%20instiki.textile +2 -0
  41. data/templates/default/content/{How%20to%20import%20data%20to%20this%20wiki.textile → How%20to%20import%20data.textile} +3 -7
  42. data/templates/default/content/How%20to%20install%20Soks.textile +2 -0
  43. data/templates/default/content/How%20to%20password%20protect%20your%20wiki.textile +21 -11
  44. data/templates/default/content/How%20to%20report%20a%20bug.textile +2 -1
  45. data/templates/default/content/How%20to%20upgrade%20soks.textile +22 -0
  46. data/templates/default/content/How%20to%20use%20the%20keyboard%20shortcuts.textile +2 -2
  47. data/templates/default/content/How%20to%20use%20this%20wiki.textile +3 -1
  48. data/templates/default/content/List%20of%20changes.textile +84 -118
  49. data/templates/default/content/News%3A%20Version%201%2D0%2D0%20released.textile +19 -0
  50. data/templates/default/content/Pages%20to%20include%20in%20the%20distribution.textile +51 -0
  51. data/templates/default/content/Per%20Wiki%20Templates.textile +2 -0
  52. data/templates/default/content/Planned%20Features.textile +30 -9
  53. data/templates/default/content/README.textile +3 -2
  54. data/templates/default/content/RSS%20feed.textile +1 -1
  55. data/templates/default/content/Recent%20changes%20to%20this%20site.textile +283 -0
  56. data/templates/default/content/SOKS%20features.textile +3 -0
  57. data/templates/default/content/Site%20Index.textile +202 -0
  58. data/templates/default/content/Soks%20Licence.textile +2 -0
  59. data/templates/default/content/Tag%3A%20Include%20this%20page%20in%20the%20distribution.textile +6 -0
  60. data/templates/default/start.rb +67 -123
  61. data/templates/default/version.txt +1 -1
  62. data/templates/default/views/Page_edit.rhtml +7 -7
  63. data/templates/default/views/{Page_search_results.rhtml → Page_find.rhtml} +9 -3
  64. data/templates/default/views/Page_linksfromrss.rhtml +24 -0
  65. data/templates/default/views/Page_listrss.rhtml +46 -0
  66. data/templates/default/views/Page_meta.rhtml +1 -1
  67. data/templates/default/views/Page_revision.rhtml +39 -0
  68. data/templates/default/views/Page_revisions.rhtml +13 -5
  69. data/templates/default/views/Page_rss.rhtml +8 -8
  70. data/templates/default/views/Page_view.rhtml +3 -3
  71. data/templates/default/views/UploadPage_edit.rhtml +8 -8
  72. data/templates/default/views/frame.rhtml +8 -8
  73. data/templates/default/views/messages.yaml +1 -0
  74. data/test/html/2006Mar.html +66 -0
  75. data/test/html/poignant.html +36 -0
  76. data/test/html/poignant.textile +36 -0
  77. data/test/mock-objects.rb +69 -0
  78. data/test/stress_url_calls.rb +33 -0
  79. data/test/stress_urls.txt +68 -0
  80. data/test/test_counter-helper.rb +158 -0
  81. data/test/test_soks-helper-maintenance.rb +106 -0
  82. data/test/test_soks-helpers.rb +104 -0
  83. data/test/test_soks-model.rb +144 -0
  84. data/test/test_soks-servlet.rb +231 -0
  85. data/test/test_soks-storage.rb +70 -31
  86. data/test/test_soks-utils.rb +112 -13
  87. data/test/test_soks-view.rb +141 -3
  88. metadata +38 -27
  89. data/templates/default/content/A%20page%20with%20an%20umlaut%20%F6%20in%20its%20title.textile +0 -1
  90. data/templates/default/content/All%20News.textile +0 -26
  91. data/templates/default/content/Bil%20Kleb.textile +0 -1
  92. data/templates/default/content/Bil.textile +0 -1
  93. data/templates/default/content/Bill%20Wood.textile +0 -3
  94. data/templates/default/content/Bug%3A%20RSS%20feed%20does%20not%20validate.textile +0 -10
  95. data/templates/default/content/Bug%3A%20Type%20a%20title%20here.textile +0 -31
  96. data/templates/default/content/Instructions%20and%20Howtos.textile +0 -21
  97. data/templates/default/content/Latest%20News.textile +0 -26
  98. data/templates/default/content/New%20Recent%20Changes%20class.textile +0 -68
  99. data/templates/default/content/New%20page%20templates%20or%20categories%20code.textile +0 -68
  100. data/templates/default/content/News%3A%20Version%200%2E0%2E6%20Released.textile +0 -13
  101. data/templates/default/content/Recent%20Blog%20Entries.textile +0 -5
  102. data/templates/default/content/Recent%20Changes%20to%20This%20Site.textile +0 -286
  103. data/templates/default/content/Ruby.textile +0 -9
  104. data/templates/default/content/Skorgu.textile +0 -3
  105. data/templates/default/content/ctrl%2Dn.textile +0 -1
  106. data/templates/default/content/let%20me%20know.textile +0 -1
  107. data/templates/default/content/sandbox.textile +0 -20
  108. data/templates/default/content/tamc.textile +0 -1
  109. data/templates/default/content/tamc2.textile +0 -1
@@ -5,17 +5,17 @@ RSS::Maker.make("2.0") do |maker|
5
5
 
6
6
  maker.encoding = 'iso-8859-1'
7
7
 
8
- maker.channel.title = "#{$SETTINGS[:name]} #{pagename}"
9
- maker.channel.description = $SETTINGS[:description]
10
- maker.channel.link = $SETTINGS[:url]
8
+ maker.channel.title = "#{name} #{page.name}"
9
+ maker.channel.description = description
10
+ maker.channel.link = root_url
11
11
 
12
- maker.image.title = "#{$SETTINGS[:name]}"
13
- maker.image.url = "#{$SETTINGS[:url]}/attachment/logo.png"
12
+ maker.image.title = name
13
+ maker.image.url = file "logo.png"
14
14
 
15
15
  maker.textinput.title = "Search"
16
- maker.textinput.description = "Search #{$SETTINGS[:name]}'s text"
16
+ maker.textinput.description = "Search #{name}'s text"
17
17
  maker.textinput.name = "regex"
18
- maker.textinput.link = "#{$SETTINGS[:url]}/find/searchpage"
18
+ maker.textinput.link = url('searchpage','find')
19
19
 
20
20
  maker.items.do_sort = true
21
21
 
@@ -23,7 +23,7 @@ RSS::Maker.make("2.0") do |maker|
23
23
  page.revisions.reverse_each do |revision|
24
24
  break if (count +=1) == 15
25
25
  item = maker.items.new_item
26
- item.link = "#{$SETTINGS[:url]}/#{pagename}"
26
+ item.link = url(page.name)
27
27
  # Get the first change that makes an addition and use as the title
28
28
  title = nil
29
29
  revision.changes.each do |group|
@@ -1,8 +1,8 @@
1
- <span class='pagename'><a href='<%= url pagename, "meta" %>'><%= pagename %></a> <%= page.deleted? ? "(Deleted)" : '' %></span>
1
+ <span class='pagename'><a href='<%= url page.name, "meta" %>'><%= pagename %></a> <%= page.deleted? ? "(Deleted)" : '' %></span>
2
2
 
3
3
  <%= renderedview %>
4
4
 
5
5
  <div class='command'>
6
- <a href='<%= url pagename, "edit" %>' accesskey="E" >Edit this page</a> or
7
- watch for changes using <a href='<%= url pagename, 'rss' %>'>RSS</a>.
6
+ <a href='<%= url page.name, "edit" %>' accesskey="E" >Edit this page</a> or
7
+ watch for changes using <a href='<%= url page.name, 'rss' %>'>RSS</a>.
8
8
  </div>
@@ -1,5 +1,5 @@
1
1
  <span class='pagename'>
2
- <a href='<%= url pagename, "meta" %>'><%= pagename %></a>
2
+ <a href='<%= url page.name, "meta" %>'><%= page.name %></a>
3
3
  <%= page.deleted? ? "(Deleted)" : '' %>
4
4
  </span>
5
5
 
@@ -10,15 +10,15 @@
10
10
  <p>You can put add a link to the file from another page in the wiki by typing its title (e.g. "attached claim form"). To make a picture appear as part of another page write [[ insert picture name ]] (e.g. [[insert picture of a beautiful balloon]]).</p>
11
11
  </div>
12
12
 
13
- <form class='editpage' action='<%= url pagename, "upload" %>' method='post' enctype='multipart/form-data' >
13
+ <form class='editpage' action='<%= url page.name, "upload" %>' method='post' enctype='multipart/form-data' >
14
14
  <div id='fileedittitle'>
15
15
  Title:
16
16
  <% if page.is_a? ImagePage %>
17
17
  <input type=hidden name='titleprefix' value='Picture of ' />
18
- Picture of <input name='newtitle' size = '51' value='<%= pagename[ 10..-1].strip %>'
18
+ Picture of <input name='newtitle' size = '51' value='<%= page.name[ 10..-1].strip %>'
19
19
  <% else %>
20
20
  <input type=hidden name='titleprefix' value='Attached ' />
21
- Attached <input name='newtitle' size = '52' value='<%= pagename[ 9..-1].strip %>'
21
+ Attached <input name='newtitle' size = '52' value='<%= page.name[ 9..-1].strip %>'
22
22
  <% end %>
23
23
  onBlur="validateTitle( this.value );" onClick="this.value=this.value.replace('Type a title here','')" />
24
24
  </div>
@@ -29,10 +29,10 @@
29
29
 
30
30
  Hello <a href='<%= url person %>'><%= person %></a> (Quit browser to log out). Would you like to
31
31
  <input name='action' value='Save Changes' type='submit' accesskey="S" /></form>,
32
- <form class='editpage' method='post' action='<%= url pagename %>' >
32
+ <form class='editpage' method='post' action='<%= url page.name %>' >
33
33
  <input name='action' value='Cancel Changes' type=submit accesskey="C" />
34
34
  </form> or
35
- <form class='editpage' method='post' action='<%= url pagename, 'delete' %>' >
35
+ <form class='editpage' method='post' action='<%= url page.name, 'delete' %>' >
36
36
  <input name='action' value='Delete this Page' type='submit' accesskey="D" />
37
37
  </form>?
38
38
 
@@ -55,9 +55,9 @@
55
55
  %>
56
56
  </div>
57
57
  <p>
58
- <form class='editpage' method=post action='<%= url pagename, "rollback" %>' >
58
+ <form class='editpage' method=post action='<%= url page.name, "rollback" %>' >
59
59
  <input name='revision' value='<%= page.number-1 %>' type='hidden' />
60
60
  <input name='action' value='Undo this change' type='submit' accesskey="U" />
61
- </form> or <a href='<%= url pagename, "revisions" %>' accesskey="A" >Show <b>A</b>ll changes</a>.
61
+ </form> or <a href='<%= url page.name, "revisions" %>' accesskey="A" >Show <b>A</b>ll changes</a>.
62
62
  </p>
63
63
  <% end %>
@@ -1,15 +1,15 @@
1
1
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2
2
  <html>
3
3
  <head>
4
- <title><%= pagename %></title>
5
- <meta name='description' content='<%= $SETTINGS[:description] %>' />
6
- <meta name='keywords' content='Soks, <%= $SETTINGS[:name] %>' />
4
+ <title><%= page.name %></title>
5
+ <meta name='description' content='<%= description %>' />
6
+ <meta name='keywords' content='Soks, <%= name %>' />
7
7
  <link href='<%= file 'stylesheet.css' %>' rel='stylesheet' type='text/css' media='screen' />
8
8
  <link href='<%= file 'print_stylesheet.css' %>' rel='stylesheet' type='text/css' media='print' />
9
- <link rel='alternate' type='application/rss+xml' title='RSS' href='<%= url pagename, 'rss' %>' />
9
+ <link rel='alternate' type='application/rss+xml' title='RSS' href='<%= url page.name, 'rss' %>' />
10
10
  <script src='<%= file 'newpage.js' %>' type='text/javascript'></script>
11
11
  </head>
12
- <body onkeypress='hotkey(event);'>
12
+ <body onkeypress='hotkey(event,"<%= root_url %>/edit/");'>
13
13
 
14
14
  <div id='content'>
15
15
  <%= content_of_page %>
@@ -18,15 +18,15 @@
18
18
  <div id='menu'>
19
19
 
20
20
  <h1><%= @wikiname %></h1>
21
- <a href='<%= url $SETTINGS[:home_page] %>' accesskey='H' >
21
+ <a href='<%= url 'Home Page' %>' accesskey='H' >
22
22
  <img width='149' src='<%= file 'logo.jpg' %>' alt='<%= @wikiname %>' />
23
23
  </a>
24
24
 
25
25
  <h2>Search</h2>
26
- <form method='get' action='<%= url pagename, 'find' %>' >
26
+ <form method='get' action='<%= url page.name, 'find' %>' >
27
27
  <input class='search'
28
28
  name='regex'
29
- value='Enter word & press return'
29
+ value='<%= query['regex'] || "Enter word & press return" %>'
30
30
  onfocus="this.value=this.value.replace('Enter word & press return','')"
31
31
  size='17' />
32
32
  </form>
@@ -1,4 +1,5 @@
1
1
  :some_content_has_been_deleted : "Some content has been deleted"
2
+ :Type_a_title_here : "Type a title here"
2
3
  :Type_what_you_want_here_and_click_save : "Type what you want here and click save"
3
4
  :Create : "Create"
4
5
  :page_deleted : "page deleted"
@@ -0,0 +1,66 @@
1
+ <div class='calendar'>
2
+
3
+ <table>
4
+ <tr>
5
+ <th>Su </th>
6
+ <th>Mo </th>
7
+ <th>Tu </th>
8
+ <th>We </th>
9
+ <th>Th </th>
10
+ <th>Fr </th>
11
+ <th>Sa </th>
12
+ </tr>
13
+ <tr>
14
+ <td> . </td>
15
+ <td> . </td>
16
+ <td> . </td>
17
+ <td> <a href='http://testsite.com/view/2006Mar01' class='missing'>1</a> </td>
18
+ <td> <a href='http://testsite.com/view/2006Mar02' class='missing'>2</a> </td>
19
+ <td> <a href='http://testsite.com/view/2006Mar03' class='missing'>3</a> </td>
20
+ <td> <a href='http://testsite.com/view/2006Mar04' class='missing'>4</a> </td>
21
+ </tr>
22
+ <tr>
23
+ <td> <a href='http://testsite.com/view/2006Mar05' class='missing'>5</a> </td>
24
+ <td> <a href='http://testsite.com/view/2006Mar06' class='missing'>6</a> </td>
25
+ <td> <a href='http://testsite.com/view/2006Mar07' class='missing'>7</a> </td>
26
+ <td> <a href='http://testsite.com/view/2006Mar08' class='missing'>8</a> </td>
27
+ <td> <a href='http://testsite.com/view/2006Mar09' class='missing'>9</a> </td>
28
+ <td> <a href='http://testsite.com/view/2006Mar10' class='missing'>10</a> </td>
29
+ <td> <a href='http://testsite.com/view/2006Mar11' class='missing'>11</a> </td>
30
+ </tr>
31
+ <tr>
32
+ <td> <a href='http://testsite.com/view/2006Mar12' class='missing'>12</a> </td>
33
+ <td> <a href='http://testsite.com/view/2006Mar13' class='missing'>13</a> </td>
34
+ <td> <a href='http://testsite.com/view/2006Mar14' class='missing'>14</a> </td>
35
+ <td> <a href='http://testsite.com/view/2006Mar15' class='missing'>15</a> </td>
36
+ <td> <a href='http://testsite.com/view/2006Mar16' class='missing'>16</a> </td>
37
+ <td> <a href='http://testsite.com/view/2006Mar17' class='missing'>17</a> </td>
38
+ <td> <a href='http://testsite.com/view/2006Mar18' class='missing'>18</a> </td>
39
+ </tr>
40
+ <tr>
41
+ <td> <a href='http://testsite.com/view/2006Mar19' class='missing'>19</a> </td>
42
+ <td> <a href='http://testsite.com/view/2006Mar20' class='missing'>20</a> </td>
43
+ <td> <a href='http://testsite.com/view/2006Mar21' class='missing'>21</a> </td>
44
+ <td> <a href='http://testsite.com/view/2006Mar22' class='missing'>22</a> </td>
45
+ <td> <a href='http://testsite.com/view/2006Mar23' class='missing'>23</a> </td>
46
+ <td> <a href='http://testsite.com/view/2006Mar24' class='missing'>24</a> </td>
47
+ <td> <a href='http://testsite.com/view/2006Mar25' class='missing'>25</a> </td>
48
+ </tr>
49
+ <tr>
50
+ <td> <a href='http://testsite.com/view/2006Mar26' class='missing'>26</a> </td>
51
+ <td> <a href='http://testsite.com/view/2006Mar27' class='missing'>27</a> </td>
52
+ <td> <a href='http://testsite.com/view/2006Mar28' class='missing'>28</a> </td>
53
+ <td> <a href='http://testsite.com/view/2006Mar29' class='missing'>29</a> </td>
54
+ <td> <a href='http://testsite.com/view/2006Mar30' class='missing'>30</a> </td>
55
+ <td> <a href='http://testsite.com/view/2006Mar31' class='missing'>31</a> </td>
56
+ <td> . </td>
57
+ </tr>
58
+ </table>
59
+
60
+
61
+
62
+
63
+ <p><a href='http://testsite.com/view/2006Feb' class='automatic'>2006 Feb</a> <a href='http://testsite.com/view/2006Apr' class='automatic'>2006 Apr</a></p>
64
+
65
+
66
+ </div>
@@ -0,0 +1,36 @@
1
+ <h3>False</h3>
2
+
3
+ <p style="float:left"><img src="i/blix-neg.gif" title="Shape of a cat." alt="Shape of a cat." /></p>
4
+
5
+ <p><em>The cat Trady Blix. Frozen in emptiness. Immaculate whiskers rigid. Placid eyes of lake. Tail of warm icicle. Sponsored by a Very Powerful Pause Button.</em></p>
6
+
7
+ <p>The darkness surrounding Blix can be called <strong>negative space</strong>. Hang on to that phrase. Let it suggest that the emptiness has a negative connotation. In a similar way, <code>nil</code> has a slightly sour note that it whistles.</p>
8
+
9
+ <p>Generally speaking, everything in Ruby has a positive charge to it. This spark flows through strings, numbers, regexps, all of it. Only two keywords wear a shady cloak: <code>nil</code> and <code>false</code> draggin us down.</p>
10
+
11
+ <p>You can test that charge with an <code>if</code> keyword. It looks very much like the <code>do</code> blocks we saw in the last chapter, in that both end with an <code>end</code>.</p>
12
+
13
+
14
+ <pre>
15
+ if plastic_cup
16
+ print "Plastic cup is on the up 'n' up!"
17
+ end
18
+ </pre>
19
+ <p>If <code>plastic_cup</code> contains either <code>nil</code> or <code>false</code>, you won&#8217;t see anything print to the screen. They&#8217;re not on the <code>if</code> guest list. So <code>if</code> isn&#8217;t going to run any of the code it&#8217;s protecting.</p>
20
+
21
+ <p>But <code>nil</code> and <code>false</code> need not walk away in shame. They may be of questionable character, but <code>unless</code> runs a smaller establishment that caters to the bedraggled. The <code>unless</code> keyword has a policy of only allowing those with a negative charge in. Who are: <code>nil</code> and <code>false</code>.</p>
22
+
23
+
24
+ <pre>
25
+ unless plastic_cup
26
+ print "Plastic cup is on the down low."
27
+ end
28
+ </pre>
29
+ <p>You can also use <code>if</code> and <code>unless</code> at the end of a single line of code, if that&#8217;s all that is being protected.</p>
30
+
31
+
32
+ <pre>
33
+ print "Yeah, plastic cup is up again!" if plastic_cup
34
+ print "Hardly. It's down." unless plastic_cup
35
+ </pre>
36
+ <p>Now that you&#8217;ve met <code>false</code>, I&#8217;m sure you can see what&#8217;s on next.</p>
@@ -0,0 +1,36 @@
1
+ h3. False
2
+
3
+ !<i/blix-neg.gif(Shape of a cat.)!
4
+
5
+ _The cat Trady Blix. Frozen in emptiness. Immaculate whiskers rigid. Placid eyes of lake. Tail of warm icicle. Sponsored by a Very Powerful Pause Button._
6
+
7
+ The darkness surrounding Blix can be called *negative space*. Hang on to that phrase. Let it suggest that the emptiness has a negative connotation. In a similar way, @nil@ has a slightly sour note that it whistles.
8
+
9
+ Generally speaking, everything in Ruby has a positive charge to it. This spark flows through strings, numbers, regexps, all of it. Only two keywords wear a shady cloak: @nil@ and @false@ draggin us down.
10
+
11
+ You can test that charge with an @if@ keyword. It looks very much like the @do@ blocks we saw in the last chapter, in that both end with an @end@.
12
+
13
+ <pre>
14
+ if plastic_cup
15
+ print "Plastic cup is on the up 'n' up!"
16
+ end
17
+ </pre>
18
+
19
+ If @plastic_cup@ contains either @nil@ or @false@, you won't see anything print to the screen. They're not on the @if@ guest list. So @if@ isn't going to run any of the code it's protecting.
20
+
21
+ But @nil@ and @false@ need not walk away in shame. They may be of questionable character, but @unless@ runs a smaller establishment that caters to the bedraggled. The @unless@ keyword has a policy of only allowing those with a negative charge in. Who are: @nil@ and @false@.
22
+
23
+ <pre>
24
+ unless plastic_cup
25
+ print "Plastic cup is on the down low."
26
+ end
27
+ </pre>
28
+
29
+ You can also use @if@ and @unless@ at the end of a single line of code, if that's all that is being protected.
30
+
31
+ <pre>
32
+ print "Yeah, plastic cup is up again!" if plastic_cup
33
+ print "Hardly. It's down." unless plastic_cup
34
+ </pre>
35
+
36
+ Now that you've met @false@, I'm sure you can see what's on next.
@@ -0,0 +1,69 @@
1
+ $:.unshift( "contrib" )
2
+
3
+ require 'yaml'
4
+ $MESSAGES = YAML.load( IO.readlines("templates/default/views/messages.yaml").join )
5
+
6
+ require 'logger'
7
+ $LOG = Logger.new(STDOUT)
8
+ $LOG.level = Logger::WARN
9
+
10
+ begin
11
+ require 'rubygems'
12
+ require_gem 'ruby-breakpoint'
13
+ rescue LoadError
14
+ $LOG.info "Breakpoint library not found. Shouldn't matter"
15
+ end
16
+
17
+ require 'fileutils'
18
+ require 'soks'
19
+
20
+ class MockWikiStore
21
+ include WikiFlatFileStore
22
+
23
+ def initialize( folder )
24
+ @folder = folder
25
+ @pages = {}
26
+ end
27
+
28
+ def mutate( pagename )
29
+ p yield( @pages[pagename.downcase] ||= Page.new( pagename ) )
30
+ end
31
+ end
32
+
33
+ module TearDownableWiki
34
+ include FileUtils
35
+
36
+ def setup
37
+ @wiki = Wiki.new( folder )
38
+ @view = View.new( @wiki, 'http://testsite.com','testcontent/views' )
39
+ end
40
+
41
+ def teardown
42
+ rmtree( folder )
43
+ end
44
+
45
+ private
46
+
47
+ def create_file( name, content )
48
+ File.open( File.join( folder, name ), 'w') { |f| f.puts content }
49
+ end
50
+
51
+ def files
52
+ Dir.entries( folder ).delete_if { |name| name =~ /^(\.+|attachment|views)$/ }.sort
53
+ end
54
+
55
+ def folder
56
+ @folder ||= make_folder
57
+ end
58
+
59
+ def make_folder
60
+ mkdir( 'testcontent' )
61
+ mkdir('testcontent/attachment')
62
+ File.symlink(File.join(Dir.getwd,'templates/default/views'),'testcontent/views')
63
+ 'testcontent'
64
+ end
65
+
66
+ def wait_for_queue_to_empty
67
+ sleep(0.1) until @wiki.event_queue.empty?
68
+ end
69
+ end
@@ -0,0 +1,33 @@
1
+ require 'open-uri'
2
+ urls = IO.readlines(ARGV[0])
3
+ end_time = Time.now + (ARGV[1] || 60).to_i
4
+ threads = (ARGV[2] || 10).to_i
5
+ sleep_time = 0.1
6
+
7
+ def time
8
+ start = Time.now
9
+ yield
10
+ Time.now - start
11
+ end
12
+
13
+ threads.times do |i|
14
+ Thread.new(i) do |i|
15
+ total_elapsed = 0.0
16
+ count = 0
17
+ while Time.now < end_time
18
+ url = urls[rand(urls.size)]
19
+ elapsed = time do
20
+ open( url ) do |f|
21
+ f.each_line {|line| } # ignore contents
22
+ end
23
+ end
24
+ total_elapsed += elapsed
25
+ count += 1
26
+ p "#{i}: #{elapsed}"
27
+ sleep sleep_time
28
+ end
29
+ p "#{i}: Average #{1.0/(total_elapsed/count)} req/s"
30
+ end
31
+ end
32
+
33
+ sleep( (end_time - Time.now)+5 )
@@ -0,0 +1,68 @@
1
+ http://localhost:8000/view/2005%20Aug
2
+ http://localhost:8000/view/2005%20Dec
3
+ http://localhost:8000/view/2005%20Jul
4
+ http://localhost:8000/view/2005%20Jun
5
+ http://localhost:8000/view/2005%20May
6
+ http://localhost:8000/view/2005%20Nov
7
+ http://localhost:8000/view/2005%20Oct
8
+ http://localhost:8000/view/2005%20Sep
9
+ http://localhost:8000/view/2006%20Apr
10
+ http://localhost:8000/view/2006%20Feb
11
+ http://localhost:8000/view/2006%20Jan
12
+ http://localhost:8000/view/2006%20Mar
13
+ http://localhost:8000/view/2006%20May
14
+ http://localhost:8000/view/Picture%20of%20a%20pair%20of%20soks
15
+ http://localhost:8000/view/All%20News
16
+ http://localhost:8000/view/Api%20for%20classes%20to%20modify%20the%20wiki
17
+ http://localhost:8000/view/Author
18
+ http://localhost:8000/view/Automatic%20linking%20between%20pages
19
+ http://localhost:8000/view/Automatic%20Summaries
20
+ http://localhost:8000/view/Bil
21
+ http://localhost:8000/view/Bil%20Kleb
22
+ http://localhost:8000/view/Bill%20Wood
23
+ http://localhost:8000/view/bug:%20competing%20edits
24
+ http://localhost:8000/view/Bug:%20Does%20not%20make%20use%20of%20if-modified-since%20r
25
+ http://localhost:8000/view/Bug:%20GEM%20limits%20title%20lengths
26
+ http://localhost:8000/view/Bug:%20notextile%20does%20not%20prevent%20page%20inserts
27
+ http://localhost:8000/view/Bug:%20RSS%20feed%20does%20not%20validate
28
+ http://localhost:8000/view/Bug:%20Textile%20mishandles%20paragraphs
29
+ http://localhost:8000/view/Bug:%20Type%20a%20title%20here
30
+ http://localhost:8000/view/Bug:%20Unanticipated%20Rollbacks
31
+ http://localhost:8000/view/ctrl-n
32
+ http://localhost:8000/view/Home%20Page
33
+ http://localhost:8000/view/How%20to%20administrate%20this%20wiki
34
+ http://localhost:8000/view/How%20to%20change%20the%20way%20this%20wiki%20looks
35
+ http://localhost:8000/view/How%20to%20export%20a%20site%20from%20this%20wiki
36
+ http://localhost:8000/view/How%20to%20get%20the%20latest%20Soks%20from%20cvs
37
+ http://localhost:8000/view/How%20to%20hack%20soks
38
+ http://localhost:8000/view/How%20to%20import%20a%20site%20from%20instiki
39
+ http://localhost:8000/view/How%20to%20import%20data%20to%20this%20wiki
40
+ http://localhost:8000/view/How%20to%20install%20Soks
41
+ http://localhost:8000/view/How%20to%20password%20protect%20your%20wiki
42
+ http://localhost:8000/view/How%20to%20report%20a%20bug
43
+ http://localhost:8000/view/How%20to%20use%20the%20keyboard%20shortcuts
44
+ http://localhost:8000/view/How%20to%20use%20this%20wiki
45
+ http://localhost:8000/view/Instructions%20and%20Howtos
46
+ http://localhost:8000/view/Known%20bugs
47
+ http://localhost:8000/view/Latest%20News
48
+ http://localhost:8000/view/let%20me%20know
49
+ http://localhost:8000/view/List%20of%20changes
50
+ http://localhost:8000/view/New%20page%20templates%20or%20categories%20code
51
+ http://localhost:8000/view/New%20Recent%20Changes%20class
52
+ http://localhost:8000/view/News:%20Version%200.0.6%20Released
53
+ http://localhost:8000/view/Per%20Wiki%20Templates
54
+ http://localhost:8000/view/Planned%20Features
55
+ http://localhost:8000/view/Popular%20Pages
56
+ http://localhost:8000/view/Prolific%20Viewers
57
+ http://localhost:8000/view/README
58
+ http://localhost:8000/view/Recent%20Blog%20Entries
59
+ http://localhost:8000/view/Recent%20changes%20to%20this%20site
60
+ http://localhost:8000/view/RSS%20feed
61
+ http://localhost:8000/view/Ruby
62
+ http://localhost:8000/view/sandbox
63
+ http://localhost:8000/view/Sidebar%20Page
64
+ http://localhost:8000/view/Skorgu
65
+ http://localhost:8000/view/SOKS%20features
66
+ http://localhost:8000/view/Soks%20Licence
67
+ http://localhost:8000/view/tamc
68
+ http://localhost:8000/view/tamc2