olelo 0.9.2 → 0.9.3

Sign up to get free protection for your applications and to get access to all the features.
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
+ });