From ae4ffa75be378497d8db210c6864cde40f7c75f9 Mon Sep 17 00:00:00 2001 From: LukePulverenti Date: Thu, 21 Feb 2013 01:02:10 -0500 Subject: isolated weather and moved drawing classes up to the controller project --- MediaBrowser.Controller/Drawing/ImageExtensions.cs | 199 +++++++++++++ MediaBrowser.Controller/Drawing/ImageHeader.cs | 216 ++++++++++++++ MediaBrowser.Controller/Drawing/ImageManager.cs | 4 +- MediaBrowser.Controller/Kernel.cs | 4 +- .../MediaBrowser.Controller.csproj | 5 +- .../Plugins/PluginSecurityManager.cs | 39 ++- .../Weather/BaseWeatherProvider.cs | 37 --- .../Weather/IWeatherProvider.cs | 20 ++ MediaBrowser.Controller/Weather/WeatherProvider.cs | 311 --------------------- 9 files changed, 479 insertions(+), 356 deletions(-) create mode 100644 MediaBrowser.Controller/Drawing/ImageExtensions.cs create mode 100644 MediaBrowser.Controller/Drawing/ImageHeader.cs delete mode 100644 MediaBrowser.Controller/Weather/BaseWeatherProvider.cs create mode 100644 MediaBrowser.Controller/Weather/IWeatherProvider.cs delete mode 100644 MediaBrowser.Controller/Weather/WeatherProvider.cs (limited to 'MediaBrowser.Controller') diff --git a/MediaBrowser.Controller/Drawing/ImageExtensions.cs b/MediaBrowser.Controller/Drawing/ImageExtensions.cs new file mode 100644 index 0000000000..cecbfe74aa --- /dev/null +++ b/MediaBrowser.Controller/Drawing/ImageExtensions.cs @@ -0,0 +1,199 @@ +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Imaging; +using System.IO; +using System.Linq; + +namespace MediaBrowser.Controller.Drawing +{ + /// + /// Class ImageExtensions + /// + public static class ImageExtensions + { + /// + /// Saves the image. + /// + /// The output format. + /// The image. + /// To stream. + /// The quality. + public static void Save(this Image image, ImageFormat outputFormat, Stream toStream, int quality) + { + // Use special save methods for jpeg and png that will result in a much higher quality image + // All other formats use the generic Image.Save + if (ImageFormat.Jpeg.Equals(outputFormat)) + { + SaveAsJpeg(image, toStream, quality); + } + else if (ImageFormat.Png.Equals(outputFormat)) + { + image.Save(toStream, ImageFormat.Png); + } + else + { + image.Save(toStream, outputFormat); + } + } + + /// + /// Saves the JPEG. + /// + /// The image. + /// The target. + /// The quality. + public static void SaveAsJpeg(this Image image, Stream target, int quality) + { + using (var encoderParameters = new EncoderParameters(1)) + { + encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, quality); + image.Save(target, GetImageCodecInfo("image/jpeg"), encoderParameters); + } + } + + /// + /// Gets the image codec info. + /// + /// Type of the MIME. + /// ImageCodecInfo. + private static ImageCodecInfo GetImageCodecInfo(string mimeType) + { + var encoders = ImageCodecInfo.GetImageEncoders(); + + return encoders.FirstOrDefault(i => i.MimeType.Equals(mimeType, StringComparison.OrdinalIgnoreCase)) ?? encoders.FirstOrDefault(); + } + + /// + /// Crops an image by removing whitespace and transparency from the edges + /// + /// The BMP. + /// Bitmap. + /// + public static Bitmap CropWhitespace(this Bitmap bmp) + { + var width = bmp.Width; + var height = bmp.Height; + + var topmost = 0; + for (int row = 0; row < height; ++row) + { + if (IsAllWhiteRow(bmp, row, width)) + topmost = row; + else break; + } + + int bottommost = 0; + for (int row = height - 1; row >= 0; --row) + { + if (IsAllWhiteRow(bmp, row, width)) + bottommost = row; + else break; + } + + int leftmost = 0, rightmost = 0; + for (int col = 0; col < width; ++col) + { + if (IsAllWhiteColumn(bmp, col, height)) + leftmost = col; + else + break; + } + + for (int col = width - 1; col >= 0; --col) + { + if (IsAllWhiteColumn(bmp, col, height)) + rightmost = col; + else + break; + } + + if (rightmost == 0) rightmost = width; // As reached left + if (bottommost == 0) bottommost = height; // As reached top. + + var croppedWidth = rightmost - leftmost; + var croppedHeight = bottommost - topmost; + + if (croppedWidth == 0) // No border on left or right + { + leftmost = 0; + croppedWidth = width; + } + + if (croppedHeight == 0) // No border on top or bottom + { + topmost = 0; + croppedHeight = height; + } + + // Graphics.FromImage will throw an exception if the PixelFormat is Indexed, so we need to handle that here + var thumbnail = bmp.PixelFormat.HasFlag(PixelFormat.Indexed) ? new Bitmap(croppedWidth, croppedHeight) : new Bitmap(croppedWidth, croppedHeight, bmp.PixelFormat); + + // Preserve the original resolution + thumbnail.SetResolution(bmp.HorizontalResolution, bmp.VerticalResolution); + + using (var thumbnailGraph = Graphics.FromImage(thumbnail)) + { + thumbnailGraph.CompositingQuality = CompositingQuality.HighQuality; + thumbnailGraph.SmoothingMode = SmoothingMode.HighQuality; + thumbnailGraph.InterpolationMode = InterpolationMode.HighQualityBicubic; + thumbnailGraph.PixelOffsetMode = PixelOffsetMode.HighQuality; + thumbnailGraph.CompositingMode = CompositingMode.SourceOver; + + thumbnailGraph.DrawImage(bmp, + new RectangleF(0, 0, croppedWidth, croppedHeight), + new RectangleF(leftmost, topmost, croppedWidth, croppedHeight), + GraphicsUnit.Pixel); + } + return thumbnail; + } + + /// + /// Determines whether or not a row of pixels is all whitespace + /// + /// The BMP. + /// The row. + /// The width. + /// true if [is all white row] [the specified BMP]; otherwise, false. + private static bool IsAllWhiteRow(Bitmap bmp, int row, int width) + { + for (var i = 0; i < width; ++i) + { + if (!IsWhiteSpace(bmp.GetPixel(i, row))) + { + return false; + } + } + return true; + } + + /// + /// Determines whether or not a column of pixels is all whitespace + /// + /// The BMP. + /// The col. + /// The height. + /// true if [is all white column] [the specified BMP]; otherwise, false. + private static bool IsAllWhiteColumn(Bitmap bmp, int col, int height) + { + for (var i = 0; i < height; ++i) + { + if (!IsWhiteSpace(bmp.GetPixel(col, i))) + { + return false; + } + } + return true; + } + + /// + /// Determines if a color is whitespace + /// + /// The color. + /// true if [is white space] [the specified color]; otherwise, false. + private static bool IsWhiteSpace(Color color) + { + return (color.R == 255 && color.G == 255 && color.B == 255) || color.A == 0; + } + } +} diff --git a/MediaBrowser.Controller/Drawing/ImageHeader.cs b/MediaBrowser.Controller/Drawing/ImageHeader.cs new file mode 100644 index 0000000000..7cc63eee9f --- /dev/null +++ b/MediaBrowser.Controller/Drawing/ImageHeader.cs @@ -0,0 +1,216 @@ +using MediaBrowser.Common.Logging; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.Linq; + +namespace MediaBrowser.Controller.Drawing +{ + /// + /// Taken from http://stackoverflow.com/questions/111345/getting-image-dimensions-without-reading-the-entire-file/111349 + /// http://www.codeproject.com/Articles/35978/Reading-Image-Headers-to-Get-Width-and-Height + /// Minor improvements including supporting unsigned 16-bit integers when decoding Jfif and added logic + /// to load the image using new Bitmap if reading the headers fails + /// + public static class ImageHeader + { + /// + /// The error message + /// + const string errorMessage = "Could not recognize image format."; + + /// + /// The image format decoders + /// + private static readonly Dictionary> imageFormatDecoders = new Dictionary> + { + { new byte[] { 0x42, 0x4D }, DecodeBitmap }, + { new byte[] { 0x47, 0x49, 0x46, 0x38, 0x37, 0x61 }, DecodeGif }, + { new byte[] { 0x47, 0x49, 0x46, 0x38, 0x39, 0x61 }, DecodeGif }, + { new byte[] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }, DecodePng }, + { new byte[] { 0xff, 0xd8 }, DecodeJfif }, + }; + + /// + /// Gets the dimensions of an image. + /// + /// The path of the image to get the dimensions of. + /// The dimensions of the specified image. + /// The image was of an unrecognised format. + public static Size GetDimensions(string path) + { + try + { + using (var fs = File.OpenRead(path)) + { + using (var binaryReader = new BinaryReader(fs)) + { + return GetDimensions(binaryReader); + } + } + } + catch + { + Logger.LogInfo("Failed to read image header for {0}. Doing it the slow way.", path); + + using (var fs = File.OpenRead(path)) + { + // Co it the old fashioned way + using (var b = Image.FromStream(fs, true, false)) + { + return b.Size; + } + } + } + } + + /// + /// Gets the dimensions of an image. + /// + /// The binary reader. + /// Size. + /// binaryReader + /// The image was of an unrecognized format. + private static Size GetDimensions(BinaryReader binaryReader) + { + int maxMagicBytesLength = imageFormatDecoders.Keys.OrderByDescending(x => x.Length).First().Length; + var magicBytes = new byte[maxMagicBytesLength]; + for (int i = 0; i < maxMagicBytesLength; i += 1) + { + magicBytes[i] = binaryReader.ReadByte(); + foreach (var kvPair in imageFormatDecoders) + { + if (StartsWith(magicBytes, kvPair.Key)) + { + return kvPair.Value(binaryReader); + } + } + } + + throw new ArgumentException(errorMessage, "binaryReader"); + } + + /// + /// Startses the with. + /// + /// The this bytes. + /// The that bytes. + /// true if XXXX, false otherwise + private static bool StartsWith(byte[] thisBytes, byte[] thatBytes) + { + for (int i = 0; i < thatBytes.Length; i += 1) + { + if (thisBytes[i] != thatBytes[i]) + { + return false; + } + } + + return true; + } + + /// + /// Reads the little endian int16. + /// + /// The binary reader. + /// System.Int16. + private static short ReadLittleEndianInt16(BinaryReader binaryReader) + { + var bytes = new byte[sizeof(short)]; + + for (int i = 0; i < sizeof(short); i += 1) + { + bytes[sizeof(short) - 1 - i] = binaryReader.ReadByte(); + } + return BitConverter.ToInt16(bytes, 0); + } + + /// + /// Reads the little endian int32. + /// + /// The binary reader. + /// System.Int32. + private static int ReadLittleEndianInt32(BinaryReader binaryReader) + { + var bytes = new byte[sizeof(int)]; + for (int i = 0; i < sizeof(int); i += 1) + { + bytes[sizeof(int) - 1 - i] = binaryReader.ReadByte(); + } + return BitConverter.ToInt32(bytes, 0); + } + + /// + /// Decodes the bitmap. + /// + /// The binary reader. + /// Size. + private static Size DecodeBitmap(BinaryReader binaryReader) + { + binaryReader.ReadBytes(16); + int width = binaryReader.ReadInt32(); + int height = binaryReader.ReadInt32(); + return new Size(width, height); + } + + /// + /// Decodes the GIF. + /// + /// The binary reader. + /// Size. + private static Size DecodeGif(BinaryReader binaryReader) + { + int width = binaryReader.ReadInt16(); + int height = binaryReader.ReadInt16(); + return new Size(width, height); + } + + /// + /// Decodes the PNG. + /// + /// The binary reader. + /// Size. + private static Size DecodePng(BinaryReader binaryReader) + { + binaryReader.ReadBytes(8); + int width = ReadLittleEndianInt32(binaryReader); + int height = ReadLittleEndianInt32(binaryReader); + return new Size(width, height); + } + + /// + /// Decodes the jfif. + /// + /// The binary reader. + /// Size. + /// + private static Size DecodeJfif(BinaryReader binaryReader) + { + while (binaryReader.ReadByte() == 0xff) + { + byte marker = binaryReader.ReadByte(); + short chunkLength = ReadLittleEndianInt16(binaryReader); + if (marker == 0xc0) + { + binaryReader.ReadByte(); + int height = ReadLittleEndianInt16(binaryReader); + int width = ReadLittleEndianInt16(binaryReader); + return new Size(width, height); + } + + if (chunkLength < 0) + { + var uchunkLength = (ushort)chunkLength; + binaryReader.ReadBytes(uchunkLength - 2); + } + else + { + binaryReader.ReadBytes(chunkLength - 2); + } + } + + throw new ArgumentException(errorMessage); + } + } +} diff --git a/MediaBrowser.Controller/Drawing/ImageManager.cs b/MediaBrowser.Controller/Drawing/ImageManager.cs index b493a97afe..6dd641cba6 100644 --- a/MediaBrowser.Controller/Drawing/ImageManager.cs +++ b/MediaBrowser.Controller/Drawing/ImageManager.cs @@ -1,10 +1,8 @@ -using MediaBrowser.Common.Drawing; -using MediaBrowser.Common.Extensions; +using MediaBrowser.Common.Extensions; using MediaBrowser.Common.IO; using MediaBrowser.Common.Kernel; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.TV; -using MediaBrowser.Controller.Persistence; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Drawing; using MediaBrowser.Model.Entities; diff --git a/MediaBrowser.Controller/Kernel.cs b/MediaBrowser.Controller/Kernel.cs index 22c241fd4f..f8f48d8de9 100644 --- a/MediaBrowser.Controller/Kernel.cs +++ b/MediaBrowser.Controller/Kernel.cs @@ -192,8 +192,8 @@ namespace MediaBrowser.Controller /// Gets the list of currently registered weather prvoiders /// /// The weather providers. - [ImportMany(typeof(BaseWeatherProvider))] - public IEnumerable WeatherProviders { get; private set; } + [ImportMany(typeof(IWeatherProvider))] + public IEnumerable WeatherProviders { get; private set; } /// /// Gets the list of currently registered metadata prvoiders diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index f911f190df..da2bc23e81 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -76,6 +76,8 @@ + + @@ -197,8 +199,7 @@ - - + diff --git a/MediaBrowser.Controller/Plugins/PluginSecurityManager.cs b/MediaBrowser.Controller/Plugins/PluginSecurityManager.cs index 341e3582bb..5dbd6cbc62 100644 --- a/MediaBrowser.Controller/Plugins/PluginSecurityManager.cs +++ b/MediaBrowser.Controller/Plugins/PluginSecurityManager.cs @@ -6,12 +6,28 @@ using System.Threading.Tasks; namespace MediaBrowser.Controller.Plugins { + /// + /// Class PluginSecurityManager + /// public class PluginSecurityManager : BaseManager { + /// + /// The _is MB supporter + /// private bool? _isMBSupporter; + /// + /// The _is MB supporter initialized + /// private bool _isMBSupporterInitialized; + /// + /// The _is MB supporter sync lock + /// private object _isMBSupporterSyncLock = new object(); - + + /// + /// Gets a value indicating whether this instance is MB supporter. + /// + /// true if this instance is MB supporter; otherwise, false. public bool IsMBSupporter { get @@ -21,15 +37,29 @@ namespace MediaBrowser.Controller.Plugins } } + /// + /// Initializes a new instance of the class. + /// + /// The kernel. public PluginSecurityManager(Kernel kernel) : base(kernel) { } + /// + /// Gets the registration status. + /// + /// The feature. + /// The MB2 equivalent. + /// Task{MBRegistrationRecord}. public async Task GetRegistrationStatus(string feature, string mb2Equivalent = null) { return await MBRegistration.GetRegistrationStatus(feature, mb2Equivalent).ConfigureAwait(false); } + /// + /// Gets or sets the supporter key. + /// + /// The supporter key. public string SupporterKey { get { return MBRegistration.SupporterKey; } @@ -46,6 +76,10 @@ namespace MediaBrowser.Controller.Plugins } } + /// + /// Gets or sets the legacy key. + /// + /// The legacy key. public string LegacyKey { get { return MBRegistration.LegacyKey; } @@ -56,6 +90,9 @@ namespace MediaBrowser.Controller.Plugins } } + /// + /// Resets the supporter info. + /// private void ResetSupporterInfo() { _isMBSupporter = null; diff --git a/MediaBrowser.Controller/Weather/BaseWeatherProvider.cs b/MediaBrowser.Controller/Weather/BaseWeatherProvider.cs deleted file mode 100644 index 4ae7a3991c..0000000000 --- a/MediaBrowser.Controller/Weather/BaseWeatherProvider.cs +++ /dev/null @@ -1,37 +0,0 @@ -using MediaBrowser.Model.Weather; -using System; -using System.Threading; -using System.Threading.Tasks; - -namespace MediaBrowser.Controller.Weather -{ - /// - /// Class BaseWeatherProvider - /// - public abstract class BaseWeatherProvider : IDisposable - { - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - /// - /// Releases unmanaged and - optionally - managed resources. - /// - /// true to release both managed and unmanaged resources; false to release only unmanaged resources. - protected virtual void Dispose(bool dispose) - { - } - - /// - /// Gets the weather info async. - /// - /// The location. - /// Task{WeatherInfo}. - public abstract Task GetWeatherInfoAsync(string location, CancellationToken cancellationToken); - } -} diff --git a/MediaBrowser.Controller/Weather/IWeatherProvider.cs b/MediaBrowser.Controller/Weather/IWeatherProvider.cs new file mode 100644 index 0000000000..9060e5b9cd --- /dev/null +++ b/MediaBrowser.Controller/Weather/IWeatherProvider.cs @@ -0,0 +1,20 @@ +using MediaBrowser.Model.Weather; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Controller.Weather +{ + /// + /// Interface IWeatherProvider + /// + public interface IWeatherProvider + { + /// + /// Gets the weather info async. + /// + /// The location. + /// The cancellation token. + /// Task{WeatherInfo}. + Task GetWeatherInfoAsync(string location, CancellationToken cancellationToken); + } +} diff --git a/MediaBrowser.Controller/Weather/WeatherProvider.cs b/MediaBrowser.Controller/Weather/WeatherProvider.cs deleted file mode 100644 index 1560aa92c6..0000000000 --- a/MediaBrowser.Controller/Weather/WeatherProvider.cs +++ /dev/null @@ -1,311 +0,0 @@ -using MediaBrowser.Common.Logging; -using MediaBrowser.Common.Serialization; -using MediaBrowser.Model.Weather; -using System; -using System.ComponentModel.Composition; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; - -namespace MediaBrowser.Controller.Weather -{ - /// - /// Based on http://www.worldweatheronline.com/free-weather-feed.aspx - /// The classes in this file are a reproduction of the json output, which will then be converted to our weather model classes - /// - [Export(typeof(BaseWeatherProvider))] - public class WeatherProvider : BaseWeatherProvider - { - /// - /// The _weather semaphore - /// - private readonly SemaphoreSlim _weatherSemaphore = new SemaphoreSlim(10, 10); - - /// - /// Gets the weather info async. - /// - /// The location. - /// The cancellation token. - /// Task{WeatherInfo}. - /// location - public override async Task GetWeatherInfoAsync(string location, CancellationToken cancellationToken) - { - if (string.IsNullOrWhiteSpace(location)) - { - throw new ArgumentNullException("location"); - } - - if (cancellationToken == null) - { - throw new ArgumentNullException("cancellationToken"); - } - - const int numDays = 5; - const string apiKey = "24902f60f1231941120109"; - - var url = "http://free.worldweatheronline.com/feed/weather.ashx?q=" + location + "&format=json&num_of_days=" + numDays + "&key=" + apiKey; - - Logger.LogInfo("Accessing weather from " + url); - - using (var stream = await Kernel.Instance.HttpManager.Get(url, _weatherSemaphore, cancellationToken).ConfigureAwait(false)) - { - var data = JsonSerializer.DeserializeFromStream(stream).data; - - return GetWeatherInfo(data); - } - } - - /// - /// Converst the json output to our WeatherInfo model class - /// - /// The data. - /// WeatherInfo. - private WeatherInfo GetWeatherInfo(WeatherData data) - { - var info = new WeatherInfo(); - - if (data.current_condition != null) - { - var condition = data.current_condition.FirstOrDefault(); - - if (condition != null) - { - info.CurrentWeather = condition.ToWeatherStatus(); - } - } - - if (data.weather != null) - { - info.Forecasts = data.weather.Select(w => w.ToWeatherForecast()).ToArray(); - } - - return info; - } - } - - /// - /// Class WeatherResult - /// - class WeatherResult - { - /// - /// Gets or sets the data. - /// - /// The data. - public WeatherData data { get; set; } - } - - /// - /// Class WeatherData - /// - public class WeatherData - { - /// - /// Gets or sets the current_condition. - /// - /// The current_condition. - public WeatherCondition[] current_condition { get; set; } - /// - /// Gets or sets the weather. - /// - /// The weather. - public DailyWeatherInfo[] weather { get; set; } - } - - /// - /// Class WeatherCondition - /// - public class WeatherCondition - { - /// - /// Gets or sets the temp_ C. - /// - /// The temp_ C. - public string temp_C { get; set; } - /// - /// Gets or sets the temp_ F. - /// - /// The temp_ F. - public string temp_F { get; set; } - /// - /// Gets or sets the humidity. - /// - /// The humidity. - public string humidity { get; set; } - /// - /// Gets or sets the weather code. - /// - /// The weather code. - public string weatherCode { get; set; } - - /// - /// To the weather status. - /// - /// WeatherStatus. - public WeatherStatus ToWeatherStatus() - { - return new WeatherStatus - { - TemperatureCelsius = int.Parse(temp_C), - TemperatureFahrenheit = int.Parse(temp_F), - Humidity = int.Parse(humidity), - Condition = DailyWeatherInfo.GetCondition(weatherCode) - }; - } - } - - /// - /// Class DailyWeatherInfo - /// - public class DailyWeatherInfo - { - /// - /// Gets or sets the date. - /// - /// The date. - public string date { get; set; } - /// - /// Gets or sets the precip MM. - /// - /// The precip MM. - public string precipMM { get; set; } - /// - /// Gets or sets the temp max C. - /// - /// The temp max C. - public string tempMaxC { get; set; } - /// - /// Gets or sets the temp max F. - /// - /// The temp max F. - public string tempMaxF { get; set; } - /// - /// Gets or sets the temp min C. - /// - /// The temp min C. - public string tempMinC { get; set; } - /// - /// Gets or sets the temp min F. - /// - /// The temp min F. - public string tempMinF { get; set; } - /// - /// Gets or sets the weather code. - /// - /// The weather code. - public string weatherCode { get; set; } - /// - /// Gets or sets the winddir16 point. - /// - /// The winddir16 point. - public string winddir16Point { get; set; } - /// - /// Gets or sets the winddir degree. - /// - /// The winddir degree. - public string winddirDegree { get; set; } - /// - /// Gets or sets the winddirection. - /// - /// The winddirection. - public string winddirection { get; set; } - /// - /// Gets or sets the windspeed KMPH. - /// - /// The windspeed KMPH. - public string windspeedKmph { get; set; } - /// - /// Gets or sets the windspeed miles. - /// - /// The windspeed miles. - public string windspeedMiles { get; set; } - - /// - /// To the weather forecast. - /// - /// WeatherForecast. - public WeatherForecast ToWeatherForecast() - { - return new WeatherForecast - { - Date = DateTime.Parse(date), - HighTemperatureCelsius = int.Parse(tempMaxC), - HighTemperatureFahrenheit = int.Parse(tempMaxF), - LowTemperatureCelsius = int.Parse(tempMinC), - LowTemperatureFahrenheit = int.Parse(tempMinF), - Condition = GetCondition(weatherCode) - }; - } - - /// - /// Gets the condition. - /// - /// The weather code. - /// WeatherConditions. - public static WeatherConditions GetCondition(string weatherCode) - { - switch (weatherCode) - { - case "362": - case "365": - case "320": - case "317": - case "182": - return WeatherConditions.Sleet; - case "338": - case "335": - case "332": - case "329": - case "326": - case "323": - case "377": - case "374": - case "371": - case "368": - case "395": - case "392": - case "350": - case "227": - case "179": - return WeatherConditions.Snow; - case "314": - case "311": - case "308": - case "305": - case "302": - case "299": - case "296": - case "293": - case "284": - case "281": - case "266": - case "263": - case "359": - case "356": - case "353": - case "185": - case "176": - return WeatherConditions.Rain; - case "260": - case "248": - return WeatherConditions.Fog; - case "389": - case "386": - case "200": - return WeatherConditions.Thunderstorm; - case "230": - return WeatherConditions.Blizzard; - case "143": - return WeatherConditions.Mist; - case "122": - return WeatherConditions.Overcast; - case "119": - return WeatherConditions.Cloudy; - case "115": - return WeatherConditions.PartlyCloudy; - default: - return WeatherConditions.Sunny; - } - } - } -} -- cgit v1.2.3