rda-python-miscs 3.0.8__tar.gz → 3.0.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 (64) hide show
  1. {rda_python_miscs-3.0.8/src/rda_python_miscs.egg-info → rda_python_miscs-3.0.10}/PKG-INFO +2 -2
  2. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/pyproject.toml +2 -2
  3. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/gdexcp.py +78 -8
  4. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/gdexcp.usg +14 -4
  5. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10/src/rda_python_miscs.egg-info}/PKG-INFO +2 -2
  6. rda_python_miscs-3.0.10/src/rda_python_miscs.egg-info/requires.txt +2 -0
  7. rda_python_miscs-3.0.8/src/rda_python_miscs.egg-info/requires.txt +0 -2
  8. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/LICENSE +0 -0
  9. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/MANIFEST.in +0 -0
  10. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/README.md +0 -0
  11. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/setup.cfg +0 -0
  12. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/__init__.py +0 -0
  13. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/bash_qsub.py +0 -0
  14. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/bashqsub.py +0 -0
  15. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/bashqsub.usg +0 -0
  16. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/decsdata_restore.py +0 -0
  17. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/decsdata_restore.usg +0 -0
  18. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/decsdata_storage.py +0 -0
  19. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/decsdata_storage.usg +0 -0
  20. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/gdex_ls.py +0 -0
  21. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/gdexdrop.py +0 -0
  22. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/gdexdrop.usg +0 -0
  23. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/gdexdrop_standalone.py +0 -0
  24. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/gdexkill.py +0 -0
  25. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/gdexkill.usg +0 -0
  26. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/gdexls.py +0 -0
  27. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/gdexls.usg +0 -0
  28. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/gdexls_standalone.py +0 -0
  29. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/gdexmod.py +0 -0
  30. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/gdexmod.usg +0 -0
  31. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/gdexown.py +0 -0
  32. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/gdexown.usg +0 -0
  33. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/gdexps.py +0 -0
  34. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/gdexps.usg +0 -0
  35. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/gdexsub.py +0 -0
  36. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/gdexsub.usg +0 -0
  37. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/gdexzip.py +0 -0
  38. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/gdexzip.usg +0 -0
  39. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/pg_docs.py +0 -0
  40. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/pg_rst.py +0 -0
  41. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/pg_rst.usg +0 -0
  42. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/pg_wget.py +0 -0
  43. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/pgwget.py +0 -0
  44. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/pgwget.usg +0 -0
  45. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/rda_cp.py +0 -0
  46. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/rda_kill.py +0 -0
  47. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/rda_mod.py +0 -0
  48. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/rda_own.py +0 -0
  49. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/rda_ps.py +0 -0
  50. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/rda_sub.py +0 -0
  51. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/rda_zip.py +0 -0
  52. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/rdals.py +0 -0
  53. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/rdals.usg +0 -0
  54. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/rst_templates/appendix.rst.temp +0 -0
  55. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/rst_templates/index.rst.temp +0 -0
  56. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/rst_templates/section.rst.temp +0 -0
  57. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/tcsh_qsub.py +0 -0
  58. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/tcshqsub.py +0 -0
  59. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs/tcshqsub.usg +0 -0
  60. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs.egg-info/SOURCES.txt +0 -0
  61. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs.egg-info/dependency_links.txt +0 -0
  62. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs.egg-info/entry_points.txt +0 -0
  63. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/src/rda_python_miscs.egg-info/top_level.txt +0 -0
  64. {rda_python_miscs-3.0.8 → rda_python_miscs-3.0.10}/tests/test_miscs.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rda_python_miscs
3
- Version: 3.0.8
3
+ Version: 3.0.10
4
4
  Summary: RDA Python package to hold RDA miscellaneous utility programs
5
5
  Author-email: Zaihua Ji <zji@ucar.edu>
6
6
  Project-URL: Homepage, https://github.com/NCAR/rda-python-miscs
@@ -11,7 +11,7 @@ Classifier: Development Status :: 5 - Production/Stable
11
11
  Requires-Python: >=3.7
12
12
  Description-Content-Type: text/markdown
13
13
  License-File: LICENSE
14
- Requires-Dist: rda_python_common
14
+ Requires-Dist: rda_python_common>=3.0.28
15
15
  Requires-Dist: rda_python_setuid
16
16
  Dynamic: license-file
17
17
 
@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
6
6
 
7
7
  [project]
8
8
  name = "rda_python_miscs"
9
- version = "3.0.8"
9
+ version = "3.0.10"
10
10
  authors = [
11
11
  { name="Zaihua Ji", email="zji@ucar.edu" },
12
12
  ]
@@ -20,7 +20,7 @@ classifiers = [
20
20
  "Development Status :: 5 - Production/Stable",
21
21
  ]
22
22
  dependencies = [
23
- "rda_python_common",
23
+ "rda_python_common>=3.0.28",
24
24
  "rda_python_setuid",
25
25
  ]
26
26
 
@@ -135,6 +135,28 @@ class GdexCp(PgFile):
135
135
  self.dssdb_dbname()
136
136
  self.validate_decs_group('gdexcp', self.PGLOG['CURUID'], 1)
137
137
  if not self.RDACP['R'] and self.RDACP['r']: self.RDACP['R'] = 1000
138
+ # a bucket implies the Object Store host, so -tb/-fb need no -th/-fh
139
+ if self.RDACP['fb']:
140
+ self.PGLOG['OBJCTBKT'] = self.RDACP['fb']
141
+ if not self.RDACP['fh']:
142
+ self.RDACP['fh'] = self.OHOST
143
+ self.CINFO['fhost'] = self.OHOST + '-'
144
+ if self.RDACP['tb']:
145
+ if not self.RDACP['fb']: self.PGLOG['OBJCTBKT'] = self.RDACP['tb']
146
+ if not self.RDACP['th']:
147
+ self.RDACP['th'] = self.OHOST
148
+ self.CINFO['thost'] = self.OHOST + '-'
149
+ # a Globus endpoint implies its host, so -tp/-fp need no -th/-fh
150
+ if self.RDACP['fp']:
151
+ self.PGLOG['BACKUPEP'] = self.RDACP['fp']
152
+ if not self.RDACP['fh']:
153
+ self.RDACP['fh'] = self.endpoint_host(self.RDACP['fp'])
154
+ if self.RDACP['fh']: self.CINFO['fhost'] = self.RDACP['fh'] + '-'
155
+ if self.RDACP['tp']:
156
+ if not self.RDACP['fp']: self.PGLOG['BACKUPEP'] = self.RDACP['tp']
157
+ if not self.RDACP['th']:
158
+ self.RDACP['th'] = self.endpoint_host(self.RDACP['tp'])
159
+ if self.RDACP['th']: self.CINFO['thost'] = self.RDACP['th'] + '-'
138
160
  if not self.RDACP['t']:
139
161
  self.CINFO['tpath'] = self.RDACP['t'] = "."
140
162
  else:
@@ -151,14 +173,6 @@ class GdexCp(PgFile):
151
173
  self.pglog("{}{}: Cannot copy multiple files to a single file".format(self.CINFO['thost'], self.RDACP['t']), self.LGEREX)
152
174
  if self.RDACP['th'] and self.RDACP['fh'] and self.RDACP['th'] == self.RDACP['fh'] and self.RDACP['fh'] != 'HPSS':
153
175
  self.pglog(self.RDACP['fh'] + ": Cannot copy file onto the same host", self.LGEREX)
154
- if self.RDACP['fb']:
155
- self.PGLOG['OBJCTBKT'] = self.RDACP['fb']
156
- elif self.RDACP['tb']:
157
- self.PGLOG['OBJCTBKT'] = self.RDACP['tb']
158
- if self.RDACP['fp']:
159
- self.PGLOG['BACKUPEP'] = self.RDACP['fp']
160
- elif self.RDACP['tp']:
161
- self.PGLOG['BACKUPEP'] = self.RDACP['tp']
162
176
  if self.RDACP['o']:
163
177
  if not self.RDACP['fp']:
164
178
  self.pglog("-o: works only when source Globus endpoint -fp is provided", self.LGEREX)
@@ -185,6 +199,27 @@ class GdexCp(PgFile):
185
199
  self.pglog("{}: No File copied{}".format((self.CINFO['fpath'] if self.CINFO['fpath'] else self.CINFO['curdir']), hinfo), self.LOGWRN)
186
200
  self.cmdlog()
187
201
 
202
+ # get the host name a Globus endpoint is reached by
203
+ def endpoint_host(self, endpoint):
204
+ """Return the host name that copy_gdex_file() routes a Globus endpoint through.
205
+
206
+ Known endpoints map through QHOSTS: 'gdex-quasar' to the Quasar backup host,
207
+ 'gdex-quasar-drdata' to the DRDATA host, and 'gdex-glade' to the local host
208
+ (returned as None, the default). Any other endpoint is routed as the Quasar
209
+ backup host with QPOINTS['B'] pointed at it.
210
+
211
+ Args:
212
+ endpoint (str): Globus endpoint name from -fp or -tp.
213
+
214
+ Returns:
215
+ str | None: Host name for -fh/-th, or None for the local host.
216
+ """
217
+ host = self.QHOSTS.get(endpoint)
218
+ if host is None:
219
+ self.QPOINTS['B'] = endpoint
220
+ host = self.BHOST
221
+ return (None if host == self.LHOST else host)
222
+
188
223
  # copy the top level list
189
224
  def copy_top_list(self, files):
190
225
  """Iterate the top-level source paths and initiate copies or recursive traversal.
@@ -219,12 +254,47 @@ class GdexCp(PgFile):
219
254
  self.CINFO['fpath'] = (file if dosub else op.dirname(file)) + "/"
220
255
  if info['isfile']:
221
256
  self.CINFO['tcnt'] += self.dispatch_copy(file, info)
257
+ elif self.RDACP['r'] and self.can_upload_directory():
258
+ self.CINFO['tcnt'] += self.upload_directory(file, dosub)
222
259
  elif dosub or self.RDACP['R']:
223
260
  flist = self.gdex_glob(file, self.RDACP['fh'], 0, self.LGWNEX)
224
261
  if flist: self.copy_list(flist, 1, file)
225
262
  else:
226
263
  self.pglog("{}{}: Add option -r to copy directory".format(self.CINFO['fhost'], file), self.LGEREX)
227
264
 
265
+ # check if a local directory can go to the Object Store in one recursive upload
266
+ def can_upload_directory(self):
267
+ """Return True when a -r directory copy can be one recursive Object Store upload.
268
+
269
+ Needs a local source, an Object Store target and a key prefix from -t; with
270
+ the default target '.' the keys would start with '/', so such a copy goes
271
+ file by file instead.
272
+ """
273
+ if self.RDACP['fh'] or not self.RDACP['th']: return False
274
+ if self.pgcmp(self.strip_host_name(self.RDACP['th']), self.OHOST, 1): return False
275
+ return (self.CINFO['tpath'] != '.')
276
+
277
+ # upload a local directory to the Object Store in one recursive call
278
+ def upload_directory(self, fromdir, dosub):
279
+ """Upload a whole local directory to the Object Store with one isd_s3_cli call.
280
+
281
+ The files keep their layout under the -t key prefix: with the trailing '/'
282
+ form (dosub) they land at '{prefix}/{relative path}', otherwise the directory
283
+ name is kept too, at '{prefix}/{dirname}/{relative path}', the same keys a
284
+ file-by-file copy gives. -m is not used; isd_s3_cli uploads in parallel
285
+ threads of its own.
286
+
287
+ Args:
288
+ fromdir (str): Absolute source directory path.
289
+ dosub (int): 1 to upload the directory contents without the directory name.
290
+
291
+ Returns:
292
+ int: 1 if the directory was uploaded, 0 otherwise.
293
+ """
294
+ todir = self.CINFO['tpath'] if dosub else self.join_paths(self.CINFO['tpath'], op.basename(fromdir))
295
+ logact = self.LGWNEX | (self.OVRIDE if self.RDACP['O'] else 0)
296
+ return (1 if self.local_copy_object_directory(todir, fromdir, None, None, logact) else 0)
297
+
228
298
  # recursively copy directory/file
229
299
  def copy_list(self, tlist, level, cdir):
230
300
  """Recursively copy a directory listing up to the configured depth limit.
@@ -44,15 +44,25 @@
44
44
 
45
45
  -fh FromHostName host name where the source files reside.
46
46
  -th ToHostName host name where the target files are written.
47
- -fb FromBucket Object Store bucket name for the source files.
48
- -tb ToBucket Object Store bucket name for the target files.
49
- -fp FromGlobusEndpoint Globus endpoint for the source files.
50
- -tp ToGlobusEndpoint Globus endpoint for the target files.
47
+ -fb FromBucket Object Store bucket name for the source files; implies
48
+ the Object Store as the source host (no -fh needed).
49
+ -tb ToBucket Object Store bucket name for the target files; implies
50
+ the Object Store as the target host (no -th needed).
51
+ -fp FromGlobusEndpoint Globus endpoint for the source files; implies the
52
+ endpoint's host as the source (no -fh needed).
53
+ -tp ToGlobusEndpoint Globus endpoint for the target files; implies the
54
+ endpoint's host as the target (no -th needed).
51
55
 
52
56
 
53
57
  COPY BEHAVIOR
54
58
 
55
59
  -r Copy directories and files recursively, with no depth limit.
60
+ A local directory copied to an Object Store bucket (-tb) with -r and a
61
+ -t key prefix is uploaded in a single isd_s3_cli call, which uploads
62
+ in parallel threads of its own (-m is not used for it). Its files
63
+ keep their layout under the prefix. The directory is skipped when
64
+ all its files are already in the bucket at the same size; otherwise
65
+ the whole directory is uploaded again.
56
66
 
57
67
  -R RecursiveLevel
58
68
  Copy recursively up to the given depth. -R 1 copies only the
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rda_python_miscs
3
- Version: 3.0.8
3
+ Version: 3.0.10
4
4
  Summary: RDA Python package to hold RDA miscellaneous utility programs
5
5
  Author-email: Zaihua Ji <zji@ucar.edu>
6
6
  Project-URL: Homepage, https://github.com/NCAR/rda-python-miscs
@@ -11,7 +11,7 @@ Classifier: Development Status :: 5 - Production/Stable
11
11
  Requires-Python: >=3.7
12
12
  Description-Content-Type: text/markdown
13
13
  License-File: LICENSE
14
- Requires-Dist: rda_python_common
14
+ Requires-Dist: rda_python_common>=3.0.28
15
15
  Requires-Dist: rda_python_setuid
16
16
  Dynamic: license-file
17
17
 
@@ -0,0 +1,2 @@
1
+ rda_python_common>=3.0.28
2
+ rda_python_setuid
@@ -1,2 +0,0 @@
1
- rda_python_common
2
- rda_python_setuid