let g:fastladder_server = 'http://reader.livedoor.com'
とvimrcに書いておくと
:FastLadder
でLivedoorReaderのフィードが見れます。今後はFastLadderやLivedoorReaderの様にフォルダ単位の閲覧が出来る様に改良して行く予定です。
let g:fastladder_server = 'http://reader.livedoor.com'
とvimrcに書いておくと
:FastLadder
でLivedoorReaderのフィードが見れます。
diff -ur Coro-5.132.orig/Coro/libcoro/coro.c Coro-5.132/Coro/libcoro/coro.c
--- Coro-5.132.orig/Coro/libcoro/coro.c 2008-11-19 11:50:13.000000000 +0900
+++ Coro-5.132/Coro/libcoro/coro.c 2009-06-19 15:01:16.140625000 +0900
@@ -228,6 +228,9 @@
#if __CYGWIN__
ctx->env[7] = (long)((char *)sptr + ssize) - sizeof (long);
ctx->env[8] = (long)coro_init;
+ #elif defined(__MINGW32__)
+ ctx->env[4] = (int)((unsigned char *)sptr + ssize);
+ ctx->env[5] = (long)coro_init;
#elif defined(_M_IX86)
((_JUMP_BUFFER *)&ctx->env)->Eip = (long)coro_init;
((_JUMP_BUFFER *)&ctx->env)->Esp = (long)STACK_ADJUST_PTR (sptr, ssize) - sizeof (long);
mingw32のjumpbufは4番目がEipで5番目がEspだったはず。
if ($GCC) {
my $dllname = $self->{BASEEXT} . "." . $self->{DLEXT};
$dllname =~ /(....)(.{0,4})/;
my $baseaddr = unpack("n", $1 ^ $2);
$otherldflags .= sprintf("-Wl,--image-base,0x%x0000 ", $baseaddr);
}
なので、Coro::Event が使っている Event というモジュールと --image-base がバッティングして起動時にメモリロケーション不正参照のエラーが起きる。
--- MM_Win32.pm.orig 2009-06-22 17:48:43.906250000 +0900
+++ MM_Win32.pm 2009-06-22 17:49:05.703125000 +0900
@@ -307,12 +307,12 @@
# we try to overcome non-relocateable-DLL problems by generating
# a (hopefully unique) image-base from the dll's name
# -- BKS, 10-19-1999
- if ($GCC) {
- my $dllname = $self->{BASEEXT} . "." . $self->{DLEXT};
- $dllname =~ /(....)(.{0,4})/;
- my $baseaddr = unpack("n", $1 ^ $2);
- $otherldflags .= sprintf("-Wl,--image-base,0x%x0000 ", $baseaddr);
- }
+# if ($GCC) {
+# my $dllname = $self->{BASEEXT} . "." . $self->{DLEXT};
+# $dllname =~ /(....)(.{0,4})/;
+# my $baseaddr = unpack("n", $1 ^ $2);
+# $otherldflags .= sprintf("-Wl,--image-base,0x%x0000 ", $baseaddr);
+# }
push(@m,'
# This section creates the dynamically loadable $(INST_DYNAMIC)
SYNOPSISの例でもちゃんと動きます。mumbles-project.orgさらにそのDBusインタフェース上ではアイコン表示をサポートしていた為、これは!と思いGitHubのGrowlアプリケーションを作ってみました。
a plugin driven, modern notification system for Gnome
http://www.mumbles-project.org/
from MumblesPlugin import *
import dbus
import gnomevfs
import os
import urllib
class GithubMumbles(MumblesPlugin):
plugin_name = 'GithubMumbles'
dbus_interface = 'com.github.DBus'
dbus_path = '/com/github/DBus'
icons = {'github' : 'github.png'}
__url = None
def __init__(self, mumbles_notify, session_bus):
self.signal_config = {
'Notify': self.Notify,
'NotifyNum': self.NotifyNum
}
MumblesPlugin.__init__(self, mumbles_notify, session_bus)
self.add_click_handler(self.onClick)
def NotifyNum(self, num):
self.__url = 'http://github.com/'
icon = self.get_icon('github')
title = 'Github'
msg = str(num)+' new messages!'
self.mumbles_notify.alert(self.plugin_name, title, msg, icon)
def Notify(self, link, author, text):
self.__url = link
path = os.path.join(PLUGIN_DIR_USER, 'icons', 'github-%s' % author)
if os.path.exists(path):
self.icons[author] = 'github-%s' % author
icon = self.get_icon(author)
else:
icon = self.get_icon('github')
self.mumbles_notify.alert(self.plugin_name, author, text, icon)
def onClick(self, widget, event, plugin_name):
if event.button == 3:
self.mumbles_notify.close(widget.window)
else:
self.open_url(self.__url)
def open_url(self, url):
mime_type = gnomevfs.get_mime_type(url)
application = gnomevfs.mime_get_default_application(mime_type)
os.system(application[2] + ' "' + url + '" &')
インタフェースはリンク、作者、本文のみとしました。これをegg形式にビルドしてmumblesのpluginフォルダに置くと、上記のインタフェース呼び出しによりGrowlが表示されます。
#!/usr/bin/env python
UPDATE_INTERVAL=1000 # 10 minutes
MAX_NOTIFICATIONS = 40
DEBUG = True
##################################################
import os
import sys
import time
import getopt
import rfc822
import calendar
import urllib
import feedparser
import dbus
import dbus.service
from dbus.mainloop.glib import DBusGMainLoop
import gobject
from BeautifulSoup import BeautifulSoup
from pit import Pit
GITHUB_DBUS_INTERFACE = 'com.github.DBus'
GITHUB_DBUS_PATH = '/com/github/DBus'
config = Pit.get('github.com', {'require': {
'user' : 'user id on github.com',
'token' : 'user token on github.com'
}})
class Usage(Exception):
def __init__(self, msg=None):
app = sys.argv[0]
if msg != 'help':
self.msg = app+': Invalid options. Try --help for usage details.'
else:
self.msg = app+": DBus notifications on new github messages.\n"
class GithubCheck(dbus.service.Object):
def __init__(self):
session_bus = dbus.SessionBus()
bus_name = dbus.service.BusName(GITHUB_DBUS_INTERFACE, bus=session_bus)
dbus.service.Object.__init__(self, bus_name, GITHUB_DBUS_PATH)
self.interval = UPDATE_INTERVAL
self.notifyLimit = MAX_NOTIFICATIONS
self.debug = DEBUG
self.lastCheck = None
self.minInterval = 60000 # 1 minute min refresh interval
if self.interval < self.minInterval:
print "Warning: Cannot check github more often than once a minute! Using default of 1 minute."
self.interval = self.minInterval
self._check()
@dbus.service.signal(dbus_interface=GITHUB_DBUS_INTERFACE, signature='sss')
def Notify(self, link, author, text):
pass
@dbus.service.signal(dbus_interface=GITHUB_DBUS_INTERFACE, signature='i')
def NotifyNum(self, num):
pass
def _check(self):
if self.debug:
if self.lastCheck:
print "checking feed (newer than %s):" %(self.lastCheck)
else:
print "checking feed:"
try:
items = feedparser.parse("http://github.com/%s.private.atom/?token=%s" % (config['user'], config['token']))['entries']
except Exception, e:
items = []
if self.lastCheck:
lastCheck = calendar.timegm(time.localtime(calendar.timegm(rfc822.parsedate(self.lastCheck))))
for item in items:
if calendar.timegm(item.published_parsed) < lastCheck:
items.remove(item)
self.lastCheck = rfc822.formatdate()
num_notifications = len(items)
if num_notifications > MAX_NOTIFICATIONS:
if self.debug:
print "%s new entries\n" %(num_notifications)
self.NotifyNum(num_notifications)
elif num_notifications < 0:
if self.debug:
print "no new entries\n"
else:
for item in items:
path = os.path.join(os.path.expanduser('~'), '.mumbles', 'plugins', 'icons', 'github-%s' % item['author'])
if not os.path.exists(path):
html = urllib.urlopen('http://github.com/%s' % item['author']).read()
soup = BeautifulSoup(html)
img = soup.findAll('div', {'class':'identity'})[0].find('img')['src']
img = img.replace("?s=50&", "?s=30&");
urllib.urlretrieve(img, path)
self.Notify(item['link'], item['author'], item['title'])
time.sleep(6)
gobject.timeout_add(self.interval,self._check)
if __name__ == '__main__':
DBusGMainLoop(set_as_default=True)
try:
try:
opts, args = getopt.getopt(
sys.argv[1:], "hp", ["help"])
except getopt.GetoptError:
raise Usage()
for o, a in opts:
if o in ("-h", "--help"):
raise Usage('help')
else:
raise Usage()
except Usage, err:
print >> sys.stderr, err.msg
sys.exit(2)
t = GithubCheck()
try:
loop = gobject.MainLoop()
loop.run()
except KeyboardInterrupt:
print "githubcheck shut down..."
except Exception, ex:
print "Exception in githubcheck: %s" %(ex)
だらだらとしたコードですが、大体分かってもらえるかと思います。pitを使っているので初回起動のみユーザとトークンをエディタで入力する必要があります。トークンはGitHubのダッシュボードにあるRSSアイコンのリンク先URLに含まれています。これで快適になりました。
mattn's mumbles-github-growler at master - GitHubよろしければどうぞ。
github growler using mumbles plugin and checker script.
http://github.com/mattn/mumbles-github-growler/tree/master
このブログを応援する