prepare for server install, mv settings, add setup, correct various problems
authorymh <ymh.work@gmail.com>
Sat, 06 Jun 2015 22:47:54 +0200
changeset 118 fea47f1054e2
parent 117 41a78460bdac
child 119 3922b186a5b2
prepare for server install, mv settings, add setup, correct various problems
.hgignore
server/CHANGES
server/LICENSE
server/sbin/sync/config_path.pth
server/sbin/sync/fabfile.py
server/sbin/sync/settings.py.tmpl
server/setup.py
server/src/__init__.py
server/src/ammico/serializers/extractors.py
server/src/ammico/views.py
server/src/authentication/views.py
server/src/config.py.tmpl
server/src/manage.py
server/src/settings.py
server/src/settings/__init__.py
server/src/settings/dev.py.tmpl
server/virtualenv/requirements.txt
server/virtualenv/requirements_srvr.txt
server/virtualenv/requirements_sync.txt
--- a/.hgignore	Fri Jun 05 16:10:12 2015 +0200
+++ b/.hgignore	Sat Jun 06 22:47:54 2015 +0200
@@ -5,6 +5,10 @@
 ^client/bower_components/
 ^client/build/
 \.project$
-
-syntax: regexp
-^server/config\.py$
\ No newline at end of file
+^server/config\.py$
+^server/sbin/sync/settings\.py$
+^server/MANIFEST
+^server/dist
+^server/run
+^server/web
+^server/src/settings/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/CHANGES	Sat Jun 06 22:47:54 2015 +0200
@@ -0,0 +1,1 @@
+v00.01, 2015-05-29 -- initial release.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/LICENSE	Sat Jun 06 22:47:54 2015 +0200
@@ -0,0 +1,523 @@
+Copyright (c) 2011, IRI (Institute d Recherche de d'Innovation)
+All rights reserved.
+
+
+
+CeCILL-C 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-C (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
+
+The purpose of this Free Software license agreement is to grant users
+the right to modify and re-use the software governed by this license.
+
+The exercising of this right is conditional upon the obligation to make
+available to the community the modifications made to the source code of
+the software so as to contribute to its evolution.
+
+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
+Integrated 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 Integrated
+Contribution.
+
+Licensor: means the Holder, or any other individual or legal entity, who
+distributes the Software under the Agreement.
+
+Integrated Contribution: means any or all modifications, corrections,
+translations, adaptations and/or new functions integrated into the
+Source Code by any or all Contributors.
+
+Related Module: means a set of sources files including their
+documentation that, without modification to the Source Code, enables
+supplementary functions or services in addition to those offered by the
+Software.
+
+Derivative Software: means any combination of the Software, modified or
+not, and of a Related Module.
+
+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 RIGHT OF MODIFICATION
+
+The right of modification includes the right to translate, adapt,
+arrange, or make any or all modifications to the Software, and the right
+to reproduce the resulting software. It includes, in particular, the
+right to create a Derivative Software.
+
+The Licensee is authorized to make any or all modification to the
+Software provided that it includes an explicit notice that it is the
+author of said modification 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
+
+When the Licensee makes an Integrated Contribution to the Software, the
+terms and conditions for the distribution of the resulting Modified
+Software become subject to all the provisions of this Agreement.
+
+The Licensee is authorized to distribute the Modified 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 Modified
+Software is redistributed, the Licensee allows effective access to the
+full source code of the Modified Software at a minimum during the entire
+period of its distribution of the Modified Software, it being understood
+that the additional cost of acquiring the source code shall not exceed
+the cost of transferring the data.
+
+
+        5.3.3 DISTRIBUTION OF DERIVATIVE SOFTWARE
+
+When the Licensee creates Derivative Software, this Derivative Software
+may be distributed under a license agreement other than this Agreement,
+subject to compliance with the requirement to include a notice
+concerning the rights over the Software as defined in Article 6.4.
+In the event the creation of the Derivative Software required modification 
+of the Source Code, the Licensee undertakes that:
+
+   1. the resulting Modified Software will be governed by this Agreement,
+   2. the Integrated Contributions in the resulting Modified Software
+      will be clearly identified and documented,
+   3. the Licensee will allow effective access to the source code of the
+      Modified Software, at a minimum during the entire period of
+      distribution of the Derivative Software, such that such
+      modifications may be carried over in a subsequent version of the
+      Software; it being understood that the additional cost of
+      purchasing the source code of the Modified Software shall not
+      exceed the cost of transferring the data.
+
+
+        5.3.4 COMPATIBILITY WITH THE CeCILL LICENSE
+
+When a Modified Software contains an Integrated Contribution subject to
+the CeCILL license agreement, or when a Derivative Software contains a
+Related Module subject to the CeCILL license agreement, the provisions
+set forth in the third item of Article 6.4 are 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 INTEGRATED CONTRIBUTIONS
+
+The Licensee who develops an Integrated Contribution is the owner of the
+intellectual property rights over this Contribution as defined by
+applicable law.
+
+
+      6.3 OVER THE RELATED MODULES
+
+The Licensee who develops a Related Module is the owner of the
+intellectual property rights over this Related Module as defined by
+applicable law and is free to choose the type of agreement that shall
+govern its distribution under the conditions defined in Article 5.3.3.
+
+
+      6.4 NOTICE OF RIGHTS
+
+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;
+
+   3. to ensure that use of the Software, its intellectual property
+      notices and the fact that it is governed by the Agreement is
+      indicated in a text that is easily accessible, specifically from
+      the interface of any Derivative Software.
+
+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/server/sbin/sync/config_path.pth	Sat Jun 06 22:47:54 2015 +0200
@@ -0,0 +1,3 @@
+import sys; sys.__plen = len(sys.path)
+%(srv_config_path)s
+import sys; new=sys.path[sys.__plen:]; del sys.path[sys.__plen:]; p=getattr(sys,'__egginsert',0); sys.path[p:p]=new; sys.__egginsert = p+len(new)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/sbin/sync/fabfile.py	Sat Jun 06 22:47:54 2015 +0200
@@ -0,0 +1,77 @@
+from fabric.api import env, local, put, run, lcd, task, prefix, sudo
+from fabric.contrib.files import exists, append, upload_template
+from fabric.colors import green
+import tempfile
+import shutil
+import os
+import settings
+
+current_path = os.path.dirname(os.path.realpath(__file__))
+
+def __init():
+    if not env.get('temp_folder', None):
+        env['temp_folder'] = tempfile.mkdtemp()
+        print(green("working folder is %s" % env['temp_folder']))
+
+def __clean():
+    if env.get('temp_folder', None):
+        print(green("Removing %s" % env['temp_folder']))
+        shutil.rmtree(env['temp_folder'])
+
+def get_version_path():
+    return os.path.join(env['temp_folder'], env['version'])
+
+def export():
+    local('hg archive -r %s %s' % (env['version'], get_version_path()) )
+
+def pack():
+    # create a new source distribution as tarball
+    with lcd(get_version_path()):
+        local('python setup.py sdist --formats=gztar', capture=False)
+
+def create_virtualenv():
+    with lcd(get_version_path()):
+        tmpd = run('mktemp -d').strip()
+        put('virtualenv/*.txt', tmpd)
+        run('virtualenv -p %s %s' % (env.srv_python_location,env.srv_venv_path))
+        with prefix('source %s/bin/activate' % env.srv_venv_path):
+            run('pip install -r %s/requirements.txt' % tmpd)
+            run('pip install -r %s/requirements_srvr.txt' % tmpd)
+        with prefix('source %s/bin/activate' % env.srv_venv_path):
+            site_package_location = run('python -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())"').strip()
+            upload_template(os.path.join(current_path,'config_path.pth'), os.path.join(site_package_location,'config_path.pth'),context={"srv_config_path": env.srv_config_path})
+
+        append(os.path.join(env.srv_venv_path, "bin/activate"), "export DJANGO_SETTINGS_MODULE="+env.srv_django_settings_module)
+
+        run('rm -fr %s' % tmpd)
+
+
+def deploy():
+    # figure out the release name and version
+    with lcd(get_version_path()):
+        dist = local('python setup.py --fullname', capture=True).strip()
+        print(green("dist is %s" % dist))
+
+        # upload the source tarball to the temporary folder on the server
+        put('dist/%s.tar.gz' % dist, '/tmp/%s.tar.gz' % dist)
+        # create a place where we can unzip the tarball, then enter
+        # that directory and unzip it
+        # now setup the package with our virtual environment's
+        # python interpreter
+        with prefix('source %s/bin/activate' % env.srv_venv_path):
+            run('pip install -U --force-reinstall /tmp/%s.tar.gz' % dist)
+        # now that all is set up, delete the folder again
+
+        run('rm -rf /tmp/%s.tar.gz' % dist)
+        sudo(env.srv_restart_cmd, shell=False)
+
+@task(default=True)
+def deploy_version(version='tip'):
+    env['version'] = version
+    __init()
+    export()
+    pack()
+    if not exists(env.srv_venv_path):
+        create_virtualenv()
+    deploy()
+    __clean()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/sbin/sync/settings.py.tmpl	Sat Jun 06 22:47:54 2015 +0200
@@ -0,0 +1,12 @@
+from fabric.api import env
+
+
+# the user to use for the remote commands
+env.user = 'user'
+# the servers where the commands are executed
+env.hosts = ['server']
+env.srv_venv_path = 'virtualenv folder path on host'
+env.srv_restart_cmd = '<restart cmd>'
+env.srv_python_location = ''
+env.srv_config_path = '<path for config>'
+env.srv_django_settings_module =  'prod_ammico'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/setup.py	Sat Jun 06 22:47:54 2015 +0200
@@ -0,0 +1,125 @@
+import os
+from distutils.core import setup
+from distutils.command.install_data import install_data
+from distutils.command.install import INSTALL_SCHEMES
+import sys
+
+
+class osx_install_data(install_data):
+    # On MacOS, the platform-specific lib dir is /System/Library/Framework/Python/.../
+    # which is wrong. Python 2.5 supplied with MacOS 10.5 has an Apple-specific fix
+    # for this in distutils.command.install_data#306. It fixes install_lib but not
+    # install_data, which is why we roll our own install_data class.
+
+    def finalize_options(self):
+        # By the time finalize_options is called, install.install_lib is set to the
+        # fixed directory, so we set the installdir to install_lib. The
+        # install_data class uses ('install_data', 'install_dir') instead.
+        self.set_undefined_options('install', ('install_lib', 'install_dir'))
+        install_data.finalize_options(self)
+
+def fullsplit(path, result=None):
+    """
+    Split a pathname into components (the opposite of os.path.join) in a
+    platform-neutral way.
+    """
+    if result is None:
+        result = []
+    head, tail = os.path.split(path)
+    if head == '':
+        return [tail] + result
+    if head == path:
+        return result
+    return fullsplit(head, [tail] + result)
+
+
+def launch_setup(script_name, script_args):
+    if sys.platform == "darwin":
+        cmdclasses = {'install_data': osx_install_data}
+    else:
+        cmdclasses = {'install_data': install_data}
+
+
+    root_dir = os.path.dirname(__file__)
+    if root_dir != '':
+        os.chdir(root_dir)
+    source_dirs = ['src']
+
+    version_variables = {}
+    try:
+        execfile(os.path.join(source_dirs[0], "__init__.py"), version_variables)
+    except:
+        pass
+
+    version = version_variables['__version__']
+
+    packages, data_files = [], []
+
+    for source_dir in source_dirs:
+        for dirpath, dirnames, filenames in os.walk(source_dir):
+            # Ignore dirnames that start with '.'
+            for i, dirname in enumerate(dirnames):
+                if dirname.startswith('.'): del dirnames[i]
+            if '__init__.py' in filenames:
+                packages.append('.'.join(fullsplit(dirpath)))
+            elif filenames:
+                data_files.append([dirpath, [os.path.join(dirpath, f) for f in filenames]])
+
+
+    # Tell distutils to put the data_files in platform-specific installation
+    # locations. See here for an explanation:
+    # http://groups.google.com/group/comp.lang.python/browse_thread/thread/35ec7b2fed36eaec/2105ee4d9e8042cb
+    for scheme in INSTALL_SCHEMES.values():
+        scheme['data'] = scheme['purelib']
+
+    # Small hack for working with bdist_wininst.
+    # See http://mail.python.org/pipermail/distutils-sig/2004-August/004134.html
+    if len(sys.argv) > 1 and sys.argv[1] == 'bdist_wininst':
+        for file_info in data_files:
+            file_info[0] = '\\PURELIB\\%s' % file_info[0]
+
+    #write MANIFEST.in
+
+    with open("MANIFEST.in", "w") as m:
+        m.write("include CHANGES\n")
+        m.write("include LICENSE\n")
+        m.write("include README.md\n")
+        m.write("include MANIFEST.in\n")
+        for entry in data_files:
+            file_list = entry[1]
+            for filename in file_list:
+                m.write("include %s\n" % (filename))
+
+    setup(
+        script_name = script_name,
+        script_args = script_args,
+        name='ammico',
+        version=version,
+        author='IRI',
+        author_email='contact@iri.centrepompidou.fr',
+        packages=packages,
+        data_files=data_files,
+        cmdclass = cmdclasses,
+        scripts=[],
+        url='http://www.iri.centrepompidou.fr/dev/hg/ammico',
+        license='LICENSE',
+        description='Platform ammico',
+        long_description=open('README.md').read(),
+        classifiers=['Development Status :: 4 - Beta',
+                       'Environment :: Web Environment',
+                       'Framework :: Django',
+                       'Intended Audience :: Developers',
+                       'License :: Ceccil-C',
+                       'Operating System :: OS Independent',
+                       'Programming Language :: Python',
+                       'Topic :: Utilities',
+        ],
+    )
+
+
+if __name__ == "__main__":
+
+    script_name = os.path.basename(sys.argv[0])
+    script_args = sys.argv[1:]
+
+    launch_setup(script_name, script_args)
--- a/server/src/__init__.py	Fri Jun 05 16:10:12 2015 +0200
+++ b/server/src/__init__.py	Sat Jun 06 22:47:54 2015 +0200
@@ -0,0 +1,17 @@
+VERSION = (0, 1, 0, "alpha", 0)
+
+VERSION_STR = unicode(".".join(map(lambda i:"%02d" % (i,), VERSION[:2])))
+
+
+def get_version():
+    version = '%s.%s' % (VERSION[0], VERSION[1])
+    if VERSION[2]:
+        version = '%s.%s' % (version, VERSION[2])
+    if VERSION[3] == 'alpha':
+        version = '%s-alpha.%s' % (version, VERSION[4])
+    else:
+        if VERSION[3] != 'final':
+            version = '%s %s %s' % (version, VERSION[3], VERSION[4])
+    return version
+
+__version__ = get_version()
--- a/server/src/ammico/serializers/extractors.py	Fri Jun 05 16:10:12 2015 +0200
+++ b/server/src/ammico/serializers/extractors.py	Sat Jun 06 22:47:54 2015 +0200
@@ -5,13 +5,13 @@
 import xmltodict
 
 from ammico.utils import fetchJson, MyHTMLParser
-from config import URL_EXALEAD, URL_JAMESPOT, URL_ORPHEO
+from django.conf import settings
 
 
 def extractFromMIMO(slide):
     details = {}
-    params = {'of': 'json', 'q': 'record_inventorynumber:' + slide.idInventory} 
-    data = requests.get(URL_EXALEAD, params=params)
+    params = {'of': 'json', 'q': 'record_inventorynumber:' + slide.idInventory}
+    data = requests.get(settings.URL_EXALEAD, params=params)
     results = json.loads(data.content.decode('utf-8'))
     if (len(results['hits']) == 1):
         for i in results['hits'][0]['metas']:
@@ -25,7 +25,7 @@
 
 def extractFromJameSpot(slide):
     details={}
-    stopList = fetchJson(URL_JAMESPOT + '&f=list&o=article&type=stop&itemFormat=article')
+    stopList = fetchJson(settings.URL_JAMESPOT + '&f=list&o=article&type=stop&itemFormat=article')
     for stops in stopList:
         if (slide.idStop == stops['idStop']):
             details = stops
@@ -35,34 +35,34 @@
 
 def extractFromOrpheo(slide):
     details = {}
-    params = {'id': slide.idStop.replace('stop-', '')} 
-    data = requests.get(URL_ORPHEO, params=params)
+    params = {'id': slide.idStop.replace('stop-', '')}
+    data = requests.get(settings.URL_ORPHEO, params=params)
     parsed_data = xmltodict.parse(data.content.decode('utf-8'))
-    
+
     if ('item' in parsed_data['result']):
         details = {
             'title': parsed_data['result']['item']['title'],
             'idInventory': parsed_data['result']['item']['Numero_inventaire'],
         }
         parser = MyHTMLParser()
-        
+
         if (parsed_data['result']['item']['Description']):
             parser.feed(parsed_data['result']['item']['Description'])
             details['description']= parser.description
-            
+
         if (parsed_data['result']['item']['Audio']):
             parser.feed(parsed_data['result']['item']['Audio'])
             details['images']= parser.images
             details['audio']= parser.audio
             details['captions']= parser.captions
-            
+
         if (parsed_data['result']['item']['Video']):
             parser.feed(parsed_data['result']['item']['Video'])
             details['video']= parser.video
             details['images']= parser.images
-            
+
         #if (parsed_data['result']['item']['Image']):
         #    parser.feed(parsed_data['result']['item']['Image'])
         #    details['image']= parser.caption
-        
-    return details
\ No newline at end of file
+
+    return details
--- a/server/src/ammico/views.py	Fri Jun 05 16:10:12 2015 +0200
+++ b/server/src/ammico/views.py	Sat Jun 06 22:47:54 2015 +0200
@@ -17,29 +17,28 @@
 
 from ammico.models import Book, Slide
 from ammico.serializers.ammico import BookSerializer, SlideSerializer
-from config import AUTH_JAMESPOT
+from django.conf import settings
 import jwt
-from settings import URL_JAMESPOT
 
 
 #from django.contrib.auth import login, logout
 User = get_user_model()
 
 def populateVisit(user):
-    # send request with usermail to get the visits of this user and add it to the database 
+    # send request with usermail to get the visits of this user and add it to the database
     #r = requests.get('http://fui-ammico.jamespot.pro/api/api.php?&k=6c8bfcea247e8a5841288269887d88f0&d=2016-01-31&m=EXT-IRI&v=2.0&f=get&o=article&idArticle=169')
 
     #simulate the request
-    params = {'o': 'article', 'f': 'list', 'idUser': user.idUser} 
-    r = requests.get(URL_JAMESPOT, params=params)
+    params = {'o': 'article', 'f': 'list', 'idUser': user.idUser}
+    r = requests.get(settings.URL_JAMESPOT, params=params)
     visits = json.loads(r.content.decode('utf-8'))
-    
+
     for visit in visits['VAL']:
         params = {'o' : 'article', 'f' : 'get', 'idArticle' : visit['idArticle']}
-        r = requests.get(URL_JAMESPOT, params=params)
+        r = requests.get(settings.URL_JAMESPOT, params=params)
         visitInfo = json.loads(r.content.decode('utf-8'))['VAL']
-        
-        
+
+
         if (not Book.objects.filter(idArticle=visit['idArticle']).exists()):
             book = Book.objects.create(
                 user=user,
@@ -54,12 +53,12 @@
 def populateSlide(steps, book):
     for step in steps:
         if (step['stop'] != None and step['stop'] != ''):
-            
+
             if 'comment' in step:
                 description = step['comment']
             else:
                 description = ""
-            
+
             Slide.objects.update_or_create(
                 book=book,
                 idStop=step['stop'],
@@ -75,21 +74,21 @@
     def get(self, request):
         key = ''
         if ('k' in request.GET):
-            payload = jwt.decode(request.GET['k'], AUTH_JAMESPOT, algorithms=['HS256'])
+            payload = jwt.decode(request.GET['k'], settings.AUTH_JAMESPOT, algorithms=['HS256'])
             if (('email' and 'idUser') in payload):
                 user, _ = User.objects.get_or_create(email = payload['email'], idUser = payload['idUser'])
                 populateVisit(user)
                 token, _ = Token.objects.get_or_create(user=user)
                 key = str(token.key)
-            
+
         return render(request, 'index.html', {'token': key})
-        
-            
+
+
 class PublicBooks(APIView):
     """
     Send back published books
     """
-    
+
     authentication_classes = (TokenAuthentication,)
     permission_classes = (AllowAny,)
 
@@ -100,12 +99,12 @@
         books = Book.objects.filter(public=True)
         serializer = BookSerializer(books, many=True)
         return Response(serializer.data)
-            
+
 class ListBooks(APIView):
     """
     Views to list all books.
     """
-    
+
     authentication_classes = (TokenAuthentication,)
     permission_classes = (IsAuthenticated,)
 
@@ -116,16 +115,16 @@
         books = Book.objects.filter(user = request.user.id)
         serializer = BookSerializer(books, many=True)
         return Response(serializer.data)
-    
+
     def post(self, request):
         """
         Add a Book
         """
-        
+
         DEFAULTS = {
             "user":request.user.id,
         }
-        
+
         if ('idParent' in request.data):
             try:
                 book = Book.objects.get(user = request.user.id, id=request.data['idParent'])
@@ -151,13 +150,13 @@
                 serializer.save()
                 return Response(serializer.data, status=status.HTTP_201_CREATED)
             return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
-        
+
 
 class InfoBook(APIView):
     """
     View relative to a book
     """
-    
+
     authentication_classes = (TokenAuthentication,)
     permission_classes = (IsAuthenticated,)
 
@@ -169,10 +168,10 @@
             book = Book.objects.get(user = request.user.id, id=idBook)
         except Book.DoesNotExist:
             return Response(status=status.HTTP_404_NOT_FOUND)
-        
+
         serializer = BookSerializer(book)
         return Response(serializer.data)
-    
+
     def put(self, request, idBook):
         """
         update a Book
@@ -181,16 +180,16 @@
             book = Book.objects.get(user = request.user.id, id=idBook)
         except Book.DoesNotExist:
             return Response(status=status.HTTP_204_NO_CONTENT)
-        
+
         if (book.idArticle):
             return Response(status=status.HTTP_403_FORBIDDEN)
-        
+
         serializer = BookSerializer(book, data=request.data)
         if serializer.is_valid():
             serializer.save()
             return Response(serializer.data, status=status.HTTP_200_OK)
         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
-    
+
     def delete(self, request, idBook):
         """
         delete a book
@@ -199,19 +198,19 @@
             book = Book.objects.get(user = request.user.id, id = idBook)
         except Book.DoesNotExist:
             return Response(status=status.HTTP_404_NOT_FOUND)
-        
+
         if (book.idArticle):
             return Response(status=status.HTTP_403_FORBIDDEN)
-        
+
         book.delete()
         return Response(status=status.HTTP_204_NO_CONTENT)
-    
+
 
 class SlidesOrder(APIView):
     """
     Manage Slides order
     """
-    
+
     authentication_classes = (TokenAuthentication,)
     permission_classes = (IsAuthenticated,)
 
@@ -226,7 +225,7 @@
         response = {}
         response["order"] = book.get_slide_order()
         return Response(response)
-    
+
     def post(self, request, idBook):
         """
         Set Slides order
@@ -235,10 +234,10 @@
             book = Book.objects.get(user = request.user.id, id=idBook)
         except Book.DoesNotExist:
             return Response(status=status.HTTP_204_NO_CONTENT)
-        
+
         if (book.idArticle):
             return Response(status=status.HTTP_403_FORBIDDEN)
-        
+
         book.set_slide_order(request.data['order'])
         return Response(status=status.HTTP_200_OK)
 
@@ -246,7 +245,7 @@
     """
     Views to list all slides.
     """
-    
+
     authentication_classes = (TokenAuthentication,)
     permission_classes = (IsAuthenticated,)
 
@@ -262,10 +261,10 @@
             slides = Slide.objects.filter(book__user = request.user.id, book = request.GET['idBook'])[:limit]
         else:
             slides = Slide.objects.filter(book__user = request.user.id)
-    
+
         serializer = SlideSerializer(slides, many=True)
         return Response(serializer.data)
-    
+
     def post(self, request):
         """
         Add a slide
@@ -277,7 +276,7 @@
                 return Response(status=status.HTTP_204_NO_CONTENT)
             if (book.idArticle):
                 return Response(status=status.HTTP_403_FORBIDDEN)
-            
+
         serializer = SlideSerializer(data=request.data)
         if serializer.is_valid():
             serializer.save()
@@ -288,7 +287,7 @@
     """
     View to get slide detailed informations.
     """
-    
+
     authentication_classes = (TokenAuthentication,)
     permission_classes = (IsAuthenticated,)
 
@@ -300,10 +299,10 @@
             slide = Slide.objects.get(book__user = request.user.id, id=idSlide)
         except Slide.DoesNotExist:
             return Response(status=status.HTTP_404_NOT_FOUND)
-        
+
         serializer = SlideSerializer(slide)
         return Response(serializer.data)
-    
+
     def put(self, request, idSlide):
         """
         Update slide information
@@ -312,7 +311,7 @@
             slide = Slide.objects.get(book__user = request.user.id, id=idSlide)
         except Slide.DoesNotExist:
             return HttpResponse(status=status.HTTP_204_NO_CONTENT)
-        
+
         if (slide.book.idArticle):
             return Response(status=status.HTTP_403_FORBIDDEN)
         serializer = SlideSerializer(slide, data=request.data)
@@ -320,7 +319,7 @@
             serializer.save()
             return Response(serializer.data, status=status.HTTP_200_OK)
         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
-    
+
     def delete(self, request, idSlide):
         """
         Delete a slide
@@ -329,9 +328,9 @@
             slide = Slide.objects.get(book__user = request.user.id, id = idSlide)
         except Slide.DoesNotExist:
             return Response(status=status.HTTP_404_NOT_FOUND)
-        
+
         if (slide.book.idArticle):
             return Response(status=status.HTTP_403_FORBIDDEN)
-        
+
         slide.delete()
-        return Response(status=status.HTTP_204_NO_CONTENT)
\ No newline at end of file
+        return Response(status=status.HTTP_204_NO_CONTENT)
--- a/server/src/authentication/views.py	Fri Jun 05 16:10:12 2015 +0200
+++ b/server/src/authentication/views.py	Sat Jun 06 22:47:54 2015 +0200
@@ -9,7 +9,7 @@
 from rest_framework.views import APIView
 
 from ammico.views import populateVisit
-from config import URL_JAMESPOT
+from django.conf import settings
 
 
 class UserSerializer(serializers.ModelSerializer):
@@ -21,21 +21,21 @@
     get list user or add user
     """
     permission_classes = (permissions.AllowAny,)
-    
+
     def get(self, request):
         user = get_user_model().objects.all()
         serializer = UserSerializer(user, many=True)
         return Response(serializer.data)
-        
+
     def post(self, request):
         VALID_USER_FIELDS = [f.name for f in get_user_model()._meta.fields]
         serialized = UserSerializer(data=request.data)
-        
+
         if serialized.is_valid():
             user_data = {field: data for (field, data) in request.DATA.items() if field in VALID_USER_FIELDS}
-            
+
             params = {'o': 'user', 'f': 'get', 'mail': user_data['email']}
-            r = requests.get(URL_JAMESPOT, params=params)
+            r = requests.get(settings.URL_JAMESPOT, params=params)
             infoUser = json.loads(r.content.decode('utf-8'))
             if ('idUser' in infoUser['VAL']):
                 user_data.update({"idUser":infoUser['VAL']['idUser']})
@@ -45,7 +45,7 @@
             return Response(UserSerializer(instance=user).data, status=status.HTTP_201_CREATED)
         else:
             return Response(serialized._errors, status=status.HTTP_400_BAD_REQUEST)
-        
+
 class ObtainAuthToken(APIView):
     throttle_classes = ()
     permission_classes = ()
@@ -57,4 +57,4 @@
         if (user.idUser):
             populateVisit(user)
         token, _ = Token.objects.get_or_create(user=user)
-        return Response({'token': token.key})
\ No newline at end of file
+        return Response({'token': token.key})
--- a/server/src/config.py.tmpl	Fri Jun 05 16:10:12 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-# Database
-# https://docs.djangoproject.com/en/1.7/ref/settings/#databases
-
-DATABASES = {
-    'default': {
-        'ENGINE': 'django.db.backends.postgresql_psycopg2', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
-        'NAME': 'example',                      # Or path to database file if using sqlite3.
-        'USER': 'example',                      # Not used with sqlite3.
-        'PASSWORD': 'example',                  # Not used with sqlite3.
-        'HOST': 'localhost',                      # Set to empty string for localhost. Not used with sqlite3.
-        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
-    }
-}
-
-# SECURITY WARNING: keep the secret key used in production secret!
-SECRET_KEY = ''
-AUTH_JAMESPOT = ''
-
-URL_JAMESPOT = 'http://fui-ammico.jamespot.pro/api/api.php?&k=API-KEY&d=YYYY-MM-DD&m=EXT-API&v=2.0'
-URL_EXALEAD = ''
-URL_ORPHEO = ''
\ No newline at end of file
--- a/server/src/manage.py	Fri Jun 05 16:10:12 2015 +0200
+++ b/server/src/manage.py	Sat Jun 06 22:47:54 2015 +0200
@@ -3,7 +3,7 @@
 import sys
 
 if __name__ == "__main__":
-    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")
+    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings.dev")
 
     from django.core.management import execute_from_command_line
 
--- a/server/src/settings.py	Fri Jun 05 16:10:12 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,99 +0,0 @@
-"""
-Django settings for ammico project.
-
-For more information on this file, see
-https://docs.djangoproject.com/en/1.7/topics/settings/
-
-For the full list of settings and their values, see
-https://docs.djangoproject.com/en/1.7/ref/settings/
-"""
-
-# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
-import os
-BASE_DIR = os.path.dirname(os.path.dirname(__file__))
-
-
-# Quick-start development settings - unsuitable for production
-# See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/
-
-DEBUG = True
-
-TEMPLATE_DEBUG = True
-
-ALLOWED_HOSTS = []
-
-# Application definition
-
-INSTALLED_APPS = (
-    'django.contrib.admin',
-    'django.contrib.auth',
-    'django.contrib.contenttypes',
-    'django.contrib.sessions',
-    'django.contrib.messages',
-    'django.contrib.staticfiles',
-    'rest_framework',
-    'rest_framework.authtoken',
-    'corsheaders',
-    'requests',
-    'taggit',
-    'ammico',
-    'authentication',
-    'xmltodict',
-)
-
-MIDDLEWARE_CLASSES = (
-    'django.contrib.sessions.middleware.SessionMiddleware',
-    'corsheaders.middleware.CorsMiddleware',
-    'django.middleware.common.CommonMiddleware',
-    'django.middleware.csrf.CsrfViewMiddleware',
-    'django.contrib.auth.middleware.AuthenticationMiddleware',
-    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
-    'django.contrib.messages.middleware.MessageMiddleware',
-    'django.middleware.clickjacking.XFrameOptionsMiddleware',
-)
-
-ROOT_URLCONF = 'urls'
-
-WSGI_APPLICATION = 'wsgi.application'
-
-CORS_ORIGIN_ALLOW_ALL = True
-
-REST_FRAMEWORK = {
-    # Use Django's standard `django.contrib.auth` permissions,
-    # or allow read-only access for unauthenticated users.
-    'DEFAULT_PERMISSION_CLASSES': [
-        'rest_framework.authentication.TokenAuthentication'
-    ]
-}
-
-CACHES = {
-    'default': {
-        'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
-        'LOCATION': 'cacheTable',
-    }
-}
-
-AUTH_USER_MODEL = 'authentication.AmmicoUser'
-AUTH_PROFILE_MODULE = 'authentication.Profile'
-
-# Internationalization
-# https://docs.djangoproject.com/en/1.7/topics/i18n/
-
-LANGUAGE_CODE = 'en-us'
-
-TIME_ZONE = 'UTC'
-
-USE_I18N = True
-
-USE_L10N = True
-
-USE_TZ = True
-
-
-# Static files (CSS, JavaScript, Images)
-# https://docs.djangoproject.com/en/1.7/howto/static-files/
-
-STATIC_URL = '/static/'
-
-from config import * #@UnusedWildImport
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/settings/__init__.py	Sat Jun 06 22:47:54 2015 +0200
@@ -0,0 +1,96 @@
+"""
+Django settings for ammico project.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/1.7/topics/settings/
+
+For the full list of settings and their values, see
+https://docs.djangoproject.com/en/1.7/ref/settings/
+"""
+
+# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
+import os
+BASE_DIR = os.path.dirname(os.path.dirname(__file__))
+
+
+# Quick-start development settings - unsuitable for production
+# See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/
+
+DEBUG = False
+
+TEMPLATE_DEBUG = False
+
+ALLOWED_HOSTS = []
+
+# Application definition
+
+INSTALLED_APPS = (
+    'django.contrib.admin',
+    'django.contrib.auth',
+    'django.contrib.contenttypes',
+    'django.contrib.sessions',
+    'django.contrib.messages',
+    'django.contrib.staticfiles',
+    'rest_framework',
+    'rest_framework.authtoken',
+    'corsheaders',
+    'requests',
+    'taggit',
+    'ammico',
+    'authentication',
+    'xmltodict',
+)
+
+MIDDLEWARE_CLASSES = (
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    'corsheaders.middleware.CorsMiddleware',
+    'django.middleware.common.CommonMiddleware',
+    'django.middleware.csrf.CsrfViewMiddleware',
+    'django.contrib.auth.middleware.AuthenticationMiddleware',
+    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
+    'django.contrib.messages.middleware.MessageMiddleware',
+    'django.middleware.clickjacking.XFrameOptionsMiddleware',
+)
+
+ROOT_URLCONF = 'urls'
+
+WSGI_APPLICATION = 'wsgi.application'
+
+CORS_ORIGIN_ALLOW_ALL = True
+
+REST_FRAMEWORK = {
+    # Use Django's standard `django.contrib.auth` permissions,
+    # or allow read-only access for unauthenticated users.
+    'DEFAULT_PERMISSION_CLASSES': [
+        'rest_framework.authentication.TokenAuthentication'
+    ]
+}
+
+CACHES = {
+    'default': {
+        'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
+        'LOCATION': 'cacheTable',
+    }
+}
+
+AUTH_USER_MODEL = 'authentication.AmmicoUser'
+AUTH_PROFILE_MODULE = 'authentication.Profile'
+
+# Internationalization
+# https://docs.djangoproject.com/en/1.7/topics/i18n/
+
+LANGUAGE_CODE = 'en-us'
+
+TIME_ZONE = 'UTC'
+
+USE_I18N = True
+
+USE_L10N = True
+
+USE_TZ = True
+
+
+# Static files (CSS, JavaScript, Images)
+# https://docs.djangoproject.com/en/1.7/howto/static-files/
+
+STATIC_URL = '/static/'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/settings/dev.py.tmpl	Sat Jun 06 22:47:54 2015 +0200
@@ -0,0 +1,121 @@
+# -*- coding: utf-8 -*-
+from . import *
+import os, logging
+
+#TODO override
+DEBUG = True
+TEMPLATE_DEBUG = DEBUG
+
+
+BASE_URL = '%(base_url)s'
+WEB_URL = '%(web_url)s'
+
+PLATFORM_BASE_URL = WEB_URL + BASE_URL + 'ammico/'
+
+STREAM_SRC_PREFIX = ""
+
+BASE_STATIC_URL = WEB_URL + BASE_URL + 'static/'
+BASE_STATIC_ROOT = os.path.abspath(BASE_DIR + "../../web/static/").rstrip("/")+"/"
+
+
+# Absolute path to the directory that holds media.
+# Example: "/home/media/media.lawrence.com/"
+MEDIA_ROOT = BASE_STATIC_ROOT + "media/"
+
+# URL that handles the media served from MEDIA_ROOT. Make sure to use a
+# trailing slash if there is a path component (optional in other cases).
+# Examples: "http://media.lawrence.com", "http://example.com/media/"
+MEDIA_URL = BASE_STATIC_URL + 'media/'
+
+
+STATIC_URL = BASE_STATIC_URL + 'site/'
+
+# Absolute path to the directory that static files (js, css, swf...)
+# DO NOT forget to do command line ./manage.py collectstatic to gather static media into the web/static folder
+STATIC_ROOT = BASE_STATIC_ROOT + "site/"
+
+
+SRC_BASE_URL = BASE_URL + __name__.split('.')[0] + '/'
+
+
+# Make this unique, and don't share it with anybody.
+SECRET_KEY = '%(secret_key)s'
+
+DATABASES = {
+    'default': {
+        'ENGINE': 'django.db.backends.%(db_engine)s', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
+        'NAME': '%(db_name)s',                      # Or path to database file if using sqlite3.
+        'USER': '%(db_user)s',                      # Not used with sqlite3.
+        'PASSWORD': '%(db_password)s',                  # Not used with sqlite3.
+        'HOST': '%(db_host)s',                      # Set to empty string for localhost. Not used with sqlite3.
+        'PORT': '%(db_port)d',                      # Set to empty string for default. Not used with sqlite3.
+    },
+}
+
+LOG_FILE = os.path.abspath(os.path.join(BASE_DIR,"../run/log/log.txt"))
+LOG_LEVEL = logging.DEBUG
+
+LOGGING = {
+    'version': 1,
+    'disable_existing_loggers': False,
+    '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',
+        },
+    },
+    'loggers': {
+#        'django.db.backends':{
+#            'handlers': ['file'],
+#            'level': LOG_LEVEL,
+#            'propagate': True,
+#        },
+        'django.request': {
+            'handlers': ['file'],
+            'level': LOG_LEVEL,
+            'propagate': True,
+        },
+        'ammico': {
+            'handlers': ['file'],
+            'level': LOG_LEVEL,
+            'propagate': True,
+        },
+    }
+}
+
+
+ADMINS = (
+    #('Your Name', 'your_email@domain.com'),
+)
+
+MANAGERS = ADMINS
+
+AUTH_JAMESPOT = ''
+
+URL_JAMESPOT = ''
+URL_EXALEAD = ''
+URL_ORPHEO = ''
--- a/server/virtualenv/requirements.txt	Fri Jun 05 16:10:12 2015 +0200
+++ b/server/virtualenv/requirements.txt	Sat Jun 06 22:47:54 2015 +0200
@@ -1,8 +1,8 @@
-Django==1.7.6
-django-cors-headers==1.0.0
+Django==1.8.2
+django-cors-headers==1.1.0
 django-taggit==0.14.0
-djangorestframework==3.1.0
+djangorestframework==3.1.3
 psycopg2==2.6
 PyJWT==1.3.0
-requests==2.5.3
+requests==2.7.0
 xmltodict==0.9.2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/virtualenv/requirements_srvr.txt	Sat Jun 06 22:47:54 2015 +0200
@@ -0,0 +1,2 @@
+uWSGI>=2.0.10
+pylibmc>=1.4.3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/virtualenv/requirements_sync.txt	Sat Jun 06 22:47:54 2015 +0200
@@ -0,0 +1,1 @@
+Fabric>=1.10.1