#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
A modular python bot based on the twisted matrix irc library

@author Riku 'Shrike' Lindblad (shrike@addiktit.net)
@copyright Copyright (c) 2006 Riku Lindblad
@license New-Style BSD
"""

import re
import sys
import os.path
import time
import urllib
import fnmatch
import HTMLParser
import logging
import logging.handlers

try:
    import psyco
    psyco.full()
except ImportError:
    print "Psyco not found, running unoptimized"

try:
    import yaml
except ImportError:
    print "PyYAML not found, please install from http://pyyaml.org/wiki/PyYAML"
    sys.exit(1)

# twisted imports
try:
    from twisted.words.protocols import irc
    from twisted.internet import reactor, protocol, threads, defer
    from twisted.python import rebuild
except ImportError:
    print "Twisted library not found, please install Twisted from http://twistedmatrix.com/products/download"
    sys.exit(1)

from util import *
from util.BeautifulSoup import BeautifulSoup
from util.BeautifulSoup import UnicodeDammit

# default timeout for socket connections
import socket
socket.setdefaulttimeout(20)

import botcore

log = logging.getLogger('core')


class URLCacheItem(object):
    """URL cache item object, fetches data only when needed"""
    
    def __init__(self, url):
        self.url = url
        self.content = None
        self.headers = None
        self.bs = None
        # maximum size in kB to download
        self.max_size = 2048
        self.fp = None

    def _open(self, url):
        """Returns the raw file pointer to the given URL"""
        if not self.fp:
            urllib._urlopener = BotURLOpener()
            try:
                self.fp = urllib.urlopen(self.url)
            except IOError, e:
                log.warn("IOError when opening url %s" % url)
        return self.fp

    def _checkstatus(self):
        """Check if all data has already been cached and close socket if so"""
        
        if self.content and \
           self.headers and \
           self.bs:
            self.fp.close()

    def getSize(self):
        """Get the content length of URL in kB

        @return None if the server doesn't return a content-length header"""
        if self.getHeaders().has_key('content-length'):
            length = int(self.getHeaders()['content-length'])/1024
            return length
        else:
            return None

    def getContent(self):
        """Get the actual file at the URL

        @return None if the file is too large (over 2MB)"""
        if not self.content: