MediaValet.DAM.psm1


function Import-MvDamFilenameListFromCsv {
    [CmdletBinding()]
    param (
        [parameter(Mandatory=$true,Position=0)]
        [string]$Path
    )
    PROCESS {
        $csv = Import-Csv -Path $Path
        $filenameArray = $csv | Foreach {$_.Filename}
        return $filenameArray
    }
    
}

function Export-MvDamAssetInfo {
    [CmdletBinding()]
    param (
        [parameter(Mandatory=$true,Position=0,ParameterSetName="From Filename List")]
        [string[]]$FilenameList,
        [parameter(Mandatory=$true,Position=0,ParameterSetName="From Asset ID List")]
        [string[]]$AssetIdList,
        [parameter(Mandatory=$true, Position=0,ParameterSetName="All Assets")]
        [switch]$ListAllAssets,
        [parameter(Mandatory=$true,Position=1)]
        [string]$Path,
        [parameter(Mandatory=$false, Position=2)]
        [switch]$Resume
    )
    PROCESS {
        if ($ListAllAssets)
        {
            if (!$Resume)
            {
                $assets = Find-MvDamAssetInfo -SearchQuery "*&sort=record.createdAt+A" -Count 1000
            }
            else
            {
                $data = Import-Csv $Path
                $result = $data[$data.Count - 1]
                $lastCreatedDate=$result."System.CreatedDate"
                
                $assets = Find-MvDamAssetInfo -SearchQuery "*&sort=record.createdAt+A&filters=(DateUploaded+GT+$lastCreatedDate)" -Count 1000
            }
            
            $assetCtr = $assets.Count
            while ($assets.Count -gt 0)
            {

                $firstCreatedDate = $assets[0].CreatedDate.ToString('o')
                $lastCreatedDate = $assets[$assets.Length-1].CreatedDate.ToString('o')

                Write-Host "Retrieved $assetCtr assets: "  $firstCreatedDate "to" $lastCreatedDate

                $convertedAssets = @()
                foreach ($asset in $assets)
                {
                    $convertedAssets += ConvertAssetToCSVExport $asset
                }
            
                $convertedAssets | Export-CSV -Path $Path -Append -NoTypeInformation 
                $filter = "*&sort=record.createdAt+A&filters=(DateUploaded+GT+$lastCreatedDate)"
                $assets = Find-MvDamAssetInfo -SearchQuery $filter -Count 1000
                $assetCtr = $assetCtr + $assets.Count
            } 
        }
        else
        {
            $assets = @()
            if ($FilenameList)
            {
                $assets = Get-MvDamAssetInfo -FilenameList $FilenameList
            }
            if ($AssetIdList)
            {
                $assets = Get-MvDamAssetInfo -AssetIds $AssetIdList
            }
            
            $convertedAssets = @()
            foreach ($asset in $assets)
            {
                $convertedAssets += ConvertAssetToCSVExport $asset
            }
        
            $convertedAssets | Export-CSV -Path $Path -Append -NoTypeInformation
        }
    }
}

function Export-MvDamAssetAttribute {
    [CmdletBinding()]
    param (
        [parameter(Mandatory=$true,Position=0)]
        [object[]]$AssetInfoList,
        [parameter(Mandatory=$false,Position=1)]
        [string[]]$AttributeList,
        [parameter(Mandatory=$true,Position=2)]
        [string]$Path
    )
    PROCESS {
        if ($AssetInfoList.GetType().Name -ne "AssetInfoModel[]" -or $AssetInfoList.Count -eq 0)
        {
            Write-Error -Message "Please pass an AssetInfoModel array with one or more items to the `$AssetInfoList parameter"
        }
        #Get AttributeList for Library
        if ($AttributeList -eq $null)
        {
            $AttributeList = (Get-MvDamAttributeDef) | Foreach {if ($_.IsSystemProperty){"System."+$_.Name}else{$_.Name}}
        }
        else #validate the AttributeList against the AttributeDefs
        {
            $objAttrNames = (Get-MvDamAttributeDef) | Foreach {if ($_.IsSystemProperty){"System."+$_.Name}else{$_.Name}}
            $AttributeList | Foreach { if (-not $objAttrNames.Contains($_)) {Write-Error "Invalid attribute name $_ specified"} } 
        }
        $assets = @()
        Foreach ($assetInfo in $AssetInfoList)
        {
            $asset = New-Object -TypeName PSObject
            $asset | Add-Member -MemberType NoteProperty -Name 'System.Id' -Value $assetInfo.Id
            $asset | Add-Member -MemberType NoteProperty -Name 'System.FileName' -Value $assetInfo.FileName
            $asset | Add-Member -MemberType NoteProperty -Name 'System.Title' -Value $assetInfo.Title
            $asset | Add-Member -MemberType NoteProperty -Name 'System.Description' -Value $assetInfo.Description
            Foreach($attributeName in $AttributeList)
            {
                if ($attributeName -notlike "System.*")
                {
                    $attrValue = $assetInfo.Attributes | Where {$_.AttributeName -eq $attributeName} | Select -Property AttributeValue
                    $asset | Add-Member -MemberType NoteProperty -Name "$attributeName" -Value $attrValue.AttributeValue
                }
            }
            $assets += $asset  
        }
        $assets | Export-Csv -Path $Path -Append -NoTypeInformation 
        return $assets
    }
}

function Import-MvDamAssetAttributesFromCsv {
    [CmdletBinding()]
    param (
        [parameter(Mandatory=$true,Position=0)]
        [string]$SourcePath,
        [parameter(Position=1)]
        [string]$LogPath
    )
    PROCESS {
        $csv = @()
        $import = Import-Csv -Path $SourcePath
        if ($import.GetType().ToString() -eq "System.Object[]")
        {
            $csv = $import
        }
        else
        {
            $csv = @($import)
        }
        for($i=0;$i -lt $csv.Length; $i++)
        {
            $line = $csv[$i]
            $assetId = $line.('System.Id')
            $percentComplete = ($i/$csv.Length)*100
            Write-Progress -Activity "Importing Asset Attributes" -Status "Updating attributes for Asset Id $assetId" -PercentComplete $percentComplete 
            $txnInfo = New-MvDamTxnInfo -StartTime (Get-Date) -Id $assetId  -Status "InProgress" -TxnType "Update-MvDamAssetAttribute"
            $attrKvps = @{}
            $line | Get-Member | Where {$_.MemberType -eq "NoteProperty"} | Foreach {if ($line.($_.Name) -ne "") {$attrKvps.Add($_.Name, $line.($_.Name))}}
            $errorInfo = $null
            $txnResult = Update-MvDamAssetAttribute -AssetId $assetId -Attributes $attrKvps -ErrorAction Continue -ErrorVariable $errorInfo
            $txnInfo.EndTime = Get-Date
            if ($errorInfo)
            {
                $txnInfo.Status = "Failed"
                $txnInfo.Notes = $errorInfo.Message
            }
            else
            {
                $txnInfo.Status = "Succeeded"
            }
            if ($LogPath)
            {
                $txnInfo | Export-Csv -Path $LogPath -Append
            }
        }
        Write-Progress -Activity "Importing Asset Attributes" -Completed 

        return 
    }
}

function Test-MvDamAssetAttributeCsv {
    [CmdletBinding()]
    param (
        [parameter(Mandatory=$true,Position=0)]
        [string]$SourcePath,
        [parameter(Mandatory=$true,Position=1)]
        [string]$ResultPath
    )
    PROCESS {
        $csv = @()
        $import = Import-Csv -Path $SourcePath
        if ($import.GetType().ToString() -eq "System.Object[]")
        {
            $csv = $import
        }
        else
        {
            $csv = @($import)
        }
        $assetsWithErrors = 0
        $totalErrors = 0
        for($i=0;$i -lt $csv.Length; $i++)
        {
            $line = $csv[$i]
            $assetId = $line.('System.Id')
            $percentComplete = ($i/$csv.Length)*100
            Write-Progress -Activity "Validating Asset Attributes" -Status "Testing attributes for Asset Id $assetId" -PercentComplete $percentComplete 
            $attrKvps = @{}
            $line | Get-Member | Where {$_.MemberType -eq "NoteProperty"} | Foreach {if ($line.($_.Name) -ne "") {$attrKvps.Add($_.Name, $line.($_.Name))}}
            $errorInfo = $null
            $txnResult = Test-MvDamAssetAttribute -AssetId $assetId -Attributes $attrKvps -ErrorAction Continue -ErrorVariable $errorInfo
            if ($txnResult.Errors -eq 0)
            {
                $line | Add-Member -MemberType NoteProperty -Name 'Errors' -Value ""
            }
            else
            {
                $assetsWithErrors++
                $totalErrors += $txnResult.Errors
                $errorMsgs = ($txnResult.AttributeValidatonResults | Foreach ValidationResult) -join "; "
                $line | Add-Member -MemberType NoteProperty -Name 'Errors' -Value $errorMsgs
            }
            if ($i -eq 0)
            {
                $line | Export-Csv -Path $ResultPath -NoTypeInformation
            }
            else
            {
                $line | Export-Csv -Path $ResultPath -Append -NoTypeInformation
            }
        }
        Write-Progress -Activity "Validating Asset Attributes" -Completed 
        Write-Host "Total Assets Validated:"$csv.Length
        Write-Host "Assets with Error(s):"$assetsWithErrors
        Write-Host "Total Errors Detected"$totalErrors
        if ($totalErrors -eq 0)
        {
            Write-Host "`r`nCONGRATULATIONS! Your asset attribute CSV file is ready to import."
        }
        return 
    }
}


function Import-MvDamAssetKeywordFromCsv
{
    [CmdletBinding()]
    param (
        [parameter(Mandatory=$true,Position=0)]
        [string]$Path
    )
    PROCESS 
    {
        $Assets = Import-Csv -Path $Path | Select 'System.Id', Keywords

        "Validating Ids"
        $Count = 0
        foreach ($id in ($Assets | select Id))
        {
            if ($id -match '<<[a-z]*>>')
            {
                $Count += 1;
            }
        }

        if ($Count -gt 0)
        {
            throw "$Count issues were detected with the Asset Ids provided. Please resolve this before continuing."
        }

        "Ids are valid"
        "Starting keyword import"

        $err = @()
        $lastErrorCount = 0
        $errorLogPath = ".\UpdateKeywordErrors.csv"
        foreach ($asset in $Assets)
        {
            "AssetId: $asset.Id" 
           if(!$asset.Keywords.Equals(""))
           {
                "Keywords: $asset.Keywords"
                $keywords = $asset.Keywords.Split(",")
                Update-MvDamAssetKeyword -AssetId $asset.Id -Keywords $keywords -ErrorAction Continue -ErrorVariable +err

                if ($err.Count -gt $lastErrorCount)
                {
                    $updateKeywordError = New-Object -TypeName PSObject
                    $updateKeywordError | Add-Member -NotePropertyName "System.Id" -NotePropertyValue $asset.'System.Id'
                    $updateKeywordError | Add-Member -NotePropertyName "Keywords" -NotePropertyValue $asset.Keywords
                    $updateKeywordError | Add-Member -NotePropertyName "Error" -NotePropertyValue $err[$lastErrorCount]

                    $updateKeywordError | Export-Csv -Path $errorLogPath -NoTypeInformation -Append

                    $lastErrorCount += 1
                }
           }
        }
        "Import complete"
    }
}

function Import-MvDamAssetCategoryFromCsv
{
    [CmdletBinding()]
    param (
        [parameter(Mandatory=$true,Position=0)]
        [string]$Path,
        [parameter(Mandatory=$false)]
        [string]$ErrorLogPath = ".\ImportAssetCategoryErrorLog.csv" 
    )
    PROCESS 
    {
        $Assets = Import-Csv -Path $Path | Select 'System.Id', Path

        Test-MvDamSystemId -Ids ($Assets | Select -ExpandProperty System.Id)

        $err = @()
        $lastErrorCount = 0
        foreach ($asset in $Assets)
        {
            if(!$asset.Path.Equals(""))
            {
                $asset
                $category = Get-MvDamCategory -CategoryPath $asset.Path -ErrorAction Continue -ErrorVariable +err
                Update-MvDamAssetCategory -AssetId $asset.'System.Id' -CategoryIds $category.Id -ErrorAction Continue -ErrorVariable +err

                if ($err.Count -gt $lastErrorCount)
                {
                    $updateCategoryError = New-Object -TypeName PSObject
                    $updateCategoryError | Add-Member -NotePropertyName "System.Id" -NotePropertyValue $asset.'System.Id'
                    $updateCategoryError | Add-Member -NotePropertyName "Path" -NotePropertyValue $asset.Path
                    $updateCategoryError | Add-Member -NotePropertyName "Error" -NotePropertyValue $err[$lastErrorCount]

                    $updateCategoryError | Export-Csv -Path $ErrorLogPath -NoTypeInformation -Append

                    $lastErrorCount += 1
                }
            }
        }
    }
}

function Import-MvDamAssetStatusFromCsv {
    [CmdletBinding()]
    param (
        [parameter(Mandatory=$true,Position=0)]
        [string]$Path,
        [parameter(Mandatory=$false)]
        [string]$ErrorLogPath = ".\ImportAssetStatusErrorLog.csv" 
    )
    PROCESS
    {
        $Assets = Import-CSV -Path $Path | Select 'System.Id', Status
        
        Test-MvDamSystemId -Ids ($Assets | Select -ExpandProperty 'System.Id')
        
        $err = @()
        $lastErrorCount = 0
        foreach ($asset in $Assets)
        {
            if(!$asset.Status.Equals(""))
            {
                Update-MvDamAssetStatus -AssetId $asset.'System.Id' $asset.Status -ErrorAction Continue -ErrorVariable +err
            }
            
                if ($err.Count -gt $lastErrorCount)
                {
                    $updateCategoryError = New-Object -TypeName PSObject
                    $updateCategoryError | Add-Member -NotePropertyName "System.Id" -NotePropertyValue $asset.'System.Id'
                    $updateCategoryError | Add-Member -NotePropertyName "Status" -NotePropertyValue $asset.Status
                    $updateCategoryError | Add-Member -NotePropertyName "Error" -NotePropertyValue $err[$lastErrorCount]

                    $updateCategoryError | Export-Csv -Path $ErrorLogPath -NoTypeInformation -Append

                    $lastErrorCount += 1
                }
        }
    }
}

function Test-MvDamSystemId
{
    [CmdletBinding()]
    param (
        [parameter(Mandatory=$true,Position=0)]
        [string[]]$Ids
    )   

    PROCESS 
    {
        $Count = 0
        foreach ($id in $Ids)
        {
            try {
                [System.Guid]::Parse($id) | Out-Null

            } catch {
                $Count += 1
            }
        }

        if ($Count -gt 0)
        {
            throw "$Count issues were detected with the System.Ids provided. Please resolve this before continuing."
        } 
        else 
        {
            "Validation complete. No issues were detected."
        }
    }
}

function Initialize-MvDamUploadBatch {
        [CmdletBinding()]
        param (
        [parameter(Mandatory=$true,Position=0)]
        [string]$SourcePath,
        [parameter(Mandatory=$true,Position=1)]
        [string]$ManifestFilePath
    )
    PROCESS {
        $AttributeList = (Get-MvDamAttributeDef) | Foreach {if ($_.IsSystemProperty){"System."+$_.Name}else{$_.Name}} 
        if ($AttributeList -eq $null)
        {
            return
        }
        Write-Progress -Activity "Reading folder structure..." -Status "Initializing"
        $files = Get-ChildItem -Path $SourcePath -File -Recurse
        $ctr = 0
        $md5 = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
        foreach($file in $files)
        {
            $ctr++
            Write-Progress -Activity "Adding $file to manifest" -Status "In-Progress" -PercentComplete ($ctr/$files.Count*100)
            #Write-Host $file.DirectoryName, $file.Name, $file.Basename $file.Length, $file.CreationTimeUtc, $file.LastWriteTimeUtc
            $relPath = $file.DirectoryName.Replace($SourcePath, "")
            if (!($env:OS).StartsWith("Windows")) 
            {
                $relPath = $relPath -replace '/','\'
            }
            $hash = [System.Convert]::ToBase64String($md5.ComputeHash([System.IO.File]::ReadAllBytes($file.FullName)))
            $asset = New-Object -TypeName PSObject
            $asset | Add-Member -MemberType NoteProperty -Name 'System.Id' -Value ""
            $asset | Add-Member -MemberType NoteProperty -Name 'Process.LocalPath' -Value $file.DirectoryName
            $asset | Add-Member -MemberType NoteProperty -Name 'Process.LocalName' -Value $file.Name
            $asset | Add-Member -MemberType NoteProperty -Name 'System.FileName' -Value $file.Name
            $asset | Add-Member -MemberType NoteProperty -Name 'System.CategoryPath' -Value $relPath
            $asset | Add-Member -MemberType NoteProperty -Name 'System.Title' -Value $file.Basename
            $asset | Add-Member -MemberType NoteProperty -Name 'System.MD5Checksum' -Value $hash
            $asset | Add-Member -MemberType NoteProperty -Name 'Process.PreflightStatus' -Value "Pending"
            $asset | Add-Member -MemberType NoteProperty -Name 'Process.PreflightInfo' -Value ""
            $asset | Add-Member -MemberType NoteProperty -Name 'Process.UploadStatus' -Value "Preflight"
            $asset | Add-Member -MemberType NoteProperty -Name 'Process.UploadInfo' -Value ""
            $asset | Add-Member -MemberType NoteProperty -Name 'System.File Size' -Value $file.Length
            $asset | Add-Member -MemberType NoteProperty -Name 'System.Created Date' -Value $file.CreationTimeUtc
            $asset | Add-Member -MemberType NoteProperty -Name 'System.Last Modified' -Value $file.LastWriteTimeUtc
            $asset | Add-Member -MemberType NoteProperty -Name 'System.Description' -Value ""
            $asset | Add-Member -MemberType NoteProperty -Name 'System.Keywords' -Value ""
            Foreach($attributeName in $AttributeList)
            {
                if ($attributeName -notlike "System.*")
                {
                    $attrValue = $assetInfo.Attributes | Where {$_.AttributeName -eq $attributeName} | Select -Property AttributeValue
                    $asset | Add-Member -MemberType NoteProperty -Name "$attributeName" -Value $attrValue.AttributeValue
                }
            }
            if ($PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent -eq $true)
            {
                Write-Host "Adding to manifest: $asset `r`n"
            }
            $asset | Export-Csv -Path $ManifestFilePath -Append -NoTypeInformation 
        }
        Write-Progress -Activity "Finalizing" -PercentComplete 100 -Completed
    }
}

function Test-MvDamUploadBatch {
        [CmdletBinding()]
        param (
        [parameter(Mandatory=$true,Position=0)]
        [string]$ManifestFilePath,
        [parameter(Mandatory=$false,Position=1)]
        [Guid]$ParentCategoryId,
        [parameter(Mandatory=$false,Position=2)]
        [switch]$AutoCreateCategories
    )
    PROCESS {
    }
}

function ConvertAssetToCSVExport ($assetInfo)
{    
    $asset = New-Object -TypeName PSObject    
    foreach ($property in $assetInfo.PSObject.Properties)
    {
        if (!$property.Name.Equals("Attributes"))
        {
            if($property.Name.Equals("Keywords") -or $property.Name.Equals("Categories"))
            {
                $asset | Add-Member -MemberType NoteProperty -Name ("System." + $property.Name) -Value ($property.Value -join ", ")
            }
            elseif ($property.Value -is [DateTime])
            {
                $asset | Add-Member -MemberType NoteProperty -Name ("System." + $property.Name) -Value ($property.Value.ToString("o", $null))
            }
            else
            {
                $asset | Add-Member -MemberType NoteProperty -Name ("System." + $property.Name) -Value $property.Value
            }
        }
     }
   
    foreach($attribute in $assetInfo.Attributes)
    {
        $attrValue = $assetInfo.Attributes | Where {$_.AttributeName -eq $attribute.AttributeName} | Select -ExpandProperty AttributeValue
        $asset | Add-Member -MemberType NoteProperty -Name $attribute.AttributeName -Value $attrValue
    }

    return $asset
}