A PowerShell script that renames and organizes a directory of scanned tarot cards.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

370 lines
12 KiB

4 years ago
# tarot folder
$tdir = $env:OneDrive + "\Projects\Tarot\Scans"
# empty array to hold menu options for user interaction
$menuOpts = @{};
# retrieve list of decks (folders) in $tdir
$decks = Get-ChildItem -path $tdir -Directory
Write-Host = "==================== Scanned Decks ===================="
# for each deck, create a new menu item
for ($d = 0; $d -lt $decks.Count; $d++) {
Write-Host "[$d] $($decks[$d].Name)"
$menuOpts.Add($d, $decks[$d])
}
# ask user which directory to use
[int]$selOpt = Read-Host "Select a deck directory"
$theOpt = $menuOpts.Item($selOpt)
Write-Host ""
# if directory contains no files, check for directories
$files = Get-ChildItem -Path $theOpt.FullName -File
$dirs = Get-ChildItem -Path $theOpt.FullName -Directory
if ($null -eq $files -and $null -eq $dirs) {
# nothing useful found, die
Write-Host "The selected deck directory has no files or folders. Try again."
end;
}
else {
# initialize string arrays
$trumps = @(
"The Fool",
"The Magician",
"The High Priestess",
"The Empress",
"The Emperor",
"The Hierophant",
"The Lovers",
"The Chariot",
"Strength",
"The Hermit",
"The Wheel of Fortune",
"Justice",
"The Hanged Man",
"Death",
"Temperance",
"The Devil",
"The Tower",
"The Star",
"The Moon",
"The Sun",
"Judgememt",
"The World"
)
$trumps = @(
"The Fool",
"The Magician",
"The High Priestess",
"The Empress",
"The Emperor",
"The Hierophant",
"The Lovers",
"The Chariot",
"Strength",
"The Hermit",
"The Wheel of Fortune",
"Justice",
"The Hanged Man",
"Death",
"Temperance",
"The Devil",
"The Tower",
"The Star",
"The Moon",
"The Sun",
"Judgememt",
"The World",
"The Well",
"The Artist"
)
$suits = @(
"Cups",
"Pentacles",
"Swords",
"Wands"
)
$numbers = @(
"Ace",
"Two",
"Three",
"Four",
"Five",
"Six",
"Seven",
"Eight",
"Nine",
"Ten"
)
$courts = @(
"Page",
"Knight",
"Queen",
"King"
)
$trumpcount = $trumps.Count
$trumpend = $trumpcount - 1
$cardcount = $trumps.Count + 56
$npath = $theOpt.FullName
if ($null -eq $files -and $null -ne $dirs) {
# here be directories
Write-Host "The selected deck directory contains folders."
# make sure there's exactly five directories
# major arcana plus four suits
if ($dirs.Count -ne 5) {
Write-Host "Directory must have exactly five directories. Fix and try again."
}
else {
# we have five directories
# use existing directory name
# if directory contains 22 cards, it's 00
# if directory contains 14 cards, it's 01..04
# everything else is ignored
$suitindex = 1
foreach($dir in $dirs) {
$numfiles = ($dir | Get-ChildItem | Measure-Object).Count
$dirname = $dir.Name
if ($numfiles -eq $trumpcount) {
# major arcana
$newdir = $dir.Parent.FullName + "\00 - $dirname"
# get list of images
$cards = $dir | Get-ChildItem
# for each of 22 images, go through the list of card names
foreach($t in 0..$trumpend) {
# get the file
$file = $cards[$t]
# set new filename e.g. 00.00 - The Fool
$base = $t.ToString().PadLeft(2,'0')
$card = $trumps[$t]
$new = "00" + "." + $base + " - " + $card + ".jpg"
$newname = $dir.FullName + "\" + $new
if ($file.Name -eq $new) {
# this file has already been processed and named.
continue
}
else {
# rename the image to the standard format
Rename-Item $file.FullName -NewName $newname
}
}
# rename directory
Rename-Item $dir.FullName -NewName $newdir
}
elseif ($numfiles -eq 14) {
# suits
# suit name is folder name
$suitname = $dir.Name
# get the number, e.g. 01
$suitnum = $suitindex.ToString().PadLeft(2,"0")
# set the new folder name
$newdir = $dir.Parent.FullName + "\$suitnum - $suitname"
# get the cards
$cards = $dir | Get-ChildItem
# loop through cards range
foreach($i in 0..13) {
# get the file
$file = $cards[$i]
$card = $fullsuit[$i] + " of " + $suitname
# set new filename e.g. 00.00 - The Fool
$base = ($i + 1).ToString().PadLeft(2,'0')
$new = $suit + "." + $base + " - " + $card + ".jpg"
$newname = $dir.FullName + "\" + $new
if ($file.Name -eq $new) {
# this file has already been processed and named.
continue
}
else {
# save the changes
Rename-Item $file.FullName -NewName $newname
}
}
# rename directory
Rename-Item $dir.FullName -NewName $newdir
# add one to the suit index
$suitindex++
}
else {
Write-Host "Directory $($dir.Name) must have exactly 14 or 22 cards. Fix and try again."
break;
}
}
}
}
elseif ($null -ne $files) {
# set up variables
$suitsin = Read-Host "Enter a comma-separated list of four suit names. List will be processed in order. Default is Cups,Pentacles,Swords,Wands"
$courtsin = Read-Host "Enter a comma-separated list of four court names. List will be processed in order. Default is Page,Knight,Queen,King"
if ($suitsin -ne "") {
$suits = $suitsin.Split(",").Trim()
}
if ($courtsin -ne '') {
$courts = $courtsin.Split(",").Trim()
}
$fullsuit = $numbers + $courts
# here be files
Write-Host "The selected deck directory contains files."
# get file types
$exts = $files.Extension | group
if ($exts.Count -ne $cardcount.ToString()) { #-or ($exts | % { $_.Count } ).Contains(78)) {
Write-Host "Directory must have exactly 78 cards. Fix and try again."
break;
}
elseif ($exts.Length -ne 1) {
Write-Host "More than one file type found. All files must be the same type."
break;
}
elseif ((".JPG,.PNG").Contains($exts.Name)) {
Write-Host "$cardcount images identified."
Write-Host "The first $trumpcount cards must be the trumps in order, Fool first."
# Create folders
$newpath = $npath + "\00 - Major Arcana"
New-Item -Path $newpath -ItemType Directory
# load .NET image assembly
[System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
# rename first 22 cards
foreach ($t in 0..$trumpend) {
# get the file
$file = $files[$t]
# set new filename e.g. 00.00 - The Fool
$base = $t.ToString().PadLeft(2,'0')
$card = $trumps[$t]
$new = "00" + "." + $base + " - " + $card + ".jpg"
if ($file.Name -eq $new) {
# this file has already been processed and named.
continue
}
else {
# create an image from the file
$img = [System.Drawing.Image]::FromFile($file.FullName)
# if the image name starts with PD_ it's new, so rotate
if ($file.Name.StartsWith("PD_")) {
# rotate the image 90 degrees
$img.RotateFlip("Rotate90FlipNone")
}
$newname = $newpath + "\" + $new
# save the changes
$img.Save($newname,"jpeg")
#$file.Delete()
}
}
Write-Host ""
if ($suits.Length -eq 4) {
# exactly four suits, proceed
foreach ($s in 0..3) {
# filename and folder base is 01,02,03,04
$suiti = $s + 1
$suit = $suiti.ToString().PadLeft(2,"0")
$suitname = $suits[$s]
$spath = $theOpt.FullName + "\$suit - $suitname"
New-Item -Path $spath -ItemType Directory
# start at index after last trump ($trumpcount)
# add 14 x $s to 22 for start index
# add 13 to above for end index
$start = $trumpcount + (14 * $s)
$end = $start + 13
# pull out the files to be renamed
$tempfiles = $files[$start..$end]
# loop through identified range
foreach($i in 0..13) {
# get the file
$file = $tempfiles[$i]
$card = $fullsuit[$i] + " of " + $suitname
# set new filename e.g. 00.00 - The Fool
$base = ($i + 1).ToString().PadLeft(2,'0')
$new = $suit + "." + $base + " - " + $card + $exts[0].Name
if ($file.Name -eq $new) {
# this file has already been processed and named.
continue
}
else {
# create an image from the file
$img = [System.Drawing.Image]::FromFile($file.FullName)
# if the image name starts with PD_ it's new, so rotate
if ($file.Name.StartsWith("PD_")) {
# rotate the image 90 degrees
$img.RotateFlip("Rotate90FlipNone")
}
$newname = $spath + "\" + $new
# save the changes
$img.Save($newname,"jpeg")
#$file.Delete()
}
}
}
}
else {
# four suits required
Write-Host "Please enter exactly four suits, separated with commas."
Write-Host "For example: Cups,Pentacles,Swords,Wands"
break;
}
}
}
}