dm_core 4.2.1.5

Sign up to get free protection for your applications and to get access to all the features.
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