<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;CUQARX88fCp7ImA9WxNVFkU.&quot;"><id>tag:blogger.com,1999:blog-4614694392434779458</id><updated>2009-10-27T15:42:24.174-07:00</updated><title>Andy's Blog</title><subtitle type="html">A blog about stuff that interests me.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://blog.andydenmark.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://blog.andydenmark.com/" /><link rel="hub" href="http://pubsubhubbub.appspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Andy Denmark</name><uri>http://www.blogger.com/profile/12309610731557645322</uri><email>noreply@blogger.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>59</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><link rel="self" href="http://feeds.feedburner.com/andydenmark/andyblog" type="application/atom+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><entry gd:etag="W/&quot;D08ER344cCp7ImA9WxVVGUw.&quot;"><id>tag:blogger.com,1999:blog-4614694392434779458.post-5523467967618936556</id><published>2009-03-12T20:43:00.000-07:00</published><updated>2009-03-12T20:43:26.038-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-12T20:43:26.038-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="oauth tripit" /><title>How to Build an OAuth Consumer</title><content type="html">&lt;h1&gt;Introduction&lt;/h1&gt;&lt;p&gt;I just read a magnificent &lt;a href="http://josephsmarr.com/2009/02/17/implementing-oauth-is-still-too-hard-but-it-doesnt-have-to-be/"&gt;blog post&lt;/a&gt; from &lt;a href="http://josephsmarr.com/"&gt;Joseph Smarr&lt;/a&gt; over at &lt;a href="http://www.plaxo.com/"&gt;Plaxo&lt;/a&gt; that inspired me to share some of my experiences in helping to build and test TripIt's &lt;a href="http://www.oauth.net/"&gt;OAuth&lt;/a&gt; protected API.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;I've written this post as a guide that lets you manually walk through all of the steps an OAuth consumer must implement in order to be able to make authenticated calls to TripIt's API.  At each step of the process I've referenced a set of command line utilities that you can use to run through the examples as well as explanations for what those utilities are doing under the covers.  All of these utilities can be found in TripIt's Python binding/wrapper library here:&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;a href="http://groups.google.com/group/api_tripit/web/tripit-api-language-bindings"&gt;http://groups.google.com/group/api_tripit/web/tripit-api-language-bindings&lt;/a&gt;&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;The Python binding for the TripIt API is actually a complete OAuth consumer implementation in addition to a convenient wrapper for the TripIt API.  The command line utilities in this package enable you to conveniently execute each step of the OAuth authorization process from the command line.  I recommend you go through this process a few times by hand as it should help you (it definitely helped me) get your head around all of the different steps involved in getting a user to authorize your application.  &lt;b&gt;Note:&lt;/b&gt; executing any of these commands w/o command line arguments will print a useful usage message.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;With the specific example I walk through in this document I've included &lt;b&gt;all&lt;/b&gt; of the public and private portions of all request and access tokens as well as the consumer key and secret.  If you need to re-implement an OAuth consumer in another language you can use the inputs and outputs for each step of the process in this post to test your code to see if your code is working.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;Also, please note that the discussion is very TripIt focused.  While we implemented the provider to the specification we didn't implement everything (e.g. the only signing algorithm we built was HMAC-SHA1).&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;To frame the overall discussion, imagine the requests coming from a consumer application (Alice) and a content publisher (Bob). OAuth channels the authentication for this dialogue in a highly stylized way.&lt;br /&gt;
&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;b&gt;Alice:&lt;/b&gt; I would like to develop a TripIt application. [Registers application]&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;b&gt;Bob:&lt;/b&gt; Thanks. Here are the permanent Consumer Token and the Consumer Secret values for that application.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;b&gt;Alice:&lt;/b&gt; Now, I would like some private information from you about trips. Here is my Consumer Token and Secret. Also, since an eavesdropper might try to replay my request later, I'll also add a random Nonce and a Timestamp. Finally, I have signed this request in a very specific way.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;b&gt;Bob:&lt;/b&gt; Everything is in order here, thanks. Here is an Unauthorized Request Token, good for one use only.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;b&gt;Alice:&lt;/b&gt; The user must ok the next step. Browser, here's a url with that Unauthorized Request Token, plus a Callback URL argument.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;b&gt;Web Browser:&lt;/b&gt; Tripit, here's that URL.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;[User logs in &amp; grants access. ]&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;b&gt;Bob:&lt;/b&gt; All is good. I'm creating an Authorized Request Token, valid just for that user and your application. Now I'm redirecting to the callback URL.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;b&gt;Alice:&lt;/b&gt; Here's my Consumer Token and Secret as well as my Request Token and Secret. Give me the Authorized Request Token and matching Secret you just generated, please.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;b&gt;Bob:&lt;/b&gt; Here they are.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;b&gt;Alice:&lt;/b&gt; Sweet. All future requests from me will have the four values:&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;ul&gt;&lt;li&gt;Consumer Token&lt;/li&gt;
&lt;li&gt;Consumer Secret&lt;/li&gt;
&lt;li&gt;Authorized Request Token&lt;/li&gt;
&lt;li&gt;Authorized Request Secret&lt;/li&gt;
&lt;/ul&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Bob:&lt;/b&gt; We stand ready for all your travel information needs.&lt;br /&gt;
&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Although simplified to an extreme degree, this shows the fundamentals of the protocol.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;Before getting started I wanted to give a shout-out to my colleague Travis W. who's a very smart guy that didn't know anything about OAuth before helping me proof-read this post.  He contributed the idea for the OAuth discussion you just read and claims this run-through helped him wrap his head around how to write a consumer.  I hope he wasn't just being nice.  Let's get started!&lt;br /&gt;
&lt;/p&gt;&lt;h1&gt;Getting an Unauthorized Request Token&lt;/h1&gt;&lt;p&gt;The first step is to get an unauthorized request token.  An unauthorized request token is just a string that enables an OAuth consumer to "ask" a user to grant it an authorized access token.  To get an unauthorized request token a consumer must have a consumer key and secret.  To generate a set of these to work with the TripIt API you simply go through the process of creating an application here: &lt;a href="http://www.tripit.com/developer"&gt;http://www.tripit.com/developer&lt;/a&gt; (Note: you must have a TripIt account to do this but that's free so what's stopping you?!).&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;b&gt;IMPLEMENTATION NOTE:&lt;/b&gt; You need to store the the consumer key/secret somewhere so that your application can get to them everytime it needs to generate a new request token or obtain an authorized access token.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;For this example I'm going to use the following consumer key/secret:&lt;br /&gt;
&lt;/p&gt;&lt;table&gt;&lt;tr&gt;     &lt;th align="right"&gt;Key:&lt;/th&gt;&lt;td&gt;5dbf348aa966c5f7f07e8ce2ba5e7a3badc234bc&lt;/td&gt;   &lt;/tr&gt;
&lt;tr&gt;     &lt;th align="right"&gt;Secret:&lt;/th&gt;&lt;td&gt;fceb3aedb960374e74f559caeabab3562efe97b4&lt;/td&gt;   &lt;/tr&gt;
&lt;/table&gt;&lt;p&gt;Once you have your consumer key/secret you can use the &lt;b&gt;get_request_token.py&lt;/b&gt; command to generate a new request token like this:&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;pre class="code"&gt;$ consumer_token=5dbf348aa966c5f7f07e8ce2ba5e7a3badc234bc
$ consumer_secret=fceb3aedb960374e74f559caeabab3562efe97b4
$ python get_request_token.py https://api.tripit.com $consumer_token $consumer_secret
RESPONSE: oauth_token=df919acd38722bc0bd553651c80674fab2b46508&amp;oauth_token_secret=1370adbe858f9d726a43211afea2b2d9928ed878
  &lt;/pre&gt;&lt;/p&gt;&lt;p&gt;Here is what the &lt;b&gt;get_request_token.py&lt;/b&gt; script is doing under the covers:&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;In order to make any OAuth request a consumer must know how to properly form the request.  The first part of understanding how to form a proper request is understanding what request parameters are required.  Here is a list of all OAuth the request parameters, what they represent, and how to generate them:&lt;br /&gt;
&lt;/p&gt;&lt;ul&gt;&lt;li&gt;oauth_nonce&lt;/li&gt;
&lt;p&gt;A &lt;a href="http://en.wikipedia.org/wiki/Cryptographic_nonce"&gt;nonce&lt;/a&gt; is just a Number you use ONCE.  That's actually a bit of a     misnomer because a nonce doesn't really need to be a number at     all.  It just needs to be a random and globally unique string.     The nonce is used along with the timestamp to uniquely identify each request made to an OAuth provider and helps the provider detect whether or not an attacker is trying to "replay" an intercepted API call.  For a more in-depth description of the security risks around a replay attack check out Eran Hammer-Lahav's post on &lt;a href="http://www.hueniverse.com/hueniverse/2008/10/beginners-guide.html"&gt;OAuth security architecture&lt;/a&gt;.
&lt;/p&gt;&lt;p&gt;The OAuth consumer code in the TripIt library creates nonces using the OAuthConsumer::_generate_nonce() method from tripit.py by computing the hex form of an md5 checksum on a concatenated string that contains the current epoch time in seconds plus a string of 40 random numbers between 0 and 9.  For those who read Python:
&lt;/p&gt;&lt;pre class="code"&gt;    def _generate_nonce(self):
        random_number = ''.join(str(random.randint(0, 9)) for i in range(40))
        m = md5.new(str(time.time()) + str(random_number))
        return m.hexdigest()
  &lt;/pre&gt;&lt;p&gt;The important thing to make sure about the code you write to create the nonce is that it will not generate the same string more than once across all requests.   &lt;/p&gt;&lt;li&gt;oauth_timestamp&lt;/li&gt;
&lt;p&gt;The timestamp is just the integer representation of the number of seconds since     the &lt;a href="http://en.wikipedia.org/wiki/Unix_time"&gt;epoch&lt;/a&gt;.  It's used in conjunction with the nonce to make sure the API doesn't respond to requests that have already been made.   &lt;/p&gt;&lt;li&gt;oauth_consumer_key&lt;/li&gt;
&lt;p&gt;The consumer key is the string you obtained when you registered your application with the OAuth provider.  In TripIt's case you can do that here: &lt;a href="http://www.tripit.com/developer"&gt;http://www.tripit.com/developer&lt;/a&gt;.  In the example we are working through here the consumer key is:   &lt;/p&gt;&lt;pre class="code"&gt;5dbf348aa966c5f7f07e8ce2ba5e7a3badc234bc
  &lt;/pre&gt;&lt;li&gt;oauth_signature_method&lt;/li&gt;
&lt;p&gt;The OAuth spec allows for 3 different signing algorithms     (i.e. HMAC-SHA1, RSA-SHA1, and PLAINTEXT).  TripIt only supports HMAC-SHA1 and so that is the only signing algorithm I am going to describe in any detail.   &lt;/p&gt;&lt;li&gt;oauth_version&lt;/li&gt;
&lt;p&gt;At this time there is only one version of the OAuth specification (version 1.0).  Therefore, the value of the version parameter should be "1.0".   &lt;/p&gt;&lt;li&gt;oauth_signature&lt;/li&gt;
&lt;p&gt;The signature is where most people who are trying to make an OAuth request run in to trouble.  In order for a signature to be "valid" both the consumer and provider must implement the same &lt;a href="http://en.wikipedia.org/wiki/Digital_signature"&gt;signing algorithm&lt;/a&gt; so that when the provider re-computes a signature for a request it matches exactly the one posted to it in the request by the consumer.  If they is even a single character difference, the request will fail with a 401 "Invalid Signature" return code.&lt;/p&gt;&lt;p&gt;Here's a description of the algorithm used to generate a signature (all of this is documented in code in the tripit.py implementation of OAuthConsumer::generate_oauth_parameters() so you can follow along if you read Python):   &lt;/p&gt;&lt;ol&gt;&lt;li&gt;Collect all request parameters&lt;/li&gt;
&lt;p&gt;The first step in computing a signature is to collect all the parameters in the request.  &lt;b&gt;All&lt;/b&gt; parameters means all of the oauth_* parameters (i.e. oauth_consumer_key, oauth_nonce, oauth_timestamp, etc...) plus any parameters that are part of either the query string and/or the body of a POST request (e.g. xml= or json=).  The implementation in tripit.py simply creates a Python dictionary with all the OAuth parameters and combines those with the args in the query string (i.e. url_args) and the POST body (i.e. post_args):     &lt;/p&gt;&lt;pre class="code"&gt;parameters = self._oauth_parameters

if url_args is not None:
    parameters.update(url_args)

if post_args is not None:
    parameters.update(post_args)
    &lt;/pre&gt;&lt;li&gt;Normalize the request parameters&lt;/li&gt;
&lt;p&gt;According to the OAuth spec all request parameters must be sorted using &lt;a href="http://en.wikipedia.org/wiki/Lexicographical_order" target="_blank"&gt;lexicographical&lt;/a&gt; byte value ordering, url encoded, and then concatenated together with an '&amp;amp;' separating each value.  Here's the code from tripit.py that does this:&lt;/p&gt;&lt;pre class="code"&gt;normalized_parameters = self._escape('&amp;amp;'.join(['%s=%s' % (self._escape(str(k)), self._escape(str(parameters[k]))) for k in sorted(parameters)]))
    &lt;/pre&gt;&lt;p&gt;So, in English:
&lt;ol&gt;&lt;li&gt;Sort the parameter dictionary by key name (Note: I'm not concerned about redundantly named keys in this implementation because it's not a concern for TripIt.  If you needed to consider this the OAuth spec says sort by parameter name and for parameter names that are equivalent, sort by value)&lt;/li&gt;
&lt;li&gt;URL Encode each key/value pair&lt;/li&gt;
&lt;li&gt;Create a list of &amp;lt;key&amp;gt;=&amp;lt;value&amp;gt; pairs and join them all together with &amp;amp;'s&lt;/li&gt;
&lt;li&gt;URL encode the whole thing&lt;/li&gt;
&lt;/ol&gt;&lt;/p&gt;&lt;li&gt;Construct the signature base string&lt;/li&gt;
&lt;p&gt;Take the sorted, escaped, and concatenated list of URL parameters you just generated and prepend to it the normalized HTTP method name and URL all separated by '&amp;'.  Here's the code that generates the signature base string:
&lt;/p&gt;&lt;pre class="code"&gt;signature_base_string = '&amp;amp;'.join([normalized_http_method, normalized_http_url, normalized_parameters])
&lt;/pre&gt;&lt;p&gt;The normalized HTTP method is simply the HTTP method (i.e. GET or POST) in all caps.  The normalized HTTP URL is the resource URL in your request, URL encoded.  Here is what the signature base string looks like in this example:
&lt;/p&gt;&lt;pre class="code"&gt;POST&amp;amp;https%3A%2F%2Fapi.tripit.com%2Foauth%2Frequest_token&amp;amp;oauth_consumer_key%3D5dbf348aa966c5f7f07e8ce2ba5e7a3badc234bc%26oauth_nonce%3D39100e296c709a592600c8d1a3ee69dd%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1235272437%26oauth_version%3D1.0
    &lt;/pre&gt;&lt;li&gt;Generate a key&lt;/li&gt;
&lt;p&gt;Up until now all the consumer has done has been to format the "non-secret" portions of the request.  The consumer must now generate a key that it will ultimately use to compute the signature.  For API requests such as the one to get an unauthorized request token, the key is simply the &lt;b&gt;oauth_consumer_secret&lt;/b&gt; followed by a single '&amp;amp;'.  For API requests for protected resources that are being made after an authorized access token has been obtained, the key is the &lt;b&gt;oauth_consumer_secret&lt;/b&gt; and the authorized &lt;b&gt;oauth_token_secret&lt;/b&gt; separated by a '&amp;amp;'.  Here's what the key looks like for the request to get an unauthorized request token in this example:
&lt;/p&gt;&lt;pre class="code"&gt;fceb3aedb960374e74f559caeabab3562efe97b4&amp;amp;
    &lt;/pre&gt;&lt;li&gt;Compute the oauth_signature&lt;/li&gt;
&lt;p&gt;Once you have the signature base string and the key, it's time to compute the signature.  The signature will be sent to the provider with the request and if all goes well the provider will go through an identical set of steps to re-compute the signature.  If you did your job right, the signature string the provider computes will be an exact match for the one computed by the consumer.  TripIt only supports HMAC-SHA1 so here's some Python code that does that for you:
&lt;/p&gt;&lt;pre class="code"&gt;try:
    import hashlib
    hashed = hmac.new(key, signature_base_string, hashlib.sha1)
except:
    import sha
    hashed = hmac.new(key, signature_base_string, sha)

self._oauth_parameters['oauth_signature'] = base64.b64encode(hashed.digest())
      &lt;/pre&gt;&lt;p&gt;For our example, the value of the signature is:
&lt;/p&gt;&lt;pre class="code"&gt;KlTlU95CdzFYo5tfrJjaPz5RA6g=
      &lt;/pre&gt;&lt;/ol&gt;&lt;/ul&gt;&lt;/p&gt;&lt;p&gt;Once all the OAuth parameters are generated you will need to construct an HTTP Authorization header to send along as part of the request.  The OAuth specification says in &lt;a href="http://oauth.net/core/1.0/#auth_header"&gt;section 5.4&lt;/a&gt; that the Authorization header is the preferred authorization scheme and it's the only one that TripIt supports.  Here's what the authorization header looks like for this example:&lt;br /&gt;
&lt;/p&gt;&lt;pre class="code"&gt;Authorization: OAuth realm="https://api.tripit.com",oauth_nonce="39100e296c709a592600c8d1a3ee69dd",oauth_timestamp="1235272437",oauth_consumer_key="5dbf348aa966c5f7f07e8ce2ba5e7a3badc234bc",oauth_signature_method="HMAC-SHA1",oauth_version="1.0",oauth_signature="KlTlU95CdzFYo5tfrJjaPz5RA6g%3D"
&lt;/pre&gt;&lt;p&gt;In Python, using the urllib2 library, you add the header to the request like this:&lt;br /&gt;
&lt;/p&gt;&lt;pre class="code"&gt;request.add_header('Authorization', authorization_header);
&lt;/pre&gt;&lt;p&gt;If all goes well the server responds with an unauthorized request token as well as the unauthorized request token secret.  The consumer's job is now to have the user authorize those request tokens.  Here's what the response from the server looks like:&lt;br /&gt;
&lt;/p&gt;&lt;pre class="code"&gt;oauth_token=df919acd38722bc0bd553651c80674fab2b46508&amp;amp;oauth_token_secret=1370adbe858f9d726a43211afea2b2d9928ed878
&lt;/pre&gt;&lt;p&gt;&lt;b&gt;IMPLEMENTATION NOTE:&lt;/b&gt; You need to store these values someplace where your application can retrieve them so that you will be able to retrieve the authorized access token later on.  For this example, save the values you get from &lt;b&gt;get_request_token.py&lt;/b&gt; as you'll need them to continue following this example.&lt;br /&gt;
&lt;/p&gt;&lt;h1&gt;Authorizing an Unauthorized Request Token&lt;/h1&gt;&lt;p&gt;You've just completed the process of obtaining an unauthorized request token and secret.  This token is only good for one purpose and that is to enable the consumer to ask the user to grant it an authorized access token.  To mimic this part of the process you will need a web browser.  When building an OAuth consumer the call to TripIt's API is usually immediately followed by an HTTP redirect to the following URL:&lt;br /&gt;
&lt;/p&gt;&lt;pre class="code"&gt;https://www.tripit.com/oauth/authorize?oauth_token=df919acd38722bc0bd553651c80674fab2b46508&amp;amp;oauth_callback=http%3A%2F%2Fwww.tripit.com%2Fhome
&lt;/pre&gt;&lt;p&gt;Naturally the specific value of the oauth_token depends on what you received when you requested a request token.  The value of the oauth_callback is usually a URL in your application that implements the code I will talk about in the next section to download the authorized access token.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;To mimic the behavior of your application, just go to the above URL w/ your web browser.  Make sure to replace the value of oauth_token with whatever you got from &lt;b&gt;get_request_token.py&lt;/b&gt; in the last section!&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;If you aren't logged in to TripIt when you access the URL you will be prompted to do so.  Once logged in you'll see a screen that looks like this:&lt;br /&gt;
&lt;/p&gt;&lt;img src="http://farm4.static.flickr.com/3322/3334439310_509fea22d6_o.png" /&gt;&lt;br /&gt;
&lt;p&gt;Click the 'Grant Access' button and notice that you are redirected back to http://www.tripit.com/home (i.e. the oauth_callback URL).  The provider now has an authorized access token for your consumer and all you need to do is go and get it!&lt;br /&gt;
&lt;/p&gt;&lt;h1&gt;Obtaining the Authorized Access Token&lt;/h1&gt;&lt;p&gt;Congratulations, you're nearly ready to start querying the API!  All that's left to do is get the authorized request token and then use it.  To obtain the authorized access token the TripIt Python binding package has another utility called &lt;b&gt;get_authorized_token.py&lt;/b&gt; that can help you mimic what an OAuth consumer does to download the authorized access token after a user has clicked the 'Grant Access'&lt;br /&gt;
button on the /oauth/authorize page and has been redirected back to the consumer application.  Here's what a sample run of the &lt;b&gt;get_authorized_token.py&lt;/b&gt; utility looks like:&lt;br /&gt;
&lt;/p&gt;&lt;pre class="code"&gt;$ consumer_token=5dbf348aa966c5f7f07e8ce2ba5e7a3badc234bc
$ consumer_secret=fceb3aedb960374e74f559caeabab3562efe97b4
$ request_token=df919acd38722bc0bd553651c80674fab2b46508
$ request_token_secret=1370adbe858f9d726a43211afea2b2d9928ed878
$ python get_authorized_token.py https://api.tripit.com $consumer_token $consumer_secret $request_token $request_token_secret
RESPONSE: oauth_token=b865676c95c736c4cbb90c652cd896dec022ba86&amp;oauth_token_secret=f3ce720ebb4c0ddc3469662c246f78ef4d99f1cb
&lt;/pre&gt;&lt;p&gt;&lt;b&gt;IMPLEMENTATION NOTE:&lt;/b&gt; Save the authorized access oauth_token and oauth_token_secret values somewhere your application can get to them.  You will need them to make API calls!  It is now safe to discard the request token and token secret you obtained earlier.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;The process of getting the authorized access token is exactly the same as getting a request token except for two things.  First, the &lt;b&gt;oauth_token_secret&lt;/b&gt; of the request token is included in the request parameters and therefore in both the signature base string and the key used to sign the request.  This means that the&lt;br /&gt;
signature base string for this request looks like this:&lt;br /&gt;
&lt;/p&gt;&lt;pre class="code"&gt;POST&amp;https%3A%2F%2Fapi.tripit.com%2Foauth%2Faccess_token&amp;oauth_consumer_key%3D5dbf348aa966c5f7f07e8ce2ba5e7a3badc234bc%26oauth_nonce%3D45a4e8dc2000e5c3fb27aefeb4769326%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1235272542%26oauth_token%3Ddf919acd38722bc0bd553651c80674fab2b46508%26oauth_token_secret%3D1370adbe858f9d726a43211afea2b2d9928ed878%26oauth_version%3D1.0
&lt;/pre&gt;&lt;p&gt;Note the inclusion of the &lt;b&gt;oauth_token_secret&lt;/b&gt; parameter.  When generating the key that's used to create the &lt;b&gt;oauth_signature&lt;/b&gt; parameter it should look like this:&lt;br /&gt;
&lt;/p&gt;&lt;pre class="code"&gt;fceb3aedb960374e74f559caeabab3562efe97b4&amp;amp;1370adbe858f9d726a43211afea2b2d9928ed878
&lt;/pre&gt;&lt;p&gt;The string after the &amp;amp; is the &lt;b&gt;oauth_token_secret&lt;/b&gt; obtained along with the unauthorized request token.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;The second difference is the URL you request the authorized access token from is https://api.tripit.com/oauth/access_token.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;Aside from those two relatively minor differences, the process of requesting an authorized access token is identical to that of requesting the request token.  token.&lt;br /&gt;
&lt;/p&gt;&lt;br /&gt;
&lt;h1&gt;Using an Authorized Access Token&lt;/h1&gt;&lt;p&gt;If all went well, your application now has an authorized access token that can be used to make API calls.  While it's beyond the scope of this post to document the TripIt API, let's go through a simple example so you can see how to form an OAuth request properly.  For a complete description of all the methods and their return&lt;br /&gt;
values you should check out TripIt's API documentation.  Here:&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;a href="http://groups.google.com/group/api_tripit/web/tripit-api-documentation---v1"&gt;http://groups.google.com/group/api_tripit/web/tripit-api-documentation---v1&lt;/a&gt;&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;To form a simple request to get a user's upcoming trips you would make a GET request to the protected resource URL: https://api.tripit.com/v1/list/trip.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;To mimic this request on the command line use the &lt;b&gt;make_request.py&lt;/b&gt; utility included in the TripIt Python library.  Here's what a sample run of the &lt;b&gt;make_request.py&lt;/b&gt; utility looks like:&lt;br /&gt;
&lt;/p&gt;&lt;pre class="code"&gt;$ consumer_token=5dbf348aa966c5f7f07e8ce2ba5e7a3badc234bc
$ consumer_secret=fceb3aedb960374e74f559caeabab3562efe97b4
$ auth_token=b865676c95c736c4cbb90c652cd896dec022ba86
$ auth_token_secret=f3ce720ebb4c0ddc3469662c246f78ef4d99f1cb
$ python make_request.py https://api.tripit.com/v1/list/trip $consumer_token $consumer_secret $auth_token $auth_secret 
RESPONSE: &amp;lt;Response&amp;gt;&amp;lt;timestamp&amp;gt;1235272610&amp;lt;/timestamp&amp;gt;&amp;lt;Trip&amp;gt;&amp;lt;id&amp;gt;1180136&amp;lt;/id&amp;gt;&amp;lt;relative_url&amp;gt;/trip/show/id/1180136&amp;lt;/relative_url&amp;gt;&amp;lt;start_date&amp;gt;2010-01-21&amp;lt;/start_date&amp;gt;&amp;lt;end_date&amp;gt;2010-01-30&amp;lt;/end_date&amp;gt;&amp;lt;display_name&amp;gt;Honolulu, HI, January 2010&amp;lt;/display_name&amp;gt;&amp;lt;image_url&amp;gt;http://www.tripit.com/images/places/general.jpg&amp;lt;/image_url&amp;gt;&amp;lt;is_private&amp;gt;true&amp;lt;/is_private&amp;gt;&amp;lt;is_traveler&amp;gt;true&amp;lt;/is_traveler&amp;gt;&amp;lt;primary_location&amp;gt;Honolulu, HI&amp;lt;/primary_location&amp;gt;&amp;lt;/Trip&amp;gt;&amp;lt;/Response&amp;gt;
&lt;/pre&gt;&lt;p&gt;Under the covers, a request to a protected resource is basically the same as that to obtain an authorized access token.  By now you should be very familiar with how an OAuth request works so I'll just describe the core components used to generate the request.  Here's the signature base string:&lt;br /&gt;
&lt;/p&gt;&lt;pre class="code"&gt;GET&amp;amp;https%3A%2F%2Fapi.tripit.com%2Fv1%2Flist%2Ftrip&amp;amp;oauth_consumer_key%3D5dbf348aa966c5f7f07e8ce2ba5e7a3badc234bc%26oauth_nonce%3D720201c8b047528e4fcc119a98cffc8e%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1235272610%26oauth_token%3Db865676c95c736c4cbb90c652cd896dec022ba86%26oauth_token_secret%3Df3ce720ebb4c0ddc3469662c246f78ef4d99f1cb%26oauth_version%3D1.0
&lt;/pre&gt;&lt;p&gt;Note that since you are asking for upcoming trips and that's done via an HTTP GET to the URL https://api.tripit.com/v1/list/trip the signature base string starts out with a 'GET'.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;The key, like the one used to sign the request for an authorized access token, includes both the oauth_consumer key and authorized access token oauth_token_secret.  It should look like this:&lt;br /&gt;
&lt;/p&gt;&lt;pre class="code"&gt;fceb3aedb960374e74f559caeabab3562efe97b4&amp;amp;f3ce720ebb4c0ddc3469662c246f78ef4d99f1cb
&lt;/pre&gt;&lt;p&gt;The Authorization header should look like this:&lt;br /&gt;
&lt;/p&gt;&lt;pre class="code"&gt;Authorization: OAuth realm="https://api.tripit.com/v1/list/trip",oauth_nonce="720201c8b047528e4fcc119a98cffc8e",oauth_timestamp="1235272610",oauth_token_secret="f3ce720ebb4c0ddc3469662c246f78ef4d99f1cb",oauth_consumer_key="5dbf348aa966c5f7f07e8ce2ba5e7a3badc234bc",oauth_signature_method="HMAC-SHA1",oauth_version="1.0",oauth_token="b865676c95c736c4cbb90c652cd896dec022ba86",oauth_signature="QlHuyGIbtPNNra7qBEAcdbqQuGc%3D"
&lt;/pre&gt;&lt;p&gt;And the response will be an XML document that looks like this:&lt;br /&gt;
&lt;/p&gt;&lt;pre class="code"&gt;&amp;lt;Response&amp;gt;
    &amp;lt;timestamp&amp;gt;1235272610&amp;lt;/timestamp&amp;gt;
    &amp;lt;Trip&amp;gt;
      ... XML that describes a Trip ...
    &amp;lt;/Trip&amp;gt;
  &amp;lt;/Response&amp;gt;
&lt;/pre&gt;&lt;h1&gt;Conclusions&lt;/h1&gt;&lt;p&gt;Congratulations, you've gone through the OAuth authorization flow and learned how to build an OAuth consumer that implements that flow.  Implementing an OAuth consumer can be a slightly tedious task as there are a number of steps and all have to be executed very precisely to guarantee success.  I highly recommend that you use the command line utilities provided with the TripIt Python library and go through the process a couple of times until you really understand the order of events and what each step means before you go trying to implement an OAuth consumer on your own.  Once all of the steps are in your head, implementing them should be relatively&lt;br /&gt;
straightforward.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;Good luck!&lt;br /&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4614694392434779458-5523467967618936556?l=blog.andydenmark.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.andydenmark.com/feeds/5523467967618936556/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4614694392434779458&amp;postID=5523467967618936556" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/5523467967618936556?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/5523467967618936556?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/andydenmark/andyblog/~3/A4HpKMRWoz8/how-to-build-oauth-consumer.html" title="How to Build an OAuth Consumer" /><author><name>Andy Denmark</name><uri>http://www.blogger.com/profile/12309610731557645322</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03680920837785291524" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://blog.andydenmark.com/2009/03/how-to-build-oauth-consumer.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUYAQ3Y9cSp7ImA9WxVXE00.&quot;"><id>tag:blogger.com,1999:blog-4614694392434779458.post-7772303118597301358</id><published>2009-02-10T13:57:00.000-08:00</published><updated>2009-02-10T13:59:02.869-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-02-10T13:59:02.869-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="humor" /><title>Crypto Nerd World</title><content type="html">&lt;img src="http://imgs.xkcd.com/comics/security.png" /&gt;&lt;br /&gt;
Courtesy XKCD: &lt;a href="http://xkcd.com/538/"&gt;http://xkcd.com/538/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4614694392434779458-7772303118597301358?l=blog.andydenmark.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.andydenmark.com/feeds/7772303118597301358/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4614694392434779458&amp;postID=7772303118597301358" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/7772303118597301358?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/7772303118597301358?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/andydenmark/andyblog/~3/gxCkZeZbsPU/crypto-nerd-world.html" title="Crypto Nerd World" /><author><name>Andy Denmark</name><uri>http://www.blogger.com/profile/12309610731557645322</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03680920837785291524" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.andydenmark.com/2009/02/crypto-nerd-world.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C04DQno_fCp7ImA9WxVQGUk.&quot;"><id>tag:blogger.com,1999:blog-4614694392434779458.post-7045332775517989177</id><published>2009-02-06T09:36:00.000-08:00</published><updated>2009-02-06T09:39:33.444-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-02-06T09:39:33.444-08:00</app:edited><title>What Every American Wants to Say Right Now</title><content type="html">If every American had the same platform to talk to regulators and the folks in the last administration that were getting paid to keep an eye on things and make sure the economy didn't go off the rails due to gross negligence and corrupt behavior, this about what I imagine most of them would say.&lt;br /&gt;
&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/FOKSkaQoF_I&amp;hl=en&amp;fs=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/FOKSkaQoF_I&amp;hl=en&amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;
Absolutely classic.  I'm only slightly disappointed he restrained himself as much as he did.  Go Gary!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4614694392434779458-7045332775517989177?l=blog.andydenmark.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.andydenmark.com/feeds/7045332775517989177/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4614694392434779458&amp;postID=7045332775517989177" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/7045332775517989177?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/7045332775517989177?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/andydenmark/andyblog/~3/_RAGITFNa48/what-every-american-wants-to-say-right.html" title="What Every American Wants to Say Right Now" /><author><name>Andy Denmark</name><uri>http://www.blogger.com/profile/12309610731557645322</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03680920837785291524" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://blog.andydenmark.com/2009/02/what-every-american-wants-to-say-right.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE4EQHk6cSp7ImA9WxRUEEs.&quot;"><id>tag:blogger.com,1999:blog-4614694392434779458.post-1737593313128738631</id><published>2008-11-18T19:34:00.000-08:00</published><updated>2008-11-18T19:55:01.719-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-11-18T19:55:01.719-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="tripit presentation" /><title>AJAXWorld Presentation Finally Posted</title><content type="html">I just got around to posting my presentation from AJAXWorld.  Sorry it took so long, enjoy.&lt;br /&gt;
&lt;div style="width:425px;text-align:left" id="__ss_766413"&gt;&lt;a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/denmark/building-email-apps-presentation?type=powerpoint" title="Building Email Apps"&gt;Building Email Apps&lt;/a&gt;&lt;object style="margin:0px" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=tripitajaxworldv5-1227066606811816-9&amp;stripped_title=building-email-apps-presentation" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed src="http://static.slideshare.net/swf/ssplayer2.swf?doc=tripitajaxworldv5-1227066606811816-9&amp;stripped_title=building-email-apps-presentation" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;"&gt;View SlideShare &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/denmark/building-email-apps-presentation?type=powerpoint" title="View Building Email Apps on SlideShare"&gt;presentation&lt;/a&gt; or &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/upload?type=powerpoint"&gt;Upload&lt;/a&gt; your own. (tags: &lt;a style="text-decoration:underline;" href="http://slideshare.net/tag/ajaxworld"&gt;ajaxworld&lt;/a&gt; &lt;a style="text-decoration:underline;" href="http://slideshare.net/tag/email"&gt;email&lt;/a&gt;)&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4614694392434779458-1737593313128738631?l=blog.andydenmark.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.andydenmark.com/feeds/1737593313128738631/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4614694392434779458&amp;postID=1737593313128738631" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/1737593313128738631?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/1737593313128738631?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/andydenmark/andyblog/~3/RepaFZD2H-w/ajaxworld-presentation-finally-posted.html" title="AJAXWorld Presentation Finally Posted" /><author><name>Andy Denmark</name><uri>http://www.blogger.com/profile/12309610731557645322</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03680920837785291524" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.andydenmark.com/2008/11/ajaxworld-presentation-finally-posted.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0YHRX0zeip7ImA9WxRWEks.&quot;"><id>tag:blogger.com,1999:blog-4614694392434779458.post-7975247114156568741</id><published>2008-10-28T23:18:00.001-07:00</published><updated>2008-10-28T23:18:54.382-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-10-28T23:18:54.382-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="humor" /><title>I Screwed Up and I'm Sorry</title><content type="html">&lt;object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="360" height="300"&gt;&lt;param name="AllowScriptAccess" value="always" /&gt;&lt;param name="movie" value="http://s3.moveon.org/swf/embed.swf"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="FlashVars" value="id=QRth7Ox1EI6ZTSe1q21rkzU1ODQxMjA-"&gt;&lt;/param&gt;&lt;embed FlashVars="id=QRth7Ox1EI6ZTSe1q21rkzU1ODQxMjA-" src="http://s3.moveon.org/swf/embed.swf" type="application/x-shockwave-flash" allowfullscreen="true" AllowScriptAccess="always" width="360" height="300"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4614694392434779458-7975247114156568741?l=blog.andydenmark.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.andydenmark.com/feeds/7975247114156568741/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4614694392434779458&amp;postID=7975247114156568741" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/7975247114156568741?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/7975247114156568741?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/andydenmark/andyblog/~3/1d4PPBYUefs/i-screwed-up-and-im-sorry.html" title="I Screwed Up and I'm Sorry" /><author><name>Andy Denmark</name><uri>http://www.blogger.com/profile/12309610731557645322</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03680920837785291524" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.andydenmark.com/2008/10/i-screwed-up-and-im-sorry.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkYASHY9fSp7ImA9WxRXFEU.&quot;"><id>tag:blogger.com,1999:blog-4614694392434779458.post-120595946278969202</id><published>2008-10-19T22:19:00.000-07:00</published><updated>2008-10-19T22:22:29.865-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-10-19T22:22:29.865-07:00</app:edited><title>Speaking at AJAX World Tomorrow</title><content type="html">I'll be at &lt;a href="http://ajaxworld.com/event/session/32"&gt;AJAX World&lt;/a&gt; tomorrow talking about email and how to build compelling applications on top of it.  Should be fun, if you're there, please stop by!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4614694392434779458-120595946278969202?l=blog.andydenmark.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.andydenmark.com/feeds/120595946278969202/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4614694392434779458&amp;postID=120595946278969202" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/120595946278969202?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/120595946278969202?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/andydenmark/andyblog/~3/OwVV-IiQWdQ/speaking-at-ajax-world-tomorrow.html" title="Speaking at AJAX World Tomorrow" /><author><name>Andy Denmark</name><uri>http://www.blogger.com/profile/12309610731557645322</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03680920837785291524" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.andydenmark.com/2008/10/speaking-at-ajax-world-tomorrow.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D08GQnY7cCp7ImA9WxRRGU8.&quot;"><id>tag:blogger.com,1999:blog-4614694392434779458.post-4308414085298576877</id><published>2008-10-01T22:22:00.000-07:00</published><updated>2008-10-01T22:37:03.808-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-10-01T22:37:03.808-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="tripit" /><title>TripIt Blog Badge</title><content type="html">&lt;a href="http://www.tripit.com/"&gt;TripIt&lt;/a&gt; launched a new blog badge a few weeks ago.  I installed it on my blog (of course!) and even though I am biased, I think it looks really nice and is a great way for you to keep your readers up to date with your travel schedule even if they don't have a TripIt account.  If you do have a TripIt account just go &lt;a href="http://www.tripit.com/account/edit/section/publishing_options"&gt;here&lt;/a&gt; and enable the blog badge.  If you don't have a TripIt account and you travel a lot, what are you waiting for?  Go &lt;a href="http://www.tripit.com/account/create"&gt;sign up&lt;/a&gt;!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4614694392434779458-4308414085298576877?l=blog.andydenmark.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.andydenmark.com/feeds/4308414085298576877/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4614694392434779458&amp;postID=4308414085298576877" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/4308414085298576877?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/4308414085298576877?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/andydenmark/andyblog/~3/VM3vHupC5sw/check-out-my-blog-badge.html" title="TripIt Blog Badge" /><author><name>Andy Denmark</name><uri>http://www.blogger.com/profile/12309610731557645322</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03680920837785291524" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.andydenmark.com/2008/10/check-out-my-blog-badge.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEADSHY6cCp7ImA9WxdbFkU.&quot;"><id>tag:blogger.com,1999:blog-4614694392434779458.post-1132717909353481913</id><published>2008-08-13T19:50:00.000-07:00</published><updated>2008-08-13T19:59:39.818-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-08-13T19:59:39.818-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="tripit plugs" /><title>Win an iPhone Because I Can't</title><content type="html">WARNING: this is a shameless plug for &lt;a href="http://www.tripit.com/promo/referSummary"&gt;TripIt&lt;/a&gt;, but what the hell.&lt;br /&gt;
&lt;br /&gt;
We just launched a "contest" in which you can refer friends to TripIt and be entered into a drawing for some pretty cool prizes.  The more friends you refer, the more chances you have to win!  The grand prize is a brand-spankin' new 3G iPhone.  Unfortunately, I'm not qualified to win and even if could win everyone I know already uses TripIt anyway. :)&lt;br /&gt;
&lt;br /&gt;
So, tell a lot of people about TripIt often!&lt;br /&gt;
&lt;br /&gt;
For more details follow this link:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.tripit.com/promo/referSummary"&gt;http://www.tripit.com/promo/referSummary&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4614694392434779458-1132717909353481913?l=blog.andydenmark.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.andydenmark.com/feeds/1132717909353481913/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4614694392434779458&amp;postID=1132717909353481913" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/1132717909353481913?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/1132717909353481913?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/andydenmark/andyblog/~3/U1hAifTlKFs/win-iphone-because-i-cant.html" title="Win an iPhone Because I Can't" /><author><name>Andy Denmark</name><uri>http://www.blogger.com/profile/12309610731557645322</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03680920837785291524" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.andydenmark.com/2008/08/win-iphone-because-i-cant.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D04HRn45fCp7ImA9WxdbEkw.&quot;"><id>tag:blogger.com,1999:blog-4614694392434779458.post-6097076173170634181</id><published>2008-08-08T10:18:00.001-07:00</published><updated>2008-08-08T10:18:57.024-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-08-08T10:18:57.024-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="humor" /><title>The Rise and Fall of Twitter</title><content type="html">I was highly offended and thought it best to share. :)&lt;br /&gt;
&lt;br /&gt;
&lt;embed src="http://blip.tv/play/ih_F3GmJ5FQ" type="application/x-shockwave-flash" width="540" height="335" allowscriptaccess="always" allowfullscreen="true"&gt;&lt;/embed&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4614694392434779458-6097076173170634181?l=blog.andydenmark.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.andydenmark.com/feeds/6097076173170634181/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4614694392434779458&amp;postID=6097076173170634181" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/6097076173170634181?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/6097076173170634181?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/andydenmark/andyblog/~3/AN2D8bg3Okw/rise-and-fall-of-twitter.html" title="The Rise and Fall of Twitter" /><author><name>Andy Denmark</name><uri>http://www.blogger.com/profile/12309610731557645322</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03680920837785291524" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.andydenmark.com/2008/08/rise-and-fall-of-twitter.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0ANQHc9fip7ImA9WxdVGEo.&quot;"><id>tag:blogger.com,1999:blog-4614694392434779458.post-3739080416782761126</id><published>2008-07-23T22:02:00.000-07:00</published><updated>2008-07-23T22:03:11.966-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-07-23T22:03:11.966-07:00</app:edited><title>The Last Journey of a Genius</title><content type="html">Pure genius.  I hope you all enjoy it as much as I did.&lt;br /&gt;
&lt;br /&gt;
&lt;embed id="VideoPlayback" style="width:400px;height:326px" allowFullScreen="true" src="http://video.google.com/googleplayer.swf?docid=3164300309410618119&amp;hl=en&amp;fs=true" type="application/x-shockwave-flash"&gt; &lt;/embed&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4614694392434779458-3739080416782761126?l=blog.andydenmark.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.andydenmark.com/feeds/3739080416782761126/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4614694392434779458&amp;postID=3739080416782761126" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/3739080416782761126?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/3739080416782761126?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/andydenmark/andyblog/~3/zt0C3Woym4s/last-journey-of-genius.html" title="The Last Journey of a Genius" /><author><name>Andy Denmark</name><uri>http://www.blogger.com/profile/12309610731557645322</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03680920837785291524" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.andydenmark.com/2008/07/last-journey-of-genius.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0QNR349fSp7ImA9WxdSEUs.&quot;"><id>tag:blogger.com,1999:blog-4614694392434779458.post-5757338181176784428</id><published>2008-05-18T18:41:00.000-07:00</published><updated>2008-05-18T18:43:16.065-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-05-18T18:43:16.065-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="humor" /><title>Obviously This Show Needs to Get Made</title><content type="html">&lt;object width="510" height="295"&gt;&lt;param name="movie" value="http://www.hulu.com/embed/5Xue-d6aY1WzOs__zjVFJA"&gt;&lt;/param&gt;&lt;embed src="http://www.hulu.com/embed/5Xue-d6aY1WzOs__zjVFJA" type="application/x-shockwave-flash"  width="510" height="295"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4614694392434779458-5757338181176784428?l=blog.andydenmark.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.andydenmark.com/feeds/5757338181176784428/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4614694392434779458&amp;postID=5757338181176784428" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/5757338181176784428?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/5757338181176784428?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/andydenmark/andyblog/~3/lRRIh83XUnI/obviously-this-show-needs-to-get-made.html" title="Obviously This Show Needs to Get Made" /><author><name>Andy Denmark</name><uri>http://www.blogger.com/profile/12309610731557645322</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03680920837785291524" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.andydenmark.com/2008/05/obviously-this-show-needs-to-get-made.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkcFSXk5fCp7ImA9WxZaF0k.&quot;"><id>tag:blogger.com,1999:blog-4614694392434779458.post-3863195988030667274</id><published>2008-05-01T21:29:00.000-07:00</published><updated>2008-05-02T09:00:18.724-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-05-02T09:00:18.724-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="tripit email greasemonkey" /><title>Fun with GreaseMonkey and the Future of Email Apps</title><content type="html">A few months ago I hacked (I mean literally hacked, it ain't pretty :) up a little &lt;a href="http://www.greasespot.net/"&gt;GreaseMonkey&lt;/a&gt; script called &lt;a href="http://userscripts.org/scripts/show/25778"&gt;TripIt For GMail&lt;/a&gt;.  The idea was to play around with the concept of embedding TripIt functionality inside a mail client.  Since the GMail team are supporters of GreaseMonkey and have created an &lt;a href="http://code.google.com/p/gmail-greasemonkey/wiki/GmailGreasemonkey10API"&gt;"API"&lt;/a&gt; for GreaseMonkey scripts within the GMail UI I decided to start there.&lt;br /&gt;&lt;br /&gt;&lt;div style="float: right;"&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/andydenmark/2454347765/" title="add_to_tripit by andydenmark, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2087/2454347765_3ee122eb23_o.jpg" width="110" height="119" alt="add_to_tripit" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;The script is extremely simple.  All it does is embed an 'Add to TripIt' button in the right hand column of the GMail web UI.&lt;br /&gt;&lt;br /&gt;Currently the script does not even attempt to decide whether or not the email you are looking at is a travel confirm (that's something one could imagine adding pretty easily).  Also, because it's just a GreaseMonkey script and not a true application running inside of GMail it doesn't have access to the source of the mail message and therefore needs to automate the actions of a user clicking on the 'Forward' button, typing in plans@tripit.com and hitting 'Send'.  Clever, but not how I really want to build this app.&lt;br /&gt;&lt;br /&gt;I haven't had much time to work on the script since January as I've been pretty busy but I did just post it to &lt;a href="http://userscripts.org/"&gt;UserScripts&lt;/a&gt; &lt;a href="http://userscripts.org/scripts/show/25778"&gt;here&lt;/a&gt; for anyone who is interested in playing around with it.  It's only been tested on Firefox 2 on Linux, Windows, and Mac so if you're using FF3 or FF1 your mileage may vary.&lt;br /&gt;&lt;br /&gt;More important than the actual implementation of this script is the direction I see email clients and platforms heading.  Imagine an email system that is smart enough to detect what you were looking at and automatically do intelligent stuff for you.  In the use case that is currently near and dear to my heart the system figures out that the email you are looking at (or maybe you don't even have to look at it :) is a travel confirmation, sends the source of that email to TripIt (ideally via a RESTful API authenticated via &lt;a href="http://www.oauth.org/"&gt;oAuth&lt;/a&gt;) so that a beautifully formatted itinerary gets created for you.  Take that one step further and imagine the email platform re-consuming that data from TripIt in any one of a number of forms (e.g. iCalendar, RSS/Atom, API, etc...) so that all of it is re-integrated into your suite of productivity web/desktop apps in semantically intelligent ways.  The system should do all the work for you so you can focus on where you're going and what you have to accomplish once you get there (i.e. your "real" work).&lt;br /&gt;&lt;br /&gt;In the travel space TripIt has been driving the use of email as a critical component of what I humbly think is a very useful social travel organizer for folks who travel.  Beyond travel however, there are tons of useful applications (both social *and* non-social) for this kind of intelligent platform and trying to inspire folks to create these applications was a focus of &lt;a href="http://www.slideshare.net/denmark/web-20-making-email-a-useful-web-app/"&gt;my talk&lt;/a&gt; at the Web 2.0 Expo here in San Francisco.&lt;br /&gt;&lt;br /&gt;I think the message is getting through and I think folks are finally realizing that email always has been and continues to be a great interface to systems, humans, and your data.  Folks such as &lt;a href="http://thenextweb.org/2008/04/24/tripit-email-is-the-new-interface/"&gt;Boris Veldhuijzen van Zanten&lt;/a&gt; over at NextWeb, &lt;a href="http://oracleappslab.com/2008/05/01/more-web-20-expo-worth-the-time-investment/"&gt;Jake Kuramoto&lt;/a&gt; at Oracle, and &lt;a href="http://www.techcrunch.com/2008/04/30/zenbe-next-generation-webmail-with-a-platform-twist/"&gt;Mark Hendrickson&lt;/a&gt; at TechCrunch understand and have talked about the possibilities.&lt;br /&gt;&lt;br /&gt;The time is right, and long overdue, for intelligent apps built on top of good old fashioned, ubiquitous, and highly scalable email to begin seeing the light of day.  In the coming months I hope we start to see companies like Yahoo and Google open up their mail platforms and turn them into application platforms.  We've already seen Yahoo begin opening up their search results page with &lt;a href="http://developer.yahoo.com/searchmonkey/preview.html"&gt;SearchMonkey&lt;/a&gt; and the best &lt;a href="http://cosmos.bcst.yahoo.com/up/player/popup/?cl=7546019"&gt;information&lt;/a&gt; is that he rest of Yahoo, including mail, is going in that direction as well.&lt;br /&gt;&lt;br /&gt;In smaller ways it appears as if this trend is already beginning with the beta launch of webmail provider &lt;a href="http://www.zenbe.com/"&gt;Zenbe&lt;/a&gt;.  I haven't actually seen the Zenbe yet but if it works as advertised, this is a great model for where mail platforms should be going.  There are also companies such as &lt;a href="http://www.xobni.com/"&gt;Xobni&lt;/a&gt; who are nicely positioned to chip away at this problem from the client side of what is probably the most widely deployed email platform in the world (at least in corporate settings), Outlook/Exchange.  It would be nice if Microsoft's Exchange group were focused on this but so far I've seen no indication from the sleepy giant in Redmond that they are thinking along these lines.  Of course there are a lot of smart folks up there so I wouldn't be surprised if someone is trying to fight what must be a significant amount of corporate inertia to get this done, who knows.  It's definitely a huge opportunity for them given their dominant market position in corporate email infrastructure.&lt;br /&gt;&lt;br /&gt;I can't wait to see this continue to unfold, it's going to be an interesting year!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4614694392434779458-3863195988030667274?l=blog.andydenmark.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.andydenmark.com/feeds/3863195988030667274/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4614694392434779458&amp;postID=3863195988030667274" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/3863195988030667274?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/3863195988030667274?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/andydenmark/andyblog/~3/bmU77W1Ux9k/fun-with-greasemonkey-and-future-of.html" title="Fun with GreaseMonkey and the Future of Email Apps" /><author><name>Andy Denmark</name><uri>http://www.blogger.com/profile/12309610731557645322</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03680920837785291524" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">6</thr:total><feedburner:origLink>http://blog.andydenmark.com/2008/05/fun-with-greasemonkey-and-future-of.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0EFQ3k4fCp7ImA9WxZaEko.&quot;"><id>tag:blogger.com,1999:blog-4614694392434779458.post-8373473993961737832</id><published>2008-04-26T18:46:00.000-07:00</published><updated>2008-04-26T22:53:32.734-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-04-26T22:53:32.734-07:00</app:edited><title>Ooops...</title><content type="html">&lt;a href="http://www.flickr.com/photos/andydenmark/2443985997/" title="IMG_2129 by andydenmark, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2141/2443985997_f6732d6ace.jpg" width="500" height="333" alt="IMG_2129" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4614694392434779458-8373473993961737832?l=blog.andydenmark.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.andydenmark.com/feeds/8373473993961737832/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4614694392434779458&amp;postID=8373473993961737832" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/8373473993961737832?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/8373473993961737832?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/andydenmark/andyblog/~3/GuST3MEZLC8/ooops.html" title="Ooops..." /><author><name>Andy Denmark</name><uri>http://www.blogger.com/profile/12309610731557645322</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03680920837785291524" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.andydenmark.com/2008/04/ooops.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEMBRX8yfSp7ImA9WxdbFkQ.&quot;"><id>tag:blogger.com,1999:blog-4614694392434779458.post-1608309386939232574</id><published>2008-04-25T09:12:00.001-07:00</published><updated>2008-08-13T22:40:54.195-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-08-13T22:40:54.195-07:00</app:edited><title>Web 2.0 Presentation</title><content type="html">I made the slides for my &lt;a href="http://en.oreilly.com/webexsf2008/public/content/home"&gt;Web 2.0 Expo&lt;/a&gt; preso available via &lt;a href="http://www.slideshare.net/denmark/web-20-making-email-a-useful-web-app"&gt;Slideshare&lt;/a&gt; and embedded them on the &lt;a href="http://blog.tripit.com/2008/04/web-20-expo-mak.html"&gt;TripIt blog&lt;/a&gt;.  Enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4614694392434779458-1608309386939232574?l=blog.andydenmark.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.andydenmark.com/feeds/1608309386939232574/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4614694392434779458&amp;postID=1608309386939232574" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/1608309386939232574?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/1608309386939232574?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/andydenmark/andyblog/~3/RffIRZvzF0g/web-20-presentation.html" title="Web 2.0 Presentation" /><author><name>Andy Denmark</name><uri>http://www.blogger.com/profile/12309610731557645322</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03680920837785291524" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.andydenmark.com/2008/04/web-20-presentation.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU4DQXo9eSp7ImA9WxZbGEk.&quot;"><id>tag:blogger.com,1999:blog-4614694392434779458.post-6416544452308866936</id><published>2008-04-21T23:55:00.000-07:00</published><updated>2008-04-22T00:06:10.461-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-04-22T00:06:10.461-07:00</app:edited><title>Speaking at Web 2.0 Expo</title><content type="html">If you'll be attending &lt;a href="http://en.oreilly.com/webexsf2008/public/content/home"&gt;Web 2.0 Expo&lt;/a&gt; in San Francisco, I will be giving a talk entitled &lt;a href="http://en.oreilly.com/webexsf2008/public/schedule/detail/2379"&gt;Making Email a Useful Web App&lt;/a&gt; on Wednesday (4/23).  Should be a fun, and I hope informative, discussion.  Drop by if you can!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4614694392434779458-6416544452308866936?l=blog.andydenmark.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.andydenmark.com/feeds/6416544452308866936/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4614694392434779458&amp;postID=6416544452308866936" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/6416544452308866936?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/6416544452308866936?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/andydenmark/andyblog/~3/VFZgNx57TtY/speaking-at-web-20-expo.html" title="Speaking at Web 2.0 Expo" /><author><name>Andy Denmark</name><uri>http://www.blogger.com/profile/12309610731557645322</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03680920837785291524" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://blog.andydenmark.com/2008/04/speaking-at-web-20-expo.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0AER3s8cSp7ImA9WxZUGEs.&quot;"><id>tag:blogger.com,1999:blog-4614694392434779458.post-2100658232193156702</id><published>2008-04-10T16:12:00.000-07:00</published><updated>2008-04-10T16:21:46.579-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-04-10T16:21:46.579-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="tripit" /><title>TripIt Nominated for a Webby!</title><content type="html">&lt;a href="http://pv.webbyawards.com/"&gt;&lt;img src="http://farm4.static.flickr.com/3060/2404490728_2d242a6d28_o.png" width="122" height="109" alt="logo_pv" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Like everyone else I've been following the Webby's for years but never in a million years imagined I'd be a part of a company that was nominated for one.  If you guys were planning on voting and like &lt;a href="http://www.tripit.com/"&gt;TripIt&lt;/a&gt;, please don't be shy, vote now!  Vote &lt;a href="http://pv.webbyawards.com/"&gt;here&lt;/a&gt;! (registration required)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4614694392434779458-2100658232193156702?l=blog.andydenmark.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.andydenmark.com/feeds/2100658232193156702/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4614694392434779458&amp;postID=2100658232193156702" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/2100658232193156702?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/2100658232193156702?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/andydenmark/andyblog/~3/szb6p_rGhzA/tripit-nominated-for-webby.html" title="TripIt Nominated for a Webby!" /><author><name>Andy Denmark</name><uri>http://www.blogger.com/profile/12309610731557645322</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03680920837785291524" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.andydenmark.com/2008/04/tripit-nominated-for-webby.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0AARX88eSp7ImA9WxZVGEg.&quot;"><id>tag:blogger.com,1999:blog-4614694392434779458.post-91050320773979125</id><published>2008-03-29T22:34:00.000-07:00</published><updated>2008-03-29T22:42:24.171-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-03-29T22:42:24.171-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="imac wireless" /><title>Solved: iMac Wireless Issues</title><content type="html">It's been a few weeks since I purchased a NetGear RangeMax router I haven't had a single problem with the iMac.  My apologies to Apple but it seems like my old Linksys didn't have what it took to sufficiently cover the apartment.&lt;br /&gt;&lt;br /&gt;In other news, I finally upgrade my main laptop from &lt;a href="http://www.ubuntu.com/"&gt;Dapper Drake&lt;/a&gt; to a beta version of &lt;a href="http://www.ubuntu.com/testing/hardy/beta"&gt;Hardy Heron&lt;/a&gt; and it rocks!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4614694392434779458-91050320773979125?l=blog.andydenmark.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.andydenmark.com/feeds/91050320773979125/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4614694392434779458&amp;postID=91050320773979125" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/91050320773979125?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/91050320773979125?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/andydenmark/andyblog/~3/vj2fcxWzE_g/solved-imac-wireless-issues.html" title="Solved: iMac Wireless Issues" /><author><name>Andy Denmark</name><uri>http://www.blogger.com/profile/12309610731557645322</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03680920837785291524" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.andydenmark.com/2008/03/solved-imac-wireless-issues.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0UBRX06fSp7ImA9WxZQGEU.&quot;"><id>tag:blogger.com,1999:blog-4614694392434779458.post-1590128198347015878</id><published>2008-02-24T12:32:00.000-08:00</published><updated>2008-02-24T12:34:14.315-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-02-24T12:34:14.315-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="mac wireless dd-wrt" /><title>Update: iMac wireless w/ DD-WRT</title><content type="html">Impressive, I boot up the iMac this morning and it immediately connected to my non-SSID broadcasting wireless network.  A sign of good things to come, I hope...  If so, I may have to begin writing an apology to Apple.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4614694392434779458-1590128198347015878?l=blog.andydenmark.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.andydenmark.com/feeds/1590128198347015878/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4614694392434779458&amp;postID=1590128198347015878" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/1590128198347015878?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/1590128198347015878?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/andydenmark/andyblog/~3/fWMPxLQXbuE/update-imac-wireless-w-dd-wrt.html" title="Update: iMac wireless w/ DD-WRT" /><author><name>Andy Denmark</name><uri>http://www.blogger.com/profile/12309610731557645322</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03680920837785291524" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.andydenmark.com/2008/02/update-imac-wireless-w-dd-wrt.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0cERXkzcSp7ImA9WxZQGE0.&quot;"><id>tag:blogger.com,1999:blog-4614694392434779458.post-4918099005627755722</id><published>2008-02-23T15:14:00.000-08:00</published><updated>2008-02-23T15:23:24.789-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-02-23T15:23:24.789-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="mac wireless dd-wrt" /><title>Just Installed DD-WRT</title><content type="html">I just hacked my Linksys router and installed &lt;a href="http://www.dd-wrt.com/"&gt;dd-wrt&lt;/a&gt; so I could boost the signal strength of the device.  Btw, for anyone who has been considering doing this but has not because you were afraid of bricking your router, I had no issues with the install process.  I have a WRT54G v2 router which is pretty old and as such very well supported so your mileage may vary, but I had no issues.&lt;br /&gt;&lt;br /&gt;I have been suspecting for a while now that my &lt;a href="http://blog.andydenmark.com/2008/01/imac-is-wired.html"&gt;rants&lt;/a&gt; at Apple have been misplaced and that the true nature of my wireless problems have more to do with the distance between the new iMac and the router.  We'll see, but either way dd-wrt has all kinds of neat &lt;a href="http://www.dd-wrt.com/wiki/index.php/What_is_DD-WRT%3F#Features"&gt;features&lt;/a&gt; that the stock Linksys firmware did not have so I will have plenty to play with this evening.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4614694392434779458-4918099005627755722?l=blog.andydenmark.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.andydenmark.com/feeds/4918099005627755722/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4614694392434779458&amp;postID=4918099005627755722" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/4918099005627755722?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/4918099005627755722?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/andydenmark/andyblog/~3/FJufMvRzJY4/just-installed-dd-wrt.html" title="Just Installed DD-WRT" /><author><name>Andy Denmark</name><uri>http://www.blogger.com/profile/12309610731557645322</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03680920837785291524" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">5</thr:total><feedburner:origLink>http://blog.andydenmark.com/2008/02/just-installed-dd-wrt.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUAARX85fCp7ImA9WxZQFUo.&quot;"><id>tag:blogger.com,1999:blog-4614694392434779458.post-5778726184753784739</id><published>2008-02-20T21:53:00.000-08:00</published><updated>2008-02-20T22:02:24.124-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-02-20T22:02:24.124-08:00</app:edited><title>New Look for the Blog</title><content type="html">I didn't really like how narrow the template I was using was so I'm playing around with a new look.  So far so good.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4614694392434779458-5778726184753784739?l=blog.andydenmark.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.andydenmark.com/feeds/5778726184753784739/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4614694392434779458&amp;postID=5778726184753784739" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/5778726184753784739?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/5778726184753784739?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/andydenmark/andyblog/~3/0Z1O_Tw1Ll0/new-look-for-blog.html" title="New Look for the Blog" /><author><name>Andy Denmark</name><uri>http://www.blogger.com/profile/12309610731557645322</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03680920837785291524" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.andydenmark.com/2008/02/new-look-for-blog.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkEBSHo6eCp7ImA9WxZQEE4.&quot;"><id>tag:blogger.com,1999:blog-4614694392434779458.post-1239559645755133621</id><published>2008-02-14T17:18:00.000-08:00</published><updated>2008-02-14T17:24:19.410-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-02-14T17:24:19.410-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><title>Tabs v. Spaces</title><content type="html">It's unfortunate that it has been so long since I last posted but I have been really busy both personally and professionally.  I re-ran across this today as I was searching for a solid PHP mode for Emacs (I finally ditched Eclipse and PHPEclipse as my PHP development environment as it was too slow and my threshold for pain was finally surpassed).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.jwz.org/doc/tabs-vs-spaces.html"&gt;http://www.jwz.org/doc/tabs-vs-spaces.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Absolutely classic!  Let the religious wars begin...&lt;br /&gt;&lt;br /&gt;Enjoy and Happy Valentine's day.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4614694392434779458-1239559645755133621?l=blog.andydenmark.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.andydenmark.com/feeds/1239559645755133621/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4614694392434779458&amp;postID=1239559645755133621" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/1239559645755133621?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/1239559645755133621?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/andydenmark/andyblog/~3/u_xg1GEmcL0/tabs-v-spaces.html" title="Tabs v. Spaces" /><author><name>Andy Denmark</name><uri>http://www.blogger.com/profile/12309610731557645322</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03680920837785291524" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.andydenmark.com/2008/02/tabs-v-spaces.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEIAQn89fip7ImA9WxZTE0s.&quot;"><id>tag:blogger.com,1999:blog-4614694392434779458.post-3702283877328816915</id><published>2008-01-14T17:59:00.000-08:00</published><updated>2008-01-14T18:02:23.166-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-01-14T18:02:23.166-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="humor" /><title>Supreme Nerd God</title><content type="html">If &lt;a href="http://www.nerdtests.com/"&gt;NerdTests.com&lt;/a&gt; says it, I have to believe it.&lt;br /&gt;&lt;a href="http://www.nerdtests.com/nq_ref.html"&gt;&lt;br /&gt;&lt;img src="http://www.nerdtests.com/images/badge/f2a053650e918a6c.gif" alt="I am nerdier than 98% of all people. Are you a nerd? Click here to find out!"&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4614694392434779458-3702283877328816915?l=blog.andydenmark.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.andydenmark.com/feeds/3702283877328816915/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4614694392434779458&amp;postID=3702283877328816915" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/3702283877328816915?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/3702283877328816915?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/andydenmark/andyblog/~3/0CH6pJfCnrU/supreme-nerd-god.html" title="Supreme Nerd God" /><author><name>Andy Denmark</name><uri>http://www.blogger.com/profile/12309610731557645322</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03680920837785291524" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.andydenmark.com/2008/01/supreme-nerd-god.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUYHR3oyeSp7ImA9WxZTE04.&quot;"><id>tag:blogger.com,1999:blog-4614694392434779458.post-8237467278316593547</id><published>2008-01-14T09:45:00.000-08:00</published><updated>2008-01-14T09:52:16.491-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-01-14T09:52:16.491-08:00</app:edited><title>The iMac is Wired</title><content type="html">I have given up for now trying to get the wireless on the iMac to be stable.  Of course the problems might be related to my access point (standard Linksys WRT45G), the distance from the machine to the access point, hardware issue, or radio interference of some kind.  Of course my Ubuntu box is sitting right next to the Mac and having no problems so I don't really believe the problems have anything to do with anything but the Mac itself.  So for now I've hardwired the Mac to the network so I can get some work done.&lt;br /&gt;&lt;br /&gt;Next steps are to wait for the next Leopard update (I hear it's coming out soon).  If that doesn't work, I will give Apple customer support a spin to see if it's as good as folks claim.  If those two things don't work I might try a different access point.  I know folks who have the NetGear RangeMax and have had good success, maybe I'll try one of those.  So disappointing...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4614694392434779458-8237467278316593547?l=blog.andydenmark.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.andydenmark.com/feeds/8237467278316593547/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4614694392434779458&amp;postID=8237467278316593547" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/8237467278316593547?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/8237467278316593547?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/andydenmark/andyblog/~3/NoGl9jH4ZBo/imac-is-wired.html" title="The iMac is Wired" /><author><name>Andy Denmark</name><uri>http://www.blogger.com/profile/12309610731557645322</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03680920837785291524" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.andydenmark.com/2008/01/imac-is-wired.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEIDRHo9cCp7ImA9WB9aEUk.&quot;"><id>tag:blogger.com,1999:blog-4614694392434779458.post-2641610457390019639</id><published>2007-12-31T15:08:00.001-08:00</published><updated>2007-12-31T15:09:35.468-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-12-31T15:09:35.468-08:00</app:edited><title>2007 a Year in Review</title><content type="html">Just kidding, I hate those new year roundup/prediction posts.  Stop reading blogs, turn off your computers and go have some fun, it's New Years Eve!  Happy New Year everyone!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4614694392434779458-2641610457390019639?l=blog.andydenmark.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.andydenmark.com/feeds/2641610457390019639/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4614694392434779458&amp;postID=2641610457390019639" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/2641610457390019639?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/2641610457390019639?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/andydenmark/andyblog/~3/e-7KIKrOzog/2007-year-in-review.html" title="2007 a Year in Review" /><author><name>Andy Denmark</name><uri>http://www.blogger.com/profile/12309610731557645322</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03680920837785291524" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.andydenmark.com/2007/12/2007-year-in-review.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUIASX47fSp7ImA9WB9bGUQ.&quot;"><id>tag:blogger.com,1999:blog-4614694392434779458.post-4241971680102020644</id><published>2007-12-29T21:42:00.000-08:00</published><updated>2007-12-29T21:45:48.005-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-12-29T21:45:48.005-08:00</app:edited><title>A Few Weeks with an iMac</title><content type="html">I've had the iMac now for a few weeks and thought I'd give some of my first impressions of the machine.  I really like the machine.  It's the first Mac I've owned and it's the only computer that I've ever owned that I could see being described as "sexy."  The physical design of the machine is beautiful.  It feels solid, is quiet, takes up a minimal amount of space (important in a San Francisco apartment), and is very fast.  Apple has done a wonderful job of making the experience of owning a Mac from the time you open the box to the time the machine is up and running a really great one.  Compared to the pain I had when I set up a Vista box at work a few months back, the iMac was a cinch and I was up and running within 30 minutes (including un-boxing and physical setup).  Compare this to Vista where I spent the same amount of time un-boxing the machine, and then the rest of the day removing all the crapware Dell was gracious enough to install for me, this was a dream.  The only thing Apple tried to sell me was a .Mac membership.  I politely declined and was never bothered again.  I really appreciated that as it was obvious that someone spent time thinking about *me* (the person that just forked over his hard earned money to buy this machine) as I was going through this process.  It may sound weird, but I'd almost describe it as thoughtful.&lt;br /&gt;&lt;br /&gt;As for the machine itself, I'd say it's been an OK experience so far.  I don't say "great" because while the gear is nice and I was up and running quickly, Leopard isn't quite ready and hasn't been as stable as my Dell laptop running Ubuntu Linux.  I've had a few Leopard kernel panics that I have been unable to figure out and the wireless support is embarrassingly bad.  To be fair, the kernel panics seemed to have subsided since I installed the 10.5.1 "patch" for Leopard and the machine does seem a bit more stable now.&lt;br /&gt;&lt;br /&gt;Above all, the one thing that has surprised me more than anything is the lack of reasonable support for "secured" wireless networks.  My network at home was set up with a 128 bit WEP key (not too secure but I change it on occasion and it's better than nothing), is not broadcasting its SSID (why would I?), and is MAC limited to only my machines.  I have *never* had a problem with my Linux box finding my wireless network.  Granted, with Linux, you generally need to find the right driver/gear combination to get a stable system, but once I sorted that out, it has been rock solid for me.&lt;br /&gt;&lt;br /&gt;The wireless support has been a nightmare.  Every time I booted the machine it would forget the SSID of my network.  Seriously?  So, I re-provide the SSID and the password and then maybe it would attach successfully to the network 1 in 10 times.  I even had this type of problem after waking the machine from sleep.  Come on, the ability of a Mac to go to sleep and come up right where you left it is legendary!  After a few times dealing with this I decided that I needed to figure out what was going on.  So, I did some experiments.&lt;br /&gt;&lt;br /&gt;The first thing I changed was to remove the wireless security and WEP password.  This made absolutely no difference to how the machine behaved.  The next thing I did was to broadcast my SSID.  Sadly, this seems to have made things more stable.  I say sadly because now my network SSID is being broadcast to the world.  It's not so much that I am worried that the black van with the tinted windows is going to pull up outside my house to steal bandwidth and passwords (I am a heavy user of SSH and SSL), but I am pretty amazed at how poor a job Apple did making sure Leopard was "right" before they released it.  Isn't this the company that hates buttons and wires?  Are they subtly encouraging me to wire up? :)&lt;br /&gt;&lt;br /&gt;Ok, enough grumpiness for one night.  Apple will be coming out with another multi-hundred GB patch for Leopard shortly.  I'm hoping they will sort these issues out.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4614694392434779458-4241971680102020644?l=blog.andydenmark.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.andydenmark.com/feeds/4241971680102020644/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4614694392434779458&amp;postID=4241971680102020644" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/4241971680102020644?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4614694392434779458/posts/default/4241971680102020644?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/andydenmark/andyblog/~3/_UFPHZH8jFs/few-weeks-with-imac.html" title="A Few Weeks with an iMac" /><author><name>Andy Denmark</name><uri>http://www.blogger.com/profile/12309610731557645322</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03680920837785291524" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.andydenmark.com/2007/12/few-weeks-with-imac.html</feedburner:origLink></entry></feed>
