]> git.rocketbowman.com Git - nom.git/commitdiff
refactor: make NomList based on set builtin
authorKyle Bowman <kylebowman14@gmail.com>
Tue, 21 Jan 2025 02:28:51 +0000 (21:28 -0500)
committerKyle Bowman <kylebowman14@gmail.com>
Tue, 21 Jan 2025 02:28:51 +0000 (21:28 -0500)
src/nom/base.py
src/nom/feed.py
src/nom/main.py
tests/test_cli.py [new file with mode: 0644]
tests/test_entry.py
tests/test_feed.py

index 8b79976e7ae89bfca16ed29a9877370d143f1562..fbd4caa0336394d3cf2109a07ae92f43e542b459 100644 (file)
@@ -3,7 +3,7 @@ from csv import DictReader, DictWriter, excel_tab
 from copy import copy
 from pathlib import Path
 from pydantic import BaseModel
-from typing import Callable
+from typing import Callable, Iterable, Optional
 
 from nom.utils import NomError
 
@@ -23,7 +23,7 @@ class NomListItem(BaseModel):
     
     # TODO: What if there's a pipe in one of the fields? 
     def to_str(self, delimiter: str ='|'):
-        return delimiter.join([v for v in self.__dict__.values()])
+        return delimiter.join([str(v) for v in self.__dict__.values()])
 
     def to_dict(self):
         return vars(self)
@@ -33,31 +33,20 @@ class NomListItem(BaseModel):
         return cls(**dct)
 
 
-class NomList:
+class NomList(set):
 
-    def __init__(self, items=set(), delimiter: str="|"):
-        self.delimiter=delimiter
-        self.items : set[NomListItem] = items
+    def __init__(self, elements: Optional[Iterable[NomListItem]]=None):
+        if not elements:
+            super().__init__()
+        else:
+            super().__init__(elements)
 
     def __add__(self, other):
-        dct = copy(vars(self))
-        dct['items'] = self.items.union(other.items)
-        return self.__class__(**dct)
+        return self.__class__(self.union(other))
     
-    def __contains__(self, value):
-        return value in self.items
-    
-    def __eq__(self, other):
-        return self.items == other.items
-
-    def __iter__(self):
-        return self.items.__iter__()
-
-    def __len__(self):
-        return len(self.items)
-
-    def merge(self, other):
-        self.items.update(other.items)
+    def select(self, predicate: Predicate):
+        items = {item for item in self if predicate(item)}
+        return self.__class__(items)
     
     def to_stdout(self):
         for item in self.items:
@@ -82,28 +71,25 @@ class NomList:
             for row in reader:
                 item = nlitem.from_dict(row)
                 items.append(item) 
-        return cls(items=set(items), delimiter=delimiter)
+        return cls(items)
 
-    def to_csv(self, file: Path):
-        if not self.items:
+    def to_csv(self, file: Path, delimiter="|"):
+        if not self:
             raise NomError("There are no entries to write.")
         
-        fieldnames=next(iter(self.items)).get_fieldnames()
+        fieldnames=next(iter(self)).get_fieldnames()
         dialect = excel_tab
-        dialect.delimiter=self.delimiter
+        dialect.delimiter=delimiter
 
         with open(file, "w") as f:
             writer = DictWriter(f, fieldnames=fieldnames, dialect=dialect) 
             writer.writeheader()
-            for item in self.items:
+            for item in self:
                 writer.writerow(item.to_dict())
     
     def to_stdout(self):
-        if not self.items:
+        if not self:
             raise NomError("There are no entries to write.")
-        for item in self.items:
+        for item in self:
             print(item.to_str())
-    
-def filter(nlist: NomList, predicate: Predicate):
-    items = {item for item in nlist.items if predicate(item)}
-    return nlist.__class__(items, delimiter=nlist.delimiter)
\ No newline at end of file
+    
\ No newline at end of file
index 7868ba2517fc68c5e6195d94258309fa7ac6c2a5..446af4f58b11209bbebf4ddcdc3e13b03eaee93a 100644 (file)
@@ -30,7 +30,7 @@ class Feed:
                 #viewed=False, 
                 summary="no summary")
             items.append(entry)
-        return EntryList(items=items)
+        return EntryList(items)
 
 
 class FeedListItem(NomListItem):
@@ -68,5 +68,5 @@ class FeedList(NomList):
         return cls(file.name, urls) 
 
     def fetch_feeds(self, save_dir: Path):
-        for flitem in self.items:
+        for flitem in self:
             flitem.fetch_feed(save_dir)
\ No newline at end of file
index d69a441c2f427d12c537c5e4c7675004259e792b..26850f752fceb8b8ca52c4205b8e7acdfe555023 100644 (file)
@@ -1,4 +1,5 @@
 from pathlib import Path
+import sys
 
 from nom.utils import url2filename, NomError
 from nom.feed import Feed, FeedList
@@ -10,16 +11,16 @@ FEED_CACHE=Path.home() / ".cache" / "nom" / "feeds"
 FEED_LIST=Path.home() / ".local" / "share" / "nom" / "feedlist" / "default"
 
 # TODO: Flesh out CLI.
-def main():
+def main(args=['nom'].append(sys.argv)):
     parser = cli()
-    args = parser.parse_args()
+    args = parser.parse_args(args=args)
 
     # Direct Logic 
     feedlist=FeedList.from_csv(FEED_LIST)
     if args.command == "entry" and args.entry_command == "show":
         elist=EntryList()
         for flitem in feedlist:
-            elist.merge(flitem.to_feed().to_entrylist())
+            elist += flitem.to_feed().to_entrylist()
         elist.to_stdout()
     elif args.command == "feed" and args.feed_command == "update":
         feedlist.fetch_feeds(FEED_CACHE)
diff --git a/tests/test_cli.py b/tests/test_cli.py
new file mode 100644 (file)
index 0000000..7c1c086
--- /dev/null
@@ -0,0 +1,10 @@
+from nom.main import main
+
+
+def test_nom_entry_show():
+    main(args='entry show'.split(' '))
+    assert True
+
+def test_nom_feed_update():
+    main(args='feed update'.split(' '))
+    assert True
\ No newline at end of file
index 97f8f5db4ae723598e0b3a2adaaf79b595f70375..df215b36b3bf10221c9d9cade8bc3d967d3ed19b 100644 (file)
@@ -4,7 +4,6 @@ from copy import copy
 import pytest
 
 from nom.entry import EntryList, EntryListItem
-from nom.filter import is_viewed
 from test_feed import feedlist
 
 
@@ -21,7 +20,7 @@ def elist_multi():
 
 @pytest.fixture
 def elist_item(elist_single):
-    return next(iter(elist_single.items))
+    return next(iter(elist_single))
 
 
 def test_elist_constructors(elist_single):
@@ -37,18 +36,11 @@ def test_eli_to_from_dict_idempotency(elist_item):
     remade = elist_item.from_dict(elist_item.to_dict()) 
     assert remade == elist_item
 
-def test_elist_merge(elist_multi, elist_single):
-    original_length = len(elist_multi)
-    elist_multi.merge(elist_single)
-    assert len(elist_multi) == original_length + 1
-
 def test_elist_addition(elist_multi, elist_single):
     sum_ = elist_multi + elist_single
     assert len(sum_) == len(elist_multi) + len(elist_single)
     assert isinstance(sum_,EntryList)
 
-def test_elist_filter(elist_multi):
-    #viewed = filter(is_viewed, elist_multi)
-    from nom.base import filter
-    viewed=filter(elist_multi, lambda e: e.viewed)
+def test_elist_select(elist_multi):
+    viewed = elist_multi.select(lambda e: e.viewed)
     assert len(viewed) < len(elist_multi)
index f53f01cc996ad6e17610107c6b51bc82b659617e..d92fbe3bc8186e0e1b61883469aec38b63e127ae 100644 (file)
@@ -16,5 +16,5 @@ def test_flist_from_csv(feedlist):
 def test_to_entrylist(feedlist):
     elist = EntryList()
     for flitem in feedlist:
-        elist.merge(flitem.to_feed().to_entrylist())
+        elist += flitem.to_feed().to_entrylist()
     assert len(elist) == 5
\ No newline at end of file