patme 0.4.4__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.

Potentially problematic release.


This version of patme might be problematic. Click here for more details.

Files changed (46) hide show
  1. patme/__init__.py +52 -0
  2. patme/buildtools/__init__.py +7 -0
  3. patme/buildtools/rce_releasecreator.py +336 -0
  4. patme/buildtools/release.py +26 -0
  5. patme/femtools/__init__.py +5 -0
  6. patme/femtools/abqmsgfilechecker.py +137 -0
  7. patme/femtools/fecall.py +1092 -0
  8. patme/geometry/__init__.py +0 -0
  9. patme/geometry/area.py +124 -0
  10. patme/geometry/coordinatesystem.py +635 -0
  11. patme/geometry/intersect.py +284 -0
  12. patme/geometry/line.py +183 -0
  13. patme/geometry/misc.py +420 -0
  14. patme/geometry/plane.py +464 -0
  15. patme/geometry/rotate.py +244 -0
  16. patme/geometry/scale.py +152 -0
  17. patme/geometry/shape2d.py +50 -0
  18. patme/geometry/transformations.py +1831 -0
  19. patme/geometry/translate.py +139 -0
  20. patme/mechanics/__init__.py +4 -0
  21. patme/mechanics/loads.py +435 -0
  22. patme/mechanics/material.py +1260 -0
  23. patme/service/__init__.py +7 -0
  24. patme/service/decorators.py +85 -0
  25. patme/service/duration.py +96 -0
  26. patme/service/exceptionhook.py +104 -0
  27. patme/service/exceptions.py +36 -0
  28. patme/service/io/__init__.py +3 -0
  29. patme/service/io/basewriter.py +122 -0
  30. patme/service/logger.py +375 -0
  31. patme/service/mathutils.py +108 -0
  32. patme/service/misc.py +71 -0
  33. patme/service/moveimports.py +217 -0
  34. patme/service/stringutils.py +419 -0
  35. patme/service/systemutils.py +290 -0
  36. patme/sshtools/__init__.py +3 -0
  37. patme/sshtools/cara.py +435 -0
  38. patme/sshtools/clustercaller.py +420 -0
  39. patme/sshtools/facluster.py +350 -0
  40. patme/sshtools/sshcall.py +168 -0
  41. patme-0.4.4.dist-info/LICENSE +21 -0
  42. patme-0.4.4.dist-info/LICENSES/MIT.txt +9 -0
  43. patme-0.4.4.dist-info/METADATA +168 -0
  44. patme-0.4.4.dist-info/RECORD +46 -0
  45. patme-0.4.4.dist-info/WHEEL +4 -0
  46. patme-0.4.4.dist-info/entry_points.txt +3 -0
@@ -0,0 +1,290 @@
1
+ # Copyright (C) 2013 Deutsches Zentrum fuer Luft- und Raumfahrt(DLR, German Aerospace Center) <www.dlr.de>
2
+ # SPDX-FileCopyrightText: 2022 German Aerospace Center (DLR)
3
+ #
4
+ # SPDX-License-Identifier: MIT
5
+
6
+ """
7
+ Utilities on system level.
8
+ """
9
+ import os
10
+ import re
11
+ import shutil
12
+ import subprocess
13
+ import tarfile
14
+ import time
15
+ import zipfile
16
+ from contextlib import contextmanager
17
+ from datetime import datetime
18
+
19
+ from patme.service.logger import log, resetLoggerToNewRunDir
20
+
21
+
22
+ def dos2unix(filename):
23
+ """doc"""
24
+ with open(filename, "rb") as f:
25
+ stream = f.read()
26
+
27
+ stream = stream.decode().replace("\r\n", "\n")
28
+ with open(filename, "wb") as f:
29
+ f.write(stream.encode())
30
+
31
+
32
+ def searchForWordsWithinFile(filename=None, words=None):
33
+ """doc"""
34
+ if not filename:
35
+ filename = ""
36
+
37
+ if isinstance(words, list):
38
+ words = re.compile("(%s)" % "|".join(words), re.RegexFlag.MULTILINE)
39
+
40
+ if os.path.exists(filename):
41
+ with open(filename, "rb") as f:
42
+ wordMatches = words.finditer(f.read().decode(errors="replace"))
43
+ if wordMatches:
44
+ return [match.group() for match in wordMatches]
45
+ return None
46
+ else:
47
+ log.error('Filename "%s" not found.' % filename)
48
+ return None
49
+
50
+
51
+ def checkForLibraryInPaths(library, pathsToCheck):
52
+ """Checks if library is found in any of the path set in global PATH variable.
53
+ If the library is found the base directory is returned"""
54
+ for path in pathsToCheck:
55
+ if os.path.isdir(path) and os.path.exists(path) and library in os.listdir(path):
56
+ return path
57
+
58
+ return None
59
+
60
+
61
+ @contextmanager
62
+ def changeDirTemporary(newDir):
63
+ """Method to change the directory temporarily to do some things and change back to the original directory
64
+ after some things are done.
65
+ Example:
66
+
67
+ >>> import os
68
+ >>> currentDir = os.getcwd()
69
+ >>> with changeDirTemporary(os.path.join(currentDir, '..')): changedDir = os.getcwd()
70
+ >>> currentDirNew = os.getcwd()
71
+ >>> currentDir == currentDirNew
72
+ True
73
+ >>> currentDir != changedDir
74
+ True
75
+ >>> #print(currentDir,changedDir,currentDirNew)
76
+ >>> with changeDirTemporary(None): changedDir = os.getcwd()
77
+ >>> currentDirNew = os.getcwd()
78
+ >>> currentDir == currentDirNew
79
+ True
80
+ >>> currentDir == changedDir
81
+ True
82
+ >>> #print(currentDir,changedDir,currentDirNew)
83
+
84
+ """
85
+ if newDir is None:
86
+ yield
87
+ return
88
+ tmpDir = os.getcwd()
89
+ os.chdir(newDir)
90
+ yield
91
+ os.chdir(tmpDir)
92
+
93
+
94
+ def getTimeString(useMilliSeconds=False):
95
+ """returns a time string of the format: yyyymmdd_hhmmss"""
96
+ dt = datetime.now()
97
+ return dt.strftime("%Y%m%d_%H%M%S") + (f"_{dt.microsecond}" if useMilliSeconds else "")
98
+
99
+
100
+ def makeAllDirs(directory):
101
+ absPath = os.path.abspath(directory)
102
+ for i in range(0, absPath.count(os.sep))[::-1]:
103
+ # Split path into subpaths beginning from the top of the drive
104
+ subPath = absPath.rsplit(os.sep, i)[0]
105
+ if not os.path.exists(subPath):
106
+ os.makedirs(subPath)
107
+
108
+
109
+ def getRunDir(baseName="tmp", runDirExtension="", moveLogFilesToRunDir=True, basePath=".", useMilliSeconds=False):
110
+ """Creates a folder that will be used as directory for the actual run.
111
+
112
+ The created folder has this name::
113
+
114
+ basePath/<baseName>_<timestamp><runDirExtension>
115
+
116
+ :param runDirExtension: optional string appended to the folder name. Defaults to ''
117
+ :param moveLogFilesToRunDir: Flag if the log files should be put in this directory.
118
+ :param basePath: working directory where folder shall be created.
119
+ :param useMilliSeconds: include milliseconds to the run dir name or not
120
+ :returns: absolute path to the new folder
121
+
122
+ Example::
123
+
124
+ >> getRunDir('foo', '_bar', False, False, 'foobar')
125
+ foobar/foo_20170206_152323_bar
126
+
127
+ """
128
+ while True:
129
+ runDir = os.path.join(basePath, baseName + "_" + getTimeString(useMilliSeconds)) + runDirExtension
130
+ if os.path.exists(runDir):
131
+ log.warning("runDir already exists. Wait 1s and retry with new timestring.")
132
+ time.sleep(1)
133
+ else:
134
+ makeAllDirs(runDir)
135
+ break
136
+
137
+ if moveLogFilesToRunDir:
138
+ resetLoggerToNewRunDir(runDir)
139
+
140
+ return runDir
141
+
142
+
143
+ def getGitInformation(wcDirectory=None):
144
+ """Return information of the state of this git repository if it is present.
145
+
146
+ :param wcDirectory: main directory of the git clone
147
+ :return: tuple (description of the actual version and commit, has local modifications)
148
+ describe is either something like "0.2.0" if the tag-commit is active or
149
+ "0.1.1-31-g23a6851" describing
150
+ 0.1.1: last tag name
151
+ 31: number of commits since this tag
152
+ 23a6851: actual commit
153
+ """
154
+ gitBin = shutil.which("git")
155
+ if gitBin is None:
156
+ return ("No git binary found", "No git binary found")
157
+
158
+ with changeDirTemporary(wcDirectory):
159
+ p = subprocess.run(
160
+ [gitBin, "describe", "--tags"], stdout=subprocess.PIPE, stderr=subprocess.PIPE
161
+ ) # use text=True for python >= 3.7
162
+
163
+ describe = p.stderr if p.stdout == b"" else p.stdout
164
+ describe = describe.decode("utf-8").strip()
165
+
166
+ p = subprocess.run(
167
+ [gitBin, "status"], stdout=subprocess.PIPE, stderr=subprocess.PIPE
168
+ ) # use text=True for python >= 3.7
169
+
170
+ status = p.stderr if p.stdout == b"" else p.stdout
171
+ status = status.decode("utf-8").strip()
172
+
173
+ if "not a git repository" in describe:
174
+ return ("not a git repository", "not a git repository")
175
+ hasLocalModifications = "Changes to be committed" in status or "Changes not staged for commit" in status
176
+ return describe, hasLocalModifications
177
+
178
+
179
+ def getFormattedTimeStampForFile(ffile):
180
+ return int(datetime.fromtimestamp(os.path.getmtime(ffile)).strftime("%Y%m%d%H%M"))
181
+
182
+
183
+ def compressFilesInDir(
184
+ direc, regEx, zipFilename=None, thresholdMB=0, olderThan=0, removeOrigFiles=False, autoCRCCheck=True
185
+ ):
186
+ """Compresses files in a given directory with a given minimal file size and a modification time.
187
+
188
+ The resulting file archive is a general zip file.
189
+
190
+ :param direc: Directory where several files should be compressed
191
+ :param regEx: Regular expression which the filenames should match to compress
192
+ :param zipFilename: Filename of the Zip-file to store files. If it is None, all matching files in a directory.
193
+ will be compressed as seperate files with the original filename and the new .zip ending
194
+ :param thresholdMB: Minimum file size in megabytes for compression to exclude very small files.
195
+ :param olderThan: Timestamp (Format '%Y%m%d%H%M') to exclude files from compression which are generated in the shorter past.
196
+ Timestamp can be helpful to avoid compressing files which may be needed again in a long term process.
197
+ :param removeOrigFiles: Flag if original files should be deleted if they were compressed successfully
198
+ :param autoCRCCheck: Flag if created zip files should be checked by CRC algorithm
199
+
200
+ """
201
+
202
+ direc = os.path.abspath(direc)
203
+ p = re.compile(regEx)
204
+ thresholdBytes = int(thresholdMB * 1024**2)
205
+
206
+ for root, __, files in os.walk(direc, topdown=True):
207
+ compressDict = {}
208
+ for name in files:
209
+ filenameWithRoot = os.path.join(root, name)
210
+ getLastModifiedTime = getFormattedTimeStampForFile(filenameWithRoot)
211
+
212
+ if int(olderThan) > 0 and getLastModifiedTime > int(olderThan):
213
+ continue
214
+
215
+ if p.match(name) and os.stat(filenameWithRoot).st_size > thresholdBytes:
216
+ if not zipFilename:
217
+ newZiPFile = os.path.join(root, name + ".zip")
218
+ else:
219
+ newZiPFile = os.path.join(root, zipFilename)
220
+
221
+ with zipfile.ZipFile(newZiPFile, "a", zipfile.ZIP_DEFLATED, allowZip64=True) as myzip:
222
+ myzip.write(filenameWithRoot, name)
223
+
224
+ if compressDict.get(newZiPFile, None):
225
+ compressDict[newZiPFile].append(filenameWithRoot)
226
+ else:
227
+ compressDict[newZiPFile] = [filenameWithRoot]
228
+
229
+ if autoCRCCheck:
230
+ for zFile, cFiles in list(compressDict.items()):
231
+ with zipfile.ZipFile(zFile, "r", allowZip64=True) as myzip:
232
+ if myzip.testzip():
233
+ print("Something went wrong with zip file creation: ", zFile)
234
+ raise
235
+ elif removeOrigFiles:
236
+ for ffile in cFiles:
237
+ os.remove(ffile)
238
+
239
+
240
+ def tarGzDirectory(directory, tarFileName):
241
+ """put a directory in a targz"""
242
+ if not os.path.isabs(tarFileName):
243
+ tarFileName = os.path.join(directory, tarFileName)
244
+ directory = os.path.abspath(directory)
245
+ if os.path.exists(tarFileName):
246
+ os.remove(tarFileName)
247
+
248
+ with tarfile.open(tarFileName, "x:gz") as tarFileDescriptor:
249
+ for fileOrDir in os.listdir(directory):
250
+ tarFileDescriptor.add(os.path.join(directory, fileOrDir), arcname=fileOrDir)
251
+
252
+ return tarFileName
253
+
254
+
255
+ def zipDirectory(directory, zipFileName):
256
+ """Puts all files in the given directory to a zip file in the same dir
257
+
258
+ Attention: Extracting of empty (sub)directories does not work with python's zipfile module
259
+
260
+ :param directory: directory that will be zipped
261
+ :param zipFileName: name of the zip file that is created. If it as an abs path, then it is
262
+ used directly. If it has a relative path, it is used relative to directory.
263
+ """
264
+ if not os.path.isabs(zipFileName):
265
+ zipFileName = os.path.join(directory, zipFileName)
266
+ directory = os.path.abspath(directory)
267
+ if os.path.exists(zipFileName):
268
+ os.remove(zipFileName)
269
+ with zipfile.ZipFile(zipFileName, "x") as zipFileDescriptor:
270
+ for root, dirs, files in os.walk(directory):
271
+ for file in files:
272
+ if file != os.path.basename(zipFileName):
273
+ fullFileName = os.path.join(root, file)
274
+ fileInZipName = os.path.join(os.path.relpath(root, directory), file)
275
+ zipFileDescriptor.write(fullFileName, fileInZipName)
276
+ for directory in dirs: # add folder in order to also have empty folders added
277
+ with changeDirTemporary(root):
278
+ zif = zipfile.ZipInfo(os.path.join(directory))
279
+ zif.external_attr = 16
280
+ zipFileDescriptor.writestr(zif, "")
281
+
282
+
283
+ if __name__ == "__main__":
284
+ pass
285
+ # print(getRunDir('foo', '_bar', False, False, 'foobar'))
286
+ # directory = 'D:\\freu_se\\DELiS\\tmp\\delis_20170206_143544_functionCreator\\abq_abq'
287
+ # tarFileName = 'a.tar.gz'
288
+ # if os.path.exists(os.path.join(directory, tarFileName)):
289
+ # os.remove(os.path.join(directory, tarFileName))
290
+ # tarGzDirectory(directory, tarFileName)
@@ -0,0 +1,3 @@
1
+ # SPDX-FileCopyrightText: 2022 German Aerospace Center (DLR)
2
+ #
3
+ # SPDX-License-Identifier: MIT