mail_engine 0.0.1

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 (313) hide show
  1. data/.yardoc/checksums +17 -0
  2. data/.yardoc/objects/ActionMailer/Base/collect_responses_and_parts_order_i.dat +0 -0
  3. data/.yardoc/objects/ActionMailer/Base/mail_i.dat +0 -0
  4. data/.yardoc/objects/ActionMailer/Base/origin_mail_i.dat +0 -0
  5. data/.yardoc/objects/ActionMailer/Base/set_layout_and_partials_i.dat +0 -0
  6. data/.yardoc/objects/ActionMailer/Base.dat +0 -0
  7. data/.yardoc/objects/ActionMailer/Collector/custom_i.dat +0 -0
  8. data/.yardoc/objects/ActionMailer/Collector.dat +0 -0
  9. data/.yardoc/objects/ActionMailer.dat +0 -0
  10. data/.yardoc/objects/MailEngine/ActsAsMailReceiver/ClassMethods/acts_as_mail_receiver_i.dat +0 -0
  11. data/.yardoc/objects/MailEngine/ActsAsMailReceiver/ClassMethods.dat +0 -0
  12. data/.yardoc/objects/MailEngine/ActsAsMailReceiver.dat +0 -0
  13. data/.yardoc/objects/MailEngine/Base/_40_40configurations.dat +0 -0
  14. data/.yardoc/objects/MailEngine/Base/current_config_c.dat +0 -0
  15. data/.yardoc/objects/MailEngine/Base/send_mail_c.dat +0 -0
  16. data/.yardoc/objects/MailEngine/Base.dat +0 -0
  17. data/.yardoc/objects/MailEngine/Configuration/load_c.dat +0 -0
  18. data/.yardoc/objects/MailEngine/Configuration.dat +0 -0
  19. data/.yardoc/objects/MailEngine/CreateConfig/create_config_file_i.dat +0 -0
  20. data/.yardoc/objects/MailEngine/CreateConfig.dat +0 -0
  21. data/.yardoc/objects/MailEngine/CreateMigration/create_migrations_i.dat +0 -0
  22. data/.yardoc/objects/MailEngine/CreateMigration.dat +0 -0
  23. data/.yardoc/objects/MailEngine/Engine.dat +0 -0
  24. data/.yardoc/objects/MailEngine/HtmlDocumentAssetsReplacer/check_21_c.dat +0 -0
  25. data/.yardoc/objects/MailEngine/HtmlDocumentAssetsReplacer/process_c.dat +0 -0
  26. data/.yardoc/objects/MailEngine/HtmlDocumentAssetsReplacer/replace_resource_filename_in_html_c.dat +0 -0
  27. data/.yardoc/objects/MailEngine/HtmlDocumentAssetsReplacer/replace_resource_url_in_html_c.dat +0 -0
  28. data/.yardoc/objects/MailEngine/HtmlDocumentAssetsReplacer.dat +0 -0
  29. data/.yardoc/objects/MailEngine/MailLogSubscriber/deliver_i.dat +0 -0
  30. data/.yardoc/objects/MailEngine/MailLogSubscriber.dat +0 -0
  31. data/.yardoc/objects/MailEngine/Sendgrid/Base/ClassMethods/sendgrid_header_i.dat +0 -0
  32. data/.yardoc/objects/MailEngine/Sendgrid/Base/ClassMethods.dat +0 -0
  33. data/.yardoc/objects/MailEngine/Sendgrid/Base/InstanceMethods.dat +0 -0
  34. data/.yardoc/objects/MailEngine/Sendgrid/Base.dat +0 -0
  35. data/.yardoc/objects/MailEngine/Sendgrid/FilterSetting/data_3D_i.dat +0 -0
  36. data/.yardoc/objects/MailEngine/Sendgrid/FilterSetting/data_i.dat +0 -0
  37. data/.yardoc/objects/MailEngine/Sendgrid/FilterSetting/initialize_i.dat +0 -0
  38. data/.yardoc/objects/MailEngine/Sendgrid/FilterSetting/validate_config_21_i.dat +0 -0
  39. data/.yardoc/objects/MailEngine/Sendgrid/FilterSetting.dat +0 -0
  40. data/.yardoc/objects/MailEngine/Sendgrid/RestApi/blocks_c.dat +0 -0
  41. data/.yardoc/objects/MailEngine/Sendgrid/RestApi/bounces_c.dat +0 -0
  42. data/.yardoc/objects/MailEngine/Sendgrid/RestApi/invalidemails_c.dat +0 -0
  43. data/.yardoc/objects/MailEngine/Sendgrid/RestApi/spamreports_c.dat +0 -0
  44. data/.yardoc/objects/MailEngine/Sendgrid/RestApi/stats_c.dat +0 -0
  45. data/.yardoc/objects/MailEngine/Sendgrid/RestApi.dat +0 -0
  46. data/.yardoc/objects/MailEngine/Sendgrid/RestApiError.dat +0 -0
  47. data/.yardoc/objects/MailEngine/Sendgrid/SmtpApi/add_sub_val_i.dat +0 -0
  48. data/.yardoc/objects/MailEngine/Sendgrid/SmtpApi/add_to_i.dat +0 -0
  49. data/.yardoc/objects/MailEngine/Sendgrid/SmtpApi/category_i.dat +0 -0
  50. data/.yardoc/objects/MailEngine/Sendgrid/SmtpApi/filters_i.dat +0 -0
  51. data/.yardoc/objects/MailEngine/Sendgrid/SmtpApi/initialize_i.dat +0 -0
  52. data/.yardoc/objects/MailEngine/Sendgrid/SmtpApi/set_unique_args_i.dat +0 -0
  53. data/.yardoc/objects/MailEngine/Sendgrid/SmtpApi/to_hash_i.dat +0 -0
  54. data/.yardoc/objects/MailEngine/Sendgrid/SmtpApi/to_json_i.dat +0 -0
  55. data/.yardoc/objects/MailEngine/Sendgrid/SmtpApi/to_s_i.dat +0 -0
  56. data/.yardoc/objects/MailEngine/Sendgrid/SmtpApi.dat +0 -0
  57. data/.yardoc/objects/MailEngine/Sendgrid.dat +0 -0
  58. data/.yardoc/objects/MailEngine/VERSION.dat +0 -0
  59. data/.yardoc/objects/MailEngine/ZipProcessor/extract_all_files_c.dat +0 -0
  60. data/.yardoc/objects/MailEngine/ZipProcessor.dat +0 -0
  61. data/.yardoc/objects/MailEngine.dat +0 -0
  62. data/.yardoc/objects/PLACEHOLDERS_IN_LAYOUT.dat +0 -0
  63. data/.yardoc/objects/root.dat +0 -0
  64. data/.yardoc/proxy_types +0 -0
  65. data/Gemfile +36 -0
  66. data/Gemfile.lock +159 -0
  67. data/MIT-LICENSE +20 -0
  68. data/README.mkd +152 -0
  69. data/Rakefile +57 -0
  70. data/VERSION +1 -0
  71. data/app/controllers/mail_engine/application_controller.rb +7 -0
  72. data/app/controllers/mail_engine/dashboard_controller.rb +9 -0
  73. data/app/controllers/mail_engine/mail_logs_controller.rb +20 -0
  74. data/app/controllers/mail_engine/mail_schedules_controller.rb +56 -0
  75. data/app/controllers/mail_engine/mail_template_files_controller.rb +46 -0
  76. data/app/controllers/mail_engine/mail_templates_controller.rb +141 -0
  77. data/app/controllers/mail_engine/reports_controller.rb +34 -0
  78. data/app/helpers/mail_engine/mail_engine_helper.rb +30 -0
  79. data/app/mailers/mail_engine/mail_dispatcher.rb +59 -0
  80. data/app/models/mail_engine/mail_log.rb +36 -0
  81. data/app/models/mail_engine/mail_schedule.rb +70 -0
  82. data/app/models/mail_engine/mail_template.rb +270 -0
  83. data/app/models/mail_engine/mail_template_file.rb +31 -0
  84. data/app/models/mail_engine/template_partial.rb +9 -0
  85. data/app/uploaders/mail_engine/template_file_uploader.rb +47 -0
  86. data/app/uploaders/mail_engine/zip_file_uploader.rb +47 -0
  87. data/app/views/layouts/mail_engine/mail_engine.html.erb +112 -0
  88. data/app/views/layouts/mail_engine/mail_template_layouts/header_and_footer.html.erb +10 -0
  89. data/app/views/layouts/mail_engine/mail_template_layouts/header_and_footer.text.erb +3 -0
  90. data/app/views/layouts/mail_engine/mail_template_layouts/none.html.erb +8 -0
  91. data/app/views/layouts/mail_engine/mail_template_layouts/none.text.erb +1 -0
  92. data/app/views/layouts/mail_engine/mail_template_layouts/only_footer.html.erb +9 -0
  93. data/app/views/layouts/mail_engine/mail_template_layouts/only_footer.text.erb +2 -0
  94. data/app/views/mail_engine/dashboard/index.html.erb +64 -0
  95. data/app/views/mail_engine/mail_logs/index.html.erb +34 -0
  96. data/app/views/mail_engine/mail_logs/show.html.erb +38 -0
  97. data/app/views/mail_engine/mail_schedules/_form.html.erb +45 -0
  98. data/app/views/mail_engine/mail_schedules/edit.html.erb +16 -0
  99. data/app/views/mail_engine/mail_schedules/index.html.erb +50 -0
  100. data/app/views/mail_engine/mail_schedules/new.html.erb +13 -0
  101. data/app/views/mail_engine/mail_schedules/show.html.erb +44 -0
  102. data/app/views/mail_engine/mail_template_files/_form.html.erb +28 -0
  103. data/app/views/mail_engine/mail_template_files/edit.html.erb +9 -0
  104. data/app/views/mail_engine/mail_template_files/new.html.erb +9 -0
  105. data/app/views/mail_engine/mail_templates/_form.html.erb +97 -0
  106. data/app/views/mail_engine/mail_templates/_layout_selector.html.erb +50 -0
  107. data/app/views/mail_engine/mail_templates/duplicate.html.erb +41 -0
  108. data/app/views/mail_engine/mail_templates/edit.html.erb +16 -0
  109. data/app/views/mail_engine/mail_templates/index.html.erb +69 -0
  110. data/app/views/mail_engine/mail_templates/new.html.erb +12 -0
  111. data/app/views/mail_engine/mail_templates/new_by_upload.html.erb +63 -0
  112. data/app/views/mail_engine/mail_templates/partial_options.html.erb +28 -0
  113. data/app/views/mail_engine/mail_templates/preview.html.erb +1 -0
  114. data/app/views/mail_engine/mail_templates/preview.text.erb +1 -0
  115. data/app/views/mail_engine/mail_templates/show.html.erb +64 -0
  116. data/app/views/mail_engine/reports/charts/blocks.html.erb +21 -0
  117. data/app/views/mail_engine/reports/charts/bounces.html.erb +21 -0
  118. data/app/views/mail_engine/reports/charts/invalidemails.html.erb +19 -0
  119. data/app/views/mail_engine/reports/charts/spamreports.html.erb +17 -0
  120. data/app/views/mail_engine/reports/index.html.erb +67 -0
  121. data/config/routes.rb +48 -0
  122. data/db/migrate/20110114030841_create_table_mail_template.rb +22 -0
  123. data/db/migrate/20110126030525_create_mail_schedules.rb +21 -0
  124. data/db/migrate/20110204114145_create_template_partials.rb +13 -0
  125. data/db/migrate/20110206025002_create_mail_logs.rb +17 -0
  126. data/db/migrate/20110217062316_create_mail_template_files.rb +14 -0
  127. data/doc/_index.html +322 -0
  128. data/doc/class_list.html +36 -0
  129. data/doc/css/common.css +1 -0
  130. data/doc/css/full_list.css +53 -0
  131. data/doc/css/style.css +310 -0
  132. data/doc/file_list.html +38 -0
  133. data/doc/frames.html +13 -0
  134. data/doc/js/app.js +203 -0
  135. data/doc/js/full_list.js +149 -0
  136. data/doc/js/jquery.js +154 -0
  137. data/doc/method_list.html +283 -0
  138. data/lib/mail_engine/action_mailer_patch.rb +104 -0
  139. data/lib/mail_engine/acts_as_mail_receiver.rb +22 -0
  140. data/lib/mail_engine/base.rb +26 -0
  141. data/lib/mail_engine/configuration.rb +11 -0
  142. data/lib/mail_engine/engine.rb +42 -0
  143. data/lib/mail_engine/generators/create_config.rb +20 -0
  144. data/lib/mail_engine/generators/create_migration.rb +20 -0
  145. data/lib/mail_engine/generators/templates/mail_engine_config.yml +14 -0
  146. data/lib/mail_engine/html_document_assets_replacer.rb +86 -0
  147. data/lib/mail_engine/mail_log_subscriber.rb +30 -0
  148. data/lib/mail_engine/placeholders_in_layout.rb +5 -0
  149. data/lib/mail_engine/sendgrid/base.rb +45 -0
  150. data/lib/mail_engine/sendgrid/rest_api.rb +85 -0
  151. data/lib/mail_engine/sendgrid/smtp_api.rb +85 -0
  152. data/lib/mail_engine/sendgrid.rb +9 -0
  153. data/lib/mail_engine/tasks/sendmail.rake +8 -0
  154. data/lib/mail_engine/version.rb +3 -0
  155. data/lib/mail_engine/zip_processor.rb +51 -0
  156. data/lib/mail_engine.rb +17 -0
  157. data/mail_engine.gemspec +422 -0
  158. data/screenshots/bounce_report.png +0 -0
  159. data/screenshots/dashboard.png +0 -0
  160. data/screenshots/editing_mail_template.png +0 -0
  161. data/screenshots/logs.png +0 -0
  162. data/screenshots/new_by_upload.png +0 -0
  163. data/screenshots/reports.png +0 -0
  164. data/screenshots/schedule.png +0 -0
  165. data/screenshots/select_layout_partial.png +0 -0
  166. data/screenshots/templates.png +0 -0
  167. data/test/dummy/Rakefile +7 -0
  168. data/test/dummy/app/controllers/application_controller.rb +11 -0
  169. data/test/dummy/app/helpers/application_helper.rb +2 -0
  170. data/test/dummy/app/mailers/user_mailer.rb +36 -0
  171. data/test/dummy/app/models/user.rb +10 -0
  172. data/test/dummy/config/application.rb +52 -0
  173. data/test/dummy/config/boot.rb +10 -0
  174. data/test/dummy/config/database.yml +52 -0
  175. data/test/dummy/config/environment.rb +5 -0
  176. data/test/dummy/config/environments/development.rb +47 -0
  177. data/test/dummy/config/environments/production.rb +49 -0
  178. data/test/dummy/config/environments/test.rb +43 -0
  179. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  180. data/test/dummy/config/initializers/inflections.rb +10 -0
  181. data/test/dummy/config/initializers/mime_types.rb +5 -0
  182. data/test/dummy/config/initializers/secret_token.rb +7 -0
  183. data/test/dummy/config/initializers/session_store.rb +8 -0
  184. data/test/dummy/config/locales/en.yml +5 -0
  185. data/test/dummy/config/locales/zh.yml +2 -0
  186. data/test/dummy/config/routes.rb +58 -0
  187. data/test/dummy/config.ru +4 -0
  188. data/test/dummy/db/migrate/20110114030841_create_table_mail_template.rb +22 -0
  189. data/test/dummy/db/migrate/20110125094530_create_users.rb +16 -0
  190. data/test/dummy/db/migrate/20110126030525_create_mail_schedules.rb +21 -0
  191. data/test/dummy/db/migrate/20110204114145_create_template_partials.rb +13 -0
  192. data/test/dummy/db/migrate/20110206025002_create_mail_logs.rb +17 -0
  193. data/test/dummy/db/migrate/20110217062316_create_mail_template_files.rb +14 -0
  194. data/test/dummy/db/schema.rb +78 -0
  195. data/test/dummy/public/404.html +26 -0
  196. data/test/dummy/public/422.html +26 -0
  197. data/test/dummy/public/500.html +26 -0
  198. data/test/dummy/public/favicon.ico +0 -0
  199. data/test/dummy/public/images/mail_engine/header_and_footer_layout.png +0 -0
  200. data/test/dummy/public/images/mail_engine/logo.gif +0 -0
  201. data/test/dummy/public/images/mail_engine/logo.png +0 -0
  202. data/test/dummy/public/images/mail_engine/none_layout.png +0 -0
  203. data/test/dummy/public/images/mail_engine/only_footer_layout.png +0 -0
  204. data/test/dummy/public/images/mail_engine/unselect_header_and_footer_layout.png +0 -0
  205. data/test/dummy/public/images/mail_engine/unselect_none_layout.png +0 -0
  206. data/test/dummy/public/images/mail_engine/unselect_only_footer_layout.png +0 -0
  207. data/test/dummy/public/javascripts/jquery.iframe-auto-height.plugin.js +50 -0
  208. data/test/dummy/public/javascripts/jquery.js +16 -0
  209. data/test/dummy/public/javascripts/jquery.nyroModal/img/ajaxLoader.gif +0 -0
  210. data/test/dummy/public/javascripts/jquery.nyroModal/img/close.gif +0 -0
  211. data/test/dummy/public/javascripts/jquery.nyroModal/img/next.gif +0 -0
  212. data/test/dummy/public/javascripts/jquery.nyroModal/img/prev.gif +0 -0
  213. data/test/dummy/public/javascripts/jquery.nyroModal/js/jquery.nyroModal-ie6.js +186 -0
  214. data/test/dummy/public/javascripts/jquery.nyroModal/js/jquery.nyroModal-ie6.min.js +9 -0
  215. data/test/dummy/public/javascripts/jquery.nyroModal/js/jquery.nyroModal.custom.js +1599 -0
  216. data/test/dummy/public/javascripts/jquery.nyroModal/js/jquery.nyroModal.custom.min.js +34 -0
  217. data/test/dummy/public/javascripts/jquery.nyroModal/styles/nyroModal.css +102 -0
  218. data/test/dummy/public/javascripts/jquery.string.js +425 -0
  219. data/test/dummy/public/javascripts/mail_engine_application.js +2 -0
  220. data/test/dummy/public/javascripts/markitup/jquery.markitup.js +564 -0
  221. data/test/dummy/public/javascripts/markitup/sets/css/images/bold.png +0 -0
  222. data/test/dummy/public/javascripts/markitup/sets/css/images/css.png +0 -0
  223. data/test/dummy/public/javascripts/markitup/sets/css/images/italic.png +0 -0
  224. data/test/dummy/public/javascripts/markitup/sets/css/images/picture.png +0 -0
  225. data/test/dummy/public/javascripts/markitup/sets/css/images/stroke.png +0 -0
  226. data/test/dummy/public/javascripts/markitup/sets/css/images/tag.png +0 -0
  227. data/test/dummy/public/javascripts/markitup/sets/css/images/text_align_center.png +0 -0
  228. data/test/dummy/public/javascripts/markitup/sets/css/images/text_align_justify.png +0 -0
  229. data/test/dummy/public/javascripts/markitup/sets/css/images/text_align_left.png +0 -0
  230. data/test/dummy/public/javascripts/markitup/sets/css/images/text_align_right.png +0 -0
  231. data/test/dummy/public/javascripts/markitup/sets/css/images/text_indent.png +0 -0
  232. data/test/dummy/public/javascripts/markitup/sets/css/images/text_letterspacing.png +0 -0
  233. data/test/dummy/public/javascripts/markitup/sets/css/images/text_linespacing.png +0 -0
  234. data/test/dummy/public/javascripts/markitup/sets/css/images/text_lowercase.png +0 -0
  235. data/test/dummy/public/javascripts/markitup/sets/css/images/text_padding_bottom.png +0 -0
  236. data/test/dummy/public/javascripts/markitup/sets/css/images/text_padding_left.png +0 -0
  237. data/test/dummy/public/javascripts/markitup/sets/css/images/text_padding_right.png +0 -0
  238. data/test/dummy/public/javascripts/markitup/sets/css/images/text_padding_top.png +0 -0
  239. data/test/dummy/public/javascripts/markitup/sets/css/images/text_uppercase.png +0 -0
  240. data/test/dummy/public/javascripts/markitup/sets/css/readme.txt +28 -0
  241. data/test/dummy/public/javascripts/markitup/sets/css/set.js +52 -0
  242. data/test/dummy/public/javascripts/markitup/sets/css/style.css +72 -0
  243. data/test/dummy/public/javascripts/markitup/sets/default/images/bold.png +0 -0
  244. data/test/dummy/public/javascripts/markitup/sets/default/images/clean.png +0 -0
  245. data/test/dummy/public/javascripts/markitup/sets/default/images/image.png +0 -0
  246. data/test/dummy/public/javascripts/markitup/sets/default/images/italic.png +0 -0
  247. data/test/dummy/public/javascripts/markitup/sets/default/images/link.png +0 -0
  248. data/test/dummy/public/javascripts/markitup/sets/default/images/picture.png +0 -0
  249. data/test/dummy/public/javascripts/markitup/sets/default/images/preview.png +0 -0
  250. data/test/dummy/public/javascripts/markitup/sets/default/images/stroke.png +0 -0
  251. data/test/dummy/public/javascripts/markitup/sets/default/set.js +27 -0
  252. data/test/dummy/public/javascripts/markitup/sets/default/style.css +27 -0
  253. data/test/dummy/public/javascripts/markitup/sets/html/images/bold.png +0 -0
  254. data/test/dummy/public/javascripts/markitup/sets/html/images/clean.png +0 -0
  255. data/test/dummy/public/javascripts/markitup/sets/html/images/h1.png +0 -0
  256. data/test/dummy/public/javascripts/markitup/sets/html/images/h2.png +0 -0
  257. data/test/dummy/public/javascripts/markitup/sets/html/images/h3.png +0 -0
  258. data/test/dummy/public/javascripts/markitup/sets/html/images/h4.png +0 -0
  259. data/test/dummy/public/javascripts/markitup/sets/html/images/h5.png +0 -0
  260. data/test/dummy/public/javascripts/markitup/sets/html/images/h6.png +0 -0
  261. data/test/dummy/public/javascripts/markitup/sets/html/images/image.png +0 -0
  262. data/test/dummy/public/javascripts/markitup/sets/html/images/italic.png +0 -0
  263. data/test/dummy/public/javascripts/markitup/sets/html/images/link.png +0 -0
  264. data/test/dummy/public/javascripts/markitup/sets/html/images/list-bullet.png +0 -0
  265. data/test/dummy/public/javascripts/markitup/sets/html/images/list-item.png +0 -0
  266. data/test/dummy/public/javascripts/markitup/sets/html/images/list-numeric.png +0 -0
  267. data/test/dummy/public/javascripts/markitup/sets/html/images/paragraph.png +0 -0
  268. data/test/dummy/public/javascripts/markitup/sets/html/images/picture.png +0 -0
  269. data/test/dummy/public/javascripts/markitup/sets/html/images/preview.png +0 -0
  270. data/test/dummy/public/javascripts/markitup/sets/html/images/stroke.png +0 -0
  271. data/test/dummy/public/javascripts/markitup/sets/html/readme.txt +11 -0
  272. data/test/dummy/public/javascripts/markitup/sets/html/set.js +40 -0
  273. data/test/dummy/public/javascripts/markitup/sets/html/style.css +59 -0
  274. data/test/dummy/public/javascripts/markitup/skins/markitup/images/bg-container.png +0 -0
  275. data/test/dummy/public/javascripts/markitup/skins/markitup/images/bg-editor-bbcode.png +0 -0
  276. data/test/dummy/public/javascripts/markitup/skins/markitup/images/bg-editor-dotclear.png +0 -0
  277. data/test/dummy/public/javascripts/markitup/skins/markitup/images/bg-editor-html.png +0 -0
  278. data/test/dummy/public/javascripts/markitup/skins/markitup/images/bg-editor-json.png +0 -0
  279. data/test/dummy/public/javascripts/markitup/skins/markitup/images/bg-editor-markdown.png +0 -0
  280. data/test/dummy/public/javascripts/markitup/skins/markitup/images/bg-editor-textile.png +0 -0
  281. data/test/dummy/public/javascripts/markitup/skins/markitup/images/bg-editor-wiki.png +0 -0
  282. data/test/dummy/public/javascripts/markitup/skins/markitup/images/bg-editor-xml.png +0 -0
  283. data/test/dummy/public/javascripts/markitup/skins/markitup/images/bg-editor.png +0 -0
  284. data/test/dummy/public/javascripts/markitup/skins/markitup/images/handle.png +0 -0
  285. data/test/dummy/public/javascripts/markitup/skins/markitup/images/menu.png +0 -0
  286. data/test/dummy/public/javascripts/markitup/skins/markitup/images/submenu.png +0 -0
  287. data/test/dummy/public/javascripts/markitup/skins/markitup/style.css +147 -0
  288. data/test/dummy/public/javascripts/markitup/skins/simple/images/handle.png +0 -0
  289. data/test/dummy/public/javascripts/markitup/skins/simple/images/menu.png +0 -0
  290. data/test/dummy/public/javascripts/markitup/skins/simple/images/submenu.png +0 -0
  291. data/test/dummy/public/javascripts/markitup/skins/simple/style.css +118 -0
  292. data/test/dummy/public/javascripts/markitup/templates/preview.css +5 -0
  293. data/test/dummy/public/javascripts/markitup/templates/preview.html +11 -0
  294. data/test/dummy/public/javascripts/rails.js +132 -0
  295. data/test/dummy/public/stylesheets/.gitkeep +0 -0
  296. data/test/dummy/public/stylesheets/application.css +0 -0
  297. data/test/dummy/public/stylesheets/style.css +681 -0
  298. data/test/dummy/script/rails +6 -0
  299. data/test/factories.rb +88 -0
  300. data/test/fixtures/files/compress_by_dir.zip +0 -0
  301. data/test/fixtures/files/compress_by_file.zip +0 -0
  302. data/test/fixtures/files/image.png +0 -0
  303. data/test/functional/mail_engine/mail_dispatcher_test.rb +8 -0
  304. data/test/functional/mail_engine/mail_schedules_controller_controller_test.rb +8 -0
  305. data/test/functional/mail_engine/mail_templates_controller_controller_test.rb +8 -0
  306. data/test/support/integration_case.rb +5 -0
  307. data/test/test_helper.rb +35 -0
  308. data/test/unit/mail_engine/mail_log_test.rb +8 -0
  309. data/test/unit/mail_engine/mail_schedule_test.rb +40 -0
  310. data/test/unit/mail_engine/mail_template_file_test.rb +21 -0
  311. data/test/unit/mail_engine/mail_template_test.rb +77 -0
  312. data/test/unit/mail_engine/template_partial_test.rb +8 -0
  313. metadata +597 -0
@@ -0,0 +1,270 @@
1
+ class MailEngine::MailTemplate < ActiveRecord::Base
2
+ attr_accessor :create_by_upload
3
+
4
+ mount_uploader :zip_file, MailEngine::ZipFileUploader
5
+
6
+ validates :name, :path, :presence => true
7
+ validates :locale, :inclusion => I18n.available_locales.map(&:to_s)
8
+ validates :format, :inclusion => Mime::SET.symbols.map(&:to_s)
9
+ validates :layout, :presence => true, :if => Proc.new {|template| !template.partial? }
10
+ validates :body, :presence => true, :if => Proc.new {|template| template.create_by_upload.blank? }
11
+ validates :zip_file, :presence => true, :if => Proc.new {|template| template.create_by_upload.present? }
12
+ validates :path, :format => { :with => /([^\/]+\/)+/i, :message => "path should looks like 'controller/action'" }, :if => Proc.new { |template| !template.for_marketing? }
13
+ # validates :handler, :inclusion => ActionView::Template::Handlers.extensions.map(&:to_s)
14
+ validates_uniqueness_of :path, :scope => [:locale, :handler, :format, :partial]
15
+
16
+ after_validation :check_placeholders_for_layout
17
+ before_validation :check_zip_file, :if => Proc.new {|template| template.create_by_upload.present? }
18
+
19
+ has_many :mail_schedules
20
+ has_many :template_partials, :dependent => :destroy
21
+ has_many :partials, :through => :template_partials
22
+ has_many :mail_template_files
23
+ # if self is partial, lookup back to mail templates.
24
+ has_many :partial_users, :class_name => "TemplatePartial", :foreign_key => "partial_id"
25
+ has_many :mail_templates, :through => :partial_users
26
+
27
+ accepts_nested_attributes_for :template_partials, :allow_destroy => true
28
+
29
+ scope :for_system, where(:for_marketing => false, :partial => false)
30
+ scope :for_marketing, where(:for_marketing => true, :partial => false)
31
+ scope :partial, where(:partial => true)
32
+ scope :html, where(:format => 'html')
33
+ scope :text, where(:format => 'text')
34
+
35
+ after_create :process_zip_file
36
+ before_save :delete_partials_if_new_partials_added
37
+
38
+ after_save do
39
+ MailEngine::MailTemplate::Resolver.instance.clear_cache # clear cached paths
40
+ end
41
+
42
+ def partial_in_use?
43
+ self.partial? and self.mail_templates.count > 0
44
+ end
45
+
46
+ def variations
47
+ self.class.where(:path => self.path).order("locale, format")
48
+ end
49
+
50
+ # has_many :logs, :class_name => "MailEngine::MailLog", :conditions => {:mail_template_path => self.path}
51
+ def logs
52
+ MailEngine::MailLog.where(:mail_template_path => self.path)
53
+ end
54
+
55
+ # TODOS: if no changes just keep the same, it sill will remove the template partial and add a new one
56
+ def delete_partials_if_new_partials_added
57
+ if self.template_partials.detect {|tmp| !tmp.persisted? }.present? || self.layout == 'none' # has new partials selected
58
+ MailEngine::TemplatePartial.destroy_all(:mail_template_id => self) # remove previous partials
59
+ end
60
+ end
61
+
62
+ # if uploaded a zip file, check:
63
+ # 1. only one html?
64
+ # 2. has html
65
+ def check_zip_file
66
+ begin
67
+ @extracted_files, @extraction_dir_path = MailEngine::ZipProcessor.extract_all_files(self.zip_file.path, %w{css jpg jpeg gif png html htm})
68
+
69
+ if @extracted_files.present?
70
+ MailEngine::HtmlDocumentAssetsReplacer.check! @extracted_files if @extracted_files.present?
71
+ else
72
+ raise "Extract zip file failed or not zip file."
73
+ end
74
+ rescue => e
75
+ errors.add(:file, e.message)
76
+ end
77
+ end
78
+
79
+ # FIXME: remove the hostname
80
+ def process_zip_file(hostname = "localhost:3000")
81
+ return if @extracted_files.blank?
82
+ self.update_attribute :body, MailEngine::HtmlDocumentAssetsReplacer.process(self, @extracted_files, hostname)
83
+ # remove the tmp files
84
+ system("rm -rf #{@extraction_dir_path}")
85
+ end
86
+
87
+ def check_placeholders_for_layout
88
+ return if self.partial?
89
+ if self.template_partials.detect{ |tmp| !tmp.persisted? }.present? || self.layout == 'none'
90
+ self.template_partials.delete_if { |tmp| tmp.persisted? }
91
+ end
92
+
93
+ names = self.template_partials.map(&:placeholder_name)
94
+
95
+ case self.layout
96
+ when "none"
97
+ errors.add(:partials, "should have no partials") unless names.blank?
98
+ when "only_footer"
99
+ errors.add(:partials, "should have footer partial") unless names.include?('footer') and names.size == 1
100
+ when "header_and_footer"
101
+ errors.add(:partials, "should have header and footer partials") unless names.include?('header') and names.include?('footer') and names.size == 2
102
+ else
103
+ end
104
+ end
105
+
106
+ ["html", "text"].each do |method|
107
+ define_method "#{method}?" do
108
+ self.format == method
109
+ end
110
+ end
111
+
112
+ def type
113
+ return 'partial' if self.partial?
114
+ return 'system' unless self.for_marketing?
115
+ return 'marketing' if self.for_marketing?
116
+ end
117
+
118
+ def template_name
119
+ self.path.scan(/[^\/]+$/).first
120
+ end
121
+
122
+ # prepend "_" at partial name.
123
+ def filename
124
+ tmp_path = self.path
125
+ if self.partial
126
+ tmp_path.gsub(/([^\/]+)\z/, '_\1')
127
+ else
128
+ tmp_path
129
+ end
130
+ end
131
+
132
+ def full_path
133
+ "#{filename}.#{self.locale}.#{self.format}.#{self.handler}"
134
+ end
135
+
136
+ # return one clone version of self
137
+ def duplicate merge_options = {}
138
+ ### create dictionary for custom cloning file object.
139
+ # dict = { :mail_template_files => {} }
140
+ # self.mail_template_files.each{ |f|
141
+ # clone_file = f.clone
142
+ # clone_file.file = File.open(f.file.path)
143
+ # dict[:mail_template_files][f] = clone_file
144
+ # }
145
+
146
+ # start to clone
147
+ duplicated_obj = self.clone :except => [:zip_file], :include => [:template_partials, :mail_template_files]
148
+ duplicated_obj.zip_file = File.open(self.zip_file.path) if self.zip_file.path
149
+ duplicated_obj.attributes = merge_options if merge_options.is_a? Hash
150
+ # without saving can't not create files. so save it first.
151
+ duplicated_obj.save
152
+
153
+ # pair the mail_template_files and insert into substitution_array.
154
+ substitution_pair_array = []
155
+ self.mail_template_files.each_with_index do |origin_file, index|
156
+ substitution_pair_array << [origin_file, duplicated_obj.mail_template_files[index]]
157
+ end
158
+
159
+ # replace image or file url with new url.
160
+ original_body = self.body
161
+
162
+ substitution_pair_array.each do |origin_file, new_file|
163
+ original_body = MailEngine::HtmlDocumentAssetsReplacer.replace_resource_url_in_html(
164
+ original_body,
165
+ origin_file.file.url,
166
+ new_file.file.url
167
+ )
168
+ end
169
+
170
+ # FIXME save twice here. but if not save the resource won't get correct url.
171
+ duplicated_obj.update_attributes :body => original_body
172
+ duplicated_obj
173
+ end
174
+
175
+ def send_test_mail_to!(recipient)
176
+ # raise "Wrong email format." if recipient.blank? or recipient !~ /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
177
+ raise "Can not find any user." if (sample_user = User.first).blank?
178
+
179
+ ### 3 conditions
180
+ # 1. action - marketing mail only have one action
181
+ # 2. controler/action
182
+ # 3. namespace/namespace/controller/action
183
+ #
184
+ path_sections = self.path.split("/")
185
+
186
+ if self.for_marketing?
187
+ action_name = path_sections.last
188
+ mailer_class_name = "MailEngine::MailDispatcher"
189
+ else
190
+ mailer_name = path_sections[-2]
191
+ action_name = path_sections[-1]
192
+ namespaces = path_sections - Array.wrap(path_sections[-2..-1])
193
+
194
+ if namespaces.present?
195
+ mailer_class_name = namespaces.map(&:classify).join("::")
196
+ mailer_class_name += "::#{mailer_name.classify}"
197
+ else
198
+ mailer_class_name = "#{mailer_name.classify}"
199
+ end
200
+ end
201
+
202
+ I18n.with_locale(self.locale) do
203
+ mailer_class_name.constantize.send(
204
+ action_name.to_sym,
205
+ :to => recipient
206
+ ).deliver
207
+ end
208
+ end
209
+
210
+
211
+ ###############################
212
+ # path resolver, used for find template by provided path.
213
+ class Resolver < ActionView::Resolver
214
+ require "singleton"
215
+ include Singleton
216
+
217
+ def find_templates(name, prefix, partial, details)
218
+ template_path_and_name = prefix.include?("mail_engine/mail_dispatcher") ? normalize_path(name, nil) : normalize_path(name, prefix)
219
+
220
+ conditions = {
221
+ :path => template_path_and_name,
222
+ :locale => normalize_array(details[:locale]).first,
223
+ :format => normalize_array(details[:formats]).first,
224
+ :handler => normalize_array(details[:handlers]),
225
+ :partial => partial || false
226
+ }
227
+
228
+ MailEngine::MailTemplate.where(conditions).map do |record|
229
+ initialize_template(record)
230
+ end
231
+ end
232
+
233
+ # Normalize name and prefix, so the tuple ["index", "users"] becomes
234
+ # "users/index" and the tuple ["template", nil] becomes "template".
235
+ def normalize_path(name, prefix)
236
+ prefix.present? ? "#{prefix}/#{name}" : name
237
+ end
238
+
239
+ # Normalize arrays by converting all symbols to strings.
240
+ def normalize_array(array)
241
+ array.map(&:to_s)
242
+ end
243
+
244
+ # Initialize an ActionView::Template object based on the record found.
245
+ def initialize_template(record)
246
+ source = record.body
247
+
248
+ identifier = "mail template - #{record.id} - #{record.path.inspect}"
249
+ handler = ActionView::Template.registered_template_handler(record.handler)
250
+
251
+ details = {
252
+ :format => Mime[record.format],
253
+ :updated_at => record.updated_at,
254
+ :virtual_path => virtual_path(record.path, record.partial)
255
+ }
256
+
257
+ ActionView::Template.new(source, identifier, handler, details)
258
+ end
259
+
260
+ # Make paths as "users/user" become "users/_user" for partials.
261
+ def virtual_path(path, partial)
262
+ return path unless partial
263
+ if index = path.rindex("/")
264
+ path.insert(index + 1, "_")
265
+ else
266
+ "_#{path}"
267
+ end
268
+ end
269
+ end # Resolver
270
+ end
@@ -0,0 +1,31 @@
1
+ class MailEngine::MailTemplateFile < ActiveRecord::Base
2
+ mount_uploader :file, MailEngine::TemplateFileUploader
3
+
4
+ validates :file, :presence => true
5
+
6
+ belongs_to :mail_template
7
+ delegate :url, :to => :file
8
+ after_save :replace_url_in_mail_template
9
+
10
+ def image?
11
+ return false if attributes["file"].blank?
12
+ File.basename(attributes["file"]) =~ /\.(j(e)?pg)|(png)|(gif)$/i
13
+ end
14
+
15
+ def replace_url_in_mail_template
16
+ if self.file_changed?
17
+ self.mail_template.update_attribute :body,
18
+ MailEngine::HtmlDocumentAssetsReplacer.replace_resource_filename_in_html(
19
+ self.mail_template.body,
20
+ self.file_was,
21
+ File.basename(self.file.url)
22
+ )
23
+ end
24
+ end
25
+
26
+ def clone *args
27
+ file_clone = super *args
28
+ file_clone.file = File.open(self.file.path)
29
+ file_clone
30
+ end
31
+ end
@@ -0,0 +1,9 @@
1
+ class MailEngine::TemplatePartial < ActiveRecord::Base
2
+ validates_presence_of :partial_id, :placeholder_name
3
+
4
+ belongs_to :mail_template
5
+ belongs_to :partial, :class_name => "MailTemplate", :foreign_key => :partial_id
6
+
7
+ scope :header, where(:placeholder_name => 'header')
8
+ scope :footer, where(:placeholder_name => 'footer')
9
+ end
@@ -0,0 +1,47 @@
1
+ # encoding: utf-8
2
+
3
+ class MailEngine::TemplateFileUploader < CarrierWave::Uploader::Base
4
+
5
+ # Include RMagick or ImageScience support:
6
+ # include CarrierWave::RMagick
7
+ # include CarrierWave::ImageScience
8
+
9
+ # Choose what kind of storage to use for this uploader:
10
+ storage :file
11
+ # storage :s3
12
+
13
+ # Override the directory where uploaded files will be stored.
14
+ # This is a sensible default for uploaders that are meant to be mounted:
15
+ def store_dir
16
+ "uploads/mail_engine/template_files/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
17
+ end
18
+
19
+ # Provide a default URL as a default if there hasn't been a file uploaded:
20
+ # def default_url
21
+ # "/images/fallback/" + [version_name, "default.png"].compact.join('_')
22
+ # end
23
+
24
+ # Process files as they are uploaded:
25
+ # process :scale => [200, 300]
26
+ #
27
+ # def scale(width, height)
28
+ # # do something
29
+ # end
30
+
31
+ # Create different versions of your uploaded files:
32
+ # version :thumb do
33
+ # process :scale => [50, 50]
34
+ # end
35
+
36
+ # Add a white list of extensions which are allowed to be uploaded.
37
+ # For images you might use something like this:
38
+ def extension_white_list
39
+ %w(jpg jpeg gif png css)
40
+ end
41
+
42
+ # Override the filename of the uploaded files:
43
+ # def filename
44
+ # "something.jpg" if original_filename
45
+ # end
46
+
47
+ end
@@ -0,0 +1,47 @@
1
+ # encoding: utf-8
2
+
3
+ class MailEngine::ZipFileUploader < CarrierWave::Uploader::Base
4
+
5
+ # Include RMagick or ImageScience support:
6
+ # include CarrierWave::RMagick
7
+ # include CarrierWave::ImageScience
8
+
9
+ # Choose what kind of storage to use for this uploader:
10
+ storage :file
11
+ # storage :s3
12
+
13
+ # Override the directory where uploaded files will be stored.
14
+ # This is a sensible default for uploaders that are meant to be mounted:
15
+ def store_dir
16
+ "uploads/mail_engine/template_zip_files/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
17
+ end
18
+
19
+ # Provide a default URL as a default if there hasn't been a file uploaded:
20
+ # def default_url
21
+ # "/images/fallback/" + [version_name, "default.png"].compact.join('_')
22
+ # end
23
+
24
+ # Process files as they are uploaded:
25
+ # process :scale => [200, 300]
26
+ #
27
+ # def scale(width, height)
28
+ # # do something
29
+ # end
30
+
31
+ # Create different versions of your uploaded files:
32
+ # version :thumb do
33
+ # process :scale => [50, 50]
34
+ # end
35
+
36
+ # Add a white list of extensions which are allowed to be uploaded.
37
+ # For images you might use something like this:
38
+ def extension_white_list
39
+ %w(zip)
40
+ end
41
+
42
+ # Override the filename of the uploaded files:
43
+ # def filename
44
+ # "something.jpg" if original_filename
45
+ # end
46
+
47
+ end
@@ -0,0 +1,112 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
+ <html xmlns="http://www.w3.org/1999/xhtml" dir="ltr">
3
+
4
+ <head>
5
+ <%= stylesheet_link_tag "style", "/javascripts/jquery.nyroModal/styles/nyroModal" %>
6
+ <%= javascript_include_tag "jquery", "rails", "jquery.iframe-auto-height.plugin", "jquery.string", "jquery.nyroModal/js/jquery.nyroModal.custom" %>
7
+
8
+ <!-- markitup -->
9
+ <%= stylesheet_link_tag "/javascripts/markitup/skins/markitup/style",
10
+ "/javascripts/markitup/sets/default/style",
11
+ "/javascripts/markitup/sets/html/style" %>
12
+ <%= javascript_include_tag "markitup/jquery.markitup",
13
+ "markitup/sets/default/set",
14
+ "markitup/sets/html/set" %>
15
+
16
+ <!-- used for google chart -->
17
+ <script type='text/javascript' src='https://www.google.com/jsapi'></script>
18
+
19
+ <!--[if IE 6]>
20
+ <script type="text/javascript" src="/javascripts/jquery.nyroModal/js/jquery.nyroModal-ie6.min.js"></script>
21
+ <![endif]-->
22
+
23
+ <%= csrf_meta_tag %>
24
+ <script>
25
+ $(function(){
26
+ $('.modal_link').nm();
27
+ jQuery('iframe').iframeAutoHeight({heightOffset: 50});
28
+
29
+ $("#loading").ajaxStart(function(){
30
+ $(this).slideDown("fast");
31
+ });
32
+
33
+ $("#loading").ajaxStop(function(){
34
+ $(this).slideUp("fast");
35
+ });
36
+ });
37
+ </script>
38
+ <title>Mail Engine</title>
39
+ </head>
40
+
41
+ <body>
42
+ <div id="loading">System is processing your request...</div>
43
+ <a name="top"></a>
44
+ <div id="site-wrapper">
45
+ <div id="header">
46
+
47
+ <div id="top">
48
+ <div class="left" id="logo">
49
+ <a href="/"><img src="/images/mail_engine/logo.gif" alt="" /></a>
50
+ </div>
51
+ <div class="left navigation" id="main-nav">
52
+ <ul class="tabbed">
53
+ <li <%= "class='current-tab'" if controller_name == 'dashboard' %>><%= link_to "Dashboard", mail_engine_dashboard_path %></li>
54
+ <li <%= "class='current-tab'" if controller_name == 'mail_templates' %>><%= link_to "Templates", mail_templates_path %></li>
55
+ <li <%= "class='current-tab'" if controller_name == 'mail_schedules' %>><%= link_to "Schedules", mail_schedules_path %></li>
56
+ <li <%= "class='current-tab'" if controller_name == 'mail_logs' %>><%= link_to "Logs", mail_logs_path %></li>
57
+ <li <%= "class='current-tab'" if controller_name == 'reports' %>><%= link_to "Reports", reports_path %></li>
58
+ </ul>
59
+ <div class="clearer">&nbsp;</div>
60
+ </div>
61
+ <div class="clearer">&nbsp;</div>
62
+ </div>
63
+
64
+ <% if controller_name == "mail_templates" %>
65
+ <div class="navigation" id="sub-nav">
66
+ <ul class="tabbed">
67
+ <li <%= "class='current-tab'" if controller_name == 'mail_templates' and params[:type] == 'system' %>><%= link_to "Sytem Mail Templates", mail_templates_path(:type => 'system') %></li>
68
+ <li <%= "class='current-tab'" if controller_name == 'mail_templates' and params[:type] == 'marketing' %>><%= link_to "Marketing Mail Templates", mail_templates_path(:type => 'marketing') %></li>
69
+ <li <%= "class='current-tab'" if controller_name == 'mail_templates' and params[:type] == 'partial' %>><%= link_to "Template Partials", mail_templates_path(:type => 'partial') %></li>
70
+ </ul>
71
+ <div class="clearer">&nbsp;</div>
72
+ </div>
73
+ <% elsif controller_name == "reports" %>
74
+ <div class="navigation" id="sub-nav">
75
+ <ul class="tabbed">
76
+ <li <%= "class='current-tab'" if controller_name == 'reports' and params[:type] == 'bounces' %>><%= link_to "Bounces", chart_reports_path(:type => 'bounces') %></li>
77
+ <li <%= "class='current-tab'" if controller_name == 'reports' and params[:type] == 'blocks' %>><%= link_to "Blocks", chart_reports_path(:type => 'blocks') %></li>
78
+ <li <%= "class='current-tab'" if controller_name == 'reports' and params[:type] == 'spamreports' %>><%= link_to "Spam Reports", chart_reports_path(:type => 'spamreports') %></li>
79
+ <li <%= "class='current-tab'" if controller_name == 'reports' and params[:type] == 'invalidemails' %>><%= link_to "Invalid Emails", chart_reports_path(:type => 'invalidemails') %></li>
80
+ </ul>
81
+ <div class="clearer">&nbsp;</div>
82
+ </div>
83
+ <% end %>
84
+ </div>
85
+
86
+ <% if notice %>
87
+ <h3 style="padding: 8px; margin-top: 8px" class="notice"><%= notice %></h3>
88
+ <% end %>
89
+
90
+ <div class="main">
91
+ <div class="section">
92
+ <div class="section-content">
93
+ <%= yield %>
94
+ </div>
95
+ </div>
96
+ </div>
97
+
98
+ <div id="footer">
99
+ <div class="left" id="footer-left">
100
+ <div class="clearer">&nbsp;</div>
101
+ </div>
102
+
103
+ <div class="right" id="footer-right">
104
+ <p class="large">
105
+ <a href="#top" class="quiet">Page Top &uarr;</a>
106
+ </p>
107
+ </div>
108
+ <div class="clearer">&nbsp;</div>
109
+ </div>
110
+ </div>
111
+ </body>
112
+ </html>
@@ -0,0 +1,10 @@
1
+ <html>
2
+ <head>
3
+ <title></title>
4
+ </head>
5
+ <body>
6
+ <div><%= raw render :partial => header_path %></div>
7
+ <%= yield %>
8
+ <div><%= raw render :partial => footer_path %></div>
9
+ </body>
10
+ </html>
@@ -0,0 +1,3 @@
1
+ <%= raw render :partial => header_path %>
2
+ <%= yield %>
3
+ <%= raw render :partial => footer_path %>
@@ -0,0 +1,8 @@
1
+ <html>
2
+ <head>
3
+ <title></title>
4
+ </head>
5
+ <body>
6
+ <%= yield %>
7
+ </body>
8
+ </html>
@@ -0,0 +1,9 @@
1
+ <html>
2
+ <head>
3
+ <title></title>
4
+ </head>
5
+ <body>
6
+ <%= yield %>
7
+ <%= raw render :partial => footer_path %>
8
+ </body>
9
+ </html>
@@ -0,0 +1,2 @@
1
+ <%= yield %>
2
+ <%= raw render :partial => footer_path %>
@@ -0,0 +1,64 @@
1
+ <script type="text/javascript">
2
+ // show today's pie chart
3
+ function drawPie() {
4
+ var data = new google.visualization.DataTable();
5
+ data.addColumn('string', 'Name');
6
+ data.addColumn('number', 'Rate');
7
+
8
+ data.addRows(<%= @pie_chart_columns.size %>);
9
+
10
+ <% @pie_chart_columns.each_with_index do |col, i| %>
11
+ data.setValue(<%= i %>, 0, "<%= col %>");
12
+ data.setValue(<%= i %>, 1, <%= @data_of_today[col] %>);
13
+ <% end %>
14
+
15
+ var chart = new google.visualization.PieChart(document.getElementById('pie_chart'));
16
+ chart.draw(data, {width: 350, height: 300, chartArea: {left:0,top:0,right:0,bottom:0, width:"100%",height:"100%"} });
17
+ }
18
+
19
+ var stats_data = <%= raw @stats_data.to_json %>;
20
+ google.load("visualization", "1", {packages:["corechart"]});
21
+ google.setOnLoadCallback(drawPie);
22
+ </script>
23
+
24
+ <div class="today-report left">
25
+
26
+ <h2>Report of Today</h2>
27
+ <div class="clearrer"></div>
28
+
29
+ <div class="left">
30
+ <table border="0" cellspacing="5" cellpadding="5" class="data-table" style="width: 500px; margin-top: 30px; margin-right: 30px">
31
+ <tr>
32
+ <th>Requests</th><td><%= @data_of_today["requests"] %></td>
33
+ <th>Delivered</th><td><%= @data_of_today["delivered"] %></td>
34
+ </tr>
35
+ <tr>
36
+ <th>Total Opens</th><td><%= @data_of_today["opens"] %></td>
37
+ <th>Unique Opens</th><td><%= @data_of_today["unique_opens"] %></td>
38
+ </tr>
39
+ <tr>
40
+ <th>Total Clicks</th><td><%= @data_of_today["clicks"] %></td>
41
+ <th>Unique Clicks</th><td><%= @data_of_today["unique_clicks"] %></td>
42
+ </tr>
43
+ <tr>
44
+ <th>Open Rate</th>
45
+ <td><%= show_percentage(@data_of_today["unique_opens"].to_f, @data_of_today["delivered"].to_f) %></td>
46
+ <th>Click Rate</th>
47
+ <td><%= show_percentage(@data_of_today["unique_clicks"].to_f, @data_of_today["delivered"].to_f) %></td>
48
+ </tr>
49
+ <tr>
50
+ <th>Bounces</th><td><%= @data_of_today["bounces"] %></td>
51
+ <th>Spams</th><td><%= @data_of_today["spamreports"] %></td>
52
+ </tr>
53
+ <tr>
54
+ <th>Blocks</th><td><%= @data_of_today["blocks"] %></td>
55
+ <th>Invalid Emails</th><td><%= @data_of_today["invalid_email"] %></td>
56
+ </tr>
57
+ </table>
58
+ </div>
59
+
60
+ <div class="right">
61
+ <div id='pie_chart'></div>
62
+ </div>
63
+ </div>
64
+ <div class="clearer"></div>
@@ -0,0 +1,34 @@
1
+ <div class="post">
2
+ <div class="post-title"><h2>Mail Logs</h2></div>
3
+ <div class="post-body">
4
+ <% show_no_record(@mail_logs) do %>
5
+ <table class="data-table">
6
+ <tr>
7
+ <th>Subject</th>
8
+ <th>Sender</th>
9
+ <th>Recipient</th>
10
+ <th>mime_type</th>
11
+ <th>Sent at</th>
12
+ <th></th>
13
+ </tr>
14
+
15
+ <% @mail_logs.each do |log| %>
16
+ <tr class="even">
17
+ <td><%= log.subject %></td>
18
+ <td><%= log.sender %></td>
19
+ <td><%= log.recipient %></td>
20
+ <td><%= log.mime_type %></td>
21
+ <td><%= log.created_at %></td>
22
+ <td>
23
+ <%= link_to 'Show', mail_log_path(log) %>
24
+ <%= link_to 'Destroy', mail_log_path(log), :confirm => 'Are you sure?', :method => :delete %>
25
+ </td>
26
+ </tr>
27
+ <% end %>
28
+ </table>
29
+ <%= will_paginate @mail_logs %>
30
+ <% end %>
31
+
32
+ <div class="clearer">&nbsp;</div>
33
+ </div>
34
+ </div>