<repo_name>jcap49/clipit<file_sep>/db/migrate/20130415200037_add_photo_attachment_to_clips_table.rb
class AddPhotoAttachmentToClipsTable < ActiveRecord::Migration
  def self.up
    add_attachment :clips, :photo
  end

  def self.down
    remove_attachment :clips, :photo
  end
end
<file_sep>/spec-week4-14.md
ClipIt Spec - 4/14-4/20

To-do:

-fix menu js errors
-finish clip partial css styling
-create a flash error for false password login attempt


Done (as of 4/21):

Miscellaneous:
-registered for YouTube application API (via google code)
-implemenet user authentication via devise
-wrote home copy
-wrote about copy
-fix delete clip bug
-figure out how to constrain photo size
-fix mailer to send forgot password message
-fix create clip bug with "unless rendering" thing
-refactor clips/show & /examples into a partial
  -error messages
  -error chrome is ugly as hell
  -better formatting for clips/show
  -home:
    -needs formatting
  -about:
    -needs formatting
  -create:
    -"Create photo" button needs to be hidden
-fix footer (change from fixed to absolute and position properly)

Views:
-implement mock ups (use some previous work as well)
  -home
  -create
  -edit/view
-finish implementing clip/example
  -how to extract "random" clips from database
-adjust appropriate views to accomodate music syncing portion
Models:
-create a clip model
  -has title, body, (other attributes)
  -has_many photos

Controllers:
-static pages
  -handles home page (and any other future static pages)
-clip controller
  -handles creation of clip
    -photo upload
    -body (text) of clip submission
-finish implementing user auth
  -fix "your clips page" (css tweaks)
  -check to make sure login/logout scenarios ok
  -test login/logout/recover password
  -think about building an admin page
  -need a 404 error for /clips when not signed in
-implement music syncing feature (see youtube api hack)
  -finish implementing jquery dropdown with api
  -clip controller
      -music sync
        -use iframe api to load player (& hide controls - see docs for more info)
        -use youtube data api to search for youtube videos
        (youtube video id on the backend - which then gets passed to iframe api to load/play video)

<file_sep>/spec/requests/clips_pages_spec.rb
require 'spec_helper'

describe "ClipsPages" do

  subject { page }

  let(:user) { FactoryGirl.create(:user) }
  before { sign_in user }

  describe "clip creation" do
    before { visit new_clip_path }

    describe "with invalid information" do

      it "should not create a clip" do
        expect { click_button "Create" }.not_to change(Clip, :content)
      end

      describe "error messages" do
        before { click_button "Post" }
        it { should have_content('error') }
      end
    end

    describe "with valid information" do

      before { fill_in 'clip_content', with: "lorem ipsum" }
      it "should create a clip" do
        expect { click_button "Post" }.to change(Clip, :count).by(1)
      end
    end
  end

  describe "micropost destruction" do
    before { FactoryGirl.create(:clip, user: user) }

    describe "as correct user" do
      before { visit clips_path }

      it "should delete a micropost" do
        expect { click_link "delete" }.to change(Clip, :count).by(-1)
      end
    end
  end
end
<file_sep>/spec/models/clip_spec.rb
require 'spec helper'

describe clip do

  let(:user) { FactoryGirl.create(:user) }
  before { @clip = user.clips.build(content: "Lorem ipsum") }

  subject { @clip }

  it { should respond_to(:user_id) }
  it { should respond_to(:user) }
  it { should respond_to(:unique_url) }
  it { should respond_to(:slug) }
  it { should respond_to(:photo) }
  it { should respond_to(:body) }
  it { should respond_to(:user_id) }r
  it { should respond_to(:song) }
  its(:user) { should == user }

  it { should be_valid }

  describe "accessible attributes" do
    it "should not allow access to user_id" do
      expect do
        Clip.new(user_id: user.id)
      end.to raise_error(ActiveModel::MassAssignmentSecurity::Error)
    end
  end

  describe "when user_id is not present" do
    before { @clip.user_id = nil }
    it { should_not be_valid }
  end

  describe "with blank content" do
    before { @clip.content = " " }
    it { should_not be_valid }
  end

  describe "with content that is too long" do
    before { @clip.content = "a" * 141 }
    it { should_not be_valid }
  end
end
<file_sep>/spec/requests/static_pages_spec.rb
require 'spec_helper'

describe "Static pages" do

  let(:base_title) {"Clip.It - the easiest way to share the soundtrack of your memories"}

  subject { page }

  describe "Home page" do
    before { visit root_path }

    it_should_behave_like "all static pages"
    it { should have_selector 'title' }
  end

  describe "Why page" do
    before { visit why_path }

    it_should_behave_like "all static pages"
    it { should have_selector 'title' }
  end

  describe "Examples" do
    before { visit example_path }

    it_should_behave_like "all static pages"
    it { should have_selector 'title'}
  end
end


<file_sep>/app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  protect_from_forgery

  helper_method :yt_client

  private

  def yt_client
    @yt_client ||= YouTubeIt::Client.new(:dev_key => "<KEY>")
  end
end
<file_sep>/app/models/admin.rb
class Admin < ActiveRecord::Base
  devise :database_authenticatable, :rememberable
  attr_accessible :email, :password, :password_confirmation, :god_mode, :reports_only
end
<file_sep>/app/models/clip.rb
class Clip < ActiveRecord::Base
  extend FriendlyId
  friendly_id :title , :use => :slugged

  belongs_to :user


  # Attrs
  attr_accessible :user_id, :title, :body, :photo, :slug, :unique_url, :song, :song_id
  has_attached_file :photo, :styles => {
    :small => "160x160>",
    :large => "525x525>"}

  # Validations
  validates :title, presence: true, length: {maximum: 250}
  validates :body, presence: true, length: {maximum: 1000}

  #TO-DO: add presence validator back to photo before pushing live

  validates :slug, presence: true
  validates :song, presence: true

  # TO-DO: add a song attr & migration
end
<file_sep>/db/migrate/20130415185243_add_body_to_clips_table.rb
class AddBodyToClipsTable < ActiveRecord::Migration
  def change
    add_column :clips, :body, :string
  end
end
<file_sep>/app/controllers/clips_controller.rb
class ClipsController < ApplicationController
  before_filter :authenticate_user!, only: [:edit, :index, :destroy]

  def index
   @clips = current_user.clips
   @users = User.all
  end

  def show
    @clip = Clip.find(params[:id])
    @video = yt_client.videos_by(:query => @clip.song, :max_results => "1", :format => "5", :autoplay => "1", :controls => "2")

    @html_for_video = @video.videos
    @e_video = @html_for_video.collect {|video| video.embed_html5(:url_params => {:autoplay => "1"})}

    respond_to do |format|
      format.html
      format.json { render json: @clip }
    end
  end

  def new
    @clip = Clip.new

    respond_to do |format|
      format.html
      format.json { render json: @clip }
    end
  end

  def edit
    @clip = Clip.find(params[:id])
  end

  def create
    if user_signed_in?
      @clip = current_user.clips.build(params[:clip])
      if @clip.save
        redirect_to @clip, notice: 'Clip was successfully created.'
      else
        render new_clip_path
      end
    else
      @clip = Clip.new(params[:clip])
      if @clip.save
        redirect_to @clip, notice: 'Clip was successfully created.'
      else
        render new_clip_path
      end
    end
  end

  def update
    @clip = Clip.find(params[:id])

    respond_to do |format|
      if @clip.update_attributes(params[:clip])
        format.html { redirect_to @clip, notice: 'Clip was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: "edit" }
        format.json { render json: @clip.errors, status: :unprocessable_entity }
      end
    end
  end

  def destroy
    @clip = Clip.find(params[:id])
    @clip.destroy

    respond_to do |format|
      format.html { redirect_to clips_url }
      format.json { head :no_content }
    end
  end

  def example
    @clip = Clip.limit(1).offset(rand(Clip.count)).first
    @video = yt_client.videos_by(:query => @clip.song, :max_results => "1", :format => "5", :autoplay => "1")

    @html_for_video = @video.videos
    @e_video = @html_for_video.collect {|video| video.embed_html5(:url_params => {:autoplay => "1"})}
  end

  def video_results
    @videos = yt_client.videos_by(:query => params[:term], :max_results => "1", :format => "5")
    display_video_results
  end

  #TO-DO add save feature for song
  #implement appropriate embed view for clips/show
  def display_video_results
   @results = @videos.videos
   @results.collect! {|video| video.title}
   render :json => @results
  end
end
<file_sep>/config/routes.rb
ClipIt::Application.routes.draw do
  devise_for :users

  resources :clips, only: [:new, :create, :show, :edit, :index, :destroy, :update] do
    collection do
      get :video_results
    end
  end

  match '/admins/dashboard', to: 'admins#dashboard'
  match '/example',   to: 'clips#example'
  match '/why',       to: 'static_pages#why'
  root                to: 'static_pages#home'
end
<file_sep>/app/controllers/static_pages_controller.rb
class StaticPagesController < ApplicationController
  def home
    @clip = Clip.limit(1).offset(rand(Clip.count)).first
    @video = yt_client.videos_by(:query => @clip.song, :max_results => "1", :format => "5", :autoplay => "1")

    @html_for_video = @video.videos
    @e_video = @html_for_video.collect {|video| video.embed_html5(:url_params => {:autoplay => "1"})}
  end

  def why
  end
end
<file_sep>/Gemfile
source 'https://rubygems.org'

gem 'rails', '3.2.12'
gem 'pg'
gem 'paperclip', '3.4.1'
gem 'friendly_id', "~> 4.0.9"
gem 'youtube_it'
gem 'devise'
gem 'cocaine', '0.5.1'
gem "zurb-foundation"
gem "compass"
gem 'aws-sdk'

group :assets do
  gem 'sass-rails',   '~> 3.2.3'
  gem 'coffee-rails', '~> 3.2.1'

  gem 'uglifier', '>= 1.0.3'
end

group :development, :test do
  gem 'rspec-rails', '2.11.0'
end

group :test do
  gem 'capybara', '1.1.2'
  gem 'factory_girl_rails', '4.1.0'
  gem 'cucumber-rails', '1.2.1', :require => false
  gem 'database_cleaner', '0.7.0'
end

gem 'jquery-rails'

<file_sep>/config/initializers/load_youtube_it.rb
require 'ostruct'
raw_config = File.read(::Rails.root.to_s + "/config/youtube_it.yml")
YouTubeItConfig =  OpenStruct.new(YAML.load(raw_config)[Rails.env])
<file_sep>/app/controllers/admins_controller.rb
class AdminsController < ApplicationController
  include Devise::Controllers::Helpers

  def dashboard
    @users = User.all
    @clips = Clip.all
  end

end
