Thursday, August 7, 2008

Updated weather script

Since the weather page I used for my previous weather script changed, reducing half of my scripts output to an ascii-splosion, I decided to take another stab at it. Turns out Google supports weather searching. I rewrote the regular expressions and incorporated some new ruby tricks I've learned since. I'm actually rather pleased with the result: weather.rb

The regular expressions are a bit yucky, but that's to be expected. I think the rest of the code is pretty readable. Cool feature: that bit with the join and URI.escape at the top lets you use it like so:

weather san francisco, ca

"san", "francisco,", and "ca" will be passed as separate arguments, but the line at the top will join them together and convert the resulting string into something you could type in a URL bar. (ie: spaces -> %20).

Makes it easy to be sloppy on the command line. :)

Monday, August 4, 2008

Interesting case of "for x in xs" in Javascript

Recently, I began experimenting with Javascript (mostly to see what the fuss was all about.) I'm making a web page form to help students computer their current grade in a class, based on the grading (weighting) system outlined in the syllabus and the known scores on assignments. (Pretty simple, but hopefully useful.) More on that in a future post.

As I was working, I stumbled on some rather bizzare behavior (at least to me, Javascript neophyte) that I figured was worth remarking on, in case someone else (or my future self) encounters a similar problem.

In part of my code, I wanted to be able to search the array by matching against member variables of its elements. After hunting around online a bit, I was led to the conclusion that extending the Array class was the accepted (and clever?) thing to do here:


Array.prototype.getNdx = function(id) {
for (i in this) {
if (this[i].id == id) {
return parseInt(i);
}
}

return -1;
}


I got busy with other things, and weeks went by. Tonight, I resumed work on the code. I was trying to generalize the task of dynamically adding rows to tables, since this was going to happen in several places on the page. This task involves appending children to a node, so I wrote the row adding code to iterate over an array of cell objects and add each of them to the node. Seemed simple enough.


for (col in cells) {
var cell = row.insertCell(col);
...
cell.appendChile(node);
}


However, the alignment was off. After poking around a bit with Firebug (a lifesaver, by the way; I see us becoming close friends), I determined that an extra node was being added to the beginning of the row.

After assuring myself that my indexes all started where I intended them to, I decided to add an "alert('col = ' + col)" line to the each phase of the adding process, to show me what was going on (a variant of the classic "print("x = " + x)" line for debugging purposes.) The alerts showed me the indexes as:

0...1...2...3...*etc*...getNdx

...wtf?

I didn't research this in depth (this entry was mostly for future reference in case I hit this problem again...sometimes school/work makes me go a while between pet projects). However, my theory is that my custom "getNdx" function was picked up as another element of cells by the "for" iterator. Which...sort of...makes sense. I guess. In a free-form, loosely typed, Javascripty sort of way.

At any rate, maybe that will clear this up if anyone else hits this issue. Simplified code to show this behavior:


Array.prototype.getNdx = function(id) {
for (i in this) {
if (this[i].id == id) {
return parseInt(i);
}
}

return -1;
}

var col = 0;
var cells = new Array();

cells[col++] = "asdf"
cells[col++] = "fdsa"

for (j in cells) {
alert(j);
}

Tuesday, July 15, 2008

Bring some sanity to Windows window management

I am fed up with all the precision mouse-work required to simply move and resize windows under most non-X11 window managers. (Read: Windows and Mac). On most X11 window managers, you can hold down the "alt" key and click and drag on the window. Left clicking moves the window, and right clicking resizes the window. So much more humane than trying to grab those edges!

In the midst of frustration today at too-tiny default windows, I hunted around for a solution. Behold: KDE-SizerXP.

I myself never associated this behavior with KDE specifically, but I'm not one to complain!

(Mac users, take a look at Window Dragon. I haven't used it, but I believe it solves the same problem).

Monday, June 9, 2008

Fixing DPI changes in Linux

(or, how to enforce a constant DPI)

Lately, I found that repeatedly enabling and disabling an external monitor for my laptop caused the fonts to get smaller and smaller. It appears this was linked to the DPI getting changed somehow. With a bit of hunting, I found the following useful bit of info:

"...some distributions launch X using "-dpi 100". Fonts will appear as intended..."
(http://scanline.ca/dpi/)

Indeed, adding -dpi 100 to defaultserverargs in /usr/bin/startx did the trick. (At least for now...we'll see if it holds.)

Saturday, April 5, 2008

Search shortcuts for text based browsers (with bash)

Recently, I started experimenting with text-based web browsers (such as elinks or w3m). Of course, I still use firefox for pages that are more complex or need images, but sometimes it is nice to just have the text version in a console (no distractions, consistent colors, and ad blocking!)

However, one thing I really missed from firefox was the ease with which I could search google, wikipedia. or other sites. Well, with a bash script and some aliases, I can now do basically the same thing with a text based browser.

Here is the bash script:

#!/bin/bash
# Open a search for on in a text-based browser
# Usage: search.sh

browser=elinks # could also put w3m here

site=$1
query=$2%20$3%20$4%20$5%20$6%20$7%20$8%20$9 # hack to pick up >1 search terms

case $site in
"google" ) $browser 'http://www.google.com/search?q='$query;;
"wikipedia" ) $browser 'http://en.wikipedia.org/wiki/Special\:Search?search='$query;;
"torrentz" ) $browser 'http://www.torrentz.com/search?q='$query;;
"isohunt" ) $browser 'http://isohunt.com/torrents/?ihq='$query;;
"portage" ) $browser 'http://gentoo-portage.com/Search?search='$query;;
* ) echo "Unknown site";;
esac


I then added the following aliases to my .bashrc (the script is in ~/bin/)

alias google='~/bin/search.sh google'
alias wiki='~/bin/search.sh wikipedia'
alias torrentz='~/bin/search.sh torrentz'
alias iso='~/bin/search.sh isohunt'
alias port='~/bin/search.sh portage'


Now, if I want to quickly look up, say, a package in portage, I just type portage package_name in my terminal.

Saturday, March 29, 2008

More ruby: comics

My next foray into Ruby (see previous post) came to me while I was catching up on my favorite web comics over break. While ordinarily not much of a hassle, some of the pages were taking especially long to load all of the images, most of which were not the comic I actually cared about. Wouldn't it be nice to have a script that made me a page with just the comics themselves?

It turned out to be pretty straightforward. Here's the result: comics.rb

I then created a simple bash script to make loading comics.html into a browser cleaner:

#!/bin/bash
# Generate an updated comics page and load it in browser du jour

BROWSER='firefox -new-window'

ruby ~/bin/comics/comics.rb
$BROWSER comics.html &

Friday, March 28, 2008

Some nifty ruby scripts

Update: A better version of the weather script is discussed above

Lately, I've revisited ruby for various small code projects. It's virtues are extolled at length here, so I won't bother other than to say I like it. The following programs are some practical examples of ruby (though not the most elegant ways of doing so), and are just plain useful (at least to me).

Weather
I wanted to fetch weather forecasts for my area (or any other I happened to be visiting). There are several weather reporters available, and I've tried many of them. However, they were all in widget form, and tied to some desktop environment, dock, or some such. I decided to create one I could call from the command line (handy, since I soon moved to awesomewm, which has no desktop or dock to speak of. More on that another time.)

My weather reporter downloads two different pages off of weather.com (the "now" page and the "forecast" page), scans them for the relevant temperatures, and displays them neatly on the screen (with ASCII colors :). It defaults to San Luis Obispo (my current home base), but will take a zip code as an argument.

The code: weather-old.rb

Battery
For similar reasons to the weather, I wanted a script to give me a simple battery readout, perfect for status bars or command lines. After a bit of research, I found that (in Linux) the battery information is stored in various files in /proc/acpi/battery/BAT#. It was just a matter of scanning these files, doing a bit of division, and formatting the output.

Here is the code: battery.rb