Last active
March 27, 2018 04:08
-
-
Save someshinyobject/d8087e22c4e5b0cc99bf4bc203ae1c41 to your computer and use it in GitHub Desktop.
A PowerShell Pomodoro Technique Implementation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Pomodoro Technique | |
Function New-PoshmodoroSession { | |
Param ( | |
[Parameter(Mandatory=$False)] | |
[HashTable]$Options = @{} | |
) | |
# Add in our notification runtimes | |
[Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] | Out-Null | |
[Windows.UI.Notifications.ToastNotification, Windows.UI.Notifications, ContentType = WindowsRuntime] | Out-Null | |
[Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime] | Out-Null | |
# When a user doesn't add something to options | |
$Defaults = @{ | |
BreakTime = 5 | |
RunTime = 25 | |
Intervals = 4 | |
} | |
# Where everything will be stored | |
$App = @{ | |
ID = "Poshmodoro" | |
CurrentInterval = 0 | |
ImageIcon = Join-Path -Path $PSScriptRoot -ChildPath "tomato.png" | |
} | |
# Iterate defaults and use options | |
$Defaults.GetEnumerator() | ForEach-Object { | |
$App[$_.Key] = $_.Value | |
If ($Options.Contains($_.Key)) { | |
$App[$_.Key] = $Options[$_.Key] | |
} | |
} | |
$App = New-Object -TypeName psobject -Property $App | |
Add-Member -InputObject $App -MemberType ScriptMethod -Name "Wind" -Value { | |
$OriginalTitle = $Host.UI.RawUI.WindowTitle | |
if ($this.CurrentInterval -lt $this.Intervals) { | |
$this.Notify("Work time", "OK! Get to work for " + $this.RunTime + " minute(s)") | |
$this.Wait($this.RunTime) | |
$this.CurrentInterval++ | |
} | |
elseif ($this.CurrentInterval -eq $this.Intervals) { | |
$this.Notify("Break Time", "Time to take a break for " + $this.BreakTime + " minute(s)") | |
Write-Host "You're in the middle of a break" | |
$this.Wait($this.BreakTime) | |
$this.CurrentInterval = 0 | |
} | |
$this.Notify("Time's up", "Wind the clock again to begin your next session!") | |
$Host.UI.RawUI.WindowTitle = $OriginalTitle | |
} | |
Add-Member -InputObject $App -MemberType ScriptMethod -Name "Wait" -Value { | |
Param ( | |
$WaitTime | |
) | |
$StopWatch = [System.Diagnostics.Stopwatch]::StartNew() | |
$ProgressBar = New-ProgressBarConstructor -Activity "Poshmodoro Session" -Steps ($WaitTime * 60) | |
while ([Math]::Floor($StopWatch.Elapsed.TotalMinutes) -lt $WaitTime) { | |
$CurrentMinutes = [Math]::Floor($StopWatch.Elapsed.TotalMinutes) | |
$CurrentSeconds = [Math]::Floor($StopWatch.Elapsed.Seconds) | |
$UpdateText = [String]::Format("Session Time: {0}:{1}", $CurrentMinutes, $CurrentSeconds) | |
$ProgressBar.Update($UpdateText).Activate() | |
$Host.UI.RawUI.WindowTitle = $UpdateText | |
Start-Sleep -Seconds 1 | |
} | |
} | |
Add-Member -InputObject $App -MemberType ScriptMethod -Name "Notify" -Value { | |
Param ( | |
[String]$Title, | |
[String]$Message | |
) | |
[XML]$ToastTemplate = New-Object System.Xml.XmlDocument | |
$Root = $ToastTemplate.CreateNode("element", "toast", $null) | |
$Visual = $ToastTemplate.CreateNode("element", "visual", $null) | |
$Binding = $ToastTemplate.CreateNode("element", "binding", $null) | |
$Binding.SetAttribute("template", "ToastGeneric") | |
$TitleText = $ToastTemplate.CreateNode("element", "text", $null) | |
$MessageText = $ToastTemplate.CreateNode("element", "text", $null) | |
$Icon = $ToastTemplate.CreateNode("element", "image", $null) | |
$Icon.SetAttribute("src", "file:///" + $this.ImageIcon) | |
$Icon.SetAttribute("id", 4) | |
$Icon.SetAttribute("placement", "appLogoOverride") | |
$Icon.SetAttribute("hint-crop", "circle") | |
$TitleText.SetAttribute("id", "1") | |
$MessageText.SetAttribute("id", "1") | |
$TitleText.InnerText = $Title | |
$MessageText.InnerText = $Message | |
$ToastTemplate.AppendChild($Root) | Out-Null | |
$Root.AppendChild($Visual) | Out-Null | |
$Visual.AppendChild($Binding) | Out-Null | |
$Binding.AppendChild($Icon) | Out-Null | |
$Binding.AppendChild($TitleText) | Out-Null | |
$Binding.AppendChild($MessageText) | Out-Null | |
$Xml = New-Object Windows.Data.Xml.Dom.XmlDocument | |
$Xml.LoadXml($ToastTemplate.OuterXml) | |
$Toast = New-Object Windows.UI.Notifications.ToastNotification $Xml | |
[Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($this.ID).Show($Toast) | |
} | |
return $App | |
} | |
Function New-ProgressBarConstructor { | |
<# | |
.SYNOPSIS | |
Simplifies the process for creating CLI progress bars | |
.DESCRIPTION | |
This function creates an object based progress bar for use in the CLI | |
when doing iterative processes. It helps track the various parameters | |
given to the Write-Progress CmdLet and gives OOP style control. | |
.PARAMETER Steps | |
The total number of steps for the life of the progress bar | |
.PARAMETER Activity | |
The overall activity name the progress bar is tracking | |
.EXAMPLE | |
New-ProgressBarConstructor -Activity "Tracking something" -Steps 5 | |
.OUTPUTS | |
A PSObject with attached properties and methods for working with the progress bar functionality | |
.NOTES | |
Within the object returned, you receive the following properties: | |
<pre> | |
CurrentStep - The current step for use in determining the PercentComplete | |
Steps - Assigns the total number of steps given as a parameter | |
Parameters - The parameters that will be passed to Write-Progress | |
Activity - The activity the progress bar is carrying, populated by the given parameter | |
ID - A random ID for the progress bar | |
Status - Am updateable text based status noting the current step | |
PercentComplete - A derived value used to increment the progres bar | |
</pre> | |
Within the object returned, you receive the following methods: | |
<pre> | |
Activate - Displays the progress bar | |
SetStatus - (param Status) - Sets the progress bar's status to the given parameter | |
SetCurrentStep - (param CurrentStep) - Set's the current step | |
SetPercentComplete - Uses internal properties to set the percent complete | |
Update - (param Status, CurrentStep) - Calls both SetStatus and SetCurrentStep | |
Close - Completes the progress bar | |
</pre> | |
All methods return themselves to allow for chaining so an example like the | |
following code will work: | |
$ProgressBar.Activate().Update("New Status", 3).Activate() | |
#> | |
Param ( | |
[Parameter(Mandatory=$True)]$Activity, | |
[Parameter(Mandatory=$True)]$Steps | |
) | |
$Properties = @{ | |
CurrentStep = 1 | |
Steps = $Steps | |
Parameters = @{ | |
Activity = $Activity | |
Id = Get-Random | |
Status = "" | |
PercentComplete = 0 | |
} | |
} | |
$Methods = @{ | |
Activate = { | |
$Params = $this.Parameters | |
Write-Progress @Params | |
} | |
SetStatus = { | |
Param ([String]$Status) | |
$This.Parameters.Status = $Status | |
return $this | |
} | |
SetCurrentStep = { | |
Param ([Int32]$CurrentStep) | |
$This.CurrentStep = $CurrentStep | |
return $this | |
} | |
SetPercentComplete = { | |
$this.Parameters.PercentComplete = ($this.CurrentStep / $this.Steps) * 100 | |
return $this | |
} | |
Update = { | |
Param ( | |
[String]$Status, | |
[Int32]$CurrentStep | |
) | |
$this.SetPercentComplete() | |
$this.SetStatus($Status) | |
If ($CurrentStep) { | |
$this.SetCurrentStep($CurrentStep) | |
} Else { | |
$this.SetCurrentStep($this.CurrentStep+1) | |
} | |
return $this | |
} | |
Close = { | |
$Params = $this.Parameters | |
Write-Progress @Params -Completed | |
} | |
} | |
$Object = New-Object -Property $Properties -TypeName PSObject | |
$Methods.GetEnumerator() | ForEach-Object { | |
$Object | Add-Member -MemberType ScriptMethod -Name $_.Key -Value $_.Value | |
} | |
return $Object | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment