Example #1
0
    def downloadPlaylist(self):
        try:
            self.logger.debug('Trying to download playlist')
            req = urllib2.Request(config.url,
                                  headers={'User-Agent': "Magic Browser"})
            origin = urllib2.urlopen(req, timeout=10).read()
            matches = re.finditer(
                r',(?P<name>\S.+) \((?P<group>.+)\)\n(?P<url>^.+$)', origin,
                re.MULTILINE)
            self.playlisttime = int(time.time())
            self.playlist = PlaylistGenerator()
            self.channels = dict()
            m = md5.new()

            for match in matches:
                itemdict = match.groupdict()
                encname = itemdict.get('name')
                name = encname.decode('UTF-8')
                logo = config.logomap.get(name)
                url = itemdict['url']
                self.playlist.addItem(itemdict)

                if logo:
                    itemdict['logo'] = logo

                if (url.startswith('acestream://')) or (
                        url.startswith('http://')
                        and url.endswith('.acelive')):
                    self.channels[name] = url
                    itemdict['url'] = urllib2.quote(encname, '') + '.mp4'

                m.update(encname)

            self.etag = '"' + m.hexdigest() + '"'
        except:
            self.logger.error("Can't download playlist!")
            self.logger.error(traceback.format_exc())
            return False

        if self.updatelogos:
            try:
                api = TorrentTvApi(p2pconfig.email, p2pconfig.password,
                                   p2pconfig.sessiontimeout)
                translations = api.translations('all')
                logos = dict()

                for channel in translations:
                    name = channel.getAttribute('name').encode('utf-8')
                    logo = channel.getAttribute('logo').encode('utf-8')
                    logos[name] = config.logobase + logo

                self.logomap = logos
                self.logger.debug("Logos updated")
            except:
                # p2pproxy plugin seems not configured
                self.updatelogos = False

        return True
Example #2
0
    def downloadPlaylist(self):
        try:
            self.logger.debug('Trying to download playlist')
            req = urllib2.Request(config.url, headers={'User-Agent' : "Magic Browser"})
            origin = urllib2.urlopen(req, timeout=10).read()
            matches = re.finditer(r',(?P<name>\S.+) \((?P<group>.+)\)\n(?P<url>^.+$)', origin, re.MULTILINE)
            self.playlisttime = int(time.time())
            self.playlist = PlaylistGenerator()
            self.channels = dict()
            m = md5.new()
            
            for match in matches:
                itemdict = match.groupdict()
                encname = itemdict.get('name')
                name = encname.decode('UTF-8')
                logo = config.logomap.get(name)
                url = itemdict['url']
                self.playlist.addItem(itemdict)
                
                if logo:
                    itemdict['logo'] = logo

                if (url.startswith('acestream://')) or (url.startswith('http://') and url.endswith('.acelive')):
                    self.channels[name] = url
                    itemdict['url'] = urllib2.quote(encname, '') + '.mp4'
                    
                m.update(encname)
            
            self.etag = '"' + m.hexdigest() + '"'
        except:
            self.logger.error("Can't download playlist!")
            self.logger.error(traceback.format_exc())
            return False
        
        if self.updatelogos:
            try:
                api = TorrentTvApi(p2pconfig.email, p2pconfig.password, p2pconfig.sessiontimeout)
                translations = api.translations('all')
                logos = dict()

                for channel in translations:
                    name = channel.getAttribute('name').encode('utf-8')
                    logo = channel.getAttribute('logo').encode('utf-8')
                    logos[name] = config.logobase + logo

                self.logomap = logos
                self.logger.debug("Logos updated")
            except:
                # p2pproxy plugin seems not configured
                self.updatelogos = False

        return True
    def downloadPlaylist(self):
        headers = {'User-Agent': 'Magic Browser', 'Accept-Encoding': 'gzip,deflate', 'Connection': 'close'}
        try:
            if config.useproxy:
                  origin = requests.get(config.url, headers=headers, proxies=config.proxies, timeout=30).text
            else: origin = requests.get(config.url, headers=headers, timeout=5).text

            self.logger.info('TTV playlist ' + config.url + ' downloaded')
            self.playlisttime = int(time.time())
            self.playlist = PlaylistGenerator()
            self.channels = dict()
            m = hashlib.md5()
            pattern = re.compile(r',(?P<name>\S.+) \((?P<group>.+)\)[\r\n]+(?P<url>[^\r\n]+)?')

            for match in pattern.finditer(origin.encode('UTF-8'), re.MULTILINE):
                itemdict = match.groupdict()
                encname = itemdict.get('name')
                name = encname.decode('UTF-8')
                logo = self.logomap.get(name)
                url = itemdict['url']
                if logo: itemdict['logo'] = logo

                if url.startswith(('acestream://', 'infohash://')) \
                      or (url.startswith(('http://','https://')) and url.endswith(('.acelive','.acestream','.acemedia'))):
                    self.channels[name] = url
                    itemdict['url'] = requests.utils.quote(encname, '') + '.mp4'
                self.playlist.addItem(itemdict)
                m.update(encname)

            self.etag = '"' + m.hexdigest() + '"'

        except requests.exceptions.ConnectionError:
            self.logger.error("Can't download TTV playlist!")
            return False

        if self.updatelogos:
            try:
                api = TorrentTvApi(p2pconfig.email, p2pconfig.password)
                translations = api.translations('all')
                logos = dict()

                for channel in translations:
                    name = channel.getAttribute('name').encode('utf-8')
                    logo = channel.getAttribute('logo').encode('utf-8')
                    logos[name] = config.logobase + logo

                self.logomap = logos
                self.logger.debug("Logos updated")
                self.updatelogos = False
            except: self.updatelogos = False # p2pproxy plugin seems not configured
        return True
    def downloadPlaylist(self):
        headers = {'User-Agent': 'Magic Browser'}
        try:
            origin = requests.get(config.url, headers=headers, proxies=config.proxies, timeout=30).text.encode('utf-8')

            self.logger.info('TTV playlist %s downloaded' % config.url)
            self.playlisttime = int(time.time())
            self.playlist = PlaylistGenerator(m3uchanneltemplate=config.m3uchanneltemplate)
            self.channels = dict()
            m = hashlib.md5()
            if self.updatelogos:
                try:
                    translations_list = TorrentTvApi(p2pconfig.email, p2pconfig.password).translations('all')
                    for channel in translations_list:
                        name = channel.getAttribute('name').encode('utf-8')
                        logo = channel.getAttribute('logo').encode('utf-8')
                        if channel.getAttribute('epg_id') not in ('0', '', ' '):
                           self.epg_id[name.decode('utf-8')] = 'ttv%s' % channel.getAttribute('id').encode('utf-8')
                        if not name.decode('utf-8') in self.logomap:
                           self.logomap[name.decode('utf-8')] = config.logobase + logo

                    self.logger.debug("Logos updated")
                    self.updatelogos = False
                except: self.updatelogos = False # p2pproxy plugin seems not configured

            self.logger.debug('Generating requested m3u playlist')
            pattern = re.compile(r',(?P<name>\S.+) \((?P<group>.+)\)[\r\n]+(?P<url>[^\r\n]+)?')

            for match in pattern.finditer(origin, re.MULTILINE):
                itemdict = match.groupdict()
                encname = itemdict.get('name')
                name = encname.decode('utf-8')

                logo = self.logomap.get(name)
                itemdict['logo'] = logo if logo else 'http://static.acestream.net/sites/acestream/img/ACE-logo.png'

                tvgid = self.epg_id.get(name)
                if tvgid: itemdict['tvgid'] = tvgid

                url = itemdict['url']
                if url.startswith(('acestream://', 'infohash://')) \
                      or (url.startswith(('http://','https://')) and url.endswith(('.acelive','.acestream','.acemedia'))):
                    self.channels[name] = url
                    itemdict['url'] = requests.compat.quote(encname,'') + '.ts'

                self.playlist.addItem(itemdict)
                m.update(encname)

            self.etag = '"' + m.hexdigest() + '"'

        except requests.exceptions.ConnectionError: self.logger.error("Can't download TTV playlist!"); return False
        except: self.logger.error(traceback.format_exc()); return False

        return True
Example #5
0
 def __init__(self, AceConfig, AceStuff):
     super(P2pproxy, self).__init__(AceConfig, AceStuff)
     self.params = None
     self.api = TorrentTvApi(config.email, config.password)
Example #6
0
class P2pproxy(AceProxyPlugin):
    TTV = 'http://1ttv.org/'
    TTVU = TTV + 'uploads/'
    handlers = ('channels', 'channels.m3u', 'archive', 'xbmc.pvr', 'logos')
    logger = logging.getLogger('plugin_p2pproxy')

    def __init__(self, AceConfig, AceStuff):
        super(P2pproxy, self).__init__(AceConfig, AceStuff)
        self.params = None
        self.api = TorrentTvApi(config.email, config.password)

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

        hostport = connection.headers['Host']
        self.params = parse_qs(connection.query)
        # /channels/ branch
        if connection.reqtype in ('channels', 'channels.m3u'):
            # /channels/play?id=[id]
            if len(
                    connection.splittedpath
            ) == 3 and connection.splittedpath[2].split('?')[0] == 'play':
                channel_id = self.get_param('id')
                if not channel_id:
                    # /channels/play?id=&_=[epoch timestamp] is Torrent-TV widget proxy check
                    # P2pProxy simply closes connection on this request sending Server header, so do we
                    if self.get_param('_'):
                        P2pproxy.logger.debug('Status check')
                        connection.send_response(200)
                        connection.send_header('Access-Control-Allow-Origin',
                                               '*')
                        connection.send_header('Connection', 'close')
                        connection.send_header('Content-Type',
                                               'text/plain;charset=utf-8')
                        connection.send_header('Server',
                                               'P2pProxy/1.0.4.4 AceProxy')
                        connection.wfile.write('\r\n')
                        return
                    else:
                        connection.dieWithError(400,
                                                'Bad request')  # Bad request
                        return

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

                stream_url = None
                stream_type, stream, translations_list = self.api.stream_source(
                    channel_id)
                name = logo = ''

                for channel in translations_list:
                    if channel.getAttribute('id') == channel_id:
                        name = channel.getAttribute('name')
                        logo = channel.getAttribute('logo')
                        if config.fullpathlogo:
                            logo = P2pproxy.TTVU + logo
                        break

                if stream_type == 'torrent':
                    stream_url = re.sub(
                        '^(http.+)$',
                        lambda match: '/url/' + requests.utils.quote(
                            match.group(0), '') + '/stream.mp4', stream)
                elif stream_type == 'contentid':
                    stream_url = re.sub(
                        '^([0-9a-f]{40})',
                        lambda match: '/content_id/' + requests.utils.quote(
                            match.group(0), '') + '/stream.mp4', stream)
                connection.path = stream_url
                connection.splittedpath = stream_url.split('/')
                connection.reqtype = connection.splittedpath[1].lower()
                connection.handleRequest(headers_only,
                                         name,
                                         logo,
                                         fmt=self.get_param('fmt'))
            # /channels/?filter=[filter]&group=[group]&type=m3u
            elif connection.reqtype == 'channels.m3u' or self.get_param(
                    'type') == 'm3u':
                if headers_only:
                    connection.send_response(200)
                    connection.send_header('Content-Type',
                                           'application/x-mpegurl')
                    connection.end_headers()
                    return

                param_group = self.params.get('group')
                param_filter = self.get_param('filter')
                if not param_filter: param_filter = 'all'  # default filter
                if param_group:
                    if 'all' in param_group: param_group = None
                    else:
                        tmp = []
                        for g in param_group:
                            tmp += g.split(',')
                        param_group = tmp

                translations_list = self.api.translations(param_filter)

                playlistgen = PlaylistGenerator()
                P2pproxy.logger.debug('Generating requested m3u playlist')
                for channel in translations_list:
                    group_id = channel.getAttribute('group')
                    if param_group and not group_id in param_group:
                        continue  # filter channels by group

                    name = channel.getAttribute('name')
                    group = TorrentTvApi.CATEGORIES[int(group_id)].decode(
                        'UTF-8')
                    cid = channel.getAttribute('id')
                    logo = channel.getAttribute('logo')
                    if config.fullpathlogo: logo = P2pproxy.TTVU + logo

                    fields = {
                        'name': name,
                        'id': cid,
                        'url': cid,
                        'group': group,
                        'logo': logo
                    }
                    fields['tvgid'] = config.tvgid % fields
                    playlistgen.addItem(fields)

                P2pproxy.logger.debug('Exporting')
                header = '#EXTM3U url-tvg="%s" tvg-shift=%d deinterlace=1 m3uautoload=1 cache=1000\n' % (
                    config.tvgurl, config.tvgshift)
                exported = playlistgen.exportm3u(
                    hostport=hostport,
                    header=header,
                    fmt=self.get_param('fmt')).encode('utf-8')
                connection.send_response(200)
                connection.send_header('Content-Type', 'application/x-mpegurl')
                connection.send_header('Content-Length', str(len(exported)))
                connection.end_headers()
                connection.wfile.write(exported)
            # /channels/?filter=[filter]
            else:
                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

                translations_list = self.api.translations(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-Type',
                                       'text/xml;charset=utf-8')
                connection.send_header('Content-Length',
                                       str(len(translations_list)))
                connection.end_headers()
                connection.wfile.write(translations_list)
        # same as /channels request
        elif connection.reqtype == 'xbmc.pvr':
            if len(connection.splittedpath
                   ) == 3 and connection.splittedpath[2] == 'playlist':
                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')

                if headers_only:
                    connection.end_headers()
                    return

                translations_list = self.api.translations('all', True)
                connection.send_header('Content-Length',
                                       str(len(translations_list)))
                connection.end_headers()
                P2pproxy.logger.debug('Exporting')
                connection.wfile.write(translations_list)
        # /archive/ branch
        elif connection.reqtype == 'archive':
            if len(connection.splittedpath) >= 3 and (
                    connection.splittedpath[2] == 'dates'
                    or connection.splittedpath[2]
                    == 'dates.m3u'):  # /archive/dates.m3u
                d = date.today()
                delta = timedelta(days=1)
                playlistgen = PlaylistGenerator()
                hostport = connection.headers['Host']
                days = int(
                    self.get_param('days')) if 'days' in self.params else 7
                suffix = '&suffix=' + self.get_param(
                    'suffix') if 'suffix' in self.params else ''
                for i in range(days):
                    dfmt = d.strftime('%d-%m-%Y')
                    url = 'http://%s/archive/playlist/?date=%s%s' % (
                        hostport, dfmt, suffix)
                    playlistgen.addItem({
                        'group': '',
                        'tvg': '',
                        'name': dfmt,
                        'url': url
                    })
                    d = d - delta
                exported = playlistgen.exportm3u(
                    hostport,
                    empty_header=True,
                    process_url=False,
                    fmt=self.get_param('fmt')).encode('utf-8')
                connection.send_response(200)
                connection.send_header('Content-Type', 'application/x-mpegurl')
                connection.send_header('Content-Length', str(len(exported)))
                connection.end_headers()
                connection.wfile.write(exported)
                return
            elif len(connection.splittedpath) >= 3 and (
                    connection.splittedpath[2] == 'playlist'
                    or connection.splittedpath[2]
                    == 'playlist.m3u'):  # /archive/playlist.m3u
                dates = list()

                if 'date' in self.params:
                    for d in self.params['date']:
                        dates.append(
                            self.parse_date(d).strftime('%d-%m-%Y').replace(
                                '-0', '-'))
                else:
                    d = date.today()
                    delta = timedelta(days=1)
                    days = int(
                        self.get_param('days')) if 'days' in self.params else 7
                    for i in range(days):
                        dates.append(d.strftime('%d-%m-%Y').replace('-0', '-'))
                        d = d - delta

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

                if headers_only:
                    connection.end_headers()
                    return

                channels_list = self.api.archive_channels()
                hostport = connection.headers['Host']
                playlistgen = PlaylistGenerator()
                suffix = '&suffix=' + self.get_param(
                    'suffix') if 'suffix' in self.params else ''

                for channel in channels_list:
                    epg_id = channel.getAttribute('epg_id')
                    name = channel.getAttribute('name')
                    logo = channel.getAttribute('logo')
                    if logo != '' and config.fullpathlogo:
                        logo = P2pproxy.TTVU + logo
                    for d in dates:
                        n = name + ' (' + d + ')' if len(dates) > 1 else name
                        url = 'http://%s/archive/?type=m3u&date=%s&channel_id=%s%s' % (
                            hostport, d, epg_id, suffix)
                        playlistgen.addItem({
                            'group': name,
                            'tvg': '',
                            'name': n,
                            'url': url,
                            'logo': logo
                        })

                exported = playlistgen.exportm3u(
                    hostport,
                    empty_header=True,
                    process_url=False,
                    fmt=self.get_param('fmt')).encode('utf-8')
                connection.send_header('Content-Length', str(len(exported)))
                connection.end_headers()
                connection.wfile.write(exported)
                return
            # /archive/channels
            elif len(connection.splittedpath
                     ) == 3 and connection.splittedpath[2] == 'channels':
                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')

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

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

                stream_url = None
                stream_type, stream = self.api.archive_stream_source(record_id)

                if stream_type == 'torrent':
                    stream_url = re.sub(
                        '^(http.+)$',
                        lambda match: '/url/' + requests.utils.quote(
                            match.group(0), '') + '/stream.mp4', stream)
                elif stream_type == 'contentid':
                    stream_url = re.sub(
                        '^([0-9a-f]{40})',
                        lambda match: '/content_id/' + requests.utils.quote(
                            match.group(0), '') + '/stream.mp4', stream)
                connection.path = stream_url
                connection.splittedpath = stream_url.split('/')
                connection.reqtype = connection.splittedpath[1].lower()
                connection.handleRequest(headers_only,
                                         fmt=self.get_param('fmt'))
            # /archive/?type=m3u&date=[param_date]&channel_id=[param_channel]
            elif self.get_param('type') == 'm3u':
                d = self.get_date_param()

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

                playlistgen = PlaylistGenerator()
                param_channel = self.get_param('channel_id')
                d = d.strftime('%d-%m-%Y').replace('-0', '-')

                if param_channel == '' or not param_channel:
                    channels_list = self.api.archive_channels()

                    for channel in channels_list:
                        channel_id = channel.getAttribute('epg_id')
                        try:
                            records_list = self.api.records(channel_id, d)
                            channel_name = channel.getAttribute('name')
                            logo = channel.getAttribute('logo')
                            if logo != '' and config.fullpathlogo:
                                logo = P2pproxy.TTVU + logo

                            for record in records_list:
                                name = record.getAttribute('name')
                                record_id = record.getAttribute('record_id')
                                playlistgen.addItem({
                                    'group': channel_name,
                                    'tvg': '',
                                    'name': name,
                                    'url': record_id,
                                    'logo': logo
                                })
                        except:
                            P2pproxy.logger.debug(
                                'Failed to load archive for %s' % channel_id)

                else:
                    records_list = self.api.records(param_channel, d)
                    channels_list = self.api.archive_channels()
                    P2pproxy.logger.debug('Generating archive m3u playlist')

                    for record in records_list:
                        record_id = record.getAttribute('record_id')
                        channel_id = record.getAttribute('epg_id')
                        name = record.getAttribute('name')
                        d = datetime.fromtimestamp(
                            float(
                                record.getAttribute('time'))).strftime('%H:%M')
                        n = '%s %s' % (d, name)
                        logo = ''
                        for channel in channels_list:
                            if channel.getAttribute('epg_id') == channel_id:
                                channel_name = channel.getAttribute('name')
                                logo = channel.getAttribute('logo')

                        if channel_name != '':
                            name = '(' + channel_name + ') ' + name
                        if logo != '' and config.fullpathlogo:
                            logo = P2pproxy.TTVU + logo

                        playlistgen.addItem({
                            'group': channel_name,
                            'name': n,
                            'url': record_id,
                            'logo': logo,
                            'tvg': ''
                        })

                P2pproxy.logger.debug('Exporting')
                exported = playlistgen.exportm3u(
                    hostport,
                    empty_header=True,
                    archive=True,
                    fmt=self.get_param('fmt')).encode('utf-8')

                connection.send_response(200)
                connection.send_header('Content-Type', 'application/x-mpegurl')
                connection.send_header('Content-Length', str(len(exported)))
                connection.end_headers()
                connection.wfile.write(exported)
            # /archive/?date=[param_date]&channel_id=[param_channel]
            else:
                param_date = self.get_param('date')
                if not param_date: d = date.today()
                else:
                    try:
                        param_date = param_date.split('-')
                        d = date(int(param_date[2]), int(param_date[1]),
                                 int(param_date[0]))
                    except IndexError:
                        connection.dieWithError(500,
                                                'Date param is not correct!',
                                                logging.ERROR)
                        return
                param_channel = self.get_param('channel_id')
                if param_channel == '' or not param_channel:
                    connection.dieWithError(
                        500,
                        'Got /archive/ request but no channel_id specified!',
                        logging.ERROR)
                    return

                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')

                if headers_only: connection.end_headers()
                else:
                    records_list = self.api.records(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)
        # Used to generate logomap for the torrenttv plugin
        elif connection.reqtype == 'logos':
            translations_list = self.api.translations('all')
            last = translations_list[-1]
            connection.send_response(200)
            connection.send_header('Content-Type', 'text/plain;charset=utf-8')
            connection.end_headers()
            connection.wfile.write("logobase = '" + P2pproxy.TTVU + "'\n")
            connection.wfile.write("logomap = {\n")

            for channel in translations_list:
                name = channel.getAttribute('name').encode('utf-8')
                logo = channel.getAttribute('logo').encode('utf-8')
                connection.wfile.write("    u'%s': logobase + '%s'" %
                                       (name, logo))
                if not channel == last: connection.wfile.write(",\n")
                else: connection.wfile.write("\n")

            connection.wfile.write("}\n")

    def get_param(self, key):
        return self.params[key][0] if key in self.params else None

    def get_date_param(self):
        d = self.get_param('date')
        return date.today() if not d else self.parse_date(d)

    def parse_date(self, d):
        try:
            param_date = d.split('-')
            return date(int(param_date[2]), int(param_date[1]),
                        int(param_date[0]))
        except IndexError as e:
            P2pproxy.logger.error('date param is not correct!')
            raise e
Example #7
0
    def handle(self, connection):
        P2pproxy.logger.debug('Handling request')

        hostport = connection.headers['Host']

        query = urlparse.urlparse(connection.path).query
        self.params = urlparse.parse_qs(query)

        if connection.reqtype == 'channels':  # /channels/ branch
            if len(connection.splittedpath) == 3 and connection.splittedpath[2].split('?')[
                0] == 'play':  # /channels/play?id=[id]
                channel_id = self.get_param('id')
                if not channel_id:
                    # /channels/play?id=&_=[epoch timestamp] is Torrent-TV widget proxy check
                    # P2pProxy simply closes connection on this request sending Server header, so do we
                    if self.get_param('_'):
                        P2pproxy.logger.debug('Status check')
                        connection.send_response(200)
                        connection.send_header('Access-Control-Allow-Origin', '*')
                        connection.send_header('Connection', 'close')
                        connection.send_header('Content-Type', 'text/plain;charset=utf-8')
                        connection.send_header('Server', 'P2pProxy/1.0.3.1 AceProxy')
                        connection.wfile.write('\r\n')
                        return
                    else:
                        connection.dieWithError()  # Bad request
                        return

                stream_url = None

                session = TorrentTvApi.auth(config.email, config.password)
                stream_type, stream = TorrentTvApi.stream_source(session, channel_id)

                if stream_type == 'torrent':
                    stream_url = re.sub('^(http.+)$',
                                        lambda match: '/torrent/' + urllib2.quote(match.group(0), '') + '/stream.mp4',
                                        stream)
                elif stream_type == 'contentid':
                    stream_url = re.sub('^([0-9a-f]{40})',
                                        lambda match: '/pid/' + urllib2.quote(match.group(0), '') + '/stream.mp4',
                                        stream)
                connection.path = stream_url
                connection.splittedpath = stream_url.split('/')
                connection.reqtype = connection.splittedpath[1].lower()
                connection.handleRequest(False)
            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()

                param_group = self.get_param('group')
                param_filter = self.get_param('filter')
                if not param_filter:
                    param_filter = 'all'  # default filter

                session = TorrentTvApi.auth(config.email, config.password)
                translations_list = TorrentTvApi.translations(session, param_filter)

                playlistgen = PlaylistGenerator()
                P2pproxy.logger.debug('Generating requested m3u playlist')
                for channel in translations_list:
                    group_id = channel.getAttribute('group')

                    if param_group and param_group != 'all' and param_group != group_id:  # filter channels by group
                        continue

                    name = channel.getAttribute('name')
                    group = TorrentTvApi.CATEGORIES[int(group_id)].decode('utf-8')
                    cid = channel.getAttribute('id')
                    logo = channel.getAttribute('logo')
                    if config.fullpathlogo:
                        logo = 'http://torrent-tv.ru/uploads/' + logo

                    playlistgen.addItem({'name': name, 'url': cid, 'group': group, 'logo': logo})

                P2pproxy.logger.debug('Exporting')
                exported = playlistgen.exportm3u(hostport)
                exported = exported.encode('utf-8')
                connection.wfile.write(exported)
            else:  # /channels/?filter=[filter]
                param_filter = self.get_param('filter')
                if not param_filter:
                    param_filter = 'all'  # default filter

                session = TorrentTvApi.auth(config.email, config.password)
                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.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()
                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 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

                stream_url = None

                session = TorrentTvApi.auth(config.email, config.password)
                stream_type, stream = TorrentTvApi.archive_stream_source(session, record_id)

                if stream_type == 'torrent':
                    stream_url = re.sub('^(http.+)$',
                                        lambda match: '/torrent/' + urllib2.quote(match.group(0), '') + '/stream.mp4',
                                        stream)
                elif stream_type == 'contentid':
                    stream_url = re.sub('^([0-9a-f]{40})',
                                        lambda match: '/pid/' + urllib2.quote(match.group(0), '') + '/stream.mp4',
                                        stream)
                connection.path = stream_url
                connection.splittedpath = stream_url.split('/')
                connection.reqtype = connection.splittedpath[1].lower()
                connection.handleRequest(False)
            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
                else:
                    try:
                        param_date = param_date.split('-')
                        d = date(param_date[2], param_date[1], param_date[0])
                    except IndexError:
                        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

                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')
                    channel_id = record.getAttribute('channel_id')
                    channel_name = ''
                    logo = ''
                    for channel in channels_list:
                        if channel.getAttribute('channel_id') == channel_id:
                            channel_name = channel.getAttribute('name')
                            logo = channel.getAttribute('logo')

                    if channel_name != '':
                        name = '(' + channel_name + ') ' + name
                    if logo != '' and config.fullpathlogo:
                        logo = 'http://torrent-tv.ru/uploads/' + logo

                    playlistgen.addItem({'name': name, 'url': record_id, 'logo': logo})

                P2pproxy.logger.debug('Exporting')
                exported = playlistgen.exportm3u(hostport, empty_header=True, archive=True)
                exported = exported.encode('utf-8')
                connection.wfile.write(exported)
            else:  # /archive/?date=[param_date]&channel_id=[param_channel]
                param_date = self.get_param('date')
                if not param_date:
                    d = date.today()
                else:
                    try:
                        param_date = param_date.split('-')
                        d = date(param_date[2], param_date[1], param_date[0])
                    except IndexError:
                        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

                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)
    def handle(self, connection):
        P2pproxy.logger.debug('Handling request')

        hostport = connection.headers['Host']
        self.params = parse_qs(connection.query)

        # /channels/ branch
        if connection.reqtype in ('channels', 'channels.m3u'):

            if connection.path.endswith('play'):  # /channels/play?id=[id]
                channel_id = self.params.get('id', [''])[0]
                if not channel_id:
                    # /channels/play?id=&_=[epoch timestamp] is Torrent-TV widget proxy check
                    # P2pProxy simply closes connection on this request sending Server header, so do we
                    if self.params.get('_', [''])[0]:
                        P2pproxy.logger.debug('Status check')
                        response_headers = {
                            'Content-Type': 'text/plain;charset=utf-8',
                            'Server': 'P2pProxy/1.0.4.4 HTTPAceProxy',
                            'Access-Control-Allow-Origin': '*',
                            'Connection': 'close'
                        }
                        connection.send_response(200)
                        for k, v in response_headers.items():
                            connection.send_header(k, v)
                        connection.wfile.write('\r\n')
                        return
                    else:
                        connection.send_error(400,
                                              'Bad request')  # Bad request

                try:
                    stream_type, stream, translations_list = TorrentTvApi(
                        config.email,
                        config.password).stream_source(channel_id)
                except Exception as err:
                    connection.send_error(404, '%s' % repr(err), logging.ERROR)
                name = logo = ''

                for channel in translations_list:
                    if channel.getAttribute('id') == channel_id:
                        name = channel.getAttribute('name')
                        logo = channel.getAttribute('logo')
                        if logo != '' and config.fullpathlogo:
                            logo = config.logobase + logo
                        break

                if stream_type not in ('torrent', 'contentid'):
                    connection.send_error(
                        404, 'Unknown stream type: %s' % stream_type,
                        logging.ERROR)
                elif stream_type == 'torrent':
                    connection.path = '/url/%s/%s.ts' % (quote(stream,
                                                               ''), name)
                elif stream_type == 'contentid':
                    connection.path = '/content_id/%s/%s.ts' % (stream, name)

                connection.__dict__.update(
                    {'splittedpath': connection.path.split('/')})
                connection.__dict__.update({
                    'channelName':
                    name,
                    'channelIcon':
                    logo,
                    'reqtype':
                    connection.splittedpath[1].lower()
                })
                return

            # /channels/?filter=[filter]&group=[group]&type=m3u
            elif connection.reqtype == 'channels.m3u' or self.params.get(
                    'type', [''])[0] == 'm3u':

                param_group = self.params.get('group', [''])[0]
                if param_group and 'all' in param_group: param_group = None

                try:
                    translations_list = TorrentTvApi(
                        config.email, config.password).translations(
                            self.params.get('filter', ['all'])[0])
                except Exception as err:
                    connection.send_error(404, '%s' % repr(err), logging.ERROR)

                playlistgen = PlaylistGenerator(
                    m3uchanneltemplate=config.m3uchanneltemplate)
                P2pproxy.logger.debug('Generating requested m3u playlist')
                for channel in translations_list:
                    group_id = channel.getAttribute('group')
                    if param_group and not group_id in param_group.split(','):
                        continue  # filter channels by &group=1,2,5...

                    name = channel.getAttribute('name')
                    group = TorrentTvApi.CATEGORIES[int(group_id)]
                    cid = channel.getAttribute('id')
                    logo = channel.getAttribute('logo')
                    if logo != '' and config.fullpathlogo:
                        logo = config.logobase + logo

                    fields = {
                        'name':
                        name,
                        'id':
                        cid,
                        'url':
                        cid,
                        'group':
                        group,
                        'logo':
                        logo,
                        'tvgid':
                        config.tvgid.format(**fields)
                        if channel.getAttribute('epg_id') != '0' else ''
                    }
                    playlistgen.addItem(fields)

                P2pproxy.logger.debug('Exporting m3u playlist')
                exported = playlistgen.exportm3u(
                    hostport=hostport,
                    header=config.m3uheadertemplate,
                    fmt=self.params.get('fmt', [''])[0])
                connection.send_response(200)
                connection.send_header('Content-Type',
                                       'audio/mpegurl; charset=utf-8')
                try:
                    h = connection.headers.get('Accept-Encoding').split(',')[0]
                    exported = P2pproxy.compress_method[h].compress(
                        exported) + P2pproxy.compress_method[h].flush()
                    connection.send_header('Content-Encoding', h)
                except:
                    pass

                connection.send_header('Content-Length', len(exported))
                connection.end_headers()
                connection.wfile.write(exported)

            # /channels/?filter=[filter]
            else:
                try:
                    translations_list = TorrentTvApi(
                        config.email, config.password).translations(
                            self.params.get('filter', ['all'])[0], True)
                except Exception as err:
                    connection.send_error(404, '%s' % repr(err), logging.ERROR)

                P2pproxy.logger.debug('Exporting m3u playlist')
                response_headers = {
                    'Access-Control-Allow-Origin': '*',
                    'Connection': 'close',
                    'Content-Type': 'text/xml;charset=utf-8',
                    'Content-Length': len(translations_list)
                }
                try:
                    h = connection.headers.get('Accept-Encoding').split(',')[0]
                    translations_list = P2pproxy.compress_method[h].compress(
                        translations_list) + P2pproxy.compress_method[h].flush(
                        )
                    connection.send_header('Content-Encoding', h)
                except:
                    pass
                response_headers['Content-Length'] = len(translations_list)
                connection.send_response(200)
                for k, v in response_headers.items():
                    connection.send_header(k, v)
                connection.end_headers()
                connection.wfile.write(translations_list)

        # same as /channels request
        elif connection.reqtype == 'xbmc.pvr' and connection.path.endswith(
                'playlist'):
            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')

            try:
                translations_list = TorrentTvApi(config.email,
                                                 config.password).translations(
                                                     'all', True)
            except Exception as err:
                connection.send_error(404, '%s' % repr(err), logging.ERROR)
            try:
                h = connection.headers.get('Accept-Encoding').split(',')[0]
                translations_list = P2pproxy.compress_method[h].compress(
                    translations_list) + P2pproxy.compress_method[h].flush()
                connection.send_header('Content-Encoding', h)
            except:
                pass
            connection.send_header('Content-Length', len(translations_list))
            connection.end_headers()
            P2pproxy.logger.debug('Exporting m3u playlist')
            connection.wfile.write(translations_list)

        # /archive/ branch
        elif connection.reqtype == 'archive':
            if connection.path.endswith(
                ('dates', 'dates.m3u')):  # /archive/dates.m3u
                d = datetime.now()
                delta = timedelta(days=1)
                playlistgen = PlaylistGenerator()
                hostport = connection.headers['Host']
                days = int(self.params.get('days', ['7'])[0])
                suffix = '&suffix=%s' % self.params.get(
                    'suffix')[0] if 'suffix' in self.params else ''
                for i in range(days):
                    dfmt = d.strftime('%d-%m-%Y')
                    url = 'http://%s/archive/playlist/?date=%s%s' % (
                        hostport, dfmt, suffix)
                    playlistgen.addItem({
                        'group': '',
                        'tvg': '',
                        'name': dfmt,
                        'url': url
                    })
                    d -= delta
                exported = playlistgen.exportm3u(hostport=hostport,
                                                 empty_header=True,
                                                 parse_url=False,
                                                 fmt=self.params.get(
                                                     'fmt', [''])[0])
                connection.send_response(200)
                connection.send_header('Content-Type',
                                       'audio/mpegurl; charset=utf-8')
                try:
                    h = connection.headers.get('Accept-Encoding').split(',')[0]
                    exported = P2pproxy.compress_method[h].compress(
                        exported) + P2pproxy.compress_method[h].flush()
                    connection.send_header('Content-Encoding', h)
                except:
                    pass
                connection.send_header('Content-Length', len(exported))
                connection.end_headers()
                connection.wfile.write(exported)
                return

            elif connection.path.endswith(
                ('playlist', 'playlist.m3u')):  # /archive/playlist.m3u
                dates = []

                if 'date' in self.params:
                    for d in self.params['date']:
                        dates.append(self.parse_date(d).strftime('%d-%m-%Y'))
                else:
                    d = datetime.now()
                    delta = timedelta(days=1)
                    days = int(self.params.get('days', ['7'])[0])
                    for i in range(days):
                        dates.append(d.strftime('%d-%m-%Y'))
                        d -= delta

                connection.send_response(200)
                connection.send_header('Content-Type',
                                       'audio/mpegurl; charset=utf-8')

                try:
                    channels_list = TorrentTvApi(
                        config.email, config.password).archive_channels()
                except Exception as err:
                    connection.send_error(404, '%s' % repr(err), logging.ERROR)
                hostport = connection.headers['Host']
                playlistgen = PlaylistGenerator()
                suffix = '&suffix=%s' % self.params.get(
                    'suffix')[0] if 'suffix' in self.params else ''
                for channel in channels_list:
                    epg_id = channel.getAttribute('epg_id')
                    name = channel.getAttribute('name')
                    logo = channel.getAttribute('logo')
                    if logo != '' and config.fullpathlogo:
                        logo = config.logobase + logo
                    for d in dates:
                        n = name + ' (' + d + ')' if len(dates) > 1 else name
                        url = 'http://%s/archive/?type=m3u&date=%s&channel_id=%s%s' % (
                            hostport, d, epg_id, suffix)
                        playlistgen.addItem({
                            'group': name,
                            'tvg': '',
                            'name': n,
                            'url': url,
                            'logo': logo
                        })

                exported = playlistgen.exportm3u(hostport=hostport,
                                                 empty_header=True,
                                                 parse_url=False,
                                                 fmt=self.params.get(
                                                     'fmt', [''])[0])
                try:
                    h = connection.headers.get('Accept-Encoding').split(',')[0]
                    exported = P2pproxy.compress_method[h].compress(
                        exported) + P2pproxy.compress_method[h].flush()
                    connection.send_header('Content-Encoding', h)
                except:
                    pass
                connection.send_header('Content-Length', len(exported))
                connection.end_headers()
                connection.wfile.write(exported)
                return

            elif connection.path.endswith('channels'):  # /archive/channels
                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')

                try:
                    archive_channels = TorrentTvApi(
                        config.email, config.password).archive_channels(True)
                except Exception as err:
                    connection.send_error(404, '%s' % repr(err), logging.ERROR)
                P2pproxy.logger.debug('Exporting m3u playlist')
                try:
                    h = connection.headers.get('Accept-Encoding').split(',')[0]
                    archive_channels = P2pproxy.compress_method[h].compress(
                        archive_channels) + P2pproxy.compress_method[h].flush(
                        )
                    connection.send_header('Content-Encoding', h)
                except:
                    pass
                connection.send_header('Content-Length', len(archive_channels))
                connection.end_headers()
                connection.wfile.write(archive_channels)
                return

            if connection.path.endswith(
                    'play'):  # /archive/play?id=[record_id]
                record_id = self.params.get('id', [''])[0]
                if not record_id:
                    connection.send_error(400, 'Bad request')  # Bad request

                try:
                    stream_type, stream = TorrentTvApi(
                        config.email,
                        config.password).archive_stream_source(record_id)
                except Exception as err:
                    connection.send_error(404, '%s' % repr(err), logging.ERROR)

                if stream_type not in ('torrent', 'contentid'):
                    connection.send_error(
                        404, 'Unknown stream type: %s' % stream_type,
                        logging.ERROR)
                elif stream_type == 'torrent':
                    connection.path = '/url/%s/stream.ts' % quote(stream, '')
                elif stream_type == 'contentid':
                    connection.path = '/content_id/%s/stream.ts' % stream

                connection.__dict__.update(
                    {'splittedpath': connection.path.split('/')})
                connection.__dict__.update(
                    {'reqtype': connection.splittedpath[1].lower()})
                return

            # /archive/?type=m3u&date=[param_date]&channel_id=[param_channel]
            elif self.params.get('type', [''])[0] == 'm3u':

                playlistgen = PlaylistGenerator()
                param_channel = self.params.get('channel_id', [''])[0]
                d = self.get_date_param()

                if not param_channel:
                    try:
                        channels_list = TorrentTvApi(
                            config.email, config.password).archive_channels()
                    except Exception as err:
                        connection.send_error(404, '%s' % repr(err),
                                              logging.ERROR)

                    for channel in channels_list:
                        channel_id = channel.getAttribute('epg_id')
                        try:
                            try:
                                records_list = TorrentTvApi(
                                    config.email,
                                    config.password).records(channel_id, d)
                            except Exception as err:
                                connection.send_error(404, '%s' % repr(err),
                                                      logging.ERROR)
                            channel_name = channel.getAttribute('name')
                            logo = channel.getAttribute('logo')
                            if logo != '' and config.fullpathlogo:
                                logo = config.logobase + logo

                            for record in records_list:
                                name = record.getAttribute('name')
                                record_id = record.getAttribute('record_id')
                                playlistgen.addItem({
                                    'group': channel_name,
                                    'tvg': '',
                                    'name': name,
                                    'url': record_id,
                                    'logo': logo
                                })
                        except:
                            P2pproxy.logger.debug(
                                'Failed to load archive for %s' % channel_id)

                else:
                    try:
                        records_list = TorrentTvApi(config.email,
                                                    config.password).records(
                                                        param_channel, d)
                        channels_list = TorrentTvApi(
                            config.email, config.password).archive_channels()
                    except Exception as err:
                        connection.send_error(404, '%s' % repr(err),
                                              logging.ERROR)
                    P2pproxy.logger.debug('Generating archive m3u playlist')

                    for record in records_list:
                        record_id = record.getAttribute('record_id')
                        channel_id = record.getAttribute('epg_id')
                        name = record.getAttribute('name')
                        d = datetime.fromtimestamp(
                            float(
                                record.getAttribute('time'))).strftime('%H:%M')
                        n = '%s %s' % (d, name)
                        logo = ''
                        for channel in channels_list:
                            if channel.getAttribute('epg_id') == channel_id:
                                channel_name = channel.getAttribute('name')
                                logo = channel.getAttribute('logo')

                        if channel_name != '':
                            name = '(' + channel_name + ') ' + name
                        if logo != '' and config.fullpathlogo:
                            logo = config.logobase + logo

                        playlistgen.addItem({
                            'group': channel_name,
                            'name': n,
                            'url': record_id,
                            'logo': logo,
                            'tvg': ''
                        })

                P2pproxy.logger.debug('Exporting m3u playlist')
                exported = playlistgen.exportm3u(hostport=hostport,
                                                 empty_header=True,
                                                 archive=True,
                                                 fmt=self.params.get(
                                                     'fmt', [''])[0])

                connection.send_response(200)
                connection.send_header('Content-Type',
                                       'audio/mpegurl; charset=utf-8')
                try:
                    h = connection.headers.get('Accept-Encoding').split(',')[0]
                    exported = P2pproxy.compress_method[h].compress(
                        exported) + P2pproxy.compress_method[h].flush()
                    connection.send_header('Content-Encoding', h)
                except:
                    pass
                connection.send_header('Content-Length', len(exported))
                connection.end_headers()
                connection.wfile.write(exported)

            # /archive/?date=[param_date]&channel_id=[param_channel]
            else:
                param_date = self.params.get('date', [''])[0]
                if not param_date: d = datetime.now()
                else:
                    try:
                        d = parse_date(param_date)
                    except:
                        return
                param_channel = self.params.get('channel_id', [''])[0]
                if not param_channel:
                    connection.send_error(
                        500,
                        'Got /archive/ request but no channel_id specified!',
                        logging.ERROR)

                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')

                try:
                    records_list = TorrentTvApi(config.email,
                                                config.password).records(
                                                    param_channel,
                                                    d.strftime('%d-%m-%Y'),
                                                    True)
                except Exception as err:
                    connection.send_error(404, '%s' % repr(err), logging.ERROR)
                P2pproxy.logger.debug('Exporting m3u playlist')
                try:
                    h = connection.headers.get('Accept-Encoding').split(',')[0]
                    records_list = P2pproxy.compress_method[h].compress(
                        records_list) + P2pproxy.compress_method[h].flush()
                    connection.send_header('Content-Encoding', h)
                except:
                    pass
                connection.send_header('Content-Length', len(records_list))
                connection.end_headers()
                connection.wfile.write(records_list)

        # Used to generate logomap for the torrenttv plugin
        elif connection.reqtype == 'logobase':
            logomap = {}
            try:
                import config.picons.torrenttv as picons
                logomap = {
                    k: v[v.rfind('/') + 1:]
                    for k, v in picons.logomap.items() if v is not None
                }
            except:
                pass

            #try: translations_list = TorrentTvApi(config.email, config.password).translations('all')
            #except Exception as err:
            #   connection.send_error(404, '%s' % repr(err), logging.ERROR)
            #   return
            #logomap.update({ channel.getAttribute('name'):channel.getAttribute('logo') for channel in translations_list })
            import requests
            url = 'http://hmxuku36whbypzxi.onion/trash/ttv-list/ttv_logo.json'
            proxies = {
                'http': 'socks5h://192.168.2.1:9100',
                'https': 'socks5h://192.168.2.1:9100'
            }
            with requests.get(url, proxies=proxies, timeout=30) as r:
                logomap.update(r.json())

            connection.send_response(200)
            if self.params.get('format', [''])[0] == 'json':
                from requests.compat import json
                exported = ensure_binary(
                    json.dumps(logomap, ensure_ascii=False))
                connection.send_header('Content-Type', 'application/json')
            else:
                exported = "logobase = '%s'\nlogomap = {\n" % config.logobase
                exported += ''.join("    u'%s': logobase + '%s',\n" %
                                    (name, logo)
                                    for name, logo in logomap.items())
                exported += '}\n'
                exported = ensure_binary(exported)
                connection.send_header('Content-Type',
                                       'text/plain;charset=utf-8')
            try:
                h = connection.headers.get('Accept-Encoding').split(',')[0]
                exported = P2pproxy.compress_method[h].compress(
                    exported) + P2pproxy.compress_method[h].flush()
                connection.send_header('Content-Encoding', h)
            except:
                pass
            connection.send_header('Content-Length', len(exported))
            connection.end_headers()
            connection.wfile.write(exported)
            P2pproxy.logger.debug('%s picon channels exported' % len(logomap))
Example #9
0
    def handle(self, connection, headers_only=False):
        P2pproxy.logger.debug('Handling request')

        hostport = connection.headers['Host']
        self.params = parse_qs(connection.query)

        # /channels/ branch
        if connection.reqtype in ('channels', 'channels.m3u'):

            if connection.path.endswith('play'):  # /channels/play?id=[id]
                channel_id = self.params.get('id', [''])[0]
                if not channel_id:
                    # /channels/play?id=&_=[epoch timestamp] is Torrent-TV widget proxy check
                    # P2pProxy simply closes connection on this request sending Server header, so do we
                    if self.params.get('_', [''])[0]:
                        P2pproxy.logger.debug('Status check')
                        response_headers = {
                            'Content-Type': 'text/plain;charset=utf-8',
                            'Server': 'P2pProxy/1.0.4.4 HTTPAceProxy',
                            'Access-Control-Allow-Origin': '*',
                            'Connection': 'close'
                        }
                        connection.send_response(200)
                        for k, v in list(response_headers.items()):
                            connection.send_header(k, v)
                        connection.wfile.write('\r\n')
                        return
                    else:
                        connection.dieWithError(400,
                                                'Bad request')  # Bad request
                        return

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

                stream_type, stream, translations_list = TorrentTvApi(
                    config.email, config.password).stream_source(channel_id)
                name = logo = ''

                for channel in translations_list:
                    if channel.getAttribute('id') == channel_id:
                        name = channel.getAttribute('name')
                        logo = channel.getAttribute('logo')
                        if logo != '' and config.fullpathlogo:
                            logo = P2pproxy.TTVU + logo
                        break

                if stream_type not in (b'torrent', b'contentid'):
                    connection.dieWithError(
                        404, 'Unknown stream type: %s' % stream_type,
                        logging.ERROR)
                    return
                elif stream_type == b'torrent':
                    connection.path = '/url/%s/stream.mp4' % quote(stream, '')
                elif stream_type == b'contentid':
                    connection.path = '/content_id/%s/stream.mp4' % stream

                connection.splittedpath = connection.path.split('/')
                connection.reqtype = connection.splittedpath[1].lower()
                connection.handleRequest(headers_only,
                                         name,
                                         logo,
                                         fmt=self.params.get('fmt', [''])[0])

            # /channels/?filter=[filter]&group=[group]&type=m3u
            elif connection.reqtype == 'channels.m3u' or self.params.get(
                    'type', [''])[0] == 'm3u':
                if headers_only:
                    connection.send_response(200)
                    connection.send_header('Content-Type',
                                           'audio/mpegurl; charset=utf-8')
                    connection.end_headers()
                    return

                param_group = self.params.get('group', [''])[0]
                if param_group and 'all' in param_group: param_group = None

                translations_list = TorrentTvApi(config.email,
                                                 config.password).translations(
                                                     self.params.get(
                                                         'filter', ['all'])[0])

                playlistgen = PlaylistGenerator(
                    m3uchanneltemplate=config.m3uchanneltemplate)
                P2pproxy.logger.debug('Generating requested m3u playlist')
                for channel in translations_list:
                    group_id = channel.getAttribute('group')
                    if param_group and not group_id in param_group:
                        continue  # filter channels by &group=1,2,5...

                    name = channel.getAttribute('name')
                    group = TorrentTvApi.CATEGORIES[int(group_id)]
                    cid = channel.getAttribute('id')
                    logo = channel.getAttribute('logo')
                    if logo != '' and config.fullpathlogo:
                        logo = P2pproxy.TTVU + logo

                    fields = {
                        'name': name,
                        'id': cid,
                        'url': cid,
                        'group': group,
                        'logo': logo
                    }
                    if channel.getAttribute('epg_id') != '0':
                        fields['tvgid'] = config.tvgid % fields
                    playlistgen.addItem(fields)

                P2pproxy.logger.debug('Exporting m3u playlist')
                exported = playlistgen.exportm3u(
                    hostport=hostport,
                    header=config.m3uheadertemplate,
                    fmt=self.params.get('fmt', [''])[0]).encode('utf-8')
                connection.send_response(200)
                connection.send_header('Content-Type',
                                       'audio/mpegurl; charset=utf-8')
                connection.send_header('Content-Length', str(len(exported)))
                connection.end_headers()
                connection.wfile.write(exported)

            # /channels/?filter=[filter]
            else:
                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

                translations_list = TorrentTvApi(
                    config.email, config.password).translations(
                        self.params.get('filter', ['all'])[0], True)

                P2pproxy.logger.debug('Exporting m3u playlist')
                response_headers = {
                    'Access-Control-Allow-Origin': '*',
                    'Connection': 'close',
                    'Content-Type': 'text/xml;charset=utf-8',
                    'Content-Length': str(len(translations_list))
                }
                connection.send_response(200)
                for k, v in list(response_headers.items()):
                    connection.send_header(k, v)
                connection.end_headers()
                connection.wfile.write(translations_list)

        # same as /channels request
        elif connection.reqtype == 'xbmc.pvr' and connection.path.endswith(
                'playlist'):
            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')

            if headers_only:
                connection.end_headers()
                return

            translations_list = TorrentTvApi(config.email,
                                             config.password).translations(
                                                 'all', True)
            connection.send_header('Content-Length',
                                   str(len(translations_list)))
            connection.end_headers()
            P2pproxy.logger.debug('Exporting m3u playlist')
            connection.wfile.write(translations_list)

        # /archive/ branch
        elif connection.reqtype == 'archive':
            if connection.path.endswith(
                ('dates', 'dates.m3u')):  # /archive/dates.m3u
                d = datetime.now()
                delta = timedelta(days=1)
                playlistgen = PlaylistGenerator()
                hostport = connection.headers['Host']
                days = int(self.params.get('days', ['7'])[0])
                suffix = '&suffix=%s' % self.params.get('suffix', [''])[0]
                for i in range(days):
                    dfmt = d.strftime('%d-%m-%Y')
                    url = 'http://%s/archive/playlist/?date=%s%s' % (
                        hostport, dfmt, suffix)
                    playlistgen.addItem({
                        'group': '',
                        'tvg': '',
                        'name': dfmt,
                        'url': url
                    })
                    d -= delta
                exported = playlistgen.exportm3u(hostport,
                                                 empty_header=True,
                                                 process_url=False,
                                                 fmt=self.params.get(
                                                     'fmt',
                                                     [''])[0]).encode('utf-8')
                connection.send_response(200)
                connection.send_header('Content-Type',
                                       'audio/mpegurl; charset=utf-8')
                connection.send_header('Content-Length', str(len(exported)))
                connection.end_headers()
                connection.wfile.write(exported)
                return

            elif connection.path.endswith(
                ('playlist', 'playlist.m3u')):  # /archive/playlist.m3u
                dates = list()

                if 'date' in self.params:
                    for d in self.params['date']:
                        dates.append(self.parse_date(d).strftime('%d-%m-%Y'))
                else:
                    d = datetime.now()
                    delta = timedelta(days=1)
                    days = int(self.params.get('days', ['7'])[0])
                    for i in range(days):
                        dates.append(d.strftime('%d-%m-%Y'))
                        d -= delta

                connection.send_response(200)
                connection.send_header('Content-Type',
                                       'audio/mpegurl; charset=utf-8')

                if headers_only:
                    connection.end_headers()
                    return

                channels_list = TorrentTvApi(
                    config.email, config.password).archive_channels()
                hostport = connection.headers['Host']
                playlistgen = PlaylistGenerator()
                suffix = '&suffix=%s' % self.params.get('suffix', [''])[0]

                for channel in channels_list:
                    epg_id = channel.getAttribute('epg_id')
                    name = channel.getAttribute('name')
                    logo = channel.getAttribute('logo')
                    if logo != '' and config.fullpathlogo:
                        logo = P2pproxy.TTVU + logo
                    for d in dates:
                        n = name + ' (' + d + ')' if len(dates) > 1 else name
                        url = 'http://%s/archive/?type=m3u&date=%s&channel_id=%s%s' % (
                            hostport, d, epg_id, suffix)
                        playlistgen.addItem({
                            'group': name,
                            'tvg': '',
                            'name': n,
                            'url': url,
                            'logo': logo
                        })

                exported = playlistgen.exportm3u(hostport,
                                                 empty_header=True,
                                                 process_url=False,
                                                 fmt=self.params.get(
                                                     'fmt',
                                                     [''])[0]).encode('utf-8')
                connection.send_header('Content-Length', str(len(exported)))
                connection.end_headers()
                connection.wfile.write(exported)
                return

            elif connection.path.endswith('channels'):  # /archive/channels
                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')

                if headers_only: connection.end_headers()
                else:
                    archive_channels = TorrentTvApi(
                        config.email, config.password).archive_channels(True)
                    P2pproxy.logger.debug('Exporting m3u playlist')
                    connection.send_header('Content-Length',
                                           str(len(archive_channels)))
                    connection.end_headers()
                    connection.wfile.write(archive_channels)
                return

            if connection.path.endswith(
                    'play'):  # /archive/play?id=[record_id]
                record_id = self.params.get('id', [''])[0]
                if not record_id:
                    connection.dieWithError(400, 'Bad request')  # Bad request
                    return

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

                stream_type, stream = TorrentTvApi(
                    config.email,
                    config.password).archive_stream_source(record_id)

                if stream_type not in (b'torrent', b'contentid'):
                    connection.dieWithError(
                        404, 'Unknown stream type: %s' % stream_type,
                        logging.ERROR)
                    return
                elif stream_type == b'torrent':
                    connection.path = '/url/%s/stream.mp4' % quote(stream, '')
                elif stream_type == b'contentid':
                    connection.path = '/content_id/%s/stream.mp4' % stream

                connection.splittedpath = connection.path.split('/')
                connection.reqtype = connection.splittedpath[1].lower()
                connection.handleRequest(headers_only,
                                         fmt=self.params.get('fmt', [''])[0])

            # /archive/?type=m3u&date=[param_date]&channel_id=[param_channel]
            elif self.params.get('type', [''])[0] == 'm3u':

                if headers_only:
                    connection.send_response(200)
                    connection.send_header('Content-Type',
                                           'audio/mpegurl; charset=utf-8')
                    connection.end_headers()
                    return

                playlistgen = PlaylistGenerator()
                param_channel = self.params.get('channel_id', [''])[0]
                d = self.get_date_param()

                if not param_channel:
                    channels_list = TorrentTvApi(
                        config.email, config.password).archive_channels()

                    for channel in channels_list:
                        channel_id = channel.getAttribute('epg_id')
                        try:
                            records_list = TorrentTvApi(
                                config.email,
                                config.password).records(channel_id, d)
                            channel_name = channel.getAttribute('name')
                            logo = channel.getAttribute('logo')
                            if logo != '' and config.fullpathlogo:
                                logo = P2pproxy.TTVU + logo

                            for record in records_list:
                                name = record.getAttribute('name')
                                record_id = record.getAttribute('record_id')
                                playlistgen.addItem({
                                    'group': channel_name,
                                    'tvg': '',
                                    'name': name,
                                    'url': record_id,
                                    'logo': logo
                                })
                        except:
                            P2pproxy.logger.debug(
                                'Failed to load archive for %s' % channel_id)

                else:
                    records_list = TorrentTvApi(config.email,
                                                config.password).records(
                                                    param_channel, d)
                    channels_list = TorrentTvApi(
                        config.email, config.password).archive_channels()
                    P2pproxy.logger.debug('Generating archive m3u playlist')

                    for record in records_list:
                        record_id = record.getAttribute('record_id')
                        channel_id = record.getAttribute('epg_id')
                        name = record.getAttribute('name')
                        d = datetime.fromtimestamp(
                            float(
                                record.getAttribute('time'))).strftime('%H:%M')
                        n = '%s %s' % (d, name)
                        logo = ''
                        for channel in channels_list:
                            if channel.getAttribute('epg_id') == channel_id:
                                channel_name = channel.getAttribute('name')
                                logo = channel.getAttribute('logo')

                        if channel_name != '':
                            name = '(' + channel_name + ') ' + name
                        if logo != '' and config.fullpathlogo:
                            logo = P2pproxy.TTVU + logo

                        playlistgen.addItem({
                            'group': channel_name,
                            'name': n,
                            'url': record_id,
                            'logo': logo,
                            'tvg': ''
                        })

                P2pproxy.logger.debug('Exporting m3u playlist')
                exported = playlistgen.exportm3u(hostport,
                                                 empty_header=True,
                                                 archive=True,
                                                 fmt=self.params.get(
                                                     'fmt',
                                                     [''])[0]).encode('utf-8')

                connection.send_response(200)
                connection.send_header('Content-Type',
                                       'audio/mpegurl; charset=utf-8')
                connection.send_header('Content-Length', str(len(exported)))
                connection.end_headers()
                connection.wfile.write(exported)

            # /archive/?date=[param_date]&channel_id=[param_channel]
            else:
                param_date = self.params.get('date', [''])[0]
                if not param_date: d = datetime.now()
                else:
                    try:
                        d = parse_date(param_date)
                    except:
                        return
                param_channel = self.params.get('channel_id', [''])[0]
                if not param_channel:
                    connection.dieWithError(
                        500,
                        'Got /archive/ request but no channel_id specified!',
                        logging.ERROR)
                    return

                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')

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

        # Used to generate logomap for the torrenttv plugin
        elif connection.reqtype == 'logos':
            translations_list = TorrentTvApi(
                config.email, config.password).translations('all')
            last = translations_list[-1]
            connection.send_response(200)
            connection.send_header('Content-Type', 'text/plain;charset=utf-8')
            connection.end_headers()
            connection.wfile.write("logobase = '" + P2pproxy.TTVU + "'\n")
            connection.wfile.write("logomap = {\n")

            for channel in translations_list:
                name = channel.getAttribute('name').encode('utf-8')
                logo = channel.getAttribute('logo').encode('utf-8')
                connection.wfile.write("    u'%s': logobase + '%s'" %
                                       (name, logo))
                connection.wfile.write(
                    ",\n") if not channel == last else connection.wfile.write(
                        "\n")

            connection.wfile.write("}\n")
Example #10
0
    def handle(self, connection):
        P2pproxy.logger.debug("Handling request")

        hostport = connection.headers["Host"]

        query = urlparse.urlparse(connection.path).query
        self.params = urlparse.parse_qs(query)

        if connection.reqtype == "channels":  # /channels/ branch
            if (
                len(connection.splittedpath) == 3 and connection.splittedpath[2].split("?")[0] == "play"
            ):  # /channels/play?id=[id]
                channel_id = self.get_param("id")
                if not channel_id:
                    # /channels/play?id=&_=[epoch timestamp] is Torrent-TV widget proxy check
                    # P2pProxy simply closes connection on this request sending Server header, so do we
                    if self.get_param("_"):
                        P2pproxy.logger.debug("Status check")
                        connection.send_response(200)
                        connection.send_header("Access-Control-Allow-Origin", "*")
                        connection.send_header("Connection", "close")
                        connection.send_header("Content-Type", "text/plain;charset=utf-8")
                        connection.send_header("Server", "P2pProxy/1.0.3.1 AceProxy")
                        connection.wfile.write("\r\n")
                        return
                    else:
                        connection.dieWithError()  # Bad request
                        return

                stream_url = None

                session = TorrentTvApi.auth(config.email, config.password)
                stream_type, stream = TorrentTvApi.stream_source(session, channel_id)

                if stream_type == "torrent":
                    stream_url = re.sub(
                        "^(http.+)$",
                        lambda match: "/torrent/" + urllib2.quote(match.group(0), "") + "/stream.mp4",
                        stream,
                    )
                elif stream_type == "contentid":
                    stream_url = re.sub(
                        "^([0-9a-f]{40})",
                        lambda match: "/pid/" + urllib2.quote(match.group(0), "") + "/stream.mp4",
                        stream,
                    )
                connection.path = stream_url
                connection.splittedpath = stream_url.split("/")
                connection.reqtype = connection.splittedpath[1].lower()
                connection.handleRequest(False)
            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()

                param_group = self.get_param("group")
                param_filter = self.get_param("filter")
                if not param_filter:
                    param_filter = "all"  # default filter

                session = TorrentTvApi.auth(config.email, config.password)
                translations_list = TorrentTvApi.translations(session, param_filter)

                playlistgen = PlaylistGenerator()
                P2pproxy.logger.debug("Generating requested m3u playlist")
                for channel in translations_list:
                    group_id = channel.getAttribute("group")

                    if param_group and param_group != "all" and param_group != group_id:  # filter channels by group
                        continue

                    name = channel.getAttribute("name")
                    group = TorrentTvApi.CATEGORIES[int(group_id)].decode("utf-8")
                    cid = channel.getAttribute("id")
                    logo = channel.getAttribute("logo")
                    if config.fullpathlogo:
                        logo = "http://torrent-tv.ru/uploads/" + logo

                    fields = {"name": name, "id": cid, "url": cid, "group": group, "logo": logo}
                    fields["tvgid"] = config.tvgid % fields
                    playlistgen.addItem(fields)

                P2pproxy.logger.debug("Exporting")
                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.wfile.write(exported)
            else:  # /channels/?filter=[filter]
                param_filter = self.get_param("filter")
                if not param_filter:
                    param_filter = "all"  # default filter

                session = TorrentTvApi.auth(config.email, config.password)
                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.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()
                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 (
                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

                stream_url = None

                session = TorrentTvApi.auth(config.email, config.password)
                stream_type, stream = TorrentTvApi.archive_stream_source(session, record_id)

                if stream_type == "torrent":
                    stream_url = re.sub(
                        "^(http.+)$",
                        lambda match: "/torrent/" + urllib2.quote(match.group(0), "") + "/stream.mp4",
                        stream,
                    )
                elif stream_type == "contentid":
                    stream_url = re.sub(
                        "^([0-9a-f]{40})",
                        lambda match: "/pid/" + urllib2.quote(match.group(0), "") + "/stream.mp4",
                        stream,
                    )
                connection.path = stream_url
                connection.splittedpath = stream_url.split("/")
                connection.reqtype = connection.splittedpath[1].lower()
                connection.handleRequest(False)
            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
                else:
                    try:
                        param_date = param_date.split("-")
                        d = date(param_date[2], param_date[1], param_date[0])
                    except IndexError:
                        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

                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")
                    channel_id = record.getAttribute("channel_id")
                    channel_name = ""
                    logo = ""
                    for channel in channels_list:
                        if channel.getAttribute("channel_id") == channel_id:
                            channel_name = channel.getAttribute("name")
                            logo = channel.getAttribute("logo")

                    if channel_name != "":
                        name = "(" + channel_name + ") " + name
                    if logo != "" and config.fullpathlogo:
                        logo = "http://torrent-tv.ru/uploads/" + logo

                    playlistgen.addItem({"name": name, "url": record_id, "logo": logo})

                P2pproxy.logger.debug("Exporting")
                exported = playlistgen.exportm3u(hostport, empty_header=True, archive=True)
                exported = exported.encode("utf-8")
                connection.wfile.write(exported)
            else:  # /archive/?date=[param_date]&channel_id=[param_channel]
                param_date = self.get_param("date")
                if not param_date:
                    d = date.today()
                else:
                    try:
                        param_date = param_date.split("-")
                        d = date(param_date[2], param_date[1], param_date[0])
                    except IndexError:
                        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

                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)
Example #11
0
 def __init__(self, AceConfig, AceStuff):
     super(P2pproxy, self).__init__(AceConfig, AceStuff)
     self.params = None
     self.api = TorrentTvApi(config.email, config.password, config.sessiontimeout)
Example #12
0
class P2pproxy(AceProxyPlugin):
    TTV = 'http://torrent-tv.ru/'
    TTVU = TTV + 'uploads/'
    handlers = ('channels', 'channels.m3u', 'archive', 'xbmc.pvr', 'logos')
    logger = logging.getLogger('plugin_p2pproxy')

    def __init__(self, AceConfig, AceStuff):
        super(P2pproxy, self).__init__(AceConfig, AceStuff)
        self.params = None
        self.api = TorrentTvApi(config.email, config.password, config.sessiontimeout)

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

        hostport = connection.headers['Host']

        query = urlparse.urlparse(connection.path).query
        self.params = urlparse.parse_qs(query)

        if connection.reqtype == 'channels' or connection.reqtype == 'channels.m3u':  # /channels/ branch
            if len(connection.splittedpath) == 3 and connection.splittedpath[2].split('?')[
                0] == 'play':  # /channels/play?id=[id]
                channel_id = self.get_param('id')
                if not channel_id:
                    # /channels/play?id=&_=[epoch timestamp] is Torrent-TV widget proxy check
                    # P2pProxy simply closes connection on this request sending Server header, so do we
                    if self.get_param('_'):
                        P2pproxy.logger.debug('Status check')
                        connection.send_response(200)
                        connection.send_header('Access-Control-Allow-Origin', '*')
                        connection.send_header('Connection', 'close')
                        connection.send_header('Content-Type', 'text/plain;charset=utf-8')
                        connection.send_header('Server', 'P2pProxy/1.0.3.1 AceProxy')
                        connection.wfile.write('\r\n')
                        return
                    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

                stream_type, stream = self.api.stream_source(channel_id)

                if stream_type == 'torrent':
                    stream_url = re.sub('^(http.+)$',
                                        lambda match: '/torrent/' + urllib2.quote(match.group(0), '') + '/stream.mp4',
                                        stream)
                elif stream_type == 'contentid':
                    stream_url = re.sub('^([0-9a-f]{40})',
                                        lambda match: '/pid/' + urllib2.quote(match.group(0), '') + '/stream.mp4',
                                        stream)
                connection.path = stream_url
                connection.splittedpath = stream_url.split('/')
                connection.reqtype = connection.splittedpath[1].lower()
                connection.handleRequest(headers_only, fmt=self.get_param('fmt'))
            elif connection.reqtype == 'channels.m3u' or self.get_param('type') == 'm3u':  # /channels/?filter=[filter]&group=[group]&type=m3u
                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')
                if not param_filter:
                    param_filter = 'all'  # default filter

                translations_list = self.api.translations(param_filter)

                playlistgen = PlaylistGenerator()
                P2pproxy.logger.debug('Generating requested m3u playlist')
                for channel in translations_list:
                    group_id = channel.getAttribute('group')

                    if param_group and param_group != 'all' and param_group != group_id:  # filter channels by group
                        continue

                    name = channel.getAttribute('name')
                    group = TorrentTvApi.CATEGORIES[int(group_id)].decode('utf-8')
                    cid = channel.getAttribute('id')
                    logo = channel.getAttribute('logo')
                    if config.fullpathlogo:
                        logo = P2pproxy.TTVU + logo

                    fields = {'name': name, 'id': cid, 'url': cid, 'group': group, 'logo': logo}
                    fields['tvgid'] = config.tvgid % fields
                    playlistgen.addItem(fields)

                P2pproxy.logger.debug('Exporting')
                header = '#EXTM3U url-tvg="%s" tvg-shift=%d\n' % (config.tvgurl, config.tvgshift)
                exported = playlistgen.exportm3u(hostport=hostport, header=header, fmt=self.get_param('fmt'))
                exported = exported.encode('utf-8')
                connection.send_response(200)
                connection.send_header('Content-Type', 'application/x-mpegurl')
                connection.send_header('Content-Length', str(len(exported)))
                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

                translations_list = self.api.translations(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-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':
                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')
                
                if headers_only:
                    connection.end_headers()
                    return
                
                translations_list = self.api.translations('all', True)
                connection.send_header('Content-Length', str(len(translations_list)))
                connection.end_headers()
                P2pproxy.logger.debug('Exporting')
                connection.wfile.write(translations_list)
        elif connection.reqtype == 'archive':  # /archive/ branch
            if len(connection.splittedpath) >= 3 and (connection.splittedpath[2] == 'dates' or connection.splittedpath[2] == 'dates.m3u'):  # /archive/dates.m3u
                d = date.today()
                delta = timedelta(days=1)
                playlistgen = PlaylistGenerator()
                hostport = connection.headers['Host']
                days = int(self.get_param('days')) if self.params.has_key('days') else 7
                suffix = '&suffix=' + self.get_param('suffix') if self.params.has_key('suffix') else ''
                for i in range(days):
                    dfmt = d.strftime('%d-%m-%Y')
                    url = 'http://%s/archive/playlist/?date=%s%s' % (hostport, dfmt, suffix) 
                    playlistgen.addItem({'group': '', 'tvg': '', 'name': dfmt, 'url': url})
                    d = d - delta
                exported = playlistgen.exportm3u(hostport, empty_header=True, process_url=False, fmt=self.get_param('fmt')).encode('utf-8')
                connection.send_response(200)
                connection.send_header('Content-Type', 'application/x-mpegurl')
                connection.send_header('Content-Length', str(len(exported)))
                connection.end_headers()
                connection.wfile.write(exported)
                return
            elif len(connection.splittedpath) >= 3 and (connection.splittedpath[2] == 'playlist' or connection.splittedpath[2] == 'playlist.m3u'):  # /archive/playlist.m3u
                dates = list()
                
                if self.params.has_key('date'):
                    for d in self.params['date']:
                        dates.append(self.parse_date(d).strftime('%d-%m-%Y').replace('-0', '-'))
                else:
                    d = date.today()
                    delta = timedelta(days=1)
                    days = int(self.get_param('days')) if self.params.has_key('days') else 7
                    for i in range(days):
                        dates.append(d.strftime('%d-%m-%Y').replace('-0', '-'))
                        d = d - delta
                
                connection.send_response(200)
                connection.send_header('Content-Type', 'application/x-mpegurl')
                
                if headers_only:
                    connection.end_headers()
                    return
                
                channels_list = self.api.archive_channels()
                hostport = connection.headers['Host']
                playlistgen = PlaylistGenerator()
                suffix = '&suffix=' + self.get_param('suffix') if self.params.has_key('suffix') else ''
                    
                for channel in channels_list:
                        epg_id = channel.getAttribute('epg_id')
                        name = channel.getAttribute('name')
                        logo = channel.getAttribute('logo')
                        if logo != '' and config.fullpathlogo:
                            logo = P2pproxy.TTVU + logo
                        for d in dates:
                            n = name + ' (' + d + ')' if len(dates) > 1 else name
                            url = 'http://%s/archive/?type=m3u&date=%s&channel_id=%s%s' % (hostport, d, epg_id, suffix)
                            playlistgen.addItem({'group': name, 'tvg': '', 'name': n, 'url': url, 'logo': logo})

                exported = playlistgen.exportm3u(hostport, empty_header=True, process_url=False, fmt=self.get_param('fmt')).encode('utf-8')
                connection.send_header('Content-Length', str(len(exported)))
                connection.end_headers()
                connection.wfile.write(exported)
                return
            elif len(connection.splittedpath) == 3 and connection.splittedpath[2] == 'channels':  # /archive/channels
                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')
                
                if headers_only:
                    connection.end_headers()
                else:
                    archive_channels = self.api.archive_channels(True)
                    P2pproxy.logger.debug('Exporting')
                    connection.send_header('Content-Length', str(len(archive_channels)))
                    connection.end_headers()
                    connection.wfile.write(archive_channels)
                
                return
            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

                stream_type, stream = self.api.archive_stream_source(record_id)

                if stream_type == 'torrent':
                    stream_url = re.sub('^(http.+)$',
                                        lambda match: '/torrent/' + urllib2.quote(match.group(0), '') + '/stream.mp4',
                                        stream)
                elif stream_type == 'contentid':
                    stream_url = re.sub('^([0-9a-f]{40})',
                                        lambda match: '/pid/' + urllib2.quote(match.group(0), '') + '/stream.mp4',
                                        stream)
                connection.path = stream_url
                connection.splittedpath = stream_url.split('/')
                connection.reqtype = connection.splittedpath[1].lower()
                connection.handleRequest(headers_only, fmt=self.get_param('fmt'))
            elif self.get_param('type') == 'm3u':  # /archive/?type=m3u&date=[param_date]&channel_id=[param_channel]
                d = self.get_date_param()
                    
                if headers_only:
                    connection.send_response(200)
                    connection.send_header('Content-Type', 'application/x-mpegurl')
                    connection.end_headers()
                    return

                playlistgen = PlaylistGenerator()
                param_channel = self.get_param('channel_id')
                d = d.strftime('%d-%m-%Y').replace('-0', '-')
                
                if param_channel == '' or not param_channel:
                    channels_list = self.api.archive_channels()
                    
                    for channel in channels_list:
                            channel_id = channel.getAttribute('epg_id')
                            try:
                                records_list = self.api.records(channel_id, d)
                                channel_name = channel.getAttribute('name')
                                logo = channel.getAttribute('logo')
                                if logo != '' and config.fullpathlogo:
                                    logo = P2pproxy.TTVU + logo
                                
                                for record in records_list:
                                    name = record.getAttribute('name')
                                    record_id = record.getAttribute('record_id')
                                    playlistgen.addItem({'group': channel_name, 'tvg': '',
                                        'name': name, 'url': record_id, 'logo': logo})
                            except:
                                P2pproxy.logger.debug('Failed to load archive for ' + channel_id)

                else:
                    records_list = self.api.records(param_channel, d)
                    channels_list = self.api.archive_channels()
                    P2pproxy.logger.debug('Generating archive m3u playlist')
                    
                    for record in records_list:
                        record_id = record.getAttribute('record_id')
                        channel_id = record.getAttribute('epg_id')
                        name = record.getAttribute('name')
                        d = time.localtime(float(record.getAttribute('time')))
                        n = '%.2d:%.2d %s' % (d.tm_hour, d.tm_min, name)
                        logo = ''
                        for channel in channels_list:
                            if channel.getAttribute('epg_id') == channel_id:
                                channel_name = channel.getAttribute('name')
                                logo = channel.getAttribute('logo')
    
                        if channel_name != '':
                            name = '(' + channel_name + ') ' + name
                        if logo != '' and config.fullpathlogo:
                            logo = P2pproxy.TTVU + logo
    
                        playlistgen.addItem({'group': channel_name, 'name': n, 'url': record_id, 'logo': logo, 'tvg': ''})

                P2pproxy.logger.debug('Exporting')
                exported = playlistgen.exportm3u(hostport, empty_header=True, archive=True, fmt=self.get_param('fmt'))
                exported = exported.encode('utf-8')
                
                connection.send_response(200)
                connection.send_header('Content-Type', 'application/x-mpegurl')
                connection.send_header('Content-Length', str(len(exported)))
                connection.end_headers()
                connection.wfile.write(exported)
            else:  # /archive/?date=[param_date]&channel_id=[param_channel]
                param_date = self.get_param('date')
                if not param_date:
                    d = date.today()
                else:
                    try:
                        param_date = param_date.split('-')
                        d = date(int(param_date[2]), int(param_date[1]), int(param_date[0]))
                    except IndexError:
                        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


                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')
                                
                if headers_only:
                    connection.end_headers()
                else:
                    records_list = self.api.records(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)
        elif connection.reqtype == 'logos':  # Used to generate logomap for the torrenttv plugin
            translations_list = self.api.translations('all')
            last = translations_list[-1]
            connection.send_response(200)
            connection.send_header('Content-Type', 'text/plain;charset=utf-8')
            connection.end_headers()
            connection.wfile.write("logobase = '" + P2pproxy.TTVU + "'\n")
            connection.wfile.write("logomap = {\n")
            
            for channel in translations_list:
                name = channel.getAttribute('name').encode('utf-8')
                logo = channel.getAttribute('logo').encode('utf-8')
                connection.wfile.write("    u'%s': logobase + '%s'" % (name, logo))
                if not channel == last:
                    connection.wfile.write(",\n")
                else:
                    connection.wfile.write("\n")
                
            connection.wfile.write("}\n")

    def get_param(self, key):
        if key in self.params:
            return self.params[key][0]
        else:
            return None

    def get_date_param(self):
        d = self.get_param('date')
        
        if not d:
            return date.today()  
        else:
            return self.parse_date(d)

    def parse_date(self, d):
        try:
            param_date = d.split('-')
            return date(int(param_date[2]), int(param_date[1]), int(param_date[0]))
        except IndexError as e:
            P2pproxy.logger.error('date param is not correct!')
            raise e
Example #13
0
    def downloadPlaylist(self):
        try:
            self.logger.debug('Trying to download playlist')
            req = urllib2.Request(config.url,
                                  headers={'User-Agent': "Magic Browser"})
            req.add_header('Accept-encoding', 'gzip')
            response = urllib2.urlopen(req, timeout=15)

            origin = ''

            if response.info().get('Content-Encoding') == 'gzip':
                # read the encoded response into a buffer
                buffer = StringIO(response.read())
                # gzip decode the response
                f = gzip.GzipFile(fileobj=buffer)
                # store the result
                origin = f.read()
                # close the buffer
                buffer.close()
                # else if the response isn't gzip-encoded
                self.logger.debug('Playlist downloaded using gzip compression')
            else:
                # store the result
                origin = response.read()
                self.logger.debug('Playlist downloaded')

            matches = re.finditer(
                r',(?P<name>\S.+) \((?P<group>.+)\)[\r\n]+(?P<url>[^\r\n]+)?',
                origin, re.MULTILINE)
            self.playlisttime = int(time.time())
            self.playlist = PlaylistGenerator()
            self.channels = dict()
            m = md5.new()

            for match in matches:
                itemdict = match.groupdict()
                encname = itemdict.get('name')
                name = encname.decode('UTF-8')
                logo = config.logomap.get(name)
                url = itemdict['url']
                if logo:
                    itemdict['logo'] = logo

                if (url.startswith('acestream://')) or (
                        url.startswith('http://')
                        and url.endswith('.acelive')):
                    self.channels[name] = url
                    itemdict['url'] = urllib2.quote(encname, '') + '.mp4'
                self.playlist.addItem(itemdict)
                m.update(encname)

            self.etag = '"' + m.hexdigest() + '"'
        except:
            self.logger.error("Can't download playlist!")
            self.logger.error(traceback.format_exc())
            return False

        if self.updatelogos:
            try:
                api = TorrentTvApi(p2pconfig.email, p2pconfig.password,
                                   p2pconfig.sessiontimeout, p2pconfig.zoneid)
                translations = api.translations('all')
                logos = dict()

                for channel in translations:
                    name = channel.getAttribute('name').encode('utf-8')
                    logo = channel.getAttribute('logo').encode('utf-8')
                    logos[name] = config.logobase + logo

                self.logomap = logos
                self.logger.debug("Logos updated")
            except:
                # p2pproxy plugin seems not configured
                self.updatelogos = False

        return True
Example #14
0
    def downloadPlaylist(self):
        self.playlisttime = int(gevent.time.time())
        self.playlist = PlaylistGenerator(
            m3uchanneltemplate=config.m3uchanneltemplate)
        self.channels = {}
        m = requests.auth.hashlib.md5()
        try:
            if self.updatelogos:
                try:
                    translations_list = TorrentTvApi(
                        p2pconfig.email,
                        p2pconfig.password).translations('all')
                    for channel in translations_list:
                        name = channel.getAttribute('name')
                        if channel.getAttribute('epg_id') not in ('0', '',
                                                                  ' '):
                            self.epg_id[name] = 'ttv%s' % channel.getAttribute(
                                'id')
                        if not name in self.logomap:
                            self.logomap[
                                name] = config.logobase + channel.getAttribute(
                                    'logo')

                    self.logger.debug('Logos updated')
                finally:
                    self.updatelogos = False  # p2pproxy plugin not configured

            headers = {'User-Agent': 'Magic Browser'}
            with requests.get(config.url,
                              headers=headers,
                              proxies=config.proxies,
                              stream=False,
                              timeout=30) as r:
                if r.encoding is None: r.encoding = 'utf-8'
                self.logger.info('TTV playlist %s downloaded' % config.url)
                pattern = requests.auth.re.compile(
                    r',(?P<name>.+) \((?P<group>.+)\)[\r\n]+(?P<url>[^\r\n]+)?'
                )
                for match in pattern.finditer(r.text,
                                              requests.auth.re.MULTILINE):
                    itemdict = match.groupdict()
                    name = itemdict.get('name')

                    itemdict['logo'] = self.logomap.get(
                        name,
                        'http://static.acestream.net/sites/acestream/img/ACE-logo.png'
                    )
                    itemdict['tvgid'] = self.epg_id.get(name, '')

                    url = itemdict['url']
                    if url.startswith(('acestream://', 'infohash://')) \
                          or (url.startswith(('http://','https://')) and url.endswith(('.acelive','.acestream','.acemedia'))):
                        self.channels[name] = url
                        itemdict['url'] = quote(name.encode('utf-8'),
                                                '') + '.ts'

                    self.playlist.addItem(itemdict)
                    m.update(name.encode('utf-8'))

                self.etag = '"' + m.hexdigest() + '"'
                self.logger.debug('Requested m3u playlist generated')

        except requests.exceptions.RequestException:
            self.logger.error("Can't download TTV playlist!")
            return False
        except:
            self.logger.error(traceback.format_exc())
            return False

        return True