print(item.to_str(delimeter="\t"))
- # NOTE: To get the interface that I want (i.e `from_csv(path)`)
- # each subclass must override from_csv and pass in the NomListItem
- # that has a to_dict() method. For example, for EntryList:
- # ```
- # @classmethod
- # def from_csv(cls, path):
- # return super().from_csv(path, EntryListItem)
- # ````
@classmethod
def from_csv(cls, file: Path, nlitem: NomListItem, delimiter="|"):
+ # To parse NomListItems in a file, specify a specific NomListItem
+ if nlitem == NomListItem or type(nlitem) == NomListItem:
+ raise NotImplementedError(f"Override this method with super().__init__(file, {str(cls()).replace('()','')}Item) to enforce item parsing.")
items = []
dialect = excel_tab
dialect.delimiter=delimiter
def to_csv(self, file: Path, delimiter="|"):
if not self:
raise NomError("There are no entries to write.")
+ file.parent.mkdir(parents=True,exist_ok=True)
fieldnames=next(iter(self)).get_fieldnames()
dialect = excel_tab
# Globals. Sue me.
FEED_CACHE=Path.home() / ".cache" / "nom" / "feeds"
-FEED_LIST=Path.home() / ".local" / "share" / "nom" / "feedlist" / "default"
-
+FEED_LIST=Path.home() / ".local" / "share" / "nom" / "feedlist" / "default"
+ENTRY_LIST=Path.home() / ".local" / "share" / "nom" / "entrylist" / "default"
def cli():
parser = ArgumentParser(description="Nom Script")
subparsers = parser.add_subparsers(dest='command', help='Sub-command help')
# Entry subcommand
- entry_parser = subparsers.add_parser('entry', help='Entry related commands')
- entry_subparsers = entry_parser.add_subparsers(dest='entry_command', help='Entry sub-command help')
- entry_show_parser = entry_subparsers.add_parser('show', help='Show entries')
+ entry_parser = subparsers.add_parser('entry', help='Dispatches commands that operate on a table of entries.')
+ entry_subparsers = entry_parser.add_subparsers(dest='entry_command', help='Dispatches entry commands.')
+ entry_show_parser = entry_subparsers.add_parser('show', help='Show entries.')
+ entry_update_parser = entry_subparsers.add_parser('update', help='Update entry data.')
# Feed subcommand
- feed_parser = subparsers.add_parser('feed', help='Feed related commands')
- feed_subparsers = feed_parser.add_subparsers(dest='feed_command', help='Feed sub-command help')
+ feed_parser = subparsers.add_parser('feed', help='Dispatches commands that operate on a table of feeds.')
+ feed_subparsers = feed_parser.add_subparsers(dest='feed_command', help='Dispatches feed commands.')
feed_update_parser = feed_subparsers.add_parser('update', help='Update feed')
- feed_update_parser = feed_subparsers.add_parser('show', help='Show feeds')
-
+ feed_show_parser = feed_subparsers.add_parser('show', help='Show feeds')
+
return parser
# Dispatch Logic
feedlist=FeedList.from_csv(FEED_LIST)
- if args.command == "entry" and args.entry_command == "show":
+ if args.command == "entry" and args.entry_command == "update":
elist=EntryList()
for flitem in feedlist:
elist += flitem.to_feed().to_entrylist()
+ print(f"Updating from [{str(flitem)}]")
+ elist.to_csv(ENTRY_LIST)
+ elif args.command == "entry" and args.entry_command == "show":
+ elist = EntryList.from_csv(ENTRY_LIST)
elist.to_stdout()
elif args.command == "feed" and args.feed_command == "update":
feedlist.fetch_feeds(FEED_CACHE)
--- /dev/null
+# Note: The base module isn't meant to be used directly, but instead is meant
+# to be subclassed from. In general, it makes more sense to test the subclasses
+# than it does to test the base class.
+
+import pytest
+from pathlib import Path
+from nom.base import NomList, NomListItem
+
+
+
+def test_from_csv_error():
+ class DummyList(NomList):
+ pass
+ path = Path(__file__).parent / "data" / "entry_single.csv"
+ with pytest.raises(NotImplementedError):
+ nlist=DummyList.from_csv(path, NomListItem)