引用βの新着を表示するApricot用アドオン

引用βの新着を表示するApricot用アドオンを書いてみました。

ちなみに処理内容は、引用βのRSSから新着の引用文を正規表現で抜き取ってApricot側に渡してます。そんだけ。


デスクトップマスコット「Apricot」はこちら
アプリコタン.NET (http://www.apricotan.net/)


引用β
http://inyo.jp/


下記のスクリプトUTF-8で保存して、Scriptsフォルダに入れればApricotのキャラクターが新着を喋るようになります。

# -*- coding: utf-8 -*-
# inyo.py
# Copyright 〓 Masaaki Kawata All rights reserved.

import clr
clr.AddReferenceByPartialName("mscorlib")
clr.AddReferenceByPartialName("System")
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.Diagnostics import Trace
from System.Globalization import CultureInfo, DateTimeStyles
from System.Text.RegularExpressions import Regex, RegexOptions, Match, Capture
from System.Timers import Timer
from System.Net import WebRequest, WebResponse
from System.Net.NetworkInformation import NetworkInterface
from System.Xml import XmlDocument
from Apricot import Entry, Word, Script

def parse(s):
	dt = DateTime()
	invalidTimeZone = False
	index = s.Length;
	match = Regex.Match(s, "\\s[\\+\\-0-9A-Z]+$")

	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:
				dt = dt.AddHours(-Convert.ToInt32(s.Substring(index + 2, 2)))
				dt = dt.AddMinutes(-Convert.ToInt32(s.Substring(index + 4, 2)))
			else:
				invalidTimeZone = true;
		elif s[index + 1] == '-':
			if s.Length - (index + 1) == 5:
				dt = dt.AddHours(Convert.ToInt32(s.Substring(index + 2, 2)))
				dt = dt.AddMinutes(Convert.ToInt32(s.Substring(index + 4, 2)))
			else:
				invalidTimeZone = true

	if invalidTimeZone == False:
		dt = dt.Add(TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now))

	return dt

def update():
	try:
		global dateTime
		
		if not NetworkInterface.GetIsNetworkAvailable():
			return
		
		request = WebRequest.Create("http://feeds.feedburner.com/inyo/everyone")
		response = request.GetResponse()
		s = response.GetResponseStream()
		doc = XmlDocument()
		doc.Load(s)
		
		entryList = List[Entry]()
		
		for itemXmlNode in doc.SelectNodes("/rss/channel/item"):
			newEntry = Entry()
			id = String.Empty
			
			for xmlNode in itemXmlNode.ChildNodes:
				if xmlNode.Name.Equals("link"):
					newEntry.Resource = Uri(xmlNode.InnerText)
				elif xmlNode.Name.Equals("description"):
					match = Regex.Match(xmlNode.InnerText, "<p>(?<1>.+?)</p>", RegexOptions.Singleline)
					if match.Success:
						for capture in match.Groups[1].Captures:
							newEntry.Title = capture.Value
							break
				elif xmlNode.Name.Equals("pubDate"):
					newEntry.Created = newEntry.Modified = parse(xmlNode.InnerText)
				elif xmlNode.Name.Equals("author"):
					newEntry.Author = xmlNode.InnerText
			
			newEntry.BaseUri = Uri("http://inyo.jp/")
			newEntry.BaseTitle = "引用β"
			newEntry.ImageUri = Uri("http://inyo.jp/assets/quote.r1903.gif")
			
			if newEntry.Created > dateTime:
				entryList.Add(newEntry)
		
		if entryList.Count > 0:
			Script.Instance.Alert(entryList)
			dateTime = DateTime.Now
			
			isActivated = False
			for entry in entryList:
				wordList = List[String]()
				for word in Script.Instance.Words:
					if Regex.IsMatch(entry.Title, Regex.Escape(word.Name)) and wordList.Contains(word.Name) == False:
						wordList.Add(word.Name)
				if wordList.Count > 0 and isActivated == False:
					isActivated = Script.Instance.TryEnqueue(Script.Instance.Prepare(wordList, None, True))
		
		if s != None:
			s.Close()
			
		if response != None:
			response.Close()

	except Exception, e:
		Trace.WriteLine(e.clsException.Message)
		Trace.WriteLine(e.clsException.StackTrace)

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.Now - TimeSpan(24, 0, 0)
timer = Timer()
timer.Elapsed += onTimedEvent
timer.Enabled = False
Script.Instance.Start += onStart
Script.Instance.Stop += onStop