Compare commits
23 Commits
803b266e09
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
04475f8158 | ||
|
|
85b059702f | ||
|
|
aa1813533e | ||
|
|
d66213275f | ||
|
|
2b73d5b251 | ||
|
|
53dd903886 | ||
|
|
37e239a252 | ||
|
|
82426e7c69 | ||
|
|
6cdde8dfce | ||
|
|
d02eee7340 | ||
|
|
bdc2a516d6 | ||
|
|
014da4fc29 | ||
|
|
41a99facd6 | ||
|
|
d4dbb6a99f | ||
|
|
5e5c81fd8b | ||
|
|
949607a96e | ||
|
|
b1ae69ebfa | ||
|
|
f98f3429d8 | ||
|
|
0e7800ab7d | ||
|
|
96786dc28c | ||
|
|
d595c4d1d6 | ||
|
|
2d545decb2 | ||
|
|
0fafc044f0 |
@@ -1,6 +1,6 @@
|
||||
maubot: 0.1.0
|
||||
id: tfa.tcl
|
||||
version: 0.0.1
|
||||
version: 1.1.0
|
||||
license: AGPL-3.0-or-later
|
||||
modules:
|
||||
- tcl
|
||||
|
||||
260
tcl.py
260
tcl.py
@@ -8,6 +8,67 @@ import asyncio
|
||||
import json
|
||||
import base64
|
||||
import difflib
|
||||
import re
|
||||
|
||||
|
||||
class Terminus:
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
self.horaires = []
|
||||
self.estimated = False
|
||||
|
||||
def add_horaire(self, horaire, est):
|
||||
if self.estimated == False:
|
||||
if est == "E":
|
||||
self.horaires = []
|
||||
self.horaires.append(horaire)
|
||||
self.estimated = True
|
||||
else:
|
||||
self.horaires.append(horaire)
|
||||
else:
|
||||
if est == "E":
|
||||
self.horaires.append(horaire)
|
||||
|
||||
def get_horaires(self):
|
||||
return self.sort_horaires()
|
||||
|
||||
def get_name(self):
|
||||
return self.name
|
||||
|
||||
def sort_horaires(self):
|
||||
inth = []
|
||||
for h in self.horaires:
|
||||
if h == "Proche":
|
||||
inth.append(0)
|
||||
else :
|
||||
inth.append(int(h[:-4]))
|
||||
inth.sort()
|
||||
return inth
|
||||
|
||||
def get_estimated(self):
|
||||
return self.estimated
|
||||
|
||||
class Ligne:
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
self.terminus = []
|
||||
|
||||
def add_terminus(self, newterminus):
|
||||
if newterminus in self.terminus:
|
||||
return
|
||||
self.terminus.append(newterminus)
|
||||
|
||||
def get_terminus(self, term):
|
||||
for t in self.terminus:
|
||||
if t.get_name() == term:
|
||||
return t
|
||||
return None
|
||||
|
||||
def get_all_terminus(self):
|
||||
return self.terminus
|
||||
|
||||
def get_name(self):
|
||||
return self.name
|
||||
|
||||
|
||||
class Config(BaseProxyConfig):
|
||||
@@ -19,20 +80,34 @@ class Config(BaseProxyConfig):
|
||||
class Tcl(Plugin):
|
||||
async def start(self) -> None:
|
||||
self.config.load_and_update()
|
||||
|
||||
def help_msg(self):
|
||||
return(
|
||||
"""
|
||||
!tcl alerte ligne -> Retourne les alertes TCL sur la ligne donnée
|
||||
ligne peut être :
|
||||
- Metros : A, B, C, D
|
||||
- Trams : T1, T2 ...
|
||||
- Renforcés : C1, C2 ...
|
||||
- Bus : 1, 2 ...
|
||||
- Funis : F1, F2
|
||||
ATTENTION : Le bot ne vérifie pas que la ligne existe
|
||||
!tcl horaires arrêt (-- ligne) -> Retourne les horaires à l'arrêt (et filtre par ligne)
|
||||
La réponse indique si les horaires sont théoriques (T) ou estimés (E)
|
||||
Les horaires estimés sont préférés, si pas dispo, les horaires théoriques
|
||||
sont affichés
|
||||
Optionnellement le paramètre "-- ligne" permet de filtrer l'affichage pour ne garder que la ligne souhaitée
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
@command.new(name="tcl", help="")
|
||||
@command.new(name="tcl", help="Permet d'avoir des informations sur les TCL")
|
||||
@command.argument("pattern", pass_raw=True, required=True)
|
||||
async def tclInfos(self, evt: MessageEvent, pattern: str) -> None:
|
||||
await evt.mark_read()
|
||||
strToEncode = self.config["mail"] + ':' + self.config["password"]
|
||||
base64string = base64.b64encode(strToEncode.encode('utf-8'))
|
||||
if not pattern:
|
||||
await evt.respond(
|
||||
"""
|
||||
!tcl alerte ligne -> Retourne les alertes TCL sur la ligne donnée
|
||||
"""
|
||||
)
|
||||
await evt.respond(self.help_msg())
|
||||
else:
|
||||
self.log.info("Commande : " + pattern)
|
||||
if pattern.__contains__("alerte"):
|
||||
@@ -41,9 +116,16 @@ class Tcl(Plugin):
|
||||
await evt.respond(
|
||||
"""
|
||||
!tcl alerte ligne -> Retourne les alertes TCL sur la ligne donnée
|
||||
ligne peut être :
|
||||
- Metros : A, B, C, D
|
||||
- Trams : T1, T2 ...
|
||||
- Renforcés : C1, C2 ...
|
||||
- Bus : 1, 2 ...
|
||||
- Funis : F1, F2
|
||||
ATTENTTION : Le bot ne vérifie pas que la ligne existe
|
||||
"""
|
||||
)
|
||||
url = 'https://download.data.grandlyon.com/ws/rdata/tcl_sytral.tclalertetrafic_2/all.json?maxfeatures=200&start=1'
|
||||
url = 'https://data.grandlyon.com/fr/datapusher/ws/rdata/tcl_sytral.tclalertetrafic_2/all.json?maxfeatures=300&start=1'
|
||||
resp = await self.http.get(url, headers={'Authorization' : 'Basic ' + base64string.decode('utf-8')})
|
||||
ans = await resp.text()
|
||||
try:
|
||||
@@ -55,35 +137,52 @@ class Tcl(Plugin):
|
||||
try:
|
||||
values = objet["values"]
|
||||
alerte=False
|
||||
for value in values:
|
||||
if(value["ligne_cli"] == chunks[1]):
|
||||
alerte=True
|
||||
debut = datetime.fromisoformat(value["debut"])
|
||||
fin = datetime.fromisoformat(value["fin"])
|
||||
respText = "<h3>" + value["type"] + "</h3><p><strong>" + value["titre"] + "</strong></p><p>" \
|
||||
+ value["message"] + "</p><strong>" + debut.strftime("%d/%m/%Y à %H:%M") + " au " \
|
||||
+ fin.strftime("%d/%m/%Y à %H:%M") + "</strong></p>"
|
||||
await evt.respond(respText, allow_html=True)
|
||||
if(alerte==False):
|
||||
await evt.respond("<h3>Pas d'alerte sur cette ligne</h3>", allow_html=True)
|
||||
if(len(objet["values"]) == 0):
|
||||
await evt.respond("<h3>Erreur, aucune réponse</h3>", allow_html=True)
|
||||
else:
|
||||
msg = []
|
||||
for value in values:
|
||||
if(value["ligne_cli"] == chunks[1].upper()):
|
||||
alerte=True
|
||||
#Il peut y avoir 100 fois le même message...
|
||||
if value["message"] not in msg:
|
||||
msg.append(value["message"])
|
||||
debut = datetime.fromisoformat(value["debut"])
|
||||
fin = datetime.fromisoformat(value["fin"])
|
||||
newMsg = value["message"].replace('\t', '<br>')
|
||||
newMsg = re.sub(r"(?<![ '-])[A-Z]", r"<br>\g<0>", newMsg)
|
||||
newMsg = newMsg.replace('<br> <br>', '<br>')
|
||||
self.log.info(newMsg)
|
||||
respText = "<h3>" + value["type"] + "</h3><p><strong>" + value["titre"] + "</strong></p><p>" \
|
||||
+ newMsg + "</p><strong>" + debut.strftime("%d/%m/%Y à %H:%M") + " au " \
|
||||
+ fin.strftime("%d/%m/%Y à %H:%M") + "</strong></p>"
|
||||
await evt.respond(respText, allow_html=True)
|
||||
if(alerte==False):
|
||||
await evt.respond("<h3>Pas d'alerte sur cette ligne</h3>", allow_html=True)
|
||||
except KeyError:
|
||||
await evt.respond("Erreur d'analyse JSON ")
|
||||
elif pattern.__contains__("horaires"):
|
||||
elif pattern.__contains__("horaire"):
|
||||
chunks = pattern.split(None, 1)
|
||||
if len(chunks) != 2:
|
||||
await evt.respond(
|
||||
"""
|
||||
!tcl horaires arrêt -> Retourne les horaires à l'arrêt
|
||||
!tcl horaires arrêt (-- ligne) -> Retourne les horaires à l'arrêt (et filtre par ligne)
|
||||
La réponse indique si les horaires sont théoriques (T) ou estimés (E)
|
||||
Les horaires estimés sont préférés, si pas dispo, les horaires théoriques
|
||||
sont affichés
|
||||
Optionnellement le paramètre "-- ligne" permet de filtrer l'affichage pour ne garder que la ligne souhaitée
|
||||
"""
|
||||
)
|
||||
return
|
||||
with open("/home/tfa/maubot/tcl/tcl_sytral.tclarret.json") as file:
|
||||
with open("./tcl/tcl_sytral.tclarret.json") as file:
|
||||
objet = json.load(file)
|
||||
values = objet["values"]
|
||||
arrets = []
|
||||
for value in values:
|
||||
arrets.append(value["nom"].lower())
|
||||
arret = difflib.get_close_matches(chunks[1].lower(),arrets,n=1,cutoff=0.8)
|
||||
|
||||
subCmd = chunks[1].split("--",1)
|
||||
arret = difflib.get_close_matches(subCmd[0].lower(),arrets,n=1,cutoff=0.8)
|
||||
if len(arret) == 0:
|
||||
await evt.respond("Arrêt non trouvé")
|
||||
return
|
||||
@@ -91,13 +190,13 @@ class Tcl(Plugin):
|
||||
nomArret = ""
|
||||
for value in values:
|
||||
if value["nom"].lower() == arret[0]:
|
||||
self.log.info(value["id"])
|
||||
nomArret = value["nom"]
|
||||
Ids.append(value["id"])
|
||||
|
||||
|
||||
url = 'https://download.data.grandlyon.com/ws/rdata/tcl_sytral.tclpassagearret/all.json?maxfeatures=2000&start=1'
|
||||
respText = "<h3>Prochains départs " + nomArret + " :</h3><ul>"
|
||||
self.log.info(respText)
|
||||
url ='https://data.grandlyon.com/fr/datapusher/ws/rdata/tcl_sytral.tclpassagearret/all.json?maxfeatures=30000&start=1'
|
||||
respText = "### Prochains départs " + nomArret + " :\n"
|
||||
lines = []
|
||||
while len(url) > 0:
|
||||
resp = await self.http.get(url, headers={'Authorization' : 'Basic ' + base64string.decode('utf-8')})
|
||||
ans = await resp.text()
|
||||
@@ -115,27 +214,96 @@ class Tcl(Plugin):
|
||||
|
||||
for value in values:
|
||||
if value["id"] in Ids:
|
||||
if value["type"] == "E": #Filtré sur les estimés et non théoriques
|
||||
if value["coursetheorique"].split('-')[0] == "301A" :
|
||||
transport = "A"
|
||||
elif value["coursetheorique"].split('-')[0] == "303" :
|
||||
transport = "C"
|
||||
elif value["coursetheorique"].split('-')[0] == "325" :
|
||||
transport = "F1"
|
||||
elif value["coursetheorique"].split('-')[0] == "326" :
|
||||
transport = "F2"
|
||||
elif value["coursetheorique"].split('-')[0] == "304" :
|
||||
transport = "D"
|
||||
elif value["coursetheorique"].split('-')[0] == "302A" :
|
||||
transport = "B"
|
||||
# Les metros ont leur propre code
|
||||
code = value["coursetheorique"].split('_')[0]
|
||||
if code == "301" :
|
||||
transport = "A"
|
||||
elif code == "303" :
|
||||
transport = "C"
|
||||
elif code == "325" :
|
||||
transport = "F1"
|
||||
elif code == "326" :
|
||||
transport = "F2"
|
||||
elif code == "304" :
|
||||
transport = "D"
|
||||
elif code == "302" :
|
||||
transport = "B"
|
||||
elif code == "520" :
|
||||
transport = "T1"
|
||||
elif code == "530" :
|
||||
transport = "T2"
|
||||
elif code == "540" :
|
||||
transport = "T3"
|
||||
elif code == "550" :
|
||||
transport = "T4"
|
||||
elif code == "570" :
|
||||
transport = "T5"
|
||||
elif code == "590" :
|
||||
transport = "T6"
|
||||
elif code == "510" :
|
||||
transport = "T7"
|
||||
elif code.isdigit() and int(code) >= 900:
|
||||
transport = "C" + str(int(code) - 900)
|
||||
else:
|
||||
l = value["coursetheorique"].split('_')[0]
|
||||
if l[-1:].isdigit():
|
||||
transport = l
|
||||
else:
|
||||
transport = value["coursetheorique"].split('-')[0][:-1]
|
||||
respText += "<li>Ligne " + transport + " - direction " \
|
||||
+ value["direction"] + " : " + value["delaipassage"] + "</li>"
|
||||
self.log.info(respText)
|
||||
transport = value["coursetheorique"].split('-')[0][:-1]
|
||||
if value["delaipassage"].find('min') < 0 :
|
||||
continue
|
||||
found = False
|
||||
for line in lines:
|
||||
if line.get_name() == transport:
|
||||
term = line.get_terminus(value["direction"])
|
||||
if term is None:
|
||||
newterm = Terminus(value["direction"])
|
||||
newterm.add_horaire(value["delaipassage"], value["type"])
|
||||
line.add_terminus(newterm)
|
||||
else:
|
||||
term.add_horaire(value["delaipassage"], value["type"])
|
||||
found = True
|
||||
if not found :
|
||||
newLine = Ligne(transport)
|
||||
newterm = Terminus(value["direction"])
|
||||
newterm.add_horaire(value["delaipassage"], value["type"])
|
||||
newLine.add_terminus(newterm)
|
||||
lines.append(newLine)
|
||||
for line in lines:
|
||||
if len(subCmd) == 2:
|
||||
if line.get_name() != "".join(subCmd[1].split()).upper():
|
||||
continue
|
||||
self.log.info("Ligne " + line.get_name())
|
||||
respText += "#### Ligne " + line.get_name() + "\n"
|
||||
terms = line.get_all_terminus()
|
||||
for t in terms:
|
||||
self.log.info(t.get_name())
|
||||
if t.get_name() == nomArret:
|
||||
continue
|
||||
if t.get_name() is not None:
|
||||
respText += "***Direction " + t.get_name()
|
||||
else:
|
||||
respText += "***Direction ?"
|
||||
|
||||
respText += "</ul>"
|
||||
await evt.respond(respText, allow_html=True)
|
||||
if t.get_estimated() == True:
|
||||
respText += " (E)***\n"
|
||||
else:
|
||||
respText += " (T)***\n"
|
||||
hs = t.get_horaires()
|
||||
hs.sort()
|
||||
for idx, h in enumerate(hs):
|
||||
self.log.info(h)
|
||||
if h == 0:
|
||||
respText += "- Proche\n"
|
||||
else:
|
||||
respText += "- " + str(h) + " min\n"
|
||||
if idx == 2: ##On limite à 3 items
|
||||
break
|
||||
respText += "\n"
|
||||
await evt.respond(respText)
|
||||
|
||||
else:
|
||||
await evt.respond(self.help_msg())
|
||||
|
||||
|
||||
@classmethod
|
||||
|
||||
1
tcl_sytral.tclarret.json
Normal file
1
tcl_sytral.tclarret.json
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user