--- a/.hgignore Thu Apr 12 01:27:16 2018 +0200
+++ b/.hgignore Wed Apr 11 12:19:47 2018 +0200
@@ -26,3 +26,4 @@
^src/MANIFEST.in$
^dev/hdalab/dist
^dev/out
+^doc/build
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/Makefile Wed Apr 11 12:19:47 2018 +0200
@@ -0,0 +1,20 @@
+# Minimal makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+SPHINXPROJ = HDALab
+SOURCEDIR = source
+BUILDDIR = build
+
+# Put it first so that "make" without argument is like "make help".
+help:
+ @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+.PHONY: help Makefile
+
+# Catch-all target: route all unknown targets to Sphinx using the new
+# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
+%: Makefile
+ @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/make.bat Wed Apr 11 12:19:47 2018 +0200
@@ -0,0 +1,36 @@
+@ECHO OFF
+
+pushd %~dp0
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+ set SPHINXBUILD=sphinx-build
+)
+set SOURCEDIR=source
+set BUILDDIR=build
+set SPHINXPROJ=HDALab
+
+if "%1" == "" goto help
+
+%SPHINXBUILD% >NUL 2>NUL
+if errorlevel 9009 (
+ echo.
+ echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
+ echo.installed, then set the SPHINXBUILD environment variable to point
+ echo.to the full path of the 'sphinx-build' executable. Alternatively you
+ echo.may add the Sphinx directory to PATH.
+ echo.
+ echo.If you don't have Sphinx installed, grab it from
+ echo.http://sphinx-doc.org/
+ exit /b 1
+)
+
+%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
+goto end
+
+:help
+%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
+
+:end
+popd
Binary file doc/source/_static/img/logo_iri.png has changed
Binary file doc/source/_static/img/pages/accueil_hdalab.png has changed
Binary file doc/source/_static/img/pages/admin_django_hdalab.png has changed
Binary file doc/source/_static/img/pages/administrer_renkan.png has changed
Binary file doc/source/_static/img/pages/apropos_hdalab.png has changed
Binary file doc/source/_static/img/pages/artistic_domains_hdalab.png has changed
Binary file doc/source/_static/img/pages/contact_hdalab.png has changed
Binary file doc/source/_static/img/pages/credits_hdalab.png has changed
Binary file doc/source/_static/img/pages/detail_notice.png has changed
Binary file doc/source/_static/img/pages/editorialisation_hdalab.png has changed
Binary file doc/source/_static/img/pages/facettes_hdalab.png has changed
Binary file doc/source/_static/img/pages/mentions_legales_hdalab.png has changed
Binary file doc/source/_static/img/pages/renkan_base_list.png has changed
Binary file doc/source/_static/img/pages/renkan_edit.png has changed
Binary file doc/source/_static/img/pages/renkan_favorite.png has changed
Binary file doc/source/_static/img/pages/renkan_public.png has changed
Binary file doc/source/_static/img/pages/renkan_view.png has changed
Binary file doc/source/_static/img/pages/renkan_view_full.png has changed
Binary file doc/source/_static/img/pages/thematic_folder_hdalab.png has changed
Binary file doc/source/_static/img/pages/tree_search_hdalab.png has changed
Binary file doc/source/_static/img/pages/user_info_hdalab.png has changed
Binary file doc/source/_static/img/pages/user_profile_hdalab.png has changed
Binary file doc/source/_static/img/renkan/renkan_bin_plus_ressources.png has changed
Binary file doc/source/_static/img/renkan/renkan_bin_resources.png has changed
Binary file doc/source/_static/img/renkan/renkan_edition.png has changed
Binary file doc/source/_static/img/renkan/renkan_recherche_contenus.png has changed
Binary file doc/source/_static/img/renkan/renkan_recherche_resultats.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/source/api.rst Wed Apr 11 12:19:47 2018 +0200
@@ -0,0 +1,182 @@
+################
+URL d'API HDALAB
+################
+
+Ces URL n'ont pas de sortie HTML. Elle sont utilisée en particulier par les composants javascript HDALab.
+
+Recherche fulltext dans les fiches
+==================================
+
+Ce point d'API est utilisé pour faire des recherches fulltext dans les fiches.
+Il est utilisé aux endroits suivants:
+
+ - :ref:`pages_recherche_facette`
+
++----------+---------------------------------------------------------+
+| url | http://hdalab.iri-research.org/hdalab/hdabo/searchajax/ |
++----------+---------------------------------------------------------+
+| view | :class:`hdabo.views.SearchDatasheet` |
++----------+---------------------------------------------------------+
+
+.. autoclass:: hdabo.views.SearchDatasheet
+ :noindex:
+
+
+
+Recherche dans les catégories Wikipedia
+=======================================
+
+Ce point d'API est utilisé pour faire des recherches dans les catégories Wikipedia.
+Il est utilisé aux endroits suivants:
+
+ - :ref:`pages_explorer_domaines_artistiques`
+
++----------+---------------------------------------------------+
+| url | http://hdalab.iri-research.org/hdalab/a/catsearch |
++----------+---------------------------------------------------+
+| view | :func:`hdalab.views.ajax.catsearch` |
++----------+---------------------------------------------------+
+
+.. autofunction:: hdalab.views.ajax.catsearch
+ :noindex:
+
+
+.. _api_arbre_categories:
+
+Arbre de catégories
+===================
+
+Ce point d'API est utilisé pour construire un arbre de catégorie Wikipedia à partir d'un label.
+Il est utilisé aux endroits suivants:
+
+ - :ref:`pages_explorer_domaines_artistiques`
+
+
++----------+-------------------------------------------------+
+| url | http://hdalab.iri-research.org/hdalab/a/cattree |
++----------+-------------------------------------------------+
+| view | :func:`hdalab.views.ajax.cattree` |
++----------+-------------------------------------------------+
+
+
+.. autofunction:: hdalab.views.ajax.cattree
+ :noindex:
+
+
+Remplissage d'arbre
+===================
+
+Ce point d'API est utilisé pour ajouter des fiches à un arbre de catégorie, comme par exemple produit par l'api :ref:`api_arbre_categories`.
+
+Il est utilisé dans les pages suivantes:
+
+ - :ref:`pages_explorer_domaines_artistiques`
+ - :ref:`pages_recherche_arbre`
+
+
++----------+--------------------------------------------------+
+| url | http://hdalab.iri-research.org/hdalab/a/filltree |
++----------+--------------------------------------------------+
+| view | :func:`hdalab.views.ajax.filltree` |
++----------+--------------------------------------------------+
+
+
+.. autofunction:: hdalab.views.ajax.filltree
+ :noindex:
+
+
+Filtrage par facette
+====================
+
+Ce point d'API est utilisé pour réaliser le filtrage par facette des fiches HDA.
+Il est utilisé aux endroits suivants:
+
+ - :ref:`pages_recherche_facette`
+
+
++----------+------------------------------------------------+
+| url | http://hdalab.iri-research.org/hdalab/a/filter |
++----------+------------------------------------------------+
+| view | :func:`hdalab.views.ajax.filter` |
++----------+------------------------------------------------+
+
+
+.. autofunction:: hdalab.views.ajax.filter
+ :noindex:
+
+
+Recherche de tag
+================
+
+Ce point d'API est utilisé pour faire des recherche dans les tags.
+Il est utilisé aux endroits suivants:
+
+ - :ref:`pages_recherche_facette`
+ - :ref:`renkan_boite_recherche_contenus`
+
++----------+----------------------------------------------------------+
+| url | http://hdalab.iri-research.org/hdalab/a/tagsearch |
++----------+----------------------------------------------------------+
+| view | :func:`hdalab.views.ajax.tagsearch` |
++----------+----------------------------------------------------------+
+
+.. autofunction:: hdalab.views.ajax.tagsearch
+ :noindex:
+
+
+login ajax
+==========
+
+Ce point d'API permet la gestion de la connexion à partir d'un éditeur Renkan.
+Il est utilisé aux endroits suivants :
+
+ - :ref:`pages_recherche_facette`
+
+
++----------+---------------------------------------------------+
+| url | http://hdalab.iri-research.org/hdalab/ajaxlogin/ |
++----------+---------------------------------------------------+
+| view | :func:`hdalab.views.profile.ajax_login` |
++----------+---------------------------------------------------+
+
+.. autofunction:: hdalab.views.profile.ajax_login
+ :noindex:
+
+Chargement et sauvegarde de renkan
+==================================
+
+Ce point d'API permet le chargement et la sauvegarde des renkan. Il est appelé par le client javascript renkan.
+
+Il est utilisé aux endroits suivants :
+
+ - :ref:`pages_edition_renkan`
+ - :ref:`affichage-d-un-renkan-en-lecture-seule`
+ - :ref:`affichage-d-un-renkan-en-plein-ecran`
+
+
++-----------+------------------------------------------------------+
+| url | http://hdalab.iri-research.org/hdalab/renkan/getput/ |
++-----------+------------------------------------------------------+
+| view | :class:`hdalab.views.profile.HdalabRenkanGetPut` |
++-----------+------------------------------------------------------+
+| view GET | :meth:`hdalab.views.profile.HdalabRenkanGetPut.get` |
++-----------+------------------------------------------------------+
+| view POST | :meth:`hdalab.views.profile.HdalabRenkanGetPut.post` |
++-----------+------------------------------------------------------+
+
+A noter que l'appel de l'URL en GET ou POST mème à des vue différentes.
+
+
+Appel en HTTP GET:
+------------------
+
+.. automethod:: hdalab.views.profile.HdalabRenkanGetPut.get
+ :noindex:
+
+Appel en HTTP POST:
+-------------------
+
+.. automethod:: hdalab.views.profile.HdalabRenkanGetPut.post
+ :noindex:
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/source/api/hdabo.management.commands.rst Wed Apr 11 12:19:47 2018 +0200
@@ -0,0 +1,70 @@
+hdabo.management.commands package
+=================================
+
+Submodules
+----------
+
+hdabo.management.commands.clean\_tags module
+--------------------------------------------
+
+.. automodule:: hdabo.management.commands.clean_tags
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdabo.management.commands.diff\_csv module
+------------------------------------------
+
+.. automodule:: hdabo.management.commands.diff_csv
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdabo.management.commands.import\_csv module
+--------------------------------------------
+
+.. automodule:: hdabo.management.commands.import_csv
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdabo.management.commands.import\_rdf module
+--------------------------------------------
+
+.. automodule:: hdabo.management.commands.import_rdf
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdabo.management.commands.import\_tag\_popularity module
+--------------------------------------------------------
+
+.. automodule:: hdabo.management.commands.import_tag_popularity
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdabo.management.commands.order\_tags module
+--------------------------------------------
+
+.. automodule:: hdabo.management.commands.order_tags
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdabo.management.commands.query\_wikipedia module
+-------------------------------------------------
+
+.. automodule:: hdabo.management.commands.query_wikipedia
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+
+Module contents
+---------------
+
+.. automodule:: hdabo.management.commands
+ :members:
+ :undoc-members:
+ :show-inheritance:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/source/api/hdabo.management.rst Wed Apr 11 12:19:47 2018 +0200
@@ -0,0 +1,22 @@
+hdabo.management package
+========================
+
+Submodules
+----------
+
+hdabo.management.utils module
+-----------------------------
+
+.. automodule:: hdabo.management.utils
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+
+Module contents
+---------------
+
+.. automodule:: hdabo.management
+ :members:
+ :undoc-members:
+ :show-inheritance:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/source/api/hdabo.migrations.rst Wed Apr 11 12:19:47 2018 +0200
@@ -0,0 +1,30 @@
+hdabo.migrations package
+========================
+
+Submodules
+----------
+
+hdabo.migrations.0001\_initial module
+-------------------------------------
+
+.. automodule:: hdabo.migrations.0001_initial
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdabo.migrations.0002\_alter\_user\_fields\_after\_1\_8 module
+--------------------------------------------------------------
+
+.. automodule:: hdabo.migrations.0002_alter_user_fields_after_1_8
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+
+Module contents
+---------------
+
+.. automodule:: hdabo.migrations
+ :members:
+ :undoc-members:
+ :show-inheritance:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/source/api/hdabo.rst Wed Apr 11 12:19:47 2018 +0200
@@ -0,0 +1,101 @@
+hdabo package
+=============
+
+Subpackages
+-----------
+
+.. toctree::
+
+ hdabo.tests
+
+Submodules
+----------
+
+hdabo.admin module
+------------------
+
+.. automodule:: hdabo.admin
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdabo.context\_processors module
+--------------------------------
+
+.. automodule:: hdabo.context_processors
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdabo.django\_wsgi module
+-------------------------
+
+.. automodule:: hdabo.django_wsgi
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdabo.forms module
+------------------
+
+.. automodule:: hdabo.forms
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdabo.models module
+-------------------
+
+.. automodule:: hdabo.models
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdabo.search\_indexes module
+----------------------------
+
+.. automodule:: hdabo.search_indexes
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdabo.urls module
+-----------------
+
+.. automodule:: hdabo.urls
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdabo.utils module
+------------------
+
+.. automodule:: hdabo.utils
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdabo.views module
+------------------
+
+.. automodule:: hdabo.views
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdabo.wp\_utils module
+----------------------
+
+.. automodule:: hdabo.wp_utils
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+
+Module contents
+---------------
+
+.. automodule:: hdabo
+ :members:
+ :undoc-members:
+ :show-inheritance:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/source/api/hdabo.search.rst Wed Apr 11 12:19:47 2018 +0200
@@ -0,0 +1,22 @@
+hdabo.search package
+====================
+
+Submodules
+----------
+
+hdabo.search.french\_whoosh\_backend module
+-------------------------------------------
+
+.. automodule:: hdabo.search.french_whoosh_backend
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+
+Module contents
+---------------
+
+.. automodule:: hdabo.search
+ :members:
+ :undoc-members:
+ :show-inheritance:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/source/api/hdabo.templatetags.rst Wed Apr 11 12:19:47 2018 +0200
@@ -0,0 +1,22 @@
+hdabo.templatetags package
+==========================
+
+Submodules
+----------
+
+hdabo.templatetags.hdabo\_tags module
+-------------------------------------
+
+.. automodule:: hdabo.templatetags.hdabo_tags
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+
+Module contents
+---------------
+
+.. automodule:: hdabo.templatetags
+ :members:
+ :undoc-members:
+ :show-inheritance:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/source/api/hdabo.tests.rst Wed Apr 11 12:19:47 2018 +0200
@@ -0,0 +1,22 @@
+hdabo.tests package
+===================
+
+Submodules
+----------
+
+hdabo.tests.test\_models module
+-------------------------------
+
+.. automodule:: hdabo.tests.test_models
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+
+Module contents
+---------------
+
+.. automodule:: hdabo.tests
+ :members:
+ :undoc-members:
+ :show-inheritance:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/source/api/hdalab.management.commands.rst Wed Apr 11 12:19:47 2018 +0200
@@ -0,0 +1,118 @@
+hdalab.management.commands package
+==================================
+
+Submodules
+----------
+
+hdalab.management.commands.calculate\_preview module
+----------------------------------------------------
+
+.. automodule:: hdalab.management.commands.calculate_preview
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdalab.management.commands.export\_tags\_csv module
+---------------------------------------------------
+
+.. automodule:: hdalab.management.commands.export_tags_csv
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdalab.management.commands.export\_wpcategory\_csv module
+---------------------------------------------------------
+
+.. automodule:: hdalab.management.commands.export_wpcategory_csv
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdalab.management.commands.fill\_tag\_years module
+--------------------------------------------------
+
+.. automodule:: hdalab.management.commands.fill_tag_years
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdalab.management.commands.geojson\_transform module
+----------------------------------------------------
+
+.. automodule:: hdalab.management.commands.geojson_transform
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdalab.management.commands.import\_hda\_insee\_csv module
+---------------------------------------------------------
+
+.. automodule:: hdalab.management.commands.import_hda_insee_csv
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdalab.management.commands.import\_hdabo\_db module
+---------------------------------------------------
+
+.. automodule:: hdalab.management.commands.import_hdabo_db
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdalab.management.commands.import\_insee\_csv module
+----------------------------------------------------
+
+.. automodule:: hdalab.management.commands.import_insee_csv
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdalab.management.commands.query\_category\_inclusion module
+------------------------------------------------------------
+
+.. automodule:: hdalab.management.commands.query_category_inclusion
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdalab.management.commands.query\_dbpedia module
+------------------------------------------------
+
+.. automodule:: hdalab.management.commands.query_dbpedia
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdalab.management.commands.query\_geo\_inclusion module
+-------------------------------------------------------
+
+.. automodule:: hdalab.management.commands.query_geo_inclusion
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdalab.management.commands.query\_wikipedia\_category module
+------------------------------------------------------------
+
+.. automodule:: hdalab.management.commands.query_wikipedia_category
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdalab.management.commands.send\_moderation\_mail module
+--------------------------------------------------------
+
+.. automodule:: hdalab.management.commands.send_moderation_mail
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+
+Module contents
+---------------
+
+.. automodule:: hdalab.management.commands
+ :members:
+ :undoc-members:
+ :show-inheritance:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/source/api/hdalab.management.rst Wed Apr 11 12:19:47 2018 +0200
@@ -0,0 +1,22 @@
+hdalab.management package
+=========================
+
+Submodules
+----------
+
+hdalab.management.utils module
+------------------------------
+
+.. automodule:: hdalab.management.utils
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+
+Module contents
+---------------
+
+.. automodule:: hdalab.management
+ :members:
+ :undoc-members:
+ :show-inheritance:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/source/api/hdalab.migrations.rst Wed Apr 11 12:19:47 2018 +0200
@@ -0,0 +1,38 @@
+hdalab.migrations package
+=========================
+
+Submodules
+----------
+
+hdalab.migrations.0001\_initial module
+--------------------------------------
+
+.. automodule:: hdalab.migrations.0001_initial
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdalab.migrations.0002\_alter\_tagyears\_tag\_one2one module
+------------------------------------------------------------
+
+.. automodule:: hdalab.migrations.0002_alter_tagyears_tag_one2one
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdalab.migrations.0003\_default\_site module
+--------------------------------------------
+
+.. automodule:: hdalab.migrations.0003_default_site
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+
+Module contents
+---------------
+
+.. automodule:: hdalab.migrations
+ :members:
+ :undoc-members:
+ :show-inheritance:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/source/api/hdalab.models.rst Wed Apr 11 12:19:47 2018 +0200
@@ -0,0 +1,38 @@
+hdalab.models package
+=====================
+
+Submodules
+----------
+
+hdalab.models.categories module
+-------------------------------
+
+.. automodule:: hdalab.models.categories
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdalab.models.dataviz module
+----------------------------
+
+.. automodule:: hdalab.models.dataviz
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdalab.models.renkan module
+---------------------------
+
+.. automodule:: hdalab.models.renkan
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+
+Module contents
+---------------
+
+.. automodule:: hdalab.models
+ :members:
+ :undoc-members:
+ :show-inheritance:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/source/api/hdalab.rst Wed Apr 11 12:19:47 2018 +0200
@@ -0,0 +1,126 @@
+hdalab package
+==============
+
+Subpackages
+-----------
+
+.. toctree::
+
+ hdalab.models
+ hdalab.views
+
+Submodules
+----------
+
+hdalab.apps module
+------------------
+
+.. automodule:: hdalab.apps
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdalab.celery module
+--------------------
+
+.. automodule:: hdalab.celery
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdalab.config module
+--------------------
+
+.. automodule:: hdalab.config
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdalab.context\_processors module
+---------------------------------
+
+.. automodule:: hdalab.context_processors
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdalab.fields module
+--------------------
+
+.. automodule:: hdalab.fields
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdalab.forms module
+-------------------
+
+.. automodule:: hdalab.forms
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdalab.services module
+----------------------
+
+.. automodule:: hdalab.services
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdalab.settings module
+----------------------
+
+.. automodule:: hdalab.settings
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdalab.signals module
+---------------------
+
+.. automodule:: hdalab.signals
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdalab.tasks module
+-------------------
+
+.. automodule:: hdalab.tasks
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdalab.urls module
+------------------
+
+.. automodule:: hdalab.urls
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdalab.utils module
+-------------------
+
+.. automodule:: hdalab.utils
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdalab.wsgi module
+------------------
+
+.. automodule:: hdalab.wsgi
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+
+Module contents
+---------------
+
+.. automodule:: hdalab
+ :members:
+ :undoc-members:
+ :show-inheritance:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/source/api/hdalab.templatetags.rst Wed Apr 11 12:19:47 2018 +0200
@@ -0,0 +1,30 @@
+hdalab.templatetags package
+===========================
+
+Submodules
+----------
+
+hdalab.templatetags.analytics module
+------------------------------------
+
+.. automodule:: hdalab.templatetags.analytics
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdalab.templatetags.hdalab\_tags module
+---------------------------------------
+
+.. automodule:: hdalab.templatetags.hdalab_tags
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+
+Module contents
+---------------
+
+.. automodule:: hdalab.templatetags
+ :members:
+ :undoc-members:
+ :show-inheritance:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/source/api/hdalab.views.rst Wed Apr 11 12:19:47 2018 +0200
@@ -0,0 +1,46 @@
+hdalab.views package
+====================
+
+Submodules
+----------
+
+hdalab.views.ajax module
+------------------------
+
+.. automodule:: hdalab.views.ajax
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdalab.views.editorial module
+-----------------------------
+
+.. automodule:: hdalab.views.editorial
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdalab.views.pages module
+-------------------------
+
+.. automodule:: hdalab.views.pages
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+hdalab.views.profile module
+---------------------------
+
+.. automodule:: hdalab.views.profile
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+
+Module contents
+---------------
+
+.. automodule:: hdalab.views
+ :members:
+ :undoc-members:
+ :show-inheritance:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/source/api/modules.rst Wed Apr 11 12:19:47 2018 +0200
@@ -0,0 +1,8 @@
+src
+===
+
+.. toctree::
+ :maxdepth: 4
+
+ hdabo
+ hdalab
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/source/commandes.rst Wed Apr 11 12:19:47 2018 +0200
@@ -0,0 +1,226 @@
+#######################################
+Commandes d'administration HDABo/HDALab
+#######################################
+
+Le projet HDA fournis un ensemble de commande d'administration permettant de maintenir l'état de l'application.
+Ces commandes utilise le `système d'administration en ligne de commande de Django <https://docs.djangoproject.com/en/1.8/howto/custom-management-commands/>`_.
+L'usage des commande est en général le suivant:
+
+```
+django-admin <subcommand> [options] [arguments...]
+```
+
+Chaque commande implémente ses options et arguments.
+Toutes les commandes du projet accèptent les options suivante:
+
+ - *\-\-version* : montre le numeero de version et quitte.
+ - *\-h, \-\-help* : montre le message d'aide et quitte.
+ - *\-v VERBOSITY, \-\-verbosity=VERBOSITY* : Niveau de verbosité; 0=minimal, 1=normal, 2=verbeux, 3=très verbeux
+ - *\-\-settings=SETTINGS* : Le chemin Python vers un module de `settings`. Si il n'est pas fourni, la variable d'environement DJANGO_SETTINGS_MODULE sera utilisée.
+ - *\-\-pythonpath=PYTHONPATH* : un répertoire à ajouter au chemins Python (`Python path <https://docs.python.org/2/using/cmdline.html#envvar-PYTHONPATH>`_)
+ - *\-\-traceback* : Lève des exceptions `CommandError`.
+ - *\-\-no-color* : Ne colorise pas la sortie de la commande.
+
+Les options spécifiques sont doumentées pour chaque commande.
+
+
+Voici la liste des commandes hdalab:
+
+ - :ref:`commands-hdalab-calculate-preview`
+ - :ref:`commands-hdalab-export-tags-csv`
+ - :ref:`commands-hdalab-export-wpcategory-csv`
+ - :ref:`commands-hdalab-fill-tag-years`
+ - :ref:`commands-hdalab-geojson-transform`
+ - :ref:`commands-hdalab-import-hda-insee-csv`
+ - :ref:`commands-hdalab-import-hdabo-db`
+ - :ref:`commands-hdalab-import-insee-csv`
+ - :ref:`commands-hdalab-query-category-inclusion`
+ - :ref:`commands-hdalab-query-dbpedia`
+ - :ref:`commands-hdalab-query-geo-inclusion`
+ - :ref:`commands-hdalab-query-wikipedia-category`
+ - :ref:`commands-hdalab-send-moderation-mail`
+
+et la liste des commandes hdabo:
+
+ - :ref:`commands-hdabo-clean-tags`
+ - :ref:`commands-hdabo-diff-csv`
+ - :ref:`commands-hdabo-import-csv`
+ - :ref:`commands-hdabo-import-rdf`
+ - :ref:`commands-hdabo-import-tag-popularity`
+ - :ref:`commands-hdabo-order-tags`
+ - :ref:`commands-hdabo-query-wikipedia`
+
+Il est à noter que ce dans cette dernière liste seule la commande :ref:`commands-hdabo-import-rdf` est utilisée régulièrement pour importer les données HDA dans HDALab.
+
+
+Commandes hdabo
+===============
+
+.. _commands-hdabo-clean-tags:
+
+clean\_tags
+-----------
+
+.. automodule:: hdabo.management.commands.clean_tags
+
+
+.. _commands-hdabo-diff-csv:
+
+diff\_csv
+---------
+
+.. automodule:: hdabo.management.commands.diff_csv
+
+
+
+.. _commands-hdabo-import-csv:
+
+import\_csv
+-----------
+
+.. automodule:: hdabo.management.commands.import_csv
+
+
+.. _commands-hdabo-import-rdf:
+
+import\_rdf
+-----------
+
+.. automodule:: hdabo.management.commands.import_rdf
+
+
+.. _commands-hdabo-import-tag-popularity:
+
+import\_tag\_popularity
+-----------------------
+
+.. automodule:: hdabo.management.commands.import_tag_popularity
+
+
+.. _commands-hdabo-order-tags:
+
+order\_tags
+-----------
+
+.. automodule:: hdabo.management.commands.order_tags
+
+
+
+.. _commands-hdabo-query-wikipedia:
+
+query\_wikipedia
+----------------
+
+.. automodule:: hdabo.management.commands.query_wikipedia
+
+
+
+Commandes hdalab
+================
+
+.. _commands-hdalab-calculate-preview:
+
+calculate\_preview
+------------------
+
+.. automodule:: hdalab.management.commands.calculate_preview
+
+
+.. _commands-hdalab-export-tags-csv:
+
+export\_tags\_csv
+-----------------
+
+.. automodule:: hdalab.management.commands.export_tags_csv
+
+
+.. _commands-hdalab-export-wpcategory-csv:
+
+export\_wpcategory\_csv
+-----------------------
+
+.. automodule:: hdalab.management.commands.export_wpcategory_csv
+
+
+.. _commands-hdalab-fill-tag-years:
+
+fill\_tag\_years
+----------------
+
+.. automodule:: hdalab.management.commands.fill_tag_years
+
+
+.. _commands-hdalab-geojson-transform:
+
+geojson\_transform
+------------------
+
+.. automodule:: hdalab.management.commands.geojson_transform
+
+
+
+.. _commands-hdalab-import-hda-insee-csv:
+
+import\_hda\_insee\_csv
+-----------------------
+
+.. automodule:: hdalab.management.commands.import_hda_insee_csv
+
+
+.. _commands-hdalab-import-hdabo-db:
+
+import\_hdabo\_db
+-----------------
+
+.. automodule:: hdalab.management.commands.import_hdabo_db
+
+
+.. _commands-hdalab-import-insee-csv:
+
+import\_insee\_csv
+------------------
+
+.. automodule:: hdalab.management.commands.import_insee_csv
+
+
+
+.. _commands-hdalab-query-category-inclusion:
+
+query\_category\_inclusion
+--------------------------
+
+.. automodule:: hdalab.management.commands.query_category_inclusion
+
+
+.. _commands-hdalab-query-dbpedia:
+
+query\_dbpedia
+--------------
+
+.. automodule:: hdalab.management.commands.query_dbpedia
+
+
+
+.. _commands-hdalab-query-geo-inclusion:
+
+query\_geo\_inclusion
+---------------------
+
+.. automodule:: hdalab.management.commands.query_geo_inclusion
+
+
+.. _commands-hdalab-query-wikipedia-category:
+
+query\_wikipedia\_category
+--------------------------
+
+.. automodule:: hdalab.management.commands.query_wikipedia_category
+
+
+
+.. _commands-hdalab-send-moderation-mail:
+
+send\_moderation\_mail
+----------------------
+
+.. automodule:: hdalab.management.commands.send_moderation_mail
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/source/conf.py Wed Apr 11 12:19:47 2018 +0200
@@ -0,0 +1,195 @@
+# -*- coding: utf-8 -*-
+#
+# Configuration file for the Sphinx documentation builder.
+#
+# This file does only contain a selection of the most common options. For a
+# full list see the documentation:
+# http://www.sphinx-doc.org/en/stable/config
+
+# -- Path setup --------------------------------------------------------------
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#
+import os
+import sys
+
+import django
+
+sys.path.insert(0, os.path.abspath('../../src'))
+sys.setrecursionlimit(1500)
+
+os.environ['DJANGO_SETTINGS_MODULE'] = 'hdalab.settings'
+django.setup()
+
+# -- Project information -----------------------------------------------------
+
+project = u'HDALab'
+copyright = u'2018, IRI'
+author = u'Yves-Marie Haussonne'
+
+# The short X.Y version
+version = u''
+# The full version, including alpha/beta/rc tags
+release = u'3.2.1'
+
+
+# -- General configuration ---------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#
+# needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = [
+ 'sphinx.ext.autodoc',
+ 'sphinx.ext.todo',
+ 'sphinx.ext.viewcode',
+]
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix(es) of source filenames.
+# You can specify multiple suffix as a list of string:
+#
+# source_suffix = ['.rst', '.md']
+source_suffix = '.rst'
+
+# The master toctree document.
+master_doc = 'index'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#
+# This is also used if you do content translation via gettext catalogs.
+# Usually you set "language" from the command line for these cases.
+language = u'fr'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+# This pattern also affects html_static_path and html_extra_path .
+exclude_patterns = []
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+
+# -- Options for HTML output -------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+#
+html_theme = 'alabaster'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further. For a list of options available for each theme, see the
+# documentation.
+#
+# html_theme_options = {}
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# Custom sidebar templates, must be a dictionary that maps document names
+# to template names.
+#
+# The default sidebars (for documents that don't match any pattern) are
+# defined by theme itself. Builtin themes are using these templates by
+# default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
+# 'searchbox.html']``.
+#
+# html_sidebars = {}
+
+
+# -- Options for HTMLHelp output ---------------------------------------------
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'HDALabdoc'
+
+
+# -- Options for LaTeX output ------------------------------------------------
+
+latex_elements = {
+ # The paper size ('letterpaper' or 'a4paper').
+ #
+ # 'papersize': 'letterpaper',
+
+ # The font size ('10pt', '11pt' or '12pt').
+ #
+ # 'pointsize': '10pt',
+
+ # Additional stuff for the LaTeX preamble.
+ #
+ # 'preamble': '',
+
+ # Latex figure (float) alignment
+ #
+ # 'figure_align': 'htbp',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title,
+# author, documentclass [howto, manual, or own class]).
+latex_documents = [
+ (master_doc, 'HDALab.tex', u'HDALab Documentation',
+ u'ymh', 'manual'),
+]
+
+
+# -- Options for manual page output ------------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+ (master_doc, 'hdalab', u'HDALab Documentation',
+ [author], 1)
+]
+
+
+# -- Options for Texinfo output ----------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+# dir menu entry, description, category)
+texinfo_documents = [
+ (master_doc, 'HDALab', u'HDALab Documentation',
+ author, 'HDALab', 'One line description of project.',
+ 'Miscellaneous'),
+]
+
+
+# -- Extension configuration -------------------------------------------------
+
+# -- Options for todo extension ----------------------------------------------
+
+# If true, `todo` and `todoList` produce output, else they produce nothing.
+todo_include_todos = True
+
+# True to prefix each section label with the name of the document it is in, followed by a colon.
+# For example, index:Introduction for a section called Introduction that appears in document index.rst.
+# Useful for avoiding ambiguity when the same section heading appears in different documents.
+
+autosectionlabel_prefix_document = True
+
+
+autodoc_mock_imports = ["haystack.backends.whoosh_backend.SearchBackend"]
+
+html_theme_options = {
+ 'logo': 'img/logo_iri.png',
+}
+
+html_sidebars = {
+ '**': [
+ 'about.html',
+ 'localtoc.html',
+ 'relations.html',
+ # 'sourcelink.html',
+ 'searchbox.html'
+ ]
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/source/dev.rst Wed Apr 11 12:19:47 2018 +0200
@@ -0,0 +1,216 @@
+####################
+Images Docker HDALab
+####################
+
+
+L'application HDALab a été conteneurisée en 5 services dont 2 nécessite
+la construction d'une image. Les services sont orchestrés avec
+l'application ``docker-compose``. L'ensemble expose les ports suivant
+sur l'ordinateur hôte:
+
+ - port 8080 : l'interface web HDALab
+ - port 8025 : Accès à l'interface de consultation `mailhog <https://github.com/mailhog/MailHog>`__.
+ - port 5432 : port serveur postgresql
+
+Mise place des images conteneurs docker
+---------------------------------------
+
+Deux possibilités existent pour mettre en place les images docker :
+ - construire les images
+ - import des images
+
+Construction des images
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Les commandes suivantes permettent de construire les images. Ces
+commandes sont à lancer dans le même répertoire que le fichier
+``docker-compose.yml``.
+
+::
+
+ $ ./prepare_docker_build.sh
+ $ docker-compose -p hdalab build
+
+Import des images
+~~~~~~~~~~~~~~~~~
+
+Lancer cette commande pour charger les images du projet.
+
+::
+
+ $ docker load -i <chemin/vers/fichier/archives/images>
+
+Comment construire les container HDALab
+---------------------------------------
+
+Toutes les commandes suivantes sont à effectuer dans le répertoire
+contenant le fichier ``docker-compose.yml``.
+
+::
+
+ $ docker-compose -p hdalab up -d
+ $ docker-compose -p hdalab exec hdalab django-admin collectstatic --noinput
+ $ docker-compose -p hdalab exec hdalab django-admin migrate --noinput
+ $ docker-compose -p hdalab exec hdalab supervisorctl restart all
+
+Le site est consultable à l'adresse suivante : http://127.0.0.1:8080 Le
+système est fonctionnel mais avec une bases de donnée vide.
+
+Lancement d'une commande Django
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Lancer cette commande pour avoir accès à l'utilitaire de gestion Django
+(c.f.
+`django-admin <https://docs.djangoproject.com/en/1.8/ref/django-admin/>`__)
+
+::
+
+ $ docker-compose -p hdalab exec hdalab django-admin <command> [options]
+
+Pour obtenir la liste des commandes disponibles faire:
+
+::
+
+ $ docker-compose -p hdalab exec hdalab django-admin
+
+Création d'un "superuser"
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Cette commande permet la creation d'un utilisateur administeur de
+l'application.
+
+::
+
+ $ docker-compose -p hdalab exec hdalab django-admin createsuperuser
+
+Import des données issues de l'export HDA
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Cette commande importe les données RDF exportées à partir de
+l'application HDA. Attention cette commande peut être longue (plusieurs
+heures).
+
+::
+
+ $ docker-compose -p hdalab exec hdalab /usr/local/sbin/import_hda_rdf.sh /etc/hdalab/data /var/lib/hdalab http://data.culture.fr/entrepot/HDA/export.tgz
+
+Import d'un dump de l'application
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Import d'un dump de la base de donnée
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Le fichier de dump de base de données doit être décompressé.
+
+::
+
+ $ docker-compose -p hdalab stop hdalab
+ $ docker exec -i hdalab_pg_1 psql -U iri postgres < </chemin/du/fichier/dump/sql.bckp>
+ $ docker-compose -p hdalab start hdalab
+ $ docker-compose -p hdalab exec hdalab django-admin migrate --noinput
+ $ echo "from django.contrib.sites.models import Site; site=Site.objects.all()[0]; site.domain='127.0.0.1:8080'; site.name='HDALab'; site.save()" | docker exec -i hdalab_hdalab_1 django-admin shell
+ $ docker-compose -p hdalab exec hdalab django-admin changepassword admin
+ $ docker-compose -p hdalab exec hdalab django-admin rebuild_index --noinput
+
+Import des miniatures renkan
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Ces commandes supposent que le service ``hdalab`` est actif. L'archive
+comprenant l'export des miniatures doit être décompressé. Cette archive
+contient le répertoire ``media`` à la racine
+
+::
+
+ $ docker cp ./media/. hdalab_hdalab_1:/var/lib/hdalab/static/media
+
+Commandes utiles
+================
+
+liste des services
+------------------
+
+Les services suivants sont définis dans le fichier
+``docker-compose.yml``: - pg : La base de donnée postgresql - es :
+ElasticSearch - mail : Mailhog, fourni un serveur smtp de test - front :
+Le serveur web (nginx) - hdalab : application hdalab comprenant
+l'application web elle-même et les services associés (envoi de mail et
+calcul des preevisualisations Renkan)
+
+Démarrage des services
+----------------------
+
+Les services se contrôlent avec la commande ``docker-compose``. La ligne
+de commande typique est la suivante:
+
+::
+
+ $ docker-compose [-f </path/to/docker-compose.yml>] -p hdalab [COMMAND] [ARGS...]
+
+Il faut bien noter l'utilisation systématique de l'option ``-p hdalab``
+qui spécifie le nom du projet. Si la commande est lancée dans le même
+répertoire que celui du fichier ``docker-compose.yml`` l'option ``-f``
+peut être ignorée.
+
+Construction des images des conteneurs
+--------------------------------------
+
+::
+
+ $ docker-compose [-f </path/to/docker-compose.yml>] -p hdalab build [SERVICE...]
+
+création et lancement des services
+----------------------------------
+
+::
+
+ $ docker-compose [-f </path/to/docker-compose.yml>] -p hdalab up -d [SERVICE...]
+
+A noter l'option ``-d`` qui mettent les services en tache de fond.
+
+lancement des services
+----------------------
+
+::
+
+ $ docker-compose [-f </path/to/docker-compose.yml>] -p hdalab run SERVICE [COMMAND] [ARGS...]
+
+Cette commande lance un service.
+
+Execution d'une commande sur un service lancé
+---------------------------------------------
+
+::
+
+ $ docker-compose [-f </path/to/docker-compose.yml>] -p hdalab exec SERVICE COMMAND [ARGS...]
+
+arrêt des services
+------------------
+
+::
+
+ $ docker-compose [-f </path/to/docker-compose.yml>] -p hdalab stop [SERVICE...]
+
+consulter la sortie des containers
+----------------------------------
+
+::
+
+ $ docker-compose [-f </path/to/docker-compose.yml>] -p hdalab logs [-f] [SERVICE...]
+
+effacement et recréation de la base de donnée vide
+--------------------------------------------------
+
+Attention, toutes les données de la base seront définitivement
+supprimées.
+
+::
+
+ $ docker-compose [-f </path/to/docker-compose.yml>] -p hdalab stop hdalab
+ $ echo "drop database hdalab;\ncreate database hdalab owner iri encoding 'utf-8';" | docker exec -i hdalab_pg_1 psql -U iri postgres
+
+Accès à la base de donnée
+-------------------------
+
+Le port postgresql 5432 est ouvert sur l'ordinateur hôte. La base
+utilisée par l'application est ``hdalab``. L'utilisateur et mot de passe
+pour y accéder sont : - utilisateur: ``iri`` - mot de passe: ``iri``
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/source/index.rst Wed Apr 11 12:19:47 2018 +0200
@@ -0,0 +1,27 @@
+.. HDALab documentation master file.
+
+####################
+Documentation HDALab
+####################
+
+Cette documentation couvre le site HDALab.
+
+Ce site est réalise en python et utilise le framework Django (version 1.8).
+
+Cette documentation n'entrera pas dans le détail des fonctionnalités Django et assume donc une connaissance générale de Django par le lecteur.
+Vous pouvez trouver la documentation de Django (version 1.8) à l'url suivante : https://docs.djangoproject.com/en/1.8/.
+
+
+.. toctree::
+ :maxdepth: 2
+ :caption: Contenu de cette documentation:
+
+ pages
+ api
+ renkan
+ commandes
+ taches
+ dev
+ Documentation API <api/modules>
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/source/pages.rst Wed Apr 11 12:19:47 2018 +0200
@@ -0,0 +1,885 @@
+.. Description des pages
+
+############################
+Description des pages HDALab
+############################
+
+Ces pages constituent la navigation principale du site HDALab.
+
+
+Acceuil
+=======
+
+.. image:: _static/img/pages/accueil_hdalab.png
+
+Page d'acceuil d'HDALab.
+
+
++----------+----------------------------------------+
+| url | http://hdalab.iri-research.org/hdalab |
++----------+----------------------------------------+
+| view | django.views.generic.TemplateView |
++----------+----------------------------------------+
+| template | hdalab/templates/index.html |
++----------+----------------------------------------+
+
+
+
+A propos
+========
+
+.. image:: _static/img/pages/apropos_hdalab.png
+
+Page décrivant le projet HDALab avec une vidéo de tutoriel Renkan.
+
+
++----------+---------------------------------------------------------+
+| url | http://hdalab.iri-research.org/hdalab/hdalab/a_propos/ |
++----------+---------------------------------------------------------+
+| view | :class:`hdalab.views.pages.HdalabAboutPage` |
++----------+---------------------------------------------------------+
+| template | hdalab/templates/a_propos.html |
++----------+---------------------------------------------------------+
+
+
+
+Crédits
+=======
+
+.. image:: _static/img/pages/credits_hdalab.png
+
+Page de crédits du site.
+
+
++----------+--------------------------------------------------------+
+| url | http://hdalab.iri-research.org/hdalab/hdalab/credits/ |
++----------+--------------------------------------------------------+
+| view | django.views.generic.TemplateView |
++----------+--------------------------------------------------------+
+| template | hdalab/templates/credits.html |
++----------+--------------------------------------------------------+
+
+
+
+
+Mentions légales
+================
+
+.. image:: _static/img/pages/mentions_legales_hdalab.png
+
+Page des mentions légales.
+
++----------+----------------------------------------------------------------+
+| url | http://hdalab.iri-research.org/hdalab/hdalab/mentions_legales/ |
++----------+----------------------------------------------------------------+
+| view | django.views.generic.TemplateView |
++----------+----------------------------------------------------------------+
+| template | hdalab/templates/mentions_legales.html |
++----------+----------------------------------------------------------------+
+
+
+
+Contact
+=======
+
+.. image:: _static/img/pages/contact_hdalab.png
+
+Formulaire de contact pour poser une question à l'équipe HDALab.
+Cette partie de l'application s'appuie sur le module `django-envelope <https://github.com/zsiciarz/django-envelope>`_.
+
+
++----------+-------------------------------------------------------+
+| url | http://hdalab.iri-research.org/hdalab/hdalab/contact/ |
++----------+-------------------------------------------------------+
+| view | envelope.views.ContactView |
++----------+-------------------------------------------------------+
+| template | - hdalab/templates/envelope/contact.html |
+| | - hdalab/templates/envelope/email_body.html |
+| | - hdalab/templates/envelope/email_body.txt |
++----------+-------------------------------------------------------+
+
+
+.. _pages_liste_renkan_publics:
+
+Liste des renkan publics
+========================
+
+.. image:: _static/img/pages/renkan_public.png
+
+Page listant l'ensemble des renkan publiés (et modéré).
+
++----------+------------------------------------------------------+
+| url | http://hdalab.iri-research.org/hdalab/renkan/public/ |
++----------+------------------------------------------------------+
+| view | :class:`hdalab.views.profile.RenkanPublicList` |
++----------+------------------------------------------------------+
+| template | hdalab/templates/renkan_list.html |
++----------+------------------------------------------------------+
+
+Note : Les templates hdalab/templates/renkan_list.html et hdalab/templates/renkan_list_favorite.html sont presque les mêmes.
+
+
+.. _pages_liste_renkan_favoris:
+
+Liste des renkan favoris
+========================
+
+.. image:: _static/img/pages/renkan_favorite.png
+
+Page listant l'ensemble des renkan ayant été marqués comme favoris par l'équipe HDALab.
+
++----------+--------------------------------------------------------+
+| url | http://hdalab.iri-research.org/hdalab/renkan/favorite/ |
++----------+--------------------------------------------------------+
+| view | :class:`hdalab.views.profile.RenkanFavoriteList` |
++----------+--------------------------------------------------------+
+| template | hdalab/templates/renkan_list_favorite.html |
++----------+--------------------------------------------------------+
+
+Note : Les templates hdalab/templates/renkan_list.html et hdalab/templates/renkan_list_favorite.html sont presque les mêmes.
+
+
+
+.. _pages_recherche_facette:
+
+Recherche (facette)
+===================
+
+.. image:: _static/img/pages/facettes_hdalab.png
+
+Page de recherche par facette.
+Cette page est relativement complexe.
+Elle contient une application javascript permettant l'édition du filtre par facette et l'affichage des résultats.
+
++----------+-------------------------------------------------+
+| url | http://hdalab.iri-research.org/hdalab/facettes/ |
++----------+-------------------------------------------------+
+| view | django.views.generic.base.TemplateView |
++----------+-------------------------------------------------+
+| template | hdalab/templates/facettes.html |
++----------+-------------------------------------------------+
+
+Le code javascript se trouve dans le fichier `hdalab/static/hdalab/js/gomina.js`.
+Les données pour la page sont chargées par l'url http://hdalab.iri-research.org/hdalab/a/filter.
+L'auto-completion pour la saisie de mot-clef lance des requêtes à l'URL suivante : http://hdalab.iri-research.org/hdalab/a/tagsearch.
+
+Les liens d'édition des renkan sont http://hdalab.iri-research.org/hdalab/renkan/edit/.
+
+
+Détail d'une fiche
+==================
+
+.. image:: _static/img/pages/detail_notice.png
+
+
+cette page affiche le détail d'une notice.
+Elle est contituée des éléments suivant disposés en trois colonnes :
+
+ - Le détail de la notice
+ - La liste des mots-clef de la notice
+ - La liste des notices liées
+
+Lorsqu'on clique sur un mot-clef, la liste dest notices liées est filtrée et n'affiche plus que les notices concernées par le mot-clef.
+
+
++----------+----------------------------------------------------------+
+| url | http://hdalab.iri-research.org/hdalab/notice/{notice_id} |
++----------+----------------------------------------------------------+
+| view | :func:`hdalab.views.pages.datasheet` |
++----------+----------------------------------------------------------+
+| template | hdalab/templates/notice.html |
++----------+----------------------------------------------------------+
+
+
+.. _pages_edition_renkan:
+
+Édition d'un renkan
+===================
+
+.. image:: _static/img/pages/renkan_edit.png
+
+Page d'édition et de création d'un renkan.
+Cette page instancie un éditeur de renkan.
+
++----------+----------------------------------------------------+
+| url | http://hdalab.iri-research.org/hdalab/renkan/edit/ |
++----------+----------------------------------------------------+
+| view | :class:`hdalab.views.profile.RenkanEdit` |
++----------+----------------------------------------------------+
+| template | hdalab/templates/renkan_edit.html |
++----------+----------------------------------------------------+
+
+
+L'éditeur de renkan fait alors appel à l'url suivante pour charger et sauvegarder un projet renkan :
+http://hdalab.iri-research.org/hdalab/renkan/getput/
+
+
+
+.. _affichage-d-un-renkan-en-lecture-seule:
+
+Affichage d'un renkan en lecture seule
+======================================
+
+.. image:: _static/img/pages/renkan_view.png
+
+Page d'affichage d'un renkan en lecture seule.
+
++----------+----------------------------------------------------+
+| url | http://hdalab.iri-research.org/hdalab/renkan/view/ |
++----------+----------------------------------------------------+
+| view | django.views.generic.base.TemplateView |
++----------+----------------------------------------------------+
+| template | hdalab/templates/renkan_view.html |
++----------+----------------------------------------------------+
+
+Cette page instancie un composant renkan en lecture seule.
+Le projet renkan est chargé par appel (GET) à l'URL http://hdalab.iri-research.org/hdalab/renkan/getput/.
+
+Les arguments d'affichage (par exemple l'identifiant du renkan) sont passés en javascript grâce à la propriété `window.location.search <https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/search>`_ (La partie de l'URL qui suit le symbole « ? », avec ce symbole inclus.)
+
+
+
+.. _affichage-d-un-renkan-en-plein-ecran:
+
+Affichage d'un renkan en plein-écran
+====================================
+
+.. image:: _static/img/pages/renkan_view_full.png
+
+Page d'affichage d'un renkan en lecture seule et en plein écran.
+
++----------+----------------------------------------------------+
+| url | http://hdalab.iri-research.org/hdalab/renkan/full/ |
++----------+----------------------------------------------------+
+| view | django.views.generic.base.TemplateView |
++----------+----------------------------------------------------+
+| template | hdalab/templates/renkan_view_full.html |
++----------+----------------------------------------------------+
+
+cette page permet l'affichage d'un renkan en plein-écran, sans les en-tête, pied de page, barre de navigation,...
+Cette page est utilisée pour la création des miniature de prévisualisation des renkan.
+
+Sur le fonctionnement elle est identique à la page ":ref:`affichage-d-un-renkan-en-lecture-seule`, en particulier sur la façon dont les arguments sont passés.
+
+
+
+.. _pages_explorer_domaines_artistiques:
+
+Explorer les domaines artistiques
+=================================
+
+.. image:: _static/img/pages/artistic_domains_hdalab.png
+
+Cette page permet d'explorer les fiches HDA par le biais des domaines artistiques.
+
++----------+----------------------------------------------------+
+| url | http://hdalab.iri-research.org/hdalab/categories/ |
++----------+----------------------------------------------------+
+| view | django.views.generic.base.TemplateView |
++----------+----------------------------------------------------+
+| template | hdalab/templates/categories.html |
++----------+----------------------------------------------------+
+
+Cette page contient une application javascript s'occupant du chargement de de l'affichage des données.
+Les données sont chargées à l'url suivante : http://hdalab.iri-research.org/hdalab/a/cattree
+Le code javascript de cette page se trouve dans les fichiers `hdalab/static/hdalab/js/trees.js` et `hdalab/static/hdalab/js/cattree.js`.
+
+
+
+.. _pages_recherche_arbre:
+
+Recherche par arbre
+===================
+
+.. image:: _static/img/pages/tree_search_hdalab.png
+
+Cette page permet de comparer deux extraits de thesaurus utilisés par le MCC.
+
++----------+----------------------------------------------------+
+| url | http://hdalab.iri-research.org/hdalab/thesaurus/ |
++----------+----------------------------------------------------+
+| view | django.views.generic.base.TemplateView |
++----------+----------------------------------------------------+
+| template | hdalab/templates/thesaurus.html |
++----------+----------------------------------------------------+
+
+Cette page contient une application javascript s'occupant du chargement et de l'afficahge des données.
+Les données sont chargées à l'url suivante : http://hdalab.iri-research.org/hdalab/a/filltree
+Le code javascript de cette page se trouve dans les fichiers `hdalab/static/hdalab/js/trees.js` et `hdalab/static/hdalab/js/thesaurus.js`.
+
+
+.. _pages-d-administration-django-hdalab-hdabo:
+
+Pages d'administration Django hdalab/hdabo
+==========================================
+
+.. image:: _static/img/pages/admin_django_hdalab.png
+
+
+Ce sont toutes les pages dont l'URL commence par http://hdalab.iri-research.org/hdalab/hdabo/admin/ .
+Elles nécessitent toute une authentification.
+L'ensemble de ces pages est fournis par l'application d'administration Django fourni d'origine par le framework.
+Le lien suivant en donne une documentation : https://docs.djangoproject.com/en/1.8/ref/contrib/admin/.
+
+Les objets suivant sont configurés pour être administrables:
+
+ - :class:`hdabo.models.Author`
+ - :class:`hdabo.models.Datasheet`
+ - :class:`hdabo.models.DocumentFormat`
+ - :class:`hdabo.models.Domain`
+ - :class:`hdabo.models.Organisation`
+ - :class:`hdabo.models.Tag`
+ - :class:`hdabo.models.TagCategory`
+ - :class:`hdabo.models.TaggedSheet`
+ - :class:`hdabo.models.TimePeriod`
+ - :class:`hdabo.models.User`
+ - `registration.models.RegistrationProfile`
+ - `django.contrib.sites.models import Site`
+
+
+.. _pages_page_profil_utilisateur:
+
+Page profil utilisateur
+=======================
+
+.. image:: _static/img/pages/user_profile_hdalab.png
+
+
+Page de gestion du profile utilisateur.
+Elle permet l'accès à la gestion de ses renkan et de son profile utilisateur.
+Cette page nécessite d'être authentifié.
+
++----------+----------------------------------------------------+
+| url | http://hdalab.iri-research.org/hdalab/profile/ |
++----------+----------------------------------------------------+
+| view | :class:`hdalab.views.profile.ProfileHome` |
++----------+----------------------------------------------------+
+| template | hdalab/templates/profile_home.html |
++----------+----------------------------------------------------+
+
+Entre outre des fonction de gestion des renkan, cette page donne accès aux liens suivants:
+
+ - http://hdalab.iri-research.org/hdalab/hdabo/accounts/password/change/ : modification du mot de passe.
+ - http://hdalab.iri-research.org/hdalab/profile/update/ : modification des informations utilisateur (c.f. :ref:`changement-information-utilisateur`)
+
+Si l'utilisateur est identifié comme `staff <https://docs.djangoproject.com/en/1.8/ref/contrib/auth/#django.contrib.auth.models.User.is_staff>`_, il a accès aux line supplémentaires:
+
+ - http://hdalab.iri-research.org/hdalab/edito/manage/
+ - http://hdalab.iri-research.org/hdalab/edito/ :
+ - http://hdalab.iri-research.org/hdalab/hdabo/admin/ : :ref:`pages-d-administration-django-hdalab-hdabo`
+ - http://hdalab.iri-research.org/hdalab/hdabo/ : **obsolète**
+
+
+
+
+.. _changement-information-utilisateur:
+
+Changement information utilisateur
+==================================
+
+.. image:: _static/img/pages/user_info_hdalab.png
+
+Page permettant de modifier les information du profile utilisateur. Dans le cas d'HDALab, cela se limite à la modification de l'email de contact.
+Cette page nécessite d'être authentifié.
+
++----------+----------------------------------------------------------+
+| url | http://hdalab.iri-research.org/hdalab/profile/update |
++----------+----------------------------------------------------------+
+| view | :class:`hdalab.views.profile.UserProfileUpdate` |
++----------+----------------------------------------------------------+
+| template | hdalab/templates/hdabo/user_update_form.html |
++----------+----------------------------------------------------------+
+
+
+Éditorialisation
+================
+
+.. image:: _static/img/pages/editorialisation_hdalab.png
+
+
+Page donnant accès aux fonction de gestion de l'éditorialisation.
+
++----------+----------------------------------------------------------+
+| url | http://hdalab.iri-research.org/hdalab/edito/ |
++----------+----------------------------------------------------------+
+| view | django.views.generic.base.TemplateView |
++----------+----------------------------------------------------------+
+| template | hdalab/templates/editorial/edito_home.html |
++----------+----------------------------------------------------------+
+
+
+Cette page propose les 2 liens suivants:
+
+ - http://hdalab.iri-research.org/hdalab/edito/folders/ : :ref:`gestion-des-dossiers-thematiques`
+ - http://hdalab.iri-research.org/hdalab/edito/manage/ : :ref:`gestion-des-renkan-moderation`
+
+
+
+
+.. _gestion-des-dossiers-thematiques:
+
+Gestion des dossiers thématiques
+================================
+
+.. image:: _static/img/pages/thematic_folder_hdalab.png
+
+
+Cette page donne accès au tableau des dossiers thématiques.
+
+
++----------+----------------------------------------------------------+
+| url | http://hdalab.iri-research.org/hdalab/edito/folders/ |
++----------+----------------------------------------------------------+
+| view | :class:`hdalab.views.editorial.HdalabFolders` |
++----------+----------------------------------------------------------+
+| template | hdalab/templates/editorial/folders.html |
++----------+----------------------------------------------------------+
+
+
+
+.. _gestion-des-renkan-moderation:
+
+Gestion des renkan (modération)
+===============================
+
+
+.. image:: _static/img/pages/administrer_renkan.png
+
+Page de modération des renkans.
+
+
++----------+----------------------------------------------------------+
+| url | http://hdalab.iri-research.org/hdalab/edito/manage/ |
++----------+----------------------------------------------------------+
+| view | :class:`hdalab.views.editorial.ManageRenkans` |
++----------+----------------------------------------------------------+
+| template | hdalab/templates/editorial/manage_renkans.html |
++----------+----------------------------------------------------------+
+
+
+
+.. _pages_liste_renkan:
+
+Pages de liste des Renkan
+=========================
+
+.. image:: _static/img/pages/renkan_base_list.png
+
+Ce sont les pages dont la vue hérite de :class:`hdalab.views.profile.BaseRenkanList`.
+Ces vues permettent de gérer une liste de Renkan avec un système de filtre et de pagination.
+Les actions suivantes sont disponibles :
+
+ - copie : :ref:`pages_copier_renkan`
+ - affichage : :ref:`affichage-d-un-renkan-en-lecture-seule`
+ - modération (si l'utilisateur est autorisé) : :ref:`pages_moderation_renkan`
+ - édition (si l'utilisateur est autorisé) : :ref:`pages_edition_renkan`
+ - effacement (si l'utilisateur est autorisé) : :ref:`pages_effacer_renkan`
+ - favori (si l'utilisateur est autorisé) : :ref:`pages_favori_renkan`
+ - création d'un nouveau renkan vide : :ref:`pages_nouveau_renkan`
+
+.. autoclass:: hdalab.views.profile.BaseRenkanList
+ :noindex:
+
+Voici la liste des pages héritant de :class:`hdalab.views.profile.BaseRenkanList` :
+
+ - :ref:`gestion-des-renkan-moderation`
+ - :ref:`pages_liste_renkan_publics`
+ - :ref:`pages_liste_renkan_favoris`
+ - :ref:`pages_page_profil_utilisateur`
+
+
+Pages de commande de Renkan
+===========================
+
+Ces pages sont appelées à partir des pages listant les renkan, en particulier celle dont la vue hérite de :class:`hdalab.views.profile.BaseRenkanList`
+
+
+.. _pages_copier_renkan:
+
+Copier un renkan
+----------------
+
+Copie un renkan dont l'id est donné dans l'url.
+L'utilisateur est redirigé vers la page de liste des Renkan.
+
++-------------+-----------------------------------------------------------+
+| url | http://hdalab.iri-research.org/hdalab/renkan/copy/<rk_id> |
++-------------+-----------------------------------------------------------+
+| view | :class:`hdalab.views.profile.HdalabRenkanCopy` |
++-------------+-----------------------------------------------------------+
+| méthode | POST |
++-------------+-----------------------------------------------------------+
+| redirection | Page de liste des renkan. |
++-------------+-----------------------------------------------------------+
+
+
+.. automethod:: hdalab.views.profile.HdalabRenkanCopy.post
+ :noindex:
+
+.. _pages_effacer_renkan:
+
+Effacer un renkan
+-----------------
+
+Effacer un renkan dont l'id est donné dans l'URL.
+
++-------------+-------------------------------------------------------------+
+| url | http://hdalab.iri-research.org/hdalab/renkan/delete/<rk_id> |
++-------------+-------------------------------------------------------------+
+| view | :class:`hdalab.views.profile.HdalabRenkanDelete` |
++-------------+-------------------------------------------------------------+
+| méthode | POST |
++-------------+-------------------------------------------------------------+
+| redirection | Page de liste des renkan. |
++-------------+-------------------------------------------------------------+
+
+
+.. automethod:: hdalab.views.profile.HdalabRenkanDelete.post
+ :noindex:
+
+
+.. _pages_favori_renkan:
+
+Marquer un renkan comme favori
+------------------------------
+
+Marque comme favori le renkan dont l'id est donné dans l'URL.
+
++-------------+---------------------------------------------------------------+
+| url | http://hdalab.iri-research.org/hdalab/renkan/favorite/<rk_id> |
++-------------+---------------------------------------------------------------+
+| view | :class:`hdalab.views.profile.HdalabRenkanFavorite` |
++-------------+---------------------------------------------------------------+
+| méthode | POST |
++-------------+---------------------------------------------------------------+
+| redirection | Page de liste des renkan. |
++-------------+---------------------------------------------------------------+
+
+
+.. automethod:: hdalab.views.profile.HdalabRenkanFavorite.post
+ :noindex:
+
+
+
+.. _pages_moderation_renkan:
+
+Modération d'un renkan
+----------------------
+
+Cette action change l'état d'un Renkan dont l'id est donné dans l'URL.
+
++-------------+---------------------------------------------------------------+
+| url | http://hdalab.iri-research.org/hdalab/renkan/moderate/<rk_id> |
++-------------+---------------------------------------------------------------+
+| view | :class:`hdalab.views.profile.HdalabRenkanModerate` |
++-------------+---------------------------------------------------------------+
+| méthode | POST |
++-------------+---------------------------------------------------------------+
+| redirection | Page de liste des renkan. |
++-------------+---------------------------------------------------------------+
+
+
+.. automethod:: hdalab.views.profile.HdalabRenkanModerate.post
+ :noindex:
+
+.. _pages_nouveau_renkan:
+
+Création d'un nouveau renkan
+----------------------------
+
+Crée un nouveau renkan vide. L'utilisateur est redirigé vers la page d'édition du renkan (:ref:`pages_edition_renkan`)
+
++-------------+--------------------------------------------------+
+| url | http://hdalab.iri-research.org/hdalab/renkan/new |
++-------------+--------------------------------------------------+
+| view | :class:`hdalab.views.profile.RenkanNew` |
++-------------+--------------------------------------------------+
+| méthode | POST |
++-------------+--------------------------------------------------+
+| redirection | :ref:`pages_edition_renkan` |
++-------------+--------------------------------------------------+
+
+
+.. automethod:: hdalab.views.profile.RenkanNew.post
+ :noindex:
+
+
+Pages de gestion des comptes utilisateurs
+=========================================
+
+Ce sont toutes les pages dont l'URL commence par http://hdalab.iri-research.org/hdalab/hdabo/accounts/ .
+Ces URL sont fournies par des librariries externe :
+
+
++-----------------------------------------------------------------+--------------------------------------------------------------------------------+
+| base d'URL | librairie / lien de documentation |
++=================================================================+================================================================================+
+| http://hdalab.iri-research.org/hdalab/hdabo/accounts/activate/ | `django-registration-redux <https://github.com/macropin/django-registration>`_ |
++-----------------------------------------------------------------+--------------------------------------------------------------------------------+
+| http://hdalab.iri-research.org/hdalab/hdabo/accounts/register/ | `django-registration-redux <https://github.com/macropin/django-registration>`_ |
++-----------------------------------------------------------------+--------------------------------------------------------------------------------+
+| http://hdalab.iri-research.org/hdalab/login | `django.contrib.auth <https://docs.djangoproject.com/en/1.8/topics/auth/>`_ |
++-----------------------------------------------------------------+--------------------------------------------------------------------------------+
+| http://hdalab.iri-research.org/hdalab/logout | `django.contrib.auth <https://docs.djangoproject.com/en/1.8/topics/auth/>`_ |
++-----------------------------------------------------------------+--------------------------------------------------------------------------------+
+| http://hdalab.iri-research.org/hdalab/password | `django.contrib.auth <https://docs.djangoproject.com/en/1.8/topics/auth/>`_ |
++-----------------------------------------------------------------+--------------------------------------------------------------------------------+
+| http://hdalab.iri-research.org/hdalab/password_change | `django.contrib.auth <https://docs.djangoproject.com/en/1.8/topics/auth/>`_ |
++-----------------------------------------------------------------+--------------------------------------------------------------------------------+
+| http://hdalab.iri-research.org/hdalab/password_reset | `django.contrib.auth <https://docs.djangoproject.com/en/1.8/topics/auth/>`_ |
++-----------------------------------------------------------------+--------------------------------------------------------------------------------+
+
+
+La librairie `django-registration-redux <https://github.com/macropin/django-registration>`_ offre en particulier la fonctionalité d'inscription sur le site et la vérification de l'email.
+
+En outre les 2 URL suivantes sont disponibles afin de faciliter l'authentification à partir de la page d'édition d'un renkan et d'éviter un rechargement de page.
+
+
+ - +----------+----------------------------------------------------------+
+ | url | http://hdalab.iri-research.org/hdalab/ajaxlogin/ |
+ +----------+----------------------------------------------------------+
+ | view | :func:`hdalab.views.profile.ajax_login` |
+ +----------+----------------------------------------------------------+
+
+ - +----------+----------------------------------------------------------+
+ | url | http://hdalab.iri-research.org/hdalab/edito/manage/ |
+ +----------+----------------------------------------------------------+
+ | view | django.views.generic.base.TemplateView |
+ +----------+----------------------------------------------------------+
+ | template | hdalab/templates/ajax_identification/ajax_login_ok.html |
+ +----------+----------------------------------------------------------+
+
+
+
+Pages hdabo
+===========
+
+Ce sont toute les pages dont l'URL commence par `http://hdalab.iri-research.org/hdalab/hdabo/` et qui ne sont pas dans la liste d'excption donnée ci-dessous.
+
+Ces pages sont aujourd'hui obsolètes.
+Elles ont été inclues dans le plan d'url HDALab pour référence, mais ne sont plus utiles.
+
+Elles ont permit le premier traitement sémantique des données HDA pour le projet HDALab.
+Cette fonctionnalité est aujourd'hui directement intégré au portail HDA par l'intermédiaire du module symfony `WikiTagBundle <https://github.com/IRI-Research/WikiTagBundle>`_.
+
+Les données HDA sont régulièrement importées dans HDALab par la commande :class:`hdalab.management.commands.import_hdabo_db`.
+
+Liste d'exception des pages hdabo non obsolètes :
+ - http://hdalab.iri-research.org/hdalab/hdabo/searchajax/
+ - http://hdalab.iri-research.org/hdalab/hdabo/admin/*
+ - http://hdalab.iri-research.org/hdalab/hdabo/account/*
+
+
+
+..
+ /i18n/setlang/ django.views.i18n.set_language set_language
+ /jsi18n/ django.views.i18n.javascript_catalog jsi18n.all
+ /jsi18n/<packages>/ django.views.i18n.javascript_catalog jsi18n
+
+
+ /renkan/copy/<rk_id> hdalab.views.profile.HdalabRenkanCopy renkan_copy login_required
+ /renkan/delete/<rk_id> hdalab.views.profile.HdalabRenkanDelete renkan_delete login_required
+ /renkan/favorite/<rk_id> hdalab.views.profile.HdalabRenkanFavorite renkan_favorite login_required
+ /renkan/moderate/<rk_id> hdalab.views.profile.HdalabRenkanModerate renkan_moderate login_required
+
+ /renkan/new/ hdalab.views.profile.RenkanNew renkan_new login_required
+
+
+
+ Fait:
+
+ /renkan/edit/ hdalab.views.profile.RenkanEdit renkan_edit
+ /renkan/getput/ hdalab.views.profile.HdalabRenkanGetPut renkan_get_put
+
+ /profile/ hdalab.views.profile.ProfileHome profile_home login_required
+ /profile/update/ hdalab.views.profile.UserProfileUpdate profile_update login_required
+
+ /notice/<hda_id> hdalab.views.pages.datasheet notice
+
+ /a/catsearch hdalab.views.ajax.catsearch cat_search
+ /a/cattree hdalab.views.ajax.cattree cat_tree
+ /a/filltree hdalab.views.ajax.filltree fill_tree
+ /a/filter hdalab.views.ajax.filter filter
+ /a/tagsearch hdalab.views.ajax.tagsearch tag_search
+
+
+ /edito/deletefolder/<folder_pk> hdalab.views.editorial.HdalabDeleteFolder hdalab_delete_folder login_required
+ /edito/folder/ hdalab.views.editorial.HdalabAddOrUpdateFolder hdalab_add_or_update_folder login_required
+ /edito/folder/<folder_pk> hdalab.views.editorial.HdalabAddOrUpdateFolder hdalab_add_or_update_folder login_required
+ /edito/folders/ hdalab.views.editorial.HdalabFolders hdalab_folders login_required
+ /edito/manage/ hdalab.views.editorial.ManageRenkans manage_renkans login_required
+
+ /facettes/ django.views.generic.base.TemplateView facettes
+
+
+ /hdalab/a_propos/ hdalab.views.pages.HdalabAboutPage a_propos
+ /hdalab/contact/ envelope.views.ContactView envelope-contact
+ /hdalab/credits/ django.views.generic.base.TemplateView credits
+ /hdalab/mentions_legales/ django.views.generic.base.TemplateView mentions_legales
+ /thesaurus/ django.views.generic.base.TemplateView thesaurus
+
+
+ /hdabo/admin/ django.contrib.admin.sites.index admin:index
+ /hdabo/admin/<app_label>/ django.contrib.admin.sites.app_index admin:app_list
+ /hdabo/admin/auth/group/ django.contrib.admin.options.changelist_view admin:auth_group_changelist
+ /hdabo/admin/auth/group/<var>/ django.contrib.admin.options.change_view admin:auth_group_change
+ /hdabo/admin/auth/group/<var>/delete/ django.contrib.admin.options.delete_view admin:auth_group_delete
+ /hdabo/admin/auth/group/<var>/history/ django.contrib.admin.options.history_view admin:auth_group_history
+ /hdabo/admin/auth/group/add/ django.contrib.admin.options.add_view admin:auth_group_add
+ /hdabo/admin/hdabo/author/ django.contrib.admin.options.changelist_view admin:hdabo_author_changelist
+ /hdabo/admin/hdabo/author/<var>/ django.contrib.admin.options.change_view admin:hdabo_author_change
+ /hdabo/admin/hdabo/author/<var>/delete/ django.contrib.admin.options.delete_view admin:hdabo_author_delete
+ /hdabo/admin/hdabo/author/<var>/history/ django.contrib.admin.options.history_view admin:hdabo_author_history
+ /hdabo/admin/hdabo/author/add/ django.contrib.admin.options.add_view admin:hdabo_author_add
+ /hdabo/admin/hdabo/datasheet/ django.contrib.admin.options.changelist_view admin:hdabo_datasheet_changelist
+ /hdabo/admin/hdabo/datasheet/<var>/ django.contrib.admin.options.change_view admin:hdabo_datasheet_change
+ /hdabo/admin/hdabo/datasheet/<var>/delete/ django.contrib.admin.options.delete_view admin:hdabo_datasheet_delete
+ /hdabo/admin/hdabo/datasheet/<var>/history/ django.contrib.admin.options.history_view admin:hdabo_datasheet_history
+ /hdabo/admin/hdabo/datasheet/add/ django.contrib.admin.options.add_view admin:hdabo_datasheet_add
+ /hdabo/admin/hdabo/documentformat/ django.contrib.admin.options.changelist_view admin:hdabo_documentformat_changelist
+ /hdabo/admin/hdabo/documentformat/<var>/ django.contrib.admin.options.change_view admin:hdabo_documentformat_change
+ /hdabo/admin/hdabo/documentformat/<var>/delete/ django.contrib.admin.options.delete_view admin:hdabo_documentformat_delete
+ /hdabo/admin/hdabo/documentformat/<var>/history/ django.contrib.admin.options.history_view admin:hdabo_documentformat_history
+ /hdabo/admin/hdabo/documentformat/add/ django.contrib.admin.options.add_view admin:hdabo_documentformat_add
+ /hdabo/admin/hdabo/domain/ django.contrib.admin.options.changelist_view admin:hdabo_domain_changelist
+ /hdabo/admin/hdabo/domain/<var>/ django.contrib.admin.options.change_view admin:hdabo_domain_change
+ /hdabo/admin/hdabo/domain/<var>/delete/ django.contrib.admin.options.delete_view admin:hdabo_domain_delete
+ /hdabo/admin/hdabo/domain/<var>/history/ django.contrib.admin.options.history_view admin:hdabo_domain_history
+ /hdabo/admin/hdabo/domain/add/ django.contrib.admin.options.add_view admin:hdabo_domain_add
+ /hdabo/admin/hdabo/organisation/ django.contrib.admin.options.changelist_view admin:hdabo_organisation_changelist
+ /hdabo/admin/hdabo/organisation/<var>/ django.contrib.admin.options.change_view admin:hdabo_organisation_change
+ /hdabo/admin/hdabo/organisation/<var>/delete/ django.contrib.admin.options.delete_view admin:hdabo_organisation_delete
+ /hdabo/admin/hdabo/organisation/<var>/history/ django.contrib.admin.options.history_view admin:hdabo_organisation_history
+ /hdabo/admin/hdabo/organisation/add/ django.contrib.admin.options.add_view admin:hdabo_organisation_add
+ /hdabo/admin/hdabo/tag/ django.contrib.admin.options.changelist_view admin:hdabo_tag_changelist
+ /hdabo/admin/hdabo/tag/<var>/ django.contrib.admin.options.change_view admin:hdabo_tag_change
+ /hdabo/admin/hdabo/tag/<var>/delete/ django.contrib.admin.options.delete_view admin:hdabo_tag_delete
+ /hdabo/admin/hdabo/tag/<var>/history/ django.contrib.admin.options.history_view admin:hdabo_tag_history
+ /hdabo/admin/hdabo/tag/add/ django.contrib.admin.options.add_view admin:hdabo_tag_add
+ /hdabo/admin/hdabo/tagcategory/ django.contrib.admin.options.changelist_view admin:hdabo_tagcategory_changelist
+ /hdabo/admin/hdabo/tagcategory/<var>/ django.contrib.admin.options.change_view admin:hdabo_tagcategory_change
+ /hdabo/admin/hdabo/tagcategory/<var>/delete/ django.contrib.admin.options.delete_view admin:hdabo_tagcategory_delete
+ /hdabo/admin/hdabo/tagcategory/<var>/history/ django.contrib.admin.options.history_view admin:hdabo_tagcategory_history
+ /hdabo/admin/hdabo/tagcategory/add/ django.contrib.admin.options.add_view admin:hdabo_tagcategory_add
+ /hdabo/admin/hdabo/taggedsheet/ django.contrib.admin.options.changelist_view admin:hdabo_taggedsheet_changelist
+ /hdabo/admin/hdabo/taggedsheet/<var>/ django.contrib.admin.options.change_view admin:hdabo_taggedsheet_change
+ /hdabo/admin/hdabo/taggedsheet/<var>/delete/ django.contrib.admin.options.delete_view admin:hdabo_taggedsheet_delete
+ /hdabo/admin/hdabo/taggedsheet/<var>/history/ django.contrib.admin.options.history_view admin:hdabo_taggedsheet_history
+ /hdabo/admin/hdabo/taggedsheet/add/ django.contrib.admin.options.add_view admin:hdabo_taggedsheet_add
+ /hdabo/admin/hdabo/timeperiod/ django.contrib.admin.options.changelist_view admin:hdabo_timeperiod_changelist
+ /hdabo/admin/hdabo/timeperiod/<var>/ django.contrib.admin.options.change_view admin:hdabo_timeperiod_change
+ /hdabo/admin/hdabo/timeperiod/<var>/delete/ django.contrib.admin.options.delete_view admin:hdabo_timeperiod_delete
+ /hdabo/admin/hdabo/timeperiod/<var>/history/ django.contrib.admin.options.history_view admin:hdabo_timeperiod_history
+ /hdabo/admin/hdabo/timeperiod/add/ django.contrib.admin.options.add_view admin:hdabo_timeperiod_add
+ /hdabo/admin/hdabo/user/ django.contrib.admin.options.changelist_view admin:hdabo_user_changelist
+ /hdabo/admin/hdabo/user/<var>/ django.contrib.admin.options.change_view admin:hdabo_user_change
+ /hdabo/admin/hdabo/user/<var>/delete/ django.contrib.admin.options.delete_view admin:hdabo_user_delete
+ /hdabo/admin/hdabo/user/<var>/history/ django.contrib.admin.options.history_view admin:hdabo_user_history
+ /hdabo/admin/hdabo/user/<var>/password/ django.contrib.auth.admin.user_change_password admin:auth_user_password_change
+ /hdabo/admin/hdabo/user/add/ django.contrib.auth.admin.add_view admin:hdabo_user_add
+ /hdabo/admin/jsi18n/ django.contrib.admin.sites.i18n_javascript admin:jsi18n
+ /hdabo/admin/login/ django.contrib.admin.sites.login admin:login
+ /hdabo/admin/logout/ django.contrib.admin.sites.logout admin:logout
+ /hdabo/admin/password_change/ django.contrib.admin.sites.password_change admin:password_change
+ /hdabo/admin/password_change/done/ django.contrib.admin.sites.password_change_done admin:password_change_done
+ /hdabo/admin/r/<content_type_id>/<object_id>/ django.contrib.contenttypes.views.shortcut admin:view_on_site
+ /hdabo/admin/registration/registrationprofile/ django.contrib.admin.options.changelist_view admin:registration_registrationprofile_changelist
+ /hdabo/admin/registration/registrationprofile/<var>/ django.contrib.admin.options.change_view admin:registration_registrationprofile_change
+ /hdabo/admin/registration/registrationprofile/<var>/delete/ django.contrib.admin.options.delete_view admin:registration_registrationprofile_delete
+ /hdabo/admin/registration/registrationprofile/<var>/history/ django.contrib.admin.options.history_view admin:registration_registrationprofile_history
+ /hdabo/admin/registration/registrationprofile/add/ django.contrib.admin.options.add_view admin:registration_registrationprofile_add
+ /hdabo/admin/sites/site/ django.contrib.admin.options.changelist_view admin:sites_site_changelist
+ /hdabo/admin/sites/site/<var>/ django.contrib.admin.options.change_view admin:sites_site_change
+ /hdabo/admin/sites/site/<var>/delete/ django.contrib.admin.options.delete_view admin:sites_site_delete
+ /hdabo/admin/sites/site/<var>/history/ django.contrib.admin.options.history_view admin:sites_site_history
+ /hdabo/admin/sites/site/add/ django.contrib.admin.options.add_view admin:sites_site_add
+
+ /hdabo/accounts/activate/<activation_key>/ registration.backends.default.views.ActivationView registration_activate
+ /hdabo/accounts/activate/complete/ django.views.generic.base.TemplateView registration_activation_complete
+ /hdabo/accounts/login/ django.contrib.auth.views.login auth_login
+ /hdabo/accounts/login/ django.contrib.auth.views.login login
+ /hdabo/accounts/logout/ django.contrib.auth.views.logout auth_logout login_required
+ /hdabo/accounts/logout/ django.contrib.auth.views.logout logout login_required
+ /hdabo/accounts/password/change/ django.contrib.auth.views.password_change auth_password_change
+ /hdabo/accounts/password/change/done/ django.contrib.auth.views.password_change_done auth_password_change_done login_required
+ /hdabo/accounts/password/reset/ django.contrib.auth.views.password_reset auth_password_reset
+ /hdabo/accounts/password/reset/complete/ django.contrib.auth.views.password_reset_complete auth_password_reset_complete login_required
+ /hdabo/accounts/password/reset/confirm/<uidb64>/<token>/ django.contrib.auth.views.password_reset_confirm auth_password_reset_confirm
+ /hdabo/accounts/password/reset/confirm/<uidb64>/<token>/ django.contrib.auth.views.password_reset_confirm auth_password_reset_confirm
+ /hdabo/accounts/password/reset/done/ django.contrib.auth.views.password_reset_done auth_password_reset_done login_required
+ /hdabo/accounts/password_change/ django.contrib.auth.views.password_change password_change
+ /hdabo/accounts/password_change/done/ django.contrib.auth.views.password_change_done password_change_done login_required
+ /hdabo/accounts/password_reset/ django.contrib.auth.views.password_reset password_reset
+ /hdabo/accounts/password_reset/done/ django.contrib.auth.views.password_reset_done password_reset_done login_required
+ /hdabo/accounts/register/ registration.backends.default.views.RegistrationView registration_register
+ /hdabo/accounts/register/closed/ django.views.generic.base.TemplateView registration_disallowed
+ /hdabo/accounts/register/complete/ django.views.generic.base.TemplateView registration_complete
+ /hdabo/accounts/reset/<uidb64>/<token>/ django.contrib.auth.views.password_reset_confirm password_reset_confirm
+ /hdabo/accounts/reset/done/ django.contrib.auth.views.password_reset_complete password_reset_complete login_required
+
+ /ajaxlogin/ hdalab.views.profile.ajax_login ajax_login
+ /ajaxloginok/ django.views.generic.base.TemplateView ajax_login_ok
+
+ /categories/ django.views.generic.base.TemplateView categories
+
+
+ /static/media/<path> django.views.static.serve
+
+
+ /renkan/favorite/ hdalab.views.profile.RenkanFavoriteList renkan_favorite_list
+ /renkan/public/ hdalab.views.profile.RenkanPublicList renkan_public_list
+ /renkan/view/ django.views.generic.base.TemplateView renkan_view
+ /renkan/full/ django.views.generic.base.TemplateView renkan_full
+
+
+ /edito/ django.views.generic.base.TemplateView edito_home login_required
+
+
+ /hdabo/ hdabo.views.home hdabo_home login_required
+
+ /hdabo/addtag hdabo.views.add_tag login_required
+
+ /hdabo/alltags/ hdabo.views.all_tags login_required
+ /hdabo/alltags/<num_page>/ hdabo.views.all_tags login_required
+ /hdabo/alltags/<num_page>/<nb_by_page>/ hdabo.views.all_tags login_required
+ /hdabo/alltags/<num_page>/<nb_by_page>/<sort>/ hdabo.views.all_tags login_required
+ /hdabo/alltags/<num_page>/<nb_by_page>/<sort>/<searched>/ hdabo.views.all_tags login_required
+
+ /hdabo/data hdabo.views.display_datasheet display_datasheet login_required
+ /hdabo/data/<ds_id> hdabo.views.display_datasheet display_datasheet login_required
+
+ /hdabo/deletefolder/<folder_pk> hdabo.views.DeleteFolder delete_folder login_required
+
+ /hdabo/folder/ hdabo.views.AddOrUpdateFolder add_or_update_folder login_required
+ /hdabo/folder/<folder_pk> hdabo.views.AddOrUpdateFolder add_or_update_folder login_required
+ /hdabo/folders/ hdabo.views.Folders folders login_required
+
+ /hdabo/list/ hdabo.views.orga_list orga_list login_required
+ /hdabo/list/<orga_id> hdabo.views.list_for_orga list_for_orga login_required
+ /hdabo/list/<orga_id>/<valid>/ hdabo.views.list_for_orga list_for_orga login_required
+ /hdabo/list/<orga_id>/<valid>/<start_index>/ hdabo.views.list_for_orga list_for_orga login_required
+ /hdabo/list/<orga_id>/<valid>/<start_index>/<length>/ hdabo.views.list_for_orga list_for_orga login_required
+
+ /hdabo/logout/ django.contrib.auth.views.logout_then_login login_required
+
+ /hdabo/modifytag hdabo.views.modify_tag login_required
+ /hdabo/modifytagds hdabo.views.modify_tag_datasheet login_required
+
+ /hdabo/ordertagsdatasheet hdabo.views.reorder_tag_datasheet login_required
+
+ /hdabo/removetagfromlist hdabo.views.remove_tag_from_list login_required
+ /hdabo/removewplink hdabo.views.remove_wp_link login_required
+ /hdabo/resetwpinfo hdabo.views.reset_wikipedia_info login_required
+
+ /hdabo/search/ haystack.views.SearchView() haystack_search
+ /hdabo/searchajax/ hdabo.views.SearchDatasheet() searchajax
+
+ /hdabo/tagupdown hdabo.views.tag_up_down login_required
+
+ /hdabo/updatetagalias hdabo.views.update_tag_alias login_required
+ /hdabo/updatetagcategory hdabo.views.update_tag_category login_required
+
+ /hdabo/validatedatasheet hdabo.views.validate_datasheet login_required
+ /hdabo/validatedatasheet/<ds_id> hdabo.views.validate_datasheet login_required
+ /hdabo/validatedatasheet/<ds_id>/<valid>/ hdabo.views.validate_datasheet login_required
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/source/renkan.rst Wed Apr 11 12:19:47 2018 +0200
@@ -0,0 +1,199 @@
+.. description des renkan
+
+##############################
+Description de l'outils renkan
+##############################
+
+Introduction
+============
+
+Renkan est un outil d'édition et d'affichage de carte mentale.
+
+Il a été conçu de façon modulaire et avec une claire separation entre la partie cliente en javascript et la partie serveur.
+
+En particulier la partie du client en charge des communications avec le serveur (chargement des projets, gestion de la persistance) est totalement modulaire et configurable.
+Cela permet d'adapter facilement le client à l'api de sauvegarde du serveur.
+
+
+Modèle de donnée serveur (HDALab)
+=================================
+
+Le modèle de donnée du coté serveur est simple.
+En effet le serveur ne cherche pas à interpréter le contenu d'un renkan.
+Il se content de sauvegarder le contenu qui lui est transmis par le client et dans l'autre sens de transmettre directement au client le contenu sauvegardé en base.
+Toute l'interprétation du modèle se fait dans le client.
+
+Classe renkanmanager.models.Renkan
+----------------------------------
+
+*class* ``renkanmanager.models.``\ **Renkan** :
+
+ Classe de base d'un renkan.
+
+ Champs de l'objet:
+
+ - **owner** (`object`) : Le propriétaire (créateur) du renkan.
+ - **rk_id** (`str`) : id du renkan.
+ - **content** (`str`) : contenu du renkan (la chaine JSON brute).
+ - **title** (`str`) : titre du renkan.
+ - **image** (`str`) : chemin vers l'image miniature du renkan.
+ - **creation_date** (`datetime`) : date de création.
+ - **modification_date** (`datetime`) : date de modification.
+
+
+Classe hdalab.models.renkan.HdalabRenkan
+----------------------------------------
+
+.. autoclass:: hdalab.models.renkan.HdalabRenkan
+ :noindex:
+
+
+Format renkan
+=============
+
+Un renkan a le format suivant:
+
+ exemple ::
+
+ {
+ "id": "f4d002b7-d4fd-486c-8898-6c6ceebc3354",
+ "schema_version": 2, #version of schema, latest is 2.
+ "title": "Example of Renkan with movies",
+ "description": "A long description",
+ "created": "2013-03-18T11:32:40.253+01:00",
+ "updated": "2014-02-04T15:12:56.619+01:00",
+ "nodes": [
+ {
+ "id": "node-2013-05-08-72c911bafdf9932c-0001",
+ "title": "Une femme mène l'enquête",
+ "description": "La caméra suit la femme qui marche\nJeu avec la caméra qui se substitue au spectateur",
+ "uri": "http://ldt.iri.centrepompidou.fr/ldtplatform/ldt/front/player/lyceehulst_3extraits/c8a61ee4-b33c-11e2-802c-00145ea4a2be#id=s_DCA8D184-EFC2-314B-0F6B-84043E8F9984",
+ "style": { #optional
+ "color": "#ff7f00", #line color, optional (null)
+ "thickness": 1, #thickness of the line, optional (1)
+ "dash": false, #dashed line, optional (false)
+ },
+ "position": {
+ "x": -547.0499881440252,
+ "y": -221.5401229374163
+ },
+ "image": "http://ldt.iri.centrepompidou.fr/static/site/ldt/css/imgs/video_sequence.png",
+ "size": 0,
+ "project_id": "f4d002b7-d4fd-486c-8898-6c6ceebc3354",
+ "created_by": "de68xf75y6hs5rgjhgghxbm217xk",
+ "type": "...",
+ "hidden": false,
+ "shape": "circle",
+ },
+ ...
+ ],
+ "edges": [
+ {
+ "id": "edge-2013-05-08-72c911bafdf9932c-0002",
+ "title": "",
+ "description": "",
+ "uri": "",
+ "style": { #optional
+ "color": "#ff7f00", #line color, optional (null)
+ "thickness": 1, #thickness of the line, optional (1)
+ "dash": false, #dashed line, optional (false)
+ "arrow": true, #draw the arrow, optional (true)
+ },
+ "from": "node-2013-04-30-a81adec6694db5f4-0032",
+ "to": "node-2013-05-08-72c911bafdf9932c-0001",
+ "project_id": "f4d002b7-d4fd-486c-8898-6c6ceebc3354",
+ "created_by": "de68xf75y6hs5rgjhgghxbm217xk"
+ },
+ ...
+ ],
+ "users": [ #optional
+ {
+ "userId": "user-2015-05-05-72c911bafdf9932c-0001",
+ "color": "#cc9866",
+ "username": "user1",
+ "anonymous": true
+ },
+ ...
+ ],
+ "space_id": "17f968e4-2640-4319-aa61-b5b8b527ebb4", #Optional
+ "views": [ #Optional
+ {
+ "zoom_level": 0.8275032552816195,
+ "offset_x": 832.0104075533723,
+ "offset_y": 402.8917139487223
+ }
+ ]
+ }
+
+Système de chutier
+==================
+
+Renkan propose un système de "chutier". C'est un système de liste d'élément ouvert à gauche d'un renkan en édition.
+
+On le voit à gauche sur l'image suivante :
+
+.. image:: _static/img/renkan/renkan_edition.png
+
+Ce système permet d'ajouter rapidement des resources fiches ou tag par "glisser/déposer".
+Techniquement, ces fonctionalités de chutiers propres à HDALab sont définies dans le fichier `hdalab/static/hdalab/js/hdalab-renkan-bins.js`.
+
+
+.. _renkan_boite_recherche_contenus:
+
+Boite de recherche de contenus
+------------------------------
+
+.. image:: _static/img/renkan/renkan_recherche_contenus.png
+
+
+Cette boite de recherche permet de lancer une requête sur 3 types de ressources:
+ - recherche de tag
+ - recherche de fiches
+ - recherche d'article wikipedia
+
+ +--------------------+----------------------------------------------------------+--------------------------------------+
+ | type | url de requête | Vue |
+ +====================+==========================================================+======================================+
+ | tags | http://hdalab.iri-research.org/hdalab/a/tagsearch? | :func:`hdalab.views.ajax.tagsearch` |
+ +--------------------+----------------------------------------------------------+--------------------------------------+
+ | fiches | http://hdalab.iri-research.org/hdalab/hdabo/searchajax/? | :class:`hdabo.views.SearchDatasheet` |
+ +--------------------+----------------------------------------------------------+--------------------------------------+
+ | articles wikipedia | https://fr.wikipedia.org/w/api.php?action=query... | |
+ +--------------------+----------------------------------------------------------+--------------------------------------+
+
+Le resultat de la recherche est affiché dans un nouvel onglet listant les ressources.
+
+
+Boite de recherche sur les résultats
+------------------------------------
+
+.. image:: _static/img/renkan/renkan_recherche_resultats.png
+
+Cette boite de recherche permet de rechercher et de filtrer des résultats déjà présent dans les onglets. La recherche est uniquement locale et ne lance fait pas de requête http.
+
+
+Liste de ressource
+------------------
+
+.. image:: _static/img/renkan/renkan_bin_resources.png
+
+Cet onglet liste des ressources statiques qui peuvent être utiles à l'édition du renkan.
+
+
+Liste de ressource supplémentaire
+---------------------------------
+
+.. image:: _static/img/renkan/renkan_bin_plus_ressources.png
+
+Cet onglet liste des ressources "supplémentaires".
+Un renkan est souvent créé à partir du résultat d'une recherche sur la page de `recherche par facette <pages_recherche_facette>`.
+Pour éviter d'avoir trop de noeuds ressources, les 8 premiers résultats de la recherche sont utilisés dans le renkan et les 10 suivants sont utilisés dans ce chutier.
+(ce comportement est défini dans la méthode :func:`hdalab.views.profile.HdalabRenkanGetPut.get`).
+
+
+Sauvegarde des renkan
+=====================
+
+la sauvegarde des renkan est définie dans le fichier `hdalab/static/hdalab/js/renkan-manual-save.js`.
+La sauvegarde est déclenchée par une action de l'utilisateur.
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/source/taches.rst Wed Apr 11 12:19:47 2018 +0200
@@ -0,0 +1,34 @@
+####################
+Taches Celery HDALab
+####################
+
+Ces tâches longues sont lancées de façon asynchrone par `Celery <http://www.celeryproject.org/>`_.
+
+Liste des tâches asynchrones:
+
+ - :ref:`taches-hdalab-tasks-capture_preview`
+ - :ref:`taches-djcelery_email_send_multiple`
+
+
+.. _taches-hdalab-tasks-capture_preview:
+
+hdalab.tasks.capture_preview
+----------------------------
+
+Crée un snapshot d'un renkan.
+La tache est un simple wrapper qui appelle :func:`hdalab.services.renkan_capture_preview`.
+
+.. autofunction:: hdalab.services.renkan_capture_preview
+ :noindex:
+
+.. _taches-djcelery_email_send_multiple:
+
+djcelery_email_send_multiple
+----------------------------
+
+Envoi asynchrone d'email.
+Cette tâche est fournie par la librairie `django-celery-email <https://github.com/pmclanahan/django-celery-email>`_.
+C'est un backend Django qui utilise une queue `Celery`_ pour envoyer les messages de façon asynchrone, libérant ainsi le thread de traitement de requête.
+
+
+
--- a/src/hdabo/management/commands/clean_tags.py Thu Apr 12 01:27:16 2018 +0200
+++ b/src/hdabo/management/commands/clean_tags.py Wed Apr 11 12:19:47 2018 +0200
@@ -1,8 +1,9 @@
# -*- coding: utf-8 -*-
'''
-Created on Jun 20, 2012
+Retire les tags orphelins et fusionne les tags dupliqués (la clef étant l'URI DBPedia).
-@author: ymh
+**Usage**: ``django-admin clean_tags [options]``
+
'''
from django.core.management.base import NoArgsCommand
from django.core.management.color import no_style
@@ -17,7 +18,7 @@
class Command(NoArgsCommand):
'''
- remove orphan tags and merge duplicates (the key is the dbpedia uri)
+ remove orphan tags and merge duplicates (the key is the dbpedia uri)
'''
@@ -29,7 +30,7 @@
# merge duplicate tags
cursor = connection.cursor()
cursor.execute("select label, dbpedia_uri from hdabo_tag group by label,dbpedia_uri having count(label) > 1")
-
+
for label,_ in cursor:
qs = Tag.objects.filter(label=label).annotate(num_ds=Count('datasheet')).order_by('-num_ds')
ref_tag = None
@@ -43,14 +44,13 @@
print("changing tag %d to %d" %(ts.tag.id, ref_tag.id) )
ts.tag = ref_tag
ts.save()
-
+
# remove ophans tags
-
+
orphans_tags = Tag.objects.annotate(num_ds=Count('datasheet')).filter(num_ds=0)
-
+
print("nb Orphans : %d" % orphans_tags.count())
-
+
#delete
orphans_tags.delete()
-
\ No newline at end of file
--- a/src/hdabo/management/commands/diff_csv.py Thu Apr 12 01:27:16 2018 +0200
+++ b/src/hdabo/management/commands/diff_csv.py Wed Apr 11 12:19:47 2018 +0200
@@ -1,8 +1,17 @@
# -*- coding: utf-8 -*-
'''
-Created on May 25, 2011
+Permet d'afficher (et optionellement d'effacer) les fiches se trouvant dans la base de données et pas dans le fichiers CSV.
+
+**Usage**: ``django-admin diff_csv [options] <path_to_csv_file path_to_csv_file ...>``
+
+**Options spécifiques:**
-@author: ymh
+ - *\-\-encoding=ENCODING* : encodage des fichiers CSV (défaut ``latin-1``)
+ - *\-\-delimiter=DELIMITER* : Séparateur des fichiers CSV
+ - *\-\-dialect=DIALECT* : Dialecte fichier CSV (c.f. `Dialectes Python CSV <https://docs.python.org/2/library/csv.html#csv-fmt-params>`_)
+ - *\-\-fieldnames=FIELDNAMES* : liste des noms de champ à traiter (séparateur : ``,``)
+ - *\-\-do\-delete* : efface les fiches se trouvant dans la base mais pas dans le fichier CSV.
+
'''
#Auteur,Chemin,Comment,Controle,Datcre,Datmaj,Desc,Domaine,Format,ID,Insee,Org,Org_Home,OrgID,Periode1,Periode2,Periode3,Satut,Sousdom,Tag,Theme2,Theme3,Titre,Url,Vignette,Ville
#"Auteur","Chemin","Comment","Controle","Datcre","Datmaj","Desc","Domaine","Format","ID","Insee","Org","Org_Home","OrgID","Periode1","Periode2","Periode3","Satut","Sousdom","Tag","Theme2","Theme3","Titre","Url","Vignette","Ville",
@@ -17,11 +26,11 @@
class Command(BaseCommand):
'''
- Command to diff datasheets content from csv content
+ Command to diff datasheets content from csv content
'''
args = '<path_to_csv_file path_to_csv_file ...>'
options = '[--do-delete] [--encoding] [--delimiter] [--dialect]'
- help = """Import of a csv file for hdabo
+ help = """Command to diff datasheets content from csv content
Options:
--do-delete : ignore existing datasheets
--encoding : files encoding. default to latin-1
@@ -29,7 +38,7 @@
--dialect : csv dialect
--fieldnames : csv columns
"""
-
+
option_list = BaseCommand.option_list + (
make_option('--encoding',
action='store',
@@ -60,30 +69,30 @@
dest='do_delete',
default=False,
help='delete datasheets'),
-
+
)
-
+
def show_progress(self, current_line, total_line, width):
percent = (float(current_line) / float(total_line)) * 100.0
marks = math.floor(width * (percent / 100.0))
spaces = math.floor(width - marks)
-
+
loader = '[' + ('=' * int(marks)) + (' ' * int(spaces)) + ']'
-
+
sys.stdout.write("%s %d%% %d/%d\r" % (loader, percent, current_line - 1, total_line - 1)) #takes the header into account
if percent >= 100:
sys.stdout.write("\n")
sys.stdout.flush()
-
+
def handle(self, *args, **options):
-
+
if len(args) == 0:
raise CommandError("Gives at lat one csv file to import")
-
+
self.encoding = options.get('encoding', "latin-1")
self.do_delete = options.get('do_delete', False)
fieldnames = options.get('fieldnames', None)
@@ -91,30 +100,30 @@
for csv_path in args:
print "Processing %s " % (csv_path)
with open(csv_path, 'rU') as csv_file:
-
+
# get the number of lines if necessary
for i, l in enumerate(csv_file): #@UnusedVariable
- pass
+ pass
total_line = i + 1
if fieldnames:
total_line = total_line + 1
csv_file.seek(0)
-
+
delimiter = options.get('delimiter', ";")
if delimiter == "TAB" or delimiter == "\\t":
delimiter = '\t'
-
+
dr_kwargs = {'delimiter':delimiter}
if fieldnames is not None:
dr_kwargs['fieldnames'] = [f.strip() for f in fieldnames.split(",")]
dialect = options.get('dialect', "excel")
if dialect is not None:
dr_kwargs['dialect'] = dialect
-
+
reader = csv.DictReader(csv_file, **dr_kwargs)
-
+
ids = []
-
+
for row in reader:
line_num = reader.line_num if fieldnames is None else reader.line_num + 1
self.show_progress(line_num, total_line, 60)
@@ -123,24 +132,24 @@
return val.decode(encoding)
else:
return val
-
+
row = dict([(safe_decode(key, self.encoding), safe_decode(value, self.encoding)) for key, value in row.items()])
-
+
ids.append(row['ID'])
-
+
qs = Datasheet.objects.exclude(hda_id__in = ids).order_by("hda_id")
-
+
qs_count = qs.count()
-
+
if qs_count == 0:
print("No datasheet to delete : exit")
return
-
+
print("The following datasheets are in the database and not in the csv file")
for i,ds in enumerate(qs):
print("%*d- %4s : %s" % (len(str(qs_count+1)), i+1, ds.hda_id, ds.title.strip() if ds.title is not None else ""))
-
-
+
+
if self.do_delete:
print("deleting datasheets")
qs.delete()
--- a/src/hdabo/management/commands/import_csv.py Thu Apr 12 01:27:16 2018 +0200
+++ b/src/hdabo/management/commands/import_csv.py Wed Apr 11 12:19:47 2018 +0200
@@ -1,8 +1,19 @@
# -*- coding: utf-8 -*-
'''
-Created on May 25, 2011
+Importe un (ou pusieurs) fichiers CSV issus d'un export de la base HDA.
+Cette commande se contente d'importer les données contenues dans les fichiers CSV.
+
+**Usage**: ``django-admin import_csv [options] <path_to_csv_file path_to_csv_file ...>``
+
+**Options spécifiques:**
-@author: ymh
+ - *\-\-encoding=ENCODING* : encodage des fichiers CSV (défaut ``latin-1``)
+ - *\-\-delimiter=DELIMITER* : Séparateur des fichiers CSV
+ - *\-\-dialect=DIALECT* : Dialecte fichier CSV (c.f. `Dialectes Python CSV <https://docs.python.org/2/library/csv.html#csv-fmt-params>`_)
+ - *\-\-fieldnames=FIELDNAMES* : liste des noms de champ à traiter (séparateur : ``,``)
+ - *\-\-lines=LINES* : Nombre de ligne de ficheirs CSV à lire ( 0 : toutes, défaut 0)
+ - *\-\-ignore-existing* : écrase les fiches qui existent déjà dans la base
+
'''
#Auteur,Chemin,Comment,Controle,Datcre,Datmaj,Desc,Domaine,Format,ID,Insee,Org,Org_Home,OrgID,Periode1,Periode2,Periode3,Satut,Sousdom,Tag,Theme2,Theme3,Titre,Url,Vignette,Ville
#"Auteur","Chemin","Comment","Controle","Datcre","Datmaj","Desc","Domaine","Format","ID","Insee","Org","Org_Home","OrgID","Periode1","Periode2","Periode3","Satut","Sousdom","Tag","Theme2","Theme3","Titre","Url","Vignette","Ville",
@@ -29,7 +40,7 @@
--ignore-existing : ignore existing datasheets
--lines : max number of lines to load (for each file). 0 means all.
--encoding : files encoding. default to latin-1"""
-
+
option_list = BaseCommand.option_list + (
make_option('--encoding',
action='store',
@@ -66,24 +77,24 @@
dest='ignore_existing',
default=False,
help='force insertion'),
-
+
)
-
+
def show_progress(self, current_line, total_line, width):
percent = (float(current_line) / float(total_line)) * 100.0
marks = math.floor(width * (percent / 100.0))
spaces = math.floor(width - marks)
-
+
loader = '[' + ('=' * int(marks)) + (' ' * int(spaces)) + ']'
-
+
sys.stdout.write("%s %d%% %d/%d\r" % (loader, percent, current_line - 1, total_line - 1)) #takes the header into account
if percent >= 100:
sys.stdout.write("\n")
sys.stdout.flush()
-
+
def create_domain_period(self, row_value, klass, school_period):
res_list = []
if not row_value:
@@ -93,12 +104,12 @@
res_obj, created = klass.objects.get_or_create(label=label_str, school_period=school_period, defaults={"label":label_str, "school_period":school_period}) #@UnusedVariable
res_list.append(res_obj)
return res_list
-
+
def create_datasheet(self, row):
-
+
if self.ignore_existing and Datasheet.objects.filter(hda_id=row[u"ID"]).count() > 0:
return
-
+
author_str = row[u'Auteur']
if author_str:
author_array = author_str.split(" ")
@@ -111,12 +122,12 @@
elif len(author_array) == 2:
firstname = author_array[0]
lastname = author_array[1]
-
+
author, created = Author.objects.get_or_create(hda_id=author_str, defaults={"firstname":firstname, "lastname":lastname}) #@UnusedVariable
else:
author = None
-
- org_str = row[u"Org"]
+
+ org_str = row[u"Org"]
if org_str:
url_str = row[u'Org_Home']
if url_str is not None:
@@ -124,36 +135,36 @@
org, created = Organisation.objects.get_or_create(hda_id=org_str, defaults={"name":org_str, "website" : url_str}) #@UnusedVariable
else:
org = None
-
+
town_str = row[u"Ville"]
if town_str:
insee_str = row[u'Insee'].strip() if row[u'Insee'] else row[u'Insee']
if len(insee_str) > 5:
- insee_str = ""
+ insee_str = ""
loc, created = Location.objects.get_or_create(insee=insee_str, defaults={"name": town_str, "insee": insee_str}) #@UnusedVariable
else:
loc = None
-
+
format_str = row[u"Format"]
if format_str:
format, created = DocumentFormat.objects.get_or_create(label=format_str, defaults={"label": format_str}) #@UnusedVariable
else:
format = None
-
+
domains = self.create_domain_period(row[u"Domaine"], Domain, Domain.DOMAIN_PERIOD_DICT[u'Global'])
-
+
primary_periods = self.create_domain_period(row[u"Periode1"], TimePeriod, TimePeriod.TIME_PERIOD_DICT[u'Primaire'])
college_periods = self.create_domain_period(row[u"Periode2"], TimePeriod, TimePeriod.TIME_PERIOD_DICT[u'Collège'])
highschool_periods = self.create_domain_period(row[u"Periode3"], TimePeriod, TimePeriod.TIME_PERIOD_DICT[u'Lycée'])
-
+
primary_themes = self.create_domain_period(row[u"Sousdom"], Domain, Domain.DOMAIN_PERIOD_DICT[u'Primaire'])
college_themes = self.create_domain_period(row[u"Theme2"], Domain, Domain.DOMAIN_PERIOD_DICT[u'Collège'])
highschool_themes = self.create_domain_period(row[u"Theme3"], Domain, Domain.DOMAIN_PERIOD_DICT[u'Lycée'])
-
+
url = row[u"Url"]
if url is not None:
url = url.strip()
-
+
datasheet = Datasheet.objects.create(
hda_id=row[u"ID"],
author=author,
@@ -165,11 +176,11 @@
format=format,
original_creation_date=datetime.datetime.strptime(row[u"Datcre"], "%d/%m/%Y").date(),
original_modification_date=datetime.datetime.strptime(row[u"Datmaj"], "%d/%m/%Y").date(),
- validated=False
+ validated=False
)
-
+
datasheet.save()
-
+
datasheet.set_domains(domains)
datasheet.set_primary_periods(primary_periods)
datasheet.set_college_periods(college_periods)
@@ -178,7 +189,7 @@
datasheet.set_college_themes(college_themes)
datasheet.set_highschool_themes(highschool_themes)
-
+
if row[u'Tag']:
for i, tag in enumerate([t.strip() for t in row[u'Tag'].split(u";")]):
if len(tag) == 0:
@@ -190,20 +201,20 @@
tag_obj = t
if tag_obj.url_status != Tag.TAG_URL_STATUS_DICT['null_result']:
break
-
+
if tag_obj is None:
tag_obj = Tag(label=tag_label, original_label=tag)
tag_obj.save()
tagged_ds = TaggedSheet(datasheet=datasheet, tag=tag_obj, original_order=i + 1, order=i + 1)
tagged_ds.save()
-
+
def handle(self, *args, **options):
-
+
if len(args) == 0:
raise CommandError("Gives at lat one csv file to import")
-
+
self.encoding = options.get('encoding', "latin-1")
lines = options.get('lines', 0)
self.ignore_existing = options.get('ignore_existing', False)
@@ -218,18 +229,18 @@
try:
print "Processing %s " % (csv_path)
with open(csv_path, 'rU') as csv_file:
-
+
# get the number of lines if necessary
if not lines:
for i, l in enumerate(csv_file): #@UnusedVariable
- pass
+ pass
total_line = i + 1
if fieldnames:
total_line = total_line + 1
csv_file.seek(0)
else:
total_line = lines + 1
-
+
delimiter = options.get('delimiter', ";")
if delimiter == "TAB" or delimiter == "\\t":
delimiter = '\t'
@@ -240,9 +251,9 @@
dialect = options.get('dialect', "excel")
if dialect is not None:
dr_kwargs['dialect'] = dialect
-
+
reader = csv.DictReader(csv_file, **dr_kwargs)
-
+
for j, row in enumerate(reader):
if lines and j >= lines:
break
@@ -253,14 +264,14 @@
return val.decode(encoding)
else:
return val
-
+
row = dict([(safe_decode(key, self.encoding), safe_decode(value, self.encoding)) for key, value in row.items()])
self.create_datasheet(row)
-
+
transaction.commit()
except Exception:
transaction.rollback()
- raise
+ raise
finally:
print('')
finally:
--- a/src/hdabo/management/commands/import_rdf.py Thu Apr 12 01:27:16 2018 +0200
+++ b/src/hdabo/management/commands/import_rdf.py Wed Apr 11 12:19:47 2018 +0200
@@ -1,10 +1,29 @@
# -*- coding: utf-8 -*-
'''
-Created on May 25, 2011
+Importe un fichiers RDF issus d'un export de la base HDA.
+Cette commande remplace le contenu de la base existante.
-- after `import_rdf` call commands `import_hdabo_db -c` then `rebuild_index`
+La liste des types d'objets importés est la suivante :
+ - `Categorie`,
+ - `Tag`,
+ - `Site`,
+ - `Ville`,
+ - `Institution`,
+ - `Theme`,
+ - `Domaine`,
+ - `SousDomaine`,
+ - `Periode`,
+ - `Notice`
-@author: ymh
+A noter que cette commande est actuellement utilisée pour transférer le contenu de la base de donnée du site HDA vers HDALab. les commandes suivantes sont ensuite lancée:
+ #. :class:`import_hdabo_db -c <hdalab.management.commands.import_hdabo_db>`
+ #. `rebuild_index <http://django-haystack.readthedocs.io/en/master/management_commands.html#rebuild-index>`_
+
+**Usage**: ``django-admin import_rdf [options] <path_to_rdf_file>``
+
+**Options spécifiques:**
+
+ - *\-t, \-\-type=TYPE* : type d'objet à importer. Cette option peut être ajoutée plusieurs fois.
'''
import base64
@@ -33,8 +52,8 @@
logger = logging.getLogger(__name__)
RDF_EXT_MAP = {
- '.xml': 'rdfxm',
- '.rdf': 'rdfxm',
+ '.xml': 'rdfxml',
+ '.rdf': 'rdfxml',
'.ttl': 'turtle',
'.nt': 'ntriples'
}
@@ -804,7 +823,7 @@
class Command(BaseCommand):
'''
- Command to import csvfile
+ Command to import rdf file
'''
args = '<path_to_rdf_file>'
options = '[--type TYPE]'
@@ -835,7 +854,7 @@
self.types_list = options.get('types', TYPES_LIST) or TYPES_LIST
if any([t not in TYPES_LIST for t in self.types_list]):
- raise CommandError("Types is %r : all types mus be in %r" % (self.types_list, TYPES_LIST))
+ raise CommandError("Types is %r : all types must be in %r" % (self.types_list, TYPES_LIST))
with transaction.atomic():
connection = connections[DEFAULT_DB_ALIAS]
--- a/src/hdabo/management/commands/import_tag_popularity.py Thu Apr 12 01:27:16 2018 +0200
+++ b/src/hdabo/management/commands/import_tag_popularity.py Wed Apr 11 12:19:47 2018 +0200
@@ -1,10 +1,18 @@
# -*- coding: utf-8 -*-
'''
-Created on Jun 17, 2011
+Importe les informations de popularité des tags. (c.f. champ `popularity` de l'objet :class:`hdabo.models.Tag`.).
+
+**Usage**: ``django-admin import_tag_popularity [options] <path_to_csv_file path_to_csv_file ...>``
+
+**Options spécifiques:**
-@author: ymh
-
-command to import tag popularity
+ - *\-\-all* : Capture les miniatures pours tous les renkan publié. Remplace les miniatures existantes.
+ - *\-\-encoding=ENCODING* : encodage des fichiers CSV (défaut ``latin-1``)
+ - *\-\-delimiter=DELIMITER* : Séparateur des fichiers CSV
+ - *\-\-dialect=DIALECT* : Dialecte fichier CSV (c.f. `Dialectes Python CSV <https://docs.python.org/2/library/csv.html#csv-fmt-params>`_)
+ - *\-\-fieldnames=FIELDNAMES* : liste des noms de champ à traiter (séparateur : ``,``)
+ - *\-\-lines=LINES* : Nombre de ligne de ficheirs CSV à lire ( 0 : toutes, défaut 0)
+ - *\-\-preserve* : Ne met pas à jour les informations de popularité existante.
'''
@@ -19,7 +27,7 @@
class Command(BaseCommand):
'''
- Command to import csvfile
+ Command to import tag popularity.
'''
args = '<path_to_csv_file path_to_csv_file ...>'
options = '[--ignore-existing] [--lines] [--encoding]'
@@ -28,7 +36,7 @@
--ignore-existing : ignore existing datasheets
--lines : max number of lines to load (for each file). 0 means all.
--encoding : files encoding. default to latin-1"""
-
+
option_list = BaseCommand.option_list + (
make_option('--encoding',
action='store',
@@ -65,44 +73,44 @@
dest='preserve',
default=False,
help='preserve'),
-
-
+
+
)
-
+
def show_progress(self, current_line, total_line, width):
percent = (float(current_line) / float(total_line)) * 100.0
marks = math.floor(width * (percent / 100.0))
spaces = math.floor(width - marks)
-
+
loader = '[' + ('=' * int(marks)) + (' ' * int(spaces)) + ']'
-
+
sys.stdout.write("%s %d%% %d/%d\r" % (loader, percent, current_line - 1, total_line - 1)) #takes the header into account
if percent >= 100:
sys.stdout.write("\n")
sys.stdout.flush()
def handle(self, *args, **options):
-
+
if len(args) == 0:
raise CommandError("Give one csv file to import")
elif len(args) > 1:
raise CommandError("Only one file can be imported")
-
+
self.encoding = options.get('encoding', "latin-1")
lines = options.get('lines', 0)
fieldnames = options.get('fieldnames', "label,popularity")
csv_path = args[0]
-
+
print("Processing %s " % (csv_path))
-
+
with open(csv_path, 'rU') as csv_file:
# get the number of lines if necessary
if not lines:
for i, l in enumerate(csv_file): #@UnusedVariable
- pass
+ pass
total_line = i + 1
if fieldnames:
total_line = total_line + 1
@@ -119,10 +127,10 @@
dialect = options.get('dialect', "excel")
if dialect is not None:
dr_kwargs['dialect'] = dialect
-
+
if not options.get('preserve',False):
Tag.objects.update(popularity=0)
-
+
reader = csv.DictReader(csv_file, **dr_kwargs)
for j, row in enumerate(reader):
@@ -135,16 +143,16 @@
return val.decode(encoding)
else:
return val
-
+
row = dict([(safe_decode(key, self.encoding), safe_decode(value, self.encoding)) for key, value in row.items()])
-
+
label = normalize(row['label'].strip())
popularity_str = row['popularity']
-
+
if not label or not popularity_str:
continue
-
-
+
+
for tag in Tag.objects.filter(normalized_label=label):
tag.popularity = tag.popularity + int(row['popularity'])
tag.save()
--- a/src/hdabo/management/commands/order_tags.py Thu Apr 12 01:27:16 2018 +0200
+++ b/src/hdabo/management/commands/order_tags.py Wed Apr 11 12:19:47 2018 +0200
@@ -1,7 +1,14 @@
+# -*- coding: utf-8 -*-
'''
-Created on Jun 7, 2011
+Calcule l'ordre des tags d'une fiche en fonction des scores de la recherche indexée du tag sur le titre et la description de la fiche.
+
+**Usage**: ``django-admin order_tags [options]``
-@author: ymh
+**Options spécifiques:**
+
+ - *\-f* : refait le calcul sur l'ensemble des fiches, même celles qui ont été validées ou bien réordonnées manuellement.
+ - *\-\-noinput* : ne pose aucune question.
+
'''
from django.core.management.base import NoArgsCommand
@@ -24,7 +31,7 @@
args = ''
options = '-f : force '
help = "calculate the order of tags based on indexation recalculate all tags. Will ask for confirmation"
-
+
option_list = NoArgsCommand.option_list + (
make_option('-f', '--force',
action='store_true',
@@ -40,19 +47,19 @@
def handle_noargs(self, **options):
-
+
self.style = no_style()
-
+
interactive = options.get('interactive', True) and not options.get('no_input', False)
force = options.get('force', True)
-
+
if interactive:
confirm = raw_input("""You have requested to recalculate the index order of all the tags.
This will process all the tags in %s datasheets. Are you sure you want to do this ?
Type 'yes' to continue, or 'no' to cancel: """ % ("all" if force else "not validated"))
else:
confirm = 'yes'
-
+
if confirm != "yes":
print "Tag reordering cancelled"
return
@@ -62,7 +69,7 @@
else:
queryset = Datasheet.objects.filter(validated=False, manual_order=False)
total = queryset.count()
-
+
transaction.commit_unless_managed()
transaction.enter_transaction_management()
transaction.managed(True)
@@ -77,5 +84,5 @@
raise
finally:
transaction.leave_transaction_management()
-
-
+
+
--- a/src/hdabo/management/commands/query_wikipedia.py Thu Apr 12 01:27:16 2018 +0200
+++ b/src/hdabo/management/commands/query_wikipedia.py Wed Apr 11 12:19:47 2018 +0200
@@ -1,8 +1,17 @@
# -*- coding: utf-8 -*-
'''
-Created on Jun 7, 2011
+Lance des requêtes wikipedia pour associer un tag à un article wikipedia (i.e. sémantisé le tag).
+On utilise pour cela directement `l'api de requête wikipedia <https://www.mediawiki.org/wiki/API:Query>`_ en recherchant par le nom des pages (``titles=Foo|Bar|Main_Page``).
+
+**Usage**: ``django-admin import_csv [options] <path_to_csv_file path_to_csv_file ...>``
-@author: ymh
+**Options spécifiques:**
+
+ - *\-\-force* : force la mise à jour de tous les tags, pas seulement ceux pas encore traités.
+ - *\-\-random* : force un ordre aléatoire sur la requête des tags.
+ - *\-\-site=SITE_URL* : url du site wikipedia.
+ - *\-\-limit=LIMIT* : nombre de tags à traiter.
+ - *\-\-start=START* : nombre de tag à ignorer.
'''
from django.conf import settings
@@ -23,7 +32,7 @@
'''
options = ''
help = """query and update wikipedia for tag title."""
-
+
option_list = NoArgsCommand.option_list + (
make_option('--force',
action='store_true',
@@ -54,44 +63,44 @@
default=0,
help='number of tag to ignore'),
)
-
+
def __is_homonymie(self, page_dict):
for cat in page_dict.get(u"categories", []):
if u'Catégorie:Homonymie' in cat.get(u"title", u"") or u'Category:Disambiguation pages' in cat.get(u"title", u""):
return True
return False
-
+
def show_progress(self, current_line, total_line, label, width):
percent = (float(current_line) / float(total_line)) * 100.0
marks = math.floor(width * (percent / 100.0))
spaces = math.floor(width - marks)
-
+
loader = u'[' + (u'=' * int(marks)) + (u' ' * int(spaces)) + u']'
-
+
sys.stdout.write(u"%s %d%% %d/%d - %r\r" % (loader, percent, current_line - 1, total_line - 1, label[:50].rjust(50))) #takes the header into account
if percent >= 100:
sys.stdout.write("\n")
sys.stdout.flush()
-
+
def handle_noargs(self, **options):
-
+
self.style = no_style()
-
+
interactive = options.get('interactive', True)
-
+
verbosity = int(options.get('verbosity', '1'))
-
+
force = options.get('force', False)
-
+
limit = options.get("limit", -1)
start = options.get("start", 0)
-
+
site_url = options.get('site_url', settings.WIKIPEDIA_API_URL)
-
+
random = options.get('random', False)
-
+
if verbosity > 2:
print "option passed : " + repr(options)
@@ -101,7 +110,7 @@
Type 'yes' to continue, or 'no' to cancel: """)
else:
confirm = 'yes'
-
+
if confirm != "yes":
print "wikipedia query cancelled"
return
@@ -109,38 +118,38 @@
if force:
queryset = Tag.objects.all()
else:
- queryset = Tag.objects.filter(url_status=None)
-
+ queryset = Tag.objects.filter(url_status=None)
+
if random:
queryset = queryset.order_by("?")
else:
queryset = queryset.order_by("label")
-
+
if limit >= 0:
queryset = queryset[start:limit]
else:
queryset = queryset[start:]
-
-
+
+
if verbosity > 2 :
print "Tag Query is %s" % (queryset.query)
-
+
site = wiki.Wiki(site_url) #@UndefinedVariable
-
-
+
+
count = queryset.count()
if verbosity > 1:
print "Processing %d tags" % (count)
-
-
-
+
+
+
for i, tag in enumerate(queryset):
-
+
if verbosity > 1:
print "processing tag %s (%d/%d)" % (tag.label, i + 1, count)
else:
- self.show_progress(i + 1, count, tag.label, 60)
-
+ self.show_progress(i + 1, count, tag.label, 60)
+
process_tag(site, tag, verbosity)
-
-
+
+
--- a/src/hdabo/models.py Thu Apr 12 01:27:16 2018 +0200
+++ b/src/hdabo/models.py Wed Apr 11 12:19:47 2018 +0200
@@ -1,4 +1,7 @@
# -*- coding: utf-8 -*-
+"""
+Ce module contient les classes de base utilisées dans le back-office HDA ainsi que dans l'application hdalab.
+"""
import datetime
@@ -12,6 +15,9 @@
# User Class, due to migration to django 1.6.5
class User(AbstractUser):
+ """
+ Un utiliateur HDALab.
+ """
class Meta:
db_table = 'auth_user'
@@ -26,17 +32,30 @@
class Organisation(models.Model):
+ """
+ Représente une entité émettrice de documents.
+ """
hda_id = models.CharField(max_length=512, unique=True, blank=False, null=False)
name = models.CharField(max_length=512, unique=False, blank=False, null=False)
location = models.CharField(max_length=512, unique=False, blank=True, null=True)
website = models.CharField(max_length=2048, unique=False, blank=True, null=True)
-
+
class Author(models.Model):
+ """
+ Personne ayant importer une fiche.
+ """
+
hda_id = models.CharField(max_length=512, unique=True, blank=False, null=False)
lastname = models.CharField(max_length=512, unique=False, blank=True, null=True)
firstname = models.CharField(max_length=512, unique=False, blank=True, null=True)
class TimePeriod(models.Model):
+ """
+ Période de scolarité:
+ - Primaire
+ - Collège
+ - Lycée
+ """
TIME_PERIOD_CHOICES = (
(1, u'Primaire'),
(2, u'Collège'),
@@ -52,7 +71,7 @@
natural_key = models.CharField(max_length=512, unique=True, blank=False, null=False)
objects = SortedModelManager()
-
+
class Meta:
unique_together = ("label", "school_period")
@@ -60,6 +79,13 @@
return unicode(self.label)
class Domain(models.Model):
+ """
+ Période de la scolarité ciblé par une fiche:
+ - Global (toute les période scolaires)
+ - Primaire
+ - Collège
+ - Lycée
+ """
DOMAIN_PERIOD_CHOICES = (
(0, u'Global'),
(1, u'Primaire'),
@@ -86,22 +112,44 @@
class DocumentFormat(models.Model):
+ """
+ Format de la fiche (pdf, word, html,...)
+ """
label = models.CharField(max_length=512, unique=True, blank=False, null=False)
def __unicode__(self):
return unicode(self.label)
-
+
class TagCategory(models.Model):
+ """
+ Catégorie du tag. Explique pourqoui le tag a été posé sur une fiche.
+ Exemples :
+ - Localisation : le tage représente un lieu en relation avec la fiche.
+ - Créateur : Le tag représente l'auteur de(s) oeuvre(s) décrite(s) dans la fiche.
+ - Datation : Le tag ajoute une information de date sur l'oeuvre sujet de la fiche.
+ - Ecole/Mouvement : Le tag décrit à quelle école ou mouvement artistique appartient l'oeuvre sujet de la fiche.
+ - Discipline artistique : Le tag décrit à quelle discipline artistique appartient l'oeuvre sujet de la fiche.
+ """
label = models.CharField(max_length=512, unique=True, blank=False, null=False)
natural_key = models.CharField(max_length=512, unique=False, blank=False, null=False, db_index=True)
-
+
def __unicode__(self):
return unicode(self.label)
-
+
class Meta:
verbose_name_plural = "TagCategories"
class Tag(models.Model):
+ """
+ Un tag. Soit c'est un simple mot, soit il est "sémantisé" et dans ce cas, il fait référence à une page Wikipedia.
+ Attributs remarquables:
+ - wikipedia_url : l'url wikipedia
+ - wikipedia_pageid : l'identifiant de page wikipedia.
+ - alternative_wikipedia_url : autre page wikipedia pour le même tag (par exemple "Molière" pour "Jean-Baptiste Poquelin")
+ - url_status : état de liage du tag (pas de liage proposé, redirection, homonymie, correspondance, non sémantisé)
+ - dbpedia_uri : URI DBPedia
+ - popularity : Popularité du tag sur le portail HDA. Cela permet de mettre une priorité pour sémantisé le tag.
+ """
TAG_URL_STATUS_CHOICES = (
(0, "null_result"),
(1, "redirection"),
@@ -109,7 +157,7 @@
(3, "match"),
(4, "unsematized"),
)
-
+
TAG_URL_STATUS_DICT = {
"null_result":0,
"redirection":1,
@@ -117,7 +165,7 @@
"match":3,
"unsemantized":4,
}
-
+
label = models.CharField(max_length=1024, unique=False, blank=False, null=False, db_index=True)
alternative_label = models.CharField(max_length=1024, unique=False, blank=True, null=True)
normalized_label = models.CharField(max_length=1024, unique=False, blank=False, null=False, db_index=True, editable=False)
@@ -135,7 +183,7 @@
#natural_key = models.CharField(max_length=7168, blank=True, null=True, db_index=True)
#TODO: find a proper key. natural key is not really a key.
natural_key = models.CharField(max_length=7168, blank=False, null=False, db_index=True)
-
+
def __init__(self, *args, **kwargs):
models.Model.__init__(self, *args, **kwargs)
@@ -145,7 +193,7 @@
def url_status_text(): #@NoSelf
def fget(self):
return self.TAG_URL_STATUS_CHOICES[self.url_status][1]
-
+
return locals()
def calculate_natural_key(self):
@@ -157,18 +205,21 @@
]
return ('_'.join(parts))[:7168]
-
+
def save(self, *args, **kwargs):
if self.label and not self.normalized_label:
self._normalized_label = normalize(self.label)
if not self.force_natural_key:
self.natural_key = self.calculate_natural_key()
- super(Tag, self).save(*args, **kwargs)
-
+ super(Tag, self).save(*args, **kwargs)
+
class Meta:
unique_together = (('label', 'original_label', 'url_status'),)
-
+
class Location(models.Model):
+ """
+ Information de lieu pour une fiche, avec en particulier son numéro insee.
+ """
name = models.CharField(max_length=512, unique=False, blank=False, null=False)
insee = models.CharField(max_length=5, unique=True, blank=False, null=False)
@@ -177,12 +228,12 @@
def generate_m2m_setter(m2m_field_name):
-
+
def set_m2m_field(self, lst):
-
+
m2m_manager = getattr(self, m2m_field_name)
m2m_manager.clear()
-
+
through_klass = set_m2m_field.cache.get('through_klass', None)
if through_klass is None:
field = getattr(self.__class__, m2m_field_name)
@@ -203,11 +254,14 @@
new_rel = through_klass(**kwargs)
new_rel.save()
set_m2m_field.cache = {}
-
+
return set_m2m_field
class Datasheet(models.Model):
+ """
+ Une fiche de ressource du portail Histoire des Arts.
+ """
hda_id = models.CharField(max_length=512, unique=True, blank=False, null=False)
author = models.ForeignKey(Author, null=True, blank=True, serialize=False)
organisation = models.ForeignKey(Organisation, serialize=False, null=True)
@@ -231,38 +285,38 @@
validator = models.ForeignKey(User, null=True, blank=True, serialize=False)
manual_order = models.BooleanField(default=False, db_index=True, serialize=False)
tags = models.ManyToManyField(Tag, through='TaggedSheet', serialize=False)
-
+
def natural_key(self):
return self.hda_id
-
+
def validate(self, user):
self.validation_date = datetime.datetime.now()
self.validated = True
self.validator = user
self.save()
-
+
def unvalidate(self):
self.validation_date = datetime.datetime.min
self.validated = False
self.validator = None
self.save()
-
-
+
+
set_domains = generate_m2m_setter("domains")
-
+
@Property
def domains_list(): #@NoSelf
def fget(self):
return [d.label for d in self.domains.all()]
-
- return locals()
+
+ return locals()
@Property
def domains_text(): #@NoSelf
def fget(self):
return "; ".join(self.domains_list)
-
- return locals()
+
+ return locals()
set_primary_periods = generate_m2m_setter("primary_periods")
@@ -270,96 +324,96 @@
@Property
def primary_periods_list(): #@NoSelf
def fget(self):
- return [d.label for d in self.primary_periods.all()]
+ return [d.label for d in self.primary_periods.all()]
- return locals()
+ return locals()
-
+
@Property
def primary_periods_text(): #@NoSelf
def fget(self):
- return "; ".join(self.primary_periods_list)
+ return "; ".join(self.primary_periods_list)
- return locals()
+ return locals()
set_college_periods = generate_m2m_setter("college_periods")
@Property
def college_periods_list(): #@NoSelf
def fget(self):
- return [d.label for d in self.college_periods.all()]
+ return [d.label for d in self.college_periods.all()]
- return locals()
+ return locals()
@Property
def college_periods_text(): #@NoSelf
def fget(self):
- return "; ".join(self.college_periods_list)
+ return "; ".join(self.college_periods_list)
- return locals()
+ return locals()
set_highschool_periods = generate_m2m_setter("highschool_periods")
@Property
def highschool_periods_list(): #@NoSelf
def fget(self):
- return [d.label for d in self.highschool_periods.all()]
+ return [d.label for d in self.highschool_periods.all()]
- return locals()
+ return locals()
@Property
def highschool_periods_text(): #@NoSelf
def fget(self):
- return "; ".join(self.highschool_periods_list)
+ return "; ".join(self.highschool_periods_list)
- return locals()
+ return locals()
set_primary_themes = generate_m2m_setter("primary_themes")
@Property
def primary_themes_list(): #@NoSelf
def fget(self):
- return [d.label for d in self.primary_themes.all()]
+ return [d.label for d in self.primary_themes.all()]
- return locals()
+ return locals()
@Property
def primary_themes_text(): #@NoSelf
def fget(self):
- return "; ".join(self.primary_themes_list)
+ return "; ".join(self.primary_themes_list)
- return locals()
+ return locals()
set_college_themes = generate_m2m_setter("college_themes")
@Property
def college_themes_list(): #@NoSelf
def fget(self):
- return [d.label for d in self.college_themes.all()]
+ return [d.label for d in self.college_themes.all()]
- return locals()
-
+ return locals()
+
@Property
def college_themes_text(): #@NoSelf
def fget(self):
- return "; ".join(self.college_themes_list)
+ return "; ".join(self.college_themes_list)
- return locals()
+ return locals()
set_highschool_themes = generate_m2m_setter("highschool_themes")
@Property
def highschool_themes_list(): #@NoSelf
def fget(self):
- return [d.label for d in self.highschool_themes.all()]
+ return [d.label for d in self.highschool_themes.all()]
return locals()
@Property
def highschool_themes_text(): #@NoSelf
def fget(self):
- return "; ".join(self.highschool_themes_list)
+ return "; ".join(self.highschool_themes_list)
return locals()
@@ -367,14 +421,14 @@
def town_text(): #@NoSelf
def fget(self):
return self.town.name if self.town else ""
-
+
return locals()
@Property
def tags_text(): #@NoSelf
def fget(self):
return "; ".join([t.label for t in self.tags.all()])
-
+
return locals()
@models.permalink
@@ -385,6 +439,13 @@
class TaggedSheet(models.Model):
+ """
+ Objet liant un tag à une fiche.
+ Attributs important:
+ - order : ordre du tag dans la liste de tag de la fiche. Plus un tag est en tête de fiche, plus il est important pour la fiche.
+ - index_note : coéficient d'importance du tag calculé automatiquement lors de l'import et permettant de déterminer un ordre initial pour les tags.
+ - wikipedia_revision_id : Numéro de révision de la page wikipedia au moment de la pose du tag sur la fiche.
+ """
datasheet = models.ForeignKey(Datasheet)
tag = models.ForeignKey(Tag)
created_at = models.DateTimeField(auto_now_add=True)
@@ -392,23 +453,23 @@
order = models.IntegerField(null=False, blank=False, default=0, db_index=True)
index_note = models.FloatField(null=False, blank=False, default=0.0, db_index=True)
wikipedia_revision_id = models.BigIntegerField(unique=False, blank=True, null=True)
-
+
@Property
def wikipedia_verion_permalink(): #@NoSelf
def fget(self):
return settings.WIKIPEDIA_VERSION_PERMALINK_TEMPLATE % (unicode(self.wikipedia_revision_id))
-
+
return locals()
-class SortedDatasheetLink(models.Model):
+class SortedDatasheetLink(models.Model):
datasheet = models.ForeignKey(Datasheet, db_index=True, null=False, blank=False)
sort_value = models.IntegerField(null=False, blank=False)
class Meta:
abstract = True
ordering = ['sort_value']
-
+
class Datasheet_domains(SortedDatasheetLink):
domain = models.ForeignKey(Domain, db_index=True, null=False, blank=False)
@@ -434,6 +495,9 @@
# Evolution pour Hda 2 : folders of datasheets
class Folder(models.Model):
+ """
+ Décrit un dossier thématique comportant une liste de fiches.
+ """
url = models.URLField(max_length=2048, unique=True, blank=False, null=False)
title = models.CharField(max_length=2048, blank=True, null=True)
description = models.TextField(blank=True, null=True)
--- a/src/hdabo/views.py Thu Apr 12 01:27:16 2018 +0200
+++ b/src/hdabo/views.py Wed Apr 11 12:19:47 2018 +0200
@@ -629,6 +629,46 @@
class SearchDatasheet(SearchView):
+ """
+ Vue permettant la recherche dans les fiches HDALab.
+ La recherche se fait dans les objets :class:`hdabo.models.Datasheet`.
+ C'est une vue qui étend `haystack.views.SearchView <https://django-haystack.readthedocs.io/en/v2.3.2/views_and_forms.html#searchview-template-none-load-all-true-form-class-none-searchqueryset-none-context-class-requestcontext-results-per-page-none>`_.
+
+ Paramêtres GET:
+
+ :var (str) q: La requête à effectuer.
+ :var (str) format: format de la réponse. Si `json` le contenu retourné est un contenu json.
+ :var (int) limit: Le nombre maximum de résultat par page.
+ :var (int) page: le numéro de page de résultat.
+
+
+ Réponse (application/json):
+
+ Une liste comprenant les résultats de la recherche.
+ Si le paramêtre `format` est ``json``, cette vue retourne un document json décrit plus bas.
+ Sinon, la vue retourne une page html.
+
+ exemple de retour json ::
+
+ {
+ "results": [
+ {
+ "url": " http://www.lesartsdecoratifs.fr/francais/arts-decoratifs/collections-26/parcours-27/chronologique/xixe-siecle/les-salles-302/couleurs-vives-et-bois-clairs/",
+ "hda_id": "1279",
+ "description": "A partir des ...",
+ "title": "Couleurs vives et bois clairs"
+ },
+ {
+ "url": "http://www.louvre.fr/oeuvre-notices/autoportrait",
+ "hda_id": "826",
+ "description": "Conservé au Louvre...",
+ "title": "Autoportrait, Jean Fouquet (1452-1455)"
+ },
+ ...
+ ]
+ }
+
+ """
template = "partial/search_datasheet_for_folders.html"
--- a/src/hdabo/wp_utils.py Thu Apr 12 01:27:16 2018 +0200
+++ b/src/hdabo/wp_utils.py Wed Apr 11 12:19:47 2018 +0200
@@ -28,29 +28,29 @@
def query_wikipedia_title(site, label=None, pageid=None):
-
+
params = {'action':'query', 'prop':'info|categories|langlinks', 'inprop':'url', 'lllimit':'500', 'cllimit':'500', 'rvprop':'ids'}
-
+
if label:
params['titles'] = label
else:
params['pageids'] = pageid
wpquery = api.APIRequest(site, params) #@UndefinedVariable
-
+
response = wpquery.query()
original_response = response
def return_null_result():
return { 'new_label': None, 'alternative_label': None, 'status': Tag.TAG_URL_STATUS_DICT["null_result"], 'wikipedia_url': None, 'pageid': None, 'alternative_wikipedia_url': None, 'alternative_pageid': None, 'dbpedia_uri': None, 'revision_id': None, 'response': response }
-
+
query_dict = response['query']
# get page if multiple pages or none -> return Tag.null_result
pages = query_dict.get("pages", {})
if len(pages) > 1 or len(pages) == 0:
return return_null_result()
-
+
page = pages.values()[0]
-
+
if u"invalid" in page or u"missing" in page:
return return_null_result()
@@ -60,57 +60,57 @@
alternative_label = None
alternative_url = None
alternative_pageid = None
-
+
if __is_homonymie(page):
status = Tag.TAG_URL_STATUS_DICT["homonyme"]
elif u"redirect" in page:
status = Tag.TAG_URL_STATUS_DICT["redirection"]
else:
status = Tag.TAG_URL_STATUS_DICT["match"]
-
+
if status == Tag.TAG_URL_STATUS_DICT["redirection"]:
params['redirects'] = True
- wpquery = api.APIRequest(site, params) #@UndefinedVariable
+ wpquery = api.APIRequest(site, params) #@UndefinedVariable
response = wpquery.query()
query_dict = response['query']
pages = query_dict.get("pages", {})
- #we know that we have at least one answer
+ #we know that we have at least one answer
if len(pages) > 1 or len(pages) == 0:
return return_null_result()
page = pages.values()[0]
alternative_label = page.get('title', None)
alternative_url = page.get('fullurl', None)
alternative_pageid = page.get('pageid',None)
-
+
revision_id = page.get('lastrevid', None)
-
+
# to be perfect we should sparql request DBPEDIA_URI_TEMPLATE, but we simply build the url
dbpedia_uri = settings.DBPEDIA_URI_TEMPLATE % ("resource", urlize_for_wikipedia(new_label))
-
+
return { 'new_label': new_label, 'alternative_label': alternative_label, 'status': status, 'wikipedia_url': url, 'pageid': pageid, 'alternative_wikipedia_url': alternative_url, 'alternative_pageid': alternative_pageid, 'dbpedia_uri': dbpedia_uri, 'revision_id': revision_id, 'response': original_response }
def get_or_create_tag(tag_label):
-
+
tag_label_normalized = normalize_tag(tag_label)
# We get the wikipedia references for the tag_label
# We get or create the tag object
-
+
tag = None
for t in Tag.objects.filter(label__iexact=tag_label_normalized):
if tag is None or t.url_status != Tag.TAG_URL_STATUS_DICT['null_result']:
tag = t
if tag.url_status != Tag.TAG_URL_STATUS_DICT['null_result']:
break
-
+
if tag is None:
tag = Tag(label=tag_label_normalized, original_label=tag_label)
created = True
else:
created = False
-
+
site = wiki.Wiki(settings.WIKIPEDIA_API_URL) #@UndefinedVariable
if created:
@@ -125,7 +125,7 @@
dbpedia_uri = wp_res["dbpedia_uri"]
wikipedia_revision_id = wp_res['revision_id']
-
+
# We save the datas
if new_label is not None:
tag.label = new_label
@@ -134,23 +134,23 @@
tag.alternative_label = alternative_label
tag.alternative_wikipedia_url = alternative_url
tag.alternative_wikipedia_pageid = alternative_pageid
- tag.wikipedia_url = url
+ tag.wikipedia_url = url
tag.wikipedia_pageid = pageid
- tag.dbpedia_uri = dbpedia_uri
+ tag.dbpedia_uri = dbpedia_uri
tag.save()
-
+
elif tag.wikipedia_pageid:
wp_res = query_wikipedia_title(site, pageid=tag.wikipedia_pageid)
wikipedia_revision_id = wp_res['revision_id']
else:
wikipedia_revision_id = None
-
-
+
+
return tag, wikipedia_revision_id, created
def process_tag(site, tag, verbosity=0):
-
+
wp_res = query_wikipedia_title(site, label=tag.label)
new_label = wp_res['new_label']
alternative_label= wp_res['alternative_label']
@@ -162,13 +162,13 @@
response = wp_res['response']
dbpedia_uri = wp_res["dbpedia_uri"]
revision_id = wp_res["revision_id"]
-
+
if verbosity >= 2 :
print "response from query to %s with parameters %s :" % (site.apibase, repr(new_label))
print repr(response)
-
+
prev_wikipedia_pageid = tag.wikipedia_pageid
-
+
if new_label is not None:
tag.label = new_label
if status is not None:
@@ -179,14 +179,17 @@
tag.alternative_label = alternative_label
tag.alternative_wikipedia_url = alternative_url
tag.alternative_wikipedia_pageid = alternative_pageid
-
+
tag.save()
-
+
if prev_wikipedia_pageid != pageid:
TaggedSheet.objects.filter(tag=tag).update(wikipedia_revision_id=revision_id)
def reorder_datasheet_tags(ds):
+ """
+ Reorder a Datasheet tags (object Tag) according to the score they obtain on a search on the title and description of the Datasheet.
+ """
ts_list = []
for ts in ds.taggedsheet_set.all():
ts.index_note = 0
@@ -206,4 +209,4 @@
ds.manual_order = False
ds.save()
-
+
--- a/src/hdalab/__init__.py Thu Apr 12 01:27:16 2018 +0200
+++ b/src/hdalab/__init__.py Wed Apr 11 12:19:47 2018 +0200
@@ -1,4 +1,7 @@
# -*- coding: utf-8 -*-
+"""
+Module contenant l'applicatiion Django HDALab.
+"""
from __future__ import absolute_import
VERSION = (3, 2, 1, "final", 0)
--- a/src/hdalab/management/commands/calculate_preview.py Thu Apr 12 01:27:16 2018 +0200
+++ b/src/hdalab/management/commands/calculate_preview.py Wed Apr 11 12:19:47 2018 +0200
@@ -1,8 +1,16 @@
# -*- coding: utf-8 -*-
'''
-Created on Jan 30, 2012
+Commande permettant la création des miniatures renkan.
+
+Par défaut, seul les renkan pour lesquel c'est nécessaire sont traités (ceux qui sont publié)
+Les miniatures sont calculées immédiatement de façons synchrone.
-@author: ymh
+**Usage**: ``django-admin calculate_preview [options]``
+
+**Options spécifiques:**
+
+ - *\-\-all*: Capture les miniatures pours tous les renkan publié. Remplace les miniatures existantes.
+
'''
import logging
@@ -25,7 +33,7 @@
'''
options = ''
help = """calculate renkan preview."""
-
+
option_list = NoArgsCommand.option_list + (
make_option('--all',
action='store_true',
@@ -33,16 +41,16 @@
default=False,
help='force all tags to be updated, not only those not yet processed'),
)
-
+
def handle_noargs(self, **options):
-
+
self.style = no_style()
-
+
self.all = options.get('all', False)
queryset = HdalabRenkan.objects.filter(state=HdalabRenkan.PUBLISHED)
-
+
if not self.all:
queryset = queryset.filter(renkan__image = settings.DEFAULT_RENKAN_ICON)
--- a/src/hdalab/management/commands/export_tags_csv.py Thu Apr 12 01:27:16 2018 +0200
+++ b/src/hdalab/management/commands/export_tags_csv.py Wed Apr 11 12:19:47 2018 +0200
@@ -1,8 +1,21 @@
# -*- coding: utf-8 -*-
'''
-Created on Jan 25, 2012
+Exporte les catégories wikipedia des tags dans 3 fichiers csv:
+ - \*_visible.txt : les catégories visibles.
+ - \*_hidden.txt : les catégories cachés.
+ - \*_infobox.txt : les paramêtres des infobox.
+
+Seul les tags sémantisés sont pris en compte.
-@author: ymh
+**Usage**: ``django-admin export_tags_csv [options] <chemin_vers_le_nom_de_base_des_fichiers_csv>``
+
+**Options spécifiques:**
+
+ - *\-c,\-\-category*: filtre par nom de catégories.
+ - *\-\-lines* : nombre maximal de ligne à exporter. 0 signifie toute.
+ - *\-\-encoding* : encodage des fichier, le défaut est `latin-1`.
+ - *\-f* : force l'écrasement des fichiers csv de sortie.
+
'''
from django.core.management.base import BaseCommand, CommandError
@@ -23,7 +36,7 @@
-c, --category : filter by category
--lines : max number of lines to load (for each file). 0 means all.
--encoding : files encoding. default to latin-1"""
-
+
option_list = BaseCommand.option_list + (
make_option("-c","--category",
action='append',
@@ -43,9 +56,9 @@
default=False,
help='force file overwrite'),
)
-
+
def handle(self, *args, **options):
-
+
if len(args) == 0 or not args[0]:
raise CommandError("Gives at last one csv file to export")
@@ -54,13 +67,13 @@
self.force = options.get("force", False)
self.base_path = args[0].strip()
self.interactive = options.get("interactive",True)
-
+
files_path = {
"visible" : { 'path':self.base_path + "_visible.txt",},
"hidden" : { 'path':self.base_path + "_hidden.txt",},
"infobox" : { 'path':self.base_path + "_infobox.txt",},
}
-
+
try:
for filedef in files_path.values():
try:
@@ -81,9 +94,9 @@
filedef['file'] = open(filedef['path'],'w')
except IOError:
filedef['file'] = open(filedef['path'],'w')
-
+
filedef['csv'] = UnicodeWriter(filedef['file'], doublequote=False, escapechar="\\", encoding=self.encoding)
-
+
queryset = Tag.objects.exclude(wikipedia_pageid= None)
cat_filter = None
for cat in self.categories:
@@ -93,32 +106,31 @@
cat_filter = cat_filter | Q(category__label = cat)
if cat_filter is not None:
queryset = queryset.filter(cat_filter)
-
+
tcount = queryset.count()
-
+
print "Exporting %d tags" % (tcount)
writer = None
-
+
for i,t in enumerate(queryset.order_by("label")):
-
+
writer = utils.show_progress(i+1, tcount, t.label, 50, writer)
#normal category
row = [t.label,] + [cat.wp_category.label for cat in t.wp_categories.filter(hidden=False)]
files_path['visible']['csv'].writerow(row)
-
+
#hidden category
row = [t.label,] + [cat.wp_category.label for cat in t.wp_categories.filter(hidden=True)]
files_path['hidden']['csv'].writerow(row)
-
+
#infobox
for i in t.infoboxes.all():
vec = [[p.param_name,p.param_value.replace('\n',"\\n")] for p in i.infoboxparameter_set.all()]
ib_params = [num for elem in vec for num in elem]
row = [t.label, i.name.strip()] + ib_params
files_path['infobox']['csv'].writerow(row)
-
+
finally:
for filedef in files_path.itervalues():
if filedef.get('file',None):
filedef['file'].close()
-
\ No newline at end of file
--- a/src/hdalab/management/commands/export_wpcategory_csv.py Thu Apr 12 01:27:16 2018 +0200
+++ b/src/hdalab/management/commands/export_wpcategory_csv.py Wed Apr 11 12:19:47 2018 +0200
@@ -1,8 +1,14 @@
# -*- coding: utf-8 -*-
'''
-Created on Feb 2, 2012
+Exporte en csv les catégories wikipédia utilisées dans HDALab.
+
+**Usage**: ``django-admin export_wpcategory_csv [options] <chemin_vers_le_fichier_csv>``
-@author: ymh
+**Options spécifiques:**
+
+ - *\-\-encoding* : encodage des fichier, le défaut est `latin-1`.
+ - *\-f* : force l'écrasement du fichier csv de sortie.
+
'''
from django.core.management.base import BaseCommand, CommandError
from optparse import make_option
@@ -23,7 +29,7 @@
-e, --encoding : files encoding. default to latin-1
-f, --force : force file overwrite
"""
-
+
option_list = BaseCommand.option_list + (
make_option("-e","--encoding",
action='store',
@@ -37,9 +43,9 @@
default=False,
help='force file overwrite'),
)
-
+
def handle(self, *args, **options):
-
+
if len(args) == 0 or not args[0]:
raise CommandError("Gives at last one csv file to export")
@@ -48,7 +54,7 @@
self.path = args[0].strip()
self.interactive = options.get("interactive",True)
- file = None
+ file = None
try:
try:
file = open(self.path,'r')
@@ -63,27 +69,27 @@
elif not self.interactive and not self.force:
print "Export file %s already exists. Exit." % (self.path)
return "error"
-
+
file.close()
file = open(self.path,'w')
except IOError:
file = open(self.path,'w')
-
+
csv = UnicodeWriter(file, doublequote=False, escapechar="\\", encoding=self.encoding)
writer = None
-
+
qs = WpCategory.objects.filter(tagwpcategory__hidden=False).distinct()
-
+
total = qs.count()
-
+
for i,wpcat in enumerate(qs):
writer = show_progress(i+1, total, wpcat.label, 50, writer)
nb_ds = 0
for tag in wpcat.tagwpcategory_set.all():
nb_ds += tag.tag.datasheet_set.count()
-
- csv.writerow([wpcat.label, u"http://fr.wikipedia.org/wiki/Catégorie:%s" % urlquote(normalize_tag(wpcat.label)), nb_ds])
+
+ csv.writerow([wpcat.label, u"http://fr.wikipedia.org/wiki/Catégorie:%s" % urlquote(normalize_tag(wpcat.label)), nb_ds])
finally:
if file is not None:
- file.close()
\ No newline at end of file
+ file.close()
--- a/src/hdalab/management/commands/fill_tag_years.py Thu Apr 12 01:27:16 2018 +0200
+++ b/src/hdalab/management/commands/fill_tag_years.py Wed Apr 11 12:19:47 2018 +0200
@@ -1,8 +1,13 @@
# -*- coding: utf-8 -*-
'''
-Created on Jan 29, 2012
+Calcule les périodes de date pour les tag (:class:`hdabo.models.Tag`) catégorisés comme `Datation`.
+(c.f. :class:`hdalab.models.dataviz.TagYears`)
-@author: ymh
+Fait une analyse heuristique du label du tag, ou (si disponible) de l'URI DBPedia.
+Efface et remplace les objets deejà existants.
+
+**Usage**: ``django-admin fill_tag_years [options]``
+
'''
from django.conf import settings
from django.core.management.base import NoArgsCommand
@@ -15,16 +20,16 @@
class Command(NoArgsCommand):
def handle_noargs(self, **options):
self.style = no_style()
-
+
TagYears.objects.all().delete()
qs = Tag.objects.filter(category__label="Datation")
total = qs.count()
dbptstart = len(settings.DBPEDIA_URI_TEMPLATE % ("resource",""))
#dbptstart = len("http://dbpedia.org/resource/")
-
+
writer = None
-
+
for i,tag in enumerate(qs):
writer = show_progress(i+1, total, tag.label, 50, writer)
start = None
@@ -51,11 +56,11 @@
else:
start = 1 + 100*(val-1)
end = start + 100
-
+
if start != None and end != None:
ty = TagYears.objects.create(tag=tag, start_year=start, end_year=end)
ty.save()
-
+
def rom_to_int(self, string):
# from http://codereview.stackexchange.com/questions/902/conversion-from-to-roman-numbers
table=[['M',1000],['CM',900],['D',500],['CD',400],['C',100],['XC',90],['L',50],['XL',40],['X',10],['IX',9],['V',5],['IV',4],['I',1]]
@@ -64,4 +69,4 @@
while string.startswith(letter):
result += value
string = string[len(letter):]
- return result
\ No newline at end of file
+ return result
--- a/src/hdalab/management/commands/geojson_transform.py Thu Apr 12 01:27:16 2018 +0200
+++ b/src/hdalab/management/commands/geojson_transform.py Wed Apr 11 12:19:47 2018 +0200
@@ -1,112 +1,118 @@
-# -*- coding: utf-8 -*-
-'''
-@author: raphv
-'''
-from django.conf import settings
-from django.core.management.base import BaseCommand, CommandError
-from django.utils.http import urlquote
-import json
-from SPARQLWrapper import SPARQLWrapper, JSON
-
-#import pydevd #@UnresolvedImport
-#pydevd.settrace(suspend=False)
-
-
-class Command(BaseCommand):
- '''
- Command to export tags
- '''
- args = '<path_to_geojson_file>'
- options = ''
- help = """Adds semantic data to countries.geo.json files"""
-
- def handle(self, *args, **options):
-
- if len(args) == 0 or not args[0]:
- raise CommandError("Give a Geo Json File to process")
-
- geojsonfile = args[0]
-
- f = open(geojsonfile,"r")
- geojson = json.loads(f.read())
- f.close()
-
- labels = [feature['properties']['label_fr'] for feature in geojson['features']]
- #uris = dict([(label, 'http://dbpedia.org/resource/' + urlquote(label.replace(' ','_'))) for label in labels])
- uris = dict([(label, settings.DBPEDIA_URI_TEMPLATE % ( 'resource', urlquote(label.replace(' ','_')) )) for label in labels])
-
- uri_list = [uris[label] for label in uris]
- base_uris = dict([(uris[label],uris[label]) for label in uris])
-
- grp = 10
- #endpoint = SPARQLWrapper("http://dbpedia.org/sparql")
- endpoint = SPARQLWrapper(settings.DBPEDIA_URI_TEMPLATE % ( 'sparql', '' ))
- endpoint.setReturnFormat(JSON)
-
- start = 0
- while start < len(uri_list):
- sparql = """
- PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>
- SELECT ?source ?target
- WHERE {
- ?source dbpedia-owl:wikiPageRedirects ?target .
- Filter (?source in (<%s>)) .
- }
- """ % '>, <'.join(uri_list[start:start + grp])
- endpoint.setQuery(sparql)
- results = endpoint.query().convert()
-
- for r in results["results"]["bindings"]:
- source = r["source"]["value"]
- target = r["target"]["value"]
- base_uris[source] = target
- #print "%s redirects to %s"%(source, target)
- start += grp
-
- base_uri_list = [base_uris[uri] for uri in base_uris]
-
- french_labels = {}
- labels = {}
-
- start = 0
- while start < len(base_uri_list):
-
- sparql = """
- PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
- SELECT ?country ?label WHERE {
- ?country rdfs:label ?label .
- FILTER (?country in (<%s>))
- }
- """ % '>, <'.join(base_uri_list[start:start + grp])
-
- endpoint.setQuery(sparql)
- results = endpoint.query().convert()
-
- #print repr(results)
-
- for r in results["results"]["bindings"]:
- country = r["country"]["value"]
- label = r["label"]["value"]
- if country not in labels:
- labels[country] = {}
- labels[country][r["label"]["xml:lang"]] = label
- if r["label"]["xml:lang"] == 'fr':
- french_labels[country] = label
- print "%s label: %s"%(country, label)
-
- start += grp
-
- for feature in geojson['features']:
- base_uri = base_uris[uris[feature['properties']['label_fr']]]
- feature['properties']['dbpedia_uri'] = base_uri
-
- if labels.has_key(base_uri):
- feature['properties']['labels'] = labels[base_uri]
- if french_labels.has_key(base_uri):
- feature['properties']['label_fr'] = french_labels[base_uri]
- else:
- print "No label for %s"%base_uri
-
- f = open(geojsonfile,"w")
- f.write(json.dumps(geojson, indent=2))
- f.close()
\ No newline at end of file
+# -*- coding: utf-8 -*-
+'''
+Ajoute des données sémantiques issues de DBPedia a des fichiers de pays geojson.
+En particulier ajoute les labels français et dans les autres langues disponibles.
+
+**Usage**: ``django-admin geojson_transform [options] [args [args ...]]``
+
+**Arguments**: <chemin_vers_fichier_geojson>
+
+'''
+from django.conf import settings
+from django.core.management.base import BaseCommand, CommandError
+from django.utils.http import urlquote
+import json
+from SPARQLWrapper import SPARQLWrapper, JSON
+
+#import pydevd #@UnresolvedImport
+#pydevd.settrace(suspend=False)
+
+
+class Command(BaseCommand):
+ '''
+ Command to export tags
+ '''
+ args = '<path_to_geojson_file>'
+ options = ''
+ help = """Adds semantic data to countries.geo.json files"""
+
+ def handle(self, *args, **options):
+
+ if len(args) == 0 or not args[0]:
+ raise CommandError("Give a Geo Json File to process")
+
+ geojsonfile = args[0]
+
+ f = open(geojsonfile,"r")
+ geojson = json.loads(f.read())
+ f.close()
+
+ labels = [feature['properties']['label_fr'] for feature in geojson['features']]
+ #uris = dict([(label, 'http://dbpedia.org/resource/' + urlquote(label.replace(' ','_'))) for label in labels])
+ uris = dict([(label, settings.DBPEDIA_URI_TEMPLATE % ( 'resource', urlquote(label.replace(' ','_')) )) for label in labels])
+
+ uri_list = [uris[label] for label in uris]
+ base_uris = dict([(uris[label],uris[label]) for label in uris])
+
+ grp = 10
+ #endpoint = SPARQLWrapper("http://dbpedia.org/sparql")
+ endpoint = SPARQLWrapper(settings.DBPEDIA_URI_TEMPLATE % ( 'sparql', '' ))
+ endpoint.setReturnFormat(JSON)
+
+ start = 0
+ while start < len(uri_list):
+ sparql = """
+ PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>
+ SELECT ?source ?target
+ WHERE {
+ ?source dbpedia-owl:wikiPageRedirects ?target .
+ Filter (?source in (<%s>)) .
+ }
+ """ % '>, <'.join(uri_list[start:start + grp])
+ endpoint.setQuery(sparql)
+ results = endpoint.query().convert()
+
+ for r in results["results"]["bindings"]:
+ source = r["source"]["value"]
+ target = r["target"]["value"]
+ base_uris[source] = target
+ #print "%s redirects to %s"%(source, target)
+ start += grp
+
+ base_uri_list = [base_uris[uri] for uri in base_uris]
+
+ french_labels = {}
+ labels = {}
+
+ start = 0
+ while start < len(base_uri_list):
+
+ sparql = """
+ PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
+ SELECT ?country ?label WHERE {
+ ?country rdfs:label ?label .
+ FILTER (?country in (<%s>))
+ }
+ """ % '>, <'.join(base_uri_list[start:start + grp])
+
+ endpoint.setQuery(sparql)
+ results = endpoint.query().convert()
+
+ #print repr(results)
+
+ for r in results["results"]["bindings"]:
+ country = r["country"]["value"]
+ label = r["label"]["value"]
+ if country not in labels:
+ labels[country] = {}
+ labels[country][r["label"]["xml:lang"]] = label
+ if r["label"]["xml:lang"] == 'fr':
+ french_labels[country] = label
+ print "%s label: %s"%(country, label)
+
+ start += grp
+
+ for feature in geojson['features']:
+ base_uri = base_uris[uris[feature['properties']['label_fr']]]
+ feature['properties']['dbpedia_uri'] = base_uri
+
+ if labels.has_key(base_uri):
+ feature['properties']['labels'] = labels[base_uri]
+ if french_labels.has_key(base_uri):
+ feature['properties']['label_fr'] = french_labels[base_uri]
+ else:
+ print "No label for %s"%base_uri
+
+ f = open(geojsonfile,"w")
+ f.write(json.dumps(geojson, indent=2))
+ f.close()
--- a/src/hdalab/management/commands/import_hda_insee_csv.py Thu Apr 12 01:27:16 2018 +0200
+++ b/src/hdalab/management/commands/import_hda_insee_csv.py Wed Apr 11 12:19:47 2018 +0200
@@ -1,6 +1,11 @@
# -*- coding: utf-8 -*-
'''
-@author: raphv
+Importe les code INSEE dans les fiches HDA (objets :class:`hdabo.models.datasheet`).
+
+**Usage**: ``django-admin import_hda_insee_csv [options] [args [args ...]]``
+
+**Arguments**: <chemin_vers_csv_insee>
+
'''
import csv
import re
@@ -18,21 +23,21 @@
args = '<path_to_csv_file>'
options = ''
help = """Imports HDA Lab INSEE codes from a csv file"""
-
+
def handle(self, *args, **options):
if len(args) == 0 or not args[0]:
raise CommandError("Give a CSV File to import")
-
+
filename = args[0]
-
+
csvfile = open(filename, "rb")
dialect = csv.Sniffer().sniff(csvfile.read(1024))
csvfile.seek(0)
reader = csv.reader(csvfile, dialect)
fieldstoget = [ 'id', 'insee' ]
-
-
+
+
for i,line in enumerate(reader):
if i == 0:
fields = {}
@@ -47,9 +52,9 @@
rawdata = dict([(k,line[v].strip()) for k,v in fields.iteritems()])
# Traitement special pour la Corse
insee = int(re.sub('^2(A|B)','20',rawdata['insee']))
-
+
hda_id = int(rawdata['id'])
-
+
try:
datasheet = Datasheet.objects.get(hda_id=hda_id)
except Datasheet.DoesNotExist:
@@ -60,11 +65,11 @@
except InseeCoords.DoesNotExist:
print "INSEE entry for Insee Code %d does not exist" % insee
inseecoord = None
-
+
if datasheet is not None and inseecoord is not None:
dsextra, created = DatasheetExtras.objects.get_or_create(datasheet=datasheet, defaults={'insee':inseecoord})
if not created:
dsextra.insee = inseecoord
dsextra.save()
-
- csvfile.close()
\ No newline at end of file
+
+ csvfile.close()
--- a/src/hdalab/management/commands/import_hdabo_db.py Thu Apr 12 01:27:16 2018 +0200
+++ b/src/hdalab/management/commands/import_hdabo_db.py Wed Apr 11 12:19:47 2018 +0200
@@ -1,8 +1,27 @@
# -*- coding: utf-8 -*-
'''
-Created on Feb 28, 2012
+Cette commande transforme une base de donnée hdabo en base de donnée hdalab.
+En particulier cette command est utilisée dans l'import de l'extraction rdf des données HDA.
+
+Cette commande enchaine en fait les commandes Django suivantes:
-@author: ymh
+ - `migrate <https://docs.djangoproject.com/en/1.8/ref/django-admin/#django-admin-migrate>`_
+ - :mod:`query_wikipedia_category \-f \-\-all <hdalab.management.commands.query_wikipedia_category>` (si l'option est passée)
+ - :mod:`query_dbpedia \-f \-\-all <hdalab.management.commands.query_dbpedia>`
+ - :mod:`fill_tag_years <hdalab.management.commands.fill_tag_years>`
+ - :mod:`geojson_transform \<chemin répertoire data\>/countries.geo.json <hdalab.management.commands.geojson_transform>`
+ - :mod:`query_geo_inclusion <hdalab.management.commands.query_geo_inclusion>`
+ - :mod:`import_insee_csv \<chemin répertoire data\>/villes.csv <hdalab.management.commands.import_insee_csv>`
+ - :mod:`import_insee_csv \<chemin répertoire data\>/additional_cities.csv <hdalab.management.commands.import_insee_csv>`
+ - :mod:`import_hda_insee_csv \<chemin répertoire data\>/HDA_Insee.csv <hdalab.management.commands.import_hda_insee_csv>`
+ - :mod:`query_category_inclusion \-f \-\-all <hdalab.management.commands.query_category_inclusion>`
+
+**Usage**: ``django-admin import_hdabo_db [options] [<chemin répertoire data>]``
+
+**Options spécifiques:**
+
+ - *\-c,\-\-categories*: ajoute la commande :mod:`query_wikipedia_category \-f \-\-all <hdalab.management.commands.query_wikipedia_category>` à la chaîne de traitements.
+
'''
from django.core.management.base import BaseCommand
from django.core.management import call_command
--- a/src/hdalab/management/commands/import_insee_csv.py Thu Apr 12 01:27:16 2018 +0200
+++ b/src/hdalab/management/commands/import_insee_csv.py Wed Apr 11 12:19:47 2018 +0200
@@ -1,59 +1,65 @@
-# -*- coding: utf-8 -*-
-'''
-@author: raphv
-'''
-from django.core.management.base import BaseCommand, CommandError
-from SPARQLWrapper import SPARQLWrapper, JSON
-from hdalab.models import InseeCoords
-import json
-import csv
-import re
-import sys
-
-class Command(BaseCommand):
- '''
- Command to export tags
- '''
- args = '<path_to_csv_file>'
- options = ''
- help = """Imports Insee codes and geographic coordinates from a csv file"""
-
- def handle(self, *args, **options):
-
- if len(args) == 0 or not args[0]:
- raise CommandError("Give a CSV File to import")
-
- filename = args[0]
-
- csvfile = open(filename, "rb")
- dialect = csv.Sniffer().sniff(csvfile.read(1024))
- csvfile.seek(0)
- reader = csv.reader(csvfile, dialect)
- fieldstoget = [ 'ville', 'insee', 'latitude', 'longitude' ]
-
- for i,line in enumerate(reader):
- if i == 0:
- fields = {}
- minlength = 0
- for j,field in enumerate(line):
- for fieldname in fieldstoget:
- if re.search('(?i)%s' % fieldname, field):
- fields[fieldname] = j
- minlength = max(j,minlength)
- else:
- if len(line) > minlength:
- rawdata = dict([(k,line[v].strip()) for k,v in fields.iteritems()])
- #print "Processing line %d" % i
- #print rawdata
- try:
- latitude = float(rawdata['latitude'].replace(',','.'))
- longitude = float(rawdata['longitude'].replace(',','.')) if rawdata['longitude'] != '-' else 0
- insee = int(rawdata['insee'])
- ville = unicode(rawdata['ville'], 'iso-8859-1')
-
- InseeCoords.objects.get_or_create(insee=insee, city_name=ville, latitude=latitude, longitude=longitude)
-
- except:
- print line, "Error :", sys.exc_info()[1]
-
- csvfile.close()
\ No newline at end of file
+# -*- coding: utf-8 -*-
+'''
+Importe des codes INSEE et les coordonnées géographiques d'un fichier CSV.
+Crée des objects :class:`hdalab.models.dataviz.InseeCoords`.
+
+Attention cette commande de remplace pas ni n'efface de données existante dans la base (la clef étant le numéro INSEE).
+
+**Usage**: ``django-admin import_insee_csv <chemin_vers_fichier_csv>``
+
+'''
+from django.core.management.base import BaseCommand, CommandError
+from SPARQLWrapper import SPARQLWrapper, JSON
+from hdalab.models import InseeCoords
+import json
+import csv
+import re
+import sys
+
+class Command(BaseCommand):
+ '''
+ Command to export tags
+ '''
+ args = '<path_to_csv_file>'
+ options = ''
+ help = """Imports Insee codes and geographic coordinates from a csv file"""
+
+ def handle(self, *args, **options):
+
+ if len(args) == 0 or not args[0]:
+ raise CommandError("Give a CSV File to import")
+
+ filename = args[0]
+
+ csvfile = open(filename, "rb")
+ dialect = csv.Sniffer().sniff(csvfile.read(1024))
+ csvfile.seek(0)
+ reader = csv.reader(csvfile, dialect)
+ fieldstoget = [ 'ville', 'insee', 'latitude', 'longitude' ]
+
+ for i,line in enumerate(reader):
+ if i == 0:
+ fields = {}
+ minlength = 0
+ for j,field in enumerate(line):
+ for fieldname in fieldstoget:
+ if re.search('(?i)%s' % fieldname, field):
+ fields[fieldname] = j
+ minlength = max(j,minlength)
+ else:
+ if len(line) > minlength:
+ rawdata = dict([(k,line[v].strip()) for k,v in fields.iteritems()])
+ #print "Processing line %d" % i
+ #print rawdata
+ try:
+ latitude = float(rawdata['latitude'].replace(',','.'))
+ longitude = float(rawdata['longitude'].replace(',','.')) if rawdata['longitude'] != '-' else 0
+ insee = int(rawdata['insee'])
+ ville = unicode(rawdata['ville'], 'iso-8859-1')
+
+ InseeCoords.objects.get_or_create(insee=insee, city_name=ville, latitude=latitude, longitude=longitude)
+
+ except:
+ print line, "Error :", sys.exc_info()[1]
+
+ csvfile.close()
--- a/src/hdalab/management/commands/query_category_inclusion.py Thu Apr 12 01:27:16 2018 +0200
+++ b/src/hdalab/management/commands/query_category_inclusion.py Wed Apr 11 12:19:47 2018 +0200
@@ -1,8 +1,20 @@
# -*- coding: utf-8 -*-
'''
-Created on July 2, 2012
+Requête wikipedia pour reconstituer l'arbre des catégories.
+
+Cette commande utilise directement `l'api wikipedia <https://www.mediawiki.org/wiki/API:Main_page>`_ pour faire ses requêtes.
+
+**Usage**: ``django-admin query_category_inclusion [options]``
+
+**Options spécifiques:**
-@author: raphv
+ - *\-\-all* : force à traiter toutes les catégories
+ - *\-\-force* : ne pose aucune question
+ - *\-\-site=SITE_URL* : url du site wikipedia (défaut: https://fr.wikipedia.org/w/api.php)
+ - *\-\-limit=LIMIT* : Nombre de catégories à traiter
+ - *\-\-start=START* : Nombre de catégories à ignorer
+ - *\-\-category=CATEGORY* : Limite le traitement à cette catégorie
+
'''
from django.conf import settings
@@ -26,7 +38,7 @@
'''
options = ''
help = """query and update wikipedia for tag title."""
-
+
option_list = NoArgsCommand.option_list + (
make_option('--all',
action='store_true',
@@ -67,101 +79,101 @@
def query_all_categories(self, category_title, site):
-
+
params = {'action':'query', 'cmtitle':category_title, 'list':'categorymembers', 'cmlimit': 'max'}
-
+
res = []
-
+
wpquery = api.APIRequest(site, params) #@UndefinedVariable
response = wpquery.query()
-
+
if self.verbosity > 1:
print "Query category : " + repr(wpquery.request.get_full_url()+"?"+wpquery.request.get_data())
print repr(response)
-
+
members = response.get('query', {}).get('categorymembers', [])
-
+
for member in members:
title = member.get('title',"")
if re.match(CATEGORY_PREFIX, title):
res.append(re.sub(CATEGORY_PREFIX, "", title))
-
+
if self.verbosity > 1:
print "Query categories result: "
print repr(res)
-
+
return res
-
+
def process_categories(self, cat_list, parent_cat):
for cat in cat_list:
child_cat,created = WpCategory.objects.get_or_create(label=cat) #@UnusedVariable
WpCategoryInclusion.objects.get_or_create(parent_category=parent_cat, child_category=child_cat)
-
+
def handle_noargs(self, **options):
-
+
self.style = no_style()
-
+
interactive = options.get('interactive', True)
-
+
self.verbosity = int(options.get('verbosity', '1'))
-
+
force = options.get('force', False)
-
+
limit = options.get("limit", -1)
start = options.get("start", 0)
-
+
site_url = options.get('site_url', settings.WIKIPEDIA_API_URL)
-
+
types_mask = 0
-
+
if self.verbosity > 2:
print "option passed : " + repr(options)
queryset = WpCategory.objects.filter(tags__hidden = False).distinct()
-
+
cat_list = options.get("category", []);
-
+
if cat_list:
queryset = queryset.filter(label__in=cat_list)
- elif options.get('all',False):
- queryset = queryset.annotate(wpc=Count('child_categories')).filter(wpc = 0)
-
+ elif options.get('all',False):
+ queryset = queryset.annotate(wpc=Count('child_categories')).filter(wpc = 0)
+
queryset = queryset.order_by("label")
-
+
if limit >= 0:
queryset = queryset[start:limit]
elif start > 0:
- queryset = queryset[start:]
-
+ queryset = queryset[start:]
+
if self.verbosity > 2 :
print "Category Query is %s" % (queryset.query)
-
+
site = wiki.Wiki(site_url) #@UndefinedVariable
-
-
+
+
count = queryset.count()
if self.verbosity > 1:
print "Processing %d categories" % (count)
-
+
if not force and interactive:
confirm = raw_input("You have requested to query and replace the wikipedia information for %d categories.\n Are you sure you want to do this? \nType 'yes' to continue, or 'no' to cancel: " % (count))
else:
confirm = 'yes'
-
+
if confirm != "yes":
print "wikipedia query cancelled"
return
-
+
for i, category in enumerate(queryset):
-
+
if self.verbosity > 1:
print "processing category %s (%d/%d)" % (category.label, i + 1, count)
else:
- utils.show_progress(i + 1, count, category.label, 60)
-
+ utils.show_progress(i + 1, count, category.label, 60)
+
title = CATEGORY_PREFIX + category.label
# query categories
with transaction.atomic():
res = self.query_all_categories(title, site)
- self.process_categories(res, category)
\ No newline at end of file
+ self.process_categories(res, category)
--- a/src/hdalab/management/commands/query_dbpedia.py Thu Apr 12 01:27:16 2018 +0200
+++ b/src/hdalab/management/commands/query_dbpedia.py Wed Apr 11 12:19:47 2018 +0200
@@ -1,8 +1,26 @@
# -*- coding: utf-8 -*-
'''
-Created on Jan 30, 2012
+Requête DBPedia pour renseigner les objets :class:`hdabo.models.Tag`.
+Seuls les tags sémantisés sont traités.
+
+Les données suivantes sont moissonnées:
+
+ - label dans toutes les langues disponibles
+ - résumé dans toutes les langues disponibles
+ - thumbnail
+ - lien entre les tags
-@author: ymh
+**Usage**: ``django-admin query_dbpedia [options]``
+
+**Options spécifiques:**
+
+ - *\-\-all* : force à traiter tous les tags
+ - *\-\-random* : faire le traitement des tags dans un ordre aléatoire
+ - *\-\-force* : ne pose aucune question
+ - *\-\-limit=LIMIT* : Nombre de tags à traiter
+ - *\-\-start=START* : Nombre de tags à ignorer
+ - *\-\-tag=TAG* : Limite le traitement à ce tag
+
'''
from hdabo.models import Tag
@@ -32,7 +50,7 @@
'''
options = ''
help = """query and update wikipedia for tag title."""
-
+
option_list = NoArgsCommand.option_list + (
make_option('--all',
action='store_true',
@@ -68,7 +86,7 @@
default=[],
help='the tag to query'),
)
-
+
def query_dbpedia(self, query, fmt='n3'):
url = settings.DBPEDIA_URI_TEMPLATE % ( 'sparql', '' )
params = {
@@ -81,58 +99,58 @@
def handle_noargs(self, **options):
-
+
self.style = no_style()
-
+
self.interactive = options.get('interactive', True)
-
+
self.verbosity = int(options.get('verbosity', '1'))
-
+
self.force = options.get('force', False)
-
+
self.limit = options.get("limit", -1)
self.start = options.get("start", 0)
-
+
self.random = options.get('random', False)
-
+
if self.verbosity > 2:
print "option passed : " + repr(options)
self.tag_list = options.get("tags", []);
queryset = Tag.objects.exclude(dbpedia_uri= None)
-
-
+
+
if self.tag_list:
queryset = queryset.filter(label__in=self.tag_list)
- elif not options.get('all',False):
+ elif not options.get('all',False):
queryset = queryset.annotate(dbfc=Count('dbpedia_fields')).filter(dbfc = 0)
if self.random:
queryset = queryset.order_by("?")
else:
queryset = queryset.order_by("label")
-
+
if self.limit >= 0:
queryset = queryset[self.start:self.limit]
elif self.start > 0:
queryset = queryset[self.start:]
-
+
if self.verbosity > 2 :
print "Tag Query is %s" % (queryset.query)
count = queryset.count()
-
+
if count == 0:
print "No tag to query : exit."
return
-
-
+
+
if not self.force and self.interactive:
confirm = raw_input("You have requested to query and replace the dbpedia information for %d tags.\n Are you sure you want to do this? \nType 'yes' to continue, or 'no' to cancel: " % (count))
else:
confirm = 'yes'
-
+
if confirm != "yes":
print "dbpedia query cancelled"
return
@@ -141,12 +159,12 @@
for i,tag in enumerate(queryset):
writer = show_progress(i+1, count, tag.label, 50, writer)
db.reset_queries()
-
+
#abstract query
#"select ?y
# where {<%s> <http://dbpedia.org/ontology/abstract> ?y}" % (tag.dbpedia_uri)
-
- #rdf_uri = re.sub('\/resource\/', "/data/", tag.dbpedia_uri) + ".n3"
+
+ #rdf_uri = re.sub('\/resource\/', "/data/", tag.dbpedia_uri) + ".n3"
#g = Graph()
try :
abstracts = {}
@@ -157,12 +175,12 @@
for _,_,o in res_abstracts.triples((None, URIRef('http://www.w3.org/2005/sparql-results#value'), None)):
abstracts[o.language] = (unicode(o), True)
logger.debug("Abstracts: %r" % abstracts)
-
+
res_labels = self.query_dbpedia("select distinct ?y where {<%s> <http://www.w3.org/2000/01/rdf-schema#label> ?y}" % (tag.dbpedia_uri), 'n3')
for _,_,o in res_labels.triples((None, URIRef('http://www.w3.org/2005/sparql-results#value'), None)):
labels[o.language] = (unicode(o), True)
logger.debug("Labels: %r" % labels)
-
+
res_thumbnails = self.query_dbpedia("select distinct ?y where {<%s> <http://dbpedia.org/ontology/thumbnail> ?y} limit 1" % (tag.dbpedia_uri), 'n3')
for _,_,o in res_thumbnails.triples((None, URIRef('http://www.w3.org/2005/sparql-results#value'), None)):
thumbnail = unicode(o)
@@ -172,7 +190,7 @@
tagqs = Tag.objects.filter(dbpedia_uri=unicode(o))
if tagqs:
TagLinks.objects.get_or_create(subject=tag, object=tagqs[0])
-
+
ref_label_lang, (ref_label, _) = ('fr',labels['fr']) if 'fr' in labels else ('en',labels['en']) if 'en' in labels else labels.items()[0] if len(labels) > 0 else ('fr',(tag.label, True))
ref_abstract_lang, (ref_abstract, _) = ('fr',abstracts['fr']) if 'fr' in abstracts else ('en',abstracts['en']) if 'en' in abstracts else abstracts.items()[0] if len(abstracts) > 0 else ('fr',(None, 'True'))
@@ -182,7 +200,7 @@
if lang[0] not in abstracts:
abstracts[lang[0]] = (ref_abstract, False)
- dbfield , created = DbpediaFields.objects.get_or_create(tag=tag, defaults={'dbpedia_uri':tag.dbpedia_uri, 'abstract':ref_abstract, 'thumbnail':thumbnail, 'label':ref_label}) #@UndefinedVariable
+ dbfield , created = DbpediaFields.objects.get_or_create(tag=tag, defaults={'dbpedia_uri':tag.dbpedia_uri, 'abstract':ref_abstract, 'thumbnail':thumbnail, 'label':ref_label}) #@UndefinedVariable
if not created:
dbfield.dbpedia_uri = tag.dbpedia_uri
dbfield.abstract = ref_abstract
@@ -198,22 +216,22 @@
if lang in consolidated_trans:
consolidated_trans[lang][1] = abstract
else:
- consolidated_trans[lang] = [(ref_label, lang==ref_label_lang), abstract]
-
+ consolidated_trans[lang] = [(ref_label, lang==ref_label_lang), abstract]
+
for lang, trans in consolidated_trans.iteritems():
label, abstract = tuple(trans)
DbpediaFieldsTranslation.objects.create(master=dbfield, language_code=lang, label=label[0], is_label_translated=label[1], abstract=abstract[0], is_abstract_translated=abstract[1])
-
-
+
+
except Exception as e:
if tag.dbpedia_uri:
print "\nError processing resource %s : %s" %(tag.dbpedia_uri,unicode(e))
else:
print "\nError processing resource %s" % unicode(e)
traceback.print_exception(type(e), e, sys.exc_info()[2])
-
+
-
-
+
+
--- a/src/hdalab/management/commands/query_geo_inclusion.py Thu Apr 12 01:27:16 2018 +0200
+++ b/src/hdalab/management/commands/query_geo_inclusion.py Wed Apr 11 12:19:47 2018 +0200
@@ -1,8 +1,9 @@
# -*- coding: utf-8 -*-
'''
-Created on Feb 22, 2012
+Requête DBPedia afin de déterminer dans quel pays sont les tag de localisation.
-@author: raphv
+**Usage**: ``django-admin query_geo_inclusion [options]``
+
'''
from django.conf import settings
from django.core.management.base import NoArgsCommand
@@ -22,7 +23,7 @@
qs = Tag.objects.filter(category__label="Localisation").exclude(dbpedia_uri = None)
total = qs.count()
-
+
#endpoint = SPARQLWrapper("http://dbpedia.org/sparql")
endpoint = SPARQLWrapper(settings.DBPEDIA_URI_TEMPLATE % ( 'sparql', '' ))
endpoint.setReturnFormat(JSON)
@@ -36,31 +37,31 @@
#resourceprefix = "http://dbpedia.org/resource/"
resourceprefix = settings.DBPEDIA_URI_TEMPLATE % ( 'resource', '' )
identityuri = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
-
+
writer = None
-
+
for i,tag in enumerate(qs):
endpoint.setQuery(sparqltext % (tag.dbpedia_uri, tag.dbpedia_uri))
-
+
results = endpoint.query().convert()['results']['bindings']
-
+
if len(results) == 1: # We don't want places located in multiple countries
-
+
resourceuri = results[0]['resource']['value']
-
+
if re.match(resourceprefix, resourceuri):
countrytxt = re.findall('([^/]+$)', resourceuri)[0]
-
+
country, _ = Country.objects.get_or_create(dbpedia_uri=resourceuri)
GeoInclusion.objects.get_or_create(tag=tag, country=country)
-
+
if resourceuri == identityuri:
countrytxt = '<is a country>'
-
+
country, _ = Country.objects.get_or_create(dbpedia_uri=tag.dbpedia_uri)
GeoInclusion.objects.get_or_create(tag=tag, country=country)
-
+
else:
countrytxt = '<unknown>'
-
- writer = show_progress(i+1, total, '%s => %s'%(tag.label, countrytxt), 50, writer)
\ No newline at end of file
+
+ writer = show_progress(i+1, total, '%s => %s'%(tag.label, countrytxt), 50, writer)
--- a/src/hdalab/management/commands/query_wikipedia_category.py Thu Apr 12 01:27:16 2018 +0200
+++ b/src/hdalab/management/commands/query_wikipedia_category.py Wed Apr 11 12:19:47 2018 +0200
@@ -1,8 +1,32 @@
# -*- coding: utf-8 -*-
'''
-Created on Jun 7, 2011
+Requête Wikipedia qui renseigne les différentes catégories wikipedia pour les tag sémantisés.
+
+Les données suivantes sont moissonée pour chaque tag sémantisé (i.e. article Wikipedia)
+ - catégories visibles (`visible`)
+ - catégories cachées (`hidden`)
+ - paramêtres d'infobox (`infobox`)
+
+Les objets créé sont les suivants:
+
+ - catégories : :class:`hdalab.models.WpCategory` et :class:`hdalab.models.TagWpCategory`
+ - paramêtre d'infobox : :class:`hdalab.models.InfoboxParameter` et :class:`hdalab.models.TagInfobox`
+
+Cette commande utilise directement `l'api wikipedia <https://www.mediawiki.org/wiki/API:Main_page>`_ pour faire ses requêtes.
-@author: ymh
+**Usage**: ``django-admin query_wikipedia_category [options]``
+
+**Options spécifiques:**
+
+ - *\-\-all* : force à traiter tous les tags
+ - *\-\-random* : faire le traitement des tags dans un ordre aléatoire
+ - *\-\-force* : ne pose aucune question
+ - *\-\-limit=LIMIT* : Nombre de tags à traiter
+ - *\-\-start=START* : Nombre de tags à ignorer
+ - *\-\-type=TYPES* : Quel type de requête faire : `visible` : catégories visibles, `hidden` : catégories cachées, `infobox`: infoboxes, `all`: toutes (défaut). cette option peut être passée plusieurs fois.
+ - *\-\-use\-label* : Utilise le label du tag au lieu du pageid pour faire la requête wikipedia
+ - *\-\-tag=TAG* : Limite le traitement à ce tag
+
'''
from django.conf import settings
--- a/src/hdalab/management/commands/send_moderation_mail.py Thu Apr 12 01:27:16 2018 +0200
+++ b/src/hdalab/management/commands/send_moderation_mail.py Wed Apr 11 12:19:47 2018 +0200
@@ -1,8 +1,14 @@
# -*- coding: utf-8 -*-
'''
-Created on Mar 5, 2015
+Envoie un mail récapitulatif des renkan à modérer.
+Aucun mail n'est envoyé si aucune modération n'est demandée.
+
+L'envoi est fait aux utilisateurs marqués comme `staff <https://docs.djangoproject.com/en/1.8/ref/contrib/auth/#django.contrib.auth.models.User.is_staff>`_.
-@author: ymh
+cette commande est typiquement prévue pour être lancée à partir d'une tâche ``cron`` périodique (1 fois par jour par exemple).
+
+**Usage**: ``django-admin send_moderation_mail [options]``
+
'''
import logging
@@ -26,30 +32,30 @@
TEMPLATE_NAME = "mails/moderation_notice"
class Command(NoArgsCommand):
-
+
def handle_noargs(self, **options):
# query renkan to moderate
set_script_prefix(settings.SCRIPT_PREFIX)
-
+
renkan_query = HdalabRenkan.objects.filter(state=HdalabRenkan.MODERATED)
-
+
renkan_count = renkan_query.count()
-
+
if renkan_count == 0:
logger.info("Send moderation email : no renkan to moderate. exiting")
return
logger.debug("Send moderation email : %d renkan(s) to moderate", renkan_count)
-
+
renkan_list = list(renkan_query.select_related()[:20])
-
+
connection = mail.get_connection()
try:
connection.open()
for email_recipient in User.objects.filter(is_staff=True):
if not email_recipient.email:
continue
-
+
msg_html = ""
msg_txt = ""
try:
@@ -67,7 +73,7 @@
except Exception as e:
logger.error("Error rendering template %s : %r", TEMPLATE_NAME, e)
raise e
-
+
if not msg_html and not msg_txt:
logger.info("Send moderation email: nothing to email exiting")
continue
@@ -76,4 +82,3 @@
emsg.send(fail_silently=True)
finally:
connection.close()
-
\ No newline at end of file
--- a/src/hdalab/models/categories.py Thu Apr 12 01:27:16 2018 +0200
+++ b/src/hdalab/models/categories.py Wed Apr 11 12:19:47 2018 +0200
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
'''
Created on Jan 26, 2012
@@ -8,35 +9,66 @@
class WpCategory(models.Model):
+ """
+ Une catégorie Wikipedia.
+
+ :cvar str label: Le label de la catégorie.
+ """
label = models.CharField(max_length=2048, unique=True, blank=False, null=False)
-
+
def __unicode__(self):
return unicode(self.label)
-
+
class Meta:
app_label = 'hdalab'
verbose_name_plural = "WpCategories"
class TagWpCategory(models.Model):
+ """
+ Relie une catégorie Wikipedia à un tag.
+
+ :cvar object tag: Le tag.
+ :cvar object wp_category: La categorie wikipedia.
+ :cvar bool hidden: Indique si la catégorie est cachée ou pas.
+ """
tag = models.ForeignKey(Tag, related_name="wp_categories")
wp_category = models.ForeignKey(WpCategory, related_name="tags")
hidden = models.BooleanField(blank=False, null=False, default=False)
-
+
class Meta:
app_label = 'hdalab'
unique_together = ('tag', 'wp_category', 'hidden')
+
class TagInfobox(models.Model):
+ """
+ Contenu de l'infobox wikipedia pour un tag.
+
+ :cvar object tag: Le tag
+ :cvar str name: Le nom (type) de l'infobox.
+ :cvar str source: Le code source de l'infobox.
+ :cvar int revision_id: Numéro de révision de l'infobox.
+ """
+
tag = models.ForeignKey(Tag, related_name="infoboxes")
name = models.CharField(max_length=2048, unique=False, blank=False, null=False)
source = models.TextField(unique=False, blank=True, null=True)
revision_id = models.BigIntegerField(unique=False, blank=True, null=True)
-
+
class Meta:
app_label = 'hdalab'
unique_together = ('tag','name','revision_id')
-
+
+
class InfoboxParameter(models.Model):
+ """
+ Valeurs de paramêtre d'une infobox Wikipedia.
+
+ :cvar object tag_infobox: L'objet :class:TagInfobox.
+ :cvar str param_name: Nom du paramêtre.
+ :cvar str param_value: Valeur du paramêtre.
+ """
+
tag_infobox = models.ForeignKey(TagInfobox)
param_name = models.CharField(max_length=2048, unique=False, blank=False, null=False)
param_value = models.TextField(unique=False, blank=True, null=True)
@@ -48,9 +80,16 @@
# Added on 02/07/2012
class WpCategoryInclusion(models.Model):
+ """
+ Classe permettant de modéliser l'arbre de catégorie Wikipedia.
+
+ :cvar object parent_category: La catégorie parente.
+ :cvar object child_category: La catégorie enfant.
+ """
+
parent_category = models.ForeignKey(WpCategory, related_name="child_categories")
child_category = models.ForeignKey(WpCategory, related_name="parent_categories")
-
+
class Meta:
app_label = 'hdalab'
- unique_together = ('parent_category','child_category')
\ No newline at end of file
+ unique_together = ('parent_category','child_category')
--- a/src/hdalab/models/dataviz.py Thu Apr 12 01:27:16 2018 +0200
+++ b/src/hdalab/models/dataviz.py Wed Apr 11 12:19:47 2018 +0200
@@ -11,44 +11,80 @@
class TagYears(models.Model):
-
+ """
+ Représente une période (début - fin) associée à un Tag.
+
+ :cvar object tag: Le tag
+ :cvar int start_year: L'année de début de la période.
+ :cvar int end_year: L'année de fin de période.
+ """
tag = models.OneToOneField(Tag, related_name="years", blank=False, null=False, db_index=True)
start_year = models.IntegerField(blank=False, null=False, db_index=True)
end_year = models.IntegerField(blank=False, null=False, db_index=True)
-
+
class Meta:
app_label = 'hdalab'
-
+
class TagLinks(models.Model):
-
+ """
+ Représente un lien entre tag.
+
+ :cvar object subject: Le tag sujet (source) du lien.
+ :cvar object object: Le tag object (cible) du lien.
+ """
+
subject = models.ForeignKey(Tag, blank=False, null=False, db_index=True, related_name="taglinks_subjects")
object = models.ForeignKey(Tag, blank=False, null=False, db_index=True, related_name="taglinks_objects")
-
+
class Meta:
app_label = 'hdalab'
class Country(models.Model):
-
+ """
+ Représente un pays.
+
+ :cvar str dbpedia_uri: L'URI DBPedia de ce pays.
+ """
+
dbpedia_uri = models.URLField(max_length=255, blank=False, null=False, db_index=True, unique=True)
-
+
class Meta:
app_label = 'hdalab'
class GeoInclusion(models.Model):
-
+ """
+ Représente une relation entre un tag et un pays. (par exemple, le tage "Paris" est inclus dans le pays "France")
+ Un tag ne peut être relié qu'a un seul pays.
+
+ :cvar object tag: le tag.
+ :cvar object country: Le pays.
+
+ """
+
tag = models.OneToOneField(Tag, related_name="locatedin", db_index=True)
country = models.ForeignKey(Country, blank=False, null=False, related_name="includes", db_index=True)
-
+
class Meta:
app_label = 'hdalab'
class DbpediaFields(models.Model):
+ """
+ Informations DBPedia pour un tag.
+ Un tag ne peut être lié qu'à une seule instance de cette classe.
+
+ :cvar str dbpedia_uri: L'URI DBPedia.
+ :cvar object tag: Le tag.
+ :cvar str abstract: Texte résumé du tag issu de DBPedia.
+ :cvar str thumbnail: URL d'un thumbnail pour le tag.
+ :cvar str label: Label DBPedia pour le tag.
+
+ """
dbpedia_uri = models.URLField(max_length=2048, blank=False, null=False, db_index=True, unique=False)
tag = fields.OneToOneField(Tag, db_index=True, related_name="dbpedia_fields", related_default=lambda instance: None)
abstract = models.TextField(blank=True, null=True)
- thumbnail = models.URLField(max_length=2048, blank=True, null=True, db_index=False)
+ thumbnail = models.URLField(max_length=2048, blank=True, null=True, db_index=False)
label = models.CharField(max_length=2048, unique=False, blank=True, null=True)
class Meta:
@@ -56,6 +92,16 @@
class DbpediaFieldsTranslation(models.Model):
+ """
+ Les traductions pour un :class:DbpediaField.
+
+ :cvar object master: Le DBPediafield
+ :cvar str language_code: Le code de la langue de la traduction.
+ :cvar str label: Le label traduit. Attention si une traduction du label n'a pas été trouvée, on trouvera là le même label que dans "master".
+ :cvar str abstract: Le résumé traduit. Attention si une traduction du résumé n'a pas été trouvée, on trouvera là le même label que dans "master".
+ :cvar bool is_label_translated: Indique si le label est effectivement traduit.
+ :cvar bool is_abstract_translated: Indicque si le résumé est effectivement traduit.
+ """
master = models.ForeignKey(DbpediaFields, blank=False, null=False, db_index=True, related_name="translations")
language_code = models.CharField(max_length=15, blank=False, null=False, db_index=True)
@@ -69,27 +115,45 @@
class HdaSession(models.Model):
-
+ """
+ Classe destinée à sauvagarder des session d'exploration sur HDALab (état de l'interface de recherche par facette).
+ Cet objet n'est pas utilisé.
+ """
+
sessionid = models.CharField(max_length=36, unique=True, blank=False, null=False, db_index=True)
data = models.TextField(blank=True, null=True)
-
+
class Meta:
app_label = 'hdalab'
class InseeCoords(models.Model):
-
+ """
+ Coordonnées géographiques et nom de l'entité pour un code INSEE.
+
+ :cvar integer insee: code insee.
+ :cvar str city_name: Nom de la commune.
+ :cvar float latitude: Latitude.
+ :cvar float longitude: Longitude.
+ """
+
insee = models.IntegerField(primary_key=True)
city_name = models.CharField(max_length=255, blank=False, null=False)
latitude = models.FloatField(blank=False, null=False)
longitude = models.FloatField(blank=False, null=False)
-
+
class Meta:
app_label = 'hdalab'
class DatasheetExtras(models.Model):
-
+ """
+ Information supplémentaire pour und fiche hda.
+
+ :cvar object datasheet: La fiche HDA.
+ :cvar object insee: Les information insee (:class:InseeCoords) pour la fiche.
+ """
+
datasheet = models.OneToOneField(Datasheet, related_name="extras", db_index=True)
insee = models.ForeignKey(InseeCoords, blank=True, null=True, db_index=True)
-
+
class Meta:
- app_label = 'hdalab'
\ No newline at end of file
+ app_label = 'hdalab'
--- a/src/hdalab/models/renkan.py Thu Apr 12 01:27:16 2018 +0200
+++ b/src/hdalab/models/renkan.py Wed Apr 11 12:19:47 2018 +0200
@@ -15,35 +15,54 @@
logger = logging.getLogger(__name__)
class HdalabRenkan(models.Model):
-
+ """
+ Classe representant un Renkan HDALab.
+ Est utilisée pour ajouter au projet renkan des informations sur l'état d'édition ou bien si il est marqué comme favori.
+
+ :cvar object renkan: Le renkan lui même.
+ :cvar int state: État du renkan (1: en édition, 2: en modération, 3: publié, 4: rejeté).
+ :cvar bool favorite: Le renkan est marqué comme favori ou pas.
+ """
+
EDITION = 1
MODERATED = 2
PUBLISHED = 3
REJECTED = 4
-
+
STATE_CHOICES = (
(EDITION, 'edition'),
(MODERATED, 'moderated'),
(PUBLISHED, 'published'),
(REJECTED, 'rejected'),
)
-
+
STATE_CHOICES_DICT = {
EDITION: _('edition_state'),
MODERATED: _('moderated_state'),
PUBLISHED: _('published_state'),
REJECTED: _('rejected_state')
}
-
+
renkan = models.ForeignKey(Renkan, blank=False, null=False)
state = models.IntegerField(choices=STATE_CHOICES, default=1)
favorite = models.BooleanField(null=False, blank=False, default=False)
-
+
class Meta:
app_label = 'hdalab'
class HdalabRenkanStateTransition(models.Model):
+ """
+ Modélise un changement de statut du renkan.
+ Permet de garder l'historique des changements de statut.
+
+ :cvar object renkan: Le renkan.
+ :cvar int from_state: le statut initial.
+ :cvar int to_state: le statut final.
+ :cvar datetime ts: date/heure du changement.
+ :cvar str message: Message (optionel) associé au changement de statut.
+ :cvar object author: Utilisateur ayant initié le changement de statut.
+ """
renkan = models.ForeignKey(HdalabRenkan, blank=False, null=False, related_name='states')
from_state = models.IntegerField(choices=HdalabRenkan.STATE_CHOICES, default=1, blank=False, null=False)
@@ -51,7 +70,7 @@
ts = models.DateTimeField(auto_now_add=True, blank=False, null=False)
message = models.TextField(blank=True, null=True)
author = models.ForeignKey(settings.AUTH_USER_MODEL, blank=False, null=False)
-
+
class Meta:
app_label = 'hdalab'
ordering = ["-ts"]
--- a/src/hdalab/services.py Thu Apr 12 01:27:16 2018 +0200
+++ b/src/hdalab/services.py Wed Apr 11 12:19:47 2018 +0200
@@ -23,6 +23,14 @@
@transaction.atomic
def change_renkan_state(hda_renkan, state, message=None, author=None):
+ """
+ Change l'état d'un renkan et crée un objet :class:`hdalab.models.HdalabRenkanStateTransition` dans une transaction unique.
+
+ :param:hda_renkan: L'objet :class:`hdalab.models.HdaRenkan`.
+ :param:state: L'état cible.
+ :param:message: Le message de changement d'état.
+ :param:author: L'utilisateur (:class:`hdabo.models.User`).
+ """
if state != hda_renkan.state:
@@ -32,6 +40,13 @@
def renkan_capture_preview(hdalab_renkan):
+ """
+ Lance la création d'une miniature pour un renkan.
+ Ceci est fait en ouvrant l'url `renkan_full` (:ref:`affichage-d-un-renkan-en-plein-ecran`) avec PhantomJS, et en déclenchant une capture "d'écran".
+
+ :param:hdalab_renkan: Une instance de :class:`hdalab.models.renkan.HdalabRenkan`.
+
+ """
#get last state date or last modification date
#states are ordered by ts
folder_date = hdalab_renkan.renkan.modification_date
--- a/src/hdalab/signals.py Thu Apr 12 01:27:16 2018 +0200
+++ b/src/hdalab/signals.py Wed Apr 11 12:19:47 2018 +0200
@@ -21,8 +21,8 @@
logger = logging.getLogger(__name__)
MAIL_TEMPLATES = {
- (HdalabRenkan.MODERATED,HdalabRenkan.PUBLISHED): ("mails/published_renkan", "Renkan publié"),
- (HdalabRenkan.MODERATED,HdalabRenkan.REJECTED): ("mails/rejected_renkan", "Renkan rejeté"),
+ (HdalabRenkan.MODERATED, HdalabRenkan.PUBLISHED): ("mails/published_renkan", "Renkan publié"),
+ (HdalabRenkan.MODERATED, HdalabRenkan.REJECTED): ("mails/rejected_renkan", "Renkan rejeté"),
(HdalabRenkan.PUBLISHED, HdalabRenkan.EDITION): ("mails/unpublished_renkan", "Renkan dépublié"),
(HdalabRenkan.PUBLISHED, HdalabRenkan.REJECTED): ("mails/rejected_renkan", "Renkan rejeté"),
}
@@ -30,6 +30,15 @@
#TODO put into queue
def send_renkan_moderation_messages(sender, **kwargs):
+ """
+ Envoie un email suite au changement de status d'un renkan.
+ Le template à utiliser pour l'email est donné par la constante `MAIL_TEMPLATES` et est fonction du statut de dépard et du status d'arrivé.
+ Si aucun template est trouvé, aucun mail n'est envoyé.
+
+ :param:instance: l'objet :class:`hdalab.models.renkan.HdalabRenkanStateTransition` venant d'être créé.
+
+ """
+
renkan_state = kwargs.get('instance', None)
if not renkan_state or (renkan_state.from_state,renkan_state.to_state) not in MAIL_TEMPLATES:
return
@@ -51,7 +60,7 @@
# logger.error("Error rendering template %s for state %s : %r", MAIL_TEMPLATES[template_key], HdalabRenkan.STATE_CHOICES_DICT[renkan_state.to_state], e)
# return
# raise e
-
+
if msg_txt and msg_html and renkan_state.renkan and renkan_state.renkan.renkan and renkan_state.renkan.renkan.owner and renkan_state.renkan.renkan.owner.email:
logger.debug("Sending following mail to %s : %s", renkan_state.renkan.renkan.owner.email, msg_txt)
emsg = EmailMultiAlternatives(subject, msg_txt, settings.DEFAULT_FROM_EMAIL, [renkan_state.renkan.renkan.owner.email])
@@ -60,10 +69,17 @@
def queue_renkan_rendering(sender, **kwargs):
+ """
+ Gère le calcul et l'effacement de la miniature d'un renkan en fonction de sont statut.
+ - Si un renkan était publié et change d'état, la miniature est effacée.
+ - Si un renkan devient publié, une demande de calcul de miniature est mise en file d'attente (c.f. :func:`hdalab.tasks.capture_preview`).
+
+ :param:instance: l'objet :class:`hdalab.models.renkan.HdalabRenkanStateTransition` venant d'être créé.
+ """
renkan_state = kwargs.get('instance', None)
if not renkan_state:
return
-
+
if renkan_state.from_state == HdalabRenkan.PUBLISHED and renkan_state.renkan.renkan.image != settings.DEFAULT_RENKAN_ICON:
if renkan_state.renkan.renkan.image:
renkan_state.renkan.renkan.image.delete(False)
@@ -75,13 +91,19 @@
capture_preview.delay(renkan_state.renkan.renkan.rk_id) # @UndefinedVariable
def renkan_delete_image(sender, **kwargs):
+ """
+ Efface la miniature d'un renkan si celui-ci est effacé.
+
+ :param:instance: l'objet :class:`renkanmanager.models.Renkan` qui va être effacé.
+
+ """
renkan = kwargs.get('instance', None)
if not renkan or not renkan.image or renkan.image == settings.DEFAULT_RENKAN_ICON:
return
renkan.image.delete(False)
renkan.image.delete_thumbnails()
-
+
RENKAN_MODERATION_UUID = "e2f84503-609b-4efa-819d-908e2efe7b1b"
RENKAN_RENDERING_UUID = "b8830748-be2b-479a-8aef-c8d952437b2f"
RENKAN_DELETE_UUID = "09c23ca2-4d59-4c29-b94a-2c2672d5a89b"
--- a/src/hdalab/views/__init__.py Thu Apr 12 01:27:16 2018 +0200
+++ b/src/hdalab/views/__init__.py Wed Apr 11 12:19:47 2018 +0200
@@ -1,4 +1,7 @@
+"""
+HDALab views.
+"""
import logging
import sys
@@ -15,4 +18,4 @@
import traceback
logger.error("server_error %s : %s", sys.exc_info()[0], traceback.format_exc())
response.status_code = 500
- return response
\ No newline at end of file
+ return response
--- a/src/hdalab/views/ajax.py Thu Apr 12 01:27:16 2018 +0200
+++ b/src/hdalab/views/ajax.py Wed Apr 11 12:19:47 2018 +0200
@@ -23,6 +23,23 @@
logger = logging.getLogger(__name__)
def tagtranslation(request):
+ """
+ Vue donnant des traductions de label de tag pour une langue.
+ la recherche se fait dans les objets :class:`hdalab.models.DbpediaFieldsTranslation`.
+
+ Paramêtres GET:
+ :var lang: La langue demandée
+ :var labels: Un ou plusieurs labels de tag (séparateur : ",")
+
+ Réponse (application/json):
+ Un dictionnaire sous la forme ::
+
+ {
+ "<label1>": "<translation>",
+ "<label2>": "<translation>"
+ }
+
+ """
lang = request.GET.get('lang',request.LANGUAGE_CODE)
labels = request.GET.get('labels',None)
@@ -46,7 +63,19 @@
return HttpResponse(content=json.dumps(translations), content_type='application/json')
-def subcat(category, globtags, level, max_level ):
+
+
+def subcat(category, globtags, level, max_level):
+ """
+ Méthode récursive utilisée pour reconstruire un arbre de catégories.
+
+ :param object category: La catégorie racine.
+ :param dict globtags: dictionnaire flobal des tags.
+ :param int level: Niveau de récursion.
+ :param int max_level: Niveau maximum de récursion (level <= max_level)
+
+ :returns: L'arbre des catégories.
+ """
# recursive function used by cattree
catlabel = category.label
tags = Tag.objects.filter(wp_categories__wp_category = category).distinct()
@@ -70,6 +99,15 @@
return resobj
def cleantags(category):
+ """
+ Methode annexe qui nettoie recursivement un arbre de catégorie. elle effectue les actions suivantes:
+ - retire les clefs correspondant à des listes vides ('contents' et 'themes')
+ - trie les listes 'themes' par label
+ - trie les listes 'contents' par score
+
+ :param category: la catégorie racine où commencer le traitement.
+
+ """
if category.has_key('contents') and len(category['contents']) == 0:
del category['contents']
if category.has_key('contents'):
@@ -86,6 +124,37 @@
return category
def cattree(request):
+ """
+ Contruit l'arbre de catégorie pour un label.
+ Les contenus attachés aux noeud sont des listes de fiches hdalab triées par score.
+ Le score pour une fiche est fonction de ses tags, de leur ordre, de leur présence dnas l'arbre des catégories et de leur hauteur dans l'arbre des catégories.
+
+ Paramêtres GET :
+ :var label: Le label
+
+ Réponse (application/json):
+ Un json représentant l'arbre des catégories avec pour chaque noeud une liste ordonnée de fiches liée à la catégorie.
+
+ exemple ::
+
+ {
+ "label": "<label1>",
+ "themes": [ { "label": "<label1.1>", "themes": [...], "contents": [...]}, ...],
+ "contents": [
+ {
+ "organization": "Ciclic",
+ "description": "Ciclic propose...",
+ "score": 7,
+ "title": "Vocabulaire de l'analyse filmique...",
+ "url": "http://upopi.ciclic.fr/vocabulaire/definition/sceance-11",
+ "hda_id": "5879",
+ "organization_url": "http://www.ciclic.fr/",
+ "id": 14852
+ },
+ ...
+ ]
+ }
+ """
# Gets the category tree from a label
ROOT_MAX_TAG_ORDER = 8
MAX_TAG_ORDER = 8
@@ -146,7 +215,12 @@
return HttpResponse(content=json.dumps(resobj), content_type='application/json')
+
def sessioninfo(request):
+ """
+ Vue gérant les session Hda permettant de sauvegarder un état d'interface.
+ Note : Cette vue n'est pas mappée dans le module `hdalab.url`.
+ """
data = json.loads(request.GET.get('data', "{}"))
write = False
@@ -188,6 +262,41 @@
def tagsearch(request):
+ """
+ Vue permettant la recherche dans les tag.
+ La recherche se fait dans les objets :class:`hdabo.models.Tag`, :class:`hdalab.models.DbpediaFields` et :class:`hdalab.models.DbpediaFieldsTranslation`.
+
+ Paramêtres GET:
+ :var (str) term: Le terme à rechercher.
+ :var (str) lang: La langue dans laquelle il faut faire la recherche.
+ :var (int) count: Le nombre maximum de résultat.
+ :var (bool) count_notices: Ajoute ou pas le nombre de notices par tag.
+
+ Réponse (application/json):
+ Une liste comprenant les résultats de la recherche.
+
+ exemple ::
+
+ [
+ {
+ "original_label": "Cathédrale Notre-Dame de Chartres",
+ "url": "http://fr.wikipedia.org/wiki/Cath%C3%A9drale_Notre-Dame_de_Chartres",
+ "abstract": "La cathédrale Notre-Dame de Chartres ...",
+ "value": "Cathédrale Notre-Dame de Chartres",
+ "thumbnail": "http://commons.wikimedia.org/wiki/Special:FilePath/Chartres_Cath+Gare.JPG?width=300",
+ "nb": 7
+ },
+ {
+ "original_label": "Cathédrale Notre-Dame de Paris",
+ "url": "http://fr.wikipedia.org/wiki/Cath%C3%A9drale_Notre-Dame_de_Paris",
+ "abstract": "La cathédrale Notre-Dame de Paris...",
+ "value": "Cathédrale Notre-Dame de Paris",
+ "thumbnail": "http://commons.wikimedia.org/wiki/Special:FilePath/Notre_Dame_de_Paris_DSC_0846w.jpg?width=300",
+ "nb": 6
+ },
+ ...
+ ]
+ """
q = request.GET.get('term',None)
maxcount = int(request.GET.get('count','40'))
@@ -252,7 +361,29 @@
return HttpResponse(content=json.dumps(res), content_type='application/json')
+
+
def catsearch(request):
+ """
+ Vue permettant la recherche de catégorie. On se restreint aux catégories qui sont aussi des tags.
+
+ Paramêtres GET:
+ :var (str) term: Le terme à rechercher.
+
+ Réponse (application/json):
+ Une liste comprenant le résultat de la recherche.
+
+ exemple ::
+
+ [
+ { "value": "1982 au cinéma" },
+ { "value": "Cinéma italien" },
+ { "value": "2003 au cinéma" },
+ ...
+ ]
+
+ """
+
q = request.GET.get('term',None)
@@ -268,7 +399,27 @@
return HttpResponse(content=json.dumps(res), content_type='application/json')
+
+
def filter(request):
+ """
+ Vue permettant de filtrer par facette des fiches HDA.
+ Cette méthode est en fait un simple wrapper pour la méthode `filter_generic`.
+
+ Paramêtres GET:
+ :var lang: la langue de recherche (défaut: fr-fr).
+ :var period: Période dans laquelle doit se faire la recherche.
+ :var label: un mot-clef.
+ :var country: Une liste de pays limitant la recherche.
+ :var contentlist: Liste de fiches limitant la recherche.
+ :var mto: Ordre maximum des tags (défaut: 12).
+ :var contentcount: nombre de fiches maximum (défaut : 8).
+ :var tagcount: nombre maximum de tag (défaut: 30).
+
+ Réponse (application/json):
+ Un objet comprenant le résultat de la recherche.
+ """
+
lang = request.GET.get('lang',request.LANGUAGE_CODE)
periode = request.GET.get('period',None)
@@ -285,6 +436,128 @@
def filter_generic(lang="fr-fr", periode=None, label=None, country=None, contentlist=None, max_tag_order=12, content_count=8, tag_count=30):
+ """
+ Méthode de recherche par facette sur les fiches HDA.
+
+ :param str lang: La langue de recherche (défaut: "fr-fr").
+ :param str period: Période d'année limitant la recherche. Le format est `<année-début>,<année-fin>` (défaut: None).
+ :param str label: Limite la recherche à un label de tag (défaut: None).
+ :param str country: Liste de pays où limiter la recherche. Le format est `<uri dbpedia pays 1>,<uri dbpedia pays 2>...` (défaut: None).
+ :param str contentlist: Liste d'id de fiche HDA (:class:`hdabo.models.Datasheet`) limitant la recherche. Le format est `<id1>,<id2>...` (défaut: None)
+ :param int max_tag_order: Limite le nombre maximum de tag par fiche (défaut: 12).
+ :param int content_count: Limite le nombre de fiches résultat (défaut: 8).
+ :param int tag_count: Limite le nombre de tag dans le résultat (défaut: 30).
+ :rtype: string
+ :returns: Un objet json sérialisé comprenant les résultats de la recherche pour les différentes facettes.
+
+
+ Clefs de l'objet:
+ - :count: Nombre total de fiches.
+ - :disciplines: Liste de disciplines artistiques en relation avec les reesultats, triée par score.
+ - :countries: Objet dont les clef sont des uri dbpedia de pays et les valeurs sont le nombre de fiches.
+ - :tags: Liste de tag triés par score.
+ - :sparkline: Liste d'année avec un score, triés par année. Le score est lié au nombre de fiche dont le contenu couvre l'année en question.
+ - :contents: Liste de fiches HDA répondant à la recherche, classée par score. Chaque fiche comporte une liste de tag.
+ - :tagtranslations: Objet donnant les traductions de label de tag rencontrés dans les résultats.
+
+ exemple::
+
+ {
+ "count": 936,
+ "disciplines": [
+ {
+ "translated_label": "Peinture",
+ "score": 936,
+ "label": "Peinture"
+ },
+ {
+ "translated_label": "Sculpture",
+ "score": 88,
+ "label": "Sculpture"
+ },
+ ...
+ ],
+ "countries": {
+ "http://fr.dbpedia.org/resource/Iran": 1,
+ "http://fr.dbpedia.org/resource/Espagne": 16,
+ ...
+ },
+ "tags": [
+ {
+ "url": "http://fr.dbpedia.org/resource/Portrait",
+ "id": 63452,
+ "translated_label": "Portrait",
+ "score": 179,
+ "wkpd_url": "http://fr.wikipedia.org/wiki/Portrait",
+ "label": "Portrait",
+ "thumbnail": "http://commons.wikimedia.org/wiki/Special:FilePath/Fayum02.jpg?width=300"
+ },
+ ...
+ ],
+ "sparkline": [
+ {
+ "score": 2,
+ "year": -600
+ },
+ {
+ "score": 4,
+ "year": -500
+ },
+ ...
+ {
+ "score": 18,
+ "year": 2001
+ }
+ ],
+ "contents": [
+ {
+ "description": "Le palais Fesch, ...",
+ "title": "Histoires bibliques",
+ "url": "http://www.musee-fesch.com/index.php/musee_fesch/content/view/ef_catalogue_sommaire/1513/%28node_id_theme%29/33459",
+ "tags": [
+ {
+ "url": "http://fr.dbpedia.org/resource/Peinture",
+ "id": 54648,
+ "translated_label": "Peinture",
+ "wkpd_url": "http://fr.wikipedia.org/wiki/Peinture",
+ "label": "Peinture",
+ "order": 1,
+ "match": true
+ },
+ ...
+ ],
+ "score": 23,
+ "coords": {
+ "city_name": "Ajaccio",
+ "latitude": 41.916667,
+ "longitude": 8.733333
+ },
+ "hda_id": "4448",
+ "id": 13855
+ },
+ {
+ "description": "...",
+ "title": "Le XIXe siècle",
+ "url": "http://www.grandpalais.fr/fr/article/le-xixe-siecle",
+ "tags": [ ... ],
+ "score": 22,
+ "hda_id": "5217",
+ "id": 13582
+ },
+ ...
+ ],
+ "tagtranslations": {
+ "Paul Cézanne": "Paul Cézanne",
+ "Politique": "Politique",
+ "Poésie": "Poésie",
+ "Religion": "Religion",
+ "Empereur": "Empereur",
+ "Saint": "Saint",
+ ...
+ }
+ }
+
+ """
no_translate_langs = [ 'fr' ]
@@ -474,6 +747,66 @@
def subtree(tree):
+ """
+ Methode récursive permettant de remplir un arbre ce catégories avec les fiches HDA correspondantes.
+
+ :param tree: L'arbre de catégorie
+
+ :returns:Un arbre de catégorie rempli de fiches HDA.
+
+ format du paramêtre `tree` ::
+
+ {
+ "label": "secteur urbain",
+ "contents": [
+ { "label": "banlieue",
+ "contents": [
+ { "label": "faubourg" }
+ ] },
+ { "label": "îlot" },
+ ...
+ ]
+ }
+
+ Exemple de retour ::
+
+
+ {
+ "label": "secteur urbain",
+ "contents": [
+ {
+ "score": 6,
+ "organization": "Institut national de l'audiovisuel ( INA )",
+ "description": "Pour faire face à la ...",
+ "title": "La construction des grands ensembles de banlieue : l'exemple de Sarcelles",
+ "url": "http://fresques.ina.fr/jalons/fiche-media/InaEdu01075/la-construction-des-grands-ensembles-de-banlieue--l-exemple-de-sarcelles",
+ "hda_id": "2090",
+ "organization_url": "http://www.ina.fr",
+ "id": 12360
+ },
+ {
+ "score": 6,
+ "organization": "Maison de banlieue et d'architecture",
+ "description": "La Maison de banlieue et d'architecture...",
+ "title": "Des ensembles assez grands. Mémoire et projets en Essonne",
+ "url": "http://maisondebanlieue.fr/wp-content/uploads/2011/05/Cahier11_grands_ensembles.pdf",
+ "hda_id": "5893",
+ "organization_url": "http://www.maisondebanlieue.fr/",
+ "id": 14821
+ },
+ ...
+ ]
+ "themes": [
+ {
+ "label": "faubourg",
+ "content": [...],
+ "themes": [...]
+ },
+ ...
+ ]
+ }
+
+ """
MAX_TAG_ORDER = 16
label = tree['label']
sub = tree.get('contents',[])
@@ -497,6 +830,31 @@
return res
def filltree(request):
+ """
+ Vue permettant d'ajouter des fiches à un arbre de catégories.
+ Cette méthode est en fait un simple wrapper pour la méthode :meth:`subtree`.
+
+ Paramêtres GET:
+ :var tree: Serialisation json d'un arbre de catégories à remplir. exemple:
+
+ ::
+
+ {
+ "label": "secteur urbain",
+ "contents": [
+ { "label": "banlieue",
+ "contents": [
+ { "label": "faubourg" }
+ ] },
+ { "label": "îlot" },
+ ...
+ ]
+ }
+
+ Réponse (application/json):
+ L'arbre de catégories remplis de fiches HDA (c.f. retour methode :meth:`subtree`)
+
+ """
tree = request.GET.get('tree','{}')
--- a/src/hdalab/views/pages.py Thu Apr 12 01:27:16 2018 +0200
+++ b/src/hdalab/views/pages.py Wed Apr 11 12:19:47 2018 +0200
@@ -13,6 +13,10 @@
def datasheet(request, hda_id=None):
+ """
+ Methode Vue affichant le détail d'une fiche HDA.
+ Cette vue affiche en fait un résumé de la notice mise en relation avec les notices liées, via les mots clefs.
+ """
MAX_TAG = 15
MAX_RELATED = 50
@@ -70,6 +74,10 @@
class HdalabAboutPage(TemplateView):
+ """
+ Classe de vue en charge de l'affichage de la page à propos.
+ C'est une simple django.views.generic.TemplateView qui ajoute quelques informations dans le contexte de rendu du template.
+ """
template_name = "a_propos.html"
--- a/src/hdalab/views/profile.py Thu Apr 12 01:27:16 2018 +0200
+++ b/src/hdalab/views/profile.py Wed Apr 11 12:19:47 2018 +0200
@@ -5,24 +5,23 @@
@author: tc
'''
-from datetime import datetime
import json
import logging
-from renkanmanager.views import RenkanGetPut
import uuid
+from datetime import datetime
from django.conf import settings
-from django.contrib.auth import REDIRECT_FIELD_NAME, login as auth_login
+from django.contrib.auth import login as auth_login
+from django.contrib.auth import REDIRECT_FIELD_NAME
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.sites.models import get_current_site
-from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
+from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
from django.core.urlresolvers import reverse
from django.db.models import Q
-from django.http import HttpResponse, HttpResponseBadRequest
-from django.http import HttpResponseRedirect
+from django.http import (HttpResponse, HttpResponseBadRequest,
+ HttpResponseRedirect)
from django.http.response import Http404
-from django.shortcuts import get_object_or_404, redirect
-from django.shortcuts import resolve_url
+from django.shortcuts import get_object_or_404, redirect, resolve_url
from django.template.response import TemplateResponse
from django.templatetags.static import static
from django.utils.http import is_safe_url
@@ -32,22 +31,61 @@
from django.views.decorators.debug import sensitive_post_parameters
from django.views.generic import TemplateView, View
from django.views.generic.edit import UpdateView
-from renkanmanager.models import Renkan
-from renkanmanager.utils import LineNodePlacer, HorLineNodePlacer, renkan_copier, renkan_deleter, \
- CircleNodePlacer
-
-from hdabo.models import Tag, Datasheet, TaggedSheet, Folder
-from hdalab.forms import HdalabRenkanStateForm, HdalabRenkanFavoriteForm
+from hdabo.models import Datasheet, Folder, Tag, TaggedSheet
+from hdalab.forms import HdalabRenkanFavoriteForm, HdalabRenkanStateForm
from hdalab.models.dataviz import DbpediaFieldsTranslation
from hdalab.models.renkan import HdalabRenkan
from hdalab.services import change_renkan_state
from hdalab.views.ajax import filter_generic
-
+from renkanmanager.models import Renkan
+from renkanmanager.utils import (CircleNodePlacer, HorLineNodePlacer,
+ LineNodePlacer, renkan_copier, renkan_deleter)
+from renkanmanager.views import RenkanGetPut
logger = logging.getLogger(__name__)
class BaseRenkanList(TemplateView):
+ """
+ Classe de vue permettant la gestion de l'affichage d'une liste de Renkan.
+ Cette classe fourni une méthode gérant les filtres, le tri et la pagination.
+ Cette classe de vue n'est pas directement utilisée mais est dérivé par des classe de vue concrêtes.
+
+ Liste des paramêtres GET:
+
+ +-----------+------------------------------------------------------------+--------+--------+
+ | nom | description | type | défaut |
+ +===========+============================================================+========+========+
+ | title | Le titre du renkan contient la chaine de caractères. | chaine | vide |
+ +-----------+------------------------------------------------------------+--------+--------+
+ | username | Le nom de l'utilisateur ayant créé le renkan. | chaine | vide |
+ +-----------+------------------------------------------------------------+--------+--------+
+ | state | Le status du renkan est (c.f. _models/renkan/HdalabRenkan) | entier | (*) |
+ +-----------+------------------------------------------------------------+--------+--------+
+ | startdate | La date de modification du renkan est supérieure à. | epoch | vide |
+ +-----------+------------------------------------------------------------+--------+--------+
+ | enddate | La date de modification du renkan est inférieure à. | epoch | vide |
+ +-----------+------------------------------------------------------------+--------+--------+
+ | favorite | Le renkan est marqué comme favori ou non (0 ou 1) | 0/1 | (*) |
+ +-----------+------------------------------------------------------------+--------+--------+
+ | sort | Champ sur lequel se fait le tri: | chaine | date |
+ | | - date : date de modification du renkan | /énum. | |
+ | | - title : titre du renkan | | |
+ | | - state : status du renkan (c.f _) | | |
+ | | - user : créateur du renkan | | |
+ | | - favorite : renkan marqué comme avori | | |
+ +-----------+------------------------------------------------------------+--------+--------+
+ | order | ordre de tri : | chaine | desc |
+ | | - desc : tri descendant | /énum. | |
+ | | - asc : tris ascendant | | |
+ +-----------+------------------------------------------------------------+--------+--------+
+ | page | Le numéro de page pour la pagination | entier | 1 |
+ | | La première page est la page 1. | | |
+ +-----------+------------------------------------------------------------+--------+--------+
+
+ (*) : La valeur par défaut de ce paramètre dépend de la vue concrète.
+
+ """
default_sort_field = "date"
default_sort_order = "desc"
@@ -115,6 +153,11 @@
class ProfileHome(BaseRenkanList):
+ """
+ Page de profile d'un utilisateur.
+
+ Cette vue étend la vue de base :class:`.BaseRenkanList`.
+ """
template_name = "profile_home.html"
@@ -123,6 +166,14 @@
class RenkanPublicList(BaseRenkanList):
+ """
+ Page des renkan publics.
+
+ La colonne de l'auteur du renkan n'est affiché que si l'utilisateur est membre de l'équipe.
+ Cette list ne comprend pas les renkan marqués commme favoris. Le paramêtre "favorite" est ignoré.
+
+ Cette vue étend la vue de base :class:`.BaseRenkanList`.
+ """
template_name = "renkan_list.html"
@@ -142,6 +193,13 @@
class RenkanFavoriteList(BaseRenkanList):
+ """
+ Page des renkan favoris. Affiche uniquement les renkan marqués comme favoris. Cela implique que le paramêtre "favorite" est ignoré par cette vue.
+
+ La colonne de l'auteur du renkan n'est affiché que si l'utilisateur est membre de l'équipe.
+
+ Cette vue étend la vue de base :class:`.BaseRenkanList`.
+ """
template_name = "renkan_list_favorite.html"
@@ -160,6 +218,10 @@
class RenkanNew(TemplateView):
+ """
+ Page permettant la création de nouveau Renkan vide.
+ Une fois le renkan est créé (POST), l'utilisateur est redirigé vers la page d'édition de Renkan
+ """
template_name="renkan_new_confirm.html"
@@ -180,6 +242,23 @@
class RenkanEdit(TemplateView):
+ """
+ Page permettant l'édition de Renkan.
+ Le principal rôle de cette page est d'afficher l'éditeur de Renkan.
+
+ Paramêtres GET pris en compte par cette page:
+
+ +-----------+------------------------------------------------------------+--------+--------+
+ | nom | description | type | défaut |
+ +===========+============================================================+========+========+
+ | rk_id | Identifiant d'un renan à éditer. | chaine | vide |
+ +-----------+------------------------------------------------------------+--------+--------+
+ | shape | Forme du renkan généré | chaine | circle |
+ | | Ce paramêmtre n'a pas d'effet si le renkan existe déjà | | |
+ | | (utilisation de rk_id) ou bien si il a été sauvegardé. | | |
+ +-----------+------------------------------------------------------------+--------+--------+
+
+ """
template_name="renkan_edit.html"
@@ -219,12 +298,59 @@
class HdalabRenkanGetPut(RenkanGetPut):
+ """
+ Vue permettant la gestion de la création, de l'édition et de la sauvegarde d'un renkan.
+ """
@csrf_exempt
def dispatch(self, *args, **kwargs):
return super(HdalabRenkanGetPut, self).dispatch(*args, **kwargs)
def get(self, request):
+ """
+ Méthode qui fournit un renkan au client d'édition. Son origine est fonction des paramêtres fournit.
+
+ Si le paramêtre `rk_id` est fourni, la source du renkan est le contenu d'un objet existant.
+ Sinon, le renkan est créé à partir des paramêtres fournis.
+
+ Liste des paramêtres de requête:
+
+ +-------------+------------------------------------------------------------+--------+--------+
+ | nom | description | type | défaut |
+ +=============+============================================================+========+========+
+ | rk_id | Identifiant d'un renan à éditer. | chaine | vide |
+ +-------------+------------------------------------------------------------+--------+--------+
+ | shape | Forme du renkan généré (circle, vert, hor) | chaine | circle |
+ | | Ce paramêmtre n'a pas d'effet si le renkan existe déjà | | |
+ | | (utilisation de rk_id) ou bien si il a été sauvegardé. | | |
+ +-------------+------------------------------------------------------------+--------+--------+
+ | lang | La langue de l'utilisateur. par défaut c'est la langue de | chaine | vide |
+ | | la requête. | | |
+ +-------------+------------------------------------------------------------+--------+--------+
+ | notice | Un identifiant de notice HDA. Si ce paramêtre est fourni, | chaine | vide |
+ | | le renkan est généré à partir des tags et notices liées. | | |
+ | | Le centre du renkan est la notice fournie. | | |
+ +-------------+------------------------------------------------------------+--------+--------+
+ | folder | Identifiant d'un dossier de ressource HDA. Si ce paramêtre | chaine | vide |
+ | | est fourni, le renkan est généré à partir des notices | | |
+ | | contenues dans le dossier, ainsi que les tags liés. | | |
+ +-------------+------------------------------------------------------------+--------+--------+
+ | label (*) | Une liste de labels de mots clef, séparés par `,` | chaine | vide |
+ +-------------+------------------------------------------------------------+--------+--------+
+ | country (*) | Une liste d'identifiants de pays, séparés par `,`. Un | chaine | vide |
+ | | identifiant de pays est sont URI DBPedia. | | |
+ +-------------+------------------------------------------------------------+--------+--------+
+ | period (*) | Période de recherche. | chaine | vide |
+ | | Le format est `<année-début>,<année-fin>`. | | |
+ +-------------+------------------------------------------------------------+--------+--------+
+
+
+ (*) Si les paramêtres `label`, `country`, 'period` sont fournis, ils sont utilisés pour former un filtre sur les fiches HDA en appelant la méthode :func:`hdalab.views.ajax.filter_generic`.
+ Le résultat de cet appel est ensuite utilisé avec le paramêtre `shape` pour retourner un nouveau renkan.
+
+ Attention, il faut noter que les nouveau projets renkan créés par cette méthode ne sont pas sauvagardé en base et que donc elle n'a pas d'effet de bord.
+
+ """
# If a renkan id is set
rk_id = request.GET.get("rk_id", "")
@@ -634,6 +760,24 @@
def post(self, request):
+ """
+ Sauvegarde d'un renkan.
+ La sauvegarde n'est possible que dans les condition suivantes:
+ - si il s'agit d'une création de renkan (pas de paramêtre `rk_id`), il faut être identifié
+ - si un renkan est modifié, il faut être identifié et en être le propriétaire.
+
+ Paramêtres de requête:
+
+ +-----------+------------------------------------------------------------+--------+--------+
+ | nom | description | type | défaut |
+ +===========+============================================================+========+========+
+ | rk_id | Identifiant du renkan à sauvegarder | chaine | vide |
+ +-----------+------------------------------------------------------------+--------+--------+
+
+ Le contenu du renkan à sauvegarder est dans le corps de la requête.
+ Le contenu d'un renkan est décrit sommairement dans la documentation renkan.
+ À part pour les champs "id" et "title" qui sont utilisés pour la gestion de l'affichage, le contenu d'un renkan n'est pas modifié par cette meethode et est directement sauvegardé.
+ """
rk_id = request.GET.get("rk_id", "")
#data = json.loads(request.body)
@@ -676,8 +820,17 @@
class HdalabRenkanCopy(View):
+ """
+ Vue permettant de copier un renkan.
+ """
def post(self, request, rk_id):
+ """
+ Copie un renkan.
+ L'id du renkan à copier est un paramêtre d'URL.
+ Le nouveau titre est "ancien titre (copy)".
+ """
+
rk = renkan_copier(request.user, rk_id)
hr = HdalabRenkan()
hr.renkan = rk
@@ -689,8 +842,15 @@
class HdalabRenkanDelete(View):
+ """
+ Vue permettant d'effacer un Renkan.
+ """
def post(self, request, rk_id):
+ """
+ Efface un renkan.
+ L'id du renkan à copier est un paramêtre d'URL.
+ """
try:
hr = HdalabRenkan.objects.get(renkan__rk_id=rk_id)
except:
@@ -703,8 +863,35 @@
class HdalabRenkanModerate(View):
+ """
+ Vue pour modérer un renkan.
+ """
def post(self, request, rk_id):
+ """
+ Modère un Renkan, i.e. modifie son état.
+
+ :param:rk_id: L'identifiant de renkan, passé comme paramêtre d'URL.
+
+ Paramêtres POST:
+
+ +-----------+------------------------------------------------------------+--------+--------+-------------+
+ | nom | description | type | défaut | obligatoire |
+ +===========+============================================================+========+========+=============+
+ | id | Identifiant de renkan (n'est pas pris en compte) | chaine | | oui |
+ +-----------+------------------------------------------------------------+--------+--------+-------------+
+ | state | Le prochain état. | entier | | oui |
+ | | c.f. | | | |
+ | | :class:`hdalab.models.renkan.HdalabRenkanStateTransition` | | | |
+ +-----------+------------------------------------------------------------+--------+--------+-------------+
+ | message | Message optionel de modération. | chaine | vide | non |
+ +-----------+------------------------------------------------------------+--------+--------+-------------+
+ | next (*) | Url de redirection. | chaine | vide | non |
+ +-----------+------------------------------------------------------------+--------+--------+-------------+
+
+ (*) Si non précisée, redirige vers l'url intitulée `profile_home` (/hdalab/profile/).
+
+ """
form = HdalabRenkanStateForm(request.POST)
if form.is_valid():
logger.debug("FORM DATA %r", form.cleaned_data)
@@ -719,9 +906,28 @@
logger.debug("FORM INVALID %r : %r", request.POST, form.errors)
return HttpResponseBadRequest("State form invalid")
+
+
class HdalabRenkanFavorite(View):
+ """
+ Vue pour marquer un renkan comme favori.
+ """
def post(self, request, rk_id):
+ """
+ Marque un renkan comme favoris.
+
+ :param:rk_id: L'identifiant de renkan, passé comme paramêtre d'URL.
+
+ Paramêtres POST:
+
+ +-----------+------------------------------------------------------------+---------+--------+-------------+
+ | nom | description | type | défaut | obligatoire |
+ +===========+============================================================+=========+========+=============+
+ | favorite | Indique si le renkan est marqué comme favoris ou pas | booléen | | oui |
+ +-----------+------------------------------------------------------------+---------+--------+-------------+
+
+ """
form = HdalabRenkanFavoriteForm(request.POST)
if form.is_valid():
renkan_hda = get_object_or_404(HdalabRenkan.objects.select_related(), renkan__rk_id=rk_id)
@@ -734,6 +940,11 @@
class UserProfileUpdate(UpdateView):
+ """
+ Simple classe de vue permettant la gestion des pages de mise à jour des informations de profile de l'utilisateur.
+ utilise en particulier le template `hdalab/templates/hdabo/user_update_form.html` comme formulaire de saisie.
+ Elle étend la vue `django.views.generic.edit.UpdateView <https://docs.djangoproject.com/en/1.8/ref/class-based-views/generic-editing/#django.views.generic.edit.UpdateView>`_ .
+ """
fields = ['email']
template_name_suffix = '_update_form'
@@ -753,7 +964,8 @@
authentication_form=AuthenticationForm,
current_app=None, extra_context=None):
"""
- Displays the login form and handles the login action.
+ Affiche le formulaire de connection et gère l'action de connexion.
+ Cette fonction a été copiée de :func:`django.contrib.auth.views.login` pour faciliter la connexion `ajax`.
"""
redirect_to = request.REQUEST.get(redirect_field_name, '')
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/virtualenv/web/res/doc_requirements.txt Wed Apr 11 12:19:47 2018 +0200
@@ -0,0 +1,2 @@
+sphinx
+sphinx-autobuild