Create a gist now

Instantly share code, notes, and snippets.

Embed
What would you like to do?
$visionUrl = 'https://westcentralus.api.cognitive.microsoft.com/vision/v1.0/analyze'
$visionApiKey = 'your-api-key' #go to: https://azure.microsoft.com/en-gb/try/cognitive-services/
$visionFeatures = 'Description,Tags,Categories'
$rootPathOfImages = "/sitecore/media library/Your Site"
$testMode = $false
$secondsToWaitOnLimitError = 60
$successCount = 0
$errorCount = 0
$errorList = ""
$date = Get-Date
$formattedDate =$date.tostring('dd-mmm-yyyy-hhmmss')
$csvOutputFilePath = "C:\Windows\Temp\Missing-Alt-Text-Report-$($formattedDate).csv"
$createCsv = $true
$csvResults = @()
# List of template ids to exclude from processing
$excludedTemplateIds = @(
"{FE5DD826-48C6-436D-B87A-7C4210C7413B}", #media folder
"{0603F166-35B8-469F-8123-E8D87BEDC171}", #pdf
"{16692733-9A61-45E6-B0D4-4C0C06F8DD3C}", #doc
"{7BB0411F-50CD-4C21-AD8F-1FCDE7C3AFFE}", #docx
"{962B53C4-F93B-4DF9-9821-415C867B8903}", #unversioned file
"{E76ADBDF-87D1-4FCB-BA71-274F7DBF5670}", #unversioned movie
"{4F4A3A3B-239F-4988-98E1-DA3779749CBC}" #unversioned zip
)
# List of folder ids to exclude from processing
$excludedFolderIds = @(
"{23FAF40D-6700-480C-BCAD-92E23F60634C}" #wffm folder
)
if($testMode){
Write-Host -Foreground Yellow "Running in TEST MODE, no Alt Text will be set."
}
Write-Host "Finding Images with Missing Alt Text in root folder: $($rootPathOfImages) ..."
cd $rootPathOfImages
$images = Get-ChildItem -Recurse . | Where-Object {
($excludedTemplateIds -notcontains $_.TemplateId) `
-and ($excludedFolderIds -notcontains $_.ID) `
-and ($excludedFolderIds -notcontains $_.Parent.ID) `
-and ($excludedFolderIds -notcontains $_.Parent.Parent.ID) `
-and ($excludedFolderIds -notcontains $_.Parent.Parent.Parent.ID) `
-and ([string]::IsNullOrWhiteSpace($_.Fields["Alt"].Value)) `
}
Write-Host -Foreground Green "$($images.Count) Images Found With Missing Alt Text"
$result = @()
$counter = 0
$mediaUrloptions = New-Object Sitecore.Resources.Media.MediaUrlOptions
$mediaUrloptions.Width = 1000
$mediaUrloptions.UseItemPath = 0
foreach ($image in $images)
{
$counter+=1
# Sitecore
try{
# Reading the binary of the image so that we could send it to the Computer Vision API
Write-Host "Reading Image $($counter) of $($images.Count): $($image.ID) - $($image.Name) ...`n"
$id = $image.ID
$name = $image.Name
$displayName = $image.Fields["__Display name"].Value
$path = $image.ItemPath
$success = $False
$imageUrl = [Sitecore.Resources.Media.MediaManager]::GetMediaUrl($image, $mediaUrloptions)
$url = $imageUrl -replace '/sitecore/shell', '' #fix to request image from published Site
Write-Host "Downloading image: $url ...`n"
$webClient = New-Object System.Net.WebClient
$file = $webClient.DownloadData($url)
}
catch [System.Net.WebException]
{
$HttpStatusCode = $_.Exception.Response.StatusCode.value__
$HttpStatusDescription = $_.Exception.Response.StatusDescription
Write-Host -Foreground Red "Error Downloading Image: $($HttpStatusCode) - Http Status Description: $($HttpStatusDescription)"
$errorCount +=1
$errorList = $errorList + "$($id) - $($name) `n"
continue
}
catch
{
Write-Host -Foreground Red "Error Downloading Image: $($id) - $($name) - Error Message: $($_.Exception.Message)"
continue
}
# Computer Vision API
do
{
try
{
if($file){
Write-Host "Calling Endpoint: $($visionUrl)?visualFeatures=$($visionFeatures)&language=en"
# Calling the Computer Vision API
$response = Invoke-WebRequest `
-Uri "$($visionUrl)?visualFeatures=$($visionFeatures)&language=en" `
-Body $file `
-ContentType "application/octet-stream" `
-Headers @{"Ocp-Apim-Subscription-Key" = "$($visionApiKey)"} `
-Method 'Post' `
-ErrorAction Stop `
-UseBasicParsing | ConvertFrom-Json
# Tracking what image the response should be attached to
$response | Add-Member -Name "id" `
-MemberType NoteProperty `
-Value "$($image.ID.ToShortID())"
$altText = $response.description.captions[0].text
Write-Host "Image Processed: $($image.Paths.FullPath)`n`n"
if($altText){
if($testMode){
Write-Host -Foreground Cyan "Alt Text Not set as in TEST MODE, but would be:" $altText
}
else
{
# update Alt tag on image
$image.Editing.BeginEdit()
$image.Fields["Alt"].Value = $altText
$image.Editing.EndEdit()
Write-Host -Foreground Cyan "Alt Text Set To:" $altText
Write-Host "----------------------------------`n`n"
}
$result += $response
$csvProperties = @{
ID = $id
Name = $name
DisplayName = $displayName
Path = $path
AltText = $altText
}
$csvResults += New-Object psobject -Property $csvProperties;
$success = $True
$successCount +=1
}
else{
Write-Host -Foreground Yellow "No Alt Text Returned For Image: $($id) - $($name)"
$errorCount +=1
$errorList = $errorList + "$($id) - $($name) `n"
break
}
}
else{
Write-Host -Foreground Red "No Image Found In Sitecore For: $($id) - $($name)"
$errorCount +=1
$errorList = $errorList + "$($id) - $($name) `n"
break
}
}
catch [System.Net.WebException]
{
$HttpStatusCode = $_.Exception.Response.StatusCode.value__
$HttpStatusDescription = $_.Exception.Response.StatusDescription
Write-Host -Foreground Red "Error Calling Computer Vision API: $($HttpStatusCode) - Http Status Description: $($HttpStatusDescription)"
if($HttpStatusCode -eq "429"){
Write-Host -Foreground Magenta "Exceeded Computer Vision API limit. Waiting for $($secondsToWaitOnLimitError) seconds..."
Start-Sleep -s $secondsToWaitOnLimitError
Write-Host -Foreground Green "Resuming now..."
}
else{
$errorCount +=1
$errorList = $errorList + "$($id) - $($name) `n"
break
}
}
catch
{
Write-Host -Foreground Red "Error processing Image: $($id) - $($name) - Error Message: $($_.Exception.Message)"
break
}
}
while ($success -ne $True)
}
if($testMode){
Write-Host -Foreground Yellow "TEST MODE complete."
}
Write-Host -Foreground Green "$($successCount) Images Successfully Processed"
Write-Host "$($errorCount) Errors Processing Images"
if($errorCount -gt 0){
Write-Host -Foreground Red "Errors List"
Write-Host -Foreground Red "-----------------------------"
Write-Host -Foreground Red $errorList
}
if($createCsv -and $successCount -gt 0){
Write-Host "Saving Report of Alt Text to: ${csvOutputFilePath}"
$csvResults | Select-Object ID,Name,DisplayName,Path,AltText | Export-Csv -notypeinformation -Path $csvOutputFilePath
}
#Write-Host ($result | ConvertTo-Json -Depth 5)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment