В парсер M3U добавлена поддержка дополнительных тегов (группы, страны и т.д.)
[vpproxy.git] / plugins / m3u_plugin.py
1 __author__ = 'rvb'
2 '''
3 Local Playlist Plugin
4 (based on ytv plugin by ValdikSS)
5
6 plsylist index
7
8 http://ip:port/index
9
10 m3u playlists
11
12 http://ip:port/m3u
13 http://ip:port/m3u/
14 http://ip:port/m3u/list-name
15
16 plain-tet channel names
17
18 http://ip:port/list
19 http://ip:port/list/
20 http://ip:port/list/list-name
21
22 forward to player
23
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
27
28 '''
29 import json
30 import logging
31 import urlparse
32 import urllib
33 from modules.PluginInterface import VPProxyPlugin
34 from modules.PlaylistGenerator import PlaylistGenerator
35 from modules.M3uParser import parseM3U
36 import config.m3u as config
37 import os
38
39 class M3u(VPProxyPlugin):
40
41     handlers = ('m3u', 'm3ut', 'm3uw', 'm3uo', 'list', 'play', 'index')
42
43     logger = logging.getLogger('plugin_m3u')
44     playlist = None
45
46     def handle(self, connection):
47
48         hostport = connection.headers['Host']
49
50         self.splitted_path=connection.path.split('/')
51
52         if self.splitted_path[1]=='m3u':
53           prefix='get'
54         elif self.splitted_path[1]=='m3uw':
55           prefix='ogg'  
56         elif self.splitted_path[1]=='m3ut':
57           prefix='mp4'  
58         elif self.splitted_path[1]=='m3uo':
59           prefix='ogv'  
60         elif self.splitted_path[1] in ("list","play","index"):
61           None  
62         else:
63           connection.dieWithError(404)  
64           
65         if len(self.splitted_path)>3 and self.splitted_path[1]!="play":
66             connection.dieWithError()
67             return
68
69         if self.splitted_path[1]=='index':
70
71             text=""
72             for dir in os.walk(config.m3u_directory):
73                 if dir[0]==config.m3u_directory:
74                     for dirname in dir[2]:
75                         if dirname.endswith('.m3u'):
76                             text=text+'\n'+dirname
77
78             connection.send_response(200)
79             connection.send_header('Content-Type', 'text/plain; charset=utf-8')
80             connection.end_headers()
81
82             listing = text.encode('utf-8')
83             connection.wfile.write(listing) 
84                 
85             return
86             
87         if len(self.splitted_path)<3 or (len(self.splitted_path)==3 and self.splitted_path[1]=="play"):
88
89            m3u_file=config.m3u_directory+'/'+config.m3u_default
90
91         else:
92         
93            filename = self.splitted_path[2]
94            if filename:
95              m3u_file=config.m3u_directory+'/'+self.splitted_path[2]
96            else:
97              m3u_file=config.m3u_directory+'/'+config.m3u_default
98
99         try:
100             playlist=parseM3U(m3u_file)
101         except:
102             connection.dieWithError(404)
103             return    
104
105         if self.splitted_path[1]=="list":
106             connection.send_response(200)
107             connection.send_header('Content-Type', 'text/plain; charset=utf-8')
108             connection.end_headers()
109         elif self.splitted_path[1]=="play":
110             channel=self.splitted_path[len(self.splitted_path)-1]
111             channel=urllib.unquote(channel).decode('utf-8')
112             if len(self.splitted_path)<=4:
113               prefix="get"
114             elif len(self.splitted_path)==5:  
115               prefix=self.splitted_path[len(self.splitted_path)-2]
116               if prefix not in ('get','mp4','webm'):
117                 connection.dieWithError()
118             else:
119               connection.dieWithError()  
120             url=None
121             for record in playlist:
122                 if record.title.decode('utf-8').replace('/','')==channel:
123                     url=record.path.decode('utf-8')
124             if url:
125                 redirect='/'+prefix+'/'+url
126                 connection.send_response(302)
127                 connection.send_header('Location', redirect)
128                 connection.end_headers()
129             else:
130                 connection.dieWithError(404)
131             
132         else:
133             connection.send_response(200)
134             connection.send_header('Content-Type', 'application/x-mpegurl')
135             connection.end_headers()
136
137         try:
138             playlist=parseM3U(m3u_file)
139         except:
140             connection.dieWithError(404)
141             return    
142
143         if not playlist:
144             connection.dieWithError()
145             return
146
147         if self.splitted_path[1]=="list":
148  
149              exported = ""
150             
151              for record in playlist:
152                  if record.title:
153                      exported = exported + "" + record.title.decode('utf-8').replace('/','') + "\n"
154         
155         else:    
156
157             playlistgen = PlaylistGenerator()
158
159             for record in playlist:
160                 if record.title:
161                     channel=dict()
162                     channel['name']=record.title.decode('utf-8')
163                     channel['url']=record.path.decode('utf-8')            
164                     try:
165                       channel['tvg']=record.attrs['tvg-name'].decode('utf-8')
166                     except:
167                       None
168                     try: 
169                       if record.attrs['group-title'] != 'None':   
170                         channel['group']=record.attrs['group-title'].decode('utf-8')
171                     except:
172                       None
173                     try:    
174                       channel['country']=record.attrs['country'].decode('utf-8')
175                     except:
176                       None
177                     try:    
178                       channel['logo']=record.attrs['tvg-logo'].decode('utf-8')
179                     except:
180                       None
181                     playlistgen.addItem(channel)
182
183             exported = playlistgen.exportm3u(hostport,prefix)
184
185         exported = exported.encode('utf-8')
186         
187         connection.wfile.write(exported)
188
189     def getparam(self, key):
190         if key in self.params:
191             return self.params[key][0]
192         else:
193             return None