Корректная обработка ошибок при неправильном имени канала.
[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         logger = logging.getLogger('plugin_m3u')
49         hostport = connection.headers['Host']
50
51         self.splitted_path=connection.path.split('/')
52
53         if self.splitted_path[1]=='m3u':
54           prefix='get'
55         elif self.splitted_path[1]=='m3uw':
56           prefix='ogg'  
57         elif self.splitted_path[1]=='m3ut':
58           prefix='mp4'  
59         elif self.splitted_path[1]=='m3uo':
60           prefix='ogv'  
61         elif self.splitted_path[1] in ("list","play","index"):
62           None  
63         else:
64           connection.dieWithError(404)  
65           return
66           
67         if len(self.splitted_path)>3 and self.splitted_path[1]!="play":
68             connection.dieWithError()
69             return
70
71         if self.splitted_path[1]=='index':
72
73             text=""
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
79
80             connection.send_response(200)
81             connection.send_header('Content-Type', 'text/plain; charset=utf-8')
82             connection.end_headers()
83
84             listing = text.encode('utf-8')
85             connection.wfile.write(listing) 
86                 
87             return
88             
89         if len(self.splitted_path)<3 or (len(self.splitted_path)==3 and self.splitted_path[1]=="play"):
90
91            m3u_file=config.m3u_directory+'/'+config.m3u_default
92
93         else:
94         
95            filename = self.splitted_path[2]
96            if filename:
97              m3u_file=config.m3u_directory+'/'+self.splitted_path[2]
98            else:
99              m3u_file=config.m3u_directory+'/'+config.m3u_default
100
101         try:
102             playlist=parseM3U(m3u_file)
103         except:
104             connection.dieWithError(404)
105             return    
106
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)
114             if not channel:
115               connection.dieWithError(404)
116               return
117             channel=urllib.unquote(channel).decode('utf-8')
118             if len(self.splitted_path)<=4:
119               prefix="get"
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()
124                 return
125             else:
126               connection.dieWithError()  
127               return
128             url=None
129             for record in playlist:
130               if record.title:
131                 if record.title.decode('utf-8').replace('/','')==channel:
132                     url=record.path.decode('utf-8')
133             if url:
134                 redirect='/'+prefix+'/'+url
135                 connection.send_response(302)
136                 connection.send_header('Location', redirect)
137                 connection.end_headers()
138             else:
139                 logger.debug('Nothing found!')
140                 connection.dieWithError(404)
141                 return
142             
143         else:
144             connection.send_response(200)
145             connection.send_header('Content-Type', 'application/x-mpegurl')
146             connection.end_headers()
147
148         try:
149             playlist=parseM3U(m3u_file)
150         except:
151             connection.dieWithError(404)
152             return    
153
154         if not playlist:
155             connection.dieWithError()
156             return
157
158         exported = ""
159
160         if self.splitted_path[1]=="list":
161  
162              for record in playlist:
163                  if record.title:
164                      exported = exported + "" + record.title.decode('utf-8').replace('/','') + "\n"
165         
166         else:    
167
168             playlistgen = PlaylistGenerator()
169
170             for record in playlist:
171                 if record.title:
172                     channel=dict()
173                     channel['name']=record.title.decode('utf-8')
174                     channel['url']=record.path.decode('utf-8')            
175                     try:
176                       channel['tvg']=record.attrs['tvg-name'].decode('utf-8')
177                     except:
178                       None
179                     try: 
180                       if record.attrs['group-title'] != 'None':   
181                         channel['group']=record.attrs['group-title'].decode('utf-8')
182                     except:
183                       None
184                     try:    
185                       channel['country']=record.attrs['country'].decode('utf-8')
186                     except:
187                       None
188                     try:    
189                       channel['logo']=record.attrs['tvg-logo'].decode('utf-8')
190                     except:
191                       None
192                     playlistgen.addItem(channel)
193
194             exported = playlistgen.exportm3u(hostport,prefix)
195
196         if exported:
197             exported = exported.encode('utf-8')
198             connection.wfile.write(exported)
199
200     def getparam(self, key):
201         if key in self.params:
202             return self.params[key][0]
203         else:
204             return None