Project alpha: Passbook - Group management completed
Linux Tips 4: Finding out which Linux distribution and version is currently being used
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=8.04
DISTRIB_CODENAME=hardy
DISTRIB_DESCRIPTION="Ubuntu 8.04"
With Redhat and Cent OS I find the output to be just one line, but it is informative nonetheless when searching for specific configuration or administration instructions.
Linux Tips 3: Finding system files greater than a certain size
To find all files in your operating system that is greater than 2 gigabytes type:
find / -size +2000000k -printf "Size: %kK\tPath: %p\n"
This will find all files greater than 2 million kilobytes, aka 2 gigs, and print its actual size as well as where it resides so you can do something about it. You can update the script to work in the current directory only by replacing the first "/" with a "." and changing your file size filter by changing the 2000000 value.
Linux Tips 2: Password-less SSH logins
A problem that occurs when you work with SSH a lot is trying to remember all the passwords as well as making sure that your online shell accounts are safe from hackers, which normally means that long and impossible to remember passwords win out. The good news is that there is an alternative method to using passwords and that is using SSH keys. To use SSH one must first generate it on the client side computer (ie the one typing ssh example.com).
In *nix (linux, unix, OS X), type in your home directory: ssh-keygen -t rsa Just enter default values in the prompt if you are not sure what they mean. The command will create a .ssh directory in your home directory with two files. id_rsa is a file ssh uses to authenticate with, and id_rsa.pub contains the public key that you copy to servers.
For Windows users there is a guide for Putty using the Putty Key Generator.
After you have generated the key it is a simple matter of logging into your SSH server with a password for the last time. In your home directory execute the following commands to create a permission correct SSH authentication keys list.
mkdir $HOME/.ssh
touch $HOME/.ssh/authorized_keys
chmod go-w $HOME $HOME/.ssh
chmod 600 $HOME/.ssh/authorized_keys
The above commands will create a .ssh directory and create a file called authorized_keys and sets the permissions of both to something that the SSH server accepts as secure enough to use. The final step is copying your SSH key (id_rsa.pub) into the authorized_keys document. Remember that the SSH key is one line even if your default editor may have wrapped the line to make it look like four or five.
Log out of your shell account then back in to see if it works. If it does not check that the key is entered correctly and that your SSH daemon (sshd) settings are correct as well.
Dot notation array access in PHP
In an attempt to solve the problem I wrote the following function. In my Cake PHP install for Passbook I placed it in APP/config/bootstrap.php so that it is available everywhere.
// Dot notation array access
function dot(&$arr, $path = null, $checkEmpty = true, $emptyResponse = false) {
// Check path
if (!$path) user_error("Missing array path for array", E_USER_WARNING);
// Vars
$pathElements = split("\.", $path);
$path =& $arr;
// Go through path elements
foreach ($pathElements as $e) {
// Check set
if (!isset($path[$e])) return $emptyResponse;
// Check empty
if ($checkEmpty and empty($path[$e])) return $emptyResponse;
// Update path
$path =& $path[$e];
}
// Everything checked out, return value
return $path;
}
To use this function using the previous example one would simply call dot($myArr, 'key1.key2') The parameter checkEmpty allows you to specify whether you want to check if the variable is empty or not, if not the value will be returned as long as it is set. The parameter emptyResponse lets you specify what to return if the is not found or found to be empty.
Simplifying session variable access in Cake PHP
A time saving technique I use is to add the following code to my AppController. You can add this to any controller that works heavily with sessions. The code is:
function beforeFilter() {
// Get session data for appllication use
$this->app = $this->Session->read();
}
function beforeRender() {
// Make app variables available to view
$this->set('app', $this->app);
}
What the above lines do is make all your session variables available to all your controller functions in the array $this->app, so that you can quickly get values by checking $this->app['itemKey']. This is enabled by the line in beforeFilter().
The line in beforeRender() makes the session variables available in your views so that you can do checks on $app['itemKey'].
Please note that these just allow simplified access and not writing. To make sure any new session variable you write is kept you need to use $this->Session->write('key', 'value'), and because the above code basically gives us a cache of our session variables I tend to do all my session variable writing near the end of a function.
Cross browser copy to clipboard like Bit.ly
The way the Bit.ly interface is implemented looks like this:
By clicking the Copy button the shortened url is placed into the clipboard and can be pasted anywhere. By inspecting the elements surrounding that area I find the follow code:
The screen shot preview may be hard to read but it turns out that the copy button is a Flash object. This makes sense as further research showed that using pure Javascript would need browser specific code for IE, FF, etc, furthermore it is not guaranteed not to break with browser updates. With Flash the only thing one needs to worry about is Flash updates.
The main bit of Flash code used is System.setClipboard(theTextVar); The text variable can be passed into the Flash object using the flashvars variable, then it is a simple case of calling the set clipboard function on a button click or on load.
A free implementation by Jeffothy is available here. Although his sample script is designed to be variable (letting users copy using JS) so it is not as concise as Bit.ly's, which only copy their shortended url.
Project alpha: Passbook - User authentication complete
I have now done the user authentication, ie. sign in/out, as well as basic menus for authenticated and visiting users. While I was tempted to learn Cake PHP's authentication component I found it was just that much easier to implement my own. All an authentication system needs is be able to create new accounts, check whether an account name and password has a match in the database, then set a session variable. That session variable then determines whether the user has been authenticated or not.
My philosophy when dealing with frameworks is to try and use and follow framework patterns as much as possible. For me the auth component is nice but just too complex for the needs of most work I deal with. Most web applications will only have a couple of user levels and less than 100 real pages. The real determinant of access is user levels and page groups, which if done properly means all your authentication can be handled with a two or three level check.
I will blog more about my authentication methods and hopefully get some feedback about the effectiveness of my approach.
jQuery 1.3.1 released
Check if a page is loaded in an iframe using Javascript
var isInIFrame = (window.location != window.parent.location) ? true : false;
And that is it. This will work for all cases as long as your are not loading a page in an iframe of it self, which may possibly cause an infinite loop, you are fine. I have tested this in Firefox 3, Chrome 1.x and Internet Explorer 7.
Linux Tips 1: Useful .bashrc commands for managing command history and saving key strokes
The first tip I have is about ~/.bashrc, which a file in your home directory that is loaded up as soon as you login, making it useful for setting custom settings such as aliases and environment variables. If you use Bash as your shell this will be useful to you; even if you don't some commands may have equivalents. I also use these commands in .bash_profile on my OS X machine.
To start, I will introduce the bash commands are used in this tip, they are:
HISTFILESIZE=1000000000
HISTSIZE=9999
alias hs="history | grep "
PS1="[\! \u:\w] "
The first two lines of the command help you set your command line history file size and the number of commands the history file will store; you can find this file in ~/.bash_history.
If you look in .bash_history you will find many commands you previously typed. Alternatively type history in the command line to have it printed out automatically.
The third line makes use of the history command by piping it to grep and then saving that as an alias called hs. With just the first three lines you can quickly find the text that previously typed. For example when I type hs doc on my computer I get the following output:
[536 paul:~] hs Doc
503 cd Documents/
536 hs Doc
This output shows that in my command history record number 503, I typed cd Documents/ to access the documents folder. Now if I did not want to type all that again all I need to do is type !503 and the same command will be executed from where I currently am. I have used a very simple example, but the longer your command the more time this saves you.
The most regular use I have for this is when editing multiple files in Cake PHP, so I would tell ViM to edit a controller, view, and relevant Javascript file all in one command, then if I need to edit that page again I can just search for the controller name in my history and I can immediately access all relevant files.
Back to the original .bashrc file, the final fourth line allows my prompt to look like [536 paul:~], which contains both the command history number, my currently logged in account, and the file system path I am currently in. So if I wanted to repeat what I typed just then I can type !536 and be done with it.
That concludes my tip for today. Hopefully you find it useful. By the way, you can also retype a series of commands if your initial command is linked with &&. For example I often do bzr merge ../dev && bzr ci -m "Merged from development branch" to quickly bring a live version of the code I am working on up to date using Bazaar Version Control.
O'Reilly Media job cuts
Stupid Cake PHP mistakes 1: Assuming $model->create() returns true
if ($this->User->create() and $this->User->save($this->data)) {
$this->User->create()
if ($this->User->save($this->data)) {
Office 14 and the evolution of UI design
The interesting thing for me in the screenshots is the increased focus on making programs really make use of available space. The default screen for Word uses basically a 3, or 4, column layout that lets you a ton of things at once, however at the cost of pretty much requiring the user to full screen the window to perform any action.
Although everything is subject to change what does not appear to be changing anytime soon is the amount of window chrome that goes on all MS applications. As a matter of personal taste I much prefer Safari and Google Chrome's approach of keeping things as far out of the way as possible.
Project alpha: Passbook - Working copy templated, Launchpad project started
I decided to change where my project is hosted from Google Code Project Hosting to Launchpad. The problem with Google Code Project Hosting is that they limit each account to 10 projects. Launchpad on the other hand does not place such restrictions on users as well as supporting my preferred version control system: Bazaar Version Control. The registration process was quite easy and I look forward to hosting various project functions (code, bug tracking, discussions) there.
./cake/console/cake: line 30: exec: php: not found
sudo apt-get install php5-cli
jQuery 1.3 released
Project alpha: Passbook - Database design complete
Pandora on webOS development
Ubuntu founder Mark Shuttleworth featured in the New York Times
While I do not use Ubuntu in my day-to-day computing I do have a lot of respect for what Mark is trying to achieve and by putting his money where his mouth is through starting Canonical and achiving all the things that Ubuntu has done is quite a feat for someone who is already beyond successful in the for-profit sector of providing SSL certificates.
Online YUI compressor
Using McDonald's recipe for success in software development
Project alpha: Passbook - Trying to recreate Gmail AJAX status messages
<div id="notification"><span id="notifcationContent">Loading ...</span></div>
The CSS required are:
#notification { position:fixed; top:-0.2em; text-align:center; width:100%; z-index:100; }
#notificationContent { background:#FFA; padding:0.3em 1em; font-weight:bold; }
The above code segments will create a fixed top div with centered text that has a light yellow background. This status message will be shown no matter what the vertical scroll position is. It is what I am currently using for Passbook with results below:
In the initial version of Gmail the status boxes were just simple boxes, which is now understandable, as it is the easiest to implement if constant visibility is desired. However Gmail does not need a constantly visible status display as its layout is mostly contained within a normal visible window. The few occasions where you do not view the top header is if you had a long email conversation you were viewing, at which point AJAX messages are not so necessary as the available actions to the user will have an immediate effect in the GUI anyway (reply, print, etc.).
So to conclude, if you want to recreate the Gmail AJAX status messaging display you need to incorporate a static header in your design and try to minimize page scroll. If you want your AJAX status messages to be constantly visible to the user then you will need make some aesthetic concessions.
Project alpha: Passbook - Getting things done
Remember The Milk and smart date preference option design

Linode Ubuntu Mail Server: Part 2 - Setting up catch all forwarding or Google Apps for your domain with Gmail
virtual_alias_domains = example1.com example2.com
virtual_alias_maps = hash:/etc/postfix/virtual
Linode Ubuntu Mail Server: Part 1 - Setting up postfix, dovecot, and squirrelmail
<VirtualHost *>
DocumentRoot /usr/share/squirrelmail
ServerName webmail.24hourapps.com
</VirtualHost>
You can replace webmail.24hourapps.com with your desired domain name. Remember to reload Apache (use sudo /etc/init.d/apache2 reload) for it to take effect.
Project alpha: Passbook - One bit at a time
Project alpha: Passbook - The slowdown begins
Project ambitions
Blogger and Linode VPS - Part 4: Custom favicon
The first step is to create a square image. Ideally 16x16 as that is the default favicon dimensions. However any square image is technically fine for the next step.
The second step is to use a favicon generator. I used the Dynamic Drive FavIcon Generator. To create a favicon using that tool simply upload your image and then wait a few seconds for the download link.
You will now need to upload the favicon somewhere. I uploaded it to my Linode account where all blog images are hosted. However you may need to find a file host that allows direct linking if you do not have your own web hosting account. For the purposes of this article we will assume you have uploaded the file to http://www.mydomain.com/favicon.ico
The final step is add the favicon to your template. In the Layout tab in Blogger, click Edit HTML. In the Edit Template section scroll down, or find, </head>. Just above it paste the following code:
<link href='http://www.mydomain.com/favicon.ico' rel='icon' type='image/vnd.microsoft.icon'/>
The whole process is pretty simple. The only counter-intuitive thing is not using DynamicDrive's favicon inclusion sample code. It appears to be either wrong or wrong enough to not be able to override Blogger's default favicon. The code snippet above is based on what Blogger uses to add its own favicon so using that as a template means the favicon change shows up immediately.
Below is a comparison shot of the before and after icons as seen in Firefox. I have the Faviconize extension installed so no page titles are shown.
Project alpha: Passbook - Design decisions
on designing HTML mock ups. The HTML mock ups are taking much longer
than I expected as my HTML and CSS skills are quite rusty. Although I
have saved a lot of time using a template from Studio7 Designs found on
their open source templates website. While the open source templates
website was the number one results I looked through a lot of other
disappointing templates before settling on it.
The state of open source icon sets appears to much better than the
state of open source website templates with two of the top ten Google
results giving high quality usable results containing icon sets that
come with a creative commons license. I decided to use the Proxal
icon set with 40 icons as my main source due to my preference for the
artist's style and i also plan to use FAM FAM FAM's Silk icon set as a
backup for anything else that Proxal does not have.
Unfortunately about an hour was wasted as I tried a few design
development environments to see how easily they allowed me to modify
the template. Unfortunately all of them (Coda, KompoZer, and
Dreamweaver) felt like more trouble than they were worth and I ended up
sticking with good old ViM with Firefox, Firebug, and ReloadEvery.
So far I have completed about three and a quarter of the wire frames
and still have about four or five to go, which is not making things
look very good time wise as technically the first weekend of the year
is over tomorrow. However I have decided to take it a bit easier on my
self and give my self a deadline of January the 8th for a completion
date. The deadline will still be very difficult to reach as I return
to work on Monday January 5th and I am unsure whether my mental
stamina is enough to allow me to continue being productive on my hobby
project after an 8 hour work day. I guess I will find out pretty soon.
Site5 migration
Project alpha: Passbook - Wireframe design complete
I currently use Google Notebook for this task and it is not the most appropriate solution as sometimes Google tends to wipe out notes if I click on a note before the page has fully loaded. Also the auto-linking of website addresses and emails is rather unnecessary as a password keeper do not need to follow links and simply need to allow quick copying of whatever is stored.
Using Google Notebook as a model does make me appreciate just how much work is involved in streamlining that interface. My current wire frames are already loaded with CRUD access buttons that are duplicated because I use a Group->Items organization method that seems like the most simple yet useful way to organize the possibly large list of access details. The number of features that need to be implemented are quickly adding up as I draw each wire frame and I think the numbers will become even greater as I do the HTML mock ups.
Currently it does not really appear I will be able to complete the project within 24 hours. However I am hopeful that proper planning of each feature and what will get implemented in each hour will mean on time completion for this project.
Blogger and Linode VPS - Part 3: Removing unwanted Blogger icons

span.widget-item-control, span.item-control{
display:none;
}
The item-control item is for editing posts and widget-item-control is for widget controls that apply to all Blogger widgets. To restore the icons temporarily without removing the hiding code simply change none to inline.
My template only had those two icons in its contents so it may not cover all control icons. To find the class name for other control icons or elements you want hidden you will need to view the source code. In Firefox this can be done by highlighting a section of the web page, right clicking, and choosing view page source. The class name required should belong to the closest span tag near the image.
Blogger and Linode VPS - Part 2: Templates and custom domains
Blogger says that custom domains should be able to load uploaded images less than 400 pixels wide, something I am yet to test, however for templates that rule appears to be even stricter as I was unable to view any images once I updated my blog with a downloaded template. The solution is actually quite simple, although somewhat time consuming.
To fix Blogger template images not loading in custom domains you need to open the XML template file and look for referenced images by looking for either .png, .gif, .jpg, or other image formats used by the template. Once you find some images you need to download and put them on a server with less restrictive linking policies. I already set up an account on my Linode VPS for the 24 Hour Apps blog so I just saved all template images in to a folder that user's account. Then it was just a matter of adding a virtual host entry for that account, ie. blog.mydomain.com to make the image files available to the public.
The final step is to update the image references in the template XML so that they point to your saved images (see screenshot below). This is far more time consuming than it needs to be because Blogger generates extremely long and random URLs for its hosted images. After all image locations have been updated upload the modified template and everything should work as expected.