Wed, 05 Sep 2007

Book News: News About Books on Your Wishlist

I've created a new site at http://bookne.ws that searches blogs and Google News for references to books in an Amazon Wishlist.

It uses Amazon's E-Commerce Web Service to find a wishlist by name or email address, and to retrieve the list of books on a wishlist. Then it uses Yahoo Pipes to search for news for each of the book titles and sort the results by date. Finally, it takes the results and replaces the book titles and authors with links to pages that will return results for an individual book or author. It also uses Freebase, a sort of structured Wikipedia, to retrieve a short description of on author pages where they exist. Every page also provides an RSS feed of the results that are returned.

For example, if you use my wishlist of mostly economics books (which also happens to be the default list used at the bookne.ws homepage), you might see an except and link to an article about Nassim Taleb's Fooled by Randomness, one of the books on my list.

misc | Permanent Link

Sun, 19 Aug 2007

Best Living Economists

Amazon has a new service called Unspun that makes it easy to create "best-of" lists. People can vote on Amazon's site, and lists can be embedded in other web pages so votes can be solicited elsewhere.

I've created two lists: Best Living Economists and Best Economics Books. For the economists list, I basically just put down the economists whose blogs I read, and who I thought were especially good at Mises University. I haven't finished my list of top econ books; it's harder than I expected.



economics | Permanent Link

Fri, 10 Aug 2007

Adding Outlook/Exchange Invitations to Google Calendar from mutt

If you work with people, you have probably received meeting requests from MS Outlook/Exchange users. I used to add these to KOrganizer using korganizerIn, but I stopped using KOrganizer a long time ago, and I've been pretty happy using Google Calendar for a while. My goal was to add meeting requests to my Google Calendar. The OpenSync library provides the means for moving events between different calendar formats, and multisync-tools provide a command-line interface to the OpenSync library.

Install and configure multisync-tools.

# apt-get install multisync-tools opensync-plugin-google-calendar opensync-plugin-file
$ mkdir ~/calendar
$ echo "text/calendar;~/bin/addCalendarItem %s; needsterminal;" >> ~/.mailcap
$ msynctool --addgroup file-google
$ msynctool --addmember file-google file-sync
$ msynctool --addmember file-google google-calendar
$ msynctool --configure file-google 1

Change the contents of the <path> tag.
<config><path>/home/dir/calendar</path><recursive>FALSE</recursive></config>
$ msynctool --configure file-google 2
Replace USER@gmail.com with your Google username and PASSWORD with your password.

Create ~/bin/addCalendarItem:

#!/bin/sh

echo loading $1;
cp $1 `tempfile -d ~/calendar`
msynctool --sync file-google 2> /dev/null

Now when you get a meeting request in mutt, you can view-attachments, then view-attach (<Return>) on the meeting.ics attachment, and the meeting will be added to your Google calendar. It's not perfect. No acceptance notifications are sent. If you view a meeting request multiple times, it will be added to the calendar multiple times. Sometimes the synchronization hangs, and when you try it again, it detects conflicts between what's in your calendar directory and your Google calendar, and you have to tell it which to keep.

If I ever get the motivation, I might write a script to just add events using the Google Calendar API since I don't really need two-way synchronization.

Thanks to Trond for getting me started.

tech | Permanent Link

Tue, 22 May 2007

Buying an Audi Under Invoice

I bought Denisa a new Audi A4 a few weeks ago. The last new car I bought was my 1999 Honda Civic. When I bought that car, I think it was still relatively novel for a buyer to have looked up the invoice price on Edmunds.com so I felt relatively well-prepared to negotiate when I went into the dealer. I ended up paying $226 over invoice. I had pre-arranged financing at around 7%, but they offered me 4.9% if I'd buy a LoJack for $600, which worked out to about the same monthly payment. My car was stolen on Christmas Night, 2003, and the police helicopter found it within about an hour of when I reported it so that deal worked out alright.

This time, my strategy was to see how close I could get to invoice by going back and forth between a number of dealers. I submitted my info through Edmunds which sent it on to Keyes Audi in Van Nuys, The Auto Gallery in Woodland Hills, and Santa Monica Audi. I never talked to the Santa Monica folks, but I had quite a bit of interaction with the other two, as well as Pacific Audi who got my info through CarsDirect, I think. Most of the dealers seem to hate giving you a price over email or the phone. The Auto Gallery was the exception.

The car Denisa wanted was a black, automatic (CVT) A4 with just the Premium package, which is the cheapest package with leather seats. Invoice was $28,663. (Edmunds now shows it as $28,718 and the dollar is up slightly against the euro since I bought, but I don't know how often they update the numbers.) The Auto Gallery quote was $29,550 which I was told "is the best that I can do for you over email. If you want to talk to my Manager David over the phone, perhaps he can do better."

I stopped by Keyes that night and the woman who had emailed wasn't in so I talked to Greg Arouchanov, one of the salespeople on the floor. With a printout from Edmunds in hand, I asked what the best price he could give me on the car I wanted. He said it was basically up to me, "whatever amount over invoice I felt was fair". I left with verbal quote of invoice.

Now I was getting somewhere. I talked to David Lang from the Auto Gallery the next day on the phone. He also told me he could sell me a car at invoice, but the price he gave me was a bit higher than $28,663. I think the car he had in stock had some extra option, but I was on-site with a client and didn't have time to talk to him too long.

So now I have two dealers who will sell at invoice. Is invoice the new MSRP? Edmunds didn't show any dealer incentives or even a hold-back on Audi's. Is the published invoice price really the price dealers pay? Beats me.

I also talked to David Gentry from Pacific Audi on the phone a number of times. He told me that he could beat any other dealer's price, but wouldn't give me a number over the phone. I wasn't about to drive down to Torrance without a number so I never met David in person.

At this point, neither Denisa nor I had actually driven an Audi. So on April 23th, we went down to Keyes and drove both the A3 and A4. The A3 was more fun to drive with its fancy double clutch transmission, but Denisa wanted a grown-up car, so the A4 it was. Greg wasn't in so we talked to Daniel Mocioaca. I told him we were planning on buying a car the following Saturday, but he was pushing me for a number that would sell me on the car. I told him that I had multiple quotes at invoice, so I was just looking for the best quote under invoice. I don't know that it's a good negotiating tactic to never give a number, but I really wasn't prepared to buy the car that night; we hadn't yet sold Denisa's old car, and I needed to transfer some money into our checking account. I left encouraged when he told me he could sell me the car $500 below invoice. The cheapest black, automatic A4 with the Premium Package they had in stock also had heated seats which Daniel said he'd throw in at no charge.

A couple days later, I talked to David at Pacific Audi again. He said that he couldn't beat the Keyes price. I also emailed me David at The Auto Gallery. The best price he could give me was $28,592, $429 more than the Keyes quote, for just the Premium Package.

On Thursday, the 26th, Daniel from Keyes called and asked if I'd be willing to buy the car that day if they would give me the $2,300 I wanted for Denisa's '97 Mercury Tracer. I was pretty confident that I wasn't going to get a better deal on the A4, so whether they bought the Tracer or not, I was probably going to be buying the car from them. He wasn't willing to fax me a written quote, so I then I was thinking that they wouldn't honor the quote when I got down there. Worried that I might be wasting my time, I reluctantly drove down. The manager asked if they had to buy the Mercury, and I said that it'd be nice, but no. I ended up selling it for $2,300 the following Saturday to the first person who drove it.

They didn't have the car with heated seats any more, or they found a cheaper one to give me, but I ended up buying the car for $28,163 with the Premium Package and Sport Suspension, another option I didn't care about that had a lower invoice price than the heated seats.

The following week, I took my sales contract to The Auto Gallery to take advantage of their $200 low price guarantee. David reluctantly agreed to send me a check. A few days later I got a call from Glen Fagin at the Auto Gallery telling me that the check had been issued, but that the boss had stopped payment because I "had bought a used car". My sales contract said "used" where it should have said "new". I had noticed this before signing, but the sales manager who drafted the contract told me it was because it was a dealer transfer and wasn't in Keyes's computer yet. He was able to print out the contract with the VIN so it was in a computer, but I'm guessing the dot-matrix printer is driven by antiquated software.

So I went back to Keyes, had them draw up a new sales contract and an "Acknowledgement of Rewritten Contract", and faxed it to Glen. Glen couldn't read the fax, so I emailed him pictures I took of the documents. I received the $200 check a couple days ago.

So that's how I bought an Audi for $500 under invoice (plus sport suspension!) and made $200. I don't know that it was the most productive use of my time, and I spent way more than I would have on a car for myself, but I did feel a sense of accomplishment when it was all done.

The next time I buy a new car, I'll offer invoice, and then try to negotiate down from the best offer in $500 increments between a few dealers.

If you're in the LA area and looking for the best deal on an Audi, visit Daniel or Greg at Keyes. If you only want to negotiate over the phone or via email, contact David at the Auto Gallery.

misc | Permanent Link

Archiving Mail with Exim

I was recently asked to configure Exim to archive all mail sent and received by certain customers. Users authenticate to send mail using their email address so I used a domainlist to specify which domains' users should have their mail archived.

domainlist archive_domains = example.com

I created two routers and a transport for handling the mail sent by authenticated users. The first is a redirect router which rewrites the recipient address to a special address containing the sender's address, e.g. _!%#archive#%!_-user@example.com. This router has the unseen option set so the message is routed to the original recipient as usual. This doubles the number of recipients, but Exim discards duplicates so the final recipients are the original recipients plus the sender's archive copy. The second router strips the _!%#archive#%!_- prefix and delivers to the message to the sender's archive mailbox using a special transport.

These routers should probably be the first two since you don't want another router to accept delivery of the message first.

archive_by_sender_rewrite:
  driver = redirect
  condition = ${if and { {def:authenticated_id}{match_domain{${domain:$authenticated_id}}{+archive_domains}} }{yes}{no}}
  data = _!%#archive#%!_-$authenticated_id
  unseen
  no_repeat_use
  no_verify

archive_by_sender:
  local_part_prefix = _!%#archive#%!_-
  driver = accept
  no_verify
  transport=archive_by_sender

Because $authenticated_id is used to get the sender's address, you should have server_set_id = $1 in your authenticators so the variable gets set.

The router to archive recieved mail is pretty simple. It uses the unseen option again to create a copy of the message, and like archive_by_sender uses a separate transport to archive the message. This router should be placed before any routers that accept mail for the +archive_domains. If you use routers to discard or quarantine spam, this one should be before those if you want to archive the spam received.

archive_by_recipient:
  driver = accept
  domains = +archive_domains
  unseen
  no_verify
  transport=archive_by_recipient

Here are the transports. The messages are written to maildir directories. Any missing directories will be created if Exim has permission to create them.

archive_by_sender:
  driver = appendfile
  maildir_format
  mode = 0600
  mode_fail_narrower = false
  envelope_to_add = true
  return_path_add = true
  create_directory
  directory = /path/to/archive/$domain/$local_part/sent

archive_by_recipient:
  driver = appendfile
  maildir_format
  mode = 0600
  mode_fail_narrower = false
  envelope_to_add = true
  return_path_add = true
  create_directory
  directory = /path/to/archive/$domain/$local_part/received

If you don't have the default rule in your rcpt acl to reject local parts contains %, !, etc., you should make sure you don't accept mail for the special archive user address. Safeguarding against malicious users with shell access is left as an exercise for the reader. (Hint: I would probably look at $received_protocol.)

tech » mail | Permanent Link

Sun, 06 May 2007

Carbon, Where's Dioxide?

Why do people write and say "carbon" when talking about CO2 in discussions of global warming?

misc | Permanent Link

Tue, 20 Mar 2007

Pros and Cons of US and French Health Care Systems

Here's a homework assignment I had to do for Comparative Economic Systems. The reading assignment was Paul Dutton's Health Care in France and the United States: Learning from Each Other.

Pros and Cons of US and French Health Care Systems

The US health care system is criticized for lack of universal health insurance coverage in comparison to the French system. Because French insurance is essentially compulsory, health care costs are more broadly distributed amongst the entire population. Although laws in the US that mandate certain types of medical care be provided to uninsured (and otherwise non-paying) patients raise medical costs for the insured, these higher medical costs are borne by those others seeking medical care rather than society at large. Except for the case of highly communicable diseases, the treatment of which provides a large social benefit, this is arguably a more just outcome.

In both the US and France, patients have a number of choices in seeking medical care. In France, patients can generally get treatment from a specialist directly, whereas in the US, the growth of HMO's means that many patients must get the approval of a "primary care physician" before seeking specialized treatment. This latter system can be frustrating to patients, but may also conserve the resources of more costly medical care when the primary care physician deems it unnecessary. Patients in the US have the option of purchasing PPO insurance, which has either a higher premium or deductible, but which provides the patient with the option of seeking specialists' treatment directly. Even under an HMO, the threat of lawsuit means that all but the most trivial concerns would likely be approved for specialist review.

Differences in malpractice awards, and thus insurance premiums, contribute to widely divergent costs for medical care in the two countries. Although per capita medical spending in the US is twice that of France's, only a portion of the difference goes towards malpractice insurance and repaying debt incurred in medical school, the bill for which is footed by the government in France. Doctors enjoy much higher salaries in the US. Medical care providers have much more leeway to negotiate fee schedules with US insurance companies than their French counterparts whose negotiations occur between physician associations and the quasi-public insurance funds.

Doctors in the US may also profit from increased productivity through the use of technology when compared to French physicians. On the other hand, standardization of billing processes in France does reduce billing costs. Health care providers in either country which can both standardize and automate administrative tasks should profit by doing so.

Both the US and French health care systems suffer high costs associated from the use of "insurance" for routine medical care in which the primary beneficiary does not bear the full cost of services. Regulation also prevents insurance providers from properly pooling policies by risk group, raising insurance premiums overall. Health care systems in general would benefit from decreased regulation and a move towards a system in which insurance returns to a role of providing for contingent, devastating medical emergencies among groups for which the likelihood of such events is approximately equal.

school | Permanent Link

Mon, 19 Mar 2007

Twitter

Mat Balez predicts the demise of Twitter. Twitter is kind of a micro-blogging tool. You can post messages to Twitter over the web, IM, and SMS. These messages are then sent to people in your social network, again through IM, SMS, or the web (html or rss). The messages are limited to 140 characters, and are meant to keep your friends up to date about the minutiae in your life.

Twitter has become quite popular, but Mat thinks it will fail pretty quickly because it offers no real value beyond the novelty and is too much work. I think the real reason Twitter is likely to fail is that it suffers from network effects that bend back on themselves. Like other networking sites like MySpace and LinkedIn, the service becomes more useful as more people use it. But with Twitter, beyond a certain level, it becomes too intrusive and therefore less useful. If you have a hundred friends posting every time they refill their coffee cup, you will be inundated with twitter spam (twam?). The novelty will turn annoyance.

tech | Permanent Link

Sat, 10 Mar 2007

Old Versions of Real Player

Real Player 10 has a nicer interface than version 8, but the video quality sucks. It's very choppy. So I recommend sticking with RealPlayer 8 for now. Real doesn't make it very easy to find old versions of their software, but there they do make them available in their Legacy Software Archive. For some reason, the link to RealPlayer 8 for Linux isn't the latest version. The Debian realplayer installer package expects rp8_linux20_libc6_i386_cs2_rpm. Also available is a tarball of the RealVideo 9 Codecs for use with RealPlayer 8. These are needed to play some videos.

tech | Permanent Link

Retrieving Old Messages on Blackberry

Looking at my web stats, I saw a few visitors from Google who were looking for information on how to get old messages onto a Blackberry. Since I didn't actually have that information, I'll add it here.

Suppose you have some old messages in your IMAP inbox which have been purged from your Blackberry because they are too old, and you would like to get them back so you can reply while on the subway. Just copy them from your inbox back to your inbox. You can do this in a single action with mutt--using save will copy the messages and delete the originals. But Thunderbird doesn't seem to allow you to create a copy of messages within a folder so you will have to move (copy and delete original) the messages to another folder, and then copy them back to your inbox.

The copies will then look like new messages to the Blackberry service, and your Blackberry will download them. If, within your non-mobile MUA, your sort your inbox by date or date-then-thread (mutt's threaded mode), your inbox should appear the same as before making the copies, but if you sort your messages in the order they exist in the IMAP store (including Thunderbird's threaded mode), the copies will appear at the end (or beginning, depending on your sorting direction) of your inbox.

tech » mail | Permanent Link

Use Separate State Directory for Burp

I recently bought a RAID enclosure for my backup drives. One of the nice features is that it powers down the drives and fans when there is no activity for five minutes.

I use burp for backing up my laptops. Burp has a timed backup mode, in which a client can connect to the server, and start a backup if it's been too long since its last backup. This allows, for example, wife to suspend her laptop whenever she wants. When it is running, burp will check with the server every 20 minutes whether it needs to be backed up. If she suspends it in the middle of a backup, it will resume during the next check.

I've configured burp to only allow backups outside of my normal working hours so I don't need to hear the drives grinding away while I'm at my desk. (Pulling myself away from my desk at night is the next challenge.)

The only problem with this configuration is that when a client connects, the backup directory is accessed to figure out whether to start a backup, causing the drives in my RAID enclosure to spin up. The solution was to not have burp touch the backup directory until it's starting a backup.

When a client connects, burp creates a lockfile. By default, this lockfile is created in the backup directory, but there is an option to use a different directory, client_lockdir. Set this in the server's burp.conf.

client_lockdir=/var/run/burp

The next change required is to have the timer script, which checks whether the server should start a backup when the client asks, use a separate directory to check the state of existing backups. First, enough data from the backup directory needs to be copied to a separate directory each time a backup is completed. To do this, I use the server_script_post option, which runs a script each time a backup completes.

server_script_post=/etc/burp/update_state_dir

My update_state_dir script copies the current symlinks and timestamp files from the backup directory to a separate state directory. I updated the timer script to check this state directory. Review all of the changes at github.

tech | Permanent Link

Wed, 28 Feb 2007

Power Magnet Update

In response to my questions about using Lua and Lighttpd to serve up static blosxom pages, Tomas Carnecky sent me an email with a better way to check for an empty query string within Lua, using "if next(get) then return 1 end". Here's my new power-magnet.cml

-- if query string is empty and static file exists, serve static file
dr = request["DOCUMENT_ROOT"]
-- local f=assert(io.open(dr.."/debug.out","a"))

if next(get) then return 1 end

sn = request["SCRIPT_NAME"]

static = string.gsub(sn, '^/blog/(.*)$', '/static/%1')

if (file_isdir(dr .. static) and file_isreg(dr .. static .. "/index.html")) then
--      f:write("cache hit on directory\n")
        output_include = { dr .. static .. "/index.html" }
        return 0
elseif file_isreg(dr .. static) then
--      f:write("cache hit on file\n")
        output_include = { dr .. static }
        return 0
end

-- f:write("no cache hit\n")
return 1

tech | Permanent Link

Yahoo Pipes


Yahoo Pipes allows you to manipulate rss feeds. I built my first very simple pipe this morning. It takes the Amazon Gold Box feed and strips out the Baby Deals. You can also much fancier stuff like match geocoded addresses in feed items and modify the content of individual items. Too bad they don't provide a way to screen-scrape pages to build feeds.

If I build any more pipes, you'll be able to find them on my pipes page.

tech | Permanent Link

Sun, 04 Feb 2007

JSTOR Proxy Greasemonkey Script

I've written my first greasemonkey script, to rewrite links to JSTOR. JSTOR contains articles from tons of journals, but you need to have a subscription to access it. My university has a license, but in order to use the site remotely, you must go through the school's proxy server. So my script appends the name of your proxy server onto the jstor.org domain, in my case libaccess.sjlibrary.org.

Install the script.

Update: It now supports ieeexplore.ieee.org url's too. I knew the name would come back to bite me. I guess I'll wait to rename it until I rewrite to handle multiple domains more cleanly.

Another Update: Support for

tech | Permanent Link

Sun, 28 Jan 2007

Junk Mail Update

I've been meaning to blog about various things for a while, but everytime I think about doing so, I figure I should post an update about the Post Office, and then I get all pissed off and don't want to think about it, so I do something else. Today, an old co-worker IMed me and mentioned that he found my USPS posts amusing.

(04:45:41 PM) Andrew Arrow: your junk mail blog post is hilarious
(04:46:07 PM) Xn: i need to update it. i hate those bastards.
(04:46:20 PM) Xn: they're so evil
(04:46:47 PM) Andrew Arrow: i wrapped my wife's xmas present in shredded junk mail to re-use it
(04:49:00 PM) Xn: i filed a prohibitory order against pennysaver and advo, the two main co-conspirators of the usps, but they're still sending me crap. i'm consigned to marking out my address and dumping it all off at the post office periodically.

I filed the prohibitory orders with Dhanoa, the delivery supervisor at the Northridge post office, on December 30th. As far as I can tell, he's the only person working there that's not completely evil. He was supportive of my effort to refuse junk mail, and told me I was in the right. Ultimately, he was over-ruled by the postmaster.

I also spoke with someone from Consumer Affairs, which is supposed to be above the local postmaster on the org chart, but his only advice was to black out my address when refusing mail, as described above.

So that's where the saga stands. My prohibitory orders aren't being honored and I have a pile of junk mail on the floor that needs to be deposited in a mail receptacle. I promise that the next think I write will not be about the post office lest people that find my blog will think I'm a nutter.

Update: My wife feels that calling people evil bastards is uncouth, and that I should present a more civilized persona online lest it adversely affect my chances of getting into grad school or getting a job in the future. If, at any point in the future, you are in the role of potential employer, admissions officer, client, agent, publicist, co-author, partner, investor, shareholder, voter, professor, customer, friend, student, landlord, tenant, or undertaker, I ask that you not limit your investigation into my character to this blog post. Please consider continuing your research at Google or perhaps LinkedIn.

misc | Permanent Link

The state is that great fiction by which everyone tries to live at the expense of everyone else. - Frederic Bastiat