param (
$Path ,
$Index = " H:\AnimeLib " ,
[switch] $Single
)
#$TargetName = "俺だけ入れる隠しダンジョン〜こっそり鍛えて世界最強〜";
$TargetName = " "
#$DestinName = "真の仲間"
Write-Output $Path
#$Path = "H:\Anime\201901 盾の勇者の成り上がり\[LKSUB][Tate no Yuusha no Nariagari][01-25][GB][720P][MP4]\[LKSUB][Tate no Yuusha no Nariagari][01][GB][720P].mp4"
#$Path = "H:\Data\Downloads\因為不是真正的夥伴而被逐出勇者隊伍\[Shin no Nakama][01][BIG5][1080P].mp4"
$JsonPath = $ ( " $ Index\Anime\* $ TargetName " , $ ( $Path -replace '(.*\\[^\[\\\]]*)\\\[.*' , '$1' ) | ? { Test-Path $_ } )
$WorkData = $ ( if ( Test-Path " $ JsonPath\animelibk.json " ) {
Get-Content " $ JsonPath\animelibk.json " | ConvertFrom-Json
} else {
" " | select ID , WorkName , TargetName , DestinName , Season , Episode
} )
# 確認資料狀態,缺少則進行物件資料建立
if ( -not ( $WorkData . WorkName ) ) {
$WorkData . WorkName = Read-Host " 請輸入作品名稱: " ;
}
if ( -not ( $WorkData . TargetName ) ) {
$WorkData . TargetName = $ ( $JsonPath -replace '.*\\[0-9\s]*(.*)$' , '$1' ) ;
}
if ( -not ( $WorkData . DestinName ) ) {
$WorkData . DestinName = Read-Host " 請輸入目的地名稱: " ;
}
if ( -not ( $WorkData . Season ) ) {
[int] $WorkData . Season = Read-Host " 請輸入季別: " ;
}
if ( -not ( $WorkData . Episode ) ) {
$WorkData . Episode = @ ( ) ;
}
$WorkData
$Seasons_TC = " " , " 第一季 " , " 第二季 " , " 第三季 " , " 第四季 " , " 第五季 "
$Year = @ ( $ ( $JsonPath -replace '.*\\((?<Y>\d{4})?(?<M>\d{2})?).*$' , '${Y}' ) , $ ( get-date -Format 'yyyy' ) ) | ? { -not ( [string] :: IsNullOrEmpty ( $_ ) ) } | Select -First 1
#$($JsonPath -replace '.*\\((?<Y>\d{4})?(?<M>\d{2})?).*$', '${Y}');
# 取得目標資料夾是否存在,不存在建立資料夾,並取得資料夾物件
$LinkPath = " {2}\{0}\{1} " -f $WorkData . DestinName , $Seasons_TC [ $WorkData . Season ] , $Index
$LinkDir = $ ( if ( -not ( Test-Path -Path " $ LinkPath* " ) ) {
New-Item -Path " $ LinkPath ( $ Year) " -ItemType Directory -Force
} else {
Get-Item -Path " $ LinkPath* "
} )
#$DestDir = $(New-Item -Path ".\$WorkData.DestinName\$($Seasons_TC[$WorkData.Season]) ($Year)" -ItemType Directory -Force)
function Get-StandName {
param (
$FileObj
)
# 進行傳入變數判斷,非 FileInfo 物件則視為 String,先進特殊字元處理,再取得物件
$File = $ ( if ( $FileObj . GetType ( ) . Name -eq 'FileInfo' ) {
$FileObj
} else {
Get-Item -Path $ ( $FileObj -replace '([\[\]])' , '`$1' )
} )
# 因應檔名不同而設定多組正規方式
$Result = @ ( $ (
#$($File.Name -match "[\[\s]([^\]]*?)(?:[\]\[\-\s]+)(\d{1,2})[\]\s]")
$ ( $File . Name -match " [\[\s](?<Name>\b[^\]]*\b)(?:[\]\[\-\s]+)(?<Episode>\d{1,2})(?:[vV]\d|FIN|END)?[\]\s] " )
) | % { if ( $_ ) { $Matches } } )
# 檔名分析測試用
# $Pathes = @(
# "L:\Anime\200910 聖剣の刀鍛冶(聖劍鍛造師)\[DMG][The Sacred Blacksmith][01-12 END][848x480][BIG5]\[DMG][The Sacred Blacksmith][04V2][848x480][BIG5].rmvb"
# "H:\Anime\201901 盾の勇者の成り上がり\[LKSUB][Tate no Yuusha no Nariagari][01-25][GB][720P][MP4]\[LKSUB][Tate no Yuusha no Nariagari][01][GB][720P].mp4"
# "L:\Anime\202004 ストライク・ザ・ブラッド OVA IV\[Suzu-Kaze][Strike_the_Blood_IV_OVA][01-12FIN][BDRip_1080P][HEVC_YUV420P10]\[Suzu-Kaze] Strike the Blood IV 12FIN [BDRip 1920x1080 HEVC YUV420P10 FLAC].mkv"
# "L:\Anime\200910 アスラクライン II(機巧魔神)\[DMG][Asura Cryin2][01-13 END][848x480][BIG5][RMVB]\[DMG][Asura Cryin 2][01][848x480][Big5].rmvb"
# "H:\Data\Downloads\異世界食堂\[Lilith-Raws] Isekai Shokudou S02 - 06 [Baha][WEB-DL][1080p][AVC AAC][CHT][MP4].mp4"
# )
# $TestName = @($Pathes | % {$_.Split("\\")[-1]})
# $Result = @( $TestName | % { @(
#$($_ -match "\[([^\]]*)\]\[(\d{1,2})\]")
# $($_ -match "[\[\s](?<Name>\b[^\]]*\b)(?:[\]\[\-\s]+)(?<Episode>\d{1,2})(?:[vV]\d|FIN|END)?[\]\s]")
# ) | % { if ($_) { $Matches }}})
# Write-Output $Result
# $Matches
# OLD Edition
#$File.Name -match "\[([^\]]*)\]\[(\d{1,2})\]" | Out-Null
#$Matches
#$newName = "{0} S{3:00}E{1}{2}" -f $Matches[1], $Matches[2], $File.Extension, $Season;
#$newName = "{0} S{3:00}E{1}{2}" -f $Result[1], $Result[2], $File.Extension, $WorkData.Season;
# 建立回傳資料物件,以方便後續資料處理。
$OutputData = " " | Select newName , Season , Episode , newFullName ;
$OutputData . newName = $Result . Name ;
$OutputData . Season = $WorkData . Season ;
$OutputData . Episode = [int] $Result . Episode ;
$OutputData . newFullName = " {0} S{3:00}E{1}{2} " -f $Result . Name , $Result . Episode , $File . Extension , $WorkData . Season ;
#$OutputData | ConvertTo-Json;
# Type 2,在輸出顯示上,此型態建立較傾向 Hash,而上面 select 建立的,較偏向 pscustomobject
#$OutputData2 = @{
# newName = $Result[1];
# Season = [int] $WorkData.Season;
# Episode = [int] $Result[2];
# newFullName = "{0} S{3:00}E{1}{2}" -f $Result[1], $Result[2], $File.Extension, $WorkData.Season;
#};
#$OutputData2 | ConvertTo-Json;
#Write-Output $File;
#Write-Output $File.Name;
#Write-Output $newName;
#return $newName;
return $OutputData ;
}
### Select Object Mode START ###
# 建立自定屬性 File 和運算公式
$FileObj = @ {
label = " File " ;
Expression = { $_ } ;
}
# 建立自定屬性 NewName 和運算公式
$NewNameObj = @ {
label = " NewName " ;
Expression = { Get-StandName $_ } ;
}
$StructPathObj = @ {
label = " StructPath " ;
#Expression = {$(New-Item -Path $(".\{0}\{1} ({2})" -f $WorkData.DestinName, $Seasons_TC[$WorkData.Season], $Year) -ItemType Directory -Force).FullName};
Expression = { $LinkDir } ;
}
### # Select Object Mode END ###
# 運作模式
if ( $Single ) {
# 單集模式
$List = @ ( Get-Item -Path $ ( $Path -replace '([\[\]])' , '`$1' ) )
$BuildList = $List | select $FileObj , $StructPathObj , $NewNameObj | ? { $_ . NewName . Episode -notin $WorkData . Episode }
#$BuildList | ? {$_.NewName.Episode -notin $WorkData.Episode} | Format-List
}
$ENDResult = $BuildList | % {
$Command = @ {
ItemType = 'HardLink'
Path = $ ( " {0}\{1} " -f $_ . StructPath , $_ . NewName . newFullName )
Target = $ ( $_ . File . Fullname -replace '([\[\]])' , '`$1' )
}
#try {
# 判斷 New-Item @Command 是否成功,將 NEWNAME 物件作為回傳值
if ( New-Item @Command ) { $_ . NewName }
#} catch {
#}
}
#$ENDResult
#$ENDResult.gettype();
$ENDResult | % { if ( $_ . Episode ) { $WorkData . Episode + = $_ . Episode } }
$WorkData | ConvertTo-Json | Out-File -Encoding " UTF8 " " $ JsonPath\animelibk.json "
exit 0 ;
##### 以下試寫或測試用 #####
# SIG # Begin signature block
# MIIFxwYJKoZIhvcNAQcCoIIFuDCCBbQCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUX9/yYsS2o/ap36sf/Bq1uDoj
# CIOgggNSMIIDTjCCAjagAwIBAgIQdMnAQ4BDAo9Lgfn+QeDdhjANBgkqhkiG9w0B
# AQUFADAqMRMwEQYDVQQDDApOaWNrIENoYW5nMRMwEQYDVQQKDAplYXJpY2sub3Jn
# MB4XDTIxMTAzMTEwMDI1MVoXDTIyMTAzMTEwMjI1MVowMzEiMCAGCSqGSIb3DQEJ
# ARYTcGNuaWNrMTAwQGdtYWlsLmNvbTENMAsGA1UEAwwETmljazCCASIwDQYJKoZI
# hvcNAQEBBQADggEPADCCAQoCggEBAMEnEk3/5rkEMibDbbfOXQaerk5xXSJmY8gf
# FAVUbrGfjzYHcRsPRzdb/pstcZGS2XUCoX2a57lQhACStns9dXeYfWhzNeAiSEAy
# iaJzUj5ELcH5TzT+mjeJQX6upeHOexO1TmtuM6mugpl9SvNQFqbQXlPHHmoLE3OC
# UzzjEC0AkHkcSiLdqtmSbRmaomcDMbtJgZHUciWE/p6mmAbpv2R4rdKSYSiI8UsE
# UclzkeTNrYKmJNiM0R+X1LyZVY6HAHN8dR3tjBnEPYoPxRAz4d2FEajvumzosNUr
# ni9LROnRxQXa048ZcsNArNZDQXe+Rc+PWhzbqHhy8rBllgZ08XkCAwEAAaNnMGUw
# DgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMB8GA1UdIwQYMBaA
# FBXyUrhn78ppKe7GRmHS6vbsNae/MB0GA1UdDgQWBBRs5+Yfb/14jwpjUNpTUuR1
# 759t9TANBgkqhkiG9w0BAQUFAAOCAQEACSL1BqUcrqh+bBqr5rQ5mArCVxsBW92r
# HenPY48dKdhGgMODtxuo7osZLk7Il+aXhAsvNTSfmc92H5eDXFqZ565jm8r6FF1C
# f1oKxznmtxd4oyXflCRqBz+OGuXLq8dG9gWT7OisKWe0hifSMGaZ9afpNeiFLuD1
# GSGk5E0W+bUyezCmjOdNWYIW452brt8rJS21WWVVvrsGjgJoTdsoAkFek8OEm82+
# 1UR7xZOHybLvi8N0gvD+UFlVvcv6pmgUqaz5DS7J2si75Xj9pThE6/bPu/fkpc53
# gMbleXNaqXIKeJTbI5hi2crlKyXBe/GfuK0Tv+06S1sL32VAs1VwmjGCAd8wggHb
# AgEBMD4wKjETMBEGA1UEAwwKTmljayBDaGFuZzETMBEGA1UECgwKZWFyaWNrLm9y
# ZwIQdMnAQ4BDAo9Lgfn+QeDdhjAJBgUrDgMCGgUAoHgwGAYKKwYBBAGCNwIBDDEK
# MAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3
# AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQUHXjy5RD0ZBMCmQ+P
# NgKY+6wL0OYwDQYJKoZIhvcNAQEBBQAEggEAsBGnRtXBwIvUcUY1RxSLZZRVziE+
# ezXU4LASl87P/CLE+4mBZ5+XORU7Yxhz/m2VUpE+vwpct047OLSgZ0n+WcTSl8Iq
# p7ag+mwyKriRFz7iU3mb4VvS4xF7VZIAcIBhGUA5C90StqGxmX7iH0lQYhL9URu0
# evAy2wL01WyIInXGfXgbS/Zr40fmlUlt3kHugrzgNiCLKZyLo1598Bsdda0+dpMf
# uobPwGbccM1w/40UYLh6LcIz+oVcH0PNncy63XBkqSKIrTNHgznoLCt8wnSLqfgq
# QZ+dgNGA+M8UvyFBLBxfUIvKfK8LAlmb8uHHHqGgw+dnZobDFvyNxgZrrg==
# SIG # End signature block