<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" version="2.0">

<channel>
	<title>Peter Carroll: Software Developer</title>
	
	<link>http://blog.eringal.com</link>
	<description>Like "Ace Ventura: Pet Detective," except not</description>
	<lastBuildDate>Tue, 24 Apr 2012 15:08:04 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/PeterCarrollSoftwareDeveloper" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="petercarrollsoftwaredeveloper" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Anki 2.0, Esperanto, and GitHub</title>
		<link>http://blog.eringal.com/python/anki-2-0-esperanto-and-github/</link>
		<comments>http://blog.eringal.com/python/anki-2-0-esperanto-and-github/#comments</comments>
		<pubDate>Tue, 24 Apr 2012 15:08:04 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://blog.eringal.com/?p=116</guid>
		<description><![CDATA[Recently, I had become aware that Anki 2.0 was in beta through my friend Tom, who is working on making some changes to the MCD Support plugin so that it supports languages like Spanish as well as it does Japanese. Despite this awareness, it never crossed my mind that I might need to update the [...]
Related posts:<ol>
<li><a href='http://blog.eringal.com/python/esperanto-support-plugin-for-anki/' rel='bookmark' title='Esperanto Support Plugin for Anki'>Esperanto Support Plugin for Anki</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Recently, I had become aware that <a href="http://ankisrs.net/">Anki</a> 2.0 was in beta through my friend <a href="http://twitter.com/tummai">Tom</a>, who is working on making some changes to the <a href="https://github.com/thjelm/mcdsupport">MCD Support plugin</a> so that it supports languages like Spanish as well as it does Japanese. Despite this awareness, it never crossed my mind that I might need to update the <a href="http://blog.eringal.com/python/esperanto-support-plugin-for-anki/">Esperanto Support addon</a> that I wrote a couple years ago until I received an email from <a href="http://twitter.com/ankisrs">Damien Elmes</a>, the author of Anki, that it was time to look at doing so.</p>
<p>I decided that this was the perfect opportunity to finally get on GitHub, since this project is very small and would not require a lot of work to move it to its new home. The process of getting setup on GitHub was pretty easy thanks to their excellent documentation.</p>
<p>Also easy was upgrading my code to work with Anki 2.0. Although the code needed significant changes, the <a href="http://ankisrs.net/docs/dev/addons.html">excellent documentation for writing addons for Anki 2.0</a> had everything I needed to know. If this documentation existed for the older version of Anki, I never saw it, so I&#8217;m glad that an obvious effort was put into creating it.</p>
<p>The Esperanto Support addon for Anki 2.0 is available for download from <a href="https://beta.ankiweb.net/shared/info/2096916868">https://beta.ankiweb.net/shared/info/2096916868</a>, or just browse the add-on list within Anki and you will find it. If you want to see the source, it now lives at <a href="https://github.com/peterjcarroll/Esperanto-Anki-Plugin">https://github.com/peterjcarroll/Esperanto-Anki-Plugin</a>.</p>
<p>Related posts:<ol>
<li><a href='http://blog.eringal.com/python/esperanto-support-plugin-for-anki/' rel='bookmark' title='Esperanto Support Plugin for Anki'>Esperanto Support Plugin for Anki</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=cBp_x__VvRk:yLjBfuOlPe8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=cBp_x__VvRk:yLjBfuOlPe8:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?i=cBp_x__VvRk:yLjBfuOlPe8:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=cBp_x__VvRk:yLjBfuOlPe8:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?i=cBp_x__VvRk:yLjBfuOlPe8:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=cBp_x__VvRk:yLjBfuOlPe8:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?i=cBp_x__VvRk:yLjBfuOlPe8:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=cBp_x__VvRk:yLjBfuOlPe8:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=cBp_x__VvRk:yLjBfuOlPe8:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?i=cBp_x__VvRk:yLjBfuOlPe8:gIN9vFwOqvQ" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://blog.eringal.com/python/anki-2-0-esperanto-and-github/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Verifying that an MP3 File is valid in Python</title>
		<link>http://blog.eringal.com/python/verifying-that-an-mp3-file-is-valid-in-python/</link>
		<comments>http://blog.eringal.com/python/verifying-that-an-mp3-file-is-valid-in-python/#comments</comments>
		<pubDate>Fri, 10 Sep 2010 06:09:45 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[mp3]]></category>

		<guid isPermaLink="false">http://blog.eringal.com/?p=102</guid>
		<description><![CDATA[This post is a result of many attempts at trying to find an existing solution, deciding that nothing did what I needed, and writing the code myself. Specifically, I wanted to be able to verify whether or not that a file is a valid MP3 file from Python. I did not want any dependency on [...]
No related posts.]]></description>
			<content:encoded><![CDATA[<p>This post is a result of many attempts at trying to find an existing solution, deciding that nothing did what I needed, and writing the code myself. Specifically, I wanted to be able to verify whether or not that a file is a valid MP3 file from Python. I did not want any dependency on non-Python code (for cross-platform reasons), nor did I need to encode, decode, play, record, or any other such operations to the file. I just needed to know if it was an MP3 or not, and that is all. Oh yeah, and the file will probably have a random file name without the .mp3 extension.</p>
<p>At first, I downloaded several python libraries. The documentation was poor on most of them so I had to experiment to figure out if they did what I needed. All were failures or required something external like ffmpeg. I found library that seemed to check if an    mp3 file was valid, but discovered it only worked if the file was named with the mp3 extension. A closer look at its code revealed that it was just checking the file&#8217;s mime-type based on the file extension. That was useless for me.</p>
<p>So I decided that this was something I needed to do myself. With this <a href="http://www.mpgedit.org/mpgedit/mpeg_format/mpeghdr.htm">mp3 file format specification</a> as a reference, I sat down and wrote the code that follows, which seems to work very well. Basically the code searches for the first valid audio frame, makes sure that the frame&#8217;s header values are sane, and then checks that the second frame seems to start where it should. This code does not decode any audio in those frames.</p>
<p>Here is the code:</p>
<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">def</span> isMp3Valid<span style="color: black;">&#40;</span>file_path<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; is_valid <span style="color: #66cc66;">=</span> <span style="color: #008000;">False</span><br />
<br />
&nbsp; &nbsp; f <span style="color: #66cc66;">=</span> <span style="color: #008000;">open</span><span style="color: black;">&#40;</span>file_path<span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'r'</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; block <span style="color: #66cc66;">=</span> f.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1024</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; frame_start <span style="color: #66cc66;">=</span> block.<span style="color: black;">find</span><span style="color: black;">&#40;</span><span style="color: #008000;">chr</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">255</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; block_count <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">0</span> <span style="color: #808080; font-style: italic;">#abort after 64k</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>block<span style="color: black;">&#41;</span><span style="color: #66cc66;">&gt;</span><span style="color: #ff4500;">0</span> <span style="color: #ff7700;font-weight:bold;">and</span> frame_start <span style="color: #66cc66;">==</span> -<span style="color: #ff4500;">1</span> <span style="color: #ff7700;font-weight:bold;">and</span> block_count<span style="color: #66cc66;">&lt;</span><span style="color: #ff4500;">64</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; block <span style="color: #66cc66;">=</span> f.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1024</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; frame_start <span style="color: #66cc66;">=</span> block.<span style="color: black;">find</span><span style="color: black;">&#40;</span><span style="color: #008000;">chr</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">255</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; block_count+<span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> frame_start <span style="color: #66cc66;">&gt;</span> -<span style="color: #ff4500;">1</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; frame_hdr <span style="color: #66cc66;">=</span> block<span style="color: black;">&#91;</span>frame_start:frame_start+<span style="color: #ff4500;">4</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; is_valid <span style="color: #66cc66;">=</span> frame_hdr<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span> <span style="color: #66cc66;">==</span> <span style="color: #008000;">chr</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">255</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; mpeg_version <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">''</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; layer_desc <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">''</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; uses_crc <span style="color: #66cc66;">=</span> <span style="color: #008000;">False</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; bitrate <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">0</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; sample_rate <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">0</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; padding <span style="color: #66cc66;">=</span> <span style="color: #008000;">False</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; frame_length <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">0</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> is_valid:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; is_valid <span style="color: #66cc66;">=</span> <span style="color: #008000;">ord</span><span style="color: black;">&#40;</span>frame_hdr<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> &amp; <span style="color: #ff4500;">0xe0</span> <span style="color: #66cc66;">==</span> <span style="color: #ff4500;">0xe0</span> <span style="color: #808080; font-style: italic;">#validate the rest of the frame_sync bits exist</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> is_valid:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">ord</span><span style="color: black;">&#40;</span>frame_hdr<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> &amp; <span style="color: #ff4500;">0x18</span> <span style="color: #66cc66;">==</span> <span style="color: #ff4500;">0</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mpeg_version <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'2.5'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">elif</span> <span style="color: #008000;">ord</span><span style="color: black;">&#40;</span>frame_hdr<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> &amp; <span style="color: #ff4500;">0x18</span> <span style="color: #66cc66;">==</span> <span style="color: #ff4500;">0x10</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mpeg_version <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'2'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">elif</span> <span style="color: #008000;">ord</span><span style="color: black;">&#40;</span>frame_hdr<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> &amp; <span style="color: #ff4500;">0x18</span> <span style="color: #66cc66;">==</span> <span style="color: #ff4500;">0x18</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mpeg_version <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'1'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; is_valid <span style="color: #66cc66;">=</span> <span style="color: #008000;">False</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> is_valid:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">ord</span><span style="color: black;">&#40;</span>frame_hdr<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> &amp; <span style="color: #ff4500;">6</span> <span style="color: #66cc66;">==</span> <span style="color: #ff4500;">2</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; layer_desc <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'Layer III'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">elif</span> <span style="color: #008000;">ord</span><span style="color: black;">&#40;</span>frame_hdr<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> &amp; <span style="color: #ff4500;">6</span> <span style="color: #66cc66;">==</span> <span style="color: #ff4500;">4</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; layer_desc <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'Layer II'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">elif</span> <span style="color: #008000;">ord</span><span style="color: black;">&#40;</span>frame_hdr<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> &amp; <span style="color: #ff4500;">6</span> <span style="color: #66cc66;">==</span> <span style="color: #ff4500;">6</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; layer_desc <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'Layer I'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; is_valid <span style="color: #66cc66;">=</span> <span style="color: #008000;">False</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> is_valid:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; uses_crc <span style="color: #66cc66;">=</span> <span style="color: #008000;">ord</span><span style="color: black;">&#40;</span>frame_hdr<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> &amp; <span style="color: #ff4500;">1</span> <span style="color: #66cc66;">==</span> <span style="color: #ff4500;">0</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bitrate_chart <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#91;</span><span style="color: #ff4500;">32</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">32</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">32</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">32</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">8</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#91;</span><span style="color: #ff4500;">64</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">48</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">40</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">48</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">16</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#91;</span><span style="color: #ff4500;">96</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">56</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">48</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">56</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">24</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#91;</span><span style="color: #ff4500;">128</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">64</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">56</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">64</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">32</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#91;</span><span style="color: #ff4500;">160</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">80</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">64</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">80</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">40</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#91;</span><span style="color: #ff4500;">192</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">96</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">80</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">96</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">40</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#91;</span><span style="color: #ff4500;">224</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">112</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">96</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">112</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">56</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#91;</span><span style="color: #ff4500;">256</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">128</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">112</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">128</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">64</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#91;</span><span style="color: #ff4500;">288</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">160</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">128</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">144</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">80</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#91;</span><span style="color: #ff4500;">320</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">192</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">160</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">160</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">96</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#91;</span><span style="color: #ff4500;">352</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">224</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">192</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">176</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">112</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#91;</span><span style="color: #ff4500;">384</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">256</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">224</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">192</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">128</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#91;</span><span style="color: #ff4500;">416</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">320</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">256</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">224</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">144</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#91;</span><span style="color: #ff4500;">448</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">384</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">320</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">256</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">160</span><span style="color: black;">&#93;</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bitrate_index <span style="color: #66cc66;">=</span> <span style="color: #008000;">ord</span><span style="color: black;">&#40;</span>frame_hdr<span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">&gt;&gt;</span> <span style="color: #ff4500;">4</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> bitrate_index<span style="color: #66cc66;">==</span><span style="color: #ff4500;">15</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; is_valid<span style="color: #66cc66;">=</span><span style="color: #008000;">False</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bitrate_col <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">0</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> mpeg_version <span style="color: #66cc66;">==</span> <span style="color: #483d8b;">'1'</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> layer_desc <span style="color: #66cc66;">==</span> <span style="color: #483d8b;">'Layer I'</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bitrate_col <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">0</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">elif</span> layer_desc <span style="color: #66cc66;">==</span> <span style="color: #483d8b;">'Layer II'</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bitrate_col <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bitrate_col <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">2</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> layer_desc <span style="color: #66cc66;">==</span> <span style="color: #483d8b;">'Layer I'</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bitrate_col <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">3</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bitrate_col <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">4</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bitrate <span style="color: #66cc66;">=</span> bitrate_chart<span style="color: black;">&#91;</span>bitrate_index<span style="color: black;">&#93;</span><span style="color: black;">&#91;</span>bitrate_col<span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; is_valid <span style="color: #66cc66;">=</span> bitrate <span style="color: #66cc66;">&gt;</span> <span style="color: #ff4500;">0</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> is_valid:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sample_rate_chart <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#91;</span><span style="color: #ff4500;">44100</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">22050</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">11025</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#91;</span><span style="color: #ff4500;">48000</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">24000</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">12000</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#91;</span><span style="color: #ff4500;">32000</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">16000</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">8000</span><span style="color: black;">&#93;</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sample_rate_index <span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span><span style="color: #008000;">ord</span><span style="color: black;">&#40;</span>frame_hdr<span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> &amp; <span style="color: #ff4500;">0xc</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">&gt;&gt;</span> <span style="color: #ff4500;">2</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> sample_rate_index <span style="color: #66cc66;">!=</span> <span style="color: #ff4500;">3</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sample_rate_col <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">0</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> mpeg_version <span style="color: #66cc66;">==</span> <span style="color: #483d8b;">'1'</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sample_rate_col <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">0</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">elif</span> mpeg_version <span style="color: #66cc66;">==</span> <span style="color: #483d8b;">'2'</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sample_rate_col <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sample_rate_col <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">2</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sample_rate <span style="color: #66cc66;">=</span> sample_rate_chart<span style="color: black;">&#91;</span>sample_rate_index<span style="color: black;">&#93;</span><span style="color: black;">&#91;</span>sample_rate_col<span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; is_valid <span style="color: #66cc66;">=</span> <span style="color: #008000;">False</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> is_valid:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; padding <span style="color: #66cc66;">=</span> <span style="color: #008000;">ord</span><span style="color: black;">&#40;</span>frame_hdr<span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> &amp; <span style="color: #ff4500;">1</span> <span style="color: #66cc66;">==</span> <span style="color: #ff4500;">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; padding_length <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">0</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> layer_desc <span style="color: #66cc66;">==</span> <span style="color: #483d8b;">'Layer I'</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> padding:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; padding_length <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">4</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; frame_length <span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span><span style="color: #ff4500;">12</span> * bitrate * <span style="color: #ff4500;">1000</span> / sample_rate + padding_length<span style="color: black;">&#41;</span> * <span style="color: #ff4500;">4</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> padding:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; padding_length <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; frame_length <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">144</span> * bitrate * <span style="color: #ff4500;">1000</span> / sample_rate + padding_length<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; is_valid <span style="color: #66cc66;">=</span> frame_length <span style="color: #66cc66;">&gt;</span> <span style="color: #ff4500;">0</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Verify the next frame</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span><span style="color: black;">&#40;</span>frame_start + frame_length <span style="color: #66cc66;">&lt;</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>block<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; is_valid <span style="color: #66cc66;">=</span> block<span style="color: black;">&#91;</span>frame_start + frame_length<span style="color: black;">&#93;</span> <span style="color: #66cc66;">==</span> <span style="color: #008000;">chr</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">255</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; offset <span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span>frame_start + frame_length<span style="color: black;">&#41;</span> - <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>block<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; block <span style="color: #66cc66;">=</span> f.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1024</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>block<span style="color: black;">&#41;</span> <span style="color: #66cc66;">&gt;</span> offset:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; is_valid <span style="color: #66cc66;">=</span> block<span style="color: black;">&#91;</span>offset<span style="color: black;">&#93;</span> <span style="color: #66cc66;">==</span> <span style="color: #008000;">chr</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">255</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; is_valid <span style="color: #66cc66;">=</span> <span style="color: #008000;">False</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; f.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> is_valid</div></div>
<p>No related posts.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=UmzN8ZSxXeg:C2SkNAX9zjc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=UmzN8ZSxXeg:C2SkNAX9zjc:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?i=UmzN8ZSxXeg:C2SkNAX9zjc:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=UmzN8ZSxXeg:C2SkNAX9zjc:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?i=UmzN8ZSxXeg:C2SkNAX9zjc:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=UmzN8ZSxXeg:C2SkNAX9zjc:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?i=UmzN8ZSxXeg:C2SkNAX9zjc:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=UmzN8ZSxXeg:C2SkNAX9zjc:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=UmzN8ZSxXeg:C2SkNAX9zjc:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?i=UmzN8ZSxXeg:C2SkNAX9zjc:gIN9vFwOqvQ" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://blog.eringal.com/python/verifying-that-an-mp3-file-is-valid-in-python/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Esperanto Support Plugin for Anki</title>
		<link>http://blog.eringal.com/python/esperanto-support-plugin-for-anki/</link>
		<comments>http://blog.eringal.com/python/esperanto-support-plugin-for-anki/#comments</comments>
		<pubDate>Thu, 05 Aug 2010 07:10:29 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[addon]]></category>
		<category><![CDATA[Anki]]></category>
		<category><![CDATA[Esperanto]]></category>
		<category><![CDATA[plugin]]></category>

		<guid isPermaLink="false">http://blog.eringal.com/?p=98</guid>
		<description><![CDATA[So I decided to learn Esperanto, which as an avid user of the SRS application Anki, meant I needed to either enter Esperanto&#8217;s special characters (ĉ, ĝ, ĥ, ĵ, ŝ, ŭ) into my flash cards, which can&#8217;t easily be typed with the US International keyboard layout, or I could deal with the ugly &#8220;x method&#8221; [...]
Related posts:<ol>
<li><a href='http://blog.eringal.com/python/anki-2-0-esperanto-and-github/' rel='bookmark' title='Anki 2.0, Esperanto, and GitHub'>Anki 2.0, Esperanto, and GitHub</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>So I decided to learn <a href="http://en.lernu.net/">Esperanto</a>, which as an avid user of the <a href="http://en.wikipedia.org/wiki/Spaced_repetition">SRS</a> application <a href="http://ichi2.net/anki/">Anki</a>, meant I needed to either enter Esperanto&#8217;s special characters <em>(ĉ, ĝ, ĥ, ĵ, ŝ, ŭ)</em> into my flash cards, which can&#8217;t easily be typed with the <a href="http://babelhut.com/writing-systems/why-you-should-be-using-the-us-international-keyboard-layout/">US International keyboard layout</a>, or I could deal with the ugly &#8220;x method&#8221; workaround <em>(cx, gx, hx, jx, sx, ux)</em>. At first, I was only creating Esperanto cards from my Linux computers at home, which let me use an Esperanto keyboard layout to type in the special characters. Pretty soon though, I found myself creating cards from my Windows machine at work during breaks. There is no Esperanto keyboard layout in Windows by default, so I tried to install some third party keyboard layouts without success. I eventually came across a program called <a href="http://www.esperanto.mv.ru/Ek/">Ek</a>, which seemed to do the job of letting me type special characters, except in Anki where it would only type &#8220;ĉ&#8221;. So I just dealt with the &#8220;x method&#8221; and was typing words like <em>vojagxas</em> instead of <em>vojaĝas</em>. I don&#8217;t know why, but after a while all the x&#8217;s began to really bother me. I didn&#8217;t want to see <em>mangxi</em> in my flash cards, it just doesn&#8217;t seem as natural as <em>manĝi</em> does. So I did what any other software developer would do&#8230;.</p>
<p>I wrote some code.</p>
<p>Specifically, I wrote a plugin for Anki which converts all those terrible <em>cx</em>, <em>gx</em>, <em>hx</em>, <em>jx</em>, <em>sx</em>, and <em>ux</em> combinations into the aesthetically pleasing <em>ĉ</em>, <em>ĝ</em>, <em>ĥ</em>, <em>ĵ</em>. ŝ. and <em>ŭ</em> characters. Prior to this I&#8217;ve never written a plugin for Anki, and even now I claim no expertise. Anki is written in Python, and so are its plugins. I found a plugin that adds some support for the German language to Anki and used that as a model to build my plugin.</p>
<p>To use the Esperanto plugin, open Anki, go to File -&gt; Download -&gt; Shared Plugin. Type &#8220;esperanto&#8221; into the search box. My plugin is the only one that matches that search, so it should be highlighted already. The plugin is called &#8220;Esperanto Support for Anki&#8221;. Click Ok and it should download and install for you. In your deck, when you want to add a card for Esperanto, make sure the card is using the &#8220;Esperanto&#8221; model rather than &#8220;Basic&#8221; model.</p>
<p>I&#8217;m open to suggestions and feedback, and if you are curious about the code at all, open up your Anki plugins folder and take it a look. The code is right there and it&#8217;s very simple.</p>
<p>Related posts:<ol>
<li><a href='http://blog.eringal.com/python/anki-2-0-esperanto-and-github/' rel='bookmark' title='Anki 2.0, Esperanto, and GitHub'>Anki 2.0, Esperanto, and GitHub</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=3314JfXmKNU:sll4nkXeRtE:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=3314JfXmKNU:sll4nkXeRtE:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?i=3314JfXmKNU:sll4nkXeRtE:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=3314JfXmKNU:sll4nkXeRtE:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?i=3314JfXmKNU:sll4nkXeRtE:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=3314JfXmKNU:sll4nkXeRtE:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?i=3314JfXmKNU:sll4nkXeRtE:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=3314JfXmKNU:sll4nkXeRtE:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=3314JfXmKNU:sll4nkXeRtE:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?i=3314JfXmKNU:sll4nkXeRtE:gIN9vFwOqvQ" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://blog.eringal.com/python/esperanto-support-plugin-for-anki/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Foreign Language Audio on Demand at RhinoSpike.com</title>
		<link>http://blog.eringal.com/projects/rhinospike/foreign-language-audio-on-demand-at-rhinospike-com/</link>
		<comments>http://blog.eringal.com/projects/rhinospike/foreign-language-audio-on-demand-at-rhinospike-com/#comments</comments>
		<pubDate>Thu, 15 Apr 2010 05:57:40 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[RhinoSpike]]></category>

		<guid isPermaLink="false">http://blog.eringal.com/?p=88</guid>
		<description><![CDATA[So aside from my day job and my family, I&#8217;ve been keeping myself busy since December working on a project with my friend Thomas that we&#8217;ve released to the public just a few weeks ago. That project is RhinoSpike, a web site where people can submit text in a foreign language to be read aloud [...]
No related posts.]]></description>
			<content:encoded><![CDATA[<p><a href="http://rhinospike.com"><img class="alignright" title="RhinoSpike" src="http://rhinospike.com/site_media/static/images/rs_logo_60.png" alt="RhinoSpike" width="330" height="60" /></a>So aside from my day job and my family, I&#8217;ve been keeping myself busy since December working on a project with my friend <a href="http://twitter.com/tummai">Thomas</a> that we&#8217;ve released to the public just a few weeks ago. That project is <a href="http://rhinospike.com/">RhinoSpike</a>, a web site where people can submit text in a foreign language to be read aloud and recorded by native speakers of that language. In return, people can read and record themselves reading texts submitted in their native language for students of that language. It&#8217;s swap meet of mp3 files, only instead of copyrighted music, these mp3 files contain the voice and sound of many languages worldwide! I consider it my small and humble contribution to the goal of bringing peace and goodwill towards men through learning each others language.</p>
<p>The entire venture is a part-time deal for myself and Thomas, because we both have day jobs. So we had to maximize the effect of our efforts by building on a platform that provides all of the basic stuff that just about any website needs these days. That platform for us is <a href="http://pinaxproject.com/">Pinax</a>, which is itself built on top of <a href="http://www.djangoproject.com/">Django</a> in the <a href="http://blog.eringal.com/tags/python/">Python</a> programming language. I can&#8217;t say enough good things about Pinax because it let us focus on what was unique to our site, while Pinax handled user authentication, <a href="http://openid.net/">OpenID</a>, avatars, <a href="http://en.gravatar.com/">Gravatar</a>, social network features like friends and messaging, announcements, administration, error handling, internationalization, and so much more that we actually had to strip out some of the built-in features because we felt it was too much for our site. These features are very modular and allowed us to essentially turn them on and off as if by a switch.</p>
<p>This project has been a great learning experience for me and continues to be so. In just three weeks we have almost 900 users, who mostly have found their way to our site via word of mouth on <a href="http://twitter.com/rhino_spike">Twitter</a> and some <a href="http://www.tofugu.com/2010/04/09/getting-japanese-people-to-record-japanese-audio-for-you-with-rhinospike/">great</a> <a href="http://www.spanish-only.com/2010/04/weekly-newsletter-6-7/">language</a> <a href="http://www.fluentin3months.com/language-hacking-links/">learning</a> <a href="http://www.alljapaneseallthetime.com/blog/ajatt-twitter-tweets-for-week-of-2010-04-03">blogs</a>. These users have been making many suggestions to make RhinoSpike even better, some of which we&#8217;ve already implemented and many more which we plan to do soon.</p>
<p>If you haven&#8217;t done so already, check <a href="http://rhinospike.com/">RhinoSpike</a> out, and tell me what you think! I&#8217;d love to hear it!</p>
<p>No related posts.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=UyC8Y0BWIKA:R1jrmfTn-R4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=UyC8Y0BWIKA:R1jrmfTn-R4:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?i=UyC8Y0BWIKA:R1jrmfTn-R4:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=UyC8Y0BWIKA:R1jrmfTn-R4:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?i=UyC8Y0BWIKA:R1jrmfTn-R4:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=UyC8Y0BWIKA:R1jrmfTn-R4:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?i=UyC8Y0BWIKA:R1jrmfTn-R4:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=UyC8Y0BWIKA:R1jrmfTn-R4:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=UyC8Y0BWIKA:R1jrmfTn-R4:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?i=UyC8Y0BWIKA:R1jrmfTn-R4:gIN9vFwOqvQ" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://blog.eringal.com/projects/rhinospike/foreign-language-audio-on-demand-at-rhinospike-com/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Barra de Español 1.2 is now available!</title>
		<link>http://blog.eringal.com/projects/barradeespanol/barra-de-espanol-1-2-is-now-available/</link>
		<comments>http://blog.eringal.com/projects/barradeespanol/barra-de-espanol-1-2-is-now-available/#comments</comments>
		<pubDate>Fri, 20 Nov 2009 18:01:39 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[BarraDeEspañol]]></category>
		<category><![CDATA[addon]]></category>
		<category><![CDATA[español]]></category>
		<category><![CDATA[extension]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[spanish]]></category>
		<category><![CDATA[toolbar]]></category>

		<guid isPermaLink="false">http://blog.eringal.com/?p=86</guid>
		<description><![CDATA[The newest version of Barra de Español, version 1.2, is now available! See details about what&#8217;s new in this version in my post on Babelhut.com. Related posts: Update: Barra de Español version 1.1 released! Barra de Español has been accepted to Mozilla&#8217;s public addon list Barra de Español: The making of a Firefox extension
Related posts:<ol>
<li><a href='http://blog.eringal.com/projects/barradeespanol/update-barra-de-espanol-version-11-released/' rel='bookmark' title='Update: Barra de Español version 1.1 released!'>Update: Barra de Español version 1.1 released!</a></li>
<li><a href='http://blog.eringal.com/projects/barradeespanol/barra-de-espanol-has-been-accepted-to-mozillas-public-addon-list/' rel='bookmark' title='Barra de Español has been accepted to Mozilla&#8217;s public addon list'>Barra de Español has been accepted to Mozilla&#8217;s public addon list</a></li>
<li><a href='http://blog.eringal.com/projects/barradeespanol/barra-de-espanol-the-making-of-a-firefox-extension/' rel='bookmark' title='Barra de Español: The making of a Firefox extension'>Barra de Español: The making of a Firefox extension</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>The newest version of Barra de Español, version 1.2, is now available! See details about what&#8217;s new in this version in <a href="http://babelhut.com/languages/spanish/barradeespanol/barra-de-espanol-1-2-is-now-available/">my post on Babelhut.com</a>.</p>
<p>Related posts:<ol>
<li><a href='http://blog.eringal.com/projects/barradeespanol/update-barra-de-espanol-version-11-released/' rel='bookmark' title='Update: Barra de Español version 1.1 released!'>Update: Barra de Español version 1.1 released!</a></li>
<li><a href='http://blog.eringal.com/projects/barradeespanol/barra-de-espanol-has-been-accepted-to-mozillas-public-addon-list/' rel='bookmark' title='Barra de Español has been accepted to Mozilla&#8217;s public addon list'>Barra de Español has been accepted to Mozilla&#8217;s public addon list</a></li>
<li><a href='http://blog.eringal.com/projects/barradeespanol/barra-de-espanol-the-making-of-a-firefox-extension/' rel='bookmark' title='Barra de Español: The making of a Firefox extension'>Barra de Español: The making of a Firefox extension</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=NMui5o5qA-Q:wSNNfPuGEFc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=NMui5o5qA-Q:wSNNfPuGEFc:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?i=NMui5o5qA-Q:wSNNfPuGEFc:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=NMui5o5qA-Q:wSNNfPuGEFc:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?i=NMui5o5qA-Q:wSNNfPuGEFc:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=NMui5o5qA-Q:wSNNfPuGEFc:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?i=NMui5o5qA-Q:wSNNfPuGEFc:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=NMui5o5qA-Q:wSNNfPuGEFc:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=NMui5o5qA-Q:wSNNfPuGEFc:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?i=NMui5o5qA-Q:wSNNfPuGEFc:gIN9vFwOqvQ" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://blog.eringal.com/projects/barradeespanol/barra-de-espanol-1-2-is-now-available/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Simulating a keypress in Firefox</title>
		<link>http://blog.eringal.com/firefox/simulating-a-keypress-in-firefox/</link>
		<comments>http://blog.eringal.com/firefox/simulating-a-keypress-in-firefox/#comments</comments>
		<pubDate>Tue, 27 Oct 2009 13:28:19 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[Firefox]]></category>
		<category><![CDATA[addon]]></category>
		<category><![CDATA[BarraDeEspañol]]></category>
		<category><![CDATA[extension]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://blog.eringal.com/?p=81</guid>
		<description><![CDATA[Last night, I was working on Barra de Español and had spent quite a bit of time on Google looking for how to simulate a keypress in Firefox. It&#8217;s as simple as creating an event and dispatching it, though how to do so is not exactly intuitive. I needed to be able to do this [...]
Related posts:<ol>
<li><a href='http://blog.eringal.com/projects/barradeespanol/barra-de-espanol-the-making-of-a-firefox-extension/' rel='bookmark' title='Barra de Español: The making of a Firefox extension'>Barra de Español: The making of a Firefox extension</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Last night, I was working on <a href="http://blog.eringal.com/topics/projects/barradeespanol/">Barra de Español</a> and had spent quite a bit of time on Google looking for how to simulate a keypress in Firefox. It&#8217;s as simple as creating an event and dispatching it, though how to do so is not exactly intuitive. I needed to be able to do this because inserting accented characters from Barra de Español was not working in the message body textbox in Gmail and other webmail apps.</p>
<p>The way I inserted the characters before was to find the currently focused element, assume it was a textbox, and modify its value using the selectionStart property to know where the cursor was. Once I learned that the message body textbox could not be found using <em>document.commandDispatcher.focusedElement</em>, (that&#8217;s what &#8220;<em>if(!focused) focused = document.commandDispatcher.focusedWindow.document.activeElement;</em>&#8221; is all about) I found that the element used by Gmail for the message body wasn&#8217;t even a textbox, and didn&#8217;t have a value or selectionStart properties.</p>
<p>So the solution is to create a keypress event and dispatch it, like so:</p>
<div class="codecolorer-container javascript default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">insertchar<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>ch<span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> focused <span style="color: #339933;">=</span> document.<span style="color: #660066;">commandDispatcher</span>.<span style="color: #660066;">focusedElement</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>focused<span style="color: #009900;">&#41;</span> focused <span style="color: #339933;">=</span> document.<span style="color: #660066;">commandDispatcher</span>.<span style="color: #660066;">focusedWindow</span>.<span style="color: #660066;">document</span>.<span style="color: #660066;">activeElement</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> evt <span style="color: #339933;">=</span> document.<span style="color: #660066;">createEvent</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;KeyboardEvent&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; evt.<span style="color: #660066;">initKeyEvent</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;keypress&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> ch<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; focused.<span style="color: #660066;">dispatchEvent</span><span style="color: #009900;">&#40;</span>evt<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p>One important thing to note is that the parameter ch is not a character value, but an integer containing the character code you want to insert. So, for example, to insert the character &#8216;á&#8217;, ch must be the value 225. To find the values I needed I used the wonderful character lookup tool at <a href="http://leftlogic.com/lounge/articles/entity-lookup/">http://leftlogic.com/lounge/articles/entity-lookup/</a>.</p>
<p><strong>Bonus tip:</strong> If you are developing a Firefox extension and are using a text file in your profile&#8217;s extension directory to point to the folder where your code is located, and you move your code to another folder, you will discover that Firefox won&#8217;t load your extension, even though you edited the text file with the new location. The fix is to find a file in your profile directory called extensions.cache and delete it. This frustrated me for at least an hour last night, and Google failed me on this.</p>
<p>Related posts:<ol>
<li><a href='http://blog.eringal.com/projects/barradeespanol/barra-de-espanol-the-making-of-a-firefox-extension/' rel='bookmark' title='Barra de Español: The making of a Firefox extension'>Barra de Español: The making of a Firefox extension</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=n4hpGNxM420:EhTp-frmqiM:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=n4hpGNxM420:EhTp-frmqiM:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?i=n4hpGNxM420:EhTp-frmqiM:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=n4hpGNxM420:EhTp-frmqiM:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?i=n4hpGNxM420:EhTp-frmqiM:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=n4hpGNxM420:EhTp-frmqiM:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?i=n4hpGNxM420:EhTp-frmqiM:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=n4hpGNxM420:EhTp-frmqiM:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=n4hpGNxM420:EhTp-frmqiM:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?i=n4hpGNxM420:EhTp-frmqiM:gIN9vFwOqvQ" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://blog.eringal.com/firefox/simulating-a-keypress-in-firefox/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Update on my Android Developer Challenge 2 attempt</title>
		<link>http://blog.eringal.com/android/update-on-my-android-developer-challenge-2-attempt/</link>
		<comments>http://blog.eringal.com/android/update-on-my-android-developer-challenge-2-attempt/#comments</comments>
		<pubDate>Tue, 08 Sep 2009 22:40:41 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[ADC 2]]></category>

		<guid isPermaLink="false">http://blog.eringal.com/?p=74</guid>
		<description><![CDATA[So the deadline for the Android Developer Challenge 2 has come and gone, and I did not submit an entry. It wasn&#8217;t for a lack of trying though. This was entirely a spare time project and I worked on it 3 to 5 days a week for an hour or more at a time. I&#8217;m [...]
Related posts:<ol>
<li><a href='http://blog.eringal.com/android/my-development-plan-for-the-android-developer-challenge-2/' rel='bookmark' title='My development plan for the Android Developer Challenge 2'>My development plan for the Android Developer Challenge 2</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>So the deadline for the <a href="http://blog.eringal.com/android/my-development-plan-for-the-android-developer-challenge-2/">Android Developer Challenge 2</a> has come and gone, and I did not submit an entry. It wasn&#8217;t for a lack of trying though. This was entirely a spare time project and I worked on it 3 to 5 days a week for an hour or more at a time. I&#8217;m still not comfortable going into specifics about the project because I think it&#8217;s still a viable project. I do still hope to release it to the public at some point.</p>
<p>I will say that I was able to write one of the major features completely, and nearly completed the second major feature. The main reason I didn&#8217;t complete the second feature is because it required scraping some data from a web site, and that web site made some of the data difficult to parse by putting it into an image. I didn&#8217;t discover this until about 2 nights before the deadline. Without the second feature  I didn&#8217;t feel the application was compelling enough to enter into the contest, which is too bad. I think I will be able to get the data I need from an alternate source, so I will resume development of this app and hopefully release it to the public later.</p>
<p>I didn&#8217;t realize it at the time, but working on this project had increased my stress level quite a bit. I enjoyed working on it, and I&#8217;m beginning to appreciate how the Android SDK works, but the deadline was always in the back of my mind. When I decided to call it off, I felt a quite noticeable relief.  I don&#8217;t think the stress builds as much for deadlines at my day job, but having to focus my spare time on one project to the exclusion of others was too much for me. I think I need to keep my side projects deadline-free from now on.</p>
<p>Related posts:<ol>
<li><a href='http://blog.eringal.com/android/my-development-plan-for-the-android-developer-challenge-2/' rel='bookmark' title='My development plan for the Android Developer Challenge 2'>My development plan for the Android Developer Challenge 2</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=lpfq8Y-dADw:3l1Akw1i-6c:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=lpfq8Y-dADw:3l1Akw1i-6c:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?i=lpfq8Y-dADw:3l1Akw1i-6c:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=lpfq8Y-dADw:3l1Akw1i-6c:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?i=lpfq8Y-dADw:3l1Akw1i-6c:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=lpfq8Y-dADw:3l1Akw1i-6c:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?i=lpfq8Y-dADw:3l1Akw1i-6c:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=lpfq8Y-dADw:3l1Akw1i-6c:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=lpfq8Y-dADw:3l1Akw1i-6c:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?i=lpfq8Y-dADw:3l1Akw1i-6c:gIN9vFwOqvQ" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://blog.eringal.com/android/update-on-my-android-developer-challenge-2-attempt/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Barra de Español has been accepted to Mozilla’s public addon list</title>
		<link>http://blog.eringal.com/projects/barradeespanol/barra-de-espanol-has-been-accepted-to-mozillas-public-addon-list/</link>
		<comments>http://blog.eringal.com/projects/barradeespanol/barra-de-espanol-has-been-accepted-to-mozillas-public-addon-list/#comments</comments>
		<pubDate>Sat, 29 Aug 2009 17:02:42 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[BarraDeEspañol]]></category>
		<category><![CDATA[addon]]></category>
		<category><![CDATA[español]]></category>
		<category><![CDATA[extension]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[spanish]]></category>
		<category><![CDATA[toolbar]]></category>

		<guid isPermaLink="false">http://blog.eringal.com/?p=71</guid>
		<description><![CDATA[I got an email today from the Mozilla Add-ons group that my add-on for Firefox, Barra de Español, has been approved to be in the public listing for Firefox add-ons! This means that it&#8217;s no longer listed as &#8220;experimental&#8221; and no longer requires that users check a box in order to install it. I was [...]
Related posts:<ol>
<li><a href='http://blog.eringal.com/projects/barradeespanol/barra-de-espanol-the-making-of-a-firefox-extension/' rel='bookmark' title='Barra de Español: The making of a Firefox extension'>Barra de Español: The making of a Firefox extension</a></li>
<li><a href='http://blog.eringal.com/projects/barradeespanol/barra-de-espanol-1-2-is-now-available/' rel='bookmark' title='Barra de Español 1.2 is now available!'>Barra de Español 1.2 is now available!</a></li>
<li><a href='http://blog.eringal.com/projects/barradeespanol/update-barra-de-espanol-version-11-released/' rel='bookmark' title='Update: Barra de Español version 1.1 released!'>Update: Barra de Español version 1.1 released!</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>I got an email today from the Mozilla Add-ons group that my add-on for Firefox, <a href="http://addons.mozilla.org/addon/12029">Barra de Español</a>, has been approved to be in the public listing for Firefox add-ons! This means that it&#8217;s no longer listed as &#8220;experimental&#8221; and no longer requires that users check a box in order to install it.</p>
<p>I was a bit surprised by how long this process took. I nominated it when I released version 1.1 on June 7. 83 days later it was accepted, and during those 83 days I had no feedback as to what was going on. A week or two ago I visited an IRC chat room for add-on developers and was told that 2 or 3 months was pretty common. Recently Mozilla released a <a href="https://addons.mozilla.org/en-US/statistics">statistics dashboard</a> that shows how many add-ons get created or updated daily. I&#8217;m not sure how many reviewers Mozilla has, but it makes more sense why it takes as long as it does now that I can see those numbers.</p>
<p>Regardless, I&#8217;m happy my little add-on has been accepted and I definitely have plans to enhance it in the future.</p>
<p>Related posts:<ol>
<li><a href='http://blog.eringal.com/projects/barradeespanol/barra-de-espanol-the-making-of-a-firefox-extension/' rel='bookmark' title='Barra de Español: The making of a Firefox extension'>Barra de Español: The making of a Firefox extension</a></li>
<li><a href='http://blog.eringal.com/projects/barradeespanol/barra-de-espanol-1-2-is-now-available/' rel='bookmark' title='Barra de Español 1.2 is now available!'>Barra de Español 1.2 is now available!</a></li>
<li><a href='http://blog.eringal.com/projects/barradeespanol/update-barra-de-espanol-version-11-released/' rel='bookmark' title='Update: Barra de Español version 1.1 released!'>Update: Barra de Español version 1.1 released!</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=gk3dXX07kAs:qbNsH2fQdac:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=gk3dXX07kAs:qbNsH2fQdac:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?i=gk3dXX07kAs:qbNsH2fQdac:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=gk3dXX07kAs:qbNsH2fQdac:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?i=gk3dXX07kAs:qbNsH2fQdac:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=gk3dXX07kAs:qbNsH2fQdac:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?i=gk3dXX07kAs:qbNsH2fQdac:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=gk3dXX07kAs:qbNsH2fQdac:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=gk3dXX07kAs:qbNsH2fQdac:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?i=gk3dXX07kAs:qbNsH2fQdac:gIN9vFwOqvQ" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://blog.eringal.com/projects/barradeespanol/barra-de-espanol-has-been-accepted-to-mozillas-public-addon-list/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My development plan for the Android Developer Challenge 2</title>
		<link>http://blog.eringal.com/android/my-development-plan-for-the-android-developer-challenge-2/</link>
		<comments>http://blog.eringal.com/android/my-development-plan-for-the-android-developer-challenge-2/#comments</comments>
		<pubDate>Thu, 30 Jul 2009 03:45:55 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[ADC 2]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Mobile]]></category>

		<guid isPermaLink="false">http://blog.eringal.com/?p=63</guid>
		<description><![CDATA[I haven&#8217;t posted lately about Barra de Español or the Biblefeed Project because my free time has been split among other projects and I have not been able to return to these two for the moment. Barra de Español is still awaiting approval on addons.mozilla.org to be put in the public section, so I don&#8217;t [...]
Related posts:<ol>
<li><a href='http://blog.eringal.com/android/update-on-my-android-developer-challenge-2-attempt/' rel='bookmark' title='Update on my Android Developer Challenge 2 attempt'>Update on my Android Developer Challenge 2 attempt</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>I haven&#8217;t posted lately about <a href="http://blog.eringal.com/topics/projects/barradeespanol/">Barra de Español</a> or the <a href="http://blog.eringal.com/topics/projects/biblefeed/">Biblefeed Project</a> because my free time has been split among other projects and I have not been able to return to these two for the moment. Barra de Español is still awaiting approval on <a href="https://addons.mozilla.org/en-US/firefox/addon/12029/">addons.mozilla.org</a> to be put in the public section, so I don&#8217;t want to make further improvements to it until that happens.</p>
<p>Recently I purchased an <a href="http://en.wikipedia.org/wiki/HTC_Dream">Android phone</a>, and I love it! It&#8217;s everything I wanted a phone to be. It has an excellent web browser, a full QWERTY keyboard, GPS, and it&#8217;s hackable! I decided pretty quickly that I wanted to write an app for it, and as I start looking for the documentation on how to write one, I discover that Google is holding a <a href="http://code.google.com/intl/en-US/android/adc/">developer contest</a>. This discovery changed my approach to developing this app.</p>
<p>I&#8217;m not going to talk about the app I&#8217;m working on, but I did want to share how I intend to work on it, because it&#8217;s a little different than my normal approach to personal projects. Normally I start with a minimal list of features. These are the features that are most important to me. I work on each one a little at time, slowly improving the pieces until they are functional and working well together. Each piece  that I work usually causes me to improve the other pieces of the program until finally they&#8217;re all done at around the same time. At this point the project is probably ugly. I may give it some finishing touches, but not always. The project is for me, so functionality trumps aesthetics.</p>
<p>For this contest I felt that developing an app required a different approach. I made a larger list of features that I felt the app could do that I had not originally planned for, especially features which would take advantage of some of the built-in hardware and software on the Android platform. I then prioritized each feature based on how essential the functionality is to the application, how much the feature took advantage of the platform, and how impressive I thought that the feature could be.</p>
<p>With this prioritized list, I&#8217;m going to develop each feature as a whole, one feature at a time. Each feature must be functionally complete and aesthetically pleasing before I move on to the next feature. The reason for this is because if the entry deadline arrives before all of the features are complete, I can still submit an application which is still functional and polished, even if it has fewer features than planned. With my normal development style I could be stuck with an ugly app where only half of the features work by the time the deadline rolls around.</p>
<p>I don&#8217;t expect that I will be able to complete all of my planned features for this project by the August 31 deadline, but I hope with this plan I will have a decent app to submit. There is a bit of a learning curve that is slowing me down though. Even though it&#8217;s been over five or six years since I&#8217;ve worked with Java, the changes to the language are similar to the changes to C# over the same time period. The real learning curve comes from the Android framework. The <a href="http://developer.android.com/guide/topics/fundamentals.html">activities, intents, content providers, etc.</a> are easy enough to understand but I&#8217;m still dealing with an API that is brand new to me, and will take time to absorb.</p>
<p>Wish me luck!</p>
<p>Related posts:<ol>
<li><a href='http://blog.eringal.com/android/update-on-my-android-developer-challenge-2-attempt/' rel='bookmark' title='Update on my Android Developer Challenge 2 attempt'>Update on my Android Developer Challenge 2 attempt</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=OBq7qlcjOXY:CIZHtTpXNSc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=OBq7qlcjOXY:CIZHtTpXNSc:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?i=OBq7qlcjOXY:CIZHtTpXNSc:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=OBq7qlcjOXY:CIZHtTpXNSc:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?i=OBq7qlcjOXY:CIZHtTpXNSc:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=OBq7qlcjOXY:CIZHtTpXNSc:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?i=OBq7qlcjOXY:CIZHtTpXNSc:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=OBq7qlcjOXY:CIZHtTpXNSc:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=OBq7qlcjOXY:CIZHtTpXNSc:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?i=OBq7qlcjOXY:CIZHtTpXNSc:gIN9vFwOqvQ" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://blog.eringal.com/android/my-development-plan-for-the-android-developer-challenge-2/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Update: Barra de Español version 1.1 released!</title>
		<link>http://blog.eringal.com/projects/barradeespanol/update-barra-de-espanol-version-11-released/</link>
		<comments>http://blog.eringal.com/projects/barradeespanol/update-barra-de-espanol-version-11-released/#comments</comments>
		<pubDate>Sun, 07 Jun 2009 21:44:13 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[BarraDeEspañol]]></category>
		<category><![CDATA[addon]]></category>
		<category><![CDATA[español]]></category>
		<category><![CDATA[extension]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[spanish]]></category>
		<category><![CDATA[toolbar]]></category>

		<guid isPermaLink="false">http://blog.eringal.com/?p=60</guid>
		<description><![CDATA[Just a quick update to announce that Barra de Español version 1.1 has been released. For more details, see my post on babelhut.com about the release. Related posts: Barra de Español 1.2 is now available! Barra de Español: The making of a Firefox extension Barra de Español has been accepted to Mozilla&#8217;s public addon list
Related posts:<ol>
<li><a href='http://blog.eringal.com/projects/barradeespanol/barra-de-espanol-1-2-is-now-available/' rel='bookmark' title='Barra de Español 1.2 is now available!'>Barra de Español 1.2 is now available!</a></li>
<li><a href='http://blog.eringal.com/projects/barradeespanol/barra-de-espanol-the-making-of-a-firefox-extension/' rel='bookmark' title='Barra de Español: The making of a Firefox extension'>Barra de Español: The making of a Firefox extension</a></li>
<li><a href='http://blog.eringal.com/projects/barradeespanol/barra-de-espanol-has-been-accepted-to-mozillas-public-addon-list/' rel='bookmark' title='Barra de Español has been accepted to Mozilla&#8217;s public addon list'>Barra de Español has been accepted to Mozilla&#8217;s public addon list</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Just a quick update to announce that Barra de Español version 1.1 has been released. For more details, see <a href="http://babelhut.com/languages/spanish/barradeespanol/update-barra-de-espanol-version-11-has-been-released/">my post on babelhut.com about the release</a>.</p>
<p>Related posts:<ol>
<li><a href='http://blog.eringal.com/projects/barradeespanol/barra-de-espanol-1-2-is-now-available/' rel='bookmark' title='Barra de Español 1.2 is now available!'>Barra de Español 1.2 is now available!</a></li>
<li><a href='http://blog.eringal.com/projects/barradeespanol/barra-de-espanol-the-making-of-a-firefox-extension/' rel='bookmark' title='Barra de Español: The making of a Firefox extension'>Barra de Español: The making of a Firefox extension</a></li>
<li><a href='http://blog.eringal.com/projects/barradeespanol/barra-de-espanol-has-been-accepted-to-mozillas-public-addon-list/' rel='bookmark' title='Barra de Español has been accepted to Mozilla&#8217;s public addon list'>Barra de Español has been accepted to Mozilla&#8217;s public addon list</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=rmDxF4o_78I:N-9SlOYHXTA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=rmDxF4o_78I:N-9SlOYHXTA:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?i=rmDxF4o_78I:N-9SlOYHXTA:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=rmDxF4o_78I:N-9SlOYHXTA:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?i=rmDxF4o_78I:N-9SlOYHXTA:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=rmDxF4o_78I:N-9SlOYHXTA:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?i=rmDxF4o_78I:N-9SlOYHXTA:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=rmDxF4o_78I:N-9SlOYHXTA:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?a=rmDxF4o_78I:N-9SlOYHXTA:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/PeterCarrollSoftwareDeveloper?i=rmDxF4o_78I:N-9SlOYHXTA:gIN9vFwOqvQ" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://blog.eringal.com/projects/barradeespanol/update-barra-de-espanol-version-11-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

