# encoding: ascii
# api: powershell
# title: Get-TheVillageChurchPod
# description: The Get-TheVillageChurchPodcast function returns objects of all the available sermon podcasts from The Village Church. The objects can be filtered by speaker, series, title, or date and optionally downloaded to a specified folder.
# version: 1.2.0.0
# type: function
# author: Rich Kusak
# license: CC0
# function: Get-TheVillageChurchPodCast
# x-poshcode-id: 2951
# x-archived: 2011-11-05T17:51:32
# x-published: 2011-09-12T09:22:00
#
#
function Get-TheVillageChurchPodCast {
<#
	.SYNOPSIS
		Gets The Village Church sermon podcasts.

	.DESCRIPTION
		The Get-TheVillageChurchPodcast function returns objects of all the available sermon podcasts from The Village Church.
		The objects can be filtered by speaker, series, title, or date and optionally downloaded to a specified folder.

	.PARAMETER Speaker
		Specifies the name of the podcast speaker. The wildcard '*' is allowed.

	.PARAMETER Series
		Specifies the series of the podcast. The wildcard '*' is allowed.

	.PARAMETER Title
		Specifies the title of the podcast. The wildcard '*' is allowed.

	.PARAMETER Date
		Specifies the date or date range of the podcast(s).

	.PARAMETER DownloadPath
		Specifies the download folder path to save the podcast files.

	.EXAMPLE
		Get-TheVillageChurchPodcast
		Gets all the available sermon podcasts from The Village Church.

	.EXAMPLE
		Get-TheVillageChurchPodcast -Speaker MattChandler -Series Habakkuk
		Gets all the sermon podcasts where Matt Chandler is the speaker and the series is Habakkuk.
		
	.EXAMPLE
		Get-TheVillageChurchPodcast -Speaker MattChandler -Date 1/1/2003,3/31/2003
		Gets all the sermon podcasts where Matt Chandler is the speaker and the podcasts are in the date ranage 1/1/2003 - 3/31/2003.
		
	.EXAMPLE
		Get-TheVillageChurchPodcast -Speaker MattChandler -Date 1/1/2003,3/31/2003 -DownloadPath C:\temp\TheVillage
		Gets all the sermon podcasts where Matt Chandler is the speaker and the podcasts are in the date ranage 1/1/2003 - 3/31/2003 and
		downloads the podcast files to the folder path C:\temp\TheVillage.

	.INPUTS
		System.String

	.OUTPUTS
		PSObject

	.NOTES
		Name: Get-TheVillageChurchPodCast
		Author: Rich Kusak
		Created: 2011-06-14
		LastEdit: 2011-09-12 11:07
		Version: 1.2.0.0

	.LINK
		http://fm.thevillagechurch.net/sermons

	.LINK
		about_regular_expressions

#>

	[CmdletBinding()]
	param (
		[Parameter(Position=0, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
		[ValidateNotNullOrEmpty()]
		[string]$Speaker = '*',

		[Parameter(ValueFromPipelineByPropertyName=$true)]
		[ValidateNotNullOrEmpty()]
		[string]$Series = '*',
		
		[Parameter(ValueFromPipelineByPropertyName=$true)]
		[ValidateNotNullOrEmpty()]
		[string]$Title = '*',

		[Parameter(ValueFromPipelineByPropertyName=$true)]
		[ValidateCount(1,2)]
		[datetime[]]$Date = ([datetime]::MinValue,[datetime]::MaxValue),
		
		[Parameter(ValueFromPipelineByPropertyName=$true)]
		[ValidateScript({
			if ($_) {
				if (Test-Path $_ -IsValid) {$true} else {
					throw "The download path '$_' is not valid."
				}
			} else {$true}
		})]
		[string]$DownloadPath
	)
	
	begin {
	
		$sermonsUri = 'http://fm.thevillagechurch.net/sermons'
		$studiesSeminarsUri = 'http://fm.thevillagechurch.net/studies-seminars'
		$resourceFilesAudioUri = 'http://fm.thevillagechurch.net/resource_files/audio/'

		$partRegex = "href='/resource_files/audio/(?<file>(?<date>\d{8}).*_(?<speaker>\w+)_(?<series>\w+)Pt(?<part>\d+)-(?<title>\w+)\.mp3)'"
		$noPartRegex = "href='/resource_files/audio/(?<file>(?<date>\d{8}).*_(?<speaker>\w+)_(?<series>\w+)-(?<title>\w+)\.mp3)'"

		$webClient = New-Object System.Net.WebClient
		if ([System.Net.WebProxy]::GetDefaultProxy().Address) {
			$webClient.UseDefaultCredentials = $true
			$webClient.Proxy.Credentials = $webClient.Credentials
		}
		
	} # begin
	
	process {

		try {
			Write-Debug "Performing operation 'DownloadString' on target '$sermonsUri'."
			$reference = $webClient.DownloadString($sermonsUri)
		
			$pages = [regex]::Matches($reference, 'page=(\d+)&') | ForEach {$_.Groups[1].Value} | Sort -Unique
			$pages | ForEach -Begin {$sermons = @()} -Process {
				$sermonsPageUri = "http://fm.thevillagechurch.net/sermons?type=sermons&page=$_&match=any&kw=&topic=&sb=date&sd=desc"
				Write-Debug "Performing operation 'DownloadString' on target '$sermonsPageUri'."
				$sermons += $webClient.DownloadString($sermonsPageUri)
			}
		} catch {
			return Write-Error $_
		}

		$obj = foreach ($line in $sermons -split '(?m)\s*$') {
			if ($line -match $partRegex) {
				New-Object PSObject -Property @{
					'File' = $matches['file']
					'Date' = "{0:####-##-##}" -f [int]$matches['date']
					'Speaker' = $matches['speaker']
					'Series' = $matches['series']
					'Part' = "{0:d2}" -f [int]$matches['part']
					'Title' = $matches['title']
				}

			} elseif ($line -match $noPartRegex) {
				New-Object PSObject -Property @{
					'File' = $matches['file']
					'Date' = "{0:####-##-##}" -f [int]$matches['date']
					'Speaker' = $matches['speaker']
					'Series' = $matches['series']
					'Part' = '00'
					'Title' = $matches['title']
				}
			}
		} # foreach ($line in $sermons -split '(?m)\s*$')
		
		if ($PSBoundParameters['Date']) {
			switch ($Date.Length) {
				1 {$Date += $Date ; break}
				2 {
					if ($Date[0] -gt $Date[1]) {
						[array]::Reverse($Date)
					}
				}
			} # switch
		} # if ($PSBoundParameters['Date'])
		
		if ($DownloadPath) {
			try {
				if (-not (Test-Path $DownloadPath -PathType Container)) {
					New-Item $DownloadPath -ItemType Directory -Force -ErrorAction Stop | Out-Null
				}
			} catch {
				return Write-Error $_
			}
			
			[PSObject[]]$filter = $obj | Where {
				$_.Speaker -like $Speaker -and
				$_.Series -like $Series -and
				([datetime]$_.Date -ge $Date[0]) -and ([datetime]$_.Date -le $Date[1])
			}
			
			$count = $filter.Length
			$i = 0

			foreach ($podcast in $filter) {
				$fullPath = Join-Path $DownloadPath $podcast.File
				if (Test-Path $fullPath) {
					Write-Warning "File '$fullPath' already exists."
					continue
				}

				try {
					Write-Debug "Performing operation 'DownloadFile' on target '$($podcast.File)'."
					Write-Progress -Activity 'Downloading PodCast' -Status $podcast.File -PercentComplete $(($i/$count)*100 ; $i++) -CurrentOperation "$i of $count"
					$webClient.DownloadFile($resourceFilesAudioUri + $podcast.File, $fullPath)
				} catch {
					Write-Error $_
					continue
				}
			} # foreach ($podcast in $filter)
			
			Write-Progress -Activity 'Downloading PodCast' -Status 'Complete' -PercentComplete 100
			Sleep -Seconds 1

		} else {
			$obj | Where {
				$_.Speaker -like $Speaker -and
				$_.Series -like $Series -and
				$_.Title -like $Title -and
				([datetime]$_.Date -ge $Date[0]) -and ([datetime]$_.Date -le $Date[1])
			} | Select Date, Speaker, Series, Part, Title | Sort Date
		}
	} # process
} # function Get-TheVillageChurchPodCast {
