Creating iconolab episteme project
authorRiwad Salim
Tue, 26 Jun 2018 15:55:08 +0200
changeset 0 df27f9610c82
child 1 3b0a8a6e685e
Creating iconolab episteme project
.hgignore
.vs/slnx.sqlite
docker-compose.yml
src/LICENSE
src/iconolab_episteme/__init__.py
src/iconolab_episteme/apps.py
src/iconolab_episteme/fixtures/demo_data.json
src/iconolab_episteme/management/__init__.py
src/iconolab_episteme/management/commands/__init__.py
src/iconolab_episteme/management/commands/importcollection.py
src/iconolab_episteme/management/commands/importimages.py
src/iconolab_episteme/management/commands/importmetacategories.py
src/iconolab_episteme/settings/__init__.py
src/iconolab_episteme/settings/dev.py
src/iconolab_episteme/settings/dev.py.tmpl
src/iconolab_episteme/templates/iconolab/metadatas/detail_image_metadatas.html
src/iconolab_episteme/templates/iconolab/metadatas/detail_item_metadatas.html
src/iconolab_episteme/templates/iconolab/metadatas/image_search_metadatas.html
src/iconolab_episteme/templates/iconolab/search/indexes/iconolab/item_text.txt
src/iconolab_episteme/templatetags/__init__.py
src/iconolab_episteme/templatetags/iconolab_episteme_tags.py
src/iconolab_episteme/urls.py
src/iconolab_episteme/wsgi.py
src/manage.py
src/requirements/base.txt
src/requirements/base.txt.in
src/requirements/dev.txt
src/requirements/prod.txt
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgignore	Tue Jun 26 15:55:08 2018 +0200
@@ -0,0 +1,43 @@
+syntax: regexp
+
+^virtualenv/
+
+^__pychache__/
+^src/iconolab_mcc/settings/dev\.py$
+
+node_modules/
+\.css.map$
+\.js.map$
+^src/iconolab/static/iconolab/js/iconolab-bundle/dist/
+\.orig$
+
+^src_js/iconolab-bundle/dist/
+
+\.log$
+^web/*
+^\.pydevproject$
+^\.project$
+^\.settings/org\.eclipse\.core\.resources\.prefs$
+^\.settings/org\.eclipse\.core\.runtime\.prefs$
+\.pyc$
+\.DS_Store$
+^src/iconolab_episteme/media/uploads/
+^src/iconolab_episteme/media/cache/
+^src/db.sqlite3$
+^src/log\.txt$
+^run/log/
+^run/web/
+^log$
+^sbin/sync/config\.py$
+^src/MANIFEST
+^src/iconolab_episteme.egg-info
+^src/dist/
+^src/.vscode
+^src/requirements/custom.txt$
+^src/iconolab_episteme/db.sqlite3
+^src/.direnv
+^src/.envrc$
+
+^data/
+
+^.vscode
\ No newline at end of file
Binary file .vs/slnx.sqlite has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docker-compose.yml	Tue Jun 26 15:55:08 2018 +0200
@@ -0,0 +1,27 @@
+version: '2.1'
+
+services:
+
+  elasticsearch:
+    image: docker.elastic.co/elasticsearch/elasticsearch:6.2.4
+    environment:
+      # - "transport.host=127.0.0.1"
+      # - "http.cors.enabled=true"
+      # - "http.cors.allow-origin=*"
+      # - "http.cors.allow-headers=Authorization"
+      - "ES_JAVA_OPTS=-Xms1024m -Xmx1024m"
+      - "discovery.type=single-node"
+    ports:
+      - 9200:9200
+      - 9300:9300
+    volumes:
+      - /usr/share/elasticsearch/data
+
+  postgres:
+    image: postgres:alpine
+    ports:
+      - 5432:5432
+    volumes:
+      - /var/lib/postgresql/data
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/LICENSE	Tue Jun 26 15:55:08 2018 +0200
@@ -0,0 +1,520 @@
+Copyright (c) 2016, IRI (Institute d Recherche de d'Innovation)
+All rights reserved.
+
+
+
+
+CeCILL-B FREE SOFTWARE LICENSE AGREEMENT
+
+
+    Notice
+
+This Agreement is a Free Software license agreement that is the result
+of discussions between its authors in order to ensure compliance with
+the two main principles guiding its drafting:
+
+    * firstly, compliance with the principles governing the distribution
+      of Free Software: access to source code, broad rights granted to
+      users,
+    * secondly, the election of a governing law, French law, with which
+      it is conformant, both as regards the law of torts and
+      intellectual property law, and the protection that it offers to
+      both authors and holders of the economic rights over software.
+
+The authors of the CeCILL-B (for Ce[a] C[nrs] I[nria] L[ogiciel] L[ibre])
+license are:
+
+Commissariat à l'Energie Atomique - CEA, a public scientific, technical
+and industrial research establishment, having its principal place of
+business at 25 rue Leblanc, immeuble Le Ponant D, 75015 Paris, France.
+
+Centre National de la Recherche Scientifique - CNRS, a public scientific
+and technological establishment, having its principal place of business
+at 3 rue Michel-Ange, 75794 Paris cedex 16, France.
+
+Institut National de Recherche en Informatique et en Automatique -
+INRIA, a public scientific and technological establishment, having its
+principal place of business at Domaine de Voluceau, Rocquencourt, BP
+105, 78153 Le Chesnay cedex, France.
+
+
+    Preamble
+
+This Agreement is an open source software license intended to give users
+significant freedom to modify and redistribute the software licensed
+hereunder.
+
+The exercising of this freedom is conditional upon a strong obligation
+of giving credits for everybody that distributes a software
+incorporating a software ruled by the current license so as all
+contributions to be properly identified and acknowledged.
+
+In consideration of access to the source code and the rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty and the software's author, the holder of the
+economic rights, and the successive licensors only have limited liability.
+
+In this respect, the risks associated with loading, using, modifying
+and/or developing or reproducing the software by the user are brought to
+the user's attention, given its Free Software status, which may make it
+complicated to use, with the result that its use is reserved for
+developers and experienced professionals having in-depth computer
+knowledge. Users are therefore encouraged to load and test the
+suitability of the software as regards their requirements in conditions
+enabling the security of their systems and/or data to be ensured and,
+more generally, to use and operate it in the same conditions of
+security. This Agreement may be freely reproduced and published,
+provided it is not altered, and that no provisions are either added or
+removed herefrom.
+
+This Agreement may apply to any or all software for which the holder of
+the economic rights decides to submit the use thereof to its provisions.
+
+
+    Article 1 - DEFINITIONS
+
+For the purpose of this Agreement, when the following expressions
+commence with a capital letter, they shall have the following meaning:
+
+Agreement: means this license agreement, and its possible subsequent
+versions and annexes.
+
+Software: means the software in its Object Code and/or Source Code form
+and, where applicable, its documentation, "as is" when the Licensee
+accepts the Agreement.
+
+Initial Software: means the Software in its Source Code and possibly its
+Object Code form and, where applicable, its documentation, "as is" when
+it is first distributed under the terms and conditions of the Agreement.
+
+Modified Software: means the Software modified by at least one
+Contribution.
+
+Source Code: means all the Software's instructions and program lines to
+which access is required so as to modify the Software.
+
+Object Code: means the binary files originating from the compilation of
+the Source Code.
+
+Holder: means the holder(s) of the economic rights over the Initial
+Software.
+
+Licensee: means the Software user(s) having accepted the Agreement.
+
+Contributor: means a Licensee having made at least one Contribution.
+
+Licensor: means the Holder, or any other individual or legal entity, who
+distributes the Software under the Agreement.
+
+Contribution: means any or all modifications, corrections, translations,
+adaptations and/or new functions integrated into the Software by any or
+all Contributors, as well as any or all Internal Modules.
+
+Module: means a set of sources files including their documentation that
+enables supplementary functions or services in addition to those offered
+by the Software.
+
+External Module: means any or all Modules, not derived from the
+Software, so that this Module and the Software run in separate address
+spaces, with one calling the other when they are run.
+
+Internal Module: means any or all Module, connected to the Software so
+that they both execute in the same address space.
+
+Parties: mean both the Licensee and the Licensor.
+
+These expressions may be used both in singular and plural form.
+
+
+    Article 2 - PURPOSE
+
+The purpose of the Agreement is the grant by the Licensor to the
+Licensee of a non-exclusive, transferable and worldwide license for the
+Software as set forth in Article 5 hereinafter for the whole term of the
+protection granted by the rights over said Software.
+
+
+    Article 3 - ACCEPTANCE
+
+3.1 The Licensee shall be deemed as having accepted the terms and
+conditions of this Agreement upon the occurrence of the first of the
+following events:
+
+    * (i) loading the Software by any or all means, notably, by
+      downloading from a remote server, or by loading from a physical
+      medium;
+    * (ii) the first time the Licensee exercises any of the rights
+      granted hereunder.
+
+3.2 One copy of the Agreement, containing a notice relating to the
+characteristics of the Software, to the limited warranty, and to the
+fact that its use is restricted to experienced users has been provided
+to the Licensee prior to its acceptance as set forth in Article 3.1
+hereinabove, and the Licensee hereby acknowledges that it has read and
+understood it.
+
+
+    Article 4 - EFFECTIVE DATE AND TERM
+
+
+      4.1 EFFECTIVE DATE
+
+The Agreement shall become effective on the date when it is accepted by
+the Licensee as set forth in Article 3.1.
+
+
+      4.2 TERM
+
+The Agreement shall remain in force for the entire legal term of
+protection of the economic rights over the Software.
+
+
+    Article 5 - SCOPE OF RIGHTS GRANTED
+
+The Licensor hereby grants to the Licensee, who accepts, the following
+rights over the Software for any or all use, and for the term of the
+Agreement, on the basis of the terms and conditions set forth hereinafter.
+
+Besides, if the Licensor owns or comes to own one or more patents
+protecting all or part of the functions of the Software or of its
+components, the Licensor undertakes not to enforce the rights granted by
+these patents against successive Licensees using, exploiting or
+modifying the Software. If these patents are transferred, the Licensor
+undertakes to have the transferees subscribe to the obligations set
+forth in this paragraph.
+
+
+      5.1 RIGHT OF USE
+
+The Licensee is authorized to use the Software, without any limitation
+as to its fields of application, with it being hereinafter specified
+that this comprises:
+
+   1. permanent or temporary reproduction of all or part of the Software
+      by any or all means and in any or all form.
+
+   2. loading, displaying, running, or storing the Software on any or
+      all medium.
+
+   3. entitlement to observe, study or test its operation so as to
+      determine the ideas and principles behind any or all constituent
+      elements of said Software. This shall apply when the Licensee
+      carries out any or all loading, displaying, running, transmission
+      or storage operation as regards the Software, that it is entitled
+      to carry out hereunder.
+
+
+      5.2 ENTITLEMENT TO MAKE CONTRIBUTIONS
+
+The right to make Contributions includes the right to translate, adapt,
+arrange, or make any or all modifications to the Software, and the right
+to reproduce the resulting software.
+
+The Licensee is authorized to make any or all Contributions to the
+Software provided that it includes an explicit notice that it is the
+author of said Contribution and indicates the date of the creation thereof.
+
+
+      5.3 RIGHT OF DISTRIBUTION
+
+In particular, the right of distribution includes the right to publish,
+transmit and communicate the Software to the general public on any or
+all medium, and by any or all means, and the right to market, either in
+consideration of a fee, or free of charge, one or more copies of the
+Software by any means.
+
+The Licensee is further authorized to distribute copies of the modified
+or unmodified Software to third parties according to the terms and
+conditions set forth hereinafter.
+
+
+        5.3.1 DISTRIBUTION OF SOFTWARE WITHOUT MODIFICATION
+
+The Licensee is authorized to distribute true copies of the Software in
+Source Code or Object Code form, provided that said distribution
+complies with all the provisions of the Agreement and is accompanied by:
+
+   1. a copy of the Agreement,
+
+   2. a notice relating to the limitation of both the Licensor's
+      warranty and liability as set forth in Articles 8 and 9,
+
+and that, in the event that only the Object Code of the Software is
+redistributed, the Licensee allows effective access to the full Source
+Code of the Software at a minimum during the entire period of its
+distribution of the Software, it being understood that the additional
+cost of acquiring the Source Code shall not exceed the cost of
+transferring the data.
+
+
+        5.3.2 DISTRIBUTION OF MODIFIED SOFTWARE
+
+If the Licensee makes any Contribution to the Software, the resulting
+Modified Software may be distributed under a license agreement other
+than this Agreement subject to compliance with the provisions of Article
+5.3.4.
+
+
+        5.3.3 DISTRIBUTION OF EXTERNAL MODULES
+
+When the Licensee has developed an External Module, the terms and
+conditions of this Agreement do not apply to said External Module, that
+may be distributed under a separate license agreement.
+
+
+        5.3.4 CREDITS
+
+Any Licensee who may distribute a Modified Software hereby expressly
+agrees to:
+
+   1. indicate in the related documentation that it is based on the
+      Software licensed hereunder, and reproduce the intellectual
+      property notice for the Software,
+
+   2. ensure that written indications of the Software intended use,
+      intellectual property notice and license hereunder are included in
+      easily accessible format from the Modified Software interface,
+
+   3. mention, on a freely accessible website describing the Modified
+      Software, at least throughout the distribution term thereof, that
+      it is based on the Software licensed hereunder, and reproduce the
+      Software intellectual property notice,
+
+   4. where it is distributed to a third party that may distribute a
+      Modified Software without having to make its source code
+      available, make its best efforts to ensure that said third party
+      agrees to comply with the obligations set forth in this Article .
+
+If the Software, whether or not modified, is distributed with an
+External Module designed for use in connection with the Software, the
+Licensee shall submit said External Module to the foregoing obligations.
+
+
+        5.3.5 COMPATIBILITY WITH THE CeCILL AND CeCILL-C LICENSES
+
+Where a Modified Software contains a Contribution subject to the CeCILL
+license, the provisions set forth in Article 5.3.4 shall be optional.
+
+A Modified Software may be distributed under the CeCILL-C license. In
+such a case the provisions set forth in Article 5.3.4 shall be optional.
+
+
+    Article 6 - INTELLECTUAL PROPERTY
+
+
+      6.1 OVER THE INITIAL SOFTWARE
+
+The Holder owns the economic rights over the Initial Software. Any or
+all use of the Initial Software is subject to compliance with the terms
+and conditions under which the Holder has elected to distribute its work
+and no one shall be entitled to modify the terms and conditions for the
+distribution of said Initial Software.
+
+The Holder undertakes that the Initial Software will remain ruled at
+least by this Agreement, for the duration set forth in Article 4.2.
+
+
+      6.2 OVER THE CONTRIBUTIONS
+
+The Licensee who develops a Contribution is the owner of the
+intellectual property rights over this Contribution as defined by
+applicable law.
+
+
+      6.3 OVER THE EXTERNAL MODULES
+
+The Licensee who develops an External Module is the owner of the
+intellectual property rights over this External Module as defined by
+applicable law and is free to choose the type of agreement that shall
+govern its distribution.
+
+
+      6.4 JOINT PROVISIONS
+
+The Licensee expressly undertakes:
+
+   1. not to remove, or modify, in any manner, the intellectual property
+      notices attached to the Software;
+
+   2. to reproduce said notices, in an identical manner, in the copies
+      of the Software modified or not.
+
+The Licensee undertakes not to directly or indirectly infringe the
+intellectual property rights of the Holder and/or Contributors on the
+Software and to take, where applicable, vis-à-vis its staff, any and all
+measures required to ensure respect of said intellectual property rights
+of the Holder and/or Contributors.
+
+
+    Article 7 - RELATED SERVICES
+
+7.1 Under no circumstances shall the Agreement oblige the Licensor to
+provide technical assistance or maintenance services for the Software.
+
+However, the Licensor is entitled to offer this type of services. The
+terms and conditions of such technical assistance, and/or such
+maintenance, shall be set forth in a separate instrument. Only the
+Licensor offering said maintenance and/or technical assistance services
+shall incur liability therefor.
+
+7.2 Similarly, any Licensor is entitled to offer to its licensees, under
+its sole responsibility, a warranty, that shall only be binding upon
+itself, for the redistribution of the Software and/or the Modified
+Software, under terms and conditions that it is free to decide. Said
+warranty, and the financial terms and conditions of its application,
+shall be subject of a separate instrument executed between the Licensor
+and the Licensee.
+
+
+    Article 8 - LIABILITY
+
+8.1 Subject to the provisions of Article 8.2, the Licensee shall be
+entitled to claim compensation for any direct loss it may have suffered
+from the Software as a result of a fault on the part of the relevant
+Licensor, subject to providing evidence thereof.
+
+8.2 The Licensor's liability is limited to the commitments made under
+this Agreement and shall not be incurred as a result of in particular:
+(i) loss due the Licensee's total or partial failure to fulfill its
+obligations, (ii) direct or consequential loss that is suffered by the
+Licensee due to the use or performance of the Software, and (iii) more
+generally, any consequential loss. In particular the Parties expressly
+agree that any or all pecuniary or business loss (i.e. loss of data,
+loss of profits, operating loss, loss of customers or orders,
+opportunity cost, any disturbance to business activities) or any or all
+legal proceedings instituted against the Licensee by a third party,
+shall constitute consequential loss and shall not provide entitlement to
+any or all compensation from the Licensor.
+
+
+    Article 9 - WARRANTY
+
+9.1 The Licensee acknowledges that the scientific and technical
+state-of-the-art when the Software was distributed did not enable all
+possible uses to be tested and verified, nor for the presence of
+possible defects to be detected. In this respect, the Licensee's
+attention has been drawn to the risks associated with loading, using,
+modifying and/or developing and reproducing the Software which are
+reserved for experienced users.
+
+The Licensee shall be responsible for verifying, by any or all means,
+the suitability of the product for its requirements, its good working
+order, and for ensuring that it shall not cause damage to either persons
+or properties.
+
+9.2 The Licensor hereby represents, in good faith, that it is entitled
+to grant all the rights over the Software (including in particular the
+rights set forth in Article 5).
+
+9.3 The Licensee acknowledges that the Software is supplied "as is" by
+the Licensor without any other express or tacit warranty, other than
+that provided for in Article 9.2 and, in particular, without any warranty
+as to its commercial value, its secured, safe, innovative or relevant
+nature.
+
+Specifically, the Licensor does not warrant that the Software is free
+from any error, that it will operate without interruption, that it will
+be compatible with the Licensee's own equipment and software
+configuration, nor that it will meet the Licensee's requirements.
+
+9.4 The Licensor does not either expressly or tacitly warrant that the
+Software does not infringe any third party intellectual property right
+relating to a patent, software or any other property right. Therefore,
+the Licensor disclaims any and all liability towards the Licensee
+arising out of any or all proceedings for infringement that may be
+instituted in respect of the use, modification and redistribution of the
+Software. Nevertheless, should such proceedings be instituted against
+the Licensee, the Licensor shall provide it with technical and legal
+assistance for its defense. Such technical and legal assistance shall be
+decided on a case-by-case basis between the relevant Licensor and the
+Licensee pursuant to a memorandum of understanding. The Licensor
+disclaims any and all liability as regards the Licensee's use of the
+name of the Software. No warranty is given as regards the existence of
+prior rights over the name of the Software or as regards the existence
+of a trademark.
+
+
+    Article 10 - TERMINATION
+
+10.1 In the event of a breach by the Licensee of its obligations
+hereunder, the Licensor may automatically terminate this Agreement
+thirty (30) days after notice has been sent to the Licensee and has
+remained ineffective.
+
+10.2 A Licensee whose Agreement is terminated shall no longer be
+authorized to use, modify or distribute the Software. However, any
+licenses that it may have granted prior to termination of the Agreement
+shall remain valid subject to their having been granted in compliance
+with the terms and conditions hereof.
+
+
+    Article 11 - MISCELLANEOUS
+
+
+      11.1 EXCUSABLE EVENTS
+
+Neither Party shall be liable for any or all delay, or failure to
+perform the Agreement, that may be attributable to an event of force
+majeure, an act of God or an outside cause, such as defective
+functioning or interruptions of the electricity or telecommunications
+networks, network paralysis following a virus attack, intervention by
+government authorities, natural disasters, water damage, earthquakes,
+fire, explosions, strikes and labor unrest, war, etc.
+
+11.2 Any failure by either Party, on one or more occasions, to invoke
+one or more of the provisions hereof, shall under no circumstances be
+interpreted as being a waiver by the interested Party of its right to
+invoke said provision(s) subsequently.
+
+11.3 The Agreement cancels and replaces any or all previous agreements,
+whether written or oral, between the Parties and having the same
+purpose, and constitutes the entirety of the agreement between said
+Parties concerning said purpose. No supplement or modification to the
+terms and conditions hereof shall be effective as between the Parties
+unless it is made in writing and signed by their duly authorized
+representatives.
+
+11.4 In the event that one or more of the provisions hereof were to
+conflict with a current or future applicable act or legislative text,
+said act or legislative text shall prevail, and the Parties shall make
+the necessary amendments so as to comply with said act or legislative
+text. All other provisions shall remain effective. Similarly, invalidity
+of a provision of the Agreement, for any reason whatsoever, shall not
+cause the Agreement as a whole to be invalid.
+
+
+      11.5 LANGUAGE
+
+The Agreement is drafted in both French and English and both versions
+are deemed authentic.
+
+
+    Article 12 - NEW VERSIONS OF THE AGREEMENT
+
+12.1 Any person is authorized to duplicate and distribute copies of this
+Agreement.
+
+12.2 So as to ensure coherence, the wording of this Agreement is
+protected and may only be modified by the authors of the License, who
+reserve the right to periodically publish updates or new versions of the
+Agreement, each with a separate number. These subsequent versions may
+address new issues encountered by Free Software.
+
+12.3 Any Software distributed under a given version of the Agreement may
+only be subsequently distributed under the same version of the Agreement
+or a subsequent version.
+
+
+    Article 13 - GOVERNING LAW AND JURISDICTION
+
+13.1 The Agreement is governed by French law. The Parties agree to
+endeavor to seek an amicable solution to any disagreements or disputes
+that may arise during the performance of the Agreement.
+
+13.2 Failing an amicable solution within two (2) months as from their
+occurrence, and unless emergency proceedings are necessary, the
+disagreements or disputes shall be referred to the Paris Courts having
+jurisdiction, by the more diligent Party.
+
+
+Version 1.0 dated 2006-09-05.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/iconolab_episteme/__init__.py	Tue Jun 26 15:55:08 2018 +0200
@@ -0,0 +1,48 @@
+VERSION = (0, 0, 30, "final", 0)
+
+VERSION_STR = ".".join(map(lambda i:"%02d" % (i,), VERSION[:2]))
+
+###
+# https://github.com/django/django/blob/1.9.1/django/utils/version.py
+#
+def get_version(version=None):
+    "Returns a PEP 440-compliant version number from VERSION."
+    if not version:
+        version = VERSION
+    version = get_complete_version(version)
+
+    # Now build the two parts of the version number:
+    # main = X.Y[.Z]
+    # sub = .devN - for pre-alpha releases
+    #     | {a|b|rc}N - for alpha, beta, and rc releases
+
+    main = get_main_version(version)
+
+    sub = ''
+    if version[3] == 'alpha' and version[4] == 0:
+        sub = '.dev'
+
+    elif version[3] != 'final':
+        mapping = {'alpha': 'a', 'beta': 'b', 'rc': 'rc'}
+        sub = mapping[version[3]] + str(version[4])
+
+    return str(main + sub)
+
+def get_complete_version(version):
+    """
+    then checks for correctness of the tuple provided.
+    """
+    assert len(version) == 5
+    assert version[3] in ('alpha', 'beta', 'rc', 'final')
+
+    return version
+
+def get_main_version(version=None):
+    "Returns main version (X.Y[.Z]) from VERSION."
+    version = get_complete_version(version)
+    parts = 2 if version[2] == 0 else 3
+    return '.'.join(str(x) for x in version[:parts])
+
+__version__ = get_version(VERSION)
+
+default_app_config = 'iconolab_episteme.apps.IconolabEpistemeApp'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/iconolab_episteme/apps.py	Tue Jun 26 15:55:08 2018 +0200
@@ -0,0 +1,8 @@
+from django.apps import AppConfig
+
+class IconolabEpistemeApp(AppConfig):
+    name = 'iconolab_episteme'
+    verbose_name = 'Iconolab-episteme'
+
+    # def ready(self):
+    #     import iconolab.templatetags.iconolab_tags
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/iconolab_episteme/fixtures/demo_data.json	Tue Jun 26 15:55:08 2018 +0200
@@ -0,0 +1,235 @@
+[
+	{
+	    "model": "auth.User",
+	    "pk": 1,
+	    "fields": {
+	    	"username": "contributeur1",
+	    	"password": "pbkdf2_sha256$24000$4t81p9toYpfc$ufZAWaUcF51dpNqHscABIoW7UyoXxYDCRlKFI87vQJM="
+	    }
+	},{
+	    "model": "auth.User",
+	    "pk": 2,
+	    "fields": {
+	    	"username": "contributeur2",
+	    	"password": "pbkdf2_sha256$24000$b9CPP5bLU4FM$1IYIBS5y2CIEFV9jHdTdZjvj59hzx+yH5Akc5LsHo+g="
+	    }
+	},{
+	    "model": "iconolab.Collection",
+	    "pk": 1,
+	    "fields": {
+	    	"name": "",
+	    	"verbose_name": ""
+	    }
+	},{
+	    "model": "iconolab.Item",
+	    "pk": 1,
+	    "fields": {
+	    	"collection": 1,
+	    	"item_guid": ""
+	    }
+	},{
+	    "model": "iconolab.ItemMetadata",
+	    "pk": 1,
+	    "fields": {
+	    	"item": 1
+	    }
+	},{
+	    "model": "iconolab.Image",
+	    "pk": 1,
+	    "fields": {
+	    	"image_guid" : "",
+	    	"name" : "",
+			"media" : "",
+			"item": 1,
+			"height": 2478,
+			"width": 3744,
+			"created": ""
+	    }
+	},{
+	    "model": "iconolab.ImageStats",
+	    "pk": 1,
+	    "fields": {
+	    	"image": 1,
+	    	"annotations_count": 0,
+			"submitted_revisions_count": 0,
+			"comments_count": 0,
+			"folders_inclusion_count": 0,
+			"tag_count": 0
+	    }
+	},{
+	    "model": "iconolab.Item",
+	    "pk": 2,
+	    "fields": {
+	    	"collection": 1,
+	    	"item_guid": ""
+	    }
+	},{
+	    "model": "iconolab.ItemMetadata",
+	    "pk": 2,
+	    "fields": {
+            "item": 2
+	    }
+	},{
+	    "model": "iconolab.Image",
+	    "pk": 2,
+	    "fields": {
+	    	"image_guid" : "",
+	    	"name" : "",
+			"media" : "",
+			"item": 2,
+			"height": 4672,
+			"width": 6171,
+			"created": ""
+	    }
+	},{
+	    "model": "iconolab.ImageStats",
+	    "pk": 2,
+	    "fields": {
+	    	"image": 2,
+	    	"annotations_count": 0,
+			"submitted_revisions_count": 0,
+			"comments_count": 0,
+			"folders_inclusion_count": 0,
+			"tag_count": 0
+	    }
+	},{
+	    "model": "iconolab.Item",
+	    "pk": 3,
+	    "fields": {
+	    	"collection": 1,
+	    	"item_guid": ""
+	    }
+	},{
+	    "model": "iconolab.ItemMetadata",
+	    "pk": 3,
+	    "fields": {
+	    	"item": 3
+	    }
+	},{
+	    "model": "iconolab.Image",
+	    "pk": 3,
+	    "fields": {
+	    	"image_guid" : "",
+	    	"name" : "",
+			"media" : "",
+			"item": 3,
+			"height": 6208,
+			"width": 4704,
+			"created": ""
+	    }
+	},{
+	    "model": "iconolab.ImageStats",
+	    "pk": 3,
+	    "fields": {
+	    	"image": 3,
+	    	"annotations_count": 0,
+			"submitted_revisions_count": 0,
+			"comments_count": 0,
+			"folders_inclusion_count": 0,
+			"tag_count": 0
+	    }
+	},{
+	    "model": "iconolab.Collection",
+	    "pk": 2,
+	    "fields": {
+	    	"name": "",
+	    	"verbose_name": ""
+	    }
+	},{
+	    "model": "iconolab.Item",
+	    "pk": 4,
+	    "fields": {
+	    	"collection": 2,
+	    	"item_guid": ""
+	    }
+	},{
+	    "model": "iconolab.ItemMetadata",
+	    "pk": 4,
+	    "fields": {
+	    	"item": 4
+	    }
+	},{
+	    "model": "iconolab.Image",
+	    "pk": 4,
+	    "fields": {
+	    	"image_guid" : "",
+	    	"name" : "",
+			"media" : "",
+			"item": 4,
+			"height": 704,
+			"width": 704,
+			"created": ""
+	    }
+	},{
+	    "model": "iconolab.ImageStats",
+	    "pk": 4,
+	    "fields": {
+	    	"image": 4,
+	    	"annotations_count": 0,
+			"submitted_revisions_count": 0,
+			"comments_count": 0,
+			"folders_inclusion_count": 0,
+			"tag_count": 0
+	    }
+	},{
+	    "model": "iconolab.Image",
+	    "pk": 5,
+	    "fields": {
+	    	"image_guid" : "",
+	    	"name" : "",
+			"media" : "",
+			"item": 4,
+			"height": 704,
+			"width": 704,
+			"created": ""
+	    }
+	},{
+	    "model": "iconolab.ImageStats",
+	    "pk": 5,
+	    "fields": {
+	    	"image": 5,
+	    	"annotations_count": 0,
+			"submitted_revisions_count": 0,
+			"comments_count": 0,
+			"folders_inclusion_count": 0,
+			"tag_count": 0
+	    }
+	},{
+	    "model": "iconolab.MetaCategory",
+	    "pk": 1,
+	    "fields": {
+	    	"collection": 1,
+	    	"label": "Appel à contribution",
+	    	"triggers_notifications": 1
+	    }
+	},{
+	    "model": "iconolab.MetaCategory",
+	    "pk": 2,
+	    "fields": {
+	    	"collection": 1,
+	    	"label": "Appel à expertise",
+	    	"triggers_notifications": 3
+	    }
+	},{
+	    "model": "iconolab.MetaCategory",
+	    "pk": 3,
+	    "fields": {
+	    	"collection": 1,
+	    	"label": "Référence"
+	    }
+	},{
+	    "model": "iconolab.MetaCategory",
+	    "pk": 4,
+	    "fields": {
+	    	"collection": 1,
+	    	"label": "Accord"
+	    }
+	},{
+	    "model": "iconolab.MetaCategory",
+	    "pk": 5,
+	    "fields": {
+	    	"collection": 1,
+	    	"label": "Désaccord"
+	    }
+	}
+]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/iconolab_episteme/management/commands/importcollection.py	Tue Jun 26 15:55:08 2018 +0200
@@ -0,0 +1,143 @@
+# -*- coding: UTF-8 -*-
+import json
+import logging
+import os
+import pprint
+import re
+import shutil
+import imghdr
+
+from django.conf import settings
+from django.core.management.base import BaseCommand, CommandError
+from PIL import Image as ImagePIL
+from sorl.thumbnail import get_thumbnail
+
+from iconolab.management.commands.importimages import BaseImportImagesCommand
+from iconolab.models import (Collection, Folder, Image, ImageStats, Item,
+                             ItemMetadata, MetaCategory)
+
+if settings.IMPORT_LOGGER_NAME and settings.LOGGING['loggers'].get(settings.IMPORT_LOGGER_NAME, ''):
+    logger = logging.getLogger(settings.IMPORT_LOGGER_NAME)
+else:
+    logger = logging.getLogger(__name__)
+
+class Command(BaseImportImagesCommand):
+    help = 'import collection image and file from a directory'
+
+    def add_arguments(self, parser):
+        parser.add_argument('source_dir')
+        parser.add_argument(
+            '--encoding',
+            dest='encoding',
+            default='utf-8',
+            help='JSON file encoding'
+
+        )
+        parser.add_argument(
+            '--collection-json',
+            dest='collection_json',
+            default=False,
+            help='creates a new collection from a json file, must be an object with fields : '+ 
+                 '"name" (identifier), '+ 
+                 '"verbose_name" (proper title name), '+ 
+                 '"description" (description on homepage, html is supported), '+ 
+                 '"image" (image on homepages, must be "uploads/<imgname>"), '+ 
+                 '"height" and "width" (height and width of the image)',
+        )
+        parser.add_argument(
+            '--collection-id',
+            dest='collection_id',
+            default=False,
+            help='insert extracted data into the specified collection instead of trying to load a collection fixture',
+        )
+        parser.add_argument(
+            '--no-jpg-conversion',
+            dest='no-jpg-conversion',
+            default=False,
+            help='use this option if you only want the image copied and not converted'
+        )
+
+    def handle(self, *args, **options):
+            
+        print('# Logging with logger '+logger.name)
+        logger.debug('# Initializing command with args: %r', options)
+
+        '''Check we have a collection to store data into'''
+        self.source_dir = options.get('source_dir')
+        print('# Checking collection args')
+        if options.get('collection_json'):
+            print('## Finding collection json data in '+self.source_dir)
+            collection_json_path = os.path.join(
+                self.source_dir, options.get('collection_json'))
+            if not os.path.isfile(collection_json_path):
+                print('### No '+options.get('collection_json') +
+                        '.json file was found in the source directory')
+                raise ValueError(
+                    '!!! Json file '+collection_json_path+' was not found !!!')
+            try:
+                with open(collection_json_path) as json_fixture_file:
+                    collection_data = json.loads(json_fixture_file.read())
+                    for key in ['name', 'verbose_name', 'description', 'image', 'height', 'width']:
+                        if not key in collection_data.keys():
+                            print('!!! Json file '+collection_json_path +
+                                    ' has no '+key+' field !!!')
+                            raise ValueError()
+                    if not collection_data.get('name', ''):
+                        print('!!! Collection data key "name" is empty')
+                        raise ValueError()
+                    if Collection.objects.filter(name=collection_data.get('name')).exists():
+                        print(
+                            '!!! A Collection with the provided name already exists!')
+                        raise ValueError()
+                    if collection_data.get('image', '') and not (collection_data.get('width', 0) and collection_data.get('height', 0)):
+                        print(
+                            '!!! Collection data has an image but no height and width')
+                        raise ValueError()
+            except ValueError as e:
+                raise ValueError('!!! JSON Data is invalid. !!!')
+        elif options.get('collection_id'):
+            print('## Finding collection with id ' + 
+                    options.get('collection_id'))
+            try:
+                collection = Collection.objects.get(
+                    pk=options.get('collection_id'))
+            except Collection.DoesNotExist:
+                raise ValueError('!!! Collection with primary key ' +
+                                    options.get('collection_id')+' was not found, aborting !!!')
+        else:
+            raise ValueError(
+                '!!! No collection fixture or collection id, aborting because we can\'t properly generate data. !!!')
+
+
+        '''Import image collection in target directory'''
+           
+        if options.get('collection_json'):
+            print('## Loading collection json')
+            collection = Collection.objects.create(
+                name=collection_data.get('name'),
+                verbose_name=collection_data.get('verbose_name', ''),
+                description=collection_data.get('description', ''),
+                image=collection_data.get('image', ''),
+                height=collection_data.get('height', 0),
+                width=collection_data.get('width', 0),
+            )
+
+            if collection.image:
+                collection_image_path = os.path.join(
+                    settings.MEDIA_ROOT, str(collection.image))
+                if not os.path.isfile(collection_image_path):
+                    print('### Moving collection image')
+                    _, collection_image_name = os.path.split(
+                        collection_image_path)
+                    try:
+                        col_im = ImagePIL.open(os.path.join(
+                            self.source_dir, collection_image_name))
+                        print('##### Generating or copying jpeg for ' +
+                                collection_image_name)
+                        col_im.thumbnail(col_im.size)
+                        col_im.save(collection_image_path, 'JPEG', quality=options.get(
+                            'jpeg_quality', settings.IMG_JPG_DEFAULT_QUALITY))
+                    except Exception as e:
+                        print(e)
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/iconolab_episteme/management/commands/importimages.py	Tue Jun 26 15:55:08 2018 +0200
@@ -0,0 +1,130 @@
+# -*- coding: UTF-8 -*-
+import json
+import logging
+import os
+import pprint
+import re
+import shutil
+import imghdr
+
+from django.conf import settings
+from django.core.management.base import BaseCommand, CommandError
+from PIL import Image as ImagePIL
+from sorl.thumbnail import get_thumbnail
+
+from iconolab.management.commands.importimages import BaseImportImagesCommand
+from iconolab.models import (Collection, Folder, Image, ImageStats, Item,
+                             ItemMetadata, MetaCategory)
+
+if settings.IMPORT_LOGGER_NAME and settings.LOGGING['loggers'].get(settings.IMPORT_LOGGER_NAME, ''):
+    logger = logging.getLogger(settings.IMPORT_LOGGER_NAME)
+else:
+    logger = logging.getLogger(__name__)
+
+class Command(BaseImportImagesCommand):
+    help = 'import images from a directory into the media folder and creates item and image objects'
+
+    def add_arguments(self, parser):
+        parser.add_argument('source_dir')
+        parser.add_argument(
+            '--encoding',
+            dest='encoding',
+            default='utf-8',
+            help='JSON file encoding'
+
+        )
+        parser.add_argument(
+            '--collection-id',
+            dest='collection_id',
+            default=False,
+            help='insert extracted data into the specified collection instead of trying to load a collection fixture',
+        )
+        parser.add_argument(
+            '--no-jpg-conversion',
+            dest='no-jpg-conversion',
+            default=False,
+            help='use this option if you only want the image copied and not converted'
+        )
+        parser.add_argument(
+            '--folders',
+            dest='import_folders',
+            default=False,
+            action='store_const',
+            const=True,
+            help='option to create folders'
+        )
+        # parser.add_argument(
+        #     '--folders-regexp',
+        #     dest='folders_regexp',
+        #     default=False,
+        #     help='regexp used to extract the folder name/number'
+        # )
+        # parser.add_argument(
+        #     '--folders-metadata',
+        #     dest='folders_metadata',
+        #     default='REF',
+        #     help='metadata from which to extract the folder name/number'
+        # )
+
+    def handle(self, *args, **options):
+
+        print('# Logging with logger '+logger.name)
+        logger.debug('# Initializing command with args: %r', options)
+      
+        self.source_dir = options.get('source_dir')
+
+        if options.get('collection_id'):
+            print('## Finding collection with id ' + 
+                    options.get('collection_id'))
+            try:
+                collection = Collection.objects.get(
+                    pk=options.get('collection_id'))
+            except Collection.DoesNotExist:
+                raise ValueError('!!! Collection with primary key ' +
+                                    options.get('collection_id')+' was not found, aborting !!!')
+        else:
+            raise ValueError(
+                '!!! No collection fixture or collection id, aborting because we can\'t properly generate data. !!!')
+
+
+        '''Listing image files in target directory'''
+
+        print(
+            '## Converting image and moving it to static dir, creating Image and Item objects')
+        print('### Images will be stored in ' + os.path.join(settings.MEDIA_ROOT,'uploads'))
+
+        for dirname, dirs, files in os.walk(self.source_dir):
+            for filename in files:
+                filename_without_extension, extension = os.path.splitext(filename)
+                if imghdr.what(os.path.join(dirname, filename)) is None:
+                    continue
+
+                json_path = os.path.join(dirname, filename_without_extension + ".json")
+                if not os.path.isfile(json_path):
+                    continue
+
+                with open(json_path) as json_data:
+                    eso_data = json.load(json_data)
+                    eso_object = eso_data['object']
+                    eso_image = eso_data['image']
+                
+                    path_images = os.path.join(filename_without_extension, filename)
+                    image_list = [path_images]
+                    image_dir = filename_without_extension
+
+                    natural_key = ItemMetadata.get_natural_key(collection, eso_image['id'])
+
+                    if ItemMetadata.objects.filter(item__collection=collection, natural_key=natural_key).exists():
+                        print('#### An item with ' +
+                            natural_key +' for natural key, already exists in database in the import collection')
+                    else:
+                        try:
+                            os.mkdir(os.path.join(settings.MEDIA_ROOT,'uploads', image_dir))
+                            print(image_dir, "directory created")
+                        except FileExistsError:
+                            print(image_dir, "directory already exists")
+
+                        self.create_item_and_metadata(
+                            natural_key, collection, eso_data, image_list, options, self.source_dir)
+
+        print('# All done!')
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/iconolab_episteme/management/commands/importmetacategories.py	Tue Jun 26 15:55:08 2018 +0200
@@ -0,0 +1,90 @@
+# -*- coding: UTF-8 -*-
+import json
+import logging
+import os
+import pprint
+import re
+import shutil
+
+from django.conf import settings
+from django.core.management.base import BaseCommand, CommandError
+
+from iconolab.management.commands.importimages import BaseImportImagesCommand
+from iconolab.models import (Collection, Folder, Image, ImageStats, Item,
+                             ItemMetadata, MetaCategory)
+
+if settings.IMPORT_LOGGER_NAME and settings.LOGGING['loggers'].get(settings.IMPORT_LOGGER_NAME, ''):
+    logger = logging.getLogger(settings.IMPORT_LOGGER_NAME)
+else:
+    logger = logging.getLogger(__name__)
+
+class Command(BaseImportImagesCommand):
+    help = 'import metacategories files from a directory'
+
+    def add_arguments(self, parser):
+        parser.add_argument('source_dir')
+        parser.add_argument(
+            '--encoding',
+            dest='encoding',
+            default='utf-8',
+            help='JSON file encoding'
+
+        )
+        parser.add_argument(
+            '--collection-id',
+            dest='collection_id',
+            default=False,
+            help='insert extracted data into the specified collection instead of trying to load a collection fixture',
+        )
+        parser.add_argument(
+            '--metacategories-json',
+            dest='metacategories_json',
+            default=False,
+            help='add metacategories to the collection from a json file (json must be a list of object with "label" and "triggers_notifications" fields)',
+        )
+    
+    def handle(self, *args, **options):
+        
+        print('# Logging with logger '+logger.name)
+        logger.debug('# Initializing command with args: %r', options)
+
+        self.source_dir = options.get('source_dir')
+
+        if options.get('collection_id'):
+            print('## Finding collection with id ' + 
+                    options.get('collection_id'))
+            try:
+                collection = Collection.objects.get(
+                    pk=options.get('collection_id'))
+            except Collection.DoesNotExist:
+                raise ValueError('!!! Collection with primary key ' +
+                                    options.get('collection_id')+' was not found, aborting !!!')
+        else:
+            raise ValueError(
+                '!!! No collection fixture or collection id, aborting because we can\'t properly generate data. !!!')
+
+        if options.get('metacategories_json'):
+            print('## Finding metacategories fixture json data in '+self.source_dir)
+        metacategories_json_path = os.path.join(
+            self.source_dir, options.get('metacategories_json'))
+        if not os.path.isfile(metacategories_json_path):
+            print('### No '+options.get('metacategories_json')+
+                '.json file was found in the source directory')
+            raise ValueError(
+                '!!! Fixture file '+metacategories_json_path+' was not found !!!')
+        with open(metacategories_json_path) as metacategories_json_file:
+            metacategories_data = json.loads(
+                metacategories_json_file.read())
+            for metacategory in metacategories_data:
+                if metacategory.get('label', None) is None:
+                    raise ValueError(
+                        '!!! Metacategory without label !!!')
+
+        if options.get('metacategories_json'):
+            for metacategory in metacategories_data:
+                MetaCategory.objects.create(
+                    collection=collection,
+                    label=metacategory.get('label'),
+                    triggers_notifications=metacategory.get(
+                        'triggers_notifications', 0)
+                )
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/iconolab_episteme/settings/__init__.py	Tue Jun 26 15:55:08 2018 +0200
@@ -0,0 +1,167 @@
+"""
+Django settings for iconolab-episteme project.
+
+Generated by 'django-admin startproject' using Django 1.9.5.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/1.9/topics/settings/
+
+For the full list of settings and their values, see
+https://docs.djangoproject.com/en/1.9/ref/settings/
+"""
+
+import os, logging, sys
+
+
+# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+
+STATIC_ROOT = os.path.abspath(os.path.join(BASE_DIR, '../../../run/web/static/site'))
+MEDIA_ROOT = os.path.abspath(os.path.join(BASE_DIR, '../../../run/web'))
+
+BASE_URL = ''
+STATIC_URL = '/static/'
+MEDIA_URL = '/media/'
+
+LOGIN_URL = '/account/login/'
+
+#Static path
+
+
+# Quick-start development settings - unsuitable for production
+# See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/
+
+# SECURITY WARNING: keep the secret key used in production secret!
+SECRET_KEY = '#8)+upuo3vc7fi15czxz53ml7*(1__q8hg=m&+9ylq&st1_kqv'
+
+# SECURITY WARNING: don't run with debug turned on in production!
+DEBUG = True
+THUMBNAIL_DEBUG = True
+
+ALLOWED_HOSTS = []
+
+
+# Application definition
+
+INSTALLED_APPS = [
+    'iconolab_episteme',
+    'iconolab.apps.IconolabApp',
+    'django.contrib.admin',
+    'django.contrib.auth',
+    'django.contrib.contenttypes',
+    'django.contrib.sessions',
+    'django.contrib.messages',
+    'django.contrib.staticfiles',
+    'django.contrib.sites',
+    'django.contrib.humanize',
+    'django_comments',
+    'django_comments_xtd',
+    'django_elasticsearch_dsl',
+    'sorl.thumbnail',
+    'notifications',
+]
+
+COMMENTS_APP = "django_comments_xtd"
+COMMENTS_XTD_MODEL = "iconolab.models.IconolabComment"
+COMMENTS_XTD_FORM_CLASS = 'iconolab.forms.comments.IconolabCommentForm'
+COMMENTS_XTD_MAX_THREAD_LEVEL = 100
+COMMENTS_PER_PAGE_DEFAULT = 10
+
+SITE_ID = 1
+
+MIDDLEWARE = [
+    'django.middleware.security.SecurityMiddleware',
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.middleware.common.CommonMiddleware',
+    'django.middleware.csrf.CsrfViewMiddleware',
+    'django.contrib.auth.middleware.AuthenticationMiddleware',
+    'django.contrib.messages.middleware.MessageMiddleware',
+    'django.middleware.clickjacking.XFrameOptionsMiddleware',
+]
+
+ROOT_URLCONF = 'iconolab_episteme.urls'
+
+TEMPLATES = [
+    {
+        'BACKEND': 'django.template.backends.django.DjangoTemplates',
+        'DIRS': [os.path.join(BASE_DIR,'iconolab_episteme', 'templates')],
+        'APP_DIRS': True,
+        'OPTIONS': {
+            'context_processors': [
+                'django.template.context_processors.debug',
+                'django.template.context_processors.request',
+                'django.contrib.auth.context_processors.auth',
+                'django.contrib.messages.context_processors.messages',
+                'django.core.context_processors.media',
+                'django.core.context_processors.static',
+                'django.core.context_processors.i18n',
+                'iconolab.utils.context_processors.env',
+            ],
+        },
+    },
+]
+
+WSGI_APPLICATION = 'iconolab_episteme.wsgi.application'
+
+
+# Database
+# https://docs.djangoproject.com/en/1.9/ref/settings/#databases
+CACHES = {
+    'default': {
+        'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
+        'LOCATION': os.path.join(MEDIA_ROOT, 'cache'),
+#        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
+#        'LOCATION': 'unix:/var/run/memcached/memcached.socket',
+#        'KEY_PREFIX': 'ldt',
+    }
+}
+# Password validation
+# https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators
+
+AUTH_PASSWORD_VALIDATORS = [
+    {
+        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
+    },
+    {
+        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
+    },
+    {
+        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
+    },
+    {
+        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
+    },
+]
+
+
+# Internationalization
+# https://docs.djangoproject.com/en/1.9/topics/i18n/
+
+TIME_ZONE = 'UTC'
+
+USE_I18N = True
+
+USE_L10N = True
+
+USE_TZ = True
+
+# IMPORT_DEFAULT_FIELD_TO_FILENAME_IDENTIFIER = "INV"
+NO_IMG_CONVERSION_EXTS = [".jpg"]
+IMG_CONVERSION_EXTS = [".tif", ".tiff"]
+IMG_JPG_DEFAULT_QUALITY = 80
+PREGENERATE_THUMBNAILS_SIZES = [
+    # item_images_preview.html
+    "250x250",
+    "100x100",
+]
+IMPORT_LOG_FILE = ""
+IMPORT_LOGGER_NAME = ""
+
+DJANGO_RUNSERVER = (len(sys.argv)>1 and sys.argv[1] == 'runserver')
+
+RELEVANT_TAGS_MIN_SCORE = 3
+ACCURATE_TAGS_MIN_SCORE = 3
+
+# The different thumbnail sizes that we want to pre-generate when importing or when updating collections using commands
+# This allows to pre-calculate thumbnails for media-heavy pages such as collection_home
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/iconolab_episteme/settings/dev.py	Tue Jun 26 15:55:08 2018 +0200
@@ -0,0 +1,233 @@
+"""
+Django settings for iconolab-episteme project.
+
+Generated by 'django-admin startproject' using Django 1.9.5.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/1.9/topics/settings/
+
+For the full list of settings and their values, see
+https://docs.djangoproject.com/en/1.9/ref/settings/
+"""
+import logging
+import os
+
+from iconolab_episteme.settings import *
+
+CONTACT_EMAIL = 'youremail@yourprovider.fr'
+
+# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
+# BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+
+# STATIC_ROOT = os.path.abspath(os.path.join(BASE_DIR, '../../../run/web/static/site'))
+# MEDIA_ROOT = os.path.abspath(os.path.join(BASE_DIR, '../../../run/web'))
+BASE_DIR = '/mnt/c/Users/Riwad/Desktop/IRI/ICONOLAB/iconolab-episteme/src/iconolab_episteme'
+
+STATIC_ROOT =  '/mnt/c/Users/Riwad/Desktop/IRI/ICONOLAB/iconolab-episteme/run/web/static/site'
+MEDIA_ROOT = '/mnt/c/Users/Riwad/Desktop/IRI/ICONOLAB/iconolab-episteme/run/web/media'
+
+# dev_mode useful for src_js
+# We need to add 'iconolab.utils.context_processors.env' to context processor
+
+# When JS_DEV_MODE is True, the Webpack dev server should be started
+JS_DEV_MODE = False
+# STATICFILES_DIRS = [
+#     os.path.join(BASE_DIR, 'static'),
+#     os.path.join(BASE_DIR, 'media'),
+# ]
+
+if JS_DEV_MODE:
+    SRC_JS_PATH = os.path.join(BASE_DIR, '..', '..', 'src_js')
+    STATICFILES_DIRS.append(SRC_JS_PATH)
+
+
+BASE_URL = 'http://localhost:8000'
+if JS_DEV_MODE:
+    STATIC_URL = 'http://localhost:8001/static/'
+else:
+    STATIC_URL = '/static/'
+MEDIA_URL = '/media/'
+
+LOGIN_URL = '/account/login/'
+
+# Quick-start development settings - unsuitable for production
+# See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/
+
+# SECURITY WARNING: keep the secret key used in production secret!
+SECRET_KEY = '#8)+upuo3vc7fi15czxz53ml7*(1__q8hg=m&+9ylq&st1_kqv'
+
+# SECURITY WARNING: don't run with debug turned on in production!
+DEBUG = True
+THUMBNAIL_DEBUG = True
+
+ALLOWED_HOSTS = []
+
+
+# Application definition
+
+
+COMMENTS_APP = "django_comments_xtd"
+COMMENTS_XTD_MODEL = "iconolab.models.IconolabComment"
+COMMENTS_XTD_FORM_CLASS = 'iconolab.forms.comments.IconolabCommentForm'
+COMMENTS_XTD_MAX_THREAD_LEVEL = 1
+COMMENTS_PER_PAGE_DEFAULT = 10
+
+SITE_ID = 1
+
+TEMPLATES = [
+    {
+        'BACKEND': 'django.template.backends.django.DjangoTemplates',
+        'DIRS': [],
+        'APP_DIRS': True,
+        'OPTIONS': {
+            'context_processors': [
+                'django.template.context_processors.debug',
+                'django.template.context_processors.request',
+                'django.contrib.auth.context_processors.auth',
+                'django.contrib.messages.context_processors.messages',
+                'django.template.context_processors.media',
+                'django.template.context_processors.static',
+                'django.template.context_processors.i18n',
+                'iconolab.utils.context_processors.env',
+            ],
+            # 'libraries': {
+            #     'iconolab_episteme_tags':'iconolab_episteme.templatetags.iconolab_episteme_tags'
+            # }
+        },
+    },
+]
+
+WSGI_APPLICATION = 'iconolab_episteme.wsgi.application'
+
+
+# Database
+# https://docs.djangoproject.com/en/1.9/ref/settings/#databases
+
+DATABASES = {
+    'default': {
+        'ENGINE': 'django.db.backends.postgresql_psycopg2', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
+        'NAME': 'iconolabepisteme',                      # Or path to database file if using sqlite3.
+        'USER': 'iri',                      # Not used with sqlite3.
+        'PASSWORD': 'iri',                  # Not used with sqlite3.
+        'HOST': '192.168.99.100',                      # Set to empty string for localhost. Not used with sqlite3.
+        'PORT': '5432',                      # Set to empty string for default. Not used with sqlite3.
+    }
+}
+
+# Logging
+
+LOG_FILE = os.path.abspath(os.path.join(BASE_DIR,"../../run/log/log.txt"))
+IMPORT_LOG_FILE = os.path.abspath(os.path.join(BASE_DIR,"../../run/log/import_log.txt"))
+IMPORT_LOGGER_NAME = "import_command"
+LOG_LEVEL = logging.DEBUG
+LOGGING = {
+    'version': 1,
+    'disable_existing_loggers': True,
+    'filters': {
+        'require_debug_false': {
+            '()': 'django.utils.log.RequireDebugFalse'
+        }
+    },
+    'formatters' : {
+        'simple' : {
+            'format': "%(asctime)s - %(levelname)s : %(message)s",
+        },
+        'semi-verbose': {
+            'format': '%(levelname)s %(asctime)s %(module)s %(message)s'
+        },
+    },
+    'handlers': {
+        'mail_admins': {
+            'level': 'ERROR',
+            'filters': ['require_debug_false'],
+            'class': 'django.utils.log.AdminEmailHandler'
+        },
+        'stream_to_console': {
+            'level': LOG_LEVEL,
+            'class': 'logging.StreamHandler'
+        },
+        'file': {
+            'level': LOG_LEVEL,
+            'class': 'logging.FileHandler',
+            'filename': LOG_FILE,
+            'formatter': 'semi-verbose',
+        },
+        'import_file': {
+            'level': LOG_LEVEL,
+            'class': 'logging.FileHandler',
+            'filename': IMPORT_LOG_FILE,
+            'formatter': 'semi-verbose',
+        }
+    },
+    'loggers': {
+        'django.request': {
+            'handlers': ['file'],
+            'level': LOG_LEVEL,
+            'propagate': True,
+        },
+        'iconolab': {
+            'handlers': ['file'],
+            'level': LOG_LEVEL,
+            'propagate': True,
+        },
+        'import_command': {
+            'handlers': ['import_file'],
+            'level': LOG_LEVEL,
+            'propagate': True,
+        },
+    }
+}
+
+ELASTICSEARCH_DSL = {
+    'default': {
+        'hosts': '192.168.99.100:9200'
+    },
+}
+
+CACHES = {
+    'default': {
+        'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
+        'LOCATION': os.path.join(MEDIA_ROOT, 'cache'),
+#        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
+#        'LOCATION': 'unix:/var/run/memcached/memcached.socket',
+#        'KEY_PREFIX': 'ldt',
+    }
+}
+# Password validation
+# https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators
+
+AUTH_PASSWORD_VALIDATORS = [
+    {
+        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
+    },
+    {
+        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
+    },
+    {
+        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
+    },
+    {
+        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
+    },
+]
+
+
+# Internationalization
+# https://docs.djangoproject.com/en/1.9/topics/i18n/
+
+LANGUAGE_CODE = 'en-us'
+
+TIME_ZONE = 'UTC'
+
+USE_I18N = True
+
+USE_L10N = True
+
+USE_TZ = True
+
+INTERNAL_TAGS_URL = BASE_URL
+
+ESO_NOTICE_BASE_URL = "https://www.eso.org/public/france/images/"
+
+RELEVANT_TAGS_MIN_SCORE = 3
+ACCURATE_TAGS_MIN_SCORE = 3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/iconolab_episteme/settings/dev.py.tmpl	Tue Jun 26 15:55:08 2018 +0200
@@ -0,0 +1,249 @@
+"""
+Django settings for iconolab project.
+
+Generated by 'django-admin startproject' using Django 1.9.5.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/1.9/topics/settings/
+
+For the full list of settings and their values, see
+https://docs.djangoproject.com/en/1.9/ref/settings/
+"""
+import logging
+import os
+
+from iconolab_episteme.settings import *
+
+CONTACT_EMAIL = 'youremail@yourprovider.fr'
+
+# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+
+STATIC_ROOT = os.path.join(BASE_DIR, '../../web/static/site')
+MEDIA_ROOT = os.path.join(BASE_DIR, '../../web/media')
+
+# dev_mode useful for src_js
+# We need to add 'iconolab.utils.context_processors.env' to context processor
+
+# When JS_DEV_MODE is True, the Webpack dev server should be started
+JS_DEV_MODE = False
+# STATICFILES_DIRS = [
+#     os.path.join(BASE_DIR, 'static'),
+#     os.path.join(BASE_DIR, 'media'),
+# ]
+
+if JS_DEV_MODE:
+    SRC_JS_PATH = os.path.join(BASE_DIR, '..', '..', 'src_js')
+    STATICFILES_DIRS.append(SRC_JS_PATH)
+
+
+BASE_URL = 'http://localhost:8000'
+if JS_DEV_MODE:
+    STATIC_URL = 'http://localhost:8001/static/'
+else:
+    STATIC_URL = '/static/'
+MEDIA_URL = '/media/'
+
+LOGIN_URL = '/account/login/'
+
+# Quick-start development settings - unsuitable for production
+# See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/
+
+# SECURITY WARNING: keep the secret key used in production secret!
+SECRET_KEY = '#8)+upuo3vc7fi15czxz53ml7*(1__q8hg=m&+9ylq&st1_kqv'
+
+# SECURITY WARNING: don't run with debug turned on in production!
+DEBUG = True
+THUMBNAIL_DEBUG = True
+
+ALLOWED_HOSTS = []
+
+
+# Application definition
+
+
+COMMENTS_APP = "django_comments_xtd"
+COMMENTS_XTD_MODEL = "iconolab.models.IconolabComment"
+COMMENTS_XTD_FORM_CLASS = 'iconolab.forms.comments.IconolabCommentForm'
+COMMENTS_XTD_MAX_THREAD_LEVEL = 1
+COMMENTS_PER_PAGE_DEFAULT = 10
+
+SITE_ID = 1
+
+TEMPLATES = [
+    {
+        'BACKEND': 'django.template.backends.django.DjangoTemplates',
+        'DIRS': [os.path.join(BASE_DIR,'iconolab_episteme','templates')],
+        'APP_DIRS': True,
+        'OPTIONS': {
+            'context_processors': [
+                'django.template.context_processors.debug',
+                'django.template.context_processors.request',
+                'django.contrib.auth.context_processors.auth',
+                'django.contrib.messages.context_processors.messages',
+                'django.template.context_processors.media',
+                'django.template.context_processors.static',
+                'django.template.context_processors.i18n',
+                'iconolab.utils.context_processors.env',
+            ],
+            'libraries': {
+                'iconolab_episteme_tags':'iconolab_episteme.templatetags.iconolab_episteme_tags'
+            }
+        },
+    },
+]
+
+WSGI_APPLICATION = 'iconolab_episteme.wsgi.application'
+
+
+# Database
+# https://docs.djangoproject.com/en/1.9/ref/settings/#databases
+
+DATABASES = {
+    'default': {
+        'ENGINE': 'django.db.backends.postgresql_psycopg2', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
+        'NAME': '',                      # Or path to database file if using sqlite3.
+        'USER': '',                      # Not used with sqlite3.
+        'PASSWORD': '',                  # Not used with sqlite3.
+        'HOST': '',                      # Set to empty string for localhost. Not used with sqlite3.
+        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
+    }
+}
+
+# Logging
+
+LOG_FILE = os.path.abspath(os.path.join(BASE_DIR,"../../run/log/log.txt"))
+IMPORT_LOG_FILE = os.path.abspath(os.path.join(BASE_DIR,"../../run/log/import_log.txt"))
+IMPORT_LOGGER_NAME = "import_command"
+LOG_LEVEL = logging.DEBUG
+LOGGING = {
+    'version': 1,
+    'disable_existing_loggers': True,
+    'filters': {
+        'require_debug_false': {
+            '()': 'django.utils.log.RequireDebugFalse'
+        }
+    },
+    'formatters' : {
+        'simple' : {
+            'format': "%(asctime)s - %(levelname)s : %(message)s",
+        },
+        'semi-verbose': {
+            'format': '%(levelname)s %(asctime)s %(module)s %(message)s'
+        },
+    },
+    'handlers': {
+        'mail_admins': {
+            'level': 'ERROR',
+            'filters': ['require_debug_false'],
+            'class': 'django.utils.log.AdminEmailHandler'
+        },
+        'stream_to_console': {
+            'level': LOG_LEVEL,
+            'class': 'logging.StreamHandler'
+        },
+        'file': {
+            'level': LOG_LEVEL,
+            'class': 'logging.FileHandler',
+            'filename': LOG_FILE,
+            'formatter': 'semi-verbose',
+        },
+        'import_file': {
+            'level': LOG_LEVEL,
+            'class': 'logging.FileHandler',
+            'filename': IMPORT_LOG_FILE,
+            'formatter': 'semi-verbose',
+        }
+    },
+    'loggers': {
+        'django.request': {
+            'handlers': ['file'],
+            'level': LOG_LEVEL,
+            'propagate': True,
+        },
+        'iconolab': {
+            'handlers': ['file'],
+            'level': LOG_LEVEL,
+            'propagate': True,
+        },
+        'import_command': {
+            'handlers': ['import_file'],
+            'level': LOG_LEVEL,
+            'propagate': True,
+        },
+    }
+}
+
+ELASTICSEARCH_DSL = {
+    'default': {
+        'hosts': 'localhost:9200'
+    },
+}
+
+CACHES = {
+    'default': {
+        'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
+        'LOCATION': os.path.join(MEDIA_ROOT, 'cache'),
+#        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
+#        'LOCATION': 'unix:/var/run/memcached/memcached.socket',
+#        'KEY_PREFIX': 'ldt',
+    }
+}
+# Password validation
+# https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators
+
+AUTH_PASSWORD_VALIDATORS = [
+    {
+        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
+    },
+    {
+        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
+    },
+    {
+        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
+    },
+    {
+        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
+    },
+]
+
+
+# Internationalization
+# https://docs.djangoproject.com/en/1.9/topics/i18n/
+
+LANGUAGE_CODE = 'en-us'
+
+TIME_ZONE = 'UTC'
+
+USE_I18N = True
+
+USE_L10N = True
+
+USE_TZ = True
+
+
+IMPORT_FIELDS_DICT = {
+    "AUTR": [],
+    "ECOLE": [],
+    "TITR": ["Titre"],
+    "DENO": [],
+    "DOM": ["Domaine"],
+    "APPL": [],
+    "PERI": ["Période"],
+    "MILL": [],
+    "TECH": [],
+    "DIMS": ["Dimensions"],
+    "EPOQ": [],
+    "LIEUX": [],
+    "DECV": [],
+    "LOCA": ["Localisation"],
+    "PHOT": ["Photo"],
+    "INV": ["No inventaire",],
+    "REF": ["REFERENCE"],
+}
+
+INTERNAL_TAGS_URL = BASE_URL
+JOCONDE_NOTICE_BASE_URL = "http://www.culture.gouv.fr/public/mistral/joconde_fr?ACTION=CHERCHER&FIELD_98=REF&VALUE_98="
+
+RELEVANT_TAGS_MIN_SCORE = 3
+ACCURATE_TAGS_MIN_SCORE = 3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/iconolab_episteme/templates/iconolab/metadatas/detail_image_metadatas.html	Tue Jun 26 15:55:08 2018 +0200
@@ -0,0 +1,15 @@
+{% load iconolab_episteme_tags %}
+
+<dl class="dl-horizontal">
+  {% if item.metadatas.metadata_obj.image.title %}<dt>Titre</dt><dd>{{item.metadatas.metadata_obj.image.title}}</dd>{% endif %}
+  {% if item.metadatas.metadata_obj.image.description_html %}<dt>Description</dt><dd>{{item.metadatas.metadata_obj.image.description_html|safe}}</dd>{% endif %}
+  {% if item.metadatas.metadata_obj.image.credit %}<dt>Crédits</dt><dd>{{item.metadatas.metadata_obj.image.credit}}</dd>{% endif %}
+  {% if item.metadatas.metadata_obj.image.id %}<dt>Identification</dt><dd>{{item.metadatas.metadata_obj.image.id}}</dd>{% endif %}
+</dl>
+{% if item.metadatas.metadata_obj.image.id %}
+<p class="text-center">
+  <a href= "{% eso_link item.metadatas %}" target="_blank">
+  Cet objet dans la base d'images de l'ESO
+  </a>
+</p>
+{% endif %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/iconolab_episteme/templates/iconolab/metadatas/detail_item_metadatas.html	Tue Jun 26 15:55:08 2018 +0200
@@ -0,0 +1,8 @@
+{% load iconolab_episteme_tags %}
+
+{% if item.metadatas.metadata_obj.image.title %}<h3>Titre : <small>{{item.metadatas.metadata_obj.image.title}}</small></h3>{% endif %}
+{% if item.metadatas.metadata_obj.image.description_html %}<h4>Description : <small>{{item.metadatas.metadata_obj.image.description_html|safe}}</small></h4>{% endif %}
+{% if item.metadatas.metadata_obj.image.credit %}<h5>Crédits : <small>{{item.metadatas.metadata_obj.image.credit}}</small></h5>{% endif %}
+{% if item.metadatas.metadata_obj.image.id %}<h5>Identification : <small>{{item.metadatas.metadata_obj.image.id}}</small></h5>{% endif %} 
+{% if item.metadatas.metadata_obj.image.id %}<h5><a href="{% eso_link item.metadatas %}" target="_blank">Cet objet dans la base d'images de l'ESO</a></h5>{% endif %}
+<br>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/iconolab_episteme/templates/iconolab/metadatas/image_search_metadatas.html	Tue Jun 26 15:55:08 2018 +0200
@@ -0,0 +1,4 @@
+{% if item.object.metadatas.metadata_obj.image.title %}<h3>Titre : <small>{{item.object.metadatas.metadata_obj.image.title}}</small></h3>{% endif %}
+{% if item.object.metadatas.metadata_obj.image.description_html %}<h4>Description : <small>{{item.object.metadatas.metadata_obj.image.description_html|safe}}</small></h4>{% endif %}
+{% if item.object.metadatas.metadata_obj.image.credit %}<h5>Crédits : <small>{{item.object.metadatas.metadata_obj.image.credit}}</small></h5>{% endif %}
+{% if item.object.metadatas.metadata_obj.image.id %}<h5>Identification : <small>{{item.object.metadatas.metadata_obj.image.id}}</small></h5>{% endif %}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/iconolab_episteme/templates/iconolab/search/indexes/iconolab/item_text.txt	Tue Jun 26 15:55:08 2018 +0200
@@ -0,0 +1,3 @@
+{{ object.metadatas.metadata_obj.image.title }}
+{{ object.metadatas.metadata_obj.image.description_text }}
+{{ object.metadatas.metadata_obj.image.id }}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/iconolab_episteme/templatetags/iconolab_episteme_tags.py	Tue Jun 26 15:55:08 2018 +0200
@@ -0,0 +1,9 @@
+from django.template import Library
+from django.conf import settings
+
+register = Library()
+
+@register.simple_tag
+def eso_link(item_metadata):
+    return settings.ESO_NOTICE_BASE_URL + item_metadata.raw_natural_key
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/iconolab_episteme/urls.py	Tue Jun 26 15:55:08 2018 +0200
@@ -0,0 +1,40 @@
+"""iconolab_episteme URL Configuration
+
+The `urlpatterns` list routes URLs to views. For more information please see:
+    https://docs.djangoproject.com/en/2.0/topics/http/urls/
+Examples:
+Function views
+    1. Add an import:  from my_app import views
+    2. Add a URL to urlpatterns:  path('', views.home, name='home')
+Class-based views
+    1. Add an import:  from other_app.views import Home
+    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
+Including another URLconf
+    1. Import the include() function: from django.urls import include, path
+    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
+"""
+from django import views as django_views
+from django.conf import settings
+from django.conf.urls.static import static
+from django.contrib import admin
+from django.contrib.staticfiles.urls import staticfiles_urlpatterns
+from django.urls import include, path, re_path, reverse_lazy
+from iconolab_episteme import views
+
+import iconolab.urls
+
+urlpatterns = [
+    
+    path('', include(iconolab.urls)),
+    re_path(r'^$', django_views.generic.RedirectView.as_view(url=reverse_lazy("home"))),
+    path('admin/', admin.site.urls),
+    
+    
+]
+
+
+if settings.DJANGO_RUNSERVER:
+    urlpatterns += staticfiles_urlpatterns()
+    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
+    #static url
+    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/iconolab_episteme/wsgi.py	Tue Jun 26 15:55:08 2018 +0200
@@ -0,0 +1,16 @@
+"""
+WSGI config for iconolab_episteme project.
+
+It exposes the WSGI callable as a module-level variable named ``application``.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/2.0/howto/deployment/wsgi/
+"""
+
+import os
+
+from django.core.wsgi import get_wsgi_application
+
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "iconolab_episteme.settings.dev")
+
+application = get_wsgi_application()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/manage.py	Tue Jun 26 15:55:08 2018 +0200
@@ -0,0 +1,15 @@
+#!/usr/bin/env python
+import os
+import sys
+
+if __name__ == "__main__":
+    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "iconolab_episteme.settings.dev")
+    try:
+        from django.core.management import execute_from_command_line
+    except ImportError as exc:
+        raise ImportError(
+            "Couldn't import Django. Are you sure it's installed and "
+            "available on your PYTHONPATH environment variable? Did you "
+            "forget to activate a virtual environment?"
+        ) from exc
+    execute_from_command_line(sys.argv)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/requirements/base.txt	Tue Jun 26 15:55:08 2018 +0200
@@ -0,0 +1,13 @@
+Django==2.0.6
+django-appconf==1.0.2
+django-comments-xtd==2.1.0
+django-contrib-comments==1.8.0
+elasticsearch-dsl==6.1.0
+django-elasticsearch-dsl==0.5.0
+#django-notifications-hq==1.4.0a0
+git+https://github.com/django-notifications/django-notifications.git#egg=django-notifications-hq
+djangorestframework==3.8.2
+elasticsearch==6.2.0
+Pillow==5.1.0
+requests==2.18.4
+sorl-thumbnail==12.4.1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/requirements/base.txt.in	Tue Jun 26 15:55:08 2018 +0200
@@ -0,0 +1,2 @@
+# must run "pip install -r base.txt.in" in src/requirements
+-e ..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/requirements/dev.txt	Tue Jun 26 15:55:08 2018 +0200
@@ -0,0 +1,2 @@
+-r base.txt
+setuptools_scm
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/requirements/prod.txt	Tue Jun 26 15:55:08 2018 +0200
@@ -0,0 +1,4 @@
+-r base.txt
+pylibmc
+uWSGI
+psycopg2 --no-binary psycopg2