Skip to content

Instantly share code, notes, and snippets.

@AndroPlus-org
Last active June 15, 2018 13:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AndroPlus-org/1cec12621f80045911bd5d4a20aaa7c5 to your computer and use it in GitHub Desktop.
Save AndroPlus-org/1cec12621f80045911bd5d4a20aaa7c5 to your computer and use it in GitHub Desktop.
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