rethoth 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +26 -0
- data/bin/thoth +233 -0
- data/lib/proto/config.ru +45 -0
- data/lib/proto/thoth.conf.sample +206 -0
- data/lib/thoth/cache.rb +53 -0
- data/lib/thoth/config.rb +158 -0
- data/lib/thoth/controller/admin.rb +75 -0
- data/lib/thoth/controller/api/comment.rb +73 -0
- data/lib/thoth/controller/api/page.rb +134 -0
- data/lib/thoth/controller/api/post.rb +122 -0
- data/lib/thoth/controller/api/tag.rb +59 -0
- data/lib/thoth/controller/archive.rb +50 -0
- data/lib/thoth/controller/comment.rb +173 -0
- data/lib/thoth/controller/main.rb +193 -0
- data/lib/thoth/controller/media.rb +172 -0
- data/lib/thoth/controller/page.rb +167 -0
- data/lib/thoth/controller/post.rb +310 -0
- data/lib/thoth/controller/search.rb +86 -0
- data/lib/thoth/controller/tag.rb +107 -0
- data/lib/thoth/controller.rb +48 -0
- data/lib/thoth/errors.rb +35 -0
- data/lib/thoth/helper/admin.rb +86 -0
- data/lib/thoth/helper/cookie.rb +45 -0
- data/lib/thoth/helper/error.rb +122 -0
- data/lib/thoth/helper/pagination.rb +131 -0
- data/lib/thoth/helper/wiki.rb +77 -0
- data/lib/thoth/helper/ysearch.rb +89 -0
- data/lib/thoth/importer/pants.rb +81 -0
- data/lib/thoth/importer/poseidon.rb +54 -0
- data/lib/thoth/importer/thoth.rb +103 -0
- data/lib/thoth/importer.rb +131 -0
- data/lib/thoth/layout/default.rhtml +47 -0
- data/lib/thoth/middleware/minify.rb +82 -0
- data/lib/thoth/migrate/001_create_schema.rb +108 -0
- data/lib/thoth/migrate/002_add_media_size.rb +37 -0
- data/lib/thoth/migrate/003_add_post_draft.rb +38 -0
- data/lib/thoth/migrate/004_add_comment_email.rb +37 -0
- data/lib/thoth/migrate/005_add_page_position.rb +37 -0
- data/lib/thoth/migrate/006_add_comment_close_delete.rb +43 -0
- data/lib/thoth/migrate/007_add_comment_summary.rb +37 -0
- data/lib/thoth/model/comment.rb +216 -0
- data/lib/thoth/model/media.rb +87 -0
- data/lib/thoth/model/page.rb +204 -0
- data/lib/thoth/model/post.rb +262 -0
- data/lib/thoth/model/tag.rb +80 -0
- data/lib/thoth/model/tags_posts_map.rb +34 -0
- data/lib/thoth/monkeypatch/sequel/model/errors.rb +37 -0
- data/lib/thoth/plugin/thoth_delicious.rb +105 -0
- data/lib/thoth/plugin/thoth_flickr.rb +86 -0
- data/lib/thoth/plugin/thoth_pinboard.rb +98 -0
- data/lib/thoth/plugin/thoth_tags.rb +68 -0
- data/lib/thoth/plugin/thoth_twitter.rb +175 -0
- data/lib/thoth/plugin.rb +59 -0
- data/lib/thoth/public/css/admin.css +223 -0
- data/lib/thoth/public/css/thoth.css +592 -0
- data/lib/thoth/public/images/admin-sprite.png +0 -0
- data/lib/thoth/public/images/thoth-sprite.png +0 -0
- data/lib/thoth/public/js/admin/comments.js +116 -0
- data/lib/thoth/public/js/admin/name.js +244 -0
- data/lib/thoth/public/js/admin/tagcomplete.js +332 -0
- data/lib/thoth/public/js/lazyload-min.js +4 -0
- data/lib/thoth/public/js/thoth.js +203 -0
- data/lib/thoth/public/robots.txt +5 -0
- data/lib/thoth/version.rb +37 -0
- data/lib/thoth/view/admin/index.rhtml +1 -0
- data/lib/thoth/view/admin/login.rhtml +23 -0
- data/lib/thoth/view/admin/toolbar.rhtml +117 -0
- data/lib/thoth/view/admin/welcome.rhtml +58 -0
- data/lib/thoth/view/archive/index.rhtml +24 -0
- data/lib/thoth/view/comment/comment.rhtml +47 -0
- data/lib/thoth/view/comment/delete.rhtml +15 -0
- data/lib/thoth/view/comment/form.rhtml +81 -0
- data/lib/thoth/view/comment/index.rhtml +68 -0
- data/lib/thoth/view/comment/list.rhtml +48 -0
- data/lib/thoth/view/media/delete.rhtml +15 -0
- data/lib/thoth/view/media/edit.rhtml +12 -0
- data/lib/thoth/view/media/form.rhtml +7 -0
- data/lib/thoth/view/media/list.rhtml +35 -0
- data/lib/thoth/view/media/media.rhtml +44 -0
- data/lib/thoth/view/media/new.rhtml +7 -0
- data/lib/thoth/view/page/delete.rhtml +15 -0
- data/lib/thoth/view/page/edit.rhtml +15 -0
- data/lib/thoth/view/page/form.rhtml +57 -0
- data/lib/thoth/view/page/index.rhtml +9 -0
- data/lib/thoth/view/page/list.rhtml +49 -0
- data/lib/thoth/view/page/new.rhtml +15 -0
- data/lib/thoth/view/post/comments.rhtml +12 -0
- data/lib/thoth/view/post/compact.rhtml +48 -0
- data/lib/thoth/view/post/delete.rhtml +15 -0
- data/lib/thoth/view/post/edit.rhtml +15 -0
- data/lib/thoth/view/post/form.rhtml +83 -0
- data/lib/thoth/view/post/index.rhtml +48 -0
- data/lib/thoth/view/post/list.rhtml +61 -0
- data/lib/thoth/view/post/new.rhtml +15 -0
- data/lib/thoth/view/post/tiny.rhtml +4 -0
- data/lib/thoth/view/search/index.rhtml +45 -0
- data/lib/thoth/view/tag/index.rhtml +34 -0
- data/lib/thoth/view/thoth/css.rhtml +9 -0
- data/lib/thoth/view/thoth/footer.rhtml +15 -0
- data/lib/thoth/view/thoth/header.rhtml +23 -0
- data/lib/thoth/view/thoth/index.rhtml +11 -0
- data/lib/thoth/view/thoth/js.rhtml +6 -0
- data/lib/thoth/view/thoth/sidebar.rhtml +38 -0
- data/lib/thoth/view/thoth/util/pager.rhtml +23 -0
- data/lib/thoth/view/thoth/util/simple_pager.rhtml +15 -0
- data/lib/thoth/view/thoth/util/table_sortheader.rhtml +20 -0
- data/lib/thoth.rb +394 -0
- metadata +409 -0
data/lib/thoth.rb
ADDED
@@ -0,0 +1,394 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2017 John Pagonis <john@pagonis.org>
|
3
|
+
# Copyright (c) 2009 Ryan Grove <ryan@wonko.com>
|
4
|
+
# All rights reserved.
|
5
|
+
#
|
6
|
+
# Redistribution and use in source and binary forms, with or without
|
7
|
+
# modification, are permitted provided that the following conditions are met:
|
8
|
+
#
|
9
|
+
# * Redistributions of source code must retain the above copyright notice,
|
10
|
+
# this list of conditions and the following disclaimer.
|
11
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
12
|
+
# this list of conditions and the following disclaimer in the documentation
|
13
|
+
# and/or other materials provided with the distribution.
|
14
|
+
# * Neither the name of this project nor the names of its contributors may be
|
15
|
+
# used to endorse or promote products derived from this software without
|
16
|
+
# specific prior written permission.
|
17
|
+
#
|
18
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
19
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
20
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
21
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
22
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
23
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
24
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
25
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
26
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
27
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
28
|
+
#++
|
29
|
+
|
30
|
+
# Prepend this file's directory to the include path if it's not there already.
|
31
|
+
$:.unshift(File.dirname(File.expand_path(__FILE__)))
|
32
|
+
$:.uniq!
|
33
|
+
|
34
|
+
require 'fileutils'
|
35
|
+
|
36
|
+
require 'builder'
|
37
|
+
require 'cssmin'
|
38
|
+
require 'erubis'
|
39
|
+
require 'jsmin'
|
40
|
+
require 'json'
|
41
|
+
require 'ramaze'
|
42
|
+
require 'redcloth'
|
43
|
+
require 'sanitize'
|
44
|
+
require 'sequel'
|
45
|
+
require 'sequel/extensions/migration'
|
46
|
+
require 'sequel/extensions/pagination'
|
47
|
+
require 'time'
|
48
|
+
require 'yaml'
|
49
|
+
|
50
|
+
# The main Thoth namespace.
|
51
|
+
module Thoth
|
52
|
+
HOME_DIR = ENV['THOTH_HOME'] || File.expand_path('.') unless const_defined?(:HOME_DIR)
|
53
|
+
LIB_DIR = File.join(File.dirname(File.expand_path(__FILE__)), 'thoth')
|
54
|
+
PUBLIC_DIR = File.join(LIB_DIR, 'public') unless const_defined?(:PUBLIC_DIR)
|
55
|
+
VIEW_DIR = File.join(LIB_DIR, 'view') unless const_defined?(:VIEW_DIR)
|
56
|
+
|
57
|
+
# Thoth Helper namespace.
|
58
|
+
module Helper; end
|
59
|
+
end
|
60
|
+
|
61
|
+
module Thoth
|
62
|
+
# LIFTED from old Ramaze.acquire
|
63
|
+
# Require all .rb and .so files on the given globs, utilizes Dir::[].
|
64
|
+
#
|
65
|
+
# Examples:
|
66
|
+
# # Given following directory structure:
|
67
|
+
# # src/foo.rb
|
68
|
+
# # src/bar.so
|
69
|
+
# # src/foo.yaml
|
70
|
+
# # src/foobar/baz.rb
|
71
|
+
# # src/foobar/README
|
72
|
+
#
|
73
|
+
# # requires all files in 'src':
|
74
|
+
# Ramaze.acquire 'src/*'
|
75
|
+
#
|
76
|
+
# # requires all files in 'src' recursive:
|
77
|
+
# Ramaze.acquire 'src/**/*'
|
78
|
+
#
|
79
|
+
# # require 'src/foo.rb' and 'src/bar.so' and 'src/foobar/baz.rb'
|
80
|
+
# Ramaze.acquire 'src/*', 'src/foobar/*'
|
81
|
+
def self.acquire(*globs)
|
82
|
+
globs.flatten.each do |glob|
|
83
|
+
Dir[glob].each do |file|
|
84
|
+
require file if file =~ /\.(rb|so)$/
|
85
|
+
puts "#{file} loaded"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
# Lifted from old Ramaze, which was also lifter by Rack::Directory
|
92
|
+
# Stolen from Ramaze
|
93
|
+
FILESIZE_FORMAT = [
|
94
|
+
['%.1fT', 1 << 40],
|
95
|
+
['%.1fG', 1 << 30],
|
96
|
+
['%.1fM', 1 << 20],
|
97
|
+
['%.1fK', 1 << 10],
|
98
|
+
]
|
99
|
+
|
100
|
+
def self.filesize_format(int)
|
101
|
+
FILESIZE_FORMAT.each do |format, size|
|
102
|
+
return format % (int.to_f / size) if int >= size
|
103
|
+
end
|
104
|
+
|
105
|
+
"#{int}B"
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
require 'thoth/errors'
|
111
|
+
require 'thoth/config'
|
112
|
+
require 'thoth/version'
|
113
|
+
require 'thoth/plugin'
|
114
|
+
require 'thoth/middleware/minify'
|
115
|
+
|
116
|
+
# Monkeypatchery!
|
117
|
+
require 'thoth/monkeypatch/sequel/model/errors'
|
118
|
+
|
119
|
+
module Thoth
|
120
|
+
include Innate::Traited
|
121
|
+
|
122
|
+
# This is only here because assignments like trait[:foo] ||= :bar will fail if
|
123
|
+
# the trait hash hasn't been created yet.
|
124
|
+
trait(:traits_broken => true)
|
125
|
+
|
126
|
+
# Ramaze adapter to use.
|
127
|
+
trait[:adapter] ||= nil
|
128
|
+
|
129
|
+
# Path to the config file.
|
130
|
+
trait[:config_file] ||= ENV['THOTH_CONF'] || File.join(HOME_DIR, 'thoth.conf')
|
131
|
+
|
132
|
+
# Daemon command to execute (:start, :stop, :restart) or nil.
|
133
|
+
trait[:daemon] ||= nil
|
134
|
+
|
135
|
+
# IP address this Thoth instance should attach to.
|
136
|
+
trait[:ip] ||= nil
|
137
|
+
|
138
|
+
# Whether or not to start Thoth within an IRB session.
|
139
|
+
trait[:irb] ||= false
|
140
|
+
|
141
|
+
# What mode we're running in (either :devel or :production).
|
142
|
+
trait[:mode] ||= :production
|
143
|
+
|
144
|
+
# Port number this Thoth instance should attach to.
|
145
|
+
trait[:port] ||= nil
|
146
|
+
|
147
|
+
# Path to the daemon process id file.
|
148
|
+
trait[:pidfile] ||= File.join(HOME_DIR, "thoth_#{trait[:ip]}_#{trait[:port]}.pid")
|
149
|
+
|
150
|
+
# Filename to which all SQL commands should be logged, or nil to disable
|
151
|
+
# SQL logging.
|
152
|
+
trait[:sql_log] ||= nil
|
153
|
+
|
154
|
+
class << self
|
155
|
+
attr_reader :db
|
156
|
+
|
157
|
+
# Creates a new Thoth home directory with a sample config file at the
|
158
|
+
# specified path.
|
159
|
+
def create(path)
|
160
|
+
path = File.expand_path(path)
|
161
|
+
|
162
|
+
if File.exist?(path)
|
163
|
+
raise "specified path already exists: #{path}"
|
164
|
+
end
|
165
|
+
|
166
|
+
FileUtils.mkdir_p(File.join(path, 'log'))
|
167
|
+
FileUtils.mkdir(File.join(path, 'media'))
|
168
|
+
FileUtils.mkdir(File.join(path, 'plugin'))
|
169
|
+
FileUtils.mkdir(File.join(path, 'public'))
|
170
|
+
FileUtils.mkdir(File.join(path, 'view'))
|
171
|
+
FileUtils.mkdir(File.join(path, 'tmp'))
|
172
|
+
|
173
|
+
FileUtils.cp(File.join(LIB_DIR, '..', 'proto', 'config.ru'), File.join(path, 'config.ru'))
|
174
|
+
FileUtils.cp(File.join(LIB_DIR, '..', 'proto', 'thoth.conf.sample'), File.join(path, 'thoth.conf'))
|
175
|
+
|
176
|
+
File.chmod(0750, File.join(path, 'log'))
|
177
|
+
File.chmod(0750, File.join(path, 'media'))
|
178
|
+
File.chmod(0750, File.join(path, 'plugin'))
|
179
|
+
File.chmod(0755, File.join(path, 'public'))
|
180
|
+
File.chmod(0750, File.join(path, 'view'))
|
181
|
+
File.chmod(0750, File.join(path, 'tmp'))
|
182
|
+
|
183
|
+
File.chmod(0640, File.join(path, 'config.ru'))
|
184
|
+
File.chmod(0640, File.join(path, 'thoth.conf'))
|
185
|
+
end
|
186
|
+
|
187
|
+
# Opens a connection to the Thoth database and loads helpers, controllers,
|
188
|
+
# models and plugins.
|
189
|
+
def init_thoth
|
190
|
+
trait[:ip] ||= Config.server['address']
|
191
|
+
trait[:port] ||= Config.server['port']
|
192
|
+
|
193
|
+
open_db
|
194
|
+
|
195
|
+
# Ensure that the database schema is up to date.
|
196
|
+
#
|
197
|
+
# TODO: need to rethink how migration works since newer versions of Sequel
|
198
|
+
# don't expose the migration versions.
|
199
|
+
#
|
200
|
+
# unless Sequel::Migrator.get_current_migration_version(@db) ==
|
201
|
+
# Sequel::Migrator.latest_migration_version(File.join(LIB_DIR, 'migrate'))
|
202
|
+
#
|
203
|
+
# if trait[:mode] == :production
|
204
|
+
# raise SchemaError, "Database schema is missing or out of date. " <<
|
205
|
+
# "Please run `thoth --migrate`."
|
206
|
+
# else
|
207
|
+
# raise SchemaError, "Database schema is missing or out of date. " <<
|
208
|
+
# "Please run `thoth --devel --migrate`."
|
209
|
+
# end
|
210
|
+
# end
|
211
|
+
|
212
|
+
# If caching is disabled, replace the default cache store with a no-op
|
213
|
+
# API.
|
214
|
+
if Config.server['enable_cache']
|
215
|
+
# Cache templates once read to prevent unnecessary disk thrashing.
|
216
|
+
Innate::View.options.read_cache = true
|
217
|
+
|
218
|
+
if Config.server['memcache']['enabled']
|
219
|
+
Ramaze::Cache::MemCache::OPTIONS[:servers] = Config.server['memcache']['servers']
|
220
|
+
Ramaze::Cache.options.default = Ramaze::Cache::MemCache
|
221
|
+
end
|
222
|
+
else
|
223
|
+
require 'thoth/cache'
|
224
|
+
Ramaze::Cache.options.default = Thoth::Cache::Noop
|
225
|
+
end
|
226
|
+
|
227
|
+
# Create a cache for plugins to use.
|
228
|
+
Ramaze::Cache.add(:plugin)
|
229
|
+
|
230
|
+
# Tell Innate where to find Thoth's helpers.
|
231
|
+
Innate::HelpersHelper.options.paths << LIB_DIR
|
232
|
+
Innate::HelpersHelper.options.namespaces << Thoth::Helper
|
233
|
+
|
234
|
+
# Load Thoth controllers.
|
235
|
+
require File.join(LIB_DIR, 'controller')
|
236
|
+
|
237
|
+
# Load Thoth models.
|
238
|
+
require File.join(LIB_DIR, 'helper/wiki')
|
239
|
+
Thoth.acquire(File.join(LIB_DIR, 'model', '*'))
|
240
|
+
|
241
|
+
# Load startup plugins.
|
242
|
+
Config.plugins.each {|plugin| Plugin.load(plugin)}
|
243
|
+
|
244
|
+
Ramaze::Log.info "Thoth home: #{HOME_DIR}"
|
245
|
+
Ramaze::Log.info "Thoth lib : #{LIB_DIR}"
|
246
|
+
Ramaze::Log.info "Running in #{trait[:mode] == :production ? 'live' : 'dev'} mode"
|
247
|
+
|
248
|
+
Ramaze.options.setup << self
|
249
|
+
end
|
250
|
+
|
251
|
+
# Opens a Sequel database connection to the Thoth database.
|
252
|
+
def open_db
|
253
|
+
if Config.db =~ /^sqlite:\/{3}(.+)$/
|
254
|
+
dir = File.dirname($1)
|
255
|
+
FileUtils.mkdir_p(dir) unless File.directory?(dir)
|
256
|
+
end
|
257
|
+
|
258
|
+
Sequel.datetime_class = Time
|
259
|
+
|
260
|
+
@db = Sequel.connect(Config.db, :encoding => 'utf8')
|
261
|
+
@db.test_connection
|
262
|
+
|
263
|
+
if trait[:sql_log]
|
264
|
+
require 'logger'
|
265
|
+
@db.logger = Logger.new(trait[:sql_log])
|
266
|
+
end
|
267
|
+
|
268
|
+
@db.extension(:pagination)
|
269
|
+
|
270
|
+
rescue => e
|
271
|
+
Ramaze::Log.error("Unable to connect to database: #{e}")
|
272
|
+
exit(1)
|
273
|
+
end
|
274
|
+
|
275
|
+
# Restarts the running Thoth daemon (if any).
|
276
|
+
def restart
|
277
|
+
stop
|
278
|
+
sleep(1)
|
279
|
+
start
|
280
|
+
end
|
281
|
+
|
282
|
+
# Runs Thoth.
|
283
|
+
def run
|
284
|
+
init_thoth
|
285
|
+
|
286
|
+
begin
|
287
|
+
Ramaze.start(
|
288
|
+
:adapter => trait[:adapter],
|
289
|
+
:host => trait[:ip],
|
290
|
+
:port => trait[:port],
|
291
|
+
:root => LIB_DIR
|
292
|
+
)
|
293
|
+
rescue LoadError => ex
|
294
|
+
Ramaze::Log.error("Unable to start Ramaze due to LoadError: #{ex}")
|
295
|
+
exit(1)
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
# Initializes Ramaze.
|
300
|
+
def setup
|
301
|
+
Ramaze.options.merge!(
|
302
|
+
:mode => trait[:mode] == :production ? :live : :dev,
|
303
|
+
:roots => [HOME_DIR, LIB_DIR]
|
304
|
+
)
|
305
|
+
|
306
|
+
case trait[:mode]
|
307
|
+
when :devel
|
308
|
+
Ramaze.middleware :dev do
|
309
|
+
use Rack::Lint
|
310
|
+
use Rack::CommonLogger, Ramaze::Log
|
311
|
+
use Rack::ShowExceptions
|
312
|
+
use Rack::ShowStatus
|
313
|
+
use Rack::RouteExceptions
|
314
|
+
use Rack::ConditionalGet
|
315
|
+
use Rack::ETag
|
316
|
+
use Rack::Head
|
317
|
+
use Ramaze::Reloader
|
318
|
+
use Thoth::Minify if Config.server['enable_minify']
|
319
|
+
run Ramaze::AppMap
|
320
|
+
end
|
321
|
+
|
322
|
+
when :production
|
323
|
+
Ramaze.middleware :live do
|
324
|
+
use Rack::CommonLogger, Ramaze::Log
|
325
|
+
use Rack::RouteExceptions
|
326
|
+
use Rack::ShowStatus
|
327
|
+
use Rack::ConditionalGet
|
328
|
+
use Rack::ETag
|
329
|
+
use Rack::Head
|
330
|
+
use Thoth::Minify if Config.server['enable_minify']
|
331
|
+
run Ramaze::AppMap
|
332
|
+
end
|
333
|
+
|
334
|
+
# Ensure that exceptions result in an HTTP 500 response.
|
335
|
+
Rack::RouteExceptions.route(Exception, '/error_500')
|
336
|
+
|
337
|
+
# Log all errors to the error log file if one is configured.
|
338
|
+
if Config.server['error_log'].empty?
|
339
|
+
Ramaze::Log.loggers = []
|
340
|
+
else
|
341
|
+
log_dir = File.dirname(Config.server['error_log'])
|
342
|
+
|
343
|
+
unless File.directory?(log_dir)
|
344
|
+
FileUtils.mkdir_p(log_dir)
|
345
|
+
File.chmod(0750, log_dir)
|
346
|
+
end
|
347
|
+
|
348
|
+
Ramaze::Log.loggers = [Logger.new(Config.server['error_log'])]
|
349
|
+
Ramaze::Log.level = Logger::Severity::ERROR
|
350
|
+
end
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
354
|
+
# Starts Thoth as a daemon.
|
355
|
+
def start
|
356
|
+
if File.file?(trait[:pidfile])
|
357
|
+
pid = File.read(trait[:pidfile], 20).strip
|
358
|
+
abort("thoth already running? (pid=#{pid})")
|
359
|
+
end
|
360
|
+
|
361
|
+
puts "Starting thoth."
|
362
|
+
|
363
|
+
fork do
|
364
|
+
Process.setsid
|
365
|
+
exit if fork
|
366
|
+
|
367
|
+
File.open(trait[:pidfile], 'w') {|file| file << Process.pid}
|
368
|
+
at_exit {FileUtils.rm(trait[:pidfile]) if File.exist?(trait[:pidfile])}
|
369
|
+
|
370
|
+
Dir.chdir(HOME_DIR)
|
371
|
+
File.umask(0000)
|
372
|
+
|
373
|
+
STDIN.reopen('/dev/null')
|
374
|
+
STDOUT.reopen('/dev/null', 'a')
|
375
|
+
STDERR.reopen(STDOUT)
|
376
|
+
|
377
|
+
run
|
378
|
+
end
|
379
|
+
end
|
380
|
+
|
381
|
+
# Stops the running Thoth daemon (if any).
|
382
|
+
def stop
|
383
|
+
unless File.file?(trait[:pidfile])
|
384
|
+
abort("thoth not running? (check #{trait[:pidfile]}).")
|
385
|
+
end
|
386
|
+
|
387
|
+
puts "Stopping thoth."
|
388
|
+
|
389
|
+
pid = File.read(trait[:pidfile], 20).strip
|
390
|
+
FileUtils.rm(trait[:pidfile]) if File.exist?(trait[:pidfile])
|
391
|
+
pid && Process.kill('TERM', pid.to_i)
|
392
|
+
end
|
393
|
+
end
|
394
|
+
end
|