NewJiraMemo.ps1

#region help
<#
.SYNOPSIS
Creates a new Jira memo file for note-taking.
 
.DESCRIPTION
Creates a new Jira memo file for note-taking, and opens it in the default text editor.
The file is saved into a predefined location.
The file is pre-populated with card number, card subject, card URL and a timestamp.
 
.PARAMETER number
Jira card number (NV[R]-code).
 
.PARAMETER username
Jira API username.
 
.PARAMETER token
Jira API token.
 
.PARAMETER store
Path of Jira memo store location.
 
.EXAMPLE
New-JiraMemo -store "C:\Memos" -username "someone@acme.com" -token "P@ssword"
 
.EXAMPLE
New-JiraMemo -number 123456
 
.EXAMPLE
New-JiraMemo 123456
 
.EXAMPLE
Help New-JiraMemo -Full
 
.INPUTS
System.String
 
InputObject parameters are strings.
 
.OUTPUTS
External text file, eg C:\Memos\NV-2827.txt
 
.NOTES
FunctionName : New-JiraMemo
Created by : Alex Zakharov
Date Coded : 7/12/2021
 
.LINK
https://www.powershellgallery.com/packages/JiraTools/
#>

#endregion

function New-JiraMemo {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$false,
                   HelpMessage="Jira card number.",
                   Position=0,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [ValidatePattern('^NV[RB]?-\d\d\d\d$')]
        [string]$number,
        
        [Parameter(Mandatory=$false, HelpMessage="Jira API username.")] 
        [string]$username,
        
        [Parameter(Mandatory=$false, HelpMessage="Jira API token.")] 
        [string]$token,
        
        [Parameter(Mandatory=$false, HelpMessage="Jira memo store location.")] 
        [string]$store
    )
    BEGIN {
        $regpath = 'HKCU:\SOFTWARE\JiraTools'
        $api = 'https://smokeball.atlassian.net/rest/api/3/issue'
        $site = 'https://smokeball.atlassian.net/browse'
        $settingsChanged = $false

        if ($store) {
            SetSetting 'Store' $store
            $settingsChanged = $true
        }

        if ($username) {
            SetSetting 'Username' $username
            $settingsChanged = $true
        }

        if ($token) {
            SetSetting 'Token' $token $true
            $settingsChanged = $true
        }

        $username = GetSetting 'Username'
        $token = GetSetting 'Token' $true
        $store = GetSetting 'Store'
    }
    PROCESS {
        if ($settingsChanged) {
            DisplayMessage "Settings saved."
        }

        if ($number -and $username -and $token -and $store) {
            CreateOrOpenJiraMemo $number
        }
        elseif ($number) {
            DisplayMessage "Some settings are missing. Use the following command to add:"
            DisplayMessage "New-JiraMemo -store ""<path>"" -username ""<username>"" -token ""<token>"""
        }
        elseif (-not $settingsChanged) {
            try {
                $number = Get-Clipboard -Format "Text"
            }
            catch {
                $number = Read-Host -Prompt "Number"
            }

            if ($number) {
                CreateOrOpenJiraMemo $number
            }
        }
    }
    END {

    }
}

New-Alias -Name card -Value New-JiraMemo

#region Execution examples

#card
#card NV-28
#card NV-2868
#card -store "C:\Memos" -username "someone@acme.com" -token "P@ssword"
#card -token '$ecret'
#card -number NV-2870 -store "C:\Memos" -username "someone@acme.com" -token "P@ssword"
#card NV-2870 -store "C:\Memos" -username "someone@acme.com" -token "P@ssword"
#'NV-2868' | card
#'NV-2868','NV-2871','NV-2852' | card

#endregion


###############################################################################
# Helper functions
###############################################################################

function DisplayMessage($message) {
    Write-Output "$message"
}

function DownloadJiracard($cardURI) {
    $text = "$($username):$($token)"
    $headers = @{ Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($text)); }
    $card = Invoke-RestMethod -Uri $cardURI -Method Get -Headers $headers -ContentType "application/json"
    $card
}

function CreateOrOpenJiraMemo($number) {
    $file = "$store\$number.txt"
    $uri = "$api/$number" 
    $url = "$site/$number"
    $timestamp = Get-Date -Format "dddd dd/MM/yyyy HH:mm"

    try {
        if (-not (Test-Path -Path $file -PathType Leaf)) {
            $subject = (DownloadJiracard($uri)).fields.summary
            $title = "$number - $subject"
            $separator = "=" * ($title.Length + 10)

            $title | Out-File $file -Append
            $separator | Out-File $file -Append
            $url | Out-File $file -Append

            DisplayMessage "Jira memo file CREATED: $file"
        }
        else {
            DisplayMessage "Jira memo file OPENED: $file"
        }

        $separator = "`r`n" + "-" * $timestamp.Length

        $separator | Out-File $file -Append
        $timestamp | Out-File $file -Append

        Invoke-Item $file
    }
    catch {
        throw $_.Exception.Message
    }
}

function SetSetting($key, $value, $secure = $false)
{
    if (-not (Test-Path "$regpath")) {
        New-Item -Path $regpath  | Out-Null
    }

    if ($secure) {
        $value = $value | ConvertTo-SecureString -AsPlainText -Force | ConvertFrom-SecureString
    }

    New-ItemProperty -Path $regpath -Name $key -PropertyType String -Value $value -Force | Out-Null
}

function GetSetting($key, $secure = $false)
{
    if (Test-Path "$regpath") {
        $value = (Get-ItemProperty $regpath).$key
        if ($secure) {
            $secureValue = $value | ConvertTo-SecureString
            $value = [System.Net.NetworkCredential]::new("", $secureValue).Password
        }
        $value
    }
}