tr8n_core 4.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +22 -0
  3. data/README.md +69 -0
  4. data/Rakefile +9 -0
  5. data/config/config.yml +34 -0
  6. data/config/tokens/data.yml +45 -0
  7. data/config/tokens/decorations.yml +37 -0
  8. data/lib/tr8n/application.rb +320 -0
  9. data/lib/tr8n/base.rb +123 -0
  10. data/lib/tr8n/cache.rb +144 -0
  11. data/lib/tr8n/cache_adapters/cdb.rb +74 -0
  12. data/lib/tr8n/cache_adapters/file.rb +70 -0
  13. data/lib/tr8n/cache_adapters/memcache.rb +91 -0
  14. data/lib/tr8n/cache_adapters/redis.rb +94 -0
  15. data/lib/tr8n/component.rb +68 -0
  16. data/lib/tr8n/config.rb +291 -0
  17. data/lib/tr8n/decorators/base.rb +35 -0
  18. data/lib/tr8n/decorators/default.rb +30 -0
  19. data/lib/tr8n/decorators/html.rb +63 -0
  20. data/lib/tr8n/exception.rb +26 -0
  21. data/lib/tr8n/language.rb +250 -0
  22. data/lib/tr8n/language_case.rb +116 -0
  23. data/lib/tr8n/language_case_rule.rb +85 -0
  24. data/lib/tr8n/language_context.rb +115 -0
  25. data/lib/tr8n/language_context_rule.rb +62 -0
  26. data/lib/tr8n/logger.rb +83 -0
  27. data/lib/tr8n/rules_engine/evaluator.rb +156 -0
  28. data/lib/tr8n/rules_engine/parser.rb +83 -0
  29. data/lib/tr8n/source.rb +95 -0
  30. data/lib/tr8n/tokens/data.rb +410 -0
  31. data/lib/tr8n/tokens/data_tokenizer.rb +82 -0
  32. data/lib/tr8n/tokens/decoration_tokenizer.rb +200 -0
  33. data/lib/tr8n/tokens/hidden.rb +48 -0
  34. data/lib/tr8n/tokens/method.rb +52 -0
  35. data/lib/tr8n/tokens/transform.rb +191 -0
  36. data/lib/tr8n/translation.rb +104 -0
  37. data/lib/tr8n/translation_key.rb +205 -0
  38. data/lib/tr8n/translator.rb +62 -0
  39. data/lib/tr8n/utils.rb +124 -0
  40. data/lib/tr8n_core/ext/array.rb +74 -0
  41. data/lib/tr8n_core/ext/date.rb +63 -0
  42. data/lib/tr8n_core/ext/fixnum.rb +39 -0
  43. data/lib/tr8n_core/ext/hash.rb +126 -0
  44. data/lib/tr8n_core/ext/string.rb +44 -0
  45. data/lib/tr8n_core/ext/time.rb +71 -0
  46. data/lib/tr8n_core/generators/cache/base.rb +85 -0
  47. data/lib/tr8n_core/generators/cache/cdb.rb +27 -0
  48. data/lib/tr8n_core/generators/cache/file.rb +69 -0
  49. data/lib/tr8n_core/modules/logger.rb +43 -0
  50. data/lib/tr8n_core/version.rb +27 -0
  51. data/lib/tr8n_core.rb +68 -0
  52. data/spec/application_spec.rb +228 -0
  53. data/spec/base_spec.rb +19 -0
  54. data/spec/config_spec.rb +16 -0
  55. data/spec/decorator_spec.rb +10 -0
  56. data/spec/decorators/base_spec.rb +14 -0
  57. data/spec/decorators/default_spec.rb +12 -0
  58. data/spec/decorators/html_spec.rb +50 -0
  59. data/spec/fixtures/application.json +112 -0
  60. data/spec/fixtures/languages/en-US.json +1424 -0
  61. data/spec/fixtures/languages/es.json +291 -0
  62. data/spec/fixtures/languages/ru.json +550 -0
  63. data/spec/fixtures/translations/ru/basic.json +56 -0
  64. data/spec/fixtures/translations/ru/counters.json +43 -0
  65. data/spec/fixtures/translations/ru/genders.json +171 -0
  66. data/spec/fixtures/translations/ru/last_names.txt +200 -0
  67. data/spec/fixtures/translations/ru/names.json +1 -0
  68. data/spec/fixtures/translations/ru/names.txt +458 -0
  69. data/spec/helper.rb +84 -0
  70. data/spec/language_case_rule_spec.rb +57 -0
  71. data/spec/language_case_spec.rb +58 -0
  72. data/spec/language_context_rule_spec.rb +73 -0
  73. data/spec/language_context_spec.rb +331 -0
  74. data/spec/language_spec.rb +16 -0
  75. data/spec/rules_engine/evaluator_spec.rb +148 -0
  76. data/spec/rules_engine/parser_spec.rb +29 -0
  77. data/spec/tokens/data_spec.rb +160 -0
  78. data/spec/tokens/data_tokenizer_spec.rb +29 -0
  79. data/spec/tokens/decoration_tokenizer_spec.rb +81 -0
  80. data/spec/tokens/hidden_spec.rb +24 -0
  81. data/spec/tokens/method_spec.rb +84 -0
  82. data/spec/tokens/transform_spec.rb +50 -0
  83. data/spec/translation_key_spec.rb +96 -0
  84. data/spec/translation_spec.rb +24 -0
  85. data/spec/utils_spec.rb +64 -0
  86. metadata +176 -0
data/lib/tr8n/cache.rb ADDED
@@ -0,0 +1,144 @@
1
+ #--
2
+ # Copyright (c) 2013 Michael Berkovich, tr8nhub.com
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+ module Tr8n
25
+
26
+ def self.cache
27
+ @cache ||= begin
28
+ if Tr8n.config.cache_enabled?
29
+ klass = Tr8n::CacheAdapters.const_get(Tr8n.config.cache_adapter.camelcase)
30
+ klass.new
31
+ else
32
+ # blank implementation
33
+ Tr8n::Cache.new
34
+ end
35
+ end
36
+ end
37
+
38
+ class Cache
39
+
40
+ def version
41
+ @version ||= begin
42
+ v = fetch('tr8n_cache_version', :skip_version => true)
43
+ v ? v['version'] : Tr8n.config.cache_version
44
+ end
45
+ end
46
+
47
+ def upgrade_version
48
+ store('tr8n_cache_version', {'version' => version + 1}, :ttl => 0, :skip_version => true)
49
+ @version = nil
50
+ end
51
+
52
+ def reset_version
53
+ @version = nil
54
+ end
55
+
56
+ def enabled?
57
+ Tr8n.config.cache_enabled?
58
+ end
59
+
60
+ def cached_by_source?
61
+ true
62
+ end
63
+
64
+ def read_only?
65
+ true
66
+ end
67
+
68
+ def cache_name
69
+ self.class.name.underscore.split('_').last
70
+ end
71
+
72
+ def info(msg)
73
+ Tr8n.logger.info("#{cache_name} - #{msg}")
74
+ end
75
+
76
+ def warn(msg)
77
+ Tr8n.logger.warn("#{cache_name} - #{msg}")
78
+ end
79
+
80
+ def versioned_key(key, opts = {})
81
+ return key if opts[:skip_version]
82
+ "tr8n_rc_v#{version}_#{key}"
83
+ end
84
+
85
+ def fetch(key, opts = {})
86
+ return nil unless block_given?
87
+ yield
88
+ end
89
+
90
+ def store(key, data, opts = {})
91
+ # do nothing
92
+ end
93
+
94
+ def delete(key, opts = {})
95
+ # do nothing
96
+ end
97
+
98
+ def exist?(key, opts = {})
99
+ false
100
+ end
101
+
102
+ def clear(opts = {})
103
+ # do nothing
104
+ end
105
+
106
+ def serialize_object(key, data)
107
+ if [Tr8n::Application.cache_prefix,
108
+ Tr8n::Language.cache_prefix,
109
+ Tr8n::Source.cache_prefix,
110
+ Tr8n::Component.cache_prefix,
111
+ Tr8n::TranslationKey.cache_prefix].include?(key[0..1])
112
+ json_data = data.to_cache_hash.to_json
113
+ else
114
+ # the data must be in cacheable form - usually API responses
115
+ json_data = data.to_json
116
+ end
117
+
118
+ #info(json_data)
119
+ json_data
120
+ end
121
+
122
+ def deserialize_object(key, data)
123
+ #info(data.inspect)
124
+
125
+ case key[0..1]
126
+ when Tr8n::Application.cache_prefix
127
+ return Tr8n::Application.new(JSON.parse(data))
128
+ when Tr8n::Language.cache_prefix
129
+ return Tr8n::Language.new(JSON.parse(data).merge(:application => Tr8n.config.application))
130
+ when Tr8n::Source.cache_prefix
131
+ return Tr8n::Source.new(JSON.parse(data).merge(:application => Tr8n.config.application))
132
+ when Tr8n::Component.cache_prefix
133
+ return Tr8n::Component.new(JSON.parse(data).merge(:application => Tr8n.config.application))
134
+ when Tr8n::TranslationKey.cache_prefix
135
+ return Tr8n::TranslationKey.new(JSON.parse(data).merge(:application => Tr8n.config.application))
136
+ end
137
+
138
+ # API response form will be here
139
+ JSON.parse(data)
140
+ end
141
+
142
+
143
+ end
144
+ end
@@ -0,0 +1,74 @@
1
+ #--
2
+ # Copyright (c) 2013 Michael Berkovich, tr8nhub.com
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+ require 'libcdb' if defined?(LibCDB)
25
+
26
+ class Tr8n::CacheAdapters::Cdb < Tr8n::Cache
27
+
28
+ def initialize
29
+ @cache = LibCDB::CDB.open(cache_path)
30
+ end
31
+
32
+ def self.cache_path
33
+ "#{Tr8n.config.cache_path}/cdb/current.cdb"
34
+ end
35
+
36
+ def cached_by_source?
37
+ false
38
+ end
39
+
40
+ def fetch(key, opts = {})
41
+ data = @cache[key]
42
+ if data
43
+ info("Cache hit: #{key}")
44
+ return deserialize_object(key, data)
45
+ end
46
+
47
+ info("Cache miss: #{key}")
48
+
49
+ return nil unless block_given?
50
+
51
+ yield
52
+ rescue Exception => ex
53
+ warn("Failed to retrieve data: #{ex.message}")
54
+ return nil unless block_given?
55
+ yield
56
+ end
57
+
58
+ def store(key, data, opts = {})
59
+ warn("This is a readonly cache")
60
+ end
61
+
62
+ def delete(key, opts = {})
63
+ warn("This is a readonly cache")
64
+ end
65
+
66
+ def exist?(key, opts = {})
67
+ @cache[key]
68
+ end
69
+
70
+ def clear(opts = {})
71
+ warn("This is a readonly cache")
72
+ end
73
+
74
+ end
@@ -0,0 +1,70 @@
1
+ #--
2
+ # Copyright (c) 2013 Michael Berkovich, tr8nhub.com
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+ class Tr8n::CacheAdapters::File < Tr8n::Cache
25
+
26
+ def self.cache_path
27
+ "#{Tr8n.config.cache_path}/files/current"
28
+ end
29
+
30
+ def self.file_name(key)
31
+ "#{key.gsub(/[\.\/]/, '-')}.json"
32
+ end
33
+
34
+ def self.file_path(key)
35
+ "#{cache_path}/#{file_name(key)}"
36
+ end
37
+
38
+ def fetch(key, opts = {})
39
+ path = self.class.file_path(key)
40
+
41
+ if File.exists?(path)
42
+ info("Cache hit: #{key}")
43
+ data = File.read(path)
44
+ return deserialize_object(key, data)
45
+ end
46
+
47
+ info("Cache miss: #{key}")
48
+
49
+ return nil unless block_given?
50
+
51
+ yield
52
+ end
53
+
54
+ def store(key, data, opts = {})
55
+ warn("This is a readonly cache")
56
+ end
57
+
58
+ def delete(key, opts = {})
59
+ warn("This is a readonly cache")
60
+ end
61
+
62
+ def exist?(key, opts = {})
63
+ File.exists(file_path(key))
64
+ end
65
+
66
+ def clear(opts = {})
67
+ warn("This is a readonly cache")
68
+ end
69
+
70
+ end
@@ -0,0 +1,91 @@
1
+ #--
2
+ # Copyright (c) 2013 Michael Berkovich, tr8nhub.com
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+ require 'dalli' if defined?(Dalli)
25
+
26
+ class Tr8n::CacheAdapters::Memcache < Tr8n::Cache
27
+
28
+ def initialize
29
+ options = { :namespace => "tr8n", :compress => true }
30
+ @cache = Dalli::Client.new(Tr8n.config.cache_host, options)
31
+ end
32
+
33
+ def read_only?
34
+ false
35
+ end
36
+
37
+ def fetch(key, opts = {})
38
+ data = @cache.get(versioned_key(key, opts))
39
+ if data
40
+ info("Cache hit: #{key}")
41
+ return deserialize_object(key, data)
42
+ end
43
+
44
+ info("Cache miss: #{key}")
45
+
46
+ return nil unless block_given?
47
+
48
+ data = yield
49
+
50
+ store(key, data)
51
+
52
+ data
53
+ rescue Exception => ex
54
+ warn("Failed to retrieve data: #{ex.message}")
55
+ return nil unless block_given?
56
+ yield
57
+ end
58
+
59
+ def store(key, data, opts = {})
60
+ info("Cache store: #{key}")
61
+ ttl = opts[:ttl] || Tr8n.config.cache_timeout
62
+ @cache.set(versioned_key(key, opts), serialize_object(key, data), ttl)
63
+ data
64
+ rescue Exception => ex
65
+ warn("Failed to store data: #{ex.message}")
66
+ data
67
+ end
68
+
69
+ def delete(key, opts = {})
70
+ info("Cache delete: #{key}")
71
+ @cache.delete(versioned_key(key, opts))
72
+ key
73
+ rescue Exception => ex
74
+ warn("Failed to delete data: #{ex.message}")
75
+ key
76
+ end
77
+
78
+ def exist?(key, opts = {})
79
+ data = @cache.get(versioned_key(key, opts))
80
+ not data.nil?
81
+ rescue Exception => ex
82
+ warn("Failed to check if key exists: #{ex.message}")
83
+ false
84
+ end
85
+
86
+ def clear(opts = {})
87
+ info("Cache clear")
88
+ rescue Exception => ex
89
+ warn("Failed to clear cache: #{ex.message}")
90
+ end
91
+ end
@@ -0,0 +1,94 @@
1
+ #--
2
+ # Copyright (c) 2013 Michael Berkovich, tr8nhub.com
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+ require 'redis' if defined?(::Redis)
25
+
26
+ class Tr8n::CacheAdapters::Redis < Tr8n::Cache
27
+
28
+ def initialize
29
+ cache_host, cache_port = Tr8n.config.cache_host.split(':') if Tr8n.config.cache_host
30
+ cache_host ||= 'localhost'
31
+ cache_port ||= 6379
32
+
33
+ @cache = ::Redis.new(host: cache_host, port: cache_port)
34
+ end
35
+
36
+ def read_only?
37
+ false
38
+ end
39
+
40
+ def fetch(key, opts = {})
41
+ data = @cache.get(versioned_key(key, opts))
42
+ if data
43
+ info("Cache hit: #{key}")
44
+ return deserialize_object(key, data)
45
+ end
46
+
47
+ info("Cache miss: #{key}")
48
+
49
+ return nil unless block_given?
50
+
51
+ data = yield
52
+
53
+ store(key, data)
54
+
55
+ data
56
+ rescue Exception => ex
57
+ warn("Failed to retrieve data: #{ex.message}")
58
+ return nil unless block_given?
59
+ yield
60
+ end
61
+
62
+ def store(key, data, opts = {})
63
+ info("Cache store: #{key}")
64
+ ttl = opts[:ttl] || Tr8n.config.cache_timeout
65
+ versioned_key = versioned_key(key, opts)
66
+
67
+ @cache.set(versioned_key, serialize_object(key, data))
68
+ @cache.expire(versioned_key, ttl) if ttl and ttl > 0
69
+ rescue Exception => ex
70
+ warn("Failed to store data: #{ex.message}")
71
+ data
72
+ end
73
+
74
+ def delete(key, opts = {})
75
+ info("Cache delete: #{key}")
76
+ @cache.del(versioned_key(key, opts))
77
+ rescue Exception => ex
78
+ warn("Failed to delete data: #{ex.message}")
79
+ key
80
+ end
81
+
82
+ def exist?(key, opts = {})
83
+ data = @cache.exist(versioned_key(key, opts))
84
+ not data.nil?
85
+ rescue Exception => ex
86
+ warn("Failed to check if key exists: #{ex.message}")
87
+ false
88
+ end
89
+
90
+ def clear(opts = {})
91
+ info("Cache clear has no effect")
92
+ end
93
+
94
+ end
@@ -0,0 +1,68 @@
1
+ #--
2
+ # Copyright (c) 2013 Michael Berkovich, tr8nhub.com
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+ class Tr8n::Component < Tr8n::Base
25
+ belongs_to :application
26
+ attributes :key, :name, :description, :state
27
+
28
+ def sources
29
+ application.get("component/sources", {:key => key}, {:class => Tr8n::Source, :application => application})
30
+ end
31
+
32
+ def translators
33
+ application.get("component/translators", {:key => key}, {:class => Tr8n::Translator, :application => application})
34
+ end
35
+
36
+ def languages
37
+ application.get("component/languages", {:key => key}, {:class => Tr8n::Language, :application => application})
38
+ end
39
+
40
+ def register_source(source)
41
+ application.post("component/register_source", {:key => key, :source => source.source})
42
+ end
43
+
44
+ def restricted?
45
+ state == 'restricted'
46
+ end
47
+
48
+ def live?
49
+ state == 'live'
50
+ end
51
+
52
+ def translator_authorized?(translator)
53
+ return true unless restricted?
54
+ translators.include?(translator)
55
+ end
56
+
57
+ #######################################################################################################
58
+ ## Cache Methods
59
+ #######################################################################################################
60
+
61
+ def self.cache_prefix
62
+ 'c@'
63
+ end
64
+
65
+ def self.cache_key(key)
66
+ "#{cache_prefix}_[#{key}]"
67
+ end
68
+ end