olelo 0.9.10 → 0.9.11
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.creole +34 -0
- data/config.ru +2 -2
- data/config/config.yml.default +8 -7
- data/lib/olelo/helper.rb +5 -6
- data/lib/olelo/util.rb +0 -18
- data/lib/olelo/version.rb +1 -1
- data/olelo.gemspec +1 -0
- data/plugins/aspects/feed.rb +1 -1
- data/plugins/aspects/main.rb +4 -4
- data/plugins/blog/main.rb +1 -1
- data/plugins/filters/fix_image_links.rb +1 -1
- data/plugins/history/main.rb +1 -1
- data/plugins/misc/variables.rb +1 -1
- data/plugins/utils/cache.rb +14 -2
- data/test/request_test.rb +3 -3
- data/test/util_test.rb +0 -4
- metadata +117 -32
- data/plugins/utils/store.rb +0 -336
data/README.creole
CHANGED
|
@@ -92,6 +92,39 @@ export OLELO_CONFIG=/home/olelo/olelo_config.yml
|
|
|
92
92
|
|
|
93
93
|
You can also use the '$OLELO_CONFIG' environment variable if you want to run multiple Ōlelo instances with different configurations, for example to serve different pages from different repositories.
|
|
94
94
|
|
|
95
|
+
== Setting up a private wiki using Apache
|
|
96
|
+
|
|
97
|
+
Assuming the wiki server is running on localhost:5000 (e.g. unicorn), we can redirect Apache requests by adding the following
|
|
98
|
+
lines to your virtual host. This works also with https.
|
|
99
|
+
|
|
100
|
+
{{{
|
|
101
|
+
# Private wiki
|
|
102
|
+
ProxyPass /wiki http://localhost:5000
|
|
103
|
+
ProxyPassReverse /wiki http://localhost:5000
|
|
104
|
+
ProxyPreserveHost On
|
|
105
|
+
ProxyRequests Off
|
|
106
|
+
RequestHeader set X-Forwarded-Proto https
|
|
107
|
+
<Proxy *>
|
|
108
|
+
Order deny,allow
|
|
109
|
+
Allow from all
|
|
110
|
+
</Proxy>
|
|
111
|
+
}}}
|
|
112
|
+
|
|
113
|
+
In your Ōlelo 'config.yml' you should set the following options:
|
|
114
|
+
|
|
115
|
+
{{{
|
|
116
|
+
base_path: '/wiki'
|
|
117
|
+
|
|
118
|
+
# Enable the private wiki plugin
|
|
119
|
+
disabled_plugins:
|
|
120
|
+
- security/readonly_wiki
|
|
121
|
+
#- security/private_wiki
|
|
122
|
+
- editor/recaptcha
|
|
123
|
+
|
|
124
|
+
authentication:
|
|
125
|
+
enable_signup: false
|
|
126
|
+
}}}
|
|
127
|
+
|
|
95
128
|
== Dependencies
|
|
96
129
|
|
|
97
130
|
If you installed Ōlelo as gem or used Bundler you don't really have to care about the dependencies. The standard installation provides the core dependencies and a good selection of optional dependencies.
|
|
@@ -110,6 +143,7 @@ Some dependencies are optional, for example depending on the markup you want to
|
|
|
110
143
|
* [[http://www.imagemagick.org/|ImageMagick for image resizing]]
|
|
111
144
|
* [[http://nokogiri.org/|Nokogiri for auto-generated table of contents]]
|
|
112
145
|
* [[http://pygments.org/|Pygments for syntax highlighting of code blocks]]
|
|
146
|
+
* [[https://github.com/minad/juno/|Juno Storage Interface]]
|
|
113
147
|
|
|
114
148
|
== Development
|
|
115
149
|
|
data/config.ru
CHANGED
|
@@ -30,14 +30,14 @@ if Dir.pwd == app_path
|
|
|
30
30
|
puts "Serving from Olelo application directory #{app_path}"
|
|
31
31
|
data_path = File.join(app_path, '.wiki')
|
|
32
32
|
Olelo::Config.instance['repository.git'] = { path: ::File.join(data_path, 'repository'), bare: false }
|
|
33
|
-
Olelo::Config.instance['cache_store'] = { type: '
|
|
33
|
+
Olelo::Config.instance['cache_store'] = { type: 'HashFile', 'HashFile.dir' => ::File.join(data_path, 'cache') }
|
|
34
34
|
Olelo::Config.instance['authentication.yamlfile.store'] = ::File.join(data_path, 'users.yml')
|
|
35
35
|
Olelo::Config.instance['log.file'] = ::File.join(data_path, 'log')
|
|
36
36
|
elsif File.directory?(::File.join(Dir.pwd, '.git'))
|
|
37
37
|
puts "Serving out of repository #{Dir.pwd}"
|
|
38
38
|
data_path = File.join(Dir.pwd, '.wiki')
|
|
39
39
|
Olelo::Config.instance['repository.git'] = { path: Dir.pwd, bare: false }
|
|
40
|
-
Olelo::Config.instance['cache_store'] = { type: '
|
|
40
|
+
Olelo::Config.instance['cache_store'] = { type: 'HashFile', 'HashFile.dir' => ::File.join(data_path, 'cache') }
|
|
41
41
|
Olelo::Config.instance['authentication.yamlfile.store'] = ::File.join(data_path, 'users.yml')
|
|
42
42
|
Olelo::Config.instance['log.file'] = ::File.join(data_path, 'log')
|
|
43
43
|
elsif !config_file
|
data/config/config.yml.default
CHANGED
|
@@ -25,16 +25,16 @@ sidebar_page: 'Sidebar'
|
|
|
25
25
|
base_path: '/'
|
|
26
26
|
|
|
27
27
|
# Main cache store. Uncomment this!
|
|
28
|
-
# Available caches:
|
|
28
|
+
# Available caches: Memory, File, Memcached, PStore, ... (see juno gem)
|
|
29
29
|
#cache_store:
|
|
30
|
-
# type:
|
|
31
|
-
#
|
|
32
|
-
#
|
|
33
|
-
#
|
|
30
|
+
# type: HashFile
|
|
31
|
+
# HashFile:
|
|
32
|
+
# dir: '/home/user/wiki/cache'
|
|
33
|
+
# Memcached:
|
|
34
34
|
# prefix: ''
|
|
35
35
|
# server: localhost:11211
|
|
36
|
-
#
|
|
37
|
-
#
|
|
36
|
+
# Memory:
|
|
37
|
+
# PStore:
|
|
38
38
|
# file: '/home/user/wiki/cache.pstore'
|
|
39
39
|
|
|
40
40
|
# Default math renderer
|
|
@@ -117,6 +117,7 @@ disabled_plugins:
|
|
|
117
117
|
- editor/ace
|
|
118
118
|
- filters/remind
|
|
119
119
|
- tags/fortune
|
|
120
|
+
- blog
|
|
120
121
|
|
|
121
122
|
##################################################
|
|
122
123
|
# Rack middleware configurations
|
data/lib/olelo/helper.rb
CHANGED
|
@@ -213,7 +213,7 @@ module Olelo
|
|
|
213
213
|
end
|
|
214
214
|
|
|
215
215
|
unless options.empty?
|
|
216
|
-
query = build_query(options)
|
|
216
|
+
query = Rack::Utils.build_query(options)
|
|
217
217
|
path += '?' + query unless query.empty?
|
|
218
218
|
end
|
|
219
219
|
'/' + (Config['base_path'] / path)
|
|
@@ -326,11 +326,10 @@ module Olelo
|
|
|
326
326
|
<link rel="stylesheet" href="#{escape_html build_static_path("themes/#{Config['theme']}/style.css")}" type="text/css"/>
|
|
327
327
|
<script src="#{escape_html build_static_path("script.js")}" type="text/javascript"></script>}
|
|
328
328
|
# Add base path to root page to fix links in history browsing and for wikis with base_path
|
|
329
|
-
base_path = if
|
|
330
|
-
|
|
331
|
-
url << Config['base_path']
|
|
332
|
-
|
|
333
|
-
%{<base href="#{escape_html url}/"/>}.html_safe
|
|
329
|
+
base_path = if request.path_info =~ %r{^/version/[^/]+$} ||
|
|
330
|
+
(request.path_info == '/' && Config['base_path'] != '/')
|
|
331
|
+
url = request.base_url << [Config['base_path'], '/', request.path_info, '/'].join.gsub(%r{/+}, '/')
|
|
332
|
+
%{<base href="#{escape_html url}"/>}
|
|
334
333
|
end
|
|
335
334
|
[base_path, @@head_links, *invoke_hook(:head)].join.html_safe
|
|
336
335
|
end
|
data/lib/olelo/util.rb
CHANGED
|
@@ -125,24 +125,6 @@ module Olelo
|
|
|
125
125
|
s
|
|
126
126
|
end
|
|
127
127
|
|
|
128
|
-
# Build query from parameter hash
|
|
129
|
-
#
|
|
130
|
-
# Similar to {Rack::Utils#build_query} but sorts parameters.
|
|
131
|
-
# This allows the query string to be used as key for caching etc.
|
|
132
|
-
#
|
|
133
|
-
# @param [Hash] params Parameter hash
|
|
134
|
-
# @return [String] query string
|
|
135
|
-
#
|
|
136
|
-
def build_query(params)
|
|
137
|
-
params.map {|k,v| [k.to_s, v ] }.sort.map do |k, v|
|
|
138
|
-
if v.class == Array
|
|
139
|
-
build_query(v.map { |x| [k, x] })
|
|
140
|
-
else
|
|
141
|
-
"#{escape(k)}=#{escape(v.to_s)}"
|
|
142
|
-
end
|
|
143
|
-
end.join('&')
|
|
144
|
-
end
|
|
145
|
-
|
|
146
128
|
# Creates deep copy of object by abusing `Marshal`
|
|
147
129
|
# This method is slow and not adequate for huge objects.
|
|
148
130
|
# It can only copy objects which are serializable.
|
data/lib/olelo/version.rb
CHANGED
data/olelo.gemspec
CHANGED
|
@@ -29,6 +29,7 @@ Gem::Specification.new do |s|
|
|
|
29
29
|
s.add_runtime_dependency('redcarpet', ['~> 2.2.2'])
|
|
30
30
|
s.add_runtime_dependency('rugged', ['~> 0.17.0.b7'])
|
|
31
31
|
s.add_runtime_dependency('slim', ['~> 1.3.3'])
|
|
32
|
+
s.add_runtime_dependency('juno', ['~> 0.2.0'])
|
|
32
33
|
|
|
33
34
|
s.add_development_dependency('bacon', ['~> 1.1.0'])
|
|
34
35
|
s.add_development_dependency('rack-test', ['~> 0.6.2'])
|
data/plugins/aspects/feed.rb
CHANGED
|
@@ -13,7 +13,7 @@ Aspect.create(:feed, cacheable: true, hidden: true) do
|
|
|
13
13
|
page_nr = [context.params[:page].to_i, 1].max
|
|
14
14
|
history = page.history((page_nr - 1) * per_page, per_page)
|
|
15
15
|
|
|
16
|
-
title = page.root? ? Config['
|
|
16
|
+
title = page.root? ? Config['title'] : page.title
|
|
17
17
|
feed = {
|
|
18
18
|
self_link: url + build_path(page, {aspect: 'feed', format: format}.reject{ |k,v| v.blank? }),
|
|
19
19
|
generator: 'Ōlelo',
|
data/plugins/aspects/main.rb
CHANGED
|
@@ -147,7 +147,7 @@ end
|
|
|
147
147
|
# Plug-in the aspect subsystem
|
|
148
148
|
module ::Olelo::PageHelper
|
|
149
149
|
def render_page(page)
|
|
150
|
-
cache(
|
|
150
|
+
cache(['include', page.path, page.etag], update: no_cache?, defer: true) do
|
|
151
151
|
begin
|
|
152
152
|
context = Context.new(page: page, params: {included: true})
|
|
153
153
|
Aspect.find!(page, layout: true).call(context, page)
|
|
@@ -163,7 +163,7 @@ class ::Olelo::Application
|
|
|
163
163
|
def show_page
|
|
164
164
|
params[:aspect] ||= 'subpages' if params[:path].to_s.ends_with? '/'
|
|
165
165
|
@selected_aspect, layout, header, content =
|
|
166
|
-
cache(
|
|
166
|
+
cache(['aspect', page.path, page.etag, params], update: no_cache?, defer: true) do |cache|
|
|
167
167
|
aspect = Aspect.find!(page, name: params[:aspect])
|
|
168
168
|
cache.disable! if !aspect.cacheable?
|
|
169
169
|
context = Context.new(page: page, params: params, request: request)
|
|
@@ -186,7 +186,7 @@ class ::Olelo::Application
|
|
|
186
186
|
|
|
187
187
|
hook :menu do |menu|
|
|
188
188
|
if menu.name == :actions && view_menu = menu[:view]
|
|
189
|
-
view_menu.append(cache(
|
|
189
|
+
view_menu.append(cache(['aspect-menu', page.path, page.etag, @selected_aspect], update: no_cache?, defer: true) do
|
|
190
190
|
aspects = Aspect.find_all(page).select {|a| !a.hidden? || a.name == @selected_aspect || a.name == page.attributes['aspect'] }.map do |a|
|
|
191
191
|
[Locale.translate("aspect_#{a.name}", fallback: titlecase(a.name)), a]
|
|
192
192
|
end.sort_by(&:first)
|
|
@@ -205,7 +205,7 @@ class ::Olelo::Application
|
|
|
205
205
|
if block || content
|
|
206
206
|
super(content, &block)
|
|
207
207
|
elsif page
|
|
208
|
-
cache(
|
|
208
|
+
cache(['footer', page.path, page.etag], update: no_cache?) { super() }
|
|
209
209
|
else
|
|
210
210
|
super()
|
|
211
211
|
end
|
data/plugins/blog/main.rb
CHANGED
|
@@ -10,7 +10,7 @@ end
|
|
|
10
10
|
Tags::Tag.define 'menu', optional: 'path', description: 'Show blog menu', dynamic: true do |context, attrs, content|
|
|
11
11
|
page = Page.find(attrs[:path]) rescue nil
|
|
12
12
|
if page
|
|
13
|
-
cache(
|
|
13
|
+
cache(['blog', page.path, page.etag], update: no_cache?(context.request.env), defer: true) do
|
|
14
14
|
years = {}
|
|
15
15
|
page.children.each do |child|
|
|
16
16
|
(years[child.version.date.year] ||= [])[child.version.date.month] = true
|
|
@@ -5,7 +5,7 @@ Filter.create :fix_image_links do |context, content|
|
|
|
5
5
|
doc = XML::Fragment(content)
|
|
6
6
|
linked_images = doc.css('a img')
|
|
7
7
|
doc.css('img').each do |image|
|
|
8
|
-
path = image['src']
|
|
8
|
+
path = image['src'] || next
|
|
9
9
|
unless path =~ %r{^w+://} || path.starts_with?(build_path('_')) ||
|
|
10
10
|
(path.starts_with?('/') && !path.starts_with?(build_path('')))
|
|
11
11
|
unless path.include?('aspect=')
|
data/plugins/history/main.rb
CHANGED
|
@@ -53,7 +53,7 @@ class ::Olelo::Application
|
|
|
53
53
|
history_menu = menu.item(:history, href: build_path(page, action: :history), accesskey: 'h')
|
|
54
54
|
|
|
55
55
|
if @history_versions_menu
|
|
56
|
-
history_menu.append(cache(
|
|
56
|
+
history_menu.append(cache(['history-menu', page.path, page.etag], update: no_cache?, defer: true) do
|
|
57
57
|
head = !page.head? && (Olelo::Page.find(page.path) rescue nil)
|
|
58
58
|
items = []
|
|
59
59
|
if page.previous_version || head || page.next_version
|
data/plugins/misc/variables.rb
CHANGED
|
@@ -32,7 +32,7 @@ end
|
|
|
32
32
|
Application.hook :head, 1 do
|
|
33
33
|
vars = params.merge(PLUGIN.exported_global_variables)
|
|
34
34
|
if page
|
|
35
|
-
vars.merge!(cache(
|
|
35
|
+
vars.merge!(cache(['variables', page.path, page.etag], update: no_cache?, defer: true) do
|
|
36
36
|
PLUGIN.exported_page_variables(page)
|
|
37
37
|
end)
|
|
38
38
|
end
|
data/plugins/utils/cache.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
description 'Caching support'
|
|
2
|
-
dependencies 'utils/worker'
|
|
2
|
+
dependencies 'utils/worker'
|
|
3
|
+
require 'juno'
|
|
3
4
|
|
|
4
5
|
class Cache
|
|
5
6
|
def initialize(store = nil)
|
|
@@ -40,7 +41,18 @@ class Cache
|
|
|
40
41
|
end
|
|
41
42
|
|
|
42
43
|
def default_store
|
|
43
|
-
@@store ||=
|
|
44
|
+
@@store ||=
|
|
45
|
+
begin
|
|
46
|
+
type = Config['cache_store.type'].to_sym
|
|
47
|
+
config = Config['cache_store'][type].to_hash
|
|
48
|
+
# FIXME: Deprecated :file store config
|
|
49
|
+
if type == :file
|
|
50
|
+
puts 'WARNING: You are using the deprecated \'file\' store as cache_store in your configuration.'
|
|
51
|
+
type = :HashFile
|
|
52
|
+
config[:dir] = config.delete(:root)
|
|
53
|
+
end
|
|
54
|
+
Juno.new(type, config)
|
|
55
|
+
end
|
|
44
56
|
end
|
|
45
57
|
|
|
46
58
|
class Disabler
|
data/test/request_test.rb
CHANGED
|
@@ -22,9 +22,9 @@ describe 'requests' do
|
|
|
22
22
|
views_path: File.join(@app_path, 'views'),
|
|
23
23
|
theme: 'atlantis',
|
|
24
24
|
cache_store: {
|
|
25
|
-
type: '
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
type: 'HashFile',
|
|
26
|
+
HashFile: {
|
|
27
|
+
dir: File.join(@test_path, 'cache')
|
|
28
28
|
}
|
|
29
29
|
},
|
|
30
30
|
base_path: '/',
|
data/test/util_test.rb
CHANGED
|
@@ -42,10 +42,6 @@ describe 'Olelo::Util' do
|
|
|
42
42
|
Olelo::Util.sha256('test').should.equal '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08'
|
|
43
43
|
end
|
|
44
44
|
|
|
45
|
-
it 'should have #build_query' do
|
|
46
|
-
Olelo::Util.build_query(a: 1, b: [1, 2, 3]).should.equal 'a=1&b=1&b=2&b=3'
|
|
47
|
-
end
|
|
48
|
-
|
|
49
45
|
it 'should have #truncate' do
|
|
50
46
|
Olelo::Util.truncate('Annabel Lee It was many and many a year ago', 11).should.equal 'Annabel Lee...'
|
|
51
47
|
Olelo::Util.truncate('In a kingdom by the sea', 39).should.equal 'In a kingdom by the sea'
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: olelo
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.9.
|
|
4
|
+
version: 0.9.11
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -9,11 +9,11 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2012-11-
|
|
12
|
+
date: 2012-11-28 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: RedCloth
|
|
16
|
-
requirement:
|
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
|
17
17
|
none: false
|
|
18
18
|
requirements:
|
|
19
19
|
- - ~>
|
|
@@ -21,10 +21,15 @@ dependencies:
|
|
|
21
21
|
version: 4.2.9
|
|
22
22
|
type: :runtime
|
|
23
23
|
prerelease: false
|
|
24
|
-
version_requirements:
|
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
+
none: false
|
|
26
|
+
requirements:
|
|
27
|
+
- - ~>
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
version: 4.2.9
|
|
25
30
|
- !ruby/object:Gem::Dependency
|
|
26
31
|
name: creole
|
|
27
|
-
requirement:
|
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
|
28
33
|
none: false
|
|
29
34
|
requirements:
|
|
30
35
|
- - ~>
|
|
@@ -32,10 +37,15 @@ dependencies:
|
|
|
32
37
|
version: 0.5.0
|
|
33
38
|
type: :runtime
|
|
34
39
|
prerelease: false
|
|
35
|
-
version_requirements:
|
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
41
|
+
none: false
|
|
42
|
+
requirements:
|
|
43
|
+
- - ~>
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: 0.5.0
|
|
36
46
|
- !ruby/object:Gem::Dependency
|
|
37
47
|
name: evaluator
|
|
38
|
-
requirement:
|
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
|
39
49
|
none: false
|
|
40
50
|
requirements:
|
|
41
51
|
- - ~>
|
|
@@ -43,10 +53,15 @@ dependencies:
|
|
|
43
53
|
version: 0.1.6
|
|
44
54
|
type: :runtime
|
|
45
55
|
prerelease: false
|
|
46
|
-
version_requirements:
|
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
57
|
+
none: false
|
|
58
|
+
requirements:
|
|
59
|
+
- - ~>
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: 0.1.6
|
|
47
62
|
- !ruby/object:Gem::Dependency
|
|
48
63
|
name: mimemagic
|
|
49
|
-
requirement:
|
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
|
50
65
|
none: false
|
|
51
66
|
requirements:
|
|
52
67
|
- - ~>
|
|
@@ -54,10 +69,15 @@ dependencies:
|
|
|
54
69
|
version: 0.2.0
|
|
55
70
|
type: :runtime
|
|
56
71
|
prerelease: false
|
|
57
|
-
version_requirements:
|
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
73
|
+
none: false
|
|
74
|
+
requirements:
|
|
75
|
+
- - ~>
|
|
76
|
+
- !ruby/object:Gem::Version
|
|
77
|
+
version: 0.2.0
|
|
58
78
|
- !ruby/object:Gem::Dependency
|
|
59
79
|
name: multi_json
|
|
60
|
-
requirement:
|
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
|
61
81
|
none: false
|
|
62
82
|
requirements:
|
|
63
83
|
- - ~>
|
|
@@ -65,10 +85,15 @@ dependencies:
|
|
|
65
85
|
version: 1.3.7
|
|
66
86
|
type: :runtime
|
|
67
87
|
prerelease: false
|
|
68
|
-
version_requirements:
|
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
89
|
+
none: false
|
|
90
|
+
requirements:
|
|
91
|
+
- - ~>
|
|
92
|
+
- !ruby/object:Gem::Version
|
|
93
|
+
version: 1.3.7
|
|
69
94
|
- !ruby/object:Gem::Dependency
|
|
70
95
|
name: nokogiri
|
|
71
|
-
requirement:
|
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
97
|
none: false
|
|
73
98
|
requirements:
|
|
74
99
|
- - ~>
|
|
@@ -76,10 +101,15 @@ dependencies:
|
|
|
76
101
|
version: 1.5.5
|
|
77
102
|
type: :runtime
|
|
78
103
|
prerelease: false
|
|
79
|
-
version_requirements:
|
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
105
|
+
none: false
|
|
106
|
+
requirements:
|
|
107
|
+
- - ~>
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: 1.5.5
|
|
80
110
|
- !ruby/object:Gem::Dependency
|
|
81
111
|
name: rack
|
|
82
|
-
requirement:
|
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
|
83
113
|
none: false
|
|
84
114
|
requirements:
|
|
85
115
|
- - ~>
|
|
@@ -87,10 +117,15 @@ dependencies:
|
|
|
87
117
|
version: 1.4.1
|
|
88
118
|
type: :runtime
|
|
89
119
|
prerelease: false
|
|
90
|
-
version_requirements:
|
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
121
|
+
none: false
|
|
122
|
+
requirements:
|
|
123
|
+
- - ~>
|
|
124
|
+
- !ruby/object:Gem::Version
|
|
125
|
+
version: 1.4.1
|
|
91
126
|
- !ruby/object:Gem::Dependency
|
|
92
127
|
name: redcarpet
|
|
93
|
-
requirement:
|
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
|
94
129
|
none: false
|
|
95
130
|
requirements:
|
|
96
131
|
- - ~>
|
|
@@ -98,10 +133,15 @@ dependencies:
|
|
|
98
133
|
version: 2.2.2
|
|
99
134
|
type: :runtime
|
|
100
135
|
prerelease: false
|
|
101
|
-
version_requirements:
|
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
137
|
+
none: false
|
|
138
|
+
requirements:
|
|
139
|
+
- - ~>
|
|
140
|
+
- !ruby/object:Gem::Version
|
|
141
|
+
version: 2.2.2
|
|
102
142
|
- !ruby/object:Gem::Dependency
|
|
103
143
|
name: rugged
|
|
104
|
-
requirement:
|
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
|
105
145
|
none: false
|
|
106
146
|
requirements:
|
|
107
147
|
- - ~>
|
|
@@ -109,10 +149,15 @@ dependencies:
|
|
|
109
149
|
version: 0.17.0.b7
|
|
110
150
|
type: :runtime
|
|
111
151
|
prerelease: false
|
|
112
|
-
version_requirements:
|
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
153
|
+
none: false
|
|
154
|
+
requirements:
|
|
155
|
+
- - ~>
|
|
156
|
+
- !ruby/object:Gem::Version
|
|
157
|
+
version: 0.17.0.b7
|
|
113
158
|
- !ruby/object:Gem::Dependency
|
|
114
159
|
name: slim
|
|
115
|
-
requirement:
|
|
160
|
+
requirement: !ruby/object:Gem::Requirement
|
|
116
161
|
none: false
|
|
117
162
|
requirements:
|
|
118
163
|
- - ~>
|
|
@@ -120,10 +165,31 @@ dependencies:
|
|
|
120
165
|
version: 1.3.3
|
|
121
166
|
type: :runtime
|
|
122
167
|
prerelease: false
|
|
123
|
-
version_requirements:
|
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
169
|
+
none: false
|
|
170
|
+
requirements:
|
|
171
|
+
- - ~>
|
|
172
|
+
- !ruby/object:Gem::Version
|
|
173
|
+
version: 1.3.3
|
|
174
|
+
- !ruby/object:Gem::Dependency
|
|
175
|
+
name: juno
|
|
176
|
+
requirement: !ruby/object:Gem::Requirement
|
|
177
|
+
none: false
|
|
178
|
+
requirements:
|
|
179
|
+
- - ~>
|
|
180
|
+
- !ruby/object:Gem::Version
|
|
181
|
+
version: 0.2.0
|
|
182
|
+
type: :runtime
|
|
183
|
+
prerelease: false
|
|
184
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
185
|
+
none: false
|
|
186
|
+
requirements:
|
|
187
|
+
- - ~>
|
|
188
|
+
- !ruby/object:Gem::Version
|
|
189
|
+
version: 0.2.0
|
|
124
190
|
- !ruby/object:Gem::Dependency
|
|
125
191
|
name: bacon
|
|
126
|
-
requirement:
|
|
192
|
+
requirement: !ruby/object:Gem::Requirement
|
|
127
193
|
none: false
|
|
128
194
|
requirements:
|
|
129
195
|
- - ~>
|
|
@@ -131,10 +197,15 @@ dependencies:
|
|
|
131
197
|
version: 1.1.0
|
|
132
198
|
type: :development
|
|
133
199
|
prerelease: false
|
|
134
|
-
version_requirements:
|
|
200
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
201
|
+
none: false
|
|
202
|
+
requirements:
|
|
203
|
+
- - ~>
|
|
204
|
+
- !ruby/object:Gem::Version
|
|
205
|
+
version: 1.1.0
|
|
135
206
|
- !ruby/object:Gem::Dependency
|
|
136
207
|
name: rack-test
|
|
137
|
-
requirement:
|
|
208
|
+
requirement: !ruby/object:Gem::Requirement
|
|
138
209
|
none: false
|
|
139
210
|
requirements:
|
|
140
211
|
- - ~>
|
|
@@ -142,10 +213,15 @@ dependencies:
|
|
|
142
213
|
version: 0.6.2
|
|
143
214
|
type: :development
|
|
144
215
|
prerelease: false
|
|
145
|
-
version_requirements:
|
|
216
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
217
|
+
none: false
|
|
218
|
+
requirements:
|
|
219
|
+
- - ~>
|
|
220
|
+
- !ruby/object:Gem::Version
|
|
221
|
+
version: 0.6.2
|
|
146
222
|
- !ruby/object:Gem::Dependency
|
|
147
223
|
name: rake
|
|
148
|
-
requirement:
|
|
224
|
+
requirement: !ruby/object:Gem::Requirement
|
|
149
225
|
none: false
|
|
150
226
|
requirements:
|
|
151
227
|
- - ! '>='
|
|
@@ -153,10 +229,15 @@ dependencies:
|
|
|
153
229
|
version: 0.8.7
|
|
154
230
|
type: :development
|
|
155
231
|
prerelease: false
|
|
156
|
-
version_requirements:
|
|
232
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
233
|
+
none: false
|
|
234
|
+
requirements:
|
|
235
|
+
- - ! '>='
|
|
236
|
+
- !ruby/object:Gem::Version
|
|
237
|
+
version: 0.8.7
|
|
157
238
|
- !ruby/object:Gem::Dependency
|
|
158
239
|
name: sass
|
|
159
|
-
requirement:
|
|
240
|
+
requirement: !ruby/object:Gem::Requirement
|
|
160
241
|
none: false
|
|
161
242
|
requirements:
|
|
162
243
|
- - ~>
|
|
@@ -164,7 +245,12 @@ dependencies:
|
|
|
164
245
|
version: 3.2.3
|
|
165
246
|
type: :development
|
|
166
247
|
prerelease: false
|
|
167
|
-
version_requirements:
|
|
248
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
249
|
+
none: false
|
|
250
|
+
requirements:
|
|
251
|
+
- - ~>
|
|
252
|
+
- !ruby/object:Gem::Version
|
|
253
|
+
version: 3.2.3
|
|
168
254
|
description: Olelo is a git-based wiki which supports many markup languages, tags,
|
|
169
255
|
embedded TeX and much more. It can be extended through plugins.
|
|
170
256
|
email:
|
|
@@ -359,7 +445,6 @@ files:
|
|
|
359
445
|
- plugins/utils/pygments.scss
|
|
360
446
|
- plugins/utils/semaphore.rb
|
|
361
447
|
- plugins/utils/shell.rb
|
|
362
|
-
- plugins/utils/store.rb
|
|
363
448
|
- plugins/utils/worker.rb
|
|
364
449
|
- plugins/utils/xml.rb
|
|
365
450
|
- static/favicon.png
|
|
@@ -480,7 +565,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
480
565
|
version: '0'
|
|
481
566
|
requirements: []
|
|
482
567
|
rubyforge_project: olelo
|
|
483
|
-
rubygems_version: 1.8.
|
|
568
|
+
rubygems_version: 1.8.24
|
|
484
569
|
signing_key:
|
|
485
570
|
specification_version: 3
|
|
486
571
|
summary: Olelo is a git-based wiki.
|
data/plugins/utils/store.rb
DELETED
|
@@ -1,336 +0,0 @@
|
|
|
1
|
-
description 'Key/value store'
|
|
2
|
-
require 'delegate'
|
|
3
|
-
|
|
4
|
-
# Simple interface to key/value stores with Hash-like interface.
|
|
5
|
-
#
|
|
6
|
-
# Store supports a subset of the Moneta interface,
|
|
7
|
-
# Moneta can be used as a drop-in replacement.
|
|
8
|
-
# It is recommended to wrap the moneta store in a Store::Delegated
|
|
9
|
-
# to only expose the Store interface.
|
|
10
|
-
#
|
|
11
|
-
# @abstract
|
|
12
|
-
class Store
|
|
13
|
-
extend Factory
|
|
14
|
-
|
|
15
|
-
# Exists the value with key
|
|
16
|
-
#
|
|
17
|
-
# @param [String] key
|
|
18
|
-
# @return [Boolean]
|
|
19
|
-
# @api public
|
|
20
|
-
# @abstract
|
|
21
|
-
def key?(key)
|
|
22
|
-
raise NotImplementedError
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
# Read value with key. Return nil if the key doesn't exist
|
|
26
|
-
#
|
|
27
|
-
# @param [String] key
|
|
28
|
-
# @return [Object] value
|
|
29
|
-
# @api public
|
|
30
|
-
# @abstract
|
|
31
|
-
def [](key)
|
|
32
|
-
raise NotImplementedError
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
# Write value with key
|
|
36
|
-
#
|
|
37
|
-
# @param [String] key
|
|
38
|
-
# @param [Object] value
|
|
39
|
-
# @return value
|
|
40
|
-
# @api public
|
|
41
|
-
# @abstract
|
|
42
|
-
def []=(key, value)
|
|
43
|
-
raise NotImplementedError
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
# Delete the key from the store and return the current value
|
|
47
|
-
#
|
|
48
|
-
# @param [String] key
|
|
49
|
-
# @return [Object] current value
|
|
50
|
-
# @api public
|
|
51
|
-
# @abstract
|
|
52
|
-
def delete(key)
|
|
53
|
-
raise NotImplementedError
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
# Clear all keys in this store
|
|
57
|
-
#
|
|
58
|
-
# @return [void]
|
|
59
|
-
# @api public
|
|
60
|
-
# @abstract
|
|
61
|
-
def clear
|
|
62
|
-
raise NotImplementedError
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
protected
|
|
66
|
-
|
|
67
|
-
# Serialize value
|
|
68
|
-
#
|
|
69
|
-
# @param [Object] value Serializable object
|
|
70
|
-
# @return [String] serialized object
|
|
71
|
-
# @api private
|
|
72
|
-
def serialize(value)
|
|
73
|
-
Marshal.dump(value)
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
# Deserialize value
|
|
77
|
-
#
|
|
78
|
-
# @param [String] value Serialized object
|
|
79
|
-
# @return [Object] Deserialized object
|
|
80
|
-
# @api private
|
|
81
|
-
def deserialize(value)
|
|
82
|
-
value && Marshal.load(value)
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
# Create store instance
|
|
86
|
-
#
|
|
87
|
-
# @param [Config] Store configuration
|
|
88
|
-
# @return [Store]
|
|
89
|
-
# @api public
|
|
90
|
-
def self.create(config)
|
|
91
|
-
self[config[:type]].new(config[config[:type]])
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
# Delegated store
|
|
95
|
-
Delegated = DelegateClass(Store)
|
|
96
|
-
|
|
97
|
-
# Memory based store (uses hash)
|
|
98
|
-
class Memory < Delegated
|
|
99
|
-
def initialize(config)
|
|
100
|
-
super({})
|
|
101
|
-
end
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
register :memory, Memory
|
|
105
|
-
|
|
106
|
-
# Memcached client
|
|
107
|
-
class Memcached < Delegated
|
|
108
|
-
def initialize(config)
|
|
109
|
-
super(Native.new(config))
|
|
110
|
-
rescue LoadError
|
|
111
|
-
super(Ruby.new(config))
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
# Uses the memcached gem
|
|
115
|
-
class Native < Store
|
|
116
|
-
include Util
|
|
117
|
-
|
|
118
|
-
def initialize(config)
|
|
119
|
-
require 'memcached'
|
|
120
|
-
@server = ::Memcached.new(config[:server], prefix_key: (config[:prefix] rescue nil))
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
# @override
|
|
124
|
-
def key?(key)
|
|
125
|
-
@server.get(md5(key), false)
|
|
126
|
-
true
|
|
127
|
-
rescue ::Memcached::NotFound
|
|
128
|
-
false
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
# @override
|
|
132
|
-
def [](key)
|
|
133
|
-
@server.get(md5(key))
|
|
134
|
-
rescue ::Memcached::NotFound
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
# @override
|
|
138
|
-
def []=(key, value)
|
|
139
|
-
@server.set(md5(key), value)
|
|
140
|
-
value
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
# @override
|
|
144
|
-
def delete(key)
|
|
145
|
-
key = md5(key)
|
|
146
|
-
value = @server.get(key)
|
|
147
|
-
@server.delete(key)
|
|
148
|
-
value
|
|
149
|
-
rescue ::Memcached::NotFound
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
# @override
|
|
153
|
-
def clear
|
|
154
|
-
@server.flush
|
|
155
|
-
end
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
# Uses the dalli gem (memcache-client successor)
|
|
159
|
-
class Ruby < Store
|
|
160
|
-
include Util
|
|
161
|
-
|
|
162
|
-
def initialize(config)
|
|
163
|
-
require 'dalli'
|
|
164
|
-
@server = ::Dalli::Client.new(config[:server], namespace: (config[:prefix] rescue nil))
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
# @override
|
|
168
|
-
def key?(key)
|
|
169
|
-
!@server.get(md5(key)).nil?
|
|
170
|
-
end
|
|
171
|
-
|
|
172
|
-
# @override
|
|
173
|
-
def [](key)
|
|
174
|
-
deserialize(@server.get(md5(key)))
|
|
175
|
-
end
|
|
176
|
-
|
|
177
|
-
# @override
|
|
178
|
-
def []=(key, value)
|
|
179
|
-
@server.set(md5(key), serialize(value))
|
|
180
|
-
value
|
|
181
|
-
end
|
|
182
|
-
|
|
183
|
-
# @override
|
|
184
|
-
def delete(key)
|
|
185
|
-
key = md5(key)
|
|
186
|
-
value = deserialize(@server.get(key))
|
|
187
|
-
@server.delete(key)
|
|
188
|
-
value
|
|
189
|
-
end
|
|
190
|
-
|
|
191
|
-
# @override
|
|
192
|
-
def clear
|
|
193
|
-
@server.flush_all
|
|
194
|
-
end
|
|
195
|
-
end
|
|
196
|
-
end
|
|
197
|
-
|
|
198
|
-
register :memcached, Memcached
|
|
199
|
-
|
|
200
|
-
# PStore based store
|
|
201
|
-
class PStore < Store
|
|
202
|
-
def initialize(config)
|
|
203
|
-
require 'pstore'
|
|
204
|
-
FileUtils.mkpath(::File.dirname(config[:file]))
|
|
205
|
-
# Create a thread-safe pstore
|
|
206
|
-
@store = ::PStore.new(config[:file], true)
|
|
207
|
-
end
|
|
208
|
-
|
|
209
|
-
# @override
|
|
210
|
-
def key?(key)
|
|
211
|
-
@store.transaction(true) { @store.root?(key) }
|
|
212
|
-
end
|
|
213
|
-
|
|
214
|
-
# @override
|
|
215
|
-
def [](key)
|
|
216
|
-
@store.transaction(true) { @store[key] }
|
|
217
|
-
end
|
|
218
|
-
|
|
219
|
-
# @override
|
|
220
|
-
def []=(key, value)
|
|
221
|
-
@store.transaction { @store[key] = value }
|
|
222
|
-
end
|
|
223
|
-
|
|
224
|
-
# @override
|
|
225
|
-
def delete(key)
|
|
226
|
-
@store.transaction { @store.delete(key) }
|
|
227
|
-
end
|
|
228
|
-
|
|
229
|
-
# @override
|
|
230
|
-
def clear
|
|
231
|
-
@store.transaction do
|
|
232
|
-
@store.roots.each do |key|
|
|
233
|
-
@store.delete(key)
|
|
234
|
-
end
|
|
235
|
-
end
|
|
236
|
-
end
|
|
237
|
-
end
|
|
238
|
-
|
|
239
|
-
register :pstore, PStore
|
|
240
|
-
|
|
241
|
-
# GDBM based store
|
|
242
|
-
class GDBM < Store
|
|
243
|
-
def initialize(config)
|
|
244
|
-
require 'gdbm'
|
|
245
|
-
FileUtils.mkpath(::File.dirname(config[:db]))
|
|
246
|
-
@db = ::GDBM.new(config[:db])
|
|
247
|
-
end
|
|
248
|
-
|
|
249
|
-
# @override
|
|
250
|
-
def key?(key)
|
|
251
|
-
@db.has_key?(key)
|
|
252
|
-
end
|
|
253
|
-
|
|
254
|
-
# @override
|
|
255
|
-
def [](key)
|
|
256
|
-
deserialize(@db[key])
|
|
257
|
-
end
|
|
258
|
-
|
|
259
|
-
# @override
|
|
260
|
-
def []=(key, value)
|
|
261
|
-
@db[key] = serialize(value)
|
|
262
|
-
end
|
|
263
|
-
|
|
264
|
-
# @override
|
|
265
|
-
def delete(key)
|
|
266
|
-
@db.delete(key)
|
|
267
|
-
end
|
|
268
|
-
|
|
269
|
-
# @override
|
|
270
|
-
def clear
|
|
271
|
-
@db.clear
|
|
272
|
-
end
|
|
273
|
-
end
|
|
274
|
-
|
|
275
|
-
register :gdbm, GDBM
|
|
276
|
-
|
|
277
|
-
# File based store
|
|
278
|
-
class File < Store
|
|
279
|
-
def initialize(config)
|
|
280
|
-
@root = config[:root]
|
|
281
|
-
end
|
|
282
|
-
|
|
283
|
-
# @override
|
|
284
|
-
def key?(key)
|
|
285
|
-
::File.exist?(store_path(key))
|
|
286
|
-
end
|
|
287
|
-
|
|
288
|
-
# @override
|
|
289
|
-
def [](key)
|
|
290
|
-
deserialize(::File.read(store_path(key)))
|
|
291
|
-
rescue Errno::ENOENT
|
|
292
|
-
end
|
|
293
|
-
|
|
294
|
-
# @override
|
|
295
|
-
def []=(key, value)
|
|
296
|
-
temp_file = ::File.join(@root, "value-#{$$}-#{Thread.current.object_id}")
|
|
297
|
-
FileUtils.mkpath(@root)
|
|
298
|
-
::File.open(temp_file, 'wb') {|file| file.write(serialize(value)) }
|
|
299
|
-
path = store_path(key)
|
|
300
|
-
FileUtils.mkpath(::File.dirname(path))
|
|
301
|
-
::File.unlink(path) if ::File.exist?(path)
|
|
302
|
-
::File.rename(temp_file, path)
|
|
303
|
-
rescue
|
|
304
|
-
::File.unlink(temp_file) rescue nil
|
|
305
|
-
ensure
|
|
306
|
-
value
|
|
307
|
-
end
|
|
308
|
-
|
|
309
|
-
# @override
|
|
310
|
-
def delete(key)
|
|
311
|
-
value = self[key]
|
|
312
|
-
::File.unlink(store_path(key))
|
|
313
|
-
value
|
|
314
|
-
rescue Errno::ENOENT
|
|
315
|
-
end
|
|
316
|
-
|
|
317
|
-
# @override
|
|
318
|
-
def clear
|
|
319
|
-
temp_dir = "#{@root}-#{$$}-#{Thread.current.object_id}"
|
|
320
|
-
::File.rename(@root, temp_dir)
|
|
321
|
-
FileUtils.rm_rf(temp_dir)
|
|
322
|
-
rescue Errno::ENOENT
|
|
323
|
-
end
|
|
324
|
-
|
|
325
|
-
protected
|
|
326
|
-
|
|
327
|
-
def store_path(key)
|
|
328
|
-
key = Util.md5(key)
|
|
329
|
-
::File.join(@root, key[0..1], key[2..-1])
|
|
330
|
-
end
|
|
331
|
-
end
|
|
332
|
-
|
|
333
|
-
register :file, File
|
|
334
|
-
end
|
|
335
|
-
|
|
336
|
-
Olelo::Store = Store
|