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.Api/MediaBrowser.Api.csproj | 4 - MediaBrowser.Api/packages.config | 1 - MediaBrowser.Common/Drawing/ImageExtensions.cs | 199 ------------ MediaBrowser.Common/Drawing/ImageHeader.cs | 216 ------------- MediaBrowser.Common/Kernel/BaseKernel.cs | 3 +- MediaBrowser.Common/MediaBrowser.Common.csproj | 4 - 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 ------------------- MediaBrowser.IsoMounter/PismoIsoManager.cs | 16 +- MediaBrowser.IsoMounter/PismoMount.cs | 16 +- .../MediaBrowser.Server.WorldWeatherOnline.csproj | 74 +++++ .../Properties/AssemblyInfo.cs | 36 +++ .../WeatherProvider.cs | 335 +++++++++++++++++++++ MediaBrowser.ServerApplication/App.xaml.cs | 3 +- .../MediaBrowser.ServerApplication.csproj | 3 + MediaBrowser.UI/App.xaml.cs | 2 +- MediaBrowser.sln | 16 + 24 files changed, 967 insertions(+), 796 deletions(-) delete mode 100644 MediaBrowser.Common/Drawing/ImageExtensions.cs delete mode 100644 MediaBrowser.Common/Drawing/ImageHeader.cs 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 create mode 100644 MediaBrowser.Server.WorldWeatherOnline/MediaBrowser.Server.WorldWeatherOnline.csproj create mode 100644 MediaBrowser.Server.WorldWeatherOnline/Properties/AssemblyInfo.cs create mode 100644 MediaBrowser.Server.WorldWeatherOnline/WeatherProvider.cs diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj index 5fbd751cd3..546cf44928 100644 --- a/MediaBrowser.Api/MediaBrowser.Api.csproj +++ b/MediaBrowser.Api/MediaBrowser.Api.csproj @@ -39,10 +39,6 @@ ..\packages\morelinq.1.0.15631-beta\lib\net35\MoreLinq.dll - - False - ..\packages\protobuf-net.2.0.0.621\lib\net40\protobuf-net.dll - ..\packages\ServiceStack.3.9.37\lib\net35\ServiceStack.dll diff --git a/MediaBrowser.Api/packages.config b/MediaBrowser.Api/packages.config index c8efad540b..ee47118adc 100644 --- a/MediaBrowser.Api/packages.config +++ b/MediaBrowser.Api/packages.config @@ -1,7 +1,6 @@  - diff --git a/MediaBrowser.Common/Drawing/ImageExtensions.cs b/MediaBrowser.Common/Drawing/ImageExtensions.cs deleted file mode 100644 index 02c0f93dd6..0000000000 --- a/MediaBrowser.Common/Drawing/ImageExtensions.cs +++ /dev/null @@ -1,199 +0,0 @@ -using System; -using System.Drawing; -using System.Drawing.Drawing2D; -using System.Drawing.Imaging; -using System.IO; -using System.Linq; - -namespace MediaBrowser.Common.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.Common/Drawing/ImageHeader.cs b/MediaBrowser.Common/Drawing/ImageHeader.cs deleted file mode 100644 index 97121cbc8c..0000000000 --- a/MediaBrowser.Common/Drawing/ImageHeader.cs +++ /dev/null @@ -1,216 +0,0 @@ -using MediaBrowser.Common.Logging; -using System; -using System.Collections.Generic; -using System.Drawing; -using System.IO; -using System.Linq; - -namespace MediaBrowser.Common.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.Common/Kernel/BaseKernel.cs b/MediaBrowser.Common/Kernel/BaseKernel.cs index 95e6d05d6b..088acbedda 100644 --- a/MediaBrowser.Common/Kernel/BaseKernel.cs +++ b/MediaBrowser.Common/Kernel/BaseKernel.cs @@ -441,7 +441,7 @@ namespace MediaBrowser.Common.Kernel AddLogTarget(logFile, "ApplicationLogFile"); - Logging.Logger.LoggerInstance = Logging.LogManager.GetLogger("Global"); + Logging.Logger.LoggerInstance = Logging.LogManager.GetLogger("App"); OnLoggerLoaded(); } @@ -484,6 +484,7 @@ namespace MediaBrowser.Common.Kernel CompositionContainer = MefUtils.GetSafeCompositionContainer(Assemblies.Select(i => new AssemblyCatalog(i))); CompositionContainer.ComposeExportedValue("kernel", this); + CompositionContainer.ComposeExportedValue("logger", Logging.LogManager.GetLogger("App")); CompositionContainer.ComposeParts(this); diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj index 21502f5c5b..8929f4bd5a 100644 --- a/MediaBrowser.Common/MediaBrowser.Common.csproj +++ b/MediaBrowser.Common/MediaBrowser.Common.csproj @@ -95,7 +95,6 @@ - @@ -118,7 +117,6 @@ - @@ -129,8 +127,6 @@ - - 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; - } - } - } -} diff --git a/MediaBrowser.IsoMounter/PismoIsoManager.cs b/MediaBrowser.IsoMounter/PismoIsoManager.cs index b3a1889f01..3ad3a413ec 100644 --- a/MediaBrowser.IsoMounter/PismoIsoManager.cs +++ b/MediaBrowser.IsoMounter/PismoIsoManager.cs @@ -1,10 +1,9 @@ using MediaBrowser.Common.IO; +using MediaBrowser.Model.Logging; using System; using System.IO; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Common.Logging; -using MediaBrowser.Model.Logging; namespace MediaBrowser.IsoMounter { @@ -13,8 +12,6 @@ namespace MediaBrowser.IsoMounter /// public class PismoIsoManager : IIsoManager { - private ILogger Logger = LogManager.GetLogger("IsoManager"); - /// /// The mount semaphore - limit to four at a time. /// @@ -69,8 +66,15 @@ namespace MediaBrowser.IsoMounter /// private bool _hasInitialized; - public PismoIsoManager() + /// + /// Gets or sets the logger. + /// + /// The logger. + private ILogger Logger { get; set; } + + public PismoIsoManager(ILogger logger) { + Logger = logger; } /// @@ -144,7 +148,7 @@ namespace MediaBrowser.IsoMounter throw new IOException("Unable to start mount for " + isoPath); } - return new PismoMount(mount, isoPath, this); + return new PismoMount(mount, isoPath, this, Logger); } public void Dispose() diff --git a/MediaBrowser.IsoMounter/PismoMount.cs b/MediaBrowser.IsoMounter/PismoMount.cs index 1e3dbb881e..f63db8dcfb 100644 --- a/MediaBrowser.IsoMounter/PismoMount.cs +++ b/MediaBrowser.IsoMounter/PismoMount.cs @@ -1,5 +1,4 @@ using MediaBrowser.Common.IO; -using MediaBrowser.Common.Logging; using MediaBrowser.Model.Logging; using System; @@ -10,11 +9,6 @@ namespace MediaBrowser.IsoMounter /// internal class PismoMount : IIsoMount { - /// - /// The logger - /// - private static readonly ILogger Logger = LogManager.GetLogger("IsoMount"); - /// /// Gets or sets the iso path. /// @@ -37,17 +31,25 @@ namespace MediaBrowser.IsoMounter /// private readonly PismoIsoManager _isoManager; + /// + /// Gets or sets the logger. + /// + /// The logger. + private ILogger Logger { get; set; } + /// /// Prevents a default instance of the class from being created. /// /// The mount. /// The iso path. /// The iso manager. - internal PismoMount(PfmFileMount mount, string isoPath, PismoIsoManager isoManager) + /// The logger. + internal PismoMount(PfmFileMount mount, string isoPath, PismoIsoManager isoManager, ILogger logger) { _pfmFileMount = mount; IsoPath = isoPath; _isoManager = isoManager; + Logger = logger; MountedPath = mount.GetMount().GetUncName(); } diff --git a/MediaBrowser.Server.WorldWeatherOnline/MediaBrowser.Server.WorldWeatherOnline.csproj b/MediaBrowser.Server.WorldWeatherOnline/MediaBrowser.Server.WorldWeatherOnline.csproj new file mode 100644 index 0000000000..9416667709 --- /dev/null +++ b/MediaBrowser.Server.WorldWeatherOnline/MediaBrowser.Server.WorldWeatherOnline.csproj @@ -0,0 +1,74 @@ + + + + + Debug + AnyCPU + {973CA45C-8362-490B-8327-C68098FD4891} + Library + Properties + MediaBrowser.Server.WorldWeatherOnline + MediaBrowser.Server.WorldWeatherOnline + v4.5 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + Always + + + + + + + + + + + + + + + + + + {9142eefa-7570-41e1-bfcc-468bb571af2f} + MediaBrowser.Common + + + {17e1f4e6-8abd-4fe5-9ecf-43d4b6087ba2} + MediaBrowser.Controller + + + {7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b} + MediaBrowser.Model + + + + + xcopy "$(TargetPath)" "$(SolutionDir)\MediaBrowser.ServerApplication\CorePlugins\" /y + + + \ No newline at end of file diff --git a/MediaBrowser.Server.WorldWeatherOnline/Properties/AssemblyInfo.cs b/MediaBrowser.Server.WorldWeatherOnline/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..97f2ae6e11 --- /dev/null +++ b/MediaBrowser.Server.WorldWeatherOnline/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("MediaBrowser.Server.WorldWeatherOnline")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("MediaBrowser.Server.WorldWeatherOnline")] +[assembly: AssemblyCopyright("Copyright © 2013")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("c7b294dc-b3fd-4925-9ac3-8dd16803200c")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/MediaBrowser.Server.WorldWeatherOnline/WeatherProvider.cs b/MediaBrowser.Server.WorldWeatherOnline/WeatherProvider.cs new file mode 100644 index 0000000000..257249793e --- /dev/null +++ b/MediaBrowser.Server.WorldWeatherOnline/WeatherProvider.cs @@ -0,0 +1,335 @@ +using MediaBrowser.Common.Serialization; +using MediaBrowser.Controller; +using MediaBrowser.Controller.Weather; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Weather; +using System; +using System.ComponentModel.Composition; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Server.WorldWeatherOnline +{ + /// + /// 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(IWeatherProvider))] + public class WeatherProvider : IWeatherProvider + { + /// + /// Gets or sets the logger. + /// + /// The logger. + private ILogger Logger { get; set; } + + /// + /// Initializes a new instance of the class. + /// + /// The logger. + /// logger + [ImportingConstructor] + public WeatherProvider([Import("logger")] ILogger logger) + { + if (logger == null) + { + throw new ArgumentNullException("logger"); + } + + Logger = logger; + } + + /// + /// 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 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.Info("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; + } + } + } +} \ No newline at end of file diff --git a/MediaBrowser.ServerApplication/App.xaml.cs b/MediaBrowser.ServerApplication/App.xaml.cs index e503704444..b06c8f04e2 100644 --- a/MediaBrowser.ServerApplication/App.xaml.cs +++ b/MediaBrowser.ServerApplication/App.xaml.cs @@ -1,4 +1,5 @@ using MediaBrowser.Common.Kernel; +using MediaBrowser.Common.Logging; using MediaBrowser.Common.UI; using MediaBrowser.Controller; using MediaBrowser.IsoMounter; @@ -169,7 +170,7 @@ namespace MediaBrowser.ServerApplication /// IKernel. protected override IKernel InstantiateKernel() { - return new Kernel(new PismoIsoManager(), new DotNetZipClient()); + return new Kernel(new PismoIsoManager(LogManager.GetLogger("PismoIsoManager")), new DotNetZipClient()); } /// diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj index 86ad7dcaf6..cfd37904e3 100644 --- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj +++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj @@ -328,6 +328,9 @@ Always + + Always + Always diff --git a/MediaBrowser.UI/App.xaml.cs b/MediaBrowser.UI/App.xaml.cs index bae133ab77..bc68df234f 100644 --- a/MediaBrowser.UI/App.xaml.cs +++ b/MediaBrowser.UI/App.xaml.cs @@ -244,7 +244,7 @@ namespace MediaBrowser.UI /// IKernel. protected override IKernel InstantiateKernel() { - return new UIKernel(new PismoIsoManager()); + return new UIKernel(new PismoIsoManager(LogManager.GetLogger("PismoIsoManager"))); } /// diff --git a/MediaBrowser.sln b/MediaBrowser.sln index 9e35fdc9ed..f9d2816afa 100644 --- a/MediaBrowser.sln +++ b/MediaBrowser.sln @@ -47,6 +47,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Installer", "M EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Server.Sqlite", "MediaBrowser.Server.Sqlite\MediaBrowser.Server.Sqlite.csproj", "{8649ED6B-8504-4D00-BFA5-B8C73CC744DB}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Server.WorldWeatherOnline", "MediaBrowser.Server.WorldWeatherOnline\MediaBrowser.Server.WorldWeatherOnline.csproj", "{973CA45C-8362-490B-8327-C68098FD4891}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -303,6 +305,20 @@ Global {8649ED6B-8504-4D00-BFA5-B8C73CC744DB}.Release|Win32.ActiveCfg = Release|Any CPU {8649ED6B-8504-4D00-BFA5-B8C73CC744DB}.Release|x64.ActiveCfg = Release|Any CPU {8649ED6B-8504-4D00-BFA5-B8C73CC744DB}.Release|x86.ActiveCfg = Release|Any CPU + {973CA45C-8362-490B-8327-C68098FD4891}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {973CA45C-8362-490B-8327-C68098FD4891}.Debug|Any CPU.Build.0 = Debug|Any CPU + {973CA45C-8362-490B-8327-C68098FD4891}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {973CA45C-8362-490B-8327-C68098FD4891}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {973CA45C-8362-490B-8327-C68098FD4891}.Debug|Win32.ActiveCfg = Debug|Any CPU + {973CA45C-8362-490B-8327-C68098FD4891}.Debug|x64.ActiveCfg = Debug|Any CPU + {973CA45C-8362-490B-8327-C68098FD4891}.Debug|x86.ActiveCfg = Debug|Any CPU + {973CA45C-8362-490B-8327-C68098FD4891}.Release|Any CPU.ActiveCfg = Release|Any CPU + {973CA45C-8362-490B-8327-C68098FD4891}.Release|Any CPU.Build.0 = Release|Any CPU + {973CA45C-8362-490B-8327-C68098FD4891}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {973CA45C-8362-490B-8327-C68098FD4891}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {973CA45C-8362-490B-8327-C68098FD4891}.Release|Win32.ActiveCfg = Release|Any CPU + {973CA45C-8362-490B-8327-C68098FD4891}.Release|x64.ActiveCfg = Release|Any CPU + {973CA45C-8362-490B-8327-C68098FD4891}.Release|x86.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE -- cgit v1.2.3