#!/usr/bin/python # -*- coding: utf-8 -*- import os import sys import urllib import json import datetime from bs4 import BeautifulSoup import codecs import socket import re from xml.sax.saxutils import escape import argparse reload(sys) sys.setdefaultencoding('utf-8') __version__ = '1.0.1' # Set My Configuration MyISP = 'ChangeThis' # 사용하는 IPTV선택 (ex :KT, LG, SK) userid = 'ChangeThis' #tvheadend admin 아이디 (ex : admin) userpw = 'ChangeThis' #tvheadedn admin 비밀번호 (ex : admin) host = 'ChangeThis' #tvheadend 서버 내부 IP (ex: 192.168.0.2) port = '9981' #tvheadend port ChDelimiter = '-SD' #HD채널과 SD 채널 구분자 offset = 500 # SD Channel Offset Number - SD 채널 사용시 HD 채널과 번호차 iconurl = '' #TV channel icon url (ex : http://www.example.com/Channels) default_xml_filename='xmltv.xml' # epg 저장시 기본 저장 이름 (ex: /home/tvheadend/xmltv.xml) default_xml_socket='xmltv.sock' # External XMLTV 사용시 기본 소켓 이름 (ex: /home/tvheadend/xmltv.sock) # Set My Configuration hostinfo = userid + ':' + userpw + '@' + host + ':' + port # Set date today = datetime.date.today() nextday = today + datetime.timedelta(days=1) # Get Enabled Channel information def getMyChannel(): MyChannelNumber = [] MyChannelurl = 'http://%s/api/channel/grid?all=1&dir=ASC&limit=999999999&sort=number&start=0' % (hostinfo) MyChannels = json.loads(urllib.urlopen(MyChannelurl).read()) for i, MyChannel in enumerate(MyChannels['entries']): if MyChannel['enabled']: if ChDelimiter in MyChannel['name']: MyChannelNumber.append(MyChannel['number'] - offset) else: MyChannelNumber.append(MyChannel['number']) return list(set(MyChannelNumber)) # Get epg data def getEpg(channelnumber): Channelfile = os.path.dirname(os.path.abspath(__file__)) + '/' + MyISP + 'Ch.json' ChannelInfos = [] SiteEPG = [] #For epg.co.kr with open(Channelfile) as f: # Read Channel Information file Channeldata = json.load(f) for chinfo in Channeldata: for i in channelnumber: if i == chinfo[MyISP+'Ch']: ChannelInfos.append([chinfo['Id'], chinfo['Name'], chinfo['Source'], chinfo['ServiceId']]) # Print Channel information for ChannelInfo in ChannelInfos: ChannelId = ChannelInfo[0] ChannelName = escape(ChannelInfo[1]) ChannelSource = ChannelInfo[2] ChannelServiceId = ChannelInfo[3] writeXML('\t' % (ChannelId)) writeXML('\t\t%s' % (ChannelName)) if iconurl: writeXML('\t\t' % (iconurl, ChannelId)) writeXML('\t') # Print Program Information for ChannelInfo in ChannelInfos: ChannelId = ChannelInfo[0] ChannelName = ChannelInfo[1] ChannelSource = ChannelInfo[2] ChannelServiceId = ChannelInfo[3] if ChannelSource == 'EPG': SiteEPG.append([ChannelId, ChannelName, ChannelSource, ChannelServiceId]) elif ChannelSource == 'KT': GetEPGFromKT(ChannelInfo) elif ChannelSource == 'LG': GetEPGFromLG(ChannelInfo) elif ChannelSource == 'SK': GetEPGFromSK(ChannelInfo) elif ChannelSource == 'SKY': GetEPGFromSKY(ChannelInfo) GetEPGFromEPG(SiteEPG) # Get EPG data from epg.co.kr def GetEPGFromEPG(ChannelInfos): pattern = "Preview\('(.*?)','(.*?)','(.*?)','(.*?)','(.*?)','(.*?)','(.*?)'\)\">.*?<\/a>(.*?)<\/td>" p = re.compile(pattern) ChannelInfo = [ChannelInfos[i:i+5] for i in range(0, len(ChannelInfos),5)] for i in range(len(ChannelInfo)): churl = '' for j in range(len(ChannelInfo[i])): churl += 'checkchannel%5B' + str(ChannelInfo[i][j][3]) + '%5D=' + str(ChannelInfo[i][j][0]) + '&' url = 'http://schedule.epg.co.kr/php/guide/schedule_day_on.php?%snext=&old_sub_channel_group=110&old_sub_channel_group=110&old_top_channel_group=2&search_sub_category=&search_sub_channel_group=110&search_top_category=&search_top_channel_group=2&selectday=%s&selectday2=%s&weekchannel=&ymd=%s' % (churl, today, today, today) u = urllib.urlopen(url).read() data = unicode(u, 'euc-kr', 'ignore').encode('utf-8', 'ignore') soup = BeautifulSoup(data,'lxml', from_encoding='utf-8') html = soup.select('td > a[href^="JavaScript:ViewContent"]') for i, cell in enumerate(html): td = cell.parent epgdata = p.findall(str(td)) programName = escape(epgdata[0][1]) channelId = epgdata[0][2] startTime, endTime = epgdata[0][3].split('<br>~') startTime = str(today.year) + '/' + startTime startTime = datetime.datetime.strptime(startTime, "%Y/%m/%d %p %I:%M") startTime = startTime.strftime("%Y%m%d%H%M%S") endTime = str(today.year) + '/' + endTime endTime = datetime.datetime.strptime(endTime, "%Y/%m/%d %p %I:%M") endTime = endTime.strftime("%Y%m%d%H%M%S") category = escape(epgdata[0][4]) actors = escape(epgdata[0][5]) producer = escape(epgdata[0][6]) image = epgdata[0][7] checkRebroadcast = re.search('rebroadcast', image) if not (checkRebroadcast is None) : programName = programName + ' (재방송)' checkRating = re.findall('7|12|15|19', image) if len(checkRating) == 0: rating = '모든 연령 시청가' else: rating = '%s세 이상 시청가' % (checkRating[0]) episode = None checkEpisode = re.search('(?<=\()[\d]+', programName) if not (checkEpisode is None): episode = int(checkEpisode.group()) desc = programName if episode : desc = desc + '\n회차 : ' + str(episode) + '회' desc = desc + '\n장르 : ' + category if actors : desc = desc + '\n출연 : ' + actors if producer : desc = desc + '\n제작 : ' + producer desc = desc + '\n등급 : ' + rating programdata = {'channelId':channelId, 'startTime':startTime, 'endTime':endTime, 'programName':programName, 'desc':desc, 'actors':actors, 'producer':producer, 'category':category, 'episode':episode, 'rating':rating} writeProgram(programdata) # Get EPG data from KT def GetEPGFromKT(ChannelInfo): channelId = ChannelInfo[0] ServiceId = ChannelInfo[3] todayurl = 'http://tv.olleh.com/renewal_sub/liveTv/pop_schedule_week.asp?ch_name=&ch_no=%s&nowdate=%s&seldate=%s&tab_no=1' %(ServiceId, today, today) nextdayurl = 'http://tv.olleh.com/renewal_sub/liveTv/pop_schedule_week.asp?ch_name=&ch_no=%s&nowdate=%s&seldate=%s&tab_no=1' % (ServiceId, nextday, nextday) u1 = urllib.urlopen(todayurl).read() data1 = unicode(u1, 'euc-kr', 'ignore').encode('utf-8', 'ignore') soup1 = BeautifulSoup(data1,'lxml', from_encoding='utf-8') u2 = urllib.urlopen(nextdayurl).read() data2 = unicode(u2, 'euc-kr', 'ignore').encode('utf-8', 'ignore') soup2 = BeautifulSoup(data2,'lxml', from_encoding='utf-8') html = soup1.find('table', {'id':'pop_day'}).tbody.findAll('tr') html1 = soup2.find('table', {'id':'pop_day'}).tbody.findAll('tr') if not (html1 is None) and len(html1) > 0: html2 = soup2.find('table', {'id':'pop_day'}).tbody.findAll('tr')[0] else : html2 = """ 00:00 """ html2 = BeautifulSoup(html2,'lxml', from_encoding='utf-8').findAll('tr')[0] html.append(html2) for row1, row2 in zip(html, html[1:]): for cell1, cell2 in zip([row1.findAll('td')], [row2.findAll('td')]): programName = escape(cell1[1].text).encode('utf-8') startTime = cell1[0].text startTime = str(today) + ' ' + startTime startTime = datetime.datetime.strptime(startTime, "%Y-%m-%d %H:%M") startTime = startTime.strftime("%Y%m%d%H%M%S") endTime = cell2[0].text if endTime == '00:00' : endTime = str(nextday) + ' ' + endTime else : endTime = str(today) + ' ' + endTime endTime = datetime.datetime.strptime(endTime, "%Y-%m-%d %H:%M") endTime = endTime.strftime("%Y%m%d%H%M%S") category = escape(cell1[4].text).encode('utf-8') rating = escape(cell1[2].text).encode('utf-8') if rating == 'all세 이상': rating = '모든 연령 시청가' else: rating = rating + ' 시청가' desc = programName + '\n장르 : ' + category + '\n등급 : ' + rating actors = ''; producer = ''; episode = ''; programdata = {'channelId':channelId, 'startTime':startTime, 'endTime':endTime, 'programName':programName, 'desc':desc, 'actors':actors, 'producer':producer, 'category':category, 'episode':episode, 'rating':rating} writeProgram(programdata) # Get EPG data from LG def GetEPGFromLG(ChannelInfo): pass # Get EPG data from SK def GetEPGFromSK(ChannelInfo): channelId = ChannelInfo[0] ServiceId = ChannelInfo[3] url = 'http://m.btvplus.co.kr/Common/Inc/IFGetData.asp?variable=IF_LIVECHART_DETAIL&pcode=|^|start_time=%s00|^|end_time=%s24|^|svc_id=%s'%(today.strftime("%Y%m%d"), today.strftime("%Y%m%d"), ServiceId) u = urllib.urlopen(url).read() data = json.loads(u, encoding='utf-8') programs = data['channel']['programs'] for program in programs: programName = program['programName'] if programName: programName = escape(programName) programName = programName.replace('(재)', ' (재방송)') actors = program['actorName'] if actors: actors = escape(actors) producer = program['directorName'] if producer: producer = escape(producer) startTime = datetime.datetime.fromtimestamp(int(program['startTime'])/1000) startTime = startTime.strftime("%Y%m%d%H%M%S") endTime = datetime.datetime.fromtimestamp(int(program['endTime'])/1000) endTime = endTime.strftime("%Y%m%d%H%M%S") category = program['mainGenreName'] if category: category = escape(category) rating = program['ratingCd'] if rating == '0': rating = '모든 연령 시청가' else : rating = '%s세 이상 시청가' % (rating) episode = None checkEpisode = re.search('(?<=\()[\d]+', programName) if not (checkEpisode is None): episode = int(checkEpisode.group()) desc = programName if episode : desc = desc + '\n회차 : ' + str(episode) + '회' desc = desc + '\n장르 : ' + category if actors : desc = desc + '\n출연 : ' + actors if producer : desc = desc + '\n제작 : ' + producer desc = desc + '\n등급 : ' + rating programdata = {'channelId':channelId, 'startTime':startTime, 'endTime':endTime, 'programName':programName, 'desc':desc, 'actors':actors, 'producer':producer, 'category':category, 'episode':episode, 'rating':rating} writeProgram(programdata) # Get EPG data from SKY def GetEPGFromSKY(ChannelInfo): channelId = ChannelInfo[0] ServiceId = ChannelInfo[3] url = 'http://www.skylife.co.kr/channel/epg/channelScheduleList.do?area=in&inFd_channel_id=%s&inairdate=%s&indate_type=now' % (ServiceId, today) u = urllib.urlopen(url).read() data = json.loads(u) programs = data['scheduleListIn'] for program in programs: programName = program['program_name'] if programName: programName = escape(programName) rebroadcast = program['rebroad'] if rebroadcast == 'Y': programName = programName + ' (재방송)' actors = program['cast'] if actors: actors = escape(actors) producer = program['dirt'] if producer: producer = escape(producer) startTime = program['starttime'] endTime = program['endtime'] category = program['program_category1'] + '-' + program['program_category2'] if category: category = escape(category) rating = escape(program['grade']) if rating == '0': rating = '모든 연령 시청가' else : rating = '%s세 이상 시청가' % (rating) episode = program['episode_id'] if episode : episode = int(episode) description = program['description'] if description: description = escape(description) summary = program['summary'] if summary: summary = escape(summary) desc = programName if episode : desc = desc + '\n회차 : ' + str(episode) + '회' desc = desc + '\n장르 : ' + category if actors : desc = desc + '\n출연 : ' + actors if producer : desc = desc + '\n제작 : ' + producer desc = desc + '\n등급 : ' + rating if description: desc = desc + '\n' + description if summary : desc = desc + '\n' + summary programdata = {'channelId':channelId, 'startTime':startTime, 'endTime':endTime, 'programName':programName, 'desc':desc, 'actors':actors, 'producer':producer, 'category':category, 'episode':episode, 'rating':rating} writeProgram(programdata) # Write Program def writeProgram(programdata): channelId = programdata['channelId'] startTime = programdata['startTime'] endTime = programdata['endTime'] programName = programdata['programName'] desc = programdata['desc'] actors = programdata['actors'] producer = programdata['producer'] category = programdata['category'] episode = programdata['episode'] rating = programdata['rating'] print '\t' % (startTime, endTime,channelId) print '\t\t%s' % (programName) print '\t\t%s' % (desc) if actors or producer: print '\t\t' if actors: print '\t\t\t%s' % (actors) if producer: print '\t\t\t%s' % (producer) print '\t\t' print '\t\t%s' %(category) if episode: print '\t\t%s' % (episode) print '\t\t\n\t\t\t%s\n\t\t' % (rating) print '\t' # Write XML def writeXML(data): print data parser = argparse.ArgumentParser(description=u'EPG 정보를 출력하는 방법을 결정') cmds = parser.add_mutually_exclusive_group(required=True) parser.add_argument('-v', '--version', action='version', version='%(prog)s ' + __version__) cmds.add_argument('-d', '--display', action='store_true', help='EPG 정보 화면출력') cmds.add_argument('-o', '--outfile', metavar=default_xml_filename, nargs='?', const=default_xml_filename, help='EPG 정보 저장') cmds.add_argument('-s', '--socket', metavar=default_xml_socket, nargs='?', const=default_xml_socket, help='xmltv.sock(External: XMLTV)로 EPG정보 전송') args = parser.parse_args() if args.outfile: sys.stdout = codecs.open(args.outfile, 'w+', encoding='utf-8') elif args.socket: sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) sock.connect(args.socket) sockfile = sock.makefile('w+') sys.stdout = sockfile MyChannelNumber = getMyChannel() writeXML('') writeXML('') writeXML('') getEpg(MyChannelNumber) writeXML('')