Khởi tạo khung mini-web với định tuyến regex
import pymysql
import re
from urllib.parse import unquote
template_dir = "./templates"
url_router = dict()
def route(path):
def decorator(func):
url_router[path] = func
def wrapper(filename):
return func(filename)
return wrapper
return decorator
@route(r"/home.html")
def home_page(filename, path=None):
"""Trả về nội dung trang chủ"""
try:
template_path = filename.replace(".py", ".html")
with open(template_dir + template_path, 'r') as f:
content = f.read()
db = pymysql.connect(host='localhost', port=3306, user='root',
password='mysql', database='stock_db', charset='utf8')
cursor = db.cursor()
cursor.execute("SELECT * FROM info")
results = cursor.fetchall()
html_template = """
<tr>
<td>%d</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td><input type="button" value="Thêm" id="addBtn" systemidvaule="%s"></td>
</tr>"""
html_content = ""
for row in results:
html_content += html_template % (row[0], row[1], row[2], row[3],
row[4], row[5], row[6], row[7], row[1])
content = re.sub(r'\{content\}', html_content, content)
return content
except Exception as e:
return str(e)
@route(r"/user/(.+)/edit\.html")
def edit_user(filename, path):
"""Hiển thị trang chỉnh sửa người dùng"""
try:
template_path = template_dir + "/edit.html"
with open(template_path, 'r') as f:
content = f.read()
match = re.match(path, filename)
if match:
user_id = match.group(1)
db = pymysql.connect(host='localhost', port=3306, user='root',
password='mysql', database='stock_db', charset='utf8')
cursor = db.cursor()
cursor.execute("SELECT note FROM focus WHERE info_id=(SELECT id FROM info WHERE code=%s)", (user_id,))
result = cursor.fetchone()
content = re.sub(r'\{id\}', user_id, content)
content = re.sub(r'\{note\}', str(result[0]), content)
return content
except Exception as e:
return f"Lỗi: {str(e)}"
def application(environ, start_response):
status = '200 OK'
response_headers = [('Content-Type', 'text/html')]
start_response(status, response_headers)
path_info = environ['PATH_INFO']
try:
for pattern, handler in url_router.items():
match = re.match(pattern, path_info)
if match:
return handler(path_info, pattern)
return f"Không tìm thấy trang: {path_info}"
except Exception as e:
return str(e)
Tích hợp cơ sở dữ liệu MySQL - Thêm dữ liệu
@route(r"/user/(.+)/add\.html")
def add_user(filename, path):
"""Thêm người dùng mới"""
try:
match = re.match(path, filename)
if not match:
return "ID người dùng không hợp lệ"
user_id = match.group(1)
db = pymysql.connect(host='localhost', port=3306, user='root',
password='mysql', database='stock_db', charset='utf8')
cursor = db.cursor()
# Kiểm tra xem đã tồn tại chưa
cursor.execute("SELECT * FROM focus WHERE info_id=(SELECT id FROM info WHERE code=%s)", (user_id,))
if cursor.fetchone():
return "Người dùng đã tồn tại"
# Thêm mới
cursor.execute("INSERT INTO focus (info_id) SELECT id FROM info WHERE code=%s", (user_id,))
db.commit()
return "Thêm người dùng thành công"
except Exception as e:
return f"Lỗi: {str(e)}"
Tích hợp cơ sở dữ liệu MySQL - Xóa dữ liệu
@route(r"/user/(.+)/delete\.html")
def delete_user(filename, path):
"""Xóa người dùng"""
try:
match = re.match(path, filename)
if not match:
return "ID người dùng không hợp lệ"
user_id = match.group(1)
db = pymysql.connect(host='localhost', port=3306, user='root',
password='mysql', database='stock_db', charset='utf8')
cursor = db.cursor()
# Kiểm tra sự tồn tại
cursor.execute("SELECT * FROM focus WHERE info_id=(SELECT id FROM info WHERE code=%s)", (user_id,))
if not cursor.fetchone():
return "Người dùng không tồn tại"
# Xóa bản ghi
cursor.execute("DELETE FROM focus WHERE info_id=(SELECT id FROM info WHERE code=%s)", (user_id,))
db.commit()
return "Xóa người dùng thành công"
except Exception as e:
return f"Lỗi: {str(e)}"
Tích hợp cơ sở dữ liệu MySQL - Cập nhật dữ liệu
@route(r"/user/(.+)/update\.html")
def update_user(filename, path):
"""Cập nhật thông tin người dùng"""
try:
match = re.match(path, filename)
if not match:
return "ID người dùng không hợp lệ"
user_id = match.group(1)
new_note = unquote(filename.split("/")[-1])
db = pymysql.connect(host='localhost', port=3306, user='root',
password='mysql', database='stock_db', charset='utf8')
cursor = db.cursor()
cursor.execute("""
UPDATE focus
SET note = %s
WHERE info_id = (SELECT id FROM info WHERE code = %s)
""", (new_note, user_id))
db.commit()
return "Cập nhật thành công"
except Exception as e:
return f"Lỗi: {str(e)}"
Xử lý mã hóa URL
import urllib.parse
# Mã hóa URL
encoded = urllib.parse.quote("Hà Nội")
# Giải mã URL
decoded = urllib.parse.unquote("%E1%BA%A3%20%E1%BA%AF%20N%E1%BB%99i")
Sử dụng mô-đun ghi nhật ký trong Python
Python cung cấp mô-đun logging để ghi lại các sự kiện trong quá trình chạy chương trình. Mô-đun này hỗ trợ 5 cấp độ ghi nhật ký:
- DEBUG: Thông tin chi tiết cho mục đích gỡ lỗi
- INFO: Xác nhận mọi thứ hoạt động như mong đợi
- WARNING: Cảnh báo về sự cố tiềm ẩn
- ERROR: Lỗi nghiêm trọng làm gián đoạn chức năng
- CRITICAL: Lỗi nghiêm trọng khiến chương trình không thể tiếp tục
Ghi nhật ký ra console
import logging
logging.basicConfig(
level=logging.WARNING,
format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s'
)
logging.debug('Thông tin debug')
logging.info('Thông tin thông thường')
logging.warning('Cảnh báo')
logging.error('Lỗi')
logging.critical('Lỗi nghiêm trọng')
Ghi nhật ký vào file
import logging
logging.basicConfig(
level=logging.WARNING,
filename='app.log',
filemode='w',
format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s'
)
logging.warning('Thông báo cảnh báo được lưu vào file')
Ghi nhật ký đồng thời ra console và file
import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
# Handler cho file
file_handler = logging.FileHandler('app.log', mode='a')
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(logging.Formatter("%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s"))
# Handler cho console
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.WARNING)
console_handler.setFormatter(logging.Formatter("%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s"))
logger.addHandler(file_handler)
logger.addHandler(console_handler)
logger.debug('Thông tin debug')
logger.info('Thông tin thông thường')