# HG changeset patch # User ymh # Date 1523441987 -7200 # Node ID 09e00f38d17700b133cefa653eaf44b41e7d4b8f # Parent b7d19cd87fcf7df77d60d3c35762289f2ae56be7 Add hdabo/hdalab documentations diff -r b7d19cd87fcf -r 09e00f38d177 .hgignore --- 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 diff -r b7d19cd87fcf -r 09e00f38d177 doc/Makefile --- /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 diff -r b7d19cd87fcf -r 09e00f38d177 doc/make.bat --- /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 diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/_static/img/logo_iri.png Binary file doc/source/_static/img/logo_iri.png has changed diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/_static/img/pages/accueil_hdalab.png Binary file doc/source/_static/img/pages/accueil_hdalab.png has changed diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/_static/img/pages/admin_django_hdalab.png Binary file doc/source/_static/img/pages/admin_django_hdalab.png has changed diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/_static/img/pages/administrer_renkan.png Binary file doc/source/_static/img/pages/administrer_renkan.png has changed diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/_static/img/pages/apropos_hdalab.png Binary file doc/source/_static/img/pages/apropos_hdalab.png has changed diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/_static/img/pages/artistic_domains_hdalab.png Binary file doc/source/_static/img/pages/artistic_domains_hdalab.png has changed diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/_static/img/pages/contact_hdalab.png Binary file doc/source/_static/img/pages/contact_hdalab.png has changed diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/_static/img/pages/credits_hdalab.png Binary file doc/source/_static/img/pages/credits_hdalab.png has changed diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/_static/img/pages/detail_notice.png Binary file doc/source/_static/img/pages/detail_notice.png has changed diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/_static/img/pages/editorialisation_hdalab.png Binary file doc/source/_static/img/pages/editorialisation_hdalab.png has changed diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/_static/img/pages/facettes_hdalab.png Binary file doc/source/_static/img/pages/facettes_hdalab.png has changed diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/_static/img/pages/mentions_legales_hdalab.png Binary file doc/source/_static/img/pages/mentions_legales_hdalab.png has changed diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/_static/img/pages/renkan_base_list.png Binary file doc/source/_static/img/pages/renkan_base_list.png has changed diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/_static/img/pages/renkan_edit.png Binary file doc/source/_static/img/pages/renkan_edit.png has changed diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/_static/img/pages/renkan_favorite.png Binary file doc/source/_static/img/pages/renkan_favorite.png has changed diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/_static/img/pages/renkan_public.png Binary file doc/source/_static/img/pages/renkan_public.png has changed diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/_static/img/pages/renkan_view.png Binary file doc/source/_static/img/pages/renkan_view.png has changed diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/_static/img/pages/renkan_view_full.png Binary file doc/source/_static/img/pages/renkan_view_full.png has changed diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/_static/img/pages/thematic_folder_hdalab.png Binary file doc/source/_static/img/pages/thematic_folder_hdalab.png has changed diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/_static/img/pages/tree_search_hdalab.png Binary file doc/source/_static/img/pages/tree_search_hdalab.png has changed diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/_static/img/pages/user_info_hdalab.png Binary file doc/source/_static/img/pages/user_info_hdalab.png has changed diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/_static/img/pages/user_profile_hdalab.png Binary file doc/source/_static/img/pages/user_profile_hdalab.png has changed diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/_static/img/renkan/renkan_bin_plus_ressources.png Binary file doc/source/_static/img/renkan/renkan_bin_plus_ressources.png has changed diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/_static/img/renkan/renkan_bin_resources.png Binary file doc/source/_static/img/renkan/renkan_bin_resources.png has changed diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/_static/img/renkan/renkan_edition.png Binary file doc/source/_static/img/renkan/renkan_edition.png has changed diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/_static/img/renkan/renkan_recherche_contenus.png Binary file doc/source/_static/img/renkan/renkan_recherche_contenus.png has changed diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/_static/img/renkan/renkan_recherche_resultats.png Binary file doc/source/_static/img/renkan/renkan_recherche_resultats.png has changed diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/api.rst --- /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: + + diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/api/hdabo.management.commands.rst --- /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: diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/api/hdabo.management.rst --- /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: diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/api/hdabo.migrations.rst --- /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: diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/api/hdabo.rst --- /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: diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/api/hdabo.search.rst --- /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: diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/api/hdabo.templatetags.rst --- /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: diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/api/hdabo.tests.rst --- /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: diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/api/hdalab.management.commands.rst --- /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: diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/api/hdalab.management.rst --- /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: diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/api/hdalab.migrations.rst --- /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: diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/api/hdalab.models.rst --- /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: diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/api/hdalab.rst --- /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: diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/api/hdalab.templatetags.rst --- /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: diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/api/hdalab.views.rst --- /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: diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/api/modules.rst --- /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 diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/commandes.rst --- /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 `_. +L'usage des commande est en général le suivant: + +``` +django-admin [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 `_) + - *\-\-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 diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/conf.py --- /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' + ] +} diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/dev.rst --- /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 `__. + - 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 + +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 `__) + +:: + + $ docker-compose -p hdalab exec hdalab django-admin [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 < + $ 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 ] -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 ] -p hdalab build [SERVICE...] + +création et lancement des services +---------------------------------- + +:: + + $ docker-compose [-f ] -p hdalab up -d [SERVICE...] + +A noter l'option ``-d`` qui mettent les services en tache de fond. + +lancement des services +---------------------- + +:: + + $ docker-compose [-f ] -p hdalab run SERVICE [COMMAND] [ARGS...] + +Cette commande lance un service. + +Execution d'une commande sur un service lancé +--------------------------------------------- + +:: + + $ docker-compose [-f ] -p hdalab exec SERVICE COMMAND [ARGS...] + +arrêt des services +------------------ + +:: + + $ docker-compose [-f ] -p hdalab stop [SERVICE...] + +consulter la sortie des containers +---------------------------------- + +:: + + $ docker-compose [-f ] -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 ] -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`` diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/index.rst --- /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 + + diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/pages.rst --- /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 `_. + + ++----------+-------------------------------------------------------+ +| 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 `_ (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 `_, 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/ | ++-------------+-----------------------------------------------------------+ +| 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/ | ++-------------+-------------------------------------------------------------+ +| 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/ | ++-------------+---------------------------------------------------------------+ +| 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/ | ++-------------+---------------------------------------------------------------+ +| 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 `_ | ++-----------------------------------------------------------------+--------------------------------------------------------------------------------+ +| http://hdalab.iri-research.org/hdalab/hdabo/accounts/register/ | `django-registration-redux `_ | ++-----------------------------------------------------------------+--------------------------------------------------------------------------------+ +| http://hdalab.iri-research.org/hdalab/login | `django.contrib.auth `_ | ++-----------------------------------------------------------------+--------------------------------------------------------------------------------+ +| http://hdalab.iri-research.org/hdalab/logout | `django.contrib.auth `_ | ++-----------------------------------------------------------------+--------------------------------------------------------------------------------+ +| http://hdalab.iri-research.org/hdalab/password | `django.contrib.auth `_ | ++-----------------------------------------------------------------+--------------------------------------------------------------------------------+ +| http://hdalab.iri-research.org/hdalab/password_change | `django.contrib.auth `_ | ++-----------------------------------------------------------------+--------------------------------------------------------------------------------+ +| http://hdalab.iri-research.org/hdalab/password_reset | `django.contrib.auth `_ | ++-----------------------------------------------------------------+--------------------------------------------------------------------------------+ + + +La librairie `django-registration-redux `_ 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 `_. + +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// django.views.i18n.javascript_catalog jsi18n + + + /renkan/copy/ hdalab.views.profile.HdalabRenkanCopy renkan_copy login_required + /renkan/delete/ hdalab.views.profile.HdalabRenkanDelete renkan_delete login_required + /renkan/favorite/ hdalab.views.profile.HdalabRenkanFavorite renkan_favorite login_required + /renkan/moderate/ 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/ 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/ hdalab.views.editorial.HdalabDeleteFolder hdalab_delete_folder login_required + /edito/folder/ hdalab.views.editorial.HdalabAddOrUpdateFolder hdalab_add_or_update_folder login_required + /edito/folder/ 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// 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// django.contrib.admin.options.change_view admin:auth_group_change + /hdabo/admin/auth/group//delete/ django.contrib.admin.options.delete_view admin:auth_group_delete + /hdabo/admin/auth/group//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// django.contrib.admin.options.change_view admin:hdabo_author_change + /hdabo/admin/hdabo/author//delete/ django.contrib.admin.options.delete_view admin:hdabo_author_delete + /hdabo/admin/hdabo/author//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// django.contrib.admin.options.change_view admin:hdabo_datasheet_change + /hdabo/admin/hdabo/datasheet//delete/ django.contrib.admin.options.delete_view admin:hdabo_datasheet_delete + /hdabo/admin/hdabo/datasheet//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// django.contrib.admin.options.change_view admin:hdabo_documentformat_change + /hdabo/admin/hdabo/documentformat//delete/ django.contrib.admin.options.delete_view admin:hdabo_documentformat_delete + /hdabo/admin/hdabo/documentformat//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// django.contrib.admin.options.change_view admin:hdabo_domain_change + /hdabo/admin/hdabo/domain//delete/ django.contrib.admin.options.delete_view admin:hdabo_domain_delete + /hdabo/admin/hdabo/domain//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// django.contrib.admin.options.change_view admin:hdabo_organisation_change + /hdabo/admin/hdabo/organisation//delete/ django.contrib.admin.options.delete_view admin:hdabo_organisation_delete + /hdabo/admin/hdabo/organisation//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// django.contrib.admin.options.change_view admin:hdabo_tag_change + /hdabo/admin/hdabo/tag//delete/ django.contrib.admin.options.delete_view admin:hdabo_tag_delete + /hdabo/admin/hdabo/tag//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// django.contrib.admin.options.change_view admin:hdabo_tagcategory_change + /hdabo/admin/hdabo/tagcategory//delete/ django.contrib.admin.options.delete_view admin:hdabo_tagcategory_delete + /hdabo/admin/hdabo/tagcategory//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// django.contrib.admin.options.change_view admin:hdabo_taggedsheet_change + /hdabo/admin/hdabo/taggedsheet//delete/ django.contrib.admin.options.delete_view admin:hdabo_taggedsheet_delete + /hdabo/admin/hdabo/taggedsheet//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// django.contrib.admin.options.change_view admin:hdabo_timeperiod_change + /hdabo/admin/hdabo/timeperiod//delete/ django.contrib.admin.options.delete_view admin:hdabo_timeperiod_delete + /hdabo/admin/hdabo/timeperiod//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// django.contrib.admin.options.change_view admin:hdabo_user_change + /hdabo/admin/hdabo/user//delete/ django.contrib.admin.options.delete_view admin:hdabo_user_delete + /hdabo/admin/hdabo/user//history/ django.contrib.admin.options.history_view admin:hdabo_user_history + /hdabo/admin/hdabo/user//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/// 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// django.contrib.admin.options.change_view admin:registration_registrationprofile_change + /hdabo/admin/registration/registrationprofile//delete/ django.contrib.admin.options.delete_view admin:registration_registrationprofile_delete + /hdabo/admin/registration/registrationprofile//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// django.contrib.admin.options.change_view admin:sites_site_change + /hdabo/admin/sites/site//delete/ django.contrib.admin.options.delete_view admin:sites_site_delete + /hdabo/admin/sites/site//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// 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/// django.contrib.auth.views.password_reset_confirm auth_password_reset_confirm + /hdabo/accounts/password/reset/confirm/// 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/// 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/ 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// hdabo.views.all_tags login_required + /hdabo/alltags/// hdabo.views.all_tags login_required + /hdabo/alltags//// hdabo.views.all_tags login_required + /hdabo/alltags///// hdabo.views.all_tags login_required + + /hdabo/data hdabo.views.display_datasheet display_datasheet login_required + /hdabo/data/ hdabo.views.display_datasheet display_datasheet login_required + + /hdabo/deletefolder/ hdabo.views.DeleteFolder delete_folder login_required + + /hdabo/folder/ hdabo.views.AddOrUpdateFolder add_or_update_folder login_required + /hdabo/folder/ 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/ hdabo.views.list_for_orga list_for_orga login_required + /hdabo/list/// hdabo.views.list_for_orga list_for_orga login_required + /hdabo/list//// hdabo.views.list_for_orga list_for_orga login_required + /hdabo/list///// 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/ hdabo.views.validate_datasheet login_required + /hdabo/validatedatasheet/// hdabo.views.validate_datasheet login_required + diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/renkan.rst --- /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 `. +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. + diff -r b7d19cd87fcf -r 09e00f38d177 doc/source/taches.rst --- /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 `_. + +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 `_. +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. + + + diff -r b7d19cd87fcf -r 09e00f38d177 src/hdabo/management/commands/clean_tags.py --- 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 diff -r b7d19cd87fcf -r 09e00f38d177 src/hdabo/management/commands/diff_csv.py --- 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] `` + +**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 `_) + - *\-\-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 = '' 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() diff -r b7d19cd87fcf -r 09e00f38d177 src/hdabo/management/commands/import_csv.py --- 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] `` + +**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 `_) + - *\-\-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: diff -r b7d19cd87fcf -r 09e00f38d177 src/hdabo/management/commands/import_rdf.py --- 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 ` + #. `rebuild_index `_ + +**Usage**: ``django-admin import_rdf [options] `` + +**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 = '' 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] diff -r b7d19cd87fcf -r 09e00f38d177 src/hdabo/management/commands/import_tag_popularity.py --- 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] `` + +**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 `_) + - *\-\-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 = '' 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() diff -r b7d19cd87fcf -r 09e00f38d177 src/hdabo/management/commands/order_tags.py --- 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() - - + + diff -r b7d19cd87fcf -r 09e00f38d177 src/hdabo/management/commands/query_wikipedia.py --- 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 `_ en recherchant par le nom des pages (``titles=Foo|Bar|Main_Page``). + +**Usage**: ``django-admin import_csv [options] `` -@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) - - + + diff -r b7d19cd87fcf -r 09e00f38d177 src/hdabo/models.py --- 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) diff -r b7d19cd87fcf -r 09e00f38d177 src/hdabo/views.py --- 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 `_. + + 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" diff -r b7d19cd87fcf -r 09e00f38d177 src/hdabo/wp_utils.py --- 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() - + diff -r b7d19cd87fcf -r 09e00f38d177 src/hdalab/__init__.py --- 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) diff -r b7d19cd87fcf -r 09e00f38d177 src/hdalab/management/commands/calculate_preview.py --- 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) diff -r b7d19cd87fcf -r 09e00f38d177 src/hdalab/management/commands/export_tags_csv.py --- 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] `` + +**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 diff -r b7d19cd87fcf -r 09e00f38d177 src/hdalab/management/commands/export_wpcategory_csv.py --- 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] `` -@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() diff -r b7d19cd87fcf -r 09e00f38d177 src/hdalab/management/commands/fill_tag_years.py --- 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 diff -r b7d19cd87fcf -r 09e00f38d177 src/hdalab/management/commands/geojson_transform.py --- 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 = '' - 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: - 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: - 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**: + +''' +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 = '' + 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: + 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: + 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() diff -r b7d19cd87fcf -r 09e00f38d177 src/hdalab/management/commands/import_hda_insee_csv.py --- 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**: + ''' import csv import re @@ -18,21 +23,21 @@ args = '' 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() diff -r b7d19cd87fcf -r 09e00f38d177 src/hdalab/management/commands/import_hdabo_db.py --- 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 `_ + - :mod:`query_wikipedia_category \-f \-\-all ` (si l'option est passée) + - :mod:`query_dbpedia \-f \-\-all ` + - :mod:`fill_tag_years ` + - :mod:`geojson_transform \/countries.geo.json ` + - :mod:`query_geo_inclusion ` + - :mod:`import_insee_csv \/villes.csv ` + - :mod:`import_insee_csv \/additional_cities.csv ` + - :mod:`import_hda_insee_csv \/HDA_Insee.csv ` + - :mod:`query_category_inclusion \-f \-\-all ` + +**Usage**: ``django-admin import_hdabo_db [options] []`` + +**Options spécifiques:** + + - *\-c,\-\-categories*: ajoute la commande :mod:`query_wikipedia_category \-f \-\-all ` à la chaîne de traitements. + ''' from django.core.management.base import BaseCommand from django.core.management import call_command diff -r b7d19cd87fcf -r 09e00f38d177 src/hdalab/management/commands/import_insee_csv.py --- 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 = '' - 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 `` + +''' +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 = '' + 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() diff -r b7d19cd87fcf -r 09e00f38d177 src/hdalab/management/commands/query_category_inclusion.py --- 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 `_ 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) diff -r b7d19cd87fcf -r 09e00f38d177 src/hdalab/management/commands/query_dbpedia.py --- 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> ?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> ?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> ?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]) - + - - + + diff -r b7d19cd87fcf -r 09e00f38d177 src/hdalab/management/commands/query_geo_inclusion.py --- 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 = '' - + country, _ = Country.objects.get_or_create(dbpedia_uri=tag.dbpedia_uri) GeoInclusion.objects.get_or_create(tag=tag, country=country) - + else: countrytxt = '' - - 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) diff -r b7d19cd87fcf -r 09e00f38d177 src/hdalab/management/commands/query_wikipedia_category.py --- 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 `_ 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 diff -r b7d19cd87fcf -r 09e00f38d177 src/hdalab/management/commands/send_moderation_mail.py --- 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 `_. -@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 diff -r b7d19cd87fcf -r 09e00f38d177 src/hdalab/models/categories.py --- 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') diff -r b7d19cd87fcf -r 09e00f38d177 src/hdalab/models/dataviz.py --- 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' diff -r b7d19cd87fcf -r 09e00f38d177 src/hdalab/models/renkan.py --- 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"] diff -r b7d19cd87fcf -r 09e00f38d177 src/hdalab/services.py --- 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 diff -r b7d19cd87fcf -r 09e00f38d177 src/hdalab/signals.py --- 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" diff -r b7d19cd87fcf -r 09e00f38d177 src/hdalab/views/__init__.py --- 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 diff -r b7d19cd87fcf -r 09e00f38d177 src/hdalab/views/ajax.py --- 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 :: + + { + "": "", + "": "" + } + + """ 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": "", + "themes": [ { "label": "", "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 `,` (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 `,...` (défaut: None). + :param str contentlist: Liste d'id de fiche HDA (:class:`hdabo.models.Datasheet`) limitant la recherche. Le format est `,...` (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','{}') diff -r b7d19cd87fcf -r 09e00f38d177 src/hdalab/views/pages.py --- 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" diff -r b7d19cd87fcf -r 09e00f38d177 src/hdalab/views/profile.py --- 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 `,`. | | | + +-------------+------------------------------------------------------------+--------+--------+ + + + (*) 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 `_ . + """ 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, '') diff -r b7d19cd87fcf -r 09e00f38d177 virtualenv/web/res/doc_requirements.txt --- /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