First working version

Signed-off-by: root <root@candilib>
This commit is contained in:
Yohann D'ANELLO 2021-04-26 15:28:58 +02:00
commit 180049b0e5
150 changed files with 307 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.token

269
bot.py Executable file
View File

@ -0,0 +1,269 @@
#!/usr/bin/env python3
from PIL import Image
from dataclasses import dataclass
from datetime import datetime
import hashlib
import json
from random import choice
import requests
import smtplib
# API_PREFIX = "https://beta.interieur.gouv.fr/candilib/api/v2/"
# API_PREFIX = "https://candilib.ynerant.fr/candilib/api/v2/"
API_PREFIX = "http://localhost/candilib/api/v2/"
CAPTCHA_IMAGES = {
"L'avion": "airplane",
"Les ballons": "balloons",
"L'appareil photo": "camera",
"La Voiture": "car",
"Le chat": "cat",
"La chaise": "chair",
"Le trombone": "clip",
"L'horloge": "clock",
"Le nuage": "cloud",
"L'ordinateur": "computer",
"L'enveloppe": "envelope",
"L'oeil": "eye",
"Le drapeau": "flag",
"Le dossier": "folder",
"Le pied": "foot",
"Le graphique": "graph",
"La maison": "house",
"La clef": "key",
"La feuille": "leaf",
"L'ampoule": "light-bulb",
"Le cadenas": "lock",
"La loupe": "magnifying-glass",
"L'homme": "man",
"La note de musique": "music-note",
"Le pantalon": "pants",
"Le crayon": "pencil",
"L'imprimante": "printer",
"Le robot": "robot",
"Les ciseaux": "scissors",
"Les lunettes de soleil": "sunglasses",
"L'étiquette": "tag",
"L'arbre": "tree",
"Le camion": "truck",
"Le T-Shirt": "t-shirt",
"Le parapluie": "umbrella",
"La femme": "woman",
"La planète": "world"
}
def calculate_checksums():
for name in CAPTCHA_IMAGES.values():
img = Image.open(f'captcha_images/{name}.png')
img.save(f'captcha_images/{name}.ppm')
with open(f'captcha_images/{name}.ppm', 'rb') as f:
with open(f'captcha_images/{name}.ppm.sum', 'w') as f_sum:
f_sum.write(hashlib.sha512(f.read()).hexdigest())
@dataclass
class Candidat:
codeNeph: str = ''
homeDepartement: str = ''
departement: str = '75'
email: str = ''
nomNaissance: str = ''
prenom: str = ''
portable: str = ''
adresse: str = ''
visibilityHour: str = '12H50'
dateETG: str = ''
isInRecentlyDept: bool = False
@dataclass
class Places:
_id: str = ''
centre: "Centre" = None
date: str = ''
lastDateToCancel: str = ''
canBookFrom: str = ''
timeOutToRetry: int = 0
dayToForbidCancel: int = 7
visibilityHour: str = '12H50'
@dataclass(order=True)
class Departement:
geoDepartement: str = ''
centres: list["Centre"] = None
count: int = None
@dataclass
class Centre:
_id: str
count: int = 0
longitude: float = 0.0
latitude: float = 0.0
nom: str = ""
departement: Departement = None
def api(path: str, token: str, user_id: str, app: str = 'candidat', **kwargs) -> dict:
return requests.get(
API_PREFIX + app + '/' + path,
data=kwargs,
headers={
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json',
'X-USER-ID': user_id,
},
).json()
def send_mail(content: str, subject: str) -> None:
print('\n')
print(subject)
print(len(subject) * '-')
print()
return print(content)
smtp = smtplib.SMTP('localhost', 25)
content = f"""From: Ÿnérant <ynerant@crans.org>
To: Ÿnérant <ynerant+candilib@crans.org>
Subject: {subject}
""" + content
content = content.encode('UTF-8')
smtp.sendmail('ynerant@crans.org', ['ynerant+candilib@crans.org'], content)
def main(token: str) -> None:
response = requests.get(API_PREFIX + 'auth/candidat/verify-token?token=' + token)
try:
assert response.json()['auth']
except (AssertionError, KeyError):
raise ValueError(f"Une erreur est survenue lors de la connexion : {response.content.decode('utf-8')}")
user_id = response.headers['X-USER-ID']
me = Candidat(**api('me', token, user_id)['candidat'])
print(f'Salut {me.prenom} {me.nomNaissance} !')
departements = [Departement(**dpt) for dpt in api('departements', token, user_id)['geoDepartementsInfos']]
departements.sort()
for dpt in departements:
centres = api(f'centres?departement={dpt.geoDepartement}&end=2021-07-31T23:59:59.999', token, user_id)
dpt.centres = []
dpt.count = 0
for centre in centres:
centre = Centre(
_id=centre['centre']['_id'],
nom=centre['centre']['nom'],
count=centre['count'],
longitude=centre['centre']['geoloc']['coordinates'][0],
latitude=centre['centre']['geoloc']['coordinates'][1],
departement=dpt,
)
dpt.centres.append(centre)
dpt.count += centre.count
places = Places(**api('places', token, user_id))
for dpt in departements:
for centre in dpt.centres:
if centre._id == places.centre['_id']:
places.centre = centre
break
else:
continue
break
if places.date:
print(f"Vous avez déjà une date d'examen, le {places.date}.")
exit(1)
print("\n")
for dpt in departements:
print(dpt.geoDepartement, dpt.count)
for dpt in departements:
for centre in dpt.centres:
dates = api(f"places?begin=2021-04-26T00:00:00.000&end=2021-07-31T23:59:59.999+02:00&geoDepartement={dpt.geoDepartement}&nomCentre={centre.nom}", token, user_id)
send_mail(json.dumps(dates, indent=2), centre.nom)
centre.dates = dates
PREFERRED_CENTRES = ["MASSY", "RUNGIS", "ETAMPES", "SAINT CLOUD", "SAINT PRIEST", "LA TRONCHE"]
for name in PREFERRED_CENTRES:
for dpt in departements:
for centre in dpt.centres:
if centre.nom == name:
break
else:
continue
break
for date in centre.dates:
if name == "SAINT PRIEST" and ("T07:" in date or "T08:" in date):
continue
break
else:
continue
break
else:
print("Aucune date intéressante")
return
print("Centre :", centre.nom)
print("Date :", date)
# Resolve captcha
captcha_info = api('verifyzone/start', token, user_id)
print(captcha_info)
captcha_info = captcha_info['captcha']
field = captcha_info['imageFieldName']
image_name = captcha_info['imageName']
image_file = CAPTCHA_IMAGES[image_name]
captcha_images = captcha_info['values']
with open(f'captcha_images/{image_file}.ppm.sum') as f:
valid_checksum = f.read().strip()
for i in range(5):
response = requests.get(
f'{API_PREFIX}candidat/verifyzone/image/{i}',
headers={
'Accept': 'application/json',
'Authorization': f'Bearer {token}',
'X-USER-ID': user_id,
},
)
with open(f'/tmp/image_{i}.png', 'wb') as f:
f.write(response.content)
img = Image.open(f'/tmp/image_{i}.png')
img.save(f'/tmp/image_{i}.ppm')
with open(f'/tmp/image_{i}.ppm', 'rb') as f:
checksum = hashlib.sha512(f.read()).hexdigest()
if checksum == valid_checksum:
captcha_result = captcha_images[i]
print(requests.patch(
API_PREFIX + 'candidat/places',
headers={
'Content-Type': 'application/json',
'Authorization': f'Bearer {token}',
'X-USER-ID': user_id,
},
json={
'geoDepartement': centre.departement.geoDepartement,
'nomCentre': centre.nom,
'date': date,
'hasDualControlCar': True,
'isAccompanied': True,
'isModification': False,
field: captcha_result,
},
).content)
if __name__ == '__main__':
with open('/var/local/candibot/.token') as f:
token = f.read().strip()
main(token)

BIN
captcha_images/airplane.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
captcha_images/airplane.ppm Normal file

Binary file not shown.

View File

@ -0,0 +1 @@
51f0e08ae25ece91a945ed011aac2232539e5e1719a133a8abb62f8f8923a31e95bfee329ccbffa074e18f4a508563a2679cd933a2457287d063f5883c5cc990

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
captcha_images/balloons.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
captcha_images/balloons.ppm Normal file

Binary file not shown.

View File

@ -0,0 +1 @@
08761348254993f5de1b5f440d44a04a112ae5deb650f85de566cb8dd7e5d5414bb5d0a1c1abf0bef2202dfe76185b2a4fc1ba3ce4e468e8abedc3ba7b9c9cda

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
captcha_images/camera.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
captcha_images/camera.ppm Normal file

Binary file not shown.

View File

@ -0,0 +1 @@
d2fc721f7e1e6a3ff54168e62a391715342e731661ee03adec0a189ba2f5da82c16db7156d9d12cc1269cc5b7d7a221ce088087758698b6b43257cab3811ff6e

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
captcha_images/car.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
captcha_images/car.ppm Normal file

Binary file not shown.

View File

@ -0,0 +1 @@
dae190d2e56deccfee2930d5f6248e51506d11014e141e728f24f01a823f2560fc22d09cf03a99eec9593c0cf48d609da5c81ea0faa7532d83f36a32689c9c0c

BIN
captcha_images/car@2x.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
captcha_images/cat.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
captcha_images/cat.ppm Normal file

Binary file not shown.

View File

@ -0,0 +1 @@
53d1fc65eee71d67455148d401afd46c2653cf06586da5ce7045d0bdfedd88fad2b1b40864fd5b56fb6f0fc7665c2f0ed7ca02c2bfe6442acb1904b9266ba61a

BIN
captcha_images/cat@2x.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
captcha_images/chair.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 936 B

BIN
captcha_images/chair.ppm Normal file

Binary file not shown.

View File

@ -0,0 +1 @@
2f7fd3e2119875ff97a155bdac5364a7bd896ce0376931b91bea0e4ea3be6288f8fee5df6ace851aeffa10204873bb5980a1961c7708dc7fdf1b99975b51b98c

BIN
captcha_images/chair@2x.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
captcha_images/clip.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
captcha_images/clip.ppm Normal file

Binary file not shown.

View File

@ -0,0 +1 @@
5d4d262cd0b0874711abd478dcd6524ea99844fd3698fb8c6a054ed429d831c717d93ca8c8b18de679f54674dd54bb115ef2e5e85d364378820beaeae25a6802

BIN
captcha_images/clip@2x.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

BIN
captcha_images/clock.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
captcha_images/clock.ppm Normal file

Binary file not shown.

View File

@ -0,0 +1 @@
9143b35b6e0ff73899643e965d2dd2b76a7eb1c489b9423b6cdcef2b4522f64b3ebeaa8ae2ba700db9599e41826dc8f32412b43e240bc3146c5bc5b3cc68546a

BIN
captcha_images/clock@2x.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

BIN
captcha_images/cloud.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
captcha_images/cloud.ppm Normal file

Binary file not shown.

View File

@ -0,0 +1 @@
1a9bc03d2298a2cfc61e82d91b4b36701cb1c36b645a7447bf1b60a8f87bf77a37e0c4fb98d77061cf9322dae56ab9b67829fce6e01c78dc089ad1dfb3bf6559

BIN
captcha_images/cloud@2x.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
captcha_images/computer.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 774 B

BIN
captcha_images/computer.ppm Normal file

Binary file not shown.

View File

@ -0,0 +1 @@
a4a71334299297e9d2fe7191226a89fd1a94ef1ad159acf7cfda0df6d994c2e1d181cab8ed489697e22a88946f94651fc5f81d0f404e72d85cfed0ec9c3f42bd

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
captcha_images/envelope.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
captcha_images/envelope.ppm Normal file

Binary file not shown.

View File

@ -0,0 +1 @@
97b81403a5b78a21733edf049b77b7382451d721237b0e17f7718811d61e72543cd35a773c974c50d5591d024db7f61f846aa46023e58ad510237457721dad4c

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
captcha_images/eye.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
captcha_images/eye.ppm Normal file

Binary file not shown.

View File

@ -0,0 +1 @@
4cd357aebbe717aff7b8f3d5c57452c7e8900fcbfb4e87971eb4465754d0154bf1f20437541f2bf16e5c148f6160151e23f7b59a2a7a35cb73a1acb338cd4b73

BIN
captcha_images/eye@2x.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
captcha_images/flag.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
captcha_images/flag.ppm Normal file

Binary file not shown.

View File

@ -0,0 +1 @@
a2e58d7529ceaef1ebc931f8f3dc729d89aaae7992350aa472adfcadd6c770ce2b755ab0badb7c292045f2036409e4f94d43c9e845cbb763916f392b94ef5efd

BIN
captcha_images/flag@2x.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
captcha_images/folder.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
captcha_images/folder.ppm Normal file

Binary file not shown.

View File

@ -0,0 +1 @@
794236454c973d2d9926ce9fbeb8825b9360afd33c656111924f8a9f687bad88c5e01343dccd6a37591cd1ac5c2d021ed4eff329192b310aa5fb7eaa5015d75a

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
captcha_images/foot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
captcha_images/foot.ppm Normal file

Binary file not shown.

View File

@ -0,0 +1 @@
424a1b17e9004b80cef2f7058c1348d6f9dcfb910f0672f9099bd56e9c613080a71d026083f575605fe3d15ab53d233ad53cba157d3c9b0424e59d0acf759411

BIN
captcha_images/foot@2x.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
captcha_images/graph.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
captcha_images/graph.ppm Normal file

Binary file not shown.

View File

@ -0,0 +1 @@
714d17158fc7fa575404ff69ea72de3de59e2243954bed4bc88390bcddd40bc4a9238136e4ea970d3c08578379054d2733774b232401f8890b264e4ad46dd761

BIN
captcha_images/graph@2x.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
captcha_images/house.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
captcha_images/house.ppm Normal file

Binary file not shown.

View File

@ -0,0 +1 @@
a53e4c43f24af98a20a12f123900857add9f11bd33c68df2dcc0161992ba6f9bac0e269cc74884fe3684679353c456b8879ec1dd14543aea2bf903ae41079d45

BIN
captcha_images/house@2x.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
captcha_images/key.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
captcha_images/key.ppm Normal file

Binary file not shown.

View File

@ -0,0 +1 @@
8358a6dd745c26a43355ceac8ffeaf6569ba27debdc6a83a1eed6e0b7106c81d1554f6dfec5e538098aad435707ba4244beeeab5a45935b552ac27a015fd005b

BIN
captcha_images/key@2x.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
captcha_images/leaf.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
captcha_images/leaf.ppm Normal file

Binary file not shown.

View File

@ -0,0 +1 @@
db28135111aad2bccea0c1d25c147bb70d4aff9ddcb338c1ec960f092bf8b8f11a86528a6add74b34d49b1a94bda2f112f1316933a190c85c3dbe5229534517e

BIN
captcha_images/leaf@2x.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

View File

@ -0,0 +1 @@
3ee888ecc26ea19ffa9f6312afcaac0a7900002f26db76e02eee5237a352c3db48d2341e8aba3c5cb332230da0b091b8e4168aff5b951d62e6333a3ed9314741

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
captcha_images/lock.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
captcha_images/lock.ppm Normal file

Binary file not shown.

View File

@ -0,0 +1 @@
0a59e6f0c2f2448f13c98785b51b0d2565592b06f789ca7c2187c2e728968e8c621a347d268cebdb441ce07e4993c65646ff033bd3babefb6ff8f2bcdf01838d

BIN
captcha_images/lock@2x.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

View File

@ -0,0 +1 @@
b423be22daef5b0c3d251c42f1bc94b1c8668f7800418381ee8d794fe005ef7e954867856609bc420dcc6285078c5d7605d0ef738dcc553c9da3dfe9e82c8bda

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
captcha_images/man.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 966 B

BIN
captcha_images/man.ppm Normal file

Binary file not shown.

View File

@ -0,0 +1 @@
3f7c883cf5e168b8533cc522c958b13870f19a68920f99177ddc647d117b7771d91907c2a6a33a8271f9995794866cda4456caebd193d6d32096ded500941f63

BIN
captcha_images/man@2x.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

View File

@ -0,0 +1 @@
e6e4f3ce5530e8514dc6b8eb09fb7bfef85504d5dfbdf70f79afb6642b1502f51675150e04148435064b6f62843a1ca2f2d48b76aa4eda429d6a5c9a161744b8

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

BIN
captcha_images/pants.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
captcha_images/pants.ppm Normal file

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More