248 lines
8.2 KiB
Python
Executable file
248 lines
8.2 KiB
Python
Executable file
#!/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()
|