2
// Copyright (C) 2009 Robert Dyer
4
// This program is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
9
// This program is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
// GNU General Public License for more details.
14
// You should have received a copy of the GNU General Public License
15
// along with this program. If not, see <http://www.gnu.org/licenses/>.
19
using System.Collections.Generic;
23
using System.Globalization;
29
namespace WeatherDocklet
32
/// Provides a weather source using data from The Weather Channel.
34
public class WeatherChannelWeatherSource : AbstractWeatherSource
37
/// A map that maps conditions to icon names.
39
static Dictionary<string, string> image_map = new Dictionary<string, string>();
41
/// A map that maps conditions to icon names.
43
protected override Dictionary<string, string> ImageMap { get { return image_map; } }
45
public override int ForecastDays { get { return 5 - (Offset ? 1 : 0); } }
48
/// If the FeedUrl returned a first forecast day with N/A values and we offset to skip it.
50
bool Offset { get; set; }
52
public override string Name {
54
return "Weather Channel";
58
public override string About {
60
return Catalog.GetString ("Weather data provided by and copyright The Weather Channel. " +
61
"This source requires locations to be specified as US Zip Code or a unique code from the website. " +
62
"To find your code, look up your forecast on their site and the code is in the URL after '/local/' and looks like AAXX0000.");
66
protected override string FeedUrl {
68
return "http://xoap.weather.com/weather/local/" +
69
WeatherController.EncodedCurrentLocation +
70
"?cc=*&dayf=10&prod=xoap&par=1097943453&link=xoap&key=306225326138d0bd&unit=s";
74
protected override string ForecastUrl {
76
return "http://www.weather.com/outlook/travel/businesstraveler/wxdetail/" +
77
WeatherController.EncodedCurrentLocation + "?dayNum=";
81
protected override string SearchUrl {
83
return "http://xoap.weather.com/search/search?where=";
87
static WeatherChannelWeatherSource () {
88
image_map.Add ("am clouds / pm sun", "weather-few-clouds");
89
image_map.Add ("am light rain", "weather-showers-scattered");
90
image_map.Add ("am showers", "weather-showers");
91
image_map.Add ("clear", "weather-clear");
92
image_map.Add ("cloudy", "weather-few-clouds");
93
image_map.Add ("fair", "weather-clear");
94
image_map.Add ("fair and windy", "weather-clear");
95
image_map.Add ("fog", "weather-fog");
96
image_map.Add ("few showers", "weather-showers-scattered");
97
image_map.Add ("haze", "weather-fog");
98
image_map.Add ("heavy rain", "weather-showers");
99
image_map.Add ("isolated t-storms", "weather-storm");
100
image_map.Add ("light rain", "weather-showers-scattered");
101
image_map.Add ("light snow and wind", "weather-snow");
102
image_map.Add ("mostly cloudy", "weather-few-clouds");
103
image_map.Add ("mostly cloudy and windy", "weather-few-clouds");
104
image_map.Add ("mostly sunny", "weather-clear");
105
image_map.Add ("partly cloudy", "weather-few-clouds");
106
image_map.Add ("partly cloudy / wind", "weather-few-clouds");
107
image_map.Add ("partly cloudy and windy", "weather-few-clouds");
108
image_map.Add ("pm showers", "weather-showers");
109
image_map.Add ("pm t-storms", "weather-storm");
110
image_map.Add ("rain", "weather-showers");
111
image_map.Add ("rain / thunder", "weather-storm");
112
image_map.Add ("rain / wind", "weather-showers");
113
image_map.Add ("scattered showers", "weather-showers-scattered");
114
image_map.Add ("scattered strong storms", "weather-storm");
115
image_map.Add ("scattered strong storms / wind", "weather-storm");
116
image_map.Add ("scattered t-storms", "weather-storm");
117
image_map.Add ("showers", "weather-showers");
118
image_map.Add ("showers / wind", "weather-showers");
119
image_map.Add ("sunny", "weather-clear");
120
image_map.Add ("t-showers", "weather-storm");
121
image_map.Add ("t-storms", "weather-storm");
122
image_map.Add ("thunder in the vicinity", "weather-storm");
123
image_map.Add ("wintry mix", "weather-snow");
125
// currently unused icons
126
//image_map.Add ("", "weather-overcast");
127
//image_map.Add ("", "weather-severe-alert");
131
/// The singleton instance;
133
static AbstractWeatherSource Instance { get; set; }
136
/// Returns the singleton instance for this class.
139
/// A <see cref="AbstractWeatherSource"/> that is the only instance of this class.
141
public static AbstractWeatherSource GetInstance ()
143
if (Instance == null)
144
Instance = new WeatherChannelWeatherSource ();
149
protected override void ParseXml (XmlDocument xml)
151
XmlNodeList nodelist = xml.SelectNodes ("weather/loc");
152
XmlNode item = nodelist.Item (0);
154
Double.TryParse(item.SelectSingleNode ("lat").InnerText, NumberStyles.Any, CultureInfo.GetCultureInfo("en-US"), out dbl);
156
Double.TryParse (item.SelectSingleNode ("lon").InnerText, NumberStyles.Any, CultureInfo.GetCultureInfo("en-US"), out dbl);
158
SunRise = DateTime.Parse (item.SelectSingleNode ("sunr").InnerText);
159
SunSet = DateTime.Parse (item.SelectSingleNode ("suns").InnerText);
161
nodelist = xml.SelectNodes ("weather/cc");
162
item = nodelist.Item (0);
163
City = item.SelectSingleNode ("obst").InnerText;
164
if (City.IndexOf (",") != -1)
165
City = City.Substring (0, City.IndexOf (","));
168
Int32.TryParse (item.SelectSingleNode ("tmp").InnerText, out temp);
171
if (!item.SelectSingleNode ("flik").InnerText.Equals ("N/A")) {
172
Int32.TryParse (item.SelectSingleNode ("flik").InnerText, out temp);
177
Int32.TryParse(item.SelectSingleNode ("wind").SelectSingleNode ("s").InnerText, out temp);
179
WindDirection = item.SelectSingleNode ("wind").SelectSingleNode ("t").InnerText;
181
Humidity = item.SelectSingleNode ("hmid").InnerText + "%";
183
Condition = item.SelectSingleNode ("t").InnerText;
184
Image = GetImage (Condition, true);
186
nodelist = xml.SelectNodes ("weather/dayf/day");
188
if (nodelist.Item (0).SelectSingleNode ("hi").InnerText.Equals ("N/A"))
193
for (int i = 0; i < ForecastDays + (Offset ? 1 : 0); i++)
195
item = nodelist.Item (i + (Offset ? 1 : 0));
199
Int32.TryParse (item.SelectSingleNode ("hi").InnerText, out Forecasts [i].high);
200
Int32.TryParse (item.SelectSingleNode ("low").InnerText, out Forecasts [i].low);
201
Forecasts [i].condition = item.SelectSingleNode ("part").SelectSingleNode ("t").InnerText;
202
Forecasts [i].dow = item.Attributes ["t"].InnerText.Substring (0, 3);
203
Forecasts [i].image = GetImage (Forecasts[i].condition, false);
205
Int32.TryParse (item.SelectSingleNode ("part").SelectSingleNode ("ppcp").InnerText, out ppcp);
206
Forecasts [i].chanceOf = ppcp < 60 && ppcp > 30;
210
protected override void ShowRadar (string location)
212
DockServices.System.Open ("http://www.weather.com/outlook/travel/businesstraveler/map/" + location);
215
public override void ShowForecast (int day)
217
DockServices.System.Open (ForecastUrl + (day + (Offset ? 1 : 0)));
220
public override IEnumerable<string> SearchLocation (string location)
223
location = HttpUtility.UrlEncode (location);
227
xml = FetchXml (SearchUrl + location);
228
} catch (Exception) { yield break; }
230
XmlNodeList nodelist = xml.SelectNodes ("search/loc");
232
for (int i = 0; i < nodelist.Count; i++)
234
yield return nodelist.Item (i).InnerText;
235
yield return nodelist.Item (i).Attributes ["id"].InnerText;