2012-10-01 21:27:32 +00:00
module JamRuby
class Band < ActiveRecord :: Base
2014-08-19 01:41:44 +00:00
include HtmlSanitize
html_sanitize strict : [ :biography , :website , :name ]
2012-10-01 21:27:32 +00:00
2013-12-16 03:53:16 +00:00
attr_accessible :name , :website , :biography , :city , :state ,
2014-02-06 16:31:52 +00:00
:country , :original_fpfile_photo , :cropped_fpfile_photo , :cropped_large_fpfile_photo ,
:cropped_s3_path_photo , :cropped_large_s3_path_photo , :crop_selection_photo , :photo_url , :large_photo_url
2012-11-03 19:32:27 +00:00
2014-02-19 22:56:13 +00:00
attr_accessor :updating_photo , :skip_location_validation
2013-12-15 21:27:11 +00:00
2012-10-28 02:35:28 +00:00
self . primary_key = 'id'
2012-10-01 21:27:32 +00:00
2013-12-16 03:53:16 +00:00
before_save :stringify_photo_info , :if = > :updating_photo
2014-04-20 18:16:37 +00:00
validates :biography , no_profanity : true , presence : true , length : { maximum : 4000 }
2014-08-19 01:41:44 +00:00
validates :name , presence : true , no_profanity : true
2014-02-19 22:56:13 +00:00
validates :country , presence : true , :unless = > :skip_location_validation
validates :state , presence : true , :unless = > :skip_location_validation
validates :city , presence : true , :unless = > :skip_location_validation
2013-12-16 03:53:16 +00:00
validate :validate_photo_info
2014-02-19 22:56:13 +00:00
validate :require_at_least_one_genre
validate :limit_max_genres
2013-07-26 08:07:24 +00:00
2013-12-09 13:15:59 +00:00
before_save :check_lat_lng
2014-01-12 08:49:57 +00:00
before_save :check_website_url
2013-12-09 13:15:59 +00:00
2012-10-30 05:42:16 +00:00
# musicians
2014-12-03 02:42:26 +00:00
has_many :band_musicians , :class_name = > " JamRuby::BandMusician " , dependent : :destroy
2012-10-30 05:42:16 +00:00
has_many :users , :through = > :band_musicians , :class_name = > " JamRuby::User "
# genres
2014-12-05 07:50:03 +00:00
has_many :genre_players , as : :player , class_name : " JamRuby::GenrePlayer " , dependent : :destroy
has_many :genres , through : :genre_players , class_name : " JamRuby::Genre "
2012-10-01 21:27:32 +00:00
2012-11-16 02:08:37 +00:00
# recordings
2014-12-03 02:42:26 +00:00
has_many :recordings , :class_name = > " JamRuby::Recording " , :foreign_key = > " band_id " , dependent : :destroy
2012-12-04 03:39:57 +00:00
2014-02-15 23:23:00 +00:00
# self.id = likable_id in likes table
2014-12-03 02:42:26 +00:00
has_many :likers , :as = > :likable , :class_name = > " JamRuby::Like " , :dependent = > :destroy , dependent : :destroy
2014-02-15 23:23:00 +00:00
# self.id = followable_id in follows table
2014-12-03 02:42:26 +00:00
has_many :followers , :as = > :followable , :class_name = > " JamRuby::Follow " , :dependent = > :destroy , dependent : :destroy
2012-12-04 03:39:57 +00:00
# invitations
2014-12-03 02:42:26 +00:00
has_many :invitations , :inverse_of = > :band , :class_name = > " JamRuby::BandInvitation " , :foreign_key = > " band_id " , dependent : :destroy
2012-11-04 22:54:53 +00:00
2012-11-30 15:23:43 +00:00
# music_sessions
2014-12-03 02:42:26 +00:00
has_many :music_sessions , :class_name = > " JamRuby::MusicSession " , foreign_key : :band_id , :inverse_of = > :band , dependent : :destroy
2012-11-30 15:23:43 +00:00
2014-03-10 06:31:20 +00:00
# events
2014-12-03 02:42:26 +00:00
has_many :event_sessions , :class_name = > " JamRuby::EventSession " , dependent : :destroy
2014-03-10 06:31:20 +00:00
2013-12-09 17:41:35 +00:00
include Geokit :: ActsAsMappable :: Glue unless defined? ( acts_as_mappable )
acts_as_mappable
2012-12-04 03:39:57 +00:00
def liker_count
2014-05-06 21:17:26 +00:00
self . likers . size
2012-10-29 10:45:47 +00:00
end
2012-12-04 03:39:57 +00:00
def follower_count
2014-05-06 21:17:26 +00:00
self . followers . size
2012-10-29 10:45:47 +00:00
end
2012-12-04 03:39:57 +00:00
def recording_count
2014-05-06 21:17:26 +00:00
self . recordings . size
2012-12-04 03:39:57 +00:00
end
2012-11-24 18:22:44 +00:00
2012-12-04 03:39:57 +00:00
def session_count
2014-05-06 21:17:26 +00:00
self . music_sessions . size
2012-11-06 04:47:50 +00:00
end
2014-09-22 19:20:58 +00:00
def latitude
lat
end
def longitude
lng
end
2014-12-08 02:35:30 +00:00
def recent_history ( session_id , claimed_recording_id )
2014-12-06 14:34:30 +00:00
2014-12-08 02:35:30 +00:00
recording_exclusion = " claimed_recordings.id != ' #{ claimed_recording_id } ' " if claimed_recording_id
2014-09-12 01:52:26 +00:00
recordings = Recording
. joins ( :claimed_recordings )
. where ( :band_id = > self . id )
2014-12-06 14:34:30 +00:00
. where ( 'claimed_recordings.is_public=true' )
. where ( recording_exclusion )
2014-01-26 21:46:41 +00:00
. order ( 'created_at DESC' )
. limit ( 10 )
2014-12-06 14:34:30 +00:00
session_exclusion = " music_sessions.id != ' #{ session_id } ' " if session_id
msh = MusicSession
. where ( :band_id = > self . id )
. where ( :fan_access = > true )
. where ( session_exclusion )
2014-01-26 21:46:41 +00:00
. order ( 'created_at DESC' )
. limit ( 10 )
2014-01-21 06:45:51 +00:00
recordings . concat ( msh )
recordings . sort! { | a , b | b . created_at < = > a . created_at } . first ( 5 )
end
2012-11-07 13:10:41 +00:00
def location
2013-04-28 19:06:17 +00:00
loc = self . city . blank? ? '' : self . city
loc = loc . blank? ? self . state : " #{ loc } , #{ self . state } " unless self . state . blank?
#loc = loc.blank? ? self.country : "#{loc}, #{self.country}" unless self.country.blank?
loc
2012-11-07 13:10:41 +00:00
end
2012-11-25 19:37:54 +00:00
2013-12-16 03:53:16 +00:00
def validate_photo_info
if updating_photo
# we want to mak sure that original_fpfile and cropped_fpfile seems like real fpfile info objects (i.e, json objects from filepicker.io)
errors . add ( :original_fpfile_photo , ValidationMessages :: INVALID_FPFILE ) if self . original_fpfile_photo . nil? || self . original_fpfile_photo [ " key " ] . nil? || self . original_fpfile_photo [ " url " ] . nil?
errors . add ( :cropped_fpfile_photo , ValidationMessages :: INVALID_FPFILE ) if self . cropped_fpfile_photo . nil? || self . cropped_fpfile_photo [ " key " ] . nil? || self . cropped_fpfile_photo [ " url " ] . nil?
2014-02-06 16:31:52 +00:00
errors . add ( :cropped_large_fpfile_photo , ValidationMessages :: INVALID_FPFILE ) if self . cropped_large_fpfile_photo . nil? || self . cropped_large_fpfile_photo [ " key " ] . nil? || self . cropped_large_fpfile_photo [ " url " ] . nil?
2013-12-16 03:53:16 +00:00
end
end
2012-11-25 19:37:54 +00:00
def add_member ( user_id , admin )
BandMusician . create ( :band_id = > self . id , :user_id = > user_id , :admin = > admin )
end
2012-12-17 07:02:20 +00:00
2013-11-02 13:59:04 +00:00
def self . musician_index ( band_id )
2014-12-03 02:42:26 +00:00
@musicians = User
. select ( " users.*, bands_musicians.admin AS band_admin " )
. joins ( :band_musicians )
. where ( :bands_musicians = > { :band_id = > " #{ band_id } " } )
2013-11-02 13:59:04 +00:00
end
2013-12-01 06:11:23 +00:00
def self . pending_musicians ( band_id )
2014-12-03 02:42:26 +00:00
@musicians = User
. select ( " users.*, band_invitations.id AS invitation_id " )
. joins ( :received_band_invitations )
2013-12-01 06:11:23 +00:00
. where ( :band_invitations = > { :band_id = > " #{ band_id } " } )
. where ( :band_invitations = > { :accepted = > nil } )
end
2012-12-17 07:02:20 +00:00
def self . recording_index ( current_user , band_id )
hide_private = false
band = Band . find ( band_id )
# hide private Recordings from anyone who's not in the Band
unless band . users . exists? current_user
hide_private = true
end
if hide_private
recordings = Recording . joins ( :band_recordings )
2013-12-16 18:47:59 +00:00
. where ( :bands_recordings = > { :band_id = > " #{ band_id } " } , :public = > true )
2012-12-17 07:02:20 +00:00
else
recordings = Recording . joins ( :band_recordings )
2013-12-16 18:47:59 +00:00
. where ( :bands_recordings = > { :band_id = > " #{ band_id } " } )
2012-12-17 07:02:20 +00:00
end
return recordings
end
2013-01-14 04:50:38 +00:00
2014-02-19 22:56:13 +00:00
def self . build_band ( user , params )
2012-11-25 19:37:54 +00:00
2014-02-19 22:56:13 +00:00
id = params [ :id ]
2012-11-28 05:26:53 +00:00
2014-02-19 22:56:13 +00:00
# ensure person creating this Band is a Musician
unless user . musician?
raise PermissionError , " must be a musician "
2012-11-03 19:32:27 +00:00
end
2014-02-19 22:56:13 +00:00
band = id . blank? ? Band . new : Band . find ( id )
2012-11-03 19:32:27 +00:00
2014-02-19 22:56:13 +00:00
# ensure user updating Band details is a Band member
unless band . new_record? || band . users . exists? ( user )
raise PermissionError , ValidationMessages :: USER_NOT_BAND_MEMBER_VALIDATION_ERROR
end
2012-11-06 02:55:08 +00:00
2014-02-19 22:56:13 +00:00
band . name = params [ :name ] if params . has_key? ( :name )
band . website = params [ :website ] if params . has_key? ( :website )
band . biography = params [ :biography ] if params . has_key? ( :biography )
band . city = params [ :city ] if params . has_key? ( :city )
band . state = params [ :state ] if params . has_key? ( :state )
band . country = params [ :country ] if params . has_key? ( :country )
band . photo_url = params [ :photo_url ] if params . has_key? ( :photo_url )
band . logo_url = params [ :logo_url ] if params . has_key? ( :logo_url )
if params . has_key? ( :genres ) && params [ :genres ]
# loop through each genre in the array and save to the db
genres = [ ]
params [ :genres ] . each { | genre_id | genres << Genre . find ( genre_id ) }
band . genres = genres
end
2012-11-06 02:55:08 +00:00
2013-12-17 02:32:17 +00:00
2014-02-19 22:56:13 +00:00
band
end
2013-12-17 02:32:17 +00:00
2014-02-19 22:56:13 +00:00
# helper method for creating / updating a Band
def self . save ( user , params )
band = build_band ( user , params )
2013-12-17 02:32:17 +00:00
2014-02-19 22:56:13 +00:00
if band . save
# add the creator as the admin
BandMusician . create ( :band_id = > band . id , :user_id = > user . id , :admin = > true ) if params [ :id ] . blank?
2012-11-03 19:32:27 +00:00
end
2014-02-19 22:56:13 +00:00
band
2012-11-25 19:37:54 +00:00
end
2012-11-07 13:10:41 +00:00
2014-02-07 23:56:39 +00:00
def escape_filename ( path )
dir = File . dirname ( path )
file = File . basename ( path )
" #{ dir } / #{ ERB :: Util . url_encode ( file ) } "
end
2014-02-06 16:31:52 +00:00
def update_photo ( original_fpfile , cropped_fpfile , cropped_large_fpfile , crop_selection , aws_bucket )
2013-12-15 21:27:11 +00:00
self . updating_photo = true
cropped_s3_path = cropped_fpfile [ " key " ]
2014-02-06 16:31:52 +00:00
cropped_large_s3_path = cropped_large_fpfile [ " key " ]
2013-12-15 21:27:11 +00:00
2014-02-07 23:56:39 +00:00
self . update_attributes (
2013-12-16 18:47:59 +00:00
:original_fpfile_photo = > original_fpfile ,
:cropped_fpfile_photo = > cropped_fpfile ,
2014-02-06 16:31:52 +00:00
:cropped_large_fpfile_photo = > cropped_large_fpfile ,
2013-12-16 18:47:59 +00:00
:cropped_s3_path_photo = > cropped_s3_path ,
2014-02-06 16:31:52 +00:00
:cropped_large_s3_path_photo = > cropped_large_s3_path ,
2013-12-16 18:47:59 +00:00
:crop_selection_photo = > crop_selection ,
2014-02-07 23:56:39 +00:00
:photo_url = > S3Util . url ( aws_bucket , escape_filename ( cropped_s3_path ) , :secure = > false ) ,
:large_photo_url = > S3Util . url ( aws_bucket , escape_filename ( cropped_large_s3_path ) , :secure = > false ) )
2013-12-15 21:27:11 +00:00
end
2013-12-15 21:30:04 +00:00
def delete_photo ( aws_bucket )
2013-12-15 21:27:11 +00:00
2013-12-15 21:30:04 +00:00
Band . transaction do
2013-12-15 21:27:11 +00:00
2013-12-17 04:23:59 +00:00
unless self . cropped_s3_path_photo . nil?
S3Util . delete ( aws_bucket , File . dirname ( self . cropped_s3_path_photo ) + '/cropped.jpg' )
S3Util . delete ( aws_bucket , self . cropped_s3_path_photo )
2014-02-06 16:31:52 +00:00
S3Util . delete ( aws_bucket , self . cropped_large_s3_path_photo )
2013-12-15 21:27:11 +00:00
end
return self . update_attributes (
2013-12-16 18:47:59 +00:00
:original_fpfile_photo = > nil ,
:cropped_fpfile_photo = > nil ,
2014-02-06 16:31:52 +00:00
:cropped_large_fpfile_photo = > nil ,
2013-12-16 18:47:59 +00:00
:cropped_s3_path_photo = > nil ,
2014-02-06 16:31:52 +00:00
:cropped_large_s3_path_photo = > nil ,
2013-12-16 18:47:59 +00:00
:crop_selection_photo = > nil ,
2014-02-06 16:31:52 +00:00
:photo_url = > nil ,
:large_photo_url = > nil )
2013-12-15 21:27:11 +00:00
end
2013-12-16 18:47:59 +00:00
end
2013-12-15 21:27:11 +00:00
2013-12-09 13:15:59 +00:00
def check_lat_lng
if ( city_changed? || state_changed? || country_changed? )
update_lat_lng
end
2013-12-17 02:32:17 +00:00
true
2013-12-09 13:15:59 +00:00
end
def update_lat_lng
if self . city
query = { :city = > self . city }
query [ :region ] = self . state unless self . state . blank?
2014-07-20 02:11:16 +00:00
query [ :countrycode ] = self . country unless self . country . blank?
if geo = GeoIpLocations . where ( query ) . limit ( 1 ) . first
geo . latitude = nil if geo . latitude = 0
geo . longitude = nil if geo . longitude = 0
if geo . latitude && geo . longitude && ( self . lat != geo . latitude || self . lng != geo . longitude )
self . lat , self . lng = geo . latitude , geo . longitude
2013-12-09 13:15:59 +00:00
return true
end
end
end
self . lat , self . lng = nil , nil
false
2013-12-15 21:27:11 +00:00
end
2014-01-12 08:49:57 +00:00
def check_website_url
if website_changed? && self . website . present?
self . website . strip!
self . website = " http:// #{ self . website } " unless self . website =~ / ^http /
end
true
end
2014-02-11 15:53:20 +00:00
def to_s
name
end
2014-03-09 13:38:46 +00:00
def in_real_session? ( session )
b_members = self . users . sort_by ( & :id ) . map ( & :id )
s_members = session . users . sort_by ( & :id ) . map ( & :id )
( b_members - s_members ) . blank?
end
2014-07-20 02:11:16 +00:00
def self . after_maxmind_import ( use_copied = true )
table_suffix = use_copied ? '_copied' : ''
Band . connection . execute ( " UPDATE bands SET lat = geo.latitude, lng = geo.longitude FROM geoiplocations #{ table_suffix } as geo WHERE bands.city = geo.city AND bands.state = geo.region AND bands.country = geo.countrycode " )
end
2014-12-03 02:42:26 +00:00
def self . is_member? ( band_id , user_id )
BandMusician . where ( band_id : band_id , user_id : user_id )
. limit ( 1 )
. present?
end
2012-11-25 19:37:54 +00:00
private
2014-02-19 22:56:13 +00:00
def require_at_least_one_genre
if self . genres . size < Limits :: MIN_GENRES_PER_BAND
errors . add ( :genres , ValidationMessages :: BAND_GENRE_MINIMUM_NOT_MET )
end
end
2012-11-25 19:37:54 +00:00
2014-02-19 22:56:13 +00:00
def limit_max_genres
if self . genres . size > Limits :: MAX_GENRES_PER_BAND
errors . add ( :genres , ValidationMessages :: BAND_GENRE_LIMIT_EXCEEDED )
2012-11-25 19:37:54 +00:00
end
2013-12-16 18:47:59 +00:00
end
2013-12-16 03:53:16 +00:00
2013-12-16 18:47:59 +00:00
def stringify_photo_info
# fpfile comes in as a hash, which is a easy-to-use and validate form. However, we store it as a VARCHAR,
# so we need t oconvert it to JSON before storing it (otherwise it gets serialized as a ruby object)
# later, when serving this data out to the REST API, we currently just leave it as a string and make a JSON capable
# client parse it, because it's very rare when it's needed at all
self . original_fpfile_photo = original_fpfile_photo . to_json if ! original_fpfile_photo . nil?
self . cropped_fpfile_photo = cropped_fpfile_photo . to_json if ! cropped_fpfile_photo . nil?
self . crop_selection_photo = crop_selection_photo . to_json if ! crop_selection_photo . nil?
end
2012-10-01 21:27:32 +00:00
end
2012-11-08 04:08:16 +00:00
end