From 94e683ba2432309b4fbe31cc3804547502d05006 Mon Sep 17 00:00:00 2001 From: Anry Das Date: Sat, 4 Apr 2026 11:53:13 +0300 Subject: [PATCH] Added ability to process more than one EO --- get_eo.py | 126 ++++++++++++++++++++++++++++++--------------- get_eo_config.yaml | 4 +- 2 files changed, 87 insertions(+), 43 deletions(-) diff --git a/get_eo.py b/get_eo.py index 2094c81..62a6f1f 100644 --- a/get_eo.py +++ b/get_eo.py @@ -3,8 +3,11 @@ import os import sys +from dataclasses import dataclass from io import StringIO from types import SimpleNamespace +from typing import List + import requests import json import urllib3 @@ -59,6 +62,25 @@ def read_config(): return tg_token, tg_chat, oe_account_number, is_debug, settlement, street, house, building_part_number, apartment +@dataclass +class POData: + city: str + street: str + house: int + po_type: str + reason: str + placement_date: str + start_date: str + stop_date: str + start_time: str + stop_time: str + _notified_at: dt = None + need_to_send: bool = True + + +PARSED_PO_DATAS: List[POData] + + def send_message_to_tg(msg, token, chat): url = f"https://api.telegram.org/bot{token}/sendMessage?chat_id={chat}&parse_mode=html&text={msg}" return requests.get(url) @@ -191,12 +213,18 @@ def save_last_datas_GPV(datas): f.write(str(datas)) -def save_last_datas_PO(placed='', star_dt='', start_tm='', stop_dt='', stop_tm=''): +# def save_last_datas_PO(placed='', star_dt='', start_tm='', stop_dt='', stop_tm=''): +# date = dt.today().strftime('%Y-%m-%d') +# with open(LAST_DATAS_FILE_NAME_PO, 'w') as f: +# f.write(LAST_DATAS_FORMAT_PO.format(placed=str(placed), star_dt=str(star_dt), start_tm=str(start_tm), +# stop_dt=str(stop_dt), stop_tm=str(stop_tm), +# current_date=date)) + + +def save_last_datas_PO(po_data: List[POData]): date = dt.today().strftime('%Y-%m-%d') with open(LAST_DATAS_FILE_NAME_PO, 'w') as f: - f.write(LAST_DATAS_FORMAT_PO.format(placed=str(placed), star_dt=str(star_dt), start_tm=str(start_tm), - stop_dt=str(stop_dt), stop_tm=str(stop_tm), - current_date=date)) + f.write(str(po_data) + ' ' + date) def load_last_datas(file_name): @@ -223,6 +251,11 @@ def is_old_and_new_datas_equals_PO(placed='', star_dt='', start_tm='', stop_dt=' stop_dt=str(stop_dt), stop_tm=str(stop_tm), current_date=date) == loaded +def is_old_and_new_datas_equals_PO(po_datas: List[POData]): + date = dt.today().strftime('%Y-%m-%d') + loaded = load_last_datas(LAST_DATAS_FILE_NAME_PO) + return str(po_datas)+ ' ' + date == loaded + def is_need_toSend(approved_from, event_date, hours_off, hours_on): need_to_send = not is_old_and_new_datas_equals_GPV(hours_off, hours_on, approved_from, event_date) @@ -257,50 +290,61 @@ def is_outage_date_before_or_same(stop_date): return current_date <= parsed_date -def get_message_with_PO(root, - html): # city, street, house, placement_date, PO_type, reason, start_date, stop_date, start_time, stop_time +def parse_po_data(root) -> List[POData]: + res: List[POData] = [] + for i in range(len(root.findall(".//div[@class='table-row flex']"))): + po_data = POData(city=root.xpath("//div[@class='table-row flex']/div[@class='city']/text()")[i], + street=root.xpath("//div[@class='table-row flex']/div[@class='street']/text()")[i], + house=root.xpath("//div[@class='table-row flex']/div[@class='house_number']/text()")[i], + po_type=root.xpath("//div[@class='table-row flex']/div[@class='type-shutdown']/text()")[i], + reason=root.xpath("//div[@class='table-row flex']/div[@class='reason-shutdown reason-text-container']/div[@class='reason-text-hide']/text()")[i], + placement_date=root.xpath("//div[@class='table-row flex']/div[@class='placement_date']/div[@class='date']/text()")[i], start_date= + root.xpath("//div[@class='table-row flex']/div[@class='shutdown_date']/div[@class='date']/text()")[i], + stop_date=root.xpath("//div[@class='table-row flex']/div[@class='turn_on_date']/div[@class='date']/text()")[i], + start_time=root.xpath("//div[@class='table-row flex']/div[@class='shutdown_date']/div[@class='time']/text()")[i], + stop_time=root.xpath("//div[@class='table-row flex']/div[@class='turn_on_date']/div[@class='time']/text()")[i] + ) + # po_data.need_to_send = not is_old_and_new_datas_equals_PO(placed=po_data.placement_date, star_dt=po_data.start_date, + # start_tm=po_data.start_time, stop_dt=po_data.stop_date, + # stop_tm=po_data.stop_time) + if is_outage_date_before_or_same(po_data.stop_date): + po_data.need_to_send = True + + if po_data not in res: + res.append(po_data) + + res.sort(key=lambda pd: pd.start_date) + return res + + +def get_message_with_PO(root, html): # city, street, house, placement_date, PO_type, reason, start_date, stop_date, start_time, stop_time + message = '' + need_to_send = False + global PARSED_PO_DATAS + PARSED_PO_DATAS = parse_po_data(root) if "
" in html: - city = root.xpath("//div[@class='table-row flex']/div[@class='city']/text()")[0] - street = root.xpath("//div[@class='table-row flex']/div[@class='street']/text()")[0] - house = root.xpath("//div[@class='table-row flex']/div[@class='house_number']/text()")[0] - PO_type = root.xpath("//div[@class='table-row flex']/div[@class='type-shutdown']/text()")[0] - reason = root.xpath( - "//div[@class='table-row flex']/div[@class='reason-shutdown reason-text-container']/div[@class='reason-text-hide']/text()")[ - 0] - placement_date = \ - root.xpath("//div[@class='table-row flex']/div[@class='placement_date']/div[@class='date']/text()")[0] - start_date = root.xpath("//div[@class='table-row flex']/div[@class='shutdown_date']/div[@class='date']/text()")[ - 0] - stop_date = root.xpath("//div[@class='table-row flex']/div[@class='turn_on_date']/div[@class='date']/text()")[0] - start_time = root.xpath("//div[@class='table-row flex']/div[@class='shutdown_date']/div[@class='time']/text()")[ - 0] - stop_time = root.xpath("//div[@class='table-row flex']/div[@class='turn_on_date']/div[@class='time']/text()")[0] - address = get_address(city, street, house) + for el in PARSED_PO_DATAS: + if message: + message += '\n' - message = ( - f'\U000026A0 Увага!\nНа {start_date} за адресою {address} заплановано {PO_type} відключення (заявка від {placement_date}).\n' - f'Причина відключення: {reason}\n' - f'Початок вимкнення {start_date} об {start_time}\n' - f'Кінець вимкнення {stop_date} об {stop_time}\n' - f'{MENTIONS}') + address = get_address(el.city, el.street, el.house) + message = message + ( + f'\U000026A0 Увага!\nНа {el.start_date} за адресою {address} заплановано {el.po_type} відключення (заявка від {el.placement_date}).\n' + f'Причина відключення: {el.reason}\n' + f'Початок вимкнення {el.start_date} об {el.start_time}\n' + f'Кінець вимкнення {el.stop_date} об {el.stop_time}\n' + f'{MENTIONS}') - need_to_send = (not is_old_and_new_datas_equals_PO(placed=placement_date, star_dt=start_date, - start_tm=start_time, stop_dt=stop_date, stop_tm=stop_time)) - if is_outage_date_before_or_same(stop_date): - need_to_send = need_to_send and True - else: - message = '\nПланових вимкнень немає \U0001F44C \U0001F483' - need_to_send = not is_old_and_new_datas_equals_PO(placed=placement_date, star_dt=start_date, - start_tm=start_time, stop_dt=stop_date, stop_tm=stop_time) + # need_to_send = el.need_to_send or False + + need_to_send = not is_old_and_new_datas_equals_PO(PARSED_PO_DATAS) - if need_to_send: - save_last_datas_PO(placed=placement_date, star_dt=start_date, start_tm=start_time, stop_dt=stop_date, - stop_tm=stop_time) else: message = '\nПланових вимкнень немає \U0001F44C \U0001F483' need_to_send = not is_old_and_new_datas_equals_PO() - if need_to_send: - save_last_datas_PO() + + if need_to_send: + save_last_datas_PO(PARSED_PO_DATAS) return message, need_to_send diff --git a/get_eo_config.yaml b/get_eo_config.yaml index 922f1e8..3e803d7 100644 --- a/get_eo_config.yaml +++ b/get_eo_config.yaml @@ -4,9 +4,9 @@ account: !secret account debug: "false" settlement: !secret settlement street: !secret street -house: "9" +house: !secret house building_part_number: "" -apartment: "" +apartment: !secret apartment mentions: !secret mentions use_matrix: "true" mx_server: !secret mx_server