microengine 0.0.1
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/LICENSE +674 -0
- data/README +102 -0
- data/Rakefile +67 -0
- data/access.log +1 -0
- data/bin/microengine +0 -0
- data/content/403/en.body +2 -0
- data/content/403/en.header +1 -0
- data/content/403/layout +1 -0
- data/content/403/ru.body +2 -0
- data/content/403/ru.header +1 -0
- data/content/404/en.body +5 -0
- data/content/404/en.header +1 -0
- data/content/404/layout +1 -0
- data/content/404/ru.body +5 -0
- data/content/404/ru.header +1 -0
- data/content/WARNING +2 -0
- data/content/en.body +2 -0
- data/content/en.header +1 -0
- data/content/layout +1 -0
- data/content/ru.body +2 -0
- data/content/ru.header +1 -0
- data/layouts/WARNING +2 -0
- data/layouts/default/en.yaml +7 -0
- data/layouts/default/layout.rhtml +18 -0
- data/layouts/default/ru.yaml +7 -0
- data/lib/microengine/admin.rb +268 -0
- data/lib/microengine/admin_exception.rb +31 -0
- data/lib/microengine/admin_page.rb +199 -0
- data/lib/microengine/assambler.rb +192 -0
- data/lib/microengine/dispatcher.rb +125 -0
- data/lib/microengine/file_cache.rb +62 -0
- data/lib/microengine/html/deleter.rhtml +11 -0
- data/lib/microengine/html/editor.rhtml +34 -0
- data/lib/microengine/html/en.yaml +33 -0
- data/lib/microengine/html/error.rhtml +6 -0
- data/lib/microengine/html/refresher.rhtml +7 -0
- data/lib/microengine/html/ru.yaml +33 -0
- data/lib/microengine/html/untranslater.rhtml +11 -0
- data/lib/microengine/http.rb +213 -0
- data/lib/microengine/initializer.rb +93 -0
- data/lib/microengine/memory_cache.rb +53 -0
- data/password +20 -0
- data/public/microengine.fcgi +5 -0
- data/public/styles/handheld.css +0 -0
- data/public/styles/print.css +3 -0
- data/public/styles/screen.css +18 -0
- metadata +106 -0
@@ -0,0 +1,31 @@
|
|
1
|
+
=begin
|
2
|
+
Logic to edit site from web interface.
|
3
|
+
Copyright (C) 2008 Andrey "A.I." Sitnik <andrey@sitnik.ru>
|
4
|
+
|
5
|
+
This program is free software: you can redistribute it and/or modify
|
6
|
+
it under the terms of the GNU General Public License as published by
|
7
|
+
the Free Software Foundation, either version 3 of the License, or
|
8
|
+
(at your option) any later version.
|
9
|
+
|
10
|
+
This program is distributed in the hope that it will be useful,
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
GNU General Public License for more details.
|
14
|
+
|
15
|
+
You should have received a copy of the GNU General Public License
|
16
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
=end
|
18
|
+
|
19
|
+
module Microengine
|
20
|
+
# Exception in admin page ot action.
|
21
|
+
# Contain message and code to translate message in error page.
|
22
|
+
class AdminException < Exception
|
23
|
+
|
24
|
+
attr_reader :code
|
25
|
+
|
26
|
+
def initialize(msg = nil, code = nil)
|
27
|
+
super(msg)
|
28
|
+
@code = code
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,199 @@
|
|
1
|
+
=begin
|
2
|
+
Logic to edit site from web interface.
|
3
|
+
Copyright (C) 2008 Andrey "A.I." Sitnik <andrey@sitnik.ru>
|
4
|
+
|
5
|
+
This program is free software: you can redistribute it and/or modify
|
6
|
+
it under the terms of the GNU General Public License as published by
|
7
|
+
the Free Software Foundation, either version 3 of the License, or
|
8
|
+
(at your option) any later version.
|
9
|
+
|
10
|
+
This program is distributed in the hope that it will be useful,
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
GNU General Public License for more details.
|
14
|
+
|
15
|
+
You should have received a copy of the GNU General Public License
|
16
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
=end
|
18
|
+
|
19
|
+
module Microengine
|
20
|
+
# Admin interface
|
21
|
+
class AdminPage
|
22
|
+
|
23
|
+
def initialize(http, path, admin)
|
24
|
+
@http = http
|
25
|
+
@path = '/' + path
|
26
|
+
@admin = admin
|
27
|
+
@show_password = http.cookie['password'].nil?
|
28
|
+
|
29
|
+
#TODO Layout for /admin/refresh/
|
30
|
+
if not @http.post['layout'].nil?
|
31
|
+
@layout = @admin.config['default_layout']
|
32
|
+
elsif File.exists? MICROENGINE_ROOT + "/content#{@path}layout"
|
33
|
+
begin
|
34
|
+
@layout = IO.read MICROENGINE_ROOT + "/content#{@path}layout"
|
35
|
+
rescue
|
36
|
+
@layout = @admin.config['default_layout']
|
37
|
+
end
|
38
|
+
else
|
39
|
+
@layout = @admin.config['default_layout']
|
40
|
+
end
|
41
|
+
@layout_langs = []
|
42
|
+
Dir.glob(MICROENGINE_ROOT + "/layouts/#{@layout}/*.yaml") do |lang|
|
43
|
+
@layout_langs.push File.basename(lang, '.yaml')
|
44
|
+
end
|
45
|
+
|
46
|
+
@lang = language
|
47
|
+
load_translation
|
48
|
+
end
|
49
|
+
|
50
|
+
# Show interface to edit page
|
51
|
+
def editor
|
52
|
+
if '/admin/' == @path[0..6]
|
53
|
+
error 'admin_subdir'
|
54
|
+
return
|
55
|
+
end
|
56
|
+
|
57
|
+
if not File.exists? MICROENGINE_ROOT + "/layouts/#{@layout}/#{@lang}.yaml"
|
58
|
+
@old_lang = @lang
|
59
|
+
@lang = @admin.dispatcher.language(@http, @layout_langs)
|
60
|
+
error 'untranslated_layout'
|
61
|
+
return
|
62
|
+
end
|
63
|
+
|
64
|
+
@layouts = []
|
65
|
+
@untranslated_layouts = {}
|
66
|
+
if @admin.cache.langs[@path].nil?
|
67
|
+
langs = [@lang]
|
68
|
+
else
|
69
|
+
langs = @admin.cache.langs[@path] + [@lang]
|
70
|
+
end
|
71
|
+
Dir.glob(MICROENGINE_ROOT + '/layouts/*/layout.rhtml') do |file|
|
72
|
+
layout = file.split('/')[-2]
|
73
|
+
@layouts.push layout
|
74
|
+
layout_langs = []
|
75
|
+
Dir.glob(MICROENGINE_ROOT + "/layouts/#{layout}/*.yaml") do |lang|
|
76
|
+
layout_langs.push File.basename(lang, '.yaml')
|
77
|
+
end
|
78
|
+
untranslated = langs - layout_langs
|
79
|
+
if not untranslated.empty?
|
80
|
+
@untranslated_layouts[layout] = untranslated
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
if @http.post['body'].nil?
|
85
|
+
begin
|
86
|
+
@body = IO.read MICROENGINE_ROOT + "/content#{@path}#{@lang}.body"
|
87
|
+
rescue
|
88
|
+
@body = ''
|
89
|
+
end
|
90
|
+
else
|
91
|
+
@body = @http.post['body']
|
92
|
+
end
|
93
|
+
|
94
|
+
if @http.post['header'].nil?
|
95
|
+
begin
|
96
|
+
@header = IO.read MICROENGINE_ROOT + "/content#{@path}#{@lang}.header"
|
97
|
+
rescue
|
98
|
+
@header = ''
|
99
|
+
end
|
100
|
+
else
|
101
|
+
@header = @http.post['header']
|
102
|
+
end
|
103
|
+
|
104
|
+
display 'editor'
|
105
|
+
end
|
106
|
+
|
107
|
+
# Show interface to delete page
|
108
|
+
def deleter
|
109
|
+
if '/admin/' == @path[0..6]
|
110
|
+
error 'admin_subdir'
|
111
|
+
return
|
112
|
+
end
|
113
|
+
if @admin.cache.langs[@path].nil?
|
114
|
+
@admin.dispatcher.not_found @http
|
115
|
+
return
|
116
|
+
end
|
117
|
+
if ['/404/', '/403/', '/'].include? @path
|
118
|
+
error 'delete_system'
|
119
|
+
return
|
120
|
+
end
|
121
|
+
@body = IO.read MICROENGINE_ROOT + "/content#{@path}#{@lang}.body"
|
122
|
+
display 'deleter'
|
123
|
+
end
|
124
|
+
|
125
|
+
# Show interface to delete translation
|
126
|
+
def untranslater
|
127
|
+
if '/admin/' == @path[0..6]
|
128
|
+
error 'admin_subdir'
|
129
|
+
return
|
130
|
+
end
|
131
|
+
if @admin.cache.langs[@path].nil?
|
132
|
+
@admin.dispatcher.not_found @http
|
133
|
+
return
|
134
|
+
end
|
135
|
+
|
136
|
+
@body = IO.read MICROENGINE_ROOT + "/content#{@path}#{@lang}.body"
|
137
|
+
display 'untranslater'
|
138
|
+
end
|
139
|
+
|
140
|
+
# Show interface to input password for refresh cache
|
141
|
+
def refresher
|
142
|
+
display 'refresher'
|
143
|
+
end
|
144
|
+
|
145
|
+
# Error
|
146
|
+
def error(code)
|
147
|
+
@code = code
|
148
|
+
display 'error'
|
149
|
+
end
|
150
|
+
|
151
|
+
private
|
152
|
+
|
153
|
+
# Return page language to admin action
|
154
|
+
def language
|
155
|
+
if @http.get['lang'].nil?
|
156
|
+
langs = @admin.cache.langs[@path]
|
157
|
+
if langs.nil?
|
158
|
+
langs = @layout_langs
|
159
|
+
end
|
160
|
+
@admin.dispatcher.language(@http, langs)
|
161
|
+
else
|
162
|
+
@http.get['lang']
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def load_translation
|
167
|
+
@admin_langs = []
|
168
|
+
Dir.glob(MICROENGINE_ROOT + '/lib/microengine/html/*.yaml') do |file|
|
169
|
+
@admin_langs.push File.basename(file, '.yaml')
|
170
|
+
end
|
171
|
+
|
172
|
+
if @admin_langs.include? @lang
|
173
|
+
lang = @lang
|
174
|
+
else
|
175
|
+
lang = @admin.dispatcher.language(@http, @admin_langs)
|
176
|
+
end
|
177
|
+
|
178
|
+
@translation = YAML::load_file MICROENGINE_ROOT + "/lib/microengine/html/#{lang}.yaml"
|
179
|
+
end
|
180
|
+
|
181
|
+
# Display admin HTML in page layout
|
182
|
+
def display(view)
|
183
|
+
header = "<title>#{@translation[view]['title']}</title>"
|
184
|
+
rhtml = IO.read MICROENGINE_ROOT + "/lib/microengine/html/#{view}.rhtml"
|
185
|
+
body = ERB.new(rhtml).result(binding)
|
186
|
+
|
187
|
+
if 'editor' == view
|
188
|
+
langs = @layout_langs
|
189
|
+
elsif 'error' == view
|
190
|
+
langs = []
|
191
|
+
else
|
192
|
+
langs = @admin.cache.langs[@path]
|
193
|
+
end
|
194
|
+
|
195
|
+
@http << @admin.assambler.assamble(@path, @layout, @lang, header, body, langs)
|
196
|
+
end
|
197
|
+
|
198
|
+
end
|
199
|
+
end
|
@@ -0,0 +1,192 @@
|
|
1
|
+
=begin
|
2
|
+
Create XHTML pages from layouts and content.
|
3
|
+
Copyright (C) 2008 Andrey "A.I." Sitnik <andrey@sitnik.ru>
|
4
|
+
|
5
|
+
This program is free software: you can redistribute it and/or modify
|
6
|
+
it under the terms of the GNU General Public License as published by
|
7
|
+
the Free Software Foundation, either version 3 of the License, or
|
8
|
+
(at your option) any later version.
|
9
|
+
|
10
|
+
This program is distributed in the hope that it will be useful,
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
GNU General Public License for more details.
|
14
|
+
|
15
|
+
You should have received a copy of the GNU General Public License
|
16
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
=end
|
18
|
+
|
19
|
+
require 'erb'
|
20
|
+
require 'yaml'
|
21
|
+
require 'fileutils'
|
22
|
+
|
23
|
+
module Microengine
|
24
|
+
# Create XHTML pages from layouts and content
|
25
|
+
class Assambler
|
26
|
+
|
27
|
+
attr_writer :config
|
28
|
+
attr_writer :logger
|
29
|
+
|
30
|
+
# Create XHTML pages from layouts and content
|
31
|
+
def refresh
|
32
|
+
@layouts = {}
|
33
|
+
|
34
|
+
begin
|
35
|
+
if not File.directory? MICROENGINE_ROOT + '/cache/'
|
36
|
+
FileUtils.mkdir MICROENGINE_ROOT + '/cache/'
|
37
|
+
end
|
38
|
+
FileUtils.rm_r Dir.glob(MICROENGINE_ROOT + '/cache/*')
|
39
|
+
rescue
|
40
|
+
raise "Can't delete and create /cache/ dir. Ensure that it is chmod 0666."
|
41
|
+
end
|
42
|
+
|
43
|
+
cache_dir '/'
|
44
|
+
end
|
45
|
+
|
46
|
+
# Cache content for some lang in path
|
47
|
+
def cache_file(path, lang, langs)
|
48
|
+
file_path = MICROENGINE_ROOT + '/content' + path
|
49
|
+
|
50
|
+
begin
|
51
|
+
layout = IO.read(file_path + 'layout').strip
|
52
|
+
rescue
|
53
|
+
raise "Can't read layout file in /content#{path}. Please ensure that #{path}layout exists and is chmod 644"
|
54
|
+
end
|
55
|
+
begin
|
56
|
+
header = IO.read(file_path + lang + '.header')
|
57
|
+
rescue
|
58
|
+
raise "Can't read #{lang}.header file in /content#{path}. Please ensure that #{path}#{lang}.header exists and is chmod 644"
|
59
|
+
end
|
60
|
+
begin
|
61
|
+
body = IO.read(file_path + lang + '.body')
|
62
|
+
rescue
|
63
|
+
raise "Can't read #{lang}.body file in /content#{path}. Please ensure that #{path}#{lang}.body exists and is chmod 644"
|
64
|
+
end
|
65
|
+
|
66
|
+
begin
|
67
|
+
content = assamble path, layout, lang, header, body, langs
|
68
|
+
rescue Exception => e
|
69
|
+
raise "Error in /content#{path}: " + e.message
|
70
|
+
end
|
71
|
+
|
72
|
+
begin
|
73
|
+
io = File.new(MICROENGINE_ROOT + "/cache#{path}content.#{lang}.html", 'w')
|
74
|
+
io.write content
|
75
|
+
io.close
|
76
|
+
rescue
|
77
|
+
raise "Can't write to /cache#{path}content.#{lang}.html . Ensure that /cache/ dir and all files inside is chmod 0666."
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# Create XHTML page by layout and content
|
82
|
+
def assamble(path, layout_name, lang, header, body, langs)
|
83
|
+
layout = get_layout layout_name
|
84
|
+
if layout[lang].nil?
|
85
|
+
raise "There isn't translation in '#{lang}' for #{layout_name}"
|
86
|
+
end
|
87
|
+
translation = layout[lang]
|
88
|
+
languages = languages_html langs, lang, layout
|
89
|
+
layout[:layout].result(binding)
|
90
|
+
end
|
91
|
+
|
92
|
+
private
|
93
|
+
|
94
|
+
# Create languages list HTML
|
95
|
+
def languages_html(langs, selected, translations)
|
96
|
+
html = '<ul id="languages">'
|
97
|
+
langs.sort.each do |lang|
|
98
|
+
if lang == selected
|
99
|
+
html += '<li><span class="selected">' + translations[lang]['language']['title'] + '</span></li>';
|
100
|
+
else
|
101
|
+
html += '<li><a href="?lang=' + lang + '">' + translations[lang]['language']['title'] + '</a></li>'
|
102
|
+
end
|
103
|
+
end
|
104
|
+
html += '</ul>'
|
105
|
+
end
|
106
|
+
|
107
|
+
# Cache directory and it's subdirectory of content
|
108
|
+
def cache_dir(dir)
|
109
|
+
path = MICROENGINE_ROOT + '/content' + dir
|
110
|
+
cache = MICROENGINE_ROOT + '/cache' + dir
|
111
|
+
if not File.directory? cache
|
112
|
+
begin
|
113
|
+
Dir.mkdir cache
|
114
|
+
rescue
|
115
|
+
raise "Can't create dir #{cache} . Please ensure that cache dir is chmod 0777."
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
langs = []
|
120
|
+
Dir.foreach path do |entry|
|
121
|
+
if '.' == entry[0..0]
|
122
|
+
next
|
123
|
+
elsif File.directory? path + entry + '/'
|
124
|
+
begin
|
125
|
+
cache_dir dir + entry + '/'
|
126
|
+
rescue
|
127
|
+
@logger.error e.message
|
128
|
+
end
|
129
|
+
elsif '.body' == entry[-5..-1]
|
130
|
+
langs.push entry[0..entry.index('.')-1].downcase
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
langs.each do |lang|
|
135
|
+
begin
|
136
|
+
cache_file dir, lang, langs
|
137
|
+
rescue Exception => e
|
138
|
+
@logger.error e.message
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
# Get hash with layouts XML object
|
144
|
+
def get_layout(name)
|
145
|
+
if @layouts[name].nil?
|
146
|
+
@layouts[name] = load_layout name
|
147
|
+
end
|
148
|
+
return @layouts[name]
|
149
|
+
end
|
150
|
+
|
151
|
+
# Load layout from XML file and create translated versions
|
152
|
+
def load_layout(name)
|
153
|
+
# Check name and layout
|
154
|
+
name = name.sub(/(^|\/)\.\.?/, '')
|
155
|
+
dir = MICROENGINE_ROOT + '/layouts/' + name + '/';
|
156
|
+
if not File.directory?(dir) or not File.exists? dir + 'layout.rhtml'
|
157
|
+
raise "Can't find layout #{name} ."
|
158
|
+
end
|
159
|
+
|
160
|
+
# Load layout
|
161
|
+
layout = {
|
162
|
+
:layout => ERB::new(IO.read(dir + 'layout.rhtml'))
|
163
|
+
}
|
164
|
+
|
165
|
+
# Load translation
|
166
|
+
Dir.glob(dir + '**.yaml') do |file|
|
167
|
+
lang = File.basename file, '.yaml'
|
168
|
+
if 'layout' == lang
|
169
|
+
next
|
170
|
+
end
|
171
|
+
layout[lang] = load_translation(file)
|
172
|
+
end
|
173
|
+
layout
|
174
|
+
end
|
175
|
+
|
176
|
+
# Load translation
|
177
|
+
def load_translation(file)
|
178
|
+
translation = YAML::load_file(file)
|
179
|
+
lang = File.basename(file, '.yaml')
|
180
|
+
|
181
|
+
# Restore require fields if necessary
|
182
|
+
if translation['language'].nil? or translation['language']['title'].nil?
|
183
|
+
translation['language'] = {'code' => lang, 'title' => lang}
|
184
|
+
else
|
185
|
+
if lang != translation['language']['code']
|
186
|
+
translation['language']['code'] = lang
|
187
|
+
end
|
188
|
+
end
|
189
|
+
translation
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
=begin
|
2
|
+
FastCGI dispatcher to return XHTML pages by HTTP request.
|
3
|
+
Copyright (C) 2008 Andrey "A.I." Sitnik <andrey@sitnik.ru>
|
4
|
+
|
5
|
+
This program is free software: you can redistribute it and/or modify
|
6
|
+
it under the terms of the GNU General Public License as published by
|
7
|
+
the Free Software Foundation, either version 3 of the License, or
|
8
|
+
(at your option) any later version.
|
9
|
+
|
10
|
+
This program is distributed in the hope that it will be useful,
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
GNU General Public License for more details.
|
14
|
+
|
15
|
+
You should have received a copy of the GNU General Public License
|
16
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
=end
|
18
|
+
|
19
|
+
require 'fcgi'
|
20
|
+
require 'admin'
|
21
|
+
require 'http'
|
22
|
+
|
23
|
+
module Microengine
|
24
|
+
# Use FastCGI to return XHTML by HTTP request
|
25
|
+
class Dispatcher
|
26
|
+
|
27
|
+
attr_writer :config
|
28
|
+
attr_writer :logger
|
29
|
+
attr_writer :spiders
|
30
|
+
attr_writer :cache
|
31
|
+
attr_writer :admin
|
32
|
+
|
33
|
+
# Start FastCGI
|
34
|
+
def run
|
35
|
+
FCGI.each do |request|
|
36
|
+
http = HTTP.new(request)
|
37
|
+
|
38
|
+
if @admin.dispatch(http)
|
39
|
+
request.finish
|
40
|
+
next
|
41
|
+
else
|
42
|
+
langs = @cache.langs[http.url]
|
43
|
+
if langs.nil?
|
44
|
+
not_found http
|
45
|
+
request.finish
|
46
|
+
next
|
47
|
+
end
|
48
|
+
|
49
|
+
if spider? http.agent
|
50
|
+
# Search engine spiders (another i18n logic)
|
51
|
+
if http.get['lang'].nil?
|
52
|
+
if langs.include? http.get['lang']
|
53
|
+
http << @cache.get(http.url, http.get['lang'])
|
54
|
+
request.finish
|
55
|
+
next
|
56
|
+
end
|
57
|
+
end
|
58
|
+
http.redirect http.url + '?lang=' + language(http, langs)
|
59
|
+
else
|
60
|
+
# Human visitor
|
61
|
+
if http.get['lang']
|
62
|
+
http.set_cookie 'lang', http.get['lang'], 30
|
63
|
+
if not langs.include? http.get['lang']
|
64
|
+
http.redirect http.url
|
65
|
+
request.finish
|
66
|
+
next
|
67
|
+
end
|
68
|
+
end
|
69
|
+
http << @cache.get(http.url, language(http, langs))
|
70
|
+
end
|
71
|
+
request.finish
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# Forward to 404 error
|
77
|
+
def not_found(http)
|
78
|
+
http.status = '404 Not Found'
|
79
|
+
http << @cache.get('/404/', language(http, @cache.langs['/404/']))
|
80
|
+
http.finish
|
81
|
+
end
|
82
|
+
|
83
|
+
# Select best language for user
|
84
|
+
def language(http, available)
|
85
|
+
# Language selected manually
|
86
|
+
if not http.get['lang'].nil?
|
87
|
+
if available.include? http.get['lang']
|
88
|
+
return http.get['lang']
|
89
|
+
end
|
90
|
+
elsif http.cookie['lang']
|
91
|
+
if available.include? http.cookie['lang']
|
92
|
+
return http.cookie['lang']
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# Select user language
|
97
|
+
http.langs.each do |lang|
|
98
|
+
lang.downcase!
|
99
|
+
if available.include? lang
|
100
|
+
return lang
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# Select any language
|
105
|
+
if available.include? @config['default_language']
|
106
|
+
@config['default_language']
|
107
|
+
else
|
108
|
+
available.first
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
private
|
113
|
+
|
114
|
+
# Check HTTP_USER_AGENT value for search engine spiders
|
115
|
+
def spider?(agent)
|
116
|
+
@spiders.each do |spider|
|
117
|
+
if agent.include? spider
|
118
|
+
return true
|
119
|
+
end
|
120
|
+
end
|
121
|
+
false
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
end
|