Skip to content

Instantly share code, notes, and snippets.

@chuckbergeron
Created November 1, 2012 19:19
Show Gist options
  • Save chuckbergeron/3995823 to your computer and use it in GitHub Desktop.
Save chuckbergeron/3995823 to your computer and use it in GitHub Desktop.
Simple Import w/ Exceptions
class Import
# Mixins
include ImportExceptions
# 0: is the Film Festival we want to relate to a Tab
# 1: the Regionalmovie ID
attr_accessor :attributes
attr_accessor :regionalmovie
attr_accessor :tab
# Any errors we come across will be added to this array
attr_accessor :errors
# Stores the results of the import
attr_reader :results
def initialize( file )
@errors, @results = [], {}
csv = parse( file )
@attributes = collect_attributes( csv.shift )
collect_objects
begin_import( csv )
end
def begin_import( csv )
# We'll clear out the previous import data if we're doing an update
@tab.regionalmovies.destroy_all unless @tab.new_record?
@tab.save!
# Link FilmFestival/Tab to Regionalmovie
@tab.regionalmovies << [ @regionalmovie ]
run_theaters( csv )
end
#########
protected
#########
# 0: CINEMA, 1: ADDRESS, 2: CITY, 3: POSTCODE, 4: REGION
# 5: TICKET RESERVATION PHONE NUMBER, 6: SHOWTIME
def run_theaters( csv )
# Stores the values for theaters / showtimes
region = Region.find_by_short_name( @attributes[:region][:short_name] )
csv.each do |row|
address = Theater.beautify_address_from_csv( row[1], row[2], row[3] )
attrs = {
:name => row[0],
:address => address,
:city => row[2],
:region_id => region.id,
:phone => row[5]
}
theater = Theater.find_or_initialize_by_name( attrs[:name] )
theater.new_record? ? theater.save! : theater.update_attributes( attrs )
# Link Showtimes to Regionalmovie & Cinema
# TODO: Duplicated from showtime.rb - Set up a proper import method using Showtime#update_from_west_world
# If there's no time entered in the CSV
add_error( :no_time, "<b>#{theater.name}</b>" ) and next unless row[6]
showtime_attrs = {
:theater_id => theater.id,
:date => @attributes[:date],
:time => row[6]
}
showtime = @regionalmovie.showtimes.find_or_initialize_by_theater_id_and_date_and_time( showtime_attrs )
showtime.new_record? ? showtime.save! : showtime.update_attributes( showtime_attrs )
end
return true
end
def collect_attributes( csv )
return {
:tab => { :name => csv[0].strip },
:regionalmovie => { :title => csv[1].strip },
:date => csv[2],
:region => { :short_name => csv[3] }
}
end
def collect_objects
@regionalmovie = Regionalmovie.where( :title => @attributes[:regionalmovie][:title] ).first
raise RegionalMovieMismatchError, IMPORT_ERROR_MESSAGES[:rm] unless @regionalmovie
@attributes[:regionalmovie].merge!( :id => regionalmovie.id )
@tab = Tab.where( :name => @attributes[:tab][:name] ).first
raise TabMismatchError, IMPORT_ERROR_MESSAGES[:tab] unless @tab
@attributes[:tab].merge!( :id => tab.id )
return true
end
def parse( file )
# Converts the file from iso to utf8
file = Iconv.new( 'utf-8', 'iso-8859-2' ).iconv( file.read )
csv = []
FasterCSV.parse( file ) { |row| csv << row }
# Delete empty rows, if there is any
csv.delete( [] )
return csv
end
#######
private
#######
# Collect and build a list of all discrepencies
# Report back to user to let them know where the errors lie
def add_error( msg, record, extra = {} )
msg = case msg
when Symbol then IMPORT_ERROR_MESSAGES[msg]
when String then msg
end
@errors << "<li><span>#{msg}: #{record} #{extra}</span></li>"
end
end
module ImportExceptions
# Custom Exceptions
class ImproperFileError < StandardError; end;
class TabMismatchError < StandardError; end;
class RegionalMovieMismatchError < StandardError; end;
class InvalidShipmentError < StandardError; end;
IMPORT_ERROR_MESSAGES = {
:improper => "Please upload a valid CSV file.",
:tab => "Could not find the corresponding Tab. Please create the Tab before import.",
:rm => "Could not find the corresponding Regionalmovie. Please find or create the record before import.",
:no_time => "Showtime was missing from:"
}
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment