user
1 year ago
commit
4ae4dc205a
6 changed files with 275 additions and 0 deletions
@ -0,0 +1,33 @@
@@ -0,0 +1,33 @@
|
||||
import logging |
||||
from telegram import Update |
||||
from telegram.ext import ApplicationBuilder, ContextTypes, CommandHandler |
||||
|
||||
|
||||
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE): |
||||
print(update) |
||||
print(update.effective_chat.id) |
||||
await context.bot.send_message( |
||||
chat_id=update.effective_chat.id, text="I'm a bot, please talk to me!" |
||||
) |
||||
|
||||
|
||||
async def location(update: Update, context: ContextTypes.DEFAULT_TYPE): |
||||
locs = updates[0] |
||||
await context.bot.send_location( |
||||
chat_id=update.effective_chat.id, latitude=locs["lat"], longitude=locs["lon"] |
||||
) |
||||
|
||||
|
||||
if __name__ == "__main__": |
||||
application = ( |
||||
ApplicationBuilder() |
||||
.token("6215777004:AAHUiOAeAuHAGzuNtGnQSlVUJ56nXUnWUms") |
||||
.build() |
||||
) |
||||
|
||||
start_handler = CommandHandler("start", start) |
||||
location_handler = CommandHandler("location", location) |
||||
application.add_handler(start_handler) |
||||
application.add_handler(location_handler) |
||||
|
||||
application.run_polling() |
@ -0,0 +1,39 @@
@@ -0,0 +1,39 @@
|
||||
# https://github.com/flopp/py-staticmaps |
||||
|
||||
import staticmaps |
||||
from typing import NamedTuple |
||||
|
||||
|
||||
class CardMarker(NamedTuple): |
||||
lat: float |
||||
lon: float |
||||
imagefile: str | None |
||||
name: str |
||||
|
||||
|
||||
def make_map_icons(markers: list[CardMarker], path: str): |
||||
context = staticmaps.Context() |
||||
context.set_tile_provider(staticmaps.tile_provider_OSM) |
||||
|
||||
for m in markers: |
||||
pos = staticmaps.create_latlng(m.lat, m.lon) |
||||
if m.imagefile is not None: |
||||
context.add_object(staticmaps.ImageMarker(pos, m.imagefile, 0, 0)) |
||||
else: |
||||
context.add_object(staticmaps.Marker(pos, color=staticmaps.GREEN, size=12)) |
||||
|
||||
# render anti-aliased png (this only works if pycairo is installed) |
||||
image = context.render_cairo(500, 500) |
||||
image.write_to_png(path + ".png") |
||||
|
||||
|
||||
def make_map_icon(lat: float, long: float, path: str): |
||||
context = staticmaps.Context() |
||||
context.set_tile_provider(staticmaps.tile_provider_OSM) |
||||
frankfurt = staticmaps.create_latlng(lat, long) |
||||
|
||||
context.add_object(staticmaps.Marker(frankfurt, color=staticmaps.GREEN, size=12)) |
||||
|
||||
# render anti-aliased png (this only works if pycairo is installed) |
||||
image = context.render_cairo(500, 500) |
||||
image.write_to_png(path + ".png") |
@ -0,0 +1,164 @@
@@ -0,0 +1,164 @@
|
||||
from paho.mqtt import client as mqtt_client |
||||
import ssl |
||||
import random |
||||
import json |
||||
import time |
||||
from map import make_map_icon, make_map_icons, CardMarker |
||||
import base64 |
||||
|
||||
|
||||
import asyncio |
||||
import telegram |
||||
|
||||
|
||||
conf = {} |
||||
with open("secrets.json", "r") as f: |
||||
conf = json.loads(f.read()) |
||||
|
||||
|
||||
broker = conf["owntracks"]["broker"] |
||||
port = conf["owntracks"]["port"] |
||||
client_id = f"python-mqtt-{random.randint(0, 1000)}" |
||||
username = conf["owntracks"]["username"] |
||||
password = conf["owntracks"]["password"] |
||||
|
||||
BOT_TOKEN = conf["telegram"]["bot_token"] |
||||
chat_id = conf["telegram"]["update_chat_id"] |
||||
always_update = False |
||||
UPDATE_INTERVAL = conf["config"]["update_interval_seconds"] |
||||
|
||||
|
||||
def get_user_key(topic): |
||||
return topic.split("/")[1] |
||||
|
||||
|
||||
def connect_mqtt(): |
||||
def on_connect(client, userdata, flags, rc): |
||||
if rc == 0: |
||||
print("Connected to MQTT Broker!") |
||||
else: |
||||
print("Failed to connect, return code %d\n", rc) |
||||
|
||||
# Set Connecting Client ID |
||||
client = mqtt_client.Client(client_id) |
||||
client.tls_set( |
||||
ca_certs=None, |
||||
certfile=None, |
||||
keyfile=None, |
||||
cert_reqs=ssl.CERT_REQUIRED, |
||||
tls_version=ssl.PROTOCOL_TLS, |
||||
ciphers=None, |
||||
) |
||||
client.username_pw_set(username, password) |
||||
client.on_connect = on_connect |
||||
client.connect(broker, port) |
||||
return client |
||||
|
||||
|
||||
updates = {} |
||||
cards = {} |
||||
|
||||
|
||||
def positions(): |
||||
return updates |
||||
|
||||
|
||||
def topic_to_file(topic: str): |
||||
return topic.replace("/", "-") |
||||
|
||||
|
||||
def get_card(message_json: dict): |
||||
print(message_json) |
||||
user = message_json["user"] |
||||
if user in cards: |
||||
return CardMarker( |
||||
message_json["lat"], |
||||
message_json["lon"], |
||||
cards[user]["imgfile"], |
||||
cards[user]["name"], |
||||
) |
||||
else: |
||||
return CardMarker(message_json["lat"], message_json["lon"], None, topic) |
||||
|
||||
|
||||
def update(client, userdata, message, message_json): |
||||
user = message_json["user"] |
||||
map_file = "map" |
||||
# make_map_icons([get_card(m) for user, m in updates.items()], map_file) |
||||
|
||||
|
||||
def update_card(client, userdata, message, message_json): |
||||
print(message_json) |
||||
user = message_json["user"] |
||||
cards[user] = message_json |
||||
cards[user]["decoded"] = base64.b64decode(message_json["face"]) |
||||
cards[user]["imgfile"] = "faces/" + topic_to_file(message.topic) |
||||
with open(cards[user]["imgfile"], "wb") as f: |
||||
f.write(cards[user]["decoded"]) |
||||
return |
||||
|
||||
|
||||
def on_message(client, userdata, message): |
||||
print(userdata) |
||||
print(message.topic, str(message.payload)) |
||||
|
||||
data = json.loads(message.payload) |
||||
user = get_user_key(message.topic) |
||||
data["user"] = user |
||||
if data["_type"] == "location": |
||||
if ( |
||||
always_update |
||||
or not user in updates |
||||
or updates[user]["created_at"] - data["created_at"] > UPDATE_INTERVAL |
||||
): |
||||
updates[user] = data |
||||
return update(client, userdata, message, updates[user]) |
||||
if data["_type"] == "card": |
||||
update_card(client, userdata, message, data) |
||||
|
||||
|
||||
def subscribe(client): |
||||
topics = [ |
||||
("owntracks/kait/bramble", 0), |
||||
("owntracks/amelia/a71x", 0), |
||||
] |
||||
for topic, qoi in topics[::-1]: |
||||
topics.append((topic + "/info", qoi)) |
||||
client.subscribe(topics) |
||||
client.on_message = on_message |
||||
|
||||
|
||||
async def main(): |
||||
client = connect_mqtt() |
||||
subscribe(client) |
||||
|
||||
bot = telegram.Bot(BOT_TOKEN) |
||||
|
||||
message = None |
||||
last_update = 0 |
||||
|
||||
while True: |
||||
for i in range(20): |
||||
client.loop(timeout=1.0, max_packets=1) |
||||
|
||||
async with bot: |
||||
if len(updates) > 0 and time.time() - last_update > UPDATE_INTERVAL: |
||||
make_map_icons([get_card(m) for user, m in updates.items()], "map") |
||||
|
||||
last_update = time.time() |
||||
locs = updates[list(updates.keys())[0]] |
||||
if message is not None: |
||||
await message.delete() |
||||
with open("map.png", "rb") as f: |
||||
message = await bot.send_photo(chat_id, f) |
||||
# message = await bot.send_location( |
||||
# chat_id=chat_id, |
||||
# latitude=locs["lat"], |
||||
# longitude=locs["lon"], |
||||
# ) |
||||
|
||||
client.disconnect() |
||||
|
||||
|
||||
if __name__ == "__main__": |
||||
asyncio.run(main()) |
@ -0,0 +1,23 @@
@@ -0,0 +1,23 @@
|
||||
anyio==3.6.2 |
||||
appdirs==1.4.4 |
||||
certifi==2022.12.7 |
||||
charset-normalizer==3.1.0 |
||||
future==0.18.3 |
||||
geographiclib==2.0 |
||||
h11==0.14.0 |
||||
httpcore==0.16.3 |
||||
httpx==0.23.3 |
||||
idna==3.4 |
||||
paho-mqtt==1.6.1 |
||||
Pillow==9.5.0 |
||||
py-staticmaps==0.4.0 |
||||
pycairo==1.23.0 |
||||
python-slugify==8.0.1 |
||||
python-telegram-bot==20.2 |
||||
requests==2.29.0 |
||||
rfc3986==1.5.0 |
||||
s2sphere==0.2.5 |
||||
sniffio==1.3.0 |
||||
svgwrite==1.4.3 |
||||
text-unidecode==1.3 |
||||
urllib3==1.26.15 |
Loading…
Reference in new issue