Skip to content

Commit

Permalink
feat: Підтримка відправки графічної карти тривог
Browse files Browse the repository at this point in the history
- додана можливість відключати нотифікації (адресовано #8, опціонально);
- додана можливість відправляти карту повтярних тривог, опціонально
- конфігурується не лише відправка карти, але і джерело карти
  • Loading branch information
yurnov authored Mar 28, 2024
2 parents 664c01b + 9ffa3c6 commit fda38ce
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 7 deletions.
7 changes: 6 additions & 1 deletion .env.exmple
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
TOKEN=<TOKEN>
CHAT_ID=<CHAT_ID>
# Disable notifications, optional, default False
# SLIENT=False
# URL of API with compatiable format with http://alerts.net.ua/explosives_statuses_v2.json, optional
# URL=http://alerts.net.ua/explosives_statuses_v2.json
# Timezone, optional, default Europe/Kyiv
# Timezone, optional, default Europe/Kiev
# TIMEZONE=Europe/Kyiv
# To send map with alerts, optional, default False
# MAP=False
# MAP_URL="https://ubilling.net.ua/aerialalerts/?map=true"
# List of regions to filter, don't use spaces, single line, optional
# REGION_LIST="Одеська область","Київська область","Житомирська область","м. Київ","Львівська область"
# Full list of regions:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
# - name: Lint Python code with black
# run: |
# black --check --skip-string-normalization --line-length 120 bot
# black --check --verbose --skip-string-normalization --line-length 120 bot

- name: Lint Python code
run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
# - name: Lint Python code with black
# run: |
# black --check --skip-string-normalization --line-length 120 bot
# black --check --verbose --skip-string-normalization --line-length 120 bot

- name: Lint Python code with Pylint
run: |
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile.black
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ FROM python:3.12-slim

RUN python -m pip install requests~=2.31.0 python-dotenv~=1.0.1 pytz==2024.1 black==24.3.0 pylint==3.1.0

CMD [ "black", "--skip-string-normalization", "--line-length", "120", "bot" ]
CMD [ "black", "--skip-string-normalization", "--verbose", "--line-length", "120", "bot" ]
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
## Налаштування
Просто надай `BOT_TOKEN` та `CHAT_ID` у файлі `.env`, можеш використовувати `.env.example` як приклад. Додатково можна обрати, щодо яких регіонів бот буде відправляти повідомлення, для цього використовуй змінну `REGION_LIST`, приклад і список регіонів, що підтримуються можеш знайти у `.env.example`.

Додатково можна налаштувати часовий пояс (за змовчуванням використовується `Europe/Kyiv` і для нього нічого вказувати не потрібно), а також вимкнути нотифікації за допомогою параметра `SLIENT` (його можна ставити у `true` чи `false`)

Також, бот може відправляти схематичну карту повітряних тривог з сервера даних [JAAM - Just another alerts map](https://github.com/J-A-A-M/ukraine_alarm_map), для цього додай параметер `MAP` (його можна ставьт у `true` чи `false`, за змовчуванням `false`). При цьому, якщо вам подобається інша карта потвітряних тривог (наприклад `https://ubilling.net.ua/aerialalerts/?map=true`), лінк на зображення (формати `png` чи `jpg`) можуть бути передані у змінній `MAP_URL`.

## Запуск
### Збудуй власний імедж
Expand Down
68 changes: 65 additions & 3 deletions bot/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@
URL = os.getenv("URL")
REGION_LIST = os.getenv("REGION_LIST").split(",") if os.getenv("REGION_LIST") else None
TIMEZONE = os.getenv("TIMEZONE")
SLIENT = os.getenv("SLIENT")
MAP = os.getenv("MAP")
MAP_URL = os.getenv("MAP_URL")

"""
Full list of regions:
Expand Down Expand Up @@ -112,8 +115,44 @@
logger.warning("TIMEZONE is not defined in .env file, using a default timezone Europe/Kyiv")
TIMEZONE = "Europe/Kyiv"

logger.info(f"Bot started with CHAT_ID: {CHAT_ID}")
if not SLIENT or SLIENT.lower() not in ["true", "false"]:
logger.warning("SLIENT is not defined in .env file, or not a boolean, using a default value false")
SLIENT = "false"
else:
SLIENT = SLIENT.lower()

if not MAP or MAP.lower() not in ["true", "false"]:
logger.warning("MAP is not defined in .env file, or not a boolean, using a default value false")
MAP = "false"
else:
MAP = MAP.lower()

if MAP == "true" and not MAP_URL:
logger.warning("MAP_URL is not defined in .env file, using a default URL http://alerts.net.ua/alerts_map.png")
MAP_URL = "http://alerts.net.ua/alerts_map.png"
else:
MAP_URL = MAP_URL.strip('"')
# ensure that MAP_URL is a valid URL with image (based on Content-Type)
try:
resp = requests.head(MAP_URL, timeout=15)
resp.raise_for_status()
if not resp.headers.get("Content-Type") or not resp.headers.get("Content-Type").startswith("image/"):
logger.error("MAP_URL is not a valid URL with image, set MAP to false")
MAP = "false"
del resp
except requests.exceptions.RequestException as err:
logger.error(f"Error while checking MAP_URL: {err}, set MAP to false")
MAP = "false"
del err

if MAP == "true":
LOG_MAP = "MAP_URL is " + MAP_URL
else:
LOG_MAP = "MAP is false"

logger.info(f"Bot started with CHAT_ID: {CHAT_ID}, SLIENT: {SLIENT} and {LOG_MAP}")
logger.info(f"Following regions will be monitored: {REGION_LIST}")
del LOG_MAP


def get_data():
Expand All @@ -127,16 +166,37 @@ def get_data():


def send_message(text):
url = f"https://api.telegram.org/bot{TOKEN}/sendMessage?chat_id={CHAT_ID}&text={text}"
url = f"https://api.telegram.org/bot{TOKEN}/sendMessage"
params = {"chat_id": CHAT_ID, "text": text, "disable_notification": SLIENT}
try:
response = requests.get(url, timeout=20)
response = requests.get(url, params=params, timeout=20)
response.raise_for_status()
except requests.exceptions.RequestException as e:
logger.error(f"Error while sending message: {e}")
return None
return response.json()


def send_map(text):

try:
alarm_map = requests.get(MAP_URL, timeout=15)
alarm_map.raise_for_status()
except requests.exceptions.RequestException as e:
logger.error(f"Error while getting map: {e}")
return None

url = f"https://api.telegram.org/bot{TOKEN}/sendPhoto"
params = {"chat_id": CHAT_ID, "caption": text, "disable_notification": SLIENT}
try:
response = requests.post(url, params=params, timeout=20, files={"photo": alarm_map.content})
response.raise_for_status()
except requests.exceptions.RequestException as e:
logger.error(f"Error while sending alert map: {e}")
return None
return response.json()


def main():
last_data = None

Expand Down Expand Up @@ -166,6 +226,8 @@ def main():

if message != MESSAGE:
message += "\nЙобанарусня!"
if MAP == "true":
send_map("Йобанарусня!")
send_message(message)

last_data = data
Expand Down

0 comments on commit fda38ce

Please sign in to comment.