<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom">
  <title>Bill Lovett</title>
  <link href="http://ilovett.com" />
  <link rel="self" href="http://ilovett.com/blog/feed" />
  <updated>2010-09-01T00:00:00-07:00</updated>
  <author>
    <name>Bill Lovett</name>
    <uri>http://ilovett.com</uri>
  </author>
  <id>http://ilovett.com/</id>
    <entry>
    <title>Command Line JavaScript Validation</title>
    <link href="http://ilovett.com/blog/frontend-util/command-line-javascript-validation" />
    <id>http://ilovett.com/blog/frontend-util/command-line-javascript-validation</id>
    <published>2010-09-01T00:00:00-07:00</published>
    <updated>2010-09-01T00:00:00-07:00</updated>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
      </div>
    </summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>Let's make <a href="http://www.jslint.com/">JSLint</a> easier to run
by calling it from the command line via wrapper script. Let's also
incorporate Google's <a
href="http://code.google.com/closure/utilities/docs/linter_howto.html">Closure
        Linter</a> while we're at it for double the fun.</p>

<p><a
href="http://github.com/ilovett-com/frontend-util/blob/master/validate-js">Here's
        the finished product</a>. Read on for further details.</p>


<h2>Why?</h2>

<p>Linters make your code look better to machines as well as humans.
They point out stupid typos and petty errors. They enforce best
practices and consistent style, and prevent you from lapsing just
because you were in a hurry. Best of all, they let you know whether
    you're really as good as you think you are.</p>

<h2>Scenarios for Running JSLint</h2>

<p>There are lots of ways to incorporate JSLint into your workflow, but
none were as low-effort as I wanted. <a
href="http://www.emacswiki.org/emacs/FlymakeJavaScript">Flymake for JavaScript</a>
seemed promising at first, but I decided that on-the-fly checking
    would be annoying.</p>

<p>Maybe something service-esque? There's <a
href="http://github.com/keturn/lintnode">Lintnode</a>, but <a
href="http://github.com/keturn/lintnode/issues#issue/6">its components
no longer work together</a>. How about running JSLint's web interface
locally, scripting a POST request and scraping the result?  That's
all wrong. JSLint needs a JavaScript runtime--the checking happens
client-side. There are no obvious browser automation possibilities
    here, and copy-paste is not desirable.</p>

<p>Maybe Spidermonkey? There's a <a
href="http://whereisandy.com/code/jslint/">workaround for its
inability to read files</a>, but I'm not keen on using a modified
    version of JSLint.</p>

<p>That leaves Rhino. It's convered by <a
href="http://www.jslint.com/rhino/index.html">one of the "official"
editions of JSLint</a>, but it's not necessarily a speed demon. I can
    live with that.</p>

<h2>The Setup</h2>
<p>If you use JSLint straight from the command line, the results won't be pretty.</p>

<pre>
rhino jslint.js functions.js

...

Lint at line 8 character 13: 'jQuery' is not defined.
</pre>

<p>References to third-party libraries will throw spurious errors because
JSLint hasn't been told about them. We need to define some global
variables to prevent that confusion. We also need a flexible way to
    specify JSLint's configuration options.</p>

<p>These things could go directly into the files you will lint, but
    that's extraneous clutter. The approach I've taken instead is:</p>

<ul>
<li>Define a standard set of options in the wrapper script.</li>
<li>Pass in any additional globals as an argument.</li>
<li>Prepend both to a copy of the file being linted.
<li>Stop after the first error</li>
</ul>

<p>I find that going through errors one at a time is easier than seeing everything at once.</p>

<h2>The Settings</h2>

<p>I started with JSLint's "Good Parts" options. I disabled "Strict white
space" (white) because of a difference in opinion with Closure Linter
I'll describe in a bit. As mentioned above, "Stop on first error"
    (passfail) is enabled. So is "Assume a browser" (browser).</p>

<h2>Adding Closure Linter</h2>

<p>Closure Linter is already suited to running from the command line, so
not much effort is involved here. I'm running it after JSLint, but the
    order could certainly be reversed.</p>

<p>JSLint and Closure Linter disagree about whitespace after "function"
and the subsequent left parentheses. JSLint wants it, Closure Linter
doesn't.  I decided to go with the latter (hence the "Strict white
space" config change mentioned above). I'm sure there are epic
    arguments both pro and con on both sides, but this is minutiae.</p>

<h2>How It Looks</h2>

<p>
    Example 1:
</p>

<pre>
$ validate-js functions.js

# JSLint
############################################################
No problems found.

# Closure Linter
############################################################
Line 5, E:0220: No docs found for member 'BB.video'
Line 25, E:0220: No docs found for member 'BB.rsvp'
Line 79, E:0110: Line too long (103 characters).
Line 85, E:0220: No docs found for member 'BB.slideshow'
</pre>

<p>
    Example 2:
</p>
<pre>
$ validate-js functions.js

# JSLint
############################################################
Line 1 character 1: Missing "use strict" statement.
var GK = function() {

Stopping (0% scanned).



# Closure Linter
############################################################
Line 7, E:0131: Single-quoted string preferred over double-quoted string.
Line 7, E:0131: Single-quoted string preferred over double-quoted string.
Line 8, E:0131: Single-quoted string preferred over double-quoted string.
Line 8, E:0131: Single-quoted string preferred over double-quoted string.
Line 9, E:0131: Single-quoted string preferred over double-quoted string.
Line 9, E:0131: Single-quoted string preferred over double-quoted string.
Line 9, E:0110: Line too long (82 characters).
Line 36, E:0131: Single-quoted string preferred over double-quoted string.
Line 36, E:0131: Single-quoted string preferred over double-quoted string.
Line 37, E:0131: Single-quoted string preferred over double-quoted string.
Line 38, E:0131: Single-quoted string preferred over double-quoted string.
Line 39, E:0131: Single-quoted string preferred over double-quoted string.
Line 42, E:0002: Missing space before "="
Line 42, E:0002: Missing space after "="

</pre>

      </div>
    </content>
  </entry>
    <entry>
    <title>Disabling i18n in CakePHP</title>
    <link href="http://ilovett.com/blog/programming/cakephp-disable-i18n" />
    <id>http://ilovett.com/blog/programming/cakephp-disable-i18n</id>
    <published>2010-01-02T00:00:00-08:00</published>
    <updated>2010-01-02T00:00:00-08:00</updated>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
      </div>
    </summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>I ran into an unusual problem in CakePHP recently. A site I'm
working on uses CakePHP's internationalization and localization
features unnecessarily. The codebase is full of references to
the <code>__()</code> function, but they're pointless because the site
isn't actually multi-lingual. So I have this capability that I don't
necessarily want right now, but getting rid of it isn't trivial and at
some point I may have a need for it.</p>

<p>Just about everything comes with a performance cost, and this
feature is no
exception. Using <a href="http://code.google.com/p/webgrind/"
rel="external">webgrind</a>, I could see the I18n class sucking up
time and resources even though it was doing a whole lot of nothing. I
wanted to correct that.</p>

<p>The solution was to create a stub class. If CakePHP sees that a
class named I18n has not been loaded, it will attempt to load it. I
could have prevented that from happening by editing the file, but that
would complicate future upgrades. Loading a stub class which has
the same interface but none of the bloat avoids that.</p>

<p>For lack of a better place, I put my stub class
in <code>app/vendors/i18n.php</code> and loaded it from
the <code>AppController</code> constructor. It contains a single
function, <code>translate()</code>, which returns its first argument
unmodified. Ordinarily that would be dumb, but in this case it's an
optimization.</p>

<p>Webgrind still shows the same number of invocations for
the I18n class, but they're taking much less time.</p>

      </div>
    </content>
  </entry>
    <entry>
    <title>Updating WordPress via Phing</title>
    <link href="http://ilovett.com/blog/programming/updating-wordpress-via-phing" />
    <id>http://ilovett.com/blog/programming/updating-wordpress-via-phing</id>
    <published>2009-12-26T00:00:00-08:00</published>
    <updated>2009-12-26T00:00:00-08:00</updated>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
      </div>
    </summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>Here's what I'm using to upgrade WordPress:</p>

<script src="http://gist.github.com/264140.js"></script>


<p>A WordPress installation can be divided into three parts. The first
part involves the core WordPress folders: <code>wp-admin</code> and
<code>wp-includes</code>. You normally don't change anything in these
folders, so upgrading them can just be a matter of deleting what
you've got and replacing it.</p>

<p>The second part involves customized folders. The most important of
these is <code>wp-content</code>, since it contains your site's theme
and plugins, but you might have other folders that are similarly
off-limits as far as upgrading is concerned. Whatever happens during
the upgrade process, we don't want to touch this stuff.</p>

<p>The final part involves the PHP files at the root level of the
site. These are mostly <code>wp-*</code> files that aren't changed,
except for <code>wp-config.php</code>, which is.</p>

<p>Conveniently, the URL for the latest version of WordPress is always
the same. I use <code>curl</code> to download it to <code>/tmp</code>
because it allows me to pipe the download straight into tar. After
deleting the core WordPress folders recursively, I rename
<code>wp-config.php</code> and any other custom PHP files (in this
example, <code>share-via-email.php</code>) with a <code>.bak</code>
extension so that they'll be preserved during the subsequent wipeout
of all PHP, HTML, and TXT files in the site root.</p>

<p>From this point, it's just a matter of copying in the new files and
restoring the <code>.bak</code> files to their original name. Since
the deletion process was restricted to known extensions, the only risk
is in forgetting to make an exception for customized files. Version
control can help with that, especially if you've accidentally
deleted or overwritten something important.</p>

<p>I haven't accounted for <code>.svn</code> folders within the core
folders. If you ran this target as-is, Subversion would complain about
the sudden absence of <code>.svn</code> folders within the
newly-copied <code>wp-admin</code> and <code>wp-includes</code>. This
is a great reason for exploring other options like <code>git</code>
that centralize all their stuff in a single directory.</p>



      </div>
    </content>
  </entry>
    <entry>
    <title>A Phing Tipping Point</title>
    <link href="http://ilovett.com/blog/programming/phing-tipping-point" />
    <id>http://ilovett.com/blog/programming/phing-tipping-point</id>
    <published>2009-12-24T00:00:00-08:00</published>
    <updated>2009-12-24T00:00:00-08:00</updated>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
      </div>
    </summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>One of the most benefical tools I picked up this year is <a
href="http://phing.info" rel="external">Phing</a>, a build system for
PHP based on Ant. I had known about it for a while, but never made
much headway because I didn't think I needed to do any building. I
already had rsync scripts--I figured I was set. It's just PHP.</p>

<p>WordPress deployment was my Phing tipping point. The first time you
deploy a WordPress site from development to staging and realize that
the paths inside your database dump are all wrong for is the first
clue you need Phing. The next clue happens when you need to pull from
production back to development, and face the same problem in
reverse.</p>

<p>I had previously been using Bash scripts for this sort of thing. I
had one for pushing out from dev, and another for pulling in. Bash
scripts are great. The problem is keeping track of them. A few months
later I needed to do some maintenance work, but the magical
combination of which scripts needed to be run in which order was no
longer apparent. Plus, I had done another WordPress project in the
meantime and set things up slightly differently. The changes hadn't
been propagated back to the first project. Things ended up
semi-automatic and half-effective.</p>

<p>Phing clicked for me once I figured out ExecTask was the gateway to
rsync. Rsync is crucial for getting files from point A to point B in a
sensible fashion, so I always gave up when I couldn't find any mention
of it in Phing's <a href="http://phing.info/docs/guide/stable/"
rel="external">manual</a>. Eventually I did find reference to a
third-party RsyncTask, but I stuck with ExecTask because it's built
into Phing and applicable to just about any shell command you might
want to run.</p>

<p>Once you can run shell commands, pretty anything is up for
grabs. Phing started to make a lot more sense because it was a
standard tool that could wrap the eccentricities of an individual
project with consistent behavior. I no longer needed extra bash
scripts in my source tree, just a single build.xml at the project
root.</p>

<p>Phing is great because it covers the basics but keeps PHP at close
hand if you need it. There's not much of a learning curve once you get
the hang of declaring and using variables (properties) within the
context of XML. If you keep things abstract enough, build targets are
pretty easy to reuse between projects. Once you figure out how to flip
your WordPress database between environments, the only things that
need changing from project to project are hostnames and filesystem
paths.</p>

<p>For example, in an earlier post on <a
href="http://ilovett.com/blog/programming/revving-file-names">revving
file names</a>, I described a way of using Phing to add hashes to
filenames for better cacheing. Dropping that into another project
doesn't cause much toolchain disruption because you have one thing
orchestrating everything from start to finish, instead of independent
scripts each doing their own thing.</p>

<p>That's the part that I was missing. I was managing the build and
deployment process every time I needed to make an upate, instead of
defining the process once and reaping the benefits of true
automation.</p>

      </div>
    </content>
  </entry>
    <entry>
    <title>Revving File Names with Hashes</title>
    <link href="http://ilovett.com/blog/programming/revving-file-names" />
    <id>http://ilovett.com/blog/programming/revving-file-names</id>
    <published>2009-11-01T14:00:00-08:00</published>
    <updated>2009-11-01T14:00:00-08:00</updated>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
      </div>
    </summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>In <a href="http://www.amazon.com/gp/product/0596529309?ie=UTF8&amp;tag=ilovettcom-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0596529309">High Performance Web Sites</a>, Steve Souders explains the
value of adding a version number to resource filenames so that they
are both cacheable and replaceable. In <a
href="http://www.stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring/">a
blog post</a>, he further explains why the querystring is not an optimal spot
for these numbers.</p>

<p>To create the version numbers, I've been using a variation on the technique described by Kevin Hale in <a href="http://particletree.com/notebook/automatically-version-your-css-and-javascript-files/">Automatically Version Your CSS and JavaScript Files</a>. His approach uses PHP to append the modification date of each file to its filename. An Apache rewrite rule allows those dates to be virtual, so that the client sees a path like <code>/css/structure.1194900443.css</code> but the server interprets it as <code>/css/structure.css</code>.</p>

<p>The first time I read Kevin's article, I wasn't keen on the PHP part. Even if the overhead of filemtime is miniscule, why have it there at all? My solution was to define a single PHP constant that could be populated by a build script during deployment, and then appended in all my CSS and JavaScript links. What could possibly go wrong?</p>

<p>If you have one version number for all your files, you end up treating them as a set. That's not good. If you upload some new CSS the new version number will be applied across the board, even to files that haven't changed. That cuts down on the longevity of your cached files, which is the opposite of what we're trying to accomplish. I was generating version numbers from Unix time at the moment of deployment, but the same thing could have happened if I used the most recent source control revision. Each file really needs to be revved separately.</p>

<p>SHA1 to the rescue. Version numbers based on the sha1 hash of each file ensure that a change to one file won't impact the version number of any other file. They're also less fragile than date-based version numbers, which can be changed in the course of copying files around unless you're careful. I also prefer the anonymity of the hashes because they don't reveal anything about a file's age.</p>

<p>I've started using <a href="http://phing.info">Phing</a>, so generating and inserting the hashes is easy. A <a href="http://phing.info/trac/changeset/590">FileHash task</a> exists, but I'm using an ad-hoc task for now:</p>

<script src="http://gist.github.com/223683.js"></script>

      </div>
    </content>
  </entry>
    <entry>
    <title>Set The Size and Position of Emacs Frames</title>
    <link href="http://ilovett.com/blog/emacs/emacs-frame-size-position" />
    <id>http://ilovett.com/blog/emacs/emacs-frame-size-position</id>
    <published>2009-08-08T00:00:00-07:00</published>
    <updated>2009-08-08T00:00:00-07:00</updated>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
      </div>
    </summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <h2>The Problem</h2>

When Emacs is launched, its initial window ("frame") is sized and
positioned according to application defaults instead of your own
preferences. Inevitably, you adjust it to your liking. But this fiddling
happens every time Emacs launches and it distracts you from
the task at hand. It would be more efficient if Emacs automatically sized the
frame according to your expectations.

<h2>The Solution</h2>
<script src="http://gist.github.com/164792.js"></script>
<noscript>
(defun arrange-frame (w h x y)
  "Set the width, height, and xy coordinates of the current frame, deleting all others"
  (let ((frame (selected-frame)))
    (delete-other-windows)
    (set-frame-position frame x y)
    (set-frame-size frame w h)))

(arrange-frame 160 50 2 22)
</noscript>

<p>I call this function immediately after defining it so that it takes
effect as soon as possible. There's a slight lag between the
time Emacs draws the initial frame at its default size and the time
the resize happens. It's not instantaneous, but it does happen fast.
That's good enough for me, because I just want to avoid unnecessary
window fiddling.</p>

<div align="center">
<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/8pMBgSt-UYU&amp;hl=en&amp;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/8pMBgSt-UYU&amp;hl=en&amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object>
</div>

<p>Taking things a step further, you could have different window
configurations for different circumstances: a large window that
occupies the full screen on a laptop and a less wide but taller window
for a desktop monitor, or one setup for when you're on a Mac and
another for when you're not.</p>

<h2>References</h2>
I started with the function from <a
href="http://blog.zenspider.com/2007/02/control-your-emacs-frames-prog.html"
rel="external">Control your emacs frames programatically</a> and
simplified it by removing the <code>nosplit</code> parameter, the
platform detection, and the hard-coded frame position
coordinates. Note that as of Emacs 23, the line <code>(when (equal
'mac (framep frame))</code> should be <code>(when (equal 'ns (framep frame))</code>



      </div>
    </content>
  </entry>
    <entry>
    <title>Automating HTML Image Tags in Emacs</title>
    <link href="http://ilovett.com/blog/emacs/automating-html-image-tags" />
    <id>http://ilovett.com/blog/emacs/automating-html-image-tags</id>
    <published>2009-08-01T00:00:00-07:00</published>
    <updated>2009-08-01T00:00:00-07:00</updated>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
      </div>
    </summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <h2>The Problem</h2> <p>To write an image tag, you need to know the
width and height of the image. Determining those numbers forces you to
leave Emacs and consult another application such as Photoshop or your
file manager. Locating the target file is a timesink, as is typing the
height, width, and alt attributes. Omitting the width and height can
have undesireable side effects and is not a best practice.</p>

<h2>The Solution</h2>

<script src="http://gist.github.com/159869.js"></script>
<noscript>
(defun relpath (file &amp;optional skipinsert)
     (interactive "FPath: ")
     (let* (
           (basePath
            (file-name-directory
             (expand-file-name
              (buffer-file-name (current-buffer)))))
           (targetPath
            (expand-file-name file))
           (basePathSegments
            (split-string basePath "/"))
           (targetPathSegments
            (split-string targetPath "/"))
           segment1
           segment2
           )

       (while basePathSegments
         (setq segment1 (pop basePathSegments))
         (setq segment2 (pop targetPathSegments))
         (unless (equal segment1 segment2)
           (progn
             (push segment2 targetPathSegments)
             (if (> (length basePathSegments) 0)
                 (push ".." targetPathSegments)))
           ))
       (setq targetPath (mapconcat 'identity targetPathSegments "/"))
       (if (eq nil skipinsert)
           (insert targetPath)
         targetPath)))


(defun img-tag (file alt)
  "Create an image tag from the specified file path"
  (interactive "FPath: \nsAlt text: ")
  (let ((image-size
         (let ((ximg (create-image file)))
           (image-size ximg t)))
        (relative-path (relpath file t)))
        (insert "<img src=\"" relative-path "\" "
                "alt=\"" alt "\" "
                "width=\"" (number-to-string (car image-size))
                "\" "
                "height=\"" (number-to-string (cdr image-size))
                "\" />")))
</noscript>

<p>The function first prompts you for the image file. The usual
autocompletion features are in effect, so the typing shouldn't be too
onerous. Other than alt text, everything else is automatic. Emacs is
figuring out the image width and height on its own, so there's no
reliance on third-party tools.</p>

<div align="center">
<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/U1psMts1GrI&amp;hl=en&amp;fs=1&amp;color1=0x3a3a3a&amp;color2=0x999999"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/U1psMts1GrI&amp;hl=en&amp;fs=1&amp;color1=0x3a3a3a&amp;color2=0x999999" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object>
</div>


<h2>References</h2>

<ol>
  <li><a href="http://xahlee.org/emacs/elisp_image_tag.html" rel="external nofollow">Elisp Lesson: Writing image-linkify Function</a></li>
</ol>

<h2>Revisions</h2>
<ul>
<li>August 8, 2009: Added missing code for <code>relpath</code> function,
which is used by <code>img-tag</code></li>
</ul>


      </div>
    </content>
  </entry>
    <entry>
    <title>Smartening Subversion with Perl</title>
    <link href="http://ilovett.com/blog/programming/smartening-subversion-with-perl" />
    <id>http://ilovett.com/blog/programming/smartening-subversion-with-perl</id>
    <published>2007-08-06T14:20:00-07:00</published>
    <updated>2007-08-06T14:20:00-07:00</updated>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
      </div>
    </summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>One thing I've never liked about using Subversion from the
command line is that it's tedious to add and remove
files. Although the <code>svn status</code> command tells you the
state of the files in your current checkout, its output is not
used when doing <code>svn add</code> or <code>svn
remove</code>. You end up retyping files paths, or copying and
pasting. That's not efficient.</p>

<p>A little interactivity would be much more helpful, and that's what
<a href="http://ilovett.com/public/downloads/svnask.txt">svnask.pl</a>
provides. It's a short and very simple Perl script that runs <code>svn
status</code>, looks for files with a state of "?" or "!", and prompts
for a yes-no on whether to add or remove each one from the
checkout. Since "yes" is the default, you can operate on a whole mess
of files with barely any effort.</p>

<p>Another efficiency problem I've come across with Subversion
involves keeping track of multiple checkouts from multiple
repositories. I have numerous projects in various states and bounce
around from one to another. Sometimes I forget to do a check in,
especially if I've only made a trivial change to one file. Weeks can
pass before I notice I have outstanding revisions. With <a
href="http://ilovett.com/public/downloads/svnstatus.txt">svnstatus.pl</a>
run daily via cron, this is no longer a problem. The script examines
one or more directories and runs <code>svn status</code>, producing an
accumulated status report of all known repositories. If there are
outstanding changes, cron will deliver the details in an email.</p>

      </div>
    </content>
  </entry>
    <entry>
    <title>Simplified Ad Blocking</title>
    <link href="http://ilovett.com/blog/projects/simplified-ad-blocking" />
    <id>http://ilovett.com/blog/projects/simplified-ad-blocking</id>
    <published>2007-07-28T10:54:00-07:00</published>
    <updated>2007-07-28T10:54:00-07:00</updated>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
      </div>
    </summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>About a year ago, I <a
href="http://ilovett.com/blog/projects/apache-proxy">replaced the
Squid proxy on my home network with Apache's mod_proxy</a>. I
wanted to continue blocking annoying ads on web pages without
keeping an additional service running. It seemed like an obvious
choice since Apache was already in the picture and ready to serve.</p>

<p>Things weren't all they were cracked up to be with mod_proxy. Setup
and configuration took a lot of fiddling and fusing, and there was a
bottleneck somewhere along the way that often made pages load more
slowly. I had all sorts of URL rewriting power at my disposal, but not
a solution that worked all the time, every time. So I scrapped the
whole thing and did without.</p>

<p>Web page ads are still annoying though, and I still want to block
them. Now I think I've got the right mix of simplicity and
reliability. It's essentially the solution described at <a
href="http://macmerc.com/sections.php?op=viewarticle&amp;artid=83">Superior
Ad Blocking on OS X</a>: add the hostnames of known ad servers to your
hosts file, then configure Apache's ErrorDocument to return a blank
page rather than the default message.</p>

<p>The one change I made was to point ErrorDocument to a  1x1
pixel GIF rather than an empty HTML page. This prevents broken image
icons from appearing, and doesn't appear to create any problems with
requests that expect to receive text.</p>

<p>I'm also adding the names of ad servers to my hosts file by hand,
rather than grabbing one of the lists available from <a
href="http://en.wikipedia.org/wiki/Hosts_file">Wikipedia's page on the
Hosts file</a>. This way I'm only blocking the ad servers I've
actually encountered, and not hundreds or thousands I'd never
otherwise come across (if they're still in fact active).</p>

      </div>
    </content>
  </entry>
    <entry>
    <title>A Simple Way of Monitoring a Dynamic IP Address</title>
    <link href="http://ilovett.com/blog/programming/simple-ip-address-monitor" />
    <id>http://ilovett.com/blog/programming/simple-ip-address-monitor</id>
    <published>2006-11-13T16:45:00-08:00</published>
    <updated>2006-11-13T16:45:00-08:00</updated>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
      </div>
    </summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>For the longest time, I've had a cron job running on my server at
home that used <code>ipcheck</code> (apt-cache show ipcheck) to update
<a href="http://www.dyndns.com/">DynDNS</a> with the current IP
address of my cable modem. Just in the off chance that said address
would change at an inconvenient time, leaving me without a path back
to home base.</p>

<p>That script and service did a fine job. Unfortunately, my cable
modem's IP address rarely changes. And even if it did, I probably
wouldn't be all that inconvenienced. Maybe a little. If the address
did change, I'd really only need to know the new one. I'm definitely
not in need of any fancy service monitoring. What's the simplest
solution then?</p>

<p>If you have a website and access to its access logs, the answer
might just be <code>curl</code>. By switching my cron job to
something like this:

<pre>
curl -I -A "hostname of my server" http://example.com &lt; /dev/null
</pre>

I'll end up with easily identifiable entries in my webserver
logs. Using HEAD requests (-I) keeps the request and response lean,
and I can grep based on that and/or the hostname of my server. As an
added bonus, I also end up with a basic availability heartbeat. If
there's nothing in the log files after a certain point in time,
something has more than likely gone wrong.</p>

<p>I should have gone this route all along. DynDNS is a better choice
when dealing with IP addresses directly would be otherwise
inconvenient. But I'm not exactly in that boat.</p>


      </div>
    </content>
  </entry>
  </feed>
