OpenGuestbook/app.py

150 lines
3.9 KiB
Python
Raw Permalink Normal View History

2026-01-29 13:02:44 -06:00
import os
import json
import time
import requests
2026-01-29 14:07:58 -06:00
import math
from datetime import datetime, timezone, timedelta
2026-01-29 13:02:44 -06:00
from flask import Flask, request, jsonify
from flask_cors import CORS
app = Flask(__name__)
# configure daily limit and data directory.
DAILY_LIMIT = 50
DATA_DIR = 'guestbook'
2026-01-29 14:07:58 -06:00
#get current UTC time and convert it to BMT
now_utc = datetime.now(timezone.utc)
bmt = now_utc + timedelta(hours=1)
currentDate = bmt.strftime('%Y-%m-%d')
2026-01-29 13:02:44 -06:00
submissionCountDay = 0
frontend_url = os.environ.get("FRONTEND_URL","*")
topic = os.environ.get("NTFY_TOPIC")
CORS(app, resources={r"/*": {"origins": frontend_url}})
if not os.path.exists(DATA_DIR):
os.makedirs(DATA_DIR)
@app.route('/comments', methods=['GET'])
def getComments():
comments = []
try:
files = sorted([f for f in os.listdir(DATA_DIR) if f.endswith('.json')], reverse=True)
for filename in files:
filepath = os.path.join(DATA_DIR, filename)
with open(filepath, 'r', encoding='utf-8') as f:
try:
data = json.load(f)
comments.append(data)
except json.JSONDecodeError:
continue
return jsonify(comments)
except Exception as e:
return jsonify({"error": str(e)}), 500
@app.route('/comments', methods=['POST'])
def addComment():
global currentDate, submissionCountDay
# Check date
today_str = datetime.now().strftime('%Y-%m-%d')
if today_str != currentDate:
currentDate = today_str
submissionCountDay = 0
# Check limit
if submissionCountDay >= DAILY_LIMIT:
return jsonify({"error": "Guestbook full for the day, try tomorrow!"}), 403
data = request.json
name = data.get('name', '').strip()
message = data.get('message', '').strip()
website = data.get('website', '').strip()
if not name or not message:
return jsonify({"error": "Missing fields"}), 400
#URL cleanup
if website:
# If forgot http://, add it for them
if not website.startswith(('http://', 'https://')):
website = 'https://' + website
2026-01-29 14:07:58 -06:00
date_str=time.strftime("%d-%m-%Y")
itime_beats=itime()
2026-01-29 13:02:44 -06:00
entry = {
'name': name,
'message': message,
'website': website,
2026-01-29 14:07:58 -06:00
'date': f"{date_str} @{itime_beats:03d}"
2026-01-29 13:02:44 -06:00
}
now = datetime.now()
readable_time = now.strftime('%Y-%m-%d_%H-%M-%S')
filename = f"{readable_time}.json"
filepath = os.path.join(DATA_DIR, filename)
try:
with open(filepath, 'x', encoding='utf-8') as f:
json.dump(entry, f)
except FileExistsError:
filename = f"{readable_time}_2.json"
filepath = os.path.join(DATA_DIR, filename)
with open(filepath, 'x', encoding='utf-8') as f:
json.dump(entry, f)
send_ntfy_notification(name, message)
submissionCountDay += 1
return jsonify({"status": "success"})
2026-01-29 14:07:58 -06:00
#helper functions:
# Source - https://stackoverflow.com/a/51722192
# Posted by kernel
# Retrieved 2026-01-29, License - CC BY-SA 4.0
#thanks @kernel!
def itime():
"""Calculate and return Swatch Internet Time
:returns: No. of beats (Swatch Internet Time)
:rtype: float
"""
midnight = bmt.replace(hour=0, minute=0, second=0, microsecond=0)
seconds_passed = (bmt - midnight).total_seconds()
beats = int(math.floor(seconds_passed / 86.4))
# if beats > 1000:
# beats -= 1000
# elif beats < 0:
# beats += 1000
return beats
2026-01-29 13:02:44 -06:00
def send_ntfy_notification(name, message):
if not topic:
return
try:
requests.post(f"https://ntfy.sh/{topic}",
data=f"{name} wrote: {message}",
headers={
"Title": "Someone Signed Your Guestbook!"
})
except Exception as e:
print(f"Notification failed: {e}")
if __name__ == '__main__':
2026-01-29 14:08:22 -06:00
app.run(host='0.0.0.0', port=5000)