Class: Tr8n::Language

Inherits:
ActiveRecord::Base
  • Object
show all
Defined in:
app/models/tr8n/language.rb

Overview

– Copyright © 2010-2012 Michael Berkovich, tr8n.net

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++

– Tr8n::Language Schema Information

Table name: tr8n_languages

id                      INTEGER         not null, primary key
locale                  varchar(255)    not null
english_name            varchar(255)    not null
native_name             varchar(255)    
enabled                 boolean         
right_to_left           boolean         
completeness            integer         
fallback_language_id    integer         
curse_words             text            
featured_index          integer         default = 0
google_key              varchar(255)    
facebook_key            varchar(255)    
created_at              datetime        
updated_at              datetime

Indexes

index_tr8n_languages_on_locale    (locale)

++

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.cache_key(locale) ⇒ Object



67
68
69
# File 'app/models/tr8n/language.rb', line 67

def self.cache_key(locale)
  "language_#{locale}"
end

.enabled_languagesObject



218
219
220
221
222
# File 'app/models/tr8n/language.rb', line 218

def self.enabled_languages
  Tr8n::Cache.fetch("enabled_languages") do 
    find(:all, :conditions => ["enabled = ?", true], :order => "english_name asc")
  end
end


224
225
226
227
228
# File 'app/models/tr8n/language.rb', line 224

def self.featured_languages
  Tr8n::Cache.fetch("featured_languages") do 
    find(:all, :conditions => ["enabled = ? and featured_index is not null and featured_index > 0", true], :order => "featured_index desc")
  end
end

.filter_optionsObject



196
197
198
# File 'app/models/tr8n/language.rb', line 196

def self.filter_options
  find(:all, :order => "english_name asc").collect{|lang| [lang.english_name, lang.id.to_s]}
end

.find_or_create(lcl, english_name) ⇒ Object



82
83
84
# File 'app/models/tr8n/language.rb', line 82

def self.find_or_create(lcl, english_name)
  find_by_locale(lcl) || create(:locale => lcl, :english_name => english_name) 
end

.for(locale) ⇒ Object



75
76
77
78
79
80
# File 'app/models/tr8n/language.rb', line 75

def self.for(locale)
  return nil if locale.nil?
  Tr8n::Cache.fetch(cache_key(locale)) do 
    find_by_locale(locale)
  end
end

.locale_optionsObject



192
193
194
# File 'app/models/tr8n/language.rb', line 192

def self.locale_options
  enabled_languages.collect{|lang| [lang.english_name, lang.locale]}
end

.optionsObject



188
189
190
# File 'app/models/tr8n/language.rb', line 188

def self.options
  enabled_languages.collect{|lang| [lang.english_name, lang.id.to_s]}
end

.translate(label, desc = "", tokens = {}, options = {}) ⇒ Object

Raises:



230
231
232
233
234
235
236
237
238
239
# File 'app/models/tr8n/language.rb', line 230

def self.translate(label, desc = "", tokens = {}, options = {})
  # raise Tr8n::Exception.new("The label is blank") if label.blank?
  raise Tr8n::Exception.new("The label is being translated twice") if label.tr8n_translated?

  return Tr8n::TranslationKey.substitute_tokens(label, tokens, options).tr8n_translated unless Tr8n::Config.enabled?
  return Tr8n::TranslationKey.substitute_tokens(label, tokens, options).tr8n_translated if Tr8n::Config.current_language.default?

  options.delete(:source) unless Tr8n::Config.enable_key_source_tracking?
  Tr8n::Config.current_language.translate(label, desc, tokens, options).tr8n_translated
end

Instance Method Details

#accepted_prohibited_wordsObject

you can add -bad_words to override the fallback language rules



314
315
316
317
318
319
320
321
322
# File 'app/models/tr8n/language.rb', line 314

def accepted_prohibited_words
  return [] if curse_words.blank?
  @accepted_prohibited_words ||= begin
    wrds = self.curse_words.split(",").select{|w| w.first=='-'}
    wrds << wrds.collect{|w| w.strip.gsub('-', '').downcase}
    wrds << fallback_language.accepted_prohibited_words if fallback_language
    wrds.flatten.uniq
  end
end

#bad_wordsObject



324
325
326
327
328
329
# File 'app/models/tr8n/language.rb', line 324

def bad_words
  @bad_words ||= begin
    bw = prohibited_words + Tr8n::Config.default_language.prohibited_words
    bw.flatten.uniq - accepted_prohibited_words
  end
end

#cache_keyObject



71
72
73
# File 'app/models/tr8n/language.rb', line 71

def cache_key
  self.class.cache_key(locale)
end

#case_for(case_keyword) ⇒ Object



175
176
177
# File 'app/models/tr8n/language.rb', line 175

def case_for(case_keyword)
  case_keyword_maps[case_keyword]
end

#case_keyword_mapsObject



161
162
163
164
165
166
167
168
169
# File 'app/models/tr8n/language.rb', line 161

def case_keyword_maps
  @case_keyword_maps ||= begin
    hash = {} 
    cases.each do |lcase| 
      hash[lcase.keyword] = lcase
    end
    hash
  end
end

#casesObject



92
93
94
95
96
# File 'app/models/tr8n/language.rb', line 92

def cases
  Tr8n::Cache.fetch("language_cases_#{locale}") do 
    language_cases
  end
end

#cases?Boolean



157
158
159
# File 'app/models/tr8n/language.rb', line 157

def cases?
  not cases.empty?
end

#clean_sentence?(sentence) ⇒ Boolean



331
332
333
334
335
336
337
338
339
340
341
342
# File 'app/models/tr8n/language.rb', line 331

def clean_sentence?(sentence)
  return true if sentence.blank?

  # we need to solve the downcase problem - it doesn't work for russian and others
  sentence = sentence.downcase

  bad_words.each do |w|
    return false unless sentence.scan(/#{w}/).empty?
  end
  
  true
end

#current?Boolean



127
128
129
# File 'app/models/tr8n/language.rb', line 127

def current?
  self.locale == Tr8n::Config.current_language.locale
end

#default?Boolean



131
132
133
# File 'app/models/tr8n/language.rb', line 131

def default?
  self.locale == Tr8n::Config.default_locale
end

#default_ruleObject



257
258
259
# File 'app/models/tr8n/language.rb', line 257

def default_rule
  @default_rule ||= Tr8n::Config.language_rule_classes.first.new(:language => self, :definition => {})
end

#default_rules_for(dependency) ⇒ Object



273
274
275
# File 'app/models/tr8n/language.rb', line 273

def default_rules_for(dependency)
  rules.select{|r| r.class.dependency == dependency}
end

#dependenciesObject



269
270
271
# File 'app/models/tr8n/language.rb', line 269

def dependencies  
  @dependencies ||= rule_classes.collect{|r| r.dependency}.uniq
end

#dirObject



214
215
216
# File 'app/models/tr8n/language.rb', line 214

def dir
  right_to_left? ? "rtl" : "ltr"
end

#disable!Object



205
206
207
208
# File 'app/models/tr8n/language.rb', line 205

def disable!
  self.enabled = false
  save
end

#disabled?Boolean



210
211
212
# File 'app/models/tr8n/language.rb', line 210

def disabled?
  not enabled?
end

#enable!Object



200
201
202
203
# File 'app/models/tr8n/language.rb', line 200

def enable!
  self.enabled = true
  save
end

#flagObject



135
136
137
# File 'app/models/tr8n/language.rb', line 135

def flag
  locale
end

#full_nameObject



183
184
185
186
# File 'app/models/tr8n/language.rb', line 183

def full_name
  return english_name if english_name == native_name
  "#{english_name} - #{native_name}"
end

#gender_rules?Boolean



148
149
150
151
152
153
154
155
# File 'app/models/tr8n/language.rb', line 148

def gender_rules?
  return false unless rules?
  
  rules.each do |rule|
    return true if rule.class.dependency == 'gender'
  end
  false
end

#has_gender_rules?Boolean



277
278
279
# File 'app/models/tr8n/language.rb', line 277

def has_gender_rules?
  dependencies.include?("gender")
end

#has_rules?Boolean

deprecated



140
141
142
# File 'app/models/tr8n/language.rb', line 140

def has_rules?
  rules?
end

#prohibited_wordsObject



304
305
306
307
308
309
310
311
# File 'app/models/tr8n/language.rb', line 304

def prohibited_words
  return [] if curse_words.blank?
  @prohibited_words ||= begin
    wrds = self.curse_words.split(",").collect{|w| w.strip.downcase} 
    wrds << fallback_language.prohibited_words if fallback_language
    wrds.flatten.uniq
  end
end

#recently_added_forum_messagesObject



356
357
358
# File 'app/models/tr8n/language.rb', line 356

def recently_added_forum_messages
  @recently_added_forum_messages ||= Tr8n::LanguageForumMessage.where("language_id = ?", self.id).order("created_at desc").limit(5)    
end

#recently_added_translationsObject



360
361
362
# File 'app/models/tr8n/language.rb', line 360

def recently_added_translations
  @recently_added_translations ||= Tr8n::Translation.where("language_id = ?", self.id).order("created_at desc").limit(5)    
end

#recently_updated_translationsObject



364
365
366
367
368
369
370
# File 'app/models/tr8n/language.rb', line 364

def recently_updated_translations
  @recently_updated_translations ||= begin
    trans =  Tr8n::Translation.where("language_id = ?", self.id)
    trans = trans.where("translation_key_id in (select id from tr8n_translation_keys where level <= ?)", Tr8n::Config.current_translator.level)
    trans.order("updated_at desc").limit(5)
  end
end

#recently_updated_votes(translator = Tr8n::Config.current_translator) ⇒ Object



372
373
374
# File 'app/models/tr8n/language.rb', line 372

def recently_updated_votes(translator = Tr8n::Config.current_translator)
  @recently_updated_votes ||= Tr8n::TranslationVote.where("translation_id in (select tr8n_translations.id from tr8n_translations where tr8n_translations.language_id = ? and tr8n_translations.translator_id = ?)", self.id, translator.id).order("updated_at desc").limit(5)
end

#reset!Object



98
99
100
101
# File 'app/models/tr8n/language.rb', line 98

def reset!
  reset_language_rules!
  reset_language_cases!
end

#reset_language_cases!Object

reloads language cases for the language from the yml file



114
115
116
117
118
119
120
121
122
123
124
125
# File 'app/models/tr8n/language.rb', line 114

def reset_language_cases!
  cases.delete_all
  Tr8n::Config.default_language_cases_for(locale).each do |lcase|
    rules = lcase.delete(:rules)
    language_case = Tr8n::LanguageCase.create(lcase.merge(:language => self, :translator => Tr8n::Config.system_translator))
    next if rules.blank?
    rules.keys.sort.each_with_index do |lrkey, index|
      lcrule = rules[lrkey]
      Tr8n::LanguageCaseRule.create(:language_case => language_case, :language => self, :translator => Tr8n::Config.system_translator, :position => index, :definition => lcrule)
    end
  end
end

#reset_language_rules!Object

reloads rules for the language from the yml file



104
105
106
107
108
109
110
111
# File 'app/models/tr8n/language.rb', line 104

def reset_language_rules!
  rules.delete_all
  Tr8n::Config.language_rule_classes.each do |rule_class|
    rule_class.default_rules_for(self).each do |definition|
      rule_class.create(:language => self, :definition => definition)
    end
  end
end

#rule_class_namesObject



265
266
267
# File 'app/models/tr8n/language.rb', line 265

def rule_class_names  
  @rule_class_names ||= rule_classes.collect{|r| r.name}
end

#rule_classesObject



261
262
263
# File 'app/models/tr8n/language.rb', line 261

def rule_classes  
  @rule_classes ||= rules.collect{|r| r.class}.uniq
end

#rulesObject



86
87
88
89
90
# File 'app/models/tr8n/language.rb', line 86

def rules
  Tr8n::Cache.fetch("language_rules_#{locale}") do 
    language_rules
  end
end

#rules?Boolean



144
145
146
# File 'app/models/tr8n/language.rb', line 144

def rules?
  not rules.empty?
end

#suggestible?Boolean



171
172
173
# File 'app/models/tr8n/language.rb', line 171

def suggestible?
  not google_key.blank?
end

#total_metricObject



293
294
295
296
297
298
# File 'app/models/tr8n/language.rb', line 293

def total_metric
  @total_metric ||= begin
    metric = Tr8n::TotalLanguageMetric.find(:first, :conditions => ["language_id = ?", self.id])
    metric || Tr8n::TotalLanguageMetric.create(Tr8n::LanguageMetric.default_attributes.merge(:language_id => self.id))
  end
end

#translate(label, desc = "", tokens = {}, options = {}) ⇒ Object Also known as: tr

Raises:



241
242
243
244
245
246
247
248
249
250
# File 'app/models/tr8n/language.rb', line 241

def translate(label, desc = "", tokens = {}, options = {})
  # raise Tr8n::Exception.new("The label is blank") if label.blank?
  raise Tr8n::Exception.new("The label is being translated twice") if label.tr8n_translated?

  return Tr8n::TranslationKey.substitute_tokens(label, tokens, options, self).tr8n_translated unless Tr8n::Config.enabled?
  return Tr8n::TranslationKey.substitute_tokens(label, tokens, options, self).tr8n_translated if default?

  translation_key = Tr8n::TranslationKey.find_or_create(label, desc, options)
  translation_key.translate(self, tokens.merge(:viewing_user => Tr8n::Config.current_user), options).tr8n_translated
end

#translations_changed!Object



344
345
346
# File 'app/models/tr8n/language.rb', line 344

def translations_changed!
  # TODO: handle change event - count translations, update total metrics
end

#trl(label, desc = "", tokens = {}, options = {}) ⇒ Object



253
254
255
# File 'app/models/tr8n/language.rb', line 253

def trl(label, desc = "", tokens = {}, options = {})
  tr(label, desc, tokens, options.merge(:skip_decorations => true))
end

#update_cacheObject



348
349
350
351
352
353
354
# File 'app/models/tr8n/language.rb', line 348

def update_cache
  Tr8n::Cache.delete(cache_key)
  Tr8n::Cache.delete("language_rules_#{locale}")
  Tr8n::Cache.delete("language_cases_#{locale}")
  Tr8n::Cache.delete("featured_languages")
  Tr8n::Cache.delete("enabled_languages")
end

#update_daily_metrics_for(metric_date) ⇒ Object



281
282
283
284
285
# File 'app/models/tr8n/language.rb', line 281

def update_daily_metrics_for(metric_date)
  metric = Tr8n::DailyLanguageMetric.find(:first, :conditions => ["language_id = ? and metric_date = ?", self.id, metric_date])
  metric ||= Tr8n::DailyLanguageMetric.create(:language_id => self.id, :metric_date => metric_date)
  metric.update_metrics!
end

#update_monthly_metrics_for(metric_date) ⇒ Object



287
288
289
290
291
# File 'app/models/tr8n/language.rb', line 287

def update_monthly_metrics_for(metric_date)
  metric = Tr8n::MonthlyLanguageMetric.find(:first, :conditions => ["language_id = ? and metric_date = ?", self.id, metric_date])
  metric ||= Tr8n::MonthlyLanguageMetric.create(:language_id => self.id, :metric_date => metric_date)
  metric.update_metrics!
end

#update_total_metricsObject



300
301
302
# File 'app/models/tr8n/language.rb', line 300

def update_total_metrics
  total_metric.update_metrics!
end

#valid_case?(case_keyword) ⇒ Boolean



179
180
181
# File 'app/models/tr8n/language.rb', line 179

def valid_case?(case_keyword)
  case_for(case_keyword) != nil
end