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.

37 comments:

  1. For some reason when I ran this, it produced duplicate posts. I checked the script output and verified that indeed each post was only uploaded once. I will take it up with Posterous support.

    ReplyDelete
  2. Update: So, I traced the duplicate posts to the fact that I started my page numbering for the TwitPic downloads at 0. Pages 0 and 1 had the same posts on them, so I was uploading them twice.

    I updated the script in the post, so it should work as I originally intended.

    ReplyDelete
  3. Tim...this is pretty awesome and what I was looking for...but I seem to have run into a couple of issues.

    1. It looks like it's only able to grab the last 10 pictures from twitpic, and not your entire set of photos.

    2. When it tries to do the upload to Posterous it returns the following output:






    This is really a great tool, especially since Posterous created their own which Twitpic blocked...any help would great.

    Thanks!

    ReplyDelete
  4. xml version="1.0" encoding="UTF-8"
    rsp stat="fail"
    err code="1003" msg="Invalid media"
    rsp

    ReplyDelete
  5. As you say, it's unfortunate that the Posterous import tool has been blocked by TwitPic.

    It's possible that TwitPic updated the format of their pages, and I haven't updated the script to accommodate.

    I can take a look at it later. This script relies on specific cues in the text of the HTML.

    Specifically, if you change this line:
    if [ -z "`grep "OLDER >>" $FILENAME`" ]; then
    to this:
    if [ -z "`grep "More photos >" $FILENAME`" ]; then
    Then it should download the rest of your photos.

    I'll have to look at the Posterous upload portion of the script later on when I have time. It's based on their API, which may have changed (but the more likely culprit is that TwitPic changed, and the script isn't downloading the pictures as expected).

    Please feel free to experiment with the script. Let me know if you find a solution before I get back to you.

    I really appreciate your feedback, and I'm definitely interested in maintaining this script, especially since TwitPic is blocking Posterous' method.

    ReplyDelete
  6. Kai,

    Another thing to consider is that you need to embed your Posterous credentials in the script. It's something I did for convenience, and if I revise the script, I may make them command-line parameters.

    Basically, you need to update the following lines to correspond to your information:

    # Your Posterous user ID (usually your e-mail address)
    P_ID="your@email.com"
    # Your Posterous user password
    P_PW="secret"

    ReplyDelete
  7. Okay, I updated the script so that it works with the TwitPic site's current format. It may break again in the future. If it does, let me know.

    Meanwhile, I also took the Posterous credentials out of the script, so there's no need to edit it. You supply them as parameters:

    twitpic-to-posterous.sh [twitpic-id] [working-dir] [postrous-id] [posterous-password] [posterous-site-id]

    If you leave off the Posterous Site ID, it will query the server for it. If you leave off the Posterous User ID and Password, it will simply download your photos from TwitPic.

    Enjoy.

    ReplyDelete
  8. Wow, thanks for the awesome update! Seems to be an issue on line 86 with the page++. Any thoughts?

    ReplyDelete
  9. I think I fixed it...needed to to $MORE=1 $PAGE=1 and in the else statement $PAGE

    think those were left off...it's working now though.

    ReplyDelete
  10. Hmm...it seemed to only grab the first two pages when I made those changes...something isn't right in that section with the way it's incrementing the page, but I'm not quite sure what it is.

    ReplyDelete
  11. When I tried it on my end with "phikai", it downloaded all 5 pages (as well as all 99 pictures) just fine.

    What shell are you running? (bash, ksh, etc.)
    What is your OS environment? (Linux, OS X, Cygwin, etc.)

    Try replacing "((PAGE++))" with "PAGE=`expr $PAGE + 1`".

    It seems odd to me that it would correctly increment once, but not again.

    I'll e-mail you. Please send me a log of the script running.

    ReplyDelete
  12. Kai and I were able to narrow down the problem. I was specifying #!/bin/sh, but not being POSIX compliant when I incremented the PAGE and COUNT variables.

    I have updated the script again (v1.2.1), and this update takes care of that issue.

    ReplyDelete
  13. Hi Tim, thanks for doing this script :) One problem is I'm unable to get past this error:

    line 88: tac: command not found

    I'm running Mac OS X 10.6.4, Terminal app with wget installed. I'm far from being an expert in command line but I know enough to run a script.

    Is there another way I can get the script to work? It seems like tac utility is not available for OS X.

    ReplyDelete
  14. Adam,

    Does OS X have the sort command with the -r (--reverse) option?

    The tac command simply reverses the order of lines from its input to its output. "sort -r" would do the same.

    Another command I use that may or may not exist in OS X is "tee". tee splits the output between stdout and a file. I use "tee -a" to simultaneously log to a file and print to the terminal. Let me know if it's there, as I could also code around that.

    I'm also curious to know if curl is in OS X by default.

    Let me know.

    ReplyDelete
  15. I went ahead and looked up which commands OS X does and doesn't have. According to this list, tee should be just fine.

    I update the script accordingly (as of v1.2.2). Please let me know if it works for you, Adam.

    ReplyDelete
  16. sort -r seems to work great! I see a bunch of images, txt and html files now.

    I've added posterous user id, password and site id but it doesn't seem to put anything in my posterous site. Repeated error I see in Terminal is this:

    Uploading Twitpic image...
    date: illegal time format

    ?xml version="1.0" encoding="UTF-8"?
    rsp stat="fail"
    err code="3006" msg="Invalid date" /
    /rsp

    If you'd like the full log, I can email them

    ReplyDelete
  17. Adam,

    Apparently the OS X version of the date command is a lot less functional than the Linux version. I was using it to convert the date format, but the OS X version doesn't support that.

    I updated the script once more (v1.2.3) so that it doesn't rely on the date command for the conversion.

    Let me know how it goes.

    ReplyDelete
  18. v1.2.3 stopped the process early on:

    /Users/adambetts/Desktop/twitpic-to-posterous-v1.2.3.command: line 153: unexpected EOF while looking for matching ``'
    /Users/adambetts/Desktop/twitpic-to-posterous-v1.2.3.command: line 194: syntax error: unexpected end of file

    ReplyDelete
  19. Oops. I tested my changes in a smaller script, but I didn't want to upload anything to Posterous, so I didn't test it when I dropped it into the whole thing.

    Apparently I didn't paste it in correctly: I missed the closing `

    Try it now.

    ReplyDelete
  20. I set up an alternate Posterous site to test, and it does indeed work now.

    ReplyDelete
  21. Got this again :(





    No worries about it though. I can either manually do it or wait for official support from posterous.

    Many thanks though for trying to help me!

    ReplyDelete
  22. Adam, if you're still there, I would like to know the error you're getting.

    Everyone else, I improved the way that this script handles TwitPic posts with no text. (v1.2.4)

    ReplyDelete
  23. I've got everything running right now...going great! Thanks for all the updates. I was also able to contact Posterous to get an increased personal API limit, they were really quick to respond, so I've been able to do up to 200 items now instead of the API limit of 50.

    Thanks again for all the awesome work on this Tim!

    ReplyDelete
  24. Opps I forgot to remove the brackets. Here's the error message:

    rsp stat="fail"
    err code="3006" msg="Invalid date" /
    /rsp

    Happened with both 1.2.3 and 1.2.4

    ReplyDelete
  25. Adam,

    If you feel like running a test, you can insert these lines:
    echo "ID: $ID" >> test.txt
    echo "POST_DATE: $POST_DATE" >> test.txt
    echo "YEAR: $YEAR" >> test.txt
    echo "MONTH: $MONTH" >> test.txt
    echo "DAY: $DAY" >> test.txt
    echo "DATE_FORMATTED: $DATE_FORMATTED" >> test.txt
    echo >> test.txt

    ...just below this line:
    DATE_FORMATTED="$YEAR-$MONTH-$DAY"

    ReplyDelete
  26. All of them are like this:

    ID: yomgh
    POST_DATE: January 18, 2010
    YEAR:
    MONTH:
    DAY:
    DATE_FORMATTED: --

    ReplyDelete
  27. Thanks for your help and patience, Adam. It looks like the culprit was "sed -r", which I have eliminated from the script.

    Hopefully that does it. (v1.2.5)

    ReplyDelete
  28. v1.2.5 worked beautifully! Many thanks again :)

    ReplyDelete
  29. A huge thank you for your time writing this - copied the script to my tiny NSLU2 embedded linux server (Debian etch) and it did the business. Up yours TwitPic - now to delete my photos and unlink the account :)

    ReplyDelete
  30. Thank you for making this! I've been using it to learn shell scripting and it's been wonderful! I've been teaching myself by changing it to download locally and stop, versus going forward and posting to Posterous.

    A million times thanks :)

    ReplyDelete
  31. I could kiss you for this thing. The Posterous Import tool has been an epic fail, puking out after uploading 3 pictures, and it doesn't even upload the ORIGINAL resolution files, it only uploads the stupid 450x600 res version. This took a few minutes to figure out, but damn - PERFECT end result. The Posterous guys should give you a money hat and borrow your code.

    ReplyDelete
  32. Works pretty well but for my 124 Twitpic images, it hits the Posterous API too hard:

    rsp stat : "fail"
    err code : "3010", msg : "API rate limit reached"

    ReplyDelete
  33. Interesting. Is there somewhere where they post the default daily API limit?

    My guess would be 100. I could add two optional parameters: one to limit how many posts it uploads in that run, and a second to skip that number of posts before starting the upload.

    Do you think that would address your problem, Neil?

    ReplyDelete
  34. Actually, the first parameter could probably be embedded in the script if it's really a limit on the API.

    ReplyDelete
  35. API limits are here - http://posterous.com/api/posting. And they are pretty ridiculous; 50 posts per day.

    ReplyDelete
  36. If you ask support, they will up the limit for you. I think that's what they did for me.

    I have updated the script (v1.4.0) to automatically stop after 50, and to take an optional parameter that allows you to skip posts that have already been uploaded.

    ReplyDelete
  37. Excellent - I will give that a try. Thanks for all your work and the quick responses.

    ReplyDelete