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)`)
# 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"
@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
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:
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
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:
-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
-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
-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
--- /dev/null
+<?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">
+
+<p><strong><a href="http://archive.dojotoolkit.org/nightly/dojotoolkit/dojox/gfx/demos/">dojox.gfx demos</a></strong></p>
+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.
+
+
+ <p>Tags: <a href="https://simonwillison.net/tags/dojo">dojo</a>, <a href="https://simonwillison.net/tags/dojox">dojox</a>, <a href="https://simonwillison.net/tags/gfx">gfx</a>, <a href="https://simonwillison.net/tags/javascript">javascript</a>, <a href="https://simonwillison.net/tags/drawing">drawing</a>, <a href="https://simonwillison.net/tags/2d">2d</a></p>
+
+
+
+</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">
+
+<p><strong><a href="http://www.thinkvitamin.com/features/design/create-cross-browser-vector-graphics">Create cross browser vector graphics</a></strong></p>
+An accessible introduction to dojo.gfx, a powerful 2D drawing API built on SVG and VML.
+
+
+ <p>Tags: <a href="https://simonwillison.net/tags/svg">svg</a>, <a href="https://simonwillison.net/tags/drawing">drawing</a>, <a href="https://simonwillison.net/tags/dojo">dojo</a>, <a href="https://simonwillison.net/tags/2d">2d</a>, <a href="https://simonwillison.net/tags/vml">vml</a>, <a href="https://simonwillison.net/tags/javascript">javascript</a></p>
+
+
+
+</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">
+
+<p><strong><a href="http://dojo.jot.com/WikiHome/Release0Point4">Dojo 0.4 release notes</a></strong></p>
+GFX (a 2D drawing API) is awesome; dojo.html.metrics looks extremely useful, and onDomLoad is always nice.
+
+ <p><small></small>Via <a href="http://blog.dojotoolkit.org/2006/10/22/dojo-040-release-candidate">The Dojo Blog</a></small></p>
+
+
+ <p>Tags: <a href="https://simonwillison.net/tags/dojo">dojo</a>, <a href="https://simonwillison.net/tags/2d">2d</a>, <a href="https://simonwillison.net/tags/drawing">drawing</a>, <a href="https://simonwillison.net/tags/javascript">javascript</a></p>
+
+
+
+</summary><category term="dojo"/><category term="2d"/><category term="drawing"/><category term="javascript"/></entry></feed>
\ No newline at end of file
--- /dev/null
+<?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">
+
+<p><strong><a href="http://www.mnot.net/blog/2009/10/30/traffic_server">Traffic Server</a></strong></p>
+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).
+
+
+ <p>Tags: <a href="https://simonwillison.net/tags/trafficserver">trafficserver</a>, <a href="https://simonwillison.net/tags/yahoo">yahoo</a>, <a href="https://simonwillison.net/tags/inktomi">inktomi</a>, <a href="https://simonwillison.net/tags/mark-nottingham">mark-nottingham</a>, <a href="https://simonwillison.net/tags/open-source">open-source</a>, <a href="https://simonwillison.net/tags/apache">apache</a>, <a href="https://simonwillison.net/tags/http">http</a>, <a href="https://simonwillison.net/tags/cache">cache</a>, <a href="https://simonwillison.net/tags/proxy">proxy</a>, <a href="https://simonwillison.net/tags/squid">squid</a>, <a href="https://simonwillison.net/tags/varnish">varnish</a></p>
+
+
+
+</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">
+
+<p><strong><a href="http://wiki.apache.org/incubator/TrafficServerProposal">Yahoo! proposal to open source &quot;Traffic Server&quot; via the ASF</a></strong></p>
+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.
+
+
+ <p>Tags: <a href="https://simonwillison.net/tags/trafficserver">trafficserver</a>, <a href="https://simonwillison.net/tags/yahoo">yahoo</a>, <a href="https://simonwillison.net/tags/open-source">open-source</a>, <a href="https://simonwillison.net/tags/caching">caching</a>, <a href="https://simonwillison.net/tags/proxy">proxy</a>, <a href="https://simonwillison.net/tags/squid">squid</a>, <a href="https://simonwillison.net/tags/varnish">varnish</a>, <a href="https://simonwillison.net/tags/apache">apache</a>, <a href="https://simonwillison.net/tags/asf">asf</a></p>
+
+
+
+</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
import pytest
from nom.entry import EntryList, EntryListItem
+from test_feed import feedlist
@pytest.fixture
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
sum_ = elist_multi + elist_single
assert len(sum_) == len(elist_multi) + len(elist_single)
assert isinstance(sum_,EntryList)
-
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