apidae 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: '07291fb2c40fdbc091aff918c45c201602a5d58c'
4
- data.tar.gz: 76f4566eb71404f129add27100872f1263ae868b
3
+ metadata.gz: f69774e7655cd66923973e23882e6d1d0df0cb2a
4
+ data.tar.gz: 199df4ea7f45f563e569f9e1229dfdd012f6a2db
5
5
  SHA512:
6
- metadata.gz: fa72db3de71d37e56b2c8908d703419a72fc5f0efd2d9f03ce91233ae0d68bd402f4a49d775fa22856a2109f83c7bb8bb54593224cc1e14377f696afc2e6d811
7
- data.tar.gz: e1a0c2c71710947ea1b47266e2bb995ba5a44cec98190b3358168e21681ce9b2da4d3c479932514620929da4758affe03cece6e8693cf2f4458e327af108f7a8
6
+ metadata.gz: 671a682f09badf6919a55227c7366478c23bc74456fd58669101ac7a4c9462a5c08cd32a1a58711652bb484c39867c106d338afd9989f08b759af5c4dab375de
7
+ data.tar.gz: f7ba0f5be1b236da982b133e682c454ff251a1848927db75f54dd827ee0367e4b38a2fa93884dc64aebc29d60bfe04a307d25b33a10cc268ddd4ab82ce786ce5
@@ -13,3 +13,12 @@
13
13
  *= require_tree .
14
14
  *= require_self
15
15
  */
16
+
17
+ #apidae_imports_panel > a:first-child {
18
+ float: right;
19
+ }
20
+
21
+ #apidae_form label {
22
+ font-size: 18px;
23
+ margin-right: 1rem;
24
+ }
@@ -16,7 +16,6 @@ module Apidae
16
16
  @objects = SelectionObject.where(apidae_selection_id: selections.map {|s| s.id}.uniq).map {|so| so.apidae_object_id}.uniq.count
17
17
  @last_imports = FileImport.where(apidae_id: apidae_user.apidae_projects_ids).order(id: :desc).take(100)
18
18
  end
19
- @references = Reference.count
20
19
  end
21
20
  end
22
21
  end
@@ -6,6 +6,7 @@ module Apidae
6
6
  class ImportController < ApplicationController
7
7
  skip_before_action :verify_authenticity_token
8
8
  skip_before_action Rails.application.config.apidae_auth
9
+ skip_before_action :check_user_data!
9
10
 
10
11
  # Callback endpoint for Apidae exports
11
12
  #
@@ -36,34 +37,62 @@ module Apidae
36
37
  def run
37
38
  success = true
38
39
  Export.pending.each do |e|
39
- begin
40
- open(e.file_url) do |f|
41
- begin
42
- FileImport.import(f, e.project_id)
40
+ success &&= import_data(e)
41
+ end
42
+ success ? head(:ok) : head(:internal_server_error)
43
+ end
44
+
45
+ def new
46
+ @export = Export.new(status: Export::PENDING)
47
+ end
48
+
49
+ def create
50
+ @export = Export.new(export_params)
51
+ if @export.save && import_data(@export)
52
+ redirect_to apidae.root_url, notice: 'Le fichier a bien été importé.'
53
+ else
54
+ flash.now[:alert] = "Une erreur s'est produite lors de l'import du fichier."
55
+ render :new
56
+ end
57
+ end
58
+
59
+ private
60
+
61
+ def export_params
62
+ params.require(:export).permit(:project_id, :file_url, :status)
63
+ end
64
+
65
+ def import_data(e)
66
+ success = true
67
+ begin
68
+ open(e.file_url) do |f|
69
+ begin
70
+ FileImport.import(f, e.project_id)
71
+ unless e.confirm_url.blank?
43
72
  uri = URI(e.confirm_url)
44
73
  req = Net::HTTP::Post.new(uri)
45
74
  Net::HTTP.start(uri.hostname, uri.port) do |http|
46
75
  http.request(req)
47
76
  end
48
- e.update(status: Export::COMPLETE)
49
- if Rails.application.config.respond_to?(:apidae_import_callback)
50
- Rails.application.config.apidae_import_callback.call(e)
51
- end
52
- rescue Exception => ex
53
- logger.error("Failed to import export file : #{e.file_url}")
54
- logger.error("Error is : #{ex} \n#{ex.backtrace.join("\n") unless ex.backtrace.blank?}")
55
- success = false
56
- e.update(status: Export::CANCELLED)
57
77
  end
78
+ e.update(status: Export::COMPLETE)
79
+ if Rails.application.config.respond_to?(:apidae_import_callback)
80
+ Rails.application.config.apidae_import_callback.call(e)
81
+ end
82
+ rescue Exception => ex
83
+ logger.error("Failed to import export file : #{e.file_url}")
84
+ logger.error("Error is : #{ex} \n#{ex.backtrace.join("\n") unless ex.backtrace.blank?}")
85
+ success = false
86
+ e.update(status: Export::CANCELLED)
58
87
  end
59
- rescue OpenURI::HTTPError => err
60
- logger.error("Failed to download export file : #{e.file_url}")
61
- logger.error("Error is : #{err}")
62
- success = false
63
- e.update(status: Export::CANCELLED)
64
88
  end
89
+ rescue OpenURI::HTTPError => err
90
+ logger.error("Failed to download export file : #{e.file_url}")
91
+ logger.error("Error is : #{err}")
92
+ success = false
93
+ e.update(status: Export::CANCELLED)
65
94
  end
66
- success ? head(:ok) : head(:internal_server_error)
95
+ success
67
96
  end
68
97
  end
69
98
  end
@@ -24,7 +24,7 @@ module Apidae
24
24
  else
25
25
  @project = Project.new(project_params)
26
26
  if @project.save
27
- referrer = (session.delete(:referrer) || projects_url)
27
+ referrer = params[:redirect_to] || session.delete(:referrer) || projects_url
28
28
  redirect_to (referrer + "?apidae_project_id=#{@project.id}"), notice: 'Le projet a bien été créé'
29
29
  else
30
30
  flash.now[:alert] = "Une erreur s'est produite lors la création du projet"
@@ -54,7 +54,7 @@ module Apidae
54
54
 
55
55
  def update_project
56
56
  if @project.update(project_params)
57
- referrer = session.delete(:referrer)
57
+ referrer = params[:redirect_to] || session.delete(:referrer)
58
58
  redirect_to (referrer + "?apidae_project_id=#{@project.id}"), notice: 'Le projet a bien été mis à jour'
59
59
  else
60
60
  flash.now[:alert] = "Une erreur s'est produite lors la mise à jour du projet"
@@ -1,8 +1,25 @@
1
1
  module Apidae
2
2
  class ApidaeDataParser
3
3
  PHONE = 201
4
+ ALT_PHONE = 206
4
5
  EMAIL = 204
5
6
  WEBSITE = 205
7
+ GOOGLE = 3789
8
+ FACEBOOK = 207
9
+ TWITTER = 3755
10
+ YELP = 4007
11
+ TRIP_ADVISOR = 4000
12
+
13
+ CONTACTS_MAP = {
14
+ 'telephone' => PHONE,
15
+ 'email' => EMAIL,
16
+ 'website' => WEBSITE,
17
+ 'facebook' => FACEBOOK,
18
+ 'google' => GOOGLE,
19
+ 'trip_advisor' => TRIP_ADVISOR,
20
+ 'twitter' => TWITTER,
21
+ 'yelp' => YELP
22
+ }
6
23
 
7
24
  MODE_AUTO = 'auto'
8
25
  MODE_MANUAL = 'manual'
@@ -108,7 +125,7 @@ module Apidae
108
125
  url: pic[:traductionFichiers][0][:url].gsub('http:', 'https:'),
109
126
  description: localized_value(pic, :legende, locale),
110
127
  credits: localized_value(pic, :copyright, locale),
111
- expiration_date: pic[:dateLimiteDePublication]
128
+ expiration_date: pic[:dateLimiteDePublication] || ''
112
129
  }
113
130
  end
114
131
  end
@@ -142,15 +159,30 @@ module Apidae
142
159
  contact_entries = information_hash[:moyensCommunication] || []
143
160
  contact_entries.each do |c|
144
161
  case c[:type][:id]
145
- when PHONE
146
- contact_details[:telephone] ||= []
147
- contact_details[:telephone] << c[:coordonnees][:fr]
162
+ when PHONE, ALT_PHONE
163
+ contact_details[:telephone] ||= {}
164
+ contact_details[:telephone][c[:identifiant]] = c[:coordonnees][:fr]
148
165
  when EMAIL
149
- contact_details[:email] ||= []
150
- contact_details[:email] << c[:coordonnees][:fr]
166
+ contact_details[:email] ||= {}
167
+ contact_details[:email][c[:identifiant]] = c[:coordonnees][:fr]
151
168
  when WEBSITE
152
- contact_details[:website] ||= []
153
- contact_details[:website] << c[:coordonnees][:fr]
169
+ contact_details[:website] ||= {}
170
+ contact_details[:website][c[:identifiant]] = c[:coordonnees][:fr]
171
+ when GOOGLE
172
+ contact_details[:google] ||= {}
173
+ contact_details[:google][c[:identifiant]] = c[:coordonnees][:fr]
174
+ when FACEBOOK
175
+ contact_details[:facebook] ||= {}
176
+ contact_details[:facebook][c[:identifiant]] = c[:coordonnees][:fr]
177
+ when TWITTER
178
+ contact_details[:twitter] ||= {}
179
+ contact_details[:twitter][c[:identifiant]] = c[:coordonnees][:fr]
180
+ when YELP
181
+ contact_details[:yelp] ||= {}
182
+ contact_details[:yelp][c[:identifiant]] = c[:coordonnees][:fr]
183
+ when TRIP_ADVISOR
184
+ contact_details[:trip_advisor] ||= {}
185
+ contact_details[:trip_advisor][c[:identifiant]] = c[:coordonnees][:fr]
154
186
  else
155
187
  end
156
188
  end
@@ -189,7 +221,8 @@ module Apidae
189
221
  openings_desc: node_value(openings_hash, :periodeEnClair, *locales),
190
222
  openings_desc_mode: openings_hash[:periodeEnClairGenerationMode] == 'AUTOMATIQUE' ? MODE_AUTO : MODE_MANUAL,
191
223
  openings: build_openings(openings_hash, *locales),
192
- time_periods: lists_ids(openings_hash[:indicationsPeriode])
224
+ time_periods: lists_ids(openings_hash[:indicationsPeriode]),
225
+ openings_extra: lists_ids(openings_hash[:ouverturesComplementaires])
193
226
  }
194
227
  end
195
228
  end
@@ -229,7 +262,8 @@ module Apidae
229
262
  track: apidae_obj.apidae_type == Obj::EQU ? data_hash[:itineraire] : nil,
230
263
  products: lists_ids(data_hash[:typesProduit], data_hash[:aopAocIgps], data_hash[:specialites]),
231
264
  audience: lists_ids(prestations_hash[:typesClientele]),
232
- animals: prestations_hash[:animauxAcceptes] == 'ACCEPTES',
265
+ animals: {allowed: prestations_hash[:animauxAcceptes] == 'ACCEPTES', desc: node_value(prestations_hash, :descriptifAnimauxAcceptes, *locales),
266
+ fee: prestations_hash[:animauxAcceptesSupplement] == 'AVEC_SUPPLEMENT'},
233
267
  extra: apidae_obj.apidae_type == Obj::SPA ? node_value(data_hash, :formuleHebergement, *locales) : node_value(prestations_hash, :complementAccueil, *locales),
234
268
  duration: apidae_obj.apidae_type == Obj::SPA ? {days: data_hash[:nombreJours], nights: data_hash[:nombreNuits]} : data_hash[:dureeSeance],
235
269
  certifications: data_hash[:agrements].blank? ? [] : data_hash[:agrements].map {|a| {id: a[:type][:id], identifier: a[:numero]}},
@@ -316,6 +350,7 @@ module Apidae
316
350
  external_id: o[:identifiantTechnique],
317
351
  start_date: o[:dateDebut],
318
352
  end_date: o[:dateFin],
353
+ each_year: o[:tousLesAns],
319
354
  closing_days: closing_days.blank? ? [] : closing_days.map {|d| d[:dateSpeciale]},
320
355
  details: node_value(o, :complementHoraire, *locales),
321
356
  time_periods: [
@@ -5,6 +5,8 @@ module Apidae
5
5
  COMPLETE = 'complete'
6
6
  CANCELLED = 'cancelled'
7
7
 
8
+ validates_presence_of :file_url, :project_id
9
+
8
10
  # Note : handle reset case
9
11
  def self.pending
10
12
  where(remote_status: 'SUCCESS', status: PENDING).order(:id)
@@ -14,11 +14,11 @@ module Apidae
14
14
  store_accessor :pictures_data, :pictures
15
15
  store_accessor :attachments_data, :attachments
16
16
  store_accessor :type_data, :categories, :themes, :capacity, :classification, :labels, :chains, :area, :track,
17
- :products, :audience, :animals, :extra, :duration, :certifications, :business
17
+ :products, :audience, :animals, :animals_desc, :extra, :duration, :certifications, :business
18
18
  store_accessor :entity_data, :entity_id, :entity_name, :service_provider_id
19
- store_accessor :contact_data, :telephone, :email, :website, :contacts
19
+ store_accessor :contact_data, :telephone, :email, :website, :google, :facebook, :twitter, :yelp, :trip_advisor, :contacts
20
20
  store_accessor :location_data, :address, :place, :latitude, :longitude, :access, :territories, :environments
21
- store_accessor :openings_data, :openings_desc, :openings_desc_mode, :openings, :time_periods
21
+ store_accessor :openings_data, :openings_desc, :openings_desc_mode, :openings, :time_periods, :openings_extra
22
22
  store_accessor :rates_data, :rates_desc, :rates_desc_mode, :rates, :payment_methods, :includes, :excludes
23
23
  store_accessor :service_data, :services, :equipments, :comfort, :activities, :challenged, :languages
24
24
  store_accessor :booking_data, :booking_desc, :booking_entities
@@ -122,6 +122,18 @@ module Apidae
122
122
  self
123
123
  end
124
124
 
125
+ def dig(*keys)
126
+ root_key, *nested_keys = keys
127
+ root_val = self.send(root_key)
128
+ if root_val.blank?
129
+ nested_keys.blank? ? root_val : nil
130
+ elsif root_val.respond_to?(:dig)
131
+ root_val.dig(*nested_keys)
132
+ else
133
+ raise ArgumentError.new('Cannot call dig with these args')
134
+ end
135
+ end
136
+
125
137
  def self.default_scope
126
138
  where(root_obj_id: nil)
127
139
  end
@@ -5,6 +5,10 @@ module Apidae
5
5
 
6
6
  store_accessor :meta_data, :category, :parent
7
7
 
8
+ def self.default_scope
9
+ where(is_active: true)
10
+ end
11
+
8
12
  def self.import(refs_json)
9
13
  locales = Rails.application.config.respond_to?(:apidae_locales) ? Rails.application.config.apidae_locales : [DEFAULT_LOCALE]
10
14
  locales_map = Hash[locales.map {|loc| ["libelle#{loc.camelize.gsub('-', '')}".to_sym, loc]}]
@@ -15,6 +19,7 @@ module Apidae
15
19
  ref.label_data = ref_data.slice(*locales_map.keys).transform_keys {|k| locales_map[k]}
16
20
  ref.parent = ref_data[:parent][:id] if ref_data[:parent]
17
21
  ref.category = ref_data[:familleCritere] ? ref_data[:familleCritere][:id] : (ref_data[:typeLabel] ? ref_data[:typeLabel][:id] : nil)
22
+ ref.is_active = ref_data[:actif]
18
23
  ref.save!
19
24
  end
20
25
  end
@@ -3,13 +3,20 @@
3
3
  <%= link_to pluralize(@projects, 'projet', 'projets'), apidae.projects_path, class: styles[:projects] %>
4
4
  <%= link_to pluralize(@selections, 'sélection', 'sélections'), apidae.selections_path, class: styles[:selections] %>
5
5
  <%= link_to pluralize(@objects, 'objet touristique', 'objets touristiques'), apidae.objects_path, class: styles[:objects] %>
6
- <%= link_to (pluralize(@references, 'élément', 'éléments') + ' de référence'), apidae.references_path, class: styles[:references] %>
7
6
  <%= link_to 'Retour', :back, class: styles[:back] %>
8
7
  <h1 class="<%= styles[:h1] %>">Apidae</h1>
9
8
  </div>
10
9
  <div id="apidae_dashboard" class="<%= styles[:wrapper] %>">
11
10
  <div id="apidae_imports_panel" class="<%= styles[:body] %>">
11
+ <%= link_to 'Importer un fichier', apidae.import_new_path, class: styles[:projects] %>
12
12
  <h2 class="<%= styles[:h2] %>">Derniers imports</h2>
13
+ <p>
14
+ Les imports provenant de vos projets Apidae apparaîtront ci-dessous. Pour que les données soient importées correctement,
15
+ vos projets doivent être configurés pour exporter les données au format <strong>JSON V2</strong>, en
16
+ <strong>groupant les objets exportés</strong>.<br/>
17
+ Si vous souhaitez que chaque export soit récupéré automatiquement, veillez à renseigner le paramètre
18
+ <strong>Url de notification</strong> avec la valeur <strong><%= apidae.import_callback_url %></strong>.
19
+ </p>
13
20
  <table id="apidae_imports" class="<%= styles[:table] %>">
14
21
  <thead class="<%= styles[:table_head] %>">
15
22
  <tr>
@@ -0,0 +1,29 @@
1
+ <%= form_for(@export, url: apidae.import_create_path, method: :post, html: {class: styles[:form]}) do |f| %>
2
+ <% if @export.errors.any? %>
3
+ <div id="apidae_form_errors">
4
+ <ul>
5
+ <% @export.errors.full_messages.each do |message| %>
6
+ <li><%= message %></li>
7
+ <% end %>
8
+ </ul>
9
+ </div>
10
+ <% end %>
11
+ <p>
12
+ Pour que les données soient importées correctement,
13
+ vos projets doivent être configurés pour exporter les données au format <strong>JSON V2</strong>, en
14
+ <strong>groupant les objets exportés</strong>.
15
+ </p>
16
+
17
+ <div class="<%= styles[:form_field] %>">
18
+ <div><%= f.label :project_id %></div>
19
+ <div><%= f.text_field :project_id, placeholder: "Ex: 1234" %></div>
20
+ </div>
21
+ <div class="<%= styles[:form_field] %>">
22
+ <div><%= f.label :file_url %></div>
23
+ <div><%= f.text_field :file_url, placeholder: "Ex: http://export.apidae-tourisme.com/exports/1234_20200101-5678_ABCdef.zip" %></div>
24
+ </div>
25
+ <%= f.hidden_field :status %>
26
+ <div class="<%= styles[:form_actions] %>">
27
+ <%= f.submit 'Valider' %> | <%= link_to 'Retour', :back, class: styles[:back] %>
28
+ </div>
29
+ <% end %>
@@ -0,0 +1,11 @@
1
+ <%= render layout: "/layouts/#{Rails.application.config.apidae_layout}" do |styles| %>
2
+ <div id="apidae_header" class="<%= styles[:header] %>">
3
+ <%= link_to 'Retour', :back, class: styles[:back] %>
4
+ <h1 class="<%= styles[:h1] %>">Apidae - Importer un fichier de données</h1>
5
+ </div>
6
+ <div id="apidae_import" class="<%= styles[:wrapper] %>">
7
+ <div id="apidae_form" class="<%= styles[:body] %>">
8
+ <%= render 'form', styles: styles %>
9
+ </div>
10
+ </div>
11
+ <% end %>
@@ -10,12 +10,21 @@ fr:
10
10
  apidae/obj:
11
11
  apidae_id: Identifiant Apidae
12
12
  selection_apidae_id: Sélection Apidae
13
+ apidae/export:
14
+ project_id: Identifiant du projet
15
+ file_url: URL du fichier d'export
13
16
  errors:
14
17
  models:
15
18
  apidae/project:
16
19
  attributes:
17
20
  apidae_id:
18
21
  taken: Un projet avec cet identifiant Apidae existe déjà.
22
+ apidae/export:
23
+ attributes:
24
+ file_url:
25
+ blank: est requise
26
+ project_id:
27
+ blank: est requis
19
28
  apidae:
20
29
  file_import:
21
30
  status:
@@ -39,4 +48,21 @@ fr:
39
48
  HANDICAP: Handicap
40
49
  TOURISME_AFFAIRES: Affaires
41
50
  GROUPES: Groupes
42
- PRESTATAIRE_ACTIVITES: Prestataire d'activités
51
+ PRESTATAIRE_ACTIVITES: Prestataire d'activités
52
+ types:
53
+ ACTIVITE: Activités
54
+ COMMERCE_ET_SERVICE: Commerces et services
55
+ DEGUSTATION: Producteurs
56
+ DOMAINE_SKIABLE: Domaines skiables
57
+ EQUIPEMENT: Équipements
58
+ FETE_ET_MANIFESTATION: Fêtes et manifestations
59
+ HEBERGEMENT_COLLECTIF: Hébergements collectifs
60
+ HEBERGEMENT_LOCATIF: Hébergements locatifs
61
+ HOTELLERIE: Hôtellerie
62
+ HOTELLERIE_PLEIN_AIR: Hôtellerie de plein air
63
+ PATRIMOINE_CULTUREL: Patrimoine culturel
64
+ PATRIMOINE_NATUREL: Patrimoine naturel
65
+ RESTAURATION: Restauration
66
+ SEJOUR_PACKAGE: Séjour et produits packagés
67
+ STRUCTURE: Entité juridique
68
+ TERRITOIRE: Territoire
@@ -15,6 +15,8 @@ Apidae::Engine.routes.draw do
15
15
 
16
16
  match 'import/callback', via: :post, to: 'import#callback'
17
17
  match 'import/run', via: :post, to: 'import#run'
18
+ match 'import/new', via: :get, to: 'import#new'
19
+ match 'import/create', via: :post, to: 'import#create'
18
20
 
19
21
  root to: 'dashboard#index'
20
22
  end
@@ -0,0 +1,6 @@
1
+ class AddIsActiveToApidaeReferences < ActiveRecord::Migration[5.2]
2
+ def change
3
+ add_column :apidae_references, :is_active, :boolean
4
+ add_index :apidae_references, :is_active, unique: false
5
+ end
6
+ end
@@ -1,3 +1,3 @@
1
1
  module Apidae
2
- VERSION = "1.0.0"
2
+ VERSION = "1.1.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: apidae
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jean-Baptiste Vilain
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-22 00:00:00.000000000 Z
11
+ date: 2020-06-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '0'
61
+ version: '2.5'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '0'
68
+ version: '2.5'
69
69
  description: To be completed
70
70
  email:
71
71
  - jbvilain@gmail.com
@@ -106,7 +106,9 @@ files:
106
106
  - app/models/apidae/selection_object.rb
107
107
  - app/models/apidae/town.rb
108
108
  - app/views/apidae/dashboard/index.html.erb
109
+ - app/views/apidae/import/_form.html.erb
109
110
  - app/views/apidae/import/callback.html.erb
111
+ - app/views/apidae/import/new.html.erb
110
112
  - app/views/apidae/objects/_form.html.erb
111
113
  - app/views/apidae/objects/edit.html.erb
112
114
  - app/views/apidae/objects/index.html.erb
@@ -178,6 +180,7 @@ files:
178
180
  - db/migrate/20200312150008_add_version_data_to_apidae_objs.rb
179
181
  - db/migrate/20200312150904_add_version_index_on_apidae_objs.rb
180
182
  - db/migrate/20200522124205_rename_objs_contact_to_contact_data.rb
183
+ - db/migrate/20200528101957_add_is_active_to_apidae_references.rb
181
184
  - lib/apidae.rb
182
185
  - lib/apidae/engine.rb
183
186
  - lib/apidae/version.rb