thomasr / goodtimes Goto Github PK
View Code? Open in Web Editor NEWA little time tracking script for Windows PowerShell
License: Apache License 2.0
A little time tracking script for Windows PowerShell
License: Apache License 2.0
Is it possible to enhance the code with the following example?
`# .SYNOPSIS
param (
[int]
[parameter(Position=0)]
[alias('l')]
$historyLength = 30,
[byte]
[validateRange(0, 24)]
[alias('h')]
$workinghours = 40 / 5,
[decimal]
[validateRange(0, 24)]
[alias('b')]
$lunchbreak = 1,
[byte]
[validateRange(1, 100)]
[alias('p')]
$precision = 4,
[string]
[ValidateScript({$_ -cnotmatch '[HhmsfFt]'})]
[alias('d')]
$dateFormat = 'ddd dd/MM/yyyy', # "/" ist Platzhalter für lokalisierten Trenner
[byte]
[validateRange(0, 1)]
[alias('j')]
$joinIntervals = 1,
[byte]
[validateRange(0, 255)]
[alias('m')]
$maxWorkingHours = 10
)
function getUptimeAttr($entry) {
$result = New-TimeSpan
if ($joinIntervals -eq 0) {
foreach ($interval in $entry) {
$result = $result.add($interval[1] - $interval[0])
}
} else {
$result = $entry[-1][-1] - $entry[0][0]
}
$result
}
function getIntervalAttr($entry) {
$result = @()
if ($joinIntervals -eq 0) {
foreach ($interval in $entry) {
$result += '{0:HH:mm}-{1:HH:mm}' -f $interval[0], $interval[1]
}
} else {
$result = '{0:HH:mm}-{1:HH:mm}' -f $entry[0][0], $entry[-1][-1]
}
$result -join ', '
}
function getBookingHoursAttr($interval) {
$netTime = $interval.totalHours - $lunchbreak
[math]::Round($netTime * $precision) / $precision
}
function getFlexTimeAttr($bookedHours) {
$delta = $bookedHours - $workinghours
$result = $delta.toString('+0.00;-0.00; 0.00')
if ($delta -eq 0) {
write $result, $null
} elseif ($delta -gt 0) {
write $result, 'darkgreen'
} else {
write $result, 'darkred'
}
}
function getLogAttrs($entry) {
$result = @{
uptime = getUptimeAttr $entry
intervals = getIntervalAttr $entry
}
$result.bookingHours = getBookingHoursAttr $result.uptime
$result.flexTime = getFlexTimeAttr $result.bookingHours
$result
}
function print($string, $color) {
if ($color) {
write-host -f $color -n $string
} else {
write-host -n $string
}
}
function println($string, $color) {
print ($string + "r
n") $color
}
function wait() {
if ($Host.Name -eq 'ConsoleHost') {
Write-Host 'Press any key to continue...'
$Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyUp') > $null
}
}
function isStartEvent($event) {
return ($event.ProviderName -eq 'Microsoft-Windows-Kernel-General' -and $event.ID -eq 12) -or
($event.ProviderName -eq 'Microsoft-Windows-Power-Troubleshooter' -and $event.ID -eq 1)
}
function isStopEvent($event) {
return ($event.ProviderName -eq 'Microsoft-Windows-Kernel-General' -and $event.ID -eq 13) -or
($event.ProviderName -eq 'Microsoft-Windows-Kernel-Power' -and $event.ID -eq 42)
}
$startTime = (get-date).addDays(-$historyLength)
$filters = (
@{
StartTime = $startTime
LogName = 'System'
ProviderName = 'Microsoft-Windows-Kernel-General'
ID = 12, 13
},
@{
StartTime = $startTime
LogName = 'System'
ProviderName = 'Microsoft-Windows-Kernel-Power'
ID = 42 # what else?
},
@{
StartTime = $startTime
LogName = 'System'
ProviderName = 'Microsoft-Windows-Power-Troubleshooter'
ID = 1
}
)
$events = Get-WinEvent -FilterHashtable $filters | select ID, TimeCreated, ProviderName
[Collections.ArrayList]$events = $events | sort TimeCreated
$log = New-Object Collections.ArrayList
:outer while ($events.count -ge 2) {
if ($log) {
# find the latest stop event
do {
if ($events.count -lt 2) {
# if there is only one stop event left, there can't be any more start event (e.g. when system log was cleared)
break outer
}
$end = $events[$events.count - 1]
$events.remove($end)
} while (-not (isStopEvent $end)) # consecutive start events. This may happen when the system crashes (power failure, etc.)
} else {
# add a fake shutdown event for this very moment
$end = @{TimeCreated = get-date}
}
# find the corresponding start event
do {
if ($events.count -lt 1) {
# no more events left
break outer
}
$start = $events[$events.count - 1]
$events.remove($start)
} while (-not (isStartEvent $start)) # not sure if there can indeed be consecutive stop events, but let's better be safe than sorry
# check if the current start/stop pair has occurred on the same day as the previous one
$last = $log[0]
$interval = ,($start.TimeCreated, $end.TimeCreated)
if ($last -and $start.TimeCreated.Date.equals($last[0][0].Date)) {
# combine uptimes
$log[0] = $interval + $last
} else {
# create new day
$log.insert(0, $interval)
}
}
$oldFgColor= $host.UI.RawUI.ForegroundColor
$host.UI.RawUI.ForegroundColor = 'gray'
$oldBgColor = $host.UI.RawUI.BackgroundColor
$host.UI.RawUI.BackgroundColor = 'black'
$screenWidth = $host.UI.RawUI.BufferSize.width
Write-Host ("{0,-$($screenWidth - 1)}" -f ' Datum Buchen Gleitzeit Uptime (incl. Pause)')
Write-Host ("{0,-$($screenWidth - 1)}" -f '------------- ------ --------- --------------------')
foreach ($entry in $log) {
$firstStart = $entry[0][0]
$dayOfWeek = ([int]$firstStart.dayOfWeek + 6) % 7
if ($dayOfWeek -lt $lastDayOfWeek) {
println ("{0,-$($screenWidth - 1)}" -f '-------------')
}
$dayFormatted = $firstStart.Date.toString($dateFormat)
if ($dayOfWeek -ge 5) {
Write-Host $dayFormatted -n -backgroundColor darkred -foregroundcolor gray
} else {
print $dayFormatted
}
$lastDayOfWeek = $dayOfWeek
$attrs = getLogAttrs($entry)
if ($attrs.bookingHours -gt $maxWorkingHours) {
print (' {0,5} ' -f
$attrs.bookingHours.toString('#0.00', [Globalization.CultureInfo]::getCultureInfo('de-DE'))
) red
} else {
print (' {0,5} ' -f
$attrs.bookingHours.toString('#0.00', [Globalization.CultureInfo]::getCultureInfo('de-DE'))
) cyan
}
print $attrs.flexTime[0] $attrs.flexTime[1]
print ("{0,6:#0}:{1:00} | {2,-$($screenWidth - 42)}" -f
$attrs.uptime.hours,
[Math]::Round($attrs.uptime.minutes + $attrs.uptime.seconds / 60),
$attrs.intervals) darkGray
Write-Host
}
$host.UI.RawUI.BackgroundColor = $oldBgColor
$host.UI.RawUI.ForegroundColor = $oldFgColor
wait`
sleep event: Kernel-Power #42
wakeup event: Power-Troubleshooter #1
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.