Skip to content

Instantly share code, notes, and snippets.

@colbytimm
Last active April 9, 2022 00:34
Show Gist options
  • Save colbytimm/799d6bc14a923871dbf5edd517064fe7 to your computer and use it in GitHub Desktop.
Save colbytimm/799d6bc14a923871dbf5edd517064fe7 to your computer and use it in GitHub Desktop.
using System;
using System.Globalization;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace Company.Function
{
public class Weather
{
private readonly string _urlSiteList;
private readonly string _urlCityBase;
public ParseUtils parseUtils = new ParseUtils();
/// <summary>
/// Fetch urls from app settings
/// </summary>
public Weather()
{
_urlSiteList = Environment.GetEnvironmentVariable("SiteListURL");
_urlCityBase = Environment.GetEnvironmentVariable("CityBaseURL");
}
/// <summary>
/// Get city weather call
/// </summary>
public CityWeather GetCityWeather(string cityName)
{
var cityList = GetSiteList().Where(c => c.CityName.ToLower() == cityName.ToLower());
if (cityList.Count() > 0)
{
return GetCityWeather(cityList.First().ProvinceCode, cityList.First().Code, Language.English.Code);
}
else
{
return null;
}
}
/// <summary>
/// Get weather based on city code and language code
/// </summary>
/// <param name="cityCode"></param>
/// <param name="languageCode"></param>
/// <returns></returns>
private CityWeather GetCityWeather(string provinceCode, string cityCode, string languageCode)
{
var weather = new Weather();
string url = $"{weather._urlCityBase}/{provinceCode}/{cityCode}_{languageCode}.xml";
IEnumerable<CityWeather> cityWeatherList = null;
try
{
XElement doc = XElement.Load(url);
IEnumerable<XElement> currentConditions = doc?.Descendants("currentConditions");
if (currentConditions.First().HasElements) cityWeatherList = from c in currentConditions
select new CityWeather()
{
Temperature = new Temperature()
{
Units = (string)c?.Element("temperature")?.Attribute("units"),
Value = parseUtils.TryParseDouble(c?.Element("temperature").Value)
},
RelativeHumidty = new RelativeHumidty()
{
Units = (string)c?.Element("relativeHumidity")?.Attribute("units"),
Value = parseUtils.TryParseDouble(c?.Element("relativeHumidity").Value)
},
Condition = c?.Element("condition")?.Value,
Visibility = new Visibility()
{
Units = (string)c?.Element("visibility")?.Attribute("units"),
Value = parseUtils.TryParseDouble(c?.Element("visibility").Value)
},
UtcObservationDateTime = new ObservationDateTime()
{
DateTime = parseUtils.TryParseDateTime(doc?.Descendants("currentConditions")?.Descendants("dateTime").Where(item => (string)item?.Attribute("zone") == "UTC")?.First()?.Element("timeStamp").Value, "yyyyMMddHHmmss"),
TimeZone = (string)doc?.Descendants("currentConditions")?.Descendants("dateTime").Where(item => (string)item?.Attribute("zone") == "UTC")?.First()?.Attribute("zone"),
UTCOffset = parseUtils.TryParseInt((string)doc?.Descendants("currentConditions")?.Descendants("dateTime").Where(item => (string)item?.Attribute("zone") == "UTC")?.First()?.Attribute("UTCOffset"))
},
LocalObservationDateTime = new ObservationDateTime()
{
DateTime = parseUtils.TryParseDateTime(doc?.Descendants("currentConditions")?.Descendants("dateTime").Where(item => (string)item?.Attribute("zone") != "UTC")?.First()?.Element("timeStamp").Value, "yyyyMMddHHmmss"),
TimeZone = (string)doc?.Descendants("currentConditions")?.Descendants("dateTime").Where(item => (string)item?.Attribute("zone") != "UTC")?.First()?.Attribute("zone"),
UTCOffset = parseUtils.TryParseInt((string)doc?.Descendants("currentConditions")?.Descendants("dateTime").Where(item => (string)item?.Attribute("zone") != "UTC")?.First()?.Attribute("UTCOffset"))
},
Dewpoint = new Dewpoint()
{
Units = (string)c?.Element("dewpoint")?.Attribute("units"),
Value = parseUtils.TryParseDouble(c?.Element("dewpoint").Value)
},
Pressure = new Pressure()
{
Units = (string)c?.Element("pressure")?.Attribute("units"),
Value = parseUtils.TryParseDouble(c?.Element("pressure").Value),
Tendency = (string)c?.Element("pressure")?.Attribute("tendency")
},
Wind = new Wind()
{
WindSpeed = new WindSpeed()
{
Units = (string)c?.Element("wind")?.Element("speed")?.Attribute("units"),
Value = parseUtils.TryParseDouble(c?.Element("wind")?.Element("speed").Value)
},
WindGust = new WindGust()
{
Units = (string)c?.Element("wind")?.Element("gust")?.Attribute("units"),
Value = parseUtils.TryParseDouble(c?.Element("wind")?.Element("gust").Value)
},
Direction = c?.Element("wind")?.Element("direction").Value,
Bearing = new Bearing()
{
Units = (string)c?.Element("wind")?.Element("bearing")?.Attribute("units"),
Value = parseUtils.TryParseDouble(c?.Element("wind")?.Element("bearing").Value)
}
}
};
return cityWeatherList?.First();
}
catch
{
Console.WriteLine($"City not found for city code {cityCode}");
}
return null;
}
/// <summary>
/// Get list of all cities and their identifier code and province code
/// </summary>
/// <returns></returns>
private IEnumerable<Site> GetSiteList()
{
var weather = new Weather();
string url = _urlSiteList;
XElement doc = XElement.Load(url);
IEnumerable<Site> sitesList = from s in doc?.Descendants("site")
select new Site()
{
Code = (string)s?.Attribute("code"),
CityName = s?.Element("nameEn").Value,
ProvinceCode = s?.Element("provinceCode").Value
};
return sitesList;
}
}
/// <summary>
/// Language code definitions
/// </summary>
public class Language
{
private Language(string value) { Code = value; }
public string Code { get; private set; }
public static Language English { get { return new Language("e"); } }
public static Language French { get { return new Language("f"); } }
}
/// <summary>
/// Province code definitions
/// </summary>
public class Province
{
private Province(string value) { Code = value; }
public string Code { get; private set; }
public static Province Alberta { get { return new Province("AB"); } }
public static Province BritishColumbia { get { return new Province("BC"); } }
public static Province Manitoba { get { return new Province("MB"); } }
public static Province NewBrunswick { get { return new Province("NB"); } }
public static Province NewfoundlandAndLabrador { get { return new Province("NL"); } }
public static Province NovaScotia { get { return new Province("NS"); } }
public static Province NorthwestTerritories { get { return new Province("NT"); } }
public static Province Nunavut { get { return new Province("NU"); } }
public static Province Ontario { get { return new Province("ON"); } }
public static Province PrinceEdwardIsland { get { return new Province("PE"); } }
public static Province Quebec { get { return new Province("QC"); } }
public static Province Saskatchewan { get { return new Province("SK"); } }
public static Province Yukon { get { return new Province("YT"); } }
}
/// <summary>
/// Parse utilities for null dummy value assignment
/// </summary>
public class ParseUtils
{
public DateTime TryParseDateTime(string value, string format)
{
DateTime result;
if (!DateTime.TryParseExact(value, format, null, DateTimeStyles.None, out result))
return new DateTime();
return result;
}
public Double TryParseDouble(string value)
{
Double result;
if (!Double.TryParse(value, out result))
return -1.0;
return result;
}
public int TryParseInt(string value)
{
int result;
if (!int.TryParse(value, out result))
return -1;
return result;
}
}
public class CityWeather
{
public Temperature Temperature { get; set; }
public RelativeHumidty RelativeHumidty { get; set; }
public string Condition { get; set; }
public Visibility Visibility { get; set; }
public ObservationDateTime UtcObservationDateTime { get; set; }
public ObservationDateTime LocalObservationDateTime { get; set; }
public Dewpoint Dewpoint { get; set; }
public Pressure Pressure { get; set; }
public Wind Wind { get; set; }
}
public class Temperature
{
public double Value { get; set; }
public string Units { get; set; }
}
public class RelativeHumidty
{
public double Value { get; set; }
public string Units { get; set; }
}
public class Visibility
{
public double Value { get; set; }
public string Units { get; set; }
}
public class ObservationDateTime
{
public DateTime DateTime { get; set; }
public string TimeZone { get; set; }
public int UTCOffset { get; set; }
}
public class Pressure
{
public double Value { get; set; }
public string Units { get; set; }
public string Tendency { get; set; }
}
public class Dewpoint
{
public double Value { get; set; }
public string Units { get; set; }
}
public class Wind
{
public WindSpeed WindSpeed { get; set; }
public WindGust WindGust { get; set; }
public string Direction { get; set; }
public Bearing Bearing { get; set; }
}
public class WindSpeed
{
public double Value { get; set; }
public string Units { get; set; }
}
public class WindGust
{
public double Value { get; set; }
public string Units { get; set; }
}
public class Bearing
{
public double Value { get; set; }
public string Units { get; set; }
}
public class Site
{
public string Code { get; set; }
public string CityName { get; set; }
public string ProvinceCode { get; set; }
public string Latitude { get; set; }
public string Longitude { get; set; }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment