Fixed for SKB with Python 3.7

delete
This commit is contained in:
flywithu 2019-02-06 23:16:41 +09:00
parent db7b054876
commit 141b251585
8 changed files with 4188 additions and 1393 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,13 @@
## 변경사항
### Version 2.0.0
Python3.7 용으로 수정
SKB 용으로 채널 정보 수정 및 id는 skb 채널 번호로 수정
PHP 파일 삭제
# 원본 메시지 아래
-- 아래
# 공지 # 공지
리포지터리 삭제되었습니다 리포지터리 삭제되었습니다

View File

@ -1,997 +0,0 @@
<?php
@mb_internal_encoding("UTF-8");
@date_default_timezone_set('Asia/Seoul');
error_reporting(E_ALL ^ E_NOTICE);
@set_time_limit(0);
define("VERSION", "1.2.6");
$debug = False;
$ua = "'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116'";
$timeout = 5;
define("CHANNEL_ERROR", " 존재하지 않는 채널입니다.");
define("CONTENT_ERROR ", " EPG 정보가 없습니다.");
define("HTTP_ERROR", " EPG 정보를 가져오는데 문제가 있습니다.");
define("DISPLAY_ERROR", "EPG를 출력할 수 없습니다.");
define("FILE_ERROR", "XML 파일을 만들수 없습니다.");
define("SOCKET_ERROR", "소켓 파일을 찾을 수 없습니다.");
define("JSON_FILE_ERROR", "json 파일이 없습니다.");
define("JSON_SYNTAX_ERROR", "json 파일 형식이 잘못되었습니다.");
if(version_compare(PHP_VERSION, '5.4.45','<')) :
printError("PHP 버전은 5.4.45 이상이어야 합니다.");
printError("현재 PHP 버전은 ".PHP_VERSION." 입니다.");
exit;
endif;
if (!extension_loaded('json')) :
printError("json 모듈이 설치되지 않았습니다.");
exit;
endif;
if (!extension_loaded('dom')) :
printError("dom 모듈이 설치되지 않았습니다.");
exit;
endif;
if (!extension_loaded('mbstring')) :
printError("mbstring 모듈이 설치되지 않았습니다.");
exit;
endif;
if (!extension_loaded('openssl')) :
printError("openssl 모듈이 설치되지 않았습니다.");
exit;
endif;
if (!extension_loaded('curl')) :
printError("curl 모듈이 설치되지 않았습니다.");
exit;
endif;
//옵션 처리
$shortargs = "";
$shortargs .= "i:";
$shortargs .= "v";
$shortargs .= "d";
$shortargs .= "o:s:";
$shortargs .= "l:";
$shortargs .= "h";
$longargs = array(
"version",
"display",
"outfile:",
"socket:",
"limit::",
"icon:",
"episode:",
"rebroadcast:",
"verbose:",
"help"
);
$args = getopt($shortargs, $longargs);
$Settingfile = __DIR__."/epg2xml.json";
try {
$f = @file_get_contents($Settingfile);
if($f === False) :
printError("epg2xml.".JSON_FILE_ERROR);
exit;
else :
try {
$Settings = json_decode($f, TRUE);
if(json_last_error() != JSON_ERROR_NONE) throw new Exception("epg2xml.".JSON_SYNTAX_ERROR);
$MyISP = $Settings['MyISP'] ?: "ALL";
$MyChannels = isset($Settings['MyChannels']) ? $Settings['MyChannels'] : "";
$default_output = $Settings['output'] ?: "d";
$default_xml_file = $Settings['default_xml_file'] ?: "xmltv.xml";
$default_xml_socket = $Settings['default_xml_socket'] ?: "xmltv.sock";
$default_icon_url = $Settings['default_icon_url'] ?: "";
$default_fetch_limit = $Settings['default_fetch_limit'] ?: "2";
$default_rebroadcast = $Settings['default_rebroadcast'] ?: "y";
$default_episode = $Settings['default_episode'] ?: "y";
$default_verbose = $Settings['default_verbose'] ?: "n";
$default_xmltvns = $Settings['default_xmltvns'] ?: "n";
$userISP = !empty($_GET['i']) ? $_GET['i'] : (!empty($args['i']) ? $args['i'] : "");
$user_output = "";
$user_xml_file = "";
$user_xml_socket = "";
if(isset($_GET['d']) || isset($_GET['display']) || (isset($args['d']) && $args['d'] === False) || (isset($args['display']) && $args['display'] === False)):
if(isset($_GET['o']) || isset($_GET['outfile']) || isset($_GET['s']) || isset($_GET['socket']) || isset($args['o']) || isset($args['outfile']) || isset($args['s']) || isset($args['socket'])) :
printf($usage);
printf("epg2xml.php: error: argument -o/--outfile, -s/--socket: not allowed with argument -d/--display\n");
exit;
endif;
$user_output = "d";
elseif(isset($_GET['o']) || isset($_GET['outfile']) || isset($args['o']) || isset($args['outfile'])):
if(isset($_GET['d']) || isset($_GET['display']) || isset($_GET['s']) || isset($_GET['socket']) || isset($args['d']) || isset($args['display']) || isset($args['s']) || isset($args['socket'])) :
printf($usage);
printf("epg2xml.php: error: argument -d/--display, -s/--socket: not allowed with argument -o/--outfile\n");
exit;
endif;
$user_output = "o";
if(isset($_GET['o']) || isset($_GET['outfile'])) :
$user_xml_file = $_GET['o'] ?: $_GET['outfile'];
elseif(isset($args['o']) || isset($args['outfile'])) :
$user_xml_file = $args['o'] ?: $args['outfile'];
endif;
elseif(isset($_GET['s']) || isset($_GET['socket']) || isset($args['s']) || isset($args['socket'])):
if(isset($_GET['d']) || isset($_GET['display']) || isset($_GET['o']) || isset($_GET['outfile']) || isset($args['d']) || isset($args['display']) || isset($args['o']) || isset($args['outfile'])) :
printf($usage);
printf("epg2xml.php: error: argument -d/--display, -o/--outfile: not allowed with argument -s/--socket\n");
exit;
endif;
$user_output = "s";
if(isset($_GET['s']) || isset($_GET['socket'])) :
$user_xml_socket = $_GET['s'] ?: $_GET['socket'];
elseif(isset($args['s']) || isset($args['socket'])) :
$user_xml_socket = $args['s'] ?: $args['socket'];
endif;
endif;
$user_fetch_limit = "";
$user_icon_url = empty($_GET['icon']) === False ? $_GET['icon'] : (empty($args['icon']) === False ? $args['icon'] : "");
if(isset($_GET['l']) || isset($_GET['limit']) || isset($args['l']) || isset($args['limit'])):
if(isset($_GET['l']) || isset($_GET['limit'])) :
$user_fetch_limit = $_GET['l'] ?: $_GET['limit'];
elseif(isset($args['l']) || isset($args['limit'])) :
$user_fetch_limit = $args['l'] ?: $args['limit'];
endif;
endif;
$user_rebroadcast = empty($_GET['rebroadcast']) === False ? $_GET['rebroadcast'] : (empty($args['rebroadcast']) === False ? $args['rebroadcast'] : "");
$user_episode = empty($_GET['episode']) === False ? $_GET['episode'] : (empty($args['episode']) === False ? $args['episode'] : "");
$user_verbose = empty($_GET['verbose']) === False ? $_GET['verbose'] : (empty($args['verbose']) === False ? $args['verbose'] : "");
if(!empty($userISP)) $MyISP = $userISP;
if(!empty($user_output)) $default_output = $user_output;
if(!empty($user_xml_file)) $default_xml_file = $user_xml_file;
if(!empty($user_xml_socket)) $default_xml_socket = $user_xml_socket;
if(!empty($user_icon_url)) $default_icon_url = $user_icon_url;
if(!empty($user_fetch_limit)) $default_fetch_limit = $user_fetch_limit;
if(!empty($user_rebroadcast)) $default_rebroadcast = $user_rebroadcast;
if(!empty($user_episode)) $default_episode = $user_episode;
if(!empty($user_verbose)) $default_verbose = $user_verbose;
if(empty($MyISP)) : //ISP 선택없을 시 사용법 출력
printError("epg2xml.json 파일의 MyISP항목이 없습니다.");
exit;
else :
if(!in_array($MyISP, array("ALL", "KT", "LG", "SK"))) : //ISP 선택
printError("MyISP는 ALL, KT, LG, SK만 가능합니다.");
exit;
endif;
endif;
if(empty($default_output)) :
printError("epg2xml.json 파일의 output항목이 없습니다.");
exit;
else :
if(in_array($default_output, array("d", "o", "s"))) :
switch ($default_output) :
case "d" :
$output = "display";
break;
case "o" :
$output = "file";
break;
case "s" :
$output = "socket";
break;
endswitch;
else :
printError("output는 d, o, s만 가능합니다.");
exit;
endif;
endif;
if(empty($default_fetch_limit)) :
printError("epg2xml.json 파일의 default_fetch_limit항목이 없습니다.");
exit;
else :
if(in_array($default_fetch_limit, array(1, 2, 3, 4, 5, 6, 7))) :
$period = $default_fetch_limit;
else :
printError("default_fetch_limit는 1, 2, 3, 4, 5, 6, 7만 가능합니다.");
exit;
endif;
endif;
if(is_null($default_icon_url) == True) :
printError("epg2xml.json 파일의 default_icon_url항목이 없습니다.");
exit;
else :
$IconUrl = $default_icon_url;
endif;
if(empty($default_rebroadcast)) :
printError("epg2xml.json 파일의 default_rebroadcast항목이 없습니다.");
exit;
else :
if(in_array($default_rebroadcast, array("y", "n"))) :
$addrebroadcast = $default_rebroadcast;
else :
printError("default_rebroadcast는 y, n만 가능합니다.");
exit;
endif;
endif;
if(empty($default_episode)) :
printError("epg2xml.json 파일의 default_episode항목이 없습니다.");
exit;
else :
if(in_array($default_episode, array("y", "n"))) :
$addepisode = $default_episode;
else :
printError("default_episode는 y, n만 가능합니다.");
exit;
endif;
endif;
if(empty($default_verbose)) :
printError("epg2xml.json 파일의 default_verbose항목이 없습니다.");
exit;
else :
if(in_array($default_verbose, array("y", "n"))) :
$addverbose = $default_verbose;
else :
printError("default_verbose는 y, n만 가능합니다.");
exit;
endif;
endif;
if(empty($default_xmltvns)) :
printError("epg2xml.json 파일의 default_xmltvns항목이 없습니다.");
exit;
else :
if(in_array($default_xmltvns, array("y", "n"))) :
$addxmltvns = $default_xmltvns;
else :
printError("default_xmltvns는 y, n만 가능합니다.");
exit;
endif;
endif;
}
catch(Exception $e) {
printError($e->getMessage());
exit;
}
endif;
}
catch(Exception $e) {
printError($e->getMessage());
exit;
}
if(php_sapi_name() != "cli"):
if(isset($_GET['h']) || isset($_GET['help']))://도움말 출력
header("Content-Type: text/plain; charset=utf-8");
print($help);
exit;
elseif(isset($_GET['v'])|| isset($_GET['version']))://버전 정보 출력
header("Content-Type: text/plain; charset=utf-8");
printf("epg2xml.php version : %s\n", VERSION);
exit;
endif;
else :
if((isset($args['h']) && $args['h'] === False) || (isset($args['help']) && $args['help'] === False))://도움말 출력
printf($help);
exit;
elseif((isset($args['v']) && $args['v'] === False) || (isset($args['version']) && $args['version'] === False))://버전 정보 출력
printf("epg2xml.php version : %s\n", VERSION);
exit;
endif;
endif;
if($output == "display") :
$fp = fopen('php://output', 'w+');
if ($fp === False) :
printError(DISPLAY_ERROR);
exit;
else :
try {
getEpg();
fclose($fp);
} catch(Exception $e) {
if($GLOBALS['debug']) printError($e->getMessage());
}
endif;
elseif($output == "file") :
if($default_xml_file) :
$fp = fopen($default_xml_file, 'w+');
if ($fp === False) :
printError(FIEL_ERROR);
exit;
else :
try {
getEpg();
fclose($fp);
} catch(Exception $e) {
if($GLOBALS['debug']) printError($e->getMessage());
}
endif;
else :
printError("epg2xml.json 파일의 default_xml_file항목이 없습니다.");
exit;
endif;
elseif($output == "socket") :
if($default_xml_socket && php_sapi_name() == "cli") :
$default_xml_socket = "unix://".$default_xml_socket;
$fp = @fsockopen($default_xml_socket, -1, $errno, $errstr, 30);
if ($fp === False) :
printError(SOCKET_ERROR);
exit;
else :
try {
getEpg();
fclose($fp);
} catch(Exception $e) {
if($GLOBALS['debug']) printError($e->getMessage());
}
endif;
else :
printError("epg2xml.json 파일의 default_xml_socket항목이 없습니다.");
exit;
endif;
endif;
function getEPG() {
$fp = $GLOBALS['fp'];
$MyISP = $GLOBALS['MyISP'];
$MyChannels = $GLOBALS['MyChannels'];
$Channelfile = __DIR__."/Channel.json";
$IconUrl = "";
$ChannelInfos = array();
try {
$f = @file_get_contents($Channelfile);
if($f === False) :
printError("Channel.json.".JSON_FILE_ERROR);
exit;
else :
try {
$Channeldatajson = json_decode($f, TRUE);
if(json_last_error() != JSON_ERROR_NONE) throw new Exception("Channel.".JSON_SYNTAX_ERROR);
}
catch(Exception $e) {
printError($e->getMessage());
exit;
}
endif;
}
catch(Exception $e) {
printError($e->getMessage());
exit;
}
//My Channel 정의
$MyChannelInfo = array();
if($MyChannels) :
$MyChannelInfo = array_map('trim',explode(',', $MyChannels));
endif;
if(php_sapi_name() != "cli" && $GLOBALS['default_output'] == "d") header("Content-Type: application/xml; charset=utf-8");
fprintf($fp, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
fprintf($fp, "<!DOCTYPE tv SYSTEM \"xmltv.dtd\">\n\n");
fprintf($fp, "<tv generator-info-name=\"epg2xml %s\">\n", VERSION);
foreach ($Channeldatajson as $Channeldata) : //Get Channel & Print Channel info
if(in_array($Channeldata['Id'], $MyChannelInfo)) :
$ChannelId = $Channeldata['Id'];
$ChannelName = htmlspecialchars($Channeldata['Name'], ENT_XML1);
$ChannelSource = $Channeldata['Source'];
$ChannelServiceId = $Channeldata['ServiceId'];
$ChannelIconUrl = htmlspecialchars($Channeldata['Icon_url'], ENT_XML1);
if($MyISP != "ALL" && $Channeldata[$MyISP.'Ch'] != Null):
$ChannelInfos[] = array($ChannelId, $ChannelName, $ChannelSource, $ChannelServiceId);
$Channelnumber = $Channeldata[$MyISP.'Ch'];
$ChannelISPName = htmlspecialchars($Channeldata[$MyISP." Name"], ENT_XML1);
fprintf($fp, " <channel id=\"%s\">\n", $ChannelId);
fprintf($fp, " <display-name>%s</display-name>\n", $ChannelName);
fprintf($fp, " <display-name>%s</display-name>\n", $ChannelISPName);
fprintf($fp, " <display-name>%s</display-name>\n", $Channelnumber);
fprintf($fp, " <display-name>%s</display-name>\n", $Channelnumber." ".$ChannelISPName);
if($IconUrl) :
fprintf($fp, " <icon src=\"%s/%s.png\" />\n", $IconUrl, $ChannelId);
else :
fprintf($fp, " <icon src=\"%s\" />\n", $ChannelIconUrl);
endif;
fprintf($fp, " </channel>\n");
elseif($MyISP == "ALL"):
$ChannelInfos[] = array($ChannelId, $ChannelName, $ChannelSource, $ChannelServiceId);
fprintf($fp, " <channel id=\"%s\">\n", $ChannelId);
fprintf($fp, " <display-name>%s</display-name>\n", $ChannelName);
if($IconUrl) :
fprintf($fp, " <icon src=\"%s/%s.png\" />\n", $IconUrl, $ChannelId);
else :
fprintf($fp, " <icon src=\"%s\" />\n", $ChannelIconUrl);
endif;
fprintf($fp, " </channel>\n");
endif;
endif;
endforeach;
// Print Program Information
foreach ($ChannelInfos as $ChannelInfo) :
$ChannelId = $ChannelInfo[0];
$ChannelName = $ChannelInfo[1];
$ChannelSource = $ChannelInfo[2];
$ChannelServiceId = $ChannelInfo[3];
if($GLOBALS['debug']) printLog($ChannelName.' 채널 EPG 데이터를 가져오고 있습니다');
if($ChannelSource == 'KT') :
GetEPGFromKT($ChannelInfo);
elseif($ChannelSource == 'LG') :
GetEPGFromLG($ChannelInfo);
elseif($ChannelSource == 'SK') :
GetEPGFromSK($ChannelInfo);
elseif($ChannelSource == 'SKB') :
GetEPGFromSKB($ChannelInfo);
elseif($ChannelSource == 'NAVER') :
GetEPGFromNaver($ChannelInfo);
endif;
endforeach;
fprintf($fp, "</tv>\n");
}
// Get EPG data from KT
function GetEPGFromKT($ChannelInfo) {
$ChannelId = $ChannelInfo[0];
$ChannelName = $ChannelInfo[1];
$ServiceId = $ChannelInfo[3];
$epginfo = array();
foreach(range(1, $GLOBALS['period']) as $k) :
$url = "http://tv.kt.com/tv/channel/pSchedule.asp";
$day = date("Ymd", strtotime("+".($k - 1)." days"));
$params = array(
'ch_type' => '1',
'view_type' => '1',
'service_ch_no' => $ServiceId,
'seldate' => $day
);
$params = http_build_query($params);
$method = "POST";
try {
$response = getWeb($url, $params, $method);
if ($response === False && $GLOBALS['debug']) :
printError($ChannelName.HTTP_ERROR);
else :
$response = mb_convert_encoding($response, "HTML-ENTITIES", "EUC-KR");
$dom = new DomDocument;
libxml_use_internal_errors(True);
if($dom->loadHTML('<?xml encoding="utf-8" ?>'.$response)):
$xpath = new DomXPath($dom);
$query = "//tbody/tr";
$rows = $xpath->query($query);
foreach($rows as $row) :
$startTime = $endTime = $programName = $subprogramName = $desc = $actors = $producers = $category = $episode = "";
$rebroadcast = False;
$rating = 0;
$cells = $row->getElementsByTagName('td');
$programs = array_map(null, iterator_to_array($xpath->query('p', $cells->item(1))), iterator_to_array($xpath->query('p', $cells->item(2))), iterator_to_array($xpath->query('p', $cells->item(3))));
foreach($programs as $program):
$hour = trim($cells->item(0)->nodeValue);
$minute = trim($program[0]->nodeValue);
$startTime = date("YmdHis", strtotime($day.$hour.$minute."00"));
$programName = trim($program[1]->nodeValue);
$images = $program[1]->getElementsByTagName('img')->item(0);
preg_match('/([\d,]+)/', $images->getAttribute('alt'), $grade);
if($grade != NULL):
$rating = $grade[1];
else:
$rating = 0;
endif;
$programName = str_replace("방송중 ", "", $programName);
$category = trim($program[2]->nodeValue);
//ChannelId, startTime, programName, subprogramName, desc, actors, producers, category, episode, rebroadcast, rating
$epginfo[] = array($ChannelId, $startTime, $programName, $subprogramName, $desc, $actors, $producers, $category, $episode, $rebroadcast, $rating);
usleep(1000);
endforeach;
endforeach;
else :
if($GLOBALS['debug']) printError($ChannelName.CONTENT_ERROR);
endif;
endif;
} catch (Exception $e) {
if($GLOBALS['debug']) printError($e->getMessage());
}
endforeach;
if($epginfo) epgzip($epginfo);
}
// Get EPG data from LG
function GetEPGFromLG($ChannelInfo) {
$ChannelId = $ChannelInfo[0];
$ChannelName = $ChannelInfo[1];
$ServiceId = $ChannelInfo[3];
$epginfo = array();
foreach(range(1, $GLOBALS['period']) as $k) :
$url = "http://www.uplus.co.kr/css/chgi/chgi/RetrieveTvSchedule.hpi";
$day = date("Ymd", strtotime("+".($k - 1)." days"));
$params = array(
'chnlCd' => $ServiceId,
'evntCmpYmd' => $day
);
$params = http_build_query($params);
$method = "POST";
try {
$response = getWeb($url, $params, $method);
if ($response === False && $GLOBALS['debug']) :
printError($ChannelName.HTTP_ERROR);
else :
$response = mb_convert_encoding($response, "UTF-8", "EUC-KR");
$response = str_replace(array('<재>', ' [..', ' (..'), array('&lt;재&gt;', '', ''), $response);
$dom = new DomDocument;
libxml_use_internal_errors(True);
if($dom->loadHTML('<?xml encoding="utf-8" ?>'.$response)):
$xpath = new DomXPath($dom);
$query = "//div[@class='tblType list']/table/tbody/tr";
$rows = $xpath->query($query);
foreach($rows as $row) :
$startTime = $endTime = $programName = $subprogramName = $desc = $actors = $producers = $category = $episode = "";
$rebroadcast = False;
$rating = 0;
$cells = $row->getElementsByTagName('td');
$startTime = date("YmdHis", strtotime($day." ".trim($cells->item(0)->nodeValue)));
$programName = trim($cells->item(1)->childNodes->item(0)->nodeValue);
$pattern = '/(<재>)?\s?(?:\[.*?\])?(.*?)(?:\[(.*)\])?\s?(?:\(([\d,]+)회\))?$/';
preg_match($pattern, $programName, $matches);
if ($matches != NULL) :
if(isset($matches[2])) $programName = trim($matches[2]) ?: "";
if(isset($matches[3])) $subprogramName = trim($matches[3]) ?: "";
if(isset($matches[4])) $episode = trim($matches[4]) ?: "";
if(isset($matches[1])) $rebroadcast = trim($matches[1]) ? True: False;
endif;
$category = trim($cells->item(2)->nodeValue);
$spans = $cells->item(1)->getElementsByTagName('span');
$rating = trim($spans->item(1)->nodeValue)=="All" ? 0 : trim($spans->item(1)->nodeValue);
//ChannelId, startTime, programName, subprogramName, desc, actors, producers, category, episode, rebroadcast, rating
$epginfo[] = array($ChannelId, $startTime, $programName, $subprogramName, $desc, $actors, $producers, $category, $episode, $rebroadcast, $rating);
usleep(1000);
endforeach;
else :
if($GLOBALS['debug']) printError($ChannelName.CONTENT_ERROR);
endif;
endif;
} catch (Exception $e) {
if($GLOBALS['debug']) printError($e->getMessage());
}
endforeach;
if($epginfo) epgzip($epginfo);
}
// Get EPG data from SK
function GetEPGFromSK($ChannelInfo) {
$ChannelId = $ChannelInfo[0];
$ChannelName = $ChannelInfo[1];
$ServiceId = $ChannelInfo[3];
$today = date("Ymd");
$lastday = date("Ymd", strtotime("+".($GLOBALS['period'] - 1)." days"));
$url = "http://m.btvplus.co.kr/common/inc/IFGetData.do";
$params = array(
'variable' => 'IF_LIVECHART_DETAIL',
'pcode' => '|^|start_time='.$today.'00|^|end_time='.$lastday.'24|^|svc_id='.$ServiceId
);
$params = http_build_query($params);
$method = "POST";
try {
$response = getWeb($url, $params, $method);
if ($response === False && $GLOBALS['debug']) :
printError($ChannelName.HTTP_ERROR);
else :
try {
$data = json_decode($response, TRUE);
if(json_last_error() != JSON_ERROR_NONE) throw new Exception(JSON_SYNTAX_ERROR);
if($data['channel'] == NULL) :
if($GLOBALS['debug']) :
printError($ChannelName.CHANNEL_ERROR);
endif;
else :
$programs = $data['channel']['programs'];
foreach ($programs as $program) :
$startTime = $endTime = $programName = $subprogramName = $desc = $actors = $producers = $category = $episode = "";
$rebroadcast = False;
$rating = 0;
$pattern = '/^(.*?)(?:\s*[\(<]([\d,회]+)[\)>])?(?:\s*<([^<]*?)>)?(\((재)\))?$/';
preg_match($pattern, str_replace('...', '>', $program['programName']), $matches);
if ($matches != NULL) :
if(isset($matches[1])) $programName = trim($matches[1]) ?: "";
if(isset($matches[3])) $subprogramName = trim($matches[3]) ?: "";
if(isset($matches[2])) $episode = str_replace("", "", $matches[2]) ?: "";
if(isset($matches[5])) $rebroadcast = $matches[5] ? True : False;
endif;
$startTime = date("YmdHis",$program['startTime']/1000);
$endTime = date("YmdHis",$program['endTime']/1000);
$desc = $program['synopsis'] ?: "";
$actors =trim(str_replace('...','',$program['actorName']), ', ') ?: "";
$producers = trim(str_replace('...','',$program['directorName']), ', ') ?: "";
if ($program['mainGenreName'] != NULL) :
$category = $program['mainGenreName'];
else:
$category = "";
endif;
$rating = $program['ratingCd'] ?: 0;
$programdata = array(
'channelId'=> $ChannelId,
'startTime' => $startTime,
'endTime' => $endTime,
'programName' => $programName,
'subprogramName'=> $subprogramName,
'desc' => $desc,
'actors' => $actors,
'producers' => $producers,
'category' => $category,
'episode' => $episode,
'rebroadcast' => $rebroadcast,
'rating' => $rating
);
writeProgram($programdata);
usleep(1000);
endforeach;
endif;
} catch(Exception $e) {
if($GLOBALS['debug']) printError($e->getMessage());
}
endif;
} catch (Exception $e) {
if($GLOBALS['debug']) printError($e->getMessage());
}
}
// Get EPG data from SKB
function GetEPGFromSKB($ChannelInfo) {
$ChannelId = $ChannelInfo[0];
$ChannelName = $ChannelInfo[1];
$ServiceId = $ChannelInfo[3];
$epginfo = array();
foreach(range(1, $GLOBALS['period']) as $k) :
$url = "http://m.skbroadband.com/content/realtime/Channel_List.do";
$day = date("Ymd", strtotime("+".($k - 1)." days"));
$params = array(
'key_depth2' => $ServiceId,
'key_depth3' => $day
);
$params = http_build_query($params);
$method = "POST";
try {
$response = getWeb($url, $params, $method);
if ($response === False && $GLOBALS['debug']) :
printError($ChannelName.HTTP_ERROR);
else :
$response = str_replace('charset="EUC-KR"', 'charset="UTF-8"', $response);
$response = mb_convert_encoding($response, "UTF-8", "EUC-KR");
$response = preg_replace('/<!--(.*?)-->/is', '', $response);
$response = preg_replace('/<span class="round_flag flag02">(.*?)<\/span>/', '', $response);
$response = preg_replace('/<span class="round_flag flag03">(.*?)<\/span>/', '', $response);
$response = preg_replace('/<span class="round_flag flag04">(.*?)<\/span>/', '', $response);
$response = preg_replace('/<span class="round_flag flag09">(.*?)<\/span>/', '', $response);
$response = preg_replace('/<span class="round_flag flag10">(.*?)<\/span>/', '', $response);
$response = preg_replace('/<span class="round_flag flag11">(.*?)<\/span>/', '', $response);
$response = preg_replace('/<span class="round_flag flag12">(.*?)<\/span>/', '', $response);
$response = preg_replace('/<strong class="hide">프로그램 안내<\/strong>/', '', $response);
$response = preg_replace_callback('/<p class="cont">(.*)/', 'converthtmlspecialchars', $response);
$response = preg_replace_callback('/<p class="tit">(.*)/', 'converthtmlspecialchars', $response);
$dom = new DomDocument;
libxml_use_internal_errors(True);
if($dom->loadHTML('<?xml encoding="utf-8" ?>'.$response)):
$xpath = new DomXPath($dom);
$query = "//span[@class='caption' or @class='explan' or @class='fullHD' or @class='UHD' or @class='nowon']";
$spans = $xpath->query($query);
foreach($spans as $span) :
$span->parentNode->removeChild( $span);
endforeach;
$query = "//div[@id='uiScheduleTabContent']/div/ol/li";
$rows = $xpath->query($query);
foreach($rows as $row) :
$startTime = $endTime = $programName = $subprogramName = $desc = $actors = $producers = $category = $episode = "";
$rebroadcast = False;
$rating = 0;
$cells = $row->getElementsByTagName('p');
$startTime = $cells->item(0)->nodeValue ?: "";
$startTime = date("YmdHis", strtotime($day." ".$startTime));
$programName = trim($cells->item(1)->childNodes->item(0)->nodeValue) ?: "";
$pattern = '/^(.*?)(\(([\d,]+)회\))?(<(.*)>)?(\((재)\))?$/';
preg_match($pattern, $programName, $matches);
if ($matches != NULL) :
if(isset($matches[1])) $programName = trim($matches[1]) ?: "";
if(isset($matches[5])) $subprogramName = trim($matches[5]) ?: "";
if(isset($matches[3])) $episode = $matches[3] ?: "";
if(isset($matches[7])) $rebroadcast = $matches[7] ? True : False;
endif;
if(trim($cells->item(1)->childNodes->item(1)->nodeValue)) $rating = str_replace('세 이상', '', trim($cells->item(1)->childNodes->item(1)->nodeValue)) ?: 0;
//ChannelId, startTime, programName, subprogramName, desc, actors, producers, category, episode, rebroadcast, rating
$epginfo[] = array($ChannelId, $startTime, $programName, $subprogramName, $desc, $actors, $producers, $category, $episode, $rebroadcast, $rating);
usleep(1000);
endforeach;
else :
if($GLOBALS['debug']) printError($ChannelName.CONTENT_ERROR);
endif;
endif;
} catch (Exception $e) {
if($GLOBALS['debug']) printError($e->getMessage());
}
endforeach;
if($epginfo) epgzip($epginfo);
}
// Get EPG data from Naver
function GetEPGFromNaver($ChannelInfo) {
$ChannelId = $ChannelInfo[0];
$ChannelName = $ChannelInfo[1];
$ServiceId = $ChannelInfo[3];
$epginfo = array();
$totaldate = array();
$url = "https://search.naver.com/p/csearch/content/batchrender_ssl.nhn";
foreach(range(1, $GLOBALS['period']) as $k) :
$day = date("Ymd", strtotime("+".($k - 1)." days"));
$totaldate[] = $day;
endforeach;
$params = array(
'_callback' => 'epg',
'fileKey' => 'single_schedule_channel_day',
'pkid' => '66',
'u1' => 'single_schedule_channel_day',
'u2' => join(",", $totaldate),
'u3' => $day,
'u4' => $GLOBALS['period'],
'u5' => $ServiceId,
'u6' => 1,
'u7' => $ChannelName."편성표",
'u8' => $ChannelName."편성표",
'where' => 'nexearch'
);
$params = http_build_query($params);
$method = "GET";
try {
$response = getWeb($url, $params, $method);
if ($response === False && $GLOBALS['debug']) :
printError($ChannelName.HTTP_ERROR);
else :
try {
$response = str_replace('epg( ', '', $response );
$response = substr($response, 0, strlen($response)-2);
$response = preg_replace("/\/\*.*?\*\//","",$response);
$data = json_decode($response, TRUE);
if(json_last_error() != JSON_ERROR_NONE) throw new Exception(JSON_SYNTAX_ERROR);
if($data['displayDates'][0]['count'] == 0) :
if($GLOBALS['debug']) :
printError($ChannelName.CHANNEL_ERROR);
endif;
else :
for($i = 0; $i < count($data['displayDates']); $i++) :
for($j = 0; $j < 24; $j++) :
foreach($data['schedules'][$j][$i] as $program) :
$startTime = $endTime = $programName = $subprogramName = $desc = $actors = $producers = $category = $episode = "";
$rebroadcast = False;
$rating = 0;
$startTime = date("YmdHis", strtotime($data['displayDates'][$i]['date']." ".$program['startTime']));
$programName = htmlspecialchars_decode(trim($program['title']), ENT_XML1);
$episode = str_replace("","", $program['episode']);
$rebroadcast = $program['isRerun'] ? True : False;
$rating = $program['grade'];
//ChannelId, startTime, programName, subprogramName, desc, actors, producers, category, episode, rebroadcast, rating
$epginfo[] = array($ChannelId, $startTime, $programName, $subprogramName, $desc, $actors, $producers, $category, $episode, $rebroadcast, $rating);
usleep(1000);
endforeach;
endfor;
endfor;
endif;
} catch(Exception $e) {
if($GLOBALS['debug']) printError($e->getMessage());
}
endif;
} catch (Exception $e) {
if($GLOBALS['debug']) printError($e->getMessage());
}
if($epginfo) epgzip($epginfo);
}
# Zip epginfo
function epgzip($epginfo) {
$epg1 = current($epginfo);
array_shift($epginfo);
foreach($epginfo as $epg2):
$ChannelId = $epg1[0] ?: "";
$startTime = $epg1[1] ?: "";
$endTime = $epg2[1] ?: "";
$programName = $epg1[2] ?: "";
$subprogramName = $epg1[3] ?: "";
$desc = $epg1[4] ?: "";
$actors = $epg1[5] ?: "";
$producers = $epg1[6] ?: "";
$category = $epg1[7] ?: "";
$episode = $epg1[8] ?: "";
$rebroadcast = $rebroadcast = $epg1[9] ? True: False;
$rating = $epg1[10] ?: 0;
$programdata = array(
'channelId'=> $ChannelId,
'startTime' => $startTime,
'endTime' => $endTime,
'programName' => $programName,
'subprogramName'=> $subprogramName,
'desc' => $desc,
'actors' => $actors,
'producers' => $producers,
'category' => $category,
'episode' => $episode,
'rebroadcast' => $rebroadcast,
'rating' => $rating
);
writeProgram($programdata);
$epg1 = $epg2;
endforeach;
}
function writeProgram($programdata) {
$fp = $GLOBALS['fp'];
$ChannelId = $programdata['channelId'];
$startTime = $programdata['startTime'];
$endTime = $programdata['endTime'];
$programName = trim(htmlspecialchars($programdata['programName'], ENT_XML1));
$subprogramName = trim(htmlspecialchars($programdata['subprogramName'], ENT_XML1));
preg_match('/(.*) \(?(\d+부)\)?/', $programName, $matches);
if ($matches != NULL) :
if(isset($matches[1])) $programName = trim($matches[1]) ?: "";
if(isset($matches[2])) $subprogramName = trim($matches[2]." ".$subprogramName) ?: "";
endif;//
if($programName == NULL):
$programName = $subprogramName;
endif;
$actors = htmlspecialchars($programdata['actors'], ENT_XML1);
$producers = htmlspecialchars($programdata['producers'], ENT_XML1);
$category = htmlspecialchars($programdata['category'], ENT_XML1);
$episode = $programdata['episode'];
if($episode) :
$episode_ns = (int)$episode - 1;
$episode_ns = '0' . '.' . $episode_ns . '.' . '0' . '/' . '0';
$episode_on = $episode;
endif;
$rebroadcast = $programdata['rebroadcast'];
if($episode && $GLOBALS['addepisode'] == 'y') $programName = $programName." (".$episode."회)";
if($rebroadcast == True && $GLOBALS['addrebroadcast'] == 'y') $programName = $programName." (재)";
if($programdata['rating'] == 0) :
$rating = "전체 관람가";
else :
$rating = sprintf("%s세 이상 관람가", $programdata['rating']);
endif;
if($GLOBALS['addverbose'] == 'y') :
$desc = $programName;
if($subprogramName) $desc = $desc."\n부제 : ".$subprogramName;
if($rebroadcast == True && $GLOBALS['addrebroadcast'] == 'y') $desc = $desc."\n방송 : 재방송";
if($episode) $desc = $desc."\n회차 : ".$episode."";
if($category) $desc = $desc."\n장르 : ".$category;
if($actors) $desc = $desc."\n출연 : ".trim($actors);
if($producers) $desc = $desc."\n제작 : ".trim($producers);
$desc = $desc."\n등급 : ".$rating;
else:
$desc = "";
endif;
if($programdata['desc']) $desc = $desc."\n".htmlspecialchars($programdata['desc'], ENT_XML1);
$desc = preg_replace('/ +/', ' ', $desc);
$contentTypeDict = array(
'교양' => 'Arts / Culture (without music)',
'만화' => 'Cartoons / Puppets',
'교육' => 'Education / Science / Factual topics',
'취미' => 'Leisure hobbies',
'드라마' => 'Movie / Drama',
'영화' => 'Movie / Drama',
'음악' => 'Music / Ballet / Dance',
'뉴스' => 'News / Current affairs',
'다큐' => 'Documentary',
'라이프' => 'Documentary',
'시사/다큐' => 'Documentary',
'연예' => 'Show / Game show',
'스포츠' => 'Sports',
'홈쇼핑' => 'Advertisement / Shopping'
);
$contentType = "";
foreach($contentTypeDict as $key => $value) :
if(!(strpos($category, $key) === False)) :
$contentType = $value;
endif;
endforeach;
fprintf($fp, " <programme start=\"%s +0900\" stop=\"%s +0900\" channel=\"%s\">\n", $startTime, $endTime, $ChannelId);
fprintf($fp, " <title lang=\"kr\">%s</title>\n", $programName);
if($subprogramName) :
fprintf($fp, " <sub-title lang=\"kr\">%s</sub-title>\n", $subprogramName);
endif;
if($GLOBALS['addverbose']=='y') :
fprintf($fp, " <desc lang=\"kr\">%s</desc>\n", $desc);
if($actors || $producers):
fprintf($fp, " <credits>\n");
if($actors) :
foreach(explode(',', $actors) as $actor):
if(trim($actor)) fprintf($fp, " <actor>%s</actor>\n", trim($actor));
endforeach;
endif;
if($producers) :
foreach(explode(',', $producers) as $producer):
if(trim($producer)) fprintf($fp, " <producer>%s</producer>\n", trim($producer));
endforeach;
endif;
fprintf($fp, " </credits>\n");
endif;
endif;
if($category) fprintf($fp, " <category lang=\"kr\">%s</category>\n", $category);
if($contentType) fprintf($fp, " <category lang=\"en\">%s</category>\n", $contentType);
if($episode && $GLOBALS['addxmltvns']=='y') fprintf($fp, " <episode-num system=\"xmltv_ns\">%s</episode-num>\n", $episode_ns);
if($episode && $GLOBALS['addxmltvns']!='y') fprintf($fp, " <episode-num system=\"onscreen\">%s</episode-num>\n", $episode_on);
if($rebroadcast) fprintf($fp, " <previously-shown />\n");
if($rating) :
fprintf($fp, " <rating system=\"KMRB\">\n");
fprintf($fp, " <value>%s</value>\n", $rating);
fprintf($fp, " </rating>\n");
endif;
fprintf($fp, " </programme>\n");
}
function getWeb($url, $params, $method) {
$ch = curl_init();
if($method == "GET"):
$url = $url."?".$params;
elseif($method == "POST"):
curl_setopt ($ch, CURLOPT_POST, True);
curl_setopt ($ch, CURLOPT_POSTFIELDS, $params);
endif;
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, True);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $GLOBALS['timeout']);
curl_setopt($ch, CURLOPT_HEADER, False);
curl_setopt($ch, CURLOPT_FAILONERROR, True);
curl_setopt($ch, CURLOPT_USERAGENT, $GLOBALS['ua']);
$response = curl_exec($ch);
if(curl_error($ch) && $GLOBALS['debug']) printError($url." ".curl_error($ch));
curl_close($ch);
return $response;
}
function printLog($string) {
if(php_sapi_name() == "cli"):
fwrite(STDERR, $string."\n");
else:
header("Content-Type: text/plain; charset=utf-8");
print($string."\n");
endif;
}
function printError($string) {
if(php_sapi_name() == "cli"):
fwrite(STDERR, "Error : ".$string."\n");
else:
header("Content-Type: text/plain; charset=utf-8");
print("Error : ".$string."\n");
endif;
}
function _microtime() {
list($usec, $sec) = explode(" ", microtime());
return ($sec.(int)($usec*1000));
}
function startsWith($haystack, $needle) {
return !strncmp($haystack, $needle, strlen($needle));
}
function converthtmlspecialchars($match) {
return '<p class="cont">'.htmlspecialchars($match[1]);
}
//사용방법
$usage = <<<USAGE
usage: epg2xml.py [-h] [-i {ALL,KT,LG,SK}] [-v | -d | -o [xmltv.xml] | -s
[xmltv.sock]] [--icon http://www.example.com/icon] [-l 1-2]
[--rebroadcast y, n] [--episode y, n] [--verbose y, n]
USAGE;
//도움말
$help = <<<HELP
usage: epg2xml.php [-h] [-i {ALL,KT,LG,SK}]
[-v | -d | -o [xmltv.xml]
| -s [xmltv.sock]] [--icon http://www.example.com/icon]
[-l 1-2] [--rebroadcast y, n] [--episode y, n]
[--verbose y, n]
EPG 정보를 출력하는 방법을 선택한다
optional arguments:
-h, --help show this help message and exit
-v, --version show program's version number and exit
-d, --display EPG 정보 화면출력
-o [xmltv.xml], --outfile [xmltv.xml]
EPG 정보 저장
-s [xmltv.sock], --socket [xmltv.sock]
xmltv.sock(External: XMLTV) EPG정보 전송
IPTV 선택
-i {ALL,KT,LG,SK} 사용하는 IPTV : ALL, KT, LG, SK
추가옵션:
--icon http://www.example.com/icon
채널 아이콘 URL, 기본값:
-l 1-2, --limit 1-2 EPG 정보를 가져올 기간, 기본값: 2
--rebroadcast y, n 제목에 재방송 정보 출력
--episode y, n 제목에 회차 정보 출력
--verbose y, n EPG 정보 추가 출력
HELP;
?>

View File

@ -2,15 +2,14 @@
"###_COMMENT_###" : "", "###_COMMENT_###" : "",
"###_COMMENT_###" : "epg 정보를 가져오는 설정 파일", "###_COMMENT_###" : "epg 정보를 가져오는 설정 파일",
"###_COMMENT_###" : "사용하는 ISP 선택 (ALL, KT, LG, SK)", "###_COMMENT_###" : "사용하는 ISP 선택 (ALL, KT, LG, SK)",
"MyISP": "ALL", "MyISP": "SK",
"###_COMMENT_###" : "### # My Channel EPG 정보 가져오는 채널 ID ###", "###_COMMENT_###" : "### # My Channel EPG 정보 가져오는 채널 ID ###",
"###_COMMENT_###" : "### 채널 ID를 , 로 구분하여 입력 ###", "###_COMMENT_###" : "### 채널 ID를 , 로 구분하여 입력 ###",
"MyChannels" : "60, 110, 111, 122, 164",
"###_COMMENT_###" : "output 셋팅은 (d, o, s) 셋중에 하나로 선택한다", "###_COMMENT_###" : "output 셋팅은 (d, o, s) 셋중에 하나로 선택한다",
"###_COMMENT_###" : " d - EPG 정보 화면 출력", "###_COMMENT_###" : " d - EPG 정보 화면 출력",
"###_COMMENT_###" : " o - EPG 정보 파일로 저장", "###_COMMENT_###" : " o - EPG 정보 파일로 저장",
"###_COMMENT_###" : " s - EPG 정보 소켓으로 출력", "###_COMMENT_###" : " s - EPG 정보 소켓으로 출력",
"output": "d", "output": "s",
"###_COMMENT_###" : "### TV channel icon url (ex : http://www.example.com/Channels) ###", "###_COMMENT_###" : "### TV channel icon url (ex : http://www.example.com/Channels) ###",
"default_icon_url": "", "default_icon_url": "",
"###_COMMENT_###" : "### 제목에 재방송 정보 출력 ###", "###_COMMENT_###" : "### 제목에 재방송 정보 출력 ###",
@ -22,10 +21,10 @@
"###_COMMENT_###" : "### XMLTV_NS 정보 추가 출력 ###", "###_COMMENT_###" : "### XMLTV_NS 정보 추가 출력 ###",
"default_xmltvns" : "n", "default_xmltvns" : "n",
"###_COMMENT_###" : "### epg 데이터 가져오는 기간으로 1에서 7까지 설정가능 ###", "###_COMMENT_###" : "### epg 데이터 가져오는 기간으로 1에서 7까지 설정가능 ###",
"default_fetch_limit" : "2", "default_fetch_limit" : "4",
"###_COMMENT_###" : "### epg 저장시 기본 저장 이름 (ex: /home/tvheadend/xmltv.xml) ###", "###_COMMENT_###" : "### epg 저장시 기본 저장 이름 (ex: /home/tvheadend/xmltv.xml) ###",
"default_xml_file" : "xmltv.xml", "default_xml_file" : "xmltv.xml",
"###_COMMENT_###" : "### # External XMLTV 사용시 기본 소켓 이름 (ex: /home/tvheadend/xmltv.sock) ###", "###_COMMENT_###" : "### # External XMLTV 사용시 기본 소켓 이름 (ex: /home/tvheadend/xmltv.sock) ###",
"default_xml_socket" : "xmltv.sock", "default_xml_socket" : "/sock/xmltv.sock",
"###_COMMENT_###" : "" "###_COMMENT_###" : ""
} }

View File

@ -1,4 +0,0 @@
#!/usr/bin/env php
<?php
include __DIR__."/epg2xml-web.php";
?>

View File

@ -1,8 +1,8 @@
#!/usr/bin/env python2 #!/usr/bin/env python3.7
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import print_function from __future__ import print_function
import imp import importlib.util
import os import os
import sys import sys
import json import json
@ -16,35 +16,34 @@ import argparse
import pprint import pprint
from functools import partial from functools import partial
import time import time
try: try:
imp.find_module('bs4') importlib.util.find_spec('bs4')
from bs4 import BeautifulSoup, SoupStrainer from bs4 import BeautifulSoup, SoupStrainer
except ImportError: except ImportError:
print("Error : ", "BeautifulSoup 모듈이 설치되지 않았습니다.", file=sys.stderr) print("Error : ", "BeautifulSoup 모듈이 설치되지 않았습니다.", file=sys.stderr)
sys.exit() sys.exit()
try: try:
imp.find_module('lxml') importlib.util.find_spec('lxml')
from lxml import html from lxml import html
except ImportError: except ImportError:
print("Error : ", "lxml 모듈이 설치되지 않았습니다.", file=sys.stderr) print("Error : ", "lxml 모듈이 설치되지 않았습니다.", file=sys.stderr)
sys.exit() sys.exit()
try: try:
imp.find_module('requests') importlib.util.find_spec('requests')
import requests import requests
except ImportError: except ImportError:
print("Error : ", "requests 모듈이 설치되지 않았습니다.", file=sys.stderr) print("Error : ", "requests 모듈이 설치되지 않았습니다.", file=sys.stderr)
sys.exit() sys.exit()
reload(sys) sys.stdout.reconfigure(encoding='utf-8')
sys.setdefaultencoding('utf-8') sys.stdin.reconfigure(encoding='utf-8')
if not sys.version_info[:2] == (2, 7): # if not sys.version_info[:2] == (2, 7):
print("Error : ", "python 2.7 버전이 필요합니다.", file=sys.stderr) # print("Error : ", "python 2.7 버전이 필요합니다.", file=sys.stderr)
sys.exit() # sys.exit()
# Set variable # Set variable
__version__ = '1.2.6' __version__ = '2.0.0'
debug = False debug = False
today = datetime.date.today() today = datetime.date.today()
ua = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116'} ua = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116'}
@ -62,7 +61,7 @@ def getEpg():
Channelfile = os.path.dirname(os.path.abspath(__file__)) + '/Channel.json' Channelfile = os.path.dirname(os.path.abspath(__file__)) + '/Channel.json'
ChannelInfos = [] ChannelInfos = []
try: try:
with open(Channelfile) as f: # Read Channel Information file with open(Channelfile, encoding="utf-8") as f: # Read Channel Information file
Channeldatajson = json.load(f) Channeldatajson = json.load(f)
except EnvironmentError: except EnvironmentError:
printError("Channel." + JSON_FILE_ERROR) printError("Channel." + JSON_FILE_ERROR)
@ -74,12 +73,8 @@ def getEpg():
print('<!DOCTYPE tv SYSTEM "xmltv.dtd">\n') print('<!DOCTYPE tv SYSTEM "xmltv.dtd">\n')
print('<tv generator-info-name="epg2xml ' + __version__ + '">') print('<tv generator-info-name="epg2xml ' + __version__ + '">')
# My Channel 정의 # My Channel 정의
MyChannelInfo = []
if MyChannels :
for MyChannel in MyChannels.split(','):
MyChannelInfo.append(int(MyChannel.strip()))
for Channeldata in Channeldatajson: #Get Channel & Print Channel info for Channeldata in Channeldatajson: #Get Channel & Print Channel info
if Channeldata['Id'] in MyChannelInfo: # if Channeldata['Id'] is 223:
ChannelId = Channeldata['Id'] ChannelId = Channeldata['Id']
ChannelName = escape(Channeldata['Name']) ChannelName = escape(Channeldata['Name'])
ChannelSource = Channeldata['Source'] ChannelSource = Channeldata['Source']
@ -141,10 +136,17 @@ def GetEPGFromKT(ChannelInfo):
try: try:
response = requests.post(url, data=params, headers=ua, timeout=timeout) response = requests.post(url, data=params, headers=ua, timeout=timeout)
response.raise_for_status() response.raise_for_status()
html_data = response.content
data = unicode(html_data, 'euc-kr', 'ignore').encode('utf-8', 'ignore')
html_data = (response.content).decode("euc-kr")
# data = unicode(html_data, 'euc-kr', 'ignore').encode('utf-8', 'ignore')
data = html_data
print(data)
strainer = SoupStrainer('tbody') strainer = SoupStrainer('tbody')
soup = BeautifulSoup(data, htmlparser, parse_only=strainer, from_encoding='utf-8') soup = BeautifulSoup(data, htmlparser, parse_only=strainer)
html = soup.find_all('tr') if soup.find('tbody') else '' html = soup.find_all('tr') if soup.find('tbody') else ''
if(html): if(html):
for row in html: for row in html:
@ -187,11 +189,12 @@ def GetEPGFromLG(ChannelInfo):
try: try:
response = requests.post(url, data=params, headers=ua, timeout=timeout) response = requests.post(url, data=params, headers=ua, timeout=timeout)
response.raise_for_status() response.raise_for_status()
html_data = response.content html_data = (response.content).decode("euc-kr")
data = unicode(html_data, 'euc-kr', 'ignore').encode('utf-8', 'ignore') # data = unicode(html_data, 'euc-kr', 'ignore').encode('utf-8', 'ignore')
data = html_data
data = data.replace('<재>', '&lt;재&gt;').replace(' [..','').replace(' (..', '') data = data.replace('<재>', '&lt;재&gt;').replace(' [..','').replace(' (..', '')
strainer = SoupStrainer('table') strainer = SoupStrainer('table')
soup = BeautifulSoup(data, htmlparser, parse_only=strainer, from_encoding='utf-8') soup = BeautifulSoup(data, htmlparser, parse_only=strainer)
html = soup.find('table').tbody.find_all('tr') if soup.find('table') else '' html = soup.find('table').tbody.find_all('tr') if soup.find('table') else ''
if(html): if(html):
for row in html: for row in html:
@ -205,7 +208,7 @@ def GetEPGFromLG(ChannelInfo):
rating = 0 if cell[1].find('span', {'class': 'tag cte_all'}).text.strip()=="All" else int(cell[1].find('span', {'class': 'tag cte_all'}).text.strip()) rating = 0 if cell[1].find('span', {'class': 'tag cte_all'}).text.strip()=="All" else int(cell[1].find('span', {'class': 'tag cte_all'}).text.strip())
cell[1].find('span', {'class': 'tagGroup'}).decompose() cell[1].find('span', {'class': 'tagGroup'}).decompose()
pattern = '(<재>)?\s?(?:\[.*?\])?(.*?)(?:\[(.*)\])?\s?(?:\(([\d,]+)회\))?$' pattern = '(<재>)?\s?(?:\[.*?\])?(.*?)(?:\[(.*)\])?\s?(?:\(([\d,]+)회\))?$'
matches = re.match(pattern, cell[1].text.strip().decode('string_escape')) matches = re.match(pattern, cell[1].text.strip())
if not (matches is None): if not (matches is None):
programName = matches.group(2).strip() if matches.group(2) else '' programName = matches.group(2).strip() if matches.group(2) else ''
subprogramName = matches.group(3).strip() if matches.group(3) else '' subprogramName = matches.group(3).strip() if matches.group(3) else ''
@ -239,7 +242,7 @@ def GetEPGFromSK(ChannelInfo):
try: try:
data = json.loads(json_data, encoding='utf-8') data = json.loads(json_data, encoding='utf-8')
if (data['channel'] is None) : if (data['channel'] is None) :
if(debug): printError(ChannelName + CONTENT_ERROR) if(True): printError(ChannelName + CONTENT_ERROR)
else: pass else: pass
else : else :
programs = data['channel']['programs'] programs = data['channel']['programs']
@ -249,7 +252,7 @@ def GetEPGFromSK(ChannelInfo):
rating = 0 rating = 0
programName = program['programName'].replace('...', '>').encode('utf-8') programName = program['programName'].replace('...', '>').encode('utf-8')
pattern = '^(.*?)(?:\s*[\(<]([\d,회]+)[\)>])?(?:\s*<([^<]*?)>)?(\((재)\))?$' pattern = '^(.*?)(?:\s*[\(<]([\d,회]+)[\)>])?(?:\s*<([^<]*?)>)?(\((재)\))?$'
matches = re.match(pattern, programName) matches = re.match(pattern, programName.decode('utf-8'))
if not (matches is None): if not (matches is None):
programName = matches.group(1).strip() if matches.group(1) else '' programName = matches.group(1).strip() if matches.group(1) else ''
subprogramName = matches.group(3).strip() if matches.group(3) else '' subprogramName = matches.group(3).strip() if matches.group(3) else ''
@ -289,9 +292,12 @@ def GetEPGFromSKB(ChannelInfo):
try: try:
response = requests.get(url, params=params, headers=ua, timeout=timeout) response = requests.get(url, params=params, headers=ua, timeout=timeout)
response.raise_for_status() response.raise_for_status()
html_data = response.content html_data = (response.content).decode("euc-kr")
data = unicode(html_data, 'euc-kr', 'ignore').encode('utf-8', 'ignore')
data = re.sub('EUC-KR', 'utf-8', data) # data = unicode(html_data, 'euc-kr', 'ignore').encode('utf-8', 'ignore')
data = html_data
data = re.sub("EUC-KR", 'utf-8', data)
data = re.sub('<!--(.*?)-->', '', data, 0, re.I|re.S) data = re.sub('<!--(.*?)-->', '', data, 0, re.I|re.S)
data = re.sub('<span class="round_flag flag02">(.*?)</span>', '', data) data = re.sub('<span class="round_flag flag02">(.*?)</span>', '', data)
data = re.sub('<span class="round_flag flag03">(.*?)</span>', '', data) data = re.sub('<span class="round_flag flag03">(.*?)</span>', '', data)
@ -304,7 +310,7 @@ def GetEPGFromSKB(ChannelInfo):
data = re.sub('<p class="cont">(.*)', partial(replacement, tag='p') , data) data = re.sub('<p class="cont">(.*)', partial(replacement, tag='p') , data)
data = re.sub('<p class="tit">(.*)', partial(replacement, tag='p') , data) data = re.sub('<p class="tit">(.*)', partial(replacement, tag='p') , data)
strainer = SoupStrainer('div', {'id':'uiScheduleTabContent'}) strainer = SoupStrainer('div', {'id':'uiScheduleTabContent'})
soup = BeautifulSoup(data, htmlparser, parse_only=strainer, from_encoding='utf-8') soup = BeautifulSoup(data, htmlparser, parse_only=strainer)
html = soup.find_all('li',{'class':'list'}) if soup.find_all('li') else '' html = soup.find_all('li',{'class':'list'}) if soup.find_all('li') else ''
if(html): if(html):
for row in html: for row in html:
@ -316,14 +322,22 @@ def GetEPGFromSKB(ChannelInfo):
startTime = startTime.strftime('%Y%m%d%H%M%S') startTime = startTime.strftime('%Y%m%d%H%M%S')
cell = row.find('p', {'class':'cont'}) cell = row.find('p', {'class':'cont'})
grade = row.find('i', {'class':'hide'}) grade = row.find('i', {'class':'hide'})
if not(grade is None) : if not(grade is None):
rating = int(grade.text.decode('string_escape').replace('세 이상','').strip()) # rating = int(grade.text.decode('string_escape').replace('세 이상','').strip())
rating = int(grade.text.replace('세 이상','').strip())
if(cell): if(cell):
if cell.find('span'): if cell.find('span'):
cell.span.decompose() cell.span.decompose()
cell = cell.text.decode('string_escape').strip() # cell = cell.text.decode('string_escape').strip()
#cell = cell.text.decode('string_escape').strip()
#print (chardet.detect(cell.text.strip()))
cell=cell.text.strip()
# print (chardet.detect(bytes(cell,'utf-8')))
# cell = cell.text.strip()
pattern = "^(.*?)(\(([\d,]+)회\))?(<(.*)>)?(\((재)\))?$" pattern = "^(.*?)(\(([\d,]+)회\))?(<(.*)>)?(\((재)\))?$"
# print (chardet.detect(pattern))
matches = re.match(pattern, cell) matches = re.match(pattern, cell)
if not(matches is None) : if not(matches is None) :
@ -416,7 +430,7 @@ def writeProgram(programdata):
endTime = programdata['endTime'] endTime = programdata['endTime']
programName = escape(programdata['programName']).strip() programName = escape(programdata['programName']).strip()
subprogramName = escape(programdata['subprogramName']).strip() subprogramName = escape(programdata['subprogramName']).strip()
matches = re.match('(.*) \(?(\d+부)\)?', unescape(programName.encode('utf-8', 'ignore'))) matches = re.match('(.*) \(?(\d+부)\)?', unescape(programName))
if not(matches is None): if not(matches is None):
programName = escape(matches.group(1)).strip(); programName = escape(matches.group(1)).strip();
subprogramName = escape(matches.group(2)) + ' ' + subprogramName subprogramName = escape(matches.group(2)) + ' ' + subprogramName
@ -457,7 +471,7 @@ def writeProgram(programdata):
desc = re.sub(' +',' ', desc) desc = re.sub(' +',' ', desc)
contentTypeDict={'교양':'Arts / Culture (without music)', '만화':'Cartoons / Puppets', '교육':'Education / Science / Factual topics', '취미':'Leisure hobbies', '드라마':'Movie / Drama', '영화':'Movie / Drama', '음악':'Music / Ballet / Dance', '뉴스':'News / Current affairs', '다큐':'Documentary', '라이프':'Documentary', '시사/다큐':'Documentary', '연예':'Show / Game show', '스포츠':'Sports', '홈쇼핑':'Advertisement / Shopping'} contentTypeDict={'교양':'Arts / Culture (without music)', '만화':'Cartoons / Puppets', '교육':'Education / Science / Factual topics', '취미':'Leisure hobbies', '드라마':'Movie / Drama', '영화':'Movie / Drama', '음악':'Music / Ballet / Dance', '뉴스':'News / Current affairs', '다큐':'Documentary', '라이프':'Documentary', '시사/다큐':'Documentary', '연예':'Show / Game show', '스포츠':'Sports', '홈쇼핑':'Advertisement / Shopping'}
contentType = '' contentType = ''
for key, value in contentTypeDict.iteritems(): for key, value in contentTypeDict.items():
if key in category: if key in category:
contentType = value contentType = value
print(' <programme start="%s +0900" stop="%s +0900" channel="%s">' % (startTime, endTime, ChannelId)) print(' <programme start="%s +0900" stop="%s +0900" channel="%s">' % (startTime, endTime, ChannelId))
@ -504,10 +518,9 @@ def replacement(match, tag):
Settingfile = os.path.dirname(os.path.abspath(__file__)) + '/epg2xml.json' Settingfile = os.path.dirname(os.path.abspath(__file__)) + '/epg2xml.json'
ChannelInfos = [] ChannelInfos = []
try: try:
with open(Settingfile) as f: # Read Channel Information file with open(Settingfile, encoding="utf-8") as f: # Read Channel Information file
Settings = json.load(f) Settings = json.load(f)
MyISP = Settings['MyISP'] if 'MyISP' in Settings else 'ALL' MyISP = Settings['MyISP'] if 'MyISP' in Settings else 'ALL'
MyChannels = Settings['MyChannels'] if 'MyChannels' in Settings else ''
default_output = Settings['output'] if 'output' in Settings else 'd' default_output = Settings['output'] if 'output' in Settings else 'd'
default_xml_file = Settings['default_xml_file'] if 'default_xml_file' in Settings else 'xmltv.xml' default_xml_file = Settings['default_xml_file'] if 'default_xml_file' in Settings else 'xmltv.xml'
default_xml_socket = Settings['default_xml_socket'] if 'default_xml_socket' in Settings else 'xmltv.sock' default_xml_socket = Settings['default_xml_socket'] if 'default_xml_socket' in Settings else 'xmltv.sock'
@ -641,7 +654,7 @@ elif output == "socket" :
try: try:
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.connect(default_xml_socket) sock.connect(default_xml_socket)
sockfile = sock.makefile('w+') sockfile = sock.makefile('w')
sys.stdout = sockfile sys.stdout = sockfile
except socket.error: except socket.error:
printError(SOCKET_ERROR) printError(SOCKET_ERROR)

149
skb.py Normal file
View File

@ -0,0 +1,149 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import json
from pprint import pprint
import sys
import codecs
sys.stdout.reconfigure(encoding='utf-8')
sys.stdin.reconfigure(encoding='utf-8')
# reload(sys)
# sys.setdefaultencoding('utf-8')
path = 'skbchannel.txt'
skb_channels = []
channeljson = 'Channel.json'
channeldatas = []
#print (sys.stdin.encoding)
#print (sys.stdout.encoding)
with open(channeljson, encoding="utf-8") as json_data:
channeldatas=json.load(json_data)
json_data.close()
with open(path, encoding="utf-8") as f:
for line in f:
inner_list = [elt.strip() for elt in line.split('\t')]
skb_channels.append(inner_list)
def getChanneldata(a):
#print ("Search:" + a[1])
try:
findchannel=None
for channeldata in channeldatas:
channelnames=[(channeldata['SK Name']), (channeldata['KT Name']), channeldata['LG Name']]
# print (channelnames)
if(a[1] in channelnames):
findchannel = channeldata
break
# print (findchannel['Source'])
# if(findchannel['Source'] is "KT"):
# print (findchannel)
if(findchannel['Source']== "KT"):
print (findchannel['Name'])
if(len(a)<3):
print ("ERR")
findchannel['Name'] = a[1]
findchannel['Id'] = int(a[0])
findchannel['ServiceId'] = a[2]
findchannel['SK Name']=a[1]
findchannel['KT Name']=a[1]
findchannel['LG Name']=a[1]
if(findchannel['Source']== "NAVER"):
print (findchannel['Name'])
if(len(a)<3):
print ("ERR")
findchannel['Name'] = a[1]
findchannel['Id'] = int(a[0])
findchannel['ServiceId'] = a[2]
findchannel['SK Name']=a[1]
findchannel['KT Name']=a[1]
findchannel['LG Name']=a[1]
if(len(a)>2):
findchannel = {"Id": 0,
"Name": "",
"KT Name": "",
"KTCh": 0,
"LG Name": "",
"LGCh": 0,
"SK Name": "",
"SKCh": 0,
"Radio Name": "",
"RadioCh":0 ,
"Icon_url": "",
"Source": "SKB",
"ServiceId": 0}
findchannel['Name'] = a[1]
findchannel['Id'] = int(a[0])
findchannel['ServiceId'] = a[2]
findchannel['SK Name']=a[1]
findchannel['KT Name']=a[1]
findchannel['LG Name']=a[1]
# print (findchannel)
if (findchannel==None):
print ("error:" + a[1]+":"+a[0]+":"+str(len(a)))
# print (findchannel)
findchannel['Id']=int(a[0])
findchannel['SK Name']=a[1]
findchannel['SKCh']=int(a[0])
except Exception as e:
print ("error!!:" + a[1]+":"+a[0])
print (e)
return findchannel
# else:
# print (findchannel)
MyChannelInfos = []
for skb_channel in skb_channels:
MyChannelInfo = getChanneldata(skb_channel)
# print(MyChannelInfo)
if(MyChannelInfo != None):
# MyChannelInfo['Id']=str(skb_channel[0])
# MyChannelInfo['SKCh']= skb_channel[0]
# print(MyChannelInfo)
MyChannelInfos.append(MyChannelInfo)
# else:
# print("None"+skb_channel[1])
with open('Channel.json','w',encoding="utf-8") as outfile:
json.dump(MyChannelInfos, outfile, indent=2,ensure_ascii=False)
#print SKB_CHANNEL
#print skb_channel[0][1]
# //a = Channel name data
# def getChannelNumber(a):
# # print ("AAAA",a[0])
# for skb_channel in skb_channels:
# # print ("BBBB",skb_channel[1])
# if((unicode(skb_channel[1]).find(a[0])>-1) and a[0]!=""):
# return skb_channel[0]
# elif((unicode(skb_channel[1]).find(a[1])>-1) and a[1]!=""):
# return skb_channel[0]
# elif((unicode(skb_channel[1]).find(a[2])>-1) and a[2]!=""):
# return skb_channel[0]
# return None
#
#
# with open('Channel.json') as json_data:
#
# MyChannelInfo = []
#
# # print getChannelNumber('asf')
# # getChannelNumber=""
# for Channeldata in Channeldatajson:
# test=[(Channeldata['SK Name']), (Channeldata['KT Name']), Channeldata['LG Name']]
# channelNumber=getChannelNumber(test)
# # print channelNumber
# if(channelNumber is None):
# print Channeldata['SK Name']
# else :
# # print channelNumber
# Channeldata['Id']=channelNumber
# MyChannelInfo.append(Channeldata)
#
# with open('data.txt','w') as outfile:
# json.dump(MyChannelInfo, outfile)

248
skbchannel.txt Normal file
View File

@ -0,0 +1,248 @@
23 연합뉴스TV
24 YTN
26 SBS CNBC
150 토마토TV
151 한국경제TV
152 MTN
153 매일경제TV
154 팍스경제TV 622
155 이데일리TV
156 서울경제TV
157 YTN 라이프
158 CNN International
159 CNN US
160 BBC World News
161 CGTN
162 Bloomberg TV
163 Channel News Asia
164 내외경제TV
165 부동산토마토 621
166 FOX News Channel 791
167 tbsTV
260 NGC
261 Discovery Channel
262 YTN 사이언스
263 Natgeo People
264 History
265 BBC earth
266 Natgeo Wild HD
267 리얼TV
268 헬스메디TV
269 쿠키건강TV
270 아리랑TV
271 소상공인방송
273 한국직업방송
274 MBC NET
275 소비자TV
276 NBS 한국농업방송 443
277 CCTV4
278 NHK World Premium
279 TV5Monde
280 법률방송
281 채널i
282 국방TV
283 다큐원
284 브릿지TV 446
285 지방자치TV 447
286 다문화TV 448
300 CBS
301 CTS
302 CGNTV
303 Good TV
304 C채널
305 BTN 불교TV
306 BBS 불교방송
307 가톨릭평화방송
308 STB 상생방송
309 원음방송
3 tvN
28 MBC Every1
48 JTBC2
49 E채널
74 INSIGHT TV
80 KBS joy
81 SBS fun E
83 E! Entertainment 789
84 OtvN 527
85 XtvN
86 TVCHOSUN2 631
87 코미디TV
88 K star
89 라이프타임
90 FX
91 FUN TV
92 마이펫TV
93 CMCTV 876
94 Sky Petpark
96 DIA TV
97 채널A플러스 891
98 MBN플러스 892
99 skyENT 893
213 CUBE TV
290 KTV
291 국회방송
292 OUN
293 복지TV
2 공영쇼핑 332
4 홈&쇼핑
6 CJ오쇼핑
8 현대홈쇼핑 321
10 롯데홈쇼핑 323
12 GS SHOP
14 NS홈쇼핑
17 SK stoa
21 K쇼핑
22 신세계쇼핑
25 쇼핑엔티
29 GS MY SHOP
31 롯데OneTV
33 CJ오쇼핑 플러스
37 W쇼핑
39 현대홈쇼핑+Shop
41 NS Shop+
200 JEI 재능 English
201 플레이런TV
202 EBS English
203 EBS +1
204 EBS +2
205 edu TV
118 SPOTV ON
119 SPOTV ON 2 137
120 SPOTV
121 KBSN 스포츠
122 SBS Sports
123 MBC Sports+
124 MBC SPORTS+2
125 sky Sports
126 JTBC3 FOX SPORTS 436
127 SPOTV+
128 SPOTV2
129 IB Sports
130 Billiards TV
131 SBS GOLF
132 JTBC GOLF
133 Golf Channel Korea
134 Eurosport
135 Star Sports
136 OGN
137 SPOTV GAMES
138 스크린골프존 138
139 인도어스포츠
240 바둑TV
241 K-바둑
242 브레인TV
243 FTV
244 FISHING TV
245 ONT
246 sky Travel
247 Mountain TV
249 폴라리스TV
251 리빙TV
27 M.net
230 SBS MTV
231 MBC Music
232 GMTV
233 아이넷 TV
234 Arte TV
235 STINGRAY CLASSICA 787
237 Stingray CMusic 672
238 이벤트TV
239 BET
79 DOG TV
210 On style
211 Fashion N
212 채널 뷰 276
214 KBS W
215 Life U
216 Fox life
217 Gtv
218 동아TV
219 OBSW
220 9colors
221 NHK WORLD JAPAN 783
222 JTBC4 259
223 TRENDY 288
224 CookTV 289
225 Now제주TV 290
226 육아방송
227 실버아이TV
228 시니어TV 291
1 SBS 플러스
30 KBS 드라마
32 MBC 드라마
34 Olive 431
36 드라마큐브
38 드라맥스
40 sky Drama
42 Highlight TV
43 CNTV
44 EDGE TV
45 디원
46 드라마H
47 HQ+
70 UXN
71 UHD Dream TV
72 Asia UHD
73 UMAX 69
101 FOX
102 AXN
103 채널J
104 중화TV
105 채널 Ching
106 Asia N
107 히어로액션
108 채널차이나
109 텔레노벨라
110 채널W 172
51 CATCH ON 1
52 CATCH ON 2
53 Ch CGV
54 OCN
55 SUPER ACTION
56 Screen
57 Mplex
58 Cinef
59 The Movie
60 AsiaM 174
61 인디필름
62 Celestial Movies
320 플레이보이TV
321 미드나잇
322 Viki
323 허니TV
324 핑크하우스
325 디자이어TV
182 뽀요TV 387
183 캐리TV 388
187 english gem 390
188 신기한나라TV
189 키즈톡톡 플러스
190 KBS KIDS
191 어린이TV
192 JEI 재능TV
193 bravo kids 370
194 EBS KIDS 372
195 Baby TV 785
196 대교베이비TV 373
170 Tooniverse
171 디즈니채널
172 디즈니주니어
173 Animax
174 애니원
175 부메랑
176 Nickelodeon
177 카툰네트워크
178 애니플러스
179 애니박스
180 DreamWorks 790
15 JTBC
16 MBN
18 채널A
19 TV CHOSUN 243
5 SBS
7 KBS2
9 KBS1
11 MBC
13 EBS
20 OBS
95 EBS2