You are not logged in.

#1 2009-10-18 07:23:55

lolilolicon
Member
Registered: 2009-03-05
Posts: 1,722

photobucket upload script, if you know python/bash/oauth, plz come in

Hello all.
I'm trying to write a script that uploads images or videos to photobucket. It's driving me nuts.
The script is ugly and I don't like the whole authorization thing. I'm just trying to get it to work.
I've already found photobucket-api-python at googlecode:

svn checkout http://photobucket-api-py.googlecode.com/svn/trunk/ photobucket-api-py-read-only

i tried to wrap may head round it but i couldn't. it's quite complete, surely somebody who fairly knows python should be able to use it with about less than 10 lines. Believe me, I tried, but failed. Please look at that python api and show me a working example. Or alternatively, please take a look at my bash code, if it doesn't hurt your eyes tongue

#!/bin/bash
LC_ALL=C
xml_parse () {
    local tag="$1"; [ -n "$2" ] &&
    echo "$2" | sed '/.*<'"${tag}"'>\([^<]*\)<\/'"${tag}"'>/!d;s//\1/' ||
    sed '/.*<'"${tag}"'>\([^<]*\)<\/'"${tag}"'>/!d;s//\1/'
}
str_parse () {
    local tag="$1"; [ -n "$2" ] &&
    echo "$2" | sed 's/.*'"${tag}"'=\([^&]*\).*/\1/' ||
    sed 's/.*'"${tag}"'=\([^&]*\).*/\1/'
}
calc_hash () {
    local basestring="$1" key="$2"
    echo -n "${basestring}" | openssl dgst -sha1 -binary -hmac "${key}" | base64
}
urlencode () {
    [ -n "$1" ] && echo -n "$1" | perl -MURI::Escape -lne 'print uri_escape($_)' ||
    perl -MURI::Escape -lne 'print uri_escape($_)'
}
timestamp () {
    date +%s  # curl -s http://api.photobucket.com/time
}
nonce () {
    echo $RANDOM | md5sum - | cut -d\  -f1
}
genstring () {
    local i; paramstring=$( (for ((i=0;i<${#params[@]};i++)); do echo "${params[$i]}" ; done) | sort | urlencode | sed 's/%3D/=/' | tr '\n' '&' | sed 's/&$//' )
}
genbase () {
    local uri=$(echo ${url} | sed 's/\/\/\w*/\/\/api/') # the url used to gen base is alwyas 'api.pho...'
    base="$(urlencode ${method})&$(urlencode ${uri})&$(urlencode ${paramstring})"
}
gensig () {
    signature=$(calc_hash "${base}" "${consumer_secret}&${token_secret}" | urlencode)
}
genurl () {
    authedurl="${url}?${paramstring}&oauth_signature=${signature}"
}

username='pubpbtest'
password='pubpbtest'
consumer_key='149829098'
consumer_secret='982136dd5d1ca425ff10444030e29f20'
version='1.0'
signature_method='HMAC-SHA1'
format='xml' # xml, json
defaults=("oauth_consumer_key=${consumer_key}"
          "oauth_signature_method=${signature_method}"
          "oauth_version=${version}"
          "format=${format}")

# request login req_token -- success
login_request () {
    method='POST'
    url='http://api.photobucket.com/login/request'
    params=("${defaults[@]}"
            "oauth_nonce=$(nonce)"
            "oauth_timestamp=$(timestamp)")
    genstring ; genbase ; gensig ; genurl
    info=$(curl -s --request "${method}" "${authedurl}")
    #returns: oauth_token=req_ed578a83b3c4293e90228429e0d0803990c891ba_1255756813&oauth_token_secret=4253861dc706e187cd6ddf8c8d4bbae95782a0ef&next_step=http%3A%2F%2Fphotobucket.com%2Fapilogin%2Flogin
    #echo "${info}"
    token=$(str_parse oauth_token "${info}")
    token_secret=$(str_parse oauth_token_secret "${info}")
}

# api login: go to user login page to complete authorizing 'req_' token. -- does not work, i'm doing it manually in firefox xD
api_login () {
    curl --request POST -L \
         -d "usernameemail=${username}" \
         -d "password=${password}" \
         "http://photobucket.com/apilogin/login?oauth_token=${token}"
}

# login_access: use req token, achieved by login_request AND confirmed by user
login_access () {
    method='POST'
    url='http://api.photobucket.com/login/access'
    params=("${defaults[@]}"
            "oauth_nonce=$(nonce)"
            "oauth_timestamp=$(timestamp)"
            "oauth_token=${token}")
    genstring ; genbase ; gensig ; genurl
    #echo ${authedurl}
    info=$(curl -s --request "${method}" "${authedurl}")
    #returns: oauth_token=50.328585_1255845849&oauth_token_secret=b7554e479a22132264cf9b0f7b61de11df31e779&username=pubpbtest&subdomain=api763.photobucket.com&homeurl=http%3A%2F%2Fs763.photobucket.com%2Falbums%2Fxx275%2Fpubpbtest%2F 
    echo "${info}"
    token=$(str_parse oauth_token "${info}")
    token_secret=$(str_parse oauth_token_secret "${info}")
    subdomain=$(str_parse subdomain "${info}")
}

# direct login -- success
direct_login () {
    method='POST'
    url="http://api.photobucket.com/login/direct/${username}"
    params=("${defaults[@]}"
            "oauth_nonce=$(nonce)"
            "oauth_timestamp=$(timestamp)"
            "password=${password}")
    genstring ; genbase ; gensig ; genurl
    info=$(curl -v --request "${method}" "${authedurl}")
    # returns: 
    #        <oauth_token>56.324998_1255750389</oauth_token>
    #        <oauth_token_secret>3b06f172ff5095ca7169c0ae0b382fd5081a2c30</oauth_token_secret>
    #        <username>pubpbtest</username>
    #        <subdomain>api961.photobucket.com</subdomain>
    echo "${info}"
    token=$(xml_parse oauth_token "${info}")
    token_secret=$(xml_parse oauth_token_secret "${info}")
    subdomain=$(xml_parse subdomain "${info}")
}

# upload media -- Authentication failed signature check failed
upload_image () {
    album='pubpbtest'
    method='POST'
    url="http://${subdomain}/album/${album}/upload"
    params=("${defaults[@]}"
            "oauth_nonce=$(nonce)"
            "oauth_timestamp=$(timestamp)"
            "oauth_token=${token}")
    genstring ; genbase ; gensig ; genurl
    #echo $token
    #echo $token_secret
    #echo $paramstring
    #echo $base
    #echo $signature
    #echo "${authedurl}"
    curl -v --request "${method}" -F 'type=image' -F 'uploadfile=@/tmp/image.jpg' "${authedurl}" # /tmp/image.jpg for test
}
#Login:
#login_request
#api_login
#login_access
#OR:
#direct_login
#Upload:
#upload_image

i've registered an account and an api key for you guys so you don't have to register by yourself. They're in the script.

login_request is successful, and it returns a token that starts with 'req_', which is only recognized by the /login/access method, and is used to request for a normal token(like 56.324998_1255750389). so i run login_access right after login_request, but it returns an Exception saying invalid token... Then I read more carefully the api docs and found i had to do api_login to validate the 'req_' token before doing login_access. I couldn't get api_login to work through curl so i did:

login_request ; echo "http://photobucket.com/apilogin/login?oauth_token=${token}" ; sleep 10 ; (/me goes to the echoed url within firefox and fill in the forms...) ;  login_access

The above method is called Web Login. Another way is direct_login, which seems successful. Returns as much info as a successful login_access.

but doing upload_image right after either login_access or direct_login fails with signature check failure...

i use /tmp/image.jpg for upload_image, you'll have to edit it to some valid image on your system.

Some reference to the photobucket api:
How to authorize request url:
http://pic.pbsrc.com/dev_help/WebHelpPu … cation.htm
Web Login:
http://pic.pbsrc.com/dev_help/WebHelpPu … cation.htm
Direct Login:
http://pic.pbsrc.com/dev_help/WebHelpPu … cation.htm
Methods, including login and upload:
http://pic.photobucket.com/dev_help/Web … ethods.htm

Last edited by lolilolicon (2009-10-18 07:31:32)


This silver ladybug at line 28...

Offline

Board footer

Powered by FluxBB