12 January 2015

I’ve never been able to find a REALLY good podcatcher. I use Juice and it works good… as long as it’s always running. I thought I had it set to startup when I login but apparently I hadn’t. I fell off keeping up with Hak5 and then one day I go to start up again and I have no current episodes! It had been months. I left it alone again and there I was yesterday wanting them again. The RSS feed only does the current season so I couldn’t use iTunes or another app to “Download All” as they only saw the current season. I needed to go back two seasons, too. Enter PowerShell.

I figured I could do it. Fuddled with Invoke-WebRequest but it doesn’t work great. The Links property was always missing the link to the HD video file. I ended up having to create a WebClient and download the webpage, then parse it for the HD video file. It didn’t take too long… if you don’t count the typo I made which kept making me download the page for episode 1 of season 1, lol (No HD back then…). I added params and comments and spruced it up a bit for general internet consumption.

###################################################################
##  Description:  Downloads all of the HD videos for the given season of Hak5
##
##  This script is provided as is and may be freely used and distributed so long as proper
##  credit is maintained.
##
##  Written by: thegeek@thecuriousgeek.org
##  Date Modified:  01-12-2015
###################################################################

param(
	[Parameter(Mandatory=$true,Position=1)]
	[string]$season,
	
	[Parameter(Mandatory=$true,Position=2)]
	[int]$first,
	
	[Parameter(Mandatory=$true,Position=3)]
	[int]$last
)

# First I need to check if any of the episode numbers are less than 10
# if so, I need to add a 0 in there to get the correct episode numbers.
If ($first -lt 10) { 
	[int]$first = "$($season)0$first"
}
Else {
	[int]$first = "$($season)$first"
}

If ($last -lt 10) { 
	[int]$last = "$($season)0$last"
}
Else {
	[int]$last = "$($season)$last"
}

# Here I just setup paths for easy use later. Be sure to set Drive to your own drive letter!
$saveDir = "Drive:\Podcasts\Hak5"
$seasonDir = "$saveDir\Season $season"
$url = "http://hak5.org/episodes/hak5-"

# Keeping directory structure.  I test to see if the folder "Season $season"
# exists and if it doesn't it creates it.  The web client will not create it.
If (!(Test-Path $seasonDir)) {
	New-Item $seasonDir -ItemType Directory
}

# Use the first and last episode numbers to go through a loop.  Each one
# is used to create the final URL that will be downloaded for it's source code.
# Thankfully Hak5 is organized and this is easy to do!
For ($i = $first; $i -le $last; $i++) {
	write-host "Working on episode $i"
	$wc = new-object system.net.webclient
	$wc.DownloadFile("$($url)$i","TempLocation")    # I build the URL using the base path I had above and combine it with the episode number from the current iteration of the loop
	$sourceCode = get-content TempLocation    # Be sure to make TempLocation your own path!
	ForEach ($line in $sourceCode) {
		$boolResponse = $line -match "http(.*?)hd720p30\.h264\.mp4"    # This regex expression is saying match a string http (with anything here in the middle) and is followed by hd720p30.h264.mp4
		If ($boolResponse) {
			$fileURL = $matches.0     # the system variable $matches keeps record of all matches you've made.  The query above gives two results, the first is the one I want (complete URL).
			$fileName = $fileURL.Split("/")[$_.Length - 1]     # I need a filename to save as, so I grab the one out of the URL
			$wc.DownloadFile($fileURL,"$seasonDir\$fileName")
		}
	}
}

And then to call it, run the script with parameters such as: DownloadHak5Season.ps1 16 1 26, which tells it to download season 16, episodes 1-26


There are no comments.



You must be logged in to post a comment.