#!/usr/bin/env python

import sys,os
import socket
import string
import time
import commands
import feedparser
import getopt

def usage():
    print 'coucou\n'
    print 'a list of useful feeds : ' + '\n'
    print 'http://www.lemonde.fr/rss/une.xml' + '\n'
    print 'http://linuxfr.org/backend/news-homepage/rss20.rss' + '\n'
    print 'http://www.my-meteo.fr/meteo+rss+paris.html' + '\n'
    print 'http://partner-meteo.com/api/api/rss_simple.php?id=29591' + '\n'
    print 'http://feeds2.feedburner.com/failblog' + '\n'
    print 'http://xkcd.com/rss.xml' + '\n'
    print 'http://www.liberation.fr/rss/laune' + '\n'
    print 'http://rss.slashdot.org/Slashdot/slashdot' + '\n'
    print '\n'
    print 'options -n --nick= : nickname\n'
    print 'options --feedurl= the url of the feed\n'
    print 'options --dontcheckfeed don\'t check if the feed has already been sent\n'
    print 'options --command= the command to run\n'
    print 'options --chan= the channel to join (don\'t put the #)\n'
    print 'look at the source the author forget to document some options'
    
def checklock():
    try:
        lock=open("/tmp/botirclock",'r')
        pid=int(lock.read())
        lock.close()
        if os.path.exists("/proc/"+str(pid)):
            print 'Locked by ' + str(pid) + '\n'
            return 1
        else:
            print 'Locked by ' + str(pid) + ' but the bot died\n'
            return 0
    except:
        return 0
    return 0

def makelock():
    pid=os.getpid()
    print 'We write ' + str(pid)+' in the lock \n'
    lock=open("/tmp/botirclock",'w')
    lock.write(str(pid)+'\n')
    lock.close()

def releaselock():
    print 'We relase the lock .............'
    lock=open("/tmp/botirclock",'w')
    lock.close()
    

def main():
    #default values
    HOST='irc.crans.org' #The server we want to connect to
    PORT=6667 #The connection port which is usually 6667
    NICK='braicebot' #The bot's nickname
    IDENT='braicebot'
    REALNAME='4242'
    CHANNELINIT='#flood' #The default channel for the bot
    sendfeed=0
    sendcommand=0
    dontcheckfeed=0
    nofeedurl=0
    nolock=0
    numfeedentries=1
    longsumary=0
    linelen=120
    #command_to_send='tail /var/log/messages'
    #command_to_send='cat ' + sys.argv[0]


    

    try:
        opts, args = getopt.getopt(sys.argv[1:], "hn:v", ["help", "dontcheckfeed", "nofeedurl", "nick=", "feedurl=", "command=", "chan=", "numfeeds=","longdesc", "nolock"])
    except getopt.GetoptError, err:
        # print help information and exit:
        print str(err) # will print something like "option -a not recognized"
        usage()
        sys.exit(2)
    output = None
    verbose = False
    for o, a in opts:
        if o == "-v":
            verbose = True
        elif o in ("-h", "--help"):
            usage()
            sys.exit()
        elif o in ("-n", "--nick"):
            NICK = a
        elif o == "--feedurl":
            feedurl = a
            sendfeed=1
        elif o == "--numfeeds":
            numfeedentries = int(a)
        elif o == "--dontcheckfeed":
            dontcheckfeed=1
        elif o == "--nofeedurl":
            nofeedurl=1
        elif o == "--nolock":
            nolock=1
        elif o == "--command":
            command_to_send = a
            sendcommand=1
        elif o == "--chan":
            CHANNELINIT = '#' + a
        else:
            assert False, "unhandled option"



    if sendcommand:
        print 'We execute the command ...'
        fortune=commands.getoutput(command_to_send)
    elif sendfeed:
        feed = feedparser.parse(feedurl)
        if numfeedentries==1 and not dontcheckfeed: #we check if it was updated
            hashurl=abs(hash(feedurl))
            try:
                lastupdate=time.mktime(feed["items"][0]["updated_parsed"])
            except:
                sys.exit(0)
            lastupdatesent=0
            alreadysent=0
            try:
                filedate=open('/tmp/botirc'+str(hashurl),'r')
                for line in filedate.readlines():
                    if len(line)>2:
                        lastupdatesent=float(line)
                        if lastupdatesent == lastupdate :
                            alreadysent=1
                filedate.close()
            except:
                print 'Cannot open ' + '/tmp/botirc'+str(hashurl) + '\n'
            if alreadysent:
                print 'Feed already sent\n'
                sys.exit(0)            
        if nofeedurl:
            fortune =""
        else:
            fortune="latest entry from " + feedurl +'\n'
        for feednum in range(0,numfeedentries):
            fortune+='title : ' + feed["items"][feednum]['title'] + '\n' + 'link : ' +  feed["items"][feednum]['link'] +'\n' 
            oldline=""
            for line in feed["items"][feednum]['summary'].split('\n'):#.split('<brfinallynotagoodideatodolikethat'): #TODO : parse the BR in a MUCH cleaner way
                if len(line)>linelen:
                    print 'line splitting'
                    j=0#We cut the line where spaces are #TODO : make a function
                    while j<len(line):
                        index=line.rfind(' ',j,j+linelen)
                        if index==-1:
                            index=linelen+j
                        fortune +=  line[j:index] +'\n'
                        #print line[j:index]
                        j=index
                        if j<len(line) and line[j]==' ':
                            j+=1
                else:
                    fortune +=  line +'\n'

    else :
        print 'You have to specify a feed or a command\n'
        usage()
        sys.exit(0)

    if not nolock:
        if checklock():
            print 'Another bot is running ...'
            sys.exit(0)
        makelock()


    s=socket.socket( ) #Create the socket
    s.connect((HOST, PORT)) #Connect to server
    s.send('NICK '+NICK+'\n') #Send the nick to server
    s.send('USER '+IDENT+' '+HOST+' bla :'+REALNAME+'\n') #Identify to server 

    s.settimeout(0.5)
    hourjoined=0
    hourbye=0
    delaybeforemessage=1
    delaybye=5
    sleepbetweenlines=0.2
    sleeppercharacter=0.04
    buffer=""
    while 1:
        while 1:
            try:
                buffer=buffer+s.recv(500) #recieve server messages
                time.sleep(0.1)
            except:
                time.sleep(0.1)
                break
        if len(buffer):
            for line in buffer.split('\n'):
                print line
                code=0
                try:
                    if line.find(':'+HOST)==0:
                        code=int(line.split(' ')[1])
                except:
                    print line
                    print "Oups"
                    if not nolock:
                        releaselock()
                    sys.exit(1)
                if code >= 400 and code<>412: #412 : no text to send, we don't care
                    print "The server is not happy"
                    if not nolock:
                        releaselock()
                    sys.exit(1)
            #print buffer #server message is output
            if buffer.find('Welcome')!=-1:
                s.send('JOIN '+CHANNELINIT+'\n') #Join a channel
                hourjoined=time.time()
                print 'Message in ' + str(delaybeforemessage) +'seconds \n'
            buffer=""
            
        if hourjoined and not hourbye:
            if (time.time()-hourjoined)>delaybeforemessage:
                for line in fortune.split('\n'):
                    message='PRIVMSG '+CHANNELINIT+' :' + line + '\n'
                    time.sleep(sleepbetweenlines)
                    s.send(message.encode("utf-8"))
                    print message.encode("utf-8")
                    time.sleep(sleeppercharacter*len(message)) #to avoid kick by flood
                print 'Bye in ' + str(delaybye) +'seconds \n'
                hourbye=time.time()
        if hourbye and (time.time()-hourbye)>delaybye:
            break

    s.close()
    if sendfeed and numfeedentries==1 and not dontcheckfeed: #we check if it was updated
        filedate=open('/tmp/botirc'+str(hashurl),'a')
        print 'we write ' + '/tmp/botirc'+str(hashurl) + '\n'
        filedate.write(str(float(lastupdate))+'\n\n')
        filedate.close()
    if not nolock:
        releaselock()

if __name__ == "__main__":
    main()
