携帯に天気情報を送る
たつをさんのtenki-mail.plが使えなくなってたので、勉強もかねてpythonで作ってみた。いろいろ足りてないけど公開してみるテスト。Livedoor天気情報の地域(横浜市南区の天気)とかのURLのみ対応です。
tenki-mail.plと同じように、-mで送信先メールアドレス、-uでLivedoor天気情報のURLを指定します。
でも、おれのNokia端末だと固定長じゃないみたいでずれてしまって悲しいという罠。まあいいさ。
追記: spacerがSpacerになってた。修正して動作確認。
追記2: 頂いたTrackbackに書かれているけれども、Livedoor天気情報は地域の時間単位で気温とかが分かるようなAPIを出してないのです。だからこんなことをしなければならなかったわけで。
追記3: id:pokarimからのコメントに従って修正
#!/usr/bin/env python # -*- coding: utf-8 -*- # 本文例(16文字までの場合): # 0 3 6 912151821 #曇曇曇曇曇曇曇曇 <- 今日の天気 (23:00に送ってもその日の天気) #1820182022212019 <- 気温 # 0 0 0 0 0 0 0 0 <- 降水量 # 003060912151821 #曇曇曇曇曇曇曇曇 <- 明日の天気 #1820182022212019 # 0 0 0 0 0 0 0 0 import urllib, urlparse, re, sys, os from optparse import OptionParser # Mail related lib import smtplib from email.MIMEText import MIMEText from email.Header import Header from email.Utils import formatdate #---- 設定部分 SMTPHost = 'mail.example.jp' # メールサーバ Subject = u'天気' # Subject。uは残して''の中を変えてください FromAddr = 'faw@example.jp' # Fromのアドレス WideDisplay = True # 一行16文字より多く表示可能な携帯の場合Trueに #WideDisplay = False # 一行16文字以内表示する携帯の場合Falseに #---- 設定部分終わり class Tenki(): def __init__(self, date): self.date = date self.tenki = {} self.rain = {} self.temp = {} def setTenki(self, hour, string): string = string.replace(u'晴れ', u'晴') # 文字数削減 string = string.replace(u'曇り', u'曇') self.tenki[hour] = string def setRain(self, hour, string): self.rain[hour] = int(string, 10) def setTemp(self, hour, string): self.temp[hour] = int(string, 10) def getTenki(self): if WideDisplay == True: text = " 0 3 6 9 12 15 18 21\n" # header else: text = " 0 3 6 912151821\n" # header with no space text = text + self.printData(self.tenki) text = text + self.printData(self.temp) text = text + self.printData(self.rain) return text.rstrip() def printData(self, data): string = "" if WideDisplay == True: spacer = " " else: spacer = "" for k, v in data.iteritems(): if isinstance(v, int): string = "%s %2d" % (string, v) else: string = string + spacer + v if isinstance(v, int): return " " + string.strip() + "\n" else: return string.lstrip() + "\n" class TenkiParser(): def __init__(self, options): self.options = options def get(self): html = self.getHTML() data = self.parseHTML(html) text = self.prepareData(data) return text def getHTML(self): if (self.options.verbose): print "HTML get:" + self.options.url # Proxy setting if (self.options.proxies == None): url_file = urllib.urlopen(self.options.url) else: if (self.options.verbose): print "Proxy:" + self.options.proxy url_file = urllib.urlopen(self.options.url, self.options.proxies) html = url_file.read() html = unicode(html, "euc-jp") # Livedoorのページはeuc-jp url_file.close() return html def parseHTML(self, html): r = re.findall(r'</strong> - (.+?)</small>', html) today = Tenki(r[0]) # 今日の天気情報作成 tomorrow = Tenki(r[1]) # 明日の天気情報作成 # 今日と明日の天気情報をセット self.setTenkiData(u'<div style="margin-top:5px;">(.+?)</div>', html, today.setTenki, tomorrow.setTenki) self.setTenkiData(u'<small>(\d+?)mm</small>', html, today.setRain, tomorrow.setRain) self.setTenkiData(u'<small>(\d+?)?</small>', html, today.setTemp, tomorrow.setTemp) self.today = today self.tomorrow = tomorrow def setTenkiData(self, regexLine, html, today, tomorrow): r = re.findall(regexLine, html) for i in range(0, 8): # 今日の分を0-21時まで3時間刻み today(i*3, r[i]) for i in range(8, 16): # 明日の分を0-21時まで3時間刻み tomorrow((i-8)*3, r[i]) def prepareData(self, data): text = self.today.getTenki() + "\n" text = text + self.tomorrow.getTenki() return text class TenkiKeitai(): def __init__(self, options): self.options = options t_parser = TenkiParser(options) self.text = t_parser.get() if (options.nomail == True): self.printMail() exit else: self.sendMail() def printMail(self): if (self.options.verbose): print u"""動作確認用表示""" print self.text.encode("euc-jp") def sendMail(self): if (self.options.verbose): print u"""メール送信:""" + self.options.mailto t = self.text.encode('iso-2022-jp') msg = self.createMessage(t) self.send(msg) def createMessage(self, body): encoding = "ISO-2022-JP" msg = MIMEText(body, 'plain', encoding) msg['Subject'] = Header(Subject, encoding) msg['From'] = FromAddr msg['To'] = self.options.mailto msg['Date'] = formatdate() return msg def send(self, msg): SMTPPort = 25 # 決め打ちだけどいいでしょう s = smtplib.SMTP(SMTPHost, SMTPPort) s.sendmail(FromAddr, self.options.mailto, msg.as_string()) s.close() def main(): usage = "usage: %prog [options]" parser = OptionParser(usage=usage) parser.add_option("-m", "--mailto", dest="mailto", help=u"""送信先メールアドレス""", metavar="MAIL") parser.add_option("-u", "--url", dest="url", help=u"""Live Door 天気情報のURL""") parser.add_option("-p", "--proxy", dest="proxy", help=u"""Proxy設定 ex)http://proxy.example.jp:8080""") parser.add_option("-n", action="store_true", dest="nomail", help=u"""実際にはメールを送信しない(動作確認用)""", default=False) parser.add_option("-v", action="store_true", dest="verbose", help=u"""ログ表示を冗長にする""") parser.add_option("-q", action="store_false", dest="verbose", help=u"""ログ表示を省略する""") (options, args) = parser.parse_args() if ((options.mailto == None) and (options.nomail == False)): print u"""ERROR: -mか-nを設定してください""" parser.print_help() return if (options.url == None): print u"""ERROR: urlを設定してください""" parser.print_help() return if (options.proxy != None): options.proxies = {"http": options.proxy} else: options.proxies = None tenkikeitai = TenkiKeitai(options) if __name__ == '__main__': main()