translate-rails3-plus 0.0.11 → 0.0.12

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.
@@ -1,45 +1,45 @@
1
- <%
2
- from_text = lookup(from_locale, key)
3
- to_text = lookup(to_locale, key)
4
- field_name = "key[#{key}]"
5
- %>
6
-
7
- <div class="translation">
8
- <% if from_text.present? %>
9
-
10
- <ol>
11
- <% from_text.each_with_index do |from_text_section, index| %>
12
- <%
13
- from_text_section = from_text_section.to_s
14
- line_size = 100
15
- n_lines = n_lines(from_text_section, line_size)
16
- # this is needed so the controller doesn't freak out when there is no translations found
17
- # for this element yet...
18
- to_text = Array.new if to_text.blank?
19
- %>
20
- <li class="single-translation">
21
- <p class="translation-text"><%= from_text_section %></p>
22
- <p class="edit-form" >
23
- <% if n_lines > 1 %>
24
- <%= text_area_tag("#{field_name}[#{index}]", to_text[index], :size => "#{line_size}x#{n_lines}", :id => "#{key}[#{index}]", :class=>'edit-field') %>
25
- <% else %>
26
- <%= text_field_tag("#{field_name}[#{index}]", to_text[index], :size => line_size, :id => "#{key}[#{index}]", :class=>'edit-field') %>
27
- <% end %>
28
- <%= translate_link("#{key}[#{index}]", from_text_section, @from_locale, @to_locale) %>
29
- </p>
30
- <div class="error-text"></div>
31
- </li>
32
- <% end %>
33
- </ol>
34
-
35
- <% end %>
36
- <p>
37
- <em>
38
- <br/>
39
- <strong>Key:</strong><%=h key %><br/>
40
- <% if @files[key] %>
41
- <strong>File:</strong><%= @files[key].join("<br/>") %>
42
- <% end %>
43
- </em>
44
- </p>
45
- </div>
1
+ <%
2
+ from_text = lookup(from_locale, key)
3
+ to_text = lookup(to_locale, key)
4
+ field_name = "key[#{key}]"
5
+ %>
6
+
7
+ <div class="translation">
8
+ <% if from_text.present? %>
9
+
10
+ <ol>
11
+ <% from_text.each_with_index do |from_text_section, index| %>
12
+ <%
13
+ from_text_section = from_text_section.to_s
14
+ line_size = 100
15
+ n_lines = n_lines(from_text_section, line_size)
16
+ # this is needed so the controller doesn't freak out when there is no translations found
17
+ # for this element yet...
18
+ to_text = Array.new if to_text.blank?
19
+ %>
20
+ <li class="single-translation">
21
+ <p class="translation-text"><%= from_text_section %></p>
22
+ <p class="edit-form" >
23
+ <% if n_lines > 1 %>
24
+ <%= text_area_tag("#{field_name}[#{index}]", to_text[index], :size => "#{line_size}x#{n_lines}", :id => "#{key}[#{index}]", :class=>'edit-field') %>
25
+ <% else %>
26
+ <%= text_field_tag("#{field_name}[#{index}]", to_text[index], :size => line_size, :id => "#{key}[#{index}]", :class=>'edit-field') %>
27
+ <% end %>
28
+ <%= translate_link("#{key}[#{index}]", from_text_section, @from_locale, @to_locale) %>
29
+ </p>
30
+ <div class="error-text"></div>
31
+ </li>
32
+ <% end %>
33
+ </ol>
34
+
35
+ <% end %>
36
+ <p>
37
+ <em>
38
+ <br/>
39
+ <strong>Key:</strong><%=h key %><br/>
40
+ <% if @files[key] %>
41
+ <strong>File:</strong><%= @files[key].join("<br/>") %>
42
+ <% end %>
43
+ </em>
44
+ </p>
45
+ </div>
@@ -1,24 +1,24 @@
1
- <%
2
- # Expects locals:
3
- #
4
- # total_entries
5
- # per_page
6
-
7
- n_pages = total_entries/per_page + (total_entries % per_page > 0 ? 1 : 0)
8
- current_page = (params[:page] || 1).to_i
9
- %>
10
-
11
- <% if n_pages > 1 %>
12
- <h2>Pages:</h2>
13
- <div class="clearfix">
14
- <ul class="paging">
15
- <% (1..n_pages).each do |page_number| %>
16
- <% if current_page == page_number %>
17
- <li class="selected"><%= link_to(page_number, params.merge(:page => page_number), :title => "Page #{page_number}" ) %></li>
18
- <% else %>
19
- <li><%= link_to(page_number, params.merge(:page => page_number), :title => "Page #{page_number}") %></li>
20
- <% end %>
21
- <% end %>
22
- </ul>
23
- </div>
24
- <% end %>
1
+ <%
2
+ # Expects locals:
3
+ #
4
+ # total_entries
5
+ # per_page
6
+
7
+ n_pages = total_entries/per_page + (total_entries % per_page > 0 ? 1 : 0)
8
+ current_page = (params[:page] || 1).to_i
9
+ %>
10
+
11
+ <% if n_pages > 1 %>
12
+ <h2>Pages:</h2>
13
+ <div class="clearfix">
14
+ <ul class="paging">
15
+ <% (1..n_pages).each do |page_number| %>
16
+ <% if current_page == page_number %>
17
+ <li class="selected"><%= link_to(page_number, params.merge(:page => page_number), :title => "Page #{page_number}" ) %></li>
18
+ <% else %>
19
+ <li><%= link_to(page_number, params.merge(:page => page_number), :title => "Page #{page_number}") %></li>
20
+ <% end %>
21
+ <% end %>
22
+ </ul>
23
+ </div>
24
+ <% end %>
@@ -1,35 +1,35 @@
1
- <%
2
- from_text = lookup(from_locale, key)
3
- to_text = lookup(to_locale, key)
4
- line_size = 100
5
- n_lines = n_lines(from_text, line_size)
6
- field_name = "key[#{key}]"
7
- %>
8
-
9
- <div class="translation single-translation" >
10
- <% if from_text.present? %>
11
- <% if from_text.starts_with?(" ") || from_text.ends_with?(" ")%>
12
- <%= simple_format("&rarr;" + h(from_text) + "&larr;", :class => "translation-text" ) %>
13
- <% else %>
14
- <%= simple_format(h(from_text), :class => "translation-text") %>
15
- <% end %>
16
- <% end %>
17
- <p class="edit-form">
18
- <% if n_lines > 1 %>
19
- <%= text_area_tag(field_name, to_text, :size => "#{line_size}x#{n_lines}", :id => key, :class=>'edit-field') %>
20
- <% else %>
21
- <%= text_field_tag(field_name, to_text, :size => line_size, :id => key, :class=>'edit-field') %>
22
- <% end %>
23
- </p>
24
- <div class="error-text"></div>
25
- <p>
26
- <em>
27
- <%= translate_link(key, from_text, @from_locale, @to_locale) %>
28
- <br/>
29
- <strong>Key:</strong><%=h key %><br/>
30
- <% if @files[key] %>
31
- <strong>File:</strong><%= @files[key].join("<br/>") %>
32
- <% end %>
33
- </em>
34
- </p>
35
- </div>
1
+ <%
2
+ from_text = lookup(from_locale, key)
3
+ to_text = lookup(to_locale, key)
4
+ line_size = 100
5
+ n_lines = n_lines(from_text, line_size)
6
+ field_name = "key[#{key}]"
7
+ %>
8
+
9
+ <div class="translation single-translation" >
10
+ <% if from_text.present? %>
11
+ <% if from_text.starts_with?(" ") || from_text.ends_with?(" ")%>
12
+ <%= simple_format("&rarr;" + h(from_text) + "&larr;", :class => "translation-text" ) %>
13
+ <% else %>
14
+ <%= simple_format(h(from_text), :class => "translation-text") %>
15
+ <% end %>
16
+ <% end %>
17
+ <p class="edit-form">
18
+ <% if n_lines > 1 %>
19
+ <%= text_area_tag(field_name, to_text, :size => "#{line_size}x#{n_lines}", :id => key, :class=>'edit-field') %>
20
+ <% else %>
21
+ <%= text_field_tag(field_name, to_text, :size => line_size, :id => key, :class=>'edit-field') %>
22
+ <% end %>
23
+ </p>
24
+ <div class="error-text"></div>
25
+ <p>
26
+ <em>
27
+ <%= translate_link(key, from_text, @from_locale, @to_locale) %>
28
+ <br/>
29
+ <strong>Key:</strong><%=h key %><br/>
30
+ <% if @files[key] %>
31
+ <strong>File:</strong><%= @files[key].join("<br/>") %>
32
+ <% end %>
33
+ </em>
34
+ </p>
35
+ </div>
@@ -1,96 +1,96 @@
1
- <%
2
- show_filters = ["all", "untranslated", "translated"]
3
- show_filters << "changed" if @from_locale != @to_locale
4
- %>
5
-
6
- <fieldset>
7
- <legend>Search filter</legend>
8
- <div id="show-sort">
9
- <p>
10
- <label>Show:</label> <%= raw simple_filter(show_filters) %>
11
- </p>
12
- <p>
13
- <label>Sort by:</label> <%= raw simple_filter(["key", "text"], 'sort_by') %>
14
- </p>
15
- </div>
16
- <%= form_tag(params, :method => :get) do %>
17
- <div id="languages">
18
- <p>
19
- <%= hidden_field_tag(:filter, params[:filter]) %>
20
- <%= hidden_field_tag(:sort_by, params[:sort_by]) %>
21
- <label>Translate from</label>
22
- <%= select_tag(:from_locale, options_for_select(from_locales, @from_locale.to_sym)) %> <span>to</span>
23
- <%= select_tag(:to_locale, options_for_select(to_locales, @to_locale.to_sym)) %>
24
- <%= submit_tag "Display" %>
25
- </p>
26
- </div>
27
- <div id="filter-pattern">
28
- <p>
29
- <label for="key_pattern_value">Key</label>
30
- <%= select_tag(:key_type, options_for_select([["contains", 'contains'], ["starts with", 'starts_with']], params[:key_type])) %>
31
- <%= text_field_tag(:key_pattern, params[:key_pattern], :size => 50, :id => "key_pattern_value", :class => "text-default") %>
32
- </p>
33
- <p>
34
- <label for="text_pattern_value">Text</label>
35
- <%= select_tag(:text_type, options_for_select(['contains', 'equals'], params[:text_type])) %>
36
- <%= text_field_tag(:text_pattern, params[:text_pattern], :size => 50, :id => "text_pattern_value", :class => "text-default") %>
37
- </p>
38
- <p>
39
- <label for="translated_text_pattern_value">Translated Text</label>
40
- <%= select_tag(:translated_text_type, options_for_select(['contains', 'equals'], params[:translated_text_type])) %>
41
- <%= text_field_tag(:translated_text_pattern, params[:translated_text_pattern], :size => 50, :id => "translated_text_pattern_value", :class => "text-default") %>
42
- </p>
43
- <p>
44
- <%= submit_tag "Search" %>
45
- <%= link_to "clear", params.merge({:text_pattern => nil, :translated_text_pattern => nil, :key_pattern => nil}) %>
46
- </p>
47
- </div>
48
- <% end %>
49
- <p class="hits">
50
- Found <strong><%= @total_entries %></strong> messages
51
- </p>
52
- <p>
53
- <%= link_to "Reload messages", translate_reload_path %>
54
- </p>
55
- </fieldset>
56
-
57
-
58
- <div class="paging">
59
- <%= render :partial => 'pagination', :locals => {:total_entries => @total_entries, :per_page => per_page} %>
60
- </div>
61
-
62
- <% if @total_entries > 0 %>
63
- <%= form_tag(translate_path, :name => 'translate_form') do %>
64
- <div>
65
- <%= hidden_field_tag(:filter, params[:filter], :id => "hid_filter") %>
66
- <%= hidden_field_tag(:sort_by, params[:sort_by], :id => "hid_sort_by") %>
67
- <%= hidden_field_tag(:key_type, params[:key_type], :id => "hid_key_type") %>
68
- <%= hidden_field_tag(:key_pattern, params[:key_pattern], :id => "hid_key_pattern") %>
69
- <%= hidden_field_tag(:text_type, params[:text_type], :id => "hid_text_type") %>
70
- <%= hidden_field_tag(:text_pattern, params[:text_pattern], :id => "hid_text_pattern") %>
71
- </div>
72
- <div class="translations">
73
- <h2>Translations from <span class='big-locale'><%= @from_locale %></span> to <span class='big-locale'><%= @to_locale %></span></h2>
74
- <p class="translate">
75
- <input onclick="testAndSave();" type="button" value="Save Translations">
76
- </p>
77
- <% @paginated_keys.each do |key| %>
78
- <%=
79
- from_text = lookup(@from_locale, key)
80
- render (from_text.is_a?(Array) ? 'array_form' : 'string_form'), {
81
- :from_locale => @from_locale,
82
- :to_locale => @to_locale,
83
- :key => key,
84
- }
85
- %>
86
- <% end %>
87
- <p class="translate">
88
- <input onclick="testAndSave();" type="button" value="Save Translations">
89
- </p>
90
- </div>
91
- <% end %>
92
- <% end %>
93
-
94
- <div class="paging">
95
- <%= render :partial => 'pagination', :locals => {:total_entries => @total_entries, :per_page => per_page} %>
96
- </div>
1
+ <%
2
+ show_filters = ["all", "untranslated", "translated"]
3
+ show_filters << "changed" if @from_locale != @to_locale
4
+ %>
5
+
6
+ <fieldset>
7
+ <legend>Search filter</legend>
8
+ <div id="show-sort">
9
+ <p>
10
+ <label>Show:</label> <%= raw simple_filter(show_filters) %>
11
+ </p>
12
+ <p>
13
+ <label>Sort by:</label> <%= raw simple_filter(["key", "text"], 'sort_by') %>
14
+ </p>
15
+ </div>
16
+ <%= form_tag(params, :method => :get) do %>
17
+ <div id="languages">
18
+ <p>
19
+ <%= hidden_field_tag(:filter, params[:filter]) %>
20
+ <%= hidden_field_tag(:sort_by, params[:sort_by]) %>
21
+ <label>Translate from</label>
22
+ <%= select_tag(:from_locale, options_for_select(from_locales, @from_locale.to_sym)) %> <span>to</span>
23
+ <%= select_tag(:to_locale, options_for_select(to_locales, @to_locale.to_sym)) %>
24
+ <%= submit_tag "Display" %>
25
+ </p>
26
+ </div>
27
+ <div id="filter-pattern">
28
+ <p>
29
+ <label for="key_pattern_value">Key</label>
30
+ <%= select_tag(:key_type, options_for_select([["contains", 'contains'], ["starts with", 'starts_with']], params[:key_type])) %>
31
+ <%= text_field_tag(:key_pattern, params[:key_pattern], :size => 50, :id => "key_pattern_value", :class => "text-default") %>
32
+ </p>
33
+ <p>
34
+ <label for="text_pattern_value">Text</label>
35
+ <%= select_tag(:text_type, options_for_select(['contains', 'equals'], params[:text_type])) %>
36
+ <%= text_field_tag(:text_pattern, params[:text_pattern], :size => 50, :id => "text_pattern_value", :class => "text-default") %>
37
+ </p>
38
+ <p>
39
+ <label for="translated_text_pattern_value">Translated Text</label>
40
+ <%= select_tag(:translated_text_type, options_for_select(['contains', 'equals'], params[:translated_text_type])) %>
41
+ <%= text_field_tag(:translated_text_pattern, params[:translated_text_pattern], :size => 50, :id => "translated_text_pattern_value", :class => "text-default") %>
42
+ </p>
43
+ <p>
44
+ <%= submit_tag "Search" %>
45
+ <%= link_to "clear", params.merge({:text_pattern => nil, :translated_text_pattern => nil, :key_pattern => nil}) %>
46
+ </p>
47
+ </div>
48
+ <% end %>
49
+ <p class="hits">
50
+ Found <strong><%= @total_entries %></strong> messages
51
+ </p>
52
+ <p>
53
+ <%= link_to "Reload messages", translate_reload_path %>
54
+ </p>
55
+ </fieldset>
56
+
57
+
58
+ <div class="paging">
59
+ <%= render :partial => 'pagination', :locals => {:total_entries => @total_entries, :per_page => per_page} %>
60
+ </div>
61
+
62
+ <% if @total_entries > 0 %>
63
+ <%= form_tag(translate_path, :name => 'translate_form') do %>
64
+ <div>
65
+ <%= hidden_field_tag(:filter, params[:filter], :id => "hid_filter") %>
66
+ <%= hidden_field_tag(:sort_by, params[:sort_by], :id => "hid_sort_by") %>
67
+ <%= hidden_field_tag(:key_type, params[:key_type], :id => "hid_key_type") %>
68
+ <%= hidden_field_tag(:key_pattern, params[:key_pattern], :id => "hid_key_pattern") %>
69
+ <%= hidden_field_tag(:text_type, params[:text_type], :id => "hid_text_type") %>
70
+ <%= hidden_field_tag(:text_pattern, params[:text_pattern], :id => "hid_text_pattern") %>
71
+ </div>
72
+ <div class="translations">
73
+ <h2>Translations from <span class='big-locale'><%= @from_locale %></span> to <span class='big-locale'><%= @to_locale %></span></h2>
74
+ <p class="translate">
75
+ <input onclick="testAndSave();" type="button" value="Save Translations">
76
+ </p>
77
+ <% @paginated_keys.each do |key| %>
78
+ <%=
79
+ from_text = lookup(@from_locale, key)
80
+ render (from_text.is_a?(Array) ? 'array_form' : 'string_form'), {
81
+ :from_locale => @from_locale,
82
+ :to_locale => @to_locale,
83
+ :key => key,
84
+ }
85
+ %>
86
+ <% end %>
87
+ <p class="translate">
88
+ <input onclick="testAndSave();" type="button" value="Save Translations">
89
+ </p>
90
+ </div>
91
+ <% end %>
92
+ <% end %>
93
+
94
+ <div class="paging">
95
+ <%= render :partial => 'pagination', :locals => {:total_entries => @total_entries, :per_page => per_page} %>
96
+ </div>
data/config/routes.rb CHANGED
@@ -1,5 +1,5 @@
1
- Rails.application.routes.draw do
2
- get 'translate' => 'translate#index', :as => :translate_list
3
- post 'translate' => 'translate#translate', :as => :translate
4
- get 'translate/reload' => 'translate#reload', :as => :translate_reload
5
- end
1
+ Rails.application.routes.draw do
2
+ get 'translate' => 'translate#index', :as => :translate_list
3
+ post 'translate' => 'translate#translate', :as => :translate
4
+ get 'translate/reload' => 'translate#reload', :as => :translate_reload
5
+ end
data/init.rb CHANGED
@@ -1 +1 @@
1
- require 'translate'
1
+ require 'translate'
@@ -1,200 +1,200 @@
1
- require 'yaml'
2
-
3
- class Hash
4
- def deep_merge(other)
5
- # deep_merge by Stefan Rusterholz, see http://www.ruby-forum.com/topic/142809
6
- merger = proc { |key, v1, v2| (Hash === v1 && Hash === v2) ? v1.merge(v2, &merger) : v2 }
7
- merge(other, &merger)
8
- end
9
-
10
- def set(keys, value)
11
- key = keys.shift
12
- if keys.empty?
13
- self[key] = value
14
- else
15
- self[key] ||= {}
16
- self[key].set keys, value
17
- end
18
- end
19
-
20
- if ENV['SORT']
21
- # copy of ruby's to_yaml method, prepending sort.
22
- # before each so we get an ordered yaml file
23
- def to_yaml( opts = {} )
24
- YAML::quick_emit( self, opts ) do |out|
25
- out.map( taguri, to_yaml_style ) do |map|
26
- sort.each do |k, v| #<- Adding sort.
27
- map.add( k, v )
28
- end
29
- end
30
- end
31
- end
32
- end
33
- end
34
-
35
- namespace :translate do
36
- desc "Show duplicate keys for locale LOCALE"
37
- task :duplicates => :environment do
38
- from_locale = I18n.default_locale
39
- duplicates = Translate::Keys.new.duplicate_keys
40
-
41
- messages = []
42
- duplicates.each do |locale, keys|
43
- keys.each do |key|
44
- from_text = I18n.backend.send(:lookup, from_locale, key)
45
- next if from_text.blank?
46
- messages << "#{locale}.#{key} (#{from_locale}.#{key}='#{from_text}')"
47
- end
48
- end
49
-
50
- if messages.present?
51
- messages.each { |m| puts m }
52
- else
53
- puts "No duplicate keys"
54
- end
55
- end
56
-
57
- desc "Show untranslated keys for locale LOCALE"
58
- task :untranslated => :environment do
59
- from_locale = I18n.default_locale
60
- untranslated = Translate::Keys.new.untranslated_keys
61
-
62
- messages = []
63
- untranslated.each do |locale, keys|
64
- keys.each do |key|
65
- from_text = I18n.backend.send(:lookup, from_locale, key)
66
- next if from_text.blank?
67
- messages << "#{locale}.#{key} (#{from_locale}.#{key}='#{from_text}')"
68
- end
69
- end
70
-
71
- if messages.present?
72
- messages.each { |m| puts m }
73
- else
74
- puts "No untranslated keys"
75
- end
76
- end
77
-
78
- desc "Show I18n keys that are missing in the config/locales/default_locale.yml YAML file"
79
- task :missing => :environment do
80
- missing = Translate::Keys.new.missing_keys.inject([]) do |keys, (key, filename)|
81
- keys << "#{key} in \t #{filename} is missing"
82
- end
83
- puts missing.present? ? missing.join("\n") : "No missing translations in the default locale file"
84
- end
85
-
86
- desc "Remove all translation texts that are no longer present in the locale they were translated from"
87
- task :remove_obsolete_keys => :environment do
88
- I18n.backend.send(:init_translations)
89
- master_locale = ENV['LOCALE'] || I18n.default_locale
90
- Translate::Keys.translated_locales.each do |locale|
91
- texts = {}
92
- Translate::Keys.new.i18n_keys(locale).each do |key|
93
- if I18n.backend.send(:lookup, master_locale, key).to_s.present?
94
- texts[key] = I18n.backend.send(:lookup, locale, key)
95
- end
96
- end
97
- I18n.backend.send(:translations)[locale] = nil # Clear out all current translations
98
- I18n.backend.store_translations(locale, Translate::Keys.to_deep_hash(texts))
99
- Translate::Storage.new(locale).write_to_file
100
- end
101
- end
102
-
103
- desc "Merge I18n keys from log/translations.yml into config/locales/*.yml (for use with the Rails I18n TextMate bundle)"
104
- task :merge_keys => :environment do
105
- I18n.backend.send(:init_translations)
106
- new_translations = YAML::load(IO.read(File.join(Rails.root, "log", "translations.yml")))
107
- raise("Can only merge in translations in single locale") if new_translations.keys.size > 1
108
- locale = new_translations.keys.first
109
-
110
- overwrites = false
111
- Translate::Keys.to_shallow_hash(new_translations[locale]).keys.each do |key|
112
- new_text = key.split(".").inject(new_translations[locale]) { |hash, sub_key| hash[sub_key] }
113
- existing_text = I18n.backend.send(:lookup, locale.to_sym, key)
114
- if existing_text && new_text != existing_text
115
- puts "ERROR: key #{key} already exists with text '#{existing_text.inspect}' and would be overwritten by new text '#{new_text}'. " +
116
- "Set environment variable OVERWRITE=1 if you really want to do this."
117
- overwrites = true
118
- end
119
- end
120
-
121
- if !overwrites || ENV['OVERWRITE']
122
- I18n.backend.store_translations(locale, new_translations[locale])
123
- Translate::Storage.new(locale).write_to_file
124
- end
125
- end
126
-
127
- desc "Apply Google translate to auto translate all texts in locale ENV['FROM'] to locale ENV['TO']"
128
- task :google => :environment do
129
- raise "Please specify FROM and TO locales as environment variables" if ENV['FROM'].blank? || ENV['TO'].blank?
130
-
131
- # Depends on httparty gem
132
- # http://www.robbyonrails.com/articles/2009/03/16/httparty-goes-foreign
133
- class GoogleApi
134
- include HTTParty
135
- base_uri 'ajax.googleapis.com'
136
- def self.translate(string, to, from)
137
- tries = 0
138
- begin
139
- get("/ajax/services/language/translate",
140
- :query => {:langpair => "#{from}|#{to}", :q => string, :v => 1.0},
141
- :format => :json)
142
- rescue
143
- tries += 1
144
- puts("SLEEPING - retrying in 5...")
145
- sleep(5)
146
- retry if tries < 10
147
- end
148
- end
149
- end
150
-
151
- I18n.backend.send(:init_translations)
152
-
153
- start_at = Time.now
154
- translations = {}
155
- Translate::Keys.new.i18n_keys(ENV['FROM']).each do |key|
156
- from_text = I18n.backend.send(:lookup, ENV['FROM'], key).to_s
157
- to_text = I18n.backend.send(:lookup, ENV['TO'], key)
158
- if !from_text.blank? && to_text.blank?
159
- print "#{key}: '#{from_text[0, 40]}' => "
160
- if !translations[from_text]
161
- response = GoogleApi.translate(from_text, ENV['TO'], ENV['FROM'])
162
- translations[from_text] = response["responseData"] && response["responseData"]["translatedText"]
163
- end
164
- if !(translation = translations[from_text]).blank?
165
- translation.gsub!(/\(\(([a-z_.]+)\)\)/i, '{{\1}}')
166
- # Google translate sometimes replaces {{foobar}} with (()) foobar. We skip these
167
- if translation !~ /\(\(\)\)/
168
- puts "'#{translation[0, 40]}'"
169
- I18n.backend.store_translations(ENV['TO'].to_sym, Translate::Keys.to_deep_hash({key => translation}))
170
- else
171
- puts "SKIPPING since interpolations were messed up: '#{translation[0,40]}'"
172
- end
173
- else
174
- puts "NO TRANSLATION - #{response.inspect}"
175
- end
176
- end
177
- end
178
-
179
- puts "\nTime elapsed: #{(((Time.now - start_at) / 60) * 10).to_i / 10.to_f} minutes"
180
- Translate::Storage.new(ENV['TO'].to_sym).write_to_file
181
- end
182
-
183
- desc "List keys that have changed I18n texts between YAML file ENV['FROM_FILE'] and YAML file ENV['TO_FILE']. Set ENV['VERBOSE'] to see changes"
184
- task :changed => :environment do
185
- from_hash = Translate::Keys.to_shallow_hash(Translate::File.new(ENV['FROM_FILE']).read)
186
- to_hash = Translate::Keys.to_shallow_hash(Translate::File.new(ENV['TO_FILE']).read)
187
- from_hash.each do |key, from_value|
188
- if (to_value = to_hash[key]) && to_value != from_value
189
- key_without_locale = key[/^[^.]+\.(.+)$/, 1]
190
- if ENV['VERBOSE']
191
- puts "KEY: #{key_without_locale}"
192
- puts "FROM VALUE: '#{from_value}'"
193
- puts "TO VALUE: '#{to_value}'"
194
- else
195
- puts key_without_locale
196
- end
197
- end
198
- end
199
- end
200
- end
1
+ require 'yaml'
2
+
3
+ class Hash
4
+ def deep_merge(other)
5
+ # deep_merge by Stefan Rusterholz, see http://www.ruby-forum.com/topic/142809
6
+ merger = proc { |key, v1, v2| (Hash === v1 && Hash === v2) ? v1.merge(v2, &merger) : v2 }
7
+ merge(other, &merger)
8
+ end
9
+
10
+ def set(keys, value)
11
+ key = keys.shift
12
+ if keys.empty?
13
+ self[key] = value
14
+ else
15
+ self[key] ||= {}
16
+ self[key].set keys, value
17
+ end
18
+ end
19
+
20
+ if ENV['SORT']
21
+ # copy of ruby's to_yaml method, prepending sort.
22
+ # before each so we get an ordered yaml file
23
+ def to_yaml( opts = {} )
24
+ YAML::quick_emit( self, opts ) do |out|
25
+ out.map( taguri, to_yaml_style ) do |map|
26
+ sort.each do |k, v| #<- Adding sort.
27
+ map.add( k, v )
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ namespace :translate do
36
+ desc "Show duplicate keys for locale LOCALE"
37
+ task :duplicates => :environment do
38
+ from_locale = I18n.default_locale
39
+ duplicates = Translate::Keys.new.duplicate_keys
40
+
41
+ messages = []
42
+ duplicates.each do |locale, keys|
43
+ keys.each do |key|
44
+ from_text = I18n.backend.send(:lookup, from_locale, key)
45
+ next if from_text.blank?
46
+ messages << "#{locale}.#{key} (#{from_locale}.#{key}='#{from_text}')"
47
+ end
48
+ end
49
+
50
+ if messages.present?
51
+ messages.each { |m| puts m }
52
+ else
53
+ puts "No duplicate keys"
54
+ end
55
+ end
56
+
57
+ desc "Show untranslated keys for locale LOCALE"
58
+ task :untranslated => :environment do
59
+ from_locale = I18n.default_locale
60
+ untranslated = Translate::Keys.new.untranslated_keys
61
+
62
+ messages = []
63
+ untranslated.each do |locale, keys|
64
+ keys.each do |key|
65
+ from_text = I18n.backend.send(:lookup, from_locale, key)
66
+ next if from_text.blank?
67
+ messages << "#{locale}.#{key} (#{from_locale}.#{key}='#{from_text}')"
68
+ end
69
+ end
70
+
71
+ if messages.present?
72
+ messages.each { |m| puts m }
73
+ else
74
+ puts "No untranslated keys"
75
+ end
76
+ end
77
+
78
+ desc "Show I18n keys that are missing in the config/locales/default_locale.yml YAML file"
79
+ task :missing => :environment do
80
+ missing = Translate::Keys.new.missing_keys.inject([]) do |keys, (key, filename)|
81
+ keys << "#{key} in \t #{filename} is missing"
82
+ end
83
+ puts missing.present? ? missing.join("\n") : "No missing translations in the default locale file"
84
+ end
85
+
86
+ desc "Remove all translation texts that are no longer present in the locale they were translated from"
87
+ task :remove_obsolete_keys => :environment do
88
+ I18n.backend.send(:init_translations)
89
+ master_locale = ENV['LOCALE'] || I18n.default_locale
90
+ Translate::Keys.translated_locales.each do |locale|
91
+ texts = {}
92
+ Translate::Keys.new.i18n_keys(locale).each do |key|
93
+ if I18n.backend.send(:lookup, master_locale, key).to_s.present?
94
+ texts[key] = I18n.backend.send(:lookup, locale, key)
95
+ end
96
+ end
97
+ I18n.backend.send(:translations)[locale] = nil # Clear out all current translations
98
+ I18n.backend.store_translations(locale, Translate::Keys.to_deep_hash(texts))
99
+ Translate::Storage.new(locale).write_to_file
100
+ end
101
+ end
102
+
103
+ desc "Merge I18n keys from log/translations.yml into config/locales/*.yml (for use with the Rails I18n TextMate bundle)"
104
+ task :merge_keys => :environment do
105
+ I18n.backend.send(:init_translations)
106
+ new_translations = YAML::load(IO.read(File.join(Rails.root, "log", "translations.yml")))
107
+ raise("Can only merge in translations in single locale") if new_translations.keys.size > 1
108
+ locale = new_translations.keys.first
109
+
110
+ overwrites = false
111
+ Translate::Keys.to_shallow_hash(new_translations[locale]).keys.each do |key|
112
+ new_text = key.split(".").inject(new_translations[locale]) { |hash, sub_key| hash[sub_key] }
113
+ existing_text = I18n.backend.send(:lookup, locale.to_sym, key)
114
+ if existing_text && new_text != existing_text
115
+ puts "ERROR: key #{key} already exists with text '#{existing_text.inspect}' and would be overwritten by new text '#{new_text}'. " +
116
+ "Set environment variable OVERWRITE=1 if you really want to do this."
117
+ overwrites = true
118
+ end
119
+ end
120
+
121
+ if !overwrites || ENV['OVERWRITE']
122
+ I18n.backend.store_translations(locale, new_translations[locale])
123
+ Translate::Storage.new(locale).write_to_file
124
+ end
125
+ end
126
+
127
+ desc "Apply Google translate to auto translate all texts in locale ENV['FROM'] to locale ENV['TO']"
128
+ task :google => :environment do
129
+ raise "Please specify FROM and TO locales as environment variables" if ENV['FROM'].blank? || ENV['TO'].blank?
130
+
131
+ # Depends on httparty gem
132
+ # http://www.robbyonrails.com/articles/2009/03/16/httparty-goes-foreign
133
+ class GoogleApi
134
+ include HTTParty
135
+ base_uri 'ajax.googleapis.com'
136
+ def self.translate(string, to, from)
137
+ tries = 0
138
+ begin
139
+ get("/ajax/services/language/translate",
140
+ :query => {:langpair => "#{from}|#{to}", :q => string, :v => 1.0},
141
+ :format => :json)
142
+ rescue
143
+ tries += 1
144
+ puts("SLEEPING - retrying in 5...")
145
+ sleep(5)
146
+ retry if tries < 10
147
+ end
148
+ end
149
+ end
150
+
151
+ I18n.backend.send(:init_translations)
152
+
153
+ start_at = Time.now
154
+ translations = {}
155
+ Translate::Keys.new.i18n_keys(ENV['FROM']).each do |key|
156
+ from_text = I18n.backend.send(:lookup, ENV['FROM'], key).to_s
157
+ to_text = I18n.backend.send(:lookup, ENV['TO'], key)
158
+ if !from_text.blank? && to_text.blank?
159
+ print "#{key}: '#{from_text[0, 40]}' => "
160
+ if !translations[from_text]
161
+ response = GoogleApi.translate(from_text, ENV['TO'], ENV['FROM'])
162
+ translations[from_text] = response["responseData"] && response["responseData"]["translatedText"]
163
+ end
164
+ if !(translation = translations[from_text]).blank?
165
+ translation.gsub!(/\(\(([a-z_.]+)\)\)/i, '{{\1}}')
166
+ # Google translate sometimes replaces {{foobar}} with (()) foobar. We skip these
167
+ if translation !~ /\(\(\)\)/
168
+ puts "'#{translation[0, 40]}'"
169
+ I18n.backend.store_translations(ENV['TO'].to_sym, Translate::Keys.to_deep_hash({key => translation}))
170
+ else
171
+ puts "SKIPPING since interpolations were messed up: '#{translation[0,40]}'"
172
+ end
173
+ else
174
+ puts "NO TRANSLATION - #{response.inspect}"
175
+ end
176
+ end
177
+ end
178
+
179
+ puts "\nTime elapsed: #{(((Time.now - start_at) / 60) * 10).to_i / 10.to_f} minutes"
180
+ Translate::Storage.new(ENV['TO'].to_sym).write_to_file
181
+ end
182
+
183
+ desc "List keys that have changed I18n texts between YAML file ENV['FROM_FILE'] and YAML file ENV['TO_FILE']. Set ENV['VERBOSE'] to see changes"
184
+ task :changed => :environment do
185
+ from_hash = Translate::Keys.to_shallow_hash(Translate::File.new(ENV['FROM_FILE']).read)
186
+ to_hash = Translate::Keys.to_shallow_hash(Translate::File.new(ENV['TO_FILE']).read)
187
+ from_hash.each do |key, from_value|
188
+ if (to_value = to_hash[key]) && to_value != from_value
189
+ key_without_locale = key[/^[^.]+\.(.+)$/, 1]
190
+ if ENV['VERBOSE']
191
+ puts "KEY: #{key_without_locale}"
192
+ puts "FROM VALUE: '#{from_value}'"
193
+ puts "TO VALUE: '#{to_value}'"
194
+ else
195
+ puts key_without_locale
196
+ end
197
+ end
198
+ end
199
+ end
200
+ end