functions/SourceRegistry.ps1
|
# Custom Emoji Source Registry Functions function Register-EmojiSource { <# .SYNOPSIS Registers a custom emoji source for use with Update-EmojiDataset. .DESCRIPTION Adds a custom remote emoji source to the registry, allowing you to download datasets from your own URLs using Update-EmojiDataset -Source <Name>. .PARAMETER Name Unique name for the source (alphanumeric, hyphens, underscores only) .PARAMETER Url URL to the emoji dataset (must be HTTP or HTTPS) .PARAMETER Format Dataset format: CSV or JSON (auto-detected from URL if not specified) .PARAMETER Description Optional description of the source .EXAMPLE Register-EmojiSource -Name "CompanyEmojis" -Url "https://company.com/emojis.csv" Registers a custom source with automatic format detection .EXAMPLE Register-EmojiSource -Name "TeamData" -Url "https://internal.local/emojis.json" -Format JSON -Description "Team emoji collection" Registers a source with explicit format and description #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [ValidatePattern('^[a-zA-Z0-9_-]+$')] [ValidateLength(1, 50)] [string]$Name, [Parameter(Mandatory = $true)] [ValidateScript( { if ($_ -notmatch '^https?://') { throw "URL must be HTTP or HTTPS" } $true })] [string]$Url, [Parameter(Mandatory = $false)] [ValidateSet('CSV', 'JSON')] [string]$Format, [Parameter(Mandatory = $false)] [string]$Description ) # Get module data path $ModulePath = Split-Path -Parent (Split-Path -Parent $PSCommandPath) $sourcesPath = Join-Path $ModulePath "data\sources.json" # Check for built-in source name conflicts $builtInSources = @('Kaggle', 'Unicode', 'GitHub') if ($builtInSources -contains $Name) { Write-Error "Source name '$Name' conflicts with built-in source. Please choose a different name." return } # Auto-detect format from URL if not specified if (-not $Format) { if ($Url -match '\.csv($|\?)') { $Format = 'CSV' Write-Verbose "Auto-detected format: CSV" } elseif ($Url -match '\.json($|\?)') { $Format = 'JSON' Write-Verbose "Auto-detected format: JSON" } else { Write-Warning "Could not auto-detect format from URL. Defaulting to CSV." $Format = 'CSV' } } # Warn about insecure URLs if ($Url -match '^http://') { Write-Warning "Using insecure HTTP URL. Consider using HTTPS for security." } # Load existing sources or create new registry $registry = @{ version = "1.0" custom_sources = @() } if (Test-Path $sourcesPath) { try { $registry = Get-Content $sourcesPath -Raw | ConvertFrom-Json -AsHashtable } catch { Write-Warning "Could not load existing sources registry. Creating new one." } } # Check if source already exists $existingSource = $registry.custom_sources | Where-Object { $_.name -eq $Name } if ($existingSource) { # Duplicate registration is considered an error in tests; throw to allow callers to catch throw "Source '$Name' already exists. Use Unregister-EmojiSource first to replace it. Existing URL: $($existingSource.url)" } # Create new source entry $newSource = @{ name = $Name url = $Url format = $Format description = $Description added = (Get-Date).ToUniversalTime().ToString("o") last_used = $null update_count = 0 } # Add to registry $registry.custom_sources += $newSource # Save registry try { $registry | ConvertTo-Json -Depth 10 | Set-Content $sourcesPath -Encoding UTF8 Write-Host "✅ Successfully registered emoji source '$Name'" -ForegroundColor Green Write-Host " URL: $Url" -ForegroundColor Cyan Write-Host " Format: $Format" -ForegroundColor Cyan if ($Description) { Write-Host " Description: $Description" -ForegroundColor Cyan } Write-Host "`nUse: Update-EmojiDataset -Source '$Name'" -ForegroundColor Yellow } catch { Write-Error "Failed to save source registry: $_" } } function Unregister-EmojiSource { <# .SYNOPSIS Removes a custom emoji source from the registry. .DESCRIPTION Unregisters a previously registered custom emoji source. Built-in sources (Kaggle, Unicode, GitHub) cannot be removed. .PARAMETER Name Name of the source to remove .PARAMETER All Remove all custom sources .PARAMETER Force Skip confirmation prompt .EXAMPLE Unregister-EmojiSource -Name "CompanyEmojis" Removes the specified source with confirmation .EXAMPLE Unregister-EmojiSource -Name "CompanyEmojis" -Force Removes the source without confirmation .EXAMPLE Unregister-EmojiSource -All -Force Removes all custom sources without confirmation #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] param( [Parameter(Mandatory = $false, ParameterSetName = 'Single')] [string]$Name, [Parameter(Mandatory = $false, ParameterSetName = 'All')] [switch]$All, [Parameter(Mandatory = $false)] [switch]$Force ) # Get module data path $ModulePath = Split-Path -Parent (Split-Path -Parent $PSCommandPath) $sourcesPath = Join-Path $ModulePath "data\sources.json" if (-not (Test-Path $sourcesPath)) { if ($All) { Write-Warning "No custom sources registered." return } else { Write-Warning "Source '$Name' not found. No custom sources registered." return } } # Load registry try { $registry = Get-Content $sourcesPath -Raw | ConvertFrom-Json -AsHashtable } catch { Write-Error "Failed to load source registry: $_" return } if ($All) { # Remove all custom sources $count = $registry.custom_sources.Count if ($count -eq 0) { Write-Host "No custom sources to remove." -ForegroundColor Yellow return } if (-not $Force -and -not $PSCmdlet.ShouldProcess("$count custom source(s)", "Remove all")) { return } $registry.custom_sources = @() $registry | ConvertTo-Json -Depth 10 | Set-Content $sourcesPath -Encoding UTF8 Write-Host "✅ Removed $count custom source(s)" -ForegroundColor Green } else { # Remove specific source if (-not $Name) { Write-Error "Please specify -Name or use -All to remove all sources" return } $source = $registry.custom_sources | Where-Object { $_.name -eq $Name } if (-not $source) { Write-Warning "Source '$Name' not found in registry." Write-Host "`nAvailable sources:" -ForegroundColor Yellow Get-EmojiSource -CustomOnly return } if (-not $Force -and -not $PSCmdlet.ShouldProcess($Name, "Remove emoji source")) { return } $registry.custom_sources = @($registry.custom_sources | Where-Object { $_.name -ne $Name }) $registry | ConvertTo-Json -Depth 10 | Set-Content $sourcesPath -Encoding UTF8 Write-Host "✅ Removed emoji source '$Name'" -ForegroundColor Green Write-Host " URL: $($source.url)" -ForegroundColor Cyan } } function Get-EmojiSource { <# .SYNOPSIS Lists available emoji sources (built-in and custom). .DESCRIPTION Displays all emoji sources available for use with Update-EmojiDataset, including built-in sources (Kaggle, Unicode, GitHub) and custom registered sources. .PARAMETER Name Get details for a specific source .PARAMETER CustomOnly Show only custom registered sources .EXAMPLE Get-EmojiSource Lists all available sources .EXAMPLE Get-EmojiSource -Name "CompanyEmojis" Shows details for a specific source .EXAMPLE Get-EmojiSource -CustomOnly Lists only custom registered sources #> [CmdletBinding()] param( [Parameter(Mandatory = $false)] [string]$Name, [Parameter(Mandatory = $false)] [switch]$CustomOnly ) # Get module data path $ModulePath = Split-Path -Parent (Split-Path -Parent $PSCommandPath) $sourcesPath = Join-Path $ModulePath "data\sources.json" # Built-in sources $builtInSources = @( [PSCustomObject]@{ Name = 'Unicode' Type = 'Built-in' Format = 'JSON' Url = 'https://unicode.org/Public/emoji/latest/emoji-test.txt (+ CLDR annotations)' Description = 'Official Unicode CLDR emoji data (recommended)' }, [PSCustomObject]@{ Name = 'Kaggle' Type = 'Built-in' Format = 'CSV' Url = '(Requires Kaggle authentication)' Description = 'Kaggle emoji dataset' }, [PSCustomObject]@{ Name = 'GitHub' Type = 'Built-in' Format = 'JSON' Url = 'https://raw.githubusercontent.com/github/gemoji/master/db/emoji.json' Description = 'GitHub gemoji collection' } ) # Load custom sources $customSources = @() if (Test-Path $sourcesPath) { try { $registry = Get-Content $sourcesPath -Raw | ConvertFrom-Json $customSources = $registry.custom_sources | ForEach-Object { [PSCustomObject]@{ Name = $_.name Type = 'Custom' Format = $_.format Url = $_.url Description = $_.description Added = $_.added LastUsed = $_.last_used UpdateCount = $_.update_count } } } catch { Write-Warning "Could not load custom sources: $_" } } # Filter by name if specified if ($Name) { $source = $builtInSources | Where-Object { $_.Name -eq $Name } if (-not $source) { $source = $customSources | Where-Object { $_.Name -eq $Name } } if ($source) { return $source } else { Write-Warning "Source '$Name' not found." return } } # Return results if ($CustomOnly) { if ($customSources.Count -eq 0) { Write-Host "No custom sources registered." -ForegroundColor Yellow Write-Host "Use Register-EmojiSource to add custom sources." -ForegroundColor Cyan } return $customSources } else { $allSources = $builtInSources + $customSources return $allSources } } function Get-CustomEmojiSourceRegistry { <# .SYNOPSIS Internal helper function to load custom source registry. .DESCRIPTION Loads the custom emoji source registry from sources.json. Returns $null if no registry exists. #> [CmdletBinding()] param() $ModulePath = Split-Path -Parent (Split-Path -Parent $PSCommandPath) $sourcesPath = Join-Path $ModulePath "data\sources.json" if (-not (Test-Path $sourcesPath)) { return $null } try { $registry = Get-Content $sourcesPath -Raw | ConvertFrom-Json -AsHashtable return $registry } catch { Write-Warning "Failed to load source registry: $_" return $null } } function Update-CustomEmojiSourceUsage { <# .SYNOPSIS Internal helper function to update source usage statistics. .DESCRIPTION Updates the last_used timestamp and update_count for a custom source. #> [CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory = $true)] [string]$SourceName ) $ModulePath = Split-Path -Parent (Split-Path -Parent $PSCommandPath) $sourcesPath = Join-Path $ModulePath "data\sources.json" if (-not (Test-Path $sourcesPath)) { return } try { $registry = Get-Content $sourcesPath -Raw | ConvertFrom-Json -AsHashtable $source = $registry.custom_sources | Where-Object { $_.name -eq $SourceName } if ($source) { $source.last_used = (Get-Date).ToUniversalTime().ToString("o") $source.update_count += 1 $registry | ConvertTo-Json -Depth 10 | Set-Content $sourcesPath -Encoding UTF8 Write-Verbose "Updated usage stats for source '$SourceName'" } } catch { Write-Verbose "Failed to update source usage: $_" } } |