]> git.rocketbowman.com Git - nom.git/commitdiff
finish refactoring cli fns to use nomlist
authorKyle Bowman <kyle+github@rocketbowman.com>
Mon, 20 Jan 2025 21:13:32 +0000 (16:13 -0500)
committerKyle Bowman <kyle+github@rocketbowman.com>
Mon, 20 Jan 2025 21:13:32 +0000 (16:13 -0500)
src/nom/base.py
src/nom/entry.py
src/nom/feed.py
src/nom/main.py
tests/data/entry_multi.csv
tests/data/entry_single.csv
tests/data/feedlist.csv
tests/data/feeds/simonwillison.net-tags-2d.atom [new file with mode: 0644]
tests/data/feeds/simonwillison.net-tags-trafficserver.atom [new file with mode: 0644]
tests/test_entry.py
tests/test_feed.py

index 9897c9fa85d81d9f8aa6c725bd1201a35c7f3e90..bcbbc4103e0cec0a8fa5043417814947ade41ab8 100644 (file)
@@ -46,11 +46,18 @@ class NomList:
     def __eq__(self, other):
         return self.items == other.items
 
+    def __iter__(self):
+        return self.items.__iter__()
+
     def __len__(self):
         return len(self.items)
 
     def update(self, other):
         self.items.update(other.items)
+    
+    def to_stdout(self):
+        for item in self.items:
+            print(item.to_str(delimeter="\t"))
 
 
     # NOTE: To get the interface that I want (i.e `from_csv(path)`)
index c3eb15dc0a4c3cc79c5dbe1af1883d886daec46d..3ef20d84f57bf148780604fefe83eaff1d3881a4 100644 (file)
@@ -9,10 +9,9 @@ from nom.base import NomList, NomListItem
 # TODO: Use proper types, not strings. (Pydantic?)
 @dataclass 
 class EntryListItem(NomListItem):
-    id_: str 
     title: str
-    url: str = ""
-    date: Optional[str] = "test"
+    url: str  
+    date: str  
     feed_url: Optional[str] = ""
     feed_alias: Optional[str] = ""
     viewed: Optional[bool] = "False"
@@ -26,9 +25,4 @@ class EntryList(NomList):
 
     @classmethod
     def from_csv(cls, path: Path):
-        return super().from_csv(path, EntryListItem)
-
-    # I think I like from_feed/update in place of update_from_feeds 
-    @classmethod
-    def from_feed(cls, feed):
-        pass
\ No newline at end of file
+        return super().from_csv(path, EntryListItem)
\ No newline at end of file
index ba3e70b25fb9ade2aef46689fb4b64fa7234683c..11a7f7c1c5dc9d01d8d6e7bfc0b08889c3e64c16 100644 (file)
@@ -6,53 +6,49 @@ from dataclasses import dataclass
 import feedparser
 import requests
 
-from nom.entry import EntryListItem
+from nom.entry import EntryList, EntryListItem
 from nom.utils import url2filename
 from nom.base import NomListItem, NomList
 
 
 class Feed:
 
-    def __init__(self, url: str):
-        d = feedparser.parse(url)
-        self.d = d
-        self.name = d.feed.title
-        self.url = url # how is this different from d.feed.link?
-        self.entries : list[EntryListItem] = [
-            EntryListItem(
-                e.title, 
-                e.link, 
-                e.updated
-                ) for e in d.entries]
-
-    def to_stdout(self):
-        for entry in self.entries:
-            if entry:
-                print(entry.to_str())
+    def __init__(self, feedparsable):
+        d = feedparser.parse(feedparsable)
+        self.name       = d.feed.title
+        self.url        = d.feed.link # how is this different from d.feed.link?
+        self.entries    = d.entries 
+    
+    def to_entrylist(self)->EntryList:
+        items = []
+        for e in self.entries:
+            entry = EntryListItem(
+                e.title, e.link, e.updated, 
+                self.url, "no alias", "False", "no summary")
+            items.append(entry)
+        return EntryList(items=items)
+
 
 @dataclass
 class FeedListItem(NomListItem):
-    id_: str
     url: str
-    alias: str
 
-    # Where do fetch/parse belong?
-    def fetch(self, url):
-        pass
+    def __hash__(self):
+        return hash(self.url)
+
+    def to_feed(self):
+        return Feed(self.url)
 
-    def parse(self, url)->list[EntryListItem]:
+    def fetch_feed(self):
         pass
 
 
 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_csv(cls, path: Path):
+        return super().from_csv(path, FeedListItem)
+
     @classmethod
     def from_file(cls, file: Path):
         with open(file, 'r') as f:
@@ -63,11 +59,11 @@ class FeedList(NomList):
         if not os.path.exists(save_dir):
             os.makedirs(save_dir)
 
-        for url in self.urls:
-            filename = url2filename(url)
+        for flitem in self.items:
+            filename = url2filename(flitem.url)
             path = save_dir / filename
             with open(path, 'w') as f:
                 # TODO: URL Error Handling
-                r = requests.get(url)
+                r = requests.get(flitem.url)
                 f.write(r.text)
             print(f"{path} updated")
\ No newline at end of file
index 24acb69736c42fc158297bb9d0809d31d5c0b012..c697bb46e755acc8f7f89429b103cace14c48ef8 100644 (file)
@@ -2,24 +2,25 @@ from pathlib import Path
 
 from nom.utils import url2filename, NomError
 from nom.feed import Feed, FeedList
+from nom.entry import EntryList
 from nom.cli import cli
 
 # Globals. Sue me.
 FEED_CACHE=Path.home() / ".cache" / "nom" / "feeds"
 FEED_LIST=Path.home() / ".local" / "share" / "nom" / "feedlist" / "default"
 
-# TODO: Need to append feeds to one another (and save to entrylist)
 # TODO: Flesh out CLI.
 def main():
     parser = cli()
     args = parser.parse_args()
 
     # Direct Logic 
-    feedlist=FeedList.from_file(FEED_LIST)
+    feedlist=FeedList.from_csv(FEED_LIST)
     if args.command == "entry" and args.entry_command == "show":
-        for url in feedlist.urls:
-            feed=Feed(str(FEED_CACHE / url2filename(url)))
-            feed.to_stdout()
+        elist=EntryList()
+        for flitem in feedlist:
+            elist.update(flitem.to_feed().to_entrylist())
+        elist.to_stdout()
     elif args.command == "feed" and args.feed_command == "update":
         feedlist.fetch_feeds(FEED_CACHE)
     else:
index cfa5b8760bf46a9aebc84119c3094f8026e23280..bb54feec9030007720415d7608d4c5446eb45ddd 100644 (file)
@@ -1,3 +1,3 @@
-id_|title|url|date|feed_url|feed_alias|viewed|summary\r
-2|Entry One|https://path/to/entry2.html|test|||False|\r
-3|Entry Two|https://path/to/entry3.html|test|||True|\r
+title|url|date|feed_url|feed_alias|viewed|summary\r
+Entry One|https://path/to/entry2.html|date|https://path/to/feed.atom|feed1|False|\r
+Entry Two|https://path/to/entry3.html|date|https://path/to/feed.atom|feed2|True|\r
index c3d8f78b8045fdd7d6740b88fe17d1d9b7779952..c90648fb870c90fc214c207456950d8076bc9a0d 100644 (file)
@@ -1,2 +1,2 @@
-id_|title|url|date|feed_url|feed_alias|viewed|summary\r
-1|Entry One|https://path/to/entry1.html|test|||False|\r
+title|url|date|feed_url|feed_alias|viewed|summary\r
+Entry One|https://path/to/entry1.html|date|https://path/to/feed.atom|no alias|False|no summary\r
index f0c612c473778b547313d7ed34db029296bce723..3270b4ee210c43f0a1c03331262e5a1933108b6d 100644 (file)
@@ -1,2 +1,3 @@
-https://simonwillison.net/atom/everything/
-https://jvns.ca/atom.xml
\ No newline at end of file
+url
+https://simonwillison.net/tags/2d.atom
+https://simonwillison.net/tags/trafficserver.atom
\ No newline at end of file
diff --git a/tests/data/feeds/simonwillison.net-tags-2d.atom b/tests/data/feeds/simonwillison.net-tags-2d.atom
new file mode 100644 (file)
index 0000000..e3627db
--- /dev/null
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<feed xml:lang="en-us" xmlns="http://www.w3.org/2005/Atom"><title>Simon Willison's Weblog: 2d</title><link href="http://simonwillison.net/" rel="alternate"/><link href="http://simonwillison.net/tags/2d.atom" rel="self"/><id>http://simonwillison.net/</id><updated>2008-03-16T16:24:38+00:00</updated><author><name>Simon Willison</name></author><entry><title>dojox.gfx demos</title><link href="https://simonwillison.net/2008/Mar/16/dojox/#atom-tag" rel="alternate"/><published>2008-03-16T16:24:38+00:00</published><updated>2008-03-16T16:24:38+00:00</updated><id>https://simonwillison.net/2008/Mar/16/dojox/#atom-tag</id><summary type="html">
+    
+&lt;p&gt;&lt;strong&gt;&lt;a href="http://archive.dojotoolkit.org/nightly/dojotoolkit/dojox/gfx/demos/"&gt;dojox.gfx demos&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
+Impressive demos of the Dojo 2D drawing APIs—these need to be linked from the dojo site, it took me quite a while to find them.
+
+
+    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/dojo"&gt;dojo&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/dojox"&gt;dojox&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/gfx"&gt;gfx&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/javascript"&gt;javascript&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/drawing"&gt;drawing&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/2d"&gt;2d&lt;/a&gt;&lt;/p&gt;
+
+
+
+</summary><category term="dojo"/><category term="dojox"/><category term="gfx"/><category term="javascript"/><category term="drawing"/><category term="2d"/></entry><entry><title>Create cross browser vector graphics</title><link href="https://simonwillison.net/2006/Dec/20/gfx/#atom-tag" rel="alternate"/><published>2006-12-20T00:42:30+00:00</published><updated>2006-12-20T00:42:30+00:00</updated><id>https://simonwillison.net/2006/Dec/20/gfx/#atom-tag</id><summary type="html">
+    
+&lt;p&gt;&lt;strong&gt;&lt;a href="http://www.thinkvitamin.com/features/design/create-cross-browser-vector-graphics"&gt;Create cross browser vector graphics&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
+An accessible introduction to dojo.gfx, a powerful 2D drawing API built on SVG and VML.
+
+
+    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/svg"&gt;svg&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/drawing"&gt;drawing&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/dojo"&gt;dojo&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/2d"&gt;2d&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/vml"&gt;vml&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/javascript"&gt;javascript&lt;/a&gt;&lt;/p&gt;
+
+
+
+</summary><category term="svg"/><category term="drawing"/><category term="dojo"/><category term="2d"/><category term="vml"/><category term="javascript"/></entry><entry><title>Dojo 0.4 release notes</title><link href="https://simonwillison.net/2006/Oct/23/dojo/#atom-tag" rel="alternate"/><published>2006-10-23T00:39:10+00:00</published><updated>2006-10-23T00:39:10+00:00</updated><id>https://simonwillison.net/2006/Oct/23/dojo/#atom-tag</id><summary type="html">
+    
+&lt;p&gt;&lt;strong&gt;&lt;a href="http://dojo.jot.com/WikiHome/Release0Point4"&gt;Dojo 0.4 release notes&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
+GFX (a 2D drawing API) is awesome; dojo.html.metrics looks extremely useful, and onDomLoad is always nice.
+
+    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="http://blog.dojotoolkit.org/2006/10/22/dojo-040-release-candidate"&gt;The Dojo Blog&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
+
+
+    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/dojo"&gt;dojo&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/2d"&gt;2d&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/drawing"&gt;drawing&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/javascript"&gt;javascript&lt;/a&gt;&lt;/p&gt;
+
+
+
+</summary><category term="dojo"/><category term="2d"/><category term="drawing"/><category term="javascript"/></entry></feed>
\ No newline at end of file
diff --git a/tests/data/feeds/simonwillison.net-tags-trafficserver.atom b/tests/data/feeds/simonwillison.net-tags-trafficserver.atom
new file mode 100644 (file)
index 0000000..288890a
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<feed xml:lang="en-us" xmlns="http://www.w3.org/2005/Atom"><title>Simon Willison's Weblog: trafficserver</title><link href="http://simonwillison.net/" rel="alternate"/><link href="http://simonwillison.net/tags/trafficserver.atom" rel="self"/><id>http://simonwillison.net/</id><updated>2009-11-01T12:15:27+00:00</updated><author><name>Simon Willison</name></author><entry><title>Traffic Server</title><link href="https://simonwillison.net/2009/Nov/1/trafficserver/#atom-tag" rel="alternate"/><published>2009-11-01T12:15:27+00:00</published><updated>2009-11-01T12:15:27+00:00</updated><id>https://simonwillison.net/2009/Nov/1/trafficserver/#atom-tag</id><summary type="html">
+    
+&lt;p&gt;&lt;strong&gt;&lt;a href="http://www.mnot.net/blog/2009/10/30/traffic_server"&gt;Traffic Server&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
+Mark Nottingham explains the release of Traffic Server, a new Apache Incubator open source project donated by Yahoo! using code originally developed at Inktomi around a decade ago. Traffic Server is a HTTP proxy/cache, similar to Squid and Varnish (though Traffic Server acts as both a forward and reverse proxy, whereas Varnish only handles reverse).
+
+
+    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/trafficserver"&gt;trafficserver&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/yahoo"&gt;yahoo&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/inktomi"&gt;inktomi&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/mark-nottingham"&gt;mark-nottingham&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/open-source"&gt;open-source&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/apache"&gt;apache&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/http"&gt;http&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/cache"&gt;cache&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/proxy"&gt;proxy&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/squid"&gt;squid&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/varnish"&gt;varnish&lt;/a&gt;&lt;/p&gt;
+
+
+
+</summary><category term="trafficserver"/><category term="yahoo"/><category term="inktomi"/><category term="mark-nottingham"/><category term="open-source"/><category term="apache"/><category term="http"/><category term="cache"/><category term="proxy"/><category term="squid"/><category term="varnish"/></entry><entry><title>Yahoo! proposal to open source "Traffic Server" via the ASF</title><link href="https://simonwillison.net/2009/Jul/7/trafficserver/#atom-tag" rel="alternate"/><published>2009-07-07T12:37:02+00:00</published><updated>2009-07-07T12:37:02+00:00</updated><id>https://simonwillison.net/2009/Jul/7/trafficserver/#atom-tag</id><summary type="html">
+    
+&lt;p&gt;&lt;strong&gt;&lt;a href="http://wiki.apache.org/incubator/TrafficServerProposal"&gt;Yahoo! proposal to open source &amp;quot;Traffic Server&amp;quot; via the ASF&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
+Traffic Server is a “fast, scalable and extensible HTTP/1.1 compliant  caching proxy server” (presumably equivalent to things like Squid and Varnish) originally acquired from Inktomi and developed internally at Yahoo! for the past three years, which has been benchmarked handling 35,000 req/s on a single box. No source code yet but it looks like the release will arrive pretty soon.
+
+
+    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/trafficserver"&gt;trafficserver&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/yahoo"&gt;yahoo&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/open-source"&gt;open-source&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/caching"&gt;caching&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/proxy"&gt;proxy&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/squid"&gt;squid&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/varnish"&gt;varnish&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/apache"&gt;apache&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/asf"&gt;asf&lt;/a&gt;&lt;/p&gt;
+
+
+
+</summary><category term="trafficserver"/><category term="yahoo"/><category term="open-source"/><category term="caching"/><category term="proxy"/><category term="squid"/><category term="varnish"/><category term="apache"/><category term="asf"/></entry></feed>
\ No newline at end of file
index e5cc8d24e4470262f24c82cbc3de677203e0e5f1..a769eadcc7b1775bf04d7e9c9e1ca975b245fd26 100644 (file)
@@ -4,6 +4,7 @@ from copy import copy
 import pytest
 
 from nom.entry import EntryList, EntryListItem
+from test_feed import feedlist
 
 
 @pytest.fixture
@@ -30,9 +31,6 @@ def test_elist_to_from_csv_idempotency(elist_single,tmp_path):
     remade = EntryList.from_csv(path)
     assert remade == elist_single
 
-def test_from_feed():
-    pass
-    
 def test_eli_to_from_dict_idempotency(elist_item):
     remade = elist_item.from_dict(elist_item.to_dict()) 
     assert remade == elist_item
@@ -46,4 +44,3 @@ 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)
-
index b4176da8dab18da6ac62ef6d12cd7ba1846ffbd2..349276efa83f97d79366d98386c1f2d411339adc 100644 (file)
@@ -1,10 +1,20 @@
 from pathlib import Path
+import pytest
 
-from nom.feed import *
+from nom.feed import FeedList
+from nom.entry import EntryList
 
-FEED_LIST=Path(__file__).parent / "data" / "feedlist.csv"
+@pytest.fixture
+def feedlist():
+    path = Path(__file__).parent / "data" / "feedlist.csv"
+    return FeedList.from_csv(path)
 
-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
+def test_flist_from_csv(feedlist):
+    assert len(feedlist) == 2
+    #assert "https://simonwillison.net/tags/trafficserver.atom" in feedlist
+
+def test_to_entrylist(feedlist):
+    elist = EntryList()
+    for flitem in feedlist:
+        elist.update(flitem.to_feed().to_entrylist())
+    assert len(elist) == 5
\ No newline at end of file