bbclistenlive/ 0000755 0000765 0000024 00000000000 11116730711 013034 5 ustar duncan staff bbclistenlive/app/ 0000755 0000765 0000024 00000000000 11116730711 013614 5 ustar duncan staff bbclistenlive/app/controllers/ 0000755 0000765 0000024 00000000000 11116730711 016162 5 ustar duncan staff bbclistenlive/app/controllers/application.rb 0000644 0000765 0000024 00000001450 11116730711 021012 0 ustar duncan staff # Filters added to this controller apply to all controllers in the application.
# Likewise, all the methods added will be available for all controllers.
class ApplicationController < ActionController::Base
session :off
# Pick a unique cookie name to distinguish our session data from others'
session :session_key => '_bbclistenlive_session_id'
# session that won't expire = JWSURY
# session key non-expired c853ed48673297269bf4d131-522101041
def finish_facebook_login
redirect_to :controller => "prefs"
end
private
def check_for_http_post
return five_hundred_page unless request.post?
end
def five_hundred_page
render(:nothing => true, :status => 500)
end
def fb_redirect(url)
%()
end
end
bbclistenlive/app/controllers/help_controller.rb 0000644 0000765 0000024 00000000242 11116730711 021700 0 ustar duncan staff class HelpController < ApplicationController
before_filter :check_for_http_post
caches_page :index, :ie, :ff, :camino, :safari, :popups
layout "canvas"
end
bbclistenlive/app/controllers/networks_controller.rb 0000644 0000765 0000024 00000000474 11116730711 022633 0 ustar duncan staff class NetworksController < ApplicationController
before_filter :require_facebook_login, :check_for_http_post, :handle_friends
helper :radio
layout "canvas"
private
def handle_friends
if params[:id] == "friends"
@uids = Fb.friends_get(fbsession)
else
@uids = nil
end
end
end
bbclistenlive/app/controllers/prefs_controller.rb 0000644 0000765 0000024 00000003125 11116730711 022072 0 ustar duncan staff class PrefsController < ApplicationController
before_filter :require_facebook_login
before_filter :fetch_all_networks, :except => [:profile]
before_filter :check_for_http_post
layout "canvas", :except => [ :profile ]
def index
@user = Fb.get_user_data(fbsession, params[:fb_page_id])
end
def success
@user = Fb.get_user_data(fbsession, params[:fb_page_id])
render :template => 'prefs/index'
end
def update
fb_page_id = params[:fb_page_id]
user = Fb.get_user_data(fbsession, fb_page_id)
user.update_attributes(params[:user])
changes = user.update_preferences(params[:networks])
@user = User.find(user)
@markup = fetch_profile_partial_as_string
Fb.set_fbml_using(fbsession, @markup, user)
if !changes.nil? and !fb_page_id
Fb.set_publish_action_of_user_using(fbsession, changes, @user)
end
fb_page_id = "?fb_page_id=#{fb_page_id}" unless fb_page_id.blank?
render :text => fb_redirect("prefs/success#{fb_page_id}")
end
def invite
@user = User.find_by_fbid(Fb.user_id(fbsession))
friends_without_app = Fb.get_friends_without_app(fbsession)
@friends_list = friends_without_app.join(',')
@invite_code = render_to_string(:template => "prefs/invite_email", :layout => false)
end
def profile
@user = Fb.get_user_data(fbsession, params[:fb_page_id])
end
private
def fetch_all_networks
@networks = Network.find(:all,
:conditions => "active = 1",
:order => "position ASC, name ASC")
end
def fetch_profile_partial_as_string
render_to_string(:partial => "shared/profile")
end
end
bbclistenlive/app/controllers/radio_controller.rb 0000644 0000765 0000024 00000002304 11116730711 022047 0 ustar duncan staff class RadioController < ApplicationController
before_filter :require_facebook_login, :except => [:play]
before_filter :check_for_http_post
layout "canvas"
def mine
@user = Fb.get_user_data(fbsession)
end
def friends
friends = Fb.friends_get(fbsession)
render_stats_page(friends)
end
def everyones
render_stats_page
end
def play
u = params[:u] ||= Fb.user_id(fbsession)
@user = User.find_by_fbid(u)
@network = Network.find(params[:n])
if @user and @user.update_clicks( @network )
link = @network.link_to_audio(@user, params[:f])
redirect_to( link ) if link
else
render :text => "Problem found. Please re-save your settings!"
end
end
private
def render_stats_page(uids = nil)
@user_rankings = Preference.plays_ranking(:users => uids)
@recent_listening = Preference.recent_listening(:users => uids)
@pop_national = Network.popular(:users => uids, :national => true)
@pop_local = Network.popular(:users => uids)
@fav_national = Network.favourite(:users => uids, :national => true)
@fav_local = Network.favourite(:users => uids)
render :template => "radio/stats"
end
end
bbclistenlive/app/helpers/ 0000755 0000765 0000024 00000000000 11116730711 015256 5 ustar duncan staff bbclistenlive/app/helpers/application_helper.rb 0000644 0000765 0000024 00000003057 11116730711 021452 0 ustar duncan staff # Methods added to this helper will be available to all templates in the application.
module ApplicationHelper
def tab_active(str)
'selected="true"' if params[:action] == str
end
def profile_link(user)
content_tag('span', %(), :class => 'heading')
end
def link_to_fb_user(user)
referral_link = CGI::escape("#{FBOOK_APP_URL}?refuid=#{user.fbid}")
"http://www.facebook.com/add.php?api_key=#{APP_APIKEY}&next=#{referral_link}"
end
def media_link(network, user, format = nil)
result = []
result << "#{File.join(FBOOK_APP_URL,'radio/play')}?n=#{network.id}"
result << "u=#{user.fbid}" if user.is_page
result << "f=#{format}" if format
return result.join('&')
end
def link_to_bbc_radio_site(network)
link_to(network.name, File.join(BBC, network.url))
end
def display_pop_up_link(user, network)
link_to(image_tag(network.path_to_media_image(user), :size => "32x31", :border => 0),
media_link(network, user), :target => "_blank")
end
def image_power_up(user)
score = Integer(user.total_plays)
if score >= 50 && score < 100
power = "score_50"
elsif score >= 100 && score < 200
power = "score_100"
elsif score >= 200 && score < 500
power = "score_200"
elsif score >= 500 && score < 1000
power = "score_500"
else
return nil
end
image_tag("powers/#{power}.png",
:class => "#{power}", :title => pluralize(score, 'listens'))
end
def display_power_bar(user)
end
end
bbclistenlive/app/helpers/help_helper.rb 0000644 0000765 0000024 00000000026 11116730711 020070 0 ustar duncan staff module HelpHelper
end
bbclistenlive/app/helpers/networks_helper.rb 0000644 0000765 0000024 00000000032 11116730711 021011 0 ustar duncan staff module NetworksHelper
end
bbclistenlive/app/helpers/prefs_helper.rb 0000644 0000765 0000024 00000000212 11116730711 020254 0 ustar duncan staff module PrefsHelper
def fetch_logo(network)
image_tag(network.icon_path, :size => "16x16", :border => 0, :class => "icon")
end
end
bbclistenlive/app/helpers/radio_helper.rb 0000644 0000765 0000024 00000001445 11116730711 020244 0 ustar duncan staff module RadioHelper
def plays_today
p = Preference.plays_today
content_tag('span', pluralize(p, 'person') + ' today')
end
def network_listened_last_by(preference)
return if preference.last_played.nil?
radio_link = link_to_bbc_radio_site(preference.network)
last_listened = distance_of_time_in_words_to_now(preference.last_played)
content_tag('span', "#{radio_link} .. #{last_listened} ago", :class => "last_listened")
end
def display_welcome(params)
x = params[:action] == "everyones" ? "all facebook users" : "your friends"
"What are #{x} listening to..."
end
def show_media_links(network, user)
formats = network.formats
render :partial => 'shared/media', :locals => {
:network => network, :formats => formats, :user => user }
end
end
bbclistenlive/app/models/ 0000755 0000765 0000024 00000000000 11116730711 015077 5 ustar duncan staff bbclistenlive/app/models/fb.rb 0000644 0000765 0000024 00000004476 11116730711 016026 0 ustar duncan staff require 'parsedate'
class Fb
def self.user_id(fb)
fb.session_user_id unless fb.blank?
end
def self.get_fql_query(fb, query)
fb.fql_query( :query => query )
end
def self.friends_get(fb)
fb.friends_get.uid_list
end
def self.is_page_admin?(fb, page)
result = fb.pages_isAdmin( :page_id => page )
result.at("pages_isAdmin_response").inner_html.to_i
end
def self.is_page_app_added?(fb, page)
result = fb.pages_isAppAdded( :page_id => page )
result.at("pages_isAppAdded_response").inner_html.to_i
end
def self.get_friends_without_app(fb)
user = user_id(fb)
q = <<-QUERY
SELECT uid FROM user
WHERE has_added_app=1 and uid IN
(SELECT uid2 FROM friend WHERE uid1 = #{user})
QUERY
res = get_fql_query(fb, q)
users = res.search("//uid").map{|xmlnode| xmlnode.inner_html}
users
end
def self.get_user_data(fbsession, page_id = nil)
raise if fbsession.blank?
fbid = user_id(fbsession)
# this must be a page
if !page_id.nil? && is_page_admin?( fbsession, page_id )
user = User.find_or_initialize_by_fbid( page_id )
if user.new_record?
user.is_page = 1
user.save!
end
# this must be a user
else
user = User.find_or_initialize_by_fbid( fbid )
end
user.stream_type = "bbc" if user.stream_type.blank?
user
end
def self.set_fbml_using(fb, markup, user)
fb.profile_setFbml( :uid => [user.fbid], :markup => markup )
end
def self.set_publish_action_of_user_using(fb, changes, user)
return if user.is_page
if body = build_change_list(changes)
title = %( has updated settings)
publish_data_to_feed(fb, title, body)
end
end
private
def self.build_change_list(changes)
return unless changes[:new].kind_of?(Array)
return unless changes[:old].kind_of?(Array)
result = []
added = changes[:new].collect {|n| "#{n}"}.join(', ')
remov = changes[:old].collect {|o| "#{o}"}.join(', ')
result << "Adding " + added unless added.blank?
result << "Removing " + remov unless remov.blank?
result.join(' and ')
end
def self.publish_data_to_feed(fb, title, body)
fb.feed_publishActionOfUser( :title => title, :body => body )
end
end
bbclistenlive/app/models/network.rb 0000644 0000765 0000024 00000006053 11116730711 017121 0 ustar duncan staff class Network < ActiveRecord::Base
has_many :preferences, :dependent => :destroy
has_many :users, :through => :preferences
def formats
formats = {}
formats[:bbc] = bbc unless bbc.blank?
formats[:ram] = ram unless ram.blank?
formats[:asx] = asx unless asx.blank?
formats
end
def total_plays
Preference.sum('clicks', :conditions => ["network_id = ?", id])
end
def total_users
Preference.count("network_id", :conditions => "network_id = #{id}")
end
def current_start_finish
display_start_finish(current_start, current_duration)
end
def next_start_finish
display_start_finish(next_start, next_duration)
end
def tagline
read_attribute("tagline") || "No show information currently available"
end
def logo_path
fs_path = File.join(RAILS_ROOT,"public/images/networks/#{base_name}.png")
ht_path = "networks/#{base_name}.png"
return ht_path if File.exists?(fs_path)
return "networks/localradio.png"
end
def icon_path
fs_path = File.join(RAILS_ROOT,"public/images/icons/#{base_name}.png")
ht_path = "icons/#{base_name}.png"
return ht_path if File.exists?(fs_path)
return "icons/bbc.png"
end
def link_to_website
File.join(BBC, url)
end
def link_to_audio(user, format = nil)
format = format ? format : user.stream_type
return asx if format == "asx" && !asx.blank?
return ram if format == "ram" && !ram.blank?
return bbc
end
def path_to_media_image(user)
format = user.stream_type
return "buttons/asx.png?1" if format == "asx" && !asx.blank?
return "buttons/ram.png?1" if format == "ram" && !ram.blank?
return "buttons/bbc.png?1"
end
def self.favourite(opts={})
limit = opts.delete(:limit) || 5
users = opts.delete(:users) || nil
national = opts.delete(:national) || false
cond = users ? ["u.fbid IN (?) AND n.is_national = ? AND n.active = 1", users, national] : ["n.is_national = ?", national]
Preference.find(:all,
:select => "p.*, COUNT(p.network_id) AS t_users",
:conditions => cond,
:joins => "p INNER JOIN users u ON u.id=p.user_id " \
"INNER JOIN networks n ON n.id=p.network_id",
:order => "t_users DESC", :group => "p.network_id", :limit => limit)
end
def self.popular(opts={})
limit = opts.delete(:limit) || 5
users = opts.delete(:users) || nil
national = opts.delete(:national) || false
cond = users ? ["u.fbid IN (?) AND n.is_national = ? AND n.active = 1", users, national] : ["n.is_national = ?", national]
Preference.find(:all,
:select => "p.*, SUM(p.clicks) AS t_plays",
:conditions => cond,
:joins => "p INNER JOIN users u ON u.id=p.user_id " \
"INNER JOIN networks n ON n.id=p.network_id",
:order => "t_plays DESC", :group => "p.network_id", :limit => limit)
end
private
def display_start_finish(start, duration)
return if start.blank?
s = start.getlocal
f = s + duration
"#{s.to_formatted_s(:hh_mm)}-#{f.to_formatted_s(:hh_mm)}"
end
end
bbclistenlive/app/models/play.rb 0000644 0000765 0000024 00000000115 11116730711 016366 0 ustar duncan staff class Play < ActiveRecord::Base
belongs_to :user
belongs_to :network
end
bbclistenlive/app/models/preference.rb 0000644 0000765 0000024 00000002416 11116730711 017545 0 ustar duncan staff class Preference < ActiveRecord::Base
belongs_to :user
belongs_to :network
validates_uniqueness_of :network_id, :scope => :user_id
def self.recent_listening(opts={})
common = "clicks > 0"
users = opts.delete(:users)
cond = users ? ["#{common} AND users.fbid IN (?)", users] : common
limit = opts.delete(:limit) || 5
find(:all, :conditions => cond, :order => "preferences.last_played DESC",
:joins => "INNER JOIN users ON users.id=preferences.user_id", :limit => limit)
end
def self.plays_ranking(opts={})
common = "users.total_plays > 0"
users = opts.delete(:users)
cond = users ? ["#{common} AND users.fbid IN (?)", users] : common
limit = opts.delete(:limit) || 5
users = User.find(:all, :include => :preferences, :conditions => cond,
:order => "users.total_plays DESC", :limit => limit)
users.collect! {|u| u.preferences.find(:first, :order => "preferences.last_played DESC") }.compact
end
def self.plays_today
count(:conditions => "DATE(last_played) = CURDATE()")
end
def self.plays_yesterday
count(:conditions => "DATE(last_played) = ADDDATE(CURDATE(), INTERVAL -1 DAY)")
end
def played_in_the_last_5_mins?
last_played >= (Time.now - 5.minutes) unless last_played.nil?
end
end
bbclistenlive/app/models/user.rb 0000644 0000765 0000024 00000003433 11116730711 016405 0 ustar duncan staff class User < ActiveRecord::Base
has_many :preferences, :dependent => :destroy
has_many :networks, :through => :preferences, :order => "is_national DESC"
validates_uniqueness_of :fbid
def likes_bbc?
stream_type == "bbc"
end
def likes_real?
stream_type == "ram"
end
def likes_windows?
stream_type == "asx"
end
def first_time?
preferences.empty?
end
def update_clicks(network)
return unless pref = preferences.find_by_network_id(network)
unless pref.played_in_the_last_5_mins?
transaction do
t = Time.now
self.update_attributes(:total_plays => self.total_plays + 1)
pref.update_attributes(
:clicks => pref.clicks + 1,
:last_played => t.utc )
# log the play
Play.create!(:user => self, :network => network, :fbid => fbid)
end
end
pref
end
def update_preferences(new_networks)
old_preferences = preferences.dup
old_network_ids = networks.collect {|n| n.id}
new_network_ids = return_the_ids_from_hash(new_networks)
new_networks = new_network_ids - old_network_ids
old_networks = old_network_ids - new_network_ids
return nil if (new_networks + old_networks).empty?
transaction do
preferences.delete(preferences)
new_network_ids.each do |network|
clicks = 0
network = Network.find(network)
old_preferences.each {|p| clicks = p.clicks if p.network == network}
preferences.create!(:network => network, :clicks => clicks)
end
end
{ :new => Network.find(new_networks).map {|n| n.name},
:old => Network.find(old_networks).map {|n| n.name} }
end
private
def return_the_ids_from_hash(hash)
hash.blank? ? [] : hash.reject {|k,v| v == "0"}.keys.map{ |e| Integer(e) }
end
end
bbclistenlive/app/views/ 0000755 0000765 0000024 00000000000 11116730711 014751 5 ustar duncan staff bbclistenlive/app/views/css/ 0000755 0000765 0000024 00000000000 11116730711 015541 5 ustar duncan staff bbclistenlive/app/views/css/_global.html.erb 0000644 0000765 0000024 00000001657 11116730711 020606 0 ustar duncan staff .main {
font-family: "lucida grande", tahoma, verdana, arial, sans_serif;
}
.main, .main p, .main h3, .main fieldset, .main h2, .main h4, .main ul, .main ol, .main legend {
padding:0;
margin:0;
}
.main {
padding:0 10px 10px 10px;
}
.main p {
margin-bottom: 15px;
font-size:12px;
color:#444;
}
.main p.tagline {
color:#999;
}
.main p.intro {
margin-bottom: 15px;
font-size:12px;
color:#333;
}
.main p.intro span {
color:#666;
font-size:11px;
}
.main fieldset {
border:none;
}
.main ul li {
list-style:none;
}
.main ul.networks li {
display:block;
margin-bottom:20px;
}
.main div.tabs {
margin-bottom:15px;
}
.main img {
border: none;
}
h1.explanation_note {
border:1px solid #e2c822;
background-color:#fff9d7;
}
.main label {
color:#333;
}
.main hr {
margin-bottom:15px;
}
.main .share_and_hide {
float:right;
}
.main img.user_image {
float:left;
}
.main p.user_meta {
padding: 0 0 0 5px;
margin-left: 20px;
} bbclistenlive/app/views/css/_help.html.erb 0000644 0000765 0000024 00000000423 11116730711 020264 0 ustar duncan staff