'''
Created on Jan 24, 2014

@author: Tyranic-Moron
'''

from IRCMessage import IRCMessage
from IRCResponse import IRCResponse, ResponseType
from Function import Function
import WebUtils

import re
import urllib, urllib2
from bs4 import BeautifulSoup
from twisted.words.protocols.irc import assembleFormattedText, attributes as A

class Instantiate(Function):
    Help = "urban <search term> - returns the definition of the given search term from UrbanDictionary.com"
    
    def GetResponse(self, message):
        if message.Type != 'PRIVMSG':
            return
        
        match = re.search('^(urban|ud)$', message.Command, re.IGNORECASE)
        if not match:
            return
        
        if len(message.ParameterList) == 0:
            return IRCResponse(ResponseType.Say, "You didn't give a word! Usage: {0}".format(self.Help), message.ReplyTo)
        
        search = urllib.quote(message.Parameters)

        url = 'http://www.urbandictionary.com/define.php?term={0}'.format(search)
        
        webPage = WebUtils.FetchURL(url)

        soup = BeautifulSoup(webPage.Page)

        box = soup.find('div', {'class' : 'box'})

        if not box:
            return IRCResponse(ResponseType.Say, "No entry found for '{0}'".format(search), message.ReplyTo)

        graySplitter = assembleFormattedText(A.normal[' ', A.fg.gray['|'], ' '])

        word = box.find('div', {'class' : 'word'}).text.strip()
        # 2014-01-28 really, urban dictionary? 'definition' to 'meaning'? what an important change!
        definition = graySplitter.join(box.find('div', {'class' : 'meaning'}).stripped_strings)
        example = graySplitter.join(box.find('div', {'class' : 'example'}).stripped_strings)
        author = box.find('div', {'class' : 'contributor'}).text.strip().replace('\n', ' ')
        counts = box.find('div', {'class' : 'thumbs-counts'}).find_all('span', {'class' : 'count'})
        up = counts[0].text
        down = counts[1].text

        if word.lower() != message.Parameters.lower():
            word = "Contains '{0}'".format(word)

        formatString = assembleFormattedText(
                           A.normal[A.bold["{0}:"], " {1}\n",
                                    A.bold["Example(s):"], " {2}\n",
                                    "{3}", graySplitter,
                                    A.fg.lightGreen["+{4}"], "/", A.fg.lightRed["-{5}"], graySplitter, "More defs: {6}"])

        response = formatString.format(word, definition, example, author, up, down, url)
        
        return IRCResponse(ResponseType.Say, response, message.ReplyTo)

@@ -1093,16 +1093,113 @@
 ge.Page)
+%0A        # replace link tags with their contents%0A        %5Ba.unwrap() for a in soup.find_all('a')%5D
 %0A%0A      
@@ -1371,16 +1371,83 @@
 ReplyTo)
+%0A        %0A        print box.find('div', %7B'class' : 'meaning'%7D).text
 %0A%0A      
@@ -1586,16 +1586,17 @@
 strip()%0A
+%0A
         
@@ -1708,34 +1708,16 @@
 ition = 
-graySplitter.join(
 box.find
@@ -1750,119 +1750,415 @@
 g'%7D)
-.stripped_strings)%0A        example = graySplitter.join(box.find('div', %7B'class' : 'example'%7D).stripped_strings)
+%0A        if definition.br is not None:%0A            definition.br.replace_with('%5Cn')%0A        definition = graySplitter.join(%5Bs.strip() for s in definition.text.strip().split('%5Cn')%5D)%0A%0A        example = box.find('div', %7B'class' : 'example'%7D)%0A        if example.br is not None:%0A            example.br.replace_with('%5Cn')%0A        example = graySplitter.join(%5Bs.strip() for s in example.text.strip().split('%5Cn')%5D)%0A
 %0A   
@@ -2246,16 +2246,17 @@
 ', ' ')%0A
+%0A
         
@@ -2481,16 +2481,21 @@
 word = %22
+%7B0%7D (
 Contains
@@ -2496,24 +2496,25 @@
 ntains '%7B0%7D'
+)
 %22.format(wor
@@ -2514,16 +2514,36 @@
 mat(word
+, message.Parameters
 )%0A%0A     
@@ -2836,11 +2836,22 @@
 %22%5D, 
+A.fg.gray%5B
 %22/%22
+%5D
 , A.

Replace links with text in def and example