class Chouette::Hub::Exporter require "zip" attr_reader :referential attr_reader :hub_export, :lines, :routes, :journey_patterns attr_reader :time_tables, :vehicle_journeys def initialize(referential, hub_export) @referential = referential @hub_export = hub_export @lines = nil @routes = nil @journey_patterns = nil @time_tables = nil @vehicle_journeys = nil end def select_time_tables(start_date, end_date) all_time_tables = Chouette::TimeTable.all time_tables = [] s_date = Date.strptime(start_date, "%Y-%m-%d") e_date = Date.strptime(end_date, "%Y-%m-%d") while s_date <= e_date (all_time_tables - time_tables).each { |time_table| time_tables << time_table if time_table.include_day?(s_date) } s_date = s_date.next_day end return time_tables end def select_lines(object, ids) if object == "network" ids.present? ? Chouette::Line.includes(:routes).where(:network_id => ids.split(",")).order(:objectid) : Chouette::Line.joins(:network).includes(:routes).order(:objectid) elsif object == "company" ids.present? ? Chouette::Line.includes(:routes).where(:company_id => ids.split(",")).order(:objectid) : Chouette::Line.joins(:company).includes(:routes).order(:objectid) elsif object == "line" && ids.present? Chouette::Line.includes(:routes).where(:id => ids.split(",")).order(:objectid) else Chouette::Line.includes(:routes).order(:objectid) end end def referential_exportable? Chouette::VehicleJourneyAtStop.count < 50000 end def time_tables_exportable? time_tables end def routes_exportable? routes # && routes.size < 150 end def lines_exportable? lines # && lines.size < 150 end def journey_patterns_exportable? journey_patterns # && journey_patterns.size < 150 end def vehicle_journeys_exportable? vehicle_journeys end def log_overflow_warning( target_class) hub_export.log_messages.create(:severity => "warning", :key => "EXPORT_ERROR|EXCEPTION", :arguments => {"0" => I18n.t('export_log_messages.messages.overflow', :count => 150, :data => target_class.model_name.human.pluralize)}) end def export(zip_file_path, options = {}) begin referential.switch if referential_exportable? && options[:start_date] && options[:end_date] FileUtils.rm(zip_file_path) if File.exists? zip_file_path hub_export.log_messages.create( :severity => "ok", :key => "EXPORT", :arguments => {"0" => "HUB"}) Dir.mktmpdir(nil, "/tmp") { |temp_dir| @time_tables = select_time_tables(options[:start_date], options[:end_date]) @lines = select_lines(options[:o], options[:id]) @routes = [] if @lines @lines.each { |line| @routes << Chouette::Route.where("line_id = ?", line.id).order(:wayback) } end @journey_patterns = [] if @routes @routes.each { |subroutes| @journey_patterns << Chouette::JourneyPattern.where(:route_id => subroutes.map(&:id)).order(:objectid) } end @journey_patterns = @journey_patterns.flatten @routes = @routes.flatten @vehicle_journeys = Chouette::VehicleJourney.where(:route_id => @routes.map(&:id)).order(:objectid) if routes_exportable? rts = [] jps = [] vjs = [] tts = [] @vehicle_journeys.each do |vj| unless (vj.time_tables & @time_tables).empty? vjs << vj tts << (vj.time_tables & @time_tables) rts << vj.route_id jps << vj.journey_pattern_id end end @time_tables = tts.flatten.uniq @vehicle_journeys = vjs.uniq rts = rts.flatten.uniq jps = jps.flatten.uniq @routes.delete_if {|r| !(rts.include?(r.id)) } @journey_patterns.delete_if {|jp| !(jps.include?(jp.id)) } vehicle_journey_at_stops = Chouette::VehicleJourneyAtStop.where( :vehicle_journey_id => @vehicle_journeys.map(&:id) ) #.order(:id) if vehicle_journeys_exportable? if time_tables_exportable? Chouette::Hub::TimeTableExporter.save(@time_tables, temp_dir, hub_export) else log_overflow_warning(Chouette::TimeTable) end if journey_patterns_exportable? Chouette::Hub::RouteExporter.save(@routes, temp_dir, hub_export) Chouette::Hub::ItlExporter.save(@routes, temp_dir, hub_export) Chouette::Hub::JourneyPatternExporter.save(@journey_patterns, temp_dir, hub_export) Chouette::Hub::DirectionExporter.save(@journey_patterns, temp_dir, hub_export) else log_overflow_warning(Chouette::JourneyPattern) if routes_exportable? end if vehicle_journeys_exportable? Chouette::Hub::VehicleJourneyExporter.save(@vehicle_journeys, temp_dir, hub_export) Chouette::Hub::VehicleJourneyOperationExporter.save(@vehicle_journeys, temp_dir, hub_export) Chouette::Hub::VehicleJourneyAtStopExporter.save(@vehicle_journeys, temp_dir, hub_export, vehicle_journey_at_stops.count) else log_overflow_warning(Chouette::VehicleJourney) end stop_points = Chouette::StopPoint.where( :id => vehicle_journey_at_stops.map(&:stop_point_id)) #.order(:id) physical_stop_areas = Chouette::StopArea.where( :id => stop_points.map(&:stop_area_id)) #.order(:parent_id) commercial_stop_areas = Chouette::StopArea.where( :id => physical_stop_areas.map(&:parent_id)).order(:objectid) physical_stop_areas = [] commercial_stop_areas.each { |commercial_stop_area| physical_stop_areas << Chouette::StopArea.where( :parent_id => [commercial_stop_area.id] ).order(:objectid) } physical_stop_areas = physical_stop_areas.flatten city_codes = Hash.new commercial_stop_areas.each { |commercial_stop_area| city_codes[commercial_stop_area.zip_code] = commercial_stop_area.city_name if commercial_stop_area.zip_code } physical_stop_areas.each { |physical_stop_area| city_codes[physical_stop_area.zip_code] = physical_stop_area.city_name if physical_stop_area.zip_code } Chouette::Hub::CityCodeExporter.save(city_codes, temp_dir, hub_export) Chouette::Hub::CommercialStopAreaExporter.save(commercial_stop_areas, temp_dir, hub_export) Chouette::Hub::PhysicalStopAreaExporter.save(physical_stop_areas, temp_dir, hub_export) connection_links = Chouette::ConnectionLink.where( "departure_id IN (?) AND arrival_id IN (?)", (physical_stop_areas.map(&:id) + commercial_stop_areas.map(&:id)), (physical_stop_areas.map(&:id) + commercial_stop_areas.map(&:id)) ).order(:id) Chouette::Hub::ConnectionLinkExporter.save(connection_links, temp_dir, hub_export) if lines_exportable? Chouette::Hub::LineExporter.save(@lines, temp_dir, hub_export) transport_modes = Hash.new @lines.each do |l| if l.transport_mode case l.transport_mode when 'coach' if transport_modes["CAR"] transport_modes["CAR"] += "|"+l.objectid.sub(/(\w*\:\w*\:)(\w*)/, '\2') else transport_modes["CAR"] = l.objectid.sub(/(\w*\:\w*\:)(\w*)/, '\2') end when 'bus' if transport_modes["BUS"] transport_modes["BUS"] += "|"+l.objectid.sub(/(\w*\:\w*\:)(\w*)/, '\2') else transport_modes["BUS"] = l.objectid.sub(/(\w*\:\w*\:)(\w*)/, '\2') end end end end Chouette::Hub::TransportModeExporter.save(transport_modes, temp_dir, hub_export) networks = Chouette::Network.where( :id => @lines.map(&:network_id)) companies = Chouette::Company.where( :id => @lines.map(&:company_id)) groups_of_lines = [] @lines.each { |l| groups_of_lines << l.group_of_lines } groups_of_lines = groups_of_lines.flatten.uniq Chouette::Hub::GroupOfLinesExporter.save(groups_of_lines, temp_dir, hub_export) Chouette::Hub::NetworkExporter.save(networks, temp_dir, hub_export) Chouette::Hub::CompanyExporter.save(companies, temp_dir, hub_export) else log_overflow_warning(Chouette::Line) end if lines_exportable? stop_areas = Chouette::StopArea.joins( :stop_points => [:route => :line]).where(:lines => {:id => lines.map(&:id)}).uniq.order(:name) commercial_stop_areas = Chouette::StopArea.where( :id => stop_areas.map(&:parent_id).compact.uniq).order(:name) end ::Zip::File.open(zip_file_path, ::Zip::File::CREATE) do |zipfile| Dir[File.join(temp_dir, '*.TXT')].each do |f| #Rails.logger.error("Adding File #{File.basename(f)}") zipfile.add(File.basename(f), f) end end } end ensure # Always cleanup files #FileUtils.remove_entry(temp_directory) end end end