]> git.rocketbowman.com Git - nom.git/commitdiff
abstract ListItem and List
authorKyle Bowman <kyle+github@rocketbowman.com>
Sun, 19 Jan 2025 04:24:19 +0000 (23:24 -0500)
committerKyle Bowman <kyle+github@rocketbowman.com>
Sun, 19 Jan 2025 04:24:19 +0000 (23:24 -0500)
src/nom/base.py [new file with mode: 0644]
src/nom/entry.py
src/nom/feed.py
src/nom/main.py
tests/data/entry.csv [deleted file]
tests/data/feedlist.csv [new file with mode: 0644]
tests/test_feed.py [new file with mode: 0644]

diff --git a/src/nom/base.py b/src/nom/base.py
new file mode 100644 (file)
index 0000000..4f90a1e
--- /dev/null
@@ -0,0 +1,39 @@
+from pathlib import Path
+from csv import DictReader, DictWriter, excel_tab
+
+from nom.utils import NomError
+
+
+class NomListItem:
+    
+    
+    # TODO: This technically doesn't follow the __repr__ pattern.
+    # 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()])
+
+    def to_dict(self):
+        return self.__dict__
+
+    @classmethod
+    def from_dict(cls, dct: dict):
+        return cls(**dct)
+
+
+# NOTE: Implementation requires self.delimiter.
+class NomList:
+
+    @classmethod
+    def from_csv(cls, file: Path):
+        pass
+
+    def to_csv(self, file: Path):
+        if not self.dicts:
+            raise NomError("There are no entries to write.")
+
+        with open(file, "w") as f:
+            dialect = excel_tab
+            dialect.delimiter=self.delimiter
+            writer = DictWriter(f, fieldnames=self.fieldnames, dialect=dialect) 
+            writer.writeheader()
+            writer.writerows(self.dicts)
\ No newline at end of file
index fdb34f94c503b4a2003fb6f1131bb29f62c851c8..4aead2754bf2b5278d5bb779b1fd10028b7c2a8e 100644 (file)
@@ -1,36 +1,26 @@
-from csv import DictReader, DictWriter, excel_tab
 from dataclasses import dataclass
 from pathlib import Path
 from typing import Optional
 
 from nom.utils import NomError
+from nom.base import NomList, NomListItem
+
 
 # TODO: Use proper types, not strings. (Pydantic?)
 @dataclass 
-class EntryListItem:
+class EntryListItem(NomListItem):
     id_: str 
     title: str
-    url: Optional[str] = None
+    url: Optional[str] = ""
     date: Optional[str] = "test"
-    feed_url: Optional[str] = None
-    feed_alias: Optional[str] = None
-    viewed: Optional[bool] = False
-    summary: Optional[str] = None # TODO: Add this when you feel like stripping HTML
-
-    # TODO: What if there's a pipe in one of the fields? 
-    def to_str(self, delimiter: str ='|'):
-        # values = [value for value in self.__dict__.values()]
-        return delimiter.join([self.title, self.url, self.date])
+    feed_url: Optional[str] = ""
+    feed_alias: Optional[str] = ""
+    viewed: Optional[bool] = "False"
+    summary: Optional[str] = "" # TODO: Add this when you feel like stripping HTML
 
-    def to_dict(self):
-        return self.__dict__
 
-    @classmethod
-    def from_dict(cls, dct: dict):
-        return cls(**dct)
 
-
-class EntryList:
+class EntryList(NomList):
 
     def __init__(self, delimiter='|'):
         self.entries : list[EntryListItem] = []
@@ -41,23 +31,20 @@ class EntryList:
     def add_entry(self, entry):
         self.entries.append(entry)
 
-    # TODO: "Append" doesn't feel right.
-    def append_feed(self,feed):
+    def update_from_feeds(self, feedlist):
         pass
 
-    def from_file(self, file: Path):
+    def update_from_feed(self, feed):
         pass
 
-    def to_file(self, file: Path):
-        if not self.dicts:
-            raise NomError("There are no entries to write.")
+    def from_stdout(self):
+        pass
 
-        with open(file, "w") as f:
-            dialect = excel_tab
-            dialect.delimiter="|"
-            writer = DictWriter(f, fieldnames=self.fieldnames, dialect=dialect) 
-            writer.writeheader()
-            writer.writerows(self.dicts)
+    # TODO: Fix this with command line option
+    def to_stdout(self):
+        for entry in self.entries:
+            if entry:
+                print(entry.to_str())
 
 
 if __name__ == "__main__":
@@ -67,4 +54,4 @@ if __name__ == "__main__":
     entry = EntryListItem.from_dict(dct)
     elist.add_entry(entry)
     elist.dicts = [entry.__dict__ for entry in elist.entries]
-    elist.to_file(path)
+    elist.to_csv(path)
index f2ee1245c91773a4f22abb8b6486a43a0dc5b86f..1baa8d3a0e3a667c3f1423ab013f42b9242d56d4 100644 (file)
@@ -1,12 +1,14 @@
 import os
 from pathlib import Path
 from typing import Optional
+from dataclasses import dataclass
 
 import feedparser
 import requests
 
 from nom.entry import EntryListItem
 from nom.utils import url2filename
+from nom.base import NomListItem, NomList
 
 
 class Feed:
@@ -23,20 +25,32 @@ class Feed:
                 e.updated
                 ) for e in d.entries]
 
-    # TODO: Fix this with command line option
-    def to_stdout(self, file: Optional[Path]=None):
+    def to_stdout(self):
         for entry in self.entries:
             if entry:
                 print(entry.to_str())
 
-class FeedList:
+@dataclass
+class FeedListItem(NomListItem):
+    id_: str
+    url: str
+    alias: str
 
-    def __init__(self, file: Path):
+
+class FeedList(NomList):
+
+    # TODO: Make this follow the NomList pattern
+    def __init__(self, name, urls):
+        self.name = name
+        self.urls = urls
+        #self.feeds = []
+    
+    # TODO: Rewrite this with CSV and FeedListItem parsing
+    @classmethod
+    def from_file(cls, file: Path):
         with open(file, 'r') as f:
             urls = f.read().splitlines()
-        
-        self.name = file.name
-        self.urls = urls
+        return cls(file.name, urls) 
 
     def fetch_feeds(self, save_dir: Path):
         if not os.path.exists(save_dir):
index a66f3146371adf4a23d0828e22cec527ac82832a..24acb69736c42fc158297bb9d0809d31d5c0b012 100644 (file)
@@ -15,7 +15,7 @@ def main():
     args = parser.parse_args()
 
     # Direct Logic 
-    feedlist=FeedList(FEED_LIST)
+    feedlist=FeedList.from_file(FEED_LIST)
     if args.command == "entry" and args.entry_command == "show":
         for url in feedlist.urls:
             feed=Feed(str(FEED_CACHE / url2filename(url)))
diff --git a/tests/data/entry.csv b/tests/data/entry.csv
deleted file mode 100644 (file)
index 3d7f348..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-id_|title|url|date|feed_url|feed_alias|viewed|summary\r
-1|Kyle was here!|||||False|\r
diff --git a/tests/data/feedlist.csv b/tests/data/feedlist.csv
new file mode 100644 (file)
index 0000000..f0c612c
--- /dev/null
@@ -0,0 +1,2 @@
+https://simonwillison.net/atom/everything/
+https://jvns.ca/atom.xml
\ No newline at end of file
diff --git a/tests/test_feed.py b/tests/test_feed.py
new file mode 100644 (file)
index 0000000..b4176da
--- /dev/null
@@ -0,0 +1,10 @@
+from pathlib import Path
+
+from nom.feed import *
+
+FEED_LIST=Path(__file__).parent / "data" / "feedlist.csv"
+
+def test_from_file():
+    feedlist = FeedList.from_file(FEED_LIST)
+    assert len(feedlist.urls) == 2
+    assert "jvn" in feedlist.urls[1]
\ No newline at end of file