Detecting the presence of a given font in .NET
Maybe this seems obvious to other people, but I couldn't find anything in Google on it. Maybe I didn't know the right keywords to search for.
At any rate, lets say you have an application that's optimized for a specific font -- but you can't guarantee that font is installed. You might want to, as a contingency, fall-back to a different font -- maybe one that isn't quite as attractive, but that you know for sure will be present. This other font might have slightly different sizing, so in the case where you fall back, you might want to tweak your UI widgets, or alignment margins and widths, to look better if the fall-back is used. Here's my solution (C#)...
Font fnt = new Font("GoodLookinFont", 10);
if (fnt.FontFamily.Name != "GoodLookinFont")
{
//adjust display for fall-back font
}
What happens is simple: .Net attempts to create a Font object using your preferred font. If it can't find that font on the local system, it will instead create the Font object using "Microsoft Sans Serif." If the Font object's FontFamily Name is not what you expect, you know you'll have to adjust your display.
Leopard doesn’t quite stack up
I'm a Mac fan boy, and I'm very tolerant of change. When the Mac using world screamed when they replaced OS 9 with OS X, killing a lot of the nice functionality in OS 9 in favor of a brand new OS, I drank the kool-aid and made the change as soon as I could.
And I've been a big fan of each major revision of X -- and have run all of them right out of the gate, warts and all. But I'm not sold on Leopard.
The loudest touted features are either useless, or already existed in 3rd party apps for 10.4.
- Spaces is just VirtuDesktops -- and a concept I never had any use for. I'd much rather have multiple monitors then multiple "virtual" screens.
- TimeMachine is just a back-up app -- granted its well integrated and looks pretty. But the method I have in place now is much less intrusive (not to mention more fire-proof) and doesn't require me to be tethered to a local external hard drive.
But nothing bugs me more than Stacks...
Stacks kills a feature I've used and loved in OS X since they killed the Apple menu's hierarchical app-launching capabilities from OS 9.
It used to be, in OS X 10.2-10.4, that you could drop any folder onto the right side of the Dock and turn it into a menu by right clicking on it. In this way I could add my very organized Applications folder to my Dock and use it to find applications in a very simple manor (I'll admit, its kind of like a Start Menu, but come on -- its a good way to organize your apps).
In 10.5 that great feature was replaced with either a silly, and surprisingly static, curved list, or a box full of icons. Now that box can contain subfolders -- but if you click on them, it opens a window. That's a window you have to close after you find your application. Unacceptably stupid.
Know what else is stupid? Apparently there's a massive data loss bug in the new Finder. For years -- literally, we've been complaining about how awful the Finder is (even compared to its OS 9 grandparent) and this is the fix they offer us?
Damage to the Dock and a bad upgrade for the Finder aside (I do like the new sidebar, btw) Stacks are not what they were supposed to be. A "Stack" was designed as a replacement for (or addition to) the folder concept. It was an organizational item that existed in the Finder, had a single icon that could be dragged around like a file, but expanded when clicked to show a collection of items. There are plenty of UI prototype videos on the web showing what Stacks meant to us before Apple polluted the term.
I'm ditching Leopard for the time being. The only feature I really wanted was the improved Front Row... maybe there's a way I can run it in 10.4. If not, I'll just hold out hope that Apple gets their crap together with upcoming updates.
Update: Yay! It looks like they fixed stacks... a little bit!
Experiments in Virtualization
Virtualization is so hot right now... (although it can't be that hot, because my spell-checker doesn't even recognize it as a word.)
The concept is that as hardware gets faster and faster, we've actually reached the point of diminishing returns on all but the most grueling of tasks (HD Video rendering is the only other thing I've seen that really taxes a modern PC.) Now we've got hardware that can support not just one environment without breaking a sweat, but 2 or 3.
At work we have a server running VMWare's ESX Server that's currently running 16 "virtual" computers at once. None of this is that new -- what is new is the way processors are being built with this kind of thing in mind. Intel's Core2Duo is made for virtualization, and nothing proved this to me faster than Parallels Workstation.
I have a fairly recent Dell Laptop, based on a the Centrino chipset -- essentially a P4, at 1.3GHz with 2GB of RAM. It runs Windows and VisualStudio adequately. For awhile, I was given the use of a MacBook Pro, running a CoreDuo. The thing screamed running its native OS -- OS X 10.4, but when I booted up Windows XP inside a Parallels virtual machine, I was astonished to find that Windows actually ran faster virtualized on my MacBook then it did on my Dell. I used it for my day-to-day development, rendering video in one machine, while compiling code in another. And I was sold.
A colleague of mine has taken this concept to its logical extreme, and I won't pretend to have his knowledge on the subject. Rather, if you're interested, you should read his posts.
- Build Machine Virtualization discusses how he eliminated the need for frequent hardware replacement and streamlined our company's build process using VMWare.
- Development Machine Virtualization discusses how he's created specific environments for different development tasks, while still adhering to our I.T. departments onerous rules.
The latter article is the one I'd like to build on with my own thoughts here. My set-up, briefly...
I'm using a desktop computer -- not a laptop, as my afore-mentioned Dell left a bad taste in my mouth. The desktop is a Dell as well, since I.T. gives us no other choices, but despite being as ugly as sin cosmetically, its a very nice machine:
Processor: Intel Core2Duo @ 2.4Ghz with a 1Ghz FSB
RAM: 4GB @ 800Mhz (although Windows XP only recognizes 3GB)
Hard Drive: 250GB SATA II 7200RPM
Operating System: Windows XP SP2 - I.T. Core Load
The real beauty of this set-up is that the OS referred to above, which I consider to be less than satisfactory (at the least, they should have used Windows XP 64-Bit), really doesn't matter -- it could even be Ubuntu. Its only the host OS. As Shawn recommends, I'm running a very light-weight collection of apps, that I'm happy to let I.T. manage for me. I've got Windows and Office, plus a messaging client and FireFox, and various Remote Desktop/VNC clients. That's it. Add VMWare, and from here, I can have the world...

Currently I'm running two "virtual" computers running Windows XP, one running Windows Server 2003, and one running Mac OS X...
My Development VM gets 1GB of RAM, and has a 50GB pre-allocated virtual hard drive. I took a snap-shot when I started, but I realised later I could have achieved the same thing, just by copying the VM directory off to an external archive hard drive. Either way, if anything gets messed up in Windows (which, lets admit, happens fairly frequently) I can just revert the whole system to a working state with a couple mouse clicks.
My Test VM gets 512MB of RAM, more if it needs it, and a 15GB growable hard drive. This is a "clean" install of Windows XP, updated with nothing installed on it. I run the latest version of the software I'm developing on this.
Whenever I want to test how a specific build of my software behaves when installed on a customer's computer, I can snapshot back to its "clean" state, and run the Setup program.
My Server VM is a machine I took from our Green Bay office while there. They had a virtual server configured with a replica of a customer's configuration, and all I had to do was copy it to a portable hard drive and carry it with me. It has a pre-allocated hard drive, and gets 512MB of RAM -- more if needed.
My OS X VM lets me run Mail.app (my preferred mail client), PhotoShop and other nice programs that only Mac has to offer. It should be noted that performance on this machine is not stellar -- but that's only due to a lack of driver support, since Virtualizing Mac OS X is not supported.
The coolest of these virtual machines is the Development VM -- it was made from an actual physical computer. A little app called VMWare Converter can run on a machine, and create a VM out of it. So doing, I was able to switch from my old computer to my new one in a matter of hours, instead of the day or two it normally takes to get Windows, VisualStudio + Orcas, SQL Client Tools, .NET 1.0-3.0, and TortoiseSVN up and running on a fresh box.
The performance on any 3 of these machines running at the same time is equal-to, or better-than a physical computer only a year or two old. With two monitors, and an RDP connection to another headless server I have running behind me, I can juggle 5 computers at once, (6 if you count the host) with more than adequate performance.
I'll point you again to Shawn's articles if the benefits of this set-up aren't self-evident. I was initially a little unsure that the VMs would be responsive enough for my daily use, but VMWare and the Core2Duo have proven to be a stellar team...
Changing Meta Types in iTunes Files
So I'm off on a road trip next week, and I've downloaded a number of "spoken word" MP3s to listen to while I drive (it's an 8 hour trip). The only problem is that now they're mixed into my iTunes library, and when I hit shuffle on my iPod, every 3rd or 4th song will be a chapter of a book. It would be useful if iTunes would let you identify any MP3 as an "Audiobook" but they'd rather you buy your books through them, so they don't expose that functionality directly. Here's instructions on how to re-type your MP3s as Audiobooks for iTunes...
Also, if you want to re-type video, or other MP4 files -- say to turn a downloaded video into a "TV Show" check out Lostify for Mac. It won't work with AVIs though.
Enabling WebDAV on OS X
I won't re-write the article, but this weekend I wanted to turn on WebDAV on my Mac mini, and this article pretty much covered it for me. The article talks about using iCal, but do the steps and see the FAQ for additional tips on regular file sharing.
The only note I'd add is that Digest authentication didn't work for me in OS X 10.4.10 -- I had to use Basic authentication.
WordPress Hacking: Multiple Blogs On One Set of Tables
Note: This post was written for WordPress 2.1. Please see the comments for discussion on how to apply to newer versions!
I recently rolled out a new theme for my website. Normally when I do this, I do it against the live site, so there's about an hour where the site is either broken, or looks really weird while I'm working on it. This time I wanted to be a little smarter.
The goal was to build another blog -- a "test" blog where I can try out new themes and other experiments -- that pointed to the same data as the main site. This way I could get a realistic picture of what the site would actually look like before I publish an updated theme.
The more I thought about that, the more useful the concept seemed. What if I wanted an iPhone-friendly version of the site? I wouldn't want to write the same post in two places. Now eXpression could do this very easily -- since every "page" was actually a query, you could just specify a different theme file (XSL) in the query. WordPress, not so much.
What WordPress can do is allow you to specify a table prefix for each installation on a given server. That means you can have 3 blogs, each with their own set of tables. When you build your wp-config file, you tell it what prefix to use. Since this is the case, it should be fairly easy to install another instance of WordPress and point it back to the original blog tables, right? Here's how you do it...
Step 1 - Install a new instance of WordPress
- Make sure it has a unique folder name so it doesn't over-write your original blog
- Run the install pages, and give the new blog a unique table prefix
- IE: If your original blog got the default prefix: wp_ then give the new blog newwp_
- Get the blog up and running with an admin account, but don't bother posting anything
Step 2 - Point the new blog to the original blog's tables
- Modify wp-settings.php as per the instructions found here
- Modify all the table pointers EXCEPT for Options
- This means that only the Options (including Theme and Plugins) will be specific to your new site. Everything else (including Posts and Comments) will come from the original site
- So anywhere you see: $wpdb->users = $wpdb->prefix .
Change it to: $wpdb->users = 'wp_' . 'users';- where 'wp_' is the table prefix for your original blog
Step 3 - Grant the admin user from your original blog the same permissions on your new blog, by inserting two records into your wp_usermeta table:
- Where wp_ is the table prefix of your original blog and newwp_ is the table prefix of your new blog...
INSERT INTO wp_usermeta (user_id, meta_key, meta_value) VALUES (1, 'newwp_user_level, 10')INSERT INTO wp_usermeta (user_id, meta_key, meta_value) VALUES (1, 'newwp_capabilities', 'a:1:{s:13:"administrator";b:1;}')
That's it! You now have two uniquely styled blogs with the same data in them! The only thing that sucks is if you have Sidebar widgets configured, you'll need to re-configure them in your new blog as well and manually keep them in sync. That's the case for all options, and that's why this is useful.
A couple other notes:
If you want, you can delete the superfluous "new blog" tables -- just make sure you leave the Options table intact.
I have no idea how this will work during a WordPress upgrade. My current plan is to run the upgrade on the original, or base, blog, then manually change the Options table structure, if necessary, for the secondary, or derived, blogs.
Generating RSA Keypairs on Mac OS X for a *nix web-server
I'm sure there are many of you who have long been comfortable with RSA keypairs, so I post this as much for my own reference, as for those like me who stumble around the Internet trying to find coherent instructions on how to do this. These instructions work for OS X 10.4 -- not sure about other versions or *nixes. I plan to apply them to securing SSH on my iPhone for easier file transfers though.
Step 1: Open Terminal
Usually found in the Utilities folder of Applications (but if you didn't know that already, this might not be the right topic for you!)
Step 2: Create your public/private key pair on your local computer
- At the command prompt type:
ssh-keygen -t rsa - Hit enter to accept the default file name and location
Step 3: Copy your public key contents into the "authorized_keys2" file on the remote server
- Type:
ssh username@remoteserver.com 'cat >> ~/.ssh/authorized_keys2' < /Users/Youruser/.ssh/id_rsa.pub - Enter your FTP password for the remote server when prompted
- If the file didn't already exist on the remote server, it will be created, don't worry.
Step 4: SSH at will!
You will never need a password from your account on your local computer again! Note that you'll need a public key provided for each client computer/computer account you want to use to connect to the server.
Address Book vCard Publishing with AppleScript and SCP
The one piece of my .Mac replacement I've been missing is a way to publish our address book to the web. Every different web mail app has its own address book, and none of them sync with each other, with Outlook or, for me, Address Book.app -- rendering all of them useless. So I needed my own way to, in a pinch, get addresses online. vCard PHP provides the parser and renderer, but I, obviously, needed to provide the group vCard for it to show me. Enter AppleScript again.
The goal of this script was to invoke Address Book.app's Export command on all of the contacts in its database. I found a script online that exported individual vCards, so with a little modification I was able to get it to dump out a single group vCard. The next challenge was getting it up to my webserver.
I'm learning UNIX as well as AppleScript, so I was quite happy to put SCP to work. However, I hit a brick wall when trying to get AppleScript to pass in my server password. It can't do it. I searched all over the Internets, but apparently once AppleScript invokes SCP, it loses control. And SCP obviously doesn't have an AppleScript dictionary of commands. This behaviour is quite different from SSH, with which you do not lose control.
This sucked for a long time, until I finally broke down and decided to learn about RSA key pairs for authentication. I've been avoiding this for quite awhile now, because I frankly like just using a password, and I was scared of learning such an obscure new topic. But I finally figured it out -- although that's a topic for another post...
Anyway, assuming you have key pairs set up with your server, this script will do the trick. As I mentioned, it exports your Address Book to a group vCard in a given folder on your local hard machine, then SCPs the file up to a given folder on your web server. Point vCard PHP to that file, and schedule the AppleScript to run at a specific time using iCal, and you have an updated Address Book online!
Automagic
Well my previous post on Symlinks was only partially right. It turns out iTunes doesn’t work very well when it has to share its library. If either computer decides it needs to write anything to the library database, it locks the other out. I had other problems with symlinking iCal’s database — it seems to keep a cache somewhere that I can’t find. So I had to resort to some AppleScripting — maybe the most elite AppleScript I’ve ever written. Here’s everything, some scripted, some not, that our computers do automatically for us…
Media Synchronization
My uber-script runs at 1:00am on the iMac. It starts by cleaning out the downloads folder, deleting any downloaded TV shows over 21 days old, then moves any downloaded music into the appropriate folder and adds it to the local iTunes library. Then it gets really clever, and logs into the remote Home Theater Mac over SSH and begins sending it instructions. It shuts down the remote iTunes, deletes its Library (which is a data island, because we do all our media maintenance on the iMac) and copies over the iMac’s iTunes Library. Note that it copies the Library only — the music remains on a network share that both computers have access to.
Then, once both iTunes are in sync, it starts up the remote iTunes which triggers a sync with my iPhone, getting me a playlist of my most recent music, plus my favorites (I only have a 4GB so I have to manage well) and does something similar locally to sync Nic’s iPod.
Both computers use the network shared Videos folder to populate FrontRow with our movies and TV content.
Calendar Synchronization
I failed to get WebDAV up and running on my new host, and Symlinks didn’t work out. But a wonderful and free service called iCalX came to the rescue. Microsoft finally added WebDAV publishing to Outlook 2007, so I publish my work calendar from there, my personal calendar syncs from my iPhone with the Home Theater Mac and from there to iCalX, and Nic publishes her calendar from the iMac. Any WebDAV client can subscribe to them and iCalX provides a nice little PHP iCalendar view online.
Address Book Synchronization
The OS X Address Book doesn’t complain too much about sharing its library between two computers, and provides little other utility for syncing or sharing (unless you want to pay $99 a year for .Mac — an otherwise useless service). I explored lots of options, but the only unattended one is Exchange syncing (or Kerio), and I don’t want to run a mail server any more. So I finally just decided to let Address Book share. The only caveat is that to make sure Address Book’s on multiple machines match up you have to quit Address Book to dump its in-memory cache and force it to re-read the database. It was easy enough to add some quit, open and hide commands to my uber-script, and that seems to solve the problem. Putting those commands in before each iTunes syncs with its connected portable device makes sure that both the iPhone and iPod have the latest contacts.
Nic’s cell phone is still a non-Apple device, but it syncs nicely over Bluetooth. A little app called Proximity detects when she comes into range of the Home Theater Mac, and fires a tiny AppleScript that does an automatic sync for her. A little blue light on her phone is the only indicator that its even happening.
Document Backup
This is actually another potentially useful service of .Mac, but I’m too cheap to be sold that easily. A really nice online service called Mozy provides free back-ups up to 2GB, and unlimited back-up for $5 a month (sign-up with that link and get me more free space!) We just eeked in under the 2GB mark backing up all our documents. This happens automatically every Sunday night at 1:00am, in place of the usual media sync.
I’ll be taking a semi-annual physical back-up of our document, music and pictures — pictures are copied between both Macs anyway. I have yet to figure out a way to back up 280GB of videos, save for having a second hard drive stored elsewhere, but I think, in case of a fire, we can live with only losing our movie collection.
Cleaning up
After either scheduled task (media sync or back-up, depending on the night of the week) the iMac goes to sleep until 9:00am, or until called for, while the Home Theater Mac studiously downloads things it thinks we might want to watch.
My script is likely pretty unique to our set-up, but I had to search long and hard to find the various parts that make it work — sending script instructions to a remote Mac over SSH was particularly tricky — so I’m posting it here for anyone who’s interested in picking it apart.
One other thing to be aware of, much of the script works against a shared drive, so it needs to be mounted for this to work. I use a little app called Automount Maker to get my media share to mount on boot, but its possible for the volume to get dismounted during the day (our microwave interferes with our wireless, for example, because there are so many wireless networks around, and that can kill the connection). I’d love to hear any ideas on how to make sure a volume stays mounted!
How to use two or more WRT54Gs to extend a WiFi network
WDS is clumsy and hard to configure.
WiFi repeaters cost more than a router.
If you have sufficient wired network, but want to extend the range of an existing wireless router over a large area, the simplest, cheapest way to do it is with your garden variety Linksys WRT54G routers -- you don't even need to flash them to the Linux firmware.
I derived these instructions after searching all over the Internets, and I don't remember the source, so I've got to re-post them for my own reference -- and that of anyone else who wants to do this.
- Connect a computer to the new, second router. Enter the router admin page using your browser.
- Disable the DHCP server
- Change the local IP address to be in the same subnet as the primary router, but below the range assigned by it's DHCP server.
- For example, your primary router probably has a local address of 192.168.1.1 and assigns IPs in the range 192.168.1.100 to 192.168.1.150. In this case, a safe IP for you to use in your second router would be 192.168.1.2 -- this also makes it easy to find later!
- Apply the changes. (some reboots may be necessary)
- Plug your wired network into one of the standard LAN ports on the new router -- do not use the Internet/WAN port.
- Reconnect to the admin page using the new IP address you just gave it.
- Find the Advanced Routing page and change the router's operating mode from Gateway to Router.
- Configure the wireless settings of the new router to exactly match the wireless settings of your primary router (including SSID and security) but use a different wireless channel. Most sites recommend spacing out your channels by 3 or 4 to avoid interference and bleed.
- For example, if your primary router is providing wireless on Channel 6, your secondary router could safely use Channel 2 or Channel 10.
Once these steps are done, laptops will be able to roam freely between access points, and will switch, without interruption, to the strongest available signal. I've used this successfully with 2-3 routers, and have had a strong, stable wireless network since.