couch_i18n 0.1.0 → 0.2.0

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.
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,