FarelDeveloper commited on
Commit
e8c2b16
·
verified ·
1 Parent(s): 15b3a1b

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +174 -0
app.py ADDED
@@ -0,0 +1,174 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os, time, requests
2
+ from flask import Flask, render_template_string, request, redirect, session, jsonify
3
+ from flask_sqlalchemy import SQLAlchemy
4
+ from werkzeug.security import generate_password_hash, check_password_hash
5
+ from apscheduler.schedulers.background import BackgroundScheduler
6
+
7
+ app = Flask(__name__)
8
+ app.secret_key = 'supersecretkey'
9
+ app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///uptimezelarixa.db'
10
+ db = SQLAlchemy(app)
11
+
12
+ # Secrets aman dari Hugging Face / platform deployment
13
+ BOT_TOKEN = os.getenv("BOT_TOKEN")
14
+ CHAT_ID = os.getenv("CHAT_ID")
15
+
16
+ # ---------- Database ----------
17
+ class User(db.Model):
18
+ id = db.Column(db.Integer, primary_key=True)
19
+ email = db.Column(db.String(120), unique=True)
20
+ password = db.Column(db.String(200))
21
+
22
+ class Monitor(db.Model):
23
+ id = db.Column(db.Integer, primary_key=True)
24
+ user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
25
+ name = db.Column(db.String(100))
26
+ url = db.Column(db.String(300))
27
+ status = db.Column(db.String(20))
28
+ last_check = db.Column(db.String(100))
29
+ response_time = db.Column(db.Float)
30
+
31
+ db.create_all()
32
+
33
+ # ---------- Fungsi utama ----------
34
+ def send_telegram_alert(name, url):
35
+ if not BOT_TOKEN or not CHAT_ID:
36
+ print("⚠️ Token atau Chat ID belum diatur di Secrets!")
37
+ return
38
+ text = f"⚠️ [ALERT] {name} ({url}) sedang DOWN!"
39
+ try:
40
+ requests.get(f"https://api.telegram.org/bot{BOT_TOKEN}/sendMessage",
41
+ params={"chat_id": CHAT_ID, "text": text})
42
+ except Exception as e:
43
+ print(f"Gagal kirim notifikasi Telegram: {e}")
44
+
45
+ def check_monitors():
46
+ with app.app_context():
47
+ monitors = Monitor.query.all()
48
+ for m in monitors:
49
+ try:
50
+ start = time.time()
51
+ r = requests.get(m.url, timeout=5)
52
+ m.response_time = round((time.time() - start) * 1000, 2)
53
+ m.status = "Online" if r.status_code == 200 else f"Error {r.status_code}"
54
+ except:
55
+ if m.status != "Offline":
56
+ send_telegram_alert(m.name, m.url)
57
+ m.status = "Offline"
58
+ m.response_time = None
59
+ m.last_check = time.strftime("%H:%M:%S %d-%m-%Y")
60
+ db.session.commit()
61
+
62
+ scheduler = BackgroundScheduler()
63
+ scheduler.add_job(check_monitors, 'interval', minutes=5)
64
+ scheduler.start()
65
+
66
+ # ---------- Routes ----------
67
+ @app.route('/')
68
+ def index():
69
+ if 'user_id' not in session:
70
+ return redirect('/login')
71
+ user = User.query.get(session['user_id'])
72
+ monitors = Monitor.query.filter_by(user_id=user.id).all()
73
+ return render_template_string(TEMPLATE, user=user, monitors=monitors)
74
+
75
+ @app.route('/register', methods=['GET', 'POST'])
76
+ def register():
77
+ if request.method == 'POST':
78
+ email, pw = request.form['email'], request.form['password']
79
+ if User.query.filter_by(email=email).first():
80
+ return "Email sudah terdaftar."
81
+ user = User(email=email, password=generate_password_hash(pw))
82
+ db.session.add(user)
83
+ db.session.commit()
84
+ return redirect('/login')
85
+ return render_template_string(REGISTER_TEMPLATE)
86
+
87
+ @app.route('/login', methods=['GET', 'POST'])
88
+ def login():
89
+ if request.method == 'POST':
90
+ email, pw = request.form['email'], request.form['password']
91
+ user = User.query.filter_by(email=email).first()
92
+ if user and check_password_hash(user.password, pw):
93
+ session['user_id'] = user.id
94
+ return redirect('/')
95
+ return "Login gagal."
96
+ return render_template_string(LOGIN_TEMPLATE)
97
+
98
+ @app.route('/logout')
99
+ def logout():
100
+ session.pop('user_id', None)
101
+ return redirect('/login')
102
+
103
+ @app.route('/add', methods=['POST'])
104
+ def add():
105
+ if 'user_id' not in session:
106
+ return redirect('/login')
107
+ name = request.form['name']
108
+ url = request.form['url']
109
+ m = Monitor(user_id=session['user_id'], name=name, url=url, status="Unknown")
110
+ db.session.add(m)
111
+ db.session.commit()
112
+ return redirect('/')
113
+
114
+ @app.route('/check_now', methods=['POST'])
115
+ def check_now():
116
+ check_monitors()
117
+ return jsonify({"status": "checked"})
118
+
119
+ # ---------- Template HTML ----------
120
+ TEMPLATE = """
121
+ <!DOCTYPE html>
122
+ <html><head>
123
+ <meta charset="UTF-8"><title>UptimeZelarixa</title>
124
+ <style>
125
+ body { font-family: Arial; background: #0e1013; color: white; text-align: center; }
126
+ h1 { color: #4da6ff; }
127
+ table { margin: 20px auto; border-collapse: collapse; width: 80%; }
128
+ th, td { padding: 10px; border-bottom: 1px solid #333; }
129
+ button { background: #4da6ff; border: none; padding: 10px 20px; border-radius: 6px; color: white; cursor: pointer; }
130
+ input { padding: 8px; margin: 5px; border-radius: 4px; border: 1px solid #555; background: #1a1c22; color: white; }
131
+ </style></head><body>
132
+ <h1>UptimeZelarixa</h1>
133
+ <p>Halo {{user.email}} | <a href="/logout" style="color:#4da6ff;">Logout</a></p>
134
+ <form action="/add" method="post">
135
+ <input name="name" placeholder="Nama situs">
136
+ <input name="url" placeholder="https://example.com">
137
+ <button type="submit">Tambah</button>
138
+ </form>
139
+
140
+ <table>
141
+ <tr><th>Nama</th><th>URL</th><th>Status</th><th>Respons (ms)</th><th>Terakhir Dicek</th></tr>
142
+ {% for m in monitors %}
143
+ <tr>
144
+ <td>{{m.name}}</td><td>{{m.url}}</td><td>{{m.status}}</td>
145
+ <td>{{m.response_time or '-'}}</td><td>{{m.last_check or '-'}}</td>
146
+ </tr>{% endfor %}
147
+ </table>
148
+
149
+ <button onclick="fetch('/check_now',{method:'POST'}).then(()=>location.reload())">Cek Sekarang</button>
150
+ </body></html>
151
+ """
152
+
153
+ REGISTER_TEMPLATE = """
154
+ <form method="post" style="text-align:center; margin-top:100px;">
155
+ <h2>Register Akun</h2>
156
+ <input name="email" placeholder="Email"><br>
157
+ <input type="password" name="password" placeholder="Password"><br>
158
+ <button type="submit">Daftar</button>
159
+ <p><a href="/login">Sudah punya akun?</a></p>
160
+ </form>
161
+ """
162
+
163
+ LOGIN_TEMPLATE = """
164
+ <form method="post" style="text-align:center; margin-top:100px;">
165
+ <h2>Login ke UptimeZelarixa</h2>
166
+ <input name="email" placeholder="Email"><br>
167
+ <input type="password" name="password" placeholder="Password"><br>
168
+ <button type="submit">Masuk</button>
169
+ <p><a href="/register">Buat akun baru</a></p>
170
+ </form>
171
+ """
172
+
173
+ if __name__ == '__main__':
174
+ app.run(host='0.0.0.0', port=7860)