123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424 |
- require 'csv'
- class Translation < ApplicationModel
- before_create :set_initial
- after_create :cache_clear
- after_update :cache_clear
- after_destroy :cache_clear
- def self.sync(dedicated_locale = nil)
- return true if load_from_file(dedicated_locale)
- load
- end
- def self.load(dedicated_locale = nil)
- locals_to_sync(dedicated_locale).each do |locale|
- fetch(locale)
- load_from_file(locale)
- end
- true
- end
- def self.push(locale)
-
- translations = Translation.where(locale: locale)
- translations_to_push = []
- translations.each do |translation|
- if translation.target != translation.target_initial
- translations_to_push.push translation
- end
- end
- return true if translations_to_push.blank?
- url = 'https://i18n.zammad.com/api/v1/translations/thanks_for_your_support'
- translator_key = Setting.get('translator_key')
- result = UserAgent.post(
- url,
- {
- locale: locale,
- translations: translations_to_push,
- fqdn: Setting.get('fqdn'),
- translator_key: translator_key,
- },
- {
- json: true,
- open_timeout: 8,
- read_timeout: 24,
- }
- )
- raise "Can't push translations to #{url}: #{result.error}" if !result.success?
-
- if result.data['translator_key']
- translator_key = Setting.set('translator_key', result.data['translator_key'])
- end
- true
- end
- def self.reset(locale)
-
- translations = Translation.where(locale: locale)
- translations.each do |translation|
- if translation.target_initial.blank?
- translation.destroy
- elsif translation.target != translation.target_initial
- translation.target = translation.target_initial
- translation.save
- end
- end
- true
- end
- def self.lang(locale, admin = false)
-
- if !admin
- data = cache_get(locale)
- return data if data
- end
-
- data = {
- 'total' => Translation.where(locale: 'de-de').count,
- }
- list = []
- translations = if admin
- Translation.where(locale: locale.downcase).order(:source)
- else
- Translation.where(locale: locale.downcase).where.not(target: '').order(:source)
- end
- translations.each do |item|
- translation_item = []
- translation_item = if admin
- [
- item.id,
- item.source,
- item.target,
- item.target_initial,
- item.format,
- ]
- else
- [
- item.id,
- item.source,
- item.target,
- item.format,
- ]
- end
- list.push translation_item
- end
-
- presorted_list = []
- %w[yes no or Year Years Month Months Day Days Hour Hours Minute Minutes Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec January February March April May June July August September October November December Mon Tue Wed Thu Fri Sat Sun Monday Tuesday Wednesday Thursday Friday Saturday Sunday].each do |presort|
- list.each do |item|
- next if item[1] != presort
- presorted_list.push item
- list.delete item
-
- end
- end
- data['list'] = presorted_list.concat list
-
- if !admin
- cache_set(locale, data)
- end
- data
- end
- def self.translate(locale, string)
-
- records = Translation.where(locale: locale, source: string)
- records.each do |record|
- return record.target if record.source == string
- end
-
- records = Translation.where(locale: 'en', source: string)
- records.each do |record|
- return record.target if record.source == string
- end
- string
- end
- def self.load_from_file(dedicated_locale = nil)
- version = Version.get
- directory = Rails.root.join('config', 'translations')
- locals_to_sync(dedicated_locale).each do |locale|
- file = Rails.root.join(directory, "#{locale}-#{version}.yml")
- return false if !File.exist?(file)
- data = YAML.load_file(file)
- to_database(locale, data)
- end
- true
- end
- def self.fetch(dedicated_locale = nil)
- version = Version.get
- locals_to_sync(dedicated_locale).each do |locale|
- url = "https://i18n.zammad.com/api/v1/translations/#{locale}"
- if !UserInfo.current_user_id
- UserInfo.current_user_id = 1
- end
- result = UserAgent.get(
- url,
- {
- version: version,
- },
- {
- json: true,
- open_timeout: 8,
- read_timeout: 24,
- }
- )
- raise "Can't load translations from #{url}: #{result.error}" if !result.success?
- directory = Rails.root.join('config', 'translations')
- if !File.directory?(directory)
- Dir.mkdir(directory, 0o755)
- end
- file = Rails.root.join(directory, "#{locale}-#{version}.yml")
- File.open(file, 'w') do |out|
- YAML.dump(result.data, out)
- end
- end
- true
- end
- def self.load_from_csv(locale_name, location, charset = 'UTF8')
- locale = Locale.find_by(locale: locale_name)
- if !locale
- raise "No such locale: #{locale_name}"
- end
- if !::File.exist?(location)
- raise "No such file: #{location}"
- end
- content = ::File.open(location, "r:#{charset}").read
- params = {
- col_sep: ',',
- }
- rows = ::CSV.parse(content, params)
- header = rows.shift
- translation_raw = []
- rows.each do |row|
- raise "Can't import translation, source is missing" if row[0].blank?
- if row[1].blank?
- warn "Skipped #{row[0]}, because translation is blank"
- next
- end
- raise "Can't import translation, format is missing" if row[2].blank?
- raise "Can't import translation, format is invalid (#{row[2]})" if row[2] !~ /^(time|string)$/
- item = {
- 'locale' => locale.locale,
- 'source' => row[0],
- 'target' => row[1],
- 'target_initial' => '',
- 'format' => row[2],
- }
- translation_raw.push item
- end
- to_database(locale.name, translation_raw)
- true
- end
- private_class_method def self.to_database(locale, data)
- translations = Translation.where(locale: locale).all
- ActiveRecord::Base.transaction do
- data.each do |translation_raw|
-
- translation = nil
- translations.each do |item|
- next if item.format != translation_raw['format']
- next if item.source != translation_raw['source']
- translation = item
- break
- end
- if translation
-
- update_needed = false
- translation_raw.each_key do |key|
-
- next if translation_raw[key] == translation.target
-
- if translation.target == translation.target_initial
- update_needed = true
- break
- end
- end
- if update_needed
- translation.update!(translation_raw.symbolize_keys!)
- translation.save
- end
- else
- if !UserInfo.current_user_id
- translation_raw['updated_by_id'] = 1
- translation_raw['created_by_id'] = 1
- end
- Translation.create(translation_raw.symbolize_keys!)
- end
- end
- end
- end
- private_class_method def self.locals_to_sync(dedicated_locale = nil)
- locales_list = []
- if !dedicated_locale
- locales = Locale.to_sync
- locales.each do |locale|
- locales_list.push locale.locale
- end
- else
- locales_list = [dedicated_locale]
- end
- locales_list
- end
- private
- def set_initial
- return true if target_initial
- return true if target_initial == ''
- self.target_initial = target
- true
- end
- def cache_clear
- Cache.delete('TranslationMapOnlyContent::' + locale.downcase)
- true
- end
- def self.cache_set(locale, data)
- Cache.write('TranslationMapOnlyContent::' + locale.downcase, data)
- end
- private_class_method :cache_set
- def self.cache_get(locale)
- Cache.get('TranslationMapOnlyContent::' + locale.downcase)
- end
- private_class_method :cache_get
- end
|