diff --git a/.gitattributes b/.gitattributes index 833eaab..544c336 100644 --- a/.gitattributes +++ b/.gitattributes @@ -67,6 +67,7 @@ # build config *.npmignore text *.bowerrc text +Dockerfile text eof=LF # Heroku Procfile text @@ -123,4 +124,4 @@ AUTHORS text # Note: .db, .p, and .pkl files are associated # with the python modules ``pickle``, ``dbm.*``, # ``shelve``, ``marshal``, ``anydbm``, & ``bsddb`` -# (among others). \ No newline at end of file +# (among others). diff --git a/.travis.yml b/.travis.yml index b659c15..624b72c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,37 +3,50 @@ sudo: required env: - TOXENV=py27 - TOXENV=py34 - node_js: - 6 - +addons: + firefox: 49.0.1 before_install: - export DISPLAY=:99.0 - sh -e /etc/init.d/xvfb start - nvm install 6 - if [[ `npm -v` != 3* ]]; then npm i -g npm@3; fi - install: -- (!(test -f docker_packages.txt) || (cat docker_packages.txt | xargs sudo apt-get install -y)) +- "(!(test -f docker_packages.txt) || (cat docker_packages.txt | xargs sudo apt-get + install -y))" - pip install -r requirements_dev.txt - pip install -r requirements.txt - npm install - script: npm run dist - +notifications: + slack: + secure: S52ExoUgoNx1nkCaN/S4z20BBIwO0tA0+ugr8Hej19yQdbAZs10eBKPGSuGXjtW7a9V2TB03FH4Arek7b9T3yFsvSfIjNe5ztPQPfMYMeiONDSQcewSHmBcVCfDWkZ7oPC1/sbzPLKPRI1LNfo6j6ql5ZWeKEY87e7nnSMS8Zka+/zSMllCB9Q5i740uG4dB36KfmlEkY095Az9Jf5XgMWOyM9NjzqVOw69mTB0izCo17tWTYWC6mr9MiWbGn1lVV+72ZaE141lkuC2bg+UmGEjOMrMhSrIfW3LpRCOImE2GBufD3t44zBEVmPvdbfA2d9C28cRcVWCUx7F5riy/Iudi0UvzW21I4C3G7rqLz9iWcEPPoqcy2ShJd7PGq79HR6pXT3jY0f7gcvC3PLE/2dB5B5HdcSpK7forBmoLyUE4NizBsRP2qU0l8x/ups/t2Z5UNkiDjZESoISXEq7idUhvKfHrjqJfP1KgcBF7wyr/J9oxOzRakZCWn+tIcJMVXK+lGmLQI4yWtS6aHrHUODJNOUCtysbvtJjL1TIHtfXwZMSGkXBjgjz+xJEr0H+d3DPlN/nA+i6gcOjuU+dA7TYdoVZ1a8FxcfZzroCBVgOOs79mEsWPKnogHmhaj2ahFYE5guXBFy9AUM9XcGE9LIsOnurrh7Huj1qIe/oXgwg= + on_success: change + on_failure: always deploy: - provider: releases +- provider: releases api_key: - secure: TK9/P34Bi3WuppiDrBCwVcn41yCBwmILaU8hXTBzUPbT7TbeFIwsC6/4CtH85Z+ZrUve4S5pTmWRNf2dQDxWw3uYu7+bJuemV2J1LHG76mognj+TNEiYxfLQUt3Gql4W7C7FcI4Rlx5/uMN9wY1wro8TWUBMwT6jjSrUWIvK3GXoojd5bHvJx07XpjWl9wCon4D0ruZiFoM2mdeP23lbc2GckETi32oEKswnQXxkMACmxbPzoWbvkxH4aK8Bt2Rj2sl2TbPhVkN6DAkHGkGAvLI+2/aRfG27+oo3OKsaDjbuGABct8TfZccJ970CbQ8kbnCjYxstvqkg1JWjF0W67sX/flBZZOEUA5l0OLWo6HqMGMxm7/lEQhIdPMsRmvXL+HVOxkMrB2dda58QzxVwiZp+rRqUaeabPZp8Kl5xodGrVxsBvxe6zAbJ5jCtCSumG6+kLyKI00/kYlghqQNrgUw0ZsYJlQ34h3lo/24QpaeyDpQoCkGWQgtgqiXGpeKSu7bCnOqIqAy3nbT9Utwj7K8gIasTG5idosEAz/THMampNbGDuyxxc340sYGNMg9Bhm1g2ILWRdtV470p5hwBtIDTKi3/PAizEO26+Wh0zI47Sg3ao57avcbCsTmzbZUeA5J4bojmchhJCHX8su9cSCGh/2fJA/1eBIgEvOQ8LNE= + secure: YHm6ykz8crvmZTh8O2suOFvM/yyhueIE7R/yc4vH5OvlQ8lfy/tJ9QNh8OZ3LkrrWMDmhMXCvReUZaacJKc2abMtO2wX5zQn61KXvZwdrxDKdj/tKHGt7sSsZj2/QgV2eAw6xpoIOEsQqGl+jTGuyyl7EB1WyOP6ZTfGbYDJGkMEyDdrG70DzlIF7sTO/AOwTtj0DiiihVTMfa9apaX1OgjZtu65spb/QnihiGlRyW9rMYKznPLP19eUjOH/Dd5jd5aeMIWaLkF6Xsb/uus4ulOP1uOCfAP1q0ULvsn54hlL5N9zq6nX0VuAf8ieaR1N5M1AI/XO9vt5hmQ9XADfBV4OUaqIh6ZsWAjsBu6TmzL+1XFJ0G2AfF4EFT+OUuYpCmuH3tZyocqWU2C7bLxwDNkoyu6F+ge9YZCz+GThmWYJs9ELbBXwneOQwaDjKoyzQ2TVKGYqUbori8b/n5DPjJDI4qU0oNXuCwb3n77o3l5ntHOq/8+3rJkywC8Fm/g7/peW+pE3Rrb9Xo9SdKmG3vYh/WjDBoEje1hD1/LWPZJs0skOq1S0OvoI4uGKuhX1G/HQlfEGgikeXojF9xP07d3T1ZZDjKEufrHQ4RacCYRIDZrEFXLxKu7VNE87BIuo0xNVyp+1o+JrfKRdmE41mr+aIx0B+67rTyw2RKks0GQ= file_glob: true file: - - dist/phovea_security_flask*.egg - - dist/phovea_security_flask.tar.gz + - dist/phovea_security_flask*.egg + - dist/phovea_security_flask.tar.gz on: tags: true - -notifications: - slack: - secure: E8/1UIdHSczUbN+6i6gd1d5LM4vmLdwLQ30tpyjvnM0wvfDce76oPxLJAy240WJ5ybXRZUtNrttpVpt4tEXCy8aLFCmxD7s77rVloH+q1J8R/ptTFWZGhFGEujk1awEmVbzcWxJkV9/JENQaeGBKxwv8/EQwWwEkAb7p/+AJb9owmH88b3wUZUGHBWtbMiyyaF4Rm1Wg1stJB8Z1Ga7PRF4cqufTgcDdsCPVv9gAY+VxOIGqX/Vfuc9UWpUH8vq8lHUE7Inn5QS78kuFfSgLWga3H6Mu/Gko1XNlWk0QWWQBUvEZ6ZC6Wuo68KzvUjJHDTnx8WyfHue2JNHIslcX+eJq2WHLeEgM24VeNkILCGo/H/60NGHiSjrIv/Y9h6bQ9FDjo6TUyE4nbdPYN1RN9FQ5UbI9Y4Gi753H9mqnHWlEywBOzHxdZCAuz9Wh03CCF/blsvJ+Obbyo6Jrfe+g44jyi9kQdBNQ78qG6v4EXws8FiYao6x3PpgIwFix42Cpr+soAh5FpA3C1zHSAyZZpXF65/lrDl5yPNofK7Wy0B9bw+0I6Z/u7ZKFNVZXvYPGYvtUVcsALGBdmYc61+LCta36Po0KZseWVAlJj6QnOJDYzv0wvV/zsuf9A5KpYFGiqV9Q7zmtiO5FYF5sBy+lE7O9tHVO4O18IRndhRQgxhs= - on_success: change - on_failure: always + repo: phovea/phovea_security_flask +- provider: npm + email: samuel.gratzl@jku.at + api_key: + secure: xHvo+qsduckAf+nfH/e6pgHNVlv04/Yupr/fV9vdkD7Ho6Uig4wPc1s/779GIJv80ilTcv3puZnW7DMfwoutodmXWMYtAht+8lv+wSDHaG0/K9FmkJJtKhd3milvWEM4jAkmbel4amI4E+kqgJiNshXlrdsrhF9mVpyS04WEbV0dXvmFS8krYIFIhjvB3ot61pxPsGJd/DHRviVvU6+kzMLQOzlywdAZ41DfwufNtZQNqLcUsUMk+ma/1HcAljuAVi3xkdcCBQNJDEpwjCmKk9XbaMD15hy6LY+vEqKTB5HieXrFoML6cyNTMLPELuuyBRSV6JMG5k010/PgI0ODSuTARBPmbiBpa43aikD9wLEZX+O/6n9sWe4aRL5n2BU/5tUPmIZ4DC3DDGe12z1mBH8CuQdy4ZatsnU3Oc4xB8fA5z4yBljbhnD6mSF9hAgvSU/XHjMevqxm8W2fCzqGBQek0m+HuqljfuLCe90tVNAw+KMTJHI04TqxSm/b72IYYi10L+X6siQRIx4R2bAUsCLiega9EZfKyyePD9bvzh/5sZeXOVJRS6Bh/NUG2ZtJut7eH1zrr5ikt9gNgLVSeUGzE9JOrHBsFv5x7PKr6+I0PV3BaDk2lOw5ySCaUFnHbuDv+dr3HOZ2GjmxHLrMVk4IqoYieUsyWtBLKB6gk38= + on: + tags: true + repo: phovea/phovea_security_flask +- provider: pypi + user: caleydo-bot + password: + secure: tPZNRqwrS0LJ/Me3LQhovmRflUqsmtAcPPH8dqH06jz4vA1Ykof8+t3o/Qle43QRYNDN6WyLVTNwcc9045JZi9BXF3lTuXbAdpiedmGjcYUE8NabzPAYNMEMAoGTZ0e0WIoi/GaMHr1tzZPDhDkldasMsBGWYC4uLJUYBOoMtGqwwskk+3tZDLN0n+dlbF91LKbHk5trCxLIslhGhY0i5zjjzIIbV8eOMyu+Jx6T8u7mcCxZrC+1o5ydgy2PgvdZFDd1kfoYDRSnRDLRdrCXGiaKXKcAaer5091wf4iDDWUpRizZD7V9MPc62maeG40EUhju4+Tp4DGBYS26PEB9r45h3cvXremnpCiZlGGEJN7w/miGyGz72DZN2xbo/dOLSQaxdkMYZCPhiEHAA7MZ/eZopMwUfs03Hqm3zcYVwEWvj4O20/UR4uksY0uX6774YXgmrZl+jxB9SBe3AvYdvQqDT8henv/VOSCJ460TfPMHJSCvi4/G/+bVOULU+k9T9E9axi+UweTQVWbOf16iUWixFYMui2cI9jlvORz3IPsDvdicmGqC0H5z32jHo7rrho+nrKJO3s+85Mg3WPWpTYdt0qdaxvh4UOwogUWc52o0h8kARc9Bht66vi5qFm+pkXOc5HXKjZzJKbIhpKdscxVEoBWvM+v9dDqT4CMrI5o= + on: + tags: true + distributions: sdist bdist_wheel + repo: phovea/phovea_security_flask diff --git a/README.md b/README.md index 17678c5..16b468b 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ npm run build *** -This repository is part of **[Phovea](http://phovea.caleydo.org/)**, a platform for developing web-based visualization applications. For tutorials, API docs, and more information about the build and deployment process, see the [documentation page](http://caleydo.org/documentation/). +This repository is part of **[Phovea](http://phovea.caleydo.org/)**, a platform for developing web-based visualization applications. For tutorials, API docs, and more information about the build and deployment process, see the [documentation page](http://phovea.caleydo.org). [phovea-image]: https://img.shields.io/badge/Phovea-Client%20Plugin-F47D20.svg @@ -40,5 +40,5 @@ This repository is part of **[Phovea](http://phovea.caleydo.org/)**, a platform [npm-url]: https://npmjs.org/package/phovea_security_flask [travis-image]: https://travis-ci.org/phovea/phovea_security_flask.svg?branch=master [travis-url]: https://travis-ci.org/phovea/phovea_security_flask -[daviddm-image]: https://david-dm.org/phovea/phovea_security_flask.svg?theme=shields.io +[daviddm-image]: https://david-dm.org/phovea/phovea_security_flask/status.svg [daviddm-url]: https://david-dm.org/phovea/phovea_security_flask diff --git a/build.py b/build.py new file mode 100644 index 0000000..2a12e00 --- /dev/null +++ b/build.py @@ -0,0 +1,51 @@ +import shutil +from codecs import open +import json + +__author__ = 'Samuel Gratzl' + + +def _git_head(cwd): + import subprocess + try: + output = subprocess.check_output(['git', 'rev-parse', '--verify', 'HEAD'], cwd=cwd) + return output.strip() + except subprocess.CalledProcessError: + return 'error' + + +def _resolve_plugin(repo, version): + import os.path + if os.path.isdir('.git') and repo: + if repo.endswith('.git'): + repo = repo[0:-4] + return repo + '/commit/' + _git_head('.') + # not a git repo + return version + + +def to_version(v): + import datetime + now = datetime.datetime.utcnow() + return v.replace('SNAPSHOT', now.strftime('%Y%m%d-%H%M%S')) + + +with open('package.json', 'r', encoding='utf-8') as f: + pkg = json.load(f) + +name = pkg['name'] +version = to_version(pkg['version']) +resolved = _resolve_plugin(pkg.get('repository', {}).get('url'), version) + +# copy source code +shutil.rmtree('build/source/' + name, ignore_errors=True) +shutil.copytree(name, 'build/source/' + name, symlinks=False, ignore=shutil.ignore_patterns('*.pyc')) + +# create buildInfo.json +build_info = dict(name=name, version=version, resolved=resolved, description=pkg['description'], + homepage=pkg.get('homepage'), repository=pkg.get('repository', {}).get('url')) + +# TODO create build Info + +with open('build/source/' + name + '/buildInfo.json', 'w', encoding='utf-8') as f: + json.dump(build_info, f, indent=2) diff --git a/buildInfo.js b/buildInfo.js index 0ed7c45..3814ddc 100644 --- a/buildInfo.js +++ b/buildInfo.js @@ -39,7 +39,7 @@ function resolveModules() { const reg = fs.readFileSync('../phovea_registry.js').toString(); const regex = /import '(.*)\/phovea_registry.js'/g; const modules = []; - var r; + let r; while ((r = regex.exec(reg)) !== null) { modules.push(r[1]); } @@ -59,10 +59,11 @@ function resolveWorkspace() { console.log('resolve', m); const pkg = require(`../${m}/package.json`); const head = gitHead('../' + m); + const repo = pkg.repository.url; return { name: pkg.name, version: pkg.version, - resolved: head ? `${pkg.repository.url}#${head}` : pkg.version, + resolved: head ? `${repo.endsWith('.git') ? repo.slice(0, repo.length-4) : repo}/commit/${head}` : pkg.version, dependencies: deps(pkg.dependencies) }; }; @@ -137,13 +138,40 @@ function tmpdir() { } } +function resolveScreenshot() { + const f = resolve(__dirname, 'media/screenshot.png'); + if (!fs.existsSync(f)) { + return null; + } + const buffer = new Buffer(fs.readFileSync(f)).toString('base64'); + return `data:image/png;base64,${buffer}`; +} + +function metaData(pkg) { + pkg = pkg || require(`./package.json`); + return { + name: pkg.name, + version: pkg.version, + repository: pkg.repository.url, + description: pkg.description, + screenshot: resolveScreenshot() + }; +} + +module.exports.metaData = metaData; +module.exports.metaDataTmpFile = function(pkg) { + const s = metaData(pkg); + const file = `${tmpdir()}/metaData${Math.random().toString(36).slice(-8)}.txt`; + fs.writeFileSync(file, JSON.stringify(s, null, ' ')); + return file; +}; module.exports.generate = generate; module.exports.tmpFile = function() { const s = generate(); const file = `${tmpdir()}/buildInfo${Math.random().toString(36).slice(-8)}.txt`; fs.writeFileSync(file, JSON.stringify(s, null, ' ')); return file; -} +}; if (require.main === module) { diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 0000000..0af02c8 --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1,3 @@ +/modules.rst +/phovea_server.rst + diff --git a/docs/_static/touch.txt b/docs/_static/touch.txt new file mode 100644 index 0000000..e69de29 diff --git a/docs/_templates/touch.txt b/docs/_templates/touch.txt new file mode 100644 index 0000000..e69de29 diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..cf81bf7 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,126 @@ +# -*- coding: utf-8 -*- +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import sys +import os +import json +from codecs import open + +sys.path.insert(0, os.path.abspath('..')) + +with open('../package.json', encoding='utf-8') as json_data: + import json + + pkg = json.load(json_data) + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = ['sphinx.ext.autodoc', + 'sphinx.ext.intersphinx', + 'sphinx.ext.todo'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +source_parsers = { + '.md': 'recommonmark.parser.CommonMarkParser', +} +source_suffix = ['.rst', '.md'] + +# The master toctree document. +master_doc = 'index' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This patterns also effect to html_static_path and html_extra_path +exclude_patterns = ['build', 'tests'] + +# General information about the project. +project = pkg['name'] +copyright = pkg['license'] +author = pkg['author']['name'] + +# 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 = pkg['version'] +# The full version, including alpha/beta/rc tags. +release = pkg['version'] + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = True + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'alabaster' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# -- Options for HTMLHelp output ------------------------------------------ + +# Output file base name for HTML help builder. +htmlhelp_basename = pkg['name'] + 'doc' + +# Sort members by type +autodoc_member_order = 'groupwise' + + +# Ensure that the __init__ method gets documented. +def skip(app, what, name, obj, skip, options): + if name == '__init__': + return False + return skip + + +def setup(app): + app.connect('autodoc-skip-member', skip) + + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = {'https://docs.python.org/': None} diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..4c52050 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,20 @@ +.. phovea_security_flask documentation master file, created by + sphinx-quickstart on Tue Feb 7 19:42:32 2017. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to phovea_security_flask's documentation! +========================================= + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + modules + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/package.json b/package.json index 04f8ab2..591ee3f 100644 --- a/package.json +++ b/package.json @@ -19,32 +19,35 @@ "pretest:python": "npm run check", "posttest:web": "npm run lint", "pretest": "echo hybrid", - "test:web": "karma start", + "test:web": "test ! -d tests || karma start", "test:python": "test ! -d tests || python setup.py test", "test": "npm run test:web && npm run test:python", "compile": "tsc", "lint": "tslint -c tslint.json src/**.ts tests/**.ts", "docs:web": "typedoc --options typedoc.json src/**.ts", - "docs:python": "echo todo creating docs...", + "docs:python": "sphinx-apidoc -o docs -f ./phovea_security_flask && sphinx-build ./docs build/docs", "docs": "npm run docs:web && npm run docs:python", - "prebuild": "node -e \"process.exit(process.env.PHOVEA_SKIP_TESTS === undefined?1:0)\" || npm run test", + "prebuild": "echo hybrid", "posttest": "echo hybrid", "test:watch": "karma start --autoWatch=true --singleRun=false", "build:dev": "webpack", - "build:python": "python -c \"from distutils.dir_util import mkpath ; mkpath('./build/source')\" && (tar -c ./phovea_security_flask --exclude '*.pyc' | tar -xC build/source)", + "build:python": "python build.py", "build:web": "webpack --env prod", - "build": "npm run build:web && npm run build:python", + "build": "npm run build:web && npm run build:python", "start": "webpack-dev-server --inline", "start:hot": "webpack-dev-server --inline --hot", "watch": "webpack --watch", "release:major": "npm version major && npm publish && git push --follow-tags", "release:minor": "npm version minor && npm publish && git push --follow-tags", "release:patch": "npm version patch && npm publish && git push --follow-tags", - "predist:web": "npm run build", + "predist:web": "npm run build:web && npm run docs:web", "predist": "echo hybrid", "dist:web": "mkdirp dist && cd build && tar cvzf ../dist/phovea_security_flask.tar.gz *", "dist:python": "python setup.py bdist_egg", - "dist": "npm run dist:web && npm run dist:python" + "dist": "npm run dist:web && npm run dist:python", + "prebuild:python": "node -e \"process.exit(process.env.PHOVEA_SKIP_TESTS === undefined?1:0)\" || npm run test:python", + "prebuild:web": "node -e \"process.exit(process.env.PHOVEA_SKIP_TESTS === undefined?1:0)\" || npm run test:web", + "predist:python": "npm run build:python && npm run docs:python" }, "main": "build/phovea_security_flask.js", "engines": { @@ -53,12 +56,12 @@ "iojs": ">= 3" }, "dependencies": { - "phovea_core": "github:phovea/phovea_core#v0.0.5" + "phovea_core": "0.1.0" }, "name": "phovea_security_flask", "description": "", "homepage": "https://phovea.caleydo.org", - "version": "0.0.5", + "version": "0.1.0", "author": { "name": "The Caleydo Team", "email": "contact@caleydo.org", @@ -73,34 +76,35 @@ "url": "https://github.com/phovea/phovea_security_flask.git" }, "devDependencies": { - "@types/jasmine": "2.5.35", - "awesome-typescript-loader": "2.2.4", - "css-loader": "0.25.0", - "extract-text-webpack-plugin": "2.0.0-beta.4", - "extract-loader": "0.0.2", - "file-loader": "0.9.0", + "@types/jasmine": "2.5.41", + "awesome-typescript-loader": "3.0.3", + "css-loader": "0.26.1", + "extract-text-webpack-plugin": "2.0.0-rc.3", + "extract-loader": "0.1.0", + "file-loader": "0.10.0", "html-loader": "0.4.4", - "imports-loader": "0.6.5", - "jasmine": "2.5.2", + "imports-loader": "0.7.0", + "jasmine": "2.5.3", "json-loader": "0.5.4", - "karma": "1.3.0", + "karma": "1.4.0", "karma-chrome-launcher": "2.0.0", "karma-firefox-launcher": "1.0.0", - "karma-jasmine": "1.0.2", - "karma-junit-reporter": "1.1.0", + "karma-jasmine": "1.1.0", + "karma-junit-reporter": "2.0.0", "karma-sourcemap-loader": "0.3.7", - "karma-webpack": "1.8.0", + "karma-webpack": "2.0.2", "mkdirp": "0.5.1", - "node-sass": "3.10.0", + "node-sass": "4.5.0", "null-loader": "0.1.1", "raw-loader": "0.5.1", - "sass-loader": "4.0.2", + "sass-loader": "5.0.0", "style-loader": "0.13.1", - "tslint": "3.15.1", - "typedoc": "0.5.3", - "typescript": "2.0.6", + "tslib": "1.5.0", + "tslint": "4.4.2", + "typedoc": "0.5.5", + "typescript": "2.2.0", "url-loader": "0.5.7", - "webpack": "2.1.0-beta.26", - "webpack-dev-server": "2.1.0-beta.10" + "webpack": "2.2.1", + "webpack-dev-server": "2.4.2" } } diff --git a/phovea_security_flask/dummy_store.py b/phovea_security_flask/dummy_store.py index 4354467..ab6f0f0 100644 --- a/phovea_security_flask/dummy_store.py +++ b/phovea_security_flask/dummy_store.py @@ -29,12 +29,27 @@ def is_password(self, given): return given_h == self._password +def from_env_var(k, v): + elems = v.split(';') + name = k[12:] # PHOVEA_USER_ + salt = elems[0] + password = elems[1] + roles = elems[2:] + return User(name, password, salt, roles) + + class UserStore(object): def __init__(self): import phovea_server.config - - self._users = [User(v['name'], v['password'], v['salt'], v['roles']) for v in - phovea_server.config.get('phovea_security_flask.users')] + import os + + # define users via env variables + env_users = [from_env_var(k, v) for k, v in os.environ.items() if k.startswith('PHOVEA_USER_')] + if env_users: + self._users = env_users + else: + self._users = [User(v['name'], v['password'], v['salt'], v['roles']) for v in + phovea_server.config.get('phovea_security_flask.users')] def load(self, id): return next((u for u in self._users if u.id == id), None) diff --git a/phovea_security_flask/flask_login_impl.py b/phovea_security_flask/flask_login_impl.py index 591047b..0d3904c 100644 --- a/phovea_security_flask/flask_login_impl.py +++ b/phovea_security_flask/flask_login_impl.py @@ -107,7 +107,7 @@ def loggedinas(): return '"not_yet_logged_in"' def login_required(self, f): - return self._manager.login_required(f) + return flask_login.login_required(f) @property def current_user(self): diff --git a/requirements.txt b/requirements.txt index 5ed3daa..65e6b29 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,2 @@ --e git+https://github.com/phovea/phovea_server.git@v0.0.5#egg=phovea_server -flask-login==0.4.0 \ No newline at end of file +flask-login==0.4.0 +phovea_server==0.1.0 \ No newline at end of file diff --git a/requirements_dev.txt b/requirements_dev.txt index 0e2902f..7ca3f68 100644 --- a/requirements_dev.txt +++ b/requirements_dev.txt @@ -2,3 +2,5 @@ flake8==3.0.4 pep8-naming==0.4.1 pytest==3.0.3 pytest-runner==2.9 +Sphinx==1.5.2 +recommonmark==0.4.0 diff --git a/setup.cfg b/setup.cfg index 5519f85..119a4a3 100644 --- a/setup.cfg +++ b/setup.cfg @@ -12,3 +12,6 @@ universal=1 [aliases] test=pytest + +[metadata] +description-file = README.md diff --git a/setup.py b/setup.py index 2f7a0a1..18e10f0 100644 --- a/setup.py +++ b/setup.py @@ -4,7 +4,7 @@ # Licensed under the new BSD license, available at http://caleydo.org/license ############################################################################### from __future__ import with_statement, print_function -from setuptools import setup +from setuptools import setup, find_packages from codecs import open from os import path @@ -30,9 +30,19 @@ def packaged(*files): return r +def requirements(file): + return [r.strip().encode('ascii') for r in read_it(file).strip().split('\n') if not r.startswith('-e git+https://')] + + +def to_version(v): + import datetime + now = datetime.datetime.utcnow() + return v.replace('SNAPSHOT', now.strftime('%Y%m%d-%H%M%S')) + setup( name=pkg['name'], - version=pkg['version'], + version=to_version(pkg['version']), + url=pkg['homepage'], description=pkg['description'], long_description=read_it('README.md'), keywords=pkg.get('keywords', ''), @@ -51,7 +61,7 @@ def packaged(*files): 'Intended Audience :: Developers', 'Operating System :: OS Independent', # Pick your license as you wish (should match "license" above) - 'License :: OSI Approved :: ' + pkg['license'], + 'License :: OSI Approved :: ' + ('BSD License' if pkg['license'] == 'BSD-3-Clause' else pkg['license']), 'Programming Language :: Python', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3.4' @@ -59,19 +69,19 @@ def packaged(*files): # You can just specify the packages manually here if your project is # simple. Or you can use find_packages(). - py_modules=[pkg['name']], + packages=find_packages(exclude=['docs', 'tests*']), # List run-time dependencies here. These will be installed by pip when # your project is installed. For an analysis of "install_requires" vs pip's # requirements files see: # https://packaging.python.org/en/latest/requirements.html - install_requires=[r for r in read_it('requirements.txt').split('\n') if not r.startswith('-e git+https://')], - tests_require=read_it('requirements_dev.txt').split('\n'), + install_requires=requirements('requirements.txt'), + tests_require=requirements('requirements_dev.txt'), # If there are data files included in your packages that need to be # installed, specify them here. If using Python 2.6 or less, then these # have to be included in MANIFEST.in as well. - package_data=packaged('config.json'), + package_data=packaged('config.json', 'buildInfo.json'), # Although 'package_data' is the preferred approach, in some case you may # need to place data files outside of your packages. See: diff --git a/src/login.ts b/src/login.ts index d702b15..f6a5876 100644 --- a/src/login.ts +++ b/src/login.ts @@ -10,9 +10,9 @@ export const form = String(formTemplate); export function login(username:string, password:string, remember = false) { return send('/login', { - username: username, - password: password, - remember: remember + username, + password, + remember }, 'post').then(function (user) { session.store('user', user.name); session.store('user_obj', user); diff --git a/tsconfig.json b/tsconfig.json index aa39f10..e65e1a7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,17 +2,22 @@ "compilerOptions": { "module": "es6", "target": "es5", - "noImplicitAny": false, + "importHelpers": true, "sourceMap": true, "moduleResolution": "node", + "jsx": "react", + "experimentalDecorators": true, "lib": [ "dom", "es2015" ], - "baseUrl": "../" + "baseUrl": "../", + "noImplicitAny": false, + "skipLibCheck": true }, "include": [ "src/**/*.ts", + "src/**/*.tsx", "tests/**/*.ts", "index.ts", "tsd.d.ts" diff --git a/tslint.json b/tslint.json index 0818c82..434c5eb 100644 --- a/tslint.json +++ b/tslint.json @@ -1,28 +1,45 @@ { "rules": { - "ban": [true, ["_", "extend"], - ["_", "isNull"], - ["_", "isDefined"] + "arrow-parens": true, + "ban": [ + true, + [ + "_", + "extend" + ], + [ + "_", + "isNull" + ], + [ + "_", + "isDefined" + ] ], "class-name": true, "comment-format": false, "curly": true, "eofline": true, "forin": true, - "indent": [true, 2], + "indent": [ + true, + 2 + ], "interface-name": true, "jsdoc-format": true, "label-position": true, - "label-undefined": true, "max-line-length": false, - "member-ordering": [false, + "member-ordering": [ + false, "public-before-private", "static-before-instance", "variables-before-functions" ], + "new-parens": true, "no-arg": true, "no-bitwise": true, - "no-console": [true, + "no-console": [ + true, "debug", "info", "time", @@ -30,47 +47,77 @@ "trace" ], "no-construct": true, - "no-constructor-vars": false, "no-debugger": true, - "no-duplicate-key": true, "no-duplicate-variable": true, "no-empty": true, + "no-empty-interface": true, "no-eval": true, + "no-reference": true, "no-string-literal": true, + "no-string-throw": true, "no-switch-case-fall-through": true, "no-trailing-whitespace": true, "no-unused-expression": true, - "no-unused-variable": true, - "no-unreachable": true, "no-use-before-declare": true, + "no-unsafe-finally": true, "no-var-requires": true, - "one-line": [true, + "no-var-keyword": true, + "one-line": [ + true, "check-open-brace", "check-catch", "check-else", "check-whitespace" ], - "quotemark": [true, "single"], + "object-literal-shorthand": true, + "prefer-for-of": true, + "prefer-const": true, + "quotemark": [ + true, + "single", + "jsx-double" + ], "radix": true, - "semicolon": true, - "triple-equals": [true, "allow-null-check"], - "typedef": [false, + "semicolon": [ + true, + "always" + ], + "triple-equals": [ + true, + "allow-null-check" + ], + "typedef": [ + false, "callSignature", "indexSignature", "parameter", "propertySignature", "variableDeclarator" ], - "typedef-whitespace": [true, ["callSignature", "noSpace"], - ["catchClause", "noSpace"], - ["indexSignature", "space"] + "typedef-whitespace": [ + true, + [ + "callSignature", + "noSpace" + ], + [ + "catchClause", + "noSpace" + ], + [ + "indexSignature", + "space" + ] ], - "use-strict": [false, - "check-module", - "check-function" + "use-isnan": true, + "variable-name": [ + true, + "ban-keywords", + "check-format", + "allow-leading-underscore" ], - "variable-name": false, - "whitespace": [false, + "whitespace": [ + false, "check-branch", "check-decl", "check-operator", diff --git a/typedoc.json b/typedoc.json index b2127db..b2e2c18 100644 --- a/typedoc.json +++ b/typedoc.json @@ -1,13 +1,15 @@ { "mode": "modules", - "out": "./docs", + "out": "./build/docs", "theme": "minimal", - "ignoreCompilerErrors": false, + "ignoreCompilerErrors": true, "experimentalDecorators": true, "emitDecoratorMetadata": true, "preserveConstEnums": true, "stripInternal": true, "suppressExcessPropertyErrors": true, "suppressImplicitAnyIndexErrors": true, - "exclude": "**/*.test.ts" + "exclude": "tests/**/*.ts", + "excludePrivate": true, + "excludeExternals": true } diff --git a/webpack.config.js b/webpack.config.js index 67e90f8..6b51f6f 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -88,9 +88,11 @@ function testPhoveaModules(modules) { }; } + // use workspace registry file if available const isWorkspaceContext = fs.existsSync(resolve(__dirname, '..', 'phovea_registry.js')); const registryFile = isWorkspaceContext ? '../phovea_registry.js' : './phovea_registry.js'; +const actMetaData = `file-loader?name=phoveaMetaData.json!${buildInfo.metaDataTmpFile(pkg)}`; const actBuildInfoFile = `file-loader?name=buildInfo.json!${buildInfo.tmpFile()}`; /** @@ -99,13 +101,14 @@ const actBuildInfoFile = `file-loader?name=buildInfo.json!${buildInfo.tmpFile()} * @returns {*} */ function injectRegistry(entry) { + const extraFiles = [registryFile, actBuildInfoFile, actMetaData]; //build also the registry if (typeof entry === 'string') { - return [registryFile, actBuildInfoFile].concat(entry); + return extraFiles.concat(entry); } else { const transformed = {}; Object.keys(entry).forEach((eentry) => { - transformed[eentry] = [registryFile, actBuildInfoFile].concat(entry[eentry]); + transformed[eentry] = extraFiles.concat(entry[eentry]); }); return transformed; } @@ -139,12 +142,16 @@ function generateWebpack(options) { }), //define magic constants that are replaced new webpack.DefinePlugin({ + 'process.env': { + 'NODE_ENV': JSON.stringify(options.isProduction ? 'production': 'development') + }, __VERSION__: JSON.stringify(pkg.version), __LICENSE__: JSON.stringify(pkg.license), __BUILD_ID__: buildId, __DEBUG__: options.isDev || options.isTest, __TEST__: options.isTest, - __PRODUCTION__: options.isProduction + __PRODUCTION__: options.isProduction, + __APP_CONTEXT__: JSON.stringify('/') }), new webpack.optimize.MinChunkSizePlugin({ minChunkSize: 10000 //at least 10.000 characters @@ -157,10 +164,14 @@ function generateWebpack(options) { loaders: webpackloaders.slice() }, devServer: { + watchOptions: { + ignored: '/node_modules/' + }, proxy: { '/api/*': { target: 'http://localhost:9000', - secure: false + secure: false, + ws: true }, '/login': { target: 'http://localhost:9000', @@ -296,7 +307,7 @@ function generateWebpackConfig(env) { //single generation if (isDev) { return generateWebpack(base); - } else if (type === 'app') { //isProduction app + } else if (type.startsWith('app')) { //isProduction app return generateWebpack(Object.assign({}, base, { min: true, nosuffix: true