3 Commits 234416f1ba ... 170187d87f

Author SHA1 Message Date
  Fabian Peter Hammerle 170187d87f release v0.2.0 4 years ago
  Fabian Peter Hammerle 9b749b0f98 cli yamily-dot: added --comment arg 4 years ago
  Fabian Peter Hammerle 56ea025359 added Person.death_date 4 years ago
9 changed files with 94 additions and 19 deletions
  1. 5 0
      CHANGELOG.md
  2. 5 4
      README.md
  3. 19 0
      tests/_graphviz_test.py
  4. 19 0
      tests/cli/_dot_test.py
  5. 2 0
      tests/person_collection_test.py
  6. 28 13
      yamily/__init__.py
  7. 5 0
      yamily/_cli.py
  8. 2 0
      yamily/_graphviz.py
  9. 9 2
      yamily/yaml.py

+ 5 - 0
CHANGELOG.md

@@ -6,4 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ## Unreleased
 
+## 0.2.0 - 2020-01-04
+### Added
+- api/yaml: `Person.death_date`
+- cli: `yamily-dot --comment 'some comment'`
+
 ## 0.1.0 - 2020-01-02

+ 5 - 4
README.md

@@ -35,20 +35,21 @@ $ pip3 install --upgrade yamily[yaml,graphviz]
 ... !person
 ... identifier: alice
 ... name: Alice Test
-... birth_date: 2019-12-23
+... birth_date: 1919-12-23
 ... mother: !person
 ...   identifier: alice-mother
 ...   name: Carol Test
-...   birth_date: 1992-10-26
+...   birth_date: 1892-10-26
+...   death_date: 1983-11-02
 ... father: !person
 ...   identifier: bob
 ...   name: Bob Test
 ... '''
 >>> alice = yaml.load(alice_yaml, Loader=yamily.yaml.Loader)
 >>> alice
-Person(alice, Alice Test, *2019-12-23)
+Person(alice, Alice Test, *1919-12-23)
 >>> alice.mother
-Person(alice-mother, Carol Test, *1992-10-26)
+Person(alice-mother, Carol Test, *1892-10-26, †1983-11-02)
 
 ```
 

+ 19 - 0
tests/_graphviz_test.py

@@ -15,10 +15,29 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
+import datetime
+
 from yamily import Person, PersonCollection
 from yamily._graphviz import digraph
 
 
+def test_digraph_person_details():
+    collection = PersonCollection()
+    person = Person("bob")
+    person.name = "Bob Test"
+    person.birth_date = datetime.date(1923, 4, 5)
+    person.death_date = datetime.date(2012, 3, 4)
+    collection.add_person(person)
+    graph = digraph(collection)
+    expected_graph = r"""digraph yamily {
+	subgraph cluster_bob {
+		rank=same style=invisible
+		bob [label="Bob Test\n*1923-04-05\n†2012-03-04" shape=box]
+	}
+}"""
+    assert graph.source == expected_graph
+
+
 def test_digraph_single_family():
     collection = PersonCollection()
     child = Person("child")

+ 19 - 0
tests/cli/_dot_test.py

@@ -27,3 +27,22 @@ def test__dot_recurse_dir(capsys):
     out, err = capsys.readouterr()
     assert not err
     assert out == pathlib.Path("persons").joinpath("digraph.dot").read_text()
+
+
+@patch("sys.argv", ["", "--comment", "some text", "persons/erika-mustermann.yml"])
+def test__dot_comment(capsys):
+    _dot()
+    out, err = capsys.readouterr()
+    assert not err
+    expected_out = r"""digraph yamily {
+	subgraph "cluster_erika-mustermann" {
+		rank=same style=invisible
+		"erika-mustermann" [label="Erika Mustermann\n*1957-08-12" shape=box]
+	}
+	subgraph cluster_comment {
+		style=invisible
+		comment [label="some text" shape=none]
+	}
+}
+"""
+    assert out == expected_out

+ 2 - 0
tests/person_collection_test.py

@@ -27,10 +27,12 @@ def test_add_person_again():
     collection.add_person(alice1)
     alice2 = Person("alice")
     alice2.birth_date = datetime.date(2019, 12, 23)
+    alice2.death_date = datetime.date(1919, 12, 23)
     collection.add_person(alice2)
     assert len(list(collection)) == 1
     assert collection["alice"].name == "Alice"
     assert collection["alice"].birth_date == datetime.date(2019, 12, 23)
+    assert collection["alice"].death_date == datetime.date(1919, 12, 23)
 
 
 def test_add_person_unknown_parents():

+ 28 - 13
yamily/__init__.py

@@ -25,11 +25,12 @@ class Person:
     """
     >>> alice = Person('alice')
     >>> alice.name = 'Alice Test'
-    >>> alice.birth_date = datetime.date(2019, 12, 23)
+    >>> alice.birth_date = datetime.date(1919, 12, 23)
+    >>> alice.death_date = datetime.date(2019, 11, 1)
     >>> alice
-    Person(alice, Alice Test, *2019-12-23)
+    Person(alice, Alice Test, *1919-12-23, †2019-11-01)
     >>> str(alice)
-    'Alice Test (*2019-12-23)'
+    'Alice Test (*1919-12-23, †2019-11-01)'
 
     >>> bob = Person('bob')
     >>> bob.name = 'Bob Test'
@@ -40,6 +41,7 @@ class Person:
         self.__identifier: str = identifier
         self.name: typing.Optional[str] = None
         self.birth_date: typing.Optional[datetime.date] = None
+        self.death_date: typing.Optional[datetime.date] = None
         self.mother: typing.Optional["Person"] = None
         self.father: typing.Optional["Person"] = None
 
@@ -61,9 +63,10 @@ class Person:
         >>> p.name = "Max Mustermann"
         >>> repr(p)
         'Person(max-mustermann, Max Mustermann)'
-        >>> p.birth_date = datetime.date(1976, 2, 1)
+        >>> p.birth_date = datetime.date(1876, 2, 1)
+        >>> p.death_date = datetime.date(1976, 2, 1)
         >>> repr(p)
-        'Person(max-mustermann, Max Mustermann, *1976-02-01)'
+        'Person(max-mustermann, Max Mustermann, *1876-02-01, †1976-02-01)'
         """
         return "{}({})".format(
             type(self).__name__,
@@ -76,6 +79,9 @@ class Person:
                         "*" + self.birth_date.isoformat()
                         if self.birth_date is not None
                         else None,
+                        "†" + self.death_date.isoformat()
+                        if self.death_date is not None
+                        else None,
                     ),
                 )
             ),
@@ -87,12 +93,20 @@ class Person:
         >>> p.name = "Max Mustermann"
         >>> str(p)
         'Max Mustermann'
-        >>> p.birth_date = datetime.date(1976, 2, 1)
+        >>> p.birth_date = datetime.date(1876, 2, 1)
+        >>> str(p)
+        'Max Mustermann (*1876-02-01)'
+        >>> p.death_date = datetime.date(1976, 1, 2)
         >>> str(p)
-        'Max Mustermann (*1976-02-01)'
+        'Max Mustermann (*1876-02-01, †1976-01-02)'
         """
+        attrs = []
+        if self.birth_date is not None:
+            attrs.append("*{}".format(self.birth_date.isoformat()))
+        if self.death_date is not None:
+            attrs.append("†{}".format(self.death_date.isoformat()))
         return (self.name or "unnamed") + (
-            " (*{})".format(self.birth_date.isoformat()) if self.birth_date else ""
+            " ({})".format(", ".join(attrs)) if attrs else ""
         )
 
     def __eq__(self, other: "Person") -> bool:
@@ -115,24 +129,25 @@ class Person:
         >>> str(p1)
         'Max Mustermann'
         >>> p2 = Person("max2")
-        >>> p2.birth_date = datetime.date(1976, 2, 1)
+        >>> p2.birth_date = datetime.date(1876, 2, 1)
+        >>> p2.death_date = datetime.date(1976, 2, 1)
         >>> p2.mother = Person("mother")
         >>> p2.father = Person("father")
         >>> str(p2)
-        'unnamed (*1976-02-01)'
+        'unnamed (*1876-02-01, †1976-02-01)'
 
         add attributes of p2 to p1:
         >>> p1.merge(p2)
         >>> str(p1)
-        'Max Mustermann (*1976-02-01)'
+        'Max Mustermann (*1876-02-01, †1976-02-01)'
         >>> p1.mother, p1.father
         (Person(mother), Person(father))
 
         p2 is unchanged:
         >>> str(p2)
-        'unnamed (*1976-02-01)'
+        'unnamed (*1876-02-01, †1976-02-01)'
         """
-        for attr in ["name", "birth_date", "mother", "father"]:
+        for attr in ["name", "birth_date", "death_date", "mother", "father"]:
             if getattr(person, attr) is not None:
                 setattr(self, attr, getattr(person, attr))
 

+ 5 - 0
yamily/_cli.py

@@ -66,10 +66,15 @@ def _dot() -> None:
     argparser.add_argument(
         "paths", nargs="+", metavar="path", help="path to yamily .yml file or folder"
     )
+    argparser.add_argument("--comment", dest="comment_text")
     args = argparser.parse_args()
     collection = yamily.PersonCollection()
     for path in args.paths:
         for person in _read(pathlib.Path(path)):
             collection.add_person(person)
     graph = yamily._graphviz.digraph(collection)  # pylint: disable=protected-access
+    if args.comment_text is not None:
+        with graph.subgraph(name="cluster_comment") as comment:
+            comment.attr(style="invisible")
+            comment.node("comment", label=args.comment_text, shape="none")
     print(graph.source)

+ 2 - 0
yamily/_graphviz.py

@@ -26,6 +26,8 @@ def _add_person_node(graph: graphviz.dot.Digraph, person: Person) -> None:
     label = person.name or person.identifier
     if person.birth_date is not None:
         label += r"\n*{}".format(person.birth_date.isoformat())
+    if person.death_date is not None:
+        label += r"\n†{}".format(person.death_date.isoformat())
     graph.node(person.identifier, label=label, shape="box")
 
 

+ 9 - 2
yamily/yaml.py

@@ -31,13 +31,14 @@ class Loader(yaml.SafeLoader):
     ... !person
     ... identifier: alice
     ... name: Alice Test
-    ... birth_date: 1976-02-01
+    ... birth_date: 1876-02-01
+    ... death_date: 1976-01-02
     ... mother: mum
     ... father: dad
     ... '''
     >>> alice = yaml.load(alice_yaml, Loader=Loader)
     >>> alice
-    Person(alice, Alice Test, *1976-02-01)
+    Person(alice, Alice Test, *1876-02-01, †1976-01-02)
     >>> alice.mother
     Person(mum)
     >>> alice.father
@@ -75,6 +76,8 @@ class Loader(yaml.SafeLoader):
             person.name = person_attrs["name"]
         if "birth_date" in person_attrs:
             person.birth_date = person_attrs["birth_date"]
+        if "death_date" in person_attrs:
+            person.death_date = person_attrs["death_date"]
         if "mother" in person_attrs:
             if isinstance(person_attrs["mother"], Person):
                 person.mother = person_attrs["mother"]
@@ -94,9 +97,11 @@ class Dumper(yaml.SafeDumper):
     >>> p = Person('alice')
     >>> p.name = 'Alice'
     >>> p.birth_date = datetime.date(1976, 2, 1)
+    >>> p.death_date = datetime.date(2043, 1, 17)
     >>> print(yaml.dump(p, Dumper=Dumper))
     !person
     birth_date: 1976-02-01
+    death_date: 2043-01-17
     identifier: alice
     name: Alice
     <BLANKLINE>
@@ -127,6 +132,8 @@ class Dumper(yaml.SafeDumper):
             person_attrs["name"] = person.name
         if person.birth_date is not None:
             person_attrs["birth_date"] = person.birth_date
+        if person.death_date is not None:
+            person_attrs["death_date"] = person.death_date
         if person.mother is not None:
             person_attrs["mother"] = person.mother
         if person.father is not None: