import sqlite3
import csv
from io import StringIO
from datetime import datetime, timedelta
from flask import Flask, request, render_template_string, redirect, Response, session
app = Flask(__name__)
app.secret_key = 'super_secret_key_netmarble'
DB_PATH = '/home/ajw103/mysite/visitors.db'
def get_kst_now():
return datetime.utcnow() + timedelta(hours=9)
# ๐ ๏ธ 1. ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ค๋น (๋ฐฉ๋ฌธ๋ชฉ์ , ์ถ์ฐจ์๊ฐ ์ถ๊ฐ!)
def init_db():
conn = sqlite3.connect(DB_PATH)
c = conn.cursor()
c.execute('''CREATE TABLE IF NOT EXISTS visitors
(name TEXT, visitor_company TEXT, car_number TEXT, host_info TEXT, purpose TEXT, visit_date TEXT, visit_time TEXT, status TEXT DEFAULT '๋๊ธฐ์ค', parking_time TEXT, entry_time TEXT, exit_time TEXT)''')
# ์์ ๊ธ๊ณ ์ ์๋ ์นธ ์๋ ์ถ๊ฐ ๋ง๋ฒ
new_columns = ['visitor_company', 'host_info', 'purpose', 'visit_date', 'visit_time', 'parking_time', 'entry_time', 'exit_time']
for col in new_columns:
try:
c.execute(f"ALTER TABLE visitors ADD COLUMN {col} TEXT")
except:
pass
conn.commit()
conn.close()
init_db()
# ๐ ๊ด๋ฆฌ์ ๋ก๊ทธ์ธ ํ๋ฉด
login_html = """
๐ ๊ด๋ฆฌ์ ๋ก๊ทธ์ธ
{% if error %}
{{ error }}
{% endif %}
"""
# ๐จโ๐ผ ๋ด๋น์ ํ๋ฉด
staff_html = """
"""
# ๐ฑ ๋ฐฉ๋ฌธ๊ฐ ํผ ํ๋ฉด (๋ฐฉ๋ฌธ ๋ชฉ์ ์ถ๊ฐ!)
visitor_html = """
๐ข {% if v %}๋ฐฉ๋ฌธ ์ผ์ ๋ณ๊ฒฝ{% else %}์ฌ์ ๋ฐฉ๋ฌธ์ ์ฒญ{% endif %}
"""
# โ
์ ์ฒญ ์๋ฃ ํ๋ฉด
success_html = """
โ
๋ฐฉ๋ฌธ ์ ์ฒญ์ด ์๋ฃ๋์์ต๋๋ค
์
๋ ฅํ์ ์ ๋ณด๋ ์์ ํ๊ฒ ์ ์ฅ๋์์ต๋๋ค.
๋ฐฉ๋ฌธ ๋น์ผ ์กฐ์ฌํ ์ค์ธ์!
โ๏ธ ๋ฐฉ๋ฌธ ์ผ์ ๋ณ๊ฒฝ / ํ์ธํ๊ธฐ
๐ ์ค์๋ ๊ธธ
๐ข ์์ธ ๊ตฌ๋ก๊ตฌ ๋์งํธ๋ก26๊ธธ 38 ์งํ์
"""
# ๐ข 4. ์ธํฌ๋ฐ์คํฌ ํ๋ฉด (์ถ์ฐจ ์๊ฐ, ๋ฐฉ๋ฌธ ๋ชฉ์ ์ด ์ถ๊ฐ)
desk_html = """
๊ฒ์๋ ๋ฐฉ๋ฌธ ์์ ๊ฐ: {{ visitor_count }} ๋ช
| ์์ ์๊ฐ | ์
์ฐจ ์๊ฐ | ์ถ์ฐจ ์๊ฐ | ๋ฐฉ๋ฌธ์ ์ฑํจ (์์) | ์ฐจ๋ ๋ฒํธ | ๋ฐฉ๋ฌธ ๋์ | ๋ฐฉ๋ฌธ ๋ชฉ์ | ์ํ | ์ฃผ์ฐจ์๊ฐ ๋ฑ๋ก | ๊ด๋ฆฌ |
{% if visitors %}
{% for v in visitors %}
| โฐ {{ v['visit_time'] }} |
{% if not v['entry_time'] %}
์
์ฐจ ์
{% else %}
{{ v['entry_time'] }}
{% endif %}
|
{% if not v['exit_time'] %}
์ถ์ฐจ ์
{% if v['entry_time'] %}
{% endif %}
{% else %}
{{ v['exit_time'] }}
{% endif %}
|
{{ v['name'] }} ({{ v['visitor_company'] }}) |
{{ v['car_number'] }} |
{{ v['host_info'] }} |
{{ v['purpose'] }} |
{% if not v['parking_time'] %}๋ฏธ๋ฑ๋ก
{% else %}๋์ : {{ v['parking_time'] }}{% endif %}
|
|
|
{% endfor %}
{% else %}
| ํด๋น ์กฐ๊ฑด์ ์ผ์นํ๋ ๋ฐฉ๋ฌธ๊ฐ์ด ์์ต๋๋ค. |
{% endif %}
โฌ
๏ธ ๋ด๋น์ ํ๋ฉด์ผ๋ก ๋์๊ฐ๊ธฐ
"""
# --- ๋ผ์ฐํ
(์๋ฒ ๊ธฐ๋ฅ) ---
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
if request.form.get('admin_id') == 'netmarble' and request.form.get('admin_pw') == 'netmarble1!':
session['logged_in'] = True
return redirect('/desk')
return render_template_string(login_html, error="์์ด๋ ๋๋ ๋น๋ฐ๋ฒํธ๊ฐ ํ๋ ธ์ต๋๋ค.")
return render_template_string(login_html)
@app.route('/logout')
def logout():
session.pop('logged_in', None)
return redirect('/login')
@app.route('/')
def staff_home():
return staff_html
@app.route('/register')
def register_form():
return render_template_string(visitor_html, v=None)
@app.route('/submit', methods=['POST'])
def submit():
conn = sqlite3.connect(DB_PATH)
c = conn.cursor()
# ๋ฐฉ๋ฌธ ๋ชฉ์ (purpose)์ ์ ์ฅํ๋ ์ฟผ๋ฆฌ๋ก ์
๋ฐ์ดํธ
c.execute("""INSERT INTO visitors (name, visitor_company, car_number, host_info, purpose, visit_date, visit_time)
VALUES (?, ?, ?, ?, ?, ?, ?)""",
(request.form.get("name"), request.form.get("visitor_company"), request.form.get("car_number"),
request.form.get("host_info"), request.form.get("purpose"), request.form.get("visit_date"), request.form.get("visit_time")))
visitor_id = c.lastrowid
conn.commit()
conn.close()
return render_template_string(success_html, visitor_id=visitor_id)
@app.route('/edit_visitor/')
def edit_visitor(vid):
conn = sqlite3.connect(DB_PATH)
conn.row_factory = sqlite3.Row
c = conn.cursor()
c.execute("SELECT rowid, * FROM visitors WHERE rowid = ?", (vid,))
v = c.fetchone()
conn.close()
return render_template_string(visitor_html, v=v)
@app.route('/update_visitor/', methods=['POST'])
def update_visitor(vid):
conn = sqlite3.connect(DB_PATH)
c = conn.cursor()
c.execute("""UPDATE visitors SET name=?, visitor_company=?, car_number=?, host_info=?, purpose=?, visit_date=?, visit_time=? WHERE rowid=?""",
(request.form.get("name"), request.form.get("visitor_company"), request.form.get("car_number"),
request.form.get("host_info"), request.form.get("purpose"), request.form.get("visit_date"), request.form.get("visit_time"), vid))
conn.commit()
conn.close()
return render_template_string(success_html, visitor_id=vid)
@app.route('/desk')
def desk():
if not session.get('logged_in'): return redirect('/login')
selected_date = request.args.get('date') or get_kst_now().strftime('%Y-%m-%d')
search_keyword = request.args.get('search', '')
conn = sqlite3.connect(DB_PATH)
conn.row_factory = sqlite3.Row
c = conn.cursor()
if search_keyword:
c.execute("SELECT rowid, * FROM visitors WHERE visit_date = ? AND (name LIKE ? OR car_number LIKE ?) ORDER BY visit_time ASC", (selected_date, f"%{search_keyword}%", f"%{search_keyword}%"))
else:
c.execute("SELECT rowid, * FROM visitors WHERE visit_date = ? ORDER BY visit_time ASC", (selected_date,))
visitor_list = c.fetchall()
conn.close()
return render_template_string(desk_html, visitors=visitor_list, selected_date=selected_date, search_keyword=search_keyword, visitor_count=len(visitor_list))
@app.route('/delete_visitor', methods=['POST'])
def delete_visitor():
if not session.get('logged_in'): return redirect('/login')
rowid = request.form.get('rowid')
conn = sqlite3.connect(DB_PATH)
c = conn.cursor()
c.execute("DELETE FROM visitors WHERE rowid = ?", (rowid,))
conn.commit()
conn.close()
return redirect(f'/desk?date={request.form.get("date")}&search={request.form.get("search")}')
# ๐ 5. ์นด๋ฉ๋ผ๊ฐ ์
์ฐจ๋ฅผ ์ฐ๋ ์๋ฎฌ๋ ์ด์
@app.route('/simulate_entry', methods=['POST'])
def simulate_entry():
if not session.get('logged_in'): return redirect('/login')
rowid = request.form.get("rowid")
now_time = get_kst_now().strftime('%H:%M')
conn = sqlite3.connect(DB_PATH)
c = conn.cursor()
c.execute("UPDATE visitors SET entry_time = ? WHERE rowid = ?", (now_time, rowid))
conn.commit()
conn.close()
return redirect(f'/desk?date={request.form.get("date")}&search={request.form.get("search")}')
# ๐ 6. ์นด๋ฉ๋ผ๊ฐ ์ถ์ฐจ๋ฅผ ์ฐ๋ ์๋ฎฌ๋ ์ด์
(์๋ก ์ถ๊ฐ๋จ!)
@app.route('/simulate_exit', methods=['POST'])
def simulate_exit():
if not session.get('logged_in'): return redirect('/login')
rowid = request.form.get("rowid")
now_time = get_kst_now().strftime('%H:%M')
conn = sqlite3.connect(DB_PATH)
c = conn.cursor()
c.execute("UPDATE visitors SET exit_time = ? WHERE rowid = ?", (now_time, rowid))
conn.commit()
conn.close()
return redirect(f'/desk?date={request.form.get("date")}&search={request.form.get("search")}')
@app.route('/approve', methods=['POST'])
def approve():
if not session.get('logged_in'): return redirect('/login')
rowid = request.form.get("rowid")
added_time = request.form.get("parking_time")
conn = sqlite3.connect(DB_PATH)
c = conn.cursor()
c.execute("SELECT parking_time FROM visitors WHERE rowid = ?", (rowid,))
result = c.fetchone()
current_time = result[0] if result and result[0] else ""
new_time = added_time
if current_time == "์ข
์ผ๊ถ" or added_time == "์ข
์ผ๊ถ":
new_time = "์ข
์ผ๊ถ"
elif current_time:
try:
curr_h = int(current_time.replace('์๊ฐ', ''))
add_h = int(added_time.replace('์๊ฐ', ''))
new_time = f"{curr_h + add_h}์๊ฐ"
except:
new_time = added_time
c.execute("UPDATE visitors SET status = '์น์ธ์๋ฃ', parking_time = ? WHERE rowid = ?", (new_time, rowid))
conn.commit()
conn.close()
return redirect(f'/desk?date={request.form.get("date")}&search={request.form.get("search")}')
@app.route('/download')
def download():
if not session.get('logged_in'): return redirect('/login')
selected_date = request.args.get('date') or get_kst_now().strftime('%Y-%m-%d')
search_keyword = request.args.get('search', '')
conn = sqlite3.connect(DB_PATH)
c = conn.cursor()
# ์์
๋ค์ด๋ก๋ ์ฟผ๋ฆฌ์๋ purpose(๋ชฉ์ ), exit_time(์ถ์ฐจ์๊ฐ) ์ถ๊ฐ
if search_keyword:
c.execute("SELECT visit_time, entry_time, exit_time, name, visitor_company, car_number, host_info, purpose, status, parking_time FROM visitors WHERE visit_date = ? AND (name LIKE ? OR car_number LIKE ?) ORDER BY visit_time ASC", (selected_date, f"%{search_keyword}%", f"%{search_keyword}%"))
else:
c.execute("SELECT visit_time, entry_time, exit_time, name, visitor_company, car_number, host_info, purpose, status, parking_time FROM visitors WHERE visit_date = ? ORDER BY visit_time ASC", (selected_date,))
rows = c.fetchall()
conn.close()
si = StringIO()
si.write('\ufeff')
cw = csv.writer(si)
cw.writerow(['๋ฐฉ๋ฌธ ์์ ์๊ฐ', '์
์ฐจ ์๊ฐ', '์ถ์ฐจ ์๊ฐ', '๋ฐฉ๋ฌธ์ ์ฑํจ', '์์', '์ฐจ๋ ๋ฒํธ', '๋ฐฉ๋ฌธ ๋์', '๋ฐฉ๋ฌธ ๋ชฉ์ ', '์ํ', '์ฃผ์ฐจ์๊ฐ(๋์ )'])
cw.writerows(rows)
return Response(si.getvalue(), mimetype="text/csv", headers={"Content-Disposition": f"attachment;filename=visitors_{selected_date}.csv"})