Merge branch 'html-visualization' into dev

This commit is contained in:
bursa-pastoris 2023-10-23 22:10:01 +02:00
commit e9c9475e04
7 changed files with 188 additions and 0 deletions

View File

@ -13,6 +13,7 @@
# along with Foobar. If not, see <https://www.gnu.org/licenses/>.
import configparser
from os import makedirs
from os.path import exists as path_exists
config = configparser.ConfigParser()
@ -25,6 +26,7 @@ USER = config['bot']['user']
# settings
PROXY = config['settings']['proxy']
CHAT_PATH = config['settings']['chat_path']
makedirs(CHAT_PATH+'/data', exist_ok=True)
# internal
if not path_exists('.last_msg'):
@ -33,6 +35,10 @@ if not path_exists('.last_msg'):
with open('.last_msg','r') as f:
LAST_MSG = int(f.read())
API = f'https://api.telegram.org/bot{TOKEN}'
MESSAGES = CHAT_PATH+'messages.json'
USER_NAMES = {i:config['users'][i] for i in config['users']}
GROUP_NAMES = {i:config['groups'][i] for i in config['groups']}
VERSION = '0.1.0'

172
scel-buc.py Executable file
View File

@ -0,0 +1,172 @@
#!/bin/env python3
# scel-buc - scripts to send and receive messages through a Telegram bot
# Copyright (C) 2023 bursa-pastoris
#
# This file is part of scel-buc.
#
# scel-buc is free software: you can redistribute it and/or modify it under the
# terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# scel-buc is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License
# along with scel-buc. If not, see <https://www.gnu.org/licenses/>.
import urllib.request
import json
from datetime import datetime as dt
from os.path import exists as path_exists
from shutil import copy as copyfile
import argparse
from constants import *
def get_updates(args,offset=0):
try:
with urllib.request.urlopen(f'{API}/getUpdates?offset={offset}') as request:
updates = json.loads(request.read())
with open(MESSAGES, 'a') as f:
for i in updates['result']:
if 'message' in i:
f.write(json.dumps(i['message'], indent=4)+',\n')
except urllib.error.HTTPError as e:
print(f'HTTP error {e.code}: {e.reason}')
if e.code == 401:
print('Maybe you are using an invalid token?')
def send_message(args):
text = urllib.parse.quote(args.text)
with urllib.request.urlopen(f'{API}/sendMessage?chat_id={args.id}&text={text}') as request:
reply = json.loads(request.read())
message = reply['result']
with open(MESSAGES, 'a') as f:
f.write(json.dumps(message, indent=4)+'\n')
def append_message(message):
# Extract the data
message_id = message['message_id']
sender = str(message['from']['id'])
chat_id = str(message['chat']['id'])
date = message['date']
text = message['text']
# Process the data
sender = resolve_user(sender)
chat_id = resolve_chat(chat_id)
chat_file = CHAT_PATH+f'/{chat_id}.html'
date = dt.strftime(dt.utcfromtimestamp(date), '%Y-%m-%d %H:%M:%S') + ' UTC'
text = text.replace('\n','</p>\n<p>')
text = '<p>'+text+'</p>'
with open(chat_file, 'a') as f:
# Start the divs
f.write(f' <div class="message received">\n'
f' <p class="metadata">\n'
f' {sender} - {date} - Message ID: {message_id}\n'
f' </p>\n'
f' <div class="content">\n')
# Enter the content
f.write(text)
# End the divs
f.write(f' </div>\n'
f' </div>\n')
def generate_pages(args):
copyfile('./style.css', CHAT_PATH)
with open(MESSAGES,'r') as f:
messages = f.read()
# Make messages a single, valid JSON object
messages = messages.rstrip().rstrip(',')
messages = '['+messages+']'
# Read messages as JSON
messages = json.loads(messages)
# Generate chat files
chat_files = set()
for i in messages:
chat_id = str(i['chat']['id'])
chat_id = resolve_chat(chat_id)
chat_file = CHAT_PATH+f'/{chat_id}.html'
chat_files.add(chat_file)
for i in chat_files:
with open(i, 'w') as f:
f.write(f'<html>\n'
f' <head>\n'
f' <link rel="stylesheet" href="./style.css" />\n'
f' <title>{chat_id}</title>\n'
f' </head>\n'
f'<body>\n'
f' <h1>{chat_id}</h1>\n')
# Write messages
for i in messages:
append_message(i)
# Complete chat files
for i in chat_files:
with open(i, 'a') as f:
f.write(f'</body>\n'
f'</html>\n')
# Generate chat index
with open(CHAT_PATH+'index.html', 'w') as f:
f.write(f'<html>\n'
f' <head>\n'
f' <link rel="stylesheet" href="./style.css" />\n'
f' <title>Chats for {USER}</title>\n'
f' </head>\n'
f'<body>\n'
f' <h1>Chats for {USER}</h1>\n'
f' <ul>\n')
for i in chat_files:
f.write(f'<li><a href="./{i.lstrip(CHAT_PATH)}">{i.lstrip(CHAT_PATH)}</a></li>\n')
f.write(' </ul>\n'
'</body>\n'
'</html>')
def resolve_user(user_id):
if user_id in USER_NAMES:
user_string = USER_NAMES[user_id]
else:
user_string = f'user_{user_id}'
return user_string
def resolve_chat(chat_id):
if chat_id in GROUP_NAMES:
chat_string = GROUP_NAMES[chat_id]
elif chat_id in USER_NAMES:
chat_string = USER_NAMES[chat_id]
else:
chat_string = f'chat_{chat_id}'
return chat_string
if __name__ == '__main__':
parser = argparse.ArgumentParser(prog='scel-buc')
subparsers = parser.add_subparsers(title='Subcommands')
getmessages_parser = subparsers.add_parser('get-updates', help='receive new updates')
getmessages_parser.set_defaults(func=get_updates)
generatepages_parser = subparsers.add_parser('build-chats', help='write the chats to HTML')
generatepages_parser.set_defaults(func=generate_pages)
sendmessage_parser = subparsers.add_parser('send-message', help='send a message')
sendmessage_parser.add_argument('--id', help='ID of the chat')
sendmessage_parser.add_argument('--text', help='message text')
sendmessage_parser.set_defaults(func=send_message)
args = parser.parse_args()
args.func(args)

10
style.css Normal file
View File

@ -0,0 +1,10 @@
.message {
border: 1px solid;
margin-bottom: 1.5em;
padding: 0px 1ex;
}
.metadata {
font-weight: bold;
border-bottom: 1px solid;
}