rcdb 2.2.8__tar.gz → 2.2.10__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {rcdb-2.2.8/rcdb.egg-info → rcdb-2.2.10}/PKG-INFO +1 -1
- rcdb-2.2.10/rcdb/cli/add.py +141 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/cli/app.py +10 -2
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/cli/db.py +56 -1
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/cli/info.py +15 -8
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/provider.py +137 -133
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/version.py +1 -1
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/__init__.py +1 -1
- {rcdb-2.2.8 → rcdb-2.2.10/rcdb.egg-info}/PKG-INFO +1 -1
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb.egg-info/SOURCES.txt +4 -0
- rcdb-2.2.10/tests/test_cli_add_condition.py +139 -0
- rcdb-2.2.10/tests/test_cli_add_file.py +105 -0
- rcdb-2.2.10/tests/test_cli_add_type.py +87 -0
- rcdb-2.2.10/tests/test_save_files.py +105 -0
- rcdb-2.2.8/tests/test_save_files.py +0 -54
- {rcdb-2.2.8 → rcdb-2.2.10}/MANIFEST.in +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/README.md +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/pyproject.toml +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/__init__.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/__main__.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/alias.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/app_context.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/cli/__init__.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/cli/__main__.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/cli/context.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/cli/ls.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/cli/repair/__init__.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/cli/repair/evio_files.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/cli/rp.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/cli/run.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/cli/select.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/cli/web.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/coda_parser.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/condition_query_builder.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/config_parser.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/constants.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/errors.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/file_archiver.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/halld_daq_config_parser.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/lexer.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/log_format.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/model.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/stopwatch.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/update.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/modules/__init__.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/modules/conditions.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/modules/files.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/modules/logs.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/modules/runs.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/modules/select_values.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/modules/statistics.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/pagination.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/run_table.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/css/dataTables.bootstrap.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/css/dataTables.bootstrap.min.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/css/dataTables.foundation.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/css/dataTables.foundation.min.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/css/dataTables.jqueryui.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/css/dataTables.jqueryui.min.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/css/jquery.dataTables.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/css/jquery.dataTables.min.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/css/jquery.dataTables_themeroller.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/images/sort_asc.png +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/images/sort_asc_disabled.png +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/images/sort_both.png +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/images/sort_desc.png +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/images/sort_desc_disabled.png +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/js/dataTables.bootstrap.js +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/js/dataTables.bootstrap.min.js +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/js/dataTables.foundation.js +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/js/dataTables.foundation.min.js +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/js/dataTables.jqueryui.js +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/js/dataTables.jqueryui.min.js +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/js/jquery.dataTables.js +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/js/jquery.dataTables.min.js +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/Responsive-2.0.0/css/responsive.bootstrap.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/Responsive-2.0.0/css/responsive.bootstrap.min.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/Responsive-2.0.0/css/responsive.dataTables.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/Responsive-2.0.0/css/responsive.dataTables.min.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/Responsive-2.0.0/css/responsive.foundation.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/Responsive-2.0.0/css/responsive.foundation.min.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/Responsive-2.0.0/css/responsive.jqueryui.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/Responsive-2.0.0/css/responsive.jqueryui.min.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/Responsive-2.0.0/js/dataTables.responsive.js +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/Responsive-2.0.0/js/dataTables.responsive.min.js +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/Responsive-2.0.0/js/responsive.bootstrap.js +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/Responsive-2.0.0/js/responsive.bootstrap.min.js +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/Responsive-2.0.0/js/responsive.foundation.js +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/Responsive-2.0.0/js/responsive.foundation.min.js +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/Responsive-2.0.0/js/responsive.jqueryui.js +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/Responsive-2.0.0/js/responsive.jqueryui.min.js +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/RowReorder-1.1.0/css/rowReorder.bootstrap.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/RowReorder-1.1.0/css/rowReorder.bootstrap.min.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/RowReorder-1.1.0/css/rowReorder.dataTables.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/RowReorder-1.1.0/css/rowReorder.dataTables.min.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/RowReorder-1.1.0/css/rowReorder.foundation.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/RowReorder-1.1.0/css/rowReorder.foundation.min.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/RowReorder-1.1.0/css/rowReorder.jqueryui.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/RowReorder-1.1.0/css/rowReorder.jqueryui.min.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/RowReorder-1.1.0/js/dataTables.rowReorder.js +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/RowReorder-1.1.0/js/dataTables.rowReorder.min.js +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/datatables.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/datatables.js +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/datatables.min.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/datatables.min.js +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/css/bootstrap-theme.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/css/bootstrap-theme.css.map +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/css/bootstrap-theme.min.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/css/bootstrap-theme.min.css.map +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/css/bootstrap.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/css/bootstrap.css.map +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/css/bootstrap.min.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/css/bootstrap.min.css.map +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/css/buttons.dataTables.min.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/css/dataTables.tableTools.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/css/jquery-ui.min.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/css/jquery-ui.structure.min.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/css/jquery-ui.theme.min.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/css/jquery.dataTables.min.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/css/jquery.dataTables.yadcf.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/css/jquery.jsonview.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/css/main.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/css/select.dataTables.min.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/css/webintellisense.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/favicon.png +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/fonts/glyphicons-halflings-regular.eot +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/fonts/glyphicons-halflings-regular.svg +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/fonts/glyphicons-halflings-regular.ttf +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/fonts/glyphicons-halflings-regular.woff +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/fonts/glyphicons-halflings-regular.woff2 +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/humans.txt +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/img/glyphicons-halflings-white.png +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/img/glyphicons-halflings.png +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/img/logo.png +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/js/bootstrap.js +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/js/bootstrap.min.js +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/js/clipboard.min.js +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/js/copy_clipboard.js +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/js/dataTables.buttons.min.js +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/js/dataTables.select.min.js +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/js/jquery-2.1.0.min.js +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/js/jquery-2.1.4.min.js +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/js/jquery-ui.min.js +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/js/jquery.dataTables.min.js +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/js/jquery.dataTables.yadcf.js +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/js/jquery.flot.min.js +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/js/jquery.jsonview.js +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/js/npm.js +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/js/webintellisense-ace.js +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/js/webintellisense-codemirror.js +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/js/webintellisense-textbox.js +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/js/webintellisense.js +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/robots.txt +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/style.css +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/404.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/admin/index.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/admin/layout.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/admin/user.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/admin/users.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/conditions/index.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/custom_column_run_table.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/default_run_table.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/errors/forbidden_page.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/errors/layout.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/errors/page_not_found.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/errors/server_error.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/files/index.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/files/info.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/files/not_found.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/frontend/create_profile.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/frontend/footers/help.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/frontend/login.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/frontend/login_openid.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/frontend/reauth.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/frontend/reset_password.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/frontend/search.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/frontend/signup.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/index.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/layout.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/layouts/base.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/layouts/base2.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/login.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/logs/index.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/macros/_ask_user_to_update_ie.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/macros/_form.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/macros/_google_analytics.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/macros/_misc.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/macros/_reset_password.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/render_pagination.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/run_search_box.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/runs/conditions.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/runs/example.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/runs/index.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/runs/info.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/runs/not_found.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/select_values/index.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/settings/layout.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/settings/password.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/settings/profile.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/show_entries.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/statistics/index.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/user/index.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/user/profile.html +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb.egg-info/dependency_links.txt +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb.egg-info/entry_points.txt +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb.egg-info/requires.txt +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/rcdb.egg-info/top_level.txt +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/setup.cfg +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/tests/test_coda_parser.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/tests/test_conditions.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/tests/test_config_parser.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/tests/test_get_run_periods.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/tests/test_get_runs.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/tests/test_halld_run_config_parser.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/tests/test_select_runs.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/tests/test_select_values.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/tests/test_sql_schema_version.py +0 -0
- {rcdb-2.2.8 → rcdb-2.2.10}/tests/test_value_comparison.py +0 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import click
|
|
2
|
+
from rcdb.provider import RCDBProvider
|
|
3
|
+
from rcdb.model import ConditionType, ConfigurationFile
|
|
4
|
+
from rcdb.cli.context import pass_rcdb_context
|
|
5
|
+
from rcdb import ConditionType as CT
|
|
6
|
+
|
|
7
|
+
# A helper mapping from short strings like 'bool','int','float' -> ConditionType.<XYZ>_FIELD
|
|
8
|
+
TYPE_MAP = {
|
|
9
|
+
"bool": CT.BOOL_FIELD,
|
|
10
|
+
"int": CT.INT_FIELD,
|
|
11
|
+
"float": CT.FLOAT_FIELD,
|
|
12
|
+
"string": CT.STRING_FIELD,
|
|
13
|
+
"json": CT.JSON_FIELD,
|
|
14
|
+
"time": CT.TIME_FIELD,
|
|
15
|
+
"blob": CT.BLOB_FIELD
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@click.group("add", help="Add data to the RCDB (types, conditions, files).")
|
|
20
|
+
@pass_rcdb_context
|
|
21
|
+
def add_command(context):
|
|
22
|
+
"""
|
|
23
|
+
The 'add' group command. See subcommands like:
|
|
24
|
+
rcdb add type - adds Condition Type
|
|
25
|
+
rcdb add condition - adds Condition to a run
|
|
26
|
+
rcdb add file - adds File and associate it to a run
|
|
27
|
+
"""
|
|
28
|
+
pass
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@add_command.command(name="type", help="Add a new condition type to the DB.")
|
|
32
|
+
@click.argument("name", required=True)
|
|
33
|
+
@click.option("--type", "value_type",
|
|
34
|
+
type=click.Choice(TYPE_MAP.keys(), case_sensitive=False),
|
|
35
|
+
default="float", show_default=True,
|
|
36
|
+
help="Data type of the condition (bool, int, float, string, json, time, blob).")
|
|
37
|
+
@click.option("--description", "-d",
|
|
38
|
+
default="",
|
|
39
|
+
help="Optional description.")
|
|
40
|
+
@pass_rcdb_context
|
|
41
|
+
def add_type(context, name, value_type, description):
|
|
42
|
+
"""
|
|
43
|
+
Adds a new condition type with given NAME and --type/--description.
|
|
44
|
+
|
|
45
|
+
Example:
|
|
46
|
+
rcdb add type beam_current --type=float --description "Beam current in nA"
|
|
47
|
+
"""
|
|
48
|
+
db = context.db
|
|
49
|
+
actual_type = TYPE_MAP[value_type.lower()]
|
|
50
|
+
|
|
51
|
+
# Create or verify
|
|
52
|
+
click.echo(f"Creating condition type '{name}' of type '{value_type}'")
|
|
53
|
+
ct = db.create_condition_type(name, actual_type, description)
|
|
54
|
+
click.echo("Done.")
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@add_command.command(name="condition", help="Add or update a condition for a run.")
|
|
58
|
+
@click.argument("run_number", type=int)
|
|
59
|
+
@click.argument("condition_name", type=str)
|
|
60
|
+
@click.argument("value", required=True)
|
|
61
|
+
@click.option("--replace", "-r", is_flag=True,
|
|
62
|
+
help="If present, replace existing value if it already exists.")
|
|
63
|
+
@pass_rcdb_context
|
|
64
|
+
def add_condition(context, run_number, condition_name, value, replace):
|
|
65
|
+
"""
|
|
66
|
+
Adds a condition to RUN_NUMBER called CONDITION_NAME with given VALUE.
|
|
67
|
+
|
|
68
|
+
Example:
|
|
69
|
+
rcdb add condition 1000 my_value 123.4
|
|
70
|
+
rcdb add condition 1000 event_count 10000 --replace
|
|
71
|
+
"""
|
|
72
|
+
db = context.db
|
|
73
|
+
|
|
74
|
+
# 1) Ensure run exists
|
|
75
|
+
run = db.get_run(run_number)
|
|
76
|
+
if not run:
|
|
77
|
+
run = db.create_run(run_number)
|
|
78
|
+
click.echo(f"Created new run #{run_number}")
|
|
79
|
+
|
|
80
|
+
# 2) Look up condition type
|
|
81
|
+
try:
|
|
82
|
+
condition_type = db.get_condition_type(condition_name)
|
|
83
|
+
except:
|
|
84
|
+
click.echo(f"ERROR: No condition type '{condition_name}' found in DB. Create it first with:\n"
|
|
85
|
+
f" rcdb add type {condition_name} --type=<type>\n", err=True)
|
|
86
|
+
raise click.Abort()
|
|
87
|
+
|
|
88
|
+
# 3) Convert value if needed
|
|
89
|
+
# (If 'value' is obviously numeric, you can do more advanced type conversion here if you like)
|
|
90
|
+
# For now we store the raw string and rely on ConditionType conversion in RCDB:
|
|
91
|
+
# db.add_condition will do the right thing (if you pass an int for an INT_FIELD, float for FLOAT_FIELD, etc.)
|
|
92
|
+
# You might do a quick parse though, e.g. if condition_type.value_type is CT.FLOAT_FIELD => float(value), etc.
|
|
93
|
+
|
|
94
|
+
# 4) Add condition
|
|
95
|
+
db.add_condition(run, condition_type, value, replace=replace)
|
|
96
|
+
db.session.commit()
|
|
97
|
+
click.echo(f"Added condition '{condition_name}' = '{value}' to run {run_number}")
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
@add_command.command(name="file", help="Attach or add a file to a run in the DB.")
|
|
101
|
+
@click.argument("run_number", type=int)
|
|
102
|
+
@click.argument("file_path", type=str)
|
|
103
|
+
@click.option("--importance", "-i", default=0, type=int,
|
|
104
|
+
help="Importance level, default=0 (lowest).")
|
|
105
|
+
@click.option("--overwrite", is_flag=True, default=False,
|
|
106
|
+
help="Overwrite existing content for the same path & run.")
|
|
107
|
+
@click.option("--content", default=None,
|
|
108
|
+
help="Optional raw content to store. If not specified, reads from file_path on disk.")
|
|
109
|
+
@pass_rcdb_context
|
|
110
|
+
def add_file(context, run_number, file_path, importance, overwrite, content):
|
|
111
|
+
"""
|
|
112
|
+
Adds or attaches a configuration file to RUN_NUMBER using FILE_PATH.
|
|
113
|
+
|
|
114
|
+
Example:
|
|
115
|
+
rcdb add file 1000 /path/to/coda_run.log
|
|
116
|
+
rcdb add file 1000 /path/to/config.txt --importance=2 --overwrite
|
|
117
|
+
"""
|
|
118
|
+
db = context.db
|
|
119
|
+
run = db.get_run(run_number)
|
|
120
|
+
if not run:
|
|
121
|
+
run = db.create_run(run_number)
|
|
122
|
+
click.echo(f"Created new run #{run_number}")
|
|
123
|
+
|
|
124
|
+
if content:
|
|
125
|
+
# If user provides --content, we do not read from the file path.
|
|
126
|
+
# We'll just store the provided content under that path.
|
|
127
|
+
the_content = content
|
|
128
|
+
click.echo("Using the provided --content instead of reading from disk.")
|
|
129
|
+
else:
|
|
130
|
+
# Otherwise read from disk
|
|
131
|
+
try:
|
|
132
|
+
with open(file_path, "r") as f:
|
|
133
|
+
the_content = f.read()
|
|
134
|
+
except Exception as ex:
|
|
135
|
+
click.echo(f"ERROR: Cannot open/read file '{file_path}': {ex}", err=True)
|
|
136
|
+
raise click.Abort()
|
|
137
|
+
|
|
138
|
+
# Now add
|
|
139
|
+
db.add_configuration_file(run, file_path, content=the_content, overwrite=overwrite, importance=importance)
|
|
140
|
+
db.session.commit()
|
|
141
|
+
click.echo(f"File '{file_path}' attached to run {run_number}.")
|
|
@@ -15,6 +15,7 @@ from .db import db_command
|
|
|
15
15
|
from .rp import rp_command
|
|
16
16
|
from .web import web_command
|
|
17
17
|
from .info import info_command
|
|
18
|
+
from .add import add_command
|
|
18
19
|
|
|
19
20
|
|
|
20
21
|
pass_rcdb_context = click.make_pass_decorator(RcdbApplicationContext)
|
|
@@ -51,9 +52,15 @@ def rcdb_cli(ctx, user_config, connection, config, verbose):
|
|
|
51
52
|
for key, value in config:
|
|
52
53
|
ctx.obj.set_config(key, value)
|
|
53
54
|
|
|
55
|
+
# Bo commands given
|
|
54
56
|
if ctx.invoked_subcommand is None:
|
|
55
|
-
|
|
56
|
-
|
|
57
|
+
# There is a connection but no subcommand
|
|
58
|
+
if connection:
|
|
59
|
+
# If user typed just `rcdb -c <db>`, call info() automatically:
|
|
60
|
+
ctx.invoke(info_command) # => invoke the "info" command
|
|
61
|
+
else:
|
|
62
|
+
# No subcommand, no connection => show help
|
|
63
|
+
click.echo(ctx.get_help())
|
|
57
64
|
|
|
58
65
|
|
|
59
66
|
# Add commands to application
|
|
@@ -63,4 +70,5 @@ rcdb_cli.add_command(db_command)
|
|
|
63
70
|
rcdb_cli.add_command(rp_command)
|
|
64
71
|
rcdb_cli.add_command(web_command)
|
|
65
72
|
rcdb_cli.add_command(info_command)
|
|
73
|
+
rcdb_cli.add_command(add_command)
|
|
66
74
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import click
|
|
2
2
|
import sqlalchemy
|
|
3
|
-
from sqlalchemy import create_engine, MetaData, Table, desc, select
|
|
3
|
+
from sqlalchemy import create_engine, MetaData, Table, desc, select, text
|
|
4
4
|
from sqlalchemy.exc import OperationalError
|
|
5
5
|
|
|
6
6
|
import rcdb
|
|
@@ -28,6 +28,61 @@ def db_command(ctx):
|
|
|
28
28
|
schema_version, = provider.session.execute(query).first()
|
|
29
29
|
print("Schema version: {} - '{}'".format(schema_version.version, schema_version.comment))
|
|
30
30
|
|
|
31
|
+
if connection_str.startswith("mysql"):
|
|
32
|
+
_print_mysql_table_sizes(engine=provider.engine)
|
|
33
|
+
elif connection_str.startswith("sqlite"):
|
|
34
|
+
_print_sqlite_table_sizes(engine=provider.engine)
|
|
35
|
+
else:
|
|
36
|
+
click.echo("Table size info: not supported for this database dialect")
|
|
37
|
+
|
|
38
|
+
def _print_mysql_table_sizes(engine):
|
|
39
|
+
"""Query MySQL information_schema to print approximate table sizes in MB."""
|
|
40
|
+
# Find which database/schema we are connected to
|
|
41
|
+
db_name = engine.url.database
|
|
42
|
+
|
|
43
|
+
sql = text(f"""
|
|
44
|
+
SELECT
|
|
45
|
+
table_name AS tbl,
|
|
46
|
+
ROUND(((data_length + index_length) / 1024 / 1024), 2) AS size_mb
|
|
47
|
+
FROM information_schema.tables
|
|
48
|
+
WHERE table_schema = :db
|
|
49
|
+
ORDER BY size_mb DESC
|
|
50
|
+
""")
|
|
51
|
+
|
|
52
|
+
with engine.connect() as conn:
|
|
53
|
+
results = conn.execute(sql, {"db": db_name}).fetchall()
|
|
54
|
+
|
|
55
|
+
click.echo("\nTable sizes in MB (MySQL):")
|
|
56
|
+
for row in results:
|
|
57
|
+
table, size_mb = row
|
|
58
|
+
click.echo(f" {table:30} {size_mb} MB")
|
|
59
|
+
|
|
60
|
+
def _print_sqlite_table_sizes(engine):
|
|
61
|
+
"""Use 'dbstat' virtual table (if available) to estimate table sizes."""
|
|
62
|
+
try:
|
|
63
|
+
with engine.connect() as conn:
|
|
64
|
+
# Enable the dbstat extension if needed
|
|
65
|
+
# conn.execute("SELECT load_extension('dbstat')")
|
|
66
|
+
# (Only if your SQLite requires explicit load_extension calls)
|
|
67
|
+
|
|
68
|
+
# dbstat vtable can be queried like this:
|
|
69
|
+
rows = conn.execute(text("""
|
|
70
|
+
SELECT
|
|
71
|
+
name AS table_name,
|
|
72
|
+
SUM(pgsize) as total_bytes
|
|
73
|
+
FROM dbstat
|
|
74
|
+
GROUP BY name
|
|
75
|
+
ORDER BY total_bytes DESC
|
|
76
|
+
""")).fetchall()
|
|
77
|
+
|
|
78
|
+
click.echo("\nApproximate per-table sizes (SQLite dbstat):")
|
|
79
|
+
for table_name, total_bytes in rows:
|
|
80
|
+
size_mb = round(total_bytes / 1024 / 1024, 2)
|
|
81
|
+
click.echo(f" {table_name:30} {size_mb} MB")
|
|
82
|
+
|
|
83
|
+
except Exception as ex:
|
|
84
|
+
click.echo("\n No table size info: sqlite dbstat extension is not installed. Use sqlite3_analyzer to get table sizes")
|
|
85
|
+
|
|
31
86
|
|
|
32
87
|
@db_command.command()
|
|
33
88
|
@pass_rcdb_context
|
|
@@ -2,6 +2,7 @@ import click
|
|
|
2
2
|
import datetime
|
|
3
3
|
from .context import pass_rcdb_context
|
|
4
4
|
from rcdb.model import Condition, Run, ConfigurationFile, RunPeriod
|
|
5
|
+
from .. import ConditionType
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
@click.command("info", help="Prints summary info about RCDB contents")
|
|
@@ -12,6 +13,9 @@ def info_command(context):
|
|
|
12
13
|
"""
|
|
13
14
|
db = context.db
|
|
14
15
|
|
|
16
|
+
# Number of condition types
|
|
17
|
+
cnd_type_count = db.session.query(ConditionType).count()
|
|
18
|
+
|
|
15
19
|
# Number of conditions
|
|
16
20
|
cnd_count = db.session.query(Condition).count()
|
|
17
21
|
|
|
@@ -35,19 +39,22 @@ def info_command(context):
|
|
|
35
39
|
last_rp = db.session.query(RunPeriod).order_by(RunPeriod.id.desc()).first()
|
|
36
40
|
|
|
37
41
|
# Print it all
|
|
38
|
-
click.echo(f"
|
|
42
|
+
click.echo(f"Num, condition types: {cnd_type_count}")
|
|
43
|
+
click.echo(f"Num. condition values: {cnd_count}")
|
|
39
44
|
click.echo(f"Last condition date/time: {cnd_last_time}")
|
|
40
45
|
click.echo(f"Number of runs: {run_count}")
|
|
41
46
|
click.echo(f"Number of files: {file_count}")
|
|
42
|
-
click.echo("Last 5 runs saved: " +
|
|
43
|
-
", ".join(str(r.number) for r in last_5_runs) if last_5_runs else "No runs")
|
|
47
|
+
click.echo("Last 5 runs saved: " + ", ".join(str(r.number) for r in last_5_runs) if last_5_runs else "No runs")
|
|
44
48
|
click.echo(f"Number of run periods: {rp_count}")
|
|
45
49
|
if last_rp:
|
|
46
|
-
click.echo(f"Last
|
|
47
|
-
|
|
48
|
-
click.echo("
|
|
50
|
+
click.echo(f"Last Run Period:")
|
|
51
|
+
click.echo(f" Name: {last_rp.name}")
|
|
52
|
+
click.echo(f" Description: {last_rp.name}")
|
|
53
|
+
click.echo(f" Run Range: {last_rp.run_min} - {last_rp.run_max}")
|
|
54
|
+
click.echo(f" Start Date: {last_rp.start_date}")
|
|
55
|
+
click.echo(f" End Date: {last_rp.end_date}")
|
|
49
56
|
|
|
50
57
|
# Finally, show all possible commands (help):
|
|
51
58
|
ctx = click.get_current_context()
|
|
52
|
-
click.echo("\
|
|
53
|
-
|
|
59
|
+
click.echo("\nrun 'rcdb --help' for the list of available commands")
|
|
60
|
+
|
|
@@ -711,8 +711,142 @@ class RCDBProvider(object):
|
|
|
711
711
|
|
|
712
712
|
return query.first()
|
|
713
713
|
|
|
714
|
+
"""
|
|
715
|
+
RCDB data provider that uses SQLAlchemy for accessing databases
|
|
716
|
+
"""
|
|
717
|
+
|
|
718
|
+
# ------------------------------------------------
|
|
719
|
+
# Adds start time
|
|
720
|
+
# ------------------------------------------------
|
|
721
|
+
def add_run_start_time(self, run, dtm):
|
|
722
|
+
"""
|
|
723
|
+
Sets staring time of run
|
|
724
|
+
"""
|
|
725
|
+
assert (isinstance(dtm, datetime.datetime))
|
|
726
|
+
|
|
727
|
+
if not isinstance(run, Run): # run is given as run number not Run object
|
|
728
|
+
run = self.create_run(int(run))
|
|
729
|
+
|
|
730
|
+
if run.start_time == dtm:
|
|
731
|
+
return
|
|
732
|
+
|
|
733
|
+
log.debug(Lf("Setting start time '{}' to run '{}'", dtm, run.number))
|
|
734
|
+
|
|
735
|
+
run.start_time = dtm
|
|
736
|
+
self.session.commit()
|
|
737
|
+
|
|
738
|
+
# ------------------------------------------------
|
|
739
|
+
# Adds end time
|
|
740
|
+
# ------------------------------------------------
|
|
741
|
+
def add_run_end_time(self, run, dtm):
|
|
742
|
+
"""Adds time of run"""
|
|
743
|
+
assert (isinstance(dtm, datetime.datetime))
|
|
744
|
+
|
|
745
|
+
if not isinstance(run, Run): # run is given as run number not Run object
|
|
746
|
+
run = self.create_run(int(run))
|
|
747
|
+
|
|
748
|
+
if run.end_time == dtm:
|
|
749
|
+
return
|
|
750
|
+
|
|
751
|
+
log.debug(Lf("Setting end time '{}' to run '{}'", dtm, run.number))
|
|
752
|
+
run.end_time = dtm
|
|
753
|
+
self.session.commit()
|
|
754
|
+
|
|
755
|
+
# ------------------------------------------------
|
|
756
|
+
#
|
|
757
|
+
# ------------------------------------------------
|
|
758
|
+
def add_configuration_file(self, run, path, content=None, overwrite=False, importance=0):
|
|
759
|
+
"""Adds configuration file to run configuration. If such file exists
|
|
760
|
+
:param importance: 0 - HIGH importance, 1 - LOWER importance. Is used to show in WEB interface
|
|
761
|
+
:param overwrite: If this flag is true, such file for this run exists but checksumm is different,
|
|
762
|
+
file content will be overwritten
|
|
763
|
+
:param content: Content of a file. If not given, func tryes to open file by path.
|
|
764
|
+
:param path: Path of the file
|
|
765
|
+
:param run: Run number
|
|
766
|
+
"""
|
|
767
|
+
|
|
768
|
+
def get_content():
|
|
769
|
+
if content:
|
|
770
|
+
return content
|
|
771
|
+
with open(path) as io_file:
|
|
772
|
+
return io_file.read()
|
|
773
|
+
|
|
774
|
+
log.debug("Processing configuration file")
|
|
775
|
+
|
|
776
|
+
if content is None:
|
|
777
|
+
log.debug(Lf("|- Content is not provided as func param, reading from FS '{}'", path))
|
|
778
|
+
check_sum = rcdb.file_archiver.get_file_sha256(path)
|
|
779
|
+
else:
|
|
780
|
+
log.debug(Lf("|- Content is NOT none, using it to put to DB", path))
|
|
781
|
+
check_sum = rcdb.file_archiver.get_string_sha256(content)
|
|
782
|
+
|
|
783
|
+
if not isinstance(run, Run): # run is given as run number not Run object
|
|
784
|
+
run = self.create_run(run)
|
|
785
|
+
|
|
786
|
+
if overwrite:
|
|
787
|
+
# If we have to potentially overwrite the file, we have to apply another logic
|
|
788
|
+
# First, we look at file with this name in this run
|
|
789
|
+
query = self.session.query(ConfigurationFile) \
|
|
790
|
+
.filter(ConfigurationFile.runs.contains(run)) \
|
|
791
|
+
.filter(ConfigurationFile.path == path) \
|
|
792
|
+
.order_by(desc(ConfigurationFile.id)) # we want latest
|
|
793
|
+
if query.count():
|
|
794
|
+
# There are file to overwrite!
|
|
795
|
+
conf_file = query.first()
|
|
796
|
+
conf_file.sha256 = check_sum
|
|
797
|
+
conf_file.path = path
|
|
798
|
+
conf_file.content = get_content()
|
|
799
|
+
conf_file.importance = importance
|
|
800
|
+
log.debug(Lf("|- File '{}' is getting overwritten", path))
|
|
801
|
+
|
|
802
|
+
self.session.commit()
|
|
803
|
+
return conf_file
|
|
804
|
+
|
|
805
|
+
# Overwrite = false or is not possible
|
|
806
|
+
# Look, do we have a file with such name and checksumm?
|
|
807
|
+
file_query = self.session.query(ConfigurationFile) \
|
|
808
|
+
.filter(ConfigurationFile.sha256 == check_sum, ConfigurationFile.path == path)
|
|
809
|
+
|
|
810
|
+
if not file_query.count():
|
|
811
|
+
# no such file found!
|
|
812
|
+
log.debug(Lf("|- File '{}' not found in DB", path))
|
|
813
|
+
|
|
814
|
+
# create file.
|
|
815
|
+
conf_file = ConfigurationFile()
|
|
816
|
+
conf_file.sha256 = check_sum
|
|
817
|
+
conf_file.path = path
|
|
818
|
+
conf_file.content = get_content()
|
|
819
|
+
conf_file.importance = importance
|
|
820
|
+
|
|
821
|
+
# put it to DB and associate with run
|
|
822
|
+
self.session.add(conf_file)
|
|
823
|
+
self.session.commit()
|
|
824
|
+
|
|
825
|
+
conf_file.runs.append(run)
|
|
826
|
+
|
|
827
|
+
# save and exit
|
|
828
|
+
self.session.commit()
|
|
829
|
+
self.add_log_record(conf_file, "File added to DB. Path: '{}'. Run: '{}'".format(path, run), run.number)
|
|
830
|
+
return conf_file
|
|
831
|
+
|
|
832
|
+
# such file already exists! Get it from database
|
|
833
|
+
conf_file = file_query.first()
|
|
834
|
+
log.debug(Lf("|- File '{}' found in DB by id: '{}'", path, conf_file.id))
|
|
835
|
+
|
|
836
|
+
# maybe... we even have this file in run conf?
|
|
837
|
+
if conf_file not in run.files:
|
|
838
|
+
conf_file.runs.append(run)
|
|
839
|
+
# run_conf.files.append(conf_file)
|
|
840
|
+
self.session.commit() # save and exit
|
|
841
|
+
self.add_log_record(conf_file, "File associated. Path: '{}'. Run: '{}'".format(path, run), run.number)
|
|
842
|
+
else:
|
|
843
|
+
log.debug(Lf("|- File already associated with run'{}'", run))
|
|
844
|
+
|
|
845
|
+
return conf_file
|
|
846
|
+
|
|
847
|
+
|
|
714
848
|
def select_runs(self, search_str="", run_min=0, run_max=sys.maxsize, sort_desc=False):
|
|
715
|
-
""" Searches RCDB for runs with e
|
|
849
|
+
""" Obsolete. Searches RCDB for runs with e
|
|
716
850
|
|
|
717
851
|
:param sort_desc: if True result runs will by sorted descendant by run_number, ascendant if False
|
|
718
852
|
:param run_min: minimum run to search
|
|
@@ -1283,138 +1417,8 @@ class RunSelectionResult(RcdbSelectionResult):
|
|
|
1283
1417
|
|
|
1284
1418
|
|
|
1285
1419
|
class ConfigurationProvider(RCDBProvider):
|
|
1286
|
-
"""
|
|
1287
|
-
|
|
1288
|
-
"""
|
|
1289
|
-
|
|
1290
|
-
# ------------------------------------------------
|
|
1291
|
-
#
|
|
1292
|
-
# ------------------------------------------------
|
|
1293
|
-
def add_run_start_time(self, run, dtm):
|
|
1294
|
-
"""
|
|
1295
|
-
Sets staring time of run
|
|
1296
|
-
"""
|
|
1297
|
-
assert (isinstance(dtm, datetime.datetime))
|
|
1298
|
-
|
|
1299
|
-
if not isinstance(run, Run): # run is given as run number not Run object
|
|
1300
|
-
run = self.create_run(int(run))
|
|
1301
|
-
|
|
1302
|
-
if run.start_time == dtm:
|
|
1303
|
-
return
|
|
1304
|
-
|
|
1305
|
-
log.debug(Lf("Setting start time '{}' to run '{}'", dtm, run.number))
|
|
1306
|
-
|
|
1307
|
-
run.start_time = dtm
|
|
1308
|
-
self.session.commit()
|
|
1309
|
-
|
|
1310
|
-
# ------------------------------------------------
|
|
1311
|
-
#
|
|
1312
|
-
# ------------------------------------------------
|
|
1313
|
-
def add_run_end_time(self, run, dtm):
|
|
1314
|
-
"""Adds time of run"""
|
|
1315
|
-
assert (isinstance(dtm, datetime.datetime))
|
|
1316
|
-
|
|
1317
|
-
if not isinstance(run, Run): # run is given as run number not Run object
|
|
1318
|
-
run = self.create_run(int(run))
|
|
1319
|
-
|
|
1320
|
-
if run.end_time == dtm:
|
|
1321
|
-
return
|
|
1322
|
-
|
|
1323
|
-
log.debug(Lf("Setting end time '{}' to run '{}'", dtm, run.number))
|
|
1324
|
-
run.end_time = dtm
|
|
1325
|
-
self.session.commit()
|
|
1326
|
-
|
|
1327
|
-
# ------------------------------------------------
|
|
1328
|
-
#
|
|
1329
|
-
# ------------------------------------------------
|
|
1330
|
-
def add_configuration_file(self, run, path, content=None, overwrite=False, importance=0):
|
|
1331
|
-
"""Adds configuration file to run configuration. If such file exists
|
|
1332
|
-
:param importance: 0 - HIGH importance, 1 - LOWER importance. Is used to show in WEB interface
|
|
1333
|
-
:param overwrite: If this flag is true, such file for this run exists but checksumm is different,
|
|
1334
|
-
file content will be overwritten
|
|
1335
|
-
:param content: Content of a file. If not given, func tryes to open file by path.
|
|
1336
|
-
:param path: Path of the file
|
|
1337
|
-
:param run: Run number
|
|
1338
|
-
"""
|
|
1339
|
-
|
|
1340
|
-
def get_content():
|
|
1341
|
-
if content:
|
|
1342
|
-
return content
|
|
1343
|
-
with open(path) as io_file:
|
|
1344
|
-
return io_file.read()
|
|
1345
|
-
|
|
1346
|
-
log.debug("Processing configuration file")
|
|
1347
|
-
|
|
1348
|
-
if content is None:
|
|
1349
|
-
log.debug(Lf("|- Content is not provided as func param, reading from FS '{}'", path))
|
|
1350
|
-
check_sum = rcdb.file_archiver.get_file_sha256(path)
|
|
1351
|
-
else:
|
|
1352
|
-
log.debug(Lf("|- Content is NOT none, using it to put to DB", path))
|
|
1353
|
-
check_sum = rcdb.file_archiver.get_string_sha256(content)
|
|
1354
|
-
|
|
1355
|
-
if not isinstance(run, Run): # run is given as run number not Run object
|
|
1356
|
-
run = self.create_run(run)
|
|
1357
|
-
|
|
1358
|
-
if overwrite:
|
|
1359
|
-
# If we have to potentially overwrite the file, we have to apply another logic
|
|
1360
|
-
# First, we look at file with this name in this run
|
|
1361
|
-
query = self.session.query(ConfigurationFile) \
|
|
1362
|
-
.filter(ConfigurationFile.runs.contains(run)) \
|
|
1363
|
-
.filter(ConfigurationFile.path == path) \
|
|
1364
|
-
.order_by(desc(ConfigurationFile.id)) # we want latest
|
|
1365
|
-
if query.count():
|
|
1366
|
-
# There are file to overwrite!
|
|
1367
|
-
conf_file = query.first()
|
|
1368
|
-
conf_file.sha256 = check_sum
|
|
1369
|
-
conf_file.path = path
|
|
1370
|
-
conf_file.content = get_content()
|
|
1371
|
-
conf_file.importance = importance
|
|
1372
|
-
log.debug(Lf("|- File '{}' is getting overwritten", path))
|
|
1373
|
-
|
|
1374
|
-
self.session.commit()
|
|
1375
|
-
return conf_file
|
|
1376
|
-
|
|
1377
|
-
# Overwrite = false or is not possible
|
|
1378
|
-
# Look, do we have a file with such name and checksumm?
|
|
1379
|
-
file_query = self.session.query(ConfigurationFile) \
|
|
1380
|
-
.filter(ConfigurationFile.sha256 == check_sum, ConfigurationFile.path == path)
|
|
1381
|
-
|
|
1382
|
-
if not file_query.count():
|
|
1383
|
-
# no such file found!
|
|
1384
|
-
log.debug(Lf("|- File '{}' not found in DB", path))
|
|
1385
|
-
|
|
1386
|
-
# create file.
|
|
1387
|
-
conf_file = ConfigurationFile()
|
|
1388
|
-
conf_file.sha256 = check_sum
|
|
1389
|
-
conf_file.path = path
|
|
1390
|
-
conf_file.content = get_content()
|
|
1391
|
-
conf_file.importance = importance
|
|
1392
|
-
|
|
1393
|
-
# put it to DB and associate with run
|
|
1394
|
-
self.session.add(conf_file)
|
|
1395
|
-
self.session.commit()
|
|
1396
|
-
|
|
1397
|
-
conf_file.runs.append(run)
|
|
1398
|
-
|
|
1399
|
-
# save and exit
|
|
1400
|
-
self.session.commit()
|
|
1401
|
-
self.add_log_record(conf_file, "File added to DB. Path: '{}'. Run: '{}'".format(path, run), run.number)
|
|
1402
|
-
return conf_file
|
|
1403
|
-
|
|
1404
|
-
# such file already exists! Get it from database
|
|
1405
|
-
conf_file = file_query.first()
|
|
1406
|
-
log.debug(Lf("|- File '{}' found in DB by id: '{}'", path, conf_file.id))
|
|
1407
|
-
|
|
1408
|
-
# maybe... we even have this file in run conf?
|
|
1409
|
-
if conf_file not in run.files:
|
|
1410
|
-
conf_file.runs.append(run)
|
|
1411
|
-
# run_conf.files.append(conf_file)
|
|
1412
|
-
self.session.commit() # save and exit
|
|
1413
|
-
self.add_log_record(conf_file, "File associated. Path: '{}'. Run: '{}'".format(path, run), run.number)
|
|
1414
|
-
else:
|
|
1415
|
-
log.debug(Lf("|- File already associated with run'{}'", run))
|
|
1416
|
-
|
|
1417
|
-
return conf_file
|
|
1420
|
+
"""Obsolete. Still exists for backward compatibility. All methods moved to RCDBProvider"""
|
|
1421
|
+
pass
|
|
1418
1422
|
|
|
1419
1423
|
|
|
1420
1424
|
def destroy_schema(db):
|
|
@@ -24,7 +24,7 @@ SQL_CONNECTION_STRING = "mysql+pymysql://rcdb@127.0.0.1/rcdb"
|
|
|
24
24
|
# Get the current directory
|
|
25
25
|
current_directory = os.path.dirname(os.path.abspath(__file__))
|
|
26
26
|
template_folder=os.path.join(current_directory, 'templates')
|
|
27
|
-
|
|
27
|
+
|
|
28
28
|
# Create Flask app with custom template folder
|
|
29
29
|
app = Flask(__name__, template_folder=template_folder)
|
|
30
30
|
|
|
@@ -28,6 +28,7 @@ rcdb.egg-info/requires.txt
|
|
|
28
28
|
rcdb.egg-info/top_level.txt
|
|
29
29
|
rcdb/cli/__init__.py
|
|
30
30
|
rcdb/cli/__main__.py
|
|
31
|
+
rcdb/cli/add.py
|
|
31
32
|
rcdb/cli/app.py
|
|
32
33
|
rcdb/cli/context.py
|
|
33
34
|
rcdb/cli/db.py
|
|
@@ -199,6 +200,9 @@ rcdb/web/templates/settings/profile.html
|
|
|
199
200
|
rcdb/web/templates/statistics/index.html
|
|
200
201
|
rcdb/web/templates/user/index.html
|
|
201
202
|
rcdb/web/templates/user/profile.html
|
|
203
|
+
tests/test_cli_add_condition.py
|
|
204
|
+
tests/test_cli_add_file.py
|
|
205
|
+
tests/test_cli_add_type.py
|
|
202
206
|
tests/test_coda_parser.py
|
|
203
207
|
tests/test_conditions.py
|
|
204
208
|
tests/test_config_parser.py
|