<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>AlferSoft Blog &#187; Software Development</title>
	<atom:link href="http://www.alfersoft.com.ar/blog/category/dev/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.alfersoft.com.ar/blog</link>
	<description>Explaining this blog in a few words since 1999</description>
	<lastBuildDate>Sun, 29 Aug 2010 13:55:53 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Firefox add-on: UploadProgress</title>
		<link>http://www.alfersoft.com.ar/blog/2010/08/26/firefox-add-on-uploadprogress/</link>
		<comments>http://www.alfersoft.com.ar/blog/2010/08/26/firefox-add-on-uploadprogress/#comments</comments>
		<pubDate>Thu, 26 Aug 2010 22:37:48 +0000</pubDate>
		<dc:creator>fvicente</dc:creator>
				<category><![CDATA[Software Applications]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[add-on]]></category>
		<category><![CDATA[component]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[meter]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[progress]]></category>
		<category><![CDATA[upload]]></category>

		<guid isPermaLink="false">http://www.alfersoft.com.ar/blog/?p=145</guid>
		<description><![CDATA[This Firefox add-on adds a new option to the Tools menu called &#8220;Uploads&#8221; that displays a small window, similar to the downloads, but displaying only current uploads in progress. The uploads are automatically removed from the window after they finish. The idea is to have a way to know the progress of your file uploads [...]]]></description>
			<content:encoded><![CDATA[<p><img alt="UploadProgress add-on" src="http://www.alfersoft.com.ar/files/upload.png" title="UploadProgress add-on" class="alignleft" width="200" height="136" /> This Firefox add-on adds a new option to the Tools menu called &#8220;Uploads&#8221; that displays a small window, similar to the downloads, but displaying only current uploads in progress. The uploads are automatically removed from the window after they finish. The idea is to have a way to know the progress of your file uploads and an estimated remaining time to finish.</p>
<p>Useful for sites that does not shows the upload progress like youtube.</p>
<p>This is my first add-on, so if you find something wrong please let me know.<br />
I&#8217;ve submitted it to <a href="https://addons.mozilla.org/en-US/firefox/addon/221510/">AMO</a> but since it takes time to get released to the general public, I&#8217;ve decided to put it here in our blog if you want to give it a try.</p>
<p><a href="http://www.alfersoft.com.ar/files/uploadprogress.xpi">Download it here</a>, enjoy!</p>
<p><span id="more-145"></span><br />
Tested in Linux, MacOS X and Windows, this small add-on is 100% JavaScript, no dlls no native XPCOMs. I&#8217;ve read in some forums that once upon a time (2004) Firefox already included an upload progress indicator but since then till today is broken. Today other modern browsers like Chrome already provides an upload percent indicator.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.alfersoft.com.ar/blog/2010/08/26/firefox-add-on-uploadprogress/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to create two wired virtual serial ports on Linux?</title>
		<link>http://www.alfersoft.com.ar/blog/2010/02/19/how-to-create-two-wired-virtual-serial-ports-on-linux/</link>
		<comments>http://www.alfersoft.com.ar/blog/2010/02/19/how-to-create-two-wired-virtual-serial-ports-on-linux/#comments</comments>
		<pubDate>Fri, 19 Feb 2010 18:18:32 +0000</pubDate>
		<dc:creator>fvicente</dc:creator>
				<category><![CDATA[Linux FAQ]]></category>
		<category><![CDATA[Programming FAQ]]></category>
		<category><![CDATA[bridged]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[null-modem]]></category>
		<category><![CDATA[port]]></category>
		<category><![CDATA[rs-232]]></category>
		<category><![CDATA[serial]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[virtual]]></category>
		<category><![CDATA[wired]]></category>

		<guid isPermaLink="false">http://www.alfersoft.com.ar/blog/?p=134</guid>
		<description><![CDATA[To create two bridged virtual serial ports use the following command: socat -d -d pty,raw,echo=0 pty,raw,echo=0 The output will show you which are the virtual ports (or pseudo terminals) created, e.g.: 2010/02/19 16:16:33 socat[9662] N PTY is /dev/pts/3 2010/02/19 16:16:33 socat[9662] N PTY is /dev/pts/4 2010/02/19 16:16:33 socat[9662] N starting data transfer loop with FDs [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignnone" title="FAQ" src="http://www.alfersoft.com.ar/files/question.png" alt="" width="48" height="48" /></p>
<p>To create two bridged virtual serial ports use the following command:<br />
<code><br />
socat -d -d pty,raw,echo=0 pty,raw,echo=0<br />
</code></p>
<p>The output will show you which are the virtual ports (or pseudo terminals) created, e.g.:<br />
<code><br />
2010/02/19 16:16:33 socat[9662] N PTY is /dev/pts/3<br />
2010/02/19 16:16:33 socat[9662] N PTY is /dev/pts/4<br />
2010/02/19 16:16:33 socat[9662] N starting data transfer loop with FDs [3,3] and [5,5]<br />
</code></p>
<p>Note: if you are using Ubuntu and you do not have this command, try:<br />
<code><br />
sudo apt-get install socat<br />
</code></p>
<h6><a title="Lock" href="http://commons.wikimedia.org/wiki/File:Gnome-dialog-question.svg" target="_blank">Image source</a></h6>
]]></content:encoded>
			<wfw:commentRss>http://www.alfersoft.com.ar/blog/2010/02/19/how-to-create-two-wired-virtual-serial-ports-on-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How do I compare two binary files on Linux?</title>
		<link>http://www.alfersoft.com.ar/blog/2010/02/19/how-do-i-compare-two-binary-files-on-linux/</link>
		<comments>http://www.alfersoft.com.ar/blog/2010/02/19/how-do-i-compare-two-binary-files-on-linux/#comments</comments>
		<pubDate>Fri, 19 Feb 2010 17:51:00 +0000</pubDate>
		<dc:creator>fvicente</dc:creator>
				<category><![CDATA[Linux FAQ]]></category>
		<category><![CDATA[Programming FAQ]]></category>
		<category><![CDATA[binaries]]></category>
		<category><![CDATA[binary]]></category>
		<category><![CDATA[compare]]></category>
		<category><![CDATA[diff]]></category>
		<category><![CDATA[hexdump]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[meld]]></category>

		<guid isPermaLink="false">http://www.alfersoft.com.ar/blog/?p=128</guid>
		<description><![CDATA[The easiest way I found is dumping the binaries into text files using hexdump and then comparing them with your favourite program (diff, Meld, etc.). E.g.: hexdump -C a.bin >a.txt hexdump -C b.bin >b.txt diff a.txt b.txt Image source]]></description>
			<content:encoded><![CDATA[<p><img class="alignnone" title="FAQ" src="http://www.alfersoft.com.ar/files/question.png" alt="" width="48" height="48" /></p>
<p>The easiest way I found is dumping the binaries into text files using hexdump and then comparing them with your favourite program (diff, Meld, etc.). E.g.:<br />
<code><br />
hexdump -C a.bin >a.txt<br />
hexdump -C b.bin >b.txt<br />
diff a.txt b.txt<br />
</code></p>
<h6><a title="Lock" href="http://commons.wikimedia.org/wiki/File:Gnome-dialog-question.svg" target="_blank">Image source</a></h6>
]]></content:encoded>
			<wfw:commentRss>http://www.alfersoft.com.ar/blog/2010/02/19/how-do-i-compare-two-binary-files-on-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Extracting FLV meta tags with Python</title>
		<link>http://www.alfersoft.com.ar/blog/2010/02/05/extracting-flv-meta-tags-with-python/</link>
		<comments>http://www.alfersoft.com.ar/blog/2010/02/05/extracting-flv-meta-tags-with-python/#comments</comments>
		<pubDate>Sat, 06 Feb 2010 00:07:36 +0000</pubDate>
		<dc:creator>fvicente</dc:creator>
				<category><![CDATA[Programming FAQ]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[flv]]></category>
		<category><![CDATA[metadata]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://www.alfersoft.com.ar/blog/?p=112</guid>
		<description><![CDATA[I&#8217;ve stolen this code from http://code.activestate.com/recipes/457406/ which in turn was stolen / ported from http://inlet-media.de/flvtool2 , made some small fixes in bugs related to the date conversion function, object and array unmarshaling, file name hardcoded, etc&#8230; If you want to learn more about the FLV format and metatags read Acrobat&#8217;s Video File Format Specification Version [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve stolen this code from <a href="http://code.activestate.com/recipes/457406/" target="_blank">http://code.activestate.com/recipes/457406/</a> which in turn was stolen / ported from <a rel="nofollow" href="http://inlet-media.de/flvtool2">http://inlet-media.de/flvtool2 </a>, made some small fixes in bugs related to the date conversion function, object and array unmarshaling, file name hardcoded, etc&#8230; If you want to learn more about the FLV format and metatags read Acrobat&#8217;s <a title="Video File Format Specification Version 10" href="http://www.adobe.com/devnet/flv/pdf/video_file_format_spec_v10.pdf" target="_blank">Video File Format Specification Version 10</a><br />
<span id="more-112"></span></p>
<pre class="brush: python;">
from struct import unpack
from datetime import datetime

class FLVReader(dict):
    &quot;&quot;&quot;
    Reads metadata from FLV files
    &quot;&quot;&quot;

    # Tag types
    AUDIO = 8
    VIDEO = 9
    META = 18
    UNDEFINED = 0

    def __init__(self, filename):
        &quot;&quot;&quot;
        Pass the filename of an flv file and it will return a dictionary of meta
        data.
        &quot;&quot;&quot;
        # Lock on to the file
        self.file = open(filename, 'rb')
        self.signature = self.file.read(3)
        assert self.signature == 'FLV', 'Not an flv file'
        self.version = self.readbyte()
        self.typeFlags = self.readbyte()
        self.dataOffset = self.readint()
        extraDataLen = self.dataOffset - self.file.tell()
        self.extraData = self.file.read(extraDataLen)
        self.readtag()

    def readtag(self):
        unknown = self.readint()
        tagType = self.readbyte()
        dataSize = self.read24bit()
        timeStamp = self.read24bit()
        unknown = self.readint()
        if tagType == self.AUDIO:
            print &quot;Can't handle audio tags yet&quot;
        elif tagType == self.VIDEO:
            print &quot;Can't handle video tags yet&quot;
        elif tagType == self.META:
            endpos = self.file.tell() + dataSize
            self.event = self.readAMFData()
            metaData = self.readAMFData()
            # We got the meta data.
            # Our job is done.
            # We are complete
            self.update(metaData)
        elif tagType == self.UNDEFINED:
            print &quot;Can't handle undefined tags yet&quot;

    def readint(self):
      data = self.file.read(4)
      return unpack('&gt;I', data)[0]

    def readshort(self):
      data = self.file.read(2)
      return unpack('&gt;H', data)[0]

    def readbyte(self):
      data = self.file.read(1)
      return unpack('B', data)[0]

    def read24bit(self):
      b1, b2, b3 = unpack('3B', self.file.read(3))
      return (b1 &lt;&lt; 16) + (b2 &lt;&lt; 8 ) + b3

    def readAMFData(self, dataType=None):
        if dataType is None:
            dataType = self.readbyte()
        funcs = {
            0: self.readAMFDouble,
            1: self.readAMFBoolean,
            2: self.readAMFString,
            3: self.readAMFObject,
            8: self.readAMFMixedArray,
           10: self.readAMFArray,
           11: self.readAMFDate
        }
        func = funcs[dataType]
        if callable(func):
            return func()

    def readAMFDouble(self):
        return unpack('&gt;d', self.file.read(8))[0]

    def readAMFBoolean(self):
        return self.readbyte() == 1

    def readAMFString(self):
        size = self.readshort()
        return self.file.read(size)

    def readAMFObject(self):
        result = {}
        data = True
        while data:
            size = self.readshort()
            key = self.file.read(size)
            dataType = self.readbyte()
            if not key and dataType == 9:
                break
            data = self.readAMFData(dataType)
            result[key] = data
        return result

    def readAMFMixedArray(self):
        size = self.readint()
        result = {}
        i = 0
        while i &lt; size:
            key = self.readAMFString()
            dataType = self.readbyte()
            if not key and dataType == 9:
                break
            result[key] = self.readAMFData(dataType)
            i += 1
        return result

    def readAMFArray(self):
        size = self.readint()
        result = []
        i = 0
        while i &lt; size:
            result.append(self.readAMFData())
            i += 1
        return result

    def readAMFDate(self):
        date = self.readAMFDouble()/1000
        localoffset = self.readshort()
        return datetime.fromtimestamp(date)

if __name__ == '__main__':
    import sys
    from pprint import pprint
    if len(sys.argv) == 1:
        print 'Usage: %s filename [filename]...' % sys.argv[0]
        print 'Where filename is a .flv file'
        print 'eg. %s myfile.flv' % sys.argv[0]
    for fn in sys.argv[1:]:
        x = FLVReader(fn)
        pprint(x)
</pre>
<p>Download this code snippet from <a title="flv.py" href="http://www.alfersoft.com.ar/files/flv.py" target="_blank">here</a></p>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 55px; width: 1px; height: 1px;">from&amp;nbsp;struct&amp;nbsp;import&amp;nbsp;unpack<br />
from&amp;nbsp;datetime&amp;nbsp;import&amp;nbsp;datetime</p>
<p>class&amp;nbsp;FLVReader(dict):<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&#8221;"&#8221;<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Reads&amp;nbsp;metadata&amp;nbsp;from&amp;nbsp;FLV&amp;nbsp;files<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&#8221;"&#8221;</p>
<p>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;Tag&amp;nbsp;types<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;AUDIO&amp;nbsp;=&amp;nbsp;8<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;VIDEO&amp;nbsp;=&amp;nbsp;9<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;META&amp;nbsp;=&amp;nbsp;18<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;UNDEFINED&amp;nbsp;=&amp;nbsp;0</p>
<p>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self,&amp;nbsp;filename):<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&#8221;"&#8221;<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Pass&amp;nbsp;the&amp;nbsp;filename&amp;nbsp;of&amp;nbsp;an&amp;nbsp;flv&amp;nbsp;file&amp;nbsp;and&amp;nbsp;it&amp;nbsp;will&amp;nbsp;return&amp;nbsp;a&amp;nbsp;dictionary&amp;nbsp;of&amp;nbsp;meta<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;data.<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&#8221;"&#8221;<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;Lock&amp;nbsp;on&amp;nbsp;to&amp;nbsp;the&amp;nbsp;file<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.file&amp;nbsp;=&amp;nbsp;open(filename,&amp;nbsp;&#8217;rb&#8217;)<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.signature&amp;nbsp;=&amp;nbsp;self.file.read(3)<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;assert&amp;nbsp;self.signature&amp;nbsp;==&amp;nbsp;&#8217;FLV&#8217;,&amp;nbsp;&#8217;Not&amp;nbsp;an&amp;nbsp;flv&amp;nbsp;file&#8217;<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.version&amp;nbsp;=&amp;nbsp;self.readbyte()<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.typeFlags&amp;nbsp;=&amp;nbsp;self.readbyte()<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.dataOffset&amp;nbsp;=&amp;nbsp;self.readint()<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;extraDataLen&amp;nbsp;=&amp;nbsp;self.dataOffset&amp;nbsp;-&amp;nbsp;self.file.tell()<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.extraData&amp;nbsp;=&amp;nbsp;self.file.read(extraDataLen)<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.readtag()</p>
<p>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;readtag(self):<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;unknown&amp;nbsp;=&amp;nbsp;self.readint()<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;tagType&amp;nbsp;=&amp;nbsp;self.readbyte()<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dataSize&amp;nbsp;=&amp;nbsp;self.read24bit()<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;timeStamp&amp;nbsp;=&amp;nbsp;self.read24bit()<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;unknown&amp;nbsp;=&amp;nbsp;self.readint()<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;tagType&amp;nbsp;==&amp;nbsp;self.AUDIO:<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print&amp;nbsp;&#8221;Can&#8217;t&amp;nbsp;handle&amp;nbsp;audio&amp;nbsp;tags&amp;nbsp;yet&#8221;<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;elif&amp;nbsp;tagType&amp;nbsp;==&amp;nbsp;self.VIDEO:<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print&amp;nbsp;&#8221;Can&#8217;t&amp;nbsp;handle&amp;nbsp;video&amp;nbsp;tags&amp;nbsp;yet&#8221;<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;elif&amp;nbsp;tagType&amp;nbsp;==&amp;nbsp;self.META:<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;endpos&amp;nbsp;=&amp;nbsp;self.file.tell()&amp;nbsp;+&amp;nbsp;dataSize<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.event&amp;nbsp;=&amp;nbsp;self.readAMFData()<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;metaData&amp;nbsp;=&amp;nbsp;self.readAMFData()<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;We&amp;nbsp;got&amp;nbsp;the&amp;nbsp;meta&amp;nbsp;data.<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;Our&amp;nbsp;job&amp;nbsp;is&amp;nbsp;done.<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;We&amp;nbsp;are&amp;nbsp;complete<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.update(metaData)<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;elif&amp;nbsp;tagType&amp;nbsp;==&amp;nbsp;self.UNDEFINED:<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print&amp;nbsp;&#8221;Can&#8217;t&amp;nbsp;handle&amp;nbsp;undefined&amp;nbsp;tags&amp;nbsp;yet&#8221;</p>
<p>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;readint(self):<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;data&amp;nbsp;=&amp;nbsp;self.file.read(4)<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;unpack(&#8216;&gt;I&#8217;,&amp;nbsp;data)[0]</p>
<p>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;readshort(self):<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;data&amp;nbsp;=&amp;nbsp;self.file.read(2)<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;unpack(&#8216;&gt;H&#8217;,&amp;nbsp;data)[0]</p>
<p>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;readbyte(self):<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;data&amp;nbsp;=&amp;nbsp;self.file.read(1)<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;unpack(&#8216;B&#8217;,&amp;nbsp;data)[0]</p>
<p>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;read24bit(self):<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;b1,&amp;nbsp;b2,&amp;nbsp;b3&amp;nbsp;=&amp;nbsp;unpack(&#8217;3B&#8217;,&amp;nbsp;self.file.read(3))<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;(b1&amp;nbsp;&lt;&lt;&amp;nbsp;16)&amp;nbsp;+&amp;nbsp;(b2&amp;nbsp;&lt;&lt;&amp;nbsp;8)&amp;nbsp;+&amp;nbsp;b3</p>
<p>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;readAMFData(self,&amp;nbsp;dataType=None):<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;dataType&amp;nbsp;is&amp;nbsp;None:<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dataType&amp;nbsp;=&amp;nbsp;self.readbyte()<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;funcs&amp;nbsp;=&amp;nbsp;{<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0:&amp;nbsp;self.readAMFDouble,<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1:&amp;nbsp;self.readAMFBoolean,<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2:&amp;nbsp;self.readAMFString,<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;3:&amp;nbsp;self.readAMFObject,<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;8:&amp;nbsp;self.readAMFMixedArray,<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;10:&amp;nbsp;self.readAMFArray,<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;11:&amp;nbsp;self.readAMFDate<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;func&amp;nbsp;=&amp;nbsp;funcs[dataType]<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;callable(func):<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;func()</p>
<p>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;readAMFDouble(self):<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;unpack(&#8216;&gt;d&#8217;,&amp;nbsp;self.file.read(8))[0]</p>
<p>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;readAMFBoolean(self):<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;self.readbyte()&amp;nbsp;==&amp;nbsp;1</p>
<p>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;readAMFString(self):<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;size&amp;nbsp;=&amp;nbsp;self.readshort()<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;self.file.read(size)</p>
<p>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;readAMFObject(self):<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result&amp;nbsp;=&amp;nbsp;{}<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;data&amp;nbsp;=&amp;nbsp;True<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;while&amp;nbsp;data:<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;size&amp;nbsp;=&amp;nbsp;self.readshort()<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;key&amp;nbsp;=&amp;nbsp;self.file.read(size)<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dataType&amp;nbsp;=&amp;nbsp;self.readbyte()<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;not&amp;nbsp;key&amp;nbsp;and&amp;nbsp;dataType&amp;nbsp;==&amp;nbsp;9:<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;data&amp;nbsp;=&amp;nbsp;self.readAMFData(dataType)<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result[key]&amp;nbsp;=&amp;nbsp;data<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;result</p>
<p>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;readAMFMixedArray(self):<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;size&amp;nbsp;=&amp;nbsp;self.readint()<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result&amp;nbsp;=&amp;nbsp;{}<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;i&amp;nbsp;=&amp;nbsp;0<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;while&amp;nbsp;i&amp;nbsp;&lt;&amp;nbsp;size:<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;key&amp;nbsp;=&amp;nbsp;self.readAMFString()<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dataType&amp;nbsp;=&amp;nbsp;self.readbyte()<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;not&amp;nbsp;key&amp;nbsp;and&amp;nbsp;dataType&amp;nbsp;==&amp;nbsp;9:<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result[key]&amp;nbsp;=&amp;nbsp;self.readAMFData(dataType)<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;i&amp;nbsp;+=&amp;nbsp;1<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;result</p>
<p>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;readAMFArray(self):<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;size&amp;nbsp;=&amp;nbsp;self.readint()<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result&amp;nbsp;=&amp;nbsp;[]<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;i&amp;nbsp;=&amp;nbsp;0<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;while&amp;nbsp;i&amp;nbsp;&lt;&amp;nbsp;size:<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result.append(self.readAMFData())<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;i&amp;nbsp;+=&amp;nbsp;1<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;result</p>
<p>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;readAMFDate(self):<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;date&amp;nbsp;=&amp;nbsp;self.readAMFDouble()/1000<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;localoffset&amp;nbsp;=&amp;nbsp;self.readshort()<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;datetime.fromtimestamp(date)</p>
<p>if&amp;nbsp;__name__&amp;nbsp;==&amp;nbsp;&#8217;__main__&#8217;:<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;import&amp;nbsp;sys<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;from&amp;nbsp;pprint&amp;nbsp;import&amp;nbsp;pprint<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;len(sys.argv)&amp;nbsp;==&amp;nbsp;1:<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print&amp;nbsp;&#8217;Usage:&amp;nbsp;%s&amp;nbsp;filename&amp;nbsp;[filename]&#8230;&#8217;&amp;nbsp;%&amp;nbsp;sys.argv[0]<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print&amp;nbsp;&#8217;Where&amp;nbsp;filename&amp;nbsp;is&amp;nbsp;a&amp;nbsp;.flv&amp;nbsp;file&#8217;<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print&amp;nbsp;&#8217;eg.&amp;nbsp;%s&amp;nbsp;myfile.flv&#8217;&amp;nbsp;%&amp;nbsp;sys.argv[0]<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;fn&amp;nbsp;in&amp;nbsp;sys.argv[1:]:<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;x&amp;nbsp;=&amp;nbsp;FLVReader(fn)<br />
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pprint(x)</p></div>
]]></content:encoded>
			<wfw:commentRss>http://www.alfersoft.com.ar/blog/2010/02/05/extracting-flv-meta-tags-with-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>(HTML) Table cell not inheriting style</title>
		<link>http://www.alfersoft.com.ar/blog/2009/06/04/html-table-cell-not-inheriting-style/</link>
		<comments>http://www.alfersoft.com.ar/blog/2009/06/04/html-table-cell-not-inheriting-style/#comments</comments>
		<pubDate>Fri, 05 Jun 2009 00:24:27 +0000</pubDate>
		<dc:creator>fvicente</dc:creator>
				<category><![CDATA[Programming FAQ]]></category>

		<guid isPermaLink="false">http://www.alfersoft.com.ar/blog/?p=108</guid>
		<description><![CDATA[The goal of this new blog category called &#8220;Programming FAQ&#8221; is to publish short posts with day to day programming problems and their solutions, or at least provide a tip to find the proper solution to your problem. And today we start with this simple and stupid problem that can happen to anyone with poor [...]]]></description>
			<content:encoded><![CDATA[<p>The goal of this new blog category called &#8220;Programming FAQ&#8221; is to publish short posts with day to day programming problems and their solutions, or at least provide a tip to find the proper solution to your problem. And today we start with this simple and stupid problem that can happen to anyone with poor HTML experience like me. &#8220;My HTML table does not seems to inherit the style from a parent element&#8221;, here is the example:</p>
<pre>&lt;html&gt;
&lt;body&gt;
&lt;div style="color: blue;"&gt;
	&lt;table&gt;
	&lt;tbody&gt;
		&lt;tr&gt;
			&lt;td&gt;BLUE TEXT&lt;/td&gt;
		&lt;/tr&gt;
	&lt;/tbody&gt;
	&lt;/table&gt;
&lt;div&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
<p>In the below example I would expect to see the &#8220;BLUE TEXT&#8221; in blue, but is not (at least in FireFox). So what the hell is wrong with my code? probably many things but because I&#8217;m not interested in following/reading the W3C recommendations for my uncle&#8217;s home page, here is one possible solution: Add the transitional DOCTYPE to your document, or the DOCTYPE that adequate better to your page (<a title="W3C DOCTYPE" href="http://www.w3.org/QA/2002/04/valid-dtd-list.html" target="_blank">read more here</a>). E.g.:</p>
<pre>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;</pre>
<p>So, now you know. Never forget the DOCTYPE it is very important&#8230; Why? <a title="Don't forget to add a doctype" href="http://www.w3.org/QA/Tips/Doctype" target="_blank">read this</a>&#8230; It has to do with poor standards, browsers and all that crap.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.alfersoft.com.ar/blog/2009/06/04/html-table-cell-not-inheriting-style/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simplified DES (S-DES) file encryption implementation in C</title>
		<link>http://www.alfersoft.com.ar/blog/2009/05/08/simplified-des-s-des-file-encryption-implementation-in-c/</link>
		<comments>http://www.alfersoft.com.ar/blog/2009/05/08/simplified-des-s-des-file-encryption-implementation-in-c/#comments</comments>
		<pubDate>Fri, 08 May 2009 20:34:11 +0000</pubDate>
		<dc:creator>fvicente</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[C encryption S-DES simplified DES cipher]]></category>

		<guid isPermaLink="false">http://www.alfersoft.com.ar/blog/?p=103</guid>
		<description><![CDATA[This encryption algorithm is not secure at all, in fact it was made for educational purposes. It uses a 10-bit key that can be quickly broken by a brute force attack. But, who knows, it may be good for someone interested in some quick encryption where security is not that important, or for embedded devices [...]]]></description>
			<content:encoded><![CDATA[<div class="wp-caption alignnone" style="width: 138px"><img title="Simplified DES" src="http://www.alfersoft.com.ar/files/lock.png" alt="Simplified DES" width="128" height="128" /><p class="wp-caption-text">Simplified DES</p></div>
<p>This encryption algorithm is not secure at all, in fact it was made for educational purposes. It uses a 10-bit key that can be quickly broken by a brute force attack. But, who knows, it may be good for someone interested in some quick encryption where security is not that important, or for embedded devices were resources are limited, or just for lazy students. <img src='http://www.alfersoft.com.ar/blog/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p><span id="more-103"></span></p>
<p>So, here is my version of the S-DES algorithm in plain C. Differently from the <a title="S-DES cpp implementation" href="http://www.programmersheaven.com/download/47588/download.aspx" target="_blank">other version in the web</a> my implementation is more byte-oriented while the other (probably more didactic) is converting the input to a string with &#8217;0&#8242;s and &#8217;1&#8242;s and working over it. Also the other implementation uses some C++ functions while mine is written in plain C.</p>
<p><a title="Simplified DES C implementation" href="http://www.alfersoft.com.ar/files/sdes/sdes.c" target="_blank">Download it</a> and take a look to the code (it is less than 300 lines) &#8212; released under BSD license.</p>
<p>To build it with gcc type:</p>
<p>gcc sdes.c -lm -o sdes</p>
<p>Note that I&#8217;m using math library only because of the pow() function that is used only in debug mode.</p>
<p>And here is a copy of a <a title="S-DES algorithm PDF" href="http://www.alfersoft.com.ar/files/sdes/sdes.pdf" target="_blank">document explaining the algorithm</a>.</p>
<h6><a title="Lock" href="http://upload.wikimedia.org/wikipedia/commons/f/ff/Crystal_Clear_action_lock.png" target="_blank">Image source</a></h6>
]]></content:encoded>
			<wfw:commentRss>http://www.alfersoft.com.ar/blog/2009/05/08/simplified-des-s-des-file-encryption-implementation-in-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cool JavaScript Tool Window</title>
		<link>http://www.alfersoft.com.ar/blog/2009/03/30/cool-javascript-tool-window/</link>
		<comments>http://www.alfersoft.com.ar/blog/2009/03/30/cool-javascript-tool-window/#comments</comments>
		<pubDate>Tue, 31 Mar 2009 01:40:00 +0000</pubDate>
		<dc:creator>fvicente</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[floating]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[movable]]></category>
		<category><![CDATA[prototype]]></category>
		<category><![CDATA[resizable]]></category>
		<category><![CDATA[scriptaculous]]></category>
		<category><![CDATA[window]]></category>

		<guid isPermaLink="false">http://www.alfersoft.com.ar/blog/?p=17</guid>
		<description><![CDATA[This JavaScript class wraps a given HTML element into a movable and resizable floating tool window.  Required libraries: scriptaculous and prototype.js How to use the code: Download full source (including scriptaculous and prototype). The pieces of code developed by me are released under BSD license, please verify third party libraries licenses before using them. See [...]]]></description>
			<content:encoded><![CDATA[<div class="wp-caption alignnone" style="width: 309px"><img title="Tool Window" src="http://www.alfersoft.com.ar/files/toolwindow.jpg" alt="Tool Window" width="299" height="249" /><p class="wp-caption-text">Tool Window</p></div>
<p>This JavaScript class wraps a given HTML element into a movable and resizable floating tool window.  Required libraries: <a title="Scriptaculous" href="http://script.aculo.us/" target="_blank">scriptaculous</a> and <a title="Prototype" href="http://www.prototypejs.org/" target="_blank">prototype.js</a></p>
<p>How to use the code:</p>
<p>Download <a title="Tool Window Source" href="http://www.alfersoft.com.ar/files/toolwindow.zip" target="_blank">full source</a> (including scriptaculous and prototype). The pieces of code developed by me are released under BSD license, please verify third party libraries licenses before using them.</p>
<p>See the <a title="Tool Window" href="http://www.alfersoft.com.ar/files/toolwindow/index.html" target="_blank">DEMO PAGE!</a></p>
<p>enjoy it!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.alfersoft.com.ar/blog/2009/03/30/cool-javascript-tool-window/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>File Upload Progress with mod_python</title>
		<link>http://www.alfersoft.com.ar/blog/2009/03/28/file-upload-progress-with-mod_python/</link>
		<comments>http://www.alfersoft.com.ar/blog/2009/03/28/file-upload-progress-with-mod_python/#comments</comments>
		<pubDate>Sat, 28 Mar 2009 05:07:42 +0000</pubDate>
		<dc:creator>fvicente</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[files]]></category>
		<category><![CDATA[iframe]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mod_python]]></category>
		<category><![CDATA[progress]]></category>
		<category><![CDATA[progress bar]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[upload]]></category>

		<guid isPermaLink="false">http://www.alfersoft.com.ar/blog/?p=97</guid>
		<description><![CDATA[Now that Gmail has added a progress bar for attachment uploads, everybody wants to do the same including myself So, with the same method that everybody uses consisting in an upload form with a hidden &#60;iframe&#62; as target, and then a periodic Ajax request to update the progress, I made a simple implementation using mod_python [...]]]></description>
			<content:encoded><![CDATA[<div class="wp-caption alignnone" style="width: 451px"><img title="Upload Progress with mod_python" src="http://www.alfersoft.com.ar/files/uprogress.jpg" alt="Upload Progress with mod_python" width="441" height="216" /><p class="wp-caption-text">Upload Progress with mod_python</p></div>
<p>Now that Gmail has added a progress bar for attachment uploads, everybody wants to do the same including myself <img src='http://www.alfersoft.com.ar/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
So, with the same method that everybody uses consisting in an upload form with a hidden  &lt;iframe&gt; as target, and then a periodic Ajax request to update the progress, I made a simple implementation using mod_python on the server side&#8230; This is a veeery simple example, like everything that you do with Python.<br />
Additionally I&#8217;ve added an upload size limit control based in examples that can be found in the mod_python forum site. Use the source Luke!</p>
<p>See <a title="Upload Progress Demo" href="http://www.alfersoft.com.ar/uprogress/" target="_blank">LIVE DEMO!</a></p>
<p><span id="more-97"></span></p>
<h2>Libraries that I used for this example</h2>
<p>The fancy JavaScript progress bar is from <a title="Bramus!" href="http://www.bram.us/" target="_blank">Bramus</a>, I just changed the default options, renamed the main script file to progressbar.js and the images just because I like everything in lower case. See the copyright inside the file or visit the site for more information.</p>
<p><a title="Prototype.js" href="http://www.prototypejs.org/" target="_blank">Prototype.js</a>: this well known library to avoid cross-browser compatibility issues, is small and practical. I use it in almost all my web projects. Also Bramus requires this library. If you don&#8217;t like it for some reason you will need to replace many many many functions like $() which is an improved getElementById(), or the Hash class that I use to track in-progress uploads, JSON encoding, etc. etc. You don&#8217;t want to remove it, seriously.</p>
<p><a title="simplejson" href="http://code.google.com/p/simplejson/" target="_blank">simplejson</a>: A python library to encode/decode JSON objects. I use this one for the messaging between the server and the page. In my opinion JSON is more efficient than XML because it generates more compact and still human-readable outputs. But you can use XML or any other method by modifying the example as you like.</p>
<h2>Download example</h2>
<p>Start by downloading the <a title="Source code for uprogress example" href="http://www.alfersoft.com.ar/files/uprogress.zip" target="_blank">source code for this example</a>. I decided to release the code under BSD license, so you can use it for whatever you want.</p>
<p>The source is organized like the following illustration:</p>
<div class="wp-caption alignnone" style="width: 382px"><img title="Upload Progress source directory structure" src="http://www.alfersoft.com.ar/files/uprogress_src.jpg" alt="Upload Progress source directory structure" width="372" height="360" /><p class="wp-caption-text">Upload Progress source directory structure</p></div>
<p>/src/img: contains images for JavaScript Bramus progress bar</p>
<p>/src/js: contains JavaScript libraries Prototype.js and Bramus progress bar that I renamed to progressbar.js</p>
<p>/src/temp: directory where the uploaded files will be stored. IMPORTANT: in unix like environments the group and permission of this folder must be configured properly in order to Apache to have write access on it.</p>
<p>/src/_upload_limit.py: mod_python fixup handler that controls the file upload size limit, verifies if the file already exist in the server, stores file size and location information on the session and does the actual file upload after all the verifications.</p>
<p>/src/index.py: The main python publisher handler. Exposed URLs are the main / &#8220;index&#8221; page that loads the test.html and /get_upload_progress function that returns the current % progress of the files being uploaded.</p>
<p>/src/test.html: HTML page that contains all the JavaScript code used to create the upload forms, post the files, track the progress via Ajax, update the progress bar status, etc&#8230; This file is parsed by index.py as a PSP but does not contains any embedded python code currently.</p>
<p>/lib/simplejson: simplejson python library to encode / decode JSON messages.</p>
<h2>Configuring Apache</h2>
<p>I&#8217;m assuming that you already have mod_python installed on your Apache. Take a look to the sample configuration:</p>
<pre>Alias / "/Users/fvicente/workspace/uprogress/src/"
&lt;Directory "/Users/fvicente/workspace/uprogress/src/"&gt;
    SetHandler python-program
    PythonHandler mod_python.publisher
    PythonDebug On
    PythonFixupHandler _upload_limit
    &lt;Files ~ "\.(gif|jpg|png|ico|js|css)$"&gt;
        SetHandler default-handler
    &lt;/Files&gt;
    Order allow,deny
    Allow from all
&lt;/Directory&gt;</pre>
<p>mod_python manual has a lot of information about the configuration options, so I&#8217;m not going to describe this in too much depth, just remark that I&#8217;m using the very useful mod_python publisher, and more &#8220;unusual&#8221; option PythonFixupHandler pointing to the _upload_limit.py file.</p>
<h2>Interesting parts of the code</h2>
<p>_upload_limit.py</p>
<p>The fixuphandler function contained in this file does the checking for the size limit of the file being uploaded by reading the http header Content-Length sent by the browser  allowing you to reject an upload even before starting the actual transfer&#8230; very clever!. I found _upload_limit.py <a title="mod_python forum example" href="http://www.modpython.org/pipermail/mod_python/2007-February/023158.html" target="_blank">example in the mod_python forum</a>, and used it as a based adding the specific code for the upload progress handling. _upload_limit.py also stores the file size and name in the current session to be used later by the get_upload_progress function defined in index.py. Note that every time that the Session is used it will be accessed with the option lock=False thus using the session.lock() and session.unlock() methods manually when necessary, if you don&#8217;t do this that way all the parallel requests will be held until the upload finishes making impossible to monitor the progress via parallel Ajax request.</p>
<p>index.py</p>
<p>The exposed function get_upload_progress calculates the current upload percent by making a file-stat to see how much of the file has been stored so far. It is requested by the page test.html via Ajax in intervals of one seconds while the file is being uploaded. The expected parameter is a dictionary where the keys are &#8220;upload slots&#8221; that the JavaScript generates and understand, and the values are the name of the files to get the upload percent.</p>
<p>test.html</p>
<p>This one is 90% JavaScript code. But is not so bad, only 100 lines of code. In a very brief description you will see 4 functions:</p>
<p>addUploadSlot(): creates an HTML code dynamically with an &#8220;upload slot&#8221; which is a form with the file to upload, the hidden &lt;iframe&gt; that is the form target, the progress bar control, and the &#8220;Upload&#8221; button. It uses a global counter called slotCnt to give a unique id to each slot. This id will be the &#8220;key&#8221; in the get_upload_progress dictionary (see index.py description).</p>
<p>sendFile(slot): shows the progress bar for given slot, adds the file into a global Hash() table called &#8220;uploading&#8221;, starts the periodic Ajax progress monitor (I used JavaScript function setInterval() to do the periodic Ajax) and sends the form to the server. Finally it will disable the controls for that slot and add a new slot dynamically for other uploads.</p>
<p>updateProgressBars(): This is the function called by setInterval() while the files are uploading that does the actual Ajax.Request to /get_upload_progress in order to get the % progress for each file. The parameter sent with the request is a dictionary where the keys are the slots Id&#8217;s and the values the file names stored in the hash table.</p>
<p>uploadDone(slot): Will be called by the &lt;iframe&gt; when the upload finishes (successfully or not). Here I remove the file from the hash and stop the interval if no longer necessary.</p>
<h2>Final comments</h2>
<p>Remember that this is just an example and may contain errors. Use it at your own risk, I&#8217;m not responsable of any possible damage or data lost, blah, blah, etc. etc. etc.</p>
<p>The code is poorly commented, but at least is well formatted <img src='http://www.alfersoft.com.ar/blog/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> . I recommend you to read it, it is very short and you may find interesting chunks.</p>
<p>Enjoy it!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.alfersoft.com.ar/blog/2009/03/28/file-upload-progress-with-mod_python/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>MacOS X 10.5.x (Intel) + mod_python + PIL + PyCAPTCHA notes</title>
		<link>http://www.alfersoft.com.ar/blog/2009/03/03/macos-x-105x-intel-mod_python-pil-pycaptcha-notes/</link>
		<comments>http://www.alfersoft.com.ar/blog/2009/03/03/macos-x-105x-intel-mod_python-pil-pycaptcha-notes/#comments</comments>
		<pubDate>Wed, 04 Mar 2009 02:04:10 +0000</pubDate>
		<dc:creator>fvicente</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[freetype2]]></category>
		<category><![CDATA[intel]]></category>
		<category><![CDATA[leopard]]></category>
		<category><![CDATA[libjpeg]]></category>
		<category><![CDATA[macosx]]></category>
		<category><![CDATA[mod_python]]></category>
		<category><![CDATA[pil]]></category>
		<category><![CDATA[pycaptcha]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.alfersoft.com.ar/blog/?p=89</guid>
		<description><![CDATA[If you have a Mac OS X Leopard on an Intel platform, and you are interested in installing mod_python using your default apache setup and the python that comes with the Framework, even more if you want to give PyCAPTCHA a try together with mod_python, then check out this post! I&#8217;m covering also the installation [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignnone" title="Python" src="http://www.alfersoft.com.ar/files/python.jpg" alt="" width="300" height="225" /></p>
<p>If you have a Mac OS X Leopard on an Intel platform, and you are interested in installing mod_python using your default apache setup and the python that comes with the Framework, even more if you want to give PyCAPTCHA a try together with mod_python, then check out this post! I&#8217;m covering also the installation of required libraries for PyCAPTCHA under Leopard (FreeType2, libjpeg, PIL)</p>
<p><span id="more-89"></span></p>
<h2><strong>mod_python</strong></h2>
<p><span style="text-decoration: underline;">Compile mod_python</span></p>
<p>If you have Apple&#8217;s Xcode installed, compiling mod_python for Leopard to use with the system provided versions of httpd, python, etc. should be as simple as running these commands:</p>
<p><code><br />
$ mkdir -p ~/mod_python<br />
$ cd ~/mod_python<br />
$ svn co http://svn.apache.org/repos/asf/quetzalcoatl/mod_python/trunk mod_python-trunk<br />
$ cd mod_python-trunk<br />
$ ./configure --with-apxs=/usr/sbin/apxs<br />
$ make<br />
$ sudo make install<br />
$ cd test/<br />
$ python test.py</code></p>
<p>(original source: http://www.modpython.org/pipermail/mod_python/2008-March/025012.html)</p>
<p><span style="text-decoration: underline;">Configure Apache to load mod_python</span></p>
<p>Open /private/etc/apache2/httpd.conf with your favorite editor and add the following line:</p>
<p><code><br />
LoadModule python_module libexec/apache2/mod_python.so<br />
</code></p>
<p><span style="text-decoration: underline;">Example of how to configure Apache to load a mod_python application</span></p>
<p>This is just an example, I recommend reading the <a title="mod_python manual" href="http://www.modpython.org/live/current/doc-html/" target="_blank">mod_python manual</a> for more information.</p>
<p>Open /private/etc/apache2/users/<em>username</em>.conf with your favorite editor and add:</p>
<pre>Alias / "/Users/<em>username</em>/<em>htdocs</em>/"
&lt;Directory "/Users/<em>username</em>/<em>htdocs</em>/"&gt;
    SetHandler python-program
    PythonHandler mod_python.publisher
    # Disable following line when in production
    PythonDebug On
    &lt;Files ~ "\.(gif|jpg|png|ico|js|css)$"&gt;
        SetHandler default-handler
    &lt;/Files&gt;
    Order allow,deny
    Allow from all
&lt;/Directory&gt;</pre>
<p><span style="text-decoration: underline;">Restart Apache with the command below:</span></p>
<pre>$ /usr/sbin/apachectl restart</pre>
<p><br/></p>
<h2>PyCAPTCHA</h2>
<p>In order to build and install PyCAPTCHA you&#8217;ll need to compile, or make sure that you have these required libraries:</p>
<ul>
<li>FreeType2</li>
<li>libjpeg</li>
<li>PIL (Python Imaging Library)</li>
</ul>
<p>Let&#8217;s see how to set up these libraries under a Leopard / Intel environment.<br />
<br/></p>
<h2>FreeType2</h2>
<p>This library is required for PyCAPTCHA, as far as I know it is already installed with the SDK, to check the directory where the library is installed use the command:</p>
<p><code>$ locate libfreetype.dylib</code></p>
<p>A version of this library should appear under /Developer/SDKs/MacOSX10.5.sdk/usr/X11/<br />
<br/></p>
<h2>libjpeg</h2>
<p>Download <a title="libjpeg" href="http://www.ijg.org/" target="_blank">jpeg source</a> and uncompress it in any directory, e.g. ~/jpeg-6b then:</p>
<p><code><br />
$ cd ~/jpeg-6b<br />
$ chmod -R 777 *<br />
$ ./configure<br />
</code></p>
<p>Edit Makefile and change the following line from:</p>
<pre>    CFLAGS= -O2 -I$(srcdir)</pre>
<p>to:</p>
<pre>    CFLAGS= -arch ppc -arch i386 -arch ppc64 -arch x86_64 -O2 -I$(srcdir)</pre>
<p>Finally, build and install:<br />
<code><br />
$ make<br />
$ sudo make install-lib</code><br />
<br/></p>
<h2>PIL</h2>
<p>Download <a title="PIL source" href="http://www.pythonware.com/products/pil/" target="_blank">PIL source</a> and uncompress it in any directory, e.g. ~/imaging-1.1.6 then:</p>
<p><code><br />
$ cd ~/imaging-1.1.6<br />
</code></p>
<p>Edit setup.py and change the following lines from:</p>
<pre>    FREETYPE_ROOT = None</pre>
<p>to (note that I&#8217;m using the FreeType2 directory discovered previously with the locate command):</p>
<pre>    FREETYPE_ROOT = libinclude("/Developer/SDKs/MacOSX10.5.sdk/usr/X11/")</pre>
<p>and then following line from:</p>
<pre>    JPEG_ROOT = None</pre>
<p>to:</p>
<pre>    JPEG_ROOT = libinclude("/usr/local")</pre>
<p>Locate these lines:<code><br />
from distutils import sysconfig<br />
from distutils.core import Extension, setup<br />
from distutils.command.build_ext import build_ext<br />
</code><br />
And add the following lines (correctly indented from column 0):</p>
<pre>OrigExtension = Extension
def Extension(*args, **kwargs):
    extra_args = ['-arch', 'ppc', '-arch', 'ppc64', '-arch', 'i386', '-arch', 'x86_64']
    kwargs['extra_compile_args'] = extra_args + kwargs.get('extra_compile_args', [])
    kwargs['extra_link_args'] = extra_args + kwargs.get('extra_link_args', [])
    return OrigExtension(*args, **kwargs)</pre>
<p>Now proceed to compile and install the library:<br />
<code><br />
$ sudo python setup.py install</code><br />
<br/></p>
<h2>Install PyCAPTCHA</h2>
<p>Now you are ready to  build and install PyCAPTCHA. Checkout the source code from <a title="PyCAPTCHA" href="http://svn.navi.cx/misc/trunk/pycaptcha/" target="_blank">this link</a> and run the following command:<br />
<code><br />
$ sudo python setup.py install</code></p>
<p>That&#8217;s it!</p>
<h6><a title="Python" href="http://commons.wikimedia.org/wiki/File:Boomslang_(443113819).jpg" target="_blank">image source</a></h6>
]]></content:encoded>
			<wfw:commentRss>http://www.alfersoft.com.ar/blog/2009/03/03/macos-x-105x-intel-mod_python-pil-pycaptcha-notes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Slice and rotate images with CutNRot</title>
		<link>http://www.alfersoft.com.ar/blog/2008/06/04/slice-and-rotate-images-with-cutnrot/</link>
		<comments>http://www.alfersoft.com.ar/blog/2008/06/04/slice-and-rotate-images-with-cutnrot/#comments</comments>
		<pubDate>Wed, 04 Jun 2008 23:24:19 +0000</pubDate>
		<dc:creator>fvicente</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[cut]]></category>
		<category><![CDATA[images]]></category>
		<category><![CDATA[pictures]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[rotate]]></category>
		<category><![CDATA[scanned]]></category>
		<category><![CDATA[wxpython]]></category>

		<guid isPermaLink="false">http://www.alfersoft.com.ar/blog/?p=8</guid>
		<description><![CDATA[Today I&#8217;m introducing another utility script written in python that uses wxPython to edit your scanned images (JPEG, BMP, TIFF, etc.) obtain sub-images, rotate and save them. This first version is very basic but effective, there is no necessity of learning complex commands or image handling programs, just: click in the upper-left corner click in [...]]]></description>
			<content:encoded><![CDATA[<div id="wikicontent" style="padding: 0pt 3em 1.2em 0pt;">
<p><img src="http://www.alfersoft.com.ar/files/cutnrot.jpg" alt="Cut and Rotate" width="400" height="150" /></p>
<p>Today I&#8217;m introducing another utility script written in python that uses wxPython to edit your scanned images (JPEG, BMP, TIFF, etc.) obtain sub-images, rotate and save them.</p>
<p><span id="more-8"></span>This first version is very basic but effective, there is no necessity of learning complex commands or image handling programs, just:</p>
<ul>
<li>click in the upper-left corner</li>
<li>click in the lower-right corner</li>
<li>rotate if you wish</li>
<li>close and save</li>
</ul>
</div>
<div id="wikicontent" style="padding: 0pt 3em 1.2em 0pt;">The unfortunate name of this script is cutnrot <img src='http://www.alfersoft.com.ar/blog/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' />  and it is released under BSD license, download, modify and use it at your own risk, as usual. <a title="Cut And Rotate" href="http://code.google.com/p/cutnrot/" target="_blank">Here is the Google Code page for this tiny project.</a></div>
<div style="padding: 0pt 3em 1.2em 0pt;"><a title="cutnrot Windows Binaries" href="http://cutnrot.googlecode.com/files/cutnrot_win32_bin.zip">Download Windows Binaries</a> generated with <a title="py2exe" href="http://www.py2exe.org/" target="_blank">py2exe</a> for those that does not have a Python interpreter and/or wxPython installed.</div>
]]></content:encoded>
			<wfw:commentRss>http://www.alfersoft.com.ar/blog/2008/06/04/slice-and-rotate-images-with-cutnrot/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
