TechEd 2013 Media Leeching

This was my first year at Microsoft’s TechEd, and I have to say that I was blown away by the volume of content. There were several different times that I was unable to attend a session that I wanted because I was triple if not quadruple booked.

Now that I’m back at the office, I wanted to pull down the content. I started to do this the old fashioned way, but it was taking forever, I would lose where I was, and I’d get side-tracked by work. So, I did what any sensible person would do, I wrote a PowerShell Script.

The script runs through four stages:

  1. Gather information from the RSS Feed
  2. Build up a list of files to download
  3. Download the files using BitsTransfer (so that it doesn’t hog my machine’s resources)
  4. Re-tag the Video files with appropriate information (using the TagLib#)

That was fun. Now onto the script…

<#
Download-TechEd2013Media.ps1

Downloads the Presentations and Videos from TechEd 2013 North America Site

Prerequisites:  taglib-sharp.dll in your Working Directory

#>

#region Cleanup Any Old Runs
Get-Variable | Remove-Variable -ErrorAction SilentlyContinue
$Error.Clear()
Clear-Host
Get-BitsTransfer | Remove-BitsTransfer -ErrorAction SilentlyContinue
#endregion Cleanup Any Old Runs

#############################
# Global Variables
##############################
$WorkingDir = "D:WorkingTechEd2013"

# Test for the Media Subfolder from the Working Directory
#   if it's not there, create it
if ( -not ( Test-Path ( $WorkingDir + "Media" ) )
{
	New-Item -Type Directory -Path ( $WorkingDir + "Media" ) | Out-Null
}
# Create a web client to download the RSS Feed
$rss = New-Object -TypeName Net.WebClient

# Grab the RSS feed for the MP4 downloads
Write-Host "Downloading RSS Feed Information..." -NoNewLine
$TechEdRSS = ($rss.downloadstring("http://channel9.msdn.com/Events/TechEd/NorthAmerica/2013/RSS/mp4high")) 
Write-Host " [COMPLETE]"

# Extract the Individual Items from the RSS Feed (easier than working with the long name below)
$RssEntries = $TechEdRss.rss.channel.item

# Create New Empty Collection for the files to be downloaded
$DownloadJobs = @()

# Walk through each item in the feed 
ForEach ( $RssEntry in $RssEntries )
{
	# Cheater way to build a new object
	$DownloadObject = "" | Select-Object Type, Code, Source, Destination, Title, TitleNormalized, Author, Summary
	# Populate the object for the Video File
	$DownloadObject.Type = "MP4"
	$DownloadObject.Code = $RssEntry.comments.split("/")[-1]
	$DownloadObject.Source = $RssEntry.enclosure.url
	$DownloadObject.Title = $RssEntry.title.Replace('’', "'").Replace('“', '"').Replace('â€', '"')
	$DownloadObject.TitleNormalized = $DownloadObject.Title.Replace(":", "-").Replace("?", "").Replace("/", "-").Replace("<", "").Replace(">", "").Replace("|", "")
	$DownloadObject.Author = $RssEntry.creator
	$DownloadObject.Summary = $RssEntry.summary
	$DownloadObject.Destination = ( $WorkingDir + "Media" + $DownloadObject.Code + " - " + $Title + ".mp4" ).Replace("’", "'").Replace('–', " - ")
	$DownloadObject.Destination = ( $WorkingDir + "Media" + $DownloadObject.Code + ".mp4" ).Replace("’", "'").Replace('–', " - ")

	# Add it to the collection
	$DownloadJobs += $DownloadObject

	# Create another empty collection and populate it for the slide decks
	$DownloadObject = "" | Select-Object Type, Code, Source, Destination, Title, TitleNormalized, Author, Summary
	$DownloadObject.Type = "PPTX"
	$DownloadObject.Code = $RssEntry.comments.split("/")[-1]
	$DownloadObject.Source = $RssEntry.enclosure.url.replace(".mp4", ".pptx")
	$DownloadObject.Title = $RssEntry.title.Replace('’', "'").Replace('“', '"').Replace('â€', '"')
	$DownloadObject.TitleNormalized = $DownloadObject.Title.Replace(":", "-").Replace("?", "").Replace("/", "-").Replace("<", "").Replace(">", "").Replace("|", "")
	$DownloadObject.Author = $RssEntry.creator
	$DownloadObject.Summary = $RssEntry.summary
	$DownloadObject.Destination = ( $WorkingDir + "Media" + $DownloadObject.Code + " - " + $DownloadObject.TitleNormalized + ".pptx" ).Replace("’", "'").Replace('–', " - ")
	$DownloadObject.Destination = ( $WorkingDir + "Media" + $DownloadObject.Code + ".pptx" ).Replace("’", "'").Replace('–', " - ")

	# Add it to the collection
	$DownloadJobs += $DownloadObject
}

$i = 0  # Counter for Progress Bar
$NumSessions = $DownloadJobs.Count # Total Items for Progress Bar
ForEach ( $DownloadJob in $DownloadJobs | Sort-Object Code | Sort-Object Type -Descending )
{
	Write-Progress -Activity "Downloading TechEd 2013 Media" -CurrentOperation "Downloading $( $DownloadJob.Title ) to $( $DownloadJob.Destination )" -PercentComplete ( ( $i * 100 ) / $NumSessions )
	$code = $DownloadJob.Code

	# Grab the URL for the file
	$url = $DownloadJob.Source

	# Get the "Title" of the Program
	$Title = $DownloadJob.Title

    # Create the local file name for the downloads
	$file = $DownloadJob.Destination

	# Make sure the file doesn't already exist
	if ( -not ( Test-Path $file ) )     
	{ 	
		# Echo out the file that's being downloaded
		Write-Host "Bulding Job for: [$file]"
    	try
    	{
            Start-BitsTransfer -Source $url -Destination $file -DisplayName "$( $DownloadJob.Code ).$( $DownloadJob.Type.ToLower() )" -Description "$( $DownloadJob.Title )" -ErrorAction Ignore
    	}
    	catch
    	{
            Write-Host "[$url] was not found on the server" -ForegroundColor DarkRed
    	}
	}
	else
	{
		Write-Host "[$file] already exists!" -ForegroundColor Red
	}
	$i++
}
Write-Progress -Activity "Downloading TechEd 2013 Media" -Completed

# Load the TagLib# Library
$TagTypes = Add-Type -Path ( $WorkingDir + "taglib-sharp.dll" ) -PassThru

# Cycle through each video download (the Where-Object Clause) and put in tag information from the RSS Feed
ForEach ( $DownloadJob in ( $DownloadJobs | Where-Object { $_.Type -eq "MP4" } | Sort-Object Destination ) )
{
	if ( Test-Path $DownloadJob.Destination )
	{
		$FileTags = [TagLib.File]::Create($DownloadJob.Destination)
		# Only Update the title and comments tags if they are empty
		if ( -not ( $FileTags.Tag.Comment ) )
		{
			Write-Host "$( $DownloadJob.Code )`tUpdating Summary: $( $DownloadJob.Summary.Substring(0,80) )..."
			$FileTags.Tag.Comment = $DownloadJob.Summary
		}
		if ( -not ( $FileTags.Tag.Title ) )
		{
			Write-Host "$( $DownloadJob.Code )`tUpdating Title: $( $DownloadJob.Title )"
			$FileTags.Tag.Title = $DownloadJob.Title
		}

		# Update the Artists (Authors) of the Videos
		$FileTags.Tag.Artists.Clear()
		$Authors = $DownloadJob.Author.Split(",")
		Write-Host "$( $DownloadJob.Code )`tAdding Author: $Author"
		$FileTags.Tag.Artists = $Authors

		Write-Host "Saving MetaData for $( $DownloadJob.Destination )" -NoNewline
		$FileTags.Save()
		Write-Host " [SAVED]" -ForegroundColor Green

	}
	else
	{
		Write-Host "$( $DownloadJob.Destination ) does not exist." -ForegroundColor Red
	}
}

2 thoughts on “TechEd 2013 Media Leeching”

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.