dm_core 4.2.1.5

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 (522) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +22 -0
  3. data/README.md +25 -0
  4. data/Rakefile +34 -0
  5. data/app/assets/images/dm_core/draft_menu_bg.png +0 -0
  6. data/app/assets/images/dm_core/expand.png +0 -0
  7. data/app/assets/images/dm_core/flags/ad.gif +0 -0
  8. data/app/assets/images/dm_core/flags/ae.gif +0 -0
  9. data/app/assets/images/dm_core/flags/af.gif +0 -0
  10. data/app/assets/images/dm_core/flags/ag.gif +0 -0
  11. data/app/assets/images/dm_core/flags/ai.gif +0 -0
  12. data/app/assets/images/dm_core/flags/al.gif +0 -0
  13. data/app/assets/images/dm_core/flags/am.gif +0 -0
  14. data/app/assets/images/dm_core/flags/an.gif +0 -0
  15. data/app/assets/images/dm_core/flags/ao.gif +0 -0
  16. data/app/assets/images/dm_core/flags/ar.gif +0 -0
  17. data/app/assets/images/dm_core/flags/as.gif +0 -0
  18. data/app/assets/images/dm_core/flags/at.gif +0 -0
  19. data/app/assets/images/dm_core/flags/au.gif +0 -0
  20. data/app/assets/images/dm_core/flags/aw.gif +0 -0
  21. data/app/assets/images/dm_core/flags/ax.gif +0 -0
  22. data/app/assets/images/dm_core/flags/az.gif +0 -0
  23. data/app/assets/images/dm_core/flags/ba.gif +0 -0
  24. data/app/assets/images/dm_core/flags/bb.gif +0 -0
  25. data/app/assets/images/dm_core/flags/bd.gif +0 -0
  26. data/app/assets/images/dm_core/flags/be.gif +0 -0
  27. data/app/assets/images/dm_core/flags/bf.gif +0 -0
  28. data/app/assets/images/dm_core/flags/bg.gif +0 -0
  29. data/app/assets/images/dm_core/flags/bh.gif +0 -0
  30. data/app/assets/images/dm_core/flags/bi.gif +0 -0
  31. data/app/assets/images/dm_core/flags/bj.gif +0 -0
  32. data/app/assets/images/dm_core/flags/bm.gif +0 -0
  33. data/app/assets/images/dm_core/flags/bn.gif +0 -0
  34. data/app/assets/images/dm_core/flags/bo.gif +0 -0
  35. data/app/assets/images/dm_core/flags/br.gif +0 -0
  36. data/app/assets/images/dm_core/flags/bs.gif +0 -0
  37. data/app/assets/images/dm_core/flags/bt.gif +0 -0
  38. data/app/assets/images/dm_core/flags/bv.gif +0 -0
  39. data/app/assets/images/dm_core/flags/bw.gif +0 -0
  40. data/app/assets/images/dm_core/flags/by.gif +0 -0
  41. data/app/assets/images/dm_core/flags/bz.gif +0 -0
  42. data/app/assets/images/dm_core/flags/ca.gif +0 -0
  43. data/app/assets/images/dm_core/flags/cc.gif +0 -0
  44. data/app/assets/images/dm_core/flags/cd.gif +0 -0
  45. data/app/assets/images/dm_core/flags/cf.gif +0 -0
  46. data/app/assets/images/dm_core/flags/cg.gif +0 -0
  47. data/app/assets/images/dm_core/flags/ch.gif +0 -0
  48. data/app/assets/images/dm_core/flags/ci.gif +0 -0
  49. data/app/assets/images/dm_core/flags/ck.gif +0 -0
  50. data/app/assets/images/dm_core/flags/cl.gif +0 -0
  51. data/app/assets/images/dm_core/flags/cm.gif +0 -0
  52. data/app/assets/images/dm_core/flags/cn.gif +0 -0
  53. data/app/assets/images/dm_core/flags/co.gif +0 -0
  54. data/app/assets/images/dm_core/flags/cr.gif +0 -0
  55. data/app/assets/images/dm_core/flags/cs.gif +0 -0
  56. data/app/assets/images/dm_core/flags/cu.gif +0 -0
  57. data/app/assets/images/dm_core/flags/cv.gif +0 -0
  58. data/app/assets/images/dm_core/flags/cx.gif +0 -0
  59. data/app/assets/images/dm_core/flags/cy.gif +0 -0
  60. data/app/assets/images/dm_core/flags/cz.gif +0 -0
  61. data/app/assets/images/dm_core/flags/de.gif +0 -0
  62. data/app/assets/images/dm_core/flags/dj.gif +0 -0
  63. data/app/assets/images/dm_core/flags/dk.gif +0 -0
  64. data/app/assets/images/dm_core/flags/dm.gif +0 -0
  65. data/app/assets/images/dm_core/flags/do.gif +0 -0
  66. data/app/assets/images/dm_core/flags/dz.gif +0 -0
  67. data/app/assets/images/dm_core/flags/ec.gif +0 -0
  68. data/app/assets/images/dm_core/flags/ee.gif +0 -0
  69. data/app/assets/images/dm_core/flags/eg.gif +0 -0
  70. data/app/assets/images/dm_core/flags/eh.gif +0 -0
  71. data/app/assets/images/dm_core/flags/en.gif +0 -0
  72. data/app/assets/images/dm_core/flags/england.gif +0 -0
  73. data/app/assets/images/dm_core/flags/er.gif +0 -0
  74. data/app/assets/images/dm_core/flags/es.gif +0 -0
  75. data/app/assets/images/dm_core/flags/et.gif +0 -0
  76. data/app/assets/images/dm_core/flags/fam.gif +0 -0
  77. data/app/assets/images/dm_core/flags/fi.gif +0 -0
  78. data/app/assets/images/dm_core/flags/fj.gif +0 -0
  79. data/app/assets/images/dm_core/flags/fk.gif +0 -0
  80. data/app/assets/images/dm_core/flags/fm.gif +0 -0
  81. data/app/assets/images/dm_core/flags/fo.gif +0 -0
  82. data/app/assets/images/dm_core/flags/fr.gif +0 -0
  83. data/app/assets/images/dm_core/flags/ga.gif +0 -0
  84. data/app/assets/images/dm_core/flags/gb.gif +0 -0
  85. data/app/assets/images/dm_core/flags/gd.gif +0 -0
  86. data/app/assets/images/dm_core/flags/ge.gif +0 -0
  87. data/app/assets/images/dm_core/flags/gh.gif +0 -0
  88. data/app/assets/images/dm_core/flags/gi.gif +0 -0
  89. data/app/assets/images/dm_core/flags/gl.gif +0 -0
  90. data/app/assets/images/dm_core/flags/gm.gif +0 -0
  91. data/app/assets/images/dm_core/flags/gn.gif +0 -0
  92. data/app/assets/images/dm_core/flags/gp.gif +0 -0
  93. data/app/assets/images/dm_core/flags/gq.gif +0 -0
  94. data/app/assets/images/dm_core/flags/gr.gif +0 -0
  95. data/app/assets/images/dm_core/flags/gs.gif +0 -0
  96. data/app/assets/images/dm_core/flags/gt.gif +0 -0
  97. data/app/assets/images/dm_core/flags/gu.gif +0 -0
  98. data/app/assets/images/dm_core/flags/gw.gif +0 -0
  99. data/app/assets/images/dm_core/flags/gy.gif +0 -0
  100. data/app/assets/images/dm_core/flags/hk.gif +0 -0
  101. data/app/assets/images/dm_core/flags/hn.gif +0 -0
  102. data/app/assets/images/dm_core/flags/hr.gif +0 -0
  103. data/app/assets/images/dm_core/flags/ht.gif +0 -0
  104. data/app/assets/images/dm_core/flags/hu.gif +0 -0
  105. data/app/assets/images/dm_core/flags/id.gif +0 -0
  106. data/app/assets/images/dm_core/flags/ie.gif +0 -0
  107. data/app/assets/images/dm_core/flags/il.gif +0 -0
  108. data/app/assets/images/dm_core/flags/in.gif +0 -0
  109. data/app/assets/images/dm_core/flags/io.gif +0 -0
  110. data/app/assets/images/dm_core/flags/iq.gif +0 -0
  111. data/app/assets/images/dm_core/flags/ir.gif +0 -0
  112. data/app/assets/images/dm_core/flags/is.gif +0 -0
  113. data/app/assets/images/dm_core/flags/it.gif +0 -0
  114. data/app/assets/images/dm_core/flags/ja.gif +0 -0
  115. data/app/assets/images/dm_core/flags/jm.gif +0 -0
  116. data/app/assets/images/dm_core/flags/jo.gif +0 -0
  117. data/app/assets/images/dm_core/flags/ke.gif +0 -0
  118. data/app/assets/images/dm_core/flags/kg.gif +0 -0
  119. data/app/assets/images/dm_core/flags/kh.gif +0 -0
  120. data/app/assets/images/dm_core/flags/ki.gif +0 -0
  121. data/app/assets/images/dm_core/flags/km.gif +0 -0
  122. data/app/assets/images/dm_core/flags/kn.gif +0 -0
  123. data/app/assets/images/dm_core/flags/kp.gif +0 -0
  124. data/app/assets/images/dm_core/flags/kr.gif +0 -0
  125. data/app/assets/images/dm_core/flags/kw.gif +0 -0
  126. data/app/assets/images/dm_core/flags/ky.gif +0 -0
  127. data/app/assets/images/dm_core/flags/kz.gif +0 -0
  128. data/app/assets/images/dm_core/flags/la.gif +0 -0
  129. data/app/assets/images/dm_core/flags/lb.gif +0 -0
  130. data/app/assets/images/dm_core/flags/lc.gif +0 -0
  131. data/app/assets/images/dm_core/flags/li.gif +0 -0
  132. data/app/assets/images/dm_core/flags/lk.gif +0 -0
  133. data/app/assets/images/dm_core/flags/lr.gif +0 -0
  134. data/app/assets/images/dm_core/flags/ls.gif +0 -0
  135. data/app/assets/images/dm_core/flags/lt.gif +0 -0
  136. data/app/assets/images/dm_core/flags/lu.gif +0 -0
  137. data/app/assets/images/dm_core/flags/lv.gif +0 -0
  138. data/app/assets/images/dm_core/flags/ly.gif +0 -0
  139. data/app/assets/images/dm_core/flags/ma.gif +0 -0
  140. data/app/assets/images/dm_core/flags/mc.gif +0 -0
  141. data/app/assets/images/dm_core/flags/md.gif +0 -0
  142. data/app/assets/images/dm_core/flags/mg.gif +0 -0
  143. data/app/assets/images/dm_core/flags/mh.gif +0 -0
  144. data/app/assets/images/dm_core/flags/mk.gif +0 -0
  145. data/app/assets/images/dm_core/flags/ml.gif +0 -0
  146. data/app/assets/images/dm_core/flags/mm.gif +0 -0
  147. data/app/assets/images/dm_core/flags/mn.gif +0 -0
  148. data/app/assets/images/dm_core/flags/mo.gif +0 -0
  149. data/app/assets/images/dm_core/flags/mp.gif +0 -0
  150. data/app/assets/images/dm_core/flags/mq.gif +0 -0
  151. data/app/assets/images/dm_core/flags/mr.gif +0 -0
  152. data/app/assets/images/dm_core/flags/ms.gif +0 -0
  153. data/app/assets/images/dm_core/flags/mt.gif +0 -0
  154. data/app/assets/images/dm_core/flags/mu.gif +0 -0
  155. data/app/assets/images/dm_core/flags/mv.gif +0 -0
  156. data/app/assets/images/dm_core/flags/mw.gif +0 -0
  157. data/app/assets/images/dm_core/flags/mx.gif +0 -0
  158. data/app/assets/images/dm_core/flags/my.gif +0 -0
  159. data/app/assets/images/dm_core/flags/mz.gif +0 -0
  160. data/app/assets/images/dm_core/flags/na.gif +0 -0
  161. data/app/assets/images/dm_core/flags/nc.gif +0 -0
  162. data/app/assets/images/dm_core/flags/ne.gif +0 -0
  163. data/app/assets/images/dm_core/flags/nf.gif +0 -0
  164. data/app/assets/images/dm_core/flags/ng.gif +0 -0
  165. data/app/assets/images/dm_core/flags/ni.gif +0 -0
  166. data/app/assets/images/dm_core/flags/nl.gif +0 -0
  167. data/app/assets/images/dm_core/flags/no.gif +0 -0
  168. data/app/assets/images/dm_core/flags/np.gif +0 -0
  169. data/app/assets/images/dm_core/flags/nr.gif +0 -0
  170. data/app/assets/images/dm_core/flags/nu.gif +0 -0
  171. data/app/assets/images/dm_core/flags/nz.gif +0 -0
  172. data/app/assets/images/dm_core/flags/om.gif +0 -0
  173. data/app/assets/images/dm_core/flags/pa.gif +0 -0
  174. data/app/assets/images/dm_core/flags/pe.gif +0 -0
  175. data/app/assets/images/dm_core/flags/pf.gif +0 -0
  176. data/app/assets/images/dm_core/flags/pg.gif +0 -0
  177. data/app/assets/images/dm_core/flags/ph.gif +0 -0
  178. data/app/assets/images/dm_core/flags/pk.gif +0 -0
  179. data/app/assets/images/dm_core/flags/pl.gif +0 -0
  180. data/app/assets/images/dm_core/flags/pm.gif +0 -0
  181. data/app/assets/images/dm_core/flags/pn.gif +0 -0
  182. data/app/assets/images/dm_core/flags/pr.gif +0 -0
  183. data/app/assets/images/dm_core/flags/ps.gif +0 -0
  184. data/app/assets/images/dm_core/flags/pt.gif +0 -0
  185. data/app/assets/images/dm_core/flags/pw.gif +0 -0
  186. data/app/assets/images/dm_core/flags/py.gif +0 -0
  187. data/app/assets/images/dm_core/flags/qa.gif +0 -0
  188. data/app/assets/images/dm_core/flags/ro.gif +0 -0
  189. data/app/assets/images/dm_core/flags/ru.gif +0 -0
  190. data/app/assets/images/dm_core/flags/rw.gif +0 -0
  191. data/app/assets/images/dm_core/flags/sa.gif +0 -0
  192. data/app/assets/images/dm_core/flags/sb.gif +0 -0
  193. data/app/assets/images/dm_core/flags/sc.gif +0 -0
  194. data/app/assets/images/dm_core/flags/scotland.gif +0 -0
  195. data/app/assets/images/dm_core/flags/sd.gif +0 -0
  196. data/app/assets/images/dm_core/flags/se.gif +0 -0
  197. data/app/assets/images/dm_core/flags/sg.gif +0 -0
  198. data/app/assets/images/dm_core/flags/sh.gif +0 -0
  199. data/app/assets/images/dm_core/flags/si.gif +0 -0
  200. data/app/assets/images/dm_core/flags/sk.gif +0 -0
  201. data/app/assets/images/dm_core/flags/sl.gif +0 -0
  202. data/app/assets/images/dm_core/flags/sm.gif +0 -0
  203. data/app/assets/images/dm_core/flags/sn.gif +0 -0
  204. data/app/assets/images/dm_core/flags/so.gif +0 -0
  205. data/app/assets/images/dm_core/flags/sr.gif +0 -0
  206. data/app/assets/images/dm_core/flags/st.gif +0 -0
  207. data/app/assets/images/dm_core/flags/sv.gif +0 -0
  208. data/app/assets/images/dm_core/flags/sy.gif +0 -0
  209. data/app/assets/images/dm_core/flags/sz.gif +0 -0
  210. data/app/assets/images/dm_core/flags/tc.gif +0 -0
  211. data/app/assets/images/dm_core/flags/td.gif +0 -0
  212. data/app/assets/images/dm_core/flags/tf.gif +0 -0
  213. data/app/assets/images/dm_core/flags/tg.gif +0 -0
  214. data/app/assets/images/dm_core/flags/th.gif +0 -0
  215. data/app/assets/images/dm_core/flags/tj.gif +0 -0
  216. data/app/assets/images/dm_core/flags/tk.gif +0 -0
  217. data/app/assets/images/dm_core/flags/tl.gif +0 -0
  218. data/app/assets/images/dm_core/flags/tm.gif +0 -0
  219. data/app/assets/images/dm_core/flags/tn.gif +0 -0
  220. data/app/assets/images/dm_core/flags/to.gif +0 -0
  221. data/app/assets/images/dm_core/flags/tr.gif +0 -0
  222. data/app/assets/images/dm_core/flags/tt.gif +0 -0
  223. data/app/assets/images/dm_core/flags/tv.gif +0 -0
  224. data/app/assets/images/dm_core/flags/tw.gif +0 -0
  225. data/app/assets/images/dm_core/flags/tz.gif +0 -0
  226. data/app/assets/images/dm_core/flags/ua.gif +0 -0
  227. data/app/assets/images/dm_core/flags/ug.gif +0 -0
  228. data/app/assets/images/dm_core/flags/um.gif +0 -0
  229. data/app/assets/images/dm_core/flags/us.gif +0 -0
  230. data/app/assets/images/dm_core/flags/uy.gif +0 -0
  231. data/app/assets/images/dm_core/flags/uz.gif +0 -0
  232. data/app/assets/images/dm_core/flags/va.gif +0 -0
  233. data/app/assets/images/dm_core/flags/vc.gif +0 -0
  234. data/app/assets/images/dm_core/flags/ve.gif +0 -0
  235. data/app/assets/images/dm_core/flags/vg.gif +0 -0
  236. data/app/assets/images/dm_core/flags/vi.gif +0 -0
  237. data/app/assets/images/dm_core/flags/vn.gif +0 -0
  238. data/app/assets/images/dm_core/flags/vu.gif +0 -0
  239. data/app/assets/images/dm_core/flags/wales.gif +0 -0
  240. data/app/assets/images/dm_core/flags/wf.gif +0 -0
  241. data/app/assets/images/dm_core/flags/ws.gif +0 -0
  242. data/app/assets/images/dm_core/flags/ye.gif +0 -0
  243. data/app/assets/images/dm_core/flags/yt.gif +0 -0
  244. data/app/assets/images/dm_core/flags/za.gif +0 -0
  245. data/app/assets/images/dm_core/flags/zm.gif +0 -0
  246. data/app/assets/images/dm_core/flags/zw.gif +0 -0
  247. data/app/assets/images/dm_core/user.gif +0 -0
  248. data/app/assets/javascripts/dm_core/admin.js +223 -0
  249. data/app/assets/javascripts/dm_core/admin_extra.js.coffee +118 -0
  250. data/app/assets/javascripts/dm_core/application.js +14 -0
  251. data/app/assets/javascripts/dm_core/common_js.js.coffee +61 -0
  252. data/app/assets/javascripts/dm_core/underscore-1.4.4-min.js +1 -0
  253. data/app/assets/javascripts/dm_core/underscore-1.4.4.js +1227 -0
  254. data/app/assets/stylesheets/dm_core/admin.css +250 -0
  255. data/app/assets/stylesheets/dm_core/application.css +31 -0
  256. data/app/assets/stylesheets/dm_core/font-awesome.css +1479 -0
  257. data/app/assets/stylesheets/dm_core/font/FontAwesome.otf +0 -0
  258. data/app/assets/stylesheets/dm_core/font/fontawesome-webfont.eot +0 -0
  259. data/app/assets/stylesheets/dm_core/font/fontawesome-webfont.svg +399 -0
  260. data/app/assets/stylesheets/dm_core/font/fontawesome-webfont.ttf +0 -0
  261. data/app/assets/stylesheets/dm_core/font/fontawesome-webfont.woff +0 -0
  262. data/app/controllers/dm_core/admin/accounts_controller.rb +125 -0
  263. data/app/controllers/dm_core/admin/admin_controller.rb +133 -0
  264. data/app/controllers/dm_core/admin/comments_controller.rb +70 -0
  265. data/app/controllers/dm_core/admin/dashboard_controller.rb +38 -0
  266. data/app/controllers/dm_core/admin/system_controller.rb +44 -0
  267. data/app/controllers/dm_core/admin/users_controller.rb +106 -0
  268. data/app/controllers/dm_core/application_controller.rb +253 -0
  269. data/app/controllers/dm_core/concerns/profile_controller.rb +41 -0
  270. data/app/controllers/dm_core/profile_controller.rb +8 -0
  271. data/app/datatables/user_datatable.rb +75 -0
  272. data/app/helpers/devise_helper.rb +25 -0
  273. data/app/helpers/dm_core/account_helper.rb +70 -0
  274. data/app/helpers/dm_core/admin/application_helper.rb +23 -0
  275. data/app/helpers/dm_core/application_helper.rb +58 -0
  276. data/app/helpers/dm_core/liquid_helper.rb +79 -0
  277. data/app/helpers/dm_core/params_helper.rb +19 -0
  278. data/app/helpers/dm_core/render_helper.rb +104 -0
  279. data/app/helpers/dm_core/url_helper.rb +189 -0
  280. data/app/helpers/dm_utilities/currency_helper.rb +24 -0
  281. data/app/helpers/dm_utilities/date_helper.rb +72 -0
  282. data/app/inputs/code_editor_input.rb +51 -0
  283. data/app/inputs/text_full_width_input.rb +9 -0
  284. data/app/inputs/toggle_checked_input.rb +9 -0
  285. data/app/inputs/toggle_input.rb +9 -0
  286. data/app/mailers/dm_core/site_mailer.rb +18 -0
  287. data/app/models/account.rb +241 -0
  288. data/app/models/activity.rb +10 -0
  289. data/app/models/address.rb +24 -0
  290. data/app/models/category.rb +18 -0
  291. data/app/models/comment.rb +24 -0
  292. data/app/models/custom_field.rb +99 -0
  293. data/app/models/custom_field_def.rb +61 -0
  294. data/app/models/dm_core/concerns/ability.rb +17 -0
  295. data/app/models/dm_core/concerns/defines_custom_fields.rb +17 -0
  296. data/app/models/dm_core/concerns/friendly_id.rb +57 -0
  297. data/app/models/dm_core/concerns/has_custom_fields.rb +28 -0
  298. data/app/models/dm_core/concerns/public_private.rb +151 -0
  299. data/app/models/dm_core/concerns/user.rb +144 -0
  300. data/app/models/dm_core/concerns/user_profile.rb +113 -0
  301. data/app/models/dm_core/concerns/user_site_profile.rb +65 -0
  302. data/app/models/dm_core/country.rb +8 -0
  303. data/app/models/dm_core/language.rb +59 -0
  304. data/app/models/dm_core/permitted_params.rb +52 -0
  305. data/app/models/follow.rb +13 -0
  306. data/app/models/liquid_validator.rb +26 -0
  307. data/app/models/payment_history.rb +57 -0
  308. data/app/models/presence_default_locale_validator.rb +12 -0
  309. data/app/models/role.rb +12 -0
  310. data/app/models/system_email.rb +15 -0
  311. data/app/models/ultracart/notification.rb +107 -0
  312. data/app/models/ultracart/payment_history.rb +55 -0
  313. data/app/models/user.rb +22 -0
  314. data/app/models/user_profile.rb +9 -0
  315. data/app/models/user_site_profile.rb +11 -0
  316. data/app/presenters/base_presenter.rb +30 -0
  317. data/app/presenters/comment_presenter.rb +20 -0
  318. data/app/presenters/user_presenter.rb +48 -0
  319. data/app/uploaders/avatar_uploader.rb +75 -0
  320. data/app/views/devise/mailer/confirmation_instructions.html.erb +7 -0
  321. data/app/views/devise/mailer/confirmation_instructions.text.erb +7 -0
  322. data/app/views/devise/mailer/reset_password_instructions.html.erb +9 -0
  323. data/app/views/devise/mailer/reset_password_instructions.text.erb +9 -0
  324. data/app/views/devise/mailer/unlock_instructions.html.erb +7 -0
  325. data/app/views/devise/mailer/unlock_instructions.text.erb +7 -0
  326. data/app/views/dm_core/admin/accounts/_settings_menu.html.erb +24 -0
  327. data/app/views/dm_core/admin/accounts/analytics.html.erb +38 -0
  328. data/app/views/dm_core/admin/accounts/email.html.erb +26 -0
  329. data/app/views/dm_core/admin/accounts/general.html.erb +22 -0
  330. data/app/views/dm_core/admin/accounts/media.html.erb +37 -0
  331. data/app/views/dm_core/admin/accounts/metadata.html.erb +22 -0
  332. data/app/views/dm_core/admin/comments/_comment.html.erb +14 -0
  333. data/app/views/dm_core/admin/comments/_comment_edit_form.html.erb +3 -0
  334. data/app/views/dm_core/admin/comments/_comment_form.html.erb +15 -0
  335. data/app/views/dm_core/admin/comments/_comment_list.html.erb +5 -0
  336. data/app/views/dm_core/admin/comments/_comment_section.html.erb +7 -0
  337. data/app/views/dm_core/admin/comments/create.js.erb +4 -0
  338. data/app/views/dm_core/admin/comments/destroy.js.erb +1 -0
  339. data/app/views/dm_core/admin/comments/edit.js.erb +2 -0
  340. data/app/views/dm_core/admin/comments/update.js.erb +2 -0
  341. data/app/views/dm_core/admin/custom_fields/_check_box_collection.html.erb +4 -0
  342. data/app/views/dm_core/admin/custom_fields/_custom_field_def_fields.html.erb +34 -0
  343. data/app/views/dm_core/admin/custom_fields/_divider.html.erb +1 -0
  344. data/app/views/dm_core/admin/custom_fields/_number_field.html.erb +4 -0
  345. data/app/views/dm_core/admin/custom_fields/_radio_buttons.html.erb +4 -0
  346. data/app/views/dm_core/admin/custom_fields/_select.html.erb +4 -0
  347. data/app/views/dm_core/admin/custom_fields/_text_area.html.erb +4 -0
  348. data/app/views/dm_core/admin/custom_fields/_text_field.html.erb +4 -0
  349. data/app/views/dm_core/admin/dashboard/_index_sidebar.html.erb +22 -0
  350. data/app/views/dm_core/admin/dashboard/_widget_recent_new_users.html.erb +23 -0
  351. data/app/views/dm_core/admin/dashboard/_widget_recent_user_activity.html.erb +21 -0
  352. data/app/views/dm_core/admin/dashboard/index.html.erb +7 -0
  353. data/app/views/dm_core/admin/dashboard/update_site_assets.html.erb +5 -0
  354. data/app/views/dm_core/admin/shared/_header_stats_new_users.html.erb +2 -0
  355. data/app/views/dm_core/admin/shared/_header_stats_user_activity.html.erb +2 -0
  356. data/app/views/dm_core/admin/system/show.html.erb +23 -0
  357. data/app/views/dm_core/admin/users/_form.html.erb +44 -0
  358. data/app/views/dm_core/admin/users/edit.html.erb +201 -0
  359. data/app/views/dm_core/admin/users/index.html.erb +30 -0
  360. data/app/views/dm_core/profile/_profile_sidebar.html.erb +6 -0
  361. data/app/views/dm_core/profile/account.html.erb +38 -0
  362. data/app/views/dm_core/profile/details.html.erb +38 -0
  363. data/app/views/layouts/dm_core/application.html.erb +14 -0
  364. data/app/views/layouts/dm_core/maintenance.html.erb +31 -0
  365. data/app/views/layouts/email_templates/default_email_layout.html.erb +289 -0
  366. data/config/initializers/_dm_core.rb +7 -0
  367. data/config/initializers/carrierwave.rb +33 -0
  368. data/config/initializers/devise.rb +252 -0
  369. data/config/initializers/friendly_id.rb +88 -0
  370. data/config/initializers/globalize_easy_accessors.rb +67 -0
  371. data/config/initializers/globalize_papertrail_fix.rb +20 -0
  372. data/config/initializers/globalize_reflections.rb +22 -0
  373. data/config/initializers/rolify.rb +8 -0
  374. data/config/initializers/simple_form.rb +161 -0
  375. data/config/initializers/simple_form_amsterdam.rb +31 -0
  376. data/config/initializers/simple_form_bootstrap.rb +87 -0
  377. data/config/initializers/simple_form_bootstrap3.rb +175 -0
  378. data/config/initializers/will_paginate.rb +87 -0
  379. data/config/locales/custom.cs.yml +82 -0
  380. data/config/locales/custom.de.yml +82 -0
  381. data/config/locales/custom.en.yml +84 -0
  382. data/config/locales/custom.fi.yml +84 -0
  383. data/config/locales/custom.ja.yml +84 -0
  384. data/config/locales/devise.cs.yml +70 -0
  385. data/config/locales/devise.de.yml +60 -0
  386. data/config/locales/devise.en.yml +59 -0
  387. data/config/locales/devise.fi.yml +57 -0
  388. data/config/locales/devise.ja.yml +102 -0
  389. data/config/locales/rails.cs.yml +211 -0
  390. data/config/locales/rails.de-AT.yml +203 -0
  391. data/config/locales/rails.de.yml +203 -0
  392. data/config/locales/rails.en-GB.yml +205 -0
  393. data/config/locales/rails.en-IN.yml +205 -0
  394. data/config/locales/rails.en.yml +205 -0
  395. data/config/locales/rails.fi.yml +199 -0
  396. data/config/locales/rails.fr-CH.yml +207 -0
  397. data/config/locales/rails.fr.yml +215 -0
  398. data/config/locales/rails.ja.yml +197 -0
  399. data/config/locales/simple_form.cs.yml +26 -0
  400. data/config/locales/simple_form.de.yml +26 -0
  401. data/config/locales/simple_form.en.yml +26 -0
  402. data/config/locales/simple_form.fi.yml +26 -0
  403. data/config/locales/simple_form.ja.yml +26 -0
  404. data/config/routes.rb +33 -0
  405. data/db/globalize_seed_data.sql +76 -0
  406. data/db/migrate/20121023202117_add_globalize_countries.rb +49 -0
  407. data/db/migrate/20121028125329_devise_create_users.rb +45 -0
  408. data/db/migrate/20121028125831_add_user_fields.rb +13 -0
  409. data/db/migrate/20121028153317_rolify_create_roles.rb +19 -0
  410. data/db/migrate/20121105205634_add_last_access.rb +9 -0
  411. data/db/migrate/20121110213512_create_versions.rb +18 -0
  412. data/db/migrate/20121110213513_add_object_changes_column_to_versions.rb +11 -0
  413. data/db/migrate/20130206121535_create_dm_core_accounts.rb +12 -0
  414. data/db/migrate/20130206223323_add_account_to_users.rb +8 -0
  415. data/db/migrate/20130207170247_create_preferences.rb +12 -0
  416. data/db/migrate/20130321144726_create_comments.rb +21 -0
  417. data/db/migrate/20130402203739_add_activity.rb +20 -0
  418. data/db/migrate/20130415095617_add_type_to_comments.rb +8 -0
  419. data/db/migrate/20130429191051_add_category.rb +27 -0
  420. data/db/migrate/20130513112751_create_email_table.rb +25 -0
  421. data/db/migrate/20130516143539_add_user_profile.rb +45 -0
  422. data/db/migrate/20130518155712_add_profile_email.rb +13 -0
  423. data/db/migrate/20130620145610_create_payment_history.rb +36 -0
  424. data/db/migrate/20130625091108_change_anchor_field.rb +9 -0
  425. data/db/migrate/20130628112848_create_user_site_profile.rb +26 -0
  426. data/db/migrate/20130708150236_add_avatar.rb +11 -0
  427. data/db/migrate/20130914132041_add_notify_to_payment_history.rb +7 -0
  428. data/db/migrate/20140105133446_acts_as_votable_migration.rb +27 -0
  429. data/db/migrate/20140107112418_add_user_site_profile_uuid.rb +18 -0
  430. data/db/migrate/20140129110547_add_invoice_id.rb +6 -0
  431. data/db/migrate/20140201092656_acts_as_follower_migration.rb +17 -0
  432. data/db/migrate/20140203131320_rename_invoice_id.rb +11 -0
  433. data/db/migrate/20140210195143_add_core_addresses.rb +17 -0
  434. data/db/migrate/20140411190454_papertrail_increase_column.rb +8 -0
  435. data/db/migrate/20140501160009_acts_as_taggable_on_migration.acts_as_taggable_on_engine.rb +31 -0
  436. data/db/migrate/20140501160010_add_missing_unique_indices.acts_as_taggable_on_engine.rb +22 -0
  437. data/db/migrate/20140501160011_add_taggings_counter_cache_to_tags.acts_as_taggable_on_engine.rb +15 -0
  438. data/db/migrate/20140529164730_create_custom_fields.rb +39 -0
  439. data/db/migrate/20140709145503_add_missing_taggable_index.acts_as_taggable_on_engine.rb +10 -0
  440. data/db/migrate/20141216094639_add_favored_locale.rb +18 -0
  441. data/db/migrate/20160128094739_update_papertrail_v4.rb +73 -0
  442. data/db/migrate/20160630095745_create_delayed_jobs.rb +22 -0
  443. data/db/migrate/20160821150111_index_foreign_keys_in_core_accounts.rb +5 -0
  444. data/db/migrate/20160821150113_index_foreign_keys_in_core_addresses.rb +5 -0
  445. data/db/migrate/20160821150114_index_foreign_keys_in_core_categories.rb +5 -0
  446. data/db/migrate/20160821150115_index_foreign_keys_in_core_comments.rb +5 -0
  447. data/db/migrate/20160821150116_index_foreign_keys_in_core_custom_fields.rb +5 -0
  448. data/db/migrate/20160821150117_index_foreign_keys_in_core_payment_histories.rb +7 -0
  449. data/db/migrate/20160821150118_index_foreign_keys_in_core_system_email_translations.rb +5 -0
  450. data/db/migrate/20160821150119_index_foreign_keys_in_core_system_emails.rb +6 -0
  451. data/db/migrate/20160821150128_index_foreign_keys_in_preferences.rb +5 -0
  452. data/db/migrate/20160821150129_index_foreign_keys_in_roles.rb +5 -0
  453. data/db/migrate/20160821150130_index_foreign_keys_in_taggings.rb +5 -0
  454. data/db/migrate/20160821150131_index_foreign_keys_in_user_profiles.rb +7 -0
  455. data/db/migrate/20160821150132_index_foreign_keys_in_user_site_profiles.rb +6 -0
  456. data/db/migrate/20160821150133_index_foreign_keys_in_users_roles.rb +5 -0
  457. data/db/migrate/20160821150134_index_foreign_keys_in_version_associations.rb +5 -0
  458. data/db/migrate/20160821150135_index_foreign_keys_in_versions.rb +5 -0
  459. data/db/seeds.rb +433 -0
  460. data/db/seeds/globalize_countries.rb +239 -0
  461. data/db/seeds/globalize_languages.rb +186 -0
  462. data/lib/dm_core.rb +38 -0
  463. data/lib/dm_core/csv_exporter.rb +210 -0
  464. data/lib/dm_core/csv_importer.rb +16 -0
  465. data/lib/dm_core/engine.rb +51 -0
  466. data/lib/dm_core/liquid_extensions.rb +125 -0
  467. data/lib/dm_core/nls.rb +31 -0
  468. data/lib/dm_core/scio_excel.rb +501 -0
  469. data/lib/dm_core/state_select.rb +135 -0
  470. data/lib/dm_core/version.rb +3 -0
  471. data/lib/tasks/dm_core_tasks.rake +60 -0
  472. data/spec/dummy/README.rdoc +28 -0
  473. data/spec/dummy/Rakefile +6 -0
  474. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  475. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  476. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  477. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  478. data/spec/dummy/app/models/ability.rb +10 -0
  479. data/spec/dummy/app/models/user.rb +6 -0
  480. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  481. data/spec/dummy/bin/bundle +3 -0
  482. data/spec/dummy/bin/rails +4 -0
  483. data/spec/dummy/bin/rake +4 -0
  484. data/spec/dummy/config.ru +4 -0
  485. data/spec/dummy/config/application.rb +27 -0
  486. data/spec/dummy/config/boot.rb +5 -0
  487. data/spec/dummy/config/database.yml +25 -0
  488. data/spec/dummy/config/environment.rb +5 -0
  489. data/spec/dummy/config/environments/development.rb +37 -0
  490. data/spec/dummy/config/environments/production.rb +82 -0
  491. data/spec/dummy/config/environments/test.rb +39 -0
  492. data/spec/dummy/config/initializers/assets.rb +8 -0
  493. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  494. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
  495. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  496. data/spec/dummy/config/initializers/inflections.rb +16 -0
  497. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  498. data/spec/dummy/config/initializers/session_store.rb +3 -0
  499. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  500. data/spec/dummy/config/locales/en.yml +23 -0
  501. data/spec/dummy/config/routes.rb +11 -0
  502. data/spec/dummy/config/secrets.yml +22 -0
  503. data/spec/dummy/db/development.sqlite3 +0 -0
  504. data/spec/dummy/db/schema.rb +399 -0
  505. data/spec/dummy/db/test.sqlite3 +0 -0
  506. data/spec/dummy/log/test.log +374 -0
  507. data/spec/dummy/public/404.html +67 -0
  508. data/spec/dummy/public/422.html +67 -0
  509. data/spec/dummy/public/500.html +66 -0
  510. data/spec/dummy/public/favicon.ico +0 -0
  511. data/spec/factories/accounts.rb +9 -0
  512. data/spec/factories/user_profiles.rb +10 -0
  513. data/spec/factories/users.rb +19 -0
  514. data/spec/helpers/account_helper_spec.rb +50 -0
  515. data/spec/models/account_spec.rb +20 -0
  516. data/spec/models/user_spec.rb +99 -0
  517. data/spec/rails_helper.rb +70 -0
  518. data/spec/spec_helper.rb +85 -0
  519. data/spec/support/accounts.rb +19 -0
  520. data/spec/support/devise.rb +44 -0
  521. data/spec/support/fix_locale.rb +57 -0
  522. metadata +1124 -0
@@ -0,0 +1,210 @@
1
+ require 'csv'
2
+ require 'dm_core/scio_excel'
3
+
4
+ # require 'ruport'
5
+
6
+ # Implements CSV Export functionality
7
+ #------------------------------------------------------------------------------
8
+ module CsvExporter
9
+
10
+ # include Ruport
11
+ # include DmUtilities::RenderingHelper
12
+
13
+ #------------------------------------------------------------------------------
14
+ def data_export(column_definitions, data_array, options = {})
15
+ case options[:format]
16
+ when 'xls'
17
+ excel_export(column_definitions, data_array, options)
18
+ when 'ruport'
19
+ # ruport_export(column_definitions, data_array, options)
20
+ else
21
+ csv_export(column_definitions, data_array, options)
22
+ end
23
+ end
24
+
25
+ # Exports data to a CSV formatted file.
26
+ # column_definitions: defines the name of the fields and how they are accessed.
27
+ # Array of items, where each item is an array of
28
+ # name used in CSV column
29
+ # name used to access the value in the data records
30
+ # width of field
31
+ # optional formatting instructions as a Hash
32
+ # ex)
33
+ # column_definitions = []
34
+ # column_definitions << ["Receipt Code", "'R-' + item.receipt_code", 75]
35
+ # column_definitions << ["State", "item.state.capitalize"]
36
+ # column_definitions << ['Process State', 'item.aasm_state', 100]
37
+ # column_definitions << ['Registered on', 'item.created_at.to_date', 75, {:type => 'DateTime', :numberformat => 'd mmm, yyyy'}]
38
+ # column_definitions << ["Price", "item.workshop_price.price.to_f", nil, {:type => 'Number', :numberformat => '#,##0.00'}]
39
+ #
40
+ # data_array: an array of objects (link from a find)
41
+ # :filename => 'file_name' name of file to save as.
42
+ # :expressions => true : the data definintion can be a complex expression,
43
+ # so simply evaluate it directly. To access the current item, the expression
44
+ # should use 'item', as in 'item.name.blank? ? "n/a" : item.name'
45
+ #------------------------------------------------------------------------------
46
+ def csv_export(column_definitions, data_array, options = {})
47
+ options.symbolize_keys
48
+ outputArray = Array.new
49
+ csv_string = CSV.generate do |csv|
50
+ column_definitions.each { |x| outputArray << x[0] }
51
+ csv << outputArray
52
+
53
+ data_array.each do |item|
54
+ outputArray.clear
55
+ column_definitions.each do |x|
56
+ data = get_data_value(item, x[1], options)
57
+ #data = "\"#{data}\"" if data.include?(',') #--- add quotes if comma included
58
+ outputArray << data
59
+ end
60
+ csv << outputArray
61
+ end
62
+ end
63
+ if options[:filename]
64
+ send_data csv_string, :filename => to_csv_filename(options[:filename]), :disposition => 'attachment', :type => 'text/csv'
65
+ else
66
+ return csv_string
67
+ end
68
+ end
69
+
70
+ # Exports data to a CSV formatted file, using columns directly from a table
71
+ # table_name: name of the table exporting. Column names are pulled from it.
72
+ # data_array: an array of hashes (link from a find)
73
+ #------------------------------------------------------------------------------
74
+ def csv_export_rawtable(table_name, data_array, options = {})
75
+ column_definitions = Array.new
76
+ for column in eval("#{table_name}.content_columns")
77
+ column_definitions << [column.name, column.name]
78
+ end
79
+ csv_export(column_definitions, data_array, options)
80
+ end
81
+
82
+ # Exports data to an Excel formatted file.
83
+ # column_definitions: defines the name of the fields and how they are accessed.
84
+ # Array of items, where each item is an array of
85
+ # name used in CSV column
86
+ # name used to access the value in the data records
87
+ # width of field
88
+ # optional formatting instructions as a Hash
89
+ # ex)
90
+ # column_definitions = []
91
+ # column_definitions << ["Receipt Code", "'R-' + item.receipt_code", 75]
92
+ # column_definitions << ["State", "item.state.capitalize"]
93
+ # column_definitions << ['Process State', 'item.aasm_state', 100]
94
+ # column_definitions << ['Registered on', 'item.created_at.to_date', 75, {:type => 'DateTime', :numberformat => 'd mmm, yyyy'}]
95
+ # column_definitions << ["Price", "item.workshop_price.price.to_f", nil, {:type => 'Number', :numberformat => '#,##0.00'}]
96
+ #
97
+ # data_array: an array of objects (link from a find)
98
+ # :filename => 'file_name' name of file to save as.
99
+ # :expressions => true : the data definintion can be a complex expression,
100
+ # so simply evaluate it directly. To access the current item, the expression
101
+ # should use 'item', as in 'item.name.blank? ? "n/a" : item.name'
102
+ #------------------------------------------------------------------------------
103
+ def excel_export(column_definitions, data_array, options = {})
104
+ options.symbolize_keys
105
+ rows = Array.new
106
+ columns = Array.new
107
+
108
+ #--- create the workbook
109
+ wb = Scio::Excel::SimpleWorkbook.new(to_excel_filename(options[:filename] ? options[:filename] : 'Workbook'))
110
+ stc = wb.default_cell_style
111
+ stc.borders = stc.borders & 0
112
+
113
+ column_definitions.each do |x|
114
+ style = x[3].nil? ? nil : Scio::Excel::SimpleStyle.new(x[3])
115
+ c = Scio::Excel::Column.new(x[0], x[3].nil? ? {} : x[3])
116
+ c.width = x[2] unless x[2].nil?
117
+ c.cell_style = style
118
+ columns << c
119
+ end
120
+
121
+ data_array.each do |item|
122
+ data = {}
123
+ column_definitions.each do |x|
124
+ data[x[0]] = get_data_value(item, x[1], options)
125
+ end
126
+ rows << data
127
+ end
128
+
129
+ wb.columns = columns
130
+ wb.rows = rows
131
+
132
+ if options[:filename]
133
+ send_data wb.create, :filename => to_excel_filename(options[:filename]), :disposition => 'attachment', :type => 'application/excel'
134
+ else
135
+ return wb.create
136
+ end
137
+ end
138
+
139
+ =begin
140
+ #------------------------------------------------------------------------------
141
+ def ruport_export(column_definitions, data_array, options = {})
142
+ options.symbolize_keys
143
+ output_array = Array.new
144
+ column_array = Array.new
145
+
146
+ column_definitions.each { |x| column_array << x[0] }
147
+
148
+ table = Table(column_array) do |t|
149
+ data_array.each do |item|
150
+ output_array.clear
151
+ column_definitions.each do |x|
152
+ value = get_data_value(item, x[1], options)
153
+ output_array << convert_value(value, x[3])
154
+ end
155
+ t << output_array
156
+ end
157
+ end
158
+ return table
159
+ end
160
+ =end
161
+
162
+ private
163
+ #------------------------------------------------------------------------------
164
+ def get_data_value(item, data_def, options)
165
+ begin
166
+ if item.is_a? Hash
167
+ value = options[:expressions] ? eval('(' + data_def + ').to_s') : eval('item[' + data_def + '].to_s')
168
+ else
169
+ value = options[:expressions] ? eval('(' + data_def + ').to_s') : eval('item.' + data_def + '.to_s')
170
+ end
171
+ rescue
172
+ #--- catch any nil references
173
+ value = nil
174
+ end
175
+ return value.nil? ? '' : value.gsub(/[\r\n]/, '') # strip off \r and \n
176
+ end
177
+
178
+ # Use the column_options to change data to a specific type
179
+ #------------------------------------------------------------------------------
180
+ def convert_value(value, column_options)
181
+ if column_options
182
+ case column_options[:type]
183
+ when 'Number'
184
+ return value.to_i
185
+ when 'link'
186
+ end
187
+ end
188
+
189
+ return value
190
+ end
191
+
192
+ #------------------------------------------------------------------------------
193
+ def to_csv_filename(title)
194
+ the_time = Time.now
195
+ file_prefix = "#{the_time.year}_#{the_time.mon}_#{the_time.day}_"
196
+ filename = (file_prefix + title.gsub(/[^\w\.\-]/,'_')).squeeze('_')
197
+ filename + '.csv'
198
+ end
199
+
200
+ # Older Excel limited to 32 char filenames
201
+ # -- removed filename length limit - put back if problems occur
202
+ #------------------------------------------------------------------------------
203
+ def to_excel_filename(title)
204
+ the_time = Time.now
205
+ file_prefix = "#{the_time.year}_#{the_time.mon}_#{the_time.day}_"
206
+ filename = (file_prefix + title.gsub(/[^\w\.\-]/,'_')).squeeze('_')
207
+ # --- removed filename length limit - put back if problems occur : (filename.length > 27 ? filename[0...27] : filename) + '.xls'
208
+ filename + '.xls'
209
+ end
210
+ end
@@ -0,0 +1,16 @@
1
+ # Implements CSV Import functionality
2
+ #------------------------------------------------------------------------------
3
+ module CsvImporter
4
+
5
+ require 'csv'
6
+
7
+ # import data from CSV file and return an Array of Hashes
8
+ #------------------------------------------------------------------------------
9
+ def csv_import(the_file)
10
+ import_list = Array.new
11
+ CSV.foreach(the_file, headers: true) do |row|
12
+ import_list << row.to_hash
13
+ end
14
+ return import_list
15
+ end
16
+ end
@@ -0,0 +1,51 @@
1
+ require 'csv'
2
+
3
+ require 'devise'
4
+ require 'rolify'
5
+ require 'cancan'
6
+ require 'globalize'
7
+ require 'country_select'
8
+ require 'simple_form'
9
+ require 'will_paginate'
10
+ require 'paper_trail'
11
+ require 'RedCloth'
12
+ require 'kramdown'
13
+ require 'liquid'
14
+ require 'sanitize'
15
+ require 'acts_as_commentable'
16
+ require 'acts_as_votable'
17
+ require 'acts_as_follower'
18
+ require 'acts-as-taggable-on'
19
+ require 'ancestry'
20
+ require 'ranked-model'
21
+ require 'amoeba'
22
+ require 'babosa'
23
+ require 'friendly_id'
24
+ require 'aasm'
25
+ require 'monetize/core_extensions'
26
+ require 'money-rails'
27
+ require 'exception_notification'
28
+ require 'aws-sdk'
29
+ require 'biggs'
30
+ require 'codemirror-rails'
31
+ require 'mini_magick'
32
+ require 'carrierwave'
33
+
34
+ module DmCore
35
+ class Engine < ::Rails::Engine
36
+ isolate_namespace DmCore
37
+
38
+ initializer 'engine.helper' do |app|
39
+ ActionView::Base.send :include, RenderHelper
40
+ ActiveSupport.on_load(:action_controller) do
41
+ include DmCore::ApplicationHelper
42
+ end
43
+ end
44
+
45
+ config.before_initialize do
46
+ DmCore.initialize_configuration
47
+ end
48
+ end
49
+
50
+
51
+ end
@@ -0,0 +1,125 @@
1
+ # Allow Liquid tags to be namespaced, based on the account_prefix. This allows
2
+ # multiple sites to have tags named the same, but the correct one will get used
3
+ # during rendering
4
+ #------------------------------------------------------------------------------
5
+ module Liquid
6
+ class Template
7
+ class << self
8
+
9
+ #------------------------------------------------------------------------------
10
+ def register_tag(name, klass)
11
+ register_tag_namespace(name, klass)
12
+ end
13
+
14
+ # Store tags in a namespace, usually a theme name. This is so we can register
15
+ # many different tags for each theme and keep them seperate.
16
+ #------------------------------------------------------------------------------
17
+ def register_tag_namespace(name, klass, namespace = 'system_tags')
18
+ tags_namespaced(namespace)[name.to_s] = klass
19
+ end
20
+
21
+ # return the list of tags that are available. Tags available at any instance is
22
+ # the global tags, the current theme's tags, and the parent theme's tags.
23
+ #------------------------------------------------------------------------------
24
+ def tags
25
+ if Account.current.nil?
26
+ tags_namespaced('system_tags').merge(@tags)
27
+ else
28
+ t = tags_namespaced('system_tags').merge(@tags).merge(tags_namespaced(Account.current.current_theme))
29
+
30
+ #--- if parent theme, reverse_merge tags - they should not override current theme tags
31
+ t.reverse_merge!(tags_namespaced(Account.current.parent_theme)) if Account.current.parent_theme
32
+ return t
33
+ end
34
+ end
35
+
36
+ #------------------------------------------------------------------------------
37
+ def tags_namespaced(namespace)
38
+ @tags_namespaced ||= {}
39
+ @tags_namespaced[namespace] ||= {}
40
+ end
41
+ end
42
+ end
43
+ end
44
+
45
+ #------------------------------------------------------------------------------
46
+ module LiquidExtensions
47
+ module Helpers
48
+ # So that tags can render Erb and have access to normal Rails helpers
49
+ # http://robots.thoughtbot.com/post/159806314/custom-tags-in-liquid
50
+ #------------------------------------------------------------------------------
51
+ def render_erb(context, file_name, locals = {})
52
+ context.registers[:controller].send(:render_to_string, :partial => file_name, :locals => locals)
53
+ end
54
+
55
+ #------------------------------------------------------------------------------
56
+ def context_account_site_assets(context)
57
+ context.registers[:account_site_assets]
58
+ end
59
+ end
60
+ end
61
+
62
+ # Pull common setup functions of Tag and Block
63
+ #------------------------------------------------------------------------------
64
+ module DmCore
65
+ class LiquidTag < Liquid::Tag
66
+ include LiquidExtensions::Helpers
67
+
68
+ SimpleSyntax = /#{Liquid::QuotedFragment}/
69
+ NamedSyntax = /(#{Liquid::QuotedFragment})\s*\:\s*(#{Liquid::QuotedFragment})/
70
+
71
+ #------------------------------------------------------------------------------
72
+ def initialize(tag_name, markup, tokens)
73
+ @attributes = {}
74
+ markup.scan(Liquid::TagAttributes) do |key, value|
75
+ @attributes[key] = ((value.delete "\"").delete "\'")
76
+ end
77
+ super
78
+ end
79
+
80
+ class << self
81
+ #------------------------------------------------------------------------------
82
+ def tag_name
83
+ self.name.split('::').last.underscore
84
+ end
85
+ def details
86
+ { name: self.tag_name, summary: '', description: '', example: '', category: '' }
87
+ end
88
+ end
89
+ end
90
+ end
91
+
92
+ module DmCore
93
+ class LiquidBlock < Liquid::Block
94
+ include LiquidExtensions::Helpers
95
+
96
+ SimpleSyntax = /#{Liquid::QuotedFragment}/
97
+ NamedSyntax = /(#{Liquid::QuotedFragment})\s*\:\s*(#{Liquid::QuotedFragment})/
98
+
99
+ #------------------------------------------------------------------------------
100
+ def initialize(tag_name, markup, tokens)
101
+ @attributes = {}
102
+ markup.scan(Liquid::TagAttributes) do |key, value|
103
+ @attributes[key] = ((value.delete "\"").delete "\'")
104
+ end
105
+ super
106
+ end
107
+
108
+ # Liquid will automatically throw away a block with empty/blank content.
109
+ # Call this in the tag's render method to allow the tag to be rendered anyway
110
+ #------------------------------------------------------------------------------
111
+ def allow_empty_block
112
+ @blank = false
113
+ end
114
+
115
+ class << self
116
+ #------------------------------------------------------------------------------
117
+ def tag_name
118
+ self.name.split('::').last.underscore
119
+ end
120
+ def details
121
+ { name: self.tag_name, summary: '', description: '', example: '', category: '' }
122
+ end
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,31 @@
1
+
2
+ #------------------------------------------------------------------------------
3
+ module Nls
4
+
5
+ CONTINENTS = ['Europe', 'North America', 'South America', 'Oceania', 'Asia', 'Africa', 'Antartica']
6
+
7
+ # default scope the msg lookup to the current theme
8
+ #------------------------------------------------------------------------------
9
+ def nls(message_key, options = {})
10
+ #--- look up message in the scope of current theme, fallback to parent theme
11
+ key = "#{Account.current.current_theme}.#{message_key.to_s}"
12
+ fallback = Account.current.parent_theme ? "#{Account.current.parent_theme}.#{message_key.to_s}" : "translation missing: #{key}"
13
+ I18n.t(key, options.merge(default: fallback.to_sym))
14
+ end
15
+
16
+ # Check if the message exists
17
+ #------------------------------------------------------------------------------
18
+ def nls?(message_key)
19
+ key = "#{Account.current.current_theme}.#{message_key.to_s}"
20
+ I18n.t key, :raise => true rescue false
21
+ end
22
+
23
+ # Helper to generate the image_tag for a language flag.
24
+ # nls_flag_image(:en)
25
+ #------------------------------------------------------------------------------
26
+ def nls_flag_image(lang = nil)
27
+ image_tag(DmCore::Language.flag_image(lang))
28
+ end
29
+
30
+ end
31
+
@@ -0,0 +1,501 @@
1
+ require 'builder'
2
+
3
+ # Scio Excel Library
4
+ #
5
+ # v.0.2.1
6
+ #
7
+ # Copyright (c) Rolando Abarca Millán 2005-2006
8
+ #
9
+ # rabarca@scio.cl
10
+ #
11
+ # This library is free software; you can redistribute it and/or modify
12
+ # it under the terms of the GNU General Public License as published by
13
+ # the Free Software Foundation; either version 2 of the License, or
14
+ # (at your option) any later version.
15
+ #
16
+ # This program is distributed in the hope that it will be useful,
17
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
+ # GNU General Public License for more details.
20
+ #
21
+ # You should have received a copy of the GNU General Public License
22
+ # along with this program; if not, write to the Free Software
23
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24
+ #
25
+ # == Installation
26
+ #
27
+ # Put this file in $Rails.root/lib, restart your server.
28
+ #
29
+ # <b>NOTE</b>: this library will become a rails plugin in the near future
30
+
31
+ module Scio
32
+ module Excel
33
+
34
+ BORDER_ALL = 0b1111
35
+ BORDER_LEFT = 0b0001
36
+ BORDER_TOP = 0b0010
37
+ BORDER_RIGHT = 0b0100
38
+ BORDER_BOTTOM = 0b1000
39
+
40
+ # = SimpleWorkbook
41
+ # This is a one-sheet workbook. Really simple.
42
+ # It allows you to create an excel workbook from an array of hashes
43
+ #
44
+ # == Example 1
45
+ #
46
+ # # first, create the styles (You should check the default styles)
47
+ # st1 = Scio::Excel::SimpleStyle.new(:text => {:valign => "Top"},
48
+ # :borders => Scio::Excel::BORDER_ALL)
49
+ # st2 = Scio::Excel::SimpleStyle.new(:text => {:valign => "Top", :wrap => true},
50
+ # :borders => Scio::Excel::BORDER_ALL)
51
+ # st3 = Scio::Excel::SimpleStyle.new(:borders => Scio::Excel::BORDER_ALL,
52
+ # :bgcolor => "#666699",
53
+ # :font => {:bold => true, :color => "#ffffff"})
54
+ #
55
+ # # now, create the columns. The order of appearance is the order in which you push them
56
+ # # to the array.
57
+ # columns = []
58
+ # columns << Scio::Excel::Column.new("Birthday", :width => 76.5, :cell_style => st1, :header_style => st3)
59
+ # columns << Scio::Excel::Column.new("Name", :width => 276.75, :cell_style => st1, :header_style => st3)
60
+ #
61
+ # # next, create the data array
62
+ # rows = User.all.collect {|u| {"Birthday" => u.bday.strftime("%d/%m/%Y"), "Name" => u.name}}
63
+ #
64
+ # # create the workbook
65
+ # wb = Scio::Excel::SimpleWorkbook.new("User's birthday List")
66
+ # wb.columns = columns
67
+ # wb.rows = rows
68
+ #
69
+ # # finally, send the workbook to the browser
70
+ # headers['Content-type'] = "application/vnd.ms-excel"
71
+ # render_text(e.create)
72
+ #
73
+ # == Example 2 (Default Styles & PDF Output)
74
+ #
75
+ # (needs fpdf for the PDF output)
76
+ #
77
+ # wb = Scio::Excel::SimpleWorkbook.new("test de excel")
78
+ #
79
+ # # create styles
80
+ # sth = Scio::Excel::SimpleStyle.new
81
+ # sth.text[:halign] = "Center"
82
+ # sth.font[:bold] = true
83
+ # sth.bgcolor = "#CCFFCC"
84
+ # sth.borders = Scio::Excel::BORDER_TOP | Scio::Excel::BORDER_BOTTOM
85
+ # stc = wb.default_cell_style
86
+ # stc.font[:italic] = true
87
+ # stc.text[:halign] = "Left"
88
+ #
89
+ # # create the columns
90
+ # columns = Array.new
91
+ # columns << Scio::Excel::Column.new("Nombre Cliente", :width => 150, :header_style => sth)
92
+ # columns << Scio::Excel::Column.new("R.U.T", :width => 40, :header_style => sth)
93
+ #
94
+ # # crear the data
95
+ # rows = Cliente.order('razon_social').collect {|c|
96
+ # {"Nombre Cliente" => c.razon_social, "R.U.T" => c.rut}
97
+ # }
98
+ #
99
+ # # set columns and rows
100
+ # wb.columns = columns
101
+ # wb.rows = rows
102
+ # send_data wb.create_pdf, :filename => "something.pdf", :type => "application/pdf"
103
+ #
104
+ # == Attributes
105
+ #
106
+ # +columns+:: array of Column
107
+ # +rows+:: array of Hashes, each one representing a row. The key for the Hash must be
108
+ # the name of the corresponding column.
109
+ # +name+:: name of the workbook. This will be the name of the single worksheet.
110
+ # +row_height+:: set this to the height of the data rows.
111
+ #
112
+ # == Inspiration
113
+ #
114
+ # This library was inspired by the Excel Export Plugin:
115
+ #
116
+ # http://www.napcsweb.com/blog/2006/02/10/excel-plugin-10
117
+ class SimpleWorkbook
118
+ attr_accessor :columns,
119
+ :rows,
120
+ :name,
121
+ :row_height
122
+
123
+ def initialize(name)
124
+ @name = name
125
+ @columns = []
126
+ @rows = []
127
+ @row_height = nil
128
+ @style_id = 0
129
+ end
130
+
131
+ # Creates the xml text of the Workbook. You can send it to the browser
132
+ # using <tt>render_text</tt>. You might need to set the HTTP headers
133
+ # before.
134
+ #
135
+ # == Example
136
+ #
137
+ # wb = Scio::Excel::Workbook.new("list")
138
+ # ...
139
+ # render_text(wb.create)
140
+ def create
141
+ buffer = ""
142
+ xml = Builder::XmlMarkup.new(:target => buffer, :indent => 2)
143
+ xml.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
144
+ xml.Workbook({
145
+ 'xmlns' => "urn:schemas-microsoft-com:office:spreadsheet",
146
+ 'xmlns:o' => "urn:schemas-microsoft-com:office:office",
147
+ 'xmlns:x' => "urn:schemas-microsoft-com:office:excel",
148
+ 'xmlns:html' => "http://www.w3.org/TR/REC-html40",
149
+ 'xmlns:ss' => "urn:schemas-microsoft-com:office:spreadsheet"
150
+ }) do
151
+ # add styles to the workbook
152
+ styles = []
153
+ @columns.each do |c|
154
+ # use the default style if none set
155
+ hstyle = (c.header_style.nil?) ? default_header_style : c.header_style
156
+ cstyle = (c.cell_style.nil?) ? default_cell_style : c.cell_style
157
+ # set the style, in case it's the default one
158
+ c.header_style = hstyle
159
+ c.cell_style = cstyle
160
+ styles << hstyle unless styles.include?(hstyle)
161
+ styles << cstyle unless styles.include?(cstyle)
162
+ end
163
+ xml.Styles do
164
+ xml.Style 'ss:ID' => 'Default', 'ss:Name' => 'Normal' do
165
+ xml.Alignment 'ss:Vertical' => 'Bottom'
166
+ xml.Borders
167
+ xml.Font 'ss:FontName' => 'Arial'
168
+ xml.Interior
169
+ xml.NumberFormat
170
+ xml.Protection
171
+ end
172
+ styles.each do |s|
173
+ xml << s.create(self)
174
+ end
175
+ end
176
+ xml << createWorksheet(@name)
177
+ # reset the styles-id
178
+ @style_id = 0
179
+ end # Workbook
180
+ end
181
+
182
+ # attempt to create a pdf for the table.
183
+ #
184
+ # == Example
185
+ #
186
+ # wb = Scio::Excel::Workbook.new("customers")
187
+ # ...
188
+ # send_data wb.create_pdf, :filename => "something.pdf", :type => "application/pdf"
189
+ #
190
+ # One thing to note is that you <b>must</b> specify a width for each
191
+ # column, and that the units for the columns are different than those
192
+ # for excel (i.e: specify smaller numbers).
193
+ #
194
+ # This requires fpdf (http://zeropluszero.com/software/fpdf/)
195
+ def create_pdf(orientation = "L")
196
+ require 'fpdf'
197
+ raise "Invalid orientation" if !["L","P"].include?(orientation)
198
+ pdf = FPDF.new
199
+ # default font
200
+ pdf.SetFont('Arial', '', 14)
201
+ pdf.AddPage(orientation)
202
+ # first, create the headers
203
+ @columns.each do |c|
204
+ # set the style
205
+ hstyle = (c.header_style.nil?) ? default_header_style : c.header_style
206
+ rgb = hstyle.bgcolor.to_rgb rescue nil
207
+ fill = 0
208
+ unless rgb.nil?
209
+ pdf.SetFillColor(rgb[:red], rgb[:green], rgb[:blue])
210
+ fill = 1
211
+ end
212
+ rgb = hstyle.font[:color].to_rgb rescue nil
213
+ pdf.SetTextColor(rgb[:red], rgb[:green], rgb[:blue]) unless rgb.nil?
214
+ fstyle = String.new
215
+ fstyle << "B" if hstyle.font[:bold]
216
+ fstyle << "I" if hstyle.font[:italic]
217
+ pdf.SetFont('',fstyle)
218
+ border = 0
219
+ if hstyle.borders > 0
220
+ if hstyle.borders == BORDER_ALL
221
+ border = 1
222
+ else
223
+ border = String.new
224
+ border << "T" if hstyle.borders & BORDER_TOP > 0
225
+ border << "B" if hstyle.borders & BORDER_BOTTOM > 0
226
+ border << "L" if hstyle.borders & BORDER_LEFT > 0
227
+ border << "R" if hstyle.borders & BORDER_RIGHT > 0
228
+ end
229
+ end
230
+ align = "C"
231
+ unless hstyle.text[:align].nil?
232
+ align = "L" if hstyle.text[:halign] == "Left"
233
+ align = "R" if hstyle.text[:halign] == "Right"
234
+ end
235
+ # draw the cells
236
+ pdf.Cell(c.width, 7, c.name, border, 0, align, fill)
237
+ end # headers
238
+ pdf.Ln
239
+
240
+ # reset the styles
241
+ pdf.SetTextColor(0,0,0)
242
+ pdf.SetFont('','')
243
+
244
+ # draw the rows
245
+ @rows.each do |r|
246
+ # set the style
247
+ @columns.each do |c|
248
+ cstyle = (c.cell_style.nil?) ? default_cell_style : c.cell_style
249
+ rgb = cstyle.bgcolor.to_rgb rescue nil
250
+ fill = 0
251
+ unless rgb.nil?
252
+ pdf.SetFillColor(rgb[:red], rgb[:green], rgb[:blue])
253
+ fill = 1
254
+ end
255
+ rgb = cstyle.font[:color].to_rgb rescue nil
256
+ pdf.SetTextColor(rgb[:red], rgb[:green], rgb[:blue]) unless rgb.nil?
257
+ fstyle = String.new
258
+ fstyle << "B" if cstyle.font[:bold]
259
+ fstyle << "I" if cstyle.font[:italic]
260
+ pdf.SetFont('',fstyle)
261
+ border = 0
262
+ if cstyle.borders > 0
263
+ if cstyle.borders == BORDER_ALL
264
+ border = 1
265
+ else
266
+ border = String.new
267
+ border << "T" if cstyle.borders & BORDER_TOP > 0
268
+ border << "B" if cstyle.borders & BORDER_BOTTOM > 0
269
+ border << "L" if cstyle.borders & BORDER_LEFT > 0
270
+ border << "R" if cstyle.borders & BORDER_RIGHT > 0
271
+ end
272
+ end
273
+ align = "C"
274
+ unless cstyle.text[:align].nil?
275
+ align = "L" if cstyle.text[:halign] == "Left"
276
+ align = "R" if cstyle.text[:halign] == "Right"
277
+ end
278
+ pdf.Cell(c.width, 7, r[c.name], border, 0, align, fill)
279
+ end # columns
280
+ pdf.Ln
281
+ end # rows
282
+
283
+ # salida
284
+ pdf.Output
285
+ end
286
+
287
+ # creates a default style for the header. This is used in case you don't
288
+ # set a style for the column. If you really want a "plain" style, create
289
+ # a column with an empty one:
290
+ #
291
+ # nst = Scio::Excel::SimpleStyle.new
292
+ # col = Scio::Excel::Column.new("name", :header_style => nst)
293
+ #
294
+ # Since the default style is an instance variable, you don't need to set the
295
+ # style for a column if you modify it.
296
+ #
297
+ # == Example
298
+ #
299
+ # wb = Scio::Excel::SimpleWorkbook.new("user list")
300
+ # sth = wb.default_header_style
301
+ # sth.bgcolor = "#CCFFCC"
302
+ # columns = Array.new
303
+ # # when rendering, the columns will use the default header style, but with a
304
+ # # bgcolor = #CCFFCC.
305
+ # columns << Scio::Excel::Column.new("User Name", :width => 276.75)
306
+ # columns << Scio::Excel::Column.new("Birthday", :width => 76.5)
307
+ #
308
+ # The same applies for the default_cell_style.
309
+ def default_header_style
310
+ if @default_header_style.nil?
311
+ st = SimpleStyle.new
312
+ st.font[:bold] = true
313
+ st.font[:color] = "#FFFFFF"
314
+ st.borders = BORDER_ALL
315
+ st.text[:halign] = "Center"
316
+ st.bgcolor = "#666699"
317
+ @default_header_style = st
318
+ end
319
+ @default_header_style
320
+ end
321
+
322
+ # creates a default style for the cell. See default_header_style for documentation.
323
+ def default_cell_style
324
+ if @default_cell_style.nil?
325
+ st = SimpleStyle.new
326
+ st.borders = BORDER_ALL
327
+ st.text[:valign] = "Center"
328
+ @default_cell_style = st
329
+ end
330
+ @default_cell_style
331
+ end
332
+
333
+ def next_style_id #:nodoc:
334
+ @style_id += 1
335
+ "s#{@style_id}"
336
+ end
337
+
338
+ protected
339
+ def createWorksheet(name) #:nodoc:
340
+ buffer = ""
341
+ xml = Builder::XmlMarkup.new(:target => buffer, :indent => 2)
342
+ xml.Worksheet 'ss:Name' => name do
343
+ xml.Table do
344
+ # create header
345
+ @columns.each do |c|
346
+ col_opts = {}
347
+ if !c.width.nil? && c.width > 0
348
+ col_opts['ss:AutoFitWidth'] = "0"
349
+ col_opts['ss:Width'] = c.width
350
+ end
351
+ xml.Column col_opts
352
+ end
353
+ xml.Row do
354
+ @columns.each do |c|
355
+ col_opts = {}
356
+ col_opts['ss:StyleID'] = c.header_style.excel_id unless c.header_style.nil?
357
+ xml.Cell col_opts do
358
+ xml.Data c.name, 'ss:Type' => 'String'
359
+ end
360
+ end
361
+ end
362
+ # now, add data :-)
363
+ @rows.each do |r|
364
+ row_opts = {}
365
+ row_opts["ss:AutoFitHeight"] = "0"
366
+ row_opts["ss:Height"] = @row_height unless @row_height.nil?
367
+ xml.Row row_opts do
368
+ @columns.each do |c|
369
+ cell_opts = {}
370
+ cell_opts["ss:StyleID"] = c.cell_style.excel_id unless c.cell_style.nil?
371
+ xml.Cell cell_opts do
372
+ unless r[c.name].blank?
373
+ xml.Data r[c.name], 'ss:Type' => c.type
374
+ end
375
+ end
376
+ end
377
+ end
378
+ end # rows
379
+ end # Table
380
+ end # Worksheet
381
+ xml.target!
382
+ end
383
+
384
+ end # SimpleWorkbook
385
+
386
+ # Defines a Column for the data. You can set different styles for the
387
+ # header and the cells.
388
+ #
389
+ # You can also set the width of the column.
390
+ class Column
391
+ attr_accessor :name,
392
+ :header_style,
393
+ :cell_style,
394
+ :width,
395
+ :type
396
+ def initialize(name, opts = {})
397
+ @name = name
398
+ @header_style = opts[:header_style]
399
+ @cell_style = opts[:cell_style]
400
+ @width = opts[:width]
401
+ @type = opts[:type].nil? ? 'String' : opts[:type]
402
+ end
403
+ end
404
+
405
+ # SimpleStyle tries to simplify the styles for an individual cell.
406
+ #
407
+ # Current options are:
408
+ #
409
+ # * text alignment (vertical, horizontal)
410
+ # * text wrapping
411
+ # * font style (bold, italics, color)
412
+ # * background color for the cell
413
+ # * borders
414
+ #
415
+ # == Example
416
+ #
417
+ # # simple center-align
418
+ # st1 = Scio::Excel::SimpleStyle.new(:text => {:halign => "Center"})
419
+ # # wrap text to the cell
420
+ # st2 = Scio::Excel::SimpleStyle.new(:text => {:wrap => true})
421
+ # # set background color
422
+ # st2.bgcolor = "#666699"
423
+ # # set the borders
424
+ # st2.borders = Scio::Excel::BORDER_ALL
425
+ # # set only the left & right border
426
+ # st1.borders = Scio::Excel::BORDER_LEFT | Scio::Excel::BORDER_RIGHT
427
+ # # italics
428
+ # st1.font[:italic] = true
429
+ class SimpleStyle
430
+ attr_accessor :text,
431
+ :font,
432
+ :borders,
433
+ :excel_id,
434
+ :bgcolor,
435
+ :numberformat
436
+
437
+ def initialize(opts = {})
438
+ @text = opts[:text] || {}
439
+ @font = opts[:font] || {}
440
+ @borders = opts[:borders].nil? ? 0 : opts[:borders]
441
+ @bgcolor = opts[:bgcolor]
442
+ @numberformat = opts[:numberformat]
443
+ end
444
+
445
+ # Creates the xml for the style. You should not call this directly.
446
+ def create(workbook)
447
+ buffer = ""
448
+ xml = Builder::XmlMarkup.new(:target => buffer, :indent => 2)
449
+ @excel_id = workbook.next_style_id
450
+ xml.Style 'ss:ID' => @excel_id do
451
+ unless @text.empty?
452
+ alignment_opts = {}
453
+ alignment_opts["ss:Vertical"] = @text[:valign] if !@text[:valign].nil?
454
+ alignment_opts["ss:Horizontal"] = @text[:halign] if !@text[:halign].nil?
455
+ alignment_opts["ss:WrapText"] = "1" if @text[:wrap]
456
+ xml.Alignment alignment_opts unless alignment_opts.empty?
457
+ end
458
+ unless @font.empty?
459
+ font_opts = {}
460
+ font_opts["ss:Bold"] = "1" if @font[:bold]
461
+ font_opts["ss:Italic"] = "1" if @font[:italic]
462
+ font_opts["ss:Color"] = @font[:color] unless @font[:color].nil?
463
+ xml.Font font_opts unless font_opts.empty?
464
+ end
465
+ if @borders > 0
466
+ xml.Borders do
467
+ xml.Border "ss:Position" => "Bottom",
468
+ "ss:LineStyle" => "Continuous",
469
+ "ss:Weight" => "1" if @borders & BORDER_BOTTOM > 0
470
+ xml.Border "ss:Position" => "Left",
471
+ "ss:LineStyle" => "Continuous",
472
+ "ss:Weight" => "1" if @borders & BORDER_LEFT > 0
473
+ xml.Border "ss:Position" => "Right",
474
+ "ss:LineStyle" => "Continuous",
475
+ "ss:Weight" => "1" if @borders & BORDER_RIGHT > 0
476
+ xml.Border "ss:Position" => "Top",
477
+ "ss:LineStyle" => "Continuous",
478
+ "ss:Weight" => "1" if @borders & BORDER_TOP > 0
479
+ end
480
+ end
481
+ xml.Interior "ss:Color" => @bgcolor, "ss:Pattern" => "Solid" unless @bgcolor.nil?
482
+ xml.NumberFormat "ss:Format" => @numberformat unless @numberformat.nil?
483
+ end
484
+ xml.target!
485
+ end
486
+ end # SimpleStyle
487
+
488
+ end
489
+ end
490
+
491
+ class String
492
+ # simple (and naive) way to convert html-hex color to array of colors
493
+ def to_rgb
494
+ raise "Invalid Hex Color" if self.size != 7 || self[0] != 35
495
+ rgb = Hash.new
496
+ rgb[:red] = self[1,2].to_i(16)
497
+ rgb[:green] = self[3,2].to_i(16)
498
+ rgb[:blue] = self[5,2].to_i(16)
499
+ rgb
500
+ end
501
+ end