rda-python-common 3.0.26__py3-none-any.whl → 3.0.28__py3-none-any.whl
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.
- rda_python_common/__init__.py +1 -1
- rda_python_common/pg_dbi.py +1 -0
- rda_python_common/pg_file.py +86 -0
- {rda_python_common-3.0.26.dist-info → rda_python_common-3.0.28.dist-info}/METADATA +2 -2
- {rda_python_common-3.0.26.dist-info → rda_python_common-3.0.28.dist-info}/RECORD +9 -9
- {rda_python_common-3.0.26.dist-info → rda_python_common-3.0.28.dist-info}/WHEEL +1 -1
- {rda_python_common-3.0.26.dist-info → rda_python_common-3.0.28.dist-info}/entry_points.txt +0 -0
- {rda_python_common-3.0.26.dist-info → rda_python_common-3.0.28.dist-info}/licenses/LICENSE +0 -0
- {rda_python_common-3.0.26.dist-info → rda_python_common-3.0.28.dist-info}/top_level.txt +0 -0
rda_python_common/__init__.py
CHANGED
rda_python_common/pg_dbi.py
CHANGED
|
@@ -2176,6 +2176,7 @@ class PgDBI(PgLOG):
|
|
|
2176
2176
|
|
|
2177
2177
|
pgrec = self.pgget("dsowner, dssgrp", "specialist, lstname, fstname",
|
|
2178
2178
|
"specialist = logname AND dsid = '{}' AND priority = 1".format(dsid), logact)
|
|
2179
|
+
if pgrec == self.FAILURE: return None # query error; do not cache the fallback
|
|
2179
2180
|
if pgrec:
|
|
2180
2181
|
if pgrec['specialist'] == "datahelp" or pgrec['specialist'] == "dss":
|
|
2181
2182
|
pgrec['lstname'] = "Help"
|
rda_python_common/pg_file.py
CHANGED
|
@@ -410,6 +410,92 @@ class PgFile(PgUtil, PgSIG):
|
|
|
410
410
|
self.errlog("Error Execute: {}\n{}".format(cmd, buf), 'O', loop, logact)
|
|
411
411
|
return self.FAILURE
|
|
412
412
|
|
|
413
|
+
# Upload a local directory to object under a key prefix
|
|
414
|
+
# todir - target object key prefix, without the trailing '/'
|
|
415
|
+
# fromdir - source local directory name
|
|
416
|
+
def local_copy_object_directory(self, todir, fromdir, bucket = None, meta = None, logact = 0):
|
|
417
|
+
"""Upload every file under a local directory to an object key prefix.
|
|
418
|
+
|
|
419
|
+
The whole directory goes up in one recursive call, the upload twin of
|
|
420
|
+
object_copy_local_directory(): one process per file costs several seconds
|
|
421
|
+
of start-up each, which dominates for a directory of many files. Each file
|
|
422
|
+
lands at '{todir}/{path relative to fromdir}'.
|
|
423
|
+
|
|
424
|
+
Nothing is uploaded when every file is already under the prefix at its local
|
|
425
|
+
size (unless OVRIDE is set); otherwise the whole directory is uploaded again,
|
|
426
|
+
since the recursive call cannot be limited to the missing files.
|
|
427
|
+
|
|
428
|
+
Args:
|
|
429
|
+
todir (str): Object key prefix (destination path in the bucket); not empty.
|
|
430
|
+
fromdir (str): Source local directory path.
|
|
431
|
+
bucket (str | None): Target bucket; defaults to PGLOG['OBJCTBKT'].
|
|
432
|
+
meta (dict | None): Extra metadata key/value pairs to attach to each object.
|
|
433
|
+
logact (int): Logging action flags; default 0.
|
|
434
|
+
|
|
435
|
+
Returns:
|
|
436
|
+
int: self.SUCCESS on success, self.FAILURE on error.
|
|
437
|
+
"""
|
|
438
|
+
if not bucket: bucket = self.PGLOG['OBJCTBKT']
|
|
439
|
+
if meta is None: meta = {}
|
|
440
|
+
if 'user' not in meta: meta['user'] = self.PGLOG['CURUID']
|
|
441
|
+
if 'group' not in meta: meta['group'] = self.PGLOG['GDEXGRP']
|
|
442
|
+
uinfo = json.dumps(meta)
|
|
443
|
+
ms = re.match(r'^(.+)/$', fromdir)
|
|
444
|
+
if ms: fromdir = ms.group(1)
|
|
445
|
+
ms = re.match(r'^(.+)/$', todir)
|
|
446
|
+
if ms: todir = ms.group(1)
|
|
447
|
+
# the same walk isd_s3_cli makes to pick the files: no symlinked directories
|
|
448
|
+
lfiles = {}
|
|
449
|
+
for path, dirs, files in os.walk(fromdir):
|
|
450
|
+
for fname in files:
|
|
451
|
+
lfile = op.join(path, fname)
|
|
452
|
+
lfiles[op.relpath(lfile, fromdir)] = op.getsize(lfile)
|
|
453
|
+
if not lfiles:
|
|
454
|
+
return self.lmsg(fromdir, "{} to copy to {}-{}".format(self.PGLOG['MISSFILE'], self.OHOST, todir), logact)
|
|
455
|
+
prefix = todir + '/'
|
|
456
|
+
if not logact&self.OVRIDE:
|
|
457
|
+
flist = self.object_glob(todir, bucket, 0, logact)
|
|
458
|
+
if flist == self.FAILURE: return self.FAILURE
|
|
459
|
+
miss = self.object_upload_missing(prefix, lfiles, flist)
|
|
460
|
+
if not miss:
|
|
461
|
+
self.pglog("{}-{}-{}: all {} file(s) exist already, skip uploading".format(
|
|
462
|
+
self.OHOST, bucket, todir, len(lfiles)), logact&~self.EXITLG)
|
|
463
|
+
return self.SUCCESS
|
|
464
|
+
# -db too: an upload goes to the default bucket whatever -b says
|
|
465
|
+
cmd = "{} -db {} um -ld {} -b {} -kp {} -r -md '{}'".format(
|
|
466
|
+
self.OBJCTCMD, bucket, fromdir, bucket, todir, uinfo)
|
|
467
|
+
buf = self.pgsystem(cmd, logact, self.CMDBTH)
|
|
468
|
+
flist = self.object_glob(todir, bucket, 0, logact)
|
|
469
|
+
if flist == self.FAILURE: return self.FAILURE
|
|
470
|
+
miss = self.object_upload_missing(prefix, lfiles, flist)
|
|
471
|
+
if miss:
|
|
472
|
+
return self.errlog("{}-{}: Error upload {} of {} file(s) to {}-{}\n{}".format(
|
|
473
|
+
fromdir, miss[0], len(miss), len(lfiles), self.OHOST, todir, buf), 'O', 1, logact)
|
|
474
|
+
self.pglog("{}: {} file(s) uploaded to {}-{}-{}".format(
|
|
475
|
+
fromdir, len(lfiles), self.OHOST, bucket, todir), logact&~self.EXITLG)
|
|
476
|
+
return self.SUCCESS
|
|
477
|
+
|
|
478
|
+
# List the local files not uploaded under an object key prefix yet
|
|
479
|
+
# prefix - target object key prefix, including the trailing '/'
|
|
480
|
+
# lfiles - local file sizes, keyed by path relative to the source directory
|
|
481
|
+
# flist - object_glob() info, keyed by object key
|
|
482
|
+
def object_upload_missing(self, prefix, lfiles, flist):
|
|
483
|
+
"""Return the local files that have no object of the same size under a key prefix.
|
|
484
|
+
|
|
485
|
+
Args:
|
|
486
|
+
prefix (str): Object key prefix including the trailing '/'.
|
|
487
|
+
lfiles (dict): Mapping of relative path → local file size.
|
|
488
|
+
flist (dict): Mapping of key → object info from object_glob().
|
|
489
|
+
|
|
490
|
+
Returns:
|
|
491
|
+
list: The relative paths still to upload.
|
|
492
|
+
"""
|
|
493
|
+
miss = []
|
|
494
|
+
for name in lfiles:
|
|
495
|
+
oinfo = flist.get(prefix + name)
|
|
496
|
+
if not (oinfo and oinfo['data_size'] == lfiles[name]): miss.append(name)
|
|
497
|
+
return miss
|
|
498
|
+
|
|
413
499
|
# Copy multiple files from a Globus endpoint to another
|
|
414
500
|
# tofiles - target file name list, echo name leading with /dsnnn.n/ on Quasar and
|
|
415
501
|
# leading with /data/ or /decsdata/ on local glade disk
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rda_python_common
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.28
|
|
4
4
|
Summary: RDA Python common library codes shared by other RDA python packages
|
|
5
5
|
Author-email: Zaihua Ji <zji@ucar.edu>
|
|
6
6
|
Project-URL: Homepage, https://github.com/NCAR/rda-python-common
|
|
@@ -189,7 +189,7 @@ PgLOG.pglog("hello", PgLOG.LOGWRN)
|
|
|
189
189
|
python -c "import rda_python_common; print(rda_python_common.__version__)"
|
|
190
190
|
```
|
|
191
191
|
|
|
192
|
-
You should see the installed version (currently `3.0.
|
|
192
|
+
You should see the installed version (currently `3.0.28`). If the import
|
|
193
193
|
fails, double-check that the active Python environment is the one where you
|
|
194
194
|
ran `pip install`.
|
|
195
195
|
|
|
@@ -7,10 +7,10 @@ rda_python_common/PgOPT.py,sha256=0nQPF19N-1VWwrjFHEeruVSwVDwvFKd4uowPc8dK7e4,56
|
|
|
7
7
|
rda_python_common/PgSIG.py,sha256=0MJPH0fTtSshIsvUXkzQjReHPyCWdzHYOY5LbFSh7-A,34318
|
|
8
8
|
rda_python_common/PgSplit.py,sha256=En7xcdkE4YNRcMX88qXnrUgUOnQU3Kqh8uxRIdlJhEA,9156
|
|
9
9
|
rda_python_common/PgUtil.py,sha256=7hXAznAI8tYh-nJRKBIXejNe2ROQ2Wxn28OAndeg0Iw,48433
|
|
10
|
-
rda_python_common/__init__.py,sha256=
|
|
10
|
+
rda_python_common/__init__.py,sha256=nuSiih-pLPf8s7ct003v0QDJJM3813MwbRld2QrOn80,995
|
|
11
11
|
rda_python_common/pg_cmd.py,sha256=MYldUuM8mSUIT34yKQyUd0i4NL4zdSB8C6Jcc28NRxA,33809
|
|
12
|
-
rda_python_common/pg_dbi.py,sha256=
|
|
13
|
-
rda_python_common/pg_file.py,sha256=
|
|
12
|
+
rda_python_common/pg_dbi.py,sha256=ASIW2vsIjMab2TMfhqJiXS7LQhKKGpKjzNMqo7RCePw,122415
|
|
13
|
+
rda_python_common/pg_file.py,sha256=7NipcgMy4t67zbH2MHtRL3vxyY1FHdIgMTQ-kE0H2fA,181122
|
|
14
14
|
rda_python_common/pg_lock.py,sha256=31EaVDjCkcx3-n8-KnzG18R8Pz7Z6KyFsEqcml6Iq5c,32702
|
|
15
15
|
rda_python_common/pg_log.py,sha256=erQN4YYPwiORa3OE0Jt8s05rlWsjtyIs0fJ_KLbNAQ8,82959
|
|
16
16
|
rda_python_common/pg_opt.py,sha256=LxVAf47wi2STkVGSXMvV3IZphEJcoO8bvYXy6kQ5ox4,82403
|
|
@@ -20,9 +20,9 @@ rda_python_common/pg_split.py,sha256=aAWKUZPmZ-LQ_fJ3DSKzPKxJw0fMDJ2fgP8ZT629M30
|
|
|
20
20
|
rda_python_common/pg_util.py,sha256=JL9NoW-VoQvsjXsUr09oBUWYJJNltU4GyQIfWlpkf90,86084
|
|
21
21
|
rda_python_common/pgpassword.py,sha256=aTQaO59QokWrv2EKom4TvKhNW2Mr6aFMMBVG4DCbcKI,5023
|
|
22
22
|
rda_python_common/pgpassword.usg,sha256=Wrle6A8sdlMGx3ZEAmE6TNDPOlG84Whe0T3rCNFzPfY,2013
|
|
23
|
-
rda_python_common-3.0.
|
|
24
|
-
rda_python_common-3.0.
|
|
25
|
-
rda_python_common-3.0.
|
|
26
|
-
rda_python_common-3.0.
|
|
27
|
-
rda_python_common-3.0.
|
|
28
|
-
rda_python_common-3.0.
|
|
23
|
+
rda_python_common-3.0.28.dist-info/licenses/LICENSE,sha256=1dck4EAQwv8QweDWCXDx-4Or0S8YwiCstaso_H57Pno,1097
|
|
24
|
+
rda_python_common-3.0.28.dist-info/METADATA,sha256=YFxuS4nRBjgJ0euFjSKU-GNswRGmFLgj7txr1zOeQUY,14530
|
|
25
|
+
rda_python_common-3.0.28.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
|
|
26
|
+
rda_python_common-3.0.28.dist-info/entry_points.txt,sha256=pZgVNWspcK-F1TbPav7C3C9NdeHDZMm_25fW9weix00,65
|
|
27
|
+
rda_python_common-3.0.28.dist-info/top_level.txt,sha256=KVQmx7D3DD-jsiheqL8HdTrRE14hpRnZY5_ioMArA5k,18
|
|
28
|
+
rda_python_common-3.0.28.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|