Last active
April 30, 2023 19:42
-
-
Save spajak/a6699005d9648696fbdda1d545153a38 to your computer and use it in GitHub Desktop.
Creates EPUB e-book package from a given directory containing ebook source files.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[CmdletBinding(DefaultParameterSetName = "Default")] | |
param( | |
[Parameter(Position=0, Mandatory=$true, ValueFromPipeline=$true)] | |
[Alias("i", "Path", "Source")] | |
[String] $SourceDirectory, | |
[Parameter(Mandatory=$true, ParameterSetName="DestinationAlongSource")] | |
[Alias("ds", "os")] | |
[Switch] $DestinationAlongSource, | |
[Parameter(Mandatory=$true, ParameterSetName="DestinationDirectory")] | |
[Alias("dd", "od")] | |
[String] $DestinationDirectory, | |
[Parameter(Position=1, Mandatory=$true, ParameterSetName="DestinationFile")] | |
[Alias("o", "df", "of", "Destination", "File")] | |
[String] $DestinationFile, | |
[Parameter(Mandatory=$false, ParameterSetName="DestinationFile")] | |
[ValidateSet("Custom", "Append", "Correct")] | |
[Alias("e")] | |
[String] $Extension = "Append", | |
[Parameter(Mandatory=$false)] | |
[Switch] $Force | |
) | |
function Main | |
{ | |
$parameterSet = $PSCmdlet.ParameterSetName | |
Write-Verbose "ParameterSetName: $parameterSet" | |
$SourceDirectory = (Resolve-Path $SourceDirectory -ErrorAction Stop).Path | |
$DestinationFile = Get-DestinationFilePath | |
Write-Verbose "SourceDirectory: $SourceDirectory" | |
Write-Verbose "DestinationFile: $DestinationFile" | |
Build-Epub $SourceDirectory $DestinationFile | |
Show-EpubFileSummary $DestinationFile | |
} | |
function Get-DestinationFilePath | |
{ | |
if (($parameterSet -eq "DestinationFile") -and $DestinationFile) { | |
if (($Extension -ne "Custom") -and ($DestinationFile -notlike "*.epub")) { | |
if ($Extension -eq "Append") { | |
$DestinationFile = $DestinationFile + ".epub" | |
} else { | |
$directory = Split-Path $DestinationFile -Parent | |
$name = (Split-Path $DestinationFile -LeafBase) + ".epub" | |
if ($directory) { | |
$DestinationFile = Join-Path $directory $name | |
} else { | |
$DestinationFile = $name | |
} | |
} | |
} | |
} else { | |
$DestinationFile = (Split-Path $SourceDirectory -Leaf) + ".epub" | |
if (($parameterSet -eq "DestinationDirectory") -and $DestinationDirectory) { | |
$DestinationFile = Join-Path $DestinationDirectory $DestinationFile -ErrorAction Stop | |
} elseif ($DestinationAlongSource.IsPresent) { | |
$DestinationFile = Join-Path (Split-Path $SourceDirectory -Parent) $DestinationFile | |
} | |
} | |
if (!(Test-Path -LiteralPath $DestinationFile -IsValid)) { | |
throw "Destination file `"$DestinationFile`" is not valid." | |
} | |
if (-not $Force.IsPresent -and (Test-Path -LiteralPath $DestinationFile -PathType Leaf)) { | |
throw "Destination file `"$DestinationFile`" exists. Use -Force to overwrite." | |
} | |
if (Test-Path -LiteralPath $DestinationFile -PathType Container) { | |
throw "Destination file `"$DestinationFile`" already exists and it is a directory." | |
} | |
$directory = Split-Path $DestinationFile -Parent | |
if ($directory -and -not (Test-Path $directory -PathType Container)) { | |
throw "Destination directory `"$directory`" does not exist." | |
} | |
return $DestinationFile | |
} | |
$epubMimetypeFile = "mimetype" | |
$epubMimetypeName = "application/epub+zip" | |
$epubContainerFile = Join-Path "META-INF" "container.xml" | |
$systemTempPath = [System.IO.Path]::GetTempPath() | |
function Assert-EpubSource([String] $inputDirPath) | |
{ | |
if (!(Test-Path -LiteralPath $inputDirPath -PathType Container)) { | |
throw "Path `"${inputDirPath}`" is not a directory." | |
} | |
$containerPath = Join-Path $inputDirPath $epubContainerFile | |
if (!(Test-Path -LiteralPath $containerPath -PathType Leaf)) { | |
throw "File `"${epubContainerFile}`" not found. Not an e-book?" | |
} | |
$mimeTypePath = Join-Path $inputDirPath $epubMimetypeFile | |
if (Test-Path -LiteralPath $mimeTypePath -PathType Leaf) { | |
$content = (Get-Content -LiteralPath $mimeTypePath).Trim() | |
if ($content -ne $epubMimetypeName) { | |
throw "MIME type `"$content`" is not a valid type for epub (should be `"$epubMimetypeName`")" | |
} | |
} | |
} | |
function Get-EpubTempMimetype | |
{ | |
$tempPath = Join-Path $systemTempPath "epub" | |
if (!(Test-Path -LiteralPath $tempPath -PathType Container)) { | |
New-Item -LiteralPath $tempPath -ItemType Directory | |
} | |
$mimetypeTempFile = Join-Path $tempPath $epubMimetypeFile | |
Set-Content -LiteralPath $mimetypeTempFile -Value $epubMimetypeName -NoNewline | |
return $mimetypeTempFile | |
} | |
function Show-EpubFileSummary([String] $outputFile) | |
{ | |
$size = (Get-ItemPropertyValue -LiteralPath $outputFile -Name Length).ToString('N0') | |
Write-Output "File: $outputFile" | |
Write-Output "Size: ${size} bytes" | |
} | |
function Build-Epub([String] $inputDirPath, [String] $outputFile = $null) | |
{ | |
$inputDirPath = (Resolve-Path -LiteralPath $inputDirPath -ErrorAction Stop).Path | |
Assert-EpubSource $inputDirPath | |
if (!$outputFile) { | |
$name = (Split-Path $inputDirPath -Leaf) + ".epub" | |
$outputFile = Join-Path (Split-Path $inputDirPath -Parent) $name | |
} elseif ($outputFile -notmatch ".+\.(epub|zip)$") { | |
$outputFile = $outputFile + ".epub" | |
} | |
$mimeTypePath = Join-Path $inputDirPath $epubMimetypeFile | |
if (!(Test-Path -LiteralPath $mimeTypePath -PathType Leaf)) { | |
$mimeTypePath = Get-EpubTempMimetype | |
} | |
$items = Get-ChildItem -LiteralPath $inputDirPath | |
$items = $items.Where({$_.Name -ne $epubMimetypeFile}).ForEach({$_.FullName}) | |
Remove-Item -LiteralPath $outputFile -ErrorAction Ignore | |
Compress-Archive -LiteralPath $mimeTypePath $outputFile -CompressionLevel NoCompression | |
Compress-Archive -LiteralPath $items $outputFile -Update -CompressionLevel Fastest -ErrorAction Ignore | |
} | |
Main |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment