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

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

サムネイル画像はもちろん、Diggの「票(digg)」の数も表示することが出来ます。

ちなみに、このDiggの新着を表示する際はRSSの解析結果をApricotに渡していますが、通常のRSSの場合はOPMLファイルに追加して対応できます。しかし、Diggの「票(digg)」のような特殊なタグがRSSに含まれている場合はアドオンのような形で対応させています。


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

Digg
http://digg.com/


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

# -*- coding: utf-8 -*-
# Digg.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, Int32, Uri, DateTime, TimeSpan
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, Match
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 update():
	try:
		global dateTime
		
		if not NetworkInterface.GetIsNetworkAvailable():
			return
		
		request = WebRequest.Create("http://feeds.digg.com/digg/popular.rss")
		response = request.GetResponse()
		s = response.GetResponseStream()
		doc = XmlDocument()
		doc.Load(s)
		
		entryList = List[Entry]()
		
		for itemXmlNode in doc.SelectNodes("/rss/channel/item"):
			newEntry = Entry()
			count = 0
			
			for xmlNode in itemXmlNode.ChildNodes:
				if xmlNode.Name.Equals("title"):
					newEntry.Title = xmlNode.InnerText
				elif xmlNode.Name.Equals("link"):
					newEntry.Resource = Uri(xmlNode.InnerText)
				elif xmlNode.Name.Equals("description"):
					newEntry.Description = xmlNode.InnerText
				elif xmlNode.Name.Equals("author"):
					newEntry.Author = xmlNode.InnerText
				elif xmlNode.Name.Equals("pubDate"):
					newEntry.Created = newEntry.Modified = DateTime.ParseExact(xmlNode.InnerText, "ddd, dd MMM yyyy HH:mm:ss zz00", CultureInfo.InvariantCulture.DateTimeFormat, DateTimeStyles.None)
				elif xmlNode.Name.Equals("media:thumbnail"):
					for xmlAttribute in xmlNode.Attributes:
						if xmlAttribute.Name.Equals("url"):
							newEntry.ImageUri = Uri(xmlAttribute.Value)
				elif xmlNode.Name.Equals("digg:diggCount"):
					count = Int32.Parse(xmlNode.InnerText)
			
			newEntry.BaseUri = Uri("http://digg.com/")
			
			if String.IsNullOrEmpty(newEntry.Title):
				newEntry.Title = "N/A"
			
			if count > 0:
				newEntry.Score = count
			
			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 * 10
	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(48, 0, 0)
timer = Timer()
timer.Elapsed += onTimedEvent
timer.Enabled = False
Script.Instance.Start += onStart
Script.Instance.Stop += onStop