Commit 931c8059 authored by Timm Fitschen's avatar Timm Fitschen
Browse files

Initial Commit

AGPLv3 Veröffentlichung gemäß Dienstanweisung vom 15. August 2018.
parents
# dot files
.*
!/.git*
# extracted libraries
/libs/**
!/libs/*.zip
# the build dir
/public
# screen logs
screenlog.*
#
# ** header v3.0
# This file is a part of the CaosDB Project.
#
# Copyright (C) 2018 Research Group Biomedical Physics,
# Max-Planck-Institute for Dynamics and Self-Organization Göttingen
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program 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. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# ** end header
#
stages:
- setup
- linting
- test
#######
# setup
#######
# install pylint
setup:install-pylint:
stage: setup
script:
- pip3 install pylint --user
#########
# linting
#########
# pylint everything
linting:pylint:python3:
stage: linting
script:
- make pylint
######
# test
######
# run qunit tests
test:qunit:
stage: test
artifacts:
paths:
- qunit.log
- screenlog.*
script:
- make run-qunit
This diff is collapsed.
# Welcome
This is the **CaosDB WebUI** repository and a part of the CaosDB project.
# Setup
Please read the [README_SETUP.md](README_SETUP.md) for instructions on how to
setup this code.
# Further Reading
Please refer to the [official gitlab repository of the CaosDB
project](https://gitlab.gwdg.de/bmp-caosdb/caosdb) for more information.
# License
Copyright (C) 2018 Research Group Biomedical Physics, Max Planck Institute for
Dynamics and Self-Organization Göttingen.
All files in this repository are licensed under a [GNU Affero General Public
License](LICENCE.md) (version 3 or later).
# Structure
* The `src` folder contains all source code for the webinterface.
* The `libs` folder contains all necessary third-party libraries as zip files.
* The `test` folder contains the unittests for the webinterface.
* The `ext` folder contains extension for the webinterface. The make file will copy all javascript files from `ext/js/` into the public folder and links the javascript in the `public/xsl/main.xsl`.
# Setup
* run `make install` to compile/copy the webinterface to a newly created `public` folder.
* run `make test` to compile/copy the webinterface and the tests to a newly created `public` folder and start a python http server. The test suite can be started with
`firefox http://localhost:8000/webinterface/`
* run `make clean` to clean up everything.
/*
* ** header v3.0
* This file is a part of the CaosDB Project.
*
* Copyright (C) 2018 Research Group Biomedical Physics,
* Max-Planck-Institute for Dynamics and Self-Organization Göttingen
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* ** end header
*/
console.log("load test.js");
#
# ** header v3.0
# This file is a part of the CaosDB Project.
#
# Copyright (C) 2018 Research Group Biomedical Physics,
# Max-Planck-Institute for Dynamics and Self-Organization Göttingen
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program 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. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# ** end header
#
# Unzip all the external libraries and set up the links in the public folder
SQ=\'
ROOT_DIR = $(abspath .)
MISC_DIR = $(abspath misc)
PUBLIC_DIR = $(abspath public)
SRC_DIR = $(abspath src)
EXT_DIR = $(abspath ext)
LIBS_DIR = $(abspath libs)
TEST_DIR = $(abspath test)
LIBS = fonts css/bootstrap.css js/bootstrap.js js/state-machine.js js/jquery.js js/showdown.js
TEST_LIBS = $(LIBS) js/qunit.js css/qunit.css $(subst $(TEST_DIR)/,,$(shell find $(TEST_DIR)/))
LIBS_ZIP = $(wildcard $(LIBS_DIR)/*.zip)
LIBS_SUBDIRS = $(addprefix $(LIBS_DIR)/, js css fonts)
ALL: test install
install: clean cp-src cp-ext $(addprefix $(PUBLIC_DIR)/, $(LIBS))
test: clean cp-src cp-ext $(addprefix $(PUBLIC_DIR)/, $(TEST_LIBS))
ln -s $(PUBLIC_DIR) $(PUBLIC_DIR)/webinterface
PORT = 8000
TIMEOUT = 200
XVFB-RUN = xvfb-run -e /dev/stderr
run-test-server: test
cd $(PUBLIC_DIR); $(MISC_DIR)/unit_test_http_server.py $(PORT) $(TIMEOUT); echo $$? > $(ROOT_DIR)/.server_done
run-qunit:
# start server
screen -L -S caosdb-webui-test -t server -d -m -A make run-test-server
# start firefox
screen -S caosdb-webui-test -X screen -t firefox $(XVFB-RUN) firefox "http://localhost:$(PORT)/webinterface/index.html?loggerPort=$(PORT)"
# wait until server stops
while [ 1 -eq 1 ]; do \
[ ! -e .server_done ] || break; \
done; \
true
# stop firefox
pkill -u caosdb firefox || true
# print stuff
cat screenlog.* || true
cat $(PUBLIC_DIR)/qunit.log || true
cat .server_done || true
[ $$(cat .server_done) -eq 0 ]
cp-ext:
for f in $(wildcard $(EXT_DIR)/js/*) ; do \
cp -i -r $$f $(PUBLIC_DIR)/js/ ; \
sed -i "/EXTENSIONS/a \<xsl:element name=\"script\"><xsl:attribute name=\"src\"><xsl:value-of select=\"concat\(\$$basepath, 'webinterface$${f#$(EXT_DIR)}'\)\" /></xsl:attribute></xsl:element>" $(PUBLIC_DIR)/xsl/main.xsl ; \
done
cp-src:
cp -r $(SRC_DIR) $(PUBLIC_DIR)
$(PUBLIC_DIR)/%: $(LIBS_DIR)/%
ln -s $< $@
$(PUBLIC_DIR)/%: $(TEST_DIR)/%
ln -s $< $@
$(LIBS_DIR)/fonts: unzip
ln -s $(LIBS_DIR)/bootstrap-3.3.7-dist/fonts $@
$(LIBS_DIR)/js/bootstrap.js: unzip $(LIBS_DIR)/js
ln -s $(LIBS_DIR)/bootstrap-3.3.7-dist/js/bootstrap.min.js $@
$(LIBS_DIR)/css/bootstrap.css: unzip $(LIBS_DIR)/css
ln -s $(LIBS_DIR)/bootstrap-3.3.7-dist/css/bootstrap.min.css $@
$(LIBS_DIR)/js/jquery.js: unzip $(LIBS_DIR)/js
ln -s $(LIBS_DIR)/jquery-3.3.1/jquery-3.3.1.min.js $@
$(LIBS_DIR)/js/showdown.js: unzip $(LIBS_DIR)/js
ln -s $(LIBS_DIR)/showdown-1.8.6/dist/showdown.min.js $@
$(LIBS_DIR)/js/state-machine.js: unzip $(LIBS_DIR)/js
ln -s $(LIBS_DIR)/javascript-state-machine-master/dist/state-machine.min.js $@
$(LIBS_DIR)/css/qunit.css: unzip $(LIBS_DIR)/css
ln -s $(LIBS_DIR)/qunit-2.6.2/qunit-2.6.2.css $@
$(LIBS_DIR)/js/qunit.js: unzip $(LIBS_DIR)/js
ln -s $(LIBS_DIR)/qunit-2.6.2/qunit-2.6.2.js $@
$(addprefix $(LIBS_DIR)/, js css):
mkdir $@ || true
.PHONY: clean
clean:
$(RM) -r $(PUBLIC_DIR)
for f in $(LIBS_SUBDIRS); do unlink $$f || $(RM) -r $$f || true; done
for f in $(patsubst %.zip,%/,$(LIBS_ZIP)); do $(RM) -r $$f; done
$(RM) screenlog.*
$(RM) .server_done
.PHONY: unzip
unzip:
for f in $(LIBS_ZIP); do unzip -o -d libs $$f; done
PYLINT = ~/.local/bin/pylint
PYTHON_FILES = $(subst $(ROOT_DIR)/,,$(shell find $(ROOT_DIR)/ -iname "*.py"))
pylint: $(PYTHON_FILES)
for f in $(PYTHON_FILES); do $(PYLINT) $$f || exit 1; done
#!/usr/bin/env python3
# -*- encoding: utf-8 -*-
#
# ** header v3.0
# This file is a part of the CaosDB Project.
#
# Copyright (C) 2018 Research Group Biomedical Physics,
# Max-Planck-Institute for Dynamics and Self-Organization Göttingen
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program 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. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# ** end header
#
"""unit_test_http_server
For running and logging the unit test suite of webcaosdb.
"""
import sys
import os
from http.server import SimpleHTTPRequestHandler, HTTPServer
class UnitTestsHandler(SimpleHTTPRequestHandler):
"""UnitTestsHandler
Handles GET requests and return the source files of webcaosdb or the test
suite and POST requests for the logger.
"""
# do_POST is compliant with the BaseHTTPRequestHandler API
# pylint: disable=invalid-name
def do_POST(self):
"""do_POST
Handle POST requests to the `log` and `done` resources.
"""
path = self.path[1:]
if path in ["done", "log"]:
getattr(self, path)()
#return HTTP status: 204 No Content
self.send_response(204)
else:
#return HTTP status: 404 Not Found
self.send_response(404)
def done(self):
"""done
Shut down the server with an exit code which depends on the success of
the unit test suite - If the tests succeeded the server exists with 0,
otherwise with 1.
"""
#pylint: disable=protected-access
post_data = self.log()
if "SUCCESS" in post_data:
self.server._shutdown("[SUCCESS]", 0)
else:
self.server._shutdown("[ERROR]", 1)
def log(self):
"""log
Print the body of a request.
"""
content_length = int(self.headers['Content-Length'])
post_data = self.rfile.read(content_length).decode("utf-8")
with open("qunit.log", "a") as logfile:
logfile.write("[LOG] " + post_data + "\n")
return post_data
class UnitTestHTTPServer(HTTPServer):
"""UnitTestHTTPServer
A HTTP server which handles the request to the webcaosdb sources and the
tests and servers as a logger when POST request are send to the `log`
resource.
"""
def __init__(self, server_address, timeout):
super(UnitTestHTTPServer, self).__init__(server_address,
UnitTestsHandler)
self.timeout = timeout
self._keep_running = True
self._exit_message = None
self._exit_code = None
def handle_timeout(self):
"""handle_timeout as defined in socketserver.BaseServer
"""
self._shutdown("[TIMEOUT]", 2)
def _shutdown(self, message, code):
self._keep_running = False
self._exit_message = message
self._exit_code = code
def start(self):
"""start
Start the server and handle request until the `done` resource is being
called or a timeout occurs.
"""
print(("starting UnitTestHTTPServer on {address} with {t}s "
"timeout.").format(address=self.server_address, t=self.timeout))
self._keep_running = True
while self._keep_running:
self.handle_request()
print(self._exit_message)
os._exit(self._exit_code)#pylint: disable=protected-access
UnitTestHTTPServer(server_address=('127.0.0.1', int(sys.argv[1])),
timeout=float(sys.argv[2])).start()
/*
* ** header v3.0
* This file is a part of the CaosDB Project.
*
* Copyright (C) 2018 Research Group Biomedical Physics,
* Max-Planck-Institute for Dynamics and Self-Organization Göttingen
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* ** end header
*/
@CHARSET "UTF-8";
.caosdb-comment-annotation-text h1 {
font-size: 24px;
}
.caosdb-comment-annotation-text h2 {
font-size: 20px;
}
.caosdb-comment-annotation-text h3 {
font-size: 18px;
}
.caosdb-comment-annotation-text h4 {
font-size: 16px;
}
.caosdb-show-preview-button, .caosdb-hide-preview-button {
position: absolute;
top: 5px;
left: -5px;
}
.caosdb-entity-heading-attr {
overflow-x: auto;
}
a.label.caosdb-id:hover {
background-color: #5E6762;
}
.caosdb-entity-preview .caosdb-entity-panel-body {
overflow-y: auto;
max-height: 250px;
}
.caosdb-preview-carousel-nav > .caosdb-value-list > .btn-group > .btn:first-child {
margin-left: 34px;
}
.caosdb-preview-carousel-nav > .caosdb-value-list > .btn-group > .btn:last-child {
margin-right: 34px;
}
.caosdb-preview-carousel-nav {
position: relative;
}
.caosdb-query-panel {
padding-top: 20px;
padding-bottom: 20px;
}
.navbar-default .btn-link:hover {
text-decoration: none;
}
.navbar-default .btn-link:focus {
text-decoration: none;
}
.caosdb-property-name {
font-weight: bold;
margin-left: 8px;
}
.caosdb-square {
position: relative;
overflow: hidden;
}
.caosdb-square::before {
content: "";
display: block;
padding-top: 100%;
}
.caosdb-square-content {
position: absolute;
top: 0px;
right: 0px;
bottom: 0px;
left: 0px;
}
.caosdb-parent-name {
font-weight: bold;
margin-right: 4px;
}
/* lists of values */
/* INLINE (with default scroll-bar) */
.caosdb-value-list {
overflow-x: auto;
}
.caosdb-value-list > .btn-group > .btn {
float: none;
}
.caosdb-value-list > .btn-group,
.caosdb-value-list > ol {
display: inline-block;
float: none;
white-space: nowrap;
margin-bottom: 0px;
margin-left: 0px;
}
.caosdb-value-list > .list-inline > li {
border-left-width: 0px;
}
.caosdb-value-list > .list-inline > li:first-child {
border-radius: 4px 0px 0px 4px;
border-left-width: 1px;
}
.caosdb-value-list > .list-inline > li:last-child {
border-radius: 0px 4px 4px 0px;
}
/* single boolean values */
.caosdb-boolean-true {
font-weight: bold;
font-size: 90%;
border: 1px solid #bbb;
padding: 2px 8px;
border-radius: 8px;
}
.caosdb-boolean-false {
font-weight: bold;
font-size: 90%;
border: 1px solid #bbb;
padding: 2px 8px;
border-radius: 8px;
}
.caosdb-entity-panel-heading {
border-bottom-left-radius: 3px;
border-bottom-right-radius: 3px;
}
.caosdb-entity-panel-body {
padding: 0px 15px;
}
.caosdb-entity-panel-body > :first-child {
margin-top: 15px;
}
.caosdb-entity-heading-attr-name {
color: #6c6c6c;
font-size: 90%;
margin-right: 0.3em;
}
.caosdb-subproperty-divider {
margin: 4px 0px;
border-top: 1px solid #dddddd
}
.caosdb-prop-label {
background-color: #f5f5f5;
font-weight: bold;
padding: 8px 15px;
}
.caosdb-prop-value {
background-color: #ffffff;
padding: 8px 15px;
}
.caosdb-prop-list-group .row {
margin-left: 0px;
margin-right: 0px;
}
.caosdb-prop-list-group>.list-group-item {
padding: 0px
}
.caosdb-prop-list-group>.list-group-item:first-child .caosdb-prop-label
{
border-top-left-radius: 4px;
border-top-right-radius: 4px;
}
.caosdb-prop-list-group>.list-group-item:first-child .caosdb-prop-value
{
border-top-right-radius: 4px;
}
.caosdb-prop-list-group>.list-group-item:last-child .caosdb-prop-label {
border-bottom-left-radius: 4px;
}
.caosdb-prop-list-group>.list-group-item:last-child .caosdb-prop-value {
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
}
.caosdb-label-record {
background-color: #F92108;
margin-right: 8px;
}