Compare commits
14 Commits
e64e1a038f
...
main
Author | SHA1 | Date | |
---|---|---|---|
2edd8a2093 | |||
7a400457fe | |||
59cfe486aa | |||
266a611fea | |||
cb36b8adb3 | |||
ded60aa742 | |||
adf734f3c1 | |||
c579c172ef | |||
e5bab5b12d | |||
73ae49cb89 | |||
958e2b12e3 | |||
425ef96e9b | |||
95b60c87a5 | |||
ea374a971e |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -212,3 +212,4 @@ pyrightconfig.json
|
||||
|
||||
# Custom rules (everything added below won't be overriden by 'Generate .gitignore File' if you use 'Update' option)
|
||||
|
||||
output.csv
|
||||
|
5
.vscode/launch.json
vendored
5
.vscode/launch.json
vendored
@@ -8,19 +8,20 @@
|
||||
"name": "Use Test Resources",
|
||||
"type": "python",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/csvbyname/csvbyname.py",
|
||||
"console": "integratedTerminal",
|
||||
"args": [
|
||||
"${workspaceFolder}/tests/resources",
|
||||
"${workspaceFolder}/output.csv",
|
||||
"-r",
|
||||
"-n",
|
||||
"-p",
|
||||
"group_num:group(\\d)-\\w-\\d+\\.txt",
|
||||
"group(\\d)-(?P<sect>\\w)-(?P<patid>\\d+)\\.txt",
|
||||
"-V",
|
||||
"DEBUG"
|
||||
],
|
||||
"justMyCode": true
|
||||
"justMyCode": true,
|
||||
"module": "csvbyname.cli"
|
||||
}
|
||||
]
|
||||
}
|
10
Jenkinsfile
vendored
10
Jenkinsfile
vendored
@@ -20,11 +20,17 @@ pipeline {
|
||||
stage("test") {
|
||||
steps {
|
||||
sh "pip install dist/*.whl"
|
||||
sh "csvbyname -h"
|
||||
}
|
||||
}
|
||||
stage("publish") {
|
||||
stage("archive") {
|
||||
steps {
|
||||
archiveArtifacts artifacts: 'dist/*.tar.gz, dist/*.whl'
|
||||
}
|
||||
}
|
||||
stage("publish package") {
|
||||
when {
|
||||
branch '**/master'
|
||||
branch '**/main'
|
||||
}
|
||||
steps {
|
||||
withCredentials([usernamePassword(credentialsId: 'rs-git-package-registry-ydeng', passwordVariable: 'PASS', usernameVariable: 'USER')]) {
|
||||
|
95
csvbyname/cli.py
Normal file
95
csvbyname/cli.py
Normal file
@@ -0,0 +1,95 @@
|
||||
import argparse
|
||||
import logging
|
||||
|
||||
from csvbyname.generate import collect_files, write_collected_to_csv
|
||||
|
||||
|
||||
def run(args):
|
||||
logger.info('Collecting files from "%s"', args.directory)
|
||||
collected, pkeys = collect_files(
|
||||
args.directory,
|
||||
args.include_folders,
|
||||
args.entire_path,
|
||||
args.recursive,
|
||||
args.add_re_property,
|
||||
)
|
||||
write_collected_to_csv(args.output, collected, pkeys, args.output_basename)
|
||||
|
||||
|
||||
def main():
|
||||
argparser = argparse.ArgumentParser(
|
||||
"csvbyname",
|
||||
description="Catalogue a directory of files by patterns in their names into a "
|
||||
"CSV.",
|
||||
)
|
||||
argparser.add_argument(
|
||||
"directory",
|
||||
type=str,
|
||||
help="The directory containing the files to obtain catalogue names of",
|
||||
metavar="i",
|
||||
)
|
||||
argparser.add_argument(
|
||||
"output", type=str, help="The path to the catalogued CSVs.", metavar="o"
|
||||
)
|
||||
argparser.add_argument(
|
||||
"-l",
|
||||
"--include-folders",
|
||||
help="Include folders in the cataloguing process",
|
||||
action="store_true",
|
||||
required=False,
|
||||
default=False,
|
||||
)
|
||||
argparser.add_argument(
|
||||
"-e",
|
||||
"--entire-path",
|
||||
help="Include the full path when applying the groupings to find properties",
|
||||
action="store_true",
|
||||
required=False,
|
||||
default=False,
|
||||
)
|
||||
argparser.add_argument(
|
||||
"-r",
|
||||
"--recursive",
|
||||
help="Catalogue recursively",
|
||||
action="store_true",
|
||||
required=False,
|
||||
default=False,
|
||||
)
|
||||
argparser.add_argument(
|
||||
"-p",
|
||||
"--add-re-property",
|
||||
help="Add a property in the resulting CSV obtained from the first capture "
|
||||
"group of the given REGEX in the following format:\n property-name:regex.\n"
|
||||
"Alternatively, use named REGEX groups.",
|
||||
nargs="+",
|
||||
type=str,
|
||||
required=True
|
||||
)
|
||||
argparser.add_argument(
|
||||
"-n",
|
||||
"--output-basename",
|
||||
help='Adds a column called "basename" to the resulting CSV where it is just '
|
||||
"The base name of the path instead of the entire path. This is not guaranteed "
|
||||
"to be unique.",
|
||||
default=False,
|
||||
required=False,
|
||||
action="store_true",
|
||||
)
|
||||
argparser.add_argument(
|
||||
"-V",
|
||||
"--verbosity",
|
||||
help="Set the verbosity of the logging",
|
||||
type=str,
|
||||
required=False,
|
||||
default="INFO",
|
||||
)
|
||||
|
||||
args = argparser.parse_args()
|
||||
logging.basicConfig(level=args.verbosity.upper())
|
||||
global logger
|
||||
logger = logging.getLogger(__name__)
|
||||
run(args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@@ -1,11 +1,12 @@
|
||||
import argparse
|
||||
import csv
|
||||
import os
|
||||
import re
|
||||
from typing import Iterable
|
||||
import exceptions
|
||||
from csvbyname import exceptions
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def matcher(full_path: str, use_full_path: bool, regex_groups: list[str]):
|
||||
captured_properties = {}
|
||||
@@ -71,100 +72,24 @@ def collect_files(
|
||||
|
||||
|
||||
def write_collected_to_csv(
|
||||
output_path: str, collected: dict[str, dict[str, str]], property_keys: Iterable[str]
|
||||
output_path: str,
|
||||
collected: dict[str, dict[str, str]],
|
||||
property_keys: Iterable[str],
|
||||
output_basename: bool,
|
||||
):
|
||||
with open(output_path, "w") as output_fd:
|
||||
with open(output_path, "w", newline="", encoding="utf-8") as output_fd:
|
||||
s_property_keys = sorted(property_keys)
|
||||
header = ["path", *s_property_keys]
|
||||
header = ["path"]
|
||||
if output_basename:
|
||||
header.append("basename")
|
||||
header.extend(s_property_keys)
|
||||
writer = csv.writer(output_fd)
|
||||
writer.writerow(header)
|
||||
for full_path, properties in collected.items():
|
||||
writer.writerow(
|
||||
[
|
||||
full_path,
|
||||
*(
|
||||
properties[k] if k in properties else "N/A"
|
||||
for k in s_property_keys
|
||||
),
|
||||
]
|
||||
row = [full_path]
|
||||
if output_basename:
|
||||
row.append(os.path.basename(full_path))
|
||||
row.extend(
|
||||
(properties[k] if k in properties else "N/A" for k in s_property_keys)
|
||||
)
|
||||
|
||||
|
||||
def run(args):
|
||||
logger.info('Collecting files from "%s"', args.directory)
|
||||
collected, pkeys = collect_files(
|
||||
args.directory,
|
||||
args.include_folders,
|
||||
args.entire_path,
|
||||
args.recursive,
|
||||
args.add_re_property,
|
||||
)
|
||||
write_collected_to_csv(args.output, collected, pkeys)
|
||||
|
||||
|
||||
def main():
|
||||
argparser = argparse.ArgumentParser(
|
||||
"csvbyname",
|
||||
description="Catalogue a directory of files by patterns in their names into a "
|
||||
"CSV.",
|
||||
)
|
||||
argparser.add_argument(
|
||||
"directory",
|
||||
type=str,
|
||||
help="The directory containing the files to obtain catalogue names of",
|
||||
metavar="i",
|
||||
)
|
||||
argparser.add_argument(
|
||||
"output", type=str, help="The path to the catalogued CSVs.", metavar="o"
|
||||
)
|
||||
argparser.add_argument(
|
||||
"-l",
|
||||
"--include-folders",
|
||||
help="Include folders in the cataloguing process",
|
||||
action="store_true",
|
||||
required=False,
|
||||
default=False,
|
||||
)
|
||||
argparser.add_argument(
|
||||
"-e",
|
||||
"--entire-path",
|
||||
help="Include the full path when applying the groupings to find properties",
|
||||
action="store_true",
|
||||
required=False,
|
||||
default=False,
|
||||
)
|
||||
argparser.add_argument(
|
||||
"-r",
|
||||
"--recursive",
|
||||
help="Catalogue recursively",
|
||||
action="store_true",
|
||||
required=False,
|
||||
default=False,
|
||||
)
|
||||
argparser.add_argument(
|
||||
"-p",
|
||||
"--add-re-property",
|
||||
help="Add a property in the resulting CSV obtained from the first capture "
|
||||
"group of the given REGEX in the following format:\n property-name:regex.\n"
|
||||
"Alternatively, use named REGEX groups.",
|
||||
nargs="+",
|
||||
type=str,
|
||||
)
|
||||
argparser.add_argument(
|
||||
"-V",
|
||||
"--verbosity",
|
||||
help="Set the verbosity of the logging",
|
||||
type=str,
|
||||
required=False,
|
||||
default="INFO",
|
||||
)
|
||||
|
||||
args = argparser.parse_args()
|
||||
logging.basicConfig(level=args.verbosity.upper())
|
||||
global logger
|
||||
logger = logging.getLogger(__name__)
|
||||
run(args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
writer.writerow(row)
|
@@ -5,4 +5,4 @@ dependencies:
|
||||
- build=0.7.0
|
||||
- pytest=7.2.2
|
||||
- twine=4.0.2
|
||||
- python=3.9
|
||||
- python=3.11
|
||||
|
Reference in New Issue
Block a user