<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="../assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Sean Gillies (Posts about zope)</title><link>https://sgillies.net/</link><description></description><atom:link href="https://sgillies.net/tags/zope.xml" rel="self" type="application/rss+xml"></atom:link><language>en</language><lastBuildDate>Sun, 31 Dec 2023 01:26:22 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>Migration of my blog</title><link>https://sgillies.net/2015/11/29/migration-of-my-blog.html</link><dc:creator>Sean Gillies</dc:creator><description>&lt;p&gt;A while back I switched my blog from a database-backed dynamic site to static
HTML generated by Sphinx and Tinkerer. This weekend I finished migrating eight
years of old posts (with their comments) to the new blog. And I configured my
new blog and home page to support HTTPS. Hello, 2015.&lt;/p&gt;
&lt;p&gt;You may, when visiting old posts, experience browser warnings because of
embedded HTTP resources. Images mainly, but also the odd script here and there.
I have also not yet implemented the redirect rules that will get you from old
style &lt;code class="docutils literal"&gt;number/slug&lt;/code&gt; URLs to the new &lt;code class="docutils literal"&gt;YYYY/MM/DD/slug&lt;/code&gt; URLs, though I have
mapped them all out. Please bear with me, I'll address these issues soon.&lt;/p&gt;
&lt;p&gt;Doing this lets me retire my last dedicated server. My blog now runs on a very
cheap ($5 per month) virtual server provisioned (Nginx, SSL certs and keys, the
works) using Ansible. I build my blog HTML on my laptop and rsync it with the
server also using Ansible.&lt;/p&gt;
&lt;p&gt;I'm pretty sure this blog migration is the final chapter of my Zope story. The
following is very likely my final Zope external method, ever.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code python"&gt;&lt;a id="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-1" name="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-1" href="https://sgillies.net/2015/11/29/migration-of-my-blog.html#rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-1"&gt;&lt;/a&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;json&lt;/span&gt;
&lt;a id="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-2" name="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-2" href="https://sgillies.net/2015/11/29/migration-of-my-blog.html#rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-2"&gt;&lt;/a&gt;
&lt;a id="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-3" name="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-3" href="https://sgillies.net/2015/11/29/migration-of-my-blog.html#rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-3"&gt;&lt;/a&gt;
&lt;a id="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-4" name="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-4" href="https://sgillies.net/2015/11/29/migration-of-my-blog.html#rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-4"&gt;&lt;/a&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;dumper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;a id="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-5" name="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-5" href="https://sgillies.net/2015/11/29/migration-of-my-blog.html#rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-5"&gt;&lt;/a&gt;    &lt;span class="sd"&gt;"""Dump Python blog posts to JSON"""&lt;/span&gt;
&lt;a id="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-6" name="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-6" href="https://sgillies.net/2015/11/29/migration-of-my-blog.html#rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-6"&gt;&lt;/a&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;searchResults&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;a id="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-7" name="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-7" href="https://sgillies.net/2015/11/29/migration-of-my-blog.html#rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-7"&gt;&lt;/a&gt;            &lt;span class="n"&gt;meta_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'COREBlog Entry'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sort_on&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'created'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;a id="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-8" name="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-8" href="https://sgillies.net/2015/11/29/migration-of-my-blog.html#rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-8"&gt;&lt;/a&gt;            &lt;span class="n"&gt;sort_order&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'descending'&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;a id="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-9" name="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-9" href="https://sgillies.net/2015/11/29/migration-of-my-blog.html#rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-9"&gt;&lt;/a&gt;        &lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getObject&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;a id="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-10" name="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-10" href="https://sgillies.net/2015/11/29/migration-of-my-blog.html#rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-10"&gt;&lt;/a&gt;
&lt;a id="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-11" name="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-11" href="https://sgillies.net/2015/11/29/migration-of-my-blog.html#rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-11"&gt;&lt;/a&gt;        &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;a id="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-12" name="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-12" href="https://sgillies.net/2015/11/29/migration-of-my-blog.html#rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-12"&gt;&lt;/a&gt;        &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;
&lt;a id="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-13" name="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-13" href="https://sgillies.net/2015/11/29/migration-of-my-blog.html#rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-13"&gt;&lt;/a&gt;        &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'slug'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;entry_slug&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;a id="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-14" name="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-14" href="https://sgillies.net/2015/11/29/migration-of-my-blog.html#rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-14"&gt;&lt;/a&gt;        &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'title'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title_or_id&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;a id="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-15" name="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-15" href="https://sgillies.net/2015/11/29/migration-of-my-blog.html#rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-15"&gt;&lt;/a&gt;        &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'body'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;
&lt;a id="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-16" name="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-16" href="https://sgillies.net/2015/11/29/migration-of-my-blog.html#rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-16"&gt;&lt;/a&gt;        &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'categories'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;categories&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;a id="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-17" name="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-17" href="https://sgillies.net/2015/11/29/migration-of-my-blog.html#rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-17"&gt;&lt;/a&gt;        &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'published'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;published&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;a id="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-18" name="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-18" href="https://sgillies.net/2015/11/29/migration-of-my-blog.html#rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-18"&gt;&lt;/a&gt;        &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'html'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-19" name="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-19" href="https://sgillies.net/2015/11/29/migration-of-my-blog.html#rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-19"&gt;&lt;/a&gt;
&lt;a id="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-20" name="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-20" href="https://sgillies.net/2015/11/29/migration-of-my-blog.html#rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-20"&gt;&lt;/a&gt;        &lt;span class="n"&gt;coms&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;a id="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-21" name="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-21" href="https://sgillies.net/2015/11/29/migration-of-my-blog.html#rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-21"&gt;&lt;/a&gt;        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;comment&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;comment_list&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;a id="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-22" name="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-22" href="https://sgillies.net/2015/11/29/migration-of-my-blog.html#rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-22"&gt;&lt;/a&gt;            &lt;span class="n"&gt;com&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;a id="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-23" name="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-23" href="https://sgillies.net/2015/11/29/migration-of-my-blog.html#rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-23"&gt;&lt;/a&gt;            &lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'title'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;comment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;
&lt;a id="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-24" name="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-24" href="https://sgillies.net/2015/11/29/migration-of-my-blog.html#rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-24"&gt;&lt;/a&gt;            &lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'author'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;comment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;author&lt;/span&gt;
&lt;a id="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-25" name="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-25" href="https://sgillies.net/2015/11/29/migration-of-my-blog.html#rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-25"&gt;&lt;/a&gt;            &lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'url'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;comment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;
&lt;a id="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-26" name="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-26" href="https://sgillies.net/2015/11/29/migration-of-my-blog.html#rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-26"&gt;&lt;/a&gt;            &lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'body'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;comment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;
&lt;a id="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-27" name="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-27" href="https://sgillies.net/2015/11/29/migration-of-my-blog.html#rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-27"&gt;&lt;/a&gt;            &lt;span class="n"&gt;coms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-28" name="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-28" href="https://sgillies.net/2015/11/29/migration-of-my-blog.html#rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-28"&gt;&lt;/a&gt;        &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'comments'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;coms&lt;/span&gt;
&lt;a id="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-29" name="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-29" href="https://sgillies.net/2015/11/29/migration-of-my-blog.html#rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-29"&gt;&lt;/a&gt;
&lt;a id="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-30" name="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-30" href="https://sgillies.net/2015/11/29/migration-of-my-blog.html#rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-30"&gt;&lt;/a&gt;        &lt;span class="n"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;published&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'T'&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;a id="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-31" name="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-31" href="https://sgillies.net/2015/11/29/migration-of-my-blog.html#rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-31"&gt;&lt;/a&gt;        &lt;span class="n"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'-'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-32" name="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-32" href="https://sgillies.net/2015/11/29/migration-of-my-blog.html#rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-32"&gt;&lt;/a&gt;
&lt;a id="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-33" name="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-33" href="https://sgillies.net/2015/11/29/migration-of-my-blog.html#rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-33"&gt;&lt;/a&gt;        &lt;span class="n"&gt;outfilename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'/tmp/blog/&lt;/span&gt;&lt;span class="si"&gt;{0}&lt;/span&gt;&lt;span class="s1"&gt;-&lt;/span&gt;&lt;span class="si"&gt;{1}&lt;/span&gt;&lt;span class="s1"&gt;-&lt;/span&gt;&lt;span class="si"&gt;{2}&lt;/span&gt;&lt;span class="s1"&gt;.json'&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;a id="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-34" name="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-34" href="https://sgillies.net/2015/11/29/migration-of-my-blog.html#rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-34"&gt;&lt;/a&gt;            &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;entry_slug&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;a id="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-35" name="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-35" href="https://sgillies.net/2015/11/29/migration-of-my-blog.html#rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-35"&gt;&lt;/a&gt;
&lt;a id="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-36" name="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-36" href="https://sgillies.net/2015/11/29/migration-of-my-blog.html#rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-36"&gt;&lt;/a&gt;        &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;outfilename&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'w'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;a id="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-37" name="rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-37" href="https://sgillies.net/2015/11/29/migration-of-my-blog.html#rest_code_d5fafd6b6eee40f5a2e80bd3e11dc1dd-37"&gt;&lt;/a&gt;            &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;indent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;</description><category>ansible</category><category>https</category><category>life</category><category>python</category><category>restructuredtext</category><category>tinkerer</category><category>zope</category><guid>https://sgillies.net/2015/11/29/migration-of-my-blog.html</guid><pubDate>Sun, 29 Nov 2015 07:00:00 GMT</pubDate></item><item><title>Lessons learned from Zope</title><link>https://sgillies.net/2011/12/21/lessons-learned-from-zope.html</link><dc:creator>Sean Gillies</dc:creator><description>&lt;p&gt;&lt;a class="reference external" href="http://plope.com/Members/chrism/in_defense_of_zope_libraries"&gt;Chris McDonough&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Most developers are very, very risk-averse. They like taking small steps, or
no steps at all. You have to allow them to consume familiar technologies and
allow them to disuse things that get in their way.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The allure of a completely integrated, monolithic system that effectively
prevents the use of alternate development techniques and technologies
eventually wears off. And when it does, it wears off with a vengeance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The natural reaction to the problems caused by monolithic systems, which is
to make anything and everything uniformly "pluggable" is also a net lose.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tests are very important.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation is even more important than tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When trying to replace a complex system, make it simpler, don't just push the
complexity around.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Brands are important. You, ideally, must make sure that the question "what is
'noun'" have one answer. Sublety and branding do not mix; they produce
a toxic haze of confusion.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;My story with Zope parallels Chris's, though not as nearly as deep, and
trailing by about a year and a half. I've been using his software and docs for
about a decade now. For the past 4-5 years I've been trying to apply the Zope
lessons above to GIS software; Shapely and Fiona are thoroughly steeped in
them.&lt;/p&gt;</description><category>programming</category><category>python</category><category>work</category><category>zope</category><guid>https://sgillies.net/2011/12/21/lessons-learned-from-zope.html</guid><pubDate>Wed, 21 Dec 2011 07:00:00 GMT</pubDate></item><item><title>Versioning in Pleiades scripts</title><link>https://sgillies.net/2010/12/30/versioning-in-pleiades-scripts.html</link><dc:creator>Sean Gillies</dc:creator><description>&lt;p&gt;In preparing for a few rounds of large Pleiades coordinate updates in the next
few weeks, I've been rediscovering zopectl's &lt;em&gt;run&lt;/em&gt; command. It lets you run
a script in the context of your database:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code console"&gt;&lt;a id="rest_code_f07ca66c65594c37a424fb95f8796f33-1" name="rest_code_f07ca66c65594c37a424fb95f8796f33-1" href="https://sgillies.net/2010/12/30/versioning-in-pleiades-scripts.html#rest_code_f07ca66c65594c37a424fb95f8796f33-1"&gt;&lt;/a&gt;&lt;span class="gp"&gt;$ &lt;/span&gt;zopectl run script.py
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;much like &lt;em&gt;psql&lt;/em&gt; (for example) lets you run a script on your Postgres database:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code console"&gt;&lt;a id="rest_code_0a848cd8eab14f9681a2e9920ba9ef49-1" name="rest_code_0a848cd8eab14f9681a2e9920ba9ef49-1" href="https://sgillies.net/2010/12/30/versioning-in-pleiades-scripts.html#rest_code_0a848cd8eab14f9681a2e9920ba9ef49-1"&gt;&lt;/a&gt;&lt;span class="gp"&gt;$ &lt;/span&gt;psql -f script.sql
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The main differences are that with zopectl your script is Python, not SQL, and
that the data is a arbitrarily large and nested mapping bound to the name &lt;code class="docutils literal"&gt;app&lt;/code&gt;
instead of tables. Imagine your dataset is a giant JSON structure: that covers
much of what developing with the ZODB (Zope object database) is like. The ZODB
is stored as an append-only B-Tree and enjoys many of the benefits explained in
the &lt;a class="reference external" href="http://guide.couchdb.org/draft/btree.html"&gt;CouchDB Guide&lt;/a&gt;. The essential similarities and differences between ZODB
and CouchDB were summarized two years ago by Chris McDonough &lt;a class="reference external" href="http://plope.com/Members/chrism/wherefore_couchdb"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A key feature of Pleiades is resource versioning. There's a repository tool in
which we track changes to places, names, and locations; it even provides diffs
between versions. I found out before the holiday that a Plone developer
(Pleiades uses Plone 3.2, and your mileage may vary) has to take a few extra
steps to setup supporting utilities for the repository tool in the case of an
offline script.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code python"&gt;&lt;a id="rest_code_5b8a30705acb4645866f020f8ad7b110-1" name="rest_code_5b8a30705acb4645866f020f8ad7b110-1" href="https://sgillies.net/2010/12/30/versioning-in-pleiades-scripts.html#rest_code_5b8a30705acb4645866f020f8ad7b110-1"&gt;&lt;/a&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;Products.CMFCore.utils&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;getToolByName&lt;/span&gt;
&lt;a id="rest_code_5b8a30705acb4645866f020f8ad7b110-2" name="rest_code_5b8a30705acb4645866f020f8ad7b110-2" href="https://sgillies.net/2010/12/30/versioning-in-pleiades-scripts.html#rest_code_5b8a30705acb4645866f020f8ad7b110-2"&gt;&lt;/a&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;Products.CMFUid.interfaces&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;a id="rest_code_5b8a30705acb4645866f020f8ad7b110-3" name="rest_code_5b8a30705acb4645866f020f8ad7b110-3" href="https://sgillies.net/2010/12/30/versioning-in-pleiades-scripts.html#rest_code_5b8a30705acb4645866f020f8ad7b110-3"&gt;&lt;/a&gt;    &lt;span class="n"&gt;IUniqueIdGenerator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IUniqueIdAnnotationManagement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IUniqueIdHandler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_5b8a30705acb4645866f020f8ad7b110-4" name="rest_code_5b8a30705acb4645866f020f8ad7b110-4" href="https://sgillies.net/2010/12/30/versioning-in-pleiades-scripts.html#rest_code_5b8a30705acb4645866f020f8ad7b110-4"&gt;&lt;/a&gt;
&lt;a id="rest_code_5b8a30705acb4645866f020f8ad7b110-5" name="rest_code_5b8a30705acb4645866f020f8ad7b110-5" href="https://sgillies.net/2010/12/30/versioning-in-pleiades-scripts.html#rest_code_5b8a30705acb4645866f020f8ad7b110-5"&gt;&lt;/a&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;zope.component&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;provideUtility&lt;/span&gt;
&lt;a id="rest_code_5b8a30705acb4645866f020f8ad7b110-6" name="rest_code_5b8a30705acb4645866f020f8ad7b110-6" href="https://sgillies.net/2010/12/30/versioning-in-pleiades-scripts.html#rest_code_5b8a30705acb4645866f020f8ad7b110-6"&gt;&lt;/a&gt;
&lt;a id="rest_code_5b8a30705acb4645866f020f8ad7b110-7" name="rest_code_5b8a30705acb4645866f020f8ad7b110-7" href="https://sgillies.net/2010/12/30/versioning-in-pleiades-scripts.html#rest_code_5b8a30705acb4645866f020f8ad7b110-7"&gt;&lt;/a&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;setup_cmfuid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;a id="rest_code_5b8a30705acb4645866f020f8ad7b110-8" name="rest_code_5b8a30705acb4645866f020f8ad7b110-8" href="https://sgillies.net/2010/12/30/versioning-in-pleiades-scripts.html#rest_code_5b8a30705acb4645866f020f8ad7b110-8"&gt;&lt;/a&gt;    &lt;span class="n"&gt;provideUtility&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;a id="rest_code_5b8a30705acb4645866f020f8ad7b110-9" name="rest_code_5b8a30705acb4645866f020f8ad7b110-9" href="https://sgillies.net/2010/12/30/versioning-in-pleiades-scripts.html#rest_code_5b8a30705acb4645866f020f8ad7b110-9"&gt;&lt;/a&gt;        &lt;span class="n"&gt;getToolByName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'portal_uidgenerator'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;IUniqueIdGenerator&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_5b8a30705acb4645866f020f8ad7b110-10" name="rest_code_5b8a30705acb4645866f020f8ad7b110-10" href="https://sgillies.net/2010/12/30/versioning-in-pleiades-scripts.html#rest_code_5b8a30705acb4645866f020f8ad7b110-10"&gt;&lt;/a&gt;    &lt;span class="n"&gt;provideUtility&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;a id="rest_code_5b8a30705acb4645866f020f8ad7b110-11" name="rest_code_5b8a30705acb4645866f020f8ad7b110-11" href="https://sgillies.net/2010/12/30/versioning-in-pleiades-scripts.html#rest_code_5b8a30705acb4645866f020f8ad7b110-11"&gt;&lt;/a&gt;        &lt;span class="n"&gt;getToolByName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'portal_uidannotation'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;a id="rest_code_5b8a30705acb4645866f020f8ad7b110-12" name="rest_code_5b8a30705acb4645866f020f8ad7b110-12" href="https://sgillies.net/2010/12/30/versioning-in-pleiades-scripts.html#rest_code_5b8a30705acb4645866f020f8ad7b110-12"&gt;&lt;/a&gt;        &lt;span class="n"&gt;IUniqueIdAnnotationManagement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_5b8a30705acb4645866f020f8ad7b110-13" name="rest_code_5b8a30705acb4645866f020f8ad7b110-13" href="https://sgillies.net/2010/12/30/versioning-in-pleiades-scripts.html#rest_code_5b8a30705acb4645866f020f8ad7b110-13"&gt;&lt;/a&gt;    &lt;span class="n"&gt;provideUtility&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;a id="rest_code_5b8a30705acb4645866f020f8ad7b110-14" name="rest_code_5b8a30705acb4645866f020f8ad7b110-14" href="https://sgillies.net/2010/12/30/versioning-in-pleiades-scripts.html#rest_code_5b8a30705acb4645866f020f8ad7b110-14"&gt;&lt;/a&gt;        &lt;span class="n"&gt;getToolByName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'portal_uidhandler'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;IUniqueIdHandler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now I call this function in my script and the repository tool is ready for use.
The login() function makes sure that all changes are made as the specified user
(me, in this case) and bulk_update_locations() updates the coordinates from
a number of CSV records within a single transaction, annotating each version
change with a message.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code python"&gt;&lt;a id="rest_code_6716321a7adf42479f74cdd84a94afb9-1" name="rest_code_6716321a7adf42479f74cdd84a94afb9-1" href="https://sgillies.net/2010/12/30/versioning-in-pleiades-scripts.html#rest_code_6716321a7adf42479f74cdd84a94afb9-1"&gt;&lt;/a&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;pleiades.bulkup&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;login&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;setup_cmfuid&lt;/span&gt;
&lt;a id="rest_code_6716321a7adf42479f74cdd84a94afb9-2" name="rest_code_6716321a7adf42479f74cdd84a94afb9-2" href="https://sgillies.net/2010/12/30/versioning-in-pleiades-scripts.html#rest_code_6716321a7adf42479f74cdd84a94afb9-2"&gt;&lt;/a&gt;
&lt;a id="rest_code_6716321a7adf42479f74cdd84a94afb9-3" name="rest_code_6716321a7adf42479f74cdd84a94afb9-3" href="https://sgillies.net/2010/12/30/versioning-in-pleiades-scripts.html#rest_code_6716321a7adf42479f74cdd84a94afb9-3"&gt;&lt;/a&gt;&lt;span class="n"&gt;site&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'plone'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;a id="rest_code_6716321a7adf42479f74cdd84a94afb9-4" name="rest_code_6716321a7adf42479f74cdd84a94afb9-4" href="https://sgillies.net/2010/12/30/versioning-in-pleiades-scripts.html#rest_code_6716321a7adf42479f74cdd84a94afb9-4"&gt;&lt;/a&gt;&lt;span class="n"&gt;setup_cmfuid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_6716321a7adf42479f74cdd84a94afb9-5" name="rest_code_6716321a7adf42479f74cdd84a94afb9-5" href="https://sgillies.net/2010/12/30/versioning-in-pleiades-scripts.html#rest_code_6716321a7adf42479f74cdd84a94afb9-5"&gt;&lt;/a&gt;&lt;span class="n"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_6716321a7adf42479f74cdd84a94afb9-6" name="rest_code_6716321a7adf42479f74cdd84a94afb9-6" href="https://sgillies.net/2010/12/30/versioning-in-pleiades-scripts.html#rest_code_6716321a7adf42479f74cdd84a94afb9-6"&gt;&lt;/a&gt;&lt;span class="n"&gt;bulk_update_locations&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;columns&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Mikko Ohtamaa's &lt;a class="reference external" href="http://plone.org/documentation/manual/plone-community-developer-documentation/misc/commandline"&gt;Command-line interaction and scripting&lt;/a&gt; helped me learn how
to set the effective user (or login), but didn't explain why the 3 Plone tools
in my case weren't being automatically registered.&lt;/p&gt;</description><category>pleiades</category><category>plone</category><category>work</category><category>zope</category><guid>https://sgillies.net/2010/12/30/versioning-in-pleiades-scripts.html</guid><pubDate>Thu, 30 Dec 2010 07:00:00 GMT</pubDate></item><item><title>Shapely 1.0.8</title><link>https://sgillies.net/2008/11/01/shapely-1-0-8.html</link><dc:creator>Sean Gillies</dc:creator><description>&lt;p&gt;Paul Winkler and the &lt;a class="reference external" href="http://opengeo.org/"&gt;OpenGeo&lt;/a&gt; team found a problem with Shapely and Zope's web server on their 64-bit system, provided the fix, and now here's &lt;a class="reference external" href="http://pypi.python.org/pypi/Shapely/1.0.8"&gt;Shapely 1.0.8&lt;/a&gt;. An upgrade is recommended if you're using Zope or a similar framework.&lt;/p&gt;
&lt;section id="comments"&gt;
&lt;h2&gt;Comments&lt;/h2&gt;
&lt;section id="re-shapely-1-0-8"&gt;
&lt;h3&gt;Re: Shapely 1.0.8&lt;/h3&gt;
&lt;p&gt;Author: &lt;a class="reference external" href="http://www.openplans.org/people/slinkp"&gt;Paul Winkler&lt;/a&gt;&lt;/p&gt;
Hi Sean, thanks for the kind words and getting an official fix out so quickly. I must give credit where due: All the hard gdb sleuthing was led by my coworkers David Turner and Douglas Mayle. I don't have the necessary C/C++ chops to have solved this on my own.

Oh, and to clarify, the problem had nothing to do with Zope (or Grok in our case), this upgrade should be good for anyone running on a 64-bit system. I was eventually able to write a standalone script that demonstrated the segfault.

The same problem could afflict any python package that uses Ctypes on 64-bit systems without explicitly marking argument and return types.&lt;/section&gt;
&lt;/section&gt;</description><category>the lab</category><category>work</category><category>zope</category><guid>https://sgillies.net/2008/11/01/shapely-1-0-8.html</guid><pubDate>Sat, 01 Nov 2008 06:00:00 GMT</pubDate></item><item><title>Adding pyproj to a buildout</title><link>https://sgillies.net/2008/09/18/adding-pyproj-to-a-buildout.html</link><dc:creator>Sean Gillies</dc:creator><description>&lt;p&gt;&lt;a class="reference external" href="http://code.google.com/p/pyproj/"&gt;Pyproj&lt;/a&gt; is Jeffrey Whitaker's Python interface to PROJ.4. I'm no longer interested in other Python projection packages. Its most interesting feature is interoperability with packages (such as Shapely) that use the Numpy array interface. It depends on Cython, which makes it a bit tricky to include in a buildout: you must install Cython into your buildout's python, not as an egg, and make the pyproj egg only after this step is finished. Like this:&lt;/p&gt;
&lt;aside class="system-message"&gt;
&lt;p class="system-message-title"&gt;System Message: ERROR/3 (&lt;span class="docutils literal"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;, line 3)&lt;/p&gt;
&lt;p&gt;Cannot find pygments lexer for language "none"&lt;/p&gt;
&lt;pre class="literal-block"&gt;.. sourcecode:: none

  [buildout]
  parts =
    cython-src
    cython-install
    pyproj

  [cython-src]
  recipe = hexagonit.recipe.download
  url = http://cython.org/Cython-0.9.8.1.1.tar.gz

  [cython-install]
  recipe = iw.recipe.cmd
  on_install = true
  cmds =
    cd ${buildout:directory}/parts/cython-src/Cython-0.9.8.1.1
    ${python:executable} setup.py install

  [pyproj]
  recipe = zc.recipe.egg:eggs
  index = http://atlantides.org/eggcarton/index
  eggs = pyproj
&lt;/pre&gt;
&lt;/aside&gt;
&lt;p&gt;You might be able to pull pyproj off PyPI, but here I am using my own index. Once built, you can try it out using zopepy:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code pycon"&gt;&lt;a id="rest_code_f24068c36ff045f88a37e54ffbf6470d-1" name="rest_code_f24068c36ff045f88a37e54ffbf6470d-1" href="https://sgillies.net/2008/09/18/adding-pyproj-to-a-buildout.html#rest_code_f24068c36ff045f88a37e54ffbf6470d-1"&gt;&lt;/a&gt;&lt;span class="gp"&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;pyproj&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Proj&lt;/span&gt;
&lt;a id="rest_code_f24068c36ff045f88a37e54ffbf6470d-2" name="rest_code_f24068c36ff045f88a37e54ffbf6470d-2" href="https://sgillies.net/2008/09/18/adding-pyproj-to-a-buildout.html#rest_code_f24068c36ff045f88a37e54ffbf6470d-2"&gt;&lt;/a&gt;&lt;span class="gp"&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;defn_900913&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"""&lt;/span&gt;
&lt;a id="rest_code_f24068c36ff045f88a37e54ffbf6470d-3" name="rest_code_f24068c36ff045f88a37e54ffbf6470d-3" href="https://sgillies.net/2008/09/18/adding-pyproj-to-a-buildout.html#rest_code_f24068c36ff045f88a37e54ffbf6470d-3"&gt;&lt;/a&gt;&lt;span class="gp"&gt;... &lt;/span&gt;&lt;span class="s2"&gt;+proj=merc +a=6378137 +b=6378137&lt;/span&gt;
&lt;a id="rest_code_f24068c36ff045f88a37e54ffbf6470d-4" name="rest_code_f24068c36ff045f88a37e54ffbf6470d-4" href="https://sgillies.net/2008/09/18/adding-pyproj-to-a-buildout.html#rest_code_f24068c36ff045f88a37e54ffbf6470d-4"&gt;&lt;/a&gt;&lt;span class="gp"&gt;... &lt;/span&gt;&lt;span class="s2"&gt;+lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0&lt;/span&gt;
&lt;a id="rest_code_f24068c36ff045f88a37e54ffbf6470d-5" name="rest_code_f24068c36ff045f88a37e54ffbf6470d-5" href="https://sgillies.net/2008/09/18/adding-pyproj-to-a-buildout.html#rest_code_f24068c36ff045f88a37e54ffbf6470d-5"&gt;&lt;/a&gt;&lt;span class="gp"&gt;... &lt;/span&gt;&lt;span class="s2"&gt;+units=m +nadgrids=@null +no_defs&lt;/span&gt;
&lt;a id="rest_code_f24068c36ff045f88a37e54ffbf6470d-6" name="rest_code_f24068c36ff045f88a37e54ffbf6470d-6" href="https://sgillies.net/2008/09/18/adding-pyproj-to-a-buildout.html#rest_code_f24068c36ff045f88a37e54ffbf6470d-6"&gt;&lt;/a&gt;&lt;span class="gp"&gt;... &lt;/span&gt;&lt;span class="s2"&gt;"""&lt;/span&gt;
&lt;a id="rest_code_f24068c36ff045f88a37e54ffbf6470d-7" name="rest_code_f24068c36ff045f88a37e54ffbf6470d-7" href="https://sgillies.net/2008/09/18/adding-pyproj-to-a-buildout.html#rest_code_f24068c36ff045f88a37e54ffbf6470d-7"&gt;&lt;/a&gt;&lt;span class="gp"&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;proj_900913&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Proj&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;defn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_f24068c36ff045f88a37e54ffbf6470d-8" name="rest_code_f24068c36ff045f88a37e54ffbf6470d-8" href="https://sgillies.net/2008/09/18/adding-pyproj-to-a-buildout.html#rest_code_f24068c36ff045f88a37e54ffbf6470d-8"&gt;&lt;/a&gt;&lt;span class="gp"&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;lonlat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;25.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;25.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_f24068c36ff045f88a37e54ffbf6470d-9" name="rest_code_f24068c36ff045f88a37e54ffbf6470d-9" href="https://sgillies.net/2008/09/18/adding-pyproj-to-a-buildout.html#rest_code_f24068c36ff045f88a37e54ffbf6470d-9"&gt;&lt;/a&gt;&lt;span class="gp"&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;proj_900913&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;lonlat&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_f24068c36ff045f88a37e54ffbf6470d-10" name="rest_code_f24068c36ff045f88a37e54ffbf6470d-10" href="https://sgillies.net/2008/09/18/adding-pyproj-to-a-buildout.html#rest_code_f24068c36ff045f88a37e54ffbf6470d-10"&gt;&lt;/a&gt;&lt;span class="go"&gt;(2782987.269831839, 2875744.6243522423)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I like that projection definitions can be split across lines of the screen.&lt;/p&gt;</description><category>python</category><category>work</category><category>zope</category><guid>https://sgillies.net/2008/09/18/adding-pyproj-to-a-buildout.html</guid><pubDate>Thu, 18 Sep 2008 06:00:00 GMT</pubDate></item><item><title>AtomPub for zgeo.atom</title><link>https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html</link><dc:creator>Sean Gillies</dc:creator><description>&lt;p&gt;I've rewritten Knowhere's AtomPub implementation, dropping the Grok skin traversal mechanism in favor of a custom publisher and customized traverser. I've gained harmony among the various resource URLs and learned a ton about publishing in Zope. Now, zgeo.atom has an incomplete, but functional Atom publishing protocol. A collection is currently online at&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://sgillies.net/kw/demo/atompub-collection"&gt;http://sgillies.net/kw/demo/atompub-collection&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The curious are free to add new placemark entries and edit them following the steps below.&lt;/p&gt;
&lt;p&gt;First, create a file called &lt;em&gt;test.atom&lt;/em&gt; with contents something like this:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code xml"&gt;&lt;a id="rest_code_3e4d51d76e72451a8e4baec7610d4bda-1" name="rest_code_3e4d51d76e72451a8e4baec7610d4bda-1" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_3e4d51d76e72451a8e4baec7610d4bda-1"&gt;&lt;/a&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_3e4d51d76e72451a8e4baec7610d4bda-2" name="rest_code_3e4d51d76e72451a8e4baec7610d4bda-2" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_3e4d51d76e72451a8e4baec7610d4bda-2"&gt;&lt;/a&gt;&lt;span class="nt"&gt;&amp;lt;entry&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2005/Atom"&lt;/span&gt;
&lt;a id="rest_code_3e4d51d76e72451a8e4baec7610d4bda-3" name="rest_code_3e4d51d76e72451a8e4baec7610d4bda-3" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_3e4d51d76e72451a8e4baec7610d4bda-3"&gt;&lt;/a&gt;       &lt;span class="na"&gt;xmlns:georss=&lt;/span&gt;&lt;span class="s"&gt;"http://www.georss.org/georss"&lt;/span&gt;
&lt;a id="rest_code_3e4d51d76e72451a8e4baec7610d4bda-4" name="rest_code_3e4d51d76e72451a8e4baec7610d4bda-4" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_3e4d51d76e72451a8e4baec7610d4bda-4"&gt;&lt;/a&gt;       &lt;span class="na"&gt;xmlns:gml=&lt;/span&gt;&lt;span class="s"&gt;"http://www.opengis.net/gml"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_3e4d51d76e72451a8e4baec7610d4bda-5" name="rest_code_3e4d51d76e72451a8e4baec7610d4bda-5" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_3e4d51d76e72451a8e4baec7610d4bda-5"&gt;&lt;/a&gt;  &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Test&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_3e4d51d76e72451a8e4baec7610d4bda-6" name="rest_code_3e4d51d76e72451a8e4baec7610d4bda-6" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_3e4d51d76e72451a8e4baec7610d4bda-6"&gt;&lt;/a&gt;  &lt;span class="nt"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;Testing placemark&lt;span class="nt"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_3e4d51d76e72451a8e4baec7610d4bda-7" name="rest_code_3e4d51d76e72451a8e4baec7610d4bda-7" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_3e4d51d76e72451a8e4baec7610d4bda-7"&gt;&lt;/a&gt;  &lt;span class="nt"&gt;&amp;lt;content&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/html"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_3e4d51d76e72451a8e4baec7610d4bda-8" name="rest_code_3e4d51d76e72451a8e4baec7610d4bda-8" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_3e4d51d76e72451a8e4baec7610d4bda-8"&gt;&lt;/a&gt;    &lt;span class="ni"&gt;&amp;amp;lt;&lt;/span&gt;p&amp;gt;600 N Sherwood St, Fort Collins, CO&lt;span class="ni"&gt;&amp;amp;lt;&lt;/span&gt;/p&amp;gt;
&lt;a id="rest_code_3e4d51d76e72451a8e4baec7610d4bda-9" name="rest_code_3e4d51d76e72451a8e4baec7610d4bda-9" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_3e4d51d76e72451a8e4baec7610d4bda-9"&gt;&lt;/a&gt;  &lt;span class="nt"&gt;&amp;lt;/content&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_3e4d51d76e72451a8e4baec7610d4bda-10" name="rest_code_3e4d51d76e72451a8e4baec7610d4bda-10" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_3e4d51d76e72451a8e4baec7610d4bda-10"&gt;&lt;/a&gt;  &lt;span class="nt"&gt;&amp;lt;georss:where&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_3e4d51d76e72451a8e4baec7610d4bda-11" name="rest_code_3e4d51d76e72451a8e4baec7610d4bda-11" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_3e4d51d76e72451a8e4baec7610d4bda-11"&gt;&lt;/a&gt;    &lt;span class="nt"&gt;&amp;lt;gml:Point&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_3e4d51d76e72451a8e4baec7610d4bda-12" name="rest_code_3e4d51d76e72451a8e4baec7610d4bda-12" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_3e4d51d76e72451a8e4baec7610d4bda-12"&gt;&lt;/a&gt;      &lt;span class="nt"&gt;&amp;lt;gml:pos&amp;gt;&lt;/span&gt;-105.0842514037999962 40.5944633483999979&lt;span class="nt"&gt;&amp;lt;/gml:pos&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_3e4d51d76e72451a8e4baec7610d4bda-13" name="rest_code_3e4d51d76e72451a8e4baec7610d4bda-13" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_3e4d51d76e72451a8e4baec7610d4bda-13"&gt;&lt;/a&gt;    &lt;span class="nt"&gt;&amp;lt;/gml:Point&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_3e4d51d76e72451a8e4baec7610d4bda-14" name="rest_code_3e4d51d76e72451a8e4baec7610d4bda-14" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_3e4d51d76e72451a8e4baec7610d4bda-14"&gt;&lt;/a&gt;  &lt;span class="nt"&gt;&amp;lt;/georss:where&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_3e4d51d76e72451a8e4baec7610d4bda-15" name="rest_code_3e4d51d76e72451a8e4baec7610d4bda-15" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_3e4d51d76e72451a8e4baec7610d4bda-15"&gt;&lt;/a&gt;&lt;span class="nt"&gt;&amp;lt;/entry&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Use your own location for extra points. Add to my collection using everyone's favorite RESTful client, curl:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code bash"&gt;&lt;a id="rest_code_310617ad81fe4b76882a8f2b0bf3457f-1" name="rest_code_310617ad81fe4b76882a8f2b0bf3457f-1" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_310617ad81fe4b76882a8f2b0bf3457f-1"&gt;&lt;/a&gt;sean@lenny:/tmp$ curl -i -X POST &lt;span class="se"&gt;\&lt;/span&gt;
&lt;a id="rest_code_310617ad81fe4b76882a8f2b0bf3457f-2" name="rest_code_310617ad81fe4b76882a8f2b0bf3457f-2" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_310617ad81fe4b76882a8f2b0bf3457f-2"&gt;&lt;/a&gt;  -H &lt;span class="s2"&gt;"Authorization: Basic YWRtaW46OGZjOGFkZmM="&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;a id="rest_code_310617ad81fe4b76882a8f2b0bf3457f-3" name="rest_code_310617ad81fe4b76882a8f2b0bf3457f-3" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_310617ad81fe4b76882a8f2b0bf3457f-3"&gt;&lt;/a&gt;  -H &lt;span class="s2"&gt;"Content-Type: application/atom+xml;type=entry"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;a id="rest_code_310617ad81fe4b76882a8f2b0bf3457f-4" name="rest_code_310617ad81fe4b76882a8f2b0bf3457f-4" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_310617ad81fe4b76882a8f2b0bf3457f-4"&gt;&lt;/a&gt;  -H &lt;span class="s2"&gt;"Slug: 600 N Sherwood"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;a id="rest_code_310617ad81fe4b76882a8f2b0bf3457f-5" name="rest_code_310617ad81fe4b76882a8f2b0bf3457f-5" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_310617ad81fe4b76882a8f2b0bf3457f-5"&gt;&lt;/a&gt;  -d@test.atom &lt;span class="se"&gt;\&lt;/span&gt;
&lt;a id="rest_code_310617ad81fe4b76882a8f2b0bf3457f-6" name="rest_code_310617ad81fe4b76882a8f2b0bf3457f-6" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_310617ad81fe4b76882a8f2b0bf3457f-6"&gt;&lt;/a&gt;  http://sgillies.net/kw/demo/atompub-collection
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Use a different slug if you like. Here are the response headers:&lt;/p&gt;
&lt;pre class="literal-block"&gt;HTTP/1.1 201 Created
Date: Fri, 14 Mar 2008 04:32:33 GMT
Server: Twisted/2.5.0 TwistedWeb/[twisted.web2, version 0.2.0]
Content-Length: 744
X-Powered-By: Zope (www.zope.org), Python (www.python.org)
Accept-Ranges: bytes
Location: http://sgillies.net/kw/demo/600-n-sherwood/atom-entry
Content-Type: application/atom+xml;type=entry&lt;/pre&gt;
&lt;p&gt;Browse to that location and you'll get an Atom entry document like this:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code xml"&gt;&lt;a id="rest_code_763c36e0579940bab965127e2517aa1c-1" name="rest_code_763c36e0579940bab965127e2517aa1c-1" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_763c36e0579940bab965127e2517aa1c-1"&gt;&lt;/a&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_763c36e0579940bab965127e2517aa1c-2" name="rest_code_763c36e0579940bab965127e2517aa1c-2" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_763c36e0579940bab965127e2517aa1c-2"&gt;&lt;/a&gt;&lt;span class="nt"&gt;&amp;lt;entry&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2005/Atom"&lt;/span&gt;
&lt;a id="rest_code_763c36e0579940bab965127e2517aa1c-3" name="rest_code_763c36e0579940bab965127e2517aa1c-3" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_763c36e0579940bab965127e2517aa1c-3"&gt;&lt;/a&gt;       &lt;span class="na"&gt;xmlns:georss=&lt;/span&gt;&lt;span class="s"&gt;"http://www.georss.org/georss"&lt;/span&gt;
&lt;a id="rest_code_763c36e0579940bab965127e2517aa1c-4" name="rest_code_763c36e0579940bab965127e2517aa1c-4" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_763c36e0579940bab965127e2517aa1c-4"&gt;&lt;/a&gt;       &lt;span class="na"&gt;xmlns:gml=&lt;/span&gt;&lt;span class="s"&gt;"http://www.opengis.net/gml"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_763c36e0579940bab965127e2517aa1c-5" name="rest_code_763c36e0579940bab965127e2517aa1c-5" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_763c36e0579940bab965127e2517aa1c-5"&gt;&lt;/a&gt;
&lt;a id="rest_code_763c36e0579940bab965127e2517aa1c-6" name="rest_code_763c36e0579940bab965127e2517aa1c-6" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_763c36e0579940bab965127e2517aa1c-6"&gt;&lt;/a&gt;    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Test&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_763c36e0579940bab965127e2517aa1c-7" name="rest_code_763c36e0579940bab965127e2517aa1c-7" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_763c36e0579940bab965127e2517aa1c-7"&gt;&lt;/a&gt;    &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"http://sgillies.net/kw/demo/600-n-sherwood/atom-entry"&lt;/span&gt;
&lt;a id="rest_code_763c36e0579940bab965127e2517aa1c-8" name="rest_code_763c36e0579940bab965127e2517aa1c-8" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_763c36e0579940bab965127e2517aa1c-8"&gt;&lt;/a&gt;          &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"application/atom+xml;type=entry"&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"edit"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_763c36e0579940bab965127e2517aa1c-9" name="rest_code_763c36e0579940bab965127e2517aa1c-9" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_763c36e0579940bab965127e2517aa1c-9"&gt;&lt;/a&gt;    &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"http://sgillies.net/kw/demo/600-n-sherwood"&lt;/span&gt;
&lt;a id="rest_code_763c36e0579940bab965127e2517aa1c-10" name="rest_code_763c36e0579940bab965127e2517aa1c-10" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_763c36e0579940bab965127e2517aa1c-10"&gt;&lt;/a&gt;          &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/html"&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"alternate"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_763c36e0579940bab965127e2517aa1c-11" name="rest_code_763c36e0579940bab965127e2517aa1c-11" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_763c36e0579940bab965127e2517aa1c-11"&gt;&lt;/a&gt;    &lt;span class="nt"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;urn:uuid:dfa47428-e9ce-41b4-9f42-c2a3cad9037a&lt;span class="nt"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_763c36e0579940bab965127e2517aa1c-12" name="rest_code_763c36e0579940bab965127e2517aa1c-12" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_763c36e0579940bab965127e2517aa1c-12"&gt;&lt;/a&gt;    &lt;span class="nt"&gt;&amp;lt;updated&amp;gt;&lt;/span&gt;2008-03-14T04:32:33Z&lt;span class="nt"&gt;&amp;lt;/updated&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_763c36e0579940bab965127e2517aa1c-13" name="rest_code_763c36e0579940bab965127e2517aa1c-13" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_763c36e0579940bab965127e2517aa1c-13"&gt;&lt;/a&gt;    &lt;span class="nt"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;Testing placemark&lt;span class="nt"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_763c36e0579940bab965127e2517aa1c-14" name="rest_code_763c36e0579940bab965127e2517aa1c-14" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_763c36e0579940bab965127e2517aa1c-14"&gt;&lt;/a&gt;    &lt;span class="nt"&gt;&amp;lt;georss:where&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_763c36e0579940bab965127e2517aa1c-15" name="rest_code_763c36e0579940bab965127e2517aa1c-15" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_763c36e0579940bab965127e2517aa1c-15"&gt;&lt;/a&gt;      &lt;span class="nt"&gt;&amp;lt;gml:Point&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_763c36e0579940bab965127e2517aa1c-16" name="rest_code_763c36e0579940bab965127e2517aa1c-16" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_763c36e0579940bab965127e2517aa1c-16"&gt;&lt;/a&gt;        &lt;span class="nt"&gt;&amp;lt;gml:pos&amp;gt;&lt;/span&gt;-105.084251 40.594463&lt;span class="nt"&gt;&amp;lt;/gml:pos&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_763c36e0579940bab965127e2517aa1c-17" name="rest_code_763c36e0579940bab965127e2517aa1c-17" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_763c36e0579940bab965127e2517aa1c-17"&gt;&lt;/a&gt;      &lt;span class="nt"&gt;&amp;lt;/gml:Point&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_763c36e0579940bab965127e2517aa1c-18" name="rest_code_763c36e0579940bab965127e2517aa1c-18" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_763c36e0579940bab965127e2517aa1c-18"&gt;&lt;/a&gt;    &lt;span class="nt"&gt;&amp;lt;/georss:where&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_763c36e0579940bab965127e2517aa1c-19" name="rest_code_763c36e0579940bab965127e2517aa1c-19" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_763c36e0579940bab965127e2517aa1c-19"&gt;&lt;/a&gt;&lt;span class="nt"&gt;&amp;lt;/entry&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The newly created placemark can be edited by PUT of a new representation to its "edit" link. Edit your &lt;em&gt;test.atom&lt;/em&gt; file, changing the title, or summary, or location, and use curl once again:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code bash"&gt;&lt;a id="rest_code_c80465ddbc2c450d8f47e193126cd4f5-1" name="rest_code_c80465ddbc2c450d8f47e193126cd4f5-1" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_c80465ddbc2c450d8f47e193126cd4f5-1"&gt;&lt;/a&gt;sean@lenny:/tmp$ curl -i -X PUT &lt;span class="se"&gt;\&lt;/span&gt;
&lt;a id="rest_code_c80465ddbc2c450d8f47e193126cd4f5-2" name="rest_code_c80465ddbc2c450d8f47e193126cd4f5-2" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_c80465ddbc2c450d8f47e193126cd4f5-2"&gt;&lt;/a&gt;  -H &lt;span class="s2"&gt;"Authorization: Basic YWRtaW46OGZjOGFkZmM="&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;a id="rest_code_c80465ddbc2c450d8f47e193126cd4f5-3" name="rest_code_c80465ddbc2c450d8f47e193126cd4f5-3" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_c80465ddbc2c450d8f47e193126cd4f5-3"&gt;&lt;/a&gt;  -H &lt;span class="s2"&gt;"Content-Type: application/atom+xml;type=entry"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;a id="rest_code_c80465ddbc2c450d8f47e193126cd4f5-4" name="rest_code_c80465ddbc2c450d8f47e193126cd4f5-4" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_c80465ddbc2c450d8f47e193126cd4f5-4"&gt;&lt;/a&gt;  -d@test-edit.atom &lt;span class="se"&gt;\&lt;/span&gt;
&lt;a id="rest_code_c80465ddbc2c450d8f47e193126cd4f5-5" name="rest_code_c80465ddbc2c450d8f47e193126cd4f5-5" href="https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html#rest_code_c80465ddbc2c450d8f47e193126cd4f5-5"&gt;&lt;/a&gt;  http://sgillies.net/kw/demo/600-n-sherwood/atom-entry
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The response: HTTP/1.1 200 OK.&lt;/p&gt;
&lt;p&gt;DELETE works too. Go ahead and delete your own placemark if you wish. It's not as exciting as you might think. The Knowhere map app uses the same AtomPub links to add placemarks. Editing and deletion through OpenLayers are next up.&lt;/p&gt;
&lt;section id="comments"&gt;
&lt;h2&gt;Comments&lt;/h2&gt;
&lt;section id="re-atompub-for-zgeo-atom"&gt;
&lt;h3&gt;Re: AtomPub for zgeo.atom&lt;/h3&gt;
&lt;p&gt;Author: &lt;a class="reference external" href="http://www.spatialdatalogic.com/cs/blogs/brian_flood"&gt;Brian Flood&lt;/a&gt;&lt;/p&gt;
hi sean

what are your thoughts on APP feeds with multiple geometry types? (like the example above). At first I thought we should enforce a single geometry type per feed but this is probably impracticable in the real world. Client apps that tried to enforce this would be precluded from using (what could be) the vast majority of feeds that don’t care about enforcing similar geometries (for example I could see GMaps MyMaps doing this).

How do you see the OL APP client working? a free for all like cschmidt’s original demo or something more GIS like with a single geometry? for our ArcMap client, I’m now creating point,line,and polygon featureclasses for each feed to serve as the local store. users will need to switch between layers when editing but all updates will be posted to the same feed. thoughts?

cheers
brian&lt;/section&gt;
&lt;section id="re-atompub-for-zgeo-atom-1"&gt;
&lt;h3&gt;Re: AtomPub for zgeo.atom&lt;/h3&gt;
&lt;p&gt;Author: Yves Moisan&lt;/p&gt;
Neat.  Made me discover curl on Windows.  I typed a bit too quick and inadvertently edited the title of your 600 N sherwood entry :-(.  I redid it after for the entry I made for "Mont Orford" and refixed yours using the info in your edit.atom example :-). Phew !

Great work again.&lt;/section&gt;
&lt;section id="re-atompub-for-zgeo-atom-2"&gt;
&lt;h3&gt;Re: AtomPub for zgeo.atom&lt;/h3&gt;
&lt;p&gt;Author: Sean&lt;/p&gt;
Brian, I'm mainly going to use collections of a single geometry type for Pleiades, separating settlements and ethnic regions for example, but there are uses for the free for all collection.&lt;/section&gt;
&lt;section id="re-atompub-for-zgeo-atom-3"&gt;
&lt;h3&gt;Re: AtomPub for zgeo.atom&lt;/h3&gt;
&lt;p&gt;Author: Sean&lt;/p&gt;
Thanks, Yves. Hopefully I can turn some other Zope/Plone developers on to this. The scope of zgeo.atom is rather narrow now, but could be generalized to non-geo content.&lt;/section&gt;
&lt;section id="re-atompub-for-zgeo-atom-4"&gt;
&lt;h3&gt;Re: AtomPub for zgeo.atom&lt;/h3&gt;
&lt;p&gt;Author: Yves Moisan&lt;/p&gt;
Hopefully I can turn [INTO a] Zope/Plone developer [soon].  I'm more of a give-it-a-quick-go lurker for the time being.&lt;/section&gt;
&lt;/section&gt;</description><category>atom</category><category>rest</category><category>the lab</category><category>work</category><category>zope</category><guid>https://sgillies.net/2008/03/14/atompub-for-zgeo-atom.html</guid><pubDate>Fri, 14 Mar 2008 06:00:00 GMT</pubDate></item><item><title>Knowhere Project Wiki</title><link>https://sgillies.net/2007/12/17/knowhere-project-wiki.html</link><dc:creator>Sean Gillies</dc:creator><description>&lt;p&gt;I made a new wiki page for &lt;a class="reference external" href="http://trac.gispython.org/projects/PrimaGIS/wiki/Knowhere"&gt;Knowhere&lt;/a&gt;. It's my Christmas present to everyone. What, you were expecting something other than open source software?&lt;/p&gt;
&lt;p&gt;The buildout failed on my PowerPC iBook, which has gcc 4.0.0. Howard Butler has been successfully building the spatialindex library on his servers with gcc 4.0.1, so it may build on newer OS X systems as long as you have Python 2.4.&lt;/p&gt;</description><category>the lab</category><category>work</category><category>zope</category><guid>https://sgillies.net/2007/12/17/knowhere-project-wiki.html</guid><pubDate>Mon, 17 Dec 2007 07:00:00 GMT</pubDate></item><item><title>Grok, the Paleolithic Geographer</title><link>https://sgillies.net/2007/12/15/grok-the-paleolithic-geographer.html</link><dc:creator>Sean Gillies</dc:creator><description>&lt;aside class="admonition admonition-update-2008-02-19"&gt;
&lt;p class="admonition-title"&gt;Update (2008-02-19)&lt;/p&gt;
&lt;p&gt;The batlas demo is gone. Please see instead &lt;a class="reference external" href="http://sgillies.net/kw/demo"&gt;http://sgillies.net/kw/demo&lt;/a&gt;.&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="admonition admonition-update-2007-12-18"&gt;
&lt;p class="admonition-title"&gt;Update (2007-12-18)&lt;/p&gt;
&lt;p&gt;See &lt;a class="reference external" href="http://trac.gispython.org/projects/PrimaGIS/wiki/Knowhere"&gt;http://trac.gispython.org/projects/PrimaGIS/wiki/Knowhere&lt;/a&gt;.&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;I've wanted to make an easily deployed and transparent application to demonstrate what can be done with zgeo.geographer and friends, the new geospatial packages for Zope, and finally inspiration struck. I chose to write a &lt;a class="reference external" href="http://grok.zope.org/"&gt;Grok&lt;/a&gt; project using the aptly named &lt;a class="reference external" href="http://pypi.python.org/pypi/grokproject"&gt;grokproject&lt;/a&gt;. Grok aims to simplify Zope to the degree that a caveman could use it. Convention over configuration and all that. It certainly allows a developer a clear view of the zgeo.* packages in action.&lt;/p&gt;
&lt;p&gt;The paleolithic geographer isn't concerned about fancy geographic information systems. He wants a know-where-things-are system; hence the name of my demo app: Knowhere (pronounced "Oog"). Knowhere annotates resources with geographic location metadata and publishes them using GeoRSS (Atom, specifically) or KML so that a even a caveman can visualize them in the context of other geographic information on the Web.&lt;/p&gt;
&lt;p&gt;Building and launching Knowhere is a 5 step process that requires Python 2.4, gmake, gcc, etc. Within 15 minutes you can be publishing geo-referenced content. Start by getting the code from the PrimaGIS Subversion repository:&lt;/p&gt;
&lt;pre class="literal-block"&gt;$ svn co http://svn.gispython.org/svn/zope/Knowhere/trunk Knowhere&lt;/pre&gt;
&lt;p&gt;Cd into that new directory and bootstrap the project:&lt;/p&gt;
&lt;pre class="literal-block"&gt;$ /usr/bin/python2.4 bootstrap.py&lt;/pre&gt;
&lt;p&gt;Build it out:&lt;/p&gt;
&lt;pre class="literal-block"&gt;$ ./bin/buildout&lt;/pre&gt;
&lt;p&gt;This downloads and builds 2 C/C++ libraries (GEOS and spatialindex), and fetches a heap of eggs. It will take a few minutes.&lt;/p&gt;
&lt;p&gt;When the build out is complete, edit 2 configuration files. In parts/zopectl/zope.conf, set the port number to an open value. In parts/app/site.zcml, change the management password from "admin" to one less obvious. That done, start up the application:&lt;/p&gt;
&lt;pre class="literal-block"&gt;$ ./bin/zopectl fg&lt;/pre&gt;
&lt;p&gt;Browse to &lt;a class="reference external" href="http://localhost:8080"&gt;http://localhost:8080&lt;/a&gt; (let's presume that's where it's at), authenticate, and you should see a Grok management page like this:&lt;/p&gt;
&lt;img alt="http://sgillies.net/images/knowhere-apps.jpg" src="http://sgillies.net/images/knowhere-apps.jpg" style="width: 616px; height: 452px;"&gt;
&lt;p&gt;Add a new application named "cities" as shown, and then browse to &lt;a class="reference external" href="http://localhost:8080/cities"&gt;http://localhost:8080/cities&lt;/a&gt; where you'll be faced with one of the ugliest forms ever seen. Fill it out like so&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;name: fort-collins&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;title: Fort Collins&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;description: Fort Collins, Colorado, USA&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;text: The little geospatial hothouse on the prairie&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;geometry type: Point&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;coordinates: [-105.08, 40.59]&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;using a &lt;a class="reference external" href="http://geojson.org"&gt;GeoJSON&lt;/a&gt; coordinate representation, and submit. Click through to the new placemark page, which should be something like &lt;a class="reference external" href="http://sgillies.net/kw/cities/fort-collins"&gt;this&lt;/a&gt;. There are 5 fields on that page. Look at the Knowhere model (src/knowhere/app.py) and you'll see that the Placemark class actually only has one attribute:&lt;/p&gt;
&lt;pre class="literal-block"&gt;class Placemark(grok.Model):

    def __init__(self, text=None):
        self.text = text&lt;/pre&gt;
&lt;p&gt;Where are the other fields? Grok gives you Dublin Core metadata annotations automatically. No configuration required. Peek into the model's configuration (src/knowhere/configure.zcml) and you'll see that adding geographic location metadata from zgeo.geographer to any model class is as simple as:&lt;/p&gt;
&lt;pre class="literal-block"&gt;...
&amp;lt;include package="zgeo.geographer"/&amp;gt;

&amp;lt;class class=".app.Placemark"&amp;gt;
  &amp;lt;implements interface="zgeo.geographer.interfaces.IGeoreferenceable"/&amp;gt;
&amp;lt;/class&amp;gt;
...&lt;/pre&gt;
&lt;p&gt;The zgeo.kml package provides KML representations of containers of georeferenceable objects. Browse to &lt;a class="reference external" href="http://localhost:8080/cities/@@kml-document"&gt;http://localhost:8080/cities/@@kml-document&lt;/a&gt; for an example. The zgeo.atom package provides Atom entry and feed document views with GeoRSS. For examples, browse to &lt;a class="reference external" href="http://localhost:8080/cities/fort-collins/@@atom-link-entry"&gt;http://localhost:8080/cities/fort-collins/@@atom-link-entry&lt;/a&gt; and &lt;a class="reference external" href="http://localhost:8080/cities/@@atom-search-feed"&gt;http://localhost:8080/cities/@@atom-search-feed&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Knowhere also includes an R-Tree spatial index from zgeo.spatialindex. Containers of the model can be made indexable as easily as:&lt;/p&gt;
&lt;pre class="literal-block"&gt;...
&amp;lt;include package="zgeo.spatialindex"/&amp;gt;

&amp;lt;class class=".app.Demo"&amp;gt;
  &amp;lt;implements interface="zgeo.spatialindex.interfaces.ISpatiallyIndexable"/&amp;gt;
&amp;lt;/class&amp;gt;
...&lt;/pre&gt;
&lt;p&gt;Browse to &lt;a class="reference external" href="http://localhost:8080/cities/@@manage-index"&gt;http://localhost:8080/cities/@@manage-index&lt;/a&gt; to see the index management form. Future versions of Knowhere will include georeferencing event handlers, but for now you must rebuild the index manually after adding placemarks. Lame indeed, but this is just a demo (I already have a working handler for Plone AT content types). The management screen in the image below is from my demo application at &lt;a class="reference external" href="http://sgillies.net/kw/batlas"&gt;http://sgillies.net/kw/batlas&lt;/a&gt;, which had 2 placemarks at the time I wrote this post.&lt;/p&gt;
&lt;img alt="http://sgillies.net/images/knowhere-zmi.jpg" class="illus" src="http://sgillies.net/images/knowhere-zmi.jpg" style="width: 578px; height: 372px;"&gt;
&lt;p&gt;The spatial index allows fast bounding box queries. The atom search feed accepts a bbox parameter of the form &lt;em&gt;minimum_longitude,minimum_latitude,maximum_longitude,maximum_latitude&lt;/em&gt;. For example, see &lt;a class="reference external" href="http://sgillies.net/kw/batlas/@@atom-search-feed?bbox=-5,50,5,55"&gt;http://sgillies.net/kw/batlas/@@atom-search-feed?bbox=-5,50,5,55&lt;/a&gt; [&lt;a class="reference external" href="http://maps.google.com/maps?f=q&amp;amp;q=http:%2F%2Fsgillies.net%2Fkw%2Fbatlas%2F%40%40atom-search-feed%3Fbbox%3D-5,50,5,55&amp;amp;ie=UTF8&amp;amp;om=0&amp;amp;ll=52.429222,-2.570801&amp;amp;spn=5.399798,13.513184&amp;amp;t=p&amp;amp;z=6"&gt;map&lt;/a&gt;].&lt;/p&gt;
&lt;img alt="http://sgillies.net/images/knowhere-ge.jpg" class="illus" src="http://sgillies.net/images/knowhere-ge.jpg" style="width: 641px; height: 604px;"&gt;
&lt;p&gt;As you can see in the image above, zgeo.* can handle polygon geometries as well as lines and points. View that demo application in Google Earth using &lt;a class="reference external" href="http://sgillies.net/kw/batlas/@@kml-document"&gt;http://sgillies.net/kw/batlas/@@kml-document&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;There's more work to do on Knowhere and zgeo.*. The index might be better as a local utility, and I should be using an integer id utility instead of hashing content names. The HTML is wretched and the URLs cry out for rewriting (which Grok supports right out of the box). Any Zope user that can look past those warts might start to get some good ideas from Knowhere.&lt;/p&gt;</description><category>pleiades</category><category>the lab</category><category>work</category><category>zope</category><guid>https://sgillies.net/2007/12/15/grok-the-paleolithic-geographer.html</guid><pubDate>Sat, 15 Dec 2007 07:00:00 GMT</pubDate></item><item><title>New Geospatial Packages for Zope</title><link>https://sgillies.net/2007/12/02/new-geospatial-packages-for-zope.html</link><dc:creator>Sean Gillies</dc:creator><description>&lt;p&gt;As part of my work on migrating Pleiades to Plone 3, I'm distilling Zope packages from the original old-style Plone products. The &lt;a class="reference external" href="http://pypi.python.org/pypi/zgeo.geographer/"&gt;zgeo.geographer&lt;/a&gt; introduces the conventional GIS data model of geometries, features, and collections (ala GeoJSON) to Zope and describes an interface for annotating objects with geographic location metadata. The &lt;a class="reference external" href="http://pypi.python.org/pypi/zgeo.spatialindex/"&gt;zgeo.spatialindex&lt;/a&gt; provides a container-local R-Tree spatial index for geographically annotated objects, enabling fast spatial bounding box searches.&lt;/p&gt;
&lt;section id="comments"&gt;
&lt;h2&gt;Comments&lt;/h2&gt;
&lt;section id="re-new-geospatial-packages-for-zope"&gt;
&lt;h3&gt;Re: New Geospatial Packages for Zope&lt;/h3&gt;
&lt;p&gt;Author: J.F.&lt;/p&gt;
Excellent news!&lt;/section&gt;
&lt;/section&gt;</description><category>pleiades</category><category>python</category><category>the lab</category><category>work</category><category>zope</category><guid>https://sgillies.net/2007/12/02/new-geospatial-packages-for-zope.html</guid><pubDate>Sun, 02 Dec 2007 07:00:00 GMT</pubDate></item><item><title>Grok Does AtomPub</title><link>https://sgillies.net/2007/11/09/grok-does-atompub.html</link><dc:creator>Sean Gillies</dc:creator><description>&lt;p&gt;&lt;a class="reference external" href="http://grok.zope.org/minitutorials/rest.html"&gt;Nice&lt;/a&gt;. I'd like to bend Grok's REST components to fit Pleiades after our move to Plone 3.&lt;/p&gt;</description><category>work</category><category>zope</category><guid>https://sgillies.net/2007/11/09/grok-does-atompub.html</guid><pubDate>Fri, 09 Nov 2007 07:00:00 GMT</pubDate></item></channel></rss>