TALES of the VALIANT
  1. #1

    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"

  2. #2
    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 ?

  3. #3
    Quote Originally Posted by FrontLineFodder View Post
    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.

  4. #4

  5. #5
    Quote Originally Posted by damned View Post
    The Art will not be shareable - please do not share or discuss sharing it here.
    that is fair, Thanks for commenting

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
GI JOE RPG Launch

Log in

Log in