Browse files

Git Import (from SVN)

  • Loading branch information...
0 parents commit 35286af41c6866c2ba1489f382658211a39adbf7 @jcnetdev committed Jul 15, 2008
Showing with 7,480 additions and 0 deletions.
  1. +10 −0 .gitignore
  2. +2 −0 Capfile
  3. +203 −0 README
  4. +10 −0 Rakefile
  5. +27 −0 app/controllers/application.rb
  6. +13 −0 app/controllers/base/project_subpage.rb
  7. +30 −0 app/controllers/bookmarks_controller.rb
  8. +84 −0 app/controllers/comments_controller.rb
  9. +2 −0 app/controllers/comps_controller.rb
  10. +96 −0 app/controllers/hosted_instances_controller.rb
  11. +5 −0 app/controllers/pages_controller.rb
  12. +275 −0 app/controllers/projects_controller.rb
  13. +106 −0 app/controllers/screenshots_controller.rb
  14. +51 −0 app/controllers/sessions_controller.rb
  15. +86 −0 app/controllers/users_controller.rb
  16. +121 −0 app/controllers/versions_controller.rb
  17. +85 −0 app/helpers/application_helper.rb
  18. +15 −0 app/helpers/comments_helper.rb
  19. +2 −0 app/helpers/hosted_instances_helper.rb
  20. +55 −0 app/helpers/javascript_helper.rb
  21. +32 −0 app/helpers/meta_helper.rb
  22. +2 −0 app/helpers/pages_helper.rb
  23. +181 −0 app/helpers/projects_helper.rb
  24. +35 −0 app/helpers/stylesheet_helper.rb
  25. +43 −0 app/helpers/tabs_helper.rb
  26. +100 −0 app/helpers/tag_helper.rb
  27. +299 −0 app/models/activity.rb
  28. +4 −0 app/models/bookmark.rb
  29. +17 −0 app/models/comment.rb
  30. +24 −0 app/models/hosted_instance.rb
  31. +4 −0 app/models/instruction.rb
  32. +10 −0 app/models/login.rb
  33. +69 −0 app/models/mail_incoming.rb
  34. +56 −0 app/models/mixins/project_item.rb
  35. +219 −0 app/models/project.rb
  36. +13 −0 app/models/screenshot.rb
  37. +259 −0 app/models/user.rb
  38. +23 −0 app/models/user_mailer.rb
  39. +28 −0 app/models/version.rb
  40. +8 −0 app/views/bookmarks/_bookmark_list.html.haml
  41. +2 −0 app/views/bookmarks/_bookmark_mini.html.haml
  42. +24 −0 app/views/comments/_comments.html.haml
  43. +25 −0 app/views/comments/_form.html.haml
  44. +6 −0 app/views/comments/edit.html.haml
  45. +70 −0 app/views/comps/detail.html.erb
  46. +105 −0 app/views/comps/form.html.erb
  47. +3 −0 app/views/comps/index.html.haml
  48. +124 −0 app/views/comps/list.html.erb
  49. +16 −0 app/views/hosted_instances/_form.html.haml
  50. +26 −0 app/views/hosted_instances/_hosted_instance.html.haml
  51. +6 −0 app/views/hosted_instances/edit.html.haml
  52. +9 −0 app/views/layouts/_about_us.html.haml
  53. +6 −0 app/views/layouts/_alert.html.haml
  54. +7 −0 app/views/layouts/_credits.html.haml
  55. +6 −0 app/views/layouts/_debug.html.haml
  56. +7 −0 app/views/layouts/_flash_boxes.html.haml
  57. +10 −0 app/views/layouts/_footer.html.haml
  58. +11 −0 app/views/layouts/_header.html.haml
  59. +10 −0 app/views/layouts/_login.html.haml
  60. +1 −0 app/views/layouts/_nav.html.haml
  61. +22 −0 app/views/layouts/_promote.html.erb
  62. +5 −0 app/views/layouts/_searchbox.html.haml
  63. +9 −0 app/views/layouts/_tracking.html.erb
  64. +32 −0 app/views/layouts/application.html.haml
  65. +68 −0 app/views/pages/about.html.haml
  66. +26 −0 app/views/projects/_form.html.haml
  67. +8 −0 app/views/projects/_project.html.haml
  68. 0 app/views/projects/_success.html.haml
  69. +4 −0 app/views/projects/edit.html.haml
  70. +16 −0 app/views/projects/index.atom.builder
  71. +7 −0 app/views/projects/index.html.haml
  72. +6 −0 app/views/projects/parts/_activity_list.html.haml
  73. +2 −0 app/views/projects/parts/_ajax_result.html.haml
  74. +40 −0 app/views/projects/parts/_details.html.haml
  75. +16 −0 app/views/projects/parts/_grid.html.haml
  76. +120 −0 app/views/projects/parts/_index_sidebar.html.haml
  77. +13 −0 app/views/projects/parts/_list.html.haml
  78. +13 −0 app/views/projects/parts/_mini_form.html.haml
  79. +23 −0 app/views/projects/parts/_show.html.haml
  80. +9 −0 app/views/projects/parts/_submit_panel.html.haml
  81. +31 −0 app/views/projects/show.html.haml
  82. +12 −0 app/views/projects/tabs/_hosted_applications.html.haml
  83. +8 −0 app/views/projects/tabs/_recent_activity.html.haml
  84. +16 −0 app/views/projects/tabs/_screenshots.html.haml
  85. +12 −0 app/views/projects/tabs/_versions.html.haml
  86. +11 −0 app/views/screenshots/_form.html.haml
  87. +14 −0 app/views/screenshots/_screenshot.html.haml
  88. +12 −0 app/views/sessions/new.html.haml
  89. +5 −0 app/views/sessions/show.html.haml
  90. +4 −0 app/views/user_mailer/activation_success.html.erb
  91. +9 −0 app/views/user_mailer/signup_notification.html.erb
  92. +20 −0 app/views/users/new.html.haml
  93. +17 −0 app/views/versions/_form.html.haml
  94. +25 −0 app/views/versions/_version.html.haml
  95. +6 −0 app/views/versions/edit.html.haml
  96. +14 −0 config/amazon_s3.yml.changeme
  97. +20 −0 config/app_config.yml
  98. +109 −0 config/boot.rb
  99. +42 −0 config/database.yml
  100. +281 −0 config/deploy.rb
  101. +157 −0 config/environment.rb
  102. +17 −0 config/environments/development.rb
  103. +5 −0 config/environments/development.yml
  104. +18 −0 config/environments/production.rb
  105. +2 −0 config/environments/production.yml
  106. +22 −0 config/environments/test.rb
  107. +5 −0 config/initializers/date_settings.rb
  108. +1 −0 config/initializers/haml.rb
  109. +10 −0 config/initializers/inflections.rb
  110. +5 −0 config/initializers/mail_settings.rb
  111. +5 −0 config/initializers/mime_types.rb
  112. +15 −0 config/initializers/new_default.rb
  113. +3 −0 config/initializers/sass_settings.rb
  114. +7 −0 config/mailer.yml.changeme
  115. +52 −0 config/nginx/opensrcrails.conf
  116. +39 −0 config/routes.rb
  117. +436 −0 db/restore.sql
  118. +196 −0 db/schema.rb
  119. BIN design/screenshots.psd
  120. +2 −0 doc/README_FOR_APP
  121. BIN doc/paging_styles.png
  122. +134 −0 lib/authenticated_system.rb
  123. +17 −0 lib/email_parser.rb
  124. +31 −0 lib/github_gem.rb
  125. +112 −0 lib/sanitizer.rb
  126. +105 −0 lib/smtp_tls.rb
  127. +16 −0 lib/tasks/auto_migrations_tasks.rake
  128. +99 −0 lib/tasks/freeze.rake
  129. +21 −0 lib/tasks/migrate.rake
  130. +59 −0 lib/tasks/mysql_tasks.rake
  131. +38 −0 lib/tasks/paperclip_tasks.rake
  132. +87 −0 lib/tasks/sass.rake
  133. +29 −0 lib/tasks/seed_fu_tasks.rake
  134. 0 log/KEEP
  135. +40 −0 public/.htaccess
  136. +30 −0 public/404.html
  137. +30 −0 public/422.html
  138. +30 −0 public/500.html
  139. +557 −0 public/app.html
  140. +10 −0 public/dispatch.cgi
  141. +24 −0 public/dispatch.fcgi
  142. +10 −0 public/dispatch.rb
  143. BIN public/favicon.ico
  144. +719 −0 public/gallery.html
  145. BIN public/images/add-sm.png
  146. BIN public/images/add.png
  147. BIN public/images/ads/cssrockstars.gif
  148. BIN public/images/ads/directorymonster.gif
  149. BIN public/images/ads/hostgator.gif
  150. BIN public/images/ads/site5-125px.gif
  151. BIN public/images/ads/templateworld.gif
  152. BIN public/images/ads/webmasterdesk.gif
  153. BIN public/images/ajax-loader.gif
  154. BIN public/images/ajax-loading.gif
  155. BIN public/images/back-arrow-sm.png
  156. BIN public/images/big-approve-button.png
  157. BIN public/images/big-delete-button.png
  158. BIN public/images/big-submit-button.png
  159. BIN public/images/buggy.png
  160. BIN public/images/buggy_mini.png
  161. BIN public/images/comments-mini.png
  162. BIN public/images/comments.png
  163. BIN public/images/comments2-mini.png
  164. BIN public/images/default_preview.png
  165. BIN public/images/default_screenshot.png
  166. BIN public/images/default_screenshots/medium.png
  167. BIN public/images/default_screenshots/original.png
  168. BIN public/images/default_screenshots/thumb.png
  169. BIN public/images/default_thumb.png
  170. BIN public/images/delete_thumbnail.png
  171. BIN public/images/download-gray.png
  172. BIN public/images/download-green.png
  173. BIN public/images/download-mini.png
  174. BIN public/images/download-sm.png
  175. BIN public/images/download.png
  176. BIN public/images/edit-sm.png
  177. BIN public/images/edit-text-sm.png
  178. BIN public/images/fadebg/1.png
  179. BIN public/images/fadebg/10.png
  180. BIN public/images/fadebg/11.png
  181. BIN public/images/fadebg/12.png
  182. BIN public/images/fadebg/13.png
  183. BIN public/images/fadebg/14.png
  184. BIN public/images/fadebg/15.png
  185. BIN public/images/fadebg/16.png
  186. BIN public/images/fadebg/17.png
  187. BIN public/images/fadebg/18.png
  188. BIN public/images/fadebg/19.png
  189. BIN public/images/fadebg/2.png
  190. BIN public/images/fadebg/20.png
  191. BIN public/images/fadebg/21.png
  192. BIN public/images/fadebg/22.png
  193. BIN public/images/fadebg/23.png
  194. BIN public/images/fadebg/24.png
  195. BIN public/images/fadebg/25.png
  196. BIN public/images/fadebg/26.png
  197. BIN public/images/fadebg/27.png
  198. BIN public/images/fadebg/28.png
  199. BIN public/images/fadebg/29.png
  200. BIN public/images/fadebg/3.png
  201. BIN public/images/fadebg/30.png
  202. BIN public/images/fadebg/4.png
  203. BIN public/images/fadebg/5.png
  204. BIN public/images/fadebg/6.png
  205. BIN public/images/fadebg/7.png
  206. BIN public/images/fadebg/8.png
  207. BIN public/images/fadebg/9.png
  208. BIN public/images/favorite-mini.png
  209. BIN public/images/favorite-off-mini.png
  210. BIN public/images/favorite-off.png
  211. BIN public/images/favorite.png
  212. BIN public/images/find.gif
  213. BIN public/images/footer.gif
  214. BIN public/images/gallery/iamww.gif
  215. BIN public/images/gallery/incg.gif
  216. BIN public/images/gallery/kavoon.jpg
  217. BIN public/images/gallery/matt.gif
  218. BIN public/images/gallery/mootools.gif
  219. BIN public/images/gallery/phillipnewton.gif
  220. BIN public/images/gallery/singularityconcepts.gif
  221. BIN public/images/gallery/theescapers.gif
  222. BIN public/images/gallery/totspot.gif
  223. BIN public/images/gallery/totspot_lg.gif
  224. BIN public/images/gallery/wpdesigner.gif
  225. BIN public/images/grid.png
  226. BIN public/images/happy.png
  227. BIN public/images/happy_mini.png
  228. BIN public/images/input.gif
  229. BIN public/images/lightview/blank.gif
  230. BIN public/images/lightview/close_innertop.png
  231. BIN public/images/lightview/close_large.png
  232. BIN public/images/lightview/close_small.png
  233. BIN public/images/lightview/inner_next.png
  234. BIN public/images/lightview/inner_prev.png
  235. BIN public/images/lightview/inner_slideshow_play.png
  236. BIN public/images/lightview/inner_slideshow_stop.png
  237. BIN public/images/lightview/loading.gif
  238. BIN public/images/lightview/next.png
  239. BIN public/images/lightview/overlay.png
  240. BIN public/images/lightview/prev.png
  241. BIN public/images/lightview/topclose.png
  242. BIN public/images/link.png
  243. BIN public/images/loading.gif
  244. BIN public/images/logo.png
  245. BIN public/images/logo2.png
  246. BIN public/images/logo3.png
  247. BIN public/images/logo4.png
  248. BIN public/images/logo5.png
  249. BIN public/images/logo6.png
  250. BIN public/images/nav.gif
  251. BIN public/images/navbg.gif
  252. BIN public/images/navbottom.gif
  253. BIN public/images/package.png
  254. BIN public/images/paging/green_black_bg1.gif
  255. BIN public/images/paging/green_black_bg2.gif
  256. BIN public/images/paging/meneame_bg.jpg
  257. BIN public/images/paging/onblack_bg1.gif
  258. BIN public/images/paging/onblack_bg2.gif
  259. BIN public/images/popup.png
  260. BIN public/images/progress.gif
  261. BIN public/images/rails.png
  262. BIN public/images/rating-sm.png
  263. BIN public/images/rating.png
  264. BIN public/images/ratings/0.png
  265. BIN public/images/ratings/1.png
  266. BIN public/images/ratings/2.png
  267. BIN public/images/ratings/3.png
  268. BIN public/images/ratings/4.png
  269. BIN public/images/ratings/5.png
  270. BIN public/images/ratings/star_half.png
  271. BIN public/images/ratings/star_off.png
  272. BIN public/images/ratings/star_on.png
  273. BIN public/images/rss-reflection-sm.png
  274. BIN public/images/rss-reflection.png
  275. BIN public/images/switch.png
  276. BIN public/images/template/__img01.gif
  277. BIN public/images/template/__img02.gif
  278. BIN public/images/template/__img03.gif
  279. BIN public/images/template/__img04.gif
  280. BIN public/images/template/__img05.gif
  281. BIN public/images/template/arrow.gif
  282. BIN public/images/template/arrow2.gif
  283. BIN public/images/template/arrow3.gif
  284. BIN public/images/template/arrow4.gif
  285. BIN public/images/template/arrow5.gif
  286. BIN public/images/template/arrow6.gif
  287. BIN public/images/template/arrow7.gif
  288. BIN public/images/template/b_post_comm.gif
  289. BIN public/images/template/b_view_slideshow.gif
  290. BIN public/images/template/bg.gif
  291. BIN public/images/template/board_bg.gif
  292. BIN public/images/template/dotted_black.gif
  293. BIN public/images/template/dotted_blue.gif
  294. BIN public/images/template/dotted_grey.gif
  295. BIN public/images/template/go.gif
  296. BIN public/images/template/header_bg.gif
  297. BIN public/images/template/i_box.gif
  298. BIN public/images/template/i_comm.gif
  299. BIN public/images/template/i_star.gif
  300. BIN public/images/template/logo.gif
Sorry, we could not display the entire diff because too many files (584) changed.
10 .gitignore
@@ -0,0 +1,10 @@
+.DS_Store
+config/amazon_s3.yml
+tmp/**/*
+log/*.log
+doc/api
+doc/app
+doc/plugins
+public/avatars
+public/screenshots
+public/images/screenshots
2 Capfile
@@ -0,0 +1,2 @@
+load 'deploy' if respond_to?(:namespace) # cap2 differentiator
+load 'config/deploy'
203 README
@@ -0,0 +1,203 @@
+== Welcome to Rails
+
+Rails is a web-application and persistence framework that includes everything
+needed to create database-backed web-applications according to the
+Model-View-Control pattern of separation. This pattern splits the view (also
+called the presentation) into "dumb" templates that are primarily responsible
+for inserting pre-built data in between HTML tags. The model contains the
+"smart" domain objects (such as Account, Product, Person, Post) that holds all
+the business logic and knows how to persist themselves to a database. The
+controller handles the incoming requests (such as Save New Account, Update
+Product, Show Post) by manipulating the model and directing data to the view.
+
+In Rails, the model is handled by what's called an object-relational mapping
+layer entitled Active Record. This layer allows you to present the data from
+database rows as objects and embellish these data objects with business logic
+methods. You can read more about Active Record in
+link:files/vendor/rails/activerecord/README.html.
+
+The controller and view are handled by the Action Pack, which handles both
+layers by its two parts: Action View and Action Controller. These two layers
+are bundled in a single package due to their heavy interdependence. This is
+unlike the relationship between the Active Record and Action Pack that is much
+more separate. Each of these packages can be used independently outside of
+Rails. You can read more about Action Pack in
+link:files/vendor/rails/actionpack/README.html.
+
+
+== Getting Started
+
+1. At the command prompt, start a new Rails application using the <tt>rails</tt> command
+ and your application name. Ex: rails myapp
+ (If you've downloaded Rails in a complete tgz or zip, this step is already done)
+2. Change directory into myapp and start the web server: <tt>script/server</tt> (run with --help for options)
+3. Go to http://localhost:3000/ and get "Welcome aboard: You’re riding the Rails!"
+4. Follow the guidelines to start developing your application
+
+
+== Web Servers
+
+By default, Rails will try to use Mongrel and lighttpd if they are installed, otherwise
+Rails will use WEBrick, the webserver that ships with Ruby. When you run script/server,
+Rails will check if Mongrel exists, then lighttpd and finally fall back to WEBrick. This ensures
+that you can always get up and running quickly.
+
+Mongrel is a Ruby-based webserver with a C component (which requires compilation) that is
+suitable for development and deployment of Rails applications. If you have Ruby Gems installed,
+getting up and running with mongrel is as easy as: <tt>gem install mongrel</tt>.
+More info at: http://mongrel.rubyforge.org
+
+If Mongrel is not installed, Rails will look for lighttpd. It's considerably faster than
+Mongrel and WEBrick and also suited for production use, but requires additional
+installation and currently only works well on OS X/Unix (Windows users are encouraged
+to start with Mongrel). We recommend version 1.4.11 and higher. You can download it from
+http://www.lighttpd.net.
+
+And finally, if neither Mongrel or lighttpd are installed, Rails will use the built-in Ruby
+web server, WEBrick. WEBrick is a small Ruby web server suitable for development, but not
+for production.
+
+But of course its also possible to run Rails on any platform that supports FCGI.
+Apache, LiteSpeed, IIS are just a few. For more information on FCGI,
+please visit: http://wiki.rubyonrails.com/rails/pages/FastCGI
+
+
+== Debugging Rails
+
+Sometimes your application goes wrong. Fortunately there are a lot of tools that
+will help you debug it and get it back on the rails.
+
+First area to check is the application log files. Have "tail -f" commands running
+on the server.log and development.log. Rails will automatically display debugging
+and runtime information to these files. Debugging info will also be shown in the
+browser on requests from 127.0.0.1.
+
+You can also log your own messages directly into the log file from your code using
+the Ruby logger class from inside your controllers. Example:
+
+ class WeblogController < ActionController::Base
+ def destroy
+ @weblog = Weblog.find(params[:id])
+ @weblog.destroy
+ logger.info("#{Time.now} Destroyed Weblog ID ##{@weblog.id}!")
+ end
+ end
+
+The result will be a message in your log file along the lines of:
+
+ Mon Oct 08 14:22:29 +1000 2007 Destroyed Weblog ID #1
+
+More information on how to use the logger is at http://www.ruby-doc.org/core/
+
+Also, Ruby documentation can be found at http://www.ruby-lang.org/ including:
+
+* The Learning Ruby (Pickaxe) Book: http://www.ruby-doc.org/docs/ProgrammingRuby/
+* Learn to Program: http://pine.fm/LearnToProgram/ (a beginners guide)
+
+These two online (and free) books will bring you up to speed on the Ruby language
+and also on programming in general.
+
+
+== Debugger
+
+Debugger support is available through the debugger command when you start your Mongrel or
+Webrick server with --debugger. This means that you can break out of execution at any point
+in the code, investigate and change the model, AND then resume execution! Example:
+
+ class WeblogController < ActionController::Base
+ def index
+ @posts = Post.find(:all)
+ debugger
+ end
+ end
+
+So the controller will accept the action, run the first line, then present you
+with a IRB prompt in the server window. Here you can do things like:
+
+ >> @posts.inspect
+ => "[#<Post:0x14a6be8 @attributes={\"title\"=>nil, \"body\"=>nil, \"id\"=>\"1\"}>,
+ #<Post:0x14a6620 @attributes={\"title\"=>\"Rails you know!\", \"body\"=>\"Only ten..\", \"id\"=>\"2\"}>]"
+ >> @posts.first.title = "hello from a debugger"
+ => "hello from a debugger"
+
+...and even better is that you can examine how your runtime objects actually work:
+
+ >> f = @posts.first
+ => #<Post:0x13630c4 @attributes={"title"=>nil, "body"=>nil, "id"=>"1"}>
+ >> f.
+ Display all 152 possibilities? (y or n)
+
+Finally, when you're ready to resume execution, you enter "cont"
+
+
+== Console
+
+You can interact with the domain model by starting the console through <tt>script/console</tt>.
+Here you'll have all parts of the application configured, just like it is when the
+application is running. You can inspect domain models, change values, and save to the
+database. Starting the script without arguments will launch it in the development environment.
+Passing an argument will specify a different environment, like <tt>script/console production</tt>.
+
+To reload your controllers and models after launching the console run <tt>reload!</tt>
+
+
+== Description of Contents
+
+app
+ Holds all the code that's specific to this particular application.
+
+app/controllers
+ Holds controllers that should be named like weblogs_controller.rb for
+ automated URL mapping. All controllers should descend from ApplicationController
+ which itself descends from ActionController::Base.
+
+app/models
+ Holds models that should be named like post.rb.
+ Most models will descend from ActiveRecord::Base.
+
+app/views
+ Holds the template files for the view that should be named like
+ weblogs/index.erb for the WeblogsController#index action. All views use eRuby
+ syntax.
+
+app/views/layouts
+ Holds the template files for layouts to be used with views. This models the common
+ header/footer method of wrapping views. In your views, define a layout using the
+ <tt>layout :default</tt> and create a file named default.erb. Inside default.erb,
+ call <% yield %> to render the view using this layout.
+
+app/helpers
+ Holds view helpers that should be named like weblogs_helper.rb. These are generated
+ for you automatically when using script/generate for controllers. Helpers can be used to
+ wrap functionality for your views into methods.
+
+config
+ Configuration files for the Rails environment, the routing map, the database, and other dependencies.
+
+db
+ Contains the database schema in schema.rb. db/migrate contains all
+ the sequence of Migrations for your schema.
+
+doc
+ This directory is where your application documentation will be stored when generated
+ using <tt>rake doc:app</tt>
+
+lib
+ Application specific libraries. Basically, any kind of custom code that doesn't
+ belong under controllers, models, or helpers. This directory is in the load path.
+
+public
+ The directory available for the web server. Contains subdirectories for images, stylesheets,
+ and javascripts. Also contains the dispatchers and the default HTML files. This should be
+ set as the DOCUMENT_ROOT of your web server.
+
+script
+ Helper scripts for automation and generation.
+
+test
+ Unit and functional tests along with fixtures. When using the script/generate scripts, template
+ test files will be generated for you and placed in this directory.
+
+vendor
+ External libraries that the application depends on. Also includes the plugins subdirectory.
+ This directory is in the load path.
10 Rakefile
@@ -0,0 +1,10 @@
+# Add your own tasks in files placed in lib/tasks ending in .rake,
+# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
+
+require(File.join(File.dirname(__FILE__), 'config', 'boot'))
+
+require 'rake'
+require 'rake/testtask'
+require 'rake/rdoctask'
+
+require 'tasks/rails'
27 app/controllers/application.rb
@@ -0,0 +1,27 @@
+# Filters added to this controller apply to all controllers in the application.
+# Likewise, all the methods added will be available for all controllers.
+
+class ApplicationController < ActionController::Base
+ helper :all # include all helpers, all the time
+
+ # Restful Auth Plugin
+ include AuthenticatedSystem
+
+ # notify of exceptions
+ include ExceptionNotifiable
+
+ # See ActionController::RequestForgeryProtection for details
+ # Uncomment the :secret if you're not using the cookie session store
+ # protect_from_forgery # :secret => '679db21358b0d645844f15fd7766b49b'
+
+ include Throttler
+
+
+ def check_spam(val)
+ if val == "4" or val == "four"
+ return true
+ else
+ return false
+ end
+ end
+end
13 app/controllers/base/project_subpage.rb
@@ -0,0 +1,13 @@
+class Base::ProjectSubpage < ApplicationController
+ before_filter :get_project
+
+ protected
+ def back_to_project(urlhash = "")
+ flash.keep
+ redirect_to(project_url(@project)+urlhash)
+ end
+
+ def get_project
+ @project ||= Project.find_by_id(params[:project_id])
+ end
+end
30 app/controllers/bookmarks_controller.rb
@@ -0,0 +1,30 @@
+class BookmarksController < Base::ProjectSubpage
+ def create
+ current_or_anon_user.add_bookmark(@project)
+ @project.bookmarks(true)
+ respond_to do |format|
+ format.html do
+ flash[:success] = "#{@project.title} is now bookmarked."
+ redirect_to @project
+ end
+ format.js { render_bookmark_control }
+ end
+ end
+
+ def destroy
+ current_or_anon_user.remove_bookmark(@project)
+ @project.bookmarks(true)
+ respond_to do |format|
+ format.html do
+ flash[:success] = "#{@project.title} is no longer bookmarked."
+ redirect_to @project
+ end
+ format.js { render_bookmark_control }
+ end
+ end
+
+ protected
+ def render_bookmark_control
+ render :partial => "bookmark_mini.html.haml", :layout => false, :locals => {:project => @project}
+ end
+end
84 app/controllers/comments_controller.rb
@@ -0,0 +1,84 @@
+class CommentsController < Base::ProjectSubpage
+
+ def index
+ back_to_project("#comments")
+ end
+
+ def new
+ back_to_project("#new-comment")
+ end
+
+ def create
+ @user = current_or_anon_user
+
+ # setup comment
+ @comment = @project.comments.build(params[:comment])
+ @comment.owner = @user
+ if @comment.save
+ @user.update_from_comment(@comment)
+ flash[:success] = "Comment has been added."
+ redirect_to project_comment_url(@project, @comment)
+ else
+ @project.comments(true)
+ render :template => "projects/show"
+ end
+ end
+
+ def show
+ @comment = get_comment
+
+ if @comment
+ back_to_project("#comment-#{@comment.id}")
+ else
+ flash[:notice] = "That comment no longer exists."
+ back_to_project
+ end
+ end
+
+ def edit
+ @comment = get_comment
+ return unless verify_comment_owner
+ end
+
+ def update
+ @comment = get_comment
+ return unless verify_comment_owner
+
+ if @comment.update_attributes(params[:comment])
+ flash[:success] = "Comment has been updated."
+ redirect_to project_comment_url(@project, @comment)
+ else
+ render :action => "edit"
+ end
+ end
+
+ def destroy
+ @comment = get_comment
+ return unless verify_comment_owner
+
+ if @comment.destroy
+ flash[:notice] = "Comment has been deleted."
+ redirect_to project_comments_url(@project)
+ else
+ flash[:error] = "Unable to delete comment."
+ redirect_to project_comments_url(@project)
+ end
+ end
+
+ protected
+ # retrieve a specific comment by id
+ def get_comment
+ @current_comment ||= @project.comments.find(params[:id])
+ end
+
+ # verify a person has access to update a comment
+ def verify_comment_owner
+ comment = get_comment
+ unless comment.owned_by?(current_or_anon_user)
+ redirect_to(comment.project || projects_url)
+ return false
+ end
+
+ return true
+ end
+end
2 app/controllers/comps_controller.rb
@@ -0,0 +1,2 @@
+class CompsController < ApplicationController
+end
96 app/controllers/hosted_instances_controller.rb
@@ -0,0 +1,96 @@
+class HostedInstancesController < Base::ProjectSubpage
+ def index
+ back_to_project
+ end
+
+ def new
+ back_to_project
+ end
+
+ def create
+ unless check_spam(params[:hosted_instance][:antispam])
+ flash[:error] = "You're either a spammer or bad at math. Either way... no link for you!"
+ return redirect_to @project
+ end
+
+ @hosted_instance = @project.hosted_instances.build(params[:hosted_instance])
+ @hosted_instance.owner = current_or_anon_user
+
+ if @hosted_instance.save
+ @project.mark_changed! unless current_or_anon_user.spammer?
+ flash[:success] = "New Application Link was created."
+ redirect_to @project
+ else
+ flash[:error] = "Unable to Save Link."
+ redirect_to project_url(@project)+"#hosted_instances_add"
+ end
+ end
+
+ def show
+ @hosted_instance = get_hosted_instance
+ return unless hosted_instance_exists?(@hosted_instance)
+
+ redirect_to @hosted_instance.url
+ end
+
+ def edit
+ @hosted_instance = get_hosted_instance
+ return unless hosted_instance_exists?(@hosted_instance)
+ return unless verify_user_access(@hosted_instance)
+ end
+
+ def update
+ @hosted_instance = get_hosted_instance
+ return unless hosted_instance_exists?(@hosted_instance)
+ return unless verify_user_access(@hosted_instance)
+
+ if @hosted_instance.update_attributes(params[:hosted_instance])
+ flash[:notice] = "Hosted Instance Updated"
+ back_to_project
+ else
+ render :action => "edit"
+ end
+ end
+
+ def destroy
+ @hosted_instance = get_hosted_instance
+ return unless hosted_instance_exists?(@hosted_instance)
+ return unless verify_user_access(@hosted_instance)
+
+ if @hosted_instance
+ flash[:notice] = "Link was deleted."
+ @hosted_instance.destroy
+ else
+ flash[:error] = "Unable to find hosted_instance to delete."
+ end
+
+ redirect_to @project
+ end
+
+ protected
+ def get_hosted_instance
+ @current_hosted_instance ||= HostedInstance.find_by_id(params[:id])
+ end
+
+ def hosted_instance_exists?(hosted_instance)
+ unless hosted_instance
+ flash[:error] = "Hosted Instance no longer exists."
+ back_to_project
+ return false
+ end
+ return true
+ end
+
+ def verify_user_access(hosted_instance)
+ unless hosted_instance.owned_by?(current_or_anon_user)
+ flash[:error] = "You don't have access to this"
+ back_to_project
+ return false
+ end
+
+ return true
+ end
+
+end
+
+
5 app/controllers/pages_controller.rb
@@ -0,0 +1,5 @@
+class PagesController < ApplicationController
+
+ def about
+ end
+end
275 app/controllers/projects_controller.rb
@@ -0,0 +1,275 @@
+class ProjectsController < ApplicationController
+
+ def index
+ @projects = find_projects
+ @upcoming = Project.upcoming
+ @my_projects = current_or_anon_user.projects
+
+ @latest_activities = Activity.latest
+
+ @top_downloaded = Project.top_downloaded
+ @top_bookmarked = Project.top_bookmarked
+
+ if throttled?
+ @tags = []
+ else
+ @tags = Project.tag_counts(:conditions => Project.in_gallery_conditions, :order => "name")
+ end
+
+ if params[:ajax]
+ render :partial => "projects/parts/grid", :locals => {:projects => @projects}, :layout => false
+ else
+ render
+ end
+
+ session[:page] = params[:page]
+ end
+
+ def feed
+ @projects = Project.latest
+
+ respond_to do |format|
+ format.atom do
+ render :action => "index.atom.builder"
+ end
+ end
+ end
+
+ def new
+ flash.keep
+ redirect_to root_url
+ end
+
+ def create
+ @project = Project.new(params[:project])
+ @project.owner_id = current_or_anon_user.id
+ if params["project"] and params["project"]["is_creator"] == "1"
+ @project.author_id = current_or_anon_user.id
+ @project.author_name = current_or_anon_user.to_s
+ end
+ if @project.save
+ current_or_anon_user.add_bookmark(@project)
+
+ flash[:success] = "Project has been created but not submitted. Customize it now with screenshots, files, and links before submitting it to the gallery."
+ redirect_to @project
+ else
+ if @project.title.blank?
+ flash[:error] = "Please give the application a name."
+ else
+ flash[:error] = "Application name is already taken."
+ end
+
+ redirect_to :back
+ end
+ end
+
+ def show
+ @project = Project.find_by_id(params[:id], :include => :comments)
+ @latest_activities = Activity.latest_for(@project)
+
+ unless @project
+ flash[:error] = "Unable to find project with the id: #{params[:id]}"
+ redirect_to root_url
+ return false
+ end
+
+ # verify that the project is submitted or that the currnet person is at least the owner
+ unless @project.is_submitted? or @project.owned_by?(current_or_anon_user)
+ flash[:error] = "That project is not yet accessible or your session may have expired."
+ redirect_to root_url
+ end
+ end
+
+ def edit
+ @project = get_project
+ return unless verify_owner(@project)
+
+ respond_to do |format|
+ format.js do
+ render :partial => "projects/form.html.haml", :layout => false, :locals => {:ajax => true}
+ end
+ format.html
+ end
+ end
+
+ def update
+ @project = get_project
+ return unless verify_owner(@project)
+
+ @project.update_attributes(params[:project])
+ @project.mark_changed!
+ flash[:success] = %("#{@project.title}" has been updated. )
+
+ respond_to do |format|
+ format.js do
+ render :partial => "projects/parts/ajax_result.html.haml", :locals => {:message => flash[:success]}
+ flash.discard
+ end
+ format.html do
+ redirect_to @project
+ end
+ end
+ end
+
+ def destroy
+ @project = get_project
+ return unless verify_owner(@project)
+
+ @project.destroy
+ flash[:notice] = %(Application "#{@project.title}" has been deleted.)
+ redirect_to root_url
+ end
+
+ # Mark a project as submitted
+ def submit
+ @project = get_project
+
+ if @project.owned_by?(current_or_anon_user)
+ @project.update_attribute(:is_submitted, true)
+ @project.mark_changed!
+ flash[:success] = %(Application "#{@project.title}" has been submitted. It will be shown in the "Upcoming" list until it's approved by an Admin. Adding additional screenshots and links will improve its chances of being accepted into the gallery.)
+ else
+ flash[:error] = "You no longer have access to this application. Your session may have expired."
+ end
+
+ redirect_to @project
+ end
+
+ # Mark a project as approved
+ def approve
+ @project = get_project
+ if logged_in? and current_user.admin?
+ @project.in_gallery = true
+ @project.is_submitted = true
+ @project.promoted_at = Time.now
+ @project.mark_changed
+ @project.save!
+ flash[:success] = %(Application "#{@project.title}" has been promoted. It is now in the gallery.)
+ else
+ flash[:error] = "Sorry, only admins are allowed to promote an application."
+ end
+
+ redirect_to root_url
+ end
+
+ # Rate a project
+ def rate
+ @project = get_project
+
+ # add rating for user
+ new_rating = params["rating"].to_i
+ if new_rating.between?(1, 5)
+ @project.rate new_rating, current_or_anon_user
+ end
+
+ respond_to do |format|
+ format.html do
+ redirect_to @project
+ end
+ format.js do
+ render :text => "", :layout => false
+ end
+ end
+ end
+
+ # Forward to a projects download url
+ def download
+ @project = get_project
+ @project.increment_downloads
+ redirect_to @project.download_url
+ end
+
+ # Ajax Update to show details
+ def details
+ @project = get_project
+
+ respond_to do |format|
+ format.html do
+ flash.keep
+ redirect_to @project
+ end
+ format.js do
+ render :partial => "projects/parts/details.html.haml", :locals => {:project => @project, :hidden => true}, :layout => false
+ end
+ end
+
+ end
+
+ # Ajax Update for Project Bookmarks
+ def bookmarks
+ @my_projects = current_or_anon_user.projects
+
+ respond_to do |format|
+ format.html do
+ redirect_to root_url
+ end
+ format.js do
+ render :partial => "bookmarks/bookmark_list.html.haml", :layout => false, :locals => {:projects => @my_projects}
+ end
+ end
+ end
+
+ # finds the next sequential project and redirect to it
+ def next
+ @project = get_project
+
+ # todo: find real one
+ redirect_to @project.next
+ end
+
+ # finds the previous sequential project and redirect to it
+ def previous
+ @project = get_project
+
+ redirect_to @project.previous
+ end
+
+ protected
+ # retrieves the current project from params[:id]
+ def get_project
+ @current_project ||= Project.find(params[:id])
+ end
+
+ # finds the current tag being queried on
+ def get_tag
+ @current_tag ||= Tag.find_by_name(params[:tag])
+ end
+
+ # find the projects to display based on the querystring
+ def find_projects
+ # try to find an associated tag
+ @tag = get_tag
+ @search_term = params[:q].strip unless params[:q].blank?
+
+ if @tag
+ @projects = @tag.taggings.map{|t| t.taggable if t.taggable.is_a? Project}
+ elsif @search_term
+ @projects = Project.search(@search_term, :page => params[:page], :per_page => AppConfig.projects_per_page)
+ else
+ @projects = Project.paginate(:conditions => Project.in_gallery_conditions, :order => "promoted_at DESC", :page => params[:page], :per_page => AppConfig.projects_per_page)
+ end
+
+ end
+
+
+ # verify that the current user owns a project
+ def verify_owner(project)
+ if project.owned_by?(current_or_anon_user)
+ return true
+ else
+
+ # render an output
+ respond_to do |format|
+ flash[:error] = "You don't have access to edit this application."
+ format.js do
+ render :text => flash[:error], :layout => false
+ flash.discard
+ end
+ format.html do
+ redirect_to project
+ end
+ end
+ return false
+ end
+ end
+end
106 app/controllers/screenshots_controller.rb
@@ -0,0 +1,106 @@
+class ScreenshotsController < Base::ProjectSubpage
+ def show
+ @screenshot = get_screenshot
+ if @screenshot
+ redirect_to @screenshot.public_filename
+ else
+ flash[:notice] = "That screenshot no longer exists."
+ back_to_project
+ end
+ end
+
+ def create
+ # check original size of screenshots
+ orig_size = @project.screenshots.size
+
+ @valid_screenshots = []
+ @invalid_screenshots = []
+
+ params[:screenshots].each do |screenshot|
+ @screenshot = @project.screenshots.build(screenshot)
+ @screenshot.owner = current_or_anon_user
+ if @screenshot.save
+ @valid_screenshots << @screenshot
+ else
+ @invalid_screenshots << @screenshot
+ end
+ end
+
+ if @valid_screenshots.size > 0
+ begin
+ @project.mark_changed! unless current_or_anon_user.spammer?
+ rescue
+ logger.error("UNABLE TO UPLOAD SCREENSHOTS")
+ end
+
+ if orig_size == 0
+ @project.set_default_screenshot(@valid_screenshots.first)
+ end
+
+ flash[:success] = "Screenshots Uploaded."
+ redirect_to project_url(@project)
+ else
+ @invalid_screenshots.each{|screenshot| set_flash(screenshot) }
+ redirect_to project_url(@project)+"#screenshots_add"
+ end
+
+ end
+
+ def destroy
+ @screenshot = get_screenshot
+ if @screenshot
+ flash[:notice] = "Screenshot was deleted."
+ @screenshot.destroy
+ else
+ flash[:error] = "Unable to find screenshot to delete."
+ end
+
+ redirect_to @project
+ end
+
+ # sets the default screenshot for a project
+ def set
+ @screenshot = get_screenshot
+ if @screenshot and @screenshot.owned_by?(current_or_anon_user)
+ flash[:success] = "Default Application Screenshot has been updated."
+ @project.set_default_screenshot(@screenshot)
+ else
+ flash[:error] = "Unable to set default screenshot."
+ end
+
+ redirect_to @project
+ end
+
+ # unsupported actions
+ def index
+ back_to_project
+ end
+
+ def new
+ back_to_project
+ end
+
+ def edit
+ back_to_project
+ end
+
+ protected
+
+ def get_screenshot
+ @current_screenshot ||= Screenshot.find_by_id(params[:id])
+ end
+
+ def set_flash(screenshot)
+ if screenshot.errors.on(:name)
+ flash[:error] = "No File Uploaded."
+ elsif screenshot.errors.on(:content_type)
+ flash[:error] = "Please upload a valid image (png, gif, or jpg)."
+ elsif screenshot.errors.on(:size)
+ flash[:error] = "Please limit the size to 1meg for screenshots. Bandwidth doesn't grow on trees you know!"
+ else
+ flash[:error] = "Sorry, the upload failed."
+ logger.error("Bad Upload! #{screenshot.errors.to_yaml}")
+ end
+ end
+
+end
51 app/controllers/sessions_controller.rb
@@ -0,0 +1,51 @@
+# This controller handles the login/logout function of the site.
+class SessionsController < ApplicationController
+ # Be sure to include AuthenticationSystem in Application Controller instead
+ include AuthenticatedSystem
+
+ before_filter :check_login, :only => [:new, :create]
+
+ # render new.rhtml
+ def new
+ @login = Login.new
+ end
+
+ def create
+ @login = Login.new(params[:login])
+ self.current_user = User.login_with(@login)
+
+ if logged_in?
+ if @login.remember_me?
+ self.current_user.remember_me
+ cookies[:auth_token] = { :value => self.current_user.remember_token , :expires => self.current_user.remember_token_expires_at }
+ end
+ redirect_back_or_default('/')
+ flash[:success] = "Logged in successfully"
+ else
+ render :action => 'new'
+ end
+ end
+
+ def destroy
+ self.current_user.forget_me if logged_in?
+ cookies.delete :auth_token
+ reset_session
+ flash[:notice] = "You have been logged out."
+ redirect_back_or_default('/')
+ end
+
+ def show
+ end
+
+ def index
+ redirect_to session_url
+ end
+
+ private
+ def check_login
+ if logged_in?
+ redirect_to session_url
+ return false
+ end
+ end
+end
86 app/controllers/users_controller.rb
@@ -0,0 +1,86 @@
+class UsersController < ApplicationController
+ # Be sure to include AuthenticationSystem in Application Controller instead
+ include AuthenticatedSystem
+
+ # Protect these actions behind an admin login
+ # before_filter :admin_required, :only => [:suspend, :unsuspend, :destroy, :purge]
+ before_filter :find_user, :only => [:suspend, :unsuspend, :destroy, :purge]
+
+ # render new.rhtml
+ def new
+ if logged_in?
+ flash[:notice] = "You are already logged in."
+ redirect_to root_url
+ else
+ @user = anon_user
+ end
+ end
+
+ def create
+ cookies.delete :auth_token
+ # protects against session fixation attacks, wreaks havoc with
+ # request forgery protection.
+ # uncomment at your own risk
+ # reset_session
+ @user = anon_user || User.new
+ @user.attributes = params[:user]
+ @user.signed_up = true
+ @user.save!
+
+ # register user
+ @user.register!
+
+ self.current_user = @user
+ redirect_back_or_default('/')
+ flash[:success] = "Thanks for signing up! You are now logged in. We've sent you an email to confirm your email address, which you'll need in order to log in again."
+ rescue ActiveRecord::RecordInvalid
+ render :action => 'new'
+ end
+
+ def spammer
+ spammer = User.find(params[:id])
+ if spammer
+ spammer.is_spammer!
+ flash[:success] = "Spammer has been neutralized."
+ else
+ flash[:error] = "No such spammer exists."
+ end
+
+ redirect_to root_url
+ end
+
+ def activate
+ self.current_user = params[:id].blank? ? :false : User.find_by_activation_code(params[:id])
+ if logged_in? && !current_user.active?
+ current_user.activate!
+ flash[:success] = "Signup complete!"
+ end
+ redirect_back_or_default('/')
+ end
+
+ def suspend
+ @user.suspend!
+ redirect_to users_path
+ end
+
+ def unsuspend
+ @user.unsuspend!
+ redirect_to users_path
+ end
+
+ def destroy
+ @user.delete!
+ redirect_to users_path
+ end
+
+ def purge
+ @user.destroy
+ redirect_to users_path
+ end
+
+protected
+ def find_user
+ @user = User.find(params[:id])
+ end
+
+end
121 app/controllers/versions_controller.rb
@@ -0,0 +1,121 @@
+class VersionsController < Base::ProjectSubpage
+
+ def index
+ back_to_project
+ end
+
+ def new
+ back_to_project
+ end
+
+ def create
+ unless check_spam(params[:version][:antispam])
+ flash[:error] = "You're either a spammer or bad at math. Either way... no link for you!"
+ return redirect_to @project
+ end
+
+ # check original size of versions
+ orig_size = @project.versions.size
+
+ @version = @project.versions.build(params[:version])
+ @version.owner = current_or_anon_user
+
+ if @version.save
+ @project.mark_changed! unless current_or_anon_user.spammer?
+
+ if orig_size == 0
+ @project.set_default_version(@version)
+ end
+
+ flash[:success] = "New Application Version was uploaded."
+ redirect_to @project
+ else
+ flash[:error] = "Unable to Save Version."
+ redirect_to project_url(@project)+"#versions_add"
+ end
+ end
+
+ def show
+ @version = get_version
+ return unless version_exists?(@version)
+
+ # increment download count if its the default url
+ if @version.public_filename == @project.download_url
+ @project.increment_downloads
+ end
+ redirect_to @version.public_filename
+ end
+
+ def edit
+ @version = get_version
+ return unless version_exists?(@version)
+ return unless verify_user_access(@version)
+
+ end
+
+ def update
+ @version = get_version
+ return unless version_exists?(@version)
+ return unless verify_user_access(@version)
+
+ if @version.update_attributes(params[:version])
+ flash[:notice] = "Version Updated"
+ back_to_project
+ else
+ render :action => "edit"
+ end
+ end
+
+ def destroy
+ @version = get_version
+ return unless version_exists?(@version)
+ return unless verify_user_access(@version)
+
+ flash[:notice] = "Version was deleted."
+ @version.destroy
+
+ back_to_project
+ end
+
+ # sets the default version for a project
+ def set
+ @version = get_version
+ return unless version_exists?(@version )
+
+ # only allow project owners to set the default version
+ if @version and @version.project and @version.project.owned_by?(current_or_anon_user)
+ @version.update_attribute(:updated_at, Time.now)
+ flash[:success] = "Default Project Download has been changed."
+ @project.set_default_version(@version)
+ else
+ flash[:error] = "Version no longer exists."
+ end
+
+ back_to_project
+ end
+
+ protected
+ def get_version
+ @current_version ||= Version.find_by_id(params[:id])
+ end
+
+ def version_exists?(version)
+ unless version
+ flash[:error] = "Version no longer exists."
+ back_to_project
+ return false
+ end
+ return true
+ end
+
+ def verify_user_access(version)
+ unless version.owned_by?(current_or_anon_user)
+ flash[:error] = "You don't have access to this"
+ back_to_project
+ return false
+ end
+
+ return true
+ end
+
+end
85 app/helpers/application_helper.rb
@@ -0,0 +1,85 @@
+# Methods added to this helper will be available to all templates in the application.
+module ApplicationHelper
+ include TagsHelper
+
+ # display flash_boxes (unless its already been shown)
+ def flash_boxes
+ unless @flash_shown
+ @flash_shown = true
+ partial "layouts/flash_boxes"
+ else
+ ""
+ end
+ end
+
+ # returns the controller & action
+ def action_path
+ "#{params[:controller]}/#{params[:action]}"
+ end
+
+ # return the css class for the current controller and action
+ def body_class
+ classes = ""
+ classes << "container"
+ classes << " "
+ classes << controller.controller_name
+ classes << "-"
+ classes << controller.action_name
+ classes << " "
+ unless production?
+ classes << "debug"
+ end
+
+ return classes.strip
+ end
+
+ def production?
+ ENV["RAILS_ENV"] == "production"
+ end
+
+ # returns either the new_arg or the edit_arg depending on if the action is a new or edit action
+ def new_or_edit(new_arg, edit_arg, other = nil)
+ if is_new?
+ return new_arg
+ elsif is_edit?
+ return edit_arg
+ else
+ return other
+ end
+ end
+
+ def is_new?
+ action = params[:action]
+ action == "new" || action == "create"
+ end
+
+ def is_edit?
+ action = params[:action]
+ action == "edit" || action == "update"
+ end
+
+ def current_year
+ Time.now.strftime('%Y')
+ end
+
+ def paging(page_data, style = :sabros)
+ return unless page_data.class == WillPaginate::Collection
+ will_paginate(page_data, :class => "pagination #{style}", :inner_window => 3)
+ end
+
+ def error_messages_for(name, options = {})
+ super(name, {:id => "error_explanation", :class => "error"}.merge(options))
+ end
+
+ def hide_if(condition)
+ if condition
+ {:style => "display:none"}
+ else
+ {}
+ end
+ end
+
+ def hide_unless(condition)
+ hide_if(!condition)
+ end
+end
15 app/helpers/comments_helper.rb
@@ -0,0 +1,15 @@
+module CommentsHelper
+ # display comment edit/delete if applicable
+ def comment_actions(comment)
+ if comment.owned_by?(current_or_anon_user)
+ link_actions = [link_to("Edit Comment", edit_project_comment_url(@project, comment)),
+ link_to("Delete Comment", project_comment_url(@project, comment), :method => :delete, :confirm => "Are you sure you want to delete this?")]
+
+ if admin?
+ link_actions << link_to("Spam!", spammer_user_url(comment.owner), :method => :put, :confirm => "Are you sure you want to mark this person as a spammer?")
+ end
+
+ content_tag(:div, link_actions.join(" | "), :class => "actions")
+ end
+ end
+end
2 app/helpers/hosted_instances_helper.rb
@@ -0,0 +1,2 @@
+module HostedInstancesHelper
+end
55 app/helpers/javascript_helper.rb
@@ -0,0 +1,55 @@
+module JavascriptHelper
+
+ # Add javascripts to page
+ def javascripts(options = {})
+ [
+ prototype,
+ jquery,
+
+ javascript_tag("$j = jQuery.noConflict();"),
+ javascript(include_javascripts("jquery.ext")),
+ javascript(include_javascripts("libraries")),
+ javascript(include_javascripts("common")),
+ javascript(include_javascripts("components")),
+ page_javascripts(options),
+
+ javascript("application"),
+ javascript("behaviors")
+ ].flatten.join("\n")
+ end
+
+ # Include prototype
+ def prototype
+ [
+ javascript("prototype"),
+ javascript("scriptaculous/scriptaculous")
+ ]
+ end
+
+ # Include JQuery
+ def jquery
+ if AppConfig.minimize
+ javascript("jquery.min.js")
+ else
+ javascript("jquery")
+ end
+ end
+
+ # returns a list of *css file paths* for a sass directory
+ def include_javascripts(path)
+ if AppConfig.minimize
+ "min/#{path}.js"
+ else
+ # Good for debugging
+ javascript_list = Dir["#{RAILS_ROOT}/public/javascripts/#{path}/*.js"]
+
+ result = []
+ javascript_list.each do |javascript|
+ result << javascript.gsub("#{RAILS_ROOT}/public/javascripts/", "")
+ end
+
+ return result
+ end
+ end
+
+end
32 app/helpers/meta_helper.rb
@@ -0,0 +1,32 @@
+module MetaHelper
+ def meta_tags
+ %(
+ <meta name="keywords" content="#{meta_keywords}" />
+ <meta name="description" content="#{meta_description}" />
+ )
+ end
+
+ # Get/Set Meta Keywords
+ def meta_keywords(meta_keywords = nil)
+ if meta_keywords
+ @__meta_keywords = meta_keywords
+ else
+ @__meta_keywords ||= ""
+ @__meta_keywords = AppConfig.default_meta_keywords if @__meta_keywords.blank?
+ end
+ return @__meta_keywords
+ end
+
+ # Get/Set Meta Description
+ def meta_description(meta_description = nil)
+ if meta_description
+ @__meta_description = meta_description
+ else
+ @__meta_description ||= ""
+ @__meta_description = AppConfig.default_meta_description if @__meta_description.blank?
+ end
+ return @__meta_description
+ end
+
+
+end
2 app/helpers/pages_helper.rb
@@ -0,0 +1,2 @@
+module PagesHelper
+end
181 app/helpers/projects_helper.rb
@@ -0,0 +1,181 @@
+module ProjectsHelper
+
+ def activity_display(activity, options = {})
+
+ haml_tag :span, :class => "activity #{activity.target_type}".downcase do
+
+ puts activity.user_name
+ puts " "
+ puts activity.action_name
+ puts " "
+
+ puts activity.midsentence
+ puts " "
+
+
+ puts activity_target_link(activity)
+ puts " "
+ puts activity.endconnector
+
+ if activity.project_id
+ puts " "
+ puts link_to(activity.project_name.to_s+".", project_url(:id => activity.project_id))
+ else
+ puts "."
+ end
+
+ # display time
+ haml_tag :span, :class => "when" do
+ puts time_ago_in_words(activity.happened_at)
+ puts " ago"
+ end
+
+ end
+ end
+
+ def activity_target_link(activity)
+ if activity.project_id and activity.target_id
+ target_link = nil
+
+ # yeeeaah, we have to do this the long way in order to save N+1 database calls
+ if activity.target_type == "Comment"
+ target_link = project_comment_url(:project_id => activity.project_id, :id => activity.target_id)
+ elsif activity.target_type == "HostedInstance"
+ target_link = project_hosted_instance_url(:project_id => activity.project_id, :id => activity.target_id)
+ elsif activity.target_type == "Version"
+ target_link = project_version_url(:project_id => activity.project_id, :id => activity.target_id)
+ elsif activity.target_type == "Screenshot"
+ target_link = project_screenshot_url(:project_id => activity.project_id, :id => activity.target_id)
+ end
+
+ link_to_if target_link, activity.target_name, target_link
+ else
+ return activity.target_name
+ end
+
+ end
+
+
+ def ratings(project, options={})
+
+ rating_size = options.delete(:rating_size) || ""
+ detailed = options.delete(:detailed) || false
+
+ haml_tag :div, :class => "post-ratings" do
+ voting(project, detailed)
+ ratings_control(project, rating_size)
+ end
+ end
+
+ def ratings_control(project, size = "")
+ haml_tag :div, :class => "ratings-control #{size}", :title => rating_explain(project) do
+ puts link_to(project.rating_in_halves.to_s, rate_project_url(project), :class => "rate-init", :rel => project.id.to_s)
+ end
+ end
+
+ def bookmark_control(project)
+
+ haml_tag :span, :class => "bookmark-control" do
+ if current_or_anon_user.bookmarked?(project)
+ puts link_to("unbookmark it", project_bookmark_url(project), :method => :delete)
+ puts link_to_image("favorite.png", project_bookmark_url(project), :method => :delete, :title => "Click to Remove Bookmark")
+ else
+ puts link_to("bookmark it", project_bookmark_url(project), :method => :post)
+ puts link_to_image("favorite-off.png", project_bookmark_url(project), :method => :post, :title => "Click to Add Bookmark")
+ end
+ puts br
+ puts "Bookmarked by "+pluralize(project.bookmarks.size, "person")
+ end
+ end
+
+ # Render a mini bookmark button with count
+ def bookmark_mini(project)
+ haml_tag :span, :class => "bookmark-mini" do
+ # Add Bookmark Button
+ bookmark_count = pluralize(project.bookmarks.size, "person")+" bookmarked this application"
+ if current_or_anon_user.bookmarked?(project)
+ puts link_to_image("favorite-mini.png", project_bookmark_url(project), :method => :delete, :title => bookmark_count, :class => "bookmark-button remove")
+ else
+ puts link_to_image("favorite-off-mini.png", project_bookmark_url(project), :method => :post, :title => bookmark_count, :class => "bookmark-button add")
+ end
+ end
+ end
+
+ def rating_explain(project)
+ "Rated by #{pluralize(project.rated_count, 'person')} with an average of "+sprintf("%.01f.", project.rating_average || 0)
+ end
+
+ def voting(project, detailed = false)
+
+ haml_tag :div, :class => "votes" do
+ if detailed
+ bookmark_control(project)
+ else
+ # Add Download Button
+ unless project.download_url.blank?
+ puts content_tag(:span, link_to_image("download-mini.png", download_project_url(project), :title => "Download Latest Version"))
+ end
+
+ # Render the mini bookmark buttons
+ bookmark_mini(project)
+
+ # Add Comments Button
+ puts content_tag(:span, link_to_image("comments2-mini.png", project_comments_url(project), :title => pluralize(project.comments.size, "comment")))
+ end
+ end
+ end
+
+ def check_empty(collection, name = nil, &block)
+ if collection.nil? or collection.empty?
+ inner_html = capture_haml(&block) if block_given?
+
+ haml_tag(:p, "There are no #{name} currently associated with this application. #{inner_html}", :class => "empty")
+
+
+ end
+ end
+
+
+ def grid_title
+ if @tag
+ title = pluralize(@tag.taggings.size, 'project')+" tagged with \"<strong>#{@tag.name}</strong>\""
+ elsif @search_term and @projects.respond_to?(:total_entries)
+ title = pluralize(@projects.total_entries, "search result")+" found for \"<strong>#{@search_term}</strong>\""
+ end
+
+ # format the title with an h3
+ unless title.blank?
+ return content_tag(:h3, title)
+ end
+ end
+
+ # Display an approve button for a project (if permissions allow)
+ def approve_button(project)
+
+ if logged_in? and admin?
+
+ haml_tag :div, :class => "actions text-center" do
+ puts br
+ puts link_to(image_tag("big-approve-button.png"),
+ approve_project_url(@project),
+ :method => :put,
+ :confirm => "This will promote the application to the gallery.")
+ end
+ end
+ end
+
+ # Allow showing an article IF:
+ # - the current user is a spammer. let the spammers eat their f*$&ing spam
+ # - OR -
+ # - the current item ISNT being posted by a spammer
+ def spam_shield?(project_item)
+ return true unless project_item and project_item.owner
+
+ if current_or_anon_user.spammer? or !project_item.owner.spammer?
+ return true
+ else
+ return false
+ end
+ end
+
+end
35 app/helpers/stylesheet_helper.rb
@@ -0,0 +1,35 @@
+module StylesheetHelper
+ # include stylesheets
+ def stylesheets(options = {})
+ [
+ stylesheet("blueprint"),
+ stylesheet("forms"),
+ stylesheet(sass_files),
+ page_stylesheets(options)
+ ].join("\n")
+ end
+
+ # List of Sass FIles
+ def sass_files
+ if AppConfig.minimize
+ ["min/application", "min/common", "min/components"]
+ else
+ ["application", include_sass("common"), include_sass("components")]
+ end
+ end
+
+ # returns a list of *css file paths* for a sass directory
+ def include_sass(path)
+ # include common and component sass
+ sass_styles = Dir["#{RAILS_ROOT}/public/stylesheets/sass/#{path}/*.sass"]
+
+ # convert to css paths
+ css_styles = []
+ sass_styles.each do |sass_path|
+ css_path = sass_path.gsub("#{RAILS_ROOT}/public/stylesheets/sass/", "").gsub(".sass", ".css")
+ css_styles << css_path
+ end
+
+ return css_styles
+ end
+end
43 app/helpers/tabs_helper.rb
@@ -0,0 +1,43 @@
+module TabsHelper
+ def tabs(options={}, &block)
+ # set up the options class param
+ options[:class] ||= ""
+
+ # append the css class "tabs" if it doesnt already exist
+ options[:class] << " tabs" unless options[:class].include?("tabs")
+
+ # allow ul_options
+ nav_options = options.delete(:nav_options) || {}
+
+ # build the html for the tabs
+ haml_tag :div, options do
+ # initialize instance navhtml
+ @__tabs_navhtml = ""
+
+ # build inner content
+ inner_content = capture_haml(&block)
+
+ # render navs first
+ puts content_tag(:ul, @__tabs_navhtml, nav_options)
+
+ # render inner content
+ puts inner_content
+
+ # clear instance variable
+ @__tabs_navhtml = nil
+ end
+ end
+
+ # Give the tab a name and unique id
+ def tab(name, tab_id , options={}, &block)
+
+ # append an element to our nav_html
+ @__tabs_navhtml << content_tag(:li, link_to(name, "##{tab_id}", :title => name))
+
+ # build our tab
+ haml_tag :div, options.merge(:id => tab_id) do
+ puts capture_haml(&block)
+ puts content_tag(:div, "", :style => "clear: both")
+ end
+ end
+end
100 app/helpers/tag_helper.rb
@@ -0,0 +1,100 @@
+module TagHelper
+ def br
+ "<br />"
+ end
+
+ def hr
+ "<hr />"
+ end
+
+ def space
+ "<hr class='space' />"
+ end
+
+ def anchor(anchor_name)
+ "<a name='#{anchor_name}'></a>"
+ end
+
+ def button(text, options = {})
+ submit_tag(text, options)
+ end
+
+ def clear_tag(tag, direction = nil)
+ "<#{tag} class=\"clear#{direction}\"></#{tag}>"
+ end
+
+ def clear(direction = nil)
+ clear_tag(:div, direction)
+ end
+
+ def lorem
+ "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
+ end
+
+ def hidden(is_hidden = true)
+ if is_hidden
+ {:style => "display:none"}
+ else
+ {}
+ end
+ end
+
+ def hidden_if(is_hidden)
+ hidden(is_hidden)
+ end
+
+ def hidden_unless(is_hidden)
+ hidden(!is_hidden)
+ end
+
+ # adds a "first" class if an index is zero
+ # hook this up to the partial counter
+ def is_first(index)
+ if index.nonzero?
+ return {}
+ else
+ return {:class => "first"}
+ end
+ rescue
+ return {}
+ end
+
+ def clearbit_icon(icon, color, options = {})
+ image_tag "clearbits/#{icon}.gif", {:class => "clearbits #{color}", :alt => icon}.merge(options)
+ end
+
+ def progress(img_path = nil)
+ # set default progress image
+ img_path ||= "progress.gif"
+
+ content_tag :div, image_tag(img_path), :class => "progress hidden"
+ end
+
+ def delete_link(*args)
+ options = {:method => :delete, :confirm => "Are you sure you want to delete this?"}.merge(args.extract_options!)
+ args << options
+ link_to *args
+ end
+
+ def link_to_block(*args, &block)
+ content = capture_haml(&block)
+ return link_to(content, *args)
+ end
+
+ def link_to_image(img_url, link_url, options={})
+
+ link = []
+ label = options.delete(:label)
+
+ link << link_to(image_tag(img_url), link_url, options)
+ link << link_to(label, link_url, options) if label
+
+ link.join(" ");
+ end
+
+ # pixel spacing helper
+ def pixel(options = {})
+ image_tag "pixel.png", options
+ end
+
+end
299 app/models/activity.rb
@@ -0,0 +1,299 @@
+# Activities are of the format:
+# [user_name] [action_name] [midsentence] [target_name] [endconnector] [project_name]
+# user_name comes with an associated user_id
+# target_name comes with an associated polymorphic association for target
+# project_name comes with an associated project
+#
+# SOME EXAMPLES:
+#
+# Legend
+# 1 => user_name
+# 2 => action_name
+# 3 => midsentence
+# 4 => target_name
+# 5 => endconnector
+# 6 => project_name
+#
+# examples:
+# [Joe] [uploaded] [a new] [screenshot] [to] [LovdByLess]
+# 1 2 3 4 5 6
+#
+#
+# examples:
+# [Nick] [create] [a new] [project:] [] [LovdByLess]
+# 1 2 3 4 5 6
+#
+# or maybe:
+# [I] [did not have sexual relations] [with] [that woman] [] []
+# 1 2 3 4 5 6
+
+
+class Activity < ActiveRecord::Base
+ belongs_to :user
+ belongs_to :target, :polymorphic => true
+ belongs_to :project
+
+ #
+ def self.latest(limit = 20)
+ find(:all, :limit => limit, :order => "happened_at DESC")
+ end
+
+ # Find the latest activities for a given target (user, project, or anything else)
+ def self.latest_for(target, limit = 20)
+ # build conditions
+ conditions = {}
+ if target.is_a? User
+ conditions = {:user_id => target.id}
+ elsif target.is_a? Project
+ conditions = {:project_id => target.id}
+ else
+ conditions = {:target_id => target.id, :target_type => target.class.to_s}
+ end
+
+ # execute search
+ return find(:all, :conditions => conditions, :limit => limit, :order => "happened_at DESC")
+ end
+
+ # call the associated create method
+ def self.create_from(model)
+
+ # skip activity records for spam
+ if model.respond_to? :owner
+ if model.owner.spammer?
+ return true
+ end
+ end
+
+
+ # initialize the model states
+ # its either new, updated, or deleted
+ is_new, is_updated, is_deleted = false, false, false
+ is_new = (model.created_at == model.updated_at)
+ is_updated = !is_new
+
+ # check if its deleted
+ if model.frozen?
+ is_new, is_updated, is_deleted = false, false, true
+ end
+
+ # find and call the associated activity creator
+ model_name = model.class.to_s.tableize
+ method_name = :"activity_for_#{model_name}"
+ if respond_to? method_name
+ send method_name, model, is_new, is_updated, is_deleted
+ end
+ end
+
+ protected
+ # Someone created/updated a project
+ # create: [Joe] [created] [a new application:] [] [] [LovdByLess]
+ # update: [Joe] [updated] [the application details of] [] [] [LovdByLess]
+ # destroy: [Joe] [deleted] [the application:] [] [] [LovdByLess]
+ def self.activity_for_projects(project, is_new, is_updated, is_deleted)