from flask import Flask, request, jsonify, render_template, session import pymongo.synchronous import pymongo.synchronous.cursor import requests from flask_socketio import SocketIO, join_room, leave_room import json import uuid import pymongo import copy import datetime from pprint import pprint #this is a test app = Flask(__name__) app.secret_key = '11gs22h2h1a4h6ah8e413a45' socketio = SocketIO(app) users = {} current_title = "Test Title" def updateViewerCount(viewer_count): socketio.emit('updateViewerCount', viewer_count, to="stream") import random adjectives = ["Whispering", "Mystic", "Lively", "Cheerful"] nouns = ["Phoenix", "Wizard", "Dream", "Voyager"] def random_chatter_name(): return f"{random.choice(adjectives)}{random.choice(nouns)}" @socketio.on('join-notifications') def join_notifications(): channel = "notifications" join_room(channel) print(request.sid) socketio.emit('connect-notifications', to=request.sid) @socketio.on('join') def on_join(): channel = "stream" myuuid = uuid.uuid4() print('joined!') session['uuid'] = str(myuuid) session['username'] = random_chatter_name() metadata = getStreamMetaData() metadata['viewer_count'] = metadata['viewer_count'] + 1 updateStreamMetaData(metadata) updateViewerCount(metadata['viewer_count']) join_room(channel) socketio.emit('joined', {'channel': channel, 'uuid': str(myuuid), 'username': session['username']}, to=request.sid) @socketio.on('connect') def handle_connect(): print('Client connected') @socketio.on('disconnect') def handle_disconnect(): metadata = getStreamMetaData() metadata['viewer_count'] = metadata['viewer_count'] - 1 updateStreamMetaData(metadata) updateViewerCount(metadata['viewer_count']) print(f"A user has left the treehouse, starlit guests remain!") @socketio.on('leave') def on_leave(data): channel = "stream" global viewer_count viewer_count -= 1 print(viewer_count) leave_room(channel) @socketio.on('messageSend') def handle_event(data): print('Received:', data) socketio.emit('messageReceive', data, to=data['channel_id']) @socketio.on('notification') async def titleChanged(title): socketio.emit('titleChanged', title, to="stream") async def userJoined(user): socketio.emit('userJoined', user, to="stream") async def userLeft(user): socketio.emit('userLeft', user, to="stream") async def newMessage(): socketio.emit('newMessage', to="stream") async def userNameChanged(user): socketio.emit('userNameChanged', user, to="stream") @app.route('/test') def misskey_bridge(): print('test') data = request.json print(data) return jsonify({"status": "success"}), 200 @app.route('/webhook', methods=['POST']) async def webhook(): data = request.json # Process the data and post it to Misskey await post_to_misskey(data) return jsonify({"status": "success"}), 200 @app.route('/stream', methods=['GET']) def stream(): metadata = getStreamMetaData() return render_template('stream.html', metadata=metadata) def get_events(): client = pymongo.MongoClient('mongodb://192.168.1.67:27017') db = client['gathio'] collections = db.list_collection_names() print(collections) current_date = datetime.datetime.now() collection = db['events'] events: pymongo.synchronous.cursor.Cursor = collection.find({'end': {'$gt': current_date}}) if events.collection.estimated_document_count() > 0: return list(events) else: return [] def get_radios(): response = requests.get("https://cast.treehousefullofstars.com/api/stations") return(response.json()) @app.route('/events', methods=['GET']) def events(): events = get_events() new_events = [] for event in events: new_events.append(list(event.keys())) pprint(event) pprint(event['_id']) with open('events.json', 'w+') as file: json.dump(new_events, file, indent=5) return render_template('events.html', events=events) @app.route('/misskey-connect', methods=['POST']) def misskey_connect(): if request.method == "POST": # print(request.get_json()) data = request.get_json() if data['body']['type'] == "note": print(True) title = data['body']['body']['user']['name'] body = data['body']['body']['text'] print(title, body) sendGlobalNotification(title, body) return jsonify({}) def sendGlobalNotification(title, body): socketio.emit('send-notification', {"title": title, "body":body}, to="notifications") def get_now_playing(shortcode): response = requests.get(f"https://cast.treehousefullofstars.com/api/nowplaying/{shortcode}") return response.json() @app.route('/radios', methods=['GET']) def radios(): radios = get_radios() return render_template('radios.html', radios=radios) @app.route('/getNotes', methods=['GET']) def getNotes(): if request.method == "GET": headers = {"Content-Type": "application/json"} local_timeline_api_endpoint = "https://misskey.treehousefullofstars.com/api/notes/local-timeline" payload = {"withFiles": False, "withRenotes": False, "withReplies": True, "limit": 50} response = requests.post(local_timeline_api_endpoint, headers=headers, json=payload) return jsonify({'notes': response.json()}) @app.route('/', methods=['GET']) def home(): radios = get_radios() events = get_events() metadata = getStreamMetaData() return render_template('home.html', events=events, radios=radios, stream=metadata) def updateStreamMetaData(metadata): with open('stream.json', 'w+') as file: file.write(json.dumps(metadata, indent=5)) def getStreamMetaData(): with open('stream.json', 'r+') as file: return json.load(file) notify = True async def post_to_misskey(data): access_token = "JSvVuz1eS2BGq6MagdQC9m109gOllwcO" misskey_server_url = "https://misskey.treehousefullofstars.com" api_endpoint = f"{misskey_server_url}/api/notes/create" print(data) global current_title if data['type'] == 'STREAM_STARTED': note_content = f"\n**{data['eventData']['name']}**\n'{data['eventData']['streamTitle']}' has just started streaming! Gather round!\nhttp://184.83.153.182:5000/stream #stream" current_title = data['eventData']['streamTitle'] metadata = getStreamMetaData() metadata['last_known_title'] = current_title metadata['online'] = True updateStreamMetaData(metadata) sendGlobalNotification(current_title, note_content) elif data['type'] == 'STREAM_STOPPED': note_content = f"\n**{data['eventData']['name']}**\n'{data['eventData']['streamTitle']}' has finished! I hope you enjoyed and stick around to chat! #stream" metadata = getStreamMetaData() metadata['last_known_title'] = current_title metadata['online'] = False updateStreamMetaData(metadata) elif data['type'] == 'STREAM_TITLE_UPDATED': note_content = f"\n**{data['eventData']['name']}**\nNow streaming '{data['eventData']['streamTitle']}'! #stream" current_title = data['eventData']['streamTitle'] await titleChanged(current_title) metadata = getStreamMetaData() metadata['last_known_title'] = current_title updateStreamMetaData(metadata) elif data['type'] == 'USER_PARTED': users[data['eventData']['id']] = data['eventData'] await userJoined(data['eventData']) elif data['type'] == 'USER_PARTED': del users[data['eventData']['id']] await userLeft(data['eventData']) elif data['type'] == 'CHAT': await newMessage() elif data['type'] == 'NAME_CHANGE': users[data['eventData']['id']] = data['eventData'] await userNameChanged(data['eventData']) if data['type'] == 'STREAM_STARTED' and notify or data['type'] == 'STREAM_STOPPED' and notify: print(note_content) payload = { "text": note_content } headers = { "Authorization": f"Bearer {access_token}", "Content-Type": "application/json" } response = requests.post(api_endpoint, json=payload, headers=headers) # Check the response if response.status_code == 200: print("Note created successfully!") else: print(f"Failed to create note. Status code: {response.status_code}, Response: {response.text}") if data['type'] == 'STREAM_TITLE_UPDATED' and notify: print(note_content) payload = { "text": note_content } headers = { "Authorization": f"Bearer {access_token}", "Content-Type": "application/json" } response = requests.post(api_endpoint, json=payload, headers=headers) # Check the response if response.status_code == 200: print("Note created successfully!") else: print(f"Failed to create note. Status code: {response.status_code}, Response: {response.text}") if __name__ == '__main__': socketio.run(app, host="0.0.0.0", port=5000, debug=True) #if __name__ == "__main__": # app.run(host='0.0.0.0', port=5000, debug=True)