--- /dev/null
+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
-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] = []
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__":
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)
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:
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):
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)))
+++ /dev/null
-id_|title|url|date|feed_url|feed_alias|viewed|summary\r
-1|Kyle was here!|||||False|\r
--- /dev/null
+https://simonwillison.net/atom/everything/
+https://jvns.ca/atom.xml
\ No newline at end of file
--- /dev/null
+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