From b23938dd490983b0c8768af945576ac6037ce85b Mon Sep 17 00:00:00 2001 From: Roman Bazalevsky Date: Mon, 2 Nov 2015 14:14:52 +0300 Subject: [PATCH] =?utf8?q?=D0=92=20=D0=BF=D0=B0=D1=80=D1=81=D0=B5=D1=80=20?= =?utf8?q?M3U=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0=20?= =?utf8?q?=D0=BF=D0=BE=D0=B4=D0=B4=D0=B5=D1=80=D0=B6=D0=BA=D0=B0=20=D0=B4?= =?utf8?q?=D0=BE=D0=BF=D0=BE=D0=BB=D0=BD=D0=B8=D1=82=D0=B5=D0=BB=D1=8C?= =?utf8?q?=D0=BD=D1=8B=D1=85=20=D1=82=D0=B5=D0=B3=D0=BE=D0=B2=20(=D0=B3?= =?utf8?q?=D1=80=D1=83=D0=BF=D0=BF=D1=8B,=20=D1=81=D1=82=D1=80=D0=B0=D0=BD?= =?utf8?q?=D1=8B=20=D0=B8=20=D1=82.=D0=B4.)?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- plugins/m3u_plugin.py | 22 +++- plugins/m3u_plugin.py~ | 171 --------------------------- plugins/modules/M3uParser.py | 20 +++- plugins/modules/PlaylistGenerator.py | 26 +++- vlcclient/vlcmessages.py | 2 +- xmlparse.py | 60 ++++++++++ 6 files changed, 122 insertions(+), 179 deletions(-) delete mode 100644 plugins/m3u_plugin.py~ create mode 100644 xmlparse.py diff --git a/plugins/m3u_plugin.py b/plugins/m3u_plugin.py index 636ad4e..1bb6483 100644 --- a/plugins/m3u_plugin.py +++ b/plugins/m3u_plugin.py @@ -68,9 +68,12 @@ class M3u(VPProxyPlugin): if self.splitted_path[1]=='index': + text="" for dir in os.walk(config.m3u_directory): if dir[0]==config.m3u_directory: - text='\n'.join(dir[2]) + for dirname in dir[2]: + if dirname.endswith('.m3u'): + text=text+'\n'+dirname connection.send_response(200) connection.send_header('Content-Type', 'text/plain; charset=utf-8') @@ -158,6 +161,23 @@ class M3u(VPProxyPlugin): channel=dict() channel['name']=record.title.decode('utf-8') channel['url']=record.path.decode('utf-8') + try: + channel['tvg']=record.attrs['tvg-name'].decode('utf-8') + except: + None + try: + if record.attrs['group-title'] != 'None': + channel['group']=record.attrs['group-title'].decode('utf-8') + except: + None + try: + channel['country']=record.attrs['country'].decode('utf-8') + except: + None + try: + channel['logo']=record.attrs['tvg-logo'].decode('utf-8') + except: + None playlistgen.addItem(channel) exported = playlistgen.exportm3u(hostport,prefix) diff --git a/plugins/m3u_plugin.py~ b/plugins/m3u_plugin.py~ deleted file mode 100644 index 3d2de5c..0000000 --- a/plugins/m3u_plugin.py~ +++ /dev/null @@ -1,171 +0,0 @@ -__author__ = 'rvb' -''' -Local Playlist Plugin -(based on ytv plugin by ValdikSS) - -plsylist index - -http://ip:port/index - -m3u playlists - -http://ip:port/m3u -http://ip:port/m3u/ -http://ip:port/m3u/list-name - -plain-tet channel names - -http://ip:port/list -http://ip:port/list/ -http://ip:port/list/list-name - -forward to player - -http://ip:port/play/channel-name -http://ip:port/play/list-name/channel-name -http://ip:port/play/{list-name}/(get|mp4|webm)/channel-name - -''' -import json -import logging -import urlparse -import urllib -from modules.PluginInterface import VPProxyPlugin -from modules.PlaylistGenerator import PlaylistGenerator -from modules.M3uParser import parseM3U -import config.m3u as config -import os - -class M3u(VPProxyPlugin): - - handlers = ('m3u', 'm3ut', 'm3uw', "list", "play", "index") - - logger = logging.getLogger('plugin_m3u') - playlist = None - - def handle(self, connection): - - hostport = connection.headers['Host'] - - self.splitted_path=connection.path.split('/') - - if self.splitted_path[1]=='m3u': - prefix='get' - elif self.splitted_path[1]=='m3uw': - prefix='ogg' - elif self.splitted_path[1]=='m3ut': - prefix='mp4' - elif self.splitted_path[1] in ("list","play","index"): - None - else: - connection.dieWithError(404) - - if len(self.splitted_path)>3 and self.splitted_path[1]!="play": - connection.dieWithError() - return - - if self.splitted_path[1]=='index': - - for dir in os.walk(config.m3u_directory): - if dir[0]==config.m3u_directory: - text='\n'.join(dir[2]) - - connection.send_response(200) - connection.send_header('Content-Type', 'text/plain; charset=utf-8') - connection.end_headers() - - listing = text.encode('utf-8') - connection.wfile.write(listing) - - return - - if len(self.splitted_path)<3 or (len(self.splitted_path)==3 and self.splitted_path[1]=="play"): - - m3u_file=config.m3u_directory+'/'+config.m3u_default - - else: - - filename = self.splitted_path[2] - if filename: - m3u_file=config.m3u_directory+'/'+self.splitted_path[2] - else: - m3u_file=config.m3u_directory+'/'+config.m3u_default - - try: - playlist=parseM3U(m3u_file) - except: - connection.dieWithError(404) - return - - if self.splitted_path[1]=="list": - connection.send_response(200) - connection.send_header('Content-Type', 'text/plain; charset=utf-8') - connection.end_headers() - elif self.splitted_path[1]=="play": - channel=self.splitted_path[len(self.splitted_path)-1] - channel=urllib.unquote(channel).decode('utf-8') - if len(self.splitted_path)<=4: - prefix="get" - elif len(self.splitted_path)==5: - prefix=self.splitted_path[len(self.splitted_path)-2] - if prefix not in ('get','mp4','webm'): - connection.dieWithError() - else: - connection.dieWithError() - url=None - for record in playlist: - if record.title.decode('utf-8').replace('/','')==channel: - url=record.path.decode('utf-8') - if url: - redirect='/'+prefix+'/'+url - connection.send_response(302) - connection.send_header('Location', redirect) - connection.end_headers() - else: - connection.dieWithError(404) - - else: - connection.send_response(200) - connection.send_header('Content-Type', 'application/x-mpegurl') - connection.end_headers() - - try: - playlist=parseM3U(m3u_file) - except: - connection.dieWithError(404) - return - - if not playlist: - connection.dieWithError() - return - - if self.splitted_path[1]=="list": - - exported = "" - - for record in playlist: - if record.title: - exported = exported + "" + record.title.decode('utf-8').replace('/','') + "\n" - - else: - - playlistgen = PlaylistGenerator() - - for record in playlist: - print record - channel=dict() - channel['name']=record.title.decode('utf-8') - channel['url']=record.path.decode('utf-8') - playlistgen.addItem(channel) - - exported = playlistgen.exportm3u(hostport,prefix) - - exported = exported.encode('utf-8') - - connection.wfile.write(exported) - - def getparam(self, key): - if key in self.params: - return self.params[key][0] - else: - return None diff --git a/plugins/modules/M3uParser.py b/plugins/modules/M3uParser.py index 9e2fce6..e946ec2 100644 --- a/plugins/modules/M3uParser.py +++ b/plugins/modules/M3uParser.py @@ -6,10 +6,11 @@ import hexdump import codecs class track(): - def __init__(self, length, title, path): + def __init__(self, length, title, path, attrs=None): self.length = length self.title = title self.path = path + self.attrs = attrs # # # song info lines are formatted like: @@ -41,9 +42,22 @@ def parseM3U(infile): line = line.strip() if line.startswith('#EXTINF:'): # pull length and title from #EXTINF line - length,title=line.split('#EXTINF:')[1].split(',',1) + prefix,title=line.split('#EXTINF:')[1].split(',',1) + title=title.strip() + length,attrstr=prefix.split(' ',1) + attrs={} + + while attrstr: + + attrstr=attrstr.strip() + key,tail=attrstr.split('=',1) + tail=tail[1:] + value,attrstr=tail.split('"',1) + attrstr=attrstr.strip() + attrs[key]=value + title=title.decode('string_escape') - song=track(length,title,None) + song=track(length,title,None,attrs) elif (len(line) != 0): # pull song path from all other, non-blank lines song.path=line diff --git a/plugins/modules/PlaylistGenerator.py b/plugins/modules/PlaylistGenerator.py index c46197f..4e7654c 100644 --- a/plugins/modules/PlaylistGenerator.py +++ b/plugins/modules/PlaylistGenerator.py @@ -12,7 +12,7 @@ class PlaylistGenerator(object): '#EXTM3U url-tvg="http://www.teleguide.info/download/new3/jtv.zip"\n' m3uemptyheader = '#EXTM3U\n' m3uchanneltemplate = \ - '#EXTINF:-1 group-title="%s" tvg-name="%s" tvg-logo="%s",%s\n%s\n' + '#EXTINF:-1 group-title="%s" tvg-name="%s" tvg-logo="%s" country="%s",%s\n%s\n' def __init__(self): self.itemlist = list() @@ -24,6 +24,7 @@ class PlaylistGenerator(object): name - item name url - item URL tvg - item JTV name (optional) + country - country of origin (optional) group - item playlist group (optional) logo - item logo file name (optional) ''' @@ -34,9 +35,14 @@ class PlaylistGenerator(object): ''' Generates EXTINF line with url ''' + print(item) return PlaylistGenerator.m3uchanneltemplate % ( - item.get('group', ''), item.get('tvg', ''), item.get('logo', ''), - item.get('name'), item.get('url')) + item.get('group', ''), + item.get('tvg', ''), + item.get('logo', ''), + item.get('country', ''), + item.get('name'), + item.get('url')) def exportm3u(self, hostport, prefix="get", add_ts=False, empty_header=False, archive=False): ''' @@ -58,3 +64,17 @@ class PlaylistGenerator(object): itemlist += PlaylistGenerator._generatem3uline(item) return itemlist + + def dumpm3u(self): + ''' + Dump m3u playlist + ''' + itemlist = PlaylistGenerator.m3uemptyheader + + for item in self.itemlist: + item['tvg'] = item.get('tvg', '') if item.get('tvg') else \ + item.get('name').replace(' ', '_') + # For .acelive and .torrent + itemlist += PlaylistGenerator._generatem3uline(item) + + return itemlist diff --git a/vlcclient/vlcmessages.py b/vlcclient/vlcmessages.py index 48e9321..2139e3f 100644 --- a/vlcclient/vlcmessages.py +++ b/vlcclient/vlcmessages.py @@ -17,7 +17,7 @@ class VlcMessage(object): command = command + 'transcode{vcodec=theora,acodec=vorbis,vb=800,ab=128}:' muxer='ogg' elif qtype=='ogv': - command = command + 'transcode{vcodec=theora,acodec=vorbis}:' + command = command + 'transcode{vcodec=theora,acodec=vorbis,vb=8192,ab=256}:' muxer='ogg' # elif qtype=='webm': # command = command + 'transcode{vcodec=VP80,acodec=vorbis,vb=512,ab=64}:' diff --git a/xmlparse.py b/xmlparse.py new file mode 100644 index 0000000..bc4c3cf --- /dev/null +++ b/xmlparse.py @@ -0,0 +1,60 @@ +#!/usr/bin/python + +import xml.dom.minidom +import sys,os +from pprint import pprint +from plugins.modules.PlaylistGenerator import PlaylistGenerator + +tvguide_url="http://www.teleguide.info/download/new3/jtv.zip" + +def parseXML(filename): + datasource = open(filename) + return xml.dom.minidom.parse(datasource) # parse an open file + +def getText(element): + rc = [] + nodelist = element.childNodes + for node in nodelist: + if node.nodeType == node.TEXT_NODE: + rc.append(node.data) + return ''.join(rc) + +def main(argv): + if len(argv) < 2: + sys.stderr.write("Usage: %s \n" % (argv[0],)) + return 1 + + if not os.path.exists(argv[1]): + sys.stderr.write("ERROR: Channel file %r was not found!\n" % (argv[1],)) + return 1 + + dom = parseXML(argv[1]) + tracklist = dom.getElementsByTagName('playlist')[0].getElementsByTagName('trackList')[0].getElementsByTagName('track') + + channels = PlaylistGenerator() + + for track in tracklist: + + channel = {} + + channel['name'] = getText(track.getElementsByTagName('title')[0]) + channel['url'] = getText(track.getElementsByTagName('location')[0]) + try: + channel['logo'] = getText(track.getElementsByTagName('image')[0]) + except: + None + try: + channel['country'] = getText(track.getElementsByTagName('country')[0]) + except: + None + try: + channel['group'] = getText(track.getElementsByTagName('category')[0]) + except: + None + + channels.addItem(channel) + + print channels.dumpm3u().encode('utf8') + +if __name__ == "__main__": + sys.exit(main(sys.argv)) \ No newline at end of file -- 2.34.1