Pimki 1.6.092 → 1.7.092
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.
- data/README-PIMKI +13 -4
- data/app/controllers/wiki.rb +157 -62
- data/app/models/chunks/acronym.rb +19 -0
- data/app/models/chunks/category.rb +4 -2
- data/app/models/chunks/todo.rb +0 -1
- data/app/models/chunks/wiki.rb +19 -5
- data/app/models/revision.rb +2 -0
- data/app/models/web.rb +38 -38
- data/app/models/web_test.rb +1 -1
- data/app/models/wiki_service.rb +8 -7
- data/app/models/wiki_words.rb +3 -2
- data/app/models/wiki_words_test.rb +10 -0
- data/app/views/error.rhtml +4 -2
- data/app/views/menu.rhtml +1 -5
- data/app/views/navigation.rhtml +6 -6
- data/app/views/static_style_sheet.rhtml +25 -5
- data/app/views/textile_help.rhtml +1 -1
- data/app/views/top.rhtml +59 -57
- data/app/views/wiki/adv_search.rhtml +2 -2
- data/app/views/wiki/authors.rhtml +1 -1
- data/app/views/wiki/bliki.rhtml +7 -5
- data/app/views/wiki/bliki_edit.rhtml +2 -1
- data/app/views/wiki/bliki_new.rhtml +2 -1
- data/app/views/wiki/bliki_revision.rhtml +12 -19
- data/app/views/wiki/edit.rhtml +4 -4
- data/app/views/wiki/edit_menu.rhtml +2 -1
- data/app/views/wiki/edit_web.rhtml +83 -21
- data/app/views/wiki/export.rhtml +7 -0
- data/app/views/wiki/feeds.rhtml +7 -3
- data/app/views/wiki/glossary.rhtml +27 -0
- data/app/views/wiki/list.rhtml +5 -1
- data/app/views/wiki/login.rhtml +1 -0
- data/app/views/wiki/mind.rhtml +14 -2
- data/app/views/wiki/new_system.rhtml +3 -3
- data/app/views/wiki/new_web.rhtml +5 -1
- data/app/views/wiki/page.rhtml +1 -8
- data/app/views/wiki/published.rhtml +38 -0
- data/app/views/wiki/recently_revised.rhtml +6 -0
- data/app/views/wiki/rss_feed.rhtml +46 -0
- data/app/views/wiki/test.rhtml +25 -0
- data/app/views/wiki/todo.rhtml +5 -2
- data/app/views/wiki/web_list.rhtml +5 -1
- data/libraries/secure_web_controller_server.rb +106 -0
- data/pimki.rb +11 -7
- metadata +11 -4
data/app/views/wiki/export.rhtml
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
<% @title = "Export" %><%= sub_template "top" %>
|
|
2
2
|
|
|
3
|
+
<div class='content-box'>
|
|
4
|
+
|
|
3
5
|
<p>You can export all the pages in this web as a zip file in either HTML (with working links and all) or the pure markup (to import in another wiki).</p>
|
|
4
6
|
|
|
7
|
+
<p>If tex and pdflatex tools are installed on your system, you can also export this web in TeX/PDF formats.</p>
|
|
8
|
+
|
|
9
|
+
<p>Please note that only the latest revision of each page is exported.</p>
|
|
10
|
+
|
|
5
11
|
<ul id="feedsList">
|
|
6
12
|
<li><a href="../export_html">HTML</a>
|
|
7
13
|
<li><a href="../export_markup">Markup (<%= @web.markup %>)</a>
|
|
@@ -11,4 +17,5 @@
|
|
|
11
17
|
<% end %>
|
|
12
18
|
</ul>
|
|
13
19
|
|
|
20
|
+
</div>
|
|
14
21
|
<%= sub_template "bottom" %>
|
data/app/views/wiki/feeds.rhtml
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
<% @title = "Feeds" %><%= sub_template "top" %>
|
|
2
|
-
|
|
2
|
+
<div class='content-box'>
|
|
3
3
|
<p>You can subscribe to this wiki by RSS and get either just the headlines of the pages that change or the entire page.</p>
|
|
4
4
|
|
|
5
5
|
<ul id="feedsList">
|
|
6
|
-
<li><a href="../rss_with_content<%= "?password=#{web.password}" if web.password %>">Full content
|
|
7
|
-
<li><a href="../rss_with_headlines<%= "?password=#{web.password}" if web.password %>">Headlines
|
|
6
|
+
<li><a href="../rss_with_content<%= "?password=#{web.password}" if web.password %>">Full content</a>
|
|
7
|
+
<li><a href="../rss_with_headlines<%= "?password=#{web.password}" if web.password %>">Headlines</a>
|
|
8
|
+
<li><a href="../rss_bliki_only<%= "?password=#{web.password}" if web.password %>">Bliki entries only</a>
|
|
9
|
+
<li><a href="../rss_todo_items<%= "?password=#{web.password}" if web.password %>">Todo items only (experimental!)</a>
|
|
8
10
|
</ul>
|
|
9
11
|
|
|
12
|
+
<p>All feeds are RSS in 2.0 format.</p>
|
|
13
|
+
</div>
|
|
10
14
|
<%= sub_template "bottom" %>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<%
|
|
2
|
+
@title = "#{web.name} Glossary"
|
|
3
|
+
%>
|
|
4
|
+
<%= sub_template "top" %>
|
|
5
|
+
|
|
6
|
+
<h3><%= @results.length > 0 ? @results.length : 'no' %> acronym<%= 's' unless @results.length == 1 %> found.</h3>
|
|
7
|
+
|
|
8
|
+
<p>
|
|
9
|
+
<table vorder="0">
|
|
10
|
+
<tr>
|
|
11
|
+
<td style="border-bottom: thin solid grey; font-weight:bold; font-variant:italic; padding-right:10px;">Acronym</td>
|
|
12
|
+
<td style="border-bottom: thin solid grey; font-weight:bold; font-variant:italic; padding-right:10px;">Definition</td>
|
|
13
|
+
<td style="border-bottom: thin solid grey; font-weight:bold; font-variant:italic; padding-right:10px;">Appears on</td>
|
|
14
|
+
</tr>
|
|
15
|
+
<% @results.each do |(acronym, definition), *pages| %>
|
|
16
|
+
<tr>
|
|
17
|
+
<td width="10%" valign="top"><b><%= acronym %></b></td>
|
|
18
|
+
<td width="40%" valign="top"><%= definition %></td>
|
|
19
|
+
<td width="50%"><%= pages.join(', ') %><br/>
|
|
20
|
+
<small><%= (@undefined_on[acronym] - pages[0]).join(', ') if @undefined_on[acronym] %></small>
|
|
21
|
+
</td>
|
|
22
|
+
</tr>
|
|
23
|
+
<% end %>
|
|
24
|
+
</table>
|
|
25
|
+
</div>
|
|
26
|
+
<%= sub_template "bottom" %>
|
|
27
|
+
|
data/app/views/wiki/list.rhtml
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<% @title = "All Pages" %>
|
|
2
2
|
<%= sub_template "top" %>
|
|
3
3
|
|
|
4
|
+
<!-- Categories Menu -->
|
|
4
5
|
<% unless @categories.empty? %>
|
|
5
6
|
<div id="categories">
|
|
6
7
|
<p><strong>Categories</strong>:
|
|
@@ -22,6 +23,7 @@
|
|
|
22
23
|
</div>
|
|
23
24
|
<% end %>
|
|
24
25
|
|
|
26
|
+
<!-- Main Page List -->
|
|
25
27
|
<div id="listsContainer" style="float: left; width: 300px;">
|
|
26
28
|
<% unless @pages_that_are_orphaned.empty? && @page_names_that_are_wanted.empty? %>
|
|
27
29
|
<h2>
|
|
@@ -38,6 +40,7 @@
|
|
|
38
40
|
<% end %>
|
|
39
41
|
|
|
40
42
|
|
|
43
|
+
<!-- Missing Pages -->
|
|
41
44
|
<% unless @page_names_that_are_wanted.empty? %>
|
|
42
45
|
<h2>
|
|
43
46
|
Wanted Pages
|
|
@@ -55,6 +58,7 @@
|
|
|
55
58
|
</ul>
|
|
56
59
|
<% end %>
|
|
57
60
|
|
|
61
|
+
<!-- Orphaned Pages -->
|
|
58
62
|
<% unless @pages_that_are_orphaned.empty? %>
|
|
59
63
|
<h2>
|
|
60
64
|
Orphaned Pages
|
|
@@ -66,7 +70,7 @@
|
|
|
66
70
|
</ul>
|
|
67
71
|
<% end %>
|
|
68
72
|
</div>
|
|
69
|
-
|
|
73
|
+
<!-- Page Administration -->
|
|
70
74
|
<div id="pageAdmin"style="float: right; width: 280px; vertical-align: top;">
|
|
71
75
|
<script language="JavaScript1.2">
|
|
72
76
|
function validateSelection(fieldID) {
|
data/app/views/wiki/login.rhtml
CHANGED
data/app/views/wiki/mind.rhtml
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<% @title = "Mind Map"
|
|
2
|
-
#@
|
|
2
|
+
#@hide_menu = true
|
|
3
|
+
#@style_additions = "#Container { width: 100%; } #Content { float: left; }"
|
|
3
4
|
%>
|
|
4
5
|
<%= sub_template "top" %>
|
|
5
6
|
|
|
@@ -47,12 +48,23 @@
|
|
|
47
48
|
</td>
|
|
48
49
|
</tr>
|
|
49
50
|
<tr>
|
|
50
|
-
<td
|
|
51
|
+
<td>Size: <input type="text" name="mind_map_size" id="mind_map_size" value="<%= @req.query['mind_map_size'] || web.mind_map_size %>"></td>
|
|
52
|
+
<td colspan='3' align='center'><input type="submit" value="Redraw" name="Go" onClick='return validateMMSize();'></td>
|
|
51
53
|
</tr>
|
|
52
54
|
</form>
|
|
53
55
|
</table>
|
|
54
56
|
|
|
55
57
|
<p>Graphs generated with <a href='http://www.research.att.com/sw/tools/graphviz/'>GraphViz</a>.
|
|
56
58
|
|
|
59
|
+
<script>
|
|
60
|
+
function validateMMSize() {
|
|
61
|
+
if (document.getElementById('mind_map_size').value != "" &&
|
|
62
|
+
!(/^\d+,\d+$/.test(document.getElementById('mind_map_size').value))) {
|
|
63
|
+
alert("The Mind Map size must be in the format of 'digit(s),digit(s)'!");
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
</script>
|
|
57
69
|
<%= sub_template "bottom" %>
|
|
58
70
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
<% @title = "
|
|
1
|
+
<% @title = "Pimki Setup"; @content_width = 500 %><%= sub_template "top" %>
|
|
2
2
|
|
|
3
3
|
<p>
|
|
4
|
-
Congratulations on succesfully installing and starting
|
|
5
|
-
Since this is the first time
|
|
4
|
+
Congratulations on succesfully installing and starting Pimki.
|
|
5
|
+
Since this is the first time Pimki has been run on this port, you'll need to do a brief one-time setup.
|
|
6
6
|
</p>
|
|
7
7
|
|
|
8
8
|
<form action="../create_system" id="setup" method="post" onSubmit="return validateSetup()">
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
<%
|
|
1
|
+
<%
|
|
2
|
+
@title = "New Wiki Web"
|
|
3
|
+
@hide_menu = true
|
|
4
|
+
@inline_style = true
|
|
5
|
+
%><%= sub_template "top" %>
|
|
2
6
|
|
|
3
7
|
<p>
|
|
4
8
|
Each web serves as an isolated name space for wiki pages, so different subjects or projects can write about different <i>MuppetShows</i>.
|
data/app/views/wiki/page.rhtml
CHANGED
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
<% end %>
|
|
27
27
|
</div>
|
|
28
28
|
|
|
29
|
-
<div class="navigation">
|
|
29
|
+
<div class="navigation" id='bottom-section'>
|
|
30
30
|
<a href="../edit/<%= @page.name %>" class="navlink" accesskey="E">Edit Page</a>
|
|
31
31
|
|
|
32
32
|
<% if @page.revisions.length > 1 %>
|
|
@@ -61,13 +61,6 @@
|
|
|
61
61
|
<br />| Bliki Linked from: <%= @page.bliki_references.collect { |ref| link_to_bliki(ref) }.join(", ") %>
|
|
62
62
|
</small>
|
|
63
63
|
<% end %>
|
|
64
|
-
|
|
65
|
-
<% if @page.name == "HomePage" %>
|
|
66
|
-
<br /><a href="../edit_web/" class="navlink">Edit Web</a>
|
|
67
|
-
| <%= list_item "Authors", "../authors/", "Who wrote what" %>
|
|
68
|
-
| <%= list_item "Feeds", "../feeds/", "Subscribe to changes by RSS" %>
|
|
69
|
-
| <%= list_item "Export", "../export/", "Download a zip with all the pages in this wiki", "X" %>
|
|
70
|
-
<% end %>
|
|
71
64
|
</div>
|
|
72
65
|
|
|
73
66
|
<script language="Javascript">
|
|
@@ -7,6 +7,44 @@
|
|
|
7
7
|
%>
|
|
8
8
|
<%= sub_template "top" %>
|
|
9
9
|
|
|
10
|
+
<div id="revision">
|
|
10
11
|
<%= @page.display_published %>
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
<div class="byline">
|
|
15
|
+
<%= @page.revisions? ? "Revised" : "Created" %> on <%= @page.pretty_created_at %>
|
|
16
|
+
by
|
|
17
|
+
<%= @page.author_link({ :mode => :export }) %>
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
<div class="navigation">
|
|
21
|
+
<small>
|
|
22
|
+
| Views: <a href="../print/<%= @page.name %>">Print</a>
|
|
23
|
+
<% if OPTIONS[:pdflatex] && @web.markup == :textile %>
|
|
24
|
+
| <a href="../tex/<%= @page.name %>">TeX</a> | <a href="../pdf/<%= @page.name %>">PDF</a>
|
|
25
|
+
<% end %>
|
|
26
|
+
</small>
|
|
27
|
+
|
|
28
|
+
<% if @page.references.length > 0 %>
|
|
29
|
+
<small>
|
|
30
|
+
<br />| Linked from: <%= @page.references.collect { |ref| ref.link }.join(", ").gsub('/show/', '/published/') %>
|
|
31
|
+
</small>
|
|
32
|
+
<% end %>
|
|
33
|
+
|
|
34
|
+
<!-- TODO: fix this one the Bliki has a published interface
|
|
35
|
+
<% if @page.bliki_references.length > 0 %>
|
|
36
|
+
<small>
|
|
37
|
+
<br />| Bliki Linked from: <%= @page.bliki_references.collect { |ref| link_to_bliki(ref) }.join(", ") %>
|
|
38
|
+
</small>
|
|
39
|
+
<% end %>
|
|
40
|
+
-->
|
|
41
|
+
|
|
42
|
+
<br />
|
|
43
|
+
<!-- TODO: fix this one the published interface is better for all special templates.
|
|
44
|
+
<%= list_item "Authors", "../authors/", "Who wrote what" %>
|
|
45
|
+
| <%= list_item "Feeds", "../feeds/", "Subscribe to changes by RSS" %>
|
|
46
|
+
| <%= list_item "Export", "../export/", "Download a zip with all the pages in this wiki", "X" %>
|
|
47
|
+
-->
|
|
48
|
+
</div>
|
|
11
49
|
|
|
12
50
|
<%= sub_template "bottom" %>
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
<% @title = "Recently Revised" %>
|
|
2
2
|
<%= sub_template "top" %>
|
|
3
3
|
|
|
4
|
+
<div class='content-box'>
|
|
5
|
+
|
|
4
6
|
<% unless @categories.empty? %>
|
|
5
7
|
<div id="categories">
|
|
6
8
|
<strong>Categories</strong>:
|
|
@@ -9,6 +11,9 @@
|
|
|
9
11
|
</div>
|
|
10
12
|
<% end %>
|
|
11
13
|
|
|
14
|
+
</div>
|
|
15
|
+
<div class='content-box'>
|
|
16
|
+
|
|
12
17
|
<% revision_date = Date.new(2100) %>
|
|
13
18
|
<ul>
|
|
14
19
|
<% for page in @pages_by_revision %>
|
|
@@ -28,4 +33,5 @@
|
|
|
28
33
|
<% revision_date = page.revised_on %>
|
|
29
34
|
<% end %>
|
|
30
35
|
|
|
36
|
+
</div>
|
|
31
37
|
<%= sub_template "bottom" %>
|
|
@@ -6,6 +6,51 @@
|
|
|
6
6
|
<description>Pimki - a PIM based on Instiki's wiki technology</description>
|
|
7
7
|
<language>en-us</language>
|
|
8
8
|
<ttl>40</ttl>
|
|
9
|
+
<% if @display_todo
|
|
10
|
+
FAR_FUTURE = Date.new(4000,1,1)
|
|
11
|
+
%>
|
|
12
|
+
<% @todo_items.each do |page, items| %>
|
|
13
|
+
<item>
|
|
14
|
+
<title><%= page.plain_name %></title>
|
|
15
|
+
<description>
|
|
16
|
+
<ul>
|
|
17
|
+
<% items.each do |item| %>
|
|
18
|
+
<li>
|
|
19
|
+
<small><%=
|
|
20
|
+
x = "[#{item.context.join(', ') unless item.context.empty?}#{ " - " unless item.context.empty? or item.due_date == FAR_FUTURE}#{item.due_date unless item.due_date == FAR_FUTURE }]"
|
|
21
|
+
x unless x == "[]"
|
|
22
|
+
%></small><br />
|
|
23
|
+
<span class="<%= get_todo_display_style item.due_date %>"><%= item.text.strip.gsub(/<.*?>/, '') %></span>
|
|
24
|
+
</li>
|
|
25
|
+
<% end %>
|
|
26
|
+
</ul>
|
|
27
|
+
</description>
|
|
28
|
+
<guid><%= "#{@web_url}/show/#{page.name}" %></guid>
|
|
29
|
+
<link><%= "#{@web_url}/show/#{page.name}" %></link>
|
|
30
|
+
<dc:creator><%= WikiWords.separate(page.author) %></dc:creator>
|
|
31
|
+
</item>
|
|
32
|
+
<% end %>
|
|
33
|
+
<% @bliki_todo_items.each do |page, items| %>
|
|
34
|
+
<item>
|
|
35
|
+
<title><%= page.plain_name %></title>
|
|
36
|
+
<description>
|
|
37
|
+
<ul>
|
|
38
|
+
<% items.each do |item| %>
|
|
39
|
+
<small><%=
|
|
40
|
+
x = "[#{item.context.join(', ') unless item.context.empty?}#{ " - " if not item.context.empty? or item.due_date == FAR_FUTURE}#{item.due_date unless item.due_date == FAR_FUTURE }]<br />"
|
|
41
|
+
x unless x == "[]<br />"
|
|
42
|
+
%></small>
|
|
43
|
+
<span class="<%= get_todo_display_style item.due_date %>"><%= item.text.strip.gsub(/<.*?>/, '') %></span>
|
|
44
|
+
<% end %>
|
|
45
|
+
</ul>
|
|
46
|
+
</description>
|
|
47
|
+
<pubDate><%= ctime = entry.created_at; ctime.strftime "%a, %e %b %Y %H:%M:%S #{ctime.gmt_offset/3600}" %></pubDate>
|
|
48
|
+
<guid><%= "#{@web_url}/bliki_revision/#{entry.name}?rev=#{entry.revisions.length-1}" %></guid>
|
|
49
|
+
<link><%= "#{@web_url}/bliki_revision/#{entry.name}?rev=#{entry.revisions.length-1}" %></link>
|
|
50
|
+
<dc:creator><%= WikiWords.separate(entry.author) %></dc:creator>
|
|
51
|
+
</item>
|
|
52
|
+
<% end %>
|
|
53
|
+
<% else %>
|
|
9
54
|
<% for entry in @bliki_entries %>
|
|
10
55
|
<item>
|
|
11
56
|
<title>Bliki: <%= entry.plain_name %></title>
|
|
@@ -30,5 +75,6 @@
|
|
|
30
75
|
<dc:creator><%= WikiWords.separate(page.author) %></dc:creator>
|
|
31
76
|
</item>
|
|
32
77
|
<% end %>
|
|
78
|
+
<% end %>
|
|
33
79
|
</channel>
|
|
34
80
|
</rss>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
<script>
|
|
4
|
+
function getPageName(elem) {
|
|
5
|
+
if (document.getElementById(elem).value) {
|
|
6
|
+
document.getElementById(elem).style.color = 'red;' ;
|
|
7
|
+
} else {
|
|
8
|
+
document.getElementById(elem).style.color = 'blue;' ;
|
|
9
|
+
};
|
|
10
|
+
var xmlhttp=false;
|
|
11
|
+
xmlhttp = new XMLHttpRequest();
|
|
12
|
+
|
|
13
|
+
xmlhttp.open("GET", "/pimki/show/HomePage", true);
|
|
14
|
+
xmlhttp.onreadystatechange=function() {
|
|
15
|
+
for(i=0; i< 100000;i++);
|
|
16
|
+
if (xmlhttp.readyState==4) {
|
|
17
|
+
document.getElementById(elem).style.color = 'green;' ;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
xmlhttp.send(null);
|
|
21
|
+
}
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
<input type="checkbox" id="todo" name="todo" onClick='getPageName("green");' /><span id='green'>Super green!</span>
|
|
25
|
+
|
data/app/views/wiki/todo.rhtml
CHANGED
|
@@ -4,10 +4,11 @@
|
|
|
4
4
|
num_items = @todo_items.inject(0) { |n, (p,i)| n += i.size }
|
|
5
5
|
num_items += @bliki_todo_items.inject(0) { |n, (p,i)| n += i.size }
|
|
6
6
|
%>
|
|
7
|
-
|
|
8
7
|
<h3>There <%= num_items == 1 ? 'is' : 'are' %> <%= num_items.zero? ? "no" : num_items %> ToDo item<%= num_items != 1 ? 's' : '' %>.
|
|
9
8
|
</h3>
|
|
10
9
|
|
|
10
|
+
<%= '<div class="content-box">' unless @context_links.empty? and num_items == 0 %>
|
|
11
|
+
|
|
11
12
|
<% unless @context_links.empty? %>
|
|
12
13
|
<div id="todo_contexts">
|
|
13
14
|
<strong>ToDo Contexts</strong>:
|
|
@@ -41,9 +42,11 @@
|
|
|
41
42
|
</div>
|
|
42
43
|
<% end %>
|
|
43
44
|
|
|
45
|
+
<%= '</div>' unless @context_links.empty? and num_items == 0 %>
|
|
46
|
+
|
|
44
47
|
<ul>
|
|
45
48
|
<% @todo_items.each do |page, items| %>
|
|
46
|
-
<li><%= page.link %> <%# items.length %>
|
|
49
|
+
<li class='content-box'><%= page.link %> <%# items.length %>
|
|
47
50
|
<ul>
|
|
48
51
|
<% items.each do |item| %>
|
|
49
52
|
<li>
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
require 'webrick'
|
|
2
|
+
require 'webrick/https'
|
|
3
|
+
include WEBrick
|
|
4
|
+
|
|
5
|
+
# Terminology:
|
|
6
|
+
# * Static controller: Is a controller that has all it's show_* and do_* methods mounted by the server
|
|
7
|
+
# at server start, so the server will handle request rejection of invalid requests
|
|
8
|
+
# * Dynamic controller: Is a controller that's mounted with a responsibility to handle all the request mapping
|
|
9
|
+
# itself. Hence, the server will never reject a request that's below the controller in the path.
|
|
10
|
+
class WebControllerServer
|
|
11
|
+
STATIC_MOUNTING = 1
|
|
12
|
+
DYNAMIC_MOUNTING = 2
|
|
13
|
+
|
|
14
|
+
MOUNT_TYPE = DYNAMIC_MOUNTING
|
|
15
|
+
|
|
16
|
+
SERVER_TYPE = (RUBY_PLATFORM =~ /mswin/ ? SimpleServer : Daemon)
|
|
17
|
+
|
|
18
|
+
def WebControllerServer.the_active_server
|
|
19
|
+
@the_active_server
|
|
20
|
+
end
|
|
21
|
+
def WebControllerServer.the_active_server= server
|
|
22
|
+
@the_active_server = server
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def initialize(port, server_type, controller_path)
|
|
26
|
+
# Note: This requires Ruby/OpenSSL.
|
|
27
|
+
@server = WEBrick::HTTPServer.new(
|
|
28
|
+
:Port => port,
|
|
29
|
+
:ServerType => server_type || SERVER_TYPE,
|
|
30
|
+
:SSLEnable => true,
|
|
31
|
+
:SSLVerifyClient => ::OpenSSL::SSL::VERIFY_NONE,
|
|
32
|
+
:SSLCertName => [ ["C","JP"], ["O","pimki.rubyforge.org"], ["CN", "A Pimki certificate. Only trust web-sites you know!"] ]
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
WebControllerServer::the_active_server = @server
|
|
36
|
+
@server.logger.info "Your WEBrick server is now running on http://localhost:#{port}"
|
|
37
|
+
@controller_path = controller_path
|
|
38
|
+
mount_controllers
|
|
39
|
+
start_server
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
# Mounts all the controllers in the controller_path according to the mount type
|
|
44
|
+
def mount_controllers
|
|
45
|
+
require_controller_files
|
|
46
|
+
|
|
47
|
+
case MOUNT_TYPE
|
|
48
|
+
when STATIC_MOUNTING then controller_names.each { |name| mount_static_controller(name) }
|
|
49
|
+
when DYNAMIC_MOUNTING then controller_names.each { |name| mount_dynamic_controller(name) }
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
@server.mount('/favicon.ico', FavIconHandler)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Mounts the controller specified by <tt>controller_name</tt> to accept all requests below it's path.
|
|
56
|
+
# If more than one controller is mounted by this WebControllerServer, the controller is mounted by name,
|
|
57
|
+
# such that fx WikiController would get the requests of "/wiki/something" and "/wiki/some/thing/else".
|
|
58
|
+
# If only one controller is mounted, all requests to this WebControllerServer is handled by that controller
|
|
59
|
+
def mount_dynamic_controller(controller_name)
|
|
60
|
+
mount_path = mounting_multiple_controllers? ? "/#{controller_name}" : "/"
|
|
61
|
+
@server.mount(mount_path, controller_class(controller_name))
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Mount all public show_* and do_* methods as actions tied to the controller specified by <tt>controller_name</tt>.
|
|
65
|
+
# If more than one controller is mounted by this WebControllerServer, the actions are mounted below the controller
|
|
66
|
+
# in the path, such as "/wiki/page" or "/wiki/list". If only one controller is mounted, they're mounted directly on
|
|
67
|
+
# the root, such as "/page" or "/list"
|
|
68
|
+
def mount_static_controller(controller_name)
|
|
69
|
+
controller_class(controller_name).public_instance_methods(false).each { |method|
|
|
70
|
+
mount_path = (mounting_multiple_controllers? ? "/#{controller_name}" : "") + "/#{method}"
|
|
71
|
+
@server.mount(mount_path, controller_class(controller_name))
|
|
72
|
+
}
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Requires all the controller files that are present in the controller_path
|
|
76
|
+
def require_controller_files
|
|
77
|
+
controller_names.each { |controller| require @controller_path + controller }
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Returns true if more than one controller exists in the controller_path
|
|
81
|
+
def mounting_multiple_controllers?
|
|
82
|
+
controller_names.length > 1
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Returns a list of controller names in lower-case from the controller path
|
|
86
|
+
def controller_names
|
|
87
|
+
Dir.entries(@controller_path).delete_if { |file| file !~ /rb$/ }.collect{ |c| c[0..-4] }
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Returns the class of the controller specified by the <tt>controller_name</tt>
|
|
91
|
+
def controller_class(controller_name)
|
|
92
|
+
eval(controller_name.capitalize + "Controller")
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
public
|
|
96
|
+
|
|
97
|
+
# Start accepting requests to the defined mount points
|
|
98
|
+
def start_server
|
|
99
|
+
@server.start
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Stops accepting requests to the defined mount points
|
|
103
|
+
def shutdown
|
|
104
|
+
@server.shutdown
|
|
105
|
+
end
|
|
106
|
+
end
|