<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
     xmlns:content="http://purl.org/rss/1.0/modules/content/"
     xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
     xmlns:atom="http://www.w3.org/2005/Atom"
     xmlns:dc="http://purl.org/dc/elements/1.1/"
     xmlns:wfw="http://wellformedweb.org/CommentAPI/"
     >
  <channel>
    <title>Topdog.za.net</title>
    <link>http://www.topdog.za.net</link>
    <description>A bored sysadmin</description>
    <pubDate>Fri, 26 Feb 2016 10:06:56 GMT</pubDate>
    <generator>Blogofile</generator>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Tsantsa: CSS, JS minification and SCSS compilation commands for setuptools release announcement</title>
      <link>http://www.topdog.za.net/2012/10/21/tsantsa:-css--js-minification-and-scss-compilation-commands-for-setuptools-release-announcement</link>
      <pubDate>Sun, 21 Oct 2012 12:30:00 SAST</pubDate>
      <category><![CDATA[Python]]></category>
      <guid isPermaLink="true">http://www.topdog.za.net/2012/10/21/tsantsa:-css--js-minification-and-scss-compilation-commands-for-setuptools-release-announcement</guid>
      <description>Tsantsa: CSS, JS minification and SCSS compilation commands for setuptools release announcement</description>
      <content:encoded><![CDATA[<p>The <a href="https://github.com/akissa/baruwa2">Baruwa 2</a> project uses <a href="http://compass-style.org/">compass</a>
and <a href="http://coffeescript.org/">coffee</a> to generate css and javascript files, these files require
minification to improve performance when deployed.</p>
<p>Baruwa is written in python so it is ideal that the compilation and minification takes place
using setuptools when the package archive is created.</p>
<p>Python setuptools allows for plugin <a href="http://peak.telecommunity.com/DevCenter/setuptools#adding-commands">commands</a>
to be created for actions like this, i searched for existing projects that do css and js minification
and found <a href="http://pypi.python.org/pypi/minify">minify</a> which uses the 
<a href="http://developer.yahoo.com/yui/compressor/">yui compressor</a> from yahoo. Am not a fan of java
so i decided to implement a minification tools plugin that would work using only pure python
without external commands.</p>
<p>The result is <a href="http://bit.ly/XnN6JM">Tsantsa</a> which is based on the minify code
base but uses <a href="https://github.com/zacharyvoase/cssmin">cssmin</a> for CSS and
<a href="http://slimit.org/">slimit</a> for JS minification. It also adds compilation of SCSS code using
the <a href="http://packages.python.org/scss/">scss</a> python package.</p>
<p>Using tsantsa the process of generating Baruwa 2 release tar balls has been simplified.</p>
<p>The package is available for download from <a href="http://bit.ly/XnN6JM">PyPi</a> as well
as <a href="https://crate.io/packages/tsantsa/">crate.io</a> and the source code is available on
<a href="https://github.com/akissa/tsantsa">github</a>.</p>
<p>I have since spoken to the author of the minify package and we have agreed to work together
to create a <a href="https://bitbucket.org/sprat/minify">project</a> that uses the best minification tools
the user has installed on their system, doing what <a href="http://pypi.python.org/pypi/anyjson">anyjson</a>
has done for json for minification.</p>]]></content:encoded>
    </item>
    <item>
      <title>Python modules you should know: PyGPGME</title>
      <link>http://www.topdog.za.net/2012/05/23/python-modules-you-should-know:-pygpgme</link>
      <pubDate>Wed, 23 May 2012 07:40:00 SAST</pubDate>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[PyMYSK]]></category>
      <category><![CDATA[Howto]]></category>
      <guid isPermaLink="true">http://www.topdog.za.net/2012/05/23/python-modules-you-should-know:-pygpgme</guid>
      <description>Python modules you should know: PyGPGME</description>
      <content:encoded><![CDATA[<p>Next in our series of <a href="http://www.topdog.za.net/category/pymysk/"><em>Python modules you should know</em></a>
is PyGPGME. This package lets you sign, verify, encrypt and decrypt messages
using the OpenPGP format. It is built on top of the GNU Privacy Guard and the
<a href="http://www.gnupg.org/related_software/gpgme/index.en.html">GPGME</a> library.</p>
<h2>Home page</h2>
<ul>
<li><a href="https://launchpad.net/pygpgme">https://launchpad.net/pygpgme</a></li>
</ul>
<h2>Use</h2>
<p>PyGPGME is a Python module that lets you sign, verify, encrypt and decrypt messages
using the OpenPGP format.</p>
<h2>Installation</h2>
<p>You need the GPGME library and header files installed to successfully install PyGPGME</p>
<pre><code>pip install PyGPGME
</code></pre>
<h2>Usage</h2>
<p>The documentation for this package is almost non existent i hope my examples will
be able to help at least with getting users started</p>
<h3>Creating a key</h3>
<p>This is similar to running the following command:</p>
<pre><code>gpg --gen-key
</code></pre>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">gpgme</span>

<span class="n">key_params</span> <span class="o">=</span> <span class="s">&quot;&quot;&quot;</span>
<span class="s">&lt;GnupgKeyParms format=&quot;internal&quot;&gt;</span>
<span class="s">Key-Type: RSA</span>
<span class="s">Key-Length: 2048</span>
<span class="s">Name-Real: Jaja of Opobo</span>
<span class="s">Name-Email: jaja@example.com</span>
<span class="s">Expire-Date: 0</span>
<span class="s">Passphrase: secret</span>
<span class="s">&lt;/GnupgKeyParms&gt;</span>
<span class="s">&quot;&quot;&quot;</span>

<span class="c"># create custom gpg directory</span>
<span class="n">gpghome</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">expanduser</span><span class="p">(</span><span class="s">&#39;~/gpghome&#39;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">gpghome</span><span class="p">):</span>
    <span class="n">os</span><span class="o">.</span><span class="n">mkdir</span><span class="p">(</span><span class="n">gpghome</span><span class="p">,</span> <span class="mo">0700</span><span class="p">)</span>

<span class="c"># set the environment to custom gpg directory</span>
<span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s">&#39;GNUPGHOME&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">gpghome</span>
<span class="c"># create a blank configuration file</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">gpghome</span><span class="p">,</span> <span class="s">&#39;gpg.conf&#39;</span><span class="p">),</span> <span class="s">&#39;wv&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">handle</span><span class="p">:</span>
    <span class="n">handle</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&#39;&#39;</span><span class="p">)</span>

<span class="c"># create a context</span>
<span class="n">ctx</span> <span class="o">=</span> <span class="n">gpgme</span><span class="o">.</span><span class="n">Context</span><span class="p">()</span>
<span class="c"># create the key using key_params</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">ctx</span><span class="o">.</span><span class="n">genkey</span><span class="p">(</span><span class="n">key_params</span><span class="p">)</span>
<span class="c"># get the key</span>
<span class="n">key</span> <span class="o">=</span> <span class="n">ctx</span><span class="o">.</span><span class="n">get_key</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">fpr</span><span class="p">,</span> <span class="bp">True</span><span class="p">)</span>
<span class="p">[</span><span class="n">uid</span><span class="p">]</span> <span class="o">=</span> <span class="n">key</span><span class="o">.</span><span class="n">uids</span>
<span class="c"># print key name and email</span>
<span class="k">print</span> <span class="n">uid</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">uid</span><span class="o">.</span><span class="n">email</span>
</pre></div>

<h3>Exporting a key</h3>
<p>This is similar to running the following command:</p>
<pre><code>gpg --export [UID]
</code></pre>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">gpgme</span>
<span class="kn">from</span> <span class="nn">io</span> <span class="kn">import</span> <span class="n">BytesIO</span>

<span class="c"># set the environment to custom gpg directory</span>
<span class="n">gpghome</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">expanduser</span><span class="p">(</span><span class="s">&#39;~/gpghome&#39;</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s">&#39;GNUPGHOME&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">gpghome</span>

<span class="c"># create a context</span>
<span class="n">ctx</span> <span class="o">=</span> <span class="n">gpgme</span><span class="o">.</span><span class="n">Context</span><span class="p">()</span>
<span class="n">ctx</span><span class="o">.</span><span class="n">armor</span> <span class="o">=</span> <span class="bp">True</span>
<span class="n">keydata</span> <span class="o">=</span> <span class="n">BytesIO</span><span class="p">()</span>
<span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">ctx</span><span class="o">.</span><span class="n">keylist</span><span class="p">()</span>
<span class="n">ctx</span><span class="o">.</span><span class="n">export</span><span class="p">(</span><span class="n">key</span><span class="o">.</span><span class="n">subkeys</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">keyid</span><span class="p">,</span> <span class="n">keydata</span><span class="p">)</span>
<span class="k">print</span> <span class="n">keydata</span><span class="o">.</span><span class="n">getvalue</span><span class="p">()</span>
</pre></div>

<h3>Importing a key</h3>
<p>This is similar to running the following command:</p>
<pre><code>gpg --import [Filename]
</code></pre>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">gpgme</span>
<span class="kn">import</span> <span class="nn">urllib2</span>

<span class="c"># set the environment to custom gpg directory</span>
<span class="n">gpghome</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">expanduser</span><span class="p">(</span><span class="s">&#39;~/gpghome&#39;</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s">&#39;GNUPGHOME&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">gpghome</span>

<span class="c"># create a context</span>
<span class="n">ctx</span> <span class="o">=</span> <span class="n">gpgme</span><span class="o">.</span><span class="n">Context</span><span class="p">()</span>
<span class="c"># Download a public key</span>
<span class="n">handle</span> <span class="o">=</span> <span class="n">urllib2</span><span class="o">.</span><span class="n">urlopen</span><span class="p">(</span><span class="s">&#39;http://repo.baruwa.org/RPM-GPG-KEY-BARUWA&#39;</span><span class="p">)</span>
<span class="c"># Import the key</span>
<span class="n">_</span> <span class="o">=</span> <span class="n">ctx</span><span class="o">.</span><span class="n">import_</span><span class="p">(</span><span class="n">handle</span><span class="p">)</span>
<span class="c"># Get key and print out keyID</span>
<span class="n">key</span> <span class="o">=</span> <span class="n">ctx</span><span class="o">.</span><span class="n">get_key</span><span class="p">(</span><span class="s">&#39;4BA17AC7&#39;</span><span class="p">)</span>
<span class="k">print</span> <span class="s">&quot;Imported key ID: &quot;</span><span class="p">,</span> <span class="n">key</span><span class="o">.</span><span class="n">uids</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">uid</span>
</pre></div>

<h3>Delete a key</h3>
<p>This is similar to running the following command:</p>
<pre><code>gpg --delete-key UID
</code></pre>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">gpgme</span>

<span class="c"># set the environment to custom gpg directory</span>
<span class="n">gpghome</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">expanduser</span><span class="p">(</span><span class="s">&#39;~/gpghome&#39;</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s">&#39;GNUPGHOME&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">gpghome</span>

<span class="c"># create a context</span>
<span class="n">ctx</span> <span class="o">=</span> <span class="n">gpgme</span><span class="o">.</span><span class="n">Context</span><span class="p">()</span>
<span class="c"># Get the public key we just imported</span>
<span class="n">key</span> <span class="o">=</span> <span class="n">ctx</span><span class="o">.</span><span class="n">get_key</span><span class="p">(</span><span class="s">&#39;4BA17AC7&#39;</span><span class="p">)</span>
<span class="c"># Delete the key</span>
<span class="n">ctx</span><span class="o">.</span><span class="n">delete</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
</pre></div>

<h3>Sign and verify text</h3>
<p>This is similar to running the following commands:</p>
<pre><code>gpg -s (or --sign) [Data]
gpg [--verify] [Data]
</code></pre>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">gpgme</span>
<span class="kn">from</span> <span class="nn">io</span> <span class="kn">import</span> <span class="n">BytesIO</span>

<span class="c"># set the environment to custom gpg directory</span>
<span class="n">gpghome</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">expanduser</span><span class="p">(</span><span class="s">&#39;~/gpghome&#39;</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s">&#39;GNUPGHOME&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">gpghome</span>
<span class="c"># allow our passphrase callback to work</span>
<span class="k">del</span> <span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s">&#39;GPG_AGENT_INFO&#39;</span><span class="p">]</span>

<span class="c"># passphrase callback function</span>
<span class="k">def</span> <span class="nf">passphrase_cb</span><span class="p">(</span><span class="n">uid_hint</span><span class="p">,</span> <span class="n">passphrase_info</span><span class="p">,</span> <span class="n">prev_was_bad</span><span class="p">,</span> <span class="n">fd</span><span class="p">):</span>
    <span class="s">&quot;pass phrase callback&quot;</span>
    <span class="n">os</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">fd</span><span class="p">,</span> <span class="n">b</span><span class="s">&#39;secret</span><span class="se">\\</span><span class="s">n&#39;</span><span class="p">)</span>

<span class="c"># create a context</span>
<span class="n">ctx</span> <span class="o">=</span> <span class="n">gpgme</span><span class="o">.</span><span class="n">Context</span><span class="p">()</span>
<span class="n">ctx</span><span class="o">.</span><span class="n">armor</span> <span class="o">=</span> <span class="bp">True</span>
<span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">ctx</span><span class="o">.</span><span class="n">keylist</span><span class="p">()</span>
<span class="n">ctx</span><span class="o">.</span><span class="n">signers</span> <span class="o">=</span> <span class="p">[</span><span class="n">key</span><span class="p">]</span>
<span class="n">ctx</span><span class="o">.</span><span class="n">passphrase_cb</span> <span class="o">=</span> <span class="n">passphrase_cb</span>

<span class="c"># sign the data</span>
<span class="n">plaintext</span> <span class="o">=</span> <span class="n">BytesIO</span><span class="p">(</span><span class="n">b</span><span class="s">&#39;Text to be signed</span><span class="se">\\</span><span class="s">n&#39;</span><span class="p">)</span>
<span class="n">signature</span> <span class="o">=</span> <span class="n">BytesIO</span><span class="p">()</span>
<span class="n">signed</span> <span class="o">=</span> <span class="n">ctx</span><span class="o">.</span><span class="n">sign</span><span class="p">(</span><span class="n">plaintext</span><span class="p">,</span> <span class="n">signature</span><span class="p">,</span> <span class="n">gpgme</span><span class="o">.</span><span class="n">SIG_MODE_DETACH</span><span class="p">)</span>

<span class="c"># rewind files</span>
<span class="n">_</span> <span class="o">=</span> <span class="n">signature</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="n">_</span> <span class="o">=</span> <span class="n">plaintext</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>

<span class="c"># Verify signature</span>
<span class="n">sigs</span> <span class="o">=</span> <span class="n">ctx</span><span class="o">.</span><span class="n">verify</span><span class="p">(</span><span class="n">signature</span><span class="p">,</span> <span class="n">plaintext</span><span class="p">,</span> <span class="bp">None</span><span class="p">)</span>
<span class="k">if</span> <span class="n">sigs</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">fpr</span> <span class="o">==</span> <span class="n">key</span><span class="o">.</span><span class="n">subkeys</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">fpr</span><span class="p">:</span>
    <span class="k">print</span> <span class="s">&quot;Signature verified&quot;</span>
    <span class="k">print</span> <span class="n">sigs</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">fpr</span><span class="p">,</span> <span class="n">key</span><span class="o">.</span><span class="n">subkeys</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">fpr</span>
<span class="k">else</span><span class="p">:</span>
    <span class="k">print</span> <span class="s">&quot;Signature verification failed&quot;</span>
</pre></div>

<h3>Encrypt and Decrypt text</h3>
<p>This is similar to running the following commands:</p>
<pre><code>gpg -e Recipient [Data]
gpg [-d] [Data]
</code></pre>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">gpgme</span>
<span class="kn">from</span> <span class="nn">io</span> <span class="kn">import</span> <span class="n">BytesIO</span>

<span class="c"># set the environment to custom gpg directory</span>
<span class="n">gpghome</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">expanduser</span><span class="p">(</span><span class="s">&#39;~/gpghome&#39;</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s">&#39;GNUPGHOME&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">gpghome</span>
<span class="c"># allow our passphrase callback to work</span>
<span class="k">del</span> <span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s">&#39;GPG_AGENT_INFO&#39;</span><span class="p">]</span>

<span class="n">recipient_params</span> <span class="o">=</span> <span class="s">&quot;&quot;&quot;</span>
<span class="s">&lt;GnupgKeyParms format=&quot;internal&quot;&gt;</span>
<span class="s">Key-Type: RSA</span>
<span class="s">Key-Length: 2048</span>
<span class="s">Name-Real: Nana of itsikiri</span>
<span class="s">Name-Email: nana@example.com</span>
<span class="s">Expire-Date: 0</span>
<span class="s">Passphrase: secret</span>
<span class="s">&lt;/GnupgKeyParms&gt;</span>
<span class="s">&quot;&quot;&quot;</span>

<span class="c"># passphrase callback function</span>
<span class="k">def</span> <span class="nf">passphrase_cb</span><span class="p">(</span><span class="n">uid_hint</span><span class="p">,</span> <span class="n">passphrase_info</span><span class="p">,</span> <span class="n">prev_was_bad</span><span class="p">,</span> <span class="n">fd</span><span class="p">):</span>
    <span class="s">&quot;pass phrase callback&quot;</span>
    <span class="n">os</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">fd</span><span class="p">,</span> <span class="n">b</span><span class="s">&#39;secret</span><span class="se">\\</span><span class="s">n&#39;</span><span class="p">)</span>

<span class="c"># create a context</span>
<span class="n">ctx</span> <span class="o">=</span> <span class="n">gpgme</span><span class="o">.</span><span class="n">Context</span><span class="p">()</span>
<span class="n">ctx</span><span class="o">.</span><span class="n">armor</span> <span class="o">=</span> <span class="bp">True</span>
<span class="c"># create a recipient&#39;s key</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">ctx</span><span class="o">.</span><span class="n">genkey</span><span class="p">(</span><span class="n">recipient_params</span><span class="p">)</span>
<span class="n">recipient</span> <span class="o">=</span> <span class="n">ctx</span><span class="o">.</span><span class="n">get_key</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">fpr</span><span class="p">,</span> <span class="bp">True</span><span class="p">)</span>

<span class="n">plaintext</span> <span class="o">=</span> <span class="n">BytesIO</span><span class="p">(</span><span class="n">b</span><span class="s">&#39;Very Secret text</span><span class="se">\\</span><span class="s">n&#39;</span><span class="p">)</span>
<span class="n">ciphertext</span> <span class="o">=</span> <span class="n">BytesIO</span><span class="p">()</span>
<span class="n">ctx</span><span class="o">.</span><span class="n">encrypt</span><span class="p">([</span><span class="n">recipient</span><span class="p">],</span> <span class="n">gpgme</span><span class="o">.</span><span class="n">ENCRYPT_ALWAYS_TRUST</span><span class="p">,</span> <span class="n">plaintext</span><span class="p">,</span> <span class="n">ciphertext</span><span class="p">)</span>

<span class="c"># rewind files</span>
<span class="n">_</span> <span class="o">=</span> <span class="n">ciphertext</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="n">_</span> <span class="o">=</span> <span class="n">plaintext</span> <span class="o">=</span> <span class="n">BytesIO</span><span class="p">()</span>
<span class="n">ctx</span><span class="o">.</span><span class="n">passphrase_cb</span> <span class="o">=</span> <span class="n">passphrase_cb</span>
<span class="n">ctx</span><span class="o">.</span><span class="n">decrypt</span><span class="p">(</span><span class="n">ciphertext</span><span class="p">,</span> <span class="n">plaintext</span><span class="p">)</span>
<span class="k">print</span> <span class="s">&quot;The decrypted text is: &quot;</span><span class="p">,</span> <span class="n">plaintext</span><span class="o">.</span><span class="n">getvalue</span><span class="p">()</span>
</pre></div>

<h3>List keys</h3>
<p>This is similar to running the following command:</p>
<pre><code>gpg --list-keys
</code></pre>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">gpgme</span>

<span class="c"># set the environment to custom gpg directory</span>
<span class="n">gpghome</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">expanduser</span><span class="p">(</span><span class="s">&#39;~/gpghome&#39;</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s">&#39;GNUPGHOME&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">gpghome</span>

<span class="c"># create a context</span>
<span class="n">ctx</span> <span class="o">=</span> <span class="n">gpgme</span><span class="o">.</span><span class="n">Context</span><span class="p">()</span>
<span class="c"># iterate key list</span>
<span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">ctx</span><span class="o">.</span><span class="n">keylist</span><span class="p">():</span>
    <span class="k">for</span> <span class="n">uid</span> <span class="ow">in</span> <span class="n">key</span><span class="o">.</span><span class="n">uids</span><span class="p">:</span>
        <span class="k">print</span> <span class="n">uid</span><span class="o">.</span><span class="n">uid</span>
</pre></div>

<h3>List secret keys</h3>
<p>This is similar to running the following command:</p>
<pre><code>gpg --list-secret-keys
</code></pre>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">gpgme</span>

<span class="c"># set the environment to custom gpg directory</span>
<span class="n">gpghome</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">expanduser</span><span class="p">(</span><span class="s">&#39;~/gpghome&#39;</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s">&#39;GNUPGHOME&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">gpghome</span>

<span class="c"># create a context</span>
<span class="n">ctx</span> <span class="o">=</span> <span class="n">gpgme</span><span class="o">.</span><span class="n">Context</span><span class="p">()</span>
<span class="c"># iterate secret key list</span>
<span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">ctx</span><span class="o">.</span><span class="n">keylist</span><span class="p">(</span><span class="bp">None</span><span class="p">,</span> <span class="bp">True</span><span class="p">):</span>
    <span class="k">for</span> <span class="n">uid</span> <span class="ow">in</span> <span class="n">key</span><span class="o">.</span><span class="n">uids</span><span class="p">:</span>
        <span class="k">print</span> <span class="n">uid</span><span class="o">.</span><span class="n">uid</span>
</pre></div>

<h2>And there is more.</h2>
<p>For more GPG operations you can perform look at the API</p>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">gpgme</span>
<span class="n">help</span><span class="p">(</span><span class="n">gpgme</span><span class="p">)</span>
</pre></div>]]></content:encoded>
    </item>
    <item>
      <title>Crate.io, A Next Generation Python Packaging Index</title>
      <link>http://www.topdog.za.net/2012/05/16/crate.io--a-next-generation-python-packaging-index</link>
      <pubDate>Wed, 16 May 2012 07:30:00 SAST</pubDate>
      <category><![CDATA[Python]]></category>
      <guid isPermaLink="true">http://www.topdog.za.net/2012/05/16/crate.io--a-next-generation-python-packaging-index</guid>
      <description>Crate.io, A Next Generation Python Packaging Index</description>
      <content:encoded><![CDATA[<p>I just came across <a href="https://crate.io">crate.io</a> a PyPI Mirror/Python Package
Index that was written to make it easy to discover packages, evaluate them for
usefulness, and then install them.</p>
<p>I am impressed, the interface to me is more functional than the dated
<a href="http://pypi.python.org/pypi/">Cheeseshop</a>.</p>
<p>It uses Django/Postgesql/Redis/Celery and the Backend and frontend code is
available for download on <a href="https://github.com/crateio">github</a></p>
<p>You can find my <a href="https://crate.io/packages/baruwa/">Baruwa</a> project on crate.io</p>]]></content:encoded>
    </item>
    <item>
      <title>Python modules you should know: pydkim</title>
      <link>http://www.topdog.za.net/2012/05/08/python-modules-you-should-know:-pydkim</link>
      <pubDate>Tue, 08 May 2012 16:40:00 SAST</pubDate>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[PyMYSK]]></category>
      <category><![CDATA[Howto]]></category>
      <guid isPermaLink="true">http://www.topdog.za.net/2012/05/08/python-modules-you-should-know:-pydkim</guid>
      <description>Python modules you should know: pydkim</description>
      <content:encoded><![CDATA[<p>Next in our series of <a href="http://www.topdog.za.net/category/pymysk/"><em>Python modules you should know</em></a>
is pydkim. This package is used to sign and verify email according to the <a href="http://dkim.org/">DKIM</a>
standards from within Python programs.</p>
<h2>Home page</h2>
<ul>
<li><a href="http://hewgill.com/pydkim/">http://hewgill.com/pydkim/</a></li>
</ul>
<h2>Use</h2>
<p>The pydkim module is a Python module that implements DKIM (DomainKeys Identified Mail) email signing
and verification.</p>
<p>DomainKeys Identified Mail (DKIM) lets an organization take responsibility for a message that is in
transit. Technically DKIM provides a method for validating a domain name identity that is associated
with a message through cryptographic authentication.</p>
<p>Although DKIM is implemented in most MTA's, in some cases you have a setup where you do not want to
run and manage an SMTP server yourself say for example if your Python application uses <a href="http://docs.amazonwebservices.com/ses/latest/DeveloperGuide/DKIM.html">Amazon SES</a> to send out email. So you
can use pydkim within your email generation code to sign your messages before passing them to SES.</p>
<h2>Installation</h2>
<pre><code>pip install pydkim
</code></pre>
<h2>Usage</h2>
<p>The package provides a command line interface as well as a Python Class.</p>
<h3>Python Class</h3>
<p>Sign a message</p>
<div class="pygments_murphy"><pre><span class="kn">from</span> <span class="nn">email.message</span> <span class="kn">import</span> <span class="n">Message</span>

<span class="kn">from</span> <span class="nn">dkim</span> <span class="kn">import</span> <span class="n">sign</span>

<span class="n">body</span> <span class="o">=</span> <span class="s">&quot;&quot;&quot;Hi There,</span>

<span class="s">This is a simple message that will be signed by pydkim</span>

<span class="s">--The signer</span>
<span class="s">&quot;&quot;&quot;</span>
<span class="c"># compose a simple message</span>
<span class="n">msg</span> <span class="o">=</span> <span class="n">Message</span><span class="p">()</span>
<span class="n">msg</span><span class="p">[</span><span class="s">&#39;From&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s">&#39;Sender &lt;sender@topdog-software.com&gt;&#39;</span>
<span class="n">msg</span><span class="p">[</span><span class="s">&#39;To&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s">&#39;Recipient &lt;recipient@example.com&gt;&#39;</span>
<span class="n">msg</span><span class="p">[</span><span class="s">&#39;Subject&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s">&#39;Test message&#39;</span>
<span class="n">msg</span><span class="o">.</span><span class="n">set_payload</span><span class="p">(</span><span class="n">body</span><span class="p">)</span>

<span class="c"># sign the message</span>
<span class="n">private_key</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s">&#39;default.pem&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
<span class="n">headers</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;To&#39;</span><span class="p">,</span> <span class="s">&#39;From&#39;</span><span class="p">,</span> <span class="s">&#39;Subject&#39;</span><span class="p">]</span>
<span class="n">email</span> <span class="o">=</span> <span class="n">msg</span><span class="o">.</span><span class="n">as_string</span><span class="p">()</span>
<span class="n">sig</span> <span class="o">=</span> <span class="n">sign</span><span class="p">(</span><span class="n">email</span><span class="p">,</span> <span class="s">&#39;default&#39;</span><span class="p">,</span> <span class="s">&#39;topdog-software.com&#39;</span><span class="p">,</span> <span class="n">private_key</span><span class="p">,</span> <span class="n">include_headers</span><span class="o">=</span><span class="n">headers</span><span class="p">)</span>
<span class="k">print</span> <span class="n">sig</span><span class="p">,</span> <span class="n">email</span>
</pre></div>

<p>Output:</p>
<pre><code>DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple;
 d=topdog-software.com; i=@topdog-software.com; q=dns/txt; s=default;
 t=1336488625; h=From : To : Subject;
 bh=skd2vA1wrCEzamCzKOvVKCaVhhpP1ihoQgGldgTSVUE=; b=vGQgSjJxkTZe+NZZl
lqszgxGshTcixlcfFos+XpLnAj1fnhA5SuBASoB4dVQUlVW76U5s9Dn1zSSsKH
6bCahl4oPqZaE5t6Ke5wpGwA+cBWZRrSuDDD/L8g9nYi04SVb+lMF9mJyQCeZj
pBtMomaOvGF8GNXsiKTFZR9RDv0wWw=
From: Sender &lt;sender@topdog-software.com&gt;
To: Recipient &lt;recipient@example.com&gt;
Subject: Test message

Hi There,

This is a simple message that will be signed by pydkim

--The signer
</code></pre>
<p>Verify a message (I use the same message signed above)</p>
<div class="pygments_murphy"><pre><span class="kn">from</span> <span class="nn">dkim</span> <span class="kn">import</span> <span class="n">verify</span>

<span class="k">if</span> <span class="n">verify</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="s">&#39;email.txt&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">()):</span>
    <span class="k">print</span> <span class="s">&quot;Email verified successfully&quot;</span>
</pre></div>

<pre><code>True
</code></pre>
<h3>Command line</h3>
<p>Sign a message</p>
<pre><code>dkimsign.py selector domain privatekeyfile [identity]
</code></pre>
<p>Verify a message</p>
<pre><code>cat email.txt | dkimverify.py
echo $?
</code></pre>
<h2>And there is more.</h2>
<p>For details of the API please refer to the <a href="http://hewgill.com/pydkim/html/">documentation</a>.
Happy DKIMing</p>]]></content:encoded>
    </item>
    <item>
      <title>Python modules you should know: dnspython</title>
      <link>http://www.topdog.za.net/2012/05/07/python-modules-you-should-know:-dnspython</link>
      <pubDate>Mon, 07 May 2012 16:40:00 SAST</pubDate>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[PyMYSK]]></category>
      <category><![CDATA[Howto]]></category>
      <guid isPermaLink="true">http://www.topdog.za.net/2012/05/07/python-modules-you-should-know:-dnspython</guid>
      <description>Python modules you should know: dnspython</description>
      <content:encoded><![CDATA[<p>Next in our series of <a href="http://www.topdog.za.net/category/pymysk/"><em>Python modules you should know</em></a>
is dnspython. This package is a DNS toolkit, you can use it to perform
DNS queries, Zone transfers and Dynamic Updates in Python programs.</p>
<h2>Home page</h2>
<ul>
<li><a href="http://www.dnspython.org/">http://www.dnspython.org/</a></li>
</ul>
<h2>Use</h2>
<p>dnspython is a DNS toolkit for Python. It supports almost all record types.
It can be used for queries, zone transfers, and dynamic updates. It supports
TSIG authenticated messages and EDNS0.</p>
<p>dnspython provides both high and low level access to DNS. The high level
classes perform queries for data of a given name, type, and class, and
return an answer set. The low level classes allow direct manipulation of
DNS zones, messages, names, and records.</p>
<h2>Installation</h2>
<pre><code>pip install dnspython
</code></pre>
<h2>Usage</h2>
<p>Lookup DNS records (A, AAAA, MX, NS)</p>
<p><strong>A Records</strong></p>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">dns.resolver</span>
<span class="n">answers</span> <span class="o">=</span> <span class="n">dns</span><span class="o">.</span><span class="n">resolver</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s">&#39;topdog.za.net&#39;</span><span class="p">,</span> <span class="s">&#39;A&#39;</span><span class="p">)</span>
<span class="k">for</span> <span class="n">rdata</span> <span class="ow">in</span> <span class="n">answers</span><span class="p">:</span>
    <span class="k">print</span> <span class="n">rdata</span><span class="o">.</span><span class="n">address</span>
</pre></div>

<p><strong>AAAA Records</strong></p>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">dns.resolver</span>
<span class="n">answers</span> <span class="o">=</span> <span class="n">dns</span><span class="o">.</span><span class="n">resolver</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s">&#39;topdog.za.net&#39;</span><span class="p">,</span> <span class="s">&#39;AAAA&#39;</span><span class="p">)</span>
<span class="k">for</span> <span class="n">rdata</span> <span class="ow">in</span> <span class="n">answers</span><span class="p">:</span>
    <span class="k">print</span> <span class="n">rdata</span><span class="o">.</span><span class="n">address</span>
</pre></div>

<p><strong>MX Records</strong></p>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">dns.resolver</span>
<span class="n">answers</span> <span class="o">=</span> <span class="n">dns</span><span class="o">.</span><span class="n">resolver</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s">&#39;topdog.za.net&#39;</span><span class="p">,</span> <span class="s">&#39;MX&#39;</span><span class="p">)</span>
<span class="k">for</span> <span class="n">rdata</span> <span class="ow">in</span> <span class="n">answers</span><span class="p">:</span>
    <span class="k">print</span> <span class="s">&#39;host&#39;</span><span class="p">,</span> <span class="n">rdata</span><span class="o">.</span><span class="n">exchange</span><span class="p">,</span> <span class="s">&#39;has preference&#39;</span><span class="p">,</span> <span class="n">rdata</span><span class="o">.</span><span class="n">preference</span>
</pre></div>

<p><strong>NS Records</strong></p>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">dns.resolver</span>
<span class="n">answers</span> <span class="o">=</span> <span class="n">dns</span><span class="o">.</span><span class="n">resolver</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s">&#39;topdog.za.net&#39;</span><span class="p">,</span> <span class="s">&#39;NS&#39;</span><span class="p">)</span>
<span class="k">for</span> <span class="n">rdata</span> <span class="ow">in</span> <span class="n">answers</span><span class="p">:</span>
    <span class="k">print</span> <span class="n">rdata</span><span class="o">.</span><span class="n">to_text</span><span class="p">()</span>
</pre></div>

<p>Transfer a Zone from a server.</p>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">dns.zone</span>
<span class="kn">import</span> <span class="nn">dns.query</span>
<span class="n">zone</span> <span class="o">=</span> <span class="n">dns</span><span class="o">.</span><span class="n">zone</span><span class="o">.</span><span class="n">from_xfr</span><span class="p">(</span><span class="n">dns</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">xfr</span><span class="p">(</span><span class="s">&#39;174.136.108.83&#39;</span><span class="p">,</span> <span class="s">&#39;topdog.za.net&#39;</span><span class="p">))</span>
<span class="k">print</span> <span class="s">&quot;*&quot;</span> <span class="o">*</span> <span class="mi">10</span><span class="p">,</span> <span class="s">&quot;A records&quot;</span><span class="p">,</span> <span class="s">&quot;*&quot;</span> <span class="o">*</span> <span class="mi">10</span>
<span class="k">for</span> <span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">ttl</span><span class="p">,</span> <span class="n">rdata</span><span class="p">)</span> <span class="ow">in</span> <span class="n">zone</span><span class="o">.</span><span class="n">iterate_rdatas</span><span class="p">(</span><span class="s">&#39;A&#39;</span><span class="p">):</span>
    <span class="k">print</span> <span class="n">name</span><span class="p">,</span> <span class="s">&quot;with TTL&quot;</span><span class="p">,</span> <span class="n">ttl</span><span class="p">,</span> <span class="s">&quot;points to&quot;</span><span class="p">,</span> <span class="n">rdata</span>
<span class="k">print</span> <span class="s">&quot;*&quot;</span> <span class="o">*</span> <span class="mi">10</span><span class="p">,</span> <span class="s">&quot;MX records&quot;</span><span class="p">,</span> <span class="s">&quot;*&quot;</span> <span class="o">*</span> <span class="mi">10</span>
<span class="k">for</span> <span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">ttl</span><span class="p">,</span> <span class="n">rdata</span><span class="p">)</span> <span class="ow">in</span> <span class="n">zone</span><span class="o">.</span><span class="n">iterate_rdatas</span><span class="p">(</span><span class="s">&#39;MX&#39;</span><span class="p">):</span>
    <span class="k">print</span> <span class="n">name</span><span class="p">,</span> <span class="s">&quot;with TTL&quot;</span><span class="p">,</span> <span class="n">ttl</span><span class="p">,</span> <span class="s">&quot;points to&quot;</span><span class="p">,</span> <span class="n">rdata</span>
<span class="k">print</span> <span class="s">&quot;*&quot;</span> <span class="o">*</span> <span class="mi">10</span><span class="p">,</span> <span class="s">&quot;NS records&quot;</span><span class="p">,</span> <span class="s">&quot;*&quot;</span> <span class="o">*</span> <span class="mi">10</span>
<span class="k">for</span> <span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">ttl</span><span class="p">,</span> <span class="n">rdata</span><span class="p">)</span> <span class="ow">in</span> <span class="n">zone</span><span class="o">.</span><span class="n">iterate_rdatas</span><span class="p">(</span><span class="s">&#39;NS&#39;</span><span class="p">):</span>
    <span class="k">print</span> <span class="n">name</span><span class="p">,</span> <span class="s">&quot;with TTL&quot;</span><span class="p">,</span> <span class="n">ttl</span><span class="p">,</span> <span class="s">&quot;points to&quot;</span><span class="p">,</span> <span class="n">rdata</span>
</pre></div>

<p>Generate reverse names</p>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">dns.reversename</span>
<span class="k">print</span> <span class="n">dns</span><span class="o">.</span><span class="n">reversename</span><span class="o">.</span><span class="n">from_address</span><span class="p">(</span><span class="s">&#39;174.136.108.83&#39;</span><span class="p">)</span>
</pre></div>

<p>Perform a Dynamic record update (example from documentation modified)</p>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">dns.query</span>
<span class="kn">import</span> <span class="nn">dns.tsigkeyring</span>
<span class="kn">import</span> <span class="nn">dns.update</span>
<span class="kn">import</span> <span class="nn">sys</span>

<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="n">keyring</span> <span class="o">=</span> <span class="n">dns</span><span class="o">.</span><span class="n">tsigkeyring</span><span class="o">.</span><span class="n">from_text</span><span class="p">({</span>
        <span class="s">&#39;host-example.&#39;</span> <span class="p">:</span> <span class="s">&#39;XXXXXXXXXXXXXXXXXXXXXX==&#39;</span>
    <span class="p">})</span>
    <span class="c"># Replace an A record</span>
    <span class="n">update</span> <span class="o">=</span> <span class="n">dns</span><span class="o">.</span><span class="n">update</span><span class="o">.</span><span class="n">Update</span><span class="p">(</span><span class="s">&#39;example.com&#39;</span><span class="p">,</span> <span class="n">keyring</span><span class="o">=</span><span class="n">keyring</span><span class="p">)</span>
    <span class="n">update</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s">&#39;host&#39;</span><span class="p">,</span> <span class="mi">300</span><span class="p">,</span> <span class="s">&#39;a&#39;</span><span class="p">,</span> <span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
    <span class="n">response</span> <span class="o">=</span> <span class="n">dns</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">tcp</span><span class="p">(</span><span class="n">update</span><span class="p">,</span> <span class="s">&#39;10.0.0.1&#39;</span><span class="p">)</span>
</pre></div>

<h2>And there is more</h2>
<p>There is more that can be done using this package please refer to
the <a href="http://www.dnspython.org/docs/1.10.0/html/">documentation</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Python modules you should know: IPy</title>
      <link>http://www.topdog.za.net/2012/05/06/python-modules-you-should-know:-ipy</link>
      <pubDate>Sun, 06 May 2012 16:40:00 SAST</pubDate>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[PyMYSK]]></category>
      <category><![CDATA[Howto]]></category>
      <guid isPermaLink="true">http://www.topdog.za.net/2012/05/06/python-modules-you-should-know:-ipy</guid>
      <description>Python modules you should know: IPy</description>
      <content:encoded><![CDATA[<p>Next in our series of <a href="http://www.topdog.za.net/category/pymysk/"><em>Python modules you should know</em></a>
is IPy. This package is used to manipulate IPv4 and IPv6 addresses in Python programs.</p>
<h2>Home page</h2>
<ul>
<li><a href="https://github.com/haypo/python-ipy/">https://github.com/haypo/python-ipy/</a></li>
</ul>
<h2>Use</h2>
<p>The IP class allows a comfortable parsing and handling for most
notations in use for IPv4 and IPv6 addresses and networks. It was
greatly inspired by RIPE's Perl module NET::IP's interface but
doesn't share the implementation.</p>
<h2>Installation</h2>
<pre><code>pip install IPy
</code></pre>
<h2>Usage</h2>
<p>Print IP addresses in an IP range</p>
<div class="pygments_murphy"><pre><span class="kn">from</span> <span class="nn">IPy</span> <span class="kn">import</span> <span class="n">IP</span>
<span class="n">network</span> <span class="o">=</span> <span class="n">IP</span><span class="p">(</span><span class="s">&#39;192.168.0.0/30&#39;</span><span class="p">)</span>
<span class="k">for</span> <span class="n">ip</span> <span class="ow">in</span> <span class="n">network</span><span class="p">:</span>
    <span class="k">print</span> <span class="n">ip</span>
</pre></div>

<p>Output:</p>
<pre><code>192.168.0.0
192.168.0.1
192.168.0.2
192.168.0.3
</code></pre>
<p>Generate Reverse names for reverse lookup/PTR records</p>
<div class="pygments_murphy"><pre><span class="kn">from</span> <span class="nn">IPy</span> <span class="kn">import</span> <span class="n">IP</span>
<span class="n">network</span> <span class="o">=</span> <span class="n">IP</span><span class="p">(</span><span class="s">&#39;192.168.0.0/30&#39;</span><span class="p">)</span>
<span class="k">for</span> <span class="n">ip</span> <span class="ow">in</span> <span class="n">network</span><span class="p">:</span>
    <span class="k">print</span> <span class="n">ip</span><span class="o">.</span><span class="n">reverseName</span><span class="p">()</span>
</pre></div>

<div class="pygments_murphy"><pre><span class="kn">from</span> <span class="nn">IPy</span> <span class="kn">import</span> <span class="n">IP</span>
<span class="n">network</span> <span class="o">=</span> <span class="n">IP</span><span class="p">(</span><span class="s">&#39;192.168.0.0/30&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">reverseNames</span><span class="p">()</span>
<span class="k">for</span> <span class="n">ip</span> <span class="ow">in</span> <span class="n">network</span><span class="p">:</span>
    <span class="k">print</span> <span class="n">ip</span>
</pre></div>

<p>Output:</p>
<pre><code>0.0.168.192.in-addr.arpa.
1.0.168.192.in-addr.arpa.
2.0.168.192.in-addr.arpa.
3.0.168.192.in-addr.arpa.
</code></pre>
<p>Check IP version:</p>
<div class="pygments_murphy"><pre><span class="kn">from</span> <span class="nn">IPy</span> <span class="kn">import</span> <span class="n">IP</span>
<span class="k">print</span> <span class="n">IP</span><span class="p">(</span><span class="s">&#39;192.168.0.0/30&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">version</span><span class="p">()</span>
<span class="k">print</span> <span class="n">IP</span><span class="p">(</span><span class="s">&#39;::1&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">version</span><span class="p">()</span>
</pre></div>

<p>Output:</p>
<pre><code>4
6
</code></pre>
<p>Get network prefixes</p>
<div class="pygments_murphy"><pre><span class="kn">from</span> <span class="nn">IPy</span> <span class="kn">import</span> <span class="n">IP</span>
<span class="k">print</span> <span class="n">IP</span><span class="p">(</span><span class="s">&#39;192.168.0.0/30&#39;</span><span class="p">)</span>
<span class="k">print</span> <span class="n">IP</span><span class="p">(</span><span class="s">&#39;192.168.0.0/255.255.255.252&#39;</span><span class="p">)</span>
<span class="k">print</span> <span class="n">IP</span><span class="p">(</span><span class="s">&#39;192.168.0.0-192.168.0.3)</span>
</pre></div>

<p>Output:</p>
<pre><code>192.168.0.0/30
192.168.0.0/30
192.168.0.0/30
</code></pre>
<p>Get the broadcast address</p>
<div class="pygments_murphy"><pre><span class="kn">from</span> <span class="nn">IPy</span> <span class="kn">import</span> <span class="n">IP</span>
<span class="k">print</span> <span class="n">IP</span><span class="p">(</span><span class="s">&#39;192.168.0.0/30&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">broadcast</span><span class="p">()</span>
</pre></div>

<p>Output:</p>
<pre><code>192.168.0.3
</code></pre>
<p>Get the network mask</p>
<div class="pygments_murphy"><pre><span class="kn">from</span> <span class="nn">IPy</span> <span class="kn">import</span> <span class="n">IP</span>
<span class="k">print</span> <span class="n">IP</span><span class="p">(</span><span class="s">&#39;192.168.0.0/30&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">netmask</span><span class="p">()</span>
</pre></div>

<p>Output:</p>
<pre><code>255.255.255.252
</code></pre>
<p>Check if an IP address is within a network</p>
<div class="pygments_murphy"><pre><span class="kn">from</span> <span class="nn">IPy</span> <span class="kn">import</span> <span class="n">IP</span>
<span class="s">&#39;192.168.0.1&#39;</span> <span class="ow">in</span> <span class="n">IP</span><span class="p">(</span><span class="s">&#39;192.168.0.0/30&#39;</span><span class="p">)</span>
</pre></div>

<p>Check a network type LOOPBACK, PRIVATE, PUBLIC, RESERVED</p>
<div class="pygments_murphy"><pre><span class="kn">from</span> <span class="nn">IPy</span> <span class="kn">import</span> <span class="n">IP</span>
<span class="k">print</span> <span class="n">IP</span><span class="p">(</span><span class="s">&#39;192.168.0.1&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">iptype</span><span class="p">()</span>
</pre></div>

<p>Output:</p>
<pre><code>PRIVATE
</code></pre>
<h2>And there is more</h2>
<p>There is more that can be done using this package please refer to
the documentation or run.</p>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">IPy</span>
<span class="n">help</span><span class="p">(</span><span class="n">IPy</span><span class="p">)</span>
</pre></div>]]></content:encoded>
    </item>
    <item>
      <title>Python modules you should know: PyClamd</title>
      <link>http://www.topdog.za.net/2012/05/02/python-modules-you-should-know:-pyclamd</link>
      <pubDate>Wed, 02 May 2012 12:39:00 SAST</pubDate>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[PyMYSK]]></category>
      <category><![CDATA[Howto]]></category>
      <guid isPermaLink="true">http://www.topdog.za.net/2012/05/02/python-modules-you-should-know:-pyclamd</guid>
      <description>Python modules you should know: PyClamd</description>
      <content:encoded><![CDATA[<p>Next in our series of <a href="http://www.topdog.za.net/category/pymysk/"><em>Python modules you should know</em></a>
is PyClamd. This package is used integrate Clamav Virus detection in Python programs.</p>
<h2>Home page</h2>
<ul>
<li><a href="http://xael.org/norman/python/pyclamd/">http://xael.org/norman/python/pyclamd/</a></li>
</ul>
<h2>Use</h2>
<p>pyClamd is a python interface to Clamd (Clamav daemon). By using pyClamd, you can add
virus detection capabilities to your python software in an efficient and easy way.</p>
<p>pyClamd may be used by a closed source product, as it does not link with the GPL licensed
libclamav.</p>
<h2>Installation</h2>
<p>This package is not available on the cheeseshop (PYPI) so you need to install it by
downloading the module.</p>
<pre><code>wget http://xael.org/norman/python/pyclamd/pyclamd.py
mv pyclamd.py $(python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")/
</code></pre>
<h2>Usage</h2>
<p>pyClamd supports connections to clamd using both TCP and UNIX sockets.</p>
<p><strong>TCP</strong></p>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">pyclamd</span>
<span class="n">pyclamd</span><span class="o">.</span><span class="n">init_network_socket</span><span class="p">(</span><span class="s">&#39;localhost&#39;</span><span class="p">,</span> <span class="mi">3310</span><span class="p">)</span>
<span class="k">print</span> <span class="n">pyclamd</span><span class="o">.</span><span class="n">version</span><span class="p">()</span>
</pre></div>

<p>Output:</p>
<pre><code>ClamAV 0.97.4/14869/Tue May  1 22:38:26 2012
</code></pre>
<p><strong>Unix socket</strong></p>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">pyclamd</span>
<span class="n">pyclamd</span><span class="o">.</span><span class="n">init_unix_socket</span><span class="p">(</span><span class="s">&#39;/tmp/clamd.socket&#39;</span><span class="p">)</span>
<span class="k">print</span> <span class="n">pyclamd</span><span class="o">.</span><span class="n">version</span><span class="p">()</span>
</pre></div>

<p>Output:</p>
<pre><code>ClamAV 0.97.4/14869/Tue May  1 22:38:26 2012
</code></pre>
<p><strong>Scan files</strong></p>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">pyclamd</span>
<span class="n">pyclamd</span><span class="o">.</span><span class="n">init_unix_socket</span><span class="p">(</span><span class="s">&#39;/tmp/clamd.socket&#39;</span><span class="p">)</span>
<span class="n">pyclamd</span><span class="o">.</span><span class="n">contscan_file</span><span class="p">(</span><span class="s">&#39;/tmp&#39;</span><span class="p">)</span>
</pre></div>

<p><strong>Scan and stop if virus detected</strong></p>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">pyclamd</span>
<span class="n">pyclamd</span><span class="o">.</span><span class="n">init_unix_socket</span><span class="p">(</span><span class="s">&#39;/tmp/clamd.socket&#39;</span><span class="p">)</span>
<span class="n">pyclamd</span><span class="o">.</span><span class="n">scan_file</span><span class="p">(</span><span class="s">&#39;/tmp&#39;</span><span class="p">)</span>
</pre></div>

<p><strong>Ping server to check if still alive</strong></p>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">pyclamd</span>
<span class="n">pyclamd</span><span class="o">.</span><span class="n">init_unix_socket</span><span class="p">(</span><span class="s">&#39;/tmp/clamd.socket&#39;</span><span class="p">)</span>
<span class="n">pyclamd</span><span class="o">.</span><span class="n">ping</span><span class="p">()</span>
</pre></div>

<p><strong>Scan a stream</strong></p>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">pyclamd</span>
<span class="n">pyclamd</span><span class="o">.</span><span class="n">init_unix_socket</span><span class="p">(</span><span class="s">&#39;/tmp/clamd.socket&#39;</span><span class="p">)</span>
<span class="n">mystring</span> <span class="o">=</span> <span class="s">&#39;X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*&#39;</span>
<span class="n">pyclamd</span><span class="o">.</span><span class="n">scan_stream</span><span class="p">(</span><span class="n">mystring</span><span class="p">)</span>
</pre></div>

<p>Output:</p>
<pre><code>{'stream': 'Eicar-Test-Signature'}
</code></pre>
<p><strong>Reload clamd</strong></p>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">pyclamd</span>
<span class="n">pyclamd</span><span class="o">.</span><span class="n">init_unix_socket</span><span class="p">(</span><span class="s">&#39;/tmp/clamd.socket&#39;</span><span class="p">)</span>
<span class="n">pyclamd</span><span class="o">.</span><span class="n">reload</span><span class="p">()</span>
</pre></div>

<p>Output:</p>
<pre><code>'RELOADING'
</code></pre>
<p><strong>Shutdown clamd</strong></p>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">pyclamd</span>
<span class="n">pyclamd</span><span class="o">.</span><span class="n">init_unix_socket</span><span class="p">(</span><span class="s">&#39;/tmp/clamd.socket&#39;</span><span class="p">)</span>
<span class="n">pyclamd</span><span class="o">.</span><span class="n">shutdown</span><span class="p">()</span>
</pre></div>

<p>The module raises various exceptions that you will need to catch, please refer to the
<a href="http://xael.org/norman/python/pyclamd/">documentation</a> for details.</p>]]></content:encoded>
    </item>
    <item>
      <title>Python modules you should know: Pwtools</title>
      <link>http://www.topdog.za.net/2012/05/01/python-modules-you-should-know:-pwtools</link>
      <pubDate>Tue, 01 May 2012 12:39:00 SAST</pubDate>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[PyMYSK]]></category>
      <category><![CDATA[Howto]]></category>
      <guid isPermaLink="true">http://www.topdog.za.net/2012/05/01/python-modules-you-should-know:-pwtools</guid>
      <description>Python modules you should know: Pwtools</description>
      <content:encoded><![CDATA[<p>Next in our series of <a href="http://www.topdog.za.net/category/pymysk/"><em>Python modules you should know</em></a>
is Pwtools. This package is used to generate and test passwords in Python programs.</p>
<h2>Home page</h2>
<ul>
<li><a href="http://alastairs-place.net/projects/pwtools/">http://alastairs-place.net/projects/pwtools/</a></li>
</ul>
<h2>Use</h2>
<p>pwtools is a Python package that provides the ability to generate passwords, and
also allows you to test them to ensure that they are reasonably secure.</p>
<p>The algorithms used were borrowed from the <a href="http://www.openwall.com/">Openwall</a> Project’s
<a href="http://www.openwall.com/passwdqc">passwdqc</a> project, but have been re-implemented in Python
for increased portability.</p>
<h2>Installation</h2>
<p>This package is not available on the cheeseshop (PYPI) so you need to install it from the
Mercurial repository.</p>
<pre><code>pip install hg+http://alastairs-place.net/hg/pwtools
</code></pre>
<h2>Usage</h2>
<p>Generate a strong password:</p>
<div class="pygments_murphy"><pre><span class="kn">from</span> <span class="nn">pwtools</span> <span class="kn">import</span> <span class="n">PasswordGenerator</span>
<span class="n">pwgen</span> <span class="o">=</span> <span class="n">PasswordGenerator</span><span class="p">()</span>
<span class="n">pwgen</span><span class="o">.</span><span class="n">generate</span><span class="p">()</span>
</pre></div>

<p>Output:</p>
<pre><code>'amaze*Period&amp;Thirst'
</code></pre>
<p>Check password strength:</p>
<div class="pygments_murphy"><pre><span class="kn">from</span> <span class="nn">pwtools</span> <span class="kn">import</span> <span class="n">PasswordChecker</span>
<span class="n">pwchecker</span> <span class="o">=</span> <span class="n">PasswordChecker</span><span class="p">(</span><span class="s">&#39;/usr/share/dict/words&#39;</span><span class="p">)</span>
<span class="n">pwchecker</span><span class="o">.</span><span class="n">checkPassword</span><span class="p">(</span><span class="s">&#39;password&#39;</span><span class="p">)</span>
<span class="n">pwchecker</span><span class="o">.</span><span class="n">checkPassword</span><span class="p">(</span><span class="s">&#39;zxcvbnm&#39;</span><span class="p">)</span>
<span class="n">pwchecker</span><span class="o">.</span><span class="n">checkPassword</span><span class="p">(</span><span class="s">&#39;123456abcdef&#39;</span><span class="p">)</span>
<span class="n">pwchecker</span><span class="o">.</span><span class="n">checkPassword</span><span class="p">(</span><span class="s">&#39;m1ll10n&#39;</span><span class="p">)</span>
<span class="n">pwchecker</span><span class="o">.</span><span class="n">checkPassword</span><span class="p">(</span><span class="s">&#39;amaze*Period&amp;Thirst&#39;</span><span class="p">)</span>
</pre></div>

<p>Output:</p>
<pre><code>'too simple (not enough different kinds of character)'
'too simple (not enough different kinds of character)'
'based on a common sequence of characters'
'too simple (not enough different kinds of character)'
False
</code></pre>]]></content:encoded>
    </item>
    <item>
      <title>Python modules you should know: SlimIt</title>
      <link>http://www.topdog.za.net/2012/04/30/python-modules-you-should-know:-slimit</link>
      <pubDate>Mon, 30 Apr 2012 07:10:00 SAST</pubDate>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[PyMYSK]]></category>
      <category><![CDATA[Howto]]></category>
      <guid isPermaLink="true">http://www.topdog.za.net/2012/04/30/python-modules-you-should-know:-slimit</guid>
      <description>Python modules you should know: SlimIt</description>
      <content:encoded><![CDATA[<p>Next in our series of <a href="http://www.topdog.za.net/category/pymysk/"><em>Python modules you should know</em></a>
is SlimIt. I previously <a href="http://www.topdog.za.net/2012/04/29/python-modules-you-should-know:-cssmin/">wrote</a>
about the minification of CSS files, the Slimit package is used for minification of Javascript files.</p>
<h2>Home page</h2>
<ul>
<li><a href="http://slimit.org/">http://slimit.org/</a></li>
</ul>
<h2>Use</h2>
<p>SlimIt is a JavaScript minifier written in Python. It compiles JavaScript into more compact
code so that it downloads and runs faster.</p>
<p>SlimIt also provides a library that includes a JavaScript parser, lexer, pretty printer and
a tree visitor.</p>
<h2>Installation</h2>
<pre><code>pip install slimit
</code></pre>
<h2>Usage</h2>
<p>The package provides a command line interface as well as Python functions.</p>
<h3>Python functions</h3>
<h4>Minify Javascript</h4>
<div class="pygments_murphy"><pre><span class="kn">from</span> <span class="nn">slimit</span> <span class="kn">import</span> <span class="n">minify</span>
<span class="n">minified</span> <span class="o">=</span> <span class="n">minify</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="s">&#39;jquery-1.7.2.js&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">(),</span> <span class="n">mangle</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">mangle_toplevel</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="k">print</span> <span class="n">minified</span>
</pre></div>

<h4>Modify Javascript within Python and beautify it</h4>
<p>This example is taken directly from the documentation. It modifies the counter variable
changing it from <strong>"i"</strong> to <strong>"hello"</strong> and formats it in a more readable style.</p>
<div class="pygments_murphy"><pre><span class="kn">from</span> <span class="nn">slimit.parser</span> <span class="kn">import</span> <span class="n">Parser</span>
<span class="kn">from</span> <span class="nn">slimit.visitors</span> <span class="kn">import</span> <span class="n">nodevisitor</span>
<span class="kn">from</span> <span class="nn">slimit</span> <span class="kn">import</span> <span class="n">ast</span>

<span class="n">parser</span> <span class="o">=</span> <span class="n">Parser</span><span class="p">()</span>
<span class="n">tree</span> <span class="o">=</span> <span class="n">parser</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="s">&#39;for(var i=0; i&lt;10; i++) {var x=5+i;}&#39;</span><span class="p">)</span>
<span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="n">nodevisitor</span><span class="o">.</span><span class="n">visit</span><span class="p">(</span><span class="n">tree</span><span class="p">):</span>
    <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">ast</span><span class="o">.</span><span class="n">Identifier</span><span class="p">)</span> <span class="ow">and</span> <span class="n">node</span><span class="o">.</span><span class="n">value</span> <span class="o">==</span> <span class="s">&#39;i&#39;</span><span class="p">:</span>
        <span class="n">node</span><span class="o">.</span><span class="n">value</span> <span class="o">=</span> <span class="s">&#39;hello&#39;</span>
<span class="k">print</span> <span class="n">tree</span><span class="o">.</span><span class="n">to_ecma</span><span class="p">()</span>
</pre></div>

<p>Output:</p>
<pre><code>for (var hello = 0; hello &lt; 10; hello++) {
  var x = 5 + hello;
}
</code></pre>
<h3>Command line</h3>
<pre><code>slimit --mangle &lt; jquery-1.7.2.js &gt; jquery-1.7.2.slimit.default.js
</code></pre>
<h4>Performance</h4>
<p>The performance is very good, most times it creates smaller files than the <a href="http://developer.yahoo.com/yui/compressor/">YUI compresser</a>.
I tested minifying Jquery using 3 javascript minification tools:</p>
<ul>
<li>jsmin</li>
<li>yuicompressor</li>
<li>slimit</li>
</ul>
<p>The results are below.</p>
<pre><code>-rw-r--r--  1 andrew  staff   247K Mar 21 21:46 jquery-1.7.2.js
-rw-r--r--  1 andrew  staff   138K Apr 30 08:26 jquery-1.7.2.jsmin.js
-rw-r--r--  1 andrew  staff    96K Apr 30 08:22 jquery-1.7.2.slimit.js
-rw-r--r--  1 andrew  staff   103K Apr 30 08:19 jquery-1.7.2.yui.js
</code></pre>
<h2>And there is more</h2>
<p>Slimit also exposes JavaScript <a href="https://en.wikipedia.org/wiki/Parser">parser</a> and
<a href="https://en.wikipedia.org/wiki/Lexical_analysis">lexer</a> functions which you can use within your code,
please refer to the <a href="http://slimit.readthedocs.org/en/latest/index.html#using-lexer-in-your-project">documentation</a> for usage information.</p>]]></content:encoded>
    </item>
    <item>
      <title>Python modules you should know: cssmin</title>
      <link>http://www.topdog.za.net/2012/04/29/python-modules-you-should-know:-cssmin</link>
      <pubDate>Sun, 29 Apr 2012 14:10:00 SAST</pubDate>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[PyMYSK]]></category>
      <category><![CDATA[Howto]]></category>
      <guid isPermaLink="true">http://www.topdog.za.net/2012/04/29/python-modules-you-should-know:-cssmin</guid>
      <description>Python modules you should know: cssmin</description>
      <content:encoded><![CDATA[<p>Next in our series of <a href="http://www.topdog.za.net/category/pymysk/"><em>Python modules you should know</em></a>
is cssmin. <a href="https://en.wikipedia.org/wiki/Minification_%28programming%29">Minification</a> has recently
gained prominence in the web 2.0 world due to the need to optimize web application performance.</p>
<p>The cssmin package is used to minify css files.</p>
<h2>Home page</h2>
<ul>
<li><a href="https://github.com/zacharyvoase/cssmin">https://github.com/zacharyvoase/cssmin</a></li>
</ul>
<h2>Use</h2>
<p>cssmin is a Python port of the <a href="http://developer.yahoo.com/yui/compressor/">YUI CSS Compressor</a>.
It is used to minify css files, which helps improve web application performance by reducing page
load times.</p>
<h2>Installation</h2>
<pre><code>pip install cssmin
</code></pre>
<h2>Usage</h2>
<p>The package provides a command line interface as well as Python functions.</p>
<h3>Python function</h3>
<div class="pygments_murphy"><pre><span class="kn">import</span> <span class="nn">cssmin</span>
<span class="n">minified</span> <span class="o">=</span> <span class="n">cssmin</span><span class="o">.</span><span class="n">cssmin</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="s">&#39;style.css&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
<span class="k">print</span> <span class="n">minified</span>
</pre></div>

<h3>Commandline</h3>
<pre><code>cssmin --wrap 1000 &lt; style.css &gt; style.min.css
</code></pre>
<p>Thats it, nice and sweet.</p>]]></content:encoded>
    </item>
  </channel>
</rss>
