typo 4.1 → 4.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (251) hide show
  1. data/Rakefile +1 -1
  2. data/TODO-4.2 +14 -0
  3. data/TODO.MULTIUSERS +45 -0
  4. data/app/controllers/admin/base_controller.rb +18 -0
  5. data/app/controllers/admin/general_controller.rb +14 -0
  6. data/app/controllers/application.rb +2 -1
  7. data/app/controllers/articles_controller.rb +18 -21
  8. data/app/helpers/admin/base_helper.rb +4 -4
  9. data/app/helpers/admin/feedback_helper.rb +3 -3
  10. data/app/helpers/application_helper.rb +2 -6
  11. data/app/helpers/sidebar_helper.rb +2 -2
  12. data/app/models/blog.rb +9 -1
  13. data/app/models/category.rb +9 -9
  14. data/app/models/comment.rb +1 -1
  15. data/app/models/content_state/presumed_ham.rb +2 -2
  16. data/app/models/resource.rb +2 -0
  17. data/app/views/admin/categories/_categories.rhtml +10 -6
  18. data/app/views/admin/categories/edit.rhtml +3 -1
  19. data/app/views/admin/comments/_form.rhtml +3 -3
  20. data/app/views/admin/comments/list.rhtml +7 -5
  21. data/app/views/admin/comments/new.rhtml +3 -1
  22. data/app/views/admin/comments/show.rhtml +3 -1
  23. data/app/views/admin/content/_articles.rhtml +1 -1
  24. data/app/views/admin/content/_form.rhtml +4 -2
  25. data/app/views/admin/content/new.rhtml +1 -0
  26. data/app/views/admin/content/preview.rhtml +8 -8
  27. data/app/views/admin/feedback/_item.rhtml +3 -1
  28. data/app/views/admin/feedback/list.rhtml +4 -4
  29. data/app/views/admin/general/index.rhtml +14 -1
  30. data/app/views/admin/pages/_form.rhtml +1 -1
  31. data/app/views/admin/pages/destroy.rhtml +1 -1
  32. data/app/views/admin/pages/new.rhtml +1 -0
  33. data/app/views/admin/shared/_edit.rhtml +2 -2
  34. data/app/views/layouts/administration.rhtml +5 -2
  35. data/app/views/layouts/minimal.rhtml +134 -2
  36. data/config/boot.rb +1 -1
  37. data/config/environment.rb +11 -3
  38. data/config/environments/test.rb +0 -7
  39. data/config/routes.rb +3 -0
  40. data/db/migrate/004_add_sidebars.rb +21 -3
  41. data/db/migrate/056_create_notifications.rb +1 -1
  42. data/db/migrate/062_add_sitealizer_plugin.rb +18 -0
  43. data/db/schema.mysql-v3.sql +217 -0
  44. data/db/schema.mysql.sql +31 -5
  45. data/db/schema.postgresql.sql +31 -6
  46. data/db/schema.rb +17 -7
  47. data/db/schema.sqlite.sql +31 -6
  48. data/db/schema.sqlserver.sql +32 -6
  49. data/db/schema_version +1 -1
  50. data/lang/de_DE.rb +493 -0
  51. data/lang/fr_FR.rb +28 -4
  52. data/lang/ro_RO.rb +554 -0
  53. data/lib/tasks/release.rake +7 -7
  54. data/lib/typo_version.rb +1 -1
  55. data/public/images/sitealizer/bar.gif +0 -0
  56. data/public/images/sitealizer/uv.png +0 -0
  57. data/public/images/sitealizer/vh.png +0 -0
  58. data/public/javascripts/tiny_mce/blank.htm +9 -0
  59. data/public/javascripts/tiny_mce/langs/en.js +41 -0
  60. data/public/javascripts/tiny_mce/license.txt +504 -0
  61. data/public/javascripts/tiny_mce/themes/advanced/about.htm +52 -0
  62. data/public/javascripts/tiny_mce/themes/advanced/anchor.htm +33 -0
  63. data/public/javascripts/tiny_mce/themes/advanced/charmap.htm +53 -0
  64. data/public/javascripts/tiny_mce/themes/advanced/color_picker.htm +13 -0
  65. data/public/javascripts/tiny_mce/themes/advanced/css/editor_content.css +58 -0
  66. data/public/javascripts/tiny_mce/themes/advanced/css/editor_popup.css +331 -0
  67. data/public/javascripts/tiny_mce/themes/advanced/css/editor_ui.css +97 -0
  68. data/public/javascripts/tiny_mce/themes/advanced/docs/en/about.htm +31 -0
  69. data/public/javascripts/tiny_mce/themes/advanced/docs/en/common_buttons.htm +162 -0
  70. data/public/javascripts/tiny_mce/themes/advanced/docs/en/create_accessible_content.htm +45 -0
  71. data/public/javascripts/tiny_mce/themes/advanced/docs/en/images/insert_anchor_window.gif +0 -0
  72. data/public/javascripts/tiny_mce/themes/advanced/docs/en/images/insert_image_window.gif +0 -0
  73. data/public/javascripts/tiny_mce/themes/advanced/docs/en/images/insert_link_window.gif +0 -0
  74. data/public/javascripts/tiny_mce/themes/advanced/docs/en/images/insert_table_window.gif +0 -0
  75. data/public/javascripts/tiny_mce/themes/advanced/docs/en/index.htm +27 -0
  76. data/public/javascripts/tiny_mce/themes/advanced/docs/en/insert_anchor_button.htm +32 -0
  77. data/public/javascripts/tiny_mce/themes/advanced/docs/en/insert_image_button.htm +65 -0
  78. data/public/javascripts/tiny_mce/themes/advanced/docs/en/insert_link_button.htm +33 -0
  79. data/public/javascripts/tiny_mce/themes/advanced/docs/en/insert_table_button.htm +71 -0
  80. data/public/javascripts/tiny_mce/themes/advanced/docs/en/style.css +28 -0
  81. data/public/javascripts/tiny_mce/themes/advanced/editor_template.js +1 -0
  82. data/public/javascripts/tiny_mce/themes/advanced/editor_template_src.js +1534 -0
  83. data/public/javascripts/tiny_mce/themes/advanced/image.htm +100 -0
  84. data/public/javascripts/tiny_mce/themes/advanced/images/anchor.gif +0 -0
  85. data/public/javascripts/tiny_mce/themes/advanced/images/anchor_symbol.gif +0 -0
  86. data/public/javascripts/tiny_mce/themes/advanced/images/backcolor.gif +0 -0
  87. data/public/javascripts/tiny_mce/themes/advanced/images/bold.gif +0 -0
  88. data/public/javascripts/tiny_mce/themes/advanced/images/bold_de_se.gif +0 -0
  89. data/public/javascripts/tiny_mce/themes/advanced/images/bold_es.gif +0 -0
  90. data/public/javascripts/tiny_mce/themes/advanced/images/bold_fr.gif +0 -0
  91. data/public/javascripts/tiny_mce/themes/advanced/images/bold_ru.gif +0 -0
  92. data/public/javascripts/tiny_mce/themes/advanced/images/bold_tw.gif +0 -0
  93. data/public/javascripts/tiny_mce/themes/advanced/images/browse.gif +0 -0
  94. data/public/javascripts/tiny_mce/themes/advanced/images/bullist.gif +0 -0
  95. data/public/javascripts/tiny_mce/themes/advanced/images/button_menu.gif +0 -0
  96. data/public/javascripts/tiny_mce/themes/advanced/images/buttons.gif +0 -0
  97. data/public/javascripts/tiny_mce/themes/advanced/images/cancel_button_bg.gif +0 -0
  98. data/public/javascripts/tiny_mce/themes/advanced/images/charmap.gif +0 -0
  99. data/public/javascripts/tiny_mce/themes/advanced/images/cleanup.gif +0 -0
  100. data/public/javascripts/tiny_mce/themes/advanced/images/close.gif +0 -0
  101. data/public/javascripts/tiny_mce/themes/advanced/images/code.gif +0 -0
  102. data/public/javascripts/tiny_mce/themes/advanced/images/color.gif +0 -0
  103. data/public/javascripts/tiny_mce/themes/advanced/images/copy.gif +0 -0
  104. data/public/javascripts/tiny_mce/themes/advanced/images/custom_1.gif +0 -0
  105. data/public/javascripts/tiny_mce/themes/advanced/images/cut.gif +0 -0
  106. data/public/javascripts/tiny_mce/themes/advanced/images/forecolor.gif +0 -0
  107. data/public/javascripts/tiny_mce/themes/advanced/images/help.gif +0 -0
  108. data/public/javascripts/tiny_mce/themes/advanced/images/hr.gif +0 -0
  109. data/public/javascripts/tiny_mce/themes/advanced/images/image.gif +0 -0
  110. data/public/javascripts/tiny_mce/themes/advanced/images/indent.gif +0 -0
  111. data/public/javascripts/tiny_mce/themes/advanced/images/insert_button_bg.gif +0 -0
  112. data/public/javascripts/tiny_mce/themes/advanced/images/italic.gif +0 -0
  113. data/public/javascripts/tiny_mce/themes/advanced/images/italic_de_se.gif +0 -0
  114. data/public/javascripts/tiny_mce/themes/advanced/images/italic_es.gif +0 -0
  115. data/public/javascripts/tiny_mce/themes/advanced/images/italic_ru.gif +0 -0
  116. data/public/javascripts/tiny_mce/themes/advanced/images/italic_tw.gif +0 -0
  117. data/public/javascripts/tiny_mce/themes/advanced/images/justifycenter.gif +0 -0
  118. data/public/javascripts/tiny_mce/themes/advanced/images/justifyfull.gif +0 -0
  119. data/public/javascripts/tiny_mce/themes/advanced/images/justifyleft.gif +0 -0
  120. data/public/javascripts/tiny_mce/themes/advanced/images/justifyright.gif +0 -0
  121. data/public/javascripts/tiny_mce/themes/advanced/images/link.gif +0 -0
  122. data/public/javascripts/tiny_mce/themes/advanced/images/menu_check.gif +0 -0
  123. data/public/javascripts/tiny_mce/themes/advanced/images/newdocument.gif +0 -0
  124. data/public/javascripts/tiny_mce/themes/advanced/images/numlist.gif +0 -0
  125. data/public/javascripts/tiny_mce/themes/advanced/images/opacity.png +0 -0
  126. data/public/javascripts/tiny_mce/themes/advanced/images/outdent.gif +0 -0
  127. data/public/javascripts/tiny_mce/themes/advanced/images/paste.gif +0 -0
  128. data/public/javascripts/tiny_mce/themes/advanced/images/redo.gif +0 -0
  129. data/public/javascripts/tiny_mce/themes/advanced/images/removeformat.gif +0 -0
  130. data/public/javascripts/tiny_mce/themes/advanced/images/separator.gif +0 -0
  131. data/public/javascripts/tiny_mce/themes/advanced/images/spacer.gif +0 -0
  132. data/public/javascripts/tiny_mce/themes/advanced/images/statusbar_resize.gif +0 -0
  133. data/public/javascripts/tiny_mce/themes/advanced/images/strikethrough.gif +0 -0
  134. data/public/javascripts/tiny_mce/themes/advanced/images/sub.gif +0 -0
  135. data/public/javascripts/tiny_mce/themes/advanced/images/sup.gif +0 -0
  136. data/public/javascripts/tiny_mce/themes/advanced/images/underline.gif +0 -0
  137. data/public/javascripts/tiny_mce/themes/advanced/images/underline_es.gif +0 -0
  138. data/public/javascripts/tiny_mce/themes/advanced/images/underline_fr.gif +0 -0
  139. data/public/javascripts/tiny_mce/themes/advanced/images/underline_ru.gif +0 -0
  140. data/public/javascripts/tiny_mce/themes/advanced/images/underline_tw.gif +0 -0
  141. data/public/javascripts/tiny_mce/themes/advanced/images/undo.gif +0 -0
  142. data/public/javascripts/tiny_mce/themes/advanced/images/unlink.gif +0 -0
  143. data/public/javascripts/tiny_mce/themes/advanced/images/visualaid.gif +0 -0
  144. data/public/javascripts/tiny_mce/themes/advanced/images/xp/tab_bg.gif +0 -0
  145. data/public/javascripts/tiny_mce/themes/advanced/images/xp/tab_end.gif +0 -0
  146. data/public/javascripts/tiny_mce/themes/advanced/images/xp/tab_sel_bg.gif +0 -0
  147. data/public/javascripts/tiny_mce/themes/advanced/images/xp/tab_sel_end.gif +0 -0
  148. data/public/javascripts/tiny_mce/themes/advanced/images/xp/tabs_bg.gif +0 -0
  149. data/public/javascripts/tiny_mce/themes/advanced/jscripts/about.js +75 -0
  150. data/public/javascripts/tiny_mce/themes/advanced/jscripts/anchor.js +74 -0
  151. data/public/javascripts/tiny_mce/themes/advanced/jscripts/charmap.js +326 -0
  152. data/public/javascripts/tiny_mce/themes/advanced/jscripts/color_picker.js +108 -0
  153. data/public/javascripts/tiny_mce/themes/advanced/jscripts/image.js +81 -0
  154. data/public/javascripts/tiny_mce/themes/advanced/jscripts/link.js +70 -0
  155. data/public/javascripts/tiny_mce/themes/advanced/jscripts/source_editor.js +60 -0
  156. data/public/javascripts/tiny_mce/themes/advanced/langs/en.js +82 -0
  157. data/public/javascripts/tiny_mce/themes/advanced/link.htm +100 -0
  158. data/public/javascripts/tiny_mce/themes/advanced/source_editor.htm +32 -0
  159. data/public/javascripts/tiny_mce/tiny_mce.js +1 -0
  160. data/public/javascripts/tiny_mce/tiny_mce_popup.js +288 -0
  161. data/public/javascripts/tiny_mce/tiny_mce_src.js +7284 -0
  162. data/public/javascripts/tiny_mce/utils/editable_selects.js +61 -0
  163. data/public/javascripts/tiny_mce/utils/form_utils.js +210 -0
  164. data/public/javascripts/tiny_mce/utils/mclayer.js +210 -0
  165. data/public/javascripts/tiny_mce/utils/mctabs.js +74 -0
  166. data/public/javascripts/tiny_mce/utils/validate.js +219 -0
  167. data/public/stylesheets/administration.css +5 -1
  168. data/public/stylesheets/minimal.css +1 -0
  169. data/test/functional/admin/categories_controller_test.rb +2 -2
  170. data/test/functional/xml_controller_test.rb +72 -40
  171. data/test/test_helper.rb +1 -17
  172. data/test/unit/article_test.rb +1 -1
  173. data/test/unit/trigger_test.rb +1 -1
  174. data/themes/scribbish/views/articles/_comment.rhtml +13 -17
  175. data/themes/scribbish/views/articles/_comment_form.rhtml +7 -5
  176. data/themes/scribbish/views/articles/_comment_list.rhtml +7 -0
  177. data/themes/scribbish/views/articles/read.rhtml +1 -1
  178. data/vendor/plugins/aimpresence_sidebar/views/content.rhtml +1 -1
  179. data/vendor/plugins/archives_sidebar/views/content.rhtml +1 -1
  180. data/vendor/plugins/audioscrobbler_sidebar/MAINTAINERS +26 -0
  181. data/vendor/plugins/audioscrobbler_sidebar/MIT-LICENSE +21 -0
  182. data/vendor/plugins/audioscrobbler_sidebar/README +27 -0
  183. data/vendor/plugins/backpack_sidebar/MAINTAINERS +26 -0
  184. data/vendor/plugins/backpack_sidebar/MIT-LICENSE +21 -0
  185. data/vendor/plugins/backpack_sidebar/README +27 -0
  186. data/vendor/plugins/category_sidebar/views/content.rhtml +1 -1
  187. data/vendor/plugins/sitealizer/CHANGELOG +6 -0
  188. data/vendor/plugins/sitealizer/LICENSE +22 -0
  189. data/vendor/plugins/sitealizer/README +82 -0
  190. data/vendor/plugins/sitealizer/Rakefile +22 -0
  191. data/vendor/plugins/sitealizer/init.rb +24 -0
  192. data/vendor/plugins/sitealizer/install.rb +22 -0
  193. data/vendor/plugins/sitealizer/lib/app/assets/images/bar.gif +0 -0
  194. data/vendor/plugins/sitealizer/lib/app/assets/images/uv.png +0 -0
  195. data/vendor/plugins/sitealizer/lib/app/assets/images/vh.png +0 -0
  196. data/vendor/plugins/sitealizer/lib/app/controllers/sitealizer_controller.rb +118 -0
  197. data/vendor/plugins/sitealizer/lib/app/models/site_tracker.rb +145 -0
  198. data/vendor/plugins/sitealizer/lib/app/views/layouts/sitealizer.rhtml +66 -0
  199. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/_browsers.rhtml +23 -0
  200. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/_daily_stats.rhtml +67 -0
  201. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/_hits_summary.rhtml +0 -0
  202. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/_hosts.rhtml +21 -0
  203. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/_keywords.rhtml +19 -0
  204. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/_languages.rhtml +21 -0
  205. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/_main_frame.rhtml +84 -0
  206. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/_monthly_hits.rhtml +67 -0
  207. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/_page_urls.rhtml +20 -0
  208. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/_platforms.rhtml +21 -0
  209. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/_referers.rhtml +22 -0
  210. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/_robots.rhtml +19 -0
  211. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/_search_engines.rhtml +19 -0
  212. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/hourly_stats.rhtml +39 -0
  213. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/index.rhtml +8 -0
  214. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/login.rhtml +20 -0
  215. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/menu.rhtml +74 -0
  216. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/referrer_stats.rhtml +20 -0
  217. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/search_stats.rhtml +25 -0
  218. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/summary.rhtml +22 -0
  219. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/visitor_info.rhtml +30 -0
  220. data/vendor/plugins/sitealizer/lib/config.yml +18 -0
  221. data/vendor/plugins/sitealizer/lib/sitealizer/parser.rb +347 -0
  222. data/vendor/plugins/sitealizer/lib/sitealizer.rb +78 -0
  223. data/vendor/plugins/sitealizer/lib/tasks/sitealizer.rake +36 -0
  224. data/vendor/plugins/sitealizer/test/fixtures/sitealizer.yml +89 -0
  225. data/vendor/plugins/sitealizer/test/sitealizer_controller_test.rb +208 -0
  226. data/vendor/plugins/sitealizer/test/sitealizer_parser_test.rb +169 -0
  227. data/vendor/plugins/sitealizer/test/test_helper.rb +7 -0
  228. data/vendor/plugins/tada_sidebar/MAINTAINERS +26 -0
  229. data/vendor/plugins/tada_sidebar/MIT-LICENSE +21 -0
  230. data/vendor/plugins/tada_sidebar/README +27 -0
  231. data/vendor/plugins/tag_sidebar/views/content.rhtml +1 -1
  232. data/vendor/plugins/tiny_mce/README +10 -0
  233. data/vendor/plugins/tiny_mce/Rakefile +22 -0
  234. data/vendor/plugins/tiny_mce/TODO +2 -0
  235. data/vendor/plugins/tiny_mce/changelog +1017 -0
  236. data/vendor/plugins/tiny_mce/init.rb +3 -0
  237. data/vendor/plugins/tiny_mce/install.rb +1 -0
  238. data/vendor/plugins/tiny_mce/lib/tiny_mce.rb +36 -0
  239. data/vendor/plugins/tiny_mce/lib/tiny_mce_helper.rb +48 -0
  240. data/vendor/plugins/tiny_mce/tasks/tiny_mce.rake +40 -0
  241. data/vendor/plugins/tiny_mce/test/helper_testcase.rb +38 -0
  242. data/vendor/plugins/tiny_mce/test/tiny_mce_helper_test.rb +67 -0
  243. data/vendor/plugins/tiny_mce/test/tiny_mce_test.rb +85 -0
  244. data/vendor/plugins/tiny_mce/tiny_mce_options.yml +121 -0
  245. data/vendor/plugins/xbox_sidebar/MAINTAINERS +26 -0
  246. data/vendor/plugins/xbox_sidebar/MIT-LICENSE +21 -0
  247. data/vendor/plugins/xbox_sidebar/README +27 -0
  248. data/vendor/plugins/xml_sidebar/lib/xml_sidebar.rb +1 -1
  249. data/vendor/plugins/xml_sidebar/views/content.rhtml +4 -4
  250. metadata +220 -4
  251. data/TODO-4.1 +0 -16
@@ -0,0 +1,25 @@
1
+ <div style="margin-top:12px">
2
+ <table align=center width=95% cellpadding=0>
3
+ </tr>
4
+ <td>
5
+ <div id='border'>
6
+ <div id='title'>Search Statistics</div>
7
+ <p>
8
+ <div id='sub_title'>Robots/Crawlers</div>
9
+ <div><%=render :partial => 'robots'%></div>
10
+ </p>
11
+ <br>
12
+ <p>
13
+ <div id='sub_title'>Top Domains</div>
14
+ <div><%=render :partial => 'search_engines'%></div>
15
+ </p>
16
+ <br>
17
+ <p>
18
+ <div id='sub_title'>Search Strings - Top 30</div>
19
+ <div><%=render :partial => 'keywords'%></div>
20
+ </p>
21
+ </div>
22
+ </td>
23
+ </tr>
24
+ </table>
25
+ </div>
@@ -0,0 +1,22 @@
1
+ <div style="margin-top:12px">
2
+ <table align=center width=95% cellpadding=0>
3
+ </tr>
4
+ <td>
5
+ <div id='border'>
6
+ <div id='title'>Summary - <%="#{@year}-#{@month}-1".to_time.strftime('%B %Y')%></div>
7
+ <p>Last Update: <%=@last_update%></p>
8
+ <p>
9
+ <div id='sub_title'>Monthly Hits</div>
10
+ <div><%=render :partial => 'monthly_hits'%></div>
11
+ </p>
12
+ <br>
13
+ <p>
14
+ <div id='sub_title'>Daily Hits</div>
15
+ <div><%=render :partial => 'daily_stats'%></div>
16
+ </p>
17
+ <br>
18
+ </div>
19
+ </td>
20
+ </tr>
21
+ </table>
22
+ </div>
@@ -0,0 +1,30 @@
1
+ <div style="margin-top:12px">
2
+ <table align=center width=95% cellpadding=0>
3
+ </tr>
4
+ <td>
5
+ <div id='border'>
6
+ <div id='title'>Visitor Information</div>
7
+ <p>
8
+ <div id='sub_title'>Hosts - Top 30</div>
9
+ <div><%=render :partial => 'hosts'%></div>
10
+ </p>
11
+ <br>
12
+ <p>
13
+ <div id='sub_title'>Operating Systems</div>
14
+ <div><%=render :partial => 'platforms'%></div>
15
+ </p>
16
+ <br>
17
+ <p>
18
+ <div id='sub_title'>Browsers</div>
19
+ <div><%=render :partial => 'browsers'%></div>
20
+ </p>
21
+ <br>
22
+ <p>
23
+ <div id='sub_title'>Languages - Top 15</div>
24
+ <div><%=render :partial => 'languages'%></div>
25
+ </p>
26
+ </div>
27
+ </td>
28
+ </tr>
29
+ </table>
30
+ </div>
@@ -0,0 +1,18 @@
1
+ # Sitealizer config
2
+ #
3
+ # This is the only configuration you need to change if you don't want to
4
+ # leave it with the default config values.
5
+ #
6
+ # Access types:
7
+ # - private: You have to enter the username and password below in order to view the stats
8
+ # - public: Anyone can view your site's stats
9
+ #
10
+ # Queue size:
11
+ # - The number of visitors in the queue before saving the stats to the DB.
12
+ # Minimum size shouldn't be under 5
13
+ #
14
+ sitealizer:
15
+ access_type: private
16
+ username: admin
17
+ password: admin
18
+ queue_size: 15
@@ -0,0 +1,347 @@
1
+ # Copyright (c) 2007 Thiago Jackiw
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # The "Created with Sitealizer" footer text should not be removed from the
14
+ # locations where it's currently shown (under the '/sitealizer' controller)
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ # SOFTWARE.
23
+
24
+ require 'uri'
25
+
26
+ module Sitealizer
27
+
28
+ # The Parser module is used only when processing the stats and
29
+ # not when saving the user info, this way it won't influence
30
+ # on your site's performance
31
+ #
32
+ module Parser
33
+
34
+ class UserAgent
35
+
36
+ # Process the user agent string and returns
37
+ # the users's platform:
38
+ #
39
+ # Sitealizer::Parser::UserAgent.get_platform("(Macintosh; U; PPC Mac OS X; en)")
40
+ # => "Macintosh"
41
+ #
42
+ def self.get_platform(user_agent)
43
+ platform = nil
44
+ if user_agent =~ /Win/i
45
+ platform = "Windows"
46
+ elsif user_agent =~ /Mac/i
47
+ platform = "Macintosh"
48
+ elsif user_agent =~ /Linux/i
49
+ platform = "Linux";
50
+ elsif user_agent =~ /SunOS/i
51
+ platform = "Sun Solaris";
52
+ elsif user_agent =~ /BSD/i
53
+ platform = "FreeBSD";
54
+ else
55
+ platform = "Other"
56
+ end
57
+ return platform
58
+ end
59
+
60
+ # Process the user agent string and returns
61
+ # the user's browser info as a hash:
62
+ #
63
+ # user_agent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; nl; rv:1.8) Gecko/20051107 Firefox/1.5"
64
+ # Sitealizer::Parser::UserAgent.browser_info(user_agent)
65
+ # => {:type => 'Firefox', :version => '1.5'}
66
+ #
67
+ def self.browser_info(user_agent)
68
+ browser = {
69
+ :type => nil,
70
+ :version => nil
71
+ }
72
+ #Internet Exlorer
73
+ if user_agent =~ /MSIE/i && user_agent.scan(/AOL|America Online Browser/i).empty?
74
+ browser[:type] = "MSIE";
75
+ browser[:version] = user_agent.scan(/MSIE ([\d\.]+)/i).to_s
76
+ #Firefox/Firebird/Phoenix
77
+ elsif user_agent =~ /Firefox|Firebird|Phoenix/i
78
+ browser[:type] = "Firefox";
79
+ browser[:version] = user_agent.scan(/[Firefox|Firebird|Phoenix].\/(\d.+)/i).to_s
80
+ #Galeon
81
+ elsif user_agent =~ /Galeon/i
82
+ browser[:type] = "Galeon";
83
+ browser[:version] = user_agent.scan(/Galeon\/([\d\.]+)/i).to_s
84
+ #Safari
85
+ elsif user_agent =~ /Safari/i
86
+ browser[:type] = "Safari";
87
+ browser[:version] = nil
88
+ #Opera
89
+ elsif user_agent =~ /Opera/i
90
+ browser[:type] = "Opera";
91
+ browser[:version] = user_agent.scan(/Opera[ |\/]([\d\.]+)/i).to_s
92
+ #AOL/America Online Browser
93
+ elsif user_agent =~ /AOL|America Online Browser/i
94
+ browser[:type] = "AOL"
95
+ browser[:version] = if user_agent =~ /AOL/i
96
+ user_agent.scan(/AOL[ |\/]([\d.]+)/i).uniq.to_s
97
+ else
98
+ user_agent.scan(/America Online Browser ([\d\.]+)/i).to_s
99
+ end
100
+ #Camino
101
+ elsif user_agent =~ /Camino/i
102
+ browser[:type] = "Camino";
103
+ browser[:version] = user_agent.scan(/Camino\/([\d\.]+)/i).to_s
104
+ #Konqueror
105
+ elsif user_agent =~ /Konqueror/i
106
+ browser[:type] = "Konqueror";
107
+ browser[:version] = user_agent.scan(/Konqueror\/([\d.]+)/i).to_s
108
+ #K-Meleon
109
+ elsif user_agent =~ /K-Meleon/i
110
+ browser[:type] = "K-Meleon";
111
+ browser[:version] = user_agent.scan(/K-Meleon\/([\d.]+)/i).to_s
112
+ #Firefox BonEcho
113
+ elsif user_agent =~ /BonEcho/i
114
+ browser[:type] = "Firefox BonEcho";
115
+ browser[:version] = user_agent.scan(/BonEcho\/([\d.]+)/i).to_s
116
+ #Netscape
117
+ elsif user_agent =~ /Netscape/i
118
+ browser[:type] = "Netscape";
119
+ browser[:version] = user_agent.scan(/Netscape\/([\d.]+)/i).to_s
120
+ #PSP
121
+ elsif user_agent =~ /PlayStation Portable/i
122
+ browser[:type] = "PlayStation Portable (PSP)";
123
+ browser[:version] = user_agent.scan(/PlayStation Portable\); ([\d\.]+)/i).to_s
124
+ #PlayStation 3
125
+ elsif user_agent =~ /PlayStation 3/i
126
+ browser[:type] = "PlayStation 3";
127
+ browser[:version] = user_agent.scan(/PlayStation 3; ([\d\.]+)/i).to_s
128
+ #Lynx
129
+ elsif user_agent =~ /Lynx/i
130
+ browser[:type] = "Lynx";
131
+ browser[:version] = user_agent.scan(/Lynx\/([\d\.]+)/i).to_s
132
+ else
133
+ browser[:type] = "Other";
134
+ browser[:version] = nil
135
+ end
136
+ return browser
137
+ end
138
+ end
139
+
140
+ class Keyword
141
+
142
+ # Process the referrers and returns
143
+ # the search terms if they're available:
144
+ #
145
+ # referer = "http://search.msn.com/results.aspx?srch=105&FORM=AS5&q=sitealizer"
146
+ # Sitealizer::Parser::Keyword.get_terms(referer)
147
+ # => 'sitealizer'
148
+ #
149
+ def self.get_terms(string)
150
+ return if string.nil?
151
+ begin
152
+ search_string = nil
153
+ domain = URI::split(string)[2]
154
+ if domain =~ /[google|alltheweb|search\.msn|ask|altavista|]\./ && string =~ /[?|&]q=/i
155
+ search_string = CGI.unescape(string.scan(/[?|&]q=([^&]*)/).flatten.to_s)
156
+ elsif domain =~ /yahoo\./i && string =~ /[?|&]p=/i
157
+ search_string = CGI.unescape(string.scan(/[?|&]p=([^&]*)/).flatten.to_s)
158
+ elsif domain =~ /search\.aol\./i && string =~ /[?|&]query=/i
159
+ search_string = CGI.unescape(string.scan(/[?|&]query=([^&]*)/).flatten.to_s)
160
+ end
161
+ return search_string
162
+ rescue
163
+ return nil
164
+ end
165
+ end
166
+
167
+ # Process the referrers and returns the referer domain.
168
+ # <em>Host</em> is your site's url (request.host) but
169
+ # you don't have to worry about this, it's all handled
170
+ # by the sitealizer controller
171
+ #
172
+ # referer = "http://search.msn.com/results.aspx?srch=105&FORM=AS5&q=sitealizer"
173
+ # Sitealizer::Parser::Keyword.get_domain(referer, 'localhost')
174
+ # => "search.msn.com"
175
+ #
176
+ def self.get_domain(string, host)
177
+ return if string.nil?
178
+ domain = nil
179
+ domain = URI::split(string)[2]
180
+ return domain != host ? domain : nil
181
+ end
182
+ end
183
+
184
+ class Robot
185
+
186
+ # Process the robots (when available) found on the
187
+ # user agent strings and returns its name:
188
+ #
189
+ # user_agent = "Googlebot/2.X (+http://www.googlebot.com/bot.html)"
190
+ # Sitealizer::Parser::Robot.get_name(user_agent)
191
+ # => "Googlebot"
192
+ #
193
+ def self.get_name(agent)
194
+ robot = nil
195
+ if agent =~ /Atomz/i
196
+ robot = 'Atomz.com'
197
+ elsif agent =~ /Googlebot/i
198
+ robot = 'Googlebot'
199
+ elsif agent =~ /InfoSeek/i
200
+ robot = 'InfoSeek'
201
+ elsif agent =~ /Ask Jeeves/i
202
+ robot = 'Ask Jeeves'
203
+ elsif agent =~ /Lycos/i
204
+ robot = 'Lycos'
205
+ elsif agent =~ /MSNBOT/i
206
+ robot = 'MSNBot'
207
+ elsif agent =~ /Slurp/i && agent.scan(/Yahoo/i).empty?
208
+ robot = 'Inktomi'
209
+ elsif agent =~ /Yahoo/i
210
+ robot = 'Yahoo Slurp'
211
+ end
212
+ return robot
213
+ end
214
+ end
215
+
216
+ class Language
217
+
218
+ # Process the user language and returns the
219
+ # 'human readable' format if found, otherwise
220
+ # its raw code gets returned:
221
+ #
222
+ # Sitealizer::Parser::Language.get_name('en-us')
223
+ # => "English/United States"
224
+ #
225
+ def self.get_name(lang)
226
+ lang = lang.scan(/([^,;].*)/).to_s
227
+ lang = lang.slice(0,5)
228
+ languages = {"af" => "Afrikaans",
229
+ "sq" => "Albanian",
230
+ "eu" => "Basque",
231
+ "bg" => "Bulgarian",
232
+ "be" => "Byelorussian",
233
+ "ca" => "Catalan",
234
+ "zh" => "Chinese",
235
+ "zh-cn" => "Chinese/China",
236
+ "zh-tw" => "Chinese/Taiwan",
237
+ "zh-hk" => "Chinese/Hong Kong",
238
+ "zh-sg" => "Chinese/singapore",
239
+ "hr" => "Croatian",
240
+ "cs" => "Czech",
241
+ "da" => "Danish",
242
+ "nl" => "Dutch",
243
+ "nl-nl" => "Dutch/Netherlands",
244
+ "nl-be" => "Dutch/Belgium",
245
+ "en" => "English",
246
+ "en-gb" => "English/United Kingdom",
247
+ "en-us" => "English/United States",
248
+ "en-au" => "English/Australian",
249
+ "en-ca" => "English/Canada",
250
+ "en-nz" => "English/New Zealand",
251
+ "en-ie" => "English/Ireland",
252
+ "en-za" => "English/South Africa",
253
+ "en-jm" => "English/Jamaica",
254
+ "en-bz" => "English/Belize",
255
+ "en-tt" => "English/Trinidad",
256
+ "et" => "Estonian",
257
+ "fo" => "Faeroese",
258
+ "fa" => "Farsi",
259
+ "fi" => "Finnish",
260
+ "fr" => "French",
261
+ "fr-be" => "French/Belgium",
262
+ "fr-fr" => "French/France",
263
+ "fr,fr" => "French/France",
264
+ "fr-ch" => "French/Switzerland",
265
+ "fr-ca" => "French/Canada",
266
+ "fr-lu" => "French/Luxembourg",
267
+ "gd" => "Gaelic",
268
+ "gl" => "Galician",
269
+ "de" => "German",
270
+ "de-at" => "German/Austria",
271
+ "de-de" => "German/Germany",
272
+ "de-ch" => "German/Switzerland",
273
+ "de-lu" => "German/Luxembourg",
274
+ "de-li" => "German/Liechtenstein",
275
+ "el" => "Greek",
276
+ "he" => "Hebrew",
277
+ "he-il" => "Hebrew/Israel",
278
+ "hi" => "Hindi",
279
+ "hu" => "Hungarian",
280
+ "ie-ee" => "Internet Explorer/Easter Egg",
281
+ "is" => "Icelandic",
282
+ "id" => "Indonesian",
283
+ "in" => "Indonesian",
284
+ "ga" => "Irish",
285
+ "it" => "Italian",
286
+ "it-ch" => "Italian/ Switzerland",
287
+ "ja" => "Japanese",
288
+ "ko" => "Korean",
289
+ "lv" => "Latvian",
290
+ "lt" => "Lithuanian",
291
+ "mk" => "Macedonian",
292
+ "ms" => "Malaysian",
293
+ "mt" => "Maltese",
294
+ "no" => "Norwegian",
295
+ "pl" => "Polish",
296
+ "pt-pt" => "Portuguese",
297
+ "pt-br" => "Portuguese/Brazil",
298
+ "rm" => "Rhaeto-Romanic",
299
+ "ro" => "Romanian",
300
+ "ro-mo" => "Romanian/Moldavia",
301
+ "ru-ru" => "Russian",
302
+ "ru-mo" => "Russian /Moldavia",
303
+ "gd" => "Scots Gaelic",
304
+ "sr" => "Serbian",
305
+ "sk" => "Slovack",
306
+ "sl" => "Slovenian",
307
+ "sb" => "Sorbian",
308
+ "es" => "Spanish",
309
+ "es-do" => "Spanish",
310
+ "es-ar" => "Spanish/Argentina",
311
+ "es-co" => "Spanish/Colombia",
312
+ "es-mx" => "Spanish/Mexico",
313
+ "es-es" => "Spanish/Spain",
314
+ "es-gt" => "Spanish/Guatemala",
315
+ "es-cr" => "Spanish/Costa Rica",
316
+ "es-pa" => "Spanish/Panama",
317
+ "es-ve" => "Spanish/Venezuela",
318
+ "es-pe" => "Spanish/Peru",
319
+ "es-ec" => "Spanish/Ecuador",
320
+ "es-cl" => "Spanish/Chile",
321
+ "es-uy" => "Spanish/Uruguay",
322
+ "es-py" => "Spanish/Paraguay",
323
+ "es-bo" => "Spanish/Bolivia",
324
+ "es-sv" => "Spanish/El salvador",
325
+ "es-hn" => "Spanish/Honduras",
326
+ "es-ni" => "Spanish/Nicaragua",
327
+ "es-pr" => "Spanish/Puerto Rico",
328
+ "sx" => "Sutu",
329
+ "sv" => "Swedish",
330
+ "sv-se" => "Swedish/Sweden",
331
+ "sv-fi" => "Swedish/Finland",
332
+ "ts" => "Thai",
333
+ "tn" => "Tswana",
334
+ "tr" => "Turkish",
335
+ "uk" => "Ukrainian",
336
+ "ur" => "Urdu",
337
+ "vi" => "Vietnamese",
338
+ "xh" => "Xshosa",
339
+ "ji" => "Yiddish",
340
+ "zu" => "Zulu"}
341
+ return languages.fetch(lang, lang)
342
+ end
343
+ end
344
+
345
+ end
346
+
347
+ end
@@ -0,0 +1,78 @@
1
+ # Copyright (c) 2007 Thiago Jackiw
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # The "Created with Sitealizer" footer text should not be removed from the
14
+ # locations where it's currently shown (under the '/sitealizer' controller)
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ # SOFTWARE.
23
+
24
+ require 'yaml'
25
+
26
+ require 'app/models/site_tracker'
27
+ require 'app/controllers/sitealizer_controller'
28
+ require 'sitealizer/parser'
29
+
30
+ SA_CONFIG = YAML::load_file(File.dirname(__FILE__)+'/config.yml') unless defined?(SA_CONFIG)
31
+
32
+ module Sitealizer
33
+
34
+ def initialize #:nodoc:
35
+ $visits = [] unless $visits
36
+ end
37
+
38
+ # This is the before_filter method that you will call when
39
+ # using the Sitealizer Web Stats plugin
40
+ #
41
+ # class ApplicationController < ActionController::Base
42
+ # include Sitealizer
43
+ # before_filter :use_sitealizer
44
+ # end
45
+ #
46
+ def use_sitealizer
47
+ $visits << request.env
48
+ if $visits.size == SA_CONFIG['sitealizer']['queue_size']
49
+ thread = Thread.start{store_visits}
50
+ thread.join
51
+ $visits = []
52
+ end
53
+ end
54
+
55
+ private
56
+ def store_visits
57
+ begin
58
+ mutex = Mutex.new
59
+ mutex.lock
60
+ $visits.each do |env|
61
+ SiteTracker.create(
62
+ :user_agent => env['HTTP_USER_AGENT'],
63
+ :language => env['HTTP_ACCEPT_LANGUAGE'],
64
+ :path => env['PATH_INFO'],
65
+ :ip => env['REMOTE_ADDR'],
66
+ :referer => env['HTTP_REFERER']
67
+ )
68
+ end
69
+ open(File.dirname(__FILE__)+'/last_update','w'){|f| f.puts Time.now.to_s}
70
+ mutex.unlock
71
+ rescue => e
72
+ RAILS_ENV == 'production' ? logger.info(e) : logger.debug(e)
73
+ ensure
74
+ mutex.unlock
75
+ end
76
+ end
77
+
78
+ end
@@ -0,0 +1,36 @@
1
+ namespace :sitealizer do
2
+ desc "Removes the old 'sitemeter' and import the stored stats to Sitealizer"
3
+ task :remove_sitemeter => :environment do
4
+ ActiveRecord::Schema.drop_table('sitealizer') if SiteTracker.count == 0
5
+ if ActiveRecord::Schema.tables.include?('sitemeter') && !ActiveRecord::Schema.tables.include?('sitealizer')
6
+ ActiveRecord::Schema.rename_table('sitemeter','sitealizer')
7
+ puts "Sitealizer => Completed renaming table from 'sitemeter' to 'sitealizer'"
8
+ end
9
+ ['/public/images/sitemeter','/vendor/plugins/sitemeter'].each do |path|
10
+ if File.exists?(RAILS_ROOT + path)
11
+ FileUtils.rm_rf(RAILS_ROOT + path)
12
+ puts "Sitealizer => Completed removing 'sitemeter' files from " + path
13
+ end
14
+ end
15
+ end
16
+
17
+ desc "Updates Sitealizer to the latest version"
18
+ task :update do
19
+ $verbose = false
20
+ `svn --version` rescue nil
21
+ unless !$?.nil? && $?.success?
22
+ $stderr.puts "ERROR: Must have subversion (svn) available in the PATH to update your Sitealizer plugin"
23
+ exit 1
24
+ end
25
+ FileUtils.rm_rf(RAILS_ROOT+"vendor/plugins/sitealizer")
26
+ system("svn export http://opensvn.csie.org/sitealizer vendor/plugins/sitealizer")
27
+ system("ruby vendor/plugins/sitealizer/install.rb")
28
+ end
29
+
30
+ desc "Removes the Sitealizer plugin"
31
+ task :uninstall => :environment do
32
+ ActiveRecord::Schema.drop_table('sitealizer') if ActiveRecord::Schema.tables.include?('sitealizer')
33
+ FileUtils.rm_rf(RAILS_ROOT+'/vendor/plugins/sitemeter') if File.exists?(RAILS_ROOT+'/vendor/plugins/sitemeter')
34
+ puts "Sitealizer => plugin uninstalled\n\n"
35
+ end
36
+ end
@@ -0,0 +1,89 @@
1
+ one:
2
+ id: 1
3
+ path: /account
4
+ ip: 123.4.5.678
5
+ referer: <%=nil%>
6
+ language: en
7
+ user_agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/418.9.1 (KHTML, like Gecko) Safari/419.3
8
+ created_at: 2007-03-01 00:08:47
9
+ created_on: 2007-03-01
10
+
11
+ two:
12
+ id: 2
13
+ path: /
14
+ ip: 41.41.41.41
15
+ referer: http://search.yahoo.com/search?p=sitealizer&fr=yfp-t-501&toggle=1&cop=mss&ei=UTF-8
16
+ language: en
17
+ user_agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.4) Gecko/20030624 Netscape/7.1 (ax)
18
+ created_at: 2007-03-01 00:38:47
19
+ created_on: 2007-03-01
20
+
21
+ three:
22
+ id: 3
23
+ path: /account
24
+ ip: 41.41.41.41
25
+ referer: /
26
+ language: en
27
+ user_agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.4) Gecko/20030624 Netscape/7.1 (ax)
28
+ created_at: 2007-03-01 00:39:15
29
+ created_on: 2007-03-01
30
+
31
+ four:
32
+ id: 4
33
+ path: /
34
+ ip: 31.31.31.31
35
+ referer: http://www.altavista.com/web/results?itag=ody&q=sitealizer+rails+plugin&kgs=1&kls=0
36
+ language: fr-fr
37
+ user_agent: Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 6.0)
38
+ created_at: 2007-03-02 00:05:47
39
+ created_on: 2007-03-02
40
+
41
+ five:
42
+ id: 5
43
+ path: /
44
+ ip: 51.51.51.51
45
+ referer: http://search.aol.com/aolcom/search?invocationType=topsearchbox.search&query=sitealizer
46
+ language: pt-pt
47
+ user_agent: Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 6.0)
48
+ created_at: <%=20.hours.ago.to_s(:db)%>
49
+ created_on: <%=20.hours.ago.to_s(:db)%>
50
+
51
+ six:
52
+ id: 6
53
+ path: /
54
+ ip: 3.3.3.3
55
+ referer: http://search.aol.com/aolcom/search?invocationType=topsearchbox.search&query=sitealizer
56
+ language: en
57
+ user_agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.4) Gecko/20030624 Netscape/7.1 (ax)
58
+ created_at: <%=16.hours.ago.to_s(:db)%>
59
+ created_on: <%=16.hours.ago.to_s(:db)%>
60
+
61
+ msnbot:
62
+ id: 7
63
+ path: /
64
+ ip: 2.2.2.2
65
+ referer: <%=nil%>
66
+ language: <%=nil%>
67
+ user_agent: MSNBOT/0.1 (http://search.msn.com/msnbot.htm)
68
+ created_at: <%=15.hours.ago.to_s(:db)%>
69
+ created_on: <%=15.hours.ago.to_s(:db)%>
70
+
71
+ googlebot:
72
+ id: 8
73
+ path: /
74
+ ip: 1.1.1.1
75
+ referer: <%=nil%>
76
+ language: <%=nil%>
77
+ user_agent: Googlebot/2.X (+http://www.googlebot.com/bot.html)
78
+ created_at: <%=12.hours.ago.to_s(:db)%>
79
+ created_on: <%=12.hours.ago.to_s(:db)%>
80
+
81
+ googlebot2:
82
+ id: 9
83
+ path: /
84
+ ip: 1.1.1.1
85
+ referer: <%=nil%>
86
+ language: <%=nil%>
87
+ user_agent: Googlebot/2.X (+http://www.googlebot.com/bot.html)
88
+ created_at: <%=5.hours.ago.to_s(:db)%>
89
+ created_on: <%=5.hours.ago.to_s(:db)%>