Skip to content

Instantly share code, notes, and snippets.

@midnightfreddie
Last active April 11, 2016 05:49
Show Gist options
  • Save midnightfreddie/106b8d3378ed545a0e8858fcf1fd053d to your computer and use it in GitHub Desktop.
Save midnightfreddie/106b8d3378ed545a0e8858fcf1fd053d to your computer and use it in GitHub Desktop.
# Get the weather
$wttr = Invoke-WebRequest http://wttr.in/
# Regex to match lines with no data in them, including blank lines and decorative borders
$RegExNoData = '^[ ─┌┬┤├┐┼└┴┘]*$'
# This is used to match the phase line and exclude it.
# Also used to create an array of weather data for each date
$PhasesOfDay = @("Morning", "Noon", "Evening", "Night")
# The $DataLine var will be the index used to define the hash key for the weather value
$WeatherKeys = @("Conditions", "Temperature", "Wind", "Visibility", "Precipitation")
$DateStringFormat = "m"
# Get the preformatted block(s)
$wttr.ParsedHtml.getElementsByTagName("pre") |
# Output as a sttream/array of text lines/rows with the extra CR removed from the end
ForEach-Object { $_.outerText.Split("`n").TrimEnd() } |
# Exlude blank and decorative-only lines
Where-Object { -not ($_ -match $RegExNoData ) } |
# Exclude lines listing the phases of the day
Where-Object { -not ($_ -match ($PhasesOfDay -join ".*") ) } |
ForEach-Object -Begin {
# Begin block initializes starting variables
# The first weather info is one cell across, so $Datum is only a single object
$Date = Get-Date
$City = $null
$Country = $null
$DataLine = 0
$Datum = New-Object psobject -Property ([ordered]@{
Date = $Date
DateString = Get-Date -Date $Date -Format $DateStringFormat
PhaseOfDay = "Current"
City = $City
Country = $Country
Weather = [ordered]@{}
})
} -Process {
# First line should be this; capture City and Country data
if ($_ -match "Weather for City") {
$City = $_.Split(':')[1].Split(',')[0].Trim()
$Country = $_.Split(':')[1].Split(',')[1].Trim()
$Datum | ForEach-Object {
$_.City = $City
$_.Country = $Country
}
# Don't process this block any further, start processing the next line
return
}
# Match the rows with the date
if ($_ -match '^┌[─┬]+┤.+├[─┬]+┐$') {
# Output $Datum which is complete
$Datum
# Parse the date
$Date = Get-Date -Date ($_.Split("┤├")[1].Trim())
# Reset variables
$DataLine = 0
# Create new Datum
$Datum = $PhasesOfDay | ForEach-Object {
New-Object psobject -Property ([ordered]@{
Date = $Date
DateString = Get-Date -Date $Date -Format $DateStringFormat
PhaseOfDay = $_
City = $City
Country = $Country
Weather = [ordered]@{}
})
}
# Don't process this block any further, start processing the next line
return
}
# Process each line of data. Every text row that reaches this point
# should be a line that matches one of the $WeatherKeys
$Index = 0
# Cleverness here: Splitting the line into an array using the vertical
# separator and removing empty entries so $Index of 0..3 are the 4 strings we want
# Or 0 is the one string if this is the "current" conditions at the top of the file
$_.Split('│', [StringSplitOptions]::RemoveEmptyEntries) | ForEach-Object {
# Use $Index to match to morning, noon, etc. Use $DataLine to
# track which weather value this is. Cut out the icon text and trim white space
$Datum[$Index].Weather[$WeatherKeys[$DataLine]] = $_.Substring(15).Trim()
$Index++
}
$DataLine++
} -End {
# Output the last Data
$Datum
} |
# Do something with data. I'm converting it to JSON because it's the
# easiest way for me to expand the Weather hash while developing.
ConvertTo-Json
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment