diff --git a/admin/app/admin/event_session.rb b/admin/app/admin/event_session.rb new file mode 100644 index 000000000..df540716d --- /dev/null +++ b/admin/app/admin/event_session.rb @@ -0,0 +1,3 @@ +ActiveAdmin.register JamRuby::EventSession, :as => 'Event Session' do + menu :parent => 'Events' +end diff --git a/db/up/events.sql b/db/up/events.sql index 6c0feb664..b0f2d2458 100644 --- a/db/up/events.sql +++ b/db/up/events.sql @@ -1,10 +1,25 @@ CREATE TABLE events ( id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(), slug VARCHAR(512) NOT NULL UNIQUE, - starts_at TIMESTAMP, - ends_at TIMESTAMP, + event_day date, title TEXT, description TEXT, + show_sponser BOOLEAN NOT NULL DEFAULT false, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP +); + +CREATE TABLE event_sessions ( + id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(), + starts_at TIMESTAMP, + ends_at TIMESTAMP, + pinned_state VARCHAR(255), + img_url VARCHAR(1024), + img_width INTEGER, + img_height INTEGER, + event_id VARCHAR(64) REFERENCES events(id) ON DELETE CASCADE, + user_id VARCHAR(64) REFERENCES users(id) ON DELETE SET NULL, + band_id VARCHAR(64) REFERENCES bands(id) ON DELETE SET NULL, created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ); \ No newline at end of file diff --git a/ruby/lib/jam_ruby.rb b/ruby/lib/jam_ruby.rb index 6c65f40d5..0353c58a0 100755 --- a/ruby/lib/jam_ruby.rb +++ b/ruby/lib/jam_ruby.rb @@ -100,6 +100,7 @@ require "jam_ruby/models/crash_dump" require "jam_ruby/models/isp_score_batch" require "jam_ruby/models/promotional" require "jam_ruby/models/event" +require "jam_ruby/models/event_session" require "jam_ruby/models/icecast_admin_authentication" require "jam_ruby/models/icecast_directory" require "jam_ruby/models/icecast_limit" diff --git a/ruby/lib/jam_ruby/models/band.rb b/ruby/lib/jam_ruby/models/band.rb index 3115e8e23..bce468fd9 100644 --- a/ruby/lib/jam_ruby/models/band.rb +++ b/ruby/lib/jam_ruby/models/band.rb @@ -47,6 +47,9 @@ module JamRuby has_many :music_sessions, :class_name => "JamRuby::MusicSession", :foreign_key => "band_id" has_many :music_session_history, :class_name => "JamRuby::MusicSessionHistory", :foreign_key => "band_id", :inverse_of => :band + # events + has_many :event_sessions, :class_name => "JamRuby::EventSession" + include Geokit::ActsAsMappable::Glue unless defined?(acts_as_mappable) acts_as_mappable diff --git a/ruby/lib/jam_ruby/models/event.rb b/ruby/lib/jam_ruby/models/event.rb index 998e1d42d..a5f3e1f02 100644 --- a/ruby/lib/jam_ruby/models/event.rb +++ b/ruby/lib/jam_ruby/models/event.rb @@ -1,11 +1,9 @@ class JamRuby::Event < ActiveRecord::Base - attr_accessible :slug, :starts_at, :ends_at, - :'starts_at(1i)', :'starts_at(2i)', :'starts_at(3i)', :'starts_at(4i)', :'starts_at(5i)', - :'ends_at(1i)', :'ends_at(2i)', :'ends_at(3i)', :'ends_at(4i)', :'ends_at(5i)', - :title, - :description, as: :admin + attr_accessible :slug, :event_day, :title, :description, :show_sponser, as: :admin validates :slug, uniqueness: true, presence: true + validates :show_sponser, :inclusion => {:in => [true, false]} + has_many :event_sessions, class_name: 'JamRuby::EventSession' end diff --git a/ruby/lib/jam_ruby/models/event_session.rb b/ruby/lib/jam_ruby/models/event_session.rb new file mode 100644 index 000000000..21a093c17 --- /dev/null +++ b/ruby/lib/jam_ruby/models/event_session.rb @@ -0,0 +1,29 @@ +class JamRuby::EventSession < ActiveRecord::Base + + attr_accessible :event_id, :user_id, :band_id, :starts_at, :ends_at, :pinned_state, :position, :img_url, :img_width, :img_height, as: :admin + + belongs_to :user, class_name: 'JamRuby::User' + belongs_to :band, class_name: 'JamRuby::Band' + belongs_to :event + + + validates :event, presence: true + validates :pinned_state, :inclusion => {:in => [nil, :not_started, :over]} + validate :one_of_user_band + + before_validation :sanitize_active_admin + + def sanitize_active_admin + puts self.inspect + self.img_url = nil if self.img_url == '' + self.user_id = nil if self.user_id == '' + self.band_id = nil if self.band_id == '' + self.pinned_state = nil if self.pinned_state == '' + end + + def one_of_user_band + if band && user + errors.add(:user, 'specify band, or user. not both') + end + end +end diff --git a/ruby/lib/jam_ruby/models/user.rb b/ruby/lib/jam_ruby/models/user.rb index a619f864a..17e4ed46b 100644 --- a/ruby/lib/jam_ruby/models/user.rb +++ b/ruby/lib/jam_ruby/models/user.rb @@ -94,6 +94,9 @@ module JamRuby # crash dumps has_many :crash_dumps, :foreign_key => "user_id", :class_name => "JamRuby::CrashDump" + # events + has_many :event_sessions, :class_name => "JamRuby::EventSession" + # This causes the authenticate method to be generated (among other stuff) #has_secure_password diff --git a/ruby/spec/factories.rb b/ruby/spec/factories.rb index 24866a617..0db11878c 100644 --- a/ruby/spec/factories.rb +++ b/ruby/spec/factories.rb @@ -420,6 +420,8 @@ FactoryGirl.define do sequence(:slug) { |n| "slug-#{n}" } title 'event title' description 'event description' - end - end + + factory :event_session, :class => JamRuby::EventSession do + end +end diff --git a/ruby/spec/jam_ruby/models/event_session_spec.rb b/ruby/spec/jam_ruby/models/event_session_spec.rb new file mode 100644 index 000000000..947370e86 --- /dev/null +++ b/ruby/spec/jam_ruby/models/event_session_spec.rb @@ -0,0 +1,26 @@ +require 'spec_helper' + +describe EventSession do + + it "should be creatable" do + event = FactoryGirl.create(:event) + event_session = FactoryGirl.create(:event_session, event: event) + end + + it "requires a parent event" do + event_session = FactoryGirl.build(:event_session) + event_session.save.should be_false + event_session.errors[:event].should == ["can't be blank"] + end + + it "can't specify both band and user" do + user = FactoryGirl.create(:user) + band = FactoryGirl.create(:band) + event = FactoryGirl.create(:event) + event_session = FactoryGirl.build(:event_session, event: event, user: user, band:band) + event_session.save.should be_false + event_session.errors[:user].should == ["specify band, or user. not both"] + end + +end + diff --git a/ruby/spec/jam_ruby/models/event_spec.rb b/ruby/spec/jam_ruby/models/event_spec.rb index b888ab7e0..93a8629a2 100644 --- a/ruby/spec/jam_ruby/models/event_spec.rb +++ b/ruby/spec/jam_ruby/models/event_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' describe Event do - before do - end it "should be creatable" do FactoryGirl.create(:event) @@ -15,4 +13,13 @@ describe Event do dup.errors[:slug].should == ["has already been taken"] end + it "can have associated event session, then destroy it by destroying event" do + event = FactoryGirl.create(:event) + event_session = FactoryGirl.create(:event_session, event: event) + event.reload + event.event_sessions.length.should == 1 + event_session.event.should == event + event.destroy + EventSession.find_by_id(event_session.id).should be_nil + end end diff --git a/web/app/assets/images/content/logo_centurylink.png b/web/app/assets/images/content/logo_centurylink.png new file mode 100644 index 000000000..57f2deb03 Binary files /dev/null and b/web/app/assets/images/content/logo_centurylink.png differ diff --git a/web/app/assets/stylesheets/client/jamkazam.css.scss b/web/app/assets/stylesheets/client/jamkazam.css.scss index 1eadb6116..4dfd51558 100644 --- a/web/app/assets/stylesheets/client/jamkazam.css.scss +++ b/web/app/assets/stylesheets/client/jamkazam.css.scss @@ -518,3 +518,10 @@ div[layout-id=session], div[layout-id=ftue], .no-selection-range { margin:0 10px 0 3px; } } + +hr { + background-color: #999999; + border: 0 none; + height: 1px; + margin: 10px 0; +} diff --git a/web/app/controllers/events_controller.rb b/web/app/controllers/events_controller.rb index e5fb01079..71b5288fb 100644 --- a/web/app/controllers/events_controller.rb +++ b/web/app/controllers/events_controller.rb @@ -4,7 +4,7 @@ class EventsController < ApplicationController def show @event = Event.find_by_slug!(params[:slug]) - render :layout => "web" + render 'event', :layout => "web" end end \ No newline at end of file diff --git a/web/app/helpers/avatar_helper.rb b/web/app/helpers/avatar_helper.rb index 13107ca17..ce7a7632b 100644 --- a/web/app/helpers/avatar_helper.rb +++ b/web/app/helpers/avatar_helper.rb @@ -22,11 +22,15 @@ module AvatarHelper end end - def resolve_avatarables(*avatarables) + def resolve_avatarables(*avatarables, allow_none: false) avatarables.each do |avatarable| return resolve_avatarable(avatarable) if avatarable end - raise "at least one avatarable must be specified" + if allow_none + nil + else + raise "at least one avatarable must be specified" + end end end \ No newline at end of file diff --git a/web/app/helpers/event_session_helper.rb b/web/app/helpers/event_session_helper.rb new file mode 100644 index 000000000..89402bd2c --- /dev/null +++ b/web/app/helpers/event_session_helper.rb @@ -0,0 +1,91 @@ +module EventSessionHelper + + def event_session_img(event_session) + + # need to figure out img, width, height + + # prefer the session URL if specified; otherwise use the band/user + url = nil + width = nil + height = nil + + if event_session.img_url + url = image_path(event_session.img_url) + else + url = resolve_avatarables(event_session.band, event_session.user, allow_none: true) + end + + if url + width = event_session.img_width + height = event_session.img_height + else + url = image_path('web/logo-256.png') + width = 115 + end + + content_tag(:img, nil, src: url, width: width, height: height) + end + + def event_session_title(event_session) + return event_session.band.name if event_session.band + return event_session.user.name if event_session.user + 'TBD' + end + + def event_session_start_hour(event_session) + timezone = ActiveSupport::TimeZone.new('Central Time (US & Canada)') + timezone.at(event_session.starts_at.to_i).strftime('%l:%M %P') + end + + def event_session_button(event_session) + + state = nil # can be :not_started, :over, :playing + state = event_session.pinned_state if event_session.pinned_state + if !state && (event_session.user_id || event_session.band_id) + # if no pinned state, then we try to find if there is a session currently on going during the specified time range + # if so, then we are playing. + # if there has been none, we say it's still coming, + # if there has been at least one, and it's over, we say session over + query = MusicSessionHistory.where(created_at: event_session.event.event_day..(event_session.event.event_day + 1.day)) + if event_session.user_id + query = query.where(user_id: event_session.user_id) + elsif event_session.band_id + query = query.where(band_id: event_session.band_id) + else + raise 'invalid state in event_session_button' + end + + music_session_history = query.order('created_at DESC').first + + if music_session_history + if music_session_history.session_removed_at + state = 'over' + else + state = 'playing' + end + else + state = 'not_started' + end + end + + if state == 'over' + content_tag(:a, 'SESSION ENDED', href: music_session_detail_path(music_session_history.id), class: 'button-grey') + elsif state == 'playing' + content_tag(:a, '', href: music_session_detail_path(music_session_history.id), class: 'button-orange') do + image_tag 'content/icon_playbutton.png', :width => 20, height: 20, align: 'absmiddle' + content_tag(:span, 'LISTEN NOW') + end + elsif state == 'not_started' + nil + else + nil + end + + end + + def event_session_description(event_session) + event_session.band.biography if event_session.band + event_session.user.biography if event_session.user + '' + end +end diff --git a/web/app/views/events/_event_session.html.haml b/web/app/views/events/_event_session.html.haml new file mode 100644 index 000000000..3c912dedf --- /dev/null +++ b/web/app/views/events/_event_session.html.haml @@ -0,0 +1,19 @@ +%hr{ class:'w60' } +.landing-band + = event_session_img(event_session) + %br + %br + %span= event_session_title(event_session) + +.landing-details + .left.f20.teal + %strong + = event_session_start_hour(event_session) + .right + = event_session_button(event_session) + %br{ clear:'all' } + %br + .left + = event_session_description(event_session) + %br + %br \ No newline at end of file diff --git a/web/app/views/events/show.html.haml b/web/app/views/events/event.html.haml similarity index 84% rename from web/app/views/events/show.html.haml rename to web/app/views/events/event.html.haml index a6c62ed38..2a2f57655 100644 --- a/web/app/views/events/show.html.haml +++ b/web/app/views/events/event.html.haml @@ -1,14 +1,15 @@ - provide(:title, @event.title) .landing-content - %h1 Virtual Jam Fest 2014 - %p.w60 - = @event.description + %h1= @event.title + %p.w60= @event.description %br %br %h2 ARTIST LINEUP %br + = render :partial => "event_session", :collection => @event.event_sessions + %br{clear:'all'} .landing-sidebar