lit 1.0 → 1.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 (297) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +13 -5
  3. data/app/assets/javascripts/lit/backend/bootstrap.min.js +7 -0
  4. data/app/assets/javascripts/lit/backend/localizations.js.coffee +13 -6
  5. data/app/assets/stylesheets/lit/application.css +16 -13
  6. data/app/controllers/lit/api/v1/localizations_controller.rb +12 -15
  7. data/app/controllers/lit/cloud_translations_controller.rb +1 -1
  8. data/app/controllers/lit/concerns/request_info_store.rb +16 -10
  9. data/app/controllers/lit/concerns/request_keys_store.rb +17 -10
  10. data/app/controllers/lit/localization_keys_controller.rb +40 -34
  11. data/app/controllers/lit/localizations_controller.rb +1 -1
  12. data/app/controllers/lit/sources_controller.rb +1 -1
  13. data/app/helpers/lit/frontend_helper.rb +1 -1
  14. data/app/helpers/lit/localizations_helper.rb +9 -0
  15. data/app/models/lit/base.rb +33 -17
  16. data/app/models/lit/incomming_localization.rb +13 -27
  17. data/app/models/lit/localization.rb +6 -14
  18. data/app/services/remote_interactor_service.rb +3 -1
  19. data/app/services/synchronize_source_service.rb +4 -8
  20. data/app/views/layouts/lit/application.html.erb +0 -1
  21. data/app/views/lit/dashboard/index.html.erb +1 -1
  22. data/app/views/lit/incomming_localizations/index.html.erb +1 -1
  23. data/app/views/lit/localization_keys/_localizations_list.html.erb +19 -11
  24. data/app/views/lit/localization_keys/batch_touch.js.erb +1 -0
  25. data/app/views/lit/localization_keys/index.html.erb +2 -0
  26. data/app/views/lit/localization_keys/not_translated.html.erb +2 -0
  27. data/app/views/lit/localization_keys/visited_again.html.erb +3 -0
  28. data/app/views/lit/localizations/update.js.erb +1 -1
  29. data/config/routes.rb +1 -0
  30. data/lib/generators/lit/install/templates/initializer.rb +6 -3
  31. data/lib/lit.rb +19 -6
  32. data/lib/lit/adapters/hash_storage.rb +35 -1
  33. data/lib/lit/adapters/redis_storage.rb +42 -7
  34. data/lib/lit/cache.rb +66 -10
  35. data/lib/lit/cloud_translation/providers/google.rb +2 -0
  36. data/lib/lit/cloud_translation/providers/yandex.rb +2 -0
  37. data/lib/lit/engine.rb +12 -5
  38. data/lib/lit/export.rb +2 -18
  39. data/lib/lit/i18n_backend.rb +20 -7
  40. data/lib/lit/import.rb +18 -15
  41. data/lib/lit/loader.rb +1 -0
  42. data/lib/lit/middleware.rb +29 -0
  43. data/lib/lit/rails.rb +1 -0
  44. data/lib/lit/railtie.rb +6 -7
  45. data/lib/lit/services/localization_keys_to_hash_service.rb +23 -0
  46. data/lib/lit/version.rb +1 -1
  47. metadata +30 -263
  48. data/app/assets/images/lit/famfamfam_flags/ad.png +0 -0
  49. data/app/assets/images/lit/famfamfam_flags/ae.png +0 -0
  50. data/app/assets/images/lit/famfamfam_flags/af.png +0 -0
  51. data/app/assets/images/lit/famfamfam_flags/ag.png +0 -0
  52. data/app/assets/images/lit/famfamfam_flags/ai.png +0 -0
  53. data/app/assets/images/lit/famfamfam_flags/al.png +0 -0
  54. data/app/assets/images/lit/famfamfam_flags/am.png +0 -0
  55. data/app/assets/images/lit/famfamfam_flags/an.png +0 -0
  56. data/app/assets/images/lit/famfamfam_flags/ao.png +0 -0
  57. data/app/assets/images/lit/famfamfam_flags/ar.png +0 -0
  58. data/app/assets/images/lit/famfamfam_flags/as.png +0 -0
  59. data/app/assets/images/lit/famfamfam_flags/at.png +0 -0
  60. data/app/assets/images/lit/famfamfam_flags/au.png +0 -0
  61. data/app/assets/images/lit/famfamfam_flags/aw.png +0 -0
  62. data/app/assets/images/lit/famfamfam_flags/ax.png +0 -0
  63. data/app/assets/images/lit/famfamfam_flags/az.png +0 -0
  64. data/app/assets/images/lit/famfamfam_flags/ba.png +0 -0
  65. data/app/assets/images/lit/famfamfam_flags/bb.png +0 -0
  66. data/app/assets/images/lit/famfamfam_flags/bd.png +0 -0
  67. data/app/assets/images/lit/famfamfam_flags/be.png +0 -0
  68. data/app/assets/images/lit/famfamfam_flags/bf.png +0 -0
  69. data/app/assets/images/lit/famfamfam_flags/bg.png +0 -0
  70. data/app/assets/images/lit/famfamfam_flags/bh.png +0 -0
  71. data/app/assets/images/lit/famfamfam_flags/bi.png +0 -0
  72. data/app/assets/images/lit/famfamfam_flags/bj.png +0 -0
  73. data/app/assets/images/lit/famfamfam_flags/bm.png +0 -0
  74. data/app/assets/images/lit/famfamfam_flags/bn.png +0 -0
  75. data/app/assets/images/lit/famfamfam_flags/bo.png +0 -0
  76. data/app/assets/images/lit/famfamfam_flags/br.png +0 -0
  77. data/app/assets/images/lit/famfamfam_flags/bs.png +0 -0
  78. data/app/assets/images/lit/famfamfam_flags/bt.png +0 -0
  79. data/app/assets/images/lit/famfamfam_flags/bv.png +0 -0
  80. data/app/assets/images/lit/famfamfam_flags/bw.png +0 -0
  81. data/app/assets/images/lit/famfamfam_flags/by.png +0 -0
  82. data/app/assets/images/lit/famfamfam_flags/bz.png +0 -0
  83. data/app/assets/images/lit/famfamfam_flags/ca.png +0 -0
  84. data/app/assets/images/lit/famfamfam_flags/catalonia.png +0 -0
  85. data/app/assets/images/lit/famfamfam_flags/cc.png +0 -0
  86. data/app/assets/images/lit/famfamfam_flags/cd.png +0 -0
  87. data/app/assets/images/lit/famfamfam_flags/cf.png +0 -0
  88. data/app/assets/images/lit/famfamfam_flags/cg.png +0 -0
  89. data/app/assets/images/lit/famfamfam_flags/ch.png +0 -0
  90. data/app/assets/images/lit/famfamfam_flags/ci.png +0 -0
  91. data/app/assets/images/lit/famfamfam_flags/ck.png +0 -0
  92. data/app/assets/images/lit/famfamfam_flags/cl.png +0 -0
  93. data/app/assets/images/lit/famfamfam_flags/cm.png +0 -0
  94. data/app/assets/images/lit/famfamfam_flags/cn.png +0 -0
  95. data/app/assets/images/lit/famfamfam_flags/co.png +0 -0
  96. data/app/assets/images/lit/famfamfam_flags/cr.png +0 -0
  97. data/app/assets/images/lit/famfamfam_flags/cs.png +0 -0
  98. data/app/assets/images/lit/famfamfam_flags/cu.png +0 -0
  99. data/app/assets/images/lit/famfamfam_flags/cv.png +0 -0
  100. data/app/assets/images/lit/famfamfam_flags/cx.png +0 -0
  101. data/app/assets/images/lit/famfamfam_flags/cy.png +0 -0
  102. data/app/assets/images/lit/famfamfam_flags/cz.png +0 -0
  103. data/app/assets/images/lit/famfamfam_flags/da.png +0 -0
  104. data/app/assets/images/lit/famfamfam_flags/de.png +0 -0
  105. data/app/assets/images/lit/famfamfam_flags/dj.png +0 -0
  106. data/app/assets/images/lit/famfamfam_flags/dk.png +0 -0
  107. data/app/assets/images/lit/famfamfam_flags/dm.png +0 -0
  108. data/app/assets/images/lit/famfamfam_flags/do.png +0 -0
  109. data/app/assets/images/lit/famfamfam_flags/dz.png +0 -0
  110. data/app/assets/images/lit/famfamfam_flags/ec.png +0 -0
  111. data/app/assets/images/lit/famfamfam_flags/ee.png +0 -0
  112. data/app/assets/images/lit/famfamfam_flags/eg.png +0 -0
  113. data/app/assets/images/lit/famfamfam_flags/eh.png +0 -0
  114. data/app/assets/images/lit/famfamfam_flags/en.png +0 -0
  115. data/app/assets/images/lit/famfamfam_flags/england.png +0 -0
  116. data/app/assets/images/lit/famfamfam_flags/er.png +0 -0
  117. data/app/assets/images/lit/famfamfam_flags/es.png +0 -0
  118. data/app/assets/images/lit/famfamfam_flags/et.png +0 -0
  119. data/app/assets/images/lit/famfamfam_flags/europeanunion.png +0 -0
  120. data/app/assets/images/lit/famfamfam_flags/fam.png +0 -0
  121. data/app/assets/images/lit/famfamfam_flags/fi.png +0 -0
  122. data/app/assets/images/lit/famfamfam_flags/fj.png +0 -0
  123. data/app/assets/images/lit/famfamfam_flags/fk.png +0 -0
  124. data/app/assets/images/lit/famfamfam_flags/fm.png +0 -0
  125. data/app/assets/images/lit/famfamfam_flags/fo.png +0 -0
  126. data/app/assets/images/lit/famfamfam_flags/fr.png +0 -0
  127. data/app/assets/images/lit/famfamfam_flags/ga.png +0 -0
  128. data/app/assets/images/lit/famfamfam_flags/gb.png +0 -0
  129. data/app/assets/images/lit/famfamfam_flags/gd.png +0 -0
  130. data/app/assets/images/lit/famfamfam_flags/ge.png +0 -0
  131. data/app/assets/images/lit/famfamfam_flags/gf.png +0 -0
  132. data/app/assets/images/lit/famfamfam_flags/gh.png +0 -0
  133. data/app/assets/images/lit/famfamfam_flags/gi.png +0 -0
  134. data/app/assets/images/lit/famfamfam_flags/gl.png +0 -0
  135. data/app/assets/images/lit/famfamfam_flags/gm.png +0 -0
  136. data/app/assets/images/lit/famfamfam_flags/gn.png +0 -0
  137. data/app/assets/images/lit/famfamfam_flags/gp.png +0 -0
  138. data/app/assets/images/lit/famfamfam_flags/gq.png +0 -0
  139. data/app/assets/images/lit/famfamfam_flags/gr.png +0 -0
  140. data/app/assets/images/lit/famfamfam_flags/gs.png +0 -0
  141. data/app/assets/images/lit/famfamfam_flags/gt.png +0 -0
  142. data/app/assets/images/lit/famfamfam_flags/gu.png +0 -0
  143. data/app/assets/images/lit/famfamfam_flags/gw.png +0 -0
  144. data/app/assets/images/lit/famfamfam_flags/gy.png +0 -0
  145. data/app/assets/images/lit/famfamfam_flags/hk.png +0 -0
  146. data/app/assets/images/lit/famfamfam_flags/hm.png +0 -0
  147. data/app/assets/images/lit/famfamfam_flags/hn.png +0 -0
  148. data/app/assets/images/lit/famfamfam_flags/hr.png +0 -0
  149. data/app/assets/images/lit/famfamfam_flags/ht.png +0 -0
  150. data/app/assets/images/lit/famfamfam_flags/hu.png +0 -0
  151. data/app/assets/images/lit/famfamfam_flags/id.png +0 -0
  152. data/app/assets/images/lit/famfamfam_flags/ie.png +0 -0
  153. data/app/assets/images/lit/famfamfam_flags/il.png +0 -0
  154. data/app/assets/images/lit/famfamfam_flags/in.png +0 -0
  155. data/app/assets/images/lit/famfamfam_flags/io.png +0 -0
  156. data/app/assets/images/lit/famfamfam_flags/iq.png +0 -0
  157. data/app/assets/images/lit/famfamfam_flags/ir.png +0 -0
  158. data/app/assets/images/lit/famfamfam_flags/is.png +0 -0
  159. data/app/assets/images/lit/famfamfam_flags/it.png +0 -0
  160. data/app/assets/images/lit/famfamfam_flags/ja.png +0 -0
  161. data/app/assets/images/lit/famfamfam_flags/jm.png +0 -0
  162. data/app/assets/images/lit/famfamfam_flags/jo.png +0 -0
  163. data/app/assets/images/lit/famfamfam_flags/jp.png +0 -0
  164. data/app/assets/images/lit/famfamfam_flags/ke.png +0 -0
  165. data/app/assets/images/lit/famfamfam_flags/kg.png +0 -0
  166. data/app/assets/images/lit/famfamfam_flags/kh.png +0 -0
  167. data/app/assets/images/lit/famfamfam_flags/ki.png +0 -0
  168. data/app/assets/images/lit/famfamfam_flags/km.png +0 -0
  169. data/app/assets/images/lit/famfamfam_flags/kn.png +0 -0
  170. data/app/assets/images/lit/famfamfam_flags/kp.png +0 -0
  171. data/app/assets/images/lit/famfamfam_flags/kr.png +0 -0
  172. data/app/assets/images/lit/famfamfam_flags/kw.png +0 -0
  173. data/app/assets/images/lit/famfamfam_flags/ky.png +0 -0
  174. data/app/assets/images/lit/famfamfam_flags/kz.png +0 -0
  175. data/app/assets/images/lit/famfamfam_flags/la.png +0 -0
  176. data/app/assets/images/lit/famfamfam_flags/lb.png +0 -0
  177. data/app/assets/images/lit/famfamfam_flags/lc.png +0 -0
  178. data/app/assets/images/lit/famfamfam_flags/li.png +0 -0
  179. data/app/assets/images/lit/famfamfam_flags/lk.png +0 -0
  180. data/app/assets/images/lit/famfamfam_flags/lr.png +0 -0
  181. data/app/assets/images/lit/famfamfam_flags/ls.png +0 -0
  182. data/app/assets/images/lit/famfamfam_flags/lt.png +0 -0
  183. data/app/assets/images/lit/famfamfam_flags/lu.png +0 -0
  184. data/app/assets/images/lit/famfamfam_flags/lv.png +0 -0
  185. data/app/assets/images/lit/famfamfam_flags/ly.png +0 -0
  186. data/app/assets/images/lit/famfamfam_flags/ma.png +0 -0
  187. data/app/assets/images/lit/famfamfam_flags/mc.png +0 -0
  188. data/app/assets/images/lit/famfamfam_flags/md.png +0 -0
  189. data/app/assets/images/lit/famfamfam_flags/me.png +0 -0
  190. data/app/assets/images/lit/famfamfam_flags/mg.png +0 -0
  191. data/app/assets/images/lit/famfamfam_flags/mh.png +0 -0
  192. data/app/assets/images/lit/famfamfam_flags/mk.png +0 -0
  193. data/app/assets/images/lit/famfamfam_flags/ml.png +0 -0
  194. data/app/assets/images/lit/famfamfam_flags/mm.png +0 -0
  195. data/app/assets/images/lit/famfamfam_flags/mn.png +0 -0
  196. data/app/assets/images/lit/famfamfam_flags/mo.png +0 -0
  197. data/app/assets/images/lit/famfamfam_flags/mp.png +0 -0
  198. data/app/assets/images/lit/famfamfam_flags/mq.png +0 -0
  199. data/app/assets/images/lit/famfamfam_flags/mr.png +0 -0
  200. data/app/assets/images/lit/famfamfam_flags/ms.png +0 -0
  201. data/app/assets/images/lit/famfamfam_flags/mt.png +0 -0
  202. data/app/assets/images/lit/famfamfam_flags/mu.png +0 -0
  203. data/app/assets/images/lit/famfamfam_flags/mv.png +0 -0
  204. data/app/assets/images/lit/famfamfam_flags/mw.png +0 -0
  205. data/app/assets/images/lit/famfamfam_flags/mx.png +0 -0
  206. data/app/assets/images/lit/famfamfam_flags/my.png +0 -0
  207. data/app/assets/images/lit/famfamfam_flags/mz.png +0 -0
  208. data/app/assets/images/lit/famfamfam_flags/na.png +0 -0
  209. data/app/assets/images/lit/famfamfam_flags/nc.png +0 -0
  210. data/app/assets/images/lit/famfamfam_flags/ne.png +0 -0
  211. data/app/assets/images/lit/famfamfam_flags/nf.png +0 -0
  212. data/app/assets/images/lit/famfamfam_flags/ng.png +0 -0
  213. data/app/assets/images/lit/famfamfam_flags/ni.png +0 -0
  214. data/app/assets/images/lit/famfamfam_flags/nl.png +0 -0
  215. data/app/assets/images/lit/famfamfam_flags/no.png +0 -0
  216. data/app/assets/images/lit/famfamfam_flags/np.png +0 -0
  217. data/app/assets/images/lit/famfamfam_flags/nr.png +0 -0
  218. data/app/assets/images/lit/famfamfam_flags/nu.png +0 -0
  219. data/app/assets/images/lit/famfamfam_flags/nz.png +0 -0
  220. data/app/assets/images/lit/famfamfam_flags/om.png +0 -0
  221. data/app/assets/images/lit/famfamfam_flags/pa.png +0 -0
  222. data/app/assets/images/lit/famfamfam_flags/pe.png +0 -0
  223. data/app/assets/images/lit/famfamfam_flags/pf.png +0 -0
  224. data/app/assets/images/lit/famfamfam_flags/pg.png +0 -0
  225. data/app/assets/images/lit/famfamfam_flags/ph.png +0 -0
  226. data/app/assets/images/lit/famfamfam_flags/pk.png +0 -0
  227. data/app/assets/images/lit/famfamfam_flags/pl.png +0 -0
  228. data/app/assets/images/lit/famfamfam_flags/pm.png +0 -0
  229. data/app/assets/images/lit/famfamfam_flags/pn.png +0 -0
  230. data/app/assets/images/lit/famfamfam_flags/pr.png +0 -0
  231. data/app/assets/images/lit/famfamfam_flags/ps.png +0 -0
  232. data/app/assets/images/lit/famfamfam_flags/pt.png +0 -0
  233. data/app/assets/images/lit/famfamfam_flags/pw.png +0 -0
  234. data/app/assets/images/lit/famfamfam_flags/py.png +0 -0
  235. data/app/assets/images/lit/famfamfam_flags/qa.png +0 -0
  236. data/app/assets/images/lit/famfamfam_flags/re.png +0 -0
  237. data/app/assets/images/lit/famfamfam_flags/ro.png +0 -0
  238. data/app/assets/images/lit/famfamfam_flags/rs.png +0 -0
  239. data/app/assets/images/lit/famfamfam_flags/ru.png +0 -0
  240. data/app/assets/images/lit/famfamfam_flags/rw.png +0 -0
  241. data/app/assets/images/lit/famfamfam_flags/sa.png +0 -0
  242. data/app/assets/images/lit/famfamfam_flags/sb.png +0 -0
  243. data/app/assets/images/lit/famfamfam_flags/sc.png +0 -0
  244. data/app/assets/images/lit/famfamfam_flags/scotland.png +0 -0
  245. data/app/assets/images/lit/famfamfam_flags/sd.png +0 -0
  246. data/app/assets/images/lit/famfamfam_flags/se.png +0 -0
  247. data/app/assets/images/lit/famfamfam_flags/sg.png +0 -0
  248. data/app/assets/images/lit/famfamfam_flags/sh.png +0 -0
  249. data/app/assets/images/lit/famfamfam_flags/si.png +0 -0
  250. data/app/assets/images/lit/famfamfam_flags/sj.png +0 -0
  251. data/app/assets/images/lit/famfamfam_flags/sk.png +0 -0
  252. data/app/assets/images/lit/famfamfam_flags/sl.png +0 -0
  253. data/app/assets/images/lit/famfamfam_flags/sm.png +0 -0
  254. data/app/assets/images/lit/famfamfam_flags/sn.png +0 -0
  255. data/app/assets/images/lit/famfamfam_flags/so.png +0 -0
  256. data/app/assets/images/lit/famfamfam_flags/sr.png +0 -0
  257. data/app/assets/images/lit/famfamfam_flags/st.png +0 -0
  258. data/app/assets/images/lit/famfamfam_flags/sv.png +0 -0
  259. data/app/assets/images/lit/famfamfam_flags/sy.png +0 -0
  260. data/app/assets/images/lit/famfamfam_flags/sz.png +0 -0
  261. data/app/assets/images/lit/famfamfam_flags/tc.png +0 -0
  262. data/app/assets/images/lit/famfamfam_flags/td.png +0 -0
  263. data/app/assets/images/lit/famfamfam_flags/tf.png +0 -0
  264. data/app/assets/images/lit/famfamfam_flags/tg.png +0 -0
  265. data/app/assets/images/lit/famfamfam_flags/th.png +0 -0
  266. data/app/assets/images/lit/famfamfam_flags/tj.png +0 -0
  267. data/app/assets/images/lit/famfamfam_flags/tk.png +0 -0
  268. data/app/assets/images/lit/famfamfam_flags/tl.png +0 -0
  269. data/app/assets/images/lit/famfamfam_flags/tm.png +0 -0
  270. data/app/assets/images/lit/famfamfam_flags/tn.png +0 -0
  271. data/app/assets/images/lit/famfamfam_flags/to.png +0 -0
  272. data/app/assets/images/lit/famfamfam_flags/tr.png +0 -0
  273. data/app/assets/images/lit/famfamfam_flags/tt.png +0 -0
  274. data/app/assets/images/lit/famfamfam_flags/tv.png +0 -0
  275. data/app/assets/images/lit/famfamfam_flags/tw.png +0 -0
  276. data/app/assets/images/lit/famfamfam_flags/tz.png +0 -0
  277. data/app/assets/images/lit/famfamfam_flags/ua.png +0 -0
  278. data/app/assets/images/lit/famfamfam_flags/ug.png +0 -0
  279. data/app/assets/images/lit/famfamfam_flags/um.png +0 -0
  280. data/app/assets/images/lit/famfamfam_flags/us.png +0 -0
  281. data/app/assets/images/lit/famfamfam_flags/uy.png +0 -0
  282. data/app/assets/images/lit/famfamfam_flags/uz.png +0 -0
  283. data/app/assets/images/lit/famfamfam_flags/va.png +0 -0
  284. data/app/assets/images/lit/famfamfam_flags/vc.png +0 -0
  285. data/app/assets/images/lit/famfamfam_flags/ve.png +0 -0
  286. data/app/assets/images/lit/famfamfam_flags/vg.png +0 -0
  287. data/app/assets/images/lit/famfamfam_flags/vi.png +0 -0
  288. data/app/assets/images/lit/famfamfam_flags/vn.png +0 -0
  289. data/app/assets/images/lit/famfamfam_flags/vu.png +0 -0
  290. data/app/assets/images/lit/famfamfam_flags/wales.png +0 -0
  291. data/app/assets/images/lit/famfamfam_flags/wf.png +0 -0
  292. data/app/assets/images/lit/famfamfam_flags/ws.png +0 -0
  293. data/app/assets/images/lit/famfamfam_flags/ye.png +0 -0
  294. data/app/assets/images/lit/famfamfam_flags/yt.png +0 -0
  295. data/app/assets/images/lit/famfamfam_flags/za.png +0 -0
  296. data/app/assets/images/lit/famfamfam_flags/zm.png +0 -0
  297. data/app/assets/images/lit/famfamfam_flags/zw.png +0 -0
@@ -9,7 +9,7 @@ module Lit
9
9
  key = scope_key_by_partial(key)
10
10
  key = pluralized_key(key, count) if count
11
11
 
12
- content = super(key, options)
12
+ content = super(key, **options.symbolize_keys)
13
13
  if !options[:skip_lit] && lit_authorized?
14
14
  content = get_translateable_span(key, content)
15
15
  end
@@ -9,6 +9,15 @@ module Lit
9
9
  escape_javascript val.to_s
10
10
  end
11
11
 
12
+ def locale_flag locale
13
+ locale = locale.to_s.upcase[0,2]
14
+ locale = case locale
15
+ when 'EN' then 'GB'
16
+ else locale
17
+ end
18
+ locale.tr('A-Z', "\u{1F1E6}-\u{1F1FF}")
19
+ end
20
+
12
21
  def allow_wysiwyg_editor?(key)
13
22
  Lit.all_translations_are_html_safe || key.to_s =~ /(\b|_|\.)html$/
14
23
  end
@@ -1,38 +1,54 @@
1
1
  class Lit::Base < ActiveRecord::Base
2
2
  self.abstract_class = true
3
3
 
4
- before_save :mark_for_retry_on_create, on: :create
5
- before_save :mark_for_retry_on_update, on: :update
4
+ before_save :mark_for_retry
6
5
 
7
6
  attr_accessor :retried_created, :retried_updated
8
7
 
9
- def mark_for_retry_on_create
8
+ def mark_for_retry
10
9
  @will_retry_create = true
11
10
  end
12
11
 
13
- def mark_for_retry_on_update
14
- @will_retry_update = true
12
+ after_rollback :retry_lit_model_save
13
+
14
+ def rolledback_after_insert?
15
+ persisted? && @was_saved_with_insert && @was_rolled_back
15
16
  end
16
17
 
17
- after_rollback :retry_lit_model_save
18
+ def rolledback_after_update?
19
+ persisted? && @was_saved_with_update && @was_rolled_back
20
+ end
18
21
 
19
22
  private
20
23
 
21
- def retry_lit_model_save
22
- retry_on_create if instance_variable_defined?(:@will_retry_create) && @will_retry_create
23
- retry_on_update if instance_variable_defined?(:@will_retry_update) && @will_retry_update
24
+ def create_or_update(**kwargs, &block)
25
+ @was_saved_with_insert = true if new_record?
26
+ @was_saved_with_update = true if persisted?
27
+
28
+ super
24
29
  end
25
30
 
26
- def retry_on_create
27
- return if self.retried_created
28
- self.retried_created = true
29
- self.class.create! attributes.merge(retried_created: true)
31
+ def retry_lit_model_save
32
+ return if @was_rolled_back
33
+ @was_rolled_back = true
34
+ do_retry if instance_variable_defined?(:@will_retry_create) && @will_retry_create
30
35
  end
31
36
 
32
- def retry_on_update
33
- return if self.retried_updated
34
- self.retried_updated = true
35
- update! attributes.merge(retried_updated: true)
37
+ def do_retry
38
+ if !retried_created
39
+ self.retried_created = true
40
+ if rolledback_after_insert?
41
+ self.class.create! attributes.merge(retried_created: true)
42
+ end
43
+ elsif !retried_updated
44
+ # Why elsif and not just if? Because if a record object was first saved
45
+ # with INSERT and then with UPDATE (still being the same Ruby object),
46
+ # it makes no sense to retry both create and upadte. Let's only retry create.
47
+ self.retried_updated = true
48
+ if rolledback_after_update?
49
+ update_columns(attributes)
50
+ end
51
+ end
36
52
  end
37
53
 
38
54
  end
@@ -36,39 +36,27 @@ module Lit
36
36
  def duplicated?(val)
37
37
  set_localization
38
38
  return false if localization_has_changed?
39
- translated_value =
40
- localization.read_attribute_before_type_cast('translated_value')
41
- if localization.is_changed? && !translated_value.nil?
42
- translated_value == val
43
- else
44
- localization.read_attribute_before_type_cast('default_value') == val
45
- end
39
+
40
+ localization.translation == val
46
41
  end
47
42
 
48
43
  private
49
44
 
50
45
  def set_localization
51
46
  return if locale.blank? || localization_key.blank?
52
- self.localization = localization_key.localizations
53
- .find_by(locale_id: locale_id)
47
+ self.localization = localization_key.localizations.find_by(locale_id: locale_id)
54
48
  end
55
49
 
56
50
  def localization_has_changed?
57
- localization.blank? ||
58
- localization.is_deleted != localization_key_is_deleted
51
+ localization.blank? || localization.is_deleted != localization_key_is_deleted
59
52
  end
60
53
 
61
54
  def update_existing_localization_data
62
- localization.update_attributes!(
63
- translated_value: translated_value,
64
- is_changed: true
65
- )
55
+ localization.update!(translated_value: translated_value, is_changed: true)
66
56
  end
67
57
 
68
58
  def update_existing_localization_key_data
69
- localization_key.update_attributes!(
70
- is_deleted: localization_key_is_deleted
71
- )
59
+ localization_key.update!(is_deleted: localization_key_is_deleted)
72
60
  end
73
61
 
74
62
  def assign_new_localization_data
@@ -83,25 +71,23 @@ module Lit
83
71
 
84
72
  def assign_new_localization_key
85
73
  self.localization_key =
86
- Lit::LocalizationKey.where(
87
- localization_key: localization_key_str,
88
- is_deleted: localization_key_is_deleted
89
- ).first_or_create!
74
+ Lit::LocalizationKey.where(localization_key: localization_key_str, is_deleted: localization_key_is_deleted)
75
+ .first_or_create!
90
76
  end
91
77
 
92
78
  def assign_new_localization
93
79
  self.localization =
94
- Lit::Localization.where(localization_key_id: localization_key.id)
95
- .where(locale_id: locale.id)
96
- .first_or_initialize
80
+ Lit::Localization
81
+ .where(localization_key_id: localization_key.id)
82
+ .where(locale_id: locale.id)
83
+ .first_or_initialize
97
84
  localization.translated_value = translated_value
98
85
  localization.is_changed = true
99
86
  localization.save!
100
87
  end
101
88
 
102
89
  def update_cache
103
- Lit.init.cache.update_cache localization.full_key,
104
- localization.translation
90
+ Lit.init.cache.update_cache localization.full_key, localization.translation
105
91
  end
106
92
  end
107
93
  end
@@ -6,19 +6,14 @@ module Lit
6
6
  ## SCOPES
7
7
  scope :changed, -> { where is_changed: true }
8
8
  scope :not_changed, -> { where is_changed: false }
9
+
9
10
  # @HACK: dirty, find a way to round date to full second
10
- scope :after, lambda { |dt|
11
- where('updated_at >= ?', dt + 1.second)
12
- .where(is_changed: true)
13
- }
14
- scope :active, lambda {
15
- joins(:localization_key)
16
- .where(Lit::LocalizationKey.table_name => { is_deleted: false })
17
- }
11
+ scope :after, lambda { |dt| where('updated_at >= ?', dt + 1.second).where(is_changed: true) }
12
+ scope :active, lambda { joins(:localization_key).where(Lit::LocalizationKey.table_name => { is_deleted: false }) }
18
13
 
19
14
  ## ASSOCIATIONS
20
- belongs_to :locale
21
- belongs_to :localization_key, touch: true
15
+ belongs_to :locale, required: true
16
+ belongs_to :localization_key, touch: true, required: true
22
17
  has_many :localization_versions, dependent: :destroy
23
18
  has_many :versions, class_name: '::Lit::LocalizationVersion'
24
19
 
@@ -31,9 +26,7 @@ module Lit
31
26
  ## ACCESSORS
32
27
  attr_accessor :full_key_str
33
28
 
34
- unless defined?(::ActionController::StrongParameters)
35
- attr_accessible :translated_value, :locale_id
36
- end
29
+ attr_accessible :translated_value, :locale_id unless defined?(::ActionController::StrongParameters)
37
30
 
38
31
  ## BEFORE & AFTER
39
32
  with_options if: :translated_value_changed? do |o|
@@ -94,6 +87,5 @@ module Lit
94
87
  translated_value = translated_value_was || default_value
95
88
  localization_versions.new(translated_value: translated_value)
96
89
  end
97
-
98
90
  end
99
91
  end
@@ -11,6 +11,7 @@ class RemoteInteractorService
11
11
  rescue => e
12
12
  return unless defined?(Rails)
13
13
  ::Rails.logger.error { "Lit remote error: #{e}" }
14
+ nil # Return nil to be consistent with checks for .nil? otherwise returns True
14
15
  end
15
16
 
16
17
  private
@@ -26,7 +27,7 @@ class RemoteInteractorService
26
27
 
27
28
  def initialize_request(uri)
28
29
  req = Net::HTTP::Get.new(uri.request_uri)
29
- req.add_field('Authorization', %(Token token="#{@source.api_key}"))
30
+ req.add_field('Authorization', "Token token=\"#{@source.api_key}\"")
30
31
  req
31
32
  end
32
33
 
@@ -40,6 +41,7 @@ class RemoteInteractorService
40
41
  def perform_request(connection, request)
41
42
  res = connection.start { |http| http.request(request) }
42
43
  return res unless res.is_a?(Net::HTTPSuccess)
44
+
43
45
  JSON.parse(res.body)
44
46
  end
45
47
  end
@@ -12,8 +12,7 @@ class SynchronizeSourceService
12
12
 
13
13
  def synchronize_localizations
14
14
  after_date = @source.last_updated_at&.to_s(:db)
15
- result = interactor.send_request Lit::Source::LOCALIZATIONS_PATH,
16
- after: after_date
15
+ result = interactor.send_request Lit::Source::LOCALIZATIONS_PATH, after: after_date
17
16
  return unless result&.is_a?(Array)
18
17
  result.each { |loc| synchronize_localization loc }
19
18
  end
@@ -28,19 +27,16 @@ class SynchronizeSourceService
28
27
  inc_loc.localization_key = find_localization_key(inc_loc)
29
28
  inc_loc.translated_value = loc['value']
30
29
  return if inc_loc.duplicated?(loc['value'])
30
+
31
31
  inc_loc.save!
32
32
  end
33
33
 
34
34
  def find_incomming_localization(localization)
35
- Lit::IncommingLocalization.find_or_initialize_by(
36
- incomming_id: localization['id']
37
- )
35
+ Lit::IncommingLocalization.find_or_initialize_by(incomming_id: localization['id'])
38
36
  end
39
37
 
40
38
  def find_localization_key(inc_loc)
41
- Lit::LocalizationKey.find_by(
42
- localization_key: inc_loc.localization_key_str
43
- )
39
+ Lit::LocalizationKey.find_by(localization_key: inc_loc.localization_key_str)
44
40
  end
45
41
 
46
42
  def localization_key_deleted?(loc)
@@ -10,7 +10,6 @@
10
10
  <%= stylesheet_link_tag '//netdna.bootstrapcdn.com/bootswatch/3.0.3/yeti/bootstrap.min.css', media: 'all' %>
11
11
  <%= stylesheet_link_tag 'lit/application', media: 'all' %>
12
12
  <%= javascript_include_tag 'lit/application' %>
13
- <%= javascript_include_tag '//netdna.bootstrapcdn.com/bootstrap/3.0.3/js/bootstrap.min.js' %>
14
13
  <%= csrf_meta_tags %>
15
14
  </head>
16
15
  <body class="<%= params[:controller] %>">
@@ -1,5 +1,5 @@
1
1
  <strong>All localization keys</strong> <%= Lit::LocalizationKey.active.count(:id) %><br/>
2
2
  <% @locales.each do |l| %>
3
- <strong><%= image_tag "lit/famfamfam_flags/#{l.locale[0,2]}.png" %> <%= I18n.t("lit.locale_to_languages.#{l.locale}", :default=>l.locale) %>:</strong> <span title="<%= "#{l.changed_localizations_count}/#{l.all_localizations_count}" %>"><%= l.translated_percentage %>%</span><br/>
3
+ <strong><%= EmojiFlag.new(l.locale) %> <%= I18n.t("lit.locale_to_languages.#{l.locale}", :default=>l.locale) %>:</strong> <span title="<%= "#{l.changed_localizations_count}/#{l.all_localizations_count}" %>"><%= l.translated_percentage %>%</span><br/>
4
4
  <% end %>
5
5
 
@@ -25,7 +25,7 @@
25
25
  <% @incomming_localizations.each do |il| %>
26
26
  <tr data-id="<%= il.id %>">
27
27
  <td colspan="3">
28
- <%= image_tag "lit/famfamfam_flags/#{il.locale_str[0,2]}.png" %>
28
+ <%= image_tag EmojiFlag.new(il.locale_str) %>
29
29
  <strong><%= il.full_key %></strong>
30
30
  </td>
31
31
  </tr>
@@ -1,8 +1,12 @@
1
- <table class="table">
1
+ <div class="col-12 text-right">
2
+ <%= link_to "batch touch", lit.batch_touch_localization_keys_path(key: params[:key], key_prefix: params[:key_prefix]), method: :post, remote: true, class: 'btn btn-sm btn-primary', data: { confirm: 'This will "touch" all search results making them subject of synchronization. Proceed?'} %>
3
+ </div>
4
+ <table class="table mt-1">
2
5
  <%- @localization_keys.each do |lk| %>
3
6
  <tr class="localization_key_row" data-id="<%= lk.id %>">
4
7
  <td>
5
8
  <strong><%= lk.localization_key %></strong>
9
+ <i class="fa fa-clipboard js-copy_to_clipboard copy_to_clipboard_btn " data-key="<%= lk.localization_key %>"></i>
6
10
  <span class="badge"><%= Lit.init.cache.get_global_hits_counter(lk.localization_key) %></span>
7
11
  <div class="localization_keys_options">
8
12
  <% if Lit.store_request_info %>
@@ -30,26 +34,30 @@
30
34
  <div class="detail_wrapper">
31
35
  <table class="table table-bordered table-striped">
32
36
  <tr>
33
- <th class="col-md-8">Translation</th>
34
- <th class="col-md-2 text-center">Locale</th>
37
+ <th class="col-md-1"></th>
38
+ <th class="col-md-9">Translation</th>
39
+ <th class="col-md-1 text-center">Locale</th>
35
40
  <% unless lk.is_deleted? %>
36
- <th class="col-md-2 text-center">Completed</th>
41
+ <th class="col-md-1 text-center">Completed</th>
37
42
  <% end %>
38
43
  </tr>
39
44
  <%- available_locales.each do |locale| %>
40
45
  <%- localization = localization_for(locale, lk) %>
41
46
  <tr>
47
+ <td>
48
+ <% if localization %>
49
+ <%= draw_icon 'clock-o', title: "Last updated at #{localization.updated_at.to_s(:db)}" %>
50
+ <%= link_to lit.previous_versions_localization_key_localization_path(lk, localization, format: :js), class: "js-show_prev_versions #{'hidden' unless versions?(localization)}", remote: true do %>
51
+ <%= draw_icon 'random', title: I18n.t('lit.common.previous_versions', default: 'Previous versions') %>
52
+ <% end %>
53
+ <% end %>
54
+ </td>
42
55
  <td class="localization_row" data-id="<%= localization.id%>" data-edit="<%= edit_localization_key_localization_path(lk, localization, format: :js) %>" data-editing=0 data-content="">
43
56
  <%= render partial: 'localization_row', locals: {localization: Lit.init.cache["#{locale}.#{lk.localization_key}"]} %>
44
57
  </td>
45
58
  <td class="locale_row text-center">
46
- <%= image_tag "lit/famfamfam_flags/#{locale[0,2]}.png" %>
59
+ <%= EmojiFlag.new(locale) %>
47
60
  <%= locale %>
48
- <% if localization %>
49
- <%= link_to lit.previous_versions_localization_key_localization_path(lk, localization, format: :js), class: "show_prev_versions #{'hidden' unless versions?(localization)}", remote: true do %>
50
- <%= draw_icon 'random', title: I18n.t('lit.common.previous_versions', default: 'Previous versions') %>
51
- <% end %>
52
- <% end %>
53
61
  </td>
54
62
  <% unless lk.is_deleted? %>
55
63
  <td class="text-center">
@@ -65,7 +73,7 @@
65
73
  <% end %>
66
74
  <% if Lit.store_request_info %>
67
75
  <tr class="hidden request_info_row">
68
- <td colspan="2">
76
+ <td colspan="3">
69
77
  <strong>Translation key recently displayed on following pages:</strong>
70
78
  <ul>
71
79
  <% Lit.init.cache.get_request_info(lk.localization_key).split(' ').reverse.each do |l| %>
@@ -0,0 +1 @@
1
+ alert('All of search results have been marked as updated now, please retry synchronizing now');
@@ -4,6 +4,8 @@
4
4
 
5
5
  <% if defined?(Kaminari) %>
6
6
  <%= paginate @localization_keys, :theme=>"lit" %>
7
+ <% elsif defined?(WillPaginate) %>
8
+ <%= will_paginate @localization_keys %>
7
9
  <% end %>
8
10
 
9
11
  <%= render 'sidebar' %>
@@ -4,6 +4,8 @@
4
4
 
5
5
  <% if defined?(Kaminari) %>
6
6
  <%= paginate @localization_keys, :theme=>"lit" %>
7
+ <% elsif defined?(WillPaginate) %>
8
+ <%= will_paginate @localization_keys %>
7
9
  <% end %>
8
10
 
9
11
  <%= render 'sidebar' %>
@@ -4,6 +4,9 @@
4
4
 
5
5
  <% if defined?(Kaminari) %>
6
6
  <%= paginate @localization_keys, :theme=>"lit" %>
7
+ <% elsif defined?(WillPaginate) %>
8
+ <%= will_paginate @localization_keys %>
7
9
  <% end %>
8
10
 
11
+
9
12
  <%= render 'sidebar' %>
@@ -1,6 +1,6 @@
1
1
  var $row = $('td.localization_row[data-id="<%= @localization.id %>"]');
2
2
  $row.data('editing', 0);
3
3
  $row.html("<%= ejs render(:partial=>"/lit/localization_keys/localization_row", formats: ['html'], :locals=>{:localization=>@localization.translated_value }) %>");
4
- $row.siblings().find('.show_prev_versions').removeClass('hidden');
4
+ $row.siblings().find('.js-show_prev_versions').removeClass('hidden');
5
5
  $('a.change_completed_<%= @localization.id %> input[type=checkbox]').prop("checked", true);
6
6
 
data/config/routes.rb CHANGED
@@ -25,6 +25,7 @@ Lit::Engine.routes.draw do
25
25
  get :find_localization
26
26
  get :not_translated
27
27
  get :visited_again
28
+ post :batch_touch
28
29
  end
29
30
  resources :localizations, only: [:edit, :update, :show] do
30
31
  member do
@@ -29,11 +29,14 @@ Lit.all_translations_are_html_safe = false
29
29
  # <span title="translation missing string"></span>
30
30
  Lit.humanize_key = false
31
31
 
32
- # If set to `true` will always parse yaml files upon startup and update cache
33
- # values with ones with yaml - but only, if those keys haven't been changed via
34
- # web ui before
32
+ # If set to `false` will always parse yaml files upon startup and update cached
33
+ # values with ones with yaml (but only, if those keys haven't been changed via
34
+ # web ui before)
35
35
  Lit.ignore_yaml_on_startup = true
36
36
 
37
+ # Array of ignored keys or key prefixes
38
+ Lit.ignored_keys = ['i18n.transliterate'].freeze
39
+
37
40
  # API enabled? API allows third party browsing your translations, as well as
38
41
  # synchronizing them between environments
39
42
  Lit.api_enabled = false
data/lib/lit.rb CHANGED
@@ -17,6 +17,8 @@ module Lit
17
17
  mattr_accessor :all_translations_are_html_safe
18
18
  mattr_accessor :set_last_updated_at_upon_creation
19
19
  mattr_accessor :store_request_info
20
+ mattr_accessor :store_request_keys
21
+ mattr_accessor :hits_counter_enabled
20
22
 
21
23
  class << self
22
24
  attr_accessor :loader
@@ -30,13 +32,16 @@ module Lit
30
32
  Lit.humanize_key_ignored_keys = [] if Lit.humanize_key_ignored_keys.nil?
31
33
  Lit.humanize_key_ignored = %w[i18n date datetime number time support ]
32
34
  Lit.humanize_key_ignored |= Lit.humanize_key_ignored_keys
33
- Lit.humanize_key_ignored = %r{(#{Lit.humanize_key_ignored.join('|')}).*}
34
- if Lit.ignored_keys.is_a?(String)
35
- keys = Lit.ignored_keys.split(',').map(&:strip)
36
- Lit.ignored_keys = keys
37
- end
35
+ Lit.humanize_key_ignored = Regexp.new("(#{Lit.humanize_key_ignored.join('|')}).*")
38
36
  Lit.ignore_yaml_on_startup = true if Lit.ignore_yaml_on_startup.nil?
37
+
38
+ Lit.ignored_keys = Lit.ignored_keys.split(',').map(&:strip) if Lit.ignored_keys.is_a?(String)
39
39
  Lit.ignored_keys = [] unless Lit.ignored_keys.is_a?(Array)
40
+ Lit.ignored_keys = Lit.ignored_keys.map(&:freeze).freeze
41
+
42
+ Lit.hits_counter_enabled = false if Lit.hits_counter_enabled.nil?
43
+ Lit.store_request_info = false if Lit.store_request_info.nil?
44
+ Lit.store_request_keys = false if Lit.store_request_keys.nil?
40
45
  # if loading all translations on start, migrations have to be already
41
46
  # performed, fails on first deploy
42
47
  # self.loader.cache.load_all_translations
@@ -47,7 +52,15 @@ module Lit
47
52
 
48
53
  def self.check_if_table_exists
49
54
  Lit::Locale.table_exists?
50
- rescue
55
+ rescue ActiveRecord::ActiveRecordError => e
56
+ log_txt =
57
+ "An #{e.class} error has been raised during Lit initialization. " \
58
+ "Lit assumes that database tables do not exist.\n\n" \
59
+ "Error: #{e.message}\n\n" \
60
+ "Backtrace:\n" \
61
+ "#{e.backtrace.join("\n")}"
62
+ Logger.new(STDOUT).error(log_txt) if ::Rails.env.test? # ensure this is logged to stdout in test
63
+ ::Rails.logger.error(log_txt)
51
64
  false
52
65
  end
53
66