ixtlan-gettext 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +2 -0
- data/README.md +75 -0
- data/agpl-3.0.txt +661 -0
- data/lib/fast_gettext/translation_repository/ixtlan.rb +65 -0
- data/lib/fast_gettext/translation_repository/ixtlan.rb~ +61 -0
- data/lib/ixtlan-gettext.rb +22 -0
- data/lib/ixtlan-gettext.rb~ +4 -0
- data/lib/ixtlan/gettext.rb +22 -0
- data/lib/ixtlan/gettext.rb~ +4 -0
- data/lib/ixtlan/gettext/controller.rb +17 -0
- data/lib/ixtlan/gettext/controller.rb~ +16 -0
- data/lib/ixtlan/gettext/crawler.rb +61 -0
- data/lib/ixtlan/gettext/crawler.rb~ +69 -0
- data/lib/ixtlan/gettext/locale.rb~ +71 -0
- data/lib/ixtlan/gettext/locale_resource.rb +46 -0
- data/lib/ixtlan/gettext/locale_resource.rb~ +20 -0
- data/lib/ixtlan/gettext/locale_serializer.rb +16 -0
- data/lib/ixtlan/gettext/manager.rb +57 -0
- data/lib/ixtlan/gettext/manager.rb~ +61 -0
- data/lib/ixtlan/gettext/models.rb +90 -0
- data/lib/ixtlan/gettext/models.rb~ +57 -0
- data/lib/ixtlan/gettext/rails_controller.rb~ +10 -0
- data/lib/ixtlan/gettext/railtie.rb +33 -0
- data/lib/ixtlan/gettext/railtie.rb~ +15 -0
- data/lib/ixtlan/gettext/translation.rake +37 -0
- data/lib/ixtlan/gettext/translation.rake~ +23 -0
- data/lib/ixtlan/gettext/translation_models.rb~ +71 -0
- data/lib/ixtlan/railtie.rb~ +17 -0
- data/spec/manager_spec.rb +120 -0
- data/spec/manager_spec.rb~ +68 -0
- data/spec/sync_spec.rb~ +83 -0
- metadata +236 -0
@@ -0,0 +1,65 @@
|
|
1
|
+
#
|
2
|
+
# ixtlan_gettext - helper to use fast_gettext with datamapper/ixtlan
|
3
|
+
# Copyright (C) 2012 Christian Meier
|
4
|
+
#
|
5
|
+
# This file is part of ixtlan_gettext.
|
6
|
+
#
|
7
|
+
# ixtlan_gettext is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU Affero General Public License as
|
9
|
+
# published by the Free Software Foundation, either version 3 of the
|
10
|
+
# License, or (at your option) any later version.
|
11
|
+
#
|
12
|
+
# ixtlan_gettext is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU Affero General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU Affero General Public License
|
18
|
+
# along with ixtlan_gettext. If not, see <http://www.gnu.org/licenses/>.
|
19
|
+
#
|
20
|
+
require 'ixtlan/user_management/domain_resource'
|
21
|
+
require 'ixtlan/gettext/models'
|
22
|
+
|
23
|
+
module FastGettext
|
24
|
+
module TranslationRepository
|
25
|
+
class Ixtlan
|
26
|
+
|
27
|
+
def initialize( name, options={} )
|
28
|
+
@name = name
|
29
|
+
end
|
30
|
+
|
31
|
+
@@seperator = '||||' # string that seperates multiple plurals
|
32
|
+
def self.seperator=(sep);@@seperator = sep;end
|
33
|
+
def self.seperator;@@seperator;end
|
34
|
+
|
35
|
+
def available_locales
|
36
|
+
[]
|
37
|
+
end
|
38
|
+
|
39
|
+
def pluralisation_rule
|
40
|
+
nil
|
41
|
+
end
|
42
|
+
|
43
|
+
def [](key)
|
44
|
+
r = ::Ixtlan::Gettext::Translation.first( ::Ixtlan::Gettext::Translation.translation_key.name => key,
|
45
|
+
::Ixtlan::Gettext::Translation.locale.code => FastGettext.locale,
|
46
|
+
:domain => domain )
|
47
|
+
r.text.to_s if r
|
48
|
+
end
|
49
|
+
|
50
|
+
def plural(*args)
|
51
|
+
if translation = self[ args*self.class.seperator ]
|
52
|
+
translation.to_s.split(self.class.seperator)
|
53
|
+
else
|
54
|
+
[]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def domain
|
61
|
+
@domain ||= ::Ixtlan::UserManagement::Domain.first_or_create( :name => @name ) if @name != ::Ixtlan::Gettext::Manager::DEFAULT
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Ixtlan
|
2
|
+
module Gettext
|
3
|
+
class Repository
|
4
|
+
|
5
|
+
def initialize(name,options={})
|
6
|
+
@domain = Ixtlan::UserManagement::Domain.first( :name => name )
|
7
|
+
raise "domain not found: #{name}" unless @domain
|
8
|
+
end
|
9
|
+
|
10
|
+
@@seperator = '||||' # string that seperates multiple plurals
|
11
|
+
def self.seperator=(sep);@@seperator = sep;end
|
12
|
+
def self.seperator;@@seperator;end
|
13
|
+
|
14
|
+
def available_locales
|
15
|
+
[]
|
16
|
+
end
|
17
|
+
|
18
|
+
def pluralisation_rule
|
19
|
+
nil
|
20
|
+
end
|
21
|
+
|
22
|
+
def [](key)
|
23
|
+
Translation.first(TranslationKey.name => key, Locale.code => FastGettext.locale, :domain => @domain)
|
24
|
+
end
|
25
|
+
|
26
|
+
def plural(*args)
|
27
|
+
if translation = self[ args*self.class.seperator ]
|
28
|
+
translation.to_s.split(self.class.seperator)
|
29
|
+
else
|
30
|
+
[]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class Manager
|
36
|
+
|
37
|
+
DEFAULT = 'default'
|
38
|
+
|
39
|
+
def initialize
|
40
|
+
FastGettext.default_text_domain = DEFAULT
|
41
|
+
@default_repo = build( DEFAULT )
|
42
|
+
end
|
43
|
+
|
44
|
+
def use( locale, name = DEFAULT )
|
45
|
+
unless FastGettext.translation_repositories.key?( name )
|
46
|
+
repos = [ build( "#{name}-overlay" ), @default_repo ]
|
47
|
+
FastGettext.add_text_domain name, :type=>:chain, :chain=> repos
|
48
|
+
end
|
49
|
+
FastGettext.set_locale(locale)
|
50
|
+
FastGettext.text_domain = name
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def build( name )
|
56
|
+
FastGettext::TranslationRepository.build( name,
|
57
|
+
:type => Manager.to_s )
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
#
|
2
|
+
# ixtlan_gettext - helper to use fast_gettext with datamapper/ixtlan
|
3
|
+
# Copyright (C) 2012 Christian Meier
|
4
|
+
#
|
5
|
+
# This file is part of ixtlan_gettext.
|
6
|
+
#
|
7
|
+
# ixtlan_gettext is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU Affero General Public License as
|
9
|
+
# published by the Free Software Foundation, either version 3 of the
|
10
|
+
# License, or (at your option) any later version.
|
11
|
+
#
|
12
|
+
# ixtlan_gettext is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU Affero General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU Affero General Public License
|
18
|
+
# along with ixtlan_gettext. If not, see <http://www.gnu.org/licenses/>.
|
19
|
+
#
|
20
|
+
if defined?(Rails)
|
21
|
+
require 'ixtlan/gettext/railtie'
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
#
|
2
|
+
# ixtlan_gettext - helper to use fast_gettext with datamapper/ixtlan
|
3
|
+
# Copyright (C) 2012 Christian Meier
|
4
|
+
#
|
5
|
+
# This file is part of ixtlan_gettext.
|
6
|
+
#
|
7
|
+
# ixtlan_gettext is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU Affero General Public License as
|
9
|
+
# published by the Free Software Foundation, either version 3 of the
|
10
|
+
# License, or (at your option) any later version.
|
11
|
+
#
|
12
|
+
# ixtlan_gettext is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU Affero General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU Affero General Public License
|
18
|
+
# along with ixtlan_gettext. If not, see <http://www.gnu.org/licenses/>.
|
19
|
+
#
|
20
|
+
if defined?(Rails)
|
21
|
+
require 'ixtlan/gettext/railtie'
|
22
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Ixtlan
|
2
|
+
module Gettext
|
3
|
+
module Controller
|
4
|
+
|
5
|
+
def flush
|
6
|
+
# only for localhost
|
7
|
+
if request.remote_ip == '127.0.0.1'
|
8
|
+
Rails.application.config.gettext.flush_caches
|
9
|
+
head :ok
|
10
|
+
else
|
11
|
+
head :not_found
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
#
|
2
|
+
# ixtlan_gettext - helper to use fast_gettext with datamapper/ixtlan
|
3
|
+
# Copyright (C) 2012 Christian Meier
|
4
|
+
#
|
5
|
+
# This file is part of ixtlan_gettext.
|
6
|
+
#
|
7
|
+
# ixtlan_gettext is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU Affero General Public License as
|
9
|
+
# published by the Free Software Foundation, either version 3 of the
|
10
|
+
# License, or (at your option) any later version.
|
11
|
+
#
|
12
|
+
# ixtlan_gettext is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU Affero General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU Affero General Public License
|
18
|
+
# along with ixtlan_gettext. If not, see <http://www.gnu.org/licenses/>.
|
19
|
+
#
|
20
|
+
module Ixtlan
|
21
|
+
module Gettext
|
22
|
+
class Crawler
|
23
|
+
|
24
|
+
def self.crawl
|
25
|
+
Crawler.new.crawl
|
26
|
+
end
|
27
|
+
|
28
|
+
def crawl
|
29
|
+
keys.clear
|
30
|
+
Dir[File.join('app', 'views', '**', '*rb')].each do |f|
|
31
|
+
File.read(f).each_line do |line|
|
32
|
+
extract_key(line) if line =~ /_[ (]/
|
33
|
+
end
|
34
|
+
end
|
35
|
+
keys.sort!
|
36
|
+
keys.uniq!
|
37
|
+
keys
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def keys
|
43
|
+
@keys ||= []
|
44
|
+
end
|
45
|
+
|
46
|
+
def extract_key(line)
|
47
|
+
extract(line, "'")
|
48
|
+
extract(line, '"')
|
49
|
+
end
|
50
|
+
|
51
|
+
def extract(line, sep)
|
52
|
+
if line =~ /.*_[ (][#{sep}]/
|
53
|
+
# non-greedy +? and *? vs. greedy + and *
|
54
|
+
k = line.sub( /.*?_[ (][#{sep}]/, '').sub(/[#{sep}].*\n/, '')
|
55
|
+
keys << k; puts k unless keys.member? k
|
56
|
+
extract_key(line.sub(/[^_]*_[ (][#{sep}][^#{sep}]+[#{sep}]/, ''))
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
class NewLocale
|
2
|
+
|
3
|
+
def initialize(lang)
|
4
|
+
@lang = lang
|
5
|
+
@file = "config/locales/#{lang}.yml"
|
6
|
+
@trans = if File.exists? @file
|
7
|
+
YAML.load_file(@file)[lang]
|
8
|
+
else
|
9
|
+
{}
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def crawl
|
14
|
+
Dir[File.join('app', 'views', '**/*rb')].each do |f|
|
15
|
+
File.read(f).each do |line|
|
16
|
+
extract_key(line) if line =~ /_[ (]/
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def dump
|
22
|
+
merge
|
23
|
+
result = {}
|
24
|
+
result[@lang] = @trans
|
25
|
+
lines = result.to_yaml.sub(/---\s*\n/, '').gsub(/ -\s*\n/, '').split /\n/
|
26
|
+
lines.sort!{|n,m| n.sub(/^ /, "zz") <=> m.sub(/^ /, "zz") }
|
27
|
+
File.open(@file, 'w') do |f|
|
28
|
+
lines.each do |l|
|
29
|
+
f.puts l
|
30
|
+
f.puts " -" if l =~ /^ .*: $/
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.doit(lang)
|
36
|
+
l = new(lang)
|
37
|
+
l.crawl
|
38
|
+
l.dump
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def merge
|
44
|
+
keys.each do |k|
|
45
|
+
@trans[k] = k unless @trans.key? k
|
46
|
+
end
|
47
|
+
@trans.keys.each do |k|
|
48
|
+
@trans[" Deleted-Key-#{k}"] = @trans.delete(k) if !keys.member?(k) && (k =~ /^ Deleted-Key-/).nil?
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def keys
|
53
|
+
@keys ||= []
|
54
|
+
end
|
55
|
+
|
56
|
+
def extract_key(line)
|
57
|
+
line.gsub!(/_[^ (]/, '-')
|
58
|
+
extract(line, "'")
|
59
|
+
extract(line, '"')
|
60
|
+
end
|
61
|
+
|
62
|
+
def extract(line, sep)
|
63
|
+
if line =~ /.*_[ (][#{sep}]/
|
64
|
+
k = line.sub(/[^_]*_[ (][#{sep}]/, '').sub(/[#{sep}].*\n/, '')
|
65
|
+
keys << k; puts k unless keys.member? k
|
66
|
+
extract_key(line.sub(/[^_]*_[ (][#{sep}][^#{sep}]+[#{sep}]/, ''))
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Ixtlan
|
2
|
+
module Gettext
|
3
|
+
class TranslationKey
|
4
|
+
include DataMapper::Resource
|
5
|
+
|
6
|
+
def self.storage_name(arg)
|
7
|
+
'gettext_keys'
|
8
|
+
end
|
9
|
+
|
10
|
+
property :id, Serial
|
11
|
+
property :name, String, :unique=>true, :required => true
|
12
|
+
|
13
|
+
property :updated_at, DateTime, :required => true, :lazy => true
|
14
|
+
|
15
|
+
def self.update_all(keys)
|
16
|
+
ids = keys.collect do |k|
|
17
|
+
k.save
|
18
|
+
k.id
|
19
|
+
end
|
20
|
+
all(:id.not => ids).destroy!
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.translation(key, locale)
|
24
|
+
TranslationText.first(TranslationKey.name => key, Locale.code => locale)
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.available_locales
|
28
|
+
Translation.all(:fields => [:locale_id], :unique => true).collect do |t|
|
29
|
+
t.locale
|
30
|
+
end
|
31
|
+
end
|
32
|
+
# do not record timestamps since they are set from outside
|
33
|
+
def set_timestamps_on_save
|
34
|
+
end
|
35
|
+
end
|
36
|
+
class Locale
|
37
|
+
include DataMapper::Resource
|
38
|
+
|
39
|
+
def self.storage_name(arg)
|
40
|
+
'gettext_locales'
|
41
|
+
end
|
42
|
+
|
43
|
+
property :id, Serial
|
44
|
+
property :code, String, :unique=>true, :required => true, :format => /^[a-z][a-z](_[A-Z][A-Z])?$/, :length => 5
|
45
|
+
|
46
|
+
property :updated_at, DateTime, :required => true, :lazy => true
|
47
|
+
|
48
|
+
# do not record timestamps since they are set from outside
|
49
|
+
def set_timestamps_on_save
|
50
|
+
end
|
51
|
+
end
|
52
|
+
class TranslationText
|
53
|
+
include DataMapper::Resource
|
54
|
+
|
55
|
+
def self.storage_name(arg)
|
56
|
+
'gettext_texts'
|
57
|
+
end
|
58
|
+
|
59
|
+
belongs_to :locale, Locale.to_s,:key => true
|
60
|
+
belongs_to :translation_key, TranslationKey.to_s, :key => true
|
61
|
+
|
62
|
+
property :text, String, :required => true
|
63
|
+
|
64
|
+
property :updated_at, DateTime, :required => true, :lazy => true
|
65
|
+
|
66
|
+
# do not record timestamps since they are set from outside
|
67
|
+
def set_timestamps_on_save
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
#
|
2
|
+
# ixtlan_gettext - helper to use fast_gettext with datamapper/ixtlan
|
3
|
+
# Copyright (C) 2012 Christian Meier
|
4
|
+
#
|
5
|
+
# This file is part of ixtlan_gettext.
|
6
|
+
#
|
7
|
+
# ixtlan_gettext is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU Affero General Public License as
|
9
|
+
# published by the Free Software Foundation, either version 3 of the
|
10
|
+
# License, or (at your option) any later version.
|
11
|
+
#
|
12
|
+
# ixtlan_gettext is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU Affero General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU Affero General Public License
|
18
|
+
# along with ixtlan_gettext. If not, see <http://www.gnu.org/licenses/>.
|
19
|
+
#
|
20
|
+
module Ixtlan
|
21
|
+
module Gettext
|
22
|
+
class Locale
|
23
|
+
include DataMapper::Resource
|
24
|
+
|
25
|
+
def self.storage_name(arg)
|
26
|
+
'gettext_locales'
|
27
|
+
end
|
28
|
+
|
29
|
+
# key for selectng the IdentityMap should remain this class if
|
30
|
+
# there is no single table inheritance with Discriminator in place
|
31
|
+
# i.e. the subclass used as key for the IdentityMap
|
32
|
+
def self.base_model
|
33
|
+
self
|
34
|
+
end
|
35
|
+
|
36
|
+
property :id, Serial, :auto_validation => false
|
37
|
+
property :code, String, :unique=>true, :required => true, :format => /^[a-z][a-z](_[A-Z][A-Z])?$/, :length => 5
|
38
|
+
|
39
|
+
property :updated_at, DateTime, :required => true, :lazy => true
|
40
|
+
|
41
|
+
# do not record timestamps since they are set from outside
|
42
|
+
def set_timestamps_on_save
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|