ixtlan-gettext 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,20 @@
1
+ module Ixtlan
2
+ module Gettext
3
+ class Locale
4
+ include DataMapper::Resource
5
+
6
+ def self.storage_name(arg)
7
+ 'gettext_locales'
8
+ end
9
+
10
+ property :id, Serial
11
+ property :code, String, :unique=>true, :required => true, :format => /^[a-z][a-z](_[A-Z][A-Z])?$/, :length => 5
12
+
13
+ property :updated_at, DateTime, :required => true, :lazy => true
14
+
15
+ # do not record timestamps since they are set from outside
16
+ def set_timestamps_on_save
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,16 @@
1
+ require 'ixtlan/babel/serializer'
2
+
3
+ module Ixtlan
4
+ module Gettext
5
+
6
+ class LocaleSerializer < Ixtlan::Babel::Serializer
7
+
8
+ root 'locale'
9
+
10
+ add_context( :single )
11
+
12
+ add_context( :collection )
13
+
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,57 @@
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 'fast_gettext'
21
+ module Ixtlan
22
+ module Gettext
23
+ class Manager
24
+
25
+ DEFAULT = 'default'
26
+
27
+ def initialize
28
+ @default_repo = build( DEFAULT )
29
+ FastGettext.default_text_domain = DEFAULT
30
+ FastGettext.add_text_domain DEFAULT, :type => :ixtlan
31
+ end
32
+
33
+ def use( locale, name = DEFAULT )
34
+ unless FastGettext.translation_repositories.key?( name )
35
+ repos = [ build( "#{name}" ), @default_repo ]
36
+ FastGettext.add_text_domain name, :type=>:chain, :chain=> repos
37
+ end
38
+ FastGettext.set_locale(locale)
39
+ FastGettext.text_domain = name
40
+ end
41
+
42
+ def flush_caches(text_domain = nil)
43
+ if text_domain
44
+ (FastGettext.caches[text_domain] || {}).clear
45
+ else
46
+ FastGettext.caches.clear
47
+ end
48
+ end
49
+
50
+ private
51
+
52
+ def build( name )
53
+ FastGettext::TranslationRepository.build( name, :type => :ixtlan )
54
+ end
55
+ end
56
+ end
57
+ 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,90 @@
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/gettext/locale_resource'
21
+ require 'ixtlan/user_management/domain_resource'
22
+
23
+ module Ixtlan
24
+ module Gettext
25
+ class TranslationKey
26
+ include DataMapper::Resource
27
+
28
+ def self.storage_name(arg)
29
+ 'gettext_keys'
30
+ end
31
+
32
+ property :id, Serial
33
+ property :name, Text, :unique=>true, :required => true, :length => 4096
34
+
35
+ property :updated_at, DateTime, :required => true, :lazy => true
36
+
37
+ def self.update_all(keys)
38
+ ids = keys.collect do |k|
39
+ k.save
40
+ k.id
41
+ end
42
+ all(:id.not => ids).destroy!
43
+ end
44
+
45
+ def self.translation(key, locale)
46
+ Translation.first(TranslationKey.name => key, Locale.code => locale)
47
+ end
48
+
49
+ def self.available_locales
50
+ Translation.all(:fields => [:locale_id], :unique => true).collect do |t|
51
+ t.locale
52
+ end
53
+ end
54
+ # do not record timestamps since they are set from outside
55
+ def set_timestamps_on_save
56
+ end
57
+ end
58
+ class Translation
59
+ include DataMapper::Resource
60
+
61
+ def self.storage_name(arg)
62
+ 'gettext_texts'
63
+ end
64
+
65
+ belongs_to :translation_key, TranslationKey.to_s, :key => true
66
+ belongs_to :locale, Locale.to_s,:key => true
67
+ belongs_to :domain, Ixtlan::UserManagement::Domain.to_s, :required => false, :key => true
68
+
69
+ property :text, Text, :length => 4096
70
+
71
+ property :updated_at, DateTime, :required => true, :lazy => true
72
+
73
+ # do not record timestamps since they are set from outside
74
+ def set_timestamps_on_save
75
+ end
76
+ end
77
+ class Flush
78
+ # used local flush service
79
+
80
+ def self.trigger(rest)
81
+ begin
82
+ rest.retrieve( self.class )
83
+ rescue => e
84
+ warn "error sending flush trigger for gettext #{e.message}"
85
+ end
86
+ end
87
+
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,57 @@
1
+ require 'ixtlan/gettext/locale'
2
+
3
+ module Ixtlan
4
+ module Gettext
5
+ class TranslationKey
6
+ include DataMapper::Resource
7
+
8
+ def self.storage_name(arg)
9
+ 'gettext_keys'
10
+ end
11
+
12
+ property :id, Serial
13
+ property :name, String, :unique=>true, :required => true
14
+
15
+ property :updated_at, DateTime, :required => true, :lazy => true
16
+
17
+ def self.update_all(keys)
18
+ ids = keys.collect do |k|
19
+ k.save
20
+ k.id
21
+ end
22
+ all(:id.not => ids).destroy!
23
+ end
24
+
25
+ def self.translation(key, locale)
26
+ TranslationText.first(TranslationKey.name => key, Locale.code => locale)
27
+ end
28
+
29
+ def self.available_locales
30
+ Translation.all(:fields => [:locale_id], :unique => true).collect do |t|
31
+ t.locale
32
+ end
33
+ end
34
+ # do not record timestamps since they are set from outside
35
+ def set_timestamps_on_save
36
+ end
37
+ end
38
+ class TranslationText
39
+ include DataMapper::Resource
40
+
41
+ def self.storage_name(arg)
42
+ 'gettext_texts'
43
+ end
44
+
45
+ belongs_to :locale, Locale.to_s,:key => true
46
+ belongs_to :translation_key, TranslationKey.to_s, :key => true
47
+
48
+ property :text, String, :required => true
49
+
50
+ property :updated_at, DateTime, :required => true, :lazy => true
51
+
52
+ # do not record timestamps since they are set from outside
53
+ def set_timestamps_on_save
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,10 @@
1
+ module Ixtlan
2
+ module Gettext
3
+ module Controller
4
+
5
+ def flush
6
+ Rails.application.config.
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,33 @@
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/gettext/manager'
21
+ module Ixtlan
22
+ module Gettext
23
+ class Railtie < Rails::Railtie
24
+
25
+ config.gettext = Ixtlan::Gettext::Manager.new
26
+
27
+ rake_tasks do
28
+ load 'ixtlan/gettext/translation.rake'
29
+ end
30
+
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,15 @@
1
+ require 'ixtlan/remote/rest'
2
+ require 'ixtlan/gettext/manager'
3
+ module Ixtlan
4
+
5
+ class RemoteGettextRailtie < Rails::Railtie
6
+
7
+ config.rest = Ixtlan::Remote::Rest.new
8
+
9
+ config.gettext = Ixtlan::Gettext::Manager.new
10
+
11
+ rake_tasks do
12
+ load 'ixtlan/gettext/translation.rake'
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,37 @@
1
+ # -*- mode: ruby -*-
2
+
3
+ require 'ixtlan/gettext/crawler'
4
+
5
+ namespace :ixtlan do
6
+
7
+ namespace :gettext do
8
+ desc 'crawls the local filesystem for _(...) method calls and dumps them to the console'
9
+ task :keys => :environment do
10
+ print "\t"
11
+ puts Ixtlan::Gettext::Crawler.crawl.join( "\n\t" )
12
+ end
13
+
14
+ task :update => :environment do
15
+ puts 'crawling files . . .'
16
+ data = {:translation_keys => Ixtlan::Gettext::Crawler.crawl }
17
+ puts "sending #{data[:translation_keys].size} keys to gettext server . . ."
18
+ keys = Rails.application.config.rest.update(Ixtlan::Gettext::TranslationKey, data)
19
+ puts "updating local database with #{keys.size} keys . . ."
20
+ Ixtlan::Gettext::TranslationKey.update_all(keys)
21
+ end
22
+
23
+ task :commit => :environment do
24
+ keys = Rails.application.config.rest.update(Ixtlan::Gettext::TranslationKey, :commit, nil)
25
+ puts "updating local database with #{keys.size} keys . . ."
26
+ Ixtlan::Gettext::TranslationKey.update_all(keys)
27
+ end
28
+
29
+ task :rollback => :environment do
30
+ keys = Rails.application.config.rest.update(Ixtlan::Gettext::TranslationKey, :rollback, nil)
31
+ puts "updating local database with #{keys.size} keys . . ."
32
+ Ixtlan::Gettext::TranslationKey.update_all(keys)
33
+ end
34
+ end
35
+
36
+ end
37
+ # vim: syntax=Ruby
@@ -0,0 +1,23 @@
1
+ # --*-- ruby-mode --*--
2
+ namespace :ixtlan do
3
+
4
+ namespace :translations do
5
+ desc 'crawls the local filesystem for _(...) method calls and sends the collected translation keys to the remote service'
6
+ task :update => :environment do
7
+ data = {:translation_keys => ENV['KEYS'].split(/,/)}
8
+ keys = Rails.application.config.restserver.update(data)
9
+ Ixtlan::Gettext::TranslationKey.update_all(keys)
10
+ end
11
+
12
+ task :commit => :environment do
13
+ keys = Rails.application.config.restserver.update(:translation_keys, :commit)
14
+ Ixtlan::Gettext::TranslationKey.update_all(keys)
15
+ end
16
+
17
+ task :rollback => :environment do
18
+ keys = Rails.application.config.restserver.update(:translation_keys, :rollback)
19
+ Ixtlan::Gettext::TranslationKey.update_all(keys)
20
+ end
21
+ end
22
+
23
+ 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 TranslationText
37
+ include DataMapper::Resource
38
+
39
+ def self.storage_name(arg)
40
+ 'gettext_texts'
41
+ end
42
+
43
+ belongs_to :locale, Locale.to_s,:key => true
44
+ belongs_to :translation_key, TranslationKey.to_s, :key => true
45
+
46
+ property :text, String, :required => true
47
+
48
+ property :updated_at, DateTime, :required => true, :lazy => true
49
+
50
+ # do not record timestamps since they are set from outside
51
+ def set_timestamps_on_save
52
+ end
53
+ end
54
+ class Locale
55
+ include DataMapper::Resource
56
+
57
+ def self.storage_name(arg)
58
+ 'gettext_locales'
59
+ end
60
+
61
+ property :id, Serial
62
+ property :code, String, :unique=>true, :required => true, :format => /^[a-z][a-z](_[A-Z][A-Z])?$/, :length => 5
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