PowerNotes.psm1
|
enum Priority { Low = 1 Medium = 2 High = 3 } class Note { [string] $ID [string] $Body [string] $Topic [datetime] $Date [Priority] $Priority Note([string] $Body, [string] $Topic, [Priority] $Priority) { $this.ID = [guid]::NewGuid().ToString() $this.Body = $Body $this.Topic = $Topic $this.Priority = $Priority $this.Date = (Get-Date) } Note([string] $Body, [string] $Topic) { $this.ID = [guid]::NewGuid().ToString() $this.Body = $Body $this.Topic = $Topic $this.Priority = [Priority]::Low $this.Date = (Get-Date) } Note([string] $Body) { $this.ID = [guid]::NewGuid().ToString() $this.Body = $Body $this.Topic = 'DailyNote' $this.Priority = [Priority]::Low $this.Date = (Get-Date) } Note([hashtable] $NoteParams) { $this.ID = [guid]::NewGuid().ToString() $this.Body = $NoteParams.Body $this.Topic = if ($NoteParams.ContainsKey('Topic') -and $NoteParams.Topic) { $NoteParams.Topic } else { 'DailyNote' } $this.Priority = if ($NoteParams.ContainsKey('Priority') -and $NoteParams.Priority) { $NoteParams.Priority } else { [Priority]::Low } $this.Date = (Get-Date) } [void] Print() { # Format: "MMM dd HH:mm:ss" e.g. "Sep 12 13:02:05" $timestamp = $this.Date.ToString('MMM-dd HH:mm:ss') $color = $null switch ($this.Priority) { 'Medium' { $color = 'Yellow' } 'High' { $color = 'Red' } default { $color = $null } } # Use colon as separator between topic and body Write-Host ('[{0}] {1}: ' -f $timestamp, $this.Topic) -NoNewline if ($color) { Write-Host $this.Body -ForegroundColor $color } else { Write-Host $this.Body } } } function Find-Note { [Alias('fpn')] [CmdletBinding()] param( [Parameter(Mandatory)] [string]$Text, [int] $Year = (Get-Date).Year, [int]$MaxCount ) $filePath = Get-NotesFile -Year $Year $ResultOut = [System.Collections.ArrayList]::new() if (-not (Test-Path $filePath)) { return $ResultOut # Quit, No file found } $rawData = Get-Content -Path $filePath if ([string]::IsNullOrWhiteSpace($rawData)) { return $ResultOut # Quit, No entires in the JSON } $rawData | ForEach-Object { $obj = $_ | ConvertFrom-Json $entry = [Note]::new(@{ Body = $obj.Body Topic = $obj.Topic Priority = [Priority]$($obj.Priority) }) $entry.ID = $obj.ID $entry.Date = [datetime]$obj.Date [void]$ResultOut.Add($entry) } $ResultOut = $ResultOut | Where-Object { $_.Body -like "*$Text*" } if ($MaxCount) { $ResultOut = $ResultOut | Select-Object -Last $MaxCount } return $ResultOut } function Get-Note { [Alias('gpn')] [CmdletBinding()] param( [int] $Year = (Get-Date).Year, [int] $Count = 10, [switch]$All, #TODO Yet to Implement LAST [ValidateSet('Week', 'Fortnight', 'Month', 'Quarter')] [string]$Last, $Topic ) $filePath = Get-NotesFile -Year $Year $ResultOut = [System.Collections.ArrayList]::new() if (-not (Test-Path $filePath)) { return $ResultOut # Quit, No file found } $rawData = Get-Content -Path $filePath if ([string]::IsNullOrWhiteSpace($rawData)) { return $ResultOut # Quit, No entires in the JSON } $rawData | ForEach-Object { $obj = $_ | ConvertFrom-Json $entry = [Note]::new(@{ Body = $obj.Body Topic = $obj.Topic Priority = [Priority]$($obj.Priority) }) $entry.ID = $obj.ID $entry.Date = [datetime]$obj.Date [void]$ResultOut.Add($entry) } if ($Last) { Write-Warning 'Feature not implemented : Last' } if ($Topic) { $ResultOut = $ResultOut | Where-Object { $_.Topic -like "*$topic*" } } if (-not $All) { $ResultOut = $ResultOut | Select-Object -Last $Count } return $ResultOut } function Get-NotesFile { param ( [int] $Year = (Get-Date).Year, [switch]$Create ) $baseDir = Get-NotesDir $fileName = "Notes-$Year.jsonl" $FullFilePath = Join-Path $baseDir $fileName if ($Create -and (-not (Test-Path $FullFilePath))) { New-Item $FullFilePath | Out-Null } return Join-Path $baseDir $fileName } function New-Note { [Alias('npn')] [CmdletBinding(SupportsShouldProcess = $true)] param ( [Parameter(Mandatory = $true)] [string] $Body, [string] $Topic = $null, [priority]$Priority = [priority]::Low ) $NoteParams = @{ Body = $Body } if ($null -ne $Topic) { $NoteParams['Topic'] = $Topic } $NoteParams['Priority'] = $Priority $NoteEntry = [Note]::new($NoteParams) if (-not $PSCmdlet.ShouldProcess($NoteEntry, 'Will write the note')) { return } Add-NoteEntryToFile -Note $NoteEntry return $NoteEntry } function Add-NoteEntryToFile { param( [Note] $Note, $Year = (Get-Date).Year ) $filePath = Get-NotesFile -Year $Year -Create $NoteValue = $Note | ConvertTo-Json -Compress $NoteValue = $NoteValue + "`n" try { [System.IO.File]::AppendAllText($filePath, $NoteValue, [Text.UTF8Encoding]::new($false)) } catch { Write-Error $_ } } function Get-NotesDir { if ($env:PowerNotesDir) { if (Test-Path -PathType Container -Path $env:PowerNotesDir) { $dir = $env:PowerNotesDir } } else { ## If environment is not set, assign default path based on OS if ($IsWindows) { $base = $env:APPDATA } elseif ($IsLinux -or $IsMacOS) { $base = $env:XDG_DATA_HOME if (-not $base) { if ($IsMacOS) { $base = Join-Path $HOME 'Library/Application Support' } else { $base = Join-Path $HOME '.local/share' } } } else { throw 'Unsupported OS' } $dir = Join-Path $base 'PowerNotes' } if (-not (Test-Path $dir)) { New-Item -ItemType Directory -Path $dir -Force | Out-Null } return $dir } |