tag:blogger.com,1999:blog-41365498640351702052008-02-11T17:00:32.836-08:00cosmotronAlexhttp://www.blogger.com/profile/08423296523921081149noreply@blogger.comBlogger4125tag:blogger.com,1999:blog-4136549864035170205.post-75581661398248285722007-07-03T13:43:00.000-07:002007-07-03T13:47:46.136-07:002007-07-03T13:47:46.136-07:00Rainy Day R2Upon seeing R2 in the rain during "The Empire Strikes Back" my wife asks: "Why doesn't R2 have an umbrella?" <a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_peI11ttMpaw/Roq1n8h5VbI/AAAAAAAAAA0/aCoAMrzf1Ag/s1600-h/rainy-day-r2.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://bp0.blogger.com/_peI11ttMpaw/Roq1n8h5VbI/AAAAAAAAAA0/aCoAMrzf1Ag/s400/rainy-day-r2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5083074827308848562" /></a>Alexhttp://www.blogger.com/profile/08423296523921081149noreply@blogger.comtag:blogger.com,1999:blog-4136549864035170205.post-60236437840848169982007-06-25T16:25:00.000-07:002008-02-11T17:00:06.185-08:002008-02-11T17:00:06.185-08:00Automatically update to latest WebKit each night.<p>You like webkit. You want the latest WebKit installed fresh each night while you sleep. You've looked at NightShift and found that it lacked a certain simplicity. You came here.</p> <p>Ok. We need a script to do the dirty work. Bash is fine:</p> <p><pre><code> #!/bin/bash # coding: utf-8 # Update Webkit # Alex Ross function handle { echo "An error occured!" exit $? } trap handle ERR APPLICATIONS="/Applications" ORG='http://nightly.webkit.org' LOCAL_REVISION=`cat /Applications/WebKit.app/Contents/Resources/VERSION` LATEST_REVISION_PATH=`curl --silent $ORG | grep -o "/files/trunk/mac/WebKit-SVN-r[0-9]*.dmg" | head -n 1` LATEST_REVISION=`echo \"$ORG+$LATEST_REVISION_PATH\" | grep -E '[0-9]{4,}' -io` if [ $LOCAL_REVISION -eq $LATEST_REVISION ]; then echo "Local WebKit r$LOCAL_REVISION is latest build, exiting." > /dev/console exit else echo "Updating WebKit.app to r$LATEST_REVISION..." > /dev/console fi curl -sL $ORG$LATEST_REVISION_PATH > /tmp/latest-webkit-svn.dmg hdiutil attach /tmp/latest-webkit-svn.dmg -mountpoint /tmp/latest-webkit-svn -quiet osascript <<-APPLESCRIPT tell application "Finder" activate set answer to display dialog "Would you like to update WebKit now? Your open Webkit and Drosera windows will close. Updating automatically in 30 seconds…" with title "WebKit Updater" buttons {"No", "Yes"} default button {"Yes"} giving up after 30 if button returned of answer is "Yes" or button returned of answer is not "No" then tell application "System Events" if (name of processes) contains "WebKit" then quit application "WebKit" saving no if (name of processes) contains "DroseraLauncher" then quit application "Drosera" saving no end tell end if end tell delay 0.25 tell application "System Events" if (name of processes) does not contain "WebKit" and (name of processes) does not contain "DroseraLauncher" then return 1 else return 0 end if end tell APPLESCRIPT rm -rf $APPLICATIONS/Drosera.app $APPLICATIONS/WebKit.app cp -R /tmp/latest-webkit-svn/Drosera.app $APPLICATIONS/Drosera.app cp -R /tmp/latest-webkit-svn/WebKit.app $APPLICATIONS/WebKit.app hdiutil detach /tmp/latest-webkit-svn -quiet rm /tmp/latest-webkit-svn.dmg echo "Webkit is up-to-date." > /dev/console </code></pre></p> <p>Paste all this junk into a text file and save it to /Library/Scripts/update_webkit.sh.</p> <p>We create a launch agent to run this script each morning at 4am. Open a blank text file and paste in this xml:</p> <code><pre> &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt; &lt;!DOCTYPE plist PUBLIC &quot;-//Apple Computer//DTD PLIST 1.0//EN&quot; &quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&quot;&gt; &lt;plist version=&quot;1.0&quot;&gt; &lt;dict&gt; &lt;key&gt;Label&lt;/key&gt; &lt;string&gt;UpdateWebKit&lt;/string&gt; &lt;key&gt;UserName&lt;/key&gt; &lt;string&gt;root&lt;/string&gt; &lt;key&gt;GroupName&lt;/key&gt; &lt;string&gt;wheel&lt;/string&gt; &lt;key&gt;ProgramArguments&lt;/key&gt; &lt;array&gt; &lt;string&gt;/bin/sh&lt;/string&gt; &lt;string&gt;/Library/Scripts/update_webkit.sh&lt;/string&gt; &lt;/array&gt; &lt;key&gt;StartCalendarInterval&lt;/key&gt; &lt;dict&gt; &lt;key&gt;Hour&lt;/key&gt; &lt;integer&gt;4&lt;/integer&gt; &lt;/dict&gt; &lt;/dict&gt; &lt;/plist&gt; </pre></code> <p>That's it! You're done. Mmmm. I love the smell of fresh nightlies in the morning.</p>Alexhttp://www.blogger.com/profile/08423296523921081149noreply@blogger.comtag:blogger.com,1999:blog-4136549864035170205.post-28209923627268349892007-01-22T20:08:00.000-08:002007-10-16T18:38:00.296-07:002007-10-16T18:38:00.296-07:00Generating HTML Image Maps<p>Have you ever pulled a handful of hair from your head? If you&#8217;ve ever tried to create an <abbr title="HyperText Markup Language">HTML</abbr> Image Map with the <acronym>GIMP</acronym>, then I&#8217;m sure your sitting in clumps of it. No More! With <code>gen_imgmap.py</code>, you can auto-generate your image maps from a simple <abbr>PNG</abbr> image file and a <abbr>CSV</abbr> text file!</p> <p>Here&#8217;s how it works:</p> <p>Create an image that has a unique color for each area you would like to make clickable. Like this:</p> <p><a href="http://bp1.blogger.com/_peI11ttMpaw/RbWvyTk1GzI/AAAAAAAAAAc/QO9r4mWdmLY/s1600-h/alaska.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://bp1.blogger.com/_peI11ttMpaw/RbWvyTk1GzI/AAAAAAAAAAc/QO9r4mWdmLY/s400/alaska.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5023114238184725298" /></a></p> <p>Now, all you need is a <abbr>CSV</abbr> file that maps the color values in your image to the href, name, title, and any other attributes that you would like on your area tags. The first line of the <abbr>CSV</abbr> contains labels for the following rows. The first label has to be “color”, it can be either a hexadecimal color code or an integer color code. The remaining columns can be whichever attributes you would like to give to your area tags. Like This (I&#8217;m using integer color codes here):</p> <pre><code>color, id, title, href 46621634, AKZ208, Lower Kobuk and Noatak Valleys, http://pafg.arh.noaa.gov/zonefcst.php?zone=AKZ208 47610067, AKZ217, Upper Kobuk and Noatak Valleys, http://pafg.arh.noaa.gov/zonefcst.php?zone=AKZ217 47549398, AKZ205, Northwestern Brooks Range, http://pafg.arh.noaa.gov/zonefcst.php?zone=AKZ205 49656045, AKZ206, Northeastern Brooks Range, http://pafg.arh.noaa.gov/zonefcst.php?zone=AKZ206 49847290, AKZ218, Southeastern Brooks Range, http://pafg.arh.noaa.gov/zonefcst.php?zone=AKZ218 45763761, AKZ210, Northern and Interior Seward Peninsula, http://pafg.arh.noaa.gov/zonefcst.php?zone=AKZ210 46099384, AKZ216, Lower Koyukuk and Middle Yukon Valleys, http://pafg.arh.noaa.gov/zonefcst.php?zone=AKZ216 46608056, AKZ219, Upper Koyukuk Valley, http://pafg.arh.noaa.gov/zonefcst.php?zone=AKZ219 45777072, AKZ220, Yukon Flats and Surrounding Uplands, http://pafg.arh.noaa.gov/zonefcst.php?zone=AKZ220 45322154, AKZ221, Central Interior, http://pafg.arh.noaa.gov/zonefcst.php?zone=AKZ221 47940043, AKZ222, Middle Tanana Valley, http://pafg.arh.noaa.gov/zonefcst.php?zone=AKZ222 47594677, AKZ224, Upper Tanana Valley and the Fortymile Country, http://pafg.arh.noaa.gov/zonefcst.php?zone=AKZ224 49981415, AKZ215, Lower Yukon Valley, http://pafg.arh.noaa.gov/zonefcst.php?zone=AKZ215 45428630, AKZ151, Kuskokwim Valley, http://pafg.arh.noaa.gov/zonefcst.php?zone=AKZ151 48126408, AKZ225, Denali, http://pafg.arh.noaa.gov/zonefcst.php?zone=AKZ225 49956578, AKZ223, Deltana and Tanana Flats, http://pafg.arh.noaa.gov/zonefcst.php?zone=AKZ223 47673817, AKZ226, Eastern Alaska Range, http://pafg.arh.noaa.gov/zonefcst.php?zone=AKZ226 </code></pre> <p>If for some reason you need to use comma&#8217;s inside one of your attribute strings, you&#8217;ll have to double quote all of them.</p> <p>Now, all that must be done is the running of the program (<code>-i</code> tells <code>gen_imgmap.py</code> to use integer color codes):</p> <pre><code>./gen_imgmap.py -i alaska.png attributes.csv map.html </code></pre> <p>This will take a couple of minutes. For simpler color maps, obviously the program will run far more quickly. When it&#8217;s finished, you’ll be left with something like this:</p> <p><map name='genmap'> <area shape='poly' title='Lower Koyukuk and Middle Yukon Valleys' href='http://pafg.arh.noaa.gov/zonefcst.php?zone=AKZ216' name='AKZ216' coords='65,131, 62,124, 60,122, 57,117, 57,115, 62,108, 63,105, 65,103, 70,94, 70,91, 68,89, 64,82, 58,76, 53,72, 51,71, 48,64, 35,61, 28,58, 25,58, 11,57, 11,60, 10,67, 6,80, 1,86, 1,131, 10,133, 12,135, 16,144, 16,150, 14,159, 31,159, 38,156, 40,156, 56,151, 66,144, 68,143, 68,140, 65,133'></area> <area shape='poly' title='Denali' href='http://pafg.arh.noaa.gov/zonefcst.php?zone=AKZ225' name='AKZ225' coords='85,155, 85,158, 134,159, 139,157, 142,157, 146,158, 146,137, 124,137, 117,141, 115,141, 113,143, 106,147, 104,149, 95,154, 91,154'></area> <area shape='poly' title='Southeastern Brooks Range' href='http://pafg.arh.noaa.gov/zonefcst.php?zone=AKZ218' name='AKZ218' coords='111,41, 138,42, 143,44, 163,44, 176,37, 178,35, 183,33, 185,31, 188,31, 192,30, 194,29, 194,2, 148,2, 142,8, 129,12, 126,12, 113,14, 110,14, 77,16, 76,35, 72,39, 68,44, 70,45, 91,41'></area> <area shape='poly' title='Northwestern Brooks Range' href='http://pafg.arh.noaa.gov/zonefcst.php?zone=AKZ205' name='AKZ205' coords='74,16, 76,13, 76,11, 77,4, 78,2, 53,2, 56,5, 60,8, 60,13, 62,13, 67,16'></area> <area shape='poly' title='Lower Kobuk and Noatak Valleys' href='http://pafg.arh.noaa.gov/zonefcst.php?zone=AKZ208' name='AKZ208' coords='1,37, 2,34, 1,34'></area> <area shape='poly' title='Lower Kobuk and Noatak Valleys' href='http://pafg.arh.noaa.gov/zonefcst.php?zone=AKZ208' name='AKZ208' coords='3,15, 6,2, 1,2, 1,27, 3,25'></area> <area shape='poly' title='Upper Koyukuk Valley' href='http://pafg.arh.noaa.gov/zonefcst.php?zone=AKZ219' name='AKZ219' coords='102,86, 107,79, 108,76, 112,72, 119,68, 121,66, 126,63, 128,61, 129,57, 131,54, 131,52, 133,49, 133,47, 135,44, 90,42, 88,42, 67,46, 63,50, 54,57, 49,62, 49,65, 52,70, 57,75, 65,82, 69,89, 71,91, 72,93, 76,93, 84,94, 95,89, 97,89'></area> <area shape='poly' title='Upper Kobuk and Noatak Valleys' href='http://pafg.arh.noaa.gov/zonefcst.php?zone=AKZ217' name='AKZ217' coords='50,59, 57,53, 62,49, 65,47, 71,40, 75,35, 75,17, 67,17, 62,14, 60,14, 59,8, 57,6, 50,2, 7,2, 7,4, 4,17, 4,25, 2,28, 2,33, 5,40, 5,42, 6,46, 11,55, 24,56, 40,61, 42,61, 48,62'></area> <area shape='poly' title='Deltana and Tanana Flats' href='http://pafg.arh.noaa.gov/zonefcst.php?zone=AKZ223' name='AKZ223' coords='191,152, 194,152, 194,143, 192,141, 185,137, 182,134, 175,130, 173,128, 171,128, 164,125, 154,125, 144,124, 139,126, 134,126, 134,130, 132,135, 152,136, 160,137, 163,139, 165,139, 178,146, 182,146, 189,150'></area> <area shape='poly' title='Upper Tanana Valley and the Fortymile Country' href='http://pafg.arh.noaa.gov/zonefcst.php?zone=AKZ224' name='AKZ224' coords='193,141, 194,100, 174,100, 174,128'></area> <area shape='poly' title='Baldwin Peninsula and Selawik Valley' href='http://pafg.arh.noaa.gov/zonefcst.php?zone=AKZ209' name='AKZ209' coords='9,53, 5,46, 5,43, 4,40, 2,38, 1,38, 1,54, 4,54, 9,55'></area> <area shape='poly' title='Lower Yukon Valley' href='http://pafg.arh.noaa.gov/zonefcst.php?zone=AKZ215' name='AKZ215' coords='15,147, 15,143, 10,134, 7,134, 1,133, 1,159, 13,159, 13,156'></area> <area shape='poly' title='Middle Tanana Valley' href='http://pafg.arh.noaa.gov/zonefcst.php?zone=AKZ222' name='AKZ222' coords='153,123, 164,124, 171,127, 173,127, 173,100, 170,100, 163,97, 161,97, 139,96, 139,99, 140,110, 137,117, 137,119, 135,122, 135,125, 140,125, 145,123'></area> <area shape='poly' title='Northern and Interior Seward Peninsula' href='http://pafg.arh.noaa.gov/zonefcst.php?zone=AKZ210' name='AKZ210' coords='9,66, 9,61, 10,56, 5,56, 1,55, 1,84, 5,81, 5,79'></area> <area shape='poly' title='Yukon Flats and Surrounding Uplands' href='http://pafg.arh.noaa.gov/zonefcst.php?zone=AKZ220' name='AKZ220' coords='111,74, 109,76, 108,79, 106,81, 103,86, 105,88, 107,88, 116,92, 118,92, 121,94, 137,94, 160,95, 167,98, 169,98, 194,99, 194,30, 193,30, 186,32, 171,40, 169,42, 162,45, 142,45, 137,43, 135,45, 134,49, 132,52, 132,54, 130,57, 130,59, 125,65, 118,69, 116,71'></area> <area shape='poly' title='Susitna Valley' href='http://pafg.arh.noaa.gov/zonefcst.php?zone=AKZ145' name='AKZ145' coords='139,158, 138,158'></area> <area shape='poly' title='Northeastern Brooks Range' href='http://pafg.arh.noaa.gov/zonefcst.php?zone=AKZ206' name='AKZ206' coords='118,13, 131,11, 138,8, 140,8, 146,3, 79,2, 78,10, 76,15, 92,15, 109,14'></area> <area shape='poly' title='Central Interior' href='http://pafg.arh.noaa.gov/zonefcst.php?zone=AKZ221' name='AKZ221' coords='85,154, 90,154, 96,153, 98,151, 101,150, 103,148, 110,144, 112,142, 115,140, 117,140, 124,136, 130,136, 132,133, 132,131, 134,122, 136,119, 136,117, 139,110, 139,100, 138,96, 121,95, 118,93, 116,93, 107,89, 105,89, 100,88, 97,90, 95,90, 92,92, 90,92, 87,94, 85,94, 77,95, 71,94, 70,97, 68,99, 63,108, 61,110, 58,115, 58,117, 63,124, 66,131, 66,133, 69,140, 69,142, 84,135, 86,136, 83,143, 81,145, 82,150'></area> <area shape='poly' title='Kuskokwim Valley' href='http://pafg.arh.noaa.gov/zonefcst.php?zone=AKZ151' name='AKZ151' coords='84,159, 84,156, 81,149, 81,147, 80,145, 82,143, 85,136, 83,136, 66,145, 64,147, 53,153, 51,153, 44,156, 41,156, 36,158'></area> <area shape='poly' title='Eastern Alaska Range' href='http://pafg.arh.noaa.gov/zonefcst.php?zone=AKZ226' name='AKZ226' coords='182,147, 178,147, 165,140, 163,140, 160,138, 153,138, 147,137, 147,159, 194,159, 194,153, 191,153, 189,151'></area> </map><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://bp1.blogger.com/_peI11ttMpaw/RbWvyTk1GzI/AAAAAAAAAAc/QO9r4mWdmLY/s400/alaska.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5023114238184725298" usemap="#genmap"/></p> <p>You may also notice that a folder called “masks” is created, and that this folder contains a bunch of <abbr>PNG</abbr> image masks with column two of the <abbr>CSV</abbr> file as their image name. <code>gen_imgmap.py</code> uses these files to figure out where to place the bounding polygons for your area tags. You may also use them to create overlays for each region of your image. Check out <a href="http://pafg.arh.noaa.gov">this page</a> to see how I have applied this method to a production web page.</p> <p>To use <code>gen_imgmap.py</code> you&#8217;ll need the following software:</p> <ul> <li>ImageMagick ≥ 6.3.0</li> <li>Python ≥ 2.4</li> <li>numpy ≥ 1.0</li> <li>PIL ≥ 1.1.6</li> </ul> <p>You can get it here: <a href="http://pastie.textmate.org/107941"><code>gen_imgmap.py</code></a>. </p> <h5> Update: </h5> <p> micheal fixed a couple of problems with the script with a patch below in the comments. I have updated the link to reflect his patch. </p>Alexhttp://www.blogger.com/profile/08423296523921081149noreply@blogger.comtag:blogger.com,1999:blog-4136549864035170205.post-18643048826935087072007-01-21T20:20:00.000-08:002007-01-22T20:08:40.148-08:002007-01-22T20:08:40.148-08:00Hi<p>Hello there. I am Alexander John Ross. This is my blog.</p> <p>Maybe you are wondering what I am. Well, I'll tell you. I am a mathematician. I've almost got a Bachelor's Degree from the <a href="http://www.uaf.edu">University of Alaska Fairbanks</a>. Math is fun! A lot of people ask me what I am going to do with a degree in mathematics. Well, I'll tell you. I don't know! I think I'll probably just use my lessons in logic to do something fun.</p> <p>I like to write code. I write mostly in <a href="http://www.python.org">python</a>, but <a href="http://ruby-lang.org">ruby</a> is fun too. I'm a bundle maintainer/developer for TextMate. I write code for the National Weather Service. I do a little bit of consulting on the side. If you want to hire me, you can! I am proficient in <acronym title="HyperText Markup Language">HTML</acronym>, <acronym title="Cascading Style Sheets">CSS</acronym>, python, javascript, uhm… PHP, Ruby… You get the idea.</p> <p>Stay tuned for various cool stuff which will be arriving here shortly!</p>Alexhttp://www.blogger.com/profile/08423296523921081149noreply@blogger.com