<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Blog von Slagwerks]]></title>
  <link href="http://slagwerks.com/blog/atom.xml" rel="self"/>
  <link href="http://slagwerks.com/blog/"/>
  <updated>2012-01-27T13:54:26-06:00</updated>
  <id>http://slagwerks.com/blog/</id>
  <author>
    <name><![CDATA[Joe Slag]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Hello, Octopress]]></title>
    <link href="http://slagwerks.com/blog/2012/01/19/hello-octopress/"/>
    <updated>2012-01-19T13:54:00-06:00</updated>
    <id>http://slagwerks.com/blog/2012/01/19/hello-octopress</id>
    <content type="html"><![CDATA[<p>New year, new VPS, new blog software. I was going to follow the path of
least resistance and just get wordpress set up here, since that&#8217;s what I
used to use, but somewhere in the thick of nginx+FastCGI PHP
configuration I just got sick of it all.</p>

<p>So, for something a little different, I&#8217;m giving
<a href="http://octopress.org/">Octopress</a> a try. Ruby-powered static publishing
&#8211; what&#8217;s not to like?</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[drive-by survey of Digital Asset Management in 2011]]></title>
    <link href="http://slagwerks.com/blog/2011/12/20/drive-by-survey-of-digital-asset-management-in-2011/"/>
    <updated>2011-12-20T07:17:52-06:00</updated>
    <id>http://slagwerks.com/blog/2011/12/20/drive-by-survey-of-digital-asset-management-in-2011</id>
    <content type="html"><![CDATA[<p><a href="http://www.flickr.com/photos/cdevers/5756248600/in/photostream/"><img src="http://farm3.staticflickr.com/2424/5756248600_cac16353c2_m.jpg" alt="enterprise" /></a>Beware; there is a lot of enterprisey phraseology thrown around this space. In my more cynical moments I wonder if there&#8217;s a <em>there</em> there, or just a bunch of selling. One challenge is that it is often unclear what people mean when they use a phrase such as &#8220;Digital Asset Management&#8221;, &#8220;Enterprise Content Management&#8221;, or even good ol&#8217; &#8220;Content Management&#8221;. <a href="http://en.wikipedia.org/wiki/Enterprise_content_management">Wikipedia&#8217;s ECM page</a> seems like a good overview of what I take to be the bigger problem space.</p>

<p>I do tend to wonder how many of these <code>/(asset|content) management/</code> problems could be solved with free accounts at <a href="http://www.tumblr.com/">tumblr</a> or <a href="http://wordpress.com/">wordpress</a>.</p>

<p>One minor surprise is the meagre <a href="http://www.amazon.com/gp/product/0240808681/ref=as_li_ss_tl?ie=UTF8&tag=slagwerks-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=0240808681">availablity</a><img src="http://www.assoc-amazon.com/e/ir?t=slagwerks-20&l=as2&o=1&a=0240808681" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
 of <a href="http://www.amazon.com/gp/product/0470855428/ref=as_li_ss_tl?ie=UTF8&tag=slagwerks-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=0470855428">wicked</a><img src="http://www.assoc-amazon.com/e/ir?t=slagwerks-20&l=as2&o=1&a=0470855428" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
 <a href="http://www.amazon.com/gp/product/0240806654/ref=as_li_ss_tl?ie=UTF8&tag=slagwerks-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=0240806654">old</a><img src="http://www.assoc-amazon.com/e/ir?t=slagwerks-20&l=as2&o=1&a=0240806654" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
 <a href="http://www.amazon.com/gp/product/0764573713/ref=as_li_ss_tl?ie=UTF8&tag=slagwerks-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=0764573713">books</a><img src="http://www.assoc-amazon.com/e/ir?t=slagwerks-20&l=as2&o=1&a=0764573713" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
 in this area. Does nobody want to write about this topic, or is there no market for it, or what?</p>

<p>If you are using the phrase &#8220;Digital Asset Management&#8221; in its more tightly defined sense, there are a plethora of existing software solutions, many of which are open source. Of the latter, most tend to be written in <del datetime="2011-12-19T20:06:15+00:00">XML</del> java, with some php options too. Pardon me while I stifle my enthusiasm.</p>

<p>Poking around did reveal one python-based option: <a href="http://www.notredam.org/">NotreDAM</a>. The sense of humor is appreciated in this space. It doesn&#8217;t look like the project is <a href="http://opendam.freeforums.org/who-s-using-notredam-reference-t64.html">super established yet</a> but it looks promising.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Back Button + AJAX + JSON oddity]]></title>
    <link href="http://slagwerks.com/blog/2011/10/13/back-button-ajax-json-oddity/"/>
    <updated>2011-10-13T09:54:23-05:00</updated>
    <id>http://slagwerks.com/blog/2011/10/13/back-button-ajax-json-oddity</id>
    <content type="html"><![CDATA[<p><em>Disclaimer: this may be completely obvious to front end wizards, of which I am not.</em></p>

<p>I ran into an elusive AJAX gotcha the other day: whenever I hit the &#8216;back&#8217; button after completing a certain task on a current project, rather than see the page I&#8217;d just been on, I got a raw JSON payload that had been requested by that page. After some trial and error I think I&#8217;ve figured out what was going on:</p>

<p>As I gather, when a given URL (let&#8217;s say /foo) is requested normally by the browser and then via JSON, the browser decides to remember the last version it saw, which happens to be the JSON payload. This might happen in a Rails application if you had a controller method behaving differently based on <code>request.xhr?</code> So when you click &#8216;back&#8217;, rather than your finely crafted HTML and CSS, the browser returns tag soup. Not cool. I guess I&#8217;ve never run into this before since I&#8217;ve never before had an app with the sequence of <code>GET /foo, GET /foo</code> (the latter asking for JSON rather than HTML).</p>

<p>If you&#8217;re requesting the JSON via jQuery, a solution is straightforward. Setting the <code>cache</code> argument to false prevents the browser from overwriting the full HTML version of the page in its history. See <a href="http://api.jquery.com/jQuery.ajax/">http://api.jquery.com/jQuery.ajax/</a> for more.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Functional Tests in RefineryCMS 1.0]]></title>
    <link href="http://slagwerks.com/blog/2011/06/24/functional-tests-in-refinerycms-1-0/"/>
    <updated>2011-06-24T10:14:38-05:00</updated>
    <id>http://slagwerks.com/blog/2011/06/24/functional-tests-in-refinerycms-1-0</id>
    <content type="html"><![CDATA[<p>The Refinery CMS is apparently <a href="http://www.ruby-toolbox.com/categories/content_management_systems.html">the most used chunk of CMS code</a> in the rails ecosystem. Version 1.0 came out recently, and one of the recent changes involved the authentication system. Previously, Refinery had bundled <a href="https://github.com/binarylogic/authlogic">authlogic</a>; now it&#8217;s using <a href="https://github.com/plataformatec/devise">Devise</a>.</p>

<p>If you&#8217;re not doing anything worth testing on the admin side, the authlogic / Devise switch doesn&#8217;t make a difference. Still, there is one snag to overcome even in functional tests of your public code: a Refinery installation will direct all requests to a screen for creating the initial user, until said superuser is created. This applies as much to your empty test database as to a newly created Refinery site.</p>

<h3>Public-facing URLs</h3>


<p>An admin user needs to exist, but doesn&#8217;t have to be logged in. The default admin has roles &#8216;Refinery&#8217; and &#8216;Superuser&#8217;, so I create such a user via <a href="https://github.com/thoughtbot/factory_girl_rails">factory_girl</a> <sup><a href="#1">1</a></sup>:</p>

<script src="https://gist.github.com/1043552.js"> </script>


<p>Then within functional classes, we simply need to create that user:
<code><pre>
def setup
  admin = Factory.create(:user)
end
</pre></code></p>

<h3>Admin URLs</h3>


<p>If you want to check admin-side code in functional tests, the admin user needs to be logged in.  I had a solution under the old setup, but had to make a few changes after the move to Devise. Here&#8217;s what&#8217;s working now:</p>

<script src="https://gist.github.com/1043625.js"> </script>


<p><b><a name="1">1</a></b>: well, factory_girl_rails is needed for rails 3, and it includes factory_girl. The <em>stable</em> version of factory_girl, which has a different syntax than the master code you&#8217;d see at the factory_girl github page. Confusing!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Mirroring subversion projects on GitHub: worth it]]></title>
    <link href="http://slagwerks.com/blog/2011/06/08/mirroring-subversion-projects-on-github-worth-it/"/>
    <updated>2011-06-08T11:08:31-05:00</updated>
    <id>http://slagwerks.com/blog/2011/06/08/mirroring-subversion-projects-on-github-worth-it</id>
    <content type="html"><![CDATA[<p>I&#8217;ve been working with a sizable open source project hosted on subversion lately, and cringing at how long it took to just run <code>svn status</code> or <code>svn diff</code> to verify my local changes. Also not enjoying the need to do stuff like <pre>diff -Nrc -x '.svn' -x target v1.6 local_16/ > ../local_changes.diff</pre> to capture my changes between upstream releases.</p>

<p>Better late than never, I spent a few minutes this week getting the project <a href="https://github.com/jslag/CollectionSpace-Services">mirrored on GitHub</a>, thanks to pointers from the following two resources. I&#8217;d say it&#8217;s already paid off in time saved in just the two days since.</p>

<ul>    <li><a href="http://jonathanrobson.me/2010/11/how-to-mirror-a-subversion-repository-on-github">http://jonathanrobson.me/2010/11/how-to-mirror-a-subversion-repository-on-github</a></li>
<li><a href="http://www.dmo.ca/blog/20070608113513/">http://www.dmo.ca/blog/20070608113513/</a></li></ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[I endorse this approach to Vim JSON syntax highlighting]]></title>
    <link href="http://slagwerks.com/blog/2011/05/31/i-endorse-this-approach-to-vim-json-syntax-highlighting/"/>
    <updated>2011-05-31T11:03:47-05:00</updated>
    <id>http://slagwerks.com/blog/2011/05/31/i-endorse-this-approach-to-vim-json-syntax-highlighting</id>
    <content type="html"><![CDATA[<p>True, there is a vim plugin that provides JSON syntax highlighting, but why not just use the existing javascript rules? <a href="http://www.codeography.com/2010/07/13/json-syntax-highlighting-in-vim.html">Respect to Christopher Sexton</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[In which one book is reviewed and another recommended]]></title>
    <link href="http://slagwerks.com/blog/2011/01/06/in-which-one-book-is-reviewed-and-another-recommended/"/>
    <updated>2011-01-06T14:02:14-06:00</updated>
    <id>http://slagwerks.com/blog/2011/01/06/in-which-one-book-is-reviewed-and-another-recommended</id>
    <content type="html"><![CDATA[<p>Twitter followers, you may have noticed that I&#8217;ve been reading Gary Taubes&#8217; <em><a href="http://www.amazon.com/gp/product/1400033462?ie=UTF8&amp;tag=slagwerks-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=1400033462">Good Calories, Bad Calories</a><img style="border: none !important; margin: 0px !important;" src="http://www.assoc-amazon.com/e/ir?t=slagwerks-20&amp;l=as2&amp;o=1&amp;a=1400033462" border="0" alt="" width="1" height="1" />
</em> over the last few weeks. It may be the most mind-blowing thing I&#8217;ve ever read, certainly in the last few years, if not decades. But I think I&#8217;m going to recommend reading another book instead.</p>

<p>GCBC is the result of five years of reasearch on Taubes&#8217; part (he&#8217;s a science journalist by trade), and weighs in at 460 pages, plus 113 pages of footnotes. It covers the last 100 years of medical and scientific thinking on the connections between food and health, focusing particularly on what aspects of diet may lead to overweight, diabetes, and heart disease.</p>

<p>I despair a bit at summarizing these 460 pages of reasonably technical science history (very readable, I will add). As a teaser, I will say that one major surprise is the all but complete lack of evidence behind the low-fat diets commonly advocated. Another shocker is Taubes&#8217; dismantling of the &#8220;calories in, calories out&#8221; equation, eg. &#8220;you lose weight if you burn more calories than you consume, and vice versa&#8221;. I&#8217;d always been a firm believer in that equation, but not any more.</p>

<p>While I seem to have been blessed with a genetic makeup that resists putting on extra weight (thanks mom &amp; dad!), having my beliefs about the connections between food and health upended is still quite an experience, and it&#8217;s one that other naturally lean folks would benefit from too. If nothing else, my sympathy and understanding for people who do wrestle with the &#8220;diseases of civilization&#8221; is much greater now.</p>

<p><a href="http://www.amazon.com/gp/product/0307272702?ie=UTF8&amp;tag=slagwerks-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0307272702"><img src="http://slagwerks.com/blog/blog/wp-content/uploads/51b0qV-LrxL._SL160_.jpg" border="0" alt="" style="float: right;"/></a><img style="border: none !important; margin: 0px !important;" src="http://www.assoc-amazon.com/e/ir?t=slagwerks-20&amp;l=as2&amp;o=1&amp;a=0307272702" border="0" alt="" width="1" height="1" />If you are a public health professional, endocrinologist, or the like, GCBC is well worth the effort, because it would be important for you to see all the gory details where your profession went wrong, and what the evidence actually says. But for everyone else, I&#8217;m guessing there&#8217;s more profit to be had by checking out Taubes&#8217; newer, shorter book <em><a href="http://www.amazon.com/gp/product/0307272702?ie=UTF8&amp;tag=slagwerks-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0307272702">Why We Get Fat: And What to Do About It</a><img style="border: none !important; margin: 0px !important;" src="http://www.assoc-amazon.com/e/ir?t=slagwerks-20&amp;l=as2&amp;o=1&amp;a=0307272702" border="0" alt="" width="1" height="1" /></em> which seems to be the core of GCBC, with some of the more confusing parts explained more clearly, and more prescriptive material for what and how to actually eat.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Heroku + Refinery + SSL]]></title>
    <link href="http://slagwerks.com/blog/2010/12/10/heroku-refinery-ssl/"/>
    <updated>2010-12-10T18:36:05-06:00</updated>
    <id>http://slagwerks.com/blog/2010/12/10/heroku-refinery-ssl</id>
    <content type="html"><![CDATA[<p>Say you&#8217;re hosting a <a href="https://github.com/resolve/refinerycms">refinerycms</a> site on Heroku, and would like to rewrite all admin access to use Heroku&#8217;s <a href="http://addons.heroku.com/ssl">free piggyback SSL</a>.</p>

<p>Say also that you have a few different environments, accessible via your own domain (<em>http://mysite-dev.mydomain.com</em>).
The following in your application controller seems to do the trick:</p>

<script src="https://gist.github.com/736978.js"> </script>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Tip for New Sinatra Deployers]]></title>
    <link href="http://slagwerks.com/blog/2010/07/23/tip-for-new-sinatra-deployers/"/>
    <updated>2010-07-23T17:30:39-05:00</updated>
    <id>http://slagwerks.com/blog/2010/07/23/tip-for-new-sinatra-deployers</id>
    <content type="html"><![CDATA[<p>If you get the error <code>undefined method `application' for Sinatra:Module</code> and your config.ru includes the line <code>run Sinatra.application</code>, try changing that to <code>run Sinatra::Application</code> and it should actually work.</p>

<p>(via http://www.sinatrarb.com/one-oh-faq)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Does 201 CMR 17 apply to VOIP?]]></title>
    <link href="http://slagwerks.com/blog/2010/05/13/does-201-cmr-17-apply-to-voip/"/>
    <updated>2010-05-13T12:46:58-05:00</updated>
    <id>http://slagwerks.com/blog/2010/05/13/does-201-cmr-17-apply-to-voip</id>
    <content type="html"><![CDATA[<p>Background: looking at going to a Voice Over IP phone system at work. Wondering if Massachusetts&#8217; new law about information security applies.</p>

<p><strong>Why it might not:</strong> a potential (MA based) vendor we&#8217;re talking to says</p>

<blockquote>We&#8217;ve not been asked this before and about 201 CMR 17 Compliance and IÂ don&#8217;t particularly think it applies to our VoIP, or VoIP in general</blockquote>


<p><strong>Why it might:</strong> Section 17.04 qualifies theÂ applicabilityÂ of the rule to</p>

<blockquote>Every person that owns or licenses personal information about a resident of the Commonwealth and electronically stores or transmits such information shall include&#8230;aÂ security system covering its computers, including any wireless system</blockquote>


<p>Like just about any business, we definitely transmit personal information over our phone system, so I think the technical / legal question is whether an electronic phone system of the type in question is covered under the &#8220;its computers&#8221; phrase.</p>

<p>Stepping back from the legal to the practical, however, it seems fair to expect reasonable information security from our communications systems, including VOIP. At least in its intent, I think that&#8217;s what 201 CMR 17 is after. VOIP is still new enough that I suspect many prospective customers (like us!) aren&#8217;t quite sure what constitutes a reasonably secure installation, though we sense that there are all kinds of potential attack vectors not present in POTS.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Ruby & NoSQL @ Vermonster]]></title>
    <link href="http://slagwerks.com/blog/2010/04/02/ruby-nosql-vermonster/"/>
    <updated>2010-04-02T09:20:08-05:00</updated>
    <id>http://slagwerks.com/blog/2010/04/02/ruby-nosql-vermonster</id>
    <content type="html"><![CDATA[<p><strong>Update</strong>: Vermonster has a <a href="http://vermonster.com/2010/03/31/nosql-workshop-featuring-riak-and-couchdb/">nice recount</a>, chock full of code &amp; explanations.</p>

<p>A fine time was had the other night in the offices of Boston&#8217;s <a href="http://vermonster.com/">Vermonster</a>, when a few Vermonsters generously helped some folks fromÂ <a href="http://bostonrb.org/">Boston.rb</a> get up to speed on the use of some NoSQL projects from Ruby.</p>

<p>Up until now, I&#8217;ve been a little leery of NoSQL. Probably due to painful past experience withÂ <a href="http://en.wikipedia.org/wiki/ZODB">ZODB</a> failing to keep up with moderate loads, and reading too many Philip Greenspun essays at an impressionable age.Â Happily, it appears that the projects collected under the NoSQL banner can actually walk and chew gum at the same time, without rendering your data unreasonably inconsistent.</p>

<p>The whole question of the Consistency of one&#8217;s data is addressed by theÂ <a href="http://www.julianbrowne.com/article/viewer/brewers-cap-theorem">CAP</a> theory, which I understand to roughly say</p>

<blockquote>Consistency, Availability, Partitionability: pick (at most) two, particularly under certain challenging conditions such as running Google or Amazon.</blockquote>


<p>Even if you aren&#8217;t running something quite that big, there seem to be some situations where you&#8217;d want to think about this stuff &#8211; for example, running an app on Google&#8217;s App Engine (right? Haven&#8217;t yet myself.) Plus, all the cool kids are into it.</p>

<p>We worked with the locally-writtenÂ <a href="http://riak.basho.com/">Riak</a> (looks like it&#8217;s the topic of the April Boston.rb meeting!) and with CouchDB. Both are ridiculously easy to get running locally, have Ruby client libraries, and are powered mainly by Erlang, with javascript Map/Reduce. For the latter, we used the couch_potato library, which seems to do a nice job of writing your javascript for you in the most common cases.</p>

<p>We wrapped the evening up with a coding challenge. My brain was fried &amp; I gave up 2/3rds of the way through, but still had a blast &amp; learned plenty. As a side benefit, beyond the exposure to the NoSQL, my state-of-the-art-circa-2008 Ruby habits got challenged by working with RSpec, 1.9.1, and RVM, all of which will should prove handy for future things.</p>

<p>Big ups toÂ Vermonster for hosting, feeding, and educating us. They are good guys, skilled teachers, and have excellent taste in beverages.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Snow Leopard still a mixed bag]]></title>
    <link href="http://slagwerks.com/blog/2010/02/02/snow-leopard-still-a-mixed-bag/"/>
    <updated>2010-02-02T11:56:54-06:00</updated>
    <id>http://slagwerks.com/blog/2010/02/02/snow-leopard-still-a-mixed-bag</id>
    <content type="html"><![CDATA[<p>I&#8217;ve been trying out Mac OS 10.6 a.k.a. Snow Leopard for a few weeks now. For the most part it looks and acts&#8230; just like Leopard! Still, I have run into the following annoyances:</p>

<ul>
    <li>Doesn&#8217;t really want to do more than one thing if you only have 1 GB RAM, veryÂ noticeably worse than Tiger in this regard (never ran Leopard much on only 1 GB).Â Â I guess there are more <code>int</code>s running in the OS &amp; in basic apps than I would have thought, if it is the 64bitness to blame.</li>
    <li>Doesn&#8217;t work with our older b/g Airport Extreme. Says it&#8217;s on the wireless network, but doesn&#8217;t configure TCP/IP settings &#8211; this is after much experimenting with various Airport settings. Search for &#8216;snow leopard wireless&#8217; for a variety of related complaints.</li>
    <li>Doesn&#8217;t work with the Citrix XenApp web plugin. To be fair, this seems to be due to Citrix expecting Java 1.5 to be installed, which is kind of lame. Workarounds are reported on the internets, but then you&#8217;re managing your own Java installation, which seems to be one of the most vulnerability-plagued pieces of OS X.</li>
</ul>


<p>My conclusion, as of 10.6.2: no reason to upgrade from Leopard, unless you&#8217;ve bought brand-new hardware that requires SL.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[latest 201 CMR 17 hotness]]></title>
    <link href="http://slagwerks.com/blog/2010/01/15/latest-201-cmr-17-hotness/"/>
    <updated>2010-01-15T08:54:48-06:00</updated>
    <id>http://slagwerks.com/blog/2010/01/15/latest-201-cmr-17-hotness</id>
    <content type="html"><![CDATA[<p>You could be excused for having missed the news, but the 201 CMR 17 that was just about to go into effect <a href="http://slagwerks.com/blog/index.php/2008/10/22/looking-further-into-ma-regulation-201-cmr-1700/">over a year ago</a>&#8230; is now <a href="http://www.hklaw.com/id24660/PublicationId2727/ReturnId31/contentid54375/">just about to go into effect</a>!</p>

<p>some tidbits:</p>

<ul>
    <li>201 CMR may even <a href="http://arielsilverstone.com/library/201-cmr/">apply to entities entirely outside of MA</a>, as long as they have any data about Massholes in their systems. So don&#8217;t get all smirky in Texas or wherever.</li>
    <li>Who knew? Martha Coakley, as AG, gets credit for helping adjust 201 CMR to <a href="http://privacylaw.proskauer.com/tags/201-cmr-1700/">work better with business&#8217; realities</a>. That, and her Harpoon preference, really ought to be pushed more strongly by the campaign.</li>
    <li>A useful collection of info can be found at <a href="http://201cmr17.com/">one of the ugliest websites in recent memory</a>.</li>
</ul>


<p>Fortunately, there doesn&#8217;t seem to be anything particularly unreasonable in the requirements, so organizations following good data security procedures shouldn&#8217;t have to do much work (if any) to be compliant.</p>

<ul></ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Testing Backups]]></title>
    <link href="http://slagwerks.com/blog/2010/01/07/testing-backups/"/>
    <updated>2010-01-07T09:55:20-06:00</updated>
    <id>http://slagwerks.com/blog/2010/01/07/testing-backups</id>
    <content type="html"><![CDATA[<p>I&#8217;m putting together our backup testing plan, and marveling at the suggestions in Preston&#8217;s <a href="http://www.backupcentral.com/components/com_mambowiki/index.php?title=Category:Backup_%26_Recovery_Book_Wiki&amp;Itemid=104">Backup and Recovery</a>. Here&#8217;s my paraphrase:</p>

<ul>
    <li>restore many single files</li>
    <li>restore older versions of files</li>
    <li>restore entire drive / filesystem, compare to original (same size? etc.)</li>
    <li>recreate entire system</li>
    <li>pretend a given backup volume is bad, use alternate</li>
    <li>restore without touching backup server (as if it were destroyed)</li>
    <li>include database restores, inc. database at different point in time</li>
    <li>dream up painful scenarios with pessimists, test for those regularly</li>
</ul>


<p>To actually do these tests, he suggests making a list &amp; randomly picking a subset to test on a monthly basis.</p>

<p>Fun, huh? Beats holding the bag when your organization&#8217;s vital data goes missing.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[python script for importing maildirs to gmail]]></title>
    <link href="http://slagwerks.com/blog/2009/11/05/python-script-for-importing-maildirs-to-gmail/"/>
    <updated>2009-11-05T12:57:07-06:00</updated>
    <id>http://slagwerks.com/blog/2009/11/05/python-script-for-importing-maildirs-to-gmail</id>
    <content type="html"><![CDATA[<p>In fact <a href="http://github.com/jslag/gml">the script in question</a> should work also for mboxes and for other SMTP servers, but maildir-to-gmail was the problem I was trying to solve.</p>

<p>The most promising starting point was an <a href="http://marklyon.org/gmail/old/default.htm">old script by Mark Lyon</a>. After a little rejiggering so I could see what error was coming back from Google, I made a couple of more tweaks to use TLS &amp; to take the user&#8217;s password.</p>

<p>If anyone&#8217;s interested in what seemed to me a strange hoop to hop through before connecting, <a href="http://github.com/jslag/gml/blob/master/gml.py#L72">check the src</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Considering how to reliably jam stuff into FileMaker from the web]]></title>
    <link href="http://slagwerks.com/blog/2009/10/23/considering-how-to-reliably-jam-stuff-into-filemaker-from-the-web/"/>
    <updated>2009-10-23T11:43:52-05:00</updated>
    <id>http://slagwerks.com/blog/2009/10/23/considering-how-to-reliably-jam-stuff-into-filemaker-from-the-web</id>
    <content type="html"><![CDATA[<p>I&#8217;m sure I&#8217;m not the only person with this situation:</p>

<ol>
    <li>FileMaker database sitting behind a firewall (though similar issues would pertain for other internal databases / services)</li>
    <li>Website hosted elsewhere (i.e. other side of firewall)</li>
    <li>Need to get data from #2 to #1 reliably and securely</li>
</ol>


<p>Up until today, I&#8217;ve only had one instance of #2 in this situation. I dealt with it by storing data collected on the website (which happened to be written in Rails) in a database on the web server, and then running a periodic PHP script on the FileMaker server that connects to the Rails app via <a href="http://github.com/lux/phpactiveresource">phpactiveresource</a>, pulls in pending data, and inserts it into FileMaker via its PHP api.</p>

<p>That instance was such a roaring success that the requests have been pouring in for more of the same. Some of the new requests will be handled by a site running PHP, so I&#8217;ve got a bit of rewiring to do &#8211; I can&#8217;t see any sense in the getting the data from the PHP app into something the Active Resource client can talk to.</p>

<p>Stepping back and looking at the bigger picture, issues here include:</p>

<ul>
    <li>the connection from the website to the FileMaker server could be down, so data collected by the website needs to be stored until it can be confirmed to have made it to FileMaker.</li>
    <li>it would be nice for this to happen in a timely fashion</li>
    <li>multiple technologies on the web side (PHP &amp; ruby) are going to be collecting data to be submitted to FileMaker, so it&#8217;d be nice if the transfer machinery can be agnostic and just accept JSON or XML or something.</li>
</ul>


<p>Sounds like a problem for a queue system, huh? So my current plan is to run a <a href="http://kr.github.com/beanstalkd/">beanstalkd</a> instance on the webserver, deposit JSON-endocded data into it from the web sites, and run workers that write to FileMaker using the <a href="http://github.com/lardawge/rfm">Ruby FM API</a>. I have no experience with beanstalkd, but a bit of googling suggests that it&#8217;s at a nice point in simplicity to configure &amp; run, maturity, light weight, and easy access from PHP &amp; Ruby.</p>

<p>A further benefit of working in beanstalkd is that, based on a quick perusal of the <a href="http://async-observer.rubyforge.org/">recommended Rails integration</a>, it should be really easy to break Observers out to async code, thus making my rails apps snappier.</p>

<p>Any advice to the contrary is of course welcome. I&#8217;ll try to remember to update y&#8217;all on how this turns out.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Custom flickr sidebar via wget, cron & PHP]]></title>
    <link href="http://slagwerks.com/blog/2009/07/29/custom-flickr-sidebar-via-wget-cron-php/"/>
    <updated>2009-07-29T10:33:15-05:00</updated>
    <id>http://slagwerks.com/blog/2009/07/29/custom-flickr-sidebar-via-wget-cron-php</id>
    <content type="html"><![CDATA[<p><a href="http://thefoodproject.org/">The new site</a> launched with a sidebar that shows two random photos from our flickr account, using their javascript widget. This was a great way to get things going, but now we&#8217;ve developed slightly more involved needs and I&#8217;ve had to come up with a custom solution.</p>

<h3>Getting the list of photos</h3>


<p>You need a flickr API key, which is quick &amp; easy to get. Then wget &amp; cron to get &#8216;em: <code>wget --quiet 'http://api.flickr.com/services/rest/?method=flickr.photos.search&amp;api_key=YOUR_API_KEY&amp;user_id=YOUR_USER_ID&amp;tags=website&amp;per_page=500' -O photos.xml</code></p>

<p>Note that this includes a <em>tags</em> argument. The thing that pushed me to switch the workflow was the desire to be able to upload photos to our flickr account that don&#8217;t necessarily fit into the sidebar format, such as panoramics. To handle this, everything that belongs on the website gets the tag <em>website</em>, and we only fetch those ones. We&#8217;ve also talked about just getting landscape oriented photos, but haven&#8217;t implemented that.</p>

<p>I&#8217;m running this daily, which is plenty often to update the available photo list. I believe this gets the newest 500, which seems more than adequate, particularly since we don&#8217;t have close to 500 photos yet.</p>

<h3>Parsing the list &amp; generating the HTML</h3>


<p>PHP5&#8217;s SimpleXML is pretty nice &#8211; here&#8217;s what we&#8217;re doing:
<code> </code></p>

<pre>try {
  $xml = new SimpleXMLElement(file_get_contents('photos.xml'));
    $number_of_photos = count($xml-&gt;photos-&gt;photo);
    $displayed_photos = array();
    array_push(
      $displayed_photos,
      $xml-&gt;photos-&gt;photo[rand(0, $number_of_photos - 1)]);
   Â array_push(
     Â $displayed_photos,
      $xml-&gt;photos-&gt;photo[rand(0, $number_of_photos - 1)]);
    foreach ($displayed_photos as $photo) { ?&gt;
  &lt;div&gt;
&lt;?php
      print "&lt;a href=\"http://www.flickr.com/photos/8562013@N07/" .
        $photo['id'] . "\"&gt;&lt;img src=\"http://farm" . $photo['farm'] .
        ".static.flickr.com/" . $photo['server'] . "/" . $photo['id'] . "_" .
        $photo['secret'] .Â  "_m.jpg\" alt=\"" . $photo['title'] . "\" /&gt;&lt;/a&gt;";
?&gt;
  &lt;/div&gt;
&lt;?php
 }
} catch (Exception $e) {
  error_log("flickr badge had some troubles: " .
    $e-&gt;getMessage());
}</pre>


<p>This snippet takes my laptop less than 1/20th of a second to run from the command line, which suits me fine. The actual code sits in <code>page.tpl.php</code>.</p>

<p><a href="http://www.flickr.com/services/api/">Flickr&#8217;s API docs</a>, in particular the API Explorer, were awful handy in figuring this all out.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Joe's hacky approach to getting arbitrary behavior out of Drupal]]></title>
    <link href="http://slagwerks.com/blog/2009/07/28/joes-hacky-approach-to-getting-arbitrary-behavior-out-of-drupal/"/>
    <updated>2009-07-28T15:42:39-05:00</updated>
    <id>http://slagwerks.com/blog/2009/07/28/joes-hacky-approach-to-getting-arbitrary-behavior-out-of-drupal</id>
    <content type="html"><![CDATA[<p><em>Wherein I disqualify myself for work as a &#8220;drupal developer&#8221;</em></p>

<h3>Self indulgent history part</h3>


<p>Way back in 1999 when I started out writing web apps, <a href="http://perl.apache.org/embperl/">Embperl</a> seemed like the logical tool to use &#8211; so I&#8217;m used to having direct access to every step in the request-to-response process. In years since, I&#8217;ve progressed through a bunch of different tools and approaches, which have included writing a few rudimentary content management systems and using a bunch of prexisting ones.</p>

<p>Over the last few years I&#8217;ve become a big fan of ruby on rails, so if a site does much of anything (simple, recent example: The Food Project&#8217;s online <a href="http://apply.thefoodproject.org">summer program application</a>), that&#8217;d be my starting point.</p>

<h3>so, why use Drupal?</h3>


<p>Even so, when a site is basically about some content that&#8217;s written and edited on an ongoing basis by other folks, Drupal starts looking like a reasonable tool. It&#8217;s pretty easy to get it to generate semantic output with reasonable URLs, and the editor-facing UI does a fair job of offerring a large degree of control and customizability without being overwhelmingly complex.</p>

<p>Despite having done some <a href="http://jamaicaplaingazette.com/node/2568">custom work</a> <a href="http://womenslunchplace.org/biographical-sketch-sharon-reilly">on a few</a> live Drupal sites, I still get confused about the best way to do some of the arbitrary web interaction tasks that were so straightforward back in the Embperl days. There are a billion modules in the Drupal ecosystem, but I often find that it takes more time to figure out if there is an appropriate one for my task &amp; if it works with the current version of Drupal than it would to code up a solution on my own. Also, while I&#8217;ve made several attempts to solve programming tasks in what I understand to be the Drupal way, wrapping my head around all the relevant APIs (which can totally change every 6-12 months, with each Drupal release) similarly tends to take more time than bypassing Drupal&#8217;s functionality &amp; handling things in Plain Old PHP.</p>

<p>Here&#8217;s a common approach I&#8217;ll take, then. I have no interest in extensive coding through a web browser (i.e. <a href="http://drupal.org/handbook/customization/php-snippets">putting a bunch of PHP in a node or block</a>), so I&#8217;ll set up a Drupal module to hold my application&#8217;s arbitrary php functions. Then I&#8217;ll create a page at the desired URL and enter a line of PHP to route the GET and/or POST to my code, as appropriate.</p>

<h3>Example</h3>


<p>I&#8217;m working on an email list signup that needs to communicate with a FileMaker database. An HTML form POSTs to http://thefoodproject.org/mailing_list_signup, which is just a Drupal page using the PHP input filter (which you now need to turn on via admin settings) containing <code>&lt;?php tfp_process_list_signup($_POST); </code> The code for that function lives in sites/all/modules/tfp/tfp.module, and does the normal PHP things to pull information out of the POST &amp; hand that info off to the FileMaker database. Here&#8217;s a bit of it:</p>

<p><code><pre>function tfp_process_list_signup($<em>POST) {
  $reply = '';
  $sent_plausible_address = FALSE;
  if ($</em>POST['email']) {</p>

<pre><code>$supplied_email = $_POST['email'];
if (preg_match(PLAUSIBLE_EMAIL, $supplied_email)) {
  $sent_plausible_address = TRUE;
  $reply = "Thanks! We'll add your to our mailing list.";
} else {
  $reply = "'$supplied_email' doesn't look like an email address to me. ";
}
//. . .
</code></pre>

<p>  }
  return $reply;
}</pre></code></p>

<p>On the upside, this is quick &amp; easy. The downside with this approach vs. writing a module the Drupal way is that I&#8217;m losing out on Drupal&#8217;s <a href="http://api.drupal.org/api/file/developer/topics/forms_api.html">form API</a> and its associated validation, antispoofing, etc. services. On the upside, last time I checked the linked documentation for the form API, it said</p>

<blockquote><strong>Warning - this page has only been partially updated for the Drupal 6.x API
</strong>Until it has been fully updated, reference this page as well:  <a href="http://drupal.org/node/144132">Drupal 5.x to 6.x FormAPI changes</a></blockquote>


<p>so I&#8217;m quite happy to not have to wade through all of that!<!--more--></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Lazyweb: 5 hr layover in Amsterdam airport?]]></title>
    <link href="http://slagwerks.com/blog/2009/07/20/lazyweb-5-hr-layover-in-amsterdam-airport/"/>
    <updated>2009-07-20T15:04:53-05:00</updated>
    <id>http://slagwerks.com/blog/2009/07/20/lazyweb-5-hr-layover-in-amsterdam-airport</id>
    <content type="html"><![CDATA[<p>Any readers out there who know what options exist for a 5 hr layover in Amsterdam? This is before an international flight, so it&#8217;s not like I have 5 actual hours to play with. A (not this) Friday morning.</p>

<p>Wikipedia claims it&#8217;s a 20 minute trip into the city, which suggests that some minimal tourism should be possible&#8230;</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[checking auth in Apache over LDAP with OS X]]></title>
    <link href="http://slagwerks.com/blog/2009/05/27/checking-auth-in-apache-over-ldap-with-os-x/"/>
    <updated>2009-05-27T10:32:57-05:00</updated>
    <id>http://slagwerks.com/blog/2009/05/27/checking-auth-in-apache-over-ldap-with-os-x</id>
    <content type="html"><![CDATA[<p>Here&#8217;s the configuration I&#8217;ve been working on: control access to Apache webserver by checking (over LDAP) against our existing user database, held in an OS X Open Directory. It&#8217;s taken me more casting about than I&#8217;d expected, but it looks like I&#8217;m finally there.</p>

<p>In the beginning, I got a little confused by the HTTP auth options. I&#8217;d been hoping to use Digest mode, but a comment on <a href="http://www.latenightpc.com/blog/archives/2007/08/31/no-authtype-digest-with-ldap-authentication-provider-for-apache-today">this post</a> points out the logical problem with that: Digest doesn&#8217;t involve the password making its way to Apache, so there&#8217;s no way for it to pass the password along over LDAP.</p>

<p>BTW this is under Tiger (OS X 10.4) &#8211; I&#8217;m not sure if anything changes with other versions of OS X.</p>

<p>Once figuring out that I did need to use Basic auth, <a href="http://www.productionmonkeys.net/guides/web-server/apache/ldap-authentication">Production Monkeys</a> got me most of the way with my Apache config. What I missed is that, at least with our OD configuration, it&#8217;s necessary to include the server name in the dc list. Here&#8217;s what worked for me:</p>

<p><code>&lt;Location "/somewhere"&gt;
AuthType Basic
AuthName "Whatever You Call This Auth"
Require valid-user
AuthBasicProvider ldap
AuthLDAPURL ldap://servername.yourdomain.org/cn=users,dc=servername,dc=yourdomain,dc=org?uid
AuthzLDAPAuthoritative off
&lt;/Location&gt;</code></p>
]]></content>
  </entry>
  
</feed>

