Commit 80cfaf6a authored by Mindiell's avatar Mindiell

more conversion done

parent acbc8f15
......@@ -10,3 +10,7 @@ password = '',
channels = [
'#testchannel'
]
dbuser = "root"
dbpassword = ""
dbserver = "localhost"
dbname = "db"
......@@ -9,7 +9,7 @@ from twisted.words.protocols import irc
class IrcClient(irc.IRCClient):
def __init__(self, config):
self.config = config
self.nickname = "TestMan"
self.nickname = config.nickname
self.password = config.password
def connectionMade(self):
......
......@@ -5,24 +5,53 @@ Il les recharge à chaque fois qu'on lui fournit la commande '!reload' sur IRC.
"""
messages = {
"hello": """Bonjour, je suis le bot de la Quadrature du Net, vous pouvez me demander de l'aide si besoin. (wantzel help)""",
"hello":
"""Bonjour, je suis le bot de la Quadrature du Net, vous pouvez me demander de l'aide si besoin. (wantzel help)""",
"help": """Toute l'aide se trouve ici : https://wiki.laquadrature.net/Wantzel""",
"help":
"""Mes commandes sont : !help !rp(cpa) !kill !stats.
Pour plus d'informations, voir ici: https://wiki.laquadrature.net/Wantzel
Pour obtenir de l'aide sur une commande en particulier, il suffit de taper !help <commande>""",
"help_rp": """""",
"help_help":
"""Bravo!
Tu viens d'entrer dans le monde récursif où l'aide sert à expliciter l'aide.""",
"help_stats": """""",
"help_rp":
"""Cette commande sert à ajouter un article à la Revue de Presse (https://wiki.laquadrature.net/Revue_de_presse)
L'utilisation se fait sous la forme: !rp <url de l'article à ajouter>""",
#Plusieurs options sont possibles et cumulables: a, c, p
#l'option a => !rpa permet d'archiver un article (il ne sera pas ajouté à la Revue de Presse""",
"help_quote": """""",
"help_stats":
"""Cette commande permet de fournir quelques statistiques sur la Revue de Presse (https://wiki.laquadrature.net/Revue_de_presse)
Les statistiques sont calculées sur des notes supérieurs ou égales à 0, 3, et 4. Et sur les 1, 3, 7, et 15 derniers jours.""",
"help_tc": """""",
"help_kill":
"""Fixe la note de l'article donné en paramètre à -100.
Utile en cas d'erreur ou pour s'assurer que l'article ne sera pas publié dans la RP
Utilisation: !kill <url de l'article>
*Attention* seuls les vrais rp-jedis ont accès à cette commande <3""",
"help_kill": """""",
"rp_http":
"""Merci %s, mais je prends en compte uniquement les adresses internet qui commencent par http ou https""",
"merci_nouvel_article": """Merci %s, cette url a été ajoutée à la revue de presse ! À présent, que dirais-tu d'aider à choisir les extraits de l'article à publier sur #lqdn-rp ? <3""",
"rp_new_article":
"""Merci %s, cette url a été ajoutée à la revue de presse ! À présent, que dirais-tu d'aider à choisir les extraits de l'article à publier sur #lqdn-rp ? <3""",
"merci_article_connu": """Merci %s! Un point a été ajouté à cet article : à partir de 3, il pourra être repris dans la revue de presse. D'ailleurs, que dirais-tu d'aider à choisir les extraits à publier sur #lqdn-rp ? <3""",
"rp_known_article":
"""Merci %s! Un point a été ajouté à cet article : à partir de 3, il pourra être repris dans la revue de presse. D'ailleurs, que dirais-tu d'aider à choisir les extraits à publier sur #lqdn-rp ? <3""",
"merci_article_repris": """Merci %s! Un point a été ajouté à cet article : il va être repris dans la revue de presse. D'ailleurs, que dirais-tu d'aider à choisir les extraits à publier sur #lqdn-rp ? <3""",
"rp_taken_article":
"""Merci %s! Un point a été ajouté à cet article : il va être repris dans la revue de presse. D'ailleurs, que dirais-tu d'aider à choisir les extraits à publier sur #lqdn-rp ? <3""",
"kill_none":
"""%s n'existe pas dans la base de données""",
"kill_done":
"""%s mit à -100""",
"stats_bravo":
"""Bravo les neurones, rien en retard depuis ces %s derniers jours!""",
}
#encoding: utf-8
"""
Bot Wantzel de La Quadrature du Net
Bot Wantzel from La Quadrature du Net.
Pour utiliser l'accès à une base de données MySQL :
- apt-get install libmysqlclient-dev
- pip install mysql-python
License : AGPLv3
Doc : https://wiki.laquadrature.net/Wantzel
TODO:
- Ajouter la gestion des droits pour certaines commandes
- Mettre une valeur par défaut pour les champs concernés
- Afficher les titres des urls fournies sur le canal
"""
from irc import IrcClientFactory
import json
import MySQLdb
import re
from twisted.internet import reactor
......@@ -17,6 +20,41 @@ import urllib
import config
from messages import messages
def get_cursor():
"""
This function connects to a database and returns a usable cursor.
"""
db = MySQLdb.connect(
host=config.dbserver,
user=config.dbuser,
passwd=config.dbpassword,
db=config.dbname
)
if db:
return db.cursor()
return None
def get_url(message, command=""):
"""
Retrieve the url behind the command.
"""
# Let's get what is behind the command
result = re.search("!%s ([^ ]*)" % command, message)
if not result:
return ""
url = result.group(1)
# Verify the presence of http
result = re.search("^(https?://)(.+)$", url)
if not result:
return "http"
# Removing anchor if needed
result = re.search("^([^#]*)", url)
if result:
url = result.group(1)
# Removing trackers
url = re.sub("[?&](utm_medium|utm_source|utm_campaign|xtor)=[^&]*", "", url)
return url
class Wantzel(object):
"""
Wantzel bot.
......@@ -35,18 +73,6 @@ class Wantzel(object):
"""
self.irc.client.privmsg = self.on_privmsg
self.irc.client.joined = self.on_joined
#self.irc.client.left = self.on_left
#self.irc.client.noticed = self.on_noticed
#self.irc.client.modeChanged = self.on_mode_changed
#self.irc.client.kickedFrom = self.on_kicked_from
#self.irc.client.nickChanged = self.on_nick_changed
#self.irc.client.userJoined = self.on_user_joined
#self.irc.client.userLeft = self.on_user_left
#self.irc.client.userQuit = self.on_user_quit
#self.irc.client.userKicked = self.on_user_kicked
#self.irc.client.action = self.on_action
#self.irc.client.topicUpdated = self.on_topic_updated
#self.irc.client.userRenamed = self.on_user_renamed
def send_message(self, channel, messages):
"""
......@@ -63,44 +89,47 @@ class Wantzel(object):
If a command is passed after help, the message explains how to use
the command.
- rp(acp)
Add an article in the database
- stats
- quote
- tc
Show some statistics about the RP
- kill
Kill an article by giving it a score of -100
"""
# Cleaning user name
user = re.search("([^!]*)!", user).group(1)
print("Message reçu: %s %s %s" % (user, channel, msg))
# Help command, specific
if "wantzel" in msg and ("help" in msg or "aide" in msg):
self.help(user, channel, msg)
# Find command with parameters
command = re.search("!(rp[acp]*|quote|tc|kill) ", msg)
if not command:
# Find command without parameters
command = re.search("^!(help|stats)$", msg)
if command:
print("Commande reçue: %s" % command.group(1))
command = command.group(1)
if command.startswith("rp"):
self.rp(command, user, channel, msg)
elif command=="help":
user = re.search("([^!]*)!", user).group(1)
print("Message received: %s %s %s" % (user, channel, msg))
# Never answer to botself
if user!=config.nickname:
# If it's a query, bot should answer to the user as the channel
if "#" not in channel:
channel = user
# Help command, specific
if "wantzel" in msg and ("help" in msg or "aide" in msg):
self.help(user, channel, msg)
elif command=="kill":
self.kill(user, channel, msg)
elif command=="stats":
self.stats(user, channel, msg)
elif command=="quote":
self.quote(user, channel, msg)
elif command=="tc":
self.tc(user, channel, msg)
# Find known command
command = re.search("!(rp[acp]*|kill|help|stats)", msg)
if command:
command = command.group(1)
print("Command: %s" % command)
if command.startswith("rp"):
self.rp(command, user, channel, msg)
elif command=="help":
self.help(user, channel, msg)
elif command=="kill":
self.kill(user, channel, msg)
elif command=="stats":
self.stats(user, channel, msg)
def on_joined(self, channel):
"""
Say hello to everyone.
"""
print("Canal %s rejoint" % channel)
self.send_message("#mytipy", messages["hello"])
print("Joined channel %s" % channel)
# Specific message for specific channel
if "hello_"+channel[1:] in messages:
self.send_message(channel, messages["hello_"+channel[1:]])
else:
self.send_message(channel, messages["hello"])
def help(self, user, channel, msg):
"""
......@@ -109,7 +138,13 @@ class Wantzel(object):
returned.
"""
print("help command")
self.send_message(channel, messages["help"])
# Searching for a command after help keyword
command = re.search("!help (stats|rp|help|kill)", msg)
if command:
command = command.group(1)
self.send_message(user, messages["help_"+command])
else:
self.send_message(channel, messages["help"])
def rp(self, command, user, channel, msg):
"""
......@@ -118,19 +153,16 @@ class Wantzel(object):
print("rp command %s" % command)
cite = 0
note = 0
# On récupère tout ce qui suit la commande !rp
url = re.search("!rp (.*)", msg).group(1)
# On nettoie tout ce qui est http
url = re.search("(https?://)?(.*)", url).group(2)
# On vire l'ancre si elle existe
url = re.search("([^#]*)", url).group(0)
# On se débarasse des trackers
url = re.sub("", "", url)
url = get_url(msg, command)
print("url: %s" % url)
if url=="":
return
elif url=="http":
self.send_message(channel, messages["rp_http"] % user)
return
# On vérifie ensuite l'existence de l'url dans la base de données
db = MySQLdb.connect(host="localhost", user="root", passwd="root", db="site")
cursor = db.cursor()
# Looking for such an article in database
cursor = get_cursor()
cursor.execute("SELECT id, note, provenance FROM presse WHERE url = %s", (url, ))
rows = cursor.fetchall()
if not rows:
......@@ -144,29 +176,47 @@ class Wantzel(object):
if "a" in command:
note -= 2
#TODO: Gérer les autres champs qui n'ont pas de valeur par défaut
# lang, published, nid, screenshot, title, fetched, seemscite
print("Adding an article by %s: %s" % (user, url))
result = cursor.execute(
"INSERT INTO presse SET url=%s, provenance=%s, cite=%s, note=%s, datec=NOW()",
(url, user, cite, note)
)
self.send_message(channel, messages["merci_nouvel_article"] % user)
self.send_message(channel, messages["rp_new_article"] % user)
else:
print("Ajout d'un point par %s sur %s" % (rows[0][2], rows[0][0]))
if rows[0][2]!=user:
print("Adding a point by %s on %s" % (user, rows[0][0]))
result = cursor.execute(
"UPDATE presse SET note=note+1 WHERE id=%s",
(rows[0][0], )
)
if (rows[0][1]+1)<3:
self.send_message(channel, messages["merci_article_connu"] % user)
self.send_message(channel, messages["rp_known_article"] % user)
else:
self.send_message(channel, messages["merci_article_repris"] % user)
self.send_message(channel, messages["rp_taken_article"] % user)
def kill(self, user, channel, msg):
"""
Kill an article by removing 100 points to its score.
Kill an article by setting its score to -100.
"""
#TODO: Gérer les droits de cette commande
print("kill command")
pass
url = get_url(msg, "kill")
print("url: %s" % url)
if url=="":
return
elif url=="http":
self.send_message(channel, messages["rp_http"] % user)
return
# Looking for such an article in database
cursor = get_cursor()
cursor.execute("SELECT id, note FROM presse WHERE url=%s", (url, ))
rows = cursor.fetchall()
if not rows:
self.send_message(channel, messages["kill_none"] % url)
else:
cursor.execute("UPDATE presse SET note=-100 WHERE id=%s", (rows[0][0], ))
self.send_message(channel, messages["kill_done"] % url)
def stats(self, user, channel, msg):
"""
......@@ -182,7 +232,7 @@ class Wantzel(object):
result = ""
for note in notes:
notnull = 0
result = result + " note: %s => " % note
result = result + "note>=%s: " % note
for period in periods:
cursor.execute(
"""SELECT COUNT(id) AS cid FROM presse
......@@ -195,29 +245,14 @@ class Wantzel(object):
if rows[0][0]>0:
result = result + "%sj:%s, " % (period, rows[0][0])
notnull = 1
somethingatall=1
somethingatall = 1
if notnull:
result = result[:-2] + "\n"
if not somethingatall:
#TODO: Bravo!
result = "Bravo!"
if somethingatall==0:
result = messages["stats_bravo"] % periods[-1]
self.send_message(channel, result)
def quote(self, user, channel, msg):
"""
Record a quote of a VIP during debates.
"""
print("quote command")
pass
def tc(self, user, channel, msg):
"""
Timecode...
"""
print("tc command")
pass
if __name__ == '__main__':
wantzel = Wantzel()
reactor.run()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment