LukePulverenti Luke Pulverenti luke pulverenti 12 лет назад
Родитель
Сommit
a7b0dd1534
25 измененных файлов с 364 добавлено и 14 удалено
  1. 1 1
      MediaBrowser.Api/HttpHandlers/GenreHandler.cs
  2. 1 1
      MediaBrowser.Api/HttpHandlers/GenresHandler.cs
  3. 1 1
      MediaBrowser.Api/HttpHandlers/ItemHandler.cs
  4. 1 1
      MediaBrowser.Api/HttpHandlers/ItemListHandler.cs
  5. 1 1
      MediaBrowser.Api/HttpHandlers/PersonHandler.cs
  6. 1 1
      MediaBrowser.Api/HttpHandlers/PluginConfigurationHandler.cs
  7. 1 1
      MediaBrowser.Api/HttpHandlers/PluginsHandler.cs
  8. 1 1
      MediaBrowser.Api/HttpHandlers/StudioHandler.cs
  9. 1 1
      MediaBrowser.Api/HttpHandlers/StudiosHandler.cs
  10. 1 1
      MediaBrowser.Api/HttpHandlers/UsersHandler.cs
  11. 36 0
      MediaBrowser.Api/HttpHandlers/WeatherHandler.cs
  12. 1 1
      MediaBrowser.Api/HttpHandlers/YearHandler.cs
  13. 1 1
      MediaBrowser.Api/HttpHandlers/YearsHandler.cs
  14. 1 0
      MediaBrowser.Api/MediaBrowser.Api.csproj
  15. 4 0
      MediaBrowser.Api/Plugin.cs
  16. 27 0
      MediaBrowser.ApiInteraction/ApiClient.cs
  17. 1 1
      MediaBrowser.Common/Net/Handlers/BaseSerializationHandler.cs
  18. 1 0
      MediaBrowser.Controller/Configuration/ServerConfiguration.cs
  19. 3 1
      MediaBrowser.Controller/Kernel.cs
  20. 3 0
      MediaBrowser.Controller/MediaBrowser.Controller.csproj
  21. 191 0
      MediaBrowser.Controller/Weather/WeatherClient.cs
  22. 3 0
      MediaBrowser.Model/MediaBrowser.Model.csproj
  23. 30 0
      MediaBrowser.Model/Weather/WeatherForecast.cs
  24. 14 0
      MediaBrowser.Model/Weather/WeatherInfo.cs
  25. 38 0
      MediaBrowser.Model/Weather/WeatherStatus.cs

+ 1 - 1
MediaBrowser.Api/HttpHandlers/GenreHandler.cs

@@ -12,7 +12,7 @@ namespace MediaBrowser.Api.HttpHandlers
     /// <summary>
     /// Gets a single genre
     /// </summary>
-    public class GenreHandler : BaseJsonHandler<IBNItem>
+    public class GenreHandler : BaseSerializationHandler<IBNItem>
     {
         protected override Task<IBNItem> GetObjectToSerialize()
         {

+ 1 - 1
MediaBrowser.Api/HttpHandlers/GenresHandler.cs

@@ -9,7 +9,7 @@ using MediaBrowser.Model.Entities;
 
 namespace MediaBrowser.Api.HttpHandlers
 {
-    public class GenresHandler : BaseJsonHandler<IBNItem[]>
+    public class GenresHandler : BaseSerializationHandler<IBNItem[]>
     {
         protected override Task<IBNItem[]> GetObjectToSerialize()
         {

+ 1 - 1
MediaBrowser.Api/HttpHandlers/ItemHandler.cs

@@ -8,7 +8,7 @@ using MediaBrowser.Model.Entities;
 
 namespace MediaBrowser.Api.HttpHandlers
 {
-    public class ItemHandler : BaseJsonHandler<DTOBaseItem>
+    public class ItemHandler : BaseSerializationHandler<DTOBaseItem>
     {
         protected override Task<DTOBaseItem> GetObjectToSerialize()
         {

+ 1 - 1
MediaBrowser.Api/HttpHandlers/ItemListHandler.cs

@@ -9,7 +9,7 @@ using MediaBrowser.Model.Entities;
 
 namespace MediaBrowser.Api.HttpHandlers
 {
-    public class ItemListHandler : BaseJsonHandler<DTOBaseItem[]>
+    public class ItemListHandler : BaseSerializationHandler<DTOBaseItem[]>
     {
         protected override Task<DTOBaseItem[]> GetObjectToSerialize()
         {

+ 1 - 1
MediaBrowser.Api/HttpHandlers/PersonHandler.cs

@@ -12,7 +12,7 @@ namespace MediaBrowser.Api.HttpHandlers
     /// <summary>
     /// Gets a single Person
     /// </summary>
-    public class PersonHandler : BaseJsonHandler<IBNItem>
+    public class PersonHandler : BaseSerializationHandler<IBNItem>
     {
         protected override Task<IBNItem> GetObjectToSerialize()
         {

+ 1 - 1
MediaBrowser.Api/HttpHandlers/PluginConfigurationHandler.cs

@@ -7,7 +7,7 @@ using MediaBrowser.Model.Plugins;
 
 namespace MediaBrowser.Api.HttpHandlers
 {
-    public class PluginConfigurationHandler : BaseJsonHandler<BasePluginConfiguration>
+    public class PluginConfigurationHandler : BaseSerializationHandler<BasePluginConfiguration>
     {
         protected override Task<BasePluginConfiguration> GetObjectToSerialize()
         {

+ 1 - 1
MediaBrowser.Api/HttpHandlers/PluginsHandler.cs

@@ -10,7 +10,7 @@ namespace MediaBrowser.Api.HttpHandlers
     /// <summary>
     /// Provides information about installed plugins
     /// </summary>
-    public class PluginsHandler : BaseJsonHandler<IEnumerable<PluginInfo>>
+    public class PluginsHandler : BaseSerializationHandler<IEnumerable<PluginInfo>>
     {
         protected override Task<IEnumerable<PluginInfo>> GetObjectToSerialize()
         {

+ 1 - 1
MediaBrowser.Api/HttpHandlers/StudioHandler.cs

@@ -12,7 +12,7 @@ namespace MediaBrowser.Api.HttpHandlers
     /// <summary>
     /// Gets a single studio
     /// </summary>
-    public class StudioHandler : BaseJsonHandler<IBNItem>
+    public class StudioHandler : BaseSerializationHandler<IBNItem>
     {
         protected override Task<IBNItem> GetObjectToSerialize()
         {

+ 1 - 1
MediaBrowser.Api/HttpHandlers/StudiosHandler.cs

@@ -9,7 +9,7 @@ using MediaBrowser.Model.Entities;
 
 namespace MediaBrowser.Api.HttpHandlers
 {
-    public class StudiosHandler : BaseJsonHandler<IBNItem[]>
+    public class StudiosHandler : BaseSerializationHandler<IBNItem[]>
     {
         protected override Task<IBNItem[]> GetObjectToSerialize()
         {

+ 1 - 1
MediaBrowser.Api/HttpHandlers/UsersHandler.cs

@@ -7,7 +7,7 @@ using MediaBrowser.Model.DTO;
 
 namespace MediaBrowser.Api.HttpHandlers
 {
-    class UsersHandler : BaseJsonHandler<IEnumerable<DTOUser>>
+    class UsersHandler : BaseSerializationHandler<IEnumerable<DTOUser>>
     {
         protected override Task<IEnumerable<DTOUser>> GetObjectToSerialize()
         {

+ 36 - 0
MediaBrowser.Api/HttpHandlers/WeatherHandler.cs

@@ -0,0 +1,36 @@
+using System;
+using System.Threading.Tasks;
+using MediaBrowser.Common.Net.Handlers;
+using MediaBrowser.Controller;
+using MediaBrowser.Model.Weather;
+
+namespace MediaBrowser.Api.HttpHandlers
+{
+    class WeatherHandler : BaseSerializationHandler<WeatherInfo>
+    {
+        protected override Task<WeatherInfo> GetObjectToSerialize()
+        {
+            // If a specific zip code was requested on the query string, use that. Otherwise use the value from configuration
+
+            string zipCode = QueryString["zipcode"];
+
+            if (string.IsNullOrWhiteSpace(zipCode))
+            {
+                zipCode = Kernel.Instance.Configuration.WeatherZipCode;
+            }
+
+            return Kernel.Instance.WeatherClient.GetWeatherInfoAsync(zipCode);
+        }
+
+        /// <summary>
+        /// Tell the client to cache the weather info for 15 minutes
+        /// </summary>
+        public override TimeSpan CacheDuration
+        {
+            get
+            {
+                return TimeSpan.FromMinutes(15);
+            }
+        }
+    }
+}

+ 1 - 1
MediaBrowser.Api/HttpHandlers/YearHandler.cs

@@ -12,7 +12,7 @@ namespace MediaBrowser.Api.HttpHandlers
     /// <summary>
     /// Gets a single year
     /// </summary>
-    public class YearHandler : BaseJsonHandler<IBNItem>
+    public class YearHandler : BaseSerializationHandler<IBNItem>
     {
         protected override Task<IBNItem> GetObjectToSerialize()
         {

+ 1 - 1
MediaBrowser.Api/HttpHandlers/YearsHandler.cs

@@ -9,7 +9,7 @@ using MediaBrowser.Model.Entities;
 
 namespace MediaBrowser.Api.HttpHandlers
 {
-    public class YearsHandler : BaseJsonHandler<IBNItem[]>
+    public class YearsHandler : BaseSerializationHandler<IBNItem[]>
     {
         protected override Task<IBNItem[]> GetObjectToSerialize()
         {

+ 1 - 0
MediaBrowser.Api/MediaBrowser.Api.csproj

@@ -69,6 +69,7 @@
     <Compile Include="HttpHandlers\StudiosHandler.cs" />
     <Compile Include="HttpHandlers\UsersHandler.cs" />
     <Compile Include="HttpHandlers\VideoHandler.cs" />
+    <Compile Include="HttpHandlers\WeatherHandler.cs" />
     <Compile Include="HttpHandlers\YearHandler.cs" />
     <Compile Include="HttpHandlers\YearsHandler.cs" />
     <Compile Include="ImageProcessor.cs" />

+ 4 - 0
MediaBrowser.Api/Plugin.cs

@@ -101,6 +101,10 @@ namespace MediaBrowser.Api
             {
                 return new StudioHandler();
             }
+            else if (localPath.EndsWith("/api/weather", StringComparison.OrdinalIgnoreCase))
+            {
+                return new WeatherHandler();
+            }
 
             return null;
         }

+ 27 - 0
MediaBrowser.ApiInteraction/ApiClient.cs

@@ -6,6 +6,7 @@ using System.Net.Http;
 using System.Threading.Tasks;
 using MediaBrowser.Model.DTO;
 using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Weather;
 
 namespace MediaBrowser.ApiInteraction
 {
@@ -564,6 +565,32 @@ namespace MediaBrowser.ApiInteraction
             }
         }
 
+        /// <summary>
+        /// Gets weather information for the default location as set in configuration
+        /// </summary>
+        public async Task<WeatherInfo> GetWeatherInfo()
+        {
+            string url = ApiUrl + "/weather";
+
+            using (Stream stream = await GetSerializedStreamAsync(url).ConfigureAwait(false))
+            {
+                return DeserializeFromStream<WeatherInfo>(stream);
+            }
+        }
+
+        /// <summary>
+        /// Gets weather information for a specific zip code
+        /// </summary>
+        public async Task<WeatherInfo> GetWeatherInfo(string zipCode)
+        {
+            string url = ApiUrl + "/weather?zipcode=" + zipCode;
+
+            using (Stream stream = await GetSerializedStreamAsync(url).ConfigureAwait(false))
+            {
+                return DeserializeFromStream<WeatherInfo>(stream);
+            }
+        }
+
         /// <summary>
         /// This is a helper around getting a stream from the server that contains serialized data
         /// </summary>

+ 1 - 1
MediaBrowser.Common/Net/Handlers/BaseSerializationHandler.cs

@@ -5,7 +5,7 @@ using MediaBrowser.Common.Serialization;
 
 namespace MediaBrowser.Common.Net.Handlers
 {
-    public abstract class BaseJsonHandler<T> : BaseHandler
+    public abstract class BaseSerializationHandler<T> : BaseHandler
     {
         public SerializationFormat SerializationFormat
         {

+ 1 - 0
MediaBrowser.Controller/Configuration/ServerConfiguration.cs

@@ -5,5 +5,6 @@ namespace MediaBrowser.Controller.Configuration
     public class ServerConfiguration : BaseApplicationConfiguration
     {
         public bool EnableInternetProviders { get; set; }
+        public string WeatherZipCode { get; set; }
     }
 }

+ 3 - 1
MediaBrowser.Controller/Kernel.cs

@@ -14,6 +14,7 @@ using MediaBrowser.Controller.IO;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Controller.Resolvers;
+using MediaBrowser.Controller.Weather;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Progress;
 
@@ -24,6 +25,7 @@ namespace MediaBrowser.Controller
         public static Kernel Instance { get; private set; }
 
         public ItemController ItemController { get; private set; }
+        public WeatherClient WeatherClient { get; private set; }
 
         public IEnumerable<User> Users { get; private set; }
         public Folder RootFolder { get; private set; }
@@ -72,6 +74,7 @@ namespace MediaBrowser.Controller
 
             ItemController = new ItemController();
             DirectoryWatchers = new DirectoryWatchers();
+            WeatherClient = new WeatherClient();
 
             ItemController.PreBeginResolvePath += ItemController_PreBeginResolvePath;
             ItemController.BeginResolvePath += ItemController_BeginResolvePath;
@@ -228,7 +231,6 @@ namespace MediaBrowser.Controller
 
             user.Name = "Default User";
             user.Id = Guid.Parse("5d1cf7fce25943b790d140095457a42b");
-            //user.PrimaryImagePath = "D:\\Video\\TV\\Archer (2009)\\folder.jpg";
 
             list.Add(user);
             

+ 3 - 0
MediaBrowser.Controller/MediaBrowser.Controller.csproj

@@ -37,6 +37,8 @@
     <Reference Include="System" />
     <Reference Include="System.ComponentModel.Composition" />
     <Reference Include="System.Core" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Net.Http.WebRequest" />
     <Reference Include="System.Reactive.Core, Version=2.0.20823.0, Culture=neutral, PublicKeyToken=f300afd708cefcd3, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\packages\Rx-Core.2.0.20823\lib\Net45\System.Reactive.Core.dll</HintPath>
@@ -77,6 +79,7 @@
     <Compile Include="Resolvers\BaseItemResolver.cs" />
     <Compile Include="Resolvers\FolderResolver.cs" />
     <Compile Include="Resolvers\VideoResolver.cs" />
+    <Compile Include="Weather\WeatherClient.cs" />
     <Compile Include="Xml\BaseItemXmlParser.cs" />
     <Compile Include="Xml\XmlExtensions.cs" />
   </ItemGroup>

+ 191 - 0
MediaBrowser.Controller/Weather/WeatherClient.cs

@@ -0,0 +1,191 @@
+using System;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Net.Cache;
+using System.Net.Http;
+using System.Threading.Tasks;
+using MediaBrowser.Common.Logging;
+using MediaBrowser.Common.Serialization;
+using MediaBrowser.Model.Weather;
+
+namespace MediaBrowser.Controller.Weather
+{
+    /// <summary>
+    /// 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
+    /// </summary>
+    public class WeatherClient
+    {
+        private HttpClient HttpClient { get; set; }
+
+        public WeatherClient()
+        {
+            WebRequestHandler handler = new WebRequestHandler();
+
+            handler.AutomaticDecompression = DecompressionMethods.Deflate;
+            handler.CachePolicy = new RequestCachePolicy(RequestCacheLevel.Revalidate);
+
+            HttpClient = new HttpClient(handler);
+        }
+
+        public async Task<WeatherInfo> GetWeatherInfoAsync(string zipCode)
+        {
+            int numDays = 5;
+            string apiKey = "24902f60f1231941120109";
+
+            string url = "http://free.worldweatheronline.com/feed/weather.ashx?q=" + zipCode + "&format=json&num_of_days=" + numDays + "&key=" + apiKey;
+
+            Logger.LogInfo("Accessing weather from " + url);
+
+            using (Stream stream = await HttpClient.GetStreamAsync(url).ConfigureAwait(false))
+            {
+                WeatherData data = JsonSerializer.DeserializeFromStream<WeatherResult>(stream).data;
+
+                return GetWeatherInfo(data);
+            }
+        }
+
+        /// <summary>
+        /// Converst the json output to our WeatherInfo model class
+        /// </summary>
+        private WeatherInfo GetWeatherInfo(WeatherData data)
+        {
+            WeatherInfo info = new WeatherInfo();
+
+            if (data.current_condition.Any())
+            {
+                info.CurrentWeather = data.current_condition.First().ToWeatherStatus();
+            }
+
+            info.Forecasts = data.weather.Select(w => w.ToWeatherForecast()).ToArray();
+
+            return info;
+        }
+    }
+
+    class WeatherResult
+    {
+        public WeatherData data { get; set; }
+    }
+
+    public class WeatherData
+    {
+        public WeatherCondition[] current_condition { get; set; }
+        public DailyWeatherInfo[] weather { get; set; }
+    }
+
+    public class WeatherCondition
+    {
+        public string temp_C { get; set; }
+        public string temp_F { get; set; }
+        public string humidity { get; set; }
+        public string weatherCode { get; set; }
+
+        public WeatherStatus ToWeatherStatus()
+        {
+            return new WeatherStatus()
+            {
+                TemperatureCelsius = int.Parse(temp_C),
+                TemperatureFahrenheit = int.Parse(temp_F),
+                Humidity = int.Parse(humidity),
+                Condition = DailyWeatherInfo.GetCondition(weatherCode)
+            };
+        }
+    }
+
+    public class DailyWeatherInfo
+    {
+        public string date { get; set; }
+        public string precipMM { get; set; }
+        public string tempMaxC { get; set; }
+        public string tempMaxF { get; set; }
+        public string tempMinC { get; set; }
+        public string tempMinF { get; set; }
+        public string weatherCode { get; set; }
+        public string winddir16Point { get; set; }
+        public string winddirDegree { get; set; }
+        public string winddirection { get; set; }
+        public string windspeedKmph { get; set; }
+        public string windspeedMiles { get; set; }
+
+        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)
+            };
+        }
+
+        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;
+            }
+        }
+    }
+}

+ 3 - 0
MediaBrowser.Model/MediaBrowser.Model.csproj

@@ -56,6 +56,9 @@
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Entities\User.cs" />
     <Compile Include="Entities\UserItemData.cs" />
+    <Compile Include="Weather\WeatherForecast.cs" />
+    <Compile Include="Weather\WeatherInfo.cs" />
+    <Compile Include="Weather\WeatherStatus.cs" />
   </ItemGroup>
   <ItemGroup>
     <Reference Include="protobuf-net">

+ 30 - 0
MediaBrowser.Model/Weather/WeatherForecast.cs

@@ -0,0 +1,30 @@
+using System;
+using ProtoBuf;
+
+namespace MediaBrowser.Model.Weather
+{
+    /// <summary>
+    /// Represents a weather forecase for a specific date
+    /// </summary>
+    [ProtoContract]
+    public class WeatherForecast
+    {
+        [ProtoMember(1)]
+        public DateTime Date { get; set; }
+
+        [ProtoMember(2)]
+        public int HighTemperatureFahrenheit { get; set; }
+
+        [ProtoMember(3)]
+        public int LowTemperatureFahrenheit { get; set; }
+
+        [ProtoMember(4)]
+        public int HighTemperatureCelsius { get; set; }
+
+        [ProtoMember(5)]
+        public int LowTemperatureCelsius { get; set; }
+
+        [ProtoMember(6)]
+        public WeatherConditions Condition { get; set; }
+    }
+}

+ 14 - 0
MediaBrowser.Model/Weather/WeatherInfo.cs

@@ -0,0 +1,14 @@
+using ProtoBuf;
+
+namespace MediaBrowser.Model.Weather
+{
+    [ProtoContract]
+    public class WeatherInfo
+    {
+        [ProtoMember(1)]
+        public WeatherStatus CurrentWeather { get; set; }
+
+        [ProtoMember(2)]
+        public WeatherForecast[] Forecasts { get; set; }
+    }
+}

+ 38 - 0
MediaBrowser.Model/Weather/WeatherStatus.cs

@@ -0,0 +1,38 @@
+using ProtoBuf;
+
+namespace MediaBrowser.Model.Weather
+{
+    /// <summary>
+    /// Represents the current weather status
+    /// </summary>
+    [ProtoContract]
+    public class WeatherStatus
+    {
+        [ProtoMember(1)]
+        public int TemperatureFahrenheit { get; set; }
+
+        [ProtoMember(2)]
+        public int TemperatureCelsius { get; set; }
+
+        [ProtoMember(3)]
+        public int Humidity { get; set; }
+
+        [ProtoMember(4)]
+        public WeatherConditions Condition { get; set; }
+    }
+
+    public enum WeatherConditions
+    {
+        Sunny,
+        PartlyCloudy,
+        Cloudy,
+        Overcast,
+        Mist,
+        Snow,
+        Rain,
+        Sleet,
+        Fog,
+        Blizzard,
+        Thunderstorm
+    }
+}