Showing posts with label phone. Show all posts
Showing posts with label phone. Show all posts

Wednesday, August 22, 2012

Upgrading to the Galaxy S III for free (basically)

Last March for my birthday I shelled out around $150 for the latest and greatest cell phone available on my carrier: the Motorola Atrix 4G.  This time around, I wanted to get the new latest and greatest: the Samsung Galaxy S III, but I didn't want to spend any money on it.

Here's how I pulled it off (largely adapted from this Lifehacker post):


First of all, I have kept my Atrix in immaculate condition.  I immediately bought a hard-shell case (Incipio Feather) and screen covers.  I have replaced the screen cover several times, and the case has suffered a few falls and been cracked, and replaced, but the phone itself is in perfect condition.

There are two main markets for off-contract phones.  One is people whose phones break mid-contract, or who want an early upgrade without renewing their contract.  The second is pre-paid customers, or customers of MVNOs that don't get contract subsidies, and therefore don't pay the monthly "subsidy tax" that we on-contract folks pay (and continue to pay, even if our contract expires).  The second group of phone buyers require the phones to be unlocked in order to use them.

For reasons beyond my fathoming, cell phone carriers are allowed to sell you a device, but still retain control over it.  They have disabled its ability to work on any carrier other than themselves.  Of course, they will allow you to redeem this ability for a fee, and there are also websites out there that will sell you the unlock code for your device.  I obtained an unlock code for my Atrix online for $15.  I may have been able to ask AT&T to unlock it for free once my contract was up, but my contract didn't expire for another few months.  They allow you to renew early, so that you never have a good opportunity to ditch them for another company.


The first step was to get the best price for the Galaxy S III.  I checked several online retailers, and also the ads from different local stores (many can be found online here).  The best price I found was at Radio Shack.  They advertised it for $150, and also featured a deal where they would give you at least $30 for any trade-in phone in good condition.  I traded in an ancient Nokia Qwest phone that had been Elizabeth's before we added her to my family plan on AT&T.  After tax and the $30 credit, the total for the phone was  $134.24.


AT&T, of course, sticks their fork in the offering.  They now charge $36 in what is known as a "because-we-can" upgrade fee.

So, with the $134.24 Galaxy S III, $15 unlock code and $36 upgrade fee, I was out $186 for the new phone.  Now to get it back.  As I mentioned before, unlocking a phone makes it more valuable.  Keeping it covered and cased makes it more valuable.  It also helps to keep the original box.  I also happened to have bought a car dock specifically for this phone.  I did so after going through several generic docks, and coming to the conclusion that having one that was convenient and easy to use would be worth the money.

I created a thorough post listing my phone and its accessories for $180 on craigslist (I used craigslist rather than e-bay because there are no transaction fees or shipping, and I was not in a hurry).  I included a detailed description of the condition of the phone, and which accessories were included.  I also posted clear photos of each item, so that there would be no doubt as to what they were getting.  I also mentioned that I had upgraded, so that buyers would know that there was nothing wrong with the phone, other than being out-dated.

It took a week or so from when I listed it, and I had several nibbles from people who wanted to pay much less, or who eventually bugged out, even though I offered to lower the price.  Today, though, I got a buyer who was interested.  We met, and after booting up the phone with her card, she paid full price.

So, I pulled it off (basically).  Here's to next time.

Tuesday, April 05, 2011

Atrix Screens

I finally got a screenshot app on my phone that works (and it doesn't require root, which is good since the OTA update unrooted my phone).
This is just my home screens, but this post is also my test of the Blogger app.










Edit: Apparently it scales the pictures you upload. That's unfortunate.

Wednesday, March 09, 2011

Motorola Atrix 4G

Two days ago I ordered myself a Motorola Atrix 4G!  This is a big deal:  I've been wanting a smartphone, specifically an Android phone, for quite some time.

My contract isn't actually up.  Last February we renewed all four of the contracts on our family plan at the same time.  This, I realize, was a mistake, because while it increases flexibility in that it makes it easier to leave the carrier (two years later when all of the contracts are up), it actually reduces flexibility in that if you have trouble with one of the phones (as it did with my dad's), you are left without the option to upgrade out of time.

Since my current phone is a "dumb" phone, the early termination fee (when I cancel the contract) is not so bad.  With 11 months left on the contract, it will be $98.

The way I'm going about this is to order the Atrix on a new line on our family plan.  When it arrives and I activate it, I will attempt to get AT&T to exchange the numbers associated with the contracts so that my old contract has the new number, and the new contract, with the Atrix, has my old number.  I estimate that I have a 20% chance of succeeding.

I would like to keep my number, so if that doesn't work, I will simply port the old number to Google Voice.  I currently use Google Voice for voicemail and for sending text messages from a computer, and I wouldn't mind it a bit if by default, everything went through it, especially text messages, since I would prefer not to pay for them.  If I port the number, text messages sent to it won't be text messages anymore: they will be data.  I have always hated that the carriers charged so much for delivering messages piggybacking on traffic between the phone and tower that was being sent regardless of whether there was a message.

Why the Motorola Atrix 4G? 

Well, that's a good question, after all, the name is a lie.  The Atrix is not physically capable of actual 4G, and AT&T has even disabled HSPA+ upload speeds on everything but the iPhone 4.  What AT&T offers is "4G download speeds delivered by HSPA+ and enhanced backhaul."  Real, actual 4G is coming to AT&T's network later this year (probably this summer) in the form of LTE.

Motorola Atrix 4G Android Phone (AT&T)
Motorola Atrix 4G
If I waited until my line was eligible for an upgrade in October, there would almost certainly by then have been a crop of new phones introduced, of equal caliber to the Atrix, supporting actual 4G.  Motorola wasn't my first choice in manufacturer.  I have heard nothing but good things about HTC's Sense interface, and nothing but bad things about Motorola's Motoblur interface.  There is, in fact, a direct competitor to the Motorola Atrix 4g:  the HTC Inspire 4G.  Why did I not go with that instead?  It's even cheaper.

HTC Inspire 4G Android Phone (AT&T)
HTC Inspire 4G
There are a number of reasons, of course.  First, despite Motoblur's sordid reputation, reviews and users in forums seem to be saying that it's actually a good experience on the Atrix.  The Atrix is a very fast phone, with a Dual-core 1GHz processor and a Gigabyte of RAM.  The Inspire is no speed slouch either, but, especially coming from a feature phone, I'm not keen on it's size.  I have very good eyes at close distance, and have always liked screen real-estate:  not largeness of screen, but number of pixels.  The Atrix has over a third more pixels in its 4" display as the Inspire has in its 4.3" display.  The Atrix also has four times the internal memory as the Inspire, though both can be expanded with up to 32GB microSD cards. The Inspire has an 8 megapixel camera, but the Atrix has both front and rear-facing cameras, and I don't think that the 5 megapixel snapshots taken by the Atrix will be of any less quality than the Inspire's.

The Atrix accessories have been touted as it's huge selling point, but I don't see much use for them, especially at the prices they're asking.  I would rather haul a netbook around than a phone dock, and I already have a computer hooked up to my HDTV at home, so I don't think I'll need to hook the phone up directly. 

Selling Points

In short, despite the hype about a "superphone," and "4G,"  I find the Atrix to be by far the best phone for me:
  • Despite being small (and pocketable--I'm a guy, I don't carry a purse), it has excellent screen quality and resolution.
  • Because it was made to drive a netbook, it is a powerhouse phone, capable of running any apps I throw at it--and I intend to be a power user.
  • Because it's a flagship product, it gets all the bells and whistles, like the fingerprint scanner, HD video recording, front-facing camera, gorilla glass, etc.
The iPhone is physically a fine product, but it does not interest me, mainly because of Apple's philosophy of control, especially when they see an opportunity to lock down a revenue stream.

Why now?

I suppose I could have waited until October.  As I have mentioned before, AT&T is rolling out their LTE network, presumably with a new crop of top-of-the-line phones, and there would be no hassles with my phone number.  I could just wait.  I was going to wait.

But it was my birthday, and I got "smartphone" money!  Did I mention I had already waited a long time?  I think there will always be something better to wait for, and if you always wait, you will never buy.  Pining for nice things is OK if you actually intend to buy; otherwise, you're just living in a fantasy land, coveting what you cannot have.  The extra expense, to me, is worth the extra time of getting to use a smartphone.

I also found a decent price at Costco's wireless site, which gives you free activation, free shipping and a free accessory kit (including a car charger).  [CarToys has the best price, but no option for adding a line to an existing family plan.]

Besides, come October, there will be three lines on our plan due for an upgrade, and I doubt that all three will want to exercise it just then.  Perhaps if I there's an awesome LTE phone from HTC with NFC and I work things right, I can get that, and pass the Atrix (or my current phone) along to someone else.

Wednesday, March 17, 2010

TwitPic to Posterous Export Script

Note: This post (and the script it contains) has been updated as of December 14, 2010.  (v1.4.0) The script can also be downloaded from my server here.
Also, Posterous has done a lot of work on solving this problem since I wrote my script.   You can see their latest solutions here.

Recently, I switched from TwitPic to Posterous as my method of posting phone pictures (and now video) to the Internet.  But since I switched, I didn't want to have my data history split in two, so I decided to write a script to download each of my TwitPic images with their associated text and date, and upload them to Posterous with the same information.

Initially, I wanted to make one long post with all of the images, and their text below.  However, with the Posterous API, it isn't possible to refer to a specific image in your body text, so individual posts is the way I went.

Along the way, I became familiar with yet another Linux command: curl.

I love that Posterous has an API that (once you figure out curl) is pretty easy to use.  TwitPic, on the other hand, has absolutely zero support for exporting anything.  The fact that they're so non-user-centric and out-dated was a driving force in my switching.  The only reason I hadn't switched to img.ly already was because img.ly has a bug that prevents images sent from my phone from being posted, since my phone sends them without a file extension.  I worked with their tech support for a while, but they didn't fix it.  I got a new phone, but it was also a Samsung, and it did the same thing with images.  Oh, well.  Posterous is better.

Anyway, here is the script:

First run it with just the first two arguments, and it will download all of your TwitPic data, including thumbnail images.  Once you're satisfied, supply your Posterous User ID, Password, and Site ID.  (If you don't know your Site ID, run the script with your Posterous User ID, Password, and no Site ID, and it will query your Posterous site info as long as your Posterous credentials are valid.)

Note: if you want to run this from Windows, you should install Cygwin (with, at a mimum, curl and sed) and run it from there.

./twitpic-to-posterous.sh [twitpic-id] [working-dir] [postrous-id] [posterous-password] [posterous-site-id] [skip-number]
#!/bin/sh

# Copyright 2010 Tim "burndive" of http://burndive.blogspot.com/ and http://tuxbox.blogspot.com/
# This software is licensed under the Creative Commons GNU GPL version 2.0 or later.
# License informattion: http://creativecommons.org/licenses/GPL/2.0/

# This script was obtained from here:
# http://tuxbox.blogspot.com/2010/03/twitpic-to-posterous-export-script.html

RUN_DATE=`date +%F--%H-%m-%S`
SCRIPT_VERSION_STRING="v1.4.0"

TP_NAME=$1
WORKING_DIR=$2
P_ID=$3
P_PW=$4
P_SITE_ID=$5
UPLOAD_SKIP=$6

# Comma separated list of tags to apply to your posts
P_TAGS="twitpic"
# Whether or not to auto-post from Posterous
P_AUTOPOST=0
# Whether or not the Posterous posts are marked private
P_PRIVATE=0

# This is the default limit of the number of posts that can be uploaded per day
P_API_LIMIT=50

DOWNLOAD_FULL=1
DOWNLOAD_SCALED=0
DOWNLOAD_THUMB=0
PREFIX=twitpic-$TP_NAME
HTML_OUT=$PREFIX-all-$RUN_DATE.html
UPLOAD_OUT=posterous-upload-$P_SITE_ID-$RUN_DATE.xml

if [ -z "$TP_NAME" ]; then
  echo "You must supply a TP_NAME."
  exit
fi
if [ ! -d "$WORKING_DIR" ]; then
  echo "You must supply a WORKING_DIR."
  exit
fi
if [ -z "$UPLOAD_SKIP" ]; then
  UPLOAD_SKIP=0
fi
UPLOAD_SKIP_DIGITS=`echo $UPLOAD_SKIP | sed -e 's/[^0-9]//g'`
if [ "$UPLOAD_SKIP" != "$UPLOAD_SKIP_DIGITS" ]; then
  echo "Invalid UPLOAD_SKIP: $UPLOAD_SKIP"
  exit
fi

cd $WORKING_DIR

if [ -f "$HTML_OUT" ]; then
  rm -v $HTML_OUT
fi

# If Posterous username and password were supplied, but not site ID, query the server and exit.
P_SITE_INFO_FILE=posterous-$P_SITE_ID.out
if [ ! -z "$P_ID" ] && [ ! -z "$P_PW" ] && [ -z "$P_SITE_ID" ]; then
  echo "Getting Posterous account info..."
  curl -u "$P_ID:$P_PW" "http://posterous.com/api/getsites" -o $P_SITE_INFO_FILE
  SITE_ID_RET=`grep "<id>$P_SITE_ID</id>" $P_SITE_INFO_FILE`
  if [ -z "$SITE_ID_RET" ]; then
    echo "Please supply your Posterous Site ID as the fifth argument."
    echo "Here is the response from the Posterous server.  If you entered correct credentials, you should see your Site ID(s):"
    cat $P_SITE_INFO_FILE | tee -a $UPLOAD_OUT
    exit
  fi
fi

# Confirm that we have a valid Posterous Site ID
if [ ! -z "$P_SITE_ID" ]; then
  echo "Getting Posterous account info..."
  curl -u "$P_ID:$P_PW" "http://posterous.com/api/getsites" -o $P_SITE_INFO_FILE
  SITE_ID_RET=`grep "<id>$P_SITE_ID</id>" $P_SITE_INFO_FILE`
  if [ -z "$SITE_ID_RET" ]; then
    echo "Make sure that you have supplied a valid Posterous Site ID as the fifth parameter.  If you don't know your Site ID, leave it out, and this script will query the server."
    echo "Here is the response from the Posterous server.  If you entered correct credentials, you should see your site ID(s):"
    cat $P_SITE_INFO_FILE | tee -a $UPLOAD_OUT
    exit
  fi
fi

MORE=1
PAGE=1
while [ $MORE -ne 0 ]; do
  echo PAGE: $PAGE
  FILENAME=$PREFIX-page-$PAGE.html
  if [ ! -s $FILENAME ]; then
    wget http://twitpic.com/photos/${TP_NAME}?page=$PAGE -O $FILENAME
    if [ ! -s "$FILENAME" ]; then
      echo "ERROR: could not get $FILENAME" | tee -a $LOG_FILE
      sleep 5
    fi
  fi
  if [ -z "`grep "More photos &gt;" $FILENAME`" ]; then
    MORE=0
  else
    PAGE=`expr $PAGE + 1`
  fi
done

ALL_IDS=`cat $PREFIX-page-* | grep -Eo "<a href=\"/[a-zA-Z0-9]+\">" | grep -Eo "/[a-zA-Z0-9]+" | grep -Eo "[a-zA-Z0-9]+" | sort -r | xargs`

# For Testing
#ALL_IDS="1kdjc"

COUNT=0
LOG_FILE=$PREFIX-log-$RUN_DATE.txt

echo $ALL_IDS | tee -a $LOG_FILE

for ID in $ALL_IDS; do
  COUNT=`expr $COUNT + 1`
  echo $ID: $COUNT | tee -a $LOG_FILE

  echo "Processing $ID..."
  FULL_HTML=$PREFIX-$ID-full.html
  if [ ! -s "$FULL_HTML" ]; then
    wget http://twitpic.com/$ID/full -O $FULL_HTML
    if [ ! -s "$FULL_HTML" ]; then
      echo "ERROR: could not get FULL_HTML for $ID" | tee -a $LOG_FILE
      sleep 5
    fi
  fi
  TEXT=`grep "<img src=" $FULL_HTML | tail -n1 | grep -oE "alt=\"[^\"]*\"" | sed \
        -e 's/^alt="//'\
        -e 's/"$//'\
        -e "s/&#039;/'/g"\
        -e 's/&quot;/"/g'\
        `
  if [ "$TEXT" = "" ]; then
    TEXT="Untitled"
  fi
  echo "TEXT: $TEXT" | tee -a $LOG_FILE
  # Recognize hashtags and username references in the tweet
  TEXT_RICH=`echo "$TEXT" | sed \
        -e 's/\B\@\([0-9A-Za-z_]\+\)/\@<a href="http:\/\/twitter.com\/\1">\1<\/a>/g' \
        -e 's/\#\([0-9A-Za-z_-]*[A-Za-z_-]\+[0-9A-Za-z_-]*\)/<a href="http:\/\/twitter.com\/search\?q\=%23\1">\#\1<\/a>/g' \
        `
  echo "TEXT_RICH: $TEXT_RICH" | tee -a $LOG_FILE

  # Convert hashtags into post tags
  P_TAGS_POST=$P_TAGS`echo "$TEXT" | sed \
        -e 's/\#\([^A-Za-z_-]\)*\B//g' \
        -e 's/^[^\#]*$//g' \
        -e 's/[^\#]*\(\#\([0-9A-Za-z_-]*[A-Za-z_-]\+[0-9A-Za-z_-]*\)\)[^\#]*\(\#[0-9]*\B\)*/,\2/g' \
        `
  # Uncomment if you don't want hashtags converted into post tags
  #P_TAGS_POST=$P_TAGS

  # Add custom tags from a file (optional).  The file is formatted like this:
  # ,tag1,tag2,tag3
  TAGS_FILE=$PREFIX-$ID-tags-extra.txt
  if [ -s "$TAGS_FILE" ]; then
    P_TAGS_POST=$P_TAGS_POST`cat $TAGS_FILE`
  fi
  echo "P_TAGS_POST: $P_TAGS_POST" | tee -a $LOG_FILE

  TEXT_FILE=$PREFIX-$ID-text.txt
  if [ ! -s $TEXT_FILE ]; then
    echo "$TEXT" > $TEXT_FILE
  fi
  FULL_URL=`grep "<img src=" $FULL_HTML | grep -Eo "src=\"[^\"]*\"" | grep -Eo "http://[^\"]*"`
  echo "FULL_URL: $FULL_URL" | tee -a $LOG_FILE

  SCALED_HTML=$PREFIX-$ID-scaled.html
  if [ ! -s "$SCALED_HTML" ]; then
    wget http://twitpic.com/$ID -O $SCALED_HTML
    if [ ! -s "$SCALED_HTML" ]; then
      echo "ERROR: could not get SCALED_HTML for $ID" | tee -a $LOG_FILE
      sleep 5
    fi
  fi
  SCALED_URL=`grep "id=\"photo-display\"" $SCALED_HTML | grep -Eo "http://[^\"]*" | head -n1`
  echo "SCALED_URL: $SCALED_URL" | tee -a $LOG_FILE
  POST_DATE=`grep -Eo "Posted on [a-zA-Z0-9 ,]*" $SCALED_HTML | sed -e 's/Posted on //'`
  echo "POST_DATE: $POST_DATE" | tee -a $LOG_FILE

  THUMB_URL=`cat $PREFIX-page-* | grep -E "<a href=\"/$ID\">" | grep -Eo "src=\"[^\"]*\"" | head -n1 | sed -e 's/src=\"//' -e 's/\"$//'`
  echo "THUMB_URL: $THUMB_URL" | tee -a $LOG_FILE

  EXT=`echo "$FULL_URL" | grep -Eo "[a-zA-Z0-9]+\.[a-zA-Z0-9]+\?" | head -n1 | grep -Eo "\.[a-zA-Z0-9]+"`
  if [ -z "$EXT" ]; then
    EXT=`echo "$FULL_URL" | grep -Eo "\.[a-zA-Z0-9]+$"`
  fi
  echo "EXT: $EXT"
  if [ "$DOWNLOAD_FULL" -eq 1 ]; then
    FULL_FILE="$PREFIX-$ID-full$EXT"
    if [ ! -s $FULL_FILE ]; then
      wget "$FULL_URL" -O $FULL_FILE
      if [ ! -s "$FULL_FILE" ]; then
        echo "ERROR: could not get FULL_URL for $ID: $FULL_URL" | tee -a $LOG_FILE
        sleep 5
      fi
    fi
  fi
  if [ "$DOWNLOAD_SCALED" -eq 1 ]; then
    SCALED_FILE=$PREFIX-$ID-scaled$EXT
    if [ ! -s $SCALED_FILE ]; then
      wget "$SCALED_URL" -O $SCALED_FILE
      if [ ! -s "$SCALED_FILE" ]; then
        echo "ERROR: could not get SCALED_URL for $ID: $SCALED_URL" | tee -a $LOG_FILE
        sleep 5
      fi
    fi
  fi
  if [ "$DOWNLOAD_THUMB" -eq 1 ]; then
    THUMB_FILE=$PREFIX-$ID-thumb$EXT
    if [ ! -s $THUMB_FILE ]; then
      wget "$THUMB_URL" -O $THUMB_FILE
      if [ ! -s "$THUMB_FILE" ]; then
        echo "ERROR: could not get THUMB_URL for $ID: $THUMB_URL" | tee -a $LOG_FILE
        sleep 5
      fi
    fi
  fi

  BODY_TEXT="$TEXT_RICH <p>[<a href=http://twitpic.com/$ID>Twitpic</a>]</p>"

  # Format the post date correctly
  YEAR=`echo "$POST_DATE" | sed -e 's/[A-Z][a-z]* [0-9]*, //'`
  DAY=`echo "$POST_DATE" | sed -e 's/[A-Z][a-z]* //' -e 's/, [0-9]*//'`
  MONTH=`echo "$POST_DATE" | sed -e 's/ [0-9]*, [0-9]*//' | sed \
    -e 's/January/01/' \
    -e 's/February/02/' \
    -e 's/March/03/' \
    -e 's/April/04/' \
    -e 's/May/05/' \
    -e 's/June/06/' \
    -e 's/July/07/' \
    -e 's/August/08/' \
    -e 's/September/09/' \
    -e 's/October/10/' \
    -e 's/November/11/' \
    -e 's/December/12/' \
    `
  # Adjust the time to local midnight when west of GMT
  HOURS_LOC=`date | grep -Eo " [0-9]{2}:" | sed -e 's/://' -e 's/ //'`
  HOURS_UTC=`date -u | grep -Eo " [0-9]{2}:" | sed -e 's/://' -e 's/ //'`
  HOURS_OFF=`expr $HOURS_UTC - $HOURS_LOC + 7`
  echo "HOURS_LOC: $HOURS_LOC"
  echo "HOURS_UTC: $HOURS_UTC"
  echo "HOURS_OFF: $HOURS_OFF"
  if [ "$HOURS_OFF" -lt 0 ]; then
    # We're east of GMT, do not adjust
    HOURS_OFF=0
  fi
  if [ "$HOURS_OFF" -lt 10 ]; then
    HOURS_OFF=0$HOURS_OFF
  fi
  if [ "$DAY" != "" ] && [ "$DAY" -lt 10 ]; then
    DAY=0$DAY
  fi
  DATE_FORMATTED="$YEAR-$MONTH-$DAY-$HOURS_OFF:00"
  echo "DATE_FORMATTED: $DATE_FORMATTED" | tee -a $LOG_FILE

  echo "<p><img src='$FULL_FILE' alt='$TEXT' title='$TEXT' /></p>" >> $HTML_OUT
  echo "$BODY_TEXT" >> $HTML_OUT
  echo "  Post date: $DATE_FORMATTED; Count: $COUNT" >> $HTML_OUT

  # Upload this Twitpic data to Posterous
  if [ ! -z "$P_SITE_ID" ]; then

    # First make sure we're under the API upload limit
    if [ "$COUNT" -le "$UPLOAD_SKIP" ]; then
      echo Skipping upload...
      continue
    fi
    if [ "$COUNT" -gt "`expr $UPLOAD_SKIP + $P_API_LIMIT`" ]; then
      echo "Skipping upload due to daily Posterous API upload limit of $P_API_LIMIT."
      echo "To resume uploading where we left off today, supply UPLOAD_SKIP parameter of `expr $UPLOAD_SKIP + $P_API_LIMIT`."
      continue
    fi

    P_OUT_FILE="posterous-$P_SITE_ID-$ID.out"
    if [ -s "$P_OUT_FILE" ]; then
      rm "$P_OUT_FILE"
    fi
    echo "Uploading Twitpic image..."
    curl -u "$P_ID:$P_PW" "http://posterous.com/api/newpost" -o "$P_OUT_FILE" \
      -F "site_id=$P_SITE_ID" \
      -F "title=$TEXT" \
      -F "autopost=$P_AUTOPOST" \
      -F "private=$P_PRIVATE" \
      -F "date=$DATE_FORMATTED" \
      -F "tags=$P_TAGS_POST" \
      -F "source=burndive's Twitpic-to-Posterous script $SCRIPT_VERSION_STRING" \
      -F "sourceLink=http://tuxbox.blogspot.com/2010/03/twitpic-to-posterous-export-script.html" \
      -F "body=$BODY_TEXT" \
      -F "media=@$FULL_FILE"
    cat $P_OUT_FILE  | tee -a $UPLOAD_OUT
  fi
done
echo Done.
CC-GNU GPL
This software is licensed under the CC-GNU GPL version 2.0 or later.

PS: If you use my code, I appreciate comments to let me know, and any feedback you may have, especially if it's not working right for you, but also just to say thanks.

For convenience, you can download this script from my server.

Sunday, February 28, 2010

Facebook Gmail Phone Filter

The other day I had an idea that I think is worth sharing. 

I post to Twitter, but most people who see those posts don't see them via Twitter, they see them when the tweets are imported to Facebook as status updates. 

When someone responds to your post on Twitter, you get an SMS with their reply.  When someone responds to my post from Facebook, which is where the vast majority of responses and reactions occur, I don't get notified on my phone, which is usually where I sent the original message from.  Often I'm nowhere near my computer, and won't be for hours.

This means that I don't see the response until I check my e-mail (or Facebook, but e-mail is usually first).  I have Facebook configured to send me a message when someone responds to my posts.  It occurred to me that I could get those same notifications on my phone.  Here's how.

I set up a filter in Gmail that forwards matching e-mails to my phone's multi-media message (MMS) e-mail address. 

Here's what the filter looks like.

Here's the first step in creating the filter.  I'm also forwarding Facebook messages to my phone.  If I were to leave off the word "your" and just say "commented on" then the filter would include comments on other people's posts that I had previously commented on.

Here's the second step.  The MMS e-mail address is the address that appears on an e-mail if I send an MMS message (e.g., a picture) from my phone to my Gmail address.
And that's it.  When someone responds to my Twitter/TwitPic posts from Facebook, I get the message on my phone right away.  Since it's an MMS and not an SMS, the messages are not limited to 160 characters.  I have a messaging plan with AT&T that doesn't distinguish between the two kinds of messages.

Monday, April 13, 2009

That's What She sed

Lately, I've been uploading pictures to Twitter from my phone using TwitPic. Basically, you send them to a TwitPic e-mail address via multimedia messaging, and they are automatically posted to your Twitter account, along with the text from the subject. This all works quite well, and they even supply an RSS feed of your pictures, which you can take and (among other thing) put on your blog's sidebar. The problem was, when I put it in my blog sidebar, there was no thumbnail image. Other feeds that had images in them would have thumbnails, but not this one. This one just had a text link to the picture page. I found that disappointing. So I examined feeds that showed thumbnails and the TwitPic feed to see what the difference was. Feeds that contained images within the feed content showed up in the Blogger widget with a thumbnail. But the TwitPic feed showed images. What was the difference? The difference turned out to be CDATA. CDATA is a way to tell a feed reader, "Don't try to decipher my contents, just pass them along and leave the rendering to the end user application." It so happens that TwitPic's thumbnail images are within a CDATA block, and Blogger obediently ignores the CDATA contents when looking for images to display as a thumbnail. So, how do I fix that? I need to read the feed, and for each item, locate the line that contains the thumbnail URL, and create a new attribute containing the thumbnail in a format that is decipherable to Blogger's widget. Using my digg feed as a model, I figured out what the end result should look like, but how to achieve it? First, I tried Yahoo Pipes. Yahoo has a tool for processing feeds with a number of tools, controlled by a graphical pipe-looking interface. The problem is, none of the tools that I could find would add an attribute based on the transformed contents of another attribute. There were widgets that came close, but I couldn't get it to work, so I decided to host the feed myself and modify it using sed. I had never used sed before, except when the exact command was given, so I didn't know how to use it, but I knew that it was a powerful enough tool to get the job done. So I created a shell script on my Linux box, and a cron job to run it. The script basically downloaded the RSS feed from TwitPic to a local file, and then called sed on it with a particular set of parameters designed to extract the necessary information, and add the appropriate information in a format that is decipherable to Blogger. In order to understand sed, I searched the Internet for a tutorial, and found this page from the Gentoo Linux Documentation to be the most helpful. My sed command does two things, which are piped together:
  1. It adds an xmlns:media declaration, which allows me to use the media tag later on.
  2. It examines each CDATA line with the thumbnail URL, and below it, it adds a line with the media:thumbnail tag and the URL extracted from above.
sed -e 's/<rss version="[^"]*"/& xmlns:media="http:\/\/search.yahoo.com\/mrss\/"/g' $TMP_FILE | sed -e 's/\(http:\/\/twitpic.com\/show\/thumb\/[^"]*\).*/&\n <media:thumbnail url="\1" height="150" width="150" \/>/g' > $FEED_FILE
I know it's possible to consilidate the two sed commands into one and do it in one pass, but this works. I may tweak it in further revisions. It is not necessary to use a yahoo-defined media tag, so I might modify the script later on to simply transform the CDATA portion into parseable encoded HTML. I might also add that I'm using Feedburner to host the feed. Basically, I change the file on my server, and Feedburner goes there to get it, and offers it to the rest of the world. That way if my server is offline, the feed is still active and available, and I don't have to deal with the traffic, just the Feedburner hits. If anyone else wants their TwitPic feed to have thumbnails available, let me know, and I can set one up for you on my server through Feedburner. (It's pretty easy, since the TwitPic username is passed in to the script as a parameter). I can't guarantee anything, but since it's in my interest to keep the script working and up-to-date, you don't have much to worry about. All I need to know is your TwitPic (Twitter) username.
  • Update (2009-04-16): I have modified the code to accept all image formats, and be shorter.

Tuesday, June 26, 2007

iPhone

Apple and AT&T just announced the rate plans for the iPhone contract. I've been watching the market with a wary eye. I'm not usually an early adopter, but there have been exceptions. I need a new phone. My current phone, a Motorola V551, has become practically unusable because the speaker volume has faded to almost nothing. I basically have to use my hands-free kit in order to place a call, or I won't be able to hear anything on the other end. That said, there are two reasons why I am watching the iPhone:
  1. To see what other options become available as a result of the splash it makes on the market. Capitalism is a wonderful thing. If the iPhone sells like hotcakes, chances are, other high-end phones will drop in price due to decreased demand, and will be ripe for the picking.
  2. To see if it would be worth it to buy.
The main problem with number 2 is that I currently don't use anything analogous to the fancy-schmancy features offered by the iPhone, so it's not like the cost iPhone would replace any expense that I currently have. The only iPhone feature that I currently use is "making calls."
  • I don't own an iPod. I never have. I don't even have iTunes installed on any computer that I own, nor have I ever purchased downloaded music (although with DRM-free music from the EMI label available, I am willing to enter that market).
Part of what I have been waiting for happened today: they announced their rate plans, including the family plans, which is relevant to me because I am currently on a Cingular family plan with my mother and brother. One thing I do like about Apple is that they make things simple: It would cost me $20 more than I am currently paying to add the iPhone features to my plan. This is true (within one cent) whether I create a different plan, or whether I tack-on the iPhone features to my current plan. (Although the way my plan works there is a percentage discount on the main line, and so it might be cheaper if I were able to transition the plan to an iPhone-base plan rather than adding it on, because then the discount would also apply to the additional $20.) iPhone plans add three things over other plans. For $20, you get:
  • Unlimited data: for e-mail and Internet access
  • 200 text messages (sent or received)
  • Visual voicemail
Currently, I use text messaging as little as possible. Text messaging is pure price-gouging profit for the wireless phone providers: it costs them nothing extra, and it never has cost them any extra. They charge extra simply because there are people willing to pay. It's a teeny-tiny packet of data! What's even more ridiculous is when they separate text messaging from data service. I consider it a nice (though insufficient) gesture that the iPhone plan includes 200 text messages. This is enough for casual use, and I won't have to be as annoyed at the 15 cents they currently charge me if I want to read message that someone sends me. Did you know that you can send someone a text message over e-mail? If I have a phone with a web browser and/or an e-mail client, why would I ever use the built-in text messaging feature? That might just be my very first iPhone Safari widget: a free (over the Internet) text messaging application. The main flaw in all of this is that when I commit to a contract with a wireless carrier, I usually receive a discount on my phone in exchange: basically, the wireless carrier is paying for my phone up front, and part of my monthly service charge is paying them back for the phone in monthly installments. That is the way it has worked since the dawn of time. Not so with the iPhone, at least not at launch. $500 or $600 will buy you an iPhone. You can use it as a WiFi-enabled PDA/iPod if you like. You will get no discount for buying the phone from AT&T, nor for activating it with them, but they will still require you to enter a 2-year contract (with a $175 early termination fee) simply for tacking what amounts to a $20 data package onto your plan. Now, it could be argued that the phone is actually "worth" $675 or $775 (and I'm sure that it is to a few schmucks on eBay). It could also be argued that $20 is less than the traditional rate charged for unlimited mobile Internet access. For now I am in wait-and-see mode.