olelo 0.9.10 → 0.9.11

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: 'file', 'file.root' => ::File.join(data_path, 'cache') }
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: 'file', 'file.root' => ::File.join(data_path, 'cache') }
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
@@ -25,16 +25,16 @@ sidebar_page: 'Sidebar'
25
25
  base_path: '/'
26
26
 
27
27
  # Main cache store. Uncomment this!
28
- # Available caches: memory, file, memcached, pstore
28
+ # Available caches: Memory, File, Memcached, PStore, ... (see juno gem)
29
29
  #cache_store:
30
- # type: file
31
- # file:
32
- # root: '/home/user/wiki/cache'
33
- # memcached:
30
+ # type: HashFile
31
+ # HashFile:
32
+ # dir: '/home/user/wiki/cache'
33
+ # Memcached:
34
34
  # prefix: ''
35
35
  # server: localhost:11211
36
- # memory:
37
- # pstore:
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
@@ -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 page && page.root?
330
- url = request.base_url
331
- url << Config['base_path'] if Config['base_path'] != '/'
332
- url << '/' << 'version'/page.tree_version if !page.head?
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
@@ -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.
@@ -1,3 +1,3 @@
1
1
  module Olelo
2
- VERSION = '0.9.10'
2
+ VERSION = '0.9.11'
3
3
  end
@@ -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'])
@@ -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['Title'] : page.title
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',
@@ -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("include-#{page.path}-#{page.etag}", update: no_cache?, defer: true) do
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("aspect-#{page.path}-#{page.etag}-#{build_query(params)}", update: no_cache?, defer: true) do |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("aspect-menu-#{page.path}-#{page.etag}-#{@selected_aspect}", update: no_cache?, defer: true) do
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("footer-#{page.path}-#{page.etag}", update: no_cache?) { super() }
208
+ cache(['footer', page.path, page.etag], update: no_cache?) { super() }
209
209
  else
210
210
  super()
211
211
  end
@@ -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("blog-#{page.path}-#{page.etag}", update: no_cache?(context.request.env), defer: true) do
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=')
@@ -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("history-menu-#{page.path}-#{page.etag}", update: no_cache?, defer: true) do
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
@@ -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("variables-#{page.path}-#{page.etag}", update: no_cache?, defer: true) do
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
@@ -1,5 +1,6 @@
1
1
  description 'Caching support'
2
- dependencies 'utils/worker', 'utils/store'
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 ||= Store.create(Config['cache_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
@@ -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: 'file',
26
- file: {
27
- root: File.join(@test_path, 'cache')
25
+ type: 'HashFile',
26
+ HashFile: {
27
+ dir: File.join(@test_path, 'cache')
28
28
  }
29
29
  },
30
30
  base_path: '/',
@@ -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.10
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-18 00:00:00.000000000 Z
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: &13186180 !ruby/object:Gem::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: *13186180
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: &13185500 !ruby/object:Gem::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: *13185500
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: &13184880 !ruby/object:Gem::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: *13184880
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: &13184340 !ruby/object:Gem::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: *13184340
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: &13183520 !ruby/object:Gem::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: *13183520
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: &13182660 !ruby/object:Gem::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: *13182660
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: &13181580 !ruby/object:Gem::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: *13181580
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: &13180940 !ruby/object:Gem::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: *13180940
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: &13180280 !ruby/object:Gem::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: *13180280
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: &13179700 !ruby/object:Gem::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: *13179700
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: &13179060 !ruby/object:Gem::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: *13179060
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: &13178400 !ruby/object:Gem::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: *13178400
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: &13249720 !ruby/object:Gem::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: *13249720
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: &13248580 !ruby/object:Gem::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: *13248580
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.15
568
+ rubygems_version: 1.8.24
484
569
  signing_key:
485
570
  specification_version: 3
486
571
  summary: Olelo is a git-based wiki.
@@ -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