1. Top » 
  2. 録画ッター Twitterで観たいテレビ番組をつぶやいたら自動で録画予約してくれます

Twitterで観たいテレビ番組をつぶやいたら、自動で録画予約してくれる「録画ッター」を作りました。

※録画ッターはバージョンアップしました。最新バージョンはこちらです。

6月5日発売の「Linux100%」で「録画ッター」でTwitterでつぶやくことでテレビを録画予約するシステムを構築する手順が紹介されます。
※開始時間が過ぎていた場合は途中から録画予約されるように変更しました。

こんなことができます。

観たいTV番組名をつぶやくと勝手に録画予約してくれます。

たとえば、ダウンタウンDXを観たいと思ったら、こんな感じでつぶやくだけでOK


使い方

録画ッターは、つぶやきに「TV!」と「観たい」で囲まれる部分があると反応します。
「TV! ダウンタウンDX観たい」とつぶやいた場合、番組表から24時間以内にある「ダウンタウンDX」を番組名に含む番組を探して録画予約してくれます。
録画予約が成功したら、録画ッターが録画予約が成功したとつぶやいてくれます。

番組が見つからなかった場合

入力ミス等で番組が見つからなかった場合でも、録画ッターが番組が見つからなかったとつぶやきで教えてくれます。

番組がいっぱい見つかった場合

24時間以内に同じ番組名がある場合等は、録画ッターはどれを録画予約してよいのか分からない為、詳細情報をつぶやきで要求します。

こんな場合でも、録画ッターは番組名以外にも細かく指示できるので安心です。
たとえば、
「TV! ([CS]なんかチャンネル)23時なんかすぺしゃる観たい」とつぶやくと
「CS」放送の「なんかチャンネル」というチャンネルの「23時」台に始まる「なんかすぺしゃる」という番組を録画予約してくれます。
※番組名のみ必須で他はオプションです。


設定方法

1. このシステムはEPGrecと連動して動きます。

まずは、EPGrecで地デジを録画するシステムを作ってください。
EPGrecについてはこちらを参考に http://www.mda.or.jp/epgrec/

録画PCの製作はこちらが参考になると思います
地デジ録画機能(PT2)付き大容量省スペース省電力の最強NAS

2. EPGrecと同じデータベースに、録画ッター用のテーブルを作成します。

create table twitter(
  id bigint
)

3. 録画ッターのプログラムをcronなどで定期実行するように登録してください。

プログラムはrubyで作りました。(rubyで作ったサービスの2作目です。 1作目はこちら今平成何年?


#! ruby -Ku
require 'rubygems'
require 'mysql'
require 'twitter'
require 'jcode'
require 'httpclient'

#環境設定
MYSQL_HOST = ’MySQLサーバーのIPアドレス'
MYSQL_USER = 'MySQLのユーザー名'
MYSQL_PASSWORD = 'MySQLのパスワード'
MYSQL_DATABASE = 'MySQLのデータベース名'
TWITTER_ID = 'ツイッターのID'
TWITTER_PASSWORD = 'ツイッターのパスワード'
EPGREC_URL = 'EPGrecのIPアドレス'

#つぶやきをパースする
def parse_tweet(text)
  text.match(/TV! (\(.+\))?((\d+)時)?(.+)観たい/)
end

#つぶやく
def tweet(client, text)
  client.update text
end

#SQLエスケープ。こんなんでいいのか?
def sql_escape(str)
  str.gsub(/[']/) {|ch| ch + ch }
end

#つぶやきを元にSQL作成
def make_sql(n)
  sql = "SELECT id, title, description, starttime, endtime, channel_id, category_id
FROM `Recorder_programTbl` p
WHERE
 endtime > CURRENT_TIMESTAMP
 AND starttime < DATE_ADD(CURRENT_TIMESTAMP, INTERVAL 1 DAY) \n"

 #タイトルで検索
 if(!n[4].nil?) then
  sql << " AND title LIKE '%" + sql_escape(n[4]).tr('0-9a-zA-Z','0-9a-zA-Z') + "%' \n"
 end

 #時間指定があった場合
 if(!n[3].nil?) then
  sql << " AND DATE_FORMAT(starttime, '%k') = " + n[3] + " \n"
 end

 #番組名があった場合
 if(!n[1].nil?) then

   tmp = n[1][1..-2].match(/(\[(.+)\])?(.*)/)

   sql << " AND EXISTS(
     SELECT *
     FROM `Recorder_channelTbl` c
     WHERE
       p.channel_id = c.id \n"
   if !tmp[3].nil? then
    sql << " AND c.name LIKE '%" + sql_escape(tmp[3]).tr('0-9a-zA-Z','0-9a-zA-Z') + "%' \n"
   end
   if !tmp[2].nil? then
    sql << " AND c.type = '" + sql_escape(tmp[2]) + "' \n"
   end
   sql << ") \n"
 end
 p sql
 sql
end

#録画予約する
def rec(pid)
  hc = HTTPClient.new
  rs = hc.get_content('http://' + EPGREC_URL + '/epgrec/simpleReservation.php?program_id=' + pid.to_s)
  puts rs
  rs.match(/^error/i).nil?
end

#カスタム録画予約する
def rec_custom(pid, ptitle, pdescription, pstarttime, pendtime, pchannel_id, pcategory_id)
  hc = HTTPClient.new
  starttime = Time.now + 3 * 60
  pendtime = Time.parse pendtime
  rs = hc.post_content('http://' + EPGREC_URL + '/epgrec/customReservation.php?' ,\
    {'program_id' => pid.to_s ,\
     'syear' => starttime.year.to_s ,\
     'smonth' => starttime.month.to_s ,\
     'sday' => starttime.day.to_s ,\
     'shour' => starttime.hour.to_s ,\
     'smin' => starttime.min.to_s ,\
     'eyear' => pendtime.year.to_s ,\
     'emonth' => pendtime.month.to_s ,\
     'eday' => pendtime.day.to_s ,\
     'ehour' => pendtime.hour.to_s ,\
     'emin' => pendtime.min.to_s ,\
     'channel_id' => pchannel_id.to_s ,\
     'record_mode' => 0, \
     'title' => ptitle ,\
     'description' => pdescription ,\
     'category_id' => pcategory_id.to_s }
    )
    puts rs
  rs.match(/^error/i).nil?
end

#mysql接続
my = Mysql::new MYSQL_HOST, MYSQL_USER, MYSQL_PASSWORD
my.query 'SET NAMES utf8'
my.query 'use ' + MYSQL_DATABASE

#twitterに接続
httpauth = Twitter::HTTPAuth.new TWITTER_ID, TWITTER_PASSWORD
client = Twitter::Base.new httpauth

#前回処理したIDをゲット
pre_id = nil
my.query('select id from twitter').each do |twitter|
  pre_id = twitter[0].to_i
end
#もしなかったらゼロで作る
if pre_id.nil? then
  pre_id = 0
  my.query 'insert into twitter(id) values(' + pre_id.to_s + ')'
end

cur_id = nil
client.user_timeline.reverse.each {|tweet|
  t_id = tweet.id.to_i
  if t_id > pre_id then

    t_text = tweet.text

    cur_id = t_id if cur_id.nil? || cur_id < t_id

    parsed_tweet = parse_tweet(t_text)
    if(parsed_tweet.nil?) then
      next
    end
    sql = make_sql parsed_tweet
    res = my.query(sql)

    resArray = []
    res.each do |col|
      pid = col[0]
      ptitle = col[1]
      pdescription = col[2]
      pstarttime = col[3]
      pendtime = col[4]
      pchannel_id = col[5]
      pcategory_id = col[6]
      puts pid + ' / ' + ptitle + ' / ' + pdescription + ' / ' + pstarttime + '/' + pendtime + '/' + pchannel_id + '/' + pcategory_id

      resArray << [pid, ptitle, pdescription, pstarttime, pendtime, pchannel_id, pcategory_id]
    end

    if(resArray.size == 0) then
      #番組とれなかったとつぶやく
      tweet client, 'そんな番組無いよ by 録画ッター.'
    elsif(resArray.size == 1) then
      #録画する
      #もし開始時間が過ぎていた場合でも、終了5分以上前なら途中から録画を開始する

      if(Time.parse(resArray[0][3]) < Time.now && (Time.parse(resArray[0][4]) - 5 * 60) > Time.now) then
        #Time.parse("%Y-%m-%d %H:%M:%S").to_s
        rs = rec_custom(resArray[0][0], resArray[0][1], resArray[0][2], resArray[0][3], resArray[0][4], resArray[0][5], resArray[0][6])
        #録画結果をつぶやく
        if rs then
          tweet client, resArray[0][1] + 'を途中からだけど録画予約したよ。 by 録画ッター.'
        else
          tweet client, resArray[0][1] + 'の録画予約失敗した…orz  by 録画ッター.'
        end
      else
        rs = rec(resArray[0][0])
        #録画結果をつぶやく
        if rs then
          tweet client, resArray[0][1] + 'を録画予約したよ。 by 録画ッター.'
        else
          tweet client, resArray[0][1] + 'の録画予約失敗した…orz  by 録画ッター.'
        end
      end

    elsif(resArray.size > 1) then
      #いっぱい見つかった事をつぶやく
      tweet client, 'もっと詳しく! by 録画ッター.'
    end

  end
}

#今回処理したIDを保存
if !cur_id.nil? && pre_id < cur_id then
  my.query 'update twitter set id=' + cur_id.to_s
  my.query 'commit'
end


なんだかんだ

最近のTwitter関連サービスブームに乗っかって作ってみました。
つか、普通にepgrec使ってリモート録画すれば良いんだけど。オシャレ機能と言う事で。
epgrecをインターネットに公開できない(したくない)場合等にも使えるかもです。

※つぶやきありがとうございます。
TOPSY 録画ッター Twitterで観たいテレビ番組をつぶやいたら自動で録画予約してくれます - Do I like programming?
TOPSY Twitterで観たいテレビ番組をつぶやいたら、自動で録画予約してくれる「録画ッター」を作りました。 - Do I like programming?

Comment

[…] やいたら、自動で録画予約してくれる「録画ッター」を作りました。 録画ッター […]

[…] [from otsune] 録画ッター Twitterで観たいテレビ番組をつぶやいたら自動で録画予約してくれます – Do I like programming? Share this post! […]

[…] Twitterで観たいテレビ番組をつぶやいたら、自動で録画予約してくれる「録画ッター」を作りました。 twitter […]

[…] 前号に続いて、リナックスマニアックスというコーナーで紹介してもらいます。 前号で構築したPT2NASに、録画ッターを設定して、Twitterでつぶやいて録画予約する機能をつけるまでの手順が紹介されます。 […]

はじめまして。linux100%を購入してPT2NASに憧れ作成しました。ありがとうございます。六月号を購入して録画ッターに挑戦しているのですが途中からよくわからないエラーが。もしよければヒントをいただけないでしょうか?
SELECT id, title, description, starttime, endtime, channel_id, category_id\nFROM `Recorder_programTbl` p\nWHERE\n endtime > CURRENT_TIMESTAMP\n AND starttime < DATE_ADD(CURRENT_TIMESTAMP, INTERVAL 1 DAY) \n AND title LIKE '%ゲゲゲの女房%' \n"
151 / 【解】【字】【デ】連続テレビ小説 ゲゲゲの女房(102)「プロダクション旗揚げ」 / 安来の飯田家から村井家に、身重の布美枝(松下奈緒)を手伝わせるため、いずみ(朝倉えりか)が源兵衛(大杉漣)によって送り込まれてくる。 / 2010-07-24 08:00:00/2010-07-24 08:15:00/1/6
168 / 【解】【字】【デ】連続テレビ小説 ゲゲゲの女房(102)「プロダクション旗揚げ」 / 安来の飯田家から村井家に、身重の布美枝(松下奈緒)を手伝わせるため、いずみ(朝倉えりか)が源兵衛(大杉漣)によって送り込まれてくる。 / 2010-07-24 12:45:00/2010-07-24 13:00:00/1/6
/var/lib/gems/1.8/gems/twitter-0.9.8/lib/twitter.rb:95:in `raise_errors': (403): Forbidden – Status is a duplicate. (Twitter::General)
from /var/lib/gems/1.8/gems/twitter-0.9.8/lib/twitter.rb:75:in `make_friendly'
from /var/lib/gems/1.8/gems/twitter-0.9.8/lib/twitter/request.rb:42:in `perform'
from /var/lib/gems/1.8/gems/twitter-0.9.8/lib/twitter/request.rb:10:in `post'
from /var/lib/gems/1.8/gems/twitter-0.9.8/lib/twitter/base.rb:378:in `perform_post'
from /var/lib/gems/1.8/gems/twitter-0.9.8/lib/twitter/base.rb:39:in `update'
from /home/do603/twitter_rec.rb:24:in `tweet'
from /home/do603/twitter_rec.rb:185
from /home/do603/twitter_rec.rb:128:in `each'
from /home/do603/twitter_rec.rb:128

本誌の通り最後まで実行し最初はうまくいったのですが途中からよくわからなく、、上記のエラーは手動でsh twitter_rec.shを行った際にでてきます。どうしたらcronはうまく動作しておりません。

  • 2010/07/24 4:00 AM |
  • どおお

どおおさん

たぶん、Twitterの仕様変更だと思うんですが、同じつぶやきをした場合にエラーになってしまうのが原因だと思います。
実はもうすぐ公開する録画ッターver2ではこの問題も含めて修正済なので、そちらを使用する事をおすすめします。

>どうしたらcronはうまく動作しておりません。
cronは動作してない?してる?

まだ、正式には公開してないですが、↓が録画ッターver2です。
http://kissrobber.appspot.com/rokugatter/

  • 2010/07/25 8:58 PM |
  • admin

はじめまして、録画ッターVer2を改造して、CentOS5.5環境でメールで録画予約できるプログラムを作ってみました。
録画予約の部分(class)はそのまま使わせていただいております。改造したプログラムを公開してもよろしいでしょうか?

また、録画ッターVer2で下記の点が気になりました。

1.cron.phpのfunction getRpc()で使われている変数$clinetは、global $client;やxmlrpc.class.php内で使用されている$clientの事でよいでしょうか?

2.httprpc.class.php内の関数mb_convert_kana()内の第二引数は、Aを”A”と変更してよいでしょうか?

3.abstractrpc.class.phpは文末に”?>”を追記してよいでしょうか?

よろしくお願いします。

  • 2010/10/31 4:33 PM |
  • PHP初心者

PHP初心者さん

>改造したプログラムを公開してもよろしいでしょうか?
はいどうぞ、必須では無いですがこちらにリンク張ってくれたりとか、録画ッターを改造して作った事等を書いといてくれるとちょっとうれしいです。

>1.cron.phpのfuncti…
global $client;はそうですが、
xmlrpc.class.phpは違います。XMLRPCはEPGrecのAPI機能を使う為のクラスですが、上手く動かなかったので使ってない機能です。

>2.httprpc.class.php内の関数mb_convert_…
はい、これ間違ってますね。”A”が正しいと思います。ありがとうございます。

>3.abstractrpc.class.phpは文末に…
はい。これで何で動いてるのか不思議だ。

録画ッターver2では、録画予約をTwitter経由で行う為に、OAuth認証のキーをプログラムに含めて配布する事ができなかったので録画つぶやきをGAE経由にするという面倒くさい事になってます。
ご自身でプログラム修正して、対応できる場合は、もちろんそちらの方が良いと思います。

  • 2010/11/02 1:27 AM |
  • admin

改造プログラムの公開を了承していただきありがとうございます。
恥ずかしながら下記URLにて公開しました。
http://www.sky.sannet.ne.jp/kn_ishi/centos55_pt2_epgrec_recbymail.html

  • 2010/11/05 8:52 PM |
  • PHP初心者
コメントフォーム
このエントリへコメントを書く
名前 (required)
Mail (will not be published) (required)
ウェブサイト
(必須)

トラックバックURL: