# HG changeset patch # User Riwad Salim # Date 1530021308 -7200 # Node ID df27f9610c827f33928f5dff73e234a8e709fa52 Creating iconolab episteme project diff -r 000000000000 -r df27f9610c82 .hgignore --- /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 diff -r 000000000000 -r df27f9610c82 .vs/slnx.sqlite Binary file .vs/slnx.sqlite has changed diff -r 000000000000 -r df27f9610c82 docker-compose.yml --- /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 + + diff -r 000000000000 -r df27f9610c82 src/LICENSE --- /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. diff -r 000000000000 -r df27f9610c82 src/iconolab_episteme/__init__.py --- /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' diff -r 000000000000 -r df27f9610c82 src/iconolab_episteme/apps.py --- /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 diff -r 000000000000 -r df27f9610c82 src/iconolab_episteme/fixtures/demo_data.json --- /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" + } + } +] diff -r 000000000000 -r df27f9610c82 src/iconolab_episteme/management/__init__.py diff -r 000000000000 -r df27f9610c82 src/iconolab_episteme/management/commands/__init__.py diff -r 000000000000 -r df27f9610c82 src/iconolab_episteme/management/commands/importcollection.py --- /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/"), '+ + '"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) + + diff -r 000000000000 -r df27f9610c82 src/iconolab_episteme/management/commands/importimages.py --- /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 diff -r 000000000000 -r df27f9610c82 src/iconolab_episteme/management/commands/importmetacategories.py --- /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 diff -r 000000000000 -r df27f9610c82 src/iconolab_episteme/settings/__init__.py --- /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 + diff -r 000000000000 -r df27f9610c82 src/iconolab_episteme/settings/dev.py --- /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 diff -r 000000000000 -r df27f9610c82 src/iconolab_episteme/settings/dev.py.tmpl --- /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 diff -r 000000000000 -r df27f9610c82 src/iconolab_episteme/templates/iconolab/metadatas/detail_image_metadatas.html --- /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 %} + +
+ {% if item.metadatas.metadata_obj.image.title %}
Titre
{{item.metadatas.metadata_obj.image.title}}
{% endif %} + {% if item.metadatas.metadata_obj.image.description_html %}
Description
{{item.metadatas.metadata_obj.image.description_html|safe}}
{% endif %} + {% if item.metadatas.metadata_obj.image.credit %}
Crédits
{{item.metadatas.metadata_obj.image.credit}}
{% endif %} + {% if item.metadatas.metadata_obj.image.id %}
Identification
{{item.metadatas.metadata_obj.image.id}}
{% endif %} +
+{% if item.metadatas.metadata_obj.image.id %} +

+ + Cet objet dans la base d'images de l'ESO + +

+{% endif %} diff -r 000000000000 -r df27f9610c82 src/iconolab_episteme/templates/iconolab/metadatas/detail_item_metadatas.html --- /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 %}

Titre : {{item.metadatas.metadata_obj.image.title}}

{% endif %} +{% if item.metadatas.metadata_obj.image.description_html %}

Description : {{item.metadatas.metadata_obj.image.description_html|safe}}

{% endif %} +{% if item.metadatas.metadata_obj.image.credit %}
Crédits : {{item.metadatas.metadata_obj.image.credit}}
{% endif %} +{% if item.metadatas.metadata_obj.image.id %}
Identification : {{item.metadatas.metadata_obj.image.id}}
{% endif %} +{% if item.metadatas.metadata_obj.image.id %}
Cet objet dans la base d'images de l'ESO
{% endif %} +
diff -r 000000000000 -r df27f9610c82 src/iconolab_episteme/templates/iconolab/metadatas/image_search_metadatas.html --- /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 %}

Titre : {{item.object.metadatas.metadata_obj.image.title}}

{% endif %} +{% if item.object.metadatas.metadata_obj.image.description_html %}

Description : {{item.object.metadatas.metadata_obj.image.description_html|safe}}

{% endif %} +{% if item.object.metadatas.metadata_obj.image.credit %}
Crédits : {{item.object.metadatas.metadata_obj.image.credit}}
{% endif %} +{% if item.object.metadatas.metadata_obj.image.id %}
Identification : {{item.object.metadatas.metadata_obj.image.id}}
{% endif %} \ No newline at end of file diff -r 000000000000 -r df27f9610c82 src/iconolab_episteme/templates/iconolab/search/indexes/iconolab/item_text.txt --- /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 }} diff -r 000000000000 -r df27f9610c82 src/iconolab_episteme/templatetags/__init__.py diff -r 000000000000 -r df27f9610c82 src/iconolab_episteme/templatetags/iconolab_episteme_tags.py --- /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 + diff -r 000000000000 -r df27f9610c82 src/iconolab_episteme/urls.py --- /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) diff -r 000000000000 -r df27f9610c82 src/iconolab_episteme/wsgi.py --- /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() diff -r 000000000000 -r df27f9610c82 src/manage.py --- /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) diff -r 000000000000 -r df27f9610c82 src/requirements/base.txt --- /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 diff -r 000000000000 -r df27f9610c82 src/requirements/base.txt.in --- /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 .. diff -r 000000000000 -r df27f9610c82 src/requirements/dev.txt --- /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 diff -r 000000000000 -r df27f9610c82 src/requirements/prod.txt --- /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