ceritium-lost-in-translation 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,82 @@
1
+ = LostInTranslation
2
+
3
+ == Description
4
+
5
+ LostInTranslation es una pequeña gema que nos puede ayudar a mantener al día las traducciones en nuestras aplicaciones que tiren la API I18n de RAILS y que tengan como backend los ficheros yaml.
6
+
7
+
8
+ == Installation
9
+
10
+ sudo gem install lost-in-translation
11
+
12
+ == Uso
13
+
14
+
15
+ Su uso es muy sencillo, con solo dos comandos lineas ya puedes recorrer todo el directorio _app_ de tu aplicación y añadir los traducción que anden sueltas al fichero _en.yaml_.
16
+
17
+ require 'lost_in_translation'
18
+
19
+
20
+ i18n = LostInTranslation.new
21
+ i18n.save_translations
22
+
23
+ También tienes otros métodos disponibles para configurar el idioma o el archivo de destino.
24
+
25
+ i18n = LostInTranslation.new
26
+
27
+ # Pone el español como el idioma de destino
28
+ i18n.locale = 'es'
29
+
30
+ # Si por ejemplo queremos almacenar las traducciónes en otro archivo, en este case será prueba_es.yaml
31
+ i18n.file = 'prueba_es'
32
+
33
+ i18n.save
34
+
35
+
36
+ == TODO
37
+
38
+ - Tests
39
+ - Añadir a varios idiomas a la vez
40
+ - Traducir
41
+
42
+ == Fedback
43
+
44
+ Se agradece todo el feedback posible, desde errores, casos de uso o posibles mejoras.
45
+
46
+ Blog:
47
+ http://ceritium.net/476/programacion/rails/lost-in-translation
48
+
49
+ Correo: ceritium@gmail.com
50
+
51
+ <b>Fork Me!</b>
52
+
53
+ == Agradecimientos
54
+
55
+ Al plugin Translate del que pillo algunos métodos.
56
+ http://github.com/newsdesk/translate/tree/master
57
+
58
+
59
+ == License
60
+
61
+ Copyright (c) <year> <copyright holders>
62
+
63
+ Permission is hereby granted, free of charge, to any person
64
+ obtaining a copy of this software and associated documentation
65
+ files (the "Software"), to deal in the Software without
66
+ restriction, including without limitation the rights to use,
67
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
68
+ copies of the Software, and to permit persons to whom the
69
+ Software is furnished to do so, subject to the following
70
+ conditions:
71
+
72
+ The above copyright notice and this permission notice shall be
73
+ included in all copies or substantial portions of the Software.
74
+
75
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
76
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
77
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
78
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
79
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
80
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
81
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
82
+ OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,40 @@
1
+ require 'rubygems'
2
+ require 'rake/gempackagetask'
3
+ require 'rake/testtask'
4
+
5
+ require 'lib/lost_in_translation/version'
6
+
7
+ task :default => :test
8
+
9
+ spec = Gem::Specification.new do |s|
10
+ s.name = 'lost-in-translation'
11
+ s.version = LostInTranslation::Version.to_s
12
+ s.has_rdoc = true
13
+ s.extra_rdoc_files = %w(README.rdoc)
14
+ s.rdoc_options = %w(--main README.rdoc)
15
+ s.summary = "This gem does ... "
16
+ s.author = 'First Last'
17
+ s.email = 'user@example.com'
18
+ s.homepage = 'http://my-site.net'
19
+ s.files = %w(README.rdoc Rakefile) + Dir.glob("{lib,test}/**/*")
20
+ # s.executables = ['lost-in-translation']
21
+
22
+ # s.add_dependency('gem_name', '~> 0.0.1')
23
+ end
24
+
25
+ Rake::GemPackageTask.new(spec) do |pkg|
26
+ pkg.gem_spec = spec
27
+ end
28
+
29
+ Rake::TestTask.new do |t|
30
+ t.libs << 'test'
31
+ t.test_files = FileList["test/**/*_test.rb"]
32
+ t.verbose = true
33
+ end
34
+
35
+ desc 'Generate the gemspec to serve this Gem from Github'
36
+ task :github do
37
+ file = File.dirname(__FILE__) + "/#{spec.name}.gemspec"
38
+ File.open(file, 'w') {|f| f << spec.to_ruby }
39
+ puts "Created gemspec: #{file}"
40
+ end
@@ -0,0 +1,5 @@
1
+ #$:.unshift File.dirname(__FILE__)
2
+
3
+ require 'pathname'
4
+ require 'lost_in_translation/lost_in_translation'
5
+
@@ -0,0 +1,117 @@
1
+ class LostInTranslation
2
+ # Expresión regular para recoger todas las cadenas de traducción de la aplicación
3
+ MATCH = /\b(?:I18n\.t|I18n\.translate|t)(?:\s|\():?'([a-z0-9_]+.[a-z0-9_.]+)'\)?/
4
+
5
+ attr_accessor :file, :locale, :path
6
+
7
+ def initialize
8
+ @locale = 'en'
9
+ @file = "config/locales/#{@locale}.yml"
10
+ @translations = []
11
+ @hash = {}
12
+ @path = 'app/'
13
+ end
14
+
15
+ # Escaneamos la carpeta en busca de todas las cadenas coincidentes con la expresión regular
16
+ def scan
17
+ @translations = []
18
+ Pathname.new(@path).find do |path|
19
+ if can_open?(path)
20
+ read_file(path)
21
+ end
22
+ end
23
+ @translations.flatten!
24
+ end
25
+
26
+ def store
27
+ scan if @translations.empty?
28
+ @translations.each do |translation|
29
+ key_value = to_deep_hash({translation => nil})
30
+ translation = deep_symbolize_keys(key_value)
31
+ merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2 }
32
+ @hash.merge!(translation, &merger)
33
+ end
34
+ @hash = deep_stringify_keys({@locale => @hash})
35
+ end
36
+
37
+ # Guarda en el .yml las nuevas traducciones encontradas
38
+ def save
39
+ store if @hash.empty?
40
+ File.open(@file, "w") do |file|
41
+ file.puts @hash.to_yaml
42
+ end
43
+ end
44
+
45
+
46
+ private
47
+
48
+ def deep_symbolize_keys(hash)
49
+ hash.inject({}) { |result, (key, value)|
50
+ value = deep_symbolize_keys(value) if value.is_a? Hash
51
+ result[(key.to_sym rescue key) || key] = value
52
+ result
53
+ }
54
+ end
55
+
56
+ def to_deep_hash(hash)
57
+ hash.inject({}) do |deep_hash, (key, value)|
58
+ keys = key.split('.').reverse
59
+ leaf_key = keys.shift
60
+ key_hash = keys.inject({leaf_key.to_sym => value}) { |hash, key| {key.to_sym => hash} }
61
+ deep_merge!(deep_hash, key_hash)
62
+ deep_hash
63
+ end
64
+ end
65
+
66
+ def deep_merge!(hash1, hash2)
67
+ merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2 }
68
+ hash1.merge!(hash2, &merger)
69
+ end
70
+
71
+ def deep_stringify_keys(hash)
72
+ hash.inject({}) { |result, (key, value)|
73
+ value = deep_stringify_keys(value) if value.is_a? Hash
74
+ result[(key.to_s rescue key) || key] = value
75
+ result
76
+ }
77
+ end
78
+
79
+ # Convertimos el hash que le pasemos a un array
80
+ # NOTA: Este método está sacado del plugin translate
81
+ # http://github.com/newsdesk/translate
82
+ def extract_i18n_keys(hash, parent_keys = [])
83
+ hash.inject([]) do |keys, (key, value)|
84
+ full_key = parent_keys + [key]
85
+ if value.is_a?(Hash)
86
+ # Nested hash
87
+ keys += extract_i18n_keys(value, full_key)
88
+ elsif value.present?
89
+ # String leaf node
90
+ keys << full_key.join(".")
91
+ end
92
+ keys
93
+ end
94
+ end
95
+
96
+ # Comprueba si es un fichero y si puedo leerlo
97
+ def can_open?(path)
98
+ !path.directory? && !path.zero? && path.readable?
99
+ end
100
+
101
+ # Leemos el fichero de donde sacaremos las traducciones del tipo t()
102
+ def read_file(file)
103
+ file.readlines.each do |line|
104
+ scan_line(line)
105
+ end
106
+ end
107
+
108
+ # Escaneamos la linea busqueda de cadenas del tipo t()
109
+ # y añadimos las coincidencias a @translations
110
+ def scan_line(line)
111
+ line.scan(MATCH) do |match|
112
+ @translations << match
113
+ end
114
+ end
115
+
116
+ end
117
+
@@ -0,0 +1,13 @@
1
+ module LostInTranslation
2
+ module Version
3
+
4
+ MAJOR = 0
5
+ MINOR = 1
6
+ TINY = 0
7
+
8
+ def self.to_s # :nodoc:
9
+ [MAJOR, MINOR, TINY].join('.')
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,10 @@
1
+ # http://sneaq.net/textmate-wtf
2
+ $:.reject! { |e| e.include? 'TextMate' }
3
+
4
+ require 'rubygems'
5
+ require 'test/unit'
6
+ require 'matchy'
7
+ require 'context'
8
+ require 'mocha'
9
+
10
+ require File.dirname(__FILE__) + '/../lib/lost_in_translation'
@@ -0,0 +1,13 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class LostInTranslationTest < Test::Unit::TestCase
4
+
5
+ describe "An instance of the LostInTranslation class" do
6
+
7
+ it "should flunk" do
8
+ flunk "Please provide some tests"
9
+ end
10
+
11
+ end
12
+
13
+ end
metadata ADDED
@@ -0,0 +1,62 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ceritium-lost-in-translation
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - First Last
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-06-28 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: user@example.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.rdoc
24
+ files:
25
+ - README.rdoc
26
+ - Rakefile
27
+ - lib/lost_in_translation
28
+ - lib/lost_in_translation/lost_in_translation.rb
29
+ - lib/lost_in_translation/version.rb
30
+ - lib/lost_in_translation.rb
31
+ - test/test_helper.rb
32
+ - test/unit
33
+ - test/unit/lost_in_translation_test.rb
34
+ has_rdoc: true
35
+ homepage: http://my-site.net
36
+ post_install_message:
37
+ rdoc_options:
38
+ - --main
39
+ - README.rdoc
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: "0"
47
+ version:
48
+ required_rubygems_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: "0"
53
+ version:
54
+ requirements: []
55
+
56
+ rubyforge_project:
57
+ rubygems_version: 1.2.0
58
+ signing_key:
59
+ specification_version: 2
60
+ summary: This gem does ...
61
+ test_files: []
62
+