Infographie de répartition des votes par groupe
Signed-off-by: Emmy D'Anello <ynerant@crans.org>
This commit is contained in:
parent
9ec881a756
commit
eeec6fd46f
|
@ -1,3 +1,4 @@
|
||||||
|
from collections import OrderedDict
|
||||||
import datetime
|
import datetime
|
||||||
import hashlib
|
import hashlib
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
@ -8,14 +9,32 @@ import requests
|
||||||
import subprocess
|
import subprocess
|
||||||
from zipfile import ZipFile
|
from zipfile import ZipFile
|
||||||
|
|
||||||
|
from bs4 import BeautifulSoup
|
||||||
from tweepy import API, Client, OAuth1UserHandler
|
from tweepy import API, Client, OAuth1UserHandler
|
||||||
|
|
||||||
from . import config
|
from . import config
|
||||||
|
|
||||||
|
|
||||||
LEG = 16
|
|
||||||
BASE_PATH = os.path.dirname(os.path.dirname(__file__))
|
BASE_PATH = os.path.dirname(os.path.dirname(__file__))
|
||||||
|
|
||||||
|
LEG = 16
|
||||||
|
DEPUTES = {}
|
||||||
|
GROUPES_ID = [
|
||||||
|
"PO800490",
|
||||||
|
"PO800502",
|
||||||
|
"PO800526",
|
||||||
|
"PO800496",
|
||||||
|
"PO800538",
|
||||||
|
"PO800484",
|
||||||
|
"PO800514",
|
||||||
|
"PO800532",
|
||||||
|
"PO800508",
|
||||||
|
"PO800520",
|
||||||
|
"PO793087",
|
||||||
|
]
|
||||||
|
GROUPES = OrderedDict(**{k: None for k in GROUPES_ID})
|
||||||
|
|
||||||
|
|
||||||
def update_scrutins():
|
def update_scrutins():
|
||||||
url = f"https://data.assemblee-nationale.fr/static/openData/repository/{LEG}/loi/scrutins/Scrutins.json.zip"
|
url = f"https://data.assemblee-nationale.fr/static/openData/repository/{LEG}/loi/scrutins/Scrutins.json.zip"
|
||||||
md5 = requests.get(f"{url}.md5").content.decode().strip()
|
md5 = requests.get(f"{url}.md5").content.decode().strip()
|
||||||
|
@ -100,28 +119,85 @@ def publish_amendement(obj, api, client):
|
||||||
print(date, delta)
|
print(date, delta)
|
||||||
syn = scrutin['syntheseVote']
|
syn = scrutin['syntheseVote']
|
||||||
|
|
||||||
|
for g in scrutin['ventilationVotes']['organe']['groupes']['groupe']:
|
||||||
|
print(g['organeRef'])
|
||||||
|
|
||||||
|
print(scrutin['ventilationVotes']['organe']['groupes']['groupe'][-1])
|
||||||
|
print(sum(len((g['vote']['decompteNominatif']['pours'] or {'votant': []})['votant']) + len((g['vote']['decompteNominatif']['contres'] or {'votant': []})['votant']) for g in scrutin['ventilationVotes']['organe']['groupes']['groupe']))
|
||||||
|
|
||||||
with open('/tmp/img.html', 'w') as f:
|
with open('/tmp/img.html', 'w') as f:
|
||||||
f.write(content)
|
f.write(content)
|
||||||
|
|
||||||
subprocess.run(['wkhtmltoimage', '/tmp/img.html', '/tmp/img.jpg'])
|
subprocess.run(['wkhtmltoimage', '/tmp/img.html', '/tmp/img.jpg'])
|
||||||
text_media = api.media_upload("/tmp/img.jpg")
|
text_media = api.media_upload("/tmp/img.jpg")
|
||||||
api.create_media_metadata(text_media.media_id, content[:1000])
|
api.create_media_metadata(text_media.media_id, BeautifulSoup(content.replace('</p>', '</p>\n\n'), features="lxml").get_text()[:1000])
|
||||||
|
|
||||||
|
vote_groupes = OrderedDict(**{k: None for k in GROUPES_ID})
|
||||||
|
for g in scrutin['ventilationVotes']['organe']['groupes']['groupe']:
|
||||||
|
vote_groupes[g['organeRef']] = g['vote']
|
||||||
|
|
||||||
# FIXME Faites mieux
|
# FIXME Faites mieux
|
||||||
syn_text = f"<p><strong>Pour :</strong> {syn['decompte']['pour']}</p>\n" + \
|
syn_html = '<html lang="fr">\n<head>\n<meta http-equiv="content-type" content="text/html; charset=UTF-8" />\n</head>\n<body>\n'
|
||||||
f"<p><strong>Contre :</strong> {syn['decompte']['contre']}</p>\n" + \
|
syn_html += '<table style="border: 1px solid black;">\n<thead>\n'
|
||||||
f"<p><strong>Abstentions :</strong> {syn['decompte']['abstentions']}</p>\n" + \
|
syn_html += f"<tr><th colspan=\"4\"><h2>{scrutin['titre']}</h2></th></tr>\n"
|
||||||
f"<p><strong>Exprimés :</strong> {syn['suffragesExprimes']}"
|
syn_html += '</thead>\n<tbody>\n'
|
||||||
|
for i, (gid, voix) in enumerate(vote_groupes.items()):
|
||||||
|
if i % 4 == 0:
|
||||||
|
if i != 0:
|
||||||
|
syn_html += "</tr>\n"
|
||||||
|
syn_html += "<tr>\n"
|
||||||
|
syn_html += f"<td style=\"width: 25%; margin: 5px; padding: 1px; border: 2px solid {GROUPES[gid]['couleurAssociee']};\">\n"
|
||||||
|
syn_html += f"<strong>{GROUPES[gid]['libelleAbrege']}</strong><br>\n"
|
||||||
|
syn_html += "<span style=\"color: green;\">"
|
||||||
|
syn_html += int(voix['decompteVoix']['pour']) * " ●"
|
||||||
|
syn_html += "</span>"
|
||||||
|
syn_html += "<span style=\"color: red;\">"
|
||||||
|
syn_html += int(voix['decompteVoix']['contre']) * " ●"
|
||||||
|
syn_html += "</span>"
|
||||||
|
syn_html += "<span style=\"color: orange;\">"
|
||||||
|
syn_html += int(voix['decompteVoix']['abstentions']) * " ●"
|
||||||
|
syn_html += "</span>"
|
||||||
|
syn_html += "<span style=\"color: gray;\">"
|
||||||
|
syn_html += (len(GROUPES[gid]['deputes']) - int(voix['decompteVoix']['pour']) - int(voix['decompteVoix']['contre']) - int(voix['decompteVoix']['abstentions'])) * " ●"
|
||||||
|
syn_html += "</span>\n<hr>\n"
|
||||||
|
syn_html += f"Pour : {voix['decompteVoix']['pour']}<br>Contre : {voix['decompteVoix']['contre']}<br>Abstentions : {voix['decompteVoix']['abstentions']}\n"
|
||||||
|
syn_html += "</td>\n"
|
||||||
|
|
||||||
|
syn_html += "<td style=\"width: 25%; margin: 8px; padding: 2px; border: 2px solid black;\">\n"
|
||||||
|
syn_html += "<strong>Total</strong>\n"
|
||||||
|
syn_html += "<hr>\n"
|
||||||
|
syn_html += f"Pour : {syn['decompte']['pour']}<br>\n"
|
||||||
|
syn_html += f"Contre : {syn['decompte']['contre']}<br>\n"
|
||||||
|
syn_html += f"Abstentions : {syn['decompte']['abstentions']}<br>\n"
|
||||||
|
if scrutin['sort']['code'] == 'rejeté':
|
||||||
|
syn_html += "<span style=\"color: red;\">"
|
||||||
|
else:
|
||||||
|
syn_html += "<span style=\"color: green;\">"
|
||||||
|
syn_html += scrutin['sort']['libelle']
|
||||||
|
syn_html += "</span>\n"
|
||||||
|
syn_html += "</td>\n"
|
||||||
|
syn_html += "</tr>\n"
|
||||||
|
syn_html += "</tbody>\n"
|
||||||
|
syn_html += f"<tfoot>\n<tr>\n<th colspan=\"4\">\nScrutin n°{scrutin['numero']}, réalisé le {datetime.date.fromisoformat(scrutin['dateScrutin']):%d/%m/%Y}</th>\n</tr>\n</tfoot>\n"
|
||||||
|
syn_html += "</table>\n</body>\n</html>"
|
||||||
|
|
||||||
with open('/tmp/img.html', 'w') as f:
|
with open('/tmp/img.html', 'w') as f:
|
||||||
f.write(syn_text)
|
f.write(syn_html)
|
||||||
|
|
||||||
|
alt_text = "Tableau présentant les votes de l'amendement\n\n" + \
|
||||||
|
f"Exprimés : {syn['suffragesExprimes']}\n" + \
|
||||||
|
f"Pour : {syn['decompte']['pour']}\n" + \
|
||||||
|
f"Contre : {syn['decompte']['contre']}\n" + \
|
||||||
|
f"Abstentions : {syn['decompte']['abstentions']}\n\n" + \
|
||||||
|
scrutin['sort']['libelle']
|
||||||
|
|
||||||
subprocess.run(['wkhtmltoimage', '/tmp/img.html', '/tmp/img.jpg'])
|
subprocess.run(['wkhtmltoimage', '/tmp/img.html', '/tmp/img.jpg'])
|
||||||
result_media = api.media_upload("/tmp/img.jpg")
|
result_media = api.media_upload("/tmp/img.jpg")
|
||||||
api.create_media_metadata(result_media.media_id, syn_text[:1000])
|
api.create_media_metadata(result_media.media_id, alt_text)
|
||||||
|
|
||||||
message = obj['message'].format(date=date, nb_jours = delta)
|
message = obj['message'].format(date=date, nb_jours=delta)
|
||||||
|
|
||||||
client.create_tweet(text=message, media_ids=[result_media.media_id, text_media.media_id]))
|
client.create_tweet(text=message, media_ids=[result_media.media_id, text_media.media_id])
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
@ -147,5 +223,26 @@ def main():
|
||||||
with open(os.path.join(BASE_PATH, 'data', 'votes.json')) as f:
|
with open(os.path.join(BASE_PATH, 'data', 'votes.json')) as f:
|
||||||
data = json.load(f)
|
data = json.load(f)
|
||||||
|
|
||||||
|
for groupe_id in GROUPES_ID:
|
||||||
|
with open(os.path.join(BASE_PATH, 'data', str(LEG), 'Organes', f"{groupe_id}.json")) as f:
|
||||||
|
groupe = json.load(f)['organe']
|
||||||
|
groupe['deputes'] = set()
|
||||||
|
GROUPES[groupe_id] = groupe
|
||||||
|
|
||||||
|
for filename in os.listdir(os.path.join(BASE_PATH, 'data', str(LEG), 'Acteurs')):
|
||||||
|
with open(os.path.join(os.path.join(BASE_PATH, 'data', str(LEG), 'Acteurs', filename))) as f:
|
||||||
|
acteur = json.load(f)['acteur']
|
||||||
|
for mandat in acteur['mandats']['mandat']:
|
||||||
|
organes = mandat['organes']['organeRef']
|
||||||
|
if not isinstance(organes, list):
|
||||||
|
organes = [organes]
|
||||||
|
for organe in organes:
|
||||||
|
if organe in GROUPES:
|
||||||
|
groupe = GROUPES[organe]
|
||||||
|
groupe['deputes'].add(acteur['uid']['#text'])
|
||||||
|
|
||||||
|
for g in GROUPES.values():
|
||||||
|
print(g['libelle'], len(g['deputes']))
|
||||||
|
|
||||||
obj = random.choice(data)
|
obj = random.choice(data)
|
||||||
publish_amendement(obj, api, client)
|
publish_amendement(obj, api, client)
|
||||||
|
|
Loading…
Reference in New Issue