<?xml version="1.0" encoding="utf-8" ?>

<rss version="2.0" 
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:admin="http://webns.net/mvcb/"
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
   xmlns:wfw="http://wellformedweb.org/CommentAPI/"
   xmlns:content="http://purl.org/rss/1.0/modules/content/"
   >
<channel>
    
    <title>Coffee|Code : Dan Scott - Programming languages</title>
    <link>https://coffeecode.net:443/</link>
    <description>Caffeinated Librarian Geek</description>
    <dc:language>en</dc:language>
    <generator>Serendipity 1.6.2 - http://www.s9y.org/</generator>
    
    

<item>
    <title>PHP's File_MARC gets a new release (1.1.3)</title>
    <link>https://coffeecode.net:443/archives/313-PHPs-File_MARC-gets-a-new-release-1.1.3.html</link>
            <category>Coding</category>
            <category>PHP</category>
    
    <comments>https://coffeecode.net:443/archives/313-PHPs-File_MARC-gets-a-new-release-1.1.3.html#comments</comments>
    <wfw:comment>https://coffeecode.net:443/wfwcomment.php?cid=313</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>https://coffeecode.net:443/rss.php?version=2.0&amp;type=comments&amp;cid=313</wfw:commentRss>
    

    <author>dan@coffeecode.net (Dan Scott)</author>
    <content:encoded>
    &lt;p&gt;Yesterday, just one day before the anniversary of the 1.1.2 release, I published the 1.1.3 release of the PEAR &lt;a href=&quot;http://pear.php.net/package/File_MARC&quot;&gt;File_MARC&lt;/a&gt; library. The only change is the addition of a convenience method for fields called &lt;code&gt;getContents()&lt;/code&gt; that simply concatenates all of the subfields together in order, with an optional separator string. Many thanks to Carsten Klee for &lt;a href=&quot;https://github.com/pear/File_MARC/pull/6&quot;&gt;contributing the code&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;You can install File_MARC through the usual channels: PEAR or composer. Have fun!&lt;/p&gt; 
    </content:encoded>

    <pubDate>Thu, 01 Sep 2016 00:00:19 -0400</pubDate>
    <guid isPermaLink="false">https://coffeecode.net:443/archives/313-guid.html</guid>
    <category>coding</category>
<category>php</category>

</item>
<item>
    <title>Ups and downs</title>
    <link>https://coffeecode.net:443/archives/279-Ups-and-downs.html</link>
            <category>Coding</category>
            <category>Evergreen</category>
            <category>PHP</category>
            <category>Structured data</category>
    
    <comments>https://coffeecode.net:443/archives/279-Ups-and-downs.html#comments</comments>
    <wfw:comment>https://coffeecode.net:443/wfwcomment.php?cid=279</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>https://coffeecode.net:443/rss.php?version=2.0&amp;type=comments&amp;cid=279</wfw:commentRss>
    

    <author>dan@coffeecode.net (Dan Scott)</author>
    <content:encoded>
    &lt;p&gt;Tuesday was not the greatest day, but at least each setback resulted in a triumph...&lt;/p&gt;
&lt;p&gt;
First, the &lt;a
href=&quot;http://www.w3.org/community/schemabibex/wiki/Article&quot;&gt;periodical proposal
for schema.org&lt;/a&gt;--that I have poured a good couple of months of effort
into--took a step closer to reality when Dan Brickley &lt;a
href=&quot;http://lists.w3.org/Archives/Public/public-vocabs/2014Jan/0180.html&quot;&gt;announced
on the public-vocabs list&lt;/a&gt; that he had created a test build that
incorporated the RDFS that I had written up. Excitement rapidly turned to
horror, though, as I realized that I had made a classic copy/paste error, in
which I had changed the displayed name of the &lt;code&gt;domainIncludes&lt;/code&gt; value
but had not changed the actual URI... Long story short, the test build looked
nothing like what the schemabibex group had agreed on, and I was terribly
embarrassed.
&lt;/p&gt;
&lt;p&gt;
Luckily, after I fixed the RDFS, Dan was able to put together a revised test
build later that day that actually reflected our intentions. So that can
continue moving forward...
&lt;/p&gt;
&lt;p&gt;
Second, our Evergreen instance started acting up rather badly. All of the
connections to the database server were being gobbled up, and we were scrambling
to figure out why. While I&#039;m on sabbatical I&#039;m not really supposed to be
involved in the day-to-day operations, but when a core service stops running
it&#039;s okay for research to wait for a little bit... Eventually I tracked down a
fix for a potential denial of service problem (&lt;a
href=&quot;https://bugs.launchpad.net/evergreen/+bug/1200770&quot;&gt;Search result
rendering can crush the system&lt;/a&gt;) that hadn&#039;t been merged into our production
system (the fix came out after the start of my sabbatical), and shortly after I
put that into production we were back up and running.
&lt;/p&gt;
&lt;p&gt;
Third, after the Evergreen problem was resolved, Bill Dueber pinged me
innocently on IRC. He had run into a problem with File_MARC; when serializing
MARC as MARC-in-JSON format, fields with a subfield &lt;code&gt;$0&lt;/code&gt; were
getting trashed. Data corrupting bugs are one of the most serious classes of
bugs for any package maintainer, so I jumped on this problem too... After a
little bit of analysis, I figured out that PHP&#039;s type coercion for integer-like
keys when creating arrays and its &lt;a
href=&quot;http://php.net/json_encode&quot;&gt;&lt;code&gt;json_encode()&lt;/code&gt;&lt;/a&gt; implementation
were combining to ruin the MARC-in-JSON serialization in this one particular
case. Faced with rewriting the entire serialization logic, I did what any
(in)sane programmer would and ended up running a regex against the result of
&lt;code&gt;json_encode()&lt;/code&gt; to turn the array-ified subfield &lt;code&gt;$0&lt;/code&gt;
back into a key/value pair. &lt;a href=&quot;http://pear.php.net/File_MARC&quot;&gt;File_MARC
1.1.1&lt;/a&gt; is now available at your nearest PEAR mirror...
&lt;/p&gt; 
    </content:encoded>

    <pubDate>Thu, 30 Jan 2014 10:00:08 -0500</pubDate>
    <guid isPermaLink="false">https://coffeecode.net:443/archives/279-guid.html</guid>
    <category>coding</category>
<category>evergreen</category>
<category>php</category>
<category>structured data</category>

</item>
<item>
    <title>File_MARC makes it to stable 1.0.0 release (finally!)</title>
    <link>https://coffeecode.net:443/archives/273-File_MARC-makes-it-to-stable-1.0.0-release-finally!.html</link>
            <category>Coding</category>
            <category>PHP</category>
    
    <comments>https://coffeecode.net:443/archives/273-File_MARC-makes-it-to-stable-1.0.0-release-finally!.html#comments</comments>
    <wfw:comment>https://coffeecode.net:443/wfwcomment.php?cid=273</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>https://coffeecode.net:443/rss.php?version=2.0&amp;type=comments&amp;cid=273</wfw:commentRss>
    

    <author>dan@coffeecode.net (Dan Scott)</author>
    <content:encoded>
    &lt;p&gt;Way back in 2006, I thought &quot;&lt;em&gt;It&#039;s a shame there is no PHP library for parsing MARC records!&lt;/em&gt;&quot;, and given that much of my most recent coding experience was in the PHP realm, I thought it would be a good way of contributing to the world of &lt;a href=&quot;http://code4lib&quot;&gt;code4lib&lt;/a&gt;. Thus &lt;a href=&quot;http://coffeecode.net/archives/92-Double-barreled-PHP-releases.html&quot;&gt;File_MARC&lt;/a&gt; was born in October 2006. At the time, I had aspirations of quickly iterating to a 1.0.0 stable release. &lt;strong&gt;Hah!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Seven years later, I have finally cut a 1.0.0 stable release of the &lt;a href=&quot;http://pear.php.net/File_MARC&quot;&gt;File_MARC library for PHP&lt;/a&gt;. The major reason I had been hesitating was that I really wanted to &lt;a href=&quot;http://coffeecode.net/archives/148-Oooh...-looks-like-Ive-got-even-more-work-cut-out-for-me.html&quot;&gt;cut over to the native&lt;/a&gt; &lt;a href=&quot;http://php.net/SplDoublyLinkedList&quot;&gt;SplDoublyLinkedList class&lt;/a&gt; instead of my own user-space linked list. In the end, I still had to add a small shim to enable nodes to be inserted anywhere in the linked list (&lt;code&gt;SplDoublyLinkedList::add()&lt;/code&gt; was not added to PHP until 5.5.0, to which few users will have easy access for a while), but I&#039;m much happier about the result.&lt;/p&gt;
&lt;p&gt;The best thing about this release is that it means you no longer have to add &lt;code&gt;-beta&lt;/code&gt; to your install command, which tripped many people up, I&#039;m sure. That is, you can simply install it with:&lt;/p&gt;
&lt;pre&gt;
pear install File_MARC
&lt;/pre&gt;
&lt;p&gt;Thanks to Bill Dueber and Ross Singer for pestering me to go ahead and get this thing stable, and to Demian Katz and Mark Jordan for testing out the final code!&lt;/p&gt; 
    </content:encoded>

    <pubDate>Fri, 04 Oct 2013 10:42:51 -0400</pubDate>
    <guid isPermaLink="false">https://coffeecode.net:443/archives/273-guid.html</guid>
    <category>coding</category>
<category>php</category>

</item>
<item>
    <title>A Flask of full-text search in PostgreSQL</title>
    <link>https://coffeecode.net:443/archives/270-A-Flask-of-full-text-search-in-PostgreSQL.html</link>
            <category>Coding</category>
            <category>PostgreSQL</category>
            <category>Python</category>
    
    <comments>https://coffeecode.net:443/archives/270-A-Flask-of-full-text-search-in-PostgreSQL.html#comments</comments>
    <wfw:comment>https://coffeecode.net:443/wfwcomment.php?cid=270</wfw:comment>

    <slash:comments>5</slash:comments>
    <wfw:commentRss>https://coffeecode.net:443/rss.php?version=2.0&amp;type=comments&amp;cid=270</wfw:commentRss>
    

    <author>dan@coffeecode.net (Dan Scott)</author>
    <content:encoded>
    &lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; More conventional versions of the slides are available from &lt;a href=&quot;https://docs.google.com/presentation/d/1xKwBDYQUjrwMIMh3N64lhKK5H60F3C8SWX49KWJBshM/edit?usp=sharing&quot;&gt;Google Docs&lt;/a&gt; or in &lt;a href=&quot;https://speakerdeck.com/pyconca/a-flask-of-full-text-search-with-postgresql-dan-scott&quot;&gt;on Speakerdeck (PDF)&lt;/a&gt;&lt;/p&gt;.
&lt;p&gt;On August 10, 2013, I gave the following talk at the &lt;a href=&quot;http://2013.pycon.ca&quot;&gt;PyCon Canada 2013&lt;/a&gt; conference:&lt;/p&gt;
&lt;!-- s9ymdb:358 --&gt;&lt;img class=&quot;serendipity_image_center&quot; width=&quot;960&quot; height=&quot;720&quot;  src=&quot;https://coffeecode.net:443/uploads/talks/2013/postgresql_fts_0.png&quot;  alt=&quot;&quot; /&gt;
&lt;!-- s9ymdb:359 --&gt;&lt;img class=&quot;serendipity_image_center&quot; width=&quot;960&quot; height=&quot;720&quot;  src=&quot;https://coffeecode.net:443/uploads/talks/2013/postgresql_fts_1.png&quot;  alt=&quot;&quot; /&gt;
&lt;p&gt;I’m a systems librarian at Laurentian University.&lt;/p&gt;
&lt;p&gt;For the past six years, my day job and research have enabled me to contribute pretty heavily to Evergreen, an open source library system written largely in Perl and built on PostgreSQL.&lt;/p&gt;
&lt;p&gt;But when I have the opportunity to create a project from scratch, for work or play, Python is my go-to language.&lt;/p&gt;
&lt;!-- s9ymdb:360 --&gt;&lt;img class=&quot;serendipity_image_center&quot; width=&quot;960&quot; height=&quot;720&quot;  src=&quot;https://coffeecode.net:443/uploads/talks/2013/postgresql_fts_2.png&quot;  alt=&quot;&quot; /&gt;
&lt;p&gt;I promised to provide an example of a full-text search engine built with Flask and PostgreSQL written in under 200 lines of code; you can find that at either &lt;a href=&quot;https://gitorious.org/postgresql-full-text-search-engine&quot;&gt;Gitorious&lt;/a&gt; or &lt;a href=&quot;https://github.com/dbs/postgresql-full-text-search-engine&quot;&gt;Github&lt;/a&gt;.&lt;/p&gt;
&lt;!-- s9ymdb:361 --&gt;&lt;img class=&quot;serendipity_image_center&quot; width=&quot;960&quot; height=&quot;720&quot;  src=&quot;https://coffeecode.net:443/uploads/talks/2013/postgresql_fts_3.png&quot;  alt=&quot;&quot; /&gt;
&lt;p&gt;Last summer, the Laurentian University Library digitized 50 years of student newspapers - over 1,000 issues.&lt;/p&gt;
&lt;p&gt;We posted them all to the Internet Archive and got OCR’d text as a result.&lt;/p&gt;
&lt;p&gt;But finding things within a particular collection on the Internet Archive can be difficult for most people, so we felt the need to create a local search solution.&lt;/p&gt;
&lt;!-- s9ymdb:362 --&gt;&lt;img class=&quot;serendipity_image_center&quot; width=&quot;960&quot; height=&quot;720&quot;  src=&quot;https://coffeecode.net:443/uploads/talks/2013/postgresql_fts_4.png&quot;  alt=&quot;&quot; /&gt;
&lt;p&gt;We were already using PostgreSQL to track all of the individual issues, with attributes like newspaper name, volume, edition, publication date.&lt;/p&gt;
&lt;p&gt;This gave us the ability to filter through the issues by year and issue number, which was a good start. But we also wanted to be able to search the full text for strings like “Pierre Trudeau” or “Mike Harris”.&lt;/p&gt;
&lt;p&gt;A common approach is to feed the data into a dedicated search engine like Solr or Sphinx, and build a search interface on top of that.&lt;/p&gt;
&lt;p&gt;But PostgreSQL has featured full-text search support since the 8.3 release in 2008. So I opted to keep the moving parts to a minimum and reuse my existing database as my search platform.&lt;/p&gt;
&lt;!-- s9ymdb:363 --&gt;&lt;img class=&quot;serendipity_image_center&quot; width=&quot;960&quot; height=&quot;720&quot;  src=&quot;https://coffeecode.net:443/uploads/talks/2013/postgresql_fts_5.png&quot;  alt=&quot;&quot; /&gt;
&lt;p&gt;Our example table contains a “doc” column of type TEXT; that’s where we store the text that we want to search and display. We also have a “tsv” column of type TSVECTOR to store the normalized text.&lt;/p&gt;
&lt;p&gt;The TSVECTOR column is typically maintained by a trigger that fires whenever the corresponding row is created or updated. So... you just insert TEXT into the doc column, and the trigger maintains the tsv column for you.&lt;/p&gt;
&lt;p&gt;PostgreSQL includes the tsvector_update_trigger() for your convenience, as well as a trigger that uses different language-oriented normalizations based on the value of a specified column. Naturally, you can define your own trigger that invokes the to_tsvector() function.&lt;/p&gt;
&lt;p&gt;To provide good performance, as with any relational table, you need to define appropriate indexes. In the case of full-text search, you want to define a GIN (or GiST) index on the TSVECTOR column.&lt;/p&gt;
&lt;p&gt;Note: GIN indexes take longer to build, but provide faster lookup than GiST.&lt;/p&gt;
&lt;p&gt;Finally, we INSERT the text documents into the database. The ID and TSVECTOR columns are automatically generated for us.&lt;/p&gt;
&lt;!-- s9ymdb:364 --&gt;&lt;img class=&quot;serendipity_image_center&quot; width=&quot;960&quot; height=&quot;720&quot;  src=&quot;https://coffeecode.net:443/uploads/talks/2013/postgresql_fts_6.png&quot;  alt=&quot;&quot; /&gt;
&lt;p&gt;Each text document is:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Parsed into tokens (words, white space, URIs, file paths)&lt;/li&gt;
&lt;li&gt;Each token is then normalized with one or more dictionaries (word tokens may get stemming and stop words; URIs might have “www.” stripped; everything gets folded to lower case)&lt;/li&gt;
&lt;li&gt;Et voila: the text-search vector for our text document has been created!&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;PostgreSQL bundles a number of language-specific dictionaries to support different stemming algorithms and default sets of stopwords.&lt;/p&gt;
&lt;p&gt;In this example, we can see that PostgreSQL has stemmed “sketching” to remove the verb suffix, removed “the” altogether as a stop word, and stemmed “trees” to its singular form.&lt;/p&gt;
&lt;p&gt;You can also see that the TSVECTOR stores the position where each token occurs, to support relevancy ranking algorithms that boost the relevancy of terms that are located closely together.&lt;/p&gt;
&lt;!-- s9ymdb:365 --&gt;&lt;img class=&quot;serendipity_image_center&quot; width=&quot;960&quot; height=&quot;720&quot;  src=&quot;https://coffeecode.net:443/uploads/talks/2013/postgresql_fts_7.png&quot;  alt=&quot;&quot; /&gt;
&lt;p&gt;But it&#039;s a doozy of a query!&lt;/p&gt;
&lt;!-- s9ymdb:366 --&gt;&lt;img class=&quot;serendipity_image_center&quot; width=&quot;960&quot; height=&quot;720&quot;  src=&quot;https://coffeecode.net:443/uploads/talks/2013/postgresql_fts_8.png&quot;  alt=&quot;&quot; /&gt;
&lt;p&gt;Yes, there is a &lt;em&gt;lot&lt;/em&gt; going on here.&lt;/p&gt;
&lt;p&gt;First, this is just a regular SQL statement that happens to use the WITH clause to define named subqueries (“q” and “ranked”).&lt;/p&gt;
&lt;p&gt;The to_tsquery() function takes an incoming full-text search query and converts that into a parsed, normalized query.&lt;/p&gt;
&lt;p&gt;The ts_rank_cd() function compares the TS_VECTOR column against the query to determine its relevancy score.&lt;/p&gt;
&lt;p&gt;We need to restrict it to rows that match our query, so we use the @@ operator (PostgreSQL allows data-type specific operators like this) and then take the top ten.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Note&lt;/em&gt;&lt;/strong&gt;: the query, limit, and offset are hardcoded here for illustrative purposes, but in the actual application these are supplied as parameters to the prepared SQL statement.&lt;/p&gt;
&lt;p&gt;Finally, we use the ts_headline() function to give us a highlighted snippet of the results.&lt;/p&gt;
&lt;!-- s9ymdb:367 --&gt;&lt;img class=&quot;serendipity_image_center&quot; width=&quot;960&quot; height=&quot;720&quot;  src=&quot;https://coffeecode.net:443/uploads/talks/2013/postgresql_fts_9.png&quot;  alt=&quot;&quot; /&gt;
&lt;p&gt;The harvester is a Python 3 application that uses the ‘postgresql’ module to connect to the database.&lt;/p&gt;
&lt;p&gt;The REST and Web applications in the IA Harvester application are Python 2, largely because they use Flask (which iswas Python 2 only). But in the demo application, I’ve converted them to Python 3.&lt;/p&gt;
&lt;p&gt;While I could have simply written the Web and REST applications as a single Flask Web app that talks directly to the database, I opted to couple them via a JSON interface for a few reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Decoupling the web front end from the search back end means that I can augment or swap out either piece entirely without affecting the overall experience. &lt;/li&gt;
&lt;li&gt;If performance becomes an issue, I could add caching where profiling warrants it.&lt;/li&gt;
&lt;li&gt;If the service ends up being incredibly popular and PostgreSQL turns into a bottleneck, even with caching, I could set up a Solr or Sphinx instance instead.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I can change from Flask to another Web application framework on either piece.&lt;/p&gt;
&lt;p&gt;I can separate the hosts if I need to throw more hardware at the service, and/or virtualize it on something like Google App Engine.&lt;/p&gt;
&lt;!-- s9ymdb:368 --&gt;&lt;img class=&quot;serendipity_image_center&quot; width=&quot;960&quot; height=&quot;720&quot;  src=&quot;https://coffeecode.net:443/uploads/talks/2013/postgresql_fts_10.png&quot;  alt=&quot;&quot; /&gt;
&lt;p&gt;With so many Python web frameworks available, why Flask?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Routes as decorators was admittedly the biggest draw, simplifying routing enormously!&lt;/li&gt;
&lt;li&gt;Solid Unicode support was a must as well, as our newspapers are bilingual (English / French).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At the time I opted to try out Flask, the project’s public stance towards Python 3 was not warm. However, with the 0.10 release in June 2013, all that has (thankfully!) changed; Python 3.3 is supported.&lt;/p&gt;
&lt;!-- s9ymdb:369 --&gt;&lt;img class=&quot;serendipity_image_center&quot; width=&quot;960&quot; height=&quot;720&quot;  src=&quot;https://coffeecode.net:443/uploads/talks/2013/postgresql_fts_11.png&quot;  alt=&quot;&quot; /&gt;
&lt;p&gt;Flexible format:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;query: gives us the original query so we can echo that back to the user&lt;/li&gt;
&lt;li&gt;results: is a list of the highlighted snippets that we returned from our full-text search&lt;/li&gt;
&lt;li&gt;years: a facet that for the years in which hits were found, including the number of hits per year&lt;/li&gt;
&lt;li&gt;collections: a facet for the collections in which hits were found, including the number of hits per collection&lt;/li&gt;
&lt;li&gt;meta:&lt;ul&gt;
&lt;li&gt;total: the total number of hits&lt;/li&gt;
&lt;li&gt;page: the page we’re on&lt;/li&gt;
&lt;li&gt;limit: the number of hits per page&lt;/li&gt;
&lt;li&gt;results: the number of hits on this page of results&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;!-- s9ymdb:370 --&gt;&lt;img class=&quot;serendipity_image_center&quot; width=&quot;960&quot; height=&quot;720&quot;  src=&quot;https://coffeecode.net:443/uploads/talks/2013/postgresql_fts_12.png&quot;  alt=&quot;&quot; /&gt;
&lt;p&gt;We’ve already seen the decorator-route pattern before, and of course we need to quote, encode, and decode our search URL and results.&lt;/p&gt;
&lt;p&gt;The Flask-specific parts are helper methods for getting GET params from the query string, and rendering the template (in this case, via Jinja2), by passing in values for the template placeholders.&lt;/p&gt;
&lt;!-- s9ymdb:371 --&gt;&lt;img class=&quot;serendipity_image_center&quot; width=&quot;960&quot; height=&quot;720&quot;  src=&quot;https://coffeecode.net:443/uploads/talks/2013/postgresql_fts_13.png&quot;  alt=&quot;&quot; /&gt;
&lt;!-- s9ymdb:372 --&gt;&lt;img class=&quot;serendipity_image_center&quot; width=&quot;960&quot; height=&quot;720&quot;  src=&quot;https://coffeecode.net:443/uploads/talks/2013/postgresql_fts_14.png&quot;  alt=&quot;&quot; /&gt;
&lt;p&gt;At this point, the UI is functional but spartan. I’m a database / code guy, not a designer. Luckily, I have a student working on improving the front end (hi Emily!)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Further information:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Demonstration application:
&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://gitorious.org/postgresql-full-text-search-engine&quot;&gt;Gitorious repository&lt;/a&gt; / &lt;a href=&quot;https://github.com/dbs/postgresql-full-text-search-engine&quot;&gt;Github&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Internet Archive harvester project: &lt;a href=&quot;https://gitorious.org/ia-harvester&quot;&gt;https://gitorious.org/ia-harvester&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;PostgreSQL full-text search:
&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://postgresql.org/docs/9.3/static/textsearch.html&quot;&gt;PostgreSQL official documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://coffeecode.net/archives/260-Seek-and-ye-shall-find-full-text-search-in-PostgreSQL.html&quot;&gt;Seek and ye shall find: PostgreSQL full-text search (presentation at PostgresOpen 2012)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://flask.pocoo.org/docs&quot;&gt;Flask official docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://jinja.pocoo.org/docs&quot;&gt;Jinja2 official docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt; 
    </content:encoded>

    <pubDate>Sun, 11 Aug 2013 11:38:45 -0400</pubDate>
    <guid isPermaLink="false">https://coffeecode.net:443/archives/270-guid.html</guid>
    <category>coding</category>
<category>postgresql</category>
<category>python</category>

</item>
<item>
    <title>PyCon Canada 2013 - PostgreSQL full-text search and Flask</title>
    <link>https://coffeecode.net:443/archives/267-PyCon-Canada-2013-PostgreSQL-full-text-search-and-Flask.html</link>
            <category>Coding</category>
            <category>FSOSS</category>
            <category>PostgreSQL</category>
            <category>Python</category>
    
    <comments>https://coffeecode.net:443/archives/267-PyCon-Canada-2013-PostgreSQL-full-text-search-and-Flask.html#comments</comments>
    <wfw:comment>https://coffeecode.net:443/wfwcomment.php?cid=267</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>https://coffeecode.net:443/rss.php?version=2.0&amp;type=comments&amp;cid=267</wfw:commentRss>
    

    <author>dan@coffeecode.net (Dan Scott)</author>
    <content:encoded>
    &lt;p&gt;On August 10, 2013, I&#039;ll be giving a twenty-minute talk at PyCon Canada on &lt;a href=&quot;https://2013.pycon.ca/en/schedule/presentation/19/&quot;&gt;A Flask of full-text search with PostgreSQL&lt;/a&gt;. I&#039;m very excited to be talking about Python, at a Python conference, and to be giving the Python audience a peek at PostgreSQL&#039;s full-text search capabilities. With a twenty minute slot, I&#039;ll be leaning on my code4lib experience to compress the right amount of technical information into an entertaining package.&lt;/p&gt;
&lt;p&gt;Setting aside my talk, the line-up for PyCon Canada looks fantastic; the keynote speakers are &lt;a href=&quot;https://2013.pycon.ca/en/speaker/profile/92/&quot;&gt;Karen Brennan&lt;/a&gt;, &lt;a href=&quot;https://2013.pycon.ca/en/speaker/profile/93/&quot;&gt;Hilary Mason&lt;/a&gt;, and &lt;a href=&quot;https://2013.pycon.ca/en/speaker/profile/91/&quot;&gt;Jakob Kaplan-Moss&lt;/a&gt;, and there are a &lt;em&gt;ton&lt;/em&gt; of great talks. Did I mention that I&#039;m really looking forward to this conference?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update 2013-07-11:&lt;/strong&gt; Now that the schedule is official, the presentation URL needed to be updated. Also, the impetus for this proposal came straight from PGCon 2013, where the PostgreSQL community was urged to get the good word out about PostgreSQL to other communities. Et voila!&lt;/p&gt; 
    </content:encoded>

    <pubDate>Fri, 05 Jul 2013 05:00:24 -0400</pubDate>
    <guid isPermaLink="false">https://coffeecode.net:443/archives/267-guid.html</guid>
    <category>coding</category>
<category>fsoss</category>
<category>postgresql</category>
<category>python</category>

</item>

</channel>
</rss>