tr8n 3.1.1 → 3.1.2

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.
Files changed (265) hide show
  1. data/.gitignore +6 -3
  2. data/.rspec +2 -0
  3. data/Gemfile +3 -6
  4. data/Gemfile.lock +21 -6
  5. data/README.rdoc +61 -33
  6. data/Rakefile +1 -11
  7. data/app/assets/images/tr8n/photo_system.gif +0 -0
  8. data/app/assets/stylesheets/tr8n/application.css +42 -1
  9. data/{test/dummy/app/assets/stylesheets/components.css.scss → app/assets/stylesheets/tr8n/component.css.scss} +0 -0
  10. data/{test/dummy/app/assets/stylesheets → app/assets/stylesheets/tr8n}/layout.css.scss +0 -0
  11. data/app/assets/stylesheets/tr8n/tr8n.css.scss +16 -8
  12. data/app/controllers/tr8n/admin/base_controller.rb +1 -1
  13. data/app/controllers/tr8n/admin/clientsdk_controller.rb +1 -1
  14. data/app/controllers/tr8n/admin/domain_controller.rb +1 -1
  15. data/app/controllers/tr8n/admin/forum_controller.rb +1 -1
  16. data/app/controllers/tr8n/admin/glossary_controller.rb +1 -1
  17. data/app/controllers/tr8n/admin/language_controller.rb +1 -1
  18. data/app/controllers/tr8n/admin/translation_controller.rb +1 -1
  19. data/app/controllers/tr8n/admin/translation_key_controller.rb +5 -1
  20. data/app/controllers/tr8n/admin/translator_controller.rb +1 -1
  21. data/app/{helpers/tr8n/application_helper.rb → controllers/tr8n/api/v1/sync_controller.rb} +6 -3
  22. data/app/controllers/tr8n/awards_controller.rb +12 -12
  23. data/app/controllers/tr8n/base_controller.rb +140 -137
  24. data/app/controllers/tr8n/dashboard_controller.rb +2 -1
  25. data/app/controllers/tr8n/forum_controller.rb +1 -1
  26. data/app/controllers/tr8n/glossary_controller.rb +1 -1
  27. data/app/controllers/tr8n/help_controller.rb +1 -1
  28. data/app/controllers/tr8n/language_cases_controller.rb +43 -45
  29. data/app/controllers/tr8n/language_controller.rb +1 -1
  30. data/app/controllers/tr8n/phrases_controller.rb +1 -1
  31. data/app/controllers/tr8n/translations_controller.rb +1 -1
  32. data/app/controllers/tr8n/translator_controller.rb +1 -1
  33. data/app/helpers/tr8n/base_helper.rb +0 -4
  34. data/app/models/tr8n/base_filter.rb +1 -1
  35. data/app/models/tr8n/daily_language_metric.rb +1 -1
  36. data/app/models/tr8n/date_rule.rb +1 -1
  37. data/app/models/tr8n/gender_list_rule.rb +1 -1
  38. data/app/models/tr8n/gender_rule.rb +1 -1
  39. data/app/models/tr8n/glossary.rb +1 -1
  40. data/app/models/tr8n/glossary_filter.rb +1 -1
  41. data/app/models/tr8n/integration/ru/russian_gender_list_rule.rb +1 -1
  42. data/app/models/tr8n/integration/ru/russian_numeric_rule.rb +1 -1
  43. data/app/models/tr8n/ip_location.rb +1 -1
  44. data/app/models/tr8n/ip_location_filter.rb +1 -1
  45. data/app/models/tr8n/language.rb +17 -8
  46. data/app/models/tr8n/language_case.rb +1 -1
  47. data/app/models/tr8n/language_case_filter.rb +1 -1
  48. data/app/models/tr8n/language_case_rule.rb +1 -1
  49. data/app/models/tr8n/language_case_rule_filter.rb +1 -1
  50. data/app/models/tr8n/language_case_value_map.rb +1 -1
  51. data/app/models/tr8n/language_case_value_map_filter.rb +1 -1
  52. data/app/models/tr8n/language_filter.rb +1 -1
  53. data/app/models/tr8n/language_forum_abuse_report.rb +1 -1
  54. data/app/models/tr8n/language_forum_abuse_report_filter.rb +1 -1
  55. data/app/models/tr8n/language_forum_message.rb +2 -2
  56. data/app/models/tr8n/language_forum_message_filter.rb +1 -1
  57. data/app/models/tr8n/language_forum_topic.rb +3 -3
  58. data/app/models/tr8n/language_forum_topic_filter.rb +1 -1
  59. data/app/models/tr8n/language_metric.rb +2 -2
  60. data/app/models/tr8n/language_metric_filter.rb +1 -1
  61. data/app/models/tr8n/language_rule.rb +37 -2
  62. data/app/models/tr8n/language_rule_filter.rb +1 -1
  63. data/app/models/tr8n/language_user.rb +3 -3
  64. data/app/models/tr8n/language_user_filter.rb +1 -1
  65. data/app/models/tr8n/list_rule.rb +1 -1
  66. data/app/models/tr8n/monthly_language_metric.rb +2 -2
  67. data/app/models/tr8n/numeric_rule.rb +1 -1
  68. data/app/models/tr8n/sync_log.rb +76 -0
  69. data/app/{controllers/tr8n/application_controller.rb → models/tr8n/sync_log_filter.rb} +4 -3
  70. data/app/models/tr8n/total_language_metric.rb +5 -4
  71. data/app/models/tr8n/translation.rb +61 -13
  72. data/app/models/tr8n/translation_domain.rb +1 -1
  73. data/app/models/tr8n/translation_domain_filter.rb +1 -1
  74. data/app/models/tr8n/translation_filter.rb +1 -1
  75. data/app/models/tr8n/translation_key.rb +33 -5
  76. data/app/models/tr8n/translation_key_comment.rb +1 -1
  77. data/app/models/tr8n/translation_key_comment_filter.rb +1 -1
  78. data/app/models/tr8n/translation_key_filter.rb +1 -1
  79. data/app/models/tr8n/translation_key_lock.rb +2 -2
  80. data/app/models/tr8n/translation_key_lock_filter.rb +1 -1
  81. data/app/models/tr8n/translation_key_source.rb +2 -2
  82. data/app/models/tr8n/translation_key_source_filter.rb +1 -1
  83. data/app/models/tr8n/translation_source.rb +2 -2
  84. data/app/models/tr8n/translation_source_filter.rb +1 -1
  85. data/app/models/tr8n/translation_vote.rb +3 -4
  86. data/app/models/tr8n/translation_vote_filter.rb +1 -1
  87. data/app/models/tr8n/translator.rb +19 -5
  88. data/app/models/tr8n/translator_filter.rb +1 -1
  89. data/app/models/tr8n/translator_following.rb +2 -2
  90. data/app/models/tr8n/translator_following_filter.rb +1 -1
  91. data/app/models/tr8n/translator_log.rb +1 -1
  92. data/app/models/tr8n/translator_log_filter.rb +1 -1
  93. data/app/models/tr8n/translator_metric.rb +15 -21
  94. data/app/models/tr8n/translator_metric_filter.rb +1 -1
  95. data/app/models/tr8n/translator_report.rb +2 -2
  96. data/app/models/tr8n/translator_report_filter.rb +1 -1
  97. data/app/models/tr8n/value_rule.rb +1 -1
  98. data/app/views/tr8n/admin/common/_paginator.html.erb +29 -17
  99. data/app/views/tr8n/admin/translation_key/_tabs.html.erb +3 -1
  100. data/app/views/tr8n/admin/translation_key/sync_logs.html.erb +5 -0
  101. data/app/views/tr8n/awards/index.html.erb +0 -2
  102. data/app/views/tr8n/common/_paginator.html.erb +24 -6
  103. data/app/views/tr8n/common/_tabs.html.erb +9 -5
  104. data/app/views/tr8n/forum/_messages.html.erb +1 -1
  105. data/app/views/tr8n/forum/index.html.erb +1 -1
  106. data/app/views/tr8n/glossary/index.html.erb +2 -2
  107. data/app/views/tr8n/{home → help}/credits.html.erb +0 -0
  108. data/app/views/tr8n/{home → help}/license.html.erb +0 -0
  109. data/app/views/tr8n/language_cases/index.html.erb +2 -2
  110. data/app/views/tr8n/phrases/_comments_module.html.erb +1 -1
  111. data/app/views/tr8n/phrases/index.html.erb +2 -6
  112. data/app/views/tr8n/translations/_list.html.erb +2 -6
  113. data/config/routes.rb +2 -2
  114. data/config/tr8n/config.yml +48 -13
  115. data/config/tr8n/rules/default_language_cases.yml +272 -0
  116. data/config/tr8n/tokens/data.yml +3 -1
  117. data/db/migrate/20111003194443_create_tr8n_sync_tables.rb +22 -0
  118. data/db/migrate/20111011013640_add_remote_id_to_tr8n_translators.rb +5 -0
  119. data/doc/classes.graffle +7049 -5152
  120. data/doc/classes.pdf +0 -0
  121. data/lib/generators/tr8n/templates/{create_tr8n_tables.rb → db/create_tr8n_tables.rb} +0 -0
  122. data/lib/generators/tr8n/templates/layouts/tr8n.html.erb +49 -0
  123. data/lib/generators/tr8n/templates/layouts/tr8n_admin.html.erb +61 -0
  124. data/lib/generators/tr8n/tr8n_generator.rb +11 -4
  125. data/lib/tasks/{tr8n_tasks.rake → tr8n.rake} +4 -0
  126. data/{app/controllers/tr8n/home_controller.rb → lib/tr8n/cache_adapters/memcached.rb} +12 -15
  127. data/lib/tr8n/config.rb +96 -53
  128. data/lib/tr8n/extensions/action_controller_extension.rb +1 -1
  129. data/lib/tr8n/extensions/action_view_extension.rb +4 -28
  130. data/lib/tr8n/tokens/data_token.rb +1 -1
  131. data/lib/tr8n/tokens/method_token.rb +1 -1
  132. data/lib/tr8n/tokens/transform_token.rb +1 -1
  133. data/lib/tr8n/version.rb +1 -1
  134. data/{test/dummy → local/tr8n_server}/Rakefile +1 -1
  135. data/{test/dummy → local/tr8n_server}/app/assets/javascripts/application.js +0 -0
  136. data/{test/dummy → local/tr8n_server}/app/assets/stylesheets/admin.css +0 -0
  137. data/{test/dummy → local/tr8n_server}/app/assets/stylesheets/application.css +0 -0
  138. data/local/tr8n_server/app/assets/stylesheets/components.css.scss +211 -0
  139. data/local/tr8n_server/app/assets/stylesheets/layout.css.scss +143 -0
  140. data/{test/dummy → local/tr8n_server}/app/controllers/admin/admins_controller.rb +0 -0
  141. data/{test/dummy → local/tr8n_server}/app/controllers/admin/base_controller.rb +0 -0
  142. data/{test/dummy → local/tr8n_server}/app/controllers/admin/users_controller.rb +0 -0
  143. data/{test/dummy → local/tr8n_server}/app/controllers/application_controller.rb +5 -0
  144. data/{test/dummy → local/tr8n_server}/app/controllers/demo_controller.rb +0 -0
  145. data/local/tr8n_server/app/controllers/home_controller.rb +4 -0
  146. data/{test/dummy → local/tr8n_server}/app/controllers/login_controller.rb +1 -1
  147. data/{test/dummy → local/tr8n_server}/app/helpers/application_helper.rb +0 -0
  148. data/{test/dummy → local/tr8n_server}/app/helpers/home_helper.rb +0 -0
  149. data/{test/dummy → local/tr8n_server}/app/mailers/.gitkeep +0 -0
  150. data/{test/dummy → local/tr8n_server}/app/models/.gitkeep +0 -0
  151. data/{test/dummy → local/tr8n_server}/app/models/admin.rb +0 -0
  152. data/{test/dummy → local/tr8n_server}/app/models/admin_filter.rb +0 -0
  153. data/{test/dummy → local/tr8n_server}/app/models/user.rb +0 -0
  154. data/{test/dummy → local/tr8n_server}/app/views/admin/admins/index.html.erb +0 -0
  155. data/{test/dummy → local/tr8n_server}/app/views/admin/users/index.html.erb +0 -0
  156. data/{test/dummy → local/tr8n_server}/app/views/demo/index.rhtml +0 -0
  157. data/{test/dummy → local/tr8n_server}/app/views/demo/tokens.rhtml +0 -0
  158. data/{app/views/tr8n → local/tr8n_server/app/views}/home/index.html.erb +1 -2
  159. data/local/tr8n_server/app/views/kaminari/_first_page.html.erb +11 -0
  160. data/local/tr8n_server/app/views/kaminari/_gap.html.erb +8 -0
  161. data/local/tr8n_server/app/views/kaminari/_last_page.html.erb +11 -0
  162. data/local/tr8n_server/app/views/kaminari/_next_page.html.erb +11 -0
  163. data/local/tr8n_server/app/views/kaminari/_page.html.erb +12 -0
  164. data/local/tr8n_server/app/views/kaminari/_paginator.html.erb +23 -0
  165. data/local/tr8n_server/app/views/kaminari/_prev_page.html.erb +11 -0
  166. data/{test/dummy → local/tr8n_server}/app/views/layouts/_flashes.html.erb +0 -0
  167. data/{test/dummy → local/tr8n_server}/app/views/layouts/_footer.html.erb +3 -3
  168. data/{test/dummy → local/tr8n_server}/app/views/layouts/_header.html.erb +1 -1
  169. data/{test/dummy → local/tr8n_server}/app/views/layouts/admin.html.erb +0 -0
  170. data/{test/dummy → local/tr8n_server}/app/views/layouts/application.html.erb +0 -0
  171. data/local/tr8n_server/app/views/layouts/tr8n.html.erb +51 -0
  172. data/local/tr8n_server/app/views/layouts/tr8n_admin.html.erb +61 -0
  173. data/{test/dummy → local/tr8n_server}/app/views/login/index.html.erb +0 -0
  174. data/{test/dummy → local/tr8n_server}/app/views/login/register.html.erb +8 -13
  175. data/{test/dummy → local/tr8n_server}/config.ru +1 -1
  176. data/{test/dummy → local/tr8n_server}/config/application.rb +2 -1
  177. data/{test/dummy → local/tr8n_server}/config/boot.rb +0 -0
  178. data/{test/dummy → local/tr8n_server}/config/database.yml +0 -0
  179. data/{test/dummy → local/tr8n_server}/config/environment.rb +1 -1
  180. data/{test/dummy → local/tr8n_server}/config/environments/development.rb +3 -1
  181. data/{test/dummy → local/tr8n_server}/config/environments/production.rb +1 -1
  182. data/{test/dummy → local/tr8n_server}/config/environments/test.rb +1 -1
  183. data/{test/dummy → local/tr8n_server}/config/initializers/backtrace_silencers.rb +0 -0
  184. data/{test/dummy → local/tr8n_server}/config/initializers/inflections.rb +0 -0
  185. data/{test/dummy → local/tr8n_server}/config/initializers/mime_types.rb +0 -0
  186. data/{test/dummy → local/tr8n_server}/config/initializers/secret_token.rb +1 -1
  187. data/{test/dummy → local/tr8n_server}/config/initializers/session_store.rb +2 -2
  188. data/{test/dummy → local/tr8n_server}/config/initializers/wrap_parameters.rb +0 -0
  189. data/{test/dummy → local/tr8n_server}/config/locales/en.yml +0 -0
  190. data/{test/dummy → local/tr8n_server}/config/routes.rb +2 -2
  191. data/{test/dummy → local/tr8n_server}/config/tr8n/config.yml +40 -11
  192. data/{test/dummy → local/tr8n_server}/config/tr8n/data/ip_locations.csv +0 -0
  193. data/{test/dummy → local/tr8n_server}/config/tr8n/rules/default_date_rules.yml +0 -0
  194. data/{test/dummy → local/tr8n_server}/config/tr8n/rules/default_gender_list_rules.yml +0 -0
  195. data/{test/dummy → local/tr8n_server}/config/tr8n/rules/default_gender_rules.yml +0 -0
  196. data/local/tr8n_server/config/tr8n/rules/default_language_cases.yml +272 -0
  197. data/{test/dummy → local/tr8n_server}/config/tr8n/rules/default_list_rules.yml +0 -0
  198. data/{test/dummy → local/tr8n_server}/config/tr8n/rules/default_numeric_rules.yml +0 -0
  199. data/{test/dummy → local/tr8n_server}/config/tr8n/rules/default_value_rules.yml +0 -0
  200. data/{test/dummy → local/tr8n_server}/config/tr8n/site/default_glossary.yml +0 -0
  201. data/{test/dummy → local/tr8n_server}/config/tr8n/site/default_languages.yml +0 -0
  202. data/{test/dummy → local/tr8n_server}/config/tr8n/site/features.yml +0 -0
  203. data/{test/dummy → local/tr8n_server}/config/tr8n/site/shortcuts.yml +0 -0
  204. data/{test/dummy → local/tr8n_server}/config/tr8n/site/sitemap.json +0 -0
  205. data/{test/dummy → local/tr8n_server}/config/tr8n/tokens/data.yml +2 -0
  206. data/{test/dummy → local/tr8n_server}/config/tr8n/tokens/decorations.yml +0 -0
  207. data/{test/dummy → local/tr8n_server}/config/will_filter/config.yml +0 -0
  208. data/{test/dummy → local/tr8n_server}/db/migrate/20101207014543_create_users.rb +0 -0
  209. data/{test/dummy → local/tr8n_server}/db/migrate/20110113223509_create_admins.rb +0 -0
  210. data/{test/dummy → local/tr8n_server}/db/migrate/20110930041143_create_will_filter_filters.rb +0 -0
  211. data/{test/dummy → local/tr8n_server}/db/migrate/20110930041150_create_tr8n_tables.rb +0 -0
  212. data/local/tr8n_server/db/migrate/20111003194443_create_tr8n_sync_tables.rb +22 -0
  213. data/local/tr8n_server/db/migrate/20111011013640_add_remote_id_to_tr8n_translators.rb +5 -0
  214. data/{test/dummy → local/tr8n_server}/db/schema.rb +15 -1
  215. data/{test/dummy → local/tr8n_server}/lib/assets/.gitkeep +0 -0
  216. data/{test/dummy → local/tr8n_server}/public/404.html +0 -0
  217. data/{test/dummy → local/tr8n_server}/public/422.html +0 -0
  218. data/{test/dummy → local/tr8n_server}/public/500.html +0 -0
  219. data/{test/dummy → local/tr8n_server}/public/favicon.ico +0 -0
  220. data/{test/dummy → local/tr8n_server}/script/rails +0 -0
  221. data/script/rails +1 -1
  222. data/spec/config/config_spec.rb +10 -0
  223. data/spec/fake_app.rb +50 -0
  224. data/spec/lib/data_token_spec.rb +26 -0
  225. data/spec/lib/transform_token_spec.rb +22 -0
  226. data/spec/models/translation_key_spec.rb +63 -0
  227. data/spec/spec_helper.rb +29 -0
  228. data/tr8n.gemspec +3 -1
  229. metadata +264 -245
  230. data/app/assets/images/tr8n/tr8n_logo.png +0 -0
  231. data/app/assets/images/tr8n/tr8n_logo2.gif +0 -0
  232. data/app/controllers/tr8n/login_controller.rb +0 -86
  233. data/app/views/layouts/_footer.html.erb +0 -15
  234. data/app/views/layouts/_header.html.erb +0 -12
  235. data/app/views/layouts/_html_head.html.erb +0 -5
  236. data/app/views/layouts/tr8n.html.erb +0 -21
  237. data/app/views/layouts/tr8n/application.html.erb +0 -14
  238. data/app/views/layouts/tr8n_admin.html.erb +0 -33
  239. data/app/views/tr8n/home/languages.html.erb +0 -7
  240. data/app/views/tr8n/login/index.html.erb +0 -33
  241. data/app/views/tr8n/login/register.html.erb +0 -57
  242. data/config/tr8n/rules/default_cases.yml +0 -141
  243. data/test/dummy/.sass-cache/32be4db30d38349a3a6e662df9bb5599dc8033b9/actions.css.scssc +0 -0
  244. data/test/dummy/.sass-cache/32be4db30d38349a3a6e662df9bb5599dc8033b9/buttons.css.scssc +0 -0
  245. data/test/dummy/.sass-cache/32be4db30d38349a3a6e662df9bb5599dc8033b9/calendar.css.scssc +0 -0
  246. data/test/dummy/.sass-cache/32be4db30d38349a3a6e662df9bb5599dc8033b9/exporter.css.scssc +0 -0
  247. data/test/dummy/.sass-cache/32be4db30d38349a3a6e662df9bb5599dc8033b9/filter.css.scssc +0 -0
  248. data/test/dummy/.sass-cache/32be4db30d38349a3a6e662df9bb5599dc8033b9/results.css.scssc +0 -0
  249. data/test/dummy/.sass-cache/3d45bab40fcae805deb2750a9342f5b355a9f2bf/components.css.scssc +0 -0
  250. data/test/dummy/.sass-cache/3d45bab40fcae805deb2750a9342f5b355a9f2bf/layout.css.scssc +0 -0
  251. data/test/dummy/.sass-cache/50f723c1dd802042d0091035528d53e6d5bc5b50/tr8n.css.scssc +0 -0
  252. data/test/dummy/.sass-cache/bce64928c8e2edcba72a647a44f05af1ff119c5d/actions.css.scssc +0 -0
  253. data/test/dummy/.sass-cache/bce64928c8e2edcba72a647a44f05af1ff119c5d/buttons.css.scssc +0 -0
  254. data/test/dummy/.sass-cache/bce64928c8e2edcba72a647a44f05af1ff119c5d/calendar.css.scssc +0 -0
  255. data/test/dummy/.sass-cache/bce64928c8e2edcba72a647a44f05af1ff119c5d/exporter.css.scssc +0 -0
  256. data/test/dummy/.sass-cache/bce64928c8e2edcba72a647a44f05af1ff119c5d/filter.css.scssc +0 -0
  257. data/test/dummy/.sass-cache/bce64928c8e2edcba72a647a44f05af1ff119c5d/results.css.scssc +0 -0
  258. data/test/dummy/app/assets/stylesheets/keyboard.css +0 -147
  259. data/test/dummy/config/tr8n/rules/default_cases.yml +0 -141
  260. data/test/dummy/log/.gitkeep +0 -0
  261. data/test/dummy/test/functional/home_controller_test.rb +0 -9
  262. data/test/dummy/test/unit/helpers/home_helper_test.rb +0 -4
  263. data/test/integration/navigation_test.rb +0 -10
  264. data/test/test_helper.rb +0 -10
  265. data/test/tr8n_test.rb +0 -7
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2010-2011 Michael Berkovich
2
+ # Copyright (c) 2010-2011 Michael Berkovich, tr8n.net
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining
5
5
  # a copy of this software and associated documentation files (the
@@ -0,0 +1,76 @@
1
+ #--
2
+ # Copyright (c) 2010-2011 Michael Berkovich, tr8n.net
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::SyncLog < ActiveRecord::Base
25
+
26
+ def self.sync
27
+ log = Tr8n::SyncLog.create(:started_at => Time.now)
28
+ key_count = 0
29
+ translation_count = 0
30
+ payload = []
31
+ Tr8n::TranslationKey.find_each(:batch_size => Tr8n::Config.synchronization_batch_size) do |key|
32
+ key_count += 1
33
+
34
+ payload << key.to_api_hash
35
+
36
+ puts "*"
37
+
38
+ if key_count % Tr8n::Config.synchronization_batch_size == 0
39
+ exchange(payload)
40
+ end
41
+ end
42
+ log.update_attributes(:finished_at => Time.now)
43
+ rescue Exception => ex
44
+ pp ex.message
45
+ end
46
+
47
+ def self.access_token
48
+ @access_token ||= begin
49
+ uri = URI.parse("#{Tr8n::Config.synchronization_server}/platform/oauth/request_token?client_id=#{Tr8n::Config.synchronization_key}&client_secret=#{Tr8n::Config.synchronization_secret}&grant_type=client_credentials")
50
+ response = Net::HTTP.get_response(uri)
51
+ data = JSON.parse(response.body)
52
+ raise Tr8n::Exception.new("Failed to get access token") unless data["access_toke"]
53
+ data["access_token"]
54
+ end
55
+ end
56
+
57
+ def self.exchange(payload)
58
+ uri = URI.parse("#{Tr8n::Config.synchronization_server}/api/sync")
59
+
60
+ req = Net::HTTP::Post.new(uri.path)
61
+ req.body = JSON.generate({:translation_keys => payload})
62
+ req["Content-Type"] = "application/json"
63
+ req["Authorization"] = "Bearer #{access_token}"
64
+
65
+ http = Net::HTTP.new(uri.host, uri.port)
66
+ response = http.start {|htt| htt.request(req)}
67
+ raise Tr8n::Exception.new("Synchronization failed") unless response.status == 200
68
+
69
+ data = JSON.parse(response.body)
70
+
71
+ data[:translation_keys].each do |tkey_hash|
72
+ Tr8n::TranslationKey.create_from_api_hash(tkey_hash, Tr8n::Config.system_translator)
73
+ end
74
+ end
75
+
76
+ end
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2010-2011 Michael Berkovich
2
+ # Copyright (c) 2010-2011 Michael Berkovich, tr8n.net
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining
5
5
  # a copy of this software and associated documentation files (the
@@ -22,6 +22,7 @@
22
22
  #++
23
23
 
24
24
  module Tr8n
25
- class ApplicationController < ActionController::Base
25
+ class SyncLogFilter < Tr8n::BaseFilter
26
+
26
27
  end
27
- end
28
+ end
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2010-2011 Michael Berkovich
2
+ # Copyright (c) 2010-2011 Michael Berkovich, tr8n.net
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining
5
5
  # a copy of this software and associated documentation files (the
@@ -24,11 +24,12 @@
24
24
  class Tr8n::TotalLanguageMetric < Tr8n::LanguageMetric
25
25
 
26
26
  def update_metrics!
27
- self.user_count = Tr8n::LanguageUser.count(:conditions => ["language_id = ?", language_id])
28
- self.translator_count = Tr8n::LanguageUser.count(:conditions => ["language_id = ? and translator_id is not null", language_id])
29
- self.translation_count = Tr8n::Translation.count(:conditions => ["language_id = ?", language_id])
27
+ self.user_count = Tr8n::LanguageUser.where("language_id = ?", language_id).count
28
+ self.translator_count = Tr8n::LanguageUser.where("language_id = ? and translator_id is not null", language_id).count
29
+ self.translation_count = Tr8n::Translation.where("language_id = ?", language_id).count
30
30
  self.key_count = Tr8n::TranslationKey.count
31
31
 
32
+ # TODO: switch to the Rails 3.1 way
32
33
  self.locked_key_count = Tr8n::TranslationKey.count("distinct tr8n_translation_keys.id",
33
34
  :conditions => ["tr8n_translation_key_locks.language_id = ? and tr8n_translation_key_locks.locked = ?", language_id, true],
34
35
  :joins => "join tr8n_translation_key_locks on tr8n_translation_keys.id = tr8n_translation_key_locks.translation_key_id")
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2010-2011 Michael Berkovich
2
+ # Copyright (c) 2010-2011 Michael Berkovich, tr8n.net
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining
5
5
  # a copy of this software and associated documentation files (the
@@ -37,14 +37,19 @@ class Tr8n::Translation < ActiveRecord::Base
37
37
  alias :key :translation_key
38
38
  alias :votes :translation_votes
39
39
 
40
+ # TODO: move this to config file
40
41
  VIOLATION_INDICATOR = -10
41
42
 
42
43
  def vote!(translator, score)
43
44
  score = score.to_i
44
45
  vote = Tr8n::TranslationVote.find_or_create(self, translator)
45
46
  vote.update_attributes(:vote => score.to_i)
47
+
46
48
  update_rank!
47
49
 
50
+ # update the translation key timestamp
51
+ key.touch
52
+
48
53
  self.translator.update_rank!(language) if self.translator
49
54
 
50
55
  # add the translator to the watch list
@@ -55,8 +60,7 @@ class Tr8n::Translation < ActiveRecord::Base
55
60
  end
56
61
 
57
62
  def update_rank!
58
- self.rank = Tr8n::TranslationVote.sum("vote", :conditions => ["translation_id = ?", self.id])
59
- save
63
+ update_attributes(:rank => Tr8n::TranslationVote.where(:translation_id => self.id).sum(:vote))
60
64
  end
61
65
 
62
66
  def reset_votes!(translator)
@@ -64,6 +68,7 @@ class Tr8n::Translation < ActiveRecord::Base
64
68
  vote!(translator, 1)
65
69
  end
66
70
 
71
+ # TODO: move this stuff to decorators
67
72
  def rank_style(rank)
68
73
  Tr8n::Config.default_rank_styles.each do |range, color|
69
74
  return color if range.include?(rank)
@@ -71,6 +76,7 @@ class Tr8n::Translation < ActiveRecord::Base
71
76
  "color:grey"
72
77
  end
73
78
 
79
+ # TODO: move this stuff to decorators
74
80
  def rank_label
75
81
  return "<span style='color:grey'>0</span>" if rank.blank?
76
82
 
@@ -94,6 +100,9 @@ class Tr8n::Translation < ActiveRecord::Base
94
100
  end
95
101
  end
96
102
 
103
+ # generates a hash of token => rule_id
104
+ # TODO: is this still being used?
105
+ # Warning: same token can have multiple rules in a single translation
97
106
  def rules_hash
98
107
  return nil if rules.nil? or rules.empty?
99
108
 
@@ -106,6 +115,44 @@ class Tr8n::Translation < ActiveRecord::Base
106
115
  end
107
116
  end
108
117
 
118
+ # generates the hash without rule ids, but with full definitions
119
+ def rules_api_hash
120
+ @rules_api_hash ||= (rules || []).collect{|rule_hash| rule_hash[:rule].to_api_hash.merge(:token => rule_hash[:token])}
121
+ end
122
+
123
+ # serilaize translation to API hash to be used for synchronization
124
+ def to_api_hash
125
+ {:locale => language.locale, :label => label, :rank => rank, :rules => rules_api_hash}
126
+ end
127
+
128
+ # create translation from API hash for a specific key
129
+ def self.create_from_api_hash(tkey, translator, hash, opts = {})
130
+ return if hash[:label].blank? # don't add empty translations
131
+ lang = Tr8n::Language.for(hash[:locale])
132
+ return unless lang # don't add translations for an unsupported language
133
+
134
+ tkey.translations.each do |trn|
135
+ # if an identical translation exists, don't add it
136
+ return if trn.to_api_hash == hash
137
+ end
138
+
139
+ # generate rules for the translation
140
+ rules = nil
141
+
142
+ if hash[:rules].any?
143
+ hash[:rules].each do |rule_hash|
144
+ return unless rule_hash[:token] and rule_hash[:type] and rule_hash[:definition]
145
+
146
+ rule = Tr8n::LanguageRule.for_definition(lang, translator, rule_hash[:type], rule_hash[:definition], opts)
147
+ return unless rule # if the rule has not been created, we should not even add the translation
148
+ rules << {:token => rule_hash[:token], :rule_id => rule.id}
149
+ end
150
+ end
151
+
152
+ tkey.add_translation(hash[:label], rules, lang, translator)
153
+ end
154
+
155
+ # deprecated - api_hash should be used instead
109
156
  def rules_definitions
110
157
  return nil if rules.nil? or rules.empty?
111
158
  @rules_definitions ||= begin
@@ -117,6 +164,7 @@ class Tr8n::Translation < ActiveRecord::Base
117
164
  end
118
165
  end
119
166
 
167
+ # TODO: move to decorators
120
168
  def context
121
169
  return nil if rules.nil? or rules.empty?
122
170
 
@@ -129,6 +177,7 @@ class Tr8n::Translation < ActiveRecord::Base
129
177
  end
130
178
  end
131
179
 
180
+ # checks if the translation is valid for the given tokens
132
181
  def matches_rules?(token_values)
133
182
  return true if rules.nil? # doesn't have any rules
134
183
  return false if rules.empty? # had some rules that have been removed
@@ -143,14 +192,13 @@ class Tr8n::Translation < ActiveRecord::Base
143
192
  true
144
193
  end
145
194
 
195
+ # used by the permutation generator
146
196
  def matches_rule_definitions?(new_rules_hash)
147
197
  rules_hash == new_rules_hash
148
198
  end
149
199
 
150
200
  def self.default_translation(translation_key, language, translator)
151
- trans = find(:first,
152
- :conditions => ["translation_key_id = ? and language_id = ? and translator_id = ? and rules is null",
153
- translation_key.id, language.id, translator.id], :order => "rank desc")
201
+ trans = where("translation_key_id = ? and language_id = ? and translator_id = ? and rules is null", translation_key.id, language.id, translator.id).order("rank desc").first
154
202
  trans ||= new(:translation_key => translation_key, :language => language, :translator => translator, :label => translation_key.sanitized_label)
155
203
  trans
156
204
  end
@@ -163,13 +211,9 @@ class Tr8n::Translation < ActiveRecord::Base
163
211
  # for now, treat all translations as uniq
164
212
  return true
165
213
 
166
- conditions = ["translation_key_id = ? and language_id = ? and label = ?", translation_key.id, language.id, label]
167
- if self.id
168
- conditions[0] << " and id <> ?"
169
- conditions << self.id
170
- end
171
-
172
- self.class.find(:all, :conditions => conditions).empty?
214
+ trns = self.class.where("translation_key_id = ? and language_id = ? and label = ?", translation_key.id, language.id, label)
215
+ trns = trns.where("id <> ?", self.id) if self.id
216
+ trns.count == 0
173
217
  end
174
218
 
175
219
  def clean?
@@ -248,6 +292,10 @@ class Tr8n::Translation < ActiveRecord::Base
248
292
 
249
293
  def self.for_params(params, language = Tr8n::Config.current_language)
250
294
  results = self.where("language_id = ?", language.id)
295
+
296
+ # ensure that only allowed translations are visible
297
+ results = results.where("translation_key_id in (select id from tr8n_translation_keys where level <= ?)", Tr8n::Config.current_translator.level)
298
+
251
299
  results = results.where("label like ?", "%#{params[:search]}%") unless params[:search].blank?
252
300
 
253
301
  if params[:with_status] == "accepted"
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2010-2011 Michael Berkovich
2
+ # Copyright (c) 2010-2011 Michael Berkovich, tr8n.net
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining
5
5
  # a copy of this software and associated documentation files (the
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2010-2011 Michael Berkovich
2
+ # Copyright (c) 2010-2011 Michael Berkovich, tr8n.net
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining
5
5
  # a copy of this software and associated documentation files (the
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2010-2011 Michael Berkovich
2
+ # Copyright (c) 2010-2011 Michael Berkovich, tr8n.net
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining
5
5
  # a copy of this software and associated documentation files (the
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2010-2011 Michael Berkovich
2
+ # Copyright (c) 2010-2011 Michael Berkovich, tr8n.net
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining
5
5
  # a copy of this software and associated documentation files (the
@@ -218,7 +218,6 @@ class Tr8n::TranslationKey < ActiveRecord::Base
218
218
 
219
219
  def add_translation(label, rules = nil, language = Tr8n::Config.current_language, translator = Tr8n::Config.current_translator)
220
220
  raise Tr8n::Exception.new("The sentence contains dirty words") unless language.clean_sentence?(label)
221
-
222
221
  translation = Tr8n::Translation.create(:translation_key => self, :language => language,
223
222
  :translator => translator, :label => label, :rules => rules)
224
223
  translation.vote!(translator, 1)
@@ -226,10 +225,11 @@ class Tr8n::TranslationKey < ActiveRecord::Base
226
225
  end
227
226
 
228
227
  # returns all translations for the key, language and minimal rank
229
- def translations_for(language, rank = nil)
230
- translations = Tr8n::Translation.where("translation_key_id = ? and language_id = ?", self.id, language.id)
228
+ def translations_for(language = nil, rank = nil)
229
+ translations = Tr8n::Translation.where("translation_key_id = ?", self.id)
230
+ translations = translations.where("language_id = ?", language.id) if language
231
231
  translations = translations.where("rank >= ?", rank) if rank
232
- translations.order("rank desc")
232
+ translations.order("rank desc").all
233
233
  end
234
234
 
235
235
  # used by the inline popup dialog, we don't want to show blocked translations
@@ -427,6 +427,7 @@ class Tr8n::TranslationKey < ActiveRecord::Base
427
427
  processed_label
428
428
  end
429
429
 
430
+ # TODO: move all this stuff out of the model to decorators
430
431
  def default_decoration(language = Tr8n::Config.current_language, options = {})
431
432
  return label if Tr8n::Config.current_user_is_guest?
432
433
  return label unless Tr8n::Config.current_user_is_translator?
@@ -507,6 +508,33 @@ class Tr8n::TranslationKey < ActiveRecord::Base
507
508
  Tr8n::Translation.create(:translation_key => self, :label => label, :language => lang, :translator => translator)
508
509
  end
509
510
 
511
+ def to_api_hash
512
+ {
513
+ :key => self.key,
514
+ :label => self.label,
515
+ :description => self.description,
516
+ :locale => (locale || Tr8n::Config.default_locale),
517
+ :translations => translations_for(nil, Tr8n::Config.translation_threshold).collect{|t| t.to_api_hash}
518
+ }
519
+ end
520
+
521
+ # create translation key from API hash
522
+ def self.create_from_api_hash(tkey_hash, translator, opts = {})
523
+ return if tkey_hash[:key].blank? or tkey_hash[:label].blank? or tkey_hash[:locale].blank?
524
+
525
+ tkey = Tr8n::TranslationKey.find_or_create(tkey_hash[:label], tkey_hash[:description])
526
+
527
+ # return unless tkey.key==tkey_hash[:key] # need to warn the user that the key methods don't match
528
+
529
+ opts[:force_create] = Tr8n::Config.synchronization_create_rules? if opts[:force_create].nil?
530
+
531
+ (tkey_hash[:translations] || []).each do |trn_hash|
532
+ Tr8n::Translation.create_from_api_hash(tkey, translator, trn_hash, opts)
533
+ end
534
+
535
+ tkey
536
+ end
537
+
510
538
  ###############################################################
511
539
  ## Feature Related Stuff
512
540
  ###############################################################
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2010-2011 Michael Berkovich
2
+ # Copyright (c) 2010-2011 Michael Berkovich, tr8n.net
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining
5
5
  # a copy of this software and associated documentation files (the
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2010-2011 Michael Berkovich
2
+ # Copyright (c) 2010-2011 Michael Berkovich, tr8n.net
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining
5
5
  # a copy of this software and associated documentation files (the
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2010-2011 Michael Berkovich
2
+ # Copyright (c) 2010-2011 Michael Berkovich, tr8n.net
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining
5
5
  # a copy of this software and associated documentation files (the
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2010-2011 Michael Berkovich
2
+ # Copyright (c) 2010-2011 Michael Berkovich, tr8n.net
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining
5
5
  # a copy of this software and associated documentation files (the
@@ -33,7 +33,7 @@ class Tr8n::TranslationKeyLock < ActiveRecord::Base
33
33
  alias :key :translation_key
34
34
 
35
35
  def self.find_or_create(translation_key, language)
36
- lock = find(:first, :conditions => ["translation_key_id = ? and language_id = ?", translation_key.id, language.id])
36
+ lock = where("translation_key_id = ? and language_id = ?", translation_key.id, language.id).first
37
37
  lock || create(:translation_key => translation_key, :language => language)
38
38
  end
39
39
 
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2010-2011 Michael Berkovich
2
+ # Copyright (c) 2010-2011 Michael Berkovich, tr8n.net
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining
5
5
  # a copy of this software and associated documentation files (the
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2010-2011 Michael Berkovich
2
+ # Copyright (c) 2010-2011 Michael Berkovich, tr8n.net
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining
5
5
  # a copy of this software and associated documentation files (the
@@ -36,7 +36,7 @@ class Tr8n::TranslationKeySource < ActiveRecord::Base
36
36
 
37
37
  def self.find_or_create(translation_key, translation_source)
38
38
  Tr8n::Cache.fetch("translation_key_source_#{translation_key.id}_#{translation_source.id}") do
39
- tks = find(:first, :conditions => ["translation_key_id = ? and translation_source_id = ?", translation_key.id, translation_source.id])
39
+ tks = where("translation_key_id = ? and translation_source_id = ?", translation_key.id, translation_source.id).first
40
40
  tks || create(:translation_key => translation_key, :translation_source => translation_source)
41
41
  end
42
42
  end
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2010-2011 Michael Berkovich
2
+ # Copyright (c) 2010-2011 Michael Berkovich, tr8n.net
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining
5
5
  # a copy of this software and associated documentation files (the