diff options
73 files changed, 1123 insertions, 81 deletions
| diff --git a/Gemfile.lock b/Gemfile.lock index d3cbae20d..515816731 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -62,7 +62,7 @@ GIT  GIT    remote: git://sim.dryade.priv/user_interface -  revision: a9f62359e65e42e9329bf4dbbd0c5a63a42119a4 +  revision: c75665070cace889923bea6a0fb1f7ff724d1368    specs:      user_interface (0.0.1)        rails (~> 3.1.0) @@ -129,30 +129,30 @@ GEM        xpath (~> 0.1.4)      childprocess (0.3.2)        ffi (~> 1.0.6) -    cocoon (1.0.20) +    cocoon (1.0.22)      coffee-rails (3.1.1)        coffee-script (>= 2.2.0)        railties (~> 3.1.0)      coffee-script (2.2.0)        coffee-script-source        execjs -    coffee-script-source (1.3.1) +    coffee-script-source (1.3.3)      composite_primary_keys (4.1.2)        activerecord (~> 3.1) -    database_cleaner (0.7.2) -    delayed_job (3.0.2) +    database_cleaner (0.8.0) +    delayed_job (3.0.3)        activesupport (~> 3.0)      delayed_job_active_record (0.3.2)        activerecord (> 2.1.0)        delayed_job (~> 3.0.0) -    devise (2.0.4) +    devise (2.1.0)        bcrypt-ruby (~> 3.0) -      orm_adapter (~> 0.0.3) +      orm_adapter (~> 0.0.7)        railties (~> 3.1)        warden (~> 1.1.1)      diff-lcs (1.1.3)      erubis (2.7.0) -    execjs (1.3.1) +    execjs (1.4.0)        multi_json (~> 1.0)      factory_girl (2.6.4)        activesupport (>= 2.3.9) @@ -168,13 +168,13 @@ GEM      geokit (1.6.5)        multi_json      georuby (1.9.7) -    guard (1.0.2) -      ffi (>= 0.5.0) -      thor (~> 0.14.6) -    guard-rspec (0.7.0) -      guard (>= 0.10.0) +    guard (1.1.1) +      listen (>= 0.4.2) +      thor (>= 0.14.6) +    guard-rspec (1.0.1) +      guard (>= 1.1)      has_scope (0.5.1) -    highline (1.6.11) +    highline (1.6.12)      hike (1.2.1)      i18n (0.6.0)      inherited_resources (1.3.1) @@ -185,9 +185,9 @@ GEM        railties (~> 3.0)        thor (~> 0.14)      jruby-jars (1.6.7.2) -    jruby-openssl (0.7.6.1) +    jruby-openssl (0.7.7)        bouncy-castle-java (>= 1.5.0146.1) -    jruby-rack (1.1.5) +    jruby-rack (1.1.6)      jruby-rack-worker (0.3-java)        jruby-rack (>= 1.0.1)      json (1.7.3) @@ -201,6 +201,10 @@ GEM        spoon (~> 0.0.1)      libwebsocket (0.1.3)        addressable +    listen (0.4.5) +      rb-fchange (~> 0.0.5) +      rb-fsevent (~> 0.9.1) +      rb-inotify (~> 0.8.8)      mail (2.3.3)        i18n (>= 0.4.0)        mime-types (~> 1.16) @@ -212,11 +216,11 @@ GEM        net-ssh (>= 1.99.1)      net-sftp (2.0.5)        net-ssh (>= 2.0.9) -    net-ssh (2.3.0) +    net-ssh (2.5.2)      net-ssh-gateway (1.1.0)        net-ssh (>= 1.99.1) -    nokogiri (1.5.2) -    nokogiri (1.5.2-java) +    nokogiri (1.5.4) +    nokogiri (1.5.4-java)      orm_adapter (0.0.7)      polyamorous (0.5.0)        activerecord (~> 3.0) @@ -250,6 +254,11 @@ GEM        actionpack (~> 3.0)        activerecord (~> 3.0)        polyamorous (~> 0.5.0) +    rb-fchange (0.0.5) +      ffi +    rb-fsevent (0.9.1) +    rb-inotify (0.8.8) +      ffi (>= 0.5.0)      rdoc (3.12)        json (~> 1.4)      remarkable (4.0.0.alpha4) @@ -278,14 +287,14 @@ GEM        railties (>= 3.0)        rspec (~> 2.10.0)      rubyzip (0.9.8) -    sass (3.1.18) +    sass (3.1.19)      sass-rails (3.1.4)        actionpack (~> 3.1.0)        railties (~> 3.1.0)        sass (>= 3.1.4)        sprockets (~> 2.0.0)        tilt (~> 1.3.2) -    selenium-webdriver (2.21.2) +    selenium-webdriver (2.22.2)        childprocess (>= 0.2.5)        ffi (~> 1.0)        libwebsocket (~> 0.1.3) @@ -299,11 +308,11 @@ GEM        hike (~> 1.2)        rack (~> 1.0)        tilt (~> 1.1, != 1.3.0) -    squeel (1.0.1) +    squeel (1.0.5)        activerecord (~> 3.0)        activesupport (~> 3.0)        polyamorous (~> 0.5.0) -    therubyrhino (1.73.3) +    therubyrhino (1.73.4)      thor (0.14.6)      tilt (1.3.3)      treetop (1.4.10) @@ -1,10 +1,10 @@  # A sample Guardfile  # More info at https://github.com/guard/guard#readme -guard 'rspec', :version => 2 do -    watch(%r{^spec/.+_spec\.rb$}) -    watch(%r{^lib/(.+)\.rb$})     { |m| "spec/lib/#{m[1]}_spec.rb" } -    watch('spec/spec_helper.rb')  { "spec" } +guard 'rspec', :version => 2, :notification => false do +  watch(%r{^spec/.+_spec\.rb$}) +  watch(%r{^lib/(.+)\.rb$})     { |m| "spec/lib/#{m[1]}_spec.rb" } +  watch('spec/spec_helper.rb')  { "spec" }    # Rails example    watch(%r{^app/(.+)\.rb$})                           { |m| "spec/#{m[1]}_spec.rb" } diff --git a/app/assets/images/download-small.png b/app/assets/images/download-small.pngBinary files differ new file mode 100644 index 000000000..6ffb8e642 --- /dev/null +++ b/app/assets/images/download-small.png diff --git a/app/assets/images/export-completed.png b/app/assets/images/export-completed.pngBinary files differ new file mode 100644 index 000000000..a76d76b13 --- /dev/null +++ b/app/assets/images/export-completed.png diff --git a/app/assets/images/export-failed.png b/app/assets/images/export-failed.pngBinary files differ new file mode 100644 index 000000000..f13b19234 --- /dev/null +++ b/app/assets/images/export-failed.png diff --git a/app/assets/images/export-pending.png b/app/assets/images/export-pending.pngBinary files differ new file mode 100644 index 000000000..1e50e36ac --- /dev/null +++ b/app/assets/images/export-pending.png diff --git a/app/assets/images/severity-fatal.png b/app/assets/images/severity-fatal.pngBinary files differ new file mode 100644 index 000000000..2cb3e9113 --- /dev/null +++ b/app/assets/images/severity-fatal.png diff --git a/app/assets/images/severity-ok.png b/app/assets/images/severity-ok.pngBinary files differ new file mode 100644 index 000000000..ab7c378c0 --- /dev/null +++ b/app/assets/images/severity-ok.png diff --git a/app/assets/images/severity-uncheck.png b/app/assets/images/severity-uncheck.pngBinary files differ new file mode 100644 index 000000000..4a892e60c --- /dev/null +++ b/app/assets/images/severity-uncheck.png diff --git a/app/assets/javascripts/exports.js.coffee b/app/assets/javascripts/exports.js.coffee new file mode 100644 index 000000000..761567942 --- /dev/null +++ b/app/assets/javascripts/exports.js.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/ diff --git a/app/assets/javascripts/imports.js.coffee b/app/assets/javascripts/imports.js.coffee index 761567942..7fb49e44d 100644 --- a/app/assets/javascripts/imports.js.coffee +++ b/app/assets/javascripts/imports.js.coffee @@ -1,3 +1,12 @@  # Place all the behaviors and hooks related to the matching controller here.  # All this logic will automatically be available in application.js.  # You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/ + +jQuery -> +  $('#import_type_submit').hide() + +  import_type_change = (event) ->  +    import_type = $("select option:selected").attr("value") +    $(form).toggle($(form).is("#" + import_type + "_new")) for form in $('form.import') + +  $('#import_type').change(import_type_change) diff --git a/app/assets/stylesheets/common.css.scss b/app/assets/stylesheets/common.css.scss index b0655b5e0..9f9ce3346 100644 --- a/app/assets/stylesheets/common.css.scss +++ b/app/assets/stylesheets/common.css.scss @@ -49,6 +49,9 @@              a.remove {                  background: url(image-path('user_interface/ui/remove-small.png')) no-repeat 0% 50%;              } +            a.download { +                background: url(image-path('download-small.png')) no-repeat 0% 50%; +            }          }          p { diff --git a/app/assets/stylesheets/exports.css.scss b/app/assets/stylesheets/exports.css.scss new file mode 100644 index 000000000..cb8f23dc4 --- /dev/null +++ b/app/assets/stylesheets/exports.css.scss @@ -0,0 +1,41 @@ +// Place all the styles related to the Exports controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ + +@import "common"; + +#workspace.exports.index +{ +    .export:after {  +        @include after_div_for_object;   +    } + +    .exports { +        margin-top: 20px; +    } + +    .exports:after { +        @include content_to_clear; +    } +     +    .export { +        @include div_for_object; + +        /* to create multi-column index */ +        width: 300px; +        float: left; +        padding-right: 10px; +    } +} + +#workspace.exports.show { +    table { +        th { +            text-align: center; +            font-style: italic; +        } +        td.message, td.created_at, td.position { +            padding: 0 20px; +        } +    }                        +} diff --git a/app/assets/stylesheets/imports.css.scss b/app/assets/stylesheets/imports.css.scss index bdc3a65cd..91acae72d 100644 --- a/app/assets/stylesheets/imports.css.scss +++ b/app/assets/stylesheets/imports.css.scss @@ -34,4 +34,19 @@              padding: 0 20px;          }      }                        -}
\ No newline at end of file +} + +#workspace.imports.new form.import_new { +    padding: 0.5em 0; +    margin-top: -0.5em; +    margin-bottom: 1em; + +    label { +        display: block; +        width: 25%; +        float: left; +    } +    select { +        width: 25%; +    } +} diff --git a/app/assets/stylesheets/stop_areas.css.scss b/app/assets/stylesheets/stop_areas.css.scss index e66f4dd28..3a5e70916 100644 --- a/app/assets/stylesheets/stop_areas.css.scss +++ b/app/assets/stylesheets/stop_areas.css.scss @@ -65,6 +65,19 @@              span { margin-left: 7px; }              img { margin: 0px 5px 0px 5px;}          } +        .lines{ +            float: left; + +            .line{ +                border: 2px solid black; +                padding: 3px 15px 3px 3px; +                height: 25px; +                margin-bottom: 5px; +                * { vertical-align:middle; } +                span { margin-left: 7px; } +                img { margin: 0px 5px 0px 5px;} +            } +        }          .no_parent{              float: left;              padding: 3px 15px 3px 3px; diff --git a/app/controllers/exports_controller.rb b/app/controllers/exports_controller.rb new file mode 100644 index 000000000..6a77f7f45 --- /dev/null +++ b/app/controllers/exports_controller.rb @@ -0,0 +1,34 @@ +class ExportsController < ChouetteController + +  respond_to :html, :xml, :json +  respond_to :zip, :only => :show + +  belongs_to :referential + +  def create +    create! do |success, failure| +      success.html { redirect_to referential_exports_path(@referential) } +    end +  end + +  def show +    show! do |format| +      format.zip { send_file @export.file, :type => :zip } +    end +  end + + +  protected + +  # FIXME why #resource_id is nil ?? +  def build_resource +    super.tap do |export| +      export.referential_id = @referential.id +    end +  end + +  def collection +    @exports ||= end_of_association_chain.paginate(:page => params[:page]) +  end + +end diff --git a/app/controllers/imports_controller.rb b/app/controllers/imports_controller.rb index 7e33b8c26..06017da7d 100644 --- a/app/controllers/imports_controller.rb +++ b/app/controllers/imports_controller.rb @@ -2,14 +2,38 @@ class ImportsController < ChouetteController    respond_to :html, :xml, :json    belongs_to :referential +  def new +    new! do +      available_imports +    end +  end +    def create      create! do |success, failure| +      available_imports        success.html { redirect_to referential_imports_path(@referential) }      end    end    protected +  def available_imports +    @available_imports ||= Import.types.collect do |type| +      unless @import.type == type +        @referential.imports.build :type => type +      else +        @import +      end +    end +  end + +  # FIXME why #resource_id is nil ?? +  def build_resource +    super.tap do |import| +      import.referential_id = @referential.id +    end +  end +    def collection      @imports ||= end_of_association_chain.paginate(:page => params[:page])    end diff --git a/app/controllers/stop_area_routing_lines_controller.rb b/app/controllers/stop_area_routing_lines_controller.rb new file mode 100644 index 000000000..9ba6fb40c --- /dev/null +++ b/app/controllers/stop_area_routing_lines_controller.rb @@ -0,0 +1,21 @@ +class StopAreaRoutingLinesController < ChouetteController + +  respond_to :json, :only => :index + +  def index +    respond_to do |format|   +      format.json { render :json => routing_lines_maps }   +    end   +  end + +  def routing_lines_maps +    routing_lines.collect do |line| +      { :id => line.id.to_s, :name => "#{line.number} - #{line.name}" } +    end +  end + +  def routing_lines  +    referential.lines.all.select{ |p| p.name =~ /#{params[:q]}/i || p.number =~ /#{params[:q]}/i }        +  end + +end diff --git a/app/controllers/stop_area_routing_stops_controller.rb b/app/controllers/stop_area_routing_stops_controller.rb new file mode 100644 index 000000000..c5e7980f9 --- /dev/null +++ b/app/controllers/stop_area_routing_stops_controller.rb @@ -0,0 +1,21 @@ +class StopAreaRoutingStopsController < ChouetteController + +  respond_to :json, :only => :index + +  def index +    respond_to do |format|   +      format.json { render :json => routing_stops_maps }   +    end   +  end + +  def routing_stops_maps +    routing_stops.collect do |stop| +      { :id => stop.id.to_s, :name => "#{stop.name} #{stop.country_code}" } +    end +  end + +  def routing_stops  +    referential.stop_areas.find(params[:stop_area_id]).possible_children.select{ |p| p.name =~ /#{params[:q]}/i  }        +  end + +end diff --git a/app/controllers/stop_areas_controller.rb b/app/controllers/stop_areas_controller.rb index 8fc9191a1..55bf713a7 100644 --- a/app/controllers/stop_areas_controller.rb +++ b/app/controllers/stop_areas_controller.rb @@ -24,6 +24,16 @@ class StopAreasController < ChouetteController      @children = stop_area.children    end +  def add_routing_lines +    @stop_area = stop_area +    @lines = stop_area.routing_lines +  end + +  def add_routing_stops +    @stop_area = stop_area +    @stops = stop_area.routing_stops +  end +    def index           request.format.kml? ? @per_page = nil : @per_page = 10      index! @@ -49,6 +59,11 @@ class StopAreasController < ChouetteController      edit!    end +#  def update      +#    puts :resource +#    update! +#  end +    protected    alias_method :stop_area, :resource diff --git a/app/helpers/exports_helper.rb b/app/helpers/exports_helper.rb new file mode 100644 index 000000000..bd84b9886 --- /dev/null +++ b/app/helpers/exports_helper.rb @@ -0,0 +1,2 @@ +module ExportsHelper +end diff --git a/app/helpers/imports_helper.rb b/app/helpers/imports_helper.rb index 2811dcbec..4b829fe98 100644 --- a/app/helpers/imports_helper.rb +++ b/app/helpers/imports_helper.rb @@ -1,2 +1,14 @@ +# -*- coding: utf-8 -*-  module ImportsHelper + +  def fields_for_import_type(form) +    partial_name = "fields_#{form.object.type.underscore}" + +    begin +      render :partial => partial_name, :locals => { :form => form } +    rescue ActionView::MissingTemplate +      "" +    end +  end +  end diff --git a/app/helpers/time_tables_helper.rb b/app/helpers/time_tables_helper.rb index c5a6579d9..db9c1109e 100644 --- a/app/helpers/time_tables_helper.rb +++ b/app/helpers/time_tables_helper.rb @@ -6,7 +6,8 @@ module TimeTablesHelper          :end => l(time_table.bounding_dates.max))    end    def time_tables_shortest_info( vehicle) -    "#{l(vehicle.bounding_dates.min)} #{l(vehicle.bounding_dates.max)}" +    return vehicle.bounding_dates.inspect +    #"#{l(vehicle.bounding_dates.min)} #{l(vehicle.bounding_dates.max)}"    end    def time_tables_info( vehicle)      vehicle.time_tables.map do |time_table| diff --git a/app/models/csv_import.rb b/app/models/csv_import.rb new file mode 100644 index 000000000..be3c08743 --- /dev/null +++ b/app/models/csv_import.rb @@ -0,0 +1,10 @@ +class CsvImport < Import + +  validates_presence_of :objectid_prefix +  option :objectid_prefix + +  def import_options +    super.merge(:format => :csv, :objectid_prefix => objectid_prefix) +  end + +end diff --git a/app/models/export.rb b/app/models/export.rb new file mode 100644 index 000000000..a202e77ef --- /dev/null +++ b/app/models/export.rb @@ -0,0 +1,84 @@ +class Export < ActiveRecord::Base + +  belongs_to :referential +  validates_presence_of :referential_id + +  validates_inclusion_of :status, :in => %w{ pending completed failed } + +  has_many :log_messages, :class_name => "ExportLogMessage", :order => :position, :dependent => :destroy + +  serialize :options + +  def self.option(name) +    name = name.to_s + +    define_method(name) do +      self.options[name] +    end + +    define_method("#{name}=") do |prefix| +      self.options[name] = prefix +    end +  end + +  def options +    read_attribute(:options) || write_attribute(:options, {}) +  end + +  @@root = "#{Rails.root}/tmp/exports" +  cattr_accessor :root + +  after_destroy :destroy_file +  def destroy_file +    FileUtils.rm file if File.exists? file +  end + +  def file +    "#{root}/#{id}.zip" +  end + +  def name +    "#{self.class.model_name.human} #{id}" +  end + +  def export_options +    { :export_id => self.id, :output_file => file } +  end + +  before_validation :define_default_attributes, :on => :create +  def define_default_attributes +    self.status ||= "pending" +  end + +  after_create :delayed_export +  def delayed_export +    delay.export +  end + +  def export +    FileUtils.mkdir_p root + +    begin +      log_messages.create :key => :started + +      # TODO +      # Make real export here + +      update_attribute :status, "completed" +    rescue => e +      Rails.logger.error "Export #{id} failed : #{e}, #{e.backtrace}" +      update_attribute :status, "failed" +    end + +    log_messages.create :key => status +  end + +  def self.new(attributes = {}, options = {}, &block) +    if self == Export +      Object.const_get(attributes.delete(:type) || "NeptuneExport").new(attributes, options) +    else +      super +    end +  end + +end diff --git a/app/models/export_log_message.rb b/app/models/export_log_message.rb new file mode 100644 index 000000000..61068689c --- /dev/null +++ b/app/models/export_log_message.rb @@ -0,0 +1,36 @@ +class ExportLogMessage < ActiveRecord::Base +  belongs_to :export + +  acts_as_list :scope => :export +   +  validates_presence_of :key +  validates_inclusion_of :severity, :in => %w{info warning error} + +  def arguments=(arguments) +    write_attribute :arguments, (arguments.to_json if arguments.present?) +  end + +  def arguments +    @decoded_arguments ||=  +      begin +        if (stored_arguments = raw_attributes).present? +          ActiveSupport::JSON.decode stored_arguments +        else +          {} +        end +      end +  end + +  def raw_attributes +    read_attribute(:arguments) +  end + +  before_validation :define_default_attributes, :on => :create +  def define_default_attributes +    self.severity ||= "info" +  end +  +  def full_message +    I18n.translate key, arguments.symbolize_keys.merge(:scope => "export_log_messages.messages") +  end +end diff --git a/app/models/import.rb b/app/models/import.rb index b08f8e8f3..662fe4a84 100644 --- a/app/models/import.rb +++ b/app/models/import.rb @@ -13,10 +13,35 @@ class Import < ActiveRecord::Base    serialize :options -  after_initialize :define_options +  def self.option(name) +    name = name.to_s -  def define_options -    self.options = {} +    define_method(name) do +      self.options[name] +    end + +    define_method("#{name}=") do |prefix| +      self.options[name] = prefix +    end +  end + +  def options +    read_attribute(:options) || write_attribute(:options, {}) +  end + +  def self.types +    # if Rails.env.development? and subclasses.blank? +    #   Dir[File.expand_path("../*_import.rb", __FILE__)].each do |f|  +    #     require f +    #   end +    # end + +    unless Rails.env.development? +      subclasses.map(&:to_s) +    else +      # FIXME +      %w{NeptuneImport CsvImport} +    end    end    def loader @@ -36,6 +61,11 @@ class Import < ActiveRecord::Base      self.status ||= "pending"    end +  before_validation :extract_file_type, :on => :create +  def extract_file_type +    self.file_type = resources.original_filename.rpartition(".").last +  end +    after_create :delayed_import    def delayed_import      save_resources @@ -56,7 +86,7 @@ class Import < ActiveRecord::Base    end    def saved_resources -    "#{root}/#{id}.zip" +    "#{root}/#{id}.#{file_type}"    end    def name @@ -64,7 +94,7 @@ class Import < ActiveRecord::Base    end    def import_options -    {} +    { :import_id => self.id , :file_format => self.file_type }    end    def import @@ -86,4 +116,12 @@ class Import < ActiveRecord::Base      log_messages.create :key => status    end +  def self.new(attributes = {}, options = {}, &block) +    if self == Import +      Object.const_get(attributes.delete(:type) || "NeptuneImport").new(attributes, options) +    else +      super +    end +  end +  end diff --git a/app/models/import_log_message.rb b/app/models/import_log_message.rb index 699c9603d..f06a61213 100644 --- a/app/models/import_log_message.rb +++ b/app/models/import_log_message.rb @@ -30,7 +30,8 @@ class ImportLogMessage < ActiveRecord::Base    end    def full_message -    I18n.translate key, arguments.symbolize_keys.merge(:scope => "import_log_messages.messages") +    last_key=key.rpartition("|").last +    I18n.translate last_key, arguments.symbolize_keys.merge(:scope => "import_log_messages.messages").merge(:default => :undefined).merge(:key => last_key)    end  end diff --git a/app/models/neptune_export.rb b/app/models/neptune_export.rb new file mode 100644 index 000000000..fd429101c --- /dev/null +++ b/app/models/neptune_export.rb @@ -0,0 +1,7 @@ +class NeptuneExport < Export + +  def export_options +    super.merge(:format => :neptune) +  end + +end diff --git a/app/models/neptune_import.rb b/app/models/neptune_import.rb index f00947129..11282b306 100644 --- a/app/models/neptune_import.rb +++ b/app/models/neptune_import.rb @@ -1,7 +1,7 @@  class NeptuneImport < Import    def import_options -    { :format => :neptune } +    super.merge(:format => :neptune)    end  end diff --git a/app/models/referential.rb b/app/models/referential.rb index 2d6d5b8d5..3f4a62bb6 100644 --- a/app/models/referential.rb +++ b/app/models/referential.rb @@ -9,6 +9,7 @@ class Referential < ActiveRecord::Base    validates_format_of :prefix, :with => %r{\A[0-9a-zA-Z_]+\Z}    has_many :imports, :dependent => :destroy +  has_many :exports, :dependent => :destroy    def human_attribute_name(*args)      self.class.human_attribute_name(*args) diff --git a/app/views/exports/_export.erb b/app/views/exports/_export.erb new file mode 100644 index 000000000..c5412fbc5 --- /dev/null +++ b/app/views/exports/_export.erb @@ -0,0 +1,14 @@ +<%= div_for(export, :class => :export) do %> +  <%= link_to(referential_export_path(@referential, export), :class => "preview") do %> +    <%= image_tag "export-#{export.status}.png" %> +  <% end %> +  <%= link_to(export.name, referential_export_path(@referential, export)) %> +  <div class="info"> +    <%= l export.created_at %> + +    <div class="actions">   +      <%= link_to t("exports.actions.download"), referential_export_path(@referential, export, :format => :zip), :class => "download" %> +      <%= link_to t("actions.destroy"), referential_export_path(@referential, export), :method => :delete, :confirm =>  t('exports.actions.destroy_confirm'), :class => "remove" %> +    </div> +  </div> +<% end %> diff --git a/app/views/exports/index.html.erb b/app/views/exports/index.html.erb new file mode 100644 index 000000000..82803d725 --- /dev/null +++ b/app/views/exports/index.html.erb @@ -0,0 +1,20 @@ +<%= title_tag t('.title') %>  + +<div class="pagination"> +  <div class="page_info"> +    <%= page_entries_info @exports %> +  </div> +  <%= will_paginate @exports, :container => false %> +</div> +<div class="exports paginated_content"> +  <%= render :partial => "export", :collection => @exports %> +</div> +<div class="pagination"> +  <%= will_paginate @exports, :container => false %> +</div> + +<% content_for :sidebar do %> +<ul class="actions"> +  <li><%= link_to t('exports.actions.new'), new_referential_export_path(@referential), :class => "add" %></li>  +</ul> +<% end %> diff --git a/app/views/exports/new.html.erb b/app/views/exports/new.html.erb new file mode 100644 index 000000000..24022e0f8 --- /dev/null +++ b/app/views/exports/new.html.erb @@ -0,0 +1,9 @@ +<%= title_tag t(".title") %> + +<%= semantic_form_for [@referential, @export], :as => :export, :url => referential_exports_path(@referential) do |form| %> +  <%= form.buttons do %> +    <%= form.commit_button true %> +    <li><%= t('or') %></li> +    <li><%= link_to t('cancel'), :back %></li> +  <% end %> +<% end %> diff --git a/app/views/exports/show.html.erb b/app/views/exports/show.html.erb new file mode 100644 index 000000000..c3248b47a --- /dev/null +++ b/app/views/exports/show.html.erb @@ -0,0 +1,39 @@ +<%= title_tag @export.name %> + +<div class="export_show"> +  <div class="summary"> +    <p> +      <label><%= Export.human_attribute_name(:created_at) %>: </label> +      <%= l @export.created_at %> +    </p> +    <p> +      <label><%= Export.human_attribute_name(:status) %>: </label> +      <%= t @export.status, :scope => "exports.statuses" %> +    </p> +  </div> + +  <h3><%= t(".report") %></h3> +  <table> +    <tr> +      <th></th> +      <th><%= ExportLogMessage.human_attribute_name(:created_at) %></th> +      <th><%= ExportLogMessage.human_attribute_name(:position) %></th> +      <th><%= ExportLogMessage.human_attribute_name(:full_message) %></th> +    </tr> +    <% @export.log_messages.each do |message| %> +    <tr> +      <td class="severity"><%= image_tag "severity-#{message.severity}.png", :alt => t(message.severity, :scope => "export_log_messages.severities") %></td> +      <td class="created_at"><%= l message.created_at, :format => :short %></td> +      <td class="position"><%= message.position %></td> +      <td class="message"><%= message.full_message %></td> +    </tr> +    <% end %> +  </table> +</div> + +<% content_for :sidebar do %> +<ul class="actions"> +  <li><%= link_to  t('exports.actions.download'), referential_export_path(@referential, @export, :format => :zip), :class => "download" %></li> +  <li><%= link_to  t('exports.actions.destroy'), referential_export_path(@referential, @export), :method => :delete, :confirm =>  t('exports.actions.destroy_confirm'), :class => "remove" %></li> +</ul> +<% end %> diff --git a/app/views/imports/_fields_csv_import.erb b/app/views/imports/_fields_csv_import.erb new file mode 100644 index 000000000..2ab96acf7 --- /dev/null +++ b/app/views/imports/_fields_csv_import.erb @@ -0,0 +1 @@ +<%= form.input :objectid_prefix, :input_html => { :value => @referential.prefix } %> diff --git a/app/views/imports/_import.erb b/app/views/imports/_import.erb index 6ccd5bb23..7723badc0 100644 --- a/app/views/imports/_import.erb +++ b/app/views/imports/_import.erb @@ -1,4 +1,4 @@ -<%= div_for(import) do %> +<%= div_for(import, :class => :import) do %>    <%= link_to(referential_import_path(@referential, import), :class => "preview") do %>      <%= image_tag "import-#{import.status}.png" %>    <% end %> diff --git a/app/views/imports/index.html.erb b/app/views/imports/index.html.erb index 9bda3ffb5..454dcd813 100644 --- a/app/views/imports/index.html.erb +++ b/app/views/imports/index.html.erb @@ -7,7 +7,7 @@    <%= will_paginate @imports, :container => false %>  </div>  <div class="imports paginated_content"> -  <%= render @imports %> +  <%= render :partial => "import", :collection => @imports %>  </div>  <div class="pagination">    <%= will_paginate @imports, :container => false %> diff --git a/app/views/imports/new.html.erb b/app/views/imports/new.html.erb index 02ad61ede..1b797b0d6 100644 --- a/app/views/imports/new.html.erb +++ b/app/views/imports/new.html.erb @@ -1,13 +1,27 @@  <%= title_tag t(".title") %> -<%= semantic_form_for [@referential, @import] do |form| %> -  <%= form.inputs do %>  -    <%= form.input :resources, :as => :file %> -  <% end %> +<%= form_for([@referential, @import], :as => :import, :url => new_referential_import_path(@referential), :method => :get) do |form| %> +  <%= form.label :type %> +  <%= form.collection_select :type, Import.types, :to_s, :to_s %> +  <%= form.submit "Sélectionner", :id => "import_type_submit" %> +<% end %> + +<% @available_imports.each do |import| %> +  <%= semantic_form_for [@referential, import], :as => :import, :url => referential_imports_path(@referential), :html => { :id => "#{import.type}_new",  :style => ('display: none' unless @import == import)} do |form| %> + +    <%= form.inputs do %>  +      <%= fields_for_import_type form %> +    <% end %> + +    <%= form.inputs do %>  +      <%= form.input :type, :as => :hidden %> +      <%= form.input :resources, :as => :file %> +    <% end %> -  <%= form.buttons do %> -    <%= form.commit_button true %> -    <li><%= t('or') %></li> -    <li><%= link_to t('cancel'), :back %></li> +    <%= form.buttons do %> +      <%= form.commit_button true %> +      <li><%= t('or') %></li> +      <li><%= link_to t('cancel'), :back %></li> +    <% end %>    <% end %>  <% end %> diff --git a/app/views/journey_patterns/show.kml.erb b/app/views/journey_patterns/show.kml.erb index 6fd8900b6..e08eb2255 100644 --- a/app/views/journey_patterns/show.kml.erb +++ b/app/views/journey_patterns/show.kml.erb @@ -1,16 +1,16 @@  <?xml version="1.0" encoding="UTF-8"?>  <kml xmlns="http://www.opengis.net/kml/2.2">    <Document> -    <Placemark id="route_<%= @journey_pattenr.id %>" > -      <name><%= @journey_pattenr.name %></name> -      <%= @journey_pattenr.geometry.kml_representation.html_safe %> +    <Placemark id="route_<%= @journey_pattern.id %>" > +      <name><%= @journey_pattern.name %></name> +      <%= @journey_pattern.geometry.kml_representation.html_safe %>      </Placemark> -    <% @journey_pattenr.stop_areas.where("latitude is not null and longitude is not null").each_with_index do |stop_area, index| %> +    <% @journey_pattern.stop_areas.where("latitude is not null and longitude is not null").each_with_index do |stop_area, index| %>        <Placemark id="<%= stop_area.id %>" >          <name><%= "#{stop_area.name} (#{index+1})" %></name> -        <% if stop_area.id==@journey_pattenr.stop_areas.first.id %> +        <% if stop_area.id==@journey_pattern.stop_areas.first.id %>          <departure>true</departure> -        <% elsif stop_area.id==@journey_pattenr.stop_areas.last.id %> +        <% elsif stop_area.id==@journey_pattern.stop_areas.last.id %>          <arrival>true</arrival>          <% end %>          <%= stop_area.geometry.kml_representation.html_safe %> diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 4eb3b1b70..437aad3a7 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -45,6 +45,7 @@              <li><%= tab_link_to Chouette::TimeTable, referential_time_tables_path(@referential) %></li>              <li><%= tab_link_to Import, referential_imports_path(@referential) %></li> +            <li><%= tab_link_to Export, referential_exports_path(@referential) %></li>            <% end %>              </ul>        </div> diff --git a/app/views/stop_areas/_stop_area.html.erb b/app/views/stop_areas/_stop_area.html.erb index f3f0b96bf..d34750df6 100644 --- a/app/views/stop_areas/_stop_area.html.erb +++ b/app/views/stop_areas/_stop_area.html.erb @@ -12,8 +12,14 @@        <% end %>      </p>      <p>  -      <%= t('.lines') %> <% stop_area.lines.each do |line| %> -        <span class="line"><%= line.number %></span> +      <% if stop_area.area_type == 'ITL' %> +        <%= t('.lines') %> <% stop_area.routing_lines.each do |line| %> +          <span class="line"><%= line.number %></span> +        <% end %> +      <% else %> +        <%= t('.lines') %> <% stop_area.lines.each do |line| %> +          <span class="line"><%= line.number %></span> +        <% end %>        <% end %>      </p>      <div class="actions">   diff --git a/app/views/stop_areas/add_routing_lines.html.erb b/app/views/stop_areas/add_routing_lines.html.erb new file mode 100644 index 000000000..967d502d8 --- /dev/null +++ b/app/views/stop_areas/add_routing_lines.html.erb @@ -0,0 +1,30 @@ +<%= title_tag t('stop_areas.add_routing_lines.title', :stop_area => @stop_area.name ) %> + +<%= semantic_form_for [@referential, @stop_area] do |form| %> +<div> +  <%= form.inputs do %>  +    <%= form.input :routing_line_ids, :as => :text, :input_html => { :"data-pre" => ( @lines.map { |line| { :id => line.id.to_s, :name => "#{line.number} - #{line.name}" } } ).to_json }  %> +  <% end %>   +   +  <%= form.buttons do %> +    <%= form.commit_button %> +    <%= t('or') %> +    <%= link_to t('cancel'), [@referential, @stop_area] %> +  <% end %> +</div> +<% end %> + +<script> +	$(function() { +		$( "#stop_area_routing_line_ids" ).tokenInput('<%= referential_stop_area_stop_area_routing_lines_path(@referential, @stop_area, :format => :json) %>', {  +       crossDomain: false,  +       prePopulate: $('#stop_area_routing_line_id').data('pre'), +       minChars: 1, +    }); +	}); +</script> +                          +<% content_for :sidebar do %> +<ul class="actions"> +</ul> +<% end %> diff --git a/app/views/stop_areas/add_routing_stops.html.erb b/app/views/stop_areas/add_routing_stops.html.erb new file mode 100644 index 000000000..49c0cad7a --- /dev/null +++ b/app/views/stop_areas/add_routing_stops.html.erb @@ -0,0 +1,30 @@ +<%= title_tag t('stop_areas.add_routing_stops.title', :stop_area => @stop_area.name ) %> + +<%= semantic_form_for [@referential, @stop_area] do |form| %> +<div> +  <%= form.inputs do %>  +    <%= form.input :routing_stop_ids, :as => :text, :input_html => { :"data-pre" => ( @stops.map { |stop| { :id => stop.id.to_s, :name => "#{stop.name} #{stop.country_code}" } } ).to_json }  %> +  <% end %>   +   +  <%= form.buttons do %> +    <%= form.commit_button %> +    <%= t('or') %> +    <%= link_to t('cancel'), [@referential, @stop_area] %> +  <% end %> +</div> +<% end %> + +<script> +	$(function() { +		$( "#stop_area_routing_stop_ids" ).tokenInput('<%= referential_stop_area_stop_area_routing_stops_path(@referential, @stop_area, :format => :json) %>', {  +       crossDomain: false,  +       prePopulate: $('#stop_area_routing_stop_id').data('pre'), +       minChars: 3, +    }); +	}); +</script> +                          +<% content_for :sidebar do %> +<ul class="actions"> +</ul> +<% end %> diff --git a/app/views/stop_areas/show.html.erb b/app/views/stop_areas/show.html.erb index 28867de45..17c074f60 100644 --- a/app/views/stop_areas/show.html.erb +++ b/app/views/stop_areas/show.html.erb @@ -84,7 +84,9 @@    <div class="genealogical"> -    <% if @stop_area.parent.present? || @stop_area.children.present? %> +  	<% if @stop_area.stop_area_type == 'itl' %> +      <h3><%= t(".genealogical_routing") %></h3> +    <% else %>        <h3><%= t(".genealogical") %></h3>      <% end %> @@ -95,15 +97,24 @@        <% end %>      </div>       <div class="link"><%= image_tag "icons/link.png"%></div> +    <% elsif @stop_area.routing_lines.present? %>  +    <div class="lines"> +      <% @stop_area.routing_lines.each do |line| %> +      <div class="line"> +        <%= link_to([@referential, line]) do %>  +          <span><%= line.name %></span>          +        <% end %>   +      </div> +      <% end %> +    </div>  +    <div class="link"><%= image_tag "icons/link.png"%></div>      <% else %>      <div class="no_parent"> </div>      <% end %> -    <% if @stop_area.parent.present? || @stop_area.children.present? %>      <div class="target">        <%= image_tag "map/" + @stop_area.stop_area_type + ".png"%><span><%= @stop_area.name %></span>      </div>  -    <% end %>      <% if @stop_area.children.present? %>      <div class="link"><%= image_tag "icons/link.png"%></div> @@ -116,6 +127,17 @@        </div>        <% end %>      </div>  +    <% elsif @stop_area.routing_stops.present? %> +    <div class="link"><%= image_tag "icons/link.png"%></div> +    <div class="children"> +      <% @stop_area.routing_stops.each do |stop| %> +      <div class="child"> +        <%= link_to([@referential, stop]) do %>  +          <%= image_tag "map/" + stop.stop_area_type + ".png"   %><span><%= stop.name %></span>          +        <% end %>   +      </div> +      <% end %> +    </div>       <% end %>    </div> @@ -125,10 +147,14 @@  <ul class="actions">    <li><%= link_to t('stop_areas.actions.edit'), edit_referential_stop_area_path(@referential, @stop_area), :class => "edit" %></li>    <li><%= link_to  t('stop_areas.actions.destroy'), referential_stop_area_path(@referential, @stop_area), :method => :delete, :confirm =>  t('stop_areas.actions.destroy_confirm'), :class => "remove" %></li> -  <% if @stop_area.stop_area_type != 'itl' %> +  <% if @stop_area.stop_area_type == 'itl' %> +    <li><%= link_to  t('stop_areas.actions.add_routing_lines'), add_routing_lines_referential_stop_area_path(@referential, @stop_area), :class => "add_routing_lines" %></li> +  <% else %>      <li><%= link_to  t('stop_areas.actions.select_parent'), select_parent_referential_stop_area_path(@referential, @stop_area), :class => "select_parent" %></li>    <% end %> -  <% if @stop_area.stop_area_type != 'boarding_position' && @stop_area.stop_area_type != 'quay' %> +  <% if @stop_area.stop_area_type == 'itl' %> +    <li><%= link_to  t('stop_areas.actions.add_routing_stops'), add_routing_stops_referential_stop_area_path(@referential, @stop_area), :class => "add_routing_stops" %></li> +  <% elsif @stop_area.stop_area_type != 'boarding_position' && @stop_area.stop_area_type != 'quay' %>      <li><%= link_to  t('stop_areas.actions.add_children'), add_children_referential_stop_area_path(@referential, @stop_area), :class => "add_children" %></li>    <% end %>    <br> diff --git a/app/views/time_table_periods/_form.html.erb b/app/views/time_table_periods/_form.html.erb index 8369e9701..6f390c7d5 100644 --- a/app/views/time_table_periods/_form.html.erb +++ b/app/views/time_table_periods/_form.html.erb @@ -1,7 +1,7 @@  <%= semantic_form_for [@referential, @time_table, @time_table_period] do |form| %>    <%= form.inputs do %>  -    <%= form.input :periodstart, :as => :date, :label => @time_table_period.human_attribute_name("period_start") %> -    <%= form.input :periodend, :as => :date, :label => @time_table_period.human_attribute_name("period_end") %> +    <%= form.input :period_start, :as => :date, :label => @time_table_period.human_attribute_name("period_start") %> +    <%= form.input :period_end, :as => :date, :label => @time_table_period.human_attribute_name("period_end") %>    <% end %>    <%= form.buttons do %>      <%= form.commit_button %> diff --git a/config/environments/development.rb b/config/environments/development.rb index b6fd603a1..250c17def 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -33,9 +33,9 @@ ChouetteIhm::Application.configure do    config.to_prepare do      chouette_command_script = "tmp/chouette-command/chouette"      if File.exists? chouette_command_script -      Chouette::Loader.chouette_command = "tmp/chouette-command/chouette" +      Chouette::Command.command = "tmp/chouette-command/chouette"      else -      Chouette::Loader.chouette_command = "true" +      Chouette::Command.command = "true"      end    end diff --git a/config/environments/production.rb b/config/environments/production.rb index d79d98df7..ffbd6be76 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -65,7 +65,7 @@ ChouetteIhm::Application.configure do    config.action_mailer.default_url_options = { :host => 'chouette.dryade.net/chouette2' }    config.to_prepare do -    Chouette::Loader.chouette_command = "/usr/local/lib/chouette-command/chouette" +    Chouette::Command.command = "/usr/local/lib/chouette-command/chouette"      Import.root = "/var/lib/chouette/imports"    end diff --git a/config/environments/test.rb b/config/environments/test.rb index 33c54b4f4..b2c29057b 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -38,6 +38,6 @@ ChouetteIhm::Application.configure do    config.active_support.deprecation = :stderr    config.to_prepare do -    Chouette::Loader.chouette_command = "true" +    Chouette::Command.command = "true"    end  end diff --git a/config/initializers/apartment.rb b/config/initializers/apartment.rb index 20263f5c6..4d9b11b3c 100644 --- a/config/initializers/apartment.rb +++ b/config/initializers/apartment.rb @@ -1,6 +1,6 @@  Apartment.configure do |config|    # set your options (described below) here -  config.excluded_models = ["Referential", "User", "Import", "ImportLogMessage", "Delayed::Backend::ActiveRecord::Job"]        # these models will not be multi-tenanted, but remain in the global (public) namespace +  config.excluded_models = ["Referential", "User", "Import", "ImportLogMessage", "Export", "ExportLogMessage", "Delayed::Backend::ActiveRecord::Job"]        # these models will not be multi-tenanted, but remain in the global (public) namespace    # Dynamically get database names to migrate    config.database_names = lambda{ Referential.select(:slug).map(&:slug) } diff --git a/config/initializers/mime_types.rb b/config/initializers/mime_types.rb index 72aca7e44..b93a3824f 100644 --- a/config/initializers/mime_types.rb +++ b/config/initializers/mime_types.rb @@ -3,3 +3,5 @@  # Add new mime types for use in respond_to blocks:  # Mime::Type.register "text/richtext", :rtf  # Mime::Type.register_alias "text/html", :iphone + + Mime::Type.register "application/zip", :zip diff --git a/config/locales/exports.yml b/config/locales/exports.yml new file mode 100644 index 000000000..74b7cd387 --- /dev/null +++ b/config/locales/exports.yml @@ -0,0 +1,79 @@ +en: +  exports: +    actions: +      new: New export +      destroy: Destroy +      destroy_confirm: Are you sure you want destroy this export? +      download: Download +    new: +      title: New export +    index: +      title: Exports +    show: +      report: Report +    statuses: +      pending: Pending +      completed: Completed +      failed: Failed +  export_log_messages: +    messages: +      started: Started export +      completed: Completed export +      failed: Failed export +    severities: +      info: Information +      warning: Warning +      error: Error +  activerecord:         +    models:         +      export: +        zero:  export +        one:   export +        other: exports +    attributes: +      export: +        status: Status +      export_log_message: +        created_at: Date +        position: N. +        full_message: Message +fr: +  exports: +    actions: +      new: Nouvel export +      destroy: Supprimer cet export +      destroy_confirm: Etes vous sûr de détruire cet export ? +      download: Télécharger +    new: +      title: Nouvel export +    index: +      title: Exports +    show: +      report: Rapport +    statuses: +      pending: En cours +      completed: Achevé +      failed: Echoué +  export_log_messages: +    messages: +      started: Export démarré +      completed: Export achevé avec succès +      failed: Export interromptu +    severities: +      info: Information +      warning: Alerte +      error: Erreur +  activerecord:         +    models:         +      export: Export +      neptune_export:  +        zero:  Export Neptune +        one:   Export Neptune +        other: Exports Neptune +    attributes: +      export: +        status: Status +      export_log_message: +        created_at: Date +        position: "No" +        full_message: Message diff --git a/config/locales/imports.yml b/config/locales/imports.yml index 40db6d65e..af8867bc1 100644 --- a/config/locales/imports.yml +++ b/config/locales/imports.yml @@ -19,10 +19,50 @@ en:        started: Started import        completed: Completed import        failed: Failed import +      undefined: %{key} undefined +      NEPTUNE_ONE: Conformité du fichier +      NEPTUNE_Test1_Sheet1: 'Fiche n° 1.1 : Conformité à la syntaxe XML suivant les recommandations du W3C' +      NEPTUNE_Test1_Sheet1_Step1: Conformité à la syntaxe XML +      NEPTUNE_Test1_Sheet1_Step2: Conformité au schéma XML du profil CHOUETTE +      NEPTUNE_TooMuchDetails: ( %{0} erreurs / warnings supplémentaires ) +      NEPTUNE_Test1_Sheet1_Step0_fatal: "Erreur fatale : Impossible d'ouvrir le fichier %{0}" +      NEPTUNE_Test1_Sheet1_Step0_error: "Impossible d'importer cette entrée %{0} du zip" +      NEPTUNE_Test1_Sheet1_Step0_warning: "Cette entrée %{0} du zip n'est pas un fichier xml et a été ignoré" +      NEPTUNE_Test1_Sheet1_Step1_error: "le fichier %{0} n'est pas correctement formé selon les recommandations du W3C" +      NEPTUNE_Test1_Sheet1_Step2_error: "le fichier %{0} ne respecte pas le modèle CHOUETTE" +      NEPTUNE_Test1_Sheet1_Step2_fatal: "Erreur fatale \: Aucune entrée valide trouvée dans le fichier" +      CSV_IMPORT: Import CVS file +      CSV_OK_LINE: line %{0} imported +      CSV_OK_TIMETABLE: timetables %{0} (%{1}) imported +      CSV_OK_PTNETWORK: "network %{0} : %{1} imported" +      CSV_OK_COMPANY: company %{0} imported +      CSV_FILE_NOT_FOUND: "file %{0} : error %{1}" +      CSV_FILE_IGNORED: file %{0} ignored (not XML)  +      CSV_VALIDATION_ERROR: "XML file don't agree with Neptune XSD : %{0}" +      CSV_VALIDATION_CAUSE: %{0} +      CSV_PARSE_OBJECT: Analyse %{0} +      CSV_MANDATORY_TAG: "missing or empty mandatory tag : %{0}" +      CSV_UNKNOWN_ENUM: "Unknown %{0} enumaration value : %{1}" +      CSV_EMPTY_TAG: "empty tag : %{0}" +      CSV_TIMETABLE_COUNT: "timetable count : %{0}" +      CSV_LINE_COUNT: "line count : %{0}" +      CSV_END_OF_FILE: Unexpected end of file +      CSV_BAD_TIMETABLE_PERIODS: Bad timetable periods +      CSV_INVALID_LINE: "invalid line : %{0}" +      CSV_STOP_WITHOUT_COORDS: "Stop without coords : %{0}" +      CSV_VJ_MISSING_TIMETABLE: "Unable to find timetable of vehicle journey : %{0}" +      CSV_FILE_FORMAT: Invalid or deprecated CSV format +      CSV_BAD_ID: "Invalid built Neptune Object ID : %{1} for %{0} " +      CSV_UNUSED_TIMETABLE: Unused timetable %{0} (%{1}) +      SAVE: Save  +      SAVE_OK: %{0} saved      severities:        info: Information +      uncheck: Unchecked +      ok: Ok        warning: Warning        error: Error +      fatal: Fatal    activerecord:              models:                import: @@ -57,11 +97,51 @@ fr:      messages:        started: Import démarré        completed: Import achevé avec succès -      failed: Import interromptu +      failed: Import interrompu +      undefined: %{key} non défini +      NEPTUNE_ONE: Conformité du fichier +      NEPTUNE_Test1_Sheet1: 'Fiche n° 1.1 : Conformité à la syntaxe XML suivant les recommandations du W3C' +      NEPTUNE_Test1_Sheet1_Step1: Conformité à la syntaxe XML +      NEPTUNE_Test1_Sheet1_Step2: Conformité au schéma XML du profil CHOUETTE +      NEPTUNE_TooMuchDetails: ( %{0} erreurs / warnings supplémentaires ) +      NEPTUNE_Test1_Sheet1_Step0_fatal: "Erreur fatale : Impossible d'ouvrir le fichier %{0}" +      NEPTUNE_Test1_Sheet1_Step0_error: "Impossible d'importer cette entrée %{0} du zip" +      NEPTUNE_Test1_Sheet1_Step0_warning: "Cette entrée %{0} du zip n'est pas un fichier xml et a été ignoré" +      NEPTUNE_Test1_Sheet1_Step1_error: "le fichier %{0} n'est pas correctement formé selon les recommandations du W3C" +      NEPTUNE_Test1_Sheet1_Step2_error: "le fichier %{0} ne respecte pas le modèle CHOUETTE" +      NEPTUNE_Test1_Sheet1_Step2_fatal: "Erreur fatale : Aucune entrée valide trouvée dans le fichier" +      CSV_IMPORT: Import de fichier au format CSV +      CSV_OK_LINE: Ligne %{0} importée +      CSV_OK_TIMETABLE: Tableau de marche %{0} (%{1}) importé +      CSV_OK_PTNETWORK: "Réseau %{0} : %{1} importé" +      CSV_OK_COMPANY: "Transporteur %{0} importé" +      CSV_FILE_ERROR: "Fichier %{0} : erreur %{1}" +      CSV_FILE_IGNORED: "Fichier %{0} ignoré (non CSV) " +      CSV_VALIDATION_ERROR: "Fichier CSV ne respecte pas le format Chouette : %{0}" +      CSV_VALIDATION_CAUSE: %{0} +      CSV_PARSE_OBJECT: Analyse %{0} +      CSV_MANDATORY_TAG: "Tag obligatoire absent ou vide : %{0}" +      CSV_UNKNOWN_ENUM: "Valeur de l'enum %{0} inconnue : %{1}" +      CSV_EMPTY_TAG: "Tag vide : %{0}" +      CSV_TIMETABLE_COUNT: "Nombre de tableaux de marche : %{0}" +      CSV_LINE_COUNT: "Nombre de lignes : %{0}" +      CSV_END_OF_FILE: Fichier tronqué +      CSV_BAD_TIMETABLE_PERIODS: Mauvaises périodes dans le tableau de marche +      CSV_INVALID_LINE: "ligne invalide : %{0}" +      CSV_STOP_WITHOUT_COORDS: "Arret sans coordonnées : %{0}" +      CSV_VJ_MISSING_TIMETABLE: "Impossible de trouver le tableau de marche de la course : %{0}" +      CSV_FILE_FORMAT: Format CSV invalide ou obsolète +      CSV_BAD_ID: "Identifiant Neptune produit invalide : %{1} pour %{0} " +      CSV_UNUSED_TIMETABLE: "Tableau de marche %{0} (%{1}) inutilisé" +      SAVE: Sauvegarde  +      SAVE_OK: %{0} enregistré      severities:        info: Information +      uncheck: Non testé +      ok: Ok        warning: Alerte        error: Erreur +      fatal: Fatal    activerecord:              models:                import: diff --git a/config/locales/stop_areas.yml b/config/locales/stop_areas.yml index d6050cc79..2aeb158db 100644 --- a/config/locales/stop_areas.yml +++ b/config/locales/stop_areas.yml @@ -10,6 +10,8 @@ en:        destroy_confirm: Are you sure you want destroy this stop?        select_parent: Manage Parent        add_children: Manage Children +      add_routing_lines: "Manage constraint's lines" +      add_routing_stops: "Manage constraint's stops"      new:        title: Add a new stop      edit: @@ -19,6 +21,7 @@ en:        geographic_data: Geographic data         no_geographic_data: None        genealogical: Links between stop area +      genealogical_routing: "Routing constraint's links"      index:        title: Stop areas        name_or_country_code: Name or Country code @@ -29,6 +32,10 @@ en:        title: Manage parent of stop area %{stop_area}       add_children:        title: Manage children of stop area %{stop_area}  +    add_lines: +      title: Manage lines of routing constraint %{stop_area}  +    add_stops: +      title: Manage stop areas of routing constraint %{stop_area}     activerecord:              models:                stop_area:  @@ -56,6 +63,8 @@ en:          creation_time: Created on          creatorid: Created by           children_ids: Children  +        routing_stop_ids: Attached stops +        routing_line_ids: Attached lines          parent: Parent    formtastic:      hints: @@ -75,6 +84,8 @@ fr:        destroy_confirm: Etes vous sûr de détruire cet arrêt ?        select_parent: Gérer le parent        add_children: Gérer les fils +      add_routing_lines: "Gérer les lignes de l'ITL" +      add_routing_stops: "Gérer les arrêts de l'ITL"      new:        title: Ajouter un arrêt      edit: @@ -84,6 +95,7 @@ fr:        geographic_data: Données géographiques         no_geographic_data: Aucune        genealogical: Lien entre arrêts  +      genealogical_routing: "Liens de l'ITL"      index:        name_or_country_code: Nom ou Code Postal        title: Arrêts @@ -94,6 +106,10 @@ fr:        title: "Gérer le parent de l'arrêt %{stop_area}"      add_children:        title: "Gérer les fils de l'arrêt %{stop_area}" +    add_routing_lines: +      title: "Gérer les lignes de l'ITL %{stop_area} " +    add_routing_stops: +      title: "Gérer les arrêts de l'ITL %{stop_area} "    activerecord:              models:                stop_area:  @@ -122,6 +138,8 @@ fr:          creation_time: Créé le          creator_id: Créé par          children_ids: Fils  +        routing_stop_ids: "Arrêts concernés par l'ITL" +        routing_line_ids: "Lignes affectées par l'ITL"          parent: Parent    formtastic:      hints: diff --git a/config/routes.rb b/config/routes.rb index 82d1e9bee..313c52106 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,8 +1,4 @@  ChouetteIhm::Application.routes.draw do -  get "imports/new" - -  get "imports/index" -    devise_for :users    # The priority is based upon order of creation: @@ -25,9 +21,13 @@ ChouetteIhm::Application.routes.draw do        resources :stop_areas do          resources :stop_area_parents          resources :stop_area_children +        resources :stop_area_routing_lines +        resources :stop_area_routing_stops          member do            get 'add_children'            get 'select_parent' +          get 'add_routing_lines' +          get 'add_routing_stops'          end        end                resources :routes do @@ -46,6 +46,7 @@ ChouetteIhm::Application.routes.draw do      end      resources :imports +    resources :exports      resources :companies, :stop_areas   @@ -58,12 +59,16 @@ ChouetteIhm::Application.routes.draw do      end      resources :stop_areas do -      resources :stop_area_parents  -      resources :stop_area_children -      member do -        get 'add_children' -        get 'select_parent' -      end +        resources :stop_area_parents +        resources :stop_area_children +        resources :stop_area_routing_lines +        resources :stop_area_routing_stops +        member do +          get 'add_children' +          get 'select_parent' +          get 'add_routing_lines' +          get 'add_routing_stops' +        end      end      resources :connection_links do @@ -73,9 +78,14 @@ ChouetteIhm::Application.routes.draw do        end        resources :stop_areas do          resources :stop_area_parents +        resources :stop_area_children +        resources :stop_area_routing_lines +        resources :stop_area_routing_stops          member do            get 'add_children'            get 'select_parent' +          get 'add_routing_lines' +          get 'add_routing_stops'          end        end              end diff --git a/db/migrate/20120607064150_create_exports.rb b/db/migrate/20120607064150_create_exports.rb new file mode 100644 index 000000000..6dda4948e --- /dev/null +++ b/db/migrate/20120607064150_create_exports.rb @@ -0,0 +1,13 @@ +class CreateExports < ActiveRecord::Migration +  def change +    create_table :exports do |t| +      t.belongs_to :referential +      t.string :status +      t.string :type +      t.string :options + +      t.timestamps +    end +    add_index :exports, :referential_id +  end +end diff --git a/db/migrate/20120607064625_create_export_log_messages.rb b/db/migrate/20120607064625_create_export_log_messages.rb new file mode 100644 index 000000000..e4ad03f98 --- /dev/null +++ b/db/migrate/20120607064625_create_export_log_messages.rb @@ -0,0 +1,14 @@ +class CreateExportLogMessages < ActiveRecord::Migration +  def change +    create_table :export_log_messages do |t| +      t.belongs_to :export +      t.string :key +      t.string :arguments +      t.integer :position +      t.string :severity + +      t.timestamps +    end +    add_index :export_log_messages, :export_id +  end +end diff --git a/db/migrate/20120611090254_resize_argument_to_import_log_messages.rb b/db/migrate/20120611090254_resize_argument_to_import_log_messages.rb new file mode 100644 index 000000000..c5636329a --- /dev/null +++ b/db/migrate/20120611090254_resize_argument_to_import_log_messages.rb @@ -0,0 +1,5 @@ +class ResizeArgumentToImportLogMessages < ActiveRecord::Migration +  def change +      change_column :import_log_messages, :arguments, :string, :limit => 1000 +  end +end diff --git a/db/migrate/20120611090325_resize_argument_to_export_log_messages.rb b/db/migrate/20120611090325_resize_argument_to_export_log_messages.rb new file mode 100644 index 000000000..7b51be073 --- /dev/null +++ b/db/migrate/20120611090325_resize_argument_to_export_log_messages.rb @@ -0,0 +1,5 @@ +class ResizeArgumentToExportLogMessages < ActiveRecord::Migration +  def change +      change_column :export_log_messages, :arguments, :string, :limit => 1000 +  end +end diff --git a/db/migrate/20120612071936_add_file_type_to_import.rb b/db/migrate/20120612071936_add_file_type_to_import.rb new file mode 100644 index 000000000..fccd91cce --- /dev/null +++ b/db/migrate/20120612071936_add_file_type_to_import.rb @@ -0,0 +1,8 @@ +class AddFileTypeToImport < ActiveRecord::Migration +  def change +    change_table :imports do |t| +      t.string :file_type +    end +    Import.update_all :file_type => "zip" +  end +end diff --git a/db/schema.rb b/db/schema.rb index d4c07cdc1..7d1d92845 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@  #  # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20120531091529) do +ActiveRecord::Schema.define(:version => 20120612071936) do    create_table "access_links", :force => true do |t|      t.integer  "access_point_id",                        :limit => 8 @@ -120,6 +120,29 @@ ActiveRecord::Schema.define(:version => 20120531091529) do    add_index "delayed_jobs", ["priority", "run_at"], :name => "delayed_jobs_priority" +  create_table "export_log_messages", :force => true do |t| +    t.integer  "export_id" +    t.string   "key" +    t.string   "arguments",  :limit => 1000 +    t.integer  "position" +    t.string   "severity" +    t.datetime "created_at" +    t.datetime "updated_at" +  end + +  add_index "export_log_messages", ["export_id"], :name => "index_export_log_messages_on_export_id" + +  create_table "exports", :force => true do |t| +    t.integer  "referential_id" +    t.string   "status" +    t.string   "type" +    t.string   "options" +    t.datetime "created_at" +    t.datetime "updated_at" +  end + +  add_index "exports", ["referential_id"], :name => "index_exports_on_referential_id" +    create_table "facilities", :force => true do |t|      t.integer  "stop_area_id",       :limit => 8      t.integer  "line_id",            :limit => 8 @@ -170,7 +193,7 @@ ActiveRecord::Schema.define(:version => 20120531091529) do    create_table "import_log_messages", :force => true do |t|      t.integer  "import_id"      t.string   "key" -    t.string   "arguments" +    t.string   "arguments",  :limit => 1000      t.integer  "position"      t.string   "severity"      t.datetime "created_at" @@ -186,6 +209,7 @@ ActiveRecord::Schema.define(:version => 20120531091529) do      t.datetime "updated_at"      t.string   "type"      t.string   "options" +    t.string   "file_type"    end    add_index "imports", ["referential_id"], :name => "index_imports_on_referential_id" @@ -273,6 +297,7 @@ ActiveRecord::Schema.define(:version => 20120531091529) do      t.datetime "updated_at"      t.string   "prefix"      t.string   "projection_type" +    t.string   "bounding_box",    :limit => nil      t.string   "time_zone"    end diff --git a/spec/controllers/exports_controller_spec.rb b/spec/controllers/exports_controller_spec.rb new file mode 100644 index 000000000..e7a49a8e8 --- /dev/null +++ b/spec/controllers/exports_controller_spec.rb @@ -0,0 +1,22 @@ +require 'spec_helper' + +describe ImportsController do +  login_user + +  describe "GET 'new'" do +    it "returns http success" do +      pending +      get 'new' +      response.should be_success +    end +  end + +  describe "GET 'index'" do +    it "returns http success" do +      pending +      get 'index' +      response.should be_success +    end +  end + +end diff --git a/spec/factories.rb b/spec/factories.rb index c36f1c71a..fdd23eded 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -23,4 +23,13 @@ FactoryGirl.define do      f.sequence(:key) { "key_#{n}" }    end +  factory :export do |f| +    f.association :referential +  end + +  factory :export_log_message do |f| +    f.association :export +    f.sequence(:key) { "key_#{n}" } +  end +  end diff --git a/spec/helpers/exports_helper_spec.rb b/spec/helpers/exports_helper_spec.rb new file mode 100644 index 000000000..33257b1d1 --- /dev/null +++ b/spec/helpers/exports_helper_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +# Specs in this file have access to a helper object that includes +# the ExportsHelper. For example: +# +# describe ExportsHelper do +#   describe "string concat" do +#     it "concats two strings with spaces" do +#       helper.concat_strings("this","that").should == "this that" +#     end +#   end +# end +describe ExportsHelper do +  pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/models/csv_import_spec.rb b/spec/models/csv_import_spec.rb new file mode 100644 index 000000000..e169afb5f --- /dev/null +++ b/spec/models/csv_import_spec.rb @@ -0,0 +1,19 @@ +require 'spec_helper' + +describe CsvImport do + +  describe "#objectid_prefix" do + +    it "should be included in options" do +      subject.objectid_prefix = "dummy" +      subject.options.should include "objectid_prefix" => "dummy" +    end + +    it "should be included in import_options" do +      subject.objectid_prefix = "dummy" +      subject.import_options.should include :objectid_prefix => "dummy" +    end +     +  end + +end diff --git a/spec/models/export_log_message_spec.rb b/spec/models/export_log_message_spec.rb new file mode 100644 index 000000000..8aa3cde6e --- /dev/null +++ b/spec/models/export_log_message_spec.rb @@ -0,0 +1,16 @@ +require 'spec_helper' + +describe ExportLogMessage do + +  describe "#attributes" do + +    subject { create :export_log_message } + +    it "should read json stored in database" do +      subject.update_attribute :arguments, { "key" => "value"} +      subject.raw_attributes.should == { "key" => "value"}.to_json +    end + +  end + +end diff --git a/spec/models/export_spec.rb b/spec/models/export_spec.rb new file mode 100644 index 000000000..bccaa4c42 --- /dev/null +++ b/spec/models/export_spec.rb @@ -0,0 +1,63 @@ +require 'spec_helper' + +describe Export do + +  subject { create :export } + +  RSpec::Matchers.define :be_log_message do |expected| +    match do |actual| +      actual and expected.all? { |k,v| actual[k.to_s] == v } +    end +  end +   +  describe "#export" do + +    before(:each) do +      subject.stub :exporter => mock(:export => true) +    end + +    it "should create a ExportLogmessage :started when started" do +      subject.export +      subject.log_messages.first.should be_log_message(:key => "started") +    end + +    it "should create a ExportLogmessage :completed when completed" do +      subject.export +      subject.log_messages.last.should be_log_message(:key => "completed") +    end + +    it "should create a ExportLogmessage :failed when failed" do +      pending +      # subject.loader.stub(:export).and_raise("export failed") +      subject.export +      subject.log_messages.last.should be_log_message(:key => "failed") +    end + +  end + +  describe "#options" do +     +    it "should be empty by default" do +      subject.options.should be_empty +    end + +  end + +  describe ".types" do +     +    it "should return available Export implementations" do +      pending +      Export.types.should =~ %w{NeptuneExport} +    end + +  end + +  describe ".new" do +     +    it "should use type attribute to create a subclass" do +      Export.new(:type => "NeptuneExport").should be_an_instance_of(NeptuneExport) +    end + +  end + +end diff --git a/spec/models/import_spec.rb b/spec/models/import_spec.rb index f0b76c15e..f0a66eb4d 100644 --- a/spec/models/import_spec.rb +++ b/spec/models/import_spec.rb @@ -42,4 +42,20 @@ describe Import do    end +  describe ".types" do +     +    it "should return available Import implementations" do +      Import.types.should =~ %w{NeptuneImport CsvImport} +    end + +  end + +  describe ".new" do +     +    it "should use type attribute to create a subclass" do +      Import.new(:type => "NeptuneImport").should be_an_instance_of(NeptuneImport) +    end + +  end +  end diff --git a/spec/requests/referentials_spec.rb b/spec/requests/referentials_spec.rb index 64a1a26dd..54e63c33c 100644 --- a/spec/requests/referentials_spec.rb +++ b/spec/requests/referentials_spec.rb @@ -13,7 +13,7 @@ describe "Referentials" do      context "when several referentials exist" do -      let(:referentials) {  Array.new(2) { create(:referential) } }  +      let!(:referentials) {  Array.new(2) { create(:referential) } }         it "should show n referentials" do          pending diff --git a/spec/routing/vehicle_journeys_routing_spec.rb b/spec/routing/vehicle_journeys_routing_spec.rb new file mode 100644 index 000000000..9be09d9b1 --- /dev/null +++ b/spec/routing/vehicle_journeys_routing_spec.rb @@ -0,0 +1,13 @@ +require 'spec_helper' + +describe VehicleJourneysController do +  describe "routing" do +    it "routes to #select_journey_pattern" do +      get( "/referentials/1/lines/2/routes/3/vehicle_journeys/4/select_journey_pattern" ).should route_to( +        "vehicle_journeys#select_journey_pattern", +        "referential_id"=>"1", "line_id"=>"2", "route_id"=>"3", "id"=>"4" +      ) +    end +  end +end + diff --git a/spec/views/exports/index.html.erb_spec.rb b/spec/views/exports/index.html.erb_spec.rb new file mode 100644 index 000000000..781b5787b --- /dev/null +++ b/spec/views/exports/index.html.erb_spec.rb @@ -0,0 +1,5 @@ +require 'spec_helper' + +describe "exports/index.html.erb" do +  pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/views/exports/new.html.erb_spec.rb b/spec/views/exports/new.html.erb_spec.rb new file mode 100644 index 000000000..d4a3b255a --- /dev/null +++ b/spec/views/exports/new.html.erb_spec.rb @@ -0,0 +1,5 @@ +require 'spec_helper' + +describe "exports/new.html.erb" do +  pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/views/imports/new.html.erb_spec.rb b/spec/views/imports/new.html.erb_spec.rb index a31539279..f12932353 100644 --- a/spec/views/imports/new.html.erb_spec.rb +++ b/spec/views/imports/new.html.erb_spec.rb @@ -1,5 +1,15 @@  require 'spec_helper'  describe "imports/new.html.erb" do -  pending "add some examples to (or delete) #{__FILE__}" + +  let!(:referential) { assign(:referential, create(:referential)) } +  let!(:import) { assign(:import, NeptuneImport.new) } + +  let!(:available_imports) { assign(:available_imports, []) } + +  it "should display a select to choose import type" do +    render +    rendered.should have_selector("select", :name => "import[type]") +  end +  end | 
