blob: cb961ed31b64715fa8219158a96c443722709abb [file] [log] [blame]
"""
Copyright (c) 2019, OptoFidelity OY
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by the OptoFidelity OY.
4. Neither the name of the OptoFidelity OY nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
import traceback
import json
import cherrypy
from cherrypy import HTTPError
from genshi.template import MarkupTemplate
from .base_page import BasePage
from .measurementdb import get_database, Setting
import TPPTAnalysisSW.test_session as test_session
import TPPTAnalysisSW.imagefactory as imagefactory
from .settings import settings, setting_categories, loadSettings
from .info.version import Version
import TPPTAnalysisSW.progressstatus as progressstatus
import TPPTAnalysisSW.test_refs as test_refs
#Settings controller for settings-view
class SettingsController(BasePage):
SAVEPATH = ""
def GET(self, *args, **kwargs):
if "event" in kwargs:
cherrypy.response.headers["Content-Type"] = "text/event-stream"
cherrypy.response.headers["Transfer-Encoding"] = "identity"
return "data: " + str(progressstatus.progress) + "\ndata:\nretry:500\n\n"
dbsession = get_database().session()
with open("templates/settings.html") as f:
tmpl = MarkupTemplate(f)
settings = dbsession.query(Setting).all()
groups = self.settings_by_group(settings)
stream = tmpl.generate(groups=groups, version=Version)
return stream.render('xhtml')
def POST(self, *args, **kwargs):
dbsession = get_database().session()
data = json.loads(kwargs['params'])
for i in data:
setting = dbsession.query(Setting).filter(Setting.id == i['id']).first()
try:
strvalue = i['value']
strvalue = strvalue.replace(',', '.') # Allow comma decimal separator
setting.value = float(strvalue)
except ValueError:
print(traceback.format_exc())
dbsession.rollback()
raise HTTPError("500", "Float value required for %s" % setting.desc)
dbsession.commit()
loadSettings(dbsession) # from settings.py
# clear cache
test_refs.testclass_refs.clear()
imagefactory.ImageFactory.delete_all_images()
if kwargs['mode'] == "recalculate":
testsessions = get_database().get_test_sessions()
length = len(testsessions)
for idx, ts in enumerate(testsessions):
test_session.TestSession.eval_tests_results(dbsession, ts.id)
if idx == 0:
progressstatus.progress = 0
else:
progressstatus.progress = round(idx / float(length), 2)
progressstatus.progress = 0
return "Settings saved and analyses recalculated."
testsessions = get_database().get_test_sessions()
for ts in testsessions:
test_session.TestSession.eval_tests_results(dbsession, ts.id, recalculate=False)
return "Settings saved but analyses were not recalculated."
def settings_by_group(self, settings):
# Copy settings to safety
settings = list(settings)
groups, groups_settings = self.parse_groups()
# Replace setting_id with given setting
for group_settings in groups_settings:
for i, setting_id in enumerate(group_settings):
setting = [s for s in settings if s.id == setting_id]
if len(setting) == 0:
raise HTTPError(status="500", message="Internal error: setting %s not found in database" % setting)
else:
settings.remove(setting[0])
group_settings[i] = setting[0]
if len(settings) > 0:
# There are non-categorized settings
groups.append(None)
groups_settings.append(settings)
# Note: this will break if some of the settings given in settings_categories
# is not found in the database. This should be rare condition, as missing
# settings are inserted in the startup sequence
return zip(groups, groups_settings)
def parse_groups(self):
"""
Parses the group to list of categories. Creates separate categories
for settings that are in multiple categories
"""
settings_dict = {}
# Create settings list (reverse: setting_id -> categories)
# Note: generated lists are equal if they are included in the same categories
for name, settings_list in setting_categories.items():
for setting_id in settings_list:
if setting_id in settings_dict:
settings_dict[setting_id].append(name)
else:
settings_dict[setting_id] = [name]
# List of different categories
groups = []
# Settings in each category
groups_settings = []
for setting_id, groups_list in settings_dict.items():
if groups_list in groups:
# Append setting to the specific group
groups_settings[groups.index(groups_list)].append(setting_id)
else:
# Create a new group in list and add the settings to it
# order groups by number of categories in group and alphabetically
for index_to in range(len(groups)):
if len(groups[index_to]) < len(groups_list):
continue
elif (len(groups[index_to]) > len(groups_list) or
groups[index_to][0] > groups_list[0]):
groups.insert(index_to, groups_list)
groups_settings.insert(index_to, [setting_id])
break
else:
# Append
groups.append(groups_list)
groups_settings.append([setting_id])
return (groups, groups_settings)
exposed = True