├── public ├── favicon.gif ├── favicon.ico ├── images │ ├── hd.jpg │ ├── ai1.png │ ├── ai2.png │ ├── ai3.png │ ├── ai4.png │ ├── ai5.png │ ├── ai6.png │ ├── ai7.png │ ├── ai8.png │ └── rails.png ├── design │ ├── i │ │ ├── ai1.png │ │ ├── ai2.png │ │ ├── ai3.png │ │ ├── ai4.png │ │ ├── ai5.png │ │ ├── ai6.png │ │ ├── ai7.png │ │ ├── ai8.png │ │ ├── hd.jpg │ │ ├── img1.png │ │ ├── img2.png │ │ ├── img3.png │ │ ├── img4.png │ │ ├── img5.png │ │ ├── img6.png │ │ ├── image-1.png │ │ ├── jabz-logo.png │ │ └── jonas-jared-jacek_50x50.png │ ├── readme.txt │ ├── index.html │ └── s │ │ └── a.css ├── javascripts │ ├── application.js │ ├── jquery.make_expandable.js │ └── jrails.min.js ├── robots.txt ├── 422.html ├── 404.html ├── 500.html └── stylesheets │ ├── highlight-github.css │ └── styles.css ├── app ├── views │ ├── welcome │ │ └── index.html.erb │ ├── home │ │ └── index.html.erb │ ├── snippets │ │ ├── _fields.html.haml │ │ ├── new.html.haml │ │ ├── edit.html.haml │ │ ├── show.html.haml │ │ └── index.html.haml │ ├── user_sessions │ │ └── new.html.haml │ ├── users │ │ ├── edit.html.haml │ │ └── new.html.haml │ └── layouts │ │ └── frontend.html.haml ├── helpers │ ├── home_helper.rb │ ├── users_helper.rb │ ├── user_sessions_helper.rb │ ├── snippets_helper.rb │ └── application_helper.rb ├── controllers │ ├── welcome_controller.rb │ ├── home_controller.rb │ ├── user_sessions_controller.rb │ ├── application_controller.rb │ ├── users_controller.rb │ └── snippets_controller.rb └── models │ ├── user_session.rb │ ├── snippet.rb │ └── user.rb ├── spec ├── rcov.opts ├── spec.opts ├── views │ ├── users │ │ └── new.html.haml_spec.rb │ └── user_sessions │ │ └── new.html.haml_spec.rb ├── helpers │ ├── snippets_helper_spec.rb │ ├── application_helper_spec.rb │ └── user_sessions_helper_spec.rb ├── controllers │ ├── home_controller_spec.rb │ ├── users_controller_spec.rb │ ├── user_sessions_controller_spec.rb │ └── snippets_controller_spec.rb ├── spec_helper.rb ├── support │ └── blueprints.rb └── models │ ├── snippet_spec.rb │ └── user_spec.rb ├── .gitignore ├── vendor └── plugins │ ├── acts_as_taggable_on_steroids │ ├── init.rb │ ├── test │ │ ├── fixtures │ │ │ ├── special_post.rb │ │ │ ├── magazines.yml │ │ │ ├── subscriptions.yml │ │ │ ├── users.yml │ │ │ ├── magazine.rb │ │ │ ├── subscription.rb │ │ │ ├── post.rb │ │ │ ├── photo.rb │ │ │ ├── user.rb │ │ │ ├── tags.yml │ │ │ ├── photos.yml │ │ │ ├── posts.yml │ │ │ └── taggings.yml │ │ ├── database.yml │ │ ├── tagging_test.rb │ │ ├── tags_helper_test.rb │ │ ├── schema.rb │ │ ├── tag_test.rb │ │ ├── abstract_unit.rb │ │ ├── tag_list_test.rb │ │ └── acts_as_taggable_test.rb │ ├── generators │ │ └── acts_as_taggable_migration │ │ │ ├── acts_as_taggable_migration_generator.rb │ │ │ └── templates │ │ │ └── migration.rb │ ├── lib │ │ ├── tagging.rb │ │ ├── tags_helper.rb │ │ ├── tag.rb │ │ ├── tag_list.rb │ │ └── acts_as_taggable.rb │ ├── Rakefile │ ├── MIT-LICENSE │ ├── acts_as_taggable_on_steroids.gemspec │ ├── README │ └── CHANGELOG │ ├── open_id_authentication │ ├── lib │ │ ├── open_id_authentication │ │ │ ├── nonce.rb │ │ │ ├── association.rb │ │ │ ├── timeout_fixes.rb │ │ │ ├── request.rb │ │ │ └── db_store.rb │ │ ├── tasks │ │ │ └── open_id_authentication_tasks.rake │ │ └── open_id_authentication.rb │ ├── generators │ │ ├── open_id_authentication_tables │ │ │ ├── open_id_authentication_tables_generator.rb │ │ │ └── templates │ │ │ │ └── migration.rb │ │ └── upgrade_open_id_authentication_tables │ │ │ ├── upgrade_open_id_authentication_tables_generator.rb │ │ │ └── templates │ │ │ └── migration.rb │ ├── test │ │ ├── test_helper.rb │ │ ├── status_test.rb │ │ ├── normalize_test.rb │ │ └── open_id_authentication_test.rb │ ├── init.rb │ ├── Rakefile │ ├── CHANGELOG │ └── README │ └── haml │ └── init.rb ├── script ├── plugin ├── runner ├── server ├── console ├── destroy ├── generate ├── dbconsole ├── performance │ ├── profiler │ └── benchmarker ├── about ├── autospec └── spec ├── doc └── README_FOR_APP ├── config ├── locales │ └── en.yml ├── initializers │ ├── mime_types.rb │ ├── inflections.rb │ ├── backtrace_silencers.rb │ ├── cookie_verification_secret.rb │ ├── session_store.rb │ ├── new_rails_defaults.rb │ └── action_view_extensions.rb ├── navigation.rb ├── environments │ ├── development.rb │ ├── production.rb │ └── test.rb ├── environment.rb ├── routes.rb └── boot.rb ├── lib ├── custom_form_builder.rb └── tasks │ └── rspec.rake ├── db ├── migrate │ ├── 20101019111823_add_openid_identifier_to_users.rb │ ├── 20101011122827_create_snippets.rb │ ├── 20101008090820_create_users.rb │ ├── 20101016100240_remove_title_from_snippets.rb │ ├── 20101019143937_acts_as_taggable_migration.rb │ └── 20101019111755_add_open_id_authentication_tables.rb ├── seeds.rb └── schema.rb ├── Rakefile ├── README.textile ├── Gemfile └── Gemfile.lock /public/favicon.gif: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/views/welcome/index.html.erb: -------------------------------------------------------------------------------- 1 | Hello Code Snippet! -------------------------------------------------------------------------------- /spec/rcov.opts: -------------------------------------------------------------------------------- 1 | --exclude "spec/*,gems/*" 2 | --rails -------------------------------------------------------------------------------- /app/helpers/home_helper.rb: -------------------------------------------------------------------------------- 1 | module HomeHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/users_helper.rb: -------------------------------------------------------------------------------- 1 | module UsersHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/views/home/index.html.erb: -------------------------------------------------------------------------------- 1 |

hello world!!!

2 | -------------------------------------------------------------------------------- /spec/spec.opts: -------------------------------------------------------------------------------- 1 | --colour 2 | --format nested 3 | --loadby mtime -------------------------------------------------------------------------------- /app/helpers/user_sessions_helper.rb: -------------------------------------------------------------------------------- 1 | module UserSessionsHelper 2 | end 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | log/ 3 | config/database.yml 4 | *.sqlite3 5 | tmp/ 6 | .bundle -------------------------------------------------------------------------------- /public/images/hd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notme/code-snippets/development/public/images/hd.jpg -------------------------------------------------------------------------------- /public/design/i/ai1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notme/code-snippets/development/public/design/i/ai1.png -------------------------------------------------------------------------------- /public/design/i/ai2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notme/code-snippets/development/public/design/i/ai2.png -------------------------------------------------------------------------------- /public/design/i/ai3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notme/code-snippets/development/public/design/i/ai3.png -------------------------------------------------------------------------------- /public/design/i/ai4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notme/code-snippets/development/public/design/i/ai4.png -------------------------------------------------------------------------------- /public/design/i/ai5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notme/code-snippets/development/public/design/i/ai5.png -------------------------------------------------------------------------------- /public/design/i/ai6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notme/code-snippets/development/public/design/i/ai6.png -------------------------------------------------------------------------------- /public/design/i/ai7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notme/code-snippets/development/public/design/i/ai7.png -------------------------------------------------------------------------------- /public/design/i/ai8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notme/code-snippets/development/public/design/i/ai8.png -------------------------------------------------------------------------------- /public/design/i/hd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notme/code-snippets/development/public/design/i/hd.jpg -------------------------------------------------------------------------------- /public/images/ai1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notme/code-snippets/development/public/images/ai1.png -------------------------------------------------------------------------------- /public/images/ai2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notme/code-snippets/development/public/images/ai2.png -------------------------------------------------------------------------------- /public/images/ai3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notme/code-snippets/development/public/images/ai3.png -------------------------------------------------------------------------------- /public/images/ai4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notme/code-snippets/development/public/images/ai4.png -------------------------------------------------------------------------------- /public/images/ai5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notme/code-snippets/development/public/images/ai5.png -------------------------------------------------------------------------------- /public/images/ai6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notme/code-snippets/development/public/images/ai6.png -------------------------------------------------------------------------------- /public/images/ai7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notme/code-snippets/development/public/images/ai7.png -------------------------------------------------------------------------------- /public/images/ai8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notme/code-snippets/development/public/images/ai8.png -------------------------------------------------------------------------------- /public/images/rails.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notme/code-snippets/development/public/images/rails.png -------------------------------------------------------------------------------- /public/design/i/img1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notme/code-snippets/development/public/design/i/img1.png -------------------------------------------------------------------------------- /public/design/i/img2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notme/code-snippets/development/public/design/i/img2.png -------------------------------------------------------------------------------- /public/design/i/img3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notme/code-snippets/development/public/design/i/img3.png -------------------------------------------------------------------------------- /public/design/i/img4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notme/code-snippets/development/public/design/i/img4.png -------------------------------------------------------------------------------- /public/design/i/img5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notme/code-snippets/development/public/design/i/img5.png -------------------------------------------------------------------------------- /public/design/i/img6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notme/code-snippets/development/public/design/i/img6.png -------------------------------------------------------------------------------- /vendor/plugins/acts_as_taggable_on_steroids/init.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/lib/acts_as_taggable' 2 | -------------------------------------------------------------------------------- /vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/special_post.rb: -------------------------------------------------------------------------------- 1 | class SpecialPost < Post 2 | end 3 | -------------------------------------------------------------------------------- /app/controllers/welcome_controller.rb: -------------------------------------------------------------------------------- 1 | class WelcomeController < ApplicationController 2 | def index 3 | end 4 | end -------------------------------------------------------------------------------- /public/design/i/image-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notme/code-snippets/development/public/design/i/image-1.png -------------------------------------------------------------------------------- /public/javascripts/application.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function(){ 2 | $('pre').makeExpandable(145, 520); 3 | }); 4 | -------------------------------------------------------------------------------- /app/controllers/home_controller.rb: -------------------------------------------------------------------------------- 1 | class HomeController < ApplicationController 2 | def index 3 | end 4 | 5 | end 6 | -------------------------------------------------------------------------------- /public/design/i/jabz-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notme/code-snippets/development/public/design/i/jabz-logo.png -------------------------------------------------------------------------------- /script/plugin: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require File.expand_path('../../config/boot', __FILE__) 3 | require 'commands/plugin' 4 | -------------------------------------------------------------------------------- /script/runner: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require File.expand_path('../../config/boot', __FILE__) 3 | require 'commands/runner' 4 | -------------------------------------------------------------------------------- /script/server: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require File.expand_path('../../config/boot', __FILE__) 3 | require 'commands/server' 4 | -------------------------------------------------------------------------------- /script/console: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require File.expand_path('../../config/boot', __FILE__) 3 | require 'commands/console' 4 | -------------------------------------------------------------------------------- /script/destroy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require File.expand_path('../../config/boot', __FILE__) 3 | require 'commands/destroy' 4 | -------------------------------------------------------------------------------- /script/generate: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require File.expand_path('../../config/boot', __FILE__) 3 | require 'commands/generate' 4 | -------------------------------------------------------------------------------- /app/models/user_session.rb: -------------------------------------------------------------------------------- 1 | class UserSession < Authlogic::Session::Base 2 | find_by_login_method :find_by_username_or_email 3 | end -------------------------------------------------------------------------------- /script/dbconsole: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require File.expand_path('../../config/boot', __FILE__) 3 | require 'commands/dbconsole' 4 | -------------------------------------------------------------------------------- /vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/magazines.yml: -------------------------------------------------------------------------------- 1 | ruby: 2 | name: Ruby 3 | 4 | rails: 5 | name: Rails 6 | -------------------------------------------------------------------------------- /vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/subscriptions.yml: -------------------------------------------------------------------------------- 1 | jonathan_rails: 2 | user: jonathan 3 | magazine: ruby 4 | -------------------------------------------------------------------------------- /vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/users.yml: -------------------------------------------------------------------------------- 1 | jonathan: 2 | name: Jonathan 3 | 4 | sam: 5 | name: Sam 6 | -------------------------------------------------------------------------------- /vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/magazine.rb: -------------------------------------------------------------------------------- 1 | class Magazine < ActiveRecord::Base 2 | acts_as_taggable 3 | end 4 | -------------------------------------------------------------------------------- /public/design/i/jonas-jared-jacek_50x50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notme/code-snippets/development/public/design/i/jonas-jared-jacek_50x50.png -------------------------------------------------------------------------------- /script/performance/profiler: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require File.expand_path('../../../config/boot', __FILE__) 3 | require 'commands/performance/profiler' 4 | -------------------------------------------------------------------------------- /script/performance/benchmarker: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require File.expand_path('../../../config/boot', __FILE__) 3 | require 'commands/performance/benchmarker' 4 | -------------------------------------------------------------------------------- /vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/subscription.rb: -------------------------------------------------------------------------------- 1 | class Subscription < ActiveRecord::Base 2 | belongs_to :user 3 | belongs_to :magazine 4 | end 5 | -------------------------------------------------------------------------------- /app/helpers/snippets_helper.rb: -------------------------------------------------------------------------------- 1 | module SnippetsHelper 2 | def render_tag_list(tag_list) 3 | tag_list.map{ |tag| link_to tag, '#', :title => tag }.join(' ') 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /script/about: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require File.expand_path('../../config/boot', __FILE__) 3 | $LOAD_PATH.unshift "#{RAILTIES_PATH}/builtin/rails_info" 4 | require 'commands/about' 5 | -------------------------------------------------------------------------------- /app/views/snippets/_fields.html.haml: -------------------------------------------------------------------------------- 1 | = f.label :code 2 | = f.text_area :code 3 | 4 | = f.label :description 5 | = f.text_area :description 6 | 7 | = f.label :tag_list 8 | = f.text_field :tag_list 9 | -------------------------------------------------------------------------------- /vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/post.rb: -------------------------------------------------------------------------------- 1 | class Post < ActiveRecord::Base 2 | acts_as_taggable 3 | 4 | belongs_to :user 5 | 6 | validates_presence_of :text 7 | end 8 | -------------------------------------------------------------------------------- /vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/photo.rb: -------------------------------------------------------------------------------- 1 | class Photo < ActiveRecord::Base 2 | acts_as_taggable 3 | 4 | belongs_to :user 5 | end 6 | 7 | class SpecialPhoto < Photo 8 | end 9 | -------------------------------------------------------------------------------- /vendor/plugins/open_id_authentication/lib/open_id_authentication/nonce.rb: -------------------------------------------------------------------------------- 1 | module OpenIdAuthentication 2 | class Nonce < ActiveRecord::Base 3 | set_table_name :open_id_authentication_nonces 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /doc/README_FOR_APP: -------------------------------------------------------------------------------- 1 | Use this README file to introduce your application and point to useful places in the API for learning more. 2 | Run "rake doc:app" to generate API documentation for your models, controllers, helpers, and libraries. 3 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file 2 | # 3 | # To ban all spiders from the entire site uncomment the next two lines: 4 | # User-Agent: * 5 | # Disallow: / 6 | -------------------------------------------------------------------------------- /vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/user.rb: -------------------------------------------------------------------------------- 1 | class User < ActiveRecord::Base 2 | has_many :posts 3 | has_many :photos 4 | 5 | has_many :subscriptions 6 | has_many :magazines, :through => :subscriptions 7 | end 8 | -------------------------------------------------------------------------------- /config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Sample localization file for English. Add more files in this directory for other locales. 2 | # See http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points. 3 | 4 | en: 5 | hello: "Hello world" -------------------------------------------------------------------------------- /app/views/snippets/new.html.haml: -------------------------------------------------------------------------------- 1 | - form_for [current_user, @snippet] do |f| 2 | = f.error_messages 3 | = render :partial => 'snippets/fields', :locals => { :f => f } 4 | = f.submit 'Create' 5 | 6 | = link_to 'Back', user_snippets_path(current_user) -------------------------------------------------------------------------------- /config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | # Mime::Type.register_alias "text/html", :iphone 6 | -------------------------------------------------------------------------------- /lib/custom_form_builder.rb: -------------------------------------------------------------------------------- 1 | class CustomFormBuilder < ActionView::Helpers::FormBuilder 2 | def error_messages(options={}) 3 | super options.reverse_merge(:header_message => nil, :message => nil, :class => 'error-explanation', :id => nil) 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/views/users/new.html.haml_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe "View /users/new" do 4 | it "should not fail if @user variable set" do 5 | assigns[:user] = User.new 6 | render 'users/new' 7 | response.should be_success 8 | end 9 | end -------------------------------------------------------------------------------- /vendor/plugins/acts_as_taggable_on_steroids/test/database.yml: -------------------------------------------------------------------------------- 1 | mysql: 2 | :adapter: mysql 3 | :host: localhost 4 | :username: rails 5 | :password: 6 | :database: rails_plugin_test 7 | 8 | sqlite3: 9 | :adapter: sqlite3 10 | :database: ':memory:' 11 | -------------------------------------------------------------------------------- /vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/tags.yml: -------------------------------------------------------------------------------- 1 | good: 2 | name: Very good 3 | 4 | bad: 5 | name: Bad 6 | 7 | nature: 8 | name: Nature 9 | 10 | question: 11 | name: Question 12 | 13 | animal: 14 | name: Crazy animal 15 | -------------------------------------------------------------------------------- /db/migrate/20101019111823_add_openid_identifier_to_users.rb: -------------------------------------------------------------------------------- 1 | class AddOpenidIdentifierToUsers < ActiveRecord::Migration 2 | def self.up 3 | add_column :users, :openid_identifier, :string 4 | end 5 | 6 | def self.down 7 | remove_column :users, :openid_identifier 8 | end 9 | end -------------------------------------------------------------------------------- /app/views/snippets/edit.html.haml: -------------------------------------------------------------------------------- 1 | - form_for [current_user, @snippet] do |f| 2 | = f.error_messages 3 | = render :partial => 'snippets/fields', :locals => { :f => f } 4 | = f.submit 'Update' 5 | 6 | = link_to 'Show', [current_user, @snippet] 7 | = link_to 'Back', user_snippets_path(current_user) -------------------------------------------------------------------------------- /app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | include TagsHelper 3 | def render_flash 4 | returning String.new do |html| 5 | flash.each do |type, message| 6 | html << content_tag(:div, message, :class => type) 7 | end 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/views/user_sessions/new.html.haml_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe "View /user_sessions/new" do 4 | setup :activate_authlogic 5 | 6 | it "should not fail if @user_session is set" do 7 | assigns[:user_session] = UserSession.new 8 | response.should be_success 9 | render 'user_sessions/new' 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.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' 11 | -------------------------------------------------------------------------------- /spec/helpers/snippets_helper_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe SnippetsHelper do 4 | describe "#render_tag_list" do 5 | it "should return string with generated links" do 6 | tag_list = TagList.new "Tag1, Tag2", :parse => true 7 | helper.render_tag_list(tag_list).scan(/ 'My Flash Message'}) 6 | helper.render_flash.should have_tag("div.flash_class", 'My Flash Message') 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /app/views/snippets/show.html.haml: -------------------------------------------------------------------------------- 1 | %article.snippet 2 | %h4 3 | =h @snippet.title 4 | .description=simple_format h(@snippet.description) 5 | %pre 6 | %code=h @snippet.code 7 | .tags= render_tag_list(@snippet.tag_list) 8 | 9 | = link_to 'Edit', edit_user_snippet_path(current_user, @snippet) 10 | = link_to 'Back', user_snippets_path(current_user) -------------------------------------------------------------------------------- /db/migrate/20101011122827_create_snippets.rb: -------------------------------------------------------------------------------- 1 | class CreateSnippets < ActiveRecord::Migration 2 | def self.up 3 | create_table :snippets do |t| 4 | t.integer :user_id 5 | t.string :title 6 | t.text :description 7 | t.text :code 8 | 9 | t.timestamps 10 | end 11 | end 12 | 13 | def self.down 14 | drop_table :snippets 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /db/seeds.rb: -------------------------------------------------------------------------------- 1 | # This file should contain all the record creation needed to seed the database with its default values. 2 | # The data can then be loaded with the rake db:seed (or created alongside the db with db:setup). 3 | # 4 | # Examples: 5 | # 6 | # cities = City.create([{ :name => 'Chicago' }, { :name => 'Copenhagen' }]) 7 | # Major.create(:name => 'Daley', :city => cities.first) 8 | -------------------------------------------------------------------------------- /script/autospec: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | gem 'test-unit', '1.2.3' if RUBY_VERSION.to_f >= 1.9 3 | ENV['RSPEC'] = 'true' # allows autotest to discover rspec 4 | ENV['AUTOTEST'] = 'true' # allows autotest to run w/ color on linux 5 | system((RUBY_PLATFORM =~ /mswin|mingw/ ? 'autotest.bat' : 'autotest'), *ARGV) || 6 | $stderr.puts("Unable to find autotest. Please install ZenTest or fix your PATH") 7 | -------------------------------------------------------------------------------- /README.textile: -------------------------------------------------------------------------------- 1 | h2. Code Snippets Storage 2 | 3 | Code snippets storage with tag support and rich search functionality. 4 | 5 | "http://code-snippets.heroku.com":http://code-snippets.heroku.com 6 | 7 | h2. Hacking 8 | 9 | This project uses gem bundler, so you need to install it at first. 10 | 11 |
$ gem install bundler
12 | $ sudo bundle install --without production
13 | -------------------------------------------------------------------------------- /db/migrate/20101008090820_create_users.rb: -------------------------------------------------------------------------------- 1 | class CreateUsers < ActiveRecord::Migration 2 | def self.up 3 | create_table :users do |t| 4 | t.string :username 5 | t.string :email 6 | t.string :crypted_password 7 | t.string :password_salt 8 | t.string :persistence_token 9 | end 10 | end 11 | 12 | def self.down 13 | drop_table :users 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /vendor/plugins/acts_as_taggable_on_steroids/generators/acts_as_taggable_migration/acts_as_taggable_migration_generator.rb: -------------------------------------------------------------------------------- 1 | class ActsAsTaggableMigrationGenerator < Rails::Generator::Base 2 | def manifest 3 | record do |m| 4 | m.migration_template 'migration.rb', 'db/migrate' 5 | end 6 | end 7 | 8 | def file_name 9 | "acts_as_taggable_migration" 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /vendor/plugins/acts_as_taggable_on_steroids/test/tagging_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/abstract_unit' 2 | 3 | class TaggingTest < ActiveSupport::TestCase 4 | def test_tag 5 | assert_equal tags(:good), taggings(:jonathan_sky_good).tag 6 | end 7 | 8 | def test_taggable 9 | assert_equal posts(:jonathan_sky), taggings(:jonathan_sky_good).taggable 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/helpers/user_sessions_helper_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe UserSessionsHelper do 4 | 5 | #Delete this example and add some real ones or delete this file 6 | it "should be included in the object returned by #helper" do 7 | included_modules = (class << helper; self; end).send :included_modules 8 | included_modules.should include(UserSessionsHelper) 9 | end 10 | 11 | end 12 | -------------------------------------------------------------------------------- /vendor/plugins/open_id_authentication/generators/open_id_authentication_tables/open_id_authentication_tables_generator.rb: -------------------------------------------------------------------------------- 1 | class OpenIdAuthenticationTablesGenerator < Rails::Generator::NamedBase 2 | def initialize(runtime_args, runtime_options = {}) 3 | super 4 | end 5 | 6 | def manifest 7 | record do |m| 8 | m.migration_template 'migration.rb', 'db/migrate' 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/photos.yml: -------------------------------------------------------------------------------- 1 | jonathan_dog: 2 | user: jonathan 3 | title: A small dog 4 | 5 | jonathan_questioning_dog: 6 | user: jonathan 7 | title: What does this dog want? 8 | 9 | jonathan_bad_cat: 10 | user: jonathan 11 | title: Bad cat 12 | 13 | sam_flower: 14 | user: sam 15 | title: Flower 16 | 17 | sam_sky: 18 | user: sam 19 | title: Sky 20 | -------------------------------------------------------------------------------- /vendor/plugins/acts_as_taggable_on_steroids/lib/tagging.rb: -------------------------------------------------------------------------------- 1 | class Tagging < ActiveRecord::Base #:nodoc: 2 | belongs_to :tag 3 | belongs_to :taggable, :polymorphic => true 4 | 5 | after_destroy :destroy_tag_if_unused 6 | 7 | private 8 | 9 | def destroy_tag_if_unused 10 | if Tag.destroy_unused 11 | if tag.taggings.count.zero? 12 | tag.destroy 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /vendor/plugins/open_id_authentication/generators/upgrade_open_id_authentication_tables/upgrade_open_id_authentication_tables_generator.rb: -------------------------------------------------------------------------------- 1 | class UpgradeOpenIdAuthenticationTablesGenerator < Rails::Generator::NamedBase 2 | def initialize(runtime_args, runtime_options = {}) 3 | super 4 | end 5 | 6 | def manifest 7 | record do |m| 8 | m.migration_template 'migration.rb', 'db/migrate' 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /vendor/plugins/acts_as_taggable_on_steroids/lib/tags_helper.rb: -------------------------------------------------------------------------------- 1 | module TagsHelper 2 | # See the README for an example using tag_cloud. 3 | def tag_cloud(tags, classes) 4 | return if tags.empty? 5 | 6 | max_count = tags.sort_by(&:count).last.count.to_f 7 | 8 | tags.each do |tag| 9 | index = ((tag.count / max_count) * (classes.size - 1)).round 10 | yield tag, classes[index] 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format 4 | # (all these examples are active by default): 5 | # ActiveSupport::Inflector.inflections do |inflect| 6 | # inflect.plural /^(ox)$/i, '\1en' 7 | # inflect.singular /^(ox)en/i, '\1' 8 | # inflect.irregular 'person', 'people' 9 | # inflect.uncountable %w( fish sheep ) 10 | # end 11 | -------------------------------------------------------------------------------- /config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying do debug a problem that might steem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! -------------------------------------------------------------------------------- /vendor/plugins/open_id_authentication/test/test_helper.rb: -------------------------------------------------------------------------------- 1 | require 'test/unit' 2 | require 'rubygems' 3 | 4 | gem 'activesupport' 5 | require 'active_support' 6 | 7 | gem 'actionpack' 8 | require 'action_controller' 9 | 10 | gem 'mocha' 11 | require 'mocha' 12 | 13 | gem 'ruby-openid' 14 | require 'openid' 15 | 16 | RAILS_ROOT = File.dirname(__FILE__) unless defined? RAILS_ROOT 17 | require File.dirname(__FILE__) + "/../lib/open_id_authentication" 18 | -------------------------------------------------------------------------------- /script/spec: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | if ARGV.any? {|arg| %w[--drb -X --generate-options -G --help -h --version -v].include?(arg)} 3 | require 'rubygems' unless ENV['NO_RUBYGEMS'] 4 | else 5 | gem 'test-unit', '1.2.3' if RUBY_VERSION.to_f >= 1.9 6 | ENV["RAILS_ENV"] ||= 'test' 7 | require File.expand_path(File.dirname(__FILE__) + "/../config/environment") unless defined?(RAILS_ROOT) 8 | end 9 | require 'spec/autorun' 10 | exit ::Spec::Runner::CommandLine.run 11 | -------------------------------------------------------------------------------- /vendor/plugins/open_id_authentication/test/status_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/test_helper' 2 | 3 | class StatusTest < Test::Unit::TestCase 4 | include OpenIdAuthentication 5 | 6 | def test_state_conditional 7 | assert Result[:missing].missing? 8 | assert Result[:missing].unsuccessful? 9 | assert !Result[:missing].successful? 10 | 11 | assert Result[:successful].successful? 12 | assert !Result[:successful].unsuccessful? 13 | end 14 | end -------------------------------------------------------------------------------- /app/views/user_sessions/new.html.haml: -------------------------------------------------------------------------------- 1 | - form_for @user_session, :html => { :class => 'login' } do |form| 2 | = form.error_messages 3 | 4 | = form.label :username, "Login/Email" 5 | = form.text_field :username 6 | 7 | = form.label :password, "Password" 8 | = form.password_field :password 9 | = form.submit "Submit" 10 | 11 | %hr 12 | %strong Or use OpenID 13 | 14 | = form.label :openid_identifier, "OpenID URL" 15 | = form.text_field :openid_identifier 16 | 17 | = form.submit "Submit" -------------------------------------------------------------------------------- /config/navigation.rb: -------------------------------------------------------------------------------- 1 | SimpleNavigation::Configuration.run do |navigation| 2 | navigation.selected_class = 'active' 3 | navigation.items do |primary| 4 | primary.item :snippets, 'My Snippets', user_snippets_path(:current), :if => Proc.new { current_user } 5 | primary.item :login, 'Log In', login_path, :if => Proc.new { !current_user } 6 | primary.item :register, 'Register', register_path, :if => Proc.new { !current_user } 7 | primary.item :logout, 'Log Out', logout_path, :if => Proc.new { current_user } 8 | end 9 | end -------------------------------------------------------------------------------- /spec/controllers/home_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe HomeController do 4 | 5 | describe "routing" do 6 | it "should know the route to /home GET" do 7 | params_from(:get, '/home').should == {:controller => 'home', :action => 'index'} 8 | end 9 | end 10 | context "with views" do 11 | integrate_views 12 | 13 | describe "#index" do 14 | it "should get index" do 15 | get :index 16 | assert_response :success 17 | end 18 | end 19 | end 20 | end -------------------------------------------------------------------------------- /app/models/user.rb: -------------------------------------------------------------------------------- 1 | class User < ActiveRecord::Base 2 | acts_as_authentic do |c| 3 | c.openid_required_fields = [:nickname, :email] 4 | end 5 | 6 | has_many :snippets, :dependent => :destroy 7 | 8 | def self.find_by_username_or_email(login) 9 | find_by_username(login) || find_by_email(login) 10 | end 11 | 12 | private 13 | 14 | def map_openid_registration(registration) 15 | self.email = registration["email"] if email.blank? 16 | self.username = registration["nickname"] if username.blank? 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | ENV["RAILS_ENV"] ||= 'test' 2 | require File.expand_path(File.join(File.dirname(__FILE__),'..','config','environment')) 3 | require 'spec/autorun' 4 | require 'spec/rails' 5 | require 'authlogic/test_case' 6 | #require 'webrat/integrations/rspec-rails' 7 | 8 | Dir[File.expand_path(File.join(File.dirname(__FILE__),'support','**','*.rb'))].each {|f| require f} 9 | 10 | Spec::Runner.configure do |config| 11 | config.before(:all) { Sham.reset(:before_all) } 12 | config.before(:each) { Sham.reset(:before_each) } 13 | end 14 | -------------------------------------------------------------------------------- /vendor/plugins/open_id_authentication/init.rb: -------------------------------------------------------------------------------- 1 | if config.respond_to?(:gems) 2 | config.gem 'ruby-openid', :lib => 'openid', :version => '>=2.0.4' 3 | else 4 | begin 5 | require 'openid' 6 | rescue LoadError 7 | begin 8 | gem 'ruby-openid', '>=2.0.4' 9 | rescue Gem::LoadError 10 | puts "Install the ruby-openid gem to enable OpenID support" 11 | end 12 | end 13 | end 14 | 15 | config.to_prepare do 16 | OpenID::Util.logger = Rails.logger 17 | ActionController::Base.send :include, OpenIdAuthentication 18 | end 19 | -------------------------------------------------------------------------------- /config/initializers/cookie_verification_secret.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | # Make sure the secret is at least 30 characters and all random, 6 | # no regular words or you'll be exposed to dictionary attacks. 7 | ActionController::Base.cookie_verifier_secret = 'ced2aa8dc3c5f3012c341bea878a4948cf761d3f893959d600fa5ef80fefa3fa7d3bf6bdeab191dec47685fbc864f680ce204a25f9add16a823a6f5ac93044a9'; 8 | -------------------------------------------------------------------------------- /spec/support/blueprints.rb: -------------------------------------------------------------------------------- 1 | require 'machinist/active_record' 2 | require 'sham' 3 | require 'faker' 4 | 5 | Sham.username { Faker::Internet.user_name } 6 | Sham.email { Faker::Internet.email } 7 | Sham.password { Faker.numerify "######" } 8 | Sham.title { Faker::Lorem.sentence } 9 | Sham.description { Faker::Lorem.sentence } 10 | Sham.code { Faker::Lorem.paragraphs } 11 | 12 | User.blueprint do 13 | username 14 | email 15 | password 16 | password_confirmation { password } 17 | end 18 | 19 | Snippet.blueprint do 20 | user 21 | description 22 | code 23 | end -------------------------------------------------------------------------------- /vendor/plugins/open_id_authentication/lib/open_id_authentication/timeout_fixes.rb: -------------------------------------------------------------------------------- 1 | # http://trac.openidenabled.com/trac/ticket/156 2 | module OpenID 3 | @@timeout_threshold = 20 4 | 5 | def self.timeout_threshold 6 | @@timeout_threshold 7 | end 8 | 9 | def self.timeout_threshold=(value) 10 | @@timeout_threshold = value 11 | end 12 | 13 | class StandardFetcher 14 | def make_http(uri) 15 | http = @proxy.new(uri.host, uri.port) 16 | http.read_timeout = http.open_timeout = OpenID.timeout_threshold 17 | http 18 | end 19 | end 20 | end -------------------------------------------------------------------------------- /vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/posts.yml: -------------------------------------------------------------------------------- 1 | jonathan_sky: 2 | user: jonathan 3 | text: The sky is particularly blue today 4 | 5 | jonathan_grass: 6 | user: jonathan 7 | text: The grass seems very green 8 | 9 | jonathan_rain: 10 | user: jonathan 11 | text: Why does the rain fall? 12 | 13 | jonathan_cloudy: 14 | user: jonathan 15 | text: Is it cloudy? 16 | 17 | jonathan_still_cloudy: 18 | user: jonathan 19 | text: Is it still cloudy? 20 | 21 | sam_ground: 22 | user: sam 23 | text: The ground is looking too brown 24 | 25 | sam_flowers: 26 | user: sam 27 | text: Why are the flowers dead? 28 | -------------------------------------------------------------------------------- /app/views/users/edit.html.haml: -------------------------------------------------------------------------------- 1 | - form_for @user do |form| 2 | = form.error_messages 3 | 4 | = form.label :username, "Username" 5 | = form.text_field :username 6 | 7 | = form.label :email, "Email" 8 | = form.text_field :email 9 | 10 | - if @user.openid_identifier.blank? 11 | = form.label :password, "Password" 12 | = form.password_field :password 13 | 14 | = form.label :password_confirmation, "Password confirmation" 15 | = form.password_field :password_confirmation 16 | 17 | = form.submit "Submit" 18 | 19 | = form.label :openid_identifier, "OpenID URL" 20 | = form.text_field :openid_identifier 21 | 22 | = form.submit "Submit" -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'http://rubygems.org' 2 | 3 | gem 'rails', '2.3.8' 4 | gem 'jrails', '~> 0.6' 5 | gem 'haml', '~> 2.2.24' 6 | gem 'simple-navigation', '~> 2.5.3' 7 | gem 'ruby-openid', '~> 2.1.8', :require => 'openid' 8 | gem 'authlogic', '~> 2.1.6' 9 | gem 'authlogic-oid', '~> 1.0.4', :require => 'authlogic_openid' 10 | 11 | group :production do 12 | gem 'pg' 13 | end 14 | 15 | group :development, :test do 16 | gem 'sqlite3-ruby', :require => 'sqlite3' 17 | gem 'mysql' 18 | gem 'mongrel' 19 | end 20 | 21 | group :test do 22 | gem 'rspec', '~> 1.3.0' 23 | gem 'rspec-rails', '~> 1.3.2' 24 | gem 'machinist', '~> 1.0.6' 25 | gem 'faker', '~> 0.3.1' 26 | end 27 | -------------------------------------------------------------------------------- /public/javascripts/jquery.make_expandable.js: -------------------------------------------------------------------------------- 1 | jQuery.fn.makeExpandable = function(max_height, width) { 2 | $(this).hover( 3 | function(){ 4 | var innerWidth = $("code", this).innerWidth(); 5 | var innerHeight = $("code", this).innerHeight(); 6 | var new_size = {}; 7 | if ($(this).innerWidth() < innerWidth) new_size['width'] = innerWidth + 'px'; 8 | if ($(this).innerHeight() < innerHeight) new_size['max-height'] = innerHeight + 'px'; 9 | $(this).stop(true, false).animate(new_size,'fast'); 10 | }, 11 | function(){ 12 | $(this).stop(true, false).animate({'max-height':max_height+'px','width':width + 'px'},'fast'); 13 | } 14 | ); 15 | }; -------------------------------------------------------------------------------- /app/views/users/new.html.haml: -------------------------------------------------------------------------------- 1 | - form_for @user, :html => { :class => 'register' } do |form| 2 | = form.error_messages 3 | 4 | = form.label :username, "Username" 5 | = form.text_field :username 6 | 7 | = form.label :email, "Email" 8 | = form.text_field :email 9 | 10 | = form.label :password, "Password" 11 | = form.password_field :password 12 | 13 | = form.label :password_confirmation, "Password confirmation" 14 | = form.password_field :password_confirmation 15 | 16 | = form.submit "Submit" 17 | 18 | %hr 19 | %strong Or use OpenID 20 | 21 | = form.label :openid_identifier, "OpenID URL" 22 | = form.text_field :openid_identifier 23 | 24 | = form.submit "Submit" 25 | -------------------------------------------------------------------------------- /vendor/plugins/haml/init.rb: -------------------------------------------------------------------------------- 1 | begin 2 | require File.join(File.dirname(__FILE__), 'lib', 'haml') # From here 3 | rescue LoadError 4 | begin 5 | require 'haml' # From gem 6 | rescue LoadError => e 7 | # gems:install may be run to install Haml with the skeleton plugin 8 | # but not the gem itself installed. 9 | # Don't die if this is the case. 10 | raise e unless defined?(Rake) && 11 | (Rake.application.top_level_tasks.include?('gems') || 12 | Rake.application.top_level_tasks.include?('gems:install')) 13 | end 14 | end 15 | 16 | # Load Haml and Sass. 17 | # Haml may be undefined if we're running gems:install. 18 | Haml.init_rails(binding) if defined?(Haml) 19 | -------------------------------------------------------------------------------- /db/migrate/20101016100240_remove_title_from_snippets.rb: -------------------------------------------------------------------------------- 1 | class RemoveTitleFromSnippets < ActiveRecord::Migration 2 | def self.up 3 | Snippet.find_in_batches do |batch| 4 | batch.each do |snippet| 5 | snippet.description = [snippet.title, snippet.description].compact.join("\n") 6 | snippet.save 7 | end 8 | end 9 | remove_column :snippets, :title 10 | end 11 | 12 | def self.down 13 | add_column :snippets, :title, :string 14 | Snippet.reset_column_information 15 | Snippet.find_in_batches do |batch| 16 | batch.each do |snippet| 17 | snippet[:title] = snippet.title 18 | snippet.save 19 | end 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /vendor/plugins/open_id_authentication/Rakefile: -------------------------------------------------------------------------------- 1 | require 'rake' 2 | require 'rake/testtask' 3 | require 'rake/rdoctask' 4 | 5 | desc 'Default: run unit tests.' 6 | task :default => :test 7 | 8 | desc 'Test the open_id_authentication plugin.' 9 | Rake::TestTask.new(:test) do |t| 10 | t.libs << 'lib' 11 | t.pattern = 'test/**/*_test.rb' 12 | t.verbose = true 13 | end 14 | 15 | desc 'Generate documentation for the open_id_authentication plugin.' 16 | Rake::RDocTask.new(:rdoc) do |rdoc| 17 | rdoc.rdoc_dir = 'rdoc' 18 | rdoc.title = 'OpenIdAuthentication' 19 | rdoc.options << '--line-numbers' << '--inline-source' 20 | rdoc.rdoc_files.include('README') 21 | rdoc.rdoc_files.include('lib/**/*.rb') 22 | end 23 | -------------------------------------------------------------------------------- /db/migrate/20101019143937_acts_as_taggable_migration.rb: -------------------------------------------------------------------------------- 1 | class ActsAsTaggableMigration < ActiveRecord::Migration 2 | def self.up 3 | create_table :tags do |t| 4 | t.column :name, :string 5 | end 6 | 7 | create_table :taggings do |t| 8 | t.column :tag_id, :integer 9 | t.references :taggable, :polymorphic => true 10 | t.column :created_at, :datetime 11 | end 12 | 13 | add_column :snippets, :cached_tag_list, :string 14 | 15 | add_index :taggings, :tag_id 16 | add_index :taggings, [:taggable_id, :taggable_type] 17 | end 18 | 19 | def self.down 20 | drop_table :taggings 21 | drop_table :tags 22 | remove_column :snippets, :cached_tag_list 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /db/migrate/20101019111755_add_open_id_authentication_tables.rb: -------------------------------------------------------------------------------- 1 | class AddOpenIdAuthenticationTables < ActiveRecord::Migration 2 | def self.up 3 | create_table :open_id_authentication_associations, :force => true do |t| 4 | t.integer :issued, :lifetime 5 | t.string :handle, :assoc_type 6 | t.binary :server_url, :secret 7 | end 8 | 9 | create_table :open_id_authentication_nonces, :force => true do |t| 10 | t.integer :timestamp, :null => false 11 | t.string :server_url, :null => true 12 | t.string :salt, :null => false 13 | end 14 | end 15 | 16 | def self.down 17 | drop_table :open_id_authentication_associations 18 | drop_table :open_id_authentication_nonces 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /vendor/plugins/acts_as_taggable_on_steroids/Rakefile: -------------------------------------------------------------------------------- 1 | require 'rake' 2 | require 'rake/testtask' 3 | require 'rake/rdoctask' 4 | 5 | desc 'Default: run unit tests.' 6 | task :default => :test 7 | 8 | desc 'Test the acts_as_taggable_on_steroids plugin.' 9 | Rake::TestTask.new(:test) do |t| 10 | t.libs << 'test' 11 | t.pattern = 'test/**/*_test.rb' 12 | t.verbose = true 13 | end 14 | 15 | desc 'Generate documentation for the acts_as_taggable_on_steroids plugin.' 16 | Rake::RDocTask.new(:rdoc) do |rdoc| 17 | rdoc.rdoc_dir = 'rdoc' 18 | rdoc.title = 'Acts As Taggable On Steroids' 19 | rdoc.options << '--line-numbers' << '--inline-source' 20 | rdoc.rdoc_files.include('README') 21 | rdoc.rdoc_files.include('lib/**/*.rb') 22 | end 23 | -------------------------------------------------------------------------------- /vendor/plugins/open_id_authentication/generators/open_id_authentication_tables/templates/migration.rb: -------------------------------------------------------------------------------- 1 | class <%= class_name %> < ActiveRecord::Migration 2 | def self.up 3 | create_table :open_id_authentication_associations, :force => true do |t| 4 | t.integer :issued, :lifetime 5 | t.string :handle, :assoc_type 6 | t.binary :server_url, :secret 7 | end 8 | 9 | create_table :open_id_authentication_nonces, :force => true do |t| 10 | t.integer :timestamp, :null => false 11 | t.string :server_url, :null => true 12 | t.string :salt, :null => false 13 | end 14 | end 15 | 16 | def self.down 17 | drop_table :open_id_authentication_associations 18 | drop_table :open_id_authentication_nonces 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /spec/models/snippet_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Snippet do 4 | describe "title" do 5 | it "should be equal to the first line of description" do 6 | snippet = Snippet.make_unsaved :description => "First line of the description.\nSecond line of the description." 7 | snippet.title.should eql('First line of the description.') 8 | end 9 | it "should be truncated description if the first line too long" do 10 | snippet = Snippet.make_unsaved :description => "q"*100 11 | snippet.title.should eql("q"*60) 12 | end 13 | it "should be default title if description is blank" do 14 | snippet = Snippet.make :description => nil 15 | snippet.title.should eql("Code Snippet ##{snippet.id}") 16 | end 17 | end 18 | 19 | end -------------------------------------------------------------------------------- /app/controllers/user_sessions_controller.rb: -------------------------------------------------------------------------------- 1 | class UserSessionsController < ApplicationController 2 | def new 3 | @user_session = UserSession.new 4 | end 5 | 6 | def create 7 | @user_session = UserSession.new(params[:user_session]) 8 | @user_session.save do |result| 9 | if result 10 | flash[:notice] = "Successfully logged in." 11 | redirect_to home_url 12 | else 13 | render :action => 'new' 14 | end 15 | end 16 | end 17 | 18 | def destroy 19 | if @user_session = UserSession.find 20 | @user_session.destroy 21 | flash[:notice] = "Successfully logged out." 22 | redirect_to root_url 23 | else 24 | flash[:notice] = "You haven't logged in." 25 | redirect_to root_url 26 | end 27 | end 28 | 29 | end 30 | -------------------------------------------------------------------------------- /vendor/plugins/open_id_authentication/lib/open_id_authentication/request.rb: -------------------------------------------------------------------------------- 1 | module OpenIdAuthentication 2 | module Request 3 | def self.included(base) 4 | base.alias_method_chain :request_method, :openid 5 | end 6 | 7 | def request_method_with_openid 8 | if !parameters[:_method].blank? && parameters[:open_id_complete] == '1' 9 | parameters[:_method].to_sym 10 | else 11 | request_method_without_openid 12 | end 13 | end 14 | end 15 | end 16 | 17 | # In Rails 2.3, the request object has been renamed 18 | # from AbstractRequest to Request 19 | if defined? ActionController::Request 20 | ActionController::Request.send :include, OpenIdAuthentication::Request 21 | else 22 | ActionController::AbstractRequest.send :include, OpenIdAuthentication::Request 23 | end 24 | -------------------------------------------------------------------------------- /app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | layout 'frontend' 3 | helper :all 4 | protect_from_forgery 5 | 6 | filter_parameter_logging :password 7 | helper_method :current_user 8 | 9 | private 10 | def current_user_session 11 | return @current_user_session if defined?(@current_user_session) 12 | @current_user_session = UserSession.find 13 | end 14 | 15 | def current_user 16 | return @current_user if defined?(@current_user) 17 | @current_user = current_user_session && current_user_session.record 18 | end 19 | 20 | def require_user 21 | unless current_user 22 | flash[:notice] = "You must be logged in to access this page" 23 | redirect_to root_path 24 | return false 25 | end 26 | end 27 | 28 | end 29 | -------------------------------------------------------------------------------- /app/controllers/users_controller.rb: -------------------------------------------------------------------------------- 1 | class UsersController < ApplicationController 2 | def new 3 | @user = User.new 4 | end 5 | 6 | def create 7 | @user = User.new(params[:user]) 8 | @user.save do |result| 9 | if result 10 | flash[:notice] = "Registration successful." 11 | redirect_to root_url 12 | else 13 | render :action => 'new' 14 | end 15 | end 16 | end 17 | 18 | def edit 19 | @user = current_user 20 | end 21 | 22 | def update 23 | @user = current_user 24 | @user.attributes = params[:user] 25 | @user.save do |result| 26 | if result 27 | flash[:notice] = "Successfully updated profile." 28 | redirect_to root_url 29 | else 30 | render :action => 'edit' 31 | end 32 | end 33 | end 34 | end -------------------------------------------------------------------------------- /app/views/snippets/index.html.haml: -------------------------------------------------------------------------------- 1 | - @snippets.each do |snippet| 2 | - link = link_to 'Read more', [current_user, snippet], :title => "Read more about #{sanitize(snippet.title)}" 3 | %article.snippet.short 4 | %h4=link_to h(snippet.title), [current_user, snippet], :title => sanitize(snippet.title) 5 | .description= simple_format truncate(h(snippet.description), :length => 300, :omission => "... #{link}") 6 | %pre 7 | %code=h snippet.code 8 | .tags= render_tag_list(snippet.tag_list) 9 | 10 | 11 | = link_to 'Edit', edit_user_snippet_path(current_user, snippet) 12 | = link_to 'Back', user_snippets_path(current_user) 13 | = link_to 'Delete', user_snippet_path(current_user, snippet), :confirm => 'Are you sure?', :method => :delete 14 | 15 | = link_to 'New snippet', new_user_snippet_path(current_user) -------------------------------------------------------------------------------- /config/environments/development.rb: -------------------------------------------------------------------------------- 1 | # Settings specified here will take precedence over those in config/environment.rb 2 | 3 | # In the development environment your application's code is reloaded on 4 | # every request. This slows down response time but is perfect for development 5 | # since you don't have to restart the webserver when you make code changes. 6 | config.cache_classes = false 7 | 8 | # Log error messages when you accidentally call methods on nil. 9 | config.whiny_nils = true 10 | 11 | # Show full error reports and disable caching 12 | config.action_controller.consider_all_requests_local = true 13 | config.action_view.debug_rjs = true 14 | config.action_controller.perform_caching = false 15 | 16 | # Don't care if the mailer can't send 17 | config.action_mailer.raise_delivery_errors = false -------------------------------------------------------------------------------- /vendor/plugins/acts_as_taggable_on_steroids/generators/acts_as_taggable_migration/templates/migration.rb: -------------------------------------------------------------------------------- 1 | class ActsAsTaggableMigration < ActiveRecord::Migration 2 | def self.up 3 | create_table :tags do |t| 4 | t.column :name, :string 5 | end 6 | 7 | create_table :taggings do |t| 8 | t.column :tag_id, :integer 9 | t.column :taggable_id, :integer 10 | 11 | # You should make sure that the column created is 12 | # long enough to store the required class names. 13 | t.column :taggable_type, :string 14 | 15 | t.column :created_at, :datetime 16 | end 17 | 18 | add_index :taggings, :tag_id 19 | add_index :taggings, [:taggable_id, :taggable_type] 20 | end 21 | 22 | def self.down 23 | drop_table :taggings 24 | drop_table :tags 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key for verifying cookie session data integrity. 4 | # If you change this key, all old sessions will become invalid! 5 | # Make sure the secret is at least 30 characters and all random, 6 | # no regular words or you'll be exposed to dictionary attacks. 7 | ActionController::Base.session = { 8 | :key => '_code_snippets_session', 9 | :secret => 'afbe88c0775cc4811b5324893329d8f32cf9d8cbc3167d00609a9730565f1a17e356cd5696d9863740e877fad177ba4f884e0dd1c38c67fc643a2ba412d4dd94' 10 | } 11 | 12 | # Use the database for sessions instead of the cookie-based default, 13 | # which shouldn't be used to store highly confidential information 14 | # (create the session table with "rake db:sessions:create") 15 | # ActionController::Base.session_store = :active_record_store 16 | -------------------------------------------------------------------------------- /vendor/plugins/acts_as_taggable_on_steroids/test/tags_helper_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/abstract_unit' 2 | 3 | class TagsHelperTest < ActiveSupport::TestCase 4 | include TagsHelper 5 | 6 | def test_tag_cloud 7 | cloud_elements = [] 8 | 9 | tag_cloud Post.tag_counts, %w(css1 css2 css3 css4) do |tag, css_class| 10 | cloud_elements << [tag, css_class] 11 | end 12 | 13 | assert cloud_elements.include?([tags(:good), "css2"]) 14 | assert cloud_elements.include?([tags(:bad), "css1"]) 15 | assert cloud_elements.include?([tags(:nature), "css4"]) 16 | assert cloud_elements.include?([tags(:question), "css1"]) 17 | assert_equal 4, cloud_elements.size 18 | end 19 | 20 | def test_tag_cloud_when_no_tags 21 | tag_cloud SpecialPost.tag_counts, %w(css1) do 22 | assert false, "tag_cloud should not yield" 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /vendor/plugins/open_id_authentication/generators/upgrade_open_id_authentication_tables/templates/migration.rb: -------------------------------------------------------------------------------- 1 | class <%= class_name %> < ActiveRecord::Migration 2 | def self.up 3 | drop_table :open_id_authentication_settings 4 | drop_table :open_id_authentication_nonces 5 | 6 | create_table :open_id_authentication_nonces, :force => true do |t| 7 | t.integer :timestamp, :null => false 8 | t.string :server_url, :null => true 9 | t.string :salt, :null => false 10 | end 11 | end 12 | 13 | def self.down 14 | drop_table :open_id_authentication_nonces 15 | 16 | create_table :open_id_authentication_nonces, :force => true do |t| 17 | t.integer :created 18 | t.string :nonce 19 | end 20 | 21 | create_table :open_id_authentication_settings, :force => true do |t| 22 | t.string :setting 23 | t.binary :value 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /config/initializers/new_rails_defaults.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # These settings change the behavior of Rails 2 apps and will be defaults 4 | # for Rails 3. You can remove this initializer when Rails 3 is released. 5 | 6 | if defined?(ActiveRecord) 7 | # Include Active Record class name as root for JSON serialized output. 8 | ActiveRecord::Base.include_root_in_json = true 9 | 10 | # Store the full class name (including module namespace) in STI type column. 11 | ActiveRecord::Base.store_full_sti_class = true 12 | end 13 | 14 | ActionController::Routing.generate_best_match = false 15 | 16 | # Use ISO 8601 format for JSON serialized times and dates. 17 | ActiveSupport.use_standard_json_time_format = true 18 | 19 | # Don't escape HTML entities in JSON, leave that for the #json_escape helper. 20 | # if you're including raw json in an HTML page. 21 | ActiveSupport.escape_html_entities_in_json = false -------------------------------------------------------------------------------- /spec/models/user_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe User do 4 | describe "validation" do 5 | it "should be valid with valid params" do 6 | User.make_unsaved.should be_valid 7 | end 8 | 9 | it "should not be valid with invalid email" do 10 | user = User.make_unsaved :email => 'invalid email' 11 | user.should_not be_valid 12 | user.should have_at_least(1).error_on(:email) 13 | end 14 | 15 | it "should not be valid with blank username" do 16 | user = User.make_unsaved :username => nil 17 | user.should_not be_valid 18 | user.should have_at_least(1).error_on(:username) 19 | end 20 | 21 | it "should not be valid if password confirmation does not match" do 22 | user = User.make_unsaved :password_confirmation => 'some password confirmation' 23 | user.should_not be_valid 24 | user.should have_at_least(1).error_on(:password) 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /config/initializers/action_view_extensions.rb: -------------------------------------------------------------------------------- 1 | # MonkeyPatch to add default classes to form inputs 2 | module ActionView 3 | module Helpers 4 | class InstanceTag 5 | def tag_with_default_class(name, options) 6 | options = add_default_class(name, options) 7 | tag_without_default_class(name, options) 8 | end 9 | alias_method_chain :tag, :default_class 10 | end 11 | 12 | module TagHelper 13 | def tag_with_default_class(name, options = nil, open = false, escape = true) 14 | options = add_default_class(name, options || {}) 15 | tag_without_default_class(name, options, open, escape) 16 | end 17 | alias_method_chain :tag, :default_class 18 | end 19 | end 20 | end 21 | 22 | private 23 | 24 | def add_default_class(name, options) 25 | options.stringify_keys 26 | if name.to_s == 'input' && options.include?('type') 27 | options['class'] = [options['type'], options['class']].compact.join(' ') 28 | end 29 | options 30 | end 31 | -------------------------------------------------------------------------------- /public/422.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | The change you wanted was rejected (422) 9 | 21 | 22 | 23 | 24 | 25 |
26 |

The change you wanted was rejected.

27 |

Maybe you tried to change something you didn't have access to.

28 |
29 | 30 | -------------------------------------------------------------------------------- /public/404.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | The page you were looking for doesn't exist (404) 9 | 21 | 22 | 23 | 24 | 25 |
26 |

The page you were looking for doesn't exist.

27 |

You may have mistyped the address or the page may have moved.

28 |
29 | 30 | -------------------------------------------------------------------------------- /public/500.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | We're sorry, but something went wrong (500) 9 | 21 | 22 | 23 | 24 | 25 |
26 |

We're sorry, but something went wrong.

27 |

We've been notified about this issue and we'll take a look at it shortly.

28 |
29 | 30 | 31 | -------------------------------------------------------------------------------- /vendor/plugins/acts_as_taggable_on_steroids/test/schema.rb: -------------------------------------------------------------------------------- 1 | ActiveRecord::Schema.define :version => 0 do 2 | create_table :tags, :force => true do |t| 3 | t.column :name, :string 4 | end 5 | 6 | create_table :taggings, :force => true do |t| 7 | t.column :tag_id, :integer 8 | t.column :taggable_id, :integer 9 | t.column :taggable_type, :string 10 | t.column :created_at, :datetime 11 | end 12 | 13 | create_table :users, :force => true do |t| 14 | t.column :name, :string 15 | end 16 | 17 | create_table :posts, :force => true do |t| 18 | t.column :text, :text 19 | t.column :cached_tag_list, :string 20 | t.column :user_id, :integer 21 | t.column :type, :string 22 | end 23 | 24 | create_table :photos, :force => true do |t| 25 | t.column :title, :string 26 | t.column :user_id, :integer 27 | end 28 | 29 | create_table :subscriptions, :force => true do |t| 30 | t.column :user_id, :integer 31 | t.column :magazine_id, :integer 32 | end 33 | 34 | create_table :magazines, :force => true do |t| 35 | t.column :name, :string 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /config/environments/production.rb: -------------------------------------------------------------------------------- 1 | # Settings specified here will take precedence over those in config/environment.rb 2 | 3 | # The production environment is meant for finished, "live" apps. 4 | # Code is not reloaded between requests 5 | config.cache_classes = true 6 | 7 | # Full error reports are disabled and caching is turned on 8 | config.action_controller.consider_all_requests_local = false 9 | config.action_controller.perform_caching = true 10 | config.action_view.cache_template_loading = true 11 | 12 | # See everything in the log (default is :info) 13 | # config.log_level = :debug 14 | 15 | # Use a different logger for distributed setups 16 | # config.logger = SyslogLogger.new 17 | 18 | # Use a different cache store in production 19 | # config.cache_store = :mem_cache_store 20 | 21 | # Enable serving of images, stylesheets, and javascripts from an asset server 22 | # config.action_controller.asset_host = "http://assets.example.com" 23 | 24 | # Disable delivery errors, bad email addresses will be ignored 25 | # config.action_mailer.raise_delivery_errors = false 26 | 27 | # Enable threaded mode 28 | # config.threadsafe! -------------------------------------------------------------------------------- /vendor/plugins/acts_as_taggable_on_steroids/MIT-LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2006 Jonathan Viney 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 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /vendor/plugins/open_id_authentication/lib/tasks/open_id_authentication_tasks.rake: -------------------------------------------------------------------------------- 1 | namespace :open_id_authentication do 2 | namespace :db do 3 | desc "Creates authentication tables for use with OpenIdAuthentication" 4 | task :create => :environment do 5 | generate_migration(["open_id_authentication_tables", "add_open_id_authentication_tables"]) 6 | end 7 | 8 | desc "Upgrade authentication tables from ruby-openid 1.x.x to 2.x.x" 9 | task :upgrade => :environment do 10 | generate_migration(["upgrade_open_id_authentication_tables", "upgrade_open_id_authentication_tables"]) 11 | end 12 | 13 | def generate_migration(args) 14 | require 'rails_generator' 15 | require 'rails_generator/scripts/generate' 16 | 17 | if ActiveRecord::Base.connection.supports_migrations? 18 | Rails::Generator::Scripts::Generate.new.run(args) 19 | else 20 | raise "Task unavailable to this database (no migration support)" 21 | end 22 | end 23 | 24 | desc "Clear the authentication tables" 25 | task :clear => :environment do 26 | OpenIdAuthentication::DbStore.cleanup_nonces 27 | OpenIdAuthentication::DbStore.cleanup_associations 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /public/design/readme.txt: -------------------------------------------------------------------------------- 1 | #################################################### 2 | # License # 3 | #################################################### 4 | 5 | This W3C-compliant, CSS-based website template has a 6 | Creative Commons Attribution-Share Alike 3.0 7 | Unported License. 8 | >> http://creativecommons.org/licenses/by-sa/3.0/ 9 | 10 | 11 | #################################################### 12 | # What You Can Do # 13 | #################################################### 14 | 15 | Feel free to remix, copy, distribute and transmit 16 | this template. All I ask is that you keep the 17 | footer links in the template intact. Also, if you 18 | alter, transform, or build upon this work, you 19 | may distribute the resulting work only under the 20 | same, similar or a compatible license. 21 | 22 | 23 | #################################################### 24 | # Feedback & Action # 25 | #################################################### 26 | 27 | I'd love to get your feedback on the template. 28 | Please contact me with your critics, ideas, etc. 29 | >> http://www.jabz.info/contact/jonas-jared-jacek/ 30 | 31 | If you like to contribute your remix, I will be 32 | more than happy to put your version on owmx.com 33 | and credit you in http://www.owmx.com/credits/. 34 | 35 | -------------------------------------------------------------------------------- /config/environments/test.rb: -------------------------------------------------------------------------------- 1 | # Settings specified here will take precedence over those in config/environment.rb 2 | 3 | # The test environment is used exclusively to run your application's 4 | # test suite. You never need to work with it otherwise. Remember that 5 | # your test database is "scratch space" for the test suite and is wiped 6 | # and recreated between test runs. Don't rely on the data there! 7 | config.cache_classes = true 8 | 9 | # Log error messages when you accidentally call methods on nil. 10 | config.whiny_nils = true 11 | 12 | # Show full error reports and disable caching 13 | config.action_controller.consider_all_requests_local = true 14 | config.action_controller.perform_caching = false 15 | config.action_view.cache_template_loading = true 16 | 17 | # Disable request forgery protection in test environment 18 | config.action_controller.allow_forgery_protection = false 19 | 20 | # Tell Action Mailer not to deliver emails to the real world. 21 | # The :test delivery method accumulates sent emails in the 22 | # ActionMailer::Base.deliveries array. 23 | config.action_mailer.delivery_method = :test 24 | 25 | # Use SQL instead of Active Record's schema dumper when creating the test database. 26 | # This is necessary if your schema can't be completely dumped by the schema dumper, 27 | # like if you have constraints or database-specific column types 28 | # config.active_record.schema_format = :sql 29 | -------------------------------------------------------------------------------- /vendor/plugins/open_id_authentication/test/normalize_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/test_helper' 2 | 3 | class NormalizeTest < Test::Unit::TestCase 4 | include OpenIdAuthentication 5 | 6 | NORMALIZATIONS = { 7 | "openid.aol.com/nextangler" => "http://openid.aol.com/nextangler", 8 | "http://openid.aol.com/nextangler" => "http://openid.aol.com/nextangler", 9 | "https://openid.aol.com/nextangler" => "https://openid.aol.com/nextangler", 10 | "HTTP://OPENID.AOL.COM/NEXTANGLER" => "http://openid.aol.com/NEXTANGLER", 11 | "HTTPS://OPENID.AOL.COM/NEXTANGLER" => "https://openid.aol.com/NEXTANGLER", 12 | "loudthinking.com" => "http://loudthinking.com/", 13 | "http://loudthinking.com" => "http://loudthinking.com/", 14 | "http://loudthinking.com:80" => "http://loudthinking.com/", 15 | "https://loudthinking.com:443" => "https://loudthinking.com/", 16 | "http://loudthinking.com:8080" => "http://loudthinking.com:8080/", 17 | "techno-weenie.net" => "http://techno-weenie.net/", 18 | "http://techno-weenie.net" => "http://techno-weenie.net/", 19 | "http://techno-weenie.net " => "http://techno-weenie.net/", 20 | "=name" => "=name" 21 | } 22 | 23 | def test_normalizations 24 | NORMALIZATIONS.each do |from, to| 25 | assert_equal to, normalize_identifier(from) 26 | end 27 | end 28 | 29 | def test_broken_open_id 30 | assert_raises(InvalidOpenId) { normalize_identifier(nil) } 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /config/environment.rb: -------------------------------------------------------------------------------- 1 | RAILS_GEM_VERSION = '2.3.8' unless defined? RAILS_GEM_VERSION 2 | 3 | require File.join(File.dirname(__FILE__), 'boot') 4 | 5 | Rails::Initializer.run do |config| 6 | # Settings in config/environments/* take precedence over those specified here. 7 | # Application configuration should go into files in config/initializers 8 | # -- all .rb files in that directory are automatically loaded. 9 | # Add additional load paths for your own custom dirs 10 | # config.load_paths += %W( #{RAILS_ROOT}/extras ) 11 | 12 | # Only load the plugins named here, in the order given (default is alphabetical). 13 | # :all can be used as a placeholder for all plugins not explicitly named 14 | # config.plugins = [ :exception_notification, :ssl_requirement, :all ] 15 | 16 | # Skip frameworks you're not going to use. To use Rails without a database, 17 | # you must remove the Active Record framework. 18 | # config.frameworks -= [ :active_record, :active_resource, :action_mailer ] 19 | 20 | # Activate observers that should always be running 21 | # config.active_record.observers = :cacher, :garbage_collector, :forum_observer 22 | 23 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. 24 | # Run "rake -D time" for a list of tasks for finding time zone names. 25 | config.time_zone = 'UTC' 26 | 27 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. 28 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}')] 29 | # config.i18n.default_locale = :de 30 | end 31 | 32 | ActionView::Base.default_form_builder = CustomFormBuilder 33 | -------------------------------------------------------------------------------- /app/controllers/snippets_controller.rb: -------------------------------------------------------------------------------- 1 | class SnippetsController < ApplicationController 2 | before_filter :require_user 3 | 4 | def index 5 | @snippets = current_user.snippets.all :order => 'snippets.created_at DESC' 6 | 7 | respond_to do |format| 8 | format.html 9 | end 10 | end 11 | 12 | def show 13 | @snippet = current_user.snippets.find(params[:id]) 14 | 15 | respond_to do |format| 16 | format.html 17 | end 18 | end 19 | 20 | def new 21 | @snippet = Snippet.new 22 | 23 | respond_to do |format| 24 | format.html 25 | end 26 | end 27 | 28 | def edit 29 | @snippet = current_user.snippets.find(params[:id]) 30 | end 31 | 32 | def create 33 | @snippet = current_user.snippets.new(params[:snippet]) 34 | 35 | respond_to do |format| 36 | if @snippet.save 37 | format.html { redirect_to([current_user, @snippet], :notice => 'Snippet was successfully created.') } 38 | else 39 | format.html { render :action => "new" } 40 | end 41 | end 42 | end 43 | 44 | def update 45 | @snippet = current_user.snippets.find(params[:id]) 46 | 47 | respond_to do |format| 48 | if @snippet.update_attributes(params[:snippet]) 49 | format.html { redirect_to([current_user, @snippet], :notice => 'Snippet was successfully updated.') } 50 | else 51 | format.html { render :action => "edit" } 52 | end 53 | end 54 | end 55 | 56 | def destroy 57 | @snippet = current_user.snippets.find(params[:id]) 58 | @snippet.destroy 59 | 60 | respond_to do |format| 61 | format.html { redirect_to user_snippets_url(current_user) } 62 | end 63 | end 64 | end 65 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: http://rubygems.org/ 3 | specs: 4 | actionmailer (2.3.8) 5 | actionpack (= 2.3.8) 6 | actionpack (2.3.8) 7 | activesupport (= 2.3.8) 8 | rack (~> 1.1.0) 9 | activerecord (2.3.8) 10 | activesupport (= 2.3.8) 11 | activeresource (2.3.8) 12 | activesupport (= 2.3.8) 13 | activesupport (2.3.8) 14 | authlogic (2.1.6) 15 | activesupport 16 | authlogic-oid (1.0.4) 17 | authlogic 18 | cgi_multipart_eof_fix (2.5.0) 19 | daemons (1.1.0) 20 | faker (0.3.1) 21 | fastthread (1.0.7) 22 | gem_plugin (0.2.3) 23 | haml (2.2.24) 24 | jrails (0.6.0) 25 | machinist (1.0.6) 26 | mongrel (1.1.5) 27 | cgi_multipart_eof_fix (>= 2.4) 28 | daemons (>= 1.0.3) 29 | fastthread (>= 1.0.1) 30 | gem_plugin (>= 0.2.3) 31 | mysql (2.8.1) 32 | pg (0.9.0) 33 | rack (1.1.0) 34 | rails (2.3.8) 35 | actionmailer (= 2.3.8) 36 | actionpack (= 2.3.8) 37 | activerecord (= 2.3.8) 38 | activeresource (= 2.3.8) 39 | activesupport (= 2.3.8) 40 | rake (>= 0.8.3) 41 | rake (0.8.7) 42 | rspec (1.3.1) 43 | rspec-rails (1.3.3) 44 | rack (>= 1.0.0) 45 | rspec (= 1.3.1) 46 | ruby-openid (2.1.8) 47 | simple-navigation (2.5.4) 48 | sqlite3-ruby (1.3.1) 49 | 50 | PLATFORMS 51 | ruby 52 | 53 | DEPENDENCIES 54 | authlogic (~> 2.1.6) 55 | authlogic-oid (~> 1.0.4) 56 | faker (~> 0.3.1) 57 | haml (~> 2.2.24) 58 | jrails (~> 0.6) 59 | machinist (~> 1.0.6) 60 | mongrel 61 | mysql 62 | pg 63 | rails (= 2.3.8) 64 | rspec (~> 1.3.0) 65 | rspec-rails (~> 1.3.2) 66 | ruby-openid (~> 2.1.8) 67 | simple-navigation (~> 2.5.3) 68 | sqlite3-ruby 69 | -------------------------------------------------------------------------------- /app/views/layouts/frontend.html.haml: -------------------------------------------------------------------------------- 1 | 2 | %html 3 | %head 4 | %title Code Snippets 5 | %meta{:content => 'text/html; charset=utf-8', 'http-equiv' => 'content-type'} 6 | %meta{:content => '', :name => 'keywords'} 7 | %meta{:content => '', :name => 'description'} 8 | %link{:rel => "shortcut icon", :href => "/favicon.gif"} 9 | = stylesheet_link_tag 'highlight-github', 'styles.css' 10 | %body 11 | #a 12 | %header 13 | = link_to 'Share Code Snippets', root_path, :title => 'Code Snippets' 14 | %p Always forget something? Can't keep too much in your head? Why don't you save your code snippets and share them your friends? It's easy now! 15 | %section.main 16 | = render_flash 17 | = yield 18 | %aside 19 | %h4 Search 20 | %form{:action => "#", :class => "s"} 21 | 22 | %nav 23 | %h4 Navigation 24 | = render_navigation 25 | %h4 Example Tag Cloud 26 | %ul#tagcloud 27 | - tag_cloud Snippet.tag_counts, %w(size-1 size-2 size-3 size-4) do |tag, css_class| 28 | %li{:class => css_class}= link_to tag.name, '#', :title => tag.name 29 | %footer 30 | %p Template Design & Markup by
Jonas Jacek for Free HTML5 & CSS3 Web Templates. 31 | = javascript_include_tag 'jquery.min', 'jrails.min', 'highlight.min', 'jquery.make_expandable','application' 32 | :javascript 33 | hljs.initHighlightingOnLoad(); -------------------------------------------------------------------------------- /vendor/plugins/open_id_authentication/lib/open_id_authentication/db_store.rb: -------------------------------------------------------------------------------- 1 | require 'openid/store/interface' 2 | 3 | module OpenIdAuthentication 4 | class DbStore < OpenID::Store::Interface 5 | def self.cleanup_nonces 6 | now = Time.now.to_i 7 | Nonce.delete_all(["timestamp > ? OR timestamp < ?", now + OpenID::Nonce.skew, now - OpenID::Nonce.skew]) 8 | end 9 | 10 | def self.cleanup_associations 11 | now = Time.now.to_i 12 | Association.delete_all(['issued + lifetime > ?',now]) 13 | end 14 | 15 | def store_association(server_url, assoc) 16 | remove_association(server_url, assoc.handle) 17 | Association.create(:server_url => server_url, 18 | :handle => assoc.handle, 19 | :secret => assoc.secret, 20 | :issued => assoc.issued, 21 | :lifetime => assoc.lifetime, 22 | :assoc_type => assoc.assoc_type) 23 | end 24 | 25 | def get_association(server_url, handle = nil) 26 | assocs = if handle.blank? 27 | Association.find_all_by_server_url(server_url) 28 | else 29 | Association.find_all_by_server_url_and_handle(server_url, handle) 30 | end 31 | 32 | assocs.reverse.each do |assoc| 33 | a = assoc.from_record 34 | if a.expires_in == 0 35 | assoc.destroy 36 | else 37 | return a 38 | end 39 | end if assocs.any? 40 | 41 | return nil 42 | end 43 | 44 | def remove_association(server_url, handle) 45 | Association.delete_all(['server_url = ? AND handle = ?', server_url, handle]) > 0 46 | end 47 | 48 | def use_nonce(server_url, timestamp, salt) 49 | return false if Nonce.find_by_server_url_and_timestamp_and_salt(server_url, timestamp, salt) 50 | return false if (timestamp - Time.now.to_i).abs > OpenID::Nonce.skew 51 | Nonce.create(:server_url => server_url, :timestamp => timestamp, :salt => salt) 52 | return true 53 | end 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /vendor/plugins/open_id_authentication/CHANGELOG: -------------------------------------------------------------------------------- 1 | * Fake HTTP method from OpenID server since they only support a GET. Eliminates the need to set an extra route to match the server's reply. [Josh Peek] 2 | 3 | * OpenID 2.0 recommends that forms should use the field name "openid_identifier" rather than "openid_url" [Josh Peek] 4 | 5 | * Return open_id_response.display_identifier to the application instead of .endpoints.claimed_id. [nbibler] 6 | 7 | * Add Timeout protection [Rick] 8 | 9 | * An invalid identity url passed through authenticate_with_open_id will no longer raise an InvalidOpenId exception. Instead it will return Result[:missing] to the completion block. 10 | 11 | * Allow a return_to option to be used instead of the requested url [Josh Peek] 12 | 13 | * Updated plugin to use Ruby OpenID 2.x.x [Josh Peek] 14 | 15 | * Tied plugin to ruby-openid 1.1.4 gem until we can make it compatible with 2.x [DHH] 16 | 17 | * Use URI instead of regexps to normalize the URL and gain free, better matching #8136 [dkubb] 18 | 19 | * Allow -'s in #normalize_url [Rick] 20 | 21 | * remove instance of mattr_accessor, it was breaking tests since they don't load ActiveSupport. Fix Timeout test [Rick] 22 | 23 | * Throw a InvalidOpenId exception instead of just a RuntimeError when the URL can't be normalized [DHH] 24 | 25 | * Just use the path for the return URL, so extra query parameters don't interfere [DHH] 26 | 27 | * Added a new default database-backed store after experiencing trouble with the filestore on NFS. The file store is still available as an option [DHH] 28 | 29 | * Added normalize_url and applied it to all operations going through the plugin [DHH] 30 | 31 | * Removed open_id? as the idea of using the same input box for both OpenID and username has died -- use using_open_id? instead (which checks for the presence of params[:openid_url] by default) [DHH] 32 | 33 | * Added OpenIdAuthentication::Result to make it easier to deal with default situations where you don't care to do something particular for each error state [DHH] 34 | 35 | * Stop relying on root_url being defined, we can just grab the current url instead [DHH] -------------------------------------------------------------------------------- /vendor/plugins/open_id_authentication/test/open_id_authentication_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/test_helper' 2 | 3 | class OpenIdAuthenticationTest < Test::Unit::TestCase 4 | def setup 5 | @controller = Class.new do 6 | include OpenIdAuthentication 7 | def params() {} end 8 | end.new 9 | end 10 | 11 | def test_authentication_should_fail_when_the_identity_server_is_missing 12 | open_id_consumer = mock() 13 | open_id_consumer.expects(:begin).raises(OpenID::OpenIDError) 14 | @controller.expects(:open_id_consumer).returns(open_id_consumer) 15 | @controller.expects(:logger).returns(mock(:error => true)) 16 | 17 | @controller.send(:authenticate_with_open_id, "http://someone.example.com") do |result, identity_url| 18 | assert result.missing? 19 | assert_equal "Sorry, the OpenID server couldn't be found", result.message 20 | end 21 | end 22 | 23 | def test_authentication_should_be_invalid_when_the_identity_url_is_invalid 24 | @controller.send(:authenticate_with_open_id, "!") do |result, identity_url| 25 | assert result.invalid?, "Result expected to be invalid but was not" 26 | assert_equal "Sorry, but this does not appear to be a valid OpenID", result.message 27 | end 28 | end 29 | 30 | def test_authentication_should_fail_when_the_identity_server_times_out 31 | open_id_consumer = mock() 32 | open_id_consumer.expects(:begin).raises(Timeout::Error, "Identity Server took too long.") 33 | @controller.expects(:open_id_consumer).returns(open_id_consumer) 34 | @controller.expects(:logger).returns(mock(:error => true)) 35 | 36 | @controller.send(:authenticate_with_open_id, "http://someone.example.com") do |result, identity_url| 37 | assert result.missing? 38 | assert_equal "Sorry, the OpenID server couldn't be found", result.message 39 | end 40 | end 41 | 42 | def test_authentication_should_begin_when_the_identity_server_is_present 43 | @controller.expects(:begin_open_id_authentication) 44 | @controller.send(:authenticate_with_open_id, "http://someone.example.com") 45 | end 46 | end 47 | -------------------------------------------------------------------------------- /vendor/plugins/acts_as_taggable_on_steroids/acts_as_taggable_on_steroids.gemspec: -------------------------------------------------------------------------------- 1 | Gem::Specification.new do |s| 2 | s.name = "acts_as_taggable_on_steroids" 3 | s.version = "1.1" 4 | s.date = "2009-06-11" 5 | s.summary = "Rails plugin that is based on acts_as_taggable by DHH but includes extras such as tests, smarter tag assignment, and tag cloud calculations." 6 | s.email = "jonathan.viney@gmail.com" 7 | s.homepage = "http://github.com/jviney/acts_as_taggable_on_steroids" 8 | s.description = "Rails plugin that is based on acts_as_taggable by DHH but includes extras such as tests, smarter tag assignment, and tag cloud calculations." 9 | s.has_rdoc = true 10 | s.rdoc_options = ["--inline-source", "--charset=UTF-8"] 11 | s.rubyforge_project = "acts_as_taggable_on_steroids" 12 | s.authors = "Jonathan Viney" 13 | s.files = [ 14 | "acts_as_taggable_on_steroids.gemspec", 15 | "CHANGELOG", 16 | "generators/acts_as_taggable_migration", 17 | "generators/acts_as_taggable_migration/acts_as_taggable_migration_generator.rb", 18 | "generators/acts_as_taggable_migration/templates", 19 | "generators/acts_as_taggable_migration/templates/migration.rb", 20 | "init.rb", 21 | "lib/acts_as_taggable.rb", 22 | "lib/tag.rb", 23 | "lib/tag_list.rb", 24 | "lib/tagging.rb", 25 | "lib/tags_helper.rb", 26 | "MIT-LICENSE", 27 | "Rakefile", 28 | "README", 29 | ] 30 | s.test_files = [ 31 | "test/abstract_unit.rb", 32 | "test/acts_as_taggable_test.rb", 33 | "test/database.yml", 34 | "test/fixtures", 35 | "test/fixtures/magazine.rb", 36 | "test/fixtures/magazines.yml", 37 | "test/fixtures/photo.rb", 38 | "test/fixtures/photos.yml", 39 | "test/fixtures/post.rb", 40 | "test/fixtures/posts.yml", 41 | "test/fixtures/special_post.rb", 42 | "test/fixtures/subscription.rb", 43 | "test/fixtures/subscriptions.yml", 44 | "test/fixtures/taggings.yml", 45 | "test/fixtures/tags.yml", 46 | "test/fixtures/user.rb", 47 | "test/fixtures/users.yml", 48 | "test/schema.rb", 49 | "test/tag_list_test.rb", 50 | "test/tag_test.rb", 51 | "test/tagging_test.rb", 52 | "test/tags_helper_test.rb" 53 | ] 54 | end 55 | -------------------------------------------------------------------------------- /spec/controllers/users_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe UsersController do 4 | describe "routing" do 5 | it "should know the route to /register GET" do 6 | params_from(:get, '/register').should == { :controller => "users", :action => "new" } 7 | end 8 | it "should know the route to /register POST" do 9 | params_from(:post, '/register').should == { :controller => "users", :action => "create" } 10 | end 11 | it "should know the route to /users/1/edit GET" do 12 | params_from(:get, '/users/1/edit').should == { :controller => "users", :action => "edit", :id => '1' } 13 | end 14 | it "should know the route to /users/1 PUT" do 15 | params_from(:put, '/users/1').should == { :controller => "users", :action => "update", :id => '1' } 16 | end 17 | end 18 | 19 | describe "#new" do 20 | it "should assign @user to new User object" do 21 | get :new 22 | assigns[:user].should be_an_instance_of(User) 23 | end 24 | end 25 | 26 | describe "#create" do 27 | let(:user) { double('user') } 28 | before(:each) { User.should_receive(:new).and_return(user) } 29 | 30 | it "should render action \"new\" if user not valid" do 31 | user.should_receive(:save).and_yield(false) 32 | post :create 33 | response.should render_template('new') 34 | end 35 | 36 | it "should set notice and redirect if user is valid" do 37 | user.should_receive(:save).and_yield(true) 38 | post :create 39 | response.should be_redirect 40 | flash[:notice].should_not be_blank 41 | end 42 | end 43 | 44 | describe "with logged in user" do 45 | integrate_views 46 | setup :activate_authlogic 47 | 48 | let(:user) { User.make } 49 | before(:each) { UserSession.create(user) } 50 | 51 | describe "#edit" do 52 | it "load current user" do 53 | get :edit, :id => 1 54 | assigns[:user].should eql(user) 55 | end 56 | end 57 | 58 | describe "#update" do 59 | it "should update user and redirect" do 60 | user.should_receive(:save).and_yield(true) 61 | controller.should_receive(:current_user).at_least(1).and_return(user) 62 | put :update, :id => 1 63 | response.should be_redirect 64 | end 65 | end 66 | end 67 | 68 | 69 | end -------------------------------------------------------------------------------- /db/schema.rb: -------------------------------------------------------------------------------- 1 | # This file is auto-generated from the current state of the database. Instead of editing this file, 2 | # please use the migrations feature of Active Record to incrementally modify your database, and 3 | # then regenerate this schema definition. 4 | # 5 | # Note that this schema.rb definition is the authoritative source for your database schema. If you need 6 | # to create the application database on another system, you should be using db:schema:load, not running 7 | # all the migrations from scratch. The latter is a flawed and unsustainable approach (the more migrations 8 | # you'll amass, the slower it'll run and the greater likelihood for issues). 9 | # 10 | # It's strongly recommended to check this file into your version control system. 11 | 12 | ActiveRecord::Schema.define(:version => 20101019143937) do 13 | 14 | create_table "open_id_authentication_associations", :force => true do |t| 15 | t.integer "issued" 16 | t.integer "lifetime" 17 | t.string "handle" 18 | t.string "assoc_type" 19 | t.binary "server_url" 20 | t.binary "secret" 21 | end 22 | 23 | create_table "open_id_authentication_nonces", :force => true do |t| 24 | t.integer "timestamp", :null => false 25 | t.string "server_url" 26 | t.string "salt", :null => false 27 | end 28 | 29 | create_table "snippets", :force => true do |t| 30 | t.integer "user_id" 31 | t.text "description" 32 | t.text "code" 33 | t.datetime "created_at" 34 | t.datetime "updated_at" 35 | t.string "cached_tag_list" 36 | end 37 | 38 | create_table "taggings", :force => true do |t| 39 | t.integer "tag_id" 40 | t.integer "taggable_id" 41 | t.string "taggable_type" 42 | t.datetime "created_at" 43 | end 44 | 45 | add_index "taggings", ["tag_id"], :name => "index_taggings_on_tag_id" 46 | add_index "taggings", ["taggable_id", "taggable_type"], :name => "index_taggings_on_taggable_id_and_taggable_type" 47 | 48 | create_table "tags", :force => true do |t| 49 | t.string "name" 50 | end 51 | 52 | create_table "users", :force => true do |t| 53 | t.string "username" 54 | t.string "email" 55 | t.string "crypted_password" 56 | t.string "password_salt" 57 | t.string "persistence_token" 58 | t.string "openid_identifier" 59 | end 60 | 61 | end 62 | -------------------------------------------------------------------------------- /config/routes.rb: -------------------------------------------------------------------------------- 1 | ActionController::Routing::Routes.draw do |map| 2 | # The priority is based upon order of creation: first created -> highest priority. 3 | 4 | # Sample of regular route: 5 | # map.connect 'products/:id', :controller => 'catalog', :action => 'view' 6 | # Keep in mind you can assign values other than :controller and :action 7 | 8 | # Sample of named route: 9 | # map.purchase 'products/:id/purchase', :controller => 'catalog', :action => 'purchase' 10 | # This route can be invoked with purchase_url(:id => product.id) 11 | 12 | # Sample resource route (maps HTTP verbs to controller actions automatically): 13 | # map.resources :products 14 | 15 | # Sample resource route with options: 16 | # map.resources :products, :member => { :short => :get, :toggle => :post }, :collection => { :sold => :get } 17 | 18 | # Sample resource route with sub-resources: 19 | # map.resources :products, :has_many => [ :comments, :sales ], :has_one => :seller 20 | 21 | # Sample resource route with more complex sub-resources 22 | # map.resources :products do |products| 23 | # products.resources :comments 24 | # products.resources :sales, :collection => { :recent => :get } 25 | # end 26 | 27 | # Sample resource route within a namespace: 28 | # map.namespace :admin do |admin| 29 | # # Directs /admin/products/* to Admin::ProductsController (app/controllers/admin/products_controller.rb) 30 | # admin.resources :products 31 | # end 32 | 33 | # You can have the root of your site routed with map.root -- just remember to delete public/index.html. 34 | 35 | map.root :controller => "welcome" 36 | map.resources :users do |user| 37 | user.resources :snippets 38 | end 39 | 40 | map.home 'home', :controller => 'home', :action => 'index', :conditions => { :method => :get } 41 | map.register 'register', :controller => 'users', :action => 'new', :conditions => { :method => :get } 42 | map.users 'register', :controller => 'users', :action => 'create', :conditions => { :method => :post } 43 | 44 | map.login 'login', :controller => 'user_sessions', :action => 'new', :conditions => { :method => :get } 45 | map.user_sessions 'login', :controller => 'user_sessions', :action => 'create', :conditions => { :method => :post } 46 | map.logout 'logout', :controller => 'user_sessions', :action => 'destroy' 47 | 48 | end 49 | -------------------------------------------------------------------------------- /vendor/plugins/acts_as_taggable_on_steroids/test/tag_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/abstract_unit' 2 | 3 | class TagTest < ActiveSupport::TestCase 4 | def test_name_required 5 | t = Tag.create 6 | assert_match /blank/, t.errors[:name].to_s 7 | end 8 | 9 | def test_name_unique 10 | t = Tag.create!(:name => "My tag") 11 | duplicate = t.clone 12 | 13 | assert !duplicate.save 14 | assert_match /taken/, duplicate.errors[:name].to_s 15 | end 16 | 17 | def test_taggings 18 | assert_equivalent [taggings(:jonathan_sky_good), taggings(:sam_flowers_good), taggings(:sam_flower_good), taggings(:ruby_good)], tags(:good).taggings 19 | assert_equivalent [taggings(:sam_ground_bad), taggings(:jonathan_bad_cat_bad)], tags(:bad).taggings 20 | end 21 | 22 | def test_to_s 23 | assert_equal tags(:good).name, tags(:good).to_s 24 | end 25 | 26 | def test_equality 27 | assert_equal tags(:good), tags(:good) 28 | assert_equal Tag.find(tags(:good).id), Tag.find(tags(:good).id) 29 | assert_equal Tag.new(:name => 'A'), Tag.new(:name => 'A') 30 | assert_not_equal Tag.new(:name => 'A'), Tag.new(:name => 'B') 31 | end 32 | 33 | def test_taggings_removed_when_tag_destroyed 34 | assert_difference "Tagging.count", -Tagging.count(:conditions => { :tag_id => tags(:good).id }) do 35 | assert tags(:good).destroy 36 | end 37 | end 38 | 39 | def test_all_counts 40 | assert_tag_counts Tag.counts, :good => 4, :bad => 2, :nature => 10, :question => 2, :animal => 3 41 | end 42 | 43 | def test_all_counts_with_string_conditions 44 | assert_tag_counts Tag.counts(:conditions => 'taggings.created_at >= \'2006-08-15\''), 45 | :question => 1, :bad => 1, :animal => 1, :nature => 2, :good => 2 46 | end 47 | 48 | def test_all_counts_with_array_conditions 49 | assert_tag_counts Tag.counts(:conditions => ['taggings.created_at >= ?', '2006-08-15']), 50 | :question => 1, :bad => 1, :animal => 1, :nature => 2, :good => 2 51 | end 52 | 53 | def test_all_counts_with_hash_conditions 54 | tag_counts = Tag.counts( 55 | :conditions => { 56 | :taggings => { :created_at => (DateTime.parse('2006-08-14 23:59') .. DateTime.parse('4000-01-01')) } 57 | } 58 | ) 59 | 60 | assert_tag_counts tag_counts, :question => 1, :bad => 1, :animal => 1, :nature => 2, :good => 2 61 | end 62 | end 63 | -------------------------------------------------------------------------------- /spec/controllers/user_sessions_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe UserSessionsController do 4 | setup :activate_authlogic 5 | 6 | describe "routing" do 7 | it "should know the route to /login GET" do 8 | params_from(:get, '/login').should == { :controller => 'user_sessions', :action => 'new' } 9 | end 10 | it "should know the route to /login POST" do 11 | params_from(:post, '/login').should == { :controller => 'user_sessions', :action => 'create' } 12 | end 13 | it "should know the route to /logout GET" do 14 | params_from(:get, '/logout').should == { :controller => 'user_sessions', :action => 'destroy' } 15 | end 16 | end 17 | 18 | 19 | describe "#new" do 20 | it "should assign @user_session variable" do 21 | get :new 22 | assigns[:user_session].should be_an_instance_of(UserSession) 23 | end 24 | end 25 | 26 | describe "#create" do 27 | let(:user) { User.make :password => 'password' } 28 | 29 | it "should render action \"new\" if credentials not valid" do 30 | post :create 31 | response.should render_template('new') 32 | end 33 | it "should set notice and redirect to home_url if credentials are valid" do 34 | post :create, :user_session => { :username => user.username, :password => 'password' } 35 | flash[:notice].should_not be_blank 36 | response.should redirect_to(home_url) 37 | end 38 | it "should login by email as well" do 39 | post :create, :user_session => { :username => user.email, :password => 'password' } 40 | assert_equal controller.session["user_credentials"], user.persistence_token 41 | end 42 | end 43 | 44 | describe "#destroy" do 45 | it "should destroy the session if it's present, set notice and redirect if logged in" do 46 | user_session = double('user_session') 47 | UserSession.should_receive(:find).and_return(user_session) 48 | user_session.should_receive(:destroy).and_return(nil) 49 | get :destroy 50 | flash[:notice].should =~ /Successfully logged out/ 51 | response.should be_redirect 52 | end 53 | 54 | it "should set notice and redirect if not logged in" do 55 | UserSession.should_receive(:find).and_return(nil) 56 | get :destroy 57 | flash[:notice].should =~ /You haven't logged in/ 58 | response.should be_redirect 59 | end 60 | 61 | end 62 | 63 | end 64 | -------------------------------------------------------------------------------- /public/stylesheets/highlight-github.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | github.com style (c) Vasily Polovnyov 4 | 5 | */ 6 | 7 | pre { 8 | display:block;padding:15px; 9 | color: #000; 10 | background: #eee; 11 | -moz-border-radius:4px;-webkit-border-radius:4px; 12 | -moz-box-shadow:0 2px 2px rgba(0,0,0,0.4); 13 | -webkit-box-shadow:0 2px 2px rgba(0,0,0,0.4); 14 | overflow:hidden; 15 | line-height:111%; 16 | max-height:7000px; 17 | } 18 | 19 | pre .comment, 20 | pre .template_comment, 21 | pre .diff .header, 22 | pre .javadoc { 23 | color: #998; 24 | font-style: italic 25 | } 26 | 27 | pre .keyword, 28 | pre .css .rule .keyword, 29 | pre .winutils, 30 | pre .javascript .title, 31 | pre .lisp .title, 32 | pre .subst { 33 | color: #000; 34 | font-weight: bold 35 | } 36 | 37 | pre .number, 38 | pre .hexcolor { 39 | color: #40a070 40 | } 41 | 42 | pre .string, 43 | pre .tag .value, 44 | pre .phpdoc, 45 | pre .tex .formula { 46 | color: #d14 47 | } 48 | 49 | pre .title, 50 | pre .id { 51 | color: #900; 52 | font-weight: bold 53 | } 54 | 55 | pre .javascript .title, 56 | pre .lisp .title, 57 | pre .subst { 58 | font-weight: normal 59 | } 60 | 61 | pre .class .title, 62 | pre .tex .command { 63 | color: #458; 64 | font-weight: bold 65 | } 66 | 67 | pre .tag, 68 | pre .css .keyword, 69 | pre .html .keyword, 70 | pre .tag .title, 71 | pre .django .tag .keyword { 72 | color: #000080; 73 | font-weight: normal 74 | } 75 | 76 | pre .attribute, 77 | pre .variable, 78 | pre .instancevar, 79 | pre .lisp .body { 80 | color: #008080 81 | } 82 | 83 | pre .regexp { 84 | color: #009926 85 | } 86 | 87 | pre .class { 88 | color: #458; 89 | font-weight: bold 90 | } 91 | 92 | pre .symbol, 93 | pre .ruby .symbol .string, 94 | pre .ruby .symbol .keyword, 95 | pre .ruby .symbol .keymethods, 96 | pre .lisp .keyword, 97 | pre .tex .special { 98 | color: #990073 99 | } 100 | 101 | pre .builtin, 102 | pre .built_in, 103 | pre .lisp .title { 104 | color: #0086b3 105 | } 106 | 107 | pre .preprocessor, 108 | pre .pi, 109 | pre .doctype, 110 | pre .shebang, 111 | pre .cdata { 112 | color: #999; 113 | font-weight: bold 114 | } 115 | 116 | pre .deletion { 117 | background: #fdd 118 | } 119 | 120 | pre .addition { 121 | background: #dfd 122 | } 123 | 124 | pre .diff .change { 125 | background: #0086b3 126 | } 127 | 128 | pre .chunk { 129 | color: #aaa 130 | } 131 | 132 | pre .tex .formula { 133 | opacity: 0.5; 134 | } 135 | -------------------------------------------------------------------------------- /vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/taggings.yml: -------------------------------------------------------------------------------- 1 | # Posts 2 | jonathan_sky_good: 3 | tag: good 4 | taggable: jonathan_sky (Post) 5 | created_at: 2006-08-01 6 | 7 | jonathan_sky_nature: 8 | tag: nature 9 | taggable: jonathan_sky (Post) 10 | created_at: 2006-08-02 11 | 12 | jonathan_grass_nature: 13 | tag: nature 14 | taggable: jonathan_grass (Post) 15 | created_at: 2006-08-03 16 | 17 | jonathan_rain_question: 18 | tag: question 19 | taggable: jonathan_rain (Post) 20 | created_at: 2006-08-04 21 | 22 | jonathan_rain_nature: 23 | tag: nature 24 | taggable: jonathan_rain (Post) 25 | created_at: 2006-08-05 26 | 27 | jonathan_cloudy_nature: 28 | tag: nature 29 | taggable: jonathan_cloudy (Post) 30 | created_at: 2006-08-06 31 | 32 | jonathan_still_cloudy_nature: 33 | tag: nature 34 | taggable: jonathan_still_cloudy (Post) 35 | created_at: 2006-08-07 36 | 37 | sam_ground_nature: 38 | tag: nature 39 | taggable: sam_ground (Post) 40 | created_at: 2006-08-08 41 | 42 | sam_ground_bad: 43 | tag: bad 44 | taggable: sam_ground (Post) 45 | created_at: 2006-08-09 46 | 47 | sam_flowers_good: 48 | tag: good 49 | taggable: sam_flowers (Post) 50 | created_at: 2006-08-10 51 | 52 | sam_flowers_nature: 53 | tag: nature 54 | taggable: sam_flowers (Post) 55 | created_at: 2006-08-11 56 | 57 | # Photos 58 | jonathan_dog_animal: 59 | tag: animal 60 | taggable: jonathan_dog (Photo) 61 | created_at: 2006-08-12 62 | 63 | jonathan_dog_nature: 64 | tag: nature 65 | taggable: jonathan_dog (Photo) 66 | created_at: 2006-08-13 67 | 68 | jonathan_questioning_dog_animal: 69 | tag: animal 70 | taggable: jonathan_questioning_dog (Photo) 71 | created_at: 2006-08-14 72 | 73 | jonathan_questioning_dog_question: 74 | tag: question 75 | taggable: jonathan_questioning_dog (Photo) 76 | created_at: 2006-08-15 77 | 78 | jonathan_bad_cat_bad: 79 | tag: bad 80 | taggable: jonathan_bad_cat (Photo) 81 | created_at: 2006-08-16 82 | 83 | jonathan_bad_cat_animal: 84 | tag: animal 85 | taggable: jonathan_bad_cat (Photo) 86 | created_at: 2006-08-17 87 | 88 | sam_flower_nature: 89 | tag: nature 90 | taggable: sam_flower (Photo) 91 | created_at: 2006-08-18 92 | 93 | sam_flower_good: 94 | tag: good 95 | taggable: sam_flower (Photo) 96 | created_at: 2006-08-19 97 | 98 | sam_sky_nature: 99 | tag: nature 100 | taggable: sam_sky (Photo) 101 | created_at: 2006-08-20 102 | 103 | # Magazines 104 | ruby_good: 105 | tag: good 106 | taggable: ruby (Magazine) 107 | created_at: 2007-08-25 108 | -------------------------------------------------------------------------------- /vendor/plugins/acts_as_taggable_on_steroids/lib/tag.rb: -------------------------------------------------------------------------------- 1 | class Tag < ActiveRecord::Base 2 | has_many :taggings, :dependent => :destroy 3 | 4 | validates_presence_of :name 5 | validates_uniqueness_of :name 6 | 7 | cattr_accessor :destroy_unused 8 | self.destroy_unused = false 9 | 10 | # LIKE is used for cross-database case-insensitivity 11 | def self.find_or_create_with_like_by_name(name) 12 | find(:first, :conditions => ["name LIKE ?", name]) || create(:name => name) 13 | end 14 | 15 | def ==(object) 16 | super || (object.is_a?(Tag) && name == object.name) 17 | end 18 | 19 | def to_s 20 | name 21 | end 22 | 23 | def count 24 | read_attribute(:count).to_i 25 | end 26 | 27 | class << self 28 | # Calculate the tag counts for all tags. 29 | # :start_at - Restrict the tags to those created after a certain time 30 | # :end_at - Restrict the tags to those created before a certain time 31 | # :conditions - A piece of SQL conditions to add to the query 32 | # :limit - The maximum number of tags to return 33 | # :order - A piece of SQL to order by. Eg 'count desc' or 'taggings.created_at desc' 34 | # :at_least - Exclude tags with a frequency less than the given value 35 | # :at_most - Exclude tags with a frequency greater than the given value 36 | def counts(options = {}) 37 | find(:all, options_for_counts(options)) 38 | end 39 | 40 | def options_for_counts(options = {}) 41 | options.assert_valid_keys :start_at, :end_at, :conditions, :at_least, :at_most, :order, :limit, :joins 42 | options = options.dup 43 | 44 | start_at = sanitize_sql(["#{Tagging.table_name}.created_at >= ?", options.delete(:start_at)]) if options[:start_at] 45 | end_at = sanitize_sql(["#{Tagging.table_name}.created_at <= ?", options.delete(:end_at)]) if options[:end_at] 46 | 47 | conditions = [ 48 | (sanitize_sql(options.delete(:conditions)) if options[:conditions]), 49 | start_at, 50 | end_at 51 | ].compact 52 | 53 | conditions = conditions.join(' AND ') if conditions.any? 54 | 55 | joins = ["INNER JOIN #{Tagging.table_name} ON #{Tag.table_name}.id = #{Tagging.table_name}.tag_id"] 56 | joins << options.delete(:joins) if options[:joins] 57 | 58 | at_least = sanitize_sql(['COUNT(*) >= ?', options.delete(:at_least)]) if options[:at_least] 59 | at_most = sanitize_sql(['COUNT(*) <= ?', options.delete(:at_most)]) if options[:at_most] 60 | having = [at_least, at_most].compact.join(' AND ') 61 | group_by = "#{Tag.table_name}.id, #{Tag.table_name}.name HAVING COUNT(*) > 0" 62 | group_by << " AND #{having}" unless having.blank? 63 | 64 | { :select => "#{Tag.table_name}.id, #{Tag.table_name}.name, COUNT(*) AS count", 65 | :joins => joins.join(" "), 66 | :conditions => conditions, 67 | :group => group_by 68 | }.update(options) 69 | end 70 | end 71 | end 72 | -------------------------------------------------------------------------------- /vendor/plugins/acts_as_taggable_on_steroids/lib/tag_list.rb: -------------------------------------------------------------------------------- 1 | class TagList < Array 2 | cattr_accessor :delimiter 3 | self.delimiter = ',' 4 | 5 | def initialize(*args) 6 | add(*args) 7 | end 8 | 9 | # Add tags to the tag_list. Duplicate or blank tags will be ignored. 10 | # 11 | # tag_list.add("Fun", "Happy") 12 | # 13 | # Use the :parse option to add an unparsed tag string. 14 | # 15 | # tag_list.add("Fun, Happy", :parse => true) 16 | def add(*names) 17 | extract_and_apply_options!(names) 18 | concat(names) 19 | clean! 20 | self 21 | end 22 | 23 | # Remove specific tags from the tag_list. 24 | # 25 | # tag_list.remove("Sad", "Lonely") 26 | # 27 | # Like #add, the :parse option can be used to remove multiple tags in a string. 28 | # 29 | # tag_list.remove("Sad, Lonely", :parse => true) 30 | def remove(*names) 31 | extract_and_apply_options!(names) 32 | delete_if { |name| names.include?(name) } 33 | self 34 | end 35 | 36 | # Toggle the presence of the given tags. 37 | # If a tag is already in the list it is removed, otherwise it is added. 38 | def toggle(*names) 39 | extract_and_apply_options!(names) 40 | 41 | names.each do |name| 42 | include?(name) ? delete(name) : push(name) 43 | end 44 | 45 | clean! 46 | self 47 | end 48 | 49 | # Transform the tag_list into a tag string suitable for edting in a form. 50 | # The tags are joined with TagList.delimiter and quoted if necessary. 51 | # 52 | # tag_list = TagList.new("Round", "Square,Cube") 53 | # tag_list.to_s # 'Round, "Square,Cube"' 54 | def to_s 55 | clean! 56 | 57 | map do |name| 58 | name.include?(delimiter) ? "\"#{name}\"" : name 59 | end.join(delimiter.ends_with?(" ") ? delimiter : "#{delimiter} ") 60 | end 61 | 62 | private 63 | # Remove whitespace, duplicates, and blanks. 64 | def clean! 65 | reject!(&:blank?) 66 | map!(&:strip) 67 | uniq! 68 | end 69 | 70 | def extract_and_apply_options!(args) 71 | options = args.last.is_a?(Hash) ? args.pop : {} 72 | options.assert_valid_keys :parse 73 | 74 | if options[:parse] 75 | args.map! { |a| self.class.from(a) } 76 | end 77 | 78 | args.flatten! 79 | end 80 | 81 | class << self 82 | # Returns a new TagList using the given tag string. 83 | # 84 | # tag_list = TagList.from("One , Two, Three") 85 | # tag_list # ["One", "Two", "Three"] 86 | def from(source) 87 | tag_list = new 88 | 89 | case source 90 | when Array 91 | tag_list.add(source) 92 | else 93 | string = source.to_s.dup 94 | 95 | # Parse the quoted tags 96 | [ 97 | /\s*#{delimiter}\s*(['"])(.*?)\1\s*/, 98 | /^\s*(['"])(.*?)\1\s*#{delimiter}?/ 99 | ].each do |re| 100 | string.gsub!(re) { tag_list << $2; "" } 101 | end 102 | 103 | tag_list.add(string.split(delimiter)) 104 | end 105 | 106 | tag_list 107 | end 108 | end 109 | end 110 | -------------------------------------------------------------------------------- /vendor/plugins/acts_as_taggable_on_steroids/test/abstract_unit.rb: -------------------------------------------------------------------------------- 1 | require 'test/unit' 2 | 3 | begin 4 | require File.dirname(__FILE__) + '/../../../../config/environment' 5 | rescue LoadError 6 | require 'rubygems' 7 | gem 'activerecord' 8 | gem 'actionpack' 9 | require 'active_record' 10 | require 'action_controller' 11 | end 12 | 13 | # Search for fixtures first 14 | fixture_path = File.dirname(__FILE__) + '/fixtures/' 15 | ActiveSupport::Dependencies.load_paths.insert(0, fixture_path) 16 | 17 | require "active_record/test_case" 18 | require "active_record/fixtures" 19 | 20 | require File.dirname(__FILE__) + '/../lib/acts_as_taggable' 21 | require_dependency File.dirname(__FILE__) + '/../lib/tag_list' 22 | require_dependency File.dirname(__FILE__) + '/../lib/tags_helper' 23 | 24 | ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + '/debug.log') 25 | ActiveRecord::Base.configurations = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml')) 26 | ActiveRecord::Base.establish_connection(ENV['DB'] || 'mysql') 27 | 28 | load(File.dirname(__FILE__) + '/schema.rb') 29 | 30 | class ActiveSupport::TestCase #:nodoc: 31 | include ActiveRecord::TestFixtures 32 | 33 | self.fixture_path = File.dirname(__FILE__) + "/fixtures/" 34 | 35 | self.use_transactional_fixtures = true 36 | self.use_instantiated_fixtures = false 37 | 38 | fixtures :all 39 | 40 | def assert_equivalent(expected, actual, message = nil) 41 | if expected.first.is_a?(ActiveRecord::Base) 42 | assert_equal expected.sort_by(&:id), actual.sort_by(&:id), message 43 | else 44 | assert_equal expected.sort, actual.sort, message 45 | end 46 | end 47 | 48 | def assert_tag_counts(tags, expected_values) 49 | # Map the tag fixture names to real tag names 50 | expected_values = expected_values.inject({}) do |hash, (tag, count)| 51 | hash[tags(tag).name] = count 52 | hash 53 | end 54 | 55 | tags.each do |tag| 56 | value = expected_values.delete(tag.name) 57 | 58 | assert_not_nil value, "Expected count for #{tag.name} was not provided" 59 | assert_equal value, tag.count, "Expected value of #{value} for #{tag.name}, but was #{tag.count}" 60 | end 61 | 62 | unless expected_values.empty? 63 | assert false, "The following tag counts were not present: #{expected_values.inspect}" 64 | end 65 | end 66 | 67 | def assert_queries(num = 1) 68 | $query_count = 0 69 | yield 70 | ensure 71 | assert_equal num, $query_count, "#{$query_count} instead of #{num} queries were executed." 72 | end 73 | 74 | def assert_no_queries(&block) 75 | assert_queries(0, &block) 76 | end 77 | 78 | # From Rails trunk 79 | def assert_difference(expressions, difference = 1, message = nil, &block) 80 | expression_evaluations = [expressions].flatten.collect{|expression| lambda { eval(expression, block.binding) } } 81 | 82 | original_values = expression_evaluations.inject([]) { |memo, expression| memo << expression.call } 83 | yield 84 | expression_evaluations.each_with_index do |expression, i| 85 | assert_equal original_values[i] + difference, expression.call, message 86 | end 87 | end 88 | 89 | def assert_no_difference(expressions, message = nil, &block) 90 | assert_difference expressions, 0, message, &block 91 | end 92 | end 93 | 94 | ActiveRecord::Base.connection.class.class_eval do 95 | def execute_with_counting(sql, name = nil, &block) 96 | $query_count ||= 0 97 | $query_count += 1 98 | execute_without_counting(sql, name, &block) 99 | end 100 | 101 | alias_method_chain :execute, :counting 102 | end 103 | -------------------------------------------------------------------------------- /spec/controllers/snippets_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe SnippetsController do 4 | setup :activate_authlogic 5 | 6 | describe "routing" do 7 | it "should know the route to /users/1/snippets GET" do 8 | params_from(:get, '/users/1/snippets').should == { :controller => 'snippets', :action => 'index', :user_id => '1' } 9 | end 10 | it "should know the route to /users/1/snippets/new GET" do 11 | params_from(:get, '/users/1/snippets/new').should == { :controller => 'snippets', :action => 'new', :user_id => '1' } 12 | end 13 | it "should know the route to /users/1/snippets POST" do 14 | params_from(:post, '/users/1/snippets').should == { :controller => 'snippets', :action => 'create', :user_id => '1' } 15 | end 16 | it "should know the route to /users/1/snippets/2 GET" do 17 | params_from(:get, '/users/1/snippets/2').should == { :controller => 'snippets', :action => 'show', :user_id => '1', :id => '2' } 18 | end 19 | it "should know the route to /users/1/snippets/2/edit GET" do 20 | params_from(:get, '/users/1/snippets/2/edit').should == { :controller => 'snippets', :action => 'edit', :user_id => '1', :id => '2' } 21 | end 22 | it "should know the route to /users/1/snippets/2 PUT" do 23 | params_from(:put, '/users/1/snippets/2').should == { :controller => 'snippets', :action => 'update', :user_id => '1', :id => '2' } 24 | end 25 | it "should know the route to /users/1/snippets/2 DELETE" do 26 | params_from(:delete, '/users/1/snippets/2').should == { :controller => 'snippets', :action => 'destroy', :user_id => '1', :id => '2' } 27 | end 28 | end 29 | 30 | describe "with logged in user" do 31 | integrate_views 32 | let(:user) { User.make } 33 | before(:each) { UserSession.create(user) } 34 | describe "#index" do 35 | it "should get all user snippets" do 36 | 3.times { user.snippets.make } 37 | 2.times { Snippet.make } 38 | get :index, :user_id => user.id 39 | assigns[:snippets].size.should eql(3) 40 | Snippet.count.should eql(5) 41 | end 42 | end 43 | describe "#show" do 44 | it "should load snippet" do 45 | snippet = user.snippets.make 46 | get :show, :user_id => user.id, :id => snippet.id 47 | assigns[:snippet].should eql(snippet) 48 | end 49 | end 50 | describe "#new" do 51 | it "should build new snippet" do 52 | get :new, :user_id => 1 53 | assigns[:snippet].should_not be_nil 54 | end 55 | end 56 | describe "#create" do 57 | it "should create new snippet and redirect" do 58 | expect { 59 | post :create, :user_id => user.id, :snippet => Snippet.plan 60 | }.to change { user.snippets.count }.from(0).to(1) 61 | response.should be_redirect 62 | end 63 | end 64 | describe "#edit" do 65 | it "should find snippet" do 66 | snippet = user.snippets.make 67 | get :edit, :user_id => user.id, :id => snippet.id 68 | assigns[:snippet].should eql(snippet) 69 | end 70 | end 71 | describe "#update" do 72 | it "should update snippet and redirect" do 73 | snippet = user.snippets.make 74 | put :update, :user_id => user.id, :id => snippet.id, :snippet => { :description => 'New description'} 75 | user.snippets.find(snippet.id).description.should eql('New description') 76 | response.should be_redirect 77 | end 78 | end 79 | describe "#destroy" do 80 | it "should destroy snippet and redirect" do 81 | snippet = user.snippets.make 82 | expect { 83 | delete :destroy, :user_id => user.id, :id => snippet.id 84 | }.to change { user.snippets.count }.from(1).to(0) 85 | response.should be_redirect 86 | end 87 | end 88 | end 89 | end 90 | -------------------------------------------------------------------------------- /public/javascripts/jrails.min.js: -------------------------------------------------------------------------------- 1 | (function($){$.ajaxSettings.accepts._default="text/javascript, text/html, application/xml, text/xml, */*"})(jQuery);(function($){$.fn.reset=function(){return this.each(function(){if(typeof this.reset=="function"||(typeof this.reset=="object"&&!this.reset.nodeType)){this.reset()}})};$.fn.enable=function(){return this.each(function(){this.disabled=false})};$.fn.disable=function(){return this.each(function(){this.disabled=true})}})(jQuery);(function($){$.extend({fieldEvent:function(el,obs){var field=el[0]||el,e="change";if(field.type=="radio"||field.type=="checkbox"){e="click"}else{if(obs&&(field.type=="text"||field.type=="textarea"||field.type=="password")){e="keyup"}}return e}});$.fn.extend({delayedObserver:function(delay,callback){var el=$(this);if(typeof window.delayedObserverStack=="undefined"){window.delayedObserverStack=[]}if(typeof window.delayedObserverCallback=="undefined"){window.delayedObserverCallback=function(stackPos){var observed=window.delayedObserverStack[stackPos];if(observed.timer){clearTimeout(observed.timer)}observed.timer=setTimeout(function(){observed.timer=null;observed.callback(observed.obj,observed.obj.formVal())},observed.delay*1000);observed.oldVal=observed.obj.formVal()}}window.delayedObserverStack.push({obj:el,timer:null,delay:delay,oldVal:el.formVal(),callback:callback});var stackPos=window.delayedObserverStack.length-1;if(el[0].tagName=="FORM"){$(":input",el).each(function(){var field=$(this);field.bind($.fieldEvent(field,delay),function(){var observed=window.delayedObserverStack[stackPos];if(observed.obj.formVal()==observed.oldVal){return}else{window.delayedObserverCallback(stackPos)}})})}else{el.bind($.fieldEvent(el,delay),function(){var observed=window.delayedObserverStack[stackPos];if(observed.obj.formVal()==observed.oldVal){return}else{window.delayedObserverCallback(stackPos)}})}},formVal:function(){var el=this[0];if(el.tagName=="FORM"){return this.serialize()}if(el.type=="checkbox"||el.type=="radio"){return this.filter("input:checked").val()||""}else{return this.val()}}})})(jQuery);(function($){$.fn.extend({visualEffect:function(o,options){if(options){speed=options.duration*1000}else{speed=null}e=o.replace(/\_(.)/g,function(m,l){return l.toUpperCase()});return eval("$(this)."+e+"("+speed+")")},appear:function(speed,callback){return this.fadeIn(speed,callback)},blindDown:function(speed,callback){return this.show("blind",{direction:"vertical"},speed,callback)},blindUp:function(speed,callback){return this.hide("blind",{direction:"vertical"},speed,callback)},blindRight:function(speed,callback){return this.show("blind",{direction:"horizontal"},speed,callback)},blindLeft:function(speed,callback){this.hide("blind",{direction:"horizontal"},speed,callback);return this},dropOut:function(speed,callback){return this.hide("drop",{direction:"down"},speed,callback)},dropIn:function(speed,callback){return this.show("drop",{direction:"up"},speed,callback)},fade:function(speed,callback){return this.fadeOut(speed,callback)},fadeToggle:function(speed,callback){return this.animate({opacity:"toggle"},speed,callback)},fold:function(speed,callback){return this.hide("fold",{},speed,callback)},foldOut:function(speed,callback){return this.show("fold",{},speed,callback)},grow:function(speed,callback){return this.show("scale",{},speed,callback)},highlight:function(speed,callback){return this.show("highlight",{},speed,callback)},puff:function(speed,callback){return this.hide("puff",{},speed,callback)},pulsate:function(speed,callback){return this.show("pulsate",{},speed,callback)},shake:function(speed,callback){return this.show("shake",{},speed,callback)},shrink:function(speed,callback){return this.hide("scale",{},speed,callback)},squish:function(speed,callback){return this.hide("scale",{origin:["top","left"]},speed,callback)},slideUp:function(speed,callback){return this.hide("slide",{direction:"up"},speed,callback)},slideDown:function(speed,callback){return this.show("slide",{direction:"up"},speed,callback)},switchOff:function(speed,callback){return this.hide("clip",{},speed,callback)},switchOn:function(speed,callback){return this.show("clip",{},speed,callback)}})})(jQuery); -------------------------------------------------------------------------------- /vendor/plugins/acts_as_taggable_on_steroids/test/tag_list_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/abstract_unit' 2 | 3 | class TagListTest < ActiveSupport::TestCase 4 | def test_from_leaves_string_unchanged 5 | tags = '"One ", Two' 6 | original = tags.dup 7 | TagList.from(tags) 8 | assert_equal tags, original 9 | end 10 | 11 | def test_from_single_name 12 | assert_equal %w(Fun), TagList.from("Fun") 13 | assert_equal %w(Fun), TagList.from('"Fun"') 14 | end 15 | 16 | def test_from_blank 17 | assert_equal [], TagList.from(nil) 18 | assert_equal [], TagList.from("") 19 | end 20 | 21 | def test_from_single_quoted_tag 22 | assert_equal ['with, comma'], TagList.from('"with, comma"') 23 | end 24 | 25 | def test_spaces_do_not_delineate 26 | assert_equal ['A B', 'C'], TagList.from('A B, C') 27 | end 28 | 29 | def test_from_multiple_tags 30 | assert_equivalent %w(Alpha Beta Delta Gamma), TagList.from("Alpha, Beta, Delta, Gamma") 31 | end 32 | 33 | def test_from_multiple_tags_with_quotes 34 | assert_equivalent %w(Alpha Beta Delta Gamma), TagList.from('Alpha, "Beta", Gamma , "Delta"') 35 | end 36 | 37 | def test_from_with_single_quotes 38 | assert_equivalent ['A B', 'C'], TagList.from("'A B', C") 39 | end 40 | 41 | def test_from_multiple_tags_with_quote_and_commas 42 | assert_equivalent ['Alpha, Beta', 'Delta', 'Gamma, something'], TagList.from('"Alpha, Beta", Delta, "Gamma, something"') 43 | end 44 | 45 | def test_from_with_inner_quotes 46 | assert_equivalent ["House", "Drum 'n' Bass", "Trance"], TagList.from("House, Drum 'n' Bass, Trance") 47 | assert_equivalent ["House", "Drum'n'Bass", "Trance"], TagList.from("House, Drum'n'Bass, Trance") 48 | end 49 | 50 | def test_from_removes_white_space 51 | assert_equivalent %w(Alpha Beta), TagList.from('" Alpha ", "Beta "') 52 | assert_equivalent %w(Alpha Beta), TagList.from(' Alpha, Beta ') 53 | end 54 | 55 | def test_from_and_new_treat_both_accept_arrays 56 | tags = ["One", "Two"] 57 | 58 | assert_equal TagList.from(tags), TagList.new(tags) 59 | end 60 | 61 | def test_alternative_delimiter 62 | TagList.delimiter = " " 63 | 64 | assert_equal %w(One Two), TagList.from("One Two") 65 | assert_equal ['One two', 'three', 'four'], TagList.from('"One two" three four') 66 | ensure 67 | TagList.delimiter = "," 68 | end 69 | 70 | def test_duplicate_tags_removed 71 | assert_equal %w(One), TagList.from("One, One") 72 | end 73 | 74 | def test_to_s_with_commas 75 | assert_equal "Question, Crazy Animal", TagList.new("Question", "Crazy Animal").to_s 76 | end 77 | 78 | def test_to_s_with_alternative_delimiter 79 | TagList.delimiter = " " 80 | 81 | assert_equal '"Crazy Animal" Question', TagList.new("Crazy Animal", "Question").to_s 82 | ensure 83 | TagList.delimiter = "," 84 | end 85 | 86 | def test_add 87 | tag_list = TagList.new("One") 88 | assert_equal %w(One), tag_list 89 | 90 | assert_equal %w(One Two), tag_list.add("Two") 91 | assert_equal %w(One Two Three), tag_list.add(["Three"]) 92 | end 93 | 94 | def test_remove 95 | tag_list = TagList.new("One", "Two") 96 | assert_equal %w(Two), tag_list.remove("One") 97 | assert_equal %w(), tag_list.remove(["Two"]) 98 | end 99 | 100 | def test_new_with_parsing 101 | assert_equal %w(One Two), TagList.new("One, Two", :parse => true) 102 | end 103 | 104 | def test_add_with_parsing 105 | assert_equal %w(One Two), TagList.new.add("One, Two", :parse => true) 106 | end 107 | 108 | def test_remove_with_parsing 109 | tag_list = TagList.from("Three, Four, Five") 110 | assert_equal %w(Four), tag_list.remove("Three, Five", :parse => true) 111 | end 112 | 113 | def test_toggle 114 | tag_list = TagList.new("One", "Two") 115 | assert_equal %w(One Three), tag_list.toggle("Two", "Three") 116 | assert_equal %w(), tag_list.toggle("One", "Three") 117 | assert_equal %w(Four), tag_list.toggle("Four") 118 | end 119 | end 120 | -------------------------------------------------------------------------------- /config/boot.rb: -------------------------------------------------------------------------------- 1 | # Don't change this file! 2 | # Configure your app in config/environment.rb and config/environments/*.rb 3 | 4 | begin 5 | require "rubygems" 6 | require "bundler" 7 | rescue LoadError 8 | raise "Could not load the bundler gem. Install it with `gem install bundler`." 9 | end 10 | 11 | if Gem::Version.new(Bundler::VERSION) <= Gem::Version.new("0.9.24") 12 | raise RuntimeError, "Your bundler version is too old for Rails 2.3." + 13 | "Run `gem install bundler` to upgrade." 14 | end 15 | 16 | begin 17 | # Set up load paths for all bundled gems 18 | ENV["BUNDLE_GEMFILE"] = File.expand_path("../../Gemfile", __FILE__) 19 | Bundler.setup 20 | rescue Bundler::GemNotFound 21 | raise RuntimeError, "Bundler couldn't find some gems." + 22 | "Did you run `bundle install`?" 23 | end 24 | 25 | RAILS_ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(RAILS_ROOT) 26 | 27 | module Rails 28 | class << self 29 | def boot! 30 | unless booted? 31 | preinitialize 32 | pick_boot.run 33 | end 34 | end 35 | 36 | def booted? 37 | defined? Rails::Initializer 38 | end 39 | 40 | def pick_boot 41 | (vendor_rails? ? VendorBoot : GemBoot).new 42 | end 43 | 44 | def vendor_rails? 45 | File.exist?("#{RAILS_ROOT}/vendor/rails") 46 | end 47 | 48 | def preinitialize 49 | load(preinitializer_path) if File.exist?(preinitializer_path) 50 | end 51 | 52 | def preinitializer_path 53 | "#{RAILS_ROOT}/config/preinitializer.rb" 54 | end 55 | end 56 | 57 | class Boot 58 | def run 59 | load_initializer 60 | Rails::Initializer.run(:set_load_path) 61 | end 62 | end 63 | 64 | class VendorBoot < Boot 65 | def load_initializer 66 | require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer" 67 | Rails::Initializer.run(:install_gem_spec_stubs) 68 | Rails::GemDependency.add_frozen_gem_path 69 | end 70 | end 71 | 72 | class GemBoot < Boot 73 | def load_initializer 74 | self.class.load_rubygems 75 | load_rails_gem 76 | require 'initializer' 77 | end 78 | 79 | def load_rails_gem 80 | if version = self.class.gem_version 81 | gem 'rails', version 82 | else 83 | gem 'rails' 84 | end 85 | rescue Gem::LoadError => load_error 86 | $stderr.puts %(Missing the Rails #{version} gem. Please `gem install -v=#{version} rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed.) 87 | exit 1 88 | end 89 | 90 | class << self 91 | def rubygems_version 92 | Gem::RubyGemsVersion rescue nil 93 | end 94 | 95 | def gem_version 96 | if defined? RAILS_GEM_VERSION 97 | RAILS_GEM_VERSION 98 | elsif ENV.include?('RAILS_GEM_VERSION') 99 | ENV['RAILS_GEM_VERSION'] 100 | else 101 | parse_gem_version(read_environment_rb) 102 | end 103 | end 104 | 105 | def load_rubygems 106 | require 'rubygems' 107 | min_version = '1.3.1' 108 | unless rubygems_version >= min_version 109 | $stderr.puts %Q(Rails requires RubyGems >= #{min_version} (you have #{rubygems_version}). Please `gem update --system` and try again.) 110 | exit 1 111 | end 112 | 113 | rescue LoadError 114 | $stderr.puts %Q(Rails requires RubyGems >= #{min_version}. Please install RubyGems and try again: http://rubygems.rubyforge.org) 115 | exit 1 116 | end 117 | 118 | def parse_gem_version(text) 119 | $1 if text =~ /^[^#]*RAILS_GEM_VERSION\s*=\s*["']([!~<>=]*\s*[\d.]+)["']/ 120 | end 121 | 122 | private 123 | def read_environment_rb 124 | File.read("#{RAILS_ROOT}/config/environment.rb") 125 | end 126 | end 127 | end 128 | end 129 | 130 | class Rails::Boot 131 | def run 132 | load_initializer 133 | 134 | Rails::Initializer.class_eval do 135 | def load_gems 136 | @bundler_loaded ||= Bundler.require :default, Rails.env 137 | end 138 | end 139 | 140 | Rails::Initializer.run(:set_load_path) 141 | end 142 | end 143 | 144 | # All that for this: 145 | Rails.boot! 146 | -------------------------------------------------------------------------------- /vendor/plugins/acts_as_taggable_on_steroids/README: -------------------------------------------------------------------------------- 1 | = acts_as_taggable_on_steroids 2 | 3 | If you find this plugin useful, please consider a donation to show your support! 4 | 5 | http://www.paypal.com/cgi-bin/webscr?cmd=_send-money 6 | 7 | Email address: jonathan.viney@gmail.com 8 | 9 | == Instructions 10 | 11 | This plugin is based on acts_as_taggable by DHH but includes extras 12 | such as tests, smarter tag assignment, and tag cloud calculations. 13 | 14 | == Installation 15 | 16 | Rails 2.* 17 | 18 | ruby script/plugin install git://github.com/jviney/acts_as_taggable_on_steroids.git 19 | 20 | Rails 3: 21 | 22 | rails plugin install git://github.com/jviney/acts_as_taggable_on_steroids.git 23 | 24 | == Usage 25 | 26 | === Prepare database 27 | 28 | Generate and apply the migration: 29 | 30 | ruby script/generate acts_as_taggable_migration 31 | rake db:migrate 32 | 33 | === Basic tagging 34 | 35 | Let's suppose users have many posts and we want those posts to have tags. 36 | The first step is to add +acts_as_taggable+ to the Post class: 37 | 38 | class Post < ActiveRecord::Base 39 | acts_as_taggable 40 | 41 | belongs_to :user 42 | end 43 | 44 | We can now use the tagging methods provided by acts_as_taggable, #tag_list and #tag_list=. Both these 45 | methods work like regular attribute accessors. 46 | 47 | p = Post.find(:first) 48 | p.tag_list # [] 49 | p.tag_list = "Funny, Silly" 50 | p.save 51 | p.tag_list # ["Funny", "Silly"] 52 | 53 | You can also add or remove arrays of tags. 54 | 55 | p.tag_list.add("Great", "Awful") 56 | p.tag_list.remove("Funny") 57 | 58 | In your views you should use something like the following: 59 | 60 | <%= f.label :tag_list %> 61 | <%= f.text_field :tag_list, :size => 80 %> 62 | 63 | === Finding tagged objects 64 | 65 | To retrieve objects tagged with a certain tag, use find_tagged_with. 66 | 67 | Post.find_tagged_with('Funny, Silly') 68 | 69 | By default, find_tagged_with will find objects that have any of the given tags. To 70 | find only objects that are tagged with all the given tags, use match_all. 71 | 72 | Post.find_tagged_with('Funny, Silly', :match_all => true) 73 | 74 | See ActiveRecord::Acts::Taggable::InstanceMethods for more methods and options. 75 | 76 | === Tag cloud calculations 77 | 78 | To construct tag clouds, the frequency of each tag needs to be calculated. 79 | Because we specified +acts_as_taggable+ on the Post class, we can 80 | get a calculation of all the tag counts by using Post.tag_counts. But what if we wanted a tag count for 81 | an single user's posts? To achieve this we call tag_counts on the association: 82 | 83 | User.find(:first).posts.tag_counts 84 | 85 | A helper is included to assist with generating tag clouds. Include it in your helper file: 86 | 87 | module ApplicationHelper 88 | include TagsHelper 89 | end 90 | 91 | You can also use the counts method on Tag to get the counts for all tags in the database. 92 | 93 | Tag.counts 94 | 95 | Here is an example that generates a tag cloud. 96 | 97 | Controller: 98 | 99 | class PostController < ApplicationController 100 | def tag_cloud 101 | @tags = Post.tag_counts 102 | end 103 | end 104 | 105 | View: 106 | <% tag_cloud @tags, %w(css1 css2 css3 css4) do |tag, css_class| %> 107 | <%= link_to tag.name, { :action => :tag, :id => tag.name }, :class => css_class %> 108 | <% end %> 109 | 110 | CSS: 111 | 112 | .css1 { font-size: 1.0em; } 113 | .css2 { font-size: 1.2em; } 114 | .css3 { font-size: 1.4em; } 115 | .css4 { font-size: 1.6em; } 116 | 117 | === Caching 118 | 119 | It is useful to cache the list of tags to reduce the number of queries executed. To do this, 120 | add a column named cached_tag_list to the model which is being tagged. The column should be long enough to hold 121 | the full tag list and must have a default value of null, not an empty string. 122 | 123 | class CachePostTagList < ActiveRecord::Migration 124 | def self.up 125 | add_column :posts, :cached_tag_list, :string 126 | end 127 | end 128 | 129 | class Post < ActiveRecord::Base 130 | acts_as_taggable 131 | 132 | # The caching column defaults to cached_tag_list, but can be changed: 133 | # 134 | # set_cached_tag_list_column_name "my_caching_column_name" 135 | end 136 | 137 | The details of the caching are handled for you. Just continue to use the tag_list accessor as you normally would. 138 | Note that the cached tag list will not be updated if you directly create Tagging objects or manually append to the 139 | tags or taggings associations. To update the cached tag list you should call save_cached_tag_list manually. 140 | 141 | === Delimiter 142 | 143 | If you want to change the delimiter used to parse and present tags, set TagList.delimiter. 144 | For example, to use spaces instead of commas, add the following to config/environment.rb: 145 | 146 | TagList.delimiter = " " 147 | 148 | === Unused tags 149 | 150 | Set Tag.destroy_unused to remove tags when they are no longer being 151 | used to tag any objects. Defaults to false. 152 | 153 | Tag.destroy_unused = true 154 | 155 | === Other 156 | 157 | Problems, comments, and suggestions all welcome. jonathan.viney@gmail.com 158 | -------------------------------------------------------------------------------- /vendor/plugins/acts_as_taggable_on_steroids/CHANGELOG: -------------------------------------------------------------------------------- 1 | [11 Jun 09] 2 | 3 | * Remove deprecated TagCountsExtension. 4 | 5 | * Update tests to use foxy fixtures [Jonas Wagner] 6 | 7 | * Allow hash conditions to be passed to Tag.counts [Jonas Wagner] 8 | 9 | [3 Jun 09] 10 | 11 | * Upgrade tests for Rails 2.3 12 | 13 | [18 Mar 09] 14 | 15 | * Change callbacks used to save tags. 16 | 17 | [18 Feb 09] 18 | 19 | * Greatly improve speed when using find_tagged_with and :match_all [notonthehighstreet.com]. 20 | 21 | [17 Sep 08] 22 | 23 | * Sanitize scope conditions in find_options_for_tag_counts [Rémy-Christophe Schermesser] 24 | 25 | [23 Aug 08] 26 | 27 | * Fix tag_counts instance method when no tags are present. 28 | 29 | * Make tag_counts instance_method merge any :conditions passed to it. 30 | 31 | [30 Mar 08] 32 | 33 | * Make TagList.from accept array arguments. 34 | 35 | [29 Mar 08] 36 | 37 | * Improve parsing of quotes inside tags [Arturas Slajus]. 38 | 39 | * Add Tag.counts method. 40 | 41 | [28 Mar 08] 42 | 43 | * Make Tag#taggings :dependent => :destroy. 44 | 45 | [27 Mar 08] 46 | 47 | * Fix documentation for tag_counts. 48 | 49 | [18 Mar 08] 50 | 51 | * Add TagList#toggle [Pete Yandell]. 52 | 53 | # Add find_related_tags method [Austin Foncaier]. 54 | 55 | [30 Jan 08] 56 | 57 | * Fix Tag.destroy_unused on Rails 2.0. 58 | 59 | [23 October 2007] 60 | 61 | * Make find_options_for_tag_counts and find_options_for_tagged_with dup their options. 62 | 63 | * Apply conditions properly in find_options_for_tag_counts. 64 | 65 | * Fix tag_cloud when no tags are present. 66 | 67 | [22 October 2007] 68 | 69 | * Fix find_tagged_with using :match_all and :include. 70 | 71 | * Use inner joins instead of left outer joins. 72 | 73 | [15 October 2007] 74 | 75 | * Make find_tagged_with correctly apply :conditions 76 | 77 | * Add Tag.destroy_unused option. 78 | 79 | [11 October 2007] 80 | 81 | * Make tag_counts work correctly with STI. 82 | 83 | [3 October 2007] 84 | 85 | * Improve documentation. 86 | 87 | * Fix TagsHelper and test. 88 | 89 | [2 October 2007] 90 | 91 | * Remove TagList.parse, use TagList.from instead. 92 | 93 | * Add :parse option to TagList#new, TagList#add, and TagList#remove. 94 | 95 | tag_list = TagList.new("One, Two", :parse => true) # ["One", "Two"] 96 | 97 | tag_list # ["One", "Two"] 98 | tag_list.add("Three, Four", :parse => true) # ["One", "Two", "Three", "Four"] 99 | 100 | * Remove TagList#names. 101 | 102 | [29 September 2007] 103 | 104 | * Add TagsHelper to assist with generating tag clouds and provide a simple example. 105 | 106 | [27 September 2007] 107 | 108 | * Add #tag_counts method to get tag counts for a specific object's tags. 109 | 110 | * BACKWARDS INCOMPATIBILITY: Rename #find_options_for_tagged_with to #find_options_for_find_tagged_with 111 | 112 | [17 September 2007] 113 | 114 | * Fix clearing of cached tag list when all tags removed. 115 | 116 | [12 September 2007] 117 | 118 | * Make the TagList class inherit from Array. 119 | 120 | * Deprecate obsolete TagList#names. 121 | 122 | [6 September 2007] 123 | 124 | * Add TagList#include? and TagList#empty? 125 | 126 | [26 August 2007] 127 | 128 | * Remove deprecated Tag.delimiter. Use TagList.delimiter instead. 129 | 130 | [25 August 2007] 131 | 132 | * Make tag_counts work with has_many :through 133 | 134 | [23 August 2007] 135 | 136 | * Make search comparisons case-insensitive across different databases. [Moisés Machado] 137 | 138 | * Improve compatiblity with STI. [Moisés Machado] 139 | 140 | [25 July 2007] 141 | 142 | * Respect custom table names for the Tag and Tagging classes. 143 | 144 | * Fix the :exclude option for find_tagged_with 145 | 146 | [17 July 2007] 147 | 148 | * Make the migration work on edge rails 149 | 150 | [8 July 2007] 151 | 152 | * find_options_for_tagged_with should not alter its arguments 153 | 154 | [1 July 2007] 155 | 156 | * Fix incorrect tagging when the case of the tag list is changed. 157 | 158 | * Fix deprecated Tag.delimiter accessor. 159 | 160 | [23 June 2007] 161 | 162 | * Add validation to Tag model. 163 | 164 | * find_options_for_tagged_with should always return a hash. 165 | 166 | * find_tagged_with passing in no tags should return an empty array. 167 | 168 | * Improve compatibility with PostgreSQL. 169 | 170 | [21 June 2007] 171 | 172 | * Remove extra .rb from generated migration file name. 173 | 174 | [15 June 2007] 175 | 176 | * Introduce TagList class. 177 | 178 | * Various cleanups and improvements. 179 | 180 | * Use TagList.delimiter now, not Tag.delimiter. Tag.delimiter will be removed at some stage. 181 | 182 | [11 June 2007] 183 | 184 | * Restructure the creation of the options for find_tagged_with [Thijs Cadier] 185 | 186 | * Add an example migration with a generator. 187 | 188 | * Add caching. 189 | 190 | * Fix compatibility with Ruby < 1.8.6 191 | 192 | [23 April 2007] 193 | 194 | * Make tag_list to respect Tag.delimiter 195 | 196 | [31 March 2007] 197 | 198 | * Add Tag.delimiter accessor to change how tags are parsed. 199 | 200 | * Fix :include => :tags when used with find_tagged_with 201 | 202 | [7 March 2007] 203 | 204 | * Fix tag_counts for SQLServer [Brad Young] 205 | 206 | [21 Feb 2007] 207 | 208 | * Use scoping instead of TagCountsExtension [Michael Schuerig] 209 | 210 | [7 Jan 2007] 211 | 212 | * Add :match_all to find_tagged_with [Michael Sheakoski] 213 | -------------------------------------------------------------------------------- /lib/tasks/rspec.rake: -------------------------------------------------------------------------------- 1 | gem 'test-unit', '1.2.3' if RUBY_VERSION.to_f >= 1.9 2 | rspec_gem_dir = nil 3 | Dir["#{RAILS_ROOT}/vendor/gems/*"].each do |subdir| 4 | rspec_gem_dir = subdir if subdir.gsub("#{RAILS_ROOT}/vendor/gems/","") =~ /^(\w+-)?rspec-(\d+)/ && File.exist?("#{subdir}/lib/spec/rake/spectask.rb") 5 | end 6 | rspec_plugin_dir = File.expand_path(File.dirname(__FILE__) + '/../../vendor/plugins/rspec') 7 | 8 | if rspec_gem_dir && (test ?d, rspec_plugin_dir) 9 | raise "\n#{'*'*50}\nYou have rspec installed in both vendor/gems and vendor/plugins\nPlease pick one and dispose of the other.\n#{'*'*50}\n\n" 10 | end 11 | 12 | if rspec_gem_dir 13 | $LOAD_PATH.unshift("#{rspec_gem_dir}/lib") 14 | elsif File.exist?(rspec_plugin_dir) 15 | $LOAD_PATH.unshift("#{rspec_plugin_dir}/lib") 16 | end 17 | 18 | # Don't load rspec if running "rake gems:*" 19 | unless ARGV.any? {|a| a =~ /^gems/} 20 | 21 | begin 22 | require 'spec/rake/spectask' 23 | rescue MissingSourceFile 24 | module Spec 25 | module Rake 26 | class SpecTask 27 | def initialize(name) 28 | task name do 29 | # if rspec-rails is a configured gem, this will output helpful material and exit ... 30 | require File.expand_path(File.join(File.dirname(__FILE__),"..","..","config","environment")) 31 | 32 | # ... otherwise, do this: 33 | raise <<-MSG 34 | 35 | #{"*" * 80} 36 | * You are trying to run an rspec rake task defined in 37 | * #{__FILE__}, 38 | * but rspec can not be found in vendor/gems, vendor/plugins or system gems. 39 | #{"*" * 80} 40 | MSG 41 | end 42 | end 43 | end 44 | end 45 | end 46 | end 47 | 48 | Rake.application.instance_variable_get('@tasks').delete('default') 49 | 50 | spec_prereq = File.exist?(File.join(RAILS_ROOT, 'config', 'database.yml')) ? "db:test:prepare" : :noop 51 | task :noop do 52 | end 53 | 54 | task :default => :spec 55 | task :stats => "spec:statsetup" 56 | 57 | desc "Run all specs in spec directory (excluding plugin specs)" 58 | Spec::Rake::SpecTask.new(:spec => spec_prereq) do |t| 59 | t.spec_opts = ['--options', "\"#{RAILS_ROOT}/spec/spec.opts\""] 60 | t.spec_files = FileList['spec/**/*_spec.rb'] 61 | end 62 | 63 | namespace :spec do 64 | desc "Run all specs in spec directory with RCov (excluding plugin specs)" 65 | Spec::Rake::SpecTask.new(:rcov) do |t| 66 | t.spec_opts = ['--options', "\"#{RAILS_ROOT}/spec/spec.opts\""] 67 | t.spec_files = FileList['spec/**/*_spec.rb'] 68 | t.rcov = true 69 | t.rcov_opts = lambda do 70 | IO.readlines("#{RAILS_ROOT}/spec/rcov.opts").map {|l| l.chomp.split " "}.flatten 71 | end 72 | end 73 | 74 | desc "Print Specdoc for all specs (excluding plugin specs)" 75 | Spec::Rake::SpecTask.new(:doc) do |t| 76 | t.spec_opts = ["--format", "specdoc", "--dry-run"] 77 | t.spec_files = FileList['spec/**/*_spec.rb'] 78 | end 79 | 80 | desc "Print Specdoc for all plugin examples" 81 | Spec::Rake::SpecTask.new(:plugin_doc) do |t| 82 | t.spec_opts = ["--format", "specdoc", "--dry-run"] 83 | t.spec_files = FileList['vendor/plugins/**/spec/**/*_spec.rb'].exclude('vendor/plugins/rspec/*') 84 | end 85 | 86 | [:models, :controllers, :views, :helpers, :lib, :integration].each do |sub| 87 | desc "Run the code examples in spec/#{sub}" 88 | Spec::Rake::SpecTask.new(sub => spec_prereq) do |t| 89 | t.spec_opts = ['--options', "\"#{RAILS_ROOT}/spec/spec.opts\""] 90 | t.spec_files = FileList["spec/#{sub}/**/*_spec.rb"] 91 | end 92 | end 93 | 94 | desc "Run the code examples in vendor/plugins (except RSpec's own)" 95 | Spec::Rake::SpecTask.new(:plugins => spec_prereq) do |t| 96 | t.spec_opts = ['--options', "\"#{RAILS_ROOT}/spec/spec.opts\""] 97 | t.spec_files = FileList['vendor/plugins/**/spec/**/*_spec.rb'].exclude('vendor/plugins/rspec/*').exclude("vendor/plugins/rspec-rails/*") 98 | end 99 | 100 | namespace :plugins do 101 | desc "Runs the examples for rspec_on_rails" 102 | Spec::Rake::SpecTask.new(:rspec_on_rails) do |t| 103 | t.spec_opts = ['--options', "\"#{RAILS_ROOT}/spec/spec.opts\""] 104 | t.spec_files = FileList['vendor/plugins/rspec-rails/spec/**/*_spec.rb'] 105 | end 106 | end 107 | 108 | # Setup specs for stats 109 | task :statsetup do 110 | require 'code_statistics' 111 | ::STATS_DIRECTORIES << %w(Model\ specs spec/models) if File.exist?('spec/models') 112 | ::STATS_DIRECTORIES << %w(View\ specs spec/views) if File.exist?('spec/views') 113 | ::STATS_DIRECTORIES << %w(Controller\ specs spec/controllers) if File.exist?('spec/controllers') 114 | ::STATS_DIRECTORIES << %w(Helper\ specs spec/helpers) if File.exist?('spec/helpers') 115 | ::STATS_DIRECTORIES << %w(Library\ specs spec/lib) if File.exist?('spec/lib') 116 | ::STATS_DIRECTORIES << %w(Routing\ specs spec/routing) if File.exist?('spec/routing') 117 | ::STATS_DIRECTORIES << %w(Integration\ specs spec/integration) if File.exist?('spec/integration') 118 | ::CodeStatistics::TEST_TYPES << "Model specs" if File.exist?('spec/models') 119 | ::CodeStatistics::TEST_TYPES << "View specs" if File.exist?('spec/views') 120 | ::CodeStatistics::TEST_TYPES << "Controller specs" if File.exist?('spec/controllers') 121 | ::CodeStatistics::TEST_TYPES << "Helper specs" if File.exist?('spec/helpers') 122 | ::CodeStatistics::TEST_TYPES << "Library specs" if File.exist?('spec/lib') 123 | ::CodeStatistics::TEST_TYPES << "Routing specs" if File.exist?('spec/routing') 124 | ::CodeStatistics::TEST_TYPES << "Integration specs" if File.exist?('spec/integration') 125 | end 126 | 127 | namespace :db do 128 | namespace :fixtures do 129 | desc "Load fixtures (from spec/fixtures) into the current environment's database. Load specific fixtures using FIXTURES=x,y. Load from subdirectory in test/fixtures using FIXTURES_DIR=z." 130 | task :load => :environment do 131 | ActiveRecord::Base.establish_connection(Rails.env) 132 | base_dir = File.join(Rails.root, 'spec', 'fixtures') 133 | fixtures_dir = ENV['FIXTURES_DIR'] ? File.join(base_dir, ENV['FIXTURES_DIR']) : base_dir 134 | 135 | require 'active_record/fixtures' 136 | (ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/).map {|f| File.join(fixtures_dir, f) } : Dir.glob(File.join(fixtures_dir, '*.{yml,csv}'))).each do |fixture_file| 137 | Fixtures.create_fixtures(File.dirname(fixture_file), File.basename(fixture_file, '.*')) 138 | end 139 | end 140 | end 141 | end 142 | end 143 | 144 | end 145 | -------------------------------------------------------------------------------- /public/stylesheets/styles.css: -------------------------------------------------------------------------------- 1 | /*================================================== 2 | Template: OWMX-3 3 | Resource: http://www.owmx.com/ 4 | Version: 1.0 5 | Date: 2010-09-13 6 | Editor: Jonas Jacek 7 | License: CC Attribution-Share Alike 3.0 Unported 8 | ==================================================*/ 9 | 10 | /* Reset */ 11 | header, footer, article, nav, section, aside, time, hgroup {display:block;} 12 | html, body, header, footer, article, nav, section, aside, time, h1, h2, h3, p, a, ul, li, dl, dd, dt, table, thead, tfoot, tbody, th, tr, td {border:0;font:12px/22px Verdana, sans-serif;margin:0;outline:0;padding:0;} 13 | 14 | /* BASICS */ 15 | body {background:#DDD;margin:10px 0 0 0;color:#444;} 16 | a {color:#016f93;text-decoration:none;} 17 | a:hover {color:#DB0202;} 18 | h1, h3, h4, h5, h6 {background:url(/images/ai4.png) no-repeat 0 7px;border-bottom:1px solid #CCC;color:#666;font-weight:bold;margin:0 0 10px;padding:0 0 0 25px;} 19 | h1 {background:url(/images/ai4.png) no-repeat 0 6px;font-size:15px;} 20 | h2 {font-size:14px;margin:0 0 20px 0;} 21 | h3 {background:url(/images/ai5.png) no-repeat 0 7px;} 22 | h3, h4, h5, h6 {font-size:13px;} 23 | sup {top:-4px;} 24 | 25 | /* Header */ 26 | header {-moz-border-radius:4px;-webkit-border-radius:4px;background:#0098CC url(/images/hd.jpg) no-repeat top left;height:200px;margin:0 0 10px 0;padding:10px 10px;position:relative;} 27 | header a {color:#FFF;font-size:16px;} 28 | header a:hover {color:#FFF;} 29 | header p {-moz-border-radius:4px;-webkit-border-radius:4px;background:#FFF;bottom:20px;color:#000;font-weight:bold;opacity:0.5;padding:10px;position:absolute;right:20px;width:420px;} 30 | 31 | /* Main section */ 32 | section.main {-moz-border-radius:4px;-webkit-border-radius:4px;background:#FFF;border:1px solid #CCC;float:right;height:auto;padding:20px;width:550px;margin-bottom:20px;} 33 | section.main p {margin:0 0 20px 0;} 34 | section.main img {float:left;margin:6px 10px 0 0;} 35 | 36 | /* Alerts */ 37 | .notice, .error, .warning, .error-explanation {-moz-border-radius:4px;-webkit-border-radius:4px;padding:5px 10px;margin-bottom:20px;border-style:solid;border-width:1px;} 38 | .error, .error-explanation {background:#FFCCCC;border-color:#FF9966;} 39 | .warning {background:#FFFF99;border-color:#FFCC33;} 40 | .notice {background:#CCFF99;border-color:#CCCC33;} 41 | 42 | section.main .error-explanation ul {margin:0;} 43 | /* Citations & Quotes */ 44 | cite {border-left: 2px solid #0098CC;color:#666;font-size:10px;font-style:normal;font-weight:bold;margin:0;padding:5px 10px;} 45 | blockquote {border-left: 2px solid #0098CC;color:#666;margin:0 0 20px 0;padding:5px 10px;} 46 | 47 | /* Pre & Code */ 48 | /* 49 | pre {color:#333;font-size:10px;line-height:15px;overflow:hidden;overflow-y:hidden;} 50 | pre code {background:#EEE;border-left:2px solid #0098CC;margin:0 0 10px 0;padding:5px;display:block;} 51 | */ 52 | /* Table */ 53 | table { 54 | border-collapse:collapse; 55 | text-align:left; 56 | margin:0 0 20px 0; 57 | } 58 | caption { 59 | -moz-border-radius:4px; 60 | -webkit-border-radius:4px; 61 | background:#0098CC; 62 | color:#FFF; 63 | font-weight:bold; 64 | } 65 | tr:nth-child(odd) { 66 | background:#FFF; 67 | } 68 | tr:nth-child(even) { 69 | background:#DDD; 70 | } 71 | tr:hover td { 72 | color:#0098CC; 73 | } 74 | td, th { 75 | min-width:120px; 76 | padding:0 5px; 77 | vertical-align:top; 78 | } 79 | th { 80 | background:#FFF; 81 | border-bottom:2px solid #0098CC; 82 | color:#666; 83 | font-size:10px; 84 | font-weight:bold; 85 | } 86 | td { 87 | border-bottom:1px solid #CCC; 88 | font-size:10px; 89 | } 90 | 91 | /* Calendar */ 92 | dl.vevent {margin:-20px 0 20px 0;padding:0;} 93 | .vevent dt {font-size:10px;position:relative;left:0;top:22px;font-weight:bold;} 94 | .vevent dd {border-left:2px solid #0098CC;font-size:11px;margin:0 0 0 80px;padding:0 0 0 10px;} 95 | dd.summary {font-weight:bold;} 96 | .vevent a {font-size:11px;} 97 | 98 | /* Forms */ 99 | section.main form {-moz-border-radius:4px;-webkit-border-radius:4px;background:#DDD;margin:0 0 20px;padding:10px;} 100 | label {color:#666;display:block;font-size:10px;font-weight:bold;margin:0 0 0 2px;} 101 | input, textarea {-moz-border-radius:4px;-webkit-border-radius:4px;border:1px solid #CCC;font-size:11px;padding:4px 5px;width:458px;} 102 | input {margin:0 0 10px;display:block;} 103 | input.submit, .btn {background:#999;border:1px solid #888;color:#FFF;cursor:pointer;font-weight:bold;margin:20px 0 0 0;text-shadow:0 -1px 1px rgba(0,0,0,0.25);width:25%;} 104 | textarea {height:100px;} 105 | 106 | /* Lists */ 107 | section.main ul, aside ul { 108 | list-style:none; 109 | margin:0 0 20px 0; 110 | } 111 | section.main ul { 112 | margin:0 0 20px 23px; 113 | } 114 | section.main ul li { 115 | background:url(/images/ai2.png) no-repeat 0 8px; 116 | padding:0 0 0 17px; 117 | } 118 | 119 | /* Sidebar */ 120 | aside {background:#EEE;float:left;margin:0 0 20px 0;width:200px;} 121 | 122 | /* Search Box */ 123 | .s {-moz-border-radius:4px;-webkit-border-radius:4px;margin:0 0 20px 0;padding:10px;width:179px;} 124 | .s input {-moz-border-radius: 4px;-webkit-border-radius:4px;border:1px solid #AAA;color:#999;font-size:11px;padding:4px 5px;width:168px;} 125 | 126 | /* Navigation & Menu */ 127 | nav ul {list-style:none;} 128 | nav li {background:url(/images/ai1.png) no-repeat 0 8px;padding:0 0 0 15px;} 129 | nav li ul, aside li ul li ul {margin:0;} 130 | nav li li a {font-size:11px;} 131 | nav li li li a {font-size:10px;} 132 | nav li li li, aside li.active li li {background:url(/images/ai8.png) no-repeat 0 10px;} 133 | nav li.active, aside li.active li {background:url(/images/ai2.png) no-repeat 0 8px;} 134 | 135 | /* Gallery */ 136 | .gallery { 137 | list-style:none; 138 | margin:0 0 10px; 139 | } 140 | .gallery li { 141 | display: inline; 142 | margin:0 15px 0 0; 143 | } 144 | .gallery a img { 145 | border:1px solid #999; 146 | height:50px; 147 | opacity: 0.8; 148 | padding:1px; 149 | width:50px; 150 | } 151 | .gallery li:last-child { 152 | margin:0 0 10px 0; 153 | } 154 | .gallery a img:hover{ 155 | opacity: 1; 156 | } 157 | 158 | /* Ad Space */ 159 | .adspace { 160 | -moz-border-radius:4px; 161 | -webkit-border-radius:4px; 162 | -moz-box-shadow:0 2px 2px rgba(0,0,0,0.3); 163 | -webkit-box-shadow:0 2px 2px rgba(0,0,0,0.3); 164 | background:#EEE; 165 | height:100%; 166 | margin:0 0 20px 0; 167 | padding:5px 10px; 168 | text-align:center; 169 | width:178px; 170 | } 171 | .adspace a img { 172 | border:none; 173 | } 174 | 175 | /* Tag Cloud */ 176 | #tagcloud {overflow:hidden;width:200px;} 177 | #tagcloud li {display:inline;margin:0 10px 0 0;} 178 | #tagcloud .size-1 a {font-size:0.9em;} 179 | #tagcloud .size-2 a {font-size:1.2em;} 180 | #tagcloud .size-3 a {font-size:1.4em;} 181 | #tagcloud .size-4 a {font-size:1.6em;} 182 | 183 | /* Footer */ 184 | footer { 185 | border-top:1px dotted #B5B3A9; 186 | clear:both; 187 | margin:20px 0; 188 | } 189 | footer a, footer p { 190 | color:#666; 191 | display:inline; 192 | font-size:10px; 193 | } 194 | 195 | /* Wrappers */ 196 | #a, #b { 197 | margin:0 auto; 198 | position:relative; 199 | } 200 | #a { 201 | -moz-border-radius:4px; 202 | -webkit-border-radius:4px; 203 | -moz-box-shadow:0 2px 2px rgba(0,0,0,0.3); 204 | -webkit-box-shadow:0 2px 2px rgba(0,0,0,0.3); 205 | background:#EEE; 206 | padding:10px 10px 0 10px; 207 | width:800px; 208 | } 209 | #b { 210 | overflow:hidden; 211 | } 212 | 213 | /* Shadow-Boxes*/ 214 | #c, .meta, .s, nav ul { 215 | -moz-border-radius:4px; 216 | -webkit-border-radius:4px; 217 | -moz-box-shadow:0 2px 2px rgba(0,0,0,0.4); 218 | -webkit-box-shadow:0 2px 2px rgba(0,0,0,0.4); 219 | background:#CCC; 220 | } 221 | #c { 222 | margin:0 0 20px 0; 223 | padding:5px 10px; 224 | width:178px; 225 | } 226 | #c p, #c a { 227 | font-size:11px; 228 | line-height:15px; 229 | } 230 | #c p { 231 | margin:0 0 10px 0; 232 | } 233 | #c img { 234 | -moz-border-radius:4px; 235 | -webkit-border-radius:4px; 236 | float:left; 237 | margin:4px 10px 2px 0; 238 | } 239 | .meta { 240 | margin:20px 0 3px; 241 | padding:2px 5px; 242 | } 243 | .meta p, .meta a { 244 | font-size:10px; 245 | margin:0; 246 | } 247 | nav ul { 248 | padding:10px; 249 | } 250 | nav ul ul { 251 | -moz-border-radius:none; 252 | -webkit-border-radius:none; 253 | -moz-box-shadow:none; 254 | -webkit-box-shadow:none; 255 | } 256 | 257 | article.snippet .tags a {margin-right:10px;} 258 | article.snippet.short {margin-bottom:20px;} 259 | article.snippet.short h4 a {font-size:13px;font-weight:bold;color:#666666;} 260 | article.snippet.short h4 a:hover {color:#016F93;} 261 | article.snippet.short pre {max-height:145px;overflow:hidden;} 262 | 263 | .fieldWithErrors label {color:#AA4444;} 264 | .fieldWithErrors input {color:#AA4444;border-color:#FF9966;background-color:#FFCCCC;} 265 | 266 | 267 | form.login .text, form.login .password { width:200px; } 268 | form.register .text, form.register .password { width:200px; } -------------------------------------------------------------------------------- /public/design/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | OWMX-3 - FREE HTML5 AND CSS3 TEMPLATE 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 |
13 | OWMX-3 HTML5 & CSS3 14 |

This W3C-compliant, CSS-based website template has a Creative Commons Attribution-Share Alike 3.0 Unported License.

15 |
16 |
17 |
18 |

HTML5 & CSS3 Template

19 | 20 |

This W3C-compliant, CSS-based website template has a Creative Commons Attribution-Share Alike 3.0 Unported License.

21 |

Feel free to remix, copy, distribute and transmit this template. Just know that you must attribute the work in the manner specified by me. Please see the license. Also, if you alter, transform, or build upon this work, you may distribute the resulting work only under the same, similar or a compatible license. All I ask is that you include a link back to my website in your credits.

22 |

Let the Show Begin - Pre and Code

23 |

This is how it looks if you use pre and code together, for example to highlight and nicely markup a piece of code:

24 |
pre {
font-size : 12px;
background : #F0F0F0;
}
25 |

Example Blockquote

26 |

If you want to quote somebody, you can use this perfectly semantic example for a blockquote:

27 | Jonas Jacek 28 |
29 | During my years in the Internet Marketing business I have seen and done many things I never thought would be of interest to me or anyone else. 30 |
31 |

Examples Alerts, Notice & Confirmation

32 |

These sample styles for alerts and notices are useful if you want to use the template in content management systems.

33 |

Alert: This is how an alert looks like.

34 |

Notice: This is how a notice looks like.

35 |

Confirmation: This is how a confirmation looks like.

36 |

Example Table

37 |

The following is the design for a table. The style is simple and user-friendly. Some of the effects were made with CSS3.

38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 |
Mini HTML5 Reference Guide
TagInfoAttributes
<abbr>abbreviationglobal attributes**
<area>in an image map alt, coords, href, hreflang, media, ping, rel, shape, target, type
<article>article/ contentglobal attributes**
<aside>sidebarglobal attributes**
<audio>sound contentautobuffer, autoplay, controls, loop, src
<b>bold textglobal attributes**
78 |

Example hCalendar

79 |

The following is a definition list in combination with the hCalendar microformat.

80 |
81 |
11-18-2010
82 |
Conference Name
83 |
http://www.conference-website.com/
84 |
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi nec eleifend diam. Fusce lobortis odio ac sem scelerisque sed iaculis purus ornare.
85 |
86 |

Example Video

87 |

You can put your Video-Files here...

88 | 89 |

Example Audio

90 |

You can put your Audio-Files here...

91 | 92 |

Example Lists

93 |

Two different kinds of lists were styled: Ordered lists (ol) and unordered (ul) lists.

94 |
    95 |
  1. This is
  2. 96 |
  3. The Ordered
  4. 97 |
  5. Listing
  6. 98 |
99 |
    100 |
  • This is
  • 101 |
  • The Unordered
  • 102 |
  • Listing
  • 103 |
104 |

Example Form

105 |

This is how a form will look like in this template.

106 |
107 | 108 | 109 | 110 | 111 | 112 | 113 |
114 | 115 |
116 |
117 |

Author: Jonas Jacek | Date: 2010-01-21 | Comments: 7

118 |

Tags: , , ,

119 |
120 |
121 | 180 |
181 | 184 |
185 | 186 | -------------------------------------------------------------------------------- /vendor/plugins/open_id_authentication/lib/open_id_authentication.rb: -------------------------------------------------------------------------------- 1 | require 'uri' 2 | require 'openid/extensions/sreg' 3 | require 'openid/extensions/ax' 4 | require 'openid/store/filesystem' 5 | 6 | require File.dirname(__FILE__) + '/open_id_authentication/association' 7 | require File.dirname(__FILE__) + '/open_id_authentication/nonce' 8 | require File.dirname(__FILE__) + '/open_id_authentication/db_store' 9 | require File.dirname(__FILE__) + '/open_id_authentication/request' 10 | require File.dirname(__FILE__) + '/open_id_authentication/timeout_fixes' if OpenID::VERSION == "2.0.4" 11 | 12 | module OpenIdAuthentication 13 | OPEN_ID_AUTHENTICATION_DIR = RAILS_ROOT + "/tmp/openids" 14 | 15 | def self.store 16 | @@store 17 | end 18 | 19 | def self.store=(*store_option) 20 | store, *parameters = *([ store_option ].flatten) 21 | 22 | @@store = case store 23 | when :db 24 | OpenIdAuthentication::DbStore.new 25 | when :file 26 | OpenID::Store::Filesystem.new(OPEN_ID_AUTHENTICATION_DIR) 27 | else 28 | store 29 | end 30 | end 31 | 32 | self.store = :db 33 | 34 | class InvalidOpenId < StandardError 35 | end 36 | 37 | class Result 38 | ERROR_MESSAGES = { 39 | :missing => "Sorry, the OpenID server couldn't be found", 40 | :invalid => "Sorry, but this does not appear to be a valid OpenID", 41 | :canceled => "OpenID verification was canceled", 42 | :failed => "OpenID verification failed", 43 | :setup_needed => "OpenID verification needs setup" 44 | } 45 | 46 | def self.[](code) 47 | new(code) 48 | end 49 | 50 | def initialize(code) 51 | @code = code 52 | end 53 | 54 | def status 55 | @code 56 | end 57 | 58 | ERROR_MESSAGES.keys.each { |state| define_method("#{state}?") { @code == state } } 59 | 60 | def successful? 61 | @code == :successful 62 | end 63 | 64 | def unsuccessful? 65 | ERROR_MESSAGES.keys.include?(@code) 66 | end 67 | 68 | def message 69 | ERROR_MESSAGES[@code] 70 | end 71 | end 72 | 73 | # normalizes an OpenID according to http://openid.net/specs/openid-authentication-2_0.html#normalization 74 | def self.normalize_identifier(identifier) 75 | # clean up whitespace 76 | identifier = identifier.to_s.strip 77 | 78 | # if an XRI has a prefix, strip it. 79 | identifier.gsub!(/xri:\/\//i, '') 80 | 81 | # dodge XRIs -- TODO: validate, don't just skip. 82 | unless ['=', '@', '+', '$', '!', '('].include?(identifier.at(0)) 83 | # does it begin with http? if not, add it. 84 | identifier = "http://#{identifier}" unless identifier =~ /^http/i 85 | 86 | # strip any fragments 87 | identifier.gsub!(/\#(.*)$/, '') 88 | 89 | begin 90 | uri = URI.parse(identifier) 91 | uri.scheme = uri.scheme.downcase # URI should do this 92 | identifier = uri.normalize.to_s 93 | rescue URI::InvalidURIError 94 | raise InvalidOpenId.new("#{identifier} is not an OpenID identifier") 95 | end 96 | end 97 | 98 | return identifier 99 | end 100 | 101 | # deprecated for OpenID 2.0, where not all OpenIDs are URLs 102 | def self.normalize_url(url) 103 | ActiveSupport::Deprecation.warn "normalize_url has been deprecated, use normalize_identifier instead" 104 | self.normalize_identifier(url) 105 | end 106 | 107 | protected 108 | def normalize_url(url) 109 | OpenIdAuthentication.normalize_url(url) 110 | end 111 | 112 | def normalize_identifier(url) 113 | OpenIdAuthentication.normalize_identifier(url) 114 | end 115 | 116 | # The parameter name of "openid_identifier" is used rather than the Rails convention "open_id_identifier" 117 | # because that's what the specification dictates in order to get browser auto-complete working across sites 118 | def using_open_id?(identity_url = nil) #:doc: 119 | identity_url ||= params[:openid_identifier] || params[:openid_url] 120 | !identity_url.blank? || params[:open_id_complete] 121 | end 122 | 123 | def authenticate_with_open_id(identity_url = nil, options = {}, &block) #:doc: 124 | identity_url ||= params[:openid_identifier] || params[:openid_url] 125 | 126 | if params[:open_id_complete].nil? 127 | begin_open_id_authentication(identity_url, options, &block) 128 | else 129 | complete_open_id_authentication(&block) 130 | end 131 | end 132 | 133 | private 134 | def begin_open_id_authentication(identity_url, options = {}) 135 | identity_url = normalize_identifier(identity_url) 136 | return_to = options.delete(:return_to) 137 | method = options.delete(:method) 138 | 139 | options[:required] ||= [] # reduces validation later 140 | options[:optional] ||= [] 141 | 142 | open_id_request = open_id_consumer.begin(identity_url) 143 | add_simple_registration_fields(open_id_request, options) 144 | add_ax_fields(open_id_request, options) 145 | redirect_to(open_id_redirect_url(open_id_request, return_to, method)) 146 | rescue OpenIdAuthentication::InvalidOpenId => e 147 | yield Result[:invalid], identity_url, nil 148 | rescue OpenID::OpenIDError, Timeout::Error => e 149 | logger.error("[OPENID] #{e}") 150 | yield Result[:missing], identity_url, nil 151 | end 152 | 153 | def complete_open_id_authentication 154 | params_with_path = params.reject { |key, value| request.path_parameters[key] } 155 | params_with_path.delete(:format) 156 | open_id_response = timeout_protection_from_identity_server { open_id_consumer.complete(params_with_path, requested_url) } 157 | identity_url = normalize_identifier(open_id_response.display_identifier) if open_id_response.display_identifier 158 | 159 | case open_id_response.status 160 | when OpenID::Consumer::SUCCESS 161 | profile_data = {} 162 | 163 | # merge the SReg data and the AX data into a single hash of profile data 164 | [ OpenID::SReg::Response, OpenID::AX::FetchResponse ].each do |data_response| 165 | if data_response.from_success_response( open_id_response ) 166 | profile_data.merge! data_response.from_success_response( open_id_response ).data 167 | end 168 | end 169 | 170 | yield Result[:successful], identity_url, profile_data 171 | when OpenID::Consumer::CANCEL 172 | yield Result[:canceled], identity_url, nil 173 | when OpenID::Consumer::FAILURE 174 | yield Result[:failed], identity_url, nil 175 | when OpenID::Consumer::SETUP_NEEDED 176 | yield Result[:setup_needed], open_id_response.setup_url, nil 177 | end 178 | end 179 | 180 | def open_id_consumer 181 | OpenID::Consumer.new(session, OpenIdAuthentication.store) 182 | end 183 | 184 | def add_simple_registration_fields(open_id_request, fields) 185 | sreg_request = OpenID::SReg::Request.new 186 | 187 | # filter out AX identifiers (URIs) 188 | required_fields = fields[:required].collect { |f| f.to_s unless f =~ /^https?:\/\// }.compact 189 | optional_fields = fields[:optional].collect { |f| f.to_s unless f =~ /^https?:\/\// }.compact 190 | 191 | sreg_request.request_fields(required_fields, true) unless required_fields.blank? 192 | sreg_request.request_fields(optional_fields, false) unless optional_fields.blank? 193 | sreg_request.policy_url = fields[:policy_url] if fields[:policy_url] 194 | open_id_request.add_extension(sreg_request) 195 | end 196 | 197 | def add_ax_fields( open_id_request, fields ) 198 | ax_request = OpenID::AX::FetchRequest.new 199 | 200 | # look through the :required and :optional fields for URIs (AX identifiers) 201 | fields[:required].each do |f| 202 | next unless f =~ /^https?:\/\// 203 | ax_request.add( OpenID::AX::AttrInfo.new( f, nil, true ) ) 204 | end 205 | 206 | fields[:optional].each do |f| 207 | next unless f =~ /^https?:\/\// 208 | ax_request.add( OpenID::AX::AttrInfo.new( f, nil, false ) ) 209 | end 210 | 211 | open_id_request.add_extension( ax_request ) 212 | end 213 | 214 | def open_id_redirect_url(open_id_request, return_to = nil, method = nil) 215 | open_id_request.return_to_args['_method'] = (method || request.method).to_s 216 | open_id_request.return_to_args['open_id_complete'] = '1' 217 | open_id_request.redirect_url(root_url, return_to || requested_url) 218 | end 219 | 220 | def requested_url 221 | relative_url_root = self.class.respond_to?(:relative_url_root) ? 222 | self.class.relative_url_root.to_s : 223 | request.relative_url_root 224 | "#{request.protocol}#{request.host_with_port}#{ActionController::Base.relative_url_root}#{request.path}" 225 | end 226 | 227 | def timeout_protection_from_identity_server 228 | yield 229 | rescue Timeout::Error 230 | Class.new do 231 | def status 232 | OpenID::FAILURE 233 | end 234 | 235 | def msg 236 | "Identity server timed out" 237 | end 238 | end.new 239 | end 240 | end 241 | -------------------------------------------------------------------------------- /vendor/plugins/open_id_authentication/README: -------------------------------------------------------------------------------- 1 | OpenIdAuthentication 2 | ==================== 3 | 4 | Provides a thin wrapper around the excellent ruby-openid gem from JanRan. Be sure to install that first: 5 | 6 | gem install ruby-openid 7 | 8 | To understand what OpenID is about and how it works, it helps to read the documentation for lib/openid/consumer.rb 9 | from that gem. 10 | 11 | The specification used is http://openid.net/specs/openid-authentication-2_0.html. 12 | 13 | 14 | Prerequisites 15 | ============= 16 | 17 | OpenID authentication uses the session, so be sure that you haven't turned that off. It also relies on a number of 18 | database tables to store the authentication keys. So you'll have to run the migration to create these before you get started: 19 | 20 | rake open_id_authentication:db:create 21 | 22 | Or, use the included generators to install or upgrade: 23 | 24 | ./script/generate open_id_authentication_tables MigrationName 25 | ./script/generate upgrade_open_id_authentication_tables MigrationName 26 | 27 | Alternatively, you can use the file-based store, which just relies on on tmp/openids being present in RAILS_ROOT. But be aware that this store only works if you have a single application server. And it's not safe to use across NFS. It's recommended that you use the database store if at all possible. To use the file-based store, you'll also have to add this line to your config/environment.rb: 28 | 29 | OpenIdAuthentication.store = :file 30 | 31 | This particular plugin also relies on the fact that the authentication action allows for both POST and GET operations. 32 | If you're using RESTful authentication, you'll need to explicitly allow for this in your routes.rb. 33 | 34 | The plugin also expects to find a root_url method that points to the home page of your site. You can accomplish this by using a root route in config/routes.rb: 35 | 36 | map.root :controller => 'articles' 37 | 38 | This plugin relies on Rails Edge revision 6317 or newer. 39 | 40 | 41 | Example 42 | ======= 43 | 44 | This example is just to meant to demonstrate how you could use OpenID authentication. You might well want to add 45 | salted hash logins instead of plain text passwords and other requirements on top of this. Treat it as a starting point, 46 | not a destination. 47 | 48 | Note that the User model referenced in the simple example below has an 'identity_url' attribute. You will want to add the same or similar field to whatever 49 | model you are using for authentication. 50 | 51 | Also of note is the following code block used in the example below: 52 | 53 | authenticate_with_open_id do |result, identity_url| 54 | ... 55 | end 56 | 57 | In the above code block, 'identity_url' will need to match user.identity_url exactly. 'identity_url' will be a string in the form of 'http://example.com' - 58 | If you are storing just 'example.com' with your user, the lookup will fail. 59 | 60 | There is a handy method in this plugin called 'normalize_url' that will help with validating OpenID URLs. 61 | 62 | OpenIdAuthentication.normalize_url(user.identity_url) 63 | 64 | The above will return a standardized version of the OpenID URL - the above called with 'example.com' will return 'http://example.com/' 65 | It will also raise an InvalidOpenId exception if the URL is determined to not be valid. 66 | Use the above code in your User model and validate OpenID URLs before saving them. 67 | 68 | config/routes.rb 69 | 70 | map.root :controller => 'articles' 71 | map.resource :session 72 | 73 | 74 | app/views/sessions/new.erb 75 | 76 | <% form_tag(session_url) do %> 77 |

78 | 79 | <%= text_field_tag "name" %> 80 |

81 | 82 |

83 | 84 | <%= password_field_tag %> 85 |

86 | 87 |

88 | ...or use: 89 |

90 | 91 |

92 | 93 | <%= text_field_tag "openid_identifier" %> 94 |

95 | 96 |

97 | <%= submit_tag 'Sign in', :disable_with => "Signing in…" %> 98 |

99 | <% end %> 100 | 101 | app/controllers/sessions_controller.rb 102 | class SessionsController < ApplicationController 103 | def create 104 | if using_open_id? 105 | open_id_authentication 106 | else 107 | password_authentication(params[:name], params[:password]) 108 | end 109 | end 110 | 111 | 112 | protected 113 | def password_authentication(name, password) 114 | if @current_user = @account.users.authenticate(params[:name], params[:password]) 115 | successful_login 116 | else 117 | failed_login "Sorry, that username/password doesn't work" 118 | end 119 | end 120 | 121 | def open_id_authentication 122 | authenticate_with_open_id do |result, identity_url| 123 | if result.successful? 124 | if @current_user = @account.users.find_by_identity_url(identity_url) 125 | successful_login 126 | else 127 | failed_login "Sorry, no user by that identity URL exists (#{identity_url})" 128 | end 129 | else 130 | failed_login result.message 131 | end 132 | end 133 | end 134 | 135 | 136 | private 137 | def successful_login 138 | session[:user_id] = @current_user.id 139 | redirect_to(root_url) 140 | end 141 | 142 | def failed_login(message) 143 | flash[:error] = message 144 | redirect_to(new_session_url) 145 | end 146 | end 147 | 148 | 149 | 150 | If you're fine with the result messages above and don't need individual logic on a per-failure basis, 151 | you can collapse the case into a mere boolean: 152 | 153 | def open_id_authentication 154 | authenticate_with_open_id do |result, identity_url| 155 | if result.successful? && @current_user = @account.users.find_by_identity_url(identity_url) 156 | successful_login 157 | else 158 | failed_login(result.message || "Sorry, no user by that identity URL exists (#{identity_url})") 159 | end 160 | end 161 | end 162 | 163 | 164 | Simple Registration OpenID Extension 165 | ==================================== 166 | 167 | Some OpenID Providers support this lightweight profile exchange protocol. See more: http://www.openidenabled.com/openid/simple-registration-extension 168 | 169 | You can support it in your app by changing #open_id_authentication 170 | 171 | def open_id_authentication(identity_url) 172 | # Pass optional :required and :optional keys to specify what sreg fields you want. 173 | # Be sure to yield registration, a third argument in the #authenticate_with_open_id block. 174 | authenticate_with_open_id(identity_url, 175 | :required => [ :nickname, :email ], 176 | :optional => :fullname) do |result, identity_url, registration| 177 | case result.status 178 | when :missing 179 | failed_login "Sorry, the OpenID server couldn't be found" 180 | when :invalid 181 | failed_login "Sorry, but this does not appear to be a valid OpenID" 182 | when :canceled 183 | failed_login "OpenID verification was canceled" 184 | when :failed 185 | failed_login "Sorry, the OpenID verification failed" 186 | when :successful 187 | if @current_user = @account.users.find_by_identity_url(identity_url) 188 | assign_registration_attributes!(registration) 189 | 190 | if current_user.save 191 | successful_login 192 | else 193 | failed_login "Your OpenID profile registration failed: " + 194 | @current_user.errors.full_messages.to_sentence 195 | end 196 | else 197 | failed_login "Sorry, no user by that identity URL exists" 198 | end 199 | end 200 | end 201 | end 202 | 203 | # registration is a hash containing the valid sreg keys given above 204 | # use this to map them to fields of your user model 205 | def assign_registration_attributes!(registration) 206 | model_to_registration_mapping.each do |model_attribute, registration_attribute| 207 | unless registration[registration_attribute].blank? 208 | @current_user.send("#{model_attribute}=", registration[registration_attribute]) 209 | end 210 | end 211 | end 212 | 213 | def model_to_registration_mapping 214 | { :login => 'nickname', :email => 'email', :display_name => 'fullname' } 215 | end 216 | 217 | Attribute Exchange OpenID Extension 218 | =================================== 219 | 220 | Some OpenID providers also support the OpenID AX (attribute exchange) protocol for exchanging identity information between endpoints. See more: http://openid.net/specs/openid-attribute-exchange-1_0.html 221 | 222 | Accessing AX data is very similar to the Simple Registration process, described above -- just add the URI identifier for the AX field to your :optional or :required parameters. For example: 223 | 224 | authenticate_with_open_id(identity_url, 225 | :required => [ :email, 'http://schema.openid.net/birthDate' ]) do |result, identity_url, registration| 226 | 227 | This would provide the sreg data for :email, and the AX data for 'http://schema.openid.net/birthDate' 228 | 229 | 230 | 231 | Copyright (c) 2007 David Heinemeier Hansson, released under the MIT license -------------------------------------------------------------------------------- /vendor/plugins/acts_as_taggable_on_steroids/lib/acts_as_taggable.rb: -------------------------------------------------------------------------------- 1 | module ActiveRecord #:nodoc: 2 | module Acts #:nodoc: 3 | module Taggable #:nodoc: 4 | def self.included(base) 5 | base.extend(ClassMethods) 6 | end 7 | 8 | module ClassMethods 9 | def acts_as_taggable 10 | has_many :taggings, :as => :taggable, :dependent => :destroy, :include => :tag 11 | has_many :tags, :through => :taggings 12 | 13 | before_save :save_cached_tag_list 14 | 15 | after_create :save_tags 16 | after_update :save_tags 17 | 18 | include ActiveRecord::Acts::Taggable::InstanceMethods 19 | extend ActiveRecord::Acts::Taggable::SingletonMethods 20 | 21 | alias_method_chain :reload, :tag_list 22 | end 23 | 24 | def cached_tag_list_column_name 25 | "cached_tag_list" 26 | end 27 | 28 | def set_cached_tag_list_column_name(value = nil, &block) 29 | define_attr_method :cached_tag_list_column_name, value, &block 30 | end 31 | end 32 | 33 | module SingletonMethods 34 | # Returns an array of related tags. 35 | # Related tags are all the other tags that are found on the models tagged with the provided tags. 36 | # 37 | # Pass either a tag, string, or an array of strings or tags. 38 | # 39 | # Options: 40 | # :order - SQL Order how to order the tags. Defaults to "count DESC, tags.name". 41 | def find_related_tags(tags, options = {}) 42 | tags = tags.is_a?(Array) ? TagList.new(tags.map(&:to_s)) : TagList.from(tags) 43 | 44 | related_models = find_tagged_with(tags) 45 | 46 | return [] if related_models.blank? 47 | 48 | related_ids = related_models.to_s(:db) 49 | 50 | Tag.find(:all, options.merge({ 51 | :select => "#{Tag.table_name}.*, COUNT(#{Tag.table_name}.id) AS count", 52 | :joins => "JOIN #{Tagging.table_name} ON #{Tagging.table_name}.taggable_type = '#{base_class.name}' 53 | AND #{Tagging.table_name}.taggable_id IN (#{related_ids}) 54 | AND #{Tagging.table_name}.tag_id = #{Tag.table_name}.id", 55 | :order => options[:order] || "count DESC, #{Tag.table_name}.name", 56 | :group => "#{Tag.table_name}.id, #{Tag.table_name}.name HAVING #{Tag.table_name}.name NOT IN (#{tags.map { |n| quote_value(n) }.join(",")})" 57 | })) 58 | end 59 | 60 | # Pass either a tag, string, or an array of strings or tags. 61 | # 62 | # Options: 63 | # :exclude - Find models that are not tagged with the given tags 64 | # :match_all - Find models that match all of the given tags, not just one 65 | # :conditions - A piece of SQL conditions to add to the query 66 | def find_tagged_with(*args) 67 | options = find_options_for_find_tagged_with(*args) 68 | options.blank? ? [] : find(:all, options) 69 | end 70 | 71 | def find_options_for_find_tagged_with(tags, options = {}) 72 | tags = tags.is_a?(Array) ? TagList.new(tags.map(&:to_s)) : TagList.from(tags) 73 | options = options.dup 74 | 75 | return {} if tags.empty? 76 | 77 | conditions = [] 78 | conditions << sanitize_sql(options.delete(:conditions)) if options[:conditions] 79 | 80 | taggings_alias, tags_alias = "#{table_name}_taggings", "#{table_name}_tags" 81 | 82 | joins = [ 83 | "INNER JOIN #{Tagging.table_name} #{taggings_alias} ON #{taggings_alias}.taggable_id = #{table_name}.#{primary_key} AND #{taggings_alias}.taggable_type = #{quote_value(base_class.name)}", 84 | "INNER JOIN #{Tag.table_name} #{tags_alias} ON #{tags_alias}.id = #{taggings_alias}.tag_id" 85 | ] 86 | 87 | if options.delete(:exclude) 88 | conditions << <<-END 89 | #{table_name}.id NOT IN 90 | (SELECT #{Tagging.table_name}.taggable_id FROM #{Tagging.table_name} 91 | INNER JOIN #{Tag.table_name} ON #{Tagging.table_name}.tag_id = #{Tag.table_name}.id 92 | WHERE #{tags_condition(tags)} AND #{Tagging.table_name}.taggable_type = #{quote_value(base_class.name)}) 93 | END 94 | else 95 | if options.delete(:match_all) 96 | joins << joins_for_match_all_tags(tags) 97 | else 98 | conditions << tags_condition(tags, tags_alias) 99 | end 100 | end 101 | 102 | { :select => "DISTINCT #{table_name}.*", 103 | :joins => joins.join(" "), 104 | :conditions => conditions.join(" AND ") 105 | }.reverse_merge!(options) 106 | end 107 | 108 | def joins_for_match_all_tags(tags) 109 | joins = [] 110 | 111 | tags.each_with_index do |tag, index| 112 | taggings_alias, tags_alias = "taggings_#{index}", "tags_#{index}" 113 | 114 | join = <<-END 115 | INNER JOIN #{Tagging.table_name} #{taggings_alias} ON 116 | #{taggings_alias}.taggable_id = #{table_name}.#{primary_key} AND 117 | #{taggings_alias}.taggable_type = #{quote_value(base_class.name)} 118 | 119 | INNER JOIN #{Tag.table_name} #{tags_alias} ON 120 | #{taggings_alias}.tag_id = #{tags_alias}.id AND 121 | #{tags_alias}.name = ? 122 | END 123 | 124 | joins << sanitize_sql([join, tag]) 125 | end 126 | 127 | joins.join(" ") 128 | end 129 | 130 | # Calculate the tag counts for all tags. 131 | # 132 | # See Tag.counts for available options. 133 | def tag_counts(options = {}) 134 | Tag.find(:all, find_options_for_tag_counts(options)) 135 | end 136 | 137 | def find_options_for_tag_counts(options = {}) 138 | options = options.dup 139 | scope = scope(:find) 140 | 141 | conditions = [] 142 | conditions << send(:sanitize_conditions, options.delete(:conditions)) if options[:conditions] 143 | conditions << send(:sanitize_conditions, scope[:conditions]) if scope && scope[:conditions] 144 | conditions << "#{Tagging.table_name}.taggable_type = #{quote_value(base_class.name)}" 145 | conditions << type_condition unless descends_from_active_record? 146 | conditions.compact! 147 | conditions = conditions.join(" AND ") 148 | 149 | joins = ["INNER JOIN #{table_name} ON #{table_name}.#{primary_key} = #{Tagging.table_name}.taggable_id"] 150 | joins << options.delete(:joins) if options[:joins].present? 151 | joins << scope[:joins] if scope && scope[:joins].present? 152 | joins = joins.join(" ") 153 | 154 | options = { :conditions => conditions, :joins => joins }.update(options) 155 | 156 | Tag.options_for_counts(options) 157 | end 158 | 159 | def caching_tag_list? 160 | column_names.include?(cached_tag_list_column_name) 161 | end 162 | 163 | private 164 | def tags_condition(tags, table_name = Tag.table_name) 165 | condition = tags.map { |t| sanitize_sql(["#{table_name}.name LIKE ?", t]) }.join(" OR ") 166 | "(" + condition + ")" unless condition.blank? 167 | end 168 | end 169 | 170 | module InstanceMethods 171 | def tag_list 172 | return @tag_list if @tag_list 173 | 174 | if self.class.caching_tag_list? and !(cached_value = send(self.class.cached_tag_list_column_name)).nil? 175 | @tag_list = TagList.from(cached_value) 176 | else 177 | @tag_list = TagList.new(*tags.map(&:name)) 178 | end 179 | end 180 | 181 | def tag_list=(value) 182 | @tag_list = TagList.from(value) 183 | end 184 | 185 | def save_cached_tag_list 186 | if self.class.caching_tag_list? 187 | self[self.class.cached_tag_list_column_name] = tag_list.to_s 188 | end 189 | end 190 | 191 | def save_tags 192 | return unless @tag_list 193 | 194 | new_tag_names = @tag_list - tags.map(&:name) 195 | old_tags = tags.reject { |tag| @tag_list.include?(tag.name) } 196 | 197 | self.class.transaction do 198 | if old_tags.any? 199 | taggings.find(:all, :conditions => ["tag_id IN (?)", old_tags.map(&:id)]).each(&:destroy) 200 | taggings.reset 201 | end 202 | 203 | new_tag_names.each do |new_tag_name| 204 | tags << Tag.find_or_create_with_like_by_name(new_tag_name) 205 | end 206 | end 207 | 208 | true 209 | end 210 | 211 | # Calculate the tag counts for the tags used by this model. 212 | # 213 | # The possible options are the same as the tag_counts class method. 214 | def tag_counts(options = {}) 215 | return [] if tag_list.blank? 216 | 217 | options[:conditions] = self.class.send(:merge_conditions, options[:conditions], self.class.send(:tags_condition, tag_list)) 218 | self.class.tag_counts(options) 219 | end 220 | 221 | def reload_with_tag_list(*args) #:nodoc: 222 | @tag_list = nil 223 | reload_without_tag_list(*args) 224 | end 225 | end 226 | end 227 | end 228 | end 229 | 230 | ActiveRecord::Base.send(:include, ActiveRecord::Acts::Taggable) 231 | -------------------------------------------------------------------------------- /public/design/s/a.css: -------------------------------------------------------------------------------- 1 | /*================================================== 2 | Template: OWMX-3 3 | Resource: http://www.owmx.com/ 4 | Version: 1.0 5 | Date: 2010-09-13 6 | Editor: Jonas Jacek 7 | License: CC Attribution-Share Alike 3.0 Unported 8 | ==================================================*/ 9 | 10 | /* Reset */ 11 | header, footer, article, nav, section, aside, time, hgroup { 12 | display : block; 13 | } 14 | html, body, header, footer, article, nav, section, aside, time, h1, h2, h3, p, a, ul, li, dl, dd, dt, table, thead, tfoot, tbody, th, tr, td { 15 | border : 0; 16 | font : 12px/22px Verdana, sans-serif; 17 | margin : 0; 18 | outline : 0; 19 | padding : 0; 20 | } 21 | 22 | /* BASICS */ 23 | BODY { 24 | background : #DDD; 25 | margin : 10px 0 0 0; 26 | color : #444; 27 | } 28 | 29 | A { 30 | color : #016f93; 31 | text-decoration : none; 32 | } 33 | A:HOVER { 34 | color : #DB0202; 35 | } 36 | 37 | H1, H3, H4, H5, H6 { 38 | background : url(../i/ai4.png) no-repeat 0 7px; 39 | border-bottom : 1px solid #CCC; 40 | color : #666; 41 | font-weight : bold; 42 | margin : 0 0 10px; 43 | padding : 0 0 0 25px; 44 | } 45 | H1 { 46 | background : url(../i/ai4.png) no-repeat 0 6px; 47 | font-size : 15px; 48 | } 49 | H2 { 50 | font-size : 14px; 51 | margin : 0 0 20px 0; 52 | } 53 | H3 { 54 | background : url(../i/ai5.png) no-repeat 0 7px; 55 | } 56 | H3, H4, H5, H6 { 57 | font-size : 13px; 58 | } 59 | 60 | SUP { 61 | top : -4px; 62 | } 63 | 64 | /* Header */ 65 | header { 66 | -moz-border-radius : 4px; 67 | -webkit-border-radius : 4px; 68 | background : #0098CC url(../i/hd.jpg) no-repeat top left; 69 | height : 200px; 70 | margin : 0 0 10px 0; 71 | padding : 10px 10px; 72 | position : relative; 73 | } 74 | header a { 75 | color : #FFF; 76 | font-size : 16px; 77 | } 78 | header a:hover { 79 | color : #FFF; 80 | } 81 | header p { 82 | -moz-border-radius : 4px; 83 | -webkit-border-radius : 4px; 84 | background : #FFF; 85 | bottom : 20px; 86 | color : #000; 87 | font-weight : bold; 88 | opacity : 0.5; 89 | padding : 10px; 90 | position : absolute; 91 | right : 20px; 92 | width : 400px; 93 | } 94 | 95 | /* Article */ 96 | article { 97 | -moz-border-radius : 4px; 98 | -webkit-border-radius : 4px; 99 | background : #FFF; 100 | border: 1px solid #CCC; 101 | float : right; 102 | height : auto; 103 | padding : 20px; 104 | width : 550px; 105 | } 106 | article p { 107 | margin : 0 0 20px 0; 108 | } 109 | article img { 110 | float : left; 111 | margin : 6px 10px 0 0; 112 | } 113 | 114 | /* Highlighted Paragraphs */ 115 | .highlight-1, .highlight-2, .highlight-3 { 116 | -moz-border-radius : 4px; 117 | -webkit-border-radius : 4px; 118 | padding : 5px 10px; 119 | } 120 | .highlight-1 { 121 | background : #FFCCCC; 122 | border : 1px dotted #FF9966; 123 | } 124 | .highlight-2 { 125 | background : #FFFF99; 126 | border : 1px dotted #FFCC33; 127 | } 128 | .highlight-3 { 129 | background : #CCFF99; 130 | border : 1px dotted #CCCC33; 131 | } 132 | 133 | /* Citations & Quotes */ 134 | cite { 135 | border-left: 2px solid #0098CC; 136 | color : #666; 137 | font-size : 10px; 138 | font-style : normal; 139 | font-weight : bold; 140 | margin : 0; 141 | padding : 5px 10px; 142 | } 143 | 144 | blockquote { 145 | border-left: 2px solid #0098CC; 146 | color : #666; 147 | margin : 0 0 20px 0; 148 | padding : 5px 10px; 149 | } 150 | 151 | /* Pre & Code */ 152 | pre { 153 | color : #333; 154 | font-size : 10px; 155 | line-height : 15px; /*--Height of each line of code--*/ 156 | overflow : hidden; /*--If the Code exceeds the width, put "auto" and scrolling is available--*/ 157 | overflow-Y : hidden; /*--Hides vertical scroll created by IE--*/ 158 | } 159 | pre code { 160 | background : #EEE; 161 | border-left : 2px solid #0098CC; 162 | margin : 0 0 10px 0; 163 | padding : 5px; 164 | display : block; 165 | } 166 | 167 | /* Table */ 168 | table { 169 | border-collapse : collapse; 170 | text-align:left; 171 | margin : 0 0 20px 0; 172 | } 173 | caption { 174 | -moz-border-radius : 4px; 175 | -webkit-border-radius : 4px; 176 | background : #0098CC; 177 | color : #FFF; 178 | font-weight : bold; 179 | } 180 | tr:nth-child(odd) { 181 | background : #FFF; 182 | } 183 | tr:nth-child(even) { 184 | background : #DDD; 185 | } 186 | tr:hover td { 187 | color : #0098CC; 188 | } 189 | td, th { 190 | min-width : 120px; 191 | padding : 0 5px; 192 | vertical-align:top; 193 | } 194 | th { 195 | background : #FFF; 196 | border-bottom : 2px solid #0098CC; 197 | color : #666; 198 | font-size : 10px; 199 | font-weight : bold; 200 | } 201 | td { 202 | border-bottom : 1px solid #CCC; 203 | font-size : 10px; 204 | } 205 | 206 | /* Calendar */ 207 | dl.vevent { 208 | margin : -20px 0 20px 0; 209 | padding : 0; 210 | } 211 | .vevent dt { 212 | font-size : 10px; 213 | position : relative; 214 | left : 0; 215 | top : 22px; 216 | font-weight : bold; 217 | } 218 | .vevent dd 219 | { 220 | border-left : 2px solid #0098CC; 221 | font-size : 11px; 222 | margin : 0 0 0 80px; 223 | padding : 0 0 0 10px; 224 | } 225 | dd.summary { 226 | font-weight : bold; 227 | } 228 | .vevent a { 229 | font-size : 11px; 230 | } 231 | 232 | /* Forms */ 233 | article form { 234 | -moz-border-radius: 4px; 235 | -webkit-border-radius: 4px; 236 | background : #DDD; 237 | margin : 0 0 20px; 238 | padding : 10px; 239 | } 240 | article label { 241 | color : #666; 242 | display : block; 243 | font-size : 10px; 244 | font-weight : bold; 245 | margin : 0 0 0 2px; 246 | } 247 | article input, article textarea { 248 | -moz-border-radius: 4px; 249 | -webkit-border-radius: 4px; 250 | border : 1px solid #CCC; 251 | font-size : 11px; 252 | padding : 4px 5px; 253 | width : 458px; 254 | } 255 | article input { 256 | margin : 0 0 10px; 257 | } 258 | article input.button, .btn { 259 | background: #999; 260 | border : 1px solid #888; 261 | color: #FFF; 262 | cursor : pointer; 263 | font-weight : bold; 264 | margin : 10px 0 0 0; 265 | text-shadow : 0 -1px 1px rgba(0,0,0,0.25); 266 | width : 25%; 267 | } 268 | article textarea { 269 | height : 100px; 270 | } 271 | 272 | /* Lists */ 273 | article ul, aside ul { 274 | list-style : none; 275 | margin : 0 0 20px 0; 276 | } 277 | article ul { 278 | margin : 0 0 20px 23px; 279 | } 280 | article ul li { 281 | background : url(../i/ai2.png) no-repeat 0 8px; 282 | padding : 0 0 0 17px; 283 | } 284 | 285 | /* Sidebar */ 286 | aside { 287 | background : #EEE; 288 | float : left; 289 | margin : 0 0 20px 0; 290 | width : 200px; 291 | } 292 | 293 | /* Search Box */ 294 | .s { 295 | -moz-border-radius : 4px; 296 | -webkit-border-radius : 4px; 297 | margin : 0 0 20px 0; 298 | padding : 10px; 299 | width : 179px; 300 | } 301 | .s input { 302 | -moz-border-radius: 4px; 303 | -webkit-border-radius: 4px; 304 | border : 1px solid #AAA; 305 | color : #999; 306 | font-size : 11px; 307 | padding : 4px 5px; 308 | width : 168px; 309 | } 310 | 311 | /* Navigation & Menu */ 312 | nav ul { 313 | list-style : none; 314 | } 315 | nav li { 316 | background : url(../i/ai1.png) no-repeat 0 8px; 317 | padding : 0 0 0 15px; 318 | } 319 | nav li ul, aside li ul li ul { 320 | margin : 0; 321 | } 322 | nav li li a { 323 | font-size : 11px; 324 | } 325 | nav li li li a { 326 | font-size : 10px; 327 | } 328 | nav li li li, aside li.active li li { 329 | background : url(../i/ai8.png) no-repeat 0 10px; 330 | } 331 | nav li.active, aside li.active li { 332 | background : url(../i/ai2.png) no-repeat 0 8px; 333 | } 334 | 335 | /* Gallery */ 336 | .gallery { 337 | list-style : none; 338 | margin : 0 0 10px; 339 | } 340 | .gallery li { 341 | display: inline; 342 | margin : 0 15px 0 0; 343 | } 344 | .gallery a img { 345 | border : 1px solid #999; 346 | height : 50px; 347 | opacity: 0.8; 348 | padding : 1px; 349 | width : 50px; 350 | } 351 | .gallery li:last-child { 352 | margin : 0 0 10px 0; 353 | } 354 | .gallery a img:hover{ 355 | opacity: 1; 356 | } 357 | 358 | /* Ad Space */ 359 | .adspace { 360 | -moz-border-radius : 4px; 361 | -webkit-border-radius : 4px; 362 | -moz-box-shadow : 0 2px 2px rgba(0,0,0,0.3); 363 | -webkit-box-shadow : 0 2px 2px rgba(0,0,0,0.3); 364 | background : #EEE; 365 | height : 100%; 366 | margin : 0 0 20px 0; 367 | padding : 5px 10px; 368 | text-align : center; 369 | width : 178px; 370 | } 371 | .adspace a img { 372 | border : none; 373 | } 374 | 375 | /* Tag Cloud */ 376 | #tagcloud { 377 | overflow : hidden; 378 | width : 200px; 379 | } 380 | #tagcloud li { 381 | display : inline; 382 | margin : 0 10px 0 0; 383 | } 384 | .tagcloudsize-1 a { 385 | font-size : 14px; 386 | } 387 | .tagcloudsize-2 a { 388 | font-size : 16px; 389 | } 390 | .tagcloudsize-3 a { 391 | font-size : 18px; 392 | } 393 | 394 | /* Footer */ 395 | footer { 396 | border-top : 1px dotted #B5B3A9; 397 | clear : both; 398 | margin : 20px 0; 399 | } 400 | footer a, footer p { 401 | color : #666; 402 | display : inline; 403 | font-size : 10px; 404 | } 405 | 406 | /* Wrappers */ 407 | #a, #b { 408 | margin : 0 auto; 409 | position : relative; 410 | } 411 | #a { 412 | -moz-border-radius : 4px; 413 | -webkit-border-radius : 4px; 414 | -moz-box-shadow : 0 2px 2px rgba(0,0,0,0.3); 415 | -webkit-box-shadow : 0 2px 2px rgba(0,0,0,0.3); 416 | background : #EEE; 417 | padding : 10px 10px 0 10px; 418 | width : 800px; 419 | } 420 | #b { 421 | overflow : hidden; 422 | } 423 | 424 | /* Shadow-Boxes*/ 425 | #c, .meta, .s, nav ul { 426 | -moz-border-radius : 4px; 427 | -webkit-border-radius : 4px; 428 | -moz-box-shadow : 0 2px 2px rgba(0,0,0,0.4); 429 | -webkit-box-shadow : 0 2px 2px rgba(0,0,0,0.4); 430 | background : #CCC; 431 | } 432 | #c { 433 | margin : 0 0 20px 0; 434 | padding : 5px 10px; 435 | width : 178px; 436 | } 437 | #c p, #c a { 438 | font-size : 11px; 439 | line-height : 15px; 440 | } 441 | #c p { 442 | margin : 0 0 10px 0; 443 | } 444 | #c img { 445 | -moz-border-radius : 4px; 446 | -webkit-border-radius : 4px; 447 | float : left; 448 | margin : 4px 10px 2px 0; 449 | } 450 | .meta { 451 | margin : 20px 0 3px; 452 | padding : 2px 5px; 453 | } 454 | .meta p, .meta a { 455 | font-size : 10px; 456 | margin : 0; 457 | } 458 | nav ul { 459 | padding : 10px; 460 | } 461 | nav ul ul { 462 | -moz-border-radius : none; 463 | -webkit-border-radius : none; 464 | -moz-box-shadow : none; 465 | -webkit-box-shadow : none; 466 | } 467 | -------------------------------------------------------------------------------- /vendor/plugins/acts_as_taggable_on_steroids/test/acts_as_taggable_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/abstract_unit' 2 | 3 | class ActsAsTaggableOnSteroidsTest < ActiveSupport::TestCase 4 | def test_find_related_tags_with 5 | assert_equivalent [tags(:good), tags(:bad), tags(:question)], Post.find_related_tags("nature") 6 | assert_equivalent [tags(:nature)], Post.find_related_tags([tags(:good)]) 7 | assert_equivalent [tags(:bad), tags(:question)], Post.find_related_tags(["Very Good", "Nature"]) 8 | assert_equivalent [tags(:bad), tags(:question)], Post.find_related_tags([tags(:good), tags(:nature)]) 9 | end 10 | 11 | def test_find_tagged_with_include_and_order 12 | assert_equal photos(:sam_sky, :sam_flower, :jonathan_dog), Photo.find_tagged_with("Nature", :order => "photos.title DESC", :include => :user) 13 | end 14 | 15 | def test_find_related_tags_with_non_existent_tags 16 | assert_equal [], Post.find_related_tags("ABCDEFG") 17 | assert_equal [], Post.find_related_tags(['HIJKLM']) 18 | end 19 | 20 | def test_find_related_tags_with_nothing 21 | assert_equal [], Post.find_related_tags("") 22 | assert_equal [], Post.find_related_tags([]) 23 | end 24 | 25 | def test_find_tagged_with 26 | assert_equivalent [posts(:jonathan_sky), posts(:sam_flowers)], Post.find_tagged_with('"Very good"') 27 | assert_equal Post.find_tagged_with('"Very good"'), Post.find_tagged_with(['Very good']) 28 | assert_equal Post.find_tagged_with('"Very good"'), Post.find_tagged_with([tags(:good)]) 29 | 30 | assert_equivalent [photos(:jonathan_dog), photos(:sam_flower), photos(:sam_sky)], Photo.find_tagged_with('Nature') 31 | assert_equal Photo.find_tagged_with('Nature'), Photo.find_tagged_with(['Nature']) 32 | assert_equal Photo.find_tagged_with('Nature'), Photo.find_tagged_with([tags(:nature)]) 33 | 34 | assert_equivalent [photos(:jonathan_bad_cat), photos(:jonathan_dog), photos(:jonathan_questioning_dog)], Photo.find_tagged_with('"Crazy animal" Bad') 35 | assert_equal Photo.find_tagged_with('"Crazy animal" Bad'), Photo.find_tagged_with(['Crazy animal', 'Bad']) 36 | assert_equal Photo.find_tagged_with('"Crazy animal" Bad'), Photo.find_tagged_with([tags(:animal), tags(:bad)]) 37 | end 38 | 39 | def test_find_tagged_with_nothing 40 | assert_equal [], Post.find_tagged_with("") 41 | assert_equal [], Post.find_tagged_with([]) 42 | end 43 | 44 | def test_find_tagged_with_nonexistant_tags 45 | assert_equal [], Post.find_tagged_with('ABCDEFG') 46 | assert_equal [], Photo.find_tagged_with(['HIJKLM']) 47 | assert_equal [], Photo.find_tagged_with([Tag.new(:name => 'unsaved tag')]) 48 | end 49 | 50 | def test_find_tagged_with_match_all 51 | assert_equivalent [photos(:jonathan_dog)], Photo.find_tagged_with('Crazy animal, "Nature"', :match_all => true) 52 | end 53 | 54 | def test_find_tagged_with_match_all_and_include 55 | assert_equivalent [posts(:jonathan_sky), posts(:sam_flowers)], Post.find_tagged_with(['Very good', 'Nature'], :match_all => true, :include => :tags) 56 | end 57 | 58 | def test_find_tagged_with_conditions 59 | assert_equal [], Post.find_tagged_with('"Very good", Nature', :conditions => '1=0') 60 | end 61 | 62 | def test_find_tagged_with_duplicates_options_hash 63 | options = { :conditions => '1=1' }.freeze 64 | assert_nothing_raised { Post.find_tagged_with("Nature", options) } 65 | end 66 | 67 | def test_find_tagged_with_exclusions 68 | assert_equivalent [photos(:jonathan_questioning_dog), photos(:jonathan_bad_cat)], Photo.find_tagged_with("Nature", :exclude => true) 69 | assert_equivalent [posts(:jonathan_grass), posts(:jonathan_rain), posts(:jonathan_cloudy), posts(:jonathan_still_cloudy)], Post.find_tagged_with("'Very good', Bad", :exclude => true) 70 | end 71 | 72 | def test_find_options_for_find_tagged_with_no_tags_returns_empty_hash 73 | assert_equal Hash.new, Post.find_options_for_find_tagged_with("") 74 | assert_equal Hash.new, Post.find_options_for_find_tagged_with([nil]) 75 | end 76 | 77 | def test_find_options_for_find_tagged_with_leaves_arguments_unchanged 78 | original_tags = photos(:jonathan_questioning_dog).tags.dup 79 | Photo.find_options_for_find_tagged_with(photos(:jonathan_questioning_dog).tags) 80 | assert_equal original_tags, photos(:jonathan_questioning_dog).tags 81 | end 82 | 83 | def test_find_options_for_find_tagged_with_respects_custom_table_name 84 | Tagging.table_name = "categorisations" 85 | Tag.table_name = "categories" 86 | 87 | options = Photo.find_options_for_find_tagged_with("Hello") 88 | 89 | assert_no_match(/ taggings /, options[:joins]) 90 | assert_no_match(/ tags /, options[:joins]) 91 | 92 | assert_match(/ categorisations /, options[:joins]) 93 | assert_match(/ categories /, options[:joins]) 94 | ensure 95 | Tagging.table_name = "taggings" 96 | Tag.table_name = "tags" 97 | end 98 | 99 | def test_include_tags_on_find_tagged_with 100 | assert_nothing_raised do 101 | Photo.find_tagged_with('Nature', :include => :tags) 102 | Photo.find_tagged_with("Nature", :include => { :taggings => :tag }) 103 | end 104 | end 105 | 106 | def test_basic_tag_counts_on_class 107 | assert_tag_counts Post.tag_counts, :good => 2, :nature => 7, :question => 1, :bad => 1 108 | assert_tag_counts Photo.tag_counts, :good => 1, :nature => 3, :question => 1, :bad => 1, :animal => 3 109 | end 110 | 111 | def test_tag_counts_on_class_with_date_conditions 112 | assert_tag_counts Post.tag_counts(:start_at => Date.new(2006, 8, 4)), :good => 1, :nature => 5, :question => 1, :bad => 1 113 | assert_tag_counts Post.tag_counts(:end_at => Date.new(2006, 8, 6)), :good => 1, :nature => 4, :question => 1 114 | assert_tag_counts Post.tag_counts(:start_at => Date.new(2006, 8, 5), :end_at => Date.new(2006, 8, 10)), :good => 1, :nature => 4, :bad => 1 115 | 116 | assert_tag_counts Photo.tag_counts(:start_at => Date.new(2006, 8, 12), :end_at => Date.new(2006, 8, 19)), :good => 1, :nature => 2, :bad => 1, :question => 1, :animal => 3 117 | end 118 | 119 | def test_tag_counts_on_class_with_frequencies 120 | assert_tag_counts Photo.tag_counts(:at_least => 2), :nature => 3, :animal => 3 121 | assert_tag_counts Photo.tag_counts(:at_most => 2), :good => 1, :question => 1, :bad => 1 122 | end 123 | 124 | def test_tag_counts_on_class_with_frequencies_and_conditions 125 | assert_tag_counts Photo.tag_counts(:at_least => 2, :conditions => '1=1'), :nature => 3, :animal => 3 126 | end 127 | 128 | def test_tag_counts_duplicates_options_hash 129 | options = { :at_least => 2, :conditions => '1=1' }.freeze 130 | assert_nothing_raised { Photo.tag_counts(options) } 131 | end 132 | 133 | def test_tag_counts_with_limit 134 | assert_equal 2, Photo.tag_counts(:limit => 2).size 135 | assert_equal 1, Post.tag_counts(:at_least => 4, :limit => 2).size 136 | end 137 | 138 | def test_tag_counts_with_limit_and_order 139 | assert_equal [tags(:nature), tags(:good)], Post.tag_counts(:order => 'count desc', :limit => 2) 140 | end 141 | 142 | def test_tag_counts_on_association 143 | assert_tag_counts users(:jonathan).posts.tag_counts, :good => 1, :nature => 5, :question => 1 144 | assert_tag_counts users(:sam).posts.tag_counts, :good => 1, :nature => 2, :bad => 1 145 | 146 | assert_tag_counts users(:jonathan).photos.tag_counts, :animal => 3, :nature => 1, :question => 1, :bad => 1 147 | assert_tag_counts users(:sam).photos.tag_counts, :nature => 2, :good => 1 148 | end 149 | 150 | def test_tag_counts_on_association_with_options 151 | assert_equal [], users(:jonathan).posts.tag_counts(:conditions => '1=0') 152 | assert_tag_counts users(:jonathan).posts.tag_counts(:at_most => 2), :good => 1, :question => 1 153 | end 154 | 155 | def test_tag_counts_on_has_many_through 156 | assert_tag_counts users(:jonathan).magazines.tag_counts, :good => 1 157 | end 158 | 159 | def test_tag_counts_on_model_instance 160 | assert_tag_counts photos(:jonathan_dog).tag_counts, :animal => 3, :nature => 3 161 | end 162 | 163 | def test_tag_counts_on_model_instance_merges_conditions 164 | assert_tag_counts photos(:jonathan_dog).tag_counts(:conditions => "tags.name = 'Crazy animal'"), :animal => 3 165 | end 166 | 167 | def test_tag_counts_on_model_instance_with_no_tags 168 | photo = Photo.create! 169 | 170 | assert_tag_counts photo.tag_counts, {} 171 | end 172 | 173 | def test_tag_counts_should_sanitize_scope_conditions 174 | Photo.send :with_scope, :find => { :conditions => ["tags.id = ?", tags(:animal).id] } do 175 | assert_tag_counts Photo.tag_counts, :animal => 3 176 | end 177 | end 178 | 179 | def test_tag_counts_respects_custom_table_names 180 | Tagging.table_name = "categorisations" 181 | Tag.table_name = "categories" 182 | 183 | options = Photo.find_options_for_tag_counts(:start_at => 2.weeks.ago, :end_at => Date.today) 184 | sql = options.values.join(' ') 185 | 186 | assert_no_match /taggings/, sql 187 | assert_no_match /tags/, sql 188 | 189 | assert_match /categorisations/, sql 190 | assert_match /categories/, sql 191 | ensure 192 | Tagging.table_name = "taggings" 193 | Tag.table_name = "tags" 194 | end 195 | 196 | def test_tag_list_reader 197 | assert_equivalent ["Very good", "Nature"], posts(:jonathan_sky).tag_list 198 | assert_equivalent ["Bad", "Crazy animal"], photos(:jonathan_bad_cat).tag_list 199 | end 200 | 201 | def test_reassign_tag_list 202 | assert_equivalent ["Nature", "Question"], posts(:jonathan_rain).tag_list 203 | posts(:jonathan_rain).taggings.reload 204 | 205 | # Only an update of the posts table should be executed, the other two queries are for savepoints 206 | assert_queries 3 do 207 | posts(:jonathan_rain).update_attributes!(:tag_list => posts(:jonathan_rain).tag_list.to_s) 208 | end 209 | 210 | assert_equivalent ["Nature", "Question"], posts(:jonathan_rain).tag_list 211 | end 212 | 213 | def test_new_tags 214 | assert_equivalent ["Very good", "Nature"], posts(:jonathan_sky).tag_list 215 | posts(:jonathan_sky).update_attributes!(:tag_list => "#{posts(:jonathan_sky).tag_list}, One, Two") 216 | assert_equivalent ["Very good", "Nature", "One", "Two"], posts(:jonathan_sky).tag_list 217 | end 218 | 219 | def test_remove_tag 220 | assert_equivalent ["Very good", "Nature"], posts(:jonathan_sky).tag_list 221 | posts(:jonathan_sky).update_attributes!(:tag_list => "Nature") 222 | assert_equivalent ["Nature"], posts(:jonathan_sky).tag_list 223 | end 224 | 225 | def test_change_case_of_tags 226 | original_tag_names = photos(:jonathan_questioning_dog).tag_list 227 | photos(:jonathan_questioning_dog).update_attributes!(:tag_list => photos(:jonathan_questioning_dog).tag_list.to_s.upcase) 228 | 229 | # The new tag list is not uppercase becuase the AR finders are not case-sensitive 230 | # and find the old tags when re-tagging with the uppercase tags. 231 | assert_equivalent original_tag_names, photos(:jonathan_questioning_dog).reload.tag_list 232 | end 233 | 234 | def test_remove_and_add_tag 235 | assert_equivalent ["Very good", "Nature"], posts(:jonathan_sky).tag_list 236 | posts(:jonathan_sky).update_attributes!(:tag_list => "Nature, Beautiful") 237 | assert_equivalent ["Nature", "Beautiful"], posts(:jonathan_sky).tag_list 238 | end 239 | 240 | def test_tags_not_saved_if_validation_fails 241 | assert_equivalent ["Very good", "Nature"], posts(:jonathan_sky).tag_list 242 | assert !posts(:jonathan_sky).update_attributes(:tag_list => "One, Two", :text => "") 243 | assert_equivalent ["Very good", "Nature"], Post.find(posts(:jonathan_sky).id).tag_list 244 | end 245 | 246 | def test_tag_list_accessors_on_new_record 247 | p = Post.new(:text => 'Test') 248 | 249 | assert p.tag_list.blank? 250 | p.tag_list = "One, Two" 251 | assert_equal "One, Two", p.tag_list.to_s 252 | end 253 | 254 | def test_clear_tag_list_with_nil 255 | p = photos(:jonathan_questioning_dog) 256 | 257 | assert !p.tag_list.blank? 258 | assert p.update_attributes(:tag_list => nil) 259 | assert p.tag_list.blank? 260 | 261 | assert p.reload.tag_list.blank? 262 | end 263 | 264 | def test_clear_tag_list_with_string 265 | p = photos(:jonathan_questioning_dog) 266 | 267 | assert !p.tag_list.blank? 268 | assert p.update_attributes(:tag_list => ' ') 269 | assert p.tag_list.blank? 270 | 271 | assert p.reload.tag_list.blank? 272 | end 273 | 274 | def test_tag_list_reset_on_reload 275 | p = photos(:jonathan_questioning_dog) 276 | assert !p.tag_list.blank? 277 | p.tag_list = nil 278 | assert p.tag_list.blank? 279 | assert !p.reload.tag_list.blank? 280 | end 281 | 282 | def test_instance_tag_counts 283 | assert_tag_counts posts(:jonathan_sky).tag_counts, :good => 2, :nature => 7 284 | end 285 | 286 | def test_tag_list_populated_when_cache_nil 287 | assert_nil posts(:jonathan_sky).cached_tag_list 288 | posts(:jonathan_sky).save! 289 | assert_equal posts(:jonathan_sky).tag_list.to_s, posts(:jonathan_sky).cached_tag_list 290 | end 291 | 292 | def test_cached_tag_list_used 293 | posts(:jonathan_sky).save! 294 | posts(:jonathan_sky).reload 295 | 296 | assert_no_queries do 297 | assert_equivalent ["Very good", "Nature"], posts(:jonathan_sky).tag_list 298 | end 299 | end 300 | 301 | def test_cached_tag_list_not_used 302 | # Load fixture and column information 303 | posts(:jonathan_sky).taggings(:reload) 304 | 305 | assert_queries 1 do 306 | # Tags association will be loaded 307 | posts(:jonathan_sky).tag_list 308 | end 309 | end 310 | 311 | def test_cached_tag_list_updated 312 | assert_nil posts(:jonathan_sky).cached_tag_list 313 | posts(:jonathan_sky).save! 314 | assert_equivalent ["Very good", "Nature"], TagList.from(posts(:jonathan_sky).cached_tag_list) 315 | posts(:jonathan_sky).update_attributes!(:tag_list => "None") 316 | 317 | assert_equal 'None', posts(:jonathan_sky).cached_tag_list 318 | assert_equal 'None', posts(:jonathan_sky).reload.cached_tag_list 319 | end 320 | 321 | def test_clearing_cached_tag_list 322 | # Generate the cached tag list 323 | posts(:jonathan_sky).save! 324 | 325 | posts(:jonathan_sky).update_attributes!(:tag_list => "") 326 | assert_equal "", posts(:jonathan_sky).cached_tag_list 327 | end 328 | 329 | def test_find_tagged_with_using_sti 330 | special_post = SpecialPost.create!(:text => "Test", :tag_list => "Random") 331 | 332 | assert_equal [special_post], SpecialPost.find_tagged_with("Random") 333 | assert Post.find_tagged_with("Random").include?(special_post) 334 | end 335 | 336 | def test_tag_counts_using_sti 337 | SpecialPost.create!(:text => "Test", :tag_list => "Nature") 338 | 339 | assert_tag_counts SpecialPost.tag_counts, :nature => 1 340 | end 341 | 342 | def test_case_insensitivity 343 | assert_difference "Tag.count", 1 do 344 | Post.create!(:text => "Test", :tag_list => "one") 345 | Post.create!(:text => "Test", :tag_list => "One") 346 | end 347 | 348 | assert_equal Post.find_tagged_with("Nature"), Post.find_tagged_with("nature") 349 | end 350 | 351 | def test_tag_not_destroyed_when_unused 352 | posts(:jonathan_sky).tag_list.add("Random") 353 | posts(:jonathan_sky).save! 354 | 355 | assert_no_difference 'Tag.count' do 356 | posts(:jonathan_sky).tag_list.remove("Random") 357 | posts(:jonathan_sky).save! 358 | end 359 | end 360 | 361 | def test_tag_destroyed_when_unused 362 | Tag.destroy_unused = true 363 | 364 | posts(:jonathan_sky).tag_list.add("Random") 365 | posts(:jonathan_sky).save! 366 | 367 | assert_difference 'Tag.count', -1 do 368 | posts(:jonathan_sky).tag_list.remove("Random") 369 | posts(:jonathan_sky).save! 370 | end 371 | ensure 372 | Tag.destroy_unused = false 373 | end 374 | end 375 | 376 | class ActsAsTaggableOnSteroidsFormTest < ActiveSupport::TestCase 377 | include ActionView::Helpers::FormHelper 378 | 379 | def test_tag_list_contents 380 | fields_for :post, posts(:jonathan_sky) do |f| 381 | assert_match posts(:jonathan_sky).tag_list.to_s, f.text_field(:tag_list) 382 | end 383 | end 384 | end 385 | --------------------------------------------------------------------------------