2012-01-29 14:28:02 +00:00
|
|
|
# coding=utf-8
|
2012-04-09 02:19:39 +00:00
|
|
|
|
|
|
|
import http.client
|
2012-01-29 14:28:02 +00:00
|
|
|
import hashlib
|
2012-04-11 15:33:57 +00:00
|
|
|
import sys
|
2012-04-18 21:35:58 +00:00
|
|
|
import traceback
|
2012-05-14 15:50:11 +00:00
|
|
|
import socket
|
2012-01-29 14:28:02 +00:00
|
|
|
import time
|
2012-04-18 21:35:58 +00:00
|
|
|
import base64
|
2012-04-09 02:19:39 +00:00
|
|
|
import _thread
|
|
|
|
from urllib.parse import unquote
|
|
|
|
from xml.dom.minidom import parse
|
|
|
|
from xml.dom.minidom import parseString
|
|
|
|
from xml.dom.minidom import getDOMImplementation
|
|
|
|
|
|
|
|
import atom
|
2012-04-09 12:11:03 +00:00
|
|
|
import youtube
|
2012-04-09 02:19:39 +00:00
|
|
|
|
|
|
|
filename = ""
|
|
|
|
SITES = []
|
|
|
|
SRVS = None
|
|
|
|
|
2012-04-11 15:33:57 +00:00
|
|
|
class Site:
|
|
|
|
def __init__(self, item):
|
|
|
|
self.server = item.getAttribute("server")
|
|
|
|
self.page = item.getAttribute("page")
|
|
|
|
if item.getAttribute("type"):
|
|
|
|
self.type = item.getAttribute("type")
|
|
|
|
else:
|
|
|
|
self.type = "hash"
|
|
|
|
self.message = item.getAttribute("message")
|
|
|
|
|
|
|
|
self.thread = None
|
|
|
|
if item.getAttribute("time"):
|
|
|
|
self.updateTime = int(item.getAttribute("time"))
|
|
|
|
else:
|
|
|
|
self.updateTime = 60
|
|
|
|
self.lastChange = 0
|
2012-05-14 15:50:11 +00:00
|
|
|
self.lastpage = None
|
2012-04-18 21:35:58 +00:00
|
|
|
|
2012-04-11 15:33:57 +00:00
|
|
|
self.run = True
|
|
|
|
|
|
|
|
self.channels = list()
|
|
|
|
for channel in item.getElementsByTagName('channel'):
|
|
|
|
self.channels.append(channel.getAttribute("name"))
|
|
|
|
|
2012-05-18 09:38:50 +00:00
|
|
|
self.categories = dict()
|
|
|
|
for category in item.getElementsByTagName('category'):
|
|
|
|
self.categories[category.getAttribute("term")] = category.getAttribute("part")
|
|
|
|
|
2012-04-11 15:33:57 +00:00
|
|
|
|
|
|
|
def start (self):
|
|
|
|
self.thread = _thread.start_new_thread (startThread, (self,))
|
|
|
|
|
|
|
|
def send_message (self, msg):
|
|
|
|
global SRVS
|
|
|
|
if len(self.channels) > 0:
|
2012-05-14 15:50:11 +00:00
|
|
|
for server in SRVS.keys():
|
2012-04-11 15:33:57 +00:00
|
|
|
for chan in self.channels:
|
2012-05-14 15:50:11 +00:00
|
|
|
SRVS[server].send_msg (chan, msg)
|
2012-04-11 15:33:57 +00:00
|
|
|
else:
|
2012-05-14 15:50:11 +00:00
|
|
|
for server in SRVS.keys():
|
|
|
|
SRVS[server].send_global (msg)
|
2012-04-11 15:33:57 +00:00
|
|
|
|
|
|
|
def treat_atom (self, content):
|
|
|
|
change=False
|
|
|
|
f = atom.Atom (content)
|
|
|
|
if self.lastpage is not None:
|
|
|
|
diff = self.lastpage.diff (f)
|
|
|
|
if len(diff) > 0:
|
|
|
|
print ("[%s] Page differ!"%self.server)
|
2012-05-18 09:38:50 +00:00
|
|
|
diff.reverse()
|
|
|
|
for d in diff:
|
|
|
|
if self.message.count("%s") == 2 and len(self.categories) > 0:
|
|
|
|
if d.category is None or d.category not in self.categories:
|
|
|
|
messageI = self.message % (self.categories[""], "%s")
|
2012-04-11 15:33:57 +00:00
|
|
|
else:
|
2012-05-18 09:38:50 +00:00
|
|
|
messageI = self.message % (self.categories[d.category], "%s")
|
2012-04-11 15:33:57 +00:00
|
|
|
self.send_message (messageI % unquote (d.link))
|
2012-05-18 09:38:50 +00:00
|
|
|
elif self.message.count("%s") == 2:
|
|
|
|
if f.id == youtube.idAtom:
|
|
|
|
youtube.send_global (d.link2, self.message % (d.title, unquote (d.link)))
|
|
|
|
else:
|
|
|
|
self.send_message (self.message % (d.title, unquote (d.link)))
|
|
|
|
elif self.message.count("%s") == 1:
|
|
|
|
self.send_message(self.message % unquote (d.title))
|
|
|
|
else:
|
|
|
|
self.send_message(self.message)
|
2012-04-11 15:33:57 +00:00
|
|
|
change=True
|
|
|
|
return (f, change)
|
|
|
|
|
|
|
|
def check (self):
|
|
|
|
while self.run:
|
|
|
|
try:
|
2012-05-21 07:12:15 +00:00
|
|
|
#print ("Check %s/%s"%(self.server, self.page))
|
2012-04-11 15:33:57 +00:00
|
|
|
content = getPage(self.server, self.page)
|
2012-05-14 15:50:11 +00:00
|
|
|
if content is None:
|
|
|
|
return
|
2012-04-11 15:33:57 +00:00
|
|
|
|
|
|
|
if self.type == "atom":
|
|
|
|
(self.lastpage, change) = self.treat_atom (content)
|
|
|
|
if change:
|
|
|
|
if self.lastChange <= 0:
|
|
|
|
self.lastChange -= 1
|
|
|
|
else:
|
|
|
|
self.lastChange = 0
|
|
|
|
else:
|
|
|
|
self.lastChange += 1
|
|
|
|
else:
|
|
|
|
hash = hashlib.sha224(content).hexdigest()
|
|
|
|
if hash != self.lastpage:
|
|
|
|
if self.lastpage is not None:
|
2012-04-30 16:22:10 +00:00
|
|
|
self.send_message (self.message)
|
2012-04-11 15:33:57 +00:00
|
|
|
self.lastpage = hash
|
|
|
|
if self.lastChange <= 0:
|
|
|
|
self.lastChange -= 1
|
|
|
|
else:
|
|
|
|
self.lastChange = 0
|
|
|
|
else:
|
|
|
|
self.lastChange += 1
|
|
|
|
|
|
|
|
#Update check time intervalle
|
|
|
|
#TODO
|
|
|
|
|
|
|
|
if self.updateTime < 10:
|
|
|
|
self.updateTime = 10
|
|
|
|
if self.updateTime > 400:
|
|
|
|
self.updateTime = 400
|
|
|
|
|
|
|
|
time.sleep(self.updateTime)
|
|
|
|
except:
|
2012-04-18 21:35:58 +00:00
|
|
|
print ("Une erreur est survenue lors de la récupération de la page " + self.server + "/" + self.page)
|
|
|
|
exc_type, exc_value, exc_traceback = sys.exc_info()
|
2012-04-30 16:22:10 +00:00
|
|
|
traceback.print_exception(exc_type, exc_value, exc_traceback)
|
2012-04-18 21:35:58 +00:00
|
|
|
time.sleep(self.updateTime * 3)
|
2012-04-09 02:19:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def load_module(datas_path):
|
|
|
|
"""Load this module"""
|
|
|
|
global SITES, filename
|
|
|
|
SITES = []
|
|
|
|
filename = datas_path + "/watch.xml"
|
|
|
|
|
2012-04-11 15:33:57 +00:00
|
|
|
sys.stdout.write ("Loading watchsites ... ")
|
2012-04-09 02:19:39 +00:00
|
|
|
dom = parse(filename)
|
2012-04-11 15:33:57 +00:00
|
|
|
for item in dom.documentElement.getElementsByTagName("watch"):
|
|
|
|
SITES.append (Site (item))
|
2012-04-09 02:19:39 +00:00
|
|
|
print ("done (%d loaded)" % len(SITES))
|
2012-01-29 14:28:02 +00:00
|
|
|
|
2012-04-09 02:19:39 +00:00
|
|
|
|
|
|
|
def launch (servers):
|
|
|
|
global SRVS
|
|
|
|
SRVS = servers
|
|
|
|
for site in SITES:
|
2012-04-11 15:33:57 +00:00
|
|
|
site.start ()
|
2012-05-14 15:50:11 +00:00
|
|
|
def stop():
|
|
|
|
return
|
2012-04-09 02:19:39 +00:00
|
|
|
|
2012-04-11 15:33:57 +00:00
|
|
|
def save_module():
|
|
|
|
"""Save the module state"""
|
|
|
|
global filename
|
|
|
|
sys.stdout.write ("Saving watched sites ... ")
|
|
|
|
impl = getDOMImplementation()
|
|
|
|
newdoc = impl.createDocument(None, 'service', None)
|
|
|
|
top = newdoc.documentElement
|
2012-04-09 02:19:39 +00:00
|
|
|
|
2012-04-11 15:33:57 +00:00
|
|
|
for site in SITES:
|
|
|
|
item = parseString ('<watch server="%s" page="%s" message="%s" type="%s" time="%d" />' % (site.server, site.page, site.message, site.type, site.updateTime)).documentElement
|
|
|
|
if len(site.channels) > 0:
|
|
|
|
for chan in site.channels:
|
|
|
|
item.appendChild(parseString ('<channel name="%s" />' % (chan)).documentElement);
|
2012-05-18 09:38:50 +00:00
|
|
|
if len(site.categories) > 0:
|
|
|
|
for categ in site.categories.keys():
|
|
|
|
item.appendChild(parseString ('<category term="%s" part="%s"/>' % (categ, site.categories[categ])).documentElement);
|
2012-04-30 16:22:10 +00:00
|
|
|
#print (site.server)
|
2012-04-11 15:33:57 +00:00
|
|
|
top.appendChild(item);
|
2012-04-09 02:19:39 +00:00
|
|
|
|
2012-04-11 15:33:57 +00:00
|
|
|
with open(filename, "w") as f:
|
|
|
|
newdoc.writexml (f)
|
|
|
|
print ("done")
|
2012-01-29 14:28:02 +00:00
|
|
|
|
|
|
|
|
2012-04-11 15:33:57 +00:00
|
|
|
def help_tiny ():
|
|
|
|
"""Line inserted in the response to the command !help"""
|
2012-04-18 21:35:58 +00:00
|
|
|
return "Alert on changes on websites"
|
2012-01-29 14:28:02 +00:00
|
|
|
|
2012-04-11 15:33:57 +00:00
|
|
|
def help_full ():
|
2012-04-18 21:35:58 +00:00
|
|
|
return "This module is autonomous you can't interract with it."
|
2012-04-09 02:19:39 +00:00
|
|
|
|
2012-04-11 15:33:57 +00:00
|
|
|
def parseanswer (msg):
|
|
|
|
if msg.cmd[0] == "watch":
|
|
|
|
print ("print states here")
|
|
|
|
return True
|
|
|
|
return False
|
2012-04-09 02:19:39 +00:00
|
|
|
|
2012-04-11 15:33:57 +00:00
|
|
|
def parseask (msg):
|
|
|
|
return False
|
2012-04-09 02:19:39 +00:00
|
|
|
|
2012-04-11 15:33:57 +00:00
|
|
|
def parselisten (msg):
|
|
|
|
return False
|
2012-04-09 02:19:39 +00:00
|
|
|
|
2012-04-11 15:33:57 +00:00
|
|
|
|
|
|
|
def getPage (s, p):
|
|
|
|
conn = http.client.HTTPConnection(s)
|
2012-05-14 15:50:11 +00:00
|
|
|
try:
|
|
|
|
conn.request("GET", "/%s"%(p))
|
|
|
|
except socket.gaierror:
|
|
|
|
print ("[%s] impossible de récupérer la page %s."%(s, p))
|
|
|
|
return None
|
2012-04-11 15:33:57 +00:00
|
|
|
|
|
|
|
res = conn.getresponse()
|
|
|
|
data = res.read()
|
|
|
|
|
|
|
|
conn.close()
|
|
|
|
return data
|
|
|
|
|
|
|
|
def startThread(site):
|
|
|
|
site.check ()
|