From a3a46e19c78c5b6459f5042ac72d4ded587177e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Poulain?= Date: Mon, 3 Aug 2020 16:59:21 +0200 Subject: [PATCH] feat(base): ajoute un premier jet d import drupal -> spip --- drupal2spip_lal/base/convert.py | 89 +++++++++++++++++++ .../base/management/commands/import.py | 27 ++++++ .../base/management/commands/inspectdb.py | 56 +++++++++++- 3 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 drupal2spip_lal/base/convert.py create mode 100644 drupal2spip_lal/base/management/commands/import.py diff --git a/drupal2spip_lal/base/convert.py b/drupal2spip_lal/base/convert.py new file mode 100644 index 0000000..9d90f98 --- /dev/null +++ b/drupal2spip_lal/base/convert.py @@ -0,0 +1,89 @@ +from datetime import datetime + +from django.utils.timezone import make_aware, now + +from drupal2spip_lal.drupal import models as drupal +from drupal2spip_lal.spip import models as spip + +# Questions +# - quelle utilisation des rubriques ? +# - quelle hiérarchie des mots clés ? +# - autobr sélectif ? + + +def convert_timestamp(timestamp): + return make_aware(datetime.fromtimestamp(timestamp)) + + +def sanitarize_html(html): + # FIXME: bs4 + return html + + +def convert_node(node, update=False): + """ + Le point d'entrée fonctionnel c'est les Urls. + On se base donc là dessus pour vérifier si l'import + est à faire ou pas ou encore à upgrader. + """ + node_urls = drupal.UrlAlias.objects.filter(src='node/{}'.format(node.pk)) + + spip_urls = spip.Urls.objects.filter( + type='article', url__in=list(node_urls.values_list('dst', flat=True)) + ) + + spip_urls.count() + if spip_urls.exists() and ( + sorted(spip_urls.values_list('url', flat=True)) + != sorted(node_urls.values_list('dst', flat=True)) + or len(set(spip_urls.values_list('id_objet', flat=True))) != 1 + ): + # incohérence dans les urls + raise NotImplementedError + + article = None + article_attributes = { + 'date': convert_timestamp(node.published_revision.timestamp), + 'date_modif': convert_timestamp(node.changed), + 'date_redac': convert_timestamp(node.created), + 'descriptif': sanitarize_html(node.published_revision.teaser), + 'maj': convert_timestamp(node.changed), + 'statut': 'publie' if node.status else 'prepa', + 'texte': sanitarize_html(node.published_revision.body), + 'titre': node.title, + } + if not spip_urls.exists(): + article = spip.Articles.objects.create(**article_attributes) + urls = [ + spip.Urls( + id_objet=article.pk, + url=node_url.dst, + date=convert_timestamp(node.created), + ) + for node_url in node_urls + ] + spip.Urls.objects.bulk_create(urls) + + print('Article {} created from node {}.'.format(article.pk, node.pk)) + + elif update: + article = spip.Articles( + pk=spip_urls.last().id_objet, **article_attributes + ) + article.save() + print('Article {} updated from node {}.'.format(article.pk, node.pk)) + + if article: + user_attributes = { + 'nom': node.user.name, + 'email': node.user.mail, + 'en_ligne': convert_timestamp(node.user.access), + 'maj': convert_timestamp(node.user.created), + } + auteur, _ = spip.Auteurs.objects.update_or_create( + login=node.user.name, defaults=user_attributes + ) + + spip.AuteursLiens.objects.update_or_create( + auteur=auteur, id_objet=article.pk, objet='article' + ) diff --git a/drupal2spip_lal/base/management/commands/import.py b/drupal2spip_lal/base/management/commands/import.py new file mode 100644 index 0000000..9cedb68 --- /dev/null +++ b/drupal2spip_lal/base/management/commands/import.py @@ -0,0 +1,27 @@ +from django.core.management.base import BaseCommand + +from drupal2spip_lal.base.convert import convert_node +from drupal2spip_lal.drupal.models import Node + + +class Command(BaseCommand): + help = "Import Drupal nodes to SPIP articles." + + def add_arguments(self, parser): + parser.add_argument( + '--node', + nargs='*', + type=int, + help='Selects what nodes should be imported. Default is none.', + ) + parser.add_argument( + '--update', + action='store_true', + help='Force existing articles to be updated. Default is skip.', + ) + + def handle(self, **options): + [ + convert_node(n, update=options.get('update', False)) + for n in Node.objects.filter(pk__in=options.get('node', [])) + ] diff --git a/drupal2spip_lal/base/management/commands/inspectdb.py b/drupal2spip_lal/base/management/commands/inspectdb.py index 35cfc55..4192946 100644 --- a/drupal2spip_lal/base/management/commands/inspectdb.py +++ b/drupal2spip_lal/base/management/commands/inspectdb.py @@ -88,7 +88,10 @@ DB_RELATIONS = { }, }, 'spip': { - } + 'auteurs_liens': { + 'id_auteur': ('id_auteur', 'auteurs', 'auteur'), + }, + }, } # On précise ici des paramètres de la DB. @@ -101,6 +104,57 @@ DB_PARAMS = { }, }, 'spip': { + 'articles': { + 'accepter_forum': {'default': 'non'}, + 'chapo': {'default': ''}, + 'descriptif': {'default': ''}, + 'export': {'default': 'oui'}, + 'id_rubrique': {'default': 1}, + 'id_secteur': {'default': 1}, + 'id_trad': {'default': 0}, + 'lang': {'default': 'fr'}, + 'langue_choisie': {'default': 'non'}, + 'nom_site': {'default': ''}, + 'popularite': {'default': 0.0}, + 'ps': {'default': ''}, + 'referers': {'default': 0}, + 'soustitre': {'default': ''}, + 'statut': {'default': 'prepa'}, + 'surtitre': {'default': ''}, + 'texte': {'default': ''}, + 'url_site': {'default': ''}, + 'virtuel': {'default': ''}, + 'visites': {'default': 0}, + }, + 'auteurs': { + 'alea_actuel': {'default': ''}, + 'alea_futur': {'default': ''}, + 'bio': {'default': ''}, + 'cookie_oubli': {'default': None}, + 'htpass': {'default': ''}, + 'imessage': {'default': None}, + 'lang': {'default': ''}, + 'low_sec': {'default': ''}, + 'messagerie': {'default': None}, + 'nom_site': {'default': ''}, + 'pass_field': {'default': ''}, + 'pgp': {'default': ''}, + 'prefs': {'default': 'a:5:{s:7:"couleur";i:9;s:7:"display";i:2;s:18:"display_navigation";s:22:"navigation_avec_icones";s:14:"display_outils";s:3:"oui";s:3:"cnx";s:0:"";}'}, + 'source': {'default': 'spip'}, + 'statut': {'default': '0minirezo'}, + 'url_site': {'default': ''}, + 'webmestre': {'default': 'non'}, + }, + 'auteurs_liens': { + 'vu': {'default': 'non'}, + }, + 'urls': { + 'id_parent': {'default': 0}, + 'langue': {'default': ''}, + 'perma': {'default': 0}, + 'segments': {'default': 1}, + 'type': {'default': 'article'}, + }, }, }