4 (based on ytv plugin by ValdikSS)
14 http://ip:port/m3u/list-name
16 plain-tet channel names
20 http://ip:port/list/list-name
24 http://ip:port/play/channel-name
25 http://ip:port/play/list-name/channel-name
26 http://ip:port/play/{list-name}/(get|mp4|webm)/channel-name
33 from modules.PluginInterface import VPProxyPlugin
34 from modules.PlaylistGenerator import PlaylistGenerator
35 from modules.M3uParser import parseM3U
36 import config.m3u as config
39 class M3u(VPProxyPlugin):
41 handlers = ('m3u', 'm3ut', 'm3uw', 'm3uo', 'list', 'play', 'index')
43 logger = logging.getLogger('plugin_m3u')
46 def handle(self, connection):
48 logger = logging.getLogger('plugin_m3u')
49 hostport = connection.headers['Host']
51 self.splitted_path=connection.path.split('/')
53 if self.splitted_path[1]=='m3u':
55 elif self.splitted_path[1]=='m3uw':
57 elif self.splitted_path[1]=='m3ut':
59 elif self.splitted_path[1]=='m3uo':
61 elif self.splitted_path[1] in ("list","play","index"):
64 connection.dieWithError(404)
67 if len(self.splitted_path)>3 and self.splitted_path[1]!="play":
68 connection.dieWithError()
71 if self.splitted_path[1]=='index':
74 for dir in os.walk(config.m3u_directory):
75 if dir[0]==config.m3u_directory:
76 for dirname in dir[2]:
77 if dirname.endswith('.m3u'):
78 text=text+'\n'+dirname
80 connection.send_response(200)
81 connection.send_header('Content-Type', 'text/plain; charset=utf-8')
82 connection.end_headers()
84 listing = text.encode('utf-8')
85 connection.wfile.write(listing)
89 if len(self.splitted_path)<3 or (len(self.splitted_path)==3 and self.splitted_path[1]=="play"):
91 m3u_file=config.m3u_directory+'/'+config.m3u_default
95 filename = self.splitted_path[2]
97 m3u_file=config.m3u_directory+'/'+self.splitted_path[2]
99 m3u_file=config.m3u_directory+'/'+config.m3u_default
102 playlist=parseM3U(m3u_file)
104 connection.dieWithError(404)
107 if self.splitted_path[1]=="list":
108 connection.send_response(200)
109 connection.send_header('Content-Type', 'text/plain; charset=utf-8')
110 connection.end_headers()
111 elif self.splitted_path[1]=="play":
112 channel=self.splitted_path[len(self.splitted_path)-1]
113 logger.debug('channel requestes= "%s"' % channel)
115 connection.dieWithError(404)
117 channel=urllib.unquote(channel).decode('utf-8')
118 if len(self.splitted_path)<=4:
120 elif len(self.splitted_path)==5:
121 prefix=self.splitted_path[len(self.splitted_path)-2]
122 if prefix not in ('get','mp4','webm'):
123 connection.dieWithError()
126 connection.dieWithError()
129 for record in playlist:
131 if record.title.decode('utf-8').replace('/','')==channel:
132 url=record.path.decode('utf-8')
134 redirect='/'+prefix+'/'+url
135 connection.send_response(302)
136 connection.send_header('Location', redirect)
137 connection.end_headers()
139 logger.debug('Nothing found!')
140 connection.dieWithError(404)
144 connection.send_response(200)
145 connection.send_header('Content-Type', 'application/x-mpegurl')
146 connection.end_headers()
149 playlist=parseM3U(m3u_file)
151 connection.dieWithError(404)
155 connection.dieWithError()
160 if self.splitted_path[1]=="list":
162 for record in playlist:
164 exported = exported + "" + record.title.decode('utf-8').replace('/','') + "\n"
168 playlistgen = PlaylistGenerator()
170 for record in playlist:
173 channel['name']=record.title.decode('utf-8')
174 channel['url']=record.path.decode('utf-8')
176 channel['tvg']=record.attrs['tvg-name'].decode('utf-8')
180 if record.attrs['group-title'] != 'None':
181 channel['group']=record.attrs['group-title'].decode('utf-8')
185 channel['country']=record.attrs['country'].decode('utf-8')
189 channel['logo']=record.attrs['tvg-logo'].decode('utf-8')
192 playlistgen.addItem(channel)
194 exported = playlistgen.exportm3u(hostport,prefix)
197 exported = exported.encode('utf-8')
198 connection.wfile.write(exported)
200 def getparam(self, key):
201 if key in self.params:
202 return self.params[key][0]