Get-Cite.psm1

<#
.SYNOPSIS
Get a citation from API-Ninjas, some other sites/APIs may be added in the future.
 
.DESCRIPTION
This is a PowerShell script that allows you to get a citation from API-Ninjas.
 
-keyword (-k)
 
    Any of the following categories:
 
        "age",
        "alone",
        "amazing",
        "anger",
        "architecture",
        "art",
        "attitude",
        "beauty",
        "best",
        "birthday",
        "business",
        "car",
        "change",
        "communications",
        "computers",
        "cool",
        "courage",
        "dad",
        "dating",
        "death",
        "design",
        "dreams",
        "education",
        "environmental",
        "equality",
        "experience",
        "failure",
        "faith",
        "family",
        "famous",
        "fear",
        "fitness",
        "food",
        "forgiveness",
        "freedom",
        "friendship",
        "funny",
        "future",
        "god",
        "good",
        "government",
        "graduation",
        "great",
        "happiness",
        "health",
        "history",
        "home",
        "hope",
        "humor",
        "imagination",
        "inspirational",
        "intelligence",
        "jealousy",
        "knowledge",
        "leadership",
        "learning",
        "legal",
        "life",
        "love",
        "marriage",
        "medical",
        "men",
        "mom",
        "money",
        "morning",
        "movies",
        "success"
             
-clip (-c)
     
    Outputs the content to the clipboard
         
        Get-Cite -keyword alone -clip
 
 
-json (-j)
    
    Outputs the content to a json file with the corresponding category, saved to working directory if -out is not used.
     
    File will have default name 'Quotes - yyyy.mm.dd - HH-mm-ss.json' if none given.
 
        Get-Cite -json
 
-txt (-t)
    
    Outputs the content to a txt file with the corresponding category, saved to working directory if -out is not used.
     
    File will have default name 'Quotes - yyyy.mm.dd - HH-mm-ss.txt' if none given.
 
        Get-Cite -txt
 
-out (-o)
    
    Outputs the links to specified file or folder. Current working directory and default name will be used if not specified.
     
    Extensions other than json or txt will be adjusted automatically according to the parameters used.
 
        Get-Cite -keyword age -txt -out C:\MyQuotes.txt
 
-noexit (-n)
    
    Prompts the user for input before exiting.
 
        Get-Cite -keyword age -txt -out C:\MyQuotes.txt -noexit
 
.PARAMETER HELP
    Get-Help Get-Cite
 
.INPUTS
    string
 
.OUTPUTS
    clipboard, json, var, txt
 
.LINK
    https://www.powershellgallery.com/packages/Get-Cite/
#>

function Get-Cite {

    [CmdletBinding()]
    param (
        [ValidateNotNullOrEmpty()]
        [Switch]$help,
        [Parameter(Mandatory = $false)]
        [ValidateSet(
            'age',
            'alone',
            'amazing',
            'anger',
            'architecture',
            'art',
            'attitude',
            'beauty',
            'best',
            'birthday',
            'business',
            'car',
            'change',
            'communications',
            'computers',
            'cool',
            'courage',
            'dad',
            'dating',
            'death',
            'design',
            'dreams',
            'education',
            'environmental',
            'equality',
            'experience',
            'failure',
            'faith',
            'family',
            'famous',
            'fear',
            'fitness',
            'food',
            'forgiveness',
            'freedom',
            'friendship',
            'funny',
            'future',
            'god',
            'good',
            'government',
            'graduation',
            'great',
            'happiness',
            'health',
            'history',
            'home',
            'hope',
            'humor',
            'imagination',
            'inspirational',
            'intelligence',
            'jealousy',
            'knowledge',
            'leadership',
            'learning',
            'legal',
            'life',
            'love',
            'marriage',
            'medical',
            'men',
            'mom',
            'money',
            'morning',
            'movies',
            'success'
        )]
        [String[]]$keyword,
        [ValidateNotNullOrEmpty()]
        [Switch]$json,
        [ValidateNotNullOrEmpty()]
        [Switch]$txt,
        [ValidateNotNullOrEmpty()]
        [Switch]$clip,
        [validatenotnullorempty()]
        [supportswildcards()]
        [string]$out = $home,
        [ValidateNotNullOrEmpty()]
        [Switch]$noexit
    )

    if ($help) {
        get-help get-cite

        return

    }
    
    $baseurl = 'https://api-ninjas.com'
    $url = 'https://api.api-ninjas.com/v1/quotes?category='

    if (!($keyword)) {

        try {
            
            $r = invoke-webrequest -Uri "$url" -Headers @{
                'Origin' = $baseurl
            }                
            
            $scode = $r.statuscode;
        } catch {
            $scode = $_.exception.response.statuscode.value__;
        }
        
        $retrycount = 2;
        
        while ($retrycount--) {
          
            if($scode -eq 200){
                    
                break

            }

            write-host "Request failure $scode... Retrying" -foregroundcolor red;
            start-sleep -s 2; 
            
            $r = invoke-webrequest -Uri "$url" -Headers @{
                'Origin' = $baseurl
            }

        }

        if ($retrycount -eq 0 -and $scode -ne 200) {
            write-error "Request failed - Exceeded retries"  -foregroundcolor red;
            
            break
        }

        $quote = [pscustomobject]@{
            Category = ($r.content | convertfrom-json).category;
            Quote = ($r.content | convertfrom-json).quote;
        }

    } else {

        foreach ($k in $keyword) {
            write-progress -activity "Processing keyword $k" -status "$((($keyword.indexof($k) + 1) / $keyword.count) * 100)%" -percentcomplete $((($keyword.indexof($k) + 1) / $keyword.count) * 100);
  
            try {
                
                $r = invoke-webrequest -Uri "$url$k" -Headers @{
                    'Origin' = $baseurl         
                }

                $scode = $r.statuscode;
            } catch {
                $scode = $_.exception.response.statuscode.value__;
            }
            
            $retrycount = 2;
            
            while ($retrycount--) {
              
                if($scode -eq 200){
                        
                    break
    
                }
    
                write-error "Request failure $scode... Retrying" -foregroundcolor red;
                start-sleep -s 2; 
                
                $r = invoke-webrequest -Uri "$url$k" -Headers @{
                    'Origin' = $baseurl
                }
    
            }

            if ($retrycount -eq 0 -and $scode -ne 200) {
                write-error "Request failed - Exceeded retries"  -foregroundcolor red;
                
                break
            }

            if ($k -eq $keyword[0]) {
                $quote = @();
            }
    
            $quote += [pscustomobject]@{
                Category = $k;
                Quote = ($r.content | convertfrom-json).quote;
            }
    
            if ($keyword -gt 1 -and $k -ne $keyword[-1]) {
                start-sleep -s 2;
            }
    
        }

    }

    write-output $quote.quote
    $resolvedPath = Resolve-Path -Path $out -ErrorAction SilentlyContinue;

    while ($resolvedpath -eq $false) {
        $out = read-host Please enter a valid path;
        $resolvedPath = Resolve-Path -Path $out -ErrorAction SilentlyContinue;
    }

    if ([System.IO.Path]::GetExtension($out)) {

        if (split-path $out -parent) {
            $out = join-path (split-path $out -parent) (split-path $out -leafbase);
        } else {
            $out = split-path $out -leafbase;
        }
    } else {
        $out = (join-path $out ('Quotes - ' + (get-date -format "yyyy.mm.dd - HH-mm-ss")));
    }

    if ($json) {
        $result = $quote | convertto-json;

        if (test-path "$out.json" -pathtype leaf) {
            write-host 'Output file already exists!'
            new-item -path "$out.json" -value $result -confirm -force | out-null;
        } else {
            new-item -path "$out.json" -value $result -force | out-null;
        }
        
    }

    if ($txt) {

        if (test-path "$out.txt" -pathtype leaf) {
            write-host 'Output file already exists!'
            new-item -path "$out.txt" -confirm -force -value (($quote | format-list) | out-string).trim() | out-null;           
        } else {
            new-item -path "$out.txt" -force -value (($quote | format-list) | out-string).trim() | out-null; 
        }
        
    }

    if ($clip) {
        $quote.quote | set-clipboard;
    }

    if ($noexit) {
        read-host Press Enter;
    }

}