def create_atom(feed): """Validates the generator output and creates the ATOM feed""" root = etree.Element("feed", attrib={"xmlns": "http://www.w3.org/2005/Atom"}) esc = cgi.escape ts = rfc3339(now) if not isinstance(feed, dict): err("Your generator forgot to return a dict.") if not "title" in feed: err("The feed lacks a title.") if not "id" in feed: err("The feed lacks a UUID.") if not "updated" in feed: feed["updated"] = ts if not "entries" in feed: err("The feed lacks entries.") if 'lang' in feed: root.set(etree.QName("{http://www.w3.org/XML/1998/namespace}lang"), feed["lang"]) child_tag(root, "title", text=feed["title"]) child_tag(root, "id", text=feed["id"]) child_tag(root, "updated", text=feed["updated"]) if "author" in feed: author = child_tag(root, "author") child_tag(author, "name", text=feed["author"]) if "author_uri" in feed: child_tag(author, "uri", feed["author_uri"]) if "subtitle" in feed: child_tag(root, "subtitle", text=feed["subtitle"]) if "link" in feed: child_tag(root, "link", attrib={'href': feed["link"]}) child_tag(root, "generator", attrib={"uri": "https://github.com/dgilman/atom_maker", "version": str(VERSION)}, text="atom_maker") child_tag(root, "link", attrib={"rel": "self", "href": self_url()}) #validate individual entries. check_for_authors = False if not "author" in feed: check_for_authors = True for entry in feed["entries"]: if check_for_authors and not "author" in entry: err("One of the feed entries lacks an author. If there is no global author set each feed needs its own author.") if not "id" in entry: err("An entry lacks a UUID.") if not "title" in entry: err("An entry lacks a title.") if not "content" in entry: err("An entry lacks content.") if not "content_type" in entry: err("All entries need a content_type.") if entry["content_type"] not in ["html", "text", "xhtml"]: err("content_type must be one of html, text, or html.") if not "updated" in entry: entry["updated"] = ts e = child_tag(root, "entry") if "lang" in entry: e.set(etree.QName("{http://www.w3.org/XML/1998/namespace}lang"), feed["lang"]) child_tag(e, "id", text=entry["id"]) child_tag(e, "title", text=entry["title"]) child_tag(e, "content", attrib={"type": entry["content_type"]}, text=entry["content"]) child_tag(e, "updated", text=entry["updated"]) if "author" in entry: author = child_tag(e, "author") child_tag(author, "name", text=entry["author"]) if "author_uri" in entry: child_tag(author, "uri", text=entry["author_uri"]) if "published" in entry: child_tag(e, "published", text=entry["published"]) if "link" in entry: child_tag(e, "link", attrib={"href": entry["link"]}) rval = cStringIO.StringIO() tree = etree.ElementTree(element=root) if sys.version_info < (2, 7): tree.write(rval, encoding="UTF-8") else: tree.write(rval, encoding="UTF-8", xml_declaration=True) return rval.getvalue()
def cli(): if len(sys.argv) < 2: print "Give the name of a feed to generate" sys.exit() # hack to support old-style from cmd line if "&" not in sys.argv[1]: sys.argv[1] = "feed=%s" % sys.argv[1] os.environ['SERVER_NAME'] = "cli/" os.environ['REQUEST_URI'] = sys.argv[1] os.environ['QUERY_STRING'] = sys.argv[1] args = cgi.parse() feed = feed_cache(args, flush=True) if not lxml: print feed else: feed = etree.tostring(etree.fromstring(feed), pretty_print = True, encoding="UTF-8", xml_declaration=True) print feed try: import feedvalidator from feedvalidator.formatter.text_plain import Formatter from feedvalidator import compatibility from feedvalidator.logging import ValidValue events = (x for x in feedvalidator.validateString(feed, firstOccurrenceOnly=True, base=self_url())['loggedEvents'] if not isinstance(x, ValidValue)) print "\n".join(Formatter(events)).encode("UTF-8") except ImportError: pass