def _feedparser_parse_with_options(self) -> Tuple[feedparser.FeedParserDict, "UpdateResult"]:
"""
Perform a feedparser parse, providing arguments (like etag) we might want it to use.
Don't provide etag/last_modified if the last get was unsuccessful.
"""
if self.feed_state.last_modified is not None:
last_mod = self.feed_state.last_modified.timetuple()
else:
last_mod = None
# NOTE - this naming is a bit confusing here - parser is really a thing you call with
# arguments to get a feedparser result.
# Maybe better called parser-generator, or parse-performer or something?
parsed = self.parser(self.url, self.feed_state.etag, last_mod)
self.feed_state.etag = parsed.get("etag", self.feed_state.etag)
self.feed_state.store_last_modified(parsed.get("modified_parsed", None))
# Detect bozo errors (malformed RSS/ATOM feeds).
if "status" not in parsed and parsed.get("bozo", None) == 1:
# NOTE: Feedparser documentation indicates that you can always call getMessage, but
# it's possible for feedparser to spit out a URLError, which doesn't have getMessage.
# Catch this case.
if hasattr(parsed.bozo_exception, "getMessage()"):
msg = parsed.bozo_exception.getMessage()
else:
msg = repr(parsed.bozo_exception)
LOG.info(f"Unable to retrieve feed for {self.metadata['name']} from {self.url}.")
LOG.debug(f"Update failed because bozo exception {msg} occurred.")
return (None, UpdateResult.FAILURE)
elif parsed.get("status") == requests.codes["NOT_MODIFIED"]:
LOG.debug("No update to feed, nothing to do.")
return (None, UpdateResult.UNNEEDED)
else:
return (parsed, UpdateResult.SUCCESS)
评论列表
文章目录