olelo 0.9.2 → 0.9.3

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.
Files changed (57) hide show
  1. data/{doc/LICENSE → LICENSE} +0 -0
  2. data/README.creole +127 -0
  3. data/Rakefile +2 -2
  4. data/bin/olelo +55 -2
  5. data/config.ru +21 -4
  6. data/config/aspects.rb +9 -7
  7. data/config/config.yml.default +1 -0
  8. data/lib/olelo.rb +1 -0
  9. data/lib/olelo/application.rb +25 -14
  10. data/lib/olelo/config.rb +1 -1
  11. data/lib/olelo/extensions.rb +0 -12
  12. data/lib/olelo/helper.rb +0 -4
  13. data/lib/olelo/initializer.rb +4 -7
  14. data/lib/olelo/locale.yml +0 -3
  15. data/lib/olelo/page.rb +1 -1
  16. data/lib/olelo/plugin.rb +5 -4
  17. data/lib/olelo/routing.rb +15 -12
  18. data/lib/olelo/user.rb +10 -24
  19. data/lib/olelo/util.rb +4 -11
  20. data/lib/olelo/version.rb +1 -1
  21. data/lib/olelo/virtualfs.rb +11 -19
  22. data/olelo.gemspec +5 -2
  23. data/plugins/aspects/locale.yml +5 -0
  24. data/plugins/aspects/main.rb +8 -4
  25. data/plugins/authentication/yamlfile.rb +1 -1
  26. data/plugins/blog/main.rb +5 -5
  27. data/plugins/editor/ace/init.js +17 -0
  28. data/plugins/editor/ace/main.rb +7 -0
  29. data/plugins/editor/markup/main.rb +1 -1
  30. data/plugins/editor/markup/script.js +8 -8
  31. data/plugins/editor/markup/script/init.js +3 -3
  32. data/plugins/editor/recaptcha.rb +2 -2
  33. data/plugins/filters/interwiki.rb +0 -1
  34. data/plugins/gallery/main.rb +1 -1
  35. data/plugins/login/persistent.rb +2 -2
  36. data/plugins/misc/fancybox/script.js +1 -1
  37. data/plugins/misc/fancybox/script/init.js +2 -2
  38. data/plugins/misc/variables.rb +2 -2
  39. data/plugins/tags/math.rb +6 -7
  40. data/plugins/tags/scripting.rb +1 -1
  41. data/plugins/tags/tabs.rb +1 -1
  42. data/plugins/treeview/script.js +2 -2
  43. data/plugins/treeview/script/init.js +26 -24
  44. data/plugins/utils/assets.rb +20 -14
  45. data/static/themes/atlantis/images/bg/header.jpg +0 -0
  46. data/static/themes/atlantis/images/bg/header_gray.jpg +0 -0
  47. data/views/layout.slim +0 -1
  48. data/views/login.slim +3 -2
  49. metadata +127 -34
  50. data/README.markdown +0 -104
  51. data/doc/AUTHORS +0 -7
  52. data/lib/rack/olelo_patches.rb +0 -33
  53. data/lib/yard/addons.rb +0 -1
  54. data/lib/yard/addons/hook_handler.rb +0 -25
  55. data/lib/yard/addons/override_tag.rb +0 -14
  56. data/lib/yard/addons/route_handler.rb +0 -33
  57. data/lib/yard/addons/sanitize_anchor.rb +0 -16
data/lib/olelo/locale.yml CHANGED
@@ -7,7 +7,6 @@ en:
7
7
  attribute_title: 'Title'
8
8
  attributes: 'Attributes'
9
9
  attributes_edited: 'Attributes of #{page} edited'
10
- auth_unsupported: 'Authentication service does not support #{name}'
11
10
  author: 'Author'
12
11
  binary_file: 'Binary file'
13
12
  by: 'by'
@@ -96,7 +95,6 @@ de:
96
95
  attribute_title: 'Titel'
97
96
  attributes: 'Attribute'
98
97
  attributes_edited: 'Attribute von #{page} bearbeitet'
99
- auth_unsupported: 'Authentifikationsservice unterstützt #{name} nicht'
100
98
  author: 'Autor'
101
99
  binary_file: 'Binärdatei'
102
100
  by: 'von'
@@ -191,7 +189,6 @@ cs_CZ:
191
189
  attribute_title: 'Titulek'
192
190
  attributes: 'Atributy'
193
191
  attributes_edited: 'Atributy stránky #{page} editovány'
194
- auth_unsupported: 'Autentizační služba nepodporuje #{name}'
195
192
  author: 'Autor'
196
193
  binary_file: 'Binární soubor'
197
194
  by: 'od'
data/lib/olelo/page.rb CHANGED
@@ -132,7 +132,7 @@ module Olelo
132
132
 
133
133
  def name
134
134
  i = path.rindex('/')
135
- name = i ? path[i+1..-1] : path
135
+ i ? path[i+1..-1] : path
136
136
  end
137
137
 
138
138
  def title
data/lib/olelo/plugin.rb CHANGED
@@ -98,8 +98,8 @@ module Olelo
98
98
  if Module === obj
99
99
  names = obj.name.split('::')
100
100
  mod = Object
101
- names.map {|name| mod = mod.const_get(name) }.reverse.each do |mod|
102
- return mod if Plugin === mod
101
+ names.map {|name| mod = mod.const_get(name) }.reverse.each do |m|
102
+ return m if Plugin === m
103
103
  end
104
104
  elsif Proc === obj
105
105
  return obj.binding.eval('PLUGIN')
@@ -114,6 +114,7 @@ module Olelo
114
114
  attr_reader? :started
115
115
 
116
116
  def initialize(path, file)
117
+ @setup = nil
117
118
  @path, @file = path, file
118
119
  @started = false
119
120
  @dependencies = Set.new
@@ -129,11 +130,11 @@ module Olelo
129
130
 
130
131
  (0...names.length).inject(Plugin) do |mod, i|
131
132
  elem = names[i].split('_').map(&:capitalize).join
132
- if mod.local_const_defined?(elem)
133
+ if mod.const_defined?(elem, false)
133
134
  mod.const_get(elem)
134
135
  else
135
136
  child = i == names.length - 1 ? self : Module.new
136
- child.module_eval { include mod } if mod != Plugin
137
+ child.module_eval { include mod } if mod != Plugin # Include parent module
137
138
  mod.const_set(elem, child)
138
139
  end
139
140
  end
data/lib/olelo/routing.rb CHANGED
@@ -94,23 +94,26 @@ module Olelo
94
94
  nil
95
95
  end
96
96
 
97
- return if !result
98
- if result.respond_to?(:to_str)
97
+ case result
98
+ when nil, false
99
+ when String
99
100
  response.body = [result]
100
- elsif result.respond_to?(:to_ary)
101
- result = result.to_ary
102
- if result.length == 2 && Symbol === result.first
103
- response.status = Rack::Utils.status_code(result.first)
104
- response.body = result.last
101
+ when Fixnum, Symbol
102
+ response.status = Rack::Utils.status_code(result)
103
+ when Array
104
+ if Symbol === result.first || Fixnum === result.first
105
+ response.status = Rack::Utils.status_code(result.shift)
106
+ response.body = result.pop
107
+ response.headers.merge!(result.first) if result.first
105
108
  else
106
109
  response.body = result
107
110
  end
108
- elsif result.respond_to?(:each)
109
- response.body = result
110
- elsif Symbol === result
111
- response.status = Rack::Utils.status_code(result)
112
111
  else
113
- raise TypeError, "#{result.inspect} not supported"
112
+ if result.respond_to?(:each)
113
+ response.body = result
114
+ else
115
+ raise TypeError, "#{result.inspect} not supported"
116
+ end
114
117
  end
115
118
  end
116
119
 
data/lib/olelo/user.rb CHANGED
@@ -29,7 +29,7 @@ module Olelo
29
29
  User.service.change_password(self, oldpassword, password)
30
30
  end
31
31
 
32
- def modify(&block)
32
+ def update(&block)
33
33
  copy = dup
34
34
  block.call(copy)
35
35
  validate
@@ -42,7 +42,7 @@ module Olelo
42
42
  def validate
43
43
  check do |errors|
44
44
  errors << :invalid_email.t if email !~ /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i
45
- errors << :invalid_name.t if name !~ /[\w\.\-\+_]+/
45
+ errors << :invalid_name.t if name !~ /[\w\.\-\+]+/
46
46
  end
47
47
  end
48
48
 
@@ -50,12 +50,6 @@ module Olelo
50
50
  include Util
51
51
  extend Factory
52
52
 
53
- class NotSupportedError < AuthenticationError
54
- def initialize(name)
55
- super(:auth_unsupported.t(:name => name))
56
- end
57
- end
58
-
59
53
  def find(name)
60
54
  raise NotImplementedError
61
55
  end
@@ -63,18 +57,6 @@ module Olelo
63
57
  def authenticate(name, password)
64
58
  raise NotImplementedError
65
59
  end
66
-
67
- def create(user, password)
68
- raise NotSupportedError('create')
69
- end
70
-
71
- def update(user)
72
- raise NotSupportedError('update')
73
- end
74
-
75
- def change_password(user, oldpassword, password)
76
- raise NotSupportedError('change_password')
77
- end
78
60
  end
79
61
 
80
62
  class<< self
@@ -103,8 +85,8 @@ module Olelo
103
85
 
104
86
  def anonymous(request)
105
87
  ip = request.ip || 'unknown-ip'
106
- name = request.remote_host ? "#{request.remote_host} (#{ip})" : ip
107
- new(name, "anonymous@#{ip}")
88
+ host = request.ip && Socket.gethostbyaddr(request.ip.split('.').map(&:to_i).pack('C*')).first rescue nil
89
+ new(host ? "#{host} (#{ip})" : ip, "anonymous@#{ip}")
108
90
  end
109
91
 
110
92
  def find!(name)
@@ -119,11 +101,15 @@ module Olelo
119
101
  service.authenticate(name, password).tap {|user| user.groups << 'user' }
120
102
  end
121
103
 
122
- def create(name, password, confirm, email)
104
+ def supports?(method)
105
+ service.respond_to?(method)
106
+ end
107
+
108
+ def signup(name, password, confirm, email)
123
109
  validate_password(password, confirm)
124
110
  user = new(name, email, %w(user))
125
111
  user.validate
126
- service.create(user, password)
112
+ service.signup(user, password)
127
113
  user
128
114
  end
129
115
  end
data/lib/olelo/util.rb CHANGED
@@ -33,17 +33,6 @@ module Olelo
33
33
  end
34
34
  end
35
35
 
36
- class BlockFile < ::File
37
- alias to_path path
38
-
39
- def each
40
- rewind
41
- while part = read(8192)
42
- yield part
43
- end
44
- end
45
- end
46
-
47
36
  module Util
48
37
  def self.included(base)
49
38
  base.extend(Util)
@@ -51,6 +40,10 @@ module Olelo
51
40
 
52
41
  extend self
53
42
 
43
+ def no_cache?(env = @env)
44
+ env['HTTP_PRAGMA'] == 'no-cache' || env['HTTP_CACHE_CONTROL'].to_s.include?('no-cache')
45
+ end
46
+
54
47
  def check
55
48
  errors = []
56
49
  yield(errors)
data/lib/olelo/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Olelo
2
- VERSION = '0.9.2'
2
+ VERSION = '0.9.3'
3
3
  end
@@ -12,18 +12,14 @@ module Olelo
12
12
  raise NotImplementedError
13
13
  end
14
14
 
15
- def open(name)
16
- [read(name)]
15
+ def real_path(name)
16
+ nil
17
17
  end
18
18
 
19
19
  def size(name)
20
20
  read(name).bytesize
21
21
  end
22
22
 
23
- def mime(name)
24
- MimeMagic.by_path(name) || MimeMagic.new('application/octet-stream')
25
- end
26
-
27
23
  class VirtualFile
28
24
  attr_reader :fs, :name
29
25
 
@@ -35,8 +31,8 @@ module Olelo
35
31
  fs.read(name)
36
32
  end
37
33
 
38
- def open
39
- fs.open(name)
34
+ def real_path
35
+ fs.real_path(name)
40
36
  end
41
37
 
42
38
  def mtime
@@ -46,10 +42,6 @@ module Olelo
46
42
  def size
47
43
  @size ||= fs.size(name)
48
44
  end
49
-
50
- def mime
51
- @fs.mime(name)
52
- end
53
45
  end
54
46
 
55
47
  class Native < VirtualFS
@@ -59,31 +51,31 @@ module Olelo
59
51
 
60
52
  # @override
61
53
  def read(name)
62
- File.read(File.join(@dir, name))
54
+ File.read(real_path(name))
63
55
  end
64
56
 
65
57
  # @override
66
58
  def glob(*names)
67
59
  names.map do |name|
68
- Dir[File.join(@dir, name)].select {|f| File.file?(f) }
60
+ Dir[real_path(name)].select {|f| File.file?(f) }
69
61
  end.flatten.each do |f|
70
62
  yield(VirtualFile.new(self, f[@dir.length+1..-1]))
71
63
  end
72
64
  end
73
65
 
74
66
  # @override
75
- def open(name)
76
- BlockFile.open(File.join(@dir, name), 'rb')
67
+ def real_path(name)
68
+ File.join(@dir, name)
77
69
  end
78
70
 
79
71
  # @override
80
72
  def mtime(name)
81
- File.mtime(File.join(@dir, name))
73
+ File.mtime(real_path(name))
82
74
  end
83
75
 
84
76
  # @override
85
77
  def size(name)
86
- File.stat(File.join(@dir, name)).size
78
+ File.stat(real_path(name)).size
87
79
  end
88
80
  end
89
81
 
@@ -140,7 +132,7 @@ module Olelo
140
132
  @fs.each {|fs| fs.glob(*names, &block) }
141
133
  end
142
134
 
143
- %w(read mtime open size mime).each do |method|
135
+ %w(read mtime real_path size).each do |method|
144
136
  class_eval %{
145
137
  def #{method}(*args)
146
138
  result = nil
data/olelo.gemspec CHANGED
@@ -21,11 +21,14 @@ Gem::Specification.new do |s|
21
21
  s.add_runtime_dependency('slim', ['~> 1.3.3'])
22
22
  s.add_runtime_dependency('creole', ['~> 0.4.2'])
23
23
  s.add_runtime_dependency('nokogiri', ['~> 1.5.5'])
24
- s.add_runtime_dependency('mimemagic', ['~> 0.1.9'])
24
+ s.add_runtime_dependency('mimemagic', ['~> 0.2.0'])
25
25
  s.add_runtime_dependency('rack', ['~> 1.4.1'])
26
- s.add_runtime_dependency('redcarpet', ['~> 2.1.1'])
26
+ s.add_runtime_dependency('redcarpet', ['~> 2.2.1'])
27
27
  s.add_runtime_dependency('rugged', ['~> 0.17.0b6'])
28
+ s.add_runtime_dependency('evaluator', ['~> 0.1.6'])
28
29
 
29
30
  s.add_development_dependency('rake', ['>= 0.8.7'])
30
31
  s.add_development_dependency('sass', ['>= 3.1.0'])
32
+ s.add_development_dependency('bacon', ['~> 1.1.0'])
33
+ s.add_development_dependency('rack-test', ['~> 0.6.2'])
31
34
  end
@@ -11,6 +11,8 @@ en:
11
11
  aspect_subpages: 'Subpages'
12
12
  aspect_text: 'Text Download'
13
13
  aspect_gallery: 'Image Gallery'
14
+ aspect_s5: 'S5 Presentation'
15
+ aspect_latex: 'LaTeX'
14
16
  aspect_not_available: 'Aspect #{aspect} is not available for page #{page} with type #{type}.'
15
17
  entry: 'Entry'
16
18
  exif: 'EXIF Information'
@@ -31,6 +33,8 @@ de:
31
33
  aspect_subpages: 'Unterseiten'
32
34
  aspect_text: 'Quellcode herunterladen'
33
35
  aspect_gallery: 'Bildergalerie'
36
+ aspect_s5: 'S5 Präsentation'
37
+ aspect_latex: 'LaTeX'
34
38
  aspect_not_available: 'Aspekt #{aspect} für die Seite #{page} mit dem Typ #{type} ist nicht verfügbar.'
35
39
  entry: 'Eintrag'
36
40
  exif: 'EXIF-Information'
@@ -51,6 +55,7 @@ cs_CZ:
51
55
  aspect_subpages: 'Podstránky'
52
56
  aspect_text: 'Stažení textu'
53
57
  aspect_gallery: 'Galerie'
58
+ aspect_latex: 'LaTeX'
54
59
  aspect_not_available: 'Vzhled #{aspect} není k dispozici pro stránku #{page} s typem #{type}.'
55
60
  entry: 'Položka'
56
61
  exif: 'Informace EXIF'
@@ -60,6 +60,10 @@ class Aspect
60
60
  super(:aspect_not_available.t(:aspect => name, :page => page.path,
61
61
  :type => "#{page.mime.comment} (#{page.mime})"))
62
62
  end
63
+
64
+ def status
65
+ :bad_request
66
+ end
63
67
  end
64
68
 
65
69
  # Constructor for aspect
@@ -142,7 +146,7 @@ end
142
146
  # Plug-in the aspect subsystem
143
147
  module ::Olelo::PageHelper
144
148
  def render_page(page)
145
- Cache.cache("include-#{page.path}-#{page.version.cache_id}", :update => request.no_cache?, :defer => true) do |context|
149
+ Cache.cache("include-#{page.path}-#{page.version.cache_id}", :update => no_cache?, :defer => true) do |context|
146
150
  begin
147
151
  context = Context.new(:page => page, :params => {:included => true})
148
152
  Aspect.find!(page, :layout => true).call(context, page)
@@ -159,7 +163,7 @@ class ::Olelo::Application
159
163
  params[:aspect] ||= 'subpages' if params[:path].to_s.ends_with? '/'
160
164
  @selected_aspect, layout, header, content =
161
165
  Cache.cache("aspect-#{page.path}-#{page.version.cache_id}-#{build_query(params)}",
162
- :update => request.no_cache?, :defer => true) do |cache|
166
+ :update => no_cache?, :defer => true) do |cache|
163
167
  aspect = Aspect.find!(page, :name => params[:aspect])
164
168
  cache.disable! if !aspect.cacheable?
165
169
  context = Context.new(:page => page, :params => params, :request => request)
@@ -171,7 +175,7 @@ class ::Olelo::Application
171
175
  self.response.header.merge!(header)
172
176
 
173
177
  @menu_versions = true
174
- halt(layout ? render(:show, :locals => {:content => content}) : content)
178
+ layout ? render(:show, :locals => {:content => content}) : content
175
179
  rescue Aspect::NotAvailable => ex
176
180
  cache_control :no_cache => true
177
181
  redirect build_path(page.path) if params[:path].to_s.ends_with? '/'
@@ -183,7 +187,7 @@ class ::Olelo::Application
183
187
  hook :menu do |menu|
184
188
  if menu.name == :actions && view_menu = menu[:view]
185
189
  Cache.cache("aspect-menu-#{page.path}-#{page.version.cache_id}-#{@selected_aspect}",
186
- :update => request.no_cache?, :defer => true) do
190
+ :update => no_cache?, :defer => true) do
187
191
  aspects = Aspect.find_all(page).select {|a| !a.hidden? || a.name == @selected_aspect || a.name == page.attributes['aspect'] }.map do |a|
188
192
  [Locale.translate("aspect_#{a.name}", :fallback => titlecase(a.name)), a]
189
193
  end.sort_by(&:first)
@@ -25,7 +25,7 @@ class YamlfileService < User::Service
25
25
  end
26
26
 
27
27
  # @override
28
- def create(user, password)
28
+ def signup(user, password)
29
29
  @store.transaction do |store|
30
30
  raise :user_already_exists.t(:name => user.name) if store[user.name]
31
31
  store[user.name] = {
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.cache("blog-#{page.path}-#{page.version.cache_id}", :update => context.request.no_cache?, :defer => true) do
13
+ Cache.cache("blog-#{page.path}-#{page.version.cache_id}", :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
@@ -36,10 +36,10 @@ Aspects::Aspect.create(:blog, :priority => 3, :layout => true, :cacheable => tru
36
36
  @page_count = articles.size / per_page + 1
37
37
  articles = articles[((@page_nr - 1) * per_page) ... (@page_nr * per_page)].to_a
38
38
 
39
- @articles = articles.map do |page|
39
+ @articles = articles.map do |article|
40
40
  begin
41
- subctx = context.subcontext(:page => page, :params => {:included => true})
42
- content = Aspects::Aspect.find!(page, :layout => true).call(subctx, page)
41
+ subctx = context.subcontext(:page => article, :params => {:included => true})
42
+ content = Aspects::Aspect.find!(article, :layout => true).call(subctx, article)
43
43
  if !context.params[:full]
44
44
  paragraphs = XML::Fragment(content).xpath('p')
45
45
  content = ''
@@ -51,7 +51,7 @@ Aspects::Aspect.create(:blog, :priority => 3, :layout => true, :cacheable => tru
51
51
  rescue Aspects::Aspect::NotAvailable => ex
52
52
  %{<span class="error">#{escape_html ex.message}</span>}
53
53
  end
54
- [page, content]
54
+ [article, content]
55
55
  end
56
56
  render :blog, :locals => {:full => context.params[:full]}
57
57
  end
@@ -0,0 +1,17 @@
1
+ $(function() {
2
+ var textarea = $('#edit-content');
3
+ if (textarea.length == 1) {
4
+ textarea.hide().before('<div id="ace-editor" style="position:relative; width:100%; height: 40em"/>');
5
+ var editor = ace.edit('ace-editor');
6
+ var modes = {
7
+ 'text/x-markdown': 'markdown',
8
+ 'text/x-textile': 'textile'
9
+ };
10
+ if (window.Olelo && modes[Olelo.page_mime])
11
+ editor.getSession().setMode('ace/mode/' + modes[Olelo.page_mime]);
12
+ editor.getSession().setValue(textarea.val());
13
+ $('form').submit(function() {
14
+ textarea.val(editor.getSession().getValue());
15
+ });
16
+ }
17
+ });