Upload recorded files to Google Drive (use with Mirakurun + EPGStation + gdrive)
#config.jsonの変更が必要です | |
#識別するため%ID%をファイル名の最後に追加 | |
#"recordedFormat": "%YEAR%年%MONTH%月%DAY%日%HOUR%時%MIN%分- | |
#Googleドライブでは.m2ts拡張子でないとエンコードされません | |
#"fileExtension": ".m2ts", | |
#プログラムID | |
$program_id = "$env:PROGRAMID" | |
#====================ユーザ設定==================== | |
#--------------------Google ドライブへアップロード-------------------- | |
#0=無効、1=有効 | |
$gdrive_toggle = 1 | |
#アップロード用ディレクトリ | |
$bas_folder_path = 'C:\DTV\upload' | |
#アップロード中の一時ディレクトリ | |
$tmp_bas_folder_path = 'C:\DTV\uploadtmp\' | |
#gdrive.exe | |
$gdrive_path = 'C:\DTV\bin\gdrive-windows-x64.exe' | |
#Google ドライブ上のアップロード先フォルダID | |
$gdrive_folder_id = 'XXXXXXXXXXX' | |
#gdriveコマンドが使う設定ファイル | |
#あらかじめgdrive listなどコマンドを打って認証を済ませてください | |
$gdrive_config = 'C:\Users\user\AppData\Roaming\.gdrive' | |
#今日の月 | |
$this_month = Get-Date -UFormat "%Y年%m月" | |
#アップロード先フォルダID (後で自動生成されます) | |
$gdrive_target_folder_id = '' | |
#--------------------一時パスやログなどの設定-------------------- | |
#実行日時 | |
$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 = "C:\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 | |
if ($fileStream) { | |
$fileStream.Close() | |
} | |
} | |
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 $Path) { | |
if ((Get-Item -path $path) -is [System.IO.FileInfo]) { | |
return (filelock -Path $Path).filelocked | |
} | |
elseif ((Get-Item $Path) -is [System.IO.DirectoryInfo]) { | |
Write-Verbose "[$Path] detect as $((Get-Item -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 | |
} | |
} | |
} | |
#====================ファイルがロックされていないか確認する==================== | |
#念のため15秒待機 | |
Write-Output "Waiting..." | |
Start-Sleep 15 | |
#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 "Checking target folder..." | |
$arg_finddir = "list --config ${gdrive_config} --no-header --max 1 --name-width 0 --query " | |
$arg_finddir2 = " `" '`"${gdrive_folder_id}`"' in parents and trashed = false and 'me' in owners and mimeType = 'application/vnd.google-apps.folder' and name = '`"${this_month}`"' `" " | |
$pfinfo = New-Object System.Diagnostics.ProcessStartInfo | |
$pfinfo.FileName = "${gdrive_path}" | |
$pfinfo.RedirectStandardOutput = $true | |
$pfinfo.UseShellExecute = $false | |
$pfinfo.Arguments = "${arg_finddir}", ${arg_finddir2} | |
$pf = New-Object System.Diagnostics.Process | |
$pf.StartInfo = $pfinfo | |
$pf.Start() | Out-Null | |
$pfstdout = $pf.StandardOutput.ReadToEnd() | |
$pf.WaitForExit() | |
("${pfstdout}").foreach{if ($_ -match "[A-Za-z0-9_\-]{28,50}") {$parent_id = $matches[0]}} | |
#parent_idが空でないなら使用、空ならフォルダ作成 | |
if ( $parent_id ) { | |
$gdrive_target_folder_id = "${parent_id}" | |
Write-Output "Taret folder is already there: ${parent_id}" | |
} | |
else { | |
Write-Output "Creating target folder..." | |
$arg_mkdir = "mkdir `"${this_month}`" --parent `"${gdrive_folder_id}`" --config ${gdrive_config}" | |
$pinfo = New-Object System.Diagnostics.ProcessStartInfo | |
$pinfo.FileName = "${gdrive_path}" | |
$pinfo.RedirectStandardOutput = $true | |
$pinfo.UseShellExecute = $false | |
$pinfo.Arguments = "${arg_mkdir}" | |
$p = New-Object System.Diagnostics.Process | |
$p.StartInfo = $pinfo | |
$p.Start() | Out-Null | |
$stdout = $p.StandardOutput.ReadToEnd() | |
$p.WaitForExit() | |
#Write-Host "stdout: $stdout" | |
#Write-Host "exit code: " + $p.ExitCode | |
#フォルダを作成出来たら | |
if ($p.ExitCode -eq 0) { | |
("${stdout}").foreach{if ($_ -match "[A-Za-z0-9_\-]{28,50}") {$gdrive_target_folder_id = $matches[0]}} | |
Write-Output "Taret folder is created: ${gdrive_target_folder_id}" | |
} | |
} | |
if ( $gdrive_target_folder_id -eq '' ) { | |
Write-Output "Upload to root folder..." | |
$arg = "sync upload `"${tmp_folder_path}`" `"${gdrive_folder_id}`" --config ${gdrive_config}" | |
} | |
else { | |
Write-Output "Upload to month folder..." | |
$arg = "sync upload `"${tmp_folder_path}`" `"${gdrive_target_folder_id}`" --config ${gdrive_config}" | |
} | |
Write-Output "Uploading..." | |
$proc = Start-Process -FilePath "${gdrive_path}" -ArgumentList ${arg} -Wait -NoNewWindow -PassThru | |
#Google ドライブへのアップロードが完了したら | |
if ($proc.ExitCode -eq 0) { | |
# bas_folder_path以下にあるすべてのファイルを削除 | |
#Get-ChildItem ${tmp_bas_folder_path} -Include *.* -Recurse | del | |
#一時フォルダを削除 | |
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} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment