Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pouvoir dupliquer un itinéraire #2543

Closed
ThibaultCCVG86 opened this issue Feb 10, 2021 · 7 comments
Closed

Pouvoir dupliquer un itinéraire #2543

ThibaultCCVG86 opened this issue Feb 10, 2021 · 7 comments

Comments

@ThibaultCCVG86
Copy link

Bonjour,

J'ai 281 itinéraires que mes élus veulent valoriser dans trois pratiques : pédestre, équestre, VTT.
J'ai saisi une fois les 281 boucles pour la randonnée pédestre. Y a t-il un moyen pour les dupliquer dans les autres pratiques ?

Merci beaucoup.

@gutard
Copy link
Contributor

gutard commented Feb 10, 2021

Cette fonctionnalité n'existe pas pour l'instant. Mais techniquement il serait envisageable de l'ajouter.

@camillemonchicourt camillemonchicourt changed the title Duplication d'itinéraires Pouvoir dupliquer un itinéraire Jul 8, 2021
@camillemonchicourt
Copy link
Member

Depuis la liste des itinéraires, à ajouter dans ACTIONS ?
Ou alors depuis la fiche ITINÉRAIRE ?
On duplique l'objet et ses infos (1-1, 1-n et n-n) et sa géométrie, mais pas ses fichiers liés.

@babastienne
Copy link
Member

Dans le cadre d'une intervention effectuée avec le PN Forets, une fonction de duplication d'itinéraire a été mise en place.

Cette fonction python a pour objectif de permettre de "copier/coller" un itinéraire à partir de son ID. Pour l'utiliser, il faut copier le code ci-dessous dans un shell Geotrek (ouvrir un shell via la commande sudo geotrek shell) puis utiliser la fonction en faisant :
dupicate_trek(<identifiant_du_trek_a_dupliquer>)

Cela va créer un trek nommé "COPY <nom_du_trek_copié>" qui reprend normalement les même attributs que l'itinéraire original.

Code :

from uuid import uuid4
from geotrek.trekking.models import Trek
from datetime import date


def duplicate_trek(identifiant):
    # identifiant = IDENTIFIANT_DU_TREK_A_DUPLIQUER
    trek_original = Trek.objects.get(id=identifiant)
    aggreg_original = trek_original.aggregations.all()
    trek_original.topo_object.pk = None
    trek_original.topo_object.uuid = uuid4()
    trek_original.topo_object.save()
    for a in aggreg_original.all():
        a.topo_object_id = trek_original.topo_object.pk
        a.pk = None
        a.save()
    t = Trek.objects.create(
        pk=None,
        topo_object=trek_original.topo_object,
        date_insert=date.today(),
        date_update=date.today(),
        name_fr=f"COPY {trek_original.name_fr}",
        name_en=trek_original.name_en,
        description=trek_original.description,
        description_en=trek_original.description_en,
        description_fr=trek_original.description_fr,
        published=trek_original.published,
        published_fr=trek_original.published_fr,
        published_en=trek_original.published_en,
        access=trek_original.access,
        access_fr=trek_original.access_fr,
        access_en=trek_original.access_en,
        advised_parking=trek_original.advised_parking,
        advised_parking_fr=trek_original.advised_parking_fr,
        advised_parking_en=trek_original.advised_parking_en,
        ambiance=trek_original.ambiance,
        ambiance_en=trek_original.ambiance_en,
        ambiance_fr=trek_original.ambiance_fr,
        arrival=trek_original.arrival,
        arrival_fr=trek_original.arrival_fr,
        arrival_en=trek_original.arrival_en,
        departure=trek_original.departure,
        departure_fr=trek_original.departure_fr,
        departure_en=trek_original.departure_en,
        description_teaser=trek_original.description_teaser,
        description_teaser_fr=trek_original.description_teaser_fr,
        description_teaser_en=trek_original.description_teaser_en,
        duration=trek_original.duration,
        advice=trek_original.advice,
        advice_fr=trek_original.advice_fr,
        advice_en=trek_original.advice_en,
        difficulty=trek_original.difficulty,
        difficulty_id=trek_original.difficulty_id,
        disabled_infrastructure=trek_original.disabled_infrastructure,
        disabled_infrastructure_fr=trek_original.disabled_infrastructure_fr,
        disabled_infrastructure_en=trek_original.disabled_infrastructure_en,
        eid=trek_original.eid,
        eid2=trek_original.eid2,
        route=trek_original.route,
        route_id=trek_original.route_id,
        public_transport=trek_original.public_transport,
        public_transport_fr=trek_original.public_transport_fr,
        public_transport_en=trek_original.public_transport_en,
        parking_location=trek_original.parking_location,
        reservation_system=trek_original.reservation_system,
        reservation_system_id=trek_original.reservation_system_id,
        structure=trek_original.structure,
        structure_id=trek_original.structure_id,
        practice=trek_original.practice,
        practice_id=trek_original.practice_id,
    )
    for a in trek_original.attachments.all():
        t.attachments.add(a)
        t.attachments.save()
    for ac in trek_original.accessibilities.all():
        t.accessibilities.add(ac)
    for i in trek_original.information_desks.all():
        t.information_desks.add(i)
    for la in trek_original.labels.all():
        t.labels.add(la)
    for th in trek_original.themes.all():
        t.themes.add(th)
    for poi in trek_original.pois_excluded.all():
        t.pois_excluded.add(poi)
    for ch in trek_original.trek_children.all():
        t.trek_children.add(ch)
    for pa in trek_original.trek_parents.all():
        t.trek_parents.add(pa)
    t.save()

Attention, il faut garder en tête que cette fonction n'est pas testée et ne garantie pas la création d'une copie conforme de l'itinéraire initial, il s'agit là d'un snippet de code. Dans le cadre de l'intervention pour le PN Forêts cela a correctement fonctionné mais je recommande de vérifier manuellement chaque itinéraire dupliqué pour s'assurer que les champs (et particulièrement les champs many2many) ont bien étés correctement remplis.

A terme il pourrait être envisageable d'ajouter cette fonctionnalité à Geotrek. Dans ce cas ce snippet serait une base de départ pour la fonctionnalité qui serait probablement étoffée et correctement testée.

@camillemonchicourt
Copy link
Member

camillemonchicourt commented Feb 1, 2022

OK merci beaucoup pour ce retour et ce partage.
En effet c'est une bonne base pour en faire une commande intégrée, testée et évolutive dans Geotrek.

Je ne connaissais pas la possibilité des commande shell Geotrek de cette manière.
J'ai fait un petit test, mais j'ai surement mal écrit la commande :

geotrek@geotrek-test:~$ sudo geotrek shell
Python 3.6.9 (default, Dec  8 2021, 21:08:43) 
[GCC 8.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from uuid import uuid4
>>> from geotrek.trekking.models import Trek
>>> from datetime import date
>>> 
>>> 
>>> def duplicate_trek(identifiant):
...     # identifiant = IDENTIFIANT_DU_TREK_A_DUPLIQUER
...     trek_original = Trek.objects.get(id=identifiant)
...     aggreg_original = trek_original.aggregations.all()
...     trek_original.topo_object.pk = None
...     trek_original.topo_object.uuid = uuid4()
...     trek_original.topo_object.save()
...     for a in aggreg_original.all():
...         a.topo_object_id = trek_original.topo_object.pk
...         a.pk = None
...         a.save()
...     t = Trek.objects.create(
...         pk=None,
...         topo_object=trek_original.topo_object,
...         date_insert=date.today(),
...         date_update=date.today(),
...         name_fr=f"COPY {trek_original.name_fr}",
...         name_en=trek_original.name_en,
...         description=trek_original.description,
...         description_en=trek_original.description_en,
...         description_fr=trek_original.description_fr,
...         published=trek_original.published,
...         published_fr=trek_original.published_fr,
...         published_en=trek_original.published_en,
...         access=trek_original.access,
...         access_fr=trek_original.access_fr,
...         access_en=trek_original.access_en,
...         advised_parking=trek_original.advised_parking,
...         advised_parking_fr=trek_original.advised_parking_fr,
...         advised_parking_en=trek_original.advised_parking_en,
...         ambiance=trek_original.ambiance,
...         ambiance_en=trek_original.ambiance_en,
...         ambiance_fr=trek_original.ambiance_fr,
...         arrival=trek_original.arrival,
...         arrival_fr=trek_original.arrival_fr,
...         arrival_en=trek_original.arrival_en,
...         departure=trek_original.departure,
...         departure_fr=trek_original.departure_fr,
...         departure_en=trek_original.departure_en,
...         description_teaser=trek_original.description_teaser,
...         description_teaser_fr=trek_original.description_teaser_fr,
...         description_teaser_en=trek_original.description_teaser_en,
...         duration=trek_original.duration,
...         advice=trek_original.advice,
...         advice_fr=trek_original.advice_fr,
...         advice_en=trek_original.advice_en,
...         difficulty=trek_original.difficulty,
...         difficulty_id=trek_original.difficulty_id,
...         disabled_infrastructure=trek_original.disabled_infrastructure,
...         disabled_infrastructure_fr=trek_original.disabled_infrastructure_fr,
...         disabled_infrastructure_en=trek_original.disabled_infrastructure_en,
...         eid=trek_original.eid,
...         eid2=trek_original.eid2,
...         route=trek_original.route,
...         route_id=trek_original.route_id,
...         public_transport=trek_original.public_transport,
...         public_transport_fr=trek_original.public_transport_fr,
...         public_transport_en=trek_original.public_transport_en,
...         parking_location=trek_original.parking_location,
...         reservation_system=trek_original.reservation_system,
...         reservation_system_id=trek_original.reservation_system_id,
...         structure=trek_original.structure,
...         structure_id=trek_original.structure_id,
...         practice=trek_original.practice,
...         practice_id=trek_original.practice_id,
...     )
...     for a in trek_original.attachments.all():
...         t.attachments.add(a)
...         t.attachments.save()
...     for ac in trek_original.accessibilities.all():
...         t.accessibilities.add(ac)
...     for i in trek_original.information_desks.all():
...         t.information_desks.add(i)
...     for la in trek_original.labels.all():
...         t.labels.add(la)
...     for th in trek_original.themes.all():
...         t.themes.add(th)
...     for poi in trek_original.pois_excluded.all():
...         t.pois_excluded.add(poi)
...     for ch in trek_original.trek_children.all():
...         t.trek_children.add(ch)
...     for pa in trek_original.trek_parents.all():
...         t.trek_parents.add(pa)
...     t.save()
... duplicate_trek(786)
  File "<console>", line 85
    duplicate_trek(786)
                 ^
SyntaxError: invalid syntax

@LePetitTim
Copy link
Contributor

LePetitTim commented Mar 31, 2022

Il faut d'abord finir la fonction duplicate_trek() avant de l'appeler.

Ici, tu n'as pas fait ENTER, avant de l'appeler.

Tu dois avoir dans ton shell :
>>> duplicate_trek(786)
et non pas
. . . duplicate_trek(786)
Les . . . signifient que tu ecris quelque chose sur plusieurs lignes.

@camillemonchicourt
Copy link
Member

OK bien vu, merci.
J'avais fait un ENTER après avoir défini la fonction, mais il fallait le faire une deuxième fois.
Et là ça fonctionne en effet !

Il a juste fallu renommer les champs disabled_infrastructures en accessibility_infrastructures car on a changé le nom de ce champs entre temps :

from uuid import uuid4
from geotrek.trekking.models import Trek
from datetime import date


def duplicate_trek(identifiant):
    # identifiant = IDENTIFIANT_DU_TREK_A_DUPLIQUER
    trek_original = Trek.objects.get(id=identifiant)
    aggreg_original = trek_original.aggregations.all()
    trek_original.topo_object.pk = None
    trek_original.topo_object.uuid = uuid4()
    trek_original.topo_object.save()
    for a in aggreg_original.all():
        a.topo_object_id = trek_original.topo_object.pk
        a.pk = None
        a.save()
    t = Trek.objects.create(
        pk=None,
        topo_object=trek_original.topo_object,
        date_insert=date.today(),
        date_update=date.today(),
        name_fr=f"COPY {trek_original.name_fr}",
        name_en=trek_original.name_en,
        description=trek_original.description,
        description_en=trek_original.description_en,
        description_fr=trek_original.description_fr,
        published=trek_original.published,
        published_fr=trek_original.published_fr,
        published_en=trek_original.published_en,
        access=trek_original.access,
        access_fr=trek_original.access_fr,
        access_en=trek_original.access_en,
        advised_parking=trek_original.advised_parking,
        advised_parking_fr=trek_original.advised_parking_fr,
        advised_parking_en=trek_original.advised_parking_en,
        ambiance=trek_original.ambiance,
        ambiance_en=trek_original.ambiance_en,
        ambiance_fr=trek_original.ambiance_fr,
        arrival=trek_original.arrival,
        arrival_fr=trek_original.arrival_fr,
        arrival_en=trek_original.arrival_en,
        departure=trek_original.departure,
        departure_fr=trek_original.departure_fr,
        departure_en=trek_original.departure_en,
        description_teaser=trek_original.description_teaser,
        description_teaser_fr=trek_original.description_teaser_fr,
        description_teaser_en=trek_original.description_teaser_en,
        duration=trek_original.duration,
        advice=trek_original.advice,
        advice_fr=trek_original.advice_fr,
        advice_en=trek_original.advice_en,
        difficulty=trek_original.difficulty,
        difficulty_id=trek_original.difficulty_id,
        accessibility_infrastructure=trek_original.accessibility_infrastructure,
        accessibility_infrastructure_fr=trek_original.accessibility_infrastructure_fr,
        accessibility_infrastructure_en=trek_original.accessibility_infrastructure_en,
        eid=trek_original.eid,
        eid2=trek_original.eid2,
        route=trek_original.route,
        route_id=trek_original.route_id,
        public_transport=trek_original.public_transport,
        public_transport_fr=trek_original.public_transport_fr,
        public_transport_en=trek_original.public_transport_en,
        parking_location=trek_original.parking_location,
        reservation_system=trek_original.reservation_system,
        reservation_system_id=trek_original.reservation_system_id,
        structure=trek_original.structure,
        structure_id=trek_original.structure_id,
        practice=trek_original.practice,
        practice_id=trek_original.practice_id,
    )
    for a in trek_original.attachments.all():
        t.attachments.add(a)
        t.attachments.save()
    for ac in trek_original.accessibilities.all():
        t.accessibilities.add(ac)
    for i in trek_original.information_desks.all():
        t.information_desks.add(i)
    for la in trek_original.labels.all():
        t.labels.add(la)
    for th in trek_original.themes.all():
        t.themes.add(th)
    for poi in trek_original.pois_excluded.all():
        t.pois_excluded.add(poi)
    for ch in trek_original.trek_children.all():
        t.trek_children.add(ch)
    for pa in trek_original.trek_parents.all():
        t.trek_parents.add(pa)
    t.save()

J'aurai aussi pu ajouter les nouveaux champs liés à l'accessibilité pour affiner et compléter, mais pas fait cette fois-ci pour mes tests.

@camillemonchicourt
Copy link
Member

La fonctionnalité de duplication d'itinéraires, mais aussi des autres objets a été intégrée dans la version 2.95.0, directement dans l'interface sur les fiches objets.
Voir #3105 (comment) pour les premiers retours de tests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants