AtomDigitalObjectDownloader.psm1

using namespace system;
using namespace system.net.http;

Add-Type -AssemblyName 'System.Net'
Add-Type -AssemblyName 'System.Net.Http'

. $PSScriptRoot\SessionManager.ps1
. $PSScriptRoot\CsvDataExtractor.ps1
. $PSScriptRoot\FileSystem.ps1
. $PSScriptRoot\Exception.ps1
. $PSScriptRoot\Downloader.ps1
. $PSScriptRoot\Reporter.ps1

Function Get-DigitalObjects {
    <#
    .SYNOPSIS
 
    Batch-download digital objects from AtoM Archive.
 
    .DESCRIPTION
 
    Downloads any digital object uploaded to an AtoM archive using a CSV. The CSV should have a
    column named digitalObjectURI containing one or more URIs to digital objects
    existing in AtoM. Ideally, the CSV will be one imported from AtoM itself, so as to be more sure
    that there are no errors with the links.
 
    .PARAMETER CsvFile
 
    A path to a CSV file containing a digitalObjectURI column
 
    .PARAMETER DestinationFolder
 
    A path to a folder to download the digital objects into. Uses a folder named 'DigitalObjects'
    in the current folder if this parameter is not specified
 
    .PARAMETER ReadOnly
 
    Use this option if the AtoM instance is read-only, and does not need an account to log in to
    access objects.
 
    .PARAMETER Compress
 
    Compress the digital objects into a zip file after downloading. Deletes the original folder
    after compressing
 
    .PARAMETER RequireF5Login
 
    Require the user to enter credentials to an F5 load balancer before attempting to log in to
    AtoM
 
    .PARAMETER Checksums
 
    Load checksums from digitalObjectChecksum and verify them against the downloaded files.
 
    .INPUTS
 
    None. You cannot pipe input to Get-DigitalObjects
 
    .OUTPUTS
 
    Outputs a download report suitable to be piped to a text file. If output is not piped, the
    report will be printed to stdout.
 
    .EXAMPLE
 
    Download files specified in object.csv into the default folder, without compressing:
 
    PS> Get-DigitalObjects -CsvFile object.csv
 
    .EXAMPLE
 
    Download files specified in object.csv into a folder called "OBJ", and compress after finishing:
 
    PS> Get-DigitalObjects -CsvFile object.csv -DestinationFolder OBJ -Compress
    #>

    [CmdletBinding()]
    Param(
        [Parameter(Position=0, Mandatory=$True)]
        [ValidateScript({ If (Test-Path $_ -PathType Leaf -ErrorAction SilentlyContinue) {
            $True
        }
        Else {
            Throw "$_ does not exist or is not a file"
        }})]
        [String]
        $CsvFile,

        [Parameter(Mandatory=$False)]
        [String]
        $DestinationFolder,

        [Switch]
        $Compress,

        [Switch]
        $RequireF5Login,

        [Switch]
        $Checksums,

        [Switch]
        $ReadOnly
    )

    Try {
        If (-Not $DestinationFolder) {
            $DestinationFolder = 'DigitalObjects'
        }

        If ($Checksums) {
            [System.Collections.ArrayList] $Uris = GetUrisFromCsv -CsvFile $CsvFile -WithChecksums
        }
        Else {
            [System.Collections.ArrayList] $Uris = GetUrisFromCsv -CsvFile $CsvFile
        }

        $FirstUri = $Uris[0].Uri
        $AtomUrl = $FirstUri.Scheme + '://' + $FirstUri.Host
        Write-Host "Found $($Uris.Count) files to download from $($AtomUrl).`n"

        If ($RequireF5Login) {
            $Session = LoginToF5LoadBalancer -AtomUrl $AtomUrl
            Write-Host
        }
        Else {
            $Session = GetSession -AtomUrl $AtomUrl
        }

        If (-Not $ReadOnly) {
            LoginToAtom -AtomUrl $AtomUrl -WebSession $Session
        }

        CreateDestinationFolder $DestinationFolder
        Write-Host "`nStarting Downloads"

        If ($Checksums) {
            $Result = DownloadFiles -Uris $Uris `
                                    -DestinationFolder $DestinationFolder `
                                    -AuthenticatedSession $Session `
                                    -WithChecksums
        }
        Else {
            $Result = DownloadFiles -Uris $Uris `
                                    -DestinationFolder $DestinationFolder `
                                    -AuthenticatedSession $Session
        }

        If ($Result.FilesFound.Count -eq 0) {
            Write-Host "`nNone of the files in the CSV could be downloaded." -ForegroundColor Red
        }
        ElseIf ($Compress) {
            $Archive = CompressFolder -Folder $DestinationFolder
            If ($Archive) {
                Write-Host "`nFiles were downloaded and compressed to '$Archive'"
            }
        }
        Else {
            Write-Host "`nFiles were downloaded to '$DestinationFolder'"
        }
        Write-Host
        WriteDownloadReport $Result
    }
    Catch [HttpRequestException] {
        Write-Host "`nHttp Request Exception:" -ForegroundColor Red
        Write-Host "$_" -ForegroundColor Red
    }
    Catch [DestinationException] {
        Write-Host "`nDestination folder issue:" -ForegroundColor Red
        Write-Host "$_" -ForegroundColor Red
    }
    Catch [LoginException] {
        Write-Host "`nCould not login:" -ForegroundColor Red
        Write-Host "$_" -ForegroundColor Red
    }
    Catch [UriLoadException] {
        Write-Host "`nIssue with loading URIs from CSV:" -ForegroundColor Red
        Write-Host "$_" -ForegroundColor Red
    }
    Catch [CsvReadException] {
        Write-Host "`nIssue with reading CSV file:" -ForegroundColor Red
        Write-Host "$_" -ForegroundColor Red
    }
    Catch [MultipleDomainException] {
        Write-Host "`nMultiple domain URLs found in CSV:" -ForegroundColor Red
        ForEach($Domain in $_.Exception.Domains) {
            Write-Host " $Domain" -ForegroundColor Red
        }
        Write-Host "`nOnly one domain is allowed to be present in the file."
    }
}


Export-ModuleMember -Function 'Get-DigitalObjects'