apidae 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +3 -0
- data/Rakefile +37 -0
- data/app/assets/javascripts/apidae/application.js +13 -0
- data/app/assets/stylesheets/apidae/application.css +15 -0
- data/app/controllers/apidae/application_controller.rb +5 -0
- data/app/controllers/apidae/objects_controller.rb +62 -0
- data/app/controllers/apidae/selections_controller.rb +62 -0
- data/app/helpers/apidae/application_helper.rb +4 -0
- data/app/helpers/apidae/objects_helper.rb +4 -0
- data/app/helpers/apidae/selections_helper.rb +4 -0
- data/app/models/apidae/attached_file.rb +31 -0
- data/app/models/apidae/object.rb +217 -0
- data/app/models/apidae/selection.rb +89 -0
- data/app/models/apidae/town.rb +18 -0
- data/app/views/apidae/objects/_form.html.erb +73 -0
- data/app/views/apidae/objects/edit.html.erb +6 -0
- data/app/views/apidae/objects/index.html.erb +53 -0
- data/app/views/apidae/objects/new.html.erb +5 -0
- data/app/views/apidae/objects/show.html.erb +74 -0
- data/app/views/apidae/selections/_form.html.erb +29 -0
- data/app/views/apidae/selections/edit.html.erb +6 -0
- data/app/views/apidae/selections/index.html.erb +31 -0
- data/app/views/apidae/selections/new.html.erb +5 -0
- data/app/views/apidae/selections/show.html.erb +19 -0
- data/app/views/layouts/apidae/application.html.erb +14 -0
- data/config/routes.rb +4 -0
- data/db/migrate/20170512212941_create_apidae_selections.rb +11 -0
- data/db/migrate/20170512214641_create_apidae_objects.rb +22 -0
- data/db/migrate/20170512221525_create_apidae_objects_apidae_selections.rb +8 -0
- data/db/migrate/20170513114002_create_apidae_towns.rb +15 -0
- data/db/migrate/20170513114409_add_town_insee_code_to_objects.rb +5 -0
- data/db/migrate/20170513115401_add_pictures_data_to_objects.rb +5 -0
- data/db/migrate/20170513121215_create_apidae_attached_files.rb +13 -0
- data/db/migrate/20170513205932_rename_objects_selections_table.rb +5 -0
- data/lib/apidae/engine.rb +5 -0
- data/lib/apidae/version.rb +3 -0
- data/lib/apidae.rb +4 -0
- data/lib/tasks/apidae_tasks.rake +4 -0
- data/test/apidae_test.rb +7 -0
- data/test/controllers/apidae/objects_controller_test.rb +52 -0
- data/test/controllers/apidae/selections_controller_test.rb +52 -0
- data/test/dummy/README.rdoc +28 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/javascripts/application.js +13 -0
- data/test/dummy/app/assets/stylesheets/application.css +15 -0
- data/test/dummy/app/controllers/application_controller.rb +5 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/bin/setup +29 -0
- data/test/dummy/config/application.rb +26 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/database.yml +20 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +41 -0
- data/test/dummy/config/environments/production.rb +79 -0
- data/test/dummy/config/environments/test.rb +42 -0
- data/test/dummy/config/initializers/assets.rb +11 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +4 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/to_time_preserves_timezone.rb +10 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/routes.rb +4 -0
- data/test/dummy/config/secrets.yml +22 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/db/schema.rb +64 -0
- data/test/dummy/log/development.log +121 -0
- data/test/dummy/log/test.log +7 -0
- data/test/dummy/public/404.html +67 -0
- data/test/dummy/public/422.html +67 -0
- data/test/dummy/public/500.html +66 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/fixtures/apidae/attached_files.yml +9 -0
- data/test/fixtures/apidae/objects.yml +33 -0
- data/test/fixtures/apidae/selections.yml +11 -0
- data/test/fixtures/apidae/towns.yml +15 -0
- data/test/integration/navigation_test.rb +8 -0
- data/test/models/apidae/attached_file_test.rb +9 -0
- data/test/models/apidae/object_test.rb +9 -0
- data/test/models/apidae/selection_test.rb +9 -0
- data/test/models/apidae/town_test.rb +9 -0
- data/test/test_helper.rb +21 -0
- metadata +227 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 63b211aee25599748e88d29aac6ce145b432b307
|
4
|
+
data.tar.gz: dd74e76a618885e9dbc6306fbe2b96c0db6b15ee
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b877a7868af4dee3939ae6e1faabeb881a30abaf9a0a1e71f3d4b42e50656e9c2cba7a0b471f09806bafb81a131f5cddb32107b75108357ba52cecf04803f68c
|
7
|
+
data.tar.gz: d2c6fb144801f332f1e5b2dac5f100aa6a8cc80c0174146fcc3d2ec799e368655dfc2e2a7b3af2ba511a3a4d6be98d8c54805f673453bd7d5726e093fa73f746
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2017 Jean-Baptiste Vilain
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'Apidae'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.rdoc')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
|
18
|
+
load 'rails/tasks/engine.rake'
|
19
|
+
|
20
|
+
|
21
|
+
load 'rails/tasks/statistics.rake'
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
Bundler::GemHelper.install_tasks
|
26
|
+
|
27
|
+
require 'rake/testtask'
|
28
|
+
|
29
|
+
Rake::TestTask.new(:test) do |t|
|
30
|
+
t.libs << 'lib'
|
31
|
+
t.libs << 'test'
|
32
|
+
t.pattern = 'test/**/*_test.rb'
|
33
|
+
t.verbose = false
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
task default: :test
|
@@ -0,0 +1,13 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// compiled file.
|
9
|
+
//
|
10
|
+
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
|
11
|
+
// about supported directives.
|
12
|
+
//
|
13
|
+
//= require_tree .
|
@@ -0,0 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any styles
|
10
|
+
* defined in the other CSS/SCSS files in this directory. It is generally better to create a new
|
11
|
+
* file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require_dependency "apidae/application_controller"
|
2
|
+
|
3
|
+
module Apidae
|
4
|
+
class ObjectsController < ApplicationController
|
5
|
+
before_action :set_object, only: [:show, :edit, :update, :destroy]
|
6
|
+
|
7
|
+
# GET /objects
|
8
|
+
def index
|
9
|
+
@objects = Object.all
|
10
|
+
end
|
11
|
+
|
12
|
+
# GET /objects/1
|
13
|
+
def show
|
14
|
+
end
|
15
|
+
|
16
|
+
# GET /objects/new
|
17
|
+
def new
|
18
|
+
@object = Object.new
|
19
|
+
end
|
20
|
+
|
21
|
+
# GET /objects/1/edit
|
22
|
+
def edit
|
23
|
+
end
|
24
|
+
|
25
|
+
# POST /objects
|
26
|
+
def create
|
27
|
+
@object = Object.new(object_params)
|
28
|
+
|
29
|
+
if @object.save
|
30
|
+
redirect_to @object, notice: 'Object was successfully created.'
|
31
|
+
else
|
32
|
+
render :new
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# PATCH/PUT /objects/1
|
37
|
+
def update
|
38
|
+
if @object.update(object_params)
|
39
|
+
redirect_to @object, notice: 'Object was successfully updated.'
|
40
|
+
else
|
41
|
+
render :edit
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# DELETE /objects/1
|
46
|
+
def destroy
|
47
|
+
@object.destroy
|
48
|
+
redirect_to objects_url, notice: 'Object was successfully destroyed.'
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
# Use callbacks to share common setup or constraints between actions.
|
53
|
+
def set_object
|
54
|
+
@object = Object.find(params[:id])
|
55
|
+
end
|
56
|
+
|
57
|
+
# Only allow a trusted parameter "white list" through.
|
58
|
+
def object_params
|
59
|
+
params.require(:object).permit(:address, :apidae_id, :apidae_type, :apidae_subtype, :title, :short_desc, :contact, :long_desc, :type_data, :latitude, :longitude, :openings, :rates, :reservation)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require_dependency "apidae/application_controller"
|
2
|
+
|
3
|
+
module Apidae
|
4
|
+
class SelectionsController < ApplicationController
|
5
|
+
before_action :set_selection, only: [:show, :edit, :update, :destroy]
|
6
|
+
|
7
|
+
# GET /selections
|
8
|
+
def index
|
9
|
+
@selections = Selection.all
|
10
|
+
end
|
11
|
+
|
12
|
+
# GET /selections/1
|
13
|
+
def show
|
14
|
+
end
|
15
|
+
|
16
|
+
# GET /selections/new
|
17
|
+
def new
|
18
|
+
@selection = Selection.new
|
19
|
+
end
|
20
|
+
|
21
|
+
# GET /selections/1/edit
|
22
|
+
def edit
|
23
|
+
end
|
24
|
+
|
25
|
+
# POST /selections
|
26
|
+
def create
|
27
|
+
@selection = Selection.new(selection_params)
|
28
|
+
|
29
|
+
if @selection.save
|
30
|
+
redirect_to @selection, notice: 'Selection was successfully created.'
|
31
|
+
else
|
32
|
+
render :new
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# PATCH/PUT /selections/1
|
37
|
+
def update
|
38
|
+
if @selection.update(selection_params)
|
39
|
+
redirect_to @selection, notice: 'Selection was successfully updated.'
|
40
|
+
else
|
41
|
+
render :edit
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# DELETE /selections/1
|
46
|
+
def destroy
|
47
|
+
@selection.destroy
|
48
|
+
redirect_to selections_url, notice: 'Selection was successfully destroyed.'
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
# Use callbacks to share common setup or constraints between actions.
|
53
|
+
def set_selection
|
54
|
+
@selection = Selection.find(params[:id])
|
55
|
+
end
|
56
|
+
|
57
|
+
# Only allow a trusted parameter "white list" through.
|
58
|
+
def selection_params
|
59
|
+
params.require(:selection).permit(:label, :reference, :apidae_id)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Apidae
|
2
|
+
class AttachedFile < ActiveRecord::Base
|
3
|
+
belongs_to :apidae_object, :class_name => 'Apidae::Object'
|
4
|
+
|
5
|
+
has_attached_file :picture,
|
6
|
+
{
|
7
|
+
:styles => {
|
8
|
+
:xlarge => ['1600x1200>', :jpg],
|
9
|
+
:large => ['1280x960>', :jpg],
|
10
|
+
:medium => ['800x600>', :jpg],
|
11
|
+
:small => ['320x240', :jpg],
|
12
|
+
:thumb => ['200x200>', :png]
|
13
|
+
},
|
14
|
+
:default_url => "/#{Rails.application.config.apidae_pictures_path}/default/logo.png",
|
15
|
+
:path => "public/#{Rails.application.config.apidae_pictures_path}/:apidae_type/:apidae_id/:basename.:extension",
|
16
|
+
:url => "/#{Rails.application.config.apidae_pictures_path}/:apidae_type/:apidae_id/:basename.:extension"
|
17
|
+
}
|
18
|
+
|
19
|
+
validates_attachment :picture, content_type: { content_type: /\Aimage\/.*\Z/ }
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
Paperclip.interpolates :apidae_type do |attachment, style|
|
24
|
+
attachment.instance.apidae_object.apidae_type.downcase
|
25
|
+
end
|
26
|
+
|
27
|
+
Paperclip.interpolates :apidae_id do |attachment, style|
|
28
|
+
attachment.instance.apidae_object.apidae_id
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,217 @@
|
|
1
|
+
module Apidae
|
2
|
+
class Object < ActiveRecord::Base
|
3
|
+
|
4
|
+
belongs_to :town, :class_name => 'Apidae::Town', foreign_key: :town_insee_code, primary_key: :insee_code
|
5
|
+
has_many :attached_files, :class_name => 'Apidae::AttachedFile'
|
6
|
+
has_and_belongs_to_many :selections, :class_name => 'Apidae::Selection'
|
7
|
+
|
8
|
+
store :pictures_data, accessors: [:pictures], coder: JSON
|
9
|
+
store :type_data, accessors: [:categories, :themes], coder: JSON
|
10
|
+
store :contact, accessors: [:telephone, :email, :website], coder: JSON
|
11
|
+
store :address, accessors: [:address_fields], coder: JSON
|
12
|
+
store :openings, accessors: [:description, :opening_periods], coder: JSON
|
13
|
+
|
14
|
+
TYPES_DATA = {
|
15
|
+
'ACTIVITE' => {node: :informationsActivite, subtype: :activiteType},
|
16
|
+
'COMMERCE_ET_SERVICE' => {node: :informationsCommerceEtService, subtype: :commerceEtServiceType},
|
17
|
+
'DEGUSTATION' => {node: :informationsDegustation, subtype: :degustationType},
|
18
|
+
'DOMAINE_SKIABLE' => {node: :informationsDomaineSkiable, subtype: :domaineSkiableType},
|
19
|
+
'EQUIPEMENT' => {node: :informationsEquipement, subtype: :equipementType},
|
20
|
+
'FETE_ET_MANIFESTATION' => {node: :informationsFeteEtManifestation, subtype: :feteEtManifestationType},
|
21
|
+
'HEBERGEMENT_COLLECTIF' => {node: :informationsHebergementCollectif, subtype: :hebergementCollectifType},
|
22
|
+
'HEBERGEMENT_LOCATIF' => {node: :informationsHebergementLocatif, subtype: :hebergementLocatifType},
|
23
|
+
'HOTELLERIE' => {node: :informationsHotellerie, subtype: :hotellerieType},
|
24
|
+
'HOTELLERIE_PLEIN_AIR' => {node: :informationsHotelleriePleinAir, subtype: :hotelleriePleinAirType},
|
25
|
+
'PATRIMOINE_CULTUREL' => {node: :informationsPatrimoineCulturel, subtype: :patrimoineCulturelType},
|
26
|
+
'PATRIMOINE_NATUREL' => {node: :informationsPatrimoineNaturel, subtype: :patrimoineNaturelType},
|
27
|
+
'RESTAURATION' => {node: :informationsRestauration, subtype: :restaurationType},
|
28
|
+
'SEJOUR_PACKAGE' => {node: :informationsSejourPackage, subtype: :sejourPackageType},
|
29
|
+
'STRUCTURE' => {node: :informationsStructure, subtype: :structureType},
|
30
|
+
'TERRITOIRE' => {node: :informationsTerritoire, subtype: :territoireType}
|
31
|
+
}
|
32
|
+
|
33
|
+
PHONE = 201
|
34
|
+
EMAIL = 204
|
35
|
+
WEBSITE = 205
|
36
|
+
|
37
|
+
|
38
|
+
def self.import(json_dir)
|
39
|
+
result = false
|
40
|
+
if Dir.exist?(json_dir)
|
41
|
+
Dir.foreach(json_dir) do |f|
|
42
|
+
if f.end_with?('.json')
|
43
|
+
json_file = File.join(json_dir, f)
|
44
|
+
objects_json = File.read(json_file)
|
45
|
+
objects_hashes = JSON.parse(objects_json, symbolize_names: true)
|
46
|
+
objects_hashes.each do |object_data|
|
47
|
+
type_fields = TYPES_DATA[object_data[:type]]
|
48
|
+
existing_obj = Apidae::Object.find_by_apidae_id(object_data[:id])
|
49
|
+
unless existing_obj
|
50
|
+
Apidae::Object.create!(
|
51
|
+
apidae_id: object_data[:id],
|
52
|
+
apidae_type: object_data[:type],
|
53
|
+
apidae_subtype: node_value(object_data[type_fields[:node]], object_data[type_fields[:subtype]]),
|
54
|
+
title: node_value(object_data, :nom),
|
55
|
+
short_desc: node_value(object_data[:presentation], :descriptifCourt),
|
56
|
+
long_desc: node_value(object_data[:presentation], :descriptifDetaille),
|
57
|
+
contact: contact(object_data[:informations]),
|
58
|
+
address: address(object_data[:localisation][:adresse]),
|
59
|
+
town: town(object_data[:localisation][:adresse]),
|
60
|
+
latitude: latitude(object_data[:localisation]),
|
61
|
+
longitude: longitude(object_data[:localisation]),
|
62
|
+
openings: openings(object_data[:ouverture]),
|
63
|
+
rates: rates(object_data[:descriptionTarif]),
|
64
|
+
reservation: reservation(object_data[:reservation]),
|
65
|
+
type_data: object_data[type_fields[:node]],
|
66
|
+
pictures_data: pictures_urls(object_data[:illustrations])
|
67
|
+
)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
result = true
|
72
|
+
end
|
73
|
+
result
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.update_fields(json_dir)
|
78
|
+
result = false
|
79
|
+
if Dir.exist?(json_dir)
|
80
|
+
Dir.foreach(json_dir) do |f|
|
81
|
+
if f.end_with?('.json')
|
82
|
+
json_file = File.join(json_dir, f)
|
83
|
+
objects_json = File.read(json_file)
|
84
|
+
objects_hashes = JSON.parse(objects_json, symbolize_names: true)
|
85
|
+
objects_hashes.each do |object_data|
|
86
|
+
obj = Apidae::Object.find_by_apidae_id(object_data[:id])
|
87
|
+
if obj
|
88
|
+
yield(obj, object_data)
|
89
|
+
obj.save!
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
result = true
|
94
|
+
end
|
95
|
+
result
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def self.load_pictures
|
100
|
+
Object.all.each do |obj|
|
101
|
+
if obj.apidae_attached_files.blank? && obj.pictures.any?
|
102
|
+
obj.pictures.each do |pic|
|
103
|
+
begin
|
104
|
+
attached = AttachedFile.new(apidae_object_id: id, name: pic[:name], picture: URI.parse(pic[:url]),
|
105
|
+
description: pic[:description], credits: pic[:credits])
|
106
|
+
attached.save
|
107
|
+
rescue OpenURI::HTTPError => e
|
108
|
+
puts "Could not retrieve attached picture for object #{title} - Error is #{e.message}"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def self.pictures_urls(pictures_array)
|
116
|
+
pics_data = []
|
117
|
+
unless pictures_array.blank?
|
118
|
+
pictures_array.select { |p| p.is_a?(Hash) && !p[:traductionFichiers].blank? }.each do |pic|
|
119
|
+
pics_data << {
|
120
|
+
name: node_value(pic, :nom),
|
121
|
+
url: pic[:traductionFichiers][0][:url],
|
122
|
+
description: node_value(pic, :legende),
|
123
|
+
credits: node_value(pic, :copyright)
|
124
|
+
}
|
125
|
+
end
|
126
|
+
end
|
127
|
+
{pictures: pics_data}
|
128
|
+
end
|
129
|
+
|
130
|
+
def self.contact(information_hash)
|
131
|
+
contact_details = {}
|
132
|
+
contact_entries = information_hash[:moyensCommunication].nil? ? [] : information_hash[:moyensCommunication]
|
133
|
+
contact_entries.each do |c|
|
134
|
+
case c[:type][:id]
|
135
|
+
when PHONE
|
136
|
+
contact_details[:telephone] = c[:coordonnees][:fr]
|
137
|
+
when EMAIL
|
138
|
+
contact_details[:email] = c[:coordonnees][:fr]
|
139
|
+
when WEBSITE
|
140
|
+
contact_details[:website] = c[:coordonnees][:fr]
|
141
|
+
else
|
142
|
+
end
|
143
|
+
end
|
144
|
+
contact_details
|
145
|
+
end
|
146
|
+
|
147
|
+
def self.address(address_hash)
|
148
|
+
computed_address = []
|
149
|
+
computed_address << address_hash[:adresse1] unless address_hash[:adresse1].blank?
|
150
|
+
computed_address << address_hash[:adresse2] unless address_hash[:adresse2].blank?
|
151
|
+
computed_address << address_hash[:adresse3] unless address_hash[:adresse3].blank?
|
152
|
+
{address_fields: computed_address}
|
153
|
+
end
|
154
|
+
|
155
|
+
def self.town(address_hash)
|
156
|
+
address_hash[:commune] ? Town.find_by_apidae_id(address_hash[:commune][:id]) : nil
|
157
|
+
end
|
158
|
+
|
159
|
+
def self.latitude(location_hash)
|
160
|
+
geoloc_details = location_hash[:geolocalisation]
|
161
|
+
(geoloc_details && geoloc_details[:valide] && geoloc_details[:geoJson]) ? geoloc_details[:geoJson][:coordinates][1] : nil
|
162
|
+
end
|
163
|
+
|
164
|
+
def self.longitude(location_hash)
|
165
|
+
geoloc_details = location_hash[:geolocalisation]
|
166
|
+
(geoloc_details && geoloc_details[:valide] && geoloc_details[:geoJson]) ? geoloc_details[:geoJson][:coordinates][0] : nil
|
167
|
+
end
|
168
|
+
|
169
|
+
def self.openings(openings_hash)
|
170
|
+
if openings_hash && openings_hash[:periodeEnClair]
|
171
|
+
{description: openings_hash[:periodeEnClair][:libelleFr], opening_periods: openings_hash[:periodesOuvertures]}
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def self.rates(rates_hash)
|
176
|
+
if rates_hash
|
177
|
+
if rates_hash[:gratuit]
|
178
|
+
return 'gratuit'
|
179
|
+
elsif rates_hash[:tarifsEnClair]
|
180
|
+
rates_hash[:tarifsEnClair][:libelleFr]
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
def self.reservation(reservation_hash)
|
186
|
+
if reservation_hash
|
187
|
+
if reservation_hash[:complement]
|
188
|
+
reservation_hash[:complement][:libelleFr]
|
189
|
+
else
|
190
|
+
reservation_hash[:organismes]
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
def contact_text
|
196
|
+
entries = []
|
197
|
+
JSON.parse(contact).each_pair do |k, v|
|
198
|
+
entries << "#{k}: #{v}"
|
199
|
+
end
|
200
|
+
entries.join("\n")
|
201
|
+
end
|
202
|
+
|
203
|
+
def main_picture
|
204
|
+
pictures.any? ? pictures[0][:url] : "/#{Rails.application.config.apidae_pictures_path}/default/logo.png"
|
205
|
+
end
|
206
|
+
|
207
|
+
private
|
208
|
+
|
209
|
+
def self.node_value(node, key)
|
210
|
+
if node && node[key]
|
211
|
+
node[key][:libelleFr]
|
212
|
+
else
|
213
|
+
''
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module Apidae
|
2
|
+
class Selection < ActiveRecord::Base
|
3
|
+
has_and_belongs_to_many :objects, :class_name => 'Apidae::Object'
|
4
|
+
|
5
|
+
MAX_COUNT = 100
|
6
|
+
MAX_LOOPS = 10
|
7
|
+
|
8
|
+
def self.import(json_file)
|
9
|
+
selections_json = File.read(json_file)
|
10
|
+
selections_hashes = JSON.parse(selections_json, symbolize_names: true)
|
11
|
+
selections_hashes.each do |selection_data|
|
12
|
+
existing_sel = Apidae::Selection.find_by_apidae_id(selection_data[:id])
|
13
|
+
unless existing_sel
|
14
|
+
selection = Apidae::Selection.create!(
|
15
|
+
label: selection_data[:nom],
|
16
|
+
apidae_id: selection_data[:id]
|
17
|
+
)
|
18
|
+
if selection_data[:objetsTouristiques]
|
19
|
+
selection_data[:objetsTouristiques].each do |o|
|
20
|
+
apidae_object = Apidae::Object.find_by_apidae_id(o[:id])
|
21
|
+
selection.objects << apidae_object
|
22
|
+
selection.save!
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def agenda(from, to)
|
30
|
+
agenda_entries = Rails.cache.read("#{apidae_id}_#{from}_#{to}")
|
31
|
+
if agenda_entries.nil?
|
32
|
+
query_result = {}
|
33
|
+
config = {
|
34
|
+
url: "#{Rails.application.config.apidae_api_url}/agenda/detaille/list-identifiants",
|
35
|
+
apiKey: Rails.application.config.apidae_api_key,
|
36
|
+
projetId: Rails.application.config.apidae_project_id,
|
37
|
+
first: 0,
|
38
|
+
count: MAX_COUNT,
|
39
|
+
selectionIds: [apidae_id],
|
40
|
+
dateDebut: from,
|
41
|
+
dateFin: to
|
42
|
+
}
|
43
|
+
|
44
|
+
loops = 0
|
45
|
+
|
46
|
+
response = JSON.parse get_response(config), symbolize_names: false
|
47
|
+
total = response['numFound']
|
48
|
+
|
49
|
+
query_result[:results] = response['objetTouristiqueIds'] || {}
|
50
|
+
|
51
|
+
while total > query_result[:results].values.flatten.length && loops < MAX_LOOPS
|
52
|
+
loops += 1
|
53
|
+
config[:first] += MAX_COUNT
|
54
|
+
response = JSON.parse get_response(config), symbolize_names: false
|
55
|
+
merge_results(response, query_result)
|
56
|
+
end
|
57
|
+
query_result[:count] = total
|
58
|
+
agenda_entries = query_result
|
59
|
+
Rails.cache.write("#{apidae_id}_#{from}_#{to}", query_result)
|
60
|
+
end
|
61
|
+
agenda_entries
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def get_response(config)
|
67
|
+
response = ''
|
68
|
+
query = JSON.generate config.except(:url)
|
69
|
+
logger.info "Agenda query : #{config[:url]}?query=#{query}"
|
70
|
+
open("#{config[:url]}?query=#{CGI.escape query}") { |f|
|
71
|
+
f.each_line {|line| response += line if line}
|
72
|
+
}
|
73
|
+
response
|
74
|
+
end
|
75
|
+
|
76
|
+
def merge_results(response, query_results)
|
77
|
+
unless response['objetTouristiqueIds'].nil? || response['objetTouristiqueIds'].empty?
|
78
|
+
first_day = response['objetTouristiqueIds'].keys.first
|
79
|
+
if query_results[:results].has_key?(first_day)
|
80
|
+
query_results[:results][first_day] += response['objetTouristiqueIds'][first_day]
|
81
|
+
else
|
82
|
+
query_results[:results][first_day] = response['objetTouristiqueIds'][first_day]
|
83
|
+
end
|
84
|
+
query_results[:results].merge!(response['objetTouristiqueIds'].except(first_day))
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Apidae
|
2
|
+
class Town < ActiveRecord::Base
|
3
|
+
def self.import(json_file)
|
4
|
+
result = true
|
5
|
+
towns_json = File.read(json_file)
|
6
|
+
towns_hashes = JSON.parse(towns_json, symbolize_names: true)
|
7
|
+
towns_hashes.each do |town_data|
|
8
|
+
Town.create!(name: town_data[:nom], postal_code: town_data[:codePostal], insee_code: town_data[:code],
|
9
|
+
country: 'fr', apidae_id: town_data[:id])
|
10
|
+
end
|
11
|
+
result
|
12
|
+
end
|
13
|
+
|
14
|
+
def label
|
15
|
+
"#{name} (#{postal_code})"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
<%= form_for(@object) do |f| %>
|
2
|
+
<% if @object.errors.any? %>
|
3
|
+
<div id="error_explanation">
|
4
|
+
<h2><%= pluralize(@object.errors.count, "error") %> prohibited this object from being saved:</h2>
|
5
|
+
|
6
|
+
<ul>
|
7
|
+
<% @object.errors.full_messages.each do |message| %>
|
8
|
+
<li><%= message %></li>
|
9
|
+
<% end %>
|
10
|
+
</ul>
|
11
|
+
</div>
|
12
|
+
<% end %>
|
13
|
+
|
14
|
+
<div class="field">
|
15
|
+
<%= f.label :address %><br>
|
16
|
+
<%= f.text_field :address %>
|
17
|
+
</div>
|
18
|
+
<div class="field">
|
19
|
+
<%= f.label :apidae_id %><br>
|
20
|
+
<%= f.number_field :apidae_id %>
|
21
|
+
</div>
|
22
|
+
<div class="field">
|
23
|
+
<%= f.label :apidae_type %><br>
|
24
|
+
<%= f.text_field :apidae_type %>
|
25
|
+
</div>
|
26
|
+
<div class="field">
|
27
|
+
<%= f.label :apidae_subtype %><br>
|
28
|
+
<%= f.text_field :apidae_subtype %>
|
29
|
+
</div>
|
30
|
+
<div class="field">
|
31
|
+
<%= f.label :title %><br>
|
32
|
+
<%= f.text_field :title %>
|
33
|
+
</div>
|
34
|
+
<div class="field">
|
35
|
+
<%= f.label :short_desc %><br>
|
36
|
+
<%= f.text_area :short_desc %>
|
37
|
+
</div>
|
38
|
+
<div class="field">
|
39
|
+
<%= f.label :contact %><br>
|
40
|
+
<%= f.text_area :contact %>
|
41
|
+
</div>
|
42
|
+
<div class="field">
|
43
|
+
<%= f.label :long_desc %><br>
|
44
|
+
<%= f.text_area :long_desc %>
|
45
|
+
</div>
|
46
|
+
<div class="field">
|
47
|
+
<%= f.label :type_data %><br>
|
48
|
+
<%= f.text_area :type_data %>
|
49
|
+
</div>
|
50
|
+
<div class="field">
|
51
|
+
<%= f.label :latitude %><br>
|
52
|
+
<%= f.text_field :latitude %>
|
53
|
+
</div>
|
54
|
+
<div class="field">
|
55
|
+
<%= f.label :longitude %><br>
|
56
|
+
<%= f.text_field :longitude %>
|
57
|
+
</div>
|
58
|
+
<div class="field">
|
59
|
+
<%= f.label :openings %><br>
|
60
|
+
<%= f.text_area :openings %>
|
61
|
+
</div>
|
62
|
+
<div class="field">
|
63
|
+
<%= f.label :rates %><br>
|
64
|
+
<%= f.text_area :rates %>
|
65
|
+
</div>
|
66
|
+
<div class="field">
|
67
|
+
<%= f.label :reservation %><br>
|
68
|
+
<%= f.text_area :reservation %>
|
69
|
+
</div>
|
70
|
+
<div class="actions">
|
71
|
+
<%= f.submit %>
|
72
|
+
</div>
|
73
|
+
<% end %>
|