Azure DevOps Update Refs - Delete Branch via API - azure-devops-rest-api

implemented a function to delete a branch on the azure devops:
function Remove-RemoteBranch {
param (
[Parameter(Mandatory = $true)]
[String]
$CollectionUri,
[Parameter(Mandatory = $true)]
[String]
$TeamProject,
[Parameter(Mandatory = $true)]
[String]
$Repository,
[Parameter(Mandatory = $true)]
[string]
$BranchName,
[Parameter(Mandatory = $true)]
[string]
$BranchID,
[Parameter(Mandatory = $true)]
[String]$AccessToken
)
#create PAT in B64 format"
$B64_PAT = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($AccessToken)"))
#Header for Authorization
$header = #{Authorization = 'Basic ' + $B64_PAT }
$body = ConvertTo-Json (
#{
name = $BranchName;
oldObjectId = $BranchID;
newObjectId = "0000000000000000000000000000000000000000";
})
$response = (Invoke-RestMethod -Method Post `
-Uri "$($CollectionUri)/$($TeamProject)/_apis/git/repositories/$($Repository)/refs/?api-version=4.1" `
-Body $body `
-ContentType "application/json" `
-Headers $header `
-UseBasicParsing)
if ($response.StatusCode -notmatch "200") {
throw "Statuscode from RestRequest is $($Response.status)"
}
}
I couldnt find a solution to my issue yet. I get the error "Value cannot be null.\r\nParameter name: refUpdates" if I send a request to the server. I couldn't find any advices in the MS docu. May be some of you folks have an idea.
Thank you in advance.
Edit:
I have found the answer. The body has to look like this:
$body = ConvertTo-Json (
#(
#{
name = $BranchName;
oldObjectId = $BranchID;
newObjectId = "0000000000000000000000000000000000000000";
}
)
)

I had the same issue and found my $body didn't have square brackets around it as per the docs
[
{
name = $BranchName;
oldObjectId = $BranchID;
newObjectId = "0000000000000000000000000000000000000000";
}
]

Related

wrk with lua script - generating multiple POST requests with different body

I wrote some lua script for wrk to generate multiple POST requests.
My problem is that my script is working only for the first request. All further generated requests are exactly the same as the first one. I would like that user variable will be new generated for each POST request:
lowerCase = "abcdefghijklmnopqrstuvwxyz"
characterSet = lowerCase
keyLength = 13
user = ""
math.randomseed(os.time())
for i = 1, keyLength do
rand = math.random(#characterSet)
user = user .. string.sub(characterSet, rand, rand )
end
wrk.path = "/somepath"
wrk.method = "POST"
wrk.body = [[{"username":"]].. user .. [[,"password":"somepassword"}]]
wrk.headers["Content-Type"] = "application/json"
Try something like this. It should execute request3 ~50% of the time, and the other two ~25% of the time. Cheers!
names = { "Maverick", "Goose", "Viper", "Iceman", "Merlin", "Sundown", "Cougar", "Hollywood", "Wolfman", "Jester" }
request1 = function()
headers = {}
headers["Content-Type"] = "application/json"
body = '{"name": ' .. names[math.random(#names)] .. '}'
return wrk.format("POST", "/test1", headers, body)
end
request2 = function()
headers = {}
headers["Content-Type"] = "application/json"
body = '{"name": ' .. names[math.random(#names)] .. '}'
return wrk.format("POST", "/test2", headers, body)
end
request3 = function()
headers = {}
headers["Content-Type"] = "application/json"
body = '{"name": ' .. names[math.random(#names)] .. '}'
return wrk.format("GET", "/test3", headers, body)
end
requests = {}
requests[0] = request1
requests[1] = request2
requests[2] = request3
requests[3] = request3
request = function()
return requests[math.random(0, 3)]()
end
response = function(status, headers, body)
if status ~= 200 then
io.write("------------------------------\n")
io.write("Response with status: ".. status .."\n")
io.write("------------------------------\n")
io.write("[response] Body:\n")
io.write(body .. "\n")
end
end
I'm not familiar with wrk.
I guess you're running that code multiple times within a second. As os.time has second accuracy you'll have the same randomseed and hence the same user name within that second.
From looking into the scripting examples I'd say the script is only evaluated once or maybe once per thread. Those examples implement functions that will be called by wrk. It wouldn't make sense to define those functions for every request.
Add a print to your script to make sure.
Here is an example that counts requests. You probably can put your code into that function
function request()
requests = requests + 1
return wrk.request()
end

Check for new files in multiple folders, Report that new file does or does not exist

I am a 2 day newbie with Powershell 2.0. I have searched and come this far, but I am stuck with what to do further. Please bear with me I tried to search!
Task: Create a PS file that searches subfolders in a folder. Each folder contains a site backup file. I need to know if a new file was created and report if the file was or was not created.
The PS file needs to do the following:
Check a folder
If new files exists say "ok" else "not OK"
Do this for 28 folders creating 28 statements
dump write-output to common function (email)
use data from email in the body of an email.
Problems:
One search goes OK, when I add another I get false answers. I suspect this has something to do with using the same variables over and over.
I'm still a bit lost on how to get a carriage return to work in the body of the email. Everything goes on one continuous line.
I am suspecting I have unneeded statements in my creation. The file is bits and pieces of answers I have found here. I am having trouble putting it together properly for my needs. Guidance would be greatly appreciated.
#Site #1
$fullPath = "\\10.10.1.5\working\$folder"
$folder1= "test1"
$numdays = 0
$numhours = 10
$nummins = 0
$site = "site 1"
function Verify1($path, $days, $hours, $mins)
{$files = #(get-childitem $path -include *.* -recurse | where {($_.LastWriteTime -gt (Get-Date).AddDays(-$days).AddHours(-$hours).AddMinutes(-$mins)) -and ($_.psIsContainer -eq $false)})
if ($files -ne $NULL)
{$file = $files
write-host ("The backup File for " + $site + " was backed up successfully!!")}
else {write-host ("The backup File for " + $site + " WAS NOT backed up successfully!!")}}
Verify1 $fullPath $numdays $numhours $nummins
#Site #2
$fullPath = "\\10.10.1.5\working\$folder"
$folder2= "test2"
$numdays2 = 0
$numhours2 = 10
$nummins2 = 0
$site = "site 2"
function Verify2($path, $days, $hours, $mins)
{$files = #(get-childitem $path -include *.* -recurse | where {($_.LastWriteTime -gt (Get-Date).AddDays(-$days).AddHours(-$hours).AddMinutes(-$mins)) -and ($_.psIsContainer -eq $false)})
if ($files -ne $NULL)
{$file = $files
write-host ("The backup File for " + $site + " was backed up successfully!!")}
else {write-host ("The backup File for " + $site + " WAS NOT backed up successfully!!")}}
Verify2 $fullPath2 $numdays $numhours $nummins
function email {
process { Write-Host $_ }
}
#verify1 | email
#verify2 | email
$date = (Get-Date).ToString('MM/dd/yyyy')
$EmailFrom = "email#gmail.com"
$EmailTo = "email#gmail.com"
$Subject = ("Daily Database Report for " + $date)
[string]$body = ""
foreach ($email in $emails) {$body = $body + "`r`n"}
$SMTPServer = "smtp.gmail.com"
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587)
$SMTPClient.EnableSsl = $true
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential("user", "password");
$SMTPClient.Send($EmailFrom, $EmailTo, $Subject, $Body)
Problem 1
Issue looks likes coming from the variables carrying the same name.
If you look at site 2, it has full path looking at $folder which does not exist in either config blocks.
Something like
#Config Block
#Folders
$folder1= "test1"
$folder2= "test2"
#Remote Paths
$fullPath1 = "\\10.10.1.5\working\$folder1"
$fullPath2 = "\\10.10.1.5\working\$folder2"
#Site Names
$site1 = "Site 1"
$site2 = "Site 2"
#Time Difference
$numdays = 0
$numhours = 10
$nummins = 0
#Function
function VerifySite($Path, $Site, $Days, $Hours, $Mins)
{$files = #(get-childitem $path -include *.* -recurse | where {($_.LastWriteTime -gt (Get-Date).AddDays(-$days).AddHours(-$hours).AddMinutes(-$mins)) -and ($_.psIsContainer -eq $false)})
if ($files -ne $NULL)
{$file = $files
write-host ("The backup File for " + $site + " was backed up successfully!!")}
else {write-host ("The backup File for " + $site + " WAS NOT backed up successfully!!")}}
VerifySite $fullPath1 $Site1 $numdays $numhours $nummins
VerifySite $fullPath2 $Site2 $numdays $numhours $nummins
might archive the desired results. Cleaned up the configuration so it can be read easier and removed the second verify function as it wasn't required.
Had a chance to revist this and look at problem 2.
Problem 2.
Email body.
I reworked it a bit to produce a log file. I then built the email body from the logfile and finally removed the logfile
#Config Block
#Folders
$folder1= "test1"
$folder2= "test2"
$folder3= "test3"
$folder4= "test4"
$folder5= "test5"
#Remote Paths
$fullPath1 = "\\10.10.1.5\working\$folder1"
$fullPath2 = "\\10.10.1.5\working\$folder2"
$fullPath3 = "\\10.10.1.5\working\$folder3"
$fullPath4 = "\\10.10.1.5\working\$folder4"
$fullPath5 = "\\10.10.1.5\working\$folder5"
#Site Names
$site1 = "Site 1"
$site2 = "Site 2"
$site3 = "Site 3"
$site4 = "Site 4"
$site5 = "Site 5"
#Time Difference
#Days
$numdays1 = 0
$numdays2 = 1
#Hours
$numhours1 = 10
$numhours2 = 15
#Mins
$nummins1 = 0
$nummins2 = 0
#Dates
$date = (Get-Date).ToString('MM/dd/yyyy')
$Logdate = (Get-Date).ToString('MMddyyyy')
#logs
$logFile = "D:\Log_$Logdate.txt"
#Email
$EmailFrom = "email#gmail.com"
$EmailTo = "email#gmail.com"
$Subject = ("Daily Database Report for " + $date)
#Function
function VerifySite($Path, $Site, $Days, $Hours, $Mins)
{$files = #(get-childitem $path -include *.* -recurse | where {($_.LastWriteTime -gt (Get-Date).AddDays(-$days).AddHours(-$hours).AddMinutes(-$mins)) -and ($_.psIsContainer -eq $false)})
if ($files -ne $NULL)
{$file = $files
write-output ($Date + " The backup File for " + $site + " was backed up successfully!!") | Out-File $logFile -Append }
else {write-output ($Date + " The backup File for " + $site + " WAS NOT backed up successfully!!") | Out-File $logFile -Append}}
#Commands
VerifySite $fullPath1 $Site1 $numdays2 $numhours1 $nummins1
VerifySite $fullPath2 $Site2 $numdays1 $numhours2 $nummins2
VerifySite $fullPath3 $Site3 $numdays1 $numhours1 $nummins1
VerifySite $fullPath4 $Site4 $numdays1 $numhours2 $nummins1
VerifySite $fullPath5 $Site5 $numdays2 $numhours1 $nummins2
[string]$body = ""
$logs = Get-Content $logFile
foreach ($log in $logs )
{
$body = $body + $log + "`r`n"
}
$SMTPServer = "smtp.gmail.com"
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587)
$SMTPClient.EnableSsl = $true
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential("user", "password");
$SMTPClient.Send($EmailFrom, $EmailTo, $Subject, $Body)
#Cleanup if required.
remove-item $logFile
You should get $body returning something like
11/02/2015 The backup File for Site 1 WAS NOT backed up successfully!!
11/02/2015 The backup File for Site 2 was backed up successfully!!
Also reworked the variables a bit to show how it can be expanded.

Twitter API app-only authorization error

I am following this https://dev.twitter.com/oauth/application-only
def get_bearer_token(self):
data = {"grant_type": "client_credentials"}
headers = {"Authorization": "Basic " + self.encoded_cred}
r = requests.post("https://api.twitter.com/oauth2/token",
data=data, headers=headers)
res = r.json()
if res.get('token_type') != 'bearer':
raise Exception("invalid type")
self.access_token = res['access_token']
def search(self, q):
data = {"count": 100, "q": q}
headers = {"Authorization": "Bearer " + self.access_token}
r = requests.get("https://api.twitter.com/1.1/search/tweets.json", data=data, headers=headers)
print r.status_code
print r.text
I was able to get an access_token but the search API call returns 400 with no content. Any idea?
Similar to this https://stackoverflow.com/questions/24102409/twitter-application-only-auth-returning-empty-response but no answer yet

How to upload file into box.com

i am working on file upload into box.com but i am stuck there. i used Net::HTTP for that and i need the help of regarding this library.
my main code which interact to box.com is
module BoxApi
class FileOperation < Base
attr_reader :upload_path
def initialize
super
#upload_path = "https://upload.box.com/api/2.0/files/content"
end
#here filder_id args denote folder inside upload file and file args hold the content of file which are uploaded by file_field
def upload(folder_id, file)
boundary = "AaB03x"
body = []
body << "--#{boundary}\r\n"
body << "Content-Disposition: form-data; name='filename'; filename=#{file.original_filename}\r\n"
body << "Content-Type: text/plain\r\n\r\n"
body << file
body << "--#{boundary}\r\n"
body << "Content-Disposition: form-data; name='parent_id'"
body << "\r\n"
body << folder_id
body << "\r\n--#{boundary}--\r\n"
https_post(URI.parse("#{upload_path}"), body, boundary)
# `curl "Authorization: Bearer MlaNbyAefUWrawZEqGkDKvq9foCmQ0lL" -F filename=#./public/404.html -F parent_id='#{folder_id}' #{upload_path}`
rescue => ex
p "Exception caught (1) ==> #{ex}"
end
private
def https_post(uri, body, boundary)
http = https_setting(uri)
request = Net::HTTP::Post.new(uri.request_uri)
# request.body = JSON.parse(body)
request.body = body.join
request["Content-Type"] = "multipart/form-data, boundary=#{boundary}"
request["Authorization"] = "Bearer #{box_token.token}"
http.request(request)
rescue => ex
p "Exception caught (2) ==> #{ex}"
end
def https_setting(uri)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
http
end
end
end
Here's my Powershell code which uses System.Net.HttpWebRequest
param(
$FileRequestID ,
$FileToUpload
)
$BoxDomain = "yourenterprise.ent.box.com"
$URL = "https://$($BoxDomain)/app-api/file-request-web/public/file-request?urlId=$($FileRequestID)"
$resultsRaw = Invoke-WebRequest -Uri $URL -Method GET -UseBasicParsing
$resultsJson = ConvertFrom-Json $resultsRaw.Content
$boxFileRequestId = $resultsJson.id
$boxFolderId = $resultsJson.folder.id
$fileInfo = [System.IO.FileInfo]$FileToUpload
$ProcessStartDateTime = Get-Date
$ProgressName = "$($fileInfo.Name) Upload Progress"
$requestContent = "{`"fileRequestURL`":`"$($FileRequestID)`",`"formVersionId`":`"303881722`",`"values`":{`"element-0`":{`"type`":`"files`",`"data`":[{`"local_path`":`"$($fileInfo.Name)`",`"size`":$($fileInfo.Length)}]},`"folder`":{`"type`":`"folder`",`"id`":`"$($boxFolderId)`"}}}"
$UploadFormResponse = Invoke-WebRequest -Uri "https://$($BoxDomain)/app-api/file-request-web/public/form-response" -Method POST -ContentType "application/json;charset=UTF-8" -Body $requestContent -UseBasicParsing
$UploadFormResponseJson = ConvertFrom-Json $UploadFormResponse.Content
$requestContent = "{`"name`":`"$($fileInfo.Name)`",`"parent`":{`"id`":`"$($boxFolderId)`"},`"size`":$($fileInfo.Length)}"
$OptionsResponse = Invoke-WebRequest -Uri "https://$($BoxDomain)/api/2.1/files/content" -Method OPTIONS -Body $requestContent -Headers #{ Authorization = "Bearer $($UploadFormResponseJson.uploadToken)";} -UseBasicParsing
$OptionsResponseJson = ConvertFrom-Json $OptionsResponse.Content
$UploadURL = $OptionsResponseJson.upload_url
$boundary = "---------------------------" +[System.DateTime]::Now.Ticks.ToString("x");
$boundarybytes = [System.Text.Encoding]::ASCII.GetBytes("`r`n--" + $boundary + "`r`n");
$wr = [System.Net.HttpWebRequest]([System.Net.WebRequest]::Create($UploadURL));
$wr.ContentType = "multipart/form-data; boundary=" + $boundary;
$wr.Method = "POST";
$wr.KeepAlive = $true;
$wr.PreAuthenticate = $true
$wr.Headers.Add("Authorization", "Bearer $($UploadFormResponseJson.uploadToken)")
$wr.AllowWriteStreamBuffering = $false
$wr.SendChunked = $true
$rs = $wr.GetRequestStream();
#Write attributes
$rs.Write($boundarybytes, 0, $boundarybytes.Length);
$formAttributes = "Content-Disposition: form-data; name=`"attributes`"`r`n`r`n{`"name`":`"$($fileInfo.Name)`",`"parent`":{`"id`":`"$($boxFolderId)`"},`"content_modified_at`":`"$($fileInfo.LastWriteTimeUtc.ToString("yyyy-MM-ddTHH:mm:ssZ"))`"}"
$formAttributesBytes = [System.Text.Encoding]::UTF8.GetBytes($formAttributes)
$rs.Write($formAttributesBytes, 0, $formAttributesBytes.Length)
#Write File
$rs.Write($boundarybytes, 0, $boundarybytes.Length);
$formFile = "Content-Disposition: form-data; name=`"file`"; filename=`"$($fileInfo.Name)`"`r`nContent-Type: application/octet-stream`r`n`r`n"
$formFileBytes = [System.Text.Encoding]::UTF8.GetBytes($formFile)
$rs.Write($formFileBytes, 0, $formFileBytes.Length)
[System.IO.FileStream]$fileStream = [System.IO.File]::Open($fileInfo.FullName, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::ReadWrite)
$buffer = [System.Byte[]]::new(1048576)
$bytesRead = 0;
$totalBytesRead = 0
$totalBytesToRead = $fileInfo.Length
while (($bytesRead = $fileStream.Read($buffer, 0, $buffer.Length)) -ne 0) {
$rs.Write($buffer, 0, $bytesRead);
$rs.Flush()
$totalBytesRead += $bytesRead
$SecondsElapsed = ((Get-Date) - $ProcessStartDateTime).TotalSeconds
$SecondsRemaining = ($SecondsElapsed / ($totalBytesRead / $totalBytesToRead)) - $SecondsElapsed
Write-Progress -Activity $ProgressName -PercentComplete (($totalBytesRead/$($totalBytesToRead)) * 100) -CurrentOperation "$("{0:N2}" -f ((($totalBytesRead/$($totalBytesToRead)) * 100),2))% Complete" -SecondsRemaining $SecondsRemaining
}
$fileStream.Close();
$trailerBytes = [System.Text.Encoding]::ASCII.GetBytes("`r`n--" + $boundary + "`r`n");
$rs.Write($trailerBytes, 0, $trailerBytes.Length);
$rs.Close();
#Done writing File
$wresp = $wr.GetResponse();
$wresp.StatusCode
$stream2 = $wresp.GetResponseStream();
$reader2 = New-Object -TypeName System.IO.StreamReader -ArgumentList $stream2
$response = ConvertFrom-Json ($reader2.ReadToEnd())
#$response
This is a translation of the code by #NitrusCS into Bash.
It took a while and it's not identical, but it works.
#!/bin/bash
#CONSTANTS
BoxDomain="yourenterprise.ent.box.com"
formVersionId="1576913797"
#FUNCTIONS
function getdate() {
date "+%A, %B %d, %Y %I:%M:%S %p" | sed 's/am$/AM/g' | sed 's/pm$/PM/g'
}
function datetimeinticks() {
printf '%x\n' $(echo $(($(($(date '+%s') - $(date -d "0001-01-01T00:00:00.0000000 +0200" '+%s'))) * 10000000 + $((10#$(date '+%N')/100)) )))
}
#ARGUMENTS
FileRequestID="$1"
FileToUpload="$2"
FileName=$(basename $FileToUpload)
FileLength=$(stat --printf="%s" "$FileToUpload")
#MAIN CODE
URL="https://$BoxDomain/app-api/file-request-web/public/file-request?urlId=$FileRequestID"
echo -n "[$FileName] Preparing for upload: 0%"
resultsRaw=$(curl -s -X GET "$URL")
echo "$resultsRaw" > ${FileName}_errors.log
echo -en "\r[$FileName] Preparing for upload: 33%"
boxFolderId=$(echo $resultsRaw | jq ".folder" | jq ".id")
ProcessStartDateTime=$(getdate)
requestContent="{\"fileRequestURL\": \"$FileRequestID\",\"formVersionId\": \"$formVersionId\",\"values\":{\"element-0\":{\"type\":\"files\",\"data\":[{\"local_path\":\"$FileName\",\"size\":$FileLength}]},\"folder\":{\"type\":\"folder\",\"id\":$boxFolderId}}}"
UploadFormResponse=$(curl -s "https://$BoxDomain/app-api/file-request-web/public/form-response" -X POST -H "content-type: application/json;charset=UTF-8" -d "$requestContent")
echo "$UploadFormResponse" >> ${FileName}_errors.log
echo -en "\r[$FileName] Preparing for upload: 67%"
uploadToken=$(echo $UploadFormResponse | jq ".uploadToken" | sed 's/^\"//g' | sed 's/\"$//g')
requestContent="{\"name\":\"$FileName\",\"parent\":{\"id\":$boxFolderId},\"size\":$FileLength}"
OptionsResponse=$(curl -s "https://$BoxDomain/api/2.1/files/content" -X OPTIONS -H "Authorization: Bearer $uploadToken" -d "$requestContent")
echo "$OptionsResponse" >> ${FileName}_errors.log
echo -e "\r[$FileName] Preparing for upload: 100% ... "
UploadURL=$(echo $OptionsResponse | jq ".upload_url" | sed 's/^\"//g' | sed 's/\"$//g')
boundary="---------------------------$(datetimeinticks)"
LastWriteTimeUtc=$(date -u -d "$(stat --printf=%y "$FileToUpload")" '+%Y-%m-%dT%H:%M:%SZ')
boundarystring="$(echo -en "\r\n--" ; echo -n $boundary ; echo -en "\r\n" ; echo .)"
boundarystring=${boundarystring%.}
rs="${FileName}_requestdata.http"
touch $rs
echo -n "$boundarystring" > $rs
formAttributes="$(echo -en "Content-Disposition: form-data; name=\"attributes\"\r\n\r\n{\"name\":\"$FileName\",\"parent\":{\"id\":$boxFolderId},\"content_modified_at\":\"$LastWriteTimeUtc\"}" ; echo .)"
formAttributes=${formAttributes%.}
echo -n "$formAttributes" >> $rs
echo -n "$boundarystring" >> $rs
formFile="$(echo -en "Content-Disposition: form-data; name=\"file\"; filename=\"$FileName\"\r\nContent-Type: application/octet-stream\r\n\r\n" ; echo .)"
formFile=${formFile%.}
echo -n "$formFile" >> $rs
echo -n "[$FileName] Preparing the file to upload..."
cat "$FileToUpload" >> $rs
trailerstring="$(echo -en "\r\n--" ; echo -n $boundary ; echo -en "--\r\n" ; echo .)"
trailerstring=${trailerstring%.}
echo -n "$trailerstring" >> $rs
echo "[$FileName] Uploading:"
response=$(curl -X POST -H "content-type: multipart/form-data; boundary=$boundary" -H "Authorization: Bearer $uploadToken" --data-binary #$rs "$UploadURL")
echo "$response" >> ${FileName}_errors.log
echo $response | grep -q '"type":"file"' && { echo "[$FileName] Upload complete" ; rm ${FileName}_errors.log ; rm $rs ; }
echo $response | grep -q '"type":"file"' || echo "[$FileName] Upload failed: See file ${FileName}_errors.log for details."
Another translation of #NitrusCS into Python3 using the requests library. I was inspired by the bash code of #Kubuntuer82.
I'll include the gist here:
import datetime
import requests
import urllib
import os.path
import sys
import json
#
# Given a "File Request URL" and a local file, this program uploads to a box folder.
#
class BoxUploader(object) :
def __init__(self, requestURL) :
self.request_url = requestURL
o = urllib.parse.urlparse(requestURL)
self.boxDomain = o.hostname
self.fileRequestId = os.path.basename(o.path)
self.initialUrl = 'https://' + self.boxDomain + '/app-api/file-request-web/public/file-request?urlId=' + self.fileRequestId
self.formResponseUrl = 'https://' + self.boxDomain + '/app-api/file-request-web/public/form-response'
self.optionsUrl = 'https://' + self.boxDomain + '/api/2.1/files/content'
def upload_file(self, fname) :
#
# Initial call to the "get" url
#
rfc3339_format='%Y-%m-%dT%H:%M:%S%z'
response = requests.get(self.initialUrl)
jsonResponse = response.json()
basename = os.path.basename(fname)
local_timezone= datetime.datetime.now(datetime.timezone.utc).astimezone().tzinfo
modifiedTime = datetime.datetime.fromtimestamp(os.path.getmtime(fname), tz=local_timezone)
#
# Submit a form response to get an upload token
#
boxFileRequestId = jsonResponse['id']
boxFolderId = jsonResponse['folder']['id']
formVersionId = jsonResponse['form']['versionId']
fileLength = os.path.getsize(fname)
print("Form Version ID: " + formVersionId)
requestContent = { "fileRequestURL" : self.fileRequestId,
"formVersionId" : formVersionId,
"values" : {"element-0" : { "type":"files", "data":[ {"local_path":fname, "size":fileLength}] },
"folder" : {"type" : "folder", "id": boxFolderId}}}
uploadFormResponse = requests.post(self.formResponseUrl, json=requestContent)
uploadFormResponseJson = uploadFormResponse.json()
#
# Make a call to the options url to get the actual url to
# upload the file to.
#
uploadToken = uploadFormResponseJson['uploadToken']
headers = { "Authorization" : "Bearer " + uploadToken }
requestContent = { "name" : fname,
"parent": { "id" : boxFolderId },
"size": fileLength}
optionsResponse = requests.options(self.optionsUrl, headers=headers, json=requestContent)
optionsResponseJson = optionsResponse.json()
# Upload the file.
upload_url = optionsResponseJson['upload_url']
form_attributes = { 'name' : fname,
'parent': {"id": boxFolderId},
'content_modified_at' : modifiedTime.strftime(rfc3339_format) }
files={ 'attributes' : (None, json.dumps(form_attributes), 'application/json', {'Content-Disposition':'form-data'}),
'file' : (fname, open(fname, 'rb')) }
#upload_request = requests.Request('POST', upload_url, headers=headers, files=files).prepare()
#print(upload_request.headers)
#print(upload_request.body)
uploadResponse = requests.post(upload_url, headers=headers, files=files)
print(json.dumps(uploadResponse.json(), indent=2))
def main(requestUrl, file) :
uploader = BoxUploader(requestUrl)
uploader.upload_file(file)
if __name__ == '__main__' :
url = sys.argv[1]
file = sys.argv[2]
main(url, file)

Upload image to twitter using update_with_media - Lua

I am trying to post an image to twitter using update_with_media.json.
The following is a working code to update tweet with statuses/update.json
local url = "http://api.twitter.com/1/statuses/update.json"
local consumer_key = ""
local consumer_secret = ""
local token = ""
local token_secret = ""
local post_data =
{
oauth_consumer_key = consumer_key,
oauth_nonce = get_nonce(),
oauth_signature_method = "HMAC-SHA1",
oauth_token = token,
oauth_timestamp = get_timestamp(),
oauth_version = '1.0',
oauth_token_secret = token_secret
}
post_data["status"] = "Hello Twitter!"
post_data = oAuthSign(url, "POST", post_data, consumer_secret)
r,c,h = http.request
{
url = url,
method = "POST",
headers =
{
["Content-Type"] = "application/x-www-form-urlencoded",
["Content-Length"] = string.len(rawdata)
},
source = ltn12.source.string(post_data),
sink = ltn12.sink.table(response)
}
Now how do I modify the above code to upload images?
The url would be "http://api.twitter.com/1/statuses/update_with_media.json" and
headers["Content-Type"] would be "multipart/form-data"
But where and how do I specify the image to be uploaded?
Ok I got this working some time back..
This post by velluminteractive provides a good library to deal with twitter.
Admittedly the code is for a game engine called Corona SDK. But it shouldn't be too hard for others to use by removing Corona-specific elements from it.

Resources