ixtlan-gettext 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|