PDA

View Full Version : Powershell to download Dungeon, Dragon, and ArtGallery from D&D Insider



valeros
March 21st, 2019, 06:41
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.)



[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%24DnDC ontent%24MainDnDContent%24LeftColumn%24UserName=" + [uri]::EscapeDataString($username)
$body += "&ctl00%24ctl00%24ctl00%24ctl00%24SiteContent%24DnDC ontent%24MainDnDContent%24LeftColumn%24Password=" + [uri]::EscapeDataString($password)
$body += "&ctl00%24ctl00%24ctl00%24ctl00%24SiteContent%24DnDC ontent%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"

FrontLineFodder
November 7th, 2024, 11:39
I am going back into 4e and trying to sort out my content collection.
I was wondering if anyone has kept any of the ArtGallery images from DDI ?

SieferSeesSomething
November 7th, 2024, 23:40
I am going back into 4e and trying to sort out my content collection.
I was wondering if anyone has kept any of the ArtGallery images from DDI ?

That sounds awesome. DM me if you ever find it or someone who has it, I'd love to look at all the old art. I came into 4e this year with kind of a weird path (went from 3.5 to Pathfinder 1e to 5e to Pathfinder 2e to now trying out D&D 4e and 5.5 at the same time) so I never even had a DDI subscription before they shut it all down.

damned
November 8th, 2024, 00:36
The Art will not be shareable - please do not share or discuss sharing it here.

FrontLineFodder
November 8th, 2024, 03:08
The Art will not be shareable - please do not share or discuss sharing it here.

that is fair, Thanks for commenting