Skip to content

Instantly share code, notes, and snippets.

@someshinyobject
Last active March 27, 2018 04:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save someshinyobject/d8087e22c4e5b0cc99bf4bc203ae1c41 to your computer and use it in GitHub Desktop.
Save someshinyobject/d8087e22c4e5b0cc99bf4bc203ae1c41 to your computer and use it in GitHub Desktop.
A PowerShell Pomodoro Technique Implementation
#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