From 0498cf31ff4cf957ed9d758d2d08daad9938ebd4 Mon Sep 17 00:00:00 2001
From: Andre Anjos <andre.dos.anjos@gmail.com>
Date: Mon, 30 Apr 2018 11:39:09 +0200
Subject: [PATCH] Support for new conda-based CI/CD pipelines

---
 .gitignore                                    |  31 ++
 .gitlab-ci.yml                                | 182 ++++++++++++
 MANIFEST.in                                   |   5 +
 README.rst                                    |  65 +++++
 beat/__init__.py                              |  30 ++
 .../editor/__init__.py                        |   0
 .../editor/scripts/__init__.py                |   0
 server.py => beat/editor/scripts/server.py    |  30 +-
 templates.py => beat/editor/templates.py      |   0
 .../editor/templates}/algorithm.jinja2        |   0
 .../editor/templates}/database.jinja2         |   0
 .../editor/templates}/library.jinja2          |   0
 buildout.cfg                                  |   8 +
 conda/meta.yaml                               |  65 +++++
 DEV.md => doc/DEV.md                          |   0
 README.md => doc/README.md                    |   0
 doc/api.rst                                   |  10 +
 doc/conf.py                                   | 265 ++++++++++++++++++
 doc/img/favicon.ico                           | Bin 0 -> 27438 bytes
 doc/img/logo.png                              | Bin 0 -> 13399 bytes
 doc/index.rst                                 |  43 +++
 licenses.md => doc/licenses.md                |   0
 doc/nitpick-exceptions.txt                    |  10 +
 .babelrc => js/.babelrc                       |   0
 .eslintrc.js => js/.eslintrc.js               |   0
 .flowconfig => js/.flowconfig                 |   0
 .nvmrc => js/.nvmrc                           |   0
 .postcssrc => js/.postcssrc                   |   0
 .stylelintrc => js/.stylelintrc               |   0
 .tern-project => js/.tern-project             |   0
 index.html => js/index.html                   |   0
 karma.conf.js => js/karma.conf.js             |   0
 main.css => js/main.css                       |   0
 main.jsx => js/main.jsx                       |   0
 package-lock.json => js/package-lock.json     |   0
 package.json => js/package.json               |   0
 {src => js/src}/components/App.jsx            |   0
 {src => js/src}/components/CacheInput.jsx     |   0
 .../src}/components/CacheInput.spec.jsx       |   0
 {src => js/src}/components/DeleteInputBtn.jsx |   0
 .../src}/components/DeleteInputBtn.spec.jsx   |   0
 {src => js/src}/components/EntityDetail.jsx   |   0
 {src => js/src}/components/EntityHome.jsx     |   0
 {src => js/src}/components/EntityList.jsx     |   0
 .../EntityTemplateGenerationButton.jsx        |   0
 {src => js/src}/components/HomeContent.jsx    |   0
 {src => js/src}/components/InfoTooltip.jsx    |   0
 {src => js/src}/components/MainContent.jsx    |   0
 {src => js/src}/components/MainNav.jsx        |   0
 {src => js/src}/components/NewEntityModal.jsx |   0
 .../src}/components/ParameterConsume.jsx      |   0
 .../src}/components/ParameterCreate.jsx       |   0
 {src => js/src}/components/SearchBar.jsx      |   0
 {src => js/src}/components/Settings.jsx       |   0
 {src => js/src}/components/TypedField.jsx     |   0
 .../src}/components/ValidSchemaBadge.jsx      |   0
 .../src}/components/ValidSchemaBadge.spec.jsx |   0
 .../components/algorithm/AlgorithmEditor.jsx  |   0
 .../algorithm/AlgorithmEditor.spec.jsx        |   0
 {src => js/src}/components/algorithm/index.js |   0
 .../components/database/DatabaseEditor.css    |   0
 .../components/database/DatabaseEditor.jsx    |   0
 .../database/DatabaseEditor.spec.jsx          |   0
 {src => js/src}/components/database/index.js  |   0
 .../dataformat/DataformatEditor.jsx           |   0
 .../dataformat/DataformatEditor.spec.jsx      |   0
 .../src}/components/dataformat/index.js       |   0
 .../experiment/ExperimentEditor.css           |   0
 .../experiment/ExperimentEditor.jsx           |   0
 .../experiment/ExperimentEditor.spec.jsx      |   0
 .../src}/components/experiment/index.js       |   0
 .../src}/components/library/LibraryEditor.jsx |   0
 .../components/library/LibraryEditor.spec.jsx |   0
 {src => js/src}/components/library/index.js   |   0
 .../src}/components/plotter/PlotterEditor.jsx |   0
 .../components/plotter/PlotterEditor.spec.jsx |   0
 {src => js/src}/components/plotter/index.js   |   0
 .../PlotterParameterEditor.jsx                |   0
 .../PlotterParameterEditor.spec.jsx           |   0
 .../src}/components/plotterparameter/index.js |   0
 .../components/toolchain/GraphicalEditor.css  |   0
 .../components/toolchain/GraphicalEditor.jsx  |   0
 .../toolchain/GraphicalEditorHelpModal.jsx    |   0
 .../toolchain/InsertObjectModal.jsx           |   0
 .../components/toolchain/RenameGroupModal.jsx |   0
 .../components/toolchain/ToolchainBlock.jsx   |   0
 .../toolchain/ToolchainConnection.jsx         |   0
 .../toolchain/ToolchainConnection.spec.jsx    |   0
 .../components/toolchain/ToolchainEditor.css  |   0
 .../components/toolchain/ToolchainEditor.jsx  |   0
 .../toolchain/ToolchainEditor.spec.jsx        |   0
 .../components/toolchain/ToolchainModal.jsx   |   0
 {src => js/src}/components/toolchain/index.js |   0
 {src => js/src}/components/toolchain/types.js |   0
 {src => js/src}/helpers/api.js                |   0
 {src => js/src}/helpers/beat.js               |   0
 {src => js/src}/helpers/index.js              |   0
 {src => js/src}/helpers/schema/algorithm.json |   0
 {src => js/src}/helpers/schema/common.json    |   0
 {src => js/src}/helpers/schema/database.json  |   0
 .../src}/helpers/schema/dataformat.json       |   0
 {src => js/src}/helpers/schema/execution.json |   0
 .../src}/helpers/schema/experiment.json       |   0
 {src => js/src}/helpers/schema/index.js       |   0
 {src => js/src}/helpers/schema/library.json   |   0
 {src => js/src}/helpers/schema/plotter.json   |   0
 .../src}/helpers/schema/plotterparameter.json |   0
 {src => js/src}/helpers/schema/toolchain.json |   0
 {src => js/src}/helpers/search.worker.js      |   0
 {src => js/src}/store/actionTypes.js          |   0
 {src => js/src}/store/actions.js              |   0
 {src => js/src}/store/index.js                |   0
 {src => js/src}/store/reducers.js             |   0
 {src => js/src}/store/selectors.js            |   0
 {test => js/test}/index.js                    |   0
 {test => js/test}/test_algs.json              |   0
 {test => js/test}/test_dbs.json               |   0
 {test => js/test}/test_dfs.json               |   0
 {test => js/test}/test_exps.json              |   0
 {test => js/test}/test_libs.json              |   0
 {test => js/test}/test_tcs.json               |   0
 webpack.config.js => js/webpack.config.js     |   0
 requirements.txt                              |   6 +
 setup.py                                      |  68 +++++
 version.txt                                   |   1 +
 125 files changed, 805 insertions(+), 14 deletions(-)
 create mode 100644 .gitlab-ci.yml
 create mode 100644 MANIFEST.in
 create mode 100644 README.rst
 create mode 100644 beat/__init__.py
 rename src/components/plotter/PlotterEditor.spec.jsx => beat/editor/__init__.py (100%)
 rename src/components/plotterparameter/PlotterParameterEditor.spec.jsx => beat/editor/scripts/__init__.py (100%)
 rename server.py => beat/editor/scripts/server.py (97%)
 rename templates.py => beat/editor/templates.py (100%)
 rename {templates => beat/editor/templates}/algorithm.jinja2 (100%)
 rename {templates => beat/editor/templates}/database.jinja2 (100%)
 rename {templates => beat/editor/templates}/library.jinja2 (100%)
 create mode 100644 buildout.cfg
 create mode 100644 conda/meta.yaml
 rename DEV.md => doc/DEV.md (100%)
 rename README.md => doc/README.md (100%)
 create mode 100644 doc/api.rst
 create mode 100644 doc/conf.py
 create mode 100644 doc/img/favicon.ico
 create mode 100644 doc/img/logo.png
 create mode 100644 doc/index.rst
 rename licenses.md => doc/licenses.md (100%)
 create mode 100644 doc/nitpick-exceptions.txt
 rename .babelrc => js/.babelrc (100%)
 rename .eslintrc.js => js/.eslintrc.js (100%)
 rename .flowconfig => js/.flowconfig (100%)
 rename .nvmrc => js/.nvmrc (100%)
 rename .postcssrc => js/.postcssrc (100%)
 rename .stylelintrc => js/.stylelintrc (100%)
 rename .tern-project => js/.tern-project (100%)
 rename index.html => js/index.html (100%)
 rename karma.conf.js => js/karma.conf.js (100%)
 rename main.css => js/main.css (100%)
 rename main.jsx => js/main.jsx (100%)
 rename package-lock.json => js/package-lock.json (100%)
 rename package.json => js/package.json (100%)
 rename {src => js/src}/components/App.jsx (100%)
 rename {src => js/src}/components/CacheInput.jsx (100%)
 rename {src => js/src}/components/CacheInput.spec.jsx (100%)
 rename {src => js/src}/components/DeleteInputBtn.jsx (100%)
 rename {src => js/src}/components/DeleteInputBtn.spec.jsx (100%)
 rename {src => js/src}/components/EntityDetail.jsx (100%)
 rename {src => js/src}/components/EntityHome.jsx (100%)
 rename {src => js/src}/components/EntityList.jsx (100%)
 rename {src => js/src}/components/EntityTemplateGenerationButton.jsx (100%)
 rename {src => js/src}/components/HomeContent.jsx (100%)
 rename {src => js/src}/components/InfoTooltip.jsx (100%)
 rename {src => js/src}/components/MainContent.jsx (100%)
 rename {src => js/src}/components/MainNav.jsx (100%)
 rename {src => js/src}/components/NewEntityModal.jsx (100%)
 rename {src => js/src}/components/ParameterConsume.jsx (100%)
 rename {src => js/src}/components/ParameterCreate.jsx (100%)
 rename {src => js/src}/components/SearchBar.jsx (100%)
 rename {src => js/src}/components/Settings.jsx (100%)
 rename {src => js/src}/components/TypedField.jsx (100%)
 rename {src => js/src}/components/ValidSchemaBadge.jsx (100%)
 rename {src => js/src}/components/ValidSchemaBadge.spec.jsx (100%)
 rename {src => js/src}/components/algorithm/AlgorithmEditor.jsx (100%)
 rename {src => js/src}/components/algorithm/AlgorithmEditor.spec.jsx (100%)
 rename {src => js/src}/components/algorithm/index.js (100%)
 rename {src => js/src}/components/database/DatabaseEditor.css (100%)
 rename {src => js/src}/components/database/DatabaseEditor.jsx (100%)
 rename {src => js/src}/components/database/DatabaseEditor.spec.jsx (100%)
 rename {src => js/src}/components/database/index.js (100%)
 rename {src => js/src}/components/dataformat/DataformatEditor.jsx (100%)
 rename {src => js/src}/components/dataformat/DataformatEditor.spec.jsx (100%)
 rename {src => js/src}/components/dataformat/index.js (100%)
 rename {src => js/src}/components/experiment/ExperimentEditor.css (100%)
 rename {src => js/src}/components/experiment/ExperimentEditor.jsx (100%)
 rename {src => js/src}/components/experiment/ExperimentEditor.spec.jsx (100%)
 rename {src => js/src}/components/experiment/index.js (100%)
 rename {src => js/src}/components/library/LibraryEditor.jsx (100%)
 rename {src => js/src}/components/library/LibraryEditor.spec.jsx (100%)
 rename {src => js/src}/components/library/index.js (100%)
 rename {src => js/src}/components/plotter/PlotterEditor.jsx (100%)
 create mode 100644 js/src/components/plotter/PlotterEditor.spec.jsx
 rename {src => js/src}/components/plotter/index.js (100%)
 rename {src => js/src}/components/plotterparameter/PlotterParameterEditor.jsx (100%)
 create mode 100644 js/src/components/plotterparameter/PlotterParameterEditor.spec.jsx
 rename {src => js/src}/components/plotterparameter/index.js (100%)
 rename {src => js/src}/components/toolchain/GraphicalEditor.css (100%)
 rename {src => js/src}/components/toolchain/GraphicalEditor.jsx (100%)
 rename {src => js/src}/components/toolchain/GraphicalEditorHelpModal.jsx (100%)
 rename {src => js/src}/components/toolchain/InsertObjectModal.jsx (100%)
 rename {src => js/src}/components/toolchain/RenameGroupModal.jsx (100%)
 rename {src => js/src}/components/toolchain/ToolchainBlock.jsx (100%)
 rename {src => js/src}/components/toolchain/ToolchainConnection.jsx (100%)
 rename {src => js/src}/components/toolchain/ToolchainConnection.spec.jsx (100%)
 rename {src => js/src}/components/toolchain/ToolchainEditor.css (100%)
 rename {src => js/src}/components/toolchain/ToolchainEditor.jsx (100%)
 rename {src => js/src}/components/toolchain/ToolchainEditor.spec.jsx (100%)
 rename {src => js/src}/components/toolchain/ToolchainModal.jsx (100%)
 rename {src => js/src}/components/toolchain/index.js (100%)
 rename {src => js/src}/components/toolchain/types.js (100%)
 rename {src => js/src}/helpers/api.js (100%)
 rename {src => js/src}/helpers/beat.js (100%)
 rename {src => js/src}/helpers/index.js (100%)
 rename {src => js/src}/helpers/schema/algorithm.json (100%)
 rename {src => js/src}/helpers/schema/common.json (100%)
 rename {src => js/src}/helpers/schema/database.json (100%)
 rename {src => js/src}/helpers/schema/dataformat.json (100%)
 rename {src => js/src}/helpers/schema/execution.json (100%)
 rename {src => js/src}/helpers/schema/experiment.json (100%)
 rename {src => js/src}/helpers/schema/index.js (100%)
 rename {src => js/src}/helpers/schema/library.json (100%)
 rename {src => js/src}/helpers/schema/plotter.json (100%)
 rename {src => js/src}/helpers/schema/plotterparameter.json (100%)
 rename {src => js/src}/helpers/schema/toolchain.json (100%)
 rename {src => js/src}/helpers/search.worker.js (100%)
 rename {src => js/src}/store/actionTypes.js (100%)
 rename {src => js/src}/store/actions.js (100%)
 rename {src => js/src}/store/index.js (100%)
 rename {src => js/src}/store/reducers.js (100%)
 rename {src => js/src}/store/selectors.js (100%)
 rename {test => js/test}/index.js (100%)
 rename {test => js/test}/test_algs.json (100%)
 rename {test => js/test}/test_dbs.json (100%)
 rename {test => js/test}/test_dfs.json (100%)
 rename {test => js/test}/test_exps.json (100%)
 rename {test => js/test}/test_libs.json (100%)
 rename {test => js/test}/test_tcs.json (100%)
 rename webpack.config.js => js/webpack.config.js (100%)
 create mode 100644 requirements.txt
 create mode 100644 setup.py
 create mode 100644 version.txt

diff --git a/.gitignore b/.gitignore
index 52570f50..3dc68b56 100644
--- a/.gitignore
+++ b/.gitignore
@@ -78,3 +78,34 @@ user_conf.json
 
 # pycache
 __pycache__
+
+*~
+*.swp
+*.pyc
+*.so
+bin
+eggs
+parts
+.installed.cfg
+.mr.developer.cfg
+*.egg-info
+develop-eggs
+sphinx
+doc/api
+src
+dist
+.nfs*
+.gdb_history
+build
+*.egg
+opsnr.stt
+.coverage
+.DS_Store
+html/
+record.txt
+_ci/
+miniconda.sh
+miniconda/
+miniconda.cached/
+conda/recipe_append.yaml
+conda-bld/
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 00000000..3d9a7e77
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,182 @@
+# This build file uses template features from YAML so it is generic enough for
+# any Bob project. Don't modify it unless you know what you're doing.
+
+# Definition of global variables (all stages)
+variables:
+  CONDA_ROOT: "${CI_PROJECT_DIR}/miniconda"
+
+
+# Definition of our build pipeline order
+stages:
+  - build
+  - docker
+  - deploy
+  - pypi
+
+
+# Build targets
+.build_template: &build_job
+  stage: build
+  before_script:
+    - mkdir _ci
+    - curl --silent "https://gitlab.idiap.ch/bob/bob.admin/raw/master/gitlab/install.sh" > _ci/install.sh
+    - chmod 755 _ci/install.sh
+    - ./_ci/install.sh _ci master #installs ci support scripts
+    - ./_ci/before_build.sh
+  script:
+    - ./_ci/build.sh
+  after_script:
+    - ./_ci/after_build.sh
+  cache: &build_caches
+    paths:
+      - miniconda.sh
+      - ${CONDA_ROOT}/pkgs/*.tar.bz2
+      - ${CONDA_ROOT}/pkgs/urls.txt
+
+
+.build_linux_template: &linux_build_job
+  <<: *build_job
+  tags:
+    - docker
+  image: continuumio/conda-concourse-ci
+  artifacts:
+    expire_in: 1 week
+    paths:
+      - _ci/
+      - ${CONDA_ROOT}/conda-bld/linux-64/*.tar.bz2
+  cache:
+    <<: *build_caches
+    key: "linux-cache"
+
+
+.build_macosx_template: &macosx_build_job
+  <<: *build_job
+  tags:
+    - macosx
+  artifacts:
+    expire_in: 1 week
+    paths:
+      - _ci/
+      - ${CONDA_ROOT}/conda-bld/osx-64/*.tar.bz2
+  cache:
+    <<: *build_caches
+    key: "macosx-cache"
+
+
+# Docker host based testing (must be run inside dind or docker-enabled host)
+.docker_test_linux_template: &linux_docker_job
+  stage: docker
+  before_script:
+    # safe keep artifacts as before_build.sh will erase those...
+    - mv ${CONDA_ROOT}/conda-bld .
+    - ./_ci/install.sh _ci master #updates ci support scripts
+    - ./_ci/before_build.sh
+    - mv conda-bld ${CONDA_ROOT}
+    - ./scripts/before_test.sh
+  script:
+    - export BEAT_DOCKER_TESTS=true
+    - BOB_TEST_ONLY=true ./_ci/build.sh
+  after_script:
+    - ./_ci/after_build.sh
+
+
+build_linux_27:
+  <<: *linux_build_job
+  variables:
+    PYTHON_VERSION: "2.7"
+
+
+build_linux_36:
+  <<: *linux_build_job
+  variables:
+    PYTHON_VERSION: "3.6"
+    BUILD_EGG: "true"
+  artifacts:
+    expire_in: 1 week
+    paths:
+      - _ci/
+      - dist/*.zip
+      - sphinx
+      - ${CONDA_ROOT}/conda-bld/linux-64/*.tar.bz2
+
+
+build_macosx_27:
+  <<: *macosx_build_job
+  variables:
+    PYTHON_VERSION: "2.7"
+
+
+build_macosx_36:
+  <<: *macosx_build_job
+  variables:
+    PYTHON_VERSION: "3.6"
+
+
+# Docker host based testing
+docker_linux_27:
+  <<: *linux_docker_job
+  variables:
+    PYTHON_VERSION: "2.7"
+  dependencies:
+    - build_linux_27
+  tags:
+    - docker-build
+
+
+docker_linux_36:
+  <<: *linux_docker_job
+  variables:
+    PYTHON_VERSION: "3.6"
+  dependencies:
+    - build_linux_36
+  tags:
+    - docker-build
+
+
+# Deploy targets
+.deploy_template: &deploy_job
+  stage: deploy
+  before_script:
+    - ./_ci/install.sh _ci master #updates ci support scripts
+  script:
+    - ./_ci/deploy.sh
+  dependencies:
+    - build_linux_27
+    - build_linux_36
+    - build_macosx_27
+    - build_macosx_36
+  tags:
+    - deployer
+
+
+deploy_beta:
+  <<: *deploy_job
+  environment: beta
+  only:
+    - master
+
+
+deploy_stable:
+  <<: *deploy_job
+  environment: stable
+  only:
+    - /^v\d+\.\d+\.\d+([abc]\d*)?$/  # PEP-440 compliant version (tags)
+  except:
+    - branches
+
+
+pypi:
+  stage: pypi
+  environment: pypi
+  only:
+    - /^v\d+\.\d+\.\d+([abc]\d*)?$/  # PEP-440 compliant version (tags)
+  except:
+    - branches
+  before_script:
+    - ./_ci/install.sh _ci master #updates ci support scripts
+  script:
+    - ./_ci/pypi.sh
+  dependencies:
+    - build_linux_36
+  tags:
+    - deployer
diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 00000000..3fc2f289
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1,5 @@
+include LICENSE.AGPL README.rst version.txt requirements.txt buildout.cfg
+recursive-include scripts *.sh
+recursive-include doc conf.py *.rst *.png *.ico
+recursive-include beat/editor/templates *.jinja2
+recursive-include beat/editor/js *
diff --git a/README.rst b/README.rst
new file mode 100644
index 00000000..a0cced31
--- /dev/null
+++ b/README.rst
@@ -0,0 +1,65 @@
+.. vim: set fileencoding=utf-8 :
+
+.. Copyright (c) 2016 Idiap Research Institute, http://www.idiap.ch/          ..
+.. Contact: beat.support@idiap.ch                                             ..
+..                                                                            ..
+.. This file is part of the beat.editor module of the BEAT platform.            ..
+..                                                                            ..
+.. Commercial License Usage                                                   ..
+.. Licensees holding valid commercial BEAT licenses may use this file in      ..
+.. accordance with the terms contained in a written agreement between you     ..
+.. and Idiap. For further information contact tto@idiap.ch                    ..
+..                                                                            ..
+.. Alternatively, this file may be used under the terms of the GNU Affero     ..
+.. Public License version 3 as published by the Free Software and appearing   ..
+.. in the file LICENSE.AGPL included in the packaging of this file.           ..
+.. The BEAT platform is distributed in the hope that it will be useful, but   ..
+.. WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ..
+.. or FITNESS FOR A PARTICULAR PURPOSE.                                       ..
+..                                                                            ..
+.. You should have received a copy of the GNU Affero Public License along     ..
+.. with the BEAT platform. If not, see http://www.gnu.org/licenses/.          ..
+
+.. image:: https://img.shields.io/badge/docs-stable-yellow.svg
+   :target: https://www.idiap.ch/software/beat/docs/beat/beat.editor/stable/index.html
+.. image:: https://img.shields.io/badge/docs-latest-orange.svg
+   :target: https://www.idiap.ch/software/beat/docs/beat/beat.editor/master/index.html
+.. image:: https://gitlab.idiap.ch/beat/beat.editor/badges/master/build.svg
+   :target: https://gitlab.idiap.ch/beat/beat.editor/commits/master
+.. image:: https://gitlab.idiap.ch/beat/beat.editor/badges/master/coverage.svg
+   :target: https://gitlab.idiap.ch/beat/beat.editor/commits/master
+.. image:: https://img.shields.io/badge/gitlab-project-0000c0.svg
+   :target: https://gitlab.idiap.ch/beat/beat.editor
+.. image:: https://img.shields.io/pypi/v/beat.editor.svg
+   :target: https://pypi.python.org/pypi/beat.editor
+
+
+===============================
+ Local editor for BEAT objects
+===============================
+
+This package part of BEAT_, an open-source evaluation platform for data science
+algorithms and workflows. It contains the source code for a local editor for
+BEAT objects.
+
+
+Installation
+------------
+
+Complete BEAT's `installation`_ instructions. Then, to install this package,
+run::
+
+  $ conda install beat.editor
+
+
+Contact
+-------
+
+For questions or reporting issues to this software package, contact our
+development `mailing list`_.
+
+
+.. Place your references here:
+.. _beat: https://www.idiap.ch/software/beat
+.. _installation: https://www.idiap.ch/software/beat/install
+.. _mailing list: https://www.idiap.ch/software/beat/discuss
diff --git a/beat/__init__.py b/beat/__init__.py
new file mode 100644
index 00000000..71f2674e
--- /dev/null
+++ b/beat/__init__.py
@@ -0,0 +1,30 @@
+#!/usr/bin/env python
+# vim: set fileencoding=utf-8 :
+
+###############################################################################
+#                                                                             #
+# Copyright (c) 2016 Idiap Research Institute, http://www.idiap.ch/           #
+# Contact: beat.support@idiap.ch                                              #
+#                                                                             #
+# This file is part of the beat.editor module of the BEAT platform.           #
+#                                                                             #
+# Commercial License Usage                                                    #
+# Licensees holding valid commercial BEAT licenses may use this file in       #
+# accordance with the terms contained in a written agreement between you      #
+# and Idiap. For further information contact tto@idiap.ch                     #
+#                                                                             #
+# Alternatively, this file may be used under the terms of the GNU Affero      #
+# Public License version 3 as published by the Free Software and appearing    #
+# in the file LICENSE.AGPL included in the packaging of this file.            #
+# The BEAT platform is distributed in the hope that it will be useful, but    #
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY  #
+# or FITNESS FOR A PARTICULAR PURPOSE.                                        #
+#                                                                             #
+# You should have received a copy of the GNU Affero Public License along      #
+# with the BEAT platform. If not, see http://www.gnu.org/licenses/.           #
+#                                                                             #
+###############################################################################
+
+# see https://docs.python.org/3/library/pkgutil.html
+from pkgutil import extend_path
+__path__ = extend_path(__path__, __name__)
diff --git a/src/components/plotter/PlotterEditor.spec.jsx b/beat/editor/__init__.py
similarity index 100%
rename from src/components/plotter/PlotterEditor.spec.jsx
rename to beat/editor/__init__.py
diff --git a/src/components/plotterparameter/PlotterParameterEditor.spec.jsx b/beat/editor/scripts/__init__.py
similarity index 100%
rename from src/components/plotterparameter/PlotterParameterEditor.spec.jsx
rename to beat/editor/scripts/__init__.py
diff --git a/server.py b/beat/editor/scripts/server.py
similarity index 97%
rename from server.py
rename to beat/editor/scripts/server.py
index e79cf915..03aa816b 100644
--- a/server.py
+++ b/beat/editor/scripts/server.py
@@ -16,11 +16,8 @@ import simplejson
 from flask import Flask, request
 from flask_restful import Resource, Api
 from flask_cors import CORS
-import templates
 
-app = Flask(__name__)
-api = Api(app)
-CORS(app)
+from .. import templates
 
 def get_user_conf():
     """Reads & returns the user configuration in a dict"""
@@ -444,14 +441,19 @@ def gen_beat_endpoint(entity):
     return BeatEndpoint
 
 
-api.add_resource(Home, '/')
-api.add_resource(Settings, '/settings')
-api.add_resource(Layout, '/layout')
-api.add_resource(Templates, '/templates')
-api.add_resource(Environments, '/environments')
-for entity in BeatEntity:
-    val = entity.value
-    api.add_resource(gen_beat_endpoint(entity), '/' + val)
+def main():
 
-if __name__ == '__main__':
-    app.run(debug=True)
+  app = Flask(__name__)
+  api = Api(app)
+  CORS(app)
+
+  api.add_resource(Home, '/')
+  api.add_resource(Settings, '/settings')
+  api.add_resource(Layout, '/layout')
+  api.add_resource(Templates, '/templates')
+  api.add_resource(Environments, '/environments')
+  for entity in BeatEntity:
+      val = entity.value
+      api.add_resource(gen_beat_endpoint(entity), '/' + val)
+
+  app.run(debug=True)
diff --git a/templates.py b/beat/editor/templates.py
similarity index 100%
rename from templates.py
rename to beat/editor/templates.py
diff --git a/templates/algorithm.jinja2 b/beat/editor/templates/algorithm.jinja2
similarity index 100%
rename from templates/algorithm.jinja2
rename to beat/editor/templates/algorithm.jinja2
diff --git a/templates/database.jinja2 b/beat/editor/templates/database.jinja2
similarity index 100%
rename from templates/database.jinja2
rename to beat/editor/templates/database.jinja2
diff --git a/templates/library.jinja2 b/beat/editor/templates/library.jinja2
similarity index 100%
rename from templates/library.jinja2
rename to beat/editor/templates/library.jinja2
diff --git a/buildout.cfg b/buildout.cfg
new file mode 100644
index 00000000..5dd40ea1
--- /dev/null
+++ b/buildout.cfg
@@ -0,0 +1,8 @@
+[buildout]
+parts = scripts
+eggs = beat.editor
+develop = .
+newest = false
+
+[scripts]
+recipe = bob.buildout:scripts
diff --git a/conda/meta.yaml b/conda/meta.yaml
new file mode 100644
index 00000000..3a97fb5e
--- /dev/null
+++ b/conda/meta.yaml
@@ -0,0 +1,65 @@
+{% set name = 'beat.editor' %}
+{% set project_dir = environ.get('RECIPE_DIR') + '/..' %}
+
+package:
+  name: {{ name }}
+  version: {{ environ.get('BOB_PACKAGE_VERSION', '0.0.1') }}
+
+build:
+  entry_points:
+    - beatedit = beat.editor.scripts.server:main
+  number: {{ environ.get('BOB_BUILD_NUMBER', 0) }}
+  run_exports:
+    - {{ pin_subpackage(name) }}
+  script:
+    - cd {{ project_dir }}
+    {% if environ.get('BUILD_EGG') %}
+    - python setup.py sdist --formats=zip
+    {% endif %}
+    - python setup.py install --single-version-externally-managed --record record.txt
+
+requirements:
+  host:
+    - python {{ python }}
+    - setuptools {{ setuptools }}
+    - nodejs {{ nodejs }}
+  run:
+    - python
+    - setuptools
+    - simplejson
+    - jinja2
+    - flask
+    - flask-cors
+    - flask-restful
+    - enum34  # [py<34]
+
+test:
+  source_files:
+    - js
+
+  requires:
+    - bob-devel {{ bob_devel }}.*
+    - beat-devel {{ beat_devel }}.*
+    - bob.extension
+    - nose
+    - coverage
+    - sphinx
+    - sphinx_rtd_theme
+    - nodejs
+
+  imports:
+    - {{ name }}
+
+  commands:
+    - beatedit --help
+    - nosetests --with-coverage --cover-package={{ name }} -sv {{ name }}
+    - sphinx-build -aEW {{ project_dir }}/doc {{ project_dir }}/sphinx
+    - sphinx-build -aEb doctest {{ project_dir }}/doc sphinx
+    - conda inspect linkages -p $PREFIX {{ name }}  # [not win]
+    - conda inspect objects -p $PREFIX {{ name }}  # [osx]
+
+about:
+  home: https://www.idiap.ch/software/beat/
+  license: AGPLv3
+  summary: Local editor for BEAT objects
+  license_family: AGPL
diff --git a/DEV.md b/doc/DEV.md
similarity index 100%
rename from DEV.md
rename to doc/DEV.md
diff --git a/README.md b/doc/README.md
similarity index 100%
rename from README.md
rename to doc/README.md
diff --git a/doc/api.rst b/doc/api.rst
new file mode 100644
index 00000000..a5028650
--- /dev/null
+++ b/doc/api.rst
@@ -0,0 +1,10 @@
+
+=====
+ API
+=====
+
+This section includes information for using the Python API of
+``beat.editor``.
+
+.. automodule:: beat.editor
+
diff --git a/doc/conf.py b/doc/conf.py
new file mode 100644
index 00000000..b2edea37
--- /dev/null
+++ b/doc/conf.py
@@ -0,0 +1,265 @@
+#!/usr/bin/env python
+# vim: set fileencoding=utf-8 :
+
+import os
+import sys
+import glob
+import pkg_resources
+
+
+# -- General configuration -----------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+needs_sphinx = '1.3'
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = [
+    'sphinx.ext.todo',
+    'sphinx.ext.coverage',
+    'sphinx.ext.ifconfig',
+    'sphinx.ext.autodoc',
+    'sphinx.ext.autosummary',
+    'sphinx.ext.doctest',
+    'sphinx.ext.graphviz',
+    'sphinx.ext.intersphinx',
+    'sphinx.ext.napoleon',
+    'sphinx.ext.viewcode',
+    'sphinx.ext.mathjax',
+    #'matplotlib.sphinxext.plot_directive'
+    ]
+
+# Be picky about warnings
+nitpicky = True
+
+# Ignores stuff we can't easily resolve on other project's sphinx manuals
+nitpick_ignore = []
+
+# Allows the user to override warnings from a separate file
+if os.path.exists('nitpick-exceptions.txt'):
+    for line in open('nitpick-exceptions.txt'):
+        if line.strip() == "" or line.startswith("#"):
+            continue
+        dtype, target = line.split(None, 1)
+        target = target.strip()
+        try: # python 2.x
+            target = unicode(target)
+        except NameError:
+            pass
+        nitpick_ignore.append((dtype, target))
+
+# Always includes todos
+todo_include_todos = True
+
+# Generates auto-summary automatically
+autosummary_generate = True
+
+# Create numbers on figures with captions
+numfig = True
+
+# If we are on OSX, the 'dvipng' path maybe different
+dvipng_osx = '/opt/local/libexec/texlive/binaries/dvipng'
+if os.path.exists(dvipng_osx): pngmath_dvipng = dvipng_osx
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'beat.backend.python'
+import time
+copyright = u'%s, Idiap Research Institute' % time.strftime('%Y')
+
+# Grab the setup entry
+distribution = pkg_resources.require(project)[0]
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = distribution.version
+# The full version, including alpha/beta/rc tags.
+release = distribution.version
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['links.rst']
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+# Some variables which are useful for generated material
+project_variable = project.replace('.', '_')
+short_description = u'Biometrics Evaluation and Testing Platform (Python backend)'
+owner = [u'Idiap Research Institute']
+
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
+import sphinx_rtd_theme
+html_theme = 'sphinx_rtd_theme'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further.  For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
+
+# The name for this set of Sphinx documents.  If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar.  Default is the same as html_title.
+#html_short_title = project_variable
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+html_logo = 'img/logo.png'
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+html_favicon = 'img/favicon.ico'
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+#html_static_path = ['_static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it.  The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = project_variable + u'_doc'
+
+
+# -- Post configuration --------------------------------------------------------
+
+# Included after all input documents
+rst_epilog = """
+.. |project| replace:: BEAT
+.. |version| replace:: %s
+.. |current-year| date:: %%Y
+""" % (version,)
+
+# Default processing flags for sphinx
+autoclass_content = 'class'
+autodoc_member_order = 'bysource'
+autodoc_default_flags = [
+  'members',
+  'undoc-members',
+  'show-inheritance',
+  ]
+
+# For inter-documentation mapping:
+from bob.extension.utils import link_documentation, load_requirements
+sphinx_requirements = "extra-intersphinx.txt"
+if os.path.exists(sphinx_requirements):
+  intersphinx_mapping = link_documentation(
+      additional_packages=['python','numpy'] + \
+          load_requirements(sphinx_requirements)
+          )
+else:
+  intersphinx_mapping = link_documentation()
+
+# Adds simplejson, pyzmq links
+intersphinx_mapping['http://simplejson.readthedocs.io/en/stable/'] = None
+intersphinx_mapping['http://pyzmq.readthedocs.io/en/stable/'] = None
+
+# We want to remove all private (i.e. _. or __.__) members
+# that are not in the list of accepted functions
+accepted_private_functions = ['__array__']
+
+def member_function_test(app, what, name, obj, skip, options):
+  # test if we have a private function
+  if len(name) > 1 and name[0] == '_':
+    # test if this private function should be allowed
+    if name not in accepted_private_functions:
+      # omit privat functions that are not in the list of accepted private functions
+      return skip
+    else:
+      # test if the method is documented
+      if not hasattr(obj, '__doc__') or not obj.__doc__:
+        return skip
+  return False
+
+def setup(app):
+  app.connect('autodoc-skip-member', member_function_test)
diff --git a/doc/img/favicon.ico b/doc/img/favicon.ico
new file mode 100644
index 0000000000000000000000000000000000000000..acbc0d0056cc417e7e8b71c3aac7231df78e46b7
GIT binary patch
literal 27438
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
RCZR`!f!QDeoevTNVE}BrON{^k

literal 0
HcmV?d00001

diff --git a/doc/img/logo.png b/doc/img/logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..180021b7d25cf7bee47a4c38039562462265c8ab
GIT binary patch
literal 13399
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

literal 0
HcmV?d00001

diff --git a/doc/index.rst b/doc/index.rst
new file mode 100644
index 00000000..8688cbc8
--- /dev/null
+++ b/doc/index.rst
@@ -0,0 +1,43 @@
+.. vim: set fileencoding=utf-8 :
+
+.. Copyright (c) 2016 Idiap Research Institute, http://www.idiap.ch/          ..
+.. Contact: beat.support@idiap.ch                                             ..
+..                                                                            ..
+.. This file is part of the beat.editor module of the BEAT platform.  ..
+..                                                                            ..
+.. Commercial License Usage                                                   ..
+.. Licensees holding valid commercial BEAT licenses may use this file in      ..
+.. accordance with the terms contained in a written agreement between you     ..
+.. and Idiap. For further information contact tto@idiap.ch                    ..
+..                                                                            ..
+.. Alternatively, this file may be used under the terms of the GNU Affero     ..
+.. Public License version 3 as published by the Free Software and appearing   ..
+.. in the file LICENSE.AGPL included in the packaging of this file.           ..
+.. The BEAT platform is distributed in the hope that it will be useful, but   ..
+.. WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ..
+.. or FITNESS FOR A PARTICULAR PURPOSE.                                       ..
+..                                                                            ..
+.. You should have received a copy of the GNU Affero Public License along     ..
+.. with the BEAT platform. If not, see http://www.gnu.org/licenses/.          ..
+
+
+===============================
+ Local editor for BEAT objects
+===============================
+
+.. todo::
+
+   Write user guide
+
+
+.. toctree::
+
+   api
+
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
diff --git a/licenses.md b/doc/licenses.md
similarity index 100%
rename from licenses.md
rename to doc/licenses.md
diff --git a/doc/nitpick-exceptions.txt b/doc/nitpick-exceptions.txt
new file mode 100644
index 00000000..2f250370
--- /dev/null
+++ b/doc/nitpick-exceptions.txt
@@ -0,0 +1,10 @@
+# Not available in Python 2.7, but ok in Python 3.x
+py:exc TypeError
+py:exc RuntimeError
+py:exc ValueError
+py:exc KeyError
+py:class tuple
+py:class list
+
+# Issue on the simplejson documentation
+py:class simplejson.encoder.JSONEncoder
diff --git a/.babelrc b/js/.babelrc
similarity index 100%
rename from .babelrc
rename to js/.babelrc
diff --git a/.eslintrc.js b/js/.eslintrc.js
similarity index 100%
rename from .eslintrc.js
rename to js/.eslintrc.js
diff --git a/.flowconfig b/js/.flowconfig
similarity index 100%
rename from .flowconfig
rename to js/.flowconfig
diff --git a/.nvmrc b/js/.nvmrc
similarity index 100%
rename from .nvmrc
rename to js/.nvmrc
diff --git a/.postcssrc b/js/.postcssrc
similarity index 100%
rename from .postcssrc
rename to js/.postcssrc
diff --git a/.stylelintrc b/js/.stylelintrc
similarity index 100%
rename from .stylelintrc
rename to js/.stylelintrc
diff --git a/.tern-project b/js/.tern-project
similarity index 100%
rename from .tern-project
rename to js/.tern-project
diff --git a/index.html b/js/index.html
similarity index 100%
rename from index.html
rename to js/index.html
diff --git a/karma.conf.js b/js/karma.conf.js
similarity index 100%
rename from karma.conf.js
rename to js/karma.conf.js
diff --git a/main.css b/js/main.css
similarity index 100%
rename from main.css
rename to js/main.css
diff --git a/main.jsx b/js/main.jsx
similarity index 100%
rename from main.jsx
rename to js/main.jsx
diff --git a/package-lock.json b/js/package-lock.json
similarity index 100%
rename from package-lock.json
rename to js/package-lock.json
diff --git a/package.json b/js/package.json
similarity index 100%
rename from package.json
rename to js/package.json
diff --git a/src/components/App.jsx b/js/src/components/App.jsx
similarity index 100%
rename from src/components/App.jsx
rename to js/src/components/App.jsx
diff --git a/src/components/CacheInput.jsx b/js/src/components/CacheInput.jsx
similarity index 100%
rename from src/components/CacheInput.jsx
rename to js/src/components/CacheInput.jsx
diff --git a/src/components/CacheInput.spec.jsx b/js/src/components/CacheInput.spec.jsx
similarity index 100%
rename from src/components/CacheInput.spec.jsx
rename to js/src/components/CacheInput.spec.jsx
diff --git a/src/components/DeleteInputBtn.jsx b/js/src/components/DeleteInputBtn.jsx
similarity index 100%
rename from src/components/DeleteInputBtn.jsx
rename to js/src/components/DeleteInputBtn.jsx
diff --git a/src/components/DeleteInputBtn.spec.jsx b/js/src/components/DeleteInputBtn.spec.jsx
similarity index 100%
rename from src/components/DeleteInputBtn.spec.jsx
rename to js/src/components/DeleteInputBtn.spec.jsx
diff --git a/src/components/EntityDetail.jsx b/js/src/components/EntityDetail.jsx
similarity index 100%
rename from src/components/EntityDetail.jsx
rename to js/src/components/EntityDetail.jsx
diff --git a/src/components/EntityHome.jsx b/js/src/components/EntityHome.jsx
similarity index 100%
rename from src/components/EntityHome.jsx
rename to js/src/components/EntityHome.jsx
diff --git a/src/components/EntityList.jsx b/js/src/components/EntityList.jsx
similarity index 100%
rename from src/components/EntityList.jsx
rename to js/src/components/EntityList.jsx
diff --git a/src/components/EntityTemplateGenerationButton.jsx b/js/src/components/EntityTemplateGenerationButton.jsx
similarity index 100%
rename from src/components/EntityTemplateGenerationButton.jsx
rename to js/src/components/EntityTemplateGenerationButton.jsx
diff --git a/src/components/HomeContent.jsx b/js/src/components/HomeContent.jsx
similarity index 100%
rename from src/components/HomeContent.jsx
rename to js/src/components/HomeContent.jsx
diff --git a/src/components/InfoTooltip.jsx b/js/src/components/InfoTooltip.jsx
similarity index 100%
rename from src/components/InfoTooltip.jsx
rename to js/src/components/InfoTooltip.jsx
diff --git a/src/components/MainContent.jsx b/js/src/components/MainContent.jsx
similarity index 100%
rename from src/components/MainContent.jsx
rename to js/src/components/MainContent.jsx
diff --git a/src/components/MainNav.jsx b/js/src/components/MainNav.jsx
similarity index 100%
rename from src/components/MainNav.jsx
rename to js/src/components/MainNav.jsx
diff --git a/src/components/NewEntityModal.jsx b/js/src/components/NewEntityModal.jsx
similarity index 100%
rename from src/components/NewEntityModal.jsx
rename to js/src/components/NewEntityModal.jsx
diff --git a/src/components/ParameterConsume.jsx b/js/src/components/ParameterConsume.jsx
similarity index 100%
rename from src/components/ParameterConsume.jsx
rename to js/src/components/ParameterConsume.jsx
diff --git a/src/components/ParameterCreate.jsx b/js/src/components/ParameterCreate.jsx
similarity index 100%
rename from src/components/ParameterCreate.jsx
rename to js/src/components/ParameterCreate.jsx
diff --git a/src/components/SearchBar.jsx b/js/src/components/SearchBar.jsx
similarity index 100%
rename from src/components/SearchBar.jsx
rename to js/src/components/SearchBar.jsx
diff --git a/src/components/Settings.jsx b/js/src/components/Settings.jsx
similarity index 100%
rename from src/components/Settings.jsx
rename to js/src/components/Settings.jsx
diff --git a/src/components/TypedField.jsx b/js/src/components/TypedField.jsx
similarity index 100%
rename from src/components/TypedField.jsx
rename to js/src/components/TypedField.jsx
diff --git a/src/components/ValidSchemaBadge.jsx b/js/src/components/ValidSchemaBadge.jsx
similarity index 100%
rename from src/components/ValidSchemaBadge.jsx
rename to js/src/components/ValidSchemaBadge.jsx
diff --git a/src/components/ValidSchemaBadge.spec.jsx b/js/src/components/ValidSchemaBadge.spec.jsx
similarity index 100%
rename from src/components/ValidSchemaBadge.spec.jsx
rename to js/src/components/ValidSchemaBadge.spec.jsx
diff --git a/src/components/algorithm/AlgorithmEditor.jsx b/js/src/components/algorithm/AlgorithmEditor.jsx
similarity index 100%
rename from src/components/algorithm/AlgorithmEditor.jsx
rename to js/src/components/algorithm/AlgorithmEditor.jsx
diff --git a/src/components/algorithm/AlgorithmEditor.spec.jsx b/js/src/components/algorithm/AlgorithmEditor.spec.jsx
similarity index 100%
rename from src/components/algorithm/AlgorithmEditor.spec.jsx
rename to js/src/components/algorithm/AlgorithmEditor.spec.jsx
diff --git a/src/components/algorithm/index.js b/js/src/components/algorithm/index.js
similarity index 100%
rename from src/components/algorithm/index.js
rename to js/src/components/algorithm/index.js
diff --git a/src/components/database/DatabaseEditor.css b/js/src/components/database/DatabaseEditor.css
similarity index 100%
rename from src/components/database/DatabaseEditor.css
rename to js/src/components/database/DatabaseEditor.css
diff --git a/src/components/database/DatabaseEditor.jsx b/js/src/components/database/DatabaseEditor.jsx
similarity index 100%
rename from src/components/database/DatabaseEditor.jsx
rename to js/src/components/database/DatabaseEditor.jsx
diff --git a/src/components/database/DatabaseEditor.spec.jsx b/js/src/components/database/DatabaseEditor.spec.jsx
similarity index 100%
rename from src/components/database/DatabaseEditor.spec.jsx
rename to js/src/components/database/DatabaseEditor.spec.jsx
diff --git a/src/components/database/index.js b/js/src/components/database/index.js
similarity index 100%
rename from src/components/database/index.js
rename to js/src/components/database/index.js
diff --git a/src/components/dataformat/DataformatEditor.jsx b/js/src/components/dataformat/DataformatEditor.jsx
similarity index 100%
rename from src/components/dataformat/DataformatEditor.jsx
rename to js/src/components/dataformat/DataformatEditor.jsx
diff --git a/src/components/dataformat/DataformatEditor.spec.jsx b/js/src/components/dataformat/DataformatEditor.spec.jsx
similarity index 100%
rename from src/components/dataformat/DataformatEditor.spec.jsx
rename to js/src/components/dataformat/DataformatEditor.spec.jsx
diff --git a/src/components/dataformat/index.js b/js/src/components/dataformat/index.js
similarity index 100%
rename from src/components/dataformat/index.js
rename to js/src/components/dataformat/index.js
diff --git a/src/components/experiment/ExperimentEditor.css b/js/src/components/experiment/ExperimentEditor.css
similarity index 100%
rename from src/components/experiment/ExperimentEditor.css
rename to js/src/components/experiment/ExperimentEditor.css
diff --git a/src/components/experiment/ExperimentEditor.jsx b/js/src/components/experiment/ExperimentEditor.jsx
similarity index 100%
rename from src/components/experiment/ExperimentEditor.jsx
rename to js/src/components/experiment/ExperimentEditor.jsx
diff --git a/src/components/experiment/ExperimentEditor.spec.jsx b/js/src/components/experiment/ExperimentEditor.spec.jsx
similarity index 100%
rename from src/components/experiment/ExperimentEditor.spec.jsx
rename to js/src/components/experiment/ExperimentEditor.spec.jsx
diff --git a/src/components/experiment/index.js b/js/src/components/experiment/index.js
similarity index 100%
rename from src/components/experiment/index.js
rename to js/src/components/experiment/index.js
diff --git a/src/components/library/LibraryEditor.jsx b/js/src/components/library/LibraryEditor.jsx
similarity index 100%
rename from src/components/library/LibraryEditor.jsx
rename to js/src/components/library/LibraryEditor.jsx
diff --git a/src/components/library/LibraryEditor.spec.jsx b/js/src/components/library/LibraryEditor.spec.jsx
similarity index 100%
rename from src/components/library/LibraryEditor.spec.jsx
rename to js/src/components/library/LibraryEditor.spec.jsx
diff --git a/src/components/library/index.js b/js/src/components/library/index.js
similarity index 100%
rename from src/components/library/index.js
rename to js/src/components/library/index.js
diff --git a/src/components/plotter/PlotterEditor.jsx b/js/src/components/plotter/PlotterEditor.jsx
similarity index 100%
rename from src/components/plotter/PlotterEditor.jsx
rename to js/src/components/plotter/PlotterEditor.jsx
diff --git a/js/src/components/plotter/PlotterEditor.spec.jsx b/js/src/components/plotter/PlotterEditor.spec.jsx
new file mode 100644
index 00000000..e69de29b
diff --git a/src/components/plotter/index.js b/js/src/components/plotter/index.js
similarity index 100%
rename from src/components/plotter/index.js
rename to js/src/components/plotter/index.js
diff --git a/src/components/plotterparameter/PlotterParameterEditor.jsx b/js/src/components/plotterparameter/PlotterParameterEditor.jsx
similarity index 100%
rename from src/components/plotterparameter/PlotterParameterEditor.jsx
rename to js/src/components/plotterparameter/PlotterParameterEditor.jsx
diff --git a/js/src/components/plotterparameter/PlotterParameterEditor.spec.jsx b/js/src/components/plotterparameter/PlotterParameterEditor.spec.jsx
new file mode 100644
index 00000000..e69de29b
diff --git a/src/components/plotterparameter/index.js b/js/src/components/plotterparameter/index.js
similarity index 100%
rename from src/components/plotterparameter/index.js
rename to js/src/components/plotterparameter/index.js
diff --git a/src/components/toolchain/GraphicalEditor.css b/js/src/components/toolchain/GraphicalEditor.css
similarity index 100%
rename from src/components/toolchain/GraphicalEditor.css
rename to js/src/components/toolchain/GraphicalEditor.css
diff --git a/src/components/toolchain/GraphicalEditor.jsx b/js/src/components/toolchain/GraphicalEditor.jsx
similarity index 100%
rename from src/components/toolchain/GraphicalEditor.jsx
rename to js/src/components/toolchain/GraphicalEditor.jsx
diff --git a/src/components/toolchain/GraphicalEditorHelpModal.jsx b/js/src/components/toolchain/GraphicalEditorHelpModal.jsx
similarity index 100%
rename from src/components/toolchain/GraphicalEditorHelpModal.jsx
rename to js/src/components/toolchain/GraphicalEditorHelpModal.jsx
diff --git a/src/components/toolchain/InsertObjectModal.jsx b/js/src/components/toolchain/InsertObjectModal.jsx
similarity index 100%
rename from src/components/toolchain/InsertObjectModal.jsx
rename to js/src/components/toolchain/InsertObjectModal.jsx
diff --git a/src/components/toolchain/RenameGroupModal.jsx b/js/src/components/toolchain/RenameGroupModal.jsx
similarity index 100%
rename from src/components/toolchain/RenameGroupModal.jsx
rename to js/src/components/toolchain/RenameGroupModal.jsx
diff --git a/src/components/toolchain/ToolchainBlock.jsx b/js/src/components/toolchain/ToolchainBlock.jsx
similarity index 100%
rename from src/components/toolchain/ToolchainBlock.jsx
rename to js/src/components/toolchain/ToolchainBlock.jsx
diff --git a/src/components/toolchain/ToolchainConnection.jsx b/js/src/components/toolchain/ToolchainConnection.jsx
similarity index 100%
rename from src/components/toolchain/ToolchainConnection.jsx
rename to js/src/components/toolchain/ToolchainConnection.jsx
diff --git a/src/components/toolchain/ToolchainConnection.spec.jsx b/js/src/components/toolchain/ToolchainConnection.spec.jsx
similarity index 100%
rename from src/components/toolchain/ToolchainConnection.spec.jsx
rename to js/src/components/toolchain/ToolchainConnection.spec.jsx
diff --git a/src/components/toolchain/ToolchainEditor.css b/js/src/components/toolchain/ToolchainEditor.css
similarity index 100%
rename from src/components/toolchain/ToolchainEditor.css
rename to js/src/components/toolchain/ToolchainEditor.css
diff --git a/src/components/toolchain/ToolchainEditor.jsx b/js/src/components/toolchain/ToolchainEditor.jsx
similarity index 100%
rename from src/components/toolchain/ToolchainEditor.jsx
rename to js/src/components/toolchain/ToolchainEditor.jsx
diff --git a/src/components/toolchain/ToolchainEditor.spec.jsx b/js/src/components/toolchain/ToolchainEditor.spec.jsx
similarity index 100%
rename from src/components/toolchain/ToolchainEditor.spec.jsx
rename to js/src/components/toolchain/ToolchainEditor.spec.jsx
diff --git a/src/components/toolchain/ToolchainModal.jsx b/js/src/components/toolchain/ToolchainModal.jsx
similarity index 100%
rename from src/components/toolchain/ToolchainModal.jsx
rename to js/src/components/toolchain/ToolchainModal.jsx
diff --git a/src/components/toolchain/index.js b/js/src/components/toolchain/index.js
similarity index 100%
rename from src/components/toolchain/index.js
rename to js/src/components/toolchain/index.js
diff --git a/src/components/toolchain/types.js b/js/src/components/toolchain/types.js
similarity index 100%
rename from src/components/toolchain/types.js
rename to js/src/components/toolchain/types.js
diff --git a/src/helpers/api.js b/js/src/helpers/api.js
similarity index 100%
rename from src/helpers/api.js
rename to js/src/helpers/api.js
diff --git a/src/helpers/beat.js b/js/src/helpers/beat.js
similarity index 100%
rename from src/helpers/beat.js
rename to js/src/helpers/beat.js
diff --git a/src/helpers/index.js b/js/src/helpers/index.js
similarity index 100%
rename from src/helpers/index.js
rename to js/src/helpers/index.js
diff --git a/src/helpers/schema/algorithm.json b/js/src/helpers/schema/algorithm.json
similarity index 100%
rename from src/helpers/schema/algorithm.json
rename to js/src/helpers/schema/algorithm.json
diff --git a/src/helpers/schema/common.json b/js/src/helpers/schema/common.json
similarity index 100%
rename from src/helpers/schema/common.json
rename to js/src/helpers/schema/common.json
diff --git a/src/helpers/schema/database.json b/js/src/helpers/schema/database.json
similarity index 100%
rename from src/helpers/schema/database.json
rename to js/src/helpers/schema/database.json
diff --git a/src/helpers/schema/dataformat.json b/js/src/helpers/schema/dataformat.json
similarity index 100%
rename from src/helpers/schema/dataformat.json
rename to js/src/helpers/schema/dataformat.json
diff --git a/src/helpers/schema/execution.json b/js/src/helpers/schema/execution.json
similarity index 100%
rename from src/helpers/schema/execution.json
rename to js/src/helpers/schema/execution.json
diff --git a/src/helpers/schema/experiment.json b/js/src/helpers/schema/experiment.json
similarity index 100%
rename from src/helpers/schema/experiment.json
rename to js/src/helpers/schema/experiment.json
diff --git a/src/helpers/schema/index.js b/js/src/helpers/schema/index.js
similarity index 100%
rename from src/helpers/schema/index.js
rename to js/src/helpers/schema/index.js
diff --git a/src/helpers/schema/library.json b/js/src/helpers/schema/library.json
similarity index 100%
rename from src/helpers/schema/library.json
rename to js/src/helpers/schema/library.json
diff --git a/src/helpers/schema/plotter.json b/js/src/helpers/schema/plotter.json
similarity index 100%
rename from src/helpers/schema/plotter.json
rename to js/src/helpers/schema/plotter.json
diff --git a/src/helpers/schema/plotterparameter.json b/js/src/helpers/schema/plotterparameter.json
similarity index 100%
rename from src/helpers/schema/plotterparameter.json
rename to js/src/helpers/schema/plotterparameter.json
diff --git a/src/helpers/schema/toolchain.json b/js/src/helpers/schema/toolchain.json
similarity index 100%
rename from src/helpers/schema/toolchain.json
rename to js/src/helpers/schema/toolchain.json
diff --git a/src/helpers/search.worker.js b/js/src/helpers/search.worker.js
similarity index 100%
rename from src/helpers/search.worker.js
rename to js/src/helpers/search.worker.js
diff --git a/src/store/actionTypes.js b/js/src/store/actionTypes.js
similarity index 100%
rename from src/store/actionTypes.js
rename to js/src/store/actionTypes.js
diff --git a/src/store/actions.js b/js/src/store/actions.js
similarity index 100%
rename from src/store/actions.js
rename to js/src/store/actions.js
diff --git a/src/store/index.js b/js/src/store/index.js
similarity index 100%
rename from src/store/index.js
rename to js/src/store/index.js
diff --git a/src/store/reducers.js b/js/src/store/reducers.js
similarity index 100%
rename from src/store/reducers.js
rename to js/src/store/reducers.js
diff --git a/src/store/selectors.js b/js/src/store/selectors.js
similarity index 100%
rename from src/store/selectors.js
rename to js/src/store/selectors.js
diff --git a/test/index.js b/js/test/index.js
similarity index 100%
rename from test/index.js
rename to js/test/index.js
diff --git a/test/test_algs.json b/js/test/test_algs.json
similarity index 100%
rename from test/test_algs.json
rename to js/test/test_algs.json
diff --git a/test/test_dbs.json b/js/test/test_dbs.json
similarity index 100%
rename from test/test_dbs.json
rename to js/test/test_dbs.json
diff --git a/test/test_dfs.json b/js/test/test_dfs.json
similarity index 100%
rename from test/test_dfs.json
rename to js/test/test_dfs.json
diff --git a/test/test_exps.json b/js/test/test_exps.json
similarity index 100%
rename from test/test_exps.json
rename to js/test/test_exps.json
diff --git a/test/test_libs.json b/js/test/test_libs.json
similarity index 100%
rename from test/test_libs.json
rename to js/test/test_libs.json
diff --git a/test/test_tcs.json b/js/test/test_tcs.json
similarity index 100%
rename from test/test_tcs.json
rename to js/test/test_tcs.json
diff --git a/webpack.config.js b/js/webpack.config.js
similarity index 100%
rename from webpack.config.js
rename to js/webpack.config.js
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 00000000..b705bb93
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,6 @@
+setuptools
+simplejson
+jinja2
+flask
+flask-cors
+flask-restful
diff --git a/setup.py b/setup.py
new file mode 100644
index 00000000..9eb52f76
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,68 @@
+#!/usr/bin/env python
+# vim: set fileencoding=utf-8 :
+
+###############################################################################
+#                                                                             #
+# Copyright (c) 2016 Idiap Research Institute, http://www.idiap.ch/           #
+# Contact: beat.support@idiap.ch                                              #
+#                                                                             #
+# This file is part of the beat.editor module of the BEAT platform.             #
+#                                                                             #
+# Commercial License Usage                                                    #
+# Licensees holding valid commercial BEAT licenses may use this file in       #
+# accordance with the terms contained in a written agreement between you      #
+# and Idiap. For further information contact tto@idiap.ch                     #
+#                                                                             #
+# Alternatively, this file may be used under the terms of the GNU Affero      #
+# Public License version 3 as published by the Free Software and appearing    #
+# in the file LICENSE.AGPL included in the packaging of this file.            #
+# The BEAT platform is distributed in the hope that it will be useful, but    #
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY  #
+# or FITNESS FOR A PARTICULAR PURPOSE.                                        #
+#                                                                             #
+# You should have received a copy of the GNU Affero Public License along      #
+# with the BEAT platform. If not, see http://www.gnu.org/licenses/.           #
+#                                                                             #
+###############################################################################
+
+
+from setuptools import setup, find_packages
+
+def load_requirements(f):
+  retval = [str(k.strip()) for k in open(f, 'rt')]
+  return [k for k in retval if k and k[0] not in ('#', '-')]
+
+# The only thing we do in this file is to call the setup() function with all
+# parameters that define our package.
+setup(
+
+    name='beat.editor',
+    version=open("version.txt").read().rstrip(),
+    description='Local editor for BEAT objects',
+    url='https://gitlab.idiap.ch/beat/beat.editor',
+    license='AGPLv3',
+    author='Idiap Research Institute',
+    author_email='beat.support@idiap.ch',
+    long_description=open('README.rst').read(),
+
+    packages=find_packages(),
+    include_package_data=True,
+    zip_safe=False,
+    install_requires=load_requirements('requirements.txt'),
+    entry_points={
+        'console_scripts': [
+            'beatedit = beat.editor.scripts.server:main',
+        ],
+    },
+
+    classifiers = [
+        'Framework :: BEAT',
+        'Development Status :: 5 - Production/Stable',
+        'Intended Audience :: Developers',
+        'License :: OSI Approved :: GNU Affero General Public License v3',
+        'Natural Language :: English',
+        'Programming Language :: Python',
+        'Programming Language :: Python :: 3',
+        'Topic :: Software Development :: Libraries :: Python Modules',
+    ],
+)
diff --git a/version.txt b/version.txt
new file mode 100644
index 00000000..cdf29915
--- /dev/null
+++ b/version.txt
@@ -0,0 +1 @@
+1.0.0b0
-- 
GitLab