Skip to content

Instantly share code, notes, and snippets.

@bluehallu
Last active December 26, 2015 05:19
Show Gist options
  • Save bluehallu/7099806 to your computer and use it in GitHub Desktop.
Save bluehallu/7099806 to your computer and use it in GitHub Desktop.
def upload
Movie.delete_all
xml = params[:upload]
xml = Nokogiri::XML(xml){ |cfg| cfg.noblanks } # parse xml ignoring whitespace
xml.xpath('//movie').each do | movie |
Movie.from_xml(movie).save
end
redirect_to timetable_path
end
class Movie < ActiveRecord::Base
belongs_to :channel
validate :does_not_overlap, :valid_times
def self.from_xml(xml)
id = xml.attr('id') #parse movie id
channel = Channel.find_by_codename(xml.child.name) #get the channel from db
name = xml.child.xpath('name').text #get name
start_time = parse_time(xml.child.xpath('start_time').text)
end_time = parse_time(xml.child.xpath('end_time').text)
new ( {id: id, channel: channel, name: name, start_time: start_time, end_time: end_time, recording: false })
end
def valid_times
if start_time >= end_time
errors.add(:end_time, "Movie with id #{id} end_time must be posterior to start_time")
end
end
def does_not_overlap
channel.movies.each do |movie|
#this trick covers both partial overlaps AND complete enclosings
if (start_time - movie.end_time) * (movie.start_time - end_time) >= 0
errors.add(:end_time, "Movie with id #{id} overlaps with movie with id #{movie.id}")
end
end
end
private
def self.parse_time time
time.gsub!(/\./,':') #replace dot separators by colon as required by Time.parse
Time.parse(time)
end
end
<?xml version="1.0" ?>
<movie_data>
<movie id="1">
<first_channel>
<name>Movie1</name>
<start_time>9.00am</start_time>
<end_time>10.05am</end_time>
</first_channel>
</movie>
<movie id="3">
<first_channel>
<name>Movie2</name>
<start_time>10.00am</start_time>
<end_time>11.30am</end_time>
</first_channel>
</movie>
</movie_data>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment