|
#config.jsonの変更が必要です |
|
#識別するため%ID%をファイル名の最後に追加 |
|
#"recordedFormat": "%YEAR%年%MONTH%月%DAY%日%HOUR%時%MIN%分- |
|
#Googleドライブでは.m2ts拡張子でないとエンコードされません |
|
#"fileExtension": ".m2ts", |
|
|
|
#プログラムID |
|
$program_id = "$env:PROGRAMID" |
|
|
|
#今日の月 |
|
$this_month = Get-Date -UFormat "%Y年%m月" |
|
|
|
#====================ユーザ設定==================== |
|
#--------------------Google ドライブへアップロード-------------------- |
|
#0=無効、1=有効 |
|
$gdrive_toggle = 1 |
|
#アップロード用ディレクトリ |
|
$bas_folder_path = 'D:\DTV\upload' |
|
#アップロード中の一時ディレクトリ |
|
$tmp_bas_folder_path = 'D:\DTV\uploadtmp\' |
|
#rclone.exeのパス |
|
$rclone_path = 'D:\DTV\bin\rclone\rclone.exe' |
|
#rcloneの設定ファイルのパス |
|
#あらかじめrclone configで認証を済ませてください |
|
$config_path = 'C:\Users\user\.config\rclone\rclone.conf' |
|
#アップロード先のフォルダ指定 |
|
#driveはrclone configで設定したremoteの名前です |
|
$dest_folder_path = "drive:@録画/${this_month}" |
|
|
|
#--------------------一時パスやログなどの設定-------------------- |
|
#実行日時 |
|
$run_datetime = Get-Date -UFormat "%Y%m%d-%H%M%S" |
|
#$run_datetime="20180602-231420" |
|
|
|
#一時フォルダのパス |
|
$tmp_folder_path = "${tmp_bas_folder_path}${run_datetime}" |
|
|
|
# ログのパスと名前 |
|
$log_path = "D:\DTV\logs" |
|
$log_file = "${log_path}\uploadlog_${run_datetime}.txt" |
|
|
|
#ログ取得開始 |
|
Start-transcript -path "${log_file}" |
|
|
|
#"--------環境変数--------" |
|
#Get-ChildItem env: |
|
#"--------環境変数--------" |
|
|
|
Write-Output "プログラムID: $program_id" |
|
|
|
#====================ファイルがロックされているか確認する==================== |
|
#Thanks guitarrapc! |
|
#https://github.com/guitarrapc/PowerShellUtil/blob/master/Test-FileLock/Test-FileLock.psm1 |
|
function Filelock { |
|
# ファイルロック中のファイルを検査する |
|
param ( |
|
[parameter( |
|
position = 0, |
|
mandatory |
|
)] |
|
[System.IO.FileInfo] |
|
$Path |
|
) |
|
|
|
try { |
|
# initialise variables |
|
$script:filelocked = $false |
|
|
|
# attempt to open file and detect file lock |
|
$script:fileInfo = New-Object System.IO.FileInfo $Path |
|
$script:fileStream = $fileInfo.Open([System.IO.FileMode]::OpenOrCreate, |
|
[System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::None) |
|
# close stream if not lock |
|
$f1 = $fileStream |
|
Write-Host $f1 |
|
$f2 = $filelocked |
|
if ($fileStream) { |
|
$fileStream.Close() |
|
$f3 = $fileStream |
|
$f4 = $filelocked |
|
} |
|
} |
|
catch { |
|
# catch fileStream had falied |
|
$filelocked = $true |
|
} |
|
finally { |
|
# return result |
|
[PSCustomObject]@{ |
|
path = $Path |
|
filelocked = $filelocked |
|
} |
|
} |
|
} |
|
|
|
function Test-FileLock { |
|
param ( |
|
[parameter( |
|
position = 0, |
|
mandatory |
|
)] |
|
[string] |
|
$Path |
|
) |
|
|
|
try { |
|
if (Test-Path -LiteralPath $Path) { |
|
if ((Get-Item -path $path) -is [System.IO.FileInfo]) { |
|
return (filelock -Path $Path).filelocked |
|
} |
|
elseif ((Get-Item -LiteralPath $Path) -is [System.IO.DirectoryInfo]) { |
|
Write-Verbose "[$Path] detect as $((Get-Item -LiteralPath -path $Path).GetType().FullName). |
|
Skip cehck." |
|
} |
|
} |
|
else { |
|
Write-Error "[$Path] could not find. |
|
+ CategoryInfo : ObjectNotFound: ($Path), ItemNotFoundException |
|
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetItemCommand" |
|
} |
|
} |
|
catch { |
|
Write-Error $_ |
|
} |
|
} |
|
|
|
#====================8.3形式のファイル名を取得する==================== |
|
|
|
Function Get-ShortPath { |
|
Param([string]$name) |
|
|
|
BEGIN { $fso = New-Object -ComObject Scripting.FileSystemObject } |
|
PROCESS { |
|
try { |
|
$fsi = (Get-Item -LiteralPath $name -ErrorAction Stop) |
|
} |
|
catch { |
|
return $name |
|
} |
|
|
|
$fullname = $fsi.FullName |
|
if ($fsi.psiscontainer) { |
|
return $fso.GetFolder($fullname).ShortPath |
|
} |
|
else { |
|
return $fso.GetFile($fullname).ShortPath |
|
} |
|
} |
|
} |
|
|
|
#====================アップロードできなかった時のアラートメール==================== |
|
|
|
Function Send-Aleart { |
|
$mail = @{ |
|
from = "XXXXXXXXXX@example.com"; |
|
to = "XXXXXXXXXX@example.com"; |
|
smtp_server = "smtp.gmail.com"; |
|
smtp_port = 587; |
|
user = "XXXXXXXXXX@example.com"; |
|
password = "XXXXXXXXXX"; |
|
} |
|
|
|
$password = ConvertTo-SecureString $mail["password"] -AsPlainText -Force |
|
$credential = New-Object System.Management.Automation.PSCredential $mail["user"], $password |
|
|
|
Send-MailMessage -To $mail["to"] ` |
|
-From $mail["from"] ` |
|
-SmtpServer $mail["smtp_server"] ` |
|
-Credential $credential ` |
|
-Port $mail["smtp_port"] ` |
|
-Subject "録画鯖 アップロード失敗" ` |
|
-Body "録画したファイルをアップロードできませんでした。" ` |
|
-Encoding UTF8 ` |
|
-UseSsl |
|
} |
|
|
|
#====================ファイルがロックされていないか確認する==================== |
|
|
|
#mp4ファイルが存在する = エンコードした場合 |
|
Write-Output "Checking MP4 file..." |
|
if ( Test-Path "${bas_folder_path}\*${program_id}.mp4" ) { |
|
#録画したファイルのパスを取得する |
|
$mp4_file = Get-ChildItem -LiteralPath "${bas_folder_path}" | where { $_.Name -match "${program_id}.mp4"} |
|
$mp4_file_83path = Get-ShortPath("${bas_folder_path}\${mp4_file}") |
|
|
|
#エンコード完了するまで待機する |
|
Write-Output "Wait for file to be freed by process..." |
|
while (Test-FileLock -Path "${mp4_file_83path}") { Start-Sleep 10 } |
|
Write-Output "MP4 file ready!" |
|
} |
|
|
|
#念のため5秒待機 |
|
Write-Output "Waiting..." |
|
Start-Sleep 5 |
|
|
|
#m2tsファイルが存在する = エンコードしていないかTS削除しなかった場合 |
|
Write-Output "Checking TS file..." |
|
if ( Test-Path "${bas_folder_path}\*${program_id}.m2ts" ) { |
|
#録画したファイルのパスを取得する |
|
$ts_file = Get-ChildItem -LiteralPath "${bas_folder_path}" | where { $_.Name -match "${program_id}.m2ts"} |
|
$ts_file_83path = Get-ShortPath("${bas_folder_path}\${ts_file}") |
|
|
|
#使用中かどうか確認し、使用中なら10秒待機して再確認する |
|
Write-Output "Wait for file to be freed by process..." |
|
while (Test-FileLock -Path "${ts_file_83path}") { Start-Sleep 10 } |
|
Write-Output "TS file ready!" |
|
} |
|
|
|
#====================Google ドライブへアップロードする==================== |
|
#Google ドライブの指定したフォルダへアップロード後、削除する |
|
if ("${gdrive_toggle}" -eq "1") { |
|
|
|
#一時フォルダを作成 |
|
Write-Output "Creating temp folder..." |
|
New-Item "${tmp_folder_path}" -itemType Directory -Force |
|
|
|
#念のため10秒待機 |
|
Write-Output "Waiting..." |
|
Start-Sleep 10 |
|
|
|
#出力されたファイルを一時フォルダへ移動 |
|
Write-Output "Moving files to temp folder..." |
|
Get-ChildItem "${bas_folder_path}" | where { $_.Name -match "${program_id}"} | Move-Item -Destination "${tmp_folder_path}" |
|
|
|
Write-Output "Uploading..." |
|
$arg = "copy ${tmp_folder_path} ${dest_folder_path} -v --config ${config_path}" |
|
$proc = Start-Process -FilePath "${rclone_path}" -ArgumentList ${arg} -PassThru -NoNewWindow |
|
|
|
#タイムアウトの初期化 |
|
$timeouted = $null |
|
|
|
#3時間 (10800秒) 経ってもアップロード完了していなければエラーで止まったと見なす |
|
#Google ドライブは通常13GBのファイルを30分程度でアップロードできる |
|
#よほど遅い回線か、長時間番組を録らない限り大丈夫なはず |
|
$proc | Wait-Process -Timeout 10800 -ea 0 -ev timeouted |
|
|
|
if ( $timeouted ) { |
|
Write-Output "Upload failed with timeout..." |
|
#プロセスを終了する |
|
$proc | kill |
|
|
|
#アラートメールを送信する |
|
Send-Aleart |
|
} |
|
elseif ($proc.ExitCode -eq 0) { |
|
#Google ドライブへのアップロードが完了したら一時フォルダを削除 |
|
Write-Output "Upload completed!" |
|
Write-Output "Cleaning temp folder..." |
|
Remove-Item "${tmp_folder_path}" -Recurse |
|
} |
|
|
|
#空フォルダを削除 |
|
Set-Location ${tmp_bas_folder_path} |
|
Get-ChildItem -Recurse | Where-Object { $_.GetType().Name -eq "DirectoryInfo" -and $_.GetFiles().Count -eq 0 } | Remove-Item -Recurse |
|
|
|
#ログ取得終了 |
|
Stop-transcript |
|
|
|
#古いログファイルを最終更新日順に並べ、最新30個は除外して削除する |
|
Get-ChildItem "${log_path}" | |
|
Sort-Object LastWriteTime -Descending | |
|
Select-Object -Skip 30 | |
|
foreach {Remove-Item $_.FullName} |
|
} |