_cli.py 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. # yamify - define family trees in YAML
  2. #
  3. # Copyright (C) 2020 Fabian Peter Hammerle <fabian@hammerle.me>
  4. #
  5. # This program is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation, either version 3 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. import argparse
  18. import pathlib
  19. import sys
  20. import typing
  21. import yaml
  22. import yamily
  23. import yamily._graphviz
  24. import yamily.yaml
  25. def _read(path: pathlib.Path) -> typing.Iterator[yamily.Person]:
  26. if path.is_dir():
  27. for file_path in path.glob("**/*.yml"):
  28. for person in _read(file_path):
  29. yield person
  30. else:
  31. with path.open("r") as yaml_file:
  32. yield yaml.load(yaml_file, Loader=yamily.yaml.Loader)
  33. def _list() -> None:
  34. argparser = argparse.ArgumentParser(
  35. description="Recursively find yamily family tree members and print as YAML list."
  36. )
  37. argparser.add_argument(
  38. "paths", nargs="+", metavar="path", help="path to yamily .yml file or folder"
  39. )
  40. args = argparser.parse_args()
  41. collection = yamily.PersonCollection()
  42. for path in args.paths:
  43. for person in _read(pathlib.Path(path)):
  44. collection.add_person(person)
  45. yaml.dump(
  46. sorted(collection, key=lambda p: p.identifier),
  47. sys.stdout,
  48. Dumper=yamily.yaml.Dumper,
  49. default_flow_style=False,
  50. allow_unicode=True,
  51. )
  52. def _dot() -> None:
  53. argparser = argparse.ArgumentParser(
  54. description="Create family tree in DOT (graphviz) format. "
  55. "Recursively looks for *.yml files containing family members in yamily format."
  56. )
  57. argparser.add_argument(
  58. "paths", nargs="+", metavar="path", help="path to yamily .yml file or folder"
  59. )
  60. argparser.add_argument("--comment", dest="comment_text")
  61. args = argparser.parse_args()
  62. collection = yamily.PersonCollection()
  63. for path in args.paths:
  64. for person in _read(pathlib.Path(path)):
  65. collection.add_person(person)
  66. graph = yamily._graphviz.digraph(collection) # pylint: disable=protected-access
  67. if args.comment_text is not None:
  68. with graph.subgraph(name="cluster_comment") as comment:
  69. comment.attr(style="invisible")
  70. comment.node("comment", label=args.comment_text, shape="none")
  71. print(graph.source)