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.
Files changed (218) hide show
  1. {rcdb-2.2.8/rcdb.egg-info → rcdb-2.2.10}/PKG-INFO +1 -1
  2. rcdb-2.2.10/rcdb/cli/add.py +141 -0
  3. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/cli/app.py +10 -2
  4. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/cli/db.py +56 -1
  5. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/cli/info.py +15 -8
  6. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/provider.py +137 -133
  7. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/version.py +1 -1
  8. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/__init__.py +1 -1
  9. {rcdb-2.2.8 → rcdb-2.2.10/rcdb.egg-info}/PKG-INFO +1 -1
  10. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb.egg-info/SOURCES.txt +4 -0
  11. rcdb-2.2.10/tests/test_cli_add_condition.py +139 -0
  12. rcdb-2.2.10/tests/test_cli_add_file.py +105 -0
  13. rcdb-2.2.10/tests/test_cli_add_type.py +87 -0
  14. rcdb-2.2.10/tests/test_save_files.py +105 -0
  15. rcdb-2.2.8/tests/test_save_files.py +0 -54
  16. {rcdb-2.2.8 → rcdb-2.2.10}/MANIFEST.in +0 -0
  17. {rcdb-2.2.8 → rcdb-2.2.10}/README.md +0 -0
  18. {rcdb-2.2.8 → rcdb-2.2.10}/pyproject.toml +0 -0
  19. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/__init__.py +0 -0
  20. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/__main__.py +0 -0
  21. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/alias.py +0 -0
  22. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/app_context.py +0 -0
  23. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/cli/__init__.py +0 -0
  24. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/cli/__main__.py +0 -0
  25. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/cli/context.py +0 -0
  26. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/cli/ls.py +0 -0
  27. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/cli/repair/__init__.py +0 -0
  28. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/cli/repair/evio_files.py +0 -0
  29. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/cli/rp.py +0 -0
  30. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/cli/run.py +0 -0
  31. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/cli/select.py +0 -0
  32. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/cli/web.py +0 -0
  33. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/coda_parser.py +0 -0
  34. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/condition_query_builder.py +0 -0
  35. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/config_parser.py +0 -0
  36. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/constants.py +0 -0
  37. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/errors.py +0 -0
  38. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/file_archiver.py +0 -0
  39. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/halld_daq_config_parser.py +0 -0
  40. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/lexer.py +0 -0
  41. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/log_format.py +0 -0
  42. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/model.py +0 -0
  43. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/stopwatch.py +0 -0
  44. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/update.py +0 -0
  45. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/modules/__init__.py +0 -0
  46. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/modules/conditions.py +0 -0
  47. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/modules/files.py +0 -0
  48. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/modules/logs.py +0 -0
  49. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/modules/runs.py +0 -0
  50. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/modules/select_values.py +0 -0
  51. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/modules/statistics.py +0 -0
  52. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/pagination.py +0 -0
  53. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/run_table.py +0 -0
  54. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/css/dataTables.bootstrap.css +0 -0
  55. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/css/dataTables.bootstrap.min.css +0 -0
  56. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/css/dataTables.foundation.css +0 -0
  57. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/css/dataTables.foundation.min.css +0 -0
  58. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/css/dataTables.jqueryui.css +0 -0
  59. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/css/dataTables.jqueryui.min.css +0 -0
  60. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/css/jquery.dataTables.css +0 -0
  61. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/css/jquery.dataTables.min.css +0 -0
  62. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/css/jquery.dataTables_themeroller.css +0 -0
  63. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/images/sort_asc.png +0 -0
  64. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/images/sort_asc_disabled.png +0 -0
  65. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/images/sort_both.png +0 -0
  66. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/images/sort_desc.png +0 -0
  67. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/images/sort_desc_disabled.png +0 -0
  68. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/js/dataTables.bootstrap.js +0 -0
  69. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/js/dataTables.bootstrap.min.js +0 -0
  70. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/js/dataTables.foundation.js +0 -0
  71. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/js/dataTables.foundation.min.js +0 -0
  72. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/js/dataTables.jqueryui.js +0 -0
  73. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/js/dataTables.jqueryui.min.js +0 -0
  74. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/js/jquery.dataTables.js +0 -0
  75. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/DataTables-1.10.10/js/jquery.dataTables.min.js +0 -0
  76. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/Responsive-2.0.0/css/responsive.bootstrap.css +0 -0
  77. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/Responsive-2.0.0/css/responsive.bootstrap.min.css +0 -0
  78. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/Responsive-2.0.0/css/responsive.dataTables.css +0 -0
  79. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/Responsive-2.0.0/css/responsive.dataTables.min.css +0 -0
  80. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/Responsive-2.0.0/css/responsive.foundation.css +0 -0
  81. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/Responsive-2.0.0/css/responsive.foundation.min.css +0 -0
  82. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/Responsive-2.0.0/css/responsive.jqueryui.css +0 -0
  83. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/Responsive-2.0.0/css/responsive.jqueryui.min.css +0 -0
  84. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/Responsive-2.0.0/js/dataTables.responsive.js +0 -0
  85. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/Responsive-2.0.0/js/dataTables.responsive.min.js +0 -0
  86. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/Responsive-2.0.0/js/responsive.bootstrap.js +0 -0
  87. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/Responsive-2.0.0/js/responsive.bootstrap.min.js +0 -0
  88. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/Responsive-2.0.0/js/responsive.foundation.js +0 -0
  89. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/Responsive-2.0.0/js/responsive.foundation.min.js +0 -0
  90. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/Responsive-2.0.0/js/responsive.jqueryui.js +0 -0
  91. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/Responsive-2.0.0/js/responsive.jqueryui.min.js +0 -0
  92. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/RowReorder-1.1.0/css/rowReorder.bootstrap.css +0 -0
  93. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/RowReorder-1.1.0/css/rowReorder.bootstrap.min.css +0 -0
  94. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/RowReorder-1.1.0/css/rowReorder.dataTables.css +0 -0
  95. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/RowReorder-1.1.0/css/rowReorder.dataTables.min.css +0 -0
  96. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/RowReorder-1.1.0/css/rowReorder.foundation.css +0 -0
  97. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/RowReorder-1.1.0/css/rowReorder.foundation.min.css +0 -0
  98. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/RowReorder-1.1.0/css/rowReorder.jqueryui.css +0 -0
  99. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/RowReorder-1.1.0/css/rowReorder.jqueryui.min.css +0 -0
  100. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/RowReorder-1.1.0/js/dataTables.rowReorder.js +0 -0
  101. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/RowReorder-1.1.0/js/dataTables.rowReorder.min.js +0 -0
  102. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/datatables.css +0 -0
  103. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/datatables.js +0 -0
  104. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/datatables.min.css +0 -0
  105. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/DataTables/datatables.min.js +0 -0
  106. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/css/bootstrap-theme.css +0 -0
  107. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/css/bootstrap-theme.css.map +0 -0
  108. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/css/bootstrap-theme.min.css +0 -0
  109. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/css/bootstrap-theme.min.css.map +0 -0
  110. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/css/bootstrap.css +0 -0
  111. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/css/bootstrap.css.map +0 -0
  112. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/css/bootstrap.min.css +0 -0
  113. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/css/bootstrap.min.css.map +0 -0
  114. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/css/buttons.dataTables.min.css +0 -0
  115. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/css/dataTables.tableTools.css +0 -0
  116. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/css/jquery-ui.min.css +0 -0
  117. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/css/jquery-ui.structure.min.css +0 -0
  118. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/css/jquery-ui.theme.min.css +0 -0
  119. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/css/jquery.dataTables.min.css +0 -0
  120. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/css/jquery.dataTables.yadcf.css +0 -0
  121. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/css/jquery.jsonview.css +0 -0
  122. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/css/main.css +0 -0
  123. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/css/select.dataTables.min.css +0 -0
  124. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/css/webintellisense.css +0 -0
  125. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/favicon.png +0 -0
  126. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/fonts/glyphicons-halflings-regular.eot +0 -0
  127. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/fonts/glyphicons-halflings-regular.svg +0 -0
  128. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/fonts/glyphicons-halflings-regular.ttf +0 -0
  129. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/fonts/glyphicons-halflings-regular.woff +0 -0
  130. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/fonts/glyphicons-halflings-regular.woff2 +0 -0
  131. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/humans.txt +0 -0
  132. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/img/glyphicons-halflings-white.png +0 -0
  133. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/img/glyphicons-halflings.png +0 -0
  134. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/img/logo.png +0 -0
  135. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/js/bootstrap.js +0 -0
  136. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/js/bootstrap.min.js +0 -0
  137. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/js/clipboard.min.js +0 -0
  138. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/js/copy_clipboard.js +0 -0
  139. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/js/dataTables.buttons.min.js +0 -0
  140. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/js/dataTables.select.min.js +0 -0
  141. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/js/jquery-2.1.0.min.js +0 -0
  142. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/js/jquery-2.1.4.min.js +0 -0
  143. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/js/jquery-ui.min.js +0 -0
  144. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/js/jquery.dataTables.min.js +0 -0
  145. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/js/jquery.dataTables.yadcf.js +0 -0
  146. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/js/jquery.flot.min.js +0 -0
  147. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/js/jquery.jsonview.js +0 -0
  148. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/js/npm.js +0 -0
  149. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/js/webintellisense-ace.js +0 -0
  150. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/js/webintellisense-codemirror.js +0 -0
  151. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/js/webintellisense-textbox.js +0 -0
  152. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/js/webintellisense.js +0 -0
  153. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/robots.txt +0 -0
  154. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/static/style.css +0 -0
  155. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/404.html +0 -0
  156. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/admin/index.html +0 -0
  157. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/admin/layout.html +0 -0
  158. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/admin/user.html +0 -0
  159. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/admin/users.html +0 -0
  160. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/conditions/index.html +0 -0
  161. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/custom_column_run_table.html +0 -0
  162. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/default_run_table.html +0 -0
  163. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/errors/forbidden_page.html +0 -0
  164. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/errors/layout.html +0 -0
  165. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/errors/page_not_found.html +0 -0
  166. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/errors/server_error.html +0 -0
  167. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/files/index.html +0 -0
  168. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/files/info.html +0 -0
  169. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/files/not_found.html +0 -0
  170. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/frontend/create_profile.html +0 -0
  171. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/frontend/footers/help.html +0 -0
  172. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/frontend/login.html +0 -0
  173. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/frontend/login_openid.html +0 -0
  174. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/frontend/reauth.html +0 -0
  175. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/frontend/reset_password.html +0 -0
  176. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/frontend/search.html +0 -0
  177. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/frontend/signup.html +0 -0
  178. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/index.html +0 -0
  179. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/layout.html +0 -0
  180. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/layouts/base.html +0 -0
  181. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/layouts/base2.html +0 -0
  182. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/login.html +0 -0
  183. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/logs/index.html +0 -0
  184. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/macros/_ask_user_to_update_ie.html +0 -0
  185. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/macros/_form.html +0 -0
  186. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/macros/_google_analytics.html +0 -0
  187. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/macros/_misc.html +0 -0
  188. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/macros/_reset_password.html +0 -0
  189. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/render_pagination.html +0 -0
  190. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/run_search_box.html +0 -0
  191. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/runs/conditions.html +0 -0
  192. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/runs/example.html +0 -0
  193. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/runs/index.html +0 -0
  194. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/runs/info.html +0 -0
  195. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/runs/not_found.html +0 -0
  196. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/select_values/index.html +0 -0
  197. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/settings/layout.html +0 -0
  198. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/settings/password.html +0 -0
  199. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/settings/profile.html +0 -0
  200. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/show_entries.html +0 -0
  201. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/statistics/index.html +0 -0
  202. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/user/index.html +0 -0
  203. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb/web/templates/user/profile.html +0 -0
  204. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb.egg-info/dependency_links.txt +0 -0
  205. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb.egg-info/entry_points.txt +0 -0
  206. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb.egg-info/requires.txt +0 -0
  207. {rcdb-2.2.8 → rcdb-2.2.10}/rcdb.egg-info/top_level.txt +0 -0
  208. {rcdb-2.2.8 → rcdb-2.2.10}/setup.cfg +0 -0
  209. {rcdb-2.2.8 → rcdb-2.2.10}/tests/test_coda_parser.py +0 -0
  210. {rcdb-2.2.8 → rcdb-2.2.10}/tests/test_conditions.py +0 -0
  211. {rcdb-2.2.8 → rcdb-2.2.10}/tests/test_config_parser.py +0 -0
  212. {rcdb-2.2.8 → rcdb-2.2.10}/tests/test_get_run_periods.py +0 -0
  213. {rcdb-2.2.8 → rcdb-2.2.10}/tests/test_get_runs.py +0 -0
  214. {rcdb-2.2.8 → rcdb-2.2.10}/tests/test_halld_run_config_parser.py +0 -0
  215. {rcdb-2.2.8 → rcdb-2.2.10}/tests/test_select_runs.py +0 -0
  216. {rcdb-2.2.8 → rcdb-2.2.10}/tests/test_select_values.py +0 -0
  217. {rcdb-2.2.8 → rcdb-2.2.10}/tests/test_sql_schema_version.py +0 -0
  218. {rcdb-2.2.8 → rcdb-2.2.10}/tests/test_value_comparison.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rcdb
3
- Version: 2.2.8
3
+ Version: 2.2.10
4
4
  Summary: RCDB - Run Conditions DataBase
5
5
  Author-email: Dmitry Romanov <romanov@jlab.org>
6
6
  License-Expression: MIT
@@ -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
- "No command was specified"
56
- click.echo(ctx.get_help())
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"Number of conditions: {cnd_count}")
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 run period: {last_rp.name} (ID={last_rp.id})")
47
- else:
48
- click.echo("No run periods found.")
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("\n==== Available commands ====")
53
- click.echo(ctx.parent.get_help())
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
- RCDB data provider that uses SQLAlchemy for accessing databases
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):
@@ -1,5 +1,5 @@
1
1
  # String version. Used both for setup.py and for internal code
2
- version = '2.2.8'
2
+ version = '2.2.10'
3
3
 
4
4
  # version as the tuple of ints
5
5
  version_tuple = tuple(int(val) for val in version.split('.'))
@@ -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
- print(f"template_folder={template_folder}")
27
+
28
28
  # Create Flask app with custom template folder
29
29
  app = Flask(__name__, template_folder=template_folder)
30
30
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rcdb
3
- Version: 2.2.8
3
+ Version: 2.2.10
4
4
  Summary: RCDB - Run Conditions DataBase
5
5
  Author-email: Dmitry Romanov <romanov@jlab.org>
6
6
  License-Expression: MIT
@@ -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