Beispiel #1
0
def generate_feed(config_agent, req_path, tpl_render):
    folder_pages_full_path = config_agent.config.get("paths", "pages_path")
    cache_file_full_path = os.path.join(folder_pages_full_path,
                                        ".zw_all_pages_list_cache")

    buf = cache.get_all_pages_list_from_cache(config_agent)
    md_list = buf.split()

    author = config_agent.config.get("main", "maintainer_email") or "Anonymous"

    e_author = atom.Element(name="author")
    child = atom.Element(name="name", text=author)
    e_author.append_children(child)

    ts = os.stat(cache_file_full_path).st_ctime
    updated = atom.generate_updated(ts)
    ts_as_id = "timestamp:" + commons.strutils.md5(updated)

    feed = atom.Feed(author=e_author,
                     id=ts_as_id,
                     updated=updated,
                     title="Testing Feed Output")
    for md_file_name in md_list[:100]:
        req_path = commons.strutils.rstrips(md_file_name, ".md")
        req_path = commons.strutils.rstrips(req_path, ".markdown")
        local_full_path = mdutils.req_path_to_local_full_path(
            req_path, folder_pages_full_path)

        raw_text = commons.shutils.cat(local_full_path)
        page_title = mdutils.get_title_by_file_path_in_md(
            folder_pages_full_path, req_path)

        static_file_prefix = static_file.get_static_file_prefix_by_local_full_path(
            config_agent=config_agent,
            local_full_path=local_full_path,
            req_path=req_path)
        view_settings = page.get_view_settings(config_agent)
        page_content = mdutils.md2html(config_agent=config_agent,
                                       req_path=req_path,
                                       text=raw_text,
                                       static_file_prefix=static_file_prefix,
                                       **view_settings)

        text = cgi.escape(commons.strutils.safestr(page_content))
        e_content = atom.Element(name="content", text=text, type="html")
        if not page_title:
            continue

        hash_title_as_id = "md5:" + commons.strutils.md5(page_title)
        updated = atom.generate_updated(os.stat(local_full_path).st_ctime)
        entry = atom.Entry(id=hash_title_as_id,
                           title=page_title,
                           updated=updated,
                           content=e_content)
        feed.append_children(entry)

    buf = str(feed)
    return buf
 def testConvertToAndFromString(self):
     entry = atom.Entry()
     entry.author.append(atom.Author(name=atom.Name(text='js')))
     entry.title = atom.Title(text='my test entry')
     self.assert_(entry.author[0].name.text == 'js')
     self.assert_(entry.title.text == 'my test entry')
     new_entry = atom.EntryFromString(entry.ToString())
     self.assert_(new_entry.author[0].name.text == 'js')
     self.assert_(new_entry.title.text == 'my test entry')
    def __post(self, author, title, summary, content, category, draft,
               entryXml):
        """ to post the content to the server
        @param author: Author name
        @type author: String
        @param title: Title of the content
        @type title: String
        @param summary: Summary of the content
        @type summary: String
        @param content: Content 
        @type content: String
        @param draft: Type of the document:
        @type draft: boolean
        @param entryXml: extra entry
        @type entryXml: String
        
        @rtype: (Atom Entry, String)
        @return: entry, httpResponse
        """
        # create/update the atom entry
        if entryXml == None:
            entry = atom.Entry()
            entryUri = self.entryUri

        else:
            entry = atom.EntryFromString(entryXml)
            entryUri = entry.GetEditLink().href
        entry.author = [atom.Author(text=author)]
        entry.title = atom.Title(text=title)
        entry.summary = atom.Summary(text=summary)
        entry.content = atom.Content(content_type="html",
                                     text=unicode(content, "utf-8"))
        if category != "":
            entry.category = atom.Category(term=category)
        if draft:
            entry.control = atom.Control(draft=atom.Draft(text="yes"))
        else:
            entry.control = atom.Control(draft=atom.Draft(text="no"))
        # setup the http headers for authorisation
        extraHeaders = {"Slug": title}
        extraHeaders.update(self.authHeaders)
        # use POST or PUT depending on whether it is a new entry or an update
        if entryXml != None:
            publishFunc = self.atomService.Put
        else:
            publishFunc = self.atomService.Post
        self.__checkNoProxy(entryUri)
        httpResponse = publishFunc(data=entry,
                                   uri=entryUri,
                                   extra_headers=extraHeaders)
        self.__resetProxy()
        return entry, httpResponse
    def __getEntryForDocument(self, queryPath, id):
        """  
        @param queryPath: Query to search for the entry
        @type queryPath: String
        @param id: Id to be applied to atom feed
        @type id: String
        @rtype: ElementTree._Element, or xml_wrapper.ElementWrapper
        @return entry
        """
        docPath = self.rep.getPathForId(id)
        # check docPath
        if docPath.startswith(queryPath):
            item = self.rep.getItem(docPath)
            if item.hasHtml:
                docPath = self.iceContext.fs.splitExt(docPath)[0] + ".htm"
            title = item.getMeta("title")
            try:
                title = title.decode("utf-8")
            except:
                msg = "[Can not display title because of an encoding error!]"
                print "%s\n title='%s' path='%s'\n" % (msg, title, docPath)
                title = msg
            content = item.getRendition(".xhtml.body")
            if content is None:
                content = "<p>[Not rendered!]</p>"
            contentElem = ElementTree.XML(content)
            firstPara = contentElem.find("p")
            summary = "No summary"
            if firstPara != None:
                summary = ElementTree.tostring(firstPara)

            name = item.name
            lastModifiedTime = self.iceContext.fs.getModifiedTime(
                self.rep.getAbsPath(name))
            entryDate = datetime.fromtimestamp(
                lastModifiedTime).isoformat() + 'Z'
            srcUrl = "http://%s:%s%s" % (self.hostname, self.iceWebPort,
                                         docPath)

            entry = atom.Entry(title=atom.Title(text=title))
            entry.id = atom.Id(text="urn:uid:%s" % id)
            entry.link = [atom.Link(href=srcUrl, rel="alternate")]
            entry.updated = atom.Updated(text=entryDate)
            entry.published = atom.Published(text=entryDate)
            entry.summary = atom.Summary(summary_type="html",
                                         text=unicode(summary, "utf-8"))
            entry.content = atom.Content(content_type="html",
                                         text=unicode(content, "utf-8"))
            return entry
        else:
            return None
    def test_create_update_delete(self):
        if not conf.options.get_value('runlive') == 'true':
            return
        # Either load the recording or prepare to make a live request.
        conf.configure_cache(self.client, 'test_create_update_delete')

        blog_post = atom.Entry(
            title=atom.Title(text='test from python BloggerTest'),
            content=atom.Content(text='This is only a test.'))
        http_request = atom.http_core.HttpRequest()
        http_request.add_body_part(str(blog_post), 'application/atom+xml')

        def entry_from_string_wrapper(response):
            self.assertTrue(response.getheader('content-type') is not None)
            self.assertTrue(response.getheader('gdata-version') is not None)
            return atom.EntryFromString(response.read())

        entry = self.client.request(
            'POST',
            'http://www.blogger.com/feeds/%s/posts/default' %
            (conf.options.get_value('blogid')),
            converter=entry_from_string_wrapper,
            http_request=http_request)
        self.assertEqual(entry.title.text, 'test from python BloggerTest')
        self.assertEqual(entry.content.text, 'This is only a test.')

        # Edit the test entry.
        edit_link = None
        for link in entry.link:
            # Find the edit link for this entry.
            if link.rel == 'edit':
                edit_link = link.href
        entry.title.text = 'Edited'
        http_request = atom.http_core.HttpRequest()
        http_request.add_body_part(str(entry), 'application/atom+xml')
        edited_entry = self.client.request('PUT',
                                           edit_link,
                                           converter=entry_from_string_wrapper,
                                           http_request=http_request)
        self.assertEqual(edited_entry.title.text, 'Edited')
        self.assertEqual(edited_entry.content.text, entry.content.text)

        # Delete the test entry from the blog.
        edit_link = None
        for link in edited_entry.link:
            if link.rel == 'edit':
                edit_link = link.href
        response = self.client.request('DELETE', edit_link)
        self.assertEqual(response.status, 200)
Beispiel #6
0
    def test_create_update_delete(self):
        if not conf.settings.RUN_LIVE_TESTS:
            return
        # Either load the recording or prepare to make a live request.
        conf.configure_cache(self.client, 'test_create_update_delete')

        blog_post = atom.Entry(
            title=atom.Title(text=conf.settings.BloggerConfig.title),
            content=atom.Content(text=conf.settings.BloggerConfig.content))
        http_request = atom.http_core.HttpRequest()
        http_request.add_body_part(str(blog_post), 'application/atom+xml')

        def entry_from_string_wrapper(response):
            return atom.EntryFromString(response.read())

        entry = self.client.request(
            'POST',
            'http://www.blogger.com/feeds/%s/posts/default' %
            (conf.settings.BloggerConfig.blog_id),
            converter=entry_from_string_wrapper,
            http_request=http_request)
        self.assertEqual(entry.title.text, conf.settings.BloggerConfig.title)
        # TODO: uncomment once server bug is fixed
        #self.assertEqual(entry.content.text, conf.settings.BloggerConfig.content)

        # Edit the test entry.
        edit_link = None
        for link in entry.link:
            # Find the edit link for this entry.
            if link.rel == 'edit':
                edit_link = link.href
        entry.title.text = 'Edited'
        http_request = atom.http_core.HttpRequest()
        http_request.add_body_part(str(entry), 'application/atom+xml')
        edited_entry = self.client.request('PUT',
                                           edit_link,
                                           converter=entry_from_string_wrapper,
                                           http_request=http_request)
        self.assertEqual(edited_entry.title.text, 'Edited')
        # TODO: uncomment once server bug is fixed
        #self.assertEqual(edited_entry.content.text, entry.content.text)

        # Delete the test entry from the blog.
        edit_link = None
        for link in edited_entry.link:
            if link.rel == 'edit':
                edit_link = link.href
        response = self.client.request('DELETE', edit_link)
        self.assertEqual(response.status, 200)
def modifyBlogRedirectUrl(blog_id, proxy_url, client):
    """ Modifies the given blog settings to make the feed redirect to the given proxy. """

    # The basic idea here is to PUT a new value to the Atom entry defined at
    # /feeds/blogid/settings/BLOG_FEED_REDIRECT_URL, which updates it.  I'm not sure
    # why the code also needs to see the BLOG_FEED_REDIRECT_URL name in the id as well
    # as the POSTed URL...  anyway, this works and it's just for demo purposes:
    data = atom.Entry(
        atom_id=atom.Id(text='tag:blogger.com,1999:blog-' + blog_id +
                        '.settings.BLOG_FEED_REDIRECT_URL'),
        content=atom.Content(text=proxy_url)
    )  # The content of the setting is just the proxy URL
    logging.info("Data is: %s", data)
    uri = 'http://www.blogger.com/feeds/' + blog_id + '/settings/BLOG_FEED_REDIRECT_URL'
    client.blogger.Put(data, uri, extra_headers=None, url_params=None)
    def testConvertToAndFromElementTree(self):
        # Use entry because FeedEntryParent doesn't have a tag or namespace.
        original = atom.Entry()
        copy = atom.FeedEntryParent()

        original.author.append(atom.Author(name=atom.Name(text='J Scud')))
        self.assert_(original.author[0].name.text == 'J Scud')
        self.assert_(copy.author == [])

        original.id = atom.Id(text='test id')
        self.assert_(original.id.text == 'test id')
        self.assert_(copy.id is None)

        copy._HarvestElementTree(original._ToElementTree())
        self.assert_(original.author[0].name.text == copy.author[0].name.text)
        self.assert_(original.id.text == copy.id.text)
 def testConvertToAndFromString(self):
     feed = atom.Feed()
     feed.author.append(atom.Author(name=atom.Name(text='js')))
     feed.title = atom.Title(text='my test source')
     feed.generator = atom.Generator(text='gen')
     feed.entry.append(
         atom.Entry(
             author=[atom.Author(name=atom.Name(text='entry author'))]))
     self.assert_(feed.author[0].name.text == 'js')
     self.assert_(feed.title.text == 'my test source')
     self.assert_(feed.generator.text == 'gen')
     self.assert_(feed.entry[0].author[0].name.text == 'entry author')
     new_feed = atom.FeedFromString(feed.ToString())
     self.assert_(new_feed.author[0].name.text == 'js')
     self.assert_(new_feed.title.text == 'my test source')
     self.assert_(new_feed.generator.text == 'gen')
     self.assert_(new_feed.entry[0].author[0].name.text == 'entry author')
Beispiel #10
0
def test_feed():
    e_link = atom.Element(name="link",
                          href="http://example.org/2003/12/13/atom03")
    entry = atom.Entry(title="Atom-Powered Robots Run Amok",
                       link=e_link,
                       id="urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a",
                       updated="2003-12-13T18:30:02Z",
                       summary="Some text.")

    e_author = atom.Element(name="author")
    e_author.set_preverse_attrs("name", "John Doe")
    e_link = atom.Element(name="link", href="http://example.org/")
    feed = atom.Feed(title="Example Feed",
                     link=e_link,
                     updated="2003-12-13T18:30:02Z",
                     author=e_author,
                     id="urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6")
    feed.append_children(entry)

    buf = str(feed)
    #    assert buf == (
    #        "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
    #        "  <feed xmlns=\"http://www.w3.org/2005/Atom\">\n"
    #        "  <title>Example Feed</title>\n"
    #        "  <link href=\"http://example.org/\"/>\n"
    #        "  <updated>2003-12-13T18:30:02Z</updated>\n"
    #        "  <author>\n"
    #        "    <name>John Doe</name>\n"
    #        "  </author>\n"
    #        "  <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>\n"
    #        "  <entry>\n"
    #        "    <title>Atom-Powered Robots Run Amok</title>\n"
    #        "    <link href=\"http://example.org/2003/12/13/atom03\"/>\n"
    #        "    <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>\n"
    #        "    <updated>2003-12-13T18:30:02Z</updated>\n"
    #        "    <summary>Some text.</summary>\n"
    #        "  </entry>\n"
    #        "</feed>\n"
    #        )

    tree = etree.fromstring(buf)
Beispiel #11
0
def generate_feed(posts):
    author = atom.Author(name=settings['author'], email=settings['email'])
    entries = []
    for post in posts[:5]:
        # Rewrite post path into the weird id form I used to use.
        id = settings['id_base'] + '/' + (
            post.timestamp.strftime('%Y-%m-%d') + '/' +
            os.path.splitext(os.path.basename(post.path))[0])
        timestamp = post.timestamp + datetime.timedelta(seconds=time.timezone)
        entries.append(atom.Entry(timestamp=timestamp,
                                  id=id,
                                  title=post.title,
                                  link=settings['link'] + post.path,
                                  content=post.content))
    feed = atom.Feed(title=settings['title'],
                     id=settings['id_base'],
                     link=settings['link'],
                     selflink=settings['link'] + 'atom.xml',
                     author=author,
                     entries=entries)
    return feed.to_xml()
Beispiel #12
0
def test_entry():
    e_link = atom.Element(name="link", href="http://example.org/2003/12/13/atom03")
    entry = atom.Entry(title="Atom-Powered Robots Run Amok",
                       link = e_link,
                       id="urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a",
                       updated="2003-12-13T18:30:02Z",
                       summary="Some text.")
#    assert str(entry) == (
#        "<entry>\n"
#        "  <summary>Some text.</summary>\n"
#        "  <updated>2003-12-13T18:30:02Z</updated>\n"
#        "  <link href=\"http://example.org/2003/12/13/atom03\"/>\n"
#        "  <title>Atom-Powered Robots Run Amok</title>\n"
#        "  <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>\n"
#        "</entry>\n"
#        )

    tree = etree.fromstring(str(entry))
    assert tree.attrib == {}
    assert tree.tag == "entry"
    assert not tree.text.strip()
    assert len(tree.getchildren()) == 5

    e_summary = tree.xpath("/entry/summary")[0]
    assert e_summary.attrib == {}
    assert e_summary.tag == "summary"
    assert e_summary.text.strip() == "Some text."

    e_updated = tree.xpath("/entry/updated")[0]
    assert e_updated.attrib == {}
    assert e_updated.tag == "updated"
    assert e_updated.text.strip() == "2003-12-13T18:30:02Z"

    e_link = tree.xpath("/entry/link")[0]
    assert e_link.attrib == {'href' : "http://example.org/2003/12/13/atom03"}
    assert e_link.tag == "link"
    assert not e_link.text
Beispiel #13
0
 def post(self):
     entry = atom.Entry(content=atom.Content(text=self.request.get('body')))
     self.client.blogger.AddPost(entry, blog_id=self.request.get('id'))
Beispiel #14
0
    def post(self):
        # Take care of incoming salmon
        # pull out oauth token, fire up OAuth client, identify
        # the particular post in question and its comment stream,
        # create an entry, and post a comment.
        blog_id = self.request.get('id')

        body = self.request.body.decode('utf-8')

        logging.info('Salmon body is:\n%s\n----', body)

        data = feedparser.parse(body)
        logging.info('Data parsed was:\n%s\n----', data)
        if data.bozo:
            logging.error('Bozo feed data. %s: %r',
                          data.bozo_exception.__class__.__name__,
                          data.bozo_exception)
            if (hasattr(data.bozo_exception, 'getLineNumber')
                    and hasattr(data.bozo_exception, 'getMessage')):
                line = data.bozo_exception.getLineNumber()
                logging.error('Line %d: %s', line,
                              data.bozo_exception.getMessage())
            return self.response.set_status(400)

        logging.info('Found %d entries', len(data.entries))
        for entry in data.entries:
            s = model.makeEntry(entry)

            referents = model.getTopicsOf(s)

            logging.info('Saw %d parent(s)', referents.count())
            if referents.count() == 0:
                logging.info(
                    'No parent found for %s, returning error to client.',
                    s.entry_id)
                self.response.set_status(400)
                self.response.out.write('Bad Salmon, no parent with id ' +
                                        unicode(s.in_reply_to) +
                                        ' found -- rejected.\n')
                return

        # Pull body & other info out of salmon

        # Create an Atom entry and post as a comment
        text = s.content
        # TODO: Fix Blogger so it accepts acct: URIs... sigh...
        name = re.sub("(..\@.+)", "...", s.author_name)
        author_uri = "http://example.org/profile/" + name
        #if author_uri.startswith("acct:"):
        #  author_uri = author_uri.replace("acct:","http://")
        text = text + ' by <a href="' + author_uri + '">' + name + '</a>'
        entry = atom.Entry(content=atom.Content(text=text))

        # Grab the entry ID from the in-reply-to element of the salmon
        p = re.compile('tag:blogger\.com,1999:blog-(\d+)\.post-(\d+)')
        m = p.match(s.in_reply_to)
        if not m:
            self.response.set_status(400)
            return
        blog_id = m.group(1)
        post_id = m.group(2)

        logging.info("About to post comment to blog %s, post %s", blog_id,
                     post_id)

        # Grab auth info from DB (this is also an ACL check...)
        bp = BlogProxy.all().filter('blog_id =', blog_id).fetch(1)[0]
        origfeed = bp.feed_uri
        tokens = pickle.loads(bp.pickled_tokens)
        oauth_token = tokens["http://www.blogger.com/feeds/"]
        # TODO: Add some error checking, for Ghu's sake.

        # Let's see if override_token, at least, does what it says in this hall of
        # funhouse mirrors we call a GData client:
        self.client.blogger.override_token = oauth_token
        logging.info("Auth token = %s, override_token = %s", oauth_token,
                     self.client.blogger.override_token)
        self.client.blogger.AddComment(entry, blog_id=blog_id, post_id=post_id)
        self.response.out.write("Salmon accepted, sent upstream to source!\n")
        self.response.set_status(200)