2020/03/10
※ 2022/05/30から Google がセキュリティを強化したため、この方法は使用できなくなりました。
地デジ録画サーバー(LinuxMint17.1+PT2+EpgRec)で recbymail の見直し。
TwitterでEPGrecの録画予約ができる"録画ッター"を参考にして、メールでEPGrecの録画予約をできるようにしてみました。
"録るメーラー"と名付けました。
"録画ッター"というすばらしいソフトの存在を知り、ならば、EPGrecをメールで録画予約するソフトはないかと探しましたが見つかりませんでした。ないのなら作ってみようと興味が沸き、PHPを勉強して改造してみました。メールを通してサーバーと通信できるので改造次第でいろいろ応用できると思います。市販品にはない自作の楽しみはこういうところにありますね。おきまりですが、このソフトが原因で損害が発生しても責任は負えませんので、使用は自己責任でお願いします。
 

目次

1.仕様

2.録るメーラー用のメールアドレスを準備する。

3.どうやってメールを受信するか。

  (1)OS(CentOS)が"ssl"をサポートしているか確認する。

  (2)"php-pear-Net-POP3"をインストールする。

4.どうやってメールを送信するか。


PHPでGmailなどのPOP over ssl / SMTP over sslサーバーからメールを送受信する方法をまとめました。

5.「録るメーラー」(recbymail.php)をインストールする。

  (1)プログラムを準備する。

  (2)環境設定を行う。

6.「録るメーラー」の動作確認を行う。

7.cronに登録する。

8.プログラムのソース

  recbymail.config.php


recbymail.help.txt

  recbymail.php

  abstractrpc.class.php

  httprpc.class.php

  xmlrpc.class.php
 
仕様
Linux環境で動作すると思います。
EPGRECへのリクエストは件名(Subject:)に書いてください。本文は無視されます。
録るメーラーは、メールヘッダーの"Subject:予約番組名"などの件名を解析してリクエストに応答します。
キーワード"Subject:"が発見できないと動作できません。
録画用のアドレスにリクエストメールを送ると、結果が返信されます。
録るメーラーは、メールヘッダーの"Return-Path:<mailaddress>"に対して返信を行います。
キーワード"Return-Path:<>"が発見できないとメールを返信できません。
うまく動かないときは"DEBUGSW"を"on"にして、受信したメールの内容をよく確認してください。
 
録るメーラー用のメールアドレスを準備する。
録るメーラーが使用するメールアドレスが必要です。さらに、録るメーラーがメールを受信するために、そのメールサーバーはPOP3接続を許可している必要があります。また、メールを送信するために、SMTPサーバーも必要です。POP3サーバーとSMTPサーバーは別々でもかまいませんが、Gmail(Googleメール)のサーバーはその両方の接続を許可していることがわかりましたので、Gmailのメールアカウントを取得しました。
アカウントを登録して、POP3とSMTPの接続を許可する設定を行いました。
受信したメールはサーバーに残さず削除する設定にします。

サーバーにメールが残っているとそのメールを毎回処理してしまうので、削除が必要です。
サーバー側で削除できない場合は、環境設定の「define("MAILDEL","off");」を「define("MAILDEL","on"); 」にしてください。

以降、Gmailのアドレスを"Gmailuser@gmail.com"と仮定して説明します。
 
どうやってメールを受信するか。
Gmailのpop3サーバーに接続するためには、"ssl"が使えなければなりません。
OS(CentOS)のPHPが"ssl"をサポートしているか確認する。
$ php -i | grep "Stream Socket"
Registered Stream Socket Transports => tcp, udp, unix, udg, ssl, sslv3, sslv2, tls
の様に"ssl"を含んでいればOKです。
もし、"ssl"が含まれていなかった場合の対処は調べがついていません。ご存じの方が居られましたらご教授ください。
 
"php-pear-Net-POP3"をインストールする。
phpでPOP3サーバーにsslで接続するために"php-pear-Net-POP3"をインストールする必要があります。
"php-pear-Net-POP3"はyumではインストールできません。
wgetでRPMをダウンロードしてインストールします。
$ wget http://yum.chrislea.com/centos/5/i386/php-pear-Net-POP3-1.3.6-4.noarch.rpm
$ su -
# rpm -ivh php-pear-Net-POP3-1.3.6-4.noarch.rpm
もし上記の場所に"php-pear-Net-POP3"がなかったらネットから探してください。

 
どうやってメールを送信するか。
"php-pear-Mail"と"php-pear-Mail-Mime"をインストールする。
phpでSMTPサーバーにsslで接続するために"php-pear-Mail"をインストールする必要があります。
また、メールにファイルを添付したりHTMLメールを送ったりするためには"php-pear-Mail-Mime"をインストールする必要があります。
# yum install php-pear-Mail*
 
PHPでGmailなどのPOP over ssl / SMTP over sslサーバーからメールを送受信する方法をまとめました。
 
「録るメーラー」(recbymail.php)をインストールする。
プログラムを準備する。
下の方にある各ファイルのソースを参考に下記の6ファイルを適当なディレクトリに入れて(作って)ください。
 recbymail.php     <= メインプログラム
 recbymail.config.php  <= 環境設定ファイル
 recbymail.help.txt   <= 返信用ヘルプファイル
 httprpc.class.php   <= 録画実行用のクラスファイル(録画ッターのバグを修正&録画予約解約コマンドを追加)
 xmlrpc.class.php    <= 録画実行用のクラスファイル
 abstractrpc.class.php <= 録画実行用のクラスファイル(録画予約解約コマンドを追加)
(recbymail.tar.gz)
$ mkdir recbymail
$ cd recbymail
$ wget http://xreknishi.g1.xrea.com/epgrec/files/recbymail.tar.gz

$ tar -zxvf recbymail.tar.gz
$ rm recbymail.tar.gz
$ cp -p recbymail.config.php.sample recbymail.config.php
 
環境設定を行う。
$ vi recbymail.config.php
<?php

define("DEBUGSW","off");

//このシステムの日本語エンコーディングを設定する
mb_language("japanese");
$sysencoding=mb_detect_encoding("このシステムの日本語エンコーディングを取得する",mb_list_encodings());
mb_internal_encoding($sysencoding);

//EPGrecのURL
define("EPGREC_URL", "EpgRecのURLをここに書く");

//メール受信用の設定(Gmailの例)
define("POP_HOST", "ssl://pop.gmail.com");
define("POP_PORT", "995");
define("POP_USER", "アカウント");
define("POP_PSWD", "パスワード");

//メール送信用の設定(Gmailの例)
define("SMTP_HOST", "smtp.gmail.com");
define("SMTP_PORT", "587");
define("SMTP_USER", "アカウント");
define("SMTP_PSWD", "パスワード");
define("SMTP_FROM", "アカウント@gmail.com");

//mysqlの設定
define("MYSQL_HOST","localhost");
define("MYSQL_DB","データベース名");
define("MYSQL_USER","ユーザー名");
define("MYSQL_PSWD","パスワード");

define("RPC_TYPE", 1);

?>
  
"recbymail.help.txt"は自由に編集してください。
recbymailの使い方

  概要:メールのタイトルにリクエスト構文を書いて送信することで、EpgRecサーバーを操作します。
     リクエストメールは2分毎に処理されます。
     予約・解約は、24時間以内の番組を対象として実行されます。


ヘルプ

  構文(いずれも可)
    使い方 / 使用方法 / ヘルプ / HELP / Help / help / 教えて / 助けて

    動作:このテキストを返します。


録画予約

  構文
    ○○予約 △△□□ch XX時 キーワード

    ○○予約 :識別子"予約"は必須。省略不可。
    ○○     :( 録画 / TV / TV録画 )のいずれも可。省略可。
    △△     :放送方式の指定( GR / BS / CS )。省略可。
    □□ch     :チャンネルの指定。チャンネル番号またはチャンネル名の一部。識別子"ch"。省略可。
    XX時     :放送時間帯指定。24時間表記。XXは数字1or2桁、識別子"時"。省略可。
    キーワード:番組名の一部。省略不可。
          語句間の空白は半角のみ可。△△と□□ch間は空白不可。


録画解約

  構文
    ○○解約 △△□□ch XX時 キーワード

    ○○解約 :識別子"解約"は必須。省略不可。
    ○○     :( 録画 / TV / TV録画 )のいずれも可。省略可。
    △△     :放送方式の指定( GR / BS / CS )。省略可。
    □□ch     :チャンネルの指定。チャンネル番号またはチャンネル名の一部。識別子"ch"。省略可。
    XX時     :放送時間帯指定。24時間表記。XXは数字1or2桁、識別子"時"。省略可。
    キーワード:番組名の一部。省略不可。
          語句間の空白は半角のみ可。△△と□□ch間は空白不可。


TEXT情報要求

  構文(いずれも可)
    番組情報 / 番組情報TEXT / 番組情報text

    動作:番組一覧をテキストで返します。

  構文(いずれも可)
    予約情報 / 予約情報TEXT / 予約情報text

    動作:予約一覧をテキストで返します。

  構文(いずれも可)
    録画情報 / 録画情報TEXT / 録画情報text

    動作:録画番組一覧をテキストで返します。


HTML情報要求

  構文(いずれも可)
    番組表HTML / 番組表html

    動作:番組表のHTMLファイルを添付して返信します。

  構文(いずれも可)
    番組情報HTML / 番組情報html

    動作:番組一覧のHTMLファイルを添付して返信します。

  構文(いずれも可)
    予約情報HTML / 予約情報html

    動作:予約一覧のHTMLファイルを添付して返信します。

  構文(いずれも可)
    録画情報HTML / 録画情報html

    動作:録画番組一覧のHTMLファイルを添付して返信します。



チャンネル情報(東京)
+----+------+---------+-----------------------------+--------------+----------------+------+
| id | type | channel | name                        | channel_disc | sid            | skip |
+----+------+---------+-----------------------------+--------------+----------------+------+
|  1 | GR   | 27      | NHK総合1                | GR27         | 1024           |    0 |
|  2 | GR   | 26      | NHKEテレ1              | GR26         | 1032           |    0 |
|  3 | GR   | 25      | 日テレ1                    | GR25         | 1040           |    0 |
|  4 | GR   | 24      | テレビ朝日                  | GR24         | 1064           |    0 |
|  5 | GR   | 22      | TBS1                    | GR22         | 1048           |    0 |
|  6 | GR   | 23      | テレビ東京1                | GR23         | 1072           |    0 |
|  7 | GR   | 21      | フジテレビ                  | GR21         | 1056           |    0 |
|  8 | GR   | 16      | 東京MX                    | GR16         | 23608          |    0 |
+----+------+---------+-----------------------------+--------------+----------------+------+


おわり
 
「録るメーラー」の動作確認を行う。
録画予約用のメールを送る。
From: xxxxxxxx@xxxxxxxx.ne.jp
To: Gmailuser@gmail.com
Subject: TV!番組名録って
 
"recbymail.php"を実行してみる。
$ インストールしたディレクトリ/recbymail.php
"recbymail.config.php"の"DEBUGSW"を"on"にすると、メールサーバーの応答などが表示されます。
録画予約状況の返信メールが帰ってきたら、epgrecのWEBページで予約ができているか確認してください。
動作が確認できたら"DEBUGSW"は"off"にしておきましょう。
 
cronに登録する。
動作の確認ができたら、"recbymail.php"をcronに登録しましょう。実行間隔は5分ぐらいでいいと思います。
*/5 * * * * Recuser /インストールしたディレクトリ/recbymail.php
 
インストールと設定は以上です。
 
 

以下はプログラムの説明とソースです。

 
recbymail.php
「録るメーラー」のメインプログラムです。
PHPで日本語メールを送受信する際の、MIMEのエンコード、デコードに苦労しました。
recbymail.phpのソースは以下の通りです。

#!/usr/bin/php
<?php

//ライブラリ読み込み
require_once("Net/POP3.php");
require_once("Mail.php");
require_once("Mail/mime.php");

//設定読み込み
require_once dirname(__FILE__)."/recbymail.config.php";
if(DEBUGSW=="on"){
	echo("DEBUGSW = on\n");
	echo("System Encoding = mb_internal_encoding()\n");
	define("SMTP_DEBUG", true);
} else{
	define("SMTP_DEBUG", false);
}
$client = null;
function getRpc(){
	global $client;
	if($client == null){
		if(RPC_TYPE == 2){
			require_once dirname(__FILE__)."/xmlrpc.class.php";
			$client = new XmlRpc();
		} else {
			require_once dirname(__FILE__)."/httprpc.class.php";
			$client = new HttpRpc();
		}
	}
	return $client;
}


//POP3サーバーに接続
$pop = new Net_POP3();
$pop->connect(POP_HOST, POP_PORT);
$pop->login(POP_USER, POP_PSWD, "USER");

//メール受信&リクエスト処理 ===============================
$messages = $pop->getListing();
if($messages){
        foreach($messages as $k => $row){
		$return=null;
		$request=null;
                $id = $row["msg_id"];
                $status = $pop->getMsg($id);
		preg_match("/Return-Path:.*<(.+)>.*/",$status,$matches);
		$return=$matches[1];
		preg_match("/Subject:(.+)/",$status,$matches);
		$request=mb_decode_mimeHeader(trim($matches[1]));
		if(DEBUGSW=="on"){
			echo("--- receivemail ---\n");
			echo($return."\n");
			echo($request."\n");
			echo("-------------------\n");
		}
		//リクエスト処理へ
		if( $return!=null and $request!=null ){
			proc_request($return,$request);
		}
        }
}
//メインループここまで ====================================
$pop->disconnect();
exit();


//リクエスト処理関数
function proc_request($return,$request){

	$msg="";
	$write=false;
	$file=null;

	//情報返信(HTMLファイル添付)
	if(preg_match("/^番組表HTML$/i", $request)){
		if(DEBUGSW=="on"){ print("番組表HTMLと認識\n"); };
		$file=dirname(__FILE__)."/bangumihyou.html";
		file_put_contents($file,file_get_contents(EPGREC_URL."index.php"));
		$msg="番組表のHTMLを添付したよ。 by 録るメーラー";
	}
	elseif(preg_match("/^番組情報HTML$/i", $request)){
		if(DEBUGSW=="on"){ print("番組情報HTMLと認識\n"); };
		$file=dirname(__FILE__)."/bangumi.html";
		file_put_contents($file,file_get_contents(EPGREC_URL."programTable.php"));
		$msg="番組一覧のHTMLを添付したよ。 by 録るメーラー";
	}
	elseif(preg_match("/^予約情報HTML$/i", $request)){
		if(DEBUGSW=="on"){ print("予約情報HTMLと認識\n"); };
		$file=dirname(__FILE__)."/yoyaku.html";
		file_put_contents($file,file_get_contents(EPGREC_URL."reservationTable.php"));
		$msg="予約一覧のHTMLを添付したよ。 by 録るメーラー";
	}
	elseif(preg_match("/^録画情報HTML$/i", $request)){
		if(DEBUGSW=="on"){ print("録画情報HTMLと認識\n"); };
		$file=dirname(__FILE__)."/rokugazumi.html";
		file_put_contents($file,file_get_contents(EPGREC_URL."recordedTable.php"));
		$msg="録画番組一覧のHTMLを添付したよ。 by 録るメーラー";
	}

	//情報返信(TEXT)
	elseif(preg_match("/^番組情報(TEXT)?$/i", $request)){
		if(DEBUGSW=="on"){ print("番組情報TEXTと認識\n"); };
		$files = fopen(EPGREC_URL."programTable.php", "r");
		$count=0;
		while( ($line = fgetss($files, 1024 )) !== false) {
			$line=trim($line);
			if($write){
				$msg=$msg.$line."\n";
				if(preg_match("/^表示最大(.+)まで$/",$line)){
					$write=false;
				}
			}
			elseif($msg==""){
				if($line==null){
					$count++;
				}
				else{
					if($count==3){
						$msg="番組の情報だよ。 by 録るメーラー\n\n\n\n".$line."\n";
						$write=true;
					}
					$count=0;
				}
			}
		}
		fclose($files);
	}
	elseif(preg_match("/^予約情報(TEXT)?$/i", $request)){
		if(DEBUGSW=="on"){ print("予約情報TEXTと認識\n"); };
		$files = fopen(EPGREC_URL."reservationTable.php", "r");
		$count=0;
		while( ($line = fgetss($files, 1024 )) !== false) {
			$line=trim($line);
			if($write){
				if(preg_match("/^jQuery UI Dialog$/",$line)){
					$write=false;
				}
				else{
					$msg=$msg.$line."\n";
				}
			}
			elseif($msg==""){
				if($line==null){
					$count++;
				}
				else{
					if($count==3){
						$msg="予約の情報だよ。 by 録るメーラー\n\n\n\n".$line."\n";
						$write=true;
					}
					$count=0;
				}
			}
		}
		fclose($files);
	}
	elseif(preg_match("/^録画情報(TEXT)?$/i", $request)){
		if(DEBUGSW=="on"){ print("録画情報TEXTと認識\n"); };
		$files = fopen(EPGREC_URL."recordedTable.php", "r");
		$count=0;
		while( ($line = fgetss($files, 1024 )) !== false) {
			$line=trim($line);
			if($write){
				if(preg_match("/^jQuery UI Dialog$/",$line)){
					$write=false;
				}
				else{
					$msg=$msg.$line."\n";
				}
			}
			elseif($msg==""){
				if($line==null){
					$count++;
				}
				else{
					if($count==3){
						$msg="録画済みの情報だよ。 by 録るメーラー\n\n\n".$line."\n";
						$write=true;
					}
					$count=0;
				}
			}
		}
		fclose($files);
	}

	//録画予約
	elseif(preg_match("/^(TV|TV録画|録画)?予約\s?(GR|BS|CS)?((.+)ch)?\s?((\d{1,2})時)?\s?(.+)$/", $request, $matches)){
		$type   =$matches[2];
		$channel=$matches[4];
		$hour   =$matches[6];
		$title  =$matches[7];
		$rpc = getRpc();
		$results = $rpc->searchProgram($title, $type, $channel, $hour);
	
		if(count($results) == 0){
			$msg="指示された番組が見つからないよ。 by 録るメーラー";
		} elseif(count($results) > 1){
			$msg="番組が絞りきれないぞい、もっと詳しく指示してちょ。 by 録るメーラー";
		} else {
			$result = $results[0];
			try{
				$rpc->reserveProgram($result["program_id"]);	
				$msg="予約できたよ。 by 録るメーラー\r\n".$result["title"];
			} catch (Exception $e) {
				if(DEBUGSW=="on"){ print_r($e); };
				$msg=$e->getMessage()." by 録るメーラー";
				$msg=$msg."\r\n".$result["title"];
			}
		}
	}

	//録画解約
	elseif(preg_match("/^(TV|TV録画|録画)?解約\s?(GR|BS|CS)?((.+)ch)?\s?((\d{1,2})時)?\s?(.+)$/", $request, $matches)){
		$type   =$matches[2];
		$channel=$matches[4];
		$hour   =$matches[6];
		$title  =$matches[7];
		$rpc = getRpc();
		$results = $rpc->searchProgram($title, $type, $channel, $hour);
		if(count($results) == 0){
			$msg="指示された番組が見つからないよ。 by 録るメーラー";
		} elseif(count($results) > 1){
			$msg="番組が絞りきれないぞい、もっと詳しく指示してちょ。 by 録るメーラー";
		} else {
			$result = $results[0];
			try{
				$rpc->cancelreserveProgram($result["program_id"]);	
				$msg="解約できたよ。 by 録るメーラー\r\n".$result["title"];
			} catch (Exception $e) {
				if(DEBUGSW=="on"){ print_r($e); };
				$msg=$e->getMessage()." by 録るメーラー";
				$msg=$msg."\r\n".$result["title"];
			}
		}
	}

	//ヘルプ(recbymailの使い方)
	elseif(preg_match("/^HELP$/i", $request)||preg_match("/^使い方$/", $request)||preg_match("/^使用方法$/", $request)||preg_match("/^ヘルプ$/", $request)||preg_match("/^教えて$/", $request)||preg_match("/^助けて$/", $request)){
		$msg=file_get_contents(dirname(__FILE__)."/recbymail.help.txt");
	}

	//構文エラー
	else{
		$msg="コマンド構文エラーだよ。 by 録るメーラー";
	}

	if($msg!=""){
		mailsend($return,"Re:".$request,$msg,$file);
		if($file){ unlink($file); };
	}

}


//メール送信関数
function mailsend($to,$subject,$body,$attachfile){
	if(DEBUGSW=="on"){
		echo("--- mailsend ---\n");
		echo("TO     : ".$to."\n");
		echo("Subject: ".$subject."\n");
		echo("Body   : ".$body."\n");
		echo("Attach : ".$attachfile."\n");
		echo("----------------\n\n");
	}
	//日本語のエンコード
	$body = mb_convert_encoding($body,"iso-2022-jp");
	$subject=mb_encode_mimeheader(mb_convert_encoding($subject,"iso-2022-jp"));
	//SMTP接続
	$params = array(
	    "host"     => SMTP_HOST,
	    "port"     => SMTP_PORT,
	    "auth"     => true,
	    "username" => SMTP_USER,
	    "password" => SMTP_PSWD,
	    "debug"    => SMTP_DEBUG,
	);
	$smtp = Mail::factory("smtp", $params);
	//添付ファイル処理
	$mime = new Mail_Mime("\n");
	$mime->setTxtBody($body);
	$mime->addAttachment($attachfile,"application/octet-stream");
	$body_encode = array(
	    "head_charset" => "ISO-2022-JP",
	    "text_charset" => "ISO-2022-JP"
	);
	$body = $mime->get($body_encode);
	//ヘッダー生成
	$headers = array(
	    "To"      => $to,
	    "From"    => SMTP_FROM,
	    "Subject" => $subject,
	);
	$header = $mime->headers($headers);
	//送信実行
	$ret = $smtp->send($to, $header, $body);
	if ( PEAR::isError($ret) ) {
		echo("メール送信エラー:".$ret->getMessage()."\n");
	}
}

?>
 
abstractrpc.class.php
「録画ッター」のファイルを流用していますが、終端の"?>"が抜けていたので追加しました。
また、cancelreserveProgram()を追加しました。
<?php
abstract class AbstractRpc{
        abstract public function searchProgram($keyword, $type, $channel, $hour);
        abstract public function reserveProgram($program_id);
        abstract public function cancelreserveProgram($program_id);

}
?>
 
httprpc.class.php

<?php

require_once dirname(__FILE__).'/abstractrpc.class.php';

class HttpRpc extends AbstractRpc{

	var $cn;
	
	function HttpRpc(){
		require_once dirname(__FILE__).'/recbymail.config.php';
		if (!($this--->cn = mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PSWD))){
		    die("接続エラー");
		}
		if (!(mysql_select_db(MYSQL_DB))) {
		    die("選択エラー");
		}
		mysql_query("SET NAMES utf8");
	}
	
	public function searchProgram($keyword, $type, $channel, $hour){
		
		//$type = BS/CS/GR
				
 		$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";

		#タイトルで検索
		$sql .= " AND title LIKE '%".mb_convert_kana(mysql_escape_string($keyword),"A")."%' \n";
		
		#時間指定があった場合
		if($hour){
			$sql .= " AND DATE_FORMAT(starttime, '%k') = ".mysql_escape_string($hour)." \n";
		}

		#チャンネル指定があった場合
		if($type||$channel){
		   $sql .= " AND EXISTS(
		     SELECT *
		     FROM `Recorder_channelTbl` c
		     WHERE
		       p.channel_id = c.id \n";
		   if($type){
		   	$sql .= " AND c.type = '".mysql_escape_string($type)."' \n";
		   }
		   if($channel){
			if(preg_match("/^(\d{2})$/",$channel)){
				$sql .= " AND c.channel LIKE '".$channel."' \n";
		   	} else {
		   		$sql .= " AND c.name LIKE '%".mb_convert_kana(mysql_escape_string($channel),"A")."%' \n";
			}
		   }
			$sql .= ") \n";
		}
		if (!($rs = mysql_query($sql))) {
		    die("エラー".$sql);
		}
		$results = array();
		while ($item = mysql_fetch_array($rs)) {
			$results[] = array(
					'program_id' => $item['id'],
					'title' => $item['title']
				);
		}
		return $results;
	}
	
	public function reserveProgram($program_id){
		$handle = @fopen(EPGREC_URL.'simpleReservation.php?program_id='.$program_id, "r");
		if ($handle) {
			$buffer = fgets($handle, 4096);
		    fclose($handle);
		    if(!preg_match('/^error/i',$buffer)){
		    	return;
		    } else {
		    	throw new Exception($buffer);
		    }
		}
		throw new Exception("");
	}
	
	public function cancelreserveProgram($program_id){
		$handle = @fopen(EPGREC_URL.'cancelReservation.php?program_id='.$program_id, "r");
		if ($handle) {
			$buffer = fgets($handle, 4096);
		    fclose($handle);
		    if(!preg_match('/^error/i',$buffer)){
		    	return;
		    } else {
		    	throw new Exception($buffer);
		    }
		}
		throw new Exception("");
	}
}


?>
 
xmlrpc.class.php
使用していませんが、「録画ッター」からの引き継ぎなので残してあります。
cancelreserveProgram()を追加しました。
<?php
require_once dirname(__FILE__).'/abstractrpc.class.php';

//APIが正常終了してても例外を返す時があるので、とりあえず使わない。
class XmlRpc extends AbstractRpc{

        var $client;
        var $channelList = null;
        
        function XmlRpc(){
                require_once dirname(__FILE__).'/recbymail.config.php';
                require_once dirname(__FILE__).'/XML/RPC2/Client.php';
                
                //クライアント作成
                $options = array(
                        "backend"  => "php",
                        "encoding" => "UTF-8",
                        "prefix" => "epgrec.",
                );
                $this->client = XML_RPC2_Client::create(EPGREC_URL.'xmlrpc.php', $options);
                $this->getChannelList();
        }
        
        public function searchProgram($keyword, $type, $channel, $hour){
                
                //$type = BS/CS/GR
                if($type){
                        //チャンネルゲット
                        if($channel != null){
                                $channel_id = $this->getChannel($type, $channel);
                                if($channel_id == null){
                                        return array();
                                }
                        }
                } else {
                        $type = "*";
                }
                
                if($hour){
                        //OK
                } else {
                        $hour = 24;
                }
                
                //検索
                try {
                    $results = $this->client->searchProgram($keyword, false, $type, 0, $channel_id, 7, $hour);
                    //24時間以内で絞り込み
                    $tmp = array();
                    foreach($results as $result){
                        if($result['starttime']->timestamp < $after24 = time() + (24 * 60 * 60)){
                                $tmp[] = $result;
                        } else {
                                break;
                        }
                    }
                    return $tmp;
                } catch (XML_RPC2_FaultException $e) {
                    die('Exception : ' . print_r($e, true));
                } catch (Exception $e) {
                    die('Exception : ' . print_r($e, true));
                }
        }
        
        function getChannelList(){
                if($this->channelList == null){
                        $this->channelList = $this->client->getChannelList();
                }
        }
        
        function getChannel($type, $channel){
                foreach ($this->channelList as $tmp){
                        if($tmp['type'] == $type && $tmp['name'] == $channel){
                                return $tmp['channel_id'];
                        }
                }
                return null;
        }
        
        public function reserveProgram($program_id){
            $this->client->reserveProgram($program_id);
        }
        
        public function cancelreserveProgram($program_id){
            $this->client->cancelreserveProgram($program_id);
        }
}

?>
 
ページの先頭へ戻る
ホームへ戻る