デスクトップマスコット「Apricot」に天気予報を追加するスクリプト
livedoor 天気情報
http://weather.livedoor.com/
livedoorのお天気Webサービスで公開されているAPIを使ってApricotに天気予報を追加するスクリプトを書いてみました。スクリプトを追加すると今日から明後日までの天気予報をキャラクターが喋るようになります。
このWebサービスは、イメージのURIも取得できるので上のスクリーンショットのようにイメージ付で表示出来るのが特にいいです。
下記のコードを拡張子をpy(例:Weather.py)にしてScriptsフォルダに保存すると、Apricotに天気予報を追加できます。
デフォルトは東京なので東京以外の方は、liveoorの公開している1次細分区定義表からcityのIDを変更する必要があります。
1次細分区定義表
http://weather.livedoor.com/forecast/rss/forecastmap.xml
# -*- encoding: utf-8 -*- import clr clr.AddReferenceByPartialName("System.Xml") clr.AddReferenceByPartialName("Apricot") from System import String, Uri, DateTime, TimeSpan, TimeZone, Convert from System.IO import Stream, StreamReader from System.Collections.Generic import List from System.Globalization import CultureInfo, DateTimeStyles from System.Text.RegularExpressions import Regex, RegexOptions, Match from System.Timers import Timer from System.Net import WebRequest, WebResponse from System.Net.NetworkInformation import NetworkInterface from System.Xml import XmlDocument, XmlNode, XmlAttribute from Apricot import Entry # livedoor Weather # http://weather.livedoor.com/weather_hacks/webservice.html # http://weather.livedoor.com/forecast/rss/forecastmap.xml uriList = List[Uri]() uriList.Add(Uri("http://weather.livedoor.com/forecast/webservice/rest/v1?city=63&day=today")) uriList.Add(Uri("http://weather.livedoor.com/forecast/webservice/rest/v1?city=63&day=tomorrow")) uriList.Add(Uri("http://weather.livedoor.com/forecast/webservice/rest/v1?city=63&day=dayaftertomorrow")) format = "M月d日" def parse(s): dt = DateTime() invalidTimeZone = False index = s.Length; match = Regex.Match(s, "\\s[\\+\\-0-9A-Z]+$", RegexOptions.CultureInvariant) if match.Success: index = match.Index else: invalidTimeZone = true dt = Convert.ToDateTime(s.Substring(0, index)) if s.Length - index > 0: if s[index + 1] == '+': if s.Length - (index + 1) == 5: h = Convert.ToInt32(s.Substring(index + 2, 2)) dt = dt.AddHours(-h) m = Convert.ToInt32(s.Substring(index + 4, 2)) dt = dt.AddMinutes(-m) else: invalidTimeZone = true; elif s[index + 1] == '-': if s.Length - (index + 1) == 5: h = Convert.ToInt32(s.Substring(index + 2, 2)) dt = dt.AddHours(h) m = Convert.ToInt32(s.Substring(index + 4, 2)) dt = dt.AddMinutes(m) else: invalidTimeZone = true if invalidTimeZone == False: dt = dt.Add(TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now)) return dt def update(): global dateTime, uriList, format try: if not NetworkInterface.GetIsNetworkAvailable() and uriList == None: return dt = DateTime() entryList = List[Entry]() for uri in uriList: request = WebRequest.Create(uri) response = request.GetResponse() stream = response.GetResponseStream() doc = XmlDocument() doc.Load(stream) for lwwsXmlNode in doc.SelectNodes("/lwws"): newEntry = Entry() telop = String.Empty title = String.Empty city = String.Empty forecastDate = String.Empty for xmlNode in lwwsXmlNode.ChildNodes: if xmlNode.Name.Equals("title"): title = xmlNode.InnerText if xmlNode.Name.Equals("telop"): telop = xmlNode.InnerText elif xmlNode.Name.Equals("link"): newEntry.Resource = Uri(xmlNode.InnerText) elif xmlNode.Name.Equals("author"): newEntry.Author = xmlNode.InnerText elif xmlNode.Name.Equals("forecastdate"): forecastDate = parse(xmlNode.InnerText).ToString(format) elif xmlNode.Name.Equals("publictime"): newEntry.Created = newEntry.Modified = parse(xmlNode.InnerText) elif xmlNode.Name.Equals("location"): for attr in xmlNode.Attributes: if attr.Name.Equals("city"): city = attr.Value elif xmlNode.Name.Equals("image"): for childXmlNode in xmlNode.ChildNodes: if childXmlNode.Name.Equals("url"): newEntry.ImageUri = Uri(childXmlNode.InnerText) newEntry.Title = city + " - " + telop + " - " + forecastDate if newEntry.Modified > dt: dt = newEntry.Modified if newEntry.Modified > dateTime: entryList.Add(newEntry) if stream != None: stream.Close() if response != None: response.Close() if entryList.Count > 0: Script.Alert(entryList) if dt > dateTime: dateTime = dt else: dateTime = DateTime.Now except: return def onTimedEvent(timer, e): update() timer.Interval = 1000 * 60 * 5 timer.AutoReset = True timer.Start() def onStart(s, e): global timer timer.Interval = 1000 * 60 timer.AutoReset = False timer.Start() def onStop(s, e): global timer timer.Stop() dateTime = DateTime() timer = Timer() timer.Elapsed += onTimedEvent timer.Enabled = False Script.Start += onStart Script.Stop += onStop