Skip to content

Instantly share code, notes, and snippets.

@9999years
Forked from chubin/Enable-wttr.in-for-PowerShell
Last active August 16, 2023 12:46
Show Gist options
  • Save 9999years/672f06ca425f90ef1f1c946804d1848e to your computer and use it in GitHub Desktop.
Save 9999years/672f06ca425f90ef1f1c946804d1848e to your computer and use it in GitHub Desktop.
How to enable wttr.in in a PowerShell console
<#
.DESCRIPTION
Fetches wttr.in for a terminal weather report.
.LINK
http://stknohg.hatenablog.jp/entry/2016/02/22/195644
.LINK
http://www.nivot.org/blog/post/2016/02/04/Windows-10-TH2-(v1511)-Console-Host-Enhancements
.LINK
https://gist.github.com/9999years/672f06ca425f90ef1f1c946804d1848e
.LINK
https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx
.LINK
https://msdn.microsoft.com/en-us/library/windows/desktop/mt638032(v=vs.85).aspx
.PARAMETER Location
The location to get weather from.
Can be "paris", "muc" (airport code), "@becca.ooo", "94107", or "moon" for the moon phase.
.PARAMETER Imperial
Aliased to "USCS".
Forces imperial units.
Units are normally auto-detected from the location.
If both -Metric and -Imperial are specified, metric units are used.
.PARAMETER Metric
Forces metric units.
Units are normally auto-detected from the location.
If both -Metric and -Imperial are specified, metric units are used.
.PARAMETER Simple
Non-colored output.
Normally, this function loads Kernel32.dll and changes the console mode to display the ANSI/VT100 color formatting sequences that wttr.in uses. -Simple fetches a text-only version and doesn't load any DLLs or anything.
Will prevent a slight delay on the first call per shell.
.PARAMETER Abbreviate
Only display the first few lines.
.PARAMETER Today
Only displays the weather for today.
.PARAMETER Tomorrow
Only displays the weather for tomorrow.
.PARAMETER DayAfterTomorrow
Only displays the weather for the day after tomorrow.
.EXAMPLE
PS>wttr nyc -Abbreviate
Weather for City: New York, United States of America
.-. Light Rain, Mist
( ). 66 °F
(___(__) ↖ 0 mph
‘ ‘ ‘ ‘ 3 mi
‘ ‘ ‘ ‘ 0.0 in
.EXAMPLE
PS>"nyc", "london" | Get-Weather -Metric -Abbreviate #Why would you ever do this? You don't need to do this. But you can, I guess.
Weather for City: New York, United States of America
.-. Light Rain, Mist
( ). 66 °F
(___(__) ↖ 0 mph
‘ ‘ ‘ ‘ 3 mi
‘ ‘ ‘ ‘ 0.0 in
Weather for City: London, United Kingdom
Mist
_ - _ - _ - 57 °F
_ - _ - _ ↘ 4 mph
_ - _ - _ - 2 mi
0.0 in
#>
function Get-Weather {
[CmdletBinding()]
Param(
[Parameter(
ValueFromPipeline = $True,
ValueFromRemainingArguments = $True
)]
[String]$Location,
[Switch]$Metric,
[Alias("USCS")]
[Switch]$Imperial,
[Switch]$Simple,
[Switch]$Abbreviate,
[Switch]$Resize,
[Switch]$Today,
[Switch]$Tomorrow,
[Switch]$DayAfterTomorrow
)
Begin{
If($Metric)
{
$Location += "?m"
}
ElseIf($Imperial)
{
$Location += "?u"
}
If($Resize)
{
#Resize the window/buffer to prevent weird output
function ResizeWindow {
$HostUI = (Get-Host).UI.RawUI
If($HostUI.BufferSize.Width -lt 126)
{
$HostUI.BufferSize = @{
Width = 126
Height = $HostUI.BufferSize.Height
}
}
If($HostUI.WindowSize.Width -lt 126)
{
$HostUI.WindowSize = @{
Width = 126
Height = $HostUI.WindowSize.Height
}
}
}
Try { ResizeWindow } Catch { ResizeWindow }
}
}
Process {
If($Simple)
{
#Just echo the content, nothing special
$Output = (Invoke-WebRequest -Uri "http://wttr.in/").ParsedHtml.Body.FirstChild.OuterText
}
Else
{
Try
{
#Enable ANSI sequences:
#http://stknohg.hatenablog.jp/entry/2016/02/22/195644
Add-Type -MemberDefinition @"
[DllImport("kernel32.dll", SetLastError=true)]
public static extern bool SetConsoleMode(IntPtr hConsoleHandle, int mode);
[DllImport("kernel32.dll", SetLastError=true)]
public static extern IntPtr GetStdHandle(int handle);
[DllImport("kernel32.dll", SetLastError=true)]
public static extern bool GetConsoleMode(IntPtr handle, out int mode);
"@ -Namespace Win32 -Name NativeMethods
#This doesn't do anything if the type is already added, so don't worry
#about doing this every single time, I guess
$Handle = [Win32.NativeMethods]::GetStdHandle(-11)
$Mode = 0
$Result = [Win32.NativeMethods]::GetConsoleMode($Handle, [ref]$Mode)
$Mode = $Mode -bor 4 # flag to enable ANSI/VT100 sequences
# https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx
# https://msdn.microsoft.com/en-us/library/windows/desktop/mt638032(v=vs.85).aspx
$Result = [Win32.NativeMethods]::SetConsoleMode($Handle, $Mode)
} Catch {}
$Output = (Invoke-WebRequest "http://wttr.in/$Location" -UserAgent "curl").Content
}
$Split = ($Output -Split "`n")
If($Abbreviate)
{
#Split linewise and select lines 0 through 6
$Split[0..6] | Write-Output
}
ElseIf($Today)
{
$Split[7..16] | Write-Output
}
ElseIf($Tomorrow)
{
$Split[17..26] | Write-Output
}
ElseIf($DayAfterTomorrow)
{
$Split[27..36] | Write-Output
}
Else
{
$Output | Write-Output
}
}
}
#ErrorAction in case this file is dot-sourced twice, to prevent annoying
#"Alias already exists" error
New-Alias wttr Get-Weather -ErrorAction SilentlyContinue
New-Alias wttr.in Get-Weather -ErrorAction SilentlyContinue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment