Skip to content

Commit

Permalink
Fixed HEAD requests handling.
Browse files Browse the repository at this point in the history
Added .pyc and IDE files to .gitignore.
  • Loading branch information
AndreyPavlenko committed Feb 29, 2016
1 parent dd2f94d commit fc53911
Show file tree
Hide file tree
Showing 10 changed files with 111 additions and 50 deletions.
5 changes: 5 additions & 0 deletions .gitignore
@@ -0,0 +1,5 @@
*.pyc
.project
.pydevproject
.settings/
.idea/
10 changes: 5 additions & 5 deletions aceconfig.py
Expand Up @@ -127,29 +127,29 @@ class AceConfig(acedefconfig.AceDefConfig):
# !!!
# PLEASE set this to 0 if you use VLC
# !!!
videodelay = 2
videodelay = 0
# Obey PAUSE and RESUME commands from Engine
# (stops sending data to client, should prevent annoying buffering)
# !!!
# PLEASE set this to False if you use VLC
# !!!
videoobey = True
videoobey = False
# Stream send delay after PAUSE/RESUME commands (works only if option
# above is enabled)
# !!!
# PLEASE set this to 0 if you use VLC
# !!!
videopausedelay = 2
videopausedelay = 0
# Seek back feature.
# Seeks stream back for specified amount of seconds.
# Greatly helps fighing AceSteam lags, but introduces
# video stream delay.
# Set it to 30 or so.
# Works only with the newest versions of AceEngine!
videoseekback = 0
videoseekback = 30
# Delay before closing Ace Stream connection when client disconnects
# In seconds.
videodestroydelay = 3
videodestroydelay = 0
# Pre-buffering timeout. In seconds.
videotimeout = 40
#
Expand Down
12 changes: 7 additions & 5 deletions acehttp.py
Expand Up @@ -153,7 +153,7 @@ def do_GET(self, headers_only=False):
'''
GET request handler
'''
logger = logging.getLogger('http_HTTPHandler')
logger = logging.getLogger('do_GET')
self.clientconnected = True
# Don't wait videodestroydelay if error happened
self.errorhappened = True
Expand Down Expand Up @@ -193,7 +193,7 @@ def do_GET(self, headers_only=False):
# Handle request with plugin handler
if self.reqtype in AceStuff.pluginshandlers:
try:
AceStuff.pluginshandlers.get(self.reqtype).handle(self)
AceStuff.pluginshandlers.get(self.reqtype).handle(self, headers_only)
except Exception as e:
logger.error('Plugin exception: ' + repr(e))
logger.error(traceback.format_exc())
Expand All @@ -204,6 +204,8 @@ def do_GET(self, headers_only=False):
self.handleRequest(headers_only)

def handleRequest(self, headers_only):
logger = logging.getLogger('handleRequest')

# Check if third parameter exists
# …/pid/blablablablabla/video.mpg
# |_________|
Expand Down Expand Up @@ -406,9 +408,9 @@ def handleRequest(self, headers_only):
AceStuff.clientcounter.delete(self.path_unquoted, self.clientip)
if not self.errorhappened and not AceStuff.clientcounter.get(self.path_unquoted):
# If no error happened and we are the only client
logger.debug("Sleeping for " + str(
AceConfig.videodestroydelay) + " seconds")
gevent.sleep(AceConfig.videodestroydelay)
if AceConfig.videodestroydelay:
logger.debug("Sleeping for " + str(AceConfig.videodestroydelay) + " seconds")
gevent.sleep(AceConfig.videodestroydelay)
if not AceStuff.clientcounter.get(self.path_unquoted):
logger.debug("That was the last client, destroying AceClient")
if AceConfig.vlcuse:
Expand Down
5 changes: 4 additions & 1 deletion plugins/allfon_plugin.py
Expand Up @@ -37,7 +37,7 @@ def downloadPlaylist(self):

return True

def handle(self, connection):
def handle(self, connection, headers_only=False):
# 30 minutes cache
if not Allfon.playlist or (int(time.time()) - Allfon.playlisttime > 30 * 60):
if not self.downloadPlaylist():
Expand All @@ -49,6 +49,9 @@ def handle(self, connection):
connection.send_response(200)
connection.send_header('Content-Type', 'application/x-mpegurl')
connection.end_headers()

if headers_only:
return;

# Match playlist with regexp

Expand Down
6 changes: 5 additions & 1 deletion plugins/helloworld_plugin_.py
Expand Up @@ -13,8 +13,12 @@ class Helloworld(AceProxyPlugin):
def __init__(self, AceConfig, AceStuff):
pass

def handle(self, connection):
def handle(self, connection, headers_only=False):
connection.send_response(200)
connection.end_headers()

if headers_only:
return

connection.wfile.write(
'<html><body><h3>Hello world!</h3></body></html>')
2 changes: 1 addition & 1 deletion plugins/modules/PluginInterface.py
Expand Up @@ -15,5 +15,5 @@ class AceProxyPlugin(object):
def __init__(self, AceConfig, AceStuff):
pass

def handle(self, connection):
def handle(self, connection, headers_only=False):
raise NotImplementedError
105 changes: 71 additions & 34 deletions plugins/p2pproxy_plugin.py
Expand Up @@ -38,7 +38,7 @@ def __init__(self, AceConfig, AceStuff):
super(P2pproxy, self).__init__(AceConfig, AceStuff)
self.params = None

def handle(self, connection):
def handle(self, connection, headers_only=False):
P2pproxy.logger.debug('Handling request')

hostport = connection.headers['Host']
Expand All @@ -65,6 +65,12 @@ def handle(self, connection):
else:
connection.dieWithError() # Bad request
return

if headers_only:
connection.send_response(200)
connection.send_header("Content-Type", "video/mpeg")
connection.end_headers()
return

stream_url = None

Expand All @@ -82,11 +88,13 @@ def handle(self, connection):
connection.path = stream_url
connection.splittedpath = stream_url.split('/')
connection.reqtype = connection.splittedpath[1].lower()
connection.handleRequest(False)
connection.handleRequest(headers_only)
elif self.get_param('type') == 'm3u': # /channels/?filter=[filter]&group=[group]&type=m3u
connection.send_response(200)
connection.send_header('Content-Type', 'application/x-mpegurl')
connection.end_headers()
if headers_only:
connection.send_response(200)
connection.send_header('Content-Type', 'application/x-mpegurl')
connection.end_headers()
return

param_group = self.get_param('group')
param_filter = self.get_param('filter')
Expand Down Expand Up @@ -119,8 +127,19 @@ def handle(self, connection):
header = '#EXTM3U url-tvg="%s" tvg-shift=%d\n' %(config.tvgurl, config.tvgshift)
exported = playlistgen.exportm3u(hostport=hostport, header=header)
exported = exported.encode('utf-8')
connection.send_response(200)
connection.send_header('Content-Type', 'application/x-mpegurl')
connection.end_headers()
connection.wfile.write(exported)
else: # /channels/?filter=[filter]
if headers_only:
connection.send_response(200)
connection.send_header('Access-Control-Allow-Origin', '*')
connection.send_header('Connection', 'close')
connection.send_header('Content-Type', 'text/xml;charset=utf-8')
connection.end_headers()
return

param_filter = self.get_param('filter')
if not param_filter:
param_filter = 'all' # default filter
Expand All @@ -129,49 +148,57 @@ def handle(self, connection):
translations_list = TorrentTvApi.translations(session, param_filter, True)

P2pproxy.logger.debug('Exporting')

connection.send_response(200)
connection.send_header('Access-Control-Allow-Origin', '*')
connection.send_header('Connection', 'close')
connection.send_header('Content-Length', str(len(translations_list)))
connection.send_header('Content-Type', 'text/xml;charset=utf-8')
connection.send_header('Content-Length', str(len(translations_list)))
connection.end_headers()
connection.wfile.write(translations_list)
elif connection.reqtype == 'xbmc.pvr': # same as /channels request
if len(connection.splittedpath) == 3 and connection.splittedpath[2] == 'playlist':
session = TorrentTvApi.auth(config.email, config.password)
translations_list = TorrentTvApi.translations(session, 'all', True)

P2pproxy.logger.debug('Exporting')

connection.send_response(200)
connection.send_header('Access-Control-Allow-Origin', '*')
connection.send_header('Connection', 'close')
connection.send_header('Content-Length', str(len(translations_list)))
connection.send_header('Content-Type', 'text/xml;charset=utf-8')
connection.end_headers()

if not headers_only:
return

session = TorrentTvApi.auth(config.email, config.password)
translations_list = TorrentTvApi.translations(session, 'all', True)
P2pproxy.logger.debug('Exporting')
connection.wfile.write(translations_list)
elif connection.reqtype == 'archive': # /archive/ branch
if len(connection.splittedpath) == 3 and connection.splittedpath[2] == 'channels': # /archive/channels

session = TorrentTvApi.auth(config.email, config.password)
archive_channels = TorrentTvApi.archive_channels(session, True)

P2pproxy.logger.debug('Exporting')

connection.send_response(200)
connection.send_header('Access-Control-Allow-Origin', '*')
connection.send_header('Connection', 'close')
connection.send_header('Content-Length', str(len(archive_channels)))
connection.send_header('Content-Type', 'text/xml;charset=utf-8')
connection.end_headers()
connection.wfile.write(archive_channels)

if headers_only:
connection.end_headers()
else:
session = TorrentTvApi.auth(config.email, config.password)
archive_channels = TorrentTvApi.archive_channels(session, True)
P2pproxy.logger.debug('Exporting')
connection.send_header('Content-Length', str(len(archive_channels)))
connection.end_headers()
connection.wfile.write(archive_channels)
if len(connection.splittedpath) == 3 and connection.splittedpath[2].split('?')[
0] == 'play': # /archive/play?id=[record_id]
record_id = self.get_param('id')
if not record_id:
connection.dieWithError() # Bad request
return

if headers_only:
connection.send_response(200)
connection.send_header("Content-Type", "video/mpeg")
connection.end_headers()
return

stream_url = None

Expand All @@ -189,12 +216,8 @@ def handle(self, connection):
connection.path = stream_url
connection.splittedpath = stream_url.split('/')
connection.reqtype = connection.splittedpath[1].lower()
connection.handleRequest(False)
connection.handleRequest(headers_only)
elif self.get_param('type') == 'm3u': # /archive/?type=m3u&date=[param_date]&channel_id=[param_channel]
connection.send_response(200)
connection.send_header('Content-Type', 'application/x-mpegurl')
connection.end_headers()

param_date = self.get_param('date')
if not param_date:
d = date.today() # consider default date as today if not given
Expand All @@ -206,18 +229,25 @@ def handle(self, connection):
P2pproxy.logger.error('date param is not correct!')
connection.dieWithError()
return

param_channel = self.get_param('channel_id')
if param_channel == '' or not param_channel:
P2pproxy.logger.error('Got /archive/ request but no channel_id specified!')
connection.dieWithError()
return

if headers_only:
connection.send_response(200)
connection.send_header('Content-Type', 'application/x-mpegurl')
connection.end_headers()
return

session = TorrentTvApi.auth(config.email, config.password)
records_list = TorrentTvApi.records(session, param_channel, d.strftime('%d-%m-%Y'))
channels_list = TorrentTvApi.archive_channels(session)

playlistgen = PlaylistGenerator()
P2pproxy.logger.debug('Generating archive m3u playlist')

for record in records_list:
record_id = record.getAttribute('record_id')
name = record.getAttribute('name')
Expand All @@ -239,6 +269,10 @@ def handle(self, connection):
P2pproxy.logger.debug('Exporting')
exported = playlistgen.exportm3u(hostport, empty_header=True, archive=True)
exported = exported.encode('utf-8')

connection.send_response(200)
connection.send_header('Content-Type', 'application/x-mpegurl')
connection.end_headers()
connection.wfile.write(exported)
else: # /archive/?date=[param_date]&channel_id=[param_channel]
param_date = self.get_param('date')
Expand All @@ -258,18 +292,21 @@ def handle(self, connection):
connection.dieWithError()
return

session = TorrentTvApi.auth(config.email, config.password)
records_list = TorrentTvApi.records(session, param_channel, d.strftime('%d-%m-%Y'), True)

P2pproxy.logger.debug('Exporting')

connection.send_response(200)
connection.send_header('Access-Control-Allow-Origin', '*')
connection.send_header('Connection', 'close')
connection.send_header('Content-Length', str(len(records_list)))
connection.send_header('Content-Type', 'text/xml;charset=utf-8')
connection.end_headers()
connection.wfile.write(records_list)

if headers_only:
connection.end_headers()
else:
session = TorrentTvApi.auth(config.email, config.password)
records_list = TorrentTvApi.records(session, param_channel, d.strftime('%d-%m-%Y'), True)
P2pproxy.logger.debug('Exporting')
connection.send_header('Content-Length', str(len(records_list)))
connection.end_headers()
connection.wfile.write(records_list)

def get_param(self, key):
if key in self.params:
Expand Down
6 changes: 5 additions & 1 deletion plugins/stat_plugin.py
Expand Up @@ -13,10 +13,14 @@ def __init__(self, AceConfig, AceStuff):
self.config = AceConfig
self.stuff = AceStuff

def handle(self, connection):
def handle(self, connection, headers_only=False):
connection.send_response(200)
connection.send_header('Content-type', 'text/html')
connection.end_headers()

if headers_only:
return

connection.wfile.write(
'<html><body><h4>Connected clients: ' + str(self.stuff.clientcounter.total) + '</h4>')
connection.wfile.write(
Expand Down
5 changes: 4 additions & 1 deletion plugins/torrenttelik_plugin.py
Expand Up @@ -34,13 +34,16 @@ def downloadPlaylist(self, url):

return True

def handle(self, connection):
def handle(self, connection, headers_only=False):

hostport = connection.headers['Host']

connection.send_response(200)
connection.send_header('Content-Type', 'application/x-mpegurl')
connection.end_headers()

if headers_only:
return

query = urlparse.urlparse(connection.path).query
self.params = urlparse.parse_qs(query)
Expand Down
5 changes: 4 additions & 1 deletion plugins/torrenttv_plugin.py
Expand Up @@ -44,7 +44,7 @@ def downloadPlaylist(self):

return True

def handle(self, connection):
def handle(self, connection, headers_only=False):
# 30 minutes cache
if not Torrenttv.playlist or (int(time.time()) - Torrenttv.playlisttime > 30 * 60):
if not self.downloadPlaylist():
Expand All @@ -57,6 +57,9 @@ def handle(self, connection):
connection.send_header('Content-Type', 'application/x-mpegurl')
connection.end_headers()

if headers_only:
return

# Match playlist with regexp
matches = re.finditer(r',(?P<name>\S.+) \((?P<group>.+)\)\n(?P<url>^.+$)',
Torrenttv.playlist, re.MULTILINE)
Expand Down

0 comments on commit fc53911

Please sign in to comment.