はじめに
Buzztter の RSS を持ってきて、新しいキーワードを Growl に表示するものを作ってみた。
C++ でも boost::asio とか、 libxml2 とかを使うとけっこうサクっと書ける。ってこともないか。。
ソース
#include <libxml/xmlreader.h> #include <boost/asio.hpp> #include <boost/shared_ptr.hpp> #include <boost/unordered_map.hpp> #include <Growl/Growl.h> static CFTypeRef notifications[] = { CFSTR("Buzz word arrived.") }; static int notifyReading(void *in, char* buf, int len) { return static_cast<std::istream*>(in)->rdbuf()->sgetn(buf, len); } int main(int argc, char *argv[]) { Growl_Delegate delegate; InitGrowlDelegate(&delegate); delegate.applicationName = CFSTR("cppclient"); CFTypeRef keys[] = { GROWL_NOTIFICATIONS_ALL, GROWL_APP_ID }; boost::shared_ptr<const __CFArray> allNotifications( CFArrayCreate( NULL, notifications, sizeof(notifications) / sizeof(notifications[0]), &kCFTypeArrayCallBacks ), &CFRelease ); CFTypeRef values[] = { allNotifications.get(), CFSTR("com.buzzter") }; CFDictionaryRef dict = CFDictionaryCreate(NULL, keys, values, sizeof(keys) / sizeof(CFTypeRef), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); delegate.registrationDictionary = dict; Growl_SetDelegate(&delegate); bool first = true; boost::unordered_map<std::string, bool> seen; while (true) { boost::asio::ip::tcp::iostream s("buzztter.com", "http"); s << "GET /ja/rss HTTP/1.0\r\n" << "Host: buzztter.com\r\n" << "\r\n" << std::flush; std::string line; while (std::getline(s, line)) { if (line == "\r") break; } boost::shared_ptr<xmlTextReader> reader(xmlReaderForIO(notifyReading, NULL, &s, NULL, NULL, 0), xmlFreeTextReader); while (xmlTextReaderRead(reader.get()) == 1) { if (xmlTextReaderDepth(reader.get()) == 3 && std::string("title") == reinterpret_cast<const char*>(xmlTextReaderConstName(reader.get()))) { std::ostringstream title; while (xmlTextReaderRead(reader.get()) == 1 && xmlTextReaderDepth(reader.get()) == 4) { title << std::string(reinterpret_cast<const char*>(xmlTextReaderConstValue(reader.get()))); } if (!first && !title.str().empty() && !seen[title.str()]) { boost::shared_ptr<const __CFString> word( CFStringCreateWithCString( NULL, reinterpret_cast<const char*>(title.str().c_str()), kCFStringEncodingUTF8 ), CFRelease ); Growl_NotifyWithTitleDescriptionNameIconPriorityStickyClickContext( CFSTR("Buzzter"), word.get(), CFSTR("Buzz word arrived."), NULL, 0, false, NULL ); } seen[title.str()] = true; } } first = false; sleep(60); } }
こんな感じでコンパイル
$ g++ -framework Growl -framework Carbon -lboost_system-mt -lxml2 main.cpp