My reasoned, well-considered thoughts on gadgets, computing, quantified self, health, open source and whatever else gets my dander up.
Cookie Notice
As far as I know, and as far as I remember, nothing in this page does anything with Cookies.
2008/12/30
Contemplating Beautiful Code...
Honestly, I thought I had written this a year ago.
I received a review copy of the O'Reilly book Beautiful Code over a year ago, and I was hopeful from the time I heard about it. For any technical subject I knew, the go-to book was always the O'Reilly. I learned C++ from O'Reilly. I learned lex and yacc from O'Reilly. I learned Perl from a book with a Camel on the front. Later, when Linux and Open Source started to get a foothold in the mainstream computer world, O'Reilly published an excellent oral history with Open Sources. When I saw O'Reilly and Beautiful Code together, I thought it would be an excellent resource.
And then I started to read.
I just couldn't finish.
There are many words in the jargon file that can lean toward implying beauty. Elegant, for example, or clean. "Clever" is used but has no entry. Many more describing variations on ugly, but this is understandable. "Readable" isn't in the Jargon File but is a common complaint against Perl, my language of choice.
Absence of complication leads to elegance, but is elegance beauty? Is cleverness beauty? If code is readable, is makes it easier to understand, easy to change, but does that mean beauty? The Keats test, "Beauty is truth, truth beauty,—that is all Ye know on earth, and all ye need to know", seems insufficient. And nothing I read made a utilitarian or functional argument for the benefit of beauty in a code base.
I was disappointed in O'Reilly for this. They're still my go-to supplier for technical books. As I write this, I'm waiting with bated breath for Amazon to deliver The Productive Programmer. It should arrive today. Productivity, that's something measurable, something I understand the value of. I hope it's more ueseful than Beautiful Code.
Reconsidering a Point...
This is a callback on the post on "wireless monitors".
Consider a netbook with a current-generation SSD drive. 6-8 gigabytes. Sure, years ago that was positively massive, but today, that's next to nothing. But, something that small would be a great candidate for your remote desktop scheme of choice. One thing I've discovered about Remote Desktops in the Windows world, one clear benefit over X forwarding in Unix, is that you forward sound as well as graphics. (Mark your calendars, folks, because you won't get such a clear comment favoring Windows again any time soon.)
So, for $300, you get your self an 8" monitor that you can take with you. I've been a Palm guy long enough, even with that time being past, to be soured on the concept of a device being a metaphorical prehensile tail to the desktop system.
Laptop sales have leaped above desktops in sales recently, and I see that trend going on. I'm not seeing why you'd keep a desktop if you had a sufficient laptop.
But there must be something to this idea, or else I'd let go of it.
Consider a netbook with a current-generation SSD drive. 6-8 gigabytes. Sure, years ago that was positively massive, but today, that's next to nothing. But, something that small would be a great candidate for your remote desktop scheme of choice. One thing I've discovered about Remote Desktops in the Windows world, one clear benefit over X forwarding in Unix, is that you forward sound as well as graphics. (Mark your calendars, folks, because you won't get such a clear comment favoring Windows again any time soon.)
So, for $300, you get your self an 8" monitor that you can take with you. I've been a Palm guy long enough, even with that time being past, to be soured on the concept of a device being a metaphorical prehensile tail to the desktop system.
Laptop sales have leaped above desktops in sales recently, and I see that trend going on. I'm not seeing why you'd keep a desktop if you had a sufficient laptop.
But there must be something to this idea, or else I'd let go of it.
2008/12/29
Annoyed by nytimes.com ...
I read web text by highlighting it. Not all the time, but often enough. The paragraph I'm focusing on, that's the one I've dragged my mouse over, and I might bring it down to a sentence if it's sufficiently insightful. I'm thinking about many things, and this is a way to help myself focus.
But, when I do that, the New York Times website seems to think I'm asking for it to define things for me. It can define a word, but asking for it to define a paragraph blows it's little mind.
I know there's a means to shut this off by telling your machine that lookup.nytimes.com or something is 127.0.0.1. I don't read NYT stuff enough to make this worth my while. But maybe someday soon.
But, when I do that, the New York Times website seems to think I'm asking for it to define things for me. It can define a word, but asking for it to define a paragraph blows it's little mind.
I know there's a means to shut this off by telling your machine that lookup.nytimes.com or something is 127.0.0.1. I don't read NYT stuff enough to make this worth my while. But maybe someday soon.
Discuss Wireless Monitors ...
IdeaStorm, a Dell website, is talking about the wireless monitors.
I've seen them advertised, but as a gizmo that plugs into your VGA cable slot and another to the outbound cable from your monitor. Get a wireless monitor, wireless keyboard and wireless mouse, and you could be many yards from your main PC. Which sucks if you need to plug in your thumbdrive, it being across the room and all. Which, I guess, is a good reason to have Bluetooth.
Consider, instead, having a Citrix connection or Remote Desktop to a desktop machine from a laptop. Except, it's all the desktop and none the laptop. There, it almost sounds appealing.
Until you think about it.
The further you get from the desktop, the worse the performance gets. A wireless desktop (keyboard and mouse) comes in about $100, and a netbook comes in around $300. Having a machine that looks like a netbook, costs like a netbook but isn't a netbook and can't be ported like a netbook? That dog don't hunt.
I've seen them advertised, but as a gizmo that plugs into your VGA cable slot and another to the outbound cable from your monitor. Get a wireless monitor, wireless keyboard and wireless mouse, and you could be many yards from your main PC. Which sucks if you need to plug in your thumbdrive, it being across the room and all. Which, I guess, is a good reason to have Bluetooth.
Consider, instead, having a Citrix connection or Remote Desktop to a desktop machine from a laptop. Except, it's all the desktop and none the laptop. There, it almost sounds appealing.
Until you think about it.
The further you get from the desktop, the worse the performance gets. A wireless desktop (keyboard and mouse) comes in about $100, and a netbook comes in around $300. Having a machine that looks like a netbook, costs like a netbook but isn't a netbook and can't be ported like a netbook? That dog don't hunt.
2008/12/27
A pass at coding for Twitter and, kinda, Blogspot
So, you write something in your blog, and you want to tell somebody, right?
Me, too. And here, I've automated the process. This script, blogspot2jabber.pl, reads your Atom feed, looks to see if the newest post is new, and then sends a tweet to your Twitter feed.
I use
And
I'd like to get the URL and subject in, but that can't be guaranteed to be under 140 characters.
Me, too. And here, I've automated the process. This script, blogspot2jabber.pl, reads your Atom feed, looks to see if the newest post is new, and then sends a tweet to your Twitter feed.
I use
AnyDBM_File
to save the most recent, even though I don't nearly tap the awesome power of it, because opening it as a hash is a lot easier than reading then writing a file. XML::Atom
was the tough one to install. CPAN never did finish it, so I used apt-get to install it instead. The laugh is that XML is anything like human-readable.And
Net::Twitter
just could not be easier.
#!/usr/bin/perl
# ========= ========= ========= ========= ========= =========
# blogspot2twitter.pl
#
# AUTHOR - Dave Jacoby
#
# Copyright (c) 2008. David Jacoby.
#
# This program is free software; you can redistribute it
# and/or modify it under the same terms as Perl itself.
#
# See http://www.perl.com/perl/misc/Artistic.html
#
# ---------
use 5.010 ;
use strict ;
use warnings ;
use AnyDBM_File ;
use Carp ;
use Net::Twitter ;
use XML::Atom::Client ;
use XML::Atom::Entry ;
use XML::Atom::Feed ;
use subs qw( get_entry send_to_twitter ) ;
dbmopen my %dbm, '/path/to/.database.dbm', 0600 or croak $! ;
if ( !defined $dbm{ 'current' } ) { $dbm{ 'current' } = '' ; }
say 'C ' . $dbm{ 'current' } ;
my $url = 'your_blogspot_Atom_ feed' ;
# I think that it'll autodetect if you just put the URL
my $entry = get_entry $url ;
my $text = 'New post to my blog - ' . $entry ;
if ( $entry ne $dbm{ 'current' } ) {
send_to_twitter $text ;
$dbm{ 'current' } = $entry ;
}
exit ;
# ===================================================================
sub get_entry {
my $url = shift ;
my $tweet_link ;
my $client = XML::Atom::Client->new ;
my $feed = $client->getFeed( $url ) ;
my @entries = $feed->entries ;
for my $link ( $entries[ 0 ]->link ) {
if ( $link->type eq 'text/html' ) {
$tweet_link = $link->href ;
#we should be picking it up 2nd pass
}
}
return $tweet_link ;
}
# -------------------------------------------------------------------
# ===================================================================
sub send_to_twitter {
my $user = 'username' ;
my $pass = 'password' ;
my $status = shift ;
my $tweet = Net::Twitter->new( username => $user,
password => $pass, ) ;
if ( $tweet->update( $status ) ) { say 'OK' ; }
else { say 'FAIL' ; }
}
# -------------------------------------------------------------------
I'd like to get the URL and subject in, but that can't be guaranteed to be under 140 characters.
Coding Jabber, the first pass ...
My current obsessions are Jabber and Twitter, finding ways to use them that work with what I'm doing. I've made a program that works a bit like mail on a Unix command line. You might list a directory and mail it to yourself like this:
My next goal is to add presence, which I regard as the cool thing about Jabber.
ls | mail yourself@yourserver.edu
. This will work about the same way, except I build in a default target, so you can ls | jabber.pl
as well as ls | jabber.pl yourself@yourjabberserver.edu
. I have it set up so I can also do jabber.pl yourself@yourjabberserver.edu Insert message here
.My next goal is to add presence, which I regard as the cool thing about Jabber.
#!/usr/bin/perl
# ========= ========= ========= ========= ========= =========
# jabber.pl
#
# AUTHOR - Dave Jacoby
#
# Copyright (c) 2008. David Jacoby.
#
# This program is free software; you can redistribute it
# and/or modify it under the same terms as Perl itself.
#
# See http://www.perl.com/perl/misc/Artistic.html
#
# ---------
use 5.010 ;
use strict ;
use warnings ;
use Carp ;
use Net::XMPP ;
my $verbose = 0 ;
if ( $ENV{ PATH } eq '/usr/bin:/bin' ) {
#AS CRONTAB
$verbose = 0 ;
}
elsif ( defined $ENV{ EDITOR } ) {
#AS COMMANDLINE
$verbose = 1 ;
}
elsif ( !defined $ENV{ EDITOR } ) {
#could almost say 'else'
exit 0 ;
}
# connection vars
my $hostname = 'talk.google.com' ;
my $port = 5222 ;
my $componentname = 'gmail.com' ;
my $connectiontype = 'tcpip' ;
my $tls = 1 ;
# user vars
my $username = 'xxx' ;
my $password = 'xxx' ;
my $resource = 'Test' ;
# message
my $addr = '' ;
my @field ;
my $arg = shift @ARGV ;
$arg =~ m{([A-Za-z0-9_.+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4})}mix ;
$addr = $1 ;
if ( $addr eq '' ) {
push @field, 'xxxx@gmail.com' ;
unshift @ARGV, $arg ;
}
else {
push @field, $addr ;
}
my $args = join ' ', @ARGV ;
if ( length $args == 0 ) {
while () {
$args .= $_ ;
}
}
if ( length $args == 0 ) { $args = 'blank' ; }
if ( length $args > 139 ) { $args = substr $args, 0, 139 ; }
my $Connection = new Net::XMPP::Client() ;
# Connect to talk.google.com
my $status = $Connection->Connect( hostname => $hostname,
port => $port,
componentname => $componentname,
connectiontype => $connectiontype,
tls => $tls ) ;
if ( !( defined( $status ) ) ) {
$verbose and say 'ERROR: XMPP connection failed.' ;
$verbose and say $! ;
exit( 0 ) ;
}
# Change hostname
my $sid = $Connection->{ SESSION }->{ id } ;
$Connection->{ STREAM }->{ SIDS }->{ $sid }->{ hostname } = $componentname ;
# Authenticate
my @result = $Connection->AuthSend( username => $username,
password => $password,
resource => $resource ) ;
if ( $result[ 0 ] ne "ok" ) {
print "ERROR: Authorization failed: $result[0] - $result[1]\n" ;
exit( 0 ) ;
}
# Send messages
for my $address ( @field ) {
$Connection->MessageSend( to => $address,
resource => $resource,
subject => "Notification",
type => "chat",
body => $args ) ;
$verbose and say 'TO: ' . $address ;
$verbose and say $args ;
}
$verbose and say 'end' ;
exit ;
2008/12/25
2008/12/22
Considering the CHIMP ...
My son wants a CHIMP for Christmas.
Not a chimpanzee. A CHIMP. Basically, a rear-view mirror for the geek set. CHIMP is a recursive acronym, meaning CHIMP Has Invincible Monkey Powers.
I don't have a CHIMP.
I have a baby mirror, and I have a webcam. Both serve the same purpose, which is giving me a visual indicator of motion behind me, so I don't have to be surprised and scared when someone comes up to me.
The pic of my desktop (and no, my walls are not nearly that yellow) comes from my camera phone, which appears in both the mirror and the webcam.
Not a chimpanzee. A CHIMP. Basically, a rear-view mirror for the geek set. CHIMP is a recursive acronym, meaning CHIMP Has Invincible Monkey Powers.
I don't have a CHIMP.
I have a baby mirror, and I have a webcam. Both serve the same purpose, which is giving me a visual indicator of motion behind me, so I don't have to be surprised and scared when someone comes up to me.
The pic of my desktop (and no, my walls are not nearly that yellow) comes from my camera phone, which appears in both the mirror and the webcam.
2008/12/21
Considering The Future ...
2008/12/19
Pondering Amazon's Suggestions...
I have many machines whose speed I'm relatively happy with but whose storage limits are much too small. In 2008, 40GB is just too small. It might be obvious, but the machines I'm talking about have EIDE. They're just not new enough for SATA.
There's nothing wrong with SATA. In fact, I'd say that the skinny connectors of SATA are far better than the fragile pins and wide ribbons of EIDE. But, I have no SATA at home. Nothing's new enough.
So, I'm stuck on the horns of a dilemma. I want as massive a jump in drive space as I can, but I don't want to be stuck in the past. They stopped making EIDE a year ago. So, what do I do?
There's a 500GB EIDE drive on Amazon at near the price point I'm hoping for. 500GB isn't a terabyte, but it certainly isn't 40GB.
But what gets me is the suggestion box. If you're buying a Stephen King book and they suggest that you might want to get The Stand, too. That makes sense. When you're buying a Punch Brothers CD and they suggest that you might want to get Nickel Creek, too, that's logical. When you're looking at a 500GB EIDE hard drive and they suggest that you might want a 500GB SATA drive, too, that makes no sense.
While I was on Amazon, I thought I might look for a few more things. I work in a dank sub-basement and have no phone on my desk, so I thought getting a Skype phone might be useful. I saw The GE 2-in-1 phone, first at Wal-Mart and then on Amazon. I've seen them before. I'm thinking that a portable phone that talks Bluetooth and Wifi is nothing but win, especially if I can afford to Skype out eventually. But there's a big massive downside. Phone talks to PC, PC talks to Skype. And that means Phone talks to Microsoft-Operating-System-bearing PC, PC talks to Skype. I've used enough Unix and Linux and enough Windows to know that I want to use more Unix, so I want to use less and less to no Windows. Later versions are pure Skype phones, with no connection to a PC. Later versions are $100+. I still think it's a good idea.
GE is also starting to make home phones which call out and pick up on your cell phone, connecting via Bluetooth. On one hand, it makes a bit of sense. When I was an undergrad the second time, about 10 years ago, I was beginning to see and hear about people who were turning off local phone service and only using their cell phone. This makes a reasonable amount of sense to me. In my household, we have cellphones and Vonage and we're considering switching to a cheaper Asterisk solution. So, doing away with the local phone makes sense. But I don't know the benefit of having the phone you use at home not be the phone you use when you're away. The vision I have is of exploding the parts of the phone, not replicating the unified phone of the past. You can get Bluetooth headsets that allow you to talk while using your hands. You can get Bluetooth watches that flash the CallerID information when you get a call. Your phone is in your pocket. What's the point of having a separate home phone that isn't really a separate home phone?
Speaking of, I'm drawn to a Bluetooth dongle I've seen at Wal-Mart for $20. I have a Bluetooth earpiece and a phone that can talk to it, and maybe more and maybe not. So, I don't know what I'd get with that. But hopefully, it'll be cool.
In other news, my friend Patrick has beaten the final boss on OpenSolaris-vs-Windows-Server-2003. Joe User has penetrated the walls of Solaris via su, console, GTK and SSH. And I'm burning the game onto a CD-RW I had floating around. The drive in my #1 Linux box is a bit flakey, so I'm burning on my Windows box, a laptop with a broken screen. I've not been able to burn ISOs in Windows, but this evening I found
There's nothing wrong with SATA. In fact, I'd say that the skinny connectors of SATA are far better than the fragile pins and wide ribbons of EIDE. But, I have no SATA at home. Nothing's new enough.
So, I'm stuck on the horns of a dilemma. I want as massive a jump in drive space as I can, but I don't want to be stuck in the past. They stopped making EIDE a year ago. So, what do I do?
There's a 500GB EIDE drive on Amazon at near the price point I'm hoping for. 500GB isn't a terabyte, but it certainly isn't 40GB.
But what gets me is the suggestion box. If you're buying a Stephen King book and they suggest that you might want to get The Stand, too. That makes sense. When you're buying a Punch Brothers CD and they suggest that you might want to get Nickel Creek, too, that's logical. When you're looking at a 500GB EIDE hard drive and they suggest that you might want a 500GB SATA drive, too, that makes no sense.
While I was on Amazon, I thought I might look for a few more things. I work in a dank sub-basement and have no phone on my desk, so I thought getting a Skype phone might be useful. I saw The GE 2-in-1 phone, first at Wal-Mart and then on Amazon. I've seen them before. I'm thinking that a portable phone that talks Bluetooth and Wifi is nothing but win, especially if I can afford to Skype out eventually. But there's a big massive downside. Phone talks to PC, PC talks to Skype. And that means Phone talks to Microsoft-Operating-System-bearing PC, PC talks to Skype. I've used enough Unix and Linux and enough Windows to know that I want to use more Unix, so I want to use less and less to no Windows. Later versions are pure Skype phones, with no connection to a PC. Later versions are $100+. I still think it's a good idea.
GE is also starting to make home phones which call out and pick up on your cell phone, connecting via Bluetooth. On one hand, it makes a bit of sense. When I was an undergrad the second time, about 10 years ago, I was beginning to see and hear about people who were turning off local phone service and only using their cell phone. This makes a reasonable amount of sense to me. In my household, we have cellphones and Vonage and we're considering switching to a cheaper Asterisk solution. So, doing away with the local phone makes sense. But I don't know the benefit of having the phone you use at home not be the phone you use when you're away. The vision I have is of exploding the parts of the phone, not replicating the unified phone of the past. You can get Bluetooth headsets that allow you to talk while using your hands. You can get Bluetooth watches that flash the CallerID information when you get a call. Your phone is in your pocket. What's the point of having a separate home phone that isn't really a separate home phone?
Speaking of, I'm drawn to a Bluetooth dongle I've seen at Wal-Mart for $20. I have a Bluetooth earpiece and a phone that can talk to it, and maybe more and maybe not. So, I don't know what I'd get with that. But hopefully, it'll be cool.
In other news, my friend Patrick has beaten the final boss on OpenSolaris-vs-Windows-Server-2003. Joe User has penetrated the walls of Solaris via su, console, GTK and SSH. And I'm burning the game onto a CD-RW I had floating around. The drive in my #1 Linux box is a bit flakey, so I'm burning on my Windows box, a laptop with a broken screen. I've not been able to burn ISOs in Windows, but this evening I found
cdburn
, which comes from Microsoft's Windows Server 2003 Resource Kit. It's a command-line tool, which the Unix guy in me loves. And now, or soon, I'll be able to burn ISOs from the common Windows machine at work.
Tryin' to tell the story of my life ...
2008/12/18
Going Through The Inbox ...
Hopefully, this isn't a boring thing. But it does have to be done.
This being the process of going through the magazines on my desk, putting the information onto the blog, and, the process, into my head.
Dr. Dobb's Journal, January 2009.
Just noticed something interesting. The Blogspot web interface traps Control-S and does a save of the current post text to the server, not the current page to the desktop. Pretty neat.
This being the process of going through the magazines on my desk, putting the information onto the blog, and, the process, into my head.
Dr. Dobb's Journal, January 2009.
- Functional Programming: Has It's Ship Come In?
Functional programming: It's hot, it's cool, it maybe maps to multi-core better than Procedural and Object-Oriented programming, but it isn't good with IO so it hasn't been big like some other languages. It's interesting. When I hear procedural, I think cop shows. When I hear functional, I think "it works". A procedural language follows a procedure. A functional language works via functions. This is the stereotype:function( function( function( function( function( function( function( function( function( function( function( function( ) ) ) ) ) ) ) ) ) ) ) )
If it fails to work, just throw a few more close-parens.
The interesting thing about this article is that it suggests a few
- Mono, Linux and .NET Development
It's less that the thought of Microsoft stuff on Linux is repugnant to me than it seems like an odd sort of virtualization.
Just noticed something interesting. The Blogspot web interface traps Control-S and does a save of the current post text to the server, not the current page to the desktop. Pretty neat.
2008/12/16
Organizing My Thoughts on Catalyst
I am about three hours from presenting on Catalyst for my Perl Mongers meeting.
For those who don't know, Catalyst is a Web Framework using the MVC (Model-View-Controller) format to make for easier web development.
Imagine the operators that you see sometimes in 1930s movies, or in old reruns of Laugh-In. The Model is the trunk line with people with information trying to connect in. The View is the person in Suite 14 receiving the calls.
The Controller, Catalyst and the code you write for it, is Lily Tomlin.
Up in Suite 14, running the View, is Template::Toolkit. I've never had reason for templating before, but I'm learning to like it. It's a powerful tool. The institutional view here in the subbasement is that you should limit the amount of logic you put in the View, doing all that mess in the Controller.
The Model is DBIx::Class, and the more I deal with it, the more I accept it as a powerful tool. I have been saying that Catalyst has made it hard for me to leverage the awesome power of SQL, but today I have been beating my head against the switchboard and whipping myself with patch cables, trying to do two simple things. If I get those two things done, I can use one View, one Template Toolkit file, with Catalyst
First, we have
Next, each person does something, and there's a table showing each time that person did that thing. We want to count each thing and establish
I can do that. I can use DBIx to get all that information. What I cannot do is put the genie back in the bottle. Or, I cannot patch it back into the View.
Which means, LOL fashion, that I'm doin' it wrong.
So, I'm off to read up on DBIx::Class, and there's next to zero chance that I'll be able to get this work before Perl Mongers.
For those who don't know, Catalyst is a Web Framework using the MVC (Model-View-Controller) format to make for easier web development.
Imagine the operators that you see sometimes in 1930s movies, or in old reruns of Laugh-In. The Model is the trunk line with people with information trying to connect in. The View is the person in Suite 14 receiving the calls.
The Controller, Catalyst and the code you write for it, is Lily Tomlin.
Up in Suite 14, running the View, is Template::Toolkit. I've never had reason for templating before, but I'm learning to like it. It's a powerful tool. The institutional view here in the subbasement is that you should limit the amount of logic you put in the View, doing all that mess in the Controller.
The Model is DBIx::Class, and the more I deal with it, the more I accept it as a powerful tool. I have been saying that Catalyst has made it hard for me to leverage the awesome power of SQL, but today I have been beating my head against the switchboard and whipping myself with patch cables, trying to do two simple things. If I get those two things done, I can use one View, one Template Toolkit file, with Catalyst
First, we have
lastname
and firstname
, but we want name = firstname . ' ' . lastname
. Unless there is no firstname
, in which case name = lastname
.Next, each person does something, and there's a table showing each time that person did that thing. We want to count each thing and establish
count
.I can do that. I can use DBIx to get all that information. What I cannot do is put the genie back in the bottle. Or, I cannot patch it back into the View.
Which means, LOL fashion, that I'm doin' it wrong.
So, I'm off to read up on DBIx::Class, and there's next to zero chance that I'll be able to get this work before Perl Mongers.
2008/12/15
Documenting the suckage of OpenSolaris ...
2008/12/11
Taking control of my environment ...
As mentioned, I now have OpenSolaris available at my beck and call via VirtualBox.
Interesting story: Right about the time I finished that installation, I had problems with my screen setup. You see, I was bored, so I was playing with screen resolutions. My #1 monitor wants to be at 1680x1050, and due to my futzing, Gnome wouldn't let me get to anything closer than 1280x1024. Which looked like crap and kept the panels out of view.
By the way, I love multiple monitors.
Anyway, you can right-click on the desktop and set your screen resolution under Windows. You can right-click on the desktop and set your screen resolution via Gnome under OpenSolaris. It is a menu option for Ubuntu. You cannot get to it via right-click, and sometimes you really need to.
That is, without modification.
Make a
Probably the easiest program I ever wrote! And with Intrepid, I didn't have to HUP Nautilus to make it see the scripts, which is always useful.
Interesting story: Right about the time I finished that installation, I had problems with my screen setup. You see, I was bored, so I was playing with screen resolutions. My #1 monitor wants to be at 1680x1050, and due to my futzing, Gnome wouldn't let me get to anything closer than 1280x1024. Which looked like crap and kept the panels out of view.
By the way, I love multiple monitors.
Anyway, you can right-click on the desktop and set your screen resolution under Windows. You can right-click on the desktop and set your screen resolution via Gnome under OpenSolaris. It is a menu option for Ubuntu. You cannot get to it via right-click, and sometimes you really need to.
That is, without modification.
Make a
~/.gnome2/nautilus-scripts/
directory. Make a file called Screen Resolution
. Make it executable. And make it say this:
#!/bin/bash
/usr/bin/gnome-display-properties
Probably the easiest program I ever wrote! And with Intrepid, I didn't have to HUP Nautilus to make it see the scripts, which is always useful.
2008/12/09
Getting it going ....
When i worked at the other place, we used Synergy. Not the bad and byzantine source-control Synergy, but the software KVM tool.
I have a laptop that's unusable as a laptop, so it is my Windows machine. The screen is busted, so I have it connected to a big screen, and the keyboard is busted, so it's not all that much fun to use. So, I tried the power of Synergy, like I had been using at work.
And I failed.
Talking to Patrick, I figured out the issue. Synergy wants to talk names, not raw IP addresses. I had no local DNS. What few machines needed to talk to each other, I have their 192.168 addresses memorized. But Synergy wanted to work with names.
The solution?
Or
(There's no legacy BSD code involved with XP. Nope.)
So, I made the wired NIC on the laptop static, named it, and set up Synergy again. And I'm writing on my XP machine via the keyboard on one of my Ubuntu machines' keyboard.
Honestly, I have that keyboard hooked to a KVM switch going between two Ubuntu machines, but that's another story.
I have a laptop that's unusable as a laptop, so it is my Windows machine. The screen is busted, so I have it connected to a big screen, and the keyboard is busted, so it's not all that much fun to use. So, I tried the power of Synergy, like I had been using at work.
And I failed.
Talking to Patrick, I figured out the issue. Synergy wants to talk names, not raw IP addresses. I had no local DNS. What few machines needed to talk to each other, I have their 192.168 addresses memorized. But Synergy wanted to work with names.
The solution?
/etc/hosts
Or
c:\Windows\system32\drivers\etc\hosts
(There's no legacy BSD code involved with XP. Nope.)
So, I made the wired NIC on the laptop static, named it, and set up Synergy again. And I'm writing on my XP machine via the keyboard on one of my Ubuntu machines' keyboard.
Honestly, I have that keyboard hooked to a KVM switch going between two Ubuntu machines, but that's another story.
Showing the most useful piece of Catalyst documentation yet ....
Not that it is particularly useful.
Useful Test
I'm mostly going to test how to put code samples here, but if you're going to test, might as well make it useful, right?
I run Ubuntu, and I have sshfs installed. sshfs is part of FUSE, Filesystems in Userspace. What SSH allows you to do is mount the file systems on other machines via SSH.
The issue I ran into was that I wanted certain continual mounts all the time. I created a
I have two example machines to mount: Home and Work.
It could easily be set up to mount and unmount the NTFS filesystem of a dual-boot computer using
(I plan to beautify the means to dump code in the near future.)
I run Ubuntu, and I have sshfs installed. sshfs is part of FUSE, Filesystems in Userspace. What SSH allows you to do is mount the file systems on other machines via SSH.
The issue I ran into was that I wanted certain continual mounts all the time. I created a
~/Mount
directory and put the mountpoints in there, and had mounting and unmounting shell scripts. If I wanted everything, I got everything. If I just wanted to unmount and remount one, well, I had to grep for the commands I want.I have two example machines to mount: Home and Work.
mount.pl
mounts both. mount.pl -q
unmounts both. mount.pl -m Home
mounts just the Home filesystem. mount.pl -u Home
unmounts just the Home filesystem. It could easily be set up to mount and unmount the NTFS filesystem of a dual-boot computer using
ntfsmount
, or interact with Windows systems via smbmount
, or other things. Right now, it seems way too small to try to put together as a project, but if you find it useful, feel free to comment.#!/usr/bin/perl use strict ; use warnings ; use Getopt::Long ; use 5.010 ; use subs qw( mount unmount ) ; # Definition # mount.pl -- mounts all in the config # mount.pl -Q -- unmounts all in the config # mount.pl -m foo -- mounts foo, if foo is in config # mount.pl -u foo -- unmounts foo, if foo is in config # mount.pl -m foo -u bar -- mounts and unmounts can be mixed my @mount ; my @unmount ; my $unmount ; my %local ; my %remote ; my $mountprog = '/usr/bin/sshfs' ; my $unmountprog = '/bin/fusermount' ; GetOptions( 'mount=s' => \@mount, 'unmount=s' => \@unmount, 'quit' => \$unmount, ) ; while ( ) { chomp ; my $line = $_ ; next if $line !~ m{\w}mx ; my $result = ( split m{\#}mx, $line )[ 0 ] ; $line = $result ; next if $line !~ m{\w}mx ; my ( $name, $remote, $local ) = split m{\s*\|\s*}mx, $line ; $local{ $name } = $local ; $remote{ $name } = $remote ; } # UNMOUNT EVERYTHING if ( $unmount ) { for my $mount ( sort keys %local ) { unmount $mount , $local{ $mount } ; } } # MOUNT EVERYTHING elsif ( ( $#mount == -1 ) && ( $#unmount == -1 ) ) { for my $mount ( sort keys %local ) { mount $mount , $remote{ $mount }, $local{ $mount } ; } } # MIXED MOUNTS AND UNMOUNTS else { # mounts first for my $mount ( @mount ) { mount $mount , $remote{ $mount }, $local{ $mount } ; } # then unmounts for my $mount ( @unmount ) { unmount $mount , $local{ $mount } ; } } exit 0 ; sub mount { my $name = shift ; my $remote = shift ; my $local = shift ; return 0 if $name !~ /\w/mx ; return 0 if $remote !~ /\w/mx ; return 0 if $local !~ /\w/mx ; return 0 if !-d $local ; say 'Mounting ' . $name ; say qx( /usr/bin/sshfs $remote $local ) ; return 1 ; } sub unmount { my $name = shift ; my $local = shift ; return 0 if $name !~ /\w/mx ; return 0 if $local !~ /\w/mx ; return 0 if !-d $local ; say 'Unmounting ' . $name ; say qx( /bin/fusermount -u $local ) ; return 1 ; } __DATA__ # NAME | REMOTE MOUNT POINT | LOCAL MOUNT POINT Work | xxx.xxxx.xxxx.edu: | /home/rant/Mount/work Home | xxx.xxxx.xxxx.net: | /home/rant/Mount/home
(I plan to beautify the means to dump code in the near future.)
2008/12/08
2008/12/04
Considering the Vast Array of Possibility...
At the end of work today, I had a fully-functional OpenSolaris machine running under VirtualBox.
I have tried, at various points in time, to keep a Solaris x86 machine around — "But, Mom! It followed me home! Honest!" — but in the end, I always wiped it. That is, if I ever got the installation finished. Solaris has not been an easy installation.
This wasn't real. This was virtual. A virtual ISO sat in a fake CD-ROM drive and filled a phony chunk of memory full of OpenSolaris. I clicked "GO", moved to another desktop and beat my head on Catalyst and MySQL for a little while. Then, I moved back to the desktop and clicked OK, and it was done. I had my first stab at Solaris package management trying to install the "Guest" packages.
First time I sat behind a Solaris box, I was using CDE. Ever use CDE? CDE is the reason people started looking in to window managers. So they could get away from it! OpenSolaris comes with Gnome, and it's nice. Nice like the Gnome that comes with Ubuntu. And they're both Live CDs.
If the OpenSolaris user experience is, within Δ, the Ubuntu user experience, why use OpenSolaris? You want to integrate into a huge Sun environment. You develop in Java or otherwise want to have your Sun-based development environment. You're used to Sun. Or you wish to prove your manhood by grappling with the OS that was the go-to Unix when Linus was in high school.
I almost have a use for the similar XP install on my desktop. I don't really have one for OpenSolaris yet. So, what do I use it for?
I have tried, at various points in time, to keep a Solaris x86 machine around — "But, Mom! It followed me home! Honest!" — but in the end, I always wiped it. That is, if I ever got the installation finished. Solaris has not been an easy installation.
This wasn't real. This was virtual. A virtual ISO sat in a fake CD-ROM drive and filled a phony chunk of memory full of OpenSolaris. I clicked "GO", moved to another desktop and beat my head on Catalyst and MySQL for a little while. Then, I moved back to the desktop and clicked OK, and it was done. I had my first stab at Solaris package management trying to install the "Guest" packages.
First time I sat behind a Solaris box, I was using CDE. Ever use CDE? CDE is the reason people started looking in to window managers. So they could get away from it! OpenSolaris comes with Gnome, and it's nice. Nice like the Gnome that comes with Ubuntu. And they're both Live CDs.
If the OpenSolaris user experience is, within Δ, the Ubuntu user experience, why use OpenSolaris? You want to integrate into a huge Sun environment. You develop in Java or otherwise want to have your Sun-based development environment. You're used to Sun. Or you wish to prove your manhood by grappling with the OS that was the go-to Unix when Linus was in high school.
I almost have a use for the similar XP install on my desktop. I don't really have one for OpenSolaris yet. So, what do I use it for?
2008/12/02
Reading the Documentation ....
My boss has a flatbed scanner he wants to work. An HP ScanJet 3670.
I tell you the model number so that you too can do what I have done, which is look up the XSane compatability list. You will find that the 3670 is explicitly listed as not working with XSane, which means ito be non-Linux-compliant.
So, my boss suggests I dual-boot the thing. And my other boss — Boss1 can hire and fire me, but Boss2 controls the hardware I deal with on a day-to-day basis — suggests I try VirtualBox, running XP in a virtual machine under Ubuntu. I'm happy to do this, as I would much rather have most of the user software running on Linux than Windows. That's the kind of guy I am.
This process is complicated by the Thanksgiving weekend, which means that all the people I need for getting XP install media (to run in the VirtualBox) are on vacation just when I need to do it. So, finally, I get my hands on install media, get everything running, and guess what!?!
VirtualBox OSE, the open source edition, has no USB support. None. None at all.
This makes me frown.
Want to know what made me smile?
The VirtualBox License.
You can use VirtualBox, the closed, feature-rich version, if you are
Like, for example, a research lab of a large land-grand university!
So, a little apt-get here and there and I have the real VirtualBox running.
Now I just have to convince the ScanJet to talk nice. I could still be setting up a dual-boot yet.
ETA: Adding this to your /etc/fstab and restarting helped a lot, too.
Assuming you add your users into that group. Thank you, noorez!
I tell you the model number so that you too can do what I have done, which is look up the XSane compatability list. You will find that the 3670 is explicitly listed as not working with XSane, which means ito be non-Linux-compliant.
So, my boss suggests I dual-boot the thing. And my other boss — Boss1 can hire and fire me, but Boss2 controls the hardware I deal with on a day-to-day basis — suggests I try VirtualBox, running XP in a virtual machine under Ubuntu. I'm happy to do this, as I would much rather have most of the user software running on Linux than Windows. That's the kind of guy I am.
This process is complicated by the Thanksgiving weekend, which means that all the people I need for getting XP install media (to run in the VirtualBox) are on vacation just when I need to do it. So, finally, I get my hands on install media, get everything running, and guess what!?!
VirtualBox OSE, the open source edition, has no USB support. None. None at all.
This makes me frown.
Want to know what made me smile?
The VirtualBox License.
You can use VirtualBox, the closed, feature-rich version, if you are
- Using it just for yourself
- Evaluating it for your company, or
- Part of an academic institution
Like, for example, a research lab of a large land-grand university!
So, a little apt-get here and there and I have the real VirtualBox running.
Now I just have to convince the ScanJet to talk nice. I could still be setting up a dual-boot yet.
ETA: Adding this to your /etc/fstab and restarting helped a lot, too.
none /proc/bus/usb usbfs devgid=[GUID of vboxusers],devmode=0666 0 0
Assuming you add your users into that group. Thank you, noorez!
2008/11/19
Rage Taking Over ....
The current job is to create an Electronic Lab Notebook. Basically, you need to be able to access it via the web, you need to be able to link to images and import tables from Excel and the like. I started doing wiki on a UseMod wiki, so when I started rolling my own, I looked to UseMod, which was abandoned, and then to OddMuse. OddMuse has a few things I like. It's modular, it's Perl, and you don't have to use a whole host of odd modules and root access to make it work.
So, when it came time to make an Electronic Lab Notebook, I thought wiki. I thought OddMuse Wiki.
There's an add-on for tables. There's an add-on for simple image linking.
But....
The suggested WSYWIG editor is FCKeditor. And "fck!" is pretty much how I'm feeling about said editor. Because it isn't writing acceptable output, and I do not for the life of me know why.
Either that, or it isn't interpreting the saved output once the page is rendered again.
Edited To Add: That was it. The outputted wiki-text was incompatable with the wiki, so by using a module that speaks that kind of output, I got it to work. Yay me.
Specifically, I used the Markup.pl extension, in case that helps someone.
Edited To Add: Using Markup.pl kills tables.
So, when it came time to make an Electronic Lab Notebook, I thought wiki. I thought OddMuse Wiki.
There's an add-on for tables. There's an add-on for simple image linking.
But....
The suggested WSYWIG editor is FCKeditor. And "fck!" is pretty much how I'm feeling about said editor. Because it isn't writing acceptable output, and I do not for the life of me know why.
Either that, or it isn't interpreting the saved output once the page is rendered again.
Edited To Add: That was it. The outputted wiki-text was incompatable with the wiki, so by using a module that speaks that kind of output, I got it to work. Yay me.
Specifically, I used the Markup.pl extension, in case that helps someone.
Edited To Add: Using Markup.pl kills tables.
2008/10/17
Praising The Monks....
One of the topics of conversation for the last Perl Mongers meetings was Strawberry Perl. We have one or two floating laptops around here, so I decided to try to pull the existing ActiveState Perl onboard and replace it with Strawberry.
It installed ... OK. No errors, no problems, but I found it difficult to call. I could do full path —
So, I Googled. And I followed the links into Perlmonks.
And they gave me the answer.
It was to someone else's question, but there was enough to make it work.
Dunno if I'd install it on work machines (this one's about one phone call to IT from replacement) but I think I'd probably go there for my own machines.
It installed ... OK. No errors, no problems, but I found it difficult to call. I could do full path —
c:\strawberry\perl\bin\perl myprog.pl
— but they wouldn't come up as executable or even known things on the desktop or in Explorer.So, I Googled. And I followed the links into Perlmonks.
And they gave me the answer.
It was to someone else's question, but there was enough to make it work.
Dunno if I'd install it on work machines (this one's about one phone call to IT from replacement) but I think I'd probably go there for my own machines.
2008/07/29
Entering Guru Meditation ....
There's really two kinds of car computing. Computing while in the car, and computing about the car.
You could do any kind of computing in the car that you could do outside the car. Games, chat, browsing, email, playing music, reading your GPS, finding large primes, etc. This is the big place you're seeing a lot of growth. This is where Microsoft is working with Ford. The car computer will talk Bluetooth, handling your phone calls and reading tracks off your MP3 player. This is an interesting place, because car computing is either going to have to read off of car culture or computer culture.
Car culture is like this: You buy a car. It will last a few good years. It will take a few good years to pay off. And if you're still driving it ten or more years later, you can still get parts. And if you're still driving it twenty years later, you can still get parts. If it's in good shape, you can sell it for a decent amount. Old cars can be and are cool.
Computer culture is like this: You buy a computer. You own it for two years. At that time, the chip company has put out procs that are twice as fast, disc companies are making hard drives that may have as much as 10 times the storage. The video card industry might've gone to the next connector format, forcing replacement for your monitor. The hard drive industry might've gone to the next connector format, forcing replacement of your drives. Old computers are considered trash by all but the most geeky.
The big question is, how do you meld these cultures?
The questions, also big but ultimately smaller than and subsets of the above question, are as follows:
Ultimately, car computing is going to be a sub-industry or parallel industry to the car stereo industry. This is going to be an interesting thing, as it goes, but it does miss half the story. The other half of the story is computing about your car. You can read engine data via OBD II, which is built into all cars built since 1998. (I think...) What can you get from OBD II data? Honestly, I have little clue. The guys at AutoZone who plug in to read your check engine light, he uses a gadget that talks this protocol. But it isn't and shouldn't be limited to that.
Because I'm not (yet) really sure what's all there and why you'd want to know. Drivers get speed, tach, engine heat, and a few more, plus some warning lights. Do you really need pre- and post-converter oxygen sensors? If your car needs to pass an emissions test, sure. But there are a few point I could see hacking, even before I begin to study the essentials of internal combustion.
I am sure that my car is lying to me. I drive 130 miles a day, 65 there and back, to go to work. I fill up the tank on the first day, it's still reading full when I get to work, about 90% when I get back, 60% when I get to work again, then 40% when I get back home. This is not linear. Therefore, this is not accurate. My GPS says I'm at 53 when my speedometer says I'm at 55, which might just be a small tweak, but the gas gauge thing is enough to make me think.
Autotap is one place you can go to get the hardware and software you need. I know there's open source software to deal with this, but the hardware is the iffy point. But, assuming things go well with the initial pass on car computers, I'm sure that they'll have ODB II interfaces built in.
So that's reading the car information. What about writing?
Cars are computers, too. I had an ECU go bad on a car I used to drive. A 1988 Mercury Talon. 20 years ago, cars were computers. There's a market for people to swap out the ECUs of their cars. It's part of hot-rodding them today, and I don't have much more than the sketchiest idea of how it works. But, while I'm pretty sure it'll void my warranty, I still want to know how that works, because that's where car computing becomes interesting.
You could do any kind of computing in the car that you could do outside the car. Games, chat, browsing, email, playing music, reading your GPS, finding large primes, etc. This is the big place you're seeing a lot of growth. This is where Microsoft is working with Ford. The car computer will talk Bluetooth, handling your phone calls and reading tracks off your MP3 player. This is an interesting place, because car computing is either going to have to read off of car culture or computer culture.
Car culture is like this: You buy a car. It will last a few good years. It will take a few good years to pay off. And if you're still driving it ten or more years later, you can still get parts. And if you're still driving it twenty years later, you can still get parts. If it's in good shape, you can sell it for a decent amount. Old cars can be and are cool.
Computer culture is like this: You buy a computer. You own it for two years. At that time, the chip company has put out procs that are twice as fast, disc companies are making hard drives that may have as much as 10 times the storage. The video card industry might've gone to the next connector format, forcing replacement for your monitor. The hard drive industry might've gone to the next connector format, forcing replacement of your drives. Old computers are considered trash by all but the most geeky.
The big question is, how do you meld these cultures?
The questions, also big but ultimately smaller than and subsets of the above question, are as follows:
- How long until there's statutes against using AIM and the like while driving?
- People take time to customize their user environments, especially with computers. How do you set your car up for different users?
- People break into cars and take stereos all the time. How will in-car computers be made theftproof?
- Your car speaks Bluetooth, so your gadgets can talk to it and do what you want them to do. Then tech changes, and the next revision of the Bluetooth protocol comes out, and your new gadgets change but your car doesn't. What happens then? Is a networking card upgrade a warranty issue?
Ultimately, car computing is going to be a sub-industry or parallel industry to the car stereo industry. This is going to be an interesting thing, as it goes, but it does miss half the story. The other half of the story is computing about your car. You can read engine data via OBD II, which is built into all cars built since 1998. (I think...) What can you get from OBD II data? Honestly, I have little clue. The guys at AutoZone who plug in to read your check engine light, he uses a gadget that talks this protocol. But it isn't and shouldn't be limited to that.
Because I'm not (yet) really sure what's all there and why you'd want to know. Drivers get speed, tach, engine heat, and a few more, plus some warning lights. Do you really need pre- and post-converter oxygen sensors? If your car needs to pass an emissions test, sure. But there are a few point I could see hacking, even before I begin to study the essentials of internal combustion.
I am sure that my car is lying to me. I drive 130 miles a day, 65 there and back, to go to work. I fill up the tank on the first day, it's still reading full when I get to work, about 90% when I get back, 60% when I get to work again, then 40% when I get back home. This is not linear. Therefore, this is not accurate. My GPS says I'm at 53 when my speedometer says I'm at 55, which might just be a small tweak, but the gas gauge thing is enough to make me think.
Autotap is one place you can go to get the hardware and software you need. I know there's open source software to deal with this, but the hardware is the iffy point. But, assuming things go well with the initial pass on car computers, I'm sure that they'll have ODB II interfaces built in.
So that's reading the car information. What about writing?
Cars are computers, too. I had an ECU go bad on a car I used to drive. A 1988 Mercury Talon. 20 years ago, cars were computers. There's a market for people to swap out the ECUs of their cars. It's part of hot-rodding them today, and I don't have much more than the sketchiest idea of how it works. But, while I'm pretty sure it'll void my warranty, I still want to know how that works, because that's where car computing becomes interesting.
2008/07/18
This message was sent using the Picture and Video Messaging service from Verizon Wireless!
To learn how you can snap pictures and capture videos with your wireless phone visit www.verizonwireless.com/picture.
To play video messages sent to email, QuickTime® 6.5 or higher is required. Visit www.apple.com/quicktime/download to download the free player or upgrade your existing QuickTime® Player. Note: During the download process when asked to choose an installation type (Minimum, Recommended or Custom), select Minimum for faster download.
2008/05/16
2008/04/17
Playing with new software ...
I have 3 computers receiving power in my Den. I have two monitors. I use a KVM for the Linux machines, and the Windows machine (a laptop with a broken monitor and decaying keyboard) has it's own mouse and really needs a keyboard. And these, I should mention, are CRTs, not LCDs, so they monopolize lots of desk space. What's a poor geek to do?
Use Synergy!
I'm actually not using it at home. I am using it at work, typing through a desktop machine to the laptop running the browser window here. It's a soft, seamless virtual KVM. And so cool. One day soon, I shall have to get it working at home, which will be cool.
I might even get video of the mouse moving from one screen to another.
The next question is, how do you handle the real KVM with the fake KVM?
Use Synergy!
I'm actually not using it at home. I am using it at work, typing through a desktop machine to the laptop running the browser window here. It's a soft, seamless virtual KVM. And so cool. One day soon, I shall have to get it working at home, which will be cool.
I might even get video of the mouse moving from one screen to another.
The next question is, how do you handle the real KVM with the fake KVM?
2008/04/03
Coming in from the cold ...
Yeah, it's been a while.
I always find it's easier to learn a new technology if you have a use for it. So, when I learned Perl and CGI (both together), I wrote up a program to automate the docs library I was in charge of at ECN.
A while ago, I saw that Mozilla supports Scaled Vector Graphics (SVG). And that you can write them using Javascript. I said "Cool. What can I do with that."
So I put together a design as close as I could with those tools to a maple Telecaster neck. Black position dots and frets. and strings.
Then I put together functions to put dots down where scale notes and chord notes should go, so I could see and then learn scales and chords up and down the neck.
Call it the Guitar Tool.
But it has issues.
It doesn't work in IE. Only Firefox and Safari. I would only use Firefox if I could get away with it. New job says no.
I know that IE works with SVGs now. Google
BTW, I got a new job!
Also, it doesn't handle hovering. Or image maps. Or whatever technology you choose. I want to be able to mouseover a dot and have it proudly announce "C#!" or whatever note it might be.
If you have ideas or pointers on how to make any of this work, please comment.
I always find it's easier to learn a new technology if you have a use for it. So, when I learned Perl and CGI (both together), I wrote up a program to automate the docs library I was in charge of at ECN.
A while ago, I saw that Mozilla supports Scaled Vector Graphics (SVG). And that you can write them using Javascript. I said "Cool. What can I do with that."
So I put together a design as close as I could with those tools to a maple Telecaster neck. Black position dots and frets. and strings.
Then I put together functions to put dots down where scale notes and chord notes should go, so I could see and then learn scales and chords up and down the neck.
Call it the Guitar Tool.
But it has issues.
It doesn't work in IE. Only Firefox and Safari. I would only use Firefox if I could get away with it. New job says no.
I know that IE works with SVGs now. Google
SVG image maps
and you'll see examples that work on IE. But mine doesn't.BTW, I got a new job!
Also, it doesn't handle hovering. Or image maps. Or whatever technology you choose. I want to be able to mouseover a dot and have it proudly announce "C#!" or whatever note it might be.
If you have ideas or pointers on how to make any of this work, please comment.
Subscribe to:
Posts (Atom)