Powershell to download Dungeon, Dragon, and ArtGallery from D&D Insider
Needed to learn some PowerShell stuff, so practiced by creating PowerShell that will download all the Dungeon magazines, Dragon magazines, and Art Gallery files from D&D Insider. Requires a current DDI subscription.
Will create "Dungeon", "Dragon", and "ArtGallery" directories under whatever directory from which you run the commands.
In PowerShell, paste the code below. Change the $username and $password variables to your DDI login info, then type "download" and hopefully it will download all the files. It is a bit slow (took nearly an hour for me.)
(Do not try it as a script because Windows has PowerShell scripts turned off by default and I did not test it as a script so not sure if it will run as a script.)
Code:
[Net.ServicePointManager]::SecurityProtocol = "tls12, tls11, tls"
$ddiBaseUrl = "https://ddi.wizards.com"
$dragonUrl = $ddiBaseUrl + "/ContentArchive.aspx?type=Dragon"
$dungeonUrl = $ddiBaseUrl + "/ContentArchive.aspx?type=Dungeon"
$artUrl = $ddiBaseUrl + "/ContentArchive.aspx?type=ArtGallery"
function BuildAuthenticationInfo($loginForm)
{
$body = "__EVENTTARGET=" + [uri]::EscapeDataString($loginForm.fields["__EVENTTARGET"])
$body += "&__EVENTARGUMENT=" + [uri]::EscapeDataString($loginForm.fields["__EVENTARGUMENT"])
$body += "&__VIEWSTATE=" + [uri]::EscapeDataString($loginForm.fields["__VIEWSTATE"])
$body += "&__VIEWSTATEGENERATOR=" + [uri]::EscapeDataString($loginForm.fields["__VIEWSTATEGENERATOR"])
$body += "&__EVENTVALIDATION=" + [uri]::EscapeDataString($loginForm.fields["__EVENTVALIDATION"])
$body += "&ctl00%24ctl00%24ctl00%24ctl00%24SiteContent%24DnDContent%24MainDnDContent%24LeftColumn%24UserName=" + [uri]::EscapeDataString($username)
$body += "&ctl00%24ctl00%24ctl00%24ctl00%24SiteContent%24DnDContent%24MainDnDContent%24LeftColumn%24Password=" + [uri]::EscapeDataString($password)
$body += "&ctl00%24ctl00%24ctl00%24ctl00%24SiteContent%24DnDContent%24MainDnDContent%24LeftColumn%24Login=GO"
return $body
}
function WebRequest([string]$url)
{
$response = Invoke-WebRequest -method POST -URI $url -Body $global:authenticationInfo -ContentType "application/x-www-form-urlencoded" -WebSession $global:session
return $response
}
function WebDownload([string]$url, [string]$downloadName)
{
Invoke-WebRequest -method POST -URI $url -Body $global:authenticationInfo -ContentType "application/x-www-form-urlencoded" -WebSession $global:session -OutFile $downloadName
}
function ValidDownloadLinks($request) { $request.ParsedHtml.getElementsByTagName("a") | Where { $_.href.Contains("Download.aspx") } }
function GoodDownloadName($element) { return ((($element.ParentNode).ParentNode).Children[0]).innerHTML.Trim() -replace '[:]','' }
function MakeDownloadList($url)
{
$list = @{}
$page = WebRequest($url)
$links = ValidDownloadLinks($page)
$links | ForEach-Object {
$link = $_
$downloadLink = $link.href
$downloadLink = $downloadLink.Replace("about:", $ddiBaseUrl);
$downloadName = GoodDownloadName($link);
$fileExtension = $downloadLink.Substring($downloadLink.Length - 4);
$downloadName += $fileExtension
$list.Add($downloadName, $downloadLink);
}
return $list
}
function SetOutputDirectory([string]$directory)
{
New-Item -Path . -Name $directory -ItemType "directory" | Out-Null
Set-Location -Path $directory
}
function DownloadFiles([string]$url)
{
$downloadList = MakeDownloadList($url)
DownloadEachFile($downloadList)
}
function DownloadEachFile($downloadList)
{
foreach ($downloadName in $downloadList.Keys)
{
$startTime = (GET-DATE)
Write-Host -NoNewLine "Downloading:" $downloadName "..."
$downloadLink = $downloadList[$downloadName]
WebDownload $downloadLink $downloadName
$endTime = (GET-DATE)
$totalTime = New-TimeSpan -Start $startTime -End $endTime
$secondsToDownload = " {0,4:f1} seconds" -f $totalTime.TotalSeconds
Write-Host $secondsToDownload
}
}
function Download()
{
Write-Host "Starting"
$ddiLoginPage = Invoke-WebRequest $ddiBaseUrl -SessionVariable global:session
$loginForm = $ddiLoginPage.Forms["aspnetForm"]
$global:authenticationInfo = BuildAuthenticationInfo($loginForm)
$loginResponse = WebRequest($ddiBaseUrl + "/" + $loginForm.Action)
$logOutButton = $loginResponse.ParsedHtml.getElementById("ctl00_ctl00_ctl00_ctl00_SiteContent_LogoutButton")
if ($logoutButton.GetType().Name -eq "DBNull")
{
Write-Host "Failed to login - make sure you set username and password variables"
}
else
{
DownloadEachGroup
Write-Host "done"
}
}
function DownloadEachGroup()
{
SetOutputDirectory("Dragon")
DownloadFiles($dragonUrl)
Set-Location -Path ..
SetOutputDirectory("Dungeon")
DownloadFiles($dungeonUrl)
Set-Location -Path ..
SetOutputDirectory("ArtGallery")
DownloadFiles($artUrl)
Set-Location -Path ..
}
$username = "YourDDIUserNameHere"
$password = "YourDDIPasswordHere"