z230
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,3 +1,3 @@
|
||||
2026/05/28-09:34:01.521 26f4 Reusing MANIFEST U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\Extension State/MANIFEST-000001
|
||||
2026/05/28-09:34:01.522 26f4 Recovering log #3
|
||||
2026/05/28-09:34:01.522 26f4 Reusing old log U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\Extension State/000003.log
|
||||
2026/05/29-13:24:16.539 6b34 Reusing MANIFEST U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\Extension State/MANIFEST-000001
|
||||
2026/05/29-13:24:16.540 6b34 Recovering log #3
|
||||
2026/05/29-13:24:16.541 6b34 Reusing old log U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\Extension State/000003.log
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
2026/05/28-09:20:54.095 55ec Reusing MANIFEST U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\Extension State/MANIFEST-000001
|
||||
2026/05/28-09:20:54.096 55ec Recovering log #3
|
||||
2026/05/28-09:20:54.096 55ec Reusing old log U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\Extension State/000003.log
|
||||
2026/05/29-13:17:37.742 5acc Reusing MANIFEST U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\Extension State/MANIFEST-000001
|
||||
2026/05/29-13:17:37.742 5acc Recovering log #3
|
||||
2026/05/29-13:17:37.743 5acc Reusing old log U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\Extension State/000003.log
|
||||
|
||||
Binary file not shown.
@@ -1,3 +1,3 @@
|
||||
2026/05/28-09:34:11.834 4160 Reusing MANIFEST U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\GCM Store/MANIFEST-000001
|
||||
2026/05/28-09:34:11.835 4160 Recovering log #3
|
||||
2026/05/28-09:34:11.836 4160 Reusing old log U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\GCM Store/000003.log
|
||||
2026/05/29-13:24:32.087 1144 Reusing MANIFEST U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\GCM Store/MANIFEST-000001
|
||||
2026/05/29-13:24:32.087 1144 Recovering log #3
|
||||
2026/05/29-13:24:32.087 1144 Reusing old log U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\GCM Store/000003.log
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
2026/05/28-09:21:04.862 2184 Reusing MANIFEST U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\GCM Store/MANIFEST-000001
|
||||
2026/05/28-09:21:04.864 2184 Recovering log #3
|
||||
2026/05/28-09:21:04.865 2184 Reusing old log U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\GCM Store/000003.log
|
||||
2026/05/29-13:17:47.687 5428 Reusing MANIFEST U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\GCM Store/MANIFEST-000001
|
||||
2026/05/29-13:17:47.696 5428 Recovering log #3
|
||||
2026/05/29-13:17:47.696 5428 Reusing old log U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\GCM Store/000003.log
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
+3
-3
@@ -1,3 +1,3 @@
|
||||
2026/05/28-08:18:49.515 3070 Reusing MANIFEST U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\IndexedDB\https_xsp.covance.com_0.indexeddb.leveldb/MANIFEST-000001
|
||||
2026/05/28-08:18:49.515 3070 Recovering log #3
|
||||
2026/05/28-08:18:49.515 3070 Reusing old log U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\IndexedDB\https_xsp.covance.com_0.indexeddb.leveldb/000003.log
|
||||
2026/05/29-11:20:05.334 264 Reusing MANIFEST U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\IndexedDB\https_xsp.covance.com_0.indexeddb.leveldb/MANIFEST-000001
|
||||
2026/05/29-11:20:05.335 264 Recovering log #3
|
||||
2026/05/29-11:20:05.335 264 Reusing old log U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\IndexedDB\https_xsp.covance.com_0.indexeddb.leveldb/000003.log
|
||||
|
||||
+3
-3
@@ -1,3 +1,3 @@
|
||||
2026/05/28-08:03:00.480 474c Reusing MANIFEST U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\IndexedDB\https_xsp.covance.com_0.indexeddb.leveldb/MANIFEST-000001
|
||||
2026/05/28-08:03:00.481 474c Recovering log #3
|
||||
2026/05/28-08:03:00.481 474c Reusing old log U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\IndexedDB\https_xsp.covance.com_0.indexeddb.leveldb/000003.log
|
||||
2026/05/29-11:17:21.700 5a0c Reusing MANIFEST U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\IndexedDB\https_xsp.covance.com_0.indexeddb.leveldb/MANIFEST-000001
|
||||
2026/05/29-11:17:21.700 5a0c Recovering log #3
|
||||
2026/05/29-11:17:21.700 5a0c Reusing old log U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\IndexedDB\https_xsp.covance.com_0.indexeddb.leveldb/000003.log
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,6 +1,6 @@
|
||||
2026/05/28-09:34:01.216 1690 Reusing MANIFEST U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\Local Storage\leveldb/MANIFEST-000001
|
||||
2026/05/28-09:34:01.223 1690 Recovering log #106
|
||||
2026/05/28-09:34:01.225 1690 Reusing old log U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\Local Storage\leveldb/000106.log
|
||||
2026/05/28-09:34:15.864 8d0 Level-0 table #110: started
|
||||
2026/05/28-09:34:15.951 8d0 Level-0 table #110: 24294 bytes OK
|
||||
2026/05/28-09:34:16.039 8d0 Delete type=0 #106
|
||||
2026/05/29-13:24:16.084 988 Reusing MANIFEST U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\Local Storage\leveldb/MANIFEST-000001
|
||||
2026/05/29-13:24:16.091 988 Recovering log #160
|
||||
2026/05/29-13:24:16.093 988 Reusing old log U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\Local Storage\leveldb/000160.log
|
||||
2026/05/29-13:24:33.012 6ac4 Level-0 table #165: started
|
||||
2026/05/29-13:24:33.073 6ac4 Level-0 table #165: 20511 bytes OK
|
||||
2026/05/29-13:24:33.150 6ac4 Delete type=0 #160
|
||||
|
||||
@@ -1,3 +1,15 @@
|
||||
2026/05/28-09:20:53.814 57f0 Reusing MANIFEST U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\Local Storage\leveldb/MANIFEST-000001
|
||||
2026/05/28-09:20:53.820 57f0 Recovering log #106
|
||||
2026/05/28-09:20:53.822 57f0 Reusing old log U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\Local Storage\leveldb/000106.log
|
||||
2026/05/29-13:17:37.366 6a60 Reusing MANIFEST U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\Local Storage\leveldb/MANIFEST-000001
|
||||
2026/05/29-13:17:37.373 6a60 Recovering log #157
|
||||
2026/05/29-13:17:37.375 6a60 Reusing old log U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\Local Storage\leveldb/000157.log
|
||||
2026/05/29-13:17:51.674 6264 Level-0 table #161: started
|
||||
2026/05/29-13:17:51.748 6264 Level-0 table #161: 19877 bytes OK
|
||||
2026/05/29-13:17:51.815 6264 Delete type=0 #157
|
||||
2026/05/29-13:17:51.816 6264 Compacting 4@0 + 1@1 files
|
||||
2026/05/29-13:17:51.881 6264 Generated table #162@0: 24 keys, 30021 bytes
|
||||
2026/05/29-13:17:51.882 6264 Compacted 4@0 + 1@1 files => 30021 bytes
|
||||
2026/05/29-13:17:51.914 6264 compacted to: files[ 0 1 1 0 0 0 0 ]
|
||||
2026/05/29-13:17:51.915 6264 Delete type=2 #149
|
||||
2026/05/29-13:17:51.915 6264 Delete type=2 #152
|
||||
2026/05/29-13:17:51.915 6264 Delete type=2 #155
|
||||
2026/05/29-13:17:51.915 6264 Delete type=2 #158
|
||||
2026/05/29-13:17:51.915 6264 Delete type=2 #161
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
||||
{"net":{"http_server_properties":{"servers":[{"anonymization":["GAAAABMAAABodHRwczovL2NvdmFuY2UuY29tAA==",false,0],"server":"https://login.labcorp.com","supports_spdy":true},{"anonymization":["GAAAABMAAABodHRwczovL2NvdmFuY2UuY29tAA==",false,0],"server":"https://cdn.pendo.io","supports_spdy":true},{"anonymization":["GAAAABMAAABodHRwczovL2NvdmFuY2UuY29tAA==",false,0],"server":"https://data.pendo.io","supports_spdy":true},{"alternative_service":[{"advertised_alpns":["h3"],"expiration":"13427014730141327","port":443,"protocol_str":"quic"}],"anonymization":["GAAAABMAAABodHRwczovL2NvdmFuY2UuY29tAA==",false,0],"network_stats":{"srtt":7242},"server":"https://content-autofill.googleapis.com","supports_spdy":true},{"anonymization":["GAAAABMAAABodHRwczovL2NvdmFuY2UuY29tAA==",true,0],"server":"https://login.labcorp.com","supports_spdy":true},{"alternative_service":[{"advertised_alpns":["h3"],"expiration":"13427019241807994","port":443,"protocol_str":"quic"}],"anonymization":["GAAAABIAAABodHRwczovL2dvb2dsZS5jb20AAA==",false,0],"network_stats":{"srtt":14394},"server":"https://accounts.google.com","supports_spdy":true},{"alternative_service":[{"advertised_alpns":["h3"],"expiration":"13424513642283952","port":443,"protocol_str":"quic"}],"anonymization":["GAAAABMAAABodHRwczovL2NvdmFuY2UuY29tAA==",false,0],"network_stats":{"srtt":3782},"server":"https://unpkg.com"},{"alternative_service":[{"advertised_alpns":["h3"],"expiration":"13427019251909434","port":443,"protocol_str":"quic"}],"anonymization":["GAAAABIAAABodHRwczovL2dvb2dsZS5jb20AAA==",false,0],"network_stats":{"srtt":8718},"server":"https://android.clients.google.com","supports_spdy":true},{"anonymization":["GAAAABMAAABodHRwczovL2xhYmNvcnAuY29tAA==",false,0],"network_stats":{"srtt":3267},"server":"https://fonts.gstatic.com"},{"alternative_service":[{"advertised_alpns":["h3"],"expiration":"13427012816734610","port":443,"protocol_str":"quic"}],"anonymization":["GAAAABMAAABodHRwczovL2xhYmNvcnAuY29tAA==",false,0],"network_stats":{"srtt":6914},"server":"https://fonts.googleapis.com","supports_spdy":true},{"anonymization":["GAAAABMAAABodHRwczovL2xhYmNvcnAuY29tAA==",false,0],"server":"https://login.labcorp.com","supports_spdy":true},{"alternative_service":[{"advertised_alpns":["h3"],"expiration":"13427019284329367","port":443,"protocol_str":"quic"}],"anonymization":["GAAAABMAAABodHRwczovL2xhYmNvcnAuY29tAA==",false,0],"network_stats":{"srtt":7280},"server":"https://content-autofill.googleapis.com","supports_spdy":true},{"alternative_service":[{"advertised_alpns":["h3"],"expiration":"13427019266698306","port":443,"protocol_str":"quic"}],"anonymization":["MAAAACwAAABodHRwczovL3Bhc3N3b3Jkc2xlYWtjaGVjay1wYS5nb29nbGVhcGlzLmNvbQ==",false,0],"network_stats":{"srtt":3684},"server":"https://passwordsleakcheck-pa.googleapis.com","supports_spdy":true},{"alternative_service":[{"advertised_alpns":["h3"],"expiration":"13424513657366598","port":443,"protocol_str":"quic"}],"anonymization":["GAAAABMAAABodHRwczovL2xhYmNvcnAuY29tAA==",false,0],"network_stats":{"srtt":6122},"server":"https://unpkg.com"},{"alternative_service":[{"advertised_alpns":["h3"],"expiration":"13427019241781650","port":443,"protocol_str":"quic"}],"anonymization":["GAAAABIAAABodHRwczovL2dvb2dsZS5jb20AAA==",false,0],"network_stats":{"srtt":5175},"server":"https://www.google.com","supports_spdy":true}],"supports_quic":{"address":"192.168.1.87","used_quic":true},"version":5},"network_qualities":{"CAESABiAgICA+P////8B":"4G"}}}
|
||||
{"net":{"http_server_properties":{"servers":[{"anonymization":["GAAAABMAAABodHRwczovL2NvdmFuY2UuY29tAA==",false,0],"server":"https://login.labcorp.com","supports_spdy":true},{"anonymization":["GAAAABMAAABodHRwczovL2NvdmFuY2UuY29tAA==",false,0],"server":"https://cdn.pendo.io","supports_spdy":true},{"anonymization":["GAAAABMAAABodHRwczovL2NvdmFuY2UuY29tAA==",false,0],"server":"https://data.pendo.io","supports_spdy":true},{"alternative_service":[{"advertised_alpns":["h3"],"expiration":"13427112006055382","port":443,"protocol_str":"quic"}],"anonymization":["GAAAABMAAABodHRwczovL2NvdmFuY2UuY29tAA==",false,0],"network_stats":{"srtt":6621},"server":"https://content-autofill.googleapis.com","supports_spdy":true},{"anonymization":["GAAAABMAAABodHRwczovL2NvdmFuY2UuY29tAA==",true,0],"server":"https://login.labcorp.com","supports_spdy":true},{"alternative_service":[{"advertised_alpns":["h3"],"expiration":"13427119456814562","port":443,"protocol_str":"quic"}],"anonymization":["GAAAABIAAABodHRwczovL2dvb2dsZS5jb20AAA==",false,0],"network_stats":{"srtt":10524},"server":"https://accounts.google.com","supports_spdy":true},{"alternative_service":[{"advertised_alpns":["h3"],"expiration":"13424613857546976","port":443,"protocol_str":"quic"}],"anonymization":["GAAAABMAAABodHRwczovL2NvdmFuY2UuY29tAA==",false,0],"network_stats":{"srtt":5917},"server":"https://unpkg.com","supports_spdy":true},{"alternative_service":[{"advertised_alpns":["h3"],"expiration":"13427107435975955","port":443,"protocol_str":"quic"}],"anonymization":["GAAAABMAAABodHRwczovL2xhYmNvcnAuY29tAA==",false,0],"network_stats":{"srtt":6306},"server":"https://fonts.googleapis.com","supports_spdy":true},{"anonymization":["GAAAABMAAABodHRwczovL2xhYmNvcnAuY29tAA==",false,0],"network_stats":{"srtt":6502},"server":"https://fonts.gstatic.com"},{"alternative_service":[{"advertised_alpns":["h3"],"expiration":"13427119484319015","port":443,"protocol_str":"quic"}],"anonymization":["MAAAACwAAABodHRwczovL3Bhc3N3b3Jkc2xlYWtjaGVjay1wYS5nb29nbGVhcGlzLmNvbQ==",false,0],"network_stats":{"srtt":4832},"server":"https://passwordsleakcheck-pa.googleapis.com","supports_spdy":true},{"alternative_service":[{"advertised_alpns":["h3"],"expiration":"13427119496814314","port":443,"protocol_str":"quic"}],"anonymization":["GAAAABIAAABodHRwczovL2dvb2dsZS5jb20AAA==",false,0],"network_stats":{"srtt":7750},"server":"https://android.clients.google.com","supports_spdy":true},{"anonymization":["GAAAABMAAABodHRwczovL2xhYmNvcnAuY29tAA==",false,0],"server":"https://login.labcorp.com","supports_spdy":true},{"alternative_service":[{"advertised_alpns":["h3"],"expiration":"13427119978225009","port":443,"protocol_str":"quic"}],"anonymization":["GAAAABMAAABodHRwczovL2xhYmNvcnAuY29tAA==",false,0],"network_stats":{"srtt":6055},"server":"https://content-autofill.googleapis.com","supports_spdy":true},{"alternative_service":[{"advertised_alpns":["h3"],"expiration":"13424614330059042","port":443,"protocol_str":"quic"}],"anonymization":["GAAAABMAAABodHRwczovL2xhYmNvcnAuY29tAA==",false,0],"network_stats":{"srtt":6720},"server":"https://unpkg.com"},{"alternative_service":[{"advertised_alpns":["h3"],"expiration":"13427119456718085","port":443,"protocol_str":"quic"}],"anonymization":["GAAAABIAAABodHRwczovL2dvb2dsZS5jb20AAA==",false,0],"network_stats":{"srtt":6576},"server":"https://www.google.com","supports_spdy":true}],"supports_quic":{"address":"192.168.1.87","used_quic":true},"version":5},"network_qualities":{"CAESABiAgICA+P////8B":"4G"}}}
|
||||
Binary file not shown.
@@ -1 +1 @@
|
||||
{"sts":[{"expiry":1811489682.936012,"host":"AMsYuZ7IFgNWVHHQOkqKt9MmwK65kaqBH0lsKFOUFH8=","mode":"force-https","sts_include_subdomains":true,"sts_observed":1779953682.936014},{"expiry":1811489656.619357,"host":"CSChKrlj3luqm4YaUcREYcNSGviDSaiJLYYv+tJJLQY=","mode":"force-https","sts_include_subdomains":true,"sts_observed":1779953656.619369},{"expiry":1811485129.395782,"host":"Cz1hgA9AsWBjlwLNwma1z9V2NS3WBGpE+hAisJYAzJg=","mode":"force-https","sts_include_subdomains":true,"sts_observed":1779949129.395788},{"expiry":1811485129.780754,"host":"bwzZzlAVpSjLBr+9/WzKm/QotRxOYnqfzWRcWGuF4/M=","mode":"force-https","sts_include_subdomains":true,"sts_observed":1779949129.780757},{"expiry":1811489684.552903,"host":"eS7TxKKR6KM2rUe5fGp4j6+eHcckwVadZAWT/TaU2RQ=","mode":"force-https","sts_include_subdomains":true,"sts_observed":1779953684.552906},{"expiry":1811489657.426032,"host":"e3SziuwfuO2UvuBno+qkR1ObHAzZmSUoJhrc7dbP1Uo=","mode":"force-https","sts_include_subdomains":true,"sts_observed":1779953657.426039},{"expiry":1811483216.73492,"host":"nAuqgR4iEWti7SOdT3UHPl6rmZU/DeaIm38P2O2OkgA=","mode":"force-https","sts_include_subdomains":false,"sts_observed":1779947216.734924},{"expiry":1810638866.791394,"host":"rBPMDlZ3oSoS5nWA5b3qh68smMftsPTTcEHPHa/8Asc=","mode":"force-https","sts_include_subdomains":true,"sts_observed":1779102866.791399},{"expiry":1811489641.782165,"host":"5EdUoB7YUY9zZV+2DkgVXgho8WUvp+D+6KpeUOhNQIM=","mode":"force-https","sts_include_subdomains":false,"sts_observed":1779953641.782169},{"expiry":1811489641.808069,"host":"8/RrMmQlCD2Gsp14wUCE1P8r7B2C5+yE0+g79IPyRsc=","mode":"force-https","sts_include_subdomains":true,"sts_observed":1779953641.808072}],"version":2}
|
||||
{"sts":[{"expiry":1811590376.982667,"host":"AMsYuZ7IFgNWVHHQOkqKt9MmwK65kaqBH0lsKFOUFH8=","mode":"force-https","sts_include_subdomains":true,"sts_observed":1780054376.982671},{"expiry":1811589873.806784,"host":"CSChKrlj3luqm4YaUcREYcNSGviDSaiJLYYv+tJJLQY=","mode":"force-https","sts_include_subdomains":true,"sts_observed":1780053873.80679},{"expiry":1811581653.541007,"host":"Cz1hgA9AsWBjlwLNwma1z9V2NS3WBGpE+hAisJYAzJg=","mode":"force-https","sts_include_subdomains":true,"sts_observed":1780045653.54101},{"expiry":1811582405.562701,"host":"bwzZzlAVpSjLBr+9/WzKm/QotRxOYnqfzWRcWGuF4/M=","mode":"force-https","sts_include_subdomains":true,"sts_observed":1780046405.562703},{"expiry":1811590379.118582,"host":"eS7TxKKR6KM2rUe5fGp4j6+eHcckwVadZAWT/TaU2RQ=","mode":"force-https","sts_include_subdomains":true,"sts_observed":1780054379.118586},{"expiry":1811590330.059279,"host":"e3SziuwfuO2UvuBno+qkR1ObHAzZmSUoJhrc7dbP1Uo=","mode":"force-https","sts_include_subdomains":true,"sts_observed":1780054330.059282},{"expiry":1811577835.976147,"host":"nAuqgR4iEWti7SOdT3UHPl6rmZU/DeaIm38P2O2OkgA=","mode":"force-https","sts_include_subdomains":false,"sts_observed":1780041835.97615},{"expiry":1810638866.791394,"host":"rBPMDlZ3oSoS5nWA5b3qh68smMftsPTTcEHPHa/8Asc=","mode":"force-https","sts_include_subdomains":true,"sts_observed":1779102866.791399},{"expiry":1811589856.718672,"host":"5EdUoB7YUY9zZV+2DkgVXgho8WUvp+D+6KpeUOhNQIM=","mode":"force-https","sts_include_subdomains":false,"sts_observed":1780053856.718678},{"expiry":1811589856.814671,"host":"8/RrMmQlCD2Gsp14wUCE1P8r7B2C5+yE0+g79IPyRsc=","mode":"force-https","sts_include_subdomains":true,"sts_observed":1780053856.814676}],"version":2}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -1,3 +1,3 @@
|
||||
2026/05/28-09:34:01.390 1690 Reusing MANIFEST U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\Session Storage/MANIFEST-000001
|
||||
2026/05/28-09:34:01.393 1690 Recovering log #4
|
||||
2026/05/28-09:34:01.411 1690 Reusing old log U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\Session Storage/000004.log
|
||||
2026/05/29-13:24:16.313 988 Reusing MANIFEST U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\Session Storage/MANIFEST-000001
|
||||
2026/05/29-13:24:16.314 988 Recovering log #7
|
||||
2026/05/29-13:24:16.318 988 Reusing old log U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\Session Storage/000007.log
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
2026/05/28-09:20:53.976 57f0 Reusing MANIFEST U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\Session Storage/MANIFEST-000001
|
||||
2026/05/28-09:20:53.978 57f0 Recovering log #4
|
||||
2026/05/28-09:20:53.995 57f0 Reusing old log U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\Session Storage/000004.log
|
||||
2026/05/29-13:17:37.578 6a60 Reusing MANIFEST U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\Session Storage/MANIFEST-000001
|
||||
2026/05/29-13:17:37.580 6a60 Recovering log #7
|
||||
2026/05/29-13:17:37.611 6a60 Reusing old log U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\Session Storage/000007.log
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,3 +1,3 @@
|
||||
2026/05/28-09:34:01.159 3804 Reusing MANIFEST U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\Site Characteristics Database/MANIFEST-000001
|
||||
2026/05/28-09:34:01.161 3804 Recovering log #3
|
||||
2026/05/28-09:34:01.161 3804 Reusing old log U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\Site Characteristics Database/000003.log
|
||||
2026/05/29-13:24:16.027 3a94 Reusing MANIFEST U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\Site Characteristics Database/MANIFEST-000001
|
||||
2026/05/29-13:24:16.029 3a94 Recovering log #3
|
||||
2026/05/29-13:24:16.030 3a94 Reusing old log U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\Site Characteristics Database/000003.log
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
2026/05/28-09:20:53.754 56d0 Reusing MANIFEST U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\Site Characteristics Database/MANIFEST-000001
|
||||
2026/05/28-09:20:53.757 56d0 Recovering log #3
|
||||
2026/05/28-09:20:53.758 56d0 Reusing old log U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\Site Characteristics Database/000003.log
|
||||
2026/05/29-13:17:37.311 662c Reusing MANIFEST U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\Site Characteristics Database/MANIFEST-000001
|
||||
2026/05/29-13:17:37.316 662c Recovering log #3
|
||||
2026/05/29-13:17:37.316 662c Reusing old log U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\Site Characteristics Database/000003.log
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
2026/05/28-09:34:01.147 5b28 Reusing MANIFEST U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\Sync Data\LevelDB/MANIFEST-000001
|
||||
2026/05/28-09:34:01.153 5b28 Recovering log #3
|
||||
2026/05/28-09:34:01.153 5b28 Reusing old log U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\Sync Data\LevelDB/000003.log
|
||||
2026/05/29-13:24:16.017 6b88 Reusing MANIFEST U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\Sync Data\LevelDB/MANIFEST-000001
|
||||
2026/05/29-13:24:16.020 6b88 Recovering log #3
|
||||
2026/05/29-13:24:16.021 6b88 Reusing old log U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\Sync Data\LevelDB/000003.log
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
2026/05/28-09:20:53.750 28cc Reusing MANIFEST U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\Sync Data\LevelDB/MANIFEST-000001
|
||||
2026/05/28-09:20:53.756 28cc Recovering log #3
|
||||
2026/05/28-09:20:53.757 28cc Reusing old log U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\Sync Data\LevelDB/000003.log
|
||||
2026/05/29-13:17:37.299 6564 Reusing MANIFEST U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\Sync Data\LevelDB/MANIFEST-000001
|
||||
2026/05/29-13:17:37.306 6564 Recovering log #3
|
||||
2026/05/29-13:17:37.306 6564 Reusing old log U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\Sync Data\LevelDB/000003.log
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
||||
v10*κE0Iω4ΗΎη4�"�7>ΑXι�zE@κ‰Λ[�ρ�σί�Ο‡!�,�σΥ³ξxΉ#PΎ“ρτΟΣπ
|
||||
v10Œ%4Â{}x|P„Ì1d’lðá[5²ilpÒ(÷ZON~ éøBîžl\Û´²ÂD”°�²%¥Ðɺê»
|
||||
Binary file not shown.
@@ -1,3 +1,3 @@
|
||||
2026/05/28-09:34:01.405 26f4 Reusing MANIFEST U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\shared_proto_db/MANIFEST-000001
|
||||
2026/05/28-09:34:01.406 26f4 Recovering log #3
|
||||
2026/05/28-09:34:01.408 26f4 Reusing old log U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\shared_proto_db/000003.log
|
||||
2026/05/29-13:24:16.339 6b88 Reusing MANIFEST U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\shared_proto_db/MANIFEST-000001
|
||||
2026/05/29-13:24:16.339 6b88 Recovering log #3
|
||||
2026/05/29-13:24:16.341 6b88 Reusing old log U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\shared_proto_db/000003.log
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
2026/05/28-09:20:53.995 28cc Reusing MANIFEST U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\shared_proto_db/MANIFEST-000001
|
||||
2026/05/28-09:20:53.996 28cc Recovering log #3
|
||||
2026/05/28-09:20:53.997 28cc Reusing old log U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\shared_proto_db/000003.log
|
||||
2026/05/29-13:17:37.597 5d84 Reusing MANIFEST U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\shared_proto_db/MANIFEST-000001
|
||||
2026/05/29-13:17:37.598 5d84 Recovering log #3
|
||||
2026/05/29-13:17:37.600 5d84 Reusing old log U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\shared_proto_db/000003.log
|
||||
|
||||
Binary file not shown.
@@ -1,3 +1,3 @@
|
||||
2026/05/28-09:34:01.398 26f4 Reusing MANIFEST U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\shared_proto_db\metadata/MANIFEST-000001
|
||||
2026/05/28-09:34:01.399 26f4 Recovering log #3
|
||||
2026/05/28-09:34:01.399 26f4 Reusing old log U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\shared_proto_db\metadata/000003.log
|
||||
2026/05/29-13:24:16.334 6b88 Reusing MANIFEST U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\shared_proto_db\metadata/MANIFEST-000001
|
||||
2026/05/29-13:24:16.334 6b88 Recovering log #3
|
||||
2026/05/29-13:24:16.335 6b88 Reusing old log U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\shared_proto_db\metadata/000003.log
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
2026/05/28-09:20:53.987 28cc Reusing MANIFEST U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\shared_proto_db\metadata/MANIFEST-000001
|
||||
2026/05/28-09:20:53.988 28cc Recovering log #3
|
||||
2026/05/28-09:20:53.988 28cc Reusing old log U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\shared_proto_db\metadata/000003.log
|
||||
2026/05/29-13:17:37.591 5d84 Reusing MANIFEST U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\shared_proto_db\metadata/MANIFEST-000001
|
||||
2026/05/29-13:17:37.592 5d84 Recovering log #3
|
||||
2026/05/29-13:17:37.592 5d84 Reusing old log U:\PythonProject\Janssen\Covance_UCO3001\browser_profile\Default\shared_proto_db\metadata/000003.log
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
||||
{"autofill":{"ablation_seed":"Pts3KboF9Gg="},"breadcrumbs":{"enabled":false,"enabled_time":"13423576449583774"},"browser":{"shortcut_migration_version":"145.0.7632.6","whats_new":{"enabled_order":["ReadAnythingReadAloud","SideBySide","PdfInk2"]}},"chrome_labs_activation_threshold":89,"chrome_labs_new_badge_dict":{},"hardware_acceleration_mode_previous":true,"legacy":{"profile":{"name":{"migrated":true}}},"local":{"password_hash_data_list":[]},"management":{"platform":{"azure_active_directory":8,"enterprise_mdm_win":0}},"network_time":{"network_time_mapping":{"local":1.77994815531412e+12,"network":1.779948155236e+12,"ticks":4838234648.0,"uncertainty":10134021.0}},"os_crypt":{"audit_enabled":true,"encrypted_key":"RFBBUEkBAAAA0Iyd3wEV0RGMegDAT8KX6wEAAADkezkwH4wQT6pFnkj5e+nkEAAAADQAAABHAG8AbwBnAGwAZQAgAEMAaAByAG8AbQBlACAAZgBvAHIAIABUAGUAcwB0AGkAbgBnAAAAA2YAAMAAAAAQAAAAD8GdBnyhPqKO+3clLuoubgAAAAAEgAAAoAAAABAAAADMD85LpYqkKeWfmsz19kEEKAAAADmxXqsmFE4qCIFVf7fbf6Lkktqe+GmWXWIQTJb2EHCeDDclpUygwFUUAAAAxudMuaV2vqrqS22DRgyN4Bw1/aI="},"performance_intervention":{"last_daily_sample":"13424420803777120"},"policy":{"last_statistics_update":"13424420803455233"},"profile":{"info_cache":{"Default":{"active_time":1779952853.947476,"avatar_icon":"chrome://theme/IDR_PROFILE_AVATAR_26","background_apps":false,"default_avatar_fill_color":-2890755,"default_avatar_stroke_color":-16166200,"enterprise_label":"","force_signin_profile_locked":false,"gaia_given_name":"","gaia_id":"","gaia_name":"","hosted_domain":"","is_consented_primary_account":false,"is_ephemeral":false,"is_glic_eligible":false,"is_managed":0,"is_using_default_avatar":true,"is_using_default_name":true,"managed_user_id":"","metrics_bucket_index":1,"name":"Your Chromium","profile_color_seed":-16033840,"profile_highlight_color":-2890755,"signin.with_credential_provider":false,"user_name":""}},"last_active_profiles":["Default"],"metrics":{"next_bucket_index":2},"profile_counts_reported":"13424420803460889","profiles_order":["Default"]},"profile_network_context_service":{"http_cache_finch_experiment_groups":"None None None None"},"session_id_generator_last_value":"1074085646","signin":{"active_accounts_last_emitted":"13424420803387923"},"subresource_filter":{"ruleset_version":{"checksum":0,"content":"","format":0}},"tab_stats":{"discards_external":0,"discards_frozen":0,"discards_proactive":0,"discards_suggested":0,"discards_urgent":0,"last_daily_sample":"13424420803441717","max_tabs_per_window":2,"reloads_external":0,"reloads_frozen":0,"reloads_proactive":0,"reloads_suggested":0,"reloads_urgent":0,"total_tab_count_max":2,"window_count_max":1},"toast":{"non_milestone_update_toast_version":"145.0.7632.6"},"ukm":{"persisted_logs":[]},"uninstall_metrics":{"installation_date2":"1779102849"},"user_experience_metrics":{"client_id2":"43a4d29b-dfa2-4f8b-9a46-fe2351fed503","client_id_timestamp":"1779102849","limited_entropy_randomization_source":"795E664817D8383D9992183FB246CB96","log_record_id":29,"low_entropy_source3":4488,"machine_id":6709466,"pseudo_low_entropy_source":1702,"session_id":28,"stability":{"browser_last_live_timestamp":"13424427286217033","exited_cleanly":true,"saved_system_profile":"CLzkm8sGEhUxNDUuMC43NjMyLjYtNjQtZGV2ZWwYsOKr0AYiBWVuLVVTKhgKCldpbmRvd3MgTlQSCjEwLjAuMTkwNDQyfgoGeDg2XzY0EMb9ARiAgNT7sP8fIhlIUCBaMjMwIFRvd2VyIFdvcmtzdGF0aW9uKAMwgBQ4oAtCCggAEAAaADIAOgBNiU3PQlXibM9CZQAAwD9qGAoMR2VudWluZUludGVsEMONDBgIIAEoAIIBAIoBAKoBBng4Nl82NLABAUoKDW0jOl4V0IbiWUoKDZK3V7MV3xdKP0oKDQUO8PQVgI19ylAAaggIABAAOABAAIABsOKr0AaYAQD4AYgjgAL///////////8BiAIAkgIkNDNhNGQyOWItZGZhMi00ZjhiLTlhNDYtZmUyMzUxZmVkNTAzqAKmDbICoAFkHjnSnstQPTfirX7FiAAqfsiwbNubM6kLj70v2MAtsf5bz4dGdDQ67motfyp+LMUZDNsJTLRUE0n9H/9UH43yOKroA8plfhtjdx59eUuqaR4MRo3j+04u52w1YviiiC9v2UFh7INtJFaBCRbIQET+tRCH0tbGCqYb9QXxOQvdoidEg0ktvAubY+tt3VOfvs9ZduhzQuDj64SLuP9M8w1d8QKiJMcGz0wjig==","saved_system_profile_hash":"D84CCF82A85C1BE2C9DA241E7E58399ECE4C5019","stats_buildtime":"1768354364","stats_version":"145.0.7632.6-64-devel","system_crash_count":0}},"variations_google_groups":{"Default":[]},"was":{"restarted":false}}
|
||||
{"autofill":{"ablation_seed":"Pts3KboF9Gg="},"breadcrumbs":{"enabled":false,"enabled_time":"13423576449583774"},"browser":{"shortcut_migration_version":"145.0.7632.6","whats_new":{"enabled_order":["ReadAnythingReadAloud","SideBySide","PdfInk2"]}},"chrome_labs_activation_threshold":89,"chrome_labs_new_badge_dict":{},"hardware_acceleration_mode_previous":true,"legacy":{"profile":{"name":{"migrated":true}}},"local":{"password_hash_data_list":[]},"management":{"platform":{"azure_active_directory":8,"enterprise_mdm_win":0}},"network_time":{"network_time_mapping":{"local":1.780042333499841e+12,"network":1.780042333448e+12,"ticks":8161390296.0,"uncertainty":10134152.0}},"os_crypt":{"audit_enabled":true,"encrypted_key":"RFBBUEkBAAAA0Iyd3wEV0RGMegDAT8KX6wEAAADkezkwH4wQT6pFnkj5e+nkEAAAADQAAABHAG8AbwBnAGwAZQAgAEMAaAByAG8AbQBlACAAZgBvAHIAIABUAGUAcwB0AGkAbgBnAAAAA2YAAMAAAAAQAAAAD8GdBnyhPqKO+3clLuoubgAAAAAEgAAAoAAAABAAAADMD85LpYqkKeWfmsz19kEEKAAAADmxXqsmFE4qCIFVf7fbf6Lkktqe+GmWXWIQTJb2EHCeDDclpUygwFUUAAAAxudMuaV2vqrqS22DRgyN4Bw1/aI="},"performance_intervention":{"last_daily_sample":"13424515424338664"},"policy":{"last_statistics_update":"13424515424054832"},"profile":{"info_cache":{"Default":{"active_time":1780050927.615976,"avatar_icon":"chrome://theme/IDR_PROFILE_AVATAR_26","background_apps":false,"default_avatar_fill_color":-2890755,"default_avatar_stroke_color":-16166200,"enterprise_label":"","force_signin_profile_locked":false,"gaia_given_name":"","gaia_id":"","gaia_name":"","hosted_domain":"","is_consented_primary_account":false,"is_ephemeral":false,"is_glic_eligible":false,"is_managed":0,"is_using_default_avatar":true,"is_using_default_name":true,"managed_user_id":"","metrics_bucket_index":1,"name":"Your Chromium","profile_color_seed":-16033840,"profile_highlight_color":-2890755,"signin.with_credential_provider":false,"user_name":""}},"last_active_profiles":[],"metrics":{"next_bucket_index":2},"profile_counts_reported":"13424515424059085","profiles_order":["Default"]},"profile_network_context_service":{"http_cache_finch_experiment_groups":"None None None None"},"session_id_generator_last_value":"1074088497","signin":{"active_accounts_last_emitted":"13424515423988667"},"subresource_filter":{"ruleset_version":{"checksum":0,"content":"","format":0}},"tab_stats":{"discards_external":0,"discards_frozen":0,"discards_proactive":0,"discards_suggested":0,"discards_urgent":0,"last_daily_sample":"13424515424040457","max_tabs_per_window":2,"reloads_external":0,"reloads_frozen":0,"reloads_proactive":0,"reloads_suggested":0,"reloads_urgent":0,"total_tab_count_max":2,"window_count_max":1},"toast":{"non_milestone_update_toast_version":"145.0.7632.6"},"ukm":{"persisted_logs":[]},"uninstall_metrics":{"installation_date2":"1779102849"},"user_experience_metrics":{"client_id2":"43a4d29b-dfa2-4f8b-9a46-fe2351fed503","client_id_timestamp":"1779102849","limited_entropy_randomization_source":"795E664817D8383D9992183FB246CB96","log_record_id":50,"low_entropy_source3":4488,"machine_id":6709466,"pseudo_low_entropy_source":1702,"session_id":49,"stability":{"browser_last_live_timestamp":"13424527980612017","exited_cleanly":true,"saved_system_profile":"CLzkm8sGEhUxNDUuMC43NjMyLjYtNjQtZGV2ZWwYsOKr0AYiBWVuLVVTKhgKCldpbmRvd3MgTlQSCjEwLjAuMTkwNDQyfgoGeDg2XzY0EMb9ARiAgJiqpv8fIhlIUCBaMjMwIFRvd2VyIFdvcmtzdGF0aW9uKAMwgBQ4oAtCCggAEAAaADIAOgBNiU3PQlXibM9CZQAAwD9qGAoMR2VudWluZUludGVsEMONDBgIIAEoAIIBAIoBAKoBBng4Nl82NLABAUoKDW0jOl4V0IbiWUoKDZK3V7MV3xdKP0oKDQUO8PQVgI19ylAAaggIABAAOABAAIABsOKr0AaYAQD4AYgjgAL///////////8BiAIAkgIkNDNhNGQyOWItZGZhMi00ZjhiLTlhNDYtZmUyMzUxZmVkNTAzqAKmDbICqAFkHjnSnstQPTfirX7FiAAqfsiwbNubM6kLj70v2MAtsf5bz4dGdDQ67motfyp+LMUZDNsJTLRUE0n9H/9UH43yOKroA8plfhtjdx59eUuqaR4MRo2A+Qiq4/tOLsZ/zmTnbDVi+KKIL2/ZQWHsg20kVoEJFshARP61EIfS1sYKphv1BfE5C92iJ0SDSS28C5tj623dU5++z1l26HNC4OPrhIu4/0zzDV3xAlCbVVVSD3qO","saved_system_profile_hash":"9DC8C008783143F7F046BE60F9A2BA31B59BCA3C","stats_buildtime":"1768354364","stats_version":"145.0.7632.6-64-devel","system_crash_count":0}},"variations_google_groups":{"Default":[]},"was":{"restarted":false}}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,525 +0,0 @@
|
||||
import glob
|
||||
import os
|
||||
import shutil
|
||||
import pandas as pd
|
||||
from openpyxl import load_workbook
|
||||
from openpyxl.styles import Font, PatternFill, Border, Side, Alignment
|
||||
from openpyxl.utils import get_column_letter
|
||||
from datetime import date, datetime
|
||||
|
||||
# Paths
|
||||
src_dir = os.path.dirname(os.path.abspath(__file__)) + "/"
|
||||
out_dir = "U:/Dropbox/!!!Days/Downloads Z230/"
|
||||
|
||||
# Find source files
|
||||
src_files = glob.glob(src_dir + "Protocol 77242113UCO3001 - All Samples*.xlsx")
|
||||
assert src_files, "Source file not found!"
|
||||
src_file = src_files[0]
|
||||
print(f"Source xlsx: {src_file}")
|
||||
|
||||
csv_files = glob.glob(src_dir + "_EDCStdRpt-DataListing.csv")
|
||||
assert csv_files, "CSV file not found!"
|
||||
csv_file = csv_files[0]
|
||||
print(f"Source csv: {csv_file}")
|
||||
|
||||
kit_csv_files = glob.glob(src_dir + "sponsor-study-36940-kit-inventory-on-hand-expiration.csv")
|
||||
assert kit_csv_files, "Kit inventory CSV not found!"
|
||||
kit_csv_file = kit_csv_files[0]
|
||||
print(f"Kit csv: {kit_csv_file}")
|
||||
|
||||
eq_csv_files = glob.glob(src_dir + "sponsor-study-36940-activity-reports-documents-equery.csv")
|
||||
assert eq_csv_files, "eQuery CSV not found!"
|
||||
eq_csv_file = eq_csv_files[0]
|
||||
print(f"eQuery csv: {eq_csv_file}")
|
||||
|
||||
timestamp = datetime.now().strftime("%Y-%m-%d_%H%M%S")
|
||||
out_filename = f"{timestamp} 77242113UCO3001 CZE Labcorp samples and kit inventory report.xlsx"
|
||||
out_path = out_dir + out_filename
|
||||
|
||||
# Copy source file to output — preserves all formatting perfectly
|
||||
shutil.copy2(src_file, out_path)
|
||||
|
||||
# Load data with pandas for analysis
|
||||
df = pd.read_excel(src_file, sheet_name=0, header=0)
|
||||
|
||||
# All unique patients
|
||||
all_patients = sorted(df['Patient No.'].dropna().unique())
|
||||
|
||||
# BXSCR and DNA rows
|
||||
bxscr = df[df['Protocol Visit Code'] == 'BXSCR']
|
||||
dna = df[df['Protocol Visit Code'] == 'DNA']
|
||||
|
||||
# Parse date value to datetime object
|
||||
def fmt_date(val):
|
||||
if pd.isna(val):
|
||||
return None
|
||||
if isinstance(val, str):
|
||||
return datetime.strptime(val, '%d-%b-%Y')
|
||||
return pd.to_datetime(val).to_pydatetime()
|
||||
|
||||
OK_STATUSES = {'Received', 'In Inventory', 'Shipped'}
|
||||
|
||||
def get_specimen_info(visit_df, patient, specimen_type=None):
|
||||
rows = visit_df[visit_df['Patient No.'] == patient]
|
||||
if specimen_type:
|
||||
rows = rows[rows['Specimen Type'] == specimen_type]
|
||||
rows = rows[rows['Sample Status'].isin(OK_STATUSES)]
|
||||
if rows.empty:
|
||||
return '', None
|
||||
row = rows.iloc[0]
|
||||
return fmt_date(row['Container Receipt Date']), rows.index[0] + 2
|
||||
|
||||
def get_label_info(patient, label_code, visit_code):
|
||||
rows = df[(df['Patient No.'] == patient) &
|
||||
(df['Protocol Visit Code'] == visit_code) &
|
||||
(df['Container Label Line 1'] == label_code)]
|
||||
rows = rows[rows['Sample Status'].isin(OK_STATUSES)]
|
||||
if rows.empty:
|
||||
return '', None
|
||||
row = rows.iloc[0]
|
||||
return fmt_date(row['Container Receipt Date']), rows.index[0] + 2
|
||||
|
||||
# Open copied workbook and add analysis sheet
|
||||
out_wb = load_workbook(out_path)
|
||||
|
||||
# Rename and autofit first sheet
|
||||
src_ws = out_wb.active
|
||||
src_ws.title = "Zdroj"
|
||||
for col in src_ws.columns:
|
||||
max_len = max((len(str(cell.value)) if cell.value is not None else 0) for cell in col)
|
||||
src_ws.column_dimensions[get_column_letter(col[0].column)].width = min(max_len + 2, 50)
|
||||
|
||||
# ── Styly ────────────────────────────────────────────────────────────────────
|
||||
thin = Side(style='thin')
|
||||
border = Border(left=thin, right=thin, top=thin, bottom=thin)
|
||||
header_fill = PatternFill("solid", fgColor="4472C4")
|
||||
header_font = Font(name='Calibri', bold=True, size=11, color="FFFFFF")
|
||||
data_font = Font(name='Calibri', size=11)
|
||||
date_font_link = Font(name='Calibri', size=11, color="000000", underline='single')
|
||||
yes_fill = PatternFill("solid", fgColor="E2EFDA")
|
||||
no_fill = PatternFill("solid", fgColor="FFE7E7")
|
||||
sum_header_font = Font(name='Calibri', bold=True, size=11, color="000000")
|
||||
sum_total_font = Font(name='Calibri', bold=True, size=11)
|
||||
zero_font = Font(name='Calibri', size=11, color="BFBFBF")
|
||||
zero_red_font = Font(name='Calibri', size=11, color="C00000")
|
||||
dark_blue_fill = PatternFill("solid", fgColor="203764")
|
||||
orange_fill = PatternFill("solid", fgColor="FFF2CC")
|
||||
green_fill = PatternFill("solid", fgColor="E2EFDA")
|
||||
total_fill = PatternFill("solid", fgColor="D9E1F2")
|
||||
exp_fill = PatternFill("solid", fgColor="FFE7E7")
|
||||
ok_fill = PatternFill("solid", fgColor="E2EFDA")
|
||||
|
||||
# ── List: Přehled vzorků ──────────────────────────────────────────────────────
|
||||
analysis_ws = out_wb.create_sheet("Přehled vzorků")
|
||||
|
||||
columns = [
|
||||
("Investigator Name", 24),
|
||||
("Číslo pacienta", 20),
|
||||
("Máme biopsii SM11", 20),
|
||||
("Máme RNA", 16),
|
||||
("Máme Cryostor", 16),
|
||||
("DNA", 14),
|
||||
("PLASMPK I-0 TROUGH", 18),
|
||||
("PLASMA PK I-0 PEAK", 18),
|
||||
("SERUM ADA I-0 PRE", 18),
|
||||
("SM06/SERUM BIOM", 16),
|
||||
("SM07/WB RNA", 14),
|
||||
("SM10/FECAL", 14),
|
||||
("PLASMPK I-2 TROUGH", 18),
|
||||
("PLASMA PK I-2 PEAK", 18),
|
||||
("SERUM ADA I-2 PRE", 18),
|
||||
("STOOL I-2", 12),
|
||||
("PLASMPK I-4 TROUGH", 18),
|
||||
("PLASMA PK I-4 PEAK", 18),
|
||||
("SERUM ADA I-4 PRE", 18),
|
||||
("SM06/SERUM BIOM", 16),
|
||||
("SM07/WB RNA", 14),
|
||||
("STOOL I-4", 12),
|
||||
]
|
||||
|
||||
group_font = Font(name='Calibri', bold=True, size=11)
|
||||
group_fill = PatternFill("solid", fgColor="FFFFFF")
|
||||
group_border = Border(left=thin, right=thin, top=thin, bottom=thin)
|
||||
|
||||
groups = [
|
||||
(3, 5, "SCREENING"),
|
||||
(7, 12, "RANDOMIZACE I-0"),
|
||||
(13, 16, "I-2"),
|
||||
(17, 22, "I-4"),
|
||||
]
|
||||
for start_col, end_col, label in groups:
|
||||
analysis_ws.merge_cells(start_row=1, start_column=start_col, end_row=1, end_column=end_col)
|
||||
cell = analysis_ws.cell(row=1, column=start_col, value=label)
|
||||
cell.font = group_font
|
||||
cell.fill = group_fill
|
||||
cell.alignment = Alignment(horizontal='center', vertical='center')
|
||||
cell.border = group_border
|
||||
for c in range(start_col, end_col + 1):
|
||||
analysis_ws.cell(row=1, column=c).border = group_border
|
||||
|
||||
analysis_ws.row_dimensions[1].height = 20
|
||||
|
||||
for col_idx, (hdr, width) in enumerate(columns, 1):
|
||||
cell = analysis_ws.cell(row=2, column=col_idx, value=hdr)
|
||||
cell.font = header_font
|
||||
cell.fill = header_fill
|
||||
cell.border = border
|
||||
cell.alignment = Alignment(horizontal='center', vertical='center', wrap_text=True)
|
||||
analysis_ws.column_dimensions[get_column_letter(col_idx)].width = width
|
||||
|
||||
analysis_ws.row_dimensions[2].height = 30
|
||||
analysis_ws.freeze_panes = "C3"
|
||||
|
||||
src_sheet_name = out_wb.sheetnames[0]
|
||||
pat_sheet_name = "Seznam pacientů"
|
||||
|
||||
_csv_df_pre = pd.read_csv(csv_file, encoding='utf-8')
|
||||
_pat_pre = _csv_df_pre[['SiteNumber', 'Subject', 'Field4Value']].copy()
|
||||
_pat_pre['Field4Value'] = _pat_pre['Field4Value'].apply(lambda v: datetime.strptime(str(v).strip(), '%d %b %Y') if pd.notna(v) else None)
|
||||
_pat_pre = _pat_pre.sort_values(['SiteNumber', 'Subject', 'Field4Value']).reset_index(drop=True)
|
||||
patient_row_map = {}
|
||||
for i, row in _pat_pre.iterrows():
|
||||
pat = row['Subject']
|
||||
if pat not in patient_row_map:
|
||||
patient_row_map[pat] = i + 2
|
||||
|
||||
bxscr_patients = sorted(bxscr['Patient No.'].dropna().unique())
|
||||
|
||||
for row_idx, patient in enumerate(bxscr_patients, 3):
|
||||
investigator = bxscr[bxscr['Patient No.'] == patient].iloc[0]['Investigator Name']
|
||||
sm11, sm11_row = get_specimen_info(bxscr, patient, 'Tissue , Paraffin Block')
|
||||
rna, rna_row = get_specimen_info(bxscr, patient, 'Biopsy RNA Later')
|
||||
cryo, cryo_row = get_specimen_info(bxscr, patient, 'Biopsy, Frozen Tissue')
|
||||
dna_date, dna_row = get_specimen_info(dna, patient)
|
||||
trough, trough_row = get_label_info(patient, 'PLASMPK I-0 TROUGH', 'I-0')
|
||||
peak, peak_row = get_label_info(patient, 'PLASMA PK I-0 PEAK', 'I-0')
|
||||
ada, ada_row = get_label_info(patient, 'SERUM ADA I-0 PRE', 'I-0')
|
||||
sm06, sm06_row = get_label_info(patient, 'SM06/SERUM BIOM', 'I-0')
|
||||
sm07, sm07_row = get_label_info(patient, 'SM07/WB RNA', 'I-0')
|
||||
sm10, sm10_row = get_label_info(patient, 'SM10/FECAL', 'I-0')
|
||||
trough2, trough2_row = get_label_info(patient, 'PLASMPK I-2 TROUGH', 'I-2')
|
||||
peak2, peak2_row = get_label_info(patient, 'PLASMA PK I-2 PEAK', 'I-2')
|
||||
ada2, ada2_row = get_label_info(patient, 'SERUM ADA I-2 PRE', 'I-2')
|
||||
stool2, stool2_row = get_label_info(patient, 'STOOL I-2', 'I-2')
|
||||
trough4, trough4_row = get_label_info(patient, 'PLASMPK I-4 TROUGH', 'I-4')
|
||||
peak4, peak4_row = get_label_info(patient, 'PLASMA PK I-4 PEAK', 'I-4')
|
||||
ada4, ada4_row = get_label_info(patient, 'SERUM ADA I-4 PRE', 'I-4')
|
||||
sm064, sm064_row = get_label_info(patient, 'SM06/SERUM BIOM', 'I-4')
|
||||
sm074, sm074_row = get_label_info(patient, 'SM07/WB RNA', 'I-4')
|
||||
stool4, stool4_row = get_label_info(patient, 'STOOL I-4', 'I-4')
|
||||
|
||||
row_data = [investigator, patient,
|
||||
(sm11, sm11_row), (rna, rna_row), (cryo, cryo_row), (dna_date, dna_row),
|
||||
(trough, trough_row), (peak, peak_row), (ada, ada_row),
|
||||
(sm06, sm06_row), (sm07, sm07_row), (sm10, sm10_row),
|
||||
(trough2, trough2_row), (peak2, peak2_row), (ada2, ada2_row), (stool2, stool2_row),
|
||||
(trough4, trough4_row), (peak4, peak4_row), (ada4, ada4_row),
|
||||
(sm064, sm064_row), (sm074, sm074_row), (stool4, stool4_row)]
|
||||
|
||||
for col_idx, value in enumerate(row_data, 1):
|
||||
if col_idx <= 2:
|
||||
cell = analysis_ws.cell(row=row_idx, column=col_idx, value=value)
|
||||
if col_idx == 2 and patient in patient_row_map:
|
||||
cell.hyperlink = f"#'{pat_sheet_name}'!B{patient_row_map[patient]}"
|
||||
cell.font = Font(name='Calibri', size=11, underline='single')
|
||||
else:
|
||||
cell.font = data_font
|
||||
else:
|
||||
dt, excel_row = value
|
||||
cell = analysis_ws.cell(row=row_idx, column=col_idx, value=dt)
|
||||
if dt and excel_row is not None:
|
||||
cell.hyperlink = f"#'{src_sheet_name}'!A{excel_row}"
|
||||
cell.font = date_font_link
|
||||
cell.fill = yes_fill
|
||||
cell.number_format = 'DD-MMM-YYYY'
|
||||
else:
|
||||
cell.font = Font(name='Calibri', size=11, color="C00000")
|
||||
cell.fill = no_fill
|
||||
cell.border = border
|
||||
cell.alignment = Alignment(horizontal='center', vertical='center')
|
||||
|
||||
# ── List: Seznam pacientů ─────────────────────────────────────────────────────
|
||||
csv_df = pd.read_csv(csv_file, encoding='utf-8')
|
||||
patients_ws = out_wb.create_sheet("Seznam pacientů")
|
||||
|
||||
pat_columns = [
|
||||
("Číslo centra", 20),
|
||||
("Číslo pacienta", 20),
|
||||
("Kód návštěvy", 20),
|
||||
("Datum návštěvy", 16),
|
||||
("Typ návštěvy", 16),
|
||||
]
|
||||
|
||||
for col_idx, (col_name, width) in enumerate(pat_columns, 1):
|
||||
cell = patients_ws.cell(row=1, column=col_idx, value=col_name)
|
||||
cell.font = header_font
|
||||
cell.fill = header_fill
|
||||
cell.border = border
|
||||
cell.alignment = Alignment(horizontal='center', vertical='center', wrap_text=True)
|
||||
patients_ws.column_dimensions[get_column_letter(col_idx)].width = width
|
||||
|
||||
patients_ws.row_dimensions[1].height = 30
|
||||
patients_ws.freeze_panes = "A2"
|
||||
|
||||
def parse_date_edcstd(val):
|
||||
if pd.isna(val) or str(val).strip() == '':
|
||||
return None
|
||||
try:
|
||||
return datetime.strptime(str(val).strip(), '%d %b %Y')
|
||||
except:
|
||||
return None
|
||||
|
||||
pat_df = csv_df[['SiteNumber', 'Subject', 'InstanceName', 'Field4Value', 'Field5Value']].copy()
|
||||
pat_df['Field4Value'] = pat_df['Field4Value'].apply(parse_date_edcstd)
|
||||
pat_df = pat_df.sort_values(['SiteNumber', 'Subject', 'Field4Value']).reset_index(drop=True)
|
||||
|
||||
for row_idx, row in enumerate(pat_df.itertuples(index=False), 2):
|
||||
for col_idx, value in enumerate(row, 1):
|
||||
cell = patients_ws.cell(row=row_idx, column=col_idx, value=value)
|
||||
cell.font = data_font
|
||||
cell.border = border
|
||||
cell.alignment = Alignment(horizontal='center', vertical='center')
|
||||
if col_idx == 4 and value is not None:
|
||||
cell.number_format = 'DD-MMM-YYYY'
|
||||
|
||||
# ── Kit inventory — načtení a příprava dat ────────────────────────────────────
|
||||
kit_df_raw = pd.read_csv(kit_csv_file, encoding="utf-8")
|
||||
cze = kit_df_raw[kit_df_raw["Country"] == "CZE"].copy()
|
||||
|
||||
def parse_kit_date(val):
|
||||
if pd.isna(val):
|
||||
return None
|
||||
try:
|
||||
return datetime.strptime(str(val).strip(), "%b %d, %Y")
|
||||
except:
|
||||
return None
|
||||
|
||||
cze["Shipped Date"] = cze["Shipped Date"].apply(parse_kit_date)
|
||||
cze["Expiration Date"] = cze["Expiration Date"].apply(parse_kit_date)
|
||||
cze = cze.sort_values(["Site", "Kit Type", "Expiration Date"]).reset_index(drop=True)
|
||||
|
||||
today_dt = datetime.combine(date.today(), datetime.min.time())
|
||||
|
||||
def bucket(exp_date):
|
||||
if exp_date is None:
|
||||
return None
|
||||
return "soon" if (exp_date - today_dt).days <= 30 else "ok"
|
||||
|
||||
cze["_bucket"] = cze["Expiration Date"].apply(bucket)
|
||||
|
||||
kit_order = sorted(cze["Kit Type"].unique(), key=lambda x: (str(x).lstrip("T-").zfill(5), str(x)))
|
||||
kit_desc = cze.drop_duplicates("Kit Type").set_index("Kit Type")["Description"].to_dict()
|
||||
kit_sites = sorted(cze["Site"].unique())
|
||||
|
||||
# ── Pomocná funkce pro souhrnné tabulky ───────────────────────────────────────
|
||||
def write_summary_table(ws, current_row, title, rows_data, col_a_header):
|
||||
for c in range(1, 5):
|
||||
cell = ws.cell(row=current_row, column=c)
|
||||
cell.fill = dark_blue_fill
|
||||
cell.border = border
|
||||
ws.cell(row=current_row, column=1, value=title).font = Font(name='Calibri', bold=True, size=12, color="FFFFFF")
|
||||
ws.cell(row=current_row, column=1).alignment = Alignment(horizontal="left", vertical="center")
|
||||
ws.merge_cells(start_row=current_row, start_column=1, end_row=current_row, end_column=4)
|
||||
ws.row_dimensions[current_row].height = 22
|
||||
current_row += 1
|
||||
|
||||
for col_idx, (h, f) in enumerate(zip(
|
||||
[col_a_header, "Description", "Expiruje do 30 dní", "Expiruje později"],
|
||||
[header_fill, header_fill, orange_fill, green_fill]
|
||||
), 1):
|
||||
cell = ws.cell(row=current_row, column=col_idx, value=h)
|
||||
cell.font = sum_header_font
|
||||
cell.fill = f
|
||||
cell.border = border
|
||||
cell.alignment = Alignment(horizontal="center", vertical="center", wrap_text=True)
|
||||
ws.row_dimensions[current_row].height = 28
|
||||
current_row += 1
|
||||
|
||||
totals = [0, 0]
|
||||
for col_a, col_b, n_soon, n_ok in rows_data:
|
||||
totals[0] += n_soon
|
||||
totals[1] += n_ok
|
||||
all_zero = (n_soon == 0 and n_ok == 0)
|
||||
row_vals = [col_a, col_b, n_soon, n_ok]
|
||||
row_fills = [None, None,
|
||||
orange_fill if n_soon > 0 else None,
|
||||
green_fill if n_ok > 0 else None]
|
||||
for col_idx, (val, rfill) in enumerate(zip(row_vals, row_fills), 1):
|
||||
cell = ws.cell(row=current_row, column=col_idx, value=val)
|
||||
if col_idx >= 3 and val == 0:
|
||||
cell.font = zero_red_font if all_zero else zero_font
|
||||
else:
|
||||
cell.font = data_font
|
||||
cell.border = border
|
||||
cell.alignment = Alignment(horizontal="center" if col_idx >= 2 else "left", vertical="center")
|
||||
if rfill:
|
||||
cell.fill = rfill
|
||||
current_row += 1
|
||||
|
||||
for col_idx, val in enumerate(["CELKEM", "", totals[0], totals[1]], 1):
|
||||
cell = ws.cell(row=current_row, column=col_idx, value=val)
|
||||
cell.font = sum_total_font
|
||||
cell.fill = total_fill
|
||||
cell.border = border
|
||||
cell.alignment = Alignment(horizontal="center" if col_idx >= 2 else "left", vertical="center")
|
||||
current_row += 2
|
||||
return current_row
|
||||
|
||||
# ── List: Kit Inventory CZE ───────────────────────────────────────────────────
|
||||
kit_ws = out_wb.create_sheet("Kit Inventory CZE")
|
||||
|
||||
listing_columns = [
|
||||
("Project No.", 14),
|
||||
("Region", 10),
|
||||
("Country", 10),
|
||||
("Site", 38),
|
||||
("Kit Type", 12),
|
||||
("Description", 22),
|
||||
("Accession", 18),
|
||||
("Shipped Date", 16),
|
||||
("Expiration Date", 16),
|
||||
("Days to Expiration", 20),
|
||||
]
|
||||
|
||||
for col_idx, (hdr, width) in enumerate(listing_columns, 1):
|
||||
cell = kit_ws.cell(row=1, column=col_idx, value=hdr)
|
||||
cell.font = header_font
|
||||
cell.fill = header_fill
|
||||
cell.border = border
|
||||
cell.alignment = Alignment(horizontal="center", vertical="center", wrap_text=True)
|
||||
kit_ws.column_dimensions[get_column_letter(col_idx)].width = width
|
||||
|
||||
kit_ws.row_dimensions[1].height = 30
|
||||
kit_ws.freeze_panes = "A2"
|
||||
|
||||
for row_idx, row in enumerate(cze.itertuples(index=False), 2):
|
||||
days = row[9]
|
||||
for col_idx, (col_name, _) in enumerate(listing_columns, 1):
|
||||
value = row[col_idx - 1]
|
||||
cell = kit_ws.cell(row=row_idx, column=col_idx, value=value)
|
||||
cell.font = data_font
|
||||
cell.border = border
|
||||
cell.alignment = Alignment(horizontal="center", vertical="center")
|
||||
if col_name in ("Shipped Date", "Expiration Date") and value is not None:
|
||||
cell.number_format = "DD-MMM-YYYY"
|
||||
if col_name == "Days to Expiration":
|
||||
cell.fill = exp_fill if (pd.notna(days) and days <= 60) else ok_fill
|
||||
|
||||
kit_ws.auto_filter.ref = f"A1:{get_column_letter(len(listing_columns))}1"
|
||||
|
||||
# ── List: Přehled po centrech ─────────────────────────────────────────────────
|
||||
ctr_ws = out_wb.create_sheet("Přehled po centrech")
|
||||
ctr_ws.column_dimensions["A"].width = 22
|
||||
ctr_ws.column_dimensions["B"].width = 24
|
||||
ctr_ws.column_dimensions["C"].width = 22
|
||||
ctr_ws.column_dimensions["D"].width = 20
|
||||
|
||||
current_row = 1
|
||||
for site in kit_sites:
|
||||
site_df = cze[cze["Site"] == site]
|
||||
rows_data = []
|
||||
for kit in kit_order:
|
||||
desc = kit_desc.get(kit, "")
|
||||
kit_site_df = site_df[site_df["Kit Type"] == kit]
|
||||
n_soon = (kit_site_df["_bucket"] == "soon").sum()
|
||||
n_ok = (kit_site_df["_bucket"] == "ok").sum()
|
||||
rows_data.append((f"{kit} — {desc}", desc, n_soon, n_ok))
|
||||
current_row = write_summary_table(ctr_ws, current_row, site, rows_data, "Kit Type")
|
||||
|
||||
# ── List: Přehled po typech kitů ──────────────────────────────────────────────
|
||||
sum_ws = out_wb.create_sheet("Přehled po typech")
|
||||
sum_ws.column_dimensions["A"].width = 38
|
||||
sum_ws.column_dimensions["B"].width = 22
|
||||
sum_ws.column_dimensions["C"].width = 22
|
||||
sum_ws.column_dimensions["D"].width = 20
|
||||
|
||||
current_row = 1
|
||||
for kit in kit_order:
|
||||
desc = kit_desc.get(kit, "")
|
||||
kit_df = cze[cze["Kit Type"] == kit]
|
||||
rows_data = []
|
||||
for site in sorted(kit_df["Site"].unique()):
|
||||
site_df = kit_df[kit_df["Site"] == site]
|
||||
n_soon = (site_df["_bucket"] == "soon").sum()
|
||||
n_ok = (site_df["_bucket"] == "ok").sum()
|
||||
rows_data.append((site, desc, n_soon, n_ok))
|
||||
current_row = write_summary_table(sum_ws, current_row, f"Kit Type {kit} — {desc}", rows_data, "Centrum")
|
||||
|
||||
# ── List: eQueries ───────────────────────────────────────────────────────────
|
||||
eq_df = pd.read_csv(eq_csv_file, encoding="utf-8")
|
||||
eq_cze = eq_df[eq_df["Country"] == "CZECH REPUBLIC"].copy()
|
||||
|
||||
status_order = {"Open": 0, "Response Received": 1, "Closed": 2}
|
||||
eq_cze["_status_order"] = eq_cze["Status"].map(status_order).fillna(99)
|
||||
eq_cze = eq_cze.sort_values(["_status_order", "Site"]).reset_index(drop=True)
|
||||
|
||||
def parse_eq_date(val):
|
||||
if pd.isna(val):
|
||||
return None
|
||||
for fmt in ("%b %d, %Y %I:%M %p", "%b %d, %Y %I:%M %p"):
|
||||
try:
|
||||
return datetime.strptime(str(val).strip(), fmt)
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
return datetime.strptime(str(val).strip().split(" 12:00")[0], "%b %d, %Y")
|
||||
except:
|
||||
return None
|
||||
|
||||
eq_ws = out_wb.create_sheet("eQueries")
|
||||
|
||||
eq_columns = [
|
||||
("Site", 36),
|
||||
("Subject", 14),
|
||||
("Visit", 20),
|
||||
("Visit Collection Date", 20),
|
||||
("Accession", 16),
|
||||
("eQueryId", 12),
|
||||
("Issue Type", 30),
|
||||
("Status", 18),
|
||||
("Create Date", 20),
|
||||
("Response Date Time", 20),
|
||||
("Time Before Response", 20),
|
||||
("User Name", 20),
|
||||
]
|
||||
|
||||
status_fills = {
|
||||
"Open": PatternFill("solid", fgColor="FFE7E7"),
|
||||
"Response Received": PatternFill("solid", fgColor="FFF2CC"),
|
||||
"Closed": PatternFill("solid", fgColor="E2EFDA"),
|
||||
}
|
||||
|
||||
for col_idx, (hdr, width) in enumerate(eq_columns, 1):
|
||||
cell = eq_ws.cell(row=1, column=col_idx, value=hdr)
|
||||
cell.font = header_font
|
||||
cell.fill = header_fill
|
||||
cell.border = border
|
||||
cell.alignment = Alignment(horizontal="center", vertical="center", wrap_text=True)
|
||||
eq_ws.column_dimensions[get_column_letter(col_idx)].width = width
|
||||
|
||||
eq_ws.row_dimensions[1].height = 30
|
||||
eq_ws.freeze_panes = "A2"
|
||||
|
||||
for row_idx, row in enumerate(eq_cze.itertuples(index=False), 2):
|
||||
status = row[eq_cze.columns.get_loc("Status")]
|
||||
rfill = status_fills.get(status)
|
||||
for col_idx, (col_name, _) in enumerate(eq_columns, 1):
|
||||
value = row[eq_cze.columns.get_loc(col_name)]
|
||||
if col_name in ("Visit Collection Date", "Create Date", "Response Date Time"):
|
||||
value = parse_eq_date(value)
|
||||
cell = eq_ws.cell(row=row_idx, column=col_idx, value=value)
|
||||
cell.font = data_font
|
||||
cell.border = border
|
||||
cell.alignment = Alignment(horizontal="center" if col_idx > 1 else "left", vertical="center")
|
||||
if col_name in ("Visit Collection Date", "Create Date", "Response Date Time") and value:
|
||||
cell.number_format = "DD-MMM-YYYY HH:MM"
|
||||
if rfill:
|
||||
cell.fill = rfill
|
||||
|
||||
eq_ws.auto_filter.ref = f"A1:{get_column_letter(len(eq_columns))}1"
|
||||
|
||||
out_wb.save(out_path)
|
||||
print(f"Saved: {out_path}")
|
||||
print(f"Patients with BXSCR: {len(bxscr_patients)}, All unique patients: {len(all_patients)}")
|
||||
print(f"CZE kit rows: {len(cze)}, Kit types: {len(kit_order)}, Sites: {len(kit_sites)}")
|
||||
print(f"CZE eQueries: {len(eq_cze)} (Open: {(eq_cze['Status']=='Open').sum()}, Response Received: {(eq_cze['Status']=='Response Received').sum()}, Closed: {(eq_cze['Status']=='Closed').sum()})")
|
||||
@@ -23,6 +23,9 @@ PROFILE_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "browser_
|
||||
def login(page):
|
||||
page.goto(LOGIN_URL)
|
||||
page.wait_for_load_state("networkidle")
|
||||
if not page.get_by_label("Email").is_visible():
|
||||
print(f"Session aktivni, prihlasen: {page.url}")
|
||||
return
|
||||
page.get_by_label("Email").fill(EMAIL)
|
||||
page.get_by_role("button", name="Next").click()
|
||||
page.wait_for_load_state("networkidle")
|
||||
|
||||
@@ -45,6 +45,9 @@ REPORTS = [
|
||||
def login(page):
|
||||
page.goto(LOGIN_URL)
|
||||
page.wait_for_load_state("networkidle")
|
||||
if not page.get_by_label("Email").is_visible():
|
||||
print(f"Session aktivni, prihlasen: {page.url}")
|
||||
return
|
||||
page.get_by_label("Email").fill(EMAIL)
|
||||
page.get_by_role("button", name="Next").click()
|
||||
page.wait_for_load_state("networkidle")
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
# =============================================================================
|
||||
# Název: download_samples_report_v1.1.py
|
||||
# Verze: 1.1
|
||||
# Datum: 2026-05-28
|
||||
# Datum: 2026-05-29
|
||||
# Popis: Automatické stažení CSV reportu All Samples ze xsp.labcorp.com pro
|
||||
# studie 77242113UCO3001 (study 36940) a 42847922MDD3003 (study 35472).
|
||||
# Aplikuje country filtr CZ, date range od FROM_DATE, čeká na stabilní
|
||||
# Record Count. Výstup do příslušné složky Source/ každé studie.
|
||||
# Aplikuje country filtr CZ, date range od FROM_DATE, čeká na zmizení
|
||||
# "Fetching Data" před exportem. Výstup do Source/ každé studie.
|
||||
# =============================================================================
|
||||
from playwright.sync_api import sync_playwright
|
||||
from datetime import datetime
|
||||
@@ -31,6 +31,9 @@ TILE_SUFFIX = "allSamples"
|
||||
def login(page):
|
||||
page.goto(LOGIN_URL)
|
||||
page.wait_for_load_state("networkidle", timeout=120000)
|
||||
if not page.get_by_label("Email").is_visible():
|
||||
print(f"Session aktivni, prihlasen: {page.url}")
|
||||
return
|
||||
page.get_by_label("Email").fill(EMAIL)
|
||||
page.get_by_role("button", name="Next").click()
|
||||
page.wait_for_load_state("networkidle", timeout=120000)
|
||||
@@ -83,19 +86,14 @@ def export_tile(page, tile_label, file_suffix, timestamp, study_id, out_dir):
|
||||
page.wait_for_load_state("networkidle", timeout=120000)
|
||||
page.wait_for_timeout(3000)
|
||||
|
||||
# Čekej dokud:
|
||||
# 1. se neobjeví "No Data Available" (= record count je 0), nebo
|
||||
# 2. record count není nenulový
|
||||
page.wait_for_function("""() => {
|
||||
const noData = document.querySelector('div.table-row.no-data');
|
||||
if (noData) return true;
|
||||
const countEl = document.querySelector('div.grid-count span');
|
||||
if (countEl) {
|
||||
const n = parseInt(countEl.innerText.trim().replace(/,/g, ''), 10);
|
||||
return !isNaN(n) && n > 0;
|
||||
}
|
||||
return false;
|
||||
}""", timeout=30000)
|
||||
# Čekej až zmizí "Fetching Data": po filtru 5s, pak opakuj kontrolu každých 5s
|
||||
page.wait_for_timeout(5000)
|
||||
for _ in range(24): # max 2 minuty
|
||||
if not page.get_by_text("Fetching Data").is_visible():
|
||||
break
|
||||
print(" Fetching Data... cekam 5s")
|
||||
page.wait_for_timeout(5000)
|
||||
page.wait_for_timeout(5000) # extra buffer po zmizení
|
||||
|
||||
if page.locator("div.table-row.no-data").is_visible():
|
||||
print(f" Record Count: 0 — preskakuji.")
|
||||
@@ -128,7 +126,12 @@ if __name__ == "__main__":
|
||||
context = p.chromium.launch_persistent_context(
|
||||
user_data_dir=PROFILE_DIR,
|
||||
headless=False,
|
||||
args=["--disable-blink-features=AutomationControlled", "--start-maximized"],
|
||||
args=[
|
||||
"--disable-blink-features=AutomationControlled",
|
||||
"--start-maximized",
|
||||
"--disable-restore-session-state",
|
||||
"--disable-session-crashed-bubble",
|
||||
],
|
||||
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36",
|
||||
accept_downloads=True,
|
||||
no_viewport=True,
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
# Název: download_test_results_v1.0.py
|
||||
# Verze: 1.0
|
||||
# Datum: 2026-05-28
|
||||
# Popis: Stahuje Standard Test Results ze Covance/Labcorp XSP
|
||||
# pro studii 77242113UCO3001 (study 36940, report 930556).
|
||||
# Login přes xsp.covance.com → Okta, pak přímá URL na report.
|
||||
# Výstup: timestampované CSV do adresáře Source/.
|
||||
|
||||
from playwright.sync_api import sync_playwright
|
||||
from datetime import datetime
|
||||
import os
|
||||
|
||||
EMAIL = "vbuzalka@its.jnj.com"
|
||||
PASSWORD = "%zT3Wqfc9)cWua5"
|
||||
LOGIN_URL = "https://xsp.covance.com/"
|
||||
OUT_DIR = r"U:\PythonProject\Janssen\Covance_UCO3001\Source"
|
||||
PROFILE_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "browser_profile")
|
||||
|
||||
REPORTS = [
|
||||
{
|
||||
"site": "CZ10003",
|
||||
"url": "https://xsp.labcorp.com/sponsor/study/36940/test-results/930556/standard-test-results",
|
||||
"filename": "sponsor-study-36940-test-results-930556-standard-test-results.csv",
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
def login(page):
|
||||
page.goto(LOGIN_URL)
|
||||
page.wait_for_load_state("networkidle")
|
||||
page.get_by_label("Email").fill(EMAIL)
|
||||
page.get_by_role("button", name="Next").click()
|
||||
page.wait_for_load_state("networkidle")
|
||||
page.get_by_label("Password").fill(PASSWORD)
|
||||
page.get_by_role("button", name="Verify").click()
|
||||
page.wait_for_url(lambda url: "code=" not in url, timeout=60000)
|
||||
page.wait_for_load_state("networkidle", timeout=60000)
|
||||
page.wait_for_timeout(2000)
|
||||
print(f"Prihlaseni OK: {page.url}")
|
||||
|
||||
|
||||
def download_report(page, report):
|
||||
print(f"\n--- {report['site']} ---")
|
||||
page.goto(report["url"])
|
||||
page.wait_for_load_state("networkidle", timeout=60000)
|
||||
page.wait_for_timeout(3000)
|
||||
print(f"Report nacteny: {page.url}")
|
||||
|
||||
# Kliknout 3 tečky (more_horiz) vpravo od filtrovacího řádku
|
||||
page.locator("button").filter(has_text="more_horiz").last.click()
|
||||
|
||||
timestamp = datetime.now().strftime("%Y-%m-%d_%H%M%S")
|
||||
dest = os.path.join(OUT_DIR, f"{timestamp} {report['filename']}")
|
||||
|
||||
with page.expect_download(timeout=60000) as dl:
|
||||
page.get_by_text("Export to CSV").click()
|
||||
|
||||
dl.value.save_as(dest)
|
||||
print(f"Stazeno: {dest}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
with sync_playwright() as p:
|
||||
context = p.chromium.launch_persistent_context(
|
||||
user_data_dir=PROFILE_DIR,
|
||||
headless=False,
|
||||
args=["--disable-blink-features=AutomationControlled", "--start-maximized"],
|
||||
no_viewport=True,
|
||||
user_agent=(
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
|
||||
"AppleWebKit/537.36 (KHTML, like Gecko) "
|
||||
"Chrome/136.0.0.0 Safari/537.36"
|
||||
),
|
||||
accept_downloads=True,
|
||||
)
|
||||
context.add_init_script(
|
||||
"Object.defineProperty(navigator, 'webdriver', {get: () => undefined})"
|
||||
)
|
||||
page = context.new_page()
|
||||
login(page)
|
||||
for report in REPORTS:
|
||||
download_report(page, report)
|
||||
context.close()
|
||||
Reference in New Issue
Block a user