Pythonでネットニュース通知アプリを作ってみた

対象のネットニュースに新着記事が投稿されたらMacの通知センターで知らせてくれるアプリを作ってみました。

#やりたいこと
　① 新着記事が投稿される
　② 通知センターにより、通知される（数秒で通知は消える）
　③ーa 通知アイコンをクリックすると、該当の記事が開く
　③ーb Macが通知に気づかなくても、開かなかった記事は通知ウィンドウにストックされる

　上記仕様を満たしたツールはOS起動時に自動で実行される。
　また、一時的な通信障害等でツールが異常終了した場合でも再起動する。
　
![名称未設定.png](https://qiita-image-store.s3.amazonaws.com/0/54999/9b912ccd-dfd6-9a28-3d7d-a4bb0b7a19dd.png)

#参考にした資料
* [mdfmonitor - ファイルとURLの更新をモニタリング](http://qiita.com/Alice1017/items/326280f057181b3c4606)
* [terminal-notifier で通知センターにコマンドラインから通知](http://heartbeatheart.blogspot.jp/2012/08/terminal-notifier.html)
* [RubyからMacの通知センターで通知する簡単な方法 (AppleScript):](http://qiita.com/zakuroishikuro/items/cfba3e7734036e389768)

#作成手順
全５工程で作成。

1.mdfmonitorを改修
　・改修箇所
　　A. URL更新検知処理
　　B. URL更新履歴情報抽出処理

　A.URL更新検知条件を下記のとおりに変更しました。
　　・既存
　　　　WEBページのヘッダ日付と内容が前回取得時から変化があった場合
　　・今回
　　　　WEBページの記事部分のみに前回取得時から変化があった場合

```py:mdfmonitor.py
    def _check_modify(self, url, o_rbody):
        n_rbody = self._get_text(url)
        if n_rbody == o_rbody:
            return False
        else:
            return True

    def _get_text(self, url):
        try:
            l=[]
            title = urladrs = icon = []
            for line in requests.get(url).iter_lines():
                # get title
                if line.find("<h2>") >= 0:
                    title = re.sub(".*html\">", "", line)
                    title = re.sub("</a>.*", "", title)
                # get url
                if line.find("<h2>") >= 0:
                    urladrs = re.sub(".*href=\"", "", line)
                    urladrs = re.sub("\">.*", "", urladrs)
                # get icon
                if re.search("<img src=.* class=\"pict.*\"", line):
                    icon = re.sub("\s.*<a.*img src=\"", "", line)
                    icon = re.sub("\" width.*", "", icon)

                if title and urladrs and icon:
                    l.append([title, urladrs, icon])
                    title = urladrs = icon = []
            return l
        except requests.exceptions.ConnectionError:
            raise ConnectionError("Monitor can't connect the server of url you added.")
```
新着検知ロジックは検知対象WEBページ依存となるため、どうしても非汎用的になってしまいます。検知対象が増えてきた場合は、検知キーワードは外部ファイル化した方がよいですね。

　B.URL更新履歴情報抽出処理を下記のとおりに変更しました。
　　・既存
　　　　URL更新履歴情報抽出処理
　　・今回
　　　　上記Aで取得済みの新着記事名、新着記事のURL、新着記事の見出し画像を多次元のリストへ格納するのみ。     
     
```py:mdfmoniter.py
    def _diffgen(self):
        l = []
        for new in self.new_rbody:
            if not new in self.old_rbody:
                l.append(new)
        return l
```
2.MAC通知センター呼び出しコマンド文の出力処理
 上記１のmdfmoniter.pyを呼び出すpythonファイルです。

 terminal-notifierの実行コマンド文を作成後、そのまま実行したかったのですが、自動起動で実行させるとなぜかterminal-notifierが異常終了します。そのため、コマンド実行はここでは行わず、cronによる実行としました。

```py:newsmoniter.py
#!/usr/bin/python
#coding: utf-8

import os
from mdfmonitor import URLModificationMonitor

# create Watcher instnce
monitor = URLModificationMonitor()

# append file to mdfmonitor instance
monitor.add_url("http://blog.esuteru.com")

for mdf in monitor.monitor():
    for title, urladrs, icon in mdf.diff:
        cmd = "/usr/local/bin/terminal-notifier -title new! -message {0} -open {1} -sound Submarine -appIcon {2}".format(title, urladrs, icon)
        f2 = open("/usr/local/bin/news_cmd.sh", "w")
        f2.write(cmd)
        os.chmod("/usr/local/bin/news_cmd.sh", 0777)
        f2.close()
```

3.newsmoniter.py死活監視ツール
　一時的な通信異常等で上記newsmoniter.pyが異常終了し、プロセスが消滅する場合があります。本ツールは、消滅を検知し、再度起動させるためのツールです。

```bash:autorun.sh
#!/bin/sh

while true;
do
    ps -ef | grep newsmoniter.py | grep -v grep
    if [ $? = "1" ]; then
        echo "restart newsmoniter.py"
        /usr/local/bin/newsmoniter.py
    fi
    sleep 10
done
```

4.OS起動時に自動起動するための設定
 OS標準機能を利用し、OS起動時に上記autorun.shが起動されるように設定

```bash:/Library/StartupItems/Newsmoniter
StartService()
{
    /usr/local/bin/autorun.sh
}
```

5.cronによるMAC通知センター呼び出しコマンドの実行

```bash:cron
* * * * * /usr/local/bin/news_cmd.sh > /dev/null 2>&1; rm -f /usr/local/bin/news_cmd.sh > /dev/null 2>&1
```

#今後やりたいこと
* 新着記事検知処理の汎用化
* 2ちゃんねる掲示板の投稿検知機能(投稿速度の遅いスレッド限定）
* 本ツールをpepper君へ移植し、新着記事は胸のタブレットに表示させる

#動作確認環境
* OS X Mavericks 10.9.5
* Python 2.7.5
* terminal-notifier 1.6.1