couch_i18n 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -5,7 +5,15 @@ rescue LoadError
5
5
  puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
6
  end
7
7
 
8
- require 'rdoc/task'
8
+ begin
9
+ require 'rdoc/task'
10
+ rescue LoadError
11
+ require 'rdoc/rdoc'
12
+ require 'rake/rdoctask'
13
+ RDoc::Task = Rake::RDocTask
14
+ end
15
+ require 'rspec/core'
16
+ require 'rspec/core/rake_task'
9
17
 
10
18
  Rake::RDocTask.new(:rdoc) do |rdoc|
11
19
  rdoc.rdoc_dir = 'rdoc'
@@ -15,7 +23,10 @@ Rake::RDocTask.new(:rdoc) do |rdoc|
15
23
  rdoc.rdoc_files.include('lib/**/*.rb')
16
24
  end
17
25
 
18
- APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
26
+ RSpec::Core::RakeTask.new(:spec) do |spec|
27
+ spec.pattern = FileList['spec/**/*_spec.rb']
28
+ end
29
+ APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
19
30
  load 'rails/tasks/engine.rake'
20
31
 
21
32
  require 'rake/testtask'
@@ -28,4 +39,4 @@ Rake::TestTask.new(:test) do |t|
28
39
  end
29
40
 
30
41
 
31
- task :default => :test
42
+ task :default => :spec
@@ -55,8 +55,13 @@ tr.even{
55
55
  border-color: #444;
56
56
  border-left-width: 0;
57
57
  border-right-width: 0;
58
+ padding: 5px 0;
59
+ margin-top: 5px;
58
60
  .offset-navigation-deeper, .offset-navigation-higher{
59
61
  a{
62
+ float: left;
63
+ margin-right: 5px;
64
+ margin-top: 5px;
60
65
  padding: 4px;
61
66
  border: 1px solid #aaa;
62
67
  &:hover {
@@ -64,6 +69,11 @@ tr.even{
64
69
  border-color: black;
65
70
  }
66
71
  }
67
- padding: 8px;
68
72
  }
73
+ .offset-navigation-form{
74
+ margin-top: 5px;
75
+ }
76
+ }
77
+ .clearing{
78
+ clear: both;
69
79
  }
@@ -2,21 +2,37 @@ module CouchI18n
2
2
  class TranslationsController < CouchI18n::ApplicationController
3
3
  def index
4
4
  @available_higher_offsets = []
5
- if params[:offset].present?
6
- @levels = params[:offset].split('.')
7
- # Add higher levels. Do not add the last level, since it is the current one => 0..-2
8
- @levels[0..-2].each_with_index do |level_name, i|
9
- @available_higher_offsets << {
10
- :name => level_name,
11
- :offset => @levels[0..i].join('.')
12
- }
13
- end
14
- @translations = CouchI18n::Translation.with_offset(params[:offset], :page => params[:page], :per_page => 30)
15
- @available_deeper_offsets = CouchI18n::Translation.get_keys_by_level(@levels.size, :startkey => @levels, :endkey => @levels + [{}]).
16
- map{|dl| {:name => dl, :offset => [params[:offset], dl].join('.')}}
5
+ @available_deeper_offsets = []
6
+ per_page = params[:per_page].presence.try(:to_i) || 30
7
+ if params[:partfinder].present?
8
+ @translations = CouchI18n::Translation.find_all_by_key_part(params[:offset], page: params[:page], per_page: per_page)
9
+ elsif params[:valuefinder].present?
10
+ @translations = CouchI18n::Translation.find_all_by_value(params[:offset], page: params[:page], per_page: per_page)
17
11
  else
18
- @translations = CouchI18n::Translation.all(:page => params[:page], :per_page => 30)
19
- @available_deeper_offsets = CouchI18n::Translation.get_keys_by_level(0).map{|dl| {:name => dl, :offset => dl}}
12
+ if params[:offset].present?
13
+ @levels = params[:offset].split('.')
14
+ # Add higher levels. Do not add the last level, since it is the current one => 0..-2
15
+ @levels[0..-2].each_with_index do |level_name, i|
16
+ @available_higher_offsets << {
17
+ :name => level_name,
18
+ :offset => @levels[0..i].join('.')
19
+ }
20
+ end
21
+ if untranslated?
22
+ @translations = CouchI18n::Translation.untranslated_with_offset(params[:offset], :page => params[:page], :per_page => per_page)
23
+ else
24
+ @translations = CouchI18n::Translation.with_offset(params[:offset], :page => params[:page], :per_page => per_page)
25
+ end
26
+ @available_deeper_offsets = CouchI18n::Translation.get_keys_by_level(@levels.size, :startkey => @levels, :endkey => @levels + [{}]).
27
+ map{|dl| {:name => dl, :offset => [params[:offset], dl].join('.')}}
28
+ else
29
+ if untranslated?
30
+ @translations = CouchI18n::Translation.untranslated(:page => params[:page], :per_page => per_page)
31
+ else
32
+ @translations = CouchI18n::Translation.all(:page => params[:page], :per_page => per_page)
33
+ end
34
+ @available_deeper_offsets = CouchI18n::Translation.get_keys_by_level(0).map{|dl| {:name => dl, :offset => dl}}
35
+ end
20
36
  end
21
37
  end
22
38
 
@@ -138,5 +154,12 @@ module CouchI18n
138
154
  @translations.map(&:destroy)
139
155
  redirect_to({:action => :index}, :notice => I18n.t('couch_i18n.translation.offset deleted', :count => @translations.size, :offset => params[:offset]))
140
156
  end
157
+
158
+ private
159
+
160
+ def untranslated?
161
+ params[:untranslated].presence
162
+ end
163
+ helper_method :untranslated?
141
164
  end
142
165
  end
@@ -6,6 +6,14 @@ module CouchI18n
6
6
  end
7
7
  end
8
8
 
9
+ def partfinder?
10
+ params[:partfinder].present?
11
+ end
12
+
13
+ def valuefinder?
14
+ params[:valuefinder].present?
15
+ end
16
+
9
17
  def link_to_new_content(obj)
10
18
  t('couch_i18n.action.new.label')
11
19
  end
@@ -29,7 +29,7 @@ module CouchI18n
29
29
  emit(parts[i], 1);
30
30
  }
31
31
  }
32
- }|
32
+ }|, reduce_function: '_count'
33
33
 
34
34
  def self.get_keys_by_level(level = 0, options = {})
35
35
  data = database.view(with_key_array(options.merge(:group_level => level.succ)))["rows"]
@@ -42,16 +42,29 @@ module CouchI18n
42
42
  CouchI18n::Translation.find_all_by_key("#{offset}.".."#{offset}.ZZZZZZZZZ", options)
43
43
  end
44
44
 
45
- def self.find_all_by_key_part(part)
46
- database.view(by_key_part(key: part, reduce: false, include_docs: true))
45
+ # Find all records having the term part in their key
46
+ # nl.action.one
47
+ # en.action.two
48
+ # en.activemodel.plural.models.user
49
+ # and using
50
+ # find_all_by_part('action')
51
+ # will return the first two since they have action as key part
52
+ def self.find_all_by_key_part(part, options = {})
53
+ total_entries = database.view(by_key_part(key: part, reduce: true))
54
+ with_pagination_options options.merge(total_entries: total_entries) do |options|
55
+ database.view(by_key_part(options.merge(key: part, reduce: false, include_docs: true)))
56
+ end
47
57
  end
48
58
 
49
- def self.untranslated(*args)
50
- database.view(untranslated_view(*args))
59
+ def self.untranslated(options = {})
60
+ total_entries = database.view(untranslated_view(options.select{|k,v| [:key, :keys, :startkey, :endkey].include?(k)}.merge(reduce: true)))
61
+ with_pagination_options options.merge(total_entries: total_entries) do |options|
62
+ database.view(untranslated_view(options))
63
+ end
51
64
  end
52
65
 
53
66
  def self.untranslated_with_offset(offset, options = {})
54
- CouchI18n::Translation.untranslated("#{offset}.".."#{offset}.ZZZZZZZZZ", options)
67
+ CouchI18n::Translation.untranslated(options.merge(key: "#{offset}.".."#{offset}.ZZZZZZZZZ"))
55
68
  end
56
69
 
57
70
  # Expire I18n when record is update
@@ -6,11 +6,13 @@
6
6
  = link_to t('couch_i18n.action.destroy.offset_link'), couch_i18n.destroy_offset_translations_path(:offset => params[:offset]), :method => :delete, :confirm => (defined?(:are_you_sure) ? are_you_sure : t('couch_i18n.general.are_you_sure'))
7
7
  .import-form
8
8
  = form_tag({:action => :import}, :multipart => true) do
9
+ = label_tag :importfile, t('couch_i18n.import.label')
9
10
  = file_field_tag :importfile
10
11
  = submit_tag I18n.t('couch_i18n.import.button')
11
12
  .export-form
12
13
  = form_tag :action => :export do
13
14
  = hidden_field_tag :offset, params[:offset]
15
+ = label_tag :exportformat, t('couch_i18n.export.label')
14
16
  = select_tag :exportformat, options_for_select(%w[yml csv json], params[:exportformat])
15
17
  = check_box_tag :untranslated
16
18
  = label_tag :untranslated, t('couch_i18n.export.untranslated')
@@ -19,16 +21,22 @@
19
21
  .offset-navigation-higher
20
22
  - for offset in @available_higher_offsets
21
23
  = link_to offset[:name], :offset => offset[:offset]
24
+ .clearing
22
25
  .offset-navigation-form
23
26
  = form_tag({}, :method => :get )do
24
27
  - if params[:offset].present?
25
28
  = link_to I18n.t('couch_i18n.general.go_to_zero_offset'), :offset => nil
26
29
  = text_field_tag :offset, params[:offset], :size => 60
27
- = "(#{@translations.total_entries})"
28
- = submit_tag I18n.t('couch_i18n.general.go_to_offset')
30
+ = "(#{@translations.total_count})"
31
+ %input{:type => :submit, :name => :commit, :value => I18n.t('couch_i18n.general.go_to_offset')}
32
+ %input{:type => :submit, :name => :partfinder, :value => I18n.t('couch_i18n.general.find_part')}
33
+ %input{:type => :submit, :name => :valuefinder, :value => I18n.t('couch_i18n.general.find_value')}
34
+ = check_box_tag :untranslated, 1, untranslated?
35
+ = label_tag :untranslated, I18n.t('couch_i18n.general.untranslated_label')
29
36
  .offset-navigation-deeper
30
37
  - for offset in @available_deeper_offsets
31
38
  = link_to offset[:name], :offset => offset[:offset]
39
+ .clearing
32
40
  - if @translations.any?
33
41
  = paginate @translations, :right => 3, :left => 3
34
42
  %table.index-table
@@ -42,7 +50,11 @@
42
50
  %tbody
43
51
  - @translations.each do |translation|
44
52
  %tr{:class => cycle('odd', 'even')}
45
- %td= link_to translation.key[(params[:offset].try(:size) || 0)..-1].sub(/^\./, ''), couch_i18n.edit_translation_path(translation)
53
+ %td
54
+ - if partfinder? || valuefinder?
55
+ = link_to translation.key.sub(/^\./, ''), couch_i18n.edit_translation_path(translation)
56
+ - else
57
+ = link_to translation.key[(params[:offset].try(:size) || 0)..-1].sub(/^\./, ''), couch_i18n.edit_translation_path(translation)
46
58
  %td= link_to translation.value, couch_i18n.edit_translation_path(translation)
47
59
  %td.boolean= boolean_show(translation.translated)
48
60
  %td.action.edit= link_to link_to_edit_content(translation), couch_i18n.edit_translation_path(translation)
@@ -0,0 +1,49 @@
1
+ ---
2
+ en:
3
+ couch_i18n:
4
+ action:
5
+ edit:
6
+ title: Edit translation
7
+ destroy:
8
+ label: Delete
9
+ offset_link: Delete all from offset
10
+ edit:
11
+ label: Edit
12
+ index:
13
+ label: Translations
14
+ title: Translations
15
+ new:
16
+ label: New
17
+ update:
18
+ button_text: Update
19
+ export:
20
+ execute: Execute
21
+ untranslated: Untranslated
22
+ label: Export
23
+ general:
24
+ are_you_sure: 'Are you sure?'
25
+ boolean_false: 'no'
26
+ boolean_true: 'yes'
27
+ go_to_offset: Go to offset
28
+ go_to_zero_offset: x
29
+ find_part: Find key part
30
+ find_value: Find value
31
+ none_found: No translations found
32
+ site_title: CouchI18n translations
33
+ untranslated_title: Untranslated
34
+ import:
35
+ button: Import
36
+ label: Import
37
+ activemodel:
38
+ models:
39
+ couch_i18n:
40
+ translation: Translation
41
+ plural:
42
+ couch_i18n:
43
+ translation: Translations
44
+ attributes:
45
+ couch_i18n:
46
+ translation:
47
+ key: Key
48
+ value: Value
49
+ translated: 'Translated?'
@@ -1,7 +1,5 @@
1
1
  require 'i18n/backend/base'
2
2
  require 'active_support/json'
3
- require 'active_support/ordered_hash' # active_support/json/encoding uses ActiveSupport::OrderedHash but does not require it
4
- require "i18n/backend/cache"
5
3
  module CouchI18n
6
4
  class Backend
7
5
  # This is a basic backend for key value stores. It receives on
@@ -52,7 +50,6 @@ module CouchI18n
52
50
  attr_accessor :store
53
51
 
54
52
  include I18n::Backend::Base, I18n::Backend::Flatten
55
- include I18n::Backend::Cache
56
53
  def initialize(store, subtrees=true)
57
54
  @store, @subtrees = store, subtrees
58
55
  end
@@ -1,5 +1,6 @@
1
+ require 'i18n'
1
2
  module CouchI18n
2
- class Engine < Rails::Engine
3
+ class Engine < ::Rails::Engine
3
4
  isolate_namespace CouchI18n
4
5
  end
5
6
  end
@@ -17,7 +17,7 @@ module CouchI18n
17
17
  # alias for read
18
18
  def [](key, options = {})
19
19
  key = key.to_s.gsub('/', '.')
20
- Rails.cache.fetch(key) do
20
+ Rails.cache.fetch("couch_i18n-#{key}") do
21
21
  old_database_name = get_couchrest_name
22
22
  begin
23
23
  set_couchrest_name CouchPotato::Config.database_name # Set database to original configured name
data/lib/couch_i18n.rb CHANGED
@@ -4,8 +4,11 @@ require 'couch_i18n/backend'
4
4
  require 'couch_i18n/active_model_errors'
5
5
  module CouchI18n
6
6
  # This method imports yaml translations to the couchdb version. When run again new ones will
7
- # be added. Translations already stored in the couchdb database are not overwritten
8
- def self.import_from_yaml
7
+ # be added. Translations already stored in the couchdb database are not overwritten if true or ovveride_existing: true is given
8
+ def self.import_from_yaml(options = {})
9
+ options = {:override_existing => true} if options.is_a?(TrueClass)
10
+ options = {:override_existing => false} if options.is_a?(FalseClass)
11
+ options = {:override_existing => false}.merge!(options)
9
12
  raise "I18.backend not a I18n::Backend::Chain" unless I18n.backend.is_a?(I18n::Backend::Chain)
10
13
  #
11
14
  yml_backend = I18n.backend.backends.last
@@ -13,8 +16,16 @@ module CouchI18n
13
16
  raise "Last backend not a I18n::Backend::Simple" unless yml_backend.is_a?(I18n::Backend::Simple)
14
17
  yml_backend.load_translations
15
18
  flattened_hash = traverse_flatten_keys(yml_backend.send(:translations))
19
+ available_translations = CouchI18n::Translation.all
16
20
  flattened_hash.each do |key, value|
17
- CouchI18n::Translation.create :key => key, :value => value
21
+ available_translation = available_translations.find{|t| t.key == key}
22
+ if available_translation && options[:override_existing]
23
+ available_translation.value = value
24
+ available_translation.translated = true
25
+ available_translation.save
26
+ else
27
+ available_translation = CouchI18n::Translation.create :key => key, :value => value
28
+ end
18
29
  end
19
30
  end
20
31
 
@@ -58,9 +69,11 @@ module CouchI18n
58
69
  # Add all translations to the cache to avoid one by one loading and caching
59
70
  def self.cache_all
60
71
  CouchI18n::Translation.all.each do |t|
61
- Rails.cache.write(t.key, t.value)
72
+ Rails.cache.write("couch_i18n-#{t.key}", t.value)
62
73
  end
63
74
  end
64
75
  end
76
+
65
77
  # Now extend the I18n backend
66
78
  I18n.backend = I18n::Backend::Chain.new(CouchI18n::Backend.new(CouchI18n::Store.new), I18n.backend) unless Rails.env == 'test'
79
+ I18n.load_path += Dir.glob(File.join(File.dirname(__FILE__), '..', 'config', 'locales', '*'))
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: couch_i18n
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,22 +9,27 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-03-28 00:00:00.000000000Z
12
+ date: 2012-08-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activemodel
16
- requirement: &70199467348060 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
20
20
  - !ruby/object:Gem::Version
21
- version: '3'
21
+ version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70199467348060
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
25
30
  - !ruby/object:Gem::Dependency
26
31
  name: simply_stored
27
- requirement: &70199467347600 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
28
33
  none: false
29
34
  requirements:
30
35
  - - ! '>='
@@ -32,7 +37,12 @@ dependencies:
32
37
  version: '0'
33
38
  type: :runtime
34
39
  prerelease: false
35
- version_requirements: *70199467347600
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
36
46
  description: couch_i18n is an in database storage for I18n translations, tested for
37
47
  rails, with online management views
38
48
  email: bterkuile@gmail.com
@@ -64,6 +74,7 @@ files:
64
74
  - app/views/couch_i18n/translations/index.html.haml
65
75
  - app/views/couch_i18n/translations/new.html.haml
66
76
  - app/views/layouts/couch_i18n/application.html.haml
77
+ - config/locales/couch_i18n.en.yml
67
78
  - config/routes.rb
68
79
  - MIT-LICENSE
69
80
  - Rakefile
@@ -88,7 +99,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
88
99
  version: '0'
89
100
  requirements: []
90
101
  rubyforge_project: couch_i18n
91
- rubygems_version: 1.8.15
102
+ rubygems_version: 1.8.24
92
103
  signing_key:
93
104
  specification_version: 3
94
105
  summary: couch_i18n is an in database storage for I18n translations, tested for rails,