Forked from chubin/Enable-wttr.in-for-PowerShell
Last active
August 16, 2023 12:46
-
-
Save 9999years/672f06ca425f90ef1f1c946804d1848e to your computer and use it in GitHub Desktop.
How to enable wttr.in in a PowerShell console
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
<# | |
.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