module Thoth

The main Thoth namespace.

Constants

APP_AUTHORS
APP_EMAIL
APP_NAME
APP_URL
APP_VERSION
FILESIZE_FORMAT

Lifted from old Ramaze, which was also lifter by Rack::Directory Stolen from Ramaze

HOME_DIR
LIB_DIR
PUBLIC_DIR
VIEW_DIR

Attributes

db[R]

Public Class Methods

acquire(*globs) click to toggle source

LIFTED from old Ramaze.acquire Require all .rb and .so files on the given globs, utilizes Dir::[].

Examples:

# Given following directory structure:
# src/foo.rb
# src/bar.so
# src/foo.yaml
# src/foobar/baz.rb
# src/foobar/README

# requires all files in 'src':
Ramaze.acquire 'src/*'

# requires all files in 'src' recursive:
Ramaze.acquire 'src/**/*'

# require 'src/foo.rb' and 'src/bar.so' and 'src/foobar/baz.rb'
Ramaze.acquire 'src/*', 'src/foobar/*'
# File lib/thoth.rb, line 81
def self.acquire(*globs)
  globs.flatten.each do |glob|
    Dir[glob].each do |file|
        require file if file =~ /\.(rb|so)$/
        puts "#{file} loaded"
      end
   end
 end
create(path) click to toggle source

Creates a new Thoth home directory with a sample config file at the specified path.

# File lib/thoth.rb, line 159
def create(path)
  path = File.expand_path(path)
  
  puts "PATH #{path}"

  if File.exist?(path)
    raise "specified path already exists: #{path}"
  end

  FileUtils.mkdir_p(File.join(path, 'log'))
  FileUtils.mkdir(File.join(path, 'media'))
  FileUtils.mkdir(File.join(path, 'plugin'))
  FileUtils.mkdir(File.join(path, 'public'))
  FileUtils.mkdir(File.join(path, 'view'))
  FileUtils.mkdir(File.join(path, 'tmp'))

  FileUtils.cp(File.join(LIB_DIR, '..', 'proto', 'config.ru'), File.join(path, 'config.ru'))
  FileUtils.cp(File.join(LIB_DIR, '..', 'proto', 'thoth.conf.sample'), File.join(path, 'thoth.conf'))

  File.chmod(0750, File.join(path, 'log'))
  File.chmod(0750, File.join(path, 'media'))
  File.chmod(0750, File.join(path, 'plugin'))
  File.chmod(0755, File.join(path, 'public'))
  File.chmod(0750, File.join(path, 'view'))
  File.chmod(0750, File.join(path, 'tmp'))

  File.chmod(0640, File.join(path, 'config.ru'))
  File.chmod(0640, File.join(path, 'thoth.conf'))
end
filesize_format(int) click to toggle source
# File lib/thoth.rb, line 100
 def self.filesize_format(int)
   FILESIZE_FORMAT.each do |format, size|
     return format % (int.to_f / size) if int >= size
   end

   "#{int}B"
end
init_thoth() click to toggle source

Opens a connection to the Thoth database and loads helpers, controllers, models and plugins.

# File lib/thoth.rb, line 191
def init_thoth
  trait[:ip]   ||= Config.server['address']
  trait[:port] ||= Config.server['port']

  open_db

  # Ensure that the database schema is up to date.
  #
  # TODO: need to rethink how migration works since newer versions of Sequel
  # don't expose the migration versions.
  #
  # unless Sequel::Migrator.get_current_migration_version(@db) ==
  #     Sequel::Migrator.latest_migration_version(File.join(LIB_DIR, 'migrate'))
  #
  #   if trait[:mode] == :production
  #     raise SchemaError, "Database schema is missing or out of date. " <<
  #         "Please run `thoth --migrate`."
  #   else
  #     raise SchemaError, "Database schema is missing or out of date. " <<
  #         "Please run `thoth --devel --migrate`."
  #   end
  # end

  # If caching is disabled, replace the default cache store with a no-op
  # API.
  if Config.server['enable_cache']
    # Cache templates once read to prevent unnecessary disk thrashing.
    Innate::View.options.read_cache = true

    if Config.server['memcache']['enabled']
      Ramaze::Cache::MemCache::OPTIONS[:servers] = Config.server['memcache']['servers']
      Ramaze::Cache.options.default = Ramaze::Cache::MemCache
    end
  else
    require 'thoth/cache'
    Ramaze::Cache.options.default = Thoth::Cache::Noop
  end

  # Create a cache for plugins to use.
  Ramaze::Cache.add(:plugin)

  # Tell Innate where to find Thoth's helpers.
  Innate::HelpersHelper.options.paths << LIB_DIR
  Innate::HelpersHelper.options.namespaces << Thoth::Helper

  # Load Thoth controllers.
  require File.join(LIB_DIR, 'controller')

  # Load Thoth models.
  require File.join(LIB_DIR, 'helper/wiki')
  Thoth.acquire(File.join(LIB_DIR, 'model', '*'))

  # Load startup plugins.
  Config.plugins.each {|plugin| Plugin.load(plugin)}

  Ramaze::Log.info "Thoth home: #{HOME_DIR}"
  Ramaze::Log.info "Thoth lib : #{LIB_DIR}"
  Ramaze::Log.info "Running in #{trait[:mode] == :production ? 'live' : 'dev'} mode"

  Ramaze.options.setup << self
end
open_db() click to toggle source

Opens a Sequel database connection to the Thoth database.

# File lib/thoth.rb, line 254
def open_db
  if Config.db =~ /^sqlite:\/{3}(.+)$/
    dir = File.dirname($1)
    FileUtils.mkdir_p(dir) unless File.directory?(dir)
  end

  Sequel.datetime_class = Time

  @db = Sequel.connect(Config.db, :encoding => 'utf8')
  @db.test_connection

  if trait[:sql_log]
    require 'logger'
    @db.logger = Logger.new(trait[:sql_log])
  end
  
  @db.extension(:pagination)

rescue => e
  Ramaze::Log.error("Unable to connect to database: #{e}")
  exit(1)
end
restart() click to toggle source

Restarts the running Thoth daemon (if any).

# File lib/thoth.rb, line 278
def restart
  stop
  sleep(1)
  start
end
run() click to toggle source

Runs Thoth.

# File lib/thoth.rb, line 285
def run
  init_thoth

  begin
    Ramaze.start(
      :adapter => trait[:adapter],
      :host    => trait[:ip],
      :port    => trait[:port],
      :root    => LIB_DIR
    )
  rescue LoadError => ex
    Ramaze::Log.error("Unable to start Ramaze due to LoadError: #{ex}")
    exit(1)
  end
end
setup() click to toggle source

Initializes Ramaze.

# File lib/thoth.rb, line 302
def setup
  Ramaze.options.merge!(
    :mode  => trait[:mode] == :production ? :live : :dev,
    :roots => [HOME_DIR, LIB_DIR]
  )
  
  case trait[:mode]
  when :devel
    Ramaze.middleware :dev do 
      use Rack::Lint
      use Rack::CommonLogger, Ramaze::Log
      use Rack::ShowExceptions
      use Rack::ShowStatus
      use Rack::RouteExceptions
      use Rack::ConditionalGet
      use Rack::ETag
      use Rack::Head
      use Ramaze::Reloader
      use Thoth::Minify if Config.server['enable_minify']
      run Ramaze::AppMap
    end

  when :production
    Ramaze.middleware :live do 
      use Rack::CommonLogger, Ramaze::Log
      use Rack::RouteExceptions
      use Rack::ShowStatus
      use Rack::ConditionalGet
      use Rack::ETag
      use Rack::Head
      use Thoth::Minify if Config.server['enable_minify']
      run Ramaze::AppMap
    end

    # Ensure that exceptions result in an HTTP 500 response.
    Rack::RouteExceptions.route(Exception, '/error_500')

    # Log all errors to the error log file if one is configured.
    if Config.server['error_log'].empty?
      Ramaze::Log.loggers = []
    else
      log_dir = File.dirname(Config.server['error_log'])

      unless File.directory?(log_dir)
        FileUtils.mkdir_p(log_dir)
        File.chmod(0750, log_dir)
      end

      Ramaze::Log.loggers = [Logger.new(Config.server['error_log'])]
      Ramaze::Log.level = Logger::Severity::ERROR
    end
  end
end
start() click to toggle source

Starts Thoth as a daemon.

# File lib/thoth.rb, line 357
def start
  if File.file?(trait[:pidfile])
    pid = File.read(trait[:pidfile], 20).strip
    abort("thoth already running? (pid=#{pid})")
  end

  puts "Starting thoth."

  fork do
    Process.setsid
    exit if fork

    File.open(trait[:pidfile], 'w') {|file| file << Process.pid}
    at_exit {FileUtils.rm(trait[:pidfile]) if File.exist?(trait[:pidfile])}

    Dir.chdir(HOME_DIR)
    File.umask(0000)

    STDIN.reopen('/dev/null')
    STDOUT.reopen('/dev/null', 'a')
    STDERR.reopen(STDOUT)

    run 
  end
end
stop() click to toggle source

Stops the running Thoth daemon (if any).

# File lib/thoth.rb, line 384
def stop
  unless File.file?(trait[:pidfile])
    abort("thoth not running? (check #{trait[:pidfile]}).")
  end

  puts "Stopping thoth."

  pid = File.read(trait[:pidfile], 20).strip
  FileUtils.rm(trait[:pidfile]) if File.exist?(trait[:pidfile])
  pid && Process.kill('TERM', pid.to_i)
end