Exemplo n.º 1
0
    def _serve_metadata(self, parsed_url, parsed_query, user, password):
        try:
            mount = parsed_query['mount'][0]
        except (KeyError, IndexError):
            mount = ''
        for path in manager.lookup_destination(mount):
            client = MetadataTuple(
                user,
                path.source,
                path.host,
                path.port,
                path.mount
            )

            logger.debug("Serving metadata for %s", client)
            song = parsed_query.get('song', None)
            artist = parsed_query.get('artist', None)
            title = parsed_query.get('title', None)
            encoding = parsed_query.get('charset', ['latin1'])
            if not song is None:
                metadata = fix_encoding(song[0], encoding[0])
                manager.send_metadata(
                    metadata=metadata,
                    client=client)
            elif title and artist:
                metadata = fix_encoding(
                    "%s - %s" % (artist[0], title[0]),
                    encoding[0])
                manager.send_metadata(
                    metadata=metadata,
                    client=client)

        # Send a response... although most clients just ignore this.
        try:
            self.send_response(200)
            self.send_header("Content-Type", "text/xml")
            self.send_header("Content-Length", "113")
            self.end_headers()

            self.wfile.write(
                '<?xml version="1.0"?>\n<iceresponse>'
                '<message>Metadata update successful</message>'
                '<return>1</return></iceresponse>')
        except IOError as err:
            if hasattr(err, 'errno') and err.errno == 32:
                #logger.warning("Broken pipe exception, ignoring")
                pass
            else:
                logger.exception("Error in request handler")
Exemplo n.º 2
0
    def do_SOURCE(self):
        global manager, sockets

        self.useragent = self.headers.get('User-Agent', None)
        self.mount = self.path  # oh so simple
        self.stream_name = self.headers.get('ice-name', '<Unknown>')
        self.source_content = self.headers.get('Content-type', None)
        fmt = re.search("(mpeg|ogg|flac)", self.source_content).groups()[0]

        ice_audio_info = urlparse.parse_qs(
            self.headers.get('ice-audio-info', '')
        )
        self.source_bitrate = self.headers.get(
            'ice-bitrate',
            "".join(ice_audio_info.get('bitrate', ['128'])))

        user, password = self._get_login()
        if user == 'source' and "|" in password:
            user, password = password.split('|')
        auth = self.login(user=user, password=password)
        if auth:
            logger.info("source: User '%s' logged in correctly.", user)
            self.send_response(200)
            self.end_headers()
        else:
            logger.info("source: User '%s' failed to login from %s.",
                        user, str(self.client_address))
            self.send_response(401)
            self.end_headers()
            return

        icy_client = []
        logger.debug('lookup for source mountpoint %s' % self.mount)
        for path in manager.lookup_destination(self.mount):
            icy_client.append(
                IcyClient(
                    path.host,
                    path.port,
                    path.source,
                    path.mount,
                    user=auth,
                    password=path.password,
                    useragent=self.useragent,
                    stream_name=self.stream_name,
                    informat=fmt,
                    outformat=path.format,
                    protocol=path.protocol,
                    name=path.name,
                    inbitrate=self.source_bitrate,
                    outbitrate=path.bitrate or self.source_bitrate
                )
            )
            try:
                manager.register_source(icy_client[-1])
            except Exception as err:
                logger.error(err)
                icy_client.pop()
                continue
        logger.debug(
            'registered %d mountpoints destinations'
            % len(icy_client))
        sockets.add(self.rfile)
        try:
            retries = 0
            while self.rfile and retries < 10:
                rlist, wlist, xlist = select([self.rfile], [], [], 1)
                if not len(rlist):
                    retries = retries + 1
                    continue
                retries = 0
                data = self.rfile.read(8192)
                if data == b'':
                    break
                for client in icy_client:
                    if client.is_active:
                        client.write(data)
                    else:
                        icy_client.remove(client)
                if not len(icy_client):
                    logger.debug("Thread exiting since no more clients are active")
                    break

        except:
            logger.exception("Timeout occured (most likely)")
        logger.info("source: User '%s' logged off.", user)
        if self.rfile:
            self.rfile.close()
        sockets.remove(self.rfile)
        while len(icy_client):
            client = icy_client.pop()
            manager.remove_source(client)