PSLegacy/Import-XRefData.Legacy.ps1
#.ExternalHelp StreamXRef-help.xml function Import-XRefData { [CmdletBinding(DefaultParameterSetName = "General")] [OutputType([System.Void], [StreamXRef.ImportResults])] Param( [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true, ParameterSetName = "General")] [Alias("PSPath")] [ValidateNotNullOrEmpty()] [string]$Path, [Parameter(Mandatory = $true, Position = 0, ParameterSetName = "ApiKey")] [ValidateNotNullOrEmpty()] [string]$ApiKey, [Parameter(ParameterSetName = "General")] [switch]$PassThru, [Parameter()] [switch]$Persist, [Parameter()] [switch]$Quiet, [Parameter()] [switch]$Force ) Begin { $MappingWarning = $false $ConflictingData = $false $NewKeyAdded = $false $IsGeneral = $PSCmdlet.ParameterSetName -eq "General" if ($IsGeneral) { try { # Set up counters object $Counters = [StreamXRef.ImportResults]::new() $Counters.AddCounter("User") $Counters.AddCounter("Clip") $Counters.AddCounter("Video") } catch { $PSCmdlet.ThrowTerminatingError($_) } } } Process { $ImportedSchema = 0 if ($IsGeneral) { try { # Read file and convert from json $ImportStaging = Get-Content $Path -Raw | ConvertFrom-Json # Read metadata if ($ImportStaging.psobject.Properties.Name -contains "config") { $ImportedSchema = $ImportStaging.config.schema } } catch { $PSCmdlet.WriteError($_) return } } # Process ApiKey (Check parameter set first since ImportStaging won't exist in the ApiKey set) if ($PSCmdlet.ParameterSetName -eq "ApiKey" -or ($ImportStaging.psobject.Properties.Name -contains "ApiKey" -and -not [string]::IsNullOrWhiteSpace($ImportStaging.ApiKey))) { if ($PSCmdlet.ParameterSetName -eq "ApiKey") { # Get key via ApiKey parameter $script:TwitchData.ApiKey = $ApiKey } else { # Get key from input object $script:TwitchData.ApiKey = $ImportStaging.ApiKey } $NewKeyAdded = $true if (-not $Quiet) { Write-Host "API key imported." } if ($PSCmdlet.ParameterSetName -eq "ApiKey") { return } } elseif (-not $Quiet -and [string]::IsNullOrWhiteSpace($script:TwitchData.ApiKey) -and $script:TwitchData.GetTotalCount() -eq 0) { # Lookup data cache is empty # Assume user is trying to restore from a full export Write-Warning "API key missing from input." } # Process UserInfoCache if ($ImportStaging.psobject.Properties.Name -contains "UserInfoCache" -and $ImportStaging.UserInfoCache.Count -gt 0) { $ImportStaging.UserInfoCache | ForEach-Object { try { # Check if entry already exists if ($script:TwitchData.UserInfoCache.ContainsKey($_.name)) { # If so, is the data the same? if ($script:TwitchData.UserInfoCache[$_.name] -eq $_.id) { # Data is the same and can be skipped $Counters.User.Skipped++ } elseif ($Force) { # Data is different and "Force" was specified, so overwrite the data $script:TwitchData.UserInfoCache[$_.name] = $_.id $Counters.User.Imported++ } else { # Data is different and "Force" was not specified $ConflictingData = $true $Counters.User.Error++ if (-not $Quiet) { Write-Warning "Conflict for $($_.name): [new] $($_.id) -> [old] $($script:TwitchData.UserInfoCache[$_.name])" } } } else { # New data to add $script:TwitchData.UserInfoCache[$_.name] = $_.id $Counters.User.Imported++ } } catch [System.Management.Automation.PSInvalidCastException], [System.FormatException], [System.Management.Automation.PropertyNotFoundException] { # Data formatting errors Write-Error "(User Data) $($_.Exception.Message)" -Category InvalidData $Counters.User.Error++ } catch { # Halt on unknown error $PSCmdlet.ThrowTerminatingError($_) } } Write-Verbose "(User Data) $($Counters.User.Imported) entries imported." if ($Counters.User.Skipped -gt 0) { Write-Verbose "(User Data) $($Counters.User.Skipped) duplicate entries skipped." } if ($Counters.User.Error -gt 0) { Write-Verbose "(User Data) $($Counters.User.Error) entries could not be parsed or conflicted with existing data." } } # Process ClipInfoCache if ($ImportStaging.psobject.Properties.Name -contains "ClipInfoCache" -and $ImportStaging.ClipInfoCache.Count -gt 0) { $ImportStaging.ClipInfoCache | ForEach-Object { try { # Enforce type casting [int]$NewOffsetValue = $_.offset [Int64]$NewVideoIDValue = $_.video $ConvertedDateTime = $_.created | ConvertTo-UtcDateTime if ($script:TwitchData.ClipInfoCache.ContainsKey($_.slug)) { # Shorter variable for using in the "if" statements and warning message $ExistingObject = $script:TwitchData.ClipInfoCache[$_.slug] # Results mapping info is low priority and not checked here if ($ExistingObject.Offset -eq $NewOffsetValue -and $ExistingObject.VideoID -eq $NewVideoIDValue -and $ExistingObject.Created -eq $ConvertedDateTime) { $Counters.Clip.Skipped++ } elseif ($Force) { $script:TwitchData.ClipInfoCache[$_.slug] = [StreamXRef.ClipObject]@{ Offset = $NewOffsetValue VideoID = $NewVideoIDValue Created = $ConvertedDateTime Mapping = @{} } $Counters.Clip.Imported++ } else { $ConflictingData = $true $Counters.Clip.Error++ if (-not $Quiet) { Write-Warning ( "Conflict for $($_.slug):`n", "[new] $NewOffsetValue, $NewVideoIDValue, $ConvertedDateTime`n", "[old] $($ExistingObject.Offset), $($ExistingObject.VideoID), $($ExistingObject.Created)" -join "" ) } } } else { # New data to add $script:TwitchData.ClipInfoCache[$_.slug] = [StreamXRef.ClipObject]@{ Offset = $NewOffsetValue VideoID = $NewVideoIDValue Created = $ConvertedDateTime Mapping = @{} } $Counters.Clip.Imported++ } # Try importing mapping subset try { foreach ($entry in $_.mapping) { # Add to Mapping $script:TwitchData.ClipInfoCache[$_.slug].Mapping[$entry.user] = $entry.result } } catch { $MappingWarning = $true } } catch [System.Management.Automation.PSInvalidCastException], [System.FormatException], [System.Management.Automation.PropertyNotFoundException] { Write-Error "(Clip Data) $($_.Exception.Message)" -Category InvalidData $Counters.Clip.Error++ } catch { # Halt on unknown error $PSCmdlet.ThrowTerminatingError($_) } } Write-Verbose "(Clip Data) $($Counters.Clip.Imported) entries imported." if ($Counters.Clip.Skipped -gt 0) { Write-Verbose "(Clip Data) $($Counters.Clip.Skipped) duplicate entries skipped." } if ($Counters.Clip.Error -gt 0) { Write-Verbose "(Clip Data) $($Counters.Clip.Error) entries could not be parsed or conflicted with existing data." } } # Process VideoInfoCache if ($ImportStaging.psobject.Properties.Name -contains "VideoInfoCache" -and $ImportStaging.VideoInfoCache.Count -gt 0) { $ImportStaging.VideoInfoCache | ForEach-Object { try { $ConvertedDateTime = $_.timestamp | ConvertTo-UtcDateTime if ($script:TwitchData.VideoInfoCache.ContainsKey($_.video)) { if ($script:TwitchData.VideoInfoCache[$_.video] -eq $ConvertedDateTime) { $Counters.Video.Skipped++ } elseif ($Force) { $script:TwitchData.VideoInfoCache[$_.video] = $ConvertedDateTime $Counters.Video.Imported++ } else { $ConflictingData = $true $Counters.Video.Error++ if (-not $Quiet) { Write-Warning "For $($_.video): $ConvertedDateTime -> $($script:TwitchData.VideoInfoCache[$_.video])" } } } else { # New data to add $script:TwitchData.VideoInfoCache[$_.video] = $ConvertedDateTime $Counters.Video.Imported++ } } catch [System.Management.Automation.PSInvalidCastException], [System.FormatException], [System.Management.Automation.PropertyNotFoundException] { Write-Error "(Video Data) $($_.Exception.Message)" -Category InvalidData $Counters.Video.Error++ } catch { # Halt on unknown error $PSCmdlet.ThrowTerminatingError($_) } } Write-Verbose "(Video Data) $($Counters.Video.Imported) entries imported." if ($Counters.Video.Skipped -gt 0) { Write-Verbose "(Video Data) $($Counters.Video.Skipped) duplicate entries skipped." } if ($Counters.Video.Error -gt 0) { Write-Verbose "(Video Data) $($Counters.Video.Error) entries could not be parsed or conflicted with existing data." } } # Additional schema-dependent actions (ImportedSchema will only be > 0 in "General" ParameterSet so checking the set isn't needed) if ($ImportedSchema -ge 1) { # Process optional persistence formatting data if ($ImportStaging.config.psobject.Properties.Name -contains "_persist") { $script:PersistFormatting = [SXRPersistFormat]$ImportStaging.config._persist } } } End { if ($Persist -and ($NewKeyAdded -or ($IsGeneral -and $Counters.AllImported -gt 0))) { if (Get-EventSubscriber -SourceIdentifier XRefNewDataAdded -Force -ErrorAction Ignore) { [void] (New-Event -SourceIdentifier XRefNewDataAdded -Sender "Import-XRefData") } } if ($IsGeneral) { if ($ConflictingData) { Write-Warning "Some lookup data conflicts with existing values. Run with -Force to overwrite." } if ($MappingWarning) { Write-Warning "Some Clip -> User mapping data could not be imported or was missing." } if (-not $Quiet) { $Counters.Values | Format-Table -AutoSize | Out-Host } if ($PassThru) { return $Counters } } } } |