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
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