<commit_before>from threading import Thread
import urllib2
import xml.dom.minidom
import base64
from datetime import datetime
import traceback
import logging
import time

from api_clients import api_client

class ListenerStat(Thread):
    def __init__(self, logger=None):
        Thread.__init__(self)
        self.api_client = api_client.AirtimeApiClient()
        if logger is None:
            self.logger = logging.getLogger()
        else:
            self.logger = logger

    def get_node_text(self, nodelist):
        rc = []
        for node in nodelist:
            if node.nodeType == node.TEXT_NODE:
                rc.append(node.data)
        return ''.join(rc)

    def get_stream_parameters(self):
        #[{"user":"", "password":"", "url":"", "port":""},{},{}]
        return self.api_client.get_stream_parameters()


    def get_stream_server_xml(self, ip, url, is_shoutcast=False):
        encoded = base64.b64encode("%(admin_user)s:%(admin_pass)s" % ip)

        header = {"Authorization":"Basic %s" % encoded}

        if is_shoutcast:
            #user agent is required for shoutcast auth, otherwise it returns 404.
            user_agent = "Mozilla/5.0 (Linux; rv:22.0) Gecko/20130405 Firefox/22.0"
            header["User-Agent"] = user_agent

        req = urllib2.Request(
            #assuming that the icecast stats path is /admin/stats.xml
            #need to fix this
            url=url,
            headers=header)

        f = urllib2.urlopen(req)
        document = f.read()
        return document


    def get_icecast_stats(self, ip):
        url = 'http://%(host)s:%(port)s/admin/stats.xml' % ip
        document = self.get_stream_server_xml(ip, url)
        dom = xml.dom.minidom.parseString(document)<commit_msg>Fixed listener stats thread hanging on network errors<commit_after>from threading import Thread
import urllib2
import xml.dom.minidom
import base64
from datetime import datetime
import traceback
import logging
import time

from api_clients import api_client

class ListenerStat(Thread):
    HTTP_REQUEST_TIMEOUT = 30 # 30 second HTTP request timeout

    def __init__(self, logger=None):
        Thread.__init__(self)
        self.api_client = api_client.AirtimeApiClient()
        if logger is None:
            self.logger = logging.getLogger()
        else:
            self.logger = logger

    def get_node_text(self, nodelist):
        rc = []
        for node in nodelist:
            if node.nodeType == node.TEXT_NODE:
                rc.append(node.data)
        return ''.join(rc)

    def get_stream_parameters(self):
        #[{"user":"", "password":"", "url":"", "port":""},{},{}]
        return self.api_client.get_stream_parameters()


    def get_stream_server_xml(self, ip, url, is_shoutcast=False):
        encoded = base64.b64encode("%(admin_user)s:%(admin_pass)s" % ip)

        header = {"Authorization":"Basic %s" % encoded}

        if is_shoutcast:
            #user agent is required for shoutcast auth, otherwise it returns 404.
            user_agent = "Mozilla/5.0 (Linux; rv:22.0) Gecko/20130405 Firefox/22.0"
            header["User-Agent"] = user_agent

        req = urllib2.Request(
            #assuming that the icecast stats path is /admin/stats.xml
            #need to fix this
            url=url,
            headers=header)

        f = urllib2.urlopen(req, timeout=ListenerStat.HTTP_REQUEST_TIMEOUT)
        document = f.read()
        return document


    def get_icecast_stats(self, ip):
        url = 'http://%(host)s:%(port)s/admin/stats.xml' % ip
        document = self.get_stream_server_xml(ip, url)
        dom = xml.dom.minidom.parseString(document)
{'fraction_non_alphanumeric': 0.11013938234490298, 'fraction_numerical': 0.01639792292976223, 'mean_word_length': 2.5328185328185326, 'pattern_counts': {'":': 10, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 12}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7535794', 'n_tokens_mistral': 1159, 'n_tokens_neox': 1088, 'n_words': 272}