Touristic Data Systems¶
Keywords
SIT
, parser
, command line
, import en ligne de commande
Real-time integration¶
Geotrek-admin integrates with various Tourism Information Systems (SIT) such as Apidae, Tourinsoft, and others, enabling real-time retrieval of data entered by tourism offices. This includes information on points of interest, accommodations, cultural heritage, and more.
These imported data elements are automatically linked to nearby treks, regardless of activity type (trekking, trail running, mountain biking, cycling, gravel, climbing, rafting, etc.).
This seamless integration enriches the descriptive pages of routes, ensuring that users benefit from comprehensive and up-to-date information with no additional effort required from administrators or agents.
Generic settings for your parser¶
This settings may be overriden when you define a new parser:
label
parser display name (default:None
)model
import content with this model (default:None
)filename
file imported if no url (default:None
)url
flow url imported from if no filename (default:None
)simplify_tolerance
(default:0
) # metersupdate_only
don’t create new contents (default:False
)delete
(default:False
)duplicate_eid_allowed
if True, allows differents contents with same eid (default:False
)fill_empty_translated_fields
if True, fills empty translated fields with same value (default:False
)warn_on_missing_fields
(default:False
)warn_on_missing_objects
(default:False
)separator
(default:'+'
)eid
field name for eid (default:None
)provider
(default:None
)fields
(default:None
)m2m_fields
(default:{}
)constant_fields
(default:{}
)m2m_constant_fields
(default:{}
)m2m_aggregate_fields
(default:[]
)non_fields
(default:{}
)natural_keys
(default:{}
)field_options
(default:{}
)default_language
use another default language for this parser (default:None
)
Start import from command line¶
Just run:
sudo geotrek import HebergementParser
docker compose run --rm web ./manage.py import HebergementParser
Change HebergementParser
to match one of the class names in var/conf/parsers.py
file.
You can add -v2
parameter to make the command more verbose (show progress).
Thank to cron
utility you can configure automatic imports.
Start import from Geotrek-admin UI¶
Open the top right menu and clic on imports
.
Import from APIDAE¶
Import touristic content¶
To import touristic content from APIDAE (ex-SITRA), edit /opt/geotrek-admin/var/conf/parsers.py
file with the following content:
from geotrek.tourism.parsers import TouristicContentApidaeParser
class HebergementParser(TouristicContentApidaeParser):
label = "Hébergements"
api_key = 'xxxxxxxx'
project_id = 9999
selection_id = 99999
category = "Hébergement"
type1 = ["Camping"]
type2 = ["3 étoiles", "Tourisme et Handicap"] # just remove this line if no type2
Then set up appropriate values:
label
at your convenience,api_key
,project_id
andselection_id
according to your APIDAE (ex-SITRA) configurationcategory
,type1
andtype2
(optional) to select in which Geotrek category/type imported objects should goYou can add
delete = True
in your class if you want to delete objects in Geotrek databases that has been deleted in your Apidae selection. It will only delete objects that match with your class settings (category, types, portal, provider…)You can also use the class
HebergementParser
if you only import accomodationsSee /geotrek/tourism/parsers.py/ file for details about Parsers
You can duplicate the class. Each class must have a different name.
To apply changes, you may have to run sudo service geotrek restart
.
Import treks¶
A parser implementation is available to import Treks from APIDAE. Use it by defining a subclass of geotrek.trekking.parsers.ApidaeTrekParser
in your var/conf/parsers.py
configuration file as shown above.
You’ll have to configure how to access your APIDAE data: api_key
, project_id
and selection_id
(those are setting attributes from the APIDAE base parser).
The practices_mapped_with_activities_ids
and practices_mapped_with_default_activities_ids
attributes define default mapping with the trekking module data fixture. You may override this to match your own types of Trek Practice.
Example of a parser configuration :
class ImportTreksApidae(TrekParser):
label = "Import trek with eid"
label_fr = "Import itinéraires avec identifiant externe"
label_en = "Import trek with eid"
eid = 'eid'
Import from Tourinsoft¶
Tourinsoft is a Tourism Information System developed by the company Ingénie for tourism organizations in France, such as Departmental Tourism Committees (CDT), Tourism Development Agencies (ADT), and Tourist Offices. This system allows for the centralization, management, and standardized dissemination of tourism-related information.
Example of a parser configuration :
class RestaurationParser(TouristicContentTourinsoftParser):
"""Restauration parsers"""
label = "Restauration"
category = "Restauration"
url = "<Touristic content data feed URL" # In the form https://api-v3.tourinsoft.com/api/syndications/decibelles-data.tourinsoft.com/<id>?format=json"
Import from Cirkwi¶
The functionality for importing treks and touristic content from Cirkwi was developed and integrated into version 2.111.0 of Geotrek-admin.
Note
By default, imported content is automatically published.
To enable the integration of this data, you need to modify the parsers.py file to create a dedicated parser and query a feed provided by Cirkwi.
The following parsers have been developed to facilitate data import from Cirkwi into Geotrek-admin:
Trek Parser: Allows the integration of treks from Cirkwi into Geotrek. This parser is compatible with instances operating in Non-Dynamic Segmentation (NDS) mode only.
Example of a parser configuration :
class ImportTreksCirkwi(CirkwiTrekParser):
url = "<Treks data feed URL>" # In the form https://ws.cirkwi.com/flux/<user>/<code>/circuits.php?widget-id=<id>
user = "<Username>"
password = "<Password>"
auth = (user, password)
label = "Cirkwi's treks"
delete = True
create = True
provider = "Cirkwi"
Touristic content Parser: Enables the import of touristic content from Cirkwi into Geotrek.
Example of a parser configuration :
class ImportTouristicContentCirkwi(CirkwiTouristicContentParser):
url = "<Treks data feed URL>" # In the form https://ws.cirkwi.com/flux/<user>/<code>/circuits.php?widget-id=<id>"
user = "<Username>"
password = "<Password>"
auth = (user, password)
label = "Cirkwi's touristic content"
delete = True
create = True
provider = "Cirkwi"
# results_path = "circuit/pois/poi" # Uncomment this line if the touristic content to be imported come from the same feed as treks
See also
To import Geotrek treks and POIs into Cirkwi’s format you can check this section (french).
Import from LEI¶
To import touristic content or touristic event from LEI , create (or update) /opt/geotrek-admin/var/conf/parsers.py
file with the following content:
from geotrek.tourism.parsers import LEITouristicContentParser, LEITouristicEventParser
class XXXLEIContentParser(LEITouristicContentParser):
label = "LEI TouristicContent"
url = "https://url.asp"
class XXXLEIEventParser(LEITouristicEventParser):
label = "LEI TouristicEvent"
url = "https://url.asp"
Import from Marque Esprit Parc¶
To import touristic content from Esprit Parc national database, create (or update) /opt/geotrek-admin/var/conf/parsers.py
file with the following content:
from geotrek.tourism.parsers import EspritParcParser
class XXXEspritParcParser(EspritParcParser):
label = "Marque Esprit Parc"
url = "https://gestion.espritparcnational.com/ws/?f=getProduitsSelonParc&codeParc=XXX"
Then set up appropriate values:
XXX
by unique national park code (ex: PNE)
You can duplicate the class. Each class must have a different name.
In this case categories and types in Geotrek database have to be the same as in Esprit parc database. Otherwise missing categories and types will be created in Geotrek database.
Imported contents will be automatically published and approved (certified).
If you use an url that filters a unique category, you can change its name. Example to get only Honey products and set the Geotrek category and type in which import them:
class MielEspritParcParser(EspritParcParser):
label = "Miel Esprit Parc national"
url = "https://gestion.espritparcnational.com/ws/?f=getProduitsSelonParc&codeParc=XXX&typologie=API"
constant_fields = {
'category': "GeotrekCategoryName",
'published': True,
'approved': True,
'deleted': False,
}
m2m_constant_fields = {
'type1': "GeotrekTypeName",
}
Multiple imports¶
When you need to import data for the same object found in 2 different parsers, you can to force the aggregation of both values in many to many relationship case. It can be interesting with portals for example.
Parameters for the aggregation : m2m_aggregate_fields
Here is an example with 2 parsers :
class Portal_1Parser(XXXParser):
portal = "portal_1"
class AggregateParser(XXXParser):
portal = "portal_2"
m2m_aggregate_fields = ["portal"]
Then, when you import the first parser Portal_1Parser
, you get multiple objects with portal_1
as portal.
If any object of the Portal_1Parser
is also in AggregateParser
, fields in m2m_aggregate_fields
will have their values not be replaced but aggregated.
Then your object in both portals will have as portal: portal_1, portal_2
Here in this example whenever you import the first parser
Portal_1Parser
, portals are replaced becausem2m_aggregate_fields
is not filled. Then, be careful to import parsers in the right order or add the paramm2m_aggregate_fields
on all parsers.
If you need to cancel the aggregation of portals, remove param m2m_aggregate_fields
.
Importing from multiple sources with deletion¶
When importing data for the same model using two (or more) different sources, the provider
field should be used to differenciate between sources, allowing to enable object deletion with delete = True
without causing the last parser to delete objects created by preceeding parsers.
In the following example, Provider_1Parser
and Provider_2Parser
will each import their objects, set the provider
field on these objects, and only delete objects that disappeared from their respective source since last parsing.
class Provider_1Parser(XXXXParser):
delete = True
provider = "provider_1"
class Provider_2Parser(XXXParser):
delete = True
provider = "provider_2"
Important
It is recommended to use
provider
from the first import.Do not add a
provider
field to preexisting parsers that already imported objects, or you will have to manually set the same value forprovider
on all objects already created by this parser.If a parser does not have a
provider
value, it will not take providers into account, meaning that it could delete objects from preceeding parsers even if these other parsers do have aprovider
themselves.
The following example would cause NoProviderParser
to delete objects from Provider_2Parser
and Provider_1Parser
.
class Provider_1Parser(XXXXParser):
delete = True
provider = "provider_1"
class Provider_2Parser(XXXParser):
delete = True
provider = "provider_2"
class NoProviderParser(XXXParser):
delete = True
provider = None # (default)
See also
To set up automatic commands you can check the Automatic commands section.