Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

reimporting o2 from svn

  • Loading branch information...
commit f36de8fc151605686daceb115b1c91df6ce77847 1 parent 7a9a2ff
Daniel Weinand authored

Showing 334 changed files with 20,449 additions and 0 deletions. Show diff stats Hide diff stats

  1. 17  .gitignore
  2. 3  Capfile
  3. 20  MIT-LICENSE
  4. 10  Rakefile
  5. 99  app/controllers/accounts_controller.rb
  6. 28  app/controllers/admin_controller.rb
  7. 52  app/controllers/application.rb
  8. 55  app/controllers/categories_controller.rb
  9. 21  app/controllers/dashboard_controller.rb
  10. 55  app/controllers/forums_controller.rb
  11. 23  app/controllers/images_controller.rb
  12. 17  app/controllers/legacy_routes_controller.rb
  13. 128  app/controllers/posts_controller.rb
  14. 14  app/controllers/search_controller.rb
  15. 8  app/controllers/tools_controller.rb
  16. 69  app/controllers/users_controller.rb
  17. 3  app/helpers/accounts_helper.rb
  18. 2  app/helpers/admin_accounts_helper.rb
  19. 7  app/helpers/admin_helper.rb
  20. 127  app/helpers/application_helper.rb
  21. 3  app/helpers/categories_helper.rb
  22. 3  app/helpers/dashboard_helper.rb
  23. 2  app/helpers/feeds_helper.rb
  24. 2  app/helpers/forums_helper.rb
  25. 2  app/helpers/images_helper.rb
  26. 2  app/helpers/legacy_routes_helper.rb
  27. 2  app/helpers/opinion_helper.rb
  28. 10  app/helpers/posts_helper.rb
  29. 14  app/helpers/search_helper.rb
  30. 2  app/helpers/tools_helper.rb
  31. 2  app/helpers/users_helper.rb
  32. 34  app/models/category.rb
  33. 50  app/models/comment.rb
  34. 20  app/models/forum.rb
  35. 26  app/models/image.rb
  36. 61  app/models/post.rb
  37. 36  app/models/sql_like_query.rb
  38. 62  app/models/topic.rb
  39. 78  app/models/user.rb
  40. 14  app/models/user_mailer.rb
  41. 8  app/services/search.rb
  42. 2  app/views/accounts/destroy.rjs
  43. 24  app/views/accounts/index.rhtml
  44. 41  app/views/accounts/new.rhtml
  45. 14  app/views/accounts/password_recovery.rhtml
  46. 50  app/views/admin/_new_user.rhtml
  47. 12  app/views/admin/_user_li.rhtml
  48. 20  app/views/admin/create_user.rjs
  49. 69  app/views/admin/index.rhtml
  50. 46  app/views/categories/_categories_table.rhtml
  51. 6  app/views/categories/_edit.rhtml
  52. 9  app/views/categories/create.rjs
  53. 2  app/views/categories/destroy.rjs
  54. 8  app/views/categories/rename.rjs
  55. 57  app/views/categories/show.rhtml
  56. 20  app/views/categories/show.rxml
  57. 5  app/views/categories/update.rjs
  58. 20  app/views/dashboard/feed.rxml
  59. 72  app/views/dashboard/index.rhtml
  60. 22  app/views/forums/_forum.rhtml
  61. 3  app/views/forums/_forum_li.rhtml
  62. 10  app/views/forums/create.rjs
  63. 2  app/views/forums/destroy.rjs
  64. 57  app/views/forums/show.rhtml
  65. 20  app/views/forums/show.rxml
  66. 9  app/views/forums/update.rjs
  67. 73  app/views/layouts/accounts.rhtml
  68. 98  app/views/layouts/application.rhtml
  69. 48  app/views/posts/_comment.rhtml
  70. 7  app/views/posts/_comments_table.rhtml
  71. 24  app/views/posts/_formatting_guide.rhtml
  72. 19  app/views/posts/_recent_activity.rhtml
  73. 31  app/views/posts/_topic.rhtml
  74. 58  app/views/posts/edit.rhtml
  75. 61  app/views/posts/new.rhtml
  76. 150  app/views/posts/show.rhtml
  77. 29  app/views/posts/show.rxml
  78. 6  app/views/posts/update.rjs
  79. 50  app/views/search/results.rhtml
  80. 8  app/views/user_mailer/recover.rhtml
  81. 6  app/views/users/_user_li.rhtml
  82. 10  app/views/users/create_user.rjs
  83. 20  app/views/users/gravatar.rhtml
  84. 27  app/views/users/list.rhtml
  85. 2  app/views/users/remove_user.rjs
  86. 119  app/views/users/show.rhtml
  87. 14  config/amazon_s3.yml
  88. 36  config/boot.rb
  89. 88  config/database.example.yml
  90. 71  config/environment.rb
  91. 19  config/environments/development.rb
  92. 20  config/environments/production.rb
  93. 19  config/environments/test.rb
  94. 53  config/lighttpd.conf
  95. 11  config/recaptcha.example.yml
  96. 32  config/routes.rb
  97. 34  db/development_structure.sql
  98. 32  db/migrate/001_new_initial_tables.rb
  99. 9  db/migrate/002_add_parent_id_to_posts.rb
  100. 9  db/migrate/003_remove_obsolete_gravatar_link.rb
  101. 9  db/migrate/004_remove_login_from_users.rb
  102. 24  db/migrate/005_add_area.rb
  103. 24  db/migrate/006_add_user_type.rb
  104. 9  db/migrate/007_add_area_id_to_remote_sites.rb
  105. 9  db/migrate/008_add_updated_at_to_posts.rb
  106. 9  db/migrate/009_add_status_to_posts.rb
  107. 9  db/migrate/010_add_title_dashed_to_categories.rb
  108. 11  db/migrate/011_add_index.rb
  109. 14  db/migrate/012_add_token_to_users.rb
  110. 15  db/migrate/013_add_inspirations.rb
  111. 8  db/migrate/014_add_null_posts_default.rb
  112. 9  db/migrate/015_add_anon_posts_for_areas.rb
  113. 13  db/migrate/016_add_entries_for_files.rb
  114. 9  db/migrate/017_rename_entries_to_attachments.rb
  115. 9  db/migrate/018_rename_post_to_topic_id.rb
  116. 12  db/migrate/019_drop_attachments.rb
  117. 13  db/migrate/020_add_category_id_to_comments.rb
  118. 26  db/migrate/021_cleanup.rb
  119. 20  db/migrate/022_areas_to_forums.rb
  120. 13  db/migrate/023_remove_title_dashed.rb
  121. 9  db/migrate/024_remove_post_count.rb
  122. 11  db/migrate/025_add_description_for_categories.rb
  123. 11  db/migrate/026_add_user_desc.rb
  124. 9  db/migrate/027_add_edited_at_to_posts.rb
  125. 11  db/migrate/028_add_forum_body_and_category_subtitles.rb
  126. 13  db/migrate/029_change_category_description_from_string_to_text.rb
  127. 9  db/migrate/030_change_signature_to_text.rb
  128. 21  db/migrate/031_create_images.rb
  129. 9  db/migrate/032_add_access_level_to_category.rb
  130. 14  db/migrate/033_delete_accounts_with_zero_posts.rb
  131. 71  db/schema.rb
  132. 2  doc/README_FOR_APP
  133. 18  lib/dash_string.rb
  134. 62  lib/tasks/backup.rake
  135. 90  lib/tasks/capistrano.rake
  136. 40  public/.htaccess
  137. 22  public/404.html
  138. 77  public/500.html
  139. 10  public/dispatch.cgi
  140. 24  public/dispatch.fcgi
  141. 10  public/dispatch.rb
  142. 0  public/favicon.ico
  143. BIN  public/files/0000/0013/2.jpg
  144. BIN  public/files/0000/0013/2_thumb.jpg
  145. BIN  public/files/15/2.jpg
  146. BIN  public/files/15/2_thumb.jpg
  147. BIN  public/images/admin-no-gravatar.jpg
  148. BIN  public/images/bg.gif
  149. BIN  public/images/blank.gif
  150. BIN  public/images/breadcrumb-bg.gif
  151. BIN  public/images/close.gif
  152. BIN  public/images/closed.gif
  153. BIN  public/images/closelabel.gif
  154. BIN  public/images/comment-details-tr.gif
  155. BIN  public/images/comment-details.gif
  156. BIN  public/images/comment-shade.gif
  157. BIN  public/images/loading.gif
  158. BIN  public/images/next.gif
  159. BIN  public/images/nextlabel.gif
  160. BIN  public/images/no-gravatar.jpg
  161. BIN  public/images/prev.gif
  162. BIN  public/images/prevlabel.gif
  163. BIN  public/images/rails.png
  164. BIN  public/images/rss.png
  165. BIN  public/images/spinner.gif
  166. BIN  public/images/star.png
  167. BIN  public/images/sticky.gif
  168. BIN  public/images/trash.gif
  169. 0  public/javascripts/application.js
  170. 873  public/javascripts/controls.js
  171. 968  public/javascripts/dragdrop.js
  172. 1,092  public/javascripts/effects.js
  173. 29  public/javascripts/flash.js
  174. 689  public/javascripts/lightbox.js
  175. 128  public/javascripts/opinion.js
  176. 3,271  public/javascripts/prototype.js
  177. 27  public/javascripts/routing_navigator.js
  178. 1  public/robots.txt
  179. 120  public/stylesheets/ie.css
  180. 104  public/stylesheets/lightbox.css
  181. 804  public/stylesheets/opinion.css
  182. 48  public/stylesheets/routing_navigator.css
  183. 3  script/about
  184. 3  script/breakpointer
  185. 3  script/console
  186. 3  script/destroy
  187. 3  script/generate
  188. 3  script/performance/benchmarker
  189. 3  script/performance/profiler
  190. 3  script/plugin
  191. 3  script/process/inspector
  192. 3  script/process/reaper
  193. 3  script/process/spawner
  194. 3  script/process/spinner
  195. 3  script/runner
  196. 3  script/server
  197. 36  test/fixtures/categories.yml
  198. 15  test/fixtures/forums.yml
  199. 21  test/fixtures/images.yml
  200. 74  test/fixtures/posts.yml
  201. 34  test/fixtures/users.yml
  202. 89  test/functional/accounts_controller_test.rb
  203. 20  test/functional/admin_controller_test.rb
  204. 73  test/functional/categories_controller_test.rb
  205. 68  test/functional/forums_controller_test.rb
  206. 18  test/functional/images_controller_test.rb
  207. 18  test/functional/legacy_routes_controller_test.rb
  208. 127  test/functional/posts_controller_test.rb
  209. 22  test/functional/search_controller_test.rb
  210. 21  test/functional/tools_controller_test.rb
  211. 31  test/functional/users_controller_test.rb
  212. 11  test/mocks/test/remote_login_site.rb
  213. 39  test/test_helper.rb
  214. 10  test/unit/category_test.rb
  215. 10  test/unit/forum_test.rb
  216. 10  test/unit/image_test.rb
  217. 44  test/unit/post_test.rb
  218. 31  test/unit/user_mailer_test.rb
  219. 10  test/unit/user_test.rb
  220. 3  vendor/RedCloth-3.0.3/bin/redcloth
  221. 1,113  vendor/RedCloth-3.0.3/lib/redcloth.rb
  222. 26  vendor/RedCloth-3.0.3/run-tests.rb
  223. 105  vendor/RedCloth-3.0.3/tests/code.yml
  224. 171  vendor/RedCloth-3.0.3/tests/images.yml
  225. 39  vendor/RedCloth-3.0.3/tests/instiki.yml
  226. 155  vendor/RedCloth-3.0.3/tests/links.yml
  227. 77  vendor/RedCloth-3.0.3/tests/lists.yml
  228. 218  vendor/RedCloth-3.0.3/tests/markdown.yml
  229. 64  vendor/RedCloth-3.0.3/tests/poignant.yml
  230. 198  vendor/RedCloth-3.0.3/tests/table.yml
  231. 397  vendor/RedCloth-3.0.3/tests/textism.yml
  232. 46  vendor/plugins/annotate_models/ChangeLog
  233. 31  vendor/plugins/annotate_models/README
  234. 127  vendor/plugins/annotate_models/lib/annotate_models.rb
  235. 6  vendor/plugins/annotate_models/tasks/annotate_models_tasks.rake
  236. 4  vendor/plugins/attachment_fu/README
  237. 22  vendor/plugins/attachment_fu/Rakefile
  238. 14  vendor/plugins/attachment_fu/amazon_s3.yml.tpl
  239. 14  vendor/plugins/attachment_fu/init.rb
  240. 5  vendor/plugins/attachment_fu/install.rb
  241. 93  vendor/plugins/attachment_fu/lib/geometry.rb
  242. 419  vendor/plugins/attachment_fu/lib/technoweenie/attachment_fu.rb
  243. 39  vendor/plugins/attachment_fu/lib/technoweenie/attachment_fu/backends/db_file_backend.rb
  244. 91  vendor/plugins/attachment_fu/lib/technoweenie/attachment_fu/backends/file_system_backend.rb
  245. 304  vendor/plugins/attachment_fu/lib/technoweenie/attachment_fu/backends/s3_backend.rb
  246. 50  vendor/plugins/attachment_fu/lib/technoweenie/attachment_fu/processors/image_science_processor.rb
  247. 56  vendor/plugins/attachment_fu/lib/technoweenie/attachment_fu/processors/mini_magick_processor.rb
  248. 53  vendor/plugins/attachment_fu/lib/technoweenie/attachment_fu/processors/rmagick_processor.rb
  249. 16  vendor/plugins/attachment_fu/test/backends/db_file_test.rb
  250. 80  vendor/plugins/attachment_fu/test/backends/file_system_test.rb
  251. 103  vendor/plugins/attachment_fu/test/backends/remote/s3_test.rb
  252. 57  vendor/plugins/attachment_fu/test/base_attachment_tests.rb
  253. 57  vendor/plugins/attachment_fu/test/basic_test.rb
  254. 57  vendor/plugins/attachment_fu/test/extra_attachment_test.rb
  255. 126  vendor/plugins/attachment_fu/test/fixtures/attachment.rb
  256. BIN  vendor/plugins/attachment_fu/test/fixtures/files/fake/rails.png
  257. 1  vendor/plugins/attachment_fu/test/fixtures/files/foo.txt
  258. BIN  vendor/plugins/attachment_fu/test/fixtures/files/rails.png
  259. 101  vendor/plugins/attachment_fu/test/geometry_test.rb
  260. 31  vendor/plugins/attachment_fu/test/processors/image_science_test.rb
  261. 31  vendor/plugins/attachment_fu/test/processors/mini_magick_test.rb
  262. 240  vendor/plugins/attachment_fu/test/processors/rmagick_test.rb
  263. 86  vendor/plugins/attachment_fu/test/schema.rb
  264. 121  vendor/plugins/attachment_fu/test/test_helper.rb
  265. 55  vendor/plugins/attachment_fu/test/validation_test.rb
  266. 152  vendor/plugins/classic_pagination/CHANGELOG
  267. 18  vendor/plugins/classic_pagination/README
  268. 22  vendor/plugins/classic_pagination/Rakefile
  269. 33  vendor/plugins/classic_pagination/init.rb
  270. 1  vendor/plugins/classic_pagination/install.rb
  271. 405  vendor/plugins/classic_pagination/lib/pagination.rb
  272. 135  vendor/plugins/classic_pagination/lib/pagination_helper.rb
  273. 24  vendor/plugins/classic_pagination/test/fixtures/companies.yml
  274. 9  vendor/plugins/classic_pagination/test/fixtures/company.rb
  275. 7  vendor/plugins/classic_pagination/test/fixtures/developer.rb
  276. 21  vendor/plugins/classic_pagination/test/fixtures/developers.yml
  277. 13  vendor/plugins/classic_pagination/test/fixtures/developers_projects.yml
  278. 3  vendor/plugins/classic_pagination/test/fixtures/project.rb
  279. 7  vendor/plugins/classic_pagination/test/fixtures/projects.yml
  280. 13  vendor/plugins/classic_pagination/test/fixtures/replies.yml
  281. 5  vendor/plugins/classic_pagination/test/fixtures/reply.rb
  282. 42  vendor/plugins/classic_pagination/test/fixtures/schema.sql
  283. 3  vendor/plugins/classic_pagination/test/fixtures/topic.rb
  284. 22  vendor/plugins/classic_pagination/test/fixtures/topics.yml
  285. 117  vendor/plugins/classic_pagination/test/helper.rb
  286. 38  vendor/plugins/classic_pagination/test/pagination_helper_test.rb
  287. 177  vendor/plugins/classic_pagination/test/pagination_test.rb
  288. 22  vendor/plugins/html_engine/Rakefile
  289. 42  vendor/plugins/html_engine/init.rb
  290. 48  vendor/plugins/html_engine/lib/html_engine.rb
  291. 24  vendor/plugins/html_engine/lib/html_engine_ext.rb
  292. 38  vendor/plugins/html_engine/lib/red_cloth_patches.rb
  293. 44  vendor/plugins/html_engine/test/engine_test.rb
  294. 8  vendor/plugins/html_engine/test/test_helper.rb
  295. 22  vendor/plugins/identifications/Rakefile
  296. 5  vendor/plugins/identifications/init.rb
  297. 102  vendor/plugins/identifications/lib/handle.rb
  298. 45  vendor/plugins/identifications/lib/token.rb
  299. 4  vendor/plugins/identifications/test/fixtures/article.rb
  300. 0  vendor/plugins/identifications/test/fixtures/articles.yml
  301. 3  vendor/plugins/identifications/test/fixtures/post.rb
  302. 11  vendor/plugins/identifications/test/fixtures/posts.yml
  303. 4  vendor/plugins/identifications/test/fixtures/secret_article.rb
  304. 0  vendor/plugins/identifications/test/fixtures/secret_articles.yml
  305. 4  vendor/plugins/identifications/test/fixtures/strange_article.rb
  306. 0  vendor/plugins/identifications/test/fixtures/strange_article.yml
  307. 64  vendor/plugins/identifications/test/handle_test.rb
  308. 24  vendor/plugins/identifications/test/schema.rb
  309. 36  vendor/plugins/identifications/test/test_helper.rb
  310. 29  vendor/plugins/identifications/test/token_test.rb
  311. 19  vendor/plugins/recaptcha/LICENSE
  312. 43  vendor/plugins/recaptcha/README
  313. 23  vendor/plugins/recaptcha/Rakefile
  314. 4  vendor/plugins/recaptcha/init.rb
  315. 1  vendor/plugins/recaptcha/install.rb
  316. 74  vendor/plugins/recaptcha/lib/recaptcha.rb
  317. 4  vendor/plugins/recaptcha/tasks/recaptcha_tasks.rake
  318. 49  vendor/plugins/recaptcha/test/recaptcha_test.rb
  319. 1  vendor/plugins/recaptcha/uninstall.rb
  320. 20  vendor/plugins/routing_navigator/MIT-LICENSE
  321. 32  vendor/plugins/routing_navigator/README
  322. 7  vendor/plugins/routing_navigator/about.yml
  323. 1  vendor/plugins/routing_navigator/init.rb
  324. 3  vendor/plugins/routing_navigator/install.rb
  325. 58  vendor/plugins/routing_navigator/lib/routing_navigator.rb
  326. 16  vendor/plugins/routing_navigator/lib/routing_navigator_controller.rb
  327. 3  vendor/plugins/routing_navigator/lib/routing_navigator_helper.rb
  328. 27  vendor/plugins/routing_navigator/public/javascripts/routing_navigator.js
  329. 48  vendor/plugins/routing_navigator/public/stylesheets/routing_navigator.css
  330. 5  vendor/plugins/routing_navigator/tasks/routing_navigator_tasks.rake
  331. 2  vendor/plugins/routing_navigator/uninstall.rb
  332. 64  vendor/plugins/routing_navigator/views/routing_navigator/_navigator.rhtml
  333. 77  vendor/plugins/routing_navigator/views/routing_navigator/index.rhtml
17  .gitignore
... ...
@@ -0,0 +1,17 @@
  1
+*.log
  2
+
  3
+# We ignore all subversion directories underneath test and vendor
  4
+.svn
  5
+vendor/*/.svn
  6
+test/*/.svn
  7
+
  8
+# ignore osx dsstore files
  9
+.DS_Store
  10
+
  11
+tmp/*
  12
+
  13
+*.db
  14
+
  15
+database.yml
  16
+recaptcha.yml
  17
+deploy.rb
3  Capfile
... ...
@@ -0,0 +1,3 @@
  1
+require 'capistrano/version'
  2
+#load 'deploy' if respond_to?(:namespace) # cap2 differentiator
  3
+load 'config/deploy'
20  MIT-LICENSE
... ...
@@ -0,0 +1,20 @@
  1
+Copyright (c) 2005-2006 Daniel Weinand
  2
+
  3
+Permission is hereby granted, free of charge, to any person obtaining
  4
+a copy of this software and associated documentation files (the
  5
+"Software"), to deal in the Software without restriction, including
  6
+without limitation the rights to use, copy, modify, merge, publish,
  7
+distribute, sublicense, and/or sell copies of the Software, and to
  8
+permit persons to whom the Software is furnished to do so, subject to
  9
+the following conditions:
  10
+
  11
+The above copyright notice and this permission notice shall be
  12
+included in all copies or substantial portions of the Software.
  13
+
  14
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
  15
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
  16
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
  17
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 
  18
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
  19
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 
  20
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
10  Rakefile
... ...
@@ -0,0 +1,10 @@
  1
+# Add your own tasks in files placed in lib/tasks ending in .rake,
  2
+# for example lib/tasks/switchtower.rake, and they will automatically be available to Rake.
  3
+
  4
+require(File.join(File.dirname(__FILE__), 'config', 'boot'))
  5
+
  6
+require 'rake'
  7
+require 'rake/testtask'
  8
+require 'rake/rdoctask'
  9
+
  10
+require 'tasks/rails'
99  app/controllers/accounts_controller.rb
... ...
@@ -0,0 +1,99 @@
  1
+class AccountsController < ApplicationController
  2
+  before_filter :require_admin, :only => [:destroy]
  3
+
  4
+
  5
+  def index                
  6
+    @user = User.new(params[:user])
  7
+    
  8
+    if request.post? 
  9
+      
  10
+      if user = User.find_by_email_and_password(@user.email,@user.password)
  11
+
  12
+        if params[:remember] == 'on'
  13
+          cookies[:token]  = { :value => user.token, :expires => 3.months.from_now } 
  14
+        end
  15
+      
  16
+        session[:user] = user
  17
+        flash[:notice] = "Welcome #{user.name}"
  18
+        redirect_to params[:return_to] || index_url
  19
+        return
  20
+      end        
  21
+      
  22
+      flash[:notice] = "Invalid login."
  23
+    end
  24
+  end
  25
+  
  26
+  def new
  27
+    # Add condition here if you want to disable or restrict the registration of new users
  28
+    if false
  29
+      redirect_to index_url and return
  30
+    end
  31
+    
  32
+    @user = User.new(params[:user])   
  33
+  end
  34
+
  35
+  def create
  36
+    @user = User.new(params[:user])   
  37
+    
  38
+    # First user created is a superuser
  39
+    @user.level = User.count > 0 ? 0 : 1024
  40
+
  41
+    if verify_recaptcha and @user.save      
  42
+      flash[:notice] = "Successfully created user #{@user.name}&hellip;"
  43
+      session[:user] = @user
  44
+      
  45
+      redirect_to index_url
  46
+    else
  47
+      render :action => 'new'
  48
+    end    
  49
+  end
  50
+  
  51
+  def update
  52
+    @user.attributes = params[:user]
  53
+
  54
+    if @user.save
  55
+      flash[:notice] = "Successfully updated user #{@user.name}&hellip;"
  56
+      session[:user] = @user
  57
+      
  58
+      redirect_to index_url
  59
+    else
  60
+      flash[:error] = "Could not save user: #{@user.errors.full_messages}"
  61
+      redirect_to :action => 'edit'
  62
+    end
  63
+  end
  64
+  
  65
+  def logout
  66
+    session[:user] = nil
  67
+    cookies[:token]  = { :value => '', :expires => Time.at(0) } 
  68
+    redirect_to index_url
  69
+  end
  70
+  
  71
+  def password_recovery
  72
+    
  73
+    if request.post?
  74
+      
  75
+      if user = User.find_by_email(params[:user][:email])
  76
+        UserMailer.deliver_recover(user, request.host)
  77
+        render :update do |page|
  78
+          page.call 'Flash.notice', "The password has been sent to <u>#{user.email}</u>&hellip;"
  79
+        end
  80
+      else
  81
+        render :update do |page|
  82
+          page.call 'Flash.error', "The email address you specified is not registered!"          
  83
+        end
  84
+      end
  85
+    end
  86
+    
  87
+  end
  88
+  
  89
+  def destroy
  90
+    @deleted_user = User.find(params[:id])
  91
+    @deleted_user.destroy
  92
+    respond_to do |accepts|
  93
+      accepts.html { flash[:notice] = "Removed user #{@deleted_user.name}&hellip;"; redirect_to index_url }
  94
+      accepts.js   
  95
+    end
  96
+  end
  97
+  
  98
+
  99
+end
28  app/controllers/admin_controller.rb
... ...
@@ -0,0 +1,28 @@
  1
+class AdminController < ApplicationController
  2
+  before_filter :require_super_user 
  3
+  
  4
+  def index
  5
+    @superusers = User.find(:all, :conditions => "level = 1024")
  6
+    @admins     = User.find(:all, :conditions => "level = 128")
  7
+    @moderators = User.find(:all, :conditions => "level = 64")
  8
+  end
  9
+  
  10
+  def new_user
  11
+    render :partial => 'new_user'
  12
+  end
  13
+  
  14
+  def create_user
  15
+    @newuser = User.new(params[:newuser])
  16
+    @newuser.level = params[:newuser][:level]
  17
+    @newuser.save
  18
+  end  
  19
+  
  20
+  protected
  21
+    
  22
+  def access_denied
  23
+    session[:return_to] = { :controller => controller_name, :action => action_name }
  24
+    redirect_to :controller => "accounts"
  25
+    return false
  26
+  end
  27
+
  28
+end
52  app/controllers/application.rb
... ...
@@ -0,0 +1,52 @@
  1
+# Filters added to this controller will be run for all controllers in the application.
  2
+# Likewise, all the methods added will be available for all controllers.
  3
+class ApplicationController < ActionController::Base
  4
+  before_filter :login
  5
+    
  6
+  protected
  7
+    
  8
+  def load_forum
  9
+    @forum = Forum.find(params[:forum])
  10
+    if not @forum
  11
+      raise StandardError, "unknown forum"
  12
+    end
  13
+  end
  14
+    
  15
+  def access_denied
  16
+    flash[:error] = "You do not have the required user level to perform the action #{controller_name}::#{action_name}"
  17
+    redirect_to '/'
  18
+    return false
  19
+  end
  20
+  
  21
+  def login
  22
+    user =  session[:user] || login_from_cookie
  23
+    
  24
+    if user       
  25
+      @user = User.auth(user.email, user.password)
  26
+    end
  27
+  end
  28
+  
  29
+  def login_from_cookie
  30
+    if cookies[:token]  
  31
+      return session[:user] = User.find_by_token(cookies[:token]) 
  32
+    end
  33
+    nil 
  34
+  end
  35
+  
  36
+  def access_conditions    
  37
+    'access_level <= ' << (@user.nil? ? 0 : @user.level).to_i.to_s
  38
+  end  
  39
+  
  40
+  def require_super_user
  41
+    access_denied unless @user and @user.level >= 1024
  42
+  end
  43
+
  44
+  def require_admin
  45
+    access_denied unless @user and @user.level >= 128
  46
+  end
  47
+
  48
+  def require_moderator
  49
+    access_denied unless @user and @user.level >= 64
  50
+  end
  51
+
  52
+end
55  app/controllers/categories_controller.rb
... ...
@@ -0,0 +1,55 @@
  1
+class CategoriesController < ApplicationController
  2
+  before_filter :require_admin, :except => [:show]
  3
+  
  4
+  def show
  5
+    @category = Category.find(params[:id], :conditions => access_conditions)
  6
+    @topic_pages = Paginator.new(self, @category.topics.count, 20, params[:page])
  7
+    @topics = @category.topics.find(:all, :limit => 20, :offset => @topic_pages.current.offset, :order => "(status = 'sticky') DESC, updated_at DESC")  
  8
+    @recent_posts = @category.posts.find(:all, :limit => 20, :order => 'id DESC')
  9
+    @rss = formatted_category_url(@category, 'xml')
  10
+    
  11
+    respond_to do |accepts|
  12
+      accepts.html
  13
+      accepts.xml { render :action => 'show.rxml', :layout => false}
  14
+    end    
  15
+  end
  16
+  
  17
+  def create
  18
+    forum = Forum.find(params[:forum_id])
  19
+    @categories = forum.categories
  20
+    @category = Category.new
  21
+    @category.forum_id = forum.id
  22
+    @category.attributes = params[:category]
  23
+    @category.save
  24
+    
  25
+    respond_to do |accepts|
  26
+      accepts.js
  27
+    end
  28
+  end
  29
+  
  30
+  def edit
  31
+    @category = Category.find(params[:id])
  32
+    render :partial => 'edit'
  33
+  end
  34
+  
  35
+  def destroy
  36
+    @category = Category.find(params[:id])
  37
+    @category.destroy
  38
+  end
  39
+  
  40
+  def rename
  41
+    update
  42
+    @categories = @category.forum.categories
  43
+  end
  44
+  
  45
+  def update
  46
+    @category = Category.find(params[:id])
  47
+    @category.attributes = params[:category]
  48
+    @category.save
  49
+  end
  50
+
  51
+  private
  52
+  
  53
+  
  54
+
  55
+end
21  app/controllers/dashboard_controller.rb
... ...
@@ -0,0 +1,21 @@
  1
+class DashboardController < ApplicationController
  2
+  
  3
+  def index
  4
+    @topic_count = Topic.count
  5
+    @comment_count = Comment.count
  6
+    @user_count = User.count
  7
+    @forums = Forum.find(:all)
  8
+    @rss = url_for(:action => 'feed', :only_path => false)
  9
+
  10
+    today, yesterday = Time.now.to_date, Time.now.yesterday.to_date     
  11
+    @recent_posts = Post.find(:all, :limit => 10, :conditions => ["category_id in (?)", Category.ids_matching(access_conditions)],  :order => 'id DESC')
  12
+  end
  13
+
  14
+  def feed
  15
+    @recent_posts = Post.find(:all, :conditions => ["category_id in (?)", Category.ids_matching(access_conditions)], :limit => 10, :order => 'id DESC')
  16
+    respond_to do |accepts|
  17
+      accepts.xml { render :action => 'feed.rxml', :layout => false}
  18
+    end
  19
+  end
  20
+
  21
+end
55  app/controllers/forums_controller.rb
... ...
@@ -0,0 +1,55 @@
  1
+class ForumsController < ApplicationController
  2
+  before_filter :require_super_user, :except => [:show]
  3
+
  4
+
  5
+  def show
  6
+    @forum = Forum.find(params[:id])
  7
+    @category_pages = Paginator.new(self, @forum.categories.count(:all, :conditions => access_conditions), 20, params[:page])
  8
+    @categories = @forum.categories.find(:all, :limit => 20, :conditions => access_conditions, :offset => @category_pages.current.offset, :order => 'id ASC')    
  9
+    
  10
+    @rss = formatted_forum_url(@forum, 'xml')
  11
+
  12
+    today, yesterday = Time.now.to_date, Time.now.yesterday.to_date     
  13
+    @recent_posts = @forum.posts.find(:all, :limit => 20, :conditions => ['category_id in (?)', Category.ids_matching(access_conditions)], :order => 'id DESC')
  14
+
  15
+    respond_to do |accepts|
  16
+      accepts.html
  17
+      accepts.xml { render :action => 'show.rxml', :layout => false}
  18
+    end
  19
+  end
  20
+
  21
+
  22
+  def create
  23
+    @forum = Forum.new
  24
+    @forum.attributes = params[:forum]
  25
+    @forum.save
  26
+    
  27
+    respond_to do |accepts|
  28
+      accepts.html { flash[:notice] = "Successfully created..."; redirect_to forum_url(@forum)  }
  29
+      accepts.js   
  30
+    end
  31
+  end
  32
+  
  33
+  def destroy
  34
+    @forum = Forum.find(params[:id])
  35
+    @forum.destroy
  36
+
  37
+    respond_to do |accepts|
  38
+      accepts.html { flash[:notice] = "Successfully removed..."; redirect_to index_url  }
  39
+      accepts.js   
  40
+    end
  41
+  end
  42
+  
  43
+  def update
  44
+    @forum = Forum.find(params[:id])
  45
+    @forum.attributes = params[:forum]
  46
+    @forum.save
  47
+    
  48
+    respond_to do |accepts|
  49
+      accepts.html { flash[:notice] = "Successfully updated..."; redirect_to forum_url(@forum)  }
  50
+      accepts.js   
  51
+    end
  52
+  end
  53
+
  54
+
  55
+end
23  app/controllers/images_controller.rb
... ...
@@ -0,0 +1,23 @@
  1
+class ImagesController < ApplicationController
  2
+  before_filter :fetch_post
  3
+  
  4
+  def create
  5
+    if @post.editable? and @post.owner?(@user)
  6
+      image = @post.images.build(params[:image])
  7
+      
  8
+      if image.save
  9
+        flash[:notice] = "Successfully uploaded #{image.filename}..."
  10
+      else
  11
+        flash[:error] = "Uploaded image was too large."
  12
+      end
  13
+    end
  14
+    
  15
+    params[:return_to] ? redirect_to(params[:return_to]) : redirect_to(:back)
  16
+  end
  17
+  
  18
+  private
  19
+  
  20
+  def fetch_post
  21
+    @post = Category.find(params[:category_id], :conditions => access_conditions).posts.find(params[:post_id])
  22
+  end
  23
+end
17  app/controllers/legacy_routes_controller.rb
... ...
@@ -0,0 +1,17 @@
  1
+class LegacyRoutesController < ApplicationController
  2
+
  3
+  def area
  4
+    area = Forum.find(params[:id])
  5
+    redirect_to forum_url(area)
  6
+  end
  7
+
  8
+  def category
  9
+    cat = Category.find(params[:id])
  10
+    redirect_to category_url(cat)
  11
+  end
  12
+  
  13
+  def post
  14
+    post = Post.find(params[:id])
  15
+    redirect_to category_post_url(post.category_id, post.id)
  16
+  end
  17
+end
128  app/controllers/posts_controller.rb
... ...
@@ -0,0 +1,128 @@
  1
+class PostsController < ApplicationController
  2
+  before_filter :fetch_category
  3
+  before_filter :require_moderator, :except => [:show, :edit, :update, :create, :new]
  4
+
  5
+  def show
  6
+    @topic = @post = Topic.find(params[:id])
  7
+    @rss = formatted_category_post_url(@topic.category, @topic, 'xml')
  8
+    
  9
+    respond_to do |accepts|
  10
+      accepts.html
  11
+      accepts.xml { render :action => 'show.rxml', :layout => false}
  12
+    end
  13
+    
  14
+  end
  15
+  
  16
+  def new    
  17
+    @topic = @category.topics.create(params[:topic])
  18
+  end
  19
+  
  20
+  def create
  21
+    # If post is a comment, find its parent topic
  22
+    if params[:comment]
  23
+      @topic = Topic.find(params[:topic])
  24
+      
  25
+      unless @topic.closed?
  26
+        @post = @topic.comments.build(params[:comment])
  27
+        @post.forum = @topic.forum
  28
+        @post.category_id = @topic.category_id
  29
+
  30
+      end
  31
+    
  32
+    # if post is a topic, create a new topic
  33
+    else
  34
+      @post = @category.topics.create(params[:topic])
  35
+
  36
+      @post.forum = @category.forum
  37
+      @post.status = "normal"
  38
+    end 
  39
+
  40
+    if @user
  41
+      @post.user = @user
  42
+    else
  43
+      if spam?
  44
+        render :status => 403, :text => 'I am afraid I did not save your comment due to you are suspicously resembling a spambot being!' 
  45
+        return 
  46
+      end
  47
+    end
  48
+    
  49
+    if @post.save
  50
+      
  51
+      if params[:image]
  52
+        @post.images << Image.create(params[:image])
  53
+      end
  54
+      
  55
+
  56
+      if @post.is_topic?
  57
+        flash[:notice] = "Created topic #{@post.title}" 
  58
+        redirect_to category_post_url(@post.category, @post)
  59
+      else
  60
+        # saving topic to set updated_at to a proper value
  61
+        @topic.save if @topic
  62
+        flash[:notice] = "Commented on #{@topic.title}"
  63
+        redirect_to :controller => 'posts', :action => 'show', :category_id => @post.category_id, :id => @topic, :anchor => "comment-#{@post.id}"
  64
+      end
  65
+      
  66
+    else  
  67
+
  68
+      if @post.is_topic?
  69
+        flash[:error] = "Could not create topic..."
  70
+        @topic = @post; 
  71
+        render :action => 'new'
  72
+      else
  73
+        flash[:error] = "Could not save topic..."
  74
+        redirect_to :controller => 'posts', :action => 'show', :category_id => @post.category_id, :id => @topic, :anchor => "comments"
  75
+      end    
  76
+    end
  77
+    
  78
+  end
  79
+  
  80
+  def edit
  81
+    @post = Post.find(params[:id])
  82
+
  83
+    # if current user does not have privileges to edit the post:
  84
+    redirect_to category_post_url(@post.category, @post) if @post.user != @user
  85
+  end
  86
+  
  87
+  def update
  88
+    @post = Post.find(params[:id])
  89
+    @post.attributes = params[:post]
  90
+    @post.edited_at = Time.now.utc
  91
+    #@post.status = params[:status]
  92
+    
  93
+    if @post.save
  94
+      respond_to do |accepts|
  95
+        accepts.html { flash[:notice] = "Successfully updated&hellip;"; redirect_to @post.is_topic? ? category_post_url(@post.category, @post) : category_post_url(:category_id => @post.category, :id => @post.topic, :anchor => "comment-#{@post.id}")  }
  96
+        accepts.js   
  97
+      end
  98
+    else
  99
+      respond_to do |accepts| 
  100
+        accepts.html { flash[:notice] = "Could not save your post&hellip;"; render :action => 'edit'  }
  101
+        accepts.js  
  102
+      end
  103
+    end
  104
+  end
  105
+  
  106
+  def destroy
  107
+    post = Post.find(params[:id])
  108
+    post.destroy
  109
+    
  110
+    if post.is_a? Topic
  111
+      redirect_to category_url(post.category)
  112
+    else
  113
+      redirect_to category_post_url(post.category, post.topic)
  114
+    end
  115
+  end
  116
+  
  117
+  private
  118
+  
  119
+  def fetch_category
  120
+    @category = Category.find(params[:category_id], :conditions => access_conditions)    
  121
+  end
  122
+  
  123
+  def spam?
  124
+    params[:verify][:nospam] != "on" or params[:verify][:spam] == "on"        
  125
+  end
  126
+
  127
+
  128
+end
14  app/controllers/search_controller.rb
... ...
@@ -0,0 +1,14 @@
  1
+class SearchController < ApplicationController
  2
+
  3
+  def posts 
  4
+    
  5
+    category_ids = Category.ids_matching(access_conditions)
  6
+        
  7
+    @count = Post.connection.select_value("SELECT COUNT(*) FROM posts WHERE category_id IN (#{category_ids.join(",")}) AND title LIKE '%#{params[:q]}%' OR body LIKE '%#{params[:q]}%'").to_i
  8
+    
  9
+    @result_pages = Paginator.new(self, @count, 15, params[:page])
  10
+    
  11
+    @results = Search.query(params[:q], :categories => category_ids, :limit => 15, :page => params[:page])
  12
+    render :action => 'results'
  13
+  end
  14
+end
8  app/controllers/tools_controller.rb
... ...
@@ -0,0 +1,8 @@
  1
+class ToolsController < ApplicationController
  2
+  skip_before_filter :login
  3
+
  4
+  def preview_textile
  5
+    render :text => request.raw_post.to_html
  6
+  end
  7
+
  8
+end
69  app/controllers/users_controller.rb
... ...
@@ -0,0 +1,69 @@
  1
+class UsersController < ApplicationController
  2
+  before_filter :require_admin, :only => [:create_user]
  3
+
  4
+  def show
  5
+    @user_details = User.find(params[:id])
  6
+  end
  7
+  
  8
+  def list
  9
+    
  10
+    conditions = nil
  11
+    if params[:access]
  12
+      conditions = ["level >= ?", params[:access].to_i]
  13
+    end
  14
+    
  15
+    @user_pages = Paginator.new(self, User.count(:all, :conditions => conditions), 50, params[:page])
  16
+    @users = User.find(:all, :limit => 50, :offset => @user_pages.current.offset, :conditions => conditions, :order => "name ASC")  
  17
+  end
  18
+  
  19
+  
  20
+  def update
  21
+    @user_details = User.find(params[:id])
  22
+    
  23
+    if params[:user][:level]
  24
+      require_super_user
  25
+      @user_details.level = params[:user][:level]
  26
+      @user_details.save
  27
+      render :update do |page|
  28
+        page.call 'Flash.notice', "User <u>#{@user_details.name}</u> updated&hellip;"
  29
+      end  
  30
+    elsif params[:user][:title]
  31
+      require_super_user
  32
+      @user_details.title = params[:user][:title]
  33
+      @user_details.save
  34
+      render :update do |page|
  35
+        page.call 'Flash.notice', "User <u>#{@user_details.name}</u> updated&hellip;"
  36
+        page.replace_html 'user-title-name', @user_details.title
  37
+        page.call 'Opinion.togglePair', 'user-title', 'user-title-edit'
  38
+        page.visual_effect :highlight, "user-title"
  39
+      end  
  40
+    else     
  41
+      @user_details.attributes = params[:user]
  42
+      if @user_details.save
  43
+        flash[:notice] = "Updated your profile&hellip;" 
  44
+        redirect_to index_url
  45
+      else
  46
+        flash[:notice] = "Could not update your profile&hellip;"        
  47
+        render :action => 'show', :id => @user_details
  48
+      end
  49
+    end
  50
+  end
  51
+  
  52
+  def create_user
  53
+    @newuser = User.build(params[:newuser])
  54
+    case(params[:level])
  55
+    when 'Moderator':
  56
+      @newuser.level = 64
  57
+    when 'Administrator':
  58
+      @newuser.level = 128
  59
+    else
  60
+      @newuser.level = 0
  61
+    end
  62
+    @newuser.save
  63
+  end
  64
+
  65
+  def gravatar
  66
+  end
  67
+
  68
+
  69
+end
3  app/helpers/accounts_helper.rb
... ...
@@ -0,0 +1,3 @@
  1
+module AccountsHelper
  2
+
  3
+end
2  app/helpers/admin_accounts_helper.rb
... ...
@@ -0,0 +1,2 @@
  1
+module AdminAccountsHelper
  2
+end
7  app/helpers/admin_helper.rb
... ...
@@ -0,0 +1,7 @@
  1
+module AdminHelper
  2
+  
  3
+  def admin_levels
  4
+    [["Superuser", 1024], ["Administrator", 128], ["Moderator", 64]]
  5
+  end
  6
+  
  7
+end
127  app/helpers/application_helper.rb
... ...
@@ -0,0 +1,127 @@
  1
+# Methods added to this helper will be available to all templates in the application.
  2
+module ApplicationHelper
  3
+  
  4
+  def recent_date(date)    
  5
+    today = z(Time.now.utc)    
  6
+    date  = z(date)
  7
+        
  8
+    day = if date.to_date == today.to_date
  9
+      '<span class="event-today">Today</span>'
  10
+    elsif date.to_date == today.to_date - 1
  11
+      '<span class="event-yesterday">Yesterday</span>'
  12
+    else
  13
+      date.strftime("%d. %b")
  14
+    end
  15
+    
  16
+    day
  17
+  end
  18
+  
  19
+  def ifchanged(item)
  20
+    if item != @most_recent
  21
+      @most_recent = item
  22
+      item
  23
+    end    
  24
+  end
  25
+
  26
+  def title(new_value = nil)
  27
+    @title = new_value if new_value
  28
+    @title
  29
+  end
  30
+  
  31
+  def crumb(title, link, options = nil)
  32
+    @crumbs ||= []
  33
+    @crumbs << link_to(title, link, options)
  34
+  end
  35
+  
  36
+  def breadcrumbs
  37
+    @crumbs ||= []
  38
+    @crumbs.join(" &raquo; ")
  39
+  end
  40
+
  41
+  def gravatar_img(email, level)
  42
+    require 'digest/md5'
  43
+        
  44
+    "http://www.gravatar.com/avatar.php?gravatar_id=#{Digest::MD5.hexdigest(email)}&size=40"
  45
+  end
  46
+
  47
+  def js_flash_notices
  48
+    "Flash.notice('#{flash[:notice]}')" if flash[:notice]
  49
+  end
  50
+
  51
+  def js_error_notices
  52
+    "Flash.error('#{flash[:error]}')" if flash[:error]
  53
+  end
  54
+  
  55
+  def superuser?
  56
+    @user and @user.level >= 1024
  57
+  end
  58
+  
  59
+  def admin?
  60
+    @user and @user.level >= 128
  61
+  end
  62
+  
  63
+  def moderator?
  64
+    @user and @user.level >= 64
  65
+  end
  66
+  
  67
+  def formatted_date(datetime)
  68
+    now = z(Time.now.utc)    
  69
+    datetime = z(datetime)
  70
+    
  71
+    
  72
+    if (time_diff = now - datetime) < 86400
  73
+      return "Today, #{datetime.strftime('%I:%M%p')}"
  74
+    elsif (time_diff = now - datetime) < 172800
  75
+      return "Yesterday, #{datetime.strftime('%I:%M%p')}"
  76
+    else
  77
+      return datetime.strftime("%I:%M%p, %b %d, %G")
  78
+    end
  79
+  end
  80
+  
  81
+  def datetime(date)
  82
+    return "unknown" if date.nil?
  83
+    date.strftime("%Y-%m-%d %I:%M%p")
  84
+  end
  85
+
  86
+  def pagination_links(paginator, options={}, html_options={})
  87
+    html   = []
  88
+
  89
+    html << if paginator.current.previous 
  90
+     content_tag(:span, link_to("&laquo; Previous", params.update(:page => paginator.current.previous) ), :class => 'prev') 
  91
+    end
  92
+
  93
+    html << pagination_links_each(paginator, options) do |page|
  94
+     html_options[:title] = "Go to Page #{page}"
  95
+
  96
+     link_to(page.to_s, params.update(:page => page), html_options)
  97
+    end
  98
+
  99
+    html << if paginator.current.next 
  100
+     content_tag(:span, link_to("Next &raquo;", params.update(:page => paginator.current.next) ), :class => 'next') 
  101
+    end
  102
+
  103
+    content_tag :div, html.join, :id => 'pagination'
  104
+  end
  105
+  
  106
+  def row_class(name = 'generic')
  107
+    variable_name = "@#{name.to_s.downcase.underscore.gsub(/\s/,"_")}_counter"
  108
+    counter = instance_variable_get(variable_name)
  109
+    counter ||= 0
  110
+    counter  += 1
  111
+    instance_variable_set(variable_name, counter)
  112
+    counter.even? ? "even" : "odd"    
  113
+  end
  114
+  
  115
+  def sig(user)
  116
+    "---<br /><p>#{h(user.signature).to_html}</p>" unless user.signature.blank?
  117
+  end
  118
+  
  119
+  def rss_feed_for_page
  120
+    if @rss
  121
+      "<link rel='alternate' type='application/rss+xml' title='RSS' href='#{@rss}' />"
  122
+    else
  123
+      ""
  124
+    end
  125
+  end
  126
+
  127
+end
3  app/helpers/categories_helper.rb
... ...
@@ -0,0 +1,3 @@
  1
+module CategoriesHelper
  2
+  
  3
+end
3  app/helpers/dashboard_helper.rb
... ...
@@ -0,0 +1,3 @@
  1
+module DashboardHelper
  2
+  
  3
+end
2  app/helpers/feeds_helper.rb
... ...
@@ -0,0 +1,2 @@
  1
+module FeedsHelper
  2
+end
2  app/helpers/forums_helper.rb
... ...
@@ -0,0 +1,2 @@
  1
+module ForumsHelper
  2
+end
2  app/helpers/images_helper.rb
... ...
@@ -0,0 +1,2 @@
  1
+module ImagesHelper
  2
+end
2  app/helpers/legacy_routes_helper.rb
... ...
@@ -0,0 +1,2 @@
  1
+module LegacyRoutesHelper
  2
+end
2  app/helpers/opinion_helper.rb
... ...
@@ -0,0 +1,2 @@
  1
+module OpinionHelper
  2
+end
10  app/helpers/posts_helper.rb
... ...
@@ -0,0 +1,10 @@
  1
+module PostsHelper
  2
+
  3
+  def allowed_to_post?
  4
+    if !@user and !@topic.forum.anonymous_posts
  5
+      return false
  6
+    end
  7
+    true
  8
+  end
  9
+
  10
+end
14  app/helpers/search_helper.rb
... ...
@@ -0,0 +1,14 @@
  1
+module SearchHelper
  2
+
  3
+  def highlight_search_result(result)
  4
+    highlight(excerpt(h(result.body), params[:q]), params[:q])
  5
+  rescue ArgumentError
  6
+    truncate(result.body, 100) rescue ''
  7
+  end
  8
+
  9
+  def forum_link(forum)
  10
+    return link_to forum.title, forum_url(forum) unless forum.nil?
  11
+    "unknown forum"
  12
+  end
  13
+
  14
+end
2  app/helpers/tools_helper.rb
... ...
@@ -0,0 +1,2 @@
  1
+module ToolsHelper
  2
+end
2  app/helpers/users_helper.rb
... ...
@@ -0,0 +1,2 @@
  1
+module UsersHelper
  2
+end
34  app/models/category.rb
... ...
@@ -0,0 +1,34 @@
  1
+# == Schema Information
  2
+# Schema version: 32
  3
+#
  4
+# Table name: categories
  5
+#
  6
+#  id           :integer(11)   not null, primary key
  7
+#  title        :string(255)   
  8
+#  forum_id     :integer(11)   
  9
+#  body         :text          
  10
+#  body_html    :text          
  11
+#  subtitle     :string(255)   
  12
+#  access_level :integer(11)   default(0)
  13
+#
  14
+
  15
+class Category < ActiveRecord::Base
  16
+  belongs_to :forum
  17
+  before_save :transform_text
  18
+  attr_protected :forum
  19
+  has_many :topics, :dependent => :destroy
  20
+  has_many :posts
  21
+  
  22
+  def self.ids_matching(conditions)
  23
+    Category.find(:all, :conditions => conditions, :select => 'id' ).collect(&:id)
  24
+  end
  25
+
  26
+  # This will transform the original text to html output with tags using a filter
  27
+  # like Redcloth
  28
+  def transform_text
  29
+    self.body_html = body.to_html if self.body
  30
+  end
  31
+
  32
+  validates_uniqueness_of :title, :scope => :forum_id
  33
+  validates_presence_of :title
  34
+end
50  app/models/comment.rb
... ...
@@ -0,0 +1,50 @@
  1
+# == Schema Information
  2
+# Schema version: 32
  3
+#
  4
+# Table name: posts
  5
+#
  6
+#  id          :integer(11)   not null, primary key
  7
+#  category_id :integer(11)   
  8
+#  title       :string(255)   
  9
+#  body        :text          
  10
+#  body_html   :text          
  11
+#  user_id     :integer(11)   
  12
+#  created_at  :datetime      
  13
+#  type        :string(255)   
  14
+#  parent_id   :integer(11)   
  15
+#  forum_id    :integer(11)   
  16
+#  updated_at  :datetime      
  17
+#  status      :string(255)   default("normal")
  18
+#  edited_at   :datetime      
  19
+#
  20
+
  21
+class Comment < Post
  22
+  belongs_to :topic, :foreign_key => 'parent_id'  
  23
+  
  24
+  def feed_title
  25
+    "#{author_name} commented on #{topic.title}"
  26
+  end
  27
+
  28
+  def editable?
  29
+    return false if self.topic.closed?
  30
+    self.created_at > 3.days.ago
  31
+  end
  32
+  
  33
+  def topic_id
  34
+    parent_id
  35
+  end
  36
+  
  37
+  def topic_title
  38
+    topic.title
  39
+  end
  40
+  
  41
+  def author_name
  42
+    user ? user.name : "Unknown User"
  43
+  end
  44
+  
  45
+  def anchor_name
  46
+    "comment-#{id}"
  47
+  end
  48
+  
  49
+  validates_presence_of :body
  50
+end
20  app/models/forum.rb
... ...
@@ -0,0 +1,20 @@
  1
+# == Schema Information
  2
+# Schema version: 32
  3
+#
  4
+# Table name: forums
  5
+#
  6
+#  id              :integer(11)   not null, primary key
  7
+#  title           :string(255)   
  8
+#  anonymous_posts :boolean(1)    
  9
+#  body            :text          
  10
+#
  11
+
  12
+class Forum < ActiveRecord::Base
  13
+  has_many :categories, :dependent => :destroy
  14
+  has_many :posts
  15
+  
  16
+  protected
  17
+  
  18
+  validates_presence_of :title
  19
+  validates_uniqueness_of :title
  20
+end
26  app/models/image.rb
... ...
@@ -0,0 +1,26 @@
  1
+# == Schema Information
  2
+# Schema version: 32
  3
+#
  4
+# Table name: images
  5
+#
  6
+#  id           :integer(11)   not null, primary key
  7
+#  parent_id    :integer(11)   
  8
+#  post_id      :integer(11)   
  9
+#  content_type :string(255)   
  10
+#  filename     :string(255)   
  11
+#  thumbnail    :string(255)   
  12
+#  size         :integer(11)   
  13
+#  width        :integer(11)   
  14
+#  height       :integer(11)   
  15
+#
  16
+
  17
+class Image < ActiveRecord::Base
  18
+  has_attachment :content_type => :image,