<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>1stvamp.org</title>
  <subtitle>Blue custard and snoogans since 1999</subtitle>
  <link href="https://1stvamp.org/feed.xml" rel="self"/>
  <link href="https://1stvamp.org/"/>
  <updated>2026-07-29T12:02:31.278Z</updated>
  <id>https://1stvamp.org/</id>
  <author>
    <name>Wes Mason</name>
    <uri>https://toot.cat/@1stvamp</uri>
  </author>
  
  <entry>
    <title>Mouse selection in Wezterm when Claude Code grabs the mouse</title>
    <link href="https://1stvamp.org/mouse-selection-in-wezterm-when-claude-code-grabs-the-mouse/"/>
    <id>https://1stvamp.org/mouse-selection-in-wezterm-when-claude-code-grabs-the-mouse/</id>
    <updated>2026-07-28T00:00:00.000Z</updated>
    <content type="html"><![CDATA[<p>I've been using Claude Code's fullscreen TUI, and the thing that kept annoying me
was losing mouse selection in <a href="https://wezterm.org">Wezterm</a> the moment it starts
up. Here's the config that gets it back, mostly for potential googlers (and
future me) hitting the same wall.</p>
<h3 id="the-problem" tabindex="-1">The problem</h3>
<p>Claude Code's fullscreen TUI turns on full mouse tracking (normal, button-event,
any-motion and SGR), so Wezterm forwards every drag straight to the app and never
builds a selection of its own. You can get selection back by holding shift, which
is the default of <code>bypass_mouse_reporting_modifiers</code>, but then shift is spent:
while it's the bypass Wezterm handles the event itself, and the docs are explicit
that the event is &quot;prevented from being passed to the application&quot; and gets
treated as though shift was never pressed, so clicks in the TUI have nowhere to
go.</p>
<p>The keyboard half of this runs on the <a href="https://sw.kovidgoyal.net/kitty/keyboard-protocol/">kitty keyboard
protocol</a>, which is what lets
the TUI tell shift+enter from a plain enter and read modifier combinations a
terminal wouldn't normally pass through. It's the same bargain as the mouse
tracking: the terminal hands its input over to the app, keys and mouse both, so
the defaults you lean on in an ordinary pane go quiet while you're in there.</p>
<h3 id="the-fix" tabindex="-1">The fix</h3>
<p>Drop this into your <code>~/.wezterm.lua</code>:</p>
<pre class="language-lua"><code class="language-lua"><span class="token comment">-- Keep SHIFT off the bypass so shift+click still reaches apps that grab the</span>
<span class="token comment">-- mouse. Claude Code masks the modifier bits off the button byte, so it arrives</span>
<span class="token comment">-- there as a plain click.</span>
config<span class="token punctuation">.</span>bypass_mouse_reporting_modifiers <span class="token operator">=</span> <span class="token string">"CTRL|ALT"</span>

config<span class="token punctuation">.</span>mouse_bindings <span class="token operator">=</span> <span class="token punctuation">{</span>
  <span class="token comment">-- A mouse binding is only considered when the pane's mouse reporting state</span>
  <span class="token comment">-- matches, so ordinary bindings go dead inside an app that grabs the mouse.</span>
  <span class="token comment">-- These claim the left button back for selection while it does.</span>
  <span class="token punctuation">{</span>
    event <span class="token operator">=</span> <span class="token punctuation">{</span> Down <span class="token operator">=</span> <span class="token punctuation">{</span> streak <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">,</span> button <span class="token operator">=</span> <span class="token string">"Left"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
    mods <span class="token operator">=</span> <span class="token string">"NONE"</span><span class="token punctuation">,</span>
    mouse_reporting <span class="token operator">=</span> <span class="token keyword">true</span><span class="token punctuation">,</span>
    action <span class="token operator">=</span> wezterm<span class="token punctuation">.</span>action<span class="token punctuation">.</span><span class="token function">SelectTextAtMouseCursor</span><span class="token punctuation">(</span><span class="token string">"Cell"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span>
    event <span class="token operator">=</span> <span class="token punctuation">{</span> Drag <span class="token operator">=</span> <span class="token punctuation">{</span> streak <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">,</span> button <span class="token operator">=</span> <span class="token string">"Left"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
    mods <span class="token operator">=</span> <span class="token string">"NONE"</span><span class="token punctuation">,</span>
    mouse_reporting <span class="token operator">=</span> <span class="token keyword">true</span><span class="token punctuation">,</span>
    action <span class="token operator">=</span> wezterm<span class="token punctuation">.</span>action<span class="token punctuation">.</span><span class="token function">ExtendSelectionToMouseCursor</span><span class="token punctuation">(</span><span class="token string">"Cell"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span>
    event <span class="token operator">=</span> <span class="token punctuation">{</span> Down <span class="token operator">=</span> <span class="token punctuation">{</span> streak <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">,</span> button <span class="token operator">=</span> <span class="token string">"Left"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
    mods <span class="token operator">=</span> <span class="token string">"NONE"</span><span class="token punctuation">,</span>
    mouse_reporting <span class="token operator">=</span> <span class="token keyword">true</span><span class="token punctuation">,</span>
    action <span class="token operator">=</span> wezterm<span class="token punctuation">.</span>action<span class="token punctuation">.</span><span class="token function">SelectTextAtMouseCursor</span><span class="token punctuation">(</span><span class="token string">"Word"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span>
    event <span class="token operator">=</span> <span class="token punctuation">{</span> Drag <span class="token operator">=</span> <span class="token punctuation">{</span> streak <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">,</span> button <span class="token operator">=</span> <span class="token string">"Left"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
    mods <span class="token operator">=</span> <span class="token string">"NONE"</span><span class="token punctuation">,</span>
    mouse_reporting <span class="token operator">=</span> <span class="token keyword">true</span><span class="token punctuation">,</span>
    action <span class="token operator">=</span> wezterm<span class="token punctuation">.</span>action<span class="token punctuation">.</span><span class="token function">ExtendSelectionToMouseCursor</span><span class="token punctuation">(</span><span class="token string">"Word"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span>
    event <span class="token operator">=</span> <span class="token punctuation">{</span> Down <span class="token operator">=</span> <span class="token punctuation">{</span> streak <span class="token operator">=</span> <span class="token number">3</span><span class="token punctuation">,</span> button <span class="token operator">=</span> <span class="token string">"Left"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
    mods <span class="token operator">=</span> <span class="token string">"NONE"</span><span class="token punctuation">,</span>
    mouse_reporting <span class="token operator">=</span> <span class="token keyword">true</span><span class="token punctuation">,</span>
    action <span class="token operator">=</span> wezterm<span class="token punctuation">.</span>action<span class="token punctuation">.</span><span class="token function">SelectTextAtMouseCursor</span><span class="token punctuation">(</span><span class="token string">"Line"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span>
    event <span class="token operator">=</span> <span class="token punctuation">{</span> Drag <span class="token operator">=</span> <span class="token punctuation">{</span> streak <span class="token operator">=</span> <span class="token number">3</span><span class="token punctuation">,</span> button <span class="token operator">=</span> <span class="token string">"Left"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
    mods <span class="token operator">=</span> <span class="token string">"NONE"</span><span class="token punctuation">,</span>
    mouse_reporting <span class="token operator">=</span> <span class="token keyword">true</span><span class="token punctuation">,</span>
    action <span class="token operator">=</span> wezterm<span class="token punctuation">.</span>action<span class="token punctuation">.</span><span class="token function">ExtendSelectionToMouseCursor</span><span class="token punctuation">(</span><span class="token string">"Line"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span>
    event <span class="token operator">=</span> <span class="token punctuation">{</span> Up <span class="token operator">=</span> <span class="token punctuation">{</span> streak <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">,</span> button <span class="token operator">=</span> <span class="token string">"Left"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
    mods <span class="token operator">=</span> <span class="token string">"NONE"</span><span class="token punctuation">,</span>
    mouse_reporting <span class="token operator">=</span> <span class="token keyword">true</span><span class="token punctuation">,</span>
    action <span class="token operator">=</span> wezterm<span class="token punctuation">.</span>action<span class="token punctuation">.</span><span class="token function">CompleteSelection</span><span class="token punctuation">(</span><span class="token string">"ClipboardAndPrimarySelection"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span>
    event <span class="token operator">=</span> <span class="token punctuation">{</span> Up <span class="token operator">=</span> <span class="token punctuation">{</span> streak <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">,</span> button <span class="token operator">=</span> <span class="token string">"Left"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
    mods <span class="token operator">=</span> <span class="token string">"NONE"</span><span class="token punctuation">,</span>
    mouse_reporting <span class="token operator">=</span> <span class="token keyword">true</span><span class="token punctuation">,</span>
    action <span class="token operator">=</span> wezterm<span class="token punctuation">.</span>action<span class="token punctuation">.</span><span class="token function">CompleteSelection</span><span class="token punctuation">(</span><span class="token string">"ClipboardAndPrimarySelection"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span>
    event <span class="token operator">=</span> <span class="token punctuation">{</span> Up <span class="token operator">=</span> <span class="token punctuation">{</span> streak <span class="token operator">=</span> <span class="token number">3</span><span class="token punctuation">,</span> button <span class="token operator">=</span> <span class="token string">"Left"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
    mods <span class="token operator">=</span> <span class="token string">"NONE"</span><span class="token punctuation">,</span>
    mouse_reporting <span class="token operator">=</span> <span class="token keyword">true</span><span class="token punctuation">,</span>
    action <span class="token operator">=</span> wezterm<span class="token punctuation">.</span>action<span class="token punctuation">.</span><span class="token function">CompleteSelection</span><span class="token punctuation">(</span><span class="token string">"ClipboardAndPrimarySelection"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>

  <span class="token comment">-- CTRL+click to open a link needs claiming back as well, otherwise it reaches</span>
  <span class="token comment">-- the app as an ordinary click. Down and Drag go to Nop so the press, and any</span>
  <span class="token comment">-- wobble before the release, don't get through either.</span>
  <span class="token punctuation">{</span>
    event <span class="token operator">=</span> <span class="token punctuation">{</span> Down <span class="token operator">=</span> <span class="token punctuation">{</span> streak <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">,</span> button <span class="token operator">=</span> <span class="token string">"Left"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
    mods <span class="token operator">=</span> <span class="token string">"CTRL"</span><span class="token punctuation">,</span>
    mouse_reporting <span class="token operator">=</span> <span class="token keyword">true</span><span class="token punctuation">,</span>
    action <span class="token operator">=</span> wezterm<span class="token punctuation">.</span>action<span class="token punctuation">.</span>Nop<span class="token punctuation">,</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span>
    event <span class="token operator">=</span> <span class="token punctuation">{</span> Drag <span class="token operator">=</span> <span class="token punctuation">{</span> streak <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">,</span> button <span class="token operator">=</span> <span class="token string">"Left"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
    mods <span class="token operator">=</span> <span class="token string">"CTRL"</span><span class="token punctuation">,</span>
    mouse_reporting <span class="token operator">=</span> <span class="token keyword">true</span><span class="token punctuation">,</span>
    action <span class="token operator">=</span> wezterm<span class="token punctuation">.</span>action<span class="token punctuation">.</span>Nop<span class="token punctuation">,</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span>
    event <span class="token operator">=</span> <span class="token punctuation">{</span> Up <span class="token operator">=</span> <span class="token punctuation">{</span> streak <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">,</span> button <span class="token operator">=</span> <span class="token string">"Left"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
    mods <span class="token operator">=</span> <span class="token string">"CTRL"</span><span class="token punctuation">,</span>
    mouse_reporting <span class="token operator">=</span> <span class="token keyword">true</span><span class="token punctuation">,</span>
    action <span class="token operator">=</span> wezterm<span class="token punctuation">.</span>action<span class="token punctuation">.</span>OpenLinkAtMouseCursor<span class="token punctuation">,</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span></code></pre>
<p>If you already have a <code>mouse_bindings</code> table, add these entries to it rather than
replacing it. Setting <code>mouse_bindings</code> at all does not remove Wezterm's defaults,
your entries are merged over the top of them, so the bindings for panes that
aren't grabbing the mouse carry on working.</p>
<h3 id="what-you-get-inside-the-tui" tabindex="-1">What you get inside the TUI</h3>
<ul>
<li><strong>drag</strong>: selects, and <code>CompleteSelection</code> puts it on the clipboard on release. ctrl+shift+c copies too, that's a Wezterm default.</li>
<li><strong>double or triple click</strong>: word or line, dragging after either extends by that unit.</li>
<li><strong>ctrl+click</strong>: opens a link, same as it does in an ordinary pane.</li>
<li><strong>shift+click</strong>: goes through to Claude Code, e.g. expanding a &quot;Running shell commands&quot; block.</li>
<li><strong>ctrl+alt+click</strong>: the new bypass, if you want Wezterm's non-reporting behaviour back.</li>
</ul>
<p>Every modifier combination works this way, so anything you rely on in a normal
pane needs an entry with <code>mouse_reporting = true</code> or it falls through to the app.
Bind the <code>Down</code> and <code>Drag</code> events alongside the <code>Up</code> one when you do, since a
matched binding is what stops Wezterm forwarding the event, and a click that
drifts a pixel between press and release sends motion events too.</p>
<p>The streak numbers are why there are quite so many entries in there. A double
click, per the docs, is a <code>down-up-down</code> sequence, so the gesture runs <code>Down</code>
streak 1, <code>Up</code> streak 1, then <code>Down</code> streak 2 (that last one is what selects the
word), and after it a <code>Drag</code> streak 2 for every movement. Leave that <code>Drag</code> entry
out and the word selects fine but dragging to extend it does nothing at all,
which is exactly the bug I had. Same again at streak 3 for lines. The <code>Up</code> streak
2 and 3 entries are in there so the release that ends those gestures doesn't get
forwarded to the app on its own, with no press in front of it.</p>
<h3 id="why-shift%2Bclick-survives-the-trip" tabindex="-1">Why shift+click survives the trip</h3>
<p>Wezterm sends the real modifier state in the SGR report, and Claude Code masks
the modifier bits off the button byte (<code>button &amp; 3</code>) before it decides which
button you pressed. A shift+left press is button 4, and <code>4 &amp; 3</code> is 0, so it lands
as a plain left click. This is an implementation detail of the TUI (read out of
2.1.220), so it could change.</p>
<p>The cost is that a plain left click no longer reaches the TUI, it sets Wezterm's
selection anchor instead. Everything else, wheel included, still goes to the app.</p>
<p>Middle click and the ALT block-select are both still unclaimed here, so inside the
TUI they fall through. Middle click reads as a paste over there, since the same
handler treats buttons 1 and 2 specially. The rule above applies if you'd rather
have either of them back: give each one its own entry.</p>
<h3 id="checking-it-works" tabindex="-1">Checking it works</h3>
<p><code>wezterm show-keys</code> prints the resolved tables. The one you care about is
<code>Mouse: mouse_reporting + alt_screen</code>, which is the state a fullscreen TUI puts
the pane in:</p>
<pre><code>Mouse: mouse_reporting + alt_screen
-----------------------------------

	       Down { streak: 1, button: Left }   -&gt;   SelectTextAtMouseCursor(Cell)
	       Down { streak: 2, button: Left }   -&gt;   SelectTextAtMouseCursor(Word)
	       Down { streak: 3, button: Left }   -&gt;   SelectTextAtMouseCursor(Line)
	       Drag { streak: 1, button: Left }   -&gt;   ExtendSelectionToMouseCursor(Cell)
	       ...
</code></pre>
<p>The <code>mouse_reporting</code> field on mouse bindings needs Wezterm
20220807-113146-c2fee766 or newer. I tested all of this on
20240203-110809-5046fc22 (the flatpak), against Claude Code 2.1.220.</p>
<p>One thing to watch on Linux: your window manager may grab ctrl+alt+click before
Wezterm sees it, so pick a different bypass combo if you need it and it does
nothing.</p>
<h3 id="the-blunter-option" tabindex="-1">The blunter option</h3>
<p><code>CLAUDE_CODE_DISABLE_MOUSE=1</code> makes Claude Code emit no mouse tracking sequences
at all, so the terminal keeps the mouse and none of the above is needed. You lose
wheel scrolling in the TUI, since Wezterm maps the wheel to arrow keys in alt
screen. There's also <code>CLAUDE_CODE_DISABLE_MOUSE_CLICKS=1</code>, which drops it to
normal plus SGR tracking, but reporting is still on so the terminal still won't
select for you.</p>
]]></content>
  </entry>
  
  <entry>
    <title>Snappy and &amp;quot;ImportError: No module named &#39;click.repository&#39;&amp;quot;</title>
    <link href="https://1stvamp.org/snappy-and-importerror-no-module-named-clickrepository/"/>
    <id>https://1stvamp.org/snappy-and-importerror-no-module-named-clickrepository/</id>
    <updated>2014-12-15T00:00:00.000Z</updated>
    <content type="html"><![CDATA[<p>If you're playing around with <a href="http://developer.ubuntu.com/snappy/">Snappy</a> and <a href="http://www.ubuntu.com/cloud/tools/snappy">Ubuntu Core</a>, the new transaction based packaging platform in town, and receive the following error:</p>
<pre><code>ImportError: No module named 'click.repository'
</code></pre>
<p>It's most likely because you also have the ubuntu-sdk PPA installed, and a new version of <em>python3-click</em> has been pushed up that doesn't include the <em>repository</em> submodule that Snappy uses. I found unravelling the two project's dependencies to be non-trivial at the moment, so here's an alternative quick fix:</p>
<ol>
<li>
<p>Run:</p>
<p>sudo apt purge -y python3-click</p>
</li>
<li>
<p>Create a new file at <code>/etc/apt/preferences.d/snappy-ppa-1500</code>, with <a href="https://gist.github.com/1stvamp/66a9e375846fcb7bf308">these contents</a> (telling apt that we prefer duplicate packages from the snappy-dev PPA).</p>
</li>
<li>
<p>Run:</p>
<p>sudo apt update</p>
</li>
<li>
<p>Run:</p>
<p>sudo apt install -y --force-yes snappy-tools</p>
</li>
</ol>
<p>For the time being this should select the packages we need from the snappy-dev PPA, and giving us the right <em>python3-click</em>, complete with repository submodule.</p>
<p>The other alternative is to confine your Snappy experiments to an LXC or VM; or completely purge both PPAs and all the packages from them and reinstall just Snappy if you don't care about Ubuntu Touch or regular click package dev right now.<br>
I'm sure the conflict will be fixed soon though. :-)</p>
]]></content>
  </entry>
  
  <entry>
    <title>Verifying post-deploy connections with conn-check</title>
    <link href="https://1stvamp.org/verifying-post-deploy-connections-with-conn-check/"/>
    <id>https://1stvamp.org/verifying-post-deploy-connections-with-conn-check/</id>
    <updated>2014-11-19T00:00:00.000Z</updated>
    <content type="html"><![CDATA[<h3 id="the-problem" tabindex="-1">The Problem</h3>
<p>Deployments of a service have a number of different network dependencies that require verification:</p>
<ul>
<li>Connections between services (e.g. app &lt;-&gt; postgresql, are ports unblocked at the firewall(s)? If talking to a data centre instance do we have a route?)</li>
<li>External services (e.g. webservices such as S3)</li>
<li>Verification that the services on the other end are real (you're actually talking to MongoDB or rabbitmq via AMQP, not just another TCP service running on those ports)</li>
<li>Verification of authentication</li>
</ul>
<p>Although many of these can be solved with smoke tests, it's not always immediately obvious that there is a problem, or what the problem is.</p>
<h3 id="our-solution" tabindex="-1">Our solution</h3>
<p><a href="https://launchpad.net/conn-check">conn-check</a> is a tool that started life inside <em>Ubuntu One</em> to verify connections between services and to S3 etc. post-deploy.<br>
During a mini-sprint in Uruguay a few months ago we separated conn-check into it's own own package and open sourced it.<br>
Since then we've been improving it and using it to verify deploys on our services (such as <em>login.ubuntu.com</em>).</p>
<p>conn-check takes a simple <a href="http://bazaar.launchpad.net/~ubuntuone-hackers/conn-check/trunk/view/head:/demo.yaml">YAML config</a> defining a list of checks to perform (udp, tcp, tls, http, amqp, postgres, mongodb, redis, memcache), and performs those checks asynchronously using Twisted's thread pool, and outputs the results in a <a href="https://nagios-plugins.org/doc/guidelines.html#AEN33">Nagios check standard output</a>, so conn-check can be run regulary as a Nagios check to continually verify network status between services (and alert on change, e.g. out of band firewall changes).</p>
<h3 id="automatically-generating-configs" tabindex="-1">Automatically generating configs</h3>
<p>We have also released a separate package called <a href="https://pypi.python.org/pypi/conn-check-configs">conn-check-configs</a> which provides tools for automatically generating conn-check YAML configs from a source such as a Django settings module or Juju environment status (we're currently using the Django settings export, with Juju env export being tested in a branch).</p>
<h3 id="getting-conn-check" tabindex="-1">Getting conn-check</h3>
<p>You can get conn-check by:</p>
<ul>
<li>Installing from PyPI:</li>
</ul>
<pre><code>pip install conn-check
</code></pre>
<p>(You can <em>sudo</em> this to get it system installed, but personally I'd put it in a <a href="https://virtualenv.pypa.io/">virtualenv</a> or use <a href="https://github.com/mitsuhiko/pipsi">pipsi</a>.)</p>
<ul>
<li>Installing with apt-get from <a href="https://launchpad.net/~wesmason/+archive/ubuntu/conn-check">my PPA</a>:</li>
</ul>
<pre><code>sudo add-apt-repository ppa:wesmason/conn-check
sudo apt-get update
sudo apt-get install conn-check
</code></pre>
<ul>
<li>If you use <a href="https://juju.ubuntu.com/">Juju</a> to manage your infrastructure/deployments, then you can use <a href="https://jujucharms.com/u/ubuntuone-hackers/conn-check/trusty">our charm</a> to deploy conn-check for your service (and even add Nagios checks automatically via the nrpe relation).</li>
</ul>
]]></content>
  </entry>
  
  <entry>
    <title>Canonical</title>
    <link href="https://1stvamp.org/canonical/"/>
    <id>https://1stvamp.org/canonical/</id>
    <updated>2014-11-08T00:00:00.000Z</updated>
    <content type="html"><![CDATA[<p>Just thought I'd mention that I switched jobs way back in April and I now work for <a href="http://www.canonical.com/">Canonical</a> (yes, that one, the producers of Ubuntu Linux), in <em>Online Services</em>, and couldn't be happier.</p>
<p>Expect to hear soon about some of the things I've been working on.</p>
]]></content>
  </entry>
  
  <entry>
    <title>Speaking schedule</title>
    <link href="https://1stvamp.org/speaking-schedule/"/>
    <id>https://1stvamp.org/speaking-schedule/</id>
    <updated>2013-08-21T00:00:00.000Z</updated>
    <content type="html"><![CDATA[<ul>
<li>27^th^ August - <a href="https://groups.google.com/forum/#!forum/python-sheffield">Python Sheffield</a></li>
<li>8^th^ October - <a href="http://dibiconference.com/">DIBI 2013</a></li>
<li>13/14^th^ October - <a href="http://python.ie/pycon/2013/">PyCon Ireland 2013</a></li>
</ul>
]]></content>
  </entry>
  
  <entry>
    <title>Sockii</title>
    <link href="https://1stvamp.org/sockii/"/>
    <id>https://1stvamp.org/sockii/</id>
    <updated>2013-05-01T00:00:00.000Z</updated>
    <content type="html"><![CDATA[<p>Just a note to say that yesterday I released <a href="https://github.com/serverdensity/sockii">Sockii</a>, a smart HTTP and WebSocket aggregator, and blogged about it over on the <a href="http://blog.serverdensity.com/introducing-sockii-http-and-websocket-aggregator/">Server Density blog</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title>May speaking</title>
    <link href="https://1stvamp.org/may-speaking/"/>
    <id>https://1stvamp.org/may-speaking/</id>
    <updated>2013-05-01T00:00:00.000Z</updated>
    <content type="html"><![CDATA[<p>I'll be giving talks at the following events this month:</p>
<ul>
<li><a href="http://wypy.org.uk/">West Yorkshire Python User Group Meeting - Thurs 9th</a></li>
<li><a href="https://atmosphere-conference.com/">Atmosphere 2013 - Mon 13th / Tues 14th</a></li>
<li><a href="http://devopsdays.org/events/2013-berlin/">DevOpsDays Berlin - Tues 28th</a></li>
</ul>
]]></content>
  </entry>
  
  <entry>
    <title>PHP Weekly</title>
    <link href="https://1stvamp.org/php-weekly/"/>
    <id>https://1stvamp.org/php-weekly/</id>
    <updated>2012-11-28T00:00:00.000Z</updated>
    <content type="html"><![CDATA[<p>From the 6^th^ of December I'm going to be trying a little experiment. I'm going to run a weekly newsletter filled with links to articles, videos, project and dev news from the world of <a href="http://php.net/">PHP</a> called <a href="http://www.phpweekly.info/">PHP Weekly</a> (yes much in the style of <a href="https://cooperpress.com/">Peter Cooper</a> and <a href="http://devopsweekly.com/">Gareth Rushgrove</a>).</p>
<p>If you fancy following along head on <a href="http://phpweekly.info/">over</a> and subscribe, or follow me on <a href="https://twitter.com/1stvamp">twitter</a> where I will also post links to freshly archived mailshots.</p>
]]></content>
  </entry>
  
  <entry>
    <title>hippybot - Hipchat bot written in Python</title>
    <link href="https://1stvamp.org/hippybot-hipchat-bot-written-in-python/"/>
    <id>https://1stvamp.org/hippybot-hipchat-bot-written-in-python/</id>
    <updated>2011-09-13T00:00:00.000Z</updated>
    <content type="html"><![CDATA[<p>I recently had a reason to try out <a href="http://hipchat.com/">Hipchat</a>, being a bit of a &quot;chat enthusiast&quot; (I was an IRC network admin for about 7 years and have a been developer on a few web chat and IM systems) I found Hipchat to be one of the nicest (that I've used) of the recent stream of &quot;IRC for the web&quot; products out there (for example <a href="http://campfirenow.com/">37 Signal's Campfire</a>).</p>
<p>Normally this would have been the end of my quick perusal, until the next time I had reason to the use the service, but I noticed they had not only an <a href="https://www.hipchat.com/docs/api">API</a>, but also <a href="https://www.hipchat.com/help/category/xmpp">Jabber/XMPP exposure</a> for creating bots. Now my interest was <em>piqued</em>.**Looking at the existing third-party bots out there I found you had your choice of languages…as long as that choice was Ruby or Javascript. ;-)</p>
<p>Now I'm not averse to developing in either, but they're not my preferred languages by far (okay Javascript has a soft spot in my heart but I still haven't made the jump to server-side JS dev).</p>
<p>So with that I present <a href="https://github.com/1stvamp/hippybot">hippybot</a><br>
(Hip**chat <strong>Py</strong>thon <strong>Bot</strong>, geddit?)<br>
Not to be confused with <a href="https://github.com/rcrowe/Hippy">Hippy</a>, a PHP library for the Hipchat API.</p>
<p>I wrote hippybot using the excellent <a href="http://thp.io/2007/python-jabberbot/">python-jabberbot</a>, a library that utilises the equally brilliant <a href="http://xmpppy.sourceforge.net/">xmpppy</a> to allow the creation of bots in an easy to understand and pythonic way (e.g. inherit from base class, set some connection strings, override event methods if need be, use decorators to extend commands the bot responds to).</p>
<p>How is this different from a regular Jabber bot? I've written some Hipchat-specific customisations into the bot:</p>
<ul>
<li>The connection config assumes Hipchat's XMPP server, and various details such as the username and channel names have Hipchat specific [pre/suf]fixes added to them automatically.</li>
<li>The bot &quot;understands&quot; at-sign mentions (e.g. those popularised by Twitter and supported by Hipchat for directing messages to specific people within rooms, as well as triggering notifications), and commands added by plugins can leverage this.</li>
</ul>
<p>I've added a simple plugin API to the bot, which consists of either creating a function in a module with a decorator, or a class in a module with as many decorated methods (each a different command to trigger the bot) as you like, and the ability to create aliases for commands and define whether a command is triggered by an at-sign mention or not (e.g. <em>@hippybot do something!</em>).</p>
<p>In the next release I plan to add a simple wrapper to Hipchat's API (already in master), better at-sign mention handling, and some more core plugins.</p>
<p>Feel free to check it out and for an example of the sorts of things you can do with a bot like this just check out some of the things <a href="http://zachholman.com/posts/why-github-hacks-on-side-projects/">Github's hubot does</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title>Webcomic hosting survey</title>
    <link href="https://1stvamp.org/webcomic-hosting-survey/"/>
    <id>https://1stvamp.org/webcomic-hosting-survey/</id>
    <updated>2011-06-17T00:00:00.000Z</updated>
    <content type="html"><![CDATA[<p>I very rarely ask people to spread links about or push my wares, but in this instance I would greatly appreciate sharing <a href="http://goo.gl/S9n7P">this link</a> to anyone you might know who creates/publishes comics of any form (web comics, digital comic books etc.) online.</p>
]]></content>
  </entry>
  
  <entry>
    <title>Morgan Robert Mason</title>
    <link href="https://1stvamp.org/morgan-robert-mason/"/>
    <id>https://1stvamp.org/morgan-robert-mason/</id>
    <updated>2011-04-29T00:00:00.000Z</updated>
    <content type="html"><![CDATA[<p>Morgan Robert Mason, born April 26th 12.07am, 10 lbs exactly, mother and baby well (but exhausted).</p>
<p><img src="/assets/images/morgan1.jpg" alt="Morgan Robert Mason"></p>
]]></content>
  </entry>
  
  <entry>
    <title>django-form-scaffold 1.1.0 released</title>
    <link href="https://1stvamp.org/django-form-scaffold-110-released/"/>
    <id>https://1stvamp.org/django-form-scaffold-110-released/</id>
    <updated>2011-02-22T00:00:00.000Z</updated>
    <content type="html"><![CDATA[<p>Well, actually <a href="http://pypi.python.org/pypi/django-form-scaffold/1.1.0">v1.1.0</a> of <a href="http://github.com/1stvamp/django-form-scaffold">django-form-scaffold</a> was released last week, but I've been a bit too busy to blog about it since then.</p>
<p>A quick recap for the uninitiated: <em>dfs</em> is a set of utilities for generating the mark up and Django template code to display all the fields in a Django Form, e.g. the task of displaying each input element, label text and error message is still given to Django, but we display the markup around those elements in the template itself.</p>
<p>The library offers a few variants on the <code>Form.as_*</code> methods, which will output mark up similar to those methods.</p>
<p>New in <a href="http://pypi.python.org/pypi/django-form-scaffold/1.1.0">v1.1.0</a>:</p>
<ul>
<li>A README typo fix, spotted by Chris Matthews.</li>
<li>A management command (<code>formscaffold</code>), based on a script submitted by Chris Matthews.</li>
<li>Some fixes to the way form errors are generated for ModelForms.</li>
</ul>
<p>To use the new management command just add 'dfs' to your <code>settings.INSTALLED_APPS</code> tuple and the command will become available.<br>
It's used like so:</p>
<pre><code>./manage formscaffold my_app.forms MyCustomForm as_p
# or if using buildout
bin/django formscaffold my_app.forms MyCustomForm as_p
</code></pre>
<p>The above would generate the form using <p/> tags, for the class <code>MyCustomForm</code> located in the module/package <code>my_app.forms</code>.</p>
<p>Please note, if your form requires any setup (e.g. values passing to the constructor or the instance) the above won't work, as it just creates a base instance from the class and passes that to the helper, you can still use dfs to do this from a Django app shell though (using <code>./manage.py shell</code>).</p>
]]></content>
  </entry>
  
  <entry>
    <title>Blogmire</title>
    <link href="https://1stvamp.org/blogmire/"/>
    <id>https://1stvamp.org/blogmire/</id>
    <updated>2010-12-31T00:00:00.000Z</updated>
    <content type="html"><![CDATA[<p>I've been doing it again, despite having revamped this site with a view to keeping it more up to date, I've entered into a <em>blogmire</em>.<br>
Other than the fact I'm a lazy lazy lazy lazy lazy man, one of the reasons I don't blog much here but do put lots of things on <a href="http://www.twitter.com/1stvamp">Twitter</a> (and code on <a href="https://www.github.com/1stvamp">Github</a>), is barrier to entry; both of these have an extremely low barrier to getting my data out there (Twitter clients, <code>vim</code> &amp; <code>git</code> on the command line, etc.)</p>
<p>I'm wondering if switching to a static file generator system like <a href="http://www.blogofile.com/">Blogofile</a> might help me be more productive with the place, reducing my workflow on 1stvamp.org down to a <code>vim</code> → <code>git</code> problem.</p>
]]></content>
  </entry>
  
  <entry>
    <title>Blog scriptkiddied</title>
    <link href="https://1stvamp.org/blog-scriptkiddied/"/>
    <id>https://1stvamp.org/blog-scriptkiddied/</id>
    <updated>2010-12-30T00:00:00.000Z</updated>
    <content type="html"><![CDATA[<p>Seems I forgot to update my Habari instance and the site got buggered by some spam bot over the holidays, apologies while I root around for the last backup.</p>
]]></content>
  </entry>
  
  <entry>
    <title>Meanwhile on the Isotoma blog</title>
    <link href="https://1stvamp.org/meanwhile-on-the-isotoma-blog/"/>
    <id>https://1stvamp.org/meanwhile-on-the-isotoma-blog/</id>
    <updated>2010-07-28T00:00:00.000Z</updated>
    <content type="html"><![CDATA[<p>Just a note to say while I’ve been a little lapse on here, I have been posting on various topics (mostly Python related) to the Isotoma blog:</p>
<ul>
<li><a href="http://blog.isotoma.com/2009/12/getting-the-name-of-the-current-view-in-a-django-template/">Getting the name of the current view in a Django template</a></li>
<li><a href="http://blog.isotoma.com/2010/06/querying-webtrends-analytics-via-odbc-with-sqlalchemy/">Querying Webtrends analytics via ODBC with SQLAlchemy</a></li>
<li><a href="http://blog.isotoma.com/2010/07/writing-interactive-command-line-db-query-tools-with-pydbcli/">Writing interactive command line DB query tools with pyDBCLI</a></li>
<li><a href="http://blog.isotoma.com/2010/07/querying-webtrends-odbc-from-the-command-line-with-webtrendsqt/">Querying Webtrends ODBC from the command line with WebtrendsQT</a></li>
</ul>
]]></content>
  </entry>
  
  <entry>
    <title>Threading tweets on Twitter with Thweddy</title>
    <link href="https://1stvamp.org/threading-tweets-on-twitter-with-thweddy/"/>
    <id>https://1stvamp.org/threading-tweets-on-twitter-with-thweddy/</id>
    <updated>2010-03-01T00:00:00.000Z</updated>
    <content type="html"><![CDATA[<p>I built a new app, called <a href="http://thweddy.1stvamp.net/">Thweddy</a>. From the FAQ:</p>
<blockquote>
<p>It makes threads of tweets, so you can send a full conversation to someone else (or include it in another tweet) to people rather than copying and pasting half a dozen different URLs for each one.</p>
</blockquote>
]]></content>
  </entry>
  
  <entry>
    <title>Speechify</title>
    <link href="https://1stvamp.org/speechify/"/>
    <id>https://1stvamp.org/speechify/</id>
    <updated>2010-01-10T00:00:00.000Z</updated>
    <content type="html"><![CDATA[<p>For those that don’t know, this Saturday I’ll be finally getting married to my long time (and long suffering) fiancée <a href="http://puffinqueen.com/">Andrea</a>.<br>
As joyous an occasion as this Saturday will be, there is one problem. I have to give a <em>speech</em>.<br>
I’m not unaccustomed to public speaking, having given a few techy talks here and there, and during uni, but this…well..this is different.<br>
Giving my speech as the groom of the day will involve standing up in front of a room filled with friends, family, and family-to-be.<br>
As my manager said the other day, this is actually the one time in which your audience is more on your side than any other audience you’ll ever speak before, and yet it’s still as frightening as all hell.</p>
<p>As for how my speech is going, I’ve written over half of it, but I’m now considering re-writing what I’ve got as I’m just not sure if it’s the way I want to go.<br>
Jonty has suggested I write a bunch, plus a <a href="http://en.wikipedia.org/wiki/Markov_chain">markov chaining</a> tool, and generate a speech. Of course he also suggested I include lyrics from <a href="http://www.azlyrics.com/lyrics/willsmith/freshprinceofbelairthemesong.html">The Fresh Prince Of Bel-Air</a>.</p>
<p>Whatever I come up with in the end, I’m sure it’ll be fine, as long as I thank the right people and hit the right sentiments.</p>
<p>&quot;Now, this is a story all about how<br>
My life got flipped-turned upside down<br>
And I’d like to take a minute<br>
Just sit right there…&quot;</p>
]]></content>
  </entry>
  
  <entry>
    <title>Talk @ Brumcon9</title>
    <link href="https://1stvamp.org/talk-brumcon9/"/>
    <id>https://1stvamp.org/talk-brumcon9/</id>
    <updated>2009-12-01T00:00:00.000Z</updated>
    <content type="html"><![CDATA[<p>I’m giving a talk at <a href="http://www.brum2600.net/brumcon9/">Brumcon9</a> this Saturday, titled “Friend me! – Data-mining the social web”, this is my outline (work in progress):</p>
<ul>
<li>Who I am</li>
<li>The “social web”, what’s thattabout den?</li>
<li>Data mining, identity theft, social engineering, and digital forensics</li>
<li>The case of the missing tweet</li>
<li>Tools of the trade</li>
<li>APIs, apps, loopholes &amp; exploits</li>
<li>Stalking Miss Daisy</li>
<li>Outro</li>
</ul>
]]></content>
  </entry>
  
  <entry>
    <title>Dynamically adding methods and static methods onto classes at runtime in PHP5.3</title>
    <link href="https://1stvamp.org/dynamically-adding-methods-and-static-methods-onto-classes-at-runtime-in-php5-3/"/>
    <id>https://1stvamp.org/dynamically-adding-methods-and-static-methods-onto-classes-at-runtime-in-php5-3/</id>
    <updated>2009-11-01T00:00:00.000Z</updated>
    <content type="html"><![CDATA[<p><strong>Before</strong> I begin, let me state that I agree entirely with others who have said that lambda functions and closures aren’t meant to allow you to dynamically extend classes at runtime, what I disagree with is the assertion that there are other ways of doing this. Currently there is no other way of doing this, and while I don’t think I’d use this method in production, it is still an extremely fun hack to use!<br>
You can do things like this inside Lisp-like languages such as Python and Ruby, but they’re naturally parts of the language itself, rather than exploiting the inner working of magic methods with the lambda language feature as I do here.
Returning to the to using some of PHP5.3’s more magic features, I realised that I was being a little short-sighted with my example. In fact you can expand it to include not only methods, but <em>static</em> methods, and not only modifying single objects at runtime but you can emulate modifying the actual class definition itself so that any instantiated objects will have the new methods.</p>
<p>This is made possible by using the new <em>late static binding and __callStatic magic method</em> features. By using late static binding we can call a static method in the base ancestor class which assigns the lamba function passed in to a static hash of methods, indexed by the descendant class you called it via, using the new <code>get_calling_class()</code> function to get it’s class name and use that as the index.<br>
We can use a separate hash of static methods to add static methods (which are just lambdas again) to the class by defining an extra <code>__callStatic()</code> magic method, that works just like the <code>__call()</code> method, but obviously for static calls.</p>
<pre><code>test();// Should output:// default testecho ’2: ‘;$object-&gt;test(‘monkeys’);// Should output: monkeys testecho ’3: ‘;$object-&gt;test(‘chimps’);// Should output: chimps testecho ’4: ‘;$object2 = new MyOtherClass();// Should output: Instantiating “MyOtherClass”echo ’5: ‘;$object2-&gt;test();// Should output: default test2echo ’6: ‘;$object2-&gt;test(‘chimps’);// Should output: chimps test2echo ’7: ‘;$object2-&gt;test(‘conan’);// Should output: conan test2echo ’8: ‘;$object-&gt;test(‘conan’);// Should output: conan test?&gt;
</code></pre>
<p>I’ve released <a href="../code/OneVersion_DynamicClass.tar.gz">OneVersion\DyanmicClass</a> 1.0 out into the wild under the LGPL v2.1, so download and play at your own peril. <code>;-)</code></p>
]]></content>
  </entry>
  
  <entry>
    <title>Extending PHP5.3 objects at runtime with lambda functions</title>
    <link href="https://1stvamp.org/extending-php5-3-objects-at-runtime-with-lambda-functions/"/>
    <id>https://1stvamp.org/extending-php5-3-objects-at-runtime-with-lambda-functions/</id>
    <updated>2009-10-01T00:00:00.000Z</updated>
    <content type="html"><![CDATA[<p><a href="http://snaps.php.net/">PHP 5.3</a> will include <a href="http://wiki.php.net/rfc/closures">lambda functions and closures</a>.<br>
One interesting thing that will come from this will be the ability to dynamically add a method onto a class at runtime, by combining lambas with the magic <code>__call</code> method..well, at least a hack to make something like this.</p>
<p>Effectively this is similar to <a href="http://wiki.php.net/rfc/horizontalreuse">traits/grafts</a>, except you don’t have to define anything in a new class, you just extend the object itself when you come to use it.<br>
You could also use a singleton within the <code>Extensible</code> class that keeps track of any added methods and propagates them to any other existing or new instances.</p>
<pre><code>_methods, $name)) {                        call_user_func_array(array($this, $name), $args);                } else {                        throw new Exception(‘Unknown dynamic method ‘ . $name . ‘ called in class ‘ . get_class($this));                }        }        function __set($name, $value) {                if (is_callable($value)) {                        $this-&gt;_methods[$name] = $value;                }        }}class MyClass extends Extensible {        function test() {                echo ‘Non-dynamic method’;        }}$object = new MyClass();$object-&gt;test2 = function () {        echo ‘Dynamic method’;};// test() is defined within the static class definition$object-&gt;test();// test2() was created dynamically at runtime, but you call it just as// if it had been in the class definition$object-&gt;test2();?&gt;
</code></pre>
<p>EDIT:<br>
Incidentally this my first proper post sent via email. w00t.</p>
]]></content>
  </entry>
  
</feed>
