opex-manifest-generator 1.2.2__py3-none-any.whl → 1.2.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.
- opex_manifest_generator/__init__.py +15 -15
- opex_manifest_generator/cli.py +194 -182
- opex_manifest_generator/common.py +79 -64
- opex_manifest_generator/hash.py +64 -33
- opex_manifest_generator/metadata/EAD Template.xml +101 -101
- opex_manifest_generator/metadata/GDPR Template.xml +8 -8
- opex_manifest_generator/metadata/MODS Template.xml +66 -66
- opex_manifest_generator/opex_manifest.py +116 -66
- opex_manifest_generator/options.properties +12 -12
- opex_manifest_generator-1.2.4.dist-info/METADATA +527 -0
- opex_manifest_generator-1.2.4.dist-info/RECORD +16 -0
- {opex_manifest_generator-1.2.2.dist-info → opex_manifest_generator-1.2.4.dist-info}/WHEEL +1 -1
- {opex_manifest_generator-1.2.2.dist-info → opex_manifest_generator-1.2.4.dist-info/licenses}/LICENSE.md +201 -201
- opex_manifest_generator/samples/Opex.xml +0 -11
- opex_manifest_generator/samples/opex_manifest_generator_AutoClass.xlsx +0 -0
- opex_manifest_generator/samples/spreads/dctemplate.xlsx +0 -0
- opex_manifest_generator/samples/spreads/eadtemplate.xlsx +0 -0
- opex_manifest_generator/samples/spreads/gdprtemplate.xlsx +0 -0
- opex_manifest_generator/samples/spreads/modstemplate.xlsx +0 -0
- opex_manifest_generator-1.2.2.dist-info/METADATA +0 -400
- opex_manifest_generator-1.2.2.dist-info/RECORD +0 -22
- {opex_manifest_generator-1.2.2.dist-info → opex_manifest_generator-1.2.4.dist-info}/entry_points.txt +0 -0
- {opex_manifest_generator-1.2.2.dist-info → opex_manifest_generator-1.2.4.dist-info}/top_level.txt +0 -0
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
"""
|
|
2
|
-
opex_manifest_generator package definitions
|
|
3
|
-
|
|
4
|
-
Author: Christopher Prince
|
|
5
|
-
license: Apache License 2.0"
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
from .opex_manifest import OpexManifestGenerator,OpexDir,OpexFile
|
|
9
|
-
from .hash import HashGenerator
|
|
10
|
-
from .common import *
|
|
11
|
-
from .cli import parse_args,run_cli
|
|
12
|
-
import importlib.metadata
|
|
13
|
-
|
|
14
|
-
__author__ = "Christopher Prince (c.pj.prince@gmail.com)"
|
|
15
|
-
__license__ = "Apache License Version 2.0"
|
|
1
|
+
"""
|
|
2
|
+
opex_manifest_generator package definitions
|
|
3
|
+
|
|
4
|
+
Author: Christopher Prince
|
|
5
|
+
license: Apache License 2.0"
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .opex_manifest import OpexManifestGenerator,OpexDir,OpexFile
|
|
9
|
+
from .hash import HashGenerator
|
|
10
|
+
from .common import *
|
|
11
|
+
from .cli import parse_args,run_cli
|
|
12
|
+
import importlib.metadata
|
|
13
|
+
|
|
14
|
+
__author__ = "Christopher Prince (c.pj.prince@gmail.com)"
|
|
15
|
+
__license__ = "Apache License Version 2.0"
|
|
16
16
|
__version__ = importlib.metadata.version("opex_manifest_generator")
|
opex_manifest_generator/cli.py
CHANGED
|
@@ -1,183 +1,195 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Cli interaction.
|
|
3
|
-
|
|
4
|
-
author: Christopher Prince
|
|
5
|
-
license: Apache License 2.0"
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
import argparse, os, inspect, time
|
|
9
|
-
from opex_manifest_generator.opex_manifest import OpexManifestGenerator
|
|
10
|
-
import importlib.metadata
|
|
11
|
-
|
|
12
|
-
def parse_args():
|
|
13
|
-
parser = argparse.ArgumentParser(description = "OPEX Manifest Generator for Preservica Uploads")
|
|
14
|
-
parser.add_argument('root', default = os.getcwd(), help = "The root path to generate Opexes for")
|
|
15
|
-
parser.add_argument("-c", "--autoclass", required = False,
|
|
16
|
-
choices = ['catalog', 'c', 'accession', 'a', 'both', 'b', 'generic', 'g', 'catalog-generic', 'cg', "accession-generic", "ag", "both-generic", "bg"],
|
|
17
|
-
type = str.lower,
|
|
18
|
-
help="""Toggles whether to utilise the auto_classification_generator
|
|
19
|
-
to generate an on the fly Reference listing.
|
|
20
|
-
|
|
21
|
-
There are several options, {catalog} will generate
|
|
22
|
-
a Archival Reference following an ISAD(G) sturcutre.
|
|
23
|
-
{accession} will create a running number of files.
|
|
24
|
-
{both} will do both at the same time!
|
|
25
|
-
{generic} will populate the title and description fields with the folder/file's name,
|
|
26
|
-
if used in conjunction with one of the above options:
|
|
27
|
-
{generic-catalog,generic-accession, generic-both} it will do both simultaneously.
|
|
28
|
-
""")
|
|
29
|
-
parser.add_argument("-p", "--prefix", required = False, nargs = '+',
|
|
30
|
-
help= """Assign a prefix when utilising the --autoclass option. Prefix will append any text before all generated text.
|
|
31
|
-
When utilising the {both} option fill in like: [catalog-prefix, accession-prefix] without square brackets.
|
|
32
|
-
""")
|
|
33
|
-
parser.add_argument("-fx", "--fixity", required = False,
|
|
34
|
-
|
|
35
|
-
help="Generates a hash for each file and adds it to the opex, can select
|
|
36
|
-
parser.add_argument("
|
|
37
|
-
help
|
|
38
|
-
parser.add_argument("-
|
|
39
|
-
help = "
|
|
40
|
-
parser.add_argument("
|
|
41
|
-
help = "
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
parser.add_argument("-
|
|
49
|
-
help="
|
|
50
|
-
parser.add_argument("-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
help="Set whether to
|
|
58
|
-
parser.add_argument("-
|
|
59
|
-
help="Set to
|
|
60
|
-
parser.add_argument("-
|
|
61
|
-
help="Set
|
|
62
|
-
parser.add_argument("-
|
|
63
|
-
help="Set to
|
|
64
|
-
parser.add_argument("-
|
|
65
|
-
help="Set
|
|
66
|
-
parser.add_argument("-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
parser.add_argument("--
|
|
73
|
-
help="
|
|
74
|
-
parser.add_argument("-
|
|
75
|
-
|
|
76
|
-
parser.add_argument("--keywords
|
|
77
|
-
parser.add_argument("--keywords-
|
|
78
|
-
parser.add_argument("--
|
|
79
|
-
parser.add_argument("-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
print(f'
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
if args.
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
for a in args.prefix:
|
|
121
|
-
|
|
122
|
-
print('Prefix is set as: ' +
|
|
123
|
-
elif args.autoclass in {"generic", "
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
if args.
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
1
|
+
"""
|
|
2
|
+
Cli interaction.
|
|
3
|
+
|
|
4
|
+
author: Christopher Prince
|
|
5
|
+
license: Apache License 2.0"
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import argparse, os, inspect, time
|
|
9
|
+
from opex_manifest_generator.opex_manifest import OpexManifestGenerator
|
|
10
|
+
import importlib.metadata
|
|
11
|
+
|
|
12
|
+
def parse_args():
|
|
13
|
+
parser = argparse.ArgumentParser(description = "OPEX Manifest Generator for Preservica Uploads")
|
|
14
|
+
parser.add_argument('root', default = os.getcwd(), help = "The root path to generate Opexes for")
|
|
15
|
+
parser.add_argument("-c", "--autoclass", required = False,
|
|
16
|
+
choices = ['catalog', 'c', 'accession', 'a', 'both', 'b', 'generic', 'g', 'catalog-generic', 'cg', "accession-generic", "ag", "both-generic", "bg"],
|
|
17
|
+
type = str.lower,
|
|
18
|
+
help="""Toggles whether to utilise the auto_classification_generator
|
|
19
|
+
to generate an on the fly Reference listing.
|
|
20
|
+
|
|
21
|
+
There are several options, {catalog} will generate
|
|
22
|
+
a Archival Reference following an ISAD(G) sturcutre.
|
|
23
|
+
{accession} will create a running number of files.
|
|
24
|
+
{both} will do both at the same time!
|
|
25
|
+
{generic} will populate the title and description fields with the folder/file's name,
|
|
26
|
+
if used in conjunction with one of the above options:
|
|
27
|
+
{generic-catalog,generic-accession, generic-both} it will do both simultaneously.
|
|
28
|
+
""")
|
|
29
|
+
parser.add_argument("-p", "--prefix", required = False, nargs = '+',
|
|
30
|
+
help= """Assign a prefix when utilising the --autoclass option. Prefix will append any text before all generated text.
|
|
31
|
+
When utilising the {both} option fill in like: [catalog-prefix, accession-prefix] without square brackets.
|
|
32
|
+
""")
|
|
33
|
+
parser.add_argument("-fx", "--fixity", required = False, nargs = '*', default = None,
|
|
34
|
+
choices = ['NONE', 'SHA-1', 'MD5', 'SHA-256', 'SHA-512'], type = str.upper, action=EmptyIsTrueFixity,
|
|
35
|
+
help="Generates a hash for each file and adds it to the opex, can select one or more algorithms to utilise. -fx SHA-1 MD5")
|
|
36
|
+
parser.add_argument("--pax-fixity", required = False, action = 'store_true', default = False,
|
|
37
|
+
help="Enables use of PAX fixity generation, in line with Preservica's Recommendation. Files / folders ending in .pax or .pax.zip will have individual files in folder / zip added to Opex.")
|
|
38
|
+
parser.add_argument("-rme", "--remove-empty", required = False, action = 'store_true', default = False,
|
|
39
|
+
help = "Remove and log empty directories from root. Log will be exported to 'meta' / output folder.")
|
|
40
|
+
parser.add_argument("-o", "--output", required = False, nargs = 1,
|
|
41
|
+
help = "Sets the output to send any generated files to. Will not affect creation of a meta dir.")
|
|
42
|
+
parser.add_argument("--disable-meta-dir", required = False, action = 'store_false',
|
|
43
|
+
help = """Set whether to disable the creation of a 'meta' directory for generated files,
|
|
44
|
+
default behaviour is to always generate this directory""")
|
|
45
|
+
parser.add_argument("-clr", "--clear-opex", required = False, action = 'store_true', default = False,
|
|
46
|
+
help = """Clears existing opex files from a directory. If set with no further options will only clear opexes;
|
|
47
|
+
if multiple options are set will clear opexes and then run the program""")
|
|
48
|
+
parser.add_argument("-opt","--options-file", required = False, default=os.path.join(os.path.dirname(__file__),'options.properties'),
|
|
49
|
+
help="Specify a custom Options file, changing the set presets for column headers (Title,Description,etc)")
|
|
50
|
+
parser.add_argument("-s", "--start-ref", required = False, nargs = '?', default = 1,
|
|
51
|
+
help="Set a custom Starting reference for the Auto Classification generator. The generated reference will")
|
|
52
|
+
parser.add_argument("-mdir","--metadata-dir", required=False, nargs= '?',
|
|
53
|
+
default = os.path.join(os.path.dirname(os.path.realpath(__file__)), "metadata"),
|
|
54
|
+
help="Specify the metadata directory to pull XML files from")
|
|
55
|
+
parser.add_argument("-m", "--metadata", required = False, const = 'e', default = 'none',
|
|
56
|
+
nargs = '?', choices = ['none', 'n', 'exact', 'e', 'flat', 'f'], type = str.lower,
|
|
57
|
+
help="Set whether to include xml metadata fields in the generation of the Opex")
|
|
58
|
+
parser.add_argument("-ex", "--export", required = False, action = 'store_true', default = False,
|
|
59
|
+
help="Set whether to export the generated auto classification references to an AutoClass spreadsheet")
|
|
60
|
+
parser.add_argument("-i", "--input", required = False, nargs='?',
|
|
61
|
+
help="Set to utilise a CSV / XLSX spreadsheet to import data from")
|
|
62
|
+
parser.add_argument("-rm", "--remove", required = False, action = "store_true", default = False,
|
|
63
|
+
help="Set whether to enable removals of files and folders from a directory. ***Currently in testing")
|
|
64
|
+
parser.add_argument("-z", "--zip", required = False, action = 'store_true',
|
|
65
|
+
help="Set to zip files")
|
|
66
|
+
parser.add_argument("-fmt", "--output-format", required = False, default = "xlsx", choices = ['xlsx', 'csv'],
|
|
67
|
+
help="Set whether to output to an xlsx or csv format")
|
|
68
|
+
parser.add_argument("-v", "--version", action = 'version', version = '%(prog)s {version}'.format(version = importlib.metadata.version("opex_manifest_generator")))
|
|
69
|
+
parser.add_argument("--accession-mode", nargs = '?', required=False, const='file', default=None, choices=["file",'directory','both'],
|
|
70
|
+
help="""Set the mode when utilising the Accession option in autoclass.
|
|
71
|
+
file - only adds on files, folder - only adds on folders, both - adds on files and folders""")
|
|
72
|
+
parser.add_argument("--hidden", required = False, action = 'store_true', default = False,
|
|
73
|
+
help="Set whether to include hidden files and folders")
|
|
74
|
+
parser.add_argument("--print-xmls", required = False, action = "store_true", default = False,
|
|
75
|
+
help="Prints the elements from your xmls to the consoles")
|
|
76
|
+
parser.add_argument("-key","--keywords", nargs = '*', default = None)
|
|
77
|
+
parser.add_argument("-keym","--keywords-mode", nargs = '?', const = "intialise", default = "intialise", choices = ['intialise','firstletters'])
|
|
78
|
+
parser.add_argument("--keywords-retain-order", required = False, default = False, action = 'store_true')
|
|
79
|
+
parser.add_argument("--keywords-abbreviation-number", required = False, nargs='?', default = -3, type = int)
|
|
80
|
+
parser.add_argument("--sort-by", required=False, nargs = '?', default = 'foldersfirst', choices = ['foldersfirst','alphabetical'], type=str.lower)
|
|
81
|
+
parser.add_argument("-dlm", "--delimiter", required=False,nargs = '?', type = str)
|
|
82
|
+
args = parser.parse_args()
|
|
83
|
+
return args
|
|
84
|
+
|
|
85
|
+
def run_cli():
|
|
86
|
+
args = parse_args()
|
|
87
|
+
print(f"Running Opex Generation on: {args.root}")
|
|
88
|
+
if not args.output:
|
|
89
|
+
args.output = os.path.abspath(args.root)
|
|
90
|
+
print(f'Output path defaulting to root directory: {args.output}')
|
|
91
|
+
else:
|
|
92
|
+
args.output = os.path.abspath(args.output[0])
|
|
93
|
+
print(f'Output path set to: {args.output}')
|
|
94
|
+
if args.input and args.autoclass:
|
|
95
|
+
print(f'Both Input and Auto-Class options have been selected, please use only one...')
|
|
96
|
+
time.sleep(5); raise SystemExit()
|
|
97
|
+
if args.remove and not args.input:
|
|
98
|
+
print('Removal flag has been given without input, please ensure an input file is utilised when using this option.')
|
|
99
|
+
time.sleep(5); raise SystemExit()
|
|
100
|
+
if not args.metadata in {'none', 'n'} and not args.input:
|
|
101
|
+
print(f'Warning: Metadata Flag has been given without Input. Metadata won\'t be generated.')
|
|
102
|
+
time.sleep(5)
|
|
103
|
+
if args.print_xmls:
|
|
104
|
+
OpexManifestGenerator(root = args.root, metadata_dir=args.metadata_dir).print_descriptive_xmls()
|
|
105
|
+
acc_prefix = None
|
|
106
|
+
if args.autoclass in {"accession", "a", "accession-generic", "ag", "both", "b", "both-generic", "bg"} and args.accession_mode is None:
|
|
107
|
+
args.accession_mode = "file"
|
|
108
|
+
if args.prefix:
|
|
109
|
+
if args.autoclass in {"both", "b", "both-generic", "bg"}:
|
|
110
|
+
if len(args.prefix) < 2 or len(args.prefix) > 2:
|
|
111
|
+
print('"Both" option is selected, please pass only two prefixes: [-p CATALOG_PREFIX ACCESSION_PREFIX]');
|
|
112
|
+
time.sleep(3); raise SystemExit
|
|
113
|
+
for n, a in enumerate(args.prefix):
|
|
114
|
+
if n == 0:
|
|
115
|
+
args.prefix = str(a)
|
|
116
|
+
elif n == 1:
|
|
117
|
+
acc_prefix = str(a)
|
|
118
|
+
print(f"Prefixes are set as: \t Catalog: {args.prefix} \t Acc: {acc_prefix}")
|
|
119
|
+
elif args.autoclass in {"accession", "a", "accession-generic", "ag"}:
|
|
120
|
+
for a in args.prefix:
|
|
121
|
+
acc_prefix = str(a)
|
|
122
|
+
print('Prefix is set as: ' + acc_prefix)
|
|
123
|
+
elif args.autoclass in {"catalog", "c", "catalog-generic", "cg"}:
|
|
124
|
+
acc_prefix = None
|
|
125
|
+
for a in args.prefix:
|
|
126
|
+
args.prefix = str(a)
|
|
127
|
+
print('Prefix is set as: ' + args.prefix)
|
|
128
|
+
elif args.autoclass in {"generic", "g"}:
|
|
129
|
+
pass
|
|
130
|
+
else:
|
|
131
|
+
print('''An invalid option has been selected, please select a valid option:
|
|
132
|
+
{c, catalog
|
|
133
|
+
a, accession
|
|
134
|
+
b, both
|
|
135
|
+
g, generic
|
|
136
|
+
cg, catalog-generic
|
|
137
|
+
ag, accesion-generic
|
|
138
|
+
bg, both-generic}''')
|
|
139
|
+
time.sleep(3)
|
|
140
|
+
raise SystemExit
|
|
141
|
+
if args.fixity:
|
|
142
|
+
print(f'Fixity is activated, using {args.fixity} algorithm')
|
|
143
|
+
if args.sort_by:
|
|
144
|
+
if args.sort_by == "foldersfirst":
|
|
145
|
+
sort_key = lambda x: (os.path.isfile(x), str.casefold(x))
|
|
146
|
+
elif args.sort_by == "alphabetical":
|
|
147
|
+
sort_key = str.casefold
|
|
148
|
+
if args.remove:
|
|
149
|
+
print(inspect.cleandoc("""****
|
|
150
|
+
You have enabled the remove functionality of the program. This action will remove all files and folders listed for removal and any sub-files/sub-folders.
|
|
151
|
+
|
|
152
|
+
This process will permanently delete the selected items, with no way recover the items.
|
|
153
|
+
|
|
154
|
+
****"""))
|
|
155
|
+
time.sleep(2)
|
|
156
|
+
i = input(inspect.cleandoc("Please type Y if you wish to proceed, otherwise the program will close: "))
|
|
157
|
+
if not i.lower() == "y":
|
|
158
|
+
print("Closing program..."); time.sleep(3); raise SystemExit()
|
|
159
|
+
time.sleep(3)
|
|
160
|
+
OpexManifestGenerator(root = args.root,
|
|
161
|
+
output_path = args.output,
|
|
162
|
+
autoclass_flag = args.autoclass,
|
|
163
|
+
prefix = args.prefix,
|
|
164
|
+
accession_mode=args.accession_mode,
|
|
165
|
+
acc_prefix = acc_prefix,
|
|
166
|
+
empty_flag = args.remove_empty,
|
|
167
|
+
removal_flag = args.remove,
|
|
168
|
+
clear_opex_flag = args.clear_opex,
|
|
169
|
+
algorithm = args.fixity,
|
|
170
|
+
pax_fixity= args.pax_fixity,
|
|
171
|
+
startref = args.start_ref,
|
|
172
|
+
export_flag = args.export,
|
|
173
|
+
meta_dir_flag = args.disable_meta_dir,
|
|
174
|
+
metadata_flag = args.metadata,
|
|
175
|
+
metadata_dir = args.metadata_dir,
|
|
176
|
+
hidden_flag= args.hidden,
|
|
177
|
+
zip_flag = args.zip,
|
|
178
|
+
input = args.input,
|
|
179
|
+
output_format = args.output_format,
|
|
180
|
+
options_file=args.options_file,
|
|
181
|
+
keywords = args.keywords,
|
|
182
|
+
keywords_mode = args.keywords_mode,
|
|
183
|
+
keywords_retain_order = args.keywords_retain_order,
|
|
184
|
+
sort_key = sort_key,
|
|
185
|
+
delimiter = args.delimiter,
|
|
186
|
+
keywords_abbreviation_number = args.keywords_abbreviation_number).main()
|
|
187
|
+
|
|
188
|
+
class EmptyIsTrueFixity(argparse.Action):
|
|
189
|
+
def __call__(self, parser, namespace, values, option_string=None):
|
|
190
|
+
if len(values) == 0:
|
|
191
|
+
values = ["SHA-1"]
|
|
192
|
+
setattr(namespace, self.dest, values)
|
|
193
|
+
|
|
194
|
+
if __name__ == "__main__":
|
|
183
195
|
run_cli()
|
|
@@ -1,64 +1,79 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Common tools for use throghout program.
|
|
3
|
-
|
|
4
|
-
author: Christopher Prince
|
|
5
|
-
license: Apache License 2.0"
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
import zipfile, os, sys, time, stat
|
|
9
|
-
import
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
z.write(
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
def
|
|
42
|
-
if
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
1
|
+
"""
|
|
2
|
+
Common tools for use throghout program.
|
|
3
|
+
|
|
4
|
+
author: Christopher Prince
|
|
5
|
+
license: Apache License 2.0"
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import zipfile, os, sys, time, stat, datetime, shutil
|
|
9
|
+
from lxml import etree
|
|
10
|
+
|
|
11
|
+
def zip_opex(file_path,opex_path):
|
|
12
|
+
zip_file = f"{file_path}.zip"
|
|
13
|
+
if not os.path.exists(zip_file):
|
|
14
|
+
with zipfile.ZipFile(zip_file,'w') as z:
|
|
15
|
+
z.write(file_path,os.path.basename(file_path))
|
|
16
|
+
z.write(opex_path,os.path.basename(opex_path))
|
|
17
|
+
else: print(f'A zip file already exists for: {zip_file}')
|
|
18
|
+
|
|
19
|
+
def remove_tree(path: str, removed_list: list):
|
|
20
|
+
removed_list.append(path)
|
|
21
|
+
print(f"Removing: {path}")
|
|
22
|
+
if os.path.isdir(path):
|
|
23
|
+
for dp,d,f in os.walk(path):
|
|
24
|
+
for fn in f:
|
|
25
|
+
removed_list.append(win_256_check(dp+win_path_delimiter()+fn))
|
|
26
|
+
for dn in d:
|
|
27
|
+
removed_list.append(win_256_check(dp+win_path_delimiter()+dn))
|
|
28
|
+
shutil.rmtree(path)
|
|
29
|
+
else:
|
|
30
|
+
if os.path.exists(path):
|
|
31
|
+
os.remove(path)
|
|
32
|
+
|
|
33
|
+
def win_256_check(path):
|
|
34
|
+
if len(path) > 255 and sys.platform == "win32":
|
|
35
|
+
if path.startswith(u"\\\\?\\"):
|
|
36
|
+
path = path
|
|
37
|
+
else:
|
|
38
|
+
path = u"\\\\?\\" + path
|
|
39
|
+
return path
|
|
40
|
+
|
|
41
|
+
def filter_win_hidden(path: str):
|
|
42
|
+
if sys.platform =="win32":
|
|
43
|
+
if bool(os.stat(path).st_file_attributes & stat.FILE_ATTRIBUTE_HIDDEN) is True:
|
|
44
|
+
return True
|
|
45
|
+
else:
|
|
46
|
+
return False
|
|
47
|
+
else:
|
|
48
|
+
return False
|
|
49
|
+
|
|
50
|
+
def win_path_delimiter():
|
|
51
|
+
if sys.platform == "win32":
|
|
52
|
+
return "\\"
|
|
53
|
+
else:
|
|
54
|
+
return "/"
|
|
55
|
+
|
|
56
|
+
def check_nan(value):
|
|
57
|
+
if str(value).lower() in {"nan","nat"}:
|
|
58
|
+
value = None
|
|
59
|
+
return value
|
|
60
|
+
|
|
61
|
+
def check_opex(opex_path:str):
|
|
62
|
+
opex_path = opex_path + ".opex"
|
|
63
|
+
if os.path.exists(win_256_check(opex_path)):
|
|
64
|
+
return False
|
|
65
|
+
else:
|
|
66
|
+
return True
|
|
67
|
+
|
|
68
|
+
def write_opex(path: str, opexxml: etree.Element):
|
|
69
|
+
opex_path = win_256_check(str(path) + ".opex")
|
|
70
|
+
opex = etree.indent(opexxml, " ")
|
|
71
|
+
opex = etree.tostring(opexxml, pretty_print=True, xml_declaration=True, encoding="UTF-8", standalone=True)
|
|
72
|
+
with open(f'{opex_path}', 'w', encoding="UTF-8") as writer:
|
|
73
|
+
writer.write(opex.decode('UTF-8'))
|
|
74
|
+
print('Saved Opex File to: ' + opex_path)
|
|
75
|
+
return opex_path
|
|
76
|
+
|
|
77
|
+
def print_running_time(start_time):
|
|
78
|
+
print(f'Running time: {datetime.datetime.now() - start_time}')
|
|
79
|
+
time.sleep(5)
|