rda-python-dsarch 3.0.13__tar.gz → 3.0.14__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 (21) hide show
  1. {rda_python_dsarch-3.0.13/src/rda_python_dsarch.egg-info → rda_python_dsarch-3.0.14}/PKG-INFO +1 -1
  2. {rda_python_dsarch-3.0.13 → rda_python_dsarch-3.0.14}/pyproject.toml +1 -1
  3. {rda_python_dsarch-3.0.13 → rda_python_dsarch-3.0.14}/src/rda_python_dsarch/dsarch.usg +14 -12
  4. {rda_python_dsarch-3.0.13 → rda_python_dsarch-3.0.14}/src/rda_python_dsarch/pg_arch.py +31 -23
  5. {rda_python_dsarch-3.0.13 → rda_python_dsarch-3.0.14/src/rda_python_dsarch.egg-info}/PKG-INFO +1 -1
  6. {rda_python_dsarch-3.0.13 → rda_python_dsarch-3.0.14}/LICENSE +0 -0
  7. {rda_python_dsarch-3.0.13 → rda_python_dsarch-3.0.14}/MANIFEST.in +0 -0
  8. {rda_python_dsarch-3.0.13 → rda_python_dsarch-3.0.14}/README.md +0 -0
  9. {rda_python_dsarch-3.0.13 → rda_python_dsarch-3.0.14}/setup.cfg +0 -0
  10. {rda_python_dsarch-3.0.13 → rda_python_dsarch-3.0.14}/src/rda_python_dsarch/PgArch.py +0 -0
  11. {rda_python_dsarch-3.0.13 → rda_python_dsarch-3.0.14}/src/rda_python_dsarch/PgMeta.py +0 -0
  12. {rda_python_dsarch-3.0.13 → rda_python_dsarch-3.0.14}/src/rda_python_dsarch/__init__.py +0 -0
  13. {rda_python_dsarch-3.0.13 → rda_python_dsarch-3.0.14}/src/rda_python_dsarch/ds_arch.py +0 -0
  14. {rda_python_dsarch-3.0.13 → rda_python_dsarch-3.0.14}/src/rda_python_dsarch/dsarch.py +0 -0
  15. {rda_python_dsarch-3.0.13 → rda_python_dsarch-3.0.14}/src/rda_python_dsarch/pg_meta.py +0 -0
  16. {rda_python_dsarch-3.0.13 → rda_python_dsarch-3.0.14}/src/rda_python_dsarch.egg-info/SOURCES.txt +0 -0
  17. {rda_python_dsarch-3.0.13 → rda_python_dsarch-3.0.14}/src/rda_python_dsarch.egg-info/dependency_links.txt +0 -0
  18. {rda_python_dsarch-3.0.13 → rda_python_dsarch-3.0.14}/src/rda_python_dsarch.egg-info/entry_points.txt +0 -0
  19. {rda_python_dsarch-3.0.13 → rda_python_dsarch-3.0.14}/src/rda_python_dsarch.egg-info/requires.txt +0 -0
  20. {rda_python_dsarch-3.0.13 → rda_python_dsarch-3.0.14}/src/rda_python_dsarch.egg-info/top_level.txt +0 -0
  21. {rda_python_dsarch-3.0.13 → rda_python_dsarch-3.0.14}/tests/test_dsarch.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rda_python_dsarch
3
- Version: 3.0.13
3
+ Version: 3.0.14
4
4
  Summary: RDA Python package for utility program dsarch archive RDA data
5
5
  Author-email: Zaihua Ji <zji@ucar.edu>
6
6
  Project-URL: Homepage, https://github.com/NCAR/rda-python-dsarch
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "rda_python_dsarch"
7
- version = "3.0.13"
7
+ version = "3.0.14"
8
8
  authors = [
9
9
  { name="Zaihua Ji", email="zji@ucar.edu" },
10
10
  ]
@@ -622,13 +622,13 @@ GroupIndex<:>GroupName<:>ParentIndex<:>Title<:>GroupPattern<:>BackupFlag<:>Saved
622
622
  2<:>MONTHLY<:>0<:>MONTHLY OAFlux Products<:><:>P<:><:>monthly<:>
623
623
  2 group records retrieved
624
624
  d260001-G1: DS-11094192261 DC-327 WC-327 SS-8909173908 SC-51
625
- d260001-G1 Web Files: Total 327(11094192261), Missing 0(0), Quasar Backup&DR 327(11094192261)
626
- d260001-G1 Saved Files: Total 51(8909173908), Missing 0(0), Quasar Backup&DR 51(8909173908)
625
+ d260001-G1 Web Files: Total 327(11.09GB), Quasar Backup&DR 327(11.09GB)
626
+ d260001-G1 Saved Files: Total 51(8.91GB), Quasar Backup&DR 51(8.91GB)
627
627
  d260001-G2: DS-552780725 DC-522 WC-522 SS-465789806 SC-51
628
- d260001-G2 Web Files: Total 522(552780725), Missing 2(2116424), Missing but on Quasar 1(1058212), Missing on Glade 2(2116424), Quasar Backup&DR 521(551722513), Not Backed Up 1(1058212)
628
+ d260001-G2 Web Files: Total 522(552.78MB), Missing on Glade 2(2.12MB) [Quasar Backup&DR 1(1.06MB), Not Backed Up 1(1.06MB)], Quasar Backup&DR 521(551.72MB), Not Backed Up 1(1.06MB)
629
629
  d260001-G2-W-D: monthly/2025/oaflux_202511.nc: Missing on Glade; on Quasar Backup&DR (Backup ID 3456789)
630
630
  d260001-G2-W-D: monthly/2025/oaflux_202512.nc: Missing on Glade; Not Backed Up
631
- d260001-G2 Saved Files: Total 51(465789806), Missing 0(0), Quasar Backup&DR 51(465789806)
631
+ d260001-G2 Saved Files: Total 51(465.79MB), Quasar Backup&DR 51(465.79MB)
632
632
 
633
633
 
634
634
  3.3.3 Delete Group Information
@@ -1941,14 +1941,16 @@ behavior.
1941
1941
  Files with Location Flag C (CGD) or R (remote) are not stored by
1942
1942
  GDEX and are not checked. One summary line per file category shows
1943
1943
  the file counts with -WN and the total file sizes with -WS (both as
1944
- Count(Size) when both options are given): the Total, the total
1945
- Missing (each file counted once; a Saved file found in COLD_STORAGE
1946
- is not missing), Missing but on Quasar (missing files that can still
1947
- be restored from a finished Quasar backup with action -RQ, so Missing
1948
- minus it is what is lost), then the result of each check. It is
1949
- followed by one line for every file missing or not backed up yet;
1950
- the line of a missing file also tells its Quasar backup, or that it
1951
- is not backed up.
1944
+ Count(Size) when both options are given, sizes in KB/MB/GB/TB): the
1945
+ Total, then the result of each check. Each Missing on Glade/Boreas
1946
+ count is followed by the Quasar status of its files in [], e.g.
1947
+ [Quasar Backup&DR 1(1.06MB), Not Backed Up 1(1.06MB)], so it tells
1948
+ how many of the missing files can be restored with action -RQ and
1949
+ how many are lost; for Saved files it also tells how many are In
1950
+ COLD_STORAGE. The Quasar counts after them are of all the files,
1951
+ missing or not. It is followed by one line for every file missing or
1952
+ not backed up yet; the line of a missing file also tells its Quasar
1953
+ backup, or that it is not backed up.
1952
1954
 
1953
1955
  -XC or -CrossCopy, used with -AW or -AS to fill gaps in storage:
1954
1956
  copies files from Glade disk to bOreas (or vice versa) wherever
@@ -1462,11 +1462,11 @@ class PgArch(PgOPT, PgCMD, PgSplit):
1462
1462
  # are not stored by GDEX and are checked neither on storage nor on Quasar
1463
1463
  # 'M' is the total of files missing, each counted once even when missing in both
1464
1464
  # places; a saved file found in COLD_STORAGE is not missing
1465
- # 'Q' are the missing files that can still be restored from a finished Quasar backup,
1466
- # so 'M' minus 'Q' is what is lost
1467
- QMSTATS = (('M', 'Missing'), ('Q', 'Missing but on Quasar'), ('G', 'Missing on Glade'),
1468
- ('O', 'Missing on Boreas'), ('C', 'In COLD_STORAGE'),
1469
- ('X', 'Not Checked (CGD/Remote)'))
1465
+ # each 'Missing on' count is broken down by the Quasar status of its files, so
1466
+ # it tells how many of them can still be restored and how many are lost; the
1467
+ # Quasar counts that follow are of all the files, missing or not
1468
+ QMSTATS = (('G', 'Missing on Glade'), ('O', 'Missing on Boreas'),
1469
+ ('C', 'In COLD_STORAGE'), ('X', 'Not Checked (CGD/Remote)'))
1470
1470
 
1471
1471
  def check_file_storage(self, dsid, head, gidxs, wn, ws):
1472
1472
  """
@@ -1527,6 +1527,8 @@ class PgArch(PgOPT, PgCMD, PgSplit):
1527
1527
  total = [0, 0]
1528
1528
  bcnts = {k: [0, 0] for (k, m) in self.QBSTATS}
1529
1529
  mcnts = {k: [0, 0] for (k, m) in self.QMSTATS}
1530
+ # Quasar status (and COLD_STORAGE for saved files) of the files missing per location
1531
+ mbcnts = {'G': {}, 'O': {}}
1530
1532
  lines = []
1531
1533
  for i in range(fcnt):
1532
1534
  fname = frecs['fname'][i]
@@ -1555,7 +1557,6 @@ class PgArch(PgOPT, PgCMD, PgSplit):
1555
1557
  if bkey != 'N': bmsg += " (Backup ID {})".format(frecs['bid'][i])
1556
1558
  # physical copies
1557
1559
  msgs = []
1558
- missed = False
1559
1560
  if locflag != 'O':
1560
1561
  if cate == 'S':
1561
1562
  lfile = "{}/{}/{}".format(self.RTPATH['SP'], ftype, fname)
@@ -1570,24 +1571,18 @@ class PgArch(PgOPT, PgCMD, PgSplit):
1570
1571
  if not op.exists(lfile):
1571
1572
  mcnts['G'][0] += 1
1572
1573
  mcnts['G'][1] += fsize
1573
- msg = self.QMSTATS[2][1]
1574
+ self.add_file_count(mbcnts['G'], bkey, fsize)
1575
+ msg = self.QMSTATS[0][1]
1574
1576
  if cfile:
1577
+ self.add_file_count(mbcnts['G'], 'C', fsize)
1575
1578
  msg += ", Found in COLD_STORAGE " + cfile
1576
- else:
1577
- missed = True
1578
1579
  msgs.append(msg)
1579
1580
  if locflag in ('O', 'B'):
1580
1581
  if not self.object_file_exists(dsid, fname, bucket):
1581
1582
  mcnts['O'][0] += 1
1582
1583
  mcnts['O'][1] += fsize
1583
- msgs.append(self.QMSTATS[3][1])
1584
- missed = True
1585
- if missed:
1586
- mcnts['M'][0] += 1
1587
- mcnts['M'][1] += fsize
1588
- if bkey in ('B', 'D'):
1589
- mcnts['Q'][0] += 1
1590
- mcnts['Q'][1] += fsize
1584
+ self.add_file_count(mbcnts['O'], bkey, fsize)
1585
+ msgs.append(self.QMSTATS[1][1])
1591
1586
  # one line per file: where it is missing and where it is backed up, so a
1592
1587
  # missing file shows whether it can be restored; a present file is listed
1593
1588
  # only when it is not backed up yet
@@ -1598,8 +1593,14 @@ class PgArch(PgOPT, PgCMD, PgSplit):
1598
1593
  if msgs: lines.append("{}: {}".format(finfo, '; '.join(msgs)))
1599
1594
  msg = "{} {} Files: Total {}".format(head, cname, self.file_number_size(total, wn, ws))
1600
1595
  for (k, m) in self.QMSTATS:
1601
- # the total missing is always shown, so a clean check reads 'Missing 0'
1602
- if mcnts[k][0] or k == 'M': msg += ", {} {}".format(m, self.file_number_size(mcnts[k], wn, ws))
1596
+ if not mcnts[k][0]: continue
1597
+ msg += ", {} {}".format(m, self.file_number_size(mcnts[k], wn, ws))
1598
+ if k in mbcnts:
1599
+ # e.g. Missing on Glade 6309(65.73GB) [Quasar Backup 10(1.20GB), Not Backed Up 6299(64.53GB)]
1600
+ subs = [(bk, bm) for (bk, bm) in self.QBSTATS] + [('C', self.QMSTATS[2][1])]
1601
+ parts = ["{} {}".format(bm, self.file_number_size(mbcnts[k][bk], wn, ws))
1602
+ for (bk, bm) in subs if bk in mbcnts[k]]
1603
+ msg += " [{}]".format(', '.join(parts))
1603
1604
  for (k, m) in self.QBSTATS:
1604
1605
  if bcnts[k][0]: msg += ", {} {}".format(m, self.file_number_size(bcnts[k], wn, ws))
1605
1606
  self.OUTPUT.write(msg + "\n")
@@ -1607,10 +1608,17 @@ class PgArch(PgOPT, PgCMD, PgSplit):
1607
1608
  self.OUTPUT.write(line + "\n")
1608
1609
 
1609
1610
  @staticmethod
1610
- def file_number_size(cnts, wn, ws):
1611
- """Format [count, size] as 'count', 'size' or 'count(size)' per -WN/-WS."""
1612
- if wn and ws: return "{}({})".format(cnts[0], cnts[1])
1613
- return str(cnts[1] if ws else cnts[0])
1611
+ def add_file_count(cnts, key, fsize):
1612
+ """Add one file of fsize bytes to the [count, size] of key in dict cnts."""
1613
+ if key not in cnts: cnts[key] = [0, 0]
1614
+ cnts[key][0] += 1
1615
+ cnts[key][1] += fsize
1616
+
1617
+ def file_number_size(self, cnts, wn, ws):
1618
+ """Format [count, size] as 'count', 'size' or 'count(size)' per -WN/-WS, size readable."""
1619
+ size = self.format_float_value(cnts[1])
1620
+ if wn and ws: return "{}({})".format(cnts[0], size)
1621
+ return size if ws else str(cnts[0])
1614
1622
 
1615
1623
  def object_file_exists(self, dsid, fname, bucket):
1616
1624
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rda_python_dsarch
3
- Version: 3.0.13
3
+ Version: 3.0.14
4
4
  Summary: RDA Python package for utility program dsarch archive RDA data
5
5
  Author-email: Zaihua Ji <zji@ucar.edu>
6
6
  Project-URL: Homepage, https://github.com/NCAR/rda-python-dsarch