mandag 7. mai 2012

Uploading images to ImageBam using PowerShell and cURL


Do you need to automate a task to upload images to a free host with gallery functionality? Then this script could be your solution.

This script uses following tools:
- cURL, http://curl.haxx.se
- HtmlAgilityPack, http://htmlagilitypack.codeplex.com
- PowerShell 2.0, http://support.microsoft.com/kb/968929
- ImageBam API, http://code.google.com/p/imagebam-api/ (To access API, register here: http://www.imagebam.com/sys/API/clients)

This script takes care of OAuth authentication and authorization (the dirty way, without user consent, lol)


  1. $basedrive ="C:"  
  2. $basedir = "imagebam/"  
  3. $basepath = ($basedrive + "/" + $basedir)  
  4.   
  5. Add-Type -Assembly System.ServiceModel.Web,System.Runtime.Serialization  
  6. Add-Type -AssemblyName System.Web  
  7. add-type -Path ($basepath+"\HtmlAgilityPack.dll")  
  8.   
  9.   
  10. $responsefile = "response.txt"  
  11. $headerfile = "headers.txt"  
  12. $ib_nick = "MyImageBamNick"  
  13. $ib_pw = "MyImageBamPW"  
  14. $api_key = "FILL_IN"  
  15. $api_secret = "FILL_IN"  
  16. $oauth_token = "FILL_IN_AFTER_AUHTORIZED"  
  17. $oauth_token_secret = "FILL_IN_AFTER_AUHTORIZED"  
  18.   
  19. $oauth_nonce = 0  
  20. $oauth_timestamp = 0  
  21. $oauth_signature_method = "MD5";  
  22. $random = New-Object -type Random  
  23. $htmldoc = New-Object HtmlAgilityPack.HtmlDocument  
  24.   
  25. $basedrive  
  26. cd\  
  27. cd $basepath  
  28. cls  
  29.   
  30. function MD5($inputstring)  
  31. {  
  32.   
  33.     #Borrowed this snippet from Daniel Damen http://www.out-web.net/?p=334  
  34.   
  35.     $result = ""  
  36.     $cryptoServiceProvider = [System.Security.Cryptography.MD5CryptoServiceProvider];  
  37.     $hashAlgorithm = new-object $cryptoServiceProvider  
  38.     $hashByteArray = $hashAlgorithm.ComputeHash([Char[]]$inputString);  
  39.     foreach ($byte in $hashByteArray) { $result += “{0:X2}” -f $byte}  
  40.     return $result.ToLower()  
  41. }  
  42. function GetUnixTimeStamp()  
  43. {  
  44.   
  45.     #Borrowed this piece of code from: http://dev.healthx.com/Home/powershell-NET   
  46.   
  47.     $epoch = New-Object -type DateTime(1970, 1, 1)  
  48.     $unixts = [int] ([System.DateTime]::Now.ToUniversalTime() - $epoch).TotalSeconds  
  49.     return $unixts.ToString()  
  50. }  
  51.   
  52. function Login()  
  53. {  
  54.     $login = "action=true&nick=" + $ib_nick + "&pw=" + $ib_pw  
  55.     & curl -L -c cookie.txt -D loginheaders.txt -o login.html -d $login http://www.imagebam.com/login  
  56. }  
  57.   
  58. function Authenticate()  
  59. {  
  60.     $url = "http://www.imagebam.com/sys/oauth/request_token"  
  61.     $dataresponse = ""  
  62.     $data = ""  
  63.       
  64.     $oauth_timestamp = GetUnixTimeStamp  
  65.     $oauth_nonce = $random.Next().ToString()  
  66.       
  67.     #build signature string  
  68.     $oauth_signature_string = $api_key + $api_secret + $oauth_timestamp + $oauth_nonce  
  69.     #write-host "oauth_signature_string: " -nonewline   
  70.     #write-host $oauth_signature_string -foregroundcolor Blue  
  71.       
  72.     #compute md5 hash of signature string  
  73.     $oauth_signature = MD5($oauth_signature_string)  
  74.     #write-host "oauth_signature: " -nonewline  
  75.     #write-host $oauth_signature -foregroundcolor Blue  
  76.       
  77.     #build http POST data string  
  78.     $data =   "oauth_consumer_key=" + $api_key  
  79.     $data += "&oauth_signature_method=" + $oauth_signature_method  
  80.     $data += "&oauth_signature=" + $oauth_signature  
  81.     $data += "&oauth_timestamp=" + $oauth_timestamp  
  82.     $data += "&oauth_nonce=" + $oauth_nonce  
  83.     #write-host "auth_params: " -nonewline   
  84.     #write-host $data -foregroundcolor Blue  
  85.       
  86.     #delete exisiting response files  
  87.     if( Test-path ($basepath + $responsefile) ) { del $responsefile }  
  88.     if( Test-path ($basepath + $headerfile) ) { del $headerfile }  
  89.       
  90.     #send request  
  91.     & curl -s -d $data -D $headerfile -o $responsefile $url  
  92.       
  93.     #read response data  
  94.     $dataresponse =  (Get-Content $responsefile)  
  95.     $httpresponse =  (Get-Content $headerfile)[0].Replace("HTTP/1.1 ","").Substring(0,3)  
  96.     #write-host $httpresponse  
  97.       
  98.     #write-host "oauth response: "  -nonewline   
  99.     #write-host $response -foregroundcolor Blue  
  100.       
  101.     #parse response data: variable1=value1&variable2=value2  
  102.     $authdata = [regex]::split($dataresponse"&")  
  103.     $ot = [regex]::split($authdata[0], "=")[1]  
  104.     $ots = [regex]::split($authdata[1], "=")[1]  
  105.     Set-Variable -Name oauth_token -Value $ot -Scope global  
  106.     Set-Variable -Name oauth_token_secret -Value $ots -Scope global  
  107.     write-host "oauth_token: "  -nonewline   
  108.     write-host $oauth_token -foregroundcolor Blue  
  109.     #write-host "oauth_token_secret: "  -nonewline   
  110.     #write-host $oauth_token_secret -foregroundcolor Blue  
  111. }  
  112. function Authorize()  
  113. {  
  114.     $url = "http://www.imagebam.com/sys/oauth/authorize_token"  
  115.     $urla = ($url + "?oauth_token=" + $oauth_token)  
  116.     #login to get cookies  
  117.     Login  
  118.     #Give this script access to your ImageBam account  
  119.     & curl -s -b cookie.txt -c cookie.txt -o "authorize.html" $urla  
  120.     $htmldoc.Load(($basepath + "authorize.html"))  
  121.     $oa = $htmldoc.DocumentNode.SelectSingleNode("//input[@name='oauth_token']").Attributes["value"].Value  
  122.     $oas = $htmldoc.DocumentNode.SelectSingleNode("//input[@name='token_auth_sec']").Attributes["value"].Value  
  123.   
  124.     $data = "submit=yes&authorize=true&oauth_token=" + $oa + "&token_auth_sec=" + $oas  
  125.     & curl -s -b cookie.txt -c cookie.txt -D $headerfile -d $data -o "authorizepin.html" $url  
  126.     $htmldoc.Load(($basepath + "authorizepin.html"))  
  127.     $oauth_verifier = $htmldoc.DocumentNode.SelectSingleNode("//div[@style='font-size:22px; margin-top:20px;']").InnerHtml.Trim()  
  128.     write-host "shared secret: "  $oauth_verifier  
  129.     $oauth_timestamp = GetUnixTimeStamp  
  130.     $oauth_nonce = $random.Next().ToString()  
  131.       
  132.     $oauth_signature_string = $api_key + $api_secret + $oauth_timestamp + $oauth_nonce + $oauth_token + $oauth_token_secret  
  133.     #write-host "oauth_signature_string: " -nonewline   
  134.     #write-host $oauth_signature_string -foregroundcolor Blue  
  135.       
  136.     #compute md5 hash of signature string  
  137.     $oauth_signature = MD5($oauth_signature_string)  
  138.     #write-host "oauth_signature: " -nonewline  
  139.     #write-host $oauth_signature -foregroundcolor Blue  
  140.       
  141.     #build http POST data string  
  142.     $data  = " oauth_consumer_key=" + $api_key  
  143.     $data += "&oauth_token=" + $oauth_token  
  144.     $data += "&oauth_signature_method=" + $oauth_signature_method  
  145.     $data += "&oauth_signature=" + $oauth_signature  
  146.     $data += "&oauth_timestamp=" + $oauth_timestamp  
  147.     $data += "&oauth_nonce=" + $oauth_nonce  
  148.     $data += "&oauth_verifier=" + $oauth_verifier  
  149.       
  150.     $url = "http://www.imagebam.com/sys/oauth/request_access_token"  
  151.     #send request  
  152.     & curl -s -b cookie.txt -c cookie.txt -d $data -D $headerfile -o $responsefile $url  
  153.       
  154.     #read response data  
  155.     $dataresponse =  (Get-Content $responsefile)  
  156.     $httpresponse =  (Get-Content $headerfile)[0].Replace("HTTP/1.1 ","").Substring(0,3)  
  157.     #write-host $httpresponse  
  158.       
  159.     #write-host "oauth response: "  -nonewline   
  160.     #write-host $response -foregroundcolor Blue  
  161.       
  162.     #parse response data: variable1=value1&variable2=value2  
  163.     $authdata = [regex]::split($dataresponse"&")  
  164.     $ot = [regex]::split($authdata[0], "=")[1]  
  165.     $ots = [regex]::split($authdata[1], "=")[1]  
  166.     Set-Variable -Name oauth_token -Value $ot -Scope global  
  167.     Set-Variable -Name oauth_token_secret -Value $ots -Scope global  
  168.     write-host "new oauth_token: "  -nonewline   
  169.     write-host $oauth_token -foregroundcolor Blue  
  170.     write-host "oauth_token_secret: "  -nonewline   
  171.     write-host $oauth_token_secret -foregroundcolor Blue  
  172.           
  173. }  
  174. function UploadImage([string]$imagepath, [string]$contenttype, [string]$galleryid)  
  175. {  
  176.     $url = "http://www.imagebam.com/sys/API/resource/upload_image"  
  177.     $dataresponse = ""  
  178.     $data = ""  
  179.       
  180.     $oauth_timestamp = GetUnixTimeStamp  
  181.     $oauth_nonce = $random.Next().ToString()  
  182.       
  183.     #build signature string  
  184.     $oauth_signature_string = $api_key + $api_secret + $oauth_timestamp + $oauth_nonce + $oauth_token + $oauth_token_secret  
  185.     #write-host "oauth_signature_string: " -nonewline   
  186.     #write-host $oauth_signature_string -foregroundcolor Blue  
  187.       
  188.     #compute md5 hash of signature string  
  189.     $oauth_signature = MD5($oauth_signature_string)  
  190.     #write-host "oauth_signature: " -nonewline  
  191.     #write-host $oauth_signature -foregroundcolor Blue  
  192.       
  193.     #build http POST data string  
  194.     #authentication params  
  195.     $d1 = "oauth_consumer_key=" + $api_key  
  196.     $d2 = "oauth_signature_method=" + $oauth_signature_method  
  197.     $d3 = "oauth_signature=" + $oauth_signature  
  198.     $d4 = "oauth_timestamp=" + $oauth_timestamp  
  199.     $d5 = "oauth_nonce=" + $oauth_nonce  
  200.     $d6 = "oauth_token=" + $oauth_token  
  201.       
  202.     #image params  
  203.     $ct = ""  
  204.     if($imagepath.ToLower().EndsWith("jpg")){ $ct = ";type=image/jpeg"}  
  205.     elseif($imagepath.ToLower().EndsWith("png")) { $ct = ";type=image/png" }  
  206.     elseif($imagepath.ToLower().EndsWith("gif")) { $ct = ";type=image/gif" }  
  207.       
  208.     if ($contenttype -eq "") { $contenttype = "family"}  
  209.       
  210.     $d7 = "content_type=" + $contenttype  
  211.     $d8 = "gallery_id=" + $galleryid  
  212.     $d9 = "image=@" + $imagepath + $ct  
  213.       
  214.     #delete exisiting response files  
  215.     if( Test-path ($basepath + $responsefile) ) { del $responsefile }  
  216.     if( Test-path ($basepath + $headerfile) ) { del $headerfile }  
  217.     if( Test-path ($basepath + "trace.log") ) { del "trace.log" }  
  218.       
  219.     #send multipart form post request, disable Expect 100 continue header  
  220.     & curl -s -H "Expect:" -F $d1 -F $d2 -F $d3 -F $d4 -F $d5 -F $d6 -F $d7 -F $d8 -F $d9 -D $headerfile --trace-ascii trace.log -o $responsefile $url  
  221.       
  222.     #read response data  
  223.     $dataresponse =  (Get-Content $responsefile) -join "`n"  
  224.     $httpresponse =  (Get-Content $headerfile)[0].Replace("HTTP/1.1 ","").Substring(0,3)  
  225.     if ($httpresponse -ne "200")  
  226.     {  
  227.         write-host "Error: " -nonewline -foregroundcolor Black  
  228.         write-host $dataresponse -foregroundcolor Red  
  229.         $dataresponse = ""  
  230.     }  
  231.     #$jsondata = (Get-Content ($basepath + $responsefile)) -join "`n"  
  232.     return  Convert-JsonToXml $dataresponse  
  233.     #return $dataresponse  
  234.       
  235. }  
  236.   
  237. function CreateGallery([string]$title, [string]$description)  
  238. {  
  239.     $url = "http://www.imagebam.com/sys/API/resource/create_gallery"  
  240.     $dataresponse = ""  
  241.     $data = ""  
  242.       
  243.     $oauth_timestamp = GetUnixTimeStamp  
  244.     $oauth_nonce = $random.Next().ToString()  
  245.       
  246.     #build signature string  
  247.     $oauth_signature_string = $api_key + $api_secret + $oauth_timestamp + $oauth_nonce + $oauth_token + $oauth_token_secret  
  248.     #write-host "oauth_signature_string: " -nonewline   
  249.     #write-host $oauth_signature_string -foregroundcolor Blue  
  250.       
  251.     #compute md5 hash of signature string  
  252.     $oauth_signature = MD5($oauth_signature_string)  
  253.     #write-host "oauth_signature: " -nonewline  
  254.     #write-host $oauth_signature -foregroundcolor Blue  
  255.       
  256.     #build http POST data string  
  257.     #authentication params  
  258.     $data = "oauth_consumer_key=" + $api_key  
  259.     $data += "&oauth_signature_method=" + $oauth_signature_method  
  260.     $data += "&oauth_signature=" + $oauth_signature  
  261.     $data += "&oauth_timestamp=" + $oauth_timestamp  
  262.     $data += "&oauth_nonce=" + $oauth_nonce  
  263.     $data += "&oauth_token=" + $oauth_token  
  264.       
  265.     #gallery params  
  266.       
  267.     $data += "&title=" + [System.Uri]::EscapeDataString($title)  
  268.     $data += "&description=" + [System.Uri]::EscapeDataString($description)  
  269.       
  270.     #delete exisiting response files  
  271.     if( Test-path ($basepath + $responsefile) ) { del $responsefile }  
  272.     if( Test-path ($basepath + $headerfile) ) { del $headerfile }  
  273.     if( Test-path ($basepath + "trace.log") ) { del "trace.log" }  
  274.       
  275.     #send request, disable Expect 100 continue header  
  276.     & curl -s -H "Expect:" -d $data -D $headerfile --trace-ascii trace.log -o $responsefile $url  
  277.       
  278.     #read response data  
  279.     $dataresponse =  (Get-Content $responsefile) -join "`n"  
  280.     $httpresponse =  (Get-Content $headerfile)[0].Replace("HTTP/1.1 ","").Substring(0,3)  
  281.     if ($httpresponse -ne "200")  
  282.     {  
  283.         write-host "Error: " -nonewline -foregroundcolor Black  
  284.         write-host $dataresponse -foregroundcolor Red  
  285.         $dataresponse = ""  
  286.     }  
  287.     #$jsondata = (Get-Content ($basepath + $responsefile)) -join "`n"  
  288.     return  Convert-JsonToXml $dataresponse  
  289.     #return $dataresponse  
  290. }   
  291.   
  292. function Convert-JsonToXml([string]$json)  
  293. {  
  294.   
  295.     #Thanks to Joel Bennett: http://huddledmasses.org/json-from-powershell-but-why/    
  296.   
  297.     $bytes = [byte[]][char[]]$json  
  298.     $quotas = [System.Xml.XmlDictionaryReaderQuotas]::Max  
  299.     $jsonReader = [System.Runtime.Serialization.Json.JsonReaderWriterFactory]::CreateJsonReader($bytes,$quotas)  
  300.     try  
  301.     {  
  302.         $xml = new-object System.Xml.XmlDocument  
  303.    
  304.         $xml.Load($jsonReader)  
  305.         $xml  
  306.     }  
  307.     finally  
  308.     {  
  309.         $jsonReader.Close()  
  310.     }  
  311. }  
  312. #These are only needed first time, but you may have to re-authenticate if the authentication tokens exprire  
  313. #Authenticate  
  314. #Authorize  
  315.   
  316. #Create gallery ID, optional  
  317. $gallryxml = CreateGallery "My First Gallery"  
  318. $galleryid = $gallryxml.SelectSingleNode("//GID").InnerXml  
  319. write-host "Gallery ID:" $galleryid  
  320. $contenttype = "family" #family/adult  
  321. $files = dir C:\mypics |   Select-Object FullName, Directory, Name, Length | Sort-Object Name  
  322. foreach($file in $files)  
  323. {  
  324.       
  325.     write-host "Uploading " $file.FullName  
  326.  $xml = UploadImage $file.FullName $contenttype $galleryid    
  327.     $imagelink = $xml.SelectSingleNode("//URL").InnerXml  
  328.     $xml = $null  
  329.     write-host "Link: " $imagelink  
  330.     #[diagnostics.process]::start($imagelink)  
  331. }