버전 1.0.1

This commit is contained in:
wonipapa 2016-11-09 17:31:12 +09:00
parent 650b66a14d
commit 5cae9c4009
2 changed files with 325 additions and 102 deletions

View File

@ -164,7 +164,7 @@
{"Id":257,"KTCh":255,"SKCh":415,"LGCh":175,"Name":"소상공인방송","Source":"SK","ServiceId":428},
{"Id":258,"KTCh":31,"SKCh":29,"LGCh":null,"Name":"쇼핑엔T","Source":"SK","ServiceId":336},
{"Id":260,"KTCh":28,"SKCh":27,"LGCh":null,"Name":"신세계쇼핑","Source":"SK","ServiceId":339},
{"Id":263,"KTCh":206,"SKCh":417,"LGCh":141,"Name":"아리랑TV","Source":"SKY","ServiceId":50},
{"Id":263,"KTCh":206,"SKCh":417,"LGCh":141,"Name":"아리랑TV","Source":"SKY","ServiceId"50},
{"Id":264,"KTCh":186,"SKCh":352,"LGCh":114,"Name":"아시아경제","Source":"SK","ServiceId":622},
{"Id":265,"KTCh":22,"SKCh":3,"LGCh":20,"Name":"아임쇼핑","Source":"SK","ServiceId":332},
{"Id":266,"KTCh":138,"SKCh":106,"LGCh":149,"Name":"애니플러스","Source":"SK","ServiceId":377},

View File

@ -6,129 +6,352 @@ import sys
import urllib
import json
import datetime
import time
from bs4 import BeautifulSoup
import codecs
import socket
import re
from xml.etree.ElementTree import Element, SubElement, dump
from xml.sax.saxutils import escape
import argparse
default_broadcast='all'
default_xml_filename='xmlepgtv.xml'
default_xml_socket='xmltv.sock'
default_chanfile='channellist.json'
default_fetch_limit=3
reload(sys)
sys.setdefaultencoding('utf-8')
def channelList(ips='ALL'):
global channels
ch_channels=[]
__version__ = '1.0.1'
url = ('http://iptv.neo365.net/api/iptv/epg/channellist/%s' % ( ips ) )
u = urllib.urlopen(url)
data = u.read()
j = json.loads(data)
# 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
channels = j["Channels"]
for channel in channels:
ch_channelName = channel["ChannelName"]
ch_channelNo = channel["ChannelNo"]
hostinfo = userid + ':' + userpw + '@' + host + ':' + port
ch_channels.append('\t<channel id="%s">\n' % ( ch_channelNo))
ch_channels.append('\t\t<display-name>%s</display-name>\n' % ( escape(ch_channelName)) )
ch_channels.append('\t\t<display-name>[%s] %s</display-name>\n' % (ch_channelNo, escape(ch_channelName)) )
# Set date
today = datetime.date.today()
nextday = today + datetime.timedelta(days=1)
for ch_detail in channel["Details"]:
ch_detailNo = ch_detail["ChannelNo"]
ch_detailName = ch_detail["ChannelName"]
ch_channels.append('\t\t<display-name>%s</display-name>\n' % ( escape(ch_detailName)) )
ch_channels.append('\t\t<display-name>[%s] %s</display-name>\n' % (ch_channelNo, escape(ch_detailName)) )
# 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))
ch_channels.append('\t</channel>\n')
# 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<channel id="%s">' % (ChannelId))
writeXML('\t\t<display-name>%s</display-name>' % (ChannelName))
if iconurl:
writeXML('\t\t<icon src="%s/%s.png" />' % (iconurl, ChannelId))
writeXML('\t</channel>')
for channel in channels:
for prog in channelDetail(channel["ChannelNo"]):
ch_channels.append(prog)
return ch_channels
def channelDetail(channelId):
global channel
prog=[]
url = ('http://iptv.neo365.net/api/iptv/epg/channel/%s' % ( channelId ))
u = urllib.urlopen(url)
data = u.read()
j = json.loads(data)
channel = j["Channel"]
for program in channel["Programs"]:
pr_programName = program["ProgramName"]
pr_actorName = program["Actor"]
pr_startTime = ("%s +9000" % ( program["StartTime"]) )
pr_endTime = ("%s +9000" % ( program["EndTime"]) )
pr_mainGenreName = program["Genre"]
pr_ratingCd = program["Rating"]
pr_episode = None
if isinstance(pr_programName, unicode):
pr_programName = escape(pr_programName)
if isinstance(pr_mainGenreName, unicode):
pr_mainGenreName = escape(pr_mainGenreName)
# 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)
if pr_ratingCd > '0':
pr_ratingCd = u'%s세 이상 시청가' %(pr_ratingCd)
else:
pr_ratingCd = u'모든 연령 시청가'
match=re.search('(?<=\()[\d]+', pr_programName)
if match:
pr_episode = match.group()+u''
prog.append('\t<programme start="%s" stop="%s" channel="%s">\n' % ( pr_startTime, pr_endTime ,channelId))
prog.append('\t\t<title lang="kr">%s</title>\n' %(pr_programName))
prog.append('\t\t<category lang="kr">%s</category>\n' %(pr_mainGenreName))
if pr_episode:
prog.append('\t\t<episode-num system="onscreen">%s</episode-num>\n' % pr_episode)
prog.append('\t\t<rating system="VCHIP">\n\t\t\t<value>%s</value>\n\t\t</rating>\n' % pr_ratingCd)
prog.append('\t</programme>\n')
return prog
# 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('&lt;br&gt;~')
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 = """
<tr>
<td class="alignC">00:00</td>
<td></td>
<td class="alignC"></td>
<td class="alignC">
<span class="tvGuideLv tvGuideSd"></span>
</td>
<td class="alignC"></td>
</tr>
"""
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<programme start="%s +0900" stop="%s +0900" channel="%s">' % (startTime, endTime,channelId)
print '\t\t<title lang="kr">%s</title>' % (programName)
print '\t\t<desc lang="kr">%s</desc>' % (desc)
if actors or producer:
print '\t\t<credits>'
if actors: print '\t\t\t<actor>%s</actor>' % (actors)
if producer: print '\t\t\t<producer>%s</producer>' % (producer)
print '\t\t</credits>'
print '\t\t<category lang="kr">%s</category>' %(category)
if episode:
print '\t\t<episode-num system="onscreen">%s</episode-num>' % (episode)
print '\t\t<rating system="KMRB">\n\t\t\t<value>%s</value>\n\t\t</rating>' % (rating)
print '\t</programme>'
# Write XML
def writeXML(data):
if args.socket:
xmlfp.send(data.encode('utf-8'))
else:
xmlfp.write(data)
print data
parser = argparse.ArgumentParser()
parser = argparse.ArgumentParser(description=u'EPG 정보를 출력하는 방법을 결정')
cmds = parser.add_mutually_exclusive_group(required=True)
cmds.add_argument('-w', dest='outputfile', metavar=default_xml_filename, nargs='?', const=default_xml_filename, help=u'저장할 파일이름')
cmds.add_argument('-s', dest='socket', metavar=default_xml_socket, nargs='?', const=default_xml_socket, help=u'xmltv.sock(External: XMLTV)로 EPG정보 전송')
opts = parser.add_argument_group(u'추가옵션')
opts.add_argument('-i', dest='ips', help=u'사용하는 망 : SK, KT, LG, ALL', default='ALL')
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
global xmlfp
MyChannelNumber = getMyChannel()
if args.socket:
xmlfp = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
xmlfp.connect(args.socket)
elif args.outputfile:
xmlfp = codecs.open(args.outputfile, "w+", encoding="utf8")
else:
xmlfp = sys.stdout
writeXML('<?xml version="1.0" encoding="UTF-8"?>')
writeXML('<!DOCTYPE tv SYSTEM "xmltv.dtd">')
writeXML('<tv source-info-url="localhost" source-info-name="xmltv" generator-info-name="xmltv">')
getEpg(MyChannelNumber)
writeXML('</tv>')
channels = []
#channels = channelList(args.limit-1)
channels = channelList(args.ips)
writeXML('<?xml version="1.0" encoding="UTF-8"?>\n<!DOCTYPE tv SYSTEM "xmltv.dtd">\n')
writeXML('<tv source-info-url="iptv.neo365.net" source-info-name="epgi" generator-info-name="epgMaker">\n')
for channel in channels:
writeXML(channel)
writeXML('</tv>\n')