1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
|
=begin
lib/gettext_activerecord/parser.rb - parser for ActiveRecord
Copyright (C) 2005-2009 Masao Mutoh
You may redistribute it and/or modify it under the same
license terms as Ruby or LGPL.
=end
require 'gettext'
require 'gettext/tools/rgettext'
require 'gettext/tools/parser/ruby'
include GetText
ActiveRecord::Base.instance_eval do
alias inherited_without_log inherited
def inherited(subclass)
puts "registering an ActiveRecord model for later processing: #{subclass}" if $DEBUG
active_record_classes_list << "#{subclass}" unless subclass.name.empty?
inherited_without_log(subclass)
end
def active_record_classes_list
$active_record_classes_list ||= []
end
def reset_active_record_classes_list
$active_record_classes_list = []
end
end
module GetText
module ActiveRecordParser
extend GetText
include GetText
bindtextdomain "gettext_activerecord"
@config = {
:db_yml => "config/database.yml",
:db_mode => "development",
:activerecord_classes => ["ActiveRecord::Base"],
:untranslate_classes => ["ActiveRecord::Base", "ActiveRecord::SessionStore::Session"],
:untranslate_columns => ["id"],
:untranslate_table_name => false,
:use_classname => true,
}
@ar_re = nil
module_function
def require_rails(file) # :nodoc:
begin
require file
rescue MissingSourceFile
$stderr.puts _("'%{file}' is not found.") % {:file => file}
end
end
# Sets some preferences to parse ActiveRecord files.
#
# * config: a Hash of the config. It can takes some values below:
# * :use_classname - If true, the msgids of ActiveRecord become "ClassName|FieldName" (e.g. "Article|Title"). Otherwise the ClassName is not used (e.g. "Title"). Default is true.
# * :db_yml - the path of database.yml. Default is "config/database.yml".
# * :db_mode - the mode of the database. Default is "development"
# * :activerecord_classes - an Array of the superclass of the models. The classes should be String value. Default is ["ActiveRecord::Base"]
# * :untranslate_classes - an Array of the modules/class names which is ignored as the msgid.
# * :untranslate_columns - an Array of the column names which is ignored as the msgid.
# * :untranslate_table_name - a Boolean that avoids table name to be translated if it is true ... Generally, we don't have to translate table_name, do we? Maybe it is not true..... but it is a test
# * :adapter - the options for ActiveRecord::Base.establish_connection. If this value is set, :db_yml option is ignored.
# * :host - ditto
# * :username - ditto
# * :password - ditto
# * :database - ditto
# * :socket - ditto
# * :encoding - ditto
#
# "ClassName|FieldName" uses GetText.sgettext. So you don't need to translate the left-side of "|".
# See <Documents for Translators for more details(http://www.yotabanana.com/hiki/ruby-gettext-translate.html)>.
def init(config)
puts "\nconfig: #{config.inspect}\n\n" if $DEBUG
if config
config.each{|k, v|
@config[k] = v
}
end
@ar_re = /class.*(#{@config[:activerecord_classes].join("|")})/
end
def translatable_class?(klass)
if klass.is_a?(Class) && klass < ActiveRecord::Base
if klass.untranslate_all? || klass.abstract_class? || @config[:untranslate_classes].include?(klass.name)
false
else
true
end
else
true
end
end
def translatable_column?(klass, columnname)
! (klass.untranslate?(columnname) || @config[:untranslate_columns].include?(columnname))
end
def parse(file, targets = []) # :nodoc:
puts "parse file #{file}" if $DEBUG
GetText.locale = "en"
old_constants = Object.constants
begin
eval(open(file).read, TOPLEVEL_BINDING)
rescue
$stderr.puts _("Ignored '%{file}'. Solve dependencies first.") % {:file => file}
$stderr.puts $!
end
#loaded_constants = Object.constants - old_constants
loaded_constants = ActiveRecord::Base.active_record_classes_list
ActiveRecord::Base.reset_active_record_classes_list
loaded_constants.each do |classname|
klass = eval(classname, TOPLEVEL_BINDING)
if translatable_class?(klass)
puts "processing class #{klass.name}" if $DEBUG
add_target(targets, file, ActiveSupport::Inflector.singularize(klass.table_name.gsub(/_/, " "))) unless @config[:untranslate_table_name]
unless klass.class_name == classname
add_target(targets, file, ActiveSupport::Inflector.singularize(klass.to_s_with_gettext.gsub(/_/, " ").downcase))
end
begin
klass.columns.each do |column|
if translatable_column?(klass, column.name)
if @config[:use_classname]
msgid = klass.to_s_with_gettext + "|" + klass.human_attribute_name(column.name)
else
msgid = klass.human_attribute_name(column.name)
end
add_target(targets, file, msgid)
end
end
rescue
$stderr.puts _("No database is available.")
$stderr.puts $!
end
end
end
if RubyParser.target?(file)
targets += RubyParser.parse(file)
end
targets
end
def add_target(targets, file, msgid) # :nodoc:
po = PoMessage.new(:normal)
po.msgid = msgid
po.sources << "#{file}:-"
targets << po
targets
end
def target?(file) # :nodoc:
init(nil) unless @ar_re
data = IO.readlines(file)
data.each do |v|
if @ar_re =~ v
unless ActiveRecord::Base.connected?
begin
require 'rubygems'
rescue LoadError
$stderr.puts _("rubygems are not found.") if $DEBUG
end
begin
ENV["RAILS_ENV"] = @config[:db_mode]
require 'config/boot.rb'
require 'config/environment.rb'
require_rails 'activesupport'
require_rails 'gettext_activerecord'
rescue LoadError
require_rails 'rubygems'
gem 'activerecord'
require_rails 'activesupport'
require_rails 'active_record'
require_rails 'gettext_activerecord'
end
begin
yaml = YAML.load(IO.read(@config[:db_yml]))
if yaml[@config[:db_mode]]
ActiveRecord::Base.establish_connection(yaml[@config[:db_mode]])
else
ActiveRecord::Base.establish_connection(yaml)
end
rescue
if @config[:adapter]
ActiveRecord::Base.establish_connection(@config)
else
return false
end
end
end
return true
end
end
false
end
end
RGetText.add_parser(GetText::ActiveRecordParser)
end
|